#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <asm/cacheflush.h>
+
#include <soc/tegra/ahb.h>
#include <soc/tegra/mc.h>
return (iova >> SMMU_PTE_SHIFT) & (SMMU_NUM_PTE - 1);
}
+static void smmu_flush_dcache(struct page *page, unsigned long offset,
+ size_t size)
+{
+#ifdef CONFIG_ARM
+ phys_addr_t phys = page_to_phys(page) + offset;
+#endif
+ void *virt = page_address(page) + offset;
+
+#ifdef CONFIG_ARM
+ __cpuc_flush_dcache_area(virt, size);
+ outer_flush_range(phys, phys + size);
+#endif
+
+#ifdef CONFIG_ARM64
+ __flush_dcache_area(virt, size);
+#endif
+}
+
static inline void smmu_flush_ptc(struct tegra_smmu *smmu, struct page *page,
unsigned long offset)
{
if (err < 0)
return err;
- smmu->soc->ops->flush_dcache(as->pd, 0, SMMU_SIZE_PD);
+ smmu_flush_dcache(as->pd, 0, SMMU_SIZE_PD);
smmu_flush_ptc(smmu, as->pd, 0);
smmu_flush_tlb_asid(smmu, as->id);
as->pts[pde] = page;
- smmu->soc->ops->flush_dcache(page, 0, SMMU_SIZE_PT);
+ smmu_flush_dcache(page, 0, SMMU_SIZE_PT);
pd[pde] = SMMU_MK_PDE(page, SMMU_PDE_ATTR | SMMU_PDE_NEXT);
- smmu->soc->ops->flush_dcache(as->pd, pde << 2, 4);
+ smmu_flush_dcache(as->pd, pde << 2, 4);
smmu_flush_ptc(smmu, as->pd, pde << 2);
smmu_flush_tlb_section(smmu, as->id, iova);
smmu_flush(smmu);
pd[pde] = 0;
/* Flush the page directory entry */
- smmu->soc->ops->flush_dcache(as->pd, offset, sizeof(*pd));
+ smmu_flush_dcache(as->pd, offset, sizeof(*pd));
smmu_flush_ptc(smmu, as->pd, offset);
smmu_flush_tlb_section(smmu, as->id, iova);
smmu_flush(smmu);
*pte = val;
- smmu->soc->ops->flush_dcache(pte_page, offset, 4);
+ smmu_flush_dcache(pte_page, offset, 4);
smmu_flush_ptc(smmu, pte_page, offset);
smmu_flush_tlb_group(smmu, as->id, iova);
smmu_flush(smmu);
#include <linux/of.h>
#include <linux/mm.h>
-#include <asm/cacheflush.h>
-
#include <dt-bindings/memory/tegra114-mc.h>
#include "mc.h"
{ .name = "tsec", .swgroup = TEGRA_SWGROUP_TSEC, .reg = 0x294 },
};
-static void tegra114_flush_dcache(struct page *page, unsigned long offset,
- size_t size)
-{
- phys_addr_t phys = page_to_phys(page) + offset;
- void *virt = page_address(page) + offset;
-
- __cpuc_flush_dcache_area(virt, size);
- outer_flush_range(phys, phys + size);
-}
-
-static const struct tegra_smmu_ops tegra114_smmu_ops = {
- .flush_dcache = tegra114_flush_dcache,
-};
-
static const struct tegra_smmu_soc tegra114_smmu_soc = {
.clients = tegra114_mc_clients,
.num_clients = ARRAY_SIZE(tegra114_mc_clients),
.supports_round_robin_arbitration = false,
.supports_request_limit = false,
.num_asids = 4,
- .ops = &tegra114_smmu_ops,
};
const struct tegra_mc_soc tegra114_mc_soc = {
#include <linux/of.h>
#include <linux/mm.h>
-#include <asm/cacheflush.h>
-
#include <dt-bindings/memory/tegra124-mc.h>
#include "mc.h"
};
#ifdef CONFIG_ARCH_TEGRA_124_SOC
-static void tegra124_flush_dcache(struct page *page, unsigned long offset,
- size_t size)
-{
- phys_addr_t phys = page_to_phys(page) + offset;
- void *virt = page_address(page) + offset;
-
- __cpuc_flush_dcache_area(virt, size);
- outer_flush_range(phys, phys + size);
-}
-
-static const struct tegra_smmu_ops tegra124_smmu_ops = {
- .flush_dcache = tegra124_flush_dcache,
-};
-
static const struct tegra_smmu_soc tegra124_smmu_soc = {
.clients = tegra124_mc_clients,
.num_clients = ARRAY_SIZE(tegra124_mc_clients),
.supports_round_robin_arbitration = true,
.supports_request_limit = true,
.num_asids = 128,
- .ops = &tegra124_smmu_ops,
};
const struct tegra_mc_soc tegra124_mc_soc = {
#endif /* CONFIG_ARCH_TEGRA_124_SOC */
#ifdef CONFIG_ARCH_TEGRA_132_SOC
-static void tegra132_flush_dcache(struct page *page, unsigned long offset,
- size_t size)
-{
- void *virt = page_address(page) + offset;
-
- __flush_dcache_area(virt, size);
-}
-
-static const struct tegra_smmu_ops tegra132_smmu_ops = {
- .flush_dcache = tegra132_flush_dcache,
-};
-
static const struct tegra_smmu_soc tegra132_smmu_soc = {
.clients = tegra124_mc_clients,
.num_clients = ARRAY_SIZE(tegra124_mc_clients),
.supports_round_robin_arbitration = true,
.supports_request_limit = true,
.num_asids = 128,
- .ops = &tegra132_smmu_ops,
};
const struct tegra_mc_soc tegra132_mc_soc = {
#include <linux/of.h>
#include <linux/mm.h>
-#include <asm/cacheflush.h>
-
#include <dt-bindings/memory/tegra30-mc.h>
#include "mc.h"
{ .name = "isp", .swgroup = TEGRA_SWGROUP_ISP, .reg = 0x258 },
};
-static void tegra30_flush_dcache(struct page *page, unsigned long offset,
- size_t size)
-{
- phys_addr_t phys = page_to_phys(page) + offset;
- void *virt = page_address(page) + offset;
-
- __cpuc_flush_dcache_area(virt, size);
- outer_flush_range(phys, phys + size);
-}
-
-static const struct tegra_smmu_ops tegra30_smmu_ops = {
- .flush_dcache = tegra30_flush_dcache,
-};
-
static const struct tegra_smmu_soc tegra30_smmu_soc = {
.clients = tegra30_mc_clients,
.num_clients = ARRAY_SIZE(tegra30_mc_clients),
.supports_round_robin_arbitration = false,
.supports_request_limit = false,
.num_asids = 4,
- .ops = &tegra30_smmu_ops,
};
const struct tegra_mc_soc tegra30_mc_soc = {
unsigned int reg;
};
-struct tegra_smmu_ops {
- void (*flush_dcache)(struct page *page, unsigned long offset,
- size_t size);
-};
-
struct tegra_smmu_soc {
const struct tegra_mc_client *clients;
unsigned int num_clients;
bool supports_request_limit;
unsigned int num_asids;
-
- const struct tegra_smmu_ops *ops;
};
struct tegra_mc;