@@ -843,6 +843,23 @@ static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
return err;
}
+static void tegra_mc_num_channel_enabled(struct tegra_mc *mc)
+{
+ unsigned int i;
+ u32 value;
+
+ value = mc_ch_readl(mc, 0, MC_EMEM_ADR_CFG_CHANNEL_ENABLE);
+ if (value <= 0) {
+ mc->num_channels = mc->soc->num_channels;
+ return;
+ }
+
+ for (i = 0; i < 32; i++) {
+ if (value & BIT(i))
+ mc->num_channels++;
+ }
+}
+
static int tegra_mc_probe(struct platform_device *pdev)
{
struct tegra_mc *mc;
@@ -881,6 +898,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
return err;
}
+ tegra_mc_num_channel_enabled(mc);
+
if (mc->soc->ops && mc->soc->ops->handle_irq) {
mc->irq = platform_get_irq(pdev, 0);
if (mc->irq < 0)
@@ -53,6 +53,7 @@
#define MC_ERR_ROUTE_SANITY_ADR 0x9c4
#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
+#define MC_EMEM_ADR_CFG_CHANNEL_ENABLE 0xdf8
#define MC_GLOBAL_INTSTATUS 0xf24
#define MC_ERR_ADR_HI 0x11fc
@@ -868,6 +868,25 @@ static int tegra234_mc_icc_set(struct icc_node *src, struct icc_node *dst)
return ret;
}
+static int tegra234_mc_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
+ u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+ struct icc_provider *p = node->provider;
+ struct tegra_mc *mc = icc_provider_to_tegra_mc(p);
+
+ if (node->id == TEGRA_ICC_MC_CPU_CLUSTER0 ||
+ node->id == TEGRA_ICC_MC_CPU_CLUSTER1 ||
+ node->id == TEGRA_ICC_MC_CPU_CLUSTER2) {
+ if (mc)
+ peak_bw = peak_bw * mc->num_channels;
+ }
+
+ *agg_avg += avg_bw;
+ *agg_peak = max(*agg_peak, peak_bw);
+
+ return 0;
+}
+
static struct icc_node*
tegra234_mc_of_icc_xlate(struct of_phandle_args *spec, void *data)
{
@@ -899,7 +918,7 @@ static int tegra234_mc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *pea
static const struct tegra_mc_icc_ops tegra234_mc_icc_ops = {
.xlate = tegra234_mc_of_icc_xlate,
- .aggregate = icc_std_aggregate,
+ .aggregate = tegra234_mc_icc_aggregate,
.get_bw = tegra234_mc_icc_get_init_bw,
.set = tegra234_mc_icc_set,
};
@@ -233,6 +233,7 @@ struct tegra_mc {
struct tegra_mc_timing *timings;
unsigned int num_timings;
+ unsigned int num_channels;
struct reset_controller_dev reset;