diff mbox series

[v3,6/7] clk/qcom: add mnd_width to clk_rcg_set_rate_mnd()

Message ID 20231103-b4-qcom-clk-v3-6-8d2d460ece84@linaro.org
State Superseded
Headers show
Series arm: mach-snapdragon: Qualcomm clock driver cleanup | expand

Commit Message

Caleb Connolly Nov. 3, 2023, 3:39 p.m. UTC
This property is needed on some platforms to ensure that only the
relevant bits are set in the M/N/D registers.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
---
 drivers/clk/qcom/clock-apq8016.c |  4 ++--
 drivers/clk/qcom/clock-apq8096.c |  4 ++--
 drivers/clk/qcom/clock-qcom.c    | 11 +++++++----
 drivers/clk/qcom/clock-qcom.h    |  2 +-
 drivers/clk/qcom/clock-qcs404.c  | 18 +++++++++---------
 drivers/clk/qcom/clock-sdm845.c  |  3 +--
 6 files changed, 22 insertions(+), 20 deletions(-)

Comments

Sumit Garg Nov. 6, 2023, 7:06 a.m. UTC | #1
On Fri, 3 Nov 2023 at 21:09, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> This property is needed on some platforms to ensure that only the
> relevant bits are set in the M/N/D registers.

This commit broke qcs404 platform which is fixed by following add-on change:

diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c
index 429ff35e1d..f5b3528039 100644
--- a/drivers/clk/qcom/clock-qcs404.c
+++ b/drivers/clk/qcom/clock-qcs404.c
@@ -195,7 +195,7 @@ static ulong qcs404_clk_set_rate(struct clk *clk,
ulong rate)
        case GCC_BLSP1_UART2_APPS_CLK:
                /* UART: 115200 */
                clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125,
-                                    CFG_CLK_SRC_CXO, 8);
+                                    CFG_CLK_SRC_CXO, 16);
                clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
                break;
        case GCC_BLSP1_AHB_CLK:

This is needed as per Linux qcs404 clock driver too. I would suggest
you double check if you have imported correct values from
corresponding Linux clock drivers for other platforms too.

BTW, after this fix feel free to add:

Tested-by: Sumit Garg <sumit.garg@linaro.org> (QCS404)

-Sumit

>
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
> ---
>  drivers/clk/qcom/clock-apq8016.c |  4 ++--
>  drivers/clk/qcom/clock-apq8096.c |  4 ++--
>  drivers/clk/qcom/clock-qcom.c    | 11 +++++++----
>  drivers/clk/qcom/clock-qcom.h    |  2 +-
>  drivers/clk/qcom/clock-qcs404.c  | 18 +++++++++---------
>  drivers/clk/qcom/clock-sdm845.c  |  3 +--
>  6 files changed, 22 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c
> index 3f44252c453e..630619c83454 100644
> --- a/drivers/clk/qcom/clock-apq8016.c
> +++ b/drivers/clk/qcom/clock-apq8016.c
> @@ -86,7 +86,7 @@ static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
>         clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot));
>         /* 800Mhz/div, gpll0 */
>         clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
> -                            CFG_CLK_SRC_GPLL0);
> +                            CFG_CLK_SRC_GPLL0, 8);
>         clk_enable_gpll0(priv->base, &gpll0_vote_clk);
>         clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
>
> @@ -109,7 +109,7 @@ static int clk_init_uart(struct msm_clk_priv *priv)
>
>         /* 7372800 uart block clock @ GPLL0 */
>         clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625,
> -                            CFG_CLK_SRC_GPLL0);
> +                            CFG_CLK_SRC_GPLL0, 8);
>
>         /* Vote for gpll0 clock */
>         clk_enable_gpll0(priv->base, &gpll0_vote_clk);
> diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c
> index 75633a7c2af8..095c1b431245 100644
> --- a/drivers/clk/qcom/clock-apq8096.c
> +++ b/drivers/clk/qcom/clock-apq8096.c
> @@ -69,7 +69,7 @@ static int clk_init_sdc(struct msm_clk_priv *priv, uint rate)
>
>         clk_enable_cbc(priv->base + SDCC2_AHB_CBCR);
>         clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0,
> -                            CFG_CLK_SRC_GPLL0);
> +                            CFG_CLK_SRC_GPLL0, 8);
>         clk_enable_gpll0(priv->base, &gpll0_vote_clk);
>         clk_enable_cbc(priv->base + SDCC2_APPS_CBCR);
>
> @@ -91,7 +91,7 @@ static int clk_init_uart(struct msm_clk_priv *priv)
>
>         /* 7372800 uart block clock @ GPLL0 */
>         clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 192, 15625,
> -                            CFG_CLK_SRC_GPLL0);
> +                            CFG_CLK_SRC_GPLL0, 8);
>
>         /* Vote for gpll0 clock */
>         clk_enable_gpll0(priv->base, &gpll0_vote_clk);
> diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
> index 77bcaacd1583..fc478554f982 100644
> --- a/drivers/clk/qcom/clock-qcom.c
> +++ b/drivers/clk/qcom/clock-qcom.c
> @@ -83,7 +83,7 @@ void clk_bcr_update(phys_addr_t apps_cmd_rcgr)
>
>  /* root set rate for clocks with half integer and MND divider */
>  void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
> -                         int div, int m, int n, int source)
> +                         int div, int m, int n, int source, u8 mnd_width)
>  {
>         u32 cfg;
>         /* M value for MND divider. */
> @@ -92,11 +92,14 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
>         u32 n_val = ~((n) - (m)) * !!(n);
>         /* NOT 2D value for MND divider. */
>         u32 d_val = ~(n);
> +       u32 mask = BIT(mnd_width) - 1;
> +
> +       debug("m %#x n %#x d %#x div %#x mask %#x\n", m_val, n_val, d_val, div, mask);
>
>         /* Program MND values */
> -       writel(m_val, base + regs->M);
> -       writel(n_val, base + regs->N);
> -       writel(d_val, base + regs->D);
> +       writel(m_val & mask, base + regs->M);
> +       writel(n_val & mask, base + regs->N);
> +       writel(d_val & mask, base + regs->D);
>
>         /* setup src select and divider */
>         cfg  = readl(base + regs->cfg_rcgr);
> diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
> index 86f9ff6eb2f6..24a32cb9666d 100644
> --- a/drivers/clk/qcom/clock-qcom.h
> +++ b/drivers/clk/qcom/clock-qcom.h
> @@ -72,7 +72,7 @@ void clk_bcr_update(phys_addr_t apps_cmd_rgcr);
>  void clk_enable_cbc(phys_addr_t cbcr);
>  void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk);
>  void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
> -                         int div, int m, int n, int source);
> +                         int div, int m, int n, int source, u8 mnd_width);
>  void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
>                       int source);
>
> diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c
> index 9ad580b50fc8..921abf1f699b 100644
> --- a/drivers/clk/qcom/clock-qcs404.c
> +++ b/drivers/clk/qcom/clock-qcs404.c
> @@ -195,7 +195,7 @@ static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate)
>         case GCC_BLSP1_UART2_APPS_CLK:
>                 /* UART: 115200 */
>                 clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125,
> -                                    CFG_CLK_SRC_CXO);
> +                                    CFG_CLK_SRC_CXO, 8);
>                 clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
>                 break;
>         case GCC_BLSP1_AHB_CLK:
> @@ -204,7 +204,7 @@ static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate)
>         case GCC_SDCC1_APPS_CLK:
>                 /* SDCC1: 200MHz */
>                 clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 4, 0, 0,
> -                                    CFG_CLK_SRC_GPLL0);
> +                                    CFG_CLK_SRC_GPLL0, 8);
>                 clk_enable_gpll0(priv->base, &gpll0_vote_clk);
>                 clk_enable_cbc(priv->base + SDCC_APPS_CBCR(1));
>                 break;
> @@ -214,16 +214,16 @@ static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate)
>         case GCC_ETH_RGMII_CLK:
>                 if (rate == 250000000)
>                         clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0,
> -                                            CFG_CLK_SRC_GPLL1);
> +                                            CFG_CLK_SRC_GPLL1, 8);
>                 else if (rate == 125000000)
>                         clk_rcg_set_rate_mnd(priv->base, &emac_regs, 4, 0, 0,
> -                                            CFG_CLK_SRC_GPLL1);
> +                                            CFG_CLK_SRC_GPLL1, 8);
>                 else if (rate == 50000000)
>                         clk_rcg_set_rate_mnd(priv->base, &emac_regs, 10, 0, 0,
> -                                            CFG_CLK_SRC_GPLL1);
> +                                            CFG_CLK_SRC_GPLL1, 8);
>                 else if (rate == 5000000)
>                         clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 1, 50,
> -                                            CFG_CLK_SRC_GPLL1);
> +                                            CFG_CLK_SRC_GPLL1, 8);
>                 break;
>         default:
>                 return 0;
> @@ -240,7 +240,7 @@ static int qcs404_clk_enable(struct clk *clk)
>         case GCC_USB30_MASTER_CLK:
>                 clk_enable_cbc(priv->base + USB30_MASTER_CBCR);
>                 clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 4, 0, 0,
> -                                    CFG_CLK_SRC_GPLL0);
> +                                    CFG_CLK_SRC_GPLL0, 8);
>                 break;
>         case GCC_SYS_NOC_USB3_CLK:
>                 clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR);
> @@ -262,14 +262,14 @@ static int qcs404_clk_enable(struct clk *clk)
>                 clk_enable_cbc(priv->base + ETH_PTP_CBCR);
>                 clk_enable_gpll0(priv->base, &gpll1_vote_clk);
>                 clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 2, 0, 0,
> -                                    CFG_CLK_SRC_GPLL1);
> +                                    CFG_CLK_SRC_GPLL1, 8);
>                 break;
>         case GCC_ETH_RGMII_CLK:
>                 /* SPEED_1000: freq -> 250MHz */
>                 clk_enable_cbc(priv->base + ETH_RGMII_CBCR);
>                 clk_enable_gpll0(priv->base, &gpll1_vote_clk);
>                 clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0,
> -                                    CFG_CLK_SRC_GPLL1);
> +                                    CFG_CLK_SRC_GPLL1, 8);
>                 break;
>         case GCC_ETH_SLAVE_AHB_CLK:
>                 clk_enable_cbc(priv->base + ETH_SLAVE_AHB_CBCR);
> diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
> index fc9a783f7354..6af1f38302d2 100644
> --- a/drivers/clk/qcom/clock-sdm845.c
> +++ b/drivers/clk/qcom/clock-sdm845.c
> @@ -89,8 +89,7 @@ static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate)
>         case GCC_QUPV3_WRAP1_S1_CLK: /* UART9 */
>                 freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
>                 clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
> -                                    freq->pre_div, freq->m, freq->n, freq->src);
> -
> +                                    freq->pre_div, freq->m, freq->n, freq->src, 16);
>                 return freq->freq;
>         default:
>                 return 0;
>
> --
> 2.42.0
>
Caleb Connolly Nov. 6, 2023, 12:39 p.m. UTC | #2
On 06/11/2023 07:06, Sumit Garg wrote:
> On Fri, 3 Nov 2023 at 21:09, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>>
>> This property is needed on some platforms to ensure that only the
>> relevant bits are set in the M/N/D registers.
> 
> This commit broke qcs404 platform which is fixed by following add-on change:
> 
> diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c
> index 429ff35e1d..f5b3528039 100644
> --- a/drivers/clk/qcom/clock-qcs404.c
> +++ b/drivers/clk/qcom/clock-qcs404.c
> @@ -195,7 +195,7 @@ static ulong qcs404_clk_set_rate(struct clk *clk,
> ulong rate)
>         case GCC_BLSP1_UART2_APPS_CLK:
>                 /* UART: 115200 */
>                 clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125,
> -                                    CFG_CLK_SRC_CXO, 8);
> +                                    CFG_CLK_SRC_CXO, 16);
>                 clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
>                 break;
>         case GCC_BLSP1_AHB_CLK:
> 
> This is needed as per Linux qcs404 clock driver too. I would suggest
> you double check if you have imported correct values from
> corresponding Linux clock drivers for other platforms too.

Ah, you're right - I think all platforms use 16 bits for the UART RCG,
Thanks a lot for testing this.

> 
> BTW, after this fix feel free to add:
> 
> Tested-by: Sumit Garg <sumit.garg@linaro.org> (QCS404)
> 
> -Sumit
> 
>>
>> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
>> Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
>> ---
>>  drivers/clk/qcom/clock-apq8016.c |  4 ++--
>>  drivers/clk/qcom/clock-apq8096.c |  4 ++--
>>  drivers/clk/qcom/clock-qcom.c    | 11 +++++++----
>>  drivers/clk/qcom/clock-qcom.h    |  2 +-
>>  drivers/clk/qcom/clock-qcs404.c  | 18 +++++++++---------
>>  drivers/clk/qcom/clock-sdm845.c  |  3 +--
>>  6 files changed, 22 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c
>> index 3f44252c453e..630619c83454 100644
>> --- a/drivers/clk/qcom/clock-apq8016.c
>> +++ b/drivers/clk/qcom/clock-apq8016.c
>> @@ -86,7 +86,7 @@ static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
>>         clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot));
>>         /* 800Mhz/div, gpll0 */
>>         clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
>> -                            CFG_CLK_SRC_GPLL0);
>> +                            CFG_CLK_SRC_GPLL0, 8);
>>         clk_enable_gpll0(priv->base, &gpll0_vote_clk);
>>         clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
>>
>> @@ -109,7 +109,7 @@ static int clk_init_uart(struct msm_clk_priv *priv)
>>
>>         /* 7372800 uart block clock @ GPLL0 */
>>         clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625,
>> -                            CFG_CLK_SRC_GPLL0);
>> +                            CFG_CLK_SRC_GPLL0, 8);
>>
>>         /* Vote for gpll0 clock */
>>         clk_enable_gpll0(priv->base, &gpll0_vote_clk);
>> diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c
>> index 75633a7c2af8..095c1b431245 100644
>> --- a/drivers/clk/qcom/clock-apq8096.c
>> +++ b/drivers/clk/qcom/clock-apq8096.c
>> @@ -69,7 +69,7 @@ static int clk_init_sdc(struct msm_clk_priv *priv, uint rate)
>>
>>         clk_enable_cbc(priv->base + SDCC2_AHB_CBCR);
>>         clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0,
>> -                            CFG_CLK_SRC_GPLL0);
>> +                            CFG_CLK_SRC_GPLL0, 8);
>>         clk_enable_gpll0(priv->base, &gpll0_vote_clk);
>>         clk_enable_cbc(priv->base + SDCC2_APPS_CBCR);
>>
>> @@ -91,7 +91,7 @@ static int clk_init_uart(struct msm_clk_priv *priv)
>>
>>         /* 7372800 uart block clock @ GPLL0 */
>>         clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 192, 15625,
>> -                            CFG_CLK_SRC_GPLL0);
>> +                            CFG_CLK_SRC_GPLL0, 8);
>>
>>         /* Vote for gpll0 clock */
>>         clk_enable_gpll0(priv->base, &gpll0_vote_clk);
>> diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
>> index 77bcaacd1583..fc478554f982 100644
>> --- a/drivers/clk/qcom/clock-qcom.c
>> +++ b/drivers/clk/qcom/clock-qcom.c
>> @@ -83,7 +83,7 @@ void clk_bcr_update(phys_addr_t apps_cmd_rcgr)
>>
>>  /* root set rate for clocks with half integer and MND divider */
>>  void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
>> -                         int div, int m, int n, int source)
>> +                         int div, int m, int n, int source, u8 mnd_width)
>>  {
>>         u32 cfg;
>>         /* M value for MND divider. */
>> @@ -92,11 +92,14 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
>>         u32 n_val = ~((n) - (m)) * !!(n);
>>         /* NOT 2D value for MND divider. */
>>         u32 d_val = ~(n);
>> +       u32 mask = BIT(mnd_width) - 1;
>> +
>> +       debug("m %#x n %#x d %#x div %#x mask %#x\n", m_val, n_val, d_val, div, mask);
>>
>>         /* Program MND values */
>> -       writel(m_val, base + regs->M);
>> -       writel(n_val, base + regs->N);
>> -       writel(d_val, base + regs->D);
>> +       writel(m_val & mask, base + regs->M);
>> +       writel(n_val & mask, base + regs->N);
>> +       writel(d_val & mask, base + regs->D);
>>
>>         /* setup src select and divider */
>>         cfg  = readl(base + regs->cfg_rcgr);
>> diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
>> index 86f9ff6eb2f6..24a32cb9666d 100644
>> --- a/drivers/clk/qcom/clock-qcom.h
>> +++ b/drivers/clk/qcom/clock-qcom.h
>> @@ -72,7 +72,7 @@ void clk_bcr_update(phys_addr_t apps_cmd_rgcr);
>>  void clk_enable_cbc(phys_addr_t cbcr);
>>  void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk);
>>  void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
>> -                         int div, int m, int n, int source);
>> +                         int div, int m, int n, int source, u8 mnd_width);
>>  void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
>>                       int source);
>>
>> diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c
>> index 9ad580b50fc8..921abf1f699b 100644
>> --- a/drivers/clk/qcom/clock-qcs404.c
>> +++ b/drivers/clk/qcom/clock-qcs404.c
>> @@ -195,7 +195,7 @@ static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate)
>>         case GCC_BLSP1_UART2_APPS_CLK:
>>                 /* UART: 115200 */
>>                 clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125,
>> -                                    CFG_CLK_SRC_CXO);
>> +                                    CFG_CLK_SRC_CXO, 8);
>>                 clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
>>                 break;
>>         case GCC_BLSP1_AHB_CLK:
>> @@ -204,7 +204,7 @@ static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate)
>>         case GCC_SDCC1_APPS_CLK:
>>                 /* SDCC1: 200MHz */
>>                 clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 4, 0, 0,
>> -                                    CFG_CLK_SRC_GPLL0);
>> +                                    CFG_CLK_SRC_GPLL0, 8);
>>                 clk_enable_gpll0(priv->base, &gpll0_vote_clk);
>>                 clk_enable_cbc(priv->base + SDCC_APPS_CBCR(1));
>>                 break;
>> @@ -214,16 +214,16 @@ static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate)
>>         case GCC_ETH_RGMII_CLK:
>>                 if (rate == 250000000)
>>                         clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0,
>> -                                            CFG_CLK_SRC_GPLL1);
>> +                                            CFG_CLK_SRC_GPLL1, 8);
>>                 else if (rate == 125000000)
>>                         clk_rcg_set_rate_mnd(priv->base, &emac_regs, 4, 0, 0,
>> -                                            CFG_CLK_SRC_GPLL1);
>> +                                            CFG_CLK_SRC_GPLL1, 8);
>>                 else if (rate == 50000000)
>>                         clk_rcg_set_rate_mnd(priv->base, &emac_regs, 10, 0, 0,
>> -                                            CFG_CLK_SRC_GPLL1);
>> +                                            CFG_CLK_SRC_GPLL1, 8);
>>                 else if (rate == 5000000)
>>                         clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 1, 50,
>> -                                            CFG_CLK_SRC_GPLL1);
>> +                                            CFG_CLK_SRC_GPLL1, 8);
>>                 break;
>>         default:
>>                 return 0;
>> @@ -240,7 +240,7 @@ static int qcs404_clk_enable(struct clk *clk)
>>         case GCC_USB30_MASTER_CLK:
>>                 clk_enable_cbc(priv->base + USB30_MASTER_CBCR);
>>                 clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 4, 0, 0,
>> -                                    CFG_CLK_SRC_GPLL0);
>> +                                    CFG_CLK_SRC_GPLL0, 8);
>>                 break;
>>         case GCC_SYS_NOC_USB3_CLK:
>>                 clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR);
>> @@ -262,14 +262,14 @@ static int qcs404_clk_enable(struct clk *clk)
>>                 clk_enable_cbc(priv->base + ETH_PTP_CBCR);
>>                 clk_enable_gpll0(priv->base, &gpll1_vote_clk);
>>                 clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 2, 0, 0,
>> -                                    CFG_CLK_SRC_GPLL1);
>> +                                    CFG_CLK_SRC_GPLL1, 8);
>>                 break;
>>         case GCC_ETH_RGMII_CLK:
>>                 /* SPEED_1000: freq -> 250MHz */
>>                 clk_enable_cbc(priv->base + ETH_RGMII_CBCR);
>>                 clk_enable_gpll0(priv->base, &gpll1_vote_clk);
>>                 clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0,
>> -                                    CFG_CLK_SRC_GPLL1);
>> +                                    CFG_CLK_SRC_GPLL1, 8);
>>                 break;
>>         case GCC_ETH_SLAVE_AHB_CLK:
>>                 clk_enable_cbc(priv->base + ETH_SLAVE_AHB_CBCR);
>> diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
>> index fc9a783f7354..6af1f38302d2 100644
>> --- a/drivers/clk/qcom/clock-sdm845.c
>> +++ b/drivers/clk/qcom/clock-sdm845.c
>> @@ -89,8 +89,7 @@ static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate)
>>         case GCC_QUPV3_WRAP1_S1_CLK: /* UART9 */
>>                 freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
>>                 clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
>> -                                    freq->pre_div, freq->m, freq->n, freq->src);
>> -
>> +                                    freq->pre_div, freq->m, freq->n, freq->src, 16);
>>                 return freq->freq;
>>         default:
>>                 return 0;
>>
>> --
>> 2.42.0
>>
diff mbox series

Patch

diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c
index 3f44252c453e..630619c83454 100644
--- a/drivers/clk/qcom/clock-apq8016.c
+++ b/drivers/clk/qcom/clock-apq8016.c
@@ -86,7 +86,7 @@  static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
 	clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot));
 	/* 800Mhz/div, gpll0 */
 	clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
-			     CFG_CLK_SRC_GPLL0);
+			     CFG_CLK_SRC_GPLL0, 8);
 	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
 	clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
 
@@ -109,7 +109,7 @@  static int clk_init_uart(struct msm_clk_priv *priv)
 
 	/* 7372800 uart block clock @ GPLL0 */
 	clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625,
-			     CFG_CLK_SRC_GPLL0);
+			     CFG_CLK_SRC_GPLL0, 8);
 
 	/* Vote for gpll0 clock */
 	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c
index 75633a7c2af8..095c1b431245 100644
--- a/drivers/clk/qcom/clock-apq8096.c
+++ b/drivers/clk/qcom/clock-apq8096.c
@@ -69,7 +69,7 @@  static int clk_init_sdc(struct msm_clk_priv *priv, uint rate)
 
 	clk_enable_cbc(priv->base + SDCC2_AHB_CBCR);
 	clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0,
-			     CFG_CLK_SRC_GPLL0);
+			     CFG_CLK_SRC_GPLL0, 8);
 	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
 	clk_enable_cbc(priv->base + SDCC2_APPS_CBCR);
 
@@ -91,7 +91,7 @@  static int clk_init_uart(struct msm_clk_priv *priv)
 
 	/* 7372800 uart block clock @ GPLL0 */
 	clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 192, 15625,
-			     CFG_CLK_SRC_GPLL0);
+			     CFG_CLK_SRC_GPLL0, 8);
 
 	/* Vote for gpll0 clock */
 	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index 77bcaacd1583..fc478554f982 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -83,7 +83,7 @@  void clk_bcr_update(phys_addr_t apps_cmd_rcgr)
 
 /* root set rate for clocks with half integer and MND divider */
 void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
-			  int div, int m, int n, int source)
+			  int div, int m, int n, int source, u8 mnd_width)
 {
 	u32 cfg;
 	/* M value for MND divider. */
@@ -92,11 +92,14 @@  void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
 	u32 n_val = ~((n) - (m)) * !!(n);
 	/* NOT 2D value for MND divider. */
 	u32 d_val = ~(n);
+	u32 mask = BIT(mnd_width) - 1;
+
+	debug("m %#x n %#x d %#x div %#x mask %#x\n", m_val, n_val, d_val, div, mask);
 
 	/* Program MND values */
-	writel(m_val, base + regs->M);
-	writel(n_val, base + regs->N);
-	writel(d_val, base + regs->D);
+	writel(m_val & mask, base + regs->M);
+	writel(n_val & mask, base + regs->N);
+	writel(d_val & mask, base + regs->D);
 
 	/* setup src select and divider */
 	cfg  = readl(base + regs->cfg_rcgr);
diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
index 86f9ff6eb2f6..24a32cb9666d 100644
--- a/drivers/clk/qcom/clock-qcom.h
+++ b/drivers/clk/qcom/clock-qcom.h
@@ -72,7 +72,7 @@  void clk_bcr_update(phys_addr_t apps_cmd_rgcr);
 void clk_enable_cbc(phys_addr_t cbcr);
 void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk);
 void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
-			  int div, int m, int n, int source);
+			  int div, int m, int n, int source, u8 mnd_width);
 void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
 		      int source);
 
diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c
index 9ad580b50fc8..921abf1f699b 100644
--- a/drivers/clk/qcom/clock-qcs404.c
+++ b/drivers/clk/qcom/clock-qcs404.c
@@ -195,7 +195,7 @@  static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate)
 	case GCC_BLSP1_UART2_APPS_CLK:
 		/* UART: 115200 */
 		clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125,
-				     CFG_CLK_SRC_CXO);
+				     CFG_CLK_SRC_CXO, 8);
 		clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
 		break;
 	case GCC_BLSP1_AHB_CLK:
@@ -204,7 +204,7 @@  static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate)
 	case GCC_SDCC1_APPS_CLK:
 		/* SDCC1: 200MHz */
 		clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 4, 0, 0,
-				     CFG_CLK_SRC_GPLL0);
+				     CFG_CLK_SRC_GPLL0, 8);
 		clk_enable_gpll0(priv->base, &gpll0_vote_clk);
 		clk_enable_cbc(priv->base + SDCC_APPS_CBCR(1));
 		break;
@@ -214,16 +214,16 @@  static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate)
 	case GCC_ETH_RGMII_CLK:
 		if (rate == 250000000)
 			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0,
-					     CFG_CLK_SRC_GPLL1);
+					     CFG_CLK_SRC_GPLL1, 8);
 		else if (rate == 125000000)
 			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 4, 0, 0,
-					     CFG_CLK_SRC_GPLL1);
+					     CFG_CLK_SRC_GPLL1, 8);
 		else if (rate == 50000000)
 			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 10, 0, 0,
-					     CFG_CLK_SRC_GPLL1);
+					     CFG_CLK_SRC_GPLL1, 8);
 		else if (rate == 5000000)
 			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 1, 50,
-					     CFG_CLK_SRC_GPLL1);
+					     CFG_CLK_SRC_GPLL1, 8);
 		break;
 	default:
 		return 0;
@@ -240,7 +240,7 @@  static int qcs404_clk_enable(struct clk *clk)
 	case GCC_USB30_MASTER_CLK:
 		clk_enable_cbc(priv->base + USB30_MASTER_CBCR);
 		clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 4, 0, 0,
-				     CFG_CLK_SRC_GPLL0);
+				     CFG_CLK_SRC_GPLL0, 8);
 		break;
 	case GCC_SYS_NOC_USB3_CLK:
 		clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR);
@@ -262,14 +262,14 @@  static int qcs404_clk_enable(struct clk *clk)
 		clk_enable_cbc(priv->base + ETH_PTP_CBCR);
 		clk_enable_gpll0(priv->base, &gpll1_vote_clk);
 		clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 2, 0, 0,
-				     CFG_CLK_SRC_GPLL1);
+				     CFG_CLK_SRC_GPLL1, 8);
 		break;
 	case GCC_ETH_RGMII_CLK:
 		/* SPEED_1000: freq -> 250MHz */
 		clk_enable_cbc(priv->base + ETH_RGMII_CBCR);
 		clk_enable_gpll0(priv->base, &gpll1_vote_clk);
 		clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0,
-				     CFG_CLK_SRC_GPLL1);
+				     CFG_CLK_SRC_GPLL1, 8);
 		break;
 	case GCC_ETH_SLAVE_AHB_CLK:
 		clk_enable_cbc(priv->base + ETH_SLAVE_AHB_CBCR);
diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
index fc9a783f7354..6af1f38302d2 100644
--- a/drivers/clk/qcom/clock-sdm845.c
+++ b/drivers/clk/qcom/clock-sdm845.c
@@ -89,8 +89,7 @@  static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate)
 	case GCC_QUPV3_WRAP1_S1_CLK: /* UART9 */
 		freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
 		clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
-				     freq->pre_div, freq->m, freq->n, freq->src);
-
+				     freq->pre_div, freq->m, freq->n, freq->src, 16);
 		return freq->freq;
 	default:
 		return 0;