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;
{
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
*-------------------------------------------------------------------------*/
}
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);
{
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);
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);
\r
#define PD_ON 1\r
#define PD_OFF 0\r
+#define DVFS_STR_DISABLE(on) ((on)?"enable":"disable")\r
\r
#define get_volt_up_delay(new_volt, old_volt) \\r
((new_volt) > (old_volt) ? (((new_volt) - (old_volt)) >> 9) : 0)\r
return 0;\r
}\r
\r
-int is_support_dvfs(struct clk_node *dvfs_info)\r
+int dvfs_vd_clk_set_rate(struct clk *clk, unsigned long rate)\r
{\r
- return (dvfs_info->vd && dvfs_info->vd->vd_dvfs_target && dvfs_info->enable_dvfs);\r
+ int ret = -1;\r
+ struct clk_node *dvfs_info=clk_get_dvfs_info(clk);\r
+ \r
+ DVFS_DBG("%s(%s(%lu))\n", __func__, dvfs_info->name, rate);\r
+\r
+ #if 0 // judge by reference func in rk\r
+ if (dvfs_support_clk_set_rate(dvfs_info)==false) {\r
+ DVFS_ERR("dvfs func:%s is not support!\n", __func__);\r
+ return ret;\r
+ }\r
+ #endif\r
+ \r
+ if(dvfs_info->vd&&dvfs_info->vd->vd_dvfs_target){\r
+ // mutex_lock(&vd->dvfs_mutex);\r
+ mutex_lock(&rk_dvfs_mutex);\r
+ ret = dvfs_info->vd->vd_dvfs_target(clk, rate);\r
+ mutex_unlock(&rk_dvfs_mutex);\r
+ // mutex_unlock(&vd->dvfs_mutex);\r
+ }\r
+ else\r
+ {\r
+ DVFS_WARNING("%s(%s),vd is no target callback\n", __func__, clk->name); \r
+ return -1;\r
+ }\r
+ DVFS_DBG("%s(%s(%lu)),is end\n", __func__, clk->name, rate);\r
+ return ret;\r
}\r
+EXPORT_SYMBOL(dvfs_vd_clk_set_rate);\r
\r
-int dvfs_set_rate(struct clk *clk, unsigned long rate)\r
+int dvfs_vd_clk_disable(struct clk *clk, int on)\r
{\r
- int ret = 0;\r
- struct vd_node *vd;\r
- DVFS_DBG("%s(%s(%lu))\n", __func__, clk->name, rate);\r
- if (!clk->dvfs_info) {\r
- DVFS_ERR("%s :This clk do not support dvfs!\n", __func__);\r
- ret = -1;\r
- } else {\r
- vd = clk->dvfs_info->vd;\r
+ int ret = -1;\r
+ struct clk_node *dvfs_info=clk_get_dvfs_info(clk); \r
+ DVFS_DBG("%s(%s(%s,%lu))\n", __func__, dvfs_info->name, DVFS_STR_DISABLE(on),clk_get_rate(clk));\r
+\r
+\r
+ #if 0 // judge by reference func in rk\r
+ if (dvfs_support_clk_disable(dvfs_info)==false) {\r
+ DVFS_ERR("dvfs func:%s is not support!\n", __func__);\r
+ return ret;\r
+ }\r
+ #endif\r
+ \r
+ if(dvfs_info->vd&&dvfs_info->vd->vd_clk_disable_target){\r
// mutex_lock(&vd->dvfs_mutex);\r
mutex_lock(&rk_dvfs_mutex);\r
- ret = vd->vd_dvfs_target(clk, rate);\r
+ ret = dvfs_info->vd->vd_clk_disable_target(clk, on);\r
mutex_unlock(&rk_dvfs_mutex);\r
// mutex_unlock(&vd->dvfs_mutex);\r
}\r
- DVFS_DBG("%s(%s(%lu)),is end\n", __func__, clk->name, rate);\r
+ else\r
+ {\r
+ DVFS_WARNING("%s(%s),vd is no target callback\n", __func__, clk->name); \r
+ return -1;\r
+ }\r
+ DVFS_DBG("%s(%s(%lu)),is end\n", __func__, dvfs_info->name, DVFS_STR_ON(on));\r
+\r
return ret;\r
}\r
\r
+EXPORT_SYMBOL(dvfs_vd_clk_disable);\r
+\r
static void dvfs_table_round_clk_rate(struct clk_node *dvfs_clk)\r
{\r
int i;\r
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 <linux/device.h>
\r
#include <mach/clock.h>\r
\r
-typedef int (*vd_dvfs_target_callback)(struct clk *clk, unsigned long rate);\r
-\r
+//typedef int (*vd_dvfs_target_callback)(struct clk *clk, unsigned long rate);\r
typedef int (*dvfs_set_rate_callback)(struct clk *clk, unsigned long rate);\r
-\r
typedef int (*clk_dvfs_target_callback)(struct clk *clk, unsigned long rate,\r
dvfs_set_rate_callback set_rate);\r
+typedef int (*dvfs_clk_disable_callback)(struct clk *clk,int on);\r
\r
/**\r
* struct vd_node: To Store All Voltage Domains' info\r
struct list_head pd_list;\r
struct list_head req_volt_list;\r
//struct mutex dvfs_mutex;\r
- vd_dvfs_target_callback vd_dvfs_target;\r
+ dvfs_clk_disable_callback vd_clk_disable_target;\r
+ dvfs_set_rate_callback vd_dvfs_target;\r
unsigned n_voltages;\r
int volt_list[VD_VOL_LIST_CNT];\r
};\r
struct depend_list dep_list;\r
struct cpufreq_frequency_table *dep_table;\r
};\r
-\r
+struct clk_disable_ctr {\r
+ dvfs_clk_disable_callback clk_disable_target;\r
+ struct clk_node *dvfs_clk;\r
+};\r
/**\r
* struct clk_node: To Store All dvfs clocks' info\r
* @name: Dvfs clock's Name\r
struct notifier_block *dvfs_nb;\r
struct cpufreq_frequency_table *dvfs_table;\r
clk_dvfs_target_callback clk_dvfs_target;\r
+ struct clk_disable_ctr *disable_ctr;\r
};\r
\r
struct dvfs_arm_table {\r
#define dvfs_clk_get(a,b) clk_get((a),(b))\r
#define dvfs_clk_get_rate_kz(a) (clk_get_rate((a))/1000)\r
#define dvfs_clk_set_rate(a,b) clk_set_rate((a),(b))\r
-#define dvfs_clk_enable(a) clk_enable((a))\r
-#define dvfs_clk_disable(a) clk_disable((a))\r
\r
\r
\r
int rk_regist_depends(struct depend_lookup *dep_node);\r
struct clk_node *dvfs_get_dvfs_clk_byname(char *name);\r
int vd_regulator_round_volt(struct vd_node *vd, int volt,int flags);\r
+int dvfs_vd_clk_disable_target(struct clk *clk, int on);\r
+void dvfs_clk_disable_delay_work(struct work_struct *work);\r
\r
-/******************************************************************************/\r
-\r
-int is_support_dvfs(struct clk_node *dvfs_info);\r
-int dvfs_set_rate(struct clk *clk, unsigned long rate);\r
+/*********************************if not define dvfs ,the following function is need defined func{}******************************/\r
+int dvfs_vd_clk_set_rate(struct clk *clk, unsigned long rate);\r
+int dvfs_vd_clk_disable(struct clk *clk, int on);\r
int clk_enable_dvfs(struct clk *clk);\r
int clk_disable_dvfs(struct clk *clk);\r
void dvfs_clk_register_set_rate_callback(struct clk *clk, clk_dvfs_target_callback clk_dvfs_target);\r
int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned max_rate);\r
int dvfs_clk_disable_limit(struct clk *clk);\r
int dvfs_scale_volt_direct(struct vd_node *vd_clk, int volt_new);\r
-\r
+/******************************** inline *******************************/\r
+static inline bool dvfs_support_clk_set_rate(struct clk_node *dvfs_info)\r
+{\r
+ return (dvfs_info&&dvfs_info->enable_dvfs);\r
+}\r
+static inline bool dvfs_support_clk_disable(struct clk_node *dvfs_info)\r
+{\r
+ return (dvfs_info&&dvfs_info->disable_ctr&&dvfs_info->enable_dvfs);\r
+}\r
+/********************************avs*******************************/\r
void avs_init(void);\r
void avs_init_val_get(int index,int vol,char *s);\r
int avs_set_scal_val(u8 avs_base);\r
void avs_board_init(struct avs_ctr_st *data);\r
\r
#else\r
-static inline int is_support_dvfs(struct clk_node *dvfs_info) { return 0; }\r
-static inline int dvfs_set_rate(struct clk *clk, unsigned long rate) { return 0; }\r
+static inline bool dvfs_support_clk_set_rate(struct clk_node *dvfs_info) { return 0; }\r
+static inline bool dvfs_support_clk_disable(struct clk_node *dvfs_info) { return 0; }\r
+\r
+static inline int dvfs_vd_clk_set_rate(struct clk *clk, unsigned long rate) { return 0; }\r
+static inline int dvfs_vd_clk_disable(struct clk *clk, int on) { return 0; }\r
static inline int clk_enable_dvfs(struct clk *clk) { return 0; }\r
static inline int clk_disable_dvfs(struct clk *clk) { return 0; }\r
static inline void dvfs_clk_register_set_rate_callback(struct clk *clk, clk_dvfs_target_callback clk_dvfs_target) {}\r