-
-
Save Coreforge/2e9fd18dcd26e8194dea9ac4d292c22d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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