162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// Spreadtrum gate clock driver
462306a36Sopenharmony_ci//
562306a36Sopenharmony_ci// Copyright (C) 2017 Spreadtrum, Inc.
662306a36Sopenharmony_ci// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifndef _SPRD_GATE_H_
962306a36Sopenharmony_ci#define _SPRD_GATE_H_
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include "common.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cistruct sprd_gate {
1462306a36Sopenharmony_ci	u32			enable_mask;
1562306a36Sopenharmony_ci	u16			flags;
1662306a36Sopenharmony_ci	u16			sc_offset;
1762306a36Sopenharmony_ci	u16			udelay;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci	struct sprd_clk_common	common;
2062306a36Sopenharmony_ci};
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/*
2362306a36Sopenharmony_ci * sprd_gate->flags is used for:
2462306a36Sopenharmony_ci * CLK_GATE_SET_TO_DISABLE	BIT(0)
2562306a36Sopenharmony_ci * CLK_GATE_HIWORD_MASK		BIT(1)
2662306a36Sopenharmony_ci * CLK_GATE_BIG_ENDIAN		BIT(2)
2762306a36Sopenharmony_ci * so we define new flags from	BIT(3)
2862306a36Sopenharmony_ci */
2962306a36Sopenharmony_ci#define SPRD_GATE_NON_AON BIT(3) /* not alway powered on, check before read */
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,	\
3262306a36Sopenharmony_ci				    _sc_offset, _enable_mask, _flags,	\
3362306a36Sopenharmony_ci				    _gate_flags, _udelay, _ops, _fn)	\
3462306a36Sopenharmony_ci	struct sprd_gate _struct = {					\
3562306a36Sopenharmony_ci		.enable_mask	= _enable_mask,				\
3662306a36Sopenharmony_ci		.sc_offset	= _sc_offset,				\
3762306a36Sopenharmony_ci		.flags		= _gate_flags,				\
3862306a36Sopenharmony_ci		.udelay		= _udelay,				\
3962306a36Sopenharmony_ci		.common	= {						\
4062306a36Sopenharmony_ci			.regmap		= NULL,				\
4162306a36Sopenharmony_ci			.reg		= _reg,				\
4262306a36Sopenharmony_ci			.hw.init	= _fn(_name, _parent,		\
4362306a36Sopenharmony_ci					      _ops, _flags),		\
4462306a36Sopenharmony_ci		}							\
4562306a36Sopenharmony_ci	}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#define SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg,	\
4862306a36Sopenharmony_ci				    _sc_offset, _enable_mask, _flags,	\
4962306a36Sopenharmony_ci				    _gate_flags, _udelay, _ops)		\
5062306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,	\
5162306a36Sopenharmony_ci				    _sc_offset, _enable_mask, _flags,	\
5262306a36Sopenharmony_ci				    _gate_flags, _udelay, _ops, CLK_HW_INIT)
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci#define SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset,	\
5562306a36Sopenharmony_ci			     _enable_mask, _flags, _gate_flags, _ops)	\
5662306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg,	\
5762306a36Sopenharmony_ci				    _sc_offset, _enable_mask, _flags,	\
5862306a36Sopenharmony_ci				    _gate_flags, 0, _ops)
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci#define SPRD_SC_GATE_CLK(_struct, _name, _parent, _reg, _sc_offset,	\
6162306a36Sopenharmony_ci			 _enable_mask, _flags, _gate_flags)		\
6262306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset,	\
6362306a36Sopenharmony_ci			     _enable_mask, _flags, _gate_flags,		\
6462306a36Sopenharmony_ci			     &sprd_sc_gate_ops)
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci#define SPRD_GATE_CLK(_struct, _name, _parent, _reg,			\
6762306a36Sopenharmony_ci		      _enable_mask, _flags, _gate_flags)		\
6862306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, 0,		\
6962306a36Sopenharmony_ci			     _enable_mask, _flags, _gate_flags,		\
7062306a36Sopenharmony_ci			     &sprd_gate_ops)
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci#define SPRD_PLL_SC_GATE_CLK(_struct, _name, _parent, _reg, _sc_offset,	\
7362306a36Sopenharmony_ci			     _enable_mask, _flags, _gate_flags,		\
7462306a36Sopenharmony_ci			     _udelay)					\
7562306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg,	\
7662306a36Sopenharmony_ci				    _sc_offset,	_enable_mask, _flags,	\
7762306a36Sopenharmony_ci				    _gate_flags, _udelay,		\
7862306a36Sopenharmony_ci				    &sprd_pll_sc_gate_ops)
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci#define SPRD_SC_GATE_CLK_HW_OPS_UDELAY(_struct, _name, _parent, _reg,	\
8262306a36Sopenharmony_ci				       _sc_offset, _enable_mask,	\
8362306a36Sopenharmony_ci				       _flags, _gate_flags,		\
8462306a36Sopenharmony_ci				       _udelay, _ops)			\
8562306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,	\
8662306a36Sopenharmony_ci				    _sc_offset, _enable_mask, _flags,	\
8762306a36Sopenharmony_ci				    _gate_flags, _udelay, _ops,		\
8862306a36Sopenharmony_ci				    CLK_HW_INIT_HW)
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci#define SPRD_SC_GATE_CLK_HW_OPS(_struct, _name, _parent, _reg,		\
9162306a36Sopenharmony_ci				_sc_offset, _enable_mask, _flags,	\
9262306a36Sopenharmony_ci				_gate_flags, _ops)			\
9362306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_HW_OPS_UDELAY(_struct, _name, _parent, _reg,	\
9462306a36Sopenharmony_ci				       _sc_offset, _enable_mask,	\
9562306a36Sopenharmony_ci				       _flags, _gate_flags, 0, _ops)
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci#define SPRD_SC_GATE_CLK_HW(_struct, _name, _parent, _reg,		\
9862306a36Sopenharmony_ci			    _sc_offset, _enable_mask, _flags,		\
9962306a36Sopenharmony_ci			    _gate_flags)				\
10062306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_HW_OPS(_struct, _name, _parent, _reg,		\
10162306a36Sopenharmony_ci				_sc_offset, _enable_mask, _flags,	\
10262306a36Sopenharmony_ci				_gate_flags, &sprd_sc_gate_ops)
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci#define SPRD_GATE_CLK_HW(_struct, _name, _parent, _reg,			\
10562306a36Sopenharmony_ci			 _enable_mask, _flags, _gate_flags)		\
10662306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_HW_OPS(_struct, _name, _parent, _reg, 0,	\
10762306a36Sopenharmony_ci				_enable_mask, _flags, _gate_flags,	\
10862306a36Sopenharmony_ci				&sprd_gate_ops)
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci#define SPRD_PLL_SC_GATE_CLK_HW(_struct, _name, _parent, _reg,		\
11162306a36Sopenharmony_ci				_sc_offset, _enable_mask, _flags,	\
11262306a36Sopenharmony_ci				_gate_flags, _udelay)			\
11362306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_HW_OPS_UDELAY(_struct, _name, _parent, _reg,	\
11462306a36Sopenharmony_ci				       _sc_offset, _enable_mask,	\
11562306a36Sopenharmony_ci				       _flags, _gate_flags, _udelay,	\
11662306a36Sopenharmony_ci				       &sprd_pll_sc_gate_ops)
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci#define SPRD_SC_GATE_CLK_FW_NAME_OPS_UDELAY(_struct, _name, _parent,	\
11962306a36Sopenharmony_ci					    _reg, _sc_offset,		\
12062306a36Sopenharmony_ci					    _enable_mask, _flags,	\
12162306a36Sopenharmony_ci					    _gate_flags, _udelay, _ops)	\
12262306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,	\
12362306a36Sopenharmony_ci				    _sc_offset, _enable_mask, _flags,	\
12462306a36Sopenharmony_ci				    _gate_flags, _udelay, _ops,		\
12562306a36Sopenharmony_ci				    CLK_HW_INIT_FW_NAME)
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci#define SPRD_SC_GATE_CLK_FW_NAME_OPS(_struct, _name, _parent, _reg,	\
12862306a36Sopenharmony_ci				     _sc_offset, _enable_mask, _flags,	\
12962306a36Sopenharmony_ci				     _gate_flags, _ops)			\
13062306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_FW_NAME_OPS_UDELAY(_struct, _name, _parent,	\
13162306a36Sopenharmony_ci					    _reg, _sc_offset,		\
13262306a36Sopenharmony_ci					    _enable_mask, _flags,	\
13362306a36Sopenharmony_ci					    _gate_flags, 0, _ops)
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci#define SPRD_SC_GATE_CLK_FW_NAME(_struct, _name, _parent, _reg,		\
13662306a36Sopenharmony_ci				 _sc_offset, _enable_mask, _flags,	\
13762306a36Sopenharmony_ci				 _gate_flags)				\
13862306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_FW_NAME_OPS(_struct, _name, _parent, _reg,	\
13962306a36Sopenharmony_ci				     _sc_offset, _enable_mask, _flags,	\
14062306a36Sopenharmony_ci				     _gate_flags, &sprd_sc_gate_ops)
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci#define SPRD_GATE_CLK_FW_NAME(_struct, _name, _parent, _reg,		\
14362306a36Sopenharmony_ci			      _enable_mask, _flags, _gate_flags)	\
14462306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_FW_NAME_OPS(_struct, _name, _parent, _reg, 0,	\
14562306a36Sopenharmony_ci				     _enable_mask, _flags, _gate_flags,	\
14662306a36Sopenharmony_ci				     &sprd_gate_ops)
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci#define SPRD_PLL_SC_GATE_CLK_FW_NAME(_struct, _name, _parent, _reg,	\
14962306a36Sopenharmony_ci				     _sc_offset, _enable_mask, _flags,	\
15062306a36Sopenharmony_ci				     _gate_flags, _udelay)		\
15162306a36Sopenharmony_ci	SPRD_SC_GATE_CLK_FW_NAME_OPS_UDELAY(_struct, _name, _parent,	\
15262306a36Sopenharmony_ci					    _reg, _sc_offset,		\
15362306a36Sopenharmony_ci					    _enable_mask, _flags,	\
15462306a36Sopenharmony_ci					    _gate_flags, _udelay,	\
15562306a36Sopenharmony_ci					    &sprd_pll_sc_gate_ops)
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_cistatic inline struct sprd_gate *hw_to_sprd_gate(const struct clk_hw *hw)
15862306a36Sopenharmony_ci{
15962306a36Sopenharmony_ci	struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	return container_of(common, struct sprd_gate, common);
16262306a36Sopenharmony_ci}
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ciextern const struct clk_ops sprd_gate_ops;
16562306a36Sopenharmony_ciextern const struct clk_ops sprd_sc_gate_ops;
16662306a36Sopenharmony_ciextern const struct clk_ops sprd_pll_sc_gate_ops;
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci#endif /* _SPRD_GATE_H_ */
169