mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 08:19:28 +00:00
![Linus Walleij](/assets/img/avatar_default.png)
This implements the two missing CLKOUT clocks for the ux500 (well really U8500/DB8500) SoC. The clocks are initialized using a specific parent and divider and these are specified in the device tree, see the separate binding patch. The implementation is a bit different in that it will only create the clock in the clock framework if a user appears in the device tree, rather than it being registered upfront like most of the other clocks. This is because the clock needs parameters for source and divider from the consumer phandle for the clock to be set up properly when the clock is registered. There could be more than one user of a CLKOUT clock, but we have not seen this in practice. If this happens the framework prints and info and returns the previously registered clock. Using the clocks requires also muxing the CLKOUT1 or CLKOUT2 to the appropriate pad. In practice this is achived in a pinctrl handle in the DTS node for the device using the CLKOUT clock, so this muxing is done separately from the clock itself. Example: haptic@49 { compatible = "immersion,isa1200"; reg = <0x49>; (...) /* clkout1 from ACLK divided by 8 */ clocks = <&clkout_clk DB8500_CLKOUT_1 DB8500_CLKOUT_SRC_ACLK 8>; pinctrl-names = "default"; pinctrl-0 = <&isa1200_janice_default>; }; isa1200_janice_default: isa1200_janice { /* Bring out clkout1 on pin GPIO227 pin AH7 */ janice_mux { function = "clkout"; groups = "clkout1_a_1"; }; janice_cfg1 { pins = "GPIO227_AH7"; ste,config = <&out_lo>; }; (...) This was tested successfully with the Immersion ISA1200 haptic feedback unit on the Samsung Galaxy S Advance GT-I9070 (Janice) mobile phone. As the CLKOUT clocks need some undefined fixed rate parent clocks that are currently missing from the PRCMU clock implementation, the three simplest are added in this patch: clk38m_to_clkgen, aclk and sysclk. The only parent not yet available in the implementation is clk009, which is a kind of special muxed and divided clock which isn't even implemented in the vendor clock driver. Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://lore.kernel.org/r/20220414221751.323525-6-linus.walleij@linaro.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
96 lines
2.5 KiB
C
96 lines
2.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Clocks for ux500 platforms
|
|
*
|
|
* Copyright (C) 2012 ST-Ericsson SA
|
|
* Author: Ulf Hansson <ulf.hansson@linaro.org>
|
|
*/
|
|
|
|
#ifndef __UX500_CLK_H
|
|
#define __UX500_CLK_H
|
|
|
|
#include <linux/device.h>
|
|
#include <linux/types.h>
|
|
|
|
struct clk;
|
|
struct clk_hw;
|
|
|
|
struct clk *clk_reg_prcc_pclk(const char *name,
|
|
const char *parent_name,
|
|
resource_size_t phy_base,
|
|
u32 cg_sel,
|
|
unsigned long flags);
|
|
|
|
struct clk *clk_reg_prcc_kclk(const char *name,
|
|
const char *parent_name,
|
|
resource_size_t phy_base,
|
|
u32 cg_sel,
|
|
unsigned long flags);
|
|
|
|
struct clk_hw *clk_reg_prcmu_scalable(const char *name,
|
|
const char *parent_name,
|
|
u8 cg_sel,
|
|
unsigned long rate,
|
|
unsigned long flags);
|
|
|
|
struct clk_hw *clk_reg_prcmu_gate(const char *name,
|
|
const char *parent_name,
|
|
u8 cg_sel,
|
|
unsigned long flags);
|
|
|
|
struct clk_hw *clk_reg_prcmu_scalable_rate(const char *name,
|
|
const char *parent_name,
|
|
u8 cg_sel,
|
|
unsigned long rate,
|
|
unsigned long flags);
|
|
|
|
struct clk_hw *clk_reg_prcmu_rate(const char *name,
|
|
const char *parent_name,
|
|
u8 cg_sel,
|
|
unsigned long flags);
|
|
|
|
struct clk_hw *clk_reg_prcmu_opp_gate(const char *name,
|
|
const char *parent_name,
|
|
u8 cg_sel,
|
|
unsigned long flags);
|
|
|
|
struct clk_hw *clk_reg_prcmu_opp_volt_scalable(const char *name,
|
|
const char *parent_name,
|
|
u8 cg_sel,
|
|
unsigned long rate,
|
|
unsigned long flags);
|
|
|
|
struct clk_hw *clk_reg_prcmu_clkout(const char *name,
|
|
const char * const *parent_names,
|
|
int num_parents,
|
|
u8 source, u8 divider);
|
|
|
|
struct clk *clk_reg_sysctrl_gate(struct device *dev,
|
|
const char *name,
|
|
const char *parent_name,
|
|
u16 reg_sel,
|
|
u8 reg_mask,
|
|
u8 reg_bits,
|
|
unsigned long enable_delay_us,
|
|
unsigned long flags);
|
|
|
|
struct clk *clk_reg_sysctrl_gate_fixed_rate(struct device *dev,
|
|
const char *name,
|
|
const char *parent_name,
|
|
u16 reg_sel,
|
|
u8 reg_mask,
|
|
u8 reg_bits,
|
|
unsigned long rate,
|
|
unsigned long enable_delay_us,
|
|
unsigned long flags);
|
|
|
|
struct clk *clk_reg_sysctrl_set_parent(struct device *dev,
|
|
const char *name,
|
|
const char **parent_names,
|
|
u8 num_parents,
|
|
u16 *reg_sel,
|
|
u8 *reg_mask,
|
|
u8 *reg_bits,
|
|
unsigned long flags);
|
|
|
|
#endif /* __UX500_CLK_H */
|