]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
ARM: tegra: clock: support get and set rate for simple PLL
authorSvyatoslav Ryhel <clamor95@gmail.com>
Mon, 3 Jul 2023 15:06:54 +0000 (18:06 +0300)
committerSvyatoslav Ryhel <clamor95@gmail.com>
Tue, 19 Dec 2023 19:24:11 +0000 (21:24 +0200)
Simple PLL clocks like PLLD2 were omitted since they do not share common
4 register structure with main clocks. Such clocks are containd in simple
PLL group. Only clock_start_pll function supported them. This patch expands
this support on clock_set_rate and clock_get_rate which should make
simple PLL clocks equal to main PLL clocks.

Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
arch/arm/mach-tegra/clock.c
arch/arm/mach-tegra/tegra114/clock.c
arch/arm/mach-tegra/tegra124/clock.c
arch/arm/mach-tegra/tegra20/clock.c
arch/arm/mach-tegra/tegra210/clock.c
arch/arm/mach-tegra/tegra30/clock.c

index 966009f3752c22c4c2a09afb06a14b774bb03005..7f31630a2347b2bf6301337ba507e664dd1d9f31 100644 (file)
@@ -128,14 +128,14 @@ unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn,
        struct clk_pll_simple *simple_pll = NULL;
        u32 misc_data, data;
 
-       if (clkid < (enum clock_id)TEGRA_CLK_PLLS) {
+       if (clkid < (enum clock_id)TEGRA_CLK_PLLS)
                pll = get_pll(clkid);
-       } else {
+       else
                simple_pll = clock_get_simple_pll(clkid);
-               if (!simple_pll) {
-                       debug("%s: Uknown simple PLL %d\n", __func__, clkid);
-                       return 0;
-               }
+
+       if (!simple_pll && !pll) {
+               log_err("Unknown PLL id %d\n", clkid);
+               return 0;
        }
 
        /*
@@ -542,7 +542,8 @@ unsigned int __weak clk_m_get_rate(unsigned int parent_rate)
 
 unsigned clock_get_rate(enum clock_id clkid)
 {
-       struct clk_pll *pll;
+       struct clk_pll *pll = NULL;
+       struct clk_pll_simple *simple_pll = NULL;
        u32 base, divm;
        u64 parent_rate, rate;
        struct clk_pll_info *pllinfo = &tegra_pll_info_table[clkid];
@@ -554,10 +555,20 @@ unsigned clock_get_rate(enum clock_id clkid)
        if (clkid == CLOCK_ID_CLK_M)
                return clk_m_get_rate(parent_rate);
 
-       pll = get_pll(clkid);
-       if (!pll)
+       if (clkid < (enum clock_id)TEGRA_CLK_PLLS)
+               pll = get_pll(clkid);
+       else
+               simple_pll = clock_get_simple_pll(clkid);
+
+       if (!simple_pll && !pll) {
+               log_err("Unknown PLL id %d\n", clkid);
                return 0;
-       base = readl(&pll->pll_base);
+       }
+
+       if (pll)
+               base = readl(&pll->pll_base);
+       else
+               base = readl(&simple_pll->pll_base);
 
        rate = parent_rate * ((base >> pllinfo->n_shift) & pllinfo->n_mask);
        divm = (base >> pllinfo->m_shift) & pllinfo->m_mask;
@@ -599,12 +610,24 @@ unsigned clock_get_rate(enum clock_id clkid)
 int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon)
 {
        u32 base_reg, misc_reg;
-       struct clk_pll *pll;
+       struct clk_pll *pll = NULL;
+       struct clk_pll_simple *simple_pll = NULL;
        struct clk_pll_info *pllinfo = &tegra_pll_info_table[clkid];
 
-       pll = get_pll(clkid);
+       if (clkid < (enum clock_id)TEGRA_CLK_PLLS)
+               pll = get_pll(clkid);
+       else
+               simple_pll = clock_get_simple_pll(clkid);
+
+       if (!simple_pll && !pll) {
+               log_err("Unknown PLL id %d\n", clkid);
+               return 0;
+       }
 
-       base_reg = readl(&pll->pll_base);
+       if (pll)
+               base_reg = readl(&pll->pll_base);
+       else
+               base_reg = readl(&simple_pll->pll_base);
 
        /* Set BYPASS, m, n and p to PLL_BASE */
        base_reg &= ~(pllinfo->m_mask << pllinfo->m_shift);
@@ -631,21 +654,37 @@ int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon)
        }
 
        base_reg |= PLL_BYPASS_MASK;
-       writel(base_reg, &pll->pll_base);
+       if (pll)
+               writel(base_reg, &pll->pll_base);
+       else
+               writel(base_reg, &simple_pll->pll_base);
 
        /* Set cpcon (KCP) to PLL_MISC */
-       misc_reg = readl(&pll->pll_misc);
+       if (pll)
+               misc_reg = readl(&pll->pll_misc);
+       else
+               misc_reg = readl(&simple_pll->pll_misc);
+
        misc_reg &= ~(pllinfo->kcp_mask << pllinfo->kcp_shift);
        misc_reg |= cpcon << pllinfo->kcp_shift;
-       writel(misc_reg, &pll->pll_misc);
+       if (pll)
+               writel(misc_reg, &pll->pll_misc);
+       else
+               writel(misc_reg, &simple_pll->pll_misc);
 
        /* Enable PLL */
        base_reg |= PLL_ENABLE_MASK;
-       writel(base_reg, &pll->pll_base);
+       if (pll)
+               writel(base_reg, &pll->pll_base);
+       else
+               writel(base_reg, &simple_pll->pll_base);
 
        /* Disable BYPASS */
        base_reg &= ~PLL_BYPASS_MASK;
-       writel(base_reg, &pll->pll_base);
+       if (pll)
+               writel(base_reg, &pll->pll_base);
+       else
+               writel(base_reg, &simple_pll->pll_base);
 
        return 0;
 }
index 8ad71f590fa71121bed4ad686dd27bdba8520867..9a8c10e3d6cd20b7101974bba6ad763145a14011 100644 (file)
@@ -768,6 +768,21 @@ void arch_timer_init(void)
        debug("%s: TSC CNTCR = 0x%08X\n", __func__, val);
 }
 
+struct clk_pll_simple *clock_get_simple_pll(enum clock_id clkid)
+{
+       struct clk_rst_ctlr *clkrst =
+                       (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+
+       switch (clkid) {
+       case CLOCK_ID_XCPU:
+       case CLOCK_ID_EPCI:
+       case CLOCK_ID_SFROM32KHZ:
+               return &clkrst->crc_pll_simple[clkid - CLOCK_ID_FIRST_SIMPLE];
+       default:
+               return NULL;
+       }
+}
+
 struct periph_clk_init periph_clk_init_table[] = {
        { PERIPH_ID_SBC1, CLOCK_ID_PERIPH },
        { PERIPH_ID_SBC2, CLOCK_ID_PERIPH },
index ca9549a318688737dfc16d841037b0484832c595..ed8b6d963816a45369d1df288944e0d0805ee957 100644 (file)
@@ -1189,10 +1189,16 @@ struct clk_pll_simple *clock_get_simple_pll(enum clock_id clkid)
        struct clk_rst_ctlr *clkrst =
                        (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
 
-       if (clkid == CLOCK_ID_DP)
+       switch (clkid) {
+       case CLOCK_ID_XCPU:
+       case CLOCK_ID_EPCI:
+       case CLOCK_ID_SFROM32KHZ:
+               return &clkrst->crc_pll_simple[clkid - CLOCK_ID_FIRST_SIMPLE];
+       case CLOCK_ID_DP:
                return &clkrst->plldp;
-
-       return NULL;
+       default:
+               return NULL;
+       }
 }
 
 struct periph_clk_init periph_clk_init_table[] = {
index abd6e3917acd731ddd2ced86c2dcd28c48f215a1..109b73bfbe7f14e6266736eb316ad1c8d2ce18b0 100644 (file)
@@ -792,6 +792,21 @@ int tegra_plle_enable(void)
        return 0;
 }
 
+struct clk_pll_simple *clock_get_simple_pll(enum clock_id clkid)
+{
+       struct clk_rst_ctlr *clkrst =
+                       (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+
+       switch (clkid) {
+       case CLOCK_ID_XCPU:
+       case CLOCK_ID_EPCI:
+       case CLOCK_ID_SFROM32KHZ:
+               return &clkrst->crc_pll_simple[clkid - CLOCK_ID_FIRST_SIMPLE];
+       default:
+               return NULL;
+       }
+}
+
 struct periph_clk_init periph_clk_init_table[] = {
        { PERIPH_ID_SPI1, CLOCK_ID_PERIPH },
        { PERIPH_ID_SBC1, CLOCK_ID_PERIPH },
index 900537afbe50831c3f6abd6c65c68495cd265fae..74817e0440b8080ac747bda8c330c1e14a2bd0fa 100644 (file)
@@ -1266,6 +1266,21 @@ int tegra_plle_enable(void)
        return 0;
 }
 
+struct clk_pll_simple *clock_get_simple_pll(enum clock_id clkid)
+{
+       struct clk_rst_ctlr *clkrst =
+                       (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+
+       switch (clkid) {
+       case CLOCK_ID_XCPU:
+       case CLOCK_ID_EPCI:
+       case CLOCK_ID_SFROM32KHZ:
+               return &clkrst->crc_pll_simple[clkid - CLOCK_ID_FIRST_SIMPLE];
+       default:
+               return NULL;
+       }
+}
+
 struct periph_clk_init periph_clk_init_table[] = {
        { PERIPH_ID_SBC1, CLOCK_ID_PERIPH },
        { PERIPH_ID_SBC2, CLOCK_ID_PERIPH },
index 698c7ab9560d26317e4d5a271b8b130ad49d1fe2..7bbe70921f0a393dacfffb565daaae3ec003c9a7 100644 (file)
@@ -871,6 +871,21 @@ int tegra_plle_enable(void)
        return 0;
 }
 
+struct clk_pll_simple *clock_get_simple_pll(enum clock_id clkid)
+{
+       struct clk_rst_ctlr *clkrst =
+                       (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+
+       switch (clkid) {
+       case CLOCK_ID_XCPU:
+       case CLOCK_ID_EPCI:
+       case CLOCK_ID_SFROM32KHZ:
+               return &clkrst->crc_pll_simple[clkid - CLOCK_ID_FIRST_SIMPLE];
+       default:
+               return NULL;
+       }
+}
+
 struct periph_clk_init periph_clk_init_table[] = {
        { PERIPH_ID_SBC1, CLOCK_ID_PERIPH },
        { PERIPH_ID_SBC2, CLOCK_ID_PERIPH },