brintos

brintos / linux-shallow public Read only

0
0
Text · 6.7 KiB · c17fe1c Raw
250 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright (c) 2014 MediaTek Inc.4 * Author: James Liao <jamesjj.liao@mediatek.com>5 */6 7#ifndef __DRV_CLK_MTK_H8#define __DRV_CLK_MTK_H9 10#include <linux/clk-provider.h>11#include <linux/io.h>12#include <linux/kernel.h>13#include <linux/spinlock.h>14#include <linux/types.h>15 16#include "reset.h"17 18#define MAX_MUX_GATE_BIT	3119#define INVALID_MUX_GATE_BIT	(MAX_MUX_GATE_BIT + 1)20 21#define MHZ (1000 * 1000)22 23struct platform_device;24 25/*26 * We need the clock IDs to start from zero but to maintain devicetree27 * backwards compatibility we can't change bindings to start from zero.28 * Only a few platforms are affected, so we solve issues given by the29 * commonized MTK clocks probe function(s) by adding a dummy clock at30 * the beginning where needed.31 */32#define CLK_DUMMY		033 34extern const struct clk_ops mtk_clk_dummy_ops;35extern const struct mtk_gate_regs cg_regs_dummy;36 37#define GATE_DUMMY(_id, _name) {				\38		.id = _id,					\39		.name = _name,					\40		.regs = &cg_regs_dummy,				\41		.ops = &mtk_clk_dummy_ops,			\42	}43 44struct mtk_fixed_clk {45	int id;46	const char *name;47	const char *parent;48	unsigned long rate;49};50 51#define FIXED_CLK(_id, _name, _parent, _rate) {		\52		.id = _id,				\53		.name = _name,				\54		.parent = _parent,			\55		.rate = _rate,				\56	}57 58int mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,59				struct clk_hw_onecell_data *clk_data);60void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,61				   struct clk_hw_onecell_data *clk_data);62 63struct mtk_fixed_factor {64	int id;65	const char *name;66	const char *parent_name;67	int mult;68	int div;69	unsigned long flags;70};71 72#define FACTOR_FLAGS(_id, _name, _parent, _mult, _div, _fl) {	\73		.id = _id,				\74		.name = _name,				\75		.parent_name = _parent,			\76		.mult = _mult,				\77		.div = _div,				\78		.flags = _fl,				\79	}80 81#define FACTOR(_id, _name, _parent, _mult, _div)	\82	FACTOR_FLAGS(_id, _name, _parent, _mult, _div, CLK_SET_RATE_PARENT)83 84int mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,85			     struct clk_hw_onecell_data *clk_data);86void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,87				struct clk_hw_onecell_data *clk_data);88 89struct mtk_composite {90	int id;91	const char *name;92	const char * const *parent_names;93	const char *parent;94	unsigned flags;95 96	uint32_t mux_reg;97	uint32_t divider_reg;98	uint32_t gate_reg;99 100	signed char mux_shift;101	signed char mux_width;102	signed char gate_shift;103 104	signed char divider_shift;105	signed char divider_width;106 107	u8 mux_flags;108 109	signed char num_parents;110};111 112#define MUX_GATE_FLAGS_2(_id, _name, _parents, _reg, _shift,		\113				_width, _gate, _flags, _muxflags) {	\114		.id = _id,						\115		.name = _name,						\116		.mux_reg = _reg,					\117		.mux_shift = _shift,					\118		.mux_width = _width,					\119		.gate_reg = _reg,					\120		.gate_shift = _gate,					\121		.divider_shift = -1,					\122		.parent_names = _parents,				\123		.num_parents = ARRAY_SIZE(_parents),			\124		.flags = _flags,					\125		.mux_flags = _muxflags,					\126	}127 128/*129 * In case the rate change propagation to parent clocks is undesirable,130 * this macro allows to specify the clock flags manually.131 */132#define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width,	\133			_gate, _flags)					\134		MUX_GATE_FLAGS_2(_id, _name, _parents, _reg,		\135					_shift, _width, _gate, _flags, 0)136 137/*138 * Unless necessary, all MUX_GATE clocks propagate rate changes to their139 * parent clock by default.140 */141#define MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate)	\142	MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width,	\143		_gate, CLK_SET_RATE_PARENT)144 145#define MUX(_id, _name, _parents, _reg, _shift, _width)			\146	MUX_FLAGS(_id, _name, _parents, _reg,				\147		  _shift, _width, CLK_SET_RATE_PARENT)148 149#define MUX_FLAGS(_id, _name, _parents, _reg, _shift, _width, _flags) {	\150		.id = _id,						\151		.name = _name,						\152		.mux_reg = _reg,					\153		.mux_shift = _shift,					\154		.mux_width = _width,					\155		.gate_shift = -1,					\156		.divider_shift = -1,					\157		.parent_names = _parents,				\158		.num_parents = ARRAY_SIZE(_parents),			\159		.flags = _flags,				\160	}161 162#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg,	\163					_div_width, _div_shift) {	\164		.id = _id,						\165		.parent = _parent,					\166		.name = _name,						\167		.divider_reg = _div_reg,				\168		.divider_shift = _div_shift,				\169		.divider_width = _div_width,				\170		.gate_reg = _gate_reg,					\171		.gate_shift = _gate_shift,				\172		.mux_shift = -1,					\173		.flags = 0,						\174	}175 176int mtk_clk_register_composites(struct device *dev,177				const struct mtk_composite *mcs, int num,178				void __iomem *base, spinlock_t *lock,179				struct clk_hw_onecell_data *clk_data);180void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,181				   struct clk_hw_onecell_data *clk_data);182 183struct mtk_clk_divider {184	int id;185	const char *name;186	const char *parent_name;187	unsigned long flags;188 189	u32 div_reg;190	unsigned char div_shift;191	unsigned char div_width;192	unsigned char clk_divider_flags;193	const struct clk_div_table *clk_div_table;194};195 196#define DIV_ADJ(_id, _name, _parent, _reg, _shift, _width) {	\197		.id = _id,					\198		.name = _name,					\199		.parent_name = _parent,				\200		.div_reg = _reg,				\201		.div_shift = _shift,				\202		.div_width = _width,				\203}204 205int mtk_clk_register_dividers(struct device *dev,206			      const struct mtk_clk_divider *mcds, int num,207			      void __iomem *base, spinlock_t *lock,208			      struct clk_hw_onecell_data *clk_data);209void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,210				 struct clk_hw_onecell_data *clk_data);211 212struct clk_hw_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);213struct clk_hw_onecell_data *mtk_devm_alloc_clk_data(struct device *dev,214						    unsigned int clk_num);215void mtk_free_clk_data(struct clk_hw_onecell_data *clk_data);216 217struct clk_hw *mtk_clk_register_ref2usb_tx(const char *name,218			const char *parent_name, void __iomem *reg);219void mtk_clk_unregister_ref2usb_tx(struct clk_hw *hw);220 221struct mtk_clk_desc {222	const struct mtk_gate *clks;223	size_t num_clks;224	const struct mtk_composite *composite_clks;225	size_t num_composite_clks;226	const struct mtk_clk_divider *divider_clks;227	size_t num_divider_clks;228	const struct mtk_fixed_clk *fixed_clks;229	size_t num_fixed_clks;230	const struct mtk_fixed_factor *factor_clks;231	size_t num_factor_clks;232	const struct mtk_mux *mux_clks;233	size_t num_mux_clks;234	const struct mtk_clk_rst_desc *rst_desc;235	spinlock_t *clk_lock;236	bool shared_io;237 238	int (*clk_notifier_func)(struct device *dev, struct clk *clk);239	unsigned int mfg_clk_idx;240 241	bool need_runtime_pm;242};243 244int mtk_clk_pdev_probe(struct platform_device *pdev);245void mtk_clk_pdev_remove(struct platform_device *pdev);246int mtk_clk_simple_probe(struct platform_device *pdev);247void mtk_clk_simple_remove(struct platform_device *pdev);248 249#endif /* __DRV_CLK_MTK_H */250