Linux Clock Framework

February 24, 2020

Hardware Clock Tree

A System On Chip usually needs at least one general input clock that is typically generated by a crystal oscillator or a PLL. Within the SoC, this input clock goes through a tree of configurable hardware multipliers, dividers, or multiplexers, to eventually provide the appropriate clock frequencies to each hardware controller. Below is an example of such a clock tree.
Figure 1 - Example of clock hardware components
In the Linux Clock Framework terminology, the blue components are known as clock sources. All clock sources generate a clock signal as an output, and they can combine one or several of those capabilites:
Function Description
Gate The clock source can be turned off, or turned on. This functionnality is typically useful to save power.
Parent The clock source can have a parent. If it doesn't have a parent, it is known as a root clock.
Multiplexer The clock source can change its parent, choosing it among a list of possible parent clocks.
Multiplier The clock generates its output rate by multiplying the rate of its parent by a given factor.
Divider The clock generates its output rate by dividing the rate of its parent by a given factor.
The clock frequency provided to a given device typically needs to be changed dynamically depending on user's needs. For example if the user changes its UART's rate, one or several of the multipliers or dividers rates might have to be changed, or a multiplexer might need to select another parent. Saving power is also one of the reasons the system would like to dynamically modify clock configuration: when a device is not used anymore, its input clock can be turned off. To cope with this complexity, Linux provides a rich clock framework.

Clock Providers and Consumers

The Linux clock framework defines two kind of devices:

Below is a figure showing the Linux device tree nodes that could represent the hardware clock tree of Figure 1.

Figure 2 - Example of clock provider and consumer nodes in the Linux device tree

All the clock sources represented in blue in Figure 1 are implemented by a single provider that you can see in Figure 2. It is interesting to note that the parent-child relationships that exist in the hardware clock tree do not show up in the Linux device tree representation. Those relationships are usually part of the provider's implementation. On the other hand, the provider-consumer relationships are represented in the Linux device tree by the clocks properties.

Clock Provider API

A clock provider driver will typically perform two operations:

Registering the clock sources

A couple of functions can be used to register clock sources.
Function Description
int
clk_hw_register(
    struct device *dev,
    struct clk_hw *hw)
	
Add a clock source to the global tree of clock sources. This is the basic registration function that can be used if you need to build your clock from scratch. Otherwise, use one of the next functions.
struct clk_hw *
clk_hw_register_fixed_rate(
    struct device *dev,
    const char *name,
    const char *parent_name,
    unsigned long flags,
    unsigned long fixed_rate)
	
Registers a fixed rate clock specified by fixed_rate.
struct clk_hw *
clk_hw_register_gate(
    struct device *dev,
    const char *name,
    const char *parent_name,
    unsigned long flags,
    void __iomem *reg,
    u8 bit_idx,
    u8 clk_gate_flags,
    spinlock_t *lock)
	
Register a gating clock. The gate is controlled by the value of the bit at index bit_idx in the register reg.
struct clk_hw *
clk_hw_register_divider(
    struct device *dev,
    const char *name,
    const char *parent_name,
    unsigned long flags,
    void __iomem *reg,
    u8 shift,
    u8 width,
    u8 clk_divider_flags,
    spinlock_t *lock)
	
Register a divider clock. The division factor is in the field of width bits in the register reg starting at bit shift
struct clk_hw *
clk_hw_register_mux(
    struct device *dev,
    const char *name,
    const char * const *parent_names,
    u8 num_parents,
    unsigned long flags,
    void __iomem *reg,
    u8 shift,
    u8 width,
    u8 clk_mux_flags,
    spinlock_t *lock)
	
Register a multiplexer clock. The parent is selected by the field of width bits starting at bit index shift of the register reg. Depending on the flags clk_mux_flags, this the field encodes the selected parent as a 0-based index, or as a 1-based index, or as a one bit per possible parent.
struct clk_hw *
clk_hw_register_mux_table(
    struct device *dev,
    const char *name,
    const char * const *parent_names,
    u8 num_parents,
    unsigned long flags,
    void __iomem *reg,
    u8 shift,
    u32 mask,
    u8 clk_mux_flags,
    u32 *table,
    spinlock_t *lock)
	
This is a variant of the previous function that takes an extra table as an input parameter that specifies what field value should be used to select the parent at a given index.
struct clk_hw *
clk_hw_register_fixed_factor(
    struct device *dev,
    const char *name,
    const char *parent_name,
    unsigned long flags,
    unsigned int mult,
    unsigned int div)
	
Registers a fixed factor clock. The output frequency of this clock is the parent clock rate divided by div and multiplied by mult.
struct clk_hw *
clk_hw_register_fractional_divider(
    struct device *dev,
    const char *name,
    const char *parent_name,
    unsigned long flags,
    void __iomem *reg,
    u8 mshift,
    u8 mwidth,
    u8 nshift,
    u8 nwidth,
    u8 clk_divider_flags,
    spinlock_t *lock)
	
Registers a fractional divider clock. Numerator is defined by the field of mwidth bits at postition mshift in the register reg, while denominator is defined by the field of nwidth bits at postition nshift in the same register.
struct clk_hw *
clk_hw_register_composite(
    struct device *dev,
    const char *name,
    const char *const *parent_names,
    int num_parents,
    struct clk_hw *mux_hw,
    const struct clk_ops *mux_ops,
    struct clk_hw *rate_hw,
    const struct clk_ops *rate_ops,
    struct clk_hw *gate_hw,
    const struct clk_ops *gate_ops,
    unsigned long flags)
	
Registers a composite clock that can combine a gate, a multiplexer, and some rate setting functionnality. Input parameters can be passed using the following structures:
/* Mux data and operations */
struct clk_mux {
    struct clk_hw	hw;
    void __iomem	*reg;
    u32		*table;
    u32		mask;
    u8		shift;
    u8		flags;
    spinlock_t	*lock;
};
extern const struct clk_ops clk_mux_ops;

/* Divider data and operations */
struct clk_divider {
    struct clk_hw	hw;
    void __iomem	*reg;
    u8		shift;
    u8		width;
    u8		flags;
    const struct clk_div_table	*table;
    spinlock_t	*lock;
};
extern const struct clk_ops clk_divider_ops;

/* Gate data and operations */
struct clk_gate {
    struct clk_hw hw;
    void __iomem	*reg;
    u8		bit_idx;
    u8		flags;
    spinlock_t	*lock;
};
extern const struct clk_ops clk_gate_ops;


      
struct clk_hw *
clk_hw_register_gpio_gate(
    struct device *dev,
    const char *name,
    const char *parent_name,
    struct gpio_desc *gpiod,
    unsigned long flags)
	
Registers a gating clock controlled by a GPIO.
struct clk_hw *
clk_hw_register_gpio_mux(
    struct device *dev,
    const char *name,
    const char * const *parent_names,
    u8 num_parents,
    struct gpio_desc *gpiod,
    unsigned long flags)
	
Registers a multiplexer clock controlled by a GPIO.
Your provider driver will first have to call one of the above function to register one or several clocks and make it available to the global Linux clock tree. If none of the predefined clock models fits your hardware clock controller, you will have to build it from scatch and register it calling the clk_hw_register() function. The struct clk_hw passed as an input parameter should contain the information defining the clock:
struct clk_hw {
        struct clk_core *core;
        struct clk *clk;
        const struct clk_init_data *init;
};
The fields core and clk should be initialized to NULL, and the init field should contain all the clock initialization data:
struct clk_init_data {
	const char		*name;
	const struct clk_ops	*ops;
	/* Only one of the following three should be assigned */
	const char		* const *parent_names;
	const struct clk_parent_data	*parent_data;
	const struct clk_hw		**parent_hws;
	u8			num_parents;
	unsigned long		flags;
};
As seen in the above structure, the clock is identified by a global name, operations, an array of parents, and some flags. Below are the most interesting operations in struct clk_ops:
/**
 * struct clk_ops -  Callback operations for hardware clocks; these are to
 * be provided by the clock implementation, and will be called by drivers
 * through the clk_* api.
 *
 * @prepare:	Prepare the clock for enabling. This must not return until
 *		the clock is fully prepared, and it's safe to call clk_enable.
 *		This callback is intended to allow clock implementations to
 *		do any initialisation that may sleep. Called with
 *		prepare_lock held.
 *
 * @unprepare:	Release the clock from its prepared state. This will typically
 *		undo any work done in the @prepare callback. Called with
 *		prepare_lock held.
 *
 * @enable:	Enable the clock atomically. This must not return until the
 *		clock is generating a valid clock signal, usable by consumer
 *		devices. Called with enable_lock held. This function must not
 *		sleep.
 *
 * @disable:	Disable the clock atomically. Called with enable_lock held.
 *		This function must not sleep.
 *
 * @recalc_rate	Recalculate the rate of this clock, by querying hardware. The
 *		parent rate is an input parameter.  It is up to the caller to
 *		ensure that the prepare_mutex is held across this call.
 *		Returns the calculated rate.  Optional, but recommended - if
 *		this op is not set then clock rate will be initialized to 0.
 *
 * @round_rate:	Given a target rate as input, returns the closest rate actually
 *		supported by the clock. The parent rate is an input/output
 *		parameter.
 *
 * @determine_rate: Given a target rate as input, returns the closest rate
 *		actually supported by the clock, and optionally the parent clock
 *		that should be used to provide the clock rate.
 *
 * @set_parent:	Change the input source of this clock; for clocks with multiple
 *		possible parents specify a new parent by passing in the index
 *		as a u8 corresponding to the parent in either the .parent_names
 *		or .parents arrays.  This function in affect translates an
 *		array index into the value programmed into the hardware.
 *		Returns 0 on success, -EERROR otherwise.
 *
 * @get_parent:	Queries the hardware to determine the parent of a clock.  The
 *		return value is a u8 which specifies the index corresponding to
 *		the parent clock.  This index can be applied to either the
 *		.parent_names or .parents arrays.  In short, this function
 *		translates the parent value read from hardware into an array
 *		index.  Currently only called when the clock is initialized by
 *		__clk_init.  This callback is mandatory for clocks with
 *		multiple parents.  It is optional (and unnecessary) for clocks
 *		with 0 or 1 parents.
 *
 * @set_rate:	Change the rate of this clock. The requested rate is specified
 *		by the second argument, which should typically be the return
 *		of .round_rate call.  The third argument gives the parent rate
 *		which is likely helpful for most .set_rate implementation.
 *		Returns 0 on success, -EERROR otherwise.
 *
 * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow
 * implementations to split any work between atomic (enable) and sleepable
 * (prepare) contexts.  If enabling a clock requires code that might sleep,
 * this must be done in clk_prepare.  Clock enable code that will never be
 * called in a sleepable context may be implemented in clk_enable.
 *
 * Typically, drivers will call clk_prepare when a clock may be needed later
 * (eg. when a device is opened), and clk_enable when the clock is actually
 * required (eg. from an interrupt). Note that clk_prepare MUST have been
 * called before clk_enable.
 */
struct clk_ops {
    int            (*prepare)(struct clk_hw *hw);
    void           (*unprepare)(struct clk_hw *hw);
    int            (*enable)(struct clk_hw *hw);
    void           (*disable)(struct clk_hw *hw);
    unsigned long  (*recalc_rate)(struct clk_hw *hw,
                                  unsigned long parent_rate);
    long           (*round_rate)(struct clk_hw *hw,
                                 unsigned long rate,
                                 unsigned long *parent_rate);
    int            (*determine_rate)(struct clk_hw *hw,
                                     struct clk_rate_request *req);
    int	           (*set_parent)(struct clk_hw *hw,
                                 u8 index);
    u8	           (*get_parent)(struct clk_hw *hw);
    int	           (*set_rate)(struct clk_hw *hw,
                               unsigned long rate,
                               unsigned long parent_rate);
    /*...*/
  };

Registering the provider

Once the clock sources are registered, you can register the provider using the following function:
int of_clk_add_hw_provider(
    struct device_node *np,
    struct clk_hw *(*get)(struct of_phandle_args *clkspec,
                          void *data),
    void *data);
The provided get function pointer converts a clock specifier to an actual clock source object. The Linux Kernel provides two implementations for this get function:
Function Description
struct clk_hw *
of_clk_hw_simple_get(
    struct of_phandle_args *clkspec,
    void *data)
get function that can be used for a provider of dimension 0. Then the data passed to of_clk_add_hw_provider() has to be a pointer to the clk_hw which is the unique clock implemented by the provider.
struct clk_hw *
of_clk_hw_onecell_get(
    struct of_phandle_args *clkspec,
    void *data)
get function that can be used for a provider of dimension 1. Then the data passed to of_clk_add_hw_provider() has to be a pointer to struct clk_hw_onecell_data.
struct clk_hw_onecell_data {
    unsigned int num;
    struct clk_hw *hws[];
};

Clock Consumer API

Any node in the device tree that includes a clocks property becomes a clock consumer node and thus allows the code of its associated driver to control the referenced clocks using the Clock Consumer API:

Function Description
struct clk *of_clk_get_by_name(
    struct device_node *np,
    const char *name)
Get a clock object by name. The name is specified in the device tree node by the clock-names property.
int clk_prepare(struct clk *clk)
Prepare the clock to be enabled. This function cannot be called from atomic contexts.
int clk_enable(struct clk *clk)
Enable the clock, i.e turn it on. This function may be called from atomic contexts.
int clk_disable(struct clk *clk)
Disable the clock, i.e turn it off. This function may be called from atomic contexts.
int clk_unprepare(struct clk *clk)
Unprepare the clock. This function cannot be called from atomic contexts.
int clk_set_parent(
    struct clk *clk,
    struct clk *parent)
Selects the parent of the clock, among its list of possible parents. This function configures the multiplexer.
int clk_set_rate(
    struct clk *clk,
    unsigned long rate)
Modifies the rate of the clock.

Note that calling the clk_set_rate() function can do pretty complex stuff like go through the entire clock tree to find the better configuration, potentially reconfiguring multipliers, dividers and multiplexers.

The framework also detects what clock nodes should be turned off. For example, disabling the UART controller's input clock will go through the clock tree and turn off all the nodes that are not used anymore, thus helping to save power.

Figure 3 - Power Saving handled by Linux Clock Framework

Dumping Clock Tree

You can observe the current clock tree configuration through debugfs.
# mount -t debugfs none /sys/kernel/debug
# cat /sys/kernel/debug/clk/clk_summary

   clock                         enable_cnt  prepare_cnt        rate   accuracy   phase
----------------------------------------------------------------------------------------
clk-ext-camera                           0            0    24000000          0 0  
ck_usbo_48m                              1            1    48000000          0 0  
   usbo_k                                1            1    48000000          0 0  
ck_dsi_phy                               0            0           0          0 0  
   dsi_k                                 0            0           0          0 0  
i2s_ckin                                 0            0           0          0 0  
clk-csi                                  0            0     4000000          0 0  
   ck_csi                                0            0     4000000          0 0  
      rng2_k                             0            0     4000000          0 0  
      rng1_k                             0            0     4000000          0 0  
clk-lsi                                  1            1       32000          0 0  
   ck_lsi                                1            1       32000          0 0  
      dac12_k                            0            0       32000          0 0  
clk-lse                                  1            1       32768          0 0  
   ck_lse                                1            1       32768          0 0  
      ck_rtc                             1            1       32768          0 0  
      cec_k                              0            0       32768          0 0  
clk-hsi                                  1            1    64000000          0 0  
   clk-hsi-div                           1            1    64000000          0 0  
      ck_hsi                             2            2    64000000          0 0  
         ck_mco1                         0            0    64000000          0 0  
         uart8_k                         0            0    64000000          0 0  
         uart7_k                         0            0    64000000          0 0  
         uart6_k                         0            0    64000000          0 0  
         uart5_k                         0            0    64000000          0 0  
         uart4_k                         1            1    64000000          0 0  
         usart3_k                        0            0    64000000          0 0  
         usart2_k                        0            0    64000000          0 0  
         usart1_k                        0            0    64000000          0 0  
         i2c6_k                          0            0    64000000          0 0  
         i2c4_k                          1            1    64000000          0 0  
         i2c5_k                          0            0    64000000          0 0  
         i2c3_k                          0            0    64000000          0 0  
         i2c2_k                          0            0    64000000          0 0  
         i2c1_k                          0            0    64000000          0 0  
         spi6_k                          0            0    64000000          0 0  
         spi5_k                          0            0    64000000          0 0  
         spi4_k                          0            0    64000000          0 0  
clk-hse                                  1            1    24000000          0 0  
   ck_hse                                6            6    24000000          0 0  
      ck_hse_rtc                         0            0     1000000          0 0  
      stgen_k                            1            1    24000000          0 0  
      usbphy_k                           1            1    24000000          0 0  
      ck_per                             0            0    24000000          0 0  
         adc12_k                         0            0    24000000          0 0  
      ref4                               1            1    24000000          0 0  
         pll4                            1            1   508000000          0 0  
            pll4_r                       0            0    56444445          0 0  
            pll4_q                       1            1    50800000          0 0  
               ltdc_px                   1            1    50800000          0 0  
               dsi_px                    0            0    50800000          0 0  
               fdcan_k                   0            0    50800000          0 0  
            pll4_p                       0            0    56444445          0 0  
      ref3                               1            1    24000000          0 0  
         pll3                            2            3   786431640          0 0  
            pll3_r                       1            1    98303955          0 0  
               sdmmc3_k                  0            0    98303955          0 0  
               sdmmc2_k                  0            0    98303955          0 0  
               sdmmc1_k                  1            1    98303955          0 0  
            pll3_q                       0            3    49151978          0 0  
               adfsdm_k                  0            0    49151978          0 0  
               sai4_k                    0            1    49151978          0 0  
               sai3_k                    0            0    49151978          0 0  
               sai2_k                    0            2    49151978          0 0  
               sai1_k                    0            0    49151978          0 0  
               spi3_k                    0            0    49151978          0 0  
               spi2_k                    0            0    49151978          0 0  
               spi1_k                    0            0    49151978          0 0  
               spdif_k                   0            1    49151978          0 0  
            pll3_p                       1            1   196607910          0 0  
               ck_mcu                    6           19   196607910          0 0  
                  dfsdm_k                0            1   196607910          0 0  
                  gpiok                  0            1   196607910          0 0  
                  gpioj                  0            1   196607910          0 0  
                  gpioi                  0            1   196607910          0 0  
                  gpioh                  0            1   196607910          0 0  
                  gpiog                  0            1   196607910          0 0  
                  gpiof                  0            1   196607910          0 0  
                  gpioe                  0            1   196607910          0 0  
                  gpiod                  0            1   196607910          0 0  
                  gpioc                  0            1   196607910          0 0  
                  gpiob                  0            1   196607910          0 0  
                  gpioa                  0            1   196607910          0 0  
                  ipcc                   2            2   196607910          0 0  
                  hsem                   0            0   196607910          0 0  
                  crc2                   0            0   196607910          0 0  
                  rng2                   0            0   196607910          0 0  
                  hash2                  0            0   196607910          0 0  
                  cryp2                  0            0   196607910          0 0  
                  dcmi                   0            0   196607910          0 0  
                  sdmmc3                 0            0   196607910          0 0  
                  usbo                   0            0   196607910          0 0  
                  adc12                  0            0   196607910          0 0  
                  dmamux                 1            1   196607910          0 0  
                  dma2                   1            1   196607910          0 0  
                  dma1                   1            1   196607910          0 0  
                  pclk3                  1            1    98303955          0 0  
                     lptim5_k            0            0    98303955          0 0  
                     lptim4_k            0            0    98303955          0 0  
                     lptim3_k            0            0    98303955          0 0  
                     lptim2_k            0            0    98303955          0 0  
                     hdp                 0            0    98303955          0 0  
                     pmbctrl             0            0    98303955          0 0  
                     tmpsens             0            0    98303955          0 0  
                     vref                0            0    98303955          0 0  
                     syscfg              1            1    98303955          0 0  
                     sai4                0            0    98303955          0 0  
                     lptim5              0            0    98303955          0 0  
                     lptim4              0            0    98303955          0 0  
                     lptim3              0            0    98303955          0 0  
                     lptim2              0            0    98303955          0 0  
                  pclk2                  0            0    98303955          0 0  
                     fdcan               0            0    98303955          0 0  
                     dfsdm               0            0    98303955          0 0  
                     sai3                0            0    98303955          0 0  
                     sai2                0            0    98303955          0 0  
                     sai1                0            0    98303955          0 0  
                     usart6              0            0    98303955          0 0  
                     spi5                0            0    98303955          0 0  
                     spi4                0            0    98303955          0 0  
                     spi1                0            0    98303955          0 0  
                     tim17               0            0    98303955          0 0  
                     tim16               0            0    98303955          0 0  
                     tim15               0            0    98303955          0 0  
                     tim8                0            0    98303955          0 0  
                     tim1                0            0    98303955          0 0  
                     ck2_tim             0            0   196607910          0 0  
                        tim17_k           0            0   196607910          0 0  
                        tim16_k           0            0   196607910          0 0  
                        tim15_k           0            0   196607910          0 0  
                        tim8_k           0            0   196607910          0 0  
                        tim1_k           0            0   196607910          0 0  
                  pclk1                  0            2    98303955          0 0  
                     lptim1_k            0            0    98303955          0 0  
                     mdio                0            0    98303955          0 0  
                     dac12               0            1    98303955          0 0  
                     cec                 0            0    98303955          0 0  
                     spdif               0            0    98303955          0 0  
                     i2c5                0            0    98303955          0 0  
                     i2c3                0            0    98303955          0 0  
                     i2c2                0            0    98303955          0 0  
                     i2c1                0            0    98303955          0 0  
                     uart8               0            0    98303955          0 0  
                     uart7               0            0    98303955          0 0  
                     uart5               0            0    98303955          0 0  
                     uart4               0            0    98303955          0 0  
                     usart3              0            0    98303955          0 0  
                     usart2              0            0    98303955          0 0  
                     spi3                0            0    98303955          0 0  
                     spi2                0            0    98303955          0 0  
                     lptim1              0            0    98303955          0 0  
                     tim14               0            0    98303955          0 0  
                     tim13               0            0    98303955          0 0  
                     tim12               0            0    98303955          0 0  
                     tim7                0            0    98303955          0 0  
                     tim6                0            0    98303955          0 0  
                     tim5                0            0    98303955          0 0  
                     tim4                0            0    98303955          0 0  
                     tim3                0            0    98303955          0 0  
                     tim2                0            0    98303955          0 0  
                     ck1_tim             0            1   196607910          0 0  
                        tim14_k           0            0   196607910          0 0  
                        tim13_k           0            0   196607910          0 0  
                        tim12_k           0            0   196607910          0 0  
                        tim7_k           0            0   196607910          0 0  
                        tim6_k           0            1   196607910          0 0  
                        tim5_k           0            0   196607910          0 0  
                        tim4_k           0            0   196607910          0 0  
                        tim3_k           0            0   196607910          0 0  
                        tim2_k           0            0   196607910          0 0  
      ref1                               2            2    24000000          0 0  
         pll2                            2            2   533000000          0 0  
            pll2_r                       1            1   533000000          0 0  
            pll2_q                       0            0   533000000          0 0  
               gpu_k                     0            0   533000000          0 0  
            pll2_p                       1            1   266500000          0 0  
               ck_axi                    9           10   266500000          0 0  
                  ck_trace               0            0   133250000          0 0  
                  ck_sys_dbg             0            0   266500000          0 0  
                  qspi_k                 1            1   266500000          0 0  
                  fmc_k                  0            0   266500000          0 0  
                  ethstp                 0            0   266500000          0 0  
                  usbh                   1            1   266500000          0 0  
                  crc1                   0            0   266500000          0 0  
                  sdmmc2                 0            0   266500000          0 0  
                  sdmmc1                 0            0   266500000          0 0  
                  qspi                   0            0   266500000          0 0  
                  fmc                    0            0   266500000          0 0  
                  ethmac                 1            1   266500000          0 0  
                  ethrx                  1            1   266500000          0 0  
                  ethtx                  1            1   266500000          0 0  
                  gpu                    0            0   266500000          0 0  
                  mdma                   1            1   266500000          0 0  
                  bkpsram                0            0   266500000          0 0  
                  rng1                   0            0   266500000          0 0  
                  hash1                  0            0   266500000          0 0  
                  cryp1                  0            0   266500000          0 0  
                  gpioz                  0            1   266500000          0 0  
                  tzc2                   0            0   266500000          0 0  
                  tzc1                   0            0   266500000          0 0  
                  pclk5                  1            1    66625000          0 0  
                     stgen               0            0    66625000          0 0  
                     bsec                0            0    66625000          0 0  
                     iwdg1               0            0    66625000          0 0  
                     tzpc                0            0    66625000          0 0  
                     rtcapb              2            2    66625000          0 0  
                     usart1              0            0    66625000          0 0  
                     i2c6                0            0    66625000          0 0  
                     i2c4                0            0    66625000          0 0  
                     spi6                0            0    66625000          0 0  
                  pclk4                  1            1   133250000          0 0  
                     stgenro             0            0   133250000          0 0  
                     usbphy              0            0   133250000          0 0  
                     iwdg2               1            1   133250000          0 0  
                     dsi                 0            0   133250000          0 0  
                     ltdc                0            0   133250000          0 0  
         pll1                            1            1   650000000          0 0  
            pll1_p                       1            1   650000000          0 0  
               ck_mpu                    1            1   650000000          0 0  
                  ck_mco2                0            0   650000000          0 0  
      clk-hse-div2                       0            0    12000000          0 0  
ethptp_k                                 0            0           0          0 0  
ethck_k
  
Note that the above information only shows the parent that is currently selected by each multiplexer. For example, you can only see that the current parent of the clock usart2_k is ck_hsi. To get the list of all the possible parents of usart2_k, you need to look at its clock entry in debugfs:
/sys/kernel/debug/clk# cd usart2_k
/sys/kernel/debug/clk/usart2_k# ls
clk_accuracy      clk_flags           clk_phase             clk_prepare_count
clk_enable_count  clk_notifier_count  clk_possible_parents  clk_rate

/sys/kernel/debug/clk/usart2_k# cat clk_possible_parents
pclk1 pll4_q ck_hsi ck_csi ck_hse
  

References

500x500