186 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Copyright (C) STMicroelectronics 2022 - All Rights Reserved4 * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics.5 */6 7#include <linux/clk-provider.h>8 9struct stm32_rcc_match_data;10 11struct stm32_mux_cfg {12 u16 offset;13 u8 shift;14 u8 width;15 u8 flags;16 u32 *table;17 u8 ready;18};19 20struct stm32_gate_cfg {21 u16 offset;22 u8 bit_idx;23 u8 set_clr;24};25 26struct stm32_div_cfg {27 u16 offset;28 u8 shift;29 u8 width;30 u8 flags;31 u8 ready;32 const struct clk_div_table *table;33};34 35struct stm32_composite_cfg {36 int mux;37 int gate;38 int div;39};40 41#define NO_ID 0xFFFFFFFF42 43#define NO_STM32_MUX 0xFFFF44#define NO_STM32_DIV 0xFFFF45#define NO_STM32_GATE 0xFFFF46 47struct clock_config {48 unsigned long id;49 int sec_id;50 void *clock_cfg;51 52 struct clk_hw *(*func)(struct device *dev,53 const struct stm32_rcc_match_data *data,54 void __iomem *base,55 spinlock_t *lock,56 const struct clock_config *cfg);57};58 59struct clk_stm32_clock_data {60 u16 *gate_cpt;61 const struct stm32_gate_cfg *gates;62 const struct stm32_mux_cfg *muxes;63 const struct stm32_div_cfg *dividers;64 struct clk_hw *(*is_multi_mux)(struct clk_hw *hw);65};66 67struct stm32_rcc_match_data {68 struct clk_hw_onecell_data *hw_clks;69 unsigned int num_clocks;70 const struct clock_config *tab_clocks;71 unsigned int maxbinding;72 struct clk_stm32_clock_data *clock_data;73 struct clk_stm32_reset_data *reset_data;74 int (*check_security)(struct device_node *np, void __iomem *base,75 const struct clock_config *cfg);76 int (*multi_mux)(void __iomem *base, const struct clock_config *cfg);77};78 79int stm32_rcc_init(struct device *dev, const struct of_device_id *match_data,80 void __iomem *base);81 82/* MUX define */83#define MUX_NO_RDY 0xFF84#define MUX_SAFE BIT(7)85 86/* DIV define */87#define DIV_NO_RDY 0xFF88 89/* Definition of clock structure */90struct clk_stm32_mux {91 u16 mux_id;92 struct clk_hw hw;93 void __iomem *base;94 struct clk_stm32_clock_data *clock_data;95 spinlock_t *lock; /* spin lock */96};97 98#define to_clk_stm32_mux(_hw) container_of(_hw, struct clk_stm32_mux, hw)99 100struct clk_stm32_gate {101 u16 gate_id;102 struct clk_hw hw;103 void __iomem *base;104 struct clk_stm32_clock_data *clock_data;105 spinlock_t *lock; /* spin lock */106};107 108#define to_clk_stm32_gate(_hw) container_of(_hw, struct clk_stm32_gate, hw)109 110struct clk_stm32_div {111 u16 div_id;112 struct clk_hw hw;113 void __iomem *base;114 struct clk_stm32_clock_data *clock_data;115 spinlock_t *lock; /* spin lock */116};117 118#define to_clk_stm32_divider(_hw) container_of(_hw, struct clk_stm32_div, hw)119 120struct clk_stm32_composite {121 u16 gate_id;122 u16 mux_id;123 u16 div_id;124 struct clk_hw hw;125 void __iomem *base;126 struct clk_stm32_clock_data *clock_data;127 spinlock_t *lock; /* spin lock */128};129 130#define to_clk_stm32_composite(_hw) container_of(_hw, struct clk_stm32_composite, hw)131 132/* Clock operators */133extern const struct clk_ops clk_stm32_mux_ops;134extern const struct clk_ops clk_stm32_gate_ops;135extern const struct clk_ops clk_stm32_divider_ops;136extern const struct clk_ops clk_stm32_composite_ops;137 138/* Clock registering */139struct clk_hw *clk_stm32_mux_register(struct device *dev,140 const struct stm32_rcc_match_data *data,141 void __iomem *base,142 spinlock_t *lock,143 const struct clock_config *cfg);144 145struct clk_hw *clk_stm32_gate_register(struct device *dev,146 const struct stm32_rcc_match_data *data,147 void __iomem *base,148 spinlock_t *lock,149 const struct clock_config *cfg);150 151struct clk_hw *clk_stm32_div_register(struct device *dev,152 const struct stm32_rcc_match_data *data,153 void __iomem *base,154 spinlock_t *lock,155 const struct clock_config *cfg);156 157struct clk_hw *clk_stm32_composite_register(struct device *dev,158 const struct stm32_rcc_match_data *data,159 void __iomem *base,160 spinlock_t *lock,161 const struct clock_config *cfg);162 163#define STM32_CLOCK_CFG(_binding, _clk, _sec_id, _struct, _register)\164{\165 .id = (_binding),\166 .sec_id = (_sec_id),\167 .clock_cfg = (_struct) {_clk},\168 .func = (_register),\169}170 171#define STM32_MUX_CFG(_binding, _clk, _sec_id)\172 STM32_CLOCK_CFG(_binding, &(_clk), _sec_id, struct clk_stm32_mux *,\173 &clk_stm32_mux_register)174 175#define STM32_GATE_CFG(_binding, _clk, _sec_id)\176 STM32_CLOCK_CFG(_binding, &(_clk), _sec_id, struct clk_stm32_gate *,\177 &clk_stm32_gate_register)178 179#define STM32_DIV_CFG(_binding, _clk, _sec_id)\180 STM32_CLOCK_CFG(_binding, &(_clk), _sec_id, struct clk_stm32_div *,\181 &clk_stm32_div_register)182 183#define STM32_COMPOSITE_CFG(_binding, _clk, _sec_id)\184 STM32_CLOCK_CFG(_binding, &(_clk), _sec_id, struct clk_stm32_composite *,\185 &clk_stm32_composite_register)186