mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
Merge remote-tracking branch 'stable/linux-6.6.y' into rpi-6.6.y
This commit is contained in:
@@ -565,7 +565,8 @@ Description: Control Symmetric Multi Threading (SMT)
|
||||
================ =========================================
|
||||
|
||||
If control status is "forceoff" or "notsupported" writes
|
||||
are rejected.
|
||||
are rejected. Note that enabling SMT on PowerPC skips
|
||||
offline cores.
|
||||
|
||||
What: /sys/devices/system/cpu/cpuX/power/energy_perf_bias
|
||||
Date: March 2019
|
||||
|
||||
@@ -85,6 +85,17 @@ is already free).
|
||||
|
||||
Should be called from a process context (might sleep).
|
||||
|
||||
::
|
||||
|
||||
int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id);
|
||||
|
||||
After verifying the owner of the hwspinlock, release a previously acquired
|
||||
hwspinlock; returns 0 on success, or an appropriate error code on failure
|
||||
(e.g. -EOPNOTSUPP if the bust operation is not defined for the specific
|
||||
hwspinlock).
|
||||
|
||||
Should be called from a process context (might sleep).
|
||||
|
||||
::
|
||||
|
||||
int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout);
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 47
|
||||
SUBLEVEL = 50
|
||||
EXTRAVERSION =
|
||||
NAME = Hurr durr I'ma ninja sloth
|
||||
|
||||
|
||||
@@ -274,24 +274,24 @@
|
||||
|
||||
led@0 {
|
||||
chan-name = "R";
|
||||
led-cur = /bits/ 8 <0x20>;
|
||||
max-cur = /bits/ 8 <0x60>;
|
||||
led-cur = /bits/ 8 <0x6e>;
|
||||
max-cur = /bits/ 8 <0xc8>;
|
||||
reg = <0>;
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
};
|
||||
|
||||
led@1 {
|
||||
chan-name = "G";
|
||||
led-cur = /bits/ 8 <0x20>;
|
||||
max-cur = /bits/ 8 <0x60>;
|
||||
led-cur = /bits/ 8 <0xbe>;
|
||||
max-cur = /bits/ 8 <0xc8>;
|
||||
reg = <1>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
};
|
||||
|
||||
led@2 {
|
||||
chan-name = "B";
|
||||
led-cur = /bits/ 8 <0x20>;
|
||||
max-cur = /bits/ 8 <0x60>;
|
||||
led-cur = /bits/ 8 <0xbe>;
|
||||
max-cur = /bits/ 8 <0xc8>;
|
||||
reg = <2>;
|
||||
color = <LED_COLOR_ID_BLUE>;
|
||||
};
|
||||
|
||||
@@ -781,7 +781,7 @@
|
||||
|
||||
mount-matrix = "-1", "0", "0",
|
||||
"0", "1", "0",
|
||||
"0", "0", "1";
|
||||
"0", "0", "-1";
|
||||
};
|
||||
|
||||
cam1: camera@3e {
|
||||
|
||||
@@ -163,13 +163,12 @@
|
||||
|
||||
simple-audio-card,cpu {
|
||||
sound-dai = <&sai3>;
|
||||
frame-master;
|
||||
bitclock-master;
|
||||
};
|
||||
|
||||
simple-audio-card,codec {
|
||||
sound-dai = <&wm8962>;
|
||||
clocks = <&clk IMX8MP_CLK_IPP_DO_CLKO1>;
|
||||
frame-master;
|
||||
bitclock-master;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -381,10 +380,9 @@
|
||||
&sai3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_sai3>;
|
||||
assigned-clocks = <&clk IMX8MP_CLK_SAI3>,
|
||||
<&clk IMX8MP_AUDIO_PLL2> ;
|
||||
assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>;
|
||||
assigned-clock-rates = <12288000>, <361267200>;
|
||||
assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
|
||||
assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
|
||||
assigned-clock-rates = <12288000>;
|
||||
fsl,sai-mclk-direction-output;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -437,7 +437,7 @@
|
||||
pinctrl-0 = <&pinctrl_usdhc2_hs>, <&pinctrl_usdhc2_gpio>;
|
||||
pinctrl-1 = <&pinctrl_usdhc2_uhs>, <&pinctrl_usdhc2_gpio>;
|
||||
pinctrl-2 = <&pinctrl_usdhc2_uhs>, <&pinctrl_usdhc2_gpio>;
|
||||
cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>;
|
||||
cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <®_usdhc2_vmmc>;
|
||||
bus-width = <4>;
|
||||
no-sdio;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
linux,cma {
|
||||
compatible = "shared-dma-pool";
|
||||
reusable;
|
||||
alloc-ranges = <0 0x60000000 0 0x40000000>;
|
||||
alloc-ranges = <0 0x80000000 0 0x40000000>;
|
||||
size = <0 0x10000000>;
|
||||
linux,cma-default;
|
||||
};
|
||||
|
||||
@@ -786,6 +786,8 @@
|
||||
fsl,num-tx-queues = <3>;
|
||||
fsl,num-rx-queues = <3>;
|
||||
fsl,stop-mode = <&wakeupmix_gpr 0x0c 1>;
|
||||
nvmem-cells = <ð_mac1>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -807,7 +809,9 @@
|
||||
<&clk IMX93_CLK_SYS_PLL_PFD0_DIV2>;
|
||||
assigned-clock-rates = <100000000>, <250000000>;
|
||||
intf_mode = <&wakeupmix_gpr 0x28>;
|
||||
snps,clk-csr = <0>;
|
||||
snps,clk-csr = <6>;
|
||||
nvmem-cells = <ð_mac2>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -888,6 +892,15 @@
|
||||
reg = <0x47510000 0x10000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
eth_mac1: mac-address@4ec {
|
||||
reg = <0x4ec 0x6>;
|
||||
};
|
||||
|
||||
eth_mac2: mac-address@4f2 {
|
||||
reg = <0x4f2 0x6>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
s4muap: mailbox@47520000 {
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <asm/numa.h>
|
||||
|
||||
static int acpi_early_node_map[NR_CPUS] __initdata = { NUMA_NO_NODE };
|
||||
static int acpi_early_node_map[NR_CPUS] __initdata = { [0 ... NR_CPUS - 1] = NUMA_NO_NODE };
|
||||
|
||||
int __init acpi_numa_get_nid(unsigned int cpu)
|
||||
{
|
||||
|
||||
@@ -371,9 +371,6 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
|
||||
smp_init_cpus();
|
||||
smp_build_mpidr_hash();
|
||||
|
||||
/* Init percpu seeds for random tags after cpus are set up. */
|
||||
kasan_init_sw_tags();
|
||||
|
||||
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
|
||||
/*
|
||||
* Make sure init_thread_info.ttbr0 always generates translation
|
||||
|
||||
@@ -459,6 +459,8 @@ void __init smp_prepare_boot_cpu(void)
|
||||
init_gic_priority_masking();
|
||||
|
||||
kasan_init_hw_tags();
|
||||
/* Init percpu seeds for random tags after cpus are set up. */
|
||||
kasan_init_sw_tags();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <trace/events/kvm.h>
|
||||
|
||||
#include "sys_regs.h"
|
||||
#include "vgic/vgic.h"
|
||||
|
||||
#include "trace.h"
|
||||
|
||||
@@ -301,6 +302,11 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
|
||||
{
|
||||
bool g1;
|
||||
|
||||
if (!kvm_has_gicv3(vcpu->kvm)) {
|
||||
kvm_inject_undefined(vcpu);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!p->is_write)
|
||||
return read_from_write_only(vcpu, p, r);
|
||||
|
||||
|
||||
@@ -343,4 +343,11 @@ void vgic_v4_configure_vsgis(struct kvm *kvm);
|
||||
void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val);
|
||||
int vgic_v4_request_vpe_irq(struct kvm_vcpu *vcpu, int irq);
|
||||
|
||||
static inline bool kvm_has_gicv3(struct kvm *kvm)
|
||||
{
|
||||
return (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) &&
|
||||
irqchip_in_kernel(kvm) &&
|
||||
kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#ifndef _LOONGARCH_DMA_DIRECT_H
|
||||
#define _LOONGARCH_DMA_DIRECT_H
|
||||
|
||||
dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
|
||||
phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
|
||||
|
||||
#endif /* _LOONGARCH_DMA_DIRECT_H */
|
||||
@@ -1725,12 +1725,16 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
|
||||
MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2);
|
||||
c->ases &= ~MIPS_ASE_VZ; /* VZ of Loongson-3A2000/3000 is incomplete */
|
||||
change_c0_config6(LOONGSON_CONF6_EXTIMER | LOONGSON_CONF6_INTIMER,
|
||||
LOONGSON_CONF6_INTIMER);
|
||||
break;
|
||||
case PRID_IMP_LOONGSON_64G:
|
||||
__cpu_name[cpu] = "ICT Loongson-3";
|
||||
set_elf_platform(cpu, "loongson3a");
|
||||
set_isa(c, MIPS_CPU_ISA_M64R2);
|
||||
decode_cpucfg(c);
|
||||
change_c0_config6(LOONGSON_CONF6_EXTIMER | LOONGSON_CONF6_INTIMER,
|
||||
LOONGSON_CONF6_INTIMER);
|
||||
break;
|
||||
default:
|
||||
panic("Unknown Loongson Processor ID!");
|
||||
|
||||
@@ -255,6 +255,9 @@ void calibrate_delay(void)
|
||||
|
||||
void __init setup_arch(char **cmdline_p)
|
||||
{
|
||||
/* setup memblock allocator */
|
||||
setup_memory();
|
||||
|
||||
unflatten_and_copy_device_tree();
|
||||
|
||||
setup_cpuinfo();
|
||||
@@ -278,9 +281,6 @@ void __init setup_arch(char **cmdline_p)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* setup memblock allocator */
|
||||
setup_memory();
|
||||
|
||||
/* paging_init() sets up the MMU and marks all pages as reserved */
|
||||
paging_init();
|
||||
|
||||
|
||||
@@ -498,7 +498,7 @@ asmlinkage void do_cpu_irq_mask(struct pt_regs *regs)
|
||||
|
||||
old_regs = set_irq_regs(regs);
|
||||
local_irq_disable();
|
||||
irq_enter();
|
||||
irq_enter_rcu();
|
||||
|
||||
eirr_val = mfctl(23) & cpu_eiem & per_cpu(local_ack_eiem, cpu);
|
||||
if (!eirr_val)
|
||||
@@ -533,7 +533,7 @@ asmlinkage void do_cpu_irq_mask(struct pt_regs *regs)
|
||||
#endif /* CONFIG_IRQSTACKS */
|
||||
|
||||
out:
|
||||
irq_exit();
|
||||
irq_exit_rcu();
|
||||
set_irq_regs(old_regs);
|
||||
return;
|
||||
|
||||
|
||||
@@ -112,8 +112,11 @@ static void *simple_realloc(void *ptr, unsigned long size)
|
||||
return ptr;
|
||||
|
||||
new = simple_malloc(size);
|
||||
memcpy(new, ptr, p->size);
|
||||
simple_free(ptr);
|
||||
if (new) {
|
||||
memcpy(new, ptr, p->size);
|
||||
simple_free(ptr);
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@ static inline int cpu_to_coregroup_id(int cpu)
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_SMT
|
||||
#include <linux/cpu_smt.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <asm/cputhreads.h>
|
||||
|
||||
static inline bool topology_is_primary_thread(unsigned int cpu)
|
||||
@@ -156,6 +157,18 @@ static inline bool topology_smt_thread_allowed(unsigned int cpu)
|
||||
{
|
||||
return cpu_thread_in_core(cpu) < cpu_smt_num_threads;
|
||||
}
|
||||
|
||||
#define topology_is_core_online topology_is_core_online
|
||||
static inline bool topology_is_core_online(unsigned int cpu)
|
||||
{
|
||||
int i, first_cpu = cpu_first_thread_sibling(cpu);
|
||||
|
||||
for (i = first_cpu; i < first_cpu + threads_per_core; ++i) {
|
||||
if (cpu_online(i))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
@@ -23,6 +23,46 @@ void papr_sysparm_buf_free(struct papr_sysparm_buf *buf)
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
static size_t papr_sysparm_buf_get_length(const struct papr_sysparm_buf *buf)
|
||||
{
|
||||
return be16_to_cpu(buf->len);
|
||||
}
|
||||
|
||||
static void papr_sysparm_buf_set_length(struct papr_sysparm_buf *buf, size_t length)
|
||||
{
|
||||
WARN_ONCE(length > sizeof(buf->val),
|
||||
"bogus length %zu, clamping to safe value", length);
|
||||
length = min(sizeof(buf->val), length);
|
||||
buf->len = cpu_to_be16(length);
|
||||
}
|
||||
|
||||
/*
|
||||
* For use on buffers returned from ibm,get-system-parameter before
|
||||
* returning them to callers. Ensures the encoded length of valid data
|
||||
* cannot overrun buf->val[].
|
||||
*/
|
||||
static void papr_sysparm_buf_clamp_length(struct papr_sysparm_buf *buf)
|
||||
{
|
||||
papr_sysparm_buf_set_length(buf, papr_sysparm_buf_get_length(buf));
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform some basic diligence on the system parameter buffer before
|
||||
* submitting it to RTAS.
|
||||
*/
|
||||
static bool papr_sysparm_buf_can_submit(const struct papr_sysparm_buf *buf)
|
||||
{
|
||||
/*
|
||||
* Firmware ought to reject buffer lengths that exceed the
|
||||
* maximum specified in PAPR, but there's no reason for the
|
||||
* kernel to allow them either.
|
||||
*/
|
||||
if (papr_sysparm_buf_get_length(buf) > sizeof(buf->val))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* papr_sysparm_get() - Retrieve the value of a PAPR system parameter.
|
||||
* @param: PAPR system parameter token as described in
|
||||
@@ -63,6 +103,9 @@ int papr_sysparm_get(papr_sysparm_t param, struct papr_sysparm_buf *buf)
|
||||
if (token == RTAS_UNKNOWN_SERVICE)
|
||||
return -ENOENT;
|
||||
|
||||
if (!papr_sysparm_buf_can_submit(buf))
|
||||
return -EINVAL;
|
||||
|
||||
work_area = rtas_work_area_alloc(sizeof(*buf));
|
||||
|
||||
memcpy(rtas_work_area_raw_buf(work_area), buf, sizeof(*buf));
|
||||
@@ -77,6 +120,7 @@ int papr_sysparm_get(papr_sysparm_t param, struct papr_sysparm_buf *buf)
|
||||
case 0:
|
||||
ret = 0;
|
||||
memcpy(buf, rtas_work_area_raw_buf(work_area), sizeof(*buf));
|
||||
papr_sysparm_buf_clamp_length(buf);
|
||||
break;
|
||||
case -3: /* parameter not implemented */
|
||||
ret = -EOPNOTSUPP;
|
||||
@@ -115,6 +159,9 @@ int papr_sysparm_set(papr_sysparm_t param, const struct papr_sysparm_buf *buf)
|
||||
if (token == RTAS_UNKNOWN_SERVICE)
|
||||
return -ENOENT;
|
||||
|
||||
if (!papr_sysparm_buf_can_submit(buf))
|
||||
return -EINVAL;
|
||||
|
||||
work_area = rtas_work_area_alloc(sizeof(*buf));
|
||||
|
||||
memcpy(rtas_work_area_raw_buf(work_area), buf, sizeof(*buf));
|
||||
|
||||
@@ -236,6 +236,8 @@ static int __init icp_native_map_one_cpu(int hw_id, unsigned long addr,
|
||||
rname = kasprintf(GFP_KERNEL, "CPU %d [0x%x] Interrupt Presentation",
|
||||
cpu, hw_id);
|
||||
|
||||
if (!rname)
|
||||
return -ENOMEM;
|
||||
if (!request_mem_region(addr, size, rname)) {
|
||||
pr_warn("icp_native: Could not reserve ICP MMIO for CPU %d, interrupt server #0x%x\n",
|
||||
cpu, hw_id);
|
||||
|
||||
@@ -164,6 +164,16 @@
|
||||
REG_L x31, PT_T6(sp)
|
||||
.endm
|
||||
|
||||
/* Annotate a function as being unsuitable for kprobes. */
|
||||
#ifdef CONFIG_KPROBES
|
||||
#define ASM_NOKPROBE(name) \
|
||||
.pushsection "_kprobe_blacklist", "aw"; \
|
||||
RISCV_PTR name; \
|
||||
.popsection
|
||||
#else
|
||||
#define ASM_NOKPROBE(name)
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_RISCV_ASM_H */
|
||||
|
||||
@@ -105,6 +105,7 @@ _save_context:
|
||||
1:
|
||||
tail do_trap_unknown
|
||||
SYM_CODE_END(handle_exception)
|
||||
ASM_NOKPROBE(handle_exception)
|
||||
|
||||
/*
|
||||
* The ret_from_exception must be called with interrupt disabled. Here is the
|
||||
@@ -171,6 +172,7 @@ SYM_CODE_START_NOALIGN(ret_from_exception)
|
||||
sret
|
||||
#endif
|
||||
SYM_CODE_END(ret_from_exception)
|
||||
ASM_NOKPROBE(ret_from_exception)
|
||||
|
||||
#ifdef CONFIG_VMAP_STACK
|
||||
SYM_CODE_START_LOCAL(handle_kernel_stack_overflow)
|
||||
@@ -206,6 +208,7 @@ SYM_CODE_START_LOCAL(handle_kernel_stack_overflow)
|
||||
move a0, sp
|
||||
tail handle_bad_stack
|
||||
SYM_CODE_END(handle_kernel_stack_overflow)
|
||||
ASM_NOKPROBE(handle_kernel_stack_overflow)
|
||||
#endif
|
||||
|
||||
SYM_CODE_START(ret_from_fork)
|
||||
|
||||
@@ -311,6 +311,7 @@ asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs)
|
||||
|
||||
regs->epc += 4;
|
||||
regs->orig_a0 = regs->a0;
|
||||
regs->a0 = -ENOSYS;
|
||||
|
||||
riscv_v_vstate_discard(regs);
|
||||
|
||||
@@ -318,8 +319,6 @@ asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs)
|
||||
|
||||
if (syscall >= 0 && syscall < NR_syscalls)
|
||||
syscall_handler(regs, syscall);
|
||||
else if (syscall != -1)
|
||||
regs->a0 = -ENOSYS;
|
||||
|
||||
syscall_exit_to_user_mode(regs);
|
||||
} else {
|
||||
|
||||
@@ -912,7 +912,7 @@ static void __init create_kernel_page_table(pgd_t *pgdir,
|
||||
PMD_SIZE, PAGE_KERNEL_EXEC);
|
||||
|
||||
/* Map the data in RAM */
|
||||
end_va = kernel_map.virt_addr + XIP_OFFSET + kernel_map.size;
|
||||
end_va = kernel_map.virt_addr + kernel_map.size;
|
||||
for (va = kernel_map.virt_addr + XIP_OFFSET; va < end_va; va += PMD_SIZE)
|
||||
create_pgd_mapping(pgdir, va,
|
||||
kernel_map.phys_addr + (va - (kernel_map.virt_addr + XIP_OFFSET)),
|
||||
@@ -1081,7 +1081,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
|
||||
|
||||
phys_ram_base = CONFIG_PHYS_RAM_BASE;
|
||||
kernel_map.phys_addr = (uintptr_t)CONFIG_PHYS_RAM_BASE;
|
||||
kernel_map.size = (uintptr_t)(&_end) - (uintptr_t)(&_sdata);
|
||||
kernel_map.size = (uintptr_t)(&_end) - (uintptr_t)(&_start);
|
||||
|
||||
kernel_map.va_kernel_xip_pa_offset = kernel_map.virt_addr - kernel_map.xiprom;
|
||||
#else
|
||||
|
||||
@@ -442,7 +442,10 @@ static inline int share(unsigned long addr, u16 cmd)
|
||||
|
||||
if (!uv_call(0, (u64)&uvcb))
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
pr_err("%s UVC failed (rc: 0x%x, rrc: 0x%x), possible hypervisor bug.\n",
|
||||
uvcb.header.cmd == UVC_CMD_SET_SHARED_ACCESS ? "Share" : "Unshare",
|
||||
uvcb.header.rc, uvcb.header.rrc);
|
||||
panic("System security cannot be guaranteed unless the system panics now.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -258,15 +258,9 @@ static inline void save_vector_registers(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void setup_control_registers(void)
|
||||
static inline void setup_low_address_protection(void)
|
||||
{
|
||||
unsigned long reg;
|
||||
|
||||
__ctl_store(reg, 0, 0);
|
||||
reg |= CR0_LOW_ADDRESS_PROTECTION;
|
||||
reg |= CR0_EMERGENCY_SIGNAL_SUBMASK;
|
||||
reg |= CR0_EXTERNAL_CALL_SUBMASK;
|
||||
__ctl_load(reg, 0, 0);
|
||||
__ctl_set_bit(0, 28);
|
||||
}
|
||||
|
||||
static inline void setup_access_registers(void)
|
||||
@@ -314,7 +308,7 @@ void __init startup_init(void)
|
||||
save_vector_registers();
|
||||
setup_topology();
|
||||
sclp_early_detect();
|
||||
setup_control_registers();
|
||||
setup_low_address_protection();
|
||||
setup_access_registers();
|
||||
lockdep_on();
|
||||
}
|
||||
|
||||
@@ -1013,12 +1013,12 @@ void __init smp_fill_possible_mask(void)
|
||||
|
||||
void __init smp_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
/* request the 0x1201 emergency signal external interrupt */
|
||||
if (register_external_irq(EXT_IRQ_EMERGENCY_SIG, do_ext_call_interrupt))
|
||||
panic("Couldn't request external interrupt 0x1201");
|
||||
/* request the 0x1202 external call external interrupt */
|
||||
ctl_set_bit(0, 14);
|
||||
if (register_external_irq(EXT_IRQ_EXTERNAL_CALL, do_ext_call_interrupt))
|
||||
panic("Couldn't request external interrupt 0x1202");
|
||||
ctl_set_bit(0, 13);
|
||||
}
|
||||
|
||||
void __init smp_prepare_boot_cpu(void)
|
||||
|
||||
@@ -249,7 +249,12 @@ static inline unsigned long kvm_s390_get_gfn_end(struct kvm_memslots *slots)
|
||||
|
||||
static inline u32 kvm_s390_get_gisa_desc(struct kvm *kvm)
|
||||
{
|
||||
u32 gd = virt_to_phys(kvm->arch.gisa_int.origin);
|
||||
u32 gd;
|
||||
|
||||
if (!kvm->arch.gisa_int.origin)
|
||||
return 0;
|
||||
|
||||
gd = virt_to_phys(kvm->arch.gisa_int.origin);
|
||||
|
||||
if (gd && sclp.has_gisaf)
|
||||
gd |= GISA_FORMAT1;
|
||||
|
||||
@@ -1030,7 +1030,10 @@ unsigned long arch_align_stack(unsigned long sp)
|
||||
|
||||
unsigned long arch_randomize_brk(struct mm_struct *mm)
|
||||
{
|
||||
return randomize_page(mm->brk, 0x02000000);
|
||||
if (mmap_is_ia32())
|
||||
return randomize_page(mm->brk, SZ_32M);
|
||||
|
||||
return randomize_page(mm->brk, SZ_1G);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -396,8 +396,6 @@ void blk_integrity_unregister(struct gendisk *disk)
|
||||
if (!bi->profile)
|
||||
return;
|
||||
|
||||
/* ensure all bios are off the integrity workqueue */
|
||||
blk_flush_integrity();
|
||||
blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue);
|
||||
memset(bi, 0, sizeof(*bi));
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ static void blk_mq_update_wake_batch(struct blk_mq_tags *tags,
|
||||
void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx)
|
||||
{
|
||||
unsigned int users;
|
||||
unsigned long flags;
|
||||
struct blk_mq_tags *tags = hctx->tags;
|
||||
|
||||
/*
|
||||
@@ -56,11 +57,11 @@ void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx)
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irq(&tags->lock);
|
||||
spin_lock_irqsave(&tags->lock, flags);
|
||||
users = tags->active_queues + 1;
|
||||
WRITE_ONCE(tags->active_queues, users);
|
||||
blk_mq_update_wake_batch(tags, users);
|
||||
spin_unlock_irq(&tags->lock);
|
||||
spin_unlock_irqrestore(&tags->lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1645,19 +1645,19 @@ static void add_files_to_device(struct hl_device *hdev, struct hl_dbg_device_ent
|
||||
&hl_data64b_fops);
|
||||
|
||||
debugfs_create_file("set_power_state",
|
||||
0200,
|
||||
0644,
|
||||
root,
|
||||
dev_entry,
|
||||
&hl_power_fops);
|
||||
|
||||
debugfs_create_file("device",
|
||||
0200,
|
||||
0644,
|
||||
root,
|
||||
dev_entry,
|
||||
&hl_device_fops);
|
||||
|
||||
debugfs_create_file("clk_gate",
|
||||
0200,
|
||||
0644,
|
||||
root,
|
||||
dev_entry,
|
||||
&hl_clk_gate_fops);
|
||||
@@ -1669,13 +1669,13 @@ static void add_files_to_device(struct hl_device *hdev, struct hl_dbg_device_ent
|
||||
&hl_stop_on_err_fops);
|
||||
|
||||
debugfs_create_file("dump_security_violations",
|
||||
0644,
|
||||
0400,
|
||||
root,
|
||||
dev_entry,
|
||||
&hl_security_violations_fops);
|
||||
|
||||
debugfs_create_file("dump_razwi_events",
|
||||
0644,
|
||||
0400,
|
||||
root,
|
||||
dev_entry,
|
||||
&hl_razwi_check_fops);
|
||||
@@ -1708,7 +1708,7 @@ static void add_files_to_device(struct hl_device *hdev, struct hl_dbg_device_ent
|
||||
&hdev->reset_info.skip_reset_on_timeout);
|
||||
|
||||
debugfs_create_file("state_dump",
|
||||
0600,
|
||||
0644,
|
||||
root,
|
||||
dev_entry,
|
||||
&hl_state_dump_fops);
|
||||
@@ -1726,7 +1726,7 @@ static void add_files_to_device(struct hl_device *hdev, struct hl_dbg_device_ent
|
||||
|
||||
for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) {
|
||||
debugfs_create_file(hl_debugfs_list[i].name,
|
||||
0444,
|
||||
0644,
|
||||
root,
|
||||
entry,
|
||||
&hl_debugfs_fops);
|
||||
|
||||
@@ -271,6 +271,9 @@ static int handle_registration_node(struct hl_device *hdev, struct hl_user_pendi
|
||||
free_node->cq_cb = pend->ts_reg_info.cq_cb;
|
||||
list_add(&free_node->free_objects_node, *free_list);
|
||||
|
||||
/* Mark TS record as free */
|
||||
pend->ts_reg_info.in_use = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1878,16 +1878,16 @@ err_dma_buf_put:
|
||||
|
||||
static int validate_export_params_common(struct hl_device *hdev, u64 device_addr, u64 size)
|
||||
{
|
||||
if (!IS_ALIGNED(device_addr, PAGE_SIZE)) {
|
||||
if (!PAGE_ALIGNED(device_addr)) {
|
||||
dev_dbg(hdev->dev,
|
||||
"exported device memory address 0x%llx should be aligned to 0x%lx\n",
|
||||
"exported device memory address 0x%llx should be aligned to PAGE_SIZE 0x%lx\n",
|
||||
device_addr, PAGE_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (size < PAGE_SIZE) {
|
||||
if (!size || !PAGE_ALIGNED(size)) {
|
||||
dev_dbg(hdev->dev,
|
||||
"exported device memory size %llu should be equal to or greater than %lu\n",
|
||||
"exported device memory size %llu should be a multiple of PAGE_SIZE %lu\n",
|
||||
size, PAGE_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1938,6 +1938,13 @@ static int validate_export_params(struct hl_device *hdev, u64 device_addr, u64 s
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (!PAGE_ALIGNED(offset)) {
|
||||
dev_dbg(hdev->dev,
|
||||
"exported device memory offset %llu should be a multiple of PAGE_SIZE %lu\n",
|
||||
offset, PAGE_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((offset + size) > phys_pg_pack->total_size) {
|
||||
dev_dbg(hdev->dev, "offset %#llx and size %#llx exceed total map size %#llx\n",
|
||||
offset, size, phys_pg_pack->total_size);
|
||||
|
||||
@@ -1601,6 +1601,7 @@ static const u32 gaudi2_pb_dcr0_tpc0_unsecured_regs[] = {
|
||||
mmDCORE0_TPC0_CFG_KERNEL_SRF_30,
|
||||
mmDCORE0_TPC0_CFG_KERNEL_SRF_31,
|
||||
mmDCORE0_TPC0_CFG_TPC_SB_L0CD,
|
||||
mmDCORE0_TPC0_CFG_TPC_COUNT,
|
||||
mmDCORE0_TPC0_CFG_TPC_ID,
|
||||
mmDCORE0_TPC0_CFG_QM_KERNEL_ID_INC,
|
||||
mmDCORE0_TPC0_CFG_QM_TID_BASE_SIZE_HIGH_DIM_0,
|
||||
|
||||
@@ -188,13 +188,9 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj,
|
||||
u8 acpi_ns_is_locked);
|
||||
|
||||
void
|
||||
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
|
||||
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, u32 max_depth,
|
||||
acpi_adr_space_type space_id, u32 function);
|
||||
|
||||
void
|
||||
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *node,
|
||||
acpi_adr_space_type space_id);
|
||||
|
||||
acpi_status
|
||||
acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function);
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ extern u8 acpi_gbl_default_address_spaces[];
|
||||
|
||||
/* Local prototypes */
|
||||
|
||||
static void
|
||||
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node,
|
||||
acpi_adr_space_type space_id);
|
||||
|
||||
static acpi_status
|
||||
acpi_ev_reg_run(acpi_handle obj_handle,
|
||||
u32 level, void *context, void **return_value);
|
||||
@@ -61,6 +65,7 @@ acpi_status acpi_ev_initialize_op_regions(void)
|
||||
acpi_gbl_default_address_spaces
|
||||
[i])) {
|
||||
acpi_ev_execute_reg_methods(acpi_gbl_root_node,
|
||||
ACPI_UINT32_MAX,
|
||||
acpi_gbl_default_address_spaces
|
||||
[i], ACPI_REG_CONNECT);
|
||||
}
|
||||
@@ -668,6 +673,7 @@ cleanup1:
|
||||
* FUNCTION: acpi_ev_execute_reg_methods
|
||||
*
|
||||
* PARAMETERS: node - Namespace node for the device
|
||||
* max_depth - Depth to which search for _REG
|
||||
* space_id - The address space ID
|
||||
* function - Passed to _REG: On (1) or Off (0)
|
||||
*
|
||||
@@ -679,7 +685,7 @@ cleanup1:
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
|
||||
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, u32 max_depth,
|
||||
acpi_adr_space_type space_id, u32 function)
|
||||
{
|
||||
struct acpi_reg_walk_info info;
|
||||
@@ -713,7 +719,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
|
||||
* regions and _REG methods. (i.e. handlers must be installed for all
|
||||
* regions of this Space ID before we can run any _REG methods)
|
||||
*/
|
||||
(void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
|
||||
(void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, max_depth,
|
||||
ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, NULL,
|
||||
&info, NULL);
|
||||
|
||||
@@ -814,7 +820,7 @@ acpi_ev_reg_run(acpi_handle obj_handle,
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
static void
|
||||
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node,
|
||||
acpi_adr_space_type space_id)
|
||||
{
|
||||
|
||||
@@ -85,7 +85,8 @@ acpi_install_address_space_handler_internal(acpi_handle device,
|
||||
/* Run all _REG methods for this address space */
|
||||
|
||||
if (run_reg) {
|
||||
acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
|
||||
acpi_ev_execute_reg_methods(node, ACPI_UINT32_MAX, space_id,
|
||||
ACPI_REG_CONNECT);
|
||||
}
|
||||
|
||||
unlock_and_exit:
|
||||
@@ -263,6 +264,7 @@ ACPI_EXPORT_SYMBOL(acpi_remove_address_space_handler)
|
||||
* FUNCTION: acpi_execute_reg_methods
|
||||
*
|
||||
* PARAMETERS: device - Handle for the device
|
||||
* max_depth - Depth to which search for _REG
|
||||
* space_id - The address space ID
|
||||
*
|
||||
* RETURN: Status
|
||||
@@ -271,7 +273,8 @@ ACPI_EXPORT_SYMBOL(acpi_remove_address_space_handler)
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id)
|
||||
acpi_execute_reg_methods(acpi_handle device, u32 max_depth,
|
||||
acpi_adr_space_type space_id)
|
||||
{
|
||||
struct acpi_namespace_node *node;
|
||||
acpi_status status;
|
||||
@@ -296,7 +299,8 @@ acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id)
|
||||
|
||||
/* Run all _REG methods for this address space */
|
||||
|
||||
acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
|
||||
acpi_ev_execute_reg_methods(node, max_depth, space_id,
|
||||
ACPI_REG_CONNECT);
|
||||
} else {
|
||||
status = AE_BAD_PARAMETER;
|
||||
}
|
||||
@@ -306,57 +310,3 @@ acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id)
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_execute_reg_methods)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_execute_orphan_reg_method
|
||||
*
|
||||
* PARAMETERS: device - Handle for the device
|
||||
* space_id - The address space ID
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Execute an "orphan" _REG method that appears under an ACPI
|
||||
* device. This is a _REG method that has no corresponding region
|
||||
* within the device's scope.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
acpi_execute_orphan_reg_method(acpi_handle device, acpi_adr_space_type space_id)
|
||||
{
|
||||
struct acpi_namespace_node *node;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_execute_orphan_reg_method);
|
||||
|
||||
/* Parameter validation */
|
||||
|
||||
if (!device) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Convert and validate the device handle */
|
||||
|
||||
node = acpi_ns_validate_handle(device);
|
||||
if (node) {
|
||||
|
||||
/*
|
||||
* If an "orphan" _REG method is present in the device's scope
|
||||
* for the given address space ID, run it.
|
||||
*/
|
||||
|
||||
acpi_ev_execute_orphan_reg_method(node, space_id);
|
||||
} else {
|
||||
status = AE_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_execute_orphan_reg_method)
|
||||
|
||||
@@ -1487,12 +1487,13 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
|
||||
static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
|
||||
bool call_reg)
|
||||
{
|
||||
acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle;
|
||||
acpi_status status;
|
||||
|
||||
acpi_ec_start(ec, false);
|
||||
|
||||
if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
|
||||
acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle;
|
||||
|
||||
acpi_ec_enter_noirq(ec);
|
||||
status = acpi_install_address_space_handler_no_reg(scope_handle,
|
||||
ACPI_ADR_SPACE_EC,
|
||||
@@ -1506,10 +1507,7 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
|
||||
}
|
||||
|
||||
if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
|
||||
acpi_execute_reg_methods(scope_handle, ACPI_ADR_SPACE_EC);
|
||||
if (scope_handle != ec->handle)
|
||||
acpi_execute_orphan_reg_method(ec->handle, ACPI_ADR_SPACE_EC);
|
||||
|
||||
acpi_execute_reg_methods(ec->handle, ACPI_UINT32_MAX, ACPI_ADR_SPACE_EC);
|
||||
set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
|
||||
}
|
||||
|
||||
@@ -1724,6 +1722,12 @@ static void acpi_ec_remove(struct acpi_device *device)
|
||||
}
|
||||
}
|
||||
|
||||
void acpi_ec_register_opregions(struct acpi_device *adev)
|
||||
{
|
||||
if (first_ec && first_ec->handle != adev->handle)
|
||||
acpi_execute_reg_methods(adev->handle, 1, ACPI_ADR_SPACE_EC);
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
ec_parse_io_ports(struct acpi_resource *resource, void *context)
|
||||
{
|
||||
|
||||
@@ -204,6 +204,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
|
||||
acpi_handle handle, acpi_ec_query_func func,
|
||||
void *data);
|
||||
void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
|
||||
void acpi_ec_register_opregions(struct acpi_device *adev);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
void acpi_ec_flush_work(void);
|
||||
|
||||
@@ -2198,6 +2198,8 @@ static int acpi_bus_attach(struct acpi_device *device, void *first_pass)
|
||||
if (device->handler)
|
||||
goto ok;
|
||||
|
||||
acpi_ec_register_opregions(device);
|
||||
|
||||
if (!device->flags.initialized) {
|
||||
device->flags.power_manageable =
|
||||
device->power.states[ACPI_STATE_D0].flags.valid;
|
||||
|
||||
@@ -1118,8 +1118,8 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
|
||||
rpp->len += skb->len;
|
||||
|
||||
if (stat & SAR_RSQE_EPDU) {
|
||||
unsigned int len, truesize;
|
||||
unsigned char *l1l2;
|
||||
unsigned int len;
|
||||
|
||||
l1l2 = (unsigned char *) ((unsigned long) skb->data + skb->len - 6);
|
||||
|
||||
@@ -1189,14 +1189,15 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
|
||||
ATM_SKB(skb)->vcc = vcc;
|
||||
__net_timestamp(skb);
|
||||
|
||||
truesize = skb->truesize;
|
||||
vcc->push(vcc, skb);
|
||||
atomic_inc(&vcc->stats->rx);
|
||||
|
||||
if (skb->truesize > SAR_FB_SIZE_3)
|
||||
if (truesize > SAR_FB_SIZE_3)
|
||||
add_rx_skb(card, 3, SAR_FB_SIZE_3, 1);
|
||||
else if (skb->truesize > SAR_FB_SIZE_2)
|
||||
else if (truesize > SAR_FB_SIZE_2)
|
||||
add_rx_skb(card, 2, SAR_FB_SIZE_2, 1);
|
||||
else if (skb->truesize > SAR_FB_SIZE_1)
|
||||
else if (truesize > SAR_FB_SIZE_1)
|
||||
add_rx_skb(card, 1, SAR_FB_SIZE_1, 1);
|
||||
else
|
||||
add_rx_skb(card, 0, SAR_FB_SIZE_0, 1);
|
||||
|
||||
@@ -122,8 +122,7 @@ static const struct regmap_bus *regmap_get_spi_bus(struct spi_device *spi,
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
max_msg_size = spi_max_message_size(spi);
|
||||
reg_reserve_size = config->reg_bits / BITS_PER_BYTE
|
||||
+ config->pad_bits / BITS_PER_BYTE;
|
||||
reg_reserve_size = (config->reg_bits + config->pad_bits) / BITS_PER_BYTE;
|
||||
if (max_size + reg_reserve_size > max_msg_size)
|
||||
max_size -= reg_reserve_size;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#define BTNXPUART_CHECK_BOOT_SIGNATURE 3
|
||||
#define BTNXPUART_SERDEV_OPEN 4
|
||||
#define BTNXPUART_IR_IN_PROGRESS 5
|
||||
#define BTNXPUART_FW_DOWNLOAD_ABORT 6
|
||||
|
||||
/* NXP HW err codes */
|
||||
#define BTNXPUART_IR_HW_ERR 0xb0
|
||||
@@ -126,6 +127,7 @@ struct ps_data {
|
||||
struct hci_dev *hdev;
|
||||
struct work_struct work;
|
||||
struct timer_list ps_timer;
|
||||
struct mutex ps_lock;
|
||||
};
|
||||
|
||||
struct wakeup_cmd_payload {
|
||||
@@ -158,6 +160,7 @@ struct btnxpuart_dev {
|
||||
u8 fw_name[MAX_FW_FILE_NAME_LEN];
|
||||
u32 fw_dnld_v1_offset;
|
||||
u32 fw_v1_sent_bytes;
|
||||
u32 fw_dnld_v3_offset;
|
||||
u32 fw_v3_offset_correction;
|
||||
u32 fw_v1_expected_len;
|
||||
u32 boot_reg_offset;
|
||||
@@ -333,6 +336,9 @@ static void ps_start_timer(struct btnxpuart_dev *nxpdev)
|
||||
|
||||
if (psdata->cur_psmode == PS_MODE_ENABLE)
|
||||
mod_timer(&psdata->ps_timer, jiffies + msecs_to_jiffies(psdata->h2c_ps_interval));
|
||||
|
||||
if (psdata->ps_state == PS_STATE_AWAKE && psdata->ps_cmd == PS_CMD_ENTER_PS)
|
||||
cancel_work_sync(&psdata->work);
|
||||
}
|
||||
|
||||
static void ps_cancel_timer(struct btnxpuart_dev *nxpdev)
|
||||
@@ -353,6 +359,7 @@ static void ps_control(struct hci_dev *hdev, u8 ps_state)
|
||||
!test_bit(BTNXPUART_SERDEV_OPEN, &nxpdev->tx_state))
|
||||
return;
|
||||
|
||||
mutex_lock(&psdata->ps_lock);
|
||||
switch (psdata->cur_h2c_wakeupmode) {
|
||||
case WAKEUP_METHOD_DTR:
|
||||
if (ps_state == PS_STATE_AWAKE)
|
||||
@@ -366,12 +373,15 @@ static void ps_control(struct hci_dev *hdev, u8 ps_state)
|
||||
status = serdev_device_break_ctl(nxpdev->serdev, 0);
|
||||
else
|
||||
status = serdev_device_break_ctl(nxpdev->serdev, -1);
|
||||
msleep(20); /* Allow chip to detect UART-break and enter sleep */
|
||||
bt_dev_dbg(hdev, "Set UART break: %s, status=%d",
|
||||
str_on_off(ps_state == PS_STATE_SLEEP), status);
|
||||
break;
|
||||
}
|
||||
if (!status)
|
||||
psdata->ps_state = ps_state;
|
||||
mutex_unlock(&psdata->ps_lock);
|
||||
|
||||
if (ps_state == PS_STATE_AWAKE)
|
||||
btnxpuart_tx_wakeup(nxpdev);
|
||||
}
|
||||
@@ -407,17 +417,42 @@ static void ps_setup(struct hci_dev *hdev)
|
||||
|
||||
psdata->hdev = hdev;
|
||||
INIT_WORK(&psdata->work, ps_work_func);
|
||||
mutex_init(&psdata->ps_lock);
|
||||
timer_setup(&psdata->ps_timer, ps_timeout_func, 0);
|
||||
}
|
||||
|
||||
static void ps_wakeup(struct btnxpuart_dev *nxpdev)
|
||||
static bool ps_wakeup(struct btnxpuart_dev *nxpdev)
|
||||
{
|
||||
struct ps_data *psdata = &nxpdev->psdata;
|
||||
u8 ps_state;
|
||||
|
||||
if (psdata->ps_state != PS_STATE_AWAKE) {
|
||||
mutex_lock(&psdata->ps_lock);
|
||||
ps_state = psdata->ps_state;
|
||||
mutex_unlock(&psdata->ps_lock);
|
||||
|
||||
if (ps_state != PS_STATE_AWAKE) {
|
||||
psdata->ps_cmd = PS_CMD_EXIT_PS;
|
||||
schedule_work(&psdata->work);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ps_cleanup(struct btnxpuart_dev *nxpdev)
|
||||
{
|
||||
struct ps_data *psdata = &nxpdev->psdata;
|
||||
u8 ps_state;
|
||||
|
||||
mutex_lock(&psdata->ps_lock);
|
||||
ps_state = psdata->ps_state;
|
||||
mutex_unlock(&psdata->ps_lock);
|
||||
|
||||
if (ps_state != PS_STATE_AWAKE)
|
||||
ps_control(psdata->hdev, PS_STATE_AWAKE);
|
||||
|
||||
ps_cancel_timer(nxpdev);
|
||||
cancel_work_sync(&psdata->work);
|
||||
mutex_destroy(&psdata->ps_lock);
|
||||
}
|
||||
|
||||
static int send_ps_cmd(struct hci_dev *hdev, void *data)
|
||||
@@ -550,6 +585,7 @@ static int nxp_download_firmware(struct hci_dev *hdev)
|
||||
nxpdev->fw_v1_sent_bytes = 0;
|
||||
nxpdev->fw_v1_expected_len = HDR_LEN;
|
||||
nxpdev->boot_reg_offset = 0;
|
||||
nxpdev->fw_dnld_v3_offset = 0;
|
||||
nxpdev->fw_v3_offset_correction = 0;
|
||||
nxpdev->baudrate_changed = false;
|
||||
nxpdev->timeout_changed = false;
|
||||
@@ -564,14 +600,23 @@ static int nxp_download_firmware(struct hci_dev *hdev)
|
||||
!test_bit(BTNXPUART_FW_DOWNLOADING,
|
||||
&nxpdev->tx_state),
|
||||
msecs_to_jiffies(60000));
|
||||
|
||||
release_firmware(nxpdev->fw);
|
||||
memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name));
|
||||
|
||||
if (err == 0) {
|
||||
bt_dev_err(hdev, "FW Download Timeout.");
|
||||
bt_dev_err(hdev, "FW Download Timeout. offset: %d",
|
||||
nxpdev->fw_dnld_v1_offset ?
|
||||
nxpdev->fw_dnld_v1_offset :
|
||||
nxpdev->fw_dnld_v3_offset);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
if (test_bit(BTNXPUART_FW_DOWNLOAD_ABORT, &nxpdev->tx_state)) {
|
||||
bt_dev_err(hdev, "FW Download Aborted");
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
serdev_device_set_flow_control(nxpdev->serdev, true);
|
||||
release_firmware(nxpdev->fw);
|
||||
memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name));
|
||||
|
||||
/* Allow the downloaded FW to initialize */
|
||||
msleep(1200);
|
||||
@@ -982,8 +1027,9 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
goto free_skb;
|
||||
}
|
||||
|
||||
serdev_device_write_buf(nxpdev->serdev, nxpdev->fw->data + offset -
|
||||
nxpdev->fw_v3_offset_correction, len);
|
||||
nxpdev->fw_dnld_v3_offset = offset - nxpdev->fw_v3_offset_correction;
|
||||
serdev_device_write_buf(nxpdev->serdev, nxpdev->fw->data +
|
||||
nxpdev->fw_dnld_v3_offset, len);
|
||||
|
||||
free_skb:
|
||||
kfree_skb(skb);
|
||||
@@ -1215,7 +1261,6 @@ static struct sk_buff *nxp_dequeue(void *data)
|
||||
{
|
||||
struct btnxpuart_dev *nxpdev = (struct btnxpuart_dev *)data;
|
||||
|
||||
ps_wakeup(nxpdev);
|
||||
ps_start_timer(nxpdev);
|
||||
return skb_dequeue(&nxpdev->txq);
|
||||
}
|
||||
@@ -1230,6 +1275,9 @@ static void btnxpuart_tx_work(struct work_struct *work)
|
||||
struct sk_buff *skb;
|
||||
int len;
|
||||
|
||||
if (ps_wakeup(nxpdev))
|
||||
return;
|
||||
|
||||
while ((skb = nxp_dequeue(nxpdev))) {
|
||||
len = serdev_device_write_buf(serdev, skb->data, skb->len);
|
||||
hdev->stat.byte_tx += len;
|
||||
@@ -1276,7 +1324,6 @@ static int btnxpuart_close(struct hci_dev *hdev)
|
||||
{
|
||||
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
|
||||
|
||||
ps_wakeup(nxpdev);
|
||||
serdev_device_close(nxpdev->serdev);
|
||||
skb_queue_purge(&nxpdev->txq);
|
||||
kfree_skb(nxpdev->rx_skb);
|
||||
@@ -1412,16 +1459,22 @@ static void nxp_serdev_remove(struct serdev_device *serdev)
|
||||
struct btnxpuart_dev *nxpdev = serdev_device_get_drvdata(serdev);
|
||||
struct hci_dev *hdev = nxpdev->hdev;
|
||||
|
||||
/* Restore FW baudrate to fw_init_baudrate if changed.
|
||||
* This will ensure FW baudrate is in sync with
|
||||
* driver baudrate in case this driver is re-inserted.
|
||||
*/
|
||||
if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) {
|
||||
nxpdev->new_baudrate = nxpdev->fw_init_baudrate;
|
||||
nxp_set_baudrate_cmd(hdev, NULL);
|
||||
if (is_fw_downloading(nxpdev)) {
|
||||
set_bit(BTNXPUART_FW_DOWNLOAD_ABORT, &nxpdev->tx_state);
|
||||
clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
|
||||
wake_up_interruptible(&nxpdev->check_boot_sign_wait_q);
|
||||
wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q);
|
||||
} else {
|
||||
/* Restore FW baudrate to fw_init_baudrate if changed.
|
||||
* This will ensure FW baudrate is in sync with
|
||||
* driver baudrate in case this driver is re-inserted.
|
||||
*/
|
||||
if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) {
|
||||
nxpdev->new_baudrate = nxpdev->fw_init_baudrate;
|
||||
nxp_set_baudrate_cmd(hdev, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ps_cancel_timer(nxpdev);
|
||||
ps_cleanup(nxpdev);
|
||||
hci_unregister_dev(hdev);
|
||||
hci_free_dev(hdev);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ MODULE_LICENSE("GPL v2");
|
||||
static const char xillyname[] = "xillyusb";
|
||||
|
||||
static unsigned int fifo_buf_order;
|
||||
static struct workqueue_struct *wakeup_wq;
|
||||
|
||||
#define USB_VENDOR_ID_XILINX 0x03fd
|
||||
#define USB_VENDOR_ID_ALTERA 0x09fb
|
||||
@@ -569,10 +570,6 @@ static void cleanup_dev(struct kref *kref)
|
||||
* errors if executed. The mechanism relies on that xdev->error is assigned
|
||||
* a non-zero value by report_io_error() prior to queueing wakeup_all(),
|
||||
* which prevents bulk_in_work() from calling process_bulk_in().
|
||||
*
|
||||
* The fact that wakeup_all() and bulk_in_work() are queued on the same
|
||||
* workqueue makes their concurrent execution very unlikely, however the
|
||||
* kernel's API doesn't seem to ensure this strictly.
|
||||
*/
|
||||
|
||||
static void wakeup_all(struct work_struct *work)
|
||||
@@ -627,7 +624,7 @@ static void report_io_error(struct xillyusb_dev *xdev,
|
||||
|
||||
if (do_once) {
|
||||
kref_get(&xdev->kref); /* xdev is used by work item */
|
||||
queue_work(xdev->workq, &xdev->wakeup_workitem);
|
||||
queue_work(wakeup_wq, &xdev->wakeup_workitem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1906,6 +1903,13 @@ static const struct file_operations xillyusb_fops = {
|
||||
|
||||
static int xillyusb_setup_base_eps(struct xillyusb_dev *xdev)
|
||||
{
|
||||
struct usb_device *udev = xdev->udev;
|
||||
|
||||
/* Verify that device has the two fundamental bulk in/out endpoints */
|
||||
if (usb_pipe_type_check(udev, usb_sndbulkpipe(udev, MSG_EP_NUM)) ||
|
||||
usb_pipe_type_check(udev, usb_rcvbulkpipe(udev, IN_EP_NUM)))
|
||||
return -ENODEV;
|
||||
|
||||
xdev->msg_ep = endpoint_alloc(xdev, MSG_EP_NUM | USB_DIR_OUT,
|
||||
bulk_out_work, 1, 2);
|
||||
if (!xdev->msg_ep)
|
||||
@@ -1935,14 +1939,15 @@ static int setup_channels(struct xillyusb_dev *xdev,
|
||||
__le16 *chandesc,
|
||||
int num_channels)
|
||||
{
|
||||
struct xillyusb_channel *chan;
|
||||
struct usb_device *udev = xdev->udev;
|
||||
struct xillyusb_channel *chan, *new_channels;
|
||||
int i;
|
||||
|
||||
chan = kcalloc(num_channels, sizeof(*chan), GFP_KERNEL);
|
||||
if (!chan)
|
||||
return -ENOMEM;
|
||||
|
||||
xdev->channels = chan;
|
||||
new_channels = chan;
|
||||
|
||||
for (i = 0; i < num_channels; i++, chan++) {
|
||||
unsigned int in_desc = le16_to_cpu(*chandesc++);
|
||||
@@ -1971,6 +1976,15 @@ static int setup_channels(struct xillyusb_dev *xdev,
|
||||
*/
|
||||
|
||||
if ((out_desc & 0x80) && i < 14) { /* Entry is valid */
|
||||
if (usb_pipe_type_check(udev,
|
||||
usb_sndbulkpipe(udev, i + 2))) {
|
||||
dev_err(xdev->dev,
|
||||
"Missing BULK OUT endpoint %d\n",
|
||||
i + 2);
|
||||
kfree(new_channels);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
chan->writable = 1;
|
||||
chan->out_synchronous = !!(out_desc & 0x40);
|
||||
chan->out_seekable = !!(out_desc & 0x20);
|
||||
@@ -1980,6 +1994,7 @@ static int setup_channels(struct xillyusb_dev *xdev,
|
||||
}
|
||||
}
|
||||
|
||||
xdev->channels = new_channels;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2096,9 +2111,11 @@ static int xillyusb_discovery(struct usb_interface *interface)
|
||||
* just after responding with the IDT, there is no reason for any
|
||||
* work item to be running now. To be sure that xdev->channels
|
||||
* is updated on anything that might run in parallel, flush the
|
||||
* workqueue, which rarely does anything.
|
||||
* device's workqueue and the wakeup work item. This rarely
|
||||
* does anything.
|
||||
*/
|
||||
flush_workqueue(xdev->workq);
|
||||
flush_work(&xdev->wakeup_workitem);
|
||||
|
||||
xdev->num_channels = num_channels;
|
||||
|
||||
@@ -2258,6 +2275,10 @@ static int __init xillyusb_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
wakeup_wq = alloc_workqueue(xillyname, 0, 0);
|
||||
if (!wakeup_wq)
|
||||
return -ENOMEM;
|
||||
|
||||
if (LOG2_INITIAL_FIFO_BUF_SIZE > PAGE_SHIFT)
|
||||
fifo_buf_order = LOG2_INITIAL_FIFO_BUF_SIZE - PAGE_SHIFT;
|
||||
else
|
||||
@@ -2265,12 +2286,17 @@ static int __init xillyusb_init(void)
|
||||
|
||||
rc = usb_register(&xillyusb_driver);
|
||||
|
||||
if (rc)
|
||||
destroy_workqueue(wakeup_wq);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void __exit xillyusb_exit(void)
|
||||
{
|
||||
usb_deregister(&xillyusb_driver);
|
||||
|
||||
destroy_workqueue(wakeup_wq);
|
||||
}
|
||||
|
||||
module_init(xillyusb_init);
|
||||
|
||||
@@ -329,12 +329,12 @@ struct visconti_pll_provider * __init visconti_init_pll(struct device_node *np,
|
||||
if (!ctx)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
for (i = 0; i < nr_plls; ++i)
|
||||
ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
|
||||
|
||||
ctx->node = np;
|
||||
ctx->reg_base = base;
|
||||
ctx->clk_data.num = nr_plls;
|
||||
|
||||
for (i = 0; i < nr_plls; ++i)
|
||||
ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@@ -290,18 +290,17 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb,
|
||||
switch (event) {
|
||||
case PRE_RATE_CHANGE:
|
||||
{
|
||||
int psv;
|
||||
unsigned long psv;
|
||||
|
||||
psv = DIV_ROUND_CLOSEST(ndata->new_rate,
|
||||
gt_target_rate);
|
||||
|
||||
if (abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR)
|
||||
psv = DIV_ROUND_CLOSEST(ndata->new_rate, gt_target_rate);
|
||||
if (!psv ||
|
||||
abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR)
|
||||
return NOTIFY_BAD;
|
||||
|
||||
psv--;
|
||||
|
||||
/* prescaler within legal range? */
|
||||
if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
|
||||
if (psv > GT_CONTROL_PRESCALER_MAX)
|
||||
return NOTIFY_BAD;
|
||||
|
||||
/*
|
||||
|
||||
@@ -62,9 +62,9 @@ static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq)
|
||||
{
|
||||
struct scmi_data *priv = policy->driver_data;
|
||||
unsigned long freq = target_freq;
|
||||
|
||||
if (!perf_ops->freq_set(ph, priv->domain_id,
|
||||
target_freq * 1000, true))
|
||||
if (!perf_ops->freq_set(ph, priv->domain_id, freq * 1000, true))
|
||||
return target_freq;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <crypto/internal/des.h>
|
||||
#include <crypto/internal/skcipher.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <linux/bottom_half.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
@@ -1665,8 +1666,11 @@ static irqreturn_t stm32_cryp_irq_thread(int irq, void *arg)
|
||||
it_mask &= ~IMSCR_OUT;
|
||||
stm32_cryp_write(cryp, cryp->caps->imsc, it_mask);
|
||||
|
||||
if (!cryp->payload_in && !cryp->header_in && !cryp->payload_out)
|
||||
if (!cryp->payload_in && !cryp->header_in && !cryp->payload_out) {
|
||||
local_bh_disable();
|
||||
stm32_cryp_finish_req(cryp, 0);
|
||||
local_bh_enable();
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ static void msgdma_free_descriptor(struct msgdma_device *mdev,
|
||||
struct msgdma_sw_desc *child, *next;
|
||||
|
||||
mdev->desc_free_cnt++;
|
||||
list_add_tail(&desc->node, &mdev->free_list);
|
||||
list_move_tail(&desc->node, &mdev->free_list);
|
||||
list_for_each_entry_safe(child, next, &desc->tx_list, node) {
|
||||
mdev->desc_free_cnt++;
|
||||
list_move_tail(&child->node, &mdev->free_list);
|
||||
@@ -583,17 +583,16 @@ static void msgdma_issue_pending(struct dma_chan *chan)
|
||||
static void msgdma_chan_desc_cleanup(struct msgdma_device *mdev)
|
||||
{
|
||||
struct msgdma_sw_desc *desc, *next;
|
||||
unsigned long irqflags;
|
||||
|
||||
list_for_each_entry_safe(desc, next, &mdev->done_list, node) {
|
||||
struct dmaengine_desc_callback cb;
|
||||
|
||||
list_del(&desc->node);
|
||||
|
||||
dmaengine_desc_get_callback(&desc->async_tx, &cb);
|
||||
if (dmaengine_desc_callback_valid(&cb)) {
|
||||
spin_unlock(&mdev->lock);
|
||||
spin_unlock_irqrestore(&mdev->lock, irqflags);
|
||||
dmaengine_desc_callback_invoke(&cb, NULL);
|
||||
spin_lock(&mdev->lock);
|
||||
spin_lock_irqsave(&mdev->lock, irqflags);
|
||||
}
|
||||
|
||||
/* Run any dependencies, then free the descriptor */
|
||||
|
||||
@@ -17,8 +17,8 @@ enum dw_hdma_control {
|
||||
DW_HDMA_V0_CB = BIT(0),
|
||||
DW_HDMA_V0_TCB = BIT(1),
|
||||
DW_HDMA_V0_LLP = BIT(2),
|
||||
DW_HDMA_V0_LIE = BIT(3),
|
||||
DW_HDMA_V0_RIE = BIT(4),
|
||||
DW_HDMA_V0_LWIE = BIT(3),
|
||||
DW_HDMA_V0_RWIE = BIT(4),
|
||||
DW_HDMA_V0_CCS = BIT(8),
|
||||
DW_HDMA_V0_LLE = BIT(9),
|
||||
};
|
||||
@@ -195,25 +195,14 @@ static void dw_hdma_v0_write_ll_link(struct dw_edma_chunk *chunk,
|
||||
static void dw_hdma_v0_core_write_chunk(struct dw_edma_chunk *chunk)
|
||||
{
|
||||
struct dw_edma_burst *child;
|
||||
struct dw_edma_chan *chan = chunk->chan;
|
||||
u32 control = 0, i = 0;
|
||||
int j;
|
||||
|
||||
if (chunk->cb)
|
||||
control = DW_HDMA_V0_CB;
|
||||
|
||||
j = chunk->bursts_alloc;
|
||||
list_for_each_entry(child, &chunk->burst->list, list) {
|
||||
j--;
|
||||
if (!j) {
|
||||
control |= DW_HDMA_V0_LIE;
|
||||
if (!(chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL))
|
||||
control |= DW_HDMA_V0_RIE;
|
||||
}
|
||||
|
||||
list_for_each_entry(child, &chunk->burst->list, list)
|
||||
dw_hdma_v0_write_ll_data(chunk, i++, control, child->sz,
|
||||
child->sar, child->dar);
|
||||
}
|
||||
|
||||
control = DW_HDMA_V0_LLP | DW_HDMA_V0_TCB;
|
||||
if (!chunk->cb)
|
||||
@@ -247,10 +236,11 @@ static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
|
||||
if (first) {
|
||||
/* Enable engine */
|
||||
SET_CH_32(dw, chan->dir, chan->id, ch_en, BIT(0));
|
||||
/* Interrupt enable&unmask - done, abort */
|
||||
tmp = GET_CH_32(dw, chan->dir, chan->id, int_setup) |
|
||||
HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK |
|
||||
HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_ABORT_INT_EN;
|
||||
/* Interrupt unmask - stop, abort */
|
||||
tmp = GET_CH_32(dw, chan->dir, chan->id, int_setup);
|
||||
tmp &= ~(HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK);
|
||||
/* Interrupt enable - stop, abort */
|
||||
tmp |= HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_ABORT_INT_EN;
|
||||
if (!(dw->chip->flags & DW_EDMA_CHIP_LOCAL))
|
||||
tmp |= HDMA_V0_REMOTE_STOP_INT_EN | HDMA_V0_REMOTE_ABORT_INT_EN;
|
||||
SET_CH_32(dw, chan->dir, chan->id, int_setup, tmp);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -621,12 +622,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
||||
struct dw_desc *prev;
|
||||
struct dw_desc *first;
|
||||
u32 ctllo, ctlhi;
|
||||
u8 m_master = dwc->dws.m_master;
|
||||
u8 lms = DWC_LLP_LMS(m_master);
|
||||
u8 lms = DWC_LLP_LMS(dwc->dws.m_master);
|
||||
dma_addr_t reg;
|
||||
unsigned int reg_width;
|
||||
unsigned int mem_width;
|
||||
unsigned int data_width = dw->pdata->data_width[m_master];
|
||||
unsigned int i;
|
||||
struct scatterlist *sg;
|
||||
size_t total_len = 0;
|
||||
@@ -660,7 +659,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
||||
mem = sg_dma_address(sg);
|
||||
len = sg_dma_len(sg);
|
||||
|
||||
mem_width = __ffs(data_width | mem | len);
|
||||
mem_width = __ffs(sconfig->src_addr_width | mem | len);
|
||||
|
||||
slave_sg_todev_fill_desc:
|
||||
desc = dwc_desc_get(dwc);
|
||||
@@ -720,7 +719,7 @@ slave_sg_fromdev_fill_desc:
|
||||
lli_write(desc, sar, reg);
|
||||
lli_write(desc, dar, mem);
|
||||
lli_write(desc, ctlhi, ctlhi);
|
||||
mem_width = __ffs(data_width | mem);
|
||||
mem_width = __ffs(sconfig->dst_addr_width | mem);
|
||||
lli_write(desc, ctllo, ctllo | DWC_CTLL_DST_WIDTH(mem_width));
|
||||
desc->len = dlen;
|
||||
|
||||
@@ -780,17 +779,93 @@ bool dw_dma_filter(struct dma_chan *chan, void *param)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dw_dma_filter);
|
||||
|
||||
static int dwc_verify_p_buswidth(struct dma_chan *chan)
|
||||
{
|
||||
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
|
||||
struct dw_dma *dw = to_dw_dma(chan->device);
|
||||
u32 reg_width, max_width;
|
||||
|
||||
if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
|
||||
reg_width = dwc->dma_sconfig.dst_addr_width;
|
||||
else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM)
|
||||
reg_width = dwc->dma_sconfig.src_addr_width;
|
||||
else /* DMA_MEM_TO_MEM */
|
||||
return 0;
|
||||
|
||||
max_width = dw->pdata->data_width[dwc->dws.p_master];
|
||||
|
||||
/* Fall-back to 1-byte transfer width if undefined */
|
||||
if (reg_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
|
||||
reg_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
||||
else if (!is_power_of_2(reg_width) || reg_width > max_width)
|
||||
return -EINVAL;
|
||||
else /* bus width is valid */
|
||||
return 0;
|
||||
|
||||
/* Update undefined addr width value */
|
||||
if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
|
||||
dwc->dma_sconfig.dst_addr_width = reg_width;
|
||||
else /* DMA_DEV_TO_MEM */
|
||||
dwc->dma_sconfig.src_addr_width = reg_width;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dwc_verify_m_buswidth(struct dma_chan *chan)
|
||||
{
|
||||
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
|
||||
struct dw_dma *dw = to_dw_dma(chan->device);
|
||||
u32 reg_width, reg_burst, mem_width;
|
||||
|
||||
mem_width = dw->pdata->data_width[dwc->dws.m_master];
|
||||
|
||||
/*
|
||||
* It's possible to have a data portion locked in the DMA FIFO in case
|
||||
* of the channel suspension. Subsequent channel disabling will cause
|
||||
* that data silent loss. In order to prevent that maintain the src and
|
||||
* dst transfer widths coherency by means of the relation:
|
||||
* (CTLx.SRC_TR_WIDTH * CTLx.SRC_MSIZE >= CTLx.DST_TR_WIDTH)
|
||||
* Look for the details in the commit message that brings this change.
|
||||
*
|
||||
* Note the DMA configs utilized in the calculations below must have
|
||||
* been verified to have correct values by this method call.
|
||||
*/
|
||||
if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV) {
|
||||
reg_width = dwc->dma_sconfig.dst_addr_width;
|
||||
if (mem_width < reg_width)
|
||||
return -EINVAL;
|
||||
|
||||
dwc->dma_sconfig.src_addr_width = mem_width;
|
||||
} else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM) {
|
||||
reg_width = dwc->dma_sconfig.src_addr_width;
|
||||
reg_burst = rounddown_pow_of_two(dwc->dma_sconfig.src_maxburst);
|
||||
|
||||
dwc->dma_sconfig.dst_addr_width = min(mem_width, reg_width * reg_burst);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
|
||||
{
|
||||
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
|
||||
struct dw_dma *dw = to_dw_dma(chan->device);
|
||||
int ret;
|
||||
|
||||
memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
|
||||
|
||||
dwc->dma_sconfig.src_maxburst =
|
||||
clamp(dwc->dma_sconfig.src_maxburst, 0U, dwc->max_burst);
|
||||
clamp(dwc->dma_sconfig.src_maxburst, 1U, dwc->max_burst);
|
||||
dwc->dma_sconfig.dst_maxburst =
|
||||
clamp(dwc->dma_sconfig.dst_maxburst, 0U, dwc->max_burst);
|
||||
clamp(dwc->dma_sconfig.dst_maxburst, 1U, dwc->max_burst);
|
||||
|
||||
ret = dwc_verify_p_buswidth(chan);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = dwc_verify_m_buswidth(chan);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dw->encode_maxburst(dwc, &dwc->dma_sconfig.src_maxburst);
|
||||
dw->encode_maxburst(dwc, &dwc->dma_sconfig.dst_maxburst);
|
||||
|
||||
@@ -659,6 +659,10 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
|
||||
memset(&res, 0, sizeof(res));
|
||||
res.mce = mce;
|
||||
res.addr = mce->addr & MCI_ADDR_PHYSADDR;
|
||||
if (!pfn_to_online_page(res.addr >> PAGE_SHIFT) && !arch_is_platform_page(res.addr)) {
|
||||
pr_err("Invalid address 0x%llx in IA32_MC%d_ADDR\n", mce->addr, mce->bank);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
/* Try driver decoder first */
|
||||
if (!(driver_decode && driver_decode(&res))) {
|
||||
|
||||
@@ -522,7 +522,7 @@ void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp)
|
||||
{
|
||||
cs_dsp_debugfs_clear(dsp);
|
||||
debugfs_remove_recursive(dsp->debugfs_root);
|
||||
dsp->debugfs_root = NULL;
|
||||
dsp->debugfs_root = ERR_PTR(-ENODEV);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cs_dsp_cleanup_debugfs, FW_CS_DSP);
|
||||
#else
|
||||
@@ -2343,6 +2343,11 @@ static int cs_dsp_common_init(struct cs_dsp *dsp)
|
||||
|
||||
mutex_init(&dsp->pwr_lock);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
/* Ensure this is invalid if client never provides a debugfs root */
|
||||
dsp->debugfs_root = ERR_PTR(-ENODEV);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ int scm_get_wq_ctx(u32 *wq_ctx, u32 *flags, u32 *more_pending)
|
||||
struct arm_smccc_res get_wq_res;
|
||||
struct arm_smccc_args get_wq_ctx = {0};
|
||||
|
||||
get_wq_ctx.args[0] = ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL,
|
||||
get_wq_ctx.args[0] = ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,
|
||||
ARM_SMCCC_SMC_64, ARM_SMCCC_OWNER_SIP,
|
||||
SCM_SMC_FNID(QCOM_SCM_SVC_WAITQ, QCOM_SCM_WAITQ_GET_WQ_CTX));
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#define MLXBF_GPIO_CAUSE_OR_EVTEN0 0x14
|
||||
#define MLXBF_GPIO_CAUSE_OR_CLRCAUSE 0x18
|
||||
|
||||
#define MLXBF_GPIO_CLR_ALL_INTS GENMASK(31, 0)
|
||||
|
||||
struct mlxbf3_gpio_context {
|
||||
struct gpio_chip gc;
|
||||
|
||||
@@ -82,6 +84,8 @@ static void mlxbf3_gpio_irq_disable(struct irq_data *irqd)
|
||||
val = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
|
||||
val &= ~BIT(offset);
|
||||
writel(val, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
|
||||
|
||||
writel(BIT(offset), gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
|
||||
raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
|
||||
|
||||
gpiochip_disable_irq(gc, offset);
|
||||
@@ -253,6 +257,15 @@ static int mlxbf3_gpio_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mlxbf3_gpio_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct mlxbf3_gpio_context *gs = platform_get_drvdata(pdev);
|
||||
|
||||
/* Disable and clear all interrupts */
|
||||
writel(0, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
|
||||
writel(MLXBF_GPIO_CLR_ALL_INTS, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
|
||||
}
|
||||
|
||||
static const struct acpi_device_id mlxbf3_gpio_acpi_match[] = {
|
||||
{ "MLNXBF33", 0 },
|
||||
{}
|
||||
@@ -265,6 +278,7 @@ static struct platform_driver mlxbf3_gpio_driver = {
|
||||
.acpi_match_table = mlxbf3_gpio_acpi_match,
|
||||
},
|
||||
.probe = mlxbf3_gpio_probe,
|
||||
.shutdown = mlxbf3_gpio_shutdown,
|
||||
};
|
||||
module_platform_driver(mlxbf3_gpio_driver);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/init.h>
|
||||
@@ -774,15 +775,15 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev)
|
||||
struct gpio_desc *desc;
|
||||
struct gpio_chip *chip = gdev->chip;
|
||||
|
||||
if (!gdev->mockdev)
|
||||
return;
|
||||
scoped_guard(mutex, &sysfs_lock) {
|
||||
if (!gdev->mockdev)
|
||||
return;
|
||||
|
||||
device_unregister(gdev->mockdev);
|
||||
device_unregister(gdev->mockdev);
|
||||
|
||||
/* prevent further gpiod exports */
|
||||
mutex_lock(&sysfs_lock);
|
||||
gdev->mockdev = NULL;
|
||||
mutex_unlock(&sysfs_lock);
|
||||
/* prevent further gpiod exports */
|
||||
gdev->mockdev = NULL;
|
||||
}
|
||||
|
||||
/* unregister gpiod class devices owned by sysfs */
|
||||
for_each_gpio_desc_with_flag(chip, desc, FLAG_SYSFS) {
|
||||
|
||||
@@ -100,6 +100,7 @@ struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock)
|
||||
amdgpu_afmt_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000);
|
||||
amdgpu_afmt_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100);
|
||||
amdgpu_afmt_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000);
|
||||
res.clock = clock;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -303,6 +303,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(struct amdgpu_device *adev,
|
||||
struct kgd_mem *mem, void *drm_priv);
|
||||
int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
|
||||
struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv);
|
||||
int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv);
|
||||
int amdgpu_amdkfd_gpuvm_sync_memory(
|
||||
struct amdgpu_device *adev, struct kgd_mem *mem, bool intr);
|
||||
int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem,
|
||||
|
||||
@@ -407,6 +407,10 @@ static int amdgpu_amdkfd_bo_validate(struct amdgpu_bo *bo, uint32_t domain,
|
||||
"Called with userptr BO"))
|
||||
return -EINVAL;
|
||||
|
||||
/* bo has been pinned, not need validate it */
|
||||
if (bo->tbo.pin_count)
|
||||
return 0;
|
||||
|
||||
amdgpu_bo_placement_from_domain(bo, domain);
|
||||
|
||||
ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
@@ -733,7 +737,7 @@ kfd_mem_dmaunmap_sg_bo(struct kgd_mem *mem,
|
||||
enum dma_data_direction dir;
|
||||
|
||||
if (unlikely(!ttm->sg)) {
|
||||
pr_err("SG Table of BO is UNEXPECTEDLY NULL");
|
||||
pr_debug("SG Table of BO is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1202,8 +1206,6 @@ static void unmap_bo_from_gpuvm(struct kgd_mem *mem,
|
||||
amdgpu_vm_clear_freed(adev, vm, &bo_va->last_pt_update);
|
||||
|
||||
amdgpu_sync_fence(sync, bo_va->last_pt_update);
|
||||
|
||||
kfd_mem_dmaunmap_attachment(mem, entry);
|
||||
}
|
||||
|
||||
static int update_gpuvm_pte(struct kgd_mem *mem,
|
||||
@@ -1258,6 +1260,7 @@ static int map_bo_to_gpuvm(struct kgd_mem *mem,
|
||||
|
||||
update_gpuvm_pte_failed:
|
||||
unmap_bo_from_gpuvm(mem, entry, sync);
|
||||
kfd_mem_dmaunmap_attachment(mem, entry);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1862,8 +1865,10 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
|
||||
mem->va + bo_size * (1 + mem->aql_queue));
|
||||
|
||||
/* Remove from VM internal data structures */
|
||||
list_for_each_entry_safe(entry, tmp, &mem->attachments, list)
|
||||
list_for_each_entry_safe(entry, tmp, &mem->attachments, list) {
|
||||
kfd_mem_dmaunmap_attachment(mem, entry);
|
||||
kfd_mem_detach(entry);
|
||||
}
|
||||
|
||||
ret = unreserve_bo_and_vms(&ctx, false, false);
|
||||
|
||||
@@ -2037,6 +2042,37 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv)
|
||||
{
|
||||
struct kfd_mem_attachment *entry;
|
||||
struct amdgpu_vm *vm;
|
||||
int ret;
|
||||
|
||||
vm = drm_priv_to_vm(drm_priv);
|
||||
|
||||
mutex_lock(&mem->lock);
|
||||
|
||||
ret = amdgpu_bo_reserve(mem->bo, true);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
list_for_each_entry(entry, &mem->attachments, list) {
|
||||
if (entry->bo_va->base.vm != vm)
|
||||
continue;
|
||||
if (entry->bo_va->base.bo->tbo.ttm &&
|
||||
!entry->bo_va->base.bo->tbo.ttm->sg)
|
||||
continue;
|
||||
|
||||
kfd_mem_dmaunmap_attachment(mem, entry);
|
||||
}
|
||||
|
||||
amdgpu_bo_unreserve(mem->bo);
|
||||
out:
|
||||
mutex_unlock(&mem->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
|
||||
struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv)
|
||||
{
|
||||
@@ -2599,7 +2635,7 @@ static int confirm_valid_user_pages_locked(struct amdkfd_process_info *process_i
|
||||
|
||||
/* keep mem without hmm range at userptr_inval_list */
|
||||
if (!mem->range)
|
||||
continue;
|
||||
continue;
|
||||
|
||||
/* Only check mem with hmm range associated */
|
||||
valid = amdgpu_ttm_tt_get_user_pages_done(
|
||||
@@ -2816,9 +2852,6 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
|
||||
if (!attachment->is_mapped)
|
||||
continue;
|
||||
|
||||
if (attachment->bo_va->base.bo->tbo.pin_count)
|
||||
continue;
|
||||
|
||||
kfd_mem_dmaunmap_attachment(mem, attachment);
|
||||
ret = update_gpuvm_pte(mem, attachment, &sync_obj);
|
||||
if (ret) {
|
||||
|
||||
@@ -1476,6 +1476,8 @@ int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev,
|
||||
(u32)le32_to_cpu(*((u32 *)reg_data + j));
|
||||
j++;
|
||||
} else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) {
|
||||
if (i == 0)
|
||||
continue;
|
||||
reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
|
||||
reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1];
|
||||
}
|
||||
|
||||
@@ -213,6 +213,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
|
||||
struct amdgpu_firmware_info *ucode;
|
||||
|
||||
id = fw_type_convert(cgs_device, type);
|
||||
if (id >= AMDGPU_UCODE_ID_MAXIMUM)
|
||||
return -EINVAL;
|
||||
|
||||
ucode = &adev->firmware.ucode[id];
|
||||
if (ucode->fw == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1057,6 +1057,9 @@ static int amdgpu_cs_patch_ibs(struct amdgpu_cs_parser *p,
|
||||
r = amdgpu_ring_parse_cs(ring, p, job, ib);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ib->sa_bo)
|
||||
ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo);
|
||||
} else {
|
||||
ib->ptr = (uint32_t *)kptr;
|
||||
r = amdgpu_ring_patch_cs_in_place(ring, p, job, ib);
|
||||
|
||||
@@ -684,16 +684,24 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
switch (args->in.op) {
|
||||
case AMDGPU_CTX_OP_ALLOC_CTX:
|
||||
if (args->in.flags)
|
||||
return -EINVAL;
|
||||
r = amdgpu_ctx_alloc(adev, fpriv, filp, priority, &id);
|
||||
args->out.alloc.ctx_id = id;
|
||||
break;
|
||||
case AMDGPU_CTX_OP_FREE_CTX:
|
||||
if (args->in.flags)
|
||||
return -EINVAL;
|
||||
r = amdgpu_ctx_free(fpriv, id);
|
||||
break;
|
||||
case AMDGPU_CTX_OP_QUERY_STATE:
|
||||
if (args->in.flags)
|
||||
return -EINVAL;
|
||||
r = amdgpu_ctx_query(adev, fpriv, id, &args->out);
|
||||
break;
|
||||
case AMDGPU_CTX_OP_QUERY_STATE2:
|
||||
if (args->in.flags)
|
||||
return -EINVAL;
|
||||
r = amdgpu_ctx_query2(adev, fpriv, id, &args->out);
|
||||
break;
|
||||
case AMDGPU_CTX_OP_GET_STABLE_PSTATE:
|
||||
|
||||
@@ -4480,7 +4480,8 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev)
|
||||
shadow = vmbo->shadow;
|
||||
|
||||
/* No need to recover an evicted BO */
|
||||
if (shadow->tbo.resource->mem_type != TTM_PL_TT ||
|
||||
if (!shadow->tbo.resource ||
|
||||
shadow->tbo.resource->mem_type != TTM_PL_TT ||
|
||||
shadow->tbo.resource->start == AMDGPU_BO_INVALID_OFFSET ||
|
||||
shadow->parent->tbo.resource->mem_type != TTM_PL_VRAM)
|
||||
continue;
|
||||
@@ -5235,7 +5236,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
* to put adev in the 1st position.
|
||||
*/
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) {
|
||||
if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1) && hive) {
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
|
||||
list_add_tail(&tmp_adev->reset_list, &device_list);
|
||||
if (gpu_reset_for_dev_remove && adev->shutdown)
|
||||
|
||||
@@ -1550,7 +1550,7 @@ static int amdgpu_discovery_get_mall_info(struct amdgpu_device *adev)
|
||||
break;
|
||||
case 2:
|
||||
mall_size_per_umc = le32_to_cpu(mall_info->v2.mall_size_per_umc);
|
||||
adev->gmc.mall_size = mall_size_per_umc * adev->gmc.num_umc;
|
||||
adev->gmc.mall_size = (uint64_t)mall_size_per_umc * adev->gmc.num_umc;
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
|
||||
@@ -179,7 +179,7 @@ static int __amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr,
|
||||
* Returns the number of bytes read/written; -errno on error.
|
||||
*/
|
||||
static int amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr,
|
||||
u8 *eeprom_buf, u16 buf_size, bool read)
|
||||
u8 *eeprom_buf, u32 buf_size, bool read)
|
||||
{
|
||||
const struct i2c_adapter_quirks *quirks = i2c_adap->quirks;
|
||||
u16 limit;
|
||||
@@ -225,7 +225,7 @@ static int amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr,
|
||||
|
||||
int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap,
|
||||
u32 eeprom_addr, u8 *eeprom_buf,
|
||||
u16 bytes)
|
||||
u32 bytes)
|
||||
{
|
||||
return amdgpu_eeprom_xfer(i2c_adap, eeprom_addr, eeprom_buf, bytes,
|
||||
true);
|
||||
@@ -233,7 +233,7 @@ int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap,
|
||||
|
||||
int amdgpu_eeprom_write(struct i2c_adapter *i2c_adap,
|
||||
u32 eeprom_addr, u8 *eeprom_buf,
|
||||
u16 bytes)
|
||||
u32 bytes)
|
||||
{
|
||||
return amdgpu_eeprom_xfer(i2c_adap, eeprom_addr, eeprom_buf, bytes,
|
||||
false);
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
|
||||
int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap,
|
||||
u32 eeprom_addr, u8 *eeprom_buf,
|
||||
u16 bytes);
|
||||
u32 bytes);
|
||||
|
||||
int amdgpu_eeprom_write(struct i2c_adapter *i2c_adap,
|
||||
u32 eeprom_addr, u8 *eeprom_buf,
|
||||
u16 bytes);
|
||||
u32 bytes);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <asm/set_memory.h>
|
||||
#endif
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_reset.h"
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/ttm/ttm_tt.h>
|
||||
|
||||
@@ -400,7 +401,10 @@ void amdgpu_gart_invalidate_tlb(struct amdgpu_device *adev)
|
||||
return;
|
||||
|
||||
mb();
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
if (down_read_trylock(&adev->reset_domain->sem)) {
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
up_read(&adev->reset_domain->sem);
|
||||
}
|
||||
for_each_set_bit(i, adev->vmhubs_mask, AMDGPU_MAX_VMHUBS)
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
|
||||
}
|
||||
|
||||
@@ -1336,6 +1336,9 @@ static void psp_xgmi_reflect_topology_info(struct psp_context *psp,
|
||||
uint8_t dst_num_links = node_info.num_links;
|
||||
|
||||
hive = amdgpu_get_xgmi_hive(psp->adev);
|
||||
if (WARN_ON(!hive))
|
||||
return;
|
||||
|
||||
list_for_each_entry(mirror_adev, &hive->device_list, gmc.xgmi.head) {
|
||||
struct psp_xgmi_topology_info *mirror_top_info;
|
||||
int j;
|
||||
|
||||
@@ -166,6 +166,9 @@ static ssize_t ta_if_load_debugfs_write(struct file *fp, const char *buf, size_t
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
|
||||
if (ta_bin_len > PSP_1_MEG)
|
||||
return -EINVAL;
|
||||
|
||||
copy_pos += sizeof(uint32_t);
|
||||
|
||||
ta_bin = kzalloc(ta_bin_len, GFP_KERNEL);
|
||||
|
||||
@@ -352,7 +352,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
|
||||
ring->max_dw = max_dw;
|
||||
ring->hw_prio = hw_prio;
|
||||
|
||||
if (!ring->no_scheduler) {
|
||||
if (!ring->no_scheduler && ring->funcs->type < AMDGPU_HW_IP_NUM) {
|
||||
hw_ip = ring->funcs->type;
|
||||
num_sched = &adev->gpu_sched[hw_ip][hw_prio].num_scheds;
|
||||
adev->gpu_sched[hw_ip][hw_prio].sched[(*num_sched)++] =
|
||||
@@ -469,8 +469,9 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_ring *ring = file_inode(f)->i_private;
|
||||
int r, i;
|
||||
uint32_t value, result, early[3];
|
||||
loff_t i;
|
||||
int r;
|
||||
|
||||
if (*pos & 3 || size & 3)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -135,6 +135,10 @@ static ssize_t amdgpu_securedisplay_debugfs_write(struct file *f, const char __u
|
||||
mutex_unlock(&psp->securedisplay_context.mutex);
|
||||
break;
|
||||
case 2:
|
||||
if (size < 3 || phy_id >= TA_SECUREDISPLAY_MAX_PHY) {
|
||||
dev_err(adev->dev, "Invalid input: %s\n", str);
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_lock(&psp->securedisplay_context.mutex);
|
||||
psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,
|
||||
TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);
|
||||
|
||||
@@ -135,6 +135,10 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
/* from vcn4 and above, only unified queue is used */
|
||||
adev->vcn.using_unified_queue =
|
||||
adev->ip_versions[UVD_HWIP][0] >= IP_VERSION(4, 0, 0);
|
||||
|
||||
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
|
||||
adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
|
||||
|
||||
@@ -259,18 +263,6 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* from vcn4 and above, only unified queue is used */
|
||||
static bool amdgpu_vcn_using_unified_queue(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
bool ret = false;
|
||||
|
||||
if (adev->ip_versions[UVD_HWIP][0] >= IP_VERSION(4, 0, 0))
|
||||
ret = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev, enum vcn_ring_type type, uint32_t vcn_instance)
|
||||
{
|
||||
bool ret = false;
|
||||
@@ -380,7 +372,9 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
|
||||
for (i = 0; i < adev->vcn.num_enc_rings; ++i)
|
||||
fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]);
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
|
||||
/* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
|
||||
!adev->vcn.using_unified_queue) {
|
||||
struct dpg_pause_state new_state;
|
||||
|
||||
if (fence[j] ||
|
||||
@@ -426,7 +420,9 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
|
||||
amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
|
||||
/* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
|
||||
!adev->vcn.using_unified_queue) {
|
||||
struct dpg_pause_state new_state;
|
||||
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) {
|
||||
@@ -452,8 +448,12 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
|
||||
|
||||
void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
|
||||
/* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */
|
||||
if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
|
||||
ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
|
||||
ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC &&
|
||||
!adev->vcn.using_unified_queue)
|
||||
atomic_dec(&ring->adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
|
||||
|
||||
atomic_dec(&ring->adev->vcn.total_submission_cnt);
|
||||
@@ -707,12 +707,11 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,
|
||||
struct amdgpu_job *job;
|
||||
struct amdgpu_ib *ib;
|
||||
uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);
|
||||
bool sq = amdgpu_vcn_using_unified_queue(ring);
|
||||
uint32_t *ib_checksum;
|
||||
uint32_t ib_pack_in_dw;
|
||||
int i, r;
|
||||
|
||||
if (sq)
|
||||
if (adev->vcn.using_unified_queue)
|
||||
ib_size_dw += 8;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
|
||||
@@ -725,7 +724,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,
|
||||
ib->length_dw = 0;
|
||||
|
||||
/* single queue headers */
|
||||
if (sq) {
|
||||
if (adev->vcn.using_unified_queue) {
|
||||
ib_pack_in_dw = sizeof(struct amdgpu_vcn_decode_buffer) / sizeof(uint32_t)
|
||||
+ 4 + 2; /* engine info + decoding ib in dw */
|
||||
ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, ib_pack_in_dw, false);
|
||||
@@ -744,7 +743,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,
|
||||
for (i = ib->length_dw; i < ib_size_dw; ++i)
|
||||
ib->ptr[i] = 0x0;
|
||||
|
||||
if (sq)
|
||||
if (adev->vcn.using_unified_queue)
|
||||
amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, ib_pack_in_dw);
|
||||
|
||||
r = amdgpu_job_submit_direct(job, ring, &f);
|
||||
@@ -834,15 +833,15 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand
|
||||
struct dma_fence **fence)
|
||||
{
|
||||
unsigned int ib_size_dw = 16;
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_job *job;
|
||||
struct amdgpu_ib *ib;
|
||||
struct dma_fence *f = NULL;
|
||||
uint32_t *ib_checksum = NULL;
|
||||
uint64_t addr;
|
||||
bool sq = amdgpu_vcn_using_unified_queue(ring);
|
||||
int i, r;
|
||||
|
||||
if (sq)
|
||||
if (adev->vcn.using_unified_queue)
|
||||
ib_size_dw += 8;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
|
||||
@@ -856,7 +855,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand
|
||||
|
||||
ib->length_dw = 0;
|
||||
|
||||
if (sq)
|
||||
if (adev->vcn.using_unified_queue)
|
||||
ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 0x11, true);
|
||||
|
||||
ib->ptr[ib->length_dw++] = 0x00000018;
|
||||
@@ -878,7 +877,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand
|
||||
for (i = ib->length_dw; i < ib_size_dw; ++i)
|
||||
ib->ptr[i] = 0x0;
|
||||
|
||||
if (sq)
|
||||
if (adev->vcn.using_unified_queue)
|
||||
amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 0x11);
|
||||
|
||||
r = amdgpu_job_submit_direct(job, ring, &f);
|
||||
@@ -901,15 +900,15 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han
|
||||
struct dma_fence **fence)
|
||||
{
|
||||
unsigned int ib_size_dw = 16;
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_job *job;
|
||||
struct amdgpu_ib *ib;
|
||||
struct dma_fence *f = NULL;
|
||||
uint32_t *ib_checksum = NULL;
|
||||
uint64_t addr;
|
||||
bool sq = amdgpu_vcn_using_unified_queue(ring);
|
||||
int i, r;
|
||||
|
||||
if (sq)
|
||||
if (adev->vcn.using_unified_queue)
|
||||
ib_size_dw += 8;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
|
||||
@@ -923,7 +922,7 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han
|
||||
|
||||
ib->length_dw = 0;
|
||||
|
||||
if (sq)
|
||||
if (adev->vcn.using_unified_queue)
|
||||
ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 0x11, true);
|
||||
|
||||
ib->ptr[ib->length_dw++] = 0x00000018;
|
||||
@@ -945,7 +944,7 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han
|
||||
for (i = ib->length_dw; i < ib_size_dw; ++i)
|
||||
ib->ptr[i] = 0x0;
|
||||
|
||||
if (sq)
|
||||
if (adev->vcn.using_unified_queue)
|
||||
amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 0x11);
|
||||
|
||||
r = amdgpu_job_submit_direct(job, ring, &f);
|
||||
|
||||
@@ -284,6 +284,7 @@ struct amdgpu_vcn {
|
||||
|
||||
uint16_t inst_mask;
|
||||
uint8_t num_inst_per_aid;
|
||||
bool using_unified_queue;
|
||||
};
|
||||
|
||||
struct amdgpu_fw_shared_rb_ptrs_struct {
|
||||
|
||||
@@ -615,7 +615,7 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev)
|
||||
vf2pf_info->dummy_page_addr = (uint64_t)adev->dummy_page_addr;
|
||||
vf2pf_info->checksum =
|
||||
amd_sriov_msg_checksum(
|
||||
vf2pf_info, vf2pf_info->header.size, 0, 0);
|
||||
vf2pf_info, sizeof(*vf2pf_info), 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -998,6 +998,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (amdgpu_device_skip_hw_access(adev))
|
||||
return 0;
|
||||
|
||||
reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl[xcc_id];
|
||||
scratch_reg0 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg0;
|
||||
scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1;
|
||||
@@ -1073,6 +1076,9 @@ void amdgpu_sriov_wreg(struct amdgpu_device *adev,
|
||||
{
|
||||
u32 rlcg_flag;
|
||||
|
||||
if (amdgpu_device_skip_hw_access(adev))
|
||||
return;
|
||||
|
||||
if (!amdgpu_sriov_runtime(adev) &&
|
||||
amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, true, &rlcg_flag)) {
|
||||
amdgpu_virt_rlcg_reg_rw(adev, offset, value, rlcg_flag, xcc_id);
|
||||
@@ -1090,6 +1096,9 @@ u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
|
||||
{
|
||||
u32 rlcg_flag;
|
||||
|
||||
if (amdgpu_device_skip_hw_access(adev))
|
||||
return 0;
|
||||
|
||||
if (!amdgpu_sriov_runtime(adev) &&
|
||||
amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, false, &rlcg_flag))
|
||||
return amdgpu_virt_rlcg_reg_rw(adev, offset, 0, rlcg_flag, xcc_id);
|
||||
|
||||
@@ -766,11 +766,15 @@ int amdgpu_vm_pde_update(struct amdgpu_vm_update_params *params,
|
||||
struct amdgpu_vm_bo_base *entry)
|
||||
{
|
||||
struct amdgpu_vm_bo_base *parent = amdgpu_vm_pt_parent(entry);
|
||||
struct amdgpu_bo *bo = parent->bo, *pbo;
|
||||
struct amdgpu_bo *bo, *pbo;
|
||||
struct amdgpu_vm *vm = params->vm;
|
||||
uint64_t pde, pt, flags;
|
||||
unsigned int level;
|
||||
|
||||
if (WARN_ON(!parent))
|
||||
return -EINVAL;
|
||||
|
||||
bo = parent->bo;
|
||||
for (level = 0, pbo = bo->parent; pbo; ++level)
|
||||
pbo = pbo->parent;
|
||||
|
||||
|
||||
@@ -500,6 +500,12 @@ static int aqua_vanjaram_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr,
|
||||
|
||||
if (mode == AMDGPU_AUTO_COMPUTE_PARTITION_MODE) {
|
||||
mode = __aqua_vanjaram_get_auto_mode(xcp_mgr);
|
||||
if (mode == AMDGPU_UNKNOWN_COMPUTE_PARTITION_MODE) {
|
||||
dev_err(adev->dev,
|
||||
"Invalid config, no compatible compute partition mode found, available memory partitions: %d",
|
||||
adev->gmc.num_mem_partitions);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (!__aqua_vanjaram_is_valid_mode(xcp_mgr, mode)) {
|
||||
dev_err(adev->dev,
|
||||
"Invalid compute partition mode requested, requested: %s, available memory partitions: %d",
|
||||
|
||||
@@ -70,6 +70,8 @@ static u32 df_v1_7_get_hbm_channel_number(struct amdgpu_device *adev)
|
||||
int fb_channel_number;
|
||||
|
||||
fb_channel_number = adev->df.funcs->get_fb_channel_number(adev);
|
||||
if (fb_channel_number >= ARRAY_SIZE(df_v1_7_channel_number))
|
||||
fb_channel_number = 0;
|
||||
|
||||
return df_v1_7_channel_number[fb_channel_number];
|
||||
}
|
||||
|
||||
@@ -7892,22 +7892,15 @@ static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev,
|
||||
static void gfx_v10_0_update_spm_vmid_internal(struct amdgpu_device *adev,
|
||||
unsigned int vmid)
|
||||
{
|
||||
u32 reg, data;
|
||||
u32 data;
|
||||
|
||||
/* not for *_SOC15 */
|
||||
reg = SOC15_REG_OFFSET(GC, 0, mmRLC_SPM_MC_CNTL);
|
||||
if (amdgpu_sriov_is_pp_one_vf(adev))
|
||||
data = RREG32_NO_KIQ(reg);
|
||||
else
|
||||
data = RREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL);
|
||||
data = RREG32_SOC15_NO_KIQ(GC, 0, mmRLC_SPM_MC_CNTL);
|
||||
|
||||
data &= ~RLC_SPM_MC_CNTL__RLC_SPM_VMID_MASK;
|
||||
data |= (vmid & RLC_SPM_MC_CNTL__RLC_SPM_VMID_MASK) << RLC_SPM_MC_CNTL__RLC_SPM_VMID__SHIFT;
|
||||
|
||||
if (amdgpu_sriov_is_pp_one_vf(adev))
|
||||
WREG32_SOC15_NO_KIQ(GC, 0, mmRLC_SPM_MC_CNTL, data);
|
||||
else
|
||||
WREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL, data);
|
||||
WREG32_SOC15_NO_KIQ(GC, 0, mmRLC_SPM_MC_CNTL, data);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_update_spm_vmid(struct amdgpu_device *adev, unsigned int vmid)
|
||||
|
||||
@@ -4961,23 +4961,16 @@ static int gfx_v11_0_update_gfx_clock_gating(struct amdgpu_device *adev,
|
||||
|
||||
static void gfx_v11_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid)
|
||||
{
|
||||
u32 reg, data;
|
||||
u32 data;
|
||||
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
|
||||
reg = SOC15_REG_OFFSET(GC, 0, regRLC_SPM_MC_CNTL);
|
||||
if (amdgpu_sriov_is_pp_one_vf(adev))
|
||||
data = RREG32_NO_KIQ(reg);
|
||||
else
|
||||
data = RREG32(reg);
|
||||
data = RREG32_SOC15_NO_KIQ(GC, 0, regRLC_SPM_MC_CNTL);
|
||||
|
||||
data &= ~RLC_SPM_MC_CNTL__RLC_SPM_VMID_MASK;
|
||||
data |= (vmid & RLC_SPM_MC_CNTL__RLC_SPM_VMID_MASK) << RLC_SPM_MC_CNTL__RLC_SPM_VMID__SHIFT;
|
||||
|
||||
if (amdgpu_sriov_is_pp_one_vf(adev))
|
||||
WREG32_SOC15_NO_KIQ(GC, 0, regRLC_SPM_MC_CNTL, data);
|
||||
else
|
||||
WREG32_SOC15(GC, 0, regRLC_SPM_MC_CNTL, data);
|
||||
WREG32_SOC15_NO_KIQ(GC, 0, regRLC_SPM_MC_CNTL, data);
|
||||
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_4_imu.bin");
|
||||
|
||||
static int imu_v11_0_init_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
char fw_name[40];
|
||||
char fw_name[45];
|
||||
char ucode_prefix[30];
|
||||
int err;
|
||||
const struct imu_firmware_header_v1_0 *imu_hdr;
|
||||
|
||||
@@ -543,11 +543,11 @@ void jpeg_v2_0_dec_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
|
||||
amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
amdgpu_ring_write(ring, (vmid | (vmid << 4)));
|
||||
amdgpu_ring_write(ring, (vmid | (vmid << 4) | (vmid << 8)));
|
||||
|
||||
amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
amdgpu_ring_write(ring, (vmid | (vmid << 4)));
|
||||
amdgpu_ring_write(ring, (vmid | (vmid << 4) | (vmid << 8)));
|
||||
|
||||
amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_jpeg.h"
|
||||
#include "amdgpu_cs.h"
|
||||
#include "soc15.h"
|
||||
#include "soc15d.h"
|
||||
#include "jpeg_v4_0_3.h"
|
||||
@@ -769,11 +770,15 @@ static void jpeg_v4_0_3_dec_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
|
||||
amdgpu_ring_write(ring, PACKETJ(regUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
amdgpu_ring_write(ring, (vmid | (vmid << 4)));
|
||||
|
||||
if (ring->funcs->parse_cs)
|
||||
amdgpu_ring_write(ring, 0);
|
||||
else
|
||||
amdgpu_ring_write(ring, (vmid | (vmid << 4) | (vmid << 8)));
|
||||
|
||||
amdgpu_ring_write(ring, PACKETJ(regUVD_LMI_JPEG_VMID_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
amdgpu_ring_write(ring, (vmid | (vmid << 4)));
|
||||
amdgpu_ring_write(ring, (vmid | (vmid << 4) | (vmid << 8)));
|
||||
|
||||
amdgpu_ring_write(ring, PACKETJ(regUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
@@ -1052,6 +1057,7 @@ static const struct amdgpu_ring_funcs jpeg_v4_0_3_dec_ring_vm_funcs = {
|
||||
.get_rptr = jpeg_v4_0_3_dec_ring_get_rptr,
|
||||
.get_wptr = jpeg_v4_0_3_dec_ring_get_wptr,
|
||||
.set_wptr = jpeg_v4_0_3_dec_ring_set_wptr,
|
||||
.parse_cs = jpeg_v4_0_3_dec_ring_parse_cs,
|
||||
.emit_frame_size =
|
||||
SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
|
||||
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
|
||||
@@ -1216,3 +1222,56 @@ static void jpeg_v4_0_3_set_ras_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->jpeg.ras = &jpeg_v4_0_3_ras;
|
||||
}
|
||||
|
||||
/**
|
||||
* jpeg_v4_0_3_dec_ring_parse_cs - command submission parser
|
||||
*
|
||||
* @parser: Command submission parser context
|
||||
* @job: the job to parse
|
||||
* @ib: the IB to parse
|
||||
*
|
||||
* Parse the command stream, return -EINVAL for invalid packet,
|
||||
* 0 otherwise
|
||||
*/
|
||||
int jpeg_v4_0_3_dec_ring_parse_cs(struct amdgpu_cs_parser *parser,
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_ib *ib)
|
||||
{
|
||||
uint32_t i, reg, res, cond, type;
|
||||
struct amdgpu_device *adev = parser->adev;
|
||||
|
||||
for (i = 0; i < ib->length_dw ; i += 2) {
|
||||
reg = CP_PACKETJ_GET_REG(ib->ptr[i]);
|
||||
res = CP_PACKETJ_GET_RES(ib->ptr[i]);
|
||||
cond = CP_PACKETJ_GET_COND(ib->ptr[i]);
|
||||
type = CP_PACKETJ_GET_TYPE(ib->ptr[i]);
|
||||
|
||||
if (res) /* only support 0 at the moment */
|
||||
return -EINVAL;
|
||||
|
||||
switch (type) {
|
||||
case PACKETJ_TYPE0:
|
||||
if (cond != PACKETJ_CONDITION_CHECK0 || reg < JPEG_REG_RANGE_START || reg > JPEG_REG_RANGE_END) {
|
||||
dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case PACKETJ_TYPE3:
|
||||
if (cond != PACKETJ_CONDITION_CHECK3 || reg < JPEG_REG_RANGE_START || reg > JPEG_REG_RANGE_END) {
|
||||
dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case PACKETJ_TYPE6:
|
||||
if (ib->ptr[i] == CP_PACKETJ_NOP)
|
||||
continue;
|
||||
dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]);
|
||||
return -EINVAL;
|
||||
default:
|
||||
dev_err(adev->dev, "Unknown packet type %d !\n", type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,12 @@
|
||||
|
||||
#define JRBC_DEC_EXTERNAL_REG_WRITE_ADDR 0x18000
|
||||
|
||||
#define JPEG_REG_RANGE_START 0x4000
|
||||
#define JPEG_REG_RANGE_END 0x41c2
|
||||
|
||||
extern const struct amdgpu_ip_block_version jpeg_v4_0_3_ip_block;
|
||||
|
||||
int jpeg_v4_0_3_dec_ring_parse_cs(struct amdgpu_cs_parser *parser,
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_ib *ib);
|
||||
#endif /* __JPEG_V4_0_3_H__ */
|
||||
|
||||
@@ -384,7 +384,7 @@ static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device
|
||||
else
|
||||
WREG32_SOC15(NBIO, 0, mmBIF_DOORBELL_INT_CNTL, bif_doorbell_intr_cntl);
|
||||
|
||||
if (!ras->disable_ras_err_cnt_harvest) {
|
||||
if (ras && !ras->disable_ras_err_cnt_harvest && obj) {
|
||||
/*
|
||||
* clear error status after ras_controller_intr
|
||||
* according to hw team and count ue number
|
||||
|
||||
@@ -76,6 +76,12 @@
|
||||
((cond & 0xF) << 24) | \
|
||||
((type & 0xF) << 28))
|
||||
|
||||
#define CP_PACKETJ_NOP 0x60000000
|
||||
#define CP_PACKETJ_GET_REG(x) ((x) & 0x3FFFF)
|
||||
#define CP_PACKETJ_GET_RES(x) (((x) >> 18) & 0x3F)
|
||||
#define CP_PACKETJ_GET_COND(x) (((x) >> 24) & 0xF)
|
||||
#define CP_PACKETJ_GET_TYPE(x) (((x) >> 28) & 0xF)
|
||||
|
||||
/* Packet 3 types */
|
||||
#define PACKET3_NOP 0x10
|
||||
#define PACKET3_SET_BASE 0x11
|
||||
|
||||
@@ -1432,17 +1432,23 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
|
||||
goto sync_memory_failed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush TLBs after waiting for the page table updates to complete */
|
||||
for (i = 0; i < args->n_devices; i++) {
|
||||
peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
|
||||
if (WARN_ON_ONCE(!peer_pdd))
|
||||
continue;
|
||||
if (flush_tlb)
|
||||
kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT);
|
||||
|
||||
/* Remove dma mapping after tlb flush to avoid IO_PAGE_FAULT */
|
||||
err = amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv);
|
||||
if (err)
|
||||
goto sync_memory_failed;
|
||||
}
|
||||
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
if (flush_tlb) {
|
||||
/* Flush TLBs after waiting for the page table updates to complete */
|
||||
for (i = 0; i < args->n_devices; i++) {
|
||||
peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
|
||||
if (WARN_ON_ONCE(!peer_pdd))
|
||||
continue;
|
||||
kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT);
|
||||
}
|
||||
}
|
||||
kfree(devices_arr);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -42,8 +42,6 @@
|
||||
#define CRAT_OEMTABLEID_LENGTH 8
|
||||
#define CRAT_RESERVED_LENGTH 6
|
||||
|
||||
#define CRAT_OEMID_64BIT_MASK ((1ULL << (CRAT_OEMID_LENGTH * 8)) - 1)
|
||||
|
||||
/* Compute Unit flags */
|
||||
#define COMPUTE_UNIT_CPU (1 << 0) /* Create Virtual CRAT for CPU */
|
||||
#define COMPUTE_UNIT_GPU (1 << 1) /* Create Virtual CRAT for GPU */
|
||||
|
||||
@@ -103,7 +103,8 @@ void debug_event_write_work_handler(struct work_struct *work)
|
||||
struct kfd_process,
|
||||
debug_event_workarea);
|
||||
|
||||
kernel_write(process->dbg_ev_file, &write_data, 1, &pos);
|
||||
if (process->debug_trap_enabled && process->dbg_ev_file)
|
||||
kernel_write(process->dbg_ev_file, &write_data, 1, &pos);
|
||||
}
|
||||
|
||||
/* update process/device/queue exception status, write to descriptor
|
||||
@@ -645,6 +646,7 @@ int kfd_dbg_trap_disable(struct kfd_process *target)
|
||||
else if (target->runtime_info.runtime_state != DEBUG_RUNTIME_STATE_DISABLED)
|
||||
target->runtime_info.runtime_state = DEBUG_RUNTIME_STATE_ENABLED;
|
||||
|
||||
cancel_work_sync(&target->debug_event_workarea);
|
||||
fput(target->dbg_ev_file);
|
||||
target->dbg_ev_file = NULL;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "kfd_priv.h"
|
||||
#include "kfd_kernel_queue.h"
|
||||
#include "amdgpu_amdkfd.h"
|
||||
#include "amdgpu_reset.h"
|
||||
|
||||
static inline struct process_queue_node *get_queue_by_qid(
|
||||
struct process_queue_manager *pqm, unsigned int qid)
|
||||
@@ -87,8 +88,12 @@ void kfd_process_dequeue_from_device(struct kfd_process_device *pdd)
|
||||
return;
|
||||
|
||||
dev->dqm->ops.process_termination(dev->dqm, &pdd->qpd);
|
||||
if (dev->kfd->shared_resources.enable_mes)
|
||||
amdgpu_mes_flush_shader_debugger(dev->adev, pdd->proc_ctx_gpu_addr);
|
||||
if (dev->kfd->shared_resources.enable_mes &&
|
||||
down_read_trylock(&dev->adev->reset_domain->sem)) {
|
||||
amdgpu_mes_flush_shader_debugger(dev->adev,
|
||||
pdd->proc_ctx_gpu_addr);
|
||||
up_read(&dev->adev->reset_domain->sem);
|
||||
}
|
||||
pdd->already_dequeued = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -958,8 +958,7 @@ static void kfd_update_system_properties(void)
|
||||
dev = list_last_entry(&topology_device_list,
|
||||
struct kfd_topology_device, list);
|
||||
if (dev) {
|
||||
sys_props.platform_id =
|
||||
(*((uint64_t *)dev->oem_id)) & CRAT_OEMID_64BIT_MASK;
|
||||
sys_props.platform_id = dev->oem_id64;
|
||||
sys_props.platform_oem = *((uint64_t *)dev->oem_table_id);
|
||||
sys_props.platform_rev = dev->oem_revision;
|
||||
}
|
||||
|
||||
@@ -154,7 +154,10 @@ struct kfd_topology_device {
|
||||
struct attribute attr_gpuid;
|
||||
struct attribute attr_name;
|
||||
struct attribute attr_props;
|
||||
uint8_t oem_id[CRAT_OEMID_LENGTH];
|
||||
union {
|
||||
uint8_t oem_id[CRAT_OEMID_LENGTH];
|
||||
uint64_t oem_id64;
|
||||
};
|
||||
uint8_t oem_table_id[CRAT_OEMTABLEID_LENGTH];
|
||||
uint32_t oem_revision;
|
||||
};
|
||||
|
||||
@@ -4357,7 +4357,10 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||
|
||||
/* There is one primary plane per CRTC */
|
||||
primary_planes = dm->dc->caps.max_streams;
|
||||
ASSERT(primary_planes <= AMDGPU_MAX_PLANES);
|
||||
if (primary_planes > AMDGPU_MAX_PLANES) {
|
||||
DRM_ERROR("DM: Plane nums out of 6 planes\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize primary planes, implicit planes for legacy IOCTLS.
|
||||
@@ -8283,15 +8286,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
bundle->stream_update.vrr_infopacket =
|
||||
&acrtc_state->stream->vrr_infopacket;
|
||||
}
|
||||
} else if (cursor_update && acrtc_state->active_planes > 0 &&
|
||||
acrtc_attach->base.state->event) {
|
||||
drm_crtc_vblank_get(pcrtc);
|
||||
|
||||
} else if (cursor_update && acrtc_state->active_planes > 0) {
|
||||
spin_lock_irqsave(&pcrtc->dev->event_lock, flags);
|
||||
|
||||
acrtc_attach->event = acrtc_attach->base.state->event;
|
||||
acrtc_attach->base.state->event = NULL;
|
||||
|
||||
if (acrtc_attach->base.state->event) {
|
||||
drm_crtc_vblank_get(pcrtc);
|
||||
acrtc_attach->event = acrtc_attach->base.state->event;
|
||||
acrtc_attach->base.state->event = NULL;
|
||||
}
|
||||
spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
#define AMDGPU_DM_MAX_NUM_EDP 2
|
||||
|
||||
#define AMDGPU_DMUB_NOTIFICATION_MAX 5
|
||||
#define AMDGPU_DMUB_NOTIFICATION_MAX 6
|
||||
|
||||
#define HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_IEEE_REGISTRATION_ID 0x00001A
|
||||
#define AMD_VSDB_VERSION_3_FEATURECAP_REPLAYMODE 0x40
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <drm/drm_blend.h>
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <drm/drm_gem_framebuffer_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "amdgpu.h"
|
||||
@@ -848,10 +849,14 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
|
||||
}
|
||||
|
||||
afb = to_amdgpu_framebuffer(new_state->fb);
|
||||
obj = new_state->fb->obj[0];
|
||||
obj = drm_gem_fb_get_obj(new_state->fb, 0);
|
||||
if (!obj) {
|
||||
DRM_ERROR("Failed to get obj from framebuffer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rbo = gem_to_amdgpu_bo(obj);
|
||||
adev = amdgpu_ttm_adev(rbo->tbo.bdev);
|
||||
|
||||
r = amdgpu_bo_reserve(rbo, true);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
|
||||
|
||||
@@ -667,6 +667,9 @@ static enum bp_result get_ss_info_v3_1(
|
||||
ss_table_header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base,
|
||||
DATA_TABLES(ASIC_InternalSS_Info),
|
||||
struct_size(ss_table_header_include, asSpreadSpectrum, 1)));
|
||||
if (!ss_table_header_include)
|
||||
return BP_RESULT_UNSUPPORTED;
|
||||
|
||||
table_size =
|
||||
(le16_to_cpu(ss_table_header_include->sHeader.usStructureSize)
|
||||
- sizeof(ATOM_COMMON_TABLE_HEADER))
|
||||
@@ -1036,6 +1039,8 @@ static enum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1(
|
||||
&bp->base,
|
||||
DATA_TABLES(ASIC_InternalSS_Info),
|
||||
struct_size(header, asSpreadSpectrum, 1)));
|
||||
if (!header)
|
||||
return result;
|
||||
|
||||
memset(info, 0, sizeof(struct spread_spectrum_info));
|
||||
|
||||
@@ -1109,6 +1114,8 @@ static enum bp_result get_ss_info_from_ss_info_table(
|
||||
get_atom_data_table_revision(header, &revision);
|
||||
|
||||
tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, DATA_TABLES(SS_Info));
|
||||
if (!tbl)
|
||||
return result;
|
||||
|
||||
if (1 != revision.major || 2 > revision.minor)
|
||||
return result;
|
||||
@@ -1636,6 +1643,8 @@ static uint32_t get_ss_entry_number_from_ss_info_tbl(
|
||||
|
||||
tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO,
|
||||
DATA_TABLES(SS_Info));
|
||||
if (!tbl)
|
||||
return number;
|
||||
|
||||
if (1 != revision.major || 2 > revision.minor)
|
||||
return number;
|
||||
@@ -1718,6 +1727,8 @@ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_v2_1(
|
||||
&bp->base,
|
||||
DATA_TABLES(ASIC_InternalSS_Info),
|
||||
struct_size(header_include, asSpreadSpectrum, 1)));
|
||||
if (!header_include)
|
||||
return 0;
|
||||
|
||||
size = (le16_to_cpu(header_include->sHeader.usStructureSize)
|
||||
- sizeof(ATOM_COMMON_TABLE_HEADER))
|
||||
@@ -1756,6 +1767,9 @@ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_V3_1(
|
||||
header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base,
|
||||
DATA_TABLES(ASIC_InternalSS_Info),
|
||||
struct_size(header_include, asSpreadSpectrum, 1)));
|
||||
if (!header_include)
|
||||
return number;
|
||||
|
||||
size = (le16_to_cpu(header_include->sHeader.usStructureSize) -
|
||||
sizeof(ATOM_COMMON_TABLE_HEADER)) /
|
||||
sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3);
|
||||
@@ -2552,8 +2566,8 @@ static enum bp_result construct_integrated_info(
|
||||
|
||||
/* Sort voltage table from low to high*/
|
||||
if (result == BP_RESULT_OK) {
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
int32_t i;
|
||||
int32_t j;
|
||||
|
||||
for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
|
||||
for (j = i; j > 0; --j) {
|
||||
|
||||
@@ -2935,8 +2935,11 @@ static enum bp_result construct_integrated_info(
|
||||
struct atom_common_table_header *header;
|
||||
struct atom_data_revision revision;
|
||||
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
int32_t i;
|
||||
int32_t j;
|
||||
|
||||
if (!info)
|
||||
return result;
|
||||
|
||||
if (info && DATA_TABLES(integratedsysteminfo)) {
|
||||
header = GET_IMAGE(struct atom_common_table_header,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user