diff --git a/src/freedreno/afuc/emu-regs.c b/src/freedreno/afuc/emu-regs.c
index b5577950bef..e714e27576a 100644
--- a/src/freedreno/afuc/emu-regs.c
+++ b/src/freedreno/afuc/emu-regs.c
@@ -210,13 +210,33 @@ emu_get_fifo_reg(struct emu *emu, unsigned n, bool peek)
/* $memdata */
EMU_CONTROL_REG(MEM_READ_DWORDS);
EMU_CONTROL_REG(MEM_READ_ADDR);
+ EMU_CONTROL_REG(MEM_READ_ADDR_HI_PRIVILEGED);
unsigned read_dwords = emu_get_reg32(emu, &MEM_READ_DWORDS);
uintptr_t read_addr = emu_get_reg64(emu, &MEM_READ_ADDR);
+ uintptr_t read_addr_hi = 0;
+ if (emu->fw_id == AFUC_A750)
+ read_addr_hi = emu_get_reg64(emu, &MEM_READ_ADDR_HI_PRIVILEGED);
+
+ /* We don't model privileged vs. non-privileged accesses here, so just
+ * use the right address.
+ *
+ * TODO: all uses of MEM_READ_ADDR_HI_PRIVILEGED set bit 31, is this the
+ * right bit or do we need to track writes to it?
+ */
+ if (read_addr_hi & (1u << 31)) {
+ read_addr = (read_addr & 0xffffffff) |
+ ((read_addr_hi & ~(1u << 31)) << 32);
+ }
if (read_dwords > 0 && !peek) {
emu_set_reg32(emu, &MEM_READ_DWORDS, read_dwords - 1);
- emu_set_reg64(emu, &MEM_READ_ADDR, read_addr + 4);
+ if (read_addr_hi & (1u << 31)) {
+ /* Privileged memory should all be in the same 4GB space. */
+ emu_set_reg32(emu, &MEM_READ_ADDR, read_addr + 4);
+ } else {
+ emu_set_reg64(emu, &MEM_READ_ADDR, read_addr + 4);
+ }
}
return emu_mem_read_dword(emu, read_addr);
diff --git a/src/freedreno/afuc/emu.c b/src/freedreno/afuc/emu.c
index 5b1de881744..13ff8fd25e7 100644
--- a/src/freedreno/afuc/emu.c
+++ b/src/freedreno/afuc/emu.c
@@ -567,7 +567,10 @@ emu_init(struct emu *emu)
break;
}
- if (emu->fw_id == AFUC_A730 || emu->fw_id == AFUC_A740) {
+ if (emu->fw_id == AFUC_A750) {
+ emu_set_control_reg(emu, 0, 7 << 28);
+ emu_set_control_reg(emu, 2, 0x40 << 8);
+ } else if (emu->fw_id == AFUC_A730 || emu->fw_id == AFUC_A740) {
emu_set_control_reg(emu, 0xef, 1 << 21);
emu_set_control_reg(emu, 0, 7 << 28);
} else if (emu->fw_id == AFUC_A660) {
diff --git a/src/freedreno/afuc/util.c b/src/freedreno/afuc/util.c
index 90c5352c188..5a37348f6a2 100644
--- a/src/freedreno/afuc/util.c
+++ b/src/freedreno/afuc/util.c
@@ -275,6 +275,13 @@ int afuc_util_init(enum afuc_fwid fw_id, int *gpuver_out, bool colors)
char *pipe_reg_name = NULL;
switch (fw_id) {
+ case AFUC_A750:
+ name = "A6XX";
+ variant = "A7XX";
+ control_reg_name = "A7XX_GEN3_CONTROL_REG";
+ pipe_reg_name = "A7XX_PIPE_REG";
+ *gpuver_out = 7;
+ break;
case AFUC_A730:
case AFUC_A740:
name = "A6XX";
diff --git a/src/freedreno/afuc/util.h b/src/freedreno/afuc/util.h
index 6ab1b954692..2030b2bc924 100644
--- a/src/freedreno/afuc/util.h
+++ b/src/freedreno/afuc/util.h
@@ -58,6 +58,7 @@ void afuc_printc(enum afuc_color c, const char *fmt, ...);
enum afuc_fwid {
AFUC_A730 = 0x730,
AFUC_A740 = 0x740,
+ AFUC_A750 = 0x520,
AFUC_A630 = 0x6ee,
AFUC_A650 = 0x6dc,
diff --git a/src/freedreno/registers/adreno/adreno_control_regs.xml b/src/freedreno/registers/adreno/adreno_control_regs.xml
index 365fef4c1ee..7a3af94fae0 100644
--- a/src/freedreno/registers/adreno/adreno_control_regs.xml
+++ b/src/freedreno/registers/adreno/adreno_control_regs.xml
@@ -364,6 +364,10 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+ These registers seem to define a range that load/store instructions can access
+
+
+
Register used to create critical sections when reading/writing
shared memory (0x200-0x2ff). Each bit contains a lock. Writing 1
@@ -394,4 +398,83 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+
+
+
+
+
+
+
+
+ After setting these, read result from $regdata
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+