2018-05-16 10:50:40 +02:00
/* SPDX-License-Identifier: GPL-2.0 */
2015-06-01 13:13:53 +02:00
/*
* Copyright ( c ) 2015 Endless Mobile , Inc .
* Author : Carlo Caione < carlo @ endlessm . com >
*/
# ifndef __CLKC_H
# define __CLKC_H
2018-02-12 15:58:36 +01:00
# include <linux/clk-provider.h>
# include "clk-regmap.h"
2015-06-01 13:13:53 +02:00
# define PMASK(width) GENMASK(width - 1, 0)
# define SETPMASK(width, shift) GENMASK(shift + width - 1, shift)
# define CLRPMASK(width, shift) (~SETPMASK(width, shift))
# define PARM_GET(width, shift, reg) \
( ( ( reg ) & SETPMASK ( width , shift ) ) > > ( shift ) )
# define PARM_SET(width, shift, reg, val) \
2017-03-09 11:41:46 +01:00
( ( ( reg ) & CLRPMASK ( width , shift ) ) | ( ( val ) < < ( shift ) ) )
2015-06-01 13:13:53 +02:00
# define MESON_PARM_APPLICABLE(p) (!!((p)->width))
struct parm {
u16 reg_off ;
u8 shift ;
u8 width ;
} ;
2016-04-28 12:01:42 -07:00
2018-02-12 15:58:39 +01:00
static inline unsigned int meson_parm_read ( struct regmap * map , struct parm * p )
{
unsigned int val ;
regmap_read ( map , p - > reg_off , & val ) ;
return PARM_GET ( p - > width , p - > shift , val ) ;
}
static inline void meson_parm_write ( struct regmap * map , struct parm * p ,
unsigned int val )
{
regmap_update_bits ( map , p - > reg_off , SETPMASK ( p - > width , p - > shift ) ,
val < < p - > shift ) ;
}
2015-06-01 13:13:53 +02:00
struct pll_rate_table {
unsigned long rate ;
u16 m ;
u16 n ;
u16 od ;
2016-06-06 18:08:15 -07:00
u16 od2 ;
2018-01-19 16:55:25 +01:00
u16 od3 ;
2015-06-01 13:13:53 +02:00
} ;
2016-06-06 18:08:15 -07:00
2015-06-01 13:13:53 +02:00
# define PLL_RATE(_r, _m, _n, _od) \
{ \
. rate = ( _r ) , \
. m = ( _m ) , \
. n = ( _n ) , \
. od = ( _od ) , \
2018-02-19 12:21:39 +01:00
}
2016-06-06 18:08:15 -07:00
2018-02-19 12:21:41 +01:00
# define CLK_MESON_PLL_ROUND_CLOSEST BIT(0)
2018-02-12 15:58:42 +01:00
struct meson_clk_pll_data {
2016-04-28 12:01:42 -07:00
struct parm m ;
struct parm n ;
2016-06-06 18:08:15 -07:00
struct parm frac ;
2016-04-28 12:01:42 -07:00
struct parm od ;
2016-06-06 18:08:15 -07:00
struct parm od2 ;
2018-01-19 16:55:25 +01:00
struct parm od3 ;
2018-02-12 15:58:42 +01:00
struct parm l ;
struct parm rst ;
const struct reg_sequence * init_regs ;
unsigned int init_count ;
const struct pll_rate_table * table ;
u8 flags ;
2015-06-01 13:13:53 +02:00
} ;
2016-04-28 12:01:42 -07:00
# define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
2018-02-12 15:58:40 +01:00
struct meson_clk_mpll_data {
2016-06-06 23:16:17 -07:00
struct parm sdm ;
2017-03-09 11:41:50 +01:00
struct parm sdm_en ;
2016-06-06 23:16:17 -07:00
struct parm n2 ;
2017-07-28 18:32:28 +02:00
struct parm ssen ;
2018-01-19 16:42:36 +01:00
struct parm misc ;
2016-06-06 23:16:17 -07:00
spinlock_t * lock ;
2018-05-15 18:36:51 +02:00
u8 flags ;
2016-06-06 23:16:17 -07:00
} ;
2018-05-15 18:36:51 +02:00
# define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0)
2018-05-22 18:34:53 +02:00
struct meson_clk_phase_data {
struct parm ph ;
} ;
int meson_clk_degrees_from_val ( unsigned int val , unsigned int width ) ;
unsigned int meson_clk_degrees_to_val ( int degrees , unsigned int width ) ;
2016-06-07 16:00:55 -07:00
# define MESON_GATE(_name, _reg, _bit) \
2018-02-12 15:58:36 +01:00
struct clk_regmap _name = { \
. data = & ( struct clk_regmap_gate_data ) { \
. offset = ( _reg ) , \
. bit_idx = ( _bit ) , \
} , \
. hw . init = & ( struct clk_init_data ) { \
. name = # _name , \
. ops = & clk_regmap_gate_ops , \
2016-06-07 16:00:55 -07:00
. parent_names = ( const char * [ ] ) { " clk81 " } , \
. num_parents = 1 , \
2018-02-12 15:58:36 +01:00
. flags = ( CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED ) , \
2016-06-07 16:00:55 -07:00
} , \
} ;
2016-04-28 12:01:42 -07:00
/* clk_ops */
extern const struct clk_ops meson_clk_pll_ro_ops ;
extern const struct clk_ops meson_clk_pll_ops ;
2016-04-30 12:47:36 -07:00
extern const struct clk_ops meson_clk_cpu_ops ;
2016-06-06 23:16:17 -07:00
extern const struct clk_ops meson_clk_mpll_ro_ops ;
2017-03-09 11:41:50 +01:00
extern const struct clk_ops meson_clk_mpll_ops ;
2018-05-22 18:34:53 +02:00
extern const struct clk_ops meson_clk_phase_ops ;
2015-06-01 13:13:53 +02:00
# endif /* __CLKC_H */