@@ -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)
{
@@ -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,
};
@@ -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__ */