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-cgu.h (7297B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Copyright(c) 2020 Intel Corporation.
      4 * Zhu YiXin <yixin.zhu@intel.com>
      5 * Rahul Tanwar <rahul.tanwar@intel.com>
      6 */
      7
      8#ifndef __CLK_CGU_H
      9#define __CLK_CGU_H
     10
     11#include <linux/io.h>
     12
     13struct lgm_clk_mux {
     14	struct clk_hw hw;
     15	void __iomem *membase;
     16	unsigned int reg;
     17	u8 shift;
     18	u8 width;
     19	unsigned long flags;
     20	spinlock_t lock;
     21};
     22
     23struct lgm_clk_divider {
     24	struct clk_hw hw;
     25	void __iomem *membase;
     26	unsigned int reg;
     27	u8 shift;
     28	u8 width;
     29	u8 shift_gate;
     30	u8 width_gate;
     31	unsigned long flags;
     32	const struct clk_div_table *table;
     33	spinlock_t lock;
     34};
     35
     36struct lgm_clk_ddiv {
     37	struct clk_hw hw;
     38	void __iomem *membase;
     39	unsigned int reg;
     40	u8 shift0;
     41	u8 width0;
     42	u8 shift1;
     43	u8 width1;
     44	u8 shift2;
     45	u8 width2;
     46	u8 shift_gate;
     47	u8 width_gate;
     48	unsigned int mult;
     49	unsigned int div;
     50	unsigned long flags;
     51	spinlock_t lock;
     52};
     53
     54struct lgm_clk_gate {
     55	struct clk_hw hw;
     56	void __iomem *membase;
     57	unsigned int reg;
     58	u8 shift;
     59	unsigned long flags;
     60	spinlock_t lock;
     61};
     62
     63enum lgm_clk_type {
     64	CLK_TYPE_FIXED,
     65	CLK_TYPE_MUX,
     66	CLK_TYPE_DIVIDER,
     67	CLK_TYPE_FIXED_FACTOR,
     68	CLK_TYPE_GATE,
     69	CLK_TYPE_NONE,
     70};
     71
     72/**
     73 * struct lgm_clk_provider
     74 * @membase: IO mem base address for CGU.
     75 * @np: device node
     76 * @dev: device
     77 * @clk_data: array of hw clocks and clk number.
     78 */
     79struct lgm_clk_provider {
     80	void __iomem *membase;
     81	struct device_node *np;
     82	struct device *dev;
     83	struct clk_hw_onecell_data clk_data;
     84	spinlock_t lock;
     85};
     86
     87enum pll_type {
     88	TYPE_ROPLL,
     89	TYPE_LJPLL,
     90	TYPE_NONE,
     91};
     92
     93struct lgm_clk_pll {
     94	struct clk_hw hw;
     95	void __iomem *membase;
     96	unsigned int reg;
     97	unsigned long flags;
     98	enum pll_type type;
     99	spinlock_t lock;
    100};
    101
    102/**
    103 * struct lgm_pll_clk_data
    104 * @id: platform specific id of the clock.
    105 * @name: name of this pll clock.
    106 * @parent_data: parent clock data.
    107 * @num_parents: number of parents.
    108 * @flags: optional flags for basic clock.
    109 * @type: platform type of pll.
    110 * @reg: offset of the register.
    111 */
    112struct lgm_pll_clk_data {
    113	unsigned int id;
    114	const char *name;
    115	const struct clk_parent_data *parent_data;
    116	u8 num_parents;
    117	unsigned long flags;
    118	enum pll_type type;
    119	int reg;
    120};
    121
    122#define LGM_PLL(_id, _name, _pdata, _flags,		\
    123		_reg, _type)				\
    124	{						\
    125		.id = _id,				\
    126		.name = _name,				\
    127		.parent_data = _pdata,			\
    128		.num_parents = ARRAY_SIZE(_pdata),	\
    129		.flags = _flags,			\
    130		.reg = _reg,				\
    131		.type = _type,				\
    132	}
    133
    134struct lgm_clk_ddiv_data {
    135	unsigned int id;
    136	const char *name;
    137	const struct clk_parent_data *parent_data;
    138	u8 flags;
    139	unsigned long div_flags;
    140	unsigned int reg;
    141	u8 shift0;
    142	u8 width0;
    143	u8 shift1;
    144	u8 width1;
    145	u8 shift_gate;
    146	u8 width_gate;
    147	u8 ex_shift;
    148	u8 ex_width;
    149};
    150
    151#define LGM_DDIV(_id, _name, _pname, _flags, _reg,		\
    152		 _shft0, _wdth0, _shft1, _wdth1,		\
    153		 _shft_gate, _wdth_gate, _xshft, _df)		\
    154	{							\
    155		.id = _id,					\
    156		.name = _name,					\
    157		.parent_data = &(const struct clk_parent_data){	\
    158			.fw_name = _pname,			\
    159			.name = _pname,				\
    160		},						\
    161		.flags = _flags,				\
    162		.reg = _reg,					\
    163		.shift0 = _shft0,				\
    164		.width0 = _wdth0,				\
    165		.shift1 = _shft1,				\
    166		.width1 = _wdth1,				\
    167		.shift_gate = _shft_gate,			\
    168		.width_gate = _wdth_gate,			\
    169		.ex_shift = _xshft,				\
    170		.ex_width = 1,					\
    171		.div_flags = _df,				\
    172	}
    173
    174struct lgm_clk_branch {
    175	unsigned int id;
    176	enum lgm_clk_type type;
    177	const char *name;
    178	const struct clk_parent_data *parent_data;
    179	u8 num_parents;
    180	unsigned long flags;
    181	unsigned int mux_off;
    182	u8 mux_shift;
    183	u8 mux_width;
    184	unsigned long mux_flags;
    185	unsigned int mux_val;
    186	unsigned int div_off;
    187	u8 div_shift;
    188	u8 div_width;
    189	u8 div_shift_gate;
    190	u8 div_width_gate;
    191	unsigned long div_flags;
    192	unsigned int div_val;
    193	const struct clk_div_table *div_table;
    194	unsigned int gate_off;
    195	u8 gate_shift;
    196	unsigned long gate_flags;
    197	unsigned int gate_val;
    198	unsigned int mult;
    199	unsigned int div;
    200};
    201
    202/* clock flags definition */
    203#define CLOCK_FLAG_VAL_INIT	BIT(16)
    204#define MUX_CLK_SW		BIT(17)
    205
    206#define LGM_MUX(_id, _name, _pdata, _f, _reg,		\
    207		_shift, _width, _cf, _v)		\
    208	{						\
    209		.id = _id,				\
    210		.type = CLK_TYPE_MUX,			\
    211		.name = _name,				\
    212		.parent_data = _pdata,			\
    213		.num_parents = ARRAY_SIZE(_pdata),	\
    214		.flags = _f,				\
    215		.mux_off = _reg,			\
    216		.mux_shift = _shift,			\
    217		.mux_width = _width,			\
    218		.mux_flags = _cf,			\
    219		.mux_val = _v,				\
    220	}
    221
    222#define LGM_DIV(_id, _name, _pname, _f, _reg, _shift, _width,	\
    223		_shift_gate, _width_gate, _cf, _v, _dtable)	\
    224	{							\
    225		.id = _id,					\
    226		.type = CLK_TYPE_DIVIDER,			\
    227		.name = _name,					\
    228		.parent_data = &(const struct clk_parent_data){	\
    229			.fw_name = _pname,			\
    230			.name = _pname,				\
    231		},						\
    232		.num_parents = 1,				\
    233		.flags = _f,					\
    234		.div_off = _reg,				\
    235		.div_shift = _shift,				\
    236		.div_width = _width,				\
    237		.div_shift_gate = _shift_gate,			\
    238		.div_width_gate = _width_gate,			\
    239		.div_flags = _cf,				\
    240		.div_val = _v,					\
    241		.div_table = _dtable,				\
    242	}
    243
    244#define LGM_GATE(_id, _name, _pname, _f, _reg,			\
    245		 _shift, _cf, _v)				\
    246	{							\
    247		.id = _id,					\
    248		.type = CLK_TYPE_GATE,				\
    249		.name = _name,					\
    250		.parent_data = &(const struct clk_parent_data){	\
    251			.fw_name = _pname,			\
    252			.name = _pname,				\
    253		},						\
    254		.num_parents = !_pname ? 0 : 1,			\
    255		.flags = _f,					\
    256		.gate_off = _reg,				\
    257		.gate_shift = _shift,				\
    258		.gate_flags = _cf,				\
    259		.gate_val = _v,					\
    260	}
    261
    262#define LGM_FIXED(_id, _name, _pname, _f, _reg,			\
    263		  _shift, _width, _cf, _freq, _v)		\
    264	{							\
    265		.id = _id,					\
    266		.type = CLK_TYPE_FIXED,				\
    267		.name = _name,					\
    268		.parent_data = &(const struct clk_parent_data){	\
    269			.fw_name = _pname,			\
    270			.name = _pname,				\
    271		},						\
    272		.num_parents = !_pname ? 0 : 1,			\
    273		.flags = _f,					\
    274		.div_off = _reg,				\
    275		.div_shift = _shift,				\
    276		.div_width = _width,				\
    277		.div_flags = _cf,				\
    278		.div_val = _v,					\
    279		.mux_flags = _freq,				\
    280	}
    281
    282#define LGM_FIXED_FACTOR(_id, _name, _pname, _f, _reg,		\
    283			 _shift, _width, _cf, _v, _m, _d)	\
    284	{							\
    285		.id = _id,					\
    286		.type = CLK_TYPE_FIXED_FACTOR,			\
    287		.name = _name,					\
    288		.parent_data = &(const struct clk_parent_data){	\
    289			.fw_name = _pname,			\
    290			.name = _pname,				\
    291		},						\
    292		.num_parents = 1,				\
    293		.flags = _f,					\
    294		.div_off = _reg,				\
    295		.div_shift = _shift,				\
    296		.div_width = _width,				\
    297		.div_flags = _cf,				\
    298		.div_val = _v,					\
    299		.mult = _m,					\
    300		.div = _d,					\
    301	}
    302
    303static inline void lgm_set_clk_val(void __iomem *membase, u32 reg,
    304				   u8 shift, u8 width, u32 set_val)
    305{
    306	u32 mask = (GENMASK(width - 1, 0) << shift);
    307	u32 regval;
    308
    309	regval = readl(membase + reg);
    310	regval = (regval & ~mask) | ((set_val << shift) & mask);
    311	writel(regval, membase + reg);
    312}
    313
    314static inline u32 lgm_get_clk_val(void __iomem *membase, u32 reg,
    315				  u8 shift, u8 width)
    316{
    317	u32 mask = (GENMASK(width - 1, 0) << shift);
    318	u32 val;
    319
    320	val = readl(membase + reg);
    321	val = (val & mask) >> shift;
    322
    323	return val;
    324}
    325
    326int lgm_clk_register_branches(struct lgm_clk_provider *ctx,
    327			      const struct lgm_clk_branch *list,
    328			      unsigned int nr_clk);
    329int lgm_clk_register_plls(struct lgm_clk_provider *ctx,
    330			  const struct lgm_pll_clk_data *list,
    331			  unsigned int nr_clk);
    332int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx,
    333			  const struct lgm_clk_ddiv_data *list,
    334			  unsigned int nr_clk);
    335#endif	/* __CLK_CGU_H */