Merge tag 'v6.7-rc1' into android-mainline
Linux 6.7-rc1 Change-Id: If8883f2cd5101d1b4b025d8f1bda416e18f91c2d Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -174,7 +174,7 @@ HWCAP2_DCPODP
|
||||
Functionality implied by ID_AA64ISAR1_EL1.DPB == 0b0010.
|
||||
|
||||
HWCAP2_SVE2
|
||||
Functionality implied by ID_AA64ZFR0_EL1.SVEVer == 0b0001.
|
||||
Functionality implied by ID_AA64ZFR0_EL1.SVEver == 0b0001.
|
||||
|
||||
HWCAP2_SVEAES
|
||||
Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0001.
|
||||
@@ -222,7 +222,7 @@ HWCAP2_RNG
|
||||
Functionality implied by ID_AA64ISAR0_EL1.RNDR == 0b0001.
|
||||
|
||||
HWCAP2_BTI
|
||||
Functionality implied by ID_AA64PFR0_EL1.BT == 0b0001.
|
||||
Functionality implied by ID_AA64PFR1_EL1.BT == 0b0001.
|
||||
|
||||
HWCAP2_MTE
|
||||
Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0010, as described
|
||||
@@ -232,7 +232,7 @@ HWCAP2_ECV
|
||||
Functionality implied by ID_AA64MMFR0_EL1.ECV == 0b0001.
|
||||
|
||||
HWCAP2_AFP
|
||||
Functionality implied by ID_AA64MFR1_EL1.AFP == 0b0001.
|
||||
Functionality implied by ID_AA64MMFR1_EL1.AFP == 0b0001.
|
||||
|
||||
HWCAP2_RPRES
|
||||
Functionality implied by ID_AA64ISAR2_EL1.RPRES == 0b0001.
|
||||
|
||||
@@ -59,8 +59,12 @@ Synopsis of fprobe-events
|
||||
and bitfield are supported.
|
||||
|
||||
(\*1) This is available only when BTF is enabled.
|
||||
(\*2) only for the probe on function entry (offs == 0).
|
||||
(\*3) only for return probe.
|
||||
(\*2) only for the probe on function entry (offs == 0). Note, this argument access
|
||||
is best effort, because depending on the argument type, it may be passed on
|
||||
the stack. But this only support the arguments via registers.
|
||||
(\*3) only for return probe. Note that this is also best effort. Depending on the
|
||||
return value type, it might be passed via a pair of registers. But this only
|
||||
accesses one register.
|
||||
(\*4) this is useful for fetching a field of data structures.
|
||||
(\*5) "u" means user-space dereference.
|
||||
|
||||
|
||||
@@ -61,8 +61,12 @@ Synopsis of kprobe_events
|
||||
(x8/x16/x32/x64), "char", "string", "ustring", "symbol", "symstr"
|
||||
and bitfield are supported.
|
||||
|
||||
(\*1) only for the probe on function entry (offs == 0).
|
||||
(\*2) only for return probe.
|
||||
(\*1) only for the probe on function entry (offs == 0). Note, this argument access
|
||||
is best effort, because depending on the argument type, it may be passed on
|
||||
the stack. But this only support the arguments via registers.
|
||||
(\*2) only for return probe. Note that this is also best effort. Depending on the
|
||||
return value type, it might be passed via a pair of registers. But this only
|
||||
accesses one register.
|
||||
(\*3) this is useful for fetching a field of data structures.
|
||||
(\*4) "u" means user-space dereference. See :ref:`user_mem_access`.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 6
|
||||
PATCHLEVEL = 7
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION =
|
||||
EXTRAVERSION = -rc1
|
||||
NAME = Hurr durr I'ma ninja sloth
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
||||
@@ -32,9 +32,6 @@ struct kprobe;
|
||||
|
||||
void arch_remove_kprobe(struct kprobe *p);
|
||||
|
||||
int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
|
||||
struct prev_kprobe {
|
||||
struct kprobe *kp;
|
||||
unsigned long status;
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#define PMUSERENR __ACCESS_CP15(c9, 0, c14, 0)
|
||||
#define PMINTENSET __ACCESS_CP15(c9, 0, c14, 1)
|
||||
#define PMINTENCLR __ACCESS_CP15(c9, 0, c14, 2)
|
||||
#define PMCEID2 __ACCESS_CP15(c9, 0, c14, 4)
|
||||
#define PMCEID3 __ACCESS_CP15(c9, 0, c14, 5)
|
||||
#define PMMIR __ACCESS_CP15(c9, 0, c14, 6)
|
||||
#define PMCCFILTR __ACCESS_CP15(c14, 0, c15, 7)
|
||||
|
||||
@@ -150,21 +152,6 @@ static inline u64 read_pmccntr(void)
|
||||
return read_sysreg(PMCCNTR);
|
||||
}
|
||||
|
||||
static inline void write_pmxevcntr(u32 val)
|
||||
{
|
||||
write_sysreg(val, PMXEVCNTR);
|
||||
}
|
||||
|
||||
static inline u32 read_pmxevcntr(void)
|
||||
{
|
||||
return read_sysreg(PMXEVCNTR);
|
||||
}
|
||||
|
||||
static inline void write_pmxevtyper(u32 val)
|
||||
{
|
||||
write_sysreg(val, PMXEVTYPER);
|
||||
}
|
||||
|
||||
static inline void write_pmcntenset(u32 val)
|
||||
{
|
||||
write_sysreg(val, PMCNTENSET);
|
||||
@@ -205,16 +192,6 @@ static inline void write_pmuserenr(u32 val)
|
||||
write_sysreg(val, PMUSERENR);
|
||||
}
|
||||
|
||||
static inline u32 read_pmceid0(void)
|
||||
{
|
||||
return read_sysreg(PMCEID0);
|
||||
}
|
||||
|
||||
static inline u32 read_pmceid1(void)
|
||||
{
|
||||
return read_sysreg(PMCEID1);
|
||||
}
|
||||
|
||||
static inline void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr) {}
|
||||
static inline void kvm_clr_pmu_events(u32 clr) {}
|
||||
static inline bool kvm_pmu_counter_deferred(struct perf_event_attr *attr)
|
||||
@@ -231,6 +208,7 @@ static inline void kvm_vcpu_pmu_resync_el0(void) {}
|
||||
|
||||
/* PMU Version in DFR Register */
|
||||
#define ARMV8_PMU_DFR_VER_NI 0
|
||||
#define ARMV8_PMU_DFR_VER_V3P1 0x4
|
||||
#define ARMV8_PMU_DFR_VER_V3P4 0x5
|
||||
#define ARMV8_PMU_DFR_VER_V3P5 0x6
|
||||
#define ARMV8_PMU_DFR_VER_IMP_DEF 0xF
|
||||
@@ -251,4 +229,24 @@ static inline bool is_pmuv3p5(int pmuver)
|
||||
return pmuver >= ARMV8_PMU_DFR_VER_V3P5;
|
||||
}
|
||||
|
||||
static inline u64 read_pmceid0(void)
|
||||
{
|
||||
u64 val = read_sysreg(PMCEID0);
|
||||
|
||||
if (read_pmuver() >= ARMV8_PMU_DFR_VER_V3P1)
|
||||
val |= (u64)read_sysreg(PMCEID2) << 32;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline u64 read_pmceid1(void)
|
||||
{
|
||||
u64 val = read_sysreg(PMCEID1);
|
||||
|
||||
if (read_pmuver() >= ARMV8_PMU_DFR_VER_V3P1)
|
||||
val |= (u64)read_sysreg(PMCEID3) << 32;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -40,8 +40,6 @@ struct kprobe_ctlblk {
|
||||
|
||||
void arch_remove_kprobe(struct kprobe *);
|
||||
int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
|
||||
int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
|
||||
/* optinsn template addresses */
|
||||
extern __visible kprobe_opcode_t optprobe_template_entry[];
|
||||
|
||||
@@ -46,12 +46,12 @@ static inline u32 read_pmuver(void)
|
||||
ID_AA64DFR0_EL1_PMUVer_SHIFT);
|
||||
}
|
||||
|
||||
static inline void write_pmcr(u32 val)
|
||||
static inline void write_pmcr(u64 val)
|
||||
{
|
||||
write_sysreg(val, pmcr_el0);
|
||||
}
|
||||
|
||||
static inline u32 read_pmcr(void)
|
||||
static inline u64 read_pmcr(void)
|
||||
{
|
||||
return read_sysreg(pmcr_el0);
|
||||
}
|
||||
@@ -71,21 +71,6 @@ static inline u64 read_pmccntr(void)
|
||||
return read_sysreg(pmccntr_el0);
|
||||
}
|
||||
|
||||
static inline void write_pmxevcntr(u32 val)
|
||||
{
|
||||
write_sysreg(val, pmxevcntr_el0);
|
||||
}
|
||||
|
||||
static inline u32 read_pmxevcntr(void)
|
||||
{
|
||||
return read_sysreg(pmxevcntr_el0);
|
||||
}
|
||||
|
||||
static inline void write_pmxevtyper(u32 val)
|
||||
{
|
||||
write_sysreg(val, pmxevtyper_el0);
|
||||
}
|
||||
|
||||
static inline void write_pmcntenset(u32 val)
|
||||
{
|
||||
write_sysreg(val, pmcntenset_el0);
|
||||
@@ -106,7 +91,7 @@ static inline void write_pmintenclr(u32 val)
|
||||
write_sysreg(val, pmintenclr_el1);
|
||||
}
|
||||
|
||||
static inline void write_pmccfiltr(u32 val)
|
||||
static inline void write_pmccfiltr(u64 val)
|
||||
{
|
||||
write_sysreg(val, pmccfiltr_el0);
|
||||
}
|
||||
@@ -126,12 +111,12 @@ static inline void write_pmuserenr(u32 val)
|
||||
write_sysreg(val, pmuserenr_el0);
|
||||
}
|
||||
|
||||
static inline u32 read_pmceid0(void)
|
||||
static inline u64 read_pmceid0(void)
|
||||
{
|
||||
return read_sysreg(pmceid0_el0);
|
||||
}
|
||||
|
||||
static inline u32 read_pmceid1(void)
|
||||
static inline u64 read_pmceid1(void)
|
||||
{
|
||||
return read_sysreg(pmceid1_el0);
|
||||
}
|
||||
|
||||
@@ -37,8 +37,6 @@ struct kprobe_ctlblk {
|
||||
|
||||
void arch_remove_kprobe(struct kprobe *);
|
||||
int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
|
||||
int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
void __kretprobe_trampoline(void);
|
||||
void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@
|
||||
ALLOW_ERROR_INJECTION(__arm64_sys##name, ERRNO); \
|
||||
static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
|
||||
static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
|
||||
asmlinkage long __arm64_sys##name(const struct pt_regs *regs); \
|
||||
asmlinkage long __arm64_sys##name(const struct pt_regs *regs) \
|
||||
{ \
|
||||
return __se_sys##name(SC_ARM64_REGS_TO_ARGS(x,__VA_ARGS__)); \
|
||||
|
||||
@@ -999,6 +999,37 @@ static void init_32bit_cpu_features(struct cpuinfo_32bit *info)
|
||||
init_cpu_ftr_reg(SYS_MVFR2_EL1, info->reg_mvfr2);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
||||
static bool enable_pseudo_nmi;
|
||||
|
||||
static int __init early_enable_pseudo_nmi(char *p)
|
||||
{
|
||||
return kstrtobool(p, &enable_pseudo_nmi);
|
||||
}
|
||||
early_param("irqchip.gicv3_pseudo_nmi", early_enable_pseudo_nmi);
|
||||
|
||||
static __init void detect_system_supports_pseudo_nmi(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
if (!enable_pseudo_nmi)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Detect broken MediaTek firmware that doesn't properly save and
|
||||
* restore GIC priorities.
|
||||
*/
|
||||
np = of_find_compatible_node(NULL, NULL, "arm,gic-v3");
|
||||
if (np && of_property_read_bool(np, "mediatek,broken-save-restore-fw")) {
|
||||
pr_info("Pseudo-NMI disabled due to MediaTek Chromebook GICR save problem\n");
|
||||
enable_pseudo_nmi = false;
|
||||
}
|
||||
of_node_put(np);
|
||||
}
|
||||
#else /* CONFIG_ARM64_PSEUDO_NMI */
|
||||
static inline void detect_system_supports_pseudo_nmi(void) { }
|
||||
#endif
|
||||
|
||||
void __init init_cpu_features(struct cpuinfo_arm64 *info)
|
||||
{
|
||||
/* Before we start using the tables, make sure it is sorted */
|
||||
@@ -1057,6 +1088,13 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
|
||||
*/
|
||||
init_cpucap_indirect_list();
|
||||
|
||||
/*
|
||||
* Detect broken pseudo-NMI. Must be called _before_ the call to
|
||||
* setup_boot_cpu_capabilities() since it interacts with
|
||||
* can_use_gic_priorities().
|
||||
*/
|
||||
detect_system_supports_pseudo_nmi();
|
||||
|
||||
/*
|
||||
* Detect and enable early CPU capabilities based on the boot CPU,
|
||||
* after we have initialised the CPU feature infrastructure.
|
||||
@@ -2086,14 +2124,6 @@ static void cpu_enable_e0pd(struct arm64_cpu_capabilities const *cap)
|
||||
#endif /* CONFIG_ARM64_E0PD */
|
||||
|
||||
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
||||
static bool enable_pseudo_nmi;
|
||||
|
||||
static int __init early_enable_pseudo_nmi(char *p)
|
||||
{
|
||||
return kstrtobool(p, &enable_pseudo_nmi);
|
||||
}
|
||||
early_param("irqchip.gicv3_pseudo_nmi", early_enable_pseudo_nmi);
|
||||
|
||||
static bool can_use_gic_priorities(const struct arm64_cpu_capabilities *entry,
|
||||
int scope)
|
||||
{
|
||||
|
||||
@@ -971,10 +971,7 @@ static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
|
||||
|
||||
static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
|
||||
{
|
||||
DECLARE_STATIC_KEY_FALSE(supports_pseudo_nmis);
|
||||
|
||||
if (!system_uses_irq_prio_masking() ||
|
||||
!static_branch_likely(&supports_pseudo_nmis))
|
||||
if (!system_uses_irq_prio_masking())
|
||||
return false;
|
||||
|
||||
switch (ipi) {
|
||||
|
||||
@@ -136,6 +136,7 @@ config LOONGARCH
|
||||
select HAVE_PERF_EVENTS
|
||||
select HAVE_PERF_REGS
|
||||
select HAVE_PERF_USER_STACK_DUMP
|
||||
select HAVE_PREEMPT_DYNAMIC_KEY
|
||||
select HAVE_REGS_AND_STACK_ACCESS_API
|
||||
select HAVE_RETHOOK
|
||||
select HAVE_RSEQ
|
||||
|
||||
@@ -68,6 +68,8 @@ LDFLAGS_vmlinux += -static -n -nostdlib
|
||||
ifdef CONFIG_AS_HAS_EXPLICIT_RELOCS
|
||||
cflags-y += $(call cc-option,-mexplicit-relocs)
|
||||
KBUILD_CFLAGS_KERNEL += $(call cc-option,-mdirect-extern-access)
|
||||
KBUILD_AFLAGS_MODULE += $(call cc-option,-fno-direct-access-external-data)
|
||||
KBUILD_CFLAGS_MODULE += $(call cc-option,-fno-direct-access-external-data)
|
||||
KBUILD_AFLAGS_MODULE += $(call cc-option,-mno-relax) $(call cc-option,-Wa$(comma)-mno-relax)
|
||||
KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax) $(call cc-option,-Wa$(comma)-mno-relax)
|
||||
else
|
||||
|
||||
@@ -36,19 +36,19 @@
|
||||
static inline void arch_atomic_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
__asm__ __volatile__( \
|
||||
"am"#asm_op"_db.w" " $zero, %1, %0 \n" \
|
||||
"am"#asm_op".w" " $zero, %1, %0 \n" \
|
||||
: "+ZB" (v->counter) \
|
||||
: "r" (I) \
|
||||
: "memory"); \
|
||||
}
|
||||
|
||||
#define ATOMIC_OP_RETURN(op, I, asm_op, c_op) \
|
||||
static inline int arch_atomic_##op##_return_relaxed(int i, atomic_t *v) \
|
||||
#define ATOMIC_OP_RETURN(op, I, asm_op, c_op, mb, suffix) \
|
||||
static inline int arch_atomic_##op##_return##suffix(int i, atomic_t *v) \
|
||||
{ \
|
||||
int result; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
"am"#asm_op"_db.w" " %1, %2, %0 \n" \
|
||||
"am"#asm_op#mb".w" " %1, %2, %0 \n" \
|
||||
: "+ZB" (v->counter), "=&r" (result) \
|
||||
: "r" (I) \
|
||||
: "memory"); \
|
||||
@@ -56,13 +56,13 @@ static inline int arch_atomic_##op##_return_relaxed(int i, atomic_t *v) \
|
||||
return result c_op I; \
|
||||
}
|
||||
|
||||
#define ATOMIC_FETCH_OP(op, I, asm_op) \
|
||||
static inline int arch_atomic_fetch_##op##_relaxed(int i, atomic_t *v) \
|
||||
#define ATOMIC_FETCH_OP(op, I, asm_op, mb, suffix) \
|
||||
static inline int arch_atomic_fetch_##op##suffix(int i, atomic_t *v) \
|
||||
{ \
|
||||
int result; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
"am"#asm_op"_db.w" " %1, %2, %0 \n" \
|
||||
"am"#asm_op#mb".w" " %1, %2, %0 \n" \
|
||||
: "+ZB" (v->counter), "=&r" (result) \
|
||||
: "r" (I) \
|
||||
: "memory"); \
|
||||
@@ -72,29 +72,53 @@ static inline int arch_atomic_fetch_##op##_relaxed(int i, atomic_t *v) \
|
||||
|
||||
#define ATOMIC_OPS(op, I, asm_op, c_op) \
|
||||
ATOMIC_OP(op, I, asm_op) \
|
||||
ATOMIC_OP_RETURN(op, I, asm_op, c_op) \
|
||||
ATOMIC_FETCH_OP(op, I, asm_op)
|
||||
ATOMIC_OP_RETURN(op, I, asm_op, c_op, _db, ) \
|
||||
ATOMIC_OP_RETURN(op, I, asm_op, c_op, , _relaxed) \
|
||||
ATOMIC_FETCH_OP(op, I, asm_op, _db, ) \
|
||||
ATOMIC_FETCH_OP(op, I, asm_op, , _relaxed)
|
||||
|
||||
ATOMIC_OPS(add, i, add, +)
|
||||
ATOMIC_OPS(sub, -i, add, +)
|
||||
|
||||
#define arch_atomic_add_return arch_atomic_add_return
|
||||
#define arch_atomic_add_return_acquire arch_atomic_add_return
|
||||
#define arch_atomic_add_return_release arch_atomic_add_return
|
||||
#define arch_atomic_add_return_relaxed arch_atomic_add_return_relaxed
|
||||
#define arch_atomic_sub_return arch_atomic_sub_return
|
||||
#define arch_atomic_sub_return_acquire arch_atomic_sub_return
|
||||
#define arch_atomic_sub_return_release arch_atomic_sub_return
|
||||
#define arch_atomic_sub_return_relaxed arch_atomic_sub_return_relaxed
|
||||
#define arch_atomic_fetch_add arch_atomic_fetch_add
|
||||
#define arch_atomic_fetch_add_acquire arch_atomic_fetch_add
|
||||
#define arch_atomic_fetch_add_release arch_atomic_fetch_add
|
||||
#define arch_atomic_fetch_add_relaxed arch_atomic_fetch_add_relaxed
|
||||
#define arch_atomic_fetch_sub arch_atomic_fetch_sub
|
||||
#define arch_atomic_fetch_sub_acquire arch_atomic_fetch_sub
|
||||
#define arch_atomic_fetch_sub_release arch_atomic_fetch_sub
|
||||
#define arch_atomic_fetch_sub_relaxed arch_atomic_fetch_sub_relaxed
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
|
||||
#define ATOMIC_OPS(op, I, asm_op) \
|
||||
ATOMIC_OP(op, I, asm_op) \
|
||||
ATOMIC_FETCH_OP(op, I, asm_op)
|
||||
ATOMIC_FETCH_OP(op, I, asm_op, _db, ) \
|
||||
ATOMIC_FETCH_OP(op, I, asm_op, , _relaxed)
|
||||
|
||||
ATOMIC_OPS(and, i, and)
|
||||
ATOMIC_OPS(or, i, or)
|
||||
ATOMIC_OPS(xor, i, xor)
|
||||
|
||||
#define arch_atomic_fetch_and arch_atomic_fetch_and
|
||||
#define arch_atomic_fetch_and_acquire arch_atomic_fetch_and
|
||||
#define arch_atomic_fetch_and_release arch_atomic_fetch_and
|
||||
#define arch_atomic_fetch_and_relaxed arch_atomic_fetch_and_relaxed
|
||||
#define arch_atomic_fetch_or arch_atomic_fetch_or
|
||||
#define arch_atomic_fetch_or_acquire arch_atomic_fetch_or
|
||||
#define arch_atomic_fetch_or_release arch_atomic_fetch_or
|
||||
#define arch_atomic_fetch_or_relaxed arch_atomic_fetch_or_relaxed
|
||||
#define arch_atomic_fetch_xor arch_atomic_fetch_xor
|
||||
#define arch_atomic_fetch_xor_acquire arch_atomic_fetch_xor
|
||||
#define arch_atomic_fetch_xor_release arch_atomic_fetch_xor
|
||||
#define arch_atomic_fetch_xor_relaxed arch_atomic_fetch_xor_relaxed
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
@@ -172,18 +196,18 @@ static inline int arch_atomic_sub_if_positive(int i, atomic_t *v)
|
||||
static inline void arch_atomic64_##op(long i, atomic64_t *v) \
|
||||
{ \
|
||||
__asm__ __volatile__( \
|
||||
"am"#asm_op"_db.d " " $zero, %1, %0 \n" \
|
||||
"am"#asm_op".d " " $zero, %1, %0 \n" \
|
||||
: "+ZB" (v->counter) \
|
||||
: "r" (I) \
|
||||
: "memory"); \
|
||||
}
|
||||
|
||||
#define ATOMIC64_OP_RETURN(op, I, asm_op, c_op) \
|
||||
static inline long arch_atomic64_##op##_return_relaxed(long i, atomic64_t *v) \
|
||||
#define ATOMIC64_OP_RETURN(op, I, asm_op, c_op, mb, suffix) \
|
||||
static inline long arch_atomic64_##op##_return##suffix(long i, atomic64_t *v) \
|
||||
{ \
|
||||
long result; \
|
||||
__asm__ __volatile__( \
|
||||
"am"#asm_op"_db.d " " %1, %2, %0 \n" \
|
||||
"am"#asm_op#mb".d " " %1, %2, %0 \n" \
|
||||
: "+ZB" (v->counter), "=&r" (result) \
|
||||
: "r" (I) \
|
||||
: "memory"); \
|
||||
@@ -191,13 +215,13 @@ static inline long arch_atomic64_##op##_return_relaxed(long i, atomic64_t *v) \
|
||||
return result c_op I; \
|
||||
}
|
||||
|
||||
#define ATOMIC64_FETCH_OP(op, I, asm_op) \
|
||||
static inline long arch_atomic64_fetch_##op##_relaxed(long i, atomic64_t *v) \
|
||||
#define ATOMIC64_FETCH_OP(op, I, asm_op, mb, suffix) \
|
||||
static inline long arch_atomic64_fetch_##op##suffix(long i, atomic64_t *v) \
|
||||
{ \
|
||||
long result; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
"am"#asm_op"_db.d " " %1, %2, %0 \n" \
|
||||
"am"#asm_op#mb".d " " %1, %2, %0 \n" \
|
||||
: "+ZB" (v->counter), "=&r" (result) \
|
||||
: "r" (I) \
|
||||
: "memory"); \
|
||||
@@ -207,29 +231,53 @@ static inline long arch_atomic64_fetch_##op##_relaxed(long i, atomic64_t *v) \
|
||||
|
||||
#define ATOMIC64_OPS(op, I, asm_op, c_op) \
|
||||
ATOMIC64_OP(op, I, asm_op) \
|
||||
ATOMIC64_OP_RETURN(op, I, asm_op, c_op) \
|
||||
ATOMIC64_FETCH_OP(op, I, asm_op)
|
||||
ATOMIC64_OP_RETURN(op, I, asm_op, c_op, _db, ) \
|
||||
ATOMIC64_OP_RETURN(op, I, asm_op, c_op, , _relaxed) \
|
||||
ATOMIC64_FETCH_OP(op, I, asm_op, _db, ) \
|
||||
ATOMIC64_FETCH_OP(op, I, asm_op, , _relaxed)
|
||||
|
||||
ATOMIC64_OPS(add, i, add, +)
|
||||
ATOMIC64_OPS(sub, -i, add, +)
|
||||
|
||||
#define arch_atomic64_add_return arch_atomic64_add_return
|
||||
#define arch_atomic64_add_return_acquire arch_atomic64_add_return
|
||||
#define arch_atomic64_add_return_release arch_atomic64_add_return
|
||||
#define arch_atomic64_add_return_relaxed arch_atomic64_add_return_relaxed
|
||||
#define arch_atomic64_sub_return arch_atomic64_sub_return
|
||||
#define arch_atomic64_sub_return_acquire arch_atomic64_sub_return
|
||||
#define arch_atomic64_sub_return_release arch_atomic64_sub_return
|
||||
#define arch_atomic64_sub_return_relaxed arch_atomic64_sub_return_relaxed
|
||||
#define arch_atomic64_fetch_add arch_atomic64_fetch_add
|
||||
#define arch_atomic64_fetch_add_acquire arch_atomic64_fetch_add
|
||||
#define arch_atomic64_fetch_add_release arch_atomic64_fetch_add
|
||||
#define arch_atomic64_fetch_add_relaxed arch_atomic64_fetch_add_relaxed
|
||||
#define arch_atomic64_fetch_sub arch_atomic64_fetch_sub
|
||||
#define arch_atomic64_fetch_sub_acquire arch_atomic64_fetch_sub
|
||||
#define arch_atomic64_fetch_sub_release arch_atomic64_fetch_sub
|
||||
#define arch_atomic64_fetch_sub_relaxed arch_atomic64_fetch_sub_relaxed
|
||||
|
||||
#undef ATOMIC64_OPS
|
||||
|
||||
#define ATOMIC64_OPS(op, I, asm_op) \
|
||||
ATOMIC64_OP(op, I, asm_op) \
|
||||
ATOMIC64_FETCH_OP(op, I, asm_op)
|
||||
ATOMIC64_FETCH_OP(op, I, asm_op, _db, ) \
|
||||
ATOMIC64_FETCH_OP(op, I, asm_op, , _relaxed)
|
||||
|
||||
ATOMIC64_OPS(and, i, and)
|
||||
ATOMIC64_OPS(or, i, or)
|
||||
ATOMIC64_OPS(xor, i, xor)
|
||||
|
||||
#define arch_atomic64_fetch_and arch_atomic64_fetch_and
|
||||
#define arch_atomic64_fetch_and_acquire arch_atomic64_fetch_and
|
||||
#define arch_atomic64_fetch_and_release arch_atomic64_fetch_and
|
||||
#define arch_atomic64_fetch_and_relaxed arch_atomic64_fetch_and_relaxed
|
||||
#define arch_atomic64_fetch_or arch_atomic64_fetch_or
|
||||
#define arch_atomic64_fetch_or_acquire arch_atomic64_fetch_or
|
||||
#define arch_atomic64_fetch_or_release arch_atomic64_fetch_or
|
||||
#define arch_atomic64_fetch_or_relaxed arch_atomic64_fetch_or_relaxed
|
||||
#define arch_atomic64_fetch_xor arch_atomic64_fetch_xor
|
||||
#define arch_atomic64_fetch_xor_acquire arch_atomic64_fetch_xor
|
||||
#define arch_atomic64_fetch_xor_release arch_atomic64_fetch_xor
|
||||
#define arch_atomic64_fetch_xor_relaxed arch_atomic64_fetch_xor_relaxed
|
||||
|
||||
#undef ATOMIC64_OPS
|
||||
|
||||
@@ -65,6 +65,8 @@ enum reg2_op {
|
||||
revbd_op = 0x0f,
|
||||
revh2w_op = 0x10,
|
||||
revhd_op = 0x11,
|
||||
extwh_op = 0x16,
|
||||
extwb_op = 0x17,
|
||||
iocsrrdb_op = 0x19200,
|
||||
iocsrrdh_op = 0x19201,
|
||||
iocsrrdw_op = 0x19202,
|
||||
@@ -572,6 +574,8 @@ static inline void emit_##NAME(union loongarch_instruction *insn, \
|
||||
DEF_EMIT_REG2_FORMAT(revb2h, revb2h_op)
|
||||
DEF_EMIT_REG2_FORMAT(revb2w, revb2w_op)
|
||||
DEF_EMIT_REG2_FORMAT(revbd, revbd_op)
|
||||
DEF_EMIT_REG2_FORMAT(extwh, extwh_op)
|
||||
DEF_EMIT_REG2_FORMAT(extwb, extwb_op)
|
||||
|
||||
#define DEF_EMIT_REG2I5_FORMAT(NAME, OP) \
|
||||
static inline void emit_##NAME(union loongarch_instruction *insn, \
|
||||
@@ -623,6 +627,9 @@ DEF_EMIT_REG2I12_FORMAT(lu52id, lu52id_op)
|
||||
DEF_EMIT_REG2I12_FORMAT(andi, andi_op)
|
||||
DEF_EMIT_REG2I12_FORMAT(ori, ori_op)
|
||||
DEF_EMIT_REG2I12_FORMAT(xori, xori_op)
|
||||
DEF_EMIT_REG2I12_FORMAT(ldb, ldb_op)
|
||||
DEF_EMIT_REG2I12_FORMAT(ldh, ldh_op)
|
||||
DEF_EMIT_REG2I12_FORMAT(ldw, ldw_op)
|
||||
DEF_EMIT_REG2I12_FORMAT(ldbu, ldbu_op)
|
||||
DEF_EMIT_REG2I12_FORMAT(ldhu, ldhu_op)
|
||||
DEF_EMIT_REG2I12_FORMAT(ldwu, ldwu_op)
|
||||
@@ -701,9 +708,12 @@ static inline void emit_##NAME(union loongarch_instruction *insn, \
|
||||
insn->reg3_format.rk = rk; \
|
||||
}
|
||||
|
||||
DEF_EMIT_REG3_FORMAT(addw, addw_op)
|
||||
DEF_EMIT_REG3_FORMAT(addd, addd_op)
|
||||
DEF_EMIT_REG3_FORMAT(subd, subd_op)
|
||||
DEF_EMIT_REG3_FORMAT(muld, muld_op)
|
||||
DEF_EMIT_REG3_FORMAT(divd, divd_op)
|
||||
DEF_EMIT_REG3_FORMAT(modd, modd_op)
|
||||
DEF_EMIT_REG3_FORMAT(divdu, divdu_op)
|
||||
DEF_EMIT_REG3_FORMAT(moddu, moddu_op)
|
||||
DEF_EMIT_REG3_FORMAT(and, and_op)
|
||||
@@ -715,6 +725,9 @@ DEF_EMIT_REG3_FORMAT(srlw, srlw_op)
|
||||
DEF_EMIT_REG3_FORMAT(srld, srld_op)
|
||||
DEF_EMIT_REG3_FORMAT(sraw, sraw_op)
|
||||
DEF_EMIT_REG3_FORMAT(srad, srad_op)
|
||||
DEF_EMIT_REG3_FORMAT(ldxb, ldxb_op)
|
||||
DEF_EMIT_REG3_FORMAT(ldxh, ldxh_op)
|
||||
DEF_EMIT_REG3_FORMAT(ldxw, ldxw_op)
|
||||
DEF_EMIT_REG3_FORMAT(ldxbu, ldxbu_op)
|
||||
DEF_EMIT_REG3_FORMAT(ldxhu, ldxhu_op)
|
||||
DEF_EMIT_REG3_FORMAT(ldxwu, ldxwu_op)
|
||||
|
||||
@@ -32,7 +32,7 @@ static inline void set_my_cpu_offset(unsigned long off)
|
||||
#define __my_cpu_offset __my_cpu_offset
|
||||
|
||||
#define PERCPU_OP(op, asm_op, c_op) \
|
||||
static inline unsigned long __percpu_##op(void *ptr, \
|
||||
static __always_inline unsigned long __percpu_##op(void *ptr, \
|
||||
unsigned long val, int size) \
|
||||
{ \
|
||||
unsigned long ret; \
|
||||
@@ -63,7 +63,7 @@ PERCPU_OP(and, and, &)
|
||||
PERCPU_OP(or, or, |)
|
||||
#undef PERCPU_OP
|
||||
|
||||
static inline unsigned long __percpu_read(void *ptr, int size)
|
||||
static __always_inline unsigned long __percpu_read(void *ptr, int size)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
@@ -100,7 +100,7 @@ static inline unsigned long __percpu_read(void *ptr, int size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void __percpu_write(void *ptr, unsigned long val, int size)
|
||||
static __always_inline void __percpu_write(void *ptr, unsigned long val, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
@@ -132,8 +132,8 @@ static inline void __percpu_write(void *ptr, unsigned long val, int size)
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned long __percpu_xchg(void *ptr, unsigned long val,
|
||||
int size)
|
||||
static __always_inline unsigned long __percpu_xchg(void *ptr, unsigned long val,
|
||||
int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
|
||||
@@ -504,8 +504,9 @@ asmlinkage void start_secondary(void)
|
||||
unsigned int cpu;
|
||||
|
||||
sync_counter();
|
||||
cpu = smp_processor_id();
|
||||
cpu = raw_smp_processor_id();
|
||||
set_my_cpu_offset(per_cpu_offset(cpu));
|
||||
rcutree_report_cpu_starting(cpu);
|
||||
|
||||
cpu_probe();
|
||||
constant_clockevent_init();
|
||||
|
||||
+112
-31
@@ -411,7 +411,11 @@ static int add_exception_handler(const struct bpf_insn *insn,
|
||||
off_t offset;
|
||||
struct exception_table_entry *ex;
|
||||
|
||||
if (!ctx->image || !ctx->prog->aux->extable || BPF_MODE(insn->code) != BPF_PROBE_MEM)
|
||||
if (!ctx->image || !ctx->prog->aux->extable)
|
||||
return 0;
|
||||
|
||||
if (BPF_MODE(insn->code) != BPF_PROBE_MEM &&
|
||||
BPF_MODE(insn->code) != BPF_PROBE_MEMSX)
|
||||
return 0;
|
||||
|
||||
if (WARN_ON_ONCE(ctx->num_exentries >= ctx->prog->aux->num_exentries))
|
||||
@@ -450,7 +454,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
|
||||
{
|
||||
u8 tm = -1;
|
||||
u64 func_addr;
|
||||
bool func_addr_fixed;
|
||||
bool func_addr_fixed, sign_extend;
|
||||
int i = insn - ctx->prog->insnsi;
|
||||
int ret, jmp_offset;
|
||||
const u8 code = insn->code;
|
||||
@@ -468,8 +472,23 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
|
||||
/* dst = src */
|
||||
case BPF_ALU | BPF_MOV | BPF_X:
|
||||
case BPF_ALU64 | BPF_MOV | BPF_X:
|
||||
move_reg(ctx, dst, src);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
switch (off) {
|
||||
case 0:
|
||||
move_reg(ctx, dst, src);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
break;
|
||||
case 8:
|
||||
move_reg(ctx, t1, src);
|
||||
emit_insn(ctx, extwb, dst, t1);
|
||||
break;
|
||||
case 16:
|
||||
move_reg(ctx, t1, src);
|
||||
emit_insn(ctx, extwh, dst, t1);
|
||||
break;
|
||||
case 32:
|
||||
emit_insn(ctx, addw, dst, src, LOONGARCH_GPR_ZERO);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* dst = imm */
|
||||
@@ -534,39 +553,71 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
|
||||
/* dst = dst / src */
|
||||
case BPF_ALU | BPF_DIV | BPF_X:
|
||||
case BPF_ALU64 | BPF_DIV | BPF_X:
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
move_reg(ctx, t1, src);
|
||||
emit_zext_32(ctx, t1, is32);
|
||||
emit_insn(ctx, divdu, dst, dst, t1);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
if (!off) {
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
move_reg(ctx, t1, src);
|
||||
emit_zext_32(ctx, t1, is32);
|
||||
emit_insn(ctx, divdu, dst, dst, t1);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
} else {
|
||||
emit_sext_32(ctx, dst, is32);
|
||||
move_reg(ctx, t1, src);
|
||||
emit_sext_32(ctx, t1, is32);
|
||||
emit_insn(ctx, divd, dst, dst, t1);
|
||||
emit_sext_32(ctx, dst, is32);
|
||||
}
|
||||
break;
|
||||
|
||||
/* dst = dst / imm */
|
||||
case BPF_ALU | BPF_DIV | BPF_K:
|
||||
case BPF_ALU64 | BPF_DIV | BPF_K:
|
||||
move_imm(ctx, t1, imm, is32);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
emit_insn(ctx, divdu, dst, dst, t1);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
if (!off) {
|
||||
move_imm(ctx, t1, imm, is32);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
emit_insn(ctx, divdu, dst, dst, t1);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
} else {
|
||||
move_imm(ctx, t1, imm, false);
|
||||
emit_sext_32(ctx, t1, is32);
|
||||
emit_sext_32(ctx, dst, is32);
|
||||
emit_insn(ctx, divd, dst, dst, t1);
|
||||
emit_sext_32(ctx, dst, is32);
|
||||
}
|
||||
break;
|
||||
|
||||
/* dst = dst % src */
|
||||
case BPF_ALU | BPF_MOD | BPF_X:
|
||||
case BPF_ALU64 | BPF_MOD | BPF_X:
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
move_reg(ctx, t1, src);
|
||||
emit_zext_32(ctx, t1, is32);
|
||||
emit_insn(ctx, moddu, dst, dst, t1);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
if (!off) {
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
move_reg(ctx, t1, src);
|
||||
emit_zext_32(ctx, t1, is32);
|
||||
emit_insn(ctx, moddu, dst, dst, t1);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
} else {
|
||||
emit_sext_32(ctx, dst, is32);
|
||||
move_reg(ctx, t1, src);
|
||||
emit_sext_32(ctx, t1, is32);
|
||||
emit_insn(ctx, modd, dst, dst, t1);
|
||||
emit_sext_32(ctx, dst, is32);
|
||||
}
|
||||
break;
|
||||
|
||||
/* dst = dst % imm */
|
||||
case BPF_ALU | BPF_MOD | BPF_K:
|
||||
case BPF_ALU64 | BPF_MOD | BPF_K:
|
||||
move_imm(ctx, t1, imm, is32);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
emit_insn(ctx, moddu, dst, dst, t1);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
if (!off) {
|
||||
move_imm(ctx, t1, imm, is32);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
emit_insn(ctx, moddu, dst, dst, t1);
|
||||
emit_zext_32(ctx, dst, is32);
|
||||
} else {
|
||||
move_imm(ctx, t1, imm, false);
|
||||
emit_sext_32(ctx, t1, is32);
|
||||
emit_sext_32(ctx, dst, is32);
|
||||
emit_insn(ctx, modd, dst, dst, t1);
|
||||
emit_sext_32(ctx, dst, is32);
|
||||
}
|
||||
break;
|
||||
|
||||
/* dst = -dst */
|
||||
@@ -712,6 +763,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
|
||||
break;
|
||||
|
||||
case BPF_ALU | BPF_END | BPF_FROM_BE:
|
||||
case BPF_ALU64 | BPF_END | BPF_FROM_LE:
|
||||
switch (imm) {
|
||||
case 16:
|
||||
emit_insn(ctx, revb2h, dst, dst);
|
||||
@@ -828,7 +880,11 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
|
||||
|
||||
/* PC += off */
|
||||
case BPF_JMP | BPF_JA:
|
||||
jmp_offset = bpf2la_offset(i, off, ctx);
|
||||
case BPF_JMP32 | BPF_JA:
|
||||
if (BPF_CLASS(code) == BPF_JMP)
|
||||
jmp_offset = bpf2la_offset(i, off, ctx);
|
||||
else
|
||||
jmp_offset = bpf2la_offset(i, imm, ctx);
|
||||
if (emit_uncond_jmp(ctx, jmp_offset) < 0)
|
||||
goto toofar;
|
||||
break;
|
||||
@@ -879,31 +935,56 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
|
||||
case BPF_LDX | BPF_PROBE_MEM | BPF_W:
|
||||
case BPF_LDX | BPF_PROBE_MEM | BPF_H:
|
||||
case BPF_LDX | BPF_PROBE_MEM | BPF_B:
|
||||
/* dst_reg = (s64)*(signed size *)(src_reg + off) */
|
||||
case BPF_LDX | BPF_MEMSX | BPF_B:
|
||||
case BPF_LDX | BPF_MEMSX | BPF_H:
|
||||
case BPF_LDX | BPF_MEMSX | BPF_W:
|
||||
case BPF_LDX | BPF_PROBE_MEMSX | BPF_B:
|
||||
case BPF_LDX | BPF_PROBE_MEMSX | BPF_H:
|
||||
case BPF_LDX | BPF_PROBE_MEMSX | BPF_W:
|
||||
sign_extend = BPF_MODE(insn->code) == BPF_MEMSX ||
|
||||
BPF_MODE(insn->code) == BPF_PROBE_MEMSX;
|
||||
switch (BPF_SIZE(code)) {
|
||||
case BPF_B:
|
||||
if (is_signed_imm12(off)) {
|
||||
emit_insn(ctx, ldbu, dst, src, off);
|
||||
if (sign_extend)
|
||||
emit_insn(ctx, ldb, dst, src, off);
|
||||
else
|
||||
emit_insn(ctx, ldbu, dst, src, off);
|
||||
} else {
|
||||
move_imm(ctx, t1, off, is32);
|
||||
emit_insn(ctx, ldxbu, dst, src, t1);
|
||||
if (sign_extend)
|
||||
emit_insn(ctx, ldxb, dst, src, t1);
|
||||
else
|
||||
emit_insn(ctx, ldxbu, dst, src, t1);
|
||||
}
|
||||
break;
|
||||
case BPF_H:
|
||||
if (is_signed_imm12(off)) {
|
||||
emit_insn(ctx, ldhu, dst, src, off);
|
||||
if (sign_extend)
|
||||
emit_insn(ctx, ldh, dst, src, off);
|
||||
else
|
||||
emit_insn(ctx, ldhu, dst, src, off);
|
||||
} else {
|
||||
move_imm(ctx, t1, off, is32);
|
||||
emit_insn(ctx, ldxhu, dst, src, t1);
|
||||
if (sign_extend)
|
||||
emit_insn(ctx, ldxh, dst, src, t1);
|
||||
else
|
||||
emit_insn(ctx, ldxhu, dst, src, t1);
|
||||
}
|
||||
break;
|
||||
case BPF_W:
|
||||
if (is_signed_imm12(off)) {
|
||||
emit_insn(ctx, ldwu, dst, src, off);
|
||||
} else if (is_signed_imm14(off)) {
|
||||
emit_insn(ctx, ldptrw, dst, src, off);
|
||||
if (sign_extend)
|
||||
emit_insn(ctx, ldw, dst, src, off);
|
||||
else
|
||||
emit_insn(ctx, ldwu, dst, src, off);
|
||||
} else {
|
||||
move_imm(ctx, t1, off, is32);
|
||||
emit_insn(ctx, ldxwu, dst, src, t1);
|
||||
if (sign_extend)
|
||||
emit_insn(ctx, ldxw, dst, src, t1);
|
||||
else
|
||||
emit_insn(ctx, ldxwu, dst, src, t1);
|
||||
}
|
||||
break;
|
||||
case BPF_DW:
|
||||
|
||||
@@ -71,8 +71,6 @@ struct kprobe_ctlblk {
|
||||
struct prev_kprobe prev_kprobe;
|
||||
};
|
||||
|
||||
extern int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
|
||||
#endif /* CONFIG_KPROBES */
|
||||
#endif /* _ASM_KPROBES_H */
|
||||
|
||||
@@ -475,13 +475,13 @@
|
||||
* to a CPU TLB 4k PFN (4k => 12 bits to shift) */
|
||||
#define PAGE_ADD_SHIFT (PAGE_SHIFT-12)
|
||||
#define PAGE_ADD_HUGE_SHIFT (REAL_HPAGE_SHIFT-12)
|
||||
#define PFN_START_BIT (63-ASM_PFN_PTE_SHIFT+(63-58)-PAGE_ADD_SHIFT)
|
||||
|
||||
/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
|
||||
.macro convert_for_tlb_insert20 pte,tmp
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
copy \pte,\tmp
|
||||
extrd,u \tmp,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
|
||||
64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
|
||||
extrd,u \tmp,PFN_START_BIT,PFN_START_BIT+1,\pte
|
||||
|
||||
depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\
|
||||
(63-58)+PAGE_ADD_SHIFT,\pte
|
||||
@@ -489,8 +489,7 @@
|
||||
depdi _HUGE_PAGE_SIZE_ENCODING_DEFAULT,63,\
|
||||
(63-58)+PAGE_ADD_HUGE_SHIFT,\pte
|
||||
#else /* Huge pages disabled */
|
||||
extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
|
||||
64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
|
||||
extrd,u \pte,PFN_START_BIT,PFN_START_BIT+1,\pte
|
||||
depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\
|
||||
(63-58)+PAGE_ADD_SHIFT,\pte
|
||||
#endif
|
||||
|
||||
@@ -70,9 +70,8 @@ $bss_loop:
|
||||
stw,ma %arg2,4(%r1)
|
||||
stw,ma %arg3,4(%r1)
|
||||
|
||||
#if !defined(CONFIG_64BIT) && defined(CONFIG_PA20)
|
||||
/* This 32-bit kernel was compiled for PA2.0 CPUs. Check current CPU
|
||||
* and halt kernel if we detect a PA1.x CPU. */
|
||||
#if defined(CONFIG_PA20)
|
||||
/* check for 64-bit capable CPU as required by current kernel */
|
||||
ldi 32,%r10
|
||||
mtctl %r10,%cr11
|
||||
.level 2.0
|
||||
|
||||
@@ -8,12 +8,7 @@ static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
|
||||
unsigned long vm_start, unsigned long vm_end,
|
||||
unsigned long offset)
|
||||
{
|
||||
/*
|
||||
* PowerPC's implementation of phys_mem_access_prot() does
|
||||
* not use the file argument. Set it to NULL in preparation
|
||||
* of later updates to the interface.
|
||||
*/
|
||||
return phys_mem_access_prot(NULL, PHYS_PFN(offset), vm_end - vm_start, prot);
|
||||
return __phys_mem_access_prot(PHYS_PFN(offset), vm_end - vm_start, prot);
|
||||
}
|
||||
#define pgprot_framebuffer pgprot_framebuffer
|
||||
|
||||
|
||||
@@ -84,8 +84,6 @@ struct arch_optimized_insn {
|
||||
kprobe_opcode_t *insn;
|
||||
};
|
||||
|
||||
extern int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
|
||||
extern int kprobe_handler(struct pt_regs *regs);
|
||||
extern int kprobe_post_handler(struct pt_regs *regs);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <linux/export.h>
|
||||
|
||||
struct pt_regs;
|
||||
struct pci_bus;
|
||||
struct pci_bus;
|
||||
struct device_node;
|
||||
struct iommu_table;
|
||||
struct rtc_time;
|
||||
@@ -78,8 +78,8 @@ struct machdep_calls {
|
||||
unsigned char (*nvram_read_val)(int addr);
|
||||
void (*nvram_write_val)(int addr, unsigned char val);
|
||||
ssize_t (*nvram_write)(char *buf, size_t count, loff_t *index);
|
||||
ssize_t (*nvram_read)(char *buf, size_t count, loff_t *index);
|
||||
ssize_t (*nvram_size)(void);
|
||||
ssize_t (*nvram_read)(char *buf, size_t count, loff_t *index);
|
||||
ssize_t (*nvram_size)(void);
|
||||
void (*nvram_sync)(void);
|
||||
|
||||
/* Exception handlers */
|
||||
@@ -102,12 +102,11 @@ struct machdep_calls {
|
||||
*/
|
||||
long (*feature_call)(unsigned int feature, ...);
|
||||
|
||||
/* Get legacy PCI/IDE interrupt mapping */
|
||||
/* Get legacy PCI/IDE interrupt mapping */
|
||||
int (*pci_get_legacy_ide_irq)(struct pci_dev *dev, int channel);
|
||||
|
||||
|
||||
/* Get access protection for /dev/mem */
|
||||
pgprot_t (*phys_mem_access_prot)(struct file *file,
|
||||
unsigned long pfn,
|
||||
pgprot_t (*phys_mem_access_prot)(unsigned long pfn,
|
||||
unsigned long size,
|
||||
pgprot_t vma_prot);
|
||||
|
||||
|
||||
@@ -105,9 +105,7 @@ extern void of_scan_pci_bridge(struct pci_dev *dev);
|
||||
extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
|
||||
extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus);
|
||||
|
||||
struct file;
|
||||
extern pgprot_t pci_phys_mem_access_prot(struct file *file,
|
||||
unsigned long pfn,
|
||||
extern pgprot_t pci_phys_mem_access_prot(unsigned long pfn,
|
||||
unsigned long size,
|
||||
pgprot_t prot);
|
||||
|
||||
|
||||
@@ -120,9 +120,15 @@ static inline void mark_initmem_nx(void) { }
|
||||
int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
|
||||
pte_t *ptep, pte_t entry, int dirty);
|
||||
|
||||
pgprot_t __phys_mem_access_prot(unsigned long pfn, unsigned long size,
|
||||
pgprot_t vma_prot);
|
||||
|
||||
struct file;
|
||||
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
||||
unsigned long size, pgprot_t vma_prot);
|
||||
static inline pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
||||
unsigned long size, pgprot_t vma_prot)
|
||||
{
|
||||
return __phys_mem_access_prot(pfn, size, vma_prot);
|
||||
}
|
||||
#define __HAVE_PHYS_MEM_ACCESS_PROT
|
||||
|
||||
void __update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep);
|
||||
|
||||
@@ -521,8 +521,7 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma)
|
||||
* PCI device, it tries to find the PCI device first and calls the
|
||||
* above routine
|
||||
*/
|
||||
pgprot_t pci_phys_mem_access_prot(struct file *file,
|
||||
unsigned long pfn,
|
||||
pgprot_t pci_phys_mem_access_prot(unsigned long pfn,
|
||||
unsigned long size,
|
||||
pgprot_t prot)
|
||||
{
|
||||
|
||||
@@ -752,6 +752,8 @@ static int ppc_rtas_tone_volume_show(struct seq_file *m, void *v)
|
||||
|
||||
/**
|
||||
* ppc_rtas_rmo_buf_show() - Describe RTAS-addressable region for user space.
|
||||
* @m: seq_file output target.
|
||||
* @v: Unused.
|
||||
*
|
||||
* Base + size description of a range of RTAS-addressable memory set
|
||||
* aside for user space to use as work area(s) for certain RTAS
|
||||
|
||||
@@ -35,18 +35,18 @@ unsigned long long memory_limit;
|
||||
unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] __page_aligned_bss;
|
||||
EXPORT_SYMBOL(empty_zero_page);
|
||||
|
||||
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
||||
unsigned long size, pgprot_t vma_prot)
|
||||
pgprot_t __phys_mem_access_prot(unsigned long pfn, unsigned long size,
|
||||
pgprot_t vma_prot)
|
||||
{
|
||||
if (ppc_md.phys_mem_access_prot)
|
||||
return ppc_md.phys_mem_access_prot(file, pfn, size, vma_prot);
|
||||
return ppc_md.phys_mem_access_prot(pfn, size, vma_prot);
|
||||
|
||||
if (!page_is_ram(pfn))
|
||||
vma_prot = pgprot_noncached(vma_prot);
|
||||
|
||||
return vma_prot;
|
||||
}
|
||||
EXPORT_SYMBOL(phys_mem_access_prot);
|
||||
EXPORT_SYMBOL(__phys_mem_access_prot);
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
static DEFINE_MUTEX(linear_mapping_mutex);
|
||||
|
||||
@@ -184,6 +184,7 @@ machine_arch_initcall(pseries, rtas_work_area_allocator_init);
|
||||
|
||||
/**
|
||||
* rtas_work_area_reserve_arena() - Reserve memory suitable for RTAS work areas.
|
||||
* @limit: Upper limit for memblock allocation.
|
||||
*/
|
||||
void __init rtas_work_area_reserve_arena(const phys_addr_t limit)
|
||||
{
|
||||
|
||||
@@ -73,8 +73,6 @@ struct kprobe_ctlblk {
|
||||
void arch_remove_kprobe(struct kprobe *p);
|
||||
|
||||
int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
|
||||
int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
|
||||
#define flush_insn_slot(p) do { } while (0)
|
||||
|
||||
|
||||
@@ -46,8 +46,6 @@ struct kprobe_ctlblk {
|
||||
};
|
||||
|
||||
extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
|
||||
extern int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
extern int kprobe_handle_illslot(unsigned long pc);
|
||||
#else
|
||||
|
||||
|
||||
@@ -47,8 +47,6 @@ struct kprobe_ctlblk {
|
||||
struct prev_kprobe prev_kprobe;
|
||||
};
|
||||
|
||||
int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
|
||||
asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
|
||||
struct pt_regs *regs);
|
||||
|
||||
@@ -113,8 +113,6 @@ struct kprobe_ctlblk {
|
||||
};
|
||||
|
||||
extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
|
||||
extern int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
extern int kprobe_int3_handler(struct pt_regs *regs);
|
||||
|
||||
#else
|
||||
|
||||
+2
-2
@@ -501,8 +501,8 @@ static inline void bio_check_ro(struct bio *bio)
|
||||
if (op_is_write(bio_op(bio)) && bdev_read_only(bio->bi_bdev)) {
|
||||
if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
|
||||
return;
|
||||
pr_warn("Trying to write to read-only block-device %pg\n",
|
||||
bio->bi_bdev);
|
||||
pr_warn_ratelimited("Trying to write to read-only block-device %pg\n",
|
||||
bio->bi_bdev);
|
||||
/* Older lvm-tools actually trigger this */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6180,24 +6180,10 @@ EXPORT_SYMBOL_GPL(ata_pci_remove_one);
|
||||
void ata_pci_shutdown_one(struct pci_dev *pdev)
|
||||
{
|
||||
struct ata_host *host = pci_get_drvdata(pdev);
|
||||
struct ata_port *ap;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
/* Tell EH to disable all devices */
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
ap = host->ports[i];
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
ap->pflags |= ATA_PFLAG_UNLOADING;
|
||||
ata_port_schedule_eh(ap);
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
}
|
||||
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
ap = host->ports[i];
|
||||
|
||||
/* Wait for EH to complete before freezing the port */
|
||||
ata_port_wait_eh(ap);
|
||||
struct ata_port *ap = host->ports[i];
|
||||
|
||||
ap->pflags |= ATA_PFLAG_FROZEN;
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ static struct ata_port_operations pata_falcon_ops = {
|
||||
.set_mode = pata_falcon_set_mode,
|
||||
};
|
||||
|
||||
static int __init pata_falcon_init_one(struct platform_device *pdev)
|
||||
static int pata_falcon_init_one(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *base_mem_res, *ctl_mem_res;
|
||||
struct resource *base_res, *ctl_res, *irq_res;
|
||||
@@ -216,23 +216,22 @@ static int __init pata_falcon_init_one(struct platform_device *pdev)
|
||||
IRQF_SHARED, &pata_falcon_sht);
|
||||
}
|
||||
|
||||
static int __exit pata_falcon_remove_one(struct platform_device *pdev)
|
||||
static void pata_falcon_remove_one(struct platform_device *pdev)
|
||||
{
|
||||
struct ata_host *host = platform_get_drvdata(pdev);
|
||||
|
||||
ata_host_detach(host);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver pata_falcon_driver = {
|
||||
.remove = __exit_p(pata_falcon_remove_one),
|
||||
.probe = pata_falcon_init_one,
|
||||
.remove_new = pata_falcon_remove_one,
|
||||
.driver = {
|
||||
.name = "atari-falcon-ide",
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver_probe(pata_falcon_driver, pata_falcon_init_one);
|
||||
module_platform_driver(pata_falcon_driver);
|
||||
|
||||
MODULE_AUTHOR("Bartlomiej Zolnierkiewicz");
|
||||
MODULE_DESCRIPTION("low-level driver for Atari Falcon PATA");
|
||||
|
||||
@@ -124,7 +124,7 @@ static struct ata_port_operations pata_gayle_a4000_ops = {
|
||||
.set_mode = pata_gayle_set_mode,
|
||||
};
|
||||
|
||||
static int __init pata_gayle_init_one(struct platform_device *pdev)
|
||||
static int pata_gayle_init_one(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct gayle_ide_platform_data *pdata;
|
||||
@@ -193,23 +193,22 @@ static int __init pata_gayle_init_one(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit pata_gayle_remove_one(struct platform_device *pdev)
|
||||
static void pata_gayle_remove_one(struct platform_device *pdev)
|
||||
{
|
||||
struct ata_host *host = platform_get_drvdata(pdev);
|
||||
|
||||
ata_host_detach(host);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver pata_gayle_driver = {
|
||||
.remove = __exit_p(pata_gayle_remove_one),
|
||||
.probe = pata_gayle_init_one,
|
||||
.remove_new = pata_gayle_remove_one,
|
||||
.driver = {
|
||||
.name = "amiga-gayle-ide",
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver_probe(pata_gayle_driver, pata_gayle_init_one);
|
||||
module_platform_driver(pata_gayle_driver);
|
||||
|
||||
MODULE_AUTHOR("Bartlomiej Zolnierkiewicz");
|
||||
MODULE_DESCRIPTION("low-level driver for Amiga Gayle PATA");
|
||||
|
||||
+9
-2
@@ -250,7 +250,6 @@ static void nbd_dev_remove(struct nbd_device *nbd)
|
||||
struct gendisk *disk = nbd->disk;
|
||||
|
||||
del_gendisk(disk);
|
||||
put_disk(disk);
|
||||
blk_mq_free_tag_set(&nbd->tag_set);
|
||||
|
||||
/*
|
||||
@@ -261,7 +260,7 @@ static void nbd_dev_remove(struct nbd_device *nbd)
|
||||
idr_remove(&nbd_index_idr, nbd->index);
|
||||
mutex_unlock(&nbd_index_mutex);
|
||||
destroy_workqueue(nbd->recv_workq);
|
||||
kfree(nbd);
|
||||
put_disk(disk);
|
||||
}
|
||||
|
||||
static void nbd_dev_remove_work(struct work_struct *work)
|
||||
@@ -1608,6 +1607,13 @@ static void nbd_release(struct gendisk *disk)
|
||||
nbd_put(nbd);
|
||||
}
|
||||
|
||||
static void nbd_free_disk(struct gendisk *disk)
|
||||
{
|
||||
struct nbd_device *nbd = disk->private_data;
|
||||
|
||||
kfree(nbd);
|
||||
}
|
||||
|
||||
static const struct block_device_operations nbd_fops =
|
||||
{
|
||||
.owner = THIS_MODULE,
|
||||
@@ -1615,6 +1621,7 @@ static const struct block_device_operations nbd_fops =
|
||||
.release = nbd_release,
|
||||
.ioctl = nbd_ioctl,
|
||||
.compat_ioctl = nbd_ioctl,
|
||||
.free_disk = nbd_free_disk,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
|
||||
@@ -1159,11 +1159,18 @@ uint32_t amdgpu_device_rreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t acc_flags);
|
||||
u32 amdgpu_device_indirect_rreg_ext(struct amdgpu_device *adev,
|
||||
u64 reg_addr);
|
||||
uint32_t amdgpu_device_xcc_rreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t acc_flags,
|
||||
uint32_t xcc_id);
|
||||
void amdgpu_device_wreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t v,
|
||||
uint32_t acc_flags);
|
||||
void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev,
|
||||
u64 reg_addr, u32 reg_data);
|
||||
void amdgpu_device_xcc_wreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t v,
|
||||
uint32_t acc_flags,
|
||||
uint32_t xcc_id);
|
||||
void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t v, uint32_t xcc_id);
|
||||
void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value);
|
||||
@@ -1204,8 +1211,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
||||
#define RREG32_NO_KIQ(reg) amdgpu_device_rreg(adev, (reg), AMDGPU_REGS_NO_KIQ)
|
||||
#define WREG32_NO_KIQ(reg, v) amdgpu_device_wreg(adev, (reg), (v), AMDGPU_REGS_NO_KIQ)
|
||||
|
||||
#define RREG32_KIQ(reg) amdgpu_kiq_rreg(adev, (reg))
|
||||
#define WREG32_KIQ(reg, v) amdgpu_kiq_wreg(adev, (reg), (v))
|
||||
#define RREG32_KIQ(reg) amdgpu_kiq_rreg(adev, (reg), 0)
|
||||
#define WREG32_KIQ(reg, v) amdgpu_kiq_wreg(adev, (reg), (v), 0)
|
||||
|
||||
#define RREG8(reg) amdgpu_mm_rreg8(adev, (reg))
|
||||
#define WREG8(reg, v) amdgpu_mm_wreg8(adev, (reg), (v))
|
||||
@@ -1215,6 +1222,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
||||
#define WREG32(reg, v) amdgpu_device_wreg(adev, (reg), (v), 0)
|
||||
#define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
|
||||
#define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
|
||||
#define RREG32_XCC(reg, inst) amdgpu_device_xcc_rreg(adev, (reg), 0, inst)
|
||||
#define WREG32_XCC(reg, v, inst) amdgpu_device_xcc_wreg(adev, (reg), (v), 0, inst)
|
||||
#define RREG32_PCIE(reg) adev->pcie_rreg(adev, (reg))
|
||||
#define WREG32_PCIE(reg, v) adev->pcie_wreg(adev, (reg), (v))
|
||||
#define RREG32_PCIE_PORT(reg) adev->pciep_rreg(adev, (reg))
|
||||
|
||||
@@ -1494,6 +1494,9 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
|
||||
if (adev->asic_type < CHIP_RAVEN)
|
||||
return false;
|
||||
|
||||
if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If ACPI_FADT_LOW_POWER_S0 is not set in the FADT, it is generally
|
||||
* risky to do any special firmware-related preparations for entering
|
||||
|
||||
@@ -300,14 +300,13 @@ static int kgd_gfx_v9_4_3_hqd_load(struct amdgpu_device *adev, void *mqd,
|
||||
hqd_end = SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_AQL_DISPATCH_ID_HI);
|
||||
|
||||
for (reg = hqd_base; reg <= hqd_end; reg++)
|
||||
WREG32_RLC(reg, mqd_hqd[reg - hqd_base]);
|
||||
WREG32_XCC(reg, mqd_hqd[reg - hqd_base], inst);
|
||||
|
||||
|
||||
/* Activate doorbell logic before triggering WPTR poll. */
|
||||
data = REG_SET_FIELD(m->cp_hqd_pq_doorbell_control,
|
||||
CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1);
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_PQ_DOORBELL_CONTROL),
|
||||
data);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_PQ_DOORBELL_CONTROL, data);
|
||||
|
||||
if (wptr) {
|
||||
/* Don't read wptr with get_user because the user
|
||||
@@ -336,27 +335,24 @@ static int kgd_gfx_v9_4_3_hqd_load(struct amdgpu_device *adev, void *mqd,
|
||||
guessed_wptr += m->cp_hqd_pq_wptr_lo & ~(queue_size - 1);
|
||||
guessed_wptr += (uint64_t)m->cp_hqd_pq_wptr_hi << 32;
|
||||
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_LO),
|
||||
lower_32_bits(guessed_wptr));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_HI),
|
||||
upper_32_bits(guessed_wptr));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_POLL_ADDR),
|
||||
lower_32_bits((uintptr_t)wptr));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst),
|
||||
regCP_HQD_PQ_WPTR_POLL_ADDR_HI),
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_LO,
|
||||
lower_32_bits(guessed_wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_HI,
|
||||
upper_32_bits(guessed_wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_POLL_ADDR,
|
||||
lower_32_bits((uintptr_t)wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_POLL_ADDR_HI,
|
||||
upper_32_bits((uintptr_t)wptr));
|
||||
WREG32(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_PQ_WPTR_POLL_CNTL1),
|
||||
(uint32_t)kgd_gfx_v9_get_queue_mask(adev, pipe_id,
|
||||
queue_id));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_PQ_WPTR_POLL_CNTL1,
|
||||
(uint32_t)kgd_gfx_v9_get_queue_mask(adev, pipe_id, queue_id));
|
||||
}
|
||||
|
||||
/* Start the EOP fetcher */
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_EOP_RPTR),
|
||||
REG_SET_FIELD(m->cp_hqd_eop_rptr,
|
||||
CP_HQD_EOP_RPTR, INIT_FETCHER, 1));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_EOP_RPTR,
|
||||
REG_SET_FIELD(m->cp_hqd_eop_rptr, CP_HQD_EOP_RPTR, INIT_FETCHER, 1));
|
||||
|
||||
data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_ACTIVE), data);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_ACTIVE, data);
|
||||
|
||||
kgd_gfx_v9_release_queue(adev, inst);
|
||||
|
||||
@@ -494,15 +490,15 @@ static uint32_t kgd_gfx_v9_4_3_set_address_watch(
|
||||
VALID,
|
||||
1);
|
||||
|
||||
WREG32_RLC((SOC15_REG_OFFSET(GC, GET_INST(GC, inst),
|
||||
WREG32_XCC((SOC15_REG_OFFSET(GC, GET_INST(GC, inst),
|
||||
regTCP_WATCH0_ADDR_H) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_high);
|
||||
watch_address_high, inst);
|
||||
|
||||
WREG32_RLC((SOC15_REG_OFFSET(GC, GET_INST(GC, inst),
|
||||
WREG32_XCC((SOC15_REG_OFFSET(GC, GET_INST(GC, inst),
|
||||
regTCP_WATCH0_ADDR_L) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_low);
|
||||
watch_address_low, inst);
|
||||
|
||||
return watch_address_cntl;
|
||||
}
|
||||
|
||||
@@ -91,8 +91,8 @@ void kgd_gfx_v9_program_sh_mem_settings(struct amdgpu_device *adev, uint32_t vmi
|
||||
{
|
||||
kgd_gfx_v9_lock_srbm(adev, 0, 0, 0, vmid, inst);
|
||||
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmSH_MEM_CONFIG), sh_mem_config);
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmSH_MEM_BASES), sh_mem_bases);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmSH_MEM_CONFIG, sh_mem_config);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmSH_MEM_BASES, sh_mem_bases);
|
||||
/* APE1 no longer exists on GFX9 */
|
||||
|
||||
kgd_gfx_v9_unlock_srbm(adev, inst);
|
||||
@@ -239,14 +239,13 @@ int kgd_gfx_v9_hqd_load(struct amdgpu_device *adev, void *mqd,
|
||||
|
||||
for (reg = hqd_base;
|
||||
reg <= SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_HI); reg++)
|
||||
WREG32_RLC(reg, mqd_hqd[reg - hqd_base]);
|
||||
WREG32_XCC(reg, mqd_hqd[reg - hqd_base], inst);
|
||||
|
||||
|
||||
/* Activate doorbell logic before triggering WPTR poll. */
|
||||
data = REG_SET_FIELD(m->cp_hqd_pq_doorbell_control,
|
||||
CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1);
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_PQ_DOORBELL_CONTROL),
|
||||
data);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_PQ_DOORBELL_CONTROL, data);
|
||||
|
||||
if (wptr) {
|
||||
/* Don't read wptr with get_user because the user
|
||||
@@ -275,25 +274,24 @@ int kgd_gfx_v9_hqd_load(struct amdgpu_device *adev, void *mqd,
|
||||
guessed_wptr += m->cp_hqd_pq_wptr_lo & ~(queue_size - 1);
|
||||
guessed_wptr += (uint64_t)m->cp_hqd_pq_wptr_hi << 32;
|
||||
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_LO),
|
||||
lower_32_bits(guessed_wptr));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_HI),
|
||||
upper_32_bits(guessed_wptr));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_POLL_ADDR),
|
||||
lower_32_bits((uintptr_t)wptr));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_POLL_ADDR_HI),
|
||||
upper_32_bits((uintptr_t)wptr));
|
||||
WREG32_SOC15(GC, GET_INST(GC, inst), mmCP_PQ_WPTR_POLL_CNTL1,
|
||||
(uint32_t)kgd_gfx_v9_get_queue_mask(adev, pipe_id, queue_id));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_LO,
|
||||
lower_32_bits(guessed_wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_HI,
|
||||
upper_32_bits(guessed_wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_POLL_ADDR,
|
||||
lower_32_bits((uintptr_t)wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_POLL_ADDR_HI,
|
||||
upper_32_bits((uintptr_t)wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_PQ_WPTR_POLL_CNTL1,
|
||||
(uint32_t)kgd_gfx_v9_get_queue_mask(adev, pipe_id, queue_id));
|
||||
}
|
||||
|
||||
/* Start the EOP fetcher */
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_EOP_RPTR),
|
||||
REG_SET_FIELD(m->cp_hqd_eop_rptr,
|
||||
CP_HQD_EOP_RPTR, INIT_FETCHER, 1));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_EOP_RPTR,
|
||||
REG_SET_FIELD(m->cp_hqd_eop_rptr, CP_HQD_EOP_RPTR, INIT_FETCHER, 1));
|
||||
|
||||
data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_ACTIVE), data);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_ACTIVE, data);
|
||||
|
||||
kgd_gfx_v9_release_queue(adev, inst);
|
||||
|
||||
@@ -556,7 +554,7 @@ int kgd_gfx_v9_hqd_destroy(struct amdgpu_device *adev, void *mqd,
|
||||
break;
|
||||
}
|
||||
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_DEQUEUE_REQUEST), type);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_DEQUEUE_REQUEST, type);
|
||||
|
||||
end_jiffies = (utimeout * HZ / 1000) + jiffies;
|
||||
while (true) {
|
||||
@@ -908,8 +906,8 @@ void kgd_gfx_v9_get_iq_wait_times(struct amdgpu_device *adev,
|
||||
uint32_t inst)
|
||||
|
||||
{
|
||||
*wait_times = RREG32(SOC15_REG_OFFSET(GC, GET_INST(GC, inst),
|
||||
mmCP_IQ_WAIT_TIME2));
|
||||
*wait_times = RREG32_SOC15_RLC(GC, GET_INST(GC, inst),
|
||||
mmCP_IQ_WAIT_TIME2);
|
||||
}
|
||||
|
||||
void kgd_gfx_v9_set_vm_context_page_table_base(struct amdgpu_device *adev,
|
||||
|
||||
@@ -172,6 +172,7 @@ int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
*result = NULL;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
||||
@@ -1415,7 +1415,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
if (r == -ENOMEM)
|
||||
DRM_ERROR("Not enough memory for command submission!\n");
|
||||
else if (r != -ERESTARTSYS && r != -EAGAIN)
|
||||
DRM_ERROR("Failed to process the buffer list %d!\n", r);
|
||||
DRM_DEBUG("Failed to process the buffer list %d!\n", r);
|
||||
goto error_fini;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
#include "amdgpu_pmu.h"
|
||||
#include "amdgpu_fru_eeprom.h"
|
||||
#include "amdgpu_reset.h"
|
||||
#include "amdgpu_virt.h"
|
||||
|
||||
#include <linux/suspend.h>
|
||||
#include <drm/task_barrier.h>
|
||||
@@ -472,7 +473,7 @@ uint32_t amdgpu_device_rreg(struct amdgpu_device *adev,
|
||||
if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
|
||||
amdgpu_sriov_runtime(adev) &&
|
||||
down_read_trylock(&adev->reset_domain->sem)) {
|
||||
ret = amdgpu_kiq_rreg(adev, reg);
|
||||
ret = amdgpu_kiq_rreg(adev, reg, 0);
|
||||
up_read(&adev->reset_domain->sem);
|
||||
} else {
|
||||
ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
|
||||
@@ -509,6 +510,49 @@ uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset)
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* amdgpu_device_xcc_rreg - read a memory mapped IO or indirect register with specific XCC
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @reg: dword aligned register offset
|
||||
* @acc_flags: access flags which require special behavior
|
||||
* @xcc_id: xcc accelerated compute core id
|
||||
*
|
||||
* Returns the 32 bit value from the offset specified.
|
||||
*/
|
||||
uint32_t amdgpu_device_xcc_rreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t acc_flags,
|
||||
uint32_t xcc_id)
|
||||
{
|
||||
uint32_t ret, rlcg_flag;
|
||||
|
||||
if (amdgpu_device_skip_hw_access(adev))
|
||||
return 0;
|
||||
|
||||
if ((reg * 4) < adev->rmmio_size) {
|
||||
if (amdgpu_sriov_vf(adev) &&
|
||||
!amdgpu_sriov_runtime(adev) &&
|
||||
adev->gfx.rlc.rlcg_reg_access_supported &&
|
||||
amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags,
|
||||
GC_HWIP, false,
|
||||
&rlcg_flag)) {
|
||||
ret = amdgpu_virt_rlcg_reg_rw(adev, reg, 0, rlcg_flag, xcc_id);
|
||||
} else if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
|
||||
amdgpu_sriov_runtime(adev) &&
|
||||
down_read_trylock(&adev->reset_domain->sem)) {
|
||||
ret = amdgpu_kiq_rreg(adev, reg, xcc_id);
|
||||
up_read(&adev->reset_domain->sem);
|
||||
} else {
|
||||
ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
|
||||
}
|
||||
} else {
|
||||
ret = adev->pcie_rreg(adev, reg * 4);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* MMIO register write with bytes helper functions
|
||||
* @offset:bytes offset from MMIO start
|
||||
@@ -556,7 +600,7 @@ void amdgpu_device_wreg(struct amdgpu_device *adev,
|
||||
if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
|
||||
amdgpu_sriov_runtime(adev) &&
|
||||
down_read_trylock(&adev->reset_domain->sem)) {
|
||||
amdgpu_kiq_wreg(adev, reg, v);
|
||||
amdgpu_kiq_wreg(adev, reg, v, 0);
|
||||
up_read(&adev->reset_domain->sem);
|
||||
} else {
|
||||
writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
|
||||
@@ -597,6 +641,47 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_xcc_wreg - write to a memory mapped IO or indirect register with specific XCC
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @reg: dword aligned register offset
|
||||
* @v: 32 bit value to write to the register
|
||||
* @acc_flags: access flags which require special behavior
|
||||
* @xcc_id: xcc accelerated compute core id
|
||||
*
|
||||
* Writes the value specified to the offset specified.
|
||||
*/
|
||||
void amdgpu_device_xcc_wreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t v,
|
||||
uint32_t acc_flags, uint32_t xcc_id)
|
||||
{
|
||||
uint32_t rlcg_flag;
|
||||
|
||||
if (amdgpu_device_skip_hw_access(adev))
|
||||
return;
|
||||
|
||||
if ((reg * 4) < adev->rmmio_size) {
|
||||
if (amdgpu_sriov_vf(adev) &&
|
||||
!amdgpu_sriov_runtime(adev) &&
|
||||
adev->gfx.rlc.rlcg_reg_access_supported &&
|
||||
amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags,
|
||||
GC_HWIP, true,
|
||||
&rlcg_flag)) {
|
||||
amdgpu_virt_rlcg_reg_rw(adev, reg, v, rlcg_flag, xcc_id);
|
||||
} else if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
|
||||
amdgpu_sriov_runtime(adev) &&
|
||||
down_read_trylock(&adev->reset_domain->sem)) {
|
||||
amdgpu_kiq_wreg(adev, reg, v, xcc_id);
|
||||
up_read(&adev->reset_domain->sem);
|
||||
} else {
|
||||
writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
|
||||
}
|
||||
} else {
|
||||
adev->pcie_wreg(adev, reg * 4, v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_indirect_rreg - read an indirect register
|
||||
*
|
||||
@@ -2499,6 +2584,18 @@ static int amdgpu_device_init_schedulers(struct amdgpu_device *adev)
|
||||
ring->name);
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_uvd_entity_init(adev, ring);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to create UVD scheduling entity on ring %s.\n",
|
||||
ring->name);
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_vce_entity_init(adev, ring);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to create VCE scheduling entity on ring %s.\n",
|
||||
ring->name);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_xcp_update_partition_sched_list(adev);
|
||||
@@ -4486,19 +4583,18 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
||||
}
|
||||
amdgpu_fence_driver_hw_init(adev);
|
||||
|
||||
r = amdgpu_device_ip_late_init(adev);
|
||||
if (r)
|
||||
goto exit;
|
||||
|
||||
queue_delayed_work(system_wq, &adev->delayed_init_work,
|
||||
msecs_to_jiffies(AMDGPU_RESUME_MS));
|
||||
|
||||
if (!adev->in_s0ix) {
|
||||
r = amdgpu_amdkfd_resume(adev, adev->in_runpm);
|
||||
if (r)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
r = amdgpu_device_ip_late_init(adev);
|
||||
if (r)
|
||||
goto exit;
|
||||
|
||||
queue_delayed_work(system_wq, &adev->delayed_init_work,
|
||||
msecs_to_jiffies(AMDGPU_RESUME_MS));
|
||||
exit:
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
amdgpu_virt_init_data_exchange(adev);
|
||||
|
||||
@@ -931,12 +931,12 @@ void amdgpu_gfx_ras_error_func(struct amdgpu_device *adev,
|
||||
func(adev, ras_error_status, i);
|
||||
}
|
||||
|
||||
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
|
||||
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_id)
|
||||
{
|
||||
signed long r, cnt = 0;
|
||||
unsigned long flags;
|
||||
uint32_t seq, reg_val_offs = 0, value = 0;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[0];
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
|
||||
struct amdgpu_ring *ring = &kiq->ring;
|
||||
|
||||
if (amdgpu_device_skip_hw_access(adev))
|
||||
@@ -999,12 +999,12 @@ failed_kiq_read:
|
||||
return ~0;
|
||||
}
|
||||
|
||||
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
|
||||
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint32_t xcc_id)
|
||||
{
|
||||
signed long r, cnt = 0;
|
||||
unsigned long flags;
|
||||
uint32_t seq;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[0];
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
|
||||
struct amdgpu_ring *ring = &kiq->ring;
|
||||
|
||||
BUG_ON(!ring->funcs->emit_wreg);
|
||||
|
||||
@@ -521,8 +521,8 @@ int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
|
||||
int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry);
|
||||
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
|
||||
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
|
||||
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_id);
|
||||
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint32_t xcc_id);
|
||||
int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev);
|
||||
void amdgpu_gfx_cp_init_microcode(struct amdgpu_device *adev, uint32_t ucode_id);
|
||||
|
||||
|
||||
@@ -826,7 +826,10 @@ void amdgpu_gmc_noretry_set(struct amdgpu_device *adev)
|
||||
gc_ver == IP_VERSION(9, 4, 3) ||
|
||||
gc_ver >= IP_VERSION(10, 3, 0));
|
||||
|
||||
gmc->noretry = (amdgpu_noretry == -1) ? noretry_default : amdgpu_noretry;
|
||||
if (!amdgpu_sriov_xnack_support(adev))
|
||||
gmc->noretry = 1;
|
||||
else
|
||||
gmc->noretry = (amdgpu_noretry == -1) ? noretry_default : amdgpu_noretry;
|
||||
}
|
||||
|
||||
void amdgpu_gmc_set_vm_fault_masks(struct amdgpu_device *adev, int hub_type,
|
||||
|
||||
@@ -143,6 +143,46 @@ int amdgpu_mca_mpio_ras_sw_init(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_mca_bank_set_init(struct mca_bank_set *mca_set)
|
||||
{
|
||||
if (!mca_set)
|
||||
return;
|
||||
|
||||
memset(mca_set, 0, sizeof(*mca_set));
|
||||
INIT_LIST_HEAD(&mca_set->list);
|
||||
}
|
||||
|
||||
int amdgpu_mca_bank_set_add_entry(struct mca_bank_set *mca_set, struct mca_bank_entry *entry)
|
||||
{
|
||||
struct mca_bank_node *node;
|
||||
|
||||
if (!entry)
|
||||
return -EINVAL;
|
||||
|
||||
node = kvzalloc(sizeof(*node), GFP_KERNEL);
|
||||
if (!node)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(&node->entry, entry, sizeof(*entry));
|
||||
|
||||
INIT_LIST_HEAD(&node->node);
|
||||
list_add_tail(&node->node, &mca_set->list);
|
||||
|
||||
mca_set->nr_entries++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_mca_bank_set_release(struct mca_bank_set *mca_set)
|
||||
{
|
||||
struct mca_bank_node *node, *tmp;
|
||||
|
||||
list_for_each_entry_safe(node, tmp, &mca_set->list, node) {
|
||||
list_del(&node->node);
|
||||
kvfree(node);
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_mca_smu_init_funcs(struct amdgpu_device *adev, const struct amdgpu_mca_smu_funcs *mca_funcs)
|
||||
{
|
||||
struct amdgpu_mca *mca = &adev->mca;
|
||||
@@ -160,6 +200,65 @@ int amdgpu_mca_smu_set_debug_mode(struct amdgpu_device *adev, bool enable)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static void amdgpu_mca_smu_mca_bank_dump(struct amdgpu_device *adev, int idx, struct mca_bank_entry *entry)
|
||||
{
|
||||
dev_info(adev->dev, "[Hardware error] Accelerator Check Architecture events logged\n");
|
||||
dev_info(adev->dev, "[Hardware error] aca entry[%02d].STATUS=0x%016llx\n",
|
||||
idx, entry->regs[MCA_REG_IDX_STATUS]);
|
||||
dev_info(adev->dev, "[Hardware error] aca entry[%02d].ADDR=0x%016llx\n",
|
||||
idx, entry->regs[MCA_REG_IDX_ADDR]);
|
||||
dev_info(adev->dev, "[Hardware error] aca entry[%02d].MISC0=0x%016llx\n",
|
||||
idx, entry->regs[MCA_REG_IDX_MISC0]);
|
||||
dev_info(adev->dev, "[Hardware error] aca entry[%02d].IPID=0x%016llx\n",
|
||||
idx, entry->regs[MCA_REG_IDX_IPID]);
|
||||
dev_info(adev->dev, "[Hardware error] aca entry[%02d].SYND=0x%016llx\n",
|
||||
idx, entry->regs[MCA_REG_IDX_SYND]);
|
||||
}
|
||||
|
||||
int amdgpu_mca_smu_log_ras_error(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type, struct ras_err_data *err_data)
|
||||
{
|
||||
struct amdgpu_smuio_mcm_config_info mcm_info;
|
||||
struct mca_bank_set mca_set;
|
||||
struct mca_bank_node *node;
|
||||
struct mca_bank_entry *entry;
|
||||
uint32_t count;
|
||||
int ret, i = 0;
|
||||
|
||||
amdgpu_mca_bank_set_init(&mca_set);
|
||||
|
||||
ret = amdgpu_mca_smu_get_mca_set(adev, blk, type, &mca_set);
|
||||
if (ret)
|
||||
goto out_mca_release;
|
||||
|
||||
list_for_each_entry(node, &mca_set.list, node) {
|
||||
entry = &node->entry;
|
||||
|
||||
amdgpu_mca_smu_mca_bank_dump(adev, i++, entry);
|
||||
|
||||
count = 0;
|
||||
ret = amdgpu_mca_smu_parse_mca_error_count(adev, blk, type, entry, &count);
|
||||
if (ret)
|
||||
goto out_mca_release;
|
||||
|
||||
if (!count)
|
||||
continue;
|
||||
|
||||
mcm_info.socket_id = entry->info.socket_id;
|
||||
mcm_info.die_id = entry->info.aid;
|
||||
|
||||
if (type == AMDGPU_MCA_ERROR_TYPE_UE)
|
||||
amdgpu_ras_error_statistic_ue_count(err_data, &mcm_info, (uint64_t)count);
|
||||
else
|
||||
amdgpu_ras_error_statistic_ce_count(err_data, &mcm_info, (uint64_t)count);
|
||||
}
|
||||
|
||||
out_mca_release:
|
||||
amdgpu_mca_bank_set_release(&mca_set);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int amdgpu_mca_smu_get_valid_mca_count(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, uint32_t *count)
|
||||
{
|
||||
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
|
||||
@@ -173,17 +272,77 @@ int amdgpu_mca_smu_get_valid_mca_count(struct amdgpu_device *adev, enum amdgpu_m
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int amdgpu_mca_smu_get_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, uint32_t *count)
|
||||
int amdgpu_mca_smu_get_mca_set_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, uint32_t *total)
|
||||
{
|
||||
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
|
||||
if (!count)
|
||||
struct mca_bank_set mca_set;
|
||||
struct mca_bank_node *node;
|
||||
struct mca_bank_entry *entry;
|
||||
uint32_t count;
|
||||
int ret;
|
||||
|
||||
if (!total)
|
||||
return -EINVAL;
|
||||
|
||||
if (mca_funcs && mca_funcs->mca_get_error_count)
|
||||
return mca_funcs->mca_get_error_count(adev, blk, type, count);
|
||||
if (!mca_funcs)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
if (!mca_funcs->mca_get_ras_mca_set || !mca_funcs->mca_get_valid_mca_count)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
amdgpu_mca_bank_set_init(&mca_set);
|
||||
|
||||
ret = mca_funcs->mca_get_ras_mca_set(adev, blk, type, &mca_set);
|
||||
if (ret)
|
||||
goto err_mca_set_release;
|
||||
|
||||
*total = 0;
|
||||
list_for_each_entry(node, &mca_set.list, node) {
|
||||
entry = &node->entry;
|
||||
|
||||
count = 0;
|
||||
ret = mca_funcs->mca_parse_mca_error_count(adev, blk, type, entry, &count);
|
||||
if (ret)
|
||||
goto err_mca_set_release;
|
||||
|
||||
*total += count;
|
||||
}
|
||||
|
||||
err_mca_set_release:
|
||||
amdgpu_mca_bank_set_release(&mca_set);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_mca_smu_parse_mca_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count)
|
||||
{
|
||||
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
|
||||
if (!count || !entry)
|
||||
return -EINVAL;
|
||||
|
||||
if (!mca_funcs || !mca_funcs->mca_parse_mca_error_count)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
|
||||
return mca_funcs->mca_parse_mca_error_count(adev, blk, type, entry, count);
|
||||
}
|
||||
|
||||
int amdgpu_mca_smu_get_mca_set(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, struct mca_bank_set *mca_set)
|
||||
{
|
||||
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
|
||||
|
||||
if (!mca_set)
|
||||
return -EINVAL;
|
||||
|
||||
if (!mca_funcs || !mca_funcs->mca_get_ras_mca_set)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
WARN_ON(!list_empty(&mca_set->list));
|
||||
|
||||
return mca_funcs->mca_get_ras_mca_set(adev, blk, type, mca_set);
|
||||
}
|
||||
|
||||
int amdgpu_mca_smu_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
|
||||
@@ -230,14 +389,21 @@ static int amdgpu_mca_smu_debug_mode_set(void *data, u64 val)
|
||||
static void mca_dump_entry(struct seq_file *m, struct mca_bank_entry *entry)
|
||||
{
|
||||
int i, idx = entry->idx;
|
||||
int reg_idx_array[] = {
|
||||
MCA_REG_IDX_STATUS,
|
||||
MCA_REG_IDX_ADDR,
|
||||
MCA_REG_IDX_MISC0,
|
||||
MCA_REG_IDX_IPID,
|
||||
MCA_REG_IDX_SYND,
|
||||
};
|
||||
|
||||
seq_printf(m, "mca entry[%d].type: %s\n", idx, entry->type == AMDGPU_MCA_ERROR_TYPE_UE ? "UE" : "CE");
|
||||
seq_printf(m, "mca entry[%d].ip: %d\n", idx, entry->ip);
|
||||
seq_printf(m, "mca entry[%d].info: socketid:%d aid:%d hwid:0x%03x mcatype:0x%04x\n",
|
||||
idx, entry->info.socket_id, entry->info.aid, entry->info.hwid, entry->info.mcatype);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(entry->regs); i++)
|
||||
seq_printf(m, "mca entry[%d].regs[%d]: 0x%016llx\n", idx, i, entry->regs[i]);
|
||||
for (i = 0; i < ARRAY_SIZE(reg_idx_array); i++)
|
||||
seq_printf(m, "mca entry[%d].regs[%d]: 0x%016llx\n", idx, reg_idx_array[i], entry->regs[reg_idx_array[i]]);
|
||||
}
|
||||
|
||||
static int mca_dump_show(struct seq_file *m, enum amdgpu_mca_error_type type)
|
||||
|
||||
@@ -25,6 +25,27 @@
|
||||
|
||||
#define MCA_MAX_REGS_COUNT (16)
|
||||
|
||||
#define MCA_REG_FIELD(x, h, l) (((x) & GENMASK_ULL(h, l)) >> l)
|
||||
#define MCA_REG__STATUS__VAL(x) MCA_REG_FIELD(x, 63, 63)
|
||||
#define MCA_REG__STATUS__OVERFLOW(x) MCA_REG_FIELD(x, 62, 62)
|
||||
#define MCA_REG__STATUS__UC(x) MCA_REG_FIELD(x, 61, 61)
|
||||
#define MCA_REG__STATUS__EN(x) MCA_REG_FIELD(x, 60, 60)
|
||||
#define MCA_REG__STATUS__MISCV(x) MCA_REG_FIELD(x, 59, 59)
|
||||
#define MCA_REG__STATUS__ADDRV(x) MCA_REG_FIELD(x, 58, 58)
|
||||
#define MCA_REG__STATUS__PCC(x) MCA_REG_FIELD(x, 57, 57)
|
||||
#define MCA_REG__STATUS__ERRCOREIDVAL(x) MCA_REG_FIELD(x, 56, 56)
|
||||
#define MCA_REG__STATUS__TCC(x) MCA_REG_FIELD(x, 55, 55)
|
||||
#define MCA_REG__STATUS__SYNDV(x) MCA_REG_FIELD(x, 53, 53)
|
||||
#define MCA_REG__STATUS__CECC(x) MCA_REG_FIELD(x, 46, 46)
|
||||
#define MCA_REG__STATUS__UECC(x) MCA_REG_FIELD(x, 45, 45)
|
||||
#define MCA_REG__STATUS__DEFERRED(x) MCA_REG_FIELD(x, 44, 44)
|
||||
#define MCA_REG__STATUS__POISON(x) MCA_REG_FIELD(x, 43, 43)
|
||||
#define MCA_REG__STATUS__SCRUB(x) MCA_REG_FIELD(x, 40, 40)
|
||||
#define MCA_REG__STATUS__ERRCOREID(x) MCA_REG_FIELD(x, 37, 32)
|
||||
#define MCA_REG__STATUS__ADDRLSB(x) MCA_REG_FIELD(x, 29, 24)
|
||||
#define MCA_REG__STATUS__ERRORCODEEXT(x) MCA_REG_FIELD(x, 21, 16)
|
||||
#define MCA_REG__STATUS__ERRORCODE(x) MCA_REG_FIELD(x, 15, 0)
|
||||
|
||||
enum amdgpu_mca_ip {
|
||||
AMDGPU_MCA_IP_UNKNOW = -1,
|
||||
AMDGPU_MCA_IP_PSP = 0,
|
||||
@@ -33,6 +54,7 @@ enum amdgpu_mca_ip {
|
||||
AMDGPU_MCA_IP_SMU,
|
||||
AMDGPU_MCA_IP_MP5,
|
||||
AMDGPU_MCA_IP_UMC,
|
||||
AMDGPU_MCA_IP_PCS_XGMI,
|
||||
AMDGPU_MCA_IP_COUNT,
|
||||
};
|
||||
|
||||
@@ -57,6 +79,15 @@ struct amdgpu_mca {
|
||||
const struct amdgpu_mca_smu_funcs *mca_funcs;
|
||||
};
|
||||
|
||||
enum mca_reg_idx {
|
||||
MCA_REG_IDX_STATUS = 1,
|
||||
MCA_REG_IDX_ADDR = 2,
|
||||
MCA_REG_IDX_MISC0 = 3,
|
||||
MCA_REG_IDX_IPID = 5,
|
||||
MCA_REG_IDX_SYND = 6,
|
||||
MCA_REG_IDX_COUNT = 16,
|
||||
};
|
||||
|
||||
struct mca_bank_info {
|
||||
int socket_id;
|
||||
int aid;
|
||||
@@ -72,18 +103,28 @@ struct mca_bank_entry {
|
||||
uint64_t regs[MCA_MAX_REGS_COUNT];
|
||||
};
|
||||
|
||||
struct mca_bank_node {
|
||||
struct mca_bank_entry entry;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
struct mca_bank_set {
|
||||
int nr_entries;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct amdgpu_mca_smu_funcs {
|
||||
int max_ue_count;
|
||||
int max_ce_count;
|
||||
int (*mca_set_debug_mode)(struct amdgpu_device *adev, bool enable);
|
||||
int (*mca_get_error_count)(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, uint32_t *count);
|
||||
int (*mca_get_ras_mca_set)(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type,
|
||||
struct mca_bank_set *mca_set);
|
||||
int (*mca_parse_mca_error_count)(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type,
|
||||
struct mca_bank_entry *entry, uint32_t *count);
|
||||
int (*mca_get_valid_mca_count)(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
|
||||
uint32_t *count);
|
||||
int (*mca_get_mca_entry)(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
|
||||
int idx, struct mca_bank_entry *entry);
|
||||
int (*mca_get_ras_mca_idx_array)(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, int *idx_array, int *idx_array_size);
|
||||
};
|
||||
|
||||
void amdgpu_mca_query_correctable_error_count(struct amdgpu_device *adev,
|
||||
@@ -107,11 +148,22 @@ int amdgpu_mca_mpio_ras_sw_init(struct amdgpu_device *adev);
|
||||
void amdgpu_mca_smu_init_funcs(struct amdgpu_device *adev, const struct amdgpu_mca_smu_funcs *mca_funcs);
|
||||
int amdgpu_mca_smu_set_debug_mode(struct amdgpu_device *adev, bool enable);
|
||||
int amdgpu_mca_smu_get_valid_mca_count(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, uint32_t *count);
|
||||
int amdgpu_mca_smu_get_mca_set_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, uint32_t *total);
|
||||
int amdgpu_mca_smu_get_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, uint32_t *count);
|
||||
int amdgpu_mca_smu_parse_mca_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count);
|
||||
int amdgpu_mca_smu_get_mca_set(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, struct mca_bank_set *mca_set);
|
||||
int amdgpu_mca_smu_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
|
||||
int idx, struct mca_bank_entry *entry);
|
||||
|
||||
void amdgpu_mca_smu_debugfs_init(struct amdgpu_device *adev, struct dentry *root);
|
||||
|
||||
void amdgpu_mca_bank_set_init(struct mca_bank_set *mca_set);
|
||||
int amdgpu_mca_bank_set_add_entry(struct mca_bank_set *mca_set, struct mca_bank_entry *entry);
|
||||
void amdgpu_mca_bank_set_release(struct mca_bank_set *mca_set);
|
||||
int amdgpu_mca_smu_log_ras_error(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type, struct ras_err_data *err_data);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1062,9 +1062,6 @@ static const char * const amdgpu_vram_names[] = {
|
||||
*/
|
||||
int amdgpu_bo_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* set the default AGP aperture state */
|
||||
amdgpu_gmc_set_agp_default(adev, &adev->gmc);
|
||||
|
||||
/* On A+A platform, VRAM can be mapped as WB */
|
||||
if (!adev->gmc.xgmi.connected_to_cpu && !adev->gmc.is_app_apu) {
|
||||
/* reserve PAT memory space to WC for VRAM */
|
||||
|
||||
@@ -1165,13 +1165,53 @@ static void amdgpu_rasmgr_error_data_statistic_update(struct ras_manager *obj, s
|
||||
}
|
||||
}
|
||||
|
||||
/* query/inject/cure begin */
|
||||
int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
|
||||
struct ras_query_if *info)
|
||||
static int amdgpu_ras_query_error_status_helper(struct amdgpu_device *adev,
|
||||
struct ras_query_if *info,
|
||||
struct ras_err_data *err_data,
|
||||
unsigned int error_query_mode)
|
||||
{
|
||||
enum amdgpu_ras_block blk = info ? info->head.block : AMDGPU_RAS_BLOCK_COUNT;
|
||||
struct amdgpu_ras_block_object *block_obj = NULL;
|
||||
|
||||
if (error_query_mode == AMDGPU_RAS_INVALID_ERROR_QUERY)
|
||||
return -EINVAL;
|
||||
|
||||
if (error_query_mode == AMDGPU_RAS_DIRECT_ERROR_QUERY) {
|
||||
if (info->head.block == AMDGPU_RAS_BLOCK__UMC) {
|
||||
amdgpu_ras_get_ecc_info(adev, err_data);
|
||||
} else {
|
||||
block_obj = amdgpu_ras_get_ras_block(adev, info->head.block, 0);
|
||||
if (!block_obj || !block_obj->hw_ops) {
|
||||
dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
|
||||
get_ras_block_str(&info->head));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (block_obj->hw_ops->query_ras_error_count)
|
||||
block_obj->hw_ops->query_ras_error_count(adev, &err_data);
|
||||
|
||||
if ((info->head.block == AMDGPU_RAS_BLOCK__SDMA) ||
|
||||
(info->head.block == AMDGPU_RAS_BLOCK__GFX) ||
|
||||
(info->head.block == AMDGPU_RAS_BLOCK__MMHUB)) {
|
||||
if (block_obj->hw_ops->query_ras_error_status)
|
||||
block_obj->hw_ops->query_ras_error_status(adev);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* FIXME: add code to check return value later */
|
||||
amdgpu_mca_smu_log_ras_error(adev, blk, AMDGPU_MCA_ERROR_TYPE_UE, err_data);
|
||||
amdgpu_mca_smu_log_ras_error(adev, blk, AMDGPU_MCA_ERROR_TYPE_CE, err_data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* query/inject/cure begin */
|
||||
int amdgpu_ras_query_error_status(struct amdgpu_device *adev, struct ras_query_if *info)
|
||||
{
|
||||
struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head);
|
||||
struct ras_err_data err_data;
|
||||
unsigned int error_query_mode;
|
||||
int ret;
|
||||
|
||||
if (!obj)
|
||||
@@ -1181,27 +1221,14 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (info->head.block == AMDGPU_RAS_BLOCK__UMC) {
|
||||
amdgpu_ras_get_ecc_info(adev, &err_data);
|
||||
} else {
|
||||
block_obj = amdgpu_ras_get_ras_block(adev, info->head.block, 0);
|
||||
if (!block_obj || !block_obj->hw_ops) {
|
||||
dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
|
||||
get_ras_block_str(&info->head));
|
||||
ret = -EINVAL;
|
||||
goto out_fini_err_data;
|
||||
}
|
||||
if (!amdgpu_ras_get_error_query_mode(adev, &error_query_mode))
|
||||
return -EINVAL;
|
||||
|
||||
if (block_obj->hw_ops->query_ras_error_count)
|
||||
block_obj->hw_ops->query_ras_error_count(adev, &err_data);
|
||||
|
||||
if ((info->head.block == AMDGPU_RAS_BLOCK__SDMA) ||
|
||||
(info->head.block == AMDGPU_RAS_BLOCK__GFX) ||
|
||||
(info->head.block == AMDGPU_RAS_BLOCK__MMHUB)) {
|
||||
if (block_obj->hw_ops->query_ras_error_status)
|
||||
block_obj->hw_ops->query_ras_error_status(adev);
|
||||
}
|
||||
}
|
||||
ret = amdgpu_ras_query_error_status_helper(adev, info,
|
||||
&err_data,
|
||||
error_query_mode);
|
||||
if (ret)
|
||||
goto out_fini_err_data;
|
||||
|
||||
amdgpu_rasmgr_error_data_statistic_update(obj, &err_data);
|
||||
|
||||
@@ -1537,7 +1564,8 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
|
||||
sysfs_remove_file_from_group(&adev->dev->kobj,
|
||||
if (adev->dev->kobj.sd)
|
||||
sysfs_remove_file_from_group(&adev->dev->kobj,
|
||||
&con->badpages_attr.attr,
|
||||
RAS_FS_NAME);
|
||||
}
|
||||
@@ -1556,7 +1584,8 @@ static int amdgpu_ras_sysfs_remove_dev_attr_node(struct amdgpu_device *adev)
|
||||
.attrs = attrs,
|
||||
};
|
||||
|
||||
sysfs_remove_group(&adev->dev->kobj, &group);
|
||||
if (adev->dev->kobj.sd)
|
||||
sysfs_remove_group(&adev->dev->kobj, &group);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1603,7 +1632,8 @@ int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev,
|
||||
if (!obj || !obj->attr_inuse)
|
||||
return -EINVAL;
|
||||
|
||||
sysfs_remove_file_from_group(&adev->dev->kobj,
|
||||
if (adev->dev->kobj.sd)
|
||||
sysfs_remove_file_from_group(&adev->dev->kobj,
|
||||
&obj->sysfs_attr.attr,
|
||||
RAS_FS_NAME);
|
||||
obj->attr_inuse = 0;
|
||||
@@ -3397,6 +3427,26 @@ bool amdgpu_ras_get_mca_debug_mode(struct amdgpu_device *adev)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool amdgpu_ras_get_error_query_mode(struct amdgpu_device *adev,
|
||||
unsigned int *error_query_mode)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
|
||||
|
||||
if (!con) {
|
||||
*error_query_mode = AMDGPU_RAS_INVALID_ERROR_QUERY;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mca_funcs && mca_funcs->mca_set_debug_mode)
|
||||
*error_query_mode =
|
||||
(con->is_mca_debug_mode) ? AMDGPU_RAS_DIRECT_ERROR_QUERY : AMDGPU_RAS_FIRMWARE_ERROR_QUERY;
|
||||
else
|
||||
*error_query_mode = AMDGPU_RAS_DIRECT_ERROR_QUERY;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Register each ip ras block into amdgpu ras */
|
||||
int amdgpu_ras_register_ras_block(struct amdgpu_device *adev,
|
||||
struct amdgpu_ras_block_object *ras_block_obj)
|
||||
|
||||
@@ -320,6 +320,12 @@ enum amdgpu_ras_ret {
|
||||
AMDGPU_RAS_PT,
|
||||
};
|
||||
|
||||
enum amdgpu_ras_error_query_mode {
|
||||
AMDGPU_RAS_INVALID_ERROR_QUERY = 0,
|
||||
AMDGPU_RAS_DIRECT_ERROR_QUERY = 1,
|
||||
AMDGPU_RAS_FIRMWARE_ERROR_QUERY = 2,
|
||||
};
|
||||
|
||||
/* ras error status reisger fields */
|
||||
#define ERR_STATUS_LO__ERR_STATUS_VALID_FLAG__SHIFT 0x0
|
||||
#define ERR_STATUS_LO__ERR_STATUS_VALID_FLAG_MASK 0x00000001L
|
||||
@@ -769,6 +775,8 @@ int amdgpu_ras_set_context(struct amdgpu_device *adev, struct amdgpu_ras *ras_co
|
||||
|
||||
void amdgpu_ras_set_mca_debug_mode(struct amdgpu_device *adev, bool enable);
|
||||
bool amdgpu_ras_get_mca_debug_mode(struct amdgpu_device *adev);
|
||||
bool amdgpu_ras_get_error_query_mode(struct amdgpu_device *adev,
|
||||
unsigned int *mode);
|
||||
|
||||
int amdgpu_ras_register_ras_block(struct amdgpu_device *adev,
|
||||
struct amdgpu_ras_block_object *ras_block_obj);
|
||||
|
||||
@@ -399,20 +399,20 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Initialize the entity used for handle management in the kernel driver.
|
||||
*/
|
||||
int amdgpu_uvd_entity_init(struct amdgpu_device *adev)
|
||||
int amdgpu_uvd_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_ring *ring;
|
||||
struct drm_gpu_scheduler *sched;
|
||||
int r;
|
||||
if (ring == &adev->uvd.inst[0].ring) {
|
||||
struct drm_gpu_scheduler *sched = &ring->sched;
|
||||
int r;
|
||||
|
||||
ring = &adev->uvd.inst[0].ring;
|
||||
sched = &ring->sched;
|
||||
r = drm_sched_entity_init(&adev->uvd.entity, DRM_SCHED_PRIORITY_NORMAL,
|
||||
&sched, 1, NULL);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed setting up UVD kernel entity.\n");
|
||||
return r;
|
||||
r = drm_sched_entity_init(&adev->uvd.entity, DRM_SCHED_PRIORITY_NORMAL,
|
||||
&sched, 1, NULL);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed setting up UVD kernel entity.\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -73,7 +73,7 @@ struct amdgpu_uvd {
|
||||
|
||||
int amdgpu_uvd_sw_init(struct amdgpu_device *adev);
|
||||
int amdgpu_uvd_sw_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_uvd_entity_init(struct amdgpu_device *adev);
|
||||
int amdgpu_uvd_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring);
|
||||
int amdgpu_uvd_prepare_suspend(struct amdgpu_device *adev);
|
||||
int amdgpu_uvd_suspend(struct amdgpu_device *adev);
|
||||
int amdgpu_uvd_resume(struct amdgpu_device *adev);
|
||||
|
||||
@@ -231,20 +231,20 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev)
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Initialize the entity used for handle management in the kernel driver.
|
||||
*/
|
||||
int amdgpu_vce_entity_init(struct amdgpu_device *adev)
|
||||
int amdgpu_vce_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_ring *ring;
|
||||
struct drm_gpu_scheduler *sched;
|
||||
int r;
|
||||
if (ring == &adev->vce.ring[0]) {
|
||||
struct drm_gpu_scheduler *sched = &ring->sched;
|
||||
int r;
|
||||
|
||||
ring = &adev->vce.ring[0];
|
||||
sched = &ring->sched;
|
||||
r = drm_sched_entity_init(&adev->vce.entity, DRM_SCHED_PRIORITY_NORMAL,
|
||||
&sched, 1, NULL);
|
||||
if (r != 0) {
|
||||
DRM_ERROR("Failed setting up VCE run queue.\n");
|
||||
return r;
|
||||
r = drm_sched_entity_init(&adev->vce.entity, DRM_SCHED_PRIORITY_NORMAL,
|
||||
&sched, 1, NULL);
|
||||
if (r != 0) {
|
||||
DRM_ERROR("Failed setting up VCE run queue.\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -55,7 +55,7 @@ struct amdgpu_vce {
|
||||
|
||||
int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size);
|
||||
int amdgpu_vce_sw_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_vce_entity_init(struct amdgpu_device *adev);
|
||||
int amdgpu_vce_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring);
|
||||
int amdgpu_vce_suspend(struct amdgpu_device *adev);
|
||||
int amdgpu_vce_resume(struct amdgpu_device *adev);
|
||||
void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp);
|
||||
|
||||
@@ -73,9 +73,10 @@ void amdgpu_virt_init_setting(struct amdgpu_device *adev)
|
||||
|
||||
void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
|
||||
uint32_t reg0, uint32_t reg1,
|
||||
uint32_t ref, uint32_t mask)
|
||||
uint32_t ref, uint32_t mask,
|
||||
uint32_t xcc_inst)
|
||||
{
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[0];
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_inst];
|
||||
struct amdgpu_ring *ring = &kiq->ring;
|
||||
signed long r, cnt = 0;
|
||||
unsigned long flags;
|
||||
@@ -942,7 +943,7 @@ void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
static bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev,
|
||||
bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev,
|
||||
u32 acc_flags, u32 hwip,
|
||||
bool write, u32 *rlcg_flag)
|
||||
{
|
||||
@@ -975,7 +976,7 @@ static bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag, u32 xcc_id)
|
||||
u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag, u32 xcc_id)
|
||||
{
|
||||
struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl;
|
||||
uint32_t timeout = 50000;
|
||||
@@ -1093,3 +1094,13 @@ u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
|
||||
else
|
||||
return RREG32(offset);
|
||||
}
|
||||
|
||||
bool amdgpu_sriov_xnack_support(struct amdgpu_device *adev)
|
||||
{
|
||||
bool xnack_mode = true;
|
||||
|
||||
if (amdgpu_sriov_vf(adev) && adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2))
|
||||
xnack_mode = false;
|
||||
|
||||
return xnack_mode;
|
||||
}
|
||||
|
||||
@@ -334,7 +334,8 @@ bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
|
||||
void amdgpu_virt_init_setting(struct amdgpu_device *adev);
|
||||
void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
|
||||
uint32_t reg0, uint32_t rreg1,
|
||||
uint32_t ref, uint32_t mask);
|
||||
uint32_t ref, uint32_t mask,
|
||||
uint32_t xcc_inst);
|
||||
int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init);
|
||||
int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init);
|
||||
int amdgpu_virt_reset_gpu(struct amdgpu_device *adev);
|
||||
@@ -365,4 +366,9 @@ u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
|
||||
bool amdgpu_virt_fw_load_skip_check(struct amdgpu_device *adev,
|
||||
uint32_t ucode_id);
|
||||
void amdgpu_virt_post_reset(struct amdgpu_device *adev);
|
||||
bool amdgpu_sriov_xnack_support(struct amdgpu_device *adev);
|
||||
bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev,
|
||||
u32 acc_flags, u32 hwip,
|
||||
bool write, u32 *rlcg_flag);
|
||||
u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag, u32 xcc_id);
|
||||
#endif
|
||||
|
||||
@@ -1098,8 +1098,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
|
||||
bo = gem_to_amdgpu_bo(gobj);
|
||||
}
|
||||
mem = bo->tbo.resource;
|
||||
if (mem->mem_type == TTM_PL_TT ||
|
||||
mem->mem_type == AMDGPU_PL_PREEMPT)
|
||||
if (mem && (mem->mem_type == TTM_PL_TT ||
|
||||
mem->mem_type == AMDGPU_PL_PREEMPT))
|
||||
pages_addr = bo->tbo.ttm->dma_address;
|
||||
}
|
||||
|
||||
@@ -2139,7 +2139,8 @@ long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout)
|
||||
* Returns:
|
||||
* 0 for success, error for failure.
|
||||
*/
|
||||
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id)
|
||||
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
int32_t xcp_id)
|
||||
{
|
||||
struct amdgpu_bo *root_bo;
|
||||
struct amdgpu_bo_vm *root;
|
||||
@@ -2158,6 +2159,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp
|
||||
INIT_LIST_HEAD(&vm->done);
|
||||
INIT_LIST_HEAD(&vm->pt_freed);
|
||||
INIT_WORK(&vm->pt_free_work, amdgpu_vm_pt_free_work);
|
||||
INIT_KFIFO(vm->faults);
|
||||
|
||||
r = amdgpu_vm_init_entities(adev, vm);
|
||||
if (r)
|
||||
@@ -2192,34 +2194,33 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp
|
||||
false, &root, xcp_id);
|
||||
if (r)
|
||||
goto error_free_delayed;
|
||||
root_bo = &root->bo;
|
||||
|
||||
root_bo = amdgpu_bo_ref(&root->bo);
|
||||
r = amdgpu_bo_reserve(root_bo, true);
|
||||
if (r) {
|
||||
amdgpu_bo_unref(&root->shadow);
|
||||
amdgpu_bo_unref(&root_bo);
|
||||
goto error_free_delayed;
|
||||
}
|
||||
|
||||
amdgpu_vm_bo_base_init(&vm->root, vm, root_bo);
|
||||
r = dma_resv_reserve_fences(root_bo->tbo.base.resv, 1);
|
||||
if (r)
|
||||
goto error_free_root;
|
||||
|
||||
r = dma_resv_reserve_fences(root_bo->tbo.base.resv, 1);
|
||||
if (r)
|
||||
goto error_unreserve;
|
||||
|
||||
amdgpu_vm_bo_base_init(&vm->root, vm, root_bo);
|
||||
|
||||
r = amdgpu_vm_pt_clear(adev, vm, root, false);
|
||||
if (r)
|
||||
goto error_unreserve;
|
||||
goto error_free_root;
|
||||
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
|
||||
INIT_KFIFO(vm->faults);
|
||||
amdgpu_bo_unref(&root_bo);
|
||||
|
||||
return 0;
|
||||
|
||||
error_unreserve:
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
|
||||
error_free_root:
|
||||
amdgpu_bo_unref(&root->shadow);
|
||||
amdgpu_vm_pt_free_root(adev, vm);
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
amdgpu_bo_unref(&root_bo);
|
||||
vm->root.bo = NULL;
|
||||
|
||||
error_free_delayed:
|
||||
dma_fence_put(vm->last_tlb_flush);
|
||||
|
||||
@@ -103,6 +103,53 @@ static const int walf_pcs_err_noncorrectable_mask_reg_aldebaran[] = {
|
||||
smnPCS_GOPX1_PCS_ERROR_NONCORRECTABLE_MASK + 0x100000
|
||||
};
|
||||
|
||||
static const int xgmi3x16_pcs_err_status_reg_v6_4[] = {
|
||||
smnPCS_XGMI3X16_PCS_ERROR_STATUS,
|
||||
smnPCS_XGMI3X16_PCS_ERROR_STATUS + 0x100000
|
||||
};
|
||||
|
||||
static const int xgmi3x16_pcs_err_noncorrectable_mask_reg_v6_4[] = {
|
||||
smnPCS_XGMI3X16_PCS_ERROR_NONCORRECTABLE_MASK,
|
||||
smnPCS_XGMI3X16_PCS_ERROR_NONCORRECTABLE_MASK + 0x100000
|
||||
};
|
||||
|
||||
static const u64 xgmi_v6_4_0_mca_base_array[] = {
|
||||
0x11a09200,
|
||||
0x11b09200,
|
||||
};
|
||||
|
||||
static const char *xgmi_v6_4_0_ras_error_code_ext[32] = {
|
||||
[0x00] = "XGMI PCS DataLossErr",
|
||||
[0x01] = "XGMI PCS TrainingErr",
|
||||
[0x02] = "XGMI PCS FlowCtrlAckErr",
|
||||
[0x03] = "XGMI PCS RxFifoUnderflowErr",
|
||||
[0x04] = "XGMI PCS RxFifoOverflowErr",
|
||||
[0x05] = "XGMI PCS CRCErr",
|
||||
[0x06] = "XGMI PCS BERExceededErr",
|
||||
[0x07] = "XGMI PCS TxMetaDataErr",
|
||||
[0x08] = "XGMI PCS ReplayBufParityErr",
|
||||
[0x09] = "XGMI PCS DataParityErr",
|
||||
[0x0a] = "XGMI PCS ReplayFifoOverflowErr",
|
||||
[0x0b] = "XGMI PCS ReplayFifoUnderflowErr",
|
||||
[0x0c] = "XGMI PCS ElasticFifoOverflowErr",
|
||||
[0x0d] = "XGMI PCS DeskewErr",
|
||||
[0x0e] = "XGMI PCS FlowCtrlCRCErr",
|
||||
[0x0f] = "XGMI PCS DataStartupLimitErr",
|
||||
[0x10] = "XGMI PCS FCInitTimeoutErr",
|
||||
[0x11] = "XGMI PCS RecoveryTimeoutErr",
|
||||
[0x12] = "XGMI PCS ReadySerialTimeoutErr",
|
||||
[0x13] = "XGMI PCS ReadySerialAttemptErr",
|
||||
[0x14] = "XGMI PCS RecoveryAttemptErr",
|
||||
[0x15] = "XGMI PCS RecoveryRelockAttemptErr",
|
||||
[0x16] = "XGMI PCS ReplayAttemptErr",
|
||||
[0x17] = "XGMI PCS SyncHdrErr",
|
||||
[0x18] = "XGMI PCS TxReplayTimeoutErr",
|
||||
[0x19] = "XGMI PCS RxReplayTimeoutErr",
|
||||
[0x1a] = "XGMI PCS LinkSubTxTimeoutErr",
|
||||
[0x1b] = "XGMI PCS LinkSubRxTimeoutErr",
|
||||
[0x1c] = "XGMI PCS RxCMDPktErr",
|
||||
};
|
||||
|
||||
static const struct amdgpu_pcs_ras_field xgmi_pcs_ras_fields[] = {
|
||||
{"XGMI PCS DataLossErr",
|
||||
SOC15_REG_FIELD(XGMI0_PCS_GOPX16_PCS_ERROR_STATUS, DataLossErr)},
|
||||
@@ -926,7 +973,7 @@ static void pcs_clear_status(struct amdgpu_device *adev, uint32_t pcs_status_reg
|
||||
WREG32_PCIE(pcs_status_reg, 0);
|
||||
}
|
||||
|
||||
static void amdgpu_xgmi_reset_ras_error_count(struct amdgpu_device *adev)
|
||||
static void amdgpu_xgmi_legacy_reset_ras_error_count(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
@@ -952,6 +999,49 @@ static void amdgpu_xgmi_reset_ras_error_count(struct amdgpu_device *adev)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (amdgpu_ip_version(adev, XGMI_HWIP, 0)) {
|
||||
case IP_VERSION(6, 4, 0):
|
||||
for (i = 0; i < ARRAY_SIZE(xgmi3x16_pcs_err_status_reg_v6_4); i++)
|
||||
pcs_clear_status(adev,
|
||||
xgmi3x16_pcs_err_status_reg_v6_4[i]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void __xgmi_v6_4_0_reset_error_count(struct amdgpu_device *adev, int xgmi_inst, u64 mca_base)
|
||||
{
|
||||
WREG64_MCA(xgmi_inst, mca_base, MCA_REG_IDX_STATUS, 0ULL);
|
||||
}
|
||||
|
||||
static void xgmi_v6_4_0_reset_error_count(struct amdgpu_device *adev, int xgmi_inst)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(xgmi_v6_4_0_mca_base_array); i++)
|
||||
__xgmi_v6_4_0_reset_error_count(adev, xgmi_inst, xgmi_v6_4_0_mca_base_array[i]);
|
||||
}
|
||||
|
||||
static void xgmi_v6_4_0_reset_ras_error_count(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_inst(i, adev->aid_mask)
|
||||
xgmi_v6_4_0_reset_error_count(adev, i);
|
||||
}
|
||||
|
||||
static void amdgpu_xgmi_reset_ras_error_count(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (amdgpu_ip_version(adev, XGMI_HWIP, 0)) {
|
||||
case IP_VERSION(6, 4, 0):
|
||||
xgmi_v6_4_0_reset_ras_error_count(adev);
|
||||
break;
|
||||
default:
|
||||
amdgpu_xgmi_legacy_reset_ras_error_count(adev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int amdgpu_xgmi_query_pcs_error_status(struct amdgpu_device *adev,
|
||||
@@ -969,7 +1059,9 @@ static int amdgpu_xgmi_query_pcs_error_status(struct amdgpu_device *adev,
|
||||
|
||||
if (is_xgmi_pcs) {
|
||||
if (amdgpu_ip_version(adev, XGMI_HWIP, 0) ==
|
||||
IP_VERSION(6, 1, 0)) {
|
||||
IP_VERSION(6, 1, 0) ||
|
||||
amdgpu_ip_version(adev, XGMI_HWIP, 0) ==
|
||||
IP_VERSION(6, 4, 0)) {
|
||||
pcs_ras_fields = &xgmi3x16_pcs_ras_fields[0];
|
||||
field_array_size = ARRAY_SIZE(xgmi3x16_pcs_ras_fields);
|
||||
} else {
|
||||
@@ -1003,11 +1095,11 @@ static int amdgpu_xgmi_query_pcs_error_status(struct amdgpu_device *adev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
|
||||
void *ras_error_status)
|
||||
static void amdgpu_xgmi_legacy_query_ras_error_count(struct amdgpu_device *adev,
|
||||
void *ras_error_status)
|
||||
{
|
||||
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
|
||||
int i;
|
||||
int i, supported = 1;
|
||||
uint32_t data, mask_data = 0;
|
||||
uint32_t ue_cnt = 0, ce_cnt = 0;
|
||||
|
||||
@@ -1071,7 +1163,25 @@ static void amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_warn(adev->dev, "XGMI RAS error query not supported");
|
||||
supported = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (amdgpu_ip_version(adev, XGMI_HWIP, 0)) {
|
||||
case IP_VERSION(6, 4, 0):
|
||||
/* check xgmi3x16 pcs error */
|
||||
for (i = 0; i < ARRAY_SIZE(xgmi3x16_pcs_err_status_reg_v6_4); i++) {
|
||||
data = RREG32_PCIE(xgmi3x16_pcs_err_status_reg_v6_4[i]);
|
||||
mask_data =
|
||||
RREG32_PCIE(xgmi3x16_pcs_err_noncorrectable_mask_reg_v6_4[i]);
|
||||
if (data)
|
||||
amdgpu_xgmi_query_pcs_error_status(adev, data,
|
||||
mask_data, &ue_cnt, &ce_cnt, true, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!supported)
|
||||
dev_warn(adev->dev, "XGMI RAS error query not supported");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1081,32 +1191,116 @@ static void amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
|
||||
err_data->ce_count += ce_cnt;
|
||||
}
|
||||
|
||||
static enum amdgpu_mca_error_type xgmi_v6_4_0_pcs_mca_get_error_type(struct amdgpu_device *adev, u64 status)
|
||||
{
|
||||
const char *error_str;
|
||||
int ext_error_code;
|
||||
|
||||
ext_error_code = MCA_REG__STATUS__ERRORCODEEXT(status);
|
||||
|
||||
error_str = ext_error_code < ARRAY_SIZE(xgmi_v6_4_0_ras_error_code_ext) ?
|
||||
xgmi_v6_4_0_ras_error_code_ext[ext_error_code] : NULL;
|
||||
if (error_str)
|
||||
dev_info(adev->dev, "%s detected\n", error_str);
|
||||
|
||||
switch (ext_error_code) {
|
||||
case 0:
|
||||
return AMDGPU_MCA_ERROR_TYPE_UE;
|
||||
case 6:
|
||||
return AMDGPU_MCA_ERROR_TYPE_CE;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void __xgmi_v6_4_0_query_error_count(struct amdgpu_device *adev, struct amdgpu_smuio_mcm_config_info *mcm_info,
|
||||
u64 mca_base, struct ras_err_data *err_data)
|
||||
{
|
||||
int xgmi_inst = mcm_info->die_id;
|
||||
u64 status = 0;
|
||||
|
||||
status = RREG64_MCA(xgmi_inst, mca_base, MCA_REG_IDX_STATUS);
|
||||
if (!MCA_REG__STATUS__VAL(status))
|
||||
return;
|
||||
|
||||
switch (xgmi_v6_4_0_pcs_mca_get_error_type(adev, status)) {
|
||||
case AMDGPU_MCA_ERROR_TYPE_UE:
|
||||
amdgpu_ras_error_statistic_ue_count(err_data, mcm_info, 1ULL);
|
||||
break;
|
||||
case AMDGPU_MCA_ERROR_TYPE_CE:
|
||||
amdgpu_ras_error_statistic_ce_count(err_data, mcm_info, 1ULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
WREG64_MCA(xgmi_inst, mca_base, MCA_REG_IDX_STATUS, 0ULL);
|
||||
}
|
||||
|
||||
static void xgmi_v6_4_0_query_error_count(struct amdgpu_device *adev, int xgmi_inst, struct ras_err_data *err_data)
|
||||
{
|
||||
struct amdgpu_smuio_mcm_config_info mcm_info = {
|
||||
.socket_id = adev->smuio.funcs->get_socket_id(adev),
|
||||
.die_id = xgmi_inst,
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(xgmi_v6_4_0_mca_base_array); i++)
|
||||
__xgmi_v6_4_0_query_error_count(adev, &mcm_info, xgmi_v6_4_0_mca_base_array[i], err_data);
|
||||
}
|
||||
|
||||
static void xgmi_v6_4_0_query_ras_error_count(struct amdgpu_device *adev, void *ras_error_status)
|
||||
{
|
||||
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
|
||||
int i;
|
||||
|
||||
for_each_inst(i, adev->aid_mask)
|
||||
xgmi_v6_4_0_query_error_count(adev, i, err_data);
|
||||
}
|
||||
|
||||
static void amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
|
||||
void *ras_error_status)
|
||||
{
|
||||
switch (amdgpu_ip_version(adev, XGMI_HWIP, 0)) {
|
||||
case IP_VERSION(6, 4, 0):
|
||||
xgmi_v6_4_0_query_ras_error_count(adev, ras_error_status);
|
||||
break;
|
||||
default:
|
||||
amdgpu_xgmi_legacy_query_ras_error_count(adev, ras_error_status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Trigger XGMI/WAFL error */
|
||||
static int amdgpu_ras_error_inject_xgmi(struct amdgpu_device *adev,
|
||||
void *inject_if, uint32_t instance_mask)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret1, ret2;
|
||||
struct ta_ras_trigger_error_input *block_info =
|
||||
(struct ta_ras_trigger_error_input *)inject_if;
|
||||
|
||||
if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_DISALLOW))
|
||||
dev_warn(adev->dev, "Failed to disallow df cstate");
|
||||
|
||||
if (amdgpu_dpm_set_xgmi_plpd_mode(adev, XGMI_PLPD_DISALLOW))
|
||||
ret1 = amdgpu_dpm_set_xgmi_plpd_mode(adev, XGMI_PLPD_DISALLOW);
|
||||
if (ret1 && ret1 != -EOPNOTSUPP)
|
||||
dev_warn(adev->dev, "Failed to disallow XGMI power down");
|
||||
|
||||
ret = psp_ras_trigger_error(&adev->psp, block_info, instance_mask);
|
||||
ret2 = psp_ras_trigger_error(&adev->psp, block_info, instance_mask);
|
||||
|
||||
if (amdgpu_ras_intr_triggered())
|
||||
return ret;
|
||||
return ret2;
|
||||
|
||||
if (amdgpu_dpm_set_xgmi_plpd_mode(adev, XGMI_PLPD_DEFAULT))
|
||||
ret1 = amdgpu_dpm_set_xgmi_plpd_mode(adev, XGMI_PLPD_DEFAULT);
|
||||
if (ret1 && ret1 != -EOPNOTSUPP)
|
||||
dev_warn(adev->dev, "Failed to allow XGMI power down");
|
||||
|
||||
if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_ALLOW))
|
||||
dev_warn(adev->dev, "Failed to allow df cstate");
|
||||
|
||||
return ret;
|
||||
return ret2;
|
||||
}
|
||||
|
||||
struct amdgpu_ras_block_hw_ops xgmi_ras_hw_ops = {
|
||||
|
||||
@@ -1102,6 +1102,7 @@ static void gfx_v9_4_3_init_rlcg_reg_access_ctrl(struct amdgpu_device *adev)
|
||||
reg_access_ctrl->grbm_idx = SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), regGRBM_GFX_INDEX);
|
||||
reg_access_ctrl->spare_int = SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), regRLC_SPARE_INT);
|
||||
}
|
||||
adev->gfx.rlc.rlcg_reg_access_supported = true;
|
||||
}
|
||||
|
||||
static int gfx_v9_4_3_rlc_init(struct amdgpu_device *adev)
|
||||
@@ -2738,16 +2739,16 @@ static void gfx_v9_4_3_xcc_set_compute_eop_interrupt_state(
|
||||
|
||||
switch (state) {
|
||||
case AMDGPU_IRQ_STATE_DISABLE:
|
||||
mec_int_cntl = RREG32(mec_int_cntl_reg);
|
||||
mec_int_cntl = RREG32_XCC(mec_int_cntl_reg, xcc_id);
|
||||
mec_int_cntl = REG_SET_FIELD(mec_int_cntl, CP_ME1_PIPE0_INT_CNTL,
|
||||
TIME_STAMP_INT_ENABLE, 0);
|
||||
WREG32(mec_int_cntl_reg, mec_int_cntl);
|
||||
WREG32_XCC(mec_int_cntl_reg, mec_int_cntl, xcc_id);
|
||||
break;
|
||||
case AMDGPU_IRQ_STATE_ENABLE:
|
||||
mec_int_cntl = RREG32(mec_int_cntl_reg);
|
||||
mec_int_cntl = RREG32_XCC(mec_int_cntl_reg, xcc_id);
|
||||
mec_int_cntl = REG_SET_FIELD(mec_int_cntl, CP_ME1_PIPE0_INT_CNTL,
|
||||
TIME_STAMP_INT_ENABLE, 1);
|
||||
WREG32(mec_int_cntl_reg, mec_int_cntl);
|
||||
WREG32_XCC(mec_int_cntl_reg, mec_int_cntl, xcc_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -3799,6 +3800,27 @@ static void gfx_v9_4_3_inst_query_ras_err_count(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
/* handle extra register entries of UE */
|
||||
for (; i < ARRAY_SIZE(gfx_v9_4_3_ue_reg_list); i++) {
|
||||
for (j = 0; j < gfx_v9_4_3_ue_reg_list[i].se_num; j++) {
|
||||
for (k = 0; k < gfx_v9_4_3_ue_reg_list[i].reg_entry.reg_inst; k++) {
|
||||
/* no need to select if instance number is 1 */
|
||||
if (gfx_v9_4_3_ue_reg_list[i].se_num > 1 ||
|
||||
gfx_v9_4_3_ue_reg_list[i].reg_entry.reg_inst > 1)
|
||||
gfx_v9_4_3_xcc_select_se_sh(adev, j, 0, k, xcc_id);
|
||||
|
||||
amdgpu_ras_inst_query_ras_error_count(adev,
|
||||
&(gfx_v9_4_3_ue_reg_list[i].reg_entry),
|
||||
1,
|
||||
gfx_v9_4_3_ras_mem_list_array[gfx_v9_4_3_ue_reg_list[i].mem_id_type].mem_id_ent,
|
||||
gfx_v9_4_3_ras_mem_list_array[gfx_v9_4_3_ue_reg_list[i].mem_id_type].size,
|
||||
GET_INST(GC, xcc_id),
|
||||
AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
|
||||
&ue_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gfx_v9_4_3_xcc_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
xcc_id);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
@@ -3838,6 +3860,23 @@ static void gfx_v9_4_3_inst_reset_ras_err_count(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
/* handle extra register entries of UE */
|
||||
for (; i < ARRAY_SIZE(gfx_v9_4_3_ue_reg_list); i++) {
|
||||
for (j = 0; j < gfx_v9_4_3_ue_reg_list[i].se_num; j++) {
|
||||
for (k = 0; k < gfx_v9_4_3_ue_reg_list[i].reg_entry.reg_inst; k++) {
|
||||
/* no need to select if instance number is 1 */
|
||||
if (gfx_v9_4_3_ue_reg_list[i].se_num > 1 ||
|
||||
gfx_v9_4_3_ue_reg_list[i].reg_entry.reg_inst > 1)
|
||||
gfx_v9_4_3_xcc_select_se_sh(adev, j, 0, k, xcc_id);
|
||||
|
||||
amdgpu_ras_inst_reset_ras_error_count(adev,
|
||||
&(gfx_v9_4_3_ue_reg_list[i].reg_entry),
|
||||
1,
|
||||
GET_INST(GC, xcc_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gfx_v9_4_3_xcc_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
xcc_id);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
@@ -4300,7 +4339,7 @@ const struct amdgpu_ip_block_version gfx_v9_4_3_ip_block = {
|
||||
.type = AMD_IP_BLOCK_TYPE_GFX,
|
||||
.major = 9,
|
||||
.minor = 4,
|
||||
.rev = 0,
|
||||
.rev = 3,
|
||||
.funcs = &gfx_v9_4_3_ip_funcs,
|
||||
};
|
||||
|
||||
|
||||
@@ -268,7 +268,7 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
if (adev->gfx.kiq[0].ring.sched.ready && !adev->enable_mes &&
|
||||
(amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
|
||||
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
|
||||
1 << vmid);
|
||||
1 << vmid, GET_INST(GC, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -672,6 +672,7 @@ static void gmc_v10_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
/* add the xgmi offset of the physical node */
|
||||
base += adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size;
|
||||
|
||||
amdgpu_gmc_set_agp_default(adev, mc);
|
||||
amdgpu_gmc_vram_location(adev, &adev->gmc, base);
|
||||
amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_BEST_FIT);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
|
||||
@@ -229,7 +229,7 @@ static void gmc_v11_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
if ((adev->gfx.kiq[0].ring.sched.ready || adev->mes.ring.sched.ready) &&
|
||||
(amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
|
||||
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
|
||||
1 << vmid);
|
||||
1 << vmid, GET_INST(GC, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -637,6 +637,7 @@ static void gmc_v11_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
|
||||
base = adev->mmhub.funcs->get_fb_location(adev);
|
||||
|
||||
amdgpu_gmc_set_agp_default(adev, mc);
|
||||
amdgpu_gmc_vram_location(adev, &adev->gmc, base);
|
||||
amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_HIGH);
|
||||
if (!amdgpu_sriov_vf(adev) ||
|
||||
|
||||
@@ -211,6 +211,7 @@ static void gmc_v6_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
|
||||
base <<= 24;
|
||||
|
||||
amdgpu_gmc_set_agp_default(adev, mc);
|
||||
amdgpu_gmc_vram_location(adev, mc, base);
|
||||
amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_BEST_FIT);
|
||||
}
|
||||
|
||||
@@ -239,6 +239,7 @@ static void gmc_v7_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
|
||||
base <<= 24;
|
||||
|
||||
amdgpu_gmc_set_agp_default(adev, mc);
|
||||
amdgpu_gmc_vram_location(adev, mc, base);
|
||||
amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_BEST_FIT);
|
||||
}
|
||||
|
||||
@@ -413,6 +413,7 @@ static void gmc_v8_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF;
|
||||
base <<= 24;
|
||||
|
||||
amdgpu_gmc_set_agp_default(adev, mc);
|
||||
amdgpu_gmc_vram_location(adev, mc, base);
|
||||
amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_BEST_FIT);
|
||||
}
|
||||
|
||||
@@ -817,7 +817,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
uint32_t vmhub, uint32_t flush_type)
|
||||
{
|
||||
bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub);
|
||||
u32 j, inv_req, tmp, sem, req, ack;
|
||||
u32 j, inv_req, tmp, sem, req, ack, inst;
|
||||
const unsigned int eng = 17;
|
||||
struct amdgpu_vmhub *hub;
|
||||
|
||||
@@ -832,13 +832,17 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
/* This is necessary for a HW workaround under SRIOV as well
|
||||
* as GFXOFF under bare metal
|
||||
*/
|
||||
if (adev->gfx.kiq[0].ring.sched.ready &&
|
||||
if (vmhub >= AMDGPU_MMHUB0(0))
|
||||
inst = GET_INST(GC, 0);
|
||||
else
|
||||
inst = vmhub;
|
||||
if (adev->gfx.kiq[inst].ring.sched.ready &&
|
||||
(amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
|
||||
uint32_t req = hub->vm_inv_eng0_req + hub->eng_distance * eng;
|
||||
uint32_t ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
|
||||
|
||||
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
|
||||
1 << vmid);
|
||||
1 << vmid, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -856,9 +860,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
for (j = 0; j < adev->usec_timeout; j++) {
|
||||
/* a read return value of 1 means semaphore acquire */
|
||||
if (vmhub >= AMDGPU_MMHUB0(0))
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, sem);
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, sem, inst);
|
||||
else
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(GC, sem);
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(GC, sem, inst);
|
||||
if (tmp & 0x1)
|
||||
break;
|
||||
udelay(1);
|
||||
@@ -869,9 +873,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
}
|
||||
|
||||
if (vmhub >= AMDGPU_MMHUB0(0))
|
||||
WREG32_SOC15_IP_NO_KIQ(MMHUB, req, inv_req);
|
||||
WREG32_SOC15_IP_NO_KIQ(MMHUB, req, inv_req, inst);
|
||||
else
|
||||
WREG32_SOC15_IP_NO_KIQ(GC, req, inv_req);
|
||||
WREG32_SOC15_IP_NO_KIQ(GC, req, inv_req, inst);
|
||||
|
||||
/*
|
||||
* Issue a dummy read to wait for the ACK register to
|
||||
@@ -884,9 +888,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
|
||||
for (j = 0; j < adev->usec_timeout; j++) {
|
||||
if (vmhub >= AMDGPU_MMHUB0(0))
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, ack);
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, ack, inst);
|
||||
else
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(GC, ack);
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(GC, ack, inst);
|
||||
if (tmp & (1 << vmid))
|
||||
break;
|
||||
udelay(1);
|
||||
@@ -899,9 +903,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
* write with 0 means semaphore release
|
||||
*/
|
||||
if (vmhub >= AMDGPU_MMHUB0(0))
|
||||
WREG32_SOC15_IP_NO_KIQ(MMHUB, sem, 0);
|
||||
WREG32_SOC15_IP_NO_KIQ(MMHUB, sem, 0, inst);
|
||||
else
|
||||
WREG32_SOC15_IP_NO_KIQ(GC, sem, 0);
|
||||
WREG32_SOC15_IP_NO_KIQ(GC, sem, 0, inst);
|
||||
}
|
||||
|
||||
spin_unlock(&adev->gmc.invalidate_lock);
|
||||
@@ -1176,7 +1180,10 @@ static void gmc_v9_0_get_coherence_flags(struct amdgpu_device *adev,
|
||||
if (uncached) {
|
||||
mtype = MTYPE_UC;
|
||||
} else if (ext_coherent) {
|
||||
mtype = is_local ? MTYPE_CC : MTYPE_UC;
|
||||
if (adev->rev_id)
|
||||
mtype = is_local ? MTYPE_CC : MTYPE_UC;
|
||||
else
|
||||
mtype = MTYPE_UC;
|
||||
} else if (adev->flags & AMD_IS_APU) {
|
||||
mtype = is_local ? mtype_local : MTYPE_NC;
|
||||
} else {
|
||||
@@ -1297,7 +1304,7 @@ static void gmc_v9_0_override_vm_pte_flags(struct amdgpu_device *adev,
|
||||
|
||||
*flags = (*flags & ~AMDGPU_PTE_MTYPE_VG10_MASK) |
|
||||
AMDGPU_PTE_MTYPE_VG10(mtype_local);
|
||||
} else {
|
||||
} else if (adev->rev_id) {
|
||||
/* MTYPE_UC case */
|
||||
*flags = (*flags & ~AMDGPU_PTE_MTYPE_VG10_MASK) |
|
||||
AMDGPU_PTE_MTYPE_VG10(MTYPE_CC);
|
||||
@@ -1614,6 +1621,8 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
{
|
||||
u64 base = adev->mmhub.funcs->get_fb_location(adev);
|
||||
|
||||
amdgpu_gmc_set_agp_default(adev, mc);
|
||||
|
||||
/* add the xgmi offset of the physical node */
|
||||
base += adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size;
|
||||
if (adev->gmc.xgmi.connected_to_cpu) {
|
||||
|
||||
@@ -145,6 +145,10 @@ static void hdp_v4_0_init_registers(struct amdgpu_device *adev)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Do not program registers if VF */
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return;
|
||||
|
||||
WREG32_FIELD15(HDP, 0, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 1);
|
||||
|
||||
if (amdgpu_ip_version(adev, HDP_HWIP, 0) == IP_VERSION(4, 4, 0))
|
||||
|
||||
@@ -654,9 +654,11 @@ static void jpeg_v4_0_3_dec_ring_set_wptr(struct amdgpu_ring *ring)
|
||||
*/
|
||||
static void jpeg_v4_0_3_dec_ring_insert_start(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
amdgpu_ring_write(ring, 0x62a04); /* PCTL0_MMHUB_DEEPSLEEP_IB */
|
||||
if (!amdgpu_sriov_vf(ring->adev)) {
|
||||
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
amdgpu_ring_write(ring, 0x62a04); /* PCTL0_MMHUB_DEEPSLEEP_IB */
|
||||
}
|
||||
|
||||
amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
@@ -672,9 +674,11 @@ static void jpeg_v4_0_3_dec_ring_insert_start(struct amdgpu_ring *ring)
|
||||
*/
|
||||
static void jpeg_v4_0_3_dec_ring_insert_end(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
amdgpu_ring_write(ring, 0x62a04);
|
||||
if (!amdgpu_sriov_vf(ring->adev)) {
|
||||
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
amdgpu_ring_write(ring, 0x62a04);
|
||||
}
|
||||
|
||||
amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
|
||||
@@ -427,6 +427,7 @@ static void sdma_v4_4_2_inst_gfx_stop(struct amdgpu_device *adev,
|
||||
uint32_t inst_mask)
|
||||
{
|
||||
struct amdgpu_ring *sdma[AMDGPU_MAX_SDMA_INSTANCES];
|
||||
u32 doorbell_offset, doorbell;
|
||||
u32 rb_cntl, ib_cntl;
|
||||
int i, unset = 0;
|
||||
|
||||
@@ -444,6 +445,18 @@ static void sdma_v4_4_2_inst_gfx_stop(struct amdgpu_device *adev,
|
||||
ib_cntl = RREG32_SDMA(i, regSDMA_GFX_IB_CNTL);
|
||||
ib_cntl = REG_SET_FIELD(ib_cntl, SDMA_GFX_IB_CNTL, IB_ENABLE, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_IB_CNTL, ib_cntl);
|
||||
|
||||
if (sdma[i]->use_doorbell) {
|
||||
doorbell = RREG32_SDMA(i, regSDMA_GFX_DOORBELL);
|
||||
doorbell_offset = RREG32_SDMA(i, regSDMA_GFX_DOORBELL_OFFSET);
|
||||
|
||||
doorbell = REG_SET_FIELD(doorbell, SDMA_GFX_DOORBELL, ENABLE, 0);
|
||||
doorbell_offset = REG_SET_FIELD(doorbell_offset,
|
||||
SDMA_GFX_DOORBELL_OFFSET,
|
||||
OFFSET, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_DOORBELL, doorbell);
|
||||
WREG32_SDMA(i, regSDMA_GFX_DOORBELL_OFFSET, doorbell_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,12 +644,6 @@ static void sdma_v4_4_2_gfx_resume(struct amdgpu_device *adev, unsigned int i)
|
||||
rb_cntl = sdma_v4_4_2_rb_cntl(ring, rb_cntl);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_CNTL, rb_cntl);
|
||||
|
||||
/* Initialize the ring buffer's read and write pointers */
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_RPTR, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_RPTR_HI, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_WPTR, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_WPTR_HI, 0);
|
||||
|
||||
/* set the wb address whether it's enabled or not */
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_RPTR_ADDR_HI,
|
||||
upper_32_bits(adev->wb.gpu_addr + wb_offset) & 0xFFFFFFFF);
|
||||
@@ -654,6 +661,12 @@ static void sdma_v4_4_2_gfx_resume(struct amdgpu_device *adev, unsigned int i)
|
||||
/* before programing wptr to a less value, need set minor_ptr_update first */
|
||||
WREG32_SDMA(i, regSDMA_GFX_MINOR_PTR_UPDATE, 1);
|
||||
|
||||
/* Initialize the ring buffer's read and write pointers */
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_RPTR, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_RPTR_HI, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_WPTR, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_WPTR_HI, 0);
|
||||
|
||||
doorbell = RREG32_SDMA(i, regSDMA_GFX_DOORBELL);
|
||||
doorbell_offset = RREG32_SDMA(i, regSDMA_GFX_DOORBELL_OFFSET);
|
||||
|
||||
@@ -2048,7 +2061,7 @@ const struct amdgpu_ip_block_version sdma_v4_4_2_ip_block = {
|
||||
.type = AMD_IP_BLOCK_TYPE_SDMA,
|
||||
.major = 4,
|
||||
.minor = 4,
|
||||
.rev = 0,
|
||||
.rev = 2,
|
||||
.funcs = &sdma_v4_4_2_ip_funcs,
|
||||
};
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
|
||||
#define RREG32_SOC15_IP(ip, reg) __RREG32_SOC15_RLC__(reg, 0, ip##_HWIP, 0)
|
||||
|
||||
#define RREG32_SOC15_IP_NO_KIQ(ip, reg) __RREG32_SOC15_RLC__(reg, AMDGPU_REGS_NO_KIQ, ip##_HWIP, 0)
|
||||
#define RREG32_SOC15_IP_NO_KIQ(ip, reg, inst) __RREG32_SOC15_RLC__(reg, AMDGPU_REGS_NO_KIQ, ip##_HWIP, inst)
|
||||
|
||||
#define RREG32_SOC15_NO_KIQ(ip, inst, reg) \
|
||||
__RREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg, \
|
||||
@@ -86,8 +86,8 @@
|
||||
#define WREG32_SOC15_IP(ip, reg, value) \
|
||||
__WREG32_SOC15_RLC__(reg, value, 0, ip##_HWIP, 0)
|
||||
|
||||
#define WREG32_SOC15_IP_NO_KIQ(ip, reg, value) \
|
||||
__WREG32_SOC15_RLC__(reg, value, AMDGPU_REGS_NO_KIQ, ip##_HWIP, 0)
|
||||
#define WREG32_SOC15_IP_NO_KIQ(ip, reg, value, inst) \
|
||||
__WREG32_SOC15_RLC__(reg, value, AMDGPU_REGS_NO_KIQ, ip##_HWIP, inst)
|
||||
|
||||
#define WREG32_SOC15_NO_KIQ(ip, inst, reg, value) \
|
||||
__WREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg, \
|
||||
@@ -140,7 +140,7 @@
|
||||
|
||||
/* for GC only */
|
||||
#define RREG32_RLC(reg) \
|
||||
__RREG32_SOC15_RLC__(reg, AMDGPU_REGS_RLC, GC_HWIP)
|
||||
__RREG32_SOC15_RLC__(reg, AMDGPU_REGS_RLC, GC_HWIP, 0)
|
||||
|
||||
#define WREG32_RLC_NO_KIQ(reg, value, hwip) \
|
||||
__WREG32_SOC15_RLC__(reg, value, AMDGPU_REGS_NO_KIQ | AMDGPU_REGS_RLC, hwip, 0)
|
||||
@@ -204,4 +204,10 @@
|
||||
+ adev->asic_funcs->encode_ext_smn_addressing(ext), \
|
||||
value) \
|
||||
|
||||
#define RREG64_MCA(ext, mca_base, idx) \
|
||||
RREG64_PCIE_EXT(adev->asic_funcs->encode_ext_smn_addressing(ext) + mca_base + (idx * 8))
|
||||
|
||||
#define WREG64_MCA(ext, mca_base, idx, val) \
|
||||
WREG64_PCIE_EXT(adev->asic_funcs->encode_ext_smn_addressing(ext) + mca_base + (idx * 8), val)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -381,6 +381,7 @@ soc21_asic_reset_method(struct amdgpu_device *adev)
|
||||
return AMD_RESET_METHOD_MODE1;
|
||||
case IP_VERSION(13, 0, 4):
|
||||
case IP_VERSION(13, 0, 11):
|
||||
case IP_VERSION(14, 0, 0):
|
||||
return AMD_RESET_METHOD_MODE2;
|
||||
default:
|
||||
if (amdgpu_dpm_is_baco_supported(adev))
|
||||
|
||||
@@ -88,7 +88,7 @@ static void umc_v12_0_reset_error_count(struct amdgpu_device *adev)
|
||||
umc_v12_0_reset_error_count_per_channel, NULL);
|
||||
}
|
||||
|
||||
static bool umc_v12_0_is_uncorrectable_error(uint64_t mc_umc_status)
|
||||
bool umc_v12_0_is_uncorrectable_error(uint64_t mc_umc_status)
|
||||
{
|
||||
return ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) &&
|
||||
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC) == 1 ||
|
||||
@@ -96,7 +96,7 @@ static bool umc_v12_0_is_uncorrectable_error(uint64_t mc_umc_status)
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1));
|
||||
}
|
||||
|
||||
static bool umc_v12_0_is_correctable_error(uint64_t mc_umc_status)
|
||||
bool umc_v12_0_is_correctable_error(uint64_t mc_umc_status)
|
||||
{
|
||||
return (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1 ||
|
||||
|
||||
@@ -117,6 +117,9 @@
|
||||
(pa) |= (UMC_V12_0_CHANNEL_HASH_CH6(channel_idx, pa) << UMC_V12_0_PA_CH6_BIT); \
|
||||
} while (0)
|
||||
|
||||
bool umc_v12_0_is_uncorrectable_error(uint64_t mc_umc_status);
|
||||
bool umc_v12_0_is_correctable_error(uint64_t mc_umc_status);
|
||||
|
||||
extern const uint32_t
|
||||
umc_v12_0_channel_idx_tbl[]
|
||||
[UMC_V12_0_UMC_INSTANCE_NUM]
|
||||
|
||||
@@ -577,8 +577,6 @@ static int uvd_v3_1_sw_init(void *handle)
|
||||
ptr += ucode_len;
|
||||
memcpy(&adev->uvd.keyselect, ptr, 4);
|
||||
|
||||
r = amdgpu_uvd_entity_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -127,8 +127,6 @@ static int uvd_v4_2_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_uvd_entity_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -125,8 +125,6 @@ static int uvd_v5_0_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_uvd_entity_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -432,8 +432,6 @@ static int uvd_v6_0_sw_init(void *handle)
|
||||
}
|
||||
}
|
||||
|
||||
r = amdgpu_uvd_entity_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -480,10 +480,6 @@ static int uvd_v7_0_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_uvd_entity_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_alloc_mm_table(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -441,8 +441,6 @@ static int vce_v2_0_sw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_vce_entity_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -450,8 +450,6 @@ static int vce_v3_0_sw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_vce_entity_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -486,11 +486,6 @@ static int vce_v4_0_sw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
r = amdgpu_vce_entity_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_alloc_mm_table(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -1416,8 +1416,13 @@ bool kfd_process_xnack_mode(struct kfd_process *p, bool supported)
|
||||
* per-process XNACK mode selection. But let the dev->noretry
|
||||
* setting still influence the default XNACK mode.
|
||||
*/
|
||||
if (supported && KFD_SUPPORT_XNACK_PER_PROCESS(dev))
|
||||
if (supported && KFD_SUPPORT_XNACK_PER_PROCESS(dev)) {
|
||||
if (!amdgpu_sriov_xnack_support(dev->kfd->adev)) {
|
||||
pr_debug("SRIOV platform xnack not supported\n");
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* GFXv10 and later GPUs do not support shader preemption
|
||||
* during page faults. This can lead to poor QoS for queue
|
||||
|
||||
@@ -1255,9 +1255,11 @@ svm_range_get_pte_flags(struct kfd_node *node,
|
||||
}
|
||||
break;
|
||||
case IP_VERSION(9, 4, 3):
|
||||
mtype_local = amdgpu_mtype_local == 1 ? AMDGPU_VM_MTYPE_NC :
|
||||
(amdgpu_mtype_local == 2 || ext_coherent ?
|
||||
AMDGPU_VM_MTYPE_CC : AMDGPU_VM_MTYPE_RW);
|
||||
if (ext_coherent)
|
||||
mtype_local = node->adev->rev_id ? AMDGPU_VM_MTYPE_CC : AMDGPU_VM_MTYPE_UC;
|
||||
else
|
||||
mtype_local = amdgpu_mtype_local == 1 ? AMDGPU_VM_MTYPE_NC :
|
||||
amdgpu_mtype_local == 2 ? AMDGPU_VM_MTYPE_CC : AMDGPU_VM_MTYPE_RW;
|
||||
snoop = true;
|
||||
if (uncached) {
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_UC;
|
||||
|
||||
@@ -1216,6 +1216,9 @@ bool dm_helpers_dp_handle_test_pattern_request(
|
||||
|
||||
}
|
||||
|
||||
pipe_ctx->stream->test_pattern.type = test_pattern;
|
||||
pipe_ctx->stream->test_pattern.color_space = test_pattern_color_space;
|
||||
|
||||
dc_link_dp_set_test_pattern(
|
||||
(struct dc_link *) link,
|
||||
test_pattern,
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <drm/drm_framebuffer.h>
|
||||
#include <drm/drm_encoder.h>
|
||||
#include <drm/drm_atomic.h>
|
||||
#include "dcn10/dcn10_optc.h"
|
||||
#include "dc/inc/hw/optc.h"
|
||||
|
||||
#include "dc/inc/core_types.h"
|
||||
|
||||
|
||||
@@ -111,17 +111,21 @@ static int dcn35_get_active_display_cnt_wa(
|
||||
return display_count;
|
||||
}
|
||||
|
||||
static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable)
|
||||
static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context,
|
||||
bool safe_to_lower, bool disable)
|
||||
{
|
||||
struct dc *dc = clk_mgr_base->ctx->dc;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; ++i) {
|
||||
struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
struct pipe_ctx *pipe = safe_to_lower
|
||||
? &context->res_ctx.pipe_ctx[i]
|
||||
: &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe->top_pipe || pipe->prev_odm_pipe)
|
||||
continue;
|
||||
if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) {
|
||||
if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal) ||
|
||||
!pipe->stream->link_enc)) {
|
||||
struct stream_encoder *stream_enc = pipe->stream_res.stream_enc;
|
||||
|
||||
if (disable) {
|
||||
@@ -301,11 +305,11 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
|
||||
}
|
||||
|
||||
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
|
||||
dcn35_disable_otg_wa(clk_mgr_base, context, true);
|
||||
dcn35_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true);
|
||||
|
||||
clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
|
||||
dcn35_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
|
||||
dcn35_disable_otg_wa(clk_mgr_base, context, false);
|
||||
dcn35_disable_otg_wa(clk_mgr_base, context, safe_to_lower, false);
|
||||
|
||||
update_dispclk = true;
|
||||
}
|
||||
@@ -814,7 +818,8 @@ static void dcn35_set_idle_state(struct clk_mgr *clk_mgr_base, bool allow_idle)
|
||||
struct dc *dc = clk_mgr_base->ctx->dc;
|
||||
uint32_t val = dcn35_smu_read_ips_scratch(clk_mgr);
|
||||
|
||||
if (dc->config.disable_ips == 0) {
|
||||
if (dc->config.disable_ips == DMUB_IPS_ENABLE ||
|
||||
dc->config.disable_ips == DMUB_IPS_DISABLE_DYNAMIC) {
|
||||
val |= DMUB_IPS1_ALLOW_MASK;
|
||||
val |= DMUB_IPS2_ALLOW_MASK;
|
||||
} else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS1) {
|
||||
@@ -1114,7 +1119,7 @@ void dcn35_clk_mgr_construct(
|
||||
dm_helpers_free_gpu_mem(clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
|
||||
smu_dpm_clks.dpm_clks);
|
||||
|
||||
if (ctx->dc->config.disable_ips == 0) {
|
||||
if (ctx->dc->config.disable_ips != DMUB_IPS_DISABLE_ALL) {
|
||||
bool ips_support = false;
|
||||
|
||||
/*avoid call pmfw at init*/
|
||||
@@ -1127,7 +1132,7 @@ void dcn35_clk_mgr_construct(
|
||||
ctx->dc->debug.disable_hpo_power_gate = false;
|
||||
} else {
|
||||
/*let's reset the config control flag*/
|
||||
ctx->dc->config.disable_ips = 1; /*pmfw not support it, disable it all*/
|
||||
ctx->dc->config.disable_ips = DMUB_IPS_DISABLE_ALL; /*pmfw not support it, disable it all*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2582,6 +2582,9 @@ static enum surface_update_type det_surface_update(const struct dc *dc,
|
||||
if (u->gamut_remap_matrix)
|
||||
update_flags->bits.gamut_remap_change = 1;
|
||||
|
||||
if (u->blend_tf)
|
||||
update_flags->bits.gamma_change = 1;
|
||||
|
||||
if (u->gamma) {
|
||||
enum surface_pixel_format format = SURFACE_PIXEL_FORMAT_GRPH_BEGIN;
|
||||
|
||||
@@ -4113,8 +4116,17 @@ static bool commit_minimal_transition_state_for_windowed_mpo_odm(struct dc *dc,
|
||||
bool success = false;
|
||||
struct dc_state *minimal_transition_context;
|
||||
struct pipe_split_policy_backup policy;
|
||||
struct mall_temp_config mall_temp_config;
|
||||
|
||||
/* commit based on new context */
|
||||
/* Since all phantom pipes are removed in full validation,
|
||||
* we have to save and restore the subvp/mall config when
|
||||
* we do a minimal transition since the flags marking the
|
||||
* pipe as subvp/phantom will be cleared (dc copy constructor
|
||||
* creates a shallow copy).
|
||||
*/
|
||||
if (dc->res_pool->funcs->save_mall_state)
|
||||
dc->res_pool->funcs->save_mall_state(dc, context, &mall_temp_config);
|
||||
minimal_transition_context = create_minimal_transition_state(dc,
|
||||
context, &policy);
|
||||
if (minimal_transition_context) {
|
||||
@@ -4123,9 +4135,20 @@ static bool commit_minimal_transition_state_for_windowed_mpo_odm(struct dc *dc,
|
||||
dc->hwss.is_pipe_topology_transition_seamless(
|
||||
dc, minimal_transition_context, context)) {
|
||||
DC_LOG_DC("%s base = new state\n", __func__);
|
||||
|
||||
success = dc_commit_state_no_check(dc, minimal_transition_context) == DC_OK;
|
||||
}
|
||||
release_minimal_transition_state(dc, minimal_transition_context, &policy);
|
||||
if (dc->res_pool->funcs->restore_mall_state)
|
||||
dc->res_pool->funcs->restore_mall_state(dc, context, &mall_temp_config);
|
||||
/* If we do a minimal transition with plane removal and the context
|
||||
* has subvp we also have to retain back the phantom stream / planes
|
||||
* since the refcount is decremented as part of the min transition
|
||||
* (we commit a state with no subvp, so the phantom streams / planes
|
||||
* had to be removed).
|
||||
*/
|
||||
if (dc->res_pool->funcs->retain_phantom_pipes)
|
||||
dc->res_pool->funcs->retain_phantom_pipes(dc, context);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
@@ -4884,7 +4907,7 @@ void dc_allow_idle_optimizations(struct dc *dc, bool allow)
|
||||
if (dc->debug.disable_idle_power_optimizations)
|
||||
return;
|
||||
|
||||
if (dc->caps.ips_support && dc->config.disable_ips)
|
||||
if (dc->caps.ips_support && (dc->config.disable_ips == DMUB_IPS_DISABLE_ALL))
|
||||
return;
|
||||
|
||||
if (dc->clk_mgr != NULL && dc->clk_mgr->funcs->is_smu_present)
|
||||
@@ -4905,7 +4928,7 @@ bool dc_dmub_is_ips_idle_state(struct dc *dc)
|
||||
if (dc->debug.disable_idle_power_optimizations)
|
||||
return false;
|
||||
|
||||
if (!dc->caps.ips_support || dc->config.disable_ips)
|
||||
if (!dc->caps.ips_support || (dc->config.disable_ips == DMUB_IPS_DISABLE_ALL))
|
||||
return false;
|
||||
|
||||
if (dc->hwss.get_idle_state)
|
||||
|
||||
@@ -49,7 +49,7 @@ struct aux_payload;
|
||||
struct set_config_cmd_payload;
|
||||
struct dmub_notification;
|
||||
|
||||
#define DC_VER "3.2.256"
|
||||
#define DC_VER "3.2.259"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
|
||||
@@ -120,6 +120,80 @@ void dc_dmub_srv_send_inbox0_cmd(struct dc_dmub_srv *dc_dmub_srv,
|
||||
}
|
||||
}
|
||||
|
||||
bool dc_dmub_srv_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_srv,
|
||||
unsigned int count,
|
||||
union dmub_rb_cmd *cmd_list)
|
||||
{
|
||||
struct dc_context *dc_ctx = dc_dmub_srv->ctx;
|
||||
struct dmub_srv *dmub;
|
||||
enum dmub_status status;
|
||||
int i;
|
||||
|
||||
if (!dc_dmub_srv || !dc_dmub_srv->dmub)
|
||||
return false;
|
||||
|
||||
dmub = dc_dmub_srv->dmub;
|
||||
|
||||
for (i = 0 ; i < count; i++) {
|
||||
// Queue command
|
||||
status = dmub_srv_cmd_queue(dmub, &cmd_list[i]);
|
||||
|
||||
if (status == DMUB_STATUS_QUEUE_FULL) {
|
||||
/* Execute and wait for queue to become empty again. */
|
||||
dmub_srv_cmd_execute(dmub);
|
||||
dmub_srv_wait_for_idle(dmub, 100000);
|
||||
|
||||
/* Requeue the command. */
|
||||
status = dmub_srv_cmd_queue(dmub, &cmd_list[i]);
|
||||
}
|
||||
|
||||
if (status != DMUB_STATUS_OK) {
|
||||
DC_ERROR("Error queueing DMUB command: status=%d\n", status);
|
||||
dc_dmub_srv_log_diagnostic_data(dc_dmub_srv);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
status = dmub_srv_cmd_execute(dmub);
|
||||
if (status != DMUB_STATUS_OK) {
|
||||
DC_ERROR("Error starting DMUB execution: status=%d\n", status);
|
||||
dc_dmub_srv_log_diagnostic_data(dc_dmub_srv);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dc_dmub_srv_wait_for_idle(struct dc_dmub_srv *dc_dmub_srv,
|
||||
enum dm_dmub_wait_type wait_type,
|
||||
union dmub_rb_cmd *cmd_list)
|
||||
{
|
||||
struct dmub_srv *dmub;
|
||||
enum dmub_status status;
|
||||
|
||||
if (!dc_dmub_srv || !dc_dmub_srv->dmub)
|
||||
return false;
|
||||
|
||||
dmub = dc_dmub_srv->dmub;
|
||||
|
||||
// Wait for DMUB to process command
|
||||
if (wait_type != DM_DMUB_WAIT_TYPE_NO_WAIT) {
|
||||
status = dmub_srv_wait_for_idle(dmub, 100000);
|
||||
|
||||
if (status != DMUB_STATUS_OK) {
|
||||
DC_LOG_DEBUG("No reply for DMUB command: status=%d\n", status);
|
||||
dc_dmub_srv_log_diagnostic_data(dc_dmub_srv);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy data back from ring buffer into command
|
||||
if (wait_type == DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)
|
||||
dmub_rb_get_return_data(&dmub->inbox1_rb, cmd_list);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dc_dmub_srv_cmd_run(struct dc_dmub_srv *dc_dmub_srv, union dmub_rb_cmd *cmd, enum dm_dmub_wait_type wait_type)
|
||||
{
|
||||
return dc_dmub_srv_cmd_run_list(dc_dmub_srv, 1, cmd, wait_type);
|
||||
|
||||
@@ -56,6 +56,14 @@ void dc_dmub_srv_wait_idle(struct dc_dmub_srv *dc_dmub_srv);
|
||||
|
||||
bool dc_dmub_srv_optimized_init_done(struct dc_dmub_srv *dc_dmub_srv);
|
||||
|
||||
bool dc_dmub_srv_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_srv,
|
||||
unsigned int count,
|
||||
union dmub_rb_cmd *cmd_list);
|
||||
|
||||
bool dc_dmub_srv_wait_for_idle(struct dc_dmub_srv *dc_dmub_srv,
|
||||
enum dm_dmub_wait_type wait_type,
|
||||
union dmub_rb_cmd *cmd_list);
|
||||
|
||||
bool dc_dmub_srv_cmd_run(struct dc_dmub_srv *dc_dmub_srv, union dmub_rb_cmd *cmd, enum dm_dmub_wait_type wait_type);
|
||||
|
||||
bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv *dc_dmub_srv, unsigned int count, union dmub_rb_cmd *cmd_list, enum dm_dmub_wait_type wait_type);
|
||||
|
||||
@@ -142,7 +142,8 @@ enum dp_test_link_rate {
|
||||
DP_TEST_LINK_RATE_HBR3 = 0x1E,
|
||||
DP_TEST_LINK_RATE_UHBR10 = 0x01,
|
||||
DP_TEST_LINK_RATE_UHBR20 = 0x02,
|
||||
DP_TEST_LINK_RATE_UHBR13_5 = 0x03,
|
||||
DP_TEST_LINK_RATE_UHBR13_5_LEGACY = 0x03, /* For backward compatibility*/
|
||||
DP_TEST_LINK_RATE_UHBR13_5 = 0x04,
|
||||
};
|
||||
|
||||
struct dc_link_settings {
|
||||
|
||||
@@ -1037,7 +1037,9 @@ struct replay_config {
|
||||
bool replay_smu_opt_supported; // SMU optimization is supported
|
||||
unsigned int replay_enable_option; // Replay enablement option
|
||||
uint32_t debug_flags; // Replay debug flags
|
||||
bool replay_timing_sync_supported; // Replay desync is supported
|
||||
bool replay_timing_sync_supported; // Replay desync is supported
|
||||
bool force_disable_desync_error_check; // Replay desync is supported
|
||||
bool received_desync_error_hpd; //Replay Received Desync Error HPD.
|
||||
union replay_error_status replay_error_status; // Replay error status
|
||||
};
|
||||
|
||||
|
||||
@@ -128,21 +128,6 @@
|
||||
SRI(DC_ABM1_ACE_THRES_12, ABM, id), \
|
||||
NBIO_SR(BIOS_SCRATCH_2)
|
||||
|
||||
#define ABM_DCN32_REG_LIST(id)\
|
||||
SRI(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \
|
||||
SRI(DC_ABM1_LS_SAMPLE_RATE, ABM, id), \
|
||||
SRI(BL1_PWM_BL_UPDATE_SAMPLE_RATE, ABM, id), \
|
||||
SRI(DC_ABM1_HG_MISC_CTRL, ABM, id), \
|
||||
SRI(DC_ABM1_IPCSC_COEFF_SEL, ABM, id), \
|
||||
SRI(BL1_PWM_CURRENT_ABM_LEVEL, ABM, id), \
|
||||
SRI(BL1_PWM_TARGET_ABM_LEVEL, ABM, id), \
|
||||
SRI(BL1_PWM_USER_LEVEL, ABM, id), \
|
||||
SRI(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, ABM, id), \
|
||||
SRI(DC_ABM1_HGLS_REG_READ_PROGRESS, ABM, id), \
|
||||
SRI(DC_ABM1_ACE_OFFSET_SLOPE_0, ABM, id), \
|
||||
SRI(DC_ABM1_ACE_THRES_12, ABM, id), \
|
||||
NBIO_SR(BIOS_SCRATCH_2)
|
||||
|
||||
#define ABM_SF(reg_name, field_name, post_fix)\
|
||||
.field_name = reg_name ## __ ## field_name ## post_fix
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef __DC_TIMING_GENERATOR_DCN10_H__
|
||||
#define __DC_TIMING_GENERATOR_DCN10_H__
|
||||
|
||||
#include "timing_generator.h"
|
||||
#include "optc.h"
|
||||
|
||||
#define DCN10TG_FROM_TG(tg)\
|
||||
container_of(tg, struct optc, base)
|
||||
@@ -594,190 +594,6 @@ struct dcn_optc_mask {
|
||||
TG_REG_FIELD_LIST_DCN3_5(uint32_t)
|
||||
};
|
||||
|
||||
struct optc {
|
||||
struct timing_generator base;
|
||||
|
||||
const struct dcn_optc_registers *tg_regs;
|
||||
const struct dcn_optc_shift *tg_shift;
|
||||
const struct dcn_optc_mask *tg_mask;
|
||||
|
||||
int opp_count;
|
||||
|
||||
uint32_t max_h_total;
|
||||
uint32_t max_v_total;
|
||||
|
||||
uint32_t min_h_blank;
|
||||
|
||||
uint32_t min_h_sync_width;
|
||||
uint32_t min_v_sync_width;
|
||||
uint32_t min_v_blank;
|
||||
uint32_t min_v_blank_interlace;
|
||||
|
||||
int vstartup_start;
|
||||
int vupdate_offset;
|
||||
int vupdate_width;
|
||||
int vready_offset;
|
||||
struct dc_crtc_timing orginal_patched_timing;
|
||||
enum signal_type signal;
|
||||
};
|
||||
|
||||
void dcn10_timing_generator_init(struct optc *optc);
|
||||
|
||||
struct dcn_otg_state {
|
||||
uint32_t v_blank_start;
|
||||
uint32_t v_blank_end;
|
||||
uint32_t v_sync_a_pol;
|
||||
uint32_t v_total;
|
||||
uint32_t v_total_max;
|
||||
uint32_t v_total_min;
|
||||
uint32_t v_total_min_sel;
|
||||
uint32_t v_total_max_sel;
|
||||
uint32_t v_sync_a_start;
|
||||
uint32_t v_sync_a_end;
|
||||
uint32_t h_blank_start;
|
||||
uint32_t h_blank_end;
|
||||
uint32_t h_sync_a_start;
|
||||
uint32_t h_sync_a_end;
|
||||
uint32_t h_sync_a_pol;
|
||||
uint32_t h_total;
|
||||
uint32_t underflow_occurred_status;
|
||||
uint32_t otg_enabled;
|
||||
uint32_t blank_enabled;
|
||||
uint32_t vertical_interrupt1_en;
|
||||
uint32_t vertical_interrupt1_line;
|
||||
uint32_t vertical_interrupt2_en;
|
||||
uint32_t vertical_interrupt2_line;
|
||||
};
|
||||
|
||||
void optc1_read_otg_state(struct optc *optc1,
|
||||
struct dcn_otg_state *s);
|
||||
|
||||
bool optc1_get_hw_timing(struct timing_generator *tg,
|
||||
struct dc_crtc_timing *hw_crtc_timing);
|
||||
|
||||
bool optc1_validate_timing(
|
||||
struct timing_generator *optc,
|
||||
const struct dc_crtc_timing *timing);
|
||||
|
||||
void optc1_program_timing(
|
||||
struct timing_generator *optc,
|
||||
const struct dc_crtc_timing *dc_crtc_timing,
|
||||
int vready_offset,
|
||||
int vstartup_start,
|
||||
int vupdate_offset,
|
||||
int vupdate_width,
|
||||
const enum signal_type signal,
|
||||
bool use_vbios);
|
||||
|
||||
void optc1_setup_vertical_interrupt0(
|
||||
struct timing_generator *optc,
|
||||
uint32_t start_line,
|
||||
uint32_t end_line);
|
||||
void optc1_setup_vertical_interrupt1(
|
||||
struct timing_generator *optc,
|
||||
uint32_t start_line);
|
||||
void optc1_setup_vertical_interrupt2(
|
||||
struct timing_generator *optc,
|
||||
uint32_t start_line);
|
||||
|
||||
void optc1_program_global_sync(
|
||||
struct timing_generator *optc,
|
||||
int vready_offset,
|
||||
int vstartup_start,
|
||||
int vupdate_offset,
|
||||
int vupdate_width);
|
||||
|
||||
bool optc1_disable_crtc(struct timing_generator *optc);
|
||||
|
||||
bool optc1_is_counter_moving(struct timing_generator *optc);
|
||||
|
||||
void optc1_get_position(struct timing_generator *optc,
|
||||
struct crtc_position *position);
|
||||
|
||||
uint32_t optc1_get_vblank_counter(struct timing_generator *optc);
|
||||
|
||||
void optc1_get_crtc_scanoutpos(
|
||||
struct timing_generator *optc,
|
||||
uint32_t *v_blank_start,
|
||||
uint32_t *v_blank_end,
|
||||
uint32_t *h_position,
|
||||
uint32_t *v_position);
|
||||
|
||||
void optc1_set_early_control(
|
||||
struct timing_generator *optc,
|
||||
uint32_t early_cntl);
|
||||
|
||||
void optc1_wait_for_state(struct timing_generator *optc,
|
||||
enum crtc_state state);
|
||||
|
||||
void optc1_set_blank(struct timing_generator *optc,
|
||||
bool enable_blanking);
|
||||
|
||||
bool optc1_is_blanked(struct timing_generator *optc);
|
||||
|
||||
void optc1_program_blank_color(
|
||||
struct timing_generator *optc,
|
||||
const struct tg_color *black_color);
|
||||
|
||||
bool optc1_did_triggered_reset_occur(
|
||||
struct timing_generator *optc);
|
||||
|
||||
void optc1_enable_reset_trigger(struct timing_generator *optc, int source_tg_inst);
|
||||
|
||||
void optc1_disable_reset_trigger(struct timing_generator *optc);
|
||||
|
||||
void optc1_lock(struct timing_generator *optc);
|
||||
|
||||
void optc1_unlock(struct timing_generator *optc);
|
||||
|
||||
void optc1_enable_optc_clock(struct timing_generator *optc, bool enable);
|
||||
|
||||
void optc1_set_drr(
|
||||
struct timing_generator *optc,
|
||||
const struct drr_params *params);
|
||||
|
||||
void optc1_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, int vtotal_max);
|
||||
|
||||
void optc1_set_static_screen_control(
|
||||
struct timing_generator *optc,
|
||||
uint32_t event_triggers,
|
||||
uint32_t num_frames);
|
||||
|
||||
void optc1_program_stereo(struct timing_generator *optc,
|
||||
const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags);
|
||||
|
||||
bool optc1_is_stereo_left_eye(struct timing_generator *optc);
|
||||
|
||||
void optc1_clear_optc_underflow(struct timing_generator *optc);
|
||||
|
||||
void optc1_tg_init(struct timing_generator *optc);
|
||||
|
||||
bool optc1_is_tg_enabled(struct timing_generator *optc);
|
||||
|
||||
bool optc1_is_optc_underflow_occurred(struct timing_generator *optc);
|
||||
|
||||
void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable);
|
||||
|
||||
void optc1_set_timing_double_buffer(struct timing_generator *optc, bool enable);
|
||||
|
||||
bool optc1_get_otg_active_size(struct timing_generator *optc,
|
||||
uint32_t *otg_active_width,
|
||||
uint32_t *otg_active_height);
|
||||
|
||||
void optc1_enable_crtc_reset(
|
||||
struct timing_generator *optc,
|
||||
int source_tg_inst,
|
||||
struct crtc_trigger_info *crtc_tp);
|
||||
|
||||
bool optc1_configure_crc(struct timing_generator *optc,
|
||||
const struct crc_params *params);
|
||||
|
||||
bool optc1_get_crc(struct timing_generator *optc,
|
||||
uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb);
|
||||
|
||||
bool optc1_is_two_pixels_per_containter(const struct dc_crtc_timing *timing);
|
||||
|
||||
void optc1_set_vtg_params(struct timing_generator *optc,
|
||||
const struct dc_crtc_timing *dc_crtc_timing, bool program_fp2);
|
||||
|
||||
#endif /* __DC_TIMING_GENERATOR_DCN10_H__ */
|
||||
|
||||
@@ -137,7 +137,15 @@ void dsc2_get_enc_caps(struct dsc_enc_caps *dsc_enc_caps, int pixel_clock_100Hz)
|
||||
dsc_enc_caps->max_total_throughput_mps = DCN20_MAX_DISPLAY_CLOCK_Mhz * 2;
|
||||
}
|
||||
|
||||
// TODO DSC: This is actually image width limitation, not a slice width. This should be added to the criteria to use ODM.
|
||||
/* For pixel clock bigger than a single-pipe limit needing four engines ODM 4:1, which then quardruples our
|
||||
* throughput and number of slices
|
||||
*/
|
||||
if (pixel_clock_100Hz > DCN20_MAX_PIXEL_CLOCK_Mhz*10000*2) {
|
||||
dsc_enc_caps->slice_caps.bits.NUM_SLICES_12 = 1;
|
||||
dsc_enc_caps->slice_caps.bits.NUM_SLICES_16 = 1;
|
||||
dsc_enc_caps->max_total_throughput_mps = DCN20_MAX_DISPLAY_CLOCK_Mhz * 4;
|
||||
}
|
||||
|
||||
dsc_enc_caps->max_slice_width = 5184; /* (including 64 overlap pixels for eDP MSO mode) */
|
||||
dsc_enc_caps->bpp_increment_div = 16; /* 1/16th of a bit */
|
||||
}
|
||||
|
||||
@@ -325,6 +325,43 @@ static void dccg35_set_dpstreamclk(
|
||||
}
|
||||
}
|
||||
|
||||
static void dccg35_set_physymclk_root_clock_gating(
|
||||
struct dccg *dccg,
|
||||
int phy_inst,
|
||||
bool enable)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
return;
|
||||
|
||||
switch (phy_inst) {
|
||||
case 0:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
|
||||
break;
|
||||
case 3:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
|
||||
break;
|
||||
case 4:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void dccg35_set_physymclk(
|
||||
struct dccg *dccg,
|
||||
int phy_inst,
|
||||
@@ -340,16 +377,10 @@ static void dccg35_set_physymclk(
|
||||
REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
|
||||
PHYASYMCLK_EN, 1,
|
||||
PHYASYMCLK_SRC_SEL, clk_src);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYASYMCLK_ROOT_GATE_DISABLE, 1);
|
||||
} else {
|
||||
REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
|
||||
PHYASYMCLK_EN, 0,
|
||||
PHYASYMCLK_SRC_SEL, 0);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYASYMCLK_ROOT_GATE_DISABLE, 0);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
@@ -357,16 +388,10 @@ static void dccg35_set_physymclk(
|
||||
REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
|
||||
PHYBSYMCLK_EN, 1,
|
||||
PHYBSYMCLK_SRC_SEL, clk_src);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYBSYMCLK_ROOT_GATE_DISABLE, 1);
|
||||
} else {
|
||||
REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
|
||||
PHYBSYMCLK_EN, 0,
|
||||
PHYBSYMCLK_SRC_SEL, 0);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYBSYMCLK_ROOT_GATE_DISABLE, 0);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
@@ -374,16 +399,10 @@ static void dccg35_set_physymclk(
|
||||
REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
|
||||
PHYCSYMCLK_EN, 1,
|
||||
PHYCSYMCLK_SRC_SEL, clk_src);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYCSYMCLK_ROOT_GATE_DISABLE, 1);
|
||||
} else {
|
||||
REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
|
||||
PHYCSYMCLK_EN, 0,
|
||||
PHYCSYMCLK_SRC_SEL, 0);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYCSYMCLK_ROOT_GATE_DISABLE, 0);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
@@ -391,16 +410,10 @@ static void dccg35_set_physymclk(
|
||||
REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
|
||||
PHYDSYMCLK_EN, 1,
|
||||
PHYDSYMCLK_SRC_SEL, clk_src);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYDSYMCLK_ROOT_GATE_DISABLE, 1);
|
||||
} else {
|
||||
REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
|
||||
PHYDSYMCLK_EN, 0,
|
||||
PHYDSYMCLK_SRC_SEL, 0);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYDSYMCLK_ROOT_GATE_DISABLE, 0);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
@@ -408,16 +421,10 @@ static void dccg35_set_physymclk(
|
||||
REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
|
||||
PHYESYMCLK_EN, 1,
|
||||
PHYESYMCLK_SRC_SEL, clk_src);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYESYMCLK_ROOT_GATE_DISABLE, 1);
|
||||
} else {
|
||||
REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
|
||||
PHYESYMCLK_EN, 0,
|
||||
PHYESYMCLK_SRC_SEL, 0);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
PHYESYMCLK_ROOT_GATE_DISABLE, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -490,8 +497,8 @@ void dccg35_init(struct dccg *dccg)
|
||||
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
for (otg_inst = 0; otg_inst < 5; otg_inst++)
|
||||
dccg35_set_physymclk(dccg, otg_inst,
|
||||
PHYSYMCLK_FORCE_SRC_SYMCLK, false);
|
||||
dccg35_set_physymclk_root_clock_gating(dccg, otg_inst,
|
||||
false);
|
||||
/*
|
||||
dccg35_enable_global_fgcg_rep(
|
||||
dccg, dccg->ctx->dc->debug.enable_fine_grain_clock_gating.bits
|
||||
@@ -754,7 +761,9 @@ static const struct dccg_funcs dccg35_funcs = {
|
||||
.disable_symclk32_se = dccg31_disable_symclk32_se,
|
||||
.enable_symclk32_le = dccg31_enable_symclk32_le,
|
||||
.disable_symclk32_le = dccg31_disable_symclk32_le,
|
||||
.set_symclk32_le_root_clock_gating = dccg31_set_symclk32_le_root_clock_gating,
|
||||
.set_physymclk = dccg35_set_physymclk,
|
||||
.set_physymclk_root_clock_gating = dccg35_set_physymclk_root_clock_gating,
|
||||
.set_dtbclk_dto = dccg35_set_dtbclk_dto,
|
||||
.set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
|
||||
.set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user