forked from Minki/linux
iommu/tegra-smmu: Move flush_dcache to tegra-smmu.c
Drivers should not be using __cpuc_* functions nor outer_cache_flush() directly. This change partly cleans up tegra-smmu.c. The only difference between cache handling of the tegra variants is Denver, which omits the call to outer_cache_flush(). This is due to Denver being an ARM64 CPU, and the ARM64 architecture does not provide this function. (This, in itself, is a good reason why these should not be used.) Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> [treding@nvidia.com: fix build failure on 64-bit ARM] Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
32924c76b0
commit
4b3c7d1076
@ -16,6 +16,8 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include <soc/tegra/ahb.h>
|
||||
#include <soc/tegra/mc.h>
|
||||
|
||||
@ -145,6 +147,24 @@ static unsigned int iova_pt_index(unsigned long iova)
|
||||
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)
|
||||
{
|
||||
@ -392,7 +412,7 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
|
||||
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);
|
||||
|
||||
@ -521,11 +541,11 @@ static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova,
|
||||
|
||||
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);
|
||||
@ -562,7 +582,7 @@ static void tegra_smmu_pte_put_use(struct tegra_smmu_as *as, unsigned long iova)
|
||||
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);
|
||||
@ -582,7 +602,7 @@ static void tegra_smmu_set_pte(struct tegra_smmu_as *as, unsigned long iova,
|
||||
|
||||
*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);
|
||||
|
@ -9,8 +9,6 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include <dt-bindings/memory/tegra114-mc.h>
|
||||
|
||||
#include "mc.h"
|
||||
@ -914,20 +912,6 @@ static const struct tegra_smmu_swgroup tegra114_swgroups[] = {
|
||||
{ .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),
|
||||
@ -936,7 +920,6 @@ static const struct tegra_smmu_soc tegra114_smmu_soc = {
|
||||
.supports_round_robin_arbitration = false,
|
||||
.supports_request_limit = false,
|
||||
.num_asids = 4,
|
||||
.ops = &tegra114_smmu_ops,
|
||||
};
|
||||
|
||||
const struct tegra_mc_soc tegra114_mc_soc = {
|
||||
|
@ -9,8 +9,6 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include <dt-bindings/memory/tegra124-mc.h>
|
||||
|
||||
#include "mc.h"
|
||||
@ -1002,20 +1000,6 @@ static const struct tegra_smmu_swgroup tegra124_swgroups[] = {
|
||||
};
|
||||
|
||||
#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),
|
||||
@ -1024,7 +1008,6 @@ static const struct tegra_smmu_soc tegra124_smmu_soc = {
|
||||
.supports_round_robin_arbitration = true,
|
||||
.supports_request_limit = true,
|
||||
.num_asids = 128,
|
||||
.ops = &tegra124_smmu_ops,
|
||||
};
|
||||
|
||||
const struct tegra_mc_soc tegra124_mc_soc = {
|
||||
@ -1039,18 +1022,6 @@ 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),
|
||||
@ -1059,7 +1030,6 @@ static const struct tegra_smmu_soc tegra132_smmu_soc = {
|
||||
.supports_round_robin_arbitration = true,
|
||||
.supports_request_limit = true,
|
||||
.num_asids = 128,
|
||||
.ops = &tegra132_smmu_ops,
|
||||
};
|
||||
|
||||
const struct tegra_mc_soc tegra132_mc_soc = {
|
||||
|
@ -9,8 +9,6 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include <dt-bindings/memory/tegra30-mc.h>
|
||||
|
||||
#include "mc.h"
|
||||
@ -936,20 +934,6 @@ static const struct tegra_smmu_swgroup tegra30_swgroups[] = {
|
||||
{ .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),
|
||||
@ -958,7 +942,6 @@ static const struct tegra_smmu_soc tegra30_smmu_soc = {
|
||||
.supports_round_robin_arbitration = false,
|
||||
.supports_request_limit = false,
|
||||
.num_asids = 4,
|
||||
.ops = &tegra30_smmu_ops,
|
||||
};
|
||||
|
||||
const struct tegra_mc_soc tegra30_mc_soc = {
|
||||
|
@ -51,11 +51,6 @@ struct tegra_smmu_swgroup {
|
||||
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;
|
||||
@ -67,8 +62,6 @@ struct tegra_smmu_soc {
|
||||
bool supports_request_limit;
|
||||
|
||||
unsigned int num_asids;
|
||||
|
||||
const struct tegra_smmu_ops *ops;
|
||||
};
|
||||
|
||||
struct tegra_mc;
|
||||
|
Loading…
Reference in New Issue
Block a user