2015-06-01 13:13:53 +02:00
/*
* Copyright ( c ) 2015 Endless Mobile , Inc .
* Author : Carlo Caione < carlo @ endlessm . com >
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms and conditions of the GNU General Public License ,
* version 2 , as published by the Free Software Foundation .
*
* This program is distributed in the hope it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License along with
* this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# ifndef __CLKC_H
# define __CLKC_H
# 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
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 ;
2016-06-06 18:08:15 -07:00
u16 frac ;
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 ) , \
} \
2016-06-06 18:08:15 -07:00
# define PLL_FRAC_RATE(_r, _m, _n, _od, _od2, _frac) \
{ \
. rate = ( _r ) , \
. m = ( _m ) , \
. n = ( _n ) , \
. od = ( _od ) , \
. od2 = ( _od2 ) , \
. frac = ( _frac ) , \
} \
2017-03-22 11:32:23 +01:00
struct pll_params_table {
unsigned int reg_off ;
unsigned int value ;
} ;
# define PLL_PARAM(_reg, _val) \
{ \
. reg_off = ( _reg ) , \
. value = ( _val ) , \
}
struct pll_setup_params {
struct pll_params_table * params_table ;
unsigned int params_count ;
/* Workaround for GP0, do not reset before configuring */
bool no_init_reset ;
/* Workaround for GP0, unreset right before checking for lock */
bool clear_reset_for_lock ;
/* Workaround for GXL GP0, reset in the lock checking loop */
bool reset_lock_loop ;
} ;
2016-04-28 12:01:42 -07:00
struct meson_clk_pll {
struct clk_hw hw ;
void __iomem * base ;
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 ;
2017-03-22 11:32:23 +01:00
const struct pll_setup_params params ;
2016-04-28 12:01:42 -07:00
const struct pll_rate_table * rate_table ;
unsigned int rate_count ;
spinlock_t * lock ;
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)
2016-04-30 12:47:36 -07:00
struct meson_clk_cpu {
struct clk_hw hw ;
void __iomem * base ;
u16 reg_off ;
struct notifier_block clk_nb ;
const struct clk_div_table * div_table ;
} ;
int meson_clk_cpu_notifier_cb ( struct notifier_block * nb , unsigned long event ,
void * data ) ;
2016-04-28 12:01:42 -07:00
2016-06-06 23:16:17 -07:00
struct meson_clk_mpll {
struct clk_hw hw ;
void __iomem * base ;
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-03-09 11:41:50 +01:00
struct parm en ;
2017-07-28 18:32:28 +02:00
struct parm ssen ;
2016-06-06 23:16:17 -07:00
spinlock_t * lock ;
} ;
2017-02-14 00:13:55 +01:00
struct meson_clk_audio_divider {
struct clk_hw hw ;
void __iomem * base ;
struct parm div ;
u8 flags ;
spinlock_t * lock ;
} ;
2016-06-07 16:00:55 -07:00
# define MESON_GATE(_name, _reg, _bit) \
2016-08-27 19:40:53 +02:00
struct clk_gate _name = { \
2016-06-07 16:00:55 -07:00
. reg = ( void __iomem * ) _reg , \
. bit_idx = ( _bit ) , \
2017-12-11 22:13:43 +08:00
. lock = & meson_clk_lock , \
2016-06-07 16:00:55 -07:00
. hw . init = & ( struct clk_init_data ) { \
. name = # _name , \
. ops = & clk_gate_ops , \
. parent_names = ( const char * [ ] ) { " clk81 " } , \
. num_parents = 1 , \
. flags = ( CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED ) , \
} , \
} ;
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 ;
2017-02-14 00:13:55 +01:00
extern const struct clk_ops meson_clk_audio_divider_ro_ops ;
extern const struct clk_ops meson_clk_audio_divider_ops ;
2015-06-01 13:13:53 +02:00
# endif /* __CLKC_H */