mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-15 15:15:47 +00:00
iommu: dart: Support a variable number of TTBRs per stream
T8110 only has one TTBR per stream, so un-hardcode that. Reviewed-by: Sven Peter <sven@svenpeter.dev> Signed-off-by: Hector Martin <marcan@marcan.st> Link: https://lore.kernel.org/r/20230113105029.26654-5-marcan@marcan.st Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
510d4072df
commit
0b459bcdc5
1 changed files with 19 additions and 9 deletions
|
@ -77,15 +77,21 @@
|
||||||
#define DART_TCR_BYPASS0_ENABLE BIT(8)
|
#define DART_TCR_BYPASS0_ENABLE BIT(8)
|
||||||
#define DART_TCR_BYPASS1_ENABLE BIT(12)
|
#define DART_TCR_BYPASS1_ENABLE BIT(12)
|
||||||
|
|
||||||
#define DART_TTBR(sid, idx) (0x200 + 16 * (sid) + 4 * (idx))
|
|
||||||
#define DART_TTBR_VALID BIT(31)
|
#define DART_TTBR_VALID BIT(31)
|
||||||
#define DART_TTBR_SHIFT 12
|
#define DART_TTBR_SHIFT 12
|
||||||
|
|
||||||
|
#define DART_TTBR(dart, sid, idx) (0x200 + \
|
||||||
|
(((dart)->hw->ttbr_count * (sid)) << 2) + \
|
||||||
|
((idx) << 2))
|
||||||
|
|
||||||
|
|
||||||
struct apple_dart_hw {
|
struct apple_dart_hw {
|
||||||
u32 oas;
|
u32 oas;
|
||||||
enum io_pgtable_fmt fmt;
|
enum io_pgtable_fmt fmt;
|
||||||
|
|
||||||
int max_sid_count;
|
int max_sid_count;
|
||||||
|
|
||||||
|
int ttbr_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -245,7 +251,7 @@ static void apple_dart_hw_set_ttbr(struct apple_dart_stream_map *stream_map,
|
||||||
WARN_ON(paddr & ((1 << DART_TTBR_SHIFT) - 1));
|
WARN_ON(paddr & ((1 << DART_TTBR_SHIFT) - 1));
|
||||||
for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||||
writel(DART_TTBR_VALID | (paddr >> DART_TTBR_SHIFT),
|
writel(DART_TTBR_VALID | (paddr >> DART_TTBR_SHIFT),
|
||||||
dart->regs + DART_TTBR(sid, idx));
|
dart->regs + DART_TTBR(dart, sid, idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apple_dart_hw_clear_ttbr(struct apple_dart_stream_map *stream_map,
|
static void apple_dart_hw_clear_ttbr(struct apple_dart_stream_map *stream_map,
|
||||||
|
@ -255,7 +261,7 @@ static void apple_dart_hw_clear_ttbr(struct apple_dart_stream_map *stream_map,
|
||||||
int sid;
|
int sid;
|
||||||
|
|
||||||
for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
|
||||||
writel(0, dart->regs + DART_TTBR(sid, idx));
|
writel(0, dart->regs + DART_TTBR(dart, sid, idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -263,7 +269,7 @@ apple_dart_hw_clear_all_ttbrs(struct apple_dart_stream_map *stream_map)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < DART_MAX_TTBR; ++i)
|
for (i = 0; i < stream_map->dart->hw->ttbr_count; ++i)
|
||||||
apple_dart_hw_clear_ttbr(stream_map, i);
|
apple_dart_hw_clear_ttbr(stream_map, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +421,7 @@ apple_dart_setup_translation(struct apple_dart_domain *domain,
|
||||||
for (i = 0; i < pgtbl_cfg->apple_dart_cfg.n_ttbrs; ++i)
|
for (i = 0; i < pgtbl_cfg->apple_dart_cfg.n_ttbrs; ++i)
|
||||||
apple_dart_hw_set_ttbr(stream_map, i,
|
apple_dart_hw_set_ttbr(stream_map, i,
|
||||||
pgtbl_cfg->apple_dart_cfg.ttbr[i]);
|
pgtbl_cfg->apple_dart_cfg.ttbr[i]);
|
||||||
for (; i < DART_MAX_TTBR; ++i)
|
for (; i < stream_map->dart->hw->ttbr_count; ++i)
|
||||||
apple_dart_hw_clear_ttbr(stream_map, i);
|
apple_dart_hw_clear_ttbr(stream_map, i);
|
||||||
|
|
||||||
apple_dart_hw_enable_translation(stream_map);
|
apple_dart_hw_enable_translation(stream_map);
|
||||||
|
@ -956,11 +962,15 @@ static const struct apple_dart_hw apple_dart_hw_t8103 = {
|
||||||
.oas = 36,
|
.oas = 36,
|
||||||
.fmt = APPLE_DART,
|
.fmt = APPLE_DART,
|
||||||
.max_sid_count = 16,
|
.max_sid_count = 16,
|
||||||
|
|
||||||
|
.ttbr_count = 4,
|
||||||
};
|
};
|
||||||
static const struct apple_dart_hw apple_dart_hw_t6000 = {
|
static const struct apple_dart_hw apple_dart_hw_t6000 = {
|
||||||
.oas = 42,
|
.oas = 42,
|
||||||
.fmt = APPLE_DART2,
|
.fmt = APPLE_DART2,
|
||||||
.max_sid_count = 16,
|
.max_sid_count = 16,
|
||||||
|
|
||||||
|
.ttbr_count = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
static __maybe_unused int apple_dart_suspend(struct device *dev)
|
static __maybe_unused int apple_dart_suspend(struct device *dev)
|
||||||
|
@ -970,9 +980,9 @@ static __maybe_unused int apple_dart_suspend(struct device *dev)
|
||||||
|
|
||||||
for (sid = 0; sid < dart->num_streams; sid++) {
|
for (sid = 0; sid < dart->num_streams; sid++) {
|
||||||
dart->save_tcr[sid] = readl_relaxed(dart->regs + DART_TCR(sid));
|
dart->save_tcr[sid] = readl_relaxed(dart->regs + DART_TCR(sid));
|
||||||
for (idx = 0; idx < DART_MAX_TTBR; idx++)
|
for (idx = 0; idx < dart->hw->ttbr_count; idx++)
|
||||||
dart->save_ttbr[sid][idx] =
|
dart->save_ttbr[sid][idx] =
|
||||||
readl(dart->regs + DART_TTBR(sid, idx));
|
readl(dart->regs + DART_TTBR(dart, sid, idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -991,9 +1001,9 @@ static __maybe_unused int apple_dart_resume(struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (sid = 0; sid < dart->num_streams; sid++) {
|
for (sid = 0; sid < dart->num_streams; sid++) {
|
||||||
for (idx = 0; idx < DART_MAX_TTBR; idx++)
|
for (idx = 0; idx < dart->hw->ttbr_count; idx++)
|
||||||
writel(dart->save_ttbr[sid][idx],
|
writel(dart->save_ttbr[sid][idx],
|
||||||
dart->regs + DART_TTBR(sid, idx));
|
dart->regs + DART_TTBR(dart, sid, idx));
|
||||||
writel(dart->save_tcr[sid], dart->regs + DART_TCR(sid));
|
writel(dart->save_tcr[sid], dart->regs + DART_TCR(sid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue