cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

clk.h (11999B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
      4 * Copyright (c) 2013 Linaro Ltd.
      5 * Author: Thomas Abraham <thomas.ab@samsung.com>
      6 *
      7 * Common Clock Framework support for all Samsung platforms
      8*/
      9
     10#ifndef __SAMSUNG_CLK_H
     11#define __SAMSUNG_CLK_H
     12
     13#include <linux/clk-provider.h>
     14#include "clk-pll.h"
     15
     16/**
     17 * struct samsung_clk_provider: information about clock provider
     18 * @reg_base: virtual address for the register base.
     19 * @lock: maintains exclusion between callbacks for a given clock-provider.
     20 * @clk_data: holds clock related data like clk_hw* and number of clocks.
     21 */
     22struct samsung_clk_provider {
     23	void __iomem *reg_base;
     24	struct device *dev;
     25	spinlock_t lock;
     26	/* clk_data must be the last entry due to variable length 'hws' array */
     27	struct clk_hw_onecell_data clk_data;
     28};
     29
     30/**
     31 * struct samsung_clock_alias: information about mux clock
     32 * @id: platform specific id of the clock.
     33 * @dev_name: name of the device to which this clock belongs.
     34 * @alias: optional clock alias name to be assigned to this clock.
     35 */
     36struct samsung_clock_alias {
     37	unsigned int		id;
     38	const char		*dev_name;
     39	const char		*alias;
     40};
     41
     42#define ALIAS(_id, dname, a)	\
     43	{							\
     44		.id		= _id,				\
     45		.dev_name	= dname,			\
     46		.alias		= a,				\
     47	}
     48
     49#define MHZ (1000 * 1000)
     50
     51/**
     52 * struct samsung_fixed_rate_clock: information about fixed-rate clock
     53 * @id: platform specific id of the clock.
     54 * @name: name of this fixed-rate clock.
     55 * @parent_name: optional parent clock name.
     56 * @flags: optional fixed-rate clock flags.
     57 * @fixed-rate: fixed clock rate of this clock.
     58 */
     59struct samsung_fixed_rate_clock {
     60	unsigned int		id;
     61	char			*name;
     62	const char		*parent_name;
     63	unsigned long		flags;
     64	unsigned long		fixed_rate;
     65};
     66
     67#define FRATE(_id, cname, pname, f, frate)		\
     68	{						\
     69		.id		= _id,			\
     70		.name		= cname,		\
     71		.parent_name	= pname,		\
     72		.flags		= f,			\
     73		.fixed_rate	= frate,		\
     74	}
     75
     76/*
     77 * struct samsung_fixed_factor_clock: information about fixed-factor clock
     78 * @id: platform specific id of the clock.
     79 * @name: name of this fixed-factor clock.
     80 * @parent_name: parent clock name.
     81 * @mult: fixed multiplication factor.
     82 * @div: fixed division factor.
     83 * @flags: optional fixed-factor clock flags.
     84 */
     85struct samsung_fixed_factor_clock {
     86	unsigned int		id;
     87	char			*name;
     88	const char		*parent_name;
     89	unsigned long		mult;
     90	unsigned long		div;
     91	unsigned long		flags;
     92};
     93
     94#define FFACTOR(_id, cname, pname, m, d, f)		\
     95	{						\
     96		.id		= _id,			\
     97		.name		= cname,		\
     98		.parent_name	= pname,		\
     99		.mult		= m,			\
    100		.div		= d,			\
    101		.flags		= f,			\
    102	}
    103
    104/**
    105 * struct samsung_mux_clock: information about mux clock
    106 * @id: platform specific id of the clock.
    107 * @name: name of this mux clock.
    108 * @parent_names: array of pointer to parent clock names.
    109 * @num_parents: number of parents listed in @parent_names.
    110 * @flags: optional flags for basic clock.
    111 * @offset: offset of the register for configuring the mux.
    112 * @shift: starting bit location of the mux control bit-field in @reg.
    113 * @width: width of the mux control bit-field in @reg.
    114 * @mux_flags: flags for mux-type clock.
    115 */
    116struct samsung_mux_clock {
    117	unsigned int		id;
    118	const char		*name;
    119	const char		*const *parent_names;
    120	u8			num_parents;
    121	unsigned long		flags;
    122	unsigned long		offset;
    123	u8			shift;
    124	u8			width;
    125	u8			mux_flags;
    126};
    127
    128#define __MUX(_id, cname, pnames, o, s, w, f, mf)		\
    129	{							\
    130		.id		= _id,				\
    131		.name		= cname,			\
    132		.parent_names	= pnames,			\
    133		.num_parents	= ARRAY_SIZE(pnames),		\
    134		.flags		= (f) | CLK_SET_RATE_NO_REPARENT, \
    135		.offset		= o,				\
    136		.shift		= s,				\
    137		.width		= w,				\
    138		.mux_flags	= mf,				\
    139	}
    140
    141#define MUX(_id, cname, pnames, o, s, w)			\
    142	__MUX(_id, cname, pnames, o, s, w, 0, 0)
    143
    144#define MUX_F(_id, cname, pnames, o, s, w, f, mf)		\
    145	__MUX(_id, cname, pnames, o, s, w, f, mf)
    146
    147/**
    148 * @id: platform specific id of the clock.
    149 * struct samsung_div_clock: information about div clock
    150 * @name: name of this div clock.
    151 * @parent_name: name of the parent clock.
    152 * @flags: optional flags for basic clock.
    153 * @offset: offset of the register for configuring the div.
    154 * @shift: starting bit location of the div control bit-field in @reg.
    155 * @div_flags: flags for div-type clock.
    156 */
    157struct samsung_div_clock {
    158	unsigned int		id;
    159	const char		*name;
    160	const char		*parent_name;
    161	unsigned long		flags;
    162	unsigned long		offset;
    163	u8			shift;
    164	u8			width;
    165	u8			div_flags;
    166	struct clk_div_table	*table;
    167};
    168
    169#define __DIV(_id, cname, pname, o, s, w, f, df, t)	\
    170	{							\
    171		.id		= _id,				\
    172		.name		= cname,			\
    173		.parent_name	= pname,			\
    174		.flags		= f,				\
    175		.offset		= o,				\
    176		.shift		= s,				\
    177		.width		= w,				\
    178		.div_flags	= df,				\
    179		.table		= t,				\
    180	}
    181
    182#define DIV(_id, cname, pname, o, s, w)				\
    183	__DIV(_id, cname, pname, o, s, w, 0, 0, NULL)
    184
    185#define DIV_F(_id, cname, pname, o, s, w, f, df)		\
    186	__DIV(_id, cname, pname, o, s, w, f, df, NULL)
    187
    188#define DIV_T(_id, cname, pname, o, s, w, t)			\
    189	__DIV(_id, cname, pname, o, s, w, 0, 0, t)
    190
    191/**
    192 * struct samsung_gate_clock: information about gate clock
    193 * @id: platform specific id of the clock.
    194 * @name: name of this gate clock.
    195 * @parent_name: name of the parent clock.
    196 * @flags: optional flags for basic clock.
    197 * @offset: offset of the register for configuring the gate.
    198 * @bit_idx: bit index of the gate control bit-field in @reg.
    199 * @gate_flags: flags for gate-type clock.
    200 */
    201struct samsung_gate_clock {
    202	unsigned int		id;
    203	const char		*name;
    204	const char		*parent_name;
    205	unsigned long		flags;
    206	unsigned long		offset;
    207	u8			bit_idx;
    208	u8			gate_flags;
    209};
    210
    211#define __GATE(_id, cname, pname, o, b, f, gf)			\
    212	{							\
    213		.id		= _id,				\
    214		.name		= cname,			\
    215		.parent_name	= pname,			\
    216		.flags		= f,				\
    217		.offset		= o,				\
    218		.bit_idx	= b,				\
    219		.gate_flags	= gf,				\
    220	}
    221
    222#define GATE(_id, cname, pname, o, b, f, gf)			\
    223	__GATE(_id, cname, pname, o, b, f, gf)
    224
    225#define PNAME(x) static const char * const x[] __initconst
    226
    227/**
    228 * struct samsung_clk_reg_dump: register dump of clock controller registers.
    229 * @offset: clock register offset from the controller base address.
    230 * @value: the value to be register at offset.
    231 */
    232struct samsung_clk_reg_dump {
    233	u32	offset;
    234	u32	value;
    235};
    236
    237/**
    238 * struct samsung_pll_clock: information about pll clock
    239 * @id: platform specific id of the clock.
    240 * @name: name of this pll clock.
    241 * @parent_name: name of the parent clock.
    242 * @flags: optional flags for basic clock.
    243 * @con_offset: offset of the register for configuring the PLL.
    244 * @lock_offset: offset of the register for locking the PLL.
    245 * @type: Type of PLL to be registered.
    246 */
    247struct samsung_pll_clock {
    248	unsigned int		id;
    249	const char		*name;
    250	const char		*parent_name;
    251	unsigned long		flags;
    252	int			con_offset;
    253	int			lock_offset;
    254	enum samsung_pll_type	type;
    255	const struct samsung_pll_rate_table *rate_table;
    256};
    257
    258#define __PLL(_typ, _id, _name, _pname, _flags, _lock, _con, _rtable)	\
    259	{								\
    260		.id		= _id,					\
    261		.type		= _typ,					\
    262		.name		= _name,				\
    263		.parent_name	= _pname,				\
    264		.flags		= _flags,				\
    265		.con_offset	= _con,					\
    266		.lock_offset	= _lock,				\
    267		.rate_table	= _rtable,				\
    268	}
    269
    270#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable)	\
    271	__PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock,	\
    272	      _con, _rtable)
    273
    274struct samsung_cpu_clock {
    275	unsigned int	id;
    276	const char	*name;
    277	unsigned int	parent_id;
    278	unsigned int	alt_parent_id;
    279	unsigned long	flags;
    280	int		offset;
    281	const struct exynos_cpuclk_cfg_data *cfg;
    282};
    283
    284#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _cfg) \
    285	{							\
    286		.id		  = _id,			\
    287		.name		  = _name,			\
    288		.parent_id	  = _pid,			\
    289		.alt_parent_id	  = _apid,			\
    290		.flags		  = _flags,			\
    291		.offset		  = _offset,			\
    292		.cfg		  = _cfg,			\
    293	}
    294
    295struct samsung_clock_reg_cache {
    296	struct list_head node;
    297	void __iomem *reg_base;
    298	struct samsung_clk_reg_dump *rdump;
    299	unsigned int rd_num;
    300	const struct samsung_clk_reg_dump *rsuspend;
    301	unsigned int rsuspend_num;
    302};
    303
    304struct samsung_cmu_info {
    305	/* list of pll clocks and respective count */
    306	const struct samsung_pll_clock *pll_clks;
    307	unsigned int nr_pll_clks;
    308	/* list of mux clocks and respective count */
    309	const struct samsung_mux_clock *mux_clks;
    310	unsigned int nr_mux_clks;
    311	/* list of div clocks and respective count */
    312	const struct samsung_div_clock *div_clks;
    313	unsigned int nr_div_clks;
    314	/* list of gate clocks and respective count */
    315	const struct samsung_gate_clock *gate_clks;
    316	unsigned int nr_gate_clks;
    317	/* list of fixed clocks and respective count */
    318	const struct samsung_fixed_rate_clock *fixed_clks;
    319	unsigned int nr_fixed_clks;
    320	/* list of fixed factor clocks and respective count */
    321	const struct samsung_fixed_factor_clock *fixed_factor_clks;
    322	unsigned int nr_fixed_factor_clks;
    323	/* total number of clocks with IDs assigned*/
    324	unsigned int nr_clk_ids;
    325	/* list of cpu clocks and respective count */
    326	const struct samsung_cpu_clock *cpu_clks;
    327	unsigned int nr_cpu_clks;
    328
    329	/* list and number of clocks registers */
    330	const unsigned long *clk_regs;
    331	unsigned int nr_clk_regs;
    332
    333	/* list and number of clocks registers to set before suspend */
    334	const struct samsung_clk_reg_dump *suspend_regs;
    335	unsigned int nr_suspend_regs;
    336	/* name of the parent clock needed for CMU register access */
    337	const char *clk_name;
    338};
    339
    340struct samsung_clk_provider * samsung_clk_init(
    341			struct device_node *np, void __iomem *base,
    342			unsigned long nr_clks);
    343void samsung_clk_of_add_provider(struct device_node *np,
    344			struct samsung_clk_provider *ctx);
    345void samsung_clk_of_register_fixed_ext(
    346			struct samsung_clk_provider *ctx,
    347			struct samsung_fixed_rate_clock *fixed_rate_clk,
    348			unsigned int nr_fixed_rate_clk,
    349			const struct of_device_id *clk_matches);
    350
    351void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
    352			struct clk_hw *clk_hw, unsigned int id);
    353
    354void samsung_clk_register_alias(struct samsung_clk_provider *ctx,
    355			const struct samsung_clock_alias *list,
    356			unsigned int nr_clk);
    357void samsung_clk_register_fixed_rate(
    358			struct samsung_clk_provider *ctx,
    359			const struct samsung_fixed_rate_clock *clk_list,
    360			unsigned int nr_clk);
    361void samsung_clk_register_fixed_factor(
    362			struct samsung_clk_provider *ctx,
    363			const struct samsung_fixed_factor_clock *list,
    364			unsigned int nr_clk);
    365void samsung_clk_register_mux(struct samsung_clk_provider *ctx,
    366			const struct samsung_mux_clock *clk_list,
    367			unsigned int nr_clk);
    368void samsung_clk_register_div(struct samsung_clk_provider *ctx,
    369			const struct samsung_div_clock *clk_list,
    370			unsigned int nr_clk);
    371void samsung_clk_register_gate(struct samsung_clk_provider *ctx,
    372			const struct samsung_gate_clock *clk_list,
    373			unsigned int nr_clk);
    374void samsung_clk_register_pll(struct samsung_clk_provider *ctx,
    375			const struct samsung_pll_clock *pll_list,
    376			unsigned int nr_clk, void __iomem *base);
    377void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
    378		const struct samsung_cpu_clock *list, unsigned int nr_clk);
    379
    380struct samsung_clk_provider *samsung_cmu_register_one(
    381			struct device_node *,
    382			const struct samsung_cmu_info *);
    383
    384#ifdef CONFIG_PM_SLEEP
    385void samsung_clk_extended_sleep_init(void __iomem *reg_base,
    386			const unsigned long *rdump,
    387			unsigned long nr_rdump,
    388			const struct samsung_clk_reg_dump *rsuspend,
    389			unsigned long nr_rsuspend);
    390#else
    391static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base,
    392			const unsigned long *rdump,
    393			unsigned long nr_rdump,
    394			const struct samsung_clk_reg_dump *rsuspend,
    395			unsigned long nr_rsuspend) {}
    396#endif
    397#define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \
    398	samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0)
    399
    400void samsung_clk_save(void __iomem *base,
    401			struct samsung_clk_reg_dump *rd,
    402			unsigned int num_regs);
    403void samsung_clk_restore(void __iomem *base,
    404			const struct samsung_clk_reg_dump *rd,
    405			unsigned int num_regs);
    406struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
    407			const unsigned long *rdump,
    408			unsigned long nr_rdump);
    409
    410#endif /* __SAMSUNG_CLK_H */