_RK3288_APLL_SET_CLKS(0, 1, 32, 16, 2, 2, 4, 4, 4),
};
+static const struct apll_clk_set rk3036_apll_table[] = {
+ _RK3036_APLL_SET_CLKS(1608, 1, 67, 1, 1, 1, 0, 81, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1584, 1, 66, 1, 1, 1, 0, 81, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1560, 1, 65, 1, 1, 1, 0, 81, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1536, 1, 64, 1, 1, 1, 0, 81, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1512, 1, 63, 1, 1, 1, 0, 81, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1488, 1, 62, 1, 1, 1, 0, 81, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1464, 1, 61, 1, 1, 1, 0, 81, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1440, 1, 60, 1, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1416, 1, 59, 1, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1392, 1, 58, 1, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1368, 1, 57, 1, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1344, 1, 56, 1, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1320, 1, 55, 1, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1296, 1, 54, 1, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1272, 1, 53, 1, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1248, 1, 52, 1, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1200, 1, 50, 1, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1104, 1, 46, 1, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(1008, 1, 84, 2, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(984, 1, 82, 2, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(960, 1, 80, 2, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(936, 1, 78, 2, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(912, 1, 76, 2, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(888, 1, 74, 2, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(864, 1, 72, 2, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(840, 1, 70, 2, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(816, 1, 68, 2, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(696, 1, 58, 2, 1, 1, 0, 41, 41, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(600, 1, 75, 3, 1, 1, 0, 41, 21, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(504, 1, 63, 3, 1, 1, 0, 41, 21, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(408, 1, 68, 2, 2, 1, 0, 41, 21, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(312, 1, 52, 2, 2, 1, 0, 41, 21, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(216, 1, 72, 4, 2, 1, 0, 41, 21, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(96, 1, 64, 4, 4, 1, 0, 21, 21, 41, 21, 21),
+ _RK3036_APLL_SET_CLKS(0, 1, 0, 1, 1, 1, 0, 21, 21, 41, 21, 21),
+};
+
+static const struct pll_clk_set rk3036plus_pll_com_table[] = {
+ _RK3036_PLL_SET_CLKS(297000, 2, 99, 4, 1, 1, 0),
+ _RK3036_PLL_SET_CLKS(768000, 1, 32, 1, 1, 1, 0),
+
+};
+
static void pll_wait_lock(struct clk_hw *hw)
{
struct clk_pll *pll = to_clk_pll(hw);
}
}
+static void rk3036_pll_wait_lock(struct clk_hw *hw)
+{
+ struct clk_pll *pll = to_clk_pll(hw);
+ int delay = 24000000;
+
+
+ while (delay > 0) {
+ if (cru_readl(pll->status_offset) & (1 << pll->status_shift))
+ break;
+ delay--;
+ }
+
+ if (delay == 0) {
+ clk_err("pll %s: can't lock! status_shift=%u\n"
+ "pll_con0=%08x\npll_con1=%08x\n"
+ "pll_con2=%08x\n",
+ __clk_get_name(hw->clk),
+ pll->status_shift,
+ cru_readl(pll->reg + RK3188_PLL_CON(0)),
+ cru_readl(pll->reg + RK3188_PLL_CON(1)),
+ cru_readl(pll->reg + RK3188_PLL_CON(2)));
+ while (1);
+
+ }
+}
+
+
/* get rate that is most close to target */
static const struct apll_clk_set *apll_get_best_set(unsigned long rate,
const struct apll_clk_set *table)
.set_rate = clk_pll_set_rate_3288_apll,
};
+/* CLK_PLL_3036_APLL type ops */
+#define FRAC_MODE 0
+static unsigned long rk3036_pll_clk_recalc(struct clk_hw *hw,
+unsigned long parent_rate)
+{
+ struct clk_pll *pll = to_clk_pll(hw);
+ unsigned long rate;
+ unsigned int dsmp = 0;
+ u64 rate64 = 0, frac_rate64 = 0;
+
+ dsmp = RK3036_PLL_GET_DSMPD(cru_readl(pll->reg + RK3188_PLL_CON(1)));
+
+ if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
+ u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
+ u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
+ u32 pll_con2 = cru_readl(pll->reg + RK3188_PLL_CON(2));
+ /*integer mode*/
+ rate64 = (u64)parent_rate * RK3036_PLL_GET_FBDIV(pll_con0);
+ do_div(rate64, RK3036_PLL_GET_REFDIV(pll_con1));
+
+ if (FRAC_MODE == dsmp) {
+ /*fractional mode*/
+ frac_rate64 = (u64)parent_rate
+ * RK3036_PLL_GET_FRAC(pll_con2);
+ do_div(frac_rate64, RK3036_PLL_GET_REFDIV(pll_con1));
+ rate64 += frac_rate64 >> 24;
+ clk_debug("%s frac_rate=%llu(%08x/2^24) by pass mode\n",
+ __func__, frac_rate64 >> 24,
+ RK3036_PLL_GET_FRAC(pll_con2));
+ }
+ do_div(rate64, RK3036_PLL_GET_POSTDIV1(pll_con0));
+ do_div(rate64, RK3036_PLL_GET_POSTDIV2(pll_con1));
+
+ rate = rate64;
+ } else {
+ rate = parent_rate;
+ clk_debug("pll_clk_recalc rate=%lu by pass mode\n", rate);
+ }
+ return rate;
+}
+
+static unsigned long clk_pll_recalc_rate_3036_apll(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ return rk3036_pll_clk_recalc(hw, parent_rate);
+}
+
+static long clk_pll_round_rate_3036_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, rk3036_apll_table)->rate);
+}
+
+static int rk3036_pll_clk_set_rate(struct pll_clk_set *clk_set,
+ struct clk_hw *hw)
+{
+ struct clk_pll *pll = to_clk_pll(hw);
+
+ /*enter slowmode*/
+ cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
+ pll->mode_offset);
+
+ cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
+ cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
+ cru_writel(clk_set->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)));
+ /*wating lock state*/
+ udelay(clk_set->rst_dly);
+ rk3036_pll_wait_lock(hw);
+
+ /*return form slow*/
+ cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
+ pll->mode_offset);
+
+ return 0;
+}
+
+#define MIN_FOUTVCO_FREQ (400 * 1000 * 1000)
+#define MAX_FOUTVCO_FREQ (1600 * 1000 * 1000)
+static int rk3036_pll_clk_set_postdiv(unsigned long fout_hz,
+u32 *postdiv1, u32 *postdiv2, u32 *foutvco)
+{
+ if (fout_hz < MIN_FOUTVCO_FREQ) {
+ for (*postdiv1 = 1; *postdiv1 <= 7; (*postdiv1)++)
+ for (*postdiv2 = 1; *postdiv2 <= 7; (*postdiv2)++) {
+ if (fout_hz * (*postdiv1) * (*postdiv2)
+ >= MIN_FOUTVCO_FREQ && fout_hz
+ * (*postdiv1) * (*postdiv2)
+ <= MAX_FOUTVCO_FREQ) {
+ *foutvco = fout_hz * (*postdiv1)
+ * (*postdiv2);
+ return 0;
+ }
+ }
+ clk_debug("CANNOT FINE postdiv1/2 to make fout in range from 400M to 1600M, fout = %lu\n",
+ fout_hz);
+ } else {
+ *postdiv1 = 1;
+ *postdiv2 = 1;
+ }
+ return 0;
+}
+
+static int rk3036_pll_clk_get_set(unsigned long fin_hz, unsigned long fout_hz,
+ u32 *refdiv, u32 *fbdiv, u32 *postdiv1,
+ u32 *postdiv2, u32 *frac)
+{
+ /* FIXME set postdiv1/2 always 1*/
+ u32 gcd, foutvco = fout_hz;
+ u64 fin_64, frac_64;
+ u32 f_frac;
+
+ if (!fin_hz || !fout_hz || fout_hz == fin_hz)
+ return -1;
+
+ rk3036_pll_clk_set_postdiv(fout_hz, postdiv1, postdiv2, &foutvco);
+ if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
+ fin_hz /= MHZ;
+ foutvco /= MHZ;
+ gcd = clk_gcd(fin_hz, foutvco);
+ *refdiv = fin_hz / gcd;
+ *fbdiv = foutvco / gcd;
+
+ *frac = 0;
+
+ clk_debug("fin=%lu,fout=%lu,gcd=%u,refdiv=%u,fbdiv=%u,postdiv1=%u,postdiv2=%u,frac=%u\n",
+ fin_hz, fout_hz, gcd, *refdiv, *fbdiv, *postdiv1, *postdiv2, *frac);
+ } else {
+ clk_debug("******frac div running, fin_hz=%lu, fout_hz=%lu,fin_INT_mhz=%lu, fout_INT_mhz=%lu\n",
+ fin_hz, fout_hz, fin_hz / MHZ * MHZ, fout_hz / MHZ * MHZ);
+ clk_debug("******frac get postdiv1=%u, postdiv2=%u,foutvco=%u\n",
+ *postdiv1, *postdiv2, foutvco);
+ gcd = clk_gcd(fin_hz / MHZ, foutvco / MHZ);
+ *refdiv = fin_hz / MHZ / gcd;
+ *fbdiv = foutvco / MHZ / gcd;
+ clk_debug("******frac get refdiv=%u, fbdiv=%u\n", *refdiv, *fbdiv);
+
+ *frac = 0;
+
+ f_frac = (foutvco % MHZ);
+ fin_64 = fin_hz;
+ do_div(fin_64, (u64)*refdiv);
+ frac_64 = (u64)f_frac << 24;
+ do_div(frac_64, fin_64);
+ *frac = (u32) frac_64;
+ clk_debug("frac=%x\n", *frac);
+ }
+ return 0;
+}
+static int rk3036_pll_set_con(struct clk_hw *hw, u32 refdiv, u32 fbdiv, u32 postdiv1, u32 postdiv2, u32 frac)
+{
+ struct pll_clk_set temp_clk_set;
+ temp_clk_set.pllcon0 = RK3036_PLL_SET_FBDIV(fbdiv) | RK3036_PLL_SET_POSTDIV1(postdiv1);
+ temp_clk_set.pllcon1 = RK3036_PLL_SET_REFDIV(refdiv) | RK3036_PLL_SET_POSTDIV2(postdiv2);
+ if (frac != 0)
+ temp_clk_set.pllcon1 |= RK3036_PLL_SET_DSMPD(0);
+ else
+ temp_clk_set.pllcon1 |= RK3036_PLL_SET_DSMPD(1);
+
+ temp_clk_set.pllcon2 = RK3036_PLL_SET_FRAC(frac);
+ temp_clk_set.rst_dly = 0;
+ clk_debug("setting....\n");
+ return rk3036_pll_clk_set_rate(&temp_clk_set, hw);
+}
+
+static int clk_pll_set_rate_3036_apll(struct clk_hw *hw, unsigned long rate,
+ 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);
+
+ while (ps->rate) {
+ if (ps->rate == rate) {
+ break;
+ }
+ ps++;
+ }
+
+ clk_debug("%s %lu\n", __func__, rate);
+ 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) {
+ printk("apll get a rate\n");
+
+ /*enter slowmode*/
+ local_irq_save(flags);
+ 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));
+ 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);
+
+ /*return form slow*/
+ 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");
+
+ return 0;
+}
+static const struct clk_ops clk_pll_ops_3036_apll = {
+ .recalc_rate = clk_pll_recalc_rate_3036_apll,
+ .round_rate = clk_pll_round_rate_3036_apll,
+ .set_rate = clk_pll_set_rate_3036_apll,
+};
+
+
+/* CLK_PLL_3036_plus_autotype ops */
+
+static long clk_pll_round_rate_3036plus_auto(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 (pll_com_get_best_set(rate, rk3036plus_pll_com_table)->rate);
+}
+
+static int clk_pll_set_rate_3036plus_auto(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3036plus_pll_com_table);
+
+ clk_debug("******%s\n", __func__);
+ while (clk_set->rate) {
+ clk_debug("******%s clk_set->rate=%lu\n", __func__, clk_set->rate);
+ if (clk_set->rate == rate) {
+ break;
+ }
+ clk_set++;
+ }
+ if (clk_set->rate == rate) {
+ rk3036_pll_clk_set_rate(clk_set, hw);
+ } else {
+ clk_debug("gpll is no corresponding rate=%lu\n", rate);
+ return -1;
+ }
+ clk_debug("******%s end\n", __func__);
+
+ return 0;
+}
+static const struct clk_ops clk_pll_ops_3036plus_auto = {
+ .recalc_rate = clk_pll_recalc_rate_3036_apll,
+ .round_rate = clk_pll_round_rate_3036plus_auto,
+ .set_rate = clk_pll_set_rate_3036plus_auto,
+};
const struct clk_ops *rk_get_pll_ops(u32 pll_flags)
{
case CLK_PLL_3188PLUS_AUTO:
return &clk_pll_ops_3188plus_auto;
+ case CLK_PLL_3036_APLL:
+ return &clk_pll_ops_3036_apll;
+
+ case CLK_PLL_3036PLUS_AUTO:
+ return &clk_pll_ops_3036plus_auto;
+
default:
clk_err("%s: unknown pll_flags!\n", __func__);
return NULL;
.clksel1 = RK3288_CLK_L2RAM_DIV(l2_div) | RK3288_ATCLK_DIV(atclk_div) | RK3288_PCLK_DBG_DIV(pclk_dbg_div),\
.lpj = (CLK_LOOPS_JIFFY_REF*_mhz) / CLK_LOOPS_RATE_REF,\
}
+/***************************RK3036 PLL**************************************/
+#define LPJ_24M (CLK_LOOPS_JIFFY_REF * 24) / CLK_LOOPS_RATE_REF
+/*****cru reg offset*****/
+#define RK3036_CRU_CLKSEL_CON 0x44
+#define RK3036_CRU_CLKGATE_CON 0xd0
+#define RK3036_CRU_GLB_SRST_FST 0x100
+#define RK3036_CRU_GLB_SRST_SND 0x104
+#define RK3036_CRU_SOFTRST_CON 0x110
+
+#define RK3036_CRU_CLKSELS_CON_CNT (35)
+#define RK3036_CRU_CLKSELS_CON(i) (RK3036_CRU_CLKSEL_CON + ((i) * 4))
+
+#define RK3036_CRU_CLKGATES_CON_CNT (10)
+#define RK3036_CRU_CLKGATES_CON(i) (RK3036_CRU_CLKGATE_CON + ((i) * 4))
+
+#define RK3036_CRU_SOFTRSTS_CON_CNT (9)
+#define RK3036_CRU_SOFTRSTS_CON(i) (RK3036_CRU_SOFTRST_CON + ((i) * 4))
+
+/*PLL_CON 0,1,2*/
+#define RK3036_PLL_PWR_ON (0)
+#define RK3036_PLL_PWR_DN (1)
+#define RK3036_PLL_BYPASS (1 << 15)
+#define RK3036_PLL_NO_BYPASS (0 << 15)
+/*con0*/
+#define RK3036_PLL_BYPASS_SHIFT (15)
+
+#define RK3036_PLL_POSTDIV1_MASK (0x7)
+#define RK3036_PLL_POSTDIV1_SHIFT (12)
+#define RK3036_PLL_FBDIV_MASK (0xfff)
+#define RK3036_PLL_FBDIV_SHIFT (0)
+
+/*con1*/
+#define RK3036_PLL_RSTMODE_SHIFT (15)
+#define RK3036_PLL_RST_SHIFT (14)
+#define RK3036_PLL_PWR_DN_SHIFT (13)
+#define RK3036_PLL_DSMPD_SHIFT (12)
+#define RK3036_PLL_LOCK_SHIFT (10)
+
+#define RK3036_PLL_POSTDIV2_MASK (0x7)
+#define RK3036_PLL_POSTDIV2_SHIFT (6)
+#define RK3036_PLL_REFDIV_MASK (0x3f)
+#define RK3036_PLL_REFDIV_SHIFT (0)
+
+/*con2*/
+#define RK3036_PLL_FOUT4PHASE_PWR_DN_SHIFT (27)
+#define RK3036_PLL_FOUTVCO_PWR_DN_SHIFT (26)
+#define RK3036_PLL_FOUTPOSTDIV_PWR_DN_SHIFT (25)
+#define RK3036_PLL_DAC_PWR_DN_SHIFT (24)
+
+#define RK3036_PLL_FRAC_MASK (0xffffff)
+#define RK3036_PLL_FRAC_SHIFT (0)
+
+#define CRU_GET_REG_BIT_VAL(reg, bits_shift) (((reg) >> (bits_shift)) & (0x1))
+#define CRU_GET_REG_BITS_VAL(reg, bits_shift, msk) (((reg) >> (bits_shift)) & (msk))
+#define CRU_SET_BIT(val, bits_shift) (((val) & (0x1)) << (bits_shift))
+#define CRU_W_MSK(bits_shift, msk) ((msk) << ((bits_shift) + 16))
+
+#define CRU_W_MSK_SETBITS(val, bits_shift, msk) (CRU_W_MSK(bits_shift, msk) \
+ | CRU_SET_BITS(val, bits_shift, msk))
+#define CRU_W_MSK_SETBIT(val, bits_shift) (CRU_W_MSK(bits_shift, 0x1) \
+ | CRU_SET_BIT(val, bits_shift))
+
+#define RK3036_PLL_SET_REFDIV(val) CRU_W_MSK_SETBITS(val, RK3036_PLL_REFDIV_SHIFT, RK3036_PLL_REFDIV_MASK)
+#define RK3036_PLL_SET_FBDIV(val) CRU_W_MSK_SETBITS(val, RK3036_PLL_FBDIV_SHIFT, RK3036_PLL_FBDIV_MASK)
+#define RK3036_PLL_SET_POSTDIV1(val) CRU_W_MSK_SETBITS(val, RK3036_PLL_POSTDIV1_SHIFT, RK3036_PLL_POSTDIV1_MASK)
+#define RK3036_PLL_SET_POSTDIV2(val) CRU_W_MSK_SETBITS(val, RK3036_PLL_POSTDIV2_SHIFT, RK3036_PLL_POSTDIV2_MASK)
+#define RK3036_PLL_SET_FRAC(val) CRU_SET_BITS(val, RK3036_PLL_FRAC_SHIFT, RK3036_PLL_FRAC_MASK)
+
+#define RK3036_PLL_GET_REFDIV(reg) CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_REFDIV_SHIFT, RK3036_PLL_REFDIV_MASK)
+#define RK3036_PLL_GET_FBDIV(reg) CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_FBDIV_SHIFT, RK3036_PLL_FBDIV_MASK)
+#define RK3036_PLL_GET_POSTDIV1(reg) CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_POSTDIV1_SHIFT, RK3036_PLL_POSTDIV1_MASK)
+#define RK3036_PLL_GET_POSTDIV2(reg) CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_POSTDIV2_SHIFT, RK3036_PLL_POSTDIV2_MASK)
+#define RK3036_PLL_GET_FRAC(reg) CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_FRAC_SHIFT, RK3036_PLL_FRAC_MASK)
+
+/*#define APLL_SET_BYPASS(val) CRU_SET_BIT(val, PLL_BYPASS_SHIFT)*/
+#define RK3036_PLL_SET_DSMPD(val) CRU_W_MSK_SETBIT(val, RK3036_PLL_DSMPD_SHIFT)
+#define RK3036_PLL_GET_DSMPD(reg) CRU_GET_REG_BIT_VAL(reg, RK3036_PLL_DSMPD_SHIFT)
+/*******************CLKSEL0 BITS***************************/
+#define RK3036_CLK_SET_DIV_CON_SUB1(val, bits_shift, msk) CRU_W_MSK_SETBITS((val - 1), bits_shift, msk)
+
+#define RK3036_CPU_CLK_PLL_SEL_SHIFT (14)
+#define RK3036_CPU_CLK_PLL_SEL_MASK (0x3)
+#define RK3036_CORE_CLK_PLL_SEL_SHIFT (7)
+#define RK3036_SEL_APLL (0)
+#define RK3036_SEL_GPLL (1)
+#define RK3036_CPU_SEL_PLL(plls) CRU_W_MSK_SETBITS(plls, RK3036_CPU_CLK_PLL_SEL_SHIFT, RK3036_CPU_CLK_PLL_SEL_MASK)
+#define RK3036_CORE_SEL_PLL(plls) CRU_W_MSK_SETBIT(plls, RK3036_CORE_CLK_PLL_SEL_SHIFT)
+
+#define RK3036_ACLK_CPU_DIV_MASK (0x1f)
+#define RK3036_ACLK_CPU_DIV_SHIFT (8)
+#define RK3036_A9_CORE_DIV_MASK (0x1f)
+#define RK3036_A9_CORE_DIV_SHIFT (0)
+
+#define RATIO_11 (1)
+#define RATIO_21 (2)
+#define RATIO_41 (4)
+#define RATIO_81 (8)
+
+#define RK3036_ACLK_CPU_DIV(val) RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_ACLK_CPU_DIV_SHIFT, RK3036_ACLK_CPU_DIV_MASK)
+#define RK3036_CLK_CORE_DIV(val) RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_A9_CORE_DIV_SHIFT, RK3036_A9_CORE_DIV_MASK)
+/*******************CLKSEL1 BITS***************************/
+#define RK3036_PCLK_CPU_DIV_MASK (0x7)
+#define RK3036_PCLK_CPU_DIV_SHIFT (12)
+#define RK3036_HCLK_CPU_DIV_MASK (0x3)
+#define RK3036_HCLK_CPU_DIV_SHIFT (8)
+#define RK3036_ACLK_CORE_DIV_MASK (0x7)
+#define RK3036_ACLK_CORE_DIV_SHIFT (4)
+#define RK3036_CORE_PERIPH_DIV_MASK (0xf)
+#define RK3036_CORE_PERIPH_DIV_SHIFT (0)
+
+#define RK3036_PCLK_CPU_DIV(val) RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_PCLK_CPU_DIV_SHIFT, RK3036_PCLK_CPU_DIV_MASK)
+#define RK3036_HCLK_CPU_DIV(val) RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_HCLK_CPU_DIV_SHIFT, RK3036_HCLK_CPU_DIV_MASK)
+#define RK3036_ACLK_CORE_DIV(val) RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_ACLK_CORE_DIV_SHIFT, RK3036_ACLK_CORE_DIV_MASK)
+#define RK3036_CLK_CORE_PERI_DIV(val) RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_CORE_PERIPH_DIV_SHIFT, RK3036_CORE_PERIPH_DIV_MASK)
+
+/*******************clksel10***************************/
+#define RK3036_PERI_PLL_SEL_SHIFT 14
+#define RK3036_PERI_PLL_SEL_MASK (0x3)
+#define RK3036_PERI_PCLK_DIV_MASK (0x3)
+#define RK3036_PERI_PCLK_DIV_SHIFT (12)
+#define RK3036_PERI_HCLK_DIV_MASK (0x3)
+#define RK3036_PERI_HCLK_DIV_SHIFT (8)
+#define RK3036_PERI_ACLK_DIV_MASK (0x1f)
+#define RK3036_PERI_ACLK_DIV_SHIFT (0)
+
+#define RK3036_SEL_3PLL_APLL (0)
+#define RK3036_SEL_3PLL_DPLL (1)
+#define RK3036_SEL_3PLL_GPLL (2)
+
+
+#define RK3036_PERI_CLK_SEL_PLL(plls) CRU_W_MSK_SETBITS(plls, RK3036_PERI_PLL_SEL_SHIFT, RK3036_PERI_PLL_SEL_MASK)
+#define RK3036_PERI_SET_ACLK_DIV(val) RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_PERI_ACLK_DIV_SHIFT, RK3036_PERI_ACLK_DIV_MASK)
+
+/*******************gate BITS***************************/
+#define RK3036_CLK_GATE_CLKID_CONS(i) RK3036_CRU_CLKGATES_CON((i) / 16)
+
+#define RK3036_CLK_GATE(i) (1 << ((i)%16))
+#define RK3036_CLK_UN_GATE(i) (0)
+
+#define RK3036_CLK_GATE_W_MSK(i) (1 << (((i) % 16) + 16))
+#define RK3036_CLK_GATE_CLKID(i) (16 * (i))
+
+#define _RK3036_APLL_SET_CLKS(_mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac, \
+ _periph_div, _aclk_core_div, _axi_div, _apb_div, _ahb_div) \
+{ \
+ .rate = (_mhz) * MHZ, \
+ .pllcon0 = RK3036_PLL_SET_POSTDIV1(_postdiv1) | RK3036_PLL_SET_FBDIV(_fbdiv), \
+ .pllcon1 = RK3036_PLL_SET_DSMPD(_dsmpd) | RK3036_PLL_SET_POSTDIV2(_postdiv2) | RK3036_PLL_SET_REFDIV(_refdiv), \
+ .pllcon2 = RK3036_PLL_SET_FRAC(_frac), \
+ .clksel1 = RK3036_ACLK_CORE_DIV(RATIO_##_aclk_core_div) | RK3036_CLK_CORE_PERI_DIV(RATIO_##_periph_div), \
+ .lpj = (CLK_LOOPS_JIFFY_REF * _mhz) / CLK_LOOPS_RATE_REF, \
+ .rst_dly = 0,\
+}
+
+#define _RK3036_PLL_SET_CLKS(_mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac) \
+{ \
+ .rate = (_mhz) * KHZ, \
+ .pllcon0 = RK3036_PLL_SET_POSTDIV1(_postdiv1) | RK3036_PLL_SET_FBDIV(_fbdiv), \
+ .pllcon1 = RK3036_PLL_SET_DSMPD(_dsmpd) | RK3036_PLL_SET_POSTDIV2(_postdiv2) | RK3036_PLL_SET_REFDIV(_refdiv), \
+ .pllcon2 = RK3036_PLL_SET_FRAC(_frac), \
+}
struct pll_clk_set {
unsigned long rate;