imx8ulp: clock: Support LPAV clocks in cgc and pcc
authorYe Li <ye.li@nxp.com>
Fri, 29 Oct 2021 01:46:18 +0000 (09:46 +0800)
committerStefano Babic <sbabic@denx.de>
Sat, 5 Feb 2022 12:38:38 +0000 (13:38 +0100)
Add the PCC5 clocks support and more LPAV clocks and PLL4 PFD in CGC.

Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
arch/arm/include/asm/arch-imx8ulp/cgc.h
arch/arm/include/asm/arch-imx8ulp/pcc.h
arch/arm/mach-imx/imx8ulp/cgc.c
arch/arm/mach-imx/imx8ulp/clock.c
arch/arm/mach-imx/imx8ulp/pcc.c

index 34a15fb..745fd7f 100644 (file)
@@ -6,11 +6,15 @@
 #ifndef _ASM_ARCH_CGC_H
 #define _ASM_ARCH_CGC_H
 
-enum cgc1_clk {
+enum cgc_clk {
        DUMMY0_CLK,
        DUMMY1_CLK,
        LPOSC,
+       NIC_APCLK,
+       NIC_PERCLK,
+       XBAR_APCLK,
        XBAR_BUSCLK,
+       AD_SLOWCLK,
        SOSC,
        SOSC_DIV1,
        SOSC_DIV2,
@@ -34,6 +38,24 @@ enum cgc1_clk {
        PLL3_PFD2_DIV2,
        PLL3_PFD3_DIV1,
        PLL3_PFD3_DIV2,
+       LVDS,
+       LPAV_AXICLK,
+       LPAV_AHBCLK,
+       LPAV_BUSCLK,
+       PLL4,
+       PLL4_VCODIV,
+       PLL4_PFD0,
+       PLL4_PFD1,
+       PLL4_PFD2,
+       PLL4_PFD3,
+       PLL4_PFD0_DIV1,
+       PLL4_PFD0_DIV2,
+       PLL4_PFD1_DIV1,
+       PLL4_PFD1_DIV2,
+       PLL4_PFD2_DIV1,
+       PLL4_PFD2_DIV2,
+       PLL4_PFD3_DIV1,
+       PLL4_PFD3_DIV2,
 };
 
 struct cgc1_regs {
@@ -119,12 +141,16 @@ struct cgc2_regs {
        u32 lvdscfg;
 };
 
-u32 cgc1_clk_get_rate(enum cgc1_clk clk);
+u32 cgc_clk_get_rate(enum cgc_clk clk);
 void cgc1_pll3_init(void);
 void cgc1_pll2_init(void);
 void cgc1_soscdiv_init(void);
 void cgc1_init_core_clk(void);
 void cgc2_pll4_init(void);
 void cgc2_ddrclk_config(u32 src, u32 div);
-u32 cgc1_sosc_div(enum cgc1_clk clk);
+u32 cgc1_sosc_div(enum cgc_clk clk);
+void cgc1_enet_stamp_sel(u32 clk_src);
+void cgc2_pll4_pfd_config(enum cgc_clk pllpfd, u32 pfd);
+void cgc2_pll4_pfddiv_config(enum cgc_clk pllpfddiv, u32 div);
+void cgc2_lpav_init(enum cgc_clk clk);
 #endif
index 091d017..4680154 100644 (file)
@@ -90,6 +90,68 @@ enum pcc4_entry {
        RGPIOF_PCC4_SLOT = 31,
 };
 
+enum pcc5_entry {
+       DMA2_MP_PCC5_SLOT = 0,
+       DMA2_CH0_PCC5_SLOT = 1,
+       DMA2_CH1_PCC5_SLOT = 2,
+       DMA2_CH2_PCC5_SLOT = 3,
+       DMA2_CH3_PCC5_SLOT = 4,
+       DMA2_CH4_PCC5_SLOT = 5,
+       DMA2_CH5_PCC5_SLOT = 6,
+       DMA2_CH6_PCC5_SLOT = 7,
+       DMA2_CH7_PCC5_SLOT = 8,
+       DMA2_CH8_PCC5_SLOT = 9,
+       DMA2_CH9_PCC5_SLOT = 10,
+       DMA2_CH10_PCC5_SLOT = 11,
+       DMA2_CH11_PCC5_SLOT = 12,
+       DMA2_CH12_PCC5_SLOT = 13,
+       DMA2_CH13_PCC5_SLOT = 14,
+       DMA2_CH14_PCC5_SLOT = 15,
+       DMA2_CH15_PCC5_SLOT = 16,
+       DMA2_CH16_PCC5_SLOT = 17,
+       DMA2_CH17_PCC5_SLOT = 18,
+       DMA2_CH18_PCC5_SLOT = 19,
+       DMA2_CH19_PCC5_SLOT = 20,
+       DMA2_CH20_PCC5_SLOT = 21,
+       DMA2_CH21_PCC5_SLOT = 22,
+       DMA2_CH22_PCC5_SLOT = 23,
+       DMA2_CH23_PCC5_SLOT = 24,
+       DMA2_CH24_PCC5_SLOT = 25,
+       DMA2_CH25_PCC5_SLOT = 26,
+       DMA2_CH26_PCC5_SLOT = 27,
+       DMA2_CH27_PCC5_SLOT = 28,
+       DMA2_CH28_PCC5_SLOT = 29,
+       DMA2_CH29_PCC5_SLOT = 30,
+       DMA2_CH30_PCC5_SLOT = 31,
+       DMA2_CH31_PCC5_SLOT = 32,
+       MU2_B_PCC5_SLOT = 33,
+       MU3_B_PCC5_SLOT = 34,
+       SEMA42_2_PCC5_SLOT = 35,
+       CMC2_PCC5_SLOT = 36,
+       AVD_SIM_PCC5_SLOT = 37,
+       LPAV_CGC_PCC5_SLOT = 38,
+       PCC5_PCC5_SLOT = 39,
+       TPM8_PCC5_SLOT = 40,
+       SAI6_PCC5_SLOT = 41,
+       SAI7_PCC5_SLOT = 42,
+       SPDIF_PCC5_SLOT = 43,
+       ISI_PCC5_SLOT = 44,
+       CSI_REGS_PCC5_SLOT = 45,
+       CSI_PCC5_SLOT = 47,
+       DSI_PCC5_SLOT = 48,
+       WDOG5_PCC5_SLOT = 50,
+       EPDC_PCC5_SLOT = 51,
+       PXP_PCC5_SLOT = 52,
+       SFA2_PCC5_SLOT = 53,
+       GPU2D_PCC5_SLOT = 60,
+       GPU3D_PCC5_SLOT = 61,
+       DCNANO_PCC5_SLOT = 62,
+       LPDDR4_PCC5_SLOT = 66,
+       CSI_CLK_UI_PCC5_SLOT = 67,
+       CSI_CLK_ESC_PCC5_SLOT = 68,
+       RGPIOD_PCC5_SLOT = 69,
+};
+
 /* PCC registers */
 #define PCC_PR_OFFSET  31
 #define PCC_PR_MASK            (0x1 << PCC_PR_OFFSET)
@@ -130,10 +192,10 @@ struct pcc_entry {
 };
 
 int pcc_clock_enable(int pcc_controller, int pcc_clk_slot, bool enable);
-int pcc_clock_sel(int pcc_controller, int pcc_clk_slot, enum cgc1_clk src);
+int pcc_clock_sel(int pcc_controller, int pcc_clk_slot, enum cgc_clk src);
 int pcc_clock_div_config(int pcc_controller, int pcc_clk_slot, bool frac, u8 div);
 bool pcc_clock_is_enable(int pcc_controller, int pcc_clk_slot);
-int pcc_clock_get_clksrc(int pcc_controller, int pcc_clk_slot, enum cgc1_clk *src);
+int pcc_clock_get_clksrc(int pcc_controller, int pcc_clk_slot, enum cgc_clk *src);
 int pcc_reset_peripheral(int pcc_controller, int pcc_clk_slot, bool reset);
 u32 pcc_clock_get_rate(int pcc_controller, int pcc_clk_slot);
 #endif
index 7bfc386..fc84f3f 100644 (file)
@@ -189,8 +189,8 @@ void cgc2_pll4_init(void)
                ;
 
        /* Enable all 4 PFDs */
-       setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 0); /* 316.8Mhz for NIC_LPAV */
-       setbits_le32(&cgc2_regs->pll4pfdcfg, 18 << 8);
+       setbits_le32(&cgc2_regs->pll4pfdcfg, 18 << 0);
+       setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 8); /* 316.8Mhz for NIC_LPAV */
        setbits_le32(&cgc2_regs->pll4pfdcfg, 12 << 16);
        setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 24);
 
@@ -205,6 +205,68 @@ void cgc2_pll4_init(void)
        clrbits_le32(&cgc2_regs->pll4div_pfd1, BIT(7) | BIT(15) | BIT(23) | BIT(31));
 }
 
+void cgc2_pll4_pfd_config(enum cgc_clk pllpfd, u32 pfd)
+{
+       void __iomem *reg = &cgc2_regs->pll4div_pfd0;
+       u32 halt_mask = BIT(7) | BIT(15);
+       u32 pfd_shift = (pllpfd - PLL4_PFD0) * 8;
+       u32 val;
+
+       if (pllpfd < PLL4_PFD0 || pllpfd > PLL4_PFD3)
+               return;
+
+       if ((pllpfd - PLL4_PFD0) >> 1)
+               reg = &cgc2_regs->pll4div_pfd1;
+
+       halt_mask = halt_mask << (((pllpfd - PLL4_PFD0) & 0x1) * 16);
+
+       /* halt pfd div */
+       setbits_le32(reg, halt_mask);
+
+       /* gate pfd */
+       setbits_le32(&cgc2_regs->pll4pfdcfg, BIT(7) << pfd_shift);
+
+       val = readl(&cgc2_regs->pll4pfdcfg);
+       val &= ~(0x3f << pfd_shift);
+       val |= (pfd << pfd_shift);
+       writel(val, &cgc2_regs->pll4pfdcfg);
+
+       /* ungate */
+       clrbits_le32(&cgc2_regs->pll4pfdcfg, BIT(7) << pfd_shift);
+
+       /* Wait stable */
+       while ((readl(&cgc2_regs->pll4pfdcfg) & (BIT(6) << pfd_shift))
+               != (BIT(6) << pfd_shift))
+               ;
+
+       /* enable pfd div */
+       clrbits_le32(reg, halt_mask);
+}
+
+void cgc2_pll4_pfddiv_config(enum cgc_clk pllpfddiv, u32 div)
+{
+       void __iomem *reg = &cgc2_regs->pll4div_pfd0;
+       u32 shift = ((pllpfddiv - PLL4_PFD0_DIV1) & 0x3) * 8;
+
+       if (pllpfddiv < PLL4_PFD0_DIV1 || pllpfddiv > PLL4_PFD3_DIV2)
+               return;
+
+       if ((pllpfddiv - PLL4_PFD0_DIV1) >> 2)
+               reg = &cgc2_regs->pll4div_pfd1;
+
+       /* Halt pfd div */
+       setbits_le32(reg, BIT(7) << shift);
+
+       /* Clear div */
+       clrbits_le32(reg, 0x3f << shift);
+
+       /* Set div*/
+       setbits_le32(reg, div << shift);
+
+       /* Enable pfd div */
+       clrbits_le32(reg, BIT(7) << shift);
+}
+
 void cgc2_ddrclk_config(u32 src, u32 div)
 {
        writel((src << 28) | (div << 21), &cgc2_regs->ddrclk);
@@ -213,7 +275,63 @@ void cgc2_ddrclk_config(u32 src, u32 div)
                ;
 }
 
-u32 decode_pll(enum cgc1_clk pll)
+void cgc2_lpav_init(enum cgc_clk clk)
+{
+       u32 i, scs, reg;
+       const enum cgc_clk src[] = {FRO, PLL4_PFD1, SOSC, LVDS};
+
+       reg = readl(&cgc2_regs->niclpavclk);
+       scs = (reg >> 28) & 0x3;
+
+       for (i = 0; i < 4; i++) {
+               if (clk == src[i]) {
+                       if (scs == i)
+                               return;
+
+                       reg &= ~(0x3 << 28);
+                       reg |= (i << 28);
+
+                       writel(reg, &cgc2_regs->niclpavclk);
+                       break;
+               }
+       }
+
+       if (i == 4)
+               printf("Invalid clock source [%u] for LPAV\n", clk);
+}
+
+u32 cgc2_nic_get_rate(enum cgc_clk clk)
+{
+       u32 reg, rate;
+       u32 scs, lpav_axi_clk, lpav_ahb_clk, lpav_bus_clk;
+       const enum cgc_clk src[] = {FRO, PLL4_PFD1, SOSC, LVDS};
+
+       reg = readl(&cgc2_regs->niclpavclk);
+       scs = (reg >> 28) & 0x3;
+       lpav_axi_clk = ((reg >> 21) & 0x3f) + 1;
+       lpav_ahb_clk = ((reg >> 14) & 0x3f) + 1;
+       lpav_bus_clk = ((reg >> 7) & 0x3f) + 1;
+
+       rate = cgc_clk_get_rate(src[scs]);
+
+       switch (clk) {
+       case LPAV_AXICLK:
+               rate = rate / lpav_axi_clk;
+               break;
+       case LPAV_AHBCLK:
+               rate = rate / (lpav_axi_clk * lpav_ahb_clk);
+               break;
+       case LPAV_BUSCLK:
+               rate = rate / (lpav_axi_clk * lpav_bus_clk);
+               break;
+       default:
+               return 0;
+       }
+
+       return rate;
+}
+
+u32 decode_pll(enum cgc_clk pll)
 {
        u32 reg, infreq, mult;
        u32 num, denom;
@@ -247,6 +365,17 @@ u32 decode_pll(enum cgc1_clk pll)
                num = readl(&cgc1_regs->pll3num) & 0x3FFFFFFF;
 
                return (u64)infreq * mult + (u64)infreq * num / denom;
+       case PLL4:
+               reg = readl(&cgc2_regs->pll4csr);
+               if (!(reg & BIT(24)))
+                       return 0;
+
+               reg = readl(&cgc2_regs->pll4cfg);
+               mult = (reg >> 16) & 0x7F;
+               denom = readl(&cgc2_regs->pll4denom) & 0x3FFFFFFF;
+               num = readl(&cgc2_regs->pll4num) & 0x3FFFFFFF;
+
+               return (u64)infreq * mult + (u64)infreq * num / denom;
        default:
                printf("Unsupported pll clocks %d\n", pll);
                break;
@@ -255,93 +384,117 @@ u32 decode_pll(enum cgc1_clk pll)
        return 0;
 }
 
-u32 cgc1_pll3_vcodiv_rate(void)
+u32 cgc_pll_vcodiv_rate(enum cgc_clk clk)
 {
        u32 reg, gate, div;
+       void __iomem *plldiv_vco;
+       enum cgc_clk pll;
+
+       if (clk == PLL3_VCODIV) {
+               plldiv_vco = &cgc1_regs->pll3div_vco;
+               pll = PLL3;
+       } else {
+               plldiv_vco = &cgc2_regs->pll4div_vco;
+               pll = PLL4;
+       }
 
-       reg = readl(&cgc1_regs->pll3div_vco);
+       reg = readl(plldiv_vco);
        gate = BIT(7) & reg;
        div = reg & 0x3F;
 
-       return gate ? 0 : decode_pll(PLL3) / (div + 1);
+       return gate ? 0 : decode_pll(pll) / (div + 1);
 }
 
-u32 cgc1_pll3_pfd_rate(enum cgc1_clk clk)
+u32 cgc_pll_pfd_rate(enum cgc_clk clk)
 {
        u32 index, gate, vld, reg;
+       void __iomem *pllpfdcfg;
+       enum cgc_clk pll;
 
        switch (clk) {
        case PLL3_PFD0:
-               index = 0;
-               break;
        case PLL3_PFD1:
-               index = 1;
-               break;
        case PLL3_PFD2:
-               index = 2;
-               break;
        case PLL3_PFD3:
-               index = 3;
+               index = clk - PLL3_PFD0;
+               pllpfdcfg = &cgc1_regs->pll3pfdcfg;
+               pll = PLL3;
+               break;
+       case PLL4_PFD0:
+       case PLL4_PFD1:
+       case PLL4_PFD2:
+       case PLL4_PFD3:
+               index = clk - PLL4_PFD0;
+               pllpfdcfg = &cgc2_regs->pll4pfdcfg;
+               pll = PLL4;
                break;
        default:
                return 0;
        }
 
-       reg = readl(&cgc1_regs->pll3pfdcfg);
+       reg = readl(pllpfdcfg);
        gate = reg & (BIT(7) << (index * 8));
        vld = reg & (BIT(6) << (index * 8));
 
        if (gate || !vld)
                return 0;
 
-       return (u64)decode_pll(PLL3) * 18 / ((reg >> (index * 8)) & 0x3F);
+       return (u64)decode_pll(pll) * 18 / ((reg >> (index * 8)) & 0x3F);
 }
 
-u32 cgc1_pll3_pfd_div(enum cgc1_clk clk)
+u32 cgc_pll_pfd_div(enum cgc_clk clk)
 {
        void __iomem *base;
        u32 pfd, index, gate, reg;
 
        switch (clk) {
        case PLL3_PFD0_DIV1:
-               base = &cgc1_regs->pll3div_pfd0;
-               pfd = PLL3_PFD0;
-               index = 0;
-               break;
        case PLL3_PFD0_DIV2:
                base = &cgc1_regs->pll3div_pfd0;
                pfd = PLL3_PFD0;
-               index = 1;
+               index = clk - PLL3_PFD0_DIV1;
                break;
        case PLL3_PFD1_DIV1:
-               base = &cgc1_regs->pll3div_pfd0;
-               pfd = PLL3_PFD1;
-               index = 2;
-               break;
        case PLL3_PFD1_DIV2:
                base = &cgc1_regs->pll3div_pfd0;
                pfd = PLL3_PFD1;
-               index = 3;
+               index = clk - PLL3_PFD0_DIV1;
                break;
        case PLL3_PFD2_DIV1:
-               base = &cgc1_regs->pll3div_pfd1;
-               pfd = PLL3_PFD2;
-               index = 0;
-               break;
        case PLL3_PFD2_DIV2:
                base = &cgc1_regs->pll3div_pfd1;
                pfd = PLL3_PFD2;
-               index = 1;
+               index = clk - PLL3_PFD2_DIV1;
                break;
        case PLL3_PFD3_DIV1:
-               base = &cgc1_regs->pll3div_pfd1;
-               pfd = PLL3_PFD3;
-               index = 2;
-               break;
        case PLL3_PFD3_DIV2:
                base = &cgc1_regs->pll3div_pfd1;
                pfd = PLL3_PFD3;
-               index = 3;
+               index = clk - PLL3_PFD2_DIV1;
+               break;
+       case PLL4_PFD0_DIV1:
+       case PLL4_PFD0_DIV2:
+               base = &cgc2_regs->pll4div_pfd0;
+               pfd = PLL4_PFD0;
+               index = clk - PLL4_PFD0_DIV1;
+               break;
+       case PLL4_PFD1_DIV1:
+       case PLL4_PFD1_DIV2:
+               base = &cgc2_regs->pll4div_pfd0;
+               pfd = PLL4_PFD1;
+               index = clk - PLL4_PFD0_DIV1;
+               break;
+       case PLL4_PFD2_DIV1:
+       case PLL4_PFD2_DIV2:
+               base = &cgc2_regs->pll4div_pfd1;
+               pfd = PLL4_PFD2;
+               index = clk - PLL4_PFD2_DIV1;
+               break;
+       case PLL4_PFD3_DIV1:
+       case PLL4_PFD3_DIV2:
+               base = &cgc2_regs->pll4div_pfd1;
+               pfd = PLL4_PFD3;
+               index = clk - PLL4_PFD2_DIV1;
                break;
        default:
                return 0;
@@ -353,10 +506,52 @@ u32 cgc1_pll3_pfd_div(enum cgc1_clk clk)
        if (gate)
                return 0;
 
-       return cgc1_pll3_pfd_rate(pfd) / (((reg >> (index * 8)) & 0x3F) + 1);
+       return cgc_pll_pfd_rate(pfd) / (((reg >> (index * 8)) & 0x3F) + 1);
+}
+
+u32 cgc1_nic_get_rate(enum cgc_clk clk)
+{
+       u32 reg, rate;
+       u32 scs, nic_ad_divplat, nic_per_divplat;
+       u32 xbar_ad_divplat, xbar_divbus, ad_slow;
+       const enum cgc_clk src[] = {FRO, PLL3_PFD0, SOSC, LVDS};
+
+       reg = readl(&cgc1_regs->nicclk);
+       scs = (reg >> 28) & 0x3;
+       nic_ad_divplat = ((reg >> 21) & 0x3f) + 1;
+       nic_per_divplat = ((reg >> 14) & 0x3f) + 1;
+
+       reg = readl(&cgc1_regs->xbarclk);
+       xbar_ad_divplat = ((reg >> 14) & 0x3f) + 1;
+       xbar_divbus = ((reg >> 7) & 0x3f) + 1;
+       ad_slow = (reg & 0x3f) + 1;
+
+       rate = cgc_clk_get_rate(src[scs]);
+
+       switch (clk) {
+       case NIC_APCLK:
+               rate = rate / nic_ad_divplat;
+               break;
+       case NIC_PERCLK:
+               rate = rate / (nic_ad_divplat * nic_per_divplat);
+               break;
+       case XBAR_APCLK:
+               rate = rate / (nic_ad_divplat * xbar_ad_divplat);
+               break;
+       case XBAR_BUSCLK:
+               rate = rate / (nic_ad_divplat * xbar_ad_divplat * xbar_divbus);
+               break;
+       case AD_SLOWCLK:
+               rate = rate / (nic_ad_divplat * xbar_ad_divplat * ad_slow);
+               break;
+       default:
+               return 0;
+       }
+
+       return rate;
 }
 
-u32 cgc1_sosc_div(enum cgc1_clk clk)
+u32 cgc1_sosc_div(enum cgc_clk clk)
 {
        u32 reg, gate, index;
 
@@ -385,7 +580,7 @@ u32 cgc1_sosc_div(enum cgc1_clk clk)
        return 24000000 / (((reg >> (index * 8)) & 0x3F) + 1);
 }
 
-u32 cgc1_fro_div(enum cgc1_clk clk)
+u32 cgc1_fro_div(enum cgc_clk clk)
 {
        u32 reg, gate, vld, index;
 
@@ -415,9 +610,11 @@ u32 cgc1_fro_div(enum cgc1_clk clk)
        return 24000000 / (((reg >> (index * 8)) & 0x3F) + 1);
 }
 
-u32 cgc1_clk_get_rate(enum cgc1_clk clk)
+u32 cgc_clk_get_rate(enum cgc_clk clk)
 {
        switch (clk) {
+       case LVDS:
+               return 0; /* No external LVDS clock used */
        case SOSC:
        case SOSC_DIV1:
        case SOSC_DIV2:
@@ -429,16 +626,21 @@ u32 cgc1_clk_get_rate(enum cgc1_clk clk)
        case FRO_DIV3:
                return cgc1_fro_div(clk);
        case PLL2:
-               return decode_pll(PLL2);
        case PLL3:
-               return decode_pll(PLL3);
+       case PLL4:
+               return decode_pll(clk);
        case PLL3_VCODIV:
-               return cgc1_pll3_vcodiv_rate();
+       case PLL4_VCODIV:
+               return cgc_pll_vcodiv_rate(clk);
        case PLL3_PFD0:
        case PLL3_PFD1:
        case PLL3_PFD2:
        case PLL3_PFD3:
-               return cgc1_pll3_pfd_rate(clk);
+       case PLL4_PFD0:
+       case PLL4_PFD1:
+       case PLL4_PFD2:
+       case PLL4_PFD3:
+               return cgc_pll_pfd_rate(clk);
        case PLL3_PFD0_DIV1:
        case PLL3_PFD0_DIV2:
        case PLL3_PFD1_DIV1:
@@ -447,9 +649,27 @@ u32 cgc1_clk_get_rate(enum cgc1_clk clk)
        case PLL3_PFD2_DIV2:
        case PLL3_PFD3_DIV1:
        case PLL3_PFD3_DIV2:
-               return cgc1_pll3_pfd_div(clk);
+       case PLL4_PFD0_DIV1:
+       case PLL4_PFD0_DIV2:
+       case PLL4_PFD1_DIV1:
+       case PLL4_PFD1_DIV2:
+       case PLL4_PFD2_DIV1:
+       case PLL4_PFD2_DIV2:
+       case PLL4_PFD3_DIV1:
+       case PLL4_PFD3_DIV2:
+               return cgc_pll_pfd_div(clk);
+       case NIC_APCLK:
+       case NIC_PERCLK:
+       case XBAR_APCLK:
+       case XBAR_BUSCLK:
+       case AD_SLOWCLK:
+               return cgc1_nic_get_rate(clk);
+       case LPAV_AXICLK:
+       case LPAV_AHBCLK:
+       case LPAV_BUSCLK:
+               return cgc2_nic_get_rate(clk);
        default:
-               printf("Unsupported cgc1 clock: %d\n", clk);
+               printf("Unsupported cgc clock: %d\n", clk);
                return 0;
        }
 }
index ebbaad4..2beacbc 100644 (file)
@@ -27,7 +27,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #define PLL_USB_LOCK_MASK              (0x01 << 31)
 #define PCC5_LPDDR4_ADDR 0x2da70108
 
-static void lpuart_set_clk(u32 index, enum cgc1_clk clk)
+static void lpuart_set_clk(u32 index, enum cgc_clk clk)
 {
        const u32 lpuart_pcc_slots[] = {
                LPUART4_PCC3_SLOT,
@@ -327,7 +327,7 @@ u32 mxc_get_clock(enum mxc_clock clk)
        case MXC_ESDHC3_CLK:
                return pcc_clock_get_rate(4, SDHC2_PCC4_SLOT);
        case MXC_ARM_CLK:
-               return cgc1_clk_get_rate(PLL2);
+               return cgc_clk_get_rate(PLL2);
        default:
                return 0;
        }
@@ -376,16 +376,40 @@ int do_mx8ulp_showclocks(struct cmd_tbl *cmdtp, int flag, int argc, char * const
        printf("SDHC1 %8d MHz\n", pcc_clock_get_rate(4, SDHC1_PCC4_SLOT) / 1000000);
        printf("SDHC2 %8d MHz\n", pcc_clock_get_rate(4, SDHC2_PCC4_SLOT) / 1000000);
 
-       printf("SOSC %8d MHz\n", cgc1_clk_get_rate(SOSC) / 1000000);
-       printf("FRO %8d MHz\n", cgc1_clk_get_rate(FRO) / 1000000);
-       printf("PLL2 %8d MHz\n", cgc1_clk_get_rate(PLL2) / 1000000);
-       printf("PLL3 %8d MHz\n", cgc1_clk_get_rate(PLL3) / 1000000);
-       printf("PLL3_VCODIV %8d MHz\n", cgc1_clk_get_rate(PLL3_VCODIV) / 1000000);
-       printf("PLL3_PFD0 %8d MHz\n", cgc1_clk_get_rate(PLL3_PFD0) / 1000000);
-       printf("PLL3_PFD1 %8d MHz\n", cgc1_clk_get_rate(PLL3_PFD1) / 1000000);
-       printf("PLL3_PFD2 %8d MHz\n", cgc1_clk_get_rate(PLL3_PFD2) / 1000000);
-       printf("PLL3_PFD3 %8d MHz\n", cgc1_clk_get_rate(PLL3_PFD3) / 1000000);
-
+       printf("SOSC %8d MHz\n", cgc_clk_get_rate(SOSC) / 1000000);
+       printf("FRO %8d MHz\n", cgc_clk_get_rate(FRO) / 1000000);
+       printf("PLL2 %8d MHz\n", cgc_clk_get_rate(PLL2) / 1000000);
+       printf("PLL3 %8d MHz\n", cgc_clk_get_rate(PLL3) / 1000000);
+       printf("PLL3_VCODIV %8d MHz\n", cgc_clk_get_rate(PLL3_VCODIV) / 1000000);
+       printf("PLL3_PFD0 %8d MHz\n", cgc_clk_get_rate(PLL3_PFD0) / 1000000);
+       printf("PLL3_PFD1 %8d MHz\n", cgc_clk_get_rate(PLL3_PFD1) / 1000000);
+       printf("PLL3_PFD2 %8d MHz\n", cgc_clk_get_rate(PLL3_PFD2) / 1000000);
+       printf("PLL3_PFD3 %8d MHz\n", cgc_clk_get_rate(PLL3_PFD3) / 1000000);
+
+       printf("PLL4_PFD0 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD0) / 1000000);
+       printf("PLL4_PFD1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD1) / 1000000);
+       printf("PLL4_PFD2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD2) / 1000000);
+       printf("PLL4_PFD3 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD3) / 1000000);
+
+       printf("PLL4_PFD0_DIV1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD0_DIV1) / 1000000);
+       printf("PLL4_PFD0_DIV2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD0_DIV2) / 1000000);
+       printf("PLL4_PFD1_DIV1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD1_DIV1) / 1000000);
+       printf("PLL4_PFD1_DIV2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD1_DIV2) / 1000000);
+
+       printf("PLL4_PFD2_DIV1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD2_DIV1) / 1000000);
+       printf("PLL4_PFD2_DIV2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD2_DIV2) / 1000000);
+       printf("PLL4_PFD3_DIV1 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD3_DIV1) / 1000000);
+       printf("PLL4_PFD3_DIV2 %8d MHz\n", cgc_clk_get_rate(PLL4_PFD3_DIV2) / 1000000);
+
+       printf("LPAV_AXICLK %8d MHz\n", cgc_clk_get_rate(LPAV_AXICLK) / 1000000);
+       printf("LPAV_AHBCLK %8d MHz\n", cgc_clk_get_rate(LPAV_AHBCLK) / 1000000);
+       printf("LPAV_BUSCLK %8d MHz\n", cgc_clk_get_rate(LPAV_BUSCLK) / 1000000);
+       printf("NIC_APCLK %8d MHz\n", cgc_clk_get_rate(NIC_APCLK) / 1000000);
+
+       printf("NIC_PERCLK %8d MHz\n", cgc_clk_get_rate(NIC_PERCLK) / 1000000);
+       printf("XBAR_APCLK %8d MHz\n", cgc_clk_get_rate(XBAR_APCLK) / 1000000);
+       printf("XBAR_BUSCLK %8d MHz\n", cgc_clk_get_rate(XBAR_BUSCLK) / 1000000);
+       printf("AD_SLOWCLK %8d MHz\n", cgc_clk_get_rate(AD_SLOWCLK) / 1000000);
        return 0;
 }
 
index 711b685..6145b3e 100644 (file)
 #include <asm/arch/cgc.h>
 #include <asm/arch/sys_proto.h>
 
-#define cgc1_clk_TYPES 2
-#define cgc1_clk_NUM 8
+#define cgc_clk_TYPES 2
+#define cgc_clk_NUM 8
 
-static enum cgc1_clk pcc3_clksrc[][8] = {
+static enum cgc_clk pcc3_clksrc[][8] = {
        {
        },
        {       DUMMY0_CLK,
@@ -29,7 +29,7 @@ static enum cgc1_clk pcc3_clksrc[][8] = {
        }
 };
 
-static enum cgc1_clk pcc4_clksrc[][8] = {
+static enum cgc_clk pcc4_clksrc[][8] = {
        {
                DUMMY0_CLK,
                SOSC_DIV1,
@@ -52,6 +52,29 @@ static enum cgc1_clk pcc4_clksrc[][8] = {
        }
 };
 
+static enum cgc_clk pcc5_clksrc[][8] = {
+       {
+               DUMMY0_CLK,
+               PLL4_PFD3_DIV2,
+               PLL4_PFD2_DIV2,
+               PLL4_PFD2_DIV1,
+               PLL4_PFD1_DIV2,
+               PLL4_PFD1_DIV1,
+               PLL4_PFD0_DIV2,
+               PLL4_PFD0_DIV1
+       },
+       {
+               DUMMY0_CLK,
+               DUMMY1_CLK,
+               LPOSC,
+               SOSC_DIV2,
+               FRO_DIV2,
+               LPAV_BUSCLK,
+               PLL4_VCODIV,
+               PLL4_PFD3_DIV1
+       }
+};
+
 static struct pcc_entry pcc3_arrays[] = {
        {PCC3_RBASE, DMA1_MP_PCC3_SLOT,         CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B},
        {PCC3_RBASE, DMA1_CH0_PCC3_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B},
@@ -136,6 +159,69 @@ static struct pcc_entry pcc4_arrays[] = {
        {}
 };
 
+static struct pcc_entry pcc5_arrays[] = {
+       {PCC5_RBASE, DMA2_MP_PCC5_SLOT,         CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH0_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH1_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH2_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH3_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH4_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH5_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH6_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH7_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH8_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH9_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH10_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH11_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH12_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH13_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH14_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH15_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH16_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH17_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH18_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH19_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH20_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH21_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH22_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH23_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH24_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH25_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH26_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH27_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH28_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH29_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH30_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, DMA2_CH31_PCC5_SLOT,       CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, MU2_B_PCC5_SLOT,           CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, MU3_B_PCC5_SLOT,           CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, SEMA42_2_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, CMC2_PCC5_SLOT,            CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, AVD_SIM_PCC5_SLOT,         CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, LPAV_CGC_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, PCC5_PCC5_SLOT,            CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, TPM8_PCC5_SLOT,            CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, SAI6_PCC5_SLOT,            CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, SAI7_PCC5_SLOT,            CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, SPDIF_PCC5_SLOT,           CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, ISI_PCC5_SLOT,             CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, CSI_REGS_PCC5_SLOT,        CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, CSI_PCC5_SLOT,             CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, DSI_PCC5_SLOT,             CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, WDOG5_PCC5_SLOT,           CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, EPDC_PCC5_SLOT,            CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, PXP_PCC5_SLOT,             CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, SFA2_PCC5_SLOT,            CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, GPU2D_PCC5_SLOT,           CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, GPU3D_PCC5_SLOT,           CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, DCNANO_PCC5_SLOT,          CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, LPDDR4_PCC5_SLOT,          CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B },
+       {PCC5_RBASE, CSI_CLK_UI_PCC5_SLOT,      CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, CSI_CLK_ESC_PCC5_SLOT,     CLKSRC_PER_PLAT, PCC_HAS_DIV, PCC_NO_RST_B },
+       {PCC5_RBASE, RGPIOD_PCC5_SLOT,          CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B },
+       {}
+};
+
 static int find_pcc_entry(int pcc_controller, int pcc_clk_slot, struct pcc_entry **out)
 {
        struct pcc_entry *pcc_array;
@@ -150,6 +236,10 @@ static int find_pcc_entry(int pcc_controller, int pcc_clk_slot, struct pcc_entry
                pcc_array = pcc4_arrays;
                *out = &pcc4_arrays[0];
                break;
+       case 5:
+               pcc_array = pcc5_arrays;
+               *out = &pcc5_arrays[0];
+               break;
        default:
                printf("Not supported pcc_controller: %d\n", pcc_controller);
                return -EINVAL;
@@ -199,12 +289,12 @@ int pcc_clock_enable(int pcc_controller, int pcc_clk_slot, bool enable)
 }
 
 /* The clock source select needs clock is disabled */
-int pcc_clock_sel(int pcc_controller, int pcc_clk_slot, enum cgc1_clk src)
+int pcc_clock_sel(int pcc_controller, int pcc_clk_slot, enum cgc_clk src)
 {
        u32 val, i, clksrc_type;
        void __iomem *reg;
        struct pcc_entry *pcc_array;
-       enum cgc1_clk *cgc1_clk_array;
+       enum cgc_clk *cgc_clk_array;
        int clk;
 
        clk = find_pcc_entry(pcc_controller, pcc_clk_slot, &pcc_array);
@@ -221,18 +311,20 @@ int pcc_clock_sel(int pcc_controller, int pcc_clk_slot, enum cgc1_clk src)
        }
 
        if (pcc_controller == 3)
-               cgc1_clk_array = pcc3_clksrc[clksrc_type];
+               cgc_clk_array = pcc3_clksrc[clksrc_type];
+       else if (pcc_controller == 4)
+               cgc_clk_array = pcc4_clksrc[clksrc_type];
        else
-               cgc1_clk_array = pcc4_clksrc[clksrc_type];
+               cgc_clk_array = pcc5_clksrc[clksrc_type];
 
-       for (i = 0; i < cgc1_clk_NUM; i++) {
-               if (cgc1_clk_array[i] == src) {
+       for (i = 0; i < cgc_clk_NUM; i++) {
+               if (cgc_clk_array[i] == src) {
                        /* Find the clock src, then set it to PCS */
                        break;
                }
        }
 
-       if (i == cgc1_clk_NUM) {
+       if (i == cgc_clk_NUM) {
                printf("No parent in PCS of PCC %d, invalid scg_clk %d\n", clk, src);
                return -EINVAL;
        }
@@ -320,13 +412,13 @@ bool pcc_clock_is_enable(int pcc_controller, int pcc_clk_slot)
        return false;
 }
 
-int pcc_clock_get_clksrc(int pcc_controller, int pcc_clk_slot, enum cgc1_clk *src)
+int pcc_clock_get_clksrc(int pcc_controller, int pcc_clk_slot, enum cgc_clk *src)
 {
        u32 val, clksrc_type;
        void __iomem *reg;
        struct pcc_entry *pcc_array;
        int clk;
-       enum cgc1_clk *cgc1_clk_array;
+       enum cgc_clk *cgc_clk_array;
 
        clk = find_pcc_entry(pcc_controller, pcc_clk_slot, &pcc_array);
        if (clk < 0)
@@ -360,11 +452,13 @@ int pcc_clock_get_clksrc(int pcc_controller, int pcc_clk_slot, enum cgc1_clk *sr
        }
 
        if (pcc_controller == 3)
-               cgc1_clk_array = pcc3_clksrc[clksrc_type];
+               cgc_clk_array = pcc3_clksrc[clksrc_type];
+       else if (pcc_controller == 4)
+               cgc_clk_array = pcc4_clksrc[clksrc_type];
        else
-               cgc1_clk_array = pcc4_clksrc[clksrc_type];
+               cgc_clk_array = pcc5_clksrc[clksrc_type];
 
-       *src = cgc1_clk_array[val];
+       *src = cgc_clk_array[val];
 
        debug("%s: parent cgc1 clk %d\n", __func__, *src);
 
@@ -412,7 +506,7 @@ u32 pcc_clock_get_rate(int pcc_controller, int pcc_clk_slot)
 {
        u32 val, rate, frac, div;
        void __iomem *reg;
-       enum cgc1_clk parent;
+       enum cgc_clk parent;
        int ret;
        int clk;
        struct pcc_entry *pcc_array;
@@ -425,7 +519,7 @@ u32 pcc_clock_get_rate(int pcc_controller, int pcc_clk_slot)
        if (ret)
                return 0;
 
-       rate = cgc1_clk_get_rate(parent);
+       rate = cgc_clk_get_rate(parent);
 
        debug("%s: parent rate %u\n", __func__, rate);