Hi Peng, > Hi All, > > > Subject: [PATCH v2 3/7] clk: imx8: Update imx8 clock driver > > Sorry to bring back this topic. > > This patch is not converting to CCF following Linux, but it could > satisfy u-boot usage and make more feature work. > > I checked Linux i.MX8 CCF recently, although Linux upstream has i.MX8 > CCF support, but NXP downstream has significantly reimplement the > code. So we could not take code directly from Linux upstream, because > this would introduce efforts in U-Boot after NXP downstream clk code > upstreamed. > > I have also tried to converting to use NXP downstream Linux ccf code > in u-boot, but there is an issue is some clks are root clks, no > parents. However u-boot ccf always requires a parent for a clk. > Anyway there is still long time to upstream nxp Linux downstream clk > code to Linux. > > I would hear your voice about U-Boot part. Proceed with current patch > or promoting CCF with NXP downstream clk?
It depends. One reason for using Linux clocks (backported from Linux) is that there is a chance that this code would be maintained for a long time and hence subsequent updates from Linux would have the chance to work. With NXP downstream code - it may happen that we will end up with some in-mainline version not being in sync with Linux and with future NXP internal BSP releases. My standpoint is as follows - if you feel like there is a pretty high chance that NXP downstream clk code will be accepted to Linux _soon_, then I don't mind to have it in U-Boot. This is all the matter of active maintenance of the CLK code ... > > Thanks, > Peng. > > > > > Update imx8 clock driver to support LPCG and full clocks tree for > > some modules aligned with kernel. > > > > We classify the clock into serveral types: slice, fixed, lpcg, gpr > > and mux. Generally slice and fixed clocks are the sources. lpcg, > > gpr and mux are the downstream of those sources and are used for > > gating, muxing or dividing functions. > > > > This patch replaces the functions defined in imx8qm and imx8qxp > > with the clock > > tables of different clock types. clk-imx8 use unified functions to > > process these clock tables. > > > > Note: since the clock depends on the power domain of its resource, > > must power > > on the resource firstly, then we can get the clock. Otherwise, we > > can't access lpcg. > > Thus, the clock dump only works for the slice clock. > > > > Signed-off-by: Ye Li <ye...@nxp.com> > > --- > > Changes in v2: > > - None > > > > drivers/clk/imx/clk-imx8.c | 304 +++++++++++++++++++++++++-- > > drivers/clk/imx/clk-imx8.h | 83 +++++++- > > drivers/clk/imx/clk-imx8qm.c | 479 > > ++++++++++++++++-------------------------- > > drivers/clk/imx/clk-imx8qxp.c | 432 > > +++++++++++++------------------------ 4 files changed, 689 > > insertions(+), 609 deletions(-) > > > > diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c > > index a755e26..afdb6ea 100644 > > --- a/drivers/clk/imx/clk-imx8.c > > +++ b/drivers/clk/imx/clk-imx8.c > > @@ -12,32 +12,294 @@ > > #include <dt-bindings/clock/imx8qxp-clock.h> > > #include <dt-bindings/soc/imx_rsrc.h> > > #include <misc.h> > > +#include <asm/arch/lpcg.h> > > > > #include "clk-imx8.h" > > > > -__weak ulong imx8_clk_get_rate(struct clk *clk) > > +struct imx8_clks_collect *soc_data[] = { > > +#ifdef CONFIG_IMX8QXP > > + &imx8qxp_clk_collect, > > +#endif > > +#ifdef CONFIG_IMX8QM > > + &imx8qm_clk_collect, > > +#endif > > +}; > > + > > +static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id); > > +static int __imx8_clk_enable(struct udevice *dev, ulong id, bool > > enable); +static ulong __imx8_clk_set_rate(struct udevice *dev, > > ulong id, unsigned long rate); > > + > > +static struct imx8_clks_collect * find_clks_collect(struct udevice > > *dev) +{ > > + ulong data = (ulong)dev_get_driver_data(dev); > > + int i; > > + > > + for (i = 0; i < ARRAY_SIZE(soc_data); i++) { > > + if (soc_data[i]->match_flag == data) > > + return soc_data[i]; > > + } > > + > > + return NULL; > > +} > > + > > +static void * check_imx8_clk(struct udevice *dev, enum > > imx8_clk_type type, ulong id, u32 size_of_clk) > > +{ > > + u32 i, size; > > + struct imx8_clks_collect *clks_col = > > find_clks_collect(dev); > > + struct imx8_clk_header *hdr; > > + ulong clks; > > + > > + if (!clks_col || !(clks_col->clks[type].type_clks)) { > > + printf("%s fails to get clks for type %d\n", > > + __func__, type); > > + return NULL; > > + } > > + > > + clks = (ulong)(clks_col->clks[type].type_clks); > > + size = clks_col->clks[type].num; > > + > > + for (i = 0; i < size; i++) { > > + hdr = (struct imx8_clk_header *)clks; > > + if (id == hdr->id) > > + return (void *)hdr; > > + > > + clks += size_of_clk; > > + } > > + > > + return NULL; > > +} > > + > > +static ulong imx8_get_rate_lpcg(struct udevice *dev, struct > > imx8_lpcg_clks *lpcg_clk) > > +{ > > + if (lpcg_clk->parent_id != 0) { > > + if (lpcg_is_clock_on(lpcg_clk->lpcg, > > lpcg_clk->bit_idx >> 2)) { > > + return __imx8_clk_get_rate(dev, > > lpcg_clk->parent_id); > > + } else { > > + return 0; > > + } > > + } else { > > + return -ENOSYS; > > + } > > +} > > + > > +static ulong imx8_get_rate_slice(struct udevice *dev, struct > > imx8_clks *slice_clk) > > +{ > > + int ret; > > + u32 rate; > > + > > + ret = sc_pm_get_clock_rate(-1, slice_clk->rsrc, > > slice_clk->pm_clk, > > + (sc_pm_clock_rate_t *)&rate); > > + if (ret) { > > + printf("%s err %d\n", __func__, ret); > > + return ret; > > + } > > + > > + return rate; > > +} > > + > > +static ulong imx8_get_rate_fixed(struct udevice *dev, struct > > imx8_fixed_clks *fixed_clk) > > +{ > > + return fixed_clk->rate; > > +} > > + > > +static ulong __imx8_clk_get_rate(struct udevice *dev, ulong id) > > +{ > > + void* clkdata; > > + > > + clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id, > > sizeof(struct imx8_lpcg_clks)); > > + if (clkdata) { > > + return imx8_get_rate_lpcg(dev, (struct > > imx8_lpcg_clks *)clkdata); > > + } > > + > > + clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id, > > sizeof(struct imx8_clks)); > > + if (clkdata) { > > + return imx8_get_rate_slice(dev, (struct imx8_clks > > *)clkdata); > > + } > > + > > + clkdata = check_imx8_clk(dev, IMX8_CLK_FIXED, id, > > sizeof(struct imx8_fixed_clks)); > > + if (clkdata) { > > + return imx8_get_rate_fixed(dev, (struct > > imx8_fixed_clks *)clkdata); > > + } > > + > > + return -ENOSYS; > > +} > > + > > +static ulong imx8_clk_get_rate(struct clk *clk) > > +{ > > + return __imx8_clk_get_rate(clk->dev, clk->id); > > +} > > + > > +static ulong imx8_set_rate_lpcg(struct udevice *dev, struct > > imx8_lpcg_clks *lpcg_clk, unsigned long rate) > > +{ > > + if (lpcg_clk->parent_id != 0) { > > + return __imx8_clk_set_rate(dev, > > lpcg_clk->parent_id, rate); > > + } else { > > + return -ENOSYS; > > + } > > +} > > + > > +static ulong imx8_set_rate_slice(struct udevice *dev, struct > > imx8_clks *slice_clk, unsigned long rate) > > +{ > > + int ret; > > + u32 new_rate = rate; > > + > > + ret = sc_pm_set_clock_rate(-1, slice_clk->rsrc, > > slice_clk->pm_clk, &new_rate); > > + if (ret) { > > + printf("%s err %d\n", __func__, ret); > > + return ret; > > + } > > + > > + return new_rate; > > +} > > + > > +static ulong imx8_set_rate_gpr(struct udevice *dev, struct > > imx8_gpr_clks *gpr_clk, unsigned long rate) > > { > > + ulong parent_rate; > > + u32 val; > > + int ret; > > + > > + if (gpr_clk->parent_id == 0) > > + return -ENOSYS; > > + > > + parent_rate = __imx8_clk_get_rate(dev, gpr_clk->parent_id); > > + if (parent_rate > 0) { > > + val = (rate < parent_rate) ? 1 : 0; > > + > > + ret = sc_misc_set_control(-1, gpr_clk->rsrc, > > + gpr_clk->gpr_id, val); > > + if (ret) { > > + printf("%s err %d\n", __func__, ret); > > + return ret; > > + } > > + > > + return rate; > > + } > > + > > + return -ENOSYS; > > +} > > + > > +static ulong __imx8_clk_set_rate(struct udevice *dev, ulong id, > > unsigned long rate) > > +{ > > + void* clkdata; > > + > > + clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id, > > sizeof(struct imx8_clks)); > > + if (clkdata) { > > + return imx8_set_rate_slice(dev, (struct imx8_clks > > *)clkdata, rate); > > + } > > + > > + clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id, > > sizeof(struct imx8_lpcg_clks)); > > + if (clkdata) { > > + return imx8_set_rate_lpcg(dev, (struct > > imx8_lpcg_clks *)clkdata, rate); > > + } > > + > > + clkdata = check_imx8_clk(dev, IMX8_CLK_GPR, id, > > sizeof(struct imx8_gpr_clks)); > > + if (clkdata) { > > + return imx8_set_rate_gpr(dev, (struct > > imx8_gpr_clks *)clkdata, rate); > > + } > > + > > + return -ENOSYS; > > +} > > + > > +static ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate) > > +{ > > + return __imx8_clk_set_rate(clk->dev, clk->id, rate); > > + > > +} > > + > > +static int imx8_enable_slice(struct udevice *dev, struct imx8_clks > > *slice_clk, bool enable) > > +{ > > + int ret; > > + > > + ret = sc_pm_clock_enable(-1, slice_clk->rsrc, > > slice_clk->pm_clk, enable, 0); > > + if (ret) { > > + printf("%s err %d\n", __func__, ret); > > + return ret; > > + } > > + > > return 0; > > } > > > > -__weak ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate) > > +static int imx8_enable_lpcg(struct udevice *dev, struct > > imx8_lpcg_clks *lpcg_clk, bool enable) > > { > > + if (enable) { > > + if (lpcg_clk->parent_id != 0) { > > + __imx8_clk_enable(dev, > > lpcg_clk->parent_id, enable); > > + } > > + > > + lpcg_clock_on(lpcg_clk->lpcg, lpcg_clk->bit_idx >> > > 2); > > + } else { > > + lpcg_clock_off(lpcg_clk->lpcg, lpcg_clk->bit_idx > > >> 2); + > > + if (lpcg_clk->parent_id != 0) { > > + __imx8_clk_enable(dev, > > lpcg_clk->parent_id, enable); > > + } > > + } > > + > > return 0; > > } > > > > -__weak int __imx8_clk_enable(struct clk *clk, bool enable) > > +static int __imx8_clk_enable(struct udevice *dev, ulong id, bool > > enable) { > > - return -ENOTSUPP; > > + void* clkdata; > > + > > + clkdata = check_imx8_clk(dev, IMX8_CLK_LPCG, id, > > sizeof(struct imx8_lpcg_clks)); > > + if (clkdata) { > > + return imx8_enable_lpcg(dev, (struct > > imx8_lpcg_clks *)clkdata, enable); > > + } > > + > > + clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, id, > > sizeof(struct imx8_clks)); > > + if (clkdata) { > > + return imx8_enable_slice(dev, (struct imx8_clks > > *)clkdata, enable); > > + } > > + > > + return -ENOSYS; > > } > > > > static int imx8_clk_disable(struct clk *clk) > > { > > - return __imx8_clk_enable(clk, 0); > > + return __imx8_clk_enable(clk->dev, clk->id, 0); > > } > > > > static int imx8_clk_enable(struct clk *clk) > > { > > - return __imx8_clk_enable(clk, 1); > > + return __imx8_clk_enable(clk->dev, clk->id, 1); > > +} > > + > > +static int imx8_set_parent_mux(struct udevice *dev, struct > > imx8_mux_clks *mux_clk, ulong pid) > > +{ > > + u32 i; > > + int ret; > > + struct imx8_clks *slice_clkdata; > > + > > + slice_clkdata = check_imx8_clk(dev, IMX8_CLK_SLICE, > > mux_clk->slice_clk_id, sizeof(struct imx8_clks)); > > + if (!slice_clkdata) { > > + printf("Error: fail to find slice clk %lu for this > > mux %lu\n", mux_clk->slice_clk_id, mux_clk->hdr.id); > > + return -EINVAL; > > + } > > + > > + for (i = 0; i< CLK_IMX8_MAX_MUX_SEL; i++) { > > + if (pid == mux_clk->parent_clks[i]) { > > + ret = sc_pm_set_clock_parent(-1, > > slice_clkdata->rsrc, slice_clkdata->pm_clk, i); > > + if (ret) > > + printf("Error: fail to set clock > > parent rsrc %d, pm_clk %d, parent clk %d\n", > > + slice_clkdata->rsrc, > > slice_clkdata->pm_clk, i); > > + return ret; > > + } > > + } > > + > > + return -ENOSYS; > > +} > > + > > +static int imx8_clk_set_parent(struct clk *clk, struct clk *parent) > > +{ > > + void* clkdata; > > + > > + clkdata = check_imx8_clk(clk->dev, IMX8_CLK_MUX, clk->id, > > sizeof(struct imx8_mux_clks)); > > + if (clkdata) { > > + return imx8_set_parent_mux(clk->dev, (struct > > imx8_mux_clks *)clkdata, parent->id); > > + } > > + > > + return -ENOSYS; > > } > > > > #if CONFIG_IS_ENABLED(CMD_CLK) > > @@ -47,6 +309,9 @@ int soc_clk_dump(void) > > struct clk clk; > > unsigned long rate; > > int i, ret; > > + u32 size; > > + struct imx8_clks *clks; > > + struct imx8_clks_collect *clks_col; > > > > ret = uclass_get_device_by_driver(UCLASS_CLK, > > DM_GET_DRIVER(imx8_clk), > > &dev); @@ -55,8 +320,19 @@ int soc_clk_dump(void) > > > > printf("Clk\t\tHz\n"); > > > > - for (i = 0; i < num_clks; i++) { > > - clk.id = imx8_clk_names[i].id; > > + clks_col = find_clks_collect(dev); > > + > > + if (!clks_col || > > !(clks_col->clks[IMX8_CLK_SLICE].type_clks)) { > > + printf("%s fails to get clks for type %d\n", > > + __func__, IMX8_CLK_SLICE); > > + return -ENODEV; > > + } > > + > > + clks = (struct imx8_clks > > *)(clks_col->clks[IMX8_CLK_SLICE].type_clks); > > + size = clks_col->clks[IMX8_CLK_SLICE].num; > > + > > + for (i = 0; i < size; i++) { > > + clk.id = clks[i].hdr.id; > > ret = clk_request(dev, &clk); > > if (ret < 0) { > > debug("%s clk_request() failed: %d\n", > > __func__, ret); @@ -70,21 +346,22 @@ int soc_clk_dump(void) > > > > if (ret == -ENOTSUPP) { > > printf("clk ID %lu not supported yet\n", > > - imx8_clk_names[i].id); > > + clks[i].hdr.id); > > continue; > > } > > if (ret < 0) { > > printf("%s %lu: get_rate err: %d\n", > > - __func__, imx8_clk_names[i].id, > > ret); > > + __func__, clks[i].hdr.id, ret); > > continue; > > } > > > > printf("%s(%3lu):\t%lu\n", > > - imx8_clk_names[i].name, > > imx8_clk_names[i].id, rate); > > + clks[i].hdr.name, clks[i].hdr.id, rate); > > } > > > > return 0; > > } > > + > > #endif > > > > static struct clk_ops imx8_clk_ops = { > > @@ -92,6 +369,7 @@ static struct clk_ops imx8_clk_ops = { > > .get_rate = imx8_clk_get_rate, > > .enable = imx8_clk_enable, > > .disable = imx8_clk_disable, > > + .set_parent = imx8_clk_set_parent, > > }; > > > > static int imx8_clk_probe(struct udevice *dev) > > @@ -100,8 +378,8 @@ static int imx8_clk_probe(struct udevice *dev) > > } > > > > static const struct udevice_id imx8_clk_ids[] = { > > - { .compatible = "fsl,imx8qxp-clk" }, > > - { .compatible = "fsl,imx8qm-clk" }, > > + { .compatible = "fsl,imx8qxp-clk", .data = > > FLAG_CLK_IMX8_IMX8QXP, }, > > + { .compatible = "fsl,imx8qm-clk", .data = > > FLAG_CLK_IMX8_IMX8QM, }, { }, > > }; > > > > diff --git a/drivers/clk/imx/clk-imx8.h b/drivers/clk/imx/clk-imx8.h > > index 68ad675..c0566f8 100644 > > --- a/drivers/clk/imx/clk-imx8.h > > +++ b/drivers/clk/imx/clk-imx8.h > > @@ -4,16 +4,87 @@ > > * Peng Fan <peng....@nxp.com> > > */ > > > > -struct imx8_clks { > > +#define CLK_IMX8_MAX_MUX_SEL 5 > > + > > +#define FLAG_CLK_IMX8_IMX8QM BIT(0) > > +#define FLAG_CLK_IMX8_IMX8QXP BIT(1) > > + > > +struct imx8_clk_header { > > ulong id; > > +#if CONFIG_IS_ENABLED(CMD_CLK) > > const char *name; > > +#endif > > +}; > > + > > +struct imx8_clks { > > + struct imx8_clk_header hdr; > > + u16 rsrc; > > + sc_pm_clk_t pm_clk; > > +}; > > + > > +struct imx8_fixed_clks { > > + struct imx8_clk_header hdr; > > + ulong rate; > > +}; > > + > > +struct imx8_gpr_clks { > > + struct imx8_clk_header hdr; > > + u16 rsrc; > > + sc_ctrl_t gpr_id; > > + ulong parent_id; > > +}; > > + > > +struct imx8_lpcg_clks { > > + struct imx8_clk_header hdr; > > + u8 bit_idx; > > + u32 lpcg; > > + ulong parent_id; > > +}; > > + > > +struct imx8_mux_clks { > > + struct imx8_clk_header hdr; > > + ulong slice_clk_id; > > + ulong parent_clks[CLK_IMX8_MAX_MUX_SEL]; > > +}; > > + > > +enum imx8_clk_type { > > + IMX8_CLK_SLICE = 0, > > + IMX8_CLK_FIXED = 1, > > + IMX8_CLK_GPR = 2, > > + IMX8_CLK_LPCG = 3, > > + IMX8_CLK_MUX = 4, > > + IMX8_CLK_END = 5, > > +}; > > + > > +struct imx8_clk_pair { > > + void *type_clks; > > + u32 num; > > +}; > > + > > +struct imx8_clks_collect { > > + struct imx8_clk_pair clks[IMX8_CLK_END]; > > + ulong match_flag; > > }; > > > > #if CONFIG_IS_ENABLED(CMD_CLK) > > -extern struct imx8_clks imx8_clk_names[]; > > -extern int num_clks; > > +#define CLK_3(ID, NAME, MEM2) \ > > + { { ID, NAME, }, MEM2, } > > +#define CLK_4(ID, NAME, MEM2, MEM3) \ > > + { { ID, NAME, }, MEM2, MEM3, } > > +#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \ > > + { { ID, NAME, }, MEM2, MEM3, MEM4, } > > +#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \ > > + { { ID, NAME, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} } > > +#else > > +#define CLK_3(ID, NAME, MEM2) \ > > + { { ID, }, MEM2, } > > +#define CLK_4(ID, NAME, MEM2, MEM3) \ > > + { { ID, }, MEM2, MEM3, } > > +#define CLK_5(ID, NAME, MEM2, MEM3, MEM4) \ > > + { { ID, }, MEM2, MEM3, MEM4, } > > +#define CLK_MUX(ID, NAME, MEM2, MUX0, MUX1, MUX2, MUX3, MUX4) \ > > + { { ID, }, MEM2, { MUX0, MUX1, MUX2, MUX3, MUX4} } > > #endif > > > > -ulong imx8_clk_get_rate(struct clk *clk); > > -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate); > > -int __imx8_clk_enable(struct clk *clk, bool enable); > > +extern struct imx8_clks_collect imx8qxp_clk_collect; > > +extern struct imx8_clks_collect imx8qm_clk_collect; > > diff --git a/drivers/clk/imx/clk-imx8qm.c > > b/drivers/clk/imx/clk-imx8qm.c index a6b09d2..f4ee007 100644 > > --- a/drivers/clk/imx/clk-imx8qm.c > > +++ b/drivers/clk/imx/clk-imx8qm.c > > @@ -12,314 +12,189 @@ > > #include <dt-bindings/clock/imx8qm-clock.h> > > #include <dt-bindings/soc/imx_rsrc.h> > > #include <misc.h> > > +#include <asm/arch/lpcg.h> > > > > #include "clk-imx8.h" > > > > -#if CONFIG_IS_ENABLED(CMD_CLK) > > -struct imx8_clks imx8_clk_names[] = { > > - { IMX8QM_A53_DIV, "A53_DIV" }, > > - { IMX8QM_UART0_CLK, "UART0" }, > > - { IMX8QM_UART1_CLK, "UART1" }, > > - { IMX8QM_UART2_CLK, "UART2" }, > > - { IMX8QM_UART3_CLK, "UART3" }, > > - { IMX8QM_SDHC0_CLK, "SDHC0" }, > > - { IMX8QM_SDHC1_CLK, "SDHC1" }, > > - { IMX8QM_SDHC2_CLK, "SDHC2" }, > > - { IMX8QM_ENET0_AHB_CLK, "ENET0_AHB" }, > > - { IMX8QM_ENET0_IPG_CLK, "ENET0_IPG" }, > > - { IMX8QM_ENET0_REF_DIV, "ENET0_REF" }, > > - { IMX8QM_ENET0_PTP_CLK, "ENET0_PTP" }, > > - { IMX8QM_ENET1_AHB_CLK, "ENET1_AHB" }, > > - { IMX8QM_ENET1_IPG_CLK, "ENET1_IPG" }, > > - { IMX8QM_ENET1_REF_DIV, "ENET1_REF" }, > > - { IMX8QM_ENET1_PTP_CLK, "ENET1_PTP" }, > > +static struct imx8_clks imx8qm_clks[] = { > > + CLK_4( IMX8QM_A53_DIV, "A53_DIV", SC_R_A53, SC_PM_CLK_CPU > > ), > > + CLK_4( IMX8QM_A72_DIV, "A72_DIV", SC_R_A72, SC_PM_CLK_CPU > > ), > > + CLK_4( IMX8QM_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_LVDS0_I2C0_DIV, "LVDS0 I2C0 DIV", > > SC_R_LVDS_0_I2C_0, SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_LVDS0_I2C1_DIV, "LVDS0 I2C1 DIV", > > SC_R_LVDS_0_I2C_1, SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_LVDS1_I2C0_DIV, "LVDS1 I2C0 DIV", > > SC_R_LVDS_1_I2C_0, SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_LVDS1_I2C1_DIV, "LVDS1 I2C1 DIV", > > SC_R_LVDS_1_I2C_1, SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV", > > SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ), > > + CLK_4( IMX8QM_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV", > > SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ), > > + CLK_4( IMX8QM_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV", > > SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ), > > + CLK_4( IMX8QM_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV", > > SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ), > > + CLK_4( IMX8QM_CSI0_I2C0_DIV, "CSI0 I2C0_DIV", > > SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_CSI1_I2C0_DIV, "CSI1 I2C0_DIV", > > SC_R_CSI_1_I2C_0, SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_HDMI_I2C0_DIV, "HDMI I2C0_DIV", > > SC_R_HDMI_I2C_0, SC_PM_CLK_MISC2 ), > > + CLK_4( IMX8QM_HDMI_IPG_CLK, "HDMI IPG_CLK", SC_R_HDMI, > > SC_PM_CLK_MISC ), > > + CLK_4( IMX8QM_HDMI_RX_I2C0_DIV, "HDMI RX I2C_DIV", > > SC_R_HDMI_RX_I2C_0, SC_PM_CLK_MISC2 ), > > + CLK_4( IMX8QM_UART0_DIV, "UART0_DIV", SC_R_UART_0, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_UART1_DIV, "UART1_DIV", SC_R_UART_1, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_UART2_DIV, "UART2_DIV", SC_R_UART_2, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_UART3_DIV, "UART3_DIV", SC_R_UART_3, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_ENET0_ROOT_DIV, "ENET0_ROOT_DIV", > > SC_R_ENET_0, SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_ENET0_RGMII_DIV, "ENET0_RGMII_DIV", > > SC_R_ENET_0, SC_PM_CLK_MISC0 ), > > + CLK_4( IMX8QM_ENET1_ROOT_DIV, "ENET1_ROOT_DIV", > > SC_R_ENET_1, SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_ENET1_RGMII_DIV, "ENET1_RGMII_DIV", > > SC_R_ENET_1, SC_PM_CLK_MISC0 ), > > + > > + CLK_4( IMX8QM_USB3_ACLK_DIV, "USB3_ACLK_DIV", SC_R_USB_2, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QM_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2, > > SC_PM_CLK_MST_BUS ), > > + CLK_4( IMX8QM_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2, > > SC_PM_CLK_MISC ), > > + > > + CLK_4( IMX8QM_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0, > > SC_PM_CLK_PER ), > > + > > + CLK_4( IMX8QM_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND, > > SC_PM_CLK_MST_BUS ), > > + CLK_4( IMX8QM_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND, > > SC_PM_CLK_PER ), > > }; > > > > -int num_clks = ARRAY_SIZE(imx8_clk_names); > > -#endif > > - > > -ulong imx8_clk_get_rate(struct clk *clk) > > -{ > > - sc_pm_clk_t pm_clk; > > - ulong rate; > > - u16 resource; > > - int ret; > > - > > - debug("%s(#%lu)\n", __func__, clk->id); > > - > > - switch (clk->id) { > > - case IMX8QM_A53_DIV: > > - resource = SC_R_A53; > > - pm_clk = SC_PM_CLK_CPU; > > - break; > > - case IMX8QM_I2C0_CLK: > > - resource = SC_R_I2C_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_I2C1_CLK: > > - resource = SC_R_I2C_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_I2C2_CLK: > > - resource = SC_R_I2C_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_I2C3_CLK: > > - resource = SC_R_I2C_3; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_SDHC0_IPG_CLK: > > - case IMX8QM_SDHC0_CLK: > > - case IMX8QM_SDHC0_DIV: > > - resource = SC_R_SDHC_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_SDHC1_IPG_CLK: > > - case IMX8QM_SDHC1_CLK: > > - case IMX8QM_SDHC1_DIV: > > - resource = SC_R_SDHC_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_SDHC2_IPG_CLK: > > - case IMX8QM_SDHC2_CLK: > > - case IMX8QM_SDHC2_DIV: > > - resource = SC_R_SDHC_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_UART0_IPG_CLK: > > - case IMX8QM_UART0_CLK: > > - resource = SC_R_UART_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_UART1_CLK: > > - resource = SC_R_UART_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_UART2_CLK: > > - resource = SC_R_UART_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_UART3_CLK: > > - resource = SC_R_UART_3; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_ENET0_IPG_CLK: > > - case IMX8QM_ENET0_AHB_CLK: > > - case IMX8QM_ENET0_REF_DIV: > > - case IMX8QM_ENET0_PTP_CLK: > > - resource = SC_R_ENET_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_ENET1_IPG_CLK: > > - case IMX8QM_ENET1_AHB_CLK: > > - case IMX8QM_ENET1_REF_DIV: > > - case IMX8QM_ENET1_PTP_CLK: > > - resource = SC_R_ENET_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - default: > > - if (clk->id < IMX8QM_UART0_IPG_CLK || > > - clk->id >= IMX8QM_CLK_END) { > > - printf("%s(Invalid clk ID #%lu)\n", > > - __func__, clk->id); > > - return -EINVAL; > > - } > > - return -ENOTSUPP; > > - }; > > - > > - ret = sc_pm_get_clock_rate(-1, resource, pm_clk, > > - (sc_pm_clock_rate_t *)&rate); > > - if (ret) { > > - printf("%s err %d\n", __func__, ret); > > - return ret; > > - } > > - > > - return rate; > > -} > > - > > -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate) > > -{ > > - sc_pm_clk_t pm_clk; > > - u32 new_rate = rate; > > - u16 resource; > > - int ret; > > - > > - debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate); > > - > > - switch (clk->id) { > > - case IMX8QM_I2C0_CLK: > > - resource = SC_R_I2C_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_I2C1_CLK: > > - resource = SC_R_I2C_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_I2C2_CLK: > > - resource = SC_R_I2C_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_I2C3_CLK: > > - resource = SC_R_I2C_3; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_UART0_CLK: > > - resource = SC_R_UART_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_UART1_CLK: > > - resource = SC_R_UART_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_UART2_CLK: > > - resource = SC_R_UART_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_UART3_CLK: > > - resource = SC_R_UART_3; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_SDHC0_IPG_CLK: > > - case IMX8QM_SDHC0_CLK: > > - case IMX8QM_SDHC0_DIV: > > - resource = SC_R_SDHC_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_SDHC1_IPG_CLK: > > - case IMX8QM_SDHC1_CLK: > > - case IMX8QM_SDHC1_DIV: > > - resource = SC_R_SDHC_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_SDHC2_IPG_CLK: > > - case IMX8QM_SDHC2_CLK: > > - case IMX8QM_SDHC2_DIV: > > - resource = SC_R_SDHC_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_ENET0_IPG_CLK: > > - case IMX8QM_ENET0_AHB_CLK: > > - case IMX8QM_ENET0_REF_DIV: > > - case IMX8QM_ENET0_PTP_CLK: > > - case IMX8QM_ENET0_ROOT_DIV: > > - resource = SC_R_ENET_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_ENET1_IPG_CLK: > > - case IMX8QM_ENET1_AHB_CLK: > > - case IMX8QM_ENET1_REF_DIV: > > - case IMX8QM_ENET1_PTP_CLK: > > - case IMX8QM_ENET1_ROOT_DIV: > > - resource = SC_R_ENET_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - default: > > - if (clk->id < IMX8QM_UART0_IPG_CLK || > > - clk->id >= IMX8QM_CLK_END) { > > - printf("%s(Invalid clk ID #%lu)\n", > > - __func__, clk->id); > > - return -EINVAL; > > - } > > - return -ENOTSUPP; > > - }; > > - > > - ret = sc_pm_set_clock_rate(-1, resource, pm_clk, > > &new_rate); > > - if (ret) { > > - printf("%s err %d\n", __func__, ret); > > - return ret; > > - } > > - > > - return new_rate; > > -} > > - > > -int __imx8_clk_enable(struct clk *clk, bool enable) > > -{ > > - sc_pm_clk_t pm_clk; > > - u16 resource; > > - int ret; > > +static struct imx8_fixed_clks imx8qm_fixed_clks[] = { > > + CLK_3( IMX8QM_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK", > > SC_83MHZ ), > > + CLK_3( IMX8QM_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK", > > SC_166MHZ ), > > + CLK_3( IMX8QM_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK", > > SC_333MHZ ), > > + CLK_3( IMX8QM_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ ), > > + CLK_3( IMX8QM_IPG_MIPI_CSI_CLK_ROOT, "IPG_MIPI_CLK", > > SC_120MHZ ), > > + CLK_3( IMX8QM_LVDS_IPG_CLK, "IPG_LVDS_CLK", SC_24MHZ ), > > + CLK_3( IMX8QM_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ), > > + CLK_3( IMX8QM_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ), > > + CLK_3( IMX8QM_MIPI0_CLK_ROOT, "MIPI0_CLK", SC_120MHZ ), > > + CLK_3( IMX8QM_MIPI1_CLK_ROOT, "MIPI1_CLK", SC_120MHZ ), > > + CLK_3( IMX8QM_HDMI_RX_IPG_CLK, "HDMI_RX_IPG_CLK", > > SC_200MHZ ), > > +}; > > > > - debug("%s(#%lu)\n", __func__, clk->id); > > +static struct imx8_gpr_clks imx8qm_gpr_clks[] = { > > + CLK_5( IMX8QM_ENET0_REF_DIV, "ENET0_REF_DIV", SC_R_ENET_0, > > SC_C_CLKDIV, IMX8QM_ENET0_ROOT_DIV ), > > + CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_SEL, > > "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ), > > + CLK_4( IMX8QM_ENET0_RMII_TX_SEL, "ENET0_RMII_TX", > > SC_R_ENET_0, SC_C_TXCLK ), > > + CLK_4( IMX8QM_ENET0_REF_25MHZ_125MHZ_CLK, > > "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ), > > + CLK_4( IMX8QM_ENET0_REF_50MHZ_CLK, "ENET0_REF_50", > > SC_R_ENET_0, SC_C_DISABLE_50 ), > > + > > + CLK_5( IMX8QM_ENET1_REF_DIV, "ENET1_REF_DIV", SC_R_ENET_1, > > SC_C_CLKDIV, IMX8QM_ENET1_ROOT_DIV ), > > + CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_SEL, > > "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ), > > + CLK_4( IMX8QM_ENET1_RMII_TX_SEL, "ENET1_RMII_TX", > > SC_R_ENET_1, SC_C_TXCLK ), > > + CLK_4( IMX8QM_ENET1_REF_25MHZ_125MHZ_CLK, > > "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ), > > + CLK_4( IMX8QM_ENET1_REF_50MHZ_CLK, "ENET1_REF_50", > > SC_R_ENET_1, SC_C_DISABLE_50 ), > > +}; > > > > - switch (clk->id) { > > - case IMX8QM_I2C0_CLK: > > - resource = SC_R_I2C_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_I2C1_CLK: > > - resource = SC_R_I2C_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_I2C2_CLK: > > - resource = SC_R_I2C_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_I2C3_CLK: > > - resource = SC_R_I2C_3; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_UART0_CLK: > > - resource = SC_R_UART_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_UART1_CLK: > > - resource = SC_R_UART_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_UART2_CLK: > > - resource = SC_R_UART_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_UART3_CLK: > > - resource = SC_R_UART_3; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_SDHC0_IPG_CLK: > > - case IMX8QM_SDHC0_CLK: > > - case IMX8QM_SDHC0_DIV: > > - resource = SC_R_SDHC_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_SDHC1_IPG_CLK: > > - case IMX8QM_SDHC1_CLK: > > - case IMX8QM_SDHC1_DIV: > > - resource = SC_R_SDHC_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_SDHC2_IPG_CLK: > > - case IMX8QM_SDHC2_CLK: > > - case IMX8QM_SDHC2_DIV: > > - resource = SC_R_SDHC_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_ENET0_IPG_CLK: > > - case IMX8QM_ENET0_AHB_CLK: > > - case IMX8QM_ENET0_REF_DIV: > > - case IMX8QM_ENET0_PTP_CLK: > > - resource = SC_R_ENET_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QM_ENET1_IPG_CLK: > > - case IMX8QM_ENET1_AHB_CLK: > > - case IMX8QM_ENET1_REF_DIV: > > - case IMX8QM_ENET1_PTP_CLK: > > - resource = SC_R_ENET_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - default: > > - if (clk->id < IMX8QM_UART0_IPG_CLK || > > - clk->id >= IMX8QM_CLK_END) { > > - printf("%s(Invalid clk ID #%lu)\n", > > - __func__, clk->id); > > - return -EINVAL; > > - } > > - return -ENOTSUPP; > > - } > > +static struct imx8_lpcg_clks imx8qm_lpcg_clks[] = { > > + CLK_5( IMX8QM_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG, > > IMX8QM_I2C0_DIV ), > > + CLK_5( IMX8QM_I2C0_IPG_CLK, "I2C0_IPG", 16, LPI2C_0_LPCG, > > IMX8QM_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QM_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG, > > IMX8QM_I2C1_DIV ), > > + CLK_5( IMX8QM_I2C1_IPG_CLK, "I2C1_IPG", 16, LPI2C_1_LPCG, > > IMX8QM_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QM_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG, > > IMX8QM_I2C2_DIV ), > > + CLK_5( IMX8QM_I2C2_IPG_CLK, "I2C2_IPG", 16, LPI2C_2_LPCG, > > IMX8QM_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QM_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG, > > IMX8QM_I2C3_DIV ), > > + CLK_5( IMX8QM_I2C3_IPG_CLK, "I2C3_IPG", 16, LPI2C_3_LPCG, > > IMX8QM_IPG_DMA_CLK_ROOT ), > > + > > + CLK_5( IMX8QM_LVDS0_I2C0_CLK, "LVDS0_I2C0_CLK", 0, > > DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS0_I2C0_DIV ), > > + CLK_5( IMX8QM_LVDS0_I2C0_IPG_CLK, "LVDS0_I2C0_IPG", 16, > > DI_LVDS_0_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ), > > + CLK_5( IMX8QM_LVDS0_I2C1_CLK, "LVDS0_I2C1_CLK", 0, > > DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS0_I2C1_DIV ), > > + CLK_5( IMX8QM_LVDS0_I2C1_IPG_CLK, "LVDS0_I2C1_IPG", 16, > > DI_LVDS_0_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ), > > + CLK_5( IMX8QM_LVDS1_I2C0_CLK, "LVDS1_I2C0_CLK", 0, > > DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS1_I2C0_DIV ), > > + CLK_5( IMX8QM_LVDS1_I2C0_IPG_CLK, "LVDS1_I2C0_IPG", 16, > > DI_LVDS_1_LPCG + 0x10, IMX8QM_LVDS_IPG_CLK ), > > + CLK_5( IMX8QM_LVDS1_I2C1_CLK, "LVDS1_I2C1_CLK", 0, > > DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS1_I2C1_DIV ), > > + CLK_5( IMX8QM_LVDS1_I2C1_IPG_CLK, "LVDS1_I2C1_IPG", 16, > > DI_LVDS_1_LPCG + 0x14, IMX8QM_LVDS_IPG_CLK ), > > + > > + CLK_5( IMX8QM_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0, > > MIPI_DSI_0_LPCG + 0x1c, IMX8QM_MIPI0_I2C0_DIV ), > > + CLK_5( IMX8QM_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 0, > > MIPI_DSI_0_LPCG + 0x14, IMX8QM_MIPI0_I2C0_IPG_S_CLK), > > + CLK_5( IMX8QM_MIPI0_I2C0_IPG_S_CLK, "MIPI0_I2C0_IPG_S", 0, > > MIPI_DSI_0_LPCG + 0x18, IMX8QM_MIPI0_CLK_ROOT ), > > + CLK_5( IMX8QM_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0, > > MIPI_DSI_0_LPCG + 0x2c, IMX8QM_MIPI0_I2C1_DIV ), > > + CLK_5( IMX8QM_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 0, > > MIPI_DSI_0_LPCG + 0x24, IMX8QM_MIPI0_I2C1_IPG_S_CLK), > > + CLK_5( IMX8QM_MIPI0_I2C1_IPG_S_CLK, "MIPI0_I2C1_IPG_S", 0, > > MIPI_DSI_0_LPCG + 0x28, IMX8QM_MIPI0_CLK_ROOT ), > > + CLK_5( IMX8QM_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0, > > MIPI_DSI_1_LPCG + 0x1c, IMX8QM_MIPI1_I2C0_DIV ), > > + CLK_5( IMX8QM_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 0, > > MIPI_DSI_1_LPCG + 0x14, IMX8QM_MIPI1_I2C0_IPG_S_CLK), > > + CLK_5( IMX8QM_MIPI1_I2C0_IPG_S_CLK, "MIPI1_I2C0_IPG_S", 0, > > MIPI_DSI_1_LPCG + 0x18, IMX8QM_MIPI1_CLK_ROOT ), > > + CLK_5( IMX8QM_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0, > > MIPI_DSI_1_LPCG + 0x2c, IMX8QM_MIPI1_I2C1_DIV ), > > + CLK_5( IMX8QM_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 0, > > MIPI_DSI_1_LPCG + 0x24, IMX8QM_MIPI1_I2C1_IPG_S_CLK), > > + CLK_5( IMX8QM_MIPI1_I2C1_IPG_S_CLK, "MIPI1_I2C1_IPG_S", 0, > > MIPI_DSI_1_LPCG + 0x28, IMX8QM_MIPI1_CLK_ROOT ), > > + > > + CLK_5( IMX8QM_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0, > > MIPI_CSI_0_LPCG > > + 0x14, IMX8QM_CSI0_I2C0_DIV ), > > + CLK_5( IMX8QM_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16, > > MIPI_CSI_0_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ), > > + CLK_5( IMX8QM_CSI1_I2C0_CLK, "CSI1_I2C0_CLK", 0, > > MIPI_CSI_1_LPCG > > + 0x14, IMX8QM_CSI1_I2C0_DIV ), > > + CLK_5( IMX8QM_CSI1_I2C0_IPG_CLK, "CSI1_I2C0_IPG", 16, > > MIPI_CSI_1_LPCG + 0x14, IMX8QM_IPG_MIPI_CSI_CLK_ROOT ), > > + CLK_5( IMX8QM_HDMI_I2C0_CLK, "HDMI_I2C0_CLK", 0, > > DI_HDMI_LPCG, IMX8QM_HDMI_I2C0_DIV ), > > + CLK_5( IMX8QM_HDMI_I2C_IPG_CLK, "HDMI_I2C0_IPG", 16, > > DI_HDMI_LPCG, IMX8QM_HDMI_IPG_CLK ), > > + CLK_5( IMX8QM_HDMI_RX_I2C_DIV_CLK, "HDMI RX_I2C_DIV_CLK", > > 0, MIPI_DSI_0_LPCG + 0x14, IMX8QM_MIPI0_I2C0_DIV ), > > + CLK_5( IMX8QM_HDMI_RX_I2C0_CLK, "HDMI RX_I2C_CLK", 0, > > MIPI_DSI_0_LPCG + 0x10, IMX8QM_HDMI_RX_I2C_DIV_CLK ), > > + CLK_5( IMX8QM_HDMI_RX_I2C_IPG_CLK, "HDMI_RX_I2C_IPG", 0, > > RX_HDMI_LPCG + 0x18, IMX8QM_HDMI_RX_I2C_IPG_S_CLK), > > + CLK_5( IMX8QM_HDMI_RX_I2C_IPG_S_CLK, "HDMI_I2C_IPG_S", 0, > > RX_HDMI_LPCG + 0x1c, IMX8QM_HDMI_RX_IPG_CLK ), > > + > > + CLK_5( IMX8QM_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG, > > IMX8QM_UART0_DIV ), > > + CLK_5( IMX8QM_UART0_IPG_CLK, "UART0_IPG", 16, > > LPUART_0_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QM_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG, > > IMX8QM_UART1_DIV ), > > + CLK_5( IMX8QM_UART1_IPG_CLK, "UART1_IPG", 16, > > LPUART_1_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QM_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG, > > IMX8QM_UART2_DIV ), > > + CLK_5( IMX8QM_UART2_IPG_CLK, "UART2_IPG", 16, > > LPUART_2_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QM_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG, > > IMX8QM_UART3_DIV ), > > + CLK_5( IMX8QM_UART3_IPG_CLK, "UART3_IPG", 16, > > LPUART_3_LPCG, IMX8QM_IPG_DMA_CLK_ROOT ), > > + > > + CLK_5( IMX8QM_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG, > > IMX8QM_SDHC0_DIV ), > > + CLK_5( IMX8QM_SDHC0_IPG_CLK, "SDHC0_IPG", 16, USDHC_0_LPCG, > > IMX8QM_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG, > > IMX8QM_SDHC1_DIV ), > > + CLK_5( IMX8QM_SDHC1_IPG_CLK, "SDHC1_IPG", 16, USDHC_1_LPCG, > > IMX8QM_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG, > > IMX8QM_SDHC2_DIV ), > > + CLK_5( IMX8QM_SDHC2_IPG_CLK, "SDHC2_IPG", 16, USDHC_2_LPCG, > > IMX8QM_IPG_CONN_CLK_ROOT ), > > + > > + CLK_5( IMX8QM_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20, > > ENET_0_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_ENET0_IPG_CLK, "ENET0_IPG", 16, ENET_0_LPCG, > > IMX8QM_ENET0_IPG_S_CLK ), > > + CLK_5( IMX8QM_ENET0_AHB_CLK, "ENET0_AHB", 8, ENET_0_LPCG, > > IMX8QM_AXI_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG, > > IMX8QM_ENET0_ROOT_DIV ), > > + CLK_5( IMX8QM_ENET0_PTP_CLK, "ENET0_PTP", 0, ENET_0_LPCG, > > IMX8QM_ENET0_ROOT_DIV ), > > + CLK_5( IMX8QM_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12, > > ENET_0_LPCG, IMX8QM_ENET0_RMII_TX_SEL ), > > + CLK_5( IMX8QM_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0, > > ENET_0_LPCG + 0x4, IMX8QM_ENET0_RGMII_DIV ), > > + > > + CLK_5( IMX8QM_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20, > > ENET_1_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_ENET1_IPG_CLK, "ENET1_IPG", 16, ENET_1_LPCG, > > IMX8QM_ENET1_IPG_S_CLK ), > > + CLK_5( IMX8QM_ENET1_AHB_CLK, "ENET1_AHB", 8, ENET_1_LPCG, > > IMX8QM_AXI_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG, > > IMX8QM_ENET1_ROOT_DIV ), > > + CLK_5( IMX8QM_ENET1_PTP_CLK, "ENET1_PTP", 0, ENET_1_LPCG, > > IMX8QM_ENET1_ROOT_DIV ), > > + CLK_5( IMX8QM_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12, > > ENET_1_LPCG, IMX8QM_ENET1_RMII_TX_SEL ), > > + CLK_5( IMX8QM_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0, > > ENET_1_LPCG + 0x4, IMX8QM_ENET1_RGMII_DIV ), > > + > > + CLK_5( IMX8QM_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18, > > FSPI_0_LPCG, IMX8QM_LSIO_BUS_CLK ), > > + CLK_5( IMX8QM_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14, > > FSPI_0_LPCG, IMX8QM_FSPI0_IPG_S_CLK ), > > + CLK_5( IMX8QM_FSPI0_HCLK, "FSPI0_HCLK", 0x10, FSPI_0_LPCG, > > IMX8QM_LSIO_MEM_CLK ), > > + CLK_5( IMX8QM_FSPI0_CLK, "FSPI0_CLK", 0, FSPI_0_LPCG, > > IMX8QM_FSPI0_DIV ), > > + > > + CLK_5( IMX8QM_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24, > > USB_2_LPCG, IMX8QM_AHB_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16, > > USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_USB2_OH_IPG_S_PL301_CLK, > > "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, > > IMX8QM_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28, > > USB_2_LPCG, IMX8QM_IPG_CONN_CLK_ROOT ), > > + > > + CLK_5( IMX8QM_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG, > > IMX8QM_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_USB3_CORE_PCLK, "USB3_CORE", 20, USB_3_LPCG, > > IMX8QM_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG, > > IMX8QM_USB3_IPG_CLK ), > > + CLK_5( IMX8QM_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG, > > IMX8QM_USB3_ACLK_DIV ), > > + CLK_5( IMX8QM_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG, > > IMX8QM_USB3_BUS_DIV ), > > + CLK_5( IMX8QM_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG, > > IMX8QM_USB3_LPM_DIV ), > > + > > + CLK_5( IMX8QM_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG, > > IMX8QM_AXI_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20, > > NAND_LPCG, IMX8QM_AXI_CONN_CLK_ROOT ), > > + CLK_5( IMX8QM_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4, NAND_LPCG, > > IMX8QM_GPMI_BCH_IO_DIV ), > > + CLK_5( IMX8QM_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0, NAND_LPCG, > > IMX8QM_GPMI_BCH_DIV ), > > + CLK_5( IMX8QM_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG + 0x4, > > IMX8QM_AXI_CONN_CLK_ROOT ), > > +}; > > > > - ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0); > > - if (ret) { > > - printf("%s err %d\n", __func__, ret); > > - return ret; > > - } > > +struct imx8_mux_clks imx8qm_mux_clks[] = { > > +}; > > > > - return 0; > > -} > > +struct imx8_clks_collect imx8qm_clk_collect = { > > + { > > + {&imx8qm_clks, ARRAY_SIZE(imx8qm_clks)}, > > + {&imx8qm_fixed_clks, > > ARRAY_SIZE(imx8qm_fixed_clks)}, > > + {&imx8qm_gpr_clks, ARRAY_SIZE(imx8qm_gpr_clks)}, > > + {&imx8qm_lpcg_clks, ARRAY_SIZE(imx8qm_lpcg_clks)}, > > + {&imx8qm_mux_clks, ARRAY_SIZE(imx8qm_mux_clks)}, > > + }, > > + FLAG_CLK_IMX8_IMX8QM, > > +}; > > diff --git a/drivers/clk/imx/clk-imx8qxp.c > > b/drivers/clk/imx/clk-imx8qxp.c index 1fca36a..8181a97 100644 > > --- a/drivers/clk/imx/clk-imx8qxp.c > > +++ b/drivers/clk/imx/clk-imx8qxp.c > > @@ -12,300 +12,156 @@ > > #include <dt-bindings/clock/imx8qxp-clock.h> > > #include <dt-bindings/soc/imx_rsrc.h> > > #include <misc.h> > > +#include <asm/arch/lpcg.h> > > > > #include "clk-imx8.h" > > > > -#if CONFIG_IS_ENABLED(CMD_CLK) > > -struct imx8_clks imx8_clk_names[] = { > > - { IMX8QXP_A35_DIV, "A35_DIV" }, > > - { IMX8QXP_I2C0_CLK, "I2C0" }, > > - { IMX8QXP_I2C1_CLK, "I2C1" }, > > - { IMX8QXP_I2C2_CLK, "I2C2" }, > > - { IMX8QXP_I2C3_CLK, "I2C3" }, > > - { IMX8QXP_UART0_CLK, "UART0" }, > > - { IMX8QXP_UART1_CLK, "UART1" }, > > - { IMX8QXP_UART2_CLK, "UART2" }, > > - { IMX8QXP_UART3_CLK, "UART3" }, > > - { IMX8QXP_SDHC0_CLK, "SDHC0" }, > > - { IMX8QXP_SDHC1_CLK, "SDHC1" }, > > - { IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB" }, > > - { IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG" }, > > - { IMX8QXP_ENET0_REF_DIV, "ENET0_REF" }, > > - { IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP" }, > > - { IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB" }, > > - { IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG" }, > > - { IMX8QXP_ENET1_REF_DIV, "ENET1_REF" }, > > - { IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP" }, > > +static struct imx8_clks imx8qxp_clks[] = { > > + CLK_4( IMX8QXP_A35_DIV, "A35_DIV", SC_R_A35, SC_PM_CLK_CPU > > ), > > + CLK_4( IMX8QXP_I2C0_DIV, "I2C0_DIV", SC_R_I2C_0, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_I2C1_DIV, "I2C1_DIV", SC_R_I2C_1, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_I2C2_DIV, "I2C2_DIV", SC_R_I2C_2, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_I2C3_DIV, "I2C3_DIV", SC_R_I2C_3, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_MIPI0_I2C0_DIV, "MIPI0 I2C0_DIV", > > SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2 ), > > + CLK_4( IMX8QXP_MIPI0_I2C1_DIV, "MIPI0 I2C1_DIV", > > SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2 ), > > + CLK_4( IMX8QXP_MIPI1_I2C0_DIV, "MIPI1 I2C0_DIV", > > SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2 ), > > + CLK_4( IMX8QXP_MIPI1_I2C1_DIV, "MIPI1 I2C1_DIV", > > SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2 ), > > + CLK_4( IMX8QXP_CSI0_I2C0_DIV, "CSI0 I2C0_DIV", > > SC_R_CSI_0_I2C_0, SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_UART0_DIV, "UART0_DIV", SC_R_UART_0, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_UART1_DIV, "UART1_DIV", SC_R_UART_1, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_UART2_DIV, "UART2_DIV", SC_R_UART_2, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_UART3_DIV, "UART3_DIV", SC_R_UART_3, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_SDHC0_DIV, "SDHC0_DIV", SC_R_SDHC_0, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_SDHC1_DIV, "SDHC1_DIV", SC_R_SDHC_1, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_SDHC2_DIV, "SDHC2_DIV", SC_R_SDHC_2, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_ENET0_ROOT_DIV, "ENET0_ROOT_DIV", > > SC_R_ENET_0, SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_ENET0_RGMII_DIV, "ENET0_RGMII_DIV", > > SC_R_ENET_0, SC_PM_CLK_MISC0 ), > > + CLK_4( IMX8QXP_ENET1_ROOT_DIV, "ENET1_ROOT_DIV", > > SC_R_ENET_1, SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_ENET1_RGMII_DIV, "ENET1_RGMII_DIV", > > SC_R_ENET_1, SC_PM_CLK_MISC0 ), > > + CLK_4( IMX8QXP_USB3_ACLK_DIV, "USB3_ACLK_DIV", SC_R_USB_2, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_USB3_BUS_DIV, "USB3_BUS_DIV", SC_R_USB_2, > > SC_PM_CLK_MST_BUS ), > > + CLK_4( IMX8QXP_USB3_LPM_DIV, "USB3_LPM_DIV", SC_R_USB_2, > > SC_PM_CLK_MISC ), > > + CLK_4( IMX8QXP_LSIO_FSPI0_DIV, "FSPI0_DIV", SC_R_FSPI_0, > > SC_PM_CLK_PER ), > > + CLK_4( IMX8QXP_GPMI_BCH_IO_DIV, "GPMI_IO_DIV", SC_R_NAND, > > SC_PM_CLK_MST_BUS ), > > + CLK_4( IMX8QXP_GPMI_BCH_DIV, "GPMI_BCH_DIV", SC_R_NAND, > > SC_PM_CLK_PER ), > > }; > > > > -int num_clks = ARRAY_SIZE(imx8_clk_names); > > -#endif > > - > > -ulong imx8_clk_get_rate(struct clk *clk) > > -{ > > - sc_pm_clk_t pm_clk; > > - ulong rate; > > - u16 resource; > > - int ret; > > - > > - debug("%s(#%lu)\n", __func__, clk->id); > > - > > - switch (clk->id) { > > - case IMX8QXP_A35_DIV: > > - resource = SC_R_A35; > > - pm_clk = SC_PM_CLK_CPU; > > - break; > > - case IMX8QXP_I2C0_CLK: > > - resource = SC_R_I2C_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_I2C1_CLK: > > - resource = SC_R_I2C_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_I2C2_CLK: > > - resource = SC_R_I2C_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_I2C3_CLK: > > - resource = SC_R_I2C_3; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_SDHC0_IPG_CLK: > > - case IMX8QXP_SDHC0_CLK: > > - case IMX8QXP_SDHC0_DIV: > > - resource = SC_R_SDHC_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_SDHC1_IPG_CLK: > > - case IMX8QXP_SDHC1_CLK: > > - case IMX8QXP_SDHC1_DIV: > > - resource = SC_R_SDHC_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_UART0_IPG_CLK: > > - case IMX8QXP_UART0_CLK: > > - resource = SC_R_UART_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_UART1_CLK: > > - resource = SC_R_UART_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_UART2_CLK: > > - resource = SC_R_UART_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_UART3_CLK: > > - resource = SC_R_UART_3; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_ENET0_IPG_CLK: > > - case IMX8QXP_ENET0_AHB_CLK: > > - case IMX8QXP_ENET0_REF_DIV: > > - case IMX8QXP_ENET0_PTP_CLK: > > - resource = SC_R_ENET_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_ENET1_IPG_CLK: > > - case IMX8QXP_ENET1_AHB_CLK: > > - case IMX8QXP_ENET1_REF_DIV: > > - case IMX8QXP_ENET1_PTP_CLK: > > - resource = SC_R_ENET_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - default: > > - if (clk->id < IMX8QXP_UART0_IPG_CLK || > > - clk->id >= IMX8QXP_CLK_END) { > > - printf("%s(Invalid clk ID #%lu)\n", > > - __func__, clk->id); > > - return -EINVAL; > > - } > > - return -ENOTSUPP; > > - }; > > - > > - ret = sc_pm_get_clock_rate(-1, resource, pm_clk, > > - (sc_pm_clock_rate_t *)&rate); > > - if (ret) { > > - printf("%s err %d\n", __func__, ret); > > - return ret; > > - } > > - > > - return rate; > > -} > > - > > -ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate) > > -{ > > - sc_pm_clk_t pm_clk; > > - u32 new_rate = rate; > > - u16 resource; > > - int ret; > > - > > - debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate); > > - > > - switch (clk->id) { > > - case IMX8QXP_I2C0_CLK: > > - resource = SC_R_I2C_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_I2C1_CLK: > > - resource = SC_R_I2C_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_I2C2_CLK: > > - resource = SC_R_I2C_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_I2C3_CLK: > > - resource = SC_R_I2C_3; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_UART0_CLK: > > - resource = SC_R_UART_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_UART1_CLK: > > - resource = SC_R_UART_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_UART2_CLK: > > - resource = SC_R_UART_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_UART3_CLK: > > - resource = SC_R_UART_3; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_SDHC0_IPG_CLK: > > - case IMX8QXP_SDHC0_CLK: > > - case IMX8QXP_SDHC0_DIV: > > - resource = SC_R_SDHC_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_SDHC1_SEL: > > - case IMX8QXP_SDHC0_SEL: > > - return 0; > > - case IMX8QXP_SDHC1_IPG_CLK: > > - case IMX8QXP_SDHC1_CLK: > > - case IMX8QXP_SDHC1_DIV: > > - resource = SC_R_SDHC_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_ENET0_IPG_CLK: > > - case IMX8QXP_ENET0_AHB_CLK: > > - case IMX8QXP_ENET0_REF_DIV: > > - case IMX8QXP_ENET0_PTP_CLK: > > - resource = SC_R_ENET_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_ENET1_IPG_CLK: > > - case IMX8QXP_ENET1_AHB_CLK: > > - case IMX8QXP_ENET1_REF_DIV: > > - case IMX8QXP_ENET1_PTP_CLK: > > - resource = SC_R_ENET_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - default: > > - if (clk->id < IMX8QXP_UART0_IPG_CLK || > > - clk->id >= IMX8QXP_CLK_END) { > > - printf("%s(Invalid clk ID #%lu)\n", > > - __func__, clk->id); > > - return -EINVAL; > > - } > > - return -ENOTSUPP; > > - }; > > - > > - ret = sc_pm_set_clock_rate(-1, resource, pm_clk, > > &new_rate); > > - if (ret) { > > - printf("%s err %d\n", __func__, ret); > > - return ret; > > - } > > - > > - return new_rate; > > -} > > - > > -int __imx8_clk_enable(struct clk *clk, bool enable) > > -{ > > - sc_pm_clk_t pm_clk; > > - u16 resource; > > - int ret; > > +static struct imx8_fixed_clks imx8qxp_fixed_clks[] = { > > + CLK_3( IMX8QXP_IPG_CONN_CLK_ROOT, "IPG_CONN_CLK", > > SC_83MHZ ), > > + CLK_3( IMX8QXP_AHB_CONN_CLK_ROOT, "AHB_CONN_CLK", > > SC_166MHZ ), > > + CLK_3( IMX8QXP_AXI_CONN_CLK_ROOT, "AXI_CONN_CLK", > > SC_333MHZ ), > > + CLK_3( IMX8QXP_IPG_DMA_CLK_ROOT, "IPG_DMA_CLK", SC_120MHZ > > ), > > + CLK_3( IMX8QXP_MIPI_IPG_CLK, "IPG_MIPI_CLK", SC_120MHZ ), > > + CLK_3( IMX8QXP_LSIO_BUS_CLK, "LSIO_BUS_CLK", SC_100MHZ ), > > + CLK_3( IMX8QXP_LSIO_MEM_CLK, "LSIO_MEM_CLK", SC_200MHZ ), > > +}; > > > > - debug("%s(#%lu)\n", __func__, clk->id); > > +static struct imx8_gpr_clks imx8qxp_gpr_clks[] = { > > + CLK_5( IMX8QXP_ENET0_REF_DIV, "ENET0_REF_DIV", SC_R_ENET_0, > > SC_C_CLKDIV, IMX8QXP_ENET0_ROOT_DIV ), > > + CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL, > > "ENET0_REF_25_125", SC_R_ENET_0, SC_C_SEL_125 ), > > + CLK_4( IMX8QXP_ENET0_RMII_TX_SEL, "ENET0_RMII_TX", > > SC_R_ENET_0, SC_C_TXCLK ), > > + CLK_4( IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK, > > "ENET0_REF_25_125_CLK", SC_R_ENET_0, SC_C_DISABLE_125 ), > > + CLK_4( IMX8QXP_ENET0_REF_50MHZ_CLK, "ENET0_REF_50", > > SC_R_ENET_0, SC_C_DISABLE_50 ), > > + > > + CLK_5( IMX8QXP_ENET1_REF_DIV, "ENET1_REF_DIV", SC_R_ENET_1, > > SC_C_CLKDIV, IMX8QXP_ENET1_ROOT_DIV ), > > + CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL, > > "ENET1_REF_25_125", SC_R_ENET_1, SC_C_SEL_125 ), > > + CLK_4( IMX8QXP_ENET1_RMII_TX_SEL, "ENET1_RMII_TX", > > SC_R_ENET_1, SC_C_TXCLK ), > > + CLK_4( IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK, > > "ENET1_REF_25_125_CLK", SC_R_ENET_1, SC_C_DISABLE_125 ), > > + CLK_4( IMX8QXP_ENET1_REF_50MHZ_CLK, "ENET1_REF_50", > > SC_R_ENET_1, SC_C_DISABLE_50 ), > > +}; > > > > - switch (clk->id) { > > - case IMX8QXP_I2C0_CLK: > > - resource = SC_R_I2C_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_I2C1_CLK: > > - resource = SC_R_I2C_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_I2C2_CLK: > > - resource = SC_R_I2C_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_I2C3_CLK: > > - resource = SC_R_I2C_3; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_UART0_CLK: > > - resource = SC_R_UART_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_UART1_CLK: > > - resource = SC_R_UART_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_UART2_CLK: > > - resource = SC_R_UART_2; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_UART3_CLK: > > - resource = SC_R_UART_3; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_SDHC0_IPG_CLK: > > - case IMX8QXP_SDHC0_CLK: > > - case IMX8QXP_SDHC0_DIV: > > - resource = SC_R_SDHC_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_SDHC1_IPG_CLK: > > - case IMX8QXP_SDHC1_CLK: > > - case IMX8QXP_SDHC1_DIV: > > - resource = SC_R_SDHC_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_ENET0_IPG_CLK: > > - case IMX8QXP_ENET0_AHB_CLK: > > - case IMX8QXP_ENET0_REF_DIV: > > - case IMX8QXP_ENET0_PTP_CLK: > > - resource = SC_R_ENET_0; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - case IMX8QXP_ENET1_IPG_CLK: > > - case IMX8QXP_ENET1_AHB_CLK: > > - case IMX8QXP_ENET1_REF_DIV: > > - case IMX8QXP_ENET1_PTP_CLK: > > - resource = SC_R_ENET_1; > > - pm_clk = SC_PM_CLK_PER; > > - break; > > - default: > > - if (clk->id < IMX8QXP_UART0_IPG_CLK || > > - clk->id >= IMX8QXP_CLK_END) { > > - printf("%s(Invalid clk ID #%lu)\n", > > - __func__, clk->id); > > - return -EINVAL; > > - } > > - return -ENOTSUPP; > > - } > > +static struct imx8_lpcg_clks imx8qxp_lpcg_clks[] = { > > + CLK_5( IMX8QXP_I2C0_CLK, "I2C0_CLK", 0, LPI2C_0_LPCG, > > IMX8QXP_I2C0_DIV ), > > + CLK_5( IMX8QXP_I2C0_IPG_CLK, "I2C0_IPG", 16, LPI2C_0_LPCG, > > IMX8QXP_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QXP_I2C1_CLK, "I2C1_CLK", 0, LPI2C_1_LPCG, > > IMX8QXP_I2C1_DIV ), > > + CLK_5( IMX8QXP_I2C1_IPG_CLK, "I2C1_IPG", 16, LPI2C_1_LPCG, > > IMX8QXP_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QXP_I2C2_CLK, "I2C2_CLK", 0, LPI2C_2_LPCG, > > IMX8QXP_I2C2_DIV ), > > + CLK_5( IMX8QXP_I2C2_IPG_CLK, "I2C2_IPG", 16, LPI2C_2_LPCG, > > IMX8QXP_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QXP_I2C3_CLK, "I2C3_CLK", 0, LPI2C_3_LPCG, > > IMX8QXP_I2C3_DIV ), > > + CLK_5( IMX8QXP_I2C3_IPG_CLK, "I2C3_IPG", 16, LPI2C_3_LPCG, > > IMX8QXP_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QXP_MIPI0_I2C0_CLK, "MIPI0_I2C0_CLK", 0, > > DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI0_I2C0_DIV ), > > + CLK_5( IMX8QXP_MIPI0_I2C0_IPG_CLK, "MIPI0_I2C0_IPG", 16, > > DI_MIPI0_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ), > > + CLK_5( IMX8QXP_MIPI0_I2C1_CLK, "MIPI0_I2C1_CLK", 0, > > DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI0_I2C1_DIV ), > > + CLK_5( IMX8QXP_MIPI0_I2C1_IPG_CLK, "MIPI0_I2C1_IPG", 16, > > DI_MIPI0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ), > > + CLK_5( IMX8QXP_MIPI1_I2C0_CLK, "MIPI1_I2C0_CLK", 0, > > DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI1_I2C0_DIV ), > > + CLK_5( IMX8QXP_MIPI1_I2C0_IPG_CLK, "MIPI1_I2C0_IPG", 16, > > DI_MIPI1_LPCG + 0x10, IMX8QXP_MIPI_IPG_CLK ), > > + CLK_5( IMX8QXP_MIPI1_I2C1_CLK, "MIPI1_I2C1_CLK", 0, > > DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI1_I2C1_DIV ), > > + CLK_5( IMX8QXP_MIPI1_I2C1_IPG_CLK, "MIPI1_I2C1_IPG", 16, > > DI_MIPI1_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ), > > + CLK_5( IMX8QXP_CSI0_I2C0_CLK, "CSI0_I2C0_CLK", 0, > > MIPI_CSI_0_LPCG + 0x14, IMX8QXP_CSI0_I2C0_DIV ), > > + CLK_5( IMX8QXP_CSI0_I2C0_IPG_CLK, "CSI0_I2C0_IPG", 16, > > MIPI_CSI_0_LPCG + 0x14, IMX8QXP_MIPI_IPG_CLK ), > > + > > + CLK_5( IMX8QXP_UART0_CLK, "UART0_CLK", 0, LPUART_0_LPCG, > > IMX8QXP_UART0_DIV ), > > + CLK_5( IMX8QXP_UART0_IPG_CLK, "UART0_IPG", 16, > > LPUART_0_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QXP_UART1_CLK, "UART1_CLK", 0, LPUART_1_LPCG, > > IMX8QXP_UART1_DIV ), > > + CLK_5( IMX8QXP_UART1_IPG_CLK, "UART1_IPG", 16, > > LPUART_1_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QXP_UART2_CLK, "UART2_CLK", 0, LPUART_2_LPCG, > > IMX8QXP_UART2_DIV ), > > + CLK_5( IMX8QXP_UART2_IPG_CLK, "UART2_IPG", 16, > > LPUART_2_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ), > > + CLK_5( IMX8QXP_UART3_CLK, "UART3_CLK", 0, LPUART_3_LPCG, > > IMX8QXP_UART3_DIV ), > > + CLK_5( IMX8QXP_UART3_IPG_CLK, "UART3_IPG", 16, > > LPUART_3_LPCG, IMX8QXP_IPG_DMA_CLK_ROOT ), > > + > > + CLK_5( IMX8QXP_SDHC0_CLK, "SDHC0_CLK", 0, USDHC_0_LPCG, > > IMX8QXP_SDHC0_DIV ), > > + CLK_5( IMX8QXP_SDHC0_IPG_CLK, "SDHC0_IPG", 16, > > USDHC_0_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_SDHC1_CLK, "SDHC1_CLK", 0, USDHC_1_LPCG, > > IMX8QXP_SDHC1_DIV ), > > + CLK_5( IMX8QXP_SDHC1_IPG_CLK, "SDHC1_IPG", 16, > > USDHC_1_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_SDHC2_CLK, "SDHC2_CLK", 0, USDHC_2_LPCG, > > IMX8QXP_SDHC2_DIV ), > > + CLK_5( IMX8QXP_SDHC2_IPG_CLK, "SDHC2_IPG", 16, > > USDHC_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), > > + > > + CLK_5( IMX8QXP_ENET0_IPG_S_CLK, "ENET0_IPG_S", 20, > > ENET_0_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG", 16, ENET_0_LPCG, > > IMX8QXP_ENET0_IPG_S_CLK ), > > + CLK_5( IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB", 8, ENET_0_LPCG, > > IMX8QXP_AXI_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_ENET0_TX_CLK, "ENET0_TX", 4, ENET_0_LPCG, > > IMX8QXP_ENET0_ROOT_DIV ), > > + CLK_5( IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP", 0, ENET_0_LPCG, > > IMX8QXP_ENET0_ROOT_DIV ), > > + CLK_5( IMX8QXP_ENET0_RGMII_TX_CLK, "ENET0_RGMII_TX", 12, > > ENET_0_LPCG, IMX8QXP_ENET0_RMII_TX_SEL ), > > + CLK_5( IMX8QXP_ENET0_RMII_RX_CLK, "ENET0_RMII_RX", 0, > > ENET_0_LPCG + 0x4, IMX8QXP_ENET0_RGMII_DIV ), > > + > > + CLK_5( IMX8QXP_ENET1_IPG_S_CLK, "ENET1_IPG_S", 20, > > ENET_1_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG", 16, ENET_1_LPCG, > > IMX8QXP_ENET1_IPG_S_CLK ), > > + CLK_5( IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB", 8, ENET_1_LPCG, > > IMX8QXP_AXI_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_ENET1_TX_CLK, "ENET1_TX", 4, ENET_1_LPCG, > > IMX8QXP_ENET1_ROOT_DIV ), > > + CLK_5( IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP", 0, ENET_1_LPCG, > > IMX8QXP_ENET1_ROOT_DIV ), > > + CLK_5( IMX8QXP_ENET1_RGMII_TX_CLK, "ENET1_RGMII_TX", 12, > > ENET_1_LPCG, IMX8QXP_ENET1_RMII_TX_SEL ), > > + CLK_5( IMX8QXP_ENET1_RMII_RX_CLK, "ENET1_RMII_RX", 0, > > ENET_1_LPCG + 0x4, IMX8QXP_ENET1_RGMII_DIV ), > > + > > + CLK_5( IMX8QXP_LSIO_FSPI0_IPG_S_CLK, "FSPI0_IPG_S", 0x18, > > FSPI_0_LPCG, IMX8QXP_LSIO_BUS_CLK ), > > + CLK_5( IMX8QXP_LSIO_FSPI0_IPG_CLK, "FSPI0_IPG", 0x14, > > FSPI_0_LPCG, IMX8QXP_LSIO_FSPI0_IPG_S_CLK ), > > + CLK_5( IMX8QXP_LSIO_FSPI0_HCLK, "FSPI0_HCLK", 0x10, > > FSPI_0_LPCG, IMX8QXP_LSIO_MEM_CLK ), > > + CLK_5( IMX8QXP_LSIO_FSPI0_CLK, "FSPI0_CLK", 0, FSPI_0_LPCG, > > IMX8QXP_LSIO_FSPI0_DIV ), > > + > > + CLK_5( IMX8QXP_USB2_OH_AHB_CLK, "USB2_OH_AHB", 24, > > USB_2_LPCG, IMX8QXP_AHB_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_USB2_OH_IPG_S_CLK, "USB2_OH_IPG_S", 16, > > USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_USB2_OH_IPG_S_PL301_CLK, > > "USB2_OH_IPG_S_PL301", 20, USB_2_LPCG, > > IMX8QXP_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_USB2_PHY_IPG_CLK, "USB2_PHY_IPG", 28, > > USB_2_LPCG, IMX8QXP_IPG_CONN_CLK_ROOT ), > > + > > + CLK_5( IMX8QXP_USB3_IPG_CLK, "USB3_IPG", 16, USB_3_LPCG, > > IMX8QXP_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_USB3_CORE_PCLK, "USB3_CORE", 20, USB_3_LPCG, > > IMX8QXP_IPG_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_USB3_PHY_CLK, "USB3_PHY", 24, USB_3_LPCG, > > IMX8QXP_USB3_IPG_CLK ), > > + CLK_5( IMX8QXP_USB3_ACLK, "USB3_ACLK", 28, USB_3_LPCG, > > IMX8QXP_USB3_ACLK_DIV ), > > + CLK_5( IMX8QXP_USB3_BUS_CLK, "USB3_BUS", 0, USB_3_LPCG, > > IMX8QXP_USB3_BUS_DIV ), > > + CLK_5( IMX8QXP_USB3_LPM_CLK, "USB3_LPM", 4, USB_3_LPCG, > > IMX8QXP_USB3_LPM_DIV ), > > + > > + CLK_5( IMX8QXP_GPMI_APB_CLK, "GPMI_APB", 16, NAND_LPCG, > > IMX8QXP_AXI_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_GPMI_APB_BCH_CLK, "GPMI_APB_BCH", 20, > > NAND_LPCG, IMX8QXP_AXI_CONN_CLK_ROOT ), > > + CLK_5( IMX8QXP_GPMI_BCH_IO_CLK, "GPMI_IO_CLK", 4, > > NAND_LPCG, IMX8QXP_GPMI_BCH_IO_DIV ), > > + CLK_5( IMX8QXP_GPMI_BCH_CLK, "GPMI_BCH_CLK", 0, NAND_LPCG, > > IMX8QXP_GPMI_BCH_DIV ), > > + CLK_5( IMX8QXP_APBHDMA_CLK, "GPMI_CLK", 16, NAND_LPCG + > > 0x4, IMX8QXP_AXI_CONN_CLK_ROOT ), > > +}; > > > > - ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0); > > - if (ret) { > > - printf("%s err %d\n", __func__, ret); > > - return ret; > > - } > > +struct imx8_mux_clks imx8qxp_mux_clks[] = { > > + CLK_MUX( IMX8QXP_SDHC0_SEL, "SDHC0_SEL", IMX8QXP_SDHC0_DIV, > > IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK, > > + IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY, > > IMX8QXP_CLK_DUMMY ), > > + CLK_MUX( IMX8QXP_SDHC1_SEL, "SDHC1_SEL", IMX8QXP_SDHC1_DIV, > > IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK, > > + IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY, > > IMX8QXP_CLK_DUMMY ), > > + CLK_MUX( IMX8QXP_SDHC2_SEL, "SDHC2_SEL", IMX8QXP_SDHC2_DIV, > > IMX8QXP_CLK_DUMMY, IMX8QXP_CONN_PLL0_CLK, > > + IMX8QXP_CONN_PLL1_CLK, IMX8QXP_CLK_DUMMY, > > IMX8QXP_CLK_DUMMY ), > > +}; > > > > - return 0; > > -} > > +struct imx8_clks_collect imx8qxp_clk_collect = { > > + { > > + {&imx8qxp_clks, ARRAY_SIZE(imx8qxp_clks)}, > > + {&imx8qxp_fixed_clks, > > ARRAY_SIZE(imx8qxp_fixed_clks)}, > > + {&imx8qxp_gpr_clks, ARRAY_SIZE(imx8qxp_gpr_clks)}, > > + {&imx8qxp_lpcg_clks, > > ARRAY_SIZE(imx8qxp_lpcg_clks)}, > > + {&imx8qxp_mux_clks, ARRAY_SIZE(imx8qxp_mux_clks)}, > > + }, > > + FLAG_CLK_IMX8_IMX8QXP, > > +}; > > -- > > 2.7.4 > Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lu...@denx.de
pgpJl8QrHYBXI.pgp
Description: OpenPGP digital signature
_______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot