mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
Merge 576e61cea1 ("Merge tag 's390-6.1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux") into android-mainline
Steps on the way to 6.1-rc3 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I81d2cc862ba86b4859b2d1df225a3d76b7195a3e
This commit is contained in:
@@ -1318,7 +1318,7 @@ instance. This setup would require the following commands:
|
||||
$ v4l2-ctl -d2 -i2
|
||||
$ v4l2-ctl -d2 -c horizontal_movement=4
|
||||
$ v4l2-ctl -d1 --overlay=1
|
||||
$ v4l2-ctl -d1 -c loop_video=1
|
||||
$ v4l2-ctl -d0 -c loop_video=1
|
||||
$ v4l2-ctl -d2 --stream-mmap --overlay=1
|
||||
|
||||
And from another console:
|
||||
|
||||
@@ -118,6 +118,12 @@ Text Searching
|
||||
CRC and Math Functions in Linux
|
||||
===============================
|
||||
|
||||
Arithmetic Overflow Checking
|
||||
----------------------------
|
||||
|
||||
.. kernel-doc:: include/linux/overflow.h
|
||||
:internal:
|
||||
|
||||
CRC Functions
|
||||
-------------
|
||||
|
||||
|
||||
@@ -107,9 +107,6 @@ Kernel utility functions
|
||||
.. kernel-doc:: kernel/panic.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/linux/overflow.h
|
||||
:internal:
|
||||
|
||||
Device Resource Management
|
||||
--------------------------
|
||||
|
||||
|
||||
15
MAINTAINERS
15
MAINTAINERS
@@ -11265,7 +11265,6 @@ M: Claudio Imbrenda <imbrenda@linux.ibm.com>
|
||||
R: David Hildenbrand <david@redhat.com>
|
||||
L: kvm@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git
|
||||
F: Documentation/virt/kvm/s390*
|
||||
F: arch/s390/include/asm/gmap.h
|
||||
@@ -15443,6 +15442,7 @@ S: Maintained
|
||||
W: http://openvswitch.org
|
||||
F: include/uapi/linux/openvswitch.h
|
||||
F: net/openvswitch/
|
||||
F: tools/testing/selftests/net/openvswitch/
|
||||
|
||||
OPERATING PERFORMANCE POINTS (OPP)
|
||||
M: Viresh Kumar <vireshk@kernel.org>
|
||||
@@ -18004,7 +18004,6 @@ R: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
R: Sven Schnelle <svens@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git
|
||||
F: Documentation/driver-api/s390-drivers.rst
|
||||
F: Documentation/s390/
|
||||
@@ -18016,7 +18015,6 @@ M: Vineeth Vijayan <vneethv@linux.ibm.com>
|
||||
M: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
F: drivers/s390/cio/
|
||||
|
||||
S390 DASD DRIVER
|
||||
@@ -18024,7 +18022,6 @@ M: Stefan Haberland <sth@linux.ibm.com>
|
||||
M: Jan Hoeppner <hoeppner@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
F: block/partitions/ibm.c
|
||||
F: drivers/s390/block/dasd*
|
||||
F: include/linux/dasd_mod.h
|
||||
@@ -18034,7 +18031,6 @@ M: Matthew Rosato <mjrosato@linux.ibm.com>
|
||||
M: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
F: drivers/iommu/s390-iommu.c
|
||||
|
||||
S390 IUCV NETWORK LAYER
|
||||
@@ -18043,7 +18039,6 @@ M: Wenjia Zhang <wenjia@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
F: drivers/s390/net/*iucv*
|
||||
F: include/net/iucv/
|
||||
F: net/iucv/
|
||||
@@ -18054,7 +18049,6 @@ M: Wenjia Zhang <wenjia@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
F: drivers/s390/net/
|
||||
|
||||
S390 PCI SUBSYSTEM
|
||||
@@ -18062,7 +18056,6 @@ M: Niklas Schnelle <schnelle@linux.ibm.com>
|
||||
M: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
F: arch/s390/pci/
|
||||
F: drivers/pci/hotplug/s390_pci_hpc.c
|
||||
F: Documentation/s390/pci.rst
|
||||
@@ -18073,7 +18066,6 @@ M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Jason Herne <jjherne@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
F: Documentation/s390/vfio-ap*
|
||||
F: drivers/s390/crypto/vfio_ap*
|
||||
|
||||
@@ -18102,7 +18094,6 @@ S390 ZCRYPT DRIVER
|
||||
M: Harald Freudenberger <freude@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
F: drivers/s390/crypto/
|
||||
|
||||
S390 ZFCP DRIVER
|
||||
@@ -18110,7 +18101,6 @@ M: Steffen Maier <maier@linux.ibm.com>
|
||||
M: Benjamin Block <bblock@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
F: drivers/s390/scsi/zfcp_*
|
||||
|
||||
S3C ADC BATTERY DRIVER
|
||||
@@ -18682,7 +18672,6 @@ M: Wenjia Zhang <wenjia@linux.ibm.com>
|
||||
M: Jan Karcher <jaka@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
F: net/smc/
|
||||
|
||||
SHARP GP2AP002A00F/GP2AP002S00F SENSOR DRIVER
|
||||
@@ -18793,7 +18782,7 @@ M: Palmer Dabbelt <palmer@dabbelt.com>
|
||||
M: Paul Walmsley <paul.walmsley@sifive.com>
|
||||
L: linux-riscv@lists.infradead.org
|
||||
S: Supported
|
||||
T: git git://github.com/sifive/riscv-linux.git
|
||||
T: git https://github.com/sifive/riscv-linux.git
|
||||
N: sifive
|
||||
K: [^@]sifive
|
||||
|
||||
|
||||
@@ -411,14 +411,16 @@ config RISCV_ISA_SVPBMT
|
||||
|
||||
If you don't know what to do here, say Y.
|
||||
|
||||
config CC_HAS_ZICBOM
|
||||
config TOOLCHAIN_HAS_ZICBOM
|
||||
bool
|
||||
default y if 64BIT && $(cc-option,-mabi=lp64 -march=rv64ima_zicbom)
|
||||
default y if 32BIT && $(cc-option,-mabi=ilp32 -march=rv32ima_zicbom)
|
||||
default y
|
||||
depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zicbom)
|
||||
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zicbom)
|
||||
depends on LLD_VERSION >= 150000 || LD_VERSION >= 23800
|
||||
|
||||
config RISCV_ISA_ZICBOM
|
||||
bool "Zicbom extension support for non-coherent DMA operation"
|
||||
depends on CC_HAS_ZICBOM
|
||||
depends on TOOLCHAIN_HAS_ZICBOM
|
||||
depends on !XIP_KERNEL && MMU
|
||||
select RISCV_DMA_NONCOHERENT
|
||||
select RISCV_ALTERNATIVE
|
||||
@@ -433,6 +435,13 @@ config RISCV_ISA_ZICBOM
|
||||
|
||||
If you don't know what to do here, say Y.
|
||||
|
||||
config TOOLCHAIN_HAS_ZIHINTPAUSE
|
||||
bool
|
||||
default y
|
||||
depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zihintpause)
|
||||
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zihintpause)
|
||||
depends on LLD_VERSION >= 150000 || LD_VERSION >= 23600
|
||||
|
||||
config FPU
|
||||
bool "FPU support"
|
||||
default y
|
||||
|
||||
@@ -59,12 +59,10 @@ toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zi
|
||||
riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei
|
||||
|
||||
# Check if the toolchain supports Zicbom extension
|
||||
toolchain-supports-zicbom := $(call cc-option-yn, -march=$(riscv-march-y)_zicbom)
|
||||
riscv-march-$(toolchain-supports-zicbom) := $(riscv-march-y)_zicbom
|
||||
riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZICBOM) := $(riscv-march-y)_zicbom
|
||||
|
||||
# Check if the toolchain supports Zihintpause extension
|
||||
toolchain-supports-zihintpause := $(call cc-option-yn, -march=$(riscv-march-y)_zihintpause)
|
||||
riscv-march-$(toolchain-supports-zihintpause) := $(riscv-march-y)_zihintpause
|
||||
riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE) := $(riscv-march-y)_zihintpause
|
||||
|
||||
KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
|
||||
KBUILD_AFLAGS += -march=$(riscv-march-y)
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
#define JUMP_LABEL_NOP_SIZE 4
|
||||
|
||||
static __always_inline bool arch_static_branch(struct static_key *key,
|
||||
bool branch)
|
||||
static __always_inline bool arch_static_branch(struct static_key * const key,
|
||||
const bool branch)
|
||||
{
|
||||
asm_volatile_goto(
|
||||
" .option push \n\t"
|
||||
@@ -35,8 +35,8 @@ label:
|
||||
return true;
|
||||
}
|
||||
|
||||
static __always_inline bool arch_static_branch_jump(struct static_key *key,
|
||||
bool branch)
|
||||
static __always_inline bool arch_static_branch_jump(struct static_key * const key,
|
||||
const bool branch)
|
||||
{
|
||||
asm_volatile_goto(
|
||||
" .option push \n\t"
|
||||
|
||||
@@ -21,7 +21,7 @@ static inline void cpu_relax(void)
|
||||
* Reduce instruction retirement.
|
||||
* This assumes the PC changes.
|
||||
*/
|
||||
#ifdef __riscv_zihintpause
|
||||
#ifdef CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE
|
||||
__asm__ __volatile__ ("pause");
|
||||
#else
|
||||
/* Encoding of the pause instruction */
|
||||
|
||||
@@ -213,6 +213,9 @@ static void print_mmu(struct seq_file *f)
|
||||
|
||||
static void *c_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
if (*pos == nr_cpu_ids)
|
||||
return NULL;
|
||||
|
||||
*pos = cpumask_next(*pos - 1, cpu_online_mask);
|
||||
if ((*pos) < nr_cpu_ids)
|
||||
return (void *)(uintptr_t)(1 + *pos);
|
||||
|
||||
@@ -113,6 +113,8 @@ static void __init kasan_populate_pud(pgd_t *pgd,
|
||||
base_pud = pt_ops.get_pud_virt(pfn_to_phys(_pgd_pfn(*pgd)));
|
||||
} else if (pgd_none(*pgd)) {
|
||||
base_pud = memblock_alloc(PTRS_PER_PUD * sizeof(pud_t), PAGE_SIZE);
|
||||
memcpy(base_pud, (void *)kasan_early_shadow_pud,
|
||||
sizeof(pud_t) * PTRS_PER_PUD);
|
||||
} else {
|
||||
base_pud = (pud_t *)pgd_page_vaddr(*pgd);
|
||||
if (base_pud == lm_alias(kasan_early_shadow_pud)) {
|
||||
@@ -173,8 +175,11 @@ static void __init kasan_populate_p4d(pgd_t *pgd,
|
||||
base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(*pgd)));
|
||||
} else {
|
||||
base_p4d = (p4d_t *)pgd_page_vaddr(*pgd);
|
||||
if (base_p4d == lm_alias(kasan_early_shadow_p4d))
|
||||
if (base_p4d == lm_alias(kasan_early_shadow_p4d)) {
|
||||
base_p4d = memblock_alloc(PTRS_PER_PUD * sizeof(p4d_t), PAGE_SIZE);
|
||||
memcpy(base_p4d, (void *)kasan_early_shadow_p4d,
|
||||
sizeof(p4d_t) * PTRS_PER_P4D);
|
||||
}
|
||||
}
|
||||
|
||||
p4dp = base_p4d + p4d_index(vaddr);
|
||||
|
||||
@@ -102,8 +102,17 @@ SECTIONS
|
||||
_compressed_start = .;
|
||||
*(.vmlinux.bin.compressed)
|
||||
_compressed_end = .;
|
||||
FILL(0xff);
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
#define SB_TRAILER_SIZE 32
|
||||
/* Trailer needed for Secure Boot */
|
||||
. += SB_TRAILER_SIZE; /* make sure .sb.trailer does not overwrite the previous section */
|
||||
. = ALIGN(4096) - SB_TRAILER_SIZE;
|
||||
.sb.trailer : {
|
||||
QUAD(0)
|
||||
QUAD(0)
|
||||
QUAD(0)
|
||||
QUAD(0x000000207a49504c)
|
||||
}
|
||||
_end = .;
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
"3: jl 1b\n" \
|
||||
" lhi %0,0\n" \
|
||||
"4: sacf 768\n" \
|
||||
EX_TABLE(0b,4b) EX_TABLE(2b,4b) EX_TABLE(3b,4b) \
|
||||
EX_TABLE(0b,4b) EX_TABLE(1b,4b) \
|
||||
EX_TABLE(2b,4b) EX_TABLE(3b,4b) \
|
||||
: "=d" (ret), "=&d" (oldval), "=&d" (newval), \
|
||||
"=m" (*uaddr) \
|
||||
: "0" (-EFAULT), "d" (oparg), "a" (uaddr), \
|
||||
|
||||
@@ -459,6 +459,7 @@ static int paiext_push_sample(void)
|
||||
raw.frag.data = cpump->save;
|
||||
raw.size = raw.frag.size;
|
||||
data.raw = &raw;
|
||||
data.sample_flags |= PERF_SAMPLE_RAW;
|
||||
}
|
||||
|
||||
overflow = perf_event_overflow(event, &data, ®s);
|
||||
|
||||
@@ -157,7 +157,7 @@ unsigned long __clear_user(void __user *to, unsigned long size)
|
||||
asm volatile(
|
||||
" lr 0,%[spec]\n"
|
||||
"0: mvcos 0(%1),0(%4),%0\n"
|
||||
" jz 4f\n"
|
||||
"6: jz 4f\n"
|
||||
"1: algr %0,%2\n"
|
||||
" slgr %1,%2\n"
|
||||
" j 0b\n"
|
||||
@@ -167,11 +167,11 @@ unsigned long __clear_user(void __user *to, unsigned long size)
|
||||
" clgr %0,%3\n" /* copy crosses next page boundary? */
|
||||
" jnh 5f\n"
|
||||
"3: mvcos 0(%1),0(%4),%3\n"
|
||||
" slgr %0,%3\n"
|
||||
"7: slgr %0,%3\n"
|
||||
" j 5f\n"
|
||||
"4: slgr %0,%0\n"
|
||||
"5:\n"
|
||||
EX_TABLE(0b,2b) EX_TABLE(3b,5b)
|
||||
EX_TABLE(0b,2b) EX_TABLE(6b,2b) EX_TABLE(3b,5b) EX_TABLE(7b,5b)
|
||||
: "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2)
|
||||
: "a" (empty_zero_page), [spec] "d" (spec.val)
|
||||
: "cc", "memory", "0");
|
||||
|
||||
@@ -64,7 +64,7 @@ static inline int __pcistg_mio_inuser(
|
||||
asm volatile (
|
||||
" sacf 256\n"
|
||||
"0: llgc %[tmp],0(%[src])\n"
|
||||
" sllg %[val],%[val],8\n"
|
||||
"4: sllg %[val],%[val],8\n"
|
||||
" aghi %[src],1\n"
|
||||
" ogr %[val],%[tmp]\n"
|
||||
" brctg %[cnt],0b\n"
|
||||
@@ -72,7 +72,7 @@ static inline int __pcistg_mio_inuser(
|
||||
"2: ipm %[cc]\n"
|
||||
" srl %[cc],28\n"
|
||||
"3: sacf 768\n"
|
||||
EX_TABLE(0b, 3b) EX_TABLE(1b, 3b) EX_TABLE(2b, 3b)
|
||||
EX_TABLE(0b, 3b) EX_TABLE(4b, 3b) EX_TABLE(1b, 3b) EX_TABLE(2b, 3b)
|
||||
:
|
||||
[src] "+a" (src), [cnt] "+d" (cnt),
|
||||
[val] "+d" (val), [tmp] "=d" (tmp),
|
||||
@@ -215,10 +215,10 @@ static inline int __pcilg_mio_inuser(
|
||||
"2: ahi %[shift],-8\n"
|
||||
" srlg %[tmp],%[val],0(%[shift])\n"
|
||||
"3: stc %[tmp],0(%[dst])\n"
|
||||
" aghi %[dst],1\n"
|
||||
"5: aghi %[dst],1\n"
|
||||
" brctg %[cnt],2b\n"
|
||||
"4: sacf 768\n"
|
||||
EX_TABLE(0b, 4b) EX_TABLE(1b, 4b) EX_TABLE(3b, 4b)
|
||||
EX_TABLE(0b, 4b) EX_TABLE(1b, 4b) EX_TABLE(3b, 4b) EX_TABLE(5b, 4b)
|
||||
:
|
||||
[ioaddr_len] "+&d" (ioaddr_len.pair),
|
||||
[cc] "+d" (cc), [val] "=d" (val),
|
||||
|
||||
@@ -27,13 +27,17 @@
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/simd.h>
|
||||
|
||||
#define POLYVAL_ALIGN 16
|
||||
#define POLYVAL_ALIGN_ATTR __aligned(POLYVAL_ALIGN)
|
||||
#define POLYVAL_ALIGN_EXTRA ((POLYVAL_ALIGN - 1) & ~(CRYPTO_MINALIGN - 1))
|
||||
#define POLYVAL_CTX_SIZE (sizeof(struct polyval_tfm_ctx) + POLYVAL_ALIGN_EXTRA)
|
||||
#define NUM_KEY_POWERS 8
|
||||
|
||||
struct polyval_tfm_ctx {
|
||||
/*
|
||||
* These powers must be in the order h^8, ..., h^1.
|
||||
*/
|
||||
u8 key_powers[NUM_KEY_POWERS][POLYVAL_BLOCK_SIZE];
|
||||
u8 key_powers[NUM_KEY_POWERS][POLYVAL_BLOCK_SIZE] POLYVAL_ALIGN_ATTR;
|
||||
};
|
||||
|
||||
struct polyval_desc_ctx {
|
||||
@@ -45,6 +49,11 @@ asmlinkage void clmul_polyval_update(const struct polyval_tfm_ctx *keys,
|
||||
const u8 *in, size_t nblocks, u8 *accumulator);
|
||||
asmlinkage void clmul_polyval_mul(u8 *op1, const u8 *op2);
|
||||
|
||||
static inline struct polyval_tfm_ctx *polyval_tfm_ctx(struct crypto_shash *tfm)
|
||||
{
|
||||
return PTR_ALIGN(crypto_shash_ctx(tfm), POLYVAL_ALIGN);
|
||||
}
|
||||
|
||||
static void internal_polyval_update(const struct polyval_tfm_ctx *keys,
|
||||
const u8 *in, size_t nblocks, u8 *accumulator)
|
||||
{
|
||||
@@ -72,7 +81,7 @@ static void internal_polyval_mul(u8 *op1, const u8 *op2)
|
||||
static int polyval_x86_setkey(struct crypto_shash *tfm,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
struct polyval_tfm_ctx *tctx = crypto_shash_ctx(tfm);
|
||||
struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(tfm);
|
||||
int i;
|
||||
|
||||
if (keylen != POLYVAL_BLOCK_SIZE)
|
||||
@@ -102,7 +111,7 @@ static int polyval_x86_update(struct shash_desc *desc,
|
||||
const u8 *src, unsigned int srclen)
|
||||
{
|
||||
struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
|
||||
const struct polyval_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
|
||||
const struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(desc->tfm);
|
||||
u8 *pos;
|
||||
unsigned int nblocks;
|
||||
unsigned int n;
|
||||
@@ -143,7 +152,7 @@ static int polyval_x86_update(struct shash_desc *desc,
|
||||
static int polyval_x86_final(struct shash_desc *desc, u8 *dst)
|
||||
{
|
||||
struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
|
||||
const struct polyval_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
|
||||
const struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(desc->tfm);
|
||||
|
||||
if (dctx->bytes) {
|
||||
internal_polyval_mul(dctx->buffer,
|
||||
@@ -167,7 +176,7 @@ static struct shash_alg polyval_alg = {
|
||||
.cra_driver_name = "polyval-clmulni",
|
||||
.cra_priority = 200,
|
||||
.cra_blocksize = POLYVAL_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct polyval_tfm_ctx),
|
||||
.cra_ctxsize = POLYVAL_CTX_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
* Arbitrary retries in case the remote processor is slow to respond
|
||||
* to PCC commands
|
||||
*/
|
||||
#define PCC_CMD_WAIT_RETRIES_NUM 500
|
||||
#define PCC_CMD_WAIT_RETRIES_NUM 500ULL
|
||||
|
||||
struct pcc_data {
|
||||
struct pcc_mbox_chan *pcc_chan;
|
||||
|
||||
@@ -425,6 +425,13 @@ static const struct dmi_system_id asus_laptop[] = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "S5402ZA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Asus Vivobook S5602ZA",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -789,6 +789,7 @@ static bool acpi_info_matches_ids(struct acpi_device_info *info,
|
||||
static const char * const acpi_ignore_dep_ids[] = {
|
||||
"PNP0D80", /* Windows-compatible System Power Management Controller */
|
||||
"INT33BD", /* Intel Baytrail Mailbox Device */
|
||||
"LATT2021", /* Lattice FW Update Client Driver */
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -2952,6 +2952,10 @@ static int genpd_iterate_idle_states(struct device_node *dn,
|
||||
np = it.node;
|
||||
if (!of_match_node(idle_state_match, np))
|
||||
continue;
|
||||
|
||||
if (!of_device_is_available(np))
|
||||
continue;
|
||||
|
||||
if (states) {
|
||||
ret = genpd_parse_state(&states[i], np);
|
||||
if (ret) {
|
||||
|
||||
@@ -229,7 +229,7 @@ EXPORT_SYMBOL_GPL(device_property_read_string);
|
||||
* Find a given string in a string array and if it is found return the
|
||||
* index back.
|
||||
*
|
||||
* Return: %0 if the property was found (success),
|
||||
* Return: index, starting from %0, if the property was found (success),
|
||||
* %-EINVAL if given arguments are not valid,
|
||||
* %-ENODATA if the property does not have a value,
|
||||
* %-EPROTO if the property is not an array of strings,
|
||||
@@ -450,7 +450,7 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_string);
|
||||
* Find a given string in a string array and if it is found return the
|
||||
* index back.
|
||||
*
|
||||
* Return: %0 if the property was found (success),
|
||||
* Return: index, starting from %0, if the property was found (success),
|
||||
* %-EINVAL if given arguments are not valid,
|
||||
* %-ENODATA if the property does not have a value,
|
||||
* %-EPROTO if the property is not an array of strings,
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <linux/pm_qos.h>
|
||||
#include <trace/events/power.h>
|
||||
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/div64.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
@@ -280,10 +281,10 @@ static struct cpudata **all_cpu_data;
|
||||
* structure is used to store those callbacks.
|
||||
*/
|
||||
struct pstate_funcs {
|
||||
int (*get_max)(void);
|
||||
int (*get_max_physical)(void);
|
||||
int (*get_min)(void);
|
||||
int (*get_turbo)(void);
|
||||
int (*get_max)(int cpu);
|
||||
int (*get_max_physical)(int cpu);
|
||||
int (*get_min)(int cpu);
|
||||
int (*get_turbo)(int cpu);
|
||||
int (*get_scaling)(void);
|
||||
int (*get_cpu_scaling)(int cpu);
|
||||
int (*get_aperf_mperf_shift)(void);
|
||||
@@ -398,16 +399,6 @@ static int intel_pstate_get_cppc_guaranteed(int cpu)
|
||||
|
||||
return cppc_perf.nominal_perf;
|
||||
}
|
||||
|
||||
static u32 intel_pstate_cppc_nominal(int cpu)
|
||||
{
|
||||
u64 nominal_perf;
|
||||
|
||||
if (cppc_get_nominal_perf(cpu, &nominal_perf))
|
||||
return 0;
|
||||
|
||||
return nominal_perf;
|
||||
}
|
||||
#else /* CONFIG_ACPI_CPPC_LIB */
|
||||
static inline void intel_pstate_set_itmt_prio(int cpu)
|
||||
{
|
||||
@@ -531,35 +522,18 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu)
|
||||
{
|
||||
int perf_ctl_max_phys = cpu->pstate.max_pstate_physical;
|
||||
int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling;
|
||||
int perf_ctl_turbo = pstate_funcs.get_turbo();
|
||||
int turbo_freq = perf_ctl_turbo * perf_ctl_scaling;
|
||||
int perf_ctl_turbo = pstate_funcs.get_turbo(cpu->cpu);
|
||||
int scaling = cpu->pstate.scaling;
|
||||
|
||||
pr_debug("CPU%d: perf_ctl_max_phys = %d\n", cpu->cpu, perf_ctl_max_phys);
|
||||
pr_debug("CPU%d: perf_ctl_max = %d\n", cpu->cpu, pstate_funcs.get_max());
|
||||
pr_debug("CPU%d: perf_ctl_turbo = %d\n", cpu->cpu, perf_ctl_turbo);
|
||||
pr_debug("CPU%d: perf_ctl_scaling = %d\n", cpu->cpu, perf_ctl_scaling);
|
||||
pr_debug("CPU%d: HWP_CAP guaranteed = %d\n", cpu->cpu, cpu->pstate.max_pstate);
|
||||
pr_debug("CPU%d: HWP_CAP highest = %d\n", cpu->cpu, cpu->pstate.turbo_pstate);
|
||||
pr_debug("CPU%d: HWP-to-frequency scaling factor: %d\n", cpu->cpu, scaling);
|
||||
|
||||
/*
|
||||
* If the product of the HWP performance scaling factor and the HWP_CAP
|
||||
* highest performance is greater than the maximum turbo frequency
|
||||
* corresponding to the pstate_funcs.get_turbo() return value, the
|
||||
* scaling factor is too high, so recompute it to make the HWP_CAP
|
||||
* highest performance correspond to the maximum turbo frequency.
|
||||
*/
|
||||
cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * scaling;
|
||||
if (turbo_freq < cpu->pstate.turbo_freq) {
|
||||
cpu->pstate.turbo_freq = turbo_freq;
|
||||
scaling = DIV_ROUND_UP(turbo_freq, cpu->pstate.turbo_pstate);
|
||||
cpu->pstate.scaling = scaling;
|
||||
|
||||
pr_debug("CPU%d: refined HWP-to-frequency scaling factor: %d\n",
|
||||
cpu->cpu, scaling);
|
||||
}
|
||||
|
||||
cpu->pstate.turbo_freq = rounddown(cpu->pstate.turbo_pstate * scaling,
|
||||
perf_ctl_scaling);
|
||||
cpu->pstate.max_freq = rounddown(cpu->pstate.max_pstate * scaling,
|
||||
perf_ctl_scaling);
|
||||
|
||||
@@ -1740,7 +1714,7 @@ static void intel_pstate_hwp_enable(struct cpudata *cpudata)
|
||||
intel_pstate_update_epp_defaults(cpudata);
|
||||
}
|
||||
|
||||
static int atom_get_min_pstate(void)
|
||||
static int atom_get_min_pstate(int not_used)
|
||||
{
|
||||
u64 value;
|
||||
|
||||
@@ -1748,7 +1722,7 @@ static int atom_get_min_pstate(void)
|
||||
return (value >> 8) & 0x7F;
|
||||
}
|
||||
|
||||
static int atom_get_max_pstate(void)
|
||||
static int atom_get_max_pstate(int not_used)
|
||||
{
|
||||
u64 value;
|
||||
|
||||
@@ -1756,7 +1730,7 @@ static int atom_get_max_pstate(void)
|
||||
return (value >> 16) & 0x7F;
|
||||
}
|
||||
|
||||
static int atom_get_turbo_pstate(void)
|
||||
static int atom_get_turbo_pstate(int not_used)
|
||||
{
|
||||
u64 value;
|
||||
|
||||
@@ -1834,23 +1808,23 @@ static void atom_get_vid(struct cpudata *cpudata)
|
||||
cpudata->vid.turbo = value & 0x7f;
|
||||
}
|
||||
|
||||
static int core_get_min_pstate(void)
|
||||
static int core_get_min_pstate(int cpu)
|
||||
{
|
||||
u64 value;
|
||||
|
||||
rdmsrl(MSR_PLATFORM_INFO, value);
|
||||
rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value);
|
||||
return (value >> 40) & 0xFF;
|
||||
}
|
||||
|
||||
static int core_get_max_pstate_physical(void)
|
||||
static int core_get_max_pstate_physical(int cpu)
|
||||
{
|
||||
u64 value;
|
||||
|
||||
rdmsrl(MSR_PLATFORM_INFO, value);
|
||||
rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value);
|
||||
return (value >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
static int core_get_tdp_ratio(u64 plat_info)
|
||||
static int core_get_tdp_ratio(int cpu, u64 plat_info)
|
||||
{
|
||||
/* Check how many TDP levels present */
|
||||
if (plat_info & 0x600000000) {
|
||||
@@ -1860,13 +1834,13 @@ static int core_get_tdp_ratio(u64 plat_info)
|
||||
int err;
|
||||
|
||||
/* Get the TDP level (0, 1, 2) to get ratios */
|
||||
err = rdmsrl_safe(MSR_CONFIG_TDP_CONTROL, &tdp_ctrl);
|
||||
err = rdmsrl_safe_on_cpu(cpu, MSR_CONFIG_TDP_CONTROL, &tdp_ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* TDP MSR are continuous starting at 0x648 */
|
||||
tdp_msr = MSR_CONFIG_TDP_NOMINAL + (tdp_ctrl & 0x03);
|
||||
err = rdmsrl_safe(tdp_msr, &tdp_ratio);
|
||||
err = rdmsrl_safe_on_cpu(cpu, tdp_msr, &tdp_ratio);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1883,7 +1857,7 @@ static int core_get_tdp_ratio(u64 plat_info)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static int core_get_max_pstate(void)
|
||||
static int core_get_max_pstate(int cpu)
|
||||
{
|
||||
u64 tar;
|
||||
u64 plat_info;
|
||||
@@ -1891,10 +1865,10 @@ static int core_get_max_pstate(void)
|
||||
int tdp_ratio;
|
||||
int err;
|
||||
|
||||
rdmsrl(MSR_PLATFORM_INFO, plat_info);
|
||||
rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &plat_info);
|
||||
max_pstate = (plat_info >> 8) & 0xFF;
|
||||
|
||||
tdp_ratio = core_get_tdp_ratio(plat_info);
|
||||
tdp_ratio = core_get_tdp_ratio(cpu, plat_info);
|
||||
if (tdp_ratio <= 0)
|
||||
return max_pstate;
|
||||
|
||||
@@ -1903,7 +1877,7 @@ static int core_get_max_pstate(void)
|
||||
return tdp_ratio;
|
||||
}
|
||||
|
||||
err = rdmsrl_safe(MSR_TURBO_ACTIVATION_RATIO, &tar);
|
||||
err = rdmsrl_safe_on_cpu(cpu, MSR_TURBO_ACTIVATION_RATIO, &tar);
|
||||
if (!err) {
|
||||
int tar_levels;
|
||||
|
||||
@@ -1918,13 +1892,13 @@ static int core_get_max_pstate(void)
|
||||
return max_pstate;
|
||||
}
|
||||
|
||||
static int core_get_turbo_pstate(void)
|
||||
static int core_get_turbo_pstate(int cpu)
|
||||
{
|
||||
u64 value;
|
||||
int nont, ret;
|
||||
|
||||
rdmsrl(MSR_TURBO_RATIO_LIMIT, value);
|
||||
nont = core_get_max_pstate();
|
||||
rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value);
|
||||
nont = core_get_max_pstate(cpu);
|
||||
ret = (value) & 255;
|
||||
if (ret <= nont)
|
||||
ret = nont;
|
||||
@@ -1952,51 +1926,38 @@ static int knl_get_aperf_mperf_shift(void)
|
||||
return 10;
|
||||
}
|
||||
|
||||
static int knl_get_turbo_pstate(void)
|
||||
static int knl_get_turbo_pstate(int cpu)
|
||||
{
|
||||
u64 value;
|
||||
int nont, ret;
|
||||
|
||||
rdmsrl(MSR_TURBO_RATIO_LIMIT, value);
|
||||
nont = core_get_max_pstate();
|
||||
rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value);
|
||||
nont = core_get_max_pstate(cpu);
|
||||
ret = (((value) >> 8) & 0xFF);
|
||||
if (ret <= nont)
|
||||
ret = nont;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_CPPC_LIB
|
||||
static u32 hybrid_ref_perf;
|
||||
static void hybrid_get_type(void *data)
|
||||
{
|
||||
u8 *cpu_type = data;
|
||||
|
||||
*cpu_type = get_this_hybrid_cpu_type();
|
||||
}
|
||||
|
||||
static int hybrid_get_cpu_scaling(int cpu)
|
||||
{
|
||||
return DIV_ROUND_UP(core_get_scaling() * hybrid_ref_perf,
|
||||
intel_pstate_cppc_nominal(cpu));
|
||||
u8 cpu_type = 0;
|
||||
|
||||
smp_call_function_single(cpu, hybrid_get_type, &cpu_type, 1);
|
||||
/* P-cores have a smaller perf level-to-freqency scaling factor. */
|
||||
if (cpu_type == 0x40)
|
||||
return 78741;
|
||||
|
||||
return core_get_scaling();
|
||||
}
|
||||
|
||||
static void intel_pstate_cppc_set_cpu_scaling(void)
|
||||
{
|
||||
u32 min_nominal_perf = U32_MAX;
|
||||
int cpu;
|
||||
|
||||
for_each_present_cpu(cpu) {
|
||||
u32 nominal_perf = intel_pstate_cppc_nominal(cpu);
|
||||
|
||||
if (nominal_perf && nominal_perf < min_nominal_perf)
|
||||
min_nominal_perf = nominal_perf;
|
||||
}
|
||||
|
||||
if (min_nominal_perf < U32_MAX) {
|
||||
hybrid_ref_perf = min_nominal_perf;
|
||||
pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline void intel_pstate_cppc_set_cpu_scaling(void)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_ACPI_CPPC_LIB */
|
||||
|
||||
static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
|
||||
{
|
||||
trace_cpu_frequency(pstate * cpu->pstate.scaling, cpu->cpu);
|
||||
@@ -2025,10 +1986,10 @@ static void intel_pstate_max_within_limits(struct cpudata *cpu)
|
||||
|
||||
static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
|
||||
{
|
||||
int perf_ctl_max_phys = pstate_funcs.get_max_physical();
|
||||
int perf_ctl_max_phys = pstate_funcs.get_max_physical(cpu->cpu);
|
||||
int perf_ctl_scaling = pstate_funcs.get_scaling();
|
||||
|
||||
cpu->pstate.min_pstate = pstate_funcs.get_min();
|
||||
cpu->pstate.min_pstate = pstate_funcs.get_min(cpu->cpu);
|
||||
cpu->pstate.max_pstate_physical = perf_ctl_max_phys;
|
||||
cpu->pstate.perf_ctl_scaling = perf_ctl_scaling;
|
||||
|
||||
@@ -2044,8 +2005,8 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
|
||||
}
|
||||
} else {
|
||||
cpu->pstate.scaling = perf_ctl_scaling;
|
||||
cpu->pstate.max_pstate = pstate_funcs.get_max();
|
||||
cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
|
||||
cpu->pstate.max_pstate = pstate_funcs.get_max(cpu->cpu);
|
||||
cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(cpu->cpu);
|
||||
}
|
||||
|
||||
if (cpu->pstate.scaling == perf_ctl_scaling) {
|
||||
@@ -3221,9 +3182,9 @@ static unsigned int force_load __initdata;
|
||||
|
||||
static int __init intel_pstate_msrs_not_valid(void)
|
||||
{
|
||||
if (!pstate_funcs.get_max() ||
|
||||
!pstate_funcs.get_min() ||
|
||||
!pstate_funcs.get_turbo())
|
||||
if (!pstate_funcs.get_max(0) ||
|
||||
!pstate_funcs.get_min(0) ||
|
||||
!pstate_funcs.get_turbo(0))
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
@@ -3450,7 +3411,7 @@ static int __init intel_pstate_init(void)
|
||||
default_driver = &intel_pstate;
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_HYBRID_CPU))
|
||||
intel_pstate_cppc_set_cpu_scaling();
|
||||
pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling;
|
||||
|
||||
goto hwp_cpu_matched;
|
||||
}
|
||||
|
||||
@@ -510,13 +510,13 @@ kfd_mem_dmamap_userptr(struct kgd_mem *mem,
|
||||
struct ttm_tt *ttm = bo->tbo.ttm;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(ttm->num_pages != src_ttm->num_pages))
|
||||
return -EINVAL;
|
||||
|
||||
ttm->sg = kmalloc(sizeof(*ttm->sg), GFP_KERNEL);
|
||||
if (unlikely(!ttm->sg))
|
||||
return -ENOMEM;
|
||||
|
||||
if (WARN_ON(ttm->num_pages != src_ttm->num_pages))
|
||||
return -EINVAL;
|
||||
|
||||
/* Same sequence as in amdgpu_ttm_tt_pin_userptr */
|
||||
ret = sg_alloc_table_from_pages(ttm->sg, src_ttm->pages,
|
||||
ttm->num_pages, 0,
|
||||
|
||||
@@ -326,7 +326,10 @@ static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ctx->stable_pstate = current_stable_pstate;
|
||||
if (mgr->adev->pm.stable_pstate_ctx)
|
||||
ctx->stable_pstate = mgr->adev->pm.stable_pstate_ctx->stable_pstate;
|
||||
else
|
||||
ctx->stable_pstate = current_stable_pstate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3210,6 +3210,15 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
|
||||
return r;
|
||||
}
|
||||
adev->ip_blocks[i].status.hw = true;
|
||||
|
||||
if (adev->in_s0ix && adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) {
|
||||
/* disable gfxoff for IP resume. The gfxoff will be re-enabled in
|
||||
* amdgpu_device_resume() after IP resume.
|
||||
*/
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
DRM_DEBUG("will disable gfxoff for re-initializing other blocks\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -4185,6 +4194,13 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
||||
/* Make sure IB tests flushed */
|
||||
flush_delayed_work(&adev->delayed_init_work);
|
||||
|
||||
if (adev->in_s0ix) {
|
||||
/* re-enable gfxoff after IP resume. This re-enables gfxoff after
|
||||
* it was disabled for IP resume in amdgpu_device_ip_resume_phase2().
|
||||
*/
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
DRM_DEBUG("will enable gfxoff for the mission mode\n");
|
||||
}
|
||||
if (fbcon)
|
||||
drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false);
|
||||
|
||||
@@ -5381,7 +5397,7 @@ skip_hw_reset:
|
||||
drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res);
|
||||
}
|
||||
|
||||
if (adev->enable_mes)
|
||||
if (adev->enable_mes && adev->ip_versions[GC_HWIP][0] != IP_VERSION(11, 0, 3))
|
||||
amdgpu_mes_self_test(tmp_adev);
|
||||
|
||||
if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled) {
|
||||
|
||||
@@ -344,6 +344,10 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
|
||||
fw_info->ver = adev->mes.ucode_fw_version[1];
|
||||
fw_info->feature = 0;
|
||||
break;
|
||||
case AMDGPU_INFO_FW_IMU:
|
||||
fw_info->ver = adev->gfx.imu_fw_version;
|
||||
fw_info->feature = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1520,6 +1524,15 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
|
||||
fw_info.feature, fw_info.ver);
|
||||
}
|
||||
|
||||
/* IMU */
|
||||
query_fw.fw_type = AMDGPU_INFO_FW_IMU;
|
||||
query_fw.index = 0;
|
||||
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
seq_printf(m, "IMU feature version: %u, firmware version: 0x%08x\n",
|
||||
fw_info.feature, fw_info.ver);
|
||||
|
||||
/* PSP SOS */
|
||||
query_fw.fw_type = AMDGPU_INFO_FW_SOS;
|
||||
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
|
||||
|
||||
@@ -698,6 +698,7 @@ FW_VERSION_ATTR(rlc_srlg_fw_version, 0444, gfx.rlc_srlg_fw_version);
|
||||
FW_VERSION_ATTR(rlc_srls_fw_version, 0444, gfx.rlc_srls_fw_version);
|
||||
FW_VERSION_ATTR(mec_fw_version, 0444, gfx.mec_fw_version);
|
||||
FW_VERSION_ATTR(mec2_fw_version, 0444, gfx.mec2_fw_version);
|
||||
FW_VERSION_ATTR(imu_fw_version, 0444, gfx.imu_fw_version);
|
||||
FW_VERSION_ATTR(sos_fw_version, 0444, psp.sos.fw_version);
|
||||
FW_VERSION_ATTR(asd_fw_version, 0444, psp.asd_context.bin_desc.fw_version);
|
||||
FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ras_context.context.bin_desc.fw_version);
|
||||
@@ -719,7 +720,8 @@ static struct attribute *fw_attrs[] = {
|
||||
&dev_attr_ta_ras_fw_version.attr, &dev_attr_ta_xgmi_fw_version.attr,
|
||||
&dev_attr_smc_fw_version.attr, &dev_attr_sdma_fw_version.attr,
|
||||
&dev_attr_sdma2_fw_version.attr, &dev_attr_vcn_fw_version.attr,
|
||||
&dev_attr_dmcu_fw_version.attr, NULL
|
||||
&dev_attr_dmcu_fw_version.attr, &dev_attr_imu_fw_version.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group fw_attr_group = {
|
||||
|
||||
@@ -547,6 +547,7 @@ static void amdgpu_virt_populate_vf2pf_ucode_info(struct amdgpu_device *adev)
|
||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_RLC_SRLS, adev->gfx.rlc_srls_fw_version);
|
||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_MEC, adev->gfx.mec_fw_version);
|
||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_MEC2, adev->gfx.mec2_fw_version);
|
||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_IMU, adev->gfx.imu_fw_version);
|
||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SOS, adev->psp.sos.fw_version);
|
||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_ASD,
|
||||
adev->psp.asd_context.bin_desc.fw_version);
|
||||
|
||||
@@ -70,6 +70,7 @@ enum amd_sriov_ucode_engine_id {
|
||||
AMD_SRIOV_UCODE_ID_RLC_SRLS,
|
||||
AMD_SRIOV_UCODE_ID_MEC,
|
||||
AMD_SRIOV_UCODE_ID_MEC2,
|
||||
AMD_SRIOV_UCODE_ID_IMU,
|
||||
AMD_SRIOV_UCODE_ID_SOS,
|
||||
AMD_SRIOV_UCODE_ID_ASD,
|
||||
AMD_SRIOV_UCODE_ID_TA_RAS,
|
||||
|
||||
@@ -5051,6 +5051,7 @@ static int gfx_v11_0_set_powergating_state(void *handle,
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
amdgpu_gfx_off_ctrl(adev, enable);
|
||||
break;
|
||||
case IP_VERSION(11, 0, 1):
|
||||
|
||||
@@ -98,7 +98,14 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
||||
struct amdgpu_device *adev = mes->adev;
|
||||
struct amdgpu_ring *ring = &mes->ring;
|
||||
unsigned long flags;
|
||||
signed long timeout = adev->usec_timeout;
|
||||
|
||||
if (amdgpu_emu_mode) {
|
||||
timeout *= 100;
|
||||
} else if (amdgpu_sriov_vf(adev)) {
|
||||
/* Worst case in sriov where all other 15 VF timeout, each VF needs about 600ms */
|
||||
timeout = 15 * 600 * 1000;
|
||||
}
|
||||
BUG_ON(size % 4 != 0);
|
||||
|
||||
spin_lock_irqsave(&mes->ring_lock, flags);
|
||||
@@ -118,7 +125,7 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
||||
DRM_DEBUG("MES msg=%d was emitted\n", x_pkt->header.opcode);
|
||||
|
||||
r = amdgpu_fence_wait_polling(ring, ring->fence_drv.sync_seq,
|
||||
adev->usec_timeout * (amdgpu_emu_mode ? 100 : 1));
|
||||
timeout);
|
||||
if (r < 1) {
|
||||
DRM_ERROR("MES failed to response msg=%d\n",
|
||||
x_pkt->header.opcode);
|
||||
|
||||
@@ -32,8 +32,6 @@
|
||||
#include "gc/gc_10_1_0_offset.h"
|
||||
#include "soc15_common.h"
|
||||
|
||||
#define mmMM_ATC_L2_MISC_CG_Sienna_Cichlid 0x064d
|
||||
#define mmMM_ATC_L2_MISC_CG_Sienna_Cichlid_BASE_IDX 0
|
||||
#define mmDAGB0_CNTL_MISC2_Sienna_Cichlid 0x0070
|
||||
#define mmDAGB0_CNTL_MISC2_Sienna_Cichlid_BASE_IDX 0
|
||||
|
||||
@@ -574,7 +572,6 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
|
||||
case IP_VERSION(2, 1, 0):
|
||||
case IP_VERSION(2, 1, 1):
|
||||
case IP_VERSION(2, 1, 2):
|
||||
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
|
||||
def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid);
|
||||
break;
|
||||
default:
|
||||
@@ -608,8 +605,6 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
|
||||
case IP_VERSION(2, 1, 0):
|
||||
case IP_VERSION(2, 1, 1):
|
||||
case IP_VERSION(2, 1, 2):
|
||||
if (def != data)
|
||||
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data);
|
||||
if (def1 != data1)
|
||||
WREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid, data1);
|
||||
break;
|
||||
@@ -634,8 +629,8 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
|
||||
case IP_VERSION(2, 1, 0):
|
||||
case IP_VERSION(2, 1, 1):
|
||||
case IP_VERSION(2, 1, 2):
|
||||
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
|
||||
break;
|
||||
/* There is no ATCL2 in MMHUB for 2.1.x */
|
||||
return;
|
||||
default:
|
||||
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
|
||||
break;
|
||||
@@ -646,18 +641,8 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
|
||||
else
|
||||
data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
|
||||
|
||||
if (def != data) {
|
||||
switch (adev->ip_versions[MMHUB_HWIP][0]) {
|
||||
case IP_VERSION(2, 1, 0):
|
||||
case IP_VERSION(2, 1, 1):
|
||||
case IP_VERSION(2, 1, 2):
|
||||
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data);
|
||||
break;
|
||||
default:
|
||||
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (def != data)
|
||||
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
|
||||
}
|
||||
|
||||
static int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev,
|
||||
@@ -695,7 +680,10 @@ static void mmhub_v2_0_get_clockgating(struct amdgpu_device *adev, u64 *flags)
|
||||
case IP_VERSION(2, 1, 0):
|
||||
case IP_VERSION(2, 1, 1):
|
||||
case IP_VERSION(2, 1, 2):
|
||||
data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
|
||||
/* There is no ATCL2 in MMHUB for 2.1.x. Keep the status
|
||||
* based on DAGB
|
||||
*/
|
||||
data = MM_ATC_L2_MISC_CG__ENABLE_MASK;
|
||||
data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -795,6 +795,102 @@ static struct kfd_gpu_cache_info yellow_carp_cache_info[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct kfd_gpu_cache_info gfx1037_cache_info[] = {
|
||||
{
|
||||
/* TCP L1 Cache per CU */
|
||||
.cache_size = 16,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 1,
|
||||
},
|
||||
{
|
||||
/* Scalar L1 Instruction Cache per SQC */
|
||||
.cache_size = 32,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_INST_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* Scalar L1 Data Cache per SQC */
|
||||
.cache_size = 16,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* GL1 Data Cache per SA */
|
||||
.cache_size = 128,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* L2 Data Cache per GPU (Total Tex Cache) */
|
||||
.cache_size = 256,
|
||||
.cache_level = 2,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static struct kfd_gpu_cache_info gc_10_3_6_cache_info[] = {
|
||||
{
|
||||
/* TCP L1 Cache per CU */
|
||||
.cache_size = 16,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 1,
|
||||
},
|
||||
{
|
||||
/* Scalar L1 Instruction Cache per SQC */
|
||||
.cache_size = 32,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_INST_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* Scalar L1 Data Cache per SQC */
|
||||
.cache_size = 16,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* GL1 Data Cache per SA */
|
||||
.cache_size = 128,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* L2 Data Cache per GPU (Total Tex Cache) */
|
||||
.cache_size = 256,
|
||||
.cache_level = 2,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev,
|
||||
struct crat_subtype_computeunit *cu)
|
||||
{
|
||||
@@ -1514,11 +1610,17 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
|
||||
num_of_cache_types = ARRAY_SIZE(beige_goby_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 3, 3):
|
||||
case IP_VERSION(10, 3, 6): /* TODO: Double check these on production silicon */
|
||||
case IP_VERSION(10, 3, 7): /* TODO: Double check these on production silicon */
|
||||
pcache_info = yellow_carp_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(yellow_carp_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 3, 6):
|
||||
pcache_info = gc_10_3_6_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(gc_10_3_6_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 3, 7):
|
||||
pcache_info = gfx1037_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(gfx1037_cache_info);
|
||||
break;
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
|
||||
@@ -1369,7 +1369,7 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(plane->dev);
|
||||
const struct drm_format_info *info = drm_format_info(format);
|
||||
struct hw_asic_id asic_id = adev->dm.dc->ctx->asic_id;
|
||||
int i;
|
||||
|
||||
enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3;
|
||||
|
||||
@@ -1386,49 +1386,13 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* check if swizzle mode is supported by this version of DCN */
|
||||
switch (asic_id.chip_family) {
|
||||
case FAMILY_SI:
|
||||
case FAMILY_CI:
|
||||
case FAMILY_KV:
|
||||
case FAMILY_CZ:
|
||||
case FAMILY_VI:
|
||||
/* asics before AI does not have modifier support */
|
||||
return false;
|
||||
case FAMILY_AI:
|
||||
case FAMILY_RV:
|
||||
case FAMILY_NV:
|
||||
case FAMILY_VGH:
|
||||
case FAMILY_YELLOW_CARP:
|
||||
case AMDGPU_FAMILY_GC_10_3_6:
|
||||
case AMDGPU_FAMILY_GC_10_3_7:
|
||||
switch (AMD_FMT_MOD_GET(TILE, modifier)) {
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_D_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_S_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_D:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case AMDGPU_FAMILY_GC_11_0_0:
|
||||
case AMDGPU_FAMILY_GC_11_0_1:
|
||||
switch (AMD_FMT_MOD_GET(TILE, modifier)) {
|
||||
case AMD_FMT_MOD_TILE_GFX11_256K_R_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_D_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_S_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_D:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT(0); /* Unknown asic */
|
||||
break;
|
||||
/* Check that the modifier is on the list of the plane's supported modifiers. */
|
||||
for (i = 0; i < plane->modifier_count; i++) {
|
||||
if (modifier == plane->modifiers[i])
|
||||
break;
|
||||
}
|
||||
if (i == plane->modifier_count)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* For D swizzle the canonical modifier depends on the bpp, so check
|
||||
|
||||
@@ -1270,16 +1270,6 @@ void dcn20_pipe_control_lock(
|
||||
lock,
|
||||
&hw_locks,
|
||||
&inst_flags);
|
||||
} else if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
|
||||
union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 };
|
||||
hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK;
|
||||
hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER;
|
||||
hw_lock_cmd.bits.lock_pipe = 1;
|
||||
hw_lock_cmd.bits.otg_inst = pipe->stream_res.tg->inst;
|
||||
hw_lock_cmd.bits.lock = lock;
|
||||
if (!lock)
|
||||
hw_lock_cmd.bits.should_release = 1;
|
||||
dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd);
|
||||
} else if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
|
||||
if (lock)
|
||||
pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
|
||||
@@ -1856,7 +1846,7 @@ void dcn20_post_unlock_program_front_end(
|
||||
|
||||
for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS*1000
|
||||
&& hubp->funcs->hubp_is_flip_pending(hubp); j++)
|
||||
mdelay(1);
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ bool dcn32_all_pipes_have_stream_and_plane(struct dc *dc,
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (!pipe->stream)
|
||||
return false;
|
||||
continue;
|
||||
|
||||
if (!pipe->plane_state)
|
||||
return false;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#define SMU13_DRIVER_IF_V13_0_0_H
|
||||
|
||||
//Increment this version if SkuTable_t or BoardTable_t change
|
||||
#define PPTABLE_VERSION 0x24
|
||||
#define PPTABLE_VERSION 0x26
|
||||
|
||||
#define NUM_GFXCLK_DPM_LEVELS 16
|
||||
#define NUM_SOCCLK_DPM_LEVELS 8
|
||||
@@ -109,6 +109,22 @@
|
||||
#define FEATURE_SPARE_63_BIT 63
|
||||
#define NUM_FEATURES 64
|
||||
|
||||
#define ALLOWED_FEATURE_CTRL_DEFAULT 0xFFFFFFFFFFFFFFFFULL
|
||||
#define ALLOWED_FEATURE_CTRL_SCPM ((1 << FEATURE_DPM_GFXCLK_BIT) | \
|
||||
(1 << FEATURE_DPM_GFX_POWER_OPTIMIZER_BIT) | \
|
||||
(1 << FEATURE_DPM_UCLK_BIT) | \
|
||||
(1 << FEATURE_DPM_FCLK_BIT) | \
|
||||
(1 << FEATURE_DPM_SOCCLK_BIT) | \
|
||||
(1 << FEATURE_DPM_MP0CLK_BIT) | \
|
||||
(1 << FEATURE_DPM_LINK_BIT) | \
|
||||
(1 << FEATURE_DPM_DCN_BIT) | \
|
||||
(1 << FEATURE_DS_GFXCLK_BIT) | \
|
||||
(1 << FEATURE_DS_SOCCLK_BIT) | \
|
||||
(1 << FEATURE_DS_FCLK_BIT) | \
|
||||
(1 << FEATURE_DS_LCLK_BIT) | \
|
||||
(1 << FEATURE_DS_DCFCLK_BIT) | \
|
||||
(1 << FEATURE_DS_UCLK_BIT))
|
||||
|
||||
//For use with feature control messages
|
||||
typedef enum {
|
||||
FEATURE_PWR_ALL,
|
||||
@@ -133,6 +149,7 @@ typedef enum {
|
||||
#define DEBUG_OVERRIDE_DISABLE_DFLL 0x00000200
|
||||
#define DEBUG_OVERRIDE_ENABLE_RLC_VF_BRINGUP_MODE 0x00000400
|
||||
#define DEBUG_OVERRIDE_DFLL_MASTER_MODE 0x00000800
|
||||
#define DEBUG_OVERRIDE_ENABLE_PROFILING_MODE 0x00001000
|
||||
|
||||
// VR Mapping Bit Defines
|
||||
#define VR_MAPPING_VR_SELECT_MASK 0x01
|
||||
@@ -262,15 +279,15 @@ typedef enum {
|
||||
} I2cControllerPort_e;
|
||||
|
||||
typedef enum {
|
||||
I2C_CONTROLLER_NAME_VR_GFX = 0,
|
||||
I2C_CONTROLLER_NAME_VR_SOC,
|
||||
I2C_CONTROLLER_NAME_VR_VMEMP,
|
||||
I2C_CONTROLLER_NAME_VR_VDDIO,
|
||||
I2C_CONTROLLER_NAME_LIQUID0,
|
||||
I2C_CONTROLLER_NAME_LIQUID1,
|
||||
I2C_CONTROLLER_NAME_PLX,
|
||||
I2C_CONTROLLER_NAME_OTHER,
|
||||
I2C_CONTROLLER_NAME_COUNT,
|
||||
I2C_CONTROLLER_NAME_VR_GFX = 0,
|
||||
I2C_CONTROLLER_NAME_VR_SOC,
|
||||
I2C_CONTROLLER_NAME_VR_VMEMP,
|
||||
I2C_CONTROLLER_NAME_VR_VDDIO,
|
||||
I2C_CONTROLLER_NAME_LIQUID0,
|
||||
I2C_CONTROLLER_NAME_LIQUID1,
|
||||
I2C_CONTROLLER_NAME_PLX,
|
||||
I2C_CONTROLLER_NAME_FAN_INTAKE,
|
||||
I2C_CONTROLLER_NAME_COUNT,
|
||||
} I2cControllerName_e;
|
||||
|
||||
typedef enum {
|
||||
@@ -282,16 +299,17 @@ typedef enum {
|
||||
I2C_CONTROLLER_THROTTLER_LIQUID0,
|
||||
I2C_CONTROLLER_THROTTLER_LIQUID1,
|
||||
I2C_CONTROLLER_THROTTLER_PLX,
|
||||
I2C_CONTROLLER_THROTTLER_FAN_INTAKE,
|
||||
I2C_CONTROLLER_THROTTLER_INA3221,
|
||||
I2C_CONTROLLER_THROTTLER_COUNT,
|
||||
} I2cControllerThrottler_e;
|
||||
|
||||
typedef enum {
|
||||
I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5,
|
||||
I2C_CONTROLLER_PROTOCOL_VR_IR35217,
|
||||
I2C_CONTROLLER_PROTOCOL_TMP_TMP102A,
|
||||
I2C_CONTROLLER_PROTOCOL_INA3221,
|
||||
I2C_CONTROLLER_PROTOCOL_COUNT,
|
||||
I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5,
|
||||
I2C_CONTROLLER_PROTOCOL_VR_IR35217,
|
||||
I2C_CONTROLLER_PROTOCOL_TMP_MAX31875,
|
||||
I2C_CONTROLLER_PROTOCOL_INA3221,
|
||||
I2C_CONTROLLER_PROTOCOL_COUNT,
|
||||
} I2cControllerProtocol_e;
|
||||
|
||||
typedef struct {
|
||||
@@ -658,13 +676,20 @@ typedef struct {
|
||||
|
||||
#define PP_NUM_OD_VF_CURVE_POINTS PP_NUM_RTAVFS_PWL_ZONES + 1
|
||||
|
||||
typedef enum {
|
||||
FAN_MODE_AUTO = 0,
|
||||
FAN_MODE_MANUAL_LINEAR,
|
||||
} FanMode_e;
|
||||
|
||||
typedef struct {
|
||||
uint32_t FeatureCtrlMask;
|
||||
|
||||
//Voltage control
|
||||
int16_t VoltageOffsetPerZoneBoundary[PP_NUM_OD_VF_CURVE_POINTS];
|
||||
uint16_t reserved[2];
|
||||
uint16_t VddGfxVmax; // in mV
|
||||
|
||||
uint8_t IdlePwrSavingFeaturesCtrl;
|
||||
uint8_t RuntimePwrSavingFeaturesCtrl;
|
||||
|
||||
//Frequency changes
|
||||
int16_t GfxclkFmin; // MHz
|
||||
@@ -674,7 +699,7 @@ typedef struct {
|
||||
|
||||
//PPT
|
||||
int16_t Ppt; // %
|
||||
int16_t reserved1;
|
||||
int16_t Tdc;
|
||||
|
||||
//Fan control
|
||||
uint8_t FanLinearPwmPoints[NUM_OD_FAN_MAX_POINTS];
|
||||
@@ -701,16 +726,19 @@ typedef struct {
|
||||
uint32_t FeatureCtrlMask;
|
||||
|
||||
int16_t VoltageOffsetPerZoneBoundary;
|
||||
uint16_t reserved[2];
|
||||
uint16_t VddGfxVmax; // in mV
|
||||
|
||||
uint16_t GfxclkFmin; // MHz
|
||||
uint16_t GfxclkFmax; // MHz
|
||||
uint8_t IdlePwrSavingFeaturesCtrl;
|
||||
uint8_t RuntimePwrSavingFeaturesCtrl;
|
||||
|
||||
int16_t GfxclkFmin; // MHz
|
||||
int16_t GfxclkFmax; // MHz
|
||||
uint16_t UclkFmin; // MHz
|
||||
uint16_t UclkFmax; // MHz
|
||||
|
||||
//PPT
|
||||
int16_t Ppt; // %
|
||||
int16_t reserved1;
|
||||
int16_t Tdc;
|
||||
|
||||
uint8_t FanLinearPwmPoints;
|
||||
uint8_t FanLinearTempPoints;
|
||||
@@ -857,7 +885,8 @@ typedef struct {
|
||||
uint16_t FanStartTempMin;
|
||||
uint16_t FanStartTempMax;
|
||||
|
||||
uint32_t Spare[12];
|
||||
uint16_t PowerMinPpt0[POWER_SOURCE_COUNT];
|
||||
uint32_t Spare[11];
|
||||
|
||||
} MsgLimits_t;
|
||||
|
||||
@@ -1041,7 +1070,17 @@ typedef struct {
|
||||
uint32_t GfxoffSpare[15];
|
||||
|
||||
// GFX GPO
|
||||
uint32_t GfxGpoSpare[16];
|
||||
uint32_t DfllBtcMasterScalerM;
|
||||
int32_t DfllBtcMasterScalerB;
|
||||
uint32_t DfllBtcSlaveScalerM;
|
||||
int32_t DfllBtcSlaveScalerB;
|
||||
|
||||
uint32_t DfllPccAsWaitCtrl; //GDFLL_AS_WAIT_CTRL_PCC register value to be passed to RLC msg
|
||||
uint32_t DfllPccAsStepCtrl; //GDFLL_AS_STEP_CTRL_PCC register value to be passed to RLC msg
|
||||
|
||||
uint32_t DfllL2FrequencyBoostM; //Unitless (float)
|
||||
uint32_t DfllL2FrequencyBoostB; //In MHz (integer)
|
||||
uint32_t GfxGpoSpare[8];
|
||||
|
||||
// GFX DCS
|
||||
|
||||
@@ -1114,12 +1153,14 @@ typedef struct {
|
||||
uint16_t IntakeTempHighIntakeAcousticLimit;
|
||||
uint16_t IntakeTempAcouticLimitReleaseRate;
|
||||
|
||||
uint16_t FanStalledTempLimitOffset;
|
||||
int16_t FanAbnormalTempLimitOffset;
|
||||
uint16_t FanStalledTriggerRpm;
|
||||
uint16_t FanAbnormalTriggerRpm;
|
||||
uint16_t FanPadding;
|
||||
uint16_t FanAbnormalTriggerRpmCoeff;
|
||||
uint16_t FanAbnormalDetectionEnable;
|
||||
|
||||
uint32_t FanSpare[14];
|
||||
uint8_t FanIntakeSensorSupport;
|
||||
uint8_t FanIntakePadding[3];
|
||||
uint32_t FanSpare[13];
|
||||
|
||||
// SECTION: VDD_GFX AVFS
|
||||
|
||||
@@ -1198,8 +1239,13 @@ typedef struct {
|
||||
int16_t TotalBoardPowerM;
|
||||
int16_t TotalBoardPowerB;
|
||||
|
||||
//PMFW-11158
|
||||
QuadraticInt_t qFeffCoeffGameClock[POWER_SOURCE_COUNT];
|
||||
QuadraticInt_t qFeffCoeffBaseClock[POWER_SOURCE_COUNT];
|
||||
QuadraticInt_t qFeffCoeffBoostClock[POWER_SOURCE_COUNT];
|
||||
|
||||
// SECTION: Sku Reserved
|
||||
uint32_t Spare[61];
|
||||
uint32_t Spare[43];
|
||||
|
||||
// Padding for MMHUB - do not modify this
|
||||
uint32_t MmHubPadding[8];
|
||||
@@ -1288,8 +1334,11 @@ typedef struct {
|
||||
uint32_t PostVoltageSetBacoDelay; // in microseconds. Amount of time FW will wait after power good is established or PSI0 command is issued
|
||||
uint32_t BacoEntryDelay; // in milliseconds. Amount of time FW will wait to trigger BACO entry after receiving entry notification from OS
|
||||
|
||||
uint8_t FuseWritePowerMuxPresent;
|
||||
uint8_t FuseWritePadding[3];
|
||||
|
||||
// SECTION: Board Reserved
|
||||
uint32_t BoardSpare[64];
|
||||
uint32_t BoardSpare[63];
|
||||
|
||||
// SECTION: Structure Padding
|
||||
|
||||
@@ -1381,7 +1430,7 @@ typedef struct {
|
||||
uint16_t AverageTotalBoardPower;
|
||||
|
||||
uint16_t AvgTemperature[TEMP_COUNT];
|
||||
uint16_t TempPadding;
|
||||
uint16_t AvgTemperatureFanIntake;
|
||||
|
||||
uint8_t PcieRate ;
|
||||
uint8_t PcieWidth ;
|
||||
@@ -1550,5 +1599,7 @@ typedef struct {
|
||||
#define IH_INTERRUPT_CONTEXT_ID_AUDIO_D0 0x5
|
||||
#define IH_INTERRUPT_CONTEXT_ID_AUDIO_D3 0x6
|
||||
#define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING 0x7
|
||||
#define IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL 0x8
|
||||
#define IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY 0x9
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#define SMU13_DRIVER_IF_VERSION_ALDE 0x08
|
||||
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07
|
||||
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
|
||||
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0 0x30
|
||||
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32
|
||||
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x2C
|
||||
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_10 0x1D
|
||||
|
||||
|
||||
@@ -289,7 +289,8 @@ int smu_v13_0_check_fw_version(struct smu_context *smu)
|
||||
smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_ALDE;
|
||||
break;
|
||||
case IP_VERSION(13, 0, 0):
|
||||
smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0;
|
||||
case IP_VERSION(13, 0, 10):
|
||||
smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10;
|
||||
break;
|
||||
case IP_VERSION(13, 0, 7):
|
||||
smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_7;
|
||||
@@ -305,9 +306,6 @@ int smu_v13_0_check_fw_version(struct smu_context *smu)
|
||||
case IP_VERSION(13, 0, 5):
|
||||
smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_5;
|
||||
break;
|
||||
case IP_VERSION(13, 0, 10):
|
||||
smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_10;
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev, "smu unsupported IP version: 0x%x.\n",
|
||||
adev->ip_versions[MP1_HWIP][0]);
|
||||
@@ -842,6 +840,7 @@ int smu_v13_0_gfx_off_control(struct smu_context *smu, bool enable)
|
||||
case IP_VERSION(13, 0, 5):
|
||||
case IP_VERSION(13, 0, 7):
|
||||
case IP_VERSION(13, 0, 8):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
|
||||
return 0;
|
||||
if (enable)
|
||||
|
||||
@@ -105,6 +105,7 @@ struct ps8640 {
|
||||
struct gpio_desc *gpio_powerdown;
|
||||
struct device_link *link;
|
||||
bool pre_enabled;
|
||||
bool need_post_hpd_delay;
|
||||
};
|
||||
|
||||
static const struct regmap_config ps8640_regmap_config[] = {
|
||||
@@ -173,14 +174,31 @@ static int _ps8640_wait_hpd_asserted(struct ps8640 *ps_bridge, unsigned long wai
|
||||
{
|
||||
struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
|
||||
int status;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Apparently something about the firmware in the chip signals that
|
||||
* HPD goes high by reporting GPIO9 as high (even though HPD isn't
|
||||
* actually connected to GPIO9).
|
||||
*/
|
||||
return regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
|
||||
status & PS_GPIO9, wait_us / 10, wait_us);
|
||||
ret = regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
|
||||
status & PS_GPIO9, wait_us / 10, wait_us);
|
||||
|
||||
/*
|
||||
* The first time we see HPD go high after a reset we delay an extra
|
||||
* 50 ms. The best guess is that the MCU is doing "stuff" during this
|
||||
* time (maybe talking to the panel) and we don't want to interrupt it.
|
||||
*
|
||||
* No locking is done around "need_post_hpd_delay". If we're here we
|
||||
* know we're holding a PM Runtime reference and the only other place
|
||||
* that touches this is PM Runtime resume.
|
||||
*/
|
||||
if (!ret && ps_bridge->need_post_hpd_delay) {
|
||||
ps_bridge->need_post_hpd_delay = false;
|
||||
msleep(50);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ps8640_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long wait_us)
|
||||
@@ -381,6 +399,9 @@ static int __maybe_unused ps8640_resume(struct device *dev)
|
||||
msleep(50);
|
||||
gpiod_set_value(ps_bridge->gpio_reset, 0);
|
||||
|
||||
/* We just reset things, so we need a delay after the first HPD */
|
||||
ps_bridge->need_post_hpd_delay = true;
|
||||
|
||||
/*
|
||||
* Mystery 200 ms delay for the "MCU to be ready". It's unclear if
|
||||
* this is truly necessary since the MCU will already signal that
|
||||
|
||||
@@ -3957,6 +3957,8 @@ intel_dp_handle_hdmi_link_status_change(struct intel_dp *intel_dp)
|
||||
|
||||
drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, &intel_dp->attached_connector->base);
|
||||
|
||||
intel_dp->frl.is_trained = false;
|
||||
|
||||
/* Restart FRL training or fall back to TMDS mode */
|
||||
intel_dp_check_frl_training(intel_dp);
|
||||
}
|
||||
|
||||
@@ -2293,11 +2293,11 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
|
||||
}
|
||||
|
||||
if (IS_DG1_GRAPHICS_STEP(i915, STEP_A0, STEP_B0) ||
|
||||
IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
|
||||
IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915) || IS_ALDERLAKE_P(i915)) {
|
||||
/*
|
||||
* Wa_1607030317:tgl
|
||||
* Wa_1607186500:tgl
|
||||
* Wa_1607297627:tgl,rkl,dg1[a0]
|
||||
* Wa_1607297627:tgl,rkl,dg1[a0],adlp
|
||||
*
|
||||
* On TGL and RKL there are multiple entries for this WA in the
|
||||
* BSpec; some indicate this is an A0-only WA, others indicate
|
||||
|
||||
@@ -591,8 +591,15 @@ void intel_runtime_pm_enable(struct intel_runtime_pm *rpm)
|
||||
pm_runtime_use_autosuspend(kdev);
|
||||
}
|
||||
|
||||
/* Enable by default */
|
||||
pm_runtime_allow(kdev);
|
||||
/*
|
||||
* FIXME: Temp hammer to keep autosupend disable on lmem supported platforms.
|
||||
* As per PCIe specs 5.3.1.4.1, all iomem read write request over a PCIe
|
||||
* function will be unsupported in case PCIe endpoint function is in D3.
|
||||
* Let's keep i915 autosuspend control 'on' till we fix all known issue
|
||||
* with lmem access in D3.
|
||||
*/
|
||||
if (!IS_DGFX(i915))
|
||||
pm_runtime_allow(kdev);
|
||||
|
||||
/*
|
||||
* The core calls the driver load handler with an RPM reference held.
|
||||
|
||||
@@ -155,7 +155,7 @@ config DRM_MSM_HDMI
|
||||
Compile in support for the HDMI output MSM DRM driver. It can
|
||||
be a primary or a secondary display on device. Note that this is used
|
||||
only for the direct HDMI output. If the device outputs HDMI data
|
||||
throught some kind of DSI-to-HDMI bridge, this option can be disabled.
|
||||
through some kind of DSI-to-HDMI bridge, this option can be disabled.
|
||||
|
||||
config DRM_MSM_HDMI_HDCP
|
||||
bool "Enable HDMI HDCP support in MSM DRM driver"
|
||||
|
||||
@@ -91,7 +91,7 @@ struct a6xx_state_memobj {
|
||||
static void *state_kcalloc(struct a6xx_gpu_state *a6xx_state, int nr, size_t objsize)
|
||||
{
|
||||
struct a6xx_state_memobj *obj =
|
||||
kzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL);
|
||||
kvzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL);
|
||||
|
||||
if (!obj)
|
||||
return NULL;
|
||||
@@ -813,6 +813,9 @@ static struct msm_gpu_state_bo *a6xx_snapshot_gmu_bo(
|
||||
{
|
||||
struct msm_gpu_state_bo *snapshot;
|
||||
|
||||
if (!bo->size)
|
||||
return NULL;
|
||||
|
||||
snapshot = state_kcalloc(a6xx_state, 1, sizeof(*snapshot));
|
||||
if (!snapshot)
|
||||
return NULL;
|
||||
@@ -1040,8 +1043,13 @@ static void a6xx_gpu_state_destroy(struct kref *kref)
|
||||
if (a6xx_state->gmu_hfi)
|
||||
kvfree(a6xx_state->gmu_hfi->data);
|
||||
|
||||
list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node)
|
||||
kfree(obj);
|
||||
if (a6xx_state->gmu_debug)
|
||||
kvfree(a6xx_state->gmu_debug->data);
|
||||
|
||||
list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node) {
|
||||
list_del(&obj->node);
|
||||
kvfree(obj);
|
||||
}
|
||||
|
||||
adreno_gpu_state_destroy(state);
|
||||
kfree(a6xx_state);
|
||||
|
||||
@@ -679,6 +679,9 @@ static int adreno_system_suspend(struct device *dev)
|
||||
struct msm_gpu *gpu = dev_to_gpu(dev);
|
||||
int remaining, ret;
|
||||
|
||||
if (!gpu)
|
||||
return 0;
|
||||
|
||||
suspend_scheduler(gpu);
|
||||
|
||||
remaining = wait_event_timeout(gpu->retire_event,
|
||||
@@ -700,7 +703,12 @@ out:
|
||||
|
||||
static int adreno_system_resume(struct device *dev)
|
||||
{
|
||||
resume_scheduler(dev_to_gpu(dev));
|
||||
struct msm_gpu *gpu = dev_to_gpu(dev);
|
||||
|
||||
if (!gpu)
|
||||
return 0;
|
||||
|
||||
resume_scheduler(gpu);
|
||||
return pm_runtime_force_resume(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -729,7 +729,12 @@ static char *adreno_gpu_ascii85_encode(u32 *src, size_t len)
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* len is expected to be in bytes */
|
||||
/* len is expected to be in bytes
|
||||
*
|
||||
* WARNING: *ptr should be allocated with kvmalloc or friends. It can be free'd
|
||||
* with kvfree() and replaced with a newly kvmalloc'd buffer on the first call
|
||||
* when the unencoded raw data is encoded
|
||||
*/
|
||||
void adreno_show_object(struct drm_printer *p, void **ptr, int len,
|
||||
bool *encoded)
|
||||
{
|
||||
|
||||
@@ -56,8 +56,9 @@ static int mdp4_lvds_connector_get_modes(struct drm_connector *connector)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
static enum drm_mode_status
|
||||
mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct mdp4_lvds_connector *mdp4_lvds_connector =
|
||||
to_mdp4_lvds_connector(connector);
|
||||
|
||||
@@ -1243,8 +1243,7 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
|
||||
{
|
||||
int ret = 0;
|
||||
const u8 *dpcd = ctrl->panel->dpcd;
|
||||
u8 encoding = DP_SET_ANSI_8B10B;
|
||||
u8 ssc;
|
||||
u8 encoding[] = { 0, DP_SET_ANSI_8B10B };
|
||||
u8 assr;
|
||||
struct dp_link_info link_info = {0};
|
||||
|
||||
@@ -1256,13 +1255,11 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
|
||||
|
||||
dp_aux_link_configure(ctrl->aux, &link_info);
|
||||
|
||||
if (drm_dp_max_downspread(dpcd)) {
|
||||
ssc = DP_SPREAD_AMP_0_5;
|
||||
drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, &ssc, 1);
|
||||
}
|
||||
if (drm_dp_max_downspread(dpcd))
|
||||
encoding[0] |= DP_SPREAD_AMP_0_5;
|
||||
|
||||
drm_dp_dpcd_write(ctrl->aux, DP_MAIN_LINK_CHANNEL_CODING_SET,
|
||||
&encoding, 1);
|
||||
/* config DOWNSPREAD_CTRL and MAIN_LINK_CHANNEL_CODING_SET */
|
||||
drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, encoding, 2);
|
||||
|
||||
if (drm_dp_alternate_scrambler_reset_cap(dpcd)) {
|
||||
assr = DP_ALTERNATE_SCRAMBLER_RESET_ENABLE;
|
||||
|
||||
@@ -1249,7 +1249,7 @@ int dp_display_request_irq(struct msm_dp *dp_display)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = devm_request_irq(&dp->pdev->dev, dp->irq,
|
||||
rc = devm_request_irq(dp_display->drm_dev->dev, dp->irq,
|
||||
dp_display_irq_handler,
|
||||
IRQF_TRIGGER_HIGH, "dp_display_isr", dp);
|
||||
if (rc < 0) {
|
||||
@@ -1528,6 +1528,11 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
|
||||
}
|
||||
}
|
||||
|
||||
static void of_dp_aux_depopulate_bus_void(void *data)
|
||||
{
|
||||
of_dp_aux_depopulate_bus(data);
|
||||
}
|
||||
|
||||
static int dp_display_get_next_bridge(struct msm_dp *dp)
|
||||
{
|
||||
int rc;
|
||||
@@ -1552,10 +1557,16 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
|
||||
* panel driver is probed asynchronously but is the best we
|
||||
* can do without a bigger driver reorganization.
|
||||
*/
|
||||
rc = devm_of_dp_aux_populate_ep_devices(dp_priv->aux);
|
||||
rc = of_dp_aux_populate_bus(dp_priv->aux, NULL);
|
||||
of_node_put(aux_bus);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
rc = devm_add_action_or_reset(dp->drm_dev->dev,
|
||||
of_dp_aux_depopulate_bus_void,
|
||||
dp_priv->aux);
|
||||
if (rc)
|
||||
goto error;
|
||||
} else if (dp->is_edp) {
|
||||
DRM_ERROR("eDP aux_bus not found\n");
|
||||
return -ENODEV;
|
||||
@@ -1568,7 +1579,7 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
|
||||
* For DisplayPort interfaces external bridges are optional, so
|
||||
* silently ignore an error if one is not present (-ENODEV).
|
||||
*/
|
||||
rc = dp_parser_find_next_bridge(dp_priv->parser);
|
||||
rc = devm_dp_parser_find_next_bridge(dp->drm_dev->dev, dp_priv->parser);
|
||||
if (!dp->is_edp && rc == -ENODEV)
|
||||
return 0;
|
||||
|
||||
@@ -1597,6 +1608,12 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
|
||||
return -EINVAL;
|
||||
|
||||
priv = dev->dev_private;
|
||||
|
||||
if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
|
||||
DRM_DEV_ERROR(dev->dev, "too many bridges\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
dp_display->drm_dev = dev;
|
||||
|
||||
dp_priv = container_of(dp_display, struct dp_display_private, dp_display);
|
||||
|
||||
@@ -31,6 +31,36 @@ static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
|
||||
connector_status_disconnected;
|
||||
}
|
||||
|
||||
static int dp_bridge_atomic_check(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *bridge_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct msm_dp *dp;
|
||||
|
||||
dp = to_dp_bridge(bridge)->dp_display;
|
||||
|
||||
drm_dbg_dp(dp->drm_dev, "is_connected = %s\n",
|
||||
(dp->is_connected) ? "true" : "false");
|
||||
|
||||
/*
|
||||
* There is no protection in the DRM framework to check if the display
|
||||
* pipeline has been already disabled before trying to disable it again.
|
||||
* Hence if the sink is unplugged, the pipeline gets disabled, but the
|
||||
* crtc->active is still true. Any attempt to set the mode or manually
|
||||
* disable this encoder will result in the crash.
|
||||
*
|
||||
* TODO: add support for telling the DRM subsystem that the pipeline is
|
||||
* disabled by the hardware and thus all access to it should be forbidden.
|
||||
* After that this piece of code can be removed.
|
||||
*/
|
||||
if (bridge->ops & DRM_BRIDGE_OP_HPD)
|
||||
return (dp->is_connected) ? 0 : -ENOTCONN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
|
||||
* @bridge: Poiner to drm bridge
|
||||
@@ -61,6 +91,9 @@ static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs dp_bridge_ops = {
|
||||
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
|
||||
.atomic_reset = drm_atomic_helper_bridge_reset,
|
||||
.enable = dp_bridge_enable,
|
||||
.disable = dp_bridge_disable,
|
||||
.post_disable = dp_bridge_post_disable,
|
||||
@@ -68,6 +101,7 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
|
||||
.mode_valid = dp_bridge_mode_valid,
|
||||
.get_modes = dp_bridge_get_modes,
|
||||
.detect = dp_bridge_detect,
|
||||
.atomic_check = dp_bridge_atomic_check,
|
||||
};
|
||||
|
||||
struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
|
||||
|
||||
@@ -240,12 +240,12 @@ static int dp_parser_clock(struct dp_parser *parser)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dp_parser_find_next_bridge(struct dp_parser *parser)
|
||||
int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser)
|
||||
{
|
||||
struct device *dev = &parser->pdev->dev;
|
||||
struct platform_device *pdev = parser->pdev;
|
||||
struct drm_bridge *bridge;
|
||||
|
||||
bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
|
||||
bridge = devm_drm_of_get_bridge(dev, pdev->dev.of_node, 1, 0);
|
||||
if (IS_ERR(bridge))
|
||||
return PTR_ERR(bridge);
|
||||
|
||||
|
||||
@@ -138,8 +138,9 @@ struct dp_parser {
|
||||
struct dp_parser *dp_parser_get(struct platform_device *pdev);
|
||||
|
||||
/**
|
||||
* dp_parser_find_next_bridge() - find an additional bridge to DP
|
||||
* devm_dp_parser_find_next_bridge() - find an additional bridge to DP
|
||||
*
|
||||
* @dev: device to tie bridge lifetime to
|
||||
* @parser: dp_parser data from client
|
||||
*
|
||||
* This function is used to find any additional bridge attached to
|
||||
@@ -147,6 +148,6 @@ struct dp_parser *dp_parser_get(struct platform_device *pdev);
|
||||
*
|
||||
* Return: 0 if able to get the bridge, otherwise negative errno for failure.
|
||||
*/
|
||||
int dp_parser_find_next_bridge(struct dp_parser *parser);
|
||||
int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -218,6 +218,12 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
|
||||
return -EINVAL;
|
||||
|
||||
priv = dev->dev_private;
|
||||
|
||||
if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
|
||||
DRM_DEV_ERROR(dev->dev, "too many bridges\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
msm_dsi->dev = dev;
|
||||
|
||||
ret = msm_dsi_host_modeset_init(msm_dsi->host, dev);
|
||||
|
||||
@@ -300,6 +300,11 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
|
||||
struct platform_device *pdev = hdmi->pdev;
|
||||
int ret;
|
||||
|
||||
if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
|
||||
DRM_DEV_ERROR(dev->dev, "too many bridges\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
hdmi->dev = dev;
|
||||
hdmi->encoder = encoder;
|
||||
|
||||
@@ -339,7 +344,7 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, hdmi->irq,
|
||||
ret = devm_request_irq(dev->dev, hdmi->irq,
|
||||
msm_hdmi_irq, IRQF_TRIGGER_HIGH,
|
||||
"hdmi_isr", hdmi);
|
||||
if (ret < 0) {
|
||||
|
||||
@@ -247,6 +247,7 @@ static int msm_drm_uninit(struct device *dev)
|
||||
|
||||
for (i = 0; i < priv->num_bridges; i++)
|
||||
drm_bridge_remove(priv->bridges[i]);
|
||||
priv->num_bridges = 0;
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
msm_irq_uninstall(ddev);
|
||||
|
||||
@@ -501,11 +501,11 @@ out:
|
||||
*/
|
||||
static void submit_cleanup(struct msm_gem_submit *submit, bool error)
|
||||
{
|
||||
unsigned cleanup_flags = BO_LOCKED | BO_OBJ_PINNED;
|
||||
unsigned cleanup_flags = BO_LOCKED;
|
||||
unsigned i;
|
||||
|
||||
if (error)
|
||||
cleanup_flags |= BO_VMA_PINNED;
|
||||
cleanup_flags |= BO_VMA_PINNED | BO_OBJ_PINNED;
|
||||
|
||||
for (i = 0; i < submit->nr_bos; i++) {
|
||||
struct msm_gem_object *msm_obj = submit->bos[i].obj;
|
||||
@@ -706,7 +706,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
struct drm_msm_gem_submit *args = data;
|
||||
struct msm_file_private *ctx = file->driver_priv;
|
||||
struct msm_gem_submit *submit = NULL;
|
||||
struct msm_gem_submit *submit;
|
||||
struct msm_gpu *gpu = priv->gpu;
|
||||
struct msm_gpu_submitqueue *queue;
|
||||
struct msm_ringbuffer *ring;
|
||||
@@ -946,8 +946,7 @@ out_unlock:
|
||||
put_unused_fd(out_fence_fd);
|
||||
mutex_unlock(&queue->lock);
|
||||
out_post_unlock:
|
||||
if (submit)
|
||||
msm_gem_submit_put(submit);
|
||||
msm_gem_submit_put(submit);
|
||||
if (!IS_ERR_OR_NULL(post_deps)) {
|
||||
for (i = 0; i < args->nr_out_syncobjs; ++i) {
|
||||
kfree(post_deps[i].chain);
|
||||
|
||||
@@ -997,4 +997,6 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
|
||||
}
|
||||
|
||||
msm_devfreq_cleanup(gpu);
|
||||
|
||||
platform_set_drvdata(gpu->pdev, NULL);
|
||||
}
|
||||
|
||||
@@ -280,6 +280,10 @@ struct msm_gpu {
|
||||
static inline struct msm_gpu *dev_to_gpu(struct device *dev)
|
||||
{
|
||||
struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(dev);
|
||||
|
||||
if (!adreno_smmu)
|
||||
return NULL;
|
||||
|
||||
return container_of(adreno_smmu, struct msm_gpu, adreno_smmu);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ static struct dma_fence *msm_job_run(struct drm_sched_job *job)
|
||||
|
||||
msm_gem_lock(obj);
|
||||
msm_gem_unpin_vma_fenced(submit->bos[i].vma, fctx);
|
||||
submit->bos[i].flags &= ~BO_VMA_PINNED;
|
||||
msm_gem_unpin_locked(obj);
|
||||
submit->bos[i].flags &= ~(BO_VMA_PINNED | BO_OBJ_PINNED);
|
||||
msm_gem_unlock(obj);
|
||||
}
|
||||
|
||||
|
||||
@@ -207,6 +207,7 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
|
||||
struct drm_sched_job *job = container_of(cb, struct drm_sched_job,
|
||||
finish_cb);
|
||||
|
||||
dma_fence_put(f);
|
||||
INIT_WORK(&job->work, drm_sched_entity_kill_jobs_work);
|
||||
schedule_work(&job->work);
|
||||
}
|
||||
@@ -234,8 +235,10 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity)
|
||||
struct drm_sched_fence *s_fence = job->s_fence;
|
||||
|
||||
/* Wait for all dependencies to avoid data corruptions */
|
||||
while ((f = drm_sched_job_dependency(job, entity)))
|
||||
while ((f = drm_sched_job_dependency(job, entity))) {
|
||||
dma_fence_wait(f, false);
|
||||
dma_fence_put(f);
|
||||
}
|
||||
|
||||
drm_sched_fence_scheduled(s_fence);
|
||||
dma_fence_set_error(&s_fence->finished, -ESRCH);
|
||||
@@ -250,6 +253,7 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity)
|
||||
continue;
|
||||
}
|
||||
|
||||
dma_fence_get(entity->last_scheduled);
|
||||
r = dma_fence_add_callback(entity->last_scheduled,
|
||||
&job->finish_cb,
|
||||
drm_sched_entity_kill_jobs_cb);
|
||||
|
||||
@@ -339,6 +339,28 @@ static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a
|
||||
return vivid_vid_out_g_fbuf(file, fh, a);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only support the framebuffer of one of the vivid instances.
|
||||
* Anything else is rejected.
|
||||
*/
|
||||
bool vivid_validate_fb(const struct v4l2_framebuffer *a)
|
||||
{
|
||||
struct vivid_dev *dev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_devs; i++) {
|
||||
dev = vivid_devs[i];
|
||||
if (!dev || !dev->video_pbase)
|
||||
continue;
|
||||
if ((unsigned long)a->base == dev->video_pbase &&
|
||||
a->fmt.width <= dev->display_width &&
|
||||
a->fmt.height <= dev->display_height &&
|
||||
a->fmt.bytesperline <= dev->display_byte_stride)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
@@ -920,8 +942,12 @@ static int vivid_detect_feature_set(struct vivid_dev *dev, int inst,
|
||||
|
||||
/* how many inputs do we have and of what type? */
|
||||
dev->num_inputs = num_inputs[inst];
|
||||
if (dev->num_inputs < 1)
|
||||
dev->num_inputs = 1;
|
||||
if (node_type & 0x20007) {
|
||||
if (dev->num_inputs < 1)
|
||||
dev->num_inputs = 1;
|
||||
} else {
|
||||
dev->num_inputs = 0;
|
||||
}
|
||||
if (dev->num_inputs >= MAX_INPUTS)
|
||||
dev->num_inputs = MAX_INPUTS;
|
||||
for (i = 0; i < dev->num_inputs; i++) {
|
||||
@@ -938,8 +964,12 @@ static int vivid_detect_feature_set(struct vivid_dev *dev, int inst,
|
||||
|
||||
/* how many outputs do we have and of what type? */
|
||||
dev->num_outputs = num_outputs[inst];
|
||||
if (dev->num_outputs < 1)
|
||||
dev->num_outputs = 1;
|
||||
if (node_type & 0x40300) {
|
||||
if (dev->num_outputs < 1)
|
||||
dev->num_outputs = 1;
|
||||
} else {
|
||||
dev->num_outputs = 0;
|
||||
}
|
||||
if (dev->num_outputs >= MAX_OUTPUTS)
|
||||
dev->num_outputs = MAX_OUTPUTS;
|
||||
for (i = 0; i < dev->num_outputs; i++) {
|
||||
|
||||
@@ -613,4 +613,6 @@ static inline bool vivid_is_hdmi_out(const struct vivid_dev *dev)
|
||||
return dev->output_type[dev->output] == HDMI;
|
||||
}
|
||||
|
||||
bool vivid_validate_fb(const struct v4l2_framebuffer *a);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -357,7 +357,7 @@ int vivid_fb_init(struct vivid_dev *dev)
|
||||
int ret;
|
||||
|
||||
dev->video_buffer_size = MAX_OSD_HEIGHT * MAX_OSD_WIDTH * 2;
|
||||
dev->video_vbase = kzalloc(dev->video_buffer_size, GFP_KERNEL | GFP_DMA32);
|
||||
dev->video_vbase = kzalloc(dev->video_buffer_size, GFP_KERNEL);
|
||||
if (dev->video_vbase == NULL)
|
||||
return -ENOMEM;
|
||||
dev->video_pbase = virt_to_phys(dev->video_vbase);
|
||||
|
||||
@@ -453,6 +453,12 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)
|
||||
tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap);
|
||||
dev->crop_cap = dev->src_rect;
|
||||
dev->crop_bounds_cap = dev->src_rect;
|
||||
if (dev->bitmap_cap &&
|
||||
(dev->compose_cap.width != dev->crop_cap.width ||
|
||||
dev->compose_cap.height != dev->crop_cap.height)) {
|
||||
vfree(dev->bitmap_cap);
|
||||
dev->bitmap_cap = NULL;
|
||||
}
|
||||
dev->compose_cap = dev->crop_cap;
|
||||
if (V4L2_FIELD_HAS_T_OR_B(dev->field_cap))
|
||||
dev->compose_cap.height /= 2;
|
||||
@@ -460,6 +466,14 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)
|
||||
tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
|
||||
tpg_s_pixel_aspect(&dev->tpg, vivid_get_pixel_aspect(dev));
|
||||
tpg_update_mv_step(&dev->tpg);
|
||||
|
||||
/*
|
||||
* We can be called from within s_ctrl, in that case we can't
|
||||
* modify controls. Luckily we don't need to in that case.
|
||||
*/
|
||||
if (keep_controls)
|
||||
return;
|
||||
|
||||
dims[0] = roundup(dev->src_rect.width, PIXEL_ARRAY_DIV);
|
||||
dims[1] = roundup(dev->src_rect.height, PIXEL_ARRAY_DIV);
|
||||
v4l2_ctrl_modify_dimensions(dev->pixel_array, dims);
|
||||
@@ -913,6 +927,8 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
|
||||
struct vivid_dev *dev = video_drvdata(file);
|
||||
struct v4l2_rect *crop = &dev->crop_cap;
|
||||
struct v4l2_rect *compose = &dev->compose_cap;
|
||||
unsigned orig_compose_w = compose->width;
|
||||
unsigned orig_compose_h = compose->height;
|
||||
unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;
|
||||
int ret;
|
||||
|
||||
@@ -1029,17 +1045,17 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
|
||||
s->r.height /= factor;
|
||||
}
|
||||
v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect);
|
||||
if (dev->bitmap_cap && (compose->width != s->r.width ||
|
||||
compose->height != s->r.height)) {
|
||||
vfree(dev->bitmap_cap);
|
||||
dev->bitmap_cap = NULL;
|
||||
}
|
||||
*compose = s->r;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dev->bitmap_cap && (compose->width != orig_compose_w ||
|
||||
compose->height != orig_compose_h)) {
|
||||
vfree(dev->bitmap_cap);
|
||||
dev->bitmap_cap = NULL;
|
||||
}
|
||||
tpg_s_crop_compose(&dev->tpg, crop, compose);
|
||||
return 0;
|
||||
}
|
||||
@@ -1276,7 +1292,14 @@ int vivid_vid_cap_s_fbuf(struct file *file, void *fh,
|
||||
return -EINVAL;
|
||||
if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8)
|
||||
return -EINVAL;
|
||||
if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage)
|
||||
if (a->fmt.bytesperline > a->fmt.sizeimage / a->fmt.height)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Only support the framebuffer of one of the vivid instances.
|
||||
* Anything else is rejected.
|
||||
*/
|
||||
if (!vivid_validate_fb(a))
|
||||
return -EINVAL;
|
||||
|
||||
dev->fb_vbase_cap = phys_to_virt((unsigned long)a->base);
|
||||
|
||||
@@ -161,6 +161,20 @@ bool v4l2_valid_dv_timings(const struct v4l2_dv_timings *t,
|
||||
(bt->interlaced && !(caps & V4L2_DV_BT_CAP_INTERLACED)) ||
|
||||
(!bt->interlaced && !(caps & V4L2_DV_BT_CAP_PROGRESSIVE)))
|
||||
return false;
|
||||
|
||||
/* sanity checks for the blanking timings */
|
||||
if (!bt->interlaced &&
|
||||
(bt->il_vbackporch || bt->il_vsync || bt->il_vfrontporch))
|
||||
return false;
|
||||
if (bt->hfrontporch > 2 * bt->width ||
|
||||
bt->hsync > 1024 || bt->hbackporch > 1024)
|
||||
return false;
|
||||
if (bt->vfrontporch > 4096 ||
|
||||
bt->vsync > 128 || bt->vbackporch > 4096)
|
||||
return false;
|
||||
if (bt->interlaced && (bt->il_vfrontporch > 4096 ||
|
||||
bt->il_vsync > 128 || bt->il_vbackporch > 4096))
|
||||
return false;
|
||||
return fnc == NULL || fnc(t, fnc_handle);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_valid_dv_timings);
|
||||
|
||||
@@ -134,6 +134,7 @@ struct mmc_blk_data {
|
||||
* track of the current selected device partition.
|
||||
*/
|
||||
unsigned int part_curr;
|
||||
#define MMC_BLK_PART_INVALID UINT_MAX /* Unknown partition active */
|
||||
int area_type;
|
||||
|
||||
/* debugfs files (only in main mmc_blk_data) */
|
||||
@@ -987,33 +988,39 @@ static unsigned int mmc_blk_data_timeout_ms(struct mmc_host *host,
|
||||
return ms;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempts to reset the card and get back to the requested partition.
|
||||
* Therefore any error here must result in cancelling the block layer
|
||||
* request, it must not be reattempted without going through the mmc_blk
|
||||
* partition sanity checks.
|
||||
*/
|
||||
static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
|
||||
int type)
|
||||
{
|
||||
int err;
|
||||
struct mmc_blk_data *main_md = dev_get_drvdata(&host->card->dev);
|
||||
|
||||
if (md->reset_done & type)
|
||||
return -EEXIST;
|
||||
|
||||
md->reset_done |= type;
|
||||
err = mmc_hw_reset(host->card);
|
||||
/*
|
||||
* A successful reset will leave the card in the main partition, but
|
||||
* upon failure it might not be, so set it to MMC_BLK_PART_INVALID
|
||||
* in that case.
|
||||
*/
|
||||
main_md->part_curr = err ? MMC_BLK_PART_INVALID : main_md->part_type;
|
||||
if (err)
|
||||
return err;
|
||||
/* Ensure we switch back to the correct partition */
|
||||
if (err) {
|
||||
struct mmc_blk_data *main_md =
|
||||
dev_get_drvdata(&host->card->dev);
|
||||
int part_err;
|
||||
|
||||
main_md->part_curr = main_md->part_type;
|
||||
part_err = mmc_blk_part_switch(host->card, md->part_type);
|
||||
if (part_err) {
|
||||
/*
|
||||
* We have failed to get back into the correct
|
||||
* partition, so we need to abort the whole request.
|
||||
*/
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
if (mmc_blk_part_switch(host->card, md->part_type))
|
||||
/*
|
||||
* We have failed to get back into the correct
|
||||
* partition, so we need to abort the whole request.
|
||||
*/
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type)
|
||||
@@ -1871,8 +1878,9 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
|
||||
return;
|
||||
|
||||
/* Reset before last retry */
|
||||
if (mqrq->retries + 1 == MMC_MAX_RETRIES)
|
||||
mmc_blk_reset(md, card->host, type);
|
||||
if (mqrq->retries + 1 == MMC_MAX_RETRIES &&
|
||||
mmc_blk_reset(md, card->host, type))
|
||||
return;
|
||||
|
||||
/* Command errors fail fast, so use all MMC_MAX_RETRIES */
|
||||
if (brq->sbc.error || brq->cmd.error)
|
||||
|
||||
@@ -48,6 +48,7 @@ static enum mmc_issue_type mmc_cqe_issue_type(struct mmc_host *host,
|
||||
case REQ_OP_DRV_OUT:
|
||||
case REQ_OP_DISCARD:
|
||||
case REQ_OP_SECURE_ERASE:
|
||||
case REQ_OP_WRITE_ZEROES:
|
||||
return MMC_ISSUE_SYNC;
|
||||
case REQ_OP_FLUSH:
|
||||
return mmc_cqe_can_dcmd(host) ? MMC_ISSUE_DCMD : MMC_ISSUE_SYNC;
|
||||
@@ -493,6 +494,13 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
|
||||
if (blk_queue_quiesced(q))
|
||||
blk_mq_unquiesce_queue(q);
|
||||
|
||||
/*
|
||||
* If the recovery completes the last (and only remaining) request in
|
||||
* the queue, and the card has been removed, we could end up here with
|
||||
* the recovery not quite finished yet, so cancel it.
|
||||
*/
|
||||
cancel_work_sync(&mq->recovery_work);
|
||||
|
||||
blk_mq_free_tag_set(&mq->tag_set);
|
||||
|
||||
/*
|
||||
|
||||
@@ -291,7 +291,8 @@ static void sdio_release_func(struct device *dev)
|
||||
{
|
||||
struct sdio_func *func = dev_to_sdio_func(dev);
|
||||
|
||||
sdio_free_func_cis(func);
|
||||
if (!(func->card->quirks & MMC_QUIRK_NONSTD_SDIO))
|
||||
sdio_free_func_cis(func);
|
||||
|
||||
kfree(func->info);
|
||||
kfree(func->tmpbuf);
|
||||
|
||||
@@ -1075,9 +1075,10 @@ config MMC_SDHCI_OMAP
|
||||
|
||||
config MMC_SDHCI_AM654
|
||||
tristate "Support for the SDHCI Controller in TI's AM654 SOCs"
|
||||
depends on MMC_SDHCI_PLTFM && OF && REGMAP_MMIO
|
||||
depends on MMC_SDHCI_PLTFM && OF
|
||||
select MMC_SDHCI_IO_ACCESSORS
|
||||
select MMC_CQHCI
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
This selects the Secure Digital Host Controller Interface (SDHCI)
|
||||
support present in TI's AM654 SOCs. The controller supports
|
||||
|
||||
@@ -1660,6 +1660,10 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
|
||||
host->mmc_host_ops.execute_tuning = usdhc_execute_tuning;
|
||||
}
|
||||
|
||||
err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
|
||||
if (err)
|
||||
goto disable_ahb_clk;
|
||||
|
||||
if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING)
|
||||
sdhci_esdhc_ops.platform_execute_tuning =
|
||||
esdhc_executing_tuning;
|
||||
@@ -1667,13 +1671,15 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
|
||||
if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
|
||||
host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
|
||||
|
||||
if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
|
||||
if (host->caps & MMC_CAP_8_BIT_DATA &&
|
||||
imx_data->socdata->flags & ESDHC_FLAG_HS400)
|
||||
host->mmc->caps2 |= MMC_CAP2_HS400;
|
||||
|
||||
if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23)
|
||||
host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN;
|
||||
|
||||
if (imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
|
||||
if (host->caps & MMC_CAP_8_BIT_DATA &&
|
||||
imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
|
||||
host->mmc->caps2 |= MMC_CAP2_HS400_ES;
|
||||
host->mmc_host_ops.hs400_enhanced_strobe =
|
||||
esdhc_hs400_enhanced_strobe;
|
||||
@@ -1695,10 +1701,6 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
|
||||
goto disable_ahb_clk;
|
||||
}
|
||||
|
||||
err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
|
||||
if (err)
|
||||
goto disable_ahb_clk;
|
||||
|
||||
sdhci_esdhc_imx_hwinit(host);
|
||||
|
||||
err = sdhci_add_host(host);
|
||||
|
||||
@@ -914,6 +914,12 @@ static bool glk_broken_cqhci(struct sdhci_pci_slot *slot)
|
||||
dmi_match(DMI_SYS_VENDOR, "IRBIS"));
|
||||
}
|
||||
|
||||
static bool jsl_broken_hs400es(struct sdhci_pci_slot *slot)
|
||||
{
|
||||
return slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_JSL_EMMC &&
|
||||
dmi_match(DMI_BIOS_VENDOR, "ASUSTeK COMPUTER INC.");
|
||||
}
|
||||
|
||||
static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot)
|
||||
{
|
||||
int ret = byt_emmc_probe_slot(slot);
|
||||
@@ -922,9 +928,11 @@ static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot)
|
||||
slot->host->mmc->caps2 |= MMC_CAP2_CQE;
|
||||
|
||||
if (slot->chip->pdev->device != PCI_DEVICE_ID_INTEL_GLK_EMMC) {
|
||||
slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES;
|
||||
slot->host->mmc_host_ops.hs400_enhanced_strobe =
|
||||
intel_hs400_enhanced_strobe;
|
||||
if (!jsl_broken_hs400es(slot)) {
|
||||
slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES;
|
||||
slot->host->mmc_host_ops.hs400_enhanced_strobe =
|
||||
intel_hs400_enhanced_strobe;
|
||||
}
|
||||
slot->host->mmc->caps2 |= MMC_CAP2_CQE_DCMD;
|
||||
}
|
||||
|
||||
|
||||
@@ -562,7 +562,7 @@ static void mtd_check_of_node(struct mtd_info *mtd)
|
||||
if (!mtd_is_partition(mtd))
|
||||
return;
|
||||
parent = mtd->parent;
|
||||
parent_dn = dev_of_node(&parent->dev);
|
||||
parent_dn = of_node_get(dev_of_node(&parent->dev));
|
||||
if (!parent_dn)
|
||||
return;
|
||||
|
||||
|
||||
@@ -608,11 +608,12 @@ static int ebu_nand_probe(struct platform_device *pdev)
|
||||
ret = of_property_read_u32(chip_np, "reg", &cs);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to get chip select: %d\n", ret);
|
||||
return ret;
|
||||
goto err_of_node_put;
|
||||
}
|
||||
if (cs >= MAX_CS) {
|
||||
dev_err(dev, "got invalid chip select: %d\n", cs);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto err_of_node_put;
|
||||
}
|
||||
|
||||
ebu_host->cs_num = cs;
|
||||
@@ -620,18 +621,22 @@ static int ebu_nand_probe(struct platform_device *pdev)
|
||||
resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs);
|
||||
ebu_host->cs[cs].chipaddr = devm_platform_ioremap_resource_byname(pdev,
|
||||
resname);
|
||||
if (IS_ERR(ebu_host->cs[cs].chipaddr))
|
||||
return PTR_ERR(ebu_host->cs[cs].chipaddr);
|
||||
if (IS_ERR(ebu_host->cs[cs].chipaddr)) {
|
||||
ret = PTR_ERR(ebu_host->cs[cs].chipaddr);
|
||||
goto err_of_node_put;
|
||||
}
|
||||
|
||||
ebu_host->clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(ebu_host->clk))
|
||||
return dev_err_probe(dev, PTR_ERR(ebu_host->clk),
|
||||
"failed to get clock\n");
|
||||
if (IS_ERR(ebu_host->clk)) {
|
||||
ret = dev_err_probe(dev, PTR_ERR(ebu_host->clk),
|
||||
"failed to get clock\n");
|
||||
goto err_of_node_put;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(ebu_host->clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable clock: %d\n", ret);
|
||||
return ret;
|
||||
goto err_of_node_put;
|
||||
}
|
||||
|
||||
ebu_host->dma_tx = dma_request_chan(dev, "tx");
|
||||
@@ -695,6 +700,8 @@ err_cleanup_dma:
|
||||
ebu_dma_cleanup(ebu_host);
|
||||
err_disable_unprepare_clk:
|
||||
clk_disable_unprepare(ebu_host->clk);
|
||||
err_of_node_put:
|
||||
of_node_put(chip_np);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2678,7 +2678,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
|
||||
chip->controller = &nfc->controller;
|
||||
nand_set_flash_node(chip, np);
|
||||
|
||||
if (!of_property_read_bool(np, "marvell,nand-keep-config"))
|
||||
if (of_property_read_bool(np, "marvell,nand-keep-config"))
|
||||
chip->options |= NAND_KEEP_TIMINGS;
|
||||
|
||||
mtd = nand_to_mtd(chip);
|
||||
|
||||
@@ -1181,7 +1181,7 @@ static int tegra_nand_probe(struct platform_device *pdev)
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
err = pm_runtime_resume_and_get(&pdev->dev);
|
||||
if (err)
|
||||
return err;
|
||||
goto err_dis_pm;
|
||||
|
||||
err = reset_control_reset(rst);
|
||||
if (err) {
|
||||
@@ -1215,6 +1215,8 @@ static int tegra_nand_probe(struct platform_device *pdev)
|
||||
err_put_pm:
|
||||
pm_runtime_put_sync_suspend(ctrl->dev);
|
||||
pm_runtime_force_suspend(ctrl->dev);
|
||||
err_dis_pm:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -233,11 +233,11 @@ static int bcm47xxpart_parse(struct mtd_info *master,
|
||||
}
|
||||
|
||||
/* Read middle of the block */
|
||||
err = mtd_read(master, offset + 0x8000, 0x4, &bytes_read,
|
||||
err = mtd_read(master, offset + (blocksize / 2), 0x4, &bytes_read,
|
||||
(uint8_t *)buf);
|
||||
if (err && !mtd_is_bitflip(err)) {
|
||||
pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
|
||||
offset + 0x8000, err);
|
||||
offset + (blocksize / 2), err);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -2724,7 +2724,9 @@ static int spi_nor_init(struct spi_nor *nor)
|
||||
*/
|
||||
WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
|
||||
"enabling reset hack; may not recover from unexpected reboots\n");
|
||||
return nor->params->set_4byte_addr_mode(nor, true);
|
||||
err = nor->params->set_4byte_addr_mode(nor, true);
|
||||
if (err && err != -ENOTSUPP)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -322,14 +322,14 @@ static int mpc5xxx_can_probe(struct platform_device *ofdev)
|
||||
&mscan_clksrc);
|
||||
if (!priv->can.clock.freq) {
|
||||
dev_err(&ofdev->dev, "couldn't get MSCAN clock properties\n");
|
||||
goto exit_free_mscan;
|
||||
goto exit_put_clock;
|
||||
}
|
||||
|
||||
err = register_mscandev(dev, mscan_clksrc);
|
||||
if (err) {
|
||||
dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
|
||||
DRV_NAME, err);
|
||||
goto exit_free_mscan;
|
||||
goto exit_put_clock;
|
||||
}
|
||||
|
||||
dev_info(&ofdev->dev, "MSCAN at 0x%p, irq %d, clock %d Hz\n",
|
||||
@@ -337,7 +337,9 @@ static int mpc5xxx_can_probe(struct platform_device *ofdev)
|
||||
|
||||
return 0;
|
||||
|
||||
exit_free_mscan:
|
||||
exit_put_clock:
|
||||
if (data->put_clock)
|
||||
data->put_clock(ofdev);
|
||||
free_candev(dev);
|
||||
exit_dispose_irq:
|
||||
irq_dispose_mapping(irq);
|
||||
|
||||
@@ -1157,11 +1157,13 @@ static void rcar_canfd_handle_global_receive(struct rcar_canfd_global *gpriv, u3
|
||||
{
|
||||
struct rcar_canfd_channel *priv = gpriv->ch[ch];
|
||||
u32 ridx = ch + RCANFD_RFFIFO_IDX;
|
||||
u32 sts;
|
||||
u32 sts, cc;
|
||||
|
||||
/* Handle Rx interrupts */
|
||||
sts = rcar_canfd_read(priv->base, RCANFD_RFSTS(gpriv, ridx));
|
||||
if (likely(sts & RCANFD_RFSTS_RFIF)) {
|
||||
cc = rcar_canfd_read(priv->base, RCANFD_RFCC(gpriv, ridx));
|
||||
if (likely(sts & RCANFD_RFSTS_RFIF &&
|
||||
cc & RCANFD_RFCC_RFIE)) {
|
||||
if (napi_schedule_prep(&priv->napi)) {
|
||||
/* Disable Rx FIFO interrupts */
|
||||
rcar_canfd_clear_bit(priv->base,
|
||||
@@ -1244,11 +1246,9 @@ static void rcar_canfd_handle_channel_tx(struct rcar_canfd_global *gpriv, u32 ch
|
||||
|
||||
static irqreturn_t rcar_canfd_channel_tx_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct rcar_canfd_global *gpriv = dev_id;
|
||||
u32 ch;
|
||||
struct rcar_canfd_channel *priv = dev_id;
|
||||
|
||||
for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels)
|
||||
rcar_canfd_handle_channel_tx(gpriv, ch);
|
||||
rcar_canfd_handle_channel_tx(priv->gpriv, priv->channel);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -1276,11 +1276,9 @@ static void rcar_canfd_handle_channel_err(struct rcar_canfd_global *gpriv, u32 c
|
||||
|
||||
static irqreturn_t rcar_canfd_channel_err_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct rcar_canfd_global *gpriv = dev_id;
|
||||
u32 ch;
|
||||
struct rcar_canfd_channel *priv = dev_id;
|
||||
|
||||
for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels)
|
||||
rcar_canfd_handle_channel_err(gpriv, ch);
|
||||
rcar_canfd_handle_channel_err(priv->gpriv, priv->channel);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -1721,6 +1719,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
|
||||
priv->ndev = ndev;
|
||||
priv->base = gpriv->base;
|
||||
priv->channel = ch;
|
||||
priv->gpriv = gpriv;
|
||||
priv->can.clock.freq = fcan_freq;
|
||||
dev_info(&pdev->dev, "can_clk rate is %u\n", priv->can.clock.freq);
|
||||
|
||||
@@ -1749,7 +1748,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
|
||||
}
|
||||
err = devm_request_irq(&pdev->dev, err_irq,
|
||||
rcar_canfd_channel_err_interrupt, 0,
|
||||
irq_name, gpriv);
|
||||
irq_name, priv);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "devm_request_irq CH Err(%d) failed, error %d\n",
|
||||
err_irq, err);
|
||||
@@ -1763,7 +1762,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
|
||||
}
|
||||
err = devm_request_irq(&pdev->dev, tx_irq,
|
||||
rcar_canfd_channel_tx_interrupt, 0,
|
||||
irq_name, gpriv);
|
||||
irq_name, priv);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "devm_request_irq Tx (%d) failed, error %d\n",
|
||||
tx_irq, err);
|
||||
@@ -1789,7 +1788,6 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
|
||||
|
||||
priv->can.do_set_mode = rcar_canfd_do_set_mode;
|
||||
priv->can.do_get_berr_counter = rcar_canfd_get_berr_counter;
|
||||
priv->gpriv = gpriv;
|
||||
SET_NETDEV_DEV(ndev, &pdev->dev);
|
||||
|
||||
netif_napi_add_weight(ndev, &priv->napi, rcar_canfd_rx_poll,
|
||||
|
||||
@@ -1415,11 +1415,14 @@ static int mcp251x_can_probe(struct spi_device *spi)
|
||||
|
||||
ret = mcp251x_gpio_setup(priv);
|
||||
if (ret)
|
||||
goto error_probe;
|
||||
goto out_unregister_candev;
|
||||
|
||||
netdev_info(net, "MCP%x successfully initialized.\n", priv->model);
|
||||
return 0;
|
||||
|
||||
out_unregister_candev:
|
||||
unregister_candev(net);
|
||||
|
||||
error_probe:
|
||||
destroy_workqueue(priv->wq);
|
||||
priv->wq = NULL;
|
||||
|
||||
@@ -1875,7 +1875,7 @@ static int kvaser_usb_hydra_start_chip(struct kvaser_usb_net_priv *priv)
|
||||
{
|
||||
int err;
|
||||
|
||||
init_completion(&priv->start_comp);
|
||||
reinit_completion(&priv->start_comp);
|
||||
|
||||
err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_START_CHIP_REQ,
|
||||
priv->channel);
|
||||
@@ -1893,7 +1893,7 @@ static int kvaser_usb_hydra_stop_chip(struct kvaser_usb_net_priv *priv)
|
||||
{
|
||||
int err;
|
||||
|
||||
init_completion(&priv->stop_comp);
|
||||
reinit_completion(&priv->stop_comp);
|
||||
|
||||
/* Make sure we do not report invalid BUS_OFF from CMD_CHIP_STATE_EVENT
|
||||
* see comment in kvaser_usb_hydra_update_state()
|
||||
|
||||
@@ -1320,7 +1320,7 @@ static int kvaser_usb_leaf_start_chip(struct kvaser_usb_net_priv *priv)
|
||||
{
|
||||
int err;
|
||||
|
||||
init_completion(&priv->start_comp);
|
||||
reinit_completion(&priv->start_comp);
|
||||
|
||||
err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_START_CHIP,
|
||||
priv->channel);
|
||||
@@ -1338,7 +1338,7 @@ static int kvaser_usb_leaf_stop_chip(struct kvaser_usb_net_priv *priv)
|
||||
{
|
||||
int err;
|
||||
|
||||
init_completion(&priv->stop_comp);
|
||||
reinit_completion(&priv->stop_comp);
|
||||
|
||||
err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP,
|
||||
priv->channel);
|
||||
|
||||
@@ -561,8 +561,6 @@ static netdev_tx_t bcm4908_enet_start_xmit(struct sk_buff *skb, struct net_devic
|
||||
|
||||
if (++ring->write_idx == ring->length - 1)
|
||||
ring->write_idx = 0;
|
||||
enet->netdev->stats.tx_bytes += skb->len;
|
||||
enet->netdev->stats.tx_packets++;
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
@@ -635,6 +633,7 @@ static int bcm4908_enet_poll_tx(struct napi_struct *napi, int weight)
|
||||
struct bcm4908_enet_dma_ring_bd *buf_desc;
|
||||
struct bcm4908_enet_dma_ring_slot *slot;
|
||||
struct device *dev = enet->dev;
|
||||
unsigned int bytes = 0;
|
||||
int handled = 0;
|
||||
|
||||
while (handled < weight && tx_ring->read_idx != tx_ring->write_idx) {
|
||||
@@ -645,12 +644,17 @@ static int bcm4908_enet_poll_tx(struct napi_struct *napi, int weight)
|
||||
|
||||
dma_unmap_single(dev, slot->dma_addr, slot->len, DMA_TO_DEVICE);
|
||||
dev_kfree_skb(slot->skb);
|
||||
if (++tx_ring->read_idx == tx_ring->length)
|
||||
tx_ring->read_idx = 0;
|
||||
|
||||
handled++;
|
||||
bytes += slot->len;
|
||||
|
||||
if (++tx_ring->read_idx == tx_ring->length)
|
||||
tx_ring->read_idx = 0;
|
||||
}
|
||||
|
||||
enet->netdev->stats.tx_packets += handled;
|
||||
enet->netdev->stats.tx_bytes += bytes;
|
||||
|
||||
if (handled < weight) {
|
||||
napi_complete_done(napi, handled);
|
||||
bcm4908_enet_dma_ring_intrs_on(enet, tx_ring);
|
||||
|
||||
@@ -1991,6 +1991,9 @@ static int bcm_sysport_open(struct net_device *dev)
|
||||
goto out_clk_disable;
|
||||
}
|
||||
|
||||
/* Indicate that the MAC is responsible for PHY PM */
|
||||
phydev->mac_managed_pm = true;
|
||||
|
||||
/* Reset house keeping link status */
|
||||
priv->old_duplex = -1;
|
||||
priv->old_link = -1;
|
||||
|
||||
@@ -2090,7 +2090,12 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
|
||||
else
|
||||
enetc_rxbdr_wr(hw, idx, ENETC_RBBSR, ENETC_RXB_DMA_SIZE);
|
||||
|
||||
/* Also prepare the consumer index in case page allocation never
|
||||
* succeeds. In that case, hardware will never advance producer index
|
||||
* to match consumer index, and will drop all frames.
|
||||
*/
|
||||
enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
|
||||
enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, 1);
|
||||
|
||||
/* enable Rx ints by setting pkt thr to 1 */
|
||||
enetc_rxbdr_wr(hw, idx, ENETC_RBICR0, ENETC_RBICR0_ICEN | 0x1);
|
||||
|
||||
@@ -2432,6 +2432,31 @@ static u32 fec_enet_register_offset[] = {
|
||||
IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR,
|
||||
IEEE_R_FDXFC, IEEE_R_OCTETS_OK
|
||||
};
|
||||
/* for i.MX6ul */
|
||||
static u32 fec_enet_register_offset_6ul[] = {
|
||||
FEC_IEVENT, FEC_IMASK, FEC_R_DES_ACTIVE_0, FEC_X_DES_ACTIVE_0,
|
||||
FEC_ECNTRL, FEC_MII_DATA, FEC_MII_SPEED, FEC_MIB_CTRLSTAT, FEC_R_CNTRL,
|
||||
FEC_X_CNTRL, FEC_ADDR_LOW, FEC_ADDR_HIGH, FEC_OPD, FEC_TXIC0, FEC_RXIC0,
|
||||
FEC_HASH_TABLE_HIGH, FEC_HASH_TABLE_LOW, FEC_GRP_HASH_TABLE_HIGH,
|
||||
FEC_GRP_HASH_TABLE_LOW, FEC_X_WMRK, FEC_R_DES_START_0,
|
||||
FEC_X_DES_START_0, FEC_R_BUFF_SIZE_0, FEC_R_FIFO_RSFL, FEC_R_FIFO_RSEM,
|
||||
FEC_R_FIFO_RAEM, FEC_R_FIFO_RAFL, FEC_RACC,
|
||||
RMON_T_DROP, RMON_T_PACKETS, RMON_T_BC_PKT, RMON_T_MC_PKT,
|
||||
RMON_T_CRC_ALIGN, RMON_T_UNDERSIZE, RMON_T_OVERSIZE, RMON_T_FRAG,
|
||||
RMON_T_JAB, RMON_T_COL, RMON_T_P64, RMON_T_P65TO127, RMON_T_P128TO255,
|
||||
RMON_T_P256TO511, RMON_T_P512TO1023, RMON_T_P1024TO2047,
|
||||
RMON_T_P_GTE2048, RMON_T_OCTETS,
|
||||
IEEE_T_DROP, IEEE_T_FRAME_OK, IEEE_T_1COL, IEEE_T_MCOL, IEEE_T_DEF,
|
||||
IEEE_T_LCOL, IEEE_T_EXCOL, IEEE_T_MACERR, IEEE_T_CSERR, IEEE_T_SQE,
|
||||
IEEE_T_FDXFC, IEEE_T_OCTETS_OK,
|
||||
RMON_R_PACKETS, RMON_R_BC_PKT, RMON_R_MC_PKT, RMON_R_CRC_ALIGN,
|
||||
RMON_R_UNDERSIZE, RMON_R_OVERSIZE, RMON_R_FRAG, RMON_R_JAB,
|
||||
RMON_R_RESVD_O, RMON_R_P64, RMON_R_P65TO127, RMON_R_P128TO255,
|
||||
RMON_R_P256TO511, RMON_R_P512TO1023, RMON_R_P1024TO2047,
|
||||
RMON_R_P_GTE2048, RMON_R_OCTETS,
|
||||
IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR,
|
||||
IEEE_R_FDXFC, IEEE_R_OCTETS_OK
|
||||
};
|
||||
#else
|
||||
static __u32 fec_enet_register_version = 1;
|
||||
static u32 fec_enet_register_offset[] = {
|
||||
@@ -2456,7 +2481,24 @@ static void fec_enet_get_regs(struct net_device *ndev,
|
||||
u32 *buf = (u32 *)regbuf;
|
||||
u32 i, off;
|
||||
int ret;
|
||||
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
|
||||
defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \
|
||||
defined(CONFIG_ARM64) || defined(CONFIG_COMPILE_TEST)
|
||||
u32 *reg_list;
|
||||
u32 reg_cnt;
|
||||
|
||||
if (!of_machine_is_compatible("fsl,imx6ul")) {
|
||||
reg_list = fec_enet_register_offset;
|
||||
reg_cnt = ARRAY_SIZE(fec_enet_register_offset);
|
||||
} else {
|
||||
reg_list = fec_enet_register_offset_6ul;
|
||||
reg_cnt = ARRAY_SIZE(fec_enet_register_offset_6ul);
|
||||
}
|
||||
#else
|
||||
/* coldfire */
|
||||
static u32 *reg_list = fec_enet_register_offset;
|
||||
static const u32 reg_cnt = ARRAY_SIZE(fec_enet_register_offset);
|
||||
#endif
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret < 0)
|
||||
return;
|
||||
@@ -2465,8 +2507,8 @@ static void fec_enet_get_regs(struct net_device *ndev,
|
||||
|
||||
memset(buf, 0, regs->len);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fec_enet_register_offset); i++) {
|
||||
off = fec_enet_register_offset[i];
|
||||
for (i = 0; i < reg_cnt; i++) {
|
||||
off = reg_list[i];
|
||||
|
||||
if ((off == FEC_R_BOUND || off == FEC_R_FSTART) &&
|
||||
!(fep->quirks & FEC_QUIRK_HAS_FRREG))
|
||||
|
||||
@@ -2900,6 +2900,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
|
||||
ret = of_device_register(&port->ofdev);
|
||||
if (ret) {
|
||||
pr_err("failed to register device. ret=%d\n", ret);
|
||||
put_device(&port->ofdev.dev);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@@ -3185,10 +3185,17 @@ static int i40e_get_rss_hash_opts(struct i40e_pf *pf, struct ethtool_rxnfc *cmd)
|
||||
|
||||
if (cmd->flow_type == TCP_V4_FLOW ||
|
||||
cmd->flow_type == UDP_V4_FLOW) {
|
||||
if (i_set & I40E_L3_SRC_MASK)
|
||||
cmd->data |= RXH_IP_SRC;
|
||||
if (i_set & I40E_L3_DST_MASK)
|
||||
cmd->data |= RXH_IP_DST;
|
||||
if (hw->mac.type == I40E_MAC_X722) {
|
||||
if (i_set & I40E_X722_L3_SRC_MASK)
|
||||
cmd->data |= RXH_IP_SRC;
|
||||
if (i_set & I40E_X722_L3_DST_MASK)
|
||||
cmd->data |= RXH_IP_DST;
|
||||
} else {
|
||||
if (i_set & I40E_L3_SRC_MASK)
|
||||
cmd->data |= RXH_IP_SRC;
|
||||
if (i_set & I40E_L3_DST_MASK)
|
||||
cmd->data |= RXH_IP_DST;
|
||||
}
|
||||
} else if (cmd->flow_type == TCP_V6_FLOW ||
|
||||
cmd->flow_type == UDP_V6_FLOW) {
|
||||
if (i_set & I40E_L3_V6_SRC_MASK)
|
||||
@@ -3546,12 +3553,15 @@ static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
|
||||
|
||||
/**
|
||||
* i40e_get_rss_hash_bits - Read RSS Hash bits from register
|
||||
* @hw: hw structure
|
||||
* @nfc: pointer to user request
|
||||
* @i_setc: bits currently set
|
||||
*
|
||||
* Returns value of bits to be set per user request
|
||||
**/
|
||||
static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
|
||||
static u64 i40e_get_rss_hash_bits(struct i40e_hw *hw,
|
||||
struct ethtool_rxnfc *nfc,
|
||||
u64 i_setc)
|
||||
{
|
||||
u64 i_set = i_setc;
|
||||
u64 src_l3 = 0, dst_l3 = 0;
|
||||
@@ -3570,8 +3580,13 @@ static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
|
||||
dst_l3 = I40E_L3_V6_DST_MASK;
|
||||
} else if (nfc->flow_type == TCP_V4_FLOW ||
|
||||
nfc->flow_type == UDP_V4_FLOW) {
|
||||
src_l3 = I40E_L3_SRC_MASK;
|
||||
dst_l3 = I40E_L3_DST_MASK;
|
||||
if (hw->mac.type == I40E_MAC_X722) {
|
||||
src_l3 = I40E_X722_L3_SRC_MASK;
|
||||
dst_l3 = I40E_X722_L3_DST_MASK;
|
||||
} else {
|
||||
src_l3 = I40E_L3_SRC_MASK;
|
||||
dst_l3 = I40E_L3_DST_MASK;
|
||||
}
|
||||
} else {
|
||||
/* Any other flow type are not supported here */
|
||||
return i_set;
|
||||
@@ -3589,6 +3604,7 @@ static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
|
||||
return i_set;
|
||||
}
|
||||
|
||||
#define FLOW_PCTYPES_SIZE 64
|
||||
/**
|
||||
* i40e_set_rss_hash_opt - Enable/Disable flow types for RSS hash
|
||||
* @pf: pointer to the physical function struct
|
||||
@@ -3601,9 +3617,11 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
|
||||
struct i40e_hw *hw = &pf->hw;
|
||||
u64 hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) |
|
||||
((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32);
|
||||
u8 flow_pctype = 0;
|
||||
DECLARE_BITMAP(flow_pctypes, FLOW_PCTYPES_SIZE);
|
||||
u64 i_set, i_setc;
|
||||
|
||||
bitmap_zero(flow_pctypes, FLOW_PCTYPES_SIZE);
|
||||
|
||||
if (pf->flags & I40E_FLAG_MFP_ENABLED) {
|
||||
dev_err(&pf->pdev->dev,
|
||||
"Change of RSS hash input set is not supported when MFP mode is enabled\n");
|
||||
@@ -3619,36 +3637,35 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
|
||||
|
||||
switch (nfc->flow_type) {
|
||||
case TCP_V4_FLOW:
|
||||
flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
|
||||
set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, flow_pctypes);
|
||||
if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
|
||||
hena |=
|
||||
BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
|
||||
set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK,
|
||||
flow_pctypes);
|
||||
break;
|
||||
case TCP_V6_FLOW:
|
||||
flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
|
||||
set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, flow_pctypes);
|
||||
if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
|
||||
hena |=
|
||||
BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
|
||||
if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
|
||||
hena |=
|
||||
BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
|
||||
set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK,
|
||||
flow_pctypes);
|
||||
break;
|
||||
case UDP_V4_FLOW:
|
||||
flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
|
||||
if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
|
||||
hena |=
|
||||
BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
|
||||
BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
|
||||
|
||||
set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, flow_pctypes);
|
||||
if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
|
||||
set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP,
|
||||
flow_pctypes);
|
||||
set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP,
|
||||
flow_pctypes);
|
||||
}
|
||||
hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4);
|
||||
break;
|
||||
case UDP_V6_FLOW:
|
||||
flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
|
||||
if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
|
||||
hena |=
|
||||
BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
|
||||
BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
|
||||
|
||||
set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, flow_pctypes);
|
||||
if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
|
||||
set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP,
|
||||
flow_pctypes);
|
||||
set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP,
|
||||
flow_pctypes);
|
||||
}
|
||||
hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6);
|
||||
break;
|
||||
case AH_ESP_V4_FLOW:
|
||||
@@ -3681,17 +3698,20 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (flow_pctype) {
|
||||
i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0,
|
||||
flow_pctype)) |
|
||||
((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1,
|
||||
flow_pctype)) << 32);
|
||||
i_set = i40e_get_rss_hash_bits(nfc, i_setc);
|
||||
i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_pctype),
|
||||
(u32)i_set);
|
||||
i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_pctype),
|
||||
(u32)(i_set >> 32));
|
||||
hena |= BIT_ULL(flow_pctype);
|
||||
if (bitmap_weight(flow_pctypes, FLOW_PCTYPES_SIZE)) {
|
||||
u8 flow_id;
|
||||
|
||||
for_each_set_bit(flow_id, flow_pctypes, FLOW_PCTYPES_SIZE) {
|
||||
i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id)) |
|
||||
((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id)) << 32);
|
||||
i_set = i40e_get_rss_hash_bits(&pf->hw, nfc, i_setc);
|
||||
|
||||
i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id),
|
||||
(u32)i_set);
|
||||
i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id),
|
||||
(u32)(i_set >> 32));
|
||||
hena |= BIT_ULL(flow_id);
|
||||
}
|
||||
}
|
||||
|
||||
i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena);
|
||||
|
||||
@@ -1404,6 +1404,10 @@ struct i40e_lldp_variables {
|
||||
#define I40E_PFQF_CTL_0_HASHLUTSIZE_512 0x00010000
|
||||
|
||||
/* INPUT SET MASK for RSS, flow director, and flexible payload */
|
||||
#define I40E_X722_L3_SRC_SHIFT 49
|
||||
#define I40E_X722_L3_SRC_MASK (0x3ULL << I40E_X722_L3_SRC_SHIFT)
|
||||
#define I40E_X722_L3_DST_SHIFT 41
|
||||
#define I40E_X722_L3_DST_MASK (0x3ULL << I40E_X722_L3_DST_SHIFT)
|
||||
#define I40E_L3_SRC_SHIFT 47
|
||||
#define I40E_L3_SRC_MASK (0x3ULL << I40E_L3_SRC_SHIFT)
|
||||
#define I40E_L3_V6_SRC_SHIFT 43
|
||||
|
||||
@@ -1536,10 +1536,12 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
|
||||
if (test_bit(__I40E_VF_RESETS_DISABLED, pf->state))
|
||||
return true;
|
||||
|
||||
/* If the VFs have been disabled, this means something else is
|
||||
* resetting the VF, so we shouldn't continue.
|
||||
*/
|
||||
if (test_and_set_bit(__I40E_VF_DISABLE, pf->state))
|
||||
/* Bail out if VFs are disabled. */
|
||||
if (test_bit(__I40E_VF_DISABLE, pf->state))
|
||||
return true;
|
||||
|
||||
/* If VF is being reset already we don't need to continue. */
|
||||
if (test_and_set_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
|
||||
return true;
|
||||
|
||||
i40e_trigger_vf_reset(vf, flr);
|
||||
@@ -1576,7 +1578,7 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
|
||||
i40e_cleanup_reset_vf(vf);
|
||||
|
||||
i40e_flush(hw);
|
||||
clear_bit(__I40E_VF_DISABLE, pf->state);
|
||||
clear_bit(I40E_VF_STATE_RESETTING, &vf->vf_states);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1609,8 +1611,12 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
||||
return false;
|
||||
|
||||
/* Begin reset on all VFs at once */
|
||||
for (v = 0; v < pf->num_alloc_vfs; v++)
|
||||
i40e_trigger_vf_reset(&pf->vf[v], flr);
|
||||
for (v = 0; v < pf->num_alloc_vfs; v++) {
|
||||
vf = &pf->vf[v];
|
||||
/* If VF is being reset no need to trigger reset again */
|
||||
if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
|
||||
i40e_trigger_vf_reset(&pf->vf[v], flr);
|
||||
}
|
||||
|
||||
/* HW requires some time to make sure it can flush the FIFO for a VF
|
||||
* when it resets it. Poll the VPGEN_VFRSTAT register for each VF in
|
||||
@@ -1626,9 +1632,11 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
||||
*/
|
||||
while (v < pf->num_alloc_vfs) {
|
||||
vf = &pf->vf[v];
|
||||
reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
|
||||
if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK))
|
||||
break;
|
||||
if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) {
|
||||
reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
|
||||
if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK))
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the current VF has finished resetting, move on
|
||||
* to the next VF in sequence.
|
||||
@@ -1656,6 +1664,10 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
||||
if (pf->vf[v].lan_vsi_idx == 0)
|
||||
continue;
|
||||
|
||||
/* If VF is reset in another thread just continue */
|
||||
if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
|
||||
continue;
|
||||
|
||||
i40e_vsi_stop_rings_no_wait(pf->vsi[pf->vf[v].lan_vsi_idx]);
|
||||
}
|
||||
|
||||
@@ -1667,6 +1679,10 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
||||
if (pf->vf[v].lan_vsi_idx == 0)
|
||||
continue;
|
||||
|
||||
/* If VF is reset in another thread just continue */
|
||||
if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
|
||||
continue;
|
||||
|
||||
i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[v].lan_vsi_idx]);
|
||||
}
|
||||
|
||||
@@ -1676,8 +1692,13 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
||||
mdelay(50);
|
||||
|
||||
/* Finish the reset on each VF */
|
||||
for (v = 0; v < pf->num_alloc_vfs; v++)
|
||||
for (v = 0; v < pf->num_alloc_vfs; v++) {
|
||||
/* If VF is reset in another thread just continue */
|
||||
if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
|
||||
continue;
|
||||
|
||||
i40e_cleanup_reset_vf(&pf->vf[v]);
|
||||
}
|
||||
|
||||
i40e_flush(hw);
|
||||
clear_bit(__I40E_VF_DISABLE, pf->state);
|
||||
|
||||
@@ -39,6 +39,7 @@ enum i40e_vf_states {
|
||||
I40E_VF_STATE_MC_PROMISC,
|
||||
I40E_VF_STATE_UC_PROMISC,
|
||||
I40E_VF_STATE_PRE_ENABLE,
|
||||
I40E_VF_STATE_RESETTING
|
||||
};
|
||||
|
||||
/* VF capabilities */
|
||||
|
||||
@@ -2004,7 +2004,7 @@ void mlx5_cmd_init_async_ctx(struct mlx5_core_dev *dev,
|
||||
ctx->dev = dev;
|
||||
/* Starts at 1 to avoid doing wake_up if we are not cleaning up */
|
||||
atomic_set(&ctx->num_inflight, 1);
|
||||
init_waitqueue_head(&ctx->wait);
|
||||
init_completion(&ctx->inflight_done);
|
||||
}
|
||||
EXPORT_SYMBOL(mlx5_cmd_init_async_ctx);
|
||||
|
||||
@@ -2018,8 +2018,8 @@ EXPORT_SYMBOL(mlx5_cmd_init_async_ctx);
|
||||
*/
|
||||
void mlx5_cmd_cleanup_async_ctx(struct mlx5_async_ctx *ctx)
|
||||
{
|
||||
atomic_dec(&ctx->num_inflight);
|
||||
wait_event(ctx->wait, atomic_read(&ctx->num_inflight) == 0);
|
||||
if (!atomic_dec_and_test(&ctx->num_inflight))
|
||||
wait_for_completion(&ctx->inflight_done);
|
||||
}
|
||||
EXPORT_SYMBOL(mlx5_cmd_cleanup_async_ctx);
|
||||
|
||||
@@ -2032,7 +2032,7 @@ static void mlx5_cmd_exec_cb_handler(int status, void *_work)
|
||||
status = cmd_status_err(ctx->dev, status, work->opcode, work->out);
|
||||
work->user_callback(status, work);
|
||||
if (atomic_dec_and_test(&ctx->num_inflight))
|
||||
wake_up(&ctx->wait);
|
||||
complete(&ctx->inflight_done);
|
||||
}
|
||||
|
||||
int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
|
||||
@@ -2050,7 +2050,7 @@ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
|
||||
ret = cmd_exec(ctx->dev, in, in_size, out, out_size,
|
||||
mlx5_cmd_exec_cb_handler, work, false);
|
||||
if (ret && atomic_dec_and_test(&ctx->num_inflight))
|
||||
wake_up(&ctx->wait);
|
||||
complete(&ctx->inflight_done);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "en.h"
|
||||
#include "en_stats.h"
|
||||
#include "en/txrx.h"
|
||||
#include <linux/ptp_classify.h>
|
||||
|
||||
#define MLX5E_PTP_CHANNEL_IX 0
|
||||
@@ -68,6 +69,14 @@ static inline bool mlx5e_use_ptpsq(struct sk_buff *skb)
|
||||
fk.ports.dst == htons(PTP_EV_PORT));
|
||||
}
|
||||
|
||||
static inline bool mlx5e_ptpsq_fifo_has_room(struct mlx5e_txqsq *sq)
|
||||
{
|
||||
if (!sq->ptpsq)
|
||||
return true;
|
||||
|
||||
return mlx5e_skb_fifo_has_room(&sq->ptpsq->skb_fifo);
|
||||
}
|
||||
|
||||
int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,
|
||||
u8 lag_port, struct mlx5e_ptp **cp);
|
||||
void mlx5e_ptp_close(struct mlx5e_ptp *c);
|
||||
|
||||
@@ -96,6 +96,7 @@ struct mlx5e_tc_flow {
|
||||
struct encap_flow_item encaps[MLX5_MAX_FLOW_FWD_VPORTS];
|
||||
struct mlx5e_tc_flow *peer_flow;
|
||||
struct mlx5e_mod_hdr_handle *mh; /* attached mod header instance */
|
||||
struct mlx5e_mod_hdr_handle *slow_mh; /* attached mod header instance for slow path */
|
||||
struct mlx5e_hairpin_entry *hpe; /* attached hairpin instance */
|
||||
struct list_head hairpin; /* flows sharing the same hairpin */
|
||||
struct list_head peer; /* flows with peer flow */
|
||||
@@ -111,6 +112,7 @@ struct mlx5e_tc_flow {
|
||||
struct completion del_hw_done;
|
||||
struct mlx5_flow_attr *attr;
|
||||
struct list_head attrs;
|
||||
u32 chain_mapping;
|
||||
};
|
||||
|
||||
struct mlx5_flow_handle *
|
||||
|
||||
@@ -57,6 +57,12 @@ netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev);
|
||||
bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget);
|
||||
void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq);
|
||||
|
||||
static inline bool
|
||||
mlx5e_skb_fifo_has_room(struct mlx5e_skb_fifo *fifo)
|
||||
{
|
||||
return (*fifo->pc - *fifo->cc) < fifo->mask;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
mlx5e_wqc_has_room_for(struct mlx5_wq_cyc *wq, u16 cc, u16 pc, u16 n)
|
||||
{
|
||||
|
||||
@@ -101,7 +101,6 @@ static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
|
||||
struct xfrm_replay_state_esn *replay_esn;
|
||||
u32 seq_bottom = 0;
|
||||
u8 overlap;
|
||||
u32 *esn;
|
||||
|
||||
if (!(sa_entry->x->props.flags & XFRM_STATE_ESN)) {
|
||||
sa_entry->esn_state.trigger = 0;
|
||||
@@ -116,11 +115,9 @@ static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
|
||||
|
||||
sa_entry->esn_state.esn = xfrm_replay_seqhi(sa_entry->x,
|
||||
htonl(seq_bottom));
|
||||
esn = &sa_entry->esn_state.esn;
|
||||
|
||||
sa_entry->esn_state.trigger = 1;
|
||||
if (unlikely(overlap && seq_bottom < MLX5E_IPSEC_ESN_SCOPE_MID)) {
|
||||
++(*esn);
|
||||
sa_entry->esn_state.overlap = 0;
|
||||
return true;
|
||||
} else if (unlikely(!overlap &&
|
||||
|
||||
@@ -432,7 +432,7 @@ static int mlx5e_macsec_update_rx_sa(struct mlx5e_macsec *macsec,
|
||||
bool active)
|
||||
{
|
||||
struct mlx5_core_dev *mdev = macsec->mdev;
|
||||
struct mlx5_macsec_obj_attrs attrs;
|
||||
struct mlx5_macsec_obj_attrs attrs = {};
|
||||
int err = 0;
|
||||
|
||||
if (rx_sa->active != active)
|
||||
@@ -444,7 +444,7 @@ static int mlx5e_macsec_update_rx_sa(struct mlx5e_macsec *macsec,
|
||||
return 0;
|
||||
}
|
||||
|
||||
attrs.sci = rx_sa->sci;
|
||||
attrs.sci = cpu_to_be64((__force u64)rx_sa->sci);
|
||||
attrs.enc_key_id = rx_sa->enc_key_id;
|
||||
err = mlx5e_macsec_create_object(mdev, &attrs, false, &rx_sa->macsec_obj_id);
|
||||
if (err)
|
||||
@@ -999,11 +999,11 @@ static int mlx5e_macsec_upd_rxsa(struct macsec_context *ctx)
|
||||
}
|
||||
|
||||
rx_sa = rx_sc->rx_sa[assoc_num];
|
||||
if (rx_sa) {
|
||||
if (!rx_sa) {
|
||||
netdev_err(ctx->netdev,
|
||||
"MACsec offload rx_sc sci %lld rx_sa %d already exist\n",
|
||||
"MACsec offload rx_sc sci %lld rx_sa %d doesn't exist\n",
|
||||
sci, assoc_num);
|
||||
err = -EEXIST;
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1055,11 +1055,11 @@ static int mlx5e_macsec_del_rxsa(struct macsec_context *ctx)
|
||||
}
|
||||
|
||||
rx_sa = rx_sc->rx_sa[assoc_num];
|
||||
if (rx_sa) {
|
||||
if (!rx_sa) {
|
||||
netdev_err(ctx->netdev,
|
||||
"MACsec offload rx_sc sci %lld rx_sa %d already exist\n",
|
||||
"MACsec offload rx_sc sci %lld rx_sa %d doesn't exist\n",
|
||||
sci, assoc_num);
|
||||
err = -EEXIST;
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@@ -1180,7 +1180,7 @@ macsec_fs_rx_add_rule(struct mlx5e_macsec_fs *macsec_fs,
|
||||
rx_rule->rule[0] = rule;
|
||||
|
||||
/* Rx crypto table without SCI rule */
|
||||
if (cpu_to_be64((__force u64)attrs->sci) & ntohs(MACSEC_PORT_ES)) {
|
||||
if ((cpu_to_be64((__force u64)attrs->sci) & 0xFFFF) == ntohs(MACSEC_PORT_ES)) {
|
||||
memset(spec, 0, sizeof(struct mlx5_flow_spec));
|
||||
memset(&dest, 0, sizeof(struct mlx5_flow_destination));
|
||||
memset(&flow_act, 0, sizeof(flow_act));
|
||||
|
||||
@@ -1405,8 +1405,13 @@ mlx5e_tc_offload_to_slow_path(struct mlx5_eswitch *esw,
|
||||
struct mlx5e_tc_flow *flow,
|
||||
struct mlx5_flow_spec *spec)
|
||||
{
|
||||
struct mlx5e_tc_mod_hdr_acts mod_acts = {};
|
||||
struct mlx5e_mod_hdr_handle *mh = NULL;
|
||||
struct mlx5_flow_attr *slow_attr;
|
||||
struct mlx5_flow_handle *rule;
|
||||
bool fwd_and_modify_cap;
|
||||
u32 chain_mapping = 0;
|
||||
int err;
|
||||
|
||||
slow_attr = mlx5_alloc_flow_attr(MLX5_FLOW_NAMESPACE_FDB);
|
||||
if (!slow_attr)
|
||||
@@ -1417,13 +1422,56 @@ mlx5e_tc_offload_to_slow_path(struct mlx5_eswitch *esw,
|
||||
slow_attr->esw_attr->split_count = 0;
|
||||
slow_attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH;
|
||||
|
||||
rule = mlx5e_tc_offload_fdb_rules(esw, flow, spec, slow_attr);
|
||||
if (!IS_ERR(rule))
|
||||
flow_flag_set(flow, SLOW);
|
||||
fwd_and_modify_cap = MLX5_CAP_ESW_FLOWTABLE((esw)->dev, fdb_modify_header_fwd_to_table);
|
||||
if (!fwd_and_modify_cap)
|
||||
goto skip_restore;
|
||||
|
||||
err = mlx5_chains_get_chain_mapping(esw_chains(esw), flow->attr->chain, &chain_mapping);
|
||||
if (err)
|
||||
goto err_get_chain;
|
||||
|
||||
err = mlx5e_tc_match_to_reg_set(esw->dev, &mod_acts, MLX5_FLOW_NAMESPACE_FDB,
|
||||
CHAIN_TO_REG, chain_mapping);
|
||||
if (err)
|
||||
goto err_reg_set;
|
||||
|
||||
mh = mlx5e_mod_hdr_attach(esw->dev, get_mod_hdr_table(flow->priv, flow),
|
||||
MLX5_FLOW_NAMESPACE_FDB, &mod_acts);
|
||||
if (IS_ERR(mh)) {
|
||||
err = PTR_ERR(mh);
|
||||
goto err_attach;
|
||||
}
|
||||
|
||||
slow_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
|
||||
slow_attr->modify_hdr = mlx5e_mod_hdr_get(mh);
|
||||
|
||||
skip_restore:
|
||||
rule = mlx5e_tc_offload_fdb_rules(esw, flow, spec, slow_attr);
|
||||
if (IS_ERR(rule)) {
|
||||
err = PTR_ERR(rule);
|
||||
goto err_offload;
|
||||
}
|
||||
|
||||
flow->slow_mh = mh;
|
||||
flow->chain_mapping = chain_mapping;
|
||||
flow_flag_set(flow, SLOW);
|
||||
|
||||
mlx5e_mod_hdr_dealloc(&mod_acts);
|
||||
kfree(slow_attr);
|
||||
|
||||
return rule;
|
||||
|
||||
err_offload:
|
||||
if (fwd_and_modify_cap)
|
||||
mlx5e_mod_hdr_detach(esw->dev, get_mod_hdr_table(flow->priv, flow), mh);
|
||||
err_attach:
|
||||
err_reg_set:
|
||||
if (fwd_and_modify_cap)
|
||||
mlx5_chains_put_chain_mapping(esw_chains(esw), chain_mapping);
|
||||
err_get_chain:
|
||||
mlx5e_mod_hdr_dealloc(&mod_acts);
|
||||
kfree(slow_attr);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw,
|
||||
@@ -1441,7 +1489,17 @@ void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw,
|
||||
slow_attr->action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
|
||||
slow_attr->esw_attr->split_count = 0;
|
||||
slow_attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH;
|
||||
if (flow->slow_mh) {
|
||||
slow_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
|
||||
slow_attr->modify_hdr = mlx5e_mod_hdr_get(flow->slow_mh);
|
||||
}
|
||||
mlx5e_tc_unoffload_fdb_rules(esw, flow, slow_attr);
|
||||
if (flow->slow_mh) {
|
||||
mlx5e_mod_hdr_detach(esw->dev, get_mod_hdr_table(flow->priv, flow), flow->slow_mh);
|
||||
mlx5_chains_put_chain_mapping(esw_chains(esw), flow->chain_mapping);
|
||||
flow->chain_mapping = 0;
|
||||
flow->slow_mh = NULL;
|
||||
}
|
||||
flow_flag_clear(flow, SLOW);
|
||||
kfree(slow_attr);
|
||||
}
|
||||
@@ -3575,6 +3633,10 @@ mlx5e_clone_flow_attr_for_post_act(struct mlx5_flow_attr *attr,
|
||||
attr2->action = 0;
|
||||
attr2->flags = 0;
|
||||
attr2->parse_attr = parse_attr;
|
||||
attr2->esw_attr->out_count = 0;
|
||||
attr2->esw_attr->split_count = 0;
|
||||
attr2->dest_chain = 0;
|
||||
attr2->dest_ft = NULL;
|
||||
return attr2;
|
||||
}
|
||||
|
||||
@@ -4008,6 +4070,7 @@ parse_tc_fdb_actions(struct mlx5e_priv *priv,
|
||||
struct mlx5e_tc_flow_parse_attr *parse_attr;
|
||||
struct mlx5_flow_attr *attr = flow->attr;
|
||||
struct mlx5_esw_flow_attr *esw_attr;
|
||||
struct net_device *filter_dev;
|
||||
int err;
|
||||
|
||||
err = flow_action_supported(flow_action, extack);
|
||||
@@ -4016,6 +4079,7 @@ parse_tc_fdb_actions(struct mlx5e_priv *priv,
|
||||
|
||||
esw_attr = attr->esw_attr;
|
||||
parse_attr = attr->parse_attr;
|
||||
filter_dev = parse_attr->filter_dev;
|
||||
parse_state = &parse_attr->parse_state;
|
||||
mlx5e_tc_act_init_parse_state(parse_state, flow, flow_action, extack);
|
||||
parse_state->ct_priv = get_ct_priv(priv);
|
||||
@@ -4025,13 +4089,21 @@ parse_tc_fdb_actions(struct mlx5e_priv *priv,
|
||||
return err;
|
||||
|
||||
/* Forward to/from internal port can only have 1 dest */
|
||||
if ((netif_is_ovs_master(parse_attr->filter_dev) || esw_attr->dest_int_port) &&
|
||||
if ((netif_is_ovs_master(filter_dev) || esw_attr->dest_int_port) &&
|
||||
esw_attr->out_count > 1) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Rules with internal port can have only one destination");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* Forward from tunnel/internal port to internal port is not supported */
|
||||
if ((mlx5e_get_tc_tun(filter_dev) || netif_is_ovs_master(filter_dev)) &&
|
||||
esw_attr->dest_int_port) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Forwarding from tunnel/internal port to internal port is not supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
err = actions_prepare_mod_hdr_actions(priv, flow, attr, extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user