summaryrefslogtreecommitdiff
path: root/drivers/net/ipa
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ipa')
-rw-r--r--drivers/net/ipa/ipa_clock.c117
-rw-r--r--drivers/net/ipa/ipa_data-sc7180.c41
-rw-r--r--drivers/net/ipa/ipa_data-sdm845.c41
-rw-r--r--drivers/net/ipa/ipa_data.h14
4 files changed, 99 insertions, 114 deletions
diff --git a/drivers/net/ipa/ipa_clock.c b/drivers/net/ipa/ipa_clock.c
index fbe42106fc2a..354675a643db 100644
--- a/drivers/net/ipa/ipa_clock.c
+++ b/drivers/net/ipa/ipa_clock.c
@@ -47,13 +47,15 @@ struct ipa_interconnect {
* @count: Clocking reference count
* @mutex: Protects clock enable/disable
* @core: IPA core clock
+ * @interconnect_count: Number of elements in interconnect[]
* @interconnect: Interconnect array
*/
struct ipa_clock {
refcount_t count;
struct mutex mutex; /* protects clock enable/disable */
struct clk *core;
- struct ipa_interconnect interconnect[IPA_INTERCONNECT_COUNT];
+ u32 interconnect_count;
+ struct ipa_interconnect *interconnect;
};
static int ipa_interconnect_init_one(struct device *dev,
@@ -90,31 +92,29 @@ static int ipa_interconnect_init(struct ipa_clock *clock, struct device *dev,
const struct ipa_interconnect_data *data)
{
struct ipa_interconnect *interconnect;
+ u32 count;
int ret;
- interconnect = &clock->interconnect[IPA_INTERCONNECT_MEMORY];
- ret = ipa_interconnect_init_one(dev, interconnect, data++);
- if (ret)
- return ret;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ret = ipa_interconnect_init_one(dev, interconnect, data++);
- if (ret)
- goto err_memory_path_put;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ret = ipa_interconnect_init_one(dev, interconnect, data++);
- if (ret)
- goto err_imem_path_put;
+ count = clock->interconnect_count;
+ interconnect = kcalloc(count, sizeof(*interconnect), GFP_KERNEL);
+ if (!interconnect)
+ return -ENOMEM;
+ clock->interconnect = interconnect;
+
+ while (count--) {
+ ret = ipa_interconnect_init_one(dev, interconnect, data++);
+ if (ret)
+ goto out_unwind;
+ interconnect++;
+ }
return 0;
-err_imem_path_put:
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ipa_interconnect_exit_one(interconnect);
-err_memory_path_put:
- interconnect = &clock->interconnect[IPA_INTERCONNECT_MEMORY];
- ipa_interconnect_exit_one(interconnect);
+out_unwind:
+ while (interconnect-- > clock->interconnect)
+ ipa_interconnect_exit_one(interconnect);
+ kfree(clock->interconnect);
+ clock->interconnect = NULL;
return ret;
}
@@ -124,12 +124,11 @@ static void ipa_interconnect_exit(struct ipa_clock *clock)
{
struct ipa_interconnect *interconnect;
- interconnect = &clock->interconnect[IPA_INTERCONNECT_CONFIG];
- ipa_interconnect_exit_one(interconnect);
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ipa_interconnect_exit_one(interconnect);
- interconnect = &clock->interconnect[IPA_INTERCONNECT_MEMORY];
- ipa_interconnect_exit_one(interconnect);
+ interconnect = clock->interconnect + clock->interconnect_count;
+ while (interconnect-- > clock->interconnect)
+ ipa_interconnect_exit_one(interconnect);
+ kfree(clock->interconnect);
+ clock->interconnect = NULL;
}
/* Currently we only use one bandwidth level, so just "enable" interconnects */
@@ -138,33 +137,23 @@ static int ipa_interconnect_enable(struct ipa *ipa)
struct ipa_interconnect *interconnect;
struct ipa_clock *clock = ipa->clock;
int ret;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_MEMORY];
- ret = icc_set_bw(interconnect->path, interconnect->average_bandwidth,
- interconnect->peak_bandwidth);
- if (ret)
- return ret;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ret = icc_set_bw(interconnect->path, interconnect->average_bandwidth,
- interconnect->peak_bandwidth);
- if (ret)
- goto err_memory_path_disable;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_CONFIG];
- ret = icc_set_bw(interconnect->path, interconnect->average_bandwidth,
- interconnect->peak_bandwidth);
- if (ret)
- goto err_imem_path_disable;
+ u32 i;
+
+ interconnect = clock->interconnect;
+ for (i = 0; i < clock->interconnect_count; i++) {
+ ret = icc_set_bw(interconnect->path,
+ interconnect->average_bandwidth,
+ interconnect->peak_bandwidth);
+ if (ret)
+ goto out_unwind;
+ interconnect++;
+ }
return 0;
-err_imem_path_disable:
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- (void)icc_set_bw(interconnect->path, 0, 0);
-err_memory_path_disable:
- interconnect = &clock->interconnect[IPA_INTERCONNECT_MEMORY];
- (void)icc_set_bw(interconnect->path, 0, 0);
+out_unwind:
+ while (interconnect-- > clock->interconnect)
+ (void)icc_set_bw(interconnect->path, 0, 0);
return ret;
}
@@ -175,22 +164,17 @@ static void ipa_interconnect_disable(struct ipa *ipa)
struct ipa_interconnect *interconnect;
struct ipa_clock *clock = ipa->clock;
int result = 0;
+ u32 count;
int ret;
- interconnect = &clock->interconnect[IPA_INTERCONNECT_MEMORY];
- ret = icc_set_bw(interconnect->path, 0, 0);
- if (ret)
- result = ret;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ret = icc_set_bw(interconnect->path, 0, 0);
- if (ret && !result)
- result = ret;
-
- interconnect = &clock->interconnect[IPA_INTERCONNECT_IMEM];
- ret = icc_set_bw(interconnect->path, 0, 0);
- if (ret && !result)
- result = ret;
+ count = clock->interconnect_count;
+ interconnect = clock->interconnect + count;
+ while (count--) {
+ interconnect--;
+ ret = icc_set_bw(interconnect->path, 0, 0);
+ if (ret && !result)
+ result = ret;
+ }
if (result)
dev_err(&ipa->pdev->dev,
@@ -314,8 +298,9 @@ ipa_clock_init(struct device *dev, const struct ipa_clock_data *data)
goto err_clk_put;
}
clock->core = clk;
+ clock->interconnect_count = data->interconnect_count;
- ret = ipa_interconnect_init(clock, dev, data->interconnect);
+ ret = ipa_interconnect_init(clock, dev, data->interconnect_data);
if (ret)
goto err_kfree;
diff --git a/drivers/net/ipa/ipa_data-sc7180.c b/drivers/net/ipa/ipa_data-sc7180.c
index 1936ecb4c110..997b51ceb7d7 100644
--- a/drivers/net/ipa/ipa_data-sc7180.c
+++ b/drivers/net/ipa/ipa_data-sc7180.c
@@ -309,27 +309,30 @@ static struct ipa_mem_data ipa_mem_data = {
.smem_size = 0x00002000,
};
+/* Interconnect bandwidths are in 1000 byte/second units */
+static struct ipa_interconnect_data ipa_interconnect_data[] = {
+ {
+ .name = "memory",
+ .peak_bandwidth = 465000, /* 465 MBps */
+ .average_bandwidth = 80000, /* 80 MBps */
+ },
+ /* Average bandwidth is unused for the next two interconnects */
+ {
+ .name = "imem",
+ .peak_bandwidth = 68570, /* 68.570 MBps */
+ .average_bandwidth = 0, /* unused */
+ },
+ {
+ .name = "config",
+ .peak_bandwidth = 30000, /* 30 MBps */
+ .average_bandwidth = 0, /* unused */
+ },
+};
+
static struct ipa_clock_data ipa_clock_data = {
.core_clock_rate = 100 * 1000 * 1000, /* Hz */
- /* Interconnect bandwidths are in 1000 byte/second units */
- .interconnect = {
- [IPA_INTERCONNECT_MEMORY] = {
- .name = "memory",
- .peak_bandwidth = 465000, /* 465 MBps */
- .average_bandwidth = 80000, /* 80 MBps */
- },
- /* Average bandwidth unused for the next two interconnects */
- [IPA_INTERCONNECT_IMEM] = {
- .name = "imem",
- .peak_bandwidth = 68570, /* 68.57 MBps */
- .average_bandwidth = 0, /* unused */
- },
- [IPA_INTERCONNECT_CONFIG] = {
- .name = "config",
- .peak_bandwidth = 30000, /* 30 MBps */
- .average_bandwidth = 0, /* unused */
- },
- },
+ .interconnect_count = ARRAY_SIZE(ipa_interconnect_data),
+ .interconnect_data = ipa_interconnect_data,
};
/* Configuration data for the SC7180 SoC. */
diff --git a/drivers/net/ipa/ipa_data-sdm845.c b/drivers/net/ipa/ipa_data-sdm845.c
index 3b556b5a6340..88c9c3562ab7 100644
--- a/drivers/net/ipa/ipa_data-sdm845.c
+++ b/drivers/net/ipa/ipa_data-sdm845.c
@@ -329,27 +329,30 @@ static struct ipa_mem_data ipa_mem_data = {
.smem_size = 0x00002000,
};
+/* Interconnect bandwidths are in 1000 byte/second units */
+static struct ipa_interconnect_data ipa_interconnect_data[] = {
+ {
+ .name = "memory",
+ .peak_bandwidth = 600000, /* 600 MBps */
+ .average_bandwidth = 80000, /* 80 MBps */
+ },
+ /* Average bandwidth is unused for the next two interconnects */
+ {
+ .name = "imem",
+ .peak_bandwidth = 350000, /* 350 MBps */
+ .average_bandwidth = 0, /* unused */
+ },
+ {
+ .name = "config",
+ .peak_bandwidth = 40000, /* 40 MBps */
+ .average_bandwidth = 0, /* unused */
+ },
+};
+
static struct ipa_clock_data ipa_clock_data = {
.core_clock_rate = 75 * 1000 * 1000, /* Hz */
- /* Interconnect bandwidths are in 1000 byte/second units */
- .interconnect = {
- [IPA_INTERCONNECT_MEMORY] = {
- .name = "memory",
- .peak_bandwidth = 600000, /* 600 MBps */
- .average_bandwidth = 80000, /* 80 MBps */
- },
- /* Average bandwidth unused for the next two interconnects */
- [IPA_INTERCONNECT_IMEM] = {
- .name = "imem",
- .peak_bandwidth = 350000, /* 350 MBps */
- .average_bandwidth = 0, /* unused */
- },
- [IPA_INTERCONNECT_CONFIG] = {
- .name = "config",
- .peak_bandwidth = 40000, /* 40 MBps */
- .average_bandwidth = 0, /* unused */
- },
- },
+ .interconnect_count = ARRAY_SIZE(ipa_interconnect_data),
+ .interconnect_data = ipa_interconnect_data,
};
/* Configuration data for the SDM845 SoC. */
diff --git a/drivers/net/ipa/ipa_data.h b/drivers/net/ipa/ipa_data.h
index d8ea6266dc6a..b476fc373f7f 100644
--- a/drivers/net/ipa/ipa_data.h
+++ b/drivers/net/ipa/ipa_data.h
@@ -258,14 +258,6 @@ struct ipa_mem_data {
u32 smem_size;
};
-/** enum ipa_interconnect_id - IPA interconnect identifier */
-enum ipa_interconnect_id {
- IPA_INTERCONNECT_MEMORY,
- IPA_INTERCONNECT_IMEM,
- IPA_INTERCONNECT_CONFIG,
- IPA_INTERCONNECT_COUNT, /* Last; not an interconnect */
-};
-
/**
* struct ipa_interconnect_data - description of IPA interconnect bandwidths
* @name: Interconnect name (matches interconnect-name in DT)
@@ -281,11 +273,13 @@ struct ipa_interconnect_data {
/**
* struct ipa_clock_data - description of IPA clock and interconnect rates
* @core_clock_rate: Core clock rate (Hz)
- * @interconnect: Array of interconnect bandwidth parameters
+ * @interconnect_count: Number of entries in the interconnect_data array
+ * @interconnect_data: IPA interconnect configuration data
*/
struct ipa_clock_data {
u32 core_clock_rate;
- struct ipa_interconnect_data interconnect[IPA_INTERCONNECT_COUNT];
+ u32 interconnect_count; /* # entries in interconnect_data[] */
+ const struct ipa_interconnect_data *interconnect_data;
};
/**