162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// OWL divider 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_DIVIDER_H_
1262306a36Sopenharmony_ci#define _OWL_DIVIDER_H_
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include "owl-common.h"
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistruct owl_divider_hw {
1762306a36Sopenharmony_ci	u32			reg;
1862306a36Sopenharmony_ci	u8			shift;
1962306a36Sopenharmony_ci	u8			width;
2062306a36Sopenharmony_ci	u8			div_flags;
2162306a36Sopenharmony_ci	struct clk_div_table	*table;
2262306a36Sopenharmony_ci};
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistruct owl_divider {
2562306a36Sopenharmony_ci	struct owl_divider_hw	div_hw;
2662306a36Sopenharmony_ci	struct owl_clk_common	common;
2762306a36Sopenharmony_ci};
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#define OWL_DIVIDER_HW(_reg, _shift, _width, _div_flags, _table)	\
3062306a36Sopenharmony_ci	{								\
3162306a36Sopenharmony_ci		.reg		= _reg,					\
3262306a36Sopenharmony_ci		.shift		= _shift,				\
3362306a36Sopenharmony_ci		.width		= _width,				\
3462306a36Sopenharmony_ci		.div_flags	= _div_flags,				\
3562306a36Sopenharmony_ci		.table		= _table,				\
3662306a36Sopenharmony_ci	}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define OWL_DIVIDER(_struct, _name, _parent, _reg,			\
3962306a36Sopenharmony_ci		    _shift, _width, _table, _div_flags, _flags)		\
4062306a36Sopenharmony_ci	struct owl_divider _struct = {					\
4162306a36Sopenharmony_ci		.div_hw	= OWL_DIVIDER_HW(_reg, _shift, _width,		\
4262306a36Sopenharmony_ci					 _div_flags, _table),		\
4362306a36Sopenharmony_ci		.common = {						\
4462306a36Sopenharmony_ci			.regmap		= NULL,				\
4562306a36Sopenharmony_ci			.hw.init	= CLK_HW_INIT(_name,		\
4662306a36Sopenharmony_ci						      _parent,		\
4762306a36Sopenharmony_ci						      &owl_divider_ops,	\
4862306a36Sopenharmony_ci						      _flags),		\
4962306a36Sopenharmony_ci		},							\
5062306a36Sopenharmony_ci	}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistatic inline struct owl_divider *hw_to_owl_divider(const struct clk_hw *hw)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	struct owl_clk_common *common = hw_to_owl_clk_common(hw);
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	return container_of(common, struct owl_divider, common);
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cilong owl_divider_helper_round_rate(struct owl_clk_common *common,
6062306a36Sopenharmony_ci				const struct owl_divider_hw *div_hw,
6162306a36Sopenharmony_ci				unsigned long rate,
6262306a36Sopenharmony_ci				unsigned long *parent_rate);
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ciunsigned long owl_divider_helper_recalc_rate(struct owl_clk_common *common,
6562306a36Sopenharmony_ci					 const struct owl_divider_hw *div_hw,
6662306a36Sopenharmony_ci					 unsigned long parent_rate);
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ciint owl_divider_helper_set_rate(const struct owl_clk_common *common,
6962306a36Sopenharmony_ci				const struct owl_divider_hw *div_hw,
7062306a36Sopenharmony_ci				unsigned long rate,
7162306a36Sopenharmony_ci				unsigned long parent_rate);
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ciextern const struct clk_ops owl_divider_ops;
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci#endif /* _OWL_DIVIDER_H_ */
76