diff options
Diffstat (limited to 'drivers/soc/apple/sart.c')
-rw-r--r-- | drivers/soc/apple/sart.c | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/drivers/soc/apple/sart.c b/drivers/soc/apple/sart.c index afa111736899..4ff1942b82a7 100644 --- a/drivers/soc/apple/sart.c +++ b/drivers/soc/apple/sart.c @@ -25,8 +25,17 @@ #define APPLE_SART_MAX_ENTRIES 16 -/* This is probably a bitfield but the exact meaning of each bit is unknown. */ -#define APPLE_SART_FLAGS_ALLOW 0xff +/* SARTv0 registers */ +#define APPLE_SART0_CONFIG(idx) (0x00 + 4 * (idx)) +#define APPLE_SART0_CONFIG_FLAGS GENMASK(28, 24) +#define APPLE_SART0_CONFIG_SIZE GENMASK(18, 0) +#define APPLE_SART0_CONFIG_SIZE_SHIFT 12 +#define APPLE_SART0_CONFIG_SIZE_MAX GENMASK(18, 0) + +#define APPLE_SART0_PADDR(idx) (0x40 + 4 * (idx)) +#define APPLE_SART0_PADDR_SHIFT 12 + +#define APPLE_SART0_FLAGS_ALLOW 0xf /* SARTv2 registers */ #define APPLE_SART2_CONFIG(idx) (0x00 + 4 * (idx)) @@ -38,6 +47,8 @@ #define APPLE_SART2_PADDR(idx) (0x40 + 4 * (idx)) #define APPLE_SART2_PADDR_SHIFT 12 +#define APPLE_SART2_FLAGS_ALLOW 0xff + /* SARTv3 registers */ #define APPLE_SART3_CONFIG(idx) (0x00 + 4 * (idx)) @@ -48,11 +59,15 @@ #define APPLE_SART3_SIZE_SHIFT 12 #define APPLE_SART3_SIZE_MAX GENMASK(29, 0) +#define APPLE_SART3_FLAGS_ALLOW 0xff + struct apple_sart_ops { void (*get_entry)(struct apple_sart *sart, int index, u8 *flags, phys_addr_t *paddr, size_t *size); void (*set_entry)(struct apple_sart *sart, int index, u8 flags, phys_addr_t paddr_shifted, size_t size_shifted); + /* This is probably a bitfield but the exact meaning of each bit is unknown. */ + unsigned int flags_allow; unsigned int size_shift; unsigned int paddr_shift; size_t size_max; @@ -68,6 +83,39 @@ struct apple_sart { unsigned long used_entries; }; +static void sart0_get_entry(struct apple_sart *sart, int index, u8 *flags, + phys_addr_t *paddr, size_t *size) +{ + u32 cfg = readl(sart->regs + APPLE_SART0_CONFIG(index)); + phys_addr_t paddr_ = readl(sart->regs + APPLE_SART0_PADDR(index)); + size_t size_ = FIELD_GET(APPLE_SART0_CONFIG_SIZE, cfg); + + *flags = FIELD_GET(APPLE_SART0_CONFIG_FLAGS, cfg); + *size = size_ << APPLE_SART0_CONFIG_SIZE_SHIFT; + *paddr = paddr_ << APPLE_SART0_PADDR_SHIFT; +} + +static void sart0_set_entry(struct apple_sart *sart, int index, u8 flags, + phys_addr_t paddr_shifted, size_t size_shifted) +{ + u32 cfg; + + cfg = FIELD_PREP(APPLE_SART0_CONFIG_FLAGS, flags); + cfg |= FIELD_PREP(APPLE_SART0_CONFIG_SIZE, size_shifted); + + writel(paddr_shifted, sart->regs + APPLE_SART0_PADDR(index)); + writel(cfg, sart->regs + APPLE_SART0_CONFIG(index)); +} + +static struct apple_sart_ops sart_ops_v0 = { + .get_entry = sart0_get_entry, + .set_entry = sart0_set_entry, + .flags_allow = APPLE_SART0_FLAGS_ALLOW, + .size_shift = APPLE_SART0_CONFIG_SIZE_SHIFT, + .paddr_shift = APPLE_SART0_PADDR_SHIFT, + .size_max = APPLE_SART0_CONFIG_SIZE_MAX, +}; + static void sart2_get_entry(struct apple_sart *sart, int index, u8 *flags, phys_addr_t *paddr, size_t *size) { @@ -95,6 +143,7 @@ static void sart2_set_entry(struct apple_sart *sart, int index, u8 flags, static struct apple_sart_ops sart_ops_v2 = { .get_entry = sart2_get_entry, .set_entry = sart2_set_entry, + .flags_allow = APPLE_SART2_FLAGS_ALLOW, .size_shift = APPLE_SART2_CONFIG_SIZE_SHIFT, .paddr_shift = APPLE_SART2_PADDR_SHIFT, .size_max = APPLE_SART2_CONFIG_SIZE_MAX, @@ -122,6 +171,7 @@ static void sart3_set_entry(struct apple_sart *sart, int index, u8 flags, static struct apple_sart_ops sart_ops_v3 = { .get_entry = sart3_get_entry, .set_entry = sart3_set_entry, + .flags_allow = APPLE_SART3_FLAGS_ALLOW, .size_shift = APPLE_SART3_SIZE_SHIFT, .paddr_shift = APPLE_SART3_PADDR_SHIFT, .size_max = APPLE_SART3_SIZE_MAX, @@ -233,7 +283,7 @@ int apple_sart_add_allowed_region(struct apple_sart *sart, phys_addr_t paddr, if (test_and_set_bit(i, &sart->used_entries)) continue; - ret = sart_set_entry(sart, i, APPLE_SART_FLAGS_ALLOW, paddr, + ret = sart_set_entry(sart, i, sart->ops->flags_allow, paddr, size); if (ret) { dev_dbg(sart->dev, @@ -314,6 +364,10 @@ static const struct of_device_id apple_sart_of_match[] = { .compatible = "apple,t8103-sart", .data = &sart_ops_v2, }, + { + .compatible = "apple,t8015-sart", + .data = &sart_ops_v0, + }, {} }; MODULE_DEVICE_TABLE(of, apple_sart_of_match); |