summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Yescas <jyescas@google.com>2024-03-05 13:19:55 -0800
committerJuan Yescas <jyescas@google.com>2024-03-15 02:47:31 +0000
commit7a356a435fc98cf9ecc10818b45fc431a52f185f (patch)
treeb6a40db276b349e4b7fb5f6f66b75c5a1961c742
parent69e29ebd6eba10a865f064e201a526ce5e151ecb (diff)
downloadgs-7a356a435fc98cf9ecc10818b45fc431a52f185f.tar.gz
iommu: pcie: Set correct pgtable base for PAGE_SIZE != 4K
The value for the page table base register was calculated under the assumption that the PAGE_SIZE macro is defined as 4kb. This breaks in configurations where PAGE_SIZE is set to 16kb or 64kb. Let's define a new local macro named PT_BASE_SHIFT to use for this calculation. This value is determined by the programming interface of the hardware and is unrelated to the page size that the operating system is using. Bug: 326481268 Bug: 318888819 Bug: 308663811 Test: Build and flash kernel with 4kb and 16kb page sizes Change-Id: I744536c1442d2f6bf0b52272048a1a12acb7bb74 Signed-off-by: Juan Yescas <jyescas@google.com>
-rw-r--r--drivers/iommu/exynos-pcie-iommu.c14
-rw-r--r--drivers/iommu/exynos-pcie-iommu.h4
2 files changed, 8 insertions, 10 deletions
diff --git a/drivers/iommu/exynos-pcie-iommu.c b/drivers/iommu/exynos-pcie-iommu.c
index 189307cd2..2f7126b00 100644
--- a/drivers/iommu/exynos-pcie-iommu.c
+++ b/drivers/iommu/exynos-pcie-iommu.c
@@ -99,9 +99,9 @@ static void __sysmmu_tlb_invalidate_all(void __iomem *sfrbase, int pcie_vid)
}
static void __sysmmu_set_ptbase(void __iomem *sfrbase,
- phys_addr_t pfn_pgtable, int pcie_vid)
+ phys_addr_t pgtable, int pcie_vid)
{
- writel_relaxed(pfn_pgtable, sfrbase + REG_PT_BASE_PPN_VID(pcie_vid));
+ writel_relaxed(pgtable >> PT_BASE_SHIFT, sfrbase + REG_PT_BASE_PPN_VID(pcie_vid));
__sysmmu_tlb_invalidate_all(sfrbase, pcie_vid);
}
@@ -157,7 +157,7 @@ static void __sysmmu_enable_nocount(struct sysmmu_drvdata *drvdata, int pcie_vid
__sysmmu_init_config(drvdata, pcie_vid);
__sysmmu_set_ptbase(drvdata->sfrbase,
- drvdata->pgtable / PAGE_SIZE, pcie_vid);
+ drvdata->pgtable, pcie_vid);
spin_lock(&drvdata->mmu_ctrl_lock);
if (!is_sysmmu_active(drvdata)) {
@@ -683,7 +683,7 @@ void print_pcie_sysmmu_tlb(int hsi_block_num)
pgtable = __raw_readl(g_sysmmu_drvdata[hsi_block_num]->sfrbase +
REG_PT_BASE_PPN_VID(pcie_vid));
- pgtable <<= PAGE_SHIFT;
+ pgtable <<= PT_BASE_SHIFT;
pr_info("Page Table Base Address : 0x%pap\n", &pgtable);
}
EXPORT_SYMBOL(print_pcie_sysmmu_tlb);
@@ -700,7 +700,7 @@ static int show_fault_information(struct sysmmu_drvdata *drvdata, int flags,
int pmmu_id, stream_id;
pgtable = __raw_readl(drvdata->sfrbase + REG_PT_BASE_PPN_VID(pcie_vid));
- pgtable <<= PAGE_SHIFT;
+ pgtable <<= PT_BASE_SHIFT;
info = __raw_readl(drvdata->sfrbase + REG_FAULT_INFO0_VID(pcie_vid));
@@ -739,7 +739,7 @@ static int show_fault_information(struct sysmmu_drvdata *drvdata, int flags,
if (fault_id == SYSMMU_FAULT_PTW_ACCESS)
pr_crit("System MMU has failed to access page table\n");
- if (!pfn_valid(pgtable >> PAGE_SHIFT)) {
+ if (!pfn_valid(PFN_DOWN(pgtable))) {
pr_crit("Page table base is not in a valid memory region\n");
} else {
sysmmu_pte_t *ent;
@@ -1240,7 +1240,7 @@ static inline int check_memory_validation(phys_addr_t paddr)
{
int ret;
- ret = pfn_valid(paddr >> PAGE_SHIFT);
+ ret = pfn_valid(PFN_DOWN(paddr));
if (!ret) {
pr_err("Requested address 0x%pap is NOT in DRAM region!!\n", &paddr);
return -EINVAL;
diff --git a/drivers/iommu/exynos-pcie-iommu.h b/drivers/iommu/exynos-pcie-iommu.h
index 77bd6c4e8..dfb2b5b06 100644
--- a/drivers/iommu/exynos-pcie-iommu.h
+++ b/drivers/iommu/exynos-pcie-iommu.h
@@ -23,9 +23,7 @@
typedef u64 sysmmu_iova_t;
typedef u32 sysmmu_pte_t;
-#define IOVM_NUM_PAGES(vmsize) ((vmsize) / PAGE_SIZE)
-#define IOVM_BITMAP_SIZE(vmsize) \
- ((IOVM_NUM_PAGES(vmsize) + BITS_PER_BYTE) / BITS_PER_BYTE)
+#define PT_BASE_SHIFT 12
#define SECT_ORDER 20
#define LPAGE_ORDER 16