mirror of https://gitee.com/openkylin/linux.git
Merge drm/drm-next into drm-misc-next
4.19 is out, Lyude asked for a backmerge, and it's been a while. All very good reasons on their own :-) Signed-off-by: Sean Paul <seanpaul@chromium.org>
This commit is contained in:
commit
6542e9adc0
|
@ -21,6 +21,9 @@ Required properties:
|
|||
- samsung,pll-clock-frequency: specifies frequency of the oscillator clock
|
||||
- #address-cells, #size-cells: should be set respectively to <1> and <0>
|
||||
according to DSI host bindings (see MIPI DSI bindings [1])
|
||||
- samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst
|
||||
mode
|
||||
- samsung,esc-clock-frequency: specifies DSI frequency in escape mode
|
||||
|
||||
Optional properties:
|
||||
- power-domains: a phandle to DSIM power domain node
|
||||
|
@ -29,25 +32,9 @@ Child nodes:
|
|||
Should contain DSI peripheral nodes (see MIPI DSI bindings [1]).
|
||||
|
||||
Video interfaces:
|
||||
Device node can contain video interface port nodes according to [2].
|
||||
The following are properties specific to those nodes:
|
||||
|
||||
port node inbound:
|
||||
- reg: (required) must be 0.
|
||||
port node outbound:
|
||||
- reg: (required) must be 1.
|
||||
|
||||
endpoint node connected from mic node (reg = 0):
|
||||
- remote-endpoint: specifies the endpoint in mic node. This node is required
|
||||
for Exynos5433 mipi dsi. So mic can access to panel node
|
||||
throughout this dsi node.
|
||||
endpoint node connected to panel node (reg = 1):
|
||||
- remote-endpoint: specifies the endpoint in panel node. This node is
|
||||
required in all kinds of exynos mipi dsi to represent
|
||||
the connection between mipi dsi and panel.
|
||||
- samsung,burst-clock-frequency: specifies DSI frequency in high-speed burst
|
||||
mode
|
||||
- samsung,esc-clock-frequency: specifies DSI frequency in escape mode
|
||||
Device node can contain following video interface port nodes according to [2]:
|
||||
0: RGB input,
|
||||
1: DSI output
|
||||
|
||||
[1]: Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
|
||||
[2]: Documentation/devicetree/bindings/media/video-interfaces.txt
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Device-Tree bindings for input/gpio_keys.c keyboard driver
|
||||
Device-Tree bindings for input/keyboard/gpio_keys.c keyboard driver
|
||||
|
||||
Required properties:
|
||||
- compatible = "gpio-keys";
|
||||
|
|
|
@ -33,4 +33,3 @@ Video Function Calls
|
|||
video-clear-buffer
|
||||
video-set-streamtype
|
||||
video-set-format
|
||||
video-set-attributes
|
||||
|
|
24
MAINTAINERS
24
MAINTAINERS
|
@ -4761,8 +4761,8 @@ F: include/uapi/drm/
|
|||
F: include/linux/vga*
|
||||
|
||||
DRM DRIVERS AND MISC GPU PATCHES
|
||||
M: Gustavo Padovan <gustavo@padovan.org>
|
||||
M: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
|
||||
M: Maxime Ripard <maxime.ripard@bootlin.com>
|
||||
M: Sean Paul <sean@poorly.run>
|
||||
W: https://01.org/linuxgraphics/gfx-docs/maintainer-tools/drm-misc.html
|
||||
S: Maintained
|
||||
|
@ -9727,13 +9727,6 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
|
|||
S: Maintained
|
||||
F: drivers/media/dvb-frontends/mn88473*
|
||||
|
||||
PCI DRIVER FOR MOBIVEIL PCIE IP
|
||||
M: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
|
||||
F: drivers/pci/controller/pcie-mobiveil.c
|
||||
|
||||
MODULE SUPPORT
|
||||
M: Jessica Yu <jeyu@kernel.org>
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux.git modules-next
|
||||
|
@ -10963,7 +10956,7 @@ M: Willy Tarreau <willy@haproxy.com>
|
|||
M: Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
|
||||
S: Odd Fixes
|
||||
F: Documentation/auxdisplay/lcd-panel-cgram.txt
|
||||
F: drivers/misc/panel.c
|
||||
F: drivers/auxdisplay/panel.c
|
||||
|
||||
PARALLEL PORT SUBSYSTEM
|
||||
M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
|
||||
|
@ -11151,6 +11144,13 @@ F: include/uapi/linux/switchtec_ioctl.h
|
|||
F: include/linux/switchtec.h
|
||||
F: drivers/ntb/hw/mscc/
|
||||
|
||||
PCI DRIVER FOR MOBIVEIL PCIE IP
|
||||
M: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
|
||||
F: drivers/pci/controller/pcie-mobiveil.c
|
||||
|
||||
PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
|
||||
M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
M: Jason Cooper <jason@lakedaemon.net>
|
||||
|
@ -11217,8 +11217,14 @@ F: tools/pci/
|
|||
|
||||
PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC
|
||||
M: Russell Currey <ruscur@russell.cc>
|
||||
M: Sam Bobroff <sbobroff@linux.ibm.com>
|
||||
M: Oliver O'Halloran <oohall@gmail.com>
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
S: Supported
|
||||
F: Documentation/PCI/pci-error-recovery.txt
|
||||
F: drivers/pci/pcie/aer.c
|
||||
F: drivers/pci/pcie/dpc.c
|
||||
F: drivers/pci/pcie/err.c
|
||||
F: Documentation/powerpc/eeh-pci-error-recovery.txt
|
||||
F: arch/powerpc/kernel/eeh*.c
|
||||
F: arch/powerpc/platforms/*/eeh*.c
|
||||
|
|
2
Makefile
2
Makefile
|
@ -2,7 +2,7 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 19
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc5
|
||||
EXTRAVERSION = -rc6
|
||||
NAME = Merciless Moray
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -9,6 +9,7 @@ extern void ppc_printk_progress(char *s, unsigned short hex);
|
|||
|
||||
extern unsigned int rtas_data;
|
||||
extern unsigned long long memory_limit;
|
||||
extern bool init_mem_is_free;
|
||||
extern unsigned long klimit;
|
||||
extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
|
||||
|
||||
|
|
|
@ -1314,9 +1314,7 @@ EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100)
|
|||
|
||||
#ifdef CONFIG_PPC_DENORMALISATION
|
||||
mfspr r10,SPRN_HSRR1
|
||||
mfspr r11,SPRN_HSRR0 /* save HSRR0 */
|
||||
andis. r10,r10,(HSRR1_DENORM)@h /* denorm? */
|
||||
addi r11,r11,-4 /* HSRR0 is next instruction */
|
||||
bne+ denorm_assist
|
||||
#endif
|
||||
|
||||
|
@ -1382,6 +1380,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
|
|||
*/
|
||||
XVCPSGNDP32(32)
|
||||
denorm_done:
|
||||
mfspr r11,SPRN_HSRR0
|
||||
subi r11,r11,4
|
||||
mtspr SPRN_HSRR0,r11
|
||||
mtcrf 0x80,r9
|
||||
ld r9,PACA_EXGEN+EX_R9(r13)
|
||||
|
|
|
@ -176,13 +176,27 @@ _GLOBAL(tm_reclaim)
|
|||
std r1, PACATMSCRATCH(r13)
|
||||
ld r1, PACAR1(r13)
|
||||
|
||||
/* Store the PPR in r11 and reset to decent value */
|
||||
std r11, GPR11(r1) /* Temporary stash */
|
||||
|
||||
/*
|
||||
* Move the saved user r1 to the kernel stack in case PACATMSCRATCH is
|
||||
* clobbered by an exception once we turn on MSR_RI below.
|
||||
*/
|
||||
ld r11, PACATMSCRATCH(r13)
|
||||
std r11, GPR1(r1)
|
||||
|
||||
/*
|
||||
* Store r13 away so we can free up the scratch SPR for the SLB fault
|
||||
* handler (needed once we start accessing the thread_struct).
|
||||
*/
|
||||
GET_SCRATCH0(r11)
|
||||
std r11, GPR13(r1)
|
||||
|
||||
/* Reset MSR RI so we can take SLB faults again */
|
||||
li r11, MSR_RI
|
||||
mtmsrd r11, 1
|
||||
|
||||
/* Store the PPR in r11 and reset to decent value */
|
||||
mfspr r11, SPRN_PPR
|
||||
HMT_MEDIUM
|
||||
|
||||
|
@ -207,11 +221,11 @@ _GLOBAL(tm_reclaim)
|
|||
SAVE_GPR(8, r7) /* user r8 */
|
||||
SAVE_GPR(9, r7) /* user r9 */
|
||||
SAVE_GPR(10, r7) /* user r10 */
|
||||
ld r3, PACATMSCRATCH(r13) /* user r1 */
|
||||
ld r3, GPR1(r1) /* user r1 */
|
||||
ld r4, GPR7(r1) /* user r7 */
|
||||
ld r5, GPR11(r1) /* user r11 */
|
||||
ld r6, GPR12(r1) /* user r12 */
|
||||
GET_SCRATCH0(8) /* user r13 */
|
||||
ld r8, GPR13(r1) /* user r13 */
|
||||
std r3, GPR1(r7)
|
||||
std r4, GPR7(r7)
|
||||
std r5, GPR11(r7)
|
||||
|
|
|
@ -443,6 +443,9 @@ _GLOBAL(csum_ipv6_magic)
|
|||
addc r0, r8, r9
|
||||
ld r10, 0(r4)
|
||||
ld r11, 8(r4)
|
||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
rotldi r5, r5, 8
|
||||
#endif
|
||||
adde r0, r0, r10
|
||||
add r5, r5, r7
|
||||
adde r0, r0, r11
|
||||
|
|
|
@ -28,6 +28,12 @@ static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
|
|||
{
|
||||
int err;
|
||||
|
||||
/* Make sure we aren't patching a freed init section */
|
||||
if (init_mem_is_free && init_section_contains(exec_addr, 4)) {
|
||||
pr_debug("Skipping init section patching addr: 0x%px\n", exec_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__put_user_size(instr, patch_addr, 4, err);
|
||||
if (err)
|
||||
return err;
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#endif
|
||||
|
||||
unsigned long long memory_limit;
|
||||
bool init_mem_is_free;
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
pte_t *kmap_pte;
|
||||
|
@ -396,6 +397,7 @@ void free_initmem(void)
|
|||
{
|
||||
ppc_md.progress = ppc_printk_progress;
|
||||
mark_initmem_nx();
|
||||
init_mem_is_free = true;
|
||||
free_initmem_default(POISON_FREE_INITMEM);
|
||||
}
|
||||
|
||||
|
|
|
@ -1204,7 +1204,9 @@ int find_and_online_cpu_nid(int cpu)
|
|||
int new_nid;
|
||||
|
||||
/* Use associativity from first thread for all siblings */
|
||||
vphn_get_associativity(cpu, associativity);
|
||||
if (vphn_get_associativity(cpu, associativity))
|
||||
return cpu_to_node(cpu);
|
||||
|
||||
new_nid = associativity_to_nid(associativity);
|
||||
if (new_nid < 0 || !node_possible(new_nid))
|
||||
new_nid = first_online_node;
|
||||
|
@ -1452,7 +1454,8 @@ static struct timer_list topology_timer;
|
|||
|
||||
static void reset_topology_timer(void)
|
||||
{
|
||||
mod_timer(&topology_timer, jiffies + topology_timer_secs * HZ);
|
||||
if (vphn_enabled)
|
||||
mod_timer(&topology_timer, jiffies + topology_timer_secs * HZ);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
|
|
@ -45,7 +45,7 @@ static void scan_pkey_feature(void)
|
|||
* Since any pkey can be used for data or execute, we will just treat
|
||||
* all keys as equal and track them as one entity.
|
||||
*/
|
||||
pkeys_total = be32_to_cpu(vals[0]);
|
||||
pkeys_total = vals[0];
|
||||
pkeys_devtree_defined = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -276,7 +276,7 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
|
|||
level_shift = entries_shift + 3;
|
||||
level_shift = max_t(unsigned int, level_shift, PAGE_SHIFT);
|
||||
|
||||
if ((level_shift - 3) * levels + page_shift >= 60)
|
||||
if ((level_shift - 3) * levels + page_shift >= 55)
|
||||
return -EINVAL;
|
||||
|
||||
/* Allocate TCE table */
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_RISCV_PROTOTYPES_H
|
||||
|
||||
#include <linux/ftrace.h>
|
||||
#include <asm-generic/asm-prototypes.h>
|
||||
|
||||
#endif /* _ASM_RISCV_PROTOTYPES_H */
|
|
@ -25,20 +25,6 @@ ENTRY(get_sev_encryption_bit)
|
|||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
push %edi
|
||||
|
||||
/*
|
||||
* RIP-relative addressing is needed to access the encryption bit
|
||||
* variable. Since we are running in 32-bit mode we need this call/pop
|
||||
* sequence to get the proper relative addressing.
|
||||
*/
|
||||
call 1f
|
||||
1: popl %edi
|
||||
subl $1b, %edi
|
||||
|
||||
movl enc_bit(%edi), %eax
|
||||
cmpl $0, %eax
|
||||
jge .Lsev_exit
|
||||
|
||||
/* Check if running under a hypervisor */
|
||||
movl $1, %eax
|
||||
|
@ -69,15 +55,12 @@ ENTRY(get_sev_encryption_bit)
|
|||
|
||||
movl %ebx, %eax
|
||||
andl $0x3f, %eax /* Return the encryption bit location */
|
||||
movl %eax, enc_bit(%edi)
|
||||
jmp .Lsev_exit
|
||||
|
||||
.Lno_sev:
|
||||
xor %eax, %eax
|
||||
movl %eax, enc_bit(%edi)
|
||||
|
||||
.Lsev_exit:
|
||||
pop %edi
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
|
@ -113,8 +96,6 @@ ENTRY(set_sev_encryption_mask)
|
|||
ENDPROC(set_sev_encryption_mask)
|
||||
|
||||
.data
|
||||
enc_bit:
|
||||
.int 0xffffffff
|
||||
|
||||
#ifdef CONFIG_AMD_MEM_ENCRYPT
|
||||
.balign 8
|
||||
|
|
|
@ -322,16 +322,11 @@ void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn,
|
|||
|
||||
/*
|
||||
* __blk_mq_update_nr_hw_queues will update the nr_hw_queues and
|
||||
* queue_hw_ctx after freeze the queue. So we could use q_usage_counter
|
||||
* to avoid race with it. __blk_mq_update_nr_hw_queues will users
|
||||
* synchronize_rcu to ensure all of the users go out of the critical
|
||||
* section below and see zeroed q_usage_counter.
|
||||
* queue_hw_ctx after freeze the queue, so we use q_usage_counter
|
||||
* to avoid race with it.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
if (percpu_ref_is_zero(&q->q_usage_counter)) {
|
||||
rcu_read_unlock();
|
||||
if (!percpu_ref_tryget(&q->q_usage_counter))
|
||||
return;
|
||||
}
|
||||
|
||||
queue_for_each_hw_ctx(q, hctx, i) {
|
||||
struct blk_mq_tags *tags = hctx->tags;
|
||||
|
@ -347,7 +342,7 @@ void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn,
|
|||
bt_for_each(hctx, &tags->breserved_tags, fn, priv, true);
|
||||
bt_for_each(hctx, &tags->bitmap_tags, fn, priv, false);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
blk_queue_exit(q);
|
||||
}
|
||||
|
||||
static int bt_alloc(struct sbitmap_queue *bt, unsigned int depth,
|
||||
|
|
|
@ -1628,7 +1628,7 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule)
|
|||
BUG_ON(!rq->q);
|
||||
if (rq->mq_ctx != this_ctx) {
|
||||
if (this_ctx) {
|
||||
trace_block_unplug(this_q, depth, from_schedule);
|
||||
trace_block_unplug(this_q, depth, !from_schedule);
|
||||
blk_mq_sched_insert_requests(this_q, this_ctx,
|
||||
&ctx_list,
|
||||
from_schedule);
|
||||
|
@ -1648,7 +1648,7 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule)
|
|||
* on 'ctx_list'. Do those.
|
||||
*/
|
||||
if (this_ctx) {
|
||||
trace_block_unplug(this_q, depth, from_schedule);
|
||||
trace_block_unplug(this_q, depth, !from_schedule);
|
||||
blk_mq_sched_insert_requests(this_q, this_ctx, &ctx_list,
|
||||
from_schedule);
|
||||
}
|
||||
|
|
|
@ -609,7 +609,7 @@ void elv_drain_elevator(struct request_queue *q)
|
|||
|
||||
while (e->type->ops.sq.elevator_dispatch_fn(q, 1))
|
||||
;
|
||||
if (q->nr_sorted && printed++ < 10) {
|
||||
if (q->nr_sorted && !blk_queue_is_zoned(q) && printed++ < 10 ) {
|
||||
printk(KERN_ERR "%s: forced dispatching is broken "
|
||||
"(nr_sorted=%u), please report this\n",
|
||||
q->elevator->type->elevator_name, q->nr_sorted);
|
||||
|
|
|
@ -2670,8 +2670,8 @@ static void purge_persistent_grants(struct blkfront_info *info)
|
|||
list_del(&gnt_list_entry->node);
|
||||
gnttab_end_foreign_access(gnt_list_entry->gref, 0, 0UL);
|
||||
rinfo->persistent_gnts_c--;
|
||||
__free_page(gnt_list_entry->page);
|
||||
kfree(gnt_list_entry);
|
||||
gnt_list_entry->gref = GRANT_INVALID_REF;
|
||||
list_add_tail(&gnt_list_entry->node, &rinfo->grants);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
|
||||
|
|
|
@ -180,26 +180,29 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node)
|
|||
data->base = of_iomap(node, 0);
|
||||
if (!data->base) {
|
||||
pr_err("Could not map PIT address\n");
|
||||
return -ENXIO;
|
||||
ret = -ENXIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data->mck = of_clk_get(node, 0);
|
||||
if (IS_ERR(data->mck)) {
|
||||
pr_err("Unable to get mck clk\n");
|
||||
return PTR_ERR(data->mck);
|
||||
ret = PTR_ERR(data->mck);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(data->mck);
|
||||
if (ret) {
|
||||
pr_err("Unable to enable mck\n");
|
||||
return ret;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Get the interrupts property */
|
||||
data->irq = irq_of_parse_and_map(node, 0);
|
||||
if (!data->irq) {
|
||||
pr_err("Unable to get IRQ from DT\n");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -227,7 +230,7 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node)
|
|||
ret = clocksource_register_hz(&data->clksrc, pit_rate);
|
||||
if (ret) {
|
||||
pr_err("Failed to register clocksource\n");
|
||||
return ret;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Set up irq handler */
|
||||
|
@ -236,7 +239,8 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node)
|
|||
"at91_tick", data);
|
||||
if (ret) {
|
||||
pr_err("Unable to setup IRQ\n");
|
||||
return ret;
|
||||
clocksource_unregister(&data->clksrc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Set up and register clockevents */
|
||||
|
@ -254,6 +258,10 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node)
|
|||
clockevents_register_device(&data->clkevt);
|
||||
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
TIMER_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit",
|
||||
at91sam926x_pit_dt_init);
|
||||
|
|
|
@ -130,13 +130,17 @@ static int fttmr010_timer_set_next_event(unsigned long cycles,
|
|||
cr &= ~fttmr010->t1_enable_val;
|
||||
writel(cr, fttmr010->base + TIMER_CR);
|
||||
|
||||
/* Setup the match register forward/backward in time */
|
||||
cr = readl(fttmr010->base + TIMER1_COUNT);
|
||||
if (fttmr010->count_down)
|
||||
cr -= cycles;
|
||||
else
|
||||
cr += cycles;
|
||||
writel(cr, fttmr010->base + TIMER1_MATCH1);
|
||||
if (fttmr010->count_down) {
|
||||
/*
|
||||
* ASPEED Timer Controller will load TIMER1_LOAD register
|
||||
* into TIMER1_COUNT register when the timer is re-enabled.
|
||||
*/
|
||||
writel(cycles, fttmr010->base + TIMER1_LOAD);
|
||||
} else {
|
||||
/* Setup the match register forward in time */
|
||||
cr = readl(fttmr010->base + TIMER1_COUNT);
|
||||
writel(cr + cycles, fttmr010->base + TIMER1_MATCH1);
|
||||
}
|
||||
|
||||
/* Start */
|
||||
cr = readl(fttmr010->base + TIMER_CR);
|
||||
|
|
|
@ -97,6 +97,9 @@ static int __init ti_32k_timer_init(struct device_node *np)
|
|||
return -ENXIO;
|
||||
}
|
||||
|
||||
if (!of_machine_is_compatible("ti,am43"))
|
||||
ti_32k_timer.cs.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
|
||||
|
||||
ti_32k_timer.counter = ti_32k_timer.base;
|
||||
|
||||
/*
|
||||
|
|
|
@ -44,7 +44,7 @@ enum _msm8996_version {
|
|||
|
||||
struct platform_device *cpufreq_dt_pdev, *kryo_cpufreq_pdev;
|
||||
|
||||
static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
|
||||
static enum _msm8996_version qcom_cpufreq_kryo_get_msm_id(void)
|
||||
{
|
||||
size_t len;
|
||||
u32 *msm_id;
|
||||
|
@ -222,7 +222,7 @@ static int __init qcom_cpufreq_kryo_init(void)
|
|||
}
|
||||
module_init(qcom_cpufreq_kryo_init);
|
||||
|
||||
static void __init qcom_cpufreq_kryo_exit(void)
|
||||
static void __exit qcom_cpufreq_kryo_exit(void)
|
||||
{
|
||||
platform_device_unregister(kryo_cpufreq_pdev);
|
||||
platform_driver_unregister(&qcom_cpufreq_kryo_driver);
|
||||
|
|
|
@ -535,6 +535,11 @@ static unsigned long dax_get_unmapped_area(struct file *filp,
|
|||
return current->mm->get_unmapped_area(filp, addr, len, pgoff, flags);
|
||||
}
|
||||
|
||||
static const struct address_space_operations dev_dax_aops = {
|
||||
.set_page_dirty = noop_set_page_dirty,
|
||||
.invalidatepage = noop_invalidatepage,
|
||||
};
|
||||
|
||||
static int dax_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct dax_device *dax_dev = inode_dax(inode);
|
||||
|
@ -544,6 +549,7 @@ static int dax_open(struct inode *inode, struct file *filp)
|
|||
dev_dbg(&dev_dax->dev, "trace\n");
|
||||
inode->i_mapping = __dax_inode->i_mapping;
|
||||
inode->i_mapping->host = __dax_inode;
|
||||
inode->i_mapping->a_ops = &dev_dax_aops;
|
||||
filp->f_mapping = inode->i_mapping;
|
||||
filp->f_wb_err = filemap_sample_wb_err(filp->f_mapping);
|
||||
filp->private_data = dev_dax;
|
||||
|
|
|
@ -110,6 +110,26 @@ config DRM_FBDEV_OVERALLOC
|
|||
is 100. Typical values for double buffering will be 200,
|
||||
triple buffering 300.
|
||||
|
||||
config DRM_FBDEV_LEAK_PHYS_SMEM
|
||||
bool "Shamelessly allow leaking of fbdev physical address (DANGEROUS)"
|
||||
depends on DRM_FBDEV_EMULATION && EXPERT
|
||||
default n
|
||||
help
|
||||
In order to keep user-space compatibility, we want in certain
|
||||
use-cases to keep leaking the fbdev physical address to the
|
||||
user-space program handling the fbdev buffer.
|
||||
This affects, not only, Amlogic, Allwinner or Rockchip devices
|
||||
with ARM Mali GPUs using an userspace Blob.
|
||||
This option is not supported by upstream developers and should be
|
||||
removed as soon as possible and be considered as a broken and
|
||||
legacy behaviour from a modern fbdev device driver.
|
||||
|
||||
Please send any bug reports when using this to your proprietary
|
||||
software vendor that requires this.
|
||||
|
||||
If in doubt, say "N" or spread the word to your closed source
|
||||
library vendor.
|
||||
|
||||
config DRM_LOAD_EDID_FIRMWARE
|
||||
bool "Allow to specify an EDID data set instead of probing for it"
|
||||
depends on DRM
|
||||
|
|
|
@ -81,6 +81,23 @@
|
|||
#include "amdgpu_bo_list.h"
|
||||
#include "amdgpu_gem.h"
|
||||
|
||||
#define MAX_GPU_INSTANCE 16
|
||||
|
||||
struct amdgpu_gpu_instance
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
int mgpu_fan_enabled;
|
||||
};
|
||||
|
||||
struct amdgpu_mgpu_info
|
||||
{
|
||||
struct amdgpu_gpu_instance gpu_ins[MAX_GPU_INSTANCE];
|
||||
struct mutex mutex;
|
||||
uint32_t num_gpu;
|
||||
uint32_t num_dgpu;
|
||||
uint32_t num_apu;
|
||||
};
|
||||
|
||||
/*
|
||||
* Modules parameters.
|
||||
*/
|
||||
|
@ -134,6 +151,7 @@ extern int amdgpu_compute_multipipe;
|
|||
extern int amdgpu_gpu_recovery;
|
||||
extern int amdgpu_emu_mode;
|
||||
extern uint amdgpu_smu_memory_pool_size;
|
||||
extern struct amdgpu_mgpu_info mgpu_info;
|
||||
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
extern int amdgpu_si_support;
|
||||
|
@ -146,6 +164,7 @@ extern int amdgpu_cik_support;
|
|||
#define AMDGPU_DEFAULT_GTT_SIZE_MB 3072ULL /* 3GB by default */
|
||||
#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000
|
||||
#define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */
|
||||
#define AMDGPU_FENCE_JIFFIES_TIMEOUT (HZ / 2)
|
||||
/* AMDGPU_IB_POOL_SIZE must be a power of 2 */
|
||||
#define AMDGPU_IB_POOL_SIZE 16
|
||||
#define AMDGPU_DEBUGFS_MAX_COMPONENTS 32
|
||||
|
@ -408,16 +427,25 @@ typedef enum _AMDGPU_DOORBELL64_ASSIGNMENT
|
|||
AMDGPU_DOORBELL64_GFX_RING0 = 0x8b,
|
||||
|
||||
/*
|
||||
* Other graphics doorbells can be allocated here: from 0x8c to 0xef
|
||||
* Other graphics doorbells can be allocated here: from 0x8c to 0xdf
|
||||
* Graphics voltage island aperture 1
|
||||
* default non-graphics QWORD index is 0xF0 - 0xFF inclusive
|
||||
* default non-graphics QWORD index is 0xe0 - 0xFF inclusive
|
||||
*/
|
||||
|
||||
/* sDMA engines */
|
||||
AMDGPU_DOORBELL64_sDMA_ENGINE0 = 0xF0,
|
||||
AMDGPU_DOORBELL64_sDMA_HI_PRI_ENGINE0 = 0xF1,
|
||||
AMDGPU_DOORBELL64_sDMA_ENGINE1 = 0xF2,
|
||||
AMDGPU_DOORBELL64_sDMA_HI_PRI_ENGINE1 = 0xF3,
|
||||
/* sDMA engines reserved from 0xe0 -oxef */
|
||||
AMDGPU_DOORBELL64_sDMA_ENGINE0 = 0xE0,
|
||||
AMDGPU_DOORBELL64_sDMA_HI_PRI_ENGINE0 = 0xE1,
|
||||
AMDGPU_DOORBELL64_sDMA_ENGINE1 = 0xE8,
|
||||
AMDGPU_DOORBELL64_sDMA_HI_PRI_ENGINE1 = 0xE9,
|
||||
|
||||
/* For vega10 sriov, the sdma doorbell must be fixed as follow
|
||||
* to keep the same setting with host driver, or it will
|
||||
* happen conflicts
|
||||
*/
|
||||
AMDGPU_VEGA10_DOORBELL64_sDMA_ENGINE0 = 0xF0,
|
||||
AMDGPU_VEGA10_DOORBELL64_sDMA_HI_PRI_ENGINE0 = 0xF1,
|
||||
AMDGPU_VEGA10_DOORBELL64_sDMA_ENGINE1 = 0xF2,
|
||||
AMDGPU_VEGA10_DOORBELL64_sDMA_HI_PRI_ENGINE1 = 0xF3,
|
||||
|
||||
/* Interrupt handler */
|
||||
AMDGPU_DOORBELL64_IH = 0xF4, /* For legacy interrupt ring buffer */
|
||||
|
@ -588,31 +616,6 @@ void amdgpu_benchmark(struct amdgpu_device *adev, int test_number);
|
|||
*/
|
||||
void amdgpu_test_moves(struct amdgpu_device *adev);
|
||||
|
||||
|
||||
/*
|
||||
* amdgpu smumgr functions
|
||||
*/
|
||||
struct amdgpu_smumgr_funcs {
|
||||
int (*check_fw_load_finish)(struct amdgpu_device *adev, uint32_t fwtype);
|
||||
int (*request_smu_load_fw)(struct amdgpu_device *adev);
|
||||
int (*request_smu_specific_fw)(struct amdgpu_device *adev, uint32_t fwtype);
|
||||
};
|
||||
|
||||
/*
|
||||
* amdgpu smumgr
|
||||
*/
|
||||
struct amdgpu_smumgr {
|
||||
struct amdgpu_bo *toc_buf;
|
||||
struct amdgpu_bo *smu_buf;
|
||||
/* asic priv smu data */
|
||||
void *priv;
|
||||
spinlock_t smu_lock;
|
||||
/* smumgr functions */
|
||||
const struct amdgpu_smumgr_funcs *smumgr_funcs;
|
||||
/* ucode loading complete flag */
|
||||
uint32_t fw_flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* ASIC specific register table accessible by UMD
|
||||
*/
|
||||
|
@ -948,9 +951,6 @@ struct amdgpu_device {
|
|||
u32 cg_flags;
|
||||
u32 pg_flags;
|
||||
|
||||
/* amdgpu smumgr */
|
||||
struct amdgpu_smumgr smu;
|
||||
|
||||
/* gfx */
|
||||
struct amdgpu_gfx gfx;
|
||||
|
||||
|
@ -1015,6 +1015,9 @@ struct amdgpu_device {
|
|||
bool has_hw_reset;
|
||||
u8 reset_magic[AMDGPU_RESET_MAGIC_NUM];
|
||||
|
||||
/* s3/s4 mask */
|
||||
bool in_suspend;
|
||||
|
||||
/* record last mm index being written through WREG32*/
|
||||
unsigned long last_mm_index;
|
||||
bool in_gpu_reset;
|
||||
|
|
|
@ -359,7 +359,9 @@ static int amdgpu_atif_get_sbios_requests(struct amdgpu_atif *atif,
|
|||
*
|
||||
* Checks the acpi event and if it matches an atif event,
|
||||
* handles it.
|
||||
* Returns NOTIFY code
|
||||
*
|
||||
* Returns:
|
||||
* NOTIFY_BAD or NOTIFY_DONE, depending on the event.
|
||||
*/
|
||||
static int amdgpu_atif_handler(struct amdgpu_device *adev,
|
||||
struct acpi_bus_event *event)
|
||||
|
@ -373,11 +375,16 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev,
|
|||
if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
/* Is this actually our event? */
|
||||
if (!atif ||
|
||||
!atif->notification_cfg.enabled ||
|
||||
event->type != atif->notification_cfg.command_code)
|
||||
/* Not our event */
|
||||
return NOTIFY_DONE;
|
||||
event->type != atif->notification_cfg.command_code) {
|
||||
/* These events will generate keypresses otherwise */
|
||||
if (event->type == ACPI_VIDEO_NOTIFY_PROBE)
|
||||
return NOTIFY_BAD;
|
||||
else
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
if (atif->functions.sbios_requests) {
|
||||
struct atif_sbios_requests req;
|
||||
|
@ -386,7 +393,7 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev,
|
|||
count = amdgpu_atif_get_sbios_requests(atif, &req);
|
||||
|
||||
if (count <= 0)
|
||||
return NOTIFY_DONE;
|
||||
return NOTIFY_BAD;
|
||||
|
||||
DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
|
|||
kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions();
|
||||
break;
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_RAVEN:
|
||||
kfd2kgd = amdgpu_amdkfd_gfx_9_0_get_functions();
|
||||
break;
|
||||
|
@ -123,7 +124,7 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
|
|||
|
||||
void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
int i, n;
|
||||
int last_valid_bit;
|
||||
if (adev->kfd) {
|
||||
struct kgd2kfd_shared_resources gpu_resources = {
|
||||
|
@ -162,7 +163,15 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
|||
&gpu_resources.doorbell_physical_address,
|
||||
&gpu_resources.doorbell_aperture_size,
|
||||
&gpu_resources.doorbell_start_offset);
|
||||
if (adev->asic_type >= CHIP_VEGA10) {
|
||||
|
||||
if (adev->asic_type < CHIP_VEGA10) {
|
||||
kgd2kfd->device_init(adev->kfd, &gpu_resources);
|
||||
return;
|
||||
}
|
||||
|
||||
n = (adev->asic_type < CHIP_VEGA20) ? 2 : 8;
|
||||
|
||||
for (i = 0; i < n; i += 2) {
|
||||
/* On SOC15 the BIF is involved in routing
|
||||
* doorbells using the low 12 bits of the
|
||||
* address. Communicate the assignments to
|
||||
|
@ -170,20 +179,31 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
|||
* process in case of 64-bit doorbells so we
|
||||
* can use each doorbell assignment twice.
|
||||
*/
|
||||
gpu_resources.sdma_doorbell[0][0] =
|
||||
AMDGPU_DOORBELL64_sDMA_ENGINE0;
|
||||
gpu_resources.sdma_doorbell[0][1] =
|
||||
AMDGPU_DOORBELL64_sDMA_ENGINE0 + 0x200;
|
||||
gpu_resources.sdma_doorbell[1][0] =
|
||||
AMDGPU_DOORBELL64_sDMA_ENGINE1;
|
||||
gpu_resources.sdma_doorbell[1][1] =
|
||||
AMDGPU_DOORBELL64_sDMA_ENGINE1 + 0x200;
|
||||
/* Doorbells 0x0f0-0ff and 0x2f0-2ff are reserved for
|
||||
* SDMA, IH and VCN. So don't use them for the CP.
|
||||
*/
|
||||
gpu_resources.reserved_doorbell_mask = 0x1f0;
|
||||
gpu_resources.reserved_doorbell_val = 0x0f0;
|
||||
if (adev->asic_type == CHIP_VEGA10) {
|
||||
gpu_resources.sdma_doorbell[0][i] =
|
||||
AMDGPU_VEGA10_DOORBELL64_sDMA_ENGINE0 + (i >> 1);
|
||||
gpu_resources.sdma_doorbell[0][i+1] =
|
||||
AMDGPU_VEGA10_DOORBELL64_sDMA_ENGINE0 + 0x200 + (i >> 1);
|
||||
gpu_resources.sdma_doorbell[1][i] =
|
||||
AMDGPU_VEGA10_DOORBELL64_sDMA_ENGINE1 + (i >> 1);
|
||||
gpu_resources.sdma_doorbell[1][i+1] =
|
||||
AMDGPU_VEGA10_DOORBELL64_sDMA_ENGINE1 + 0x200 + (i >> 1);
|
||||
} else {
|
||||
gpu_resources.sdma_doorbell[0][i] =
|
||||
AMDGPU_DOORBELL64_sDMA_ENGINE0 + (i >> 1);
|
||||
gpu_resources.sdma_doorbell[0][i+1] =
|
||||
AMDGPU_DOORBELL64_sDMA_ENGINE0 + 0x200 + (i >> 1);
|
||||
gpu_resources.sdma_doorbell[1][i] =
|
||||
AMDGPU_DOORBELL64_sDMA_ENGINE1 + (i >> 1);
|
||||
gpu_resources.sdma_doorbell[1][i+1] =
|
||||
AMDGPU_DOORBELL64_sDMA_ENGINE1 + 0x200 + (i >> 1);
|
||||
}
|
||||
}
|
||||
/* Doorbells 0x0e0-0ff and 0x2e0-2ff are reserved for
|
||||
* SDMA, IH and VCN. So don't use them for the CP.
|
||||
*/
|
||||
gpu_resources.reserved_doorbell_mask = 0x1e0;
|
||||
gpu_resources.reserved_doorbell_val = 0x0e0;
|
||||
|
||||
kgd2kfd->device_init(adev->kfd, &gpu_resources);
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
|
|||
struct amdgpu_vm *vm);
|
||||
void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm);
|
||||
void amdgpu_amdkfd_gpuvm_release_process_vm(struct kgd_dev *kgd, void *vm);
|
||||
uint32_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *vm);
|
||||
uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *vm);
|
||||
int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
||||
struct kgd_dev *kgd, uint64_t va, uint64_t size,
|
||||
void *vm, struct kgd_mem **mem,
|
||||
|
|
|
@ -142,7 +142,7 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type);
|
|||
static void set_scratch_backing_va(struct kgd_dev *kgd,
|
||||
uint64_t va, uint32_t vmid);
|
||||
static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
|
||||
uint32_t page_table_base);
|
||||
uint64_t page_table_base);
|
||||
static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid);
|
||||
static int invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid);
|
||||
static uint32_t read_vmid_from_vmfault_reg(struct kgd_dev *kgd);
|
||||
|
@ -874,7 +874,7 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
|
|||
}
|
||||
|
||||
static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
|
||||
uint32_t page_table_base)
|
||||
uint64_t page_table_base)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
|
||||
|
@ -882,7 +882,8 @@ static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
|
|||
pr_err("trying to set page table base for wrong VMID\n");
|
||||
return;
|
||||
}
|
||||
WREG32(mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vmid - 8, page_table_base);
|
||||
WREG32(mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vmid - 8,
|
||||
lower_32_bits(page_table_base));
|
||||
}
|
||||
|
||||
static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
|
||||
|
|
|
@ -45,8 +45,6 @@ enum hqd_dequeue_request_type {
|
|||
RESET_WAVES
|
||||
};
|
||||
|
||||
struct vi_sdma_mqd;
|
||||
|
||||
/*
|
||||
* Register access functions
|
||||
*/
|
||||
|
@ -100,7 +98,7 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type);
|
|||
static void set_scratch_backing_va(struct kgd_dev *kgd,
|
||||
uint64_t va, uint32_t vmid);
|
||||
static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
|
||||
uint32_t page_table_base);
|
||||
uint64_t page_table_base);
|
||||
static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid);
|
||||
static int invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid);
|
||||
|
||||
|
@ -282,7 +280,8 @@ static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id)
|
|||
|
||||
lock_srbm(kgd, mec, pipe, 0, 0);
|
||||
|
||||
WREG32(mmCPC_INT_CNTL, CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK);
|
||||
WREG32(mmCPC_INT_CNTL, CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK |
|
||||
CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK);
|
||||
|
||||
unlock_srbm(kgd);
|
||||
|
||||
|
@ -834,7 +833,7 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
|
|||
}
|
||||
|
||||
static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
|
||||
uint32_t page_table_base)
|
||||
uint64_t page_table_base)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
|
||||
|
@ -842,7 +841,8 @@ static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
|
|||
pr_err("trying to set page table base for wrong VMID\n");
|
||||
return;
|
||||
}
|
||||
WREG32(mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vmid - 8, page_table_base);
|
||||
WREG32(mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vmid - 8,
|
||||
lower_32_bits(page_table_base));
|
||||
}
|
||||
|
||||
static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
|
||||
|
|
|
@ -138,7 +138,7 @@ static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd,
|
|||
static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
|
||||
uint8_t vmid);
|
||||
static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
|
||||
uint32_t page_table_base);
|
||||
uint64_t page_table_base);
|
||||
static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type);
|
||||
static void set_scratch_backing_va(struct kgd_dev *kgd,
|
||||
uint64_t va, uint32_t vmid);
|
||||
|
@ -1013,11 +1013,10 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
|
|||
}
|
||||
|
||||
static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
|
||||
uint32_t page_table_base)
|
||||
uint64_t page_table_base)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
uint64_t base = (uint64_t)page_table_base << PAGE_SHIFT |
|
||||
AMDGPU_PTE_VALID;
|
||||
uint64_t base = page_table_base | AMDGPU_PTE_VALID;
|
||||
|
||||
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
|
||||
pr_err("trying to set page table base for wrong VMID %u\n",
|
||||
|
|
|
@ -1131,11 +1131,15 @@ void amdgpu_amdkfd_gpuvm_release_process_vm(struct kgd_dev *kgd, void *vm)
|
|||
amdgpu_vm_release_compute(adev, avm);
|
||||
}
|
||||
|
||||
uint32_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *vm)
|
||||
uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *vm)
|
||||
{
|
||||
struct amdgpu_vm *avm = (struct amdgpu_vm *)vm;
|
||||
struct amdgpu_bo *pd = avm->root.base.bo;
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(pd->tbo.bdev);
|
||||
|
||||
return avm->pd_phys_addr >> AMDGPU_GPU_PAGE_SHIFT;
|
||||
if (adev->asic_type < CHIP_VEGA10)
|
||||
return avm->pd_phys_addr >> AMDGPU_GPU_PAGE_SHIFT;
|
||||
return avm->pd_phys_addr;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
||||
|
|
|
@ -826,21 +826,13 @@ int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)
|
|||
{
|
||||
struct drm_minor *minor = adev->ddev->primary;
|
||||
struct dentry *ent, *root = minor->debugfs_root;
|
||||
unsigned i, j;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) {
|
||||
ent = debugfs_create_file(debugfs_regs_names[i],
|
||||
S_IFREG | S_IRUGO, root,
|
||||
adev, debugfs_regs[i]);
|
||||
if (IS_ERR(ent)) {
|
||||
for (j = 0; j < i; j++) {
|
||||
debugfs_remove(adev->debugfs_regs[i]);
|
||||
adev->debugfs_regs[i] = NULL;
|
||||
}
|
||||
return PTR_ERR(ent);
|
||||
}
|
||||
|
||||
if (!i)
|
||||
if (!i && !IS_ERR_OR_NULL(ent))
|
||||
i_size_write(ent->d_inode, adev->rmmio_size);
|
||||
adev->debugfs_regs[i] = ent;
|
||||
}
|
||||
|
|
|
@ -1525,6 +1525,92 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_device_ip_hw_init_phase1(struct amdgpu_device *adev)
|
||||
{
|
||||
int i, r;
|
||||
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (!adev->ip_blocks[i].status.sw)
|
||||
continue;
|
||||
if (adev->ip_blocks[i].status.hw)
|
||||
continue;
|
||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) {
|
||||
r = adev->ip_blocks[i].version->funcs->hw_init(adev);
|
||||
if (r) {
|
||||
DRM_ERROR("hw_init of IP block <%s> failed %d\n",
|
||||
adev->ip_blocks[i].version->funcs->name, r);
|
||||
return r;
|
||||
}
|
||||
adev->ip_blocks[i].status.hw = true;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_device_ip_hw_init_phase2(struct amdgpu_device *adev)
|
||||
{
|
||||
int i, r;
|
||||
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (!adev->ip_blocks[i].status.sw)
|
||||
continue;
|
||||
if (adev->ip_blocks[i].status.hw)
|
||||
continue;
|
||||
r = adev->ip_blocks[i].version->funcs->hw_init(adev);
|
||||
if (r) {
|
||||
DRM_ERROR("hw_init of IP block <%s> failed %d\n",
|
||||
adev->ip_blocks[i].version->funcs->name, r);
|
||||
return r;
|
||||
}
|
||||
adev->ip_blocks[i].status.hw = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_device_fw_loading(struct amdgpu_device *adev)
|
||||
{
|
||||
int r = 0;
|
||||
int i;
|
||||
|
||||
if (adev->asic_type >= CHIP_VEGA10) {
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP) {
|
||||
if (adev->in_gpu_reset || adev->in_suspend) {
|
||||
if (amdgpu_sriov_vf(adev) && adev->in_gpu_reset)
|
||||
break; /* sriov gpu reset, psp need to do hw_init before IH because of hw limit */
|
||||
r = adev->ip_blocks[i].version->funcs->resume(adev);
|
||||
if (r) {
|
||||
DRM_ERROR("resume of IP block <%s> failed %d\n",
|
||||
adev->ip_blocks[i].version->funcs->name, r);
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
r = adev->ip_blocks[i].version->funcs->hw_init(adev);
|
||||
if (r) {
|
||||
DRM_ERROR("hw_init of IP block <%s> failed %d\n",
|
||||
adev->ip_blocks[i].version->funcs->name, r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
adev->ip_blocks[i].status.hw = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (adev->powerplay.pp_funcs->load_firmware) {
|
||||
r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle);
|
||||
if (r) {
|
||||
pr_err("firmware loading failed\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_ip_init - run init for hardware IPs
|
||||
*
|
||||
|
@ -1581,19 +1667,21 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (!adev->ip_blocks[i].status.sw)
|
||||
continue;
|
||||
if (adev->ip_blocks[i].status.hw)
|
||||
continue;
|
||||
r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
|
||||
if (r) {
|
||||
DRM_ERROR("hw_init of IP block <%s> failed %d\n",
|
||||
adev->ip_blocks[i].version->funcs->name, r);
|
||||
return r;
|
||||
}
|
||||
adev->ip_blocks[i].status.hw = true;
|
||||
}
|
||||
r = amdgpu_ucode_create_bo(adev); /* create ucode bo when sw_init complete*/
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_device_ip_hw_init_phase1(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_device_fw_loading(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_device_ip_hw_init_phase2(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_xgmi_add_device(adev);
|
||||
amdgpu_amdkfd_device_init(adev);
|
||||
|
@ -1656,7 +1744,7 @@ static int amdgpu_device_set_cg_state(struct amdgpu_device *adev,
|
|||
|
||||
for (j = 0; j < adev->num_ip_blocks; j++) {
|
||||
i = state == AMD_CG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
|
||||
if (!adev->ip_blocks[i].status.valid)
|
||||
if (!adev->ip_blocks[i].status.late_initialized)
|
||||
continue;
|
||||
/* skip CG for VCE/UVD, it's handled specially */
|
||||
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
|
||||
|
@ -1686,7 +1774,7 @@ static int amdgpu_device_set_pg_state(struct amdgpu_device *adev, enum amd_power
|
|||
|
||||
for (j = 0; j < adev->num_ip_blocks; j++) {
|
||||
i = state == AMD_PG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
|
||||
if (!adev->ip_blocks[i].status.valid)
|
||||
if (!adev->ip_blocks[i].status.late_initialized)
|
||||
continue;
|
||||
/* skip CG for VCE/UVD, it's handled specially */
|
||||
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
|
||||
|
@ -1723,7 +1811,7 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
|
|||
int i = 0, r;
|
||||
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (!adev->ip_blocks[i].status.valid)
|
||||
if (!adev->ip_blocks[i].status.hw)
|
||||
continue;
|
||||
if (adev->ip_blocks[i].version->funcs->late_init) {
|
||||
r = adev->ip_blocks[i].version->funcs->late_init((void *)adev);
|
||||
|
@ -1732,8 +1820,8 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
|
|||
adev->ip_blocks[i].version->funcs->name, r);
|
||||
return r;
|
||||
}
|
||||
adev->ip_blocks[i].status.late_initialized = true;
|
||||
}
|
||||
adev->ip_blocks[i].status.late_initialized = true;
|
||||
}
|
||||
|
||||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE);
|
||||
|
@ -1803,6 +1891,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
|
|||
continue;
|
||||
|
||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) {
|
||||
amdgpu_ucode_free_bo(adev);
|
||||
amdgpu_free_static_csa(adev);
|
||||
amdgpu_device_wb_fini(adev);
|
||||
amdgpu_device_vram_scratch_fini(adev);
|
||||
|
@ -1833,6 +1922,43 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_device_enable_mgpu_fan_boost(void)
|
||||
{
|
||||
struct amdgpu_gpu_instance *gpu_ins;
|
||||
struct amdgpu_device *adev;
|
||||
int i, ret = 0;
|
||||
|
||||
mutex_lock(&mgpu_info.mutex);
|
||||
|
||||
/*
|
||||
* MGPU fan boost feature should be enabled
|
||||
* only when there are two or more dGPUs in
|
||||
* the system
|
||||
*/
|
||||
if (mgpu_info.num_dgpu < 2)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < mgpu_info.num_dgpu; i++) {
|
||||
gpu_ins = &(mgpu_info.gpu_ins[i]);
|
||||
adev = gpu_ins->adev;
|
||||
if (!(adev->flags & AMD_IS_APU) &&
|
||||
!gpu_ins->mgpu_fan_enabled &&
|
||||
adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->enable_mgpu_fan_boost) {
|
||||
ret = amdgpu_dpm_enable_mgpu_fan_boost(adev);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
gpu_ins->mgpu_fan_enabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&mgpu_info.mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_ip_late_init_func_handler - work handler for ib test
|
||||
*
|
||||
|
@ -1847,6 +1973,10 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work)
|
|||
r = amdgpu_ib_ring_tests(adev);
|
||||
if (r)
|
||||
DRM_ERROR("ib ring test failed (%d).\n", r);
|
||||
|
||||
r = amdgpu_device_enable_mgpu_fan_boost();
|
||||
if (r)
|
||||
DRM_ERROR("enable mgpu fan boost failed (%d).\n", r);
|
||||
}
|
||||
|
||||
static void amdgpu_device_delay_enable_gfx_off(struct work_struct *work)
|
||||
|
@ -2082,7 +2212,8 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
|
|||
continue;
|
||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC ||
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH)
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH ||
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)
|
||||
continue;
|
||||
r = adev->ip_blocks[i].version->funcs->resume(adev);
|
||||
if (r) {
|
||||
|
@ -2114,6 +2245,11 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev)
|
|||
r = amdgpu_device_ip_resume_phase1(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_device_fw_loading(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_device_ip_resume_phase2(adev);
|
||||
|
||||
return r;
|
||||
|
@ -2608,6 +2744,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
|
|||
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
|
||||
return 0;
|
||||
|
||||
adev->in_suspend = true;
|
||||
drm_kms_helper_poll_disable(dev);
|
||||
|
||||
if (fbcon)
|
||||
|
@ -2793,6 +2930,8 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
|
|||
#ifdef CONFIG_PM
|
||||
dev->dev->power.disable_depth--;
|
||||
#endif
|
||||
adev->in_suspend = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3061,6 +3200,10 @@ static int amdgpu_device_reset(struct amdgpu_device *adev)
|
|||
if (r)
|
||||
goto out;
|
||||
|
||||
r = amdgpu_device_fw_loading(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_device_ip_resume_phase2(adev);
|
||||
if (r)
|
||||
goto out;
|
||||
|
@ -3117,6 +3260,10 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
|
|||
/* we need recover gart prior to run SMC/CP/SDMA resume */
|
||||
amdgpu_gtt_mgr_recover(&adev->mman.bdev.man[TTM_PL_TT]);
|
||||
|
||||
r = amdgpu_device_fw_loading(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* now we are okay to resume SMC/CP/SDMA */
|
||||
r = amdgpu_device_ip_reinit_late_sriov(adev);
|
||||
if (r)
|
||||
|
|
|
@ -278,6 +278,9 @@ enum amdgpu_pcie_gen {
|
|||
#define amdgpu_dpm_get_fan_speed_rpm(adev, s) \
|
||||
((adev)->powerplay.pp_funcs->get_fan_speed_rpm)((adev)->powerplay.pp_handle, (s))
|
||||
|
||||
#define amdgpu_dpm_set_fan_speed_rpm(adev, s) \
|
||||
((adev)->powerplay.pp_funcs->set_fan_speed_rpm)((adev)->powerplay.pp_handle, (s))
|
||||
|
||||
#define amdgpu_dpm_get_sclk(adev, l) \
|
||||
((adev)->powerplay.pp_funcs->get_sclk((adev)->powerplay.pp_handle, (l)))
|
||||
|
||||
|
@ -357,6 +360,10 @@ enum amdgpu_pcie_gen {
|
|||
((adev)->powerplay.pp_funcs->odn_edit_dpm_table(\
|
||||
(adev)->powerplay.pp_handle, type, parameter, size))
|
||||
|
||||
#define amdgpu_dpm_enable_mgpu_fan_boost(adev) \
|
||||
((adev)->powerplay.pp_funcs->enable_mgpu_fan_boost(\
|
||||
(adev)->powerplay.pp_handle))
|
||||
|
||||
struct amdgpu_dpm {
|
||||
struct amdgpu_ps *ps;
|
||||
/* number of valid power states */
|
||||
|
|
|
@ -127,6 +127,9 @@ int amdgpu_compute_multipipe = -1;
|
|||
int amdgpu_gpu_recovery = -1; /* auto */
|
||||
int amdgpu_emu_mode = 0;
|
||||
uint amdgpu_smu_memory_pool_size = 0;
|
||||
struct amdgpu_mgpu_info mgpu_info = {
|
||||
.mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
|
||||
};
|
||||
|
||||
/**
|
||||
* DOC: vramlimit (int)
|
||||
|
|
|
@ -195,6 +195,19 @@ int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_fence_schedule_fallback - schedule fallback check
|
||||
*
|
||||
* @ring: pointer to struct amdgpu_ring
|
||||
*
|
||||
* Start a timer as fallback to our interrupts.
|
||||
*/
|
||||
static void amdgpu_fence_schedule_fallback(struct amdgpu_ring *ring)
|
||||
{
|
||||
mod_timer(&ring->fence_drv.fallback_timer,
|
||||
jiffies + AMDGPU_FENCE_JIFFIES_TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_fence_process - check for fence activity
|
||||
*
|
||||
|
@ -203,8 +216,10 @@ int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s)
|
|||
* Checks the current fence value and calculates the last
|
||||
* signalled fence value. Wakes the fence queue if the
|
||||
* sequence number has increased.
|
||||
*
|
||||
* Returns true if fence was processed
|
||||
*/
|
||||
void amdgpu_fence_process(struct amdgpu_ring *ring)
|
||||
bool amdgpu_fence_process(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_fence_driver *drv = &ring->fence_drv;
|
||||
uint32_t seq, last_seq;
|
||||
|
@ -216,8 +231,12 @@ void amdgpu_fence_process(struct amdgpu_ring *ring)
|
|||
|
||||
} while (atomic_cmpxchg(&drv->last_seq, last_seq, seq) != last_seq);
|
||||
|
||||
if (del_timer(&ring->fence_drv.fallback_timer) &&
|
||||
seq != ring->fence_drv.sync_seq)
|
||||
amdgpu_fence_schedule_fallback(ring);
|
||||
|
||||
if (unlikely(seq == last_seq))
|
||||
return;
|
||||
return false;
|
||||
|
||||
last_seq &= drv->num_fences_mask;
|
||||
seq &= drv->num_fences_mask;
|
||||
|
@ -244,6 +263,24 @@ void amdgpu_fence_process(struct amdgpu_ring *ring)
|
|||
|
||||
dma_fence_put(fence);
|
||||
} while (last_seq != seq);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_fence_fallback - fallback for hardware interrupts
|
||||
*
|
||||
* @work: delayed work item
|
||||
*
|
||||
* Checks for fence activity.
|
||||
*/
|
||||
static void amdgpu_fence_fallback(struct timer_list *t)
|
||||
{
|
||||
struct amdgpu_ring *ring = from_timer(ring, t,
|
||||
fence_drv.fallback_timer);
|
||||
|
||||
if (amdgpu_fence_process(ring))
|
||||
DRM_WARN("Fence fallback timer expired on ring %s\n", ring->name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -393,6 +430,8 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
|
|||
atomic_set(&ring->fence_drv.last_seq, 0);
|
||||
ring->fence_drv.initialized = false;
|
||||
|
||||
timer_setup(&ring->fence_drv.fallback_timer, amdgpu_fence_fallback, 0);
|
||||
|
||||
ring->fence_drv.num_fences_mask = num_hw_submission * 2 - 1;
|
||||
spin_lock_init(&ring->fence_drv.lock);
|
||||
ring->fence_drv.fences = kcalloc(num_hw_submission * 2, sizeof(void *),
|
||||
|
@ -468,6 +507,7 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
|
|||
amdgpu_irq_put(adev, ring->fence_drv.irq_src,
|
||||
ring->fence_drv.irq_type);
|
||||
drm_sched_fini(&ring->sched);
|
||||
del_timer_sync(&ring->fence_drv.fallback_timer);
|
||||
for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j)
|
||||
dma_fence_put(ring->fence_drv.fences[j]);
|
||||
kfree(ring->fence_drv.fences);
|
||||
|
@ -560,6 +600,27 @@ static const char *amdgpu_fence_get_timeline_name(struct dma_fence *f)
|
|||
return (const char *)fence->ring->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_fence_enable_signaling - enable signalling on fence
|
||||
* @fence: fence
|
||||
*
|
||||
* This function is called with fence_queue lock held, and adds a callback
|
||||
* to fence_queue that checks if this fence is signaled, and if so it
|
||||
* signals the fence and removes itself.
|
||||
*/
|
||||
static bool amdgpu_fence_enable_signaling(struct dma_fence *f)
|
||||
{
|
||||
struct amdgpu_fence *fence = to_amdgpu_fence(f);
|
||||
struct amdgpu_ring *ring = fence->ring;
|
||||
|
||||
if (!timer_pending(&ring->fence_drv.fallback_timer))
|
||||
amdgpu_fence_schedule_fallback(ring);
|
||||
|
||||
DMA_FENCE_TRACE(&fence->base, "armed on ring %i!\n", ring->idx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_fence_free - free up the fence memory
|
||||
*
|
||||
|
@ -590,6 +651,7 @@ static void amdgpu_fence_release(struct dma_fence *f)
|
|||
static const struct dma_fence_ops amdgpu_fence_ops = {
|
||||
.get_driver_name = amdgpu_fence_get_driver_name,
|
||||
.get_timeline_name = amdgpu_fence_get_timeline_name,
|
||||
.enable_signaling = amdgpu_fence_enable_signaling,
|
||||
.release = amdgpu_fence_release,
|
||||
};
|
||||
|
||||
|
|
|
@ -297,8 +297,7 @@ struct amdgpu_gfx {
|
|||
/* reset mask */
|
||||
uint32_t grbm_soft_reset;
|
||||
uint32_t srbm_soft_reset;
|
||||
/* s3/s4 mask */
|
||||
bool in_suspend;
|
||||
|
||||
/* NGG */
|
||||
struct amdgpu_ngg ngg;
|
||||
|
||||
|
|
|
@ -146,6 +146,8 @@ void amdgpu_gmc_gart_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc)
|
|||
{
|
||||
const uint64_t four_gb = 0x100000000ULL;
|
||||
u64 size_af, size_bf;
|
||||
/*To avoid the hole, limit the max mc address to AMDGPU_GMC_HOLE_START*/
|
||||
u64 max_mc_address = min(adev->gmc.mc_mask, AMDGPU_GMC_HOLE_START - 1);
|
||||
|
||||
mc->gart_size += adev->pm.smu_prv_buffer_size;
|
||||
|
||||
|
@ -153,7 +155,7 @@ void amdgpu_gmc_gart_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc)
|
|||
* the GART base on a 4GB boundary as well.
|
||||
*/
|
||||
size_bf = mc->fb_start;
|
||||
size_af = adev->gmc.mc_mask + 1 - ALIGN(mc->fb_end + 1, four_gb);
|
||||
size_af = max_mc_address + 1 - ALIGN(mc->fb_end + 1, four_gb);
|
||||
|
||||
if (mc->gart_size > max(size_bf, size_af)) {
|
||||
dev_warn(adev->dev, "limiting GART\n");
|
||||
|
@ -164,7 +166,7 @@ void amdgpu_gmc_gart_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc)
|
|||
(size_af < mc->gart_size))
|
||||
mc->gart_start = 0;
|
||||
else
|
||||
mc->gart_start = mc->mc_mask - mc->gart_size + 1;
|
||||
mc->gart_start = max_mc_address - mc->gart_size + 1;
|
||||
|
||||
mc->gart_start &= ~(four_gb - 1);
|
||||
mc->gart_end = mc->gart_start + mc->gart_size - 1;
|
||||
|
@ -200,16 +202,13 @@ void amdgpu_gmc_agp_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc)
|
|||
}
|
||||
|
||||
if (size_bf > size_af) {
|
||||
mc->agp_start = mc->fb_start > mc->gart_start ?
|
||||
mc->gart_end + 1 : 0;
|
||||
mc->agp_start = (mc->fb_start - size_bf) & sixteen_gb_mask;
|
||||
mc->agp_size = size_bf;
|
||||
} else {
|
||||
mc->agp_start = (mc->fb_start > mc->gart_start ?
|
||||
mc->fb_end : mc->gart_end) + 1,
|
||||
mc->agp_start = ALIGN(mc->fb_end + 1, sixteen_gb);
|
||||
mc->agp_size = size_af;
|
||||
}
|
||||
|
||||
mc->agp_start = ALIGN(mc->agp_start, sixteen_gb);
|
||||
mc->agp_end = mc->agp_start + mc->agp_size - 1;
|
||||
dev_info(adev->dev, "AGP: %lluM 0x%016llX - 0x%016llX\n",
|
||||
mc->agp_size >> 20, mc->agp_start, mc->agp_end);
|
||||
|
|
|
@ -354,6 +354,14 @@ int amdgpu_ib_ring_tests(struct amdgpu_device *adev)
|
|||
if (!ring || !ring->ready)
|
||||
continue;
|
||||
|
||||
/* skip IB tests for KIQ in general for the below reasons:
|
||||
* 1. We never submit IBs to the KIQ
|
||||
* 2. KIQ doesn't use the EOP interrupts,
|
||||
* we use some other CP interrupt.
|
||||
*/
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_KIQ)
|
||||
continue;
|
||||
|
||||
/* MM engine need more time */
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_UVD ||
|
||||
ring->funcs->type == AMDGPU_RING_TYPE_VCE ||
|
||||
|
|
|
@ -574,7 +574,7 @@ void amdgpu_vmid_mgr_init(struct amdgpu_device *adev)
|
|||
/* skip over VMID 0, since it is the system VM */
|
||||
for (j = 1; j < id_mgr->num_ids; ++j) {
|
||||
amdgpu_vmid_reset(adev, i, j);
|
||||
amdgpu_sync_create(&id_mgr->ids[i].active);
|
||||
amdgpu_sync_create(&id_mgr->ids[j].active);
|
||||
list_add_tail(&id_mgr->ids[j].list, &id_mgr->ids_lru);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,46 +24,21 @@
|
|||
#include <drm/drmP.h>
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_ih.h"
|
||||
#include "amdgpu_amdkfd.h"
|
||||
|
||||
/**
|
||||
* amdgpu_ih_ring_alloc - allocate memory for the IH ring
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Allocate a ring buffer for the interrupt controller.
|
||||
* Returns 0 for success, errors for failure.
|
||||
*/
|
||||
static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* Allocate ring buffer */
|
||||
if (adev->irq.ih.ring_obj == NULL) {
|
||||
r = amdgpu_bo_create_kernel(adev, adev->irq.ih.ring_size,
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->irq.ih.ring_obj,
|
||||
&adev->irq.ih.gpu_addr,
|
||||
(void **)&adev->irq.ih.ring);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu: failed to create ih ring buffer (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_ih_ring_init - initialize the IH state
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @ih: ih ring to initialize
|
||||
* @ring_size: ring size to allocate
|
||||
* @use_bus_addr: true when we can use dma_alloc_coherent
|
||||
*
|
||||
* Initializes the IH state and allocates a buffer
|
||||
* for the IH ring buffer.
|
||||
* Returns 0 for success, errors for failure.
|
||||
*/
|
||||
int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size,
|
||||
bool use_bus_addr)
|
||||
int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
|
||||
unsigned ring_size, bool use_bus_addr)
|
||||
{
|
||||
u32 rb_bufsz;
|
||||
int r;
|
||||
|
@ -71,70 +46,76 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size,
|
|||
/* Align ring size */
|
||||
rb_bufsz = order_base_2(ring_size / 4);
|
||||
ring_size = (1 << rb_bufsz) * 4;
|
||||
adev->irq.ih.ring_size = ring_size;
|
||||
adev->irq.ih.ptr_mask = adev->irq.ih.ring_size - 1;
|
||||
adev->irq.ih.rptr = 0;
|
||||
adev->irq.ih.use_bus_addr = use_bus_addr;
|
||||
ih->ring_size = ring_size;
|
||||
ih->ptr_mask = ih->ring_size - 1;
|
||||
ih->rptr = 0;
|
||||
ih->use_bus_addr = use_bus_addr;
|
||||
|
||||
if (adev->irq.ih.use_bus_addr) {
|
||||
if (!adev->irq.ih.ring) {
|
||||
/* add 8 bytes for the rptr/wptr shadows and
|
||||
* add them to the end of the ring allocation.
|
||||
*/
|
||||
adev->irq.ih.ring = pci_alloc_consistent(adev->pdev,
|
||||
adev->irq.ih.ring_size + 8,
|
||||
&adev->irq.ih.rb_dma_addr);
|
||||
if (adev->irq.ih.ring == NULL)
|
||||
return -ENOMEM;
|
||||
memset((void *)adev->irq.ih.ring, 0, adev->irq.ih.ring_size + 8);
|
||||
adev->irq.ih.wptr_offs = (adev->irq.ih.ring_size / 4) + 0;
|
||||
adev->irq.ih.rptr_offs = (adev->irq.ih.ring_size / 4) + 1;
|
||||
}
|
||||
return 0;
|
||||
if (use_bus_addr) {
|
||||
if (ih->ring)
|
||||
return 0;
|
||||
|
||||
/* add 8 bytes for the rptr/wptr shadows and
|
||||
* add them to the end of the ring allocation.
|
||||
*/
|
||||
ih->ring = dma_alloc_coherent(adev->dev, ih->ring_size + 8,
|
||||
&ih->rb_dma_addr, GFP_KERNEL);
|
||||
if (ih->ring == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memset((void *)ih->ring, 0, ih->ring_size + 8);
|
||||
ih->wptr_offs = (ih->ring_size / 4) + 0;
|
||||
ih->rptr_offs = (ih->ring_size / 4) + 1;
|
||||
} else {
|
||||
r = amdgpu_device_wb_get(adev, &adev->irq.ih.wptr_offs);
|
||||
r = amdgpu_device_wb_get(adev, &ih->wptr_offs);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_device_wb_get(adev, &ih->rptr_offs);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "(%d) ih wptr_offs wb alloc failed\n", r);
|
||||
amdgpu_device_wb_free(adev, ih->wptr_offs);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_device_wb_get(adev, &adev->irq.ih.rptr_offs);
|
||||
r = amdgpu_bo_create_kernel(adev, ih->ring_size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&ih->ring_obj, &ih->gpu_addr,
|
||||
(void **)&ih->ring);
|
||||
if (r) {
|
||||
amdgpu_device_wb_free(adev, adev->irq.ih.wptr_offs);
|
||||
dev_err(adev->dev, "(%d) ih rptr_offs wb alloc failed\n", r);
|
||||
amdgpu_device_wb_free(adev, ih->rptr_offs);
|
||||
amdgpu_device_wb_free(adev, ih->wptr_offs);
|
||||
return r;
|
||||
}
|
||||
|
||||
return amdgpu_ih_ring_alloc(adev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_ih_ring_fini - tear down the IH state
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @ih: ih ring to tear down
|
||||
*
|
||||
* Tears down the IH state and frees buffer
|
||||
* used for the IH ring buffer.
|
||||
*/
|
||||
void amdgpu_ih_ring_fini(struct amdgpu_device *adev)
|
||||
void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
|
||||
{
|
||||
if (adev->irq.ih.use_bus_addr) {
|
||||
if (adev->irq.ih.ring) {
|
||||
/* add 8 bytes for the rptr/wptr shadows and
|
||||
* add them to the end of the ring allocation.
|
||||
*/
|
||||
pci_free_consistent(adev->pdev, adev->irq.ih.ring_size + 8,
|
||||
(void *)adev->irq.ih.ring,
|
||||
adev->irq.ih.rb_dma_addr);
|
||||
adev->irq.ih.ring = NULL;
|
||||
}
|
||||
if (ih->use_bus_addr) {
|
||||
if (!ih->ring)
|
||||
return;
|
||||
|
||||
/* add 8 bytes for the rptr/wptr shadows and
|
||||
* add them to the end of the ring allocation.
|
||||
*/
|
||||
dma_free_coherent(adev->dev, ih->ring_size + 8,
|
||||
(void *)ih->ring, ih->rb_dma_addr);
|
||||
ih->ring = NULL;
|
||||
} else {
|
||||
amdgpu_bo_free_kernel(&adev->irq.ih.ring_obj,
|
||||
&adev->irq.ih.gpu_addr,
|
||||
(void **)&adev->irq.ih.ring);
|
||||
amdgpu_device_wb_free(adev, adev->irq.ih.wptr_offs);
|
||||
amdgpu_device_wb_free(adev, adev->irq.ih.rptr_offs);
|
||||
amdgpu_bo_free_kernel(&ih->ring_obj, &ih->gpu_addr,
|
||||
(void **)&ih->ring);
|
||||
amdgpu_device_wb_free(adev, ih->wptr_offs);
|
||||
amdgpu_device_wb_free(adev, ih->rptr_offs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,56 +123,43 @@ void amdgpu_ih_ring_fini(struct amdgpu_device *adev)
|
|||
* amdgpu_ih_process - interrupt handler
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @ih: ih ring to process
|
||||
*
|
||||
* Interrupt hander (VI), walk the IH ring.
|
||||
* Returns irq process return code.
|
||||
*/
|
||||
int amdgpu_ih_process(struct amdgpu_device *adev)
|
||||
int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
|
||||
void (*callback)(struct amdgpu_device *adev,
|
||||
struct amdgpu_ih_ring *ih))
|
||||
{
|
||||
struct amdgpu_iv_entry entry;
|
||||
u32 wptr;
|
||||
|
||||
if (!adev->irq.ih.enabled || adev->shutdown)
|
||||
if (!ih->enabled || adev->shutdown)
|
||||
return IRQ_NONE;
|
||||
|
||||
wptr = amdgpu_ih_get_wptr(adev);
|
||||
|
||||
restart_ih:
|
||||
/* is somebody else already processing irqs? */
|
||||
if (atomic_xchg(&adev->irq.ih.lock, 1))
|
||||
if (atomic_xchg(&ih->lock, 1))
|
||||
return IRQ_NONE;
|
||||
|
||||
DRM_DEBUG("%s: rptr %d, wptr %d\n", __func__, adev->irq.ih.rptr, wptr);
|
||||
DRM_DEBUG("%s: rptr %d, wptr %d\n", __func__, ih->rptr, wptr);
|
||||
|
||||
/* Order reading of wptr vs. reading of IH ring data */
|
||||
rmb();
|
||||
|
||||
while (adev->irq.ih.rptr != wptr) {
|
||||
u32 ring_index = adev->irq.ih.rptr >> 2;
|
||||
|
||||
/* Prescreening of high-frequency interrupts */
|
||||
if (!amdgpu_ih_prescreen_iv(adev)) {
|
||||
adev->irq.ih.rptr &= adev->irq.ih.ptr_mask;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Before dispatching irq to IP blocks, send it to amdkfd */
|
||||
amdgpu_amdkfd_interrupt(adev,
|
||||
(const void *) &adev->irq.ih.ring[ring_index]);
|
||||
|
||||
entry.iv_entry = (const uint32_t *)
|
||||
&adev->irq.ih.ring[ring_index];
|
||||
amdgpu_ih_decode_iv(adev, &entry);
|
||||
adev->irq.ih.rptr &= adev->irq.ih.ptr_mask;
|
||||
|
||||
amdgpu_irq_dispatch(adev, &entry);
|
||||
while (ih->rptr != wptr) {
|
||||
callback(adev, ih);
|
||||
ih->rptr &= ih->ptr_mask;
|
||||
}
|
||||
|
||||
amdgpu_ih_set_rptr(adev);
|
||||
atomic_set(&adev->irq.ih.lock, 0);
|
||||
atomic_set(&ih->lock, 0);
|
||||
|
||||
/* make sure wptr hasn't changed while processing */
|
||||
wptr = amdgpu_ih_get_wptr(adev);
|
||||
if (wptr != adev->irq.ih.rptr)
|
||||
if (wptr != ih->rptr)
|
||||
goto restart_ih;
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
|
|
@ -24,12 +24,8 @@
|
|||
#ifndef __AMDGPU_IH_H__
|
||||
#define __AMDGPU_IH_H__
|
||||
|
||||
#include "soc15_ih_clientid.h"
|
||||
|
||||
struct amdgpu_device;
|
||||
|
||||
#define AMDGPU_IH_CLIENTID_LEGACY 0
|
||||
#define AMDGPU_IH_CLIENTID_MAX SOC15_IH_CLIENTID_MAX
|
||||
struct amdgpu_iv_entry;
|
||||
|
||||
/*
|
||||
* R6xx+ IH ring
|
||||
|
@ -51,22 +47,6 @@ struct amdgpu_ih_ring {
|
|||
dma_addr_t rb_dma_addr; /* only used when use_bus_addr = true */
|
||||
};
|
||||
|
||||
#define AMDGPU_IH_SRC_DATA_MAX_SIZE_DW 4
|
||||
|
||||
struct amdgpu_iv_entry {
|
||||
unsigned client_id;
|
||||
unsigned src_id;
|
||||
unsigned ring_id;
|
||||
unsigned vmid;
|
||||
unsigned vmid_src;
|
||||
uint64_t timestamp;
|
||||
unsigned timestamp_src;
|
||||
unsigned pasid;
|
||||
unsigned pasid_src;
|
||||
unsigned src_data[AMDGPU_IH_SRC_DATA_MAX_SIZE_DW];
|
||||
const uint32_t *iv_entry;
|
||||
};
|
||||
|
||||
/* provided by the ih block */
|
||||
struct amdgpu_ih_funcs {
|
||||
/* ring read/write ptr handling, called from interrupt context */
|
||||
|
@ -82,9 +62,11 @@ struct amdgpu_ih_funcs {
|
|||
#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv))
|
||||
#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev))
|
||||
|
||||
int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size,
|
||||
bool use_bus_addr);
|
||||
void amdgpu_ih_ring_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_ih_process(struct amdgpu_device *adev);
|
||||
int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
|
||||
unsigned ring_size, bool use_bus_addr);
|
||||
void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
|
||||
int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
|
||||
void (*callback)(struct amdgpu_device *adev,
|
||||
struct amdgpu_ih_ring *ih));
|
||||
|
||||
#endif
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "atom.h"
|
||||
#include "amdgpu_connectors.h"
|
||||
#include "amdgpu_trace.h"
|
||||
#include "amdgpu_amdkfd.h"
|
||||
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
|
@ -123,7 +124,7 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev)
|
|||
int r;
|
||||
|
||||
spin_lock_irqsave(&adev->irq.lock, irqflags);
|
||||
for (i = 0; i < AMDGPU_IH_CLIENTID_MAX; ++i) {
|
||||
for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) {
|
||||
if (!adev->irq.client[i].sources)
|
||||
continue;
|
||||
|
||||
|
@ -146,6 +147,34 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev)
|
|||
spin_unlock_irqrestore(&adev->irq.lock, irqflags);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_irq_callback - callback from the IH ring
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @ih: amdgpu ih ring
|
||||
*
|
||||
* Callback from IH ring processing to handle the entry at the current position
|
||||
* and advance the read pointer.
|
||||
*/
|
||||
static void amdgpu_irq_callback(struct amdgpu_device *adev,
|
||||
struct amdgpu_ih_ring *ih)
|
||||
{
|
||||
u32 ring_index = ih->rptr >> 2;
|
||||
struct amdgpu_iv_entry entry;
|
||||
|
||||
/* Prescreening of high-frequency interrupts */
|
||||
if (!amdgpu_ih_prescreen_iv(adev))
|
||||
return;
|
||||
|
||||
/* Before dispatching irq to IP blocks, send it to amdkfd */
|
||||
amdgpu_amdkfd_interrupt(adev, (const void *) &ih->ring[ring_index]);
|
||||
|
||||
entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
|
||||
amdgpu_ih_decode_iv(adev, &entry);
|
||||
|
||||
amdgpu_irq_dispatch(adev, &entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_irq_handler - IRQ handler
|
||||
*
|
||||
|
@ -163,7 +192,7 @@ irqreturn_t amdgpu_irq_handler(int irq, void *arg)
|
|||
struct amdgpu_device *adev = dev->dev_private;
|
||||
irqreturn_t ret;
|
||||
|
||||
ret = amdgpu_ih_process(adev);
|
||||
ret = amdgpu_ih_process(adev, &adev->irq.ih, amdgpu_irq_callback);
|
||||
if (ret == IRQ_HANDLED)
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
return ret;
|
||||
|
@ -273,7 +302,7 @@ void amdgpu_irq_fini(struct amdgpu_device *adev)
|
|||
cancel_work_sync(&adev->reset_work);
|
||||
}
|
||||
|
||||
for (i = 0; i < AMDGPU_IH_CLIENTID_MAX; ++i) {
|
||||
for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) {
|
||||
if (!adev->irq.client[i].sources)
|
||||
continue;
|
||||
|
||||
|
@ -313,7 +342,7 @@ int amdgpu_irq_add_id(struct amdgpu_device *adev,
|
|||
unsigned client_id, unsigned src_id,
|
||||
struct amdgpu_irq_src *source)
|
||||
{
|
||||
if (client_id >= AMDGPU_IH_CLIENTID_MAX)
|
||||
if (client_id >= AMDGPU_IRQ_CLIENTID_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (src_id >= AMDGPU_MAX_IRQ_SRC_ID)
|
||||
|
@ -367,7 +396,7 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
|
|||
|
||||
trace_amdgpu_iv(entry);
|
||||
|
||||
if (client_id >= AMDGPU_IH_CLIENTID_MAX) {
|
||||
if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
|
||||
DRM_DEBUG("Invalid client_id in IV: %d\n", client_id);
|
||||
return;
|
||||
}
|
||||
|
@ -440,7 +469,7 @@ void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev)
|
|||
{
|
||||
int i, j, k;
|
||||
|
||||
for (i = 0; i < AMDGPU_IH_CLIENTID_MAX; ++i) {
|
||||
for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) {
|
||||
if (!adev->irq.client[i].sources)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -25,19 +25,38 @@
|
|||
#define __AMDGPU_IRQ_H__
|
||||
|
||||
#include <linux/irqdomain.h>
|
||||
#include "soc15_ih_clientid.h"
|
||||
#include "amdgpu_ih.h"
|
||||
|
||||
#define AMDGPU_MAX_IRQ_SRC_ID 0x100
|
||||
#define AMDGPU_MAX_IRQ_SRC_ID 0x100
|
||||
#define AMDGPU_MAX_IRQ_CLIENT_ID 0x100
|
||||
|
||||
#define AMDGPU_IRQ_CLIENTID_LEGACY 0
|
||||
#define AMDGPU_IRQ_CLIENTID_MAX SOC15_IH_CLIENTID_MAX
|
||||
|
||||
#define AMDGPU_IRQ_SRC_DATA_MAX_SIZE_DW 4
|
||||
|
||||
struct amdgpu_device;
|
||||
struct amdgpu_iv_entry;
|
||||
|
||||
enum amdgpu_interrupt_state {
|
||||
AMDGPU_IRQ_STATE_DISABLE,
|
||||
AMDGPU_IRQ_STATE_ENABLE,
|
||||
};
|
||||
|
||||
struct amdgpu_iv_entry {
|
||||
unsigned client_id;
|
||||
unsigned src_id;
|
||||
unsigned ring_id;
|
||||
unsigned vmid;
|
||||
unsigned vmid_src;
|
||||
uint64_t timestamp;
|
||||
unsigned timestamp_src;
|
||||
unsigned pasid;
|
||||
unsigned pasid_src;
|
||||
unsigned src_data[AMDGPU_IRQ_SRC_DATA_MAX_SIZE_DW];
|
||||
const uint32_t *iv_entry;
|
||||
};
|
||||
|
||||
struct amdgpu_irq_src {
|
||||
unsigned num_types;
|
||||
atomic_t *enabled_types;
|
||||
|
@ -63,7 +82,7 @@ struct amdgpu_irq {
|
|||
bool installed;
|
||||
spinlock_t lock;
|
||||
/* interrupt sources */
|
||||
struct amdgpu_irq_client client[AMDGPU_IH_CLIENTID_MAX];
|
||||
struct amdgpu_irq_client client[AMDGPU_IRQ_CLIENTID_MAX];
|
||||
|
||||
/* status, etc. */
|
||||
bool msi_enabled; /* msi enabled */
|
||||
|
|
|
@ -40,6 +40,30 @@
|
|||
#include "amdgpu_gem.h"
|
||||
#include "amdgpu_display.h"
|
||||
|
||||
static void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_gpu_instance *gpu_instance;
|
||||
int i;
|
||||
|
||||
mutex_lock(&mgpu_info.mutex);
|
||||
|
||||
for (i = 0; i < mgpu_info.num_gpu; i++) {
|
||||
gpu_instance = &(mgpu_info.gpu_ins[i]);
|
||||
if (gpu_instance->adev == adev) {
|
||||
mgpu_info.gpu_ins[i] =
|
||||
mgpu_info.gpu_ins[mgpu_info.num_gpu - 1];
|
||||
mgpu_info.num_gpu--;
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
mgpu_info.num_apu--;
|
||||
else
|
||||
mgpu_info.num_dgpu--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&mgpu_info.mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_driver_unload_kms - Main unload function for KMS.
|
||||
*
|
||||
|
@ -55,6 +79,8 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
|
|||
if (adev == NULL)
|
||||
return;
|
||||
|
||||
amdgpu_unregister_gpu_instance(adev);
|
||||
|
||||
if (adev->rmmio == NULL)
|
||||
goto done_free;
|
||||
|
||||
|
@ -75,6 +101,31 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
|
|||
dev->dev_private = NULL;
|
||||
}
|
||||
|
||||
static void amdgpu_register_gpu_instance(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_gpu_instance *gpu_instance;
|
||||
|
||||
mutex_lock(&mgpu_info.mutex);
|
||||
|
||||
if (mgpu_info.num_gpu >= MAX_GPU_INSTANCE) {
|
||||
DRM_ERROR("Cannot register more gpu instance\n");
|
||||
mutex_unlock(&mgpu_info.mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
gpu_instance = &(mgpu_info.gpu_ins[mgpu_info.num_gpu]);
|
||||
gpu_instance->adev = adev;
|
||||
gpu_instance->mgpu_fan_enabled = 0;
|
||||
|
||||
mgpu_info.num_gpu++;
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
mgpu_info.num_apu++;
|
||||
else
|
||||
mgpu_info.num_dgpu++;
|
||||
|
||||
mutex_unlock(&mgpu_info.mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_driver_load_kms - Main load function for KMS.
|
||||
*
|
||||
|
@ -169,6 +220,7 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
|
|||
pm_runtime_put_autosuspend(dev->dev);
|
||||
}
|
||||
|
||||
amdgpu_register_gpu_instance(adev);
|
||||
out:
|
||||
if (r) {
|
||||
/* balance pm_runtime_get_sync in amdgpu_driver_unload_kms */
|
||||
|
|
|
@ -1120,12 +1120,19 @@ static ssize_t amdgpu_hwmon_set_pwm1(struct device *dev,
|
|||
struct amdgpu_device *adev = dev_get_drvdata(dev);
|
||||
int err;
|
||||
u32 value;
|
||||
u32 pwm_mode;
|
||||
|
||||
/* Can't adjust fan when the card is off */
|
||||
if ((adev->flags & AMD_IS_PX) &&
|
||||
(adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON))
|
||||
return -EINVAL;
|
||||
|
||||
pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);
|
||||
if (pwm_mode != AMD_FAN_CTRL_MANUAL) {
|
||||
pr_info("manual fan speed control should be enabled first\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = kstrtou32(buf, 10, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -1187,6 +1194,148 @@ static ssize_t amdgpu_hwmon_get_fan1_input(struct device *dev,
|
|||
return sprintf(buf, "%i\n", speed);
|
||||
}
|
||||
|
||||
static ssize_t amdgpu_hwmon_get_fan1_min(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct amdgpu_device *adev = dev_get_drvdata(dev);
|
||||
u32 min_rpm = 0;
|
||||
u32 size = sizeof(min_rpm);
|
||||
int r;
|
||||
|
||||
if (!adev->powerplay.pp_funcs->read_sensor)
|
||||
return -EINVAL;
|
||||
|
||||
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MIN_FAN_RPM,
|
||||
(void *)&min_rpm, &size);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", min_rpm);
|
||||
}
|
||||
|
||||
static ssize_t amdgpu_hwmon_get_fan1_max(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct amdgpu_device *adev = dev_get_drvdata(dev);
|
||||
u32 max_rpm = 0;
|
||||
u32 size = sizeof(max_rpm);
|
||||
int r;
|
||||
|
||||
if (!adev->powerplay.pp_funcs->read_sensor)
|
||||
return -EINVAL;
|
||||
|
||||
r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MAX_FAN_RPM,
|
||||
(void *)&max_rpm, &size);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", max_rpm);
|
||||
}
|
||||
|
||||
static ssize_t amdgpu_hwmon_get_fan1_target(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct amdgpu_device *adev = dev_get_drvdata(dev);
|
||||
int err;
|
||||
u32 rpm = 0;
|
||||
|
||||
/* Can't adjust fan when the card is off */
|
||||
if ((adev->flags & AMD_IS_PX) &&
|
||||
(adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON))
|
||||
return -EINVAL;
|
||||
|
||||
if (adev->powerplay.pp_funcs->get_fan_speed_rpm) {
|
||||
err = amdgpu_dpm_get_fan_speed_rpm(adev, &rpm);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%i\n", rpm);
|
||||
}
|
||||
|
||||
static ssize_t amdgpu_hwmon_set_fan1_target(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct amdgpu_device *adev = dev_get_drvdata(dev);
|
||||
int err;
|
||||
u32 value;
|
||||
u32 pwm_mode;
|
||||
|
||||
pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);
|
||||
if (pwm_mode != AMD_FAN_CTRL_MANUAL)
|
||||
return -ENODATA;
|
||||
|
||||
/* Can't adjust fan when the card is off */
|
||||
if ((adev->flags & AMD_IS_PX) &&
|
||||
(adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON))
|
||||
return -EINVAL;
|
||||
|
||||
err = kstrtou32(buf, 10, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (adev->powerplay.pp_funcs->set_fan_speed_rpm) {
|
||||
err = amdgpu_dpm_set_fan_speed_rpm(adev, value);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t amdgpu_hwmon_get_fan1_enable(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct amdgpu_device *adev = dev_get_drvdata(dev);
|
||||
u32 pwm_mode = 0;
|
||||
|
||||
if (!adev->powerplay.pp_funcs->get_fan_control_mode)
|
||||
return -EINVAL;
|
||||
|
||||
pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);
|
||||
|
||||
return sprintf(buf, "%i\n", pwm_mode == AMD_FAN_CTRL_AUTO ? 0 : 1);
|
||||
}
|
||||
|
||||
static ssize_t amdgpu_hwmon_set_fan1_enable(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct amdgpu_device *adev = dev_get_drvdata(dev);
|
||||
int err;
|
||||
int value;
|
||||
u32 pwm_mode;
|
||||
|
||||
/* Can't adjust fan when the card is off */
|
||||
if ((adev->flags & AMD_IS_PX) &&
|
||||
(adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON))
|
||||
return -EINVAL;
|
||||
|
||||
if (!adev->powerplay.pp_funcs->set_fan_control_mode)
|
||||
return -EINVAL;
|
||||
|
||||
err = kstrtoint(buf, 10, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (value == 0)
|
||||
pwm_mode = AMD_FAN_CTRL_AUTO;
|
||||
else if (value == 1)
|
||||
pwm_mode = AMD_FAN_CTRL_MANUAL;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
amdgpu_dpm_set_fan_control_mode(adev, pwm_mode);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t amdgpu_hwmon_show_vddgfx(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
|
@ -1406,8 +1555,16 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev,
|
|||
*
|
||||
* - pwm1_max: pulse width modulation fan control maximum level (255)
|
||||
*
|
||||
* - fan1_min: an minimum value Unit: revolution/min (RPM)
|
||||
*
|
||||
* - fan1_max: an maxmum value Unit: revolution/max (RPM)
|
||||
*
|
||||
* - fan1_input: fan speed in RPM
|
||||
*
|
||||
* - fan[1-*]_target: Desired fan speed Unit: revolution/min (RPM)
|
||||
*
|
||||
* - fan[1-*]_enable: Enable or disable the sensors.1: Enable 0: Disable
|
||||
*
|
||||
* You can use hwmon tools like sensors to view this information on your system.
|
||||
*
|
||||
*/
|
||||
|
@ -1420,6 +1577,10 @@ static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_pwm1_
|
|||
static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO, amdgpu_hwmon_get_pwm1_min, NULL, 0);
|
||||
static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO, amdgpu_hwmon_get_pwm1_max, NULL, 0);
|
||||
static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, amdgpu_hwmon_get_fan1_input, NULL, 0);
|
||||
static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO, amdgpu_hwmon_get_fan1_min, NULL, 0);
|
||||
static SENSOR_DEVICE_ATTR(fan1_max, S_IRUGO, amdgpu_hwmon_get_fan1_max, NULL, 0);
|
||||
static SENSOR_DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_fan1_target, amdgpu_hwmon_set_fan1_target, 0);
|
||||
static SENSOR_DEVICE_ATTR(fan1_enable, S_IRUGO | S_IWUSR, amdgpu_hwmon_get_fan1_enable, amdgpu_hwmon_set_fan1_enable, 0);
|
||||
static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, amdgpu_hwmon_show_vddgfx, NULL, 0);
|
||||
static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, amdgpu_hwmon_show_vddgfx_label, NULL, 0);
|
||||
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, amdgpu_hwmon_show_vddnb, NULL, 0);
|
||||
|
@ -1438,6 +1599,10 @@ static struct attribute *hwmon_attributes[] = {
|
|||
&sensor_dev_attr_pwm1_min.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm1_max.dev_attr.attr,
|
||||
&sensor_dev_attr_fan1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_fan1_min.dev_attr.attr,
|
||||
&sensor_dev_attr_fan1_max.dev_attr.attr,
|
||||
&sensor_dev_attr_fan1_target.dev_attr.attr,
|
||||
&sensor_dev_attr_fan1_enable.dev_attr.attr,
|
||||
&sensor_dev_attr_in0_input.dev_attr.attr,
|
||||
&sensor_dev_attr_in0_label.dev_attr.attr,
|
||||
&sensor_dev_attr_in1_input.dev_attr.attr,
|
||||
|
@ -1456,13 +1621,16 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
|
|||
struct amdgpu_device *adev = dev_get_drvdata(dev);
|
||||
umode_t effective_mode = attr->mode;
|
||||
|
||||
|
||||
/* Skip fan attributes if fan is not present */
|
||||
if (adev->pm.no_fan && (attr == &sensor_dev_attr_pwm1.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_pwm1_min.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_fan1_input.dev_attr.attr))
|
||||
attr == &sensor_dev_attr_fan1_input.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_fan1_min.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_fan1_max.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_fan1_target.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_fan1_enable.dev_attr.attr))
|
||||
return 0;
|
||||
|
||||
/* Skip limit attributes if DPM is not enabled */
|
||||
|
@ -1472,7 +1640,12 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
|
|||
attr == &sensor_dev_attr_pwm1.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
|
||||
attr == &sensor_dev_attr_pwm1_min.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_fan1_input.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_fan1_min.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_fan1_max.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_fan1_target.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_fan1_enable.dev_attr.attr))
|
||||
return 0;
|
||||
|
||||
/* mask fan attributes if we have no bindings for this asic to expose */
|
||||
|
@ -1497,10 +1670,18 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
|
|||
/* hide max/min values if we can't both query and manage the fan */
|
||||
if ((!adev->powerplay.pp_funcs->set_fan_speed_percent &&
|
||||
!adev->powerplay.pp_funcs->get_fan_speed_percent) &&
|
||||
(!adev->powerplay.pp_funcs->set_fan_speed_rpm &&
|
||||
!adev->powerplay.pp_funcs->get_fan_speed_rpm) &&
|
||||
(attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
|
||||
return 0;
|
||||
|
||||
if ((!adev->powerplay.pp_funcs->set_fan_speed_rpm &&
|
||||
!adev->powerplay.pp_funcs->get_fan_speed_rpm) &&
|
||||
(attr == &sensor_dev_attr_fan1_max.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_fan1_min.dev_attr.attr))
|
||||
return 0;
|
||||
|
||||
/* only APUs have vddnb */
|
||||
if (!(adev->flags & AMD_IS_APU) &&
|
||||
(attr == &sensor_dev_attr_in1_input.dev_attr.attr ||
|
||||
|
@ -1976,6 +2157,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
|
|||
static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t value;
|
||||
uint64_t value64;
|
||||
uint32_t query = 0;
|
||||
int size;
|
||||
|
||||
|
@ -2014,6 +2196,10 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
|
|||
seq_printf(m, "GPU Load: %u %%\n", value);
|
||||
seq_printf(m, "\n");
|
||||
|
||||
/* SMC feature mask */
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_ENABLED_SMC_FEATURES_MASK, (void *)&value64, &size))
|
||||
seq_printf(m, "SMC Feature Mask: 0x%016llx\n", value64);
|
||||
|
||||
/* UVD clocks */
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_POWER, (void *)&value, &size)) {
|
||||
if (!value) {
|
||||
|
|
|
@ -452,8 +452,6 @@ static int psp_hw_fini(void *handle)
|
|||
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
|
||||
return 0;
|
||||
|
||||
amdgpu_ucode_fini_bo(adev);
|
||||
|
||||
psp_ring_destroy(psp, PSP_RING_TYPE__KM);
|
||||
|
||||
amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
|
||||
|
|
|
@ -77,6 +77,7 @@ struct amdgpu_fence_driver {
|
|||
bool initialized;
|
||||
struct amdgpu_irq_src *irq_src;
|
||||
unsigned irq_type;
|
||||
struct timer_list fallback_timer;
|
||||
unsigned num_fences_mask;
|
||||
spinlock_t lock;
|
||||
struct dma_fence **fences;
|
||||
|
@ -96,7 +97,7 @@ void amdgpu_fence_driver_resume(struct amdgpu_device *adev);
|
|||
int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence,
|
||||
unsigned flags);
|
||||
int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s);
|
||||
void amdgpu_fence_process(struct amdgpu_ring *ring);
|
||||
bool amdgpu_fence_process(struct amdgpu_ring *ring);
|
||||
int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
|
||||
signed long amdgpu_fence_wait_polling(struct amdgpu_ring *ring,
|
||||
uint32_t wait_seq,
|
||||
|
|
|
@ -46,10 +46,6 @@ struct amdgpu_sdma_instance {
|
|||
|
||||
struct amdgpu_sdma {
|
||||
struct amdgpu_sdma_instance instance[AMDGPU_MAX_SDMA_INSTANCES];
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
//SI DMA has a difference trap irq number for the second engine
|
||||
struct amdgpu_irq_src trap_irq_1;
|
||||
#endif
|
||||
struct amdgpu_irq_src trap_irq;
|
||||
struct amdgpu_irq_src illegal_inst_irq;
|
||||
int num_instances;
|
||||
|
|
|
@ -103,7 +103,7 @@ TRACE_EVENT(amdgpu_iv,
|
|||
__entry->src_data[2] = iv->src_data[2];
|
||||
__entry->src_data[3] = iv->src_data[3];
|
||||
),
|
||||
TP_printk("client_id:%u src_id:%u ring:%u vmid:%u timestamp: %llu pasid:%u src_data: %08x %08x %08x %08x\n",
|
||||
TP_printk("client_id:%u src_id:%u ring:%u vmid:%u timestamp: %llu pasid:%u src_data: %08x %08x %08x %08x",
|
||||
__entry->client_id, __entry->src_id,
|
||||
__entry->ring_id, __entry->vmid,
|
||||
__entry->timestamp, __entry->pasid,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
/* Copyright Red Hat Inc 2010.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
|
|
|
@ -297,10 +297,7 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
|
|||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
case CHIP_VEGAM:
|
||||
if (!load_type)
|
||||
return AMDGPU_FW_LOAD_DIRECT;
|
||||
else
|
||||
return AMDGPU_FW_LOAD_SMU;
|
||||
return AMDGPU_FW_LOAD_SMU;
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_VEGA12:
|
||||
|
@ -423,32 +420,41 @@ static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_ucode_create_bo(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) {
|
||||
amdgpu_bo_create_kernel(adev, adev->firmware.fw_size, PAGE_SIZE,
|
||||
amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->firmware.fw_buf,
|
||||
&adev->firmware.fw_buf_mc,
|
||||
&adev->firmware.fw_buf_ptr);
|
||||
if (!adev->firmware.fw_buf) {
|
||||
dev_err(adev->dev, "failed to create kernel buffer for firmware.fw_buf\n");
|
||||
return -ENOMEM;
|
||||
} else if (amdgpu_sriov_vf(adev)) {
|
||||
memset(adev->firmware.fw_buf_ptr, 0, adev->firmware.fw_size);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_ucode_free_bo(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT)
|
||||
amdgpu_bo_free_kernel(&adev->firmware.fw_buf,
|
||||
&adev->firmware.fw_buf_mc,
|
||||
&adev->firmware.fw_buf_ptr);
|
||||
}
|
||||
|
||||
int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
|
||||
{
|
||||
uint64_t fw_offset = 0;
|
||||
int i, err;
|
||||
int i;
|
||||
struct amdgpu_firmware_info *ucode = NULL;
|
||||
const struct common_firmware_header *header = NULL;
|
||||
|
||||
if (!adev->firmware.fw_size) {
|
||||
dev_warn(adev->dev, "No ip firmware need to load\n");
|
||||
/* for baremetal, the ucode is allocated in gtt, so don't need to fill the bo when reset/suspend */
|
||||
if (!amdgpu_sriov_vf(adev) && (adev->in_gpu_reset || adev->in_suspend))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!adev->in_gpu_reset) {
|
||||
err = amdgpu_bo_create_kernel(adev, adev->firmware.fw_size, PAGE_SIZE,
|
||||
amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->firmware.fw_buf,
|
||||
&adev->firmware.fw_buf_mc,
|
||||
&adev->firmware.fw_buf_ptr);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "failed to create kernel buffer for firmware.fw_buf\n");
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
memset(adev->firmware.fw_buf_ptr, 0, adev->firmware.fw_size);
|
||||
|
||||
/*
|
||||
* if SMU loaded firmware, it needn't add SMC, UVD, and VCE
|
||||
* ucode info here
|
||||
|
@ -465,7 +471,6 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
|
|||
for (i = 0; i < adev->firmware.max_ucodes; i++) {
|
||||
ucode = &adev->firmware.ucode[i];
|
||||
if (ucode->fw) {
|
||||
header = (const struct common_firmware_header *)ucode->fw->data;
|
||||
amdgpu_ucode_init_single_fw(adev, ucode, adev->firmware.fw_buf_mc + fw_offset,
|
||||
adev->firmware.fw_buf_ptr + fw_offset);
|
||||
if (i == AMDGPU_UCODE_ID_CP_MEC1 &&
|
||||
|
@ -480,33 +485,4 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
if (err)
|
||||
adev->firmware.load_type = AMDGPU_FW_LOAD_DIRECT;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int amdgpu_ucode_fini_bo(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
struct amdgpu_firmware_info *ucode = NULL;
|
||||
|
||||
if (!adev->firmware.fw_size)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < adev->firmware.max_ucodes; i++) {
|
||||
ucode = &adev->firmware.ucode[i];
|
||||
if (ucode->fw) {
|
||||
ucode->mc_addr = 0;
|
||||
ucode->kaddr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_bo_free_kernel(&adev->firmware.fw_buf,
|
||||
&adev->firmware.fw_buf_mc,
|
||||
&adev->firmware.fw_buf_ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -276,8 +276,10 @@ void amdgpu_ucode_print_gpu_info_hdr(const struct common_firmware_header *hdr);
|
|||
int amdgpu_ucode_validate(const struct firmware *fw);
|
||||
bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr,
|
||||
uint16_t hdr_major, uint16_t hdr_minor);
|
||||
|
||||
int amdgpu_ucode_init_bo(struct amdgpu_device *adev);
|
||||
int amdgpu_ucode_fini_bo(struct amdgpu_device *adev);
|
||||
int amdgpu_ucode_create_bo(struct amdgpu_device *adev);
|
||||
void amdgpu_ucode_free_bo(struct amdgpu_device *adev);
|
||||
|
||||
enum amdgpu_firmware_load_type
|
||||
amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type);
|
||||
|
|
|
@ -258,6 +258,8 @@ int amdgpu_vce_suspend(struct amdgpu_device *adev)
|
|||
{
|
||||
int i;
|
||||
|
||||
cancel_delayed_work_sync(&adev->vce.idle_work);
|
||||
|
||||
if (adev->vce.vcpu_bo == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -268,7 +270,6 @@ int amdgpu_vce_suspend(struct amdgpu_device *adev)
|
|||
if (i == AMDGPU_MAX_VCE_HANDLES)
|
||||
return 0;
|
||||
|
||||
cancel_delayed_work_sync(&adev->vce.idle_work);
|
||||
/* TODO: suspending running encoding sessions isn't supported */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "soc15_common.h"
|
||||
|
||||
#include "vcn/vcn_1_0_offset.h"
|
||||
#include "vcn/vcn_1_0_sh_mask.h"
|
||||
|
||||
/* 1 second timeout */
|
||||
#define VCN_IDLE_TIMEOUT msecs_to_jiffies(1000)
|
||||
|
@ -120,8 +121,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
|||
version_major, version_minor, family_id);
|
||||
}
|
||||
|
||||
bo_size = AMDGPU_VCN_STACK_SIZE + AMDGPU_VCN_HEAP_SIZE
|
||||
+ AMDGPU_VCN_SESSION_SIZE * 40;
|
||||
bo_size = AMDGPU_VCN_STACK_SIZE + AMDGPU_VCN_CONTEXT_SIZE;
|
||||
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
|
||||
bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
|
||||
r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
|
||||
|
@ -162,11 +162,11 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
|
|||
unsigned size;
|
||||
void *ptr;
|
||||
|
||||
cancel_delayed_work_sync(&adev->vcn.idle_work);
|
||||
|
||||
if (adev->vcn.vcpu_bo == NULL)
|
||||
return 0;
|
||||
|
||||
cancel_delayed_work_sync(&adev->vcn.idle_work);
|
||||
|
||||
size = amdgpu_bo_size(adev->vcn.vcpu_bo);
|
||||
ptr = adev->vcn.cpu_addr;
|
||||
|
||||
|
@ -212,18 +212,161 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_vcn_pause_dpg_mode(struct amdgpu_device *adev,
|
||||
struct dpg_pause_state *new_state)
|
||||
{
|
||||
int ret_code;
|
||||
uint32_t reg_data = 0;
|
||||
uint32_t reg_data2 = 0;
|
||||
struct amdgpu_ring *ring;
|
||||
|
||||
/* pause/unpause if state is changed */
|
||||
if (adev->vcn.pause_state.fw_based != new_state->fw_based) {
|
||||
DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d",
|
||||
adev->vcn.pause_state.fw_based, adev->vcn.pause_state.jpeg,
|
||||
new_state->fw_based, new_state->jpeg);
|
||||
|
||||
reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) &
|
||||
(~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
|
||||
|
||||
if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
|
||||
ret_code = 0;
|
||||
|
||||
if (!(reg_data & UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK))
|
||||
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
|
||||
if (!ret_code) {
|
||||
/* pause DPG non-jpeg */
|
||||
reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
|
||||
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE,
|
||||
UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
|
||||
UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, ret_code);
|
||||
|
||||
/* Restore */
|
||||
ring = &adev->vcn.ring_enc[0];
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
|
||||
|
||||
ring = &adev->vcn.ring_enc[1];
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
|
||||
|
||||
ring = &adev->vcn.ring_dec;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
|
||||
RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2));
|
||||
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
|
||||
UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
}
|
||||
} else {
|
||||
/* unpause dpg non-jpeg, no need to wait */
|
||||
reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
|
||||
}
|
||||
adev->vcn.pause_state.fw_based = new_state->fw_based;
|
||||
}
|
||||
|
||||
/* pause/unpause if state is changed */
|
||||
if (adev->vcn.pause_state.jpeg != new_state->jpeg) {
|
||||
DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d",
|
||||
adev->vcn.pause_state.fw_based, adev->vcn.pause_state.jpeg,
|
||||
new_state->fw_based, new_state->jpeg);
|
||||
|
||||
reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) &
|
||||
(~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK);
|
||||
|
||||
if (new_state->jpeg == VCN_DPG_STATE__PAUSE) {
|
||||
ret_code = 0;
|
||||
|
||||
if (!(reg_data & UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK))
|
||||
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
|
||||
if (!ret_code) {
|
||||
/* Make sure JPRG Snoop is disabled before sending the pause */
|
||||
reg_data2 = RREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS);
|
||||
reg_data2 |= UVD_POWER_STATUS__JRBC_SNOOP_DIS_MASK;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, reg_data2);
|
||||
|
||||
/* pause DPG jpeg */
|
||||
reg_data |= UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
|
||||
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE,
|
||||
UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK,
|
||||
UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK, ret_code);
|
||||
|
||||
/* Restore */
|
||||
ring = &adev->vcn.ring_jpeg;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,
|
||||
UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK |
|
||||
UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
|
||||
lower_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
|
||||
upper_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR, ring->wptr);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, ring->wptr);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,
|
||||
UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
|
||||
|
||||
ring = &adev->vcn.ring_dec;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
|
||||
RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2));
|
||||
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
|
||||
UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
}
|
||||
} else {
|
||||
/* unpause dpg jpeg, no need to wait */
|
||||
reg_data &= ~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
|
||||
}
|
||||
adev->vcn.pause_state.jpeg = new_state->jpeg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_device *adev =
|
||||
container_of(work, struct amdgpu_device, vcn.idle_work.work);
|
||||
unsigned fences = amdgpu_fence_count_emitted(&adev->vcn.ring_dec);
|
||||
unsigned i;
|
||||
unsigned int fences = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
|
||||
fences += amdgpu_fence_count_emitted(&adev->vcn.ring_enc[i]);
|
||||
}
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
|
||||
struct dpg_pause_state new_state;
|
||||
|
||||
if (fences)
|
||||
new_state.fw_based = VCN_DPG_STATE__PAUSE;
|
||||
else
|
||||
new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
|
||||
|
||||
if (amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg))
|
||||
new_state.jpeg = VCN_DPG_STATE__PAUSE;
|
||||
else
|
||||
new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
|
||||
|
||||
amdgpu_vcn_pause_dpg_mode(adev, &new_state);
|
||||
}
|
||||
|
||||
fences += amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg);
|
||||
fences += amdgpu_fence_count_emitted(&adev->vcn.ring_dec);
|
||||
|
||||
if (fences == 0) {
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
|
@ -250,6 +393,22 @@ 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) {
|
||||
struct dpg_pause_state new_state;
|
||||
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
|
||||
new_state.fw_based = VCN_DPG_STATE__PAUSE;
|
||||
else
|
||||
new_state.fw_based = adev->vcn.pause_state.fw_based;
|
||||
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG)
|
||||
new_state.jpeg = VCN_DPG_STATE__PAUSE;
|
||||
else
|
||||
new_state.jpeg = adev->vcn.pause_state.jpeg;
|
||||
|
||||
amdgpu_vcn_pause_dpg_mode(adev, &new_state);
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
|
||||
|
@ -264,7 +423,7 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring)
|
|||
unsigned i;
|
||||
int r;
|
||||
|
||||
WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0xCAFEDEAD);
|
||||
WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD);
|
||||
r = amdgpu_ring_alloc(ring, 3);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n",
|
||||
|
@ -272,11 +431,11 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring)
|
|||
return r;
|
||||
}
|
||||
amdgpu_ring_write(ring,
|
||||
PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0));
|
||||
PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0));
|
||||
amdgpu_ring_write(ring, 0xDEADBEEF);
|
||||
amdgpu_ring_commit(ring);
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID));
|
||||
tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9));
|
||||
if (tmp == 0xDEADBEEF)
|
||||
break;
|
||||
DRM_UDELAY(1);
|
||||
|
@ -616,7 +775,7 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring)
|
|||
unsigned i;
|
||||
int r;
|
||||
|
||||
WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0xCAFEDEAD);
|
||||
WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD);
|
||||
r = amdgpu_ring_alloc(ring, 3);
|
||||
|
||||
if (r) {
|
||||
|
@ -626,12 +785,12 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
amdgpu_ring_write(ring,
|
||||
PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0, 0, 0));
|
||||
PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0, 0, 0));
|
||||
amdgpu_ring_write(ring, 0xDEADBEEF);
|
||||
amdgpu_ring_commit(ring);
|
||||
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID));
|
||||
tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9));
|
||||
if (tmp == 0xDEADBEEF)
|
||||
break;
|
||||
DRM_UDELAY(1);
|
||||
|
@ -665,7 +824,7 @@ static int amdgpu_vcn_jpeg_set_reg(struct amdgpu_ring *ring, uint32_t handle,
|
|||
|
||||
ib = &job->ibs[0];
|
||||
|
||||
ib->ptr[0] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_PITCH), 0, 0, PACKETJ_TYPE0);
|
||||
ib->ptr[0] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0, 0, PACKETJ_TYPE0);
|
||||
ib->ptr[1] = 0xDEADBEEF;
|
||||
for (i = 2; i < 16; i += 2) {
|
||||
ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
|
||||
|
@ -714,7 +873,7 @@ int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
r = 0;
|
||||
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_PITCH));
|
||||
tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9));
|
||||
if (tmp == 0xDEADBEEF)
|
||||
break;
|
||||
DRM_UDELAY(1);
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
#ifndef __AMDGPU_VCN_H__
|
||||
#define __AMDGPU_VCN_H__
|
||||
|
||||
#define AMDGPU_VCN_STACK_SIZE (200*1024)
|
||||
#define AMDGPU_VCN_HEAP_SIZE (256*1024)
|
||||
#define AMDGPU_VCN_SESSION_SIZE (50*1024)
|
||||
#define AMDGPU_VCN_STACK_SIZE (128*1024)
|
||||
#define AMDGPU_VCN_CONTEXT_SIZE (512*1024)
|
||||
|
||||
#define AMDGPU_VCN_FIRMWARE_OFFSET 256
|
||||
#define AMDGPU_VCN_MAX_ENC_RINGS 3
|
||||
|
||||
|
@ -56,6 +56,16 @@ enum engine_status_constants {
|
|||
UVD_STATUS__RBC_BUSY = 0x1,
|
||||
};
|
||||
|
||||
enum internal_dpg_state {
|
||||
VCN_DPG_STATE__UNPAUSE = 0,
|
||||
VCN_DPG_STATE__PAUSE,
|
||||
};
|
||||
|
||||
struct dpg_pause_state {
|
||||
enum internal_dpg_state fw_based;
|
||||
enum internal_dpg_state jpeg;
|
||||
};
|
||||
|
||||
struct amdgpu_vcn {
|
||||
struct amdgpu_bo *vcpu_bo;
|
||||
void *cpu_addr;
|
||||
|
@ -69,6 +79,8 @@ struct amdgpu_vcn {
|
|||
struct amdgpu_ring ring_jpeg;
|
||||
struct amdgpu_irq_src irq;
|
||||
unsigned num_enc_rings;
|
||||
enum amd_powergating_state cur_state;
|
||||
struct dpg_pause_state pause_state;
|
||||
};
|
||||
|
||||
int amdgpu_vcn_sw_init(struct amdgpu_device *adev);
|
||||
|
|
|
@ -6277,12 +6277,12 @@ static int ci_dpm_sw_init(void *handle)
|
|||
int ret;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
ret = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 230,
|
||||
ret = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 230,
|
||||
&adev->pm.dpm.thermal.irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 231,
|
||||
ret = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 231,
|
||||
&adev->pm.dpm.thermal.irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -2002,6 +2002,8 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &cik_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v7_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &cik_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v7_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
|
||||
if (amdgpu_dpm == -1)
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
else
|
||||
|
@ -2014,8 +2016,6 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
|
|||
#endif
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &dce_v8_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v7_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &uvd_v4_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vce_v2_0_ip_block);
|
||||
break;
|
||||
|
@ -2023,6 +2023,8 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &cik_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v7_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &cik_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v7_3_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
|
||||
if (amdgpu_dpm == -1)
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
else
|
||||
|
@ -2035,8 +2037,6 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
|
|||
#endif
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &dce_v8_5_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v7_3_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &uvd_v4_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vce_v2_0_ip_block);
|
||||
break;
|
||||
|
@ -2044,6 +2044,8 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &cik_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v7_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &cik_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v7_1_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &kv_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
|
@ -2053,8 +2055,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
|
|||
#endif
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &dce_v8_1_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v7_1_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
|
||||
|
||||
amdgpu_device_ip_block_add(adev, &uvd_v4_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vce_v2_0_ip_block);
|
||||
break;
|
||||
|
@ -2063,6 +2064,8 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &cik_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v7_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &cik_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v7_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &kv_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
|
@ -2072,8 +2075,6 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
|
|||
#endif
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &dce_v8_3_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v7_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &uvd_v4_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vce_v2_0_ip_block);
|
||||
break;
|
||||
|
|
|
@ -276,7 +276,7 @@ static void cik_ih_decode_iv(struct amdgpu_device *adev,
|
|||
dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
|
||||
dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
|
||||
|
||||
entry->client_id = AMDGPU_IH_CLIENTID_LEGACY;
|
||||
entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
|
||||
entry->src_id = dw[0] & 0xff;
|
||||
entry->src_data[0] = dw[1] & 0xfffffff;
|
||||
entry->ring_id = dw[2] & 0xff;
|
||||
|
@ -318,7 +318,7 @@ static int cik_ih_sw_init(void *handle)
|
|||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = amdgpu_ih_ring_init(adev, 64 * 1024, false);
|
||||
r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 64 * 1024, false);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -332,7 +332,7 @@ static int cik_ih_sw_fini(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
amdgpu_irq_fini(adev);
|
||||
amdgpu_ih_ring_fini(adev);
|
||||
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
|
||||
amdgpu_irq_remove_domain(adev);
|
||||
|
||||
return 0;
|
||||
|
@ -468,8 +468,7 @@ static const struct amdgpu_ih_funcs cik_ih_funcs = {
|
|||
|
||||
static void cik_ih_set_interrupt_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->irq.ih_funcs == NULL)
|
||||
adev->irq.ih_funcs = &cik_ih_funcs;
|
||||
adev->irq.ih_funcs = &cik_ih_funcs;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version cik_ih_ip_block =
|
||||
|
|
|
@ -970,19 +970,19 @@ static int cik_sdma_sw_init(void *handle)
|
|||
}
|
||||
|
||||
/* SDMA trap event */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 224,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 224,
|
||||
&adev->sdma.trap_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* SDMA Privileged inst */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 241,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 241,
|
||||
&adev->sdma.illegal_inst_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* SDMA Privileged inst */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 247,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 247,
|
||||
&adev->sdma.illegal_inst_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -1370,10 +1370,8 @@ static const struct amdgpu_buffer_funcs cik_sdma_buffer_funcs = {
|
|||
|
||||
static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->mman.buffer_funcs == NULL) {
|
||||
adev->mman.buffer_funcs = &cik_sdma_buffer_funcs;
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
|
||||
}
|
||||
adev->mman.buffer_funcs = &cik_sdma_buffer_funcs;
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
|
||||
}
|
||||
|
||||
static const struct amdgpu_vm_pte_funcs cik_sdma_vm_pte_funcs = {
|
||||
|
@ -1389,15 +1387,13 @@ static void cik_sdma_set_vm_pte_funcs(struct amdgpu_device *adev)
|
|||
struct drm_gpu_scheduler *sched;
|
||||
unsigned i;
|
||||
|
||||
if (adev->vm_manager.vm_pte_funcs == NULL) {
|
||||
adev->vm_manager.vm_pte_funcs = &cik_sdma_vm_pte_funcs;
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
sched = &adev->sdma.instance[i].ring.sched;
|
||||
adev->vm_manager.vm_pte_rqs[i] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances;
|
||||
adev->vm_manager.vm_pte_funcs = &cik_sdma_vm_pte_funcs;
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
sched = &adev->sdma.instance[i].ring.sched;
|
||||
adev->vm_manager.vm_pte_rqs[i] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version cik_sdma_ip_block =
|
||||
|
|
|
@ -255,7 +255,7 @@ static void cz_ih_decode_iv(struct amdgpu_device *adev,
|
|||
dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
|
||||
dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
|
||||
|
||||
entry->client_id = AMDGPU_IH_CLIENTID_LEGACY;
|
||||
entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
|
||||
entry->src_id = dw[0] & 0xff;
|
||||
entry->src_data[0] = dw[1] & 0xfffffff;
|
||||
entry->ring_id = dw[2] & 0xff;
|
||||
|
@ -297,7 +297,7 @@ static int cz_ih_sw_init(void *handle)
|
|||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = amdgpu_ih_ring_init(adev, 64 * 1024, false);
|
||||
r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 64 * 1024, false);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -311,7 +311,7 @@ static int cz_ih_sw_fini(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
amdgpu_irq_fini(adev);
|
||||
amdgpu_ih_ring_fini(adev);
|
||||
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
|
||||
amdgpu_irq_remove_domain(adev);
|
||||
|
||||
return 0;
|
||||
|
@ -449,8 +449,7 @@ static const struct amdgpu_ih_funcs cz_ih_funcs = {
|
|||
|
||||
static void cz_ih_set_interrupt_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->irq.ih_funcs == NULL)
|
||||
adev->irq.ih_funcs = &cz_ih_funcs;
|
||||
adev->irq.ih_funcs = &cz_ih_funcs;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version cz_ih_ip_block =
|
||||
|
|
|
@ -2746,19 +2746,19 @@ static int dce_v10_0_sw_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
for (i = 0; i < adev->mode_info.num_crtc; i++) {
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + 1, &adev->crtc_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i + 1, &adev->crtc_irq);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
for (i = VISLANDS30_IV_SRCID_D1_GRPH_PFLIP; i < 20; i += 2) {
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i, &adev->pageflip_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i, &adev->pageflip_irq);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* HPD hotplug */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A, &adev->hpd_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A, &adev->hpd_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -3570,8 +3570,7 @@ static const struct amdgpu_display_funcs dce_v10_0_display_funcs = {
|
|||
|
||||
static void dce_v10_0_set_display_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->mode_info.funcs == NULL)
|
||||
adev->mode_info.funcs = &dce_v10_0_display_funcs;
|
||||
adev->mode_info.funcs = &dce_v10_0_display_funcs;
|
||||
}
|
||||
|
||||
static const struct amdgpu_irq_src_funcs dce_v10_0_crtc_irq_funcs = {
|
||||
|
|
|
@ -2867,19 +2867,19 @@ static int dce_v11_0_sw_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
for (i = 0; i < adev->mode_info.num_crtc; i++) {
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + 1, &adev->crtc_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i + 1, &adev->crtc_irq);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
for (i = VISLANDS30_IV_SRCID_D1_GRPH_PFLIP; i < 20; i += 2) {
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i, &adev->pageflip_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i, &adev->pageflip_irq);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* HPD hotplug */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A, &adev->hpd_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A, &adev->hpd_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -3702,8 +3702,7 @@ static const struct amdgpu_display_funcs dce_v11_0_display_funcs = {
|
|||
|
||||
static void dce_v11_0_set_display_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->mode_info.funcs == NULL)
|
||||
adev->mode_info.funcs = &dce_v11_0_display_funcs;
|
||||
adev->mode_info.funcs = &dce_v11_0_display_funcs;
|
||||
}
|
||||
|
||||
static const struct amdgpu_irq_src_funcs dce_v11_0_crtc_irq_funcs = {
|
||||
|
|
|
@ -2616,19 +2616,19 @@ static int dce_v6_0_sw_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
for (i = 0; i < adev->mode_info.num_crtc; i++) {
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + 1, &adev->crtc_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i + 1, &adev->crtc_irq);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
for (i = 8; i < 20; i += 2) {
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i, &adev->pageflip_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i, &adev->pageflip_irq);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* HPD hotplug */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 42, &adev->hpd_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 42, &adev->hpd_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -3376,8 +3376,7 @@ static const struct amdgpu_display_funcs dce_v6_0_display_funcs = {
|
|||
|
||||
static void dce_v6_0_set_display_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->mode_info.funcs == NULL)
|
||||
adev->mode_info.funcs = &dce_v6_0_display_funcs;
|
||||
adev->mode_info.funcs = &dce_v6_0_display_funcs;
|
||||
}
|
||||
|
||||
static const struct amdgpu_irq_src_funcs dce_v6_0_crtc_irq_funcs = {
|
||||
|
|
|
@ -2643,19 +2643,19 @@ static int dce_v8_0_sw_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
for (i = 0; i < adev->mode_info.num_crtc; i++) {
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + 1, &adev->crtc_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i + 1, &adev->crtc_irq);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
for (i = 8; i < 20; i += 2) {
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i, &adev->pageflip_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i, &adev->pageflip_irq);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* HPD hotplug */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 42, &adev->hpd_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 42, &adev->hpd_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -3458,8 +3458,7 @@ static const struct amdgpu_display_funcs dce_v8_0_display_funcs = {
|
|||
|
||||
static void dce_v8_0_set_display_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->mode_info.funcs == NULL)
|
||||
adev->mode_info.funcs = &dce_v8_0_display_funcs;
|
||||
adev->mode_info.funcs = &dce_v8_0_display_funcs;
|
||||
}
|
||||
|
||||
static const struct amdgpu_irq_src_funcs dce_v8_0_crtc_irq_funcs = {
|
||||
|
|
|
@ -372,7 +372,7 @@ static int dce_virtual_sw_init(void *handle)
|
|||
int r, i;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER, &adev->crtc_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER, &adev->crtc_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -649,8 +649,7 @@ static const struct amdgpu_display_funcs dce_virtual_display_funcs = {
|
|||
|
||||
static void dce_virtual_set_display_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->mode_info.funcs == NULL)
|
||||
adev->mode_info.funcs = &dce_virtual_display_funcs;
|
||||
adev->mode_info.funcs = &dce_virtual_display_funcs;
|
||||
}
|
||||
|
||||
static int dce_virtual_pageflip(struct amdgpu_device *adev,
|
||||
|
|
|
@ -1552,7 +1552,7 @@ static void gfx_v6_0_config_init(struct amdgpu_device *adev)
|
|||
adev->gfx.config.double_offchip_lds_buf = 0;
|
||||
}
|
||||
|
||||
static void gfx_v6_0_gpu_init(struct amdgpu_device *adev)
|
||||
static void gfx_v6_0_constants_init(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 gb_addr_config = 0;
|
||||
u32 mc_shared_chmap, mc_arb_ramcfg;
|
||||
|
@ -3094,15 +3094,15 @@ static int gfx_v6_0_sw_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 181, &adev->gfx.eop_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 181, &adev->gfx.eop_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 184, &adev->gfx.priv_reg_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 184, &adev->gfx.priv_reg_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 185, &adev->gfx.priv_inst_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 185, &adev->gfx.priv_inst_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -3175,7 +3175,7 @@ static int gfx_v6_0_hw_init(void *handle)
|
|||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
gfx_v6_0_gpu_init(adev);
|
||||
gfx_v6_0_constants_init(adev);
|
||||
|
||||
r = gfx_v6_0_rlc_resume(adev);
|
||||
if (r)
|
||||
|
|
|
@ -1886,14 +1886,14 @@ static void gfx_v7_0_config_init(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
/**
|
||||
* gfx_v7_0_gpu_init - setup the 3D engine
|
||||
* gfx_v7_0_constants_init - setup the 3D engine
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Configures the 3D engine and tiling configuration
|
||||
* registers so that the 3D engine is usable.
|
||||
* init the gfx constants such as the 3D engine, tiling configuration
|
||||
* registers, maximum number of quad pipes, render backends...
|
||||
*/
|
||||
static void gfx_v7_0_gpu_init(struct amdgpu_device *adev)
|
||||
static void gfx_v7_0_constants_init(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 sh_mem_cfg, sh_static_mem_cfg, sh_mem_base;
|
||||
u32 tmp;
|
||||
|
@ -4516,18 +4516,18 @@ static int gfx_v7_0_sw_init(void *handle)
|
|||
adev->gfx.mec.num_queue_per_pipe = 8;
|
||||
|
||||
/* EOP Event */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 181, &adev->gfx.eop_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 181, &adev->gfx.eop_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Privileged reg */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 184,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 184,
|
||||
&adev->gfx.priv_reg_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Privileged inst */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 185,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 185,
|
||||
&adev->gfx.priv_inst_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -4624,7 +4624,7 @@ static int gfx_v7_0_hw_init(void *handle)
|
|||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
gfx_v7_0_gpu_init(adev);
|
||||
gfx_v7_0_constants_init(adev);
|
||||
|
||||
/* init rlc */
|
||||
r = gfx_v7_0_rlc_resume(adev);
|
||||
|
|
|
@ -1173,64 +1173,61 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_PFP];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_PFP;
|
||||
info->fw = adev->gfx.pfp_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_PFP];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_PFP;
|
||||
info->fw = adev->gfx.pfp_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_ME];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_ME;
|
||||
info->fw = adev->gfx.me_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_ME];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_ME;
|
||||
info->fw = adev->gfx.me_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_CE];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_CE;
|
||||
info->fw = adev->gfx.ce_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_CE];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_CE;
|
||||
info->fw = adev->gfx.ce_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_G];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_G;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_G];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_G;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1;
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
/* we need account JT in */
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr->jt_size) << 2, PAGE_SIZE);
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_STORAGE];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_STORAGE;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(64 * PAGE_SIZE), PAGE_SIZE);
|
||||
}
|
||||
|
||||
if (adev->gfx.mec2_fw) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC2];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
info->fw = adev->gfx.mec2_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
/* we need account JT in */
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr->jt_size) << 2, PAGE_SIZE);
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_STORAGE];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_STORAGE;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(64 * PAGE_SIZE), PAGE_SIZE);
|
||||
}
|
||||
|
||||
if (adev->gfx.mec2_fw) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC2];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
info->fw = adev->gfx.mec2_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -2048,36 +2045,31 @@ static int gfx_v8_0_sw_init(void *handle)
|
|||
adev->gfx.mec.num_pipe_per_mec = 4;
|
||||
adev->gfx.mec.num_queue_per_pipe = 8;
|
||||
|
||||
/* KIQ event */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_INT_IB2, &adev->gfx.kiq.irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* EOP Event */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_END_OF_PIPE, &adev->gfx.eop_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_END_OF_PIPE, &adev->gfx.eop_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Privileged reg */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_PRIV_REG_FAULT,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_PRIV_REG_FAULT,
|
||||
&adev->gfx.priv_reg_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Privileged inst */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_PRIV_INSTR_FAULT,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_PRIV_INSTR_FAULT,
|
||||
&adev->gfx.priv_inst_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Add CP EDC/ECC irq */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_ECC_ERROR,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_ECC_ERROR,
|
||||
&adev->gfx.cp_ecc_error_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* SQ interrupts. */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SQ_INTERRUPT_MSG,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SQ_INTERRUPT_MSG,
|
||||
&adev->gfx.sq_irq);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu_irq_add() for SQ failed: %d\n", r);
|
||||
|
@ -3835,7 +3827,7 @@ static void gfx_v8_0_config_init(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
|
||||
static void gfx_v8_0_gpu_init(struct amdgpu_device *adev)
|
||||
static void gfx_v8_0_constants_init(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 tmp, sh_static_mem_cfg;
|
||||
int i;
|
||||
|
@ -4181,65 +4173,11 @@ static void gfx_v8_0_rlc_start(struct amdgpu_device *adev)
|
|||
udelay(50);
|
||||
}
|
||||
|
||||
static int gfx_v8_0_rlc_load_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct rlc_firmware_header_v2_0 *hdr;
|
||||
const __le32 *fw_data;
|
||||
unsigned i, fw_size;
|
||||
|
||||
if (!adev->gfx.rlc_fw)
|
||||
return -EINVAL;
|
||||
|
||||
hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
|
||||
amdgpu_ucode_print_rlc_hdr(&hdr->header);
|
||||
|
||||
fw_data = (const __le32 *)(adev->gfx.rlc_fw->data +
|
||||
le32_to_cpu(hdr->header.ucode_array_offset_bytes));
|
||||
fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
|
||||
|
||||
WREG32(mmRLC_GPM_UCODE_ADDR, 0);
|
||||
for (i = 0; i < fw_size; i++)
|
||||
WREG32(mmRLC_GPM_UCODE_DATA, le32_to_cpup(fw_data++));
|
||||
WREG32(mmRLC_GPM_UCODE_ADDR, adev->gfx.rlc_fw_version);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
u32 tmp;
|
||||
|
||||
gfx_v8_0_rlc_stop(adev);
|
||||
|
||||
/* disable CG */
|
||||
tmp = RREG32(mmRLC_CGCG_CGLS_CTRL);
|
||||
tmp &= ~(RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK |
|
||||
RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK);
|
||||
WREG32(mmRLC_CGCG_CGLS_CTRL, tmp);
|
||||
if (adev->asic_type == CHIP_POLARIS11 ||
|
||||
adev->asic_type == CHIP_POLARIS10 ||
|
||||
adev->asic_type == CHIP_POLARIS12 ||
|
||||
adev->asic_type == CHIP_VEGAM) {
|
||||
tmp = RREG32(mmRLC_CGCG_CGLS_CTRL_3D);
|
||||
tmp &= ~0x3;
|
||||
WREG32(mmRLC_CGCG_CGLS_CTRL_3D, tmp);
|
||||
}
|
||||
|
||||
/* disable PG */
|
||||
WREG32(mmRLC_PG_CNTL, 0);
|
||||
|
||||
gfx_v8_0_rlc_reset(adev);
|
||||
gfx_v8_0_init_pg(adev);
|
||||
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
|
||||
/* legacy rlc firmware loading */
|
||||
r = gfx_v8_0_rlc_load_microcode(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
gfx_v8_0_rlc_start(adev);
|
||||
|
||||
return 0;
|
||||
|
@ -4265,63 +4203,6 @@ static void gfx_v8_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
|
|||
udelay(50);
|
||||
}
|
||||
|
||||
static int gfx_v8_0_cp_gfx_load_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct gfx_firmware_header_v1_0 *pfp_hdr;
|
||||
const struct gfx_firmware_header_v1_0 *ce_hdr;
|
||||
const struct gfx_firmware_header_v1_0 *me_hdr;
|
||||
const __le32 *fw_data;
|
||||
unsigned i, fw_size;
|
||||
|
||||
if (!adev->gfx.me_fw || !adev->gfx.pfp_fw || !adev->gfx.ce_fw)
|
||||
return -EINVAL;
|
||||
|
||||
pfp_hdr = (const struct gfx_firmware_header_v1_0 *)
|
||||
adev->gfx.pfp_fw->data;
|
||||
ce_hdr = (const struct gfx_firmware_header_v1_0 *)
|
||||
adev->gfx.ce_fw->data;
|
||||
me_hdr = (const struct gfx_firmware_header_v1_0 *)
|
||||
adev->gfx.me_fw->data;
|
||||
|
||||
amdgpu_ucode_print_gfx_hdr(&pfp_hdr->header);
|
||||
amdgpu_ucode_print_gfx_hdr(&ce_hdr->header);
|
||||
amdgpu_ucode_print_gfx_hdr(&me_hdr->header);
|
||||
|
||||
gfx_v8_0_cp_gfx_enable(adev, false);
|
||||
|
||||
/* PFP */
|
||||
fw_data = (const __le32 *)
|
||||
(adev->gfx.pfp_fw->data +
|
||||
le32_to_cpu(pfp_hdr->header.ucode_array_offset_bytes));
|
||||
fw_size = le32_to_cpu(pfp_hdr->header.ucode_size_bytes) / 4;
|
||||
WREG32(mmCP_PFP_UCODE_ADDR, 0);
|
||||
for (i = 0; i < fw_size; i++)
|
||||
WREG32(mmCP_PFP_UCODE_DATA, le32_to_cpup(fw_data++));
|
||||
WREG32(mmCP_PFP_UCODE_ADDR, adev->gfx.pfp_fw_version);
|
||||
|
||||
/* CE */
|
||||
fw_data = (const __le32 *)
|
||||
(adev->gfx.ce_fw->data +
|
||||
le32_to_cpu(ce_hdr->header.ucode_array_offset_bytes));
|
||||
fw_size = le32_to_cpu(ce_hdr->header.ucode_size_bytes) / 4;
|
||||
WREG32(mmCP_CE_UCODE_ADDR, 0);
|
||||
for (i = 0; i < fw_size; i++)
|
||||
WREG32(mmCP_CE_UCODE_DATA, le32_to_cpup(fw_data++));
|
||||
WREG32(mmCP_CE_UCODE_ADDR, adev->gfx.ce_fw_version);
|
||||
|
||||
/* ME */
|
||||
fw_data = (const __le32 *)
|
||||
(adev->gfx.me_fw->data +
|
||||
le32_to_cpu(me_hdr->header.ucode_array_offset_bytes));
|
||||
fw_size = le32_to_cpu(me_hdr->header.ucode_size_bytes) / 4;
|
||||
WREG32(mmCP_ME_RAM_WADDR, 0);
|
||||
for (i = 0; i < fw_size; i++)
|
||||
WREG32(mmCP_ME_RAM_DATA, le32_to_cpup(fw_data++));
|
||||
WREG32(mmCP_ME_RAM_WADDR, adev->gfx.me_fw_version);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 gfx_v8_0_get_csb_size(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 count = 0;
|
||||
|
@ -4521,52 +4402,6 @@ static void gfx_v8_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
|
|||
udelay(50);
|
||||
}
|
||||
|
||||
static int gfx_v8_0_cp_compute_load_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct gfx_firmware_header_v1_0 *mec_hdr;
|
||||
const __le32 *fw_data;
|
||||
unsigned i, fw_size;
|
||||
|
||||
if (!adev->gfx.mec_fw)
|
||||
return -EINVAL;
|
||||
|
||||
gfx_v8_0_cp_compute_enable(adev, false);
|
||||
|
||||
mec_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data;
|
||||
amdgpu_ucode_print_gfx_hdr(&mec_hdr->header);
|
||||
|
||||
fw_data = (const __le32 *)
|
||||
(adev->gfx.mec_fw->data +
|
||||
le32_to_cpu(mec_hdr->header.ucode_array_offset_bytes));
|
||||
fw_size = le32_to_cpu(mec_hdr->header.ucode_size_bytes) / 4;
|
||||
|
||||
/* MEC1 */
|
||||
WREG32(mmCP_MEC_ME1_UCODE_ADDR, 0);
|
||||
for (i = 0; i < fw_size; i++)
|
||||
WREG32(mmCP_MEC_ME1_UCODE_DATA, le32_to_cpup(fw_data+i));
|
||||
WREG32(mmCP_MEC_ME1_UCODE_ADDR, adev->gfx.mec_fw_version);
|
||||
|
||||
/* Loading MEC2 firmware is only necessary if MEC2 should run different microcode than MEC1. */
|
||||
if (adev->gfx.mec2_fw) {
|
||||
const struct gfx_firmware_header_v1_0 *mec2_hdr;
|
||||
|
||||
mec2_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec2_fw->data;
|
||||
amdgpu_ucode_print_gfx_hdr(&mec2_hdr->header);
|
||||
|
||||
fw_data = (const __le32 *)
|
||||
(adev->gfx.mec2_fw->data +
|
||||
le32_to_cpu(mec2_hdr->header.ucode_array_offset_bytes));
|
||||
fw_size = le32_to_cpu(mec2_hdr->header.ucode_size_bytes) / 4;
|
||||
|
||||
WREG32(mmCP_MEC_ME2_UCODE_ADDR, 0);
|
||||
for (i = 0; i < fw_size; i++)
|
||||
WREG32(mmCP_MEC_ME2_UCODE_DATA, le32_to_cpup(fw_data+i));
|
||||
WREG32(mmCP_MEC_ME2_UCODE_ADDR, adev->gfx.mec2_fw_version);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* KIQ functions */
|
||||
static void gfx_v8_0_kiq_setting(struct amdgpu_ring *ring)
|
||||
{
|
||||
|
@ -4892,7 +4727,7 @@ static int gfx_v8_0_kcq_init_queue(struct amdgpu_ring *ring)
|
|||
struct vi_mqd *mqd = ring->mqd_ptr;
|
||||
int mqd_idx = ring - &adev->gfx.compute_ring[0];
|
||||
|
||||
if (!adev->in_gpu_reset && !adev->gfx.in_suspend) {
|
||||
if (!adev->in_gpu_reset && !adev->in_suspend) {
|
||||
memset((void *)mqd, 0, sizeof(struct vi_mqd_allocation));
|
||||
((struct vi_mqd_allocation *)mqd)->dynamic_cu_mask = 0xFFFFFFFF;
|
||||
((struct vi_mqd_allocation *)mqd)->dynamic_rb_mask = 0xFFFFFFFF;
|
||||
|
@ -5000,17 +4835,6 @@ static int gfx_v8_0_cp_resume(struct amdgpu_device *adev)
|
|||
if (!(adev->flags & AMD_IS_APU))
|
||||
gfx_v8_0_enable_gui_idle_interrupt(adev, false);
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
|
||||
/* legacy firmware loading */
|
||||
r = gfx_v8_0_cp_gfx_load_microcode(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = gfx_v8_0_cp_compute_load_microcode(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = gfx_v8_0_kiq_resume(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -5039,7 +4863,7 @@ static int gfx_v8_0_hw_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
gfx_v8_0_init_golden_registers(adev);
|
||||
gfx_v8_0_gpu_init(adev);
|
||||
gfx_v8_0_constants_init(adev);
|
||||
|
||||
r = gfx_v8_0_rlc_resume(adev);
|
||||
if (r)
|
||||
|
@ -5080,6 +4904,55 @@ static int gfx_v8_0_kcq_disable(struct amdgpu_device *adev)
|
|||
return r;
|
||||
}
|
||||
|
||||
static bool gfx_v8_0_is_idle(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (REG_GET_FIELD(RREG32(mmGRBM_STATUS), GRBM_STATUS, GUI_ACTIVE)
|
||||
|| RREG32(mmGRBM_STATUS2) != 0x8)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gfx_v8_0_rlc_is_idle(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (RREG32(mmGRBM_STATUS2) != 0x8)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static int gfx_v8_0_wait_for_rlc_idle(void *handle)
|
||||
{
|
||||
unsigned int i;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (gfx_v8_0_rlc_is_idle(handle))
|
||||
return 0;
|
||||
|
||||
udelay(1);
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int gfx_v8_0_wait_for_idle(void *handle)
|
||||
{
|
||||
unsigned int i;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (gfx_v8_0_is_idle(handle))
|
||||
return 0;
|
||||
|
||||
udelay(1);
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int gfx_v8_0_hw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
@ -5098,51 +4971,27 @@ static int gfx_v8_0_hw_fini(void *handle)
|
|||
pr_debug("For SRIOV client, shouldn't do anything.\n");
|
||||
return 0;
|
||||
}
|
||||
gfx_v8_0_cp_enable(adev, false);
|
||||
gfx_v8_0_rlc_stop(adev);
|
||||
|
||||
adev->gfx.rlc.funcs->enter_safe_mode(adev);
|
||||
if (!gfx_v8_0_wait_for_idle(adev))
|
||||
gfx_v8_0_cp_enable(adev, false);
|
||||
else
|
||||
pr_err("cp is busy, skip halt cp\n");
|
||||
if (!gfx_v8_0_wait_for_rlc_idle(adev))
|
||||
gfx_v8_0_rlc_stop(adev);
|
||||
else
|
||||
pr_err("rlc is busy, skip halt rlc\n");
|
||||
adev->gfx.rlc.funcs->exit_safe_mode(adev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v8_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
adev->gfx.in_suspend = true;
|
||||
return gfx_v8_0_hw_fini(adev);
|
||||
return gfx_v8_0_hw_fini(handle);
|
||||
}
|
||||
|
||||
static int gfx_v8_0_resume(void *handle)
|
||||
{
|
||||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = gfx_v8_0_hw_init(adev);
|
||||
adev->gfx.in_suspend = false;
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool gfx_v8_0_is_idle(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (REG_GET_FIELD(RREG32(mmGRBM_STATUS), GRBM_STATUS, GUI_ACTIVE))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static int gfx_v8_0_wait_for_idle(void *handle)
|
||||
{
|
||||
unsigned i;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (gfx_v8_0_is_idle(handle))
|
||||
return 0;
|
||||
|
||||
udelay(1);
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
return gfx_v8_0_hw_init(handle);
|
||||
}
|
||||
|
||||
static bool gfx_v8_0_check_soft_reset(void *handle)
|
||||
|
@ -7013,52 +6862,6 @@ static int gfx_v8_0_sq_irq(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v8_0_kiq_set_interrupt_state(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *src,
|
||||
unsigned int type,
|
||||
enum amdgpu_interrupt_state state)
|
||||
{
|
||||
struct amdgpu_ring *ring = &(adev->gfx.kiq.ring);
|
||||
|
||||
switch (type) {
|
||||
case AMDGPU_CP_KIQ_IRQ_DRIVER0:
|
||||
WREG32_FIELD(CPC_INT_CNTL, GENERIC2_INT_ENABLE,
|
||||
state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1);
|
||||
if (ring->me == 1)
|
||||
WREG32_FIELD_OFFSET(CP_ME1_PIPE0_INT_CNTL,
|
||||
ring->pipe,
|
||||
GENERIC2_INT_ENABLE,
|
||||
state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1);
|
||||
else
|
||||
WREG32_FIELD_OFFSET(CP_ME2_PIPE0_INT_CNTL,
|
||||
ring->pipe,
|
||||
GENERIC2_INT_ENABLE,
|
||||
state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1);
|
||||
break;
|
||||
default:
|
||||
BUG(); /* kiq only support GENERIC2_INT now */
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v8_0_kiq_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
u8 me_id, pipe_id, queue_id;
|
||||
struct amdgpu_ring *ring = &(adev->gfx.kiq.ring);
|
||||
|
||||
me_id = (entry->ring_id & 0x0c) >> 2;
|
||||
pipe_id = (entry->ring_id & 0x03) >> 0;
|
||||
queue_id = (entry->ring_id & 0x70) >> 4;
|
||||
DRM_DEBUG("IH: CPC GENERIC2_INT, me:%d, pipe:%d, queue:%d\n",
|
||||
me_id, pipe_id, queue_id);
|
||||
|
||||
amdgpu_fence_process(ring);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs gfx_v8_0_ip_funcs = {
|
||||
.name = "gfx_v8_0",
|
||||
.early_init = gfx_v8_0_early_init,
|
||||
|
@ -7209,11 +7012,6 @@ static const struct amdgpu_irq_src_funcs gfx_v8_0_priv_inst_irq_funcs = {
|
|||
.process = gfx_v8_0_priv_inst_irq,
|
||||
};
|
||||
|
||||
static const struct amdgpu_irq_src_funcs gfx_v8_0_kiq_irq_funcs = {
|
||||
.set = gfx_v8_0_kiq_set_interrupt_state,
|
||||
.process = gfx_v8_0_kiq_irq,
|
||||
};
|
||||
|
||||
static const struct amdgpu_irq_src_funcs gfx_v8_0_cp_ecc_error_irq_funcs = {
|
||||
.set = gfx_v8_0_set_cp_ecc_int_state,
|
||||
.process = gfx_v8_0_cp_ecc_error_irq,
|
||||
|
@ -7235,9 +7033,6 @@ static void gfx_v8_0_set_irq_funcs(struct amdgpu_device *adev)
|
|||
adev->gfx.priv_inst_irq.num_types = 1;
|
||||
adev->gfx.priv_inst_irq.funcs = &gfx_v8_0_priv_inst_irq_funcs;
|
||||
|
||||
adev->gfx.kiq.irq.num_types = AMDGPU_CP_KIQ_IRQ_LAST;
|
||||
adev->gfx.kiq.irq.funcs = &gfx_v8_0_kiq_irq_funcs;
|
||||
|
||||
adev->gfx.cp_ecc_error_irq.num_types = 1;
|
||||
adev->gfx.cp_ecc_error_irq.funcs = &gfx_v8_0_cp_ecc_error_irq_funcs;
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ MODULE_FIRMWARE("amdgpu/raven2_rlc.bin");
|
|||
static const struct soc15_reg_golden golden_settings_gc_9_0[] =
|
||||
{
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG2, 0xf00fffff, 0x00000400),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG3, 0x80000000, 0x80000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_GPU_ID, 0x0000000f, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_EVENT_CNTL_3, 0x00000003, 0x82400024),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE, 0x3fffffff, 0x00000001),
|
||||
|
@ -133,7 +134,10 @@ static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] =
|
|||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_UTCL1_CNTL2, 0x00030000, 0x00020000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0x0000000f, 0x01000107),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x00001800, 0x00000800),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmWD_UTCL1_CNTL, 0x08000000, 0x08000080)
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmWD_UTCL1_CNTL, 0x08000000, 0x08000080),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC1_F32_INT_DIS, 0x00000000, 0x00000800),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC2_F32_INT_DIS, 0x00000000, 0x00000800),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_DEBUG, 0x00000000, 0x00008000)
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_9_0_vg20[] =
|
||||
|
@ -173,7 +177,10 @@ static const struct soc15_reg_golden golden_settings_gc_9_1[] =
|
|||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_LO, 0xffffffff, 0x00003120),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_CACHE_INVALIDATION, 0x3fff3af3, 0x19200000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000000ff),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmWD_UTCL1_CNTL, 0x08000000, 0x08000080)
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmWD_UTCL1_CNTL, 0x08000000, 0x08000080),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC1_F32_INT_DIS, 0x00000000, 0x00000800),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC2_F32_INT_DIS, 0x00000000, 0x00000800),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_DEBUG, 0x00000000, 0x00008000)
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_9_1_rv1[] =
|
||||
|
@ -247,7 +254,10 @@ static const struct soc15_reg_golden golden_settings_gc_9_2_1_vg12[] =
|
|||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0xffff03ff, 0x01000107),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI, 0xffffffff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_LO, 0xffffffff, 0x76325410),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x01bd9f33, 0x01000000)
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x01bd9f33, 0x01000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC1_F32_INT_DIS, 0x00000000, 0x00000800),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_MEC2_F32_INT_DIS, 0x00000000, 0x00000800),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_DEBUG, 0x00000000, 0x00008000)
|
||||
};
|
||||
|
||||
static const u32 GFX_RLC_SRM_INDEX_CNTL_ADDR_OFFSETS[] =
|
||||
|
@ -908,6 +918,50 @@ static void gfx_v9_0_get_csb_buffer(struct amdgpu_device *adev,
|
|||
buffer[count++] = cpu_to_le32(0);
|
||||
}
|
||||
|
||||
static void gfx_v9_0_init_always_on_cu_mask(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_cu_info *cu_info = &adev->gfx.cu_info;
|
||||
uint32_t pg_always_on_cu_num = 2;
|
||||
uint32_t always_on_cu_num;
|
||||
uint32_t i, j, k;
|
||||
uint32_t mask, cu_bitmap, counter;
|
||||
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
always_on_cu_num = 4;
|
||||
else if (adev->asic_type == CHIP_VEGA12)
|
||||
always_on_cu_num = 8;
|
||||
else
|
||||
always_on_cu_num = 12;
|
||||
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
|
||||
for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
|
||||
mask = 1;
|
||||
cu_bitmap = 0;
|
||||
counter = 0;
|
||||
gfx_v9_0_select_se_sh(adev, i, j, 0xffffffff);
|
||||
|
||||
for (k = 0; k < adev->gfx.config.max_cu_per_sh; k ++) {
|
||||
if (cu_info->bitmap[i][j] & mask) {
|
||||
if (counter == pg_always_on_cu_num)
|
||||
WREG32_SOC15(GC, 0, mmRLC_PG_ALWAYS_ON_CU_MASK, cu_bitmap);
|
||||
if (counter < always_on_cu_num)
|
||||
cu_bitmap |= mask;
|
||||
else
|
||||
break;
|
||||
counter++;
|
||||
}
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_ALWAYS_ACTIVE_CU_MASK, cu_bitmap);
|
||||
cu_info->ao_cu_bitmap[i][j] = cu_bitmap;
|
||||
}
|
||||
}
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
}
|
||||
|
||||
static void gfx_v9_0_init_lbpw(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t data;
|
||||
|
@ -941,8 +995,10 @@ static void gfx_v9_0_init_lbpw(struct amdgpu_device *adev)
|
|||
data |= 0x00C00000;
|
||||
WREG32_SOC15(GC, 0, mmRLC_GPM_GENERAL_7, data);
|
||||
|
||||
/* set RLC_LB_ALWAYS_ACTIVE_CU_MASK = 0xFFF */
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_ALWAYS_ACTIVE_CU_MASK, 0xFFF);
|
||||
/*
|
||||
* RLC_LB_ALWAYS_ACTIVE_CU_MASK = 0xF (4 CUs AON for Raven),
|
||||
* programmed in gfx_v9_0_init_always_on_cu_mask()
|
||||
*/
|
||||
|
||||
/* set RLC_LB_CNTL = 0x8000_0095, 31 bit is reserved,
|
||||
* but used for RLC_LB_CNTL configuration */
|
||||
|
@ -951,6 +1007,57 @@ static void gfx_v9_0_init_lbpw(struct amdgpu_device *adev)
|
|||
data |= REG_SET_FIELD(data, RLC_LB_CNTL, RESERVED, 0x80000);
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_CNTL, data);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
gfx_v9_0_init_always_on_cu_mask(adev);
|
||||
}
|
||||
|
||||
static void gfx_v9_4_init_lbpw(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t data;
|
||||
|
||||
/* set mmRLC_LB_THR_CONFIG_1/2/3/4 */
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_THR_CONFIG_1, 0x0000007F);
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_THR_CONFIG_2, 0x033388F8);
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_THR_CONFIG_3, 0x00000077);
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_THR_CONFIG_4, (0x10 | 0x27 << 8 | 0x02FA << 16));
|
||||
|
||||
/* set mmRLC_LB_CNTR_INIT = 0x0000_0000 */
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_CNTR_INIT, 0x00000000);
|
||||
|
||||
/* set mmRLC_LB_CNTR_MAX = 0x0000_0500 */
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_CNTR_MAX, 0x00000800);
|
||||
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
/* set mmRLC_LB_INIT_CU_MASK thru broadcast mode to enable all SE/SH*/
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_INIT_CU_MASK, 0xffffffff);
|
||||
|
||||
/* set mmRLC_LB_PARAMS = 0x003F_1006 */
|
||||
data = REG_SET_FIELD(0, RLC_LB_PARAMS, FIFO_SAMPLES, 0x0003);
|
||||
data |= REG_SET_FIELD(data, RLC_LB_PARAMS, PG_IDLE_SAMPLES, 0x0010);
|
||||
data |= REG_SET_FIELD(data, RLC_LB_PARAMS, PG_IDLE_SAMPLE_INTERVAL, 0x033F);
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_PARAMS, data);
|
||||
|
||||
/* set mmRLC_GPM_GENERAL_7[31-16] = 0x00C0 */
|
||||
data = RREG32_SOC15(GC, 0, mmRLC_GPM_GENERAL_7);
|
||||
data &= 0x0000FFFF;
|
||||
data |= 0x00C00000;
|
||||
WREG32_SOC15(GC, 0, mmRLC_GPM_GENERAL_7, data);
|
||||
|
||||
/*
|
||||
* RLC_LB_ALWAYS_ACTIVE_CU_MASK = 0xFFF (12 CUs AON),
|
||||
* programmed in gfx_v9_0_init_always_on_cu_mask()
|
||||
*/
|
||||
|
||||
/* set RLC_LB_CNTL = 0x8000_0095, 31 bit is reserved,
|
||||
* but used for RLC_LB_CNTL configuration */
|
||||
data = RLC_LB_CNTL__LB_CNT_SPIM_ACTIVE_MASK;
|
||||
data |= REG_SET_FIELD(data, RLC_LB_CNTL, CU_MASK_USED_OFF_HYST, 0x09);
|
||||
data |= REG_SET_FIELD(data, RLC_LB_CNTL, RESERVED, 0x80000);
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_CNTL, data);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
gfx_v9_0_init_always_on_cu_mask(adev);
|
||||
}
|
||||
|
||||
static void gfx_v9_0_enable_lbpw(struct amdgpu_device *adev, bool enable)
|
||||
|
@ -1084,8 +1191,17 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
|
|||
rv_init_cp_jump_table(adev);
|
||||
amdgpu_bo_kunmap(adev->gfx.rlc.cp_table_obj);
|
||||
amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
|
||||
}
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
gfx_v9_0_init_lbpw(adev);
|
||||
break;
|
||||
case CHIP_VEGA20:
|
||||
gfx_v9_4_init_lbpw(adev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1605,11 +1721,6 @@ static int gfx_v9_0_sw_init(void *handle)
|
|||
adev->gfx.mec.num_pipe_per_mec = 4;
|
||||
adev->gfx.mec.num_queue_per_pipe = 8;
|
||||
|
||||
/* KIQ event */
|
||||
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP, GFX_9_0__SRCID__CP_IB2_INTERRUPT_PKT, &adev->gfx.kiq.irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* EOP Event */
|
||||
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP, GFX_9_0__SRCID__CP_EOP_INTERRUPT, &adev->gfx.eop_irq);
|
||||
if (r)
|
||||
|
@ -1847,7 +1958,7 @@ static void gfx_v9_0_init_compute_vmid(struct amdgpu_device *adev)
|
|||
mutex_unlock(&adev->srbm_mutex);
|
||||
}
|
||||
|
||||
static void gfx_v9_0_gpu_init(struct amdgpu_device *adev)
|
||||
static void gfx_v9_0_constants_init(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 tmp;
|
||||
int i;
|
||||
|
@ -2403,7 +2514,8 @@ static int gfx_v9_0_rlc_resume(struct amdgpu_device *adev)
|
|||
return r;
|
||||
}
|
||||
|
||||
if (adev->asic_type == CHIP_RAVEN) {
|
||||
if (adev->asic_type == CHIP_RAVEN ||
|
||||
adev->asic_type == CHIP_VEGA20) {
|
||||
if (amdgpu_lbpw != 0)
|
||||
gfx_v9_0_enable_lbpw(adev, true);
|
||||
else
|
||||
|
@ -3091,7 +3203,7 @@ static int gfx_v9_0_kcq_init_queue(struct amdgpu_ring *ring)
|
|||
struct v9_mqd *mqd = ring->mqd_ptr;
|
||||
int mqd_idx = ring - &adev->gfx.compute_ring[0];
|
||||
|
||||
if (!adev->in_gpu_reset && !adev->gfx.in_suspend) {
|
||||
if (!adev->in_gpu_reset && !adev->in_suspend) {
|
||||
memset((void *)mqd, 0, sizeof(struct v9_mqd_allocation));
|
||||
((struct v9_mqd_allocation *)mqd)->dynamic_cu_mask = 0xFFFFFFFF;
|
||||
((struct v9_mqd_allocation *)mqd)->dynamic_rb_mask = 0xFFFFFFFF;
|
||||
|
@ -3235,7 +3347,7 @@ static int gfx_v9_0_hw_init(void *handle)
|
|||
|
||||
gfx_v9_0_init_golden_registers(adev);
|
||||
|
||||
gfx_v9_0_gpu_init(adev);
|
||||
gfx_v9_0_constants_init(adev);
|
||||
|
||||
r = gfx_v9_0_csb_vram_pin(adev);
|
||||
if (r)
|
||||
|
@ -3310,7 +3422,7 @@ static int gfx_v9_0_hw_fini(void *handle)
|
|||
/* Use deinitialize sequence from CAIL when unbinding device from driver,
|
||||
* otherwise KIQ is hanging when binding back
|
||||
*/
|
||||
if (!adev->in_gpu_reset && !adev->gfx.in_suspend) {
|
||||
if (!adev->in_gpu_reset && !adev->in_suspend) {
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc15_grbm_select(adev, adev->gfx.kiq.ring.me,
|
||||
adev->gfx.kiq.ring.pipe,
|
||||
|
@ -3330,20 +3442,12 @@ static int gfx_v9_0_hw_fini(void *handle)
|
|||
|
||||
static int gfx_v9_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->gfx.in_suspend = true;
|
||||
return gfx_v9_0_hw_fini(adev);
|
||||
return gfx_v9_0_hw_fini(handle);
|
||||
}
|
||||
|
||||
static int gfx_v9_0_resume(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = gfx_v9_0_hw_init(adev);
|
||||
adev->gfx.in_suspend = false;
|
||||
return r;
|
||||
return gfx_v9_0_hw_init(handle);
|
||||
}
|
||||
|
||||
static bool gfx_v9_0_is_idle(void *handle)
|
||||
|
@ -4609,68 +4713,6 @@ static int gfx_v9_0_priv_inst_irq(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v9_0_kiq_set_interrupt_state(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *src,
|
||||
unsigned int type,
|
||||
enum amdgpu_interrupt_state state)
|
||||
{
|
||||
uint32_t tmp, target;
|
||||
struct amdgpu_ring *ring = &(adev->gfx.kiq.ring);
|
||||
|
||||
if (ring->me == 1)
|
||||
target = SOC15_REG_OFFSET(GC, 0, mmCP_ME1_PIPE0_INT_CNTL);
|
||||
else
|
||||
target = SOC15_REG_OFFSET(GC, 0, mmCP_ME2_PIPE0_INT_CNTL);
|
||||
target += ring->pipe;
|
||||
|
||||
switch (type) {
|
||||
case AMDGPU_CP_KIQ_IRQ_DRIVER0:
|
||||
if (state == AMDGPU_IRQ_STATE_DISABLE) {
|
||||
tmp = RREG32_SOC15(GC, 0, mmCPC_INT_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CPC_INT_CNTL,
|
||||
GENERIC2_INT_ENABLE, 0);
|
||||
WREG32_SOC15(GC, 0, mmCPC_INT_CNTL, tmp);
|
||||
|
||||
tmp = RREG32(target);
|
||||
tmp = REG_SET_FIELD(tmp, CP_ME2_PIPE0_INT_CNTL,
|
||||
GENERIC2_INT_ENABLE, 0);
|
||||
WREG32(target, tmp);
|
||||
} else {
|
||||
tmp = RREG32_SOC15(GC, 0, mmCPC_INT_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CPC_INT_CNTL,
|
||||
GENERIC2_INT_ENABLE, 1);
|
||||
WREG32_SOC15(GC, 0, mmCPC_INT_CNTL, tmp);
|
||||
|
||||
tmp = RREG32(target);
|
||||
tmp = REG_SET_FIELD(tmp, CP_ME2_PIPE0_INT_CNTL,
|
||||
GENERIC2_INT_ENABLE, 1);
|
||||
WREG32(target, tmp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BUG(); /* kiq only support GENERIC2_INT now */
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v9_0_kiq_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
u8 me_id, pipe_id, queue_id;
|
||||
struct amdgpu_ring *ring = &(adev->gfx.kiq.ring);
|
||||
|
||||
me_id = (entry->ring_id & 0x0c) >> 2;
|
||||
pipe_id = (entry->ring_id & 0x03) >> 0;
|
||||
queue_id = (entry->ring_id & 0x70) >> 4;
|
||||
DRM_DEBUG("IH: CPC GENERIC2_INT, me:%d, pipe:%d, queue:%d\n",
|
||||
me_id, pipe_id, queue_id);
|
||||
|
||||
amdgpu_fence_process(ring);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs gfx_v9_0_ip_funcs = {
|
||||
.name = "gfx_v9_0",
|
||||
.early_init = gfx_v9_0_early_init,
|
||||
|
@ -4819,11 +4861,6 @@ static void gfx_v9_0_set_ring_funcs(struct amdgpu_device *adev)
|
|||
adev->gfx.compute_ring[i].funcs = &gfx_v9_0_ring_funcs_compute;
|
||||
}
|
||||
|
||||
static const struct amdgpu_irq_src_funcs gfx_v9_0_kiq_irq_funcs = {
|
||||
.set = gfx_v9_0_kiq_set_interrupt_state,
|
||||
.process = gfx_v9_0_kiq_irq,
|
||||
};
|
||||
|
||||
static const struct amdgpu_irq_src_funcs gfx_v9_0_eop_irq_funcs = {
|
||||
.set = gfx_v9_0_set_eop_interrupt_state,
|
||||
.process = gfx_v9_0_eop_irq,
|
||||
|
@ -4849,9 +4886,6 @@ static void gfx_v9_0_set_irq_funcs(struct amdgpu_device *adev)
|
|||
|
||||
adev->gfx.priv_inst_irq.num_types = 1;
|
||||
adev->gfx.priv_inst_irq.funcs = &gfx_v9_0_priv_inst_irq_funcs;
|
||||
|
||||
adev->gfx.kiq.irq.num_types = AMDGPU_CP_KIQ_IRQ_LAST;
|
||||
adev->gfx.kiq.irq.funcs = &gfx_v9_0_kiq_irq_funcs;
|
||||
}
|
||||
|
||||
static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev)
|
||||
|
@ -4871,7 +4905,20 @@ static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev)
|
|||
static void gfx_v9_0_set_gds_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* init asci gds info */
|
||||
adev->gds.mem.total_size = RREG32_SOC15(GC, 0, mmGDS_VMID0_SIZE);
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
adev->gds.mem.total_size = 0x10000;
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
adev->gds.mem.total_size = 0x1000;
|
||||
break;
|
||||
default:
|
||||
adev->gds.mem.total_size = 0x10000;
|
||||
break;
|
||||
}
|
||||
|
||||
adev->gds.gws.total_size = 64;
|
||||
adev->gds.oa.total_size = 16;
|
||||
|
||||
|
|
|
@ -82,7 +82,8 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
* to get rid of the VM fault and hardware hang.
|
||||
*/
|
||||
WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
(max(adev->gmc.vram_end, adev->gmc.agp_end) >> 18) + 0x1);
|
||||
max((adev->gmc.vram_end >> 18) + 0x1,
|
||||
adev->gmc.agp_end >> 18));
|
||||
else
|
||||
WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
max(adev->gmc.vram_end, adev->gmc.agp_end) >> 18);
|
||||
|
|
|
@ -859,11 +859,11 @@ static int gmc_v6_0_sw_init(void *handle)
|
|||
adev->gmc.vram_type = gmc_v6_0_convert_vram_type(tmp);
|
||||
}
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 146, &adev->gmc.vm_fault);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 146, &adev->gmc.vm_fault);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 147, &adev->gmc.vm_fault);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 147, &adev->gmc.vm_fault);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -1180,8 +1180,7 @@ static const struct amdgpu_irq_src_funcs gmc_v6_0_irq_funcs = {
|
|||
|
||||
static void gmc_v6_0_set_gmc_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->gmc.gmc_funcs == NULL)
|
||||
adev->gmc.gmc_funcs = &gmc_v6_0_gmc_funcs;
|
||||
adev->gmc.gmc_funcs = &gmc_v6_0_gmc_funcs;
|
||||
}
|
||||
|
||||
static void gmc_v6_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
|
|
|
@ -991,11 +991,11 @@ static int gmc_v7_0_sw_init(void *handle)
|
|||
adev->gmc.vram_type = gmc_v7_0_convert_vram_type(tmp);
|
||||
}
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_PAGE_INV_FAULT, &adev->gmc.vm_fault);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_PAGE_INV_FAULT, &adev->gmc.vm_fault);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_MEM_PROT_FAULT, &adev->gmc.vm_fault);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_MEM_PROT_FAULT, &adev->gmc.vm_fault);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -1388,8 +1388,7 @@ static const struct amdgpu_irq_src_funcs gmc_v7_0_irq_funcs = {
|
|||
|
||||
static void gmc_v7_0_set_gmc_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->gmc.gmc_funcs == NULL)
|
||||
adev->gmc.gmc_funcs = &gmc_v7_0_gmc_funcs;
|
||||
adev->gmc.gmc_funcs = &gmc_v7_0_gmc_funcs;
|
||||
}
|
||||
|
||||
static void gmc_v7_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
|
|
|
@ -1095,11 +1095,11 @@ static int gmc_v8_0_sw_init(void *handle)
|
|||
adev->gmc.vram_type = gmc_v8_0_convert_vram_type(tmp);
|
||||
}
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_PAGE_INV_FAULT, &adev->gmc.vm_fault);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_PAGE_INV_FAULT, &adev->gmc.vm_fault);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_MEM_PROT_FAULT, &adev->gmc.vm_fault);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_MEM_PROT_FAULT, &adev->gmc.vm_fault);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -1733,8 +1733,7 @@ static const struct amdgpu_irq_src_funcs gmc_v8_0_irq_funcs = {
|
|||
|
||||
static void gmc_v8_0_set_gmc_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->gmc.gmc_funcs == NULL)
|
||||
adev->gmc.gmc_funcs = &gmc_v8_0_gmc_funcs;
|
||||
adev->gmc.gmc_funcs = &gmc_v8_0_gmc_funcs;
|
||||
}
|
||||
|
||||
static void gmc_v8_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
|
|
|
@ -593,8 +593,7 @@ static const struct amdgpu_gmc_funcs gmc_v9_0_gmc_funcs = {
|
|||
|
||||
static void gmc_v9_0_set_gmc_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->gmc.gmc_funcs == NULL)
|
||||
adev->gmc.gmc_funcs = &gmc_v9_0_gmc_funcs;
|
||||
adev->gmc.gmc_funcs = &gmc_v9_0_gmc_funcs;
|
||||
}
|
||||
|
||||
static int gmc_v9_0_early_init(void *handle)
|
||||
|
|
|
@ -255,7 +255,7 @@ static void iceland_ih_decode_iv(struct amdgpu_device *adev,
|
|||
dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
|
||||
dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
|
||||
|
||||
entry->client_id = AMDGPU_IH_CLIENTID_LEGACY;
|
||||
entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
|
||||
entry->src_id = dw[0] & 0xff;
|
||||
entry->src_data[0] = dw[1] & 0xfffffff;
|
||||
entry->ring_id = dw[2] & 0xff;
|
||||
|
@ -297,7 +297,7 @@ static int iceland_ih_sw_init(void *handle)
|
|||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = amdgpu_ih_ring_init(adev, 64 * 1024, false);
|
||||
r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 64 * 1024, false);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -311,7 +311,7 @@ static int iceland_ih_sw_fini(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
amdgpu_irq_fini(adev);
|
||||
amdgpu_ih_ring_fini(adev);
|
||||
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
|
||||
amdgpu_irq_remove_domain(adev);
|
||||
|
||||
return 0;
|
||||
|
@ -447,8 +447,7 @@ static const struct amdgpu_ih_funcs iceland_ih_funcs = {
|
|||
|
||||
static void iceland_ih_set_interrupt_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->irq.ih_funcs == NULL)
|
||||
adev->irq.ih_funcs = &iceland_ih_funcs;
|
||||
adev->irq.ih_funcs = &iceland_ih_funcs;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version iceland_ih_ip_block =
|
||||
|
|
|
@ -2995,12 +2995,12 @@ static int kv_dpm_sw_init(void *handle)
|
|||
int ret;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
ret = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 230,
|
||||
ret = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 230,
|
||||
&adev->pm.dpm.thermal.irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 231,
|
||||
ret = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 231,
|
||||
&adev->pm.dpm.thermal.irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -100,7 +100,8 @@ static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
* to get rid of the VM fault and hardware hang.
|
||||
*/
|
||||
WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
(max(adev->gmc.vram_end, adev->gmc.agp_end) >> 18) + 0x1);
|
||||
max((adev->gmc.vram_end >> 18) + 0x1,
|
||||
adev->gmc.agp_end >> 18));
|
||||
else
|
||||
WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
max(adev->gmc.vram_end, adev->gmc.agp_end) >> 18);
|
||||
|
|
|
@ -580,11 +580,11 @@ int xgpu_vi_mailbox_add_irq_id(struct amdgpu_device *adev)
|
|||
{
|
||||
int r;
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 135, &adev->virt.rcv_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 135, &adev->virt.rcv_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 138, &adev->virt.ack_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 138, &adev->virt.ack_irq);
|
||||
if (r) {
|
||||
amdgpu_irq_put(adev, &adev->virt.rcv_irq, 0);
|
||||
return r;
|
||||
|
|
|
@ -306,11 +306,8 @@ static int psp_v11_0_ring_stop(struct psp_context *psp,
|
|||
enum psp_ring_type ring_type)
|
||||
{
|
||||
int ret = 0;
|
||||
struct psp_ring *ring;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
ring = &psp->km_ring;
|
||||
|
||||
/* Write the ring destroy command to C2PMSG_64 */
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, GFX_CTRL_CMD_ID_DESTROY_RINGS);
|
||||
|
||||
|
|
|
@ -504,41 +504,6 @@ static int sdma_v2_4_rlc_resume(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdma_v2_4_load_microcode - load the sDMA ME ucode
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Loads the sDMA0/1 ucode.
|
||||
* Returns 0 for success, -EINVAL if the ucode is not available.
|
||||
*/
|
||||
static int sdma_v2_4_load_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct sdma_firmware_header_v1_0 *hdr;
|
||||
const __le32 *fw_data;
|
||||
u32 fw_size;
|
||||
int i, j;
|
||||
|
||||
/* halt the MEs */
|
||||
sdma_v2_4_enable(adev, false);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
if (!adev->sdma.instance[i].fw)
|
||||
return -EINVAL;
|
||||
hdr = (const struct sdma_firmware_header_v1_0 *)adev->sdma.instance[i].fw->data;
|
||||
amdgpu_ucode_print_sdma_hdr(&hdr->header);
|
||||
fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
|
||||
fw_data = (const __le32 *)
|
||||
(adev->sdma.instance[i].fw->data +
|
||||
le32_to_cpu(hdr->header.ucode_array_offset_bytes));
|
||||
WREG32(mmSDMA0_UCODE_ADDR + sdma_offsets[i], 0);
|
||||
for (j = 0; j < fw_size; j++)
|
||||
WREG32(mmSDMA0_UCODE_DATA + sdma_offsets[i], le32_to_cpup(fw_data++));
|
||||
WREG32(mmSDMA0_UCODE_ADDR + sdma_offsets[i], adev->sdma.instance[i].fw_version);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdma_v2_4_start - setup and start the async dma engines
|
||||
|
@ -552,13 +517,6 @@ static int sdma_v2_4_start(struct amdgpu_device *adev)
|
|||
{
|
||||
int r;
|
||||
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
|
||||
r = sdma_v2_4_load_microcode(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* halt the engine before programing */
|
||||
sdma_v2_4_enable(adev, false);
|
||||
|
||||
|
@ -898,19 +856,19 @@ static int sdma_v2_4_sw_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
/* SDMA trap event */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SDMA_TRAP,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SDMA_TRAP,
|
||||
&adev->sdma.trap_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* SDMA Privileged inst */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 241,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 241,
|
||||
&adev->sdma.illegal_inst_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* SDMA Privileged inst */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SDMA_SRBM_WRITE,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SDMA_SRBM_WRITE,
|
||||
&adev->sdma.illegal_inst_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -1296,10 +1254,8 @@ static const struct amdgpu_buffer_funcs sdma_v2_4_buffer_funcs = {
|
|||
|
||||
static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->mman.buffer_funcs == NULL) {
|
||||
adev->mman.buffer_funcs = &sdma_v2_4_buffer_funcs;
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
|
||||
}
|
||||
adev->mman.buffer_funcs = &sdma_v2_4_buffer_funcs;
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
|
||||
}
|
||||
|
||||
static const struct amdgpu_vm_pte_funcs sdma_v2_4_vm_pte_funcs = {
|
||||
|
@ -1315,15 +1271,13 @@ static void sdma_v2_4_set_vm_pte_funcs(struct amdgpu_device *adev)
|
|||
struct drm_gpu_scheduler *sched;
|
||||
unsigned i;
|
||||
|
||||
if (adev->vm_manager.vm_pte_funcs == NULL) {
|
||||
adev->vm_manager.vm_pte_funcs = &sdma_v2_4_vm_pte_funcs;
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
sched = &adev->sdma.instance[i].ring.sched;
|
||||
adev->vm_manager.vm_pte_rqs[i] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances;
|
||||
adev->vm_manager.vm_pte_funcs = &sdma_v2_4_vm_pte_funcs;
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
sched = &adev->sdma.instance[i].ring.sched;
|
||||
adev->vm_manager.vm_pte_rqs[i] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version sdma_v2_4_ip_block =
|
||||
|
|
|
@ -318,14 +318,13 @@ static int sdma_v3_0_init_microcode(struct amdgpu_device *adev)
|
|||
if (adev->sdma.instance[i].feature_version >= 20)
|
||||
adev->sdma.instance[i].burst_nop = true;
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SDMA0 + i;
|
||||
info->fw = adev->sdma.instance[i].fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SDMA0 + i;
|
||||
info->fw = adev->sdma.instance[i].fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
}
|
||||
out:
|
||||
if (err) {
|
||||
|
@ -777,42 +776,6 @@ static int sdma_v3_0_rlc_resume(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdma_v3_0_load_microcode - load the sDMA ME ucode
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Loads the sDMA0/1 ucode.
|
||||
* Returns 0 for success, -EINVAL if the ucode is not available.
|
||||
*/
|
||||
static int sdma_v3_0_load_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct sdma_firmware_header_v1_0 *hdr;
|
||||
const __le32 *fw_data;
|
||||
u32 fw_size;
|
||||
int i, j;
|
||||
|
||||
/* halt the MEs */
|
||||
sdma_v3_0_enable(adev, false);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
if (!adev->sdma.instance[i].fw)
|
||||
return -EINVAL;
|
||||
hdr = (const struct sdma_firmware_header_v1_0 *)adev->sdma.instance[i].fw->data;
|
||||
amdgpu_ucode_print_sdma_hdr(&hdr->header);
|
||||
fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
|
||||
fw_data = (const __le32 *)
|
||||
(adev->sdma.instance[i].fw->data +
|
||||
le32_to_cpu(hdr->header.ucode_array_offset_bytes));
|
||||
WREG32(mmSDMA0_UCODE_ADDR + sdma_offsets[i], 0);
|
||||
for (j = 0; j < fw_size; j++)
|
||||
WREG32(mmSDMA0_UCODE_DATA + sdma_offsets[i], le32_to_cpup(fw_data++));
|
||||
WREG32(mmSDMA0_UCODE_ADDR + sdma_offsets[i], adev->sdma.instance[i].fw_version);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdma_v3_0_start - setup and start the async dma engines
|
||||
*
|
||||
|
@ -825,12 +788,6 @@ static int sdma_v3_0_start(struct amdgpu_device *adev)
|
|||
{
|
||||
int r;
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
|
||||
r = sdma_v3_0_load_microcode(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* disable sdma engine before programing it */
|
||||
sdma_v3_0_ctx_switch_enable(adev, false);
|
||||
sdma_v3_0_enable(adev, false);
|
||||
|
@ -1177,19 +1134,19 @@ static int sdma_v3_0_sw_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
/* SDMA trap event */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SDMA_TRAP,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SDMA_TRAP,
|
||||
&adev->sdma.trap_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* SDMA Privileged inst */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 241,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 241,
|
||||
&adev->sdma.illegal_inst_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* SDMA Privileged inst */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SDMA_SRBM_WRITE,
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SDMA_SRBM_WRITE,
|
||||
&adev->sdma.illegal_inst_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -1736,10 +1693,8 @@ static const struct amdgpu_buffer_funcs sdma_v3_0_buffer_funcs = {
|
|||
|
||||
static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->mman.buffer_funcs == NULL) {
|
||||
adev->mman.buffer_funcs = &sdma_v3_0_buffer_funcs;
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
|
||||
}
|
||||
adev->mman.buffer_funcs = &sdma_v3_0_buffer_funcs;
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
|
||||
}
|
||||
|
||||
static const struct amdgpu_vm_pte_funcs sdma_v3_0_vm_pte_funcs = {
|
||||
|
@ -1755,15 +1710,13 @@ static void sdma_v3_0_set_vm_pte_funcs(struct amdgpu_device *adev)
|
|||
struct drm_gpu_scheduler *sched;
|
||||
unsigned i;
|
||||
|
||||
if (adev->vm_manager.vm_pte_funcs == NULL) {
|
||||
adev->vm_manager.vm_pte_funcs = &sdma_v3_0_vm_pte_funcs;
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
sched = &adev->sdma.instance[i].ring.sched;
|
||||
adev->vm_manager.vm_pte_rqs[i] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances;
|
||||
adev->vm_manager.vm_pte_funcs = &sdma_v3_0_vm_pte_funcs;
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
sched = &adev->sdma.instance[i].ring.sched;
|
||||
adev->vm_manager.vm_pte_rqs[i] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version sdma_v3_0_ip_block =
|
||||
|
|
|
@ -148,6 +148,7 @@ static const struct soc15_reg_golden golden_settings_sdma0_4_2[] =
|
|||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC7_RB_RPTR_ADDR_LO, 0xfffffffd, 0x00000001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xFE000000, 0x00000000),
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma1_4_2[] = {
|
||||
|
@ -177,6 +178,7 @@ static const struct soc15_reg_golden golden_settings_sdma1_4_2[] = {
|
|||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC7_RB_RPTR_ADDR_LO, 0xfffffffd, 0x00000001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_WATERMK, 0xFE000000, 0x00000000),
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_rv1[] =
|
||||
|
@ -818,7 +820,7 @@ sdma_v4_1_update_power_gating(struct amdgpu_device *adev, bool enable)
|
|||
uint32_t def, data;
|
||||
|
||||
if (enable && (adev->pg_flags & AMD_PG_SUPPORT_SDMA)) {
|
||||
/* disable idle interrupt */
|
||||
/* enable idle interrupt */
|
||||
def = data = RREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CNTL));
|
||||
data |= SDMA0_CNTL__CTXEMPTY_INT_ENABLE_MASK;
|
||||
|
||||
|
@ -1320,9 +1322,15 @@ static int sdma_v4_0_sw_init(void *handle)
|
|||
DRM_INFO("use_doorbell being set to: [%s]\n",
|
||||
ring->use_doorbell?"true":"false");
|
||||
|
||||
ring->doorbell_index = (i == 0) ?
|
||||
(AMDGPU_DOORBELL64_sDMA_ENGINE0 << 1) //get DWORD offset
|
||||
: (AMDGPU_DOORBELL64_sDMA_ENGINE1 << 1); // get DWORD offset
|
||||
if (adev->asic_type == CHIP_VEGA10)
|
||||
ring->doorbell_index = (i == 0) ?
|
||||
(AMDGPU_VEGA10_DOORBELL64_sDMA_ENGINE0 << 1) //get DWORD offset
|
||||
: (AMDGPU_VEGA10_DOORBELL64_sDMA_ENGINE1 << 1); // get DWORD offset
|
||||
else
|
||||
ring->doorbell_index = (i == 0) ?
|
||||
(AMDGPU_DOORBELL64_sDMA_ENGINE0 << 1) //get DWORD offset
|
||||
: (AMDGPU_DOORBELL64_sDMA_ENGINE1 << 1); // get DWORD offset
|
||||
|
||||
|
||||
sprintf(ring->name, "sdma%d", i);
|
||||
r = amdgpu_ring_init(adev, ring, 1024,
|
||||
|
@ -1358,6 +1366,9 @@ static int sdma_v4_0_hw_init(void *handle)
|
|||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs->set_powergating_by_smu)
|
||||
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false);
|
||||
|
||||
sdma_v4_0_init_golden_registers(adev);
|
||||
|
||||
r = sdma_v4_0_start(adev);
|
||||
|
@ -1375,6 +1386,9 @@ static int sdma_v4_0_hw_fini(void *handle)
|
|||
sdma_v4_0_ctx_switch_enable(adev, false);
|
||||
sdma_v4_0_enable(adev, false);
|
||||
|
||||
if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs->set_powergating_by_smu)
|
||||
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1801,10 +1815,8 @@ static const struct amdgpu_buffer_funcs sdma_v4_0_buffer_funcs = {
|
|||
|
||||
static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->mman.buffer_funcs == NULL) {
|
||||
adev->mman.buffer_funcs = &sdma_v4_0_buffer_funcs;
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
|
||||
}
|
||||
adev->mman.buffer_funcs = &sdma_v4_0_buffer_funcs;
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
|
||||
}
|
||||
|
||||
static const struct amdgpu_vm_pte_funcs sdma_v4_0_vm_pte_funcs = {
|
||||
|
@ -1820,15 +1832,13 @@ static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev)
|
|||
struct drm_gpu_scheduler *sched;
|
||||
unsigned i;
|
||||
|
||||
if (adev->vm_manager.vm_pte_funcs == NULL) {
|
||||
adev->vm_manager.vm_pte_funcs = &sdma_v4_0_vm_pte_funcs;
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
sched = &adev->sdma.instance[i].ring.sched;
|
||||
adev->vm_manager.vm_pte_rqs[i] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances;
|
||||
adev->vm_manager.vm_pte_funcs = &sdma_v4_0_vm_pte_funcs;
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
sched = &adev->sdma.instance[i].ring.sched;
|
||||
adev->vm_manager.vm_pte_rqs[i] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version sdma_v4_0_ip_block = {
|
||||
|
|
|
@ -2057,13 +2057,13 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &si_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v6_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v6_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &dce_v6_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v6_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
|
||||
/* amdgpu_device_ip_block_add(adev, &uvd_v3_1_ip_block); */
|
||||
/* amdgpu_device_ip_block_add(adev, &vce_v1_0_ip_block); */
|
||||
break;
|
||||
|
@ -2071,13 +2071,14 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &si_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v6_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v6_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &dce_v6_4_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v6_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
|
||||
|
||||
/* amdgpu_device_ip_block_add(adev, &uvd_v3_1_ip_block); */
|
||||
/* amdgpu_device_ip_block_add(adev, &vce_v1_0_ip_block); */
|
||||
break;
|
||||
|
@ -2085,11 +2086,11 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &si_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v6_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v6_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v6_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
|
|
@ -502,12 +502,14 @@ static int si_dma_sw_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
/* DMA0 trap event */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 224, &adev->sdma.trap_irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 224,
|
||||
&adev->sdma.trap_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* DMA1 trap event */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 244, &adev->sdma.trap_irq_1);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 244,
|
||||
&adev->sdma.trap_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -649,17 +651,10 @@ static int si_dma_process_trap_irq(struct amdgpu_device *adev,
|
|||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
amdgpu_fence_process(&adev->sdma.instance[0].ring);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int si_dma_process_trap_irq_1(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
amdgpu_fence_process(&adev->sdma.instance[1].ring);
|
||||
|
||||
if (entry->src_id == 224)
|
||||
amdgpu_fence_process(&adev->sdma.instance[0].ring);
|
||||
else
|
||||
amdgpu_fence_process(&adev->sdma.instance[1].ring);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -786,11 +781,6 @@ static const struct amdgpu_irq_src_funcs si_dma_trap_irq_funcs = {
|
|||
.process = si_dma_process_trap_irq,
|
||||
};
|
||||
|
||||
static const struct amdgpu_irq_src_funcs si_dma_trap_irq_funcs_1 = {
|
||||
.set = si_dma_set_trap_irq_state,
|
||||
.process = si_dma_process_trap_irq_1,
|
||||
};
|
||||
|
||||
static const struct amdgpu_irq_src_funcs si_dma_illegal_inst_irq_funcs = {
|
||||
.process = si_dma_process_illegal_inst_irq,
|
||||
};
|
||||
|
@ -799,7 +789,6 @@ static void si_dma_set_irq_funcs(struct amdgpu_device *adev)
|
|||
{
|
||||
adev->sdma.trap_irq.num_types = AMDGPU_SDMA_IRQ_LAST;
|
||||
adev->sdma.trap_irq.funcs = &si_dma_trap_irq_funcs;
|
||||
adev->sdma.trap_irq_1.funcs = &si_dma_trap_irq_funcs_1;
|
||||
adev->sdma.illegal_inst_irq.funcs = &si_dma_illegal_inst_irq_funcs;
|
||||
}
|
||||
|
||||
|
@ -863,10 +852,8 @@ static const struct amdgpu_buffer_funcs si_dma_buffer_funcs = {
|
|||
|
||||
static void si_dma_set_buffer_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->mman.buffer_funcs == NULL) {
|
||||
adev->mman.buffer_funcs = &si_dma_buffer_funcs;
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
|
||||
}
|
||||
adev->mman.buffer_funcs = &si_dma_buffer_funcs;
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
|
||||
}
|
||||
|
||||
static const struct amdgpu_vm_pte_funcs si_dma_vm_pte_funcs = {
|
||||
|
@ -882,15 +869,13 @@ static void si_dma_set_vm_pte_funcs(struct amdgpu_device *adev)
|
|||
struct drm_gpu_scheduler *sched;
|
||||
unsigned i;
|
||||
|
||||
if (adev->vm_manager.vm_pte_funcs == NULL) {
|
||||
adev->vm_manager.vm_pte_funcs = &si_dma_vm_pte_funcs;
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
sched = &adev->sdma.instance[i].ring.sched;
|
||||
adev->vm_manager.vm_pte_rqs[i] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances;
|
||||
adev->vm_manager.vm_pte_funcs = &si_dma_vm_pte_funcs;
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
sched = &adev->sdma.instance[i].ring.sched;
|
||||
adev->vm_manager.vm_pte_rqs[i] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version si_dma_ip_block =
|
||||
|
|
|
@ -7687,11 +7687,11 @@ static int si_dpm_sw_init(void *handle)
|
|||
int ret;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
ret = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 230, &adev->pm.dpm.thermal.irq);
|
||||
ret = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 230, &adev->pm.dpm.thermal.irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 231, &adev->pm.dpm.thermal.irq);
|
||||
ret = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 231, &adev->pm.dpm.thermal.irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ static void si_ih_decode_iv(struct amdgpu_device *adev,
|
|||
dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
|
||||
dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
|
||||
|
||||
entry->client_id = AMDGPU_IH_CLIENTID_LEGACY;
|
||||
entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
|
||||
entry->src_id = dw[0] & 0xff;
|
||||
entry->src_data[0] = dw[1] & 0xfffffff;
|
||||
entry->ring_id = dw[2] & 0xff;
|
||||
|
@ -170,7 +170,7 @@ static int si_ih_sw_init(void *handle)
|
|||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = amdgpu_ih_ring_init(adev, 64 * 1024, false);
|
||||
r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 64 * 1024, false);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -182,7 +182,7 @@ static int si_ih_sw_fini(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
amdgpu_irq_fini(adev);
|
||||
amdgpu_ih_ring_fini(adev);
|
||||
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -308,8 +308,7 @@ static const struct amdgpu_ih_funcs si_ih_funcs = {
|
|||
|
||||
static void si_ih_set_interrupt_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->irq.ih_funcs == NULL)
|
||||
adev->irq.ih_funcs = &si_ih_funcs;
|
||||
adev->irq.ih_funcs = &si_ih_funcs;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version si_ih_ip_block =
|
||||
|
|
|
@ -529,6 +529,8 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
|
@ -539,8 +541,6 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
|||
#else
|
||||
# warning "Enable CONFIG_DRM_AMD_DC for display support on SOC15."
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev))) {
|
||||
amdgpu_device_ip_block_add(adev, &uvd_v7_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vce_v4_0_ip_block);
|
||||
|
@ -551,6 +551,8 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &psp_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
|
@ -560,8 +562,6 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
|||
#else
|
||||
# warning "Enable CONFIG_DRM_AMD_DC for display support on SOC15."
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v1_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
|
@ -739,7 +739,8 @@ static int soc15_common_early_init(void *handle)
|
|||
|
||||
adev->pg_flags = AMD_PG_SUPPORT_SDMA |
|
||||
AMD_PG_SUPPORT_MMHUB |
|
||||
AMD_PG_SUPPORT_VCN;
|
||||
AMD_PG_SUPPORT_VCN |
|
||||
AMD_PG_SUPPORT_VCN_DPG;
|
||||
} else {
|
||||
adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
|
||||
AMD_CG_SUPPORT_GFX_MGLS |
|
||||
|
|
|
@ -57,13 +57,33 @@
|
|||
loop--; \
|
||||
if (!loop) { \
|
||||
DRM_ERROR("Register(%d) [%s] failed to reach value 0x%08x != 0x%08x\n", \
|
||||
inst, #reg, expected_value, (tmp_ & (mask))); \
|
||||
inst, #reg, (unsigned)expected_value, (unsigned)(tmp_ & (mask))); \
|
||||
ret = -ETIMEDOUT; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RREG32_SOC15_DPG_MODE(ip, inst, reg, mask, sram_sel) \
|
||||
({ WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_MASK, mask); \
|
||||
WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_CTL, \
|
||||
UVD_DPG_LMA_CTL__MASK_EN_MASK | \
|
||||
((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) \
|
||||
<< UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT) | \
|
||||
(sram_sel << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT)); \
|
||||
RREG32_SOC15(ip, inst, mmUVD_DPG_LMA_DATA); })
|
||||
|
||||
#define WREG32_SOC15_DPG_MODE(ip, inst, reg, value, mask, sram_sel) \
|
||||
do { \
|
||||
WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_DATA, value); \
|
||||
WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_MASK, mask); \
|
||||
WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_CTL, \
|
||||
UVD_DPG_LMA_CTL__READ_WRITE_MASK | \
|
||||
((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) \
|
||||
<< UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT) | \
|
||||
(sram_sel << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT)); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -266,7 +266,7 @@ static void tonga_ih_decode_iv(struct amdgpu_device *adev,
|
|||
dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
|
||||
dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
|
||||
|
||||
entry->client_id = AMDGPU_IH_CLIENTID_LEGACY;
|
||||
entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
|
||||
entry->src_id = dw[0] & 0xff;
|
||||
entry->src_data[0] = dw[1] & 0xfffffff;
|
||||
entry->ring_id = dw[2] & 0xff;
|
||||
|
@ -317,7 +317,7 @@ static int tonga_ih_sw_init(void *handle)
|
|||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = amdgpu_ih_ring_init(adev, 64 * 1024, true);
|
||||
r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 64 * 1024, true);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -334,7 +334,7 @@ static int tonga_ih_sw_fini(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
amdgpu_irq_fini(adev);
|
||||
amdgpu_ih_ring_fini(adev);
|
||||
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
|
||||
amdgpu_irq_remove_domain(adev);
|
||||
|
||||
return 0;
|
||||
|
@ -513,8 +513,7 @@ static const struct amdgpu_ih_funcs tonga_ih_funcs = {
|
|||
|
||||
static void tonga_ih_set_interrupt_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->irq.ih_funcs == NULL)
|
||||
adev->irq.ih_funcs = &tonga_ih_funcs;
|
||||
adev->irq.ih_funcs = &tonga_ih_funcs;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version tonga_ih_ip_block =
|
||||
|
|
|
@ -108,7 +108,7 @@ static int uvd_v4_2_sw_init(void *handle)
|
|||
int r;
|
||||
|
||||
/* UVD TRAP */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.inst->irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 124, &adev->uvd.inst->irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ static int uvd_v5_0_sw_init(void *handle)
|
|||
int r;
|
||||
|
||||
/* UVD TRAP */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_UVD_SYSTEM_MESSAGE, &adev->uvd.inst->irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_UVD_SYSTEM_MESSAGE, &adev->uvd.inst->irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -274,7 +274,7 @@ static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle
|
|||
*/
|
||||
static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring,
|
||||
uint32_t handle,
|
||||
bool direct, struct dma_fence **fence)
|
||||
struct dma_fence **fence)
|
||||
{
|
||||
const unsigned ib_size_dw = 16;
|
||||
struct amdgpu_job *job;
|
||||
|
@ -310,11 +310,7 @@ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring,
|
|||
for (i = ib->length_dw; i < ib_size_dw; ++i)
|
||||
ib->ptr[i] = 0x0;
|
||||
|
||||
if (direct)
|
||||
r = amdgpu_job_submit_direct(job, ring, &f);
|
||||
else
|
||||
r = amdgpu_job_submit(job, &ring->adev->vce.entity,
|
||||
AMDGPU_FENCE_OWNER_UNDEFINED, &f);
|
||||
r = amdgpu_job_submit_direct(job, ring, &f);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
|
@ -345,7 +341,7 @@ static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
goto error;
|
||||
}
|
||||
|
||||
r = uvd_v6_0_enc_get_destroy_msg(ring, 1, true, &fence);
|
||||
r = uvd_v6_0_enc_get_destroy_msg(ring, 1, &fence);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r);
|
||||
goto error;
|
||||
|
@ -393,14 +389,14 @@ static int uvd_v6_0_sw_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
/* UVD TRAP */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_UVD_SYSTEM_MESSAGE, &adev->uvd.inst->irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_UVD_SYSTEM_MESSAGE, &adev->uvd.inst->irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* UVD ENC TRAP */
|
||||
if (uvd_v6_0_enc_support(adev)) {
|
||||
for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + VISLANDS30_IV_SRCID_UVD_ENC_GEN_PURP, &adev->uvd.inst->irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, i + VISLANDS30_IV_SRCID_UVD_ENC_GEN_PURP, &adev->uvd.inst->irq);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -280,8 +280,8 @@ static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle
|
|||
*
|
||||
* Close up a stream for HW test or if userspace failed to do so
|
||||
*/
|
||||
int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
||||
bool direct, struct dma_fence **fence)
|
||||
static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
||||
struct dma_fence **fence)
|
||||
{
|
||||
const unsigned ib_size_dw = 16;
|
||||
struct amdgpu_job *job;
|
||||
|
@ -317,11 +317,7 @@ int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
|||
for (i = ib->length_dw; i < ib_size_dw; ++i)
|
||||
ib->ptr[i] = 0x0;
|
||||
|
||||
if (direct)
|
||||
r = amdgpu_job_submit_direct(job, ring, &f);
|
||||
else
|
||||
r = amdgpu_job_submit(job, &ring->adev->vce.entity,
|
||||
AMDGPU_FENCE_OWNER_UNDEFINED, &f);
|
||||
r = amdgpu_job_submit_direct(job, ring, &f);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
|
@ -352,7 +348,7 @@ static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
goto error;
|
||||
}
|
||||
|
||||
r = uvd_v7_0_enc_get_destroy_msg(ring, 1, true, &fence);
|
||||
r = uvd_v7_0_enc_get_destroy_msg(ring, 1, &fence);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu: (%d)failed to get destroy ib (%ld).\n", ring->me, r);
|
||||
goto error;
|
||||
|
|
|
@ -417,7 +417,7 @@ static int vce_v2_0_sw_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
/* VCE */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 167, &adev->vce.irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 167, &adev->vce.irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -423,7 +423,7 @@ static int vce_v3_0_sw_init(void *handle)
|
|||
int r, i;
|
||||
|
||||
/* VCE */
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_VCE_TRAP, &adev->vce.irq);
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_VCE_TRAP, &adev->vce.irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
|
||||
#include "ivsrcid/vcn/irqsrcs_vcn_1_0.h"
|
||||
|
||||
#define mmUVD_RBC_XX_IB_REG_CHECK 0x05ab
|
||||
#define mmUVD_RBC_XX_IB_REG_CHECK_BASE_IDX 1
|
||||
#define mmUVD_REG_XX_MASK 0x05ac
|
||||
#define mmUVD_REG_XX_MASK_BASE_IDX 1
|
||||
|
||||
static int vcn_v1_0_stop(struct amdgpu_device *adev);
|
||||
static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
|
||||
static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev);
|
||||
|
@ -198,7 +203,8 @@ static int vcn_v1_0_hw_init(void *handle)
|
|||
|
||||
done:
|
||||
if (!r)
|
||||
DRM_INFO("VCN decode and encode initialized successfully.\n");
|
||||
DRM_INFO("VCN decode and encode initialized successfully(under %s).\n",
|
||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)?"DPG Mode":"SPG Mode");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -266,17 +272,18 @@ static int vcn_v1_0_resume(void *handle)
|
|||
}
|
||||
|
||||
/**
|
||||
* vcn_v1_0_mc_resume - memory controller programming
|
||||
* vcn_v1_0_mc_resume_spg_mode - memory controller programming
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Let the VCN memory controller know it's offsets
|
||||
*/
|
||||
static void vcn_v1_0_mc_resume(struct amdgpu_device *adev)
|
||||
static void vcn_v1_0_mc_resume_spg_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
|
||||
uint32_t offset;
|
||||
|
||||
/* cache window 0: fw */
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
|
||||
(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo));
|
||||
|
@ -296,20 +303,21 @@ static void vcn_v1_0_mc_resume(struct amdgpu_device *adev)
|
|||
|
||||
WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE0, size);
|
||||
|
||||
/* cache window 1: stack */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
|
||||
lower_32_bits(adev->vcn.gpu_addr + offset));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
|
||||
upper_32_bits(adev->vcn.gpu_addr + offset));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1, 0);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_HEAP_SIZE);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
|
||||
|
||||
/* cache window 2: context */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
|
||||
lower_32_bits(adev->vcn.gpu_addr + offset + AMDGPU_VCN_HEAP_SIZE));
|
||||
lower_32_bits(adev->vcn.gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
|
||||
upper_32_bits(adev->vcn.gpu_addr + offset + AMDGPU_VCN_HEAP_SIZE));
|
||||
upper_32_bits(adev->vcn.gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2, 0);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE2,
|
||||
AMDGPU_VCN_STACK_SIZE + (AMDGPU_VCN_SESSION_SIZE * 40));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
|
||||
|
||||
WREG32_SOC15(UVD, 0, mmUVD_UDEC_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
|
@ -317,6 +325,96 @@ static void vcn_v1_0_mc_resume(struct amdgpu_device *adev)
|
|||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_UDEC_DBW_UV_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MIF_CURR_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MIF_CURR_UV_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MIF_RECON1_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MIF_RECON1_UV_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MIF_REF_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MIF_REF_UV_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_JPEG_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_JPEG_UV_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
}
|
||||
|
||||
static void vcn_v1_0_mc_resume_dpg_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
|
||||
uint32_t offset;
|
||||
|
||||
/* cache window 0: fw */
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
|
||||
(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo),
|
||||
0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
|
||||
(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi),
|
||||
0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0, 0,
|
||||
0xFFFFFFFF, 0);
|
||||
offset = 0;
|
||||
} else {
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
|
||||
lower_32_bits(adev->vcn.gpu_addr), 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
|
||||
upper_32_bits(adev->vcn.gpu_addr), 0xFFFFFFFF, 0);
|
||||
offset = size;
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0,
|
||||
AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0xFFFFFFFF, 0);
|
||||
}
|
||||
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_SIZE0, size, 0xFFFFFFFF, 0);
|
||||
|
||||
/* cache window 1: stack */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
|
||||
lower_32_bits(adev->vcn.gpu_addr + offset), 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
|
||||
upper_32_bits(adev->vcn.gpu_addr + offset), 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1, 0,
|
||||
0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE,
|
||||
0xFFFFFFFF, 0);
|
||||
|
||||
/* cache window 2: context */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
|
||||
lower_32_bits(adev->vcn.gpu_addr + offset + AMDGPU_VCN_STACK_SIZE),
|
||||
0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
|
||||
upper_32_bits(adev->vcn.gpu_addr + offset + AMDGPU_VCN_STACK_SIZE),
|
||||
0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2, 0, 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE,
|
||||
0xFFFFFFFF, 0);
|
||||
|
||||
/* VCN global tiling registers */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_DBW_UV_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MIF_CURR_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MIF_CURR_UV_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MIF_RECON1_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MIF_RECON1_UV_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MIF_REF_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MIF_REF_UV_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -519,6 +617,60 @@ static void vcn_v1_0_enable_clock_gating(struct amdgpu_device *adev)
|
|||
WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL, data);
|
||||
}
|
||||
|
||||
static void vcn_v1_0_clock_gating_dpg_mode(struct amdgpu_device *adev, uint8_t sram_sel)
|
||||
{
|
||||
uint32_t reg_data = 0;
|
||||
|
||||
/* disable JPEG CGC */
|
||||
if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
|
||||
reg_data = 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
|
||||
else
|
||||
reg_data = 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
|
||||
reg_data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
|
||||
reg_data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmJPEG_CGC_CTRL, reg_data, 0xFFFFFFFF, sram_sel);
|
||||
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmJPEG_CGC_GATE, 0, 0xFFFFFFFF, sram_sel);
|
||||
|
||||
/* enable sw clock gating control */
|
||||
if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
|
||||
reg_data = 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
|
||||
else
|
||||
reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
|
||||
reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
|
||||
reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
|
||||
reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
|
||||
UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
|
||||
UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
|
||||
UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
|
||||
UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
|
||||
UVD_CGC_CTRL__SYS_MODE_MASK |
|
||||
UVD_CGC_CTRL__UDEC_MODE_MASK |
|
||||
UVD_CGC_CTRL__MPEG2_MODE_MASK |
|
||||
UVD_CGC_CTRL__REGS_MODE_MASK |
|
||||
UVD_CGC_CTRL__RBC_MODE_MASK |
|
||||
UVD_CGC_CTRL__LMI_MC_MODE_MASK |
|
||||
UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
|
||||
UVD_CGC_CTRL__IDCT_MODE_MASK |
|
||||
UVD_CGC_CTRL__MPRD_MODE_MASK |
|
||||
UVD_CGC_CTRL__MPC_MODE_MASK |
|
||||
UVD_CGC_CTRL__LBSI_MODE_MASK |
|
||||
UVD_CGC_CTRL__LRBBM_MODE_MASK |
|
||||
UVD_CGC_CTRL__WCB_MODE_MASK |
|
||||
UVD_CGC_CTRL__VCPU_MODE_MASK |
|
||||
UVD_CGC_CTRL__SCPU_MODE_MASK);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_CGC_CTRL, reg_data, 0xFFFFFFFF, sram_sel);
|
||||
|
||||
/* turn off clock gating */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_CGC_GATE, 0, 0xFFFFFFFF, sram_sel);
|
||||
|
||||
/* turn on SUVD clock gating */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_SUVD_CGC_GATE, 1, 0xFFFFFFFF, sram_sel);
|
||||
|
||||
/* turn on sw mode in UVD_SUVD_CGC_CTRL */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_SUVD_CGC_CTRL, 0, 0xFFFFFFFF, sram_sel);
|
||||
}
|
||||
|
||||
static void vcn_1_0_disable_static_power_gating(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
|
@ -614,7 +766,7 @@ static void vcn_1_0_enable_static_power_gating(struct amdgpu_device *adev)
|
|||
*
|
||||
* Setup and start the VCN block
|
||||
*/
|
||||
static int vcn_v1_0_start(struct amdgpu_device *adev)
|
||||
static int vcn_v1_0_start_spg_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *ring = &adev->vcn.ring_dec;
|
||||
uint32_t rb_bufsz, tmp;
|
||||
|
@ -625,41 +777,24 @@ static int vcn_v1_0_start(struct amdgpu_device *adev)
|
|||
lmi_swap_cntl = 0;
|
||||
|
||||
vcn_1_0_disable_static_power_gating(adev);
|
||||
|
||||
tmp = RREG32_SOC15(UVD, 0, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_STATUS, tmp);
|
||||
|
||||
/* disable clock gating */
|
||||
vcn_v1_0_disable_clock_gating(adev);
|
||||
|
||||
vcn_v1_0_mc_resume(adev);
|
||||
|
||||
/* disable interupt */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0,
|
||||
~UVD_MASTINT_EN__VCPU_EN_MASK);
|
||||
|
||||
/* stall UMC and register bus before resetting VCPU */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
|
||||
UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
|
||||
~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
|
||||
mdelay(1);
|
||||
|
||||
/* put LMI, VCPU, RBC etc... into reset */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET,
|
||||
UVD_SOFT_RESET__LMI_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__RBC_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__CSM_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__CXW_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__TAP_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
|
||||
mdelay(5);
|
||||
|
||||
/* initialize VCN memory controller */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL,
|
||||
(0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
|
||||
UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
|
||||
UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
|
||||
UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
|
||||
UVD_LMI_CTRL__REQ_MODE_MASK |
|
||||
0x00100000L);
|
||||
tmp = RREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL, tmp |
|
||||
UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
|
||||
UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
|
||||
UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
|
||||
UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
|
||||
|
||||
#ifdef __BIG_ENDIAN
|
||||
/* swap (8 in 32) RB and IB */
|
||||
|
@ -667,41 +802,61 @@ static int vcn_v1_0_start(struct amdgpu_device *adev)
|
|||
#endif
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl);
|
||||
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA0, 0x40c2040);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA1, 0x0);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB0, 0x40c2040);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB1, 0x0);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_ALU, 0);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUX, 0x88);
|
||||
tmp = RREG32_SOC15(UVD, 0, mmUVD_MPC_CNTL);
|
||||
tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
|
||||
tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MPC_CNTL, tmp);
|
||||
|
||||
/* take all subblocks out of reset, except VCPU */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET,
|
||||
UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
|
||||
mdelay(5);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA0,
|
||||
((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
|
||||
(0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
|
||||
(0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
|
||||
(0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
|
||||
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB0,
|
||||
((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
|
||||
(0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
|
||||
(0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
|
||||
(0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
|
||||
|
||||
WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUX,
|
||||
((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
|
||||
(0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
|
||||
(0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
|
||||
|
||||
vcn_v1_0_mc_resume_spg_mode(adev);
|
||||
|
||||
WREG32_SOC15(UVD, 0, mmUVD_REG_XX_MASK, 0x10);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK,
|
||||
RREG32_SOC15(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK) | 0x3);
|
||||
|
||||
/* enable VCPU clock */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL,
|
||||
UVD_VCPU_CNTL__CLK_EN_MASK);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, UVD_VCPU_CNTL__CLK_EN_MASK);
|
||||
|
||||
/* boot up the VCPU */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0,
|
||||
~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
|
||||
|
||||
/* enable UMC */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0,
|
||||
~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
|
||||
|
||||
/* boot up the VCPU */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, 0);
|
||||
mdelay(10);
|
||||
tmp = RREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET);
|
||||
tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
|
||||
tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, tmp);
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
uint32_t status;
|
||||
|
||||
for (j = 0; j < 100; ++j) {
|
||||
status = RREG32_SOC15(UVD, 0, mmUVD_STATUS);
|
||||
if (status & 2)
|
||||
if (status & UVD_STATUS__IDLE)
|
||||
break;
|
||||
mdelay(10);
|
||||
}
|
||||
r = 0;
|
||||
if (status & 2)
|
||||
if (status & UVD_STATUS__IDLE)
|
||||
break;
|
||||
|
||||
DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n");
|
||||
|
@ -721,24 +876,22 @@ static int vcn_v1_0_start(struct amdgpu_device *adev)
|
|||
}
|
||||
/* enable master interrupt */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN),
|
||||
(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK),
|
||||
~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK));
|
||||
UVD_MASTINT_EN__VCPU_EN_MASK, ~UVD_MASTINT_EN__VCPU_EN_MASK);
|
||||
|
||||
/* enable system interrupt for JRBC, TODO: move to set interrupt*/
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SYS_INT_EN),
|
||||
UVD_SYS_INT_EN__UVD_JRBC_EN_MASK,
|
||||
~UVD_SYS_INT_EN__UVD_JRBC_EN_MASK);
|
||||
|
||||
/* clear the bit 4 of VCN_STATUS */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0,
|
||||
~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
|
||||
/* clear the busy bit of UVD_STATUS */
|
||||
tmp = RREG32_SOC15(UVD, 0, mmUVD_STATUS) & ~UVD_STATUS__UVD_BUSY;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_STATUS, tmp);
|
||||
|
||||
/* force RBC into idle state */
|
||||
rb_bufsz = order_base_2(ring->ring_size);
|
||||
tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp);
|
||||
|
@ -759,6 +912,8 @@ static int vcn_v1_0_start(struct amdgpu_device *adev)
|
|||
/* Initialize the ring buffer's read and write pointers */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR, 0);
|
||||
|
||||
WREG32_SOC15(UVD, 0, mmUVD_SCRATCH2, 0);
|
||||
|
||||
ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
|
||||
lower_32_bits(ring->wptr));
|
||||
|
@ -782,12 +937,13 @@ static int vcn_v1_0_start(struct amdgpu_device *adev)
|
|||
|
||||
ring = &adev->vcn.ring_jpeg;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK |
|
||||
UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, lower_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, upper_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR, 0);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, 0);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL, 0x00000002L);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
|
||||
|
||||
/* initialize wptr */
|
||||
ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR);
|
||||
|
@ -799,6 +955,166 @@ static int vcn_v1_0_start(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vcn_v1_0_start_dpg_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *ring = &adev->vcn.ring_dec;
|
||||
uint32_t rb_bufsz, tmp;
|
||||
uint32_t lmi_swap_cntl;
|
||||
|
||||
/* disable byte swapping */
|
||||
lmi_swap_cntl = 0;
|
||||
|
||||
vcn_1_0_enable_static_power_gating(adev);
|
||||
|
||||
/* enable dynamic power gating mode */
|
||||
tmp = RREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS);
|
||||
tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;
|
||||
tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK;
|
||||
WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, tmp);
|
||||
|
||||
/* enable clock gating */
|
||||
vcn_v1_0_clock_gating_dpg_mode(adev, 0);
|
||||
|
||||
/* enable VCPU clock */
|
||||
tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
|
||||
tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
|
||||
tmp |= UVD_VCPU_CNTL__MIF_WR_LOW_THRESHOLD_BP_MASK;
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CNTL, tmp, 0xFFFFFFFF, 0);
|
||||
|
||||
/* disable interupt */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MASTINT_EN,
|
||||
0, UVD_MASTINT_EN__VCPU_EN_MASK, 0);
|
||||
|
||||
/* initialize VCN memory controller */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_CTRL,
|
||||
(8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
|
||||
UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
|
||||
UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
|
||||
UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
|
||||
UVD_LMI_CTRL__REQ_MODE_MASK |
|
||||
UVD_LMI_CTRL__CRC_RESET_MASK |
|
||||
UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
|
||||
0x00100000L, 0xFFFFFFFF, 0);
|
||||
|
||||
#ifdef __BIG_ENDIAN
|
||||
/* swap (8 in 32) RB and IB */
|
||||
lmi_swap_cntl = 0xa;
|
||||
#endif
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl, 0xFFFFFFFF, 0);
|
||||
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_CNTL,
|
||||
0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0xFFFFFFFF, 0);
|
||||
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_SET_MUXA0,
|
||||
((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
|
||||
(0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
|
||||
(0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
|
||||
(0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0xFFFFFFFF, 0);
|
||||
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_SET_MUXB0,
|
||||
((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
|
||||
(0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
|
||||
(0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
|
||||
(0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0xFFFFFFFF, 0);
|
||||
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MPC_SET_MUX,
|
||||
((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
|
||||
(0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
|
||||
(0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0xFFFFFFFF, 0);
|
||||
|
||||
vcn_v1_0_mc_resume_dpg_mode(adev);
|
||||
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_REG_XX_MASK, 0x10, 0xFFFFFFFF, 0);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK, 0x3, 0xFFFFFFFF, 0);
|
||||
|
||||
/* boot up the VCPU */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_SOFT_RESET, 0, 0xFFFFFFFF, 0);
|
||||
|
||||
/* enable UMC */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_CTRL2,
|
||||
0x1F << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT,
|
||||
0xFFFFFFFF, 0);
|
||||
|
||||
/* enable master interrupt */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_MASTINT_EN,
|
||||
UVD_MASTINT_EN__VCPU_EN_MASK, UVD_MASTINT_EN__VCPU_EN_MASK, 0);
|
||||
|
||||
vcn_v1_0_clock_gating_dpg_mode(adev, 1);
|
||||
/* setup mmUVD_LMI_CTRL */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_CTRL,
|
||||
(8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
|
||||
UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
|
||||
UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
|
||||
UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
|
||||
UVD_LMI_CTRL__REQ_MODE_MASK |
|
||||
UVD_LMI_CTRL__CRC_RESET_MASK |
|
||||
UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
|
||||
0x00100000L, 0xFFFFFFFF, 1);
|
||||
|
||||
tmp = adev->gfx.config.gb_addr_config;
|
||||
/* setup VCN global tiling registers */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_JPEG_ADDR_CONFIG, tmp, 0xFFFFFFFF, 1);
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_JPEG_UV_ADDR_CONFIG, tmp, 0xFFFFFFFF, 1);
|
||||
|
||||
/* enable System Interrupt for JRBC */
|
||||
WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_SYS_INT_EN,
|
||||
UVD_SYS_INT_EN__UVD_JRBC_EN_MASK, 0xFFFFFFFF, 1);
|
||||
|
||||
/* force RBC into idle state */
|
||||
rb_bufsz = order_base_2(ring->ring_size);
|
||||
tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp);
|
||||
|
||||
/* set the write pointer delay */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL, 0);
|
||||
|
||||
/* set the wb address */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR_ADDR,
|
||||
(upper_32_bits(ring->gpu_addr) >> 2));
|
||||
|
||||
/* programm the RB_BASE for ring buffer */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
|
||||
lower_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
|
||||
upper_32_bits(ring->gpu_addr));
|
||||
|
||||
/* Initialize the ring buffer's read and write pointers */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR, 0);
|
||||
|
||||
WREG32_SOC15(UVD, 0, mmUVD_SCRATCH2, 0);
|
||||
|
||||
ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
|
||||
lower_32_bits(ring->wptr));
|
||||
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0,
|
||||
~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK);
|
||||
|
||||
/* initialize wptr */
|
||||
ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR);
|
||||
|
||||
/* copy patch commands to the jpeg ring */
|
||||
vcn_v1_0_jpeg_ring_set_patch_ring(ring,
|
||||
(ring->wptr + ring->max_dw * amdgpu_sched_hw_submission));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vcn_v1_0_start(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
|
||||
r = vcn_v1_0_start_dpg_mode(adev);
|
||||
else
|
||||
r = vcn_v1_0_start_spg_mode(adev);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* vcn_v1_0_stop - stop VCN block
|
||||
*
|
||||
|
@ -806,41 +1122,90 @@ static int vcn_v1_0_start(struct amdgpu_device *adev)
|
|||
*
|
||||
* stop the VCN block
|
||||
*/
|
||||
static int vcn_v1_0_stop(struct amdgpu_device *adev)
|
||||
static int vcn_v1_0_stop_spg_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
/* force RBC into idle state */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, 0x11010101);
|
||||
int ret_code, tmp;
|
||||
|
||||
/* Stall UMC and register bus before resetting VCPU */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
|
||||
UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
|
||||
~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
|
||||
mdelay(1);
|
||||
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7, ret_code);
|
||||
|
||||
tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
|
||||
UVD_LMI_STATUS__READ_CLEAN_MASK |
|
||||
UVD_LMI_STATUS__WRITE_CLEAN_MASK |
|
||||
UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
|
||||
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_LMI_STATUS, tmp, tmp, ret_code);
|
||||
|
||||
/* put VCPU into reset */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET,
|
||||
UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
|
||||
mdelay(5);
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
|
||||
UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,
|
||||
~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
|
||||
|
||||
tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK |
|
||||
UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
|
||||
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_LMI_STATUS, tmp, tmp, ret_code);
|
||||
|
||||
/* disable VCPU clock */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, 0x0);
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL), 0,
|
||||
~UVD_VCPU_CNTL__CLK_EN_MASK);
|
||||
|
||||
/* Unstall UMC and register bus */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0,
|
||||
~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
|
||||
/* reset LMI UMC/LMI */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
|
||||
UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK,
|
||||
~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
|
||||
|
||||
WREG32_SOC15(VCN, 0, mmUVD_STATUS, 0);
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
|
||||
UVD_SOFT_RESET__LMI_SOFT_RESET_MASK,
|
||||
~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK);
|
||||
|
||||
WREG32_SOC15(UVD, 0, mmUVD_STATUS, 0);
|
||||
|
||||
vcn_v1_0_enable_clock_gating(adev);
|
||||
vcn_1_0_enable_static_power_gating(adev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vcn_v1_0_stop_dpg_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
int ret_code = 0;
|
||||
|
||||
/* Wait for power status to be UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF */
|
||||
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
|
||||
if (!ret_code) {
|
||||
int tmp = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF;
|
||||
/* wait for read ptr to be equal to write ptr */
|
||||
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF, ret_code);
|
||||
|
||||
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
}
|
||||
|
||||
/* disable dynamic power gating mode */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), 0,
|
||||
~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vcn_v1_0_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
|
||||
r = vcn_v1_0_stop_dpg_mode(adev);
|
||||
else
|
||||
r = vcn_v1_0_stop_spg_mode(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool vcn_v1_0_is_idle(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
return (RREG32_SOC15(VCN, 0, mmUVD_STATUS) == 0x2);
|
||||
return (RREG32_SOC15(VCN, 0, mmUVD_STATUS) == UVD_STATUS__IDLE);
|
||||
}
|
||||
|
||||
static int vcn_v1_0_wait_for_idle(void *handle)
|
||||
|
@ -848,7 +1213,8 @@ static int vcn_v1_0_wait_for_idle(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret = 0;
|
||||
|
||||
SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_STATUS, 0x2, 0x2, ret);
|
||||
SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_STATUS, UVD_STATUS__IDLE,
|
||||
UVD_STATUS__IDLE, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -910,6 +1276,10 @@ static void vcn_v1_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
|
|||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
|
||||
WREG32_SOC15(UVD, 0, mmUVD_SCRATCH2,
|
||||
lower_32_bits(ring->wptr) | 0x80000000);
|
||||
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
|
||||
}
|
||||
|
||||
|
@ -1633,12 +2003,20 @@ static int vcn_v1_0_set_powergating_state(void *handle,
|
|||
* revisit this when there is a cleaner line between
|
||||
* the smc and the hw blocks
|
||||
*/
|
||||
int ret;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if(state == adev->vcn.cur_state)
|
||||
return 0;
|
||||
|
||||
if (state == AMD_PG_STATE_GATE)
|
||||
return vcn_v1_0_stop(adev);
|
||||
ret = vcn_v1_0_stop(adev);
|
||||
else
|
||||
return vcn_v1_0_start(adev);
|
||||
ret = vcn_v1_0_start(adev);
|
||||
|
||||
if(!ret)
|
||||
adev->vcn.cur_state = state;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs vcn_v1_0_ip_funcs = {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue