2015-04-23 11:35:39 +03:00
/*
* Copyright ( c ) 2014 MediaTek Inc .
* Author : James Liao < jamesjj . liao @ mediatek . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that 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 .
*/
# ifndef __DRV_CLK_MTK_H
# define __DRV_CLK_MTK_H
# include <linux/regmap.h>
# include <linux/bitops.h>
# include <linux/clk-provider.h>
2015-06-20 01:00:46 +03:00
struct clk ;
2015-04-23 11:35:39 +03:00
# define MAX_MUX_GATE_BIT 31
# define INVALID_MUX_GATE_BIT (MAX_MUX_GATE_BIT + 1)
# define MHZ (1000 * 1000)
2015-07-10 06:39:15 +03:00
struct mtk_fixed_clk {
int id ;
const char * name ;
const char * parent ;
unsigned long rate ;
} ;
# define FIXED_CLK(_id, _name, _parent, _rate) { \
. id = _id , \
. name = _name , \
. parent = _parent , \
. rate = _rate , \
}
void mtk_clk_register_fixed_clks ( const struct mtk_fixed_clk * clks ,
int num , struct clk_onecell_data * clk_data ) ;
2015-04-23 11:35:39 +03:00
struct mtk_fixed_factor {
int id ;
const char * name ;
const char * parent_name ;
int mult ;
int div ;
} ;
# define FACTOR(_id, _name, _parent, _mult, _div) { \
. id = _id , \
. name = _name , \
. parent_name = _parent , \
. mult = _mult , \
. div = _div , \
}
2015-07-28 09:53:29 +03:00
void mtk_clk_register_factors ( const struct mtk_fixed_factor * clks ,
2015-04-23 11:35:39 +03:00
int num , struct clk_onecell_data * clk_data ) ;
struct mtk_composite {
int id ;
const char * name ;
const char * const * parent_names ;
const char * parent ;
unsigned flags ;
uint32_t mux_reg ;
uint32_t divider_reg ;
uint32_t gate_reg ;
signed char mux_shift ;
signed char mux_width ;
signed char gate_shift ;
signed char divider_shift ;
signed char divider_width ;
signed char num_parents ;
} ;
2016-01-04 20:36:42 +03:00
/*
* In case the rate change propagation to parent clocks is undesirable ,
* this macro allows to specify the clock flags manually .
*/
2016-11-04 10:43:05 +03:00
# define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \
_gate , _flags ) { \
2015-04-23 11:35:39 +03:00
. id = _id , \
. name = _name , \
. mux_reg = _reg , \
. mux_shift = _shift , \
. mux_width = _width , \
. gate_reg = _reg , \
. gate_shift = _gate , \
. divider_shift = - 1 , \
. parent_names = _parents , \
. num_parents = ARRAY_SIZE ( _parents ) , \
2016-01-04 20:36:42 +03:00
. flags = _flags , \
2015-04-23 11:35:39 +03:00
}
2016-01-04 20:36:42 +03:00
/*
* Unless necessary , all MUX_GATE clocks propagate rate changes to their
* parent clock by default .
*/
# define MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate) \
2016-11-04 10:43:05 +03:00
MUX_GATE_FLAGS ( _id , _name , _parents , _reg , _shift , _width , \
_gate , CLK_SET_RATE_PARENT )
2016-01-04 20:36:42 +03:00
2015-04-23 11:35:39 +03:00
# define MUX(_id, _name, _parents, _reg, _shift, _width) { \
. id = _id , \
. name = _name , \
. mux_reg = _reg , \
. mux_shift = _shift , \
. mux_width = _width , \
. gate_shift = - 1 , \
. divider_shift = - 1 , \
. parent_names = _parents , \
. num_parents = ARRAY_SIZE ( _parents ) , \
. flags = CLK_SET_RATE_PARENT , \
}
2016-11-04 10:43:05 +03:00
# define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \
_div_width , _div_shift ) { \
2015-04-23 11:35:39 +03:00
. id = _id , \
. parent = _parent , \
. name = _name , \
. divider_reg = _div_reg , \
. divider_shift = _div_shift , \
. divider_width = _div_width , \
. gate_reg = _gate_reg , \
. gate_shift = _gate_shift , \
. mux_shift = - 1 , \
. flags = 0 , \
}
struct clk * mtk_clk_register_composite ( const struct mtk_composite * mc ,
void __iomem * base , spinlock_t * lock ) ;
void mtk_clk_register_composites ( const struct mtk_composite * mcs ,
int num , void __iomem * base , spinlock_t * lock ,
struct clk_onecell_data * clk_data ) ;
struct mtk_gate_regs {
u32 sta_ofs ;
u32 clr_ofs ;
u32 set_ofs ;
} ;
struct mtk_gate {
int id ;
const char * name ;
const char * parent_name ;
const struct mtk_gate_regs * regs ;
int shift ;
const struct clk_ops * ops ;
} ;
2016-11-04 10:43:05 +03:00
int mtk_clk_register_gates ( struct device_node * node ,
const struct mtk_gate * clks , int num ,
struct clk_onecell_data * clk_data ) ;
struct mtk_clk_divider {
int id ;
const char * name ;
const char * parent_name ;
unsigned long flags ;
u32 div_reg ;
unsigned char div_shift ;
unsigned char div_width ;
unsigned char clk_divider_flags ;
const struct clk_div_table * clk_div_table ;
} ;
# define DIV_ADJ(_id, _name, _parent, _reg, _shift, _width) { \
. id = _id , \
. name = _name , \
. parent_name = _parent , \
. div_reg = _reg , \
. div_shift = _shift , \
. div_width = _width , \
}
void mtk_clk_register_dividers ( const struct mtk_clk_divider * mcds ,
int num , void __iomem * base , spinlock_t * lock ,
struct clk_onecell_data * clk_data ) ;
2015-04-23 11:35:39 +03:00
struct clk_onecell_data * mtk_alloc_clk_data ( unsigned int clk_num ) ;
# define HAVE_RST_BAR BIT(0)
2016-11-04 10:43:05 +03:00
# define PLL_AO BIT(1)
2015-04-23 11:35:39 +03:00
2015-07-10 11:39:34 +03:00
struct mtk_pll_div_table {
u32 div ;
unsigned long freq ;
} ;
2015-04-23 11:35:39 +03:00
struct mtk_pll_data {
int id ;
const char * name ;
uint32_t reg ;
uint32_t pwr_reg ;
uint32_t en_mask ;
uint32_t pd_reg ;
uint32_t tuner_reg ;
int pd_shift ;
unsigned int flags ;
const struct clk_ops * ops ;
u32 rst_bar_mask ;
unsigned long fmax ;
int pcwbits ;
uint32_t pcw_reg ;
int pcw_shift ;
2015-07-10 11:39:34 +03:00
const struct mtk_pll_div_table * div_table ;
2015-04-23 11:35:39 +03:00
} ;
2015-07-28 09:53:29 +03:00
void mtk_clk_register_plls ( struct device_node * node ,
2015-04-23 11:35:39 +03:00
const struct mtk_pll_data * plls , int num_plls ,
struct clk_onecell_data * clk_data ) ;
2015-05-20 10:59:21 +03:00
struct clk * mtk_clk_register_ref2usb_tx ( const char * name ,
const char * parent_name , void __iomem * reg ) ;
2015-04-23 11:35:40 +03:00
# ifdef CONFIG_RESET_CONTROLLER
void mtk_register_reset_controller ( struct device_node * np ,
unsigned int num_regs , int regofs ) ;
# else
static inline void mtk_register_reset_controller ( struct device_node * np ,
unsigned int num_regs , int regofs )
{
}
# endif
2015-04-23 11:35:39 +03:00
# endif /* __DRV_CLK_MTK_H */