[PATCH] clk: zynqmp: Fix clk dump values

Michal Simek monstr at monstr.eu
Tue Mar 30 09:23:40 CEST 2021


pá 26. 2. 2021 v 11:53 odesílatel Michal Simek <michal.simek at xilinx.com> napsal:
>
> From: T Karthik Reddy <t.karthik.reddy at xilinx.com>
>
> With "clk dump" command, few clocks are showing up incorrect values
> and some clocks are displayed as "unknown".
>
> Add missing clocks to zynqmp clock driver to display proper
> clocks rates.
>
> Implement a simple way to get clock source, instead of calling
> functions. Change existing functions to this simple mechanism.
>
> Fix gem clock name "gem_rx" to "gem_tx" which was incorrect.
> Change dbf_fpd & dbf_lpd clk names to dbg_fpd & dbg_lpd.
>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> Signed-off-by: T Karthik Reddy <t.karthik.reddy at xilinx.com>
> ---
>
>  drivers/clk/clk_zynqmp.c | 251 ++++++++++++++++++++++++++-------------
>  1 file changed, 170 insertions(+), 81 deletions(-)
>
> diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c
> index 609d8e3b2fff..13a623fdb96a 100644
> --- a/drivers/clk/clk_zynqmp.c
> +++ b/drivers/clk/clk_zynqmp.c
> @@ -97,8 +97,7 @@ static const resource_size_t zynqmp_crl_apb_clkc_base = 0xff5e0020;
>  #define CLK_CTRL_DIV1_MASK     (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT)
>  #define CLK_CTRL_DIV0_SHIFT    8
>  #define CLK_CTRL_DIV0_MASK     (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT)
> -#define CLK_CTRL_SRCSEL_SHIFT  0
> -#define CLK_CTRL_SRCSEL_MASK   (0x3 << CLK_CTRL_SRCSEL_SHIFT)
> +#define CLK_CTRL_SRCSEL_MASK   0x7
>  #define PLLCTRL_FBDIV_MASK     0x7f00
>  #define PLLCTRL_FBDIV_SHIFT    8
>  #define PLLCTRL_RESET_MASK     1
> @@ -132,7 +131,7 @@ enum zynqmp_clk {
>         iou_switch,
>         gem_tsu_ref, gem_tsu,
>         gem0_ref, gem1_ref, gem2_ref, gem3_ref,
> -       gem0_rx, gem1_rx, gem2_rx, gem3_rx,
> +       gem0_tx, gem1_tx, gem2_tx, gem3_tx,
>         qspi_ref,
>         sdio0_ref, sdio1_ref,
>         uart0_ref, uart1_ref,
> @@ -152,7 +151,7 @@ static const char * const clk_names[clk_max] = {
>         "iopll", "rpll", "apll", "dpll",
>         "vpll", "iopll_to_fpd", "rpll_to_fpd",
>         "apll_to_lpd", "dpll_to_lpd", "vpll_to_lpd",
> -       "acpu", "acpu_half", "dbf_fpd", "dbf_lpd",
> +       "acpu", "acpu_half", "dbg_fpd", "dbg_lpd",
>         "dbg_trace", "dbg_tstmp", "dp_video_ref",
>         "dp_audio_ref", "dp_stc_ref", "gdma_ref",
>         "dpdma_ref", "ddr_ref", "sata_ref", "pcie_ref",
> @@ -172,6 +171,38 @@ static const char * const clk_names[clk_max] = {
>         "ams_ref", "pl0", "pl1", "pl2", "pl3", "wdt"
>  };
>
> +static const u32 pll_src[][4] = {
> +       {apll, 0xff, dpll, vpll},               /* acpu */
> +       {dpll, vpll, 0xff, 0xff},               /* ddr_ref */
> +       {rpll, iopll, 0xff, 0xff},              /* dll_ref */
> +       {iopll, 0xff, rpll, dpll_to_lpd},       /* gem_tsu_ref */
> +       {iopll, 0xff, rpll, dpll},              /* peripheral */
> +       {apll, 0xff, iopll_to_fpd, dpll},       /* wdt */
> +       {iopll_to_fpd, 0xff, dpll, apll},       /* dbg_fpd */
> +       {iopll, 0xff, rpll, dpll_to_lpd},       /* timestamp_ref */
> +       {iopll_to_fpd, 0xff, apll, dpll},       /* sata_ref */
> +       {iopll_to_fpd, 0xff, rpll_to_fpd, dpll},/* pcie_ref */
> +       {iopll_to_fpd, 0xff, vpll, dpll},       /* gpu_ref */
> +       {apll, 0xff, vpll, dpll},               /* topsw_main_ref */
> +       {rpll, 0xff, iopll, dpll_to_lpd},       /* cpu_r5_ref */
> +};
> +
> +enum zynqmp_clk_pll_src {
> +       ACPU_CLK_SRC = 0,
> +       DDR_CLK_SRC,
> +       DLL_CLK_SRC,
> +       GEM_TSU_CLK_SRC,
> +       PERI_CLK_SRC,
> +       WDT_CLK_SRC,
> +       DBG_FPD_CLK_SRC,
> +       TIMESTAMP_CLK_SRC,
> +       SATA_CLK_SRC,
> +       PCIE_CLK_SRC,
> +       GPU_CLK_SRC,
> +       TOPSW_MAIN_CLK_SRC,
> +       CPU_R5_CLK_SRC
> +};
> +
>  struct zynqmp_clk_priv {
>         unsigned long ps_clk_freq;
>         unsigned long video_clk;
> @@ -195,12 +226,38 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id)
>                 return CRF_APB_VPLL_CTRL;
>         case acpu:
>                 return CRF_APB_ACPU_CTRL;
> +       case dbg_fpd:
> +               return CRF_APB_DBG_FPD_CTRL;
> +       case dbg_trace:
> +               return CRF_APB_DBG_TRACE_CTRL;
> +       case dbg_tstmp:
> +               return CRF_APB_DBG_TSTMP_CTRL;
> +       case gpu_ref ...  gpu_pp1_ref:
> +               return CRF_APB_GPU_REF_CTRL;
>         case ddr_ref:
>                 return CRF_APB_DDR_CTRL;
> +       case sata_ref:
> +               return CRF_APB_SATA_REF_CTRL;
> +       case pcie_ref:
> +               return CRF_APB_PCIE_REF_CTRL;
> +       case gdma_ref:
> +               return CRF_APB_GDMA_REF_CTRL;
> +       case dpdma_ref:
> +               return CRF_APB_DPDMA_REF_CTRL;
> +       case topsw_main:
> +               return CRF_APB_TOPSW_MAIN_CTRL;
> +       case topsw_lsbus:
> +               return CRF_APB_TOPSW_LSBUS_CTRL;
> +       case lpd_switch:
> +               return CRL_APB_LPD_SWITCH_CTRL;
> +       case lpd_lsbus:
> +               return CRL_APB_LPD_LSBUS_CTRL;
>         case qspi_ref:
>                 return CRL_APB_QSPI_REF_CTRL;
>         case usb3_dual_ref:
>                 return CRL_APB_USB3_DUAL_REF_CTRL;
> +       case gem_tsu_ref:
> +               return CRL_APB_GEM_TSU_REF_CTRL;
>         case gem0_ref:
>                 return CRL_APB_GEM0_REF_CTRL;
>         case gem1_ref:
> @@ -213,6 +270,8 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id)
>                 return CRL_APB_USB0_BUS_REF_CTRL;
>         case usb1_bus_ref:
>                 return CRL_APB_USB1_BUS_REF_CTRL;
> +       case cpu_r5:
> +               return CRL_APB_CPU_R5_CTRL;
>         case uart0_ref:
>                 return CRL_APB_UART0_REF_CTRL;
>         case uart1_ref:
> @@ -235,6 +294,14 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id)
>                 return CRL_APB_CAN0_REF_CTRL;
>         case can1_ref:
>                 return CRL_APB_CAN1_REF_CTRL;
> +       case dll_ref:
> +               return CRL_APB_DLL_REF_CTRL;
> +       case adma_ref:
> +               return CRL_APB_ADMA_REF_CTRL;
> +       case timestamp_ref:
> +               return CRL_APB_TIMESTAMP_REF_CTRL;
> +       case ams_ref:
> +               return CRL_APB_AMS_REF_CTRL;
>         case pl0:
>                 return CRL_APB_PL0_REF_CTRL;
>         case pl1:
> @@ -253,68 +320,6 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id)
>         return 0;
>  }
>
> -static enum zynqmp_clk zynqmp_clk_get_cpu_pll(u32 clk_ctrl)
> -{
> -       u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >>
> -                     CLK_CTRL_SRCSEL_SHIFT;
> -
> -       switch (srcsel) {
> -       case 2:
> -               return dpll;
> -       case 3:
> -               return vpll;
> -       case 0 ... 1:
> -       default:
> -               return apll;
> -       }
> -}
> -
> -static enum zynqmp_clk zynqmp_clk_get_ddr_pll(u32 clk_ctrl)
> -{
> -       u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >>
> -                     CLK_CTRL_SRCSEL_SHIFT;
> -
> -       switch (srcsel) {
> -       case 1:
> -               return vpll;
> -       case 0:
> -       default:
> -               return dpll;
> -       }
> -}
> -
> -static enum zynqmp_clk zynqmp_clk_get_peripheral_pll(u32 clk_ctrl)
> -{
> -       u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >>
> -                     CLK_CTRL_SRCSEL_SHIFT;
> -
> -       switch (srcsel) {
> -       case 2:
> -               return rpll;
> -       case 3:
> -               return dpll;
> -       case 0 ... 1:
> -       default:
> -               return iopll;
> -       }
> -}
> -
> -static enum zynqmp_clk zynqmp_clk_get_wdt_pll(u32 clk_ctrl)
> -{
> -       u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >>
> -                     CLK_CTRL_SRCSEL_SHIFT;
> -
> -       switch (srcsel) {
> -       case 2:
> -               return iopll_to_fpd;
> -       case 3:
> -               return dpll;
> -       case 0 ... 1:
> -       default:
> -               return apll;
> -       }
> -}
> -
>  static ulong zynqmp_clk_get_pll_src(ulong clk_ctrl,
>                                     struct zynqmp_clk_priv *priv,
>                                     bool is_pre_src)
> @@ -378,7 +383,7 @@ static ulong zynqmp_clk_get_pll_rate(struct zynqmp_clk_priv *priv,
>  static ulong zynqmp_clk_get_cpu_rate(struct zynqmp_clk_priv *priv,
>                                      enum zynqmp_clk id)
>  {
> -       u32 clk_ctrl, div;
> +       u32 clk_ctrl, div, srcsel;
>         enum zynqmp_clk pll;
>         int ret;
>         unsigned long pllrate;
> @@ -391,7 +396,8 @@ static ulong zynqmp_clk_get_cpu_rate(struct zynqmp_clk_priv *priv,
>
>         div = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
>
> -       pll = zynqmp_clk_get_cpu_pll(clk_ctrl);
> +       srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
> +       pll = pll_src[ACPU_CLK_SRC][srcsel];
>         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
>         if (IS_ERR_VALUE(pllrate))
>                 return pllrate;
> @@ -401,7 +407,7 @@ static ulong zynqmp_clk_get_cpu_rate(struct zynqmp_clk_priv *priv,
>
>  static ulong zynqmp_clk_get_ddr_rate(struct zynqmp_clk_priv *priv)
>  {
> -       u32 clk_ctrl, div;
> +       u32 clk_ctrl, div, srcsel;
>         enum zynqmp_clk pll;
>         int ret;
>         ulong pllrate;
> @@ -414,7 +420,8 @@ static ulong zynqmp_clk_get_ddr_rate(struct zynqmp_clk_priv *priv)
>
>         div = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
>
> -       pll = zynqmp_clk_get_ddr_pll(clk_ctrl);
> +       srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
> +       pll = pll_src[DDR_CLK_SRC][srcsel];
>         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
>         if (IS_ERR_VALUE(pllrate))
>                 return pllrate;
> @@ -422,11 +429,33 @@ static ulong zynqmp_clk_get_ddr_rate(struct zynqmp_clk_priv *priv)
>         return DIV_ROUND_CLOSEST(pllrate, div);
>  }
>
> +static ulong zynqmp_clk_get_dll_rate(struct zynqmp_clk_priv *priv)
> +{
> +       u32 clk_ctrl, srcsel;
> +       enum zynqmp_clk pll;
> +       ulong pllrate;
> +       int ret;
> +
> +       ret = zynqmp_mmio_read(CRL_APB_DLL_REF_CTRL, &clk_ctrl);
> +       if (ret) {
> +               printf("%s mio read fail\n", __func__);
> +               return -EIO;
> +       }
> +
> +       srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
> +       pll = pll_src[DLL_CLK_SRC][srcsel];
> +       pllrate = zynqmp_clk_get_pll_rate(priv, pll);
> +       if (IS_ERR_VALUE(pllrate))
> +               return pllrate;
> +
> +       return pllrate;
> +}
> +
>  static ulong zynqmp_clk_get_peripheral_rate(struct zynqmp_clk_priv *priv,
> -                                         enum zynqmp_clk id, bool two_divs)
> +                                           enum zynqmp_clk id, bool two_divs)
>  {
>         enum zynqmp_clk pll;
> -       u32 clk_ctrl, div0;
> +       u32 clk_ctrl, div0, srcsel;
>         u32 div1 = 1;
>         int ret;
>         ulong pllrate;
> @@ -446,8 +475,13 @@ static ulong zynqmp_clk_get_peripheral_rate(struct zynqmp_clk_priv *priv,
>                 if (!div1)
>                         div1 = 1;
>         }
> +       srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
> +
> +       if (id == gem_tsu_ref)
> +               pll = pll_src[GEM_TSU_CLK_SRC][srcsel];
> +       else
> +               pll = pll_src[PERI_CLK_SRC][srcsel];
>
> -       pll = zynqmp_clk_get_peripheral_pll(clk_ctrl);
>         pllrate = zynqmp_clk_get_pll_rate(priv, pll);
>         if (IS_ERR_VALUE(pllrate))
>                 return pllrate;
> @@ -457,11 +491,11 @@ static ulong zynqmp_clk_get_peripheral_rate(struct zynqmp_clk_priv *priv,
>                         DIV_ROUND_CLOSEST(pllrate, div0), div1);
>  }
>
> -static ulong zynqmp_clk_get_wdt_rate(struct zynqmp_clk_priv *priv,
> -                                    enum zynqmp_clk id, bool two_divs)
> +static ulong zynqmp_clk_get_crf_crl_rate(struct zynqmp_clk_priv *priv,
> +                                        enum zynqmp_clk id, bool two_divs)
>  {
>         enum zynqmp_clk pll;
> -       u32 clk_ctrl, div0;
> +       u32 clk_ctrl, div0, srcsel;
>         u32 div1 = 1;
>         int ret;
>         ulong pllrate;
> @@ -475,8 +509,45 @@ static ulong zynqmp_clk_get_wdt_rate(struct zynqmp_clk_priv *priv,
>         div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
>         if (!div0)
>                 div0 = 1;
> +       srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
>
> -       pll = zynqmp_clk_get_wdt_pll(clk_ctrl);
> +       switch (id) {
> +       case wdt:
> +       case dbg_trace:
> +       case topsw_lsbus:
> +               pll = pll_src[WDT_CLK_SRC][srcsel];
> +               break;
> +       case dbg_fpd:
> +       case dbg_tstmp:
> +               pll = pll_src[DBG_FPD_CLK_SRC][srcsel];
> +               break;
> +       case timestamp_ref:
> +               pll = pll_src[TIMESTAMP_CLK_SRC][srcsel];
> +               break;
> +       case sata_ref:
> +               pll = pll_src[SATA_CLK_SRC][srcsel];
> +               break;
> +       case pcie_ref:
> +               pll = pll_src[PCIE_CLK_SRC][srcsel];
> +               break;
> +       case gpu_ref ... gpu_pp1_ref:
> +               pll = pll_src[GPU_CLK_SRC][srcsel];
> +               break;
> +       case gdma_ref:
> +       case dpdma_ref:
> +       case topsw_main:
> +               pll = pll_src[TOPSW_MAIN_CLK_SRC][srcsel];
> +               break;
> +       case cpu_r5:
> +       case ams_ref:
> +       case adma_ref:
> +       case lpd_lsbus:
> +       case lpd_switch:
> +               pll = pll_src[CPU_R5_CLK_SRC][srcsel];
> +               break;
> +       default:
> +               return -ENXIO;
> +       }
>         if (two_divs) {
>                 ret = zynqmp_mmio_read(zynqmp_clk_get_register(pll), &clk_ctrl);
>                 if (ret) {
> @@ -533,7 +604,7 @@ static ulong zynqmp_clk_set_peripheral_rate(struct zynqmp_clk_priv *priv,
>         enum zynqmp_clk pll;
>         u32 clk_ctrl, div0 = 0, div1 = 0;
>         ulong pll_rate, new_rate;
> -       u32 reg;
> +       u32 reg, srcsel;
>         int ret;
>         u32 mask;
>
> @@ -544,7 +615,8 @@ static ulong zynqmp_clk_set_peripheral_rate(struct zynqmp_clk_priv *priv,
>                 return -EIO;
>         }
>
> -       pll = zynqmp_clk_get_peripheral_pll(clk_ctrl);
> +       srcsel = clk_ctrl & CLK_CTRL_SRCSEL_MASK;
> +       pll = pll_src[PERI_CLK_SRC][srcsel];
>         pll_rate = zynqmp_clk_get_pll_rate(priv, pll);
>         if (IS_ERR_VALUE(pll_rate))
>                 return pll_rate;
> @@ -588,14 +660,31 @@ static ulong zynqmp_clk_get_rate(struct clk *clk)
>                 return zynqmp_clk_get_cpu_rate(priv, id);
>         case ddr_ref:
>                 return zynqmp_clk_get_ddr_rate(priv);
> +       case dll_ref:
> +               return zynqmp_clk_get_dll_rate(priv);
> +       case gem_tsu_ref:
> +       case pl0 ... pl3:
>         case gem0_ref ... gem3_ref:
>         case qspi_ref ... can1_ref:
> -       case pl0 ... pl3:
> +       case usb0_bus_ref ... usb3_dual_ref:
>                 two_divs = true;
>                 return zynqmp_clk_get_peripheral_rate(priv, id, two_divs);
>         case wdt:
> +       case topsw_lsbus:
> +       case sata_ref ... gpu_pp1_ref:
>                 two_divs = true;
> -               return zynqmp_clk_get_wdt_rate(priv, id, two_divs);
> +       case cpu_r5:
> +       case dbg_fpd:
> +       case ams_ref:
> +       case adma_ref:
> +       case lpd_lsbus:
> +       case dbg_trace:
> +       case dbg_tstmp:
> +       case lpd_switch:
> +       case topsw_main:
> +       case timestamp_ref:
> +       case gdma_ref ... dpdma_ref:
> +               return zynqmp_clk_get_crf_crl_rate(priv, id, two_divs);
>         default:
>                 return -ENXIO;
>         }
> --
> 2.30.0
>

Applied.
M

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


More information about the U-Boot mailing list