xref: /kernel/linux/linux-5.10/drivers/clk/sprd/div.h (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci//
38c2ecf20Sopenharmony_ci// Spreadtrum divider clock driver
48c2ecf20Sopenharmony_ci//
58c2ecf20Sopenharmony_ci// Copyright (C) 2017 Spreadtrum, Inc.
68c2ecf20Sopenharmony_ci// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef _SPRD_DIV_H_
98c2ecf20Sopenharmony_ci#define _SPRD_DIV_H_
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include "common.h"
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci/**
148c2ecf20Sopenharmony_ci * struct sprd_div_internal - Internal divider description
158c2ecf20Sopenharmony_ci * @shift: Bit offset of the divider in its register
168c2ecf20Sopenharmony_ci * @width: Width of the divider field in its register
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci * That structure represents a single divider, and is meant to be
198c2ecf20Sopenharmony_ci * embedded in other structures representing the various clock
208c2ecf20Sopenharmony_ci * classes.
218c2ecf20Sopenharmony_ci */
228c2ecf20Sopenharmony_cistruct sprd_div_internal {
238c2ecf20Sopenharmony_ci	u8	shift;
248c2ecf20Sopenharmony_ci	u8	width;
258c2ecf20Sopenharmony_ci};
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#define _SPRD_DIV_CLK(_shift, _width)	\
288c2ecf20Sopenharmony_ci	{				\
298c2ecf20Sopenharmony_ci		.shift	= _shift,	\
308c2ecf20Sopenharmony_ci		.width	= _width,	\
318c2ecf20Sopenharmony_ci	}
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cistruct sprd_div {
348c2ecf20Sopenharmony_ci	struct sprd_div_internal	div;
358c2ecf20Sopenharmony_ci	struct sprd_clk_common	common;
368c2ecf20Sopenharmony_ci};
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#define SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,		\
398c2ecf20Sopenharmony_ci				_shift, _width, _flags, _fn)		\
408c2ecf20Sopenharmony_ci	struct sprd_div _struct = {					\
418c2ecf20Sopenharmony_ci		.div	= _SPRD_DIV_CLK(_shift, _width),		\
428c2ecf20Sopenharmony_ci		.common	= {						\
438c2ecf20Sopenharmony_ci			.regmap		= NULL,				\
448c2ecf20Sopenharmony_ci			.reg		= _reg,				\
458c2ecf20Sopenharmony_ci			.hw.init	= _fn(_name, _parent,		\
468c2ecf20Sopenharmony_ci					      &sprd_div_ops, _flags),	\
478c2ecf20Sopenharmony_ci		}							\
488c2ecf20Sopenharmony_ci	}
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci#define SPRD_DIV_CLK(_struct, _name, _parent, _reg,			\
518c2ecf20Sopenharmony_ci		     _shift, _width, _flags)				\
528c2ecf20Sopenharmony_ci	SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,		\
538c2ecf20Sopenharmony_ci				_shift, _width, _flags, CLK_HW_INIT)
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci#define SPRD_DIV_CLK_HW(_struct, _name, _parent, _reg,			\
568c2ecf20Sopenharmony_ci			_shift, _width, _flags)				\
578c2ecf20Sopenharmony_ci	SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,		\
588c2ecf20Sopenharmony_ci				_shift, _width, _flags, CLK_HW_INIT_HW)
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_cistatic inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw)
618c2ecf20Sopenharmony_ci{
628c2ecf20Sopenharmony_ci	struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	return container_of(common, struct sprd_div, common);
658c2ecf20Sopenharmony_ci}
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_cilong sprd_div_helper_round_rate(struct sprd_clk_common *common,
688c2ecf20Sopenharmony_ci				const struct sprd_div_internal *div,
698c2ecf20Sopenharmony_ci				unsigned long rate,
708c2ecf20Sopenharmony_ci				unsigned long *parent_rate);
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ciunsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
738c2ecf20Sopenharmony_ci					  const struct sprd_div_internal *div,
748c2ecf20Sopenharmony_ci					  unsigned long parent_rate);
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ciint sprd_div_helper_set_rate(const struct sprd_clk_common *common,
778c2ecf20Sopenharmony_ci			     const struct sprd_div_internal *div,
788c2ecf20Sopenharmony_ci			     unsigned long rate,
798c2ecf20Sopenharmony_ci			     unsigned long parent_rate);
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ciextern const struct clk_ops sprd_div_ops;
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci#endif /* _SPRD_DIV_H_ */
84