Loading arch/arm64/boot/dts/qcom/sdm439.dtsi +8 −8 Original line number Diff line number Diff line Loading @@ -341,10 +341,10 @@ reg = <0x001a94400 0x400>, <0x0184d074 0x8>; reg-names = "pll_base", "gdsc_base"; /delete-property/ qcom,dsi-pll-ssc-en; /delete-property/ qcom,dsi-pll-ssc-mode; /delete-property/ qcom,ssc-frequency-hz; /delete-property/ qcom,ssc-ppm; qcom,dsi-pll-ssc-en; qcom,dsi-pll-ssc-mode = "down-spread"; qcom,ssc-frequency-hz = <31500>; qcom,ssc-ppm = <5000>; }; &mdss_dsi1_pll { Loading @@ -352,10 +352,10 @@ reg = <0x001a96400 0x400>, <0x0184d074 0x8>; reg-names = "pll_base", "gdsc_base"; /delete-property/ qcom,dsi-pll-ssc-en; /delete-property/ qcom,dsi-pll-ssc-mode; /delete-property/ qcom,ssc-frequency-hz; /delete-property/ qcom,ssc-ppm; qcom,dsi-pll-ssc-en; qcom,dsi-pll-ssc-mode = "down-spread"; qcom,ssc-frequency-hz = <31500>; qcom,ssc-ppm = <5000>; }; &mdss_dsi { Loading drivers/clk/msm/mdss/mdss-dsi-pll-12nm-util.c +168 −15 Original line number Diff line number Diff line Loading @@ -165,7 +165,8 @@ int get_gp_mux_sel(struct mux_clk *clk) return sel; } static bool pll_is_pll_locked_12nm(struct mdss_pll_resources *pll) static bool pll_is_pll_locked_12nm(struct mdss_pll_resources *pll, bool is_handoff) { u32 status; bool pll_locked; Loading @@ -177,6 +178,7 @@ static bool pll_is_pll_locked_12nm(struct mdss_pll_resources *pll) ((status & BIT(1)) > 0), DSI_PLL_POLL_MAX_READS, DSI_PLL_POLL_TIMEOUT_US)) { if (!is_handoff) pr_err("DSI PLL ndx=%d status=%x failed to Lock\n", pll->index, status); pll_locked = false; Loading Loading @@ -213,7 +215,7 @@ int dsi_pll_enable_seq_12nm(struct mdss_pll_resources *pll) wmb(); /* make sure register committed before enabling branch clocks */ udelay(50); /* h/w recommended delay */ if (!pll_is_pll_locked_12nm(pll)) { if (!pll_is_pll_locked_12nm(pll, false)) { pr_err("DSI PLL ndx=%d lock failed!\n", pll->index); rc = -EINVAL; Loading Loading @@ -261,7 +263,7 @@ static int dsi_pll_relock(struct mdss_pll_resources *pll) MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_POWERUP_CTRL, data); ndelay(500); /* h/w recommended delay */ if (!pll_is_pll_locked_12nm(pll)) { if (!pll_is_pll_locked_12nm(pll, false)) { pr_err("DSI PLL ndx=%d lock failed!\n", pll->index); rc = -EINVAL; Loading Loading @@ -556,6 +558,142 @@ static void mdss_dsi_pll_12nm_calc_reg(struct mdss_pll_resources *pll, param->gmp_cntrl = 0x1; } static u32 __mdss_dsi_get_multi_intX100(u64 vco_rate, u32 *rem) { u32 reminder = 0; u64 temp = 0; const u32 ref_clk_rate = 19200000, quarterX100 = 25; temp = div_u64_rem(vco_rate, ref_clk_rate, &reminder); temp *= 100; /* * Multiplication integer needs to be floored in steps of 0.25 * Hence multi_intX100 needs to be rounded off in steps of 25 */ if (reminder < (ref_clk_rate / 4)) { *rem = reminder; return temp; } else if ((reminder >= (ref_clk_rate / 4)) && reminder < (ref_clk_rate / 2)) { *rem = (reminder - (ref_clk_rate / 4)); return (temp + quarterX100); } else if ((reminder >= (ref_clk_rate / 2)) && (reminder < ((3 * ref_clk_rate) / 4))) { *rem = (reminder - (ref_clk_rate / 2)); return (temp + (quarterX100 * 2)); } *rem = (reminder - ((3 * ref_clk_rate) / 4)); return (temp + (quarterX100 * 3)); } static u32 __calc_gcd(u32 num1, u32 num2) { if (num2 != 0) return __calc_gcd(num2, (num1 % num2)); else return num1; } static void mdss_dsi_pll_12nm_calc_ssc(struct mdss_pll_resources *pll, struct dsi_pll_db *pdb) { struct dsi_pll_param *param = &pdb->param; u64 multi_intX100 = 0, temp = 0; u32 temp_rem1 = 0, temp_rem2 = 0; const u64 power_2_17 = 131072, power_2_10 = 1024; const u32 ref_clk_rate = 19200000; multi_intX100 = __mdss_dsi_get_multi_intX100(pll->vco_current_rate, &temp_rem1); /* Calculation for mpll_ssc_peak_i */ temp = (multi_intX100 * pll->ssc_ppm * power_2_17); temp = div_u64(temp, 100); /* 100 div for multi_intX100 */ param->mpll_ssc_peak_i = (u32) div_u64(temp, 1000000); /*10^6 for SSC PPM */ /* Calculation for mpll_stepsize_i */ param->mpll_stepsize_i = (u32) div_u64((param->mpll_ssc_peak_i * pll->ssc_freq * power_2_10), ref_clk_rate); /* Calculation for mpll_mint_i */ param->mpll_mint_i = (u32) (div_u64((multi_intX100 * 4), 100) - 32); /* Calculation for mpll_frac_den */ param->mpll_frac_den = (u32) div_u64(ref_clk_rate, __calc_gcd((u32)pll->vco_current_rate, ref_clk_rate)); /* Calculation for mpll_frac_quot_i */ temp = (temp_rem1 * power_2_17); param->mpll_frac_quot_i = (u32) div_u64_rem(temp, ref_clk_rate, &temp_rem2); /* Calculation for mpll_frac_rem */ param->mpll_frac_rem = (u32) div_u64(((u64)temp_rem2 * param->mpll_frac_den), ref_clk_rate); pr_debug("mpll_ssc_peak_i=%d mpll_stepsize_i=%d mpll_mint_i=%d\n", param->mpll_ssc_peak_i, param->mpll_stepsize_i, param->mpll_mint_i); pr_debug("mpll_frac_den=%d mpll_frac_quot_i=%d mpll_frac_rem=%d", param->mpll_frac_den, param->mpll_frac_quot_i, param->mpll_frac_rem); } static void pll_db_commit_12nm_ssc(struct mdss_pll_resources *pll, struct dsi_pll_db *pdb) { void __iomem *pll_base = pll->pll_base; struct dsi_pll_param *param = &pdb->param; char data = 0; MDSS_PLL_REG_W(pll_base, DSIPHY_SSC0, 0x27); data = (param->mpll_mint_i & 0xff); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC7, data); data = ((param->mpll_mint_i & 0xff00) >> 8); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC8, data); data = (param->mpll_ssc_peak_i & 0xff); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC1, data); data = ((param->mpll_ssc_peak_i & 0xff00) >> 8); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC2, data); data = ((param->mpll_ssc_peak_i & 0xf0000) >> 16); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC3, data); data = (param->mpll_stepsize_i & 0xff); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC4, data); data = ((param->mpll_stepsize_i & 0xff00) >> 8); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC5, data); data = ((param->mpll_stepsize_i & 0x1f0000) >> 16); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC6, data); data = (param->mpll_frac_quot_i & 0xff); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC10, data); data = ((param->mpll_frac_quot_i & 0xff00) >> 8); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC11, data); data = (param->mpll_frac_rem & 0xff); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC12, data); data = ((param->mpll_frac_rem & 0xff00) >> 8); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC13, data); data = (param->mpll_frac_den & 0xff); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC14, data); data = ((param->mpll_frac_den & 0xff00) >> 8); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC15, data); } static void pll_db_commit_12nm(struct mdss_pll_resources *pll, struct dsi_pll_db *pdb) { Loading Loading @@ -616,6 +754,9 @@ static void pll_db_commit_12nm(struct mdss_pll_resources *pll, MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PRO_DLY_RELOCK, 0x0c); MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_LOCK_DET_MODE_SEL, 0x02); if (pll->ssc_en) pll_db_commit_12nm_ssc(pll, pdb); pr_debug("pll:%d\n", pll->index); wmb(); /* make sure register committed before preparing the clocks */ } Loading Loading @@ -710,7 +851,7 @@ enum handoff pll_vco_handoff_12nm(struct clk *c) return ret; } if (pll_is_pll_locked_12nm(pll)) { if (pll_is_pll_locked_12nm(pll, true)) { pll->handoff_resources = true; pll->pll_on = true; c->rate = pll_vco_get_rate_12nm(c); Loading Loading @@ -756,18 +897,27 @@ int pll_vco_prepare_12nm(struct clk *c) rc, pll->index); goto error; } } /* * For cases where DSI PHY is already enabled like: * 1.) LP-11 during static screen * 2.) ULPS during static screen * 3.) Boot up with cont splash enabled where PHY is programmed in LK * Execute the Re-lock sequence to enable the DSI PLL. */ data = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_SYS_CTRL); if (data & BIT(7)) { /* DSI PHY in LP-11 or ULPS */ if (data & BIT(7)) { rc = dsi_pll_relock(pll); if (rc) goto error; else goto end; } } mdss_dsi_pll_12nm_calc_reg(pll, pdb); if (pll->ssc_en) mdss_dsi_pll_12nm_calc_ssc(pll, pdb); /* commit DSI vco */ pll_db_commit_12nm(pll, pdb); Loading Loading @@ -802,6 +952,7 @@ int pll_vco_enable_12nm(struct clk *c) { struct dsi_pll_vco_clk *vco = to_vco_clk(c); struct mdss_pll_resources *pll = vco->priv; u32 data = 0; if (!pll) { pr_err("Dsi pll resources are not available\n"); Loading @@ -813,7 +964,9 @@ int pll_vco_enable_12nm(struct clk *c) return -EINVAL; } MDSS_PLL_REG_W(pll->pll_base, DSIPHY_SSC0, 0x40); data = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_SSC0); data |= BIT(6); /* enable GP_CLK_EN */ MDSS_PLL_REG_W(pll->pll_base, DSIPHY_SSC0, data); wmb(); /* make sure register committed before enabling branch clocks */ return 0; Loading drivers/clk/msm/mdss/mdss-dsi-pll-12nm.c +20 −0 Original line number Diff line number Diff line Loading @@ -636,11 +636,13 @@ static struct div_clk dsi1pll_byte_clk_src = { }; static struct clk_lookup mdss_dsi_pllcc_12nm[] = { CLK_LIST(dsi0pll_vco_clk), CLK_LIST(dsi0pll_byte_clk_src), CLK_LIST(dsi0pll_pixel_clk_src), }; static struct clk_lookup mdss_dsi_pllcc_12nm_1[] = { CLK_LIST(dsi1pll_vco_clk), CLK_LIST(dsi1pll_byte_clk_src), CLK_LIST(dsi1pll_pixel_clk_src), }; Loading @@ -650,6 +652,9 @@ int dsi_pll_clock_register_12nm(struct platform_device *pdev, { int rc = 0, ndx; struct dsi_pll_db *pdb; int const ssc_freq_min = 30000; /* min. recommended freq. value */ int const ssc_freq_max = 33000; /* max. recommended freq. value */ int const ssc_ppm_max = 5000; /* max. recommended ppm */ if (!pdev || !pdev->dev.of_node) { pr_err("Invalid input parameters\n"); Loading Loading @@ -680,6 +685,21 @@ int dsi_pll_clock_register_12nm(struct platform_device *pdev, pixel_div_clk_src_ops = clk_ops_div; pixel_div_clk_src_ops.prepare = dsi_pll_div_prepare; if (pll_res->ssc_en) { if (!pll_res->ssc_freq || (pll_res->ssc_freq < ssc_freq_min) || (pll_res->ssc_freq > ssc_freq_max)) { pll_res->ssc_freq = ssc_freq_min; pr_debug("SSC frequency out of recommended range. Set to default=%d\n", pll_res->ssc_freq); } if (!pll_res->ssc_ppm || (pll_res->ssc_ppm > ssc_ppm_max)) { pll_res->ssc_ppm = ssc_ppm_max; pr_debug("SSC PPM out of recommended range. Set to default=%d\n", pll_res->ssc_ppm); } } /* Set client data to mux, div and vco clocks. */ if (pll_res->index == DSI_PLL_1) { dsi1pll_byte_clk_src.priv = pll_res; Loading drivers/clk/msm/mdss/mdss-dsi-pll-12nm.h +24 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,22 @@ #define DSIPHY_PLL_LOOP_DIV_RATIO_1 0x2e8 #define DSIPHY_SLEWRATE_DDL_CYC_FRQ_ADJ_1 0x328 #define DSIPHY_SSC0 0x394 #define DSIPHY_SSC7 0x3b0 #define DSIPHY_SSC8 0x3b4 #define DSIPHY_SSC1 0x398 #define DSIPHY_SSC2 0x39c #define DSIPHY_SSC3 0x3a0 #define DSIPHY_SSC4 0x3a4 #define DSIPHY_SSC5 0x3a8 #define DSIPHY_SSC6 0x3ac #define DSIPHY_SSC10 0x360 #define DSIPHY_SSC11 0x364 #define DSIPHY_SSC12 0x368 #define DSIPHY_SSC13 0x36c #define DSIPHY_SSC14 0x370 #define DSIPHY_SSC15 0x374 #define DSIPHY_SSC7 0x3b0 #define DSIPHY_SSC8 0x3b4 #define DSIPHY_SSC9 0x3b8 #define DSIPHY_STAT0 0x3e0 #define DSIPHY_CTRL0 0x3e8 Loading @@ -58,6 +74,14 @@ struct dsi_pll_param { u32 post_div_mux; u32 pixel_divhf; u32 fsm_ovr_ctrl; /* ssc_params */ u32 mpll_ssc_peak_i; u32 mpll_stepsize_i; u32 mpll_mint_i; u32 mpll_frac_den; u32 mpll_frac_quot_i; u32 mpll_frac_rem; }; enum { Loading include/dt-bindings/clock/msm-clocks-8952.h +2 −0 Original line number Diff line number Diff line Loading @@ -237,8 +237,10 @@ #define clk_dsi0pll_byte_clk_src 0xbbaa30be #define clk_dsi0pll_pixel_clk_src 0x45b3260f #define clk_dsi0pll_vco_clk 0x15940d40 #define clk_dsi1pll_byte_clk_src 0x63930a8f #define clk_dsi1pll_pixel_clk_src 0x0e4c9b56 #define clk_dsi1pll_vco_clk 0x99797b50 #define clk_dsi_pll0_byte_clk_src 0x44539836 #define clk_dsi_pll0_pixel_clk_src 0x5767c287 Loading Loading
arch/arm64/boot/dts/qcom/sdm439.dtsi +8 −8 Original line number Diff line number Diff line Loading @@ -341,10 +341,10 @@ reg = <0x001a94400 0x400>, <0x0184d074 0x8>; reg-names = "pll_base", "gdsc_base"; /delete-property/ qcom,dsi-pll-ssc-en; /delete-property/ qcom,dsi-pll-ssc-mode; /delete-property/ qcom,ssc-frequency-hz; /delete-property/ qcom,ssc-ppm; qcom,dsi-pll-ssc-en; qcom,dsi-pll-ssc-mode = "down-spread"; qcom,ssc-frequency-hz = <31500>; qcom,ssc-ppm = <5000>; }; &mdss_dsi1_pll { Loading @@ -352,10 +352,10 @@ reg = <0x001a96400 0x400>, <0x0184d074 0x8>; reg-names = "pll_base", "gdsc_base"; /delete-property/ qcom,dsi-pll-ssc-en; /delete-property/ qcom,dsi-pll-ssc-mode; /delete-property/ qcom,ssc-frequency-hz; /delete-property/ qcom,ssc-ppm; qcom,dsi-pll-ssc-en; qcom,dsi-pll-ssc-mode = "down-spread"; qcom,ssc-frequency-hz = <31500>; qcom,ssc-ppm = <5000>; }; &mdss_dsi { Loading
drivers/clk/msm/mdss/mdss-dsi-pll-12nm-util.c +168 −15 Original line number Diff line number Diff line Loading @@ -165,7 +165,8 @@ int get_gp_mux_sel(struct mux_clk *clk) return sel; } static bool pll_is_pll_locked_12nm(struct mdss_pll_resources *pll) static bool pll_is_pll_locked_12nm(struct mdss_pll_resources *pll, bool is_handoff) { u32 status; bool pll_locked; Loading @@ -177,6 +178,7 @@ static bool pll_is_pll_locked_12nm(struct mdss_pll_resources *pll) ((status & BIT(1)) > 0), DSI_PLL_POLL_MAX_READS, DSI_PLL_POLL_TIMEOUT_US)) { if (!is_handoff) pr_err("DSI PLL ndx=%d status=%x failed to Lock\n", pll->index, status); pll_locked = false; Loading Loading @@ -213,7 +215,7 @@ int dsi_pll_enable_seq_12nm(struct mdss_pll_resources *pll) wmb(); /* make sure register committed before enabling branch clocks */ udelay(50); /* h/w recommended delay */ if (!pll_is_pll_locked_12nm(pll)) { if (!pll_is_pll_locked_12nm(pll, false)) { pr_err("DSI PLL ndx=%d lock failed!\n", pll->index); rc = -EINVAL; Loading Loading @@ -261,7 +263,7 @@ static int dsi_pll_relock(struct mdss_pll_resources *pll) MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_POWERUP_CTRL, data); ndelay(500); /* h/w recommended delay */ if (!pll_is_pll_locked_12nm(pll)) { if (!pll_is_pll_locked_12nm(pll, false)) { pr_err("DSI PLL ndx=%d lock failed!\n", pll->index); rc = -EINVAL; Loading Loading @@ -556,6 +558,142 @@ static void mdss_dsi_pll_12nm_calc_reg(struct mdss_pll_resources *pll, param->gmp_cntrl = 0x1; } static u32 __mdss_dsi_get_multi_intX100(u64 vco_rate, u32 *rem) { u32 reminder = 0; u64 temp = 0; const u32 ref_clk_rate = 19200000, quarterX100 = 25; temp = div_u64_rem(vco_rate, ref_clk_rate, &reminder); temp *= 100; /* * Multiplication integer needs to be floored in steps of 0.25 * Hence multi_intX100 needs to be rounded off in steps of 25 */ if (reminder < (ref_clk_rate / 4)) { *rem = reminder; return temp; } else if ((reminder >= (ref_clk_rate / 4)) && reminder < (ref_clk_rate / 2)) { *rem = (reminder - (ref_clk_rate / 4)); return (temp + quarterX100); } else if ((reminder >= (ref_clk_rate / 2)) && (reminder < ((3 * ref_clk_rate) / 4))) { *rem = (reminder - (ref_clk_rate / 2)); return (temp + (quarterX100 * 2)); } *rem = (reminder - ((3 * ref_clk_rate) / 4)); return (temp + (quarterX100 * 3)); } static u32 __calc_gcd(u32 num1, u32 num2) { if (num2 != 0) return __calc_gcd(num2, (num1 % num2)); else return num1; } static void mdss_dsi_pll_12nm_calc_ssc(struct mdss_pll_resources *pll, struct dsi_pll_db *pdb) { struct dsi_pll_param *param = &pdb->param; u64 multi_intX100 = 0, temp = 0; u32 temp_rem1 = 0, temp_rem2 = 0; const u64 power_2_17 = 131072, power_2_10 = 1024; const u32 ref_clk_rate = 19200000; multi_intX100 = __mdss_dsi_get_multi_intX100(pll->vco_current_rate, &temp_rem1); /* Calculation for mpll_ssc_peak_i */ temp = (multi_intX100 * pll->ssc_ppm * power_2_17); temp = div_u64(temp, 100); /* 100 div for multi_intX100 */ param->mpll_ssc_peak_i = (u32) div_u64(temp, 1000000); /*10^6 for SSC PPM */ /* Calculation for mpll_stepsize_i */ param->mpll_stepsize_i = (u32) div_u64((param->mpll_ssc_peak_i * pll->ssc_freq * power_2_10), ref_clk_rate); /* Calculation for mpll_mint_i */ param->mpll_mint_i = (u32) (div_u64((multi_intX100 * 4), 100) - 32); /* Calculation for mpll_frac_den */ param->mpll_frac_den = (u32) div_u64(ref_clk_rate, __calc_gcd((u32)pll->vco_current_rate, ref_clk_rate)); /* Calculation for mpll_frac_quot_i */ temp = (temp_rem1 * power_2_17); param->mpll_frac_quot_i = (u32) div_u64_rem(temp, ref_clk_rate, &temp_rem2); /* Calculation for mpll_frac_rem */ param->mpll_frac_rem = (u32) div_u64(((u64)temp_rem2 * param->mpll_frac_den), ref_clk_rate); pr_debug("mpll_ssc_peak_i=%d mpll_stepsize_i=%d mpll_mint_i=%d\n", param->mpll_ssc_peak_i, param->mpll_stepsize_i, param->mpll_mint_i); pr_debug("mpll_frac_den=%d mpll_frac_quot_i=%d mpll_frac_rem=%d", param->mpll_frac_den, param->mpll_frac_quot_i, param->mpll_frac_rem); } static void pll_db_commit_12nm_ssc(struct mdss_pll_resources *pll, struct dsi_pll_db *pdb) { void __iomem *pll_base = pll->pll_base; struct dsi_pll_param *param = &pdb->param; char data = 0; MDSS_PLL_REG_W(pll_base, DSIPHY_SSC0, 0x27); data = (param->mpll_mint_i & 0xff); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC7, data); data = ((param->mpll_mint_i & 0xff00) >> 8); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC8, data); data = (param->mpll_ssc_peak_i & 0xff); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC1, data); data = ((param->mpll_ssc_peak_i & 0xff00) >> 8); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC2, data); data = ((param->mpll_ssc_peak_i & 0xf0000) >> 16); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC3, data); data = (param->mpll_stepsize_i & 0xff); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC4, data); data = ((param->mpll_stepsize_i & 0xff00) >> 8); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC5, data); data = ((param->mpll_stepsize_i & 0x1f0000) >> 16); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC6, data); data = (param->mpll_frac_quot_i & 0xff); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC10, data); data = ((param->mpll_frac_quot_i & 0xff00) >> 8); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC11, data); data = (param->mpll_frac_rem & 0xff); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC12, data); data = ((param->mpll_frac_rem & 0xff00) >> 8); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC13, data); data = (param->mpll_frac_den & 0xff); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC14, data); data = ((param->mpll_frac_den & 0xff00) >> 8); MDSS_PLL_REG_W(pll_base, DSIPHY_SSC15, data); } static void pll_db_commit_12nm(struct mdss_pll_resources *pll, struct dsi_pll_db *pdb) { Loading Loading @@ -616,6 +754,9 @@ static void pll_db_commit_12nm(struct mdss_pll_resources *pll, MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PRO_DLY_RELOCK, 0x0c); MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_LOCK_DET_MODE_SEL, 0x02); if (pll->ssc_en) pll_db_commit_12nm_ssc(pll, pdb); pr_debug("pll:%d\n", pll->index); wmb(); /* make sure register committed before preparing the clocks */ } Loading Loading @@ -710,7 +851,7 @@ enum handoff pll_vco_handoff_12nm(struct clk *c) return ret; } if (pll_is_pll_locked_12nm(pll)) { if (pll_is_pll_locked_12nm(pll, true)) { pll->handoff_resources = true; pll->pll_on = true; c->rate = pll_vco_get_rate_12nm(c); Loading Loading @@ -756,18 +897,27 @@ int pll_vco_prepare_12nm(struct clk *c) rc, pll->index); goto error; } } /* * For cases where DSI PHY is already enabled like: * 1.) LP-11 during static screen * 2.) ULPS during static screen * 3.) Boot up with cont splash enabled where PHY is programmed in LK * Execute the Re-lock sequence to enable the DSI PLL. */ data = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_SYS_CTRL); if (data & BIT(7)) { /* DSI PHY in LP-11 or ULPS */ if (data & BIT(7)) { rc = dsi_pll_relock(pll); if (rc) goto error; else goto end; } } mdss_dsi_pll_12nm_calc_reg(pll, pdb); if (pll->ssc_en) mdss_dsi_pll_12nm_calc_ssc(pll, pdb); /* commit DSI vco */ pll_db_commit_12nm(pll, pdb); Loading Loading @@ -802,6 +952,7 @@ int pll_vco_enable_12nm(struct clk *c) { struct dsi_pll_vco_clk *vco = to_vco_clk(c); struct mdss_pll_resources *pll = vco->priv; u32 data = 0; if (!pll) { pr_err("Dsi pll resources are not available\n"); Loading @@ -813,7 +964,9 @@ int pll_vco_enable_12nm(struct clk *c) return -EINVAL; } MDSS_PLL_REG_W(pll->pll_base, DSIPHY_SSC0, 0x40); data = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_SSC0); data |= BIT(6); /* enable GP_CLK_EN */ MDSS_PLL_REG_W(pll->pll_base, DSIPHY_SSC0, data); wmb(); /* make sure register committed before enabling branch clocks */ return 0; Loading
drivers/clk/msm/mdss/mdss-dsi-pll-12nm.c +20 −0 Original line number Diff line number Diff line Loading @@ -636,11 +636,13 @@ static struct div_clk dsi1pll_byte_clk_src = { }; static struct clk_lookup mdss_dsi_pllcc_12nm[] = { CLK_LIST(dsi0pll_vco_clk), CLK_LIST(dsi0pll_byte_clk_src), CLK_LIST(dsi0pll_pixel_clk_src), }; static struct clk_lookup mdss_dsi_pllcc_12nm_1[] = { CLK_LIST(dsi1pll_vco_clk), CLK_LIST(dsi1pll_byte_clk_src), CLK_LIST(dsi1pll_pixel_clk_src), }; Loading @@ -650,6 +652,9 @@ int dsi_pll_clock_register_12nm(struct platform_device *pdev, { int rc = 0, ndx; struct dsi_pll_db *pdb; int const ssc_freq_min = 30000; /* min. recommended freq. value */ int const ssc_freq_max = 33000; /* max. recommended freq. value */ int const ssc_ppm_max = 5000; /* max. recommended ppm */ if (!pdev || !pdev->dev.of_node) { pr_err("Invalid input parameters\n"); Loading Loading @@ -680,6 +685,21 @@ int dsi_pll_clock_register_12nm(struct platform_device *pdev, pixel_div_clk_src_ops = clk_ops_div; pixel_div_clk_src_ops.prepare = dsi_pll_div_prepare; if (pll_res->ssc_en) { if (!pll_res->ssc_freq || (pll_res->ssc_freq < ssc_freq_min) || (pll_res->ssc_freq > ssc_freq_max)) { pll_res->ssc_freq = ssc_freq_min; pr_debug("SSC frequency out of recommended range. Set to default=%d\n", pll_res->ssc_freq); } if (!pll_res->ssc_ppm || (pll_res->ssc_ppm > ssc_ppm_max)) { pll_res->ssc_ppm = ssc_ppm_max; pr_debug("SSC PPM out of recommended range. Set to default=%d\n", pll_res->ssc_ppm); } } /* Set client data to mux, div and vco clocks. */ if (pll_res->index == DSI_PLL_1) { dsi1pll_byte_clk_src.priv = pll_res; Loading
drivers/clk/msm/mdss/mdss-dsi-pll-12nm.h +24 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,22 @@ #define DSIPHY_PLL_LOOP_DIV_RATIO_1 0x2e8 #define DSIPHY_SLEWRATE_DDL_CYC_FRQ_ADJ_1 0x328 #define DSIPHY_SSC0 0x394 #define DSIPHY_SSC7 0x3b0 #define DSIPHY_SSC8 0x3b4 #define DSIPHY_SSC1 0x398 #define DSIPHY_SSC2 0x39c #define DSIPHY_SSC3 0x3a0 #define DSIPHY_SSC4 0x3a4 #define DSIPHY_SSC5 0x3a8 #define DSIPHY_SSC6 0x3ac #define DSIPHY_SSC10 0x360 #define DSIPHY_SSC11 0x364 #define DSIPHY_SSC12 0x368 #define DSIPHY_SSC13 0x36c #define DSIPHY_SSC14 0x370 #define DSIPHY_SSC15 0x374 #define DSIPHY_SSC7 0x3b0 #define DSIPHY_SSC8 0x3b4 #define DSIPHY_SSC9 0x3b8 #define DSIPHY_STAT0 0x3e0 #define DSIPHY_CTRL0 0x3e8 Loading @@ -58,6 +74,14 @@ struct dsi_pll_param { u32 post_div_mux; u32 pixel_divhf; u32 fsm_ovr_ctrl; /* ssc_params */ u32 mpll_ssc_peak_i; u32 mpll_stepsize_i; u32 mpll_mint_i; u32 mpll_frac_den; u32 mpll_frac_quot_i; u32 mpll_frac_rem; }; enum { Loading
include/dt-bindings/clock/msm-clocks-8952.h +2 −0 Original line number Diff line number Diff line Loading @@ -237,8 +237,10 @@ #define clk_dsi0pll_byte_clk_src 0xbbaa30be #define clk_dsi0pll_pixel_clk_src 0x45b3260f #define clk_dsi0pll_vco_clk 0x15940d40 #define clk_dsi1pll_byte_clk_src 0x63930a8f #define clk_dsi1pll_pixel_clk_src 0x0e4c9b56 #define clk_dsi1pll_vco_clk 0x99797b50 #define clk_dsi_pll0_byte_clk_src 0x44539836 #define clk_dsi_pll0_pixel_clk_src 0x5767c287 Loading