summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_falcon.h
blob: 69a56e246715c351f87c5de0f582465e937cad60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef GSP_PHYS_FALCON_H
#define GSP_PHYS_FALCON_H

#include <linux/types.h>
#include <linux/io.h>

/*
 * Shared Falcon engine helpers for the real-GSP boot stages.
 *
 * The register map, field bits and the reset/copy/start/halt sequences are
 * identical for the GSP and SEC2 falcons on Turing; the FWSEC stage (3c) uses
 * them through the generic SEC2 boot-loader, and the Booter Load stage (3d)
 * uses them directly on SEC2. Keeping the helpers in one place keeps both
 * ports on the same verified register sequence.
 *
 * All BAR0 writes go through these helpers; the only device reads are the
 * bounded liveness polls the reference performs as well.
 */

/* Falcon engine bases (BAR0 absolute). */
#define GSP_PHYS_GSP_BASE		0x00110000
#define GSP_PHYS_GSP_FBIF_BASE		0x00110600
#define GSP_PHYS_SEC2_BASE		0x00840000
#define GSP_PHYS_SEC2_FBIF_BASE		0x00840600

/* Falcon register offsets, relative to the engine base. */
#define GSP_PHYS_FALCON_MAILBOX0	0x40
#define GSP_PHYS_FALCON_MAILBOX1	0x44
#define GSP_PHYS_FALCON_OS		0x80
#define GSP_PHYS_FALCON_RM		0x84
#define GSP_PHYS_FALCON_HWCFG2		0xf4
#define GSP_PHYS_FALCON_CPUCTL		0x100
#define GSP_PHYS_FALCON_BOOTVEC		0x104
#define GSP_PHYS_FALCON_HWCFG		0x108
#define GSP_PHYS_FALCON_DMACTL		0x10c
#define GSP_PHYS_FALCON_CPUCTL_ALIAS	0x130
#define GSP_PHYS_FALCON_IMEMC		0x180
#define GSP_PHYS_FALCON_IMEMD		0x184
#define GSP_PHYS_FALCON_IMEMT		0x188
#define GSP_PHYS_FALCON_DMEMC		0x1c0
#define GSP_PHYS_FALCON_DMEMD		0x1c4
#define GSP_PHYS_FALCON_ENGINE		0x3c0

/* FBIF registers, relative to the falcon's FBIF base. */
#define GSP_PHYS_FBIF_TRANSCFG(i)	((i) * 4)
#define GSP_PHYS_FBIF_CTL		0x24

/* Falcon CPUCTL / ENGINE / DMACTL field bits. */
#define GSP_PHYS_CPUCTL_STARTCPU	BIT(1)
#define GSP_PHYS_CPUCTL_HALTED		BIT(4)
#define GSP_PHYS_CPUCTL_ALIAS_EN	BIT(6)
#define GSP_PHYS_ENGINE_RESET		BIT(0)
#define GSP_PHYS_DMACTL_DMEM_SCRUBBING	BIT(1)
#define GSP_PHYS_DMACTL_IMEM_SCRUBBING	BIT(2)
#define GSP_PHYS_HWCFG_IMEM_SIZE	0x1ff
/*
 * SEC2 falcon HWCFG DMEM capacity: bits 17:9 in 256-byte blocks (the v04
 * falcon reports IMEM at 8:0 and DMEM at 17:9).
 */
#define GSP_PHYS_HWCFG_DMEM_SIZE	0x0003fe00
#define GSP_PHYS_HWCFG_DMEM_SIZE_SHIFT	9

/* FBIF CTL / TRANSCFG fields. */
#define GSP_PHYS_FBIF_CTL_ALLOW_PHYS_NO_CTX	BIT(7)
#define GSP_PHYS_FBIF_TRANSCFG_TARGET_MASK	0x3
#define GSP_PHYS_FBIF_TRANSCFG_TARGET_COHERENT_SYSMEM	0x1
#define GSP_PHYS_FBIF_TRANSCFG_MEM_TYPE		BIT(2)

/* IMEM/DMEM access port fields. */
#define GSP_PHYS_FALCON_ADDR_MASK	(0x0000fffc)
#define GSP_PHYS_FALCON_AINCW		BIT(24)
#define GSP_PHYS_FALCON_AINCR		BIT(25)
#define GSP_PHYS_FALCON_IMEMC_SECURE	BIT(28)

/*
 * Reset: pulse the engine reset bit with the reference's propagation read
 * cycles, wait for the IMEM/DMEM scrubbers to report done (bounded), then
 * load FALCON_RM with the raw PMC_BOOT_0 value.
 */
int gsp_phys_falcon_reset(void __iomem *bar0, u32 base);

/*
 * Allow physical DMA without a bound context: FBIF CTL bit7 and DMACTL=0,
 * so a directly-loaded ucode (or the generic boot-loader) can fetch its
 * descriptors.
 */
void gsp_phys_falcon_disable_ctx_req(void __iomem *bar0, u32 base, u32 fbif);

/* Copy a word-aligned buffer through the DMEM access port at dest. */
void gsp_phys_falcon_dmem_copy(void __iomem *bar0, u32 base, u32 dest,
			       const u8 *src, u32 size);

/*
 * Copy a 256-byte-block-aligned buffer through the IMEM access port with
 * per-256-byte tags starting at tag>>8, incrementing once per block. The tag
 * names the virtual IMEM block; callers pass the source image offset.
 */
void gsp_phys_falcon_imem_copy(void __iomem *bar0, u32 base, u32 dest,
			       const u8 *src, u32 size, bool secure, u32 tag);

/* Start the CPU (CPUCTL.STARTCPU, via the alias register when ALIAS_EN). */
void gsp_phys_falcon_start_cpu(void __iomem *bar0, u32 base);

/* Poll CPUCTL.HALTED with a bounded timeout; returns -ETIMEDOUT on expiry. */
int gsp_phys_falcon_wait_halt(void __iomem *bar0, u32 base, u32 timeout_ms);

#endif /* GSP_PHYS_FALCON_H */