_RK3036_PLL_SET_CLKS(400000, 6, 400, 2, 2, 1, 0),
};
+static const struct apll_clk_set rk3368_apll_table[] = {
+ /* _RK3368_APLL_SET_CLKS(); */
+};
+
static void pll_wait_lock(struct clk_hw *hw)
{
struct clk_pll *pll = to_clk_pll(hw);
unsigned long parent_rate)
{
struct clk_pll *pll = to_clk_pll(hw);
- unsigned long flags;
- u32 refdiv, fbdiv, postdiv1, postdiv2, frac;
struct apll_clk_set *ps = (struct apll_clk_set *)(rk3036_apll_table);
+ struct clk *arm_gpll = __clk_lookup("clk_gpll");
+ struct clk *clk = hw->clk;
+ unsigned long flags, arm_gpll_rate, old_rate, temp_rate;
+ u32 temp_div;
while (ps->rate) {
if (ps->rate == rate) {
ps++;
}
- clk_debug("%s %lu\n", __func__, rate);
+ if (ps->rate != rate) {
+ clk_err("%s: unsupport arm rate %lu\n", __func__, rate);
+ return 0;
+ }
+
+ if (!arm_gpll) {
+ clk_err("clk arm_gpll is NULL!\n");
+ return 0;
+ }
+
+ old_rate = __clk_get_rate(clk);
+ arm_gpll_rate = __clk_get_rate(arm_gpll);
+ if (soc_is_rk3128() || soc_is_rk3126())
+ arm_gpll_rate /= 2;
+
+ temp_rate = (old_rate > rate) ? old_rate : rate;
+ temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
+
+ local_irq_save(flags);
+
+ if (rate >= old_rate) {
+ cru_writel(ps->clksel0, RK3036_CRU_CLKSELS_CON(0));
+ cru_writel(ps->clksel1, RK3036_CRU_CLKSELS_CON(1));
+ }
+
+ /* set div first, then select gpll */
+ if (temp_div > 1)
+ cru_writel(RK3036_CLK_CORE_DIV(temp_div), RK3036_CRU_CLKSELS_CON(0));
+ cru_writel(RK3036_CORE_SEL_PLL(1), RK3036_CRU_CLKSELS_CON(0));
+
+ clk_debug("temp select arm_gpll path, get rate %lu\n",
+ arm_gpll_rate/temp_div);
+ clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
+ temp_div);
+
+ /**************enter slow mode 24M***********/
+ /*cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);*/
+ loops_per_jiffy = LPJ_24M;
+
+ cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
+ cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
+ cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
+
clk_debug("pllcon0 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
clk_debug("pllcon1 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
clk_debug("pllcon2 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
clk_debug("clksel0 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(0)));
clk_debug("clksel1 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(1)));
- if (ps->rate == rate) {
- clk_debug("apll get a rate\n");
-
- local_irq_save(flags);
- /************select gpll_div2******************/
- cru_writel(RK3036_CORE_SEL_PLL(1), RK3036_CRU_CLKSELS_CON(0));
- /**************enter slow mode 24M***********/
- /*cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);*/
- loops_per_jiffy = LPJ_24M;
-
- cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
- cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
- cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
+
+ /*wating lock state*/
+ udelay(ps->rst_dly);
+ rk3036_pll_wait_lock(hw);
+
+ /************select apll******************/
+ cru_writel(RK3036_CORE_SEL_PLL(0), RK3036_CRU_CLKSELS_CON(0));
+ /**************return slow mode***********/
+ /*cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);*/
+
+ cru_writel(RK3036_CLK_CORE_DIV(1), RK3036_CRU_CLKSELS_CON(0));
+
+ if (rate < old_rate) {
cru_writel(ps->clksel0, RK3036_CRU_CLKSELS_CON(0));
cru_writel(ps->clksel1, RK3036_CRU_CLKSELS_CON(1));
-
- clk_debug("pllcon0 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
- clk_debug("pllcon1 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
- clk_debug("pllcon2 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
- clk_debug("clksel0 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(0)));
- clk_debug("clksel1 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(1)));
-
- /*wating lock state*/
- udelay(ps->rst_dly);
- rk3036_pll_wait_lock(hw);
-
- /************select apll******************/
- cru_writel(RK3036_CORE_SEL_PLL(0), RK3036_CRU_CLKSELS_CON(0));
- /**************return slow mode***********/
- /*cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);*/
- loops_per_jiffy = ps->lpj;
- local_irq_restore(flags);
- } else {
- /*FIXME*/
- rk3036_pll_clk_get_set(parent_rate, rate, &refdiv, &fbdiv, &postdiv1, &postdiv2, &frac);
- rk3036_pll_set_con(hw, refdiv, fbdiv, postdiv1, postdiv2, frac);
}
- clk_debug("setting OK\n");
+
+ loops_per_jiffy = ps->lpj;
+ local_irq_restore(flags);
return 0;
}
.set_rate = clk_cpll_set_rate_312xplus,
};
+static long clk_pll_round_rate_3368_apll(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk *parent = __clk_get_parent(hw->clk);
+
+ if (parent && (rate == __clk_get_rate(parent))) {
+ clk_debug("pll %s round rate=%lu equal to parent rate\n",
+ __clk_get_name(hw->clk), rate);
+ return rate;
+ }
+
+ return (apll_get_best_set(rate, rk3368_apll_table)->rate);
+}
+
+/* 1: use, 0: no use */
+#define RK3368_APLLB_USE_GPLL 1
+
+/* when define 1, we will set div to make rate change gently, but it will cost
+ more time */
+#define RK3368_APLLB_DIV_MORE 1
+
+static int clk_pll_set_rate_3368_apllb(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pll *pll = to_clk_pll(hw);
+ struct clk *clk = hw->clk;
+ struct clk *arm_gpll = __clk_lookup("clk_gpll");
+ unsigned long arm_gpll_rate, temp_rate, old_rate;
+ const struct apll_clk_set *ps;
+ u32 temp_div;
+ unsigned long flags;
+ int sel_gpll = 0;
+
+
+#if !RK3368_APLLB_USE_GPLL
+ goto CHANGE_APLL;
+#endif
+
+ /* prepare arm_gpll before reparent clk_core to it */
+ if (!arm_gpll) {
+ clk_err("clk arm_gpll is NULL!\n");
+ goto CHANGE_APLL;
+ }
+
+ arm_gpll_rate = __clk_get_rate(arm_gpll);
+ old_rate = __clk_get_rate(clk);
+
+ temp_rate = (old_rate > rate) ? old_rate : rate;
+ temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
+
+ if (temp_div > RK3368_CORE_CLK_MAX_DIV) {
+ clk_debug("temp_div %d > max_div %d\n", temp_div,
+ RK3368_CORE_CLK_MAX_DIV);
+ clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
+ __clk_get_rate(clk), arm_gpll_rate);
+ goto CHANGE_APLL;
+ }
+
+#if 0
+ if (clk_prepare(arm_gpll)) {
+ clk_err("fail to prepare arm_gpll path\n");
+ clk_unprepare(arm_gpll);
+ goto CHANGE_APLL;
+ }
+
+ if (clk_enable(arm_gpll)) {
+ clk_err("fail to enable arm_gpll path\n");
+ clk_disable(arm_gpll);
+ clk_unprepare(arm_gpll);
+ goto CHANGE_APLL;
+ }
+#endif
+
+ local_irq_save(flags);
+
+ /* select gpll */
+#if RK3368_APLLB_DIV_MORE
+ if (temp_div == 1) {
+ /* when old_rate/2 < (old_rate-arm_gpll_rate),
+ we can set div to make rate change more gently */
+ if (old_rate > (2*arm_gpll_rate)) {
+ cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
+ udelay(10);
+ cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(0));
+ udelay(10);
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+ RK3368_CRU_CLKSELS_CON(0));
+ udelay(10);
+ cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
+ udelay(10);
+ cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(0));
+ } else {
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+ RK3368_CRU_CLKSELS_CON(0));
+ }
+ } else {
+ cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(0));
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+ RK3368_CRU_CLKSELS_CON(0));
+ }
+#else
+ cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(0));
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+ RK3368_CRU_CLKSELS_CON(0));
+#endif
+
+ sel_gpll = 1;
+
+ smp_wmb();
+
+ local_irq_restore(flags);
+
+ clk_debug("temp select arm_gpll path, get rate %lu\n",
+ arm_gpll_rate/temp_div);
+ clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
+ temp_div);
+
+CHANGE_APLL:
+ ps = apll_get_best_set(rate, rk3368_apll_table);
+ clk_debug("apll will set rate %lu\n", ps->rate);
+ clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
+ ps->pllcon0, ps->pllcon1, ps->pllcon2,
+ ps->clksel0, ps->clksel1);
+
+ local_irq_save(flags);
+
+ /* If core src don't select gpll, apll need to enter slow mode
+ * before reset
+ */
+ if (!sel_gpll)
+ cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
+ pll->mode_offset);
+
+ /* PLL enter reset */
+ cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
+
+ cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
+ cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
+ cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
+
+ udelay(5);
+
+ /* return from rest */
+ cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
+
+ /* wating lock state */
+ udelay(ps->rst_dly);
+ pll_wait_lock(hw);
+
+ if (rate >= __clk_get_rate(hw->clk)) {
+ cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(0));
+ cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(1));
+ }
+
+ /* PLL return from slow mode */
+ if (!sel_gpll)
+ cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
+ pll->mode_offset);
+
+ /* reparent to apll, and set div to 1 */
+ if (sel_gpll) {
+#if RK3368_APLLB_DIV_MORE
+ if (temp_div == 1) {
+ /* when rate/2 < (old_rate-arm_gpll_rate),
+ we can set div to make rate change more gently */
+ if (rate > (2*arm_gpll_rate)) {
+ cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
+ udelay(10);
+ cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(0));
+ udelay(10);
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+ RK3368_CRU_CLKSELS_CON(0));
+ udelay(10);
+ cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
+ udelay(10);
+ cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(0));
+ } else {
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+ RK3368_CRU_CLKSELS_CON(0));
+ }
+ } else {
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+ RK3368_CRU_CLKSELS_CON(0));
+ cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(0));
+ }
+#else
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+ RK3368_CRU_CLKSELS_CON(0));
+ cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(0));
+#endif
+ }
+
+ if (rate < __clk_get_rate(hw->clk)) {
+ cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(0));
+ cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(1));
+ }
+
+ smp_wmb();
+
+ local_irq_restore(flags);
+
+ if (sel_gpll) {
+ sel_gpll = 0;
+ /* clk_disable(arm_gpll);
+ clk_unprepare(arm_gpll); */
+ }
+
+ clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
+ ps->rate,
+ cru_readl(pll->reg + RK3188_PLL_CON(0)),
+ cru_readl(pll->reg + RK3188_PLL_CON(1)),
+ cru_readl(pll->reg + RK3188_PLL_CON(2)),
+ cru_readl(pll->reg + RK3188_PLL_CON(3)),
+ cru_readl(RK3368_CRU_CLKSELS_CON(0)),
+ cru_readl(RK3368_CRU_CLKSELS_CON(1)));
+
+ return 0;
+}
+
+static const struct clk_ops clk_pll_ops_3368_apllb = {
+ .recalc_rate = clk_pll_recalc_rate_3188plus,
+ .round_rate = clk_pll_round_rate_3368_apll,
+ .set_rate = clk_pll_set_rate_3368_apllb,
+};
+
+/* 1: use, 0: no use */
+#define RK3368_APLLL_USE_GPLL 1
+
+/* when define 1, we will set div to make rate change gently, but it will cost
+ more time */
+#define RK3368_APLLL_DIV_MORE 1
+
+static int clk_pll_set_rate_3368_aplll(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pll *pll = to_clk_pll(hw);
+ struct clk *clk = hw->clk;
+ struct clk *arm_gpll = __clk_lookup("clk_gpll");
+ unsigned long arm_gpll_rate, temp_rate, old_rate;
+ const struct apll_clk_set *ps;
+ u32 temp_div;
+ unsigned long flags;
+ int sel_gpll = 0;
+
+
+#if !RK3368_APLLL_USE_GPLL
+ goto CHANGE_APLL;
+#endif
+
+ /* prepare arm_gpll before reparent clk_core to it */
+ if (!arm_gpll) {
+ clk_err("clk arm_gpll is NULL!\n");
+ goto CHANGE_APLL;
+ }
+
+ arm_gpll_rate = __clk_get_rate(arm_gpll);
+ old_rate = __clk_get_rate(clk);
+
+ temp_rate = (old_rate > rate) ? old_rate : rate;
+ temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
+
+ if (temp_div > RK3368_CORE_CLK_MAX_DIV) {
+ clk_debug("temp_div %d > max_div %d\n", temp_div,
+ RK3368_CORE_CLK_MAX_DIV);
+ clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
+ __clk_get_rate(clk), arm_gpll_rate);
+ goto CHANGE_APLL;
+ }
+
+#if 0
+ if (clk_prepare(arm_gpll)) {
+ clk_err("fail to prepare arm_gpll path\n");
+ clk_unprepare(arm_gpll);
+ goto CHANGE_APLL;
+ }
+
+ if (clk_enable(arm_gpll)) {
+ clk_err("fail to enable arm_gpll path\n");
+ clk_disable(arm_gpll);
+ clk_unprepare(arm_gpll);
+ goto CHANGE_APLL;
+ }
+#endif
+
+ local_irq_save(flags);
+
+ /* select gpll */
+#if RK3368_APLLL_DIV_MORE
+ if (temp_div == 1) {
+ /* when old_rate/2 < (old_rate-arm_gpll_rate),
+ we can set div to make rate change more gently */
+ if (old_rate > (2*arm_gpll_rate)) {
+ cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
+ udelay(10);
+ cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(2));
+ udelay(10);
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+ RK3368_CRU_CLKSELS_CON(2));
+ udelay(10);
+ cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
+ udelay(10);
+ cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(2));
+ } else {
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+ RK3368_CRU_CLKSELS_CON(2));
+ }
+ } else {
+ cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(2));
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+ RK3368_CRU_CLKSELS_CON(2));
+ }
+#else
+ cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(2));
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+ RK3368_CRU_CLKSELS_CON(2));
+#endif
+
+ sel_gpll = 1;
+
+ smp_wmb();
+
+ local_irq_restore(flags);
+
+ clk_debug("temp select arm_gpll path, get rate %lu\n",
+ arm_gpll_rate/temp_div);
+ clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
+ temp_div);
+
+CHANGE_APLL:
+ ps = apll_get_best_set(rate, rk3368_apll_table);
+ clk_debug("apll will set rate %lu\n", ps->rate);
+ clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
+ ps->pllcon0, ps->pllcon1, ps->pllcon2,
+ ps->clksel0, ps->clksel1);
+
+ local_irq_save(flags);
+
+ /* If core src don't select gpll, apll need to enter slow mode
+ * before reset
+ */
+ if (!sel_gpll)
+ cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
+ pll->mode_offset);
+
+ /* PLL enter reset */
+ cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
+
+ cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
+ cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
+ cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
+
+ udelay(5);
+
+ /* return from rest */
+ cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
+
+ /* wating lock state */
+ udelay(ps->rst_dly);
+ pll_wait_lock(hw);
+
+ if (rate >= __clk_get_rate(hw->clk)) {
+ cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(2));
+ cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(3));
+ }
+
+ /* PLL return from slow mode */
+ if (!sel_gpll)
+ cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
+ pll->mode_offset);
+
+ /* reparent to apll, and set div to 1 */
+ if (sel_gpll) {
+#if RK3368_APLLL_DIV_MORE
+ if (temp_div == 1) {
+ /* when rate/2 < (old_rate-arm_gpll_rate),
+ we can set div to make rate change more gently */
+ if (rate > (2*arm_gpll_rate)) {
+ cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
+ udelay(10);
+ cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(2));
+ udelay(10);
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+ RK3368_CRU_CLKSELS_CON(2));
+ udelay(10);
+ cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
+ udelay(10);
+ cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(2));
+ } else {
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+ RK3368_CRU_CLKSELS_CON(2));
+ }
+ } else {
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+ RK3368_CRU_CLKSELS_CON(2));
+ cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(2));
+ }
+#else
+ cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+ RK3368_CRU_CLKSELS_CON(2));
+ cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(2));
+#endif
+ }
+
+ if (rate < __clk_get_rate(hw->clk)) {
+ cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(2));
+ cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(3));
+ }
+
+ smp_wmb();
+
+ local_irq_restore(flags);
+
+ if (sel_gpll) {
+ sel_gpll = 0;
+ /* clk_disable(arm_gpll);
+ clk_unprepare(arm_gpll); */
+ }
+
+ clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
+ ps->rate,
+ cru_readl(pll->reg + RK3188_PLL_CON(0)),
+ cru_readl(pll->reg + RK3188_PLL_CON(1)),
+ cru_readl(pll->reg + RK3188_PLL_CON(2)),
+ cru_readl(pll->reg + RK3188_PLL_CON(3)),
+ cru_readl(RK3368_CRU_CLKSELS_CON(2)),
+ cru_readl(RK3368_CRU_CLKSELS_CON(3)));
+
+ return 0;
+}
+
+static const struct clk_ops clk_pll_ops_3368_aplll = {
+ .recalc_rate = clk_pll_recalc_rate_3188plus,
+ .round_rate = clk_pll_round_rate_3368_apll,
+ .set_rate = clk_pll_set_rate_3368_aplll,
+};
+
const struct clk_ops *rk_get_pll_ops(u32 pll_flags)
{
switch (pll_flags) {
case CLK_PLL_312XPLUS:
return &clk_pll_ops_312xplus;
+ case CLK_PLL_3368_APLLB:
+ return &clk_pll_ops_3368_apllb;
+
+ case CLK_PLL_3368_APLLL:
+ return &clk_pll_ops_3368_aplll;
+
default:
clk_err("%s: unknown pll_flags!\n", __func__);
return NULL;
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <asm/io.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
#include <linux/adc.h>
#include <linux/delay.h>
#include <linux/ktime.h>
#define TIMER_MS_COUNTS 1000
#define SLOPE_SECOND_COUNTS 15
#define DISCHARGE_MIN_SECOND 30
- #define CHARGE_MIN_SECOND 30
+ #define CHARGE_MIN_SECOND 45
#define CHARGE_MID_SECOND 90
#define CHARGE_MAX_SECOND 250
#define CHARGE_FULL_DELAY_TIMES 10
- #define BATT_FILENAME "/data/bat_last_capacity.dat"
+ //#define BATT_FILENAME "/data/bat_last_capacity.dat"
#define BATTERY_APK
int gDoubleVoltageCnt = 6800;
unsigned long gSecondsCnt = 0;
char gDischargeFlag[4] = {"on "};
+ static int g_old_cap = -1;
+ static int g_uboot_incre = 0;
#if 1
#define BATT_MAX_VOL_VALUE 4250/*Full charge volatge*/
}
return size;
}
+
+ static int __init adc_bootloader_setup(char *str)
+ {
+
+ if(str) {
+ printk("adc.incre is %s\n", str);
+ sscanf(str, "%d", &g_uboot_incre);
+ }
+ return 0;
+ }
+ early_param("adc.incre", adc_bootloader_setup);
+
+ static ssize_t rkbatt_show_oldcap_attrs(struct device *dev, struct device_attribute *attr, char *buf)
+ {
+ return sprintf(buf, "%d\n", g_old_cap);
+ }
+
+ static ssize_t rkbatt_restore_oldcap_attrs(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
+ {
+ int old_cap;
+
+ sscanf(buf, "%d", &old_cap);
+
+ if(old_cap >= 0 && old_cap <= 100)
+ {
+ g_old_cap = old_cap;
+ }
+ else
+ {
+ dev_err(dev, "rk29adc_restore_oldcap_attrs err\n");
+ }
+ return size;
+ }
+
+
static struct device_attribute rkbatt_attrs[] = {
__ATTR(state, 0664, rkbatt_show_state_attrs, rkbatt_restore_state_attrs),
__ATTR(debug, 0664, rkbatt_show_debug_attrs, rkbatt_restore_debug_attrs),
__ATTR(value, 0555, rkbatt_show_value_attrs, rkbatt_restore_value_attrs),
__ATTR(flag, 0555, rkbatt_show_flag_attrs, rkbatt_restore_flag_attrs),
+ __ATTR(oldcap, 0664, rkbatt_show_oldcap_attrs, rkbatt_restore_oldcap_attrs),
};
static int rk_adc_battery_iio_read(struct rk30_adc_battery_platform_data *data)
#endif
+ #if 0
static int rk30_adc_battery_load_capacity(void)
{
char value[4];
sys_write(fd, (const char __user *)value, 4);
sys_close(fd);
}
+ #endif
static BLOCKING_NOTIFIER_HEAD(adc_battery_chain_head);
int register_adc_battery_notifier(struct notifier_block *nb)
new_capacity = bat ->bat_capacity;
while( cnt -- ){
- old_capacity = rk30_adc_battery_load_capacity();
- if( old_capacity >= 0 ){
+ g_old_cap = g_old_cap + g_uboot_incre;
+ if(g_old_cap > 100)
+ g_old_cap = 100;
+ old_capacity = g_old_cap; // rk30_adc_battery_load_capacity();
+ if( old_capacity != -1 ){
break ;
}
msleep(100);
}
+ printk("func:%s; line:%d; old_capacity = %d; new_capacity = %d; g_uboot_incre = %d\n", __func__, __LINE__, old_capacity, new_capacity,g_uboot_incre);
if ((old_capacity < 0) || (old_capacity > 100)){
old_capacity = new_capacity;
//chargeing state
bat->bat_capacity = (old_capacity < 10) ? (old_capacity + 2) : old_capacity;
}else{
- bat ->bat_capacity = old_capacity + 5;
+ bat ->bat_capacity = old_capacity;
if(bat->bat_capacity == 100)
bat->bat_capacity = 99;
if(bat->bat_capacity == 0)
}
}
- rk30_adc_battery_put_capacity(bat ->bat_capacity);
+ // rk30_adc_battery_put_capacity(bat ->bat_capacity);
power_supply_changed(&bat ->bat);
power_supply_changed(&bat ->ac);
#if defined (CONFIG_BATTERY_RK30_USB_CHARGE)
// data->wq = create_singlethread_workqueue("adc_battd");
INIT_DELAYED_WORK(&data->delay_work, rk30_adc_battery_timer_work);
- if (1 == data->pdata->save_capacity) {
+ //if (1 == data->pdata->save_capacity) {
+ if (1) {
queue_delayed_work(data->wq, &data->delay_work, msecs_to_jiffies(TIMER_MS_COUNTS*10));
data ->poweron_check = 1;
}else{
static void ion_iommu_force_unmap(struct ion_buffer *buffer);
#endif
#ifdef CONFIG_ION_ROCKCHIP_SNAPSHOT
-extern char *rockchip_ion_snapshot_get(unsigned *size);
+extern char *rockchip_ion_snapshot_get(size_t *size);
extern int rockchip_ion_snapshot_debugfs(struct dentry* root);
static int ion_snapshot_save(struct ion_device *idev, size_t len);
#endif
void ion_buffer_destroy(struct ion_buffer *buffer)
{
- trace_ion_buffer_destroy("", (unsigned int)buffer, buffer->size);
+ trace_ion_buffer_destroy("", (void*)buffer, buffer->size);
if (WARN_ON(buffer->kmap_cnt > 0))
buffer->heap->ops->unmap_kernel(buffer->heap, buffer);
return handle->buffer;
}
- static void ion_handle_get(struct ion_handle *handle)
+ void ion_handle_get(struct ion_handle *handle)
{
kref_get(&handle->ref);
}
handle = ERR_PTR(ret);
}
- trace_ion_buffer_alloc(client->display_name, (unsigned int)buffer,
+ trace_ion_buffer_alloc(client->display_name, (void*)buffer,
buffer->size);
return handle;
return;
}
mutex_unlock(&client->lock);
- trace_ion_buffer_free(client->display_name, (unsigned int)handle->buffer,
+ trace_ion_buffer_free(client->display_name, (void*)handle->buffer,
handle->buffer->size);
ion_handle_put(handle);
}
vaddr = ion_handle_kmap_get(handle);
mutex_unlock(&buffer->lock);
mutex_unlock(&client->lock);
- trace_ion_kernel_map(client->display_name, (unsigned int)buffer,
- buffer->size, (unsigned int)vaddr);
+ trace_ion_kernel_map(client->display_name, (void*)buffer,
+ buffer->size, (void*)vaddr);
return vaddr;
}
EXPORT_SYMBOL(ion_map_kernel);
mutex_lock(&client->lock);
buffer = handle->buffer;
mutex_lock(&buffer->lock);
- trace_ion_kernel_unmap(client->display_name, (unsigned int)buffer,
+ trace_ion_kernel_unmap(client->display_name, (void*)buffer,
buffer->size);
ion_handle_kmap_put(handle);
mutex_unlock(&buffer->lock);
} else if (iommu->key > entry->key) {
p = &(*p)->rb_right;
} else {
- pr_err("%s: buffer %p already has mapping for domainid %x\n",
+ pr_err("%s: buffer %p already has mapping for domainid %lx\n",
__func__,
buffer,
iommu->key);
}
static struct ion_iommu_map *ion_iommu_lookup(struct ion_buffer *buffer,
- uint32_t key)
+ unsigned long key)
{
struct rb_node **p = &buffer->iommu_maps.rb_node;
struct rb_node *parent = NULL;
return ERR_PTR(-ENOMEM);
data->buffer = buffer;
- data->key = (uint32_t)iommu_dev;
+ data->key = (unsigned long)iommu_dev;
ret = buffer->heap->ops->map_iommu(buffer, iommu_dev, data,
buffer->size, buffer->flags);
}
if (buffer->size & ~PAGE_MASK) {
- pr_debug("%s: buffer size %x is not aligned to %lx", __func__,
+ pr_debug("%s: buffer size %zu is not aligned to %lx", __func__,
buffer->size, PAGE_SIZE);
ret = -EINVAL;
goto out;
}
- iommu_map = ion_iommu_lookup(buffer, (uint32_t)iommu_dev);
+ iommu_map = ion_iommu_lookup(buffer, (unsigned long)iommu_dev);
if (!iommu_map) {
pr_debug("%s: create new map for buffer(%p)\n", __func__, buffer);
iommu_map = __ion_iommu_map(buffer, iommu_dev, iova);
pr_debug("%s: buffer(%p) already mapped\n", __func__, buffer);
if (iommu_map->mapped_size != buffer->size) {
pr_err("%s: handle %p is already mapped with length"
- " %x, trying to map with length %x\n",
+ " %d, trying to map with length %zu\n",
__func__, handle, iommu_map->mapped_size, buffer->size);
ret = -EINVAL;
} else {
if (!ret)
buffer->iommu_map_cnt++;
*size = buffer->size;
- trace_ion_iommu_map(client->display_name, (unsigned int)buffer, buffer->size,
+ trace_ion_iommu_map(client->display_name, (void*)buffer, buffer->size,
dev_name(iommu_dev), *iova, *size, buffer->iommu_map_cnt);
out:
mutex_unlock(&buffer->lock);
ref);
struct ion_buffer *buffer = map->buffer;
- trace_ion_iommu_release("", (unsigned int)buffer, buffer->size,
+ trace_ion_iommu_release("", (void*)buffer, buffer->size,
"", map->iova_addr, map->mapped_size, buffer->iommu_map_cnt);
rb_erase(&map->node, &buffer->iommu_maps);
mutex_lock(&buffer->lock);
- iommu_map = ion_iommu_lookup(buffer, (uint32_t)iommu_dev);
+ iommu_map = ion_iommu_lookup(buffer, (unsigned long)iommu_dev);
if (!iommu_map) {
WARN(1, "%s: (%p) was never mapped for %p\n", __func__,
buffer->iommu_map_cnt--;
- trace_ion_iommu_unmap(client->display_name, (unsigned int)buffer, buffer->size,
+ trace_ion_iommu_unmap(client->display_name, (void*)buffer, buffer->size,
dev_name(iommu_dev), iommu_map->iova_addr,
iommu_map->mapped_size, buffer->iommu_map_cnt);
out:
while (node != NULL) {
iommu_map = rb_entry(node, struct ion_iommu_map, node);
seq_printf(s, "%16.16s: 0x%08lx 0x%08x 0x%08x %8zuKB %4d\n",
- "<iommu>", iommu_map->iova_addr, 0, 0, iommu_map->mapped_size>>10,
+ "<iommu>", iommu_map->iova_addr, 0, 0,
+ (size_t)iommu_map->mapped_size>>10,
atomic_read(&iommu_map->ref.refcount));
node = rb_next(node);
if (fd < 0)
dma_buf_put(dmabuf);
- trace_ion_buffer_share(client->display_name, (unsigned int)handle->buffer,
+ trace_ion_buffer_share(client->display_name, (void*)handle->buffer,
handle->buffer->size, fd);
return fd;
}
handle = ERR_PTR(ret);
}
- trace_ion_buffer_import(client->display_name, (unsigned int)buffer,
+ trace_ion_buffer_import(client->display_name, (void*)buffer,
buffer->size);
end:
dma_buf_put(dmabuf);
seq_printf(s, "%s Heap bitmap:\n", heap->name);
for(i = rows - 1; i>= 0; i--){
- seq_printf(s, "%.4uM@0x%08x: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- i+1, base+(i)*SZ_1M,
+ seq_printf(s, "%.4uM@0x%lx: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ i+1, (unsigned long)base+(i)*SZ_1M,
cma->bitmap[i*8 + 7],
cma->bitmap[i*8 + 6],
cma->bitmap[i*8 + 5],
cma->bitmap[i*8 + 1],
cma->bitmap[i*8]);
}
- seq_printf(s, "Heap size: %luM, Heap base: 0x%08x\n",
- (cma->count)>>8, base);
+ seq_printf(s, "Heap size: %luM, Heap base: 0x%lx\n",
+ (cma->count)>>8, (unsigned long)base);
return 0;
}
}
memset(seqf.buf, 0, seqf.size);
seqf.count = 0;
- pr_debug("%s: save snapshot 0x%x@0x%lx\n", __func__, seqf.size,
- __pa(seqf.buf));
+ pr_debug("%s: save snapshot 0x%zx@0x%lx\n", __func__, seqf.size,
+ (unsigned long)__pa(seqf.buf));
- seq_printf(&seqf, "call by comm: %s pid: %d, alloc: %uKB\n",
+ seq_printf(&seqf, "call by comm: %s pid: %d, alloc: %zuKB\n",
current->comm, current->pid, len>>10);
down_read(&idev->lock);