diff options
author | Stephen Warren <swarren@nvidia.com> | 2016-09-13 10:45:56 -0600 |
---|---|---|
committer | Tom Warren <twarren@nvidia.com> | 2016-09-27 09:11:02 -0700 |
commit | d0ad8a5cbfe8d52339ac5bea3617af21d2fd079a (patch) | |
tree | bd1c2c55ae9bc2b1cde71ec494ef7a910d4b8a07 /arch/arm/mach-tegra/tegra20/clock.c | |
parent | 6dbcc962e48e4f2395806469ba59f19fb18aa64a (diff) | |
download | u-boot-imx-d0ad8a5cbfe8d52339ac5bea3617af21d2fd079a.zip u-boot-imx-d0ad8a5cbfe8d52339ac5bea3617af21d2fd079a.tar.gz u-boot-imx-d0ad8a5cbfe8d52339ac5bea3617af21d2fd079a.tar.bz2 |
ARM: tegra: add APIs the clock uclass driver will need
A future patch will implement a clock uclass driver for Tegra. That driver
will call into Tegra's existing clock code to simplify the transition;
this avoids tieing the clock uclass patches into significant refactoring
of the existing custom clock API implementation.
Some of the Tegra clock APIs that manipulate peripheral clocks require
both the peripheral clock ID and parent clock ID to be passed in together.
However, the clock uclass API does not require any such "parent"
parameter, so the clock driver must determine this information itself.
This patch implements new Tegra- specific clock API
clock_get_periph_parent() for this purpose.
The new API is implemented in the core Tegra clock code rather than SoC-
specific clock code. The implementation uses various SoC-/clock-specific
data. That data is only available in SoC-specific clock code.
Consequently, two new internal APIs are added that enable the core clock
code to retrieve this information from the SoC-specific clock code. Due to
the structure of the Tegra clock code, this leads to some unfortunate code
duplication. However, this situation predates this patch.
Ideally, future work will de-duplicate the Tegra clock code, and migrate
it into drivers/clk/tegra. However, such refactoring is kept separate from
this series.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Tom Warren <twarren@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra20/clock.c')
-rw-r--r-- | arch/arm/mach-tegra/tegra20/clock.c | 76 |
1 files changed, 54 insertions, 22 deletions
diff --git a/arch/arm/mach-tegra/tegra20/clock.c b/arch/arm/mach-tegra/tegra20/clock.c index d11e89b..ec04cf5 100644 --- a/arch/arm/mach-tegra/tegra20/clock.c +++ b/arch/arm/mach-tegra/tegra20/clock.c @@ -413,46 +413,78 @@ u32 *get_periph_source_reg(enum periph_id periph_id) return &clkrst->crc_clk_src[internal_id]; } -/** - * Given a peripheral ID and the required source clock, this returns which - * value should be programmed into the source mux for that peripheral. - * - * There is special code here to handle the one source type with 5 sources. - * - * @param periph_id peripheral to start - * @param source PLL id of required parent clock - * @param mux_bits Set to number of bits in mux register: 2 or 4 - * @param divider_bits Set to number of divider bits (8 or 16) - * @return mux value (0-4, or -1 if not found) - */ -int get_periph_clock_source(enum periph_id periph_id, - enum clock_id parent, int *mux_bits, int *divider_bits) +int get_periph_clock_info(enum periph_id periph_id, int *mux_bits, + int *divider_bits, int *type) { - enum clock_type_id type; enum periphc_internal_id internal_id; - int mux; - assert(clock_periph_id_isvalid(periph_id)); + if (!clock_periph_id_isvalid(periph_id)) + return -1; internal_id = periph_id_to_internal_id[periph_id]; - assert(periphc_internal_id_isvalid(internal_id)); + if (!periphc_internal_id_isvalid(internal_id)) + return -1; - type = clock_periph_type[internal_id]; - assert(clock_type_id_isvalid(type)); + *type = clock_periph_type[internal_id]; + if (!clock_type_id_isvalid(*type)) + return -1; /* * Special cases here for the clock with a 4-bit source mux and I2C * with its 16-bit divisor */ - if (type == CLOCK_TYPE_PCXTS) + if (*type == CLOCK_TYPE_PCXTS) *mux_bits = MASK_BITS_31_28; else *mux_bits = MASK_BITS_31_30; - if (type == CLOCK_TYPE_PCMT16) + if (*type == CLOCK_TYPE_PCMT16) *divider_bits = 16; else *divider_bits = 8; + return 0; +} + +enum clock_id get_periph_clock_id(enum periph_id periph_id, int source) +{ + enum periphc_internal_id internal_id; + int type; + + if (!clock_periph_id_isvalid(periph_id)) + return CLOCK_ID_NONE; + + internal_id = periph_id_to_internal_id[periph_id]; + if (!periphc_internal_id_isvalid(internal_id)) + return CLOCK_ID_NONE; + + type = clock_periph_type[internal_id]; + if (!clock_type_id_isvalid(type)) + return CLOCK_ID_NONE; + + return clock_source[type][source]; +} + +/** + * Given a peripheral ID and the required source clock, this returns which + * value should be programmed into the source mux for that peripheral. + * + * There is special code here to handle the one source type with 5 sources. + * + * @param periph_id peripheral to start + * @param source PLL id of required parent clock + * @param mux_bits Set to number of bits in mux register: 2 or 4 + * @param divider_bits Set to number of divider bits (8 or 16) + * @return mux value (0-4, or -1 if not found) + */ +int get_periph_clock_source(enum periph_id periph_id, + enum clock_id parent, int *mux_bits, int *divider_bits) +{ + enum clock_type_id type; + int mux, err; + + err = get_periph_clock_info(periph_id, mux_bits, divider_bits, &type); + assert(!err); + for (mux = 0; mux < CLOCK_MAX_MUX; mux++) if (clock_source[type][mux] == parent) return mux; |