18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */
28c2ecf20Sopenharmony_ci//
38c2ecf20Sopenharmony_ci// OWL pll clock driver
48c2ecf20Sopenharmony_ci//
58c2ecf20Sopenharmony_ci// Copyright (c) 2014 Actions Semi Inc.
68c2ecf20Sopenharmony_ci// Author: David Liu <liuwei@actions-semi.com>
78c2ecf20Sopenharmony_ci//
88c2ecf20Sopenharmony_ci// Copyright (c) 2018 Linaro Ltd.
98c2ecf20Sopenharmony_ci// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifndef _OWL_PLL_H_
128c2ecf20Sopenharmony_ci#define _OWL_PLL_H_
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include "owl-common.h"
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#define OWL_PLL_DEF_DELAY	50
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/* last entry should have rate = 0 */
198c2ecf20Sopenharmony_cistruct clk_pll_table {
208c2ecf20Sopenharmony_ci	unsigned int		val;
218c2ecf20Sopenharmony_ci	unsigned long		rate;
228c2ecf20Sopenharmony_ci};
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_cistruct owl_pll_hw {
258c2ecf20Sopenharmony_ci	u32			reg;
268c2ecf20Sopenharmony_ci	u32			bfreq;
278c2ecf20Sopenharmony_ci	u8			bit_idx;
288c2ecf20Sopenharmony_ci	u8			shift;
298c2ecf20Sopenharmony_ci	u8			width;
308c2ecf20Sopenharmony_ci	u8			min_mul;
318c2ecf20Sopenharmony_ci	u8			max_mul;
328c2ecf20Sopenharmony_ci	u8			delay;
338c2ecf20Sopenharmony_ci	const struct clk_pll_table *table;
348c2ecf20Sopenharmony_ci};
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cistruct owl_pll {
378c2ecf20Sopenharmony_ci	struct owl_pll_hw	pll_hw;
388c2ecf20Sopenharmony_ci	struct owl_clk_common	common;
398c2ecf20Sopenharmony_ci};
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci#define OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift,			\
428c2ecf20Sopenharmony_ci		   _width, _min_mul, _max_mul, _delay, _table)		\
438c2ecf20Sopenharmony_ci	{								\
448c2ecf20Sopenharmony_ci		.reg		= _reg,					\
458c2ecf20Sopenharmony_ci		.bfreq		= _bfreq,				\
468c2ecf20Sopenharmony_ci		.bit_idx	= _bit_idx,				\
478c2ecf20Sopenharmony_ci		.shift		= _shift,				\
488c2ecf20Sopenharmony_ci		.width		= _width,				\
498c2ecf20Sopenharmony_ci		.min_mul	= _min_mul,				\
508c2ecf20Sopenharmony_ci		.max_mul	= _max_mul,				\
518c2ecf20Sopenharmony_ci		.delay		= _delay,				\
528c2ecf20Sopenharmony_ci		.table		= _table,				\
538c2ecf20Sopenharmony_ci	}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci#define OWL_PLL(_struct, _name, _parent, _reg, _bfreq, _bit_idx,	\
568c2ecf20Sopenharmony_ci		_shift, _width, _min_mul, _max_mul, _table, _flags)	\
578c2ecf20Sopenharmony_ci	struct owl_pll _struct = {					\
588c2ecf20Sopenharmony_ci		.pll_hw	= OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift,	\
598c2ecf20Sopenharmony_ci				     _width, _min_mul, _max_mul,	\
608c2ecf20Sopenharmony_ci				     OWL_PLL_DEF_DELAY,	_table),	\
618c2ecf20Sopenharmony_ci		.common = {						\
628c2ecf20Sopenharmony_ci			.regmap = NULL,					\
638c2ecf20Sopenharmony_ci			.hw.init = CLK_HW_INIT(_name,			\
648c2ecf20Sopenharmony_ci					       _parent,			\
658c2ecf20Sopenharmony_ci					       &owl_pll_ops,		\
668c2ecf20Sopenharmony_ci					       _flags),			\
678c2ecf20Sopenharmony_ci		},							\
688c2ecf20Sopenharmony_ci	}
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#define OWL_PLL_NO_PARENT(_struct, _name, _reg, _bfreq, _bit_idx,	\
718c2ecf20Sopenharmony_ci		_shift, _width, _min_mul, _max_mul, _table, _flags)	\
728c2ecf20Sopenharmony_ci	struct owl_pll _struct = {					\
738c2ecf20Sopenharmony_ci		.pll_hw	= OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift,	\
748c2ecf20Sopenharmony_ci				     _width, _min_mul, _max_mul,	\
758c2ecf20Sopenharmony_ci				     OWL_PLL_DEF_DELAY,	_table),	\
768c2ecf20Sopenharmony_ci		.common = {						\
778c2ecf20Sopenharmony_ci			.regmap = NULL,					\
788c2ecf20Sopenharmony_ci			.hw.init = CLK_HW_INIT_NO_PARENT(_name,		\
798c2ecf20Sopenharmony_ci					       &owl_pll_ops,		\
808c2ecf20Sopenharmony_ci					       _flags),			\
818c2ecf20Sopenharmony_ci		},							\
828c2ecf20Sopenharmony_ci	}
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci#define OWL_PLL_NO_PARENT_DELAY(_struct, _name, _reg, _bfreq, _bit_idx,	\
858c2ecf20Sopenharmony_ci		_shift, _width, _min_mul, _max_mul, _delay, _table,	\
868c2ecf20Sopenharmony_ci		_flags)							\
878c2ecf20Sopenharmony_ci	struct owl_pll _struct = {					\
888c2ecf20Sopenharmony_ci		.pll_hw	= OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift,	\
898c2ecf20Sopenharmony_ci				     _width, _min_mul,  _max_mul,	\
908c2ecf20Sopenharmony_ci				     _delay, _table),			\
918c2ecf20Sopenharmony_ci		.common = {						\
928c2ecf20Sopenharmony_ci			.regmap = NULL,					\
938c2ecf20Sopenharmony_ci			.hw.init = CLK_HW_INIT_NO_PARENT(_name,		\
948c2ecf20Sopenharmony_ci					       &owl_pll_ops,		\
958c2ecf20Sopenharmony_ci					       _flags),			\
968c2ecf20Sopenharmony_ci		},							\
978c2ecf20Sopenharmony_ci	}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci#define mul_mask(m)		((1 << ((m)->width)) - 1)
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_cistatic inline struct owl_pll *hw_to_owl_pll(const struct clk_hw *hw)
1028c2ecf20Sopenharmony_ci{
1038c2ecf20Sopenharmony_ci	struct owl_clk_common *common = hw_to_owl_clk_common(hw);
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	return container_of(common, struct owl_pll, common);
1068c2ecf20Sopenharmony_ci}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ciextern const struct clk_ops owl_pll_ops;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci#endif /* _OWL_PLL_H_ */
111