brintos

brintos / linux-shallow public Read only

0
0
Text · 4.5 KiB · eb1172e Raw
167 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef _CCU_MUX_H_3#define _CCU_MUX_H_4 5#include <linux/clk-provider.h>6 7#include "ccu_common.h"8 9struct ccu_mux_fixed_prediv {10	u8	index;11	u16	div;12};13 14struct ccu_mux_var_prediv {15	u8	index;16	u8	shift;17	u8	width;18};19 20struct ccu_mux_internal {21	u8		shift;22	u8		width;23	const u8	*table;24 25	const struct ccu_mux_fixed_prediv	*fixed_predivs;26	u8		n_predivs;27 28	const struct ccu_mux_var_prediv		*var_predivs;29	u8		n_var_predivs;30};31 32#define _SUNXI_CCU_MUX_TABLE(_shift, _width, _table)	\33	{						\34		.shift	= _shift,			\35		.width	= _width,			\36		.table	= _table,			\37	}38 39#define _SUNXI_CCU_MUX(_shift, _width) \40	_SUNXI_CCU_MUX_TABLE(_shift, _width, NULL)41 42struct ccu_mux {43	u32			enable;44 45	struct ccu_mux_internal	mux;46	struct ccu_common	common;47};48 49#define SUNXI_CCU_MUX_TABLE_WITH_GATE_FEAT(_struct, _name, _parents, _table,	\50				     _reg, _shift, _width, _gate,		\51				     _flags, _features)				\52	struct ccu_mux _struct = {						\53		.enable	= _gate,						\54		.mux	= _SUNXI_CCU_MUX_TABLE(_shift, _width, _table),		\55		.common	= {							\56			.reg		= _reg,					\57			.hw.init	= CLK_HW_INIT_PARENTS(_name,		\58							      _parents,		\59							      &ccu_mux_ops,	\60							      _flags),		\61			.features	= _features,				\62		}								\63	}64 65#define SUNXI_CCU_MUX_TABLE_WITH_GATE_CLOSEST(_struct, _name, _parents,	\66					      _table, _reg, _shift,	\67					      _width, _gate, _flags)	\68	SUNXI_CCU_MUX_TABLE_WITH_GATE_FEAT(_struct, _name, _parents,	\69					   _table, _reg, _shift,	\70					   _width, _gate, _flags,	\71					   CCU_FEATURE_CLOSEST_RATE)72 73#define SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, _table,	\74				     _reg, _shift, _width, _gate,	\75				     _flags)				\76	SUNXI_CCU_MUX_TABLE_WITH_GATE_FEAT(_struct, _name, _parents,	\77					   _table, _reg, _shift,	\78					   _width, _gate, _flags, 0)79 80#define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg,		\81				_shift, _width, _gate, _flags)		\82	SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL,	\83				      _reg, _shift, _width, _gate,	\84				      _flags)85 86#define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width,	\87		      _flags)						\88	SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL,	\89				      _reg, _shift, _width, 0, _flags)90 91#define SUNXI_CCU_MUX_DATA_WITH_GATE(_struct, _name, _parents, _reg,	\92				     _shift, _width, _gate, _flags)	\93	struct ccu_mux _struct = {					\94		.enable	= _gate,					\95		.mux	= _SUNXI_CCU_MUX(_shift, _width),		\96		.common	= {						\97			.reg		= _reg,				\98			.hw.init	= CLK_HW_INIT_PARENTS_DATA(_name, \99								   _parents, \100								   &ccu_mux_ops, \101								   _flags), \102		}							\103	}104 105#define SUNXI_CCU_MUX_DATA(_struct, _name, _parents, _reg,		\106		      _shift, _width, _flags)				\107	SUNXI_CCU_MUX_DATA_WITH_GATE(_struct, _name, _parents, _reg,	\108				     _shift, _width, 0, _flags)109 110#define SUNXI_CCU_MUX_HW_WITH_GATE(_struct, _name, _parents, _reg,	\111				   _shift, _width, _gate, _flags)	\112	struct ccu_mux _struct = {					\113		.enable	= _gate,					\114		.mux	= _SUNXI_CCU_MUX(_shift, _width),		\115		.common	= {						\116			.reg		= _reg,				\117			.hw.init	= CLK_HW_INIT_PARENTS_HW(_name, \118								 _parents, \119								 &ccu_mux_ops, \120								 _flags), \121		}							\122	}123 124static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)125{126	struct ccu_common *common = hw_to_ccu_common(hw);127 128	return container_of(common, struct ccu_mux, common);129}130 131extern const struct clk_ops ccu_mux_ops;132 133unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,134					  struct ccu_mux_internal *cm,135					  int parent_index,136					  unsigned long parent_rate);137int ccu_mux_helper_determine_rate(struct ccu_common *common,138				  struct ccu_mux_internal *cm,139				  struct clk_rate_request *req,140				  unsigned long (*round)(struct ccu_mux_internal *,141							 struct clk_hw *,142							 unsigned long *,143							 unsigned long,144							 void *),145				  void *data);146u8 ccu_mux_helper_get_parent(struct ccu_common *common,147			     struct ccu_mux_internal *cm);148int ccu_mux_helper_set_parent(struct ccu_common *common,149			      struct ccu_mux_internal *cm,150			      u8 index);151 152struct ccu_mux_nb {153	struct notifier_block	clk_nb;154	struct ccu_common	*common;155	struct ccu_mux_internal	*cm;156 157	u32	delay_us;	/* How many us to wait after reparenting */158	u8	bypass_index;	/* Which parent to temporarily use */159	u8	original_index;	/* This is set by the notifier callback */160};161 162#define to_ccu_mux_nb(_nb) container_of(_nb, struct ccu_mux_nb, clk_nb)163 164int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb);165 166#endif /* _CCU_MUX_H_ */167