162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// OWL pll clock driver
462306a36Sopenharmony_ci//
562306a36Sopenharmony_ci// Copyright (c) 2014 Actions Semi Inc.
662306a36Sopenharmony_ci// Author: David Liu <liuwei@actions-semi.com>
762306a36Sopenharmony_ci//
862306a36Sopenharmony_ci// Copyright (c) 2018 Linaro Ltd.
962306a36Sopenharmony_ci// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifndef _OWL_PLL_H_
1262306a36Sopenharmony_ci#define _OWL_PLL_H_
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include "owl-common.h"
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define OWL_PLL_DEF_DELAY	50
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* last entry should have rate = 0 */
1962306a36Sopenharmony_cistruct clk_pll_table {
2062306a36Sopenharmony_ci	unsigned int		val;
2162306a36Sopenharmony_ci	unsigned long		rate;
2262306a36Sopenharmony_ci};
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistruct owl_pll_hw {
2562306a36Sopenharmony_ci	u32			reg;
2662306a36Sopenharmony_ci	u32			bfreq;
2762306a36Sopenharmony_ci	u8			bit_idx;
2862306a36Sopenharmony_ci	u8			shift;
2962306a36Sopenharmony_ci	u8			width;
3062306a36Sopenharmony_ci	u8			min_mul;
3162306a36Sopenharmony_ci	u8			max_mul;
3262306a36Sopenharmony_ci	u8			delay;
3362306a36Sopenharmony_ci	const struct clk_pll_table *table;
3462306a36Sopenharmony_ci};
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cistruct owl_pll {
3762306a36Sopenharmony_ci	struct owl_pll_hw	pll_hw;
3862306a36Sopenharmony_ci	struct owl_clk_common	common;
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#define OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift,			\
4262306a36Sopenharmony_ci		   _width, _min_mul, _max_mul, _delay, _table)		\
4362306a36Sopenharmony_ci	{								\
4462306a36Sopenharmony_ci		.reg		= _reg,					\
4562306a36Sopenharmony_ci		.bfreq		= _bfreq,				\
4662306a36Sopenharmony_ci		.bit_idx	= _bit_idx,				\
4762306a36Sopenharmony_ci		.shift		= _shift,				\
4862306a36Sopenharmony_ci		.width		= _width,				\
4962306a36Sopenharmony_ci		.min_mul	= _min_mul,				\
5062306a36Sopenharmony_ci		.max_mul	= _max_mul,				\
5162306a36Sopenharmony_ci		.delay		= _delay,				\
5262306a36Sopenharmony_ci		.table		= _table,				\
5362306a36Sopenharmony_ci	}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci#define OWL_PLL(_struct, _name, _parent, _reg, _bfreq, _bit_idx,	\
5662306a36Sopenharmony_ci		_shift, _width, _min_mul, _max_mul, _table, _flags)	\
5762306a36Sopenharmony_ci	struct owl_pll _struct = {					\
5862306a36Sopenharmony_ci		.pll_hw	= OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift,	\
5962306a36Sopenharmony_ci				     _width, _min_mul, _max_mul,	\
6062306a36Sopenharmony_ci				     OWL_PLL_DEF_DELAY,	_table),	\
6162306a36Sopenharmony_ci		.common = {						\
6262306a36Sopenharmony_ci			.regmap = NULL,					\
6362306a36Sopenharmony_ci			.hw.init = CLK_HW_INIT(_name,			\
6462306a36Sopenharmony_ci					       _parent,			\
6562306a36Sopenharmony_ci					       &owl_pll_ops,		\
6662306a36Sopenharmony_ci					       _flags),			\
6762306a36Sopenharmony_ci		},							\
6862306a36Sopenharmony_ci	}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci#define OWL_PLL_NO_PARENT(_struct, _name, _reg, _bfreq, _bit_idx,	\
7162306a36Sopenharmony_ci		_shift, _width, _min_mul, _max_mul, _table, _flags)	\
7262306a36Sopenharmony_ci	struct owl_pll _struct = {					\
7362306a36Sopenharmony_ci		.pll_hw	= OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift,	\
7462306a36Sopenharmony_ci				     _width, _min_mul, _max_mul,	\
7562306a36Sopenharmony_ci				     OWL_PLL_DEF_DELAY,	_table),	\
7662306a36Sopenharmony_ci		.common = {						\
7762306a36Sopenharmony_ci			.regmap = NULL,					\
7862306a36Sopenharmony_ci			.hw.init = CLK_HW_INIT_NO_PARENT(_name,		\
7962306a36Sopenharmony_ci					       &owl_pll_ops,		\
8062306a36Sopenharmony_ci					       _flags),			\
8162306a36Sopenharmony_ci		},							\
8262306a36Sopenharmony_ci	}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci#define OWL_PLL_NO_PARENT_DELAY(_struct, _name, _reg, _bfreq, _bit_idx,	\
8562306a36Sopenharmony_ci		_shift, _width, _min_mul, _max_mul, _delay, _table,	\
8662306a36Sopenharmony_ci		_flags)							\
8762306a36Sopenharmony_ci	struct owl_pll _struct = {					\
8862306a36Sopenharmony_ci		.pll_hw	= OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift,	\
8962306a36Sopenharmony_ci				     _width, _min_mul,  _max_mul,	\
9062306a36Sopenharmony_ci				     _delay, _table),			\
9162306a36Sopenharmony_ci		.common = {						\
9262306a36Sopenharmony_ci			.regmap = NULL,					\
9362306a36Sopenharmony_ci			.hw.init = CLK_HW_INIT_NO_PARENT(_name,		\
9462306a36Sopenharmony_ci					       &owl_pll_ops,		\
9562306a36Sopenharmony_ci					       _flags),			\
9662306a36Sopenharmony_ci		},							\
9762306a36Sopenharmony_ci	}
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci#define mul_mask(m)		((1 << ((m)->width)) - 1)
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_cistatic inline struct owl_pll *hw_to_owl_pll(const struct clk_hw *hw)
10262306a36Sopenharmony_ci{
10362306a36Sopenharmony_ci	struct owl_clk_common *common = hw_to_owl_clk_common(hw);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	return container_of(common, struct owl_pll, common);
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ciextern const struct clk_ops owl_pll_ops;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci#endif /* _OWL_PLL_H_ */
111