From: xxx Date: Thu, 11 Apr 2013 07:16:00 +0000 (+0800) Subject: dvfs add disable clk interfacet X-Git-Tag: firefly_0821_release~7277 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=1ef7299e1f52e45c7e33a03747ff9a831439e332;p=firefly-linux-kernel-4.4.55.git dvfs add disable clk interfacet --- diff --git a/arch/arm/plat-rk/clock.c b/arch/arm/plat-rk/clock.c old mode 100755 new mode 100644 index 7902e8742e0b..2fdd5bb5a0a4 --- a/arch/arm/plat-rk/clock.c +++ b/arch/arm/plat-rk/clock.c @@ -322,12 +322,6 @@ int clk_set_parent_nolock(struct clk *clk, struct clk *parent) return ret; } /**********************************dvfs****************************************************/ - -struct clk_node *clk_get_dvfs_info(struct clk *clk) -{ - return clk->dvfs_info; -} - int clk_set_rate_locked(struct clk * clk,unsigned long rate) { int ret; @@ -342,8 +336,18 @@ void clk_register_dvfs(struct clk_node *dvfs_clk, struct clk *clk) { clk->dvfs_info = dvfs_clk; } - - +int clk_set_enable_locked(struct clk * clk,int on) +{ + int ret=0; + LOCK(); + if(on) + ret=clk_enable_nolock(clk); + else + clk_disable_nolock(clk); + UNLOCK(); + return ret; +} +EXPORT_SYMBOL(clk_set_enable_locked); /*------------------------------------------------------------------------- * Optional clock functions defined in include/linux/clk.h *-------------------------------------------------------------------------*/ @@ -402,8 +406,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) } if (rate == clk->rate) return 0; - if (clk->dvfs_info!=NULL&&is_support_dvfs(clk->dvfs_info)) - return dvfs_set_rate(clk, rate); + if (dvfs_support_clk_set_rate(clk->dvfs_info)==true) + return dvfs_vd_clk_set_rate(clk, rate); LOCK(); ret = clk_set_rate_nolock(clk, rate); @@ -488,6 +492,8 @@ void clk_disable(struct clk *clk) { if (clk == NULL || IS_ERR(clk)) return; + if (dvfs_support_clk_disable(clk->dvfs_info)==true) + return dvfs_vd_clk_disable(clk, 0); LOCK(); clk_disable_nolock(clk); @@ -509,6 +515,8 @@ int clk_enable(struct clk *clk) if (clk == NULL || IS_ERR(clk)) return -EINVAL; + if (dvfs_support_clk_disable(clk->dvfs_info)==true) + return dvfs_vd_clk_disable(clk, 1); LOCK(); ret = clk_enable_nolock(clk); diff --git a/arch/arm/plat-rk/dvfs.c b/arch/arm/plat-rk/dvfs.c old mode 100755 new mode 100644 index 4f82c153d4c3..bda91b07ba30 --- a/arch/arm/plat-rk/dvfs.c +++ b/arch/arm/plat-rk/dvfs.c @@ -36,6 +36,7 @@ static int dump_dbg_map(char *buf); #define PD_ON 1 #define PD_OFF 0 +#define DVFS_STR_DISABLE(on) ((on)?"enable":"disable") #define get_volt_up_delay(new_volt, old_volt) \ ((new_volt) > (old_volt) ? (((new_volt) - (old_volt)) >> 9) : 0) @@ -280,31 +281,70 @@ int dvfs_clk_disable_limit(struct clk *clk) return 0; } -int is_support_dvfs(struct clk_node *dvfs_info) +int dvfs_vd_clk_set_rate(struct clk *clk, unsigned long rate) { - return (dvfs_info->vd && dvfs_info->vd->vd_dvfs_target && dvfs_info->enable_dvfs); + int ret = -1; + struct clk_node *dvfs_info=clk_get_dvfs_info(clk); + + DVFS_DBG("%s(%s(%lu))\n", __func__, dvfs_info->name, rate); + + #if 0 // judge by reference func in rk + if (dvfs_support_clk_set_rate(dvfs_info)==false) { + DVFS_ERR("dvfs func:%s is not support!\n", __func__); + return ret; + } + #endif + + if(dvfs_info->vd&&dvfs_info->vd->vd_dvfs_target){ + // mutex_lock(&vd->dvfs_mutex); + mutex_lock(&rk_dvfs_mutex); + ret = dvfs_info->vd->vd_dvfs_target(clk, rate); + mutex_unlock(&rk_dvfs_mutex); + // mutex_unlock(&vd->dvfs_mutex); + } + else + { + DVFS_WARNING("%s(%s),vd is no target callback\n", __func__, clk->name); + return -1; + } + DVFS_DBG("%s(%s(%lu)),is end\n", __func__, clk->name, rate); + return ret; } +EXPORT_SYMBOL(dvfs_vd_clk_set_rate); -int dvfs_set_rate(struct clk *clk, unsigned long rate) +int dvfs_vd_clk_disable(struct clk *clk, int on) { - int ret = 0; - struct vd_node *vd; - DVFS_DBG("%s(%s(%lu))\n", __func__, clk->name, rate); - if (!clk->dvfs_info) { - DVFS_ERR("%s :This clk do not support dvfs!\n", __func__); - ret = -1; - } else { - vd = clk->dvfs_info->vd; + int ret = -1; + struct clk_node *dvfs_info=clk_get_dvfs_info(clk); + DVFS_DBG("%s(%s(%s,%lu))\n", __func__, dvfs_info->name, DVFS_STR_DISABLE(on),clk_get_rate(clk)); + + + #if 0 // judge by reference func in rk + if (dvfs_support_clk_disable(dvfs_info)==false) { + DVFS_ERR("dvfs func:%s is not support!\n", __func__); + return ret; + } + #endif + + if(dvfs_info->vd&&dvfs_info->vd->vd_clk_disable_target){ // mutex_lock(&vd->dvfs_mutex); mutex_lock(&rk_dvfs_mutex); - ret = vd->vd_dvfs_target(clk, rate); + ret = dvfs_info->vd->vd_clk_disable_target(clk, on); mutex_unlock(&rk_dvfs_mutex); // mutex_unlock(&vd->dvfs_mutex); } - DVFS_DBG("%s(%s(%lu)),is end\n", __func__, clk->name, rate); + else + { + DVFS_WARNING("%s(%s),vd is no target callback\n", __func__, clk->name); + return -1; + } + DVFS_DBG("%s(%s(%lu)),is end\n", __func__, dvfs_info->name, DVFS_STR_ON(on)); + return ret; } +EXPORT_SYMBOL(dvfs_vd_clk_disable); + static void dvfs_table_round_clk_rate(struct clk_node *dvfs_clk) { int i; diff --git a/arch/arm/plat-rk/include/plat/clock.h b/arch/arm/plat-rk/include/plat/clock.h index ece9e1f18faf..65b23a2879af 100644 --- a/arch/arm/plat-rk/include/plat/clock.h +++ b/arch/arm/plat-rk/include/plat/clock.h @@ -70,8 +70,17 @@ int clk_set_rate_nolock(struct clk *clk, unsigned long rate); int clk_set_parent_nolock(struct clk *clk, struct clk *parent); int clk_set_rate_locked(struct clk * clk,unsigned long rate); void clk_register_dvfs(struct clk_node *dvfs_clk, struct clk *clk); -struct clk_node *clk_get_dvfs_info(struct clk *clk); int is_suport_round_rate(struct clk *clk); +int clk_set_enable_locked(struct clk * clk,int on); +/************************inline fun*****************************/ +static inline struct clk_node *clk_get_dvfs_info(struct clk *clk) +{ + return clk->dvfs_info; +} +static inline s16 clk_used_count(struct clk * clk) +{ + return (clk->usecount); +} #ifdef RK30_CLK_OFFBOARD_TEST #include diff --git a/arch/arm/plat-rk/include/plat/dvfs.h b/arch/arm/plat-rk/include/plat/dvfs.h old mode 100755 new mode 100644 index 5278f9104218..02b6c31f5492 --- a/arch/arm/plat-rk/include/plat/dvfs.h +++ b/arch/arm/plat-rk/include/plat/dvfs.h @@ -17,12 +17,11 @@ #include -typedef int (*vd_dvfs_target_callback)(struct clk *clk, unsigned long rate); - +//typedef int (*vd_dvfs_target_callback)(struct clk *clk, unsigned long rate); typedef int (*dvfs_set_rate_callback)(struct clk *clk, unsigned long rate); - typedef int (*clk_dvfs_target_callback)(struct clk *clk, unsigned long rate, dvfs_set_rate_callback set_rate); +typedef int (*dvfs_clk_disable_callback)(struct clk *clk,int on); /** * struct vd_node: To Store All Voltage Domains' info @@ -52,7 +51,8 @@ struct vd_node { struct list_head pd_list; struct list_head req_volt_list; //struct mutex dvfs_mutex; - vd_dvfs_target_callback vd_dvfs_target; + dvfs_clk_disable_callback vd_clk_disable_target; + dvfs_set_rate_callback vd_dvfs_target; unsigned n_voltages; int volt_list[VD_VOL_LIST_CNT]; }; @@ -107,7 +107,10 @@ struct depend_lookup { struct depend_list dep_list; struct cpufreq_frequency_table *dep_table; }; - +struct clk_disable_ctr { + dvfs_clk_disable_callback clk_disable_target; + struct clk_node *dvfs_clk; +}; /** * struct clk_node: To Store All dvfs clocks' info * @name: Dvfs clock's Name @@ -137,6 +140,7 @@ struct clk_node { struct notifier_block *dvfs_nb; struct cpufreq_frequency_table *dvfs_table; clk_dvfs_target_callback clk_dvfs_target; + struct clk_disable_ctr *disable_ctr; }; struct dvfs_arm_table { @@ -182,8 +186,6 @@ struct dvfs_arm_table { #define dvfs_clk_get(a,b) clk_get((a),(b)) #define dvfs_clk_get_rate_kz(a) (clk_get_rate((a))/1000) #define dvfs_clk_set_rate(a,b) clk_set_rate((a),(b)) -#define dvfs_clk_enable(a) clk_enable((a)) -#define dvfs_clk_disable(a) clk_disable((a)) @@ -215,11 +217,12 @@ int rk_regist_clk(struct clk_node *dvfs_clk); int rk_regist_depends(struct depend_lookup *dep_node); struct clk_node *dvfs_get_dvfs_clk_byname(char *name); int vd_regulator_round_volt(struct vd_node *vd, int volt,int flags); +int dvfs_vd_clk_disable_target(struct clk *clk, int on); +void dvfs_clk_disable_delay_work(struct work_struct *work); -/******************************************************************************/ - -int is_support_dvfs(struct clk_node *dvfs_info); -int dvfs_set_rate(struct clk *clk, unsigned long rate); +/*********************************if not define dvfs ,the following function is need defined func{}******************************/ +int dvfs_vd_clk_set_rate(struct clk *clk, unsigned long rate); +int dvfs_vd_clk_disable(struct clk *clk, int on); int clk_enable_dvfs(struct clk *clk); int clk_disable_dvfs(struct clk *clk); void dvfs_clk_register_set_rate_callback(struct clk *clk, clk_dvfs_target_callback clk_dvfs_target); @@ -231,15 +234,27 @@ struct regulator* dvfs_get_regulator(char *regulator_name); int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned max_rate); int dvfs_clk_disable_limit(struct clk *clk); int dvfs_scale_volt_direct(struct vd_node *vd_clk, int volt_new); - +/******************************** inline *******************************/ +static inline bool dvfs_support_clk_set_rate(struct clk_node *dvfs_info) +{ + return (dvfs_info&&dvfs_info->enable_dvfs); +} +static inline bool dvfs_support_clk_disable(struct clk_node *dvfs_info) +{ + return (dvfs_info&&dvfs_info->disable_ctr&&dvfs_info->enable_dvfs); +} +/********************************avs*******************************/ void avs_init(void); void avs_init_val_get(int index,int vol,char *s); int avs_set_scal_val(u8 avs_base); void avs_board_init(struct avs_ctr_st *data); #else -static inline int is_support_dvfs(struct clk_node *dvfs_info) { return 0; } -static inline int dvfs_set_rate(struct clk *clk, unsigned long rate) { return 0; } +static inline bool dvfs_support_clk_set_rate(struct clk_node *dvfs_info) { return 0; } +static inline bool dvfs_support_clk_disable(struct clk_node *dvfs_info) { return 0; } + +static inline int dvfs_vd_clk_set_rate(struct clk *clk, unsigned long rate) { return 0; } +static inline int dvfs_vd_clk_disable(struct clk *clk, int on) { return 0; } static inline int clk_enable_dvfs(struct clk *clk) { return 0; } static inline int clk_disable_dvfs(struct clk *clk) { return 0; } static inline void dvfs_clk_register_set_rate_callback(struct clk *clk, clk_dvfs_target_callback clk_dvfs_target) {}