net: ipa: define clock and interconnect data

Define a new type of configuration data, used to initialize the
IPA core clock and interconnects.  This is the first of three
patches, and defines the data types and interface but doesn't
yet use them.

Switch the return value if there is no matching configuration data
to ENODEV instead of ENOTSUPP (to avoid using the nonstandard errno).

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Alex Elder 2020-11-19 16:40:39 -06:00 committed by Jakub Kicinski
parent 0a12ad5929
commit dfccb8b13c
4 changed files with 50 additions and 14 deletions

View File

@ -13,6 +13,7 @@
#include "ipa.h" #include "ipa.h"
#include "ipa_clock.h" #include "ipa_clock.h"
#include "ipa_modem.h" #include "ipa_modem.h"
#include "ipa_data.h"
/** /**
* DOC: IPA Clocking * DOC: IPA Clocking
@ -49,6 +50,7 @@
* @memory_path: Memory interconnect * @memory_path: Memory interconnect
* @imem_path: Internal memory interconnect * @imem_path: Internal memory interconnect
* @config_path: Configuration space interconnect * @config_path: Configuration space interconnect
* @interconnect_data: Interconnect configuration data
*/ */
struct ipa_clock { struct ipa_clock {
refcount_t count; refcount_t count;
@ -57,6 +59,7 @@ struct ipa_clock {
struct icc_path *memory_path; struct icc_path *memory_path;
struct icc_path *imem_path; struct icc_path *imem_path;
struct icc_path *config_path; struct icc_path *config_path;
const struct ipa_interconnect_data *interconnect_data;
}; };
static struct icc_path * static struct icc_path *
@ -257,7 +260,8 @@ u32 ipa_clock_rate(struct ipa *ipa)
} }
/* Initialize IPA clocking */ /* Initialize IPA clocking */
struct ipa_clock *ipa_clock_init(struct device *dev) struct ipa_clock *
ipa_clock_init(struct device *dev, const struct ipa_clock_data *data)
{ {
struct ipa_clock *clock; struct ipa_clock *clock;
struct clk *clk; struct clk *clk;
@ -282,6 +286,7 @@ struct ipa_clock *ipa_clock_init(struct device *dev)
goto err_clk_put; goto err_clk_put;
} }
clock->core = clk; clock->core = clk;
clock->interconnect_data = data->interconnect;
ret = ipa_interconnect_init(clock, dev); ret = ipa_interconnect_init(clock, dev);
if (ret) if (ret)

View File

@ -9,6 +9,7 @@
struct device; struct device;
struct ipa; struct ipa;
struct ipa_clock_data;
/** /**
* ipa_clock_rate() - Return the current IPA core clock rate * ipa_clock_rate() - Return the current IPA core clock rate
@ -21,10 +22,12 @@ u32 ipa_clock_rate(struct ipa *ipa);
/** /**
* ipa_clock_init() - Initialize IPA clocking * ipa_clock_init() - Initialize IPA clocking
* @dev: IPA device * @dev: IPA device
* @data: Clock configuration data
* *
* Return: A pointer to an ipa_clock structure, or a pointer-coded error * Return: A pointer to an ipa_clock structure, or a pointer-coded error
*/ */
struct ipa_clock *ipa_clock_init(struct device *dev); struct ipa_clock *ipa_clock_init(struct device *dev,
const struct ipa_clock_data *data);
/** /**
* ipa_clock_exit() - Inverse of ipa_clock_init() * ipa_clock_exit() - Inverse of ipa_clock_init()

View File

@ -241,7 +241,7 @@ struct ipa_resource_data {
}; };
/** /**
* struct ipa_mem - description of IPA memory regions * struct ipa_mem_data - description of IPA memory regions
* @local_count: number of regions defined in the local[] array * @local_count: number of regions defined in the local[] array
* @local: array of IPA-local memory region descriptors * @local: array of IPA-local memory region descriptors
* @imem_addr: physical address of IPA region within IMEM * @imem_addr: physical address of IPA region within IMEM
@ -258,6 +258,34 @@ struct ipa_mem_data {
u32 smem_size; 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 rates
* @peak_rate: Peak interconnect bandwidth (in 1000 byte/sec units)
* @average_rate: Average interconnect bandwidth (in 1000 byte/sec units)
*/
struct ipa_interconnect_data {
u32 peak_rate;
u32 average_rate;
};
/**
* struct ipa_clock_data - description of IPA clock and interconnect rates
* @core_clock_rate: Core clock rate (Hz)
* @interconnect: Array of interconnect bandwidth parameters
*/
struct ipa_clock_data {
u32 core_clock_rate;
struct ipa_interconnect_data interconnect[IPA_INTERCONNECT_COUNT];
};
/** /**
* struct ipa_data - combined IPA/GSI configuration data * struct ipa_data - combined IPA/GSI configuration data
* @version: IPA hardware version * @version: IPA hardware version
@ -273,6 +301,7 @@ struct ipa_data {
const struct ipa_gsi_endpoint_data *endpoint_data; const struct ipa_gsi_endpoint_data *endpoint_data;
const struct ipa_resource_data *resource_data; const struct ipa_resource_data *resource_data;
const struct ipa_mem_data *mem_data; const struct ipa_mem_data *mem_data;
const struct ipa_clock_data *clock_data;
}; };
extern const struct ipa_data ipa_data_sdm845; extern const struct ipa_data ipa_data_sdm845;

View File

@ -728,6 +728,14 @@ static int ipa_probe(struct platform_device *pdev)
ipa_validate_build(); ipa_validate_build();
/* Get configuration data early; needed for clock initialization */
data = of_device_get_match_data(dev);
if (!data) {
/* This is really IPA_VALIDATE (should never happen) */
dev_err(dev, "matched hardware not supported\n");
return -ENODEV;
}
/* If we need Trust Zone, make sure it's available */ /* If we need Trust Zone, make sure it's available */
modem_init = of_property_read_bool(dev->of_node, "modem-init"); modem_init = of_property_read_bool(dev->of_node, "modem-init");
if (!modem_init) if (!modem_init)
@ -748,22 +756,13 @@ static int ipa_probe(struct platform_device *pdev)
/* The clock and interconnects might not be ready when we're /* The clock and interconnects might not be ready when we're
* probed, so might return -EPROBE_DEFER. * probed, so might return -EPROBE_DEFER.
*/ */
clock = ipa_clock_init(dev); clock = ipa_clock_init(dev, data->clock_data);
if (IS_ERR(clock)) { if (IS_ERR(clock)) {
ret = PTR_ERR(clock); ret = PTR_ERR(clock);
goto err_rproc_put; goto err_rproc_put;
} }
/* No more EPROBE_DEFER. Get our configuration data */ /* No more EPROBE_DEFER. Allocate and initialize the IPA structure */
data = of_device_get_match_data(dev);
if (!data) {
/* This is really IPA_VALIDATE (should never happen) */
dev_err(dev, "matched hardware not supported\n");
ret = -ENOTSUPP;
goto err_clock_exit;
}
/* Allocate and initialize the IPA structure */
ipa = kzalloc(sizeof(*ipa), GFP_KERNEL); ipa = kzalloc(sizeof(*ipa), GFP_KERNEL);
if (!ipa) { if (!ipa) {
ret = -ENOMEM; ret = -ENOMEM;