memory: tegra: Add API for retrieving carveout bounds
authorMikko Perttunen <mperttunen@nvidia.com>
Tue, 20 Sep 2022 08:11:56 +0000 (11:11 +0300)
committerThierry Reding <treding@nvidia.com>
Fri, 25 Nov 2022 15:14:58 +0000 (16:14 +0100)
On Tegra234 NVDEC firmware is loaded from a secure carveout, where it
has been loaded by a bootloader. When booting NVDEC, we need to tell it
the address of this firmware, which we can determine by checking the
starting address of the carveout. As such, add an MC API to query the
bounds of carveouts, and add related information on Tegra234.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/memory/tegra/mc.c
drivers/memory/tegra/tegra234.c
include/soc/tegra/mc.h

index 2f7a58a9df1aec3e6912aec8c9b7335e5fe1ab52..592907546ee64a7acc48e65980ecb8e695f24bf4 100644 (file)
@@ -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)
 {
index a9e8fd99730fa990fdcace2fff19fe8f76ed4681..74d291d66366bf924cacdd7591a375d5262e9a94 100644 (file)
@@ -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,
 };
index 47ce6d4344273231057c9bf192027bdbd7ef625c..51a2263e1bc59d2b2fd5cc42b2279800b09fbb0d 100644 (file)
@@ -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__ */