From 2a07137641769e06d4775698ff05d3a63ce82743 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:51:29 +0530 Subject: clk: exynos: provide device pointer to clk_register_* functions The device pointer set as NULL causes problems when clock banks depend on clocks from another clock bank. In such case, the appropriate clock needs to be resolved from OF phandle arguments, which is not possible if the associated device is not provided. Make necessary changes to make the correct device pointer available. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- drivers/clk/exynos/clk-pll.c | 3 ++- drivers/clk/exynos/clk-pll.h | 3 ++- drivers/clk/exynos/clk.c | 43 ++++++++++++++++++++++++------------------- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/drivers/clk/exynos/clk-pll.c b/drivers/clk/exynos/clk-pll.c index 542d577eaa6..fc7e638134a 100644 --- a/drivers/clk/exynos/clk-pll.c +++ b/drivers/clk/exynos/clk-pll.c @@ -136,7 +136,8 @@ static struct clk *_samsung_clk_register_pll(void __iomem *base, return clk; } -void samsung_clk_register_pll(void __iomem *base, unsigned int cmu_id, +void samsung_clk_register_pll(struct udevice *dev, void __iomem *base, + unsigned int cmu_id, const struct samsung_pll_clock *clk_list, unsigned int nr_clk) { diff --git a/drivers/clk/exynos/clk-pll.h b/drivers/clk/exynos/clk-pll.h index bdc94e7624d..22cc15a40a4 100644 --- a/drivers/clk/exynos/clk-pll.h +++ b/drivers/clk/exynos/clk-pll.h @@ -22,7 +22,8 @@ enum samsung_pll_type { pll_0831x, }; -void samsung_clk_register_pll(void __iomem *base, unsigned int cmu_id, +void samsung_clk_register_pll(struct udevice *dev, void __iomem *base, + unsigned int cmu_id, const struct samsung_pll_clock *clk_list, unsigned int nr_clk); diff --git a/drivers/clk/exynos/clk.c b/drivers/clk/exynos/clk.c index 943e8bd0189..2f5a3de6563 100644 --- a/drivers/clk/exynos/clk.c +++ b/drivers/clk/exynos/clk.c @@ -10,7 +10,8 @@ #include #include "clk.h" -static void samsung_clk_register_mux(void __iomem *base, unsigned int cmu_id, +static void samsung_clk_register_mux(struct udevice *dev, void __iomem *base, + unsigned int cmu_id, const struct samsung_mux_clock *clk_list, unsigned int nr_clk) { @@ -22,15 +23,17 @@ static void samsung_clk_register_mux(void __iomem *base, unsigned int cmu_id, unsigned long clk_id; m = &clk_list[cnt]; - clk = clk_register_mux(NULL, m->name, m->parent_names, - m->num_parents, m->flags, base + m->offset, m->shift, - m->width, m->mux_flags); + clk = clk_register_mux(dev, m->name, m->parent_names, + m->num_parents, m->flags, + base + m->offset, m->shift, m->width, + m->mux_flags); clk_id = SAMSUNG_TO_CLK_ID(cmu_id, m->id); clk_dm(clk_id, clk); } } -static void samsung_clk_register_div(void __iomem *base, unsigned int cmu_id, +static void samsung_clk_register_div(struct udevice *dev, void __iomem *base, + unsigned int cmu_id, const struct samsung_div_clock *clk_list, unsigned int nr_clk) { @@ -42,15 +45,16 @@ static void samsung_clk_register_div(void __iomem *base, unsigned int cmu_id, unsigned long clk_id; d = &clk_list[cnt]; - clk = clk_register_divider(NULL, d->name, d->parent_name, - d->flags, base + d->offset, d->shift, - d->width, d->div_flags); + clk = clk_register_divider(dev, d->name, d->parent_name, + d->flags, base + d->offset, d->shift, + d->width, d->div_flags); clk_id = SAMSUNG_TO_CLK_ID(cmu_id, d->id); clk_dm(clk_id, clk); } } -static void samsung_clk_register_gate(void __iomem *base, unsigned int cmu_id, +static void samsung_clk_register_gate(struct udevice *dev, void __iomem *base, + unsigned int cmu_id, const struct samsung_gate_clock *clk_list, unsigned int nr_clk) { @@ -62,16 +66,16 @@ static void samsung_clk_register_gate(void __iomem *base, unsigned int cmu_id, unsigned long clk_id; g = &clk_list[cnt]; - clk = clk_register_gate(NULL, g->name, g->parent_name, - g->flags, base + g->offset, g->bit_idx, - g->gate_flags, NULL); + clk = clk_register_gate(dev, g->name, g->parent_name, + g->flags, base + g->offset, g->bit_idx, + g->gate_flags, NULL); clk_id = SAMSUNG_TO_CLK_ID(cmu_id, g->id); clk_dm(clk_id, clk); } } -typedef void (*samsung_clk_register_fn)(void __iomem *base, unsigned int cmu_id, - const void *clk_list, +typedef void (*samsung_clk_register_fn)(struct udevice *dev, void __iomem *base, + unsigned int cmu_id, const void *clk_list, unsigned int nr_clk); static const samsung_clk_register_fn samsung_clk_register_fns[] = { @@ -91,16 +95,17 @@ static const samsung_clk_register_fn samsung_clk_register_fns[] = { * Having the array of clock groups @clk_groups makes it possible to keep a * correct clocks registration order. */ -static void samsung_cmu_register_clocks(void __iomem *base, unsigned int cmu_id, - const struct samsung_clk_group *clk_groups, - unsigned int nr_groups) +static void samsung_cmu_register_clocks(struct udevice *dev, void __iomem *base, + unsigned int cmu_id, + const struct samsung_clk_group *clk_groups, + unsigned int nr_groups) { unsigned int i; for (i = 0; i < nr_groups; i++) { const struct samsung_clk_group *g = &clk_groups[i]; - samsung_clk_register_fns[g->type](base, cmu_id, + samsung_clk_register_fns[g->type](dev, base, cmu_id, g->clk_list, g->nr_clk); } } @@ -124,7 +129,7 @@ int samsung_cmu_register_one(struct udevice *dev, unsigned int cmu_id, if (!base) return -EINVAL; - samsung_cmu_register_clocks(base, cmu_id, clk_groups, nr_groups); + samsung_cmu_register_clocks(dev, base, cmu_id, clk_groups, nr_groups); return 0; } -- cgit v1.3.1 From b006e40963c5db79fca7134cdfced643e095f64c Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:51:30 +0530 Subject: clk: exynos: add support for fixed rate and fixed factor clocks Add register functions for fixed rate and fixed factor clock drivers. The vendor-specific structs defined are borrowed from the CCF driver found in the Linux kernel. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- drivers/clk/exynos/clk.c | 43 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/exynos/clk.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/drivers/clk/exynos/clk.c b/drivers/clk/exynos/clk.c index 2f5a3de6563..a3832981f90 100644 --- a/drivers/clk/exynos/clk.c +++ b/drivers/clk/exynos/clk.c @@ -10,6 +10,47 @@ #include #include "clk.h" +static void +samsung_clk_register_fixed_rate(struct udevice *dev, void __iomem *base, + unsigned int cmu_id, + const struct samsung_fixed_rate_clock *clk_list, + unsigned int nr_clk) +{ + unsigned int cnt; + + for (cnt = 0; cnt < nr_clk; cnt++) { + struct clk *clk; + const struct samsung_fixed_rate_clock *m; + unsigned long clk_id; + + m = &clk_list[cnt]; + clk = clk_register_fixed_rate(NULL, m->name, m->fixed_rate); + clk_id = SAMSUNG_TO_CLK_ID(cmu_id, m->id); + clk_dm(clk_id, clk); + } +} + +static void +samsung_clk_register_fixed_factor(struct udevice *dev, void __iomem *base, + unsigned int cmu_id, + const struct samsung_fixed_factor_clock *clk_list, + unsigned int nr_clk) +{ + unsigned int cnt; + + for (cnt = 0; cnt < nr_clk; cnt++) { + struct clk *clk; + const struct samsung_fixed_factor_clock *m; + unsigned long clk_id; + + m = &clk_list[cnt]; + clk = clk_register_fixed_factor(dev, m->name, m->parent_name, + m->flags, m->mult, m->div); + clk_id = SAMSUNG_TO_CLK_ID(cmu_id, m->id); + clk_dm(clk_id, clk); + } +} + static void samsung_clk_register_mux(struct udevice *dev, void __iomem *base, unsigned int cmu_id, const struct samsung_mux_clock *clk_list, @@ -79,6 +120,8 @@ typedef void (*samsung_clk_register_fn)(struct udevice *dev, void __iomem *base, unsigned int nr_clk); static const samsung_clk_register_fn samsung_clk_register_fns[] = { + [S_CLK_FRATE] = (samsung_clk_register_fn)samsung_clk_register_fixed_rate, + [S_CLK_FFACTOR] = (samsung_clk_register_fn)samsung_clk_register_fixed_factor, [S_CLK_MUX] = (samsung_clk_register_fn)samsung_clk_register_mux, [S_CLK_DIV] = (samsung_clk_register_fn)samsung_clk_register_div, [S_CLK_GATE] = (samsung_clk_register_fn)samsung_clk_register_gate, diff --git a/drivers/clk/exynos/clk.h b/drivers/clk/exynos/clk.h index ed0a395f0f6..e53dcc6a821 100644 --- a/drivers/clk/exynos/clk.h +++ b/drivers/clk/exynos/clk.h @@ -58,6 +58,53 @@ static const struct clk_ops _name##_clk_ops = { \ */ #define SAMSUNG_TO_CLK_ID(_cmu, _id) (((_cmu) << 8) | ((_id) & 0xff)) +/** + * struct samsung_fixed_rate_clock - information about fixed-rate clock + * @id: platform specific id of the clock + * @name: name of this fixed-rate clock + * @fixed_rate: fixed clock rate of this clock + */ +struct samsung_fixed_rate_clock { + unsigned int id; + const char *name; + unsigned long fixed_rate; +}; + +#define FRATE(_id, cname, frate) \ + { \ + .id = _id, \ + .name = cname, \ + .fixed_rate = frate, \ + } + +/** + * struct samsung_fixed_factor_clock - information about fixed-factor clock + * @id: platform specific id of the clock + * @name: name of this fixed-factor clock + * @parent_name: parent clock name + * @mult: fixed multiplication factor + * @div: fixed division factor + * @flags: optional fixed-factor clock flags + */ +struct samsung_fixed_factor_clock { + unsigned int id; + const char *name; + const char *parent_name; + unsigned long mult; + unsigned long div; + unsigned long flags; +}; + +#define FFACTOR(_id, cname, pname, m, d, f) \ + { \ + .id = _id, \ + .name = cname, \ + .parent_name = pname, \ + .mult = m, \ + .div = d, \ + .flags = f, \ + } + /** * struct samsung_mux_clock - information about mux clock * @id: platform specific id of the clock @@ -206,6 +253,8 @@ struct samsung_pll_clock { } enum samsung_clock_type { + S_CLK_FRATE, + S_CLK_FFACTOR, S_CLK_MUX, S_CLK_DIV, S_CLK_GATE, -- cgit v1.3.1 From 526a257fdba7c1a8288b6454b1551a35b0ec5723 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:51:31 +0530 Subject: clk: exynos: add support for PLL1417X PLL1417X seem to be compatible with PLL0822X, as also seen in the respective Linux kernel driver. Add an enum entry for the type, while merely being an alias for PLL0822X. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- drivers/clk/exynos/clk-pll.c | 1 + drivers/clk/exynos/clk-pll.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/clk/exynos/clk-pll.c b/drivers/clk/exynos/clk-pll.c index fc7e638134a..4b67591af10 100644 --- a/drivers/clk/exynos/clk-pll.c +++ b/drivers/clk/exynos/clk-pll.c @@ -117,6 +117,7 @@ static struct clk *_samsung_clk_register_pll(void __iomem *base, switch (pll_clk->type) { case pll_0822x: + case pll_1417x: drv_name = UBOOT_DM_CLK_SAMSUNG_PLL0822X; break; case pll_0831x: diff --git a/drivers/clk/exynos/clk-pll.h b/drivers/clk/exynos/clk-pll.h index 22cc15a40a4..d5dfc8934ba 100644 --- a/drivers/clk/exynos/clk-pll.h +++ b/drivers/clk/exynos/clk-pll.h @@ -20,6 +20,7 @@ struct samsung_pll_clock; enum samsung_pll_type { pll_0822x, pll_0831x, + pll_1417x, }; void samsung_clk_register_pll(struct udevice *dev, void __iomem *base, -- cgit v1.3.1 From 4bee54fbfa9e5be4bb17435dc809b0002566f986 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:51:32 +0530 Subject: clk: exynos: add function for Samsung CMU ops->request The request function performs a simple check if the clock with the provided ID is present or not. This is done with a simple call to clk_get_by_id(). A non-zero return value indicates that the requested clock is not available. In some cases, clk->dev points to the clock bank device instead of the clock device. This pointer is therefore overwritten in order to reference to the correct device instance. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- drivers/clk/exynos/clk.c | 13 +++++++++++++ drivers/clk/exynos/clk.h | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/drivers/clk/exynos/clk.c b/drivers/clk/exynos/clk.c index a3832981f90..a2c9f4851da 100644 --- a/drivers/clk/exynos/clk.c +++ b/drivers/clk/exynos/clk.c @@ -10,6 +10,19 @@ #include #include "clk.h" +int samsung_clk_request(struct clk *clk) +{ + struct clk *c; + int ret; + + ret = clk_get_by_id(clk->id, &c); + if (ret) + return ret; + + clk->dev = c->dev; + return 0; +} + static void samsung_clk_register_fixed_rate(struct udevice *dev, void __iomem *base, unsigned int cmu_id, diff --git a/drivers/clk/exynos/clk.h b/drivers/clk/exynos/clk.h index e53dcc6a821..c25b7cb59d4 100644 --- a/drivers/clk/exynos/clk.h +++ b/drivers/clk/exynos/clk.h @@ -9,10 +9,13 @@ #ifndef __EXYNOS_CLK_H #define __EXYNOS_CLK_H +#include #include #include #include "clk-pll.h" +int samsung_clk_request(struct clk *clk); + #define _SAMSUNG_CLK_OPS(_name, _cmu) \ static int _name##_of_xlate(struct clk *clk, \ struct ofnode_phandle_args *args) \ @@ -37,6 +40,7 @@ static const struct clk_ops _name##_clk_ops = { \ .enable = ccf_clk_enable, \ .disable = ccf_clk_disable, \ .of_xlate = _name##_of_xlate, \ + .request = samsung_clk_request, \ } /** -- cgit v1.3.1 From 67fea5775b37b53379434377691772602e3064b3 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:51:33 +0530 Subject: clk: exynos: add support for Exynos7870 CMU Introduce a simple clock driver for Exynos7870's CMU blocks, more specifically, CMU_MIF, CMU_FSYS, and CMU_PERI banks. This should be enough to serve U-Boot's minimal requirements. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- drivers/clk/exynos/Kconfig | 7 + drivers/clk/exynos/Makefile | 1 + drivers/clk/exynos/clk-exynos7870.c | 929 ++++++++++++++++++++++++++++++++++++ 3 files changed, 937 insertions(+) create mode 100644 drivers/clk/exynos/clk-exynos7870.c diff --git a/drivers/clk/exynos/Kconfig b/drivers/clk/exynos/Kconfig index 85ce9d6e241..dcecbd51b5b 100644 --- a/drivers/clk/exynos/Kconfig +++ b/drivers/clk/exynos/Kconfig @@ -15,6 +15,13 @@ config CLK_EXYNOS7420 This enables common clock driver support for platforms based on Samsung Exynos7420 SoC. +config CLK_EXYNOS7870 + bool "Clock driver for Samsung's Exynos7870 SoC" + select CLK_CCF + help + This enables common clock driver support for platforms based + on Samsung Exynos7870 SoC. + config CLK_EXYNOS850 bool "Clock driver for Samsung's Exynos850 SoC" select CLK_CCF diff --git a/drivers/clk/exynos/Makefile b/drivers/clk/exynos/Makefile index 77385864fef..f5d27d87bd2 100644 --- a/drivers/clk/exynos/Makefile +++ b/drivers/clk/exynos/Makefile @@ -9,4 +9,5 @@ obj-$(CONFIG_$(PHASE_)CLK_CCF) += clk.o clk-pll.o obj-$(CONFIG_CLK_EXYNOS7420) += clk-exynos7420.o +obj-$(CONFIG_CLK_EXYNOS7870) += clk-exynos7870.o obj-$(CONFIG_CLK_EXYNOS850) += clk-exynos850.o diff --git a/drivers/clk/exynos/clk-exynos7870.c b/drivers/clk/exynos/clk-exynos7870.c new file mode 100644 index 00000000000..d01b1c75350 --- /dev/null +++ b/drivers/clk/exynos/clk-exynos7870.c @@ -0,0 +1,929 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Samsung Exynos7870 clock driver. + * Copyright (C) 2015 Samsung Electronics Co., Ltd. + * Author: Kaustabh Chakraborty + */ + +#include "linux/clk-provider.h" +#include +#include +#include +#include "clk.h" + +enum exynos7870_cmu_id { + CMU_MIF, + CMU_FSYS, + CMU_PERI, +}; + +/* + * Register offsets for CMU_MIF (0x10460000) + */ +#define PLL_LOCKTIME_MIF_MEM_PLL 0x0000 +#define PLL_LOCKTIME_MIF_MEDIA_PLL 0x0020 +#define PLL_LOCKTIME_MIF_BUS_PLL 0x0040 +#define PLL_CON0_MIF_MEM_PLL 0x0100 +#define PLL_CON0_MIF_MEDIA_PLL 0x0120 +#define PLL_CON0_MIF_BUS_PLL 0x0140 +#define CLK_CON_GAT_MIF_MUX_MEM_PLL 0x0200 +#define CLK_CON_GAT_MIF_MUX_MEM_PLL_CON 0x0200 +#define CLK_CON_GAT_MIF_MUX_MEDIA_PLL 0x0204 +#define CLK_CON_GAT_MIF_MUX_MEDIA_PLL_CON 0x0204 +#define CLK_CON_GAT_MIF_MUX_BUS_PLL 0x0208 +#define CLK_CON_GAT_MIF_MUX_BUS_PLL_CON 0x0208 +#define CLK_CON_GAT_MIF_MUX_BUSD 0x0220 +#define CLK_CON_MUX_MIF_BUSD 0x0220 +#define CLK_CON_GAT_MIF_MUX_CMU_ISP_VRA 0x0264 +#define CLK_CON_MUX_MIF_CMU_ISP_VRA 0x0264 +#define CLK_CON_GAT_MIF_MUX_CMU_ISP_CAM 0x0268 +#define CLK_CON_MUX_MIF_CMU_ISP_CAM 0x0268 +#define CLK_CON_GAT_MIF_MUX_CMU_ISP_ISP 0x026c +#define CLK_CON_MUX_MIF_CMU_ISP_ISP 0x026c +#define CLK_CON_GAT_MIF_MUX_CMU_DISPAUD_BUS 0x0270 +#define CLK_CON_MUX_MIF_CMU_DISPAUD_BUS 0x0270 +#define CLK_CON_GAT_MIF_MUX_CMU_DISPAUD_DECON_VCLK 0x0274 +#define CLK_CON_MUX_MIF_CMU_DISPAUD_DECON_VCLK 0x0274 +#define CLK_CON_GAT_MIF_MUX_CMU_DISPAUD_DECON_ECLK 0x0278 +#define CLK_CON_MUX_MIF_CMU_DISPAUD_DECON_ECLK 0x0278 +#define CLK_CON_GAT_MIF_MUX_CMU_MFCMSCL_MSCL 0x027c +#define CLK_CON_MUX_MIF_CMU_MFCMSCL_MSCL 0x027c +#define CLK_CON_GAT_MIF_MUX_CMU_MFCMSCL_MFC 0x0280 +#define CLK_CON_MUX_MIF_CMU_MFCMSCL_MFC 0x0280 +#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_BUS 0x0284 +#define CLK_CON_MUX_MIF_CMU_FSYS_BUS 0x0284 +#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC0 0x0288 +#define CLK_CON_MUX_MIF_CMU_FSYS_MMC0 0x0288 +#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC1 0x028c +#define CLK_CON_MUX_MIF_CMU_FSYS_MMC1 0x028c +#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC2 0x0290 +#define CLK_CON_MUX_MIF_CMU_FSYS_MMC2 0x0290 +#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_USB20DRD_REFCLK 0x029c +#define CLK_CON_MUX_MIF_CMU_FSYS_USB20DRD_REFCLK 0x029c +#define CLK_CON_GAT_MIF_MUX_CMU_PERI_BUS 0x02a0 +#define CLK_CON_MUX_MIF_CMU_PERI_BUS 0x02a0 +#define CLK_CON_GAT_MIF_MUX_CMU_PERI_UART1 0x02a4 +#define CLK_CON_MUX_MIF_CMU_PERI_UART1 0x02a4 +#define CLK_CON_GAT_MIF_MUX_CMU_PERI_UART2 0x02a8 +#define CLK_CON_MUX_MIF_CMU_PERI_UART2 0x02a8 +#define CLK_CON_GAT_MIF_MUX_CMU_PERI_UART0 0x02ac +#define CLK_CON_MUX_MIF_CMU_PERI_UART0 0x02ac +#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI2 0x02b0 +#define CLK_CON_MUX_MIF_CMU_PERI_SPI2 0x02b0 +#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI1 0x02b4 +#define CLK_CON_MUX_MIF_CMU_PERI_SPI1 0x02b4 +#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI0 0x02b8 +#define CLK_CON_MUX_MIF_CMU_PERI_SPI0 0x02b8 +#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI3 0x02bc +#define CLK_CON_MUX_MIF_CMU_PERI_SPI3 0x02bc +#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI4 0x02c0 +#define CLK_CON_MUX_MIF_CMU_PERI_SPI4 0x02c0 +#define CLK_CON_GAT_MIF_MUX_CMU_ISP_SENSOR0 0x02c4 +#define CLK_CON_MUX_MIF_CMU_ISP_SENSOR0 0x02c4 +#define CLK_CON_GAT_MIF_MUX_CMU_ISP_SENSOR1 0x02c8 +#define CLK_CON_MUX_MIF_CMU_ISP_SENSOR1 0x02c8 +#define CLK_CON_GAT_MIF_MUX_CMU_ISP_SENSOR2 0x02cc +#define CLK_CON_MUX_MIF_CMU_ISP_SENSOR2 0x02cc +#define CLK_CON_DIV_MIF_BUSD 0x0420 +#define CLK_CON_DIV_MIF_APB 0x0424 +#define CLK_CON_DIV_MIF_HSI2C 0x0430 +#define CLK_CON_DIV_MIF_CMU_G3D_SWITCH 0x0460 +#define CLK_CON_DIV_MIF_CMU_ISP_VRA 0x0464 +#define CLK_CON_DIV_MIF_CMU_ISP_CAM 0x0468 +#define CLK_CON_DIV_MIF_CMU_ISP_ISP 0x046c +#define CLK_CON_DIV_MIF_CMU_DISPAUD_BUS 0x0470 +#define CLK_CON_DIV_MIF_CMU_DISPAUD_DECON_VCLK 0x0474 +#define CLK_CON_DIV_MIF_CMU_DISPAUD_DECON_ECLK 0x0478 +#define CLK_CON_DIV_MIF_CMU_MFCMSCL_MSCL 0x047c +#define CLK_CON_DIV_MIF_CMU_MFCMSCL_MFC 0x0480 +#define CLK_CON_DIV_MIF_CMU_FSYS_BUS 0x0484 +#define CLK_CON_DIV_MIF_CMU_FSYS_MMC0 0x0488 +#define CLK_CON_DIV_MIF_CMU_FSYS_MMC1 0x048c +#define CLK_CON_DIV_MIF_CMU_FSYS_MMC2 0x0490 +#define CLK_CON_DIV_MIF_CMU_FSYS_USB20DRD_REFCLK 0x049c +#define CLK_CON_DIV_MIF_CMU_PERI_BUS 0x04a0 +#define CLK_CON_DIV_MIF_CMU_PERI_UART1 0x04a4 +#define CLK_CON_DIV_MIF_CMU_PERI_UART2 0x04a8 +#define CLK_CON_DIV_MIF_CMU_PERI_UART0 0x04ac +#define CLK_CON_DIV_MIF_CMU_PERI_SPI2 0x04b0 +#define CLK_CON_DIV_MIF_CMU_PERI_SPI1 0x04b4 +#define CLK_CON_DIV_MIF_CMU_PERI_SPI0 0x04b8 +#define CLK_CON_DIV_MIF_CMU_PERI_SPI3 0x04bc +#define CLK_CON_DIV_MIF_CMU_PERI_SPI4 0x04c0 +#define CLK_CON_DIV_MIF_CMU_ISP_SENSOR0 0x04c4 +#define CLK_CON_DIV_MIF_CMU_ISP_SENSOR1 0x04c8 +#define CLK_CON_DIV_MIF_CMU_ISP_SENSOR2 0x04cc +#define CLK_CON_GAT_MIF_WRAP_ADC_IF_OSC_SYS 0x080c +#define CLK_CON_GAT_MIF_HSI2C_AP_PCLKS 0x0828 +#define CLK_CON_GAT_MIF_HSI2C_CP_PCLKS 0x0828 +#define CLK_CON_GAT_MIF_WRAP_ADC_IF_PCLK_S0 0x0828 +#define CLK_CON_GAT_MIF_WRAP_ADC_IF_PCLK_S1 0x0828 +#define CLK_CON_GAT_MIF_CP_PCLK_HSI2C 0x0840 +#define CLK_CON_GAT_MIF_CP_PCLK_HSI2C_BAT_0 0x0840 +#define CLK_CON_GAT_MIF_CP_PCLK_HSI2C_BAT_1 0x0840 +#define CLK_CON_GAT_MIF_HSI2C_AP_PCLKM 0x0840 +#define CLK_CON_GAT_MIF_HSI2C_CP_PCLKM 0x0840 +#define CLK_CON_GAT_MIF_HSI2C_IPCLK 0x0840 +#define CLK_CON_GAT_MIF_HSI2C_ITCLK 0x0840 +#define CLK_CON_GAT_MIF_CMU_G3D_SWITCH 0x0860 +#define CLK_CON_GAT_MIF_CMU_ISP_VRA 0x0864 +#define CLK_CON_GAT_MIF_CMU_ISP_CAM 0x0868 +#define CLK_CON_GAT_MIF_CMU_ISP_ISP 0x086c +#define CLK_CON_GAT_MIF_CMU_DISPAUD_BUS 0x0870 +#define CLK_CON_GAT_MIF_CMU_DISPAUD_DECON_VCLK 0x0874 +#define CLK_CON_GAT_MIF_CMU_DISPAUD_DECON_ECLK 0x0878 +#define CLK_CON_GAT_MIF_CMU_MFCMSCL_MSCL 0x087c +#define CLK_CON_GAT_MIF_CMU_MFCMSCL_MFC 0x0880 +#define CLK_CON_GAT_MIF_CMU_FSYS_BUS 0x0884 +#define CLK_CON_GAT_MIF_CMU_FSYS_MMC0 0x0888 +#define CLK_CON_GAT_MIF_CMU_FSYS_MMC1 0x088c +#define CLK_CON_GAT_MIF_CMU_FSYS_MMC2 0x0890 +#define CLK_CON_GAT_MIF_CMU_FSYS_USB20DRD_REFCLK 0x089c +#define CLK_CON_GAT_MIF_CMU_PERI_BUS 0x08a0 +#define CLK_CON_GAT_MIF_CMU_PERI_UART1 0x08a4 +#define CLK_CON_GAT_MIF_CMU_PERI_UART2 0x08a8 +#define CLK_CON_GAT_MIF_CMU_PERI_UART0 0x08ac +#define CLK_CON_GAT_MIF_CMU_PERI_SPI2 0x08b0 +#define CLK_CON_GAT_MIF_CMU_PERI_SPI1 0x08b4 +#define CLK_CON_GAT_MIF_CMU_PERI_SPI0 0x08b8 +#define CLK_CON_GAT_MIF_CMU_PERI_SPI3 0x08bc +#define CLK_CON_GAT_MIF_CMU_PERI_SPI4 0x08c0 +#define CLK_CON_GAT_MIF_CMU_ISP_SENSOR0 0x08c4 +#define CLK_CON_GAT_MIF_CMU_ISP_SENSOR1 0x08c8 +#define CLK_CON_GAT_MIF_CMU_ISP_SENSOR2 0x08cc + +static const struct samsung_pll_clock mif_pll_clks[] = { + PLL(pll_1417x, CLK_FOUT_MIF_BUS_PLL, "fout_mif_bus_pll", "oscclk", + PLL_CON0_MIF_BUS_PLL), + PLL(pll_1417x, CLK_FOUT_MIF_MEDIA_PLL, "fout_mif_media_pll", "oscclk", + PLL_CON0_MIF_MEDIA_PLL), + PLL(pll_1417x, CLK_FOUT_MIF_MEM_PLL, "fout_mif_mem_pll", "oscclk", + PLL_CON0_MIF_MEM_PLL), +}; + +static const struct samsung_gate_clock mif_pll_gate_clks[] = { + GATE(CLK_GOUT_MIF_MUX_BUS_PLL_CON, + "gout_mif_mux_bus_pll_con", "fout_mif_bus_pll", + CLK_CON_GAT_MIF_MUX_BUS_PLL_CON, 12, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_MEDIA_PLL_CON, + "gout_mif_mux_media_pll_con", "fout_mif_media_pll", + CLK_CON_GAT_MIF_MUX_MEDIA_PLL_CON, 12, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_MEM_PLL_CON, + "gout_mif_mux_mem_pll_con", "fout_mif_mem_pll", + CLK_CON_GAT_MIF_MUX_MEM_PLL_CON, 12, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_BUS_PLL, + "gout_mif_mux_bus_pll", "gout_mif_mux_bus_pll_con", + CLK_CON_GAT_MIF_MUX_BUS_PLL, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_MEM_PLL, + "gout_mif_mux_mem_pll", "gout_mif_mux_mem_pll_con", + CLK_CON_GAT_MIF_MUX_MEM_PLL, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_MEDIA_PLL, + "gout_mif_mux_media_pll", "gout_mif_mux_media_pll_con", + CLK_CON_GAT_MIF_MUX_MEDIA_PLL, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), +}; + +static const struct samsung_fixed_factor_clock mif_fixed_factor_clks[] = { + FFACTOR(0, "ffac_mif_mux_bus_pll_div2", "gout_mif_mux_bus_pll_con", + 1, 2, 0), + FFACTOR(0, "ffac_mif_mux_media_pll_div2", "gout_mif_mux_media_pll_con", + 1, 2, 0), + FFACTOR(0, "ffac_mif_mux_mem_pll_div2", "gout_mif_mux_mem_pll_con", + 1, 2, 0), +}; + +/* List of parent clocks for muxes in CMU_MIF */ +PNAME(mout_mif_busd_p) = { "ffac_mif_mux_bus_pll_div2", + "ffac_mif_mux_media_pll_div2", + "ffac_mif_mux_mem_pll_div2" }; +PNAME(mout_mif_cmu_fsys_bus_p) = { "ffac_mif_mux_bus_pll_div2", + "ffac_mif_mux_media_pll_div2" }; +PNAME(mout_mif_cmu_fsys_mmc0_p) = { "ffac_mif_mux_bus_pll_div2", + "ffac_mif_mux_media_pll_div2" }; +PNAME(mout_mif_cmu_fsys_mmc1_p) = { "ffac_mif_mux_bus_pll_div2", + "ffac_mif_mux_media_pll_div2" }; +PNAME(mout_mif_cmu_fsys_mmc2_p) = { "ffac_mif_mux_bus_pll_div2", + "ffac_mif_mux_media_pll_div2" }; +PNAME(mout_mif_cmu_fsys_usb20drd_refclk_p) = { "ffac_mif_mux_bus_pll_div2", + "ffac_mif_mux_media_pll_div2" }; +PNAME(mout_mif_cmu_peri_bus_p) = { "ffac_mif_mux_bus_pll_div2", + "ffac_mif_mux_media_pll_div2" }; +PNAME(mout_mif_cmu_peri_spi0_p) = { "ffac_mif_mux_bus_pll_div2", + "oscclk" }; +PNAME(mout_mif_cmu_peri_spi1_p) = { "ffac_mif_mux_bus_pll_div2", + "oscclk" }; +PNAME(mout_mif_cmu_peri_spi2_p) = { "ffac_mif_mux_bus_pll_div2", + "oscclk" }; +PNAME(mout_mif_cmu_peri_spi3_p) = { "ffac_mif_mux_bus_pll_div2", + "oscclk" }; +PNAME(mout_mif_cmu_peri_spi4_p) = { "ffac_mif_mux_bus_pll_div2", + "oscclk" }; +PNAME(mout_mif_cmu_peri_uart2_p) = { "ffac_mif_mux_bus_pll_div2", + "ffac_mif_mux_media_pll_div2" }; +PNAME(mout_mif_cmu_peri_uart0_p) = { "ffac_mif_mux_bus_pll_div2", + "ffac_mif_mux_media_pll_div2" }; +PNAME(mout_mif_cmu_peri_uart1_p) = { "ffac_mif_mux_bus_pll_div2", + "ffac_mif_mux_media_pll_div2" }; + +static const struct samsung_mux_clock mif_mux_clks[] = { + MUX(CLK_MOUT_MIF_BUSD, + "mout_mif_busd", mout_mif_busd_p, + CLK_CON_MUX_MIF_BUSD, 12, 2), + MUX(CLK_MOUT_MIF_CMU_FSYS_BUS, + "mout_mif_cmu_fsys_bus", mout_mif_cmu_fsys_bus_p, + CLK_CON_MUX_MIF_CMU_FSYS_BUS, 12, 1), + MUX(CLK_MOUT_MIF_CMU_FSYS_MMC0, + "mout_mif_cmu_fsys_mmc0", mout_mif_cmu_fsys_mmc0_p, + CLK_CON_MUX_MIF_CMU_FSYS_MMC0, 12, 1), + MUX(CLK_MOUT_MIF_CMU_FSYS_MMC1, + "mout_mif_cmu_fsys_mmc1", mout_mif_cmu_fsys_mmc1_p, + CLK_CON_MUX_MIF_CMU_FSYS_MMC1, 12, 1), + MUX(CLK_MOUT_MIF_CMU_FSYS_MMC2, + "mout_mif_cmu_fsys_mmc2", mout_mif_cmu_fsys_mmc2_p, + CLK_CON_MUX_MIF_CMU_FSYS_MMC2, 12, 1), + MUX(CLK_MOUT_MIF_CMU_FSYS_USB20DRD_REFCLK, + "mout_mif_cmu_fsys_usb20drd_refclk", mout_mif_cmu_fsys_usb20drd_refclk_p, + CLK_CON_MUX_MIF_CMU_FSYS_USB20DRD_REFCLK, 12, 1), + MUX(CLK_MOUT_MIF_CMU_PERI_BUS, + "mout_mif_cmu_peri_bus", mout_mif_cmu_peri_bus_p, + CLK_CON_MUX_MIF_CMU_PERI_BUS, 12, 1), + MUX(CLK_MOUT_MIF_CMU_PERI_SPI0, + "mout_mif_cmu_peri_spi0", mout_mif_cmu_peri_spi0_p, + CLK_CON_MUX_MIF_CMU_PERI_SPI0, 12, 1), + MUX(CLK_MOUT_MIF_CMU_PERI_SPI1, + "mout_mif_cmu_peri_spi1", mout_mif_cmu_peri_spi1_p, + CLK_CON_MUX_MIF_CMU_PERI_SPI1, 12, 1), + MUX(CLK_MOUT_MIF_CMU_PERI_SPI2, + "mout_mif_cmu_peri_spi2", mout_mif_cmu_peri_spi2_p, + CLK_CON_MUX_MIF_CMU_PERI_SPI2, 12, 1), + MUX(CLK_MOUT_MIF_CMU_PERI_SPI3, + "mout_mif_cmu_peri_spi3", mout_mif_cmu_peri_spi3_p, + CLK_CON_MUX_MIF_CMU_PERI_SPI3, 12, 1), + MUX(CLK_MOUT_MIF_CMU_PERI_SPI4, + "mout_mif_cmu_peri_spi4", mout_mif_cmu_peri_spi4_p, + CLK_CON_MUX_MIF_CMU_PERI_SPI4, 12, 1), + MUX(CLK_MOUT_MIF_CMU_PERI_UART0, + "mout_mif_cmu_peri_uart0", mout_mif_cmu_peri_uart0_p, + CLK_CON_MUX_MIF_CMU_PERI_UART0, 12, 1), + MUX(CLK_MOUT_MIF_CMU_PERI_UART1, + "mout_mif_cmu_peri_uart1", mout_mif_cmu_peri_uart1_p, + CLK_CON_MUX_MIF_CMU_PERI_UART1, 12, 1), + MUX(CLK_MOUT_MIF_CMU_PERI_UART2, + "mout_mif_cmu_peri_uart2", mout_mif_cmu_peri_uart2_p, + CLK_CON_MUX_MIF_CMU_PERI_UART2, 12, 1), +}; + +static const struct samsung_gate_clock mif_mux_gate_clks[] = { + GATE(CLK_GOUT_MIF_MUX_BUSD, + "gout_mif_mux_busd", "mout_mif_busd", + CLK_CON_GAT_MIF_MUX_BUSD, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_BUS, + "gout_mif_mux_cmu_fsys_bus", "mout_mif_cmu_fsys_bus", + CLK_CON_GAT_MIF_MUX_CMU_FSYS_BUS, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_MMC0, + "gout_mif_mux_cmu_fsys_mmc0", "mout_mif_cmu_fsys_mmc0", + CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC0, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_MMC1, + "gout_mif_mux_cmu_fsys_mmc1", "mout_mif_cmu_fsys_mmc1", + CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC1, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_MMC2, + "gout_mif_mux_cmu_fsys_mmc2", "mout_mif_cmu_fsys_mmc2", + CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC2, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_USB20DRD_REFCLK, + "gout_mif_mux_cmu_fsys_usb20drd_refclk", "mout_mif_cmu_fsys_usb20drd_refclk", + CLK_CON_GAT_MIF_MUX_CMU_FSYS_USB20DRD_REFCLK, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_PERI_BUS, + "gout_mif_mux_cmu_peri_bus", "mout_mif_cmu_peri_bus", + CLK_CON_GAT_MIF_MUX_CMU_PERI_BUS, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI0, + "gout_mif_mux_cmu_peri_spi0", "mout_mif_cmu_peri_spi0", + CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI0, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI1, + "gout_mif_mux_cmu_peri_spi1", "mout_mif_cmu_peri_spi1", + CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI1, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI2, + "gout_mif_mux_cmu_peri_spi2", "mout_mif_cmu_peri_spi2", + CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI2, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI3, + "gout_mif_mux_cmu_peri_spi3", "mout_mif_cmu_peri_spi3", + CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI3, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI4, + "gout_mif_mux_cmu_peri_spi4", "mout_mif_cmu_peri_spi4", + CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI4, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_PERI_UART0, + "gout_mif_mux_cmu_peri_uart0", "mout_mif_cmu_peri_uart0", + CLK_CON_GAT_MIF_MUX_CMU_PERI_UART0, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_PERI_UART1, + "gout_mif_mux_cmu_peri_uart1", "mout_mif_cmu_peri_uart1", + CLK_CON_GAT_MIF_MUX_CMU_PERI_UART1, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_MUX_CMU_PERI_UART2, + "gout_mif_mux_cmu_peri_uart2", "mout_mif_cmu_peri_uart2", + CLK_CON_GAT_MIF_MUX_CMU_PERI_UART2, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), +}; + +static const struct samsung_div_clock mif_div_clks[] = { + DIV(CLK_DOUT_MIF_HSI2C, + "dout_mif_hsi2c", "ffac_mif_mux_media_pll_div2", + CLK_CON_DIV_MIF_HSI2C, 0, 4), + DIV(CLK_DOUT_MIF_BUSD, + "dout_mif_busd", "gout_mif_mux_busd", + CLK_CON_DIV_MIF_BUSD, 0, 4), + DIV(CLK_DOUT_MIF_CMU_FSYS_BUS, + "dout_mif_cmu_fsys_bus", "gout_mif_mux_cmu_fsys_bus", + CLK_CON_DIV_MIF_CMU_FSYS_BUS, 0, 4), + DIV(CLK_DOUT_MIF_CMU_FSYS_MMC0, + "dout_mif_cmu_fsys_mmc0", "gout_mif_mux_cmu_fsys_mmc0", + CLK_CON_DIV_MIF_CMU_FSYS_MMC0, 0, 10), + DIV(CLK_DOUT_MIF_CMU_FSYS_MMC1, + "dout_mif_cmu_fsys_mmc1", "gout_mif_mux_cmu_fsys_mmc1", + CLK_CON_DIV_MIF_CMU_FSYS_MMC1, 0, 10), + DIV(CLK_DOUT_MIF_CMU_FSYS_MMC2, + "dout_mif_cmu_fsys_mmc2", "gout_mif_mux_cmu_fsys_mmc2", + CLK_CON_DIV_MIF_CMU_FSYS_MMC2, 0, 10), + DIV(CLK_DOUT_MIF_CMU_FSYS_USB20DRD_REFCLK, + "dout_mif_cmu_fsys_usb20drd_refclk", "gout_mif_mux_cmu_fsys_usb20drd_refclk", + CLK_CON_DIV_MIF_CMU_FSYS_USB20DRD_REFCLK, 0, 4), + DIV(CLK_DOUT_MIF_CMU_PERI_BUS, + "dout_mif_cmu_peri_bus", "gout_mif_mux_cmu_peri_bus", + CLK_CON_DIV_MIF_CMU_PERI_BUS, 0, 4), + DIV(CLK_DOUT_MIF_CMU_PERI_SPI0, + "dout_mif_cmu_peri_spi0", "gout_mif_mux_cmu_peri_spi0", + CLK_CON_DIV_MIF_CMU_PERI_SPI0, 0, 6), + DIV(CLK_DOUT_MIF_CMU_PERI_SPI1, + "dout_mif_cmu_peri_spi1", "gout_mif_mux_cmu_peri_spi1", + CLK_CON_DIV_MIF_CMU_PERI_SPI1, 0, 6), + DIV(CLK_DOUT_MIF_CMU_PERI_SPI2, + "dout_mif_cmu_peri_spi2", "gout_mif_mux_cmu_peri_spi2", + CLK_CON_DIV_MIF_CMU_PERI_SPI2, 0, 6), + DIV(CLK_DOUT_MIF_CMU_PERI_SPI3, + "dout_mif_cmu_peri_spi3", "gout_mif_mux_cmu_peri_spi3", + CLK_CON_DIV_MIF_CMU_PERI_SPI3, 0, 6), + DIV(CLK_DOUT_MIF_CMU_PERI_SPI4, + "dout_mif_cmu_peri_spi4", "gout_mif_mux_cmu_peri_spi4", + CLK_CON_DIV_MIF_CMU_PERI_SPI4, 0, 6), + DIV(CLK_DOUT_MIF_CMU_PERI_UART0, + "dout_mif_cmu_peri_uart0", "gout_mif_mux_cmu_peri_uart0", + CLK_CON_DIV_MIF_CMU_PERI_UART0, 0, 4), + DIV(CLK_DOUT_MIF_CMU_PERI_UART1, + "dout_mif_cmu_peri_uart1", "gout_mif_mux_cmu_peri_uart1", + CLK_CON_DIV_MIF_CMU_PERI_UART1, 0, 4), + DIV(CLK_DOUT_MIF_CMU_PERI_UART2, + "dout_mif_cmu_peri_uart2", "gout_mif_mux_cmu_peri_uart2", + CLK_CON_DIV_MIF_CMU_PERI_UART2, 0, 4), + DIV(CLK_DOUT_MIF_APB, + "dout_mif_apb", "dout_mif_busd", + CLK_CON_DIV_MIF_APB, 0, 2), +}; + +static const struct samsung_gate_clock mif_gate_clks[] = { + GATE(CLK_GOUT_MIF_WRAP_ADC_IF_OSC_SYS, + "gout_mif_wrap_adc_if_osc_sys", "oscclk", + CLK_CON_GAT_MIF_WRAP_ADC_IF_OSC_SYS, 3, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_HSI2C_AP_PCLKS, + "gout_mif_hsi2c_ap_pclks", "dout_mif_apb", + CLK_CON_GAT_MIF_HSI2C_AP_PCLKS, 14, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_HSI2C_CP_PCLKS, + "gout_mif_hsi2c_cp_pclks", "dout_mif_apb", + CLK_CON_GAT_MIF_HSI2C_CP_PCLKS, 15, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_WRAP_ADC_IF_PCLK_S0, + "gout_mif_wrap_adc_if_pclk_s0", "dout_mif_apb", + CLK_CON_GAT_MIF_WRAP_ADC_IF_PCLK_S0, 20, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_WRAP_ADC_IF_PCLK_S1, + "gout_mif_wrap_adc_if_pclk_s1", "dout_mif_apb", + CLK_CON_GAT_MIF_WRAP_ADC_IF_PCLK_S1, 21, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_FSYS_BUS, + "gout_mif_cmu_fsys_bus", "dout_mif_cmu_fsys_bus", + CLK_CON_GAT_MIF_CMU_FSYS_BUS, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_FSYS_MMC0, + "gout_mif_cmu_fsys_mmc0", "dout_mif_cmu_fsys_mmc0", + CLK_CON_GAT_MIF_CMU_FSYS_MMC0, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_FSYS_MMC1, + "gout_mif_cmu_fsys_mmc1", "dout_mif_cmu_fsys_mmc1", + CLK_CON_GAT_MIF_CMU_FSYS_MMC1, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_FSYS_MMC2, + "gout_mif_cmu_fsys_mmc2", "dout_mif_cmu_fsys_mmc2", + CLK_CON_GAT_MIF_CMU_FSYS_MMC2, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_FSYS_USB20DRD_REFCLK, + "gout_mif_cmu_fsys_usb20drd_refclk", "dout_mif_cmu_fsys_usb20drd_refclk", + CLK_CON_GAT_MIF_CMU_FSYS_USB20DRD_REFCLK, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_PERI_BUS, + "gout_mif_cmu_peri_bus", "dout_mif_cmu_peri_bus", + CLK_CON_GAT_MIF_CMU_PERI_BUS, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_PERI_SPI0, + "gout_mif_cmu_peri_spi0", "dout_mif_cmu_peri_spi0", + CLK_CON_GAT_MIF_CMU_PERI_SPI0, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_PERI_SPI1, + "gout_mif_cmu_peri_spi1", "dout_mif_cmu_peri_spi1", + CLK_CON_GAT_MIF_CMU_PERI_SPI1, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_PERI_SPI2, + "gout_mif_cmu_peri_spi2", "dout_mif_cmu_peri_spi2", + CLK_CON_GAT_MIF_CMU_PERI_SPI2, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_PERI_SPI3, + "gout_mif_cmu_peri_spi3", "dout_mif_cmu_peri_spi3", + CLK_CON_GAT_MIF_CMU_PERI_SPI3, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_PERI_SPI4, + "gout_mif_cmu_peri_spi4", "dout_mif_cmu_peri_spi4", + CLK_CON_GAT_MIF_CMU_PERI_SPI4, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_PERI_UART0, + "gout_mif_cmu_peri_uart0", "dout_mif_cmu_peri_uart0", + CLK_CON_GAT_MIF_CMU_PERI_UART0, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_PERI_UART1, + "gout_mif_cmu_peri_uart1", "dout_mif_cmu_peri_uart1", + CLK_CON_GAT_MIF_CMU_PERI_UART1, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CMU_PERI_UART2, + "gout_mif_cmu_peri_uart2", "dout_mif_cmu_peri_uart2", + CLK_CON_GAT_MIF_CMU_PERI_UART2, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CP_PCLK_HSI2C, + "gout_mif_cp_pclk_hsi2c", "dout_mif_hsi2c", + CLK_CON_GAT_MIF_CP_PCLK_HSI2C, 6, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CP_PCLK_HSI2C_BAT_0, + "gout_mif_cp_pclk_hsi2c_bat_0", "dout_mif_hsi2c", + CLK_CON_GAT_MIF_CP_PCLK_HSI2C_BAT_0, 4, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_CP_PCLK_HSI2C_BAT_1, + "gout_mif_cp_pclk_hsi2c_bat_1", "dout_mif_hsi2c", + CLK_CON_GAT_MIF_CP_PCLK_HSI2C_BAT_1, 5, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_HSI2C_AP_PCLKM, + "gout_mif_hsi2c_ap_pclkm", "dout_mif_hsi2c", + CLK_CON_GAT_MIF_HSI2C_AP_PCLKM, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_HSI2C_CP_PCLKM, + "gout_mif_hsi2c_cp_pclkm", "dout_mif_hsi2c", + CLK_CON_GAT_MIF_HSI2C_CP_PCLKM, 1, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_HSI2C_IPCLK, + "gout_mif_hsi2c_ipclk", "dout_mif_hsi2c", + CLK_CON_GAT_MIF_HSI2C_IPCLK, 2, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_MIF_HSI2C_ITCLK, + "gout_mif_hsi2c_itclk", "dout_mif_hsi2c", + CLK_CON_GAT_MIF_HSI2C_ITCLK, 3, + CLK_SET_RATE_PARENT, 0), +}; + +static const struct samsung_clk_group mif_cmu_clks[] = { + { S_CLK_PLL, mif_pll_clks, ARRAY_SIZE(mif_pll_clks) }, + { S_CLK_GATE, mif_pll_gate_clks, ARRAY_SIZE(mif_pll_gate_clks) }, + { S_CLK_FFACTOR, mif_fixed_factor_clks, ARRAY_SIZE(mif_fixed_factor_clks) }, + { S_CLK_MUX, mif_mux_clks, ARRAY_SIZE(mif_mux_clks) }, + { S_CLK_GATE, mif_mux_gate_clks, ARRAY_SIZE(mif_mux_gate_clks) }, + { S_CLK_DIV, mif_div_clks, ARRAY_SIZE(mif_div_clks) }, + { S_CLK_GATE, mif_gate_clks, ARRAY_SIZE(mif_gate_clks) }, +}; + +static int exynos7870_cmu_mif_probe(struct udevice *dev) +{ + return samsung_register_cmu(dev, CMU_MIF, mif_cmu_clks, + exynos7870_cmu_mif); +} + +static const struct udevice_id exynos7870_cmu_mif_ids[] = { + { .compatible = "samsung,exynos7870-cmu-mif" }, + { } +}; + +SAMSUNG_CLK_OPS(exynos7870_cmu_mif, CMU_MIF); + +U_BOOT_DRIVER(exynos7870_cmu_mif) = { + .name = "exynos7870-cmu-mif", + .id = UCLASS_CLK, + .of_match = exynos7870_cmu_mif_ids, + .ops = &exynos7870_cmu_mif_clk_ops, + .probe = exynos7870_cmu_mif_probe, + .flags = DM_FLAG_PRE_RELOC, +}; + +/* + * Register offsets for CMU_FSYS (0x13730000) + */ +#define PLL_LOCKTIME_FSYS_USB_PLL 0x0000 +#define PLL_CON0_FSYS_USB_PLL 0x0100 +#define CLK_CON_GAT_FSYS_MUX_USB_PLL 0x0200 +#define CLK_CON_GAT_FSYS_MUX_USB_PLL_CON 0x0200 +#define CLK_CON_GAT_FSYS_MUX_USB20DRD_PHYCLOCK_USER 0x0230 +#define CLK_CON_GAT_FSYS_MUX_USB20DRD_PHYCLOCK_USER_CON 0x0230 +#define CLK_CON_GAT_FSYS_BUSP3_HCLK 0x0804 +#define CLK_CON_GAT_FSYS_MMC0_ACLK 0x0804 +#define CLK_CON_GAT_FSYS_MMC1_ACLK 0x0804 +#define CLK_CON_GAT_FSYS_MMC2_ACLK 0x0804 +#define CLK_CON_GAT_FSYS_PDMA0_ACLK_PDMA0 0x0804 +#define CLK_CON_GAT_FSYS_PPMU_ACLK 0x0804 +#define CLK_CON_GAT_FSYS_PPMU_PCLK 0x0804 +#define CLK_CON_GAT_FSYS_SROMC_HCLK 0x0804 +#define CLK_CON_GAT_FSYS_UPSIZER_BUS1_ACLK 0x0804 +#define CLK_CON_GAT_FSYS_USB20DRD_ACLK_HSDRD 0x0804 +#define CLK_CON_GAT_FSYS_USB20DRD_HCLK_USB20_CTRL 0x0804 +#define CLK_CON_GAT_FSYS_USB20DRD_HSDRD_REF_CLK 0x0828 + +static const struct samsung_fixed_rate_clock fsys_fixed_rate_clks[] = { + FRATE(0, "frat_fsys_usb20drd_phyclock", 60000000), +}; + +static const struct samsung_pll_clock fsys_pll_clks[] = { + PLL(pll_1417x, CLK_FOUT_FSYS_USB_PLL, "fout_fsys_usb_pll", "oscclk", + PLL_CON0_FSYS_USB_PLL), +}; + +static const struct samsung_gate_clock fsys_gate_clks[] = { + GATE(CLK_GOUT_FSYS_BUSP3_HCLK, + "gout_fsys_busp3_hclk", "bus", + CLK_CON_GAT_FSYS_BUSP3_HCLK, 2, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_UPSIZER_BUS1_ACLK, + "gout_fsys_upsizer_bus1_aclk", "bus", + CLK_CON_GAT_FSYS_UPSIZER_BUS1_ACLK, 12, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_PPMU_ACLK, + "gout_fsys_ppmu_aclk", "bus", + CLK_CON_GAT_FSYS_PPMU_ACLK, 17, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_PPMU_PCLK, + "gout_fsys_ppmu_pclk", "bus", + CLK_CON_GAT_FSYS_PPMU_PCLK, 18, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_USB20DRD_HSDRD_REF_CLK, + "gout_fsys_usb20drd_hsdrd_ref_clk", "usb20drd", + CLK_CON_GAT_FSYS_USB20DRD_HSDRD_REF_CLK, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_MUX_USB20DRD_PHYCLOCK_USER_CON, + "gout_fsys_mux_usb20drd_phyclock_user_con", "frat_fsys_usb20drd_phyclock", + CLK_CON_GAT_FSYS_MUX_USB20DRD_PHYCLOCK_USER_CON, 12, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_MUX_USB_PLL_CON, + "gout_fsys_mux_usb_pll_con", "fout_fsys_usb_pll", + CLK_CON_GAT_FSYS_MUX_USB_PLL_CON, 12, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_MMC0_ACLK, + "gout_fsys_mmc0_aclk", "gout_fsys_busp3_hclk", + CLK_CON_GAT_FSYS_MMC0_ACLK, 8, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_MMC1_ACLK, + "gout_fsys_mmc1_aclk", "gout_fsys_busp3_hclk", + CLK_CON_GAT_FSYS_MMC1_ACLK, 9, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_MMC2_ACLK, + "gout_fsys_mmc2_aclk", "gout_fsys_busp3_hclk", + CLK_CON_GAT_FSYS_MMC2_ACLK, 10, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_USB20DRD_ACLK_HSDRD, + "gout_fsys_usb20drd_aclk_hsdrd", "gout_fsys_busp3_hclk", + CLK_CON_GAT_FSYS_USB20DRD_ACLK_HSDRD, 20, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_SROMC_HCLK, + "gout_fsys_sromc_hclk", "gout_fsys_busp3_hclk", + CLK_CON_GAT_FSYS_SROMC_HCLK, 6, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_USB20DRD_HCLK_USB20_CTRL, + "gout_fsys_usb20drd_hclk_usb20_ctrl", "gout_fsys_busp3_hclk", + CLK_CON_GAT_FSYS_USB20DRD_HCLK_USB20_CTRL, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_MUX_USB_PLL, + "gout_fsys_mux_usb_pll", "gout_fsys_mux_usb_pll_con", + CLK_CON_GAT_FSYS_MUX_USB_PLL, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_MUX_USB20DRD_PHYCLOCK_USER, + "gout_fsys_mux_usb20drd_phyclock_user", "gout_fsys_mux_usb20drd_phyclock_user_con", + CLK_CON_GAT_FSYS_MUX_USB20DRD_PHYCLOCK_USER, 21, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_PDMA0_ACLK_PDMA0, + "gout_fsys_pdma0_aclk_pdma0", "gout_fsys_upsizer_bus1_aclk", + CLK_CON_GAT_FSYS_PDMA0_ACLK_PDMA0, 7, + CLK_SET_RATE_PARENT, 0), +}; + +static const struct samsung_clk_group fsys_cmu_clks[] = { + { S_CLK_FRATE, fsys_fixed_rate_clks, ARRAY_SIZE(fsys_fixed_rate_clks) }, + { S_CLK_PLL, fsys_pll_clks, ARRAY_SIZE(fsys_pll_clks) }, + { S_CLK_GATE, fsys_gate_clks, ARRAY_SIZE(fsys_gate_clks) }, +}; + +static int exynos7870_cmu_fsys_probe(struct udevice *dev) +{ + return samsung_register_cmu(dev, CMU_FSYS, fsys_cmu_clks, + exynos7870_cmu_fsys); +} + +static const struct udevice_id exynos7870_cmu_fsys_ids[] = { + { .compatible = "samsung,exynos7870-cmu-fsys" }, + { } +}; + +SAMSUNG_CLK_OPS(exynos7870_cmu_fsys, CMU_FSYS); + +U_BOOT_DRIVER(exynos7870_cmu_fsys) = { + .name = "exynos7870-cmu-fsys", + .id = UCLASS_CLK, + .of_match = exynos7870_cmu_fsys_ids, + .ops = &exynos7870_cmu_fsys_clk_ops, + .probe = exynos7870_cmu_fsys_probe, + .flags = DM_FLAG_PRE_RELOC, +}; + +/* + * Register offsets for CMU_PERI (0x101f0000) + */ +#define CLK_CON_GAT_PERI_PWM_MOTOR_OSCCLK 0x0800 +#define CLK_CON_GAT_PERI_TMU_CLK 0x0800 +#define CLK_CON_GAT_PERI_TMU_CPUCL0_CLK 0x0800 +#define CLK_CON_GAT_PERI_TMU_CPUCL1_CLK 0x0800 +#define CLK_CON_GAT_PERI_BUSP1_PERIC0_HCLK 0x0810 +#define CLK_CON_GAT_PERI_GPIO2_PCLK 0x0810 +#define CLK_CON_GAT_PERI_GPIO5_PCLK 0x0810 +#define CLK_CON_GAT_PERI_GPIO6_PCLK 0x0810 +#define CLK_CON_GAT_PERI_GPIO7_PCLK 0x0810 +#define CLK_CON_GAT_PERI_HSI2C1_IPCLK 0x0810 +#define CLK_CON_GAT_PERI_HSI2C2_IPCLK 0x0810 +#define CLK_CON_GAT_PERI_HSI2C3_IPCLK 0x0810 +#define CLK_CON_GAT_PERI_HSI2C4_IPCLK 0x0810 +#define CLK_CON_GAT_PERI_HSI2C5_IPCLK 0x0810 +#define CLK_CON_GAT_PERI_HSI2C6_IPCLK 0x0810 +#define CLK_CON_GAT_PERI_I2C0_PCLK 0x0810 +#define CLK_CON_GAT_PERI_I2C1_PCLK 0x0810 +#define CLK_CON_GAT_PERI_I2C2_PCLK 0x0810 +#define CLK_CON_GAT_PERI_I2C3_PCLK 0x0810 +#define CLK_CON_GAT_PERI_I2C4_PCLK 0x0810 +#define CLK_CON_GAT_PERI_I2C5_PCLK 0x0810 +#define CLK_CON_GAT_PERI_I2C6_PCLK 0x0810 +#define CLK_CON_GAT_PERI_I2C7_PCLK 0x0810 +#define CLK_CON_GAT_PERI_I2C8_PCLK 0x0810 +#define CLK_CON_GAT_PERI_MCT_PCLK 0x0810 +#define CLK_CON_GAT_PERI_PWM_MOTOR_PCLK_S0 0x0810 +#define CLK_CON_GAT_PERI_SFRIF_TMU_CPUCL0_PCLK 0x0814 +#define CLK_CON_GAT_PERI_SFRIF_TMU_CPUCL1_PCLK 0x0814 +#define CLK_CON_GAT_PERI_SFRIF_TMU_PCLK 0x0814 +#define CLK_CON_GAT_PERI_SPI0_PCLK 0x0814 +#define CLK_CON_GAT_PERI_SPI1_PCLK 0x0814 +#define CLK_CON_GAT_PERI_SPI2_PCLK 0x0814 +#define CLK_CON_GAT_PERI_SPI3_PCLK 0x0814 +#define CLK_CON_GAT_PERI_SPI4_PCLK 0x0814 +#define CLK_CON_GAT_PERI_UART0_PCLK 0x0814 +#define CLK_CON_GAT_PERI_UART1_PCLK 0x0814 +#define CLK_CON_GAT_PERI_UART2_PCLK 0x0814 +#define CLK_CON_GAT_PERI_WDT_CPUCL0_PCLK 0x0814 +#define CLK_CON_GAT_PERI_WDT_CPUCL1_PCLK 0x0814 +#define CLK_CON_GAT_PERI_UART1_EXT_UCLK 0x0830 +#define CLK_CON_GAT_PERI_UART2_EXT_UCLK 0x0834 +#define CLK_CON_GAT_PERI_UART0_EXT_UCLK 0x0838 +#define CLK_CON_GAT_PERI_SPI2_SPI_EXT_CLK 0x083c +#define CLK_CON_GAT_PERI_SPI1_SPI_EXT_CLK 0x0840 +#define CLK_CON_GAT_PERI_SPI0_SPI_EXT_CLK 0x0844 +#define CLK_CON_GAT_PERI_SPI3_SPI_EXT_CLK 0x0848 +#define CLK_CON_GAT_PERI_SPI4_SPI_EXT_CLK 0x084c + +static const struct samsung_gate_clock peri_gate_clks[] = { + GATE(CLK_GOUT_PERI_PWM_MOTOR_OSCCLK, + "gout_peri_pwm_motor_oscclk", "oscclk", + CLK_CON_GAT_PERI_PWM_MOTOR_OSCCLK, 2, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_TMU_CLK, + "gout_peri_tmu_clk", "oscclk", + CLK_CON_GAT_PERI_TMU_CLK, 6, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_TMU_CPUCL0_CLK, + "gout_peri_tmu_cpucl0_clk", "oscclk", + CLK_CON_GAT_PERI_TMU_CPUCL0_CLK, 4, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_TMU_CPUCL1_CLK, + "gout_peri_tmu_cpucl1_clk", "oscclk", + CLK_CON_GAT_PERI_TMU_CPUCL1_CLK, 5, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_BUSP1_PERIC0_HCLK, + "gout_peri_busp1_peric0_hclk", "bus", + CLK_CON_GAT_PERI_BUSP1_PERIC0_HCLK, 3, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_GPIO2_PCLK, + "gout_peri_gpio2_pclk", "bus", + CLK_CON_GAT_PERI_GPIO2_PCLK, 7, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_GPIO5_PCLK, + "gout_peri_gpio5_pclk", "bus", + CLK_CON_GAT_PERI_GPIO5_PCLK, 8, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_GPIO6_PCLK, + "gout_peri_gpio6_pclk", "bus", + CLK_CON_GAT_PERI_GPIO6_PCLK, 9, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_GPIO7_PCLK, + "gout_peri_gpio7_pclk", "bus", + CLK_CON_GAT_PERI_GPIO7_PCLK, 10, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_HSI2C5_IPCLK, + "gout_peri_hsi2c5_ipclk", "bus", + CLK_CON_GAT_PERI_HSI2C5_IPCLK, 15, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_HSI2C6_IPCLK, + "gout_peri_hsi2c6_ipclk", "bus", + CLK_CON_GAT_PERI_HSI2C6_IPCLK, 16, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_MCT_PCLK, + "gout_peri_mct_pclk", "bus", + CLK_CON_GAT_PERI_MCT_PCLK, 26, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_PWM_MOTOR_PCLK_S0, + "gout_peri_pwm_motor_pclk_s0", "bus", + CLK_CON_GAT_PERI_PWM_MOTOR_PCLK_S0, 29, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SFRIF_TMU_CPUCL0_PCLK, + "gout_peri_sfrif_tmu_cpucl0_pclk", "bus", + CLK_CON_GAT_PERI_SFRIF_TMU_CPUCL0_PCLK, 1, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SFRIF_TMU_CPUCL1_PCLK, + "gout_peri_sfrif_tmu_cpucl1_pclk", "bus", + CLK_CON_GAT_PERI_SFRIF_TMU_CPUCL1_PCLK, 2, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SFRIF_TMU_PCLK, + "gout_peri_sfrif_tmu_pclk", "bus", + CLK_CON_GAT_PERI_SFRIF_TMU_PCLK, 3, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SPI0_PCLK, + "gout_peri_spi0_pclk", "bus", + CLK_CON_GAT_PERI_SPI0_PCLK, 6, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SPI1_PCLK, + "gout_peri_spi1_pclk", "bus", + CLK_CON_GAT_PERI_SPI1_PCLK, 5, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SPI2_PCLK, + "gout_peri_spi2_pclk", "bus", + CLK_CON_GAT_PERI_SPI2_PCLK, 4, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SPI3_PCLK, + "gout_peri_spi3_pclk", "bus", + CLK_CON_GAT_PERI_SPI3_PCLK, 7, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SPI4_PCLK, + "gout_peri_spi4_pclk", "bus", + CLK_CON_GAT_PERI_SPI4_PCLK, 8, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_WDT_CPUCL0_PCLK, + "gout_peri_wdt_cpucl0_pclk", "bus", + CLK_CON_GAT_PERI_WDT_CPUCL0_PCLK, 13, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_WDT_CPUCL1_PCLK, + "gout_peri_wdt_cpucl1_pclk", "bus", + CLK_CON_GAT_PERI_WDT_CPUCL1_PCLK, 14, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SPI0_SPI_EXT_CLK, + "gout_peri_spi0_spi_ext_clk", "spi0", + CLK_CON_GAT_PERI_SPI0_SPI_EXT_CLK, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SPI1_SPI_EXT_CLK, + "gout_peri_spi1_spi_ext_clk", "spi1", + CLK_CON_GAT_PERI_SPI1_SPI_EXT_CLK, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SPI2_SPI_EXT_CLK, + "gout_peri_spi2_spi_ext_clk", "spi2", + CLK_CON_GAT_PERI_SPI2_SPI_EXT_CLK, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SPI3_SPI_EXT_CLK, + "gout_peri_spi3_spi_ext_clk", "spi3", + CLK_CON_GAT_PERI_SPI3_SPI_EXT_CLK, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SPI4_SPI_EXT_CLK, + "gout_peri_spi4_spi_ext_clk", "spi4", + CLK_CON_GAT_PERI_SPI4_SPI_EXT_CLK, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_UART0_EXT_UCLK, + "gout_peri_uart0_ext_uclk", "uart0", + CLK_CON_GAT_PERI_UART0_EXT_UCLK, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_UART1_EXT_UCLK, + "gout_peri_uart1_ext_uclk", "uart1", + CLK_CON_GAT_PERI_UART1_EXT_UCLK, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_UART2_EXT_UCLK, + "gout_peri_uart2_ext_uclk", "uart2", + CLK_CON_GAT_PERI_UART2_EXT_UCLK, 0, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_HSI2C1_IPCLK, + "gout_peri_hsi2c1_ipclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_HSI2C1_IPCLK, 11, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_HSI2C2_IPCLK, + "gout_peri_hsi2c2_ipclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_HSI2C2_IPCLK, 12, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_HSI2C3_IPCLK, + "gout_peri_hsi2c3_ipclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_HSI2C3_IPCLK, 13, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_HSI2C4_IPCLK, + "gout_peri_hsi2c4_ipclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_HSI2C4_IPCLK, 14, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_I2C0_PCLK, + "gout_peri_i2c0_pclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_I2C0_PCLK, 21, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_I2C1_PCLK, + "gout_peri_i2c1_pclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_I2C1_PCLK, 23, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_I2C2_PCLK, + "gout_peri_i2c2_pclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_I2C2_PCLK, 22, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_I2C3_PCLK, + "gout_peri_i2c3_pclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_I2C3_PCLK, 20, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_I2C4_PCLK, + "gout_peri_i2c4_pclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_I2C4_PCLK, 17, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_I2C5_PCLK, + "gout_peri_i2c5_pclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_I2C5_PCLK, 18, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_I2C6_PCLK, + "gout_peri_i2c6_pclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_I2C6_PCLK, 19, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_I2C7_PCLK, + "gout_peri_i2c7_pclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_I2C7_PCLK, 24, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_I2C8_PCLK, + "gout_peri_i2c8_pclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_I2C8_PCLK, 25, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_UART0_PCLK, + "gout_peri_uart0_pclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_UART0_PCLK, 10, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_UART1_PCLK, + "gout_peri_uart1_pclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_UART1_PCLK, 11, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_UART2_PCLK, + "gout_peri_uart2_pclk", "gout_peri_busp1_peric0_hclk", + CLK_CON_GAT_PERI_UART2_PCLK, 12, + CLK_SET_RATE_PARENT, 0), +}; + +static const struct samsung_clk_group peri_cmu_clks[] = { + { S_CLK_GATE, peri_gate_clks, ARRAY_SIZE(peri_gate_clks) }, +}; + +static int exynos7870_cmu_peri_probe(struct udevice *dev) +{ + return samsung_register_cmu(dev, CMU_PERI, peri_cmu_clks, + exynos7870_cmu_peri); +} + +static const struct udevice_id exynos7870_cmu_peri_ids[] = { + { .compatible = "samsung,exynos7870-cmu-peri" }, + { } +}; + +SAMSUNG_CLK_OPS(exynos7870_cmu_peri, CMU_PERI); + +U_BOOT_DRIVER(exynos7870_cmu_peri) = { + .name = "exynos7870-cmu-peri", + .id = UCLASS_CLK, + .of_match = exynos7870_cmu_peri_ids, + .ops = &exynos7870_cmu_peri_clk_ops, + .probe = exynos7870_cmu_peri_probe, + .flags = DM_FLAG_PRE_RELOC, +}; -- cgit v1.3.1 From 07b8261d482549351dfd6f9a5e49b7d59e1fc3d9 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:51:34 +0530 Subject: clk: use private clk struct to access clock flags There may be cases where the flags set for a clock is not available. This is usually the case with clocks which have been retrieved using clk_request(). However, clock flags are found in their respective private clock struct, so use that instead. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- drivers/clk/clk-uclass.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 3dbe1ce9441..f7709d89a82 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -594,12 +594,13 @@ ulong clk_set_rate(struct clk *clk, ulong rate) if (!clk_valid(clk)) return 0; ops = clk_dev_ops(clk->dev); + clk_get_priv(clk, &clkp); /* Try to find parents which can set rate */ while (!ops->set_rate) { struct clk *parent; - if (!(clk->flags & CLK_SET_RATE_PARENT)) + if (!(clkp->flags & CLK_SET_RATE_PARENT)) return -ENOSYS; parent = clk_get_parent(clk); @@ -608,10 +609,9 @@ ulong clk_set_rate(struct clk *clk, ulong rate) clk = parent; ops = clk_dev_ops(clk->dev); + clk_get_priv(clk, &clkp); } - /* get private clock struct used for cache */ - clk_get_priv(clk, &clkp); /* Clean up cached rates for us and all child clocks */ clk_clean_rate_cache(clkp); -- cgit v1.3.1 From b526ec6f3c805f0ad5e5a4f86360dbdc59989c79 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:57:40 +0530 Subject: pinctrl: exynos: bind GPIO driver along with pinctrl The devicetree of Samsung devices typically have the pin controller and GPIO bank descriptors under the same pinctrl node. In U-Boot, these are handled by two separate drivers. It is not possible to invoke both drivers from a single node compatible. Bind the GPIO driver on pinctrl driver bind, with the same OF node as the pinctrl driver. This solution is already being used in other pinctrl drivers. The hierarchy, as represented in `dm tree`, is as follows: pinctrl@13750000 |-- gpio-banks | |-- gpr0-gpio-bank | |-- gpr1-gpio-bank | |-- gpr2-gpio-bank | |-- gpr3-gpio-bank | `-- gpr4-gpio-bank |-- sd0-bus-width1-pins |-- sd0-bus-width4-pins |-- sd0-bus-width8-pins `-- sd0-clk-pins Since a bind function doesn't exist, create and add it to all pinctrl drivers. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- drivers/pinctrl/exynos/pinctrl-exynos.c | 11 +++++++++++ drivers/pinctrl/exynos/pinctrl-exynos.h | 1 + drivers/pinctrl/exynos/pinctrl-exynos7420.c | 1 + drivers/pinctrl/exynos/pinctrl-exynos78x0.c | 1 + drivers/pinctrl/exynos/pinctrl-exynos850.c | 1 + 5 files changed, 15 insertions(+) diff --git a/drivers/pinctrl/exynos/pinctrl-exynos.c b/drivers/pinctrl/exynos/pinctrl-exynos.c index b37282fa9d6..4c06b41c7aa 100644 --- a/drivers/pinctrl/exynos/pinctrl-exynos.c +++ b/drivers/pinctrl/exynos/pinctrl-exynos.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include "pinctrl-exynos.h" @@ -178,3 +179,13 @@ int exynos_pinctrl_probe(struct udevice *dev) return 0; } + +int exynos_pinctrl_bind(struct udevice *dev) +{ + /* + * Attempt to bind the Exynos GPIO driver. The GPIOs and + * pin controller descriptors are found in the same OF node. + */ + return device_bind_driver_to_node(dev, "gpio_exynos", "gpio-banks", + dev_ofnode(dev), NULL); +} diff --git a/drivers/pinctrl/exynos/pinctrl-exynos.h b/drivers/pinctrl/exynos/pinctrl-exynos.h index da666777581..73cc2ce4117 100644 --- a/drivers/pinctrl/exynos/pinctrl-exynos.h +++ b/drivers/pinctrl/exynos/pinctrl-exynos.h @@ -97,5 +97,6 @@ void exynos_pinctrl_setup_peri(struct exynos_pinctrl_config_data *conf, int exynos_pinctrl_set_state(struct udevice *dev, struct udevice *config); int exynos_pinctrl_probe(struct udevice *dev); +int exynos_pinctrl_bind(struct udevice *dev); #endif /* __PINCTRL_EXYNOS_H_ */ diff --git a/drivers/pinctrl/exynos/pinctrl-exynos7420.c b/drivers/pinctrl/exynos/pinctrl-exynos7420.c index 8fdf60715a5..b1d983fd383 100644 --- a/drivers/pinctrl/exynos/pinctrl-exynos7420.c +++ b/drivers/pinctrl/exynos/pinctrl-exynos7420.c @@ -114,4 +114,5 @@ U_BOOT_DRIVER(pinctrl_exynos7420) = { .priv_auto = sizeof(struct exynos_pinctrl_priv), .ops = &exynos7420_pinctrl_ops, .probe = exynos_pinctrl_probe, + .bind = exynos_pinctrl_bind, }; diff --git a/drivers/pinctrl/exynos/pinctrl-exynos78x0.c b/drivers/pinctrl/exynos/pinctrl-exynos78x0.c index 61b98443daf..cc01028add1 100644 --- a/drivers/pinctrl/exynos/pinctrl-exynos78x0.c +++ b/drivers/pinctrl/exynos/pinctrl-exynos78x0.c @@ -115,4 +115,5 @@ U_BOOT_DRIVER(pinctrl_exynos78x0) = { .priv_auto = sizeof(struct exynos_pinctrl_priv), .ops = &exynos78x0_pinctrl_ops, .probe = exynos_pinctrl_probe, + .bind = exynos_pinctrl_bind, }; diff --git a/drivers/pinctrl/exynos/pinctrl-exynos850.c b/drivers/pinctrl/exynos/pinctrl-exynos850.c index 3ec2636e0d8..5bf09ae20ee 100644 --- a/drivers/pinctrl/exynos/pinctrl-exynos850.c +++ b/drivers/pinctrl/exynos/pinctrl-exynos850.c @@ -122,4 +122,5 @@ U_BOOT_DRIVER(pinctrl_exynos850) = { .priv_auto = sizeof(struct exynos_pinctrl_priv), .ops = &exynos850_pinctrl_ops, .probe = exynos_pinctrl_probe, + .bind = exynos_pinctrl_bind, }; -- cgit v1.3.1 From 9145d93c591b3141e70b215427a00bd2fc227c03 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:57:41 +0530 Subject: pinctrl: exynos78x0: add proper support for exynos7870 pinctrl The pinctrl blocks for Exynos7870 and Exynos7880 are similar, however in Exynos7870, the CCORE block is actually referred to as MIF. Since ordering happens lexically, it isn't directly compatible with samsung,exynos78x0-pinctrl. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- drivers/pinctrl/exynos/pinctrl-exynos78x0.c | 59 +++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/drivers/pinctrl/exynos/pinctrl-exynos78x0.c b/drivers/pinctrl/exynos/pinctrl-exynos78x0.c index cc01028add1..04e72173802 100644 --- a/drivers/pinctrl/exynos/pinctrl-exynos78x0.c +++ b/drivers/pinctrl/exynos/pinctrl-exynos78x0.c @@ -45,6 +45,11 @@ static const struct samsung_pin_bank_data exynos78x0_pin_banks2[] = { EXYNOS_PIN_BANK(4, 0x040, "gpz2"), }; +/* pin banks of exynos78x0 pin-controller 3 (ESE) */ +static const struct samsung_pin_bank_data exynos78x0_pin_banks3[] = { + EXYNOS_PIN_BANK(5, 0x000, "gpc7"), +}; + /* pin banks of exynos78x0 pin-controller 4 (FSYS) */ static const struct samsung_pin_bank_data exynos78x0_pin_banks4[] = { EXYNOS_PIN_BANK(3, 0x000, "gpr0"), @@ -54,6 +59,11 @@ static const struct samsung_pin_bank_data exynos78x0_pin_banks4[] = { EXYNOS_PIN_BANK(6, 0x080, "gpr4"), }; +/* pin banks of exynos78x0 pin-controller 5 (NFC) */ +static const struct samsung_pin_bank_data exynos78x0_pin_banks5[] = { + EXYNOS_PIN_BANK(4, 0x000, "gpc2"), +}; + /* pin banks of exynos78x0 pin-controller 6 (TOP) */ static const struct samsung_pin_bank_data exynos78x0_pin_banks6[] = { EXYNOS_PIN_BANK(4, 0x000, "gpb0"), @@ -77,6 +87,11 @@ static const struct samsung_pin_bank_data exynos78x0_pin_banks6[] = { EXYNOS_PIN_BANK(5, 0x240, "gpf4"), }; +/* pin banks of exynos7870 pin-controller 7 (TOUCH) */ +static const struct samsung_pin_bank_data exynos78x0_pin_banks7[] = { + EXYNOS_PIN_BANK(3, 0x000, "gpc3"), +}; + const struct samsung_pin_ctrl exynos78x0_pin_ctrl[] = { { /* pin-controller instance 0 Alive data */ @@ -102,9 +117,53 @@ const struct samsung_pin_ctrl exynos78x0_pin_ctrl[] = { {/* list terminator */} }; +/* + * In Exynos7870, the CCORE block is named as MIF instead. As the + * pinctrl blocks are sorted in lexical order of their names, the + * order isn't the same as Exynos7880. + */ +const struct samsung_pin_ctrl exynos7870_pin_ctrl[] = { + { + /* pin-controller instance 0 Alive data */ + .pin_banks = exynos78x0_pin_banks0, + .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks0), + }, { + /* pin-controller instance 1 DISPAUD data */ + .pin_banks = exynos78x0_pin_banks2, + .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks2), + }, { + /* pin-controller instance 2 ESE data */ + .pin_banks = exynos78x0_pin_banks3, + .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks3), + }, { + /* pin-controller instance 3 FSYS data */ + .pin_banks = exynos78x0_pin_banks4, + .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks4), + }, { + /* pin-controller instance 4 MIF data */ + .pin_banks = exynos78x0_pin_banks1, + .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks1), + }, { + /* pin-controller instance 5 NFC data */ + .pin_banks = exynos78x0_pin_banks5, + .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks5), + }, { + /* pin-controller instance 6 TOP data */ + .pin_banks = exynos78x0_pin_banks6, + .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks6), + }, { + /* pin-controller instance 7 TOUCH data */ + .pin_banks = exynos78x0_pin_banks7, + .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks7), + }, + {/* list terminator */} +}; + static const struct udevice_id exynos78x0_pinctrl_ids[] = { { .compatible = "samsung,exynos78x0-pinctrl", .data = (ulong)exynos78x0_pin_ctrl }, + { .compatible = "samsung,exynos7870-pinctrl", + .data = (ulong)exynos7870_pin_ctrl }, { } }; -- cgit v1.3.1 From 0bdc54e8df381424cb078c2f16767780534c8648 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:59:22 +0530 Subject: serial: s5p: add compatible for exynos8895 Add the compatible for Exynos8895 UART as described in upstream devicetree bindings. This enables support for Exynos8895 and other similar UART devices, such as Exynos7870. Other than that, the driver works as-is. Signed-off-by: Kaustabh Chakraborty Reviewed-by: Henrik Grimler Signed-off-by: Minkyu Kang --- drivers/serial/serial_s5p.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c index 734780a124a..d46a88610ab 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c @@ -258,6 +258,7 @@ static const struct dm_serial_ops s5p_serial_ops = { static const struct udevice_id s5p_serial_ids[] = { { .compatible = "samsung,exynos4210-uart", .data = PORT_S5P }, { .compatible = "samsung,exynos850-uart", .data = PORT_S5P }, + { .compatible = "samsung,exynos8895-uart", .data = PORT_S5P }, { .compatible = "apple,s5l-uart", .data = PORT_S5L }, { } }; -- cgit v1.3.1 From 1ca7bcdb9d6489caa55742a2938be2091d24e3b2 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 17 Oct 2025 20:59:48 +0530 Subject: soc: exynos-pmu: add support for Exynos7 PMU Add the compatible string of Exynos7's PMU as defined in upstream dt-schema. This also supports derivative PMUs as defined in schema. There's no additional setup required here, so pmu_init is skipped. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- drivers/soc/samsung/exynos-pmu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c index 233ad4a908f..0f533bcdae5 100644 --- a/drivers/soc/samsung/exynos-pmu.c +++ b/drivers/soc/samsung/exynos-pmu.c @@ -85,6 +85,9 @@ static int exynos_pmu_probe(struct udevice *dev) } static const struct udevice_id exynos_pmu_ids[] = { + { + .compatible = "samsung,exynos7-pmu", + }, { .compatible = "samsung,exynos850-pmu", .data = (ulong)&exynos850_pmu_data -- cgit v1.3.1 From ee5053adcb30f03b20dfe03456be1f0a524a4d9a Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Fri, 7 Nov 2025 16:02:23 +0100 Subject: mtd: rawnand: atmel: set pmecc data setup time Setup the pmecc data setup time as 3 clock cycles for 133MHz as recommended by the datasheet. Backported from Linux: f55f552a7c7e0a1 ("mtd: rawnand: atmel: set pmecc data setup time") Fixes: a490e1b7c017c ("nand: atmel: Add pmecc driver") Signed-off-by: Zixun LI Tested-by: Alexander Dahl Reviewed-by: Eugen Hristev --- drivers/mtd/nand/raw/atmel/pmecc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c index e500a0fe3f8..7c4e9bd5f99 100644 --- a/drivers/mtd/nand/raw/atmel/pmecc.c +++ b/drivers/mtd/nand/raw/atmel/pmecc.c @@ -142,6 +142,7 @@ struct atmel_pmecc_caps { int nstrengths; int el_offset; bool correct_erased_chunks; + bool clk_ctrl; }; struct atmel_pmecc_user_conf_cache { @@ -840,6 +841,10 @@ atmel_pmecc_create(struct udevice *dev, pmecc->regs.timing = 0; + /* pmecc data setup time */ + if (caps->clk_ctrl) + writel(PMECC_CLK_133MHZ, pmecc->regs.base + ATMEL_PMECC_CLK); + /* Disable all interrupts before registering the PMECC handler. */ writel(0xffffffff, pmecc->regs.base + ATMEL_PMECC_IDR); atmel_pmecc_reset(pmecc); @@ -884,6 +889,7 @@ static struct atmel_pmecc_caps at91sam9g45_caps = { .strengths = atmel_pmecc_strengths, .nstrengths = 5, .el_offset = 0x8c, + .clk_ctrl = true, }; static struct atmel_pmecc_caps sama5d4_caps = { -- cgit v1.3.1 From ba7721badf08a1e52d8f76b406c52070d2aa9320 Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Fri, 7 Nov 2025 16:02:24 +0100 Subject: mtd: rawnand: atmel: atmel_pmecc_create: Remove unused code "timing" and "timing_res_idx" are unused and not exist in Linux driver, let's remove them. Signed-off-by: Zixun LI Acked-by: Alexander Dahl Reviewed-by: Eugen Hristev --- drivers/mtd/nand/raw/atmel/pmecc.c | 7 ++----- drivers/mtd/nand/raw/atmel/pmecc.h | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c index 7c4e9bd5f99..1acaa5d0e07 100644 --- a/drivers/mtd/nand/raw/atmel/pmecc.c +++ b/drivers/mtd/nand/raw/atmel/pmecc.c @@ -820,8 +820,7 @@ EXPORT_SYMBOL_GPL(atmel_pmecc_wait_rdy); static struct atmel_pmecc * atmel_pmecc_create(struct udevice *dev, const struct atmel_pmecc_caps *caps, - int pmecc_res_idx, int errloc_res_idx, - int timing_res_idx) + int pmecc_res_idx, int errloc_res_idx) { struct atmel_pmecc *pmecc; struct resource res; @@ -839,8 +838,6 @@ atmel_pmecc_create(struct udevice *dev, ofnode_read_resource(dev->node_, 1, &res); pmecc->regs.errloc = (void *)res.start; - pmecc->regs.timing = 0; - /* pmecc data setup time */ if (caps->clk_ctrl) writel(PMECC_CLK_133MHZ, pmecc->regs.base + ATMEL_PMECC_CLK); @@ -952,7 +949,7 @@ static int atmel_pmecc_probe(struct udevice *dev) return -EINVAL; } - pmecc = atmel_pmecc_create(dev, caps, 0, 1, 2); + pmecc = atmel_pmecc_create(dev, caps, 0, 1); if (IS_ERR(pmecc)) return PTR_ERR(pmecc); diff --git a/drivers/mtd/nand/raw/atmel/pmecc.h b/drivers/mtd/nand/raw/atmel/pmecc.h index 43f96b2f168..88b0d18040e 100644 --- a/drivers/mtd/nand/raw/atmel/pmecc.h +++ b/drivers/mtd/nand/raw/atmel/pmecc.h @@ -65,7 +65,6 @@ struct atmel_pmecc { struct { void __iomem *base; void __iomem *errloc; - void __iomem *timing; } regs; /* Mutex used for pmecc enable/disable */ -- cgit v1.3.1 From 46e0ac55e56638d2543fc5a4c1ed28470095233e Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Sat, 15 Nov 2025 09:33:29 +0200 Subject: rpi: Fix compilation with larger configs Tom reports that adding more Kconfig options fails with board/raspberrypi/rpi/lowlevel_init.o: in function `save_boot_params': board/raspberrypi/rpi/lowlevel_init.S:20:(.text+0x0): relocation truncated to fit: R_AARCH64_ADR_PREL_LO21 against symbol `fw_dtb_pointer' defined in .data section in board/raspberrypi/rpi/rpi.o make: *** [Makefile:2029: u-boot] Error 1 Since fw_dtb_pointer lives in .data it might end up above the +-1MB that adr can reach. So switch over to adrp+add which has a +-4gb reach. Reported-by: Tom Rini Closes: https://source.denx.de/u-boot/custodians/u-boot-raspberrypi/-/issues/2 Signed-off-by: Ilias Apalodimas Reviewed-by: Peter Robinson --- board/raspberrypi/rpi/lowlevel_init.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/board/raspberrypi/rpi/lowlevel_init.S b/board/raspberrypi/rpi/lowlevel_init.S index 8c39b3e12e8..30c0b0c27a8 100644 --- a/board/raspberrypi/rpi/lowlevel_init.S +++ b/board/raspberrypi/rpi/lowlevel_init.S @@ -16,7 +16,8 @@ save_boot_params: /* The firmware provided ATAG/FDT address can be found in r2/x0 */ #ifdef CONFIG_ARM64 - adr x8, fw_dtb_pointer + adrp x8, fw_dtb_pointer + add x8, x8, #:lo12:fw_dtb_pointer str x0, [x8] #else ldr r8, =fw_dtb_pointer -- cgit v1.3.1 From 2c39d975f87cfcce3805bff34918708bf7491b25 Mon Sep 17 00:00:00 2001 From: Cibil Pankiras Date: Fri, 14 Nov 2025 00:45:32 +0100 Subject: pinctrl: bcm283x: Add GPIO pull-up/down control for BCM2835 and BCM2711 This patch adds support for configuring GPIO pull-up and pull-down resistors in the BCM283x pinctrl driver. It implements the brcm,pull device tree property to control pin bias settings. The implementation follows the hardware-specific pull control mechanisms: - BCM2835: two-step GPPUD register sequence - BCM2711: direct per-pin control registers This enables device tree configurations to specify pull-up, pull-down, or no bias for individual GPIO pins. Tested on Raspberry Pi boards with both BCM2835 and BCM2711 SoCs. Signed-off-by: Cibil Pankiras Reviewed-by: Matthias Brugger --- arch/arm/mach-bcm283x/include/mach/gpio.h | 10 +++ drivers/pinctrl/broadcom/pinctrl-bcm283x.c | 105 ++++++++++++++++++++++++++++- 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-bcm283x/include/mach/gpio.h b/arch/arm/mach-bcm283x/include/mach/gpio.h index 4aeb48eeb20..c54414a012c 100644 --- a/arch/arm/mach-bcm283x/include/mach/gpio.h +++ b/arch/arm/mach-bcm283x/include/mach/gpio.h @@ -26,6 +26,16 @@ #define BCM2835_GPIO_FSEL_BANK(gpio) (gpio / 10) #define BCM2835_GPIO_FSEL_SHIFT(gpio) ((gpio % 10) * 3) +/* BCM2835 GPIO Pull-up/down register offsets */ +#define BCM2835_GPPUD 37 +#define BCM2835_GPPUDCLK0 38 + +/* BCM2711 GPIO Pull-up/down control */ +#define BCM2711_GPPUD_CNTRL_REG0 57 +#define BCM2711_PUD_REG_OFFSET(gpio) ((gpio) / 16) +#define BCM2711_PUD_REG_SHIFT(gpio) (((gpio) % 16) * 2) +#define BCM2711_PUD_2711_MASK 0x3 + struct bcm2835_gpio_regs { u32 gpfsel[6]; u32 reserved1; diff --git a/drivers/pinctrl/broadcom/pinctrl-bcm283x.c b/drivers/pinctrl/broadcom/pinctrl-bcm283x.c index cf9350c151e..4ecc8bac645 100644 --- a/drivers/pinctrl/broadcom/pinctrl-bcm283x.c +++ b/drivers/pinctrl/broadcom/pinctrl-bcm283x.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include struct bcm283x_pinctrl_priv { u32 *base_reg; @@ -54,7 +56,66 @@ static int bcm2835_gpio_get_func_id(struct udevice *dev, unsigned int gpio) } /* - * bcm283x_pinctrl_set_state: configure pin functions. + * bcm2835_gpio_set_pull: Set GPIO pull-up/down resistor for BCM2835 + * @dev: the pinctrl device + * @gpio: the GPIO pin number + * @pull: pull setting (BCM2835_PUD_OFF, BCM2835_PUD_DOWN, BCM2835_PUD_UP) + */ +static void bcm2835_gpio_set_pull(struct udevice *dev, unsigned int gpio, int pull) +{ + struct bcm283x_pinctrl_priv *priv = dev_get_priv(dev); + u32 bank = BCM2835_GPPUDCLK0 + BCM2835_GPIO_COMMON_BANK(gpio); + u32 bit = BCM2835_GPIO_COMMON_SHIFT(gpio); + + /* Set required control signal */ + writel(pull & 0x3, &priv->base_reg[BCM2835_GPPUD]); + udelay(1); + + /* Clock the control signal into the GPIO pads */ + writel(1 << bit, &priv->base_reg[bank]); + udelay(1); + + /* Remove the control signal and clock */ + writel(0, &priv->base_reg[BCM2835_GPPUD]); + writel(0, &priv->base_reg[bank]); +} + +/* + * bcm2711_gpio_set_pull: Set GPIO pull-up/down resistor for BCM2711 + * @dev: the pinctrl device + * @gpio: the GPIO pin number + * @pull: pull setting (BCM2835_PUD_OFF, BCM2835_PUD_DOWN, BCM2835_PUD_UP) + */ +static void bcm2711_gpio_set_pull(struct udevice *dev, unsigned int gpio, int pull) +{ + struct bcm283x_pinctrl_priv *priv = dev_get_priv(dev); + u32 reg_offset; + u32 bit_shift; + u32 pull_bits; + + /* Findout which GPIO_PUP_PDN_CNTRL register to use */ + reg_offset = BCM2711_GPPUD_CNTRL_REG0 + BCM2711_PUD_REG_OFFSET(gpio); + + /* Findout the bit position */ + bit_shift = BCM2711_PUD_REG_SHIFT(gpio); + + /* Update the 2-bit field for this GPIO */ + pull_bits = pull & BCM2711_PUD_2711_MASK; + clrsetbits_le32(&priv->base_reg[reg_offset], + BCM2711_PUD_2711_MASK << bit_shift, + pull_bits << bit_shift); +} + +static void bcm283x_gpio_set_pull(struct udevice *dev, unsigned int gpio, int pull) +{ + if (device_is_compatible(dev, "brcm,bcm2835-gpio")) + bcm2835_gpio_set_pull(dev, gpio, pull); + else + bcm2711_gpio_set_pull(dev, gpio, pull); +} + +/* + * bcm283x_pinctrl_set_state: configure pin functions and pull states. * @dev: the pinctrl device to be configured. * @config: the state to be configured. * @return: 0 in success @@ -62,8 +123,10 @@ static int bcm2835_gpio_get_func_id(struct udevice *dev, unsigned int gpio) int bcm283x_pinctrl_set_state(struct udevice *dev, struct udevice *config) { u32 pin_arr[MAX_PINS_PER_BANK]; + u32 pull_arr[MAX_PINS_PER_BANK]; int function; - int i, len, pin_count = 0; + int i, len, pin_count = 0, pull_len = 0, pull_count = 0; + int pull_value; if (!dev_read_prop(config, "brcm,pins", &len) || !len || len & 0x3 || dev_read_u32_array(config, "brcm,pins", pin_arr, @@ -82,8 +145,44 @@ int bcm283x_pinctrl_set_state(struct udevice *dev, struct udevice *config) return -EINVAL; } - for (i = 0; i < pin_count; i++) + /* Check if brcm,pull property exists */ + if (dev_read_prop(config, "brcm,pull", &pull_len) && pull_len > 0) { + if (pull_len & 0x3) { + debug("Invalid pull array length for pinconfig %s (%d)\n", + config->name, pull_len); + return -EINVAL; + } + + pull_count = pull_len / sizeof(u32); + + if (pull_count != 1 && pull_count != pin_count) { + debug("Pull array count (%d) must be 1 or match pin count (%d) for pinconfig %s\n", + pull_count, pin_count, config->name); + return -EINVAL; + } + + if (dev_read_u32_array(config, "brcm,pull", pull_arr, pull_count)) { + debug("Failed reading pull array for pinconfig %s\n", config->name); + return -EINVAL; + } + + /* Validate pull values */ + for (i = 0; i < pull_count; i++) { + if (pull_arr[i] > 2) { + debug("Invalid pull value %d for pin %d in pinconfig %s\n", + pull_arr[i], pin_arr[i], config->name); + return -EINVAL; + } + } + } + + for (i = 0; i < pin_count; i++) { bcm2835_gpio_set_func_id(dev, pin_arr[i], function); + if (pull_count > 0) { + pull_value = (pull_count == 1) ? pull_arr[0] : pull_arr[i]; + bcm283x_gpio_set_pull(dev, pin_arr[i], pull_value); + } + } return 0; } -- cgit v1.3.1 From 15c719174cf30c4ef1c5a3638156db8c318fbd18 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 27 Sep 2025 05:30:15 -0600 Subject: rpi: Use the U-Boot control FDT for fdt_addr The fdt_addr variable is used in extlinux as a fallback devicetree if none is provided by the boot command. Otherwise the only use in U-Boot seems to me efi_install_fdt() when the internal FDT is required. The existing mechanism uses the devicetree provided to U-Boot, but in its original, unrelocated position. In my testing on an rpi_4, this ends up at 2b35ef00 which is not a convenient place in memory, if the ramdisk is large. U-Boot already deals with this sort of problem by relocating the FDT to a safe address. So use the control-FDT address instead. Remove the existing comment, which is confusing, since the FDT is not actually passed unmodified to the kernel: U-Boot adds various things using its FDT-fixup mechanism. Note that board_get_usable_ram_top() reduces the RAM top for boards with less RAM. This behaviour is left unchanged as there is no other mechanism for U-Boot to handle this. Signed-off-by: Simon Glass Reviewed-by: Christopher Obbard Tested-by: Christopher Obbard # CM4 1G --- board/raspberrypi/rpi/rpi.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 1b0b664fa2b..6f96c1ebc96 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -3,6 +3,8 @@ * (C) Copyright 2012-2016 Stephen Warren */ +#define LOG_CATEGORY LOGC_BOARD + #include #include #include @@ -354,15 +356,13 @@ static void set_fdtfile(void) } /* - * If the firmware provided a valid FDT at boot time, let's expose it in - * ${fdt_addr} so it may be passed unmodified to the kernel. + * Allow U-Boot to use its control FDT with extlinux if one is not provided. + * This will then go through the usual fixups that U-Boot does, before being + * handed off to Linux */ static void set_fdt_addr(void) { - if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC) - return; - - env_set_hex("fdt_addr", fw_dtb_pointer); + env_set_hex("fdt_addr", (ulong)gd->fdt_blob); } /* @@ -608,7 +608,10 @@ int ft_board_setup(void *blob, struct bd_info *bd) { int node; - update_fdt_from_fw(blob, (void *)fw_dtb_pointer); + if (blob == gd->fdt_blob) + log_debug("Same FDT: nothing to do\n"); + else + update_fdt_from_fw(blob, (void *)gd->fdt_blob); if (CONFIG_IS_ENABLED(FDT_SIMPLEFB)) { node = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer"); -- cgit v1.3.1 From 4937a9778cfb22cad3f411522c62a14d5242e55e Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Tue, 21 Oct 2025 19:51:35 +0530 Subject: gpio: s5p: increment bank base address only if bank is initialized There is a condition guard which ensures that the GPIO node, indeed describes a GPIO controller. if (!fdtdec_get_bool(blob, node, "gpio-controller")) continue; Since the bank base is being incremented in the loop, it is done so irrespective of whether the node is a GPIO controller or not. This leads to the incorrect resolution of bank base addresses. Move it out of the loop, and instead increment the bank base address only if the driver successfully binds a GPIO controller. Reviewed-by: Henrik Grimler Fixes: b8809e60cdb5 ("dm: exynos: gpio: Convert to driver model") Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- drivers/gpio/s5p_gpio.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c index 53dbbe97b5a..c072f146514 100644 --- a/drivers/gpio/s5p_gpio.c +++ b/drivers/gpio/s5p_gpio.c @@ -319,7 +319,7 @@ static int gpio_exynos_bind(struct udevice *parent) base = dev_read_addr_ptr(parent); for (node = fdt_first_subnode(blob, dev_of_offset(parent)), bank = base; node > 0; - node = fdt_next_subnode(blob, node), bank++) { + node = fdt_next_subnode(blob, node)) { struct exynos_gpio_plat *plat; struct udevice *dev; fdt_addr_t reg; @@ -341,9 +341,8 @@ static int gpio_exynos_bind(struct udevice *parent) if (reg != FDT_ADDR_T_NONE) bank = (struct s5p_gpio_bank *)((ulong)base + reg); - plat->bank = bank; - debug("dev at %p: %s\n", bank, plat->bank_name); + plat->bank = bank++; } return 0; -- cgit v1.3.1 From 29f6afc6e39f8699f0f0e62c891b1eefb7833225 Mon Sep 17 00:00:00 2001 From: Francesco Valla Date: Thu, 13 Nov 2025 18:03:55 +0100 Subject: imx91: fix pinmux macros for ENET1_TD3 and I2C2_SCL Fix macros for the GPIO function for two pads (ENET1_TD3 and I2C2_SCL), aligning them to the functions specified in the datasheet. Fixes: a9d562daa3c3 ("imx: Add iMX91 support") Suggested-by: Javier Viguera Signed-off-by: Francesco Valla Reviewed-by: Fabio Estevam --- arch/arm/dts/imx91-11x11-evk.dts | 2 +- arch/arm/dts/imx91-pinfunc.h | 4 ++-- arch/arm/include/asm/arch-imx9/imx91_pins.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/dts/imx91-11x11-evk.dts b/arch/arm/dts/imx91-11x11-evk.dts index 65571fc223b..ca9070a4c76 100644 --- a/arch/arm/dts/imx91-11x11-evk.dts +++ b/arch/arm/dts/imx91-11x11-evk.dts @@ -503,7 +503,7 @@ MX91_PAD_ENET1_TD0__GPIO4_IO5 0x31e MX91_PAD_ENET1_TD1__GPIO4_IO4 0x31e MX91_PAD_ENET1_TD2__GPIO4_IO3 0x31e - MX91_PAD_ENET1_TD3__GPIO4_IO3 0x31e + MX91_PAD_ENET1_TD3__GPIO4_IO2 0x31e MX91_PAD_ENET1_TXC__GPIO4_IO7 0x31e MX91_PAD_ENET1_TX_CTL__GPIO4_IO6 0x31e >; diff --git a/arch/arm/dts/imx91-pinfunc.h b/arch/arm/dts/imx91-pinfunc.h index b0066df173b..5677928ab7c 100644 --- a/arch/arm/dts/imx91-pinfunc.h +++ b/arch/arm/dts/imx91-pinfunc.h @@ -330,7 +330,7 @@ #define MX91_PAD_ENET1_TD3__CAN2_TX 0x00a0 0x0250 0x0000 0x02 0x00 #define MX91_PAD_ENET1_TD3__HSIOMIX_OTG_ID2 0x00a0 0x0250 0x0000 0x03 0x00 #define MX91_PAD_ENET1_TD3__FLEXIO2_FLEXIO2 0x00a0 0x0250 0x0000 0x04 0x00 -#define MX91_PAD_ENET1_TD3__GPIO4_IO3 0x00a0 0x0250 0x0000 0x05 0x00 +#define MX91_PAD_ENET1_TD3__GPIO4_IO2 0x00a0 0x0250 0x0000 0x05 0x00 #define MX91_PAD_ENET1_TD3__LPI2C2_SCL 0x00a0 0x0250 0x03e8 0x06 0x00 #define MX91_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x00a4 0x0254 0x0000 0x00 0x00 @@ -680,7 +680,7 @@ #define MX91_PAD_I2C2_SCL__LPUART2_DCB_B 0x0178 0x0328 0x0000 0x02 0x00 #define MX91_PAD_I2C2_SCL__TPM2_CH2 0x0178 0x0328 0x0000 0x03 0x00 #define MX91_PAD_I2C2_SCL__SAI1_RX_SYNC 0x0178 0x0328 0x0000 0x04 0x00 -#define MX91_PAD_I2C2_SCL__GPIO1_IO3 0x0178 0x0328 0x0000 0x05 0x00 +#define MX91_PAD_I2C2_SCL__GPIO1_IO2 0x0178 0x0328 0x0000 0x05 0x00 #define MX91_PAD_I2C2_SCL__I3C1_PUR_B 0x0178 0x0328 0x0000 0x06 0x00 #define MX91_PAD_I2C2_SDA__LPI2C2_SDA 0x017c 0x032c 0x03ec 0x00 0x01 diff --git a/arch/arm/include/asm/arch-imx9/imx91_pins.h b/arch/arm/include/asm/arch-imx9/imx91_pins.h index 26246702a96..838a8142257 100644 --- a/arch/arm/include/asm/arch-imx9/imx91_pins.h +++ b/arch/arm/include/asm/arch-imx9/imx91_pins.h @@ -329,7 +329,7 @@ enum { MX91_PAD_ENET1_TD3__CAN2_TX = IOMUX_PAD(0x0250, 0x00A0, 0x02, 0x0000, 0x00, 0x00), MX91_PAD_ENET1_TD3__HSIOMIX_OTG_ID2 = IOMUX_PAD(0x0250, 0x00A0, 0x03, 0x0000, 0x00, 0x00), MX91_PAD_ENET1_TD3__FLEXIO2_FLEXIO2 = IOMUX_PAD(0x0250, 0x00A0, 0x04, 0x0000, 0x00, 0x00), - MX91_PAD_ENET1_TD3__GPIO4_IO3 = IOMUX_PAD(0x0250, 0x00A0, 0x05, 0x0000, 0x00, 0x00), + MX91_PAD_ENET1_TD3__GPIO4_IO2 = IOMUX_PAD(0x0250, 0x00A0, 0x05, 0x0000, 0x00, 0x00), MX91_PAD_ENET1_TD3__LPI2C2_SCL = IOMUX_PAD(0x0250, 0x00A0, 0x06, 0x03E8, 0x00, 0x00), MX91_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 = IOMUX_PAD(0x0254, 0x00A4, 0x00, 0x0000, 0x00, 0x00), @@ -679,7 +679,7 @@ enum { MX91_PAD_I2C2_SCL__LPUART2_DCB_B = IOMUX_PAD(0x0328, 0x0178, 0x02, 0x0000, 0x00, 0x00), MX91_PAD_I2C2_SCL__TPM2_CH2 = IOMUX_PAD(0x0328, 0x0178, 0x03, 0x0000, 0x00, 0x00), MX91_PAD_I2C2_SCL__SAI1_RX_SYNC = IOMUX_PAD(0x0328, 0x0178, 0x04, 0x0000, 0x00, 0x00), - MX91_PAD_I2C2_SCL__GPIO1_IO3 = IOMUX_PAD(0x0328, 0x0178, 0x05, 0x0000, 0x00, 0x00), + MX91_PAD_I2C2_SCL__GPIO1_IO2 = IOMUX_PAD(0x0328, 0x0178, 0x05, 0x0000, 0x00, 0x00), MX91_PAD_I2C2_SCL__I3C1_PUR_B = IOMUX_PAD(0x0328, 0x0178, 0x06, 0x0000, 0x00, 0x00), MX91_PAD_I2C2_SDA__LPI2C2_SDA = IOMUX_PAD(0x032C, 0x017C, 0x00, 0x03EC, 0x01, 0x00), -- cgit v1.3.1 From 1312a503462ae23b791265af03c588785768bb09 Mon Sep 17 00:00:00 2001 From: Ernest Van Hoecke Date: Tue, 18 Nov 2025 15:48:00 +0100 Subject: configs: colibri-imx7*: set 'fdtfile' generically in PREBOOT In TEZI (Toradex Easy Installer), we use one U-Boot binary for both our NAND and eMMC Colibri iMX7 modules. Currently, CONFIG_PREBOOT sets the environment variable 'fdtfile' depending on which defconfig was used, adding the '-emmc' variant for the emmc defconfig. Since we always build the TEZI recovery U-Boot with the standard (non-emmc) defconfig, fdtfile has to be overwritten later or it will be wrong there. By using '$variant', the fdtfile var is properly constructed at run time for both the NAND and eMMC variants, and we do not have to worry about setting fdtfile again when building the recovery TEZI U-Boot. This also synchronizes these configs with how we handle the iMX6ULL. Fixes: 327381e8b57c ("colibri_imx7: use preboot for fdtfile evaluation") Signed-off-by: Ernest Van Hoecke Reviewed-by: Francesco Dolcini --- configs/colibri_imx7_defconfig | 2 +- configs/colibri_imx7_emmc_defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/colibri_imx7_defconfig b/configs/colibri_imx7_defconfig index 5a415120bea..2a3cb84c3b6 100644 --- a/configs/colibri_imx7_defconfig +++ b/configs/colibri_imx7_defconfig @@ -22,7 +22,7 @@ CONFIG_BOOTDELAY=1 CONFIG_OF_ENV_SETUP=y CONFIG_BOOTCOMMAND="run ubiboot ; echo ; echo ubiboot failed ; run distro_bootcmd;" CONFIG_USE_PREBOOT=y -CONFIG_PREBOOT="test -n ${fdtfile} || setenv fdtfile ${soc}-colibri-${fdt_board}.dtb " +CONFIG_PREBOOT="test -n ${fdtfile} || setenv fdtfile ${soc}-colibri${variant}-${fdt_board}.dtb " CONFIG_SYS_PBSIZE=544 CONFIG_SYS_CONSOLE_IS_IN_ENV=y # CONFIG_DISPLAY_BOARDINFO is not set diff --git a/configs/colibri_imx7_emmc_defconfig b/configs/colibri_imx7_emmc_defconfig index bae43fe45aa..a95a3214d0c 100644 --- a/configs/colibri_imx7_emmc_defconfig +++ b/configs/colibri_imx7_emmc_defconfig @@ -19,7 +19,7 @@ CONFIG_FIT_VERBOSE=y CONFIG_DISTRO_DEFAULTS=y CONFIG_BOOTDELAY=1 CONFIG_USE_PREBOOT=y -CONFIG_PREBOOT="test -n ${fdtfile} || setenv fdtfile ${soc}-colibri-emmc-${fdt_board}.dtb" +CONFIG_PREBOOT="test -n ${fdtfile} || setenv fdtfile ${soc}-colibri${variant}-${fdt_board}.dtb" CONFIG_SYS_PBSIZE=544 CONFIG_SYS_CONSOLE_IS_IN_ENV=y # CONFIG_DISPLAY_BOARDINFO is not set -- cgit v1.3.1 From 091df90a89ecd2526c6ba401c1b55af6b77da95e Mon Sep 17 00:00:00 2001 From: Alice Guo Date: Thu, 20 Nov 2025 19:22:59 +0800 Subject: arm: dts: imx8ulp: Ensure mu@27020000 and lpuart5 availability during all boot phases mu@27020000 is required for communication with ELE firmware, and lpuart5 is the standard output device. Both peripherals must be available before U-Boot relocation. Use bootph-all instead of bootph-pre-ram so these nodes are retained across all boot phases. Signed-off-by: Alice Guo --- arch/arm/dts/imx8ulp-evk-u-boot.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/dts/imx8ulp-evk-u-boot.dtsi b/arch/arm/dts/imx8ulp-evk-u-boot.dtsi index 845fe205925..2782dc7dd75 100644 --- a/arch/arm/dts/imx8ulp-evk-u-boot.dtsi +++ b/arch/arm/dts/imx8ulp-evk-u-boot.dtsi @@ -10,16 +10,16 @@ compatible = "fsl,imx8ulp-mu"; reg = <0 0x27020000 0 0x10000>; status = "okay"; - bootph-pre-ram; + bootph-all; }; }; &soc { - bootph-pre-ram; + bootph-all; }; &per_bridge3 { - bootph-pre-ram; + bootph-all; }; &per_bridge4 { @@ -27,15 +27,15 @@ }; &iomuxc1 { - bootph-pre-ram; + bootph-all; }; &pinctrl_lpuart5 { - bootph-pre-ram; + bootph-all; }; &lpuart5 { - bootph-pre-ram; + bootph-all; }; &usdhc0 { -- cgit v1.3.1 From e2c435bd0aafa87d15c066cf45ca53c50981ffca Mon Sep 17 00:00:00 2001 From: Alice Guo Date: Thu, 20 Nov 2025 19:23:00 +0800 Subject: arm: dts: imx8ulp: Disable wdog3 until DM watchdog support is available The driver model for watchdog timer is not enabled yet, so disable wdog3 temporarily. Signed-off-by: Alice Guo --- arch/arm/dts/imx8ulp-evk.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/dts/imx8ulp-evk.dts b/arch/arm/dts/imx8ulp-evk.dts index f1c6d933a17..7aec1706382 100644 --- a/arch/arm/dts/imx8ulp-evk.dts +++ b/arch/arm/dts/imx8ulp-evk.dts @@ -119,3 +119,7 @@ >; }; }; + +&wdog3 { + status = "disabled"; +}; -- cgit v1.3.1 From f737f0675f0b3b942c3f302eebcfd716d87139c5 Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Tue, 18 Nov 2025 17:21:14 -0600 Subject: board: samsung: e850-96: Keep public functions together Move DRAM init functions close to other public functions, to make things visually distinct and improve the readability. No functional change. Signed-off-by: Sam Protsenko Signed-off-by: Minkyu Kang --- board/samsung/e850-96/e850-96.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c index 3df241edde2..34e01914032 100644 --- a/board/samsung/e850-96/e850-96.c +++ b/board/samsung/e850-96/e850-96.c @@ -77,16 +77,6 @@ static struct acpm acpm = { .ipc_ch = EXYNOS850_IPC_AP_I3C, }; -int dram_init(void) -{ - return fdtdec_setup_mem_size_base(); -} - -int dram_init_banksize(void) -{ - return fdtdec_setup_memory_banksize(); -} - /* Read the unique SoC ID from OTP registers */ static u64 get_chip_id(void) { @@ -166,6 +156,16 @@ void load_firmware(void) printf("ERROR: LDFW loading failed (%d)\n", err); } +int dram_init(void) +{ + return fdtdec_setup_mem_size_base(); +} + +int dram_init_banksize(void) +{ + return fdtdec_setup_memory_banksize(); +} + int board_late_init(void) { setup_serial(); -- cgit v1.3.1 From 1d9aafa751dd76bd3088b746d53004d04fcb9b6c Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Tue, 18 Nov 2025 17:21:15 -0600 Subject: board: samsung: e850-96: Add routines for checking boot dev Implement functionality to check the current boot device (a device where the SoC ROM code is loading the bootloaders from). The boot device order can be changed using the SW1 DIP switch on the E850-96 board (which controls XOM SoC lines), as stated in [1]. The boot device information is requested from EL3 software using the corresponding SMC call, which in turn reads it from iRAM memory, which was written by the ROM code. New routines decode that data and allow the user to check the current boot device, boot order, etc. That API can be used further to implement different code flows depending on the current boot device, e.g.: - on eMMC boot: obtain the firmware binaries from eMMC - on USB boot: download the firmware over USB instead No functional change; this patch only adds new functionality but it's not used yet. [1] doc/board/samsung/e850-96.rst Signed-off-by: Sam Protsenko Signed-off-by: Minkyu Kang --- board/samsung/e850-96/Makefile | 2 +- board/samsung/e850-96/bootdev.c | 99 +++++++++++++++++++++++++++++++++++++++++ board/samsung/e850-96/bootdev.h | 23 ++++++++++ 3 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 board/samsung/e850-96/bootdev.c create mode 100644 board/samsung/e850-96/bootdev.h diff --git a/board/samsung/e850-96/Makefile b/board/samsung/e850-96/Makefile index 76b8d47994e..e9c62d3181f 100644 --- a/board/samsung/e850-96/Makefile +++ b/board/samsung/e850-96/Makefile @@ -3,4 +3,4 @@ # Copyright (C) 2024, Linaro Limited # Sam Protsenko -obj-y := e850-96.o fw.o acpm.o pmic.o +obj-y := e850-96.o fw.o acpm.o pmic.o bootdev.o diff --git a/board/samsung/e850-96/bootdev.c b/board/samsung/e850-96/bootdev.c new file mode 100644 index 00000000000..7d5ae7128f4 --- /dev/null +++ b/board/samsung/e850-96/bootdev.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2025 Linaro Ltd. + * Author: Sam Protsenko + * + * Routines for checking current boot device. + */ + +#include +#include +#include "bootdev.h" + +/* Flag from BL2 bootloader in RAM */ +#define BL2_TAG_ADDR 0x80000000 /* DRAM base */ +#define BL2_TAG 0xabcdef + +/* Boot device info location in iRAM (only accessible from EL3) */ +#define IRAM_BASE 0x02020000 +#define BOOTDEVICE_INFO_ADDR (IRAM_BASE + 0x64) + +/* SMC call for getting boot device information from EL3 monitor */ +#define SMC_CMD_CHECK_SECOND_BOOT -233 + +/* Boot device constants for the encoded boot device info value */ +#define BD_NO_DEVICE 0x0 +#define BD_UFS 0x1 +#define BD_EMMC 0x2 +#define BD_ERROR 0x3 +#define BD_USB 0x4 +#define BD_SDMMC 0x5 +#define BD_UFS_CARD 0x6 +#define BD_SPI 0x7 + +/* If BL2 bootloader wasn't executed, it means U-Boot is running via JTAG */ +static bool bootdev_is_jtag_session(void) +{ + u32 bl2_tag_val = *(u32 *)BL2_TAG_ADDR; + + return bl2_tag_val != BL2_TAG; +} + +/* Obtain boot device information encoded in 32-bit value */ +static u32 bootdev_get_info(void) +{ + u32 info; + + /* + * On regular boot U-Boot is executed by BL2 bootloader, and is running + * in EL1 mode, so the boot device information has to be obtained via + * SMC call from EL3 software (EL3 monitor), which can read that info + * from the protected iRAM memory. If U-Boot is running via TRACE32 JTAG + * (in EL3 mode), read the boot device info directly from iRAM, as EL3 + * software might not be available. + */ + if (bootdev_is_jtag_session()) { + info = *(u32 *)BOOTDEVICE_INFO_ADDR; + } else { + struct arm_smccc_res res; + + arm_smccc_smc(SMC_CMD_CHECK_SECOND_BOOT, 0, 0, 0, 0, 0, 0, 0, + &res); + info = (u32)res.a2; + } + + return info; +} + +enum bootdev bootdev_get_current(void) +{ + u32 info, magic, order, dev; + + info = bootdev_get_info(); + magic = info >> 24; + order = info & 0xf; + dev = (info >> (4 * order)) & 0xf; + + if (magic != 0xcb) + panic("Abnormal boot"); + + switch (dev) { + case BD_UFS: + return BOOTDEV_UFS; + case BD_EMMC: + return BOOTDEV_EMMC; + case BD_USB: + return BOOTDEV_USB; + case BD_SDMMC: + return BOOTDEV_SD; + default: + return BOOTDEV_ERROR; + } + + return BOOTDEV_ERROR; +} + +bool bootdev_is_usb(void) +{ + return bootdev_get_current() == BOOTDEV_USB; +} diff --git a/board/samsung/e850-96/bootdev.h b/board/samsung/e850-96/bootdev.h new file mode 100644 index 00000000000..5f454bf0090 --- /dev/null +++ b/board/samsung/e850-96/bootdev.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2025 Linaro Ltd. + * Sam Protsenko + */ + +#ifndef __E850_96_BOOTDEV_H +#define __E850_96_BOOTDEV_H + +#include + +enum bootdev { + BOOTDEV_ERROR, + BOOTDEV_SD, + BOOTDEV_EMMC, + BOOTDEV_USB, + BOOTDEV_UFS, +}; + +enum bootdev bootdev_get_current(void); +bool bootdev_is_usb(void); + +#endif /* __E850_96_BOOTDEV_H */ -- cgit v1.3.1 From 3d1ae437a66795c34604a61104b2ff92ab493b9c Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Tue, 18 Nov 2025 17:21:16 -0600 Subject: board: samsung: e850-96: Split LDFW loading and init The LDFW firmware loading is done in two steps: 1. Read the firmware binary from some block device 2. Provide it to EL3 monitor software via an SMC call, so it can copy it to a Secure World memory and start using it Let's split the load_ldfw() function by two functions correspondingly, to reflect that process better: - load_ldfw_from_blk() - init_ldfw() It can be useful in case when the LDFW binary should be obtained from some different media, e.g. downloaded over USB during USB boot. No functional change. Signed-off-by: Sam Protsenko Signed-off-by: Minkyu Kang --- board/samsung/e850-96/e850-96.c | 9 +++++++-- board/samsung/e850-96/fw.c | 37 +++++++++++++++++++++++++------------ board/samsung/e850-96/fw.h | 3 ++- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c index 34e01914032..3cf98a01b70 100644 --- a/board/samsung/e850-96/e850-96.c +++ b/board/samsung/e850-96/e850-96.c @@ -151,9 +151,14 @@ void load_firmware(void) } printf("Loading LDFW firmware (from %s %ld)...\n", ifname, dev); - err = load_ldfw(ifname, dev, part, LDFW_NWD_ADDR); - if (err) + err = load_ldfw_from_blk(ifname, dev, part, LDFW_NWD_ADDR); + if (err) { printf("ERROR: LDFW loading failed (%d)\n", err); + return; + } + err = init_ldfw(LDFW_NWD_ADDR); + if (err) + printf("ERROR: LDFW init failed (%d)\n", err); } int dram_init(void) diff --git a/board/samsung/e850-96/fw.c b/board/samsung/e850-96/fw.c index 64235c01a25..2d52433e38a 100644 --- a/board/samsung/e850-96/fw.c +++ b/board/samsung/e850-96/fw.c @@ -94,7 +94,7 @@ static int read_fw_from_raw(const char *ifname, int dev, const char *part_name, } /** - * load_ldfw - Load the loadable firmware (LDFW) + * load_ldfw_from_blk - Load the loadable firmware (LDFW) from block device * @ifname: Interface name of the block device to load the firmware from * @dev: Device number * @part: Partition number @@ -102,24 +102,37 @@ static int read_fw_from_raw(const char *ifname, int dev, const char *part_name, * * Return: 0 on success or a negative value on error. */ -int load_ldfw(const char *ifname, int dev, int part, phys_addr_t addr) +int load_ldfw_from_blk(const char *ifname, int dev, int part, phys_addr_t addr) { - struct ldfw_header *hdr; - struct arm_smccc_res res; void *buf = (void *)addr; - u64 size = 0; - int err, i; + int err; /* First try to read LDFW from EFI partition, then from the raw one */ err = read_fw_from_fat(ifname, dev, part, LDFW_FAT_PATH, buf); - if (err) { - err = read_fw_from_raw(ifname, dev, LDFW_RAW_PART, buf); - if (err) - return err; - } + if (err) + return read_fw_from_raw(ifname, dev, LDFW_RAW_PART, buf); + + return 0; +} + +/** + * init_ldfw - Provide the LDFW (loaded to RAM) to EL3 monitor to make use of it + * @addr: Memory address where LDFW resides + * + * EL3 monitor will copy the LDFW from the provided Normal World memory @addr to + * Secure World location, and start using it. + * + * Return: 0 on success or a negative value on error. + */ +int init_ldfw(phys_addr_t addr) +{ + struct ldfw_header *hdr; + struct arm_smccc_res res; + u64 size = 0; + int err, i; /* Validate LDFW by magic number in its header */ - hdr = buf; + hdr = (struct ldfw_header *)addr; if (hdr->magic != LDFW_MAGIC) { debug("%s: Wrong LDFW magic; is LDFW flashed?\n", __func__); return -EINVAL; diff --git a/board/samsung/e850-96/fw.h b/board/samsung/e850-96/fw.h index 73d9615d4a9..b061abc4df6 100644 --- a/board/samsung/e850-96/fw.h +++ b/board/samsung/e850-96/fw.h @@ -9,6 +9,7 @@ #include -int load_ldfw(const char *ifname, int dev, int part, phys_addr_t addr); +int load_ldfw_from_blk(const char *ifname, int dev, int part, phys_addr_t addr); +int init_ldfw(phys_addr_t addr); #endif /* __E850_96_FW_H */ -- cgit v1.3.1 From 3d9115a045d2d48c28019b3d6673ab30271819f5 Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Tue, 18 Nov 2025 17:21:17 -0600 Subject: board: samsung: e850-96: Add routine for loading images over USB During USB boot U-Boot is supposed to download some firmware over USB. It's done by EL3 software, so it has to be requested via corresponding SMC call. Implement a routine for doing that. No functional change. Signed-off-by: Sam Protsenko Signed-off-by: Minkyu Kang --- board/samsung/e850-96/fw.c | 39 ++++++++++++++++++++++++++++++++------- board/samsung/e850-96/fw.h | 7 +++++++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/board/samsung/e850-96/fw.c b/board/samsung/e850-96/fw.c index 2d52433e38a..576167122ec 100644 --- a/board/samsung/e850-96/fw.c +++ b/board/samsung/e850-96/fw.c @@ -11,14 +11,19 @@ #include #include "fw.h" -#define LDFW_RAW_PART "ldfw" -#define LDFW_FAT_PATH "/EFI/firmware/ldfw.bin" +#define LDFW_RAW_PART "ldfw" +#define LDFW_FAT_PATH "/EFI/firmware/ldfw.bin" +#define LDFW_MAGIC 0x10adab1e -#define LDFW_MAGIC 0x10adab1e -#define SMC_CMD_LOAD_LDFW -0x500 -#define SDM_HW_RESET_STATUS 0x1230 -#define SDM_SW_RESET_STATUS 0x1231 -#define SB_ERROR_PREFIX 0xfdaa0000 +/* SMC command for providing LDFW to EL3 monitor */ +#define SMC_CMD_LOAD_LDFW -0x500 +/* SMC command for loading some binary over USB */ +#define SMC_CMD_LOAD_IMAGE_BY_USB -0x512 + +/* Error codes for SMC_CMD_LOAD_LDFW */ +#define SDM_HW_RESET_STATUS 0x1230 +#define SDM_SW_RESET_STATUS 0x1231 +#define SB_ERROR_PREFIX 0xfdaa0000 struct ldfw_header { u32 magic; @@ -93,6 +98,26 @@ static int read_fw_from_raw(const char *ifname, int dev, const char *part_name, return 0; } +/** + * load_image_usb - Load some binary over USB during USB boot + * @type: Image type + * @addr: Memory address where the image should be downloaded to + * @size: Image size + * + * Return: 0 on success or a negative value on error. + */ +int load_image_usb(enum usb_dn_image type, phys_addr_t addr, phys_size_t size) +{ + struct arm_smccc_res res; + + arm_smccc_smc(SMC_CMD_LOAD_IMAGE_BY_USB, (u64)type, addr, size, + 0, 0, 0, 0, &res); + if (res.a0) + return -EIO; + + return 0; +} + /** * load_ldfw_from_blk - Load the loadable firmware (LDFW) from block device * @ifname: Interface name of the block device to load the firmware from diff --git a/board/samsung/e850-96/fw.h b/board/samsung/e850-96/fw.h index b061abc4df6..68f943e8bbc 100644 --- a/board/samsung/e850-96/fw.h +++ b/board/samsung/e850-96/fw.h @@ -9,6 +9,13 @@ #include +/* Image types for downloading over USB */ +enum usb_dn_image { + USB_DN_IMAGE_LDFW = 1, /* Loadable Firmware */ + USB_DN_IMAGE_SP = 2, /* Secure Payload (tzsw.img) */ +}; + +int load_image_usb(enum usb_dn_image type, phys_addr_t addr, phys_size_t size); int load_ldfw_from_blk(const char *ifname, int dev, int part, phys_addr_t addr); int init_ldfw(phys_addr_t addr); -- cgit v1.3.1 From 7b583b66639fa1fd883d48bc259aa39490970df6 Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Tue, 18 Nov 2025 17:21:18 -0600 Subject: board: samsung: e850-96: Load firmwares over USB on USB boot During USB boot it's expected that the bootloader (U-Boot) should download LDFW and TZSW firmware binaries over USB, using corresponding SMC call. Once it's done, the Boot ROM code can release the USB block, so that it can be used in U-Boot (e.g. for flashing images to eMMC using DFU or fastboot). Otherwise USB wouldn't be accessible in U-Boot, and any attempt to access USB PHY or DWC3 registers will lead to abort. Signed-off-by: Sam Protsenko Signed-off-by: Minkyu Kang --- board/samsung/e850-96/e850-96.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c index 3cf98a01b70..3aa4992a36d 100644 --- a/board/samsung/e850-96/e850-96.c +++ b/board/samsung/e850-96/e850-96.c @@ -11,6 +11,7 @@ #include #include #include +#include "bootdev.h" #include "fw.h" #include "pmic.h" @@ -31,6 +32,10 @@ #define EMMC_DEV_NUM 0 #define EMMC_ESP_PART 1 +/* Firmware size */ +#define LDFW_MAX_SIZE SZ_4M +#define SP_MAX_SIZE SZ_1M + struct efi_fw_image fw_images[] = { { .image_type_id = E850_96_FWBL1_IMAGE_GUID, @@ -127,11 +132,34 @@ static void setup_ethaddr(void) eth_env_set_enetaddr("ethaddr", mac_addr); } +static void load_firmware_usb(void) +{ + int err; + + printf("Loading LDFW firmware (over USB)...\n"); + err = load_image_usb(USB_DN_IMAGE_LDFW, LDFW_NWD_ADDR, LDFW_MAX_SIZE); + if (err) { + printf("ERROR: LDFW loading failed (%d)\n", err); + return; + } + + err = init_ldfw(LDFW_NWD_ADDR); + if (err) { + printf("ERROR: LDFW init failed (%d)\n", err); + /* Do not return, still need to download SP */ + } + + printf("Loading SP firmware (over USB)...\n"); + err = load_image_usb(USB_DN_IMAGE_SP, LDFW_NWD_ADDR, SP_MAX_SIZE); + if (err) + printf("ERROR: SP loading failed (%d)\n", err); +} + /* * Call this in board_late_init() to avoid probing block devices before * efi_init_early(). */ -void load_firmware(void) +static void load_firmware_blk(void) { const char *ifname; ulong dev, part; @@ -175,7 +203,11 @@ int board_late_init(void) { setup_serial(); setup_ethaddr(); - load_firmware(); + + if (bootdev_is_usb()) + load_firmware_usb(); + else + load_firmware_blk(); return 0; } -- cgit v1.3.1 From 17d6b90a5f362612118b029b457471118524657c Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Tue, 18 Nov 2025 17:21:19 -0600 Subject: board: samsung: e850-96: Enter DFU automatically on USB boot Doing USB boot on E850-96 is most useful in two cases: 1. For unbricking the board 2. During the bootloader development In both cases a U-Boot binary is being re-flashed to eMMC. The most convenient way to update U-Boot in eMMC is by using DFU. Implement entering DFU flashing mode automatically when U-Boot is executed on USB boot. That makes it easier for users to re-flash U-Boot without even having serial console running, e.g.: $ ./smdk-usbdl $ dfu-util -D u-boot.bin -a bootloader See [1,2] for details. Entering DFU mode is implemented by setting corresponding environment variables: bootcmd="dfu 0 mmc 0" bootdelay=0 Do not save the U-Boot environment though, to avoid falling through to DFU mode on a regular eMMC boot. [1] doc/board/samsung/e850-96.rst [2] https://gitlab.com/LinaroLtd/e850-96/tools/dltool/-/tree/uboot Signed-off-by: Sam Protsenko Signed-off-by: Minkyu Kang --- board/samsung/e850-96/e850-96.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c index 3aa4992a36d..415505f2561 100644 --- a/board/samsung/e850-96/e850-96.c +++ b/board/samsung/e850-96/e850-96.c @@ -209,6 +209,12 @@ int board_late_init(void) else load_firmware_blk(); + if (bootdev_is_usb()) { + env_set("bootcmd", "echo \"Entering DFU mode...\"; " + "dfu 0 mmc 0"); + env_set("bootdelay", "0"); + } + return 0; } -- cgit v1.3.1 From ff3b4e9936a720870decd6ddb0e77c7b5d464d5d Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 19 Nov 2025 08:55:35 -0600 Subject: s5p4418_nanopi2: Stop disabling device tree relocation Remove setting of fdt_high to ~0, which disables device tree relocation, from the default environment. Doing so prevents U-Boot from correcting problems such as having an unaligned device tree and leads to various failure modes in the OS. Signed-off-by: Tom Rini Signed-off-by: Minkyu Kang --- include/configs/s5p4418_nanopi2.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/configs/s5p4418_nanopi2.h b/include/configs/s5p4418_nanopi2.h index fec1bfd50eb..8a8d54daf7b 100644 --- a/include/configs/s5p4418_nanopi2.h +++ b/include/configs/s5p4418_nanopi2.h @@ -139,7 +139,6 @@ #endif #define CFG_EXTRA_ENV_SETTINGS \ - "fdt_high=0xffffffff\0" \ "initrd_high=0xffffffff\0" \ "rootdev=" __stringify(CONFIG_ROOT_DEV) "\0" \ "rootpart=" __stringify(CONFIG_ROOT_PART) "\0" \ -- cgit v1.3.1 From bd19527c755963de9c1d231fdacd112e54f33480 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 19 Nov 2025 08:32:58 -0600 Subject: Docker: Update QEMU to 10.0.6 The QEMU project has the 10.0.x series as an LTS release. While we are not doing an LTS ourselves, we can be confident in the changes between 10.0.2 and 10.0.6, so update ourselves. Signed-off-by: Tom Rini --- tools/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 58f2a28daa0..92be7f76341 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -220,7 +220,7 @@ RUN git clone git://git.savannah.gnu.org/grub.git /tmp/grub && \ RUN git clone https://gitlab.com/qemu-project/qemu.git /tmp/qemu && \ cd /tmp/qemu && \ - git checkout v10.0.2 && \ + git checkout v10.0.6 && \ # config user.name and user.email to make 'git am' happy git config user.name u-boot && \ git config user.email u-boot@denx.de && \ -- cgit v1.3.1 From bc4a1e56bfcdd70a5307c91c94dafcf6bb27da93 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 13 Nov 2025 16:09:56 -0600 Subject: Dockerfile: Include python3-tk for FATtools In some cases our tests for exFAT don't run because we fail to be able to create the underlying image. This is in turn because while creation of the image succeeds, it seems that some way of how we invoke FATtools wants to import tkinter, that fails and so the test stops there. Having tkinter available (and then presumably a fallback to non-GUI because it's not available) leads to the tests running as expected. Reviewed-by: Marek Vasut Signed-off-by: Tom Rini --- tools/docker/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 92be7f76341..f98b42e7357 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -126,6 +126,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ python3-pip \ python3-pyelftools \ python3-sphinx \ + python3-tk \ python3-tomli \ python3-venv \ rpm2cpio \ -- cgit v1.3.1 From 4dfa4c14b8e5b37885f9eb281b3bc230938c5972 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 26 Nov 2025 10:21:54 -0600 Subject: Dockerfile: Update building trace tools slightly We have not been picking a tag for the trace-cmd build process. Currently the tip of libtraceevent fails to build. Address both problems here by picking recent stable tags for libtraceevent and libtracefs (trace-cmd has no recent tags). Further, as it is often reported that this fails to build due to a race, stop using "make -j$(nproc)" as this is also small enough of a set of builds to not be an issue. Signed-off-by: Tom Rini --- tools/docker/Dockerfile | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index f98b42e7357..960e4a7177f 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -311,17 +311,19 @@ RUN git clone https://github.com/stefanberger/swtpm /tmp/swtpm && \ # Build trace-cmd RUN mkdir /tmp/trace && \ - git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git /tmp/trace/libtraceevent && \ + git clone --depth=1 https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git /tmp/trace/libtraceevent \ + -b libtraceevent-1.8.6 && \ cd /tmp/trace/libtraceevent && \ - make -j$(nproc) && \ + make && \ sudo make install && \ - git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git /tmp/trace/libtracefs && \ + git clone --depth=1 https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git /tmp/trace/libtracefs \ + -b libtracefs-1.8.2 && \ cd /tmp/trace/libtracefs && \ - make -j$(nproc) && \ + make && \ sudo make install && \ git clone https://github.com/rostedt/trace-cmd.git /tmp/trace/trace-cmd && \ cd /tmp/trace/trace-cmd && \ - make -j$(nproc) && \ + make && \ sudo make install && \ rm -rf /tmp/trace -- cgit v1.3.1 From 0ae3dc6809ffb6568b5e46d9022829e36d473d36 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 26 Nov 2025 10:30:24 -0600 Subject: CI: Update to latest container - Move to jammy-20251013 tag - Bring in tkinter so that FATtools should run and more tests should be run. - Update to QEMU 10.0.6 - Pick tags for (most of) trace-cmd Signed-off-by: Tom Rini --- .azure-pipelines.yml | 2 +- .gitlab-ci.yml | 2 +- tools/docker/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 3f671dd078d..0c7c38ba730 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -2,7 +2,7 @@ variables: windows_vm: windows-2022 ubuntu_vm: ubuntu-24.04 macos_vm: macOS-14 - ci_runner_image: trini/u-boot-gitlab-ci-runner:jammy-20251001-04Nov2025 + ci_runner_image: trini/u-boot-gitlab-ci-runner:jammy-20251013-26Nov2025 # Ensure we do a shallow clone Agent.Source.Git.ShallowFetchDepth: 1 # Add '-u 0' options for Azure pipelines, otherwise we get "permission diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 86d3c741ea1..e7234e003ea 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -18,7 +18,7 @@ workflow: # Grab our configured image. The source for this is found # in the u-boot tree at tools/docker/Dockerfile -image: ${MIRROR_DOCKER}/trini/u-boot-gitlab-ci-runner:jammy-20251001-04Nov2025 +image: ${MIRROR_DOCKER}/trini/u-boot-gitlab-ci-runner:jammy-20251013-26Nov2025 # We run some tests in different order, to catch some failures quicker. stages: diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 960e4a7177f..8ab1cff5584 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -2,7 +2,7 @@ # This Dockerfile is used to build an image containing basic stuff to be used # to build U-Boot and run our test suites. -FROM ubuntu:jammy-20251001 +FROM ubuntu:jammy-20251013 LABEL org.opencontainers.image.authors="Tom Rini " LABEL org.opencontainers.image.description=" This image is for building U-Boot inside a container" -- cgit v1.3.1 From 642a9e716e1e4ecfa64e01a81e815b74e9c142bf Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 16 Nov 2025 12:41:53 +0100 Subject: cmd/extension: avoid NULL pointer dereference extension_get_list() will return NULL if there is no extension device. Check for this situation. Addresses-Coverity-ID: 638557 - Null pointer dereferences (NULL_RETURNS) Fixes: 2d12958ee71b ("boot: Remove legacy extension board support") Signed-off-by: Heinrich Schuchardt Acked-by: Kory Maincent --- cmd/extension_board.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/extension_board.c b/cmd/extension_board.c index 86e4795ba8a..75358abf666 100644 --- a/cmd/extension_board.c +++ b/cmd/extension_board.c @@ -99,6 +99,10 @@ static int do_extension_list(struct cmd_tbl *cmdtp, int flag, int i = 0; extension_list = extension_get_list(); + if (!extension_list) { + printf("No extension device\n"); + return CMD_RET_FAILURE; + } if (!alist_get_ptr(extension_list, 0)) { printf("No extension registered - Please run \"extension scan\"\n"); return CMD_RET_SUCCESS; -- cgit v1.3.1 From e3b7dd93d39e1c0a6bcf95d13b3ac4e8035c5db2 Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Tue, 18 Nov 2025 17:50:52 +0530 Subject: power: domain: ti: fix ti_pd_get() to return after verifying transition The helper function "ti_pd_get()" is responsible for powering on a domain if it is powered off. In the current implementation, if a power domain is determined to be powered off - no prior users and the PDCTL register indicates that the user desired state is OFF, then powering on the domain constitutes setting 'PDCTL_STATE_ON' field of the PDCTL register. While the current implementation indeed requests the power domain to be transition to the ON state, the helper function "ti_pd_get()" doesn't verify that the power domain has 'transitioned' to the ON state before returning to its caller. As a result, it is possible that the device(s) belonging to the power domain may be accessed before it is truly powered on, leading to a bus abort. Fix this by waiting for the power domain to transition to the ON state by using "ti_pd_wait()" before returning from "ti_pd_get()". Fixes: 144464bd2c67 ("power: domain: Introduce driver for raw TI K3 PDs") Signed-off-by: Siddharth Vadapalli Tested-by: Hrushikesh Salunke --- drivers/power/domain/ti-power-domain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/domain/ti-power-domain.c b/drivers/power/domain/ti-power-domain.c index c3519307340..a554e659392 100644 --- a/drivers/power/domain/ti-power-domain.c +++ b/drivers/power/domain/ti-power-domain.c @@ -227,7 +227,7 @@ static int ti_pd_get(struct ti_pd *pd) pd_write(pdctl, pd, PSC_PDCTL); - return 0; + return ti_pd_wait(pd); } static int ti_pd_put(struct ti_pd *pd) -- cgit v1.3.1 From cc0ce9e8c494d20e75258584807aaaac4cc514bd Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Fri, 21 Nov 2025 18:51:53 +0530 Subject: net: ti: am65-cpsw-nuss: Ignore disabled ethernet ports Currently, the bind callback of the driver namely am65_cpsw_nuss_bind() registers all ethernet ports including the ones that have been disabled in the device-tree. Since the ports that have been disabled are ought to be ignored, fix the implementation to register only the enabled ports as indicated by their 'status' in their respective device-tree node. Fixes: 3943531a5468 ("net: ti: am65-cpsw-nuss: Define bind method for CPSW driver") Reported-by: Wadim Egorov Closes: https://patch.msgid.link/8b4ac072-125c-493b-b12a-f0a4e9d56e7e@phytec.de Signed-off-by: Siddharth Vadapalli --- drivers/net/ti/am65-cpsw-nuss.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c index 7a88f76fd09..84a3e44ecbc 100644 --- a/drivers/net/ti/am65-cpsw-nuss.c +++ b/drivers/net/ti/am65-cpsw-nuss.c @@ -819,6 +819,10 @@ static int am65_cpsw_nuss_bind(struct udevice *dev) ofnode_for_each_subnode(node, ports_np) { const char *node_name; + /* Ignore disabled ports */ + if (!ofnode_is_enabled(node)) + continue; + node_name = ofnode_get_name(node); ret = device_bind_driver_to_node(dev, "am65_cpsw_nuss_port", node_name, node, -- cgit v1.3.1 From 3afc99727ad0e829b0275b3ffa5b970b343bc0db Mon Sep 17 00:00:00 2001 From: "Guillaume La Roque (TI.com)" Date: Mon, 24 Nov 2025 16:09:47 +0100 Subject: board: ti: am6x: Restore do_board_detect functions This patch fixes a boot failure on the AM64x EVM that was introduced when the do_board_detect function was removed during a refactoring. It restores the do_board_detect function for the AM64x, AM62x, and AM65x boards to ensure the common board detection logic is executed correctly. Fixes: 804b80288ac ("board: am65x: Use generic AM6x board detection function") Fixes: ce56e553c31 ("board: am64x: Use generic AM6x board detection functions") Fixes: ff1b83c095c ("board: am62x: Add support for reading eeprom data") Signed-off-by: Guillaume La Roque (TI.com) --- board/ti/am62x/evm.c | 9 +++++++-- board/ti/am64x/evm.c | 9 +++++++-- board/ti/am65x/evm.c | 9 +++++++-- board/ti/common/board_detect.c | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/board/ti/am62x/evm.c b/board/ti/am62x/evm.c index 6bb243ee597..e9eba57eba7 100644 --- a/board/ti/am62x/evm.c +++ b/board/ti/am62x/evm.c @@ -82,11 +82,16 @@ struct efi_capsule_update_info update_info = { }; #if CONFIG_IS_ENABLED(TI_I2C_BOARD_DETECT) +int do_board_detect(void) +{ + return do_board_detect_am6(); +} + int checkboard(void) { struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA; - if (!do_board_detect_am6()) + if (!do_board_detect()) printf("Board: %s rev %s\n", ep->name, ep->version); return 0; @@ -97,7 +102,7 @@ static void setup_board_eeprom_env(void) { char *name = "am62x_skevm"; - if (do_board_detect_am6()) + if (do_board_detect()) goto invalid_eeprom; if (board_is_am62x_skevm()) diff --git a/board/ti/am64x/evm.c b/board/ti/am64x/evm.c index 3688cf2ca25..25076a8a588 100644 --- a/board/ti/am64x/evm.c +++ b/board/ti/am64x/evm.c @@ -114,11 +114,16 @@ void spl_perform_board_fixups(struct spl_image_info *spl_image) #endif #ifdef CONFIG_TI_I2C_BOARD_DETECT +int do_board_detect(void) +{ + return do_board_detect_am6(); +} + int checkboard(void) { struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA; - if (!do_board_detect_am6()) + if (!do_board_detect()) printf("Board: %s rev %s\n", ep->name, ep->version); return 0; @@ -135,7 +140,7 @@ static void setup_board_eeprom_env(void) { char *name = "am64x_gpevm"; - if (do_board_detect_am6()) + if (do_board_detect()) goto invalid_eeprom; if (board_is_am64x_gpevm()) diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c index 68606746d5f..b35a9229033 100644 --- a/board/ti/am65x/evm.c +++ b/board/ti/am65x/evm.c @@ -72,11 +72,16 @@ int board_fit_config_name_match(const char *name) #endif #ifdef CONFIG_TI_I2C_BOARD_DETECT +int do_board_detect(void) +{ + return do_board_detect_am6(); +} + int checkboard(void) { struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA; - if (do_board_detect_am6()) + if (do_board_detect()) /* EEPROM not populated */ printf("Board: %s rev %s\n", "AM6-COMPROCEVM", "E3"); else @@ -89,7 +94,7 @@ static void setup_board_eeprom_env(void) { char *name = "am65x"; - if (do_board_detect_am6()) + if (do_board_detect()) goto invalid_eeprom; if (board_is_am65x_base_board()) diff --git a/board/ti/common/board_detect.c b/board/ti/common/board_detect.c index d49e26fa453..a235ea9ef21 100644 --- a/board/ti/common/board_detect.c +++ b/board/ti/common/board_detect.c @@ -825,7 +825,7 @@ bool __maybe_unused board_ti_was_eeprom_read(void) return false; } -#if CONFIG_IS_ENABLED(TI_I2C_BOARD_DETECT) +#if IS_ENABLED(CONFIG_TI_I2C_BOARD_DETECT) int do_board_detect_am6(void) { int ret; -- cgit v1.3.1 From f06e1c04bffb89cd14d559c8d3e219ab2b815093 Mon Sep 17 00:00:00 2001 From: Maarten Brock Date: Tue, 25 Nov 2025 13:55:24 +0000 Subject: board: ti: am335x: Fix DM_TPS65910 condition scale_vcores_generic() calls functions implemented in tps65910.c, not tps65910_dm.c. Change guard from CONFIG_DM_PMIC_TPS65910 to CONFIG_SPL_POWER_TPS65910. Fixes: 0b9ff0851592 ("board: ti: am335x: Do not call disabled PMIC functions") Signed-off-by: Markus Schneider-Pargmann (TI.com) Signed-off-by: Maarten Brock Reviewed-by: Kory Maincent Acked-by: Maarten Brock --- board/ti/am335x/board.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c index 712818ec235..90e37a8d913 100644 --- a/board/ti/am335x/board.c +++ b/board/ti/am335x/board.c @@ -429,7 +429,7 @@ void scale_vcores_generic(int freq) { int sil_rev, mpu_vdd; - if (!IS_ENABLED(CONFIG_DM_PMIC_TPS65910)) + if (!IS_ENABLED(CONFIG_SPL_POWER_TPS65910)) return; /* -- cgit v1.3.1 From 70ab39e2305f6ab9b7b1752e26b0e4293129009b Mon Sep 17 00:00:00 2001 From: Greg Malysa Date: Wed, 26 Nov 2025 14:50:31 -0500 Subject: board: adi: Fix missing semicolon in nfsroot The nfsroot constructed as part of the default Analog Devices boot strategy is missing a semicolon between the server ip and the root path itself. This adds the missing semicolon. Signed-off-by: Greg Malysa --- include/env/adi/adi_boot.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/env/adi/adi_boot.env b/include/env/adi/adi_boot.env index d56b14f5172..7f0dfe15ff9 100644 --- a/include/env/adi/adi_boot.env +++ b/include/env/adi/adi_boot.env @@ -41,7 +41,7 @@ addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmas /* Boot modes are selectable and should be defined in the board env before including */ #if defined(USE_NFS) // rootpath is set by CONFIG_ROOTPATH -nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}${rootpath},tcp,nfsvers=3 ${adi_bootargs} +nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath},tcp,nfsvers=3 ${adi_bootargs} nfsboot=run init_ethernet; tftp ${loadaddr} ${tftp_dir_prefix}${imagefile}; run nfsargs; -- cgit v1.3.1 From 5d7c080ae5dc1f8d5ca4fb1dd93a15ea96ca8c72 Mon Sep 17 00:00:00 2001 From: Leonard Anderweit Date: Tue, 18 Nov 2025 15:30:20 +0100 Subject: bootstd: rauc: Don't check root part filesystem Only check if the root partition exists when scanning for the slots partitions and not if the filesystem can be accessed. It is not needed to access the filesystem of the root partition as it might not be supported by u-boot or be encrypted. Signed-off-by: Leonard Anderweit Tested-by: Martin Schwan --- boot/bootmeth_rauc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boot/bootmeth_rauc.c b/boot/bootmeth_rauc.c index f5d5a971e87..1096daedb5a 100644 --- a/boot/bootmeth_rauc.c +++ b/boot/bootmeth_rauc.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -121,10 +122,9 @@ static int distro_rauc_scan_parts(struct bootflow *bflow) if (ret) return log_msg_ret("part", ret); fs_close(); - ret = fs_set_blk_dev_with_part(desc, slot->root_part); + ret = part_get_info(desc, slot->root_part, NULL); if (ret) return log_msg_ret("part", ret); - fs_close(); } } str_free_list(boot_order_list); -- cgit v1.3.1 From 962711498ddac6179f1d1f3fa123397ba02a381b Mon Sep 17 00:00:00 2001 From: Leonard Anderweit Date: Tue, 18 Nov 2025 15:30:21 +0100 Subject: bootstd: rauc: Only require partitions for one slot Partitions can be become unusable due to power cuts or failed updates. Use the bootmeth RAUC if partitions for at least one slot exist. The bootmeth can then select the working slot. Signed-off-by: Leonard Anderweit Tested-by: Martin Schwan --- boot/bootmeth_rauc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/boot/bootmeth_rauc.c b/boot/bootmeth_rauc.c index 1096daedb5a..833715e1395 100644 --- a/boot/bootmeth_rauc.c +++ b/boot/bootmeth_rauc.c @@ -99,6 +99,7 @@ static int distro_rauc_scan_parts(struct bootflow *bflow) struct distro_rauc_priv *priv; char *boot_order; const char **boot_order_list; + bool slot_found = false; int ret; int i; @@ -120,16 +121,20 @@ static int distro_rauc_scan_parts(struct bootflow *bflow) if (desc) { ret = fs_set_blk_dev_with_part(desc, slot->boot_part); if (ret) - return log_msg_ret("part", ret); + continue; fs_close(); ret = part_get_info(desc, slot->root_part, NULL); if (ret) - return log_msg_ret("part", ret); + continue; + slot_found = true; } } str_free_list(boot_order_list); - return 0; + if (slot_found) + return 0; + + return -1; } static int distro_rauc_read_bootflow(struct udevice *dev, struct bootflow *bflow) -- cgit v1.3.1 From 2736ed925e3226346b10d3e4ee9ba9fe9544d2f0 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 15 Nov 2025 10:58:20 +0100 Subject: usb: USB_EHCI_PCI depends on PCI CONFIG_USB_EHCI_PCI cannot work without CONFIG_PCI. Signed-off-by: Heinrich Schuchardt Reviewed-by: Marek Vasut --- drivers/usb/host/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 427b62e934b..99f381db9f9 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -271,6 +271,7 @@ config USB_EHCI_MSM config USB_EHCI_PCI bool "Support for PCI-based EHCI USB controller" + depends on PCI default y if X86 help Enables support for the PCI-based EHCI controller. -- cgit v1.3.1 From 610a3eb27ea1e68363fffcb3f14b7fc097ef08b6 Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Wed, 26 Nov 2025 14:41:04 +0100 Subject: configs: toradex-smarc-imx95: set spl_stack The SPL_STACK config option now depends on having SPL_HAVE_INIT_STACK defined. This made savedefconfig dropping SPL_STACK when sending the initial configuration. Note that SPL/U-Boot are able to boot linux from mass storage with SPL_STACK not set but other use cases might run out of stack or overlap with other RAM use. Compare with: commit d6a53f523afe ("spl: Add an SPL_HAVE_INIT_STACK option") commit 25fefa05d732 ("configs: Resync with savedefconfig") Fixes: ff0540fcfe49 ("board: toradex: add Toradex SMARC iMX95") Signed-off-by: Max Krummenacher Reviewed-by: Fabio Estevam Acked-by: Francesco Dolcini --- configs/toradex-smarc-imx95_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/toradex-smarc-imx95_defconfig b/configs/toradex-smarc-imx95_defconfig index c5cea6e4e5f..5ab420ae519 100644 --- a/configs/toradex-smarc-imx95_defconfig +++ b/configs/toradex-smarc-imx95_defconfig @@ -17,6 +17,7 @@ CONFIG_SYS_MONITOR_LEN=524288 CONFIG_SPL_MMC=y CONFIG_SPL_SERIAL=y CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_STACK=0x204d6000 CONFIG_SPL_TEXT_BASE=0x20480000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y CONFIG_SPL_BSS_START_ADDR=0x204d6000 @@ -49,6 +50,7 @@ CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_LOAD_IMX_CONTAINER=y CONFIG_IMX_CONTAINER_CFG="arch/arm/mach-imx/imx9/scmi/container.cfg" # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_HAVE_INIT_STACK=y CONFIG_SPL_SYS_MALLOC=y CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x93200000 -- cgit v1.3.1 From 7dbcc316a64d3e5bf86632f078c5c08295e882fd Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 27 Nov 2025 18:54:25 +0100 Subject: usb/xhci: avoid noisy 'Register NbrPorts' message We should avoid overwhelming users with non-essential messages. 'Register NbrPorts' is a debug message for EHCI. Do the same for XHCI. Signed-off-by: Heinrich Schuchardt Reviewed-by: Marek Vasut --- drivers/usb/host/xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 3ee1f67190f..d59804580f1 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1249,7 +1249,7 @@ static int xhci_lowlevel_init(struct xhci_ctrl *ctrl) reg = xhci_readl(&hccr->cr_hcsparams1); ctrl->hub_desc.bNbrPorts = HCS_MAX_PORTS(reg); - printf("Register %x NbrPorts %d\n", reg, ctrl->hub_desc.bNbrPorts); + debug("Register %x NbrPorts %d\n", reg, ctrl->hub_desc.bNbrPorts); /* Port Indicators */ reg = xhci_readl(&hccr->cr_hccparams); -- cgit v1.3.1 From 5b702cf4d09f84f6cfe2989038b67feafe9945ed Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Tue, 25 Nov 2025 11:23:58 +0100 Subject: rpi: Fix DRAM size reporting to show total RAM The VideoCore mailbox GET_ARM_MEMORY only reports the size of the first accessible memory region (~947 MiB on RPi4 with 8GB), not the total RAM. This causes U-Boot to display "DRAM: 947 MiB (total 7.9 GiB)" instead of "DRAM: 7.9 GiB". On Raspberry Pi 4 with 8GB RAM, the memory is split across multiple non-contiguous banks. The dram_init() function only sets gd->ram_size to the first bank size reported by the VideoCore firmware, while fdtdec_setup_memory_banksize() correctly populates all memory banks from the device tree. Fix this by updating gd->ram_size after dram_init_banksize() has populated all memory banks, so it reflects the actual total RAM across all banks. Signed-off-by: Anders Roxell Reviewed-by: Peter Robinson --- board/raspberrypi/rpi/rpi.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 6f96c1ebc96..f9b643555dd 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -334,13 +334,27 @@ int dram_init(void) #ifdef CONFIG_OF_BOARD int dram_init_banksize(void) { + phys_addr_t total_size = 0; + int i; int ret; ret = fdtdec_setup_memory_banksize(); if (ret) return ret; - return fdtdec_setup_mem_size_base(); + ret = fdtdec_setup_mem_size_base(); + if (ret) + return ret; + + /* Update gd->ram_size to reflect total RAM across all banks */ + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + if (gd->bd->bi_dram[i].size == 0) + break; + total_size += gd->bd->bi_dram[i].size; + } + gd->ram_size = total_size; + + return 0; } #endif -- cgit v1.3.1 From b17c28488b31e44279b58e87fd838f601c393176 Mon Sep 17 00:00:00 2001 From: Nikunj Kela Date: Thu, 28 Aug 2025 21:12:32 -0700 Subject: net: xgmac: Augment mdio read/write with cl-45 format support Currently, clause-22 format is supported. This change adds support for clause-45 format. Signed-off-by: Nikunj Kela Reviewed-by: Boon Khai Ng Tested-by: Boon Khai Ng Reviewed-by: Boon Khai Ng Tested-by: Boon Khai Ng Reviewed-by: Tien Fong Chee --- drivers/net/dwc_eth_xgmac.c | 60 ++++++++++++++++++++++++++++++--------------- drivers/net/dwc_eth_xgmac.h | 1 + 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/drivers/net/dwc_eth_xgmac.c b/drivers/net/dwc_eth_xgmac.c index d29d871ea8c..458b87af7a2 100644 --- a/drivers/net/dwc_eth_xgmac.c +++ b/drivers/net/dwc_eth_xgmac.c @@ -140,9 +140,34 @@ static int xgmac_mdio_wait_idle(struct xgmac_priv *xgmac) XGMAC_TIMEOUT_100MS, true); } +static u32 xgmac_set_clause(struct xgmac_priv *xgmac, int mdio_addr, int mdio_devad, + int mdio_reg, bool is_c45) +{ + u32 hw_addr; + u32 val; + + if (is_c45) { + val = readl(&xgmac->mac_regs->mdio_clause_22_port); + val &= ~BIT(mdio_addr); + writel(val, &xgmac->mac_regs->mdio_clause_22_port); + hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) | + (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C45P_MASK); + hw_addr |= mdio_devad << XGMAC_MAC_MDIO_ADDRESS_DA_SHIFT; + } else { + /* Set clause 22 format */ + val = BIT(mdio_addr); + writel(val, &xgmac->mac_regs->mdio_clause_22_port); + hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) | + (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK); + } + + return hw_addr; +} + static int xgmac_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad, int mdio_reg) { + bool is_c45 = (mdio_devad != MDIO_DEVAD_NONE); struct xgmac_priv *xgmac = bus->priv; u32 val; u32 hw_addr; @@ -159,19 +184,16 @@ static int xgmac_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad, return ret; } - /* Set clause 22 format */ - val = BIT(mdio_addr); - writel(val, &xgmac->mac_regs->mdio_clause_22_port); - - hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) | - (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK); + hw_addr = xgmac_set_clause(xgmac, mdio_addr, mdio_devad, mdio_reg, is_c45); val = xgmac->config->config_mac_mdio << XGMAC_MAC_MDIO_ADDRESS_CR_SHIFT; - val |= XGMAC_MAC_MDIO_ADDRESS_SADDR | - XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_READ | - XGMAC_MAC_MDIO_ADDRESS_SBUSY; + if (!is_c45) + val |= XGMAC_MAC_MDIO_ADDRESS_SADDR; + + val |= XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_READ | + XGMAC_MAC_MDIO_ADDRESS_SBUSY; ret = xgmac_mdio_wait_idle(xgmac); if (ret) { @@ -203,6 +225,7 @@ static int xgmac_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad, static int xgmac_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad, int mdio_reg, u16 mdio_val) { + bool is_c45 = (mdio_devad != MDIO_DEVAD_NONE); struct xgmac_priv *xgmac = bus->priv; u32 val; u32 hw_addr; @@ -219,21 +242,18 @@ static int xgmac_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad, return ret; } - /* Set clause 22 format */ - val = BIT(mdio_addr); - writel(val, &xgmac->mac_regs->mdio_clause_22_port); - - hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) | - (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK); - - hw_addr |= (mdio_reg >> XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) << - XGMAC_MAC_MDIO_ADDRESS_DA_SHIFT; + hw_addr = xgmac_set_clause(xgmac, mdio_addr, mdio_devad, mdio_reg, is_c45); val = (xgmac->config->config_mac_mdio << XGMAC_MAC_MDIO_ADDRESS_CR_SHIFT); - val |= XGMAC_MAC_MDIO_ADDRESS_SADDR | - mdio_val | XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_WRITE | + if (!is_c45) { + hw_addr |= (mdio_reg >> XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) << + XGMAC_MAC_MDIO_ADDRESS_DA_SHIFT; + val |= XGMAC_MAC_MDIO_ADDRESS_SADDR; + } + + val |= mdio_val | XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_WRITE | XGMAC_MAC_MDIO_ADDRESS_SBUSY; ret = xgmac_mdio_wait_idle(xgmac); diff --git a/drivers/net/dwc_eth_xgmac.h b/drivers/net/dwc_eth_xgmac.h index 259f815f3f2..90c2e22997c 100644 --- a/drivers/net/dwc_eth_xgmac.h +++ b/drivers/net/dwc_eth_xgmac.h @@ -109,6 +109,7 @@ struct xgmac_mac_regs { #define XGMAC_MAC_MDIO_ADDRESS_SBUSY BIT(22) #define XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK GENMASK(4, 0) #define XGMAC_MAC_MDIO_DATA_GD_MASK GENMASK(15, 0) +#define XGMAC_MAC_MDIO_REG_ADDR_C45P_MASK GENMASK(15, 0) /* MTL Registers */ -- cgit v1.3.1 From 2b30c416f0b210328fc5869f90926e346da08521 Mon Sep 17 00:00:00 2001 From: Tanmay Kathpalia Date: Wed, 15 Oct 2025 08:44:45 -0700 Subject: gpio: dwapb: Enable SPL support for DWAPB GPIO driver Add SPL_DWAPB_GPIO configuration option to enable the Designware APB GPIO driver in SPL builds. Changes: - Add SPL_DWAPB_GPIO Kconfig option with SPL_DM_GPIO dependency - Update Makefile to use CONFIG_$(PHASE_)DWAPB_GPIO pattern for conditional compilation in both SPL and main U-Boot builds Signed-off-by: Tanmay Kathpalia Reviewed-by: Tom Rini Reviewed-by: Tom Rini --- drivers/gpio/Kconfig | 8 ++++++++ drivers/gpio/Makefile | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b5729a39774..2ed2bc82946 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -138,6 +138,14 @@ config DWAPB_GPIO help Support for the Designware APB GPIO driver. +config SPL_DWAPB_GPIO + bool "DWAPB GPIO driver in SPL" + depends on SPL_DM_GPIO + help + Support for the Designware APB GPIO driver in SPL. + + If unsure, say N. + config AT91_GPIO bool "AT91 PIO GPIO driver" depends on ARCH_AT91 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 73c94329e36..910478c0c7a 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -4,12 +4,12 @@ # Wolfgang Denk, DENX Software Engineering, wd@denx.de. ifndef CONFIG_XPL_BUILD -obj-$(CONFIG_DWAPB_GPIO) += dwapb_gpio.o obj-$(CONFIG_AXP_GPIO) += axp_gpio.o obj-$(CONFIG_DM_74X164) += 74x164_gpio.o endif obj-$(CONFIG_$(PHASE_)DM_GPIO) += gpio-uclass.o +obj-$(CONFIG_$(PHASE_)DWAPB_GPIO) += dwapb_gpio.o obj-$(CONFIG_$(PHASE_)DM_PCA953X) += pca953x_gpio.o obj-$(CONFIG_ADI_GPIO) += gpio-adi-adsp.o -- cgit v1.3.1 From 1feebc36e5887cbea12e3d006cc590a51a40def0 Mon Sep 17 00:00:00 2001 From: Brian Sune Date: Mon, 20 Oct 2025 21:35:54 +0800 Subject: FPGA2SDRAM setup fix After testing, w/o proper setup the FPGA2SDRAM bridge will not work and stall. Pulling from official fix and w/o this initialization, both 2025.07 and 2025.10 also suffer stall on U-Boot and distro. Any FPGA to HPS-SDRAM action will immediate stall the CPU. As such, this patch fix the issue. Signed-off-by: Brian Sune Reviewed-by: Tien Fong Chee --- arch/arm/mach-socfpga/misc_gen5.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c index b136691c685..5259ef54d73 100644 --- a/arch/arm/mach-socfpga/misc_gen5.c +++ b/arch/arm/mach-socfpga/misc_gen5.c @@ -217,6 +217,34 @@ int arch_early_init_r(void) static struct socfpga_sdr_ctrl *sdr_ctrl = (struct socfpga_sdr_ctrl *)SDR_CTRLGRP_ADDRESS; +void socfpga_sdram_apply_static_cfg(void) +{ + const u32 applymask = 0x8; + u32 val = readl(&sdr_ctrl->static_cfg) | applymask; + + /* + * SDRAM staticcfg register specific: + * When applying the register setting, the CPU must not access + * SDRAM. Luckily for us, we can use i-cache here to help us + * circumvent the SDRAM access issue. The idea is to make sure + * that the code is in one full i-cache line by branching past + * it and back. Once it is in the i-cache, we execute the core + * of the code and apply the register settings. + * + * The code below uses 7 instructions, while the Cortex-A9 has + * 32-byte cachelines, thus the limit is 8 instructions total. + */ + asm volatile(".align 5 \n" + " b 2f \n" + "1: str %0, [%1] \n" + " dsb \n" + " isb \n" + " b 3f \n" + "2: b 1b \n" + "3: nop \n" + : : "r"(val), "r"(&sdr_ctrl->static_cfg) : "memory", "cc"); +} + void do_bridge_reset(int enable, unsigned int mask) { int i; @@ -234,7 +262,10 @@ void do_bridge_reset(int enable, unsigned int mask) writel(iswgrp_handoff[2], socfpga_get_sysmgr_addr() + SYSMGR_GEN5_FPGAINFGRP_MODULE); - writel(iswgrp_handoff[3], &sdr_ctrl->fpgaport_rst); + if (iswgrp_handoff[3]) { + writel(iswgrp_handoff[3], &sdr_ctrl->fpgaport_rst); + socfpga_sdram_apply_static_cfg(); + } writel(iswgrp_handoff[0], socfpga_get_rstmgr_addr() + RSTMGR_GEN5_BRGMODRST); writel(iswgrp_handoff[1], &nic301_regs->remap); @@ -246,6 +277,7 @@ void do_bridge_reset(int enable, unsigned int mask) writel(0, socfpga_get_sysmgr_addr() + SYSMGR_GEN5_FPGAINFGRP_MODULE); writel(0, &sdr_ctrl->fpgaport_rst); + socfpga_sdram_apply_static_cfg(); writel(0x7, socfpga_get_rstmgr_addr() + RSTMGR_GEN5_BRGMODRST); writel(1, &nic301_regs->remap); } -- cgit v1.3.1 From ec4b7710f87f02e94d5418713da8c1930a5c6528 Mon Sep 17 00:00:00 2001 From: Alif Zakuan Yuslaimi Date: Thu, 23 Oct 2025 01:51:22 -0700 Subject: configs: agilex5: Enable FAT-based environment storage in defconfig Enable storing the U-Boot environment in a FAT filesystem for Agilex5. This allows the board to read and write environment variables from the first partition of the first device formatted with FAT, in addition to the existing UBI-based environment configuration. Signed-off-by: Alif Zakuan Yuslaimi Reviewed-by: Tien Fong Chee --- configs/socfpga_agilex5_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/socfpga_agilex5_defconfig b/configs/socfpga_agilex5_defconfig index bbe712f8452..64f2f1bf115 100644 --- a/configs/socfpga_agilex5_defconfig +++ b/configs/socfpga_agilex5_defconfig @@ -70,7 +70,9 @@ CONFIG_CMD_UBI=y # CONFIG_ISO_PARTITION is not set # CONFIG_EFI_PARTITION is not set CONFIG_OF_LIST="" +CONFIG_ENV_IS_IN_FAT=y CONFIG_ENV_IS_IN_UBI=y +CONFIG_ENV_FAT_DEVICE_AND_PART="0:1" CONFIG_ENV_UBI_PART="root" CONFIG_ENV_UBI_VOLUME="env" CONFIG_ENV_RELOC_GD_ENV_ADDR=y -- cgit v1.3.1 From 5eb14e1ea26c22c8994ef6a5013e26eef825c23a Mon Sep 17 00:00:00 2001 From: Boon Khai Ng Date: Mon, 27 Oct 2025 14:36:54 +0800 Subject: spi: cadence: Add driver for xSPI This patch ports the Cadence xSPI controller driver from the Linux kernel. The controller supports three operating modes: 1. ACMD (Auto Command) mode - Includes PIO and CDMA submodes. - CDMA mode uses linked descriptors for high-performance, low-overhead operation. - PIO mode is suitable for simple, single-command transactions. 2. STIG (Software Triggered Instruction Generator) mode - Issues low-level 128-bit instructions to memory. - Uses the Slave DMA interface for data transfers. 3. Direct mode - Enables direct data access through the slave interface without commands. Currently, only the STIG work mode is enabled. Additional modes will be supported in future updates. At the same time, also enabling the kconfig option for xSPI driver. This driver has been ported and functionally verified on the Intel Simics platform. It is intended for evaluation and experimental use at this stage. Link: https://lore.kernel.org/all/1632038734-23999-1-git-send-email-pthombar@cadence.com/ Signed-off-by: Boon Khai Ng Reviewed-by: Tien Fong Chee --- drivers/spi/Kconfig | 15 ++ drivers/spi/Makefile | 1 + drivers/spi/cadence_xspi.c | 449 +++++++++++++++++++++++++++++++++++++++++++++ drivers/spi/cadence_xspi.h | 226 +++++++++++++++++++++++ 4 files changed, 691 insertions(+) create mode 100644 drivers/spi/cadence_xspi.c create mode 100644 drivers/spi/cadence_xspi.h diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index c88918606d2..2afb15fff1e 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -180,6 +180,21 @@ config CADENCE_OSPI_VERSAL This option is used to enable Versal OSPI DMA operations which are used for ospi flash read using cadence qspi controller. +config CADENCE_XSPI + bool "Cadence XSPI driver (Experimental feature)" + help + Important: this feature is experimental so far and tested only + on simulated environment. + + Enable the Cadence eXpanded Serial Periheral Interface (xSPI) flash + driver. This driver can be used to access the SPI NOR flash on + platforms embedding this Cadence IP core up to 8 bit wide bus. + xSPI flash controller IP offers three work mode, Auto Command (ACMD) + work mode, Software Triggered Instruction Generator (STIG) work mode + and Direct work mode. This flash controller able to coomunicate + with Flash Memory Devices supporting JESD216 and JESD251 stadards + by using the Auto Command work mode. + config CF_SPI bool "ColdFire SPI driver" depends on M68K diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 5129d649f84..d5d1e543588 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -8,6 +8,7 @@ ifdef CONFIG_$(PHASE_)DM_SPI obj-y += spi-uclass.o obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o obj-$(CONFIG_CADENCE_OSPI_VERSAL) += cadence_ospi_versal.o +obj-$(CONFIG_CADENCE_XSPI) += cadence_xspi.o obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o obj-$(CONFIG_SOFT_SPI) += soft_spi.o obj-$(CONFIG_SPI_ASPEED_SMC) += spi-aspeed-smc.o diff --git a/drivers/spi/cadence_xspi.c b/drivers/spi/cadence_xspi.c new file mode 100644 index 00000000000..717f226b709 --- /dev/null +++ b/drivers/spi/cadence_xspi.c @@ -0,0 +1,449 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2025 + * Altera Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cadence_xspi.h" + +static int cdns_xspi_wait_for_controller_idle(struct cdns_xspi_plat *cdns_xspi) +{ + u32 ctrl_stat; + + return readl_relaxed_poll_timeout(cdns_xspi->iobase + + CDNS_XSPI_CTRL_STATUS_REG, + ctrl_stat, + !(ctrl_stat & + CDNS_XSPI_CTRL_BUSY), + 1000); +} + +static int cdns_xspi_wait_for_sdma_complete(struct cdns_xspi_plat *cdns_xspi) +{ + u32 irq_status; + int ret = 0; + + ret = readl_relaxed_poll_timeout(cdns_xspi->iobase + + CDNS_XSPI_INTR_STATUS_REG, + irq_status, + (irq_status & + CDNS_XSPI_SDMA_TRIGGER), + 1000); + + if (!ret) { + /* + * SDMA return an interrupt, need to clear + * the interrupt after read, wrtting 1 to clear the bit. + */ + setbits_le32(cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG, + CDNS_XSPI_SDMA_TRIGGER); + } + + /* Check if SDMA ERROR happened */ + if (irq_status & CDNS_XSPI_SDMA_ERROR) { + /* + * Need to clear the SDMA_ERROR interrupt + * after read, wrtting 1 to clear the bit. + */ + dev_err(cdns_xspi->dev, + "Slave DMA transaction error\n"); + + cdns_xspi->sdma_error = true; + setbits_le32(cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG, + CDNS_XSPI_SDMA_ERROR); + + ret = -EIO; + } + + return ret; +} + +static int cdns_xspi_wait_for_cmd_complete(struct cdns_xspi_plat *cdns_xspi) +{ + u32 irq_status; + int ret = 0; + + ret = readl_relaxed_poll_timeout(cdns_xspi->iobase + + CDNS_XSPI_INTR_STATUS_REG, + irq_status, + (irq_status & + CDNS_XSPI_STIG_DONE), + 100000); + + irq_status = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG); + + if (!ret) { + /* + * Need to clear the interrupt after read, + * wrtting 1 to the clear the bit. + */ + writel(irq_status & CDNS_XSPI_STIG_DONE, + cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG); + } + + return ret; +} + +static void cdns_xspi_trigger_command(struct cdns_xspi_plat *cdns_xspi, + u32 cmd_regs[6]) +{ + writel(cmd_regs[5], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_5); + writel(cmd_regs[4], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_4); + writel(cmd_regs[3], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_3); + writel(cmd_regs[2], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_2); + writel(cmd_regs[1], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_1); + writel(cmd_regs[0], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_0); +} + +static int cdns_xspi_check_command_status(struct cdns_xspi_plat *cdns_xspi) +{ + int ret = 0; + u32 cmd_status = readl(cdns_xspi->iobase + CDNS_XSPI_CMD_STATUS_REG); + + /* Check if the command has completed */ + if (cmd_status & CDNS_XSPI_CMD_STATUS_COMPLETED) { + /*Check for failure status and report each type of error */ + if ((cmd_status & CDNS_XSPI_CMD_STATUS_FAILED) != 0) { + if (cmd_status & CDNS_XSPI_CMD_STATUS_DQS_ERROR) + dev_err(cdns_xspi->dev, + "Incorrect DQS pulses detected\n"); + + if (cmd_status & CDNS_XSPI_CMD_STATUS_CRC_ERROR) + dev_err(cdns_xspi->dev, + "CRC error received\n"); + + if (cmd_status & CDNS_XSPI_CMD_STATUS_BUS_ERROR) + dev_err(cdns_xspi->dev, + "Error resp on system DMA interface\n"); + + if (cmd_status & CDNS_XSPI_CMD_STATUS_INV_SEQ_ERROR) + dev_err(cdns_xspi->dev, + "Invalid command sequence detected\n"); + + ret = -EPROTO; + } + } else { + /* Command did not complete at all -- fatal error */ + dev_err(cdns_xspi->dev, "Fatal err - command not completed\n"); + ret = -EPROTO; + } + + return ret; +} + +static void cdns_xspi_set_interrupts(struct cdns_xspi_plat *cdns_xspi, + bool enabled) +{ + u32 intr_enable; + + intr_enable = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG); + if (enabled) + intr_enable |= CDNS_XSPI_INTR_MASK; + else + intr_enable &= ~CDNS_XSPI_INTR_MASK; + writel(intr_enable, cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG); +} + +static int cdns_xspi_controller_init(struct cdns_xspi_plat *cdns_xspi) +{ + u32 ctrl_ver; + u32 ctrl_features; + u16 hw_magic_num; + + ctrl_ver = readl(cdns_xspi->iobase + CDNS_XSPI_CTRL_VERSION_REG); + hw_magic_num = FIELD_GET(CDNS_XSPI_MAGIC_NUM, ctrl_ver); + if (hw_magic_num != CDNS_XSPI_MAGIC_NUM_VALUE) { + dev_err(cdns_xspi->dev, + "Incorrect XSPI magic number: %x, expected: %x\n", + hw_magic_num, CDNS_XSPI_MAGIC_NUM_VALUE); + return -ENXIO; + } + + ctrl_features = readl(cdns_xspi->iobase + CDNS_XSPI_CTRL_FEATURES_REG); + cdns_xspi->hw_num_banks = FIELD_GET(CDNS_XSPI_NUM_BANKS, ctrl_features); + cdns_xspi->set_interrupts_handler(cdns_xspi, false); + + return 0; +} + +static void cdns_xspi_sdma_handle(struct cdns_xspi_plat *cdns_xspi) +{ + u32 sdma_size, sdma_trd_info; + u8 sdma_dir; + u8 *in_buf; + u8 *out_buf; + + sdma_size = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_SIZE_REG); + sdma_trd_info = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_TRD_INFO_REG); + sdma_dir = FIELD_GET(CDNS_XSPI_SDMA_DIR, sdma_trd_info); + + in_buf = (u8 *)cdns_xspi->in_buffer; + out_buf = (u8 *)cdns_xspi->out_buffer; + + switch (sdma_dir) { + case CDNS_XSPI_SDMA_DIR_READ: + if (in_buf) + memcpy_fromio(in_buf, cdns_xspi->sdmabase, sdma_size); + break; + + case CDNS_XSPI_SDMA_DIR_WRITE: + if (in_buf) + memcpy_toio(cdns_xspi->sdmabase, out_buf, sdma_size); + break; + + default: + /* Handle unexpected direction */ + dev_warn(cdns_xspi->dev, + "Unknown SDMA direction: %u\n", sdma_dir); + break; + } +} + +static int cdns_xspi_send_stig_command(struct cdns_xspi_plat *cdns_xspi, + const struct spi_mem_op *op, + bool data_phase) +{ + u32 cmd_regs[6] = {0}; + int ret = 0; + int dummybytes = op->dummy.nbytes; + + ret = cdns_xspi_wait_for_controller_idle(cdns_xspi); + if (ret < 0) + return ret; + + writel(FIELD_PREP(CDNS_XSPI_CTRL_WORK_MODE, CDNS_XSPI_WORK_MODE_STIG), + cdns_xspi->iobase + CDNS_XSPI_CTRL_CONFIG_REG); + + cdns_xspi->set_interrupts_handler(cdns_xspi, true); + cdns_xspi->sdma_error = false; + + cmd_regs[1] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1(op, data_phase); + cmd_regs[2] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_2(op); + if (dummybytes != 0) { + cmd_regs[3] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op, 1); + dummybytes--; + } else { + cmd_regs[3] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op, 0); + } + cmd_regs[4] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4(op, + cdns_xspi->cur_cs); + + cdns_xspi_trigger_command(cdns_xspi, cmd_regs); + + if (data_phase) { + cmd_regs[0] = CDNS_XSPI_STIG_DONE_FLAG; + cmd_regs[1] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_1; + cmd_regs[2] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_2(op); + cmd_regs[3] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_3(op, dummybytes); + cmd_regs[4] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_4(op, + cdns_xspi->cur_cs); + + cdns_xspi->in_buffer = op->data.buf.in; + cdns_xspi->out_buffer = op->data.buf.out; + + cdns_xspi_trigger_command(cdns_xspi, cmd_regs); + + cdns_xspi_wait_for_sdma_complete(cdns_xspi); + + if (cdns_xspi->sdma_error) { + cdns_xspi->set_interrupts_handler(cdns_xspi, false); + return -EIO; + } + cdns_xspi_sdma_handle(cdns_xspi); + } + + cdns_xspi_wait_for_cmd_complete(cdns_xspi); + ret = cdns_xspi_check_command_status(cdns_xspi); + if (ret) + return ret; + + return 0; +} + +static int cdns_xspi_mem_op(struct udevice *bus, + const struct spi_mem_op *op, + unsigned int cs) +{ + struct cdns_xspi_plat *plat = dev_get_plat(bus); + enum spi_mem_data_dir dir = op->data.dir; + + if (plat->cur_cs != cs) + plat->cur_cs = cs; + + return cdns_xspi_send_stig_command(plat, op, + (dir != SPI_MEM_NO_DATA)); +} + +static int cdns_xspi_mem_op_execute(struct spi_slave *spi, + const struct spi_mem_op *op) +{ + struct udevice *bus = spi->dev->parent; + unsigned int cs = 0; + int ret = 0; + + cs = spi_chip_select(spi->dev); + + if (cs < 0) { + /* + * spi_chip_select will return error number when not + * able to get chip select. + */ + pr_err("%s: Unable to get chip select, ret=%d", + spi->dev->name, cs); + return cs; + } + + ret = cdns_xspi_mem_op(bus, op, cs); + + return ret; +} + +static int cdns_xspi_adjust_mem_op_size(struct spi_slave *spi, + struct spi_mem_op *op) +{ + struct udevice *bus = spi->dev->parent; + struct cdns_xspi_plat *plat = dev_get_plat(bus); + + op->data.nbytes = clamp_val(op->data.nbytes, 0, plat->sdmasize); + + return 0; +} + +static const struct spi_controller_mem_ops cadence_xspi_mem_ops = { + .exec_op = cdns_xspi_mem_op_execute, + .adjust_op_size = cdns_xspi_adjust_mem_op_size, +}; + +static void cdns_xspi_print_phy_config(struct cdns_xspi_plat *cdns_xspi) +{ + struct device *dev = cdns_xspi->dev; + + dev_info(dev, "PHY configuration\n"); + dev_info(dev, " * xspi_dll_phy_ctrl: %08x\n", + readl(cdns_xspi->iobase + CDNS_XSPI_DLL_PHY_CTRL)); + dev_info(dev, " * phy_dq_timing: %08x\n", + readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DQ_TIMING)); + dev_info(dev, " * phy_dqs_timing: %08x\n", + readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DQS_TIMING)); + dev_info(dev, " * phy_gate_loopback_ctrl: %08x\n", + readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_GATE_LPBCK_CTRL)); + dev_info(dev, " * phy_dll_slave_ctrl: %08x\n", + readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL)); +} + +static int cdns_xspi_probe(struct udevice *bus) +{ + struct cdns_xspi_plat *cdns_xspi = dev_get_plat(bus); + struct resource res; + int ret = 0; + + cdns_xspi->sdma_handler = &cdns_xspi_sdma_handle; + cdns_xspi->set_interrupts_handler = &cdns_xspi_set_interrupts; + cdns_xspi->cur_cs = 0; + + ret = dev_read_resource_byname(bus, "io", &res); + if (ret) + return ret; + + cdns_xspi->iobase = devm_ioremap(bus, res.start, resource_size(&res)); + + if (IS_ERR(cdns_xspi->iobase)) { + dev_err(bus, "Failed to remap controller base address\n"); + return PTR_ERR(cdns_xspi->iobase); + } + + ret = dev_read_resource_byname(bus, "sdma", &res); + if (ret) + return ret; + + cdns_xspi->sdmabase = devm_ioremap(bus, res.start, resource_size(&res)); + + if (IS_ERR(cdns_xspi->sdmabase)) { + dev_err(bus, "Failed to remap SDMA address\n"); + return PTR_ERR(cdns_xspi->sdmabase); + } + cdns_xspi->sdmasize = resource_size(&res); + + ret = dev_read_resource_byname(bus, "aux", &res); + if (ret) + return ret; + + cdns_xspi->auxbase = devm_ioremap(bus, res.start, resource_size(&res)); + + if (IS_ERR(cdns_xspi->auxbase)) { + dev_err(bus, "Failed to remap AUX address\n"); + return PTR_ERR(cdns_xspi->auxbase); + } + + cdns_xspi_print_phy_config(cdns_xspi); + + ret = cdns_xspi_controller_init(cdns_xspi); + + if (ret) { + dev_err(bus, "Failed to initialize controller\n"); + return ret; + } + + return 0; +} + +static int cdns_xspi_remove(struct udevice *dev) +{ + struct cdns_xspi_plat *plat = dev_get_plat(dev); + int ret = 0; + + if (plat->resets) + ret = reset_release_bulk(plat->resets); + + return ret; +} + +static int cadence_spi_set_speed(struct udevice *bus, uint hz) +{ + return 0; +} + +static int cadence_spi_set_mode(struct udevice *bus, uint mode) +{ + return 0; +} + +static const struct dm_spi_ops cdns_xspi_ops = { + .set_speed = cadence_spi_set_speed, + .set_mode = cadence_spi_set_mode, + .mem_ops = &cadence_xspi_mem_ops, +}; + +static const struct udevice_id cdns_xspi_of_match[] = { + { + .compatible = "cdns,xspi-nor", + }, + {/* end of table */} +}; + +U_BOOT_DRIVER(cadence_xspi) = { + .name = CDNS_XSPI_NAME, + .id = UCLASS_SPI, + .of_match = cdns_xspi_of_match, + .ops = &cdns_xspi_ops, + .probe = cdns_xspi_probe, + .remove = cdns_xspi_remove, + .flags = DM_FLAG_OS_PREPARE, +}; diff --git a/drivers/spi/cadence_xspi.h b/drivers/spi/cadence_xspi.h new file mode 100644 index 00000000000..e408d27303f --- /dev/null +++ b/drivers/spi/cadence_xspi.h @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2025 + * Altera Corporation + */ + +#ifndef __CADENCE_XSPI_H__ +#define __CADENCE_XSPI_H__ + +#include +#include +#include +#include +#include + +#define CDNS_XSPI_MAGIC_NUM_VALUE 0x6522 +#define CDNS_XSPI_MAX_BANKS 8 +#define CDNS_XSPI_NAME "cadence_xspi" + +/* + * Note: below are additional auxiliary registers to + * configure XSPI controller pin-strap settings + */ + +/* PHY DQ timing register */ +#define CDNS_XSPI_CCP_PHY_DQ_TIMING 0x0000 + +/* PHY DQS timing register */ +#define CDNS_XSPI_CCP_PHY_DQS_TIMING 0x0004 + +/* PHY gate loopback control register */ +#define CDNS_XSPI_CCP_PHY_GATE_LPBCK_CTRL 0x0008 + +/* PHY DLL slave control register */ +#define CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL 0x0010 + +/* DLL PHY control register */ +#define CDNS_XSPI_DLL_PHY_CTRL 0x1034 + +/* Command registers */ +#define CDNS_XSPI_CMD_REG_0 0x0000 +#define CDNS_XSPI_CMD_REG_1 0x0004 +#define CDNS_XSPI_CMD_REG_2 0x0008 +#define CDNS_XSPI_CMD_REG_3 0x000C +#define CDNS_XSPI_CMD_REG_4 0x0010 +#define CDNS_XSPI_CMD_REG_5 0x0014 + +/* Command status registers */ +#define CDNS_XSPI_CMD_STATUS_REG 0x0044 + +/* Controller status register */ +#define CDNS_XSPI_CTRL_STATUS_REG 0x0100 +#define CDNS_XSPI_INIT_COMPLETED BIT(16) +#define CDNS_XSPI_INIT_LEGACY BIT(9) +#define CDNS_XSPI_INIT_FAIL BIT(8) +#define CDNS_XSPI_CTRL_BUSY BIT(7) + +/* Controller interrupt status register */ +#define CDNS_XSPI_INTR_STATUS_REG 0x0110 +#define CDNS_XSPI_STIG_DONE BIT(23) +#define CDNS_XSPI_SDMA_ERROR BIT(22) +#define CDNS_XSPI_SDMA_TRIGGER BIT(21) +#define CDNS_XSPI_CMD_IGNRD_EN BIT(20) +#define CDNS_XSPI_DDMA_TERR_EN BIT(18) +#define CDNS_XSPI_CDMA_TREE_EN BIT(17) +#define CDNS_XSPI_CTRL_IDLE_EN BIT(16) + +#define CDNS_XSPI_TRD_COMP_INTR_STATUS 0x0120 +#define CDNS_XSPI_TRD_ERR_INTR_STATUS 0x0130 +#define CDNS_XSPI_TRD_ERR_INTR_EN 0x0134 + +/* Controller interrupt enable register */ +#define CDNS_XSPI_INTR_ENABLE_REG 0x0114 +#define CDNS_XSPI_INTR_EN BIT(31) +#define CDNS_XSPI_STIG_DONE_EN BIT(23) +#define CDNS_XSPI_SDMA_ERROR_EN BIT(22) +#define CDNS_XSPI_SDMA_TRIGGER_EN BIT(21) + +#define CDNS_XSPI_INTR_MASK (CDNS_XSPI_INTR_EN | \ + CDNS_XSPI_STIG_DONE_EN | \ + CDNS_XSPI_SDMA_ERROR_EN | \ + CDNS_XSPI_SDMA_TRIGGER_EN) + +/* Controller config register */ +#define CDNS_XSPI_CTRL_CONFIG_REG 0x0230 +#define CDNS_XSPI_CTRL_WORK_MODE GENMASK(6, 5) + +#define CDNS_XSPI_WORK_MODE_DIRECT 0 +#define CDNS_XSPI_WORK_MODE_STIG 1 +#define CDNS_XSPI_WORK_MODE_ACMD 3 + +/* SDMA trigger transaction registers */ +#define CDNS_XSPI_SDMA_SIZE_REG 0x0240 +#define CDNS_XSPI_SDMA_TRD_INFO_REG 0x0244 +#define CDNS_XSPI_SDMA_DIR BIT(8) + +/* Controller features register */ +#define CDNS_XSPI_CTRL_FEATURES_REG 0x0F04 +#define CDNS_XSPI_NUM_BANKS GENMASK(25, 24) +#define CDNS_XSPI_DMA_DATA_WIDTH BIT(21) +#define CDNS_XSPI_NUM_THREADS GENMASK(3, 0) + +/* Controller version register */ +#define CDNS_XSPI_CTRL_VERSION_REG 0x0F00 +#define CDNS_XSPI_MAGIC_NUM GENMASK(31, 16) +#define CDNS_XSPI_CTRL_REV GENMASK(7, 0) + +/* STIG Profile 1.0 instruction fields (split into registers) */ +#define CDNS_XSPI_CMD_INSTR_TYPE GENMASK(6, 0) +#define CDNS_XSPI_CMD_P1_R1_ADDR0 GENMASK(31, 24) +#define CDNS_XSPI_CMD_P1_R2_ADDR1 GENMASK(7, 0) +#define CDNS_XSPI_CMD_P1_R2_ADDR2 GENMASK(15, 8) +#define CDNS_XSPI_CMD_P1_R2_ADDR3 GENMASK(23, 16) +#define CDNS_XSPI_CMD_P1_R2_ADDR4 GENMASK(31, 24) +#define CDNS_XSPI_CMD_P1_R3_ADDR5 GENMASK(7, 0) +#define CDNS_XSPI_CMD_P1_R3_CMD GENMASK(23, 16) +#define CDNS_XSPI_CMD_P1_R3_NUM_ADDR_BYTES GENMASK(30, 28) +#define CDNS_XSPI_CMD_P1_R4_ADDR_IOS GENMASK(1, 0) +#define CDNS_XSPI_CMD_P1_R4_CMD_IOS GENMASK(9, 8) +#define CDNS_XSPI_CMD_P1_R4_BANK GENMASK(14, 12) + +/* STIG data sequence instruction fields (split into registers) */ +#define CDNS_XSPI_CMD_DSEQ_R2_DCNT_L GENMASK(31, 16) +#define CDNS_XSPI_CMD_DSEQ_R3_DCNT_H GENMASK(15, 0) +#define CDNS_XSPI_CMD_DSEQ_R3_NUM_OF_DUMMY GENMASK(25, 20) +#define CDNS_XSPI_CMD_DSEQ_R4_BANK GENMASK(14, 12) +#define CDNS_XSPI_CMD_DSEQ_R4_DATA_IOS GENMASK(9, 8) +#define CDNS_XSPI_CMD_DSEQ_R4_DIR BIT(4) + +/* STIG command status fields */ +#define CDNS_XSPI_CMD_STATUS_COMPLETED BIT(15) +#define CDNS_XSPI_CMD_STATUS_FAILED BIT(14) +#define CDNS_XSPI_CMD_STATUS_DQS_ERROR BIT(3) +#define CDNS_XSPI_CMD_STATUS_CRC_ERROR BIT(2) +#define CDNS_XSPI_CMD_STATUS_BUS_ERROR BIT(1) +#define CDNS_XSPI_CMD_STATUS_INV_SEQ_ERROR BIT(0) + +#define CDNS_XSPI_STIG_DONE_FLAG BIT(0) +#define CDNS_XSPI_TRD_STATUS 0x0104 + +#define MODE_NO_OF_BYTES GENMASK(25, 24) +#define MODEBYTES_COUNT 1 + +/* Helper macros for filling command registers */ +#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1(op, data_phase) ( \ + FIELD_PREP(CDNS_XSPI_CMD_INSTR_TYPE, (data_phase) ? \ + CDNS_XSPI_STIG_INSTR_TYPE_1 : CDNS_XSPI_STIG_INSTR_TYPE_0) | \ + FIELD_PREP(CDNS_XSPI_CMD_P1_R1_ADDR0, (op)->addr.val & 0xff)) + +#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_2(op) ( \ + FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR1, ((op)->addr.val >> 8) & 0xFF) | \ + FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR2, ((op)->addr.val >> 16) & 0xFF) | \ + FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR3, ((op)->addr.val >> 24) & 0xFF) | \ + FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR4, ((op)->addr.val >> 32) & 0xFF)) + +#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op, modebytes) ( \ + FIELD_PREP(CDNS_XSPI_CMD_P1_R3_ADDR5, ((op)->addr.val >> 40) & 0xFF) | \ + FIELD_PREP(CDNS_XSPI_CMD_P1_R3_CMD, (op)->cmd.opcode) | \ + FIELD_PREP(MODE_NO_OF_BYTES, modebytes) | \ + FIELD_PREP(CDNS_XSPI_CMD_P1_R3_NUM_ADDR_BYTES, (op)->addr.nbytes)) + +#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4(op, chipsel) ( \ + FIELD_PREP(CDNS_XSPI_CMD_P1_R4_ADDR_IOS, ilog2((op)->addr.buswidth)) | \ + FIELD_PREP(CDNS_XSPI_CMD_P1_R4_CMD_IOS, ilog2((op)->cmd.buswidth)) | \ + FIELD_PREP(CDNS_XSPI_CMD_P1_R4_BANK, chipsel)) + +#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_1 \ + FIELD_PREP(CDNS_XSPI_CMD_INSTR_TYPE, CDNS_XSPI_STIG_INSTR_TYPE_DATA_SEQ) + +#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_2(op) \ + FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R2_DCNT_L, (op)->data.nbytes & 0xFFFF) + +#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_3(op, dummybytes) ( \ + FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_DCNT_H, \ + ((op)->data.nbytes >> 16) & 0xffff) | \ + FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_NUM_OF_DUMMY, \ + (op)->dummy.buswidth != 0 ? \ + (((dummybytes) * 8) / (op)->dummy.buswidth) : \ + 0)) + +#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_4(op, chipsel) ( \ + FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R4_BANK, chipsel) | \ + FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R4_DATA_IOS, \ + ilog2((op)->data.buswidth)) | \ + FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R4_DIR, \ + ((op)->data.dir == SPI_MEM_DATA_IN) ? \ + CDNS_XSPI_STIG_CMD_DIR_READ : CDNS_XSPI_STIG_CMD_DIR_WRITE)) + +enum cdns_xspi_stig_instr_type { + CDNS_XSPI_STIG_INSTR_TYPE_0, + CDNS_XSPI_STIG_INSTR_TYPE_1, + CDNS_XSPI_STIG_INSTR_TYPE_DATA_SEQ = 127, +}; + +enum cdns_xspi_sdma_dir { + CDNS_XSPI_SDMA_DIR_READ, + CDNS_XSPI_SDMA_DIR_WRITE, +}; + +enum cdns_xspi_stig_cmd_dir { + CDNS_XSPI_STIG_CMD_DIR_READ, + CDNS_XSPI_STIG_CMD_DIR_WRITE, +}; + +struct cdns_xspi_plat { + struct device *dev; + struct reset_ctl_bulk *resets; + + void __iomem *iobase; + void __iomem *auxbase; + void __iomem *sdmabase; + + int cur_cs; + unsigned int sdmasize; + bool sdma_error; + + void *in_buffer; + const void *out_buffer; + + u8 hw_num_banks; + + void (*sdma_handler)(struct cdns_xspi_plat *cdns_xspi); + void (*set_interrupts_handler)(struct cdns_xspi_plat *cdns_xspi, bool enabled); +}; + +#endif /* __CADENCE_XSPI_H__ */ -- cgit v1.3.1 From 3ba9b1f7bd7e7c47ff2768fc88abeb249400d374 Mon Sep 17 00:00:00 2001 From: Brian Sune Date: Sat, 1 Nov 2025 02:04:19 +0800 Subject: Cyclone V Board handsoff script Since turning from old build flow. New Altera SoCFPGA requires converting handsoff conversion via the python script. This is from official provided, and now sync to U-Boot with better location at tools/cv_xxxx. Meantime, requirement.txt is also provided to further explain the libraries require for these scripts. Signed-off-by: Brian Sune Reviewed-by: Tien Fong Chee --- tools/cv_bsp_generator/cv_bsp_generator.py | 100 +++++ tools/cv_bsp_generator/doc.py | 243 ++++++++++++ tools/cv_bsp_generator/emif.py | 424 +++++++++++++++++++++ tools/cv_bsp_generator/hps.py | 571 +++++++++++++++++++++++++++++ tools/cv_bsp_generator/iocsr.py | 203 ++++++++++ tools/cv_bsp_generator/model.py | 114 ++++++ tools/cv_bsp_generator/renderer.py | 196 ++++++++++ tools/cv_bsp_generator/requirements.txt | 5 + tools/cv_bsp_generator/streamer.py | 102 ++++++ tools/cv_bsp_generator/xmlgrok.py | 32 ++ 10 files changed, 1990 insertions(+) create mode 100755 tools/cv_bsp_generator/cv_bsp_generator.py create mode 100755 tools/cv_bsp_generator/doc.py create mode 100755 tools/cv_bsp_generator/emif.py create mode 100755 tools/cv_bsp_generator/hps.py create mode 100755 tools/cv_bsp_generator/iocsr.py create mode 100755 tools/cv_bsp_generator/model.py create mode 100755 tools/cv_bsp_generator/renderer.py create mode 100644 tools/cv_bsp_generator/requirements.txt create mode 100755 tools/cv_bsp_generator/streamer.py create mode 100755 tools/cv_bsp_generator/xmlgrok.py diff --git a/tools/cv_bsp_generator/cv_bsp_generator.py b/tools/cv_bsp_generator/cv_bsp_generator.py new file mode 100755 index 00000000000..aff597d3978 --- /dev/null +++ b/tools/cv_bsp_generator/cv_bsp_generator.py @@ -0,0 +1,100 @@ +#! /usr/bin/env python +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +""" +Bsp preloader header file generator + +Process the handoff files from Quartus and convert them to headers +usable by U-Boot. Includes the qts filter.sh capability to generate +correct format for headers to be used for mainline Uboot on FPGA, +namely Cyclone V & Arria V. + +Copyright (C) 2022 Intel Corporation + +Author: Lee, Kah Jing +""" +import glob +import optparse +import os +import shutil +import emif +import hps +import iocsr +import renderer +import model +import collections +import sys + +def printUsage(): + """ usage string """ + print ("Usage:\n\t%s\n" % ("sys.argv[0], --input_dir= --output_dir=")) + exit(1) + +def verifyInputDir(dir): + """ check if the input directory exists """ + if not os.path.isdir(dir): + print ("There is no such directory '%s'!\n" % (dir)) + exit(1) + +def verifyOutputDir(dir): + """ check if the output directory exists """ + if not os.path.isdir(dir): + os.makedirs(dir) + +if __name__ == '__main__': + # Do some rudimentary command line processing until it is proven we need something + # heavier, such as argparse (preferred, but 2.7+ only) or optparse + + inputDir = '.' + outputDir = '.' + + progVersion = '%prog 1.0' + progDesc = 'Generate board-specific files for the preloader' + optParser = optparse.OptionParser(version=progVersion, description=progDesc) + optParser.add_option('-i', '--input-dir', action='store', type='string', dest='inputDir', default='.', + help='input-dir is usually the iswinfo directory') + optParser.add_option('-o', '--output-dir', action='store', type='string', dest='outputDir', default='.', + help='output-dir is usually the directory containing the preloader source') + + (options, args) = optParser.parse_args() + + for arg in args: + print ("***WARNING: I don't understand '%s', so I am ignoring it\n" % (arg)) + + inputDir = options.inputDir + verifyInputDir(inputDir) + outputDir = options.outputDir + + verifyOutputDir(outputDir) + + emif = emif.EMIFGrokker(inputDir, outputDir, 'emif.xml') + hps = hps.HPSGrokker(inputDir, outputDir) + + pllConfigH = outputDir + "/" + "pll_config.h" + print ("Generating file: " + pllConfigH) + hpsModel = model.hps.create(inputDir + "/" + "hps.xml") + emifModel = model.emif.create(inputDir +"/" + "emif.xml") + + content=str(renderer.pll_config_h(hpsModel, emifModel)) + f = open(pllConfigH, "w") + f.write(content) + f.close() + + # For all the .hiof files, make a iocsr_config.[h|c] + # Only support single hiof file currently + hiof_list = glob.glob(inputDir + os.sep + "*.hiof") + if len(hiof_list) < 1: + print ("***Error: No .hiof files found in input!") + + elif len(hiof_list) > 1: + print ("***Error: We don't handle more than one .hiof file yet") + print (" Only the last .hiof file in the list will be converted") + print (" hiof files found:") + for f in hiof_list: + print (" " + f) + + for hiof_file_path in hiof_list: + hiof_file = os.path.basename(hiof_file_path) + # Avoid IOCSRGrokker having to parse hps.xml to determine + # device family for output file name, instead we'll just + # get it from HPSGrokker + iocsr = iocsr.IOCSRGrokker(hps.getDeviceFamily(), inputDir, outputDir, hiof_file) diff --git a/tools/cv_bsp_generator/doc.py b/tools/cv_bsp_generator/doc.py new file mode 100755 index 00000000000..86c5726c5f1 --- /dev/null +++ b/tools/cv_bsp_generator/doc.py @@ -0,0 +1,243 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +""" +Generic document construction classes. + +These classes are templates for creating documents that are not bound +to a specific usage or data model. + +Copyright (C) 2022 Intel Corporation + +Author: Lee, Kah Jing +""" + +class document(object): + """ + An abstract document class which does not dictate + how a document should be constructed or manipulated. + + It's sole purpose is to describe the entire document + in smaller units + """ + + class entry(object): + """ + An entry is the smallest unit + """ + + def __init__(self, parent): + """ entry initialization """ + if parent != None: + parent.add(self) + + class block(entry): + """ + A block is the smallest collection unit + consists of entries and blocks. + """ + + def __init__(self, parent): + """ block initialization """ + super(document.block, self).__init__(parent) + self.entries = [] + + def add(self, entry): + """ add entry to block """ + self.entries.append(entry) + + + def __init__(self): + """ document initialization """ + self.entries = [] + + def add(self, entry): + """ add entry to entry list """ + self.entries.append(entry) + + +class text(document): + """ + A simple text document implementation + """ + + class string(document.entry): + """ + The smallest unit of a text file is a string + """ + + def __init__(self, parent, stringString=None): + """ string initialization """ + super(text.string, self).__init__(parent) + self.stringString = stringString + + def __str__(self): + """ convert None to empty string """ + if (self.stringString != None): + return self.stringString + else: + return "" + + + class line(string): + """ + A line is a string with EOL character + """ + + def __str__(self): + """ convert string with newline """ + return super(text.line, self).__str__() + "\n" + + class block(document.block): + """ + A block of text which can be made up of + strings or lines + """ + + def __str__(self): + """ concatenate strings or lines """ + blockString = "" + + for entry in self.entries: + blockString += str(entry) + + return blockString + + + def __str__(self): + """ concatenate strings or lines """ + textString = "" + + for entry in self.entries: + textString += str(entry) + + return textString + + +class c_source(text): + """ + A simple C header document implementation + """ + + class define(text.string): + """ + C header define + """ + + def __init__(self, parent, id, token=None): + """ c header constructor initialization """ + super(c_source.define, self).__init__(parent, id) + self.token = token + + def __str__(self): + """ c header to strings """ + defineString = "#define" + " " + super(c_source.define, self).__str__() + + if self.token != None: + defineString += " " + self.token + + defineString += "\n" + + return defineString + + class comment_string(text.string): + """ + C header comment + """ + + def __str__(self): + """ c comment """ + return "/*" + " " + super(c_source.comment_string, self).__str__() + " " + "*/" + + class comment_line(comment_string): + """ + C header comment with newline + """ + + def __str__(self): + """ c comment with newline """ + return super(c_source.comment_line, self).__str__() + "\n" + + class block(text.block): + """ + A simple C block string implementation + """ + + def __init__(self, parent, prologue=None, epilogue=None): + """ ifdef block string implementation """ + super(c_source.block, self).__init__(parent) + + self.prologue = None + self.epilogue = None + + if prologue != None: + self.prologue = prologue + + if epilogue != None: + self.epilogue = epilogue + + def __str__(self): + """ convert ifdef to string """ + blockString = "" + + if self.prologue != None: + blockString += str(self.prologue) + + blockString += super(c_source.block, self).__str__() + + if self.epilogue != None: + blockString += str(self.epilogue) + + return blockString + + class comment_block(block): + """ + A simple C header block comment implementation + """ + + def __init__(self, parent, comments): + """ block comment initialization """ + super(c_source.comment_block, self).__init__(parent, "/*\n", " */\n") + for comment in comments.split("\n"): + self.add(comment) + + def add(self, entry): + """ add line to block comment """ + super(c_source.block, self).add(" * " + entry + "\n") + + class ifndef_block(block): + """ + A simple C header ifndef implementation + """ + + def __init__(self, parent, id): + """ ifndef block initialization """ + prologue = text.line(None, "#ifndef" + " " + id) + epilogue = text.block(None) + text.string(epilogue, "#endif") + text.string(epilogue, " ") + c_source.comment_line(epilogue, id) + super(c_source.ifndef_block, self).__init__(parent, prologue, epilogue) + + +class generated_c_source(c_source): + """ + Caller to generate c format files using the helper classes + """ + + def __init__(self, filename): + """ Generate c header file with license, copyright, comment, + ifdef block + """ + super(generated_c_source, self).__init__() + + self.entries.append(c_source.comment_line(None, "SPDX-License-Identifier: BSD-3-Clause")) + self.entries.append(c_source.comment_block(None, "Copyright (C) 2022 Intel Corporation ")) + self.entries.append(c_source.comment_block(None, "Altera SoCFPGA Clock and PLL configuration")) + self.entries.append(text.line(None)) + + self.body = c_source.ifndef_block(None, filename) + self.body.add(c_source.define(None, filename)) + self.entries.append(self.body) + + def add(self, entry): + """ add content to be written into c header file """ + self.body.add(entry) diff --git a/tools/cv_bsp_generator/emif.py b/tools/cv_bsp_generator/emif.py new file mode 100755 index 00000000000..143bd2da550 --- /dev/null +++ b/tools/cv_bsp_generator/emif.py @@ -0,0 +1,424 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +""" +SDRAM header file generator + +Process the handoff files from Quartus and convert them to headers +usable by U-Boot. + +Copyright (C) 2022 Intel Corporation + +Author: Lee, Kah Jing +""" + +import os +import re +import xml.dom.minidom +import streamer +import xmlgrok + +class EMIFGrokker(object): + """ parse an emif.xml input and translate to various + outputs + """ + SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_DIR = os.path.dirname(SCRIPT_DIR) + '/src' + SDRAM_FILE_HEADER = '/*\n' + ' * Altera SoCFPGA SDRAM configuration\n' + ' *\n' + ' */\n\n' + SDRAM_SENTINEL = '__SOCFPGA_SDRAM_CONFIG_H__' + SDRAM_MATCH = r'#define (CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE|CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT|CFG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT|CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT|CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES|CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES|CFG_HPS_SDR_CTRLCFG_DRAMODT_READ|CFG_HPS_SDR_CTRLCFG_DRAMODT_WRITE|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS|CFG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH|CFG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH|CFG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN|CFG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK|CFG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL|CFG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA|CFG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH|CFG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH|CFG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP|CFG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP|CFG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP|CFG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP|CFG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR|CFG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN|CFG_HPS_SDR_CTRLCFG_FPGAPORTRST|CFG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE|CFG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC|CFG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46|CFG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0|CFG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0|CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32|CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0|CFG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4|CFG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64|RW_MGR_ACTIVATE_0_AND_1|RW_MGR_ACTIVATE_0_AND_1_WAIT1|RW_MGR_ACTIVATE_0_AND_1_WAIT2|RW_MGR_ACTIVATE_1|RW_MGR_CLEAR_DQS_ENABLE|RW_MGR_EMR_OCD_ENABLE|RW_MGR_EMR|RW_MGR_EMR2|RW_MGR_EMR3|RW_MGR_GUARANTEED_READ|RW_MGR_GUARANTEED_READ_CONT|RW_MGR_GUARANTEED_WRITE|RW_MGR_GUARANTEED_WRITE_WAIT0|RW_MGR_GUARANTEED_WRITE_WAIT1|RW_MGR_GUARANTEED_WRITE_WAIT2|RW_MGR_GUARANTEED_WRITE_WAIT3|RW_MGR_IDLE|RW_MGR_IDLE_LOOP1|RW_MGR_IDLE_LOOP2|RW_MGR_INIT_RESET_0_CKE_0|RW_MGR_INIT_RESET_1_CKE_0|RW_MGR_INIT_CKE_0|RW_MGR_LFSR_WR_RD_BANK_0|RW_MGR_LFSR_WR_RD_BANK_0_DATA|RW_MGR_LFSR_WR_RD_BANK_0_DQS|RW_MGR_LFSR_WR_RD_BANK_0_NOP|RW_MGR_LFSR_WR_RD_BANK_0_WAIT|RW_MGR_LFSR_WR_RD_BANK_0_WL_1|RW_MGR_LFSR_WR_RD_DM_BANK_0|RW_MGR_LFSR_WR_RD_DM_BANK_0_DATA|RW_MGR_LFSR_WR_RD_DM_BANK_0_DQS|RW_MGR_LFSR_WR_RD_DM_BANK_0_NOP|RW_MGR_LFSR_WR_RD_DM_BANK_0_WAIT|RW_MGR_LFSR_WR_RD_DM_BANK_0_WL_1|RW_MGR_MR_CALIB|RW_MGR_MR_USER|RW_MGR_MR_DLL_RESET|RW_MGR_MRS0_DLL_RESET|RW_MGR_MRS0_DLL_RESET_MIRR|RW_MGR_MRS0_USER|RW_MGR_MRS0_USER_MIRR|RW_MGR_MRS1|RW_MGR_MRS1_MIRR|RW_MGR_MRS2|RW_MGR_MRS2_MIRR|RW_MGR_MRS3|RW_MGR_MRS3_MIRR|RW_MGR_NOP|RW_MGR_PRECHARGE_ALL|RW_MGR_READ_B2B|RW_MGR_READ_B2B_WAIT1|RW_MGR_READ_B2B_WAIT2|RW_MGR_REFRESH|RW_MGR_REFRESH_ALL|RW_MGR_RETURN|RW_MGR_SGLE_READ|RW_MGR_ZQCL|RW_MGR_TRUE_MEM_DATA_MASK_WIDTH|RW_MGR_MEM_ADDRESS_MIRRORING|RW_MGR_MEM_DATA_MASK_WIDTH|RW_MGR_MEM_DATA_WIDTH|RW_MGR_MEM_DQ_PER_READ_DQS|RW_MGR_MEM_DQ_PER_WRITE_DQS|RW_MGR_MEM_IF_READ_DQS_WIDTH|RW_MGR_MEM_IF_WRITE_DQS_WIDTH|RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM|RW_MGR_MEM_NUMBER_OF_RANKS|RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS|RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS|IO_DELAY_PER_DCHAIN_TAP|IO_DELAY_PER_DQS_EN_DCHAIN_TAP|IO_DELAY_PER_OPA_TAP|IO_DLL_CHAIN_LENGTH|IO_DQDQS_OUT_PHASE_MAX|IO_DQS_EN_DELAY_MAX|IO_DQS_EN_DELAY_OFFSET|IO_DQS_EN_PHASE_MAX|IO_DQS_IN_DELAY_MAX|IO_DQS_IN_RESERVE|IO_DQS_OUT_RESERVE|IO_IO_IN_DELAY_MAX|IO_IO_OUT1_DELAY_MAX|IO_IO_OUT2_DELAY_MAX|IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS|AFI_RATE_RATIO|AFI_CLK_FREQ|CALIB_LFIFO_OFFSET|CALIB_VFIFO_OFFSET|ENABLE_SUPER_QUICK_CALIBRATION|MAX_LATENCY_COUNT_WIDTH|READ_VALID_FIFO_SIZE|REG_FILE_INIT_SEQ_SIGNATURE|TINIT_CNTR0_VAL|TINIT_CNTR1_VAL|TINIT_CNTR2_VAL|TRESET_CNTR0_VAL|TRESET_CNTR1_VAL|TRESET_CNTR2_VAL|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP)\s+' + + SDRAM_CONFIG_H_FILENAME = "sdram_config.h" + + sdramHTemplate = "" + seqAutoTemplate = "" + seqDefinesTemplate = "" + seqAutoAcTemplate = "" + seqAutoInstTemplate = "" + seqAutoTemplateList = [] + seqDefinesTemplateList = [] + seqAutoAcTemplateList = [] + seqAutoInstTemplateList = [] + + def __init__(self, inputDir, outputDir, emifFileName='emif.xml', hpsFileName='hps.xml'): + """ EMIFGrokker initialization """ + self.inputDir = inputDir + self.outputDir = outputDir + + sdramDir = self.outputDir + if not os.path.isdir(sdramDir): + os.makedirs(sdramDir) + + self.emifFileName = inputDir + os.sep + emifFileName + self.hpsFileName = inputDir + os.sep + hpsFileName + self.emifDom = xml.dom.minidom.parse(self.emifFileName) + self.hpsDom = xml.dom.minidom.parse(self.hpsFileName) + self.sequencerDefinesStream = None + self.seqAutoFileName = inputDir + os.sep + "sequencer_auto.h" + self.seqDefinesFileName = inputDir + os.sep + "sequencer_defines.h" + self.seqAutoACFileName = inputDir + os.sep + "sequencer_auto_ac_init.c" + self.seqAutoInstFileName = inputDir + os.sep + "sequencer_auto_inst_init.c" + + self.createFilesFromEMIF() + + def openSeqFiles(self): + """ files to retrieve values to written to sdram_config.h """ + self.seq_auto_fd = open(self.seqAutoFileName, "r") + self.seq_defines_fd = open(self.seqDefinesFileName, "r") + self.seq_auto_ac_fd = open(self.seqAutoACFileName, "r") + self.seq_auto_inst_fd = open(self.seqAutoInstFileName, "r") + + def closeSeqFiles(self): + """ close files """ + self.seq_auto_fd.close() + self.seq_defines_fd.close() + self.seq_auto_ac_fd.close() + self.seq_auto_inst_fd.close() + + def processSeqAuto(self): + """ process sequencer files to retrieve variable. Regex match is from + qts-filter.sh + """ + # replace underscore & bracket in sequencer_auto.h define + for line in self.seq_auto_fd.readlines(): + if re.match(".*__RW_MGR_", line) and not re.match(".*ac_", line) and not re.match(".*CONTENT_", line): + line = re.sub("__RW_MGR", "RW_MGR", line) + if re.match(self.SDRAM_MATCH, line): + self.seqAutoTemplateList.append(re.sub(r' (\w+)(\s+)(\d+)', r' \1\t\3', line)) + self.seqAutoTemplateList.sort() + self.seqAutoTemplate = ''.join([item for item in self.seqAutoTemplateList]) + + # replace underscore & bracket in sequencer_defines.h define + for line in self.seq_defines_fd.readlines(): + if re.match("^#define (\w+_)", line): + line = re.sub("__", "", line) + if re.match(self.SDRAM_MATCH, line): + self.seqDefinesTemplateList.append(re.sub(r' (\w+)(\s+)(\d+)', r' \1\t\3', line)) + self.seqDefinesTemplateList.sort() + self.seqDefinesTemplate = ''.join([item for item in self.seqDefinesTemplateList]) + + arrayMatchStart = 0 + # replace const variable declaration in sequencer_auto_ac_init.c + for line in self.seq_auto_ac_fd.readlines(): + if re.match("^const.*\[", line) or arrayMatchStart: + if arrayMatchStart == 0: + line = line.strip() + " " + arrayMatchStart = 1 + if re.match("};", line): + arrayMatchStart = 0 + self.seqAutoAcTemplateList.append("};") + continue + line = re.sub("alt_u32", "u32", line) + self.seqAutoAcTemplateList.append(re.sub("\[.*\]", "[]", line)) + self.seqAutoAcTemplate = ''.join([item for item in self.seqAutoAcTemplateList]) + + arrayMatchStart = 0 + # replace const variable declaration in sequencer_auto_inst_init.c + for line in self.seq_auto_inst_fd.readlines(): + if re.match("^const.*\[", line) or arrayMatchStart: + if arrayMatchStart == 0: + line = line.strip() + " " + arrayMatchStart = 1 + if re.match("};", line): + arrayMatchStart = 0 + self.seqAutoInstTemplateList.append("};") + continue + line = re.sub("alt_u32", "u32", line) + self.seqAutoInstTemplateList.append(re.sub("\[.*\]", "[]", line)) + self.seqAutoInstTemplate = ''.join([item for item in self.seqAutoInstTemplateList]) + + def handleSettingNode(self, settingNode): + """ create define string from variable name and value """ + if settingNode.hasAttribute('name') and settingNode.hasAttribute('value'): + name = settingNode.getAttribute('name') + value = settingNode.getAttribute('value') + self.sequencerDefinesStream.write("#define " + name + ' ' + '(' + value + ')' + '\n') + + def updateTemplate(self, name, value): + """ update sdram template """ + pattern = "${" + name + "}" + self.sdramHTemplate = self.sdramHTemplate.replace(pattern, value) + + def handleEMIFControllerNode(self, node): + """ retrieve values from emif.xml for controller node """ + derivedNoDmPins = 0 + derivedCtrlWidth = 0 + derivedEccEn = 0 + derivedEccCorrEn = 0 + + self.mem_if_rd_to_wr_turnaround_oct = 0 + + node = xmlgrok.firstElementChild(node) + while node != None: + name = node.getAttribute('name') + value = node.getAttribute('value') + + if value == "true": + value = "1" + elif value == "false": + value = "0" + + self.updateTemplate(name, value) + + if name == "MEM_IF_DM_PINS_EN": + if value == "1": + derivedNoDmPins = 0 + else: + derivedNoDmPins = 1 + + if name == "MEM_DQ_WIDTH": + if value == "8": + derivedCtrlWidth = 0 + derivedEccEn = 0 + derivedEccCorrEn = 0 + elif value == "16": + derivedCtrlWidth = 1 + derivedEccEn = 0 + derivedEccCorrEn = 0 + elif value == "24": + derivedCtrlWidth = 1 + derivedEccEn = 1 + derivedEccCorrEn = 1 + elif value == "32": + derivedCtrlWidth = 2 + derivedEccEn = 0 + derivedEccCorrEn = 0 + elif value == "40": + derivedCtrlWidth = 2 + derivedEccEn = 1 + derivedEccCorrEn = 1 + + if name == "MEM_IF_RD_TO_WR_TURNAROUND_OCT": + self.mem_if_rd_to_wr_turnaround_oct = int(value) + + node = xmlgrok.nextElementSibling(node) + + self.updateTemplate("DERIVED_NODMPINS", str(derivedNoDmPins)) + self.updateTemplate("DERIVED_CTRLWIDTH", str(derivedCtrlWidth)) + self.updateTemplate("DERIVED_ECCEN", str(derivedEccEn)) + self.updateTemplate("DERIVED_ECCCORREN", str(derivedEccCorrEn)) + + def handleEMIFPllNode(self, node): + """ retrieve values for pll node """ + node = xmlgrok.firstElementChild(node) + while node != None: + name = node.getAttribute('name') + value = node.getAttribute('value') + + self.updateTemplate(name, value) + + node = xmlgrok.nextElementSibling(node) + + def handleEMIFSequencerNode(self, node): + """ retrieve values for sequencer node """ + derivedMemtype = 0 + derivedSelfrfshexit = 0 + + self.afi_rate_ratio = 0 + + node = xmlgrok.firstElementChild(node) + while node != None: + name = node.getAttribute('name') + value = node.getAttribute('value') + + self.updateTemplate(name, value) + + if value.isdigit(): + intValue = int(value) + else: + intValue = 0 + + if name == "DDR2" and intValue != 0: + derivedMemtype = 1 + derivedSelfrfshexit = 200 + elif name == "DDR3" and intValue != 0: + derivedMemtype = 2 + derivedSelfrfshexit = 512 + elif name == "LPDDR1" and intValue != 0: + derivedMemtype = 3 + derivedSelfrfshexit = 200 + elif name == "LPDDR2" and intValue != 0: + derivedMemtype = 4 + derivedSelfrfshexit = 200 + elif name == "AFI_RATE_RATIO" and intValue != 0: + self.afi_rate_ratio = intValue + + node = xmlgrok.nextElementSibling(node) + + self.updateTemplate("DERIVED_MEMTYPE", str(derivedMemtype)) + self.updateTemplate("DERIVED_SELFRFSHEXIT", str(derivedSelfrfshexit)) + + + def handleHpsFpgaInterfaces(self, node): + """ retrieve values for fpga interface """ + node = xmlgrok.firstElementChild(node) + + while node != None: + name = node.getAttribute('name') + value = node.getAttribute('value') + + self.updateTemplate(name, value) + + node = xmlgrok.nextElementSibling(node) + + + def createFilesFromEMIF(self): + """ create sdram_config.h with the template and value read from xml. + Different sequencer files are written to individual section, with + comment at the start. + """ + self.sdramHTemplate ="""\ +#define CFG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR 0x5A56A +#define CFG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP 0xB00088 +#define CFG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH 0x44555 +#define CFG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP 0x2C011000 +#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER ${ADDR_ORDER} +#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN ${USE_HPS_DQS_TRACKING} +#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN ${DERIVED_ECCCORREN} +#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN ${DERIVED_ECCEN} +#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL ${MEM_BURST_LENGTH} +#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE ${DERIVED_MEMTYPE} +#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS ${DERIVED_NODMPINS} +#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN 1 +#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT 10 +#define CFG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH ${DERIVED_CTRLWIDTH} +#define CFG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS ${MEM_IF_BANKADDR_WIDTH} +#define CFG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS ${MEM_IF_COL_ADDR_WIDTH} +#define CFG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS ${DEVICE_DEPTH} +#define CFG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS ${MEM_IF_ROW_ADDR_WIDTH} +#define CFG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH 8 +#define CFG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH ${MEM_DQ_WIDTH} +#define CFG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN 0 +#define CFG_HPS_SDR_CTRLCFG_DRAMODT_READ ${CFG_READ_ODT_CHIP} +#define CFG_HPS_SDR_CTRLCFG_DRAMODT_WRITE ${CFG_WRITE_ODT_CHIP} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL 0 +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL ${MEM_TCL} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL ${MEM_WTCL_INT} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW ${MEM_TFAW} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC ${MEM_TRFC} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD ${MEM_TRRD} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD ${MEM_TRCD} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI ${MEM_TREFI} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP ${MEM_TRP} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR ${MEM_TWR} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR ${MEM_TWTR} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD 4 +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD ${MEM_TMRD_CK} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS ${MEM_TRAS} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC ${MEM_TRC} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP ${MEM_TRTP} +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT 3 +#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT ${DERIVED_SELFRFSHEXIT} +#define CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR ${DERIVED_CLK_RD_TO_WR} +#define CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC ${DERIVED_CLK_RD_TO_WR} +#define CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP ${DERIVED_CLK_RD_TO_WR} +#define CFG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC 0 +#define CFG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE 0 +#define CFG_HPS_SDR_CTRLCFG_FPGAPORTRST ${F2SDRAM_RESET_PORT_USED} +#define CFG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK 3 +#define CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES 0 +#define CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES 8 +#define CFG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0 0x20820820 +#define CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32 0x8208208 +#define CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0 0 +#define CFG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4 0x41041041 +#define CFG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36 0x410410 +#define CFG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY 0x0 +#define CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0 0x01010101 +#define CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32 0x01010101 +#define CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64 0x0101 +#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0 0x21084210 +#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32 0x10441 +#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0 0x78 +#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14 0x0 +#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46 0x0 +#define CFG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0 0x200 +#define CFG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN 0 +#define CFG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP 0x760210 +#define CFG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL 2 +#define CFG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA 0 +#define CFG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP 0x980543 +""" + + # Get a list of all nodes with the emif element name + emifNodeList = self.emifDom.getElementsByTagName('emif') + if len(emifNodeList) > 1: + print ("*** WARNING:" + "Multiple emif Elements found in %s!" % self.emifFileName) + # For each of the emif element nodes, go through the child list + # Note that currently there is only one emif Element + # but this code will handle more than one emif node + # In the future, multiple emif nodes may need additional code + # to combine settings from the multiple emif Elements + for emifNode in emifNodeList: + # Currently, there are only 3 children of the emif Element: + # sequencer, controller, and pll + # but this is left open-ended for future additions to the + # specification for the emif.xml + childNode = xmlgrok.firstElementChild(emifNode) + while childNode != None: + + if childNode.nodeName == 'controller': + self.handleEMIFControllerNode(childNode) + elif childNode.nodeName == 'sequencer': + self.handleEMIFSequencerNode(childNode) + elif childNode.nodeName == 'pll': + self.handleEMIFPllNode(childNode) + + childNode = xmlgrok.nextElementSibling(childNode) + + data_rate_ratio = 2 + dwidth_ratio = self.afi_rate_ratio * data_rate_ratio + if dwidth_ratio == 0: + derivedClkRdToWr = 0 + else: + derivedClkRdToWr = (self.mem_if_rd_to_wr_turnaround_oct / (dwidth_ratio / 2)) + + if (self.mem_if_rd_to_wr_turnaround_oct % (dwidth_ratio / 2)) > 0: + derivedClkRdToWr += 1 + + self.updateTemplate("DERIVED_CLK_RD_TO_WR", str(int(derivedClkRdToWr))) + + # MPFE information are stored in hps.xml despite we generate + # them into sdram_config, so let's load hps.xml + hpsNodeList = self.hpsDom.getElementsByTagName('hps') + + for hpsNode in hpsNodeList: + + childNode = xmlgrok.firstElementChild(hpsNode) + + while childNode != None: + # MPFE info is part of fpga_interfaces + if childNode.nodeName == 'fpga_interfaces': + self.handleHpsFpgaInterfaces(childNode) + + childNode = xmlgrok.nextElementSibling(childNode) + + self.sequencerDefinesStream = streamer.Streamer(self.outputDir + os.sep + EMIFGrokker.SDRAM_CONFIG_H_FILENAME, 'w') + self.sequencerDefinesStream.open() + self.sequencerDefinesStream.writeLicenseHeader() + self.sequencerDefinesStream.write(EMIFGrokker.SDRAM_FILE_HEADER) + ret = self.sequencerDefinesStream.writeSentinelStart(EMIFGrokker.SDRAM_SENTINEL) + if ret == -1: + print("Empty header written. Exiting.") + self.sequencerDefinesStream.write("/* SDRAM configuration */\n") + self.sequencerDefinesStream.write(self.sdramHTemplate) + self.openSeqFiles() + self.processSeqAuto() + + self.sequencerDefinesStream.write("\n") + self.sequencerDefinesStream.write("/* Sequencer auto configuration */\n") + self.sequencerDefinesStream.write(self.seqAutoTemplate) + self.sequencerDefinesStream.write("\n") + self.sequencerDefinesStream.write("/* Sequencer defines configuration */\n") + self.sequencerDefinesStream.write(self.seqDefinesTemplate) + self.sequencerDefinesStream.write("\n") + self.sequencerDefinesStream.write("/* Sequencer ac_rom_init configuration */\n") + self.sequencerDefinesStream.write(self.seqAutoAcTemplate) + self.sequencerDefinesStream.write("\n\n") + self.sequencerDefinesStream.write("/* Sequencer inst_rom_init configuration */\n") + self.sequencerDefinesStream.write(self.seqAutoInstTemplate) + self.sequencerDefinesStream.write("\n") + + ret = self.sequencerDefinesStream.writeSentinelEnd(EMIFGrokker.SDRAM_SENTINEL) + if ret == -1: + print("Empty header written. Exiting.") + self.sequencerDefinesStream.close() + self.closeSeqFiles() diff --git a/tools/cv_bsp_generator/hps.py b/tools/cv_bsp_generator/hps.py new file mode 100755 index 00000000000..d702c5b4891 --- /dev/null +++ b/tools/cv_bsp_generator/hps.py @@ -0,0 +1,571 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +""" +Pinmux header file generator + +Process the hps.xml from Quartus and convert them to headers +usable by U-Boot. + +Copyright (C) 2022 Intel Corporation + +Author: Lee, Kah Jing +""" +import os +import re +import streamer +import xmlgrok +import xml.dom.minidom +import collections +import io +from io import StringIO + +class CompatStringIO(io.StringIO): + def write(self, s): + if hasattr(s, 'decode'): + # Use unicode for python2 to keep compatible + return int(super(CompatStringIO, self).write(s.decode('utf-8'))) + else: + return super(CompatStringIO, self).write(s) + def getvalue(self): + return str(super(CompatStringIO, self).getvalue()) + +class HPSGrokker(object): + + SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_DIR = os.path.dirname(SCRIPT_DIR) + '/src' + + MAKEFILE_FILENAME = "Makefile" + makefileTemplate = "" + RESET_CONFIG_H_FILENAME = "reset_config.h" + resetConfigHTemplate = "" + + # If no device family is specified, assume Cyclone V. + derivedDeviceFamily = "cyclone5" + + # Assume FPGA DMA 0-7 are not in use by default + # Note: there appears to be a weird mismatch between sopcinfo + # value vs hps.xml value of DMA_Enable of string_list hw.tcl + # type, where sopcinfo uses comma as separator e.g. + # "No,No,No,..." while hps.xml uses space as separator. + dmaEnable = "No No No No No No No No" + + def __init__(self, inputDir, outputDir, hpsFileName='hps.xml'): + """ HPSGrokker initialization """ + self.inputDir = inputDir + self.outputDir = outputDir + self.hpsInFileName = inputDir + os.sep + hpsFileName + self.dom = xml.dom.minidom.parse(self.hpsInFileName) + self.peripheralStream = None + self.pinmuxConfigBuffer = None + self.pinmuxHeaderBuffer = None + self.pinmuxHeaderFile = None + self.pinmuxArraySize = 0 + self.config_hps_ = "CFG_HPS_" + self.clockStream = None + self.pinmux_regs = self.get_default_pinmux_regs() + self.pinmux_configs = self.get_default_pinmux_configs() + self.pinmux_config_h = None + + self.createFilesFromHPS() + + def get_default_pinmux_regs(self): + """ Set default pinmux values """ + p = collections.OrderedDict() + + p['EMACIO0'] = 0 + p['EMACIO1'] = 0 + p['EMACIO2'] = 0 + p['EMACIO3'] = 0 + p['EMACIO4'] = 0 + p['EMACIO5'] = 0 + p['EMACIO6'] = 0 + p['EMACIO7'] = 0 + p['EMACIO8'] = 0 + p['EMACIO9'] = 0 + p['EMACIO10'] = 0 + p['EMACIO11'] = 0 + p['EMACIO12'] = 0 + p['EMACIO13'] = 0 + p['EMACIO14'] = 0 + p['EMACIO15'] = 0 + p['EMACIO16'] = 0 + p['EMACIO17'] = 0 + p['EMACIO18'] = 0 + p['EMACIO19'] = 0 + p['FLASHIO0'] = 0 + p['FLASHIO1'] = 0 + p['FLASHIO2'] = 0 + p['FLASHIO3'] = 0 + p['FLASHIO4'] = 0 + p['FLASHIO5'] = 0 + p['FLASHIO6'] = 0 + p['FLASHIO7'] = 0 + p['FLASHIO8'] = 0 + p['FLASHIO9'] = 0 + p['FLASHIO10'] = 0 + p['FLASHIO11'] = 0 + p['GENERALIO0'] = 0 + p['GENERALIO1'] = 0 + p['GENERALIO2'] = 0 + p['GENERALIO3'] = 0 + p['GENERALIO4'] = 0 + p['GENERALIO5'] = 0 + p['GENERALIO6'] = 0 + p['GENERALIO7'] = 0 + p['GENERALIO8'] = 0 + p['GENERALIO9'] = 0 + p['GENERALIO10'] = 0 + p['GENERALIO11'] = 0 + p['GENERALIO12'] = 0 + p['GENERALIO13'] = 0 + p['GENERALIO14'] = 0 + p['GENERALIO15'] = 0 + p['GENERALIO16'] = 0 + p['GENERALIO17'] = 0 + p['GENERALIO18'] = 0 + p['GENERALIO19'] = 0 + p['GENERALIO20'] = 0 + p['GENERALIO21'] = 0 + p['GENERALIO22'] = 0 + p['GENERALIO23'] = 0 + p['GENERALIO24'] = 0 + p['GENERALIO25'] = 0 + p['GENERALIO26'] = 0 + p['GENERALIO27'] = 0 + p['GENERALIO28'] = 0 + p['GENERALIO29'] = 0 + p['GENERALIO30'] = 0 + p['GENERALIO31'] = 0 + p['MIXED1IO0'] = 0 + p['MIXED1IO1'] = 0 + p['MIXED1IO2'] = 0 + p['MIXED1IO3'] = 0 + p['MIXED1IO4'] = 0 + p['MIXED1IO5'] = 0 + p['MIXED1IO6'] = 0 + p['MIXED1IO7'] = 0 + p['MIXED1IO8'] = 0 + p['MIXED1IO9'] = 0 + p['MIXED1IO10'] = 0 + p['MIXED1IO11'] = 0 + p['MIXED1IO12'] = 0 + p['MIXED1IO13'] = 0 + p['MIXED1IO14'] = 0 + p['MIXED1IO15'] = 0 + p['MIXED1IO16'] = 0 + p['MIXED1IO17'] = 0 + p['MIXED1IO18'] = 0 + p['MIXED1IO19'] = 0 + p['MIXED1IO20'] = 0 + p['MIXED1IO21'] = 0 + p['MIXED2IO0'] = 0 + p['MIXED2IO1'] = 0 + p['MIXED2IO2'] = 0 + p['MIXED2IO3'] = 0 + p['MIXED2IO4'] = 0 + p['MIXED2IO5'] = 0 + p['MIXED2IO6'] = 0 + p['MIXED2IO7'] = 0 + p['GPLINMUX48'] = 0 + p['GPLINMUX49'] = 0 + p['GPLINMUX50'] = 0 + p['GPLINMUX51'] = 0 + p['GPLINMUX52'] = 0 + p['GPLINMUX53'] = 0 + p['GPLINMUX54'] = 0 + p['GPLINMUX55'] = 0 + p['GPLINMUX56'] = 0 + p['GPLINMUX57'] = 0 + p['GPLINMUX58'] = 0 + p['GPLINMUX59'] = 0 + p['GPLINMUX60'] = 0 + p['GPLINMUX61'] = 0 + p['GPLINMUX62'] = 0 + p['GPLINMUX63'] = 0 + p['GPLINMUX64'] = 0 + p['GPLINMUX65'] = 0 + p['GPLINMUX66'] = 0 + p['GPLINMUX67'] = 0 + p['GPLINMUX68'] = 0 + p['GPLINMUX69'] = 0 + p['GPLINMUX70'] = 0 + p['GPLMUX0'] = 1 + p['GPLMUX1'] = 1 + p['GPLMUX2'] = 1 + p['GPLMUX3'] = 1 + p['GPLMUX4'] = 1 + p['GPLMUX5'] = 1 + p['GPLMUX6'] = 1 + p['GPLMUX7'] = 1 + p['GPLMUX8'] = 1 + p['GPLMUX9'] = 1 + p['GPLMUX10'] = 1 + p['GPLMUX11'] = 1 + p['GPLMUX12'] = 1 + p['GPLMUX13'] = 1 + p['GPLMUX14'] = 1 + p['GPLMUX15'] = 1 + p['GPLMUX16'] = 1 + p['GPLMUX17'] = 1 + p['GPLMUX18'] = 1 + p['GPLMUX19'] = 1 + p['GPLMUX20'] = 1 + p['GPLMUX21'] = 1 + p['GPLMUX22'] = 1 + p['GPLMUX23'] = 1 + p['GPLMUX24'] = 1 + p['GPLMUX25'] = 1 + p['GPLMUX26'] = 1 + p['GPLMUX27'] = 1 + p['GPLMUX28'] = 1 + p['GPLMUX29'] = 1 + p['GPLMUX30'] = 1 + p['GPLMUX31'] = 1 + p['GPLMUX32'] = 1 + p['GPLMUX33'] = 1 + p['GPLMUX34'] = 1 + p['GPLMUX35'] = 1 + p['GPLMUX36'] = 1 + p['GPLMUX37'] = 1 + p['GPLMUX38'] = 1 + p['GPLMUX39'] = 1 + p['GPLMUX40'] = 1 + p['GPLMUX41'] = 1 + p['GPLMUX42'] = 1 + p['GPLMUX43'] = 1 + p['GPLMUX44'] = 1 + p['GPLMUX45'] = 1 + p['GPLMUX46'] = 1 + p['GPLMUX47'] = 1 + p['GPLMUX48'] = 1 + p['GPLMUX49'] = 1 + p['GPLMUX50'] = 1 + p['GPLMUX51'] = 1 + p['GPLMUX52'] = 1 + p['GPLMUX53'] = 1 + p['GPLMUX54'] = 1 + p['GPLMUX55'] = 1 + p['GPLMUX56'] = 1 + p['GPLMUX57'] = 1 + p['GPLMUX58'] = 1 + p['GPLMUX59'] = 1 + p['GPLMUX60'] = 1 + p['GPLMUX61'] = 1 + p['GPLMUX62'] = 1 + p['GPLMUX63'] = 1 + p['GPLMUX64'] = 1 + p['GPLMUX65'] = 1 + p['GPLMUX66'] = 1 + p['GPLMUX67'] = 1 + p['GPLMUX68'] = 1 + p['GPLMUX69'] = 1 + p['GPLMUX70'] = 1 + p['NANDUSEFPGA'] = 0 + p['UART0USEFPGA'] = 0 + p['RGMII1USEFPGA'] = 0 + p['SPIS0USEFPGA'] = 0 + p['CAN0USEFPGA'] = 0 + p['I2C0USEFPGA'] = 0 + p['SDMMCUSEFPGA'] = 0 + p['QSPIUSEFPGA'] = 0 + p['SPIS1USEFPGA'] = 0 + p['RGMII0USEFPGA'] = 0 + p['UART1USEFPGA'] = 0 + p['CAN1USEFPGA'] = 0 + p['USB1USEFPGA'] = 0 + p['I2C3USEFPGA'] = 0 + p['I2C2USEFPGA'] = 0 + p['I2C1USEFPGA'] = 0 + p['SPIM1USEFPGA'] = 0 + p['USB0USEFPGA'] = 0 + p['SPIM0USEFPGA'] = 0 + + return p + + + def get_default_pinmux_configs(self): + """ Get default pinmux values """ + p = collections.OrderedDict() + + p['rgmii0'] = { 'name': 'CFG_HPS_EMAC0', 'used': 0 } + p['rgmii1'] = { 'name': 'CFG_HPS_EMAC1', 'used': 0 } + p['usb0'] = { 'name': 'CFG_HPS_USB0', 'used': 0 } + p['usb1'] = { 'name': 'CFG_HPS_USB1', 'used': 0 } + p['nand'] = { 'name': 'CFG_HPS_NAND', 'used': 0 } + p['sdmmc'] = { 'name': 'CFG_HPS_SDMMC', 'used': 0 } + p['CFG_HPS_SDMMC_BUSWIDTH'] = { 'name': 'CFG_HPS_SDMMC_BUSWIDTH', 'used': 0 } + p['qspi'] = { 'name': 'CFG_HPS_QSPI', 'used': 0 } + p['CFG_HPS_QSPI_CS3'] = { 'name': 'CFG_HPS_QSPI_CS3', 'used': 0 } + p['CFG_HPS_QSPI_CS2'] = { 'name': 'CFG_HPS_QSPI_CS2', 'used': 0 } + p['CFG_HPS_QSPI_CS1'] = { 'name': 'CFG_HPS_QSPI_CS1', 'used': 0 } + p['CFG_HPS_QSPI_CS0'] = { 'name': 'CFG_HPS_QSPI_CS0', 'used': 0 } + p['uart0'] = { 'name': 'CFG_HPS_UART0', 'used': 0 } + p['CFG_HPS_UART0_TX'] = { 'name': 'CFG_HPS_UART0_TX', 'used': 0 } + p['CFG_HPS_UART0_CTS'] = { 'name': 'CFG_HPS_UART0_CTS', 'used': 0 } + p['CFG_HPS_UART0_RTS'] = { 'name': 'CFG_HPS_UART0_RTS', 'used': 0 } + p['CFG_HPS_UART0_RX'] = { 'name': 'CFG_HPS_UART0_RX', 'used': 0 } + p['uart1'] = { 'name': 'CFG_HPS_UART1', 'used': 0 } + p['CFG_HPS_UART1_TX'] = { 'name': 'CFG_HPS_UART1_TX', 'used': 0 } + p['CFG_HPS_UART1_CTS'] = { 'name': 'CFG_HPS_UART1_CTS', 'used': 0 } + p['CFG_HPS_UART1_RTS'] = { 'name': 'CFG_HPS_UART1_RTS', 'used': 0 } + p['CFG_HPS_UART1_RX'] = { 'name': 'CFG_HPS_UART1_RX', 'used': 0 } + p['trace'] = { 'name': 'CFG_HPS_TRACE', 'used': 0 } + p['i2c0'] = { 'name': 'CFG_HPS_I2C0', 'used': 0 } + p['i2c1'] = { 'name': 'CFG_HPS_I2C1', 'used': 0 } + p['i2c2'] = { 'name': 'CFG_HPS_I2C2', 'used': 0 } + p['i2c3'] = { 'name': 'CFG_HPS_I2C3', 'used': 0 } + p['spim0'] = { 'name': 'CFG_HPS_SPIM0', 'used': 0 } + p['spim1'] = { 'name': 'CFG_HPS_SPIM1', 'used': 0 } + p['spis0'] = { 'name': 'CFG_HPS_SPIS0', 'used': 0 } + p['spis1'] = { 'name': 'CFG_HPS_SPIS1', 'used': 0 } + p['can0'] = { 'name': 'CFG_HPS_CAN0', 'used': 0 } + p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 } + + p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 } + p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 } + p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 } + p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 } + + return p + + def updateTemplate(self, name, value): + """ Update Makefile & reset_config.h """ + pattern = "${" + name + "}" + self.makefileTemplate = self.makefileTemplate.replace(pattern, value) + self.resetConfigHTemplate = self.resetConfigHTemplate.replace(pattern, value) + + def romanToInteger(self, roman): + """ + Convert roman numerals to integer + Since we only support I,V,X, the + supported range is 1-39 + """ + table = { 'I':1 , 'V':5, 'X':10 } + + literals = list(roman) + + value = 0 + i = 0 + + while(i < (len(literals) - 1)): + current = table[literals[i]] + next = table[literals[i + 1]] + if (current < next): + value += (next - current) + i += 2 + else: + value += current + i += 1 + + if (i < (len(literals))): + value += table[literals[i]] + + return value + + def getDeviceFamily(self): + """ Get device family """ + return self.derivedDeviceFamily + + def getDeviceFamilyName(self, deviceFamily): + """ Get device family name """ + p = re.compile('^(\w+)\s+(\w+)$') + m = p.match(deviceFamily) + return m.group(1).lower() + str(self.romanToInteger(m.group(2))) + + def handleHPSSystemNode(self, systemNode): + """ handleHPSPeripheralsNode(peripheralsNode) + peripheralsNode is a peripherals element node in hps.xml + peripheralsNode is a list of peripheralNodes + """ + configNode = xmlgrok.firstElementChild(systemNode) + while configNode != None: + + name = configNode.getAttribute('name') + value = configNode.getAttribute('value') + + self.updateTemplate(name, value) + + if name == "DEVICE_FAMILY": + self.derivedDeviceFamily = self.getDeviceFamilyName(value) + + if name == "DMA_Enable": + self.dmaEnable = value + + configNode = xmlgrok.nextElementSibling(configNode) + + def handleHPSPeripheralNode(self, peripheralNode): + """ This node of the hps.xml may contain a name, value pair + We need to: + emit a #define for the peripheral for is 'used' state + emit a #define for that pair, if it is marked 'used' + """ + peripheralNode = xmlgrok.firstElementChild(peripheralNode) + + while peripheralNode != None: + if peripheralNode.hasAttribute('name') and peripheralNode.hasAttribute('used'): + newLine = "\n" + name = peripheralNode.getAttribute('name') + used = peripheralNode.getAttribute('used') + + if used == 'true' or used == True: + used = 1 + elif used == 'false' or used == False: + used = 0 + + configs = collections.OrderedDict() + + configNode = xmlgrok.firstElementChild(peripheralNode) + while configNode != None: + config_define_name = configNode.getAttribute('name') + config_define_value = configNode.getAttribute('value') + configs[config_define_name] = config_define_value + configNode = xmlgrok.nextElementSibling(configNode) + if configNode == None: + newLine += newLine + self.pinmuxConfigBuffer.write("#define " + str(config_define_name) + ' ' + '(' + str(config_define_value) + ')' + newLine) + + entry = self.pinmux_configs[name] + define_name = entry['name'] + + if (len(configs) > 0): + self.pinmux_configs[name] = { 'name': define_name, 'used': used, 'configs': configs } + else: + self.pinmux_configs[name] = { 'name': define_name, 'used': used } + + # skip the parent peripheral node + # since only need to define child config node(s) + peripheralNode = xmlgrok.nextElementSibling(peripheralNode) + + def handleHPSPinmuxNode(self, pinmuxNode): + """ For a pinmuxNode, we may emit a #define for the name, value pair + """ + if pinmuxNode.hasAttribute('name') and pinmuxNode.hasAttribute('value'): + self.pinmuxArraySize += 1 + name = pinmuxNode.getAttribute('name') + value = pinmuxNode.getAttribute('value') + + def handleHPSPinmuxesNode(self, pinmuxesNode): + """ PinmuxesNode is a list of pinmuxNodes + """ + self.pinmuxHeaderBuffer.write(str("const u8 sys_mgr_init_table[] = {\n")) + + pinmuxNode = xmlgrok.firstElementChild(pinmuxesNode) + while pinmuxNode != None: + if pinmuxNode.hasAttribute('name') and pinmuxNode.hasAttribute('value'): + self.pinmuxArraySize += 1 + name = pinmuxNode.getAttribute('name') + value = pinmuxNode.getAttribute('value') + self.pinmux_regs[name] = value + pinmuxNode = xmlgrok.nextElementSibling(pinmuxNode) + + reg_count = 0 + pinmux_regs_count = len(self.pinmux_regs) + for reg, value in self.pinmux_regs.items(): + reg_count += 1 + if reg_count < pinmux_regs_count: + self.pinmuxHeaderBuffer.write(str("\t" + str(value) + ', /* ' + reg + ' */\n' )) + else: + self.pinmuxHeaderBuffer.write(str("\t" + str(value) + ' /* ' + reg + ' */\n' )) + + # Write the close of the pin MUX array in the header + self.pinmuxHeaderBuffer.write(str("};" )) + + def handleHPSClockNode(self, clockNode): + """ A clockNode may emit a #define for the name, frequency pair + """ + if clockNode.hasAttribute('name') and clockNode.hasAttribute('frequency'): + name = clockNode.getAttribute('name') + frequency = clockNode.getAttribute('frequency') + self.clockStream.write("#define " + name + ' ' + '(' + frequency + ')' + '\n') + + def handleHPSClocksNode(self, clocksNode): + """ A list of clockNodes is call clocksNode + """ + self.clockStream = streamer.Streamer(self.outputDir + os.sep + clocksNode.nodeName + '.h', 'w') + self.clockStream.open() + clockNode = xmlgrok.firstElementChild(clocksNode) + while clockNode != None: + self.handleHPSClockNode(clockNode) + clockNode = xmlgrok.nextElementSibling(clockNode) + + self.clockStream.close() + + def handleHpsFpgaInterfaces(self, node): + """ Update FPGA Interface registers """ + node = xmlgrok.firstElementChild(node) + + while node != None: + name = node.getAttribute('name') + used = node.getAttribute('used') + + if used == 'true': + reset = 0 + else: + reset = 1 + + if name == 'F2H_AXI_SLAVE': + self.updateTemplate("DERIVED_RESET_ASSERT_FPGA2HPS", str(reset)) + elif name == 'H2F_AXI_MASTER': + self.updateTemplate("DERIVED_RESET_ASSERT_HPS2FPGA", str(reset)) + elif name == 'LWH2F_AXI_MASTER': + self.updateTemplate("DERIVED_RESET_ASSERT_LWHPS2FPGA", str(reset)) + + node = xmlgrok.nextElementSibling(node) + + def createFilesFromHPS(self): + """ Parse xml and create pinmux_config.h """ + # Unfortunately we can't determine the file name before + # parsing the XML, so let's build up the source file + # content in string buffer + self.pinmuxHeaderBuffer = CompatStringIO() + self.pinmuxConfigBuffer = CompatStringIO() + + # Get a list of all nodes with the hps element name + hpsNodeList = self.dom.getElementsByTagName('hps') + if len(hpsNodeList) > 1: + print ("*** WARNING:" + "Multiple hps Elements found in %s!" % self.hpsInFileName) + # For each of the hps element nodes, go through the child list + # Note that currently there is only one hps Element + # but this code will handle more than one hps node + # In the future, multiple hps nodes may need additional code + # to combine settings from the multiple hps Elements + for hpsNode in hpsNodeList: + # Currently, there are only 3 children of the hps Element: + # peripherals, pin_muxes, and clocks + # but this is left open-ended for future additions to the + # specification for the hps.xml + childNode = xmlgrok.firstElementChild(hpsNode) + while childNode != None: + if childNode.nodeName == 'pin_muxes': + self.handleHPSPinmuxesNode(childNode) + elif childNode.nodeName == 'system': + self.handleHPSSystemNode(childNode) + elif childNode.nodeName == 'fpga_interfaces': + self.handleHpsFpgaInterfaces(childNode) + elif childNode.nodeName == 'peripherals': + self.handleHPSPeripheralNode(childNode) + else: + print ("***Error:Found unexpected HPS child node:%s" % childNode.nodeName) + childNode = xmlgrok.nextElementSibling(childNode) + + self.updateTemplate("DERIVED_DEVICE_FAMILY", self.derivedDeviceFamily) + + # Now we write string buffers into files once we know the device family + self.pinmux_config_h = 'pinmux_config.h' + self.pinmux_config_src = 'pinmux_config_' + self.derivedDeviceFamily + '.c' + + # Create pinmux_config .h + headerDefine = "__SOCFPGA_PINMUX_CONFIG_H__" + self.pinmuxHeaderFile = streamer.Streamer(self.outputDir + os.sep + self.pinmux_config_h, 'w') + self.pinmuxHeaderFile.open() + self.pinmuxHeaderFile.writeLicenseHeader() + self.pinmuxHeaderFile.write('/*\n * Altera SoCFPGA PinMux configuration\n */\n\n') + + self.pinmuxHeaderFile.write("#ifndef " + headerDefine + "\n") + self.pinmuxHeaderFile.write("#define " + headerDefine + "\n\n") + self.pinmuxHeaderFile.write(self.pinmuxHeaderBuffer.getvalue()) + self.pinmuxHeaderFile.write("\n#endif /* " + headerDefine + " */\n") + self.pinmuxHeaderFile.close() + + # Free up string buffers + self.pinmuxHeaderBuffer.close() + self.pinmuxConfigBuffer.close() diff --git a/tools/cv_bsp_generator/iocsr.py b/tools/cv_bsp_generator/iocsr.py new file mode 100755 index 00000000000..a6ff5dfd829 --- /dev/null +++ b/tools/cv_bsp_generator/iocsr.py @@ -0,0 +1,203 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +""" +IOCSR header file generator + +Process the hiof file from Quartus and generate iocsr header +usable by U-Boot. + +Copyright (C) 2022 Intel Corporation + +Author: Lee, Kah Jing +""" +import os +import struct +import streamer + +class IOCSRGrokker(object): + """ Decode the .hiof file and produce some C source code + """ + IOCSR_ROOT_FILENAME = 'iocsr_config' + IOCSR_SENTINEL = '__SOCFPGA_IOCSR_CONFIG_H__' + IOCSR_FILE_EXTENSION_MAX_LEN = 6 + PTAG_HPS_IOCSR_INFO = 39 + PTAG_HPS_IOCSR = 40 + PTAG_DEVICE_NAME = 2 + PTAG_TERMINATION = 8 + + def __init__(self, deviceFamily, inputDir, outputDir, hiofSrcFileName): + """ IOCSRGrokker Initialization """ + self.deviceFamily = deviceFamily + self.inputDir = inputDir + self.outputDir = outputDir + self.hiofInFileName = hiofSrcFileName + self.iocsrFileName = self.IOCSR_ROOT_FILENAME + self.headerOut = None + self.sourceOut = None + self.createFilesFromHIOF() + + @staticmethod + def byteArrayToStr(bytes): + """ Convert a list of bytes into a string + """ + # We don't like nulls + bytes = bytes.replace('\x00', '') + s = '' + for b in bytes: + s += b + return s + + @staticmethod + def getLengthData(bytes): + """ + @param: bytes is a chunk of bytes that we need to decode + There will be a ptag that we may care about. + If we care about it, we will get the length of the chunk + that the ptag cares about. + @rtype: a pair, length of chunk and the chunk itself + @return: length of the ptag chunk we care about + @return: data chunk that ptag indicates we need to decode + """ + blockSize = len(bytes) + i = 0 + bitlength = 0 + length = 0 + data = [] + + while i < blockSize: + byte = struct.unpack('B', bytes[i:i+1])[0] + i += 1 + + if byte == 1: + bitlength = struct.unpack('I', bytes[i:i+4])[0] + i += 4 + elif byte == 2: + length = struct.unpack('I', bytes[i:i+4])[0] + i += 4 + + elif byte == 5: + j = 0 + while i < blockSize: + data.append(struct.unpack('I', bytes[i:i+4])[0]) + i += 4 + j += 1 + + else: + i += 4 + + return (bitlength, data) + + + def verifyRead(self, tagWeRead, tagWeExpected): + """ verify the hiof value with tag expected """ + if tagWeRead != tagWeExpected: + print ("***Error: Expected ptag of %02d, but got %02d" % (tagWeExpected, tagWeRead)) + + def createFilesFromHIOF(self): + """ read the hiof file to create iocsr_config.h """ + self.hiofStream = streamer.Streamer(self.inputDir + os.sep + self.hiofInFileName, 'rb') + self.iocsrHeaderStream = streamer.Streamer(self.outputDir + os.sep + self.iocsrFileName + '.h', 'w') + self.hiofStream.open() + self.iocsrHeaderStream.open() + self.iocsrHeaderStream.writeLicenseHeader() + self.iocsrHeaderStream.write('/*\n * Altera SoCFPGA IOCSR configuration\n */\n\n') + ret = self.iocsrHeaderStream.writeSentinelStart(IOCSRGrokker.IOCSR_SENTINEL) + if ret == -1: + print("Empty header written. Exiting.") + + # Read the file extension (typically .hiof) + # and the file version + self.fileExtension = self.hiofStream.readBytesAsString(IOCSRGrokker.IOCSR_FILE_EXTENSION_MAX_LEN) + self.fileVersion = self.hiofStream.readUnsignedInt() + + # Now read the ptags + # Device name is first + self.programmerTag = self.hiofStream.readUnsignedShort() + self.verifyRead(self.programmerTag, self.PTAG_DEVICE_NAME) + self.deviceNameLength = self.hiofStream.readUnsignedInt() + self.deviceName = self.hiofStream.readBytesAsString(self.deviceNameLength) + + # Basic information of the HIOF files + # This is not used by the preloader generator, but we read it and ignore the + # contents. + programmerTag = self.hiofStream.readUnsignedShort() + self.verifyRead(programmerTag, self.PTAG_HPS_IOCSR_INFO) + basicHPSIOCSRInfoLength = self.hiofStream.readUnsignedInt() + self.hiofStream.read(basicHPSIOCSRInfoLength) + + # Actual content of IOCSR information + self.programmerTag1 = self.hiofStream.readUnsignedShort() + self.verifyRead(self.programmerTag1, self.PTAG_HPS_IOCSR) + self.HPSIOCSRLength1 = self.hiofStream.readUnsignedInt() + self.HPSIOCSRBytes1 = self.hiofStream.read(self.HPSIOCSRLength1) + self.HPSIOCSRDataLength1, self.HPSIOCSRData1 = IOCSRGrokker.getLengthData(self.HPSIOCSRBytes1) + + # Actual content of IOCSR information + self.programmerTag2 = self.hiofStream.readUnsignedShort() + self.verifyRead(self.programmerTag2, self.PTAG_HPS_IOCSR) + self.HPSIOCSRLength2 = self.hiofStream.readUnsignedInt() + self.HPSIOCSRBytes2 = self.hiofStream.read(self.HPSIOCSRLength2) + self.HPSIOCSRDataLength2, self.HPSIOCSRData2 = IOCSRGrokker.getLengthData(self.HPSIOCSRBytes2) + + # Actual content of IOCSR information + self.programmerTag3 = self.hiofStream.readUnsignedShort() + self.verifyRead(self.programmerTag3, self.PTAG_HPS_IOCSR) + self.HPSIOCSRLength3 = self.hiofStream.readUnsignedInt() + self.HPSIOCSRBytes3 = self.hiofStream.read(self.HPSIOCSRLength3) + self.HPSIOCSRDataLength3, self.HPSIOCSRData3 = IOCSRGrokker.getLengthData(self.HPSIOCSRBytes3) + + # Actual content of IOCSR information + self.programmerTag4 = self.hiofStream.readUnsignedShort() + self.verifyRead(self.programmerTag4, self.PTAG_HPS_IOCSR) + self.HPSIOCSRLength4 = self.hiofStream.readUnsignedInt() + self.HPSIOCSRBytes4 = self.hiofStream.read(self.HPSIOCSRLength4) + self.HPSIOCSRDataLength4, self.HPSIOCSRData4 = IOCSRGrokker.getLengthData(self.HPSIOCSRBytes4) + + # Now we should see the end of the hiof input + programmerTag = self.hiofStream.readUnsignedShort() + if 8 != programmerTag: + print ("I didn't find the end of the .hiof file when I expected to!") + + self.iocsrHeaderStream.write('#define CFG_HPS_IOCSR_SCANCHAIN0_LENGTH\t' +\ + str(self.HPSIOCSRDataLength1) + '\n') + self.iocsrHeaderStream.write('#define CFG_HPS_IOCSR_SCANCHAIN1_LENGTH\t' +\ + str(self.HPSIOCSRDataLength2) + '\n') + self.iocsrHeaderStream.write('#define CFG_HPS_IOCSR_SCANCHAIN2_LENGTH\t' +\ + str(self.HPSIOCSRDataLength3) + '\n') + self.iocsrHeaderStream.write('#define CFG_HPS_IOCSR_SCANCHAIN3_LENGTH\t' +\ + str(self.HPSIOCSRDataLength4) + '\n') + + self.iocsrHeaderStream.write("\n") + + self.iocsrHeaderStream.write('const unsigned long iocsr_scan_chain0_table[] = {\n') + for value in self.HPSIOCSRData1: + hv = '0x%08X' % (value) + self.iocsrHeaderStream.write('\t' + hv + ',\n') + self.iocsrHeaderStream.write('};\n') + self.iocsrHeaderStream.write('\n') + + self.iocsrHeaderStream.write('const unsigned long iocsr_scan_chain1_table[] = {\n') + for value in self.HPSIOCSRData2: + hv = '0x%08X' % (value) + self.iocsrHeaderStream.write('\t' + hv + ',\n') + self.iocsrHeaderStream.write('};\n') + self.iocsrHeaderStream.write('\n') + + self.iocsrHeaderStream.write('const unsigned long iocsr_scan_chain2_table[] = {\n') + for value in self.HPSIOCSRData3: + hv = '0x%08X' % (value) + self.iocsrHeaderStream.write('\t' + hv + ',\n') + self.iocsrHeaderStream.write('};\n') + self.iocsrHeaderStream.write('\n') + + self.iocsrHeaderStream.write('const unsigned long iocsr_scan_chain3_table[] = {\n') + for value in self.HPSIOCSRData4: + hv = '0x%08X' % (value) + self.iocsrHeaderStream.write('\t' + hv + ',\n') + self.iocsrHeaderStream.write('};\n') + self.iocsrHeaderStream.write('\n\n') + + ret = self.iocsrHeaderStream.writeSentinelEnd(IOCSRGrokker.IOCSR_SENTINEL) + if ret == -1: + print("Empty header written. Exiting.") + + self.iocsrHeaderStream.close() diff --git a/tools/cv_bsp_generator/model.py b/tools/cv_bsp_generator/model.py new file mode 100755 index 00000000000..c30d6246cc4 --- /dev/null +++ b/tools/cv_bsp_generator/model.py @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +""" +Data models for XML files required for generating a preloader. + +These classes encapsulate the complexities of XML DOM in order to +make retrieving data from XML files easier and more reliable. +By shielding data model deserialization from data consumers, +it'd be easier to switch to other formats such as JSON if required. + +There are some assumptions about how these XML files are structured +such as the hierarchy of elements and ordering of attributes, these +are relatively safe assumptions for as long as the XML files are +always generated by HPS megawizard (isw.tcl) and are not hand-edited. + +Copyright (C) 2022 Intel Corporation + +Author: Lee, Kah Jing +""" +import xml.dom.minidom + +def getSingletonElementByTagName(parent, tagName): + """ + Find tag by name and ensure that there is exactly one match + """ + nodes = parent.getElementsByTagName(tagName) + + if len(nodes) == 0: + raise Exception("Can't find element: " + tagName) + elif len(nodes) > 1: + raise Exception("Unexpected multiple matches for singleton element: " + tagName) + else: + return nodes[0] + +class hps(object): + """ + Data model for hps.xml + """ + @staticmethod + def create(file): + """ hps model """ + return hps(file) + + def __init__(self, file): + """ hps model initialization """ + self.dom = xml.dom.minidom.parse(file) + + try: + # Look for node + self.hpsNode = getSingletonElementByTagName(self.dom, "hps") + # Look for node + self.hpsSystemNode = getSingletonElementByTagName(self.hpsNode, "system") + except Exception: + raise Exception("Can't initialize from file: " + file) + + def getSystemConfig(self, param): + """ parse system configuration tag """ + hpsSystemConfigNode = None + + # Look for nodes + for node in self.hpsSystemNode.getElementsByTagName("config"): + # assume name is the first attribute as in + nameAttrNode = node.attributes.item(0) + if nameAttrNode.nodeName == "name" and nameAttrNode.nodeValue == param: + # assume value is the second attribute as in + valueAttrNode = node.attributes.item(1) + if valueAttrNode.nodeName == "value": + hpsSystemConfigNode = valueAttrNode + break + + if hpsSystemConfigNode == None: + raise ValueError("Can't find node: " + param) + + return hpsSystemConfigNode.nodeValue + +class emif(object): + """ + Data model for emif.xml. + """ + @staticmethod + def create(file): + """ emif model """ + return emif(file) + + def __init__(self, file): + """ emif model initialization """ + self.dom = xml.dom.minidom.parse(file) + + try: + # Look for node + self.emifNode = getSingletonElementByTagName(self.dom, "emif") + # Look for node + self.emifPllNode = getSingletonElementByTagName(self.emifNode, "pll") + except Exception: + raise Exception("Can't initialize from file: " + file) + + def getPllDefine(self, param): + """ parse pll define tag """ + emifPllDefineNode = None + + # Look for nodes + for node in self.emifPllNode.getElementsByTagName("define"): + nameAttrNode = node.attributes.item(0) + # assume name is the first attribute as in + if nameAttrNode.nodeName == "name" and nameAttrNode.nodeValue == param: + # assume value is the second attribute as in + valueAttrNode = node.attributes.item(1) + if valueAttrNode.nodeName == "value": + emifPllDefineNode = valueAttrNode + break + + if emifPllDefineNode == None: + raise Exception("Can't find EMIF PLL define node: " + param) + + return emifPllDefineNode.nodeValue diff --git a/tools/cv_bsp_generator/renderer.py b/tools/cv_bsp_generator/renderer.py new file mode 100755 index 00000000000..0ab1e2f2df2 --- /dev/null +++ b/tools/cv_bsp_generator/renderer.py @@ -0,0 +1,196 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +""" +Document renderer class for preloader source files + +Each document renderer takes care of a full construction of +a specific file format using the required data model. + +Copyright (C) 2022 Intel Corporation + +Author: Lee, Kah Jing +""" +import collections +import doc + +class pll_config_h: + """ + pll_config.h renderer. + """ + + def __init__(self, hpsModel, emifModel): + """ renderer initialization """ + self.hpsModel = hpsModel + self.emifModel = emifModel + self.doc = doc.generated_c_source("__SOCFPGA_PLL_CONFIG_H__") + + def createContent(self): + """ add the content based on settings parsed. eventually it will be + written to pll_config.h file + """ + doc.c_source.line(self.doc) + id = "CFG_HPS_DBCTRL_STAYOSC1" + valueString = self.hpsModel.getSystemConfig("dbctrl_stayosc1") + # Unfortunately hps.xml never tells us the data type of values + # attributes. Here we workaround this type of problem, often + # this is case-by-case, i.e. having to know which parameter that + # we're dealing with, hence this ugly parameter-specific + # if-statement needs here to workaround the data type inconsistency + if valueString.lower() == "true": + value = "1" + else: + value = "0" + doc.c_source.define(self.doc, id, value ) + doc.c_source.line(self.doc) + self.addMainPllSettings() + doc.c_source.line(self.doc) + self.addPeriphPllSettings() + doc.c_source.line(self.doc) + self.addSdramPllSettings() + doc.c_source.line(self.doc) + self.addClockFreq() + doc.c_source.line(self.doc) + self.addAlteraSettings() + doc.c_source.line(self.doc) + + def addMainPllSettings(self): + """ add pll settings to the file """ + paramMap = collections.OrderedDict() + paramMap["VCO_DENOM"] = "main_pll_n" + paramMap["VCO_NUMER"] = "main_pll_m" + + for key in paramMap.keys(): + id = "CFG_HPS_MAINPLLGRP_" + key + value = self.hpsModel.getSystemConfig(paramMap[key]) + doc.c_source.define(self.doc, id, value ) + + # main_pll_c0, main_pll_c1, main_pll_c2 are fixed counters, + doc.c_source.define(self.doc, "CFG_HPS_MAINPLLGRP_MPUCLK_CNT", "0") + doc.c_source.define(self.doc, "CFG_HPS_MAINPLLGRP_MAINCLK_CNT", "0") + doc.c_source.define(self.doc, "CFG_HPS_MAINPLLGRP_DBGATCLK_CNT", "0") + + paramMap = collections.OrderedDict() + + paramMap["MAINQSPICLK_CNT"] = "main_pll_c3" + paramMap["MAINNANDSDMMCCLK_CNT"] = "main_pll_c4" + paramMap["CFGS2FUSER0CLK_CNT"] = "main_pll_c5" + paramMap["MAINDIV_L3MPCLK"] = "l3_mp_clk_div" + paramMap["MAINDIV_L3SPCLK"] = "l3_sp_clk_div" + paramMap["MAINDIV_L4MPCLK"] = "l4_mp_clk_div" + paramMap["MAINDIV_L4SPCLK"] = "l4_sp_clk_div" + paramMap["DBGDIV_DBGATCLK"] = "dbg_at_clk_div" + paramMap["DBGDIV_DBGCLK"] = "dbg_clk_div" + paramMap["TRACEDIV_TRACECLK"] = "dbg_trace_clk_div" + paramMap["L4SRC_L4MP"] = "l4_mp_clk_source" + paramMap["L4SRC_L4SP"] = "l4_sp_clk_source" + + for key in paramMap.keys(): + id = "CFG_HPS_MAINPLLGRP_" + key + value = self.hpsModel.getSystemConfig(paramMap[key]) + doc.c_source.define(self.doc, id, value ) + + def addPeriphPllSettings(self): + """ add peripheral pll settings to the file """ + paramMap = collections.OrderedDict() + paramMap["VCO_DENOM"] = "periph_pll_n" + paramMap["VCO_NUMER"] = "periph_pll_m" + paramMap["VCO_PSRC"] = "periph_pll_source" + paramMap["EMAC0CLK_CNT"] = "periph_pll_c0" + paramMap["EMAC1CLK_CNT"] = "periph_pll_c1" + paramMap["PERQSPICLK_CNT"] = "periph_pll_c2" + paramMap["PERNANDSDMMCCLK_CNT"] = "periph_pll_c3" + paramMap["PERBASECLK_CNT"] = "periph_pll_c4" + paramMap["S2FUSER1CLK_CNT"] = "periph_pll_c5" + paramMap["DIV_USBCLK"] = "usb_mp_clk_div" + paramMap["DIV_SPIMCLK"] = "spi_m_clk_div" + paramMap["DIV_CAN0CLK"] = "can0_clk_div" + paramMap["DIV_CAN1CLK"] = "can1_clk_div" + paramMap["GPIODIV_GPIODBCLK"] = "gpio_db_clk_div" + paramMap["SRC_SDMMC"] = "sdmmc_clk_source" + paramMap["SRC_NAND"] = "nand_clk_source" + paramMap["SRC_QSPI"] = "qspi_clk_source" + + for key in paramMap.keys(): + id = "CFG_HPS_PERPLLGRP_" + key + value = self.hpsModel.getSystemConfig(paramMap[key]) + doc.c_source.define(self.doc, id, value ) + + def addSdramPllSettings(self): + """ add sdram pll settings to the file """ + value = self.emifModel.getPllDefine("PLL_MEM_CLK_DIV") + doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_VCO_DENOM", value ) + value = self.emifModel.getPllDefine("PLL_MEM_CLK_MULT") + doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_VCO_NUMER", value ) + doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_VCO_SSRC", "0") + doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDRDQSCLK_CNT", "1") + value = self.emifModel.getPllDefine("PLL_MEM_CLK_PHASE_DEG") + doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDRDQSCLK_PHASE", value ) + doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDR2XDQSCLK_CNT", "0") + doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDR2XDQSCLK_PHASE", "0") + doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDRDQCLK_CNT", "1") + value = self.emifModel.getPllDefine("PLL_WRITE_CLK_PHASE_DEG") + doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDRDQCLK_PHASE", value ) + + try: + value = self.hpsModel.getSystemConfig("sdram_pll_c5") + except ValueError: + value = "5" + doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_S2FUSER2CLK_CNT", value ) + doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_S2FUSER2CLK_PHASE", "0") + + def addClockFreq(self): + """ add clock frequency settings to the file """ + paramMap = collections.OrderedDict() + paramMap["OSC1"] = "eosc1_clk_hz" + paramMap["OSC2"] = "eosc2_clk_hz" + paramMap["F2S_SDR_REF"] = "F2SCLK_SDRAMCLK_FREQ" + paramMap["F2S_PER_REF"] = "F2SCLK_PERIPHCLK_FREQ" + paramMap["MAINVCO"] = "main_pll_vco_hz" + paramMap["PERVCO"] = "periph_pll_vco_hz" + + for key in paramMap.keys(): + id = "CFG_HPS_CLK_" + key + "_HZ" + value = self.hpsModel.getSystemConfig(paramMap[key]) + doc.c_source.define(self.doc, id, value ) + + eosc1 = int(self.hpsModel.getSystemConfig("eosc1_clk_hz")) + eosc2 = int(self.hpsModel.getSystemConfig("eosc2_clk_hz")) + m = int(self.emifModel.getPllDefine("PLL_MEM_CLK_MULT")) + n = int(self.emifModel.getPllDefine("PLL_MEM_CLK_DIV")) + vco = int(round(eosc1 * (m + 1) / (n + 1))) + doc.c_source.define(self.doc, "CFG_HPS_CLK_SDRVCO_HZ", str(vco) ) + + paramMap = collections.OrderedDict() + paramMap["EMAC0"] = "emac0_clk_hz" + paramMap["EMAC1"] = "emac1_clk_hz" + paramMap["USBCLK"] = "usb_mp_clk_hz" + paramMap["NAND"] = "nand_clk_hz" + paramMap["SDMMC"] = "sdmmc_clk_hz" + paramMap["QSPI"] = "qspi_clk_hz" + paramMap["SPIM"] = "spi_m_clk_hz" + paramMap["CAN0"] = "can0_clk_hz" + paramMap["CAN1"] = "can1_clk_hz" + paramMap["GPIODB"] = "gpio_db_clk_hz" + paramMap["L4_MP"] = "l4_mp_clk_hz" + paramMap["L4_SP"] = "l4_sp_clk_hz" + + for key in paramMap.keys(): + id = "CFG_HPS_CLK_" + key + "_HZ" + value = self.hpsModel.getSystemConfig(paramMap[key]) + doc.c_source.define(self.doc, id, value ) + + def addAlteraSettings(self): + """ add Altera-related settings to the file """ + paramMap = collections.OrderedDict() + paramMap["MPUCLK"] = "main_pll_c0_internal" + paramMap["MAINCLK"] = "main_pll_c1_internal" + paramMap["DBGATCLK"] = "main_pll_c2_internal" + + for key in paramMap.keys(): + id = "CFG_HPS_ALTERAGRP_" + key + value = self.hpsModel.getSystemConfig(paramMap[key]) + doc.c_source.define(self.doc, id, value ) + + def __str__(self): + """ convert to string """ + self.createContent() + return str(self.doc) diff --git a/tools/cv_bsp_generator/requirements.txt b/tools/cv_bsp_generator/requirements.txt new file mode 100644 index 00000000000..2ad65d1c331 --- /dev/null +++ b/tools/cv_bsp_generator/requirements.txt @@ -0,0 +1,5 @@ +# requirements.txt for cv_bsp_generator.py +# All dependencies are either standard library modules +# or local Python files included in this BSP tool. +# No external pip packages are required. + diff --git a/tools/cv_bsp_generator/streamer.py b/tools/cv_bsp_generator/streamer.py new file mode 100755 index 00000000000..19c30aced6a --- /dev/null +++ b/tools/cv_bsp_generator/streamer.py @@ -0,0 +1,102 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +""" +Generate license, file header and close tag. + +Copyright (C) 2022 Intel Corporation + +Author: Lee, Kah Jing +""" +import os +import struct +import doc + +class Streamer(object): + """ Streamer class to generate license, header, and close tag. + """ + def __init__(self, fileName, mode='r'): + """ Streamer initialization """ + self.fileName = fileName + self.mode = mode + self.file = None + self.sentinel = None + if '+' in mode or 'w' in mode or 'a' in mode: + self.fileMode = 'write' + else: + self.fileMode = 'read' + + def close(self): + """ file close """ + if self.file != None: + self.file.close() + self.file = None + + def open(self): + """ file open """ + if self.fileName != None: + if self.file == None: + if self.fileMode == 'write': + print ("Generating file: %s..." % self.fileName) + else: + print ("Reading file: %s..." % self.fileName) + self.file = open(self.fileName, self.mode) + + def read(self, numBytes): + """ file read number of bytes """ + if self.file == None: + print ("***Error: Attempted to read from unopened file %s" \ + % (self.fileName)) + exit(-1) + + else: + return self.file.read(numBytes) + + def readUnsignedInt(self): + """ read unsigned integer """ + return struct.unpack('I', self.read(4))[0] + + def readUnsignedShort(self): + """ read unsigned short """ + return struct.unpack('H', self.read(2))[0] + + def readBytesAsString(self, numBytes): + """ Read some bytes from a binary file + and interpret the data values as a String + """ + bytes = self.read(numBytes) + s = bytes.decode('utf-8') + + return s + + def write(self, str): + """ file write """ + if self.file == None: + print ("***Error: Attempted to write to unopened file %s" \ + % (self.fileName)) + exit(-1) + + else: + self.file.write("%s" % str) + + def writeLicenseHeader(self): + """ write license & copyright """ + # format the license header + licenseHeader = "/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */\n" + self.file.write("%s" % licenseHeader) + copyrightHeader = "/*\n * Copyright (C) 2022 Intel Corporation \n *\n */\n" + self.file.write("%s" % copyrightHeader) + + def writeSentinelStart(self, sentinel): + """ start header """ + if sentinel == None: + return -1 + self.sentinel = sentinel + self.file.write("%s\n%s\n\n" % (\ + "#ifndef " + self.sentinel, + "#define " + self.sentinel)) + + def writeSentinelEnd(self, sentinel): + """ end header """ + if sentinel == None: + return -1 + self.sentinel = sentinel + self.file.write("\n%s\n" % ("#endif /* " + self.sentinel + " */")) diff --git a/tools/cv_bsp_generator/xmlgrok.py b/tools/cv_bsp_generator/xmlgrok.py new file mode 100755 index 00000000000..fae1d745bfd --- /dev/null +++ b/tools/cv_bsp_generator/xmlgrok.py @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +""" +XML node parser + +Copyright (C) 2022 Intel Corporation + +Author: Lee, Kah Jing +""" +import xml.dom + +def isElementNode(XMLNode): + """ check if the node is element node """ + return XMLNode.nodeType == xml.dom.Node.ELEMENT_NODE + +def firstElementChild(XMLNode): + """ Calling firstChild on an Node of type Element often (always?) + returns a Node of Text type. How annoying! Return the first Element + child + """ + child = XMLNode.firstChild + while child != None and not isElementNode(child): + child = nextElementSibling(child) + return child + +def nextElementSibling(XMLNode): + """ nextElementSibling will return the next sibling of XMLNode that is + an Element Node Type + """ + sib = XMLNode.nextSibling + while sib != None and not isElementNode(sib): + sib = sib.nextSibling + return sib -- cgit v1.3.1 From 6beb48a3952b59e7b8b613ecf29e75d87d796f60 Mon Sep 17 00:00:00 2001 From: Dinesh Maniyam Date: Wed, 5 Nov 2025 01:16:17 +0800 Subject: nand: denali: enable ONFI detection for SoCFPGA SoC64 Enable ONFI parameter page detection for SoCFPGA SoC64 devices by selecting SYS_NAND_ONFI_DETECTION in the NAND_DENALI Kconfig entry. This allows SoCFPGA SoC64 platforms using the Denali NAND controller to automatically detect NAND parameters via the ONFI interface instead of relying on hardcoded configuration values. The selection is limited to TARGET_SOCFPGA_SOC64 to avoid affecting non-SoC64 platforms that use legacy NAND handling. Signed-off-by: Dinesh Maniyam Reviewed-by: Tien Fong Chee --- drivers/mtd/nand/raw/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index c76c10e1ef9..a93b00cdb7e 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -212,6 +212,7 @@ config NAND_CADENCE config NAND_DENALI bool select SYS_NAND_SELF_INIT + select SYS_NAND_ONFI_DETECTION if TARGET_SOCFPGA_SOC64 imply CMD_NAND config NAND_DENALI_DT -- cgit v1.3.1 From e291277689f62e2e9170d8e130d876de6161b363 Mon Sep 17 00:00:00 2001 From: Brian Sune Date: Mon, 10 Nov 2025 13:00:40 +0800 Subject: sync socfpga common u-boot dts The dtsi for socfpga common should turn on L2 and memory and no reason not to do so Signed-off-by: Brian Sune Reviewed-by: Tien Fong Chee --- arch/arm/dts/socfpga-common-u-boot.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/dts/socfpga-common-u-boot.dtsi b/arch/arm/dts/socfpga-common-u-boot.dtsi index eb3d1039314..695242bec21 100644 --- a/arch/arm/dts/socfpga-common-u-boot.dtsi +++ b/arch/arm/dts/socfpga-common-u-boot.dtsi @@ -5,6 +5,10 @@ * Copyright (c) 2019 Simon Goldschmidt */ /{ + memory { + bootph-all; + }; + soc { bootph-all; }; @@ -14,6 +18,10 @@ bootph-all; }; +&L2 { + bootph-all; +}; + &rst { bootph-all; }; -- cgit v1.3.1 From 5b1fe6ef6b812c87a7f634cdfac81324ae9e09f7 Mon Sep 17 00:00:00 2001 From: Brian Sune Date: Sat, 15 Nov 2025 00:04:23 +0800 Subject: Altera SoCFpga Boot Stall Fix Since U-Boot 2025.07 pure SD Card boot no longer works. Now Altera released 2025.07 shows the different on the u-boot files. After testing, the major root case is get_managers_addr. And this patch fix the SD boot stall via pulling from offical. Signed-off-by: Brian Sune Reviewed-by: Tien Fong Chee --- arch/arm/mach-socfpga/misc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c index 76747c2196a..07694107c8a 100644 --- a/arch/arm/mach-socfpga/misc.c +++ b/arch/arm/mach-socfpga/misc.c @@ -222,7 +222,7 @@ static int do_bridge(struct cmd_tbl *cmdtp, int flag, int argc, } U_BOOT_CMD(bridge, 3, 1, do_bridge, - "SoCFPGA HPS FPGA bridge control", + "GEN5 SoCFPGA HPS FPGA bridge control", "enable [mask] - Enable HPS-to-FPGA (Bit 0), LWHPS-to-FPGA (Bit 1), FPGA-to-HPS (Bit 2) bridges\n" "bridge disable [mask] - Disable HPS-to-FPGA (Bit 0), LWHPS-to-FPGA (Bit 1), FPGA-to-HPS (Bit 2) bridges\n" "" @@ -261,7 +261,16 @@ void socfpga_get_managers_addr(void) if (ret) hang(); - else if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X)) + if (!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) && + !IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M) && + !IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)) { + ret = socfpga_get_base_addr("altr,sys-mgr", + &socfpga_sysmgr_base); + if (ret) + hang(); + } + + if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X)) ret = socfpga_get_base_addr("intel,n5x-clkmgr", &socfpga_clkmgr_base); else if (!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) && -- cgit v1.3.1 From 0af9efa7c1873b2d52eaa82d67a8c67351a7f8ca Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 19 Nov 2025 08:55:38 -0600 Subject: socfpga_vining_fpga: Stop disabling device tree relocation Remove setting of fdt_high to ~0, which disables device tree relocation, from the default environment. Doing so prevents U-Boot from correcting problems such as having an unaligned device tree and leads to various failure modes in the OS. Signed-off-by: Tom Rini Reviewed-by: Marek Vasut --- include/configs/socfpga_vining_fpga.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/configs/socfpga_vining_fpga.h b/include/configs/socfpga_vining_fpga.h index 4bb15cf4629..ad13f1345b0 100644 --- a/include/configs/socfpga_vining_fpga.h +++ b/include/configs/socfpga_vining_fpga.h @@ -40,7 +40,6 @@ "hostname=vining_fpga\0" \ "kernel_addr_r=0x10000000\0" \ "fdt_addr_r=0x20000000\0" \ - "fdt_high=0xffffffff\0" \ "initrd_high=0xffffffff\0" \ "dfu_alt_info=qspi0 sf 0:0;qspi1 sf 0:1\0" \ "mtdparts_0_16m=ff705000.spi.0:" /* 16MiB+128MiB SF config */ \ -- cgit v1.3.1 From da09bb6a6c1f40dd5fec18ee5c946ebf5722b7ad Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Wed, 19 Nov 2025 18:19:55 +0100 Subject: board: softing: vining: migrate to modern LED framework This migrates from the legacy LED API to use the modern LED framework which makes use of the FDT. Signed-off-by: Quentin Schulz Acked-by: Tien Fong Chee --- .../dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi | 26 ++++++++++++++++++++++ board/softing/vining_fpga/socfpga.c | 12 +++++++--- configs/socfpga_vining_fpga_defconfig | 13 ++--------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi index 330949c0184..bf5e12ec90c 100644 --- a/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi +++ b/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi @@ -13,6 +13,32 @@ spi0 = "/soc/spi@ff705000"; udc0 = &usb1; }; + + leds { + compatible = "gpio-leds"; + + led-0 { + default-state = "off"; + gpios = <&portb 20 GPIO_ACTIVE_HIGH>; + }; + + led-1 { + default-state = "off"; + gpios = <&portb 25 GPIO_ACTIVE_HIGH>; + label = "status_1"; + }; + + led-2 { + default-state = "off"; + gpios = <&portb 26 GPIO_ACTIVE_HIGH>; + label = "status_2"; + }; + + led-3 { + default-state = "off"; + gpios = <&portc 7 GPIO_ACTIVE_HIGH>; + }; + }; }; &mmc { diff --git a/board/softing/vining_fpga/socfpga.c b/board/softing/vining_fpga/socfpga.c index ec2c7ea3631..475c19f2781 100644 --- a/board/softing/vining_fpga/socfpga.c +++ b/board/softing/vining_fpga/socfpga.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include @@ -24,10 +24,16 @@ DECLARE_GLOBAL_DATA_PTR; int board_late_init(void) { const unsigned int usb_nrst_gpio = 35; + struct udevice *dev; int ret; - status_led_set(1, CONFIG_LED_STATUS_ON); - status_led_set(2, CONFIG_LED_STATUS_ON); + ret = led_get_by_label("status_1", &dev); + if (!ret) + led_set_state(dev, LEDST_ON); + + ret = led_get_by_label("status_2", &dev); + if (!ret) + led_set_state(dev, LEDST_ON); /* Address of boot parameters for ATAG (if ATAG is used) */ gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100; diff --git a/configs/socfpga_vining_fpga_defconfig b/configs/socfpga_vining_fpga_defconfig index f3b6cb717b3..396b7a9715d 100644 --- a/configs/socfpga_vining_fpga_defconfig +++ b/configs/socfpga_vining_fpga_defconfig @@ -78,17 +78,8 @@ CONFIG_SYS_DFU_DATA_BUF_SIZE=0x1000000 CONFIG_DWAPB_GPIO=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_DW=y -CONFIG_LED_STATUS=y -CONFIG_LED_STATUS_GPIO=y -CONFIG_LED_STATUS0=y -CONFIG_LED_STATUS_BIT=48 -CONFIG_LED_STATUS1=y -CONFIG_LED_STATUS_BIT1=53 -CONFIG_LED_STATUS2=y -CONFIG_LED_STATUS_BIT2=54 -CONFIG_LED_STATUS3=y -CONFIG_LED_STATUS_BIT3=65 -CONFIG_LED_STATUS_CMD=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_MISC=y CONFIG_I2C_EEPROM=y CONFIG_SYS_I2C_EEPROM_ADDR=0x50 -- cgit v1.3.1 From 83d157e0362260974b3ed0da14a7c011fdb3768a Mon Sep 17 00:00:00 2001 From: Alif Zakuan Yuslaimi Date: Tue, 25 Nov 2025 00:13:09 -0800 Subject: configs: cyclone5: Disable mkeficapsule tool build mkeficapsule tool will be built by default if EFI_LOADER is set due to commit b7a625b1ce49 ("tools: Build mkeficapsule tool by default if EFI_LOADER is set"). This will cause compilation error on all our SoCFPGA devices, hence we will be disabling this config as we do not utilize this tool. Signed-off-by: Alif Zakuan Yuslaimi Reviewed-by: Tien Fong Chee --- configs/socfpga_cyclone5_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/socfpga_cyclone5_defconfig b/configs/socfpga_cyclone5_defconfig index fef4cb90516..4a6f9b336cb 100644 --- a/configs/socfpga_cyclone5_defconfig +++ b/configs/socfpga_cyclone5_defconfig @@ -79,3 +79,4 @@ CONFIG_USB_GADGET_DWC2_OTG=y CONFIG_USB_GADGET_DOWNLOAD=y # CONFIG_SPL_WDT is not set CONFIG_SYS_TIMER_COUNTS_DOWN=y +# CONFIG_TOOLS_MKEFICAPSULE is not set -- cgit v1.3.1 From a2bd59f7c38b1b7729b022f608f7527e1f69ae89 Mon Sep 17 00:00:00 2001 From: Alif Zakuan Yuslaimi Date: Tue, 25 Nov 2025 00:13:12 -0800 Subject: mmc: socfpga_dw_mmc: Restore legacy clkmgr address retrieval Restore legacy implementation of retrieving clkmgr base address from mach-socfpga/misc.c driver for our legacy devices. Excluding Agilex7/7M from this implementation as these devices' clock driver is already following clock driver model and is supporting enable/disable APIs. The legacy devices' clock driver will have to be refactored to support driver model which enables us to support enable/disable APIs for these devices. Fixes: ab27182cac8f ("mmc: socfpga_dw_mmc: Enable/disable SDMMC clock via API") Signed-off-by: Alif Zakuan Yuslaimi Reviewed-by: Tien Fong Chee --- drivers/mmc/socfpga_dw_mmc.c | 46 +++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c index db4e0129c2e..6219284df3e 100644 --- a/drivers/mmc/socfpga_dw_mmc.c +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -58,17 +58,24 @@ static int socfpga_dwmci_clksel(struct dwmci_host *host) u32 sdmmc_mask = ((priv->smplsel & 0x7) << SYSMGR_SDMMC_SMPLSEL_SHIFT) | ((priv->drvsel & 0x7) << SYSMGR_SDMMC_DRVSEL_SHIFT); - ret = clk_get_by_name(priv->dev, "ciu", &priv->mmc_clk_ciu); - if (ret) { - debug("%s: Failed to get SDMMC clock from dts\n", __func__); - return ret; - } - - /* Disable SDMMC clock. */ - ret = clk_disable(&priv->mmc_clk_ciu); - if (ret) { - printf("%s: Failed to disable SDMMC clock\n", __func__); - return ret; + if (!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) && + !IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M)) { + /* Disable SDMMC clock. */ + clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN, + CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); + } else { + ret = clk_get_by_name(priv->dev, "ciu", &priv->mmc_clk_ciu); + if (ret) { + debug("%s: Failed to get SDMMC clock from dts\n", __func__); + return ret; + } + + /* Disable SDMMC clock. */ + ret = clk_disable(&priv->mmc_clk_ciu); + if (ret) { + printf("%s: Failed to disable SDMMC clock\n", __func__); + return ret; + } } debug("%s: drvsel %d smplsel %d\n", __func__, @@ -88,11 +95,18 @@ static int socfpga_dwmci_clksel(struct dwmci_host *host) readl(socfpga_get_sysmgr_addr() + SYSMGR_SDMMC)); #endif - /* Enable SDMMC clock */ - ret = clk_enable(&priv->mmc_clk_ciu); - if (ret) { - printf("%s: Failed to enable SDMMC clock\n", __func__); - return ret; + if (!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) && + !IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M)) { + /* Enable SDMMC clock */ + setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN, + CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); + } else { + /* Enable SDMMC clock */ + ret = clk_enable(&priv->mmc_clk_ciu); + if (ret) { + printf("%s: Failed to enable SDMMC clock\n", __func__); + return ret; + } } return 0; -- cgit v1.3.1 From f85293aac7234c9161201852b2b6312f6da4552b Mon Sep 17 00:00:00 2001 From: Alif Zakuan Yuslaimi Date: Tue, 25 Nov 2025 00:13:13 -0800 Subject: spl: Remove ARCH_SOCFPGA from MMC raw mode enablement We no longer use raw mode to boot from MMC for our devices in favor of FAT filesystem. Maintaining this config for legacy gen5 devices as to not risk breaking any configurations still utilizing raw mode. Signed-off-by: Alif Zakuan Yuslaimi Reviewed-by: Tien Fong Chee --- common/spl/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 8dade2b501e..3b7b6cafef8 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -545,7 +545,7 @@ config SPL_SYS_MMCSD_RAW_MODE depends on SPL_DM_MMC || SPL_MMC default y if ARCH_SUNXI || ARCH_DAVINCI || ARCH_UNIPHIER || \ ARCH_MX6 || ARCH_MX7 || \ - ARCH_ROCKCHIP || ARCH_MVEBU || ARCH_SOCFPGA || \ + ARCH_ROCKCHIP || ARCH_MVEBU || TARGET_SOCFPGA_GEN5 || \ ARCH_AT91 || ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \ OMAP54XX || AM33XX || AM43XX || \ TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED @@ -589,7 +589,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR default 0x8a if ARCH_MX6 || ARCH_MX7 default 0x100 if ARCH_UNIPHIER default 0x0 if ARCH_MVEBU - default 0x200 if ARCH_SOCFPGA || ARCH_AT91 + default 0x200 if TARGET_SOCFPGA_GEN5 || ARCH_AT91 default 0x300 if ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \ OMAP54XX || AM33XX || AM43XX || ARCH_K3 default 0x4000 if ARCH_ROCKCHIP -- cgit v1.3.1 From 5790f5ef335629ca7487b79c77774e8e7ff4d4af Mon Sep 17 00:00:00 2001 From: Alif Zakuan Yuslaimi Date: Tue, 25 Nov 2025 00:13:14 -0800 Subject: configs: cyclone5: Enable SPL FAT support Enable support for FAT filesystem with SPL for CycloneV instead of raw mode. Recent changes breaks CycloneV MMC boot from raw mode, and so we are taking this opportunity to migrate MMC boot mode to FAT as smaller OCRAM size is required, as well as aligning MMC boot flow with our other devices. Fixes: 2a00d73d081a1 ("spl: mmc: Try to clean up raw-mode options") Signed-off-by: Alif Zakuan Yuslaimi Reviewed-by: Tien Fong Chee --- configs/socfpga_cyclone5_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/socfpga_cyclone5_defconfig b/configs/socfpga_cyclone5_defconfig index 4a6f9b336cb..1d3d2078636 100644 --- a/configs/socfpga_cyclone5_defconfig +++ b/configs/socfpga_cyclone5_defconfig @@ -12,6 +12,7 @@ CONFIG_DM_RESET=y CONFIG_SPL_STACK=0x0 CONFIG_SPL_TEXT_BASE=0xFFFF0000 CONFIG_TARGET_SOCFPGA_CYCLONE5_SOCDK=y +CONFIG_SPL_FS_FAT=y CONFIG_TIMESTAMP=y CONFIG_FIT=y CONFIG_DISTRO_DEFAULTS=y @@ -27,6 +28,7 @@ CONFIG_SPL_PAD_TO=0x10000 CONFIG_SPL_NO_BSS_LIMIT=y # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_HAVE_INIT_STACK=y +# CONFIG_SPL_SYS_MMCSD_RAW_MODE is not set CONFIG_SPL_SPI_LOAD=y CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000 CONFIG_SYS_MAXARGS=32 -- cgit v1.3.1 From cd74c05619f946b7a96327ffa14d0fc7090a043e Mon Sep 17 00:00:00 2001 From: Alif Zakuan Yuslaimi Date: Tue, 25 Nov 2025 00:13:15 -0800 Subject: configs: cyclone5: Update boot command for CycloneV Update CycloneV boot command to sync with Altera official release Signed-off-by: Alif Zakuan Yuslaimi Reviewed-by: Tien Fong Chee --- configs/socfpga_cyclone5_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/socfpga_cyclone5_defconfig b/configs/socfpga_cyclone5_defconfig index 1d3d2078636..7d01cecd5d2 100644 --- a/configs/socfpga_cyclone5_defconfig +++ b/configs/socfpga_cyclone5_defconfig @@ -16,7 +16,7 @@ CONFIG_SPL_FS_FAT=y CONFIG_TIMESTAMP=y CONFIG_FIT=y CONFIG_DISTRO_DEFAULTS=y -# CONFIG_USE_BOOTCOMMAND is not set +CONFIG_BOOTCOMMAND="run fatscript;bridge enable; run distro_bootcmd" CONFIG_DEFAULT_FDT_FILE="socfpga_cyclone5_socdk.dtb" CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y -- cgit v1.3.1 From 05f72f28e9a96a37650582b38d6158aa65ca9ec2 Mon Sep 17 00:00:00 2001 From: Alif Zakuan Yuslaimi Date: Tue, 25 Nov 2025 00:13:16 -0800 Subject: configs: cyclone5: Disable SPI in SPL Disable support for using SPI in SPL to solve Cyclone V storage issue as the OCRAM is only 64kb. The SPI configurations are only required during uboot proper only. Signed-off-by: Alif Zakuan Yuslaimi Reviewed-by: Tien Fong Chee --- configs/socfpga_cyclone5_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/socfpga_cyclone5_defconfig b/configs/socfpga_cyclone5_defconfig index 7d01cecd5d2..f1bf0aec015 100644 --- a/configs/socfpga_cyclone5_defconfig +++ b/configs/socfpga_cyclone5_defconfig @@ -12,6 +12,7 @@ CONFIG_DM_RESET=y CONFIG_SPL_STACK=0x0 CONFIG_SPL_TEXT_BASE=0xFFFF0000 CONFIG_TARGET_SOCFPGA_CYCLONE5_SOCDK=y +# CONFIG_SPL_SPI is not set CONFIG_SPL_FS_FAT=y CONFIG_TIMESTAMP=y CONFIG_FIT=y -- cgit v1.3.1 From 85a7e45c3350afd9f7c17bb0bb2a47aa94be982d Mon Sep 17 00:00:00 2001 From: Thanh Quan Date: Mon, 27 Oct 2025 15:03:58 +0100 Subject: net: phy: dp83869: fix STRAP_OPMODE bitmask According to the TI DP83869HM datasheet Revision D (June 2025), section 7.6.1.41 STRAP_STS Register, the STRAP_OPMODE bitmask is bit [11:9]. Fix this. In case the PHY is auto-detected via PHY ID registers, or not described in DT, or, in case the PHY is described in DT but the optional DT property "ti,op-mode" is not present, then the driver reads out the PHY functional mode (RGMII, SGMII, ...) from hardware straps. Currently, all upstream users of this PHY specify both DT compatible string "ethernet-phy-id2000.a0f1" and ti,op-mode = property, therefore it seems no upstream users are affected by this bug. The driver currently interprets bits [2:0] of STRAP_STS register as PHY functional mode. Those bits are controlled by ANEG_DIS, ANEGSEL_0 straps and an always-zero reserved bit. Systems that use RGMII-to-Copper functional mode are unlikely to disable auto-negotiation via ANEG_DIS strap, or change auto-negotiation behavior via ANEGSEL_0 strap. Therefore, even with this bug in place, the STRAP_STS register content is likely going to be interpreted by the driver as RGMII-to-Copper mode. However, for a system with PHY functional mode strapping set to other mode than RGMII-to-Copper, the driver is likely to misinterpret the strapping as RGMII-to-Copper and misconfigure the PHY. For example, on a system with SGMII-to-Copper strapping, the STRAP_STS register reads as 0x0c20, but the PHY ends up being configured for incompatible RGMII-to-Copper mode. Fixes: f3e22eea815d ("net: phy: add TI DP83869HM ethernet driver") Signed-off-by: Thanh Quan Signed-off-by: Hai Pham Signed-off-by: Marek Vasut # Use FIELD_GET() --- drivers/net/phy/dp83869.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c index b6fb5adae1f..c60fbf26a03 100644 --- a/drivers/net/phy/dp83869.c +++ b/drivers/net/phy/dp83869.c @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -64,7 +65,7 @@ #define DP83869_RGMII_RX_CLK_DELAY_EN BIT(0) /* STRAP_STS1 bits */ -#define DP83869_STRAP_OP_MODE_MASK GENMASK(2, 0) +#define DP83869_STRAP_OP_MODE_MASK GENMASK(11, 9) #define DP83869_STRAP_STS1_RESERVED BIT(11) #define DP83869_STRAP_MIRROR_ENABLED BIT(12) @@ -168,7 +169,7 @@ static int dp83869_set_strapped_mode(struct phy_device *phydev) if (val < 0) return val; - dp83869->mode = val & DP83869_STRAP_OP_MODE_MASK; + dp83869->mode = FIELD_GET(DP83869_STRAP_OP_MODE_MASK, val); return 0; } -- cgit v1.3.1 From 7c1b99bd60185c24d2c78862c3345895ffcd1d71 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Thu, 27 Nov 2025 16:25:27 +0100 Subject: net: phy: broadcom: fix RGMII delays for BCM54210E MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bcm54210e_config() configures the RGMII delays and then calls bcm5461_config(). But the latter will do a PHY soft reset and thus resets the delay settings again. Call bcm5461_config() first to fix it. Fixes: cba79a1b2e11 ("net: phy: broadcom: add support for BCM54210E") Signed-off-by: Michael Walle Reviewed-by: Rafał Miłecki --- drivers/net/phy/broadcom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 1c02e3efedc..2d93ce0c966 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -176,11 +176,11 @@ static int bcm54210e_config(struct phy_device *phydev) { int ret; - ret = bcm54xx_config_clock_delay(phydev); + ret = bcm5461_config(phydev); if (ret < 0) return ret; - ret = bcm5461_config(phydev); + ret = bcm54xx_config_clock_delay(phydev); if (ret < 0) return ret; -- cgit v1.3.1 From 87cb318344250ac7d598284c0a1928df6bcd1f4e Mon Sep 17 00:00:00 2001 From: Brian Sune Date: Mon, 1 Dec 2025 17:04:07 +0800 Subject: Add optimized Makefile support for SoCFPGA handoff - Introduce socfpga_g5_handoff_prepare target in U-Boot arch/arm/mach-socfpga/config.mk - Users can convert the handoff via make prepare. - Detects Altera/Intel SoCFPGA boards from .config - Combines vendor/board extraction into a single shell call - Checks for hps_isw_handoff folder and .hiof files - Uses ls -d instead of find for faster folder detection - Runs BSP generator script only if files exist - Non-blocking: continues if handoff folder or files are missing - HANDOFF_PATH user define allows overriding auto-detected folder - Minimizes subshells and other slow constructs for faster CI Signed-off-by: Brian Sune --- arch/arm/mach-socfpga/config.mk | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 arch/arm/mach-socfpga/config.mk diff --git a/arch/arm/mach-socfpga/config.mk b/arch/arm/mach-socfpga/config.mk new file mode 100644 index 00000000000..2290118f747 --- /dev/null +++ b/arch/arm/mach-socfpga/config.mk @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Brian Sune + +ifeq ($(CONFIG_TARGET_SOCFPGA_CYCLONE5),y) +archprepare: socfpga_g5_handoff_prepare +else ifeq ($(CONFIG_TARGET_SOCFPGA_ARRIA5),y) +archprepare: socfpga_g5_handoff_prepare +endif + +socfpga_g5_handoff_prepare: + @SOCFAMILY="$(SOCFAMILY)"; \ + if [ -z "$$SOCFAMILY" ]; then \ + exit 0; \ + fi; \ + echo "[INFO] SOC family detected: $$SOCFAMILY"; + @set -- $$(awk -F'"' ' \ + /^CONFIG_SYS_VENDOR=/ {v=$$2} \ + /^CONFIG_SYS_BOARD=/ {b=$$2} \ + END {print v, b}' .config); \ + VENDOR=$$1; \ + BOARD=$$2; \ + if [ -z "$$VENDOR" ] || [ -z "$$BOARD" ]; then \ + exit 0; \ + fi; \ + BOARD_DIR=$(src)/board/$$VENDOR/$$BOARD; \ + if [ "$$HANDOFF_PATH" ]; then \ + echo "[INFO] Using manually specified handoff folder: $$HANDOFF_PATH"; \ + else \ + HANDOFF_BASE=$$BOARD_DIR/hps_isw_handoff; \ + if [ ! -d "$$HANDOFF_BASE" ]; then \ + exit 0; \ + fi; \ + HANDOFF_PATH=$$(ls -d "$$HANDOFF_BASE"/*/ 2>/dev/null | head -n1); \ + if [ -z "$$HANDOFF_PATH" ]; then \ + exit 0; \ + fi; \ + echo "[INFO] Auto-detected handoff folder: $$HANDOFF_PATH"; \ + fi; \ + HIOF_FILE=$$HANDOFF_PATH/$$(basename $$HANDOFF_PATH).hiof; \ + if [ ! -f "$$HIOF_FILE" ]; then \ + echo "[WARN] No .hiof file found in $$HANDOFF_PATH, skipping BSP generation."; \ + exit 0; \ + fi; \ + echo "[INFO] Found hiof file: $$HIOF_FILE"; \ + echo "[INFO] Running BSP generator..."; \ + python3 $(src)/tools/cv_bsp_generator/cv_bsp_generator.py -i "$$HANDOFF_PATH" -o "$$BOARD_DIR/qts" || echo "[WARN] BSP generator failed, continuing..."; \ + echo "[DONE] SoCFPGA QTS handoff conversion complete." -- cgit v1.3.1 From 5e9f5ea30f6d371ddf93ea472c0885e48504c968 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 26 Nov 2025 17:49:46 -0600 Subject: Azure: Rework jobs for disk space and 29 jobs The problem we face currently with Azure jobs is that we're running out of disk space on the runners as we build. There's not a good way to split approximately 1500 configurations across 10 jobs and not be close to or exceeding that limit. Split this in to 29 jobs instead with a goal of averaging an hour per job. This split gets us close, but there are still some challenging jobs to try and break up further. The list is mostly alphabetized but with some intentional changes (catch-all are last, mx/imx are together, SoC family splits are just grouped together). The average build time should be close to the same, but outliers can and will happen. Signed-off-by: Tom Rini --- .azure-pipelines.yml | 137 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 107 insertions(+), 30 deletions(-) diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 0c7c38ba730..e4695f1c55b 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -11,16 +11,35 @@ variables: container_option: -u 0 work_dir: /u # We define all of these as variables so we can easily reference them twice - am33xx_kirkwood_ls1_mvebu_omap: "am33xx kirkwood ls1 mvebu omap -x siemens,freescale" - amlogic_bcm_boundary_engicam_siemens_technexion_oradex: "amlogic bcm boundary engicam siemens technexion toradex -x mips" - arm_nxp_minus_imx_and_at91: "at91 freescale -x powerpc,m68k,imx,mx" - imx: "mx imx -x boundary,engicam,technexion,toradex" - rk: "rk" - sunxi: "sunxi" + am33xx_kirkwood: "am33xx kirkwood" + amd: "amd xilinx zynq" + amlogic_bcm: "amlogic bcm -x mips" + atmel: "atmel" + engicam_renesas: "engicam renesas" + k3_32b: "k3 -x aarch64,phytec,toradex" + k3_64b: "k3 -x armv7,phytec,toradex" + kirkwood_mvebu: "kirkwood mvebu" + layerscape_vf610: "ls1 ls2 lx2 vf610 -x phytec,toradex" + m68k_remaining_mx_xtensa: "m68k imxrt mx xtensa -x mx6,aarch64" + mips_x86: "mips x86 -x mediatek" + mx6: "mx6 -x engicam,phytec,toradex" + imx8: "imx8 -x engicam,phytec,toradex" + imx9_arc_nios2_socfpga: "imx9 arc nios2 socfpga -x phytec,toradex" + phytec_toradex: "phytec toradex" powerpc: "powerpc" - arm_catch_all: "arm -x aarch64,am33xx,at91,bcm,ls1,kirkwood,mvebu,omap,rk,siemens,mx,sunxi,technexion,toradex" - aarch64_catch_all: "aarch64 -x amlogic,bcm,engicam,imx,ls1,ls2,lx216,mvebu,rk,siemens,sunxi,toradex" - everything_but_arm_and_powerpc: "arc m68k microblaze mips nios2 riscv sandbox sh x86 xtensa -x arm,powerpc" + riscv_stm32: "riscv stm32 -x engicam,xilinx" + rk3399: "rk3399" + rk352x_rk358x: "rk352 rk358" + rk356x_rk357x: "rk356 rk357" + rk3xxx_rest: "rk30 rk31 rk32 rk33 -x rk3399,phytec" + sandbox_tegra: "tegra sandbox -x toradex" + samsung_omap_mediatek: "samsung omap mediatek" + sun4i_5i: "sun4i sun5i" + sun6i_sun7i: "sun6i sun7i" + sun8i: "sun8i" + sunxi_rest: "sunxi -x sun4i,sun5i,sun6i,sun7i,sun8i" + arm_catch_all: "arm -x aarch64,am33xx,atmel,bcm,ls,lx,imx,k3,kirkwood,mvebu,mx,omap,renesas,rk,samsung,socfpga,stm32,sunxi,tegra,vf610,xilinx,zynq" + aarch64_catch_all: "aarch64 -x amd,amlogic,bcm,engicam,imx,k3,ls,lx,mediatek,mvebu,renesas,rk,samsung,socfpga,stm32,sunxi,tegra,xilinx,zynq" stages: - stage: testsuites @@ -213,16 +232,36 @@ stages: # First get the total number of boards total=$(tools/buildman/buildman ${BMANARGS} | grep "Total boards to build for each commit" | cut -d ' ' -f 8) # Now build up the list of what each job built. - built="$(tools/buildman/buildman ${BMANARGS} $(am33xx_kirkwood_ls1_mvebu_omap) | grep '^ ')" - built="$built $(tools/buildman/buildman ${BMANARGS} $(amlogic_bcm_boundary_engicam_siemens_technexion_oradex) | grep '^ ')" - built="$built $(tools/buildman/buildman ${BMANARGS} $(arm_nxp_minus_imx_and_at91) | grep '^ ')" - built="$built $(tools/buildman/buildman ${BMANARGS} $(imx) | grep '^ ')" - built="$built $(tools/buildman/buildman ${BMANARGS} $(rk) | grep '^ ')" - built="$built $(tools/buildman/buildman ${BMANARGS} $(sunxi) | grep '^ ')" + built="$(tools/buildman/buildman ${BMANARGS} $(am33xx_kirkwood) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(amd) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(amlogic_bcm) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(atmel) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(engicam_renesas) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(k3_32b) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(k3_64b) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(kirkwood_mvebu) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(layerscape_vf610) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(m68k_remaining_mx_xtensa) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(mips_x86) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(mx6) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(imx8) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(imx9_arc_nios2_socfpga) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(phytec_toradex) | grep '^ ')" built="$built $(tools/buildman/buildman ${BMANARGS} $(powerpc) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(riscv_stm32) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(rk3399) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(rk352x_rk358x) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(rk356x_rk357x) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(rk3xxx_rest) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(sandbox_tegra) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(samsung_omap_mediatek) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(sun4i_5i) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(sun6i_sun7i) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(sun8i) | grep '^ ')" + built="$built $(tools/buildman/buildman ${BMANARGS} $(sunxi_rest) | grep '^ ')" built="$built $(tools/buildman/buildman ${BMANARGS} $(arm_catch_all) | grep '^ ')" built="$built $(tools/buildman/buildman ${BMANARGS} $(aarch64_catch_all) | grep '^ ')" - built="$built $(tools/buildman/buildman ${BMANARGS} $(everything_but_arm_and_powerpc) | grep '^ ')" + # Finally see how many machines that is. actual=$(tools/buildman/buildman ${BMANARGS} $built | grep "Total boards to build for each commit" | cut -d ' ' -f 8) echo We would build a total of $actual out of $total platforms this CI run @@ -617,26 +656,64 @@ stages: # We split the world up in to 10 jobs as we can have at most 10 # parallel jobs going on the free tier of Azure. matrix: - am33xx_kirkwood_ls1_mvebu_omap: - BUILDMAN: $(am33xx_kirkwood_ls1_mvebu_omap) - amlogic_bcm_boundary_engicam_siemens_technexion_oradex: - BUILDMAN: $(amlogic_bcm_boundary_engicam_siemens_technexion_oradex) - arm_nxp_minus_imx_and_at91: - BUILDMAN: $(arm_nxp_minus_imx_and_at91) - imx: - BUILDMAN: $(imx) - rk: - BUILDMAN: $(rk) - sunxi: - BUILDMAN: $(sunxi) + am33xx_kirkwood: + BUILDMAN: $(am33xx_kirkwood) + amd: + BUILDMAN: $(amd) + amlogic_bcm: + BUILDMAN: $(amlogic_bcm) + atmel: + BUILDMAN: $(atmel) + engicam_renesas: + BUILDMAN: $(engicam_renesas) + k3_32b: + BUILDMAN: $(k3_32b) + k3_64b: + BUILDMAN: $(k3_64b) + kirkwood_mvebu: + BUILDMAN: $(kirkwood_mvebu) + layerscape_vf610: + BUILDMAN: $(layerscape_vf610) + m68k_remaining_mx_xtensa: + BUILDMAN: $(m68k_remaining_mx_xtensa) + mips_x86: + BUILDMAN: $(mips_x86) + mx6: + BUILDMAN: $(mx6) + imx8: + BUILDMAN: $(imx8) + imx9_arc_nios2_socfpga: + BUILDMAN: $(imx9_arc_nios2_socfpga) + phytec_toradex: + BUILDMAN: $(phytec_toradex) powerpc: BUILDMAN: $(powerpc) + riscv_stm32: + BUILDMAN: $(riscv_stm32) + rk3399: + BUILDMAN: $(rk3399) + rk352x_rk358x: + BUILDMAN: $(rk352x_rk358x) + rk356x_rk357x: + BUILDMAN: $(rk356x_rk357x) + rk3xxx_rest: + BUILDMAN: $(rk3xxx_rest) + sandbox_tegra: + BUILDMAN: $(sandbox_tegra) + samsung_omap_mediatek: + BUILDMAN: $(samsung_omap_mediatek) + sun4i_5i: + BUILDMAN: $(sun4i_5i) + sun6i_sun7i: + BUILDMAN: $(sun6i_sun7i) + sun8i: + BUILDMAN: $(sun8i) + sunxi_rest: + BUILDMAN: $(sunxi_rest) arm_catch_all: BUILDMAN: $(arm_catch_all) aarch64_catch_all: BUILDMAN: $(aarch64_catch_all) - everything_but_arm_and_powerpc: - BUILDMAN: $(everything_but_arm_and_powerpc) steps: - script: | cat << EOF > build.sh -- cgit v1.3.1 From ed9ba442ee1f9aea1ab92b10e56c8ac710a770cf Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 24 Oct 2025 22:58:27 +0530 Subject: board: samsung: add support for Samsung Exynos mobile device boards Add support for a generic platform which intends to support multiple boards powered by ARMv8 Samsung Exynos SoCs. Some important features include: * Fastboot: This is present to provide an open alternative to Samsung's proprietary Odin protocol. The board file configures certain features for fastboot, such as a dynamically allocated fastboot buffer, and standardized (lowercase) partition aliases. * EFI: Kernel image can be loaded from an EFI partition. This adopts a standard booting process, which multiple OS distributions can rely on. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- arch/arm/mach-exynos/Kconfig | 11 +- board/samsung/exynos-mobile/Kconfig | 18 ++ board/samsung/exynos-mobile/MAINTAINERS | 6 + board/samsung/exynos-mobile/Makefile | 5 + board/samsung/exynos-mobile/exynos-mobile.c | 287 ++++++++++++++++++++++++++ board/samsung/exynos-mobile/exynos-mobile.env | 18 ++ configs/exynos-mobile_defconfig | 68 ++++++ doc/board/samsung/exynos-mobile.rst | 40 ++++ doc/board/samsung/index.rst | 1 + include/configs/exynos-mobile.h | 14 ++ 10 files changed, 467 insertions(+), 1 deletion(-) create mode 100644 board/samsung/exynos-mobile/Kconfig create mode 100644 board/samsung/exynos-mobile/MAINTAINERS create mode 100644 board/samsung/exynos-mobile/Makefile create mode 100644 board/samsung/exynos-mobile/exynos-mobile.c create mode 100644 board/samsung/exynos-mobile/exynos-mobile.env create mode 100644 configs/exynos-mobile_defconfig create mode 100644 doc/board/samsung/exynos-mobile.rst create mode 100644 include/configs/exynos-mobile.h diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 2cd67d02386..b084b7284aa 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -2,7 +2,7 @@ if ARCH_EXYNOS config BOARD_COMMON def_bool y - depends on !TARGET_SMDKV310 && !TARGET_ARNDALE && !TARGET_E850_96 + depends on !TARGET_SMDKV310 && !TARGET_ARNDALE && !TARGET_EXYNOS_MOBILE && !TARGET_E850_96 config SPI_BOOTING bool @@ -252,6 +252,14 @@ config TARGET_E850_96 endchoice endif +config TARGET_EXYNOS_MOBILE + bool "Samsung Exynos Generic Boards (for mobile devices)" + select ARM64 + select BOARD_EARLY_INIT_F + select CLK_EXYNOS + select LINUX_KERNEL_IMAGE_HEADER + select OF_CONTROL + config SYS_SOC default "exynos" @@ -277,5 +285,6 @@ source "board/samsung/smdk5420/Kconfig" source "board/samsung/espresso7420/Kconfig" source "board/samsung/axy17lte/Kconfig" source "board/samsung/e850-96/Kconfig" +source "board/samsung/exynos-mobile/Kconfig" endif diff --git a/board/samsung/exynos-mobile/Kconfig b/board/samsung/exynos-mobile/Kconfig new file mode 100644 index 00000000000..ed7d16b8c6b --- /dev/null +++ b/board/samsung/exynos-mobile/Kconfig @@ -0,0 +1,18 @@ +if TARGET_EXYNOS_MOBILE + +config ENV_SOURCE_FILE + default "exynos-mobile" + +config LNX_KRNL_IMG_TEXT_OFFSET_BASE + default TEXT_BASE + +config SYS_BOARD + default "exynos-mobile" + +config SYS_CONFIG_NAME + default "exynos-mobile" + +config SYS_VENDOR + default "samsung" + +endif # TARGET_EXYNOS_MOBILE diff --git a/board/samsung/exynos-mobile/MAINTAINERS b/board/samsung/exynos-mobile/MAINTAINERS new file mode 100644 index 00000000000..11fea212fb1 --- /dev/null +++ b/board/samsung/exynos-mobile/MAINTAINERS @@ -0,0 +1,6 @@ +Exynos Generic Boards (for mobile devices) +M: Kaustabh Chakraborty +S: Maintained +F: board/samsung/exynos-mobile/ +F: configs/exynos-mobile_defconfig +F: include/configs/exynos-mobile.h diff --git a/board/samsung/exynos-mobile/Makefile b/board/samsung/exynos-mobile/Makefile new file mode 100644 index 00000000000..e049ed217c1 --- /dev/null +++ b/board/samsung/exynos-mobile/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2025 Kaustabh Chakraborty + +obj-y := exynos-mobile.o diff --git a/board/samsung/exynos-mobile/exynos-mobile.c b/board/samsung/exynos-mobile/exynos-mobile.c new file mode 100644 index 00000000000..c16281dbc36 --- /dev/null +++ b/board/samsung/exynos-mobile/exynos-mobile.c @@ -0,0 +1,287 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Samsung Exynos Generic Board Source (for mobile devices) + * + * Copyright (c) 2025 Kaustabh Chakraborty + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define lmb_alloc(size, addr) \ + lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE) + +struct exynos_board_info { + const char *name; + const char *chip; + const u64 *const dram_bank_bases; + + char serial[64]; + + int (*const match)(struct exynos_board_info *); + const char *match_model; + const u8 match_max_rev; +}; + +/* + * The memory mapping includes all DRAM banks, along with the + * peripheral block, and a sentinel at the end. This is filled in + * dynamically. + */ +static struct mm_region exynos_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { + { + /* Peripheral MMIO block */ + .virt = 0x10000000UL, + .phys = 0x10000000UL, + .size = 0x10000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN, + }, +}; + +struct mm_region *mem_map = exynos_mem_map; + +/* + * This array is used for matching the models and revisions with the + * devicetree used by U-Boot. This allows a single U-Boot to work on + * multiple devices. + * + * Entries are kept in lexicographical order of board SoCs, followed by + * board names. + */ +static struct exynos_board_info exynos_board_info_match[] = { +}; + +static void exynos_parse_dram_banks(const struct exynos_board_info *board_info, + const void *fdt_base) +{ + u64 mem_addr, mem_size = 0; + u32 na, ns, i, j; + int offset; + + if (fdt_check_header(fdt_base) < 0) + return; + + /* #address-cells and #size-cells as defined in the fdt root. */ + na = fdt_address_cells(fdt_base, 0); + ns = fdt_size_cells(fdt_base, 0); + + fdt_for_each_subnode(offset, fdt_base, 0) { + if (strncmp(fdt_get_name(fdt_base, offset, NULL), "memory", 6)) + continue; + + for (i = 0; ; i++) { + mem_addr = fdtdec_get_addr_size_fixed(fdt_base, offset, + "reg", i, na, ns, + &mem_size, false); + if (mem_addr == FDT_ADDR_T_NONE) + break; + + if (!mem_size) + continue; + + for (j = 0; j < CONFIG_NR_DRAM_BANKS; j++) { + if (board_info->dram_bank_bases[j] != mem_addr) + continue; + + mem_map[j + 1].phys = mem_addr; + mem_map[j + 1].virt = mem_addr; + mem_map[j + 1].size = mem_size; + mem_map[j + 1].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE; + break; + } + } + } +} + +static int exynos_fastboot_setup(void) +{ + struct blk_desc *blk_dev; + struct disk_partition info = {0}; + char buf[128]; + phys_addr_t addr; + int offset, i, j; + + /* Allocate and define buffer address for fastboot interface. */ + if (lmb_alloc(CONFIG_FASTBOOT_BUF_SIZE, &addr)) { + log_err("%s: failed to allocate fastboot buffer\n", __func__); + return -ENOMEM; + } + env_set_hex("fastboot_addr_r", addr); + + blk_dev = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV); + if (!blk_dev) { + log_err("%s: required mmc device not available\n", __func__); + return -ENODEV; + } + + strcpy(buf, "fastboot_partition_alias_"); + offset = strlen(buf); + + for (i = 1; i < CONFIG_EFI_PARTITION_ENTRIES_NUMBERS; i++) { + if (part_get_info(blk_dev, i, &info)) + continue; + + /* + * The partition name must be lowercase (stored in buf[]), + * as is expected in all fastboot partitions ... + */ + strlcpy(buf + offset, info.name, sizeof(buf) - offset); + for (j = offset; buf[j]; j++) + buf[j] = tolower(buf[j]); + if (!strcmp(buf + offset, info.name)) + continue; + /* + * ... However, if that isn't the case, a fastboot + * partition alias must be defined to establish it. + */ + env_set(buf, info.name); + } + + return 0; +} + +int board_fit_config_name_match(const char *name) +{ + struct exynos_board_info *board_info; + char buf[128]; + unsigned int i; + int ret; + + /* + * Iterate over exynos_board_info_match[] to select the + * appropriate board info struct. If not found, exit. + */ + for (i = 0; i < ARRAY_SIZE(exynos_board_info_match); i++) { + board_info = exynos_board_info_match + i; + snprintf(buf, sizeof(buf), "%s-%s", board_info->chip, + board_info->name); + + if (!strcmp(name, buf)) + break; + } + if (i == ARRAY_SIZE(exynos_board_info_match)) + return -1; + + /* + * Execute match logic for the target board. This is separated + * as the process may be different for multiple boards. + */ + ret = board_info->match(board_info); + if (ret) + return ret; + + /* + * Store the correct board info struct in gd->board_type to + * allow other functions to access it. + */ + gd->board_type = (ulong)board_info; + log_debug("%s: device detected: %s\n", __func__, name); + + return 0; +} + +int timer_init(void) +{ + ofnode timer_node; + + /* + * In a lot of Exynos devices, the previous bootloader does not + * set CNTFRQ_EL0 properly. However, the timer node in + * devicetree has the correct frequency, use that instead. + */ + timer_node = ofnode_by_compatible(ofnode_null(), "arm,armv8-timer"); + gd->arch.timer_rate_hz = ofnode_read_u32_default(timer_node, + "clock-frequency", 0); + + return 0; +} + +int board_early_init_f(void) +{ + const struct exynos_board_info *board_info; + + if (!gd->board_type) + return -ENODATA; + board_info = (const struct exynos_board_info *)gd->board_type; + + exynos_parse_dram_banks(board_info, gd->fdt_blob); + /* + * Some devices have multiple variants based on the amount of + * memory and internal storage. The lowest bank base has been + * observed to have the same memory range in all board variants. + * For variants with more memory, the previous bootloader should + * overlay the devicetree with the required extra memory ranges. + */ + exynos_parse_dram_banks(board_info, (const void *)get_prev_bl_fdt_addr()); + + return 0; +} + +int dram_init(void) +{ + unsigned int i; + + /* Select the largest RAM bank for U-Boot. */ + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + if (gd->ram_size < mem_map[i + 1].size) { + gd->ram_base = mem_map[i + 1].phys; + gd->ram_size = mem_map[i + 1].size; + } + } + + return 0; +} + +int dram_init_banksize(void) +{ + unsigned int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + gd->bd->bi_dram[i].start = mem_map[i + 1].phys; + gd->bd->bi_dram[i].size = mem_map[i + 1].size; + } + + return 0; +} + +int board_init(void) +{ + return 0; +} + +int misc_init_r(void) +{ + const struct exynos_board_info *board_info; + char buf[128]; + + if (!gd->board_type) + return -ENODATA; + board_info = (const struct exynos_board_info *)gd->board_type; + + env_set("platform", board_info->chip); + env_set("board", board_info->name); + + if (strlen(board_info->serial)) + env_set("serial#", board_info->serial); + + /* EFI booting requires the path to correct dtb, specify it here. */ + snprintf(buf, sizeof(buf), "exynos/%s-%s.dtb", board_info->chip, + board_info->name); + env_set("fdtfile", buf); + + return exynos_fastboot_setup(); +} diff --git a/board/samsung/exynos-mobile/exynos-mobile.env b/board/samsung/exynos-mobile/exynos-mobile.env new file mode 100644 index 00000000000..aa2e89afbac --- /dev/null +++ b/board/samsung/exynos-mobile/exynos-mobile.env @@ -0,0 +1,18 @@ +stdin=serial,button-kbd +stdout=serial,vidconsole +stderr=serial,vidconsole + +bootdelay=0 +bootcmd=bootefi bootmgr; pause; bootmenu + +fastbootcmd=echo "Fastboot Mode"; + fastboot -l $fastboot_addr_r usb 0 + +bootmenu_0=Continue Boot=boot +bootmenu_1=Enter Fastboot Mode=run fastbootcmd +bootmenu_2=UEFI Maintenance Menu=eficonfig +bootmenu_3=Reboot=reset +bootmenu_4=Power Off=poweroff + +button_cmd_0_name=Volume Down Key +button_cmd_0=bootmenu diff --git a/configs/exynos-mobile_defconfig b/configs/exynos-mobile_defconfig new file mode 100644 index 00000000000..2dbf90010ba --- /dev/null +++ b/configs/exynos-mobile_defconfig @@ -0,0 +1,68 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=26000000 +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_EXYNOS=y +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SYS_MALLOC_F_LEN=0x16000 +CONFIG_TARGET_EXYNOS_MOBILE=y +CONFIG_NR_DRAM_BANKS=3 +CONFIG_SYS_BOOTM_LEN=0x2000000 +CONFIG_SYS_LOAD_ADDR=0x80000000 +CONFIG_ARMV8_CNTFRQ_BROKEN=y +# CONFIG_PSCI_RESET is not set +CONFIG_BUTTON_CMD=y +CONFIG_SAVE_PREV_BL_FDT_ADDR=y +CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR=y +CONFIG_SYS_PBSIZE=1024 +CONFIG_BOARD_TYPES=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_MISC_INIT_R=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_BOOTMENU=y +CONFIG_CMD_POWEROFF=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_EFI_PARTITION=y +CONFIG_OF_UPSTREAM=y +CONFIG_MULTI_DTB_FIT=y +CONFIG_BUTTON=y +CONFIG_BUTTON_REMAP_PHONE_KEYS=y +CONFIG_CLK=y +CONFIG_CLK_CCF=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0xdead0000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_SYS_I2C_S3C24X0=y +CONFIG_BUTTON_KEYBOARD=y +CONFIG_MISC=y +CONFIG_MMC_BROKEN_CD=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y +CONFIG_MMC_HS400_SUPPORT=y +CONFIG_MMC_DW=y +CONFIG_PHY=y +CONFIG_PHY_EXYNOS_USBDRD=y +CONFIG_PINCTRL=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_S2MPS11=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_S2MPS11=y +CONFIG_SOC_SAMSUNG=y +CONFIG_EXYNOS_PMU=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_CMD_POWEROFF=y +CONFIG_SYSRESET_SYSCON=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Samsung" +CONFIG_USB_GADGET_VENDOR_NUM=0x04e8 +CONFIG_USB_GADGET_PRODUCT_NUM=0x6602 +CONFIG_VIDEO=y +CONFIG_VIDEO_SIMPLE=y +CONFIG_FS_EXT4=y +CONFIG_FS_FAT=y diff --git a/doc/board/samsung/exynos-mobile.rst b/doc/board/samsung/exynos-mobile.rst new file mode 100644 index 00000000000..d5c1c83a4e8 --- /dev/null +++ b/doc/board/samsung/exynos-mobile.rst @@ -0,0 +1,40 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. sectionauthor:: Kaustabh Chakraborty + +Samsung Exynos Generic ARMv8 Boards (for mobile devices) +======================================================= + +Overview +-------- +This document describes how to build and run U-Boot for Samsung Exynos generic +boards. Boards are expected to boot with a primary bootloader, such as S-BOOT or +S-LK, which hands off control to U-Boot. Presently, only ARMv8 devices are +supported. + +The U-Boot image is built with all device tree blobs packed in a single FIT +image. During boot, it uses simple heuristics to detect the target board, and +subsequently the appropriate FDT is selected. + +Installation +------------ +Building +^^^^^^^^ +If a cross-compiler is required, install it and set it up like so: + +.. prompt:: bash $ + + export CROSS_COMPILE=aarch64-linux-gnu- + +Then, run the following commands to build U-Boot: + +.. prompt:: bash $ + + make O=.output exynos-mobile_defconfig + make O=.output -j$(nproc) + +If successful, the U-Boot binary will be present in ``.output/u-boot.bin``. + +Preparation and Flashing +^^^^^^^^^^^^^^^^^^^^^^^^ +Since U-Boot supports multiple boards, and devices have different requirements, +this step will vary depending on your target. diff --git a/doc/board/samsung/index.rst b/doc/board/samsung/index.rst index 1b92c9518a5..1fbe88130c0 100644 --- a/doc/board/samsung/index.rst +++ b/doc/board/samsung/index.rst @@ -8,4 +8,5 @@ Samsung axy17lte e850-96 + exynos-mobile n1 diff --git a/include/configs/exynos-mobile.h b/include/configs/exynos-mobile.h new file mode 100644 index 00000000000..862db5779ef --- /dev/null +++ b/include/configs/exynos-mobile.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Samsung Exynos Generic Board Configuration (for mobile devices) + * + * Copyright (C) 2025 Kaustabh Chakraborty + */ + +#ifndef __CONFIG_EXYNOS_MOBILE_H +#define __CONFIG_EXYNOS_MOBILE_H + +#define CPU_RELEASE_ADDR secondary_boot_addr +#define CFG_SYS_BAUDRATE_TABLE {9600, 115200} + +#endif /* __CONFIG_EXYNOS_MOBILE_H */ -- cgit v1.3.1 From 8580ca964f6e2b0ec4d118b42dfb019301f07d0d Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 24 Oct 2025 22:58:28 +0530 Subject: board: samsung: exynos-mobile: add exynos7870 support and three devices Add basic support for the Exynos7870 SoC, this includes device tree match logic using multiple boards, where devices use a stub dtb in Samsung's QCDT format. S-BOOT, the previous stage bootloader, places its cmdline arguments there, which has identifying information. This is added with support for three devices: * Samsung Galaxy A2 Core (codename: a2corelte) * Samsung Galaxy J6 (codename: j6lte) * Samsung Galaxy J7 Prime (codename: on7xelte) Add their device trees in the defconfig, and also enable the clock and pin controller drivers. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- .../samsung/exynos-mobile/debug-exynos7870.config | 7 ++ board/samsung/exynos-mobile/exynos-mobile.c | 116 +++++++++++++++++++++ configs/exynos-mobile_defconfig | 4 + 3 files changed, 127 insertions(+) create mode 100644 board/samsung/exynos-mobile/debug-exynos7870.config diff --git a/board/samsung/exynos-mobile/debug-exynos7870.config b/board/samsung/exynos-mobile/debug-exynos7870.config new file mode 100644 index 00000000000..1aa506a675d --- /dev/null +++ b/board/samsung/exynos-mobile/debug-exynos7870.config @@ -0,0 +1,7 @@ +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_BASE=0x13820000 +CONFIG_DEBUG_UART_CLOCK=133250000 +CONFIG_DEBUG_UART_S5P=y +CONFIG_LOG=y +CONFIG_LOG_CONSOLE=y +CONFIG_LOG_MAX_LEVEL=8 diff --git a/board/samsung/exynos-mobile/exynos-mobile.c b/board/samsung/exynos-mobile/exynos-mobile.c index c16281dbc36..8ef38816abf 100644 --- a/board/samsung/exynos-mobile/exynos-mobile.c +++ b/board/samsung/exynos-mobile/exynos-mobile.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,96 @@ static struct mm_region exynos_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { struct mm_region *mem_map = exynos_mem_map; +static const u64 exynos7870_common_dram_bank_bases[CONFIG_NR_DRAM_BANKS] = { + 0x40000000, 0x80000000, 0x100000000, +}; + +static const char *exynos_prev_bl_get_bootargs(void) +{ + void *prev_bl_fdt_base = (void *)get_prev_bl_fdt_addr(); + int chosen_node_offset, ret; + const struct fdt_property *bootargs_prop; + + ret = fdt_check_header(prev_bl_fdt_base); + if (ret < 0) { + log_err("%s: FDT is invalid (FDT_ERR %d)\n", __func__, ret); + return NULL; + } + + ret = fdt_path_offset(prev_bl_fdt_base, "/chosen"); + chosen_node_offset = ret; + if (ret < 0) { + log_err("%s: /chosen node not found (FDT_ERR %d)\n", __func__, + ret); + return NULL; + } + + bootargs_prop = fdt_get_property(prev_bl_fdt_base, chosen_node_offset, + "bootargs", &ret); + if (!bootargs_prop) { + log_err("%s: /chosen/bootargs property not found (FDT_ERR %d)\n", + __func__, ret); + return NULL; + } + + return bootargs_prop->data; +} + +static int exynos7870_fdt_match(struct exynos_board_info *board_info) +{ + const char *prev_bl_bootargs; + int val, ret; + + prev_bl_bootargs = exynos_prev_bl_get_bootargs(); + if (!prev_bl_bootargs) + return -1; + + /* + * Read the cmdline property which stores the + * bootloader/firmware version. An example value of the option + * can be: "J600GDXU3ARH5". This can be used to verify the model + * of the device. + */ + ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.bootloader", &val); + if (ret < 0) { + log_err("%s: unable to find property for bootloader version (%d)\n", + __func__, ret); + return -1; + } + + if (strncmp(prev_bl_bootargs + val, board_info->match_model, + strlen(board_info->match_model))) + return -1; + + /* + * Read the cmdline property which stores the hardware revision. + * This is required to allow selecting one of multiple dtbs + * available of a single device, varying in hardware changes in + * different revisions. + */ + ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.revision", &val); + if (ret < 0) + ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.hw_rev", &val); + if (ret < 0) { + log_err("%s: unable to find property for bootloader revision (%d)\n", + __func__, ret); + return -1; + } + + if (strtoul(prev_bl_bootargs + val, NULL, 10) > board_info->match_max_rev) + return -1; + + /* + * Read the cmdline property which stores the serial number. + * Store this in the board info struct. + */ + ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.serialno", &val); + if (ret > 0) + strlcpy(board_info->serial, prev_bl_bootargs + val, ret); + + return 0; +} + /* * This array is used for matching the models and revisions with the * devicetree used by U-Boot. This allows a single U-Boot to work on @@ -62,6 +153,31 @@ struct mm_region *mem_map = exynos_mem_map; * board names. */ static struct exynos_board_info exynos_board_info_match[] = { + { + /* Samsung Galaxy A2 Core */ + .name = "a2corelte", + .chip = "exynos7870", + .dram_bank_bases = exynos7870_common_dram_bank_bases, + .match = exynos7870_fdt_match, + .match_model = "A260", + .match_max_rev = U8_MAX, + }, { + /* Samsung Galaxy J6 */ + .name = "j6lte", + .chip = "exynos7870", + .dram_bank_bases = exynos7870_common_dram_bank_bases, + .match = exynos7870_fdt_match, + .match_model = "J600", + .match_max_rev = U8_MAX, + }, { + /* Samsung Galaxy J7 Prime */ + .name = "on7xelte", + .chip = "exynos7870", + .dram_bank_bases = exynos7870_common_dram_bank_bases, + .match = exynos7870_fdt_match, + .match_model = "G610", + .match_max_rev = U8_MAX, + }, }; static void exynos_parse_dram_banks(const struct exynos_board_info *board_info, diff --git a/configs/exynos-mobile_defconfig b/configs/exynos-mobile_defconfig index 2dbf90010ba..81a2c4d3373 100644 --- a/configs/exynos-mobile_defconfig +++ b/configs/exynos-mobile_defconfig @@ -7,6 +7,7 @@ CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x16000 CONFIG_TARGET_EXYNOS_MOBILE=y CONFIG_NR_DRAM_BANKS=3 +CONFIG_DEFAULT_DEVICE_TREE="exynos/exynos7870-a2corelte" CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0x80000000 CONFIG_ARMV8_CNTFRQ_BROKEN=y @@ -24,11 +25,13 @@ CONFIG_CMD_POWEROFF=y CONFIG_CMD_FS_GENERIC=y CONFIG_EFI_PARTITION=y CONFIG_OF_UPSTREAM=y +CONFIG_OF_LIST="exynos/exynos7870-a2corelte exynos/exynos7870-j6lte exynos/exynos7870-on7xelte" CONFIG_MULTI_DTB_FIT=y CONFIG_BUTTON=y CONFIG_BUTTON_REMAP_PHONE_KEYS=y CONFIG_CLK=y CONFIG_CLK_CCF=y +CONFIG_CLK_EXYNOS7870=y CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0xdead0000 CONFIG_FASTBOOT_FLASH=y @@ -44,6 +47,7 @@ CONFIG_MMC_DW=y CONFIG_PHY=y CONFIG_PHY_EXYNOS_USBDRD=y CONFIG_PINCTRL=y +CONFIG_PINCTRL_EXYNOS78x0=y CONFIG_DM_PMIC=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_REGULATOR=y -- cgit v1.3.1 From 422b15bb5b693376e345d3f32d7cec4588f3bfba Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 24 Oct 2025 22:58:29 +0530 Subject: doc: samsung: exynos-mobile: add documentation for exynos7870 Document the image preparation and flashing techniques for Exynos7870-based boards. This is done in a separate file in a sub-directory, which is linked back to the main documentation. Signed-off-by: Kaustabh Chakraborty Signed-off-by: Minkyu Kang --- doc/board/samsung/exynos-mobile.rst | 5 ++ doc/board/samsung/exynos-mobile/exynos7870.rst | 85 ++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 doc/board/samsung/exynos-mobile/exynos7870.rst diff --git a/doc/board/samsung/exynos-mobile.rst b/doc/board/samsung/exynos-mobile.rst index d5c1c83a4e8..9634991c0a1 100644 --- a/doc/board/samsung/exynos-mobile.rst +++ b/doc/board/samsung/exynos-mobile.rst @@ -38,3 +38,8 @@ Preparation and Flashing ^^^^^^^^^^^^^^^^^^^^^^^^ Since U-Boot supports multiple boards, and devices have different requirements, this step will vary depending on your target. + +.. toctree:: + :maxdepth: 1 + + exynos-mobile/exynos7870 diff --git a/doc/board/samsung/exynos-mobile/exynos7870.rst b/doc/board/samsung/exynos-mobile/exynos7870.rst new file mode 100644 index 00000000000..bbd857580b8 --- /dev/null +++ b/doc/board/samsung/exynos-mobile/exynos7870.rst @@ -0,0 +1,85 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. sectionauthor:: Kaustabh Chakraborty + +Samsung Exynos 7870 Boards +========================== + +Preparation +----------- +Create the following device tree (named ``stub.dts``) + +.. code-block:: devicetree + + /dts-v1/; + + / { + compatible = "samsung,exynos7870"; + #address-cells = <2>; + #size-cells = <1>; + + model_info-chip = <7870>; + model_info-hw_rev = <0>; + model_info-hw_rev_end = <255>; + + chosen { + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0>; + }; + + memory@100000000 { + device_type = "memory"; + reg = <0x1 0x00000000 0x0>; + }; + }; + +The chosen node and memory ranges are populated by S-BOOT. A certain device +model may have multiple variants, with differing amounts of RAM and storage. The +RAM capacity information is graciously provided by S-BOOT's device tree +overlays. + +Compile it to a device tree blob, then pack it in the QCDT format [1]_ using +``dtbTool-exynos`` [2]_ by issuing the following commands: + +.. prompt:: bash $ + + dtc -I dts -O dtb -o stub.dtb stub.dts + dtbTool-exynos -o stub-dt.img stub.dtb + +Finally, use ``mkbootimg`` by osm0sis [3]_ to generate the boot image: + +.. prompt:: bash $ + + mkbootimg -o u-boot.img \ + --kernel .output/u-boot.bin \ + --dt stub-dt.img + +Offsets are not provided to ``mkbootimg`` as S-BOOT ignores them. + +Flashing +-------- +If flashing for the first time, it must be done via Samsung's Download (Odin) +mode. Heimdall [4]_ can be used for flashing, like so: + +.. prompt:: bash $ + + heimdall flash --BOOT u-boot.img + +However, if U-Boot is already installed, you may also use its fastboot interface +for flashing. Boot into the boot menu by holding the volume down key. Enable +fastboot mode from there, connect the device to your host, then run: + +.. prompt:: bash $ + + fastboot flash boot u-boot.img + +To flash an OS image in internal storage, fastboot is a reliable option. + +References +---------- +.. [1] https://wiki.postmarketos.org/wiki/QCDT +.. [2] https://github.com/dsankouski/dtbtool-exynos +.. [3] https://github.com/osm0sis/mkbootimg +.. [4] https://git.sr.ht/~grimler/Heimdall -- cgit v1.3.1 From 710a7c791275433383dcdebde79efc04e1e97a83 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 19 Nov 2025 21:39:48 +0100 Subject: ARM: dts: renesas: Enable R8A779G0 V4H White Hawk RPC SPI DT node Disabling RPC breaks SPL boot on R-Car V4H White Hawk board, re-enable RPC. Fixes: 1d94364c7f17 ("ARM: dts: renesas: Disable R8A779G0 V4H White Hawk RPC SPI DT node again") Signed-off-by: Marek Vasut --- arch/arm/dts/r8a779g0-white-hawk-u-boot.dtsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/dts/r8a779g0-white-hawk-u-boot.dtsi b/arch/arm/dts/r8a779g0-white-hawk-u-boot.dtsi index 8e4307ff87d..85e32208b29 100644 --- a/arch/arm/dts/r8a779g0-white-hawk-u-boot.dtsi +++ b/arch/arm/dts/r8a779g0-white-hawk-u-boot.dtsi @@ -23,8 +23,6 @@ &rpc { bootph-all; - status = "disabled"; - flash@0 { bootph-all; spi-tx-bus-width = <1>; -- cgit v1.3.1 From 925e0cb3b99ab73b26926d8aa006579b7a8214a9 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 6 Nov 2025 20:13:24 +0100 Subject: ARM: renesas: Disable CONFIG_ENV_OVERWRITE on all boards The CONFIG_ENV_OVERWRITE allows easy rewrite of environment variables like 'ethaddr' and 'serial#' without any protection against accidental removal of those variables. Remove this setting to add extra layer of protection to those variables. The variables can still be overridden using 'env set -f' (force set) if really needed. Signed-off-by: Marek Vasut --- configs/renesas_rcar.config | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/renesas_rcar.config b/configs/renesas_rcar.config index 45776be62ea..d9a99e1f428 100644 --- a/configs/renesas_rcar.config +++ b/configs/renesas_rcar.config @@ -17,7 +17,6 @@ CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y CONFIG_DM_SPI=y CONFIG_DM_SPI_FLASH=y -CONFIG_ENV_OVERWRITE=y CONFIG_ENV_VARS_UBOOT_CONFIG=y CONFIG_FIT=y CONFIG_HUSH_PARSER=y -- cgit v1.3.1 From 6ec94acd15e3a44700287c27ca8cf15488afd424 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 19 Nov 2025 21:36:59 +0100 Subject: arm64: renesas: r8a779g3: Use redundant env on Retronix R-Car V4H Sparrow Hawk board The redundant environment offset is already set in board configuration, but the redundant environment itself is not explicitly enabled. Make sure the redundant environment is enabled, as we most certainly do want to have two copies of the environment. Signed-off-by: Marek Vasut --- configs/r8a779g3_sparrowhawk_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/r8a779g3_sparrowhawk_defconfig b/configs/r8a779g3_sparrowhawk_defconfig index 2d1abf6f26d..ee8f2711985 100644 --- a/configs/r8a779g3_sparrowhawk_defconfig +++ b/configs/r8a779g3_sparrowhawk_defconfig @@ -6,6 +6,7 @@ CONFIG_RCAR_GEN4=y CONFIG_ARM_SMCCC=y CONFIG_ARMV8_PSCI=y CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_ENV_REDUNDANT=y CONFIG_ENV_OFFSET=0x3f80000 CONFIG_ENV_OFFSET_REDUND=0x3fc0000 CONFIG_ENV_SECT_SIZE=0x40000 -- cgit v1.3.1 From 209bbc4e0032228c6ea17e2172a8a6b89756c4f5 Mon Sep 17 00:00:00 2001 From: Adriana Nicolae Date: Thu, 27 Nov 2025 08:28:34 -0800 Subject: boot/bootfdt: Add smbios3-entrypoint to FDT for non-EFI boots The Linux kernel can discover SMBIOS tables through two primary methods: 1. Via EFI tables, when using EFI boot; 2. Via the 'smbios3-entrypoint' property in the /chosen node of the device tree. When U-Boot boots a Linux kernel using a non-EFI command ("bootm", "bootz", or "booti"), the kernel relies on the device tree to detect the hardware. If SMBIOS tables are available in U-Boot, they should be passed to the kernel via this device tree property. This patch modifies boot_fdt_prepare(), to inject the SMBIOSv3 table address into the device tree if there is a table generated by U-boot. The "board_fdt_chosen_smbios" is weak in order to leave the possibilty for specific boards to select custom SMBIOS addresses. The changes in this patch are added in the context of supporting this device tree property in linux kernel: https://lkml.org/lkml/2025/10/24/1393 Device tree schema was updated to include the "smbios3-entrypoint" node in pull request: https://github.com/devicetree-org/dt-schema/pull/177 Signed-off-by: Adriana Nicolae --- boot/fdt_support.c | 19 +++++++++++++++++++ test/cmd/fdt.c | 9 +++++++++ test/dm/fdtdec.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/boot/fdt_support.c b/boot/fdt_support.c index 92f2f534ee0..1c215e548db 100644 --- a/boot/fdt_support.c +++ b/boot/fdt_support.c @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -333,6 +334,7 @@ int fdt_chosen(void *fdt) int nodeoffset; int err; const char *str; /* used to set string properties */ + ulong smbiosaddr; /* SMBIOS table address */ err = fdt_check_header(fdt); if (err < 0) { @@ -387,6 +389,23 @@ int fdt_chosen(void *fdt) return err; } + if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) { + /* Inject SMBIOS address when we have a valid address. + * This is useful for systems using booti/bootm instead of bootefi. + * Failure to set this property is non-fatal, we only generate a + * warning. + */ + smbiosaddr = gd_smbios_start(); + if (smbiosaddr) { + err = fdt_setprop_u64(fdt, nodeoffset, "smbios3-entrypoint", + smbiosaddr); + if (err < 0) { + printf("WARNING: could not set smbios3-entrypoint %s.\n", + fdt_strerror(err)); + } + } + } + return fdt_fixup_stdout(fdt, nodeoffset); } diff --git a/test/cmd/fdt.c b/test/cmd/fdt.c index 4c3c6308ab4..a121b294185 100644 --- a/test/cmd/fdt.c +++ b/test/cmd/fdt.c @@ -1274,6 +1274,7 @@ static int fdt_test_chosen(struct unit_test_state *uts) char fdt[8192]; struct udevice *dev; ulong addr; + ulong smbiosaddr = gd_smbios_start(); ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt), &addr)); fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */ @@ -1292,6 +1293,10 @@ static int fdt_test_chosen(struct unit_test_state *uts) ut_assert(0 < console_record_readline(uts->actual_str, sizeof(uts->actual_str))); ut_asserteq_str("chosen {", uts->actual_str); + if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) + ut_assert_nextline("\tsmbios3-entrypoint = <0x%08x 0x%08x>;", + upper_32_bits(smbiosaddr), + lower_32_bits(smbiosaddr)); ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */ if (env_bootargs) ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs); @@ -1316,6 +1321,10 @@ static int fdt_test_chosen(struct unit_test_state *uts) lower_32_bits(0x1234 + 0x5678 - 1)); ut_assert_nextline("\tlinux,initrd-start = <0x%08x 0x%08x>;", upper_32_bits(0x1234), lower_32_bits(0x1234)); + if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) + ut_assert_nextline("\tsmbios3-entrypoint = <0x%08x 0x%08x>;", + upper_32_bits(smbiosaddr), + lower_32_bits(smbiosaddr)); ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */ if (env_bootargs) ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs); diff --git a/test/dm/fdtdec.c b/test/dm/fdtdec.c index 1f24f1d5dff..ea5a494612c 100644 --- a/test/dm/fdtdec.c +++ b/test/dm/fdtdec.c @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -129,3 +132,48 @@ static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts) } DM_TEST(dm_test_fdtdec_add_reserved_memory, UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_FLAT_TREE); + +static int dm_test_fdt_chosen_smbios(struct unit_test_state *uts) +{ + void *blob; + ulong val; + struct smbios3_entry *entry; + int chosen, blob_sz; + const fdt64_t *prop; + + if (!CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) { + return -EAGAIN; + } + + blob_sz = fdt_totalsize(gd->fdt_blob) + 4096; + blob = memalign(8, blob_sz); + ut_assertnonnull(blob); + + /* Make a writable copy of the fdt blob */ + ut_assertok(fdt_open_into(gd->fdt_blob, blob, blob_sz)); + + /* Mock SMBIOS table */ + entry = map_sysmem(gd->arch.smbios_start, sizeof(struct smbios3_entry)); + memcpy(entry->anchor, "_SM3_", 5); + entry->length = sizeof(struct smbios3_entry); + unmap_sysmem(entry); + + /* Force fdt_chosen to run */ + ut_assertok(fdt_chosen(blob)); + + chosen = fdt_path_offset(blob, "/chosen"); + ut_assert(chosen >= 0); + + /* Verify the property exists */ + prop = fdt_getprop(blob, chosen, "smbios3-entrypoint", NULL); + ut_assertnonnull(prop); + + /* Verify the property matches smbios_start */ + val = fdt64_to_cpu(*prop); + ut_asserteq_64(gd->arch.smbios_start, val); + + free(blob); + + return 0; +} +DM_TEST(dm_test_fdt_chosen_smbios, UTF_SCAN_PDATA | UTF_SCAN_FDT); -- cgit v1.3.1 From db95933996603814ba648ac6bae4eca07b4061ef Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 19 Nov 2025 18:44:36 +0100 Subject: sh: Assure end of U-Boot is at 8-byte aligned offset Make sure the end of U-Boot is at 8-byte aligned offset, not 4-byte aligned offset. This allows safely appending DT at the end of U-Boot with the guarantee that the DT will be at 8-byte aligned offset. This 8-byte alignment is now checked by newer libfdt 1.7.2 . Signed-off-by: Marek Vasut --- arch/sh/cpu/u-boot.lds | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/sh/cpu/u-boot.lds b/arch/sh/cpu/u-boot.lds index c31deecec65..81526f5bd23 100644 --- a/arch/sh/cpu/u-boot.lds +++ b/arch/sh/cpu/u-boot.lds @@ -72,6 +72,7 @@ SECTIONS __u_boot_list : { KEEP(*(SORT(__u_boot_list*))); + . = ALIGN(8); } >ram PROVIDE (__init_end = .); @@ -83,7 +84,7 @@ SECTIONS .bss : { *(.bss) - . = ALIGN(4); + . = ALIGN(8); } >ram PROVIDE (bss_end = .); PROVIDE (__bss_end = .); -- cgit v1.3.1 From af96395a821c4c87e2026351b5d05de9726df1ef Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 27 Oct 2025 17:33:07 +0100 Subject: clk: renesas: Introduce temporary compound clock for SCP compatibility The current state of SCP on Renesas R-Car Gen5 is not yet final and is still missing full clock control, the clock control is exposed as separate enable/disable and rate controls. Temporarily introduce custom local compound clock, which are used as an adaptation layer between U-Boot clock tree and current state of SCP, and which bind two SCP clock into a single compound clock, which provides both enable/disable and rate controls. This is mainly meant to be used by SD/eMMC controller, to allow the driver to both turn its clock on and off, and also obtain the current clock rate. This is going to be removed once the SCP clock protocol solidifies. Signed-off-by: Marek Vasut --- drivers/clk/renesas/Makefile | 4 ++ drivers/clk/renesas/compound-clock.c | 92 ++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 drivers/clk/renesas/compound-clock.c diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 6c742553091..354035baf2d 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -26,3 +26,7 @@ obj-$(CONFIG_CLK_R8A779H0) += r8a779h0-cpg-mssr.o obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o obj-$(CONFIG_CLK_RZG2L) += rzg2l-cpg.o obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o + +# Temporary stub clock used for SCP compatibility. +# This is going to be removed once SCP solidifies. +obj-$(CONFIG_R8A78000) += compound-clock.o diff --git a/drivers/clk/renesas/compound-clock.c b/drivers/clk/renesas/compound-clock.c new file mode 100644 index 00000000000..499a2598833 --- /dev/null +++ b/drivers/clk/renesas/compound-clock.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2025 Marek Vasut + */ + +#define LOG_CATEGORY UCLASS_CLK + +#include +#include +#include +#include +#include + +struct clk_compound_rate { + struct clk clk; /* This clock */ + struct clk mdlc; /* MDLC parent module clock */ + struct clk per; /* Peripheral parent clock */ +}; + +static struct clk_compound_rate *to_clk_compound_rate(struct clk *clk) +{ + return (struct clk_compound_rate *)dev_get_plat(clk->dev); +} + +static int clk_compound_rate_enable(struct clk *clk) +{ + struct clk_compound_rate *cc = to_clk_compound_rate(clk); + + return clk_enable(&cc->mdlc); +} + +static int clk_compound_rate_disable(struct clk *clk) +{ + struct clk_compound_rate *cc = to_clk_compound_rate(clk); + + return clk_disable(&cc->mdlc); +} + +static ulong clk_compound_rate_get_rate(struct clk *clk) +{ + struct clk_compound_rate *cc = to_clk_compound_rate(clk); + + return clk_get_rate(&cc->per); +} + +static ulong clk_compound_rate_set_rate(struct clk *clk, ulong rate) +{ + return 0; /* Set rate is not forwarded to SCP */ +} + +const struct clk_ops clk_compound_rate_ops = { + .enable = clk_compound_rate_enable, + .disable = clk_compound_rate_disable, + .get_rate = clk_compound_rate_get_rate, + .set_rate = clk_compound_rate_set_rate, +}; + +static int clk_compound_rate_of_to_plat(struct udevice *dev) +{ + struct clk_compound_rate *cc = (struct clk_compound_rate *)dev_get_plat(dev); + struct clk *clk = &cc->clk; + int ret; + + clk->dev = dev; + clk->id = CLK_ID(dev, 0); + clk->enable_count = 0; + + ret = clk_get_by_index(dev, 0, &cc->mdlc); + if (ret) + return ret; + + ret = clk_get_by_index(dev, 1, &cc->per); + if (ret) + return ret; + + return 0; +} + +static const struct udevice_id clk_compound_rate_match[] = { + { .compatible = "renesas,compound-clock", }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(renesas_compound_clock) = { + .name = "compound-clock", + .id = UCLASS_CLK, + .of_match = clk_compound_rate_match, + .of_to_plat = clk_compound_rate_of_to_plat, + .plat_auto = sizeof(struct clk_compound_rate), + .ops = &clk_compound_rate_ops, + .flags = DM_FLAG_PRE_RELOC, +}; -- cgit v1.3.1 From 5353fc464f00b2bf8e69ddbbcb4f1704566bcde2 Mon Sep 17 00:00:00 2001 From: Tuyen Dang Date: Mon, 27 Oct 2025 17:39:17 +0100 Subject: mailbox: renesas: Add Renesas MFIS Multifunctional Interface mailbox driver Add support for the Renesas MFIS mailbox, which provides an interface between the different CPU Cores, such as AP System Core domain and the Realtime Core domain, SCP Core domain and AP System Core domain or Realtime Core domain and AP System Core domain or Realtime Core domain. Signed-off-by: Tuyen Dang Signed-off-by: Marek Vasut # Update the driver [Marek: Rename the driver to renesas-mfis, simplify the driver. Always use only one TX channel and no RX channel, drop all unnecessary code. Perform 1ms delay in send callback which is perfectly fine to do in U-Boot which does RX polling] --- drivers/mailbox/Kconfig | 10 +++++++ drivers/mailbox/Makefile | 1 + drivers/mailbox/renesas-mfis.c | 59 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 drivers/mailbox/renesas-mfis.c diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index f9531c1627c..cfd2a3be3fd 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -66,6 +66,16 @@ config K3_SEC_PROXY Select this driver if your platform has support for this hardware block. +config RCAR_MFIS_MBOX + bool "Renesas MFIS Multifunctional Interface mailbox driver" + depends on DM_MAILBOX && ARCH_RENESAS + help + This enables support for the Renesas MFIS mailbox module, which + provides an interface between the different CPU Cores, such as AP + System Core domain and the Realtime Core domain, SCP Core domain + and AP System Core domain or Realtime Core domain and AP System + Core domain or Realtime Core domain. + config ZYNQMP_IPI bool "Xilinx ZynqMP IPI controller support" depends on DM_MAILBOX && (ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2) diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index b54fbdfff15..b3a36691497 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -12,4 +12,5 @@ obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox-test.o obj-$(CONFIG_STM32_IPCC) += stm32-ipcc.o obj-$(CONFIG_TEGRA_HSP) += tegra-hsp.o obj-$(CONFIG_K3_SEC_PROXY) += k3-sec-proxy.o +obj-$(CONFIG_RCAR_MFIS_MBOX) += renesas-mfis.o obj-$(CONFIG_ZYNQMP_IPI) += zynqmp-ipi.o diff --git a/drivers/mailbox/renesas-mfis.c b/drivers/mailbox/renesas-mfis.c new file mode 100644 index 00000000000..1e9e8285974 --- /dev/null +++ b/drivers/mailbox/renesas-mfis.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020-2025, Renesas Electronics Corporation. + */ + +#include +#include +#include +#include + +#define COM 0x0 +#define IIR BIT(0) + +struct mfis_priv { + void __iomem *tx_base; +}; + +static int mfis_send(struct mbox_chan *chan, const void *data) +{ + struct mfis_priv *mfis = dev_get_priv(chan->dev); + + writel(IIR, mfis->tx_base + COM); + + /* Give the remote side some time. */ + mdelay(1); + + writel(0, mfis->tx_base + COM); + + return 0; +} + +struct mbox_ops mfis_mbox_ops = { + .send = mfis_send, +}; + +static int mfis_mbox_probe(struct udevice *dev) +{ + struct mfis_priv *mbox = dev_get_priv(dev); + + mbox->tx_base = dev_read_addr_index_ptr(dev, 0); + if (!mbox->tx_base) + return -ENODEV; + + return 0; +} + +static const struct udevice_id mfis_mbox_of_match[] = { + { .compatible = "renesas,mfis-mbox", }, + {}, +}; + +U_BOOT_DRIVER(renesas_mfis) = { + .name = "renesas-mfis", + .id = UCLASS_MAILBOX, + .of_match = mfis_mbox_of_match, + .probe = mfis_mbox_probe, + .priv_auto = sizeof(struct mfis_priv), + .ops = &mfis_mbox_ops, +}; -- cgit v1.3.1 From e84a0bbefe19496b31b21c74133eedeefd1cc11c Mon Sep 17 00:00:00 2001 From: Hai Pham Date: Tue, 2 Dec 2025 19:34:14 +0100 Subject: arm64: renesas: Add Renesas R-Car Gen5 infrastructure Add initial changes to support Renesas R-Car Gen5 SoC. Introduce Kconfig entries, architecture headers and PRR IDs for Renesas R-Car Gen5 and R-Car X5H R8A78000 SoC. Add Makefile change to produce u-boot-elf.srec with correct offset for installation tooling. Update MAINTAINERS entry to cover both r8a77nnn and r8a78nnn . Signed-off-by: Hai Pham Signed-off-by: Marek Vasut --- Makefile | 9 +++++ arch/arm/mach-renesas/Kconfig | 5 +++ arch/arm/mach-renesas/Kconfig.64 | 1 + arch/arm/mach-renesas/Kconfig.rcar5 | 12 ++++++ arch/arm/mach-renesas/Makefile | 1 + arch/arm/mach-renesas/cpu_info-rcar.c | 8 +++- arch/arm/mach-renesas/cpu_info.c | 1 + .../arm/mach-renesas/include/mach/rcar-gen5-base.h | 44 ++++++++++++++++++++++ arch/arm/mach-renesas/include/mach/renesas.h | 3 ++ board/renesas/MAINTAINERS | 2 +- 10 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-renesas/Kconfig.rcar5 create mode 100644 arch/arm/mach-renesas/include/mach/rcar-gen5-base.h diff --git a/Makefile b/Makefile index 375af33e5e7..1a613e70b27 100644 --- a/Makefile +++ b/Makefile @@ -1499,6 +1499,15 @@ ifeq ($(CONFIG_POSITION_INDEPENDENT)$(CONFIG_RCAR_GEN3),yy) OBJCOPYFLAGS_u-boot-elf.srec += --change-addresses=0x50000000 endif +ifeq ($(CONFIG_POSITION_INDEPENDENT)$(CONFIG_RCAR_GEN5),yy) +# The flash_writer tool and previous recovery tools +# require the SREC load address to be 0x8e30_0000 . +# The PIE U-Boot build sets the address to 0x0, so +# override the address back to make u-boot-elf.srec +# compatible with the recovery tools. +OBJCOPYFLAGS_u-boot-elf.srec += --change-addresses=0x8e300000 +endif + u-boot-elf.srec: u-boot.elf FORCE $(call if_changed,zobjcopy) diff --git a/arch/arm/mach-renesas/Kconfig b/arch/arm/mach-renesas/Kconfig index 8f4fba4615c..fa4e312a4dd 100644 --- a/arch/arm/mach-renesas/Kconfig +++ b/arch/arm/mach-renesas/Kconfig @@ -46,6 +46,11 @@ config RCAR_GEN4 select RCAR_64 select PINCTRL_PFC +config RCAR_GEN5 + bool "Renesas ARM SoCs R-Car Gen5 (64bit)" + select RCAR_64 + select PINCTRL_PFC + config RZA1 prompt "Renesas ARM SoCs RZ/A1 (32bit)" select CPU_V7A diff --git a/arch/arm/mach-renesas/Kconfig.64 b/arch/arm/mach-renesas/Kconfig.64 index b5067d0a8f0..1b1ed88339b 100644 --- a/arch/arm/mach-renesas/Kconfig.64 +++ b/arch/arm/mach-renesas/Kconfig.64 @@ -8,5 +8,6 @@ config OF_LIBFDT_OVERLAY source "arch/arm/mach-renesas/Kconfig.rcar3" source "arch/arm/mach-renesas/Kconfig.rcar4" +source "arch/arm/mach-renesas/Kconfig.rcar5" endif diff --git a/arch/arm/mach-renesas/Kconfig.rcar5 b/arch/arm/mach-renesas/Kconfig.rcar5 new file mode 100644 index 00000000000..34c0ae8772b --- /dev/null +++ b/arch/arm/mach-renesas/Kconfig.rcar5 @@ -0,0 +1,12 @@ +if RCAR_GEN5 + +menu "Select Target SoC" + +config R8A78000 + bool "Renesas SoC R8A78000" + select GICV3 + imply PINCTRL_PFC_R8A78000 + +endmenu + +endif diff --git a/arch/arm/mach-renesas/Makefile b/arch/arm/mach-renesas/Makefile index 9165ceab4a3..c0454fffa48 100644 --- a/arch/arm/mach-renesas/Makefile +++ b/arch/arm/mach-renesas/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_RCAR_GEN2) += lowlevel_init_ca15.o cpu_info-rcar.o obj-$(CONFIG_RCAR_64) += lowlevel_init_gen3.o obj-$(CONFIG_RCAR_GEN3) += cpu_info-rcar.o memmap-gen3.o obj-$(CONFIG_RCAR_GEN4) += cpu_info-rcar.o memmap-gen3.o +obj-$(CONFIG_RCAR_GEN5) += cpu_info-rcar.o memmap-gen3.o obj-$(CONFIG_RZ_G2) += cpu_info-rzg.o obj-$(CONFIG_RZG2L) += cpu_info-rzg2l.o memmap-rzg2l.o diff --git a/arch/arm/mach-renesas/cpu_info-rcar.c b/arch/arm/mach-renesas/cpu_info-rcar.c index 74140fd38ab..a6e0b739e55 100644 --- a/arch/arm/mach-renesas/cpu_info-rcar.c +++ b/arch/arm/mach-renesas/cpu_info-rcar.c @@ -15,8 +15,12 @@ static u32 renesas_get_prr(void) { - if (IS_ENABLED(CONFIG_RCAR_64)) - return readl(0xFFF00044); + if (IS_ENABLED(CONFIG_RCAR_64)) { + if (IS_ENABLED(CONFIG_RCAR_GEN5)) + return readl(0x189E0044); + else + return readl(0xFFF00044); + } return readl(0xFF000044); } diff --git a/arch/arm/mach-renesas/cpu_info.c b/arch/arm/mach-renesas/cpu_info.c index 2f9a4374a96..f040d732a51 100644 --- a/arch/arm/mach-renesas/cpu_info.c +++ b/arch/arm/mach-renesas/cpu_info.c @@ -72,6 +72,7 @@ static const struct { { RENESAS_CPU_TYPE_R8A779F0, "R8A779F0" }, { RENESAS_CPU_TYPE_R8A779G0, "R8A779G0" }, { RENESAS_CPU_TYPE_R8A779H0, "R8A779H0" }, + { RMOBILE_CPU_TYPE_R8A78000, "R8A78000" }, { 0x0, "CPU" }, }; diff --git a/arch/arm/mach-renesas/include/mach/rcar-gen5-base.h b/arch/arm/mach-renesas/include/mach/rcar-gen5-base.h new file mode 100644 index 00000000000..f9af3ef885a --- /dev/null +++ b/arch/arm/mach-renesas/include/mach/rcar-gen5-base.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +#ifndef __ASM_ARCH_RCAR_GEN5_BASE_H +#define __ASM_ARCH_RCAR_GEN5_BASE_H + +/* + * R-Car (R8A78000) I/O Addresses + */ +#define TMU_BASE 0x1C030000 + +/* Arm Generic Timer */ +#define CNTCR_BASE 0x1C000FFF /* Region 0 */ +#define CNTFID0 (CNTCR_BASE + 0x020) +#define CNTCR_EN BIT(0) + +/* Reset */ +#define RST_BASE 0xC1320000 /* Domain0 */ +#define RST_SWSRES1A (RST_BASE + 0x410) +#define RST_WDTRSTCR (RST_BASE + 0x420) +#define RST_RWDT_RSTMSK BIT(0) +#define RST_WWDT_RSTMSK BIT(2) +#define RST_RESKCPROT0 (RST_BASE + 0x4F0) +#define RST_KCPROT_DIS 0xA5A5A501 + +/* GICv4 */ +/* Distributor Registers */ +#define GICD_BASE 0x38000000 +#define GICR_BASE (GICR_LPI_BASE) + +/* ReDistributor Registers for Control and Physical LPIs */ +#define GICR_LPI_BASE 0x38080000 +#define GICR_WAKER 0x0014 +#define GICR_PWRR 0x0024 +#define GICR_LPI_WAKER (GICR_LPI_BASE + GICR_WAKER) +#define GICR_LPI_PWRR (GICR_LPI_BASE + GICR_PWRR) + +/* ReDistributor Registers for SGIs and PPIs */ +#define GICR_SGI_BASE 0x38090000 +#define GICR_IGROUPR0 0x0080 + +#endif /* __ASM_ARCH_RCAR_GEN5_BASE_H */ diff --git a/arch/arm/mach-renesas/include/mach/renesas.h b/arch/arm/mach-renesas/include/mach/renesas.h index c69c764adb8..deaeffedef9 100644 --- a/arch/arm/mach-renesas/include/mach/renesas.h +++ b/arch/arm/mach-renesas/include/mach/renesas.h @@ -16,6 +16,8 @@ #include #elif defined(CONFIG_RCAR_GEN4) #include +#elif defined(CONFIG_RCAR_GEN5) +#include #elif defined(CONFIG_R7S72100) #elif defined(CONFIG_RZG2L) #include @@ -42,6 +44,7 @@ #define RENESAS_CPU_TYPE_R8A779F0 0x5A #define RENESAS_CPU_TYPE_R8A779G0 0x5C #define RENESAS_CPU_TYPE_R8A779H0 0x5D +#define RMOBILE_CPU_TYPE_R8A78000 0x60 #define RENESAS_CPU_TYPE_R9A07G044L 0x9A070440 #ifndef __ASSEMBLY__ diff --git a/board/renesas/MAINTAINERS b/board/renesas/MAINTAINERS index 13551cdd2b4..8571bb02576 100644 --- a/board/renesas/MAINTAINERS +++ b/board/renesas/MAINTAINERS @@ -6,7 +6,7 @@ N: grpeach N: r2dplus N: r7s72100 N: r8a66597 -N: r8a77 +N: r8a7[78] N: r9a0[0-9]g N: rcar N: renesas -- cgit v1.3.1 From b546189a4b515ba5aaf542558e9778d7d2a05b4e Mon Sep 17 00:00:00 2001 From: Hai Pham Date: Tue, 2 Dec 2025 19:34:15 +0100 Subject: arm64: dts: renesas: Add Renesas R-Car X5H R8A78000 SoC DTs Add initial device trees for Renesas R-Car X5H R8A78000 SoC. Include very basic clock, reset, power domain headers which are used to control supported peripherals via SCMI / SCP. The headers are currently kept limited to avoid possible ABI break. A lot of clock are still stubbed via fixed-clock, this is going to be gradually removed over time, as more of the platform is upstreamed. Signed-off-by: Hai Pham Signed-off-by: Khanh Le Signed-off-by: Marek Vasut --- arch/arm/dts/r8a78000-u-boot.dtsi | 139 +++ arch/arm/dts/r8a78000.dtsi | 1164 +++++++++++++++++++++++ include/dt-bindings/clock/r8a78000-clock-scmi.h | 46 + include/dt-bindings/power/r8a78000-power-scmi.h | 25 + include/dt-bindings/reset/r8a78000-reset-scmi.h | 33 + 5 files changed, 1407 insertions(+) create mode 100644 arch/arm/dts/r8a78000-u-boot.dtsi create mode 100644 arch/arm/dts/r8a78000.dtsi create mode 100644 include/dt-bindings/clock/r8a78000-clock-scmi.h create mode 100644 include/dt-bindings/power/r8a78000-power-scmi.h create mode 100644 include/dt-bindings/reset/r8a78000-reset-scmi.h diff --git a/arch/arm/dts/r8a78000-u-boot.dtsi b/arch/arm/dts/r8a78000-u-boot.dtsi new file mode 100644 index 00000000000..1bc73252430 --- /dev/null +++ b/arch/arm/dts/r8a78000-u-boot.dtsi @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Source extras for U-Boot on R-Car R8A78000 SoC + * + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +/ { + soc { + bootph-all; + }; + + /* Placeholder clock until the clock provider is in place */ + clk_stub_gpio: clk-stub-gpio { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + }; + + clk_stub_i2c0: clk-stub-i2c0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <150000000>; + }; + + clk_stub_i2c1: clk-stub-i2c1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <133333333>; + }; + + clk_stub_mmc: clk-stub-mmc { + compatible = "renesas,compound-clock"; + #clock-cells = <0>; + clocks = <&scmi_clk SCP_CLOCK_ID_MDLC_SDHI0>, + <&scmi_clk 1691>; + clock-names = "mdlc", "per"; + }; +}; + +&cpg { + bootph-all; +}; + +&extal_clk { + bootph-all; +}; + +&extalr_clk { + bootph-all; +}; + +&gpio0 { + clocks = <&clk_stub_gpio>; +}; + +&gpio1 { + clocks = <&clk_stub_gpio>; +}; + +&gpio2 { + clocks = <&clk_stub_gpio>; +}; + +&gpio3 { + clocks = <&clk_stub_gpio>; +}; + +&gpio4 { + clocks = <&clk_stub_gpio>; +}; + +&gpio5 { + clocks = <&clk_stub_gpio>; +}; + +&gpio6 { + clocks = <&clk_stub_gpio>; +}; + +&gpio7 { + clocks = <&clk_stub_gpio>; +}; + +&gpio8 { + clocks = <&clk_stub_gpio>; +}; + +&gpio9 { + clocks = <&clk_stub_gpio>; +}; + +&gpio10 { + clocks = <&clk_stub_gpio>; +}; + +&i2c0 { + clocks = <&clk_stub_i2c0>; +}; + +&i2c1 { + clocks = <&clk_stub_i2c1>; +}; + +&i2c2 { + clocks = <&clk_stub_i2c1>; +}; + +&i2c3 { + clocks = <&clk_stub_i2c1>; +}; + +&i2c4 { + clocks = <&clk_stub_i2c1>; +}; + +&i2c5 { + clocks = <&clk_stub_i2c1>; +}; + +&i2c6 { + clocks = <&clk_stub_i2c1>; +}; + +&i2c7 { + clocks = <&clk_stub_i2c1>; +}; + +&i2c8 { + clocks = <&clk_stub_i2c1>; +}; + +&mmc0 { + clocks = <&clk_stub_mmc>; +}; + +&prr { + bootph-all; +}; diff --git a/arch/arm/dts/r8a78000.dtsi b/arch/arm/dts/r8a78000.dtsi new file mode 100644 index 00000000000..0d0c24503e2 --- /dev/null +++ b/arch/arm/dts/r8a78000.dtsi @@ -0,0 +1,1164 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Source for the R-Car X5H (R8A78000) SoC + * + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +#include +#include +#include +#include + +/ { + compatible = "renesas,r8a78000"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&a720_0>; + }; + core1 { + cpu = <&a720_1>; + }; + core2 { + cpu = <&a720_2>; + }; + core3 { + cpu = <&a720_3>; + }; + }; + + cluster1 { + core0 { + cpu = <&a720_4>; + }; + core1 { + cpu = <&a720_5>; + }; + core2 { + cpu = <&a720_6>; + }; + core3 { + cpu = <&a720_7>; + }; + }; + + cluster2 { + core0 { + cpu = <&a720_8>; + }; + core1 { + cpu = <&a720_9>; + }; + core2 { + cpu = <&a720_10>; + }; + core3 { + cpu = <&a720_11>; + }; + }; + + cluster3 { + core0 { + cpu = <&a720_12>; + }; + core1 { + cpu = <&a720_13>; + }; + core2 { + cpu = <&a720_14>; + }; + core3 { + cpu = <&a720_15>; + }; + }; + + cluster4 { + core0 { + cpu = <&a720_16>; + }; + core1 { + cpu = <&a720_17>; + }; + core2 { + cpu = <&a720_18>; + }; + core3 { + cpu = <&a720_19>; + }; + }; + + cluster5 { + core0 { + cpu = <&a720_20>; + }; + core1 { + cpu = <&a720_21>; + }; + core2 { + cpu = <&a720_22>; + }; + core3 { + cpu = <&a720_23>; + }; + }; + + cluster6 { + core0 { + cpu = <&a720_24>; + }; + core1 { + cpu = <&a720_25>; + }; + core2 { + cpu = <&a720_26>; + }; + core3 { + cpu = <&a720_27>; + }; + }; + + cluster7 { + core0 { + cpu = <&a720_28>; + }; + core1 { + cpu = <&a720_29>; + }; + core2 { + cpu = <&a720_30>; + }; + core3 { + cpu = <&a720_31>; + }; + }; + }; + + a720_0: cpu@0 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x0>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_0>; + }; + + a720_1: cpu@100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_1>; + }; + + a720_2: cpu@200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_2>; + }; + + a720_3: cpu@300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_3>; + }; + + a720_4: cpu@10000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x10000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_4>; + }; + + a720_5: cpu@10100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x10100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_5>; + }; + + a720_6: cpu@10200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x10200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_6>; + }; + + a720_7: cpu@10300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x10300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_7>; + }; + + a720_8: cpu@20000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x20000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_8>; + }; + + a720_9: cpu@20100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x20100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_9>; + }; + + a720_10: cpu@20200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x20200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_10>; + }; + + a720_11: cpu@20300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x20300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_11>; + }; + + a720_12: cpu@30000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x30000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_12>; + }; + + a720_13: cpu@30100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x30100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_13>; + }; + + a720_14: cpu@30200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x30200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_14>; + }; + + a720_15: cpu@30300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x30300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_15>; + }; + + a720_16: cpu@40000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x40000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_16>; + }; + + a720_17: cpu@40100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x40100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_17>; + }; + + a720_18: cpu@40200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x40200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_18>; + }; + + a720_19: cpu@40300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x40300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_19>; + }; + + a720_20: cpu@50000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x50000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_20>; + }; + + a720_21: cpu@50100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x50100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_21>; + }; + + a720_22: cpu@50200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x50200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_22>; + }; + + a720_23: cpu@50300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x50300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_23>; + }; + + a720_24: cpu@60000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x60000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_24>; + }; + + a720_25: cpu@60100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x60100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_25>; + }; + + a720_26: cpu@60200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x60200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_26>; + }; + + a720_27: cpu@60300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x60300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_27>; + }; + + a720_28: cpu@70000 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x70000>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_28>; + }; + + a720_29: cpu@70100 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x70100>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_29>; + }; + + a720_30: cpu@70200 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x70200>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_30>; + }; + + a720_31: cpu@70300 { + compatible = "arm,cortex-a720ae"; + reg = <0x0 0x70300>; + device_type = "cpu"; + next-level-cache = <&L2_CA720_31>; + }; + + L2_CA720_0: cache-controller-200 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_0>; + }; + + L2_CA720_1: cache-controller-201 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_0>; + }; + + L2_CA720_2: cache-controller-202 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_0>; + }; + + L2_CA720_3: cache-controller-203 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_0>; + }; + + L2_CA720_4: cache-controller-204 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_1>; + }; + + L2_CA720_5: cache-controller-205 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_1>; + }; + + L2_CA720_6: cache-controller-206 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_1>; + }; + + L2_CA720_7: cache-controller-207 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_1>; + }; + + L2_CA720_8: cache-controller-208 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_2>; + }; + + L2_CA720_9: cache-controller-209 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_2>; + }; + + L2_CA720_10: cache-controller-210 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_2>; + }; + + L2_CA720_11: cache-controller-211 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_2>; + }; + + L2_CA720_12: cache-controller-212 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_3>; + }; + + L2_CA720_13: cache-controller-213 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_3>; + }; + + L2_CA720_14: cache-controller-214 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_3>; + }; + + L2_CA720_15: cache-controller-215 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_3>; + }; + + L2_CA720_16: cache-controller-216 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_4>; + }; + + L2_CA720_17: cache-controller-217 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_4>; + }; + + L2_CA720_18: cache-controller-218 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_4>; + }; + + L2_CA720_19: cache-controller-219 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_4>; + }; + + L2_CA720_20: cache-controller-220 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_5>; + }; + + L2_CA720_21: cache-controller-221 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_5>; + }; + + L2_CA720_22: cache-controller-222 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_5>; + }; + + L2_CA720_23: cache-controller-223 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_5>; + }; + + L2_CA720_24: cache-controller-224 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_6>; + }; + + L2_CA720_25: cache-controller-225 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_6>; + }; + + L2_CA720_26: cache-controller-226 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_6>; + }; + + L2_CA720_27: cache-controller-227 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_6>; + }; + + L2_CA720_28: cache-controller-228 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_7>; + }; + + L2_CA720_29: cache-controller-229 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_7>; + }; + + L2_CA720_30: cache-controller-230 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_7>; + }; + + L2_CA720_31: cache-controller-231 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + next-level-cache = <&L3_CA720_7>; + }; + + L3_CA720_0: cache-controller-30 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_1: cache-controller-31 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_2: cache-controller-32 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_3: cache-controller-33 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_4: cache-controller-34 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_5: cache-controller-35 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_6: cache-controller-36 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + + L3_CA720_7: cache-controller-37 { + compatible = "cache"; + cache-unified; + cache-level = <3>; + }; + }; + + /* + * In the early phase, there is no clock control support, + * so assume that the clocks are enabled by default. + * Therefore, dummy clocks are used. + */ + dummy_clk_sgasyncd16: dummy-clk-sgasyncd16 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <66666000>; + }; + + dummy_clk_sgasyncd4: dummy-clk-sgasyncd4 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <266660000>; + }; + + extal_clk: extal-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* clock-frequency must be set on board */ + }; + + extalr_clk: extalr-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* clock-frequency must be set on board */ + }; + + firmware { + scmi { + compatible = "arm,scmi"; + arm,poll-transport; + mbox-names = "tx", "rx"; + mboxes = <&mailbox 0>, <&mailbox 1>; + shmem = <&cpu_scp_lpri0>, <&cpu_scp_hpri0>; + #address-cells = <1>; + #size-cells = <0>; + + scmi_devpd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi_clk: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; + + scmi_reset: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + }; + + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2"; + method = "smc"; + }; + + /* External SCIF clock - to be overridden by boards that provide it */ + scif_clk: scif-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; /* optional */ + }; + + soc: soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + mailbox: mfis_mbox@18842000 { + compatible = "renesas,mfis-mbox"; + #mbox-cells = <1>; + reg = <0 0x18842004 0 0x8>; + interrupts = ; + }; + + prr: chipid@189e0044 { + compatible = "renesas,prr"; + reg = <0 0x189e0044 0 4>; + }; + + /* Application Processors manage View-1 of a GIC-720AE */ + gic: interrupt-controller@39000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0 0x39000000 0 0x10000>, + <0 0x39080000 0 0x800000>; + interrupts = ; + }; + + pfc: pinctrl@c0400000 { + compatible = "renesas,pfc-r8a78000"; + reg = <0 0xc1080000 0 0x104>, <0 0xc1080800 0 0x104>, + <0 0xc1081000 0 0x104>, <0 0xc0800000 0 0x104>, + <0 0xc0800800 0 0x104>, <0 0xc0400000 0 0x104>, + <0 0xc0400800 0 0x104>, <0 0xc0401000 0 0x104>, + <0 0xc0401800 0 0x104>, <0 0xc9b00000 0 0x104>, + <0 0xc9b00800 0 0x104>; + }; + + scif0: serial@c0700000 { + compatible = "renesas,scif-r8a78000", + "renesas,rcar-gen5-scif", "renesas,scif"; + reg = <0 0xc0700000 0 0x40>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + scif1: serial@c0704000 { + compatible = "renesas,scif-r8a78000", + "renesas,rcar-gen5-scif", "renesas,scif"; + reg = <0 0xc0704000 0 0x40>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "okay"; + }; + + scif3: serial@c0708000 { + compatible = "renesas,scif-r8a78000", + "renesas,rcar-gen5-scif", "renesas,scif"; + reg = <0 0xc0708000 0 0x40>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + scif4: serial@c070c000 { + compatible = "renesas,scif-r8a78000", + "renesas,rcar-gen5-scif", "renesas,scif"; + reg = <0 0xc070c000 0 0x40>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + mmc0: mmc@c0880000 { + compatible = "renesas,rcar-gen5-sdhi"; + reg = <0 0xc0880000 0 0x2000>; + clock-names = "core"; + max-frequency = <200000000>; + status = "disabled"; + }; + + ufs0: ufs@c0a80000 { + compatible = "renesas,r8a78000-ufs"; + reg = <0 0xc0a80000 0 0x1100>, <0 0xc0a00000 0 0x40000>; + reg-names = "hcr", "phy"; + interrupts = ; + power-domains = <&scmi_devpd X5H_POWER_DOMAIN_ID_UFS0>; + clocks = <&scmi_clk SCP_CLOCK_ID_MDLC_UFS0>; + resets = <&scmi_reset SCP_RESET_DOMAIN_ID_UFS0>; + freq-table-hz = <38400000 38400000>; + status = "disabled"; + }; + + ufs1: ufs@c0a90000 { + compatible = "renesas,r8a78000-ufs"; + reg = <0 0xc0a90000 0 0x1100>, <0 0xc0a40000 0 0x40000>; + reg-names = "hcr", "phy"; + interrupts = ; + power-domains = <&scmi_devpd X5H_POWER_DOMAIN_ID_UFS1>; + clocks = <&scmi_clk SCP_CLOCK_ID_MDLC_UFS1>; + resets = <&scmi_reset SCP_RESET_DOMAIN_ID_UFS1>; + freq-table-hz = <38400000 38400000>; + status = "disabled"; + }; + + scp: sram@c1000000 { + compatible = "arm,rcar-sram-ns", "mmio-sram"; + reg = <0x0 0xc1000000 0x0 0x80000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x0 0xc1000000 0x80000>; + + cpu_scp_lpri0: scp-shmem@60000 { + compatible = "arm,rcar-scp-shmem", "arm,scmi-shmem"; + reg = <0x61200 0x0100>; + }; + + cpu_scp_hpri0: scp-shmem@60300 { + compatible = "arm,rcar-scp-shmem", "arm,scmi-shmem"; + reg = <0x61300 0x100>; + }; + }; + + cpg: clock-controller@c64f0000 { + compatible = "renesas,r8a78000-cpg-mssr"; + reg = <0 0xc64f0000 0 0x4000>; + clocks = <&extal_clk>, <&extalr_clk>; + clock-names = "extal", "extalr"; + #clock-cells = <2>; + #power-domain-cells = <0>; + #reset-cells = <1>; + }; + + hscif0: serial@c0710000 { + compatible = "renesas,hscif-r8a78000", + "renesas,rcar-gen5-hscif", "renesas,hscif"; + reg = <0 0xc0710000 0 0x60>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + hscif1: serial@c0714000 { + compatible = "renesas,hscif-r8a78000", + "renesas,rcar-gen5-hscif", "renesas,hscif"; + reg = <0 0xc0714000 0 0x60>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + hscif2: serial@c0718000 { + compatible = "renesas,hscif-r8a78000", + "renesas,rcar-gen5-hscif", "renesas,hscif"; + reg = <0 0xc0718000 0 0x60>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + hscif3: serial@c071c000 { + compatible = "renesas,hscif-r8a78000", + "renesas,rcar-gen5-hscif", "renesas,hscif"; + reg = <0 0xc071c000 0 0x60>; + interrupts = ; + clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + status = "disabled"; + }; + + i2c0: i2c@c11d0000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc11d0000 0 0x40>; + i2c-scl-internal-delay-ns = <110>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@c06c0000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06c0000 0 0x40>; + i2c-scl-internal-delay-ns = <110>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@c06c8000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06c8000 0 0x40>; + i2c-scl-internal-delay-ns = <110>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c3: i2c@c06d0000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06d0000 0 0x40>; + i2c-scl-internal-delay-ns = <110>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c4: i2c@c06d8000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06d8000 0 0x40>; + i2c-scl-internal-delay-ns = <110>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c5: i2c@c06e0000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06e0000 0 0x40>; + i2c-scl-internal-delay-ns = <110>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c6: i2c@c06e8000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06e8000 0 0x40>; + i2c-scl-internal-delay-ns = <110>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c7: i2c@c06f0000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06f0000 0 0x40>; + i2c-scl-internal-delay-ns = <110>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c8: i2c@c06f8000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06f8000 0 0x40>; + i2c-scl-internal-delay-ns = <110>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + gpio0: gpio@c1080110 { + compatible = "renesas,gpio-r8a78000", + "renesas,rcar-gen5-gpio"; + reg = <0 0xc1080110 0 0xc0>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 0 28>; + }; + + gpio1: gpio@c1080910 { + compatible = "renesas,gpio-r8a78000", + "renesas,rcar-gen5-gpio"; + reg = <0 0xc1080910 0 0xc0>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 32 22>; + }; + + gpio2: gpio@c1081110 { + compatible = "renesas,gpio-r8a78000", + "renesas,rcar-gen5-gpio"; + reg = <0 0xc1081110 0 0xc0>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 64 29>; + }; + + gpio3: gpio@c0800110 { + compatible = "renesas,gpio-r8a78000", + "renesas,rcar-gen5-gpio"; + reg = <0 0xc0800110 0 0xc0>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 96 17>; + }; + + gpio4: gpio@c0800910 { + compatible = "renesas,gpio-r8a78000", + "renesas,rcar-gen5-gpio"; + reg = <0 0xc0800910 0 0xc0>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 128 16>; + }; + + gpio5: gpio@c0400110 { + compatible = "renesas,gpio-r8a78000", + "renesas,rcar-gen5-gpio"; + reg = <0 0xc0400110 0 0xc0>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 160 23>; + }; + + gpio6: gpio@c0400910 { + compatible = "renesas,gpio-r8a78000", + "renesas,rcar-gen5-gpio"; + reg = <0 0xc0400910 0 0xc0>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 192 31>; + }; + + gpio7: gpio@c0401110 { + compatible = "renesas,gpio-r8a78000", + "renesas,rcar-gen5-gpio"; + reg = <0 0xc0401110 0 0xc0>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 224 31>; + }; + + gpio8: gpio@c0401910 { + compatible = "renesas,gpio-r8a78000", + "renesas,rcar-gen5-gpio"; + reg = <0 0xc0401910 0 0xc0>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 256 32>; + gpio-reserved-ranges = <16 10>; + }; + + gpio9: gpio@c9b00110 { + compatible = "renesas,gpio-r8a78000", + "renesas,rcar-gen5-gpio"; + reg = <0 0xc9b00110 0 0xc0>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 288 17>; + }; + + gpio10: gpio@c9b00910 { + compatible = "renesas,gpio-r8a78000", + "renesas,rcar-gen5-gpio"; + reg = <0 0xc9b00910 0 0xc0>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 320 14>; + }; + + mp_phy: mp_phy@c9a00000 { + compatible = "renesas,r8a78000-multi-protocol-phy"; + reg = <0 0xc9a00000 0 0x100000>; + #phy-cells = <2>; + clocks = <&scmi_clk SCP_CLOCK_ID_MDLC_MPPHY01>, + <&scmi_clk SCP_CLOCK_ID_MDLC_MPPHY11>, + <&scmi_clk SCP_CLOCK_ID_MDLC_MPPHY21>, + <&scmi_clk SCP_CLOCK_ID_MDLC_MPPHY31>, + <&scmi_clk SCP_CLOCK_ID_MDLC_MPPHY02>; + clock-names = "mpphy01", "mpphy11", "mpphy21", + "mpphy31", "mpphy02"; + power-domains = <&scmi_devpd X5H_POWER_DOMAIN_ID_MPP0>, + <&scmi_devpd X5H_POWER_DOMAIN_ID_MPP1>, + <&scmi_devpd X5H_POWER_DOMAIN_ID_MPP2>, + <&scmi_devpd X5H_POWER_DOMAIN_ID_MPP3>; + resets = <&scmi_reset SCP_RESET_DOMAIN_ID_MPPHY01>, + <&scmi_reset SCP_RESET_DOMAIN_ID_MPPHY11>, + <&scmi_reset SCP_RESET_DOMAIN_ID_MPPHY21>, + <&scmi_reset SCP_RESET_DOMAIN_ID_MPPHY31>, + <&scmi_reset SCP_RESET_DOMAIN_ID_MPPHY02>; + status = "disabled"; + }; + + rswitch3: ethernet@c9bc0000 { + compatible = "renesas,r8a78000-ether-switch3", + "renesas,etherswitch"; + reg = <0 0xc9bc0000 0 0x40000>, <0 0xc9b80000 0 0x240000>; + reg-names = "base", "secure_base"; + power-domains = <&scmi_devpd X5H_POWER_DOMAIN_ID_RSW>; + clocks = <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3>, + <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSN>, + <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3AES>, + <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES0>, + <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES1>, + <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES2>, + <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES3>, + <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES4>, + <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES5>, + <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES6>, + <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES7>, + <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3MFWD>; + clock-names = "rsw3", "rsw3tsn", "rsw3aes", + "rsw3tsntes0", "rsw3tsntes1", "rsw3tsntes2", + "rsw3tsntes3", "rsw3tsntes4", "rsw3tsntes5", + "rsw3tsntes6", "rsw3tsntes7", "rsw3mfwd"; + status = "disabled"; + }; + + eth_pcs: phy@c9c50000 { + compatible = "renesas,r8a78000-ether-pcs"; + reg = <0 0xc9c50000 0 0x4000>; + #phy-cells = <1>; + clocks = <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS0>, + <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS1>, + <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS2>, + <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS3>, + <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS4>, + <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS5>, + <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS6>, + <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS7>; + clock-names = "xpcs0", "xpcs1", "xpcs2", "xpcs3", + "xpcs4", "xpcs5", "xpcs6", "xpcs7"; + resets = <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS0>, + <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS1>, + <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS2>, + <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS3>, + <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS4>, + <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS5>, + <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS6>, + <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS7>; + reset-names = "xpcs0", "xpcs1", "xpcs2", "xpcs3", + "xpcs4", "xpcs5", "xpcs6", "xpcs7"; + status = "disabled"; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + , + ; + interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt"; + }; +}; diff --git a/include/dt-bindings/clock/r8a78000-clock-scmi.h b/include/dt-bindings/clock/r8a78000-clock-scmi.h new file mode 100644 index 00000000000..455402ee8cc --- /dev/null +++ b/include/dt-bindings/clock/r8a78000-clock-scmi.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2025 Renesas Electronics Corp. + * + * IDs match SCP 4.27 + */ + +#ifndef __DT_BINDINGS_R8A78000_SCMI_CLOCK_H__ +#define __DT_BINDINGS_R8A78000_SCMI_CLOCK_H__ + +/* + * These definition indices match the Clock ID defined by SCP FW 4.27. + */ + +#define SCP_CLOCK_ID_MDLC_UFS0 202 +#define SCP_CLOCK_ID_MDLC_UFS1 203 +#define SCP_CLOCK_ID_MDLC_SDHI0 204 + +#define SCP_CLOCK_ID_MDLC_XPCS0 316 +#define SCP_CLOCK_ID_MDLC_XPCS1 317 +#define SCP_CLOCK_ID_MDLC_XPCS2 318 +#define SCP_CLOCK_ID_MDLC_XPCS3 319 +#define SCP_CLOCK_ID_MDLC_XPCS4 320 +#define SCP_CLOCK_ID_MDLC_XPCS5 321 +#define SCP_CLOCK_ID_MDLC_XPCS6 322 +#define SCP_CLOCK_ID_MDLC_XPCS7 323 +#define SCP_CLOCK_ID_MDLC_RSW3 324 +#define SCP_CLOCK_ID_MDLC_RSW3TSN 325 +#define SCP_CLOCK_ID_MDLC_RSW3AES 326 +#define SCP_CLOCK_ID_MDLC_RSW3TSNTES0 327 +#define SCP_CLOCK_ID_MDLC_RSW3TSNTES1 328 +#define SCP_CLOCK_ID_MDLC_RSW3TSNTES2 329 +#define SCP_CLOCK_ID_MDLC_RSW3TSNTES3 330 +#define SCP_CLOCK_ID_MDLC_RSW3TSNTES4 331 +#define SCP_CLOCK_ID_MDLC_RSW3TSNTES5 332 +#define SCP_CLOCK_ID_MDLC_RSW3TSNTES6 333 +#define SCP_CLOCK_ID_MDLC_RSW3TSNTES7 334 +#define SCP_CLOCK_ID_MDLC_RSW3MFWD 335 + +#define SCP_CLOCK_ID_MDLC_MPPHY01 344 +#define SCP_CLOCK_ID_MDLC_MPPHY11 345 +#define SCP_CLOCK_ID_MDLC_MPPHY21 346 +#define SCP_CLOCK_ID_MDLC_MPPHY31 347 +#define SCP_CLOCK_ID_MDLC_MPPHY02 348 + +#endif /* __DT_BINDINGS_R8A78000_SCMI_CLOCK_H__ */ diff --git a/include/dt-bindings/power/r8a78000-power-scmi.h b/include/dt-bindings/power/r8a78000-power-scmi.h new file mode 100644 index 00000000000..2f1cb8e909c --- /dev/null +++ b/include/dt-bindings/power/r8a78000-power-scmi.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2025 Renesas Electronics Corp. + * + * IDs match SCP 4.27 + */ + +#ifndef __DT_BINDINGS_R8A78000_SCMI_POWER_H__ +#define __DT_BINDINGS_R8A78000_SCMI_POWER_H__ + +/* + * These power domain indices match the Power Domain ID defined by SCP FW 4.27. + */ + +#define X5H_POWER_DOMAIN_ID_UFS0 12 +#define X5H_POWER_DOMAIN_ID_UFS1 13 + +#define X5H_POWER_DOMAIN_ID_RSW 15 + +#define X5H_POWER_DOMAIN_ID_MPP0 17 +#define X5H_POWER_DOMAIN_ID_MPP1 18 +#define X5H_POWER_DOMAIN_ID_MPP2 19 +#define X5H_POWER_DOMAIN_ID_MPP3 20 + +#endif /* __DT_BINDINGS_R8A78000_SCMI_POWER_H__ */ diff --git a/include/dt-bindings/reset/r8a78000-reset-scmi.h b/include/dt-bindings/reset/r8a78000-reset-scmi.h new file mode 100644 index 00000000000..e0d10caa589 --- /dev/null +++ b/include/dt-bindings/reset/r8a78000-reset-scmi.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2025 Renesas Electronics Corp. + * + * IDs match SCP 4.27 + */ + +#ifndef __DT_BINDINGS_R8A78000_SCMI_RESET_H__ +#define __DT_BINDINGS_R8A78000_SCMI_RESET_H__ + +/* + * These definition indices match the Reset ID defined by SCP FW 4.27. + */ + +#define SCP_RESET_DOMAIN_ID_UFS0 202 +#define SCP_RESET_DOMAIN_ID_UFS1 203 + +#define SCP_RESET_DOMAIN_ID_XPCS0 316 +#define SCP_RESET_DOMAIN_ID_XPCS1 317 +#define SCP_RESET_DOMAIN_ID_XPCS2 318 +#define SCP_RESET_DOMAIN_ID_XPCS3 319 +#define SCP_RESET_DOMAIN_ID_XPCS4 320 +#define SCP_RESET_DOMAIN_ID_XPCS5 321 +#define SCP_RESET_DOMAIN_ID_XPCS6 322 +#define SCP_RESET_DOMAIN_ID_XPCS7 323 + +#define SCP_RESET_DOMAIN_ID_MPPHY01 344 +#define SCP_RESET_DOMAIN_ID_MPPHY11 345 +#define SCP_RESET_DOMAIN_ID_MPPHY21 346 +#define SCP_RESET_DOMAIN_ID_MPPHY31 347 +#define SCP_RESET_DOMAIN_ID_MPPHY02 348 + +#endif /* __DT_BINDINGS_R8A78000_SCMI_RESET_H__ */ -- cgit v1.3.1 From cf71963778ee1c1ac4b86c78acae138591b4169c Mon Sep 17 00:00:00 2001 From: Hai Pham Date: Tue, 2 Dec 2025 19:34:16 +0100 Subject: arm64: dts: renesas: Add Renesas R-Car X5H R8A78000 Ironhide board code Add initial support for Renesas R-Car X5H R8A78000 Ironhide board. This consists mainly of DTs, Makefile and Kconfig entries and board specific configuration files. The DTs will be gradually switched over to Linux DTs via OF_UPSTREAM once Linux DTs become available upstream, as upstreaming progresses. Signed-off-by: Hai Pham Signed-off-by: Marek Vasut --- arch/arm/dts/Makefile | 7 + arch/arm/dts/r8a78000-ironhide-u-boot.dtsi | 8 + arch/arm/dts/r8a78000-ironhide.dts | 257 +++++++++++++++++++++++++++++ arch/arm/mach-renesas/Kconfig.rcar5 | 14 ++ board/renesas/common/Makefile | 4 + board/renesas/common/gen5-common.c | 75 +++++++++ board/renesas/ironhide/Kconfig | 15 ++ configs/r8a78000_ironhide_defconfig | 43 +++++ configs/renesas_rcar5.config | 23 +++ include/configs/ironhide.h | 11 ++ include/configs/rcar-gen5-common.h | 24 +++ 11 files changed, 481 insertions(+) create mode 100644 arch/arm/dts/r8a78000-ironhide-u-boot.dtsi create mode 100644 arch/arm/dts/r8a78000-ironhide.dts create mode 100644 board/renesas/common/gen5-common.c create mode 100644 board/renesas/ironhide/Kconfig create mode 100644 configs/r8a78000_ironhide_defconfig create mode 100644 configs/renesas_rcar5.config create mode 100644 include/configs/ironhide.h create mode 100644 include/configs/rcar-gen5-common.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 865ceb65f9a..fcad6fb2fc7 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -918,6 +918,13 @@ dtb-$(CONFIG_RZA1) += \ r7s72100-genmai.dtb \ r7s72100-gr-peach.dtb +dtb-$(CONFIG_RCAR_GEN5) += \ + r8a78000-ironhide.dtb + +ifdef CONFIG_RCAR_GEN5 +DTC_FLAGS += -R 4 -p 0x1000 +endif + dtb-$(CONFIG_TARGET_AT91SAM9261EK) += at91sam9261ek.dtb dtb-$(CONFIG_TARGET_PM9261) += at91sam9261ek.dtb diff --git a/arch/arm/dts/r8a78000-ironhide-u-boot.dtsi b/arch/arm/dts/r8a78000-ironhide-u-boot.dtsi new file mode 100644 index 00000000000..9c72f3e55f4 --- /dev/null +++ b/arch/arm/dts/r8a78000-ironhide-u-boot.dtsi @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Source extras for U-Boot for the Ironhide board + * + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +#include "r8a78000-u-boot.dtsi" diff --git a/arch/arm/dts/r8a78000-ironhide.dts b/arch/arm/dts/r8a78000-ironhide.dts new file mode 100644 index 00000000000..601f2740b54 --- /dev/null +++ b/arch/arm/dts/r8a78000-ironhide.dts @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Source for the Ironhide board + * + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +/dts-v1/; +#include "r8a78000.dtsi" +#include + +/ { + model = "Renesas Ironhide board based on r8a78000"; + compatible = "renesas,ironhide", "renesas,r8a78000"; + + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; + mmc0 = &mmc0; + serial0 = &hscif0; + }; + + chosen { + stdout-path = "serial0:1843200n8"; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0x0 0x40000000 0x0 0x80000000>; + }; + + memory@1080000000 { + device_type = "memory"; + reg = <0x10 0x80000000 0x0 0x80000000>; + }; + + memory@1200000000 { + device_type = "memory"; + reg = <0x12 0x00000000 0x1 0x00000000>; + }; + + memory@1400000000 { + device_type = "memory"; + reg = <0x14 0x00000000 0x1 0x00000000>; + }; + + memory@1600000000 { + device_type = "memory"; + reg = <0x16 0x00000000 0x1 0x00000000>; + }; + + memory@1800000000 { + device_type = "memory"; + reg = <0x18 0x00000000 0x1 0x00000000>; + }; + + memory@1a00000000 { + device_type = "memory"; + reg = <0x1a 0x00000000 0x1 0x00000000>; + }; + + memory@1c00000000 { + device_type = "memory"; + reg = <0x1c 0x00000000 0x1 0x00000000>; + }; + + memory@1e00000000 { + device_type = "memory"; + reg = <0x1e 0x00000000 0x1 0x00000000>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&extal_clk { + clock-frequency = <16666600>; +}; + +&extalr_clk { + clock-frequency = <32768>; +}; + +&hscif0 { + pinctrl-0 = <&hscif0_pins>; + pinctrl-names = "default"; + uart-has-rtscts; + status = "okay"; +}; + +&i2c0 { + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + clock-frequency = <400000>; + status = "okay"; + + eeprom@50 { + compatible = "rohm,br24g01", "atmel,24c01"; + reg = <0x50>; + pagesize = <8>; + }; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + clock-frequency = <400000>; + status = "okay"; +}; + +ð_pcs { + phys = <&mp_phy 2 1>; + status = "okay"; +}; + +&mmc0 { + pinctrl-0 = <&mmc0_pins>; + pinctrl-1 = <&mmc0_pins>; + pinctrl-names = "default", "state_uhs"; + + bus-width = <8>; + full-pwr-cycle-in-suspend; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + no-sd; + no-sdio; + non-removable; + + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_1p8v>; + + status = "okay"; +}; + +&ufs0 { + status = "okay"; +}; + +&ufs1 { + status = "okay"; +}; + +&mp_phy { + status = "okay"; +}; + +&pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + + eth25g2_pins: eth25g2 { + groups = "eth25g2_mdio", "eth25g2_link", "eth25g2_phyint"; + function = "eth25g2"; + drive-strength = <24>; + }; + + ethes0_pins: ethes0 { + groups = "ethes0_match", "ethes0_capture", "ethes0_pps"; + function = "ethes0"; + drive-strength = <24>; + }; + + hscif0_pins: hscif0 { + groups = "hscif0_data", "hscif0_ctrl"; + function = "hscif0"; + }; + + i2c0_pins: i2c0 { + groups = "i2c0"; + function = "i2c0"; + }; + + i2c1_pins: i2c1 { + groups = "i2c1"; + function = "i2c1"; + }; + + mmc0_pins: mmc0 { + groups = "mmc0_data8", "mmc0_ctrl", "mmc0_ds"; + function = "mmc0"; + drive-strength = <24>; + }; + + rsw3_pins: rsw3 { + groups = "rsw3_match", "rsw3_capture", "rsw3_pps"; + function = "rsw3"; + drive-strength = <24>; + }; + + scif_clk_pins: scif-clk { + groups = "scif_clk"; + function = "scif_clk"; + }; +}; + +&rswitch3 { + pinctrl-0 = <&rsw3_pins>, <ð25g2_pins>, <ðes0_pins>; + pinctrl-names = "default"; + status = "okay"; + + ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + + /* + * NOTE: Only port@4 is configured for R-Car X5H board. + * Other ports (0-3, 5-12) are currently unused or not + * connected. + */ + port@4 { + reg = <4>; + renesas,connect_to_xpcs; + phy-handle = <&dp83869_phy>; + phy-mode = "sgmii"; + phys = <ð_pcs 5>; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + dp83869_phy: ethernet-phy@2 { + reg = <2>; + ti,sgmii-interface; + ti,max-output-impedance; + ti,refclk-output-enable; + ti,clk-output-sel = ; + }; + }; + }; + }; +}; + +&scif_clk { + clock-frequency = <26000000>; +}; diff --git a/arch/arm/mach-renesas/Kconfig.rcar5 b/arch/arm/mach-renesas/Kconfig.rcar5 index 34c0ae8772b..528fc5aecc9 100644 --- a/arch/arm/mach-renesas/Kconfig.rcar5 +++ b/arch/arm/mach-renesas/Kconfig.rcar5 @@ -9,4 +9,18 @@ config R8A78000 endmenu +choice + prompt "Renesas ARM64 SoCs board select" + optional + +config TARGET_IRONHIDE + bool "Ironhide board" + imply R8A78000 + help + Support for Renesas R-Car Gen5 Ironhide platform + +endchoice + +source "board/renesas/ironhide/Kconfig" + endif diff --git a/board/renesas/common/Makefile b/board/renesas/common/Makefile index 1849c995aee..889de8ea9ac 100644 --- a/board/renesas/common/Makefile +++ b/board/renesas/common/Makefile @@ -43,6 +43,10 @@ else obj-y += gen4-common.o endif endif + +ifdef CONFIG_RCAR_GEN5 +obj-y += gen5-common.o +endif endif endif diff --git a/board/renesas/common/gen5-common.c b/board/renesas/common/gen5-common.c new file mode 100644 index 00000000000..a05a3e8abef --- /dev/null +++ b/board/renesas/common/gen5-common.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static void init_generic_timer(void) +{ + const u32 freq = CONFIG_SYS_CLK_FREQ; + + /* Update memory mapped and register based freqency */ + asm volatile ("msr cntfrq_el0, %0" :: "r" (freq)); + writel(freq, CNTFID0); + + /* Enable counter */ + setbits_le32(CNTCR_BASE, CNTCR_EN); +} + +static void init_gic_v3(void) +{ + /* GIC v3 power on */ + writel(BIT(1), GICR_LPI_PWRR); + + /* Wait till the WAKER_CA_BIT changes to 0 */ + clrbits_le32(GICR_LPI_WAKER, BIT(1)); + while (readl(GICR_LPI_WAKER) & BIT(2)) + ; + + writel(0xffffffff, GICR_SGI_BASE + GICR_IGROUPR0); +} + +void s_init(void) +{ + if (current_el() == 3) + init_generic_timer(); +} + +int board_early_init_f(void) +{ + return 0; +} + +int board_init(void) +{ + /* Allow WDT reset */ + writel(RST_KCPROT_DIS, RST_RESKCPROT0); + clrbits_le32(RST_WDTRSTCR, RST_WWDT_RSTMSK | RST_RWDT_RSTMSK); + + if (current_el() != 3) + return 0; + init_gic_v3(); + + return 0; +} + +void __weak reset_cpu(void) +{ + writel(RST_KCPROT_DIS, RST_RESKCPROT0); + writel(0x1, RST_SWSRES1A); +} + +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return 0; +} diff --git a/board/renesas/ironhide/Kconfig b/board/renesas/ironhide/Kconfig new file mode 100644 index 00000000000..34b596714f3 --- /dev/null +++ b/board/renesas/ironhide/Kconfig @@ -0,0 +1,15 @@ +if TARGET_IRONHIDE + +config SYS_SOC + default "renesas" + +config SYS_BOARD + default "ironhide" + +config SYS_VENDOR + default "renesas" + +config SYS_CONFIG_NAME + default "ironhide" + +endif diff --git a/configs/r8a78000_ironhide_defconfig b/configs/r8a78000_ironhide_defconfig new file mode 100644 index 00000000000..180704e75af --- /dev/null +++ b/configs/r8a78000_ironhide_defconfig @@ -0,0 +1,43 @@ +#include + +CONFIG_ARM=y +CONFIG_ARCH_RENESAS=y +CONFIG_RCAR_GEN5=y +CONFIG_TARGET_IRONHIDE=y + +# CONFIG_OF_UPSTREAM is not set +CONFIG_ARMV8_PSCI=y +CONFIG_ARM_SMCCC=y +CONFIG_BAUDRATE=1843200 +CONFIG_BOOTCOMMAND="setexpr dloadaddr ${loadaddr} + 0x200000 && setexpr dloadaddr ${dloadaddr} \\\\& 0xffc00000 && setexpr kloadaddr ${dloadaddr} + 0x200000 && tftp ${dloadaddr} r8a78000-ironhide.dtb && tftp ${kloadaddr} Image && booti ${kloadaddr} - ${dloadaddr}" +CONFIG_DEFAULT_DEVICE_TREE="r8a78000-ironhide" +CONFIG_CLK_CCF=y +CONFIG_CLK_COMPOSITE_CCF=y +CONFIG_CLK_SCMI=y +CONFIG_CMD_CLK=y +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_SCMI=y +CONFIG_CMD_UFS=y +CONFIG_DM_MAILBOX=y +CONFIG_DM_RESET=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_MMC_DEVICE_INDEX=0 +CONFIG_ENV_MMC_EMMC_HW_PARTITION=2 +CONFIG_ENV_OFFSET=0xFFFE0000 +CONFIG_ENV_SIZE=0x20000 +CONFIG_FIRMWARE=y +CONFIG_NR_DRAM_BANKS=16 +CONFIG_POWER_DOMAIN=y +CONFIG_RCAR_MFIS_MBOX=y +CONFIG_RESET_SCMI=y +CONFIG_SCMI_AGENT_MAILBOX=y +CONFIG_SCMI_FIRMWARE=y +CONFIG_SCMI_POWER_DOMAIN=y +CONFIG_SCSI=y +CONFIG_SYS_ALT_MEMTEST=y +CONFIG_SYS_BARGSIZE=2048 +CONFIG_SYS_BOOT_GET_CMDLINE=y +CONFIG_SYS_CBSIZE=2048 +CONFIG_SYS_CLK_FREQ=1066666667 +CONFIG_UFS=y +CONFIG_UFS_RENESAS_GEN5=y diff --git a/configs/renesas_rcar5.config b/configs/renesas_rcar5.config new file mode 100644 index 00000000000..fbf158dfdb3 --- /dev/null +++ b/configs/renesas_rcar5.config @@ -0,0 +1,23 @@ +#include + +CONFIG_ARCH_CPU_INIT=y +CONFIG_SYS_LOAD_ADDR=0x9E600000 +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_USE_BOOTARGS=y +CONFIG_USE_BOOTCOMMAND=y + +CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.0.1:/export/rfs ip=192.168.0.20" +CONFIG_CMD_MMC=y +CONFIG_DM_ETH_PHY=y +# CONFIG_MMC_HS200_SUPPORT is not set +# CONFIG_MMC_IO_VOLTAGE is not set +# CONFIG_MMC_UHS_SUPPORT is not set +CONFIG_PHY_R8A78000_ETHERNET_PCS=y +CONFIG_PHY_R8A78000_MP_PHY=y +CONFIG_PHY_TI_DP83869=y +# CONFIG_PSCI_RESET is not set +CONFIG_RENESAS_ETHER_SWITCH=y +CONFIG_RENESAS_SDHI=y +CONFIG_SPI_FLASH_SPANSION=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_SYS_I2C_RCAR_I2C=y diff --git a/include/configs/ironhide.h b/include/configs/ironhide.h new file mode 100644 index 00000000000..703c1714052 --- /dev/null +++ b/include/configs/ironhide.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +#ifndef __IRONHIDE_H +#define __IRONHIDE_H + +#include "rcar-gen5-common.h" + +#endif /* __IRONHIDE_H */ diff --git a/include/configs/rcar-gen5-common.h b/include/configs/rcar-gen5-common.h new file mode 100644 index 00000000000..dc28d07c7f9 --- /dev/null +++ b/include/configs/rcar-gen5-common.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2025 Renesas Electronics Corporation + */ + +#ifndef __RCAR_GEN5_COMMON_H +#define __RCAR_GEN5_COMMON_H + +#include + +/* Console */ +#define CFG_SYS_BAUDRATE_TABLE { 38400, 115200, 921600, 1843200, 3250000 } + +/* Memory */ +#define DRAM_RSV_SIZE 0x08000000 +#define CFG_SYS_SDRAM_BASE (0x40000000 + DRAM_RSV_SIZE) +#define CFG_SYS_SDRAM_SIZE (0x80000000u - DRAM_RSV_SIZE) +#define CFG_MAX_MEM_MAPPED (0x80000000u - DRAM_RSV_SIZE) + +/* Environment setting */ +#define CFG_EXTRA_ENV_SETTINGS \ + "bootm_size=0x10000000\0" + +#endif /* __RCAR_GEN5_COMMON_H */ -- cgit v1.3.1 From 186de8a8fa860b44c528711d295fe3f32952074b Mon Sep 17 00:00:00 2001 From: Hai Pham Date: Mon, 27 Oct 2025 18:22:55 +0100 Subject: arm64: renesas: Extend stub PSCI implementation to R-Car Gen5 Extend the stub PSCI implementation with support for R-Car Gen5. R-Car Gen5 uses different register to perform reset, therefore add a compile-time conditional. This is __secure code, therefore the runtime SoC detection parts are not available to it, hence the compile time conditional. Signed-off-by: Hai Pham Signed-off-by: Marek Vasut # Tweak commit message --- arch/arm/mach-renesas/psci-rcar64.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-renesas/psci-rcar64.c b/arch/arm/mach-renesas/psci-rcar64.c index 459dd55ff45..22c2ee045cc 100644 --- a/arch/arm/mach-renesas/psci-rcar64.c +++ b/arch/arm/mach-renesas/psci-rcar64.c @@ -32,7 +32,12 @@ u32 __secure psci_version(void) void __secure __noreturn psci_system_reset(void) { +#if defined(CONFIG_RCAR_GEN5) + writel(RST_KCPROT_DIS, RST_RESKCPROT0); + writel(0x1, RST_SWSRES1A); +#else writel(RST_SPRES, RST_SRESCR0); +#endif while (1) ; -- cgit v1.3.1 From d9a765222dae01ea24fc3240cc05745b4b47c698 Mon Sep 17 00:00:00 2001 From: Wolfgang Wallner Date: Tue, 2 Dec 2025 10:24:58 +0100 Subject: Change email addresses for B&R Industrial Automation B&R Industrial Automation has been acquired by ABB in 2017, and this will be reflected in our email addresses beginning from December 2025. The email addresses change as follows: @br-automation.com -> @.abb.com The existing email addresses will be valid until December 2026. Add entries for Bernhard Messerklinger and myself to .mailmap, and update the MAINTAINERS files. Signed-off-by: Wolfgang Wallner Signed-off-by: Wolfgang Wallner --- .mailmap | 2 ++ board/BuR/brppt1/MAINTAINERS | 2 +- board/BuR/brppt2/MAINTAINERS | 2 +- board/BuR/brsmarc1/MAINTAINERS | 2 +- board/BuR/brxre1/MAINTAINERS | 2 +- board/BuR/zynq/MAINTAINERS | 2 +- 6 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.mailmap b/.mailmap index 145e9ea26e4..04daa274ef3 100644 --- a/.mailmap +++ b/.mailmap @@ -28,6 +28,7 @@ Anurag Kumar Vulisha Ashok Reddy Soma Atish Patra +Bernhard Messerklinger Bharat Kumar Gogada Bharat Kumar Gogada Bhargava Sreekantappa Gayathri @@ -156,6 +157,7 @@ Wolfgang Denk Wolfgang Denk Wolfgang Denk Wolfgang Denk +Wolfgang Wallner York Sun York Sun Łukasz Majewski diff --git a/board/BuR/brppt1/MAINTAINERS b/board/BuR/brppt1/MAINTAINERS index a974a97c157..b24d7eb9ad5 100644 --- a/board/BuR/brppt1/MAINTAINERS +++ b/board/BuR/brppt1/MAINTAINERS @@ -1,5 +1,5 @@ BRPPT1 BOARD -M: Wolfgang Wallner +M: Wolfgang Wallner S: Maintained F: board/BuR/brppt1/ F: board/BuR/common/ diff --git a/board/BuR/brppt2/MAINTAINERS b/board/BuR/brppt2/MAINTAINERS index bfeaa571a82..2ab54a909c5 100644 --- a/board/BuR/brppt2/MAINTAINERS +++ b/board/BuR/brppt2/MAINTAINERS @@ -1,5 +1,5 @@ BUR_PPT2 BOARD -M: Wolfgang Wallner +M: Wolfgang Wallner S: Maintained F: board/BuR/brppt2/ F: board/BuR/common/ diff --git a/board/BuR/brsmarc1/MAINTAINERS b/board/BuR/brsmarc1/MAINTAINERS index 7421f61fc43..f2754582b59 100644 --- a/board/BuR/brsmarc1/MAINTAINERS +++ b/board/BuR/brsmarc1/MAINTAINERS @@ -1,5 +1,5 @@ BRSMARC1 BOARD -M: Wolfgang Wallner +M: Wolfgang Wallner S: Maintained F: board/BuR/brsmarc1/ F: board/BuR/common/ diff --git a/board/BuR/brxre1/MAINTAINERS b/board/BuR/brxre1/MAINTAINERS index f826a44b6ac..b424ddca6ca 100644 --- a/board/BuR/brxre1/MAINTAINERS +++ b/board/BuR/brxre1/MAINTAINERS @@ -1,5 +1,5 @@ BRXRE1 BOARD -M: Wolfgang Wallner +M: Wolfgang Wallner S: Maintained F: board/BuR/brxre1/ F: board/BuR/common/ diff --git a/board/BuR/zynq/MAINTAINERS b/board/BuR/zynq/MAINTAINERS index d655cae58d4..e2b04980403 100644 --- a/board/BuR/zynq/MAINTAINERS +++ b/board/BuR/zynq/MAINTAINERS @@ -1,5 +1,5 @@ ZYNQ BOARD -M: Wolfgang Wallner +M: Wolfgang Wallner S: Maintained F: board/BuR/zynq/ F: board/BuR/common/ -- cgit v1.3.1 From 97e202a72160ea038dda46130d911546e66a189c Mon Sep 17 00:00:00 2001 From: Wolfgang Wallner Date: Tue, 2 Dec 2025 10:43:41 +0100 Subject: board: BuR: Update MAINTAINERS files The MAINTAINERS files for B&R boards are not in sync with the current file names. Update the files so that they are correct again. Signed-off-by: Wolfgang Wallner --- board/BuR/brppt1/MAINTAINERS | 3 +-- board/BuR/brppt2/MAINTAINERS | 1 + board/BuR/brsmarc1/MAINTAINERS | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/board/BuR/brppt1/MAINTAINERS b/board/BuR/brppt1/MAINTAINERS index b24d7eb9ad5..fc2ee146668 100644 --- a/board/BuR/brppt1/MAINTAINERS +++ b/board/BuR/brppt1/MAINTAINERS @@ -5,5 +5,4 @@ F: board/BuR/brppt1/ F: board/BuR/common/ F: include/configs/brppt1.h F: configs/brppt1_mmc_defconfig -F: configs/brppt1_nand_defconfig -F: configs/brppt1_spi_defconfig +F: arch/arm/dts/am335x-brppt1-mmc* diff --git a/board/BuR/brppt2/MAINTAINERS b/board/BuR/brppt2/MAINTAINERS index 2ab54a909c5..84cb6573463 100644 --- a/board/BuR/brppt2/MAINTAINERS +++ b/board/BuR/brppt2/MAINTAINERS @@ -5,3 +5,4 @@ F: board/BuR/brppt2/ F: board/BuR/common/ F: include/configs/brppt2.h F: configs/brppt2_defconfig +F: arch/arm/dts/imx6dl-brppt2.dts diff --git a/board/BuR/brsmarc1/MAINTAINERS b/board/BuR/brsmarc1/MAINTAINERS index f2754582b59..8716002c172 100644 --- a/board/BuR/brsmarc1/MAINTAINERS +++ b/board/BuR/brsmarc1/MAINTAINERS @@ -5,3 +5,4 @@ F: board/BuR/brsmarc1/ F: board/BuR/common/ F: include/configs/brsmarc1.h F: configs/brsmarc1_defconfig +F: arch/arm/dts/am335x-brsmarc1.dts -- cgit v1.3.1 From 02aa1a56a7cfcb858973ef8965e54cf539060fd9 Mon Sep 17 00:00:00 2001 From: Chukun Pan Date: Tue, 2 Dec 2025 18:00:00 +0800 Subject: binman: fallback to importlib_resources on Python 3.8 Python 3.7 and 3.8 lack the files attribute in importlib.resources. Use importlib_resources to fix build errors with Python 3.8: binman: module 'importlib.resources' has no attribute 'files' Fixes: 538719cb6a77 ("binman: migrate from pkg_resources to importlib") Signed-off-by: Chukun Pan Acked-by: Quentin Schulz [trini: Re-add # pragma: no cover line] Signed-off-by: Tom Rini --- tools/binman/control.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/binman/control.py b/tools/binman/control.py index 1307222591d..816f7c1eba2 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -9,8 +9,9 @@ from collections import OrderedDict import glob try: import importlib.resources as importlib_resources -except ImportError: # pragma: no cover - # for Python 3.6 + # for Python 3.6, 3.7 and 3.8 + importlib_resources.files +except (ImportError, AttributeError): # pragma: no cover import importlib_resources import os import re -- cgit v1.3.1 From a0bf98cedbc6c1b8c32b0ce8e984386d3e5aa48f Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 3 Dec 2025 15:46:40 -0500 Subject: test: strlcat: Fix SPDX license When I modified this code I meant to accept the LGPL offer to convert the license to GPL. However, while there is an LGPL 2.1, the next version of the GPL after 2.0 is 3.0. Fix the license version Fixess: c4ac52f55d9 ("test: Add test for strlcat") Signed-off-by: Sean Anderson --- test/lib/strlcat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lib/strlcat.c b/test/lib/strlcat.c index d1a0293271b..a3d4eee4795 100644 --- a/test/lib/strlcat.c +++ b/test/lib/strlcat.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.1+ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2021 Sean Anderson * Copyright (C) 2011-2021 Free Software Foundation, Inc. -- cgit v1.3.1 From c98b6a6dcd1fc7bcba081fc2353954e33de5053c Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 3 Dec 2025 16:03:35 -0500 Subject: clk: Remove myself as a maintainer Unfortunately I don't really have time to review clock patches. When I initially started maintaining this subsystem I had more free time than I do now. But I also found it hard to motivate myself to review patches. Many clock patches add support for new SoCs and they are time consuming to review properly. You effectively have to spend a few hours reading the reference manual (if it's public!) and reviewing drivers is no small feat either. This is made more difficult since clocking is often very different between SoCs and it can be difficult to determine whether something is a bug in the driver or a workaround for some hardware behavior. I mostly don't care about any given SoC unless I'm hacking on it so I ended up with a ton (more than 7000) of unreviewed patches piling up in my inbox. I'd love to be more active, but I have a day job and I usually want to work on something more interesting when I get home. I still think the clock subsystem is a major mess but I don't care enough to fix it :l The subsystem itself should probably get orphaned since AFAICT all patches go through the mach/arch maintainer or to Tom. Signed-off-by: Sean Anderson --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index b43dae882b3..cddeca734ff 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1039,7 +1039,6 @@ F: drivers/mtd/jedec_flash.c CLOCK M: Lukasz Majewski -M: Sean Anderson S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-clk.git F: drivers/clk/ -- cgit v1.3.1 From 56778d4c2787cb0eea35b5e9bb82e4782b17ff41 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 22 Nov 2025 23:17:37 +0100 Subject: tools/logos: Add U-Boot logo with text 'U-Boot' The logo with the text 'U-Boot' has been used in multiple presentations. Up to now it was only available from my upload to wikimedia.org. Make it available in our repository. Link: https://upload.wikimedia.org/wikipedia/commons/9/9e/U-Boot_Logo.svg Signed-off-by: Heinrich Schuchardt --- tools/logos/u-boot_logo_with_text.svg | 280 ++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 tools/logos/u-boot_logo_with_text.svg diff --git a/tools/logos/u-boot_logo_with_text.svg b/tools/logos/u-boot_logo_with_text.svg new file mode 100644 index 00000000000..1527e79a3a9 --- /dev/null +++ b/tools/logos/u-boot_logo_with_text.svg @@ -0,0 +1,280 @@ + + + + + + + U-Boot Logo + + + + image/svg+xml + + U-Boot Logo + + + + Heinrich Schuchardt <xypron.glpk@gmx.de> + + + May 21st, 2018 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.3.1 From cb8156e9efbf2a70a9f16a4634a8d8a86801b811 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 22 Nov 2025 23:17:38 +0100 Subject: doc: add a page for downloading the U-Boot logo Add a page showing the logo with and without text. Signed-off-by: Heinrich Schuchardt --- doc/learn/index.rst | 1 + doc/learn/logo.rst | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 doc/learn/logo.rst diff --git a/doc/learn/index.rst b/doc/learn/index.rst index 8075c01d1df..5b139e3c9fd 100644 --- a/doc/learn/index.rst +++ b/doc/learn/index.rst @@ -6,4 +6,5 @@ Learn about U-Boot .. toctree:: :maxdepth: 1 + logo talks diff --git a/doc/learn/logo.rst b/doc/learn/logo.rst new file mode 100644 index 00000000000..66d403e4cff --- /dev/null +++ b/doc/learn/logo.rst @@ -0,0 +1,20 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later + +U-Boot logo +=========== + +The project uses the logos below. + +Logo with text +-------------- + +.. image:: ../../tools/logos/u-boot_logo_with_text.svg + :width: 10em + :alt: U-Boot logo with text + +Logo without text +----------------- + +.. image:: ../../tools/logos/u-boot_logo.svg + :width: 10em + :alt: U-Boot logo without text -- cgit v1.3.1 From 50cbdaba66ac0fc1bd8d915a2452c54a120f06f6 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 24 Nov 2025 16:44:06 -0600 Subject: doc: pytest: fix hook script environment variable names Fix the names of environment variables set for hook scripts. These have a U_BOOT_ prefix, not UBOOT_. Signed-off-by: David Lechner --- doc/develop/pytest/usage.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/develop/pytest/usage.rst b/doc/develop/pytest/usage.rst index 7335a39b963..7c42a31528f 100644 --- a/doc/develop/pytest/usage.rst +++ b/doc/develop/pytest/usage.rst @@ -315,14 +315,14 @@ Environment variables The following environment variables are set when running hook scripts: -- ``UBOOT_BOARD_TYPE`` the board type being tested. -- ``UBOOT_BOARD_IDENTITY`` the board identity being tested, or ``na`` if none +- ``U_BOOT_BOARD_TYPE`` the board type being tested. +- ``U_BOOT_BOARD_IDENTITY`` the board identity being tested, or ``na`` if none was specified. -- ``UBOOT_SOURCE_DIR`` the U-Boot source directory. -- ``UBOOT_TEST_PY_DIR`` the full path to ``test/py/`` in the source directory. -- ``UBOOT_BUILD_DIR`` the U-Boot build directory. -- ``UBOOT_RESULT_DIR`` the test result directory. -- ``UBOOT_PERSISTENT_DATA_DIR`` the test persistent data directory. +- ``U_BOOT_SOURCE_DIR`` the U-Boot source directory. +- ``U_BOOT_TEST_PY_DIR`` the full path to ``test/py/`` in the source directory. +- ``U_BOOT_BUILD_DIR`` the U-Boot build directory. +- ``U_BOOT_RESULT_DIR`` the test result directory. +- ``U_BOOT_PERSISTENT_DATA_DIR`` the test persistent data directory. u-boot-test-console ''''''''''''''''''' -- cgit v1.3.1 From 18e2a059ff3f04e21cf2f17af59d2c812cebc517 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 24 Nov 2025 16:44:07 -0600 Subject: doc: pytest: add missing hook script env vars Add the _EXTRA variants of U_BOOT_BUILD_DIR and U_BOOT_RESULT_DIR to the list of environment variables set for hook scripts. These were added in commit 8f2a9fa7d6e7 ("test: Support testing with two board-builds") but were not documented. Signed-off-by: David Lechner --- doc/develop/pytest/usage.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/develop/pytest/usage.rst b/doc/develop/pytest/usage.rst index 7c42a31528f..df3821da20d 100644 --- a/doc/develop/pytest/usage.rst +++ b/doc/develop/pytest/usage.rst @@ -316,11 +316,13 @@ Environment variables The following environment variables are set when running hook scripts: - ``U_BOOT_BOARD_TYPE`` the board type being tested. +- ``U_BOOT_BOARD_TYPE_EXTRA`` the 2nd board type being tested, if applicable. - ``U_BOOT_BOARD_IDENTITY`` the board identity being tested, or ``na`` if none was specified. - ``U_BOOT_SOURCE_DIR`` the U-Boot source directory. - ``U_BOOT_TEST_PY_DIR`` the full path to ``test/py/`` in the source directory. - ``U_BOOT_BUILD_DIR`` the U-Boot build directory. +- ``U_BOOT_BUILD_DIR_EXTRA`` the 2nd U-Boot build directory, if applicable. - ``U_BOOT_RESULT_DIR`` the test result directory. - ``U_BOOT_PERSISTENT_DATA_DIR`` the test persistent data directory. -- cgit v1.3.1 From ad53505a4861ad7eec5c6a919ea39692d915e433 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Thu, 27 Nov 2025 14:19:06 +0200 Subject: efi_loader: Fix a memory leak when retrieving device paths from boot vars get_dp_device() is used to derive the device path from a boot variable. However, if the last efi_get_variable_int() call fails, we return an error without freeing 'buf'. There's no need to call efi_get_variable_int() for variables we don't know the size since we have the efi_get_var() wrapper. Replace that in the two instances we use it. The first one will also fix the memory leak. A nice sideeffect is that the code size is also reduced, since we are re-using functions instead of open coding them $~ bloat-o-meter u-boot u-boot.new add/remove: 0/0 grow/shrink: 1/2 up/down: 6/-196 (-190) Function old new delta version_string 70 76 +6 efi_launch_capsules 2288 2196 -92 get_dp_device 244 140 -104 Total: Before=1222331, After=1222141, chg -0.02% Fixes: c74cd8bd08d1 ("efi_loader: capsule: add capsule_on_disk support") Signed-off-by: Ilias Apalodimas Reviewed-by: Heinrich Schuchardt --- lib/efi_loader/efi_capsule.c | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 31b47a20186..eafc647f558 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -857,18 +857,9 @@ static efi_status_t get_dp_device(u16 *boot_var, struct efi_device_path *file_dp; efi_status_t ret; - size = 0; - ret = efi_get_variable_int(boot_var, &efi_global_variable_guid, - NULL, &size, NULL, NULL); - if (ret == EFI_BUFFER_TOO_SMALL) { - buf = malloc(size); - if (!buf) - return EFI_OUT_OF_RESOURCES; - ret = efi_get_variable_int(boot_var, &efi_global_variable_guid, - NULL, &size, buf, NULL); - } - if (ret != EFI_SUCCESS) - return ret; + buf = efi_get_var(boot_var, &efi_global_variable_guid, &size); + if (!buf) + return EFI_NOT_FOUND; efi_deserialize_load_option(&lo, buf, &size); @@ -960,22 +951,11 @@ static efi_status_t find_boot_device(void) skip: /* find active boot device in BootOrder */ - size = 0; - ret = efi_get_variable_int(u"BootOrder", &efi_global_variable_guid, - NULL, &size, NULL, NULL); - if (ret == EFI_BUFFER_TOO_SMALL) { - boot_order = malloc(size); - if (!boot_order) { - ret = EFI_OUT_OF_RESOURCES; - goto out; - } - - ret = efi_get_variable_int(u"BootOrder", - &efi_global_variable_guid, - NULL, &size, boot_order, NULL); - } - if (ret != EFI_SUCCESS) + boot_order = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!boot_order) { + ret = EFI_NOT_FOUND; goto out; + } /* check in higher order */ num = size / sizeof(u16); -- cgit v1.3.1 From e5996e3ed350598c79cd7afaf6d4f0618598e390 Mon Sep 17 00:00:00 2001 From: Francesco Dolcini Date: Fri, 5 Dec 2025 09:27:28 +0100 Subject: doc: board: verdin-am62p: Fix boot log output Fix boot log output not being rendered correctly, fix it doing the same as done in verdin-am62.rst. Fixes: b8c43968b801 ("board: toradex: add verdin am62p support") Signed-off-by: Francesco Dolcini --- doc/board/toradex/verdin-am62p.rst | 135 ++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 69 deletions(-) diff --git a/doc/board/toradex/verdin-am62p.rst b/doc/board/toradex/verdin-am62p.rst index 2f3262b8d1e..cc60505a40c 100644 --- a/doc/board/toradex/verdin-am62p.rst +++ b/doc/board/toradex/verdin-am62p.rst @@ -125,72 +125,69 @@ one may also use the update U-Boot wrappers: Boot ---- -Output: - -.. code-block:: console - -U-Boot SPL 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:46:57 +0100) -SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)') -Changed A53 CPU frequency to 1250000000Hz (U grade) in DT -SPL initial stack usage: 17080 bytes -Trying to boot from MMC1 -Authentication passed -Authentication passed -Authentication passed -Loading Environment from nowhere... OK -init_env from device 9 not supported! -Authentication passed -Authentication passed -Starting ATF on ARM64 core... - -NOTICE: BL31: v2.12.0(release):v2.12.0-1106-g4301798db096 -NOTICE: BL31: Built : 10:57:58, May 9 2025 -I/TC: -I/TC: OP-TEE version: 4.6.0-18-g76d920d354df (gcc version 12.3.1 20230626 (Arm GNU Toolchain 12.3.Rel1 (Build arm-12.35))) #4 Tue May 6 19:48:13 UTC 2025 aarch64 -I/TC: WARNING: This OP-TEE configuration might be insecure! -I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html -I/TC: Primary CPU initializing -I/TC: GIC redistributor base address not provided -I/TC: Assuming default GIC group status and modifier -I/TC: SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)') -I/TC: Activated SA2UL device -I/TC: Enabled firewalls for SA2UL TRNG device -I/TC: SA2UL TRNG initialized -I/TC: SA2UL Drivers initialized -I/TC: HUK Initialized -I/TC: Primary CPU switching to normal world boot - -U-Boot SPL 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:47:54 +0100) -SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)') -SPL initial stack usage: 1760 bytes -HW CFG: 0x00 -Trying to boot from MMC1 -Authentication passed -Authentication passed - - -U-Boot 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:47:54 +0100) - -SoC: AM62PX SR1.0 HS-FS -DRAM: 2 GiB -Core: 147 devices, 31 uclasses, devicetree: separate -MMC: mmc@fa10000: 0, mmc@fa00000: 1 -Loading Environment from MMC... Reading from MMC(0)... OK -In: serial@2800000 -Out: serial@2800000 -Err: serial@2800000 -Model: Toradex 0099 Verdin AM62P Quad 2GB WB IT V1.0A -Serial#: 15664919 -Carrier: Toradex Dahlia V1.1D, Serial# 11287149 -am65_cpsw_nuss ethernet@8000000: K3 CPSW: nuss_ver: 0x6BA01903 cpsw_ver: 0x6BA81903 ale_ver: 0x00290105 Ports:2 -Setting variant to wifi -Net: -Warning: ethernet@8000000port@1 MAC addresses don't match: -Address in ROM is 58:a1:5f:b8:93:f9 -Address in environment is 00:14:2d:ef:07:17 -eth0: ethernet@8000000port@1 [PRIME]Could not get PHY for mdio@f00: addr 7 -am65_cpsw_nuss_port ethernet@8000000port@2: phy_connect() failed - -Hit any key to stop autoboot: 0 -Verdin AM62P # - +Output:: + + U-Boot SPL 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:46:57 +0100) + SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)') + Changed A53 CPU frequency to 1250000000Hz (U grade) in DT + SPL initial stack usage: 17080 bytes + Trying to boot from MMC1 + Authentication passed + Authentication passed + Authentication passed + Loading Environment from nowhere... OK + init_env from device 9 not supported! + Authentication passed + Authentication passed + Starting ATF on ARM64 core... + + NOTICE: BL31: v2.12.0(release):v2.12.0-1106-g4301798db096 + NOTICE: BL31: Built : 10:57:58, May 9 2025 + I/TC: + I/TC: OP-TEE version: 4.6.0-18-g76d920d354df (gcc version 12.3.1 20230626 (Arm GNU Toolchain 12.3.Rel1 (Build arm-12.35))) #4 Tue May 6 19:48:13 UTC 2025 aarch64 + I/TC: WARNING: This OP-TEE configuration might be insecure! + I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html + I/TC: Primary CPU initializing + I/TC: GIC redistributor base address not provided + I/TC: Assuming default GIC group status and modifier + I/TC: SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)') + I/TC: Activated SA2UL device + I/TC: Enabled firewalls for SA2UL TRNG device + I/TC: SA2UL TRNG initialized + I/TC: SA2UL Drivers initialized + I/TC: HUK Initialized + I/TC: Primary CPU switching to normal world boot + + U-Boot SPL 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:47:54 +0100) + SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)') + SPL initial stack usage: 1760 bytes + HW CFG: 0x00 + Trying to boot from MMC1 + Authentication passed + Authentication passed + + + U-Boot 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:47:54 +0100) + + SoC: AM62PX SR1.0 HS-FS + DRAM: 2 GiB + Core: 147 devices, 31 uclasses, devicetree: separate + MMC: mmc@fa10000: 0, mmc@fa00000: 1 + Loading Environment from MMC... Reading from MMC(0)... OK + In: serial@2800000 + Out: serial@2800000 + Err: serial@2800000 + Model: Toradex 0099 Verdin AM62P Quad 2GB WB IT V1.0A + Serial#: 15664919 + Carrier: Toradex Dahlia V1.1D, Serial# 11287149 + am65_cpsw_nuss ethernet@8000000: K3 CPSW: nuss_ver: 0x6BA01903 cpsw_ver: 0x6BA81903 ale_ver: 0x00290105 Ports:2 + Setting variant to wifi + Net: + Warning: ethernet@8000000port@1 MAC addresses don't match: + Address in ROM is 58:a1:5f:b8:93:f9 + Address in environment is 00:14:2d:ef:07:17 + eth0: ethernet@8000000port@1 [PRIME]Could not get PHY for mdio@f00: addr 7 + am65_cpsw_nuss_port ethernet@8000000port@2: phy_connect() failed + + Hit any key to stop autoboot: 0 + Verdin AM62P # -- cgit v1.3.1 From b5d592eff12c8a7ad6a8d88573faaef0894f00b0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 5 Dec 2025 17:01:38 +0100 Subject: MAINTAINERS: update my email address I am moving over to using my email address at kernel.org. Change this in all the affected MAINTAINERS files. Reviewed-by: Quentin Schulz Signed-off-by: Linus Walleij Reviewed-by: Neil Armstrong --- .mailmap | 1 + MAINTAINERS | 4 ++-- board/armltd/integrator/MAINTAINERS | 2 +- board/armltd/vexpress64/MAINTAINERS | 6 +++--- board/broadcom/bcmns/MAINTAINERS | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.mailmap b/.mailmap index 04daa274ef3..0e01452a70c 100644 --- a/.mailmap +++ b/.mailmap @@ -75,6 +75,7 @@ Jyotheeswar Reddy Mutthareddyvari Klaus Goger Masahisa Kojima +Linus Walleij Love Kumar Lukasz Majewski Marek Behún diff --git a/MAINTAINERS b/MAINTAINERS index cddeca734ff..1789f023631 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -820,7 +820,7 @@ F: include/linux/soc/ti/ ARM U8500 M: Stephan Gerhold -R: Linus Walleij +R: Linus Walleij S: Maintained F: arch/arm/dts/ste-* F: arch/arm/mach-u8500/ @@ -1648,7 +1648,7 @@ F: include/scmi* N: scmi SEAMA -M: Linus Walleij +M: Linus Walleij S: Maintained F: cmd/seama.c F: doc/usage/cmd/seama.rst diff --git a/board/armltd/integrator/MAINTAINERS b/board/armltd/integrator/MAINTAINERS index 8af765eaebc..a228fc3daec 100644 --- a/board/armltd/integrator/MAINTAINERS +++ b/board/armltd/integrator/MAINTAINERS @@ -1,5 +1,5 @@ INTEGRATOR BOARD -M: Linus Walleij +M: Linus Walleij S: Maintained F: board/armltd/integrator/ F: include/configs/integratorcp.h diff --git a/board/armltd/vexpress64/MAINTAINERS b/board/armltd/vexpress64/MAINTAINERS index c38ab520c52..58ab5db7e4a 100644 --- a/board/armltd/vexpress64/MAINTAINERS +++ b/board/armltd/vexpress64/MAINTAINERS @@ -1,18 +1,18 @@ VEXPRESS64 PLATFORM M: David Feng -M: Linus Walleij +M: Linus Walleij M: Peter Hoyes S: Maintained F: board/armltd/vexpress64/ F: include/configs/vexpress_aemv8.h VEXPRESS_AEMV8A_SEMI BOARD -M: Linus Walleij +M: Linus Walleij S: Maintained F: configs/vexpress_aemv8a_semi_defconfig JUNO DEVELOPMENT PLATFORM BOARD -M: Linus Walleij +M: Linus Walleij S: Maintained F: configs/vexpress_aemv8a_juno_defconfig diff --git a/board/broadcom/bcmns/MAINTAINERS b/board/broadcom/bcmns/MAINTAINERS index 63c6d8bb4ac..4972d6cc934 100644 --- a/board/broadcom/bcmns/MAINTAINERS +++ b/board/broadcom/bcmns/MAINTAINERS @@ -1,5 +1,5 @@ BCMNS BOARD -M: Linus Walleij +M: Linus Walleij S: Maintained F: board/broadcom/bcmns/ F: configs/bcmns_defconfig -- cgit v1.3.1 From bb1c2b463265175f05a1e5de7b39de815db1a03a Mon Sep 17 00:00:00 2001 From: Brian Sune Date: Tue, 2 Dec 2025 12:10:29 +0800 Subject: update GCC version check after Kbuild bump ARM GCC tool check is not up to date, while issues are reported such as file truncated linker errors. Using ARM official cross tools shows that 10.0.1 is a safe version to support latest kbuild bump properly. Signed-off-by: Brian Sune --- arch/arm/config.mk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/config.mk b/arch/arm/config.mk index 73fddd50bd7..a7eff84a267 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -58,7 +58,7 @@ endif # Only test once ifeq ($(CONFIG_$(PHASE_)SYS_THUMB_BUILD),y) -archprepare: checkthumb checkgcc6 +archprepare: checkthumb checkgcc10 checkthumb: @if test "$(call cc-name)" = "gcc" -a \ @@ -69,13 +69,13 @@ checkthumb: false; \ fi else -archprepare: checkgcc6 +archprepare: checkgcc10 endif -checkgcc6: +checkgcc10: @if test "$(call cc-name)" = "gcc" -a \ - "$(call cc-version)" -lt "0600"; then \ - echo '*** Your GCC is older than 6.0 and is not supported'; \ + "$(call cc-version)" -lt "1000"; then \ + echo '*** Your GCC is older than 10.0 and is not supported'; \ false; \ fi -- cgit v1.3.1 From c7c2c3c0101f625c01bf101d652e03a6d4aa950f Mon Sep 17 00:00:00 2001 From: Chintan Vankar Date: Thu, 4 Dec 2025 17:51:27 +0530 Subject: arm: mach-k3: j722s: Fix eMMC boot functionality broken by Ethernet boot While adding CPSW device support to enable Ethernet boot for J722S, dev-data and clk-data for eMMC was removed by mistake, which leads to eMMC boot failure. Update the dev-data and clk-data to fix that. Fixes: a02009f3a816 ("arm: mach-k3: j722s: Update SoC autogenerated data to enable Ethernet boot") Reported-by: Michael Walle Signed-off-by: Chintan Vankar Tested-by: Michael Walle Reviewed-by: Udit Kumar --- arch/arm/mach-k3/r5/j722s/clk-data.c | 12 +++++++++ arch/arm/mach-k3/r5/j722s/dev-data.c | 50 +++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-k3/r5/j722s/clk-data.c b/arch/arm/mach-k3/r5/j722s/clk-data.c index 238d57d0aa0..cb3d864c5a3 100644 --- a/arch/arm/mach-k3/r5/j722s/clk-data.c +++ b/arch/arm/mach-k3/r5/j722s/clk-data.c @@ -68,6 +68,11 @@ static const char * const main_cp_gemac_cpts_clk_sel_out0_parents[] = { "sam62_pll_ctrl_wrap_main_0_chip_div1_clk_clk", }; +static const char * const main_emmcsd0_refclk_sel_out0_parents[] = { + "postdiv4_16ff_main_0_hsdivout5_clk", + "hsdiv4_16fft_main_2_hsdivout2_clk", +}; + static const char * const main_emmcsd1_refclk_sel_out0_parents[] = { "postdiv4_16ff_main_0_hsdivout5_clk", "hsdiv4_16fft_main_2_hsdivout2_clk", @@ -106,6 +111,8 @@ static const char * const main_timerclkn_sel_out0_parents[] = { NULL, NULL, NULL, + NULL, + NULL, }; static const char * const wkup_clkout_sel_out0_parents[] = { @@ -205,6 +212,7 @@ static const struct clk_data clk_list[] = { CLK_MUX_PLLCTRL("sam62_pll_ctrl_wrap_mcu_0_sysclkout_clk", sam62_pll_ctrl_wrap_mcu_0_sysclkout_clk_parents, 2, 0x4020000, 0), CLK_DIV("sam62_pll_ctrl_wrap_mcu_0_chip_div1_clk_clk", "sam62_pll_ctrl_wrap_mcu_0_sysclkout_clk", 0x4020118, 0, 5, 0, 0), CLK_MUX("clkout0_ctrl_out0", clkout0_ctrl_out0_parents, 2, 0x108010, 0, 1, 0), + CLK_MUX("main_emmcsd0_refclk_sel_out0", main_emmcsd0_refclk_sel_out0_parents, 2, 0x108160, 0, 1, 0), CLK_MUX("main_cp_gemac_cpts_clk_sel_out0", main_cp_gemac_cpts_clk_sel_out0_parents, 8, 0x108140, 0, 3, 0), CLK_MUX("main_emmcsd1_refclk_sel_out0", main_emmcsd1_refclk_sel_out0_parents, 2, 0x108168, 0, 1, 0), CLK_MUX("main_gtcclk_sel_out0", main_gtcclk_sel_out0_parents, 8, 0x43008030, 0, 3, 0), @@ -262,6 +270,10 @@ static const struct dev_clk soc_dev_clk_data[] = { DEV_CLK(36, 10, "board_0_cp_gemac_cpts0_rft_clk_out"), DEV_CLK(36, 11, "hsdiv4_16fft_main_1_hsdivout3_clk"), DEV_CLK(36, 12, "postdiv4_16ff_main_2_hsdivout6_clk"), + DEV_CLK(57, 1, "sam62_pll_ctrl_wrap_main_0_chip_div1_clk_clk"), + DEV_CLK(57, 2, "main_emmcsd0_refclk_sel_out0"), + DEV_CLK(57, 3, "postdiv4_16ff_main_0_hsdivout5_clk"), + DEV_CLK(57, 4, "hsdiv4_16fft_main_2_hsdivout2_clk"), DEV_CLK(36, 13, "cpsw_3guss_am67_main_0_cpts_genf0"), DEV_CLK(36, 14, "cpsw_3guss_am67_main_0_cpts_genf1"), DEV_CLK(58, 0, "main_emmcsd1_io_clklb_sel_out0"), diff --git a/arch/arm/mach-k3/r5/j722s/dev-data.c b/arch/arm/mach-k3/r5/j722s/dev-data.c index d6832266884..5f7e2a44fed 100644 --- a/arch/arm/mach-k3/r5/j722s/dev-data.c +++ b/arch/arm/mach-k3/r5/j722s/dev-data.c @@ -23,18 +23,19 @@ static struct ti_pd soc_pd_list[] = { static struct ti_lpsc soc_lpsc_list[] = { [0] = PSC_LPSC(0, &soc_psc_list[0], &soc_pd_list[0], NULL), - [1] = PSC_LPSC(12, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[4]), - [2] = PSC_LPSC(13, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[4]), - [3] = PSC_LPSC(21, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[6]), - [4] = PSC_LPSC(23, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[6]), - [5] = PSC_LPSC(28, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[6]), - [6] = PSC_LPSC(34, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[6]), - [7] = PSC_LPSC(42, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[6]), - [8] = PSC_LPSC(53, &soc_psc_list[0], &soc_pd_list[1], &soc_lpsc_list[6]), - [9] = PSC_LPSC(56, &soc_psc_list[0], &soc_pd_list[2], &soc_lpsc_list[8]), - [10] = PSC_LPSC(72, &soc_psc_list[0], &soc_pd_list[3], &soc_lpsc_list[6]), - [11] = PSC_LPSC(73, &soc_psc_list[0], &soc_pd_list[3], &soc_lpsc_list[10]), - [12] = PSC_LPSC(74, &soc_psc_list[0], &soc_pd_list[3], &soc_lpsc_list[11]), + [1] = PSC_LPSC(12, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[5]), + [2] = PSC_LPSC(13, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[5]), + [3] = PSC_LPSC(20, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[7]), + [4] = PSC_LPSC(21, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[7]), + [5] = PSC_LPSC(23, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[7]), + [6] = PSC_LPSC(28, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[7]), + [7] = PSC_LPSC(34, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[7]), + [8] = PSC_LPSC(42, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[7]), + [9] = PSC_LPSC(53, &soc_psc_list[0], &soc_pd_list[1], &soc_lpsc_list[7]), + [10] = PSC_LPSC(56, &soc_psc_list[0], &soc_pd_list[2], &soc_lpsc_list[9]), + [11] = PSC_LPSC(72, &soc_psc_list[0], &soc_pd_list[3], &soc_lpsc_list[7]), + [12] = PSC_LPSC(73, &soc_psc_list[0], &soc_pd_list[3], &soc_lpsc_list[11]), + [13] = PSC_LPSC(74, &soc_psc_list[0], &soc_pd_list[3], &soc_lpsc_list[12]), }; static struct ti_dev soc_dev_list[] = { @@ -43,18 +44,19 @@ static struct ti_dev soc_dev_list[] = { PSC_DEV(61, &soc_lpsc_list[0]), PSC_DEV(178, &soc_lpsc_list[1]), PSC_DEV(179, &soc_lpsc_list[2]), - PSC_DEV(58, &soc_lpsc_list[3]), - PSC_DEV(161, &soc_lpsc_list[4]), - PSC_DEV(75, &soc_lpsc_list[5]), - PSC_DEV(36, &soc_lpsc_list[6]), - PSC_DEV(102, &soc_lpsc_list[6]), - PSC_DEV(146, &soc_lpsc_list[6]), - PSC_DEV(13, &soc_lpsc_list[7]), - PSC_DEV(166, &soc_lpsc_list[8]), - PSC_DEV(135, &soc_lpsc_list[9]), - PSC_DEV(170, &soc_lpsc_list[10]), - PSC_DEV(177, &soc_lpsc_list[11]), - PSC_DEV(55, &soc_lpsc_list[12]), + PSC_DEV(57, &soc_lpsc_list[3]), + PSC_DEV(58, &soc_lpsc_list[4]), + PSC_DEV(161, &soc_lpsc_list[5]), + PSC_DEV(75, &soc_lpsc_list[6]), + PSC_DEV(36, &soc_lpsc_list[7]), + PSC_DEV(102, &soc_lpsc_list[7]), + PSC_DEV(146, &soc_lpsc_list[7]), + PSC_DEV(13, &soc_lpsc_list[8]), + PSC_DEV(166, &soc_lpsc_list[9]), + PSC_DEV(135, &soc_lpsc_list[10]), + PSC_DEV(170, &soc_lpsc_list[11]), + PSC_DEV(177, &soc_lpsc_list[12]), + PSC_DEV(55, &soc_lpsc_list[13]), }; const struct ti_k3_pd_platdata j722s_pd_platdata = { -- cgit v1.3.1 From d3291d35b605552e1ad0117a2c396fe90011358e Mon Sep 17 00:00:00 2001 From: Dominik Haller Date: Thu, 20 Nov 2025 13:26:17 -0800 Subject: configs: phycore_am64x_a53_defconfig: Drop eMMC HS400 mode Remove the unsupported MMC_HS400 mode and select MMC_HS200 instead to avoid confusion. Signed-off-by: Dominik Haller --- configs/phycore_am64x_a53_defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/phycore_am64x_a53_defconfig b/configs/phycore_am64x_a53_defconfig index 9d6aa9c308c..2e096415743 100644 --- a/configs/phycore_am64x_a53_defconfig +++ b/configs/phycore_am64x_a53_defconfig @@ -122,8 +122,8 @@ CONFIG_SYS_I2C_OMAP24XX=y CONFIG_DM_MAILBOX=y CONFIG_K3_SEC_PROXY=y CONFIG_SUPPORT_EMMC_BOOT=y -CONFIG_MMC_HS400_SUPPORT=y -CONFIG_SPL_MMC_HS400_SUPPORT=y +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_SPL_MMC_HS200_SUPPORT=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ADMA=y CONFIG_SPL_MMC_SDHCI_ADMA=y -- cgit v1.3.1 From f21a301147a017ce9f99b63e2f69343c3cbabd9c Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 8 Dec 2025 08:37:35 -0600 Subject: configs: Resync with savedefconfig Resync all defconfig files using qconfig.py Signed-off-by: Tom Rini --- configs/apalis-tk1_defconfig | 2 +- configs/apalis_t30_defconfig | 2 +- configs/brcp150_defconfig | 2 +- configs/brcp170_defconfig | 2 +- configs/brcp1_1r_defconfig | 2 +- configs/brcp1_1r_switch_defconfig | 2 +- configs/brcp1_2r_defconfig | 2 +- configs/brsmarc2_defconfig | 2 +- configs/cardhu_defconfig | 2 +- configs/chagall_defconfig | 2 +- configs/colibri_t20_defconfig | 2 +- configs/colibri_t30_defconfig | 2 +- configs/endeavoru_defconfig | 2 +- configs/exynos-mobile_defconfig | 2 -- configs/grouper_defconfig | 2 +- configs/ideapad-yoga-11_defconfig | 2 +- configs/imx6dl_sielaff_defconfig | 2 +- configs/imx8mn_beacon_2g_defconfig | 2 +- configs/imx8mn_beacon_defconfig | 2 +- configs/imx8mn_beacon_fspi_defconfig | 2 +- configs/imx93-phycore_defconfig | 2 +- configs/imx943_evk_defconfig | 2 +- configs/imx95_15x15_evk_defconfig | 2 +- configs/imxrt1050-evk_fspi_defconfig | 2 +- configs/mocha_defconfig | 2 +- configs/mot_defconfig | 2 +- configs/n1_defconfig | 2 +- configs/ouya_defconfig | 2 +- configs/p2771-0000-000_defconfig | 2 +- configs/p3450-0000_defconfig | 2 +- configs/pg_wcom_expu1_defconfig | 2 +- configs/pg_wcom_expu1_update_defconfig | 2 +- configs/pg_wcom_seli8_defconfig | 2 +- configs/pg_wcom_seli8_update_defconfig | 2 +- configs/picasso_defconfig | 2 +- configs/qc750_defconfig | 2 +- configs/socfpga_cyclone5_defconfig | 4 +--- configs/star_defconfig | 2 +- configs/surface-2_defconfig | 2 +- configs/surface-rt_defconfig | 2 +- configs/tegratab_defconfig | 2 +- configs/tf701t_defconfig | 2 +- configs/transformer_t20_defconfig | 2 +- configs/transformer_t30_defconfig | 2 +- 44 files changed, 43 insertions(+), 47 deletions(-) diff --git a/configs/apalis-tk1_defconfig b/configs/apalis-tk1_defconfig index 846c7bde234..14d98041980 100644 --- a/configs/apalis-tk1_defconfig +++ b/configs/apalis-tk1_defconfig @@ -3,8 +3,8 @@ CONFIG_SYS_L2CACHE_OFF=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="apalis-tk1" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0xFFFFDE00 CONFIG_DEFAULT_DEVICE_TREE="tegra124-apalis" diff --git a/configs/apalis_t30_defconfig b/configs/apalis_t30_defconfig index 57e1eb733a8..f98582fca16 100644 --- a/configs/apalis_t30_defconfig +++ b/configs/apalis_t30_defconfig @@ -3,8 +3,8 @@ CONFIG_SYS_L2CACHE_OFF=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="apalis_t30" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0xFFFFDE00 CONFIG_DEFAULT_DEVICE_TREE="tegra30-apalis" diff --git a/configs/brcp150_defconfig b/configs/brcp150_defconfig index bae185e8126..84cf7c8067e 100644 --- a/configs/brcp150_defconfig +++ b/configs/brcp150_defconfig @@ -6,8 +6,8 @@ CONFIG_ARCH_ZYNQ=y CONFIG_TEXT_BASE=0x4000000 CONFIG_SYS_MALLOC_F_LEN=0x1000 CONFIG_SPL_GPIO=y -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="env/brcp150" +CONFIG_NR_DRAM_BANKS=1 CONFIG_SF_DEFAULT_SPEED=100000000 CONFIG_SF_DEFAULT_MODE=0x3 CONFIG_ENV_SIZE=0x10000 diff --git a/configs/brcp170_defconfig b/configs/brcp170_defconfig index f8e17ece276..ea7c239ac94 100644 --- a/configs/brcp170_defconfig +++ b/configs/brcp170_defconfig @@ -6,8 +6,8 @@ CONFIG_ARCH_ZYNQ=y CONFIG_TEXT_BASE=0x4000000 CONFIG_SYS_MALLOC_F_LEN=0x1000 CONFIG_SPL_GPIO=y -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="env/brcp1" +CONFIG_NR_DRAM_BANKS=1 CONFIG_SF_DEFAULT_SPEED=100000000 CONFIG_SF_DEFAULT_MODE=0x3 CONFIG_ENV_SIZE=0x10000 diff --git a/configs/brcp1_1r_defconfig b/configs/brcp1_1r_defconfig index 568313d4860..af87780a68a 100644 --- a/configs/brcp1_1r_defconfig +++ b/configs/brcp1_1r_defconfig @@ -6,8 +6,8 @@ CONFIG_ARCH_ZYNQ=y CONFIG_TEXT_BASE=0x4000000 CONFIG_SYS_MALLOC_F_LEN=0x1000 CONFIG_SPL_GPIO=y -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="env/brcp1" +CONFIG_NR_DRAM_BANKS=1 CONFIG_SF_DEFAULT_SPEED=100000000 CONFIG_SF_DEFAULT_MODE=0x3 CONFIG_ENV_SIZE=0x10000 diff --git a/configs/brcp1_1r_switch_defconfig b/configs/brcp1_1r_switch_defconfig index 805de796df6..6162ca6b5bb 100644 --- a/configs/brcp1_1r_switch_defconfig +++ b/configs/brcp1_1r_switch_defconfig @@ -6,8 +6,8 @@ CONFIG_ARCH_ZYNQ=y CONFIG_TEXT_BASE=0x4000000 CONFIG_SYS_MALLOC_F_LEN=0x1000 CONFIG_SPL_GPIO=y -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="env/brcp1" +CONFIG_NR_DRAM_BANKS=1 CONFIG_SF_DEFAULT_SPEED=100000000 CONFIG_SF_DEFAULT_MODE=0x3 CONFIG_ENV_SIZE=0x10000 diff --git a/configs/brcp1_2r_defconfig b/configs/brcp1_2r_defconfig index e92d8381bbb..95e185f6ac6 100644 --- a/configs/brcp1_2r_defconfig +++ b/configs/brcp1_2r_defconfig @@ -6,8 +6,8 @@ CONFIG_ARCH_ZYNQ=y CONFIG_TEXT_BASE=0x4000000 CONFIG_SYS_MALLOC_F_LEN=0x1000 CONFIG_SPL_GPIO=y -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="env/brcp1" +CONFIG_NR_DRAM_BANKS=1 CONFIG_SF_DEFAULT_SPEED=100000000 CONFIG_SF_DEFAULT_MODE=0x3 CONFIG_ENV_SIZE=0x10000 diff --git a/configs/brsmarc2_defconfig b/configs/brsmarc2_defconfig index 2ed54817af4..0e85ea594d7 100644 --- a/configs/brsmarc2_defconfig +++ b/configs/brsmarc2_defconfig @@ -8,8 +8,8 @@ CONFIG_INITRD_TAG=y CONFIG_TEXT_BASE=0x4000000 CONFIG_SYS_MALLOC_F_LEN=0x1000 CONFIG_SPL_GPIO=y -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="env/brcp1" +CONFIG_NR_DRAM_BANKS=1 CONFIG_SF_DEFAULT_SPEED=100000000 CONFIG_SF_DEFAULT_MODE=0x3 CONFIG_ENV_SIZE=0x10000 diff --git a/configs/cardhu_defconfig b/configs/cardhu_defconfig index 318fbaa529b..9deed0a1e93 100644 --- a/configs/cardhu_defconfig +++ b/configs/cardhu_defconfig @@ -3,8 +3,8 @@ CONFIG_SYS_HAS_NONCACHED_MEMORY=y CONFIG_SYS_L2CACHE_OFF=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="cardhu" +CONFIG_NR_DRAM_BANKS=2 CONFIG_SF_DEFAULT_SPEED=24000000 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0xFFFFE000 diff --git a/configs/chagall_defconfig b/configs/chagall_defconfig index 1688b4c4d07..f51c4f18d63 100644 --- a/configs/chagall_defconfig +++ b/configs/chagall_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="chagall" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra30-pegatron-chagall" diff --git a/configs/colibri_t20_defconfig b/configs/colibri_t20_defconfig index 02e33ba5e3c..036717160aa 100644 --- a/configs/colibri_t20_defconfig +++ b/configs/colibri_t20_defconfig @@ -3,8 +3,8 @@ CONFIG_SYS_L2CACHE_OFF=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x00110000 CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="colibri_t20" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x10000 CONFIG_ENV_OFFSET=0x200000 CONFIG_DEFAULT_DEVICE_TREE="tegra20-colibri" diff --git a/configs/colibri_t30_defconfig b/configs/colibri_t30_defconfig index 63b695c1e54..cd98d75ba19 100644 --- a/configs/colibri_t30_defconfig +++ b/configs/colibri_t30_defconfig @@ -3,8 +3,8 @@ CONFIG_SYS_L2CACHE_OFF=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="colibri_t30" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0xFFFFDE00 CONFIG_DEFAULT_DEVICE_TREE="tegra30-colibri" diff --git a/configs/endeavoru_defconfig b/configs/endeavoru_defconfig index 165c0996038..220b8616ae9 100644 --- a/configs/endeavoru_defconfig +++ b/configs/endeavoru_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="endeavoru" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra30-htc-endeavoru" diff --git a/configs/exynos-mobile_defconfig b/configs/exynos-mobile_defconfig index 81a2c4d3373..3a0b455b169 100644 --- a/configs/exynos-mobile_defconfig +++ b/configs/exynos-mobile_defconfig @@ -29,8 +29,6 @@ CONFIG_OF_LIST="exynos/exynos7870-a2corelte exynos/exynos7870-j6lte exynos/exyno CONFIG_MULTI_DTB_FIT=y CONFIG_BUTTON=y CONFIG_BUTTON_REMAP_PHONE_KEYS=y -CONFIG_CLK=y -CONFIG_CLK_CCF=y CONFIG_CLK_EXYNOS7870=y CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0xdead0000 diff --git a/configs/grouper_defconfig b/configs/grouper_defconfig index b6c9550bbbc..91ba341c941 100644 --- a/configs/grouper_defconfig +++ b/configs/grouper_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="grouper" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-nexus7-grouper-E1565" diff --git a/configs/ideapad-yoga-11_defconfig b/configs/ideapad-yoga-11_defconfig index 68ca8333019..20eecb716fc 100644 --- a/configs/ideapad-yoga-11_defconfig +++ b/configs/ideapad-yoga-11_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="ideapad-yoga-11" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra30-lenovo-ideapad-yoga-11" diff --git a/configs/imx6dl_sielaff_defconfig b/configs/imx6dl_sielaff_defconfig index a4271ea071a..917b8250e8f 100644 --- a/configs/imx6dl_sielaff_defconfig +++ b/configs/imx6dl_sielaff_defconfig @@ -5,8 +5,8 @@ CONFIG_SYS_MALLOC_F_LEN=0x4000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="imx6dl-sielaff" +CONFIG_NR_DRAM_BANKS=1 CONFIG_SF_DEFAULT_SPEED=20000000 CONFIG_ENV_SIZE=0x10000 CONFIG_ENV_OFFSET=0xF0000 diff --git a/configs/imx8mn_beacon_2g_defconfig b/configs/imx8mn_beacon_2g_defconfig index c757a2180c0..32319823a43 100644 --- a/configs/imx8mn_beacon_2g_defconfig +++ b/configs/imx8mn_beacon_2g_defconfig @@ -5,8 +5,8 @@ CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="imx8mn_beacon" +CONFIG_NR_DRAM_BANKS=1 CONFIG_SF_DEFAULT_SPEED=40000000 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0xFFFFDE00 diff --git a/configs/imx8mn_beacon_defconfig b/configs/imx8mn_beacon_defconfig index ddaea0c68bd..4f77d51ab4b 100644 --- a/configs/imx8mn_beacon_defconfig +++ b/configs/imx8mn_beacon_defconfig @@ -5,8 +5,8 @@ CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="imx8mn_beacon" +CONFIG_NR_DRAM_BANKS=1 CONFIG_SF_DEFAULT_SPEED=40000000 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0xFFFFDE00 diff --git a/configs/imx8mn_beacon_fspi_defconfig b/configs/imx8mn_beacon_fspi_defconfig index 4a49355195a..96c2ed3da71 100644 --- a/configs/imx8mn_beacon_fspi_defconfig +++ b/configs/imx8mn_beacon_fspi_defconfig @@ -5,8 +5,8 @@ CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="imx8mn_beacon" +CONFIG_NR_DRAM_BANKS=1 CONFIG_SF_DEFAULT_SPEED=40000000 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0xFFFFDE00 diff --git a/configs/imx93-phycore_defconfig b/configs/imx93-phycore_defconfig index 4c952e966d1..189d92543d7 100644 --- a/configs/imx93-phycore_defconfig +++ b/configs/imx93-phycore_defconfig @@ -5,10 +5,10 @@ CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x20000 CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_ENV_SOURCE_FILE="phycore_imx93" CONFIG_NR_DRAM_BANKS=2 CONFIG_PHYTEC_SOM_DETECTION=y CONFIG_PHYTEC_EEPROM_BUS=2 -CONFIG_ENV_SOURCE_FILE="phycore_imx93" CONFIG_ENV_SIZE=0x10000 CONFIG_ENV_OFFSET=0x700000 CONFIG_IMX_CONFIG="arch/arm/mach-imx/imx9/imximage.cfg" diff --git a/configs/imx943_evk_defconfig b/configs/imx943_evk_defconfig index 39b616e266e..0371dbe28a9 100644 --- a/configs/imx943_evk_defconfig +++ b/configs/imx943_evk_defconfig @@ -6,8 +6,8 @@ CONFIG_SYS_MALLOC_F_LEN=0x10000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="imx94_evk" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x4000 CONFIG_ENV_OFFSET=0x700000 CONFIG_DM_GPIO=y diff --git a/configs/imx95_15x15_evk_defconfig b/configs/imx95_15x15_evk_defconfig index 96b1d2a64af..f3099f14401 100644 --- a/configs/imx95_15x15_evk_defconfig +++ b/configs/imx95_15x15_evk_defconfig @@ -6,8 +6,8 @@ CONFIG_SYS_MALLOC_F_LEN=0x10000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=3 CONFIG_ENV_SOURCE_FILE="imx95_evk" +CONFIG_NR_DRAM_BANKS=3 CONFIG_SF_DEFAULT_SPEED=40000000 CONFIG_ENV_SIZE=0x4000 CONFIG_ENV_OFFSET=0x700000 diff --git a/configs/imxrt1050-evk_fspi_defconfig b/configs/imxrt1050-evk_fspi_defconfig index cc7e8a3e10b..f213135eb20 100644 --- a/configs/imxrt1050-evk_fspi_defconfig +++ b/configs/imxrt1050-evk_fspi_defconfig @@ -8,8 +8,8 @@ CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="imxrt1050-evk-nor" +CONFIG_NR_DRAM_BANKS=1 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x20020000 CONFIG_ENV_OFFSET=0x80000 diff --git a/configs/mocha_defconfig b/configs/mocha_defconfig index ded43ccea58..19c3693a8c5 100644 --- a/configs/mocha_defconfig +++ b/configs/mocha_defconfig @@ -2,8 +2,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 CONFIG_SYS_MALLOC_LEN=0x2500000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="mocha" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra124-xiaomi-mocha" diff --git a/configs/mot_defconfig b/configs/mot_defconfig index f6066b9e149..fec44ac8f79 100644 --- a/configs/mot_defconfig +++ b/configs/mot_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x00110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="mot" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra20-motorola-olympus" diff --git a/configs/n1_defconfig b/configs/n1_defconfig index 1940a2208a9..15acd675afb 100644 --- a/configs/n1_defconfig +++ b/configs/n1_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x00110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="n1" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra20-samsung-n1" diff --git a/configs/ouya_defconfig b/configs/ouya_defconfig index e82f65a9a86..ed1d1b64395 100644 --- a/configs/ouya_defconfig +++ b/configs/ouya_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="ouya" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra30-ouya" diff --git a/configs/p2771-0000-000_defconfig b/configs/p2771-0000-000_defconfig index 462bec3bae2..24655774374 100644 --- a/configs/p2771-0000-000_defconfig +++ b/configs/p2771-0000-000_defconfig @@ -4,8 +4,8 @@ CONFIG_COUNTER_FREQUENCY=19200000 CONFIG_SYS_L2CACHE_OFF=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80080000 -CONFIG_NR_DRAM_BANKS=1026 CONFIG_ENV_SOURCE_FILE="p2771-0000" +CONFIG_NR_DRAM_BANKS=1026 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0xFFFFE000 CONFIG_DEFAULT_DEVICE_TREE="tegra186-p2771-0000-000" diff --git a/configs/p3450-0000_defconfig b/configs/p3450-0000_defconfig index 2ebcf8b83fc..f6e09ba1fee 100644 --- a/configs/p3450-0000_defconfig +++ b/configs/p3450-0000_defconfig @@ -5,8 +5,8 @@ CONFIG_SYS_L2CACHE_OFF=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80080000 CONFIG_SYS_MALLOC_LEN=0x2500000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="p3450-0000" +CONFIG_NR_DRAM_BANKS=2 CONFIG_SF_DEFAULT_SPEED=24000000 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0xFFFFE000 diff --git a/configs/pg_wcom_expu1_defconfig b/configs/pg_wcom_expu1_defconfig index 321e46e8c52..27e40c87c73 100644 --- a/configs/pg_wcom_expu1_defconfig +++ b/configs/pg_wcom_expu1_defconfig @@ -4,8 +4,8 @@ CONFIG_COUNTER_FREQUENCY=8333333 CONFIG_TARGET_PG_WCOM_EXPU1=y CONFIG_TEXT_BASE=0x60100000 CONFIG_SYS_MALLOC_LEN=0x1004000 -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="pg-wcom-expu1" +CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x4000 CONFIG_ENV_SECT_SIZE=0x20000 CONFIG_DM_GPIO=y diff --git a/configs/pg_wcom_expu1_update_defconfig b/configs/pg_wcom_expu1_update_defconfig index b53af5be52c..6e4925562c3 100644 --- a/configs/pg_wcom_expu1_update_defconfig +++ b/configs/pg_wcom_expu1_update_defconfig @@ -4,8 +4,8 @@ CONFIG_COUNTER_FREQUENCY=8333333 CONFIG_TARGET_PG_WCOM_EXPU1=y CONFIG_TEXT_BASE=0x60240000 CONFIG_SYS_MALLOC_LEN=0x1004000 -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="pg-wcom-expu1" +CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x4000 CONFIG_ENV_SECT_SIZE=0x20000 CONFIG_DM_GPIO=y diff --git a/configs/pg_wcom_seli8_defconfig b/configs/pg_wcom_seli8_defconfig index 561df3ee009..915483fb72a 100644 --- a/configs/pg_wcom_seli8_defconfig +++ b/configs/pg_wcom_seli8_defconfig @@ -4,8 +4,8 @@ CONFIG_COUNTER_FREQUENCY=8333333 CONFIG_TARGET_PG_WCOM_SELI8=y CONFIG_TEXT_BASE=0x60100000 CONFIG_SYS_MALLOC_LEN=0x1004000 -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="pg-wcom-seli8" +CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x4000 CONFIG_ENV_SECT_SIZE=0x20000 CONFIG_DM_GPIO=y diff --git a/configs/pg_wcom_seli8_update_defconfig b/configs/pg_wcom_seli8_update_defconfig index 2a631176095..81ca109facb 100644 --- a/configs/pg_wcom_seli8_update_defconfig +++ b/configs/pg_wcom_seli8_update_defconfig @@ -4,8 +4,8 @@ CONFIG_COUNTER_FREQUENCY=8333333 CONFIG_TARGET_PG_WCOM_SELI8=y CONFIG_TEXT_BASE=0x60240000 CONFIG_SYS_MALLOC_LEN=0x1004000 -CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SOURCE_FILE="pg-wcom-seli8" +CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x4000 CONFIG_ENV_SECT_SIZE=0x20000 CONFIG_DM_GPIO=y diff --git a/configs/picasso_defconfig b/configs/picasso_defconfig index 9d153694245..ddc51c5b55c 100644 --- a/configs/picasso_defconfig +++ b/configs/picasso_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x00110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="picasso" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra20-acer-a500-picasso" diff --git a/configs/qc750_defconfig b/configs/qc750_defconfig index 2be3838ae60..3db8550266b 100644 --- a/configs/qc750_defconfig +++ b/configs/qc750_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="qc750" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra30-wexler-qc750" diff --git a/configs/socfpga_cyclone5_defconfig b/configs/socfpga_cyclone5_defconfig index f1bf0aec015..992abdbfdc4 100644 --- a/configs/socfpga_cyclone5_defconfig +++ b/configs/socfpga_cyclone5_defconfig @@ -12,8 +12,8 @@ CONFIG_DM_RESET=y CONFIG_SPL_STACK=0x0 CONFIG_SPL_TEXT_BASE=0xFFFF0000 CONFIG_TARGET_SOCFPGA_CYCLONE5_SOCDK=y -# CONFIG_SPL_SPI is not set CONFIG_SPL_FS_FAT=y +# CONFIG_SPL_SPI is not set CONFIG_TIMESTAMP=y CONFIG_FIT=y CONFIG_DISTRO_DEFAULTS=y @@ -30,8 +30,6 @@ CONFIG_SPL_NO_BSS_LIMIT=y # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_HAVE_INIT_STACK=y # CONFIG_SPL_SYS_MMCSD_RAW_MODE is not set -CONFIG_SPL_SPI_LOAD=y -CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000 CONFIG_SYS_MAXARGS=32 CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y diff --git a/configs/star_defconfig b/configs/star_defconfig index 59eabdcb2b4..f2cdcf066c0 100644 --- a/configs/star_defconfig +++ b/configs/star_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x00110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="star" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra20-lg-star" diff --git a/configs/surface-2_defconfig b/configs/surface-2_defconfig index d3e6166cf89..5ec0d234fe3 100644 --- a/configs/surface-2_defconfig +++ b/configs/surface-2_defconfig @@ -2,8 +2,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 CONFIG_SYS_MALLOC_LEN=0x2500000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="surface-2" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra114-microsoft-surface-2-0b" diff --git a/configs/surface-rt_defconfig b/configs/surface-rt_defconfig index 88b67749095..6e3752c72a3 100644 --- a/configs/surface-rt_defconfig +++ b/configs/surface-rt_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="surface-rt" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra30-microsoft-surface-rt" diff --git a/configs/tegratab_defconfig b/configs/tegratab_defconfig index 27cb75c92b5..d2596453d8d 100644 --- a/configs/tegratab_defconfig +++ b/configs/tegratab_defconfig @@ -2,8 +2,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 CONFIG_SYS_MALLOC_LEN=0x2500000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="tegratab" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra114-nvidia-tegratab" diff --git a/configs/tf701t_defconfig b/configs/tf701t_defconfig index e8f920587c3..abed3d65baf 100644 --- a/configs/tf701t_defconfig +++ b/configs/tf701t_defconfig @@ -2,8 +2,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 CONFIG_SYS_MALLOC_LEN=0x2500000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="transformer-t114" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra114-asus-tf701t" diff --git a/configs/transformer_t20_defconfig b/configs/transformer_t20_defconfig index 61eab59fa3b..251bc955beb 100644 --- a/configs/transformer_t20_defconfig +++ b/configs/transformer_t20_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x00110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="transformer-t20" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra20-asus-tf101" diff --git a/configs/transformer_t30_defconfig b/configs/transformer_t30_defconfig index 6f8953aa103..fb1900299b1 100644 --- a/configs/transformer_t30_defconfig +++ b/configs/transformer_t30_defconfig @@ -1,8 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_TEGRA=y CONFIG_TEXT_BASE=0x80110000 -CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SOURCE_FILE="transformer-t30" +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x3000 CONFIG_ENV_OFFSET=0xFFFFD000 CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-tf201" -- cgit v1.3.1 From 976c1cb85ffaf9d35d002d20c9afb585d8aebabd Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Sat, 6 Dec 2025 10:50:34 -0600 Subject: doc: Update urllib3 version for building The GitHub dependabot tool has reported two "high" priority bugs, CVE-2025-66418 and CVE-2025-66471, with this package. Update to the patched version. Reported-by: GitHub dependabot Acked-by: Heinrich Schuchardt Signed-off-by: Tom Rini --- doc/sphinx/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx/requirements.txt b/doc/sphinx/requirements.txt index 8572c15ef68..dd433e2bb15 100644 --- a/doc/sphinx/requirements.txt +++ b/doc/sphinx/requirements.txt @@ -24,4 +24,4 @@ sphinxcontrib-jquery==4.1 sphinxcontrib-jsmath==1.0.1 sphinxcontrib-qthelp==2.0.0 sphinxcontrib-serializinghtml==2.0.0 -urllib3==2.5.0 +urllib3==2.6.0 -- cgit v1.3.1 From ae184121e00b131b84c04885cecfded18e320a8d Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Sun, 7 Dec 2025 08:50:28 -0600 Subject: omap3_evm: Take over maintainership After talking with Derald, take over the maintainership role for this platform. Signed-off-by: Tom Rini --- board/ti/omap3evm/MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/ti/omap3evm/MAINTAINERS b/board/ti/omap3evm/MAINTAINERS index fb4268b312f..491ab4fbed7 100644 --- a/board/ti/omap3evm/MAINTAINERS +++ b/board/ti/omap3evm/MAINTAINERS @@ -1,5 +1,5 @@ EVM BOARD -M: Derald D. Woods +M: Tom Rini S: Maintained F: board/ti/omap3evm/ F: include/configs/omap3_evm.h -- cgit v1.3.1 From f2c148e0df3a50c74130b4cd0c9bd3d02ba375b2 Mon Sep 17 00:00:00 2001 From: Pranav Tilak Date: Mon, 8 Dec 2025 14:54:24 +0100 Subject: arm64: versal: Fix LTO for mini_ospi/mini_qspi With LTO enabled, mini U-Boot was hanging during reloc_fdt(). The initial stack pointer was placed too low, and the FDT memcpy destination was carved only 4KB above it. This left insufficient margin, causing the FDT copy to overwrite the live early stack and corrupt execution before relocation. To fix this, increase the malloc heap from 8KB to 12KB and raise the initial stack pointer by 4KB. Together these adjustments increase the separation between the early stack and the FDT region during the pre-relocation phase, eliminating the overlap and fixing the hang on mini builds (QSPI/OSPI). Signed-off-by: Pranav Tilak Signed-off-by: Michal Simek --- configs/xilinx_versal_mini_ospi_defconfig | 4 ++-- configs/xilinx_versal_mini_qspi_defconfig | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configs/xilinx_versal_mini_ospi_defconfig b/configs/xilinx_versal_mini_ospi_defconfig index 11811f3c0fd..eb101d03973 100644 --- a/configs/xilinx_versal_mini_ospi_defconfig +++ b/configs/xilinx_versal_mini_ospi_defconfig @@ -3,11 +3,11 @@ CONFIG_SYS_CONFIG_NAME="xilinx_versal_mini" CONFIG_COUNTER_FREQUENCY=100000000 CONFIG_ARCH_VERSAL=y CONFIG_TEXT_BASE=0xFFFC0000 -CONFIG_SYS_MALLOC_LEN=0x2000 +CONFIG_SYS_MALLOC_LEN=0x3000 CONFIG_SYS_MALLOC_F_LEN=0x500 CONFIG_NR_DRAM_BANKS=1 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xFFFE1000 +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xFFFE2000 CONFIG_SF_DEFAULT_SPEED=30000000 CONFIG_ENV_SIZE=0x80 # CONFIG_DM_GPIO is not set diff --git a/configs/xilinx_versal_mini_qspi_defconfig b/configs/xilinx_versal_mini_qspi_defconfig index 47737ce0f8f..20fab6931c3 100644 --- a/configs/xilinx_versal_mini_qspi_defconfig +++ b/configs/xilinx_versal_mini_qspi_defconfig @@ -3,10 +3,10 @@ CONFIG_SYS_CONFIG_NAME="xilinx_versal_mini" CONFIG_COUNTER_FREQUENCY=100000000 CONFIG_ARCH_VERSAL=y CONFIG_TEXT_BASE=0xFFFC0000 -CONFIG_SYS_MALLOC_LEN=0x2000 +CONFIG_SYS_MALLOC_LEN=0x3000 CONFIG_NR_DRAM_BANKS=1 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xFFFE0000 +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xFFFE2000 CONFIG_SF_DEFAULT_SPEED=30000000 CONFIG_ENV_SIZE=0x80 CONFIG_DEFAULT_DEVICE_TREE="versal-mini-qspi-single" -- cgit v1.3.1 From 543900ab530a4c65d0130c10b001378c3290107b Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Mon, 8 Dec 2025 18:17:08 +0000 Subject: MAINTAINERS: update my email address My old mail address, ziyao@disroot.org, has stopped working. Switch to my new address, me@ziyao.cc, and map it in .mailmap. Signed-off-by: Yao Zi --- .mailmap | 1 + MAINTAINERS | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index 0e01452a70c..7b0d730b618 100644 --- a/.mailmap +++ b/.mailmap @@ -159,6 +159,7 @@ Wolfgang Denk Wolfgang Denk Wolfgang Denk Wolfgang Wallner +Yao Zi York Sun York Sun Łukasz Majewski diff --git a/MAINTAINERS b/MAINTAINERS index 1789f023631..6ce0bbce13d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1605,7 +1605,7 @@ F: drivers/pinctrl/pinctrl-k210.c F: include/k210/ RISC-V T-HEAD TH1520 -M: Yao Zi +M: Yao Zi S: Maintained F: arch/riscv/cpu/th1520/ F: drivers/clk/thead/clk-th1520-ap.c -- cgit v1.3.1 From 0e0a198a68be71148f5ec27ef86796174f91436f Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 8 Dec 2025 12:54:47 -0600 Subject: Prepare v2026.01-rc4 Signed-off-by: Tom Rini --- Makefile | 2 +- doc/develop/release_cycle.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1a613e70b27..571c07e0e9c 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ VERSION = 2026 PATCHLEVEL = 01 SUBLEVEL = -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = # *DOCUMENTATION* diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst index 56cbfcb4b65..be6b09b250e 100644 --- a/doc/develop/release_cycle.rst +++ b/doc/develop/release_cycle.rst @@ -77,7 +77,7 @@ For the next scheduled release, release candidates were made on: * U-Boot |next_ver|-rc3 was released on Mon 24 November 2025. -.. * U-Boot |next_ver|-rc4 was released on Mon 08 December 2025. +* U-Boot |next_ver|-rc4 was released on Mon 08 December 2025. .. * U-Boot |next_ver|-rc5 was released on Tue 22 December 2025. -- cgit v1.3.1