Skip to content

Instantly share code, notes, and snippets.

@Coreforge
Created September 11, 2021 19:36
Show Gist options
  • Save Coreforge/2e9fd18dcd26e8194dea9ac4d292c22d to your computer and use it in GitHub Desktop.
Save Coreforge/2e9fd18dcd26e8194dea9ac4d292c22d to your computer and use it in GitHub Desktop.
From f6fd42700eef4852fe48c1a5d405f5299ec55dd5 Mon Sep 17 00:00:00 2001
From: Coreforge <BC549b@gmail.com>
Date: Sat, 11 Sep 2021 21:05:57 +0200
Subject: [PATCH] added memcpy_toio_pcie, memcpy_fromio_pcie and memset_io
functions and replaced all calls in amdgpu with them
---
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 ++
drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 6 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 97 +++++++++++++++++++++-
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 8 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 8 +-
drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 4 +-
drivers/gpu/drm/amd/amdgpu/vce_v4_0.c | 4 +-
9 files changed, 120 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 87f095dc385c..bb798be83a91 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1051,6 +1051,14 @@ bool amdgpu_device_has_dc_support(struct amdgpu_device *adev);
int emu_soc_asic_init(struct amdgpu_device *adev);
+/*
+ * memcpy_io and memset_io functions that work on a raspberry pi 4
+ */
+
+void memcpy_fromio_pcie(void *to, const volatile void __iomem *from, size_t count);
+void memcpy_toio_pcie(volatile void __iomem *to, const void *from, size_t count);
+void memset_io_pcie(volatile void __iomem *dst, int c, size_t count);
+
/*
* Registers read & write functions.
*/
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index 6333cada1e09..2caf315933f9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -110,7 +110,7 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev)
return false;
}
adev->bios_size = size;
- memcpy_fromio(adev->bios, bios, size);
+ memcpy_fromio_pcie(adev->bios, bios, size);
iounmap(bios);
if (!check_atom_bios(adev->bios, size)) {
@@ -139,7 +139,7 @@ bool amdgpu_read_bios(struct amdgpu_device *adev)
return false;
}
adev->bios_size = size;
- memcpy_fromio(adev->bios, bios, size);
+ memcpy_fromio_pcie(adev->bios, bios, size);
pci_unmap_rom(adev->pdev, bios);
if (!check_atom_bios(adev->bios, size)) {
@@ -209,7 +209,7 @@ static bool amdgpu_read_platform_bios(struct amdgpu_device *adev)
if (!bios)
goto free_bios;
- memcpy_fromio(adev->bios, bios, romlen);
+ memcpy_fromio_pcie(adev->bios, bios, romlen);
iounmap(bios);
if (!check_atom_bios(adev->bios, romlen))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 76d10f1c579b..a23f82a6d410 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -117,6 +117,99 @@ const char *amdgpu_asic_name[] = {
"LAST",
};
+
+/**
+ * DOC: memcpy_fromio_pcie
+ *
+ * like memcpy_fromio, but it only uses 8-bit and 32-bit wide accesses to work on a raspberry pi 4
+ */
+
+void memcpy_fromio_pcie(void *to, const volatile void __iomem *from, size_t count)
+{
+ while (count && !IS_ALIGNED((unsigned long)from, 8)) {
+ *(u8 *)to = __raw_readb(from);
+ from++;
+ to++;
+ count--;
+ }
+
+ while (count >= 4) {
+ *(u32 *)to = __raw_readl(from);
+ from += 4;
+ to += 4;
+ count -= 4;
+ }
+
+ while (count) {
+ *(u8 *)to = __raw_readb(from);
+ from++;
+ to++;
+ count--;
+ }
+}
+
+/**
+ * DOC: memcpy_toio_pcie
+ *
+ * like memcpy_toio, but it only uses 8-bit and 32-bit wide accesses to work on a raspberry pi 4
+ */
+
+void memcpy_toio_pcie(volatile void __iomem *to, const void *from, size_t count)
+{
+ while (count && !IS_ALIGNED((unsigned long)to, 8)) {
+ __raw_writeb(*(u8 *)from, to);
+ from++;
+ to++;
+ count--;
+ }
+
+ while (count >= 4) {
+ __raw_writel(*(u64 *)from, to);
+ from += 4;
+ to += 4;
+ count -= 4;
+ }
+
+ while (count) {
+ __raw_writeb(*(u8 *)from, to);
+ from++;
+ to++;
+ count--;
+ }
+}
+
+/**
+ * DOC: memset_io_pcie
+ *
+ * like memset_io, but it only uses 8-bit and 32-bit wide accesses to work on a raspberry pi 4
+ */
+
+void memset_io_pcie(volatile void __iomem *dst, int c, size_t count)
+{
+ u32 qc = (u8)c;
+
+ qc |= qc << 8;
+ qc |= qc << 16;
+
+ while (count && !IS_ALIGNED((unsigned long)dst, 8)) {
+ __raw_writeb(c, dst);
+ dst++;
+ count--;
+ }
+
+ while (count >= 4) {
+ __raw_writel(qc, dst);
+ dst += 4;
+ count -= 4;
+ }
+
+ while (count) {
+ __raw_writeb(c, dst);
+ dst++;
+ count--;
+ }
+}
+
/**
* DOC: pcie_replay_count
*
@@ -267,13 +360,13 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
size_t count = last - pos;
if (write) {
- memcpy_toio(addr, buf, count);
+ memcpy_toio_pcie(addr, buf, count);
mb();
amdgpu_asic_flush_hdp(adev, NULL);
} else {
amdgpu_asic_invalidate_hdp(adev, NULL);
mb();
- memcpy_fromio(buf, addr, count);
+ memcpy_fromio_pcie(buf, addr, count);
}
if (count == size)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 2f47f81a74a5..717a40b11eba 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -2690,7 +2690,7 @@ static ssize_t psp_usbc_pd_fw_sysfs_write(struct device *dev,
if (ret)
goto rel_buf;
- memcpy_toio(cpu_addr, usbc_pd_fw->data, usbc_pd_fw->size);
+ memcpy_toio_pcie(cpu_addr, usbc_pd_fw->data, usbc_pd_fw->size);
/*
* x86 specific workaround.
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index f8bebf18ee36..4d6843bc84df 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -407,7 +407,7 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
if (in_ras_intr)
memset(adev->uvd.inst[j].saved_bo, 0, size);
else
- memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size);
+ memcpy_fromio_pcie(adev->uvd.inst[j].saved_bo, ptr, size);
}
if (in_ras_intr)
@@ -432,7 +432,7 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
ptr = adev->uvd.inst[i].cpu_addr;
if (adev->uvd.inst[i].saved_bo != NULL) {
- memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size);
+ memcpy_toio_pcie(ptr, adev->uvd.inst[i].saved_bo, size);
kvfree(adev->uvd.inst[i].saved_bo);
adev->uvd.inst[i].saved_bo = NULL;
} else {
@@ -442,12 +442,12 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
- memcpy_toio(adev->uvd.inst[i].cpu_addr, adev->uvd.fw->data + offset,
+ memcpy_toio_pcie(adev->uvd.inst[i].cpu_addr, adev->uvd.fw->data + offset,
le32_to_cpu(hdr->ucode_size_bytes));
size -= le32_to_cpu(hdr->ucode_size_bytes);
ptr += le32_to_cpu(hdr->ucode_size_bytes);
}
- memset_io(ptr, 0, size);
+ memset_io_pcie(ptr, 0, size);
/* to restore uvd fence seq */
amdgpu_fence_driver_force_completion(&adev->uvd.inst[i].ring);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index ecaa2d7483b2..2e120448b13e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -312,7 +312,7 @@ int amdgpu_vce_resume(struct amdgpu_device *adev)
hdr = (const struct common_firmware_header *)adev->vce.fw->data;
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
- memcpy_toio(cpu_addr, adev->vce.fw->data + offset,
+ memcpy_toio_pcie(cpu_addr, adev->vce.fw->data + offset,
adev->vce.fw->size - offset);
amdgpu_bo_kunmap(adev->vce.vcpu_bo);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index a563328e3dae..f616715bbcf4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -271,7 +271,7 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
if (!adev->vcn.inst[i].saved_bo)
return -ENOMEM;
- memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);
+ memcpy_fromio_pcie(adev->vcn.inst[i].saved_bo, ptr, size);
}
return 0;
}
@@ -292,7 +292,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
ptr = adev->vcn.inst[i].cpu_addr;
if (adev->vcn.inst[i].saved_bo != NULL) {
- memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size);
+ memcpy_toio_pcie(ptr, adev->vcn.inst[i].saved_bo, size);
kvfree(adev->vcn.inst[i].saved_bo);
adev->vcn.inst[i].saved_bo = NULL;
} else {
@@ -302,12 +302,12 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
- memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset,
+ memcpy_toio_pcie(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset,
le32_to_cpu(hdr->ucode_size_bytes));
size -= le32_to_cpu(hdr->ucode_size_bytes);
ptr += le32_to_cpu(hdr->ucode_size_bytes);
}
- memset_io(ptr, 0, size);
+ memset_io_pcie(ptr, 0, size);
}
}
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
index 6c5d9612abcb..9c119136c089 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
@@ -693,7 +693,7 @@ static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
return -ENOMEM;
}
- memcpy_fromio(buf, adev->mman.aper_base_kaddr, sz);
+ memcpy_fromio_pcie(buf, adev->mman.aper_base_kaddr, sz);
ret = psp_v11_0_memory_training_send_msg(psp, PSP_BL__DRAM_LONG_TRAIN);
if (ret) {
DRM_ERROR("Send long training msg failed.\n");
@@ -701,7 +701,7 @@ static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
return ret;
}
- memcpy_toio(adev->mman.aper_base_kaddr, buf, sz);
+ memcpy_toio_pcie(adev->mman.aper_base_kaddr, buf, sz);
adev->nbio.funcs->hdp_flush(adev, NULL);
vfree(buf);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
index 37fa163393fd..2b1842904a93 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
@@ -564,7 +564,7 @@ static int vce_v4_0_suspend(void *handle)
unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo);
void *ptr = adev->vce.cpu_addr;
- memcpy_fromio(adev->vce.saved_bo, ptr, size);
+ memcpy_fromio_pcie(adev->vce.saved_bo, ptr, size);
}
r = vce_v4_0_hw_fini(adev);
@@ -586,7 +586,7 @@ static int vce_v4_0_resume(void *handle)
unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo);
void *ptr = adev->vce.cpu_addr;
- memcpy_toio(ptr, adev->vce.saved_bo, size);
+ memcpy_toio_pcie(ptr, adev->vce.saved_bo, size);
} else {
r = amdgpu_vce_resume(adev);
if (r)
--
2.25.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment