brintos

brintos / linux-shallow public Read only

0
0
Text · 7.9 KiB · 90d49ee Raw
287 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright (c) 2016 Maxime Ripard. All rights reserved.4 */5 6#ifndef _CCU_DIV_H_7#define _CCU_DIV_H_8 9#include <linux/clk-provider.h>10 11#include "ccu_common.h"12#include "ccu_mux.h"13 14/**15 * struct ccu_div_internal - Internal divider description16 * @shift: Bit offset of the divider in its register17 * @width: Width of the divider field in its register18 * @max: Maximum value allowed for that divider. This is the19 *       arithmetic value, not the maximum value to be set in the20 *       register.21 * @flags: clk_divider flags to apply on this divider22 * @table: Divider table pointer (if applicable)23 *24 * That structure represents a single divider, and is meant to be25 * embedded in other structures representing the various clock26 * classes.27 *28 * It is basically a wrapper around the clk_divider functions29 * arguments.30 */31struct ccu_div_internal {32	u8			shift;33	u8			width;34 35	u32			max;36	u32			offset;37 38	u32			flags;39 40	struct clk_div_table	*table;41};42 43#define _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, _flags)	\44	{								\45		.shift	= _shift,					\46		.width	= _width,					\47		.flags	= _flags,					\48		.table	= _table,					\49	}50 51#define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table)			\52	_SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)53 54#define _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _off, _max, _flags) \55	{								\56		.shift	= _shift,					\57		.width	= _width,					\58		.flags	= _flags,					\59		.max	= _max,						\60		.offset	= _off,						\61	}62 63#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags)		\64	_SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, 1, _max, _flags)65 66#define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags)			\67	_SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)68 69#define _SUNXI_CCU_DIV_MAX(_shift, _width, _max)			\70	_SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)71 72#define _SUNXI_CCU_DIV_OFFSET(_shift, _width, _offset)			\73	_SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _offset, 0, 0)74 75#define _SUNXI_CCU_DIV(_shift, _width)					\76	_SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)77 78struct ccu_div {79	u32			enable;80 81	struct ccu_div_internal	div;82	struct ccu_mux_internal	mux;83	struct ccu_common	common;84	unsigned int		fixed_post_div;85};86 87#define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg,	\88				      _shift, _width,			\89				      _table, _gate, _flags)		\90	struct ccu_div _struct = {					\91		.div		= _SUNXI_CCU_DIV_TABLE(_shift, _width,	\92						       _table),		\93		.enable		= _gate,				\94		.common	= {						\95			.reg		= _reg,				\96			.hw.init	= CLK_HW_INIT(_name,		\97						      _parent,		\98						      &ccu_div_ops,	\99						      _flags),		\100		}							\101	}102 103 104#define SUNXI_CCU_DIV_TABLE(_struct, _name, _parent, _reg,		\105			    _shift, _width,				\106			    _table, _flags)				\107	SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg,	\108				      _shift, _width, _table, 0,	\109				      _flags)110 111#define SUNXI_CCU_DIV_TABLE_HW(_struct, _name, _parent, _reg,		\112			       _shift, _width,				\113			       _table, _flags)				\114	struct ccu_div _struct = {					\115		.div		= _SUNXI_CCU_DIV_TABLE(_shift, _width,	\116						       _table),		\117		.common	= {						\118			.reg		= _reg,				\119			.hw.init	= CLK_HW_INIT_HW(_name,		\120							 _parent,	\121							 &ccu_div_ops,	\122							 _flags),	\123		}							\124	}125 126 127#define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,			\128					_parents, _table,		\129					_reg,				\130					_mshift, _mwidth,		\131					_muxshift, _muxwidth,		\132					_gate, _flags)			\133	struct ccu_div _struct = {					\134		.enable	= _gate,					\135		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\136		.mux	= _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \137		.common	= {						\138			.reg		= _reg,				\139			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\140							      _parents, \141							      &ccu_div_ops, \142							      _flags),	\143		},							\144	}145 146#define SUNXI_CCU_M_WITH_MUX_TABLE_GATE_CLOSEST(_struct, _name,		\147						_parents, _table,	\148						_reg,			\149						_mshift, _mwidth,	\150						_muxshift, _muxwidth,	\151						_gate, _flags)		\152	struct ccu_div _struct = {					\153		.enable	= _gate,					\154		.div	= _SUNXI_CCU_DIV_FLAGS(_mshift, _mwidth, CLK_DIVIDER_ROUND_CLOSEST), \155		.mux	= _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \156		.common	= {						\157			.reg		= _reg,				\158			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\159							      _parents, \160							      &ccu_div_ops, \161							      _flags),	\162			.features	= CCU_FEATURE_CLOSEST_RATE,	\163		},							\164	}165 166#define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\167				  _mshift, _mwidth, _muxshift, _muxwidth, \168				  _gate, _flags)			\169	SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,			\170					_parents, NULL,			\171					_reg, _mshift, _mwidth,		\172					_muxshift, _muxwidth,		\173					_gate, _flags)174 175#define SUNXI_CCU_M_WITH_MUX_GATE_CLOSEST(_struct, _name, _parents,	\176					  _reg, _mshift, _mwidth,	\177					  _muxshift, _muxwidth,		\178					  _gate, _flags)		\179	SUNXI_CCU_M_WITH_MUX_TABLE_GATE_CLOSEST(_struct, _name,		\180						_parents, NULL,		\181						_reg, _mshift, _mwidth,	\182						_muxshift, _muxwidth,	\183						_gate, _flags)184 185#define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg,		\186			     _mshift, _mwidth, _muxshift, _muxwidth,	\187			     _flags)					\188	SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,			\189					_parents, NULL,			\190					_reg, _mshift, _mwidth,		\191					_muxshift, _muxwidth,		\192					0, _flags)193 194 195#define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg,		\196			      _mshift, _mwidth,	_gate,			\197			      _flags)					\198	struct ccu_div _struct = {					\199		.enable	= _gate,					\200		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\201		.common	= {						\202			.reg		= _reg,				\203			.hw.init	= CLK_HW_INIT(_name,		\204						      _parent,		\205						      &ccu_div_ops,	\206						      _flags),		\207		},							\208	}209 210#define SUNXI_CCU_M(_struct, _name, _parent, _reg, _mshift, _mwidth,	\211		    _flags)						\212	SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg,		\213			      _mshift, _mwidth, 0, _flags)214 215#define SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\216				       _mshift, _mwidth,		\217				       _muxshift, _muxwidth,		\218				       _gate, _flags)			\219	struct ccu_div _struct = {					\220		.enable	= _gate,					\221		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\222		.mux	= _SUNXI_CCU_MUX(_muxshift, _muxwidth),		\223		.common	= {						\224			.reg		= _reg,				\225			.hw.init	= CLK_HW_INIT_PARENTS_DATA(_name, \226								   _parents, \227								   &ccu_div_ops, \228								   _flags), \229		},							\230	}231 232#define SUNXI_CCU_M_DATA_WITH_MUX(_struct, _name, _parents, _reg,	\233				  _mshift, _mwidth,			\234				  _muxshift, _muxwidth,			\235				  _flags)				\236	SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg,  \237				       _mshift, _mwidth,		\238				       _muxshift, _muxwidth,		\239				       0, _flags)240 241#define SUNXI_CCU_M_HW_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\242				     _mshift, _mwidth, _muxshift, _muxwidth, \243				     _gate, _flags)			\244	struct ccu_div _struct = {					\245		.enable	= _gate,					\246		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\247		.mux	= _SUNXI_CCU_MUX(_muxshift, _muxwidth),		\248		.common	= {						\249			.reg		= _reg,				\250			.hw.init	= CLK_HW_INIT_PARENTS_HW(_name,	\251								 _parents, \252								 &ccu_div_ops, \253								 _flags), \254		},							\255	}256 257#define SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg,	\258				  _mshift, _mwidth, _gate,		\259				  _flags)				\260	struct ccu_div _struct = {					\261		.enable	= _gate,					\262		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\263		.common	= {						\264			.reg		= _reg,				\265			.hw.init	= CLK_HW_INIT_HWS(_name,	\266							  _parent,	\267							  &ccu_div_ops,	\268							  _flags),	\269		},							\270	}271 272#define SUNXI_CCU_M_HWS(_struct, _name, _parent, _reg, _mshift,		\273			_mwidth, _flags)				\274	SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg,	\275				  _mshift, _mwidth, 0, _flags)276 277static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)278{279	struct ccu_common *common = hw_to_ccu_common(hw);280 281	return container_of(common, struct ccu_div, common);282}283 284extern const struct clk_ops ccu_div_ops;285 286#endif /* _CCU_DIV_H_ */287