diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c index 2f7a58a9df1a..592907546ee6 100644 --- a/drivers/memory/tegra/mc.c +++ b/drivers/memory/tegra/mc.c @@ -107,6 +107,31 @@ int tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev) } EXPORT_SYMBOL_GPL(tegra_mc_probe_device); +int tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id, + phys_addr_t *base, u64 *size) +{ + u32 offset; + + if (id < 1 || id >= mc->soc->num_carveouts) + return -EINVAL; + + if (id < 6) + offset = 0xc0c + 0x50 * (id - 1); + else + offset = 0x2004 + 0x50 * (id - 6); + + *base = mc_ch_readl(mc, MC_BROADCAST_CHANNEL, offset + 0x0); +#ifdef CONFIG_PHYS_ADDR_T_64BIT + *base |= (phys_addr_t)mc_ch_readl(mc, MC_BROADCAST_CHANNEL, offset + 0x4) << 32; +#endif + + if (size) + *size = mc_ch_readl(mc, MC_BROADCAST_CHANNEL, offset + 0x8) << 17; + + return 0; +} +EXPORT_SYMBOL_GPL(tegra_mc_get_carveout_info); + static int tegra_mc_block_dma_common(struct tegra_mc *mc, const struct tegra_mc_reset *rst) { diff --git a/drivers/memory/tegra/tegra234.c b/drivers/memory/tegra/tegra234.c index a9e8fd99730f..74d291d66366 100644 --- a/drivers/memory/tegra/tegra234.c +++ b/drivers/memory/tegra/tegra234.c @@ -187,4 +187,9 @@ const struct tegra_mc_soc tegra234_mc_soc = { .ops = &tegra186_mc_ops, .ch_intmask = 0x0000ff00, .global_intstatus_channel_shift = 8, + /* + * Additionally, there are lite carveouts but those are not currently + * supported. + */ + .num_carveouts = 32, }; diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h index 47ce6d434427..51a2263e1bc5 100644 --- a/include/soc/tegra/mc.h +++ b/include/soc/tegra/mc.h @@ -193,6 +193,8 @@ struct tegra_mc_soc { unsigned int num_address_bits; unsigned int atom_size; + unsigned int num_carveouts; + u16 client_id_mask; u8 num_channels; @@ -244,6 +246,8 @@ unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc); #ifdef CONFIG_TEGRA_MC struct tegra_mc *devm_tegra_memory_controller_get(struct device *dev); int tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev); +int tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id, + phys_addr_t *base, u64 *size); #else static inline struct tegra_mc * devm_tegra_memory_controller_get(struct device *dev) @@ -256,6 +260,13 @@ tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev) { return -ENODEV; } + +static inline int +tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id, + phys_addr_t *base, u64 *size) +{ + return -ENODEV; +} #endif #endif /* __SOC_TEGRA_MC_H__ */