Loading drivers/clk/msm/clock-local2.c +2 −2 Original line number Diff line number Diff line Loading @@ -1517,8 +1517,8 @@ static int set_rate_pixel(struct clk *clk, unsigned long rate) { struct rcg_clk *rcg = to_rcg_clk(clk); struct clk_freq_tbl *pixel_freq = rcg->current_freq; int frac_num[] = {3, 2, 4, 1}; int frac_den[] = {8, 9, 9, 1}; int frac_num[] = {1, 2, 4, 3, 2}; int frac_den[] = {1, 3, 9, 8, 9}; int delta = 100000; int i, rc; Loading drivers/clk/msm/mdss/mdss-dsi-pll-8998.c +294 −105 Original line number Diff line number Diff line Loading @@ -152,8 +152,6 @@ struct dsi_pll_regs { struct dsi_pll_config { u32 ref_freq; bool div_override; u32 output_div; bool ignore_frac; bool disable_prescaler; bool enable_ssc; Loading Loading @@ -212,7 +210,6 @@ static void dsi_pll_setup_config(struct dsi_pll_8998 *pll, struct dsi_pll_config *config = &pll->pll_configuration; config->ref_freq = 19200000; config->output_div = 1; config->dec_bits = 8; config->frac_bits = 18; config->lock_timer = 64; Loading @@ -222,7 +219,6 @@ static void dsi_pll_setup_config(struct dsi_pll_8998 *pll, config->thresh_cycles = 32; config->refclk_cycles = 256; config->div_override = false; config->ignore_frac = false; config->disable_prescaler = false; config->enable_ssc = rsc->ssc_en; Loading @@ -243,54 +239,14 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_8998 *pll, { struct dsi_pll_config *config = &pll->pll_configuration; struct dsi_pll_regs *regs = &pll->reg_setup; u64 target_freq; u64 fref = rsc->vco_ref_clk_rate; u32 computed_output_div, div_log = 0; u64 pll_freq; u64 divider; u64 dec, dec_multiple; u32 frac; u64 multiplier; u32 i; target_freq = rsc->vco_current_rate; pr_debug("target_freq = %llu\n", target_freq); if (config->div_override) { computed_output_div = config->output_div; /* * Computed_output_div = 2 ^ div_log * To get div_log from output div just get the index of the * 1 bit in the value. * div_log ranges from 0-3. so check the 4 lsbs */ for (i = 0; i < 4; i++) { if (computed_output_div & (1 << i)) { div_log = i; break; } } } else { if (target_freq < MHZ_250) { computed_output_div = 8; div_log = 3; } else if (target_freq < MHZ_500) { computed_output_div = 4; div_log = 2; } else if (target_freq < MHZ_1000) { computed_output_div = 2; div_log = 1; } else { computed_output_div = 1; div_log = 0; } } pr_debug("computed_output_div = %d\n", computed_output_div); pll_freq = target_freq * computed_output_div; pll_freq = rsc->vco_current_rate; if (config->disable_prescaler) divider = fref; Loading @@ -315,7 +271,6 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_8998 *pll, else regs->pll_clock_inverters = 0; regs->pll_outdiv_rate = div_log; regs->pll_lockdet_rate = config->lock_timer; regs->decimal_div_start = dec; regs->frac_div_start_low = (frac & 0xff); Loading Loading @@ -478,7 +433,6 @@ static void dsi_pll_commit(struct dsi_pll_8998 *pll, MDSS_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_HIGH_1, reg->frac_div_start_high); MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCKDET_RATE_1, 0x40); MDSS_PLL_REG_W(pll_base, PLL_PLL_OUTDIV_RATE, reg->pll_outdiv_rate); MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_DELAY, 0x06); MDSS_PLL_REG_W(pll_base, PLL_CMODE, 0x10); MDSS_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS, reg->pll_clock_inverters); Loading Loading @@ -597,11 +551,23 @@ static int dsi_pll_enable(struct dsi_pll_vco_clk *vco) { int rc; struct mdss_pll_resources *rsc = vco->priv; struct dsi_pll_8998 *pll = rsc->priv; struct dsi_pll_regs *regs = &pll->reg_setup; dsi_pll_enable_pll_bias(rsc); if (rsc->slave) dsi_pll_enable_pll_bias(rsc->slave); /* * The PLL out dividers are fixed divider clocks and hence the * set_div is not called during set_rate cycle of the tree. * The outdiv rate is therefore set in the pll out mux's set_sel * callback. But that will be called only after vco's set rate. * Hence PLL out div value is set here before locking the PLL. */ MDSS_PLL_REG_W(rsc->pll_base, PLL_PLL_OUTDIV_RATE, regs->pll_outdiv_rate); /* Start PLL */ MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_PLL_CNTRL, 0x01); Loading Loading @@ -728,7 +694,9 @@ static int vco_8998_prepare(struct clk *c) static unsigned long dsi_pll_get_vco_rate(struct clk *c) { struct dsi_pll_vco_clk *vco = to_vco_clk(c); struct mdss_pll_resources *pll = vco->priv; struct mdss_pll_resources *rsc = vco->priv; struct dsi_pll_8998 *pll = rsc->priv; struct dsi_pll_regs *regs = &pll->reg_setup; int rc; u64 ref_clk = vco->ref_clk_rate; u64 vco_rate; Loading @@ -738,27 +706,30 @@ static unsigned long dsi_pll_get_vco_rate(struct clk *c) u32 outdiv; u64 pll_freq, tmp64; rc = mdss_pll_resource_enable(pll, true); rc = mdss_pll_resource_enable(rsc, true); if (rc) { pr_err("failed to enable pll(%d) resource, rc=%d\n", pll->index, rc); rsc->index, rc); return 0; } dec = MDSS_PLL_REG_R(pll->pll_base, PLL_DECIMAL_DIV_START_1); dec = MDSS_PLL_REG_R(rsc->pll_base, PLL_DECIMAL_DIV_START_1); dec &= 0xFF; frac = MDSS_PLL_REG_R(pll->pll_base, PLL_FRAC_DIV_START_LOW_1); frac |= ((MDSS_PLL_REG_R(pll->pll_base, PLL_FRAC_DIV_START_MID_1) & frac = MDSS_PLL_REG_R(rsc->pll_base, PLL_FRAC_DIV_START_LOW_1); frac |= ((MDSS_PLL_REG_R(rsc->pll_base, PLL_FRAC_DIV_START_MID_1) & 0xFF) << 8); frac |= ((MDSS_PLL_REG_R(pll->pll_base, PLL_FRAC_DIV_START_HIGH_1) & frac |= ((MDSS_PLL_REG_R(rsc->pll_base, PLL_FRAC_DIV_START_HIGH_1) & 0x3) << 16); /* OUTDIV_1:0 field is (log(outdiv, 2)) */ outdiv = MDSS_PLL_REG_R(pll->pll_base, PLL_PLL_OUTDIV_RATE); outdiv = MDSS_PLL_REG_R(rsc->pll_base, PLL_PLL_OUTDIV_RATE); outdiv &= 0x3; regs->pll_outdiv_rate = outdiv; outdiv = 1 << outdiv; /* Loading @@ -776,7 +747,7 @@ static unsigned long dsi_pll_get_vco_rate(struct clk *c) pr_debug("dec=0x%x, frac=0x%x, outdiv=%d, vco=%llu\n", dec, frac, outdiv, vco_rate); (void)mdss_pll_resource_enable(pll, false); (void)mdss_pll_resource_enable(rsc, false); return (unsigned long)vco_rate; } Loading Loading @@ -930,6 +901,26 @@ static int bit_clk_set_div(struct div_clk *clk, int div) return rc; } static int dsi_pll_out_set_mux_sel(struct mux_clk *clk, int sel) { struct mdss_pll_resources *rsc = clk->priv; struct dsi_pll_8998 *pll = rsc->priv; struct dsi_pll_regs *regs = &pll->reg_setup; regs->pll_outdiv_rate = sel; return 0; } static int dsi_pll_out_get_mux_sel(struct mux_clk *clk) { struct mdss_pll_resources *rsc = clk->priv; struct dsi_pll_8998 *pll = rsc->priv; struct dsi_pll_regs *regs = &pll->reg_setup; return regs->pll_outdiv_rate; } static int post_vco_clk_get_div(struct div_clk *clk) { int rc; Loading Loading @@ -1125,43 +1116,66 @@ static struct clk_mux_ops mdss_mux_ops = { .get_mux_sel = mdss_get_mux_sel, }; static struct clk_mux_ops mdss_pll_out_mux_ops = { .set_mux_sel = dsi_pll_out_set_mux_sel, .get_mux_sel = dsi_pll_out_get_mux_sel, }; /* * Clock tree for generating DSI byte and pixel clocks. * * * +---------------+ * | vco_clk | * | | * +-------+-------+ * | * +----------------------+------------------+ * | * +-------+--------+------------------+-----------------+ * | | | | * +------v-------+ +------v-------+ +-------v------+ +------v-------+ * | pll_out_div1 | | pll_out_div2 | | pll_out_div4 | | pll_out_div8 | * | DIV(1) | | DIV(2) | | DIV(4) | | DIV(8) | * +------+-------+ +------+-------+ +-------+------+ +------+-------+ * | | | | * +------------+ | +--------------+ | * | | | +---------------------------+ * | | | | * +--v---v---v----v--+ * \ pll_out_mux / * \ / * +------+-----+ * | * +---------------+-----------------+ * | | | * +-------v-------+ +-------v-------+ +-------v-------+ * +------v-----+ +-------v-------+ +-------v-------+ * | bitclk_src | | post_vco_div1 | | post_vco_div4 | * | DIV(1..15) | +-------+-------+ +-------+-------+ * +-------+-------+ | | * | +------------+ | * +--------------------+ | | * Shadow Path | | | | * + +-------v-------+ +------v------+ +---v-----v------+ * | DIV(1..15) | + DIV(1) | | DIV(4) | * +------+-----+ +-------+-------+ +-------+-------+ * | | | * Shadow | | +---------------------+ * Path | +-----------------------------+ | * + | | | * | +---------------------------------+ | | * | | | | | * | +------v------=+ +------v-------+ +-v---------v----+ * | | byteclk_src | | post_bit_div | \ post_vco_mux / * | | DIV(8) | | DIV(1,2) | \ / * | +-------+-------+ +------+------+ +---+------+ * | +------+-------+ +------+-------+ +---+------+ * | | | | * | | | +----------+ * | | | | * | | +------+ +----+ * | +--------+ | | * | | +----v-----v------+ * +-v---------v----+ \ pclk_src_mux / * +-v--------v---------+ \ pclk_src_mux / * \ byteclk_mux / \ / * \ / +-----+-----+ * +----+-----+ | Shadow Path * | | + * v +-----v------+ | * +------+-------+ | Shadow * | | Path * v +-----v------+ + * dsi_byte_clk | pclk_src | | * | DIV(1..15) | | * +-----+------+ | * | | * | | * +--------+ | * +------+ | * | | * +---v----v----+ * \ pclk_mux / Loading @@ -1186,6 +1200,83 @@ static struct dsi_pll_vco_clk dsi0pll_vco_clk = { }, }; static struct div_clk dsi0pll_pll_out_div1 = { .data = { .div = 1, .min_div = 1, .max_div = 1, }, .c = { .parent = &dsi0pll_vco_clk.c, .dbg_name = "dsi0pll_pll_out_div1", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi0pll_pll_out_div1.c), } }; static struct div_clk dsi0pll_pll_out_div2 = { .data = { .div = 2, .min_div = 2, .max_div = 2, }, .c = { .parent = &dsi0pll_vco_clk.c, .dbg_name = "dsi0pll_pll_out_div2", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi0pll_pll_out_div2.c), } }; static struct div_clk dsi0pll_pll_out_div4 = { .data = { .div = 4, .min_div = 4, .max_div = 4, }, .c = { .parent = &dsi0pll_vco_clk.c, .dbg_name = "dsi0pll_pll_out_div4", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi0pll_pll_out_div4.c), } }; static struct div_clk dsi0pll_pll_out_div8 = { .data = { .div = 8, .min_div = 8, .max_div = 8, }, .c = { .parent = &dsi0pll_vco_clk.c, .dbg_name = "dsi0pll_pll_out_div8", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi0pll_pll_out_div8.c), } }; static struct mux_clk dsi0pll_pll_out_mux = { .num_parents = 4, .parents = (struct clk_src[]) { {&dsi0pll_pll_out_div1.c, 0}, {&dsi0pll_pll_out_div2.c, 1}, {&dsi0pll_pll_out_div4.c, 2}, {&dsi0pll_pll_out_div8.c, 3}, }, .ops = &mdss_pll_out_mux_ops, .c = { .parent = &dsi0pll_pll_out_div1.c, .dbg_name = "dsi0pll_pll_out_mux", .ops = &clk_ops_gen_mux, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi0pll_pll_out_mux.c), } }; static struct div_clk dsi0pll_bitclk_src = { .data = { .div = 1, Loading @@ -1194,7 +1285,7 @@ static struct div_clk dsi0pll_bitclk_src = { }, .ops = &clk_bitclk_src_ops, .c = { .parent = &dsi0pll_vco_clk.c, .parent = &dsi0pll_pll_out_mux.c, .dbg_name = "dsi0pll_bitclk_src", .ops = &clk_ops_bitclk_src_c, .flags = CLKFLAG_NO_RATE_CACHE, Loading @@ -1210,7 +1301,7 @@ static struct div_clk dsi0pll_post_vco_div1 = { }, .ops = &clk_post_vco_div_ops, .c = { .parent = &dsi0pll_vco_clk.c, .parent = &dsi0pll_pll_out_mux.c, .dbg_name = "dsi0pll_post_vco_div1", .ops = &clk_ops_post_vco_div_c, .flags = CLKFLAG_NO_RATE_CACHE, Loading @@ -1226,7 +1317,7 @@ static struct div_clk dsi0pll_post_vco_div4 = { }, .ops = &clk_post_vco_div_ops, .c = { .parent = &dsi0pll_vco_clk.c, .parent = &dsi0pll_pll_out_mux.c, .dbg_name = "dsi0pll_post_vco_div4", .ops = &clk_ops_post_vco_div_c, .flags = CLKFLAG_NO_RATE_CACHE, Loading Loading @@ -1355,6 +1446,84 @@ static struct dsi_pll_vco_clk dsi1pll_vco_clk = { }, }; static struct div_clk dsi1pll_pll_out_div1 = { .data = { .div = 1, .min_div = 1, .max_div = 1, }, .c = { .parent = &dsi1pll_vco_clk.c, .dbg_name = "dsi1pll_pll_out_div1", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi1pll_pll_out_div1.c), } }; static struct div_clk dsi1pll_pll_out_div2 = { .data = { .div = 2, .min_div = 2, .max_div = 2, }, .c = { .parent = &dsi1pll_vco_clk.c, .dbg_name = "dsi1pll_pll_out_div2", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi1pll_pll_out_div2.c), } }; static struct div_clk dsi1pll_pll_out_div4 = { .data = { .div = 4, .min_div = 4, .max_div = 4, }, .c = { .parent = &dsi1pll_vco_clk.c, .dbg_name = "dsi1pll_pll_out_div4", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi1pll_pll_out_div4.c), } }; static struct div_clk dsi1pll_pll_out_div8 = { .data = { .div = 8, .min_div = 8, .max_div = 8, }, .c = { .parent = &dsi1pll_vco_clk.c, .dbg_name = "dsi1pll_pll_out_div8", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi1pll_pll_out_div8.c), } }; static struct mux_clk dsi1pll_pll_out_mux = { .num_parents = 4, .parents = (struct clk_src[]) { {&dsi1pll_pll_out_div1.c, 0}, {&dsi1pll_pll_out_div2.c, 1}, {&dsi1pll_pll_out_div4.c, 2}, {&dsi1pll_pll_out_div8.c, 3}, }, .ops = &mdss_pll_out_mux_ops, .c = { .parent = &dsi1pll_pll_out_div1.c, .dbg_name = "dsi1pll_pll_out_mux", .ops = &clk_ops_gen_mux, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi1pll_pll_out_mux.c), } }; static struct div_clk dsi1pll_bitclk_src = { .data = { .div = 1, Loading @@ -1363,7 +1532,7 @@ static struct div_clk dsi1pll_bitclk_src = { }, .ops = &clk_bitclk_src_ops, .c = { .parent = &dsi1pll_vco_clk.c, .parent = &dsi1pll_pll_out_mux.c, .dbg_name = "dsi1pll_bitclk_src", .ops = &clk_ops_bitclk_src_c, .flags = CLKFLAG_NO_RATE_CACHE, Loading @@ -1379,7 +1548,7 @@ static struct div_clk dsi1pll_post_vco_div1 = { }, .ops = &clk_post_vco_div_ops, .c = { .parent = &dsi1pll_vco_clk.c, .parent = &dsi1pll_pll_out_mux.c, .dbg_name = "dsi1pll_post_vco_div1", .ops = &clk_ops_post_vco_div_c, .flags = CLKFLAG_NO_RATE_CACHE, Loading @@ -1395,7 +1564,7 @@ static struct div_clk dsi1pll_post_vco_div4 = { }, .ops = &clk_post_vco_div_ops, .c = { .parent = &dsi1pll_vco_clk.c, .parent = &dsi1pll_pll_out_mux.c, .dbg_name = "dsi1pll_post_vco_div4", .ops = &clk_ops_post_vco_div_c, .flags = CLKFLAG_NO_RATE_CACHE, Loading Loading @@ -1523,6 +1692,11 @@ static struct clk_lookup mdss_dsi_pll0cc_8998[] = { CLK_LIST(dsi0pll_post_vco_div1), CLK_LIST(dsi0pll_post_vco_div4), CLK_LIST(dsi0pll_bitclk_src), CLK_LIST(dsi0pll_pll_out_mux), CLK_LIST(dsi0pll_pll_out_div8), CLK_LIST(dsi0pll_pll_out_div4), CLK_LIST(dsi0pll_pll_out_div2), CLK_LIST(dsi0pll_pll_out_div1), CLK_LIST(dsi0pll_vco_clk), }; static struct clk_lookup mdss_dsi_pll1cc_8998[] = { Loading @@ -1536,6 +1710,11 @@ static struct clk_lookup mdss_dsi_pll1cc_8998[] = { CLK_LIST(dsi1pll_post_vco_div1), CLK_LIST(dsi1pll_post_vco_div4), CLK_LIST(dsi1pll_bitclk_src), CLK_LIST(dsi1pll_pll_out_mux), CLK_LIST(dsi1pll_pll_out_div8), CLK_LIST(dsi1pll_pll_out_div4), CLK_LIST(dsi1pll_pll_out_div2), CLK_LIST(dsi1pll_pll_out_div1), CLK_LIST(dsi1pll_vco_clk), }; Loading Loading @@ -1596,6 +1775,11 @@ int dsi_pll_clock_register_8998(struct platform_device *pdev, dsi0pll_post_vco_div1.priv = pll_res; dsi0pll_post_vco_div4.priv = pll_res; dsi0pll_bitclk_src.priv = pll_res; dsi0pll_pll_out_div1.priv = pll_res; dsi0pll_pll_out_div2.priv = pll_res; dsi0pll_pll_out_div4.priv = pll_res; dsi0pll_pll_out_div8.priv = pll_res; dsi0pll_pll_out_mux.priv = pll_res; dsi0pll_vco_clk.priv = pll_res; rc = of_msm_clock_register(pdev->dev.of_node, Loading @@ -1612,6 +1796,11 @@ int dsi_pll_clock_register_8998(struct platform_device *pdev, dsi1pll_post_vco_div1.priv = pll_res; dsi1pll_post_vco_div4.priv = pll_res; dsi1pll_bitclk_src.priv = pll_res; dsi1pll_pll_out_div1.priv = pll_res; dsi1pll_pll_out_div2.priv = pll_res; dsi1pll_pll_out_div4.priv = pll_res; dsi1pll_pll_out_div8.priv = pll_res; dsi1pll_pll_out_mux.priv = pll_res; dsi1pll_vco_clk.priv = pll_res; rc = of_msm_clock_register(pdev->dev.of_node, Loading include/dt-bindings/clock/msm-clocks-8998.h +10 −0 Original line number Diff line number Diff line Loading @@ -443,6 +443,11 @@ #define clk_dsi0pll_pclk_src 0x5efd85d4 #define clk_dsi0pll_pclk_src_mux 0x84b14663 #define clk_dsi0pll_post_bit_div 0xf46dcf27 #define clk_dsi0pll_pll_out_div1 0xeda5b7fe #define clk_dsi0pll_pll_out_div2 0x97fa476d #define clk_dsi0pll_pll_out_div4 0x90a98ce0 #define clk_dsi0pll_pll_out_div8 0x9d9d85cf #define clk_dsi0pll_pll_out_mux 0x179c27ca #define clk_dsi0pll_post_vco_mux 0xfaf9bd1f #define clk_dsi0pll_post_vco_div1 0xabb50b2a #define clk_dsi0pll_post_vco_div4 0xbe51c091 Loading @@ -455,6 +460,11 @@ #define clk_dsi1pll_pclk_src 0xeddcd80e #define clk_dsi1pll_pclk_src_mux 0x3651feb3 #define clk_dsi1pll_post_bit_div 0x712f0260 #define clk_dsi1pll_pll_out_div8 0x87628ddb #define clk_dsi1pll_pll_out_div4 0x0d9a384b #define clk_dsi1pll_pll_out_div2 0x0c9b5748 #define clk_dsi1pll_pll_out_div1 0x3193164e #define clk_dsi1pll_pll_out_mux 0x171bf8fd #define clk_dsi1pll_post_vco_mux 0xc6a90d20 #define clk_dsi1pll_post_vco_div1 0x6f47ca7d #define clk_dsi1pll_post_vco_div4 0x90628974 Loading Loading
drivers/clk/msm/clock-local2.c +2 −2 Original line number Diff line number Diff line Loading @@ -1517,8 +1517,8 @@ static int set_rate_pixel(struct clk *clk, unsigned long rate) { struct rcg_clk *rcg = to_rcg_clk(clk); struct clk_freq_tbl *pixel_freq = rcg->current_freq; int frac_num[] = {3, 2, 4, 1}; int frac_den[] = {8, 9, 9, 1}; int frac_num[] = {1, 2, 4, 3, 2}; int frac_den[] = {1, 3, 9, 8, 9}; int delta = 100000; int i, rc; Loading
drivers/clk/msm/mdss/mdss-dsi-pll-8998.c +294 −105 Original line number Diff line number Diff line Loading @@ -152,8 +152,6 @@ struct dsi_pll_regs { struct dsi_pll_config { u32 ref_freq; bool div_override; u32 output_div; bool ignore_frac; bool disable_prescaler; bool enable_ssc; Loading Loading @@ -212,7 +210,6 @@ static void dsi_pll_setup_config(struct dsi_pll_8998 *pll, struct dsi_pll_config *config = &pll->pll_configuration; config->ref_freq = 19200000; config->output_div = 1; config->dec_bits = 8; config->frac_bits = 18; config->lock_timer = 64; Loading @@ -222,7 +219,6 @@ static void dsi_pll_setup_config(struct dsi_pll_8998 *pll, config->thresh_cycles = 32; config->refclk_cycles = 256; config->div_override = false; config->ignore_frac = false; config->disable_prescaler = false; config->enable_ssc = rsc->ssc_en; Loading @@ -243,54 +239,14 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_8998 *pll, { struct dsi_pll_config *config = &pll->pll_configuration; struct dsi_pll_regs *regs = &pll->reg_setup; u64 target_freq; u64 fref = rsc->vco_ref_clk_rate; u32 computed_output_div, div_log = 0; u64 pll_freq; u64 divider; u64 dec, dec_multiple; u32 frac; u64 multiplier; u32 i; target_freq = rsc->vco_current_rate; pr_debug("target_freq = %llu\n", target_freq); if (config->div_override) { computed_output_div = config->output_div; /* * Computed_output_div = 2 ^ div_log * To get div_log from output div just get the index of the * 1 bit in the value. * div_log ranges from 0-3. so check the 4 lsbs */ for (i = 0; i < 4; i++) { if (computed_output_div & (1 << i)) { div_log = i; break; } } } else { if (target_freq < MHZ_250) { computed_output_div = 8; div_log = 3; } else if (target_freq < MHZ_500) { computed_output_div = 4; div_log = 2; } else if (target_freq < MHZ_1000) { computed_output_div = 2; div_log = 1; } else { computed_output_div = 1; div_log = 0; } } pr_debug("computed_output_div = %d\n", computed_output_div); pll_freq = target_freq * computed_output_div; pll_freq = rsc->vco_current_rate; if (config->disable_prescaler) divider = fref; Loading @@ -315,7 +271,6 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_8998 *pll, else regs->pll_clock_inverters = 0; regs->pll_outdiv_rate = div_log; regs->pll_lockdet_rate = config->lock_timer; regs->decimal_div_start = dec; regs->frac_div_start_low = (frac & 0xff); Loading Loading @@ -478,7 +433,6 @@ static void dsi_pll_commit(struct dsi_pll_8998 *pll, MDSS_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_HIGH_1, reg->frac_div_start_high); MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCKDET_RATE_1, 0x40); MDSS_PLL_REG_W(pll_base, PLL_PLL_OUTDIV_RATE, reg->pll_outdiv_rate); MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_DELAY, 0x06); MDSS_PLL_REG_W(pll_base, PLL_CMODE, 0x10); MDSS_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS, reg->pll_clock_inverters); Loading Loading @@ -597,11 +551,23 @@ static int dsi_pll_enable(struct dsi_pll_vco_clk *vco) { int rc; struct mdss_pll_resources *rsc = vco->priv; struct dsi_pll_8998 *pll = rsc->priv; struct dsi_pll_regs *regs = &pll->reg_setup; dsi_pll_enable_pll_bias(rsc); if (rsc->slave) dsi_pll_enable_pll_bias(rsc->slave); /* * The PLL out dividers are fixed divider clocks and hence the * set_div is not called during set_rate cycle of the tree. * The outdiv rate is therefore set in the pll out mux's set_sel * callback. But that will be called only after vco's set rate. * Hence PLL out div value is set here before locking the PLL. */ MDSS_PLL_REG_W(rsc->pll_base, PLL_PLL_OUTDIV_RATE, regs->pll_outdiv_rate); /* Start PLL */ MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_PLL_CNTRL, 0x01); Loading Loading @@ -728,7 +694,9 @@ static int vco_8998_prepare(struct clk *c) static unsigned long dsi_pll_get_vco_rate(struct clk *c) { struct dsi_pll_vco_clk *vco = to_vco_clk(c); struct mdss_pll_resources *pll = vco->priv; struct mdss_pll_resources *rsc = vco->priv; struct dsi_pll_8998 *pll = rsc->priv; struct dsi_pll_regs *regs = &pll->reg_setup; int rc; u64 ref_clk = vco->ref_clk_rate; u64 vco_rate; Loading @@ -738,27 +706,30 @@ static unsigned long dsi_pll_get_vco_rate(struct clk *c) u32 outdiv; u64 pll_freq, tmp64; rc = mdss_pll_resource_enable(pll, true); rc = mdss_pll_resource_enable(rsc, true); if (rc) { pr_err("failed to enable pll(%d) resource, rc=%d\n", pll->index, rc); rsc->index, rc); return 0; } dec = MDSS_PLL_REG_R(pll->pll_base, PLL_DECIMAL_DIV_START_1); dec = MDSS_PLL_REG_R(rsc->pll_base, PLL_DECIMAL_DIV_START_1); dec &= 0xFF; frac = MDSS_PLL_REG_R(pll->pll_base, PLL_FRAC_DIV_START_LOW_1); frac |= ((MDSS_PLL_REG_R(pll->pll_base, PLL_FRAC_DIV_START_MID_1) & frac = MDSS_PLL_REG_R(rsc->pll_base, PLL_FRAC_DIV_START_LOW_1); frac |= ((MDSS_PLL_REG_R(rsc->pll_base, PLL_FRAC_DIV_START_MID_1) & 0xFF) << 8); frac |= ((MDSS_PLL_REG_R(pll->pll_base, PLL_FRAC_DIV_START_HIGH_1) & frac |= ((MDSS_PLL_REG_R(rsc->pll_base, PLL_FRAC_DIV_START_HIGH_1) & 0x3) << 16); /* OUTDIV_1:0 field is (log(outdiv, 2)) */ outdiv = MDSS_PLL_REG_R(pll->pll_base, PLL_PLL_OUTDIV_RATE); outdiv = MDSS_PLL_REG_R(rsc->pll_base, PLL_PLL_OUTDIV_RATE); outdiv &= 0x3; regs->pll_outdiv_rate = outdiv; outdiv = 1 << outdiv; /* Loading @@ -776,7 +747,7 @@ static unsigned long dsi_pll_get_vco_rate(struct clk *c) pr_debug("dec=0x%x, frac=0x%x, outdiv=%d, vco=%llu\n", dec, frac, outdiv, vco_rate); (void)mdss_pll_resource_enable(pll, false); (void)mdss_pll_resource_enable(rsc, false); return (unsigned long)vco_rate; } Loading Loading @@ -930,6 +901,26 @@ static int bit_clk_set_div(struct div_clk *clk, int div) return rc; } static int dsi_pll_out_set_mux_sel(struct mux_clk *clk, int sel) { struct mdss_pll_resources *rsc = clk->priv; struct dsi_pll_8998 *pll = rsc->priv; struct dsi_pll_regs *regs = &pll->reg_setup; regs->pll_outdiv_rate = sel; return 0; } static int dsi_pll_out_get_mux_sel(struct mux_clk *clk) { struct mdss_pll_resources *rsc = clk->priv; struct dsi_pll_8998 *pll = rsc->priv; struct dsi_pll_regs *regs = &pll->reg_setup; return regs->pll_outdiv_rate; } static int post_vco_clk_get_div(struct div_clk *clk) { int rc; Loading Loading @@ -1125,43 +1116,66 @@ static struct clk_mux_ops mdss_mux_ops = { .get_mux_sel = mdss_get_mux_sel, }; static struct clk_mux_ops mdss_pll_out_mux_ops = { .set_mux_sel = dsi_pll_out_set_mux_sel, .get_mux_sel = dsi_pll_out_get_mux_sel, }; /* * Clock tree for generating DSI byte and pixel clocks. * * * +---------------+ * | vco_clk | * | | * +-------+-------+ * | * +----------------------+------------------+ * | * +-------+--------+------------------+-----------------+ * | | | | * +------v-------+ +------v-------+ +-------v------+ +------v-------+ * | pll_out_div1 | | pll_out_div2 | | pll_out_div4 | | pll_out_div8 | * | DIV(1) | | DIV(2) | | DIV(4) | | DIV(8) | * +------+-------+ +------+-------+ +-------+------+ +------+-------+ * | | | | * +------------+ | +--------------+ | * | | | +---------------------------+ * | | | | * +--v---v---v----v--+ * \ pll_out_mux / * \ / * +------+-----+ * | * +---------------+-----------------+ * | | | * +-------v-------+ +-------v-------+ +-------v-------+ * +------v-----+ +-------v-------+ +-------v-------+ * | bitclk_src | | post_vco_div1 | | post_vco_div4 | * | DIV(1..15) | +-------+-------+ +-------+-------+ * +-------+-------+ | | * | +------------+ | * +--------------------+ | | * Shadow Path | | | | * + +-------v-------+ +------v------+ +---v-----v------+ * | DIV(1..15) | + DIV(1) | | DIV(4) | * +------+-----+ +-------+-------+ +-------+-------+ * | | | * Shadow | | +---------------------+ * Path | +-----------------------------+ | * + | | | * | +---------------------------------+ | | * | | | | | * | +------v------=+ +------v-------+ +-v---------v----+ * | | byteclk_src | | post_bit_div | \ post_vco_mux / * | | DIV(8) | | DIV(1,2) | \ / * | +-------+-------+ +------+------+ +---+------+ * | +------+-------+ +------+-------+ +---+------+ * | | | | * | | | +----------+ * | | | | * | | +------+ +----+ * | +--------+ | | * | | +----v-----v------+ * +-v---------v----+ \ pclk_src_mux / * +-v--------v---------+ \ pclk_src_mux / * \ byteclk_mux / \ / * \ / +-----+-----+ * +----+-----+ | Shadow Path * | | + * v +-----v------+ | * +------+-------+ | Shadow * | | Path * v +-----v------+ + * dsi_byte_clk | pclk_src | | * | DIV(1..15) | | * +-----+------+ | * | | * | | * +--------+ | * +------+ | * | | * +---v----v----+ * \ pclk_mux / Loading @@ -1186,6 +1200,83 @@ static struct dsi_pll_vco_clk dsi0pll_vco_clk = { }, }; static struct div_clk dsi0pll_pll_out_div1 = { .data = { .div = 1, .min_div = 1, .max_div = 1, }, .c = { .parent = &dsi0pll_vco_clk.c, .dbg_name = "dsi0pll_pll_out_div1", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi0pll_pll_out_div1.c), } }; static struct div_clk dsi0pll_pll_out_div2 = { .data = { .div = 2, .min_div = 2, .max_div = 2, }, .c = { .parent = &dsi0pll_vco_clk.c, .dbg_name = "dsi0pll_pll_out_div2", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi0pll_pll_out_div2.c), } }; static struct div_clk dsi0pll_pll_out_div4 = { .data = { .div = 4, .min_div = 4, .max_div = 4, }, .c = { .parent = &dsi0pll_vco_clk.c, .dbg_name = "dsi0pll_pll_out_div4", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi0pll_pll_out_div4.c), } }; static struct div_clk dsi0pll_pll_out_div8 = { .data = { .div = 8, .min_div = 8, .max_div = 8, }, .c = { .parent = &dsi0pll_vco_clk.c, .dbg_name = "dsi0pll_pll_out_div8", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi0pll_pll_out_div8.c), } }; static struct mux_clk dsi0pll_pll_out_mux = { .num_parents = 4, .parents = (struct clk_src[]) { {&dsi0pll_pll_out_div1.c, 0}, {&dsi0pll_pll_out_div2.c, 1}, {&dsi0pll_pll_out_div4.c, 2}, {&dsi0pll_pll_out_div8.c, 3}, }, .ops = &mdss_pll_out_mux_ops, .c = { .parent = &dsi0pll_pll_out_div1.c, .dbg_name = "dsi0pll_pll_out_mux", .ops = &clk_ops_gen_mux, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi0pll_pll_out_mux.c), } }; static struct div_clk dsi0pll_bitclk_src = { .data = { .div = 1, Loading @@ -1194,7 +1285,7 @@ static struct div_clk dsi0pll_bitclk_src = { }, .ops = &clk_bitclk_src_ops, .c = { .parent = &dsi0pll_vco_clk.c, .parent = &dsi0pll_pll_out_mux.c, .dbg_name = "dsi0pll_bitclk_src", .ops = &clk_ops_bitclk_src_c, .flags = CLKFLAG_NO_RATE_CACHE, Loading @@ -1210,7 +1301,7 @@ static struct div_clk dsi0pll_post_vco_div1 = { }, .ops = &clk_post_vco_div_ops, .c = { .parent = &dsi0pll_vco_clk.c, .parent = &dsi0pll_pll_out_mux.c, .dbg_name = "dsi0pll_post_vco_div1", .ops = &clk_ops_post_vco_div_c, .flags = CLKFLAG_NO_RATE_CACHE, Loading @@ -1226,7 +1317,7 @@ static struct div_clk dsi0pll_post_vco_div4 = { }, .ops = &clk_post_vco_div_ops, .c = { .parent = &dsi0pll_vco_clk.c, .parent = &dsi0pll_pll_out_mux.c, .dbg_name = "dsi0pll_post_vco_div4", .ops = &clk_ops_post_vco_div_c, .flags = CLKFLAG_NO_RATE_CACHE, Loading Loading @@ -1355,6 +1446,84 @@ static struct dsi_pll_vco_clk dsi1pll_vco_clk = { }, }; static struct div_clk dsi1pll_pll_out_div1 = { .data = { .div = 1, .min_div = 1, .max_div = 1, }, .c = { .parent = &dsi1pll_vco_clk.c, .dbg_name = "dsi1pll_pll_out_div1", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi1pll_pll_out_div1.c), } }; static struct div_clk dsi1pll_pll_out_div2 = { .data = { .div = 2, .min_div = 2, .max_div = 2, }, .c = { .parent = &dsi1pll_vco_clk.c, .dbg_name = "dsi1pll_pll_out_div2", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi1pll_pll_out_div2.c), } }; static struct div_clk dsi1pll_pll_out_div4 = { .data = { .div = 4, .min_div = 4, .max_div = 4, }, .c = { .parent = &dsi1pll_vco_clk.c, .dbg_name = "dsi1pll_pll_out_div4", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi1pll_pll_out_div4.c), } }; static struct div_clk dsi1pll_pll_out_div8 = { .data = { .div = 8, .min_div = 8, .max_div = 8, }, .c = { .parent = &dsi1pll_vco_clk.c, .dbg_name = "dsi1pll_pll_out_div8", .ops = &clk_ops_div, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi1pll_pll_out_div8.c), } }; static struct mux_clk dsi1pll_pll_out_mux = { .num_parents = 4, .parents = (struct clk_src[]) { {&dsi1pll_pll_out_div1.c, 0}, {&dsi1pll_pll_out_div2.c, 1}, {&dsi1pll_pll_out_div4.c, 2}, {&dsi1pll_pll_out_div8.c, 3}, }, .ops = &mdss_pll_out_mux_ops, .c = { .parent = &dsi1pll_pll_out_div1.c, .dbg_name = "dsi1pll_pll_out_mux", .ops = &clk_ops_gen_mux, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi1pll_pll_out_mux.c), } }; static struct div_clk dsi1pll_bitclk_src = { .data = { .div = 1, Loading @@ -1363,7 +1532,7 @@ static struct div_clk dsi1pll_bitclk_src = { }, .ops = &clk_bitclk_src_ops, .c = { .parent = &dsi1pll_vco_clk.c, .parent = &dsi1pll_pll_out_mux.c, .dbg_name = "dsi1pll_bitclk_src", .ops = &clk_ops_bitclk_src_c, .flags = CLKFLAG_NO_RATE_CACHE, Loading @@ -1379,7 +1548,7 @@ static struct div_clk dsi1pll_post_vco_div1 = { }, .ops = &clk_post_vco_div_ops, .c = { .parent = &dsi1pll_vco_clk.c, .parent = &dsi1pll_pll_out_mux.c, .dbg_name = "dsi1pll_post_vco_div1", .ops = &clk_ops_post_vco_div_c, .flags = CLKFLAG_NO_RATE_CACHE, Loading @@ -1395,7 +1564,7 @@ static struct div_clk dsi1pll_post_vco_div4 = { }, .ops = &clk_post_vco_div_ops, .c = { .parent = &dsi1pll_vco_clk.c, .parent = &dsi1pll_pll_out_mux.c, .dbg_name = "dsi1pll_post_vco_div4", .ops = &clk_ops_post_vco_div_c, .flags = CLKFLAG_NO_RATE_CACHE, Loading Loading @@ -1523,6 +1692,11 @@ static struct clk_lookup mdss_dsi_pll0cc_8998[] = { CLK_LIST(dsi0pll_post_vco_div1), CLK_LIST(dsi0pll_post_vco_div4), CLK_LIST(dsi0pll_bitclk_src), CLK_LIST(dsi0pll_pll_out_mux), CLK_LIST(dsi0pll_pll_out_div8), CLK_LIST(dsi0pll_pll_out_div4), CLK_LIST(dsi0pll_pll_out_div2), CLK_LIST(dsi0pll_pll_out_div1), CLK_LIST(dsi0pll_vco_clk), }; static struct clk_lookup mdss_dsi_pll1cc_8998[] = { Loading @@ -1536,6 +1710,11 @@ static struct clk_lookup mdss_dsi_pll1cc_8998[] = { CLK_LIST(dsi1pll_post_vco_div1), CLK_LIST(dsi1pll_post_vco_div4), CLK_LIST(dsi1pll_bitclk_src), CLK_LIST(dsi1pll_pll_out_mux), CLK_LIST(dsi1pll_pll_out_div8), CLK_LIST(dsi1pll_pll_out_div4), CLK_LIST(dsi1pll_pll_out_div2), CLK_LIST(dsi1pll_pll_out_div1), CLK_LIST(dsi1pll_vco_clk), }; Loading Loading @@ -1596,6 +1775,11 @@ int dsi_pll_clock_register_8998(struct platform_device *pdev, dsi0pll_post_vco_div1.priv = pll_res; dsi0pll_post_vco_div4.priv = pll_res; dsi0pll_bitclk_src.priv = pll_res; dsi0pll_pll_out_div1.priv = pll_res; dsi0pll_pll_out_div2.priv = pll_res; dsi0pll_pll_out_div4.priv = pll_res; dsi0pll_pll_out_div8.priv = pll_res; dsi0pll_pll_out_mux.priv = pll_res; dsi0pll_vco_clk.priv = pll_res; rc = of_msm_clock_register(pdev->dev.of_node, Loading @@ -1612,6 +1796,11 @@ int dsi_pll_clock_register_8998(struct platform_device *pdev, dsi1pll_post_vco_div1.priv = pll_res; dsi1pll_post_vco_div4.priv = pll_res; dsi1pll_bitclk_src.priv = pll_res; dsi1pll_pll_out_div1.priv = pll_res; dsi1pll_pll_out_div2.priv = pll_res; dsi1pll_pll_out_div4.priv = pll_res; dsi1pll_pll_out_div8.priv = pll_res; dsi1pll_pll_out_mux.priv = pll_res; dsi1pll_vco_clk.priv = pll_res; rc = of_msm_clock_register(pdev->dev.of_node, Loading
include/dt-bindings/clock/msm-clocks-8998.h +10 −0 Original line number Diff line number Diff line Loading @@ -443,6 +443,11 @@ #define clk_dsi0pll_pclk_src 0x5efd85d4 #define clk_dsi0pll_pclk_src_mux 0x84b14663 #define clk_dsi0pll_post_bit_div 0xf46dcf27 #define clk_dsi0pll_pll_out_div1 0xeda5b7fe #define clk_dsi0pll_pll_out_div2 0x97fa476d #define clk_dsi0pll_pll_out_div4 0x90a98ce0 #define clk_dsi0pll_pll_out_div8 0x9d9d85cf #define clk_dsi0pll_pll_out_mux 0x179c27ca #define clk_dsi0pll_post_vco_mux 0xfaf9bd1f #define clk_dsi0pll_post_vco_div1 0xabb50b2a #define clk_dsi0pll_post_vco_div4 0xbe51c091 Loading @@ -455,6 +460,11 @@ #define clk_dsi1pll_pclk_src 0xeddcd80e #define clk_dsi1pll_pclk_src_mux 0x3651feb3 #define clk_dsi1pll_post_bit_div 0x712f0260 #define clk_dsi1pll_pll_out_div8 0x87628ddb #define clk_dsi1pll_pll_out_div4 0x0d9a384b #define clk_dsi1pll_pll_out_div2 0x0c9b5748 #define clk_dsi1pll_pll_out_div1 0x3193164e #define clk_dsi1pll_pll_out_mux 0x171bf8fd #define clk_dsi1pll_post_vco_mux 0xc6a90d20 #define clk_dsi1pll_post_vco_div1 0x6f47ca7d #define clk_dsi1pll_post_vco_div4 0x90628974 Loading