1*ddd3e8b9SNishad Kamdar /* SPDX-License-Identifier: GPL-2.0+ */
22792c37eSManivannan Sadhasivam //
32792c37eSManivannan Sadhasivam // OWL pll clock driver
42792c37eSManivannan Sadhasivam //
52792c37eSManivannan Sadhasivam // Copyright (c) 2014 Actions Semi Inc.
62792c37eSManivannan Sadhasivam // Author: David Liu <liuwei@actions-semi.com>
72792c37eSManivannan Sadhasivam //
82792c37eSManivannan Sadhasivam // Copyright (c) 2018 Linaro Ltd.
92792c37eSManivannan Sadhasivam // Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
102792c37eSManivannan Sadhasivam
112792c37eSManivannan Sadhasivam #ifndef _OWL_PLL_H_
122792c37eSManivannan Sadhasivam #define _OWL_PLL_H_
132792c37eSManivannan Sadhasivam
142792c37eSManivannan Sadhasivam #include "owl-common.h"
152792c37eSManivannan Sadhasivam
169831289fSManivannan Sadhasivam #define OWL_PLL_DEF_DELAY 50
179831289fSManivannan Sadhasivam
182792c37eSManivannan Sadhasivam /* last entry should have rate = 0 */
192792c37eSManivannan Sadhasivam struct clk_pll_table {
202792c37eSManivannan Sadhasivam unsigned int val;
212792c37eSManivannan Sadhasivam unsigned long rate;
222792c37eSManivannan Sadhasivam };
232792c37eSManivannan Sadhasivam
242792c37eSManivannan Sadhasivam struct owl_pll_hw {
252792c37eSManivannan Sadhasivam u32 reg;
262792c37eSManivannan Sadhasivam u32 bfreq;
272792c37eSManivannan Sadhasivam u8 bit_idx;
282792c37eSManivannan Sadhasivam u8 shift;
292792c37eSManivannan Sadhasivam u8 width;
302792c37eSManivannan Sadhasivam u8 min_mul;
312792c37eSManivannan Sadhasivam u8 max_mul;
329831289fSManivannan Sadhasivam u8 delay;
332792c37eSManivannan Sadhasivam const struct clk_pll_table *table;
342792c37eSManivannan Sadhasivam };
352792c37eSManivannan Sadhasivam
362792c37eSManivannan Sadhasivam struct owl_pll {
372792c37eSManivannan Sadhasivam struct owl_pll_hw pll_hw;
382792c37eSManivannan Sadhasivam struct owl_clk_common common;
392792c37eSManivannan Sadhasivam };
402792c37eSManivannan Sadhasivam
412792c37eSManivannan Sadhasivam #define OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \
429831289fSManivannan Sadhasivam _width, _min_mul, _max_mul, _delay, _table) \
432792c37eSManivannan Sadhasivam { \
442792c37eSManivannan Sadhasivam .reg = _reg, \
452792c37eSManivannan Sadhasivam .bfreq = _bfreq, \
462792c37eSManivannan Sadhasivam .bit_idx = _bit_idx, \
472792c37eSManivannan Sadhasivam .shift = _shift, \
482792c37eSManivannan Sadhasivam .width = _width, \
492792c37eSManivannan Sadhasivam .min_mul = _min_mul, \
502792c37eSManivannan Sadhasivam .max_mul = _max_mul, \
519831289fSManivannan Sadhasivam .delay = _delay, \
522792c37eSManivannan Sadhasivam .table = _table, \
532792c37eSManivannan Sadhasivam }
542792c37eSManivannan Sadhasivam
552792c37eSManivannan Sadhasivam #define OWL_PLL(_struct, _name, _parent, _reg, _bfreq, _bit_idx, \
562792c37eSManivannan Sadhasivam _shift, _width, _min_mul, _max_mul, _table, _flags) \
572792c37eSManivannan Sadhasivam struct owl_pll _struct = { \
582792c37eSManivannan Sadhasivam .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \
599831289fSManivannan Sadhasivam _width, _min_mul, _max_mul, \
609831289fSManivannan Sadhasivam OWL_PLL_DEF_DELAY, _table), \
612792c37eSManivannan Sadhasivam .common = { \
622792c37eSManivannan Sadhasivam .regmap = NULL, \
632792c37eSManivannan Sadhasivam .hw.init = CLK_HW_INIT(_name, \
642792c37eSManivannan Sadhasivam _parent, \
652792c37eSManivannan Sadhasivam &owl_pll_ops, \
662792c37eSManivannan Sadhasivam _flags), \
672792c37eSManivannan Sadhasivam }, \
682792c37eSManivannan Sadhasivam }
692792c37eSManivannan Sadhasivam
702792c37eSManivannan Sadhasivam #define OWL_PLL_NO_PARENT(_struct, _name, _reg, _bfreq, _bit_idx, \
712792c37eSManivannan Sadhasivam _shift, _width, _min_mul, _max_mul, _table, _flags) \
722792c37eSManivannan Sadhasivam struct owl_pll _struct = { \
732792c37eSManivannan Sadhasivam .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \
749831289fSManivannan Sadhasivam _width, _min_mul, _max_mul, \
759831289fSManivannan Sadhasivam OWL_PLL_DEF_DELAY, _table), \
769831289fSManivannan Sadhasivam .common = { \
779831289fSManivannan Sadhasivam .regmap = NULL, \
789831289fSManivannan Sadhasivam .hw.init = CLK_HW_INIT_NO_PARENT(_name, \
799831289fSManivannan Sadhasivam &owl_pll_ops, \
809831289fSManivannan Sadhasivam _flags), \
819831289fSManivannan Sadhasivam }, \
829831289fSManivannan Sadhasivam }
839831289fSManivannan Sadhasivam
849831289fSManivannan Sadhasivam #define OWL_PLL_NO_PARENT_DELAY(_struct, _name, _reg, _bfreq, _bit_idx, \
859831289fSManivannan Sadhasivam _shift, _width, _min_mul, _max_mul, _delay, _table, \
869831289fSManivannan Sadhasivam _flags) \
879831289fSManivannan Sadhasivam struct owl_pll _struct = { \
889831289fSManivannan Sadhasivam .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \
899831289fSManivannan Sadhasivam _width, _min_mul, _max_mul, \
909831289fSManivannan Sadhasivam _delay, _table), \
912792c37eSManivannan Sadhasivam .common = { \
922792c37eSManivannan Sadhasivam .regmap = NULL, \
932792c37eSManivannan Sadhasivam .hw.init = CLK_HW_INIT_NO_PARENT(_name, \
942792c37eSManivannan Sadhasivam &owl_pll_ops, \
952792c37eSManivannan Sadhasivam _flags), \
962792c37eSManivannan Sadhasivam }, \
972792c37eSManivannan Sadhasivam }
982792c37eSManivannan Sadhasivam
992792c37eSManivannan Sadhasivam #define mul_mask(m) ((1 << ((m)->width)) - 1)
1002792c37eSManivannan Sadhasivam
hw_to_owl_pll(const struct clk_hw * hw)1012792c37eSManivannan Sadhasivam static inline struct owl_pll *hw_to_owl_pll(const struct clk_hw *hw)
1022792c37eSManivannan Sadhasivam {
1032792c37eSManivannan Sadhasivam struct owl_clk_common *common = hw_to_owl_clk_common(hw);
1042792c37eSManivannan Sadhasivam
1052792c37eSManivannan Sadhasivam return container_of(common, struct owl_pll, common);
1062792c37eSManivannan Sadhasivam }
1072792c37eSManivannan Sadhasivam
1082792c37eSManivannan Sadhasivam extern const struct clk_ops owl_pll_ops;
1092792c37eSManivannan Sadhasivam
1102792c37eSManivannan Sadhasivam #endif /* _OWL_PLL_H_ */
111