RE: [PATCH] mmc: fsl_esdhc: Fix 'Internal clock never stabilised.' error
+Yangbo > -Original Message- > From: Peng Fan (OSS) > Sent: 2022年5月9日 13:37 > To: Pali Rohár ; Peng Fan ; Priyanka Jain > ; Jaehoon Chung ; Sinan > Akman ; Bough Chen > Cc: u-boot@lists.denx.de > Subject: Re: [PATCH] mmc: fsl_esdhc: Fix 'Internal clock never stabilised.' > error > > +Haibo > > On 2022/4/30 2:27, Pali Rohár wrote: > > Only newer eSDHC controllers set PRSSTAT_SDSTB flag. So do not wait > > until flag PRSSTAT_SDSTB is set on old pre-2.2 controllers. Instead > > sleep for fixed amount of time like it was before commit 6f883e501b65 > ("mmc: > > fsl_esdhc: Add emmc hs200 support"). > > > > This change fixes error 'Internal clock never stabilised.' which is > > printed on P2020 board at every access to SD card. > > > > Fixes: 6f883e501b65 ("mmc: fsl_esdhc: Add emmc hs200 support") > > Signed-off-by: Pali Rohár > > --- > > drivers/mmc/fsl_esdhc.c | 17 + > > 1 file changed, 17 insertions(+) > > > > diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index > > fdf2cc290e06..3b3587bd8d72 100644 > > --- a/drivers/mmc/fsl_esdhc.c > > +++ b/drivers/mmc/fsl_esdhc.c > > @@ -503,6 +503,7 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, > > struct > mmc *mmc, uint clock) > > u32 time_out; > > u32 value; > > uint clk; > > + u32 hostver; > > > > if (clock < mmc->cfg->f_min) > > clock = mmc->cfg->f_min; > > @@ -543,6 +544,14 @@ static void set_sysctl(struct fsl_esdhc_priv > > *priv, struct mmc *mmc, uint clock) > > > > esdhc_clrsetbits32(®s->sysctl, SYSCTL_CLOCK_MASK, clk); > > > > + /* Only newer eSDHC controllers set PRSSTAT_SDSTB flag */ > > + hostver = esdhc_read32(&priv->esdhc_regs->hostver); > > + if (HOSTVER_VENDOR(hostver) <= VENDOR_V_22) { > > + udelay(1); > > + esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_CKEN); > > + return; > > + } > > + > > time_out = 20; > > value = PRSSTAT_SDSTB; > > while (!(esdhc_read32(®s->prsstat) & value)) { @@ -562,6 +571,7 > > @@ static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable) > > struct fsl_esdhc *regs = priv->esdhc_regs; > > u32 value; > > u32 time_out; > > + u32 hostver; > > > > value = esdhc_read32(®s->sysctl); > > > > @@ -572,6 +582,13 @@ static void esdhc_clock_control(struct > > fsl_esdhc_priv *priv, bool enable) > > > > esdhc_write32(®s->sysctl, value); > > > > + /* Only newer eSDHC controllers set PRSSTAT_SDSTB flag */ > > + hostver = esdhc_read32(&priv->esdhc_regs->hostver); > > + if (HOSTVER_VENDOR(hostver) <= VENDOR_V_22) { > > + udelay(1); > > + return; > > + } > > + > > time_out = 20; > > value = PRSSTAT_SDSTB; > > while (!(esdhc_read32(®s->prsstat) & value)) { > >
Re: [PATCH] mmc: fsl_esdhc: Fix 'Internal clock never stabilised.' error
+Haibo On 2022/4/30 2:27, Pali Rohár wrote: Only newer eSDHC controllers set PRSSTAT_SDSTB flag. So do not wait until flag PRSSTAT_SDSTB is set on old pre-2.2 controllers. Instead sleep for fixed amount of time like it was before commit 6f883e501b65 ("mmc: fsl_esdhc: Add emmc hs200 support"). This change fixes error 'Internal clock never stabilised.' which is printed on P2020 board at every access to SD card. Fixes: 6f883e501b65 ("mmc: fsl_esdhc: Add emmc hs200 support") Signed-off-by: Pali Rohár --- drivers/mmc/fsl_esdhc.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index fdf2cc290e06..3b3587bd8d72 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -503,6 +503,7 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock) u32 time_out; u32 value; uint clk; + u32 hostver; if (clock < mmc->cfg->f_min) clock = mmc->cfg->f_min; @@ -543,6 +544,14 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock) esdhc_clrsetbits32(®s->sysctl, SYSCTL_CLOCK_MASK, clk); + /* Only newer eSDHC controllers set PRSSTAT_SDSTB flag */ + hostver = esdhc_read32(&priv->esdhc_regs->hostver); + if (HOSTVER_VENDOR(hostver) <= VENDOR_V_22) { + udelay(1); + esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_CKEN); + return; + } + time_out = 20; value = PRSSTAT_SDSTB; while (!(esdhc_read32(®s->prsstat) & value)) { @@ -562,6 +571,7 @@ static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable) struct fsl_esdhc *regs = priv->esdhc_regs; u32 value; u32 time_out; + u32 hostver; value = esdhc_read32(®s->sysctl); @@ -572,6 +582,13 @@ static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable) esdhc_write32(®s->sysctl, value); + /* Only newer eSDHC controllers set PRSSTAT_SDSTB flag */ + hostver = esdhc_read32(&priv->esdhc_regs->hostver); + if (HOSTVER_VENDOR(hostver) <= VENDOR_V_22) { + udelay(1); + return; + } + time_out = 20; value = PRSSTAT_SDSTB; while (!(esdhc_read32(®s->prsstat) & value)) {
Re: [PATCH] efi_loader: disk: allow blk devices even without UCLASS_PARTITION
Simon, On Thu, Apr 28, 2022 at 12:43:03PM +0200, Heinrich Schuchardt wrote: > On 4/28/22 06:49, AKASHI Takahiro wrote: > > While GPT partition is mandated in UEFI specification, CONFIG_PARTITION is > > seen optional under the current implementation. > > So modify efi_disk_rw_blocks() to allow accepting UCLASS_BLK devices. > > > > Fixes: commit d97e98c887ed ("efi_loader: disk: use udevice instead of > > blk_desc") > > Signed-off-by: AKASHI Takahiro > > --- > > lib/efi_loader/efi_disk.c | 29 +++-- > > 1 file changed, 15 insertions(+), 14 deletions(-) > > > > diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c > > index 8fb5b2363c45..f5b462fb164a 100644 > > --- a/lib/efi_loader/efi_disk.c > > +++ b/lib/efi_loader/efi_disk.c > > @@ -99,21 +99,22 @@ static efi_status_t efi_disk_rw_blocks(struct > > efi_block_io *this, > > if (buffer_size & (blksz - 1)) > > return EFI_BAD_BUFFER_SIZE; > > > > -#if CONFIG_IS_ENABLED(PARTITIONS) > > - if (direction == EFI_DISK_READ) > > - n = dev_read(diskobj->dev, lba, blocks, buffer); > > - else > > - n = dev_write(diskobj->dev, lba, blocks, buffer); > > -#else > > - /* dev is always a block device (UCLASS_BLK) */ > > - struct blk_desc *desc; > > + if (CONFIG_IS_ENABLED(PARTITIONS) && > > + device_get_uclass_id(diskobj->dev) == UCLASS_PARTITION) { > > + if (direction == EFI_DISK_READ) > > + n = dev_read(diskobj->dev, lba, blocks, buffer); > > + else > > + n = dev_write(diskobj->dev, lba, blocks, buffer); > > Thanks for the patch. It solves the problem with the block IO protocol. > > Why should dev_read() and dev_write only work for UCLASS_PARTITION? I don't remember well, but I have expected that even a whole disk be represented as a partition (0). > Can't we make it work for any block device? I think the treatment of > different types of block devices should be moved to disk/disk-uclass.c. @Simon, what are your thoughts? -Takahiro Akashi > I will pull this patch as a fast fix. But this should not be the final > design. > > Reviewed-by: Heinrich Schuchardt > > > + } else { > > + /* dev is a block device (UCLASS_BLK) */ > > + struct blk_desc *desc; > > > > - desc = dev_get_uclass_plat(diskobj->dev); > > - if (direction == EFI_DISK_READ) > > - n = blk_dread(desc, lba, blocks, buffer); > > - else > > - n = blk_dwrite(desc, lba, blocks, buffer); > > -#endif > > + desc = dev_get_uclass_plat(diskobj->dev); > > + if (direction == EFI_DISK_READ) > > + n = blk_dread(desc, lba, blocks, buffer); > > + else > > + n = blk_dwrite(desc, lba, blocks, buffer); > > + } > > > > /* We don't do interrupts, so check for timers cooperatively */ > > efi_timer_check(); >
[PATCH 7/7] reset: sunxi: Reuse the platform data from the clock driver
The clock and reset drivers use the exact same platform data. Simplify them by sharing the object. This is safe because the parent device (the clock device) always gets its driver model callbacks run first. Signed-off-by: Samuel Holland --- drivers/clk/sunxi/clk_sunxi.c | 7 +- drivers/reset/reset-sunxi.c | 43 +++ include/clk/sunxi.h | 8 --- 3 files changed, 9 insertions(+), 49 deletions(-) diff --git a/drivers/clk/sunxi/clk_sunxi.c b/drivers/clk/sunxi/clk_sunxi.c index cadfca767b..10c5d2f4b6 100644 --- a/drivers/clk/sunxi/clk_sunxi.c +++ b/drivers/clk/sunxi/clk_sunxi.c @@ -12,9 +12,12 @@ #include #include #include +#include #include #include +extern U_BOOT_DRIVER(sunxi_reset); + static const struct ccu_clk_gate *plat_to_gate(struct ccu_plat *plat, unsigned long id) { @@ -66,7 +69,9 @@ struct clk_ops sunxi_clk_ops = { static int sunxi_clk_bind(struct udevice *dev) { - return sunxi_reset_bind(dev); + /* Reuse the platform data for the reset driver. */ + return device_bind(dev, DM_DRIVER_REF(sunxi_reset), "reset", + dev_get_plat(dev), dev_ofnode(dev), NULL); } static int sunxi_clk_probe(struct udevice *dev) diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index b060d7f5ed..5d4b8dc92f 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c @@ -12,17 +12,10 @@ #include #include #include -#include -#include #include #include -struct sunxi_reset_plat { - void *base; - const struct ccu_desc *desc; -}; - -static const struct ccu_reset *plat_to_reset(struct sunxi_reset_plat *plat, +static const struct ccu_reset *plat_to_reset(struct ccu_plat *plat, unsigned long id) { return &plat->desc->resets[id]; @@ -30,7 +23,7 @@ static const struct ccu_reset *plat_to_reset(struct sunxi_reset_plat *plat, static int sunxi_reset_request(struct reset_ctl *reset_ctl) { - struct sunxi_reset_plat *plat = dev_get_plat(reset_ctl->dev); + struct ccu_plat *plat = dev_get_plat(reset_ctl->dev); debug("%s: (RST#%ld)\n", __func__, reset_ctl->id); @@ -49,7 +42,7 @@ static int sunxi_reset_free(struct reset_ctl *reset_ctl) static int sunxi_set_reset(struct reset_ctl *reset_ctl, bool on) { - struct sunxi_reset_plat *plat = dev_get_plat(reset_ctl->dev); + struct ccu_plat *plat = dev_get_plat(reset_ctl->dev); const struct ccu_reset *reset = plat_to_reset(plat, reset_ctl->id); u32 reg; @@ -89,38 +82,8 @@ struct reset_ops sunxi_reset_ops = { .rst_deassert = sunxi_reset_deassert, }; -static int sunxi_reset_of_to_plat(struct udevice *dev) -{ - struct sunxi_reset_plat *plat = dev_get_plat(dev); - - plat->base = dev_read_addr_ptr(dev); - - return 0; -} - -int sunxi_reset_bind(struct udevice *dev) -{ - struct udevice *rst_dev; - struct sunxi_reset_plat *plat; - int ret; - - ret = device_bind_driver_to_node(dev, "sunxi_reset", "reset", -dev_ofnode(dev), &rst_dev); - if (ret) { - debug("failed to bind sunxi_reset driver (ret=%d)\n", ret); - return ret; - } - plat = malloc(sizeof(struct sunxi_reset_plat)); - plat->desc = (const struct ccu_desc *)dev_get_driver_data(dev); - dev_set_plat(rst_dev, plat); - - return 0; -} - U_BOOT_DRIVER(sunxi_reset) = { .name = "sunxi_reset", .id = UCLASS_RESET, .ops= &sunxi_reset_ops, - .of_to_plat = sunxi_reset_of_to_plat, - .plat_auto = sizeof(struct sunxi_reset_plat), }; diff --git a/include/clk/sunxi.h b/include/clk/sunxi.h index e90e078972..b9587050d9 100644 --- a/include/clk/sunxi.h +++ b/include/clk/sunxi.h @@ -82,12 +82,4 @@ struct ccu_plat { extern struct clk_ops sunxi_clk_ops; -/** - * sunxi_reset_bind() - reset binding - * - * @dev: reset device - * Return: 0 success, or error value - */ -int sunxi_reset_bind(struct udevice *dev); - #endif /* _CLK_SUNXI_H */ -- 2.35.1
[PATCH 6/7] reset: sunxi: Convert driver private data to platform data
The reason here is the same as the reason for changing the clock driver: platform data can be provided when binding the driver. Signed-off-by: Samuel Holland --- drivers/reset/reset-sunxi.c | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index 4d02d02834..b060d7f5ed 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c @@ -17,24 +17,24 @@ #include #include -struct sunxi_reset_priv { +struct sunxi_reset_plat { void *base; const struct ccu_desc *desc; }; -static const struct ccu_reset *priv_to_reset(struct sunxi_reset_priv *priv, +static const struct ccu_reset *plat_to_reset(struct sunxi_reset_plat *plat, unsigned long id) { - return &priv->desc->resets[id]; + return &plat->desc->resets[id]; } static int sunxi_reset_request(struct reset_ctl *reset_ctl) { - struct sunxi_reset_priv *priv = dev_get_priv(reset_ctl->dev); + struct sunxi_reset_plat *plat = dev_get_plat(reset_ctl->dev); debug("%s: (RST#%ld)\n", __func__, reset_ctl->id); - if (reset_ctl->id >= priv->desc->num_resets) + if (reset_ctl->id >= plat->desc->num_resets) return -EINVAL; return 0; @@ -49,8 +49,8 @@ static int sunxi_reset_free(struct reset_ctl *reset_ctl) static int sunxi_set_reset(struct reset_ctl *reset_ctl, bool on) { - struct sunxi_reset_priv *priv = dev_get_priv(reset_ctl->dev); - const struct ccu_reset *reset = priv_to_reset(priv, reset_ctl->id); + struct sunxi_reset_plat *plat = dev_get_plat(reset_ctl->dev); + const struct ccu_reset *reset = plat_to_reset(plat, reset_ctl->id); u32 reg; if (!(reset->flags & CCU_RST_F_IS_VALID)) { @@ -61,13 +61,13 @@ static int sunxi_set_reset(struct reset_ctl *reset_ctl, bool on) debug("%s: (RST#%ld) off#0x%x, BIT(%d)\n", __func__, reset_ctl->id, reset->off, ilog2(reset->bit)); - reg = readl(priv->base + reset->off); + reg = readl(plat->base + reset->off); if (on) reg |= reset->bit; else reg &= ~reset->bit; - writel(reg, priv->base + reset->off); + writel(reg, plat->base + reset->off); return 0; } @@ -89,11 +89,11 @@ struct reset_ops sunxi_reset_ops = { .rst_deassert = sunxi_reset_deassert, }; -static int sunxi_reset_probe(struct udevice *dev) +static int sunxi_reset_of_to_plat(struct udevice *dev) { - struct sunxi_reset_priv *priv = dev_get_priv(dev); + struct sunxi_reset_plat *plat = dev_get_plat(dev); - priv->base = dev_read_addr_ptr(dev); + plat->base = dev_read_addr_ptr(dev); return 0; } @@ -101,7 +101,7 @@ static int sunxi_reset_probe(struct udevice *dev) int sunxi_reset_bind(struct udevice *dev) { struct udevice *rst_dev; - struct sunxi_reset_priv *priv; + struct sunxi_reset_plat *plat; int ret; ret = device_bind_driver_to_node(dev, "sunxi_reset", "reset", @@ -110,9 +110,9 @@ int sunxi_reset_bind(struct udevice *dev) debug("failed to bind sunxi_reset driver (ret=%d)\n", ret); return ret; } - priv = malloc(sizeof(struct sunxi_reset_priv)); - priv->desc = (const struct ccu_desc *)dev_get_driver_data(dev); - dev_set_priv(rst_dev, priv); + plat = malloc(sizeof(struct sunxi_reset_plat)); + plat->desc = (const struct ccu_desc *)dev_get_driver_data(dev); + dev_set_plat(rst_dev, plat); return 0; } @@ -121,6 +121,6 @@ U_BOOT_DRIVER(sunxi_reset) = { .name = "sunxi_reset", .id = UCLASS_RESET, .ops= &sunxi_reset_ops, - .probe = sunxi_reset_probe, - .priv_auto = sizeof(struct sunxi_reset_priv), + .of_to_plat = sunxi_reset_of_to_plat, + .plat_auto = sizeof(struct sunxi_reset_plat), }; -- 2.35.1
[PATCH 4/7] clk: sunxi: Use a single driver for all variants
Now that all of the variants use the same bind/probe functions and ops, there is no need to have a separate driver for each variant. Since most SoCs contain two variants (the main CCU and PRCM CCU), this saves a bit of firmware size and RAM. Signed-off-by: Samuel Holland --- drivers/clk/sunxi/clk_a10.c | 20 +- drivers/clk/sunxi/clk_a10s.c | 20 +- drivers/clk/sunxi/clk_a23.c | 20 +- drivers/clk/sunxi/clk_a31.c | 18 +- drivers/clk/sunxi/clk_a31_r.c | 22 +-- drivers/clk/sunxi/clk_a64.c | 18 +- drivers/clk/sunxi/clk_a80.c | 22 +-- drivers/clk/sunxi/clk_a83t.c | 18 +- drivers/clk/sunxi/clk_h3.c| 20 +- drivers/clk/sunxi/clk_h6.c| 18 +- drivers/clk/sunxi/clk_h616.c | 18 +- drivers/clk/sunxi/clk_h6_r.c | 20 +- drivers/clk/sunxi/clk_r40.c | 18 +- drivers/clk/sunxi/clk_sunxi.c | 118 +- drivers/clk/sunxi/clk_v3s.c | 20 +- include/clk/sunxi.h | 12 16 files changed, 131 insertions(+), 271 deletions(-) diff --git a/drivers/clk/sunxi/clk_a10.c b/drivers/clk/sunxi/clk_a10.c index e5374f6cf0..4752a1167b 100644 --- a/drivers/clk/sunxi/clk_a10.c +++ b/drivers/clk/sunxi/clk_a10.c @@ -62,27 +62,9 @@ static struct ccu_reset a10_resets[] = { [RST_USB_PHY2] = RESET(0x0cc, BIT(2)), }; -static const struct ccu_desc a10_ccu_desc = { +const struct ccu_desc a10_ccu_desc = { .gates = a10_gates, .resets = a10_resets, .num_gates = ARRAY_SIZE(a10_gates), .num_resets = ARRAY_SIZE(a10_resets), }; - -static const struct udevice_id a10_ccu_ids[] = { - { .compatible = "allwinner,sun4i-a10-ccu", - .data = (ulong)&a10_ccu_desc }, - { .compatible = "allwinner,sun7i-a20-ccu", - .data = (ulong)&a10_ccu_desc }, - { } -}; - -U_BOOT_DRIVER(clk_sun4i_a10) = { - .name = "sun4i_a10_ccu", - .id = UCLASS_CLK, - .of_match = a10_ccu_ids, - .priv_auto = sizeof(struct ccu_priv), - .ops= &sunxi_clk_ops, - .probe = sunxi_clk_probe, - .bind = sunxi_clk_bind, -}; diff --git a/drivers/clk/sunxi/clk_a10s.c b/drivers/clk/sunxi/clk_a10s.c index 07d518c121..9619c5f935 100644 --- a/drivers/clk/sunxi/clk_a10s.c +++ b/drivers/clk/sunxi/clk_a10s.c @@ -47,27 +47,9 @@ static struct ccu_reset a10s_resets[] = { [RST_USB_PHY1] = RESET(0x0cc, BIT(1)), }; -static const struct ccu_desc a10s_ccu_desc = { +const struct ccu_desc a10s_ccu_desc = { .gates = a10s_gates, .resets = a10s_resets, .num_gates = ARRAY_SIZE(a10s_gates), .num_resets = ARRAY_SIZE(a10s_resets), }; - -static const struct udevice_id a10s_ccu_ids[] = { - { .compatible = "allwinner,sun5i-a10s-ccu", - .data = (ulong)&a10s_ccu_desc }, - { .compatible = "allwinner,sun5i-a13-ccu", - .data = (ulong)&a10s_ccu_desc }, - { } -}; - -U_BOOT_DRIVER(clk_sun5i_a10s) = { - .name = "sun5i_a10s_ccu", - .id = UCLASS_CLK, - .of_match = a10s_ccu_ids, - .priv_auto = sizeof(struct ccu_priv), - .ops= &sunxi_clk_ops, - .probe = sunxi_clk_probe, - .bind = sunxi_clk_bind, -}; diff --git a/drivers/clk/sunxi/clk_a23.c b/drivers/clk/sunxi/clk_a23.c index 9c0e5db07c..5e19c11c23 100644 --- a/drivers/clk/sunxi/clk_a23.c +++ b/drivers/clk/sunxi/clk_a23.c @@ -66,27 +66,9 @@ static struct ccu_reset a23_resets[] = { [RST_BUS_UART4] = RESET(0x2d8, BIT(20)), }; -static const struct ccu_desc a23_ccu_desc = { +const struct ccu_desc a23_ccu_desc = { .gates = a23_gates, .resets = a23_resets, .num_gates = ARRAY_SIZE(a23_gates), .num_resets = ARRAY_SIZE(a23_resets), }; - -static const struct udevice_id a23_clk_ids[] = { - { .compatible = "allwinner,sun8i-a23-ccu", - .data = (ulong)&a23_ccu_desc }, - { .compatible = "allwinner,sun8i-a33-ccu", - .data = (ulong)&a23_ccu_desc }, - { } -}; - -U_BOOT_DRIVER(clk_sun8i_a23) = { - .name = "sun8i_a23_ccu", - .id = UCLASS_CLK, - .of_match = a23_clk_ids, - .priv_auto = sizeof(struct ccu_priv), - .ops= &sunxi_clk_ops, - .probe = sunxi_clk_probe, - .bind = sunxi_clk_bind, -}; diff --git a/drivers/clk/sunxi/clk_a31.c b/drivers/clk/sunxi/clk_a31.c index 3d0767e290..0f58ea 100644 --- a/drivers/clk/sunxi/clk_a31.c +++ b/drivers/clk/sunxi/clk_a31.c @@ -87,25 +87,9 @@ static struct ccu_reset a31_resets[] = { [RST_APB2_UART5]= RESET(0x2d8, BIT(21)), }; -static const struct ccu_desc a31_ccu_desc = { +const struct ccu_desc a31_ccu_desc = { .gates = a31_gates, .resets = a31_resets, .num_gates = ARRAY_SIZE(a31_gates), .num_resets = ARRAY_SIZE(a31_reset
[PATCH 5/7] clk: sunxi: Convert driver private data to platform data
All of the driver private data should really be platform data since it is determined statically (selected by the compatible string or extracted from the devicetree). Move everything to platform data, so it can be provided when binding the driver. This is useful for SPL, or for instantiating the driver as part of an MFD. Signed-off-by: Samuel Holland --- drivers/clk/sunxi/clk_sunxi.c | 41 --- include/clk/sunxi.h | 4 ++-- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/clk/sunxi/clk_sunxi.c b/drivers/clk/sunxi/clk_sunxi.c index 7d9e6029ff..cadfca767b 100644 --- a/drivers/clk/sunxi/clk_sunxi.c +++ b/drivers/clk/sunxi/clk_sunxi.c @@ -15,19 +15,19 @@ #include #include -static const struct ccu_clk_gate *priv_to_gate(struct ccu_priv *priv, +static const struct ccu_clk_gate *plat_to_gate(struct ccu_plat *plat, unsigned long id) { - if (id >= priv->desc->num_gates) + if (id >= plat->desc->num_gates) return NULL; - return &priv->desc->gates[id]; + return &plat->desc->gates[id]; } static int sunxi_set_gate(struct clk *clk, bool on) { - struct ccu_priv *priv = dev_get_priv(clk->dev); - const struct ccu_clk_gate *gate = priv_to_gate(priv, clk->id); + struct ccu_plat *plat = dev_get_plat(clk->dev); + const struct ccu_clk_gate *gate = plat_to_gate(plat, clk->id); u32 reg; if (!gate || !(gate->flags & CCU_CLK_F_IS_VALID)) { @@ -38,13 +38,13 @@ static int sunxi_set_gate(struct clk *clk, bool on) debug("%s: (CLK#%ld) off#0x%x, BIT(%d)\n", __func__, clk->id, gate->off, ilog2(gate->bit)); - reg = readl(priv->base + gate->off); + reg = readl(plat->base + gate->off); if (on) reg |= gate->bit; else reg &= ~gate->bit; - writel(reg, priv->base + gate->off); + writel(reg, plat->base + gate->off); return 0; } @@ -71,19 +71,10 @@ static int sunxi_clk_bind(struct udevice *dev) static int sunxi_clk_probe(struct udevice *dev) { - struct ccu_priv *priv = dev_get_priv(dev); struct clk_bulk clk_bulk; struct reset_ctl_bulk rst_bulk; int ret; - priv->base = dev_read_addr_ptr(dev); - if (!priv->base) - return -ENOMEM; - - priv->desc = (const struct ccu_desc *)dev_get_driver_data(dev); - if (!priv->desc) - return -EINVAL; - ret = clk_get_bulk(dev, &clk_bulk); if (!ret) clk_enable_bulk(&clk_bulk); @@ -95,6 +86,21 @@ static int sunxi_clk_probe(struct udevice *dev) return 0; } +static int sunxi_clk_of_to_plat(struct udevice *dev) +{ + struct ccu_plat *plat = dev_get_plat(dev); + + plat->base = dev_read_addr_ptr(dev); + if (!plat->base) + return -ENOMEM; + + plat->desc = (const struct ccu_desc *)dev_get_driver_data(dev); + if (!plat->desc) + return -EINVAL; + + return 0; +} + extern const struct ccu_desc a10_ccu_desc; extern const struct ccu_desc a10s_ccu_desc; extern const struct ccu_desc a23_ccu_desc; @@ -205,6 +211,7 @@ U_BOOT_DRIVER(sunxi_clk) = { .of_match = sunxi_clk_ids, .bind = sunxi_clk_bind, .probe = sunxi_clk_probe, - .priv_auto = sizeof(struct ccu_priv), + .of_to_plat = sunxi_clk_of_to_plat, + .plat_auto = sizeof(struct ccu_plat), .ops= &sunxi_clk_ops, }; diff --git a/include/clk/sunxi.h b/include/clk/sunxi.h index 11caf12b17..e90e078972 100644 --- a/include/clk/sunxi.h +++ b/include/clk/sunxi.h @@ -70,12 +70,12 @@ struct ccu_desc { }; /** - * struct ccu_priv - sunxi clock control unit + * struct ccu_plat - sunxi clock control unit platform data * * @base: base address * @desc: ccu descriptor */ -struct ccu_priv { +struct ccu_plat { void *base; const struct ccu_desc *desc; }; -- 2.35.1
[PATCH 3/7] reset: sunxi: Get the reset count from the CCU descriptor
This allows all of the clock drivers to use a common bind function. Signed-off-by: Samuel Holland --- drivers/clk/sunxi/clk_a10.c | 7 +-- drivers/clk/sunxi/clk_a10s.c | 7 +-- drivers/clk/sunxi/clk_a23.c | 7 +-- drivers/clk/sunxi/clk_a31.c | 7 +-- drivers/clk/sunxi/clk_a31_r.c | 7 +-- drivers/clk/sunxi/clk_a64.c | 7 +-- drivers/clk/sunxi/clk_a80.c | 12 +--- drivers/clk/sunxi/clk_a83t.c | 7 +-- drivers/clk/sunxi/clk_h3.c| 7 +-- drivers/clk/sunxi/clk_h6.c| 7 +-- drivers/clk/sunxi/clk_h616.c | 7 +-- drivers/clk/sunxi/clk_h6_r.c | 7 +-- drivers/clk/sunxi/clk_r40.c | 7 +-- drivers/clk/sunxi/clk_sunxi.c | 5 + drivers/clk/sunxi/clk_v3s.c | 7 +-- drivers/reset/reset-sunxi.c | 6 ++ include/clk/sunxi.h | 9 +++-- 17 files changed, 28 insertions(+), 95 deletions(-) diff --git a/drivers/clk/sunxi/clk_a10.c b/drivers/clk/sunxi/clk_a10.c index 6b58cffc8a..e5374f6cf0 100644 --- a/drivers/clk/sunxi/clk_a10.c +++ b/drivers/clk/sunxi/clk_a10.c @@ -69,11 +69,6 @@ static const struct ccu_desc a10_ccu_desc = { .num_resets = ARRAY_SIZE(a10_resets), }; -static int a10_clk_bind(struct udevice *dev) -{ - return sunxi_reset_bind(dev, ARRAY_SIZE(a10_resets)); -} - static const struct udevice_id a10_ccu_ids[] = { { .compatible = "allwinner,sun4i-a10-ccu", .data = (ulong)&a10_ccu_desc }, @@ -89,5 +84,5 @@ U_BOOT_DRIVER(clk_sun4i_a10) = { .priv_auto = sizeof(struct ccu_priv), .ops= &sunxi_clk_ops, .probe = sunxi_clk_probe, - .bind = a10_clk_bind, + .bind = sunxi_clk_bind, }; diff --git a/drivers/clk/sunxi/clk_a10s.c b/drivers/clk/sunxi/clk_a10s.c index 81b146ce1e..07d518c121 100644 --- a/drivers/clk/sunxi/clk_a10s.c +++ b/drivers/clk/sunxi/clk_a10s.c @@ -54,11 +54,6 @@ static const struct ccu_desc a10s_ccu_desc = { .num_resets = ARRAY_SIZE(a10s_resets), }; -static int a10s_clk_bind(struct udevice *dev) -{ - return sunxi_reset_bind(dev, ARRAY_SIZE(a10s_resets)); -} - static const struct udevice_id a10s_ccu_ids[] = { { .compatible = "allwinner,sun5i-a10s-ccu", .data = (ulong)&a10s_ccu_desc }, @@ -74,5 +69,5 @@ U_BOOT_DRIVER(clk_sun5i_a10s) = { .priv_auto = sizeof(struct ccu_priv), .ops= &sunxi_clk_ops, .probe = sunxi_clk_probe, - .bind = a10s_clk_bind, + .bind = sunxi_clk_bind, }; diff --git a/drivers/clk/sunxi/clk_a23.c b/drivers/clk/sunxi/clk_a23.c index c7c78bc7d8..9c0e5db07c 100644 --- a/drivers/clk/sunxi/clk_a23.c +++ b/drivers/clk/sunxi/clk_a23.c @@ -73,11 +73,6 @@ static const struct ccu_desc a23_ccu_desc = { .num_resets = ARRAY_SIZE(a23_resets), }; -static int a23_clk_bind(struct udevice *dev) -{ - return sunxi_reset_bind(dev, ARRAY_SIZE(a23_resets)); -} - static const struct udevice_id a23_clk_ids[] = { { .compatible = "allwinner,sun8i-a23-ccu", .data = (ulong)&a23_ccu_desc }, @@ -93,5 +88,5 @@ U_BOOT_DRIVER(clk_sun8i_a23) = { .priv_auto = sizeof(struct ccu_priv), .ops= &sunxi_clk_ops, .probe = sunxi_clk_probe, - .bind = a23_clk_bind, + .bind = sunxi_clk_bind, }; diff --git a/drivers/clk/sunxi/clk_a31.c b/drivers/clk/sunxi/clk_a31.c index c8c7f4ecf5..3d0767e290 100644 --- a/drivers/clk/sunxi/clk_a31.c +++ b/drivers/clk/sunxi/clk_a31.c @@ -94,11 +94,6 @@ static const struct ccu_desc a31_ccu_desc = { .num_resets = ARRAY_SIZE(a31_resets), }; -static int a31_clk_bind(struct udevice *dev) -{ - return sunxi_reset_bind(dev, ARRAY_SIZE(a31_resets)); -} - static const struct udevice_id a31_clk_ids[] = { { .compatible = "allwinner,sun6i-a31-ccu", .data = (ulong)&a31_ccu_desc }, @@ -112,5 +107,5 @@ U_BOOT_DRIVER(clk_sun6i_a31) = { .priv_auto = sizeof(struct ccu_priv), .ops= &sunxi_clk_ops, .probe = sunxi_clk_probe, - .bind = a31_clk_bind, + .bind = sunxi_clk_bind, }; diff --git a/drivers/clk/sunxi/clk_a31_r.c b/drivers/clk/sunxi/clk_a31_r.c index 7bf1c4578c..04c238204d 100644 --- a/drivers/clk/sunxi/clk_a31_r.c +++ b/drivers/clk/sunxi/clk_a31_r.c @@ -35,11 +35,6 @@ static const struct ccu_desc a31_r_ccu_desc = { .num_resets = ARRAY_SIZE(a31_r_resets), }; -static int a31_r_clk_bind(struct udevice *dev) -{ - return sunxi_reset_bind(dev, ARRAY_SIZE(a31_r_resets)); -} - static const struct udevice_id a31_r_clk_ids[] = { { .compatible = "allwinner,sun8i-a83t-r-ccu", .data = (ulong)&a31_r_ccu_desc }, @@ -57,5 +52,5 @@ U_BOOT_DRIVER(clk_sun6i_a31_r) = { .priv_auto = sizeof(struct ccu_priv), .ops= &sunxi_clk_ops, .probe = sunxi_clk_probe, - .bind
[PATCH 1/7] clk: sunxi: Store the array sizes in the CCU descriptor
The reset array size is currently used for bounds checking in the reset driver. The same bounds check should really be done in the clock driver. Currently, the array size is provided to the reset driver separately from the CCU descriptor, which is a bit strange. Let's do this the usual way, with the array sizes next to the arrays themselves. Signed-off-by: Samuel Holland --- drivers/clk/sunxi/clk_a10.c | 2 ++ drivers/clk/sunxi/clk_a10s.c | 2 ++ drivers/clk/sunxi/clk_a23.c | 2 ++ drivers/clk/sunxi/clk_a31.c | 2 ++ drivers/clk/sunxi/clk_a31_r.c | 2 ++ drivers/clk/sunxi/clk_a64.c | 2 ++ drivers/clk/sunxi/clk_a80.c | 4 drivers/clk/sunxi/clk_a83t.c | 2 ++ drivers/clk/sunxi/clk_h3.c| 2 ++ drivers/clk/sunxi/clk_h6.c| 2 ++ drivers/clk/sunxi/clk_h616.c | 2 ++ drivers/clk/sunxi/clk_h6_r.c | 2 ++ drivers/clk/sunxi/clk_r40.c | 2 ++ drivers/clk/sunxi/clk_v3s.c | 2 ++ include/clk/sunxi.h | 2 ++ 15 files changed, 32 insertions(+) diff --git a/drivers/clk/sunxi/clk_a10.c b/drivers/clk/sunxi/clk_a10.c index 90b929d3d3..6b58cffc8a 100644 --- a/drivers/clk/sunxi/clk_a10.c +++ b/drivers/clk/sunxi/clk_a10.c @@ -65,6 +65,8 @@ static struct ccu_reset a10_resets[] = { static const struct ccu_desc a10_ccu_desc = { .gates = a10_gates, .resets = a10_resets, + .num_gates = ARRAY_SIZE(a10_gates), + .num_resets = ARRAY_SIZE(a10_resets), }; static int a10_clk_bind(struct udevice *dev) diff --git a/drivers/clk/sunxi/clk_a10s.c b/drivers/clk/sunxi/clk_a10s.c index addf4f4d5c..81b146ce1e 100644 --- a/drivers/clk/sunxi/clk_a10s.c +++ b/drivers/clk/sunxi/clk_a10s.c @@ -50,6 +50,8 @@ static struct ccu_reset a10s_resets[] = { static const struct ccu_desc a10s_ccu_desc = { .gates = a10s_gates, .resets = a10s_resets, + .num_gates = ARRAY_SIZE(a10s_gates), + .num_resets = ARRAY_SIZE(a10s_resets), }; static int a10s_clk_bind(struct udevice *dev) diff --git a/drivers/clk/sunxi/clk_a23.c b/drivers/clk/sunxi/clk_a23.c index c45d2c3529..c7c78bc7d8 100644 --- a/drivers/clk/sunxi/clk_a23.c +++ b/drivers/clk/sunxi/clk_a23.c @@ -69,6 +69,8 @@ static struct ccu_reset a23_resets[] = { static const struct ccu_desc a23_ccu_desc = { .gates = a23_gates, .resets = a23_resets, + .num_gates = ARRAY_SIZE(a23_gates), + .num_resets = ARRAY_SIZE(a23_resets), }; static int a23_clk_bind(struct udevice *dev) diff --git a/drivers/clk/sunxi/clk_a31.c b/drivers/clk/sunxi/clk_a31.c index 251fc3b705..c8c7f4ecf5 100644 --- a/drivers/clk/sunxi/clk_a31.c +++ b/drivers/clk/sunxi/clk_a31.c @@ -90,6 +90,8 @@ static struct ccu_reset a31_resets[] = { static const struct ccu_desc a31_ccu_desc = { .gates = a31_gates, .resets = a31_resets, + .num_gates = ARRAY_SIZE(a31_gates), + .num_resets = ARRAY_SIZE(a31_resets), }; static int a31_clk_bind(struct udevice *dev) diff --git a/drivers/clk/sunxi/clk_a31_r.c b/drivers/clk/sunxi/clk_a31_r.c index 1f08ea956f..7bf1c4578c 100644 --- a/drivers/clk/sunxi/clk_a31_r.c +++ b/drivers/clk/sunxi/clk_a31_r.c @@ -31,6 +31,8 @@ static struct ccu_reset a31_r_resets[] = { static const struct ccu_desc a31_r_ccu_desc = { .gates = a31_r_gates, .resets = a31_r_resets, + .num_gates = ARRAY_SIZE(a31_r_gates), + .num_resets = ARRAY_SIZE(a31_r_resets), }; static int a31_r_clk_bind(struct udevice *dev) diff --git a/drivers/clk/sunxi/clk_a64.c b/drivers/clk/sunxi/clk_a64.c index 1004a79503..6da861ddc1 100644 --- a/drivers/clk/sunxi/clk_a64.c +++ b/drivers/clk/sunxi/clk_a64.c @@ -76,6 +76,8 @@ static const struct ccu_reset a64_resets[] = { static const struct ccu_desc a64_ccu_desc = { .gates = a64_gates, .resets = a64_resets, + .num_gates = ARRAY_SIZE(a64_gates), + .num_resets = ARRAY_SIZE(a64_resets), }; static int a64_clk_bind(struct udevice *dev) diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c index 8a0834d83a..7025d3cbe6 100644 --- a/drivers/clk/sunxi/clk_a80.c +++ b/drivers/clk/sunxi/clk_a80.c @@ -75,11 +75,15 @@ static const struct ccu_reset a80_mmc_resets[] = { static const struct ccu_desc a80_ccu_desc = { .gates = a80_gates, .resets = a80_resets, + .num_gates = ARRAY_SIZE(a80_gates), + .num_resets = ARRAY_SIZE(a80_resets), }; static const struct ccu_desc a80_mmc_clk_desc = { .gates = a80_mmc_gates, .resets = a80_mmc_resets, + .num_gates = ARRAY_SIZE(a80_mmc_gates), + .num_resets = ARRAY_SIZE(a80_mmc_resets), }; static int a80_clk_bind(struct udevice *dev) diff --git a/drivers/clk/sunxi/clk_a83t.c b/drivers/clk/sunxi/clk_a83t.c index 8c6043f51e..c50d253f84 100644 --- a/drivers/clk/sunxi/clk_a83t.c +++ b/drivers/clk/sunxi/clk_a83t.c @@ -73,6 +73,8 @@ static struct ccu_reset a83t_resets[] = { static const struct ccu_desc a83t_ccu_desc = { .gates = a83t_gates, .resets = a83t_resets, + .num_gates = A
[PATCH 2/7] clk: sunxi: Prevent out-of-bounds gate array access
Because the gate arrays are not given explicit sizes, the arrays are only as large as the highest-numbered gate described in the driver. However, only a subset of the CCU clocks are needed by U-Boot. So there are valid clock specifiers with indexes greater than the size of the arrays. Referencing any of these clocks causes out-of-bounds access. Fix this by checking the identifier against the size of the array. Fixes: 0d47bc705651 ("clk: Add Allwinner A64 CLK driver") Signed-off-by: Samuel Holland --- drivers/clk/sunxi/clk_sunxi.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/clk/sunxi/clk_sunxi.c b/drivers/clk/sunxi/clk_sunxi.c index 9673b58a49..3108e5b66d 100644 --- a/drivers/clk/sunxi/clk_sunxi.c +++ b/drivers/clk/sunxi/clk_sunxi.c @@ -18,6 +18,9 @@ static const struct ccu_clk_gate *priv_to_gate(struct ccu_priv *priv, unsigned long id) { + if (id >= priv->desc->num_gates) + return NULL; + return &priv->desc->gates[id]; } @@ -27,7 +30,7 @@ static int sunxi_set_gate(struct clk *clk, bool on) const struct ccu_clk_gate *gate = priv_to_gate(priv, clk->id); u32 reg; - if (!(gate->flags & CCU_CLK_F_IS_VALID)) { + if (!gate || !(gate->flags & CCU_CLK_F_IS_VALID)) { printf("%s: (CLK#%ld) unhandled\n", __func__, clk->id); return 0; } -- 2.35.1
[PATCH 0/7] clk: sunxi: Out-of-bounds access fix and driver cleanup
This series fixes an issue with out-of-bounds access to the gate array (patches 1-2), uses the rearranged array size information to remove a bunch of duplicate code (patches 3-4), and then simplifies how the reset driver is bound (patches 5-7). The original motivation for these changes was adding a driver for the legacy A31/A23/A33 PRCM binding (which I will send separately), and trying to use OF_PLATDATA in SPL (which did not work out). But I think at least some of the cleanup is worth applying on its own. Patch 4 is generally the same change I made between v1 and v2 of the pinctrl series, using some #ifdefs to share a U_BOOT_DRIVER. It's not quite as clean as the pinctrl case, because here the SoC-specific parts are in different files, so all of the CCU descriptors have to be global. Samuel Holland (7): clk: sunxi: Store the array sizes in the CCU descriptor clk: sunxi: Prevent out-of-bounds gate array access reset: sunxi: Get the reset count from the CCU descriptor clk: sunxi: Use a single driver for all variants clk: sunxi: Convert driver private data to platform data reset: sunxi: Convert driver private data to platform data reset: sunxi: Reuse the platform data from the clock driver drivers/clk/sunxi/clk_a10.c | 27 +- drivers/clk/sunxi/clk_a10s.c | 27 +- drivers/clk/sunxi/clk_a23.c | 27 +- drivers/clk/sunxi/clk_a31.c | 25 + drivers/clk/sunxi/clk_a31_r.c | 29 +- drivers/clk/sunxi/clk_a64.c | 25 + drivers/clk/sunxi/clk_a80.c | 36 ++-- drivers/clk/sunxi/clk_a83t.c | 25 + drivers/clk/sunxi/clk_h3.c| 27 +- drivers/clk/sunxi/clk_h6.c| 25 + drivers/clk/sunxi/clk_h616.c | 25 + drivers/clk/sunxi/clk_h6_r.c | 27 +- drivers/clk/sunxi/clk_r40.c | 25 + drivers/clk/sunxi/clk_sunxi.c | 168 ++ drivers/clk/sunxi/clk_v3s.c | 27 +- drivers/reset/reset-sunxi.c | 55 ++- include/clk/sunxi.h | 21 + 17 files changed, 208 insertions(+), 413 deletions(-) -- 2.35.1
Re: [PATCH 1/1] test: fix some pylint problems in test_capsule_firmware_raw.py
On Sat, Apr 30, 2022 at 03:55:41PM +0200, Heinrich Schuchardt wrote: > * improve doc-string formatting > * remove unused imports Similar changes should be applied to test_capsule_firmware_fit.py and test_capsule_firmware_signed.py as well. -Takahiro Akashi > Signed-off-by: Heinrich Schuchardt > --- > .../test_capsule_firmware_raw.py | 42 +-- > 1 file changed, 20 insertions(+), 22 deletions(-) > > diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py > b/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py > index ae99f080ff..c8c647d0b1 100644 > --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py > +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py > @@ -1,17 +1,13 @@ > # SPDX-License-Identifier: GPL-2.0+ > # Copyright (c) 2020, Linaro Limited > # Author: AKASHI Takahiro > -# > -# U-Boot UEFI: Firmware Update Test > > -""" > +""" U-Boot UEFI: Firmware Update Test > This test verifies capsule-on-disk firmware update for raw images > """ > > -from subprocess import check_call, check_output, CalledProcessError > import pytest > -from capsule_defs import * > - > +from capsule_defs import CAPSULE_DATA_DIR, CAPSULE_INSTALL_DIR > > @pytest.mark.boardspec('sandbox') > @pytest.mark.buildconfigspec('efi_capsule_firmware_raw') > @@ -24,15 +20,18 @@ from capsule_defs import * > @pytest.mark.buildconfigspec('cmd_nvedit_efi') > @pytest.mark.buildconfigspec('cmd_sf') > @pytest.mark.slow > -class TestEfiCapsuleFirmwareRaw(object): > +class TestEfiCapsuleFirmwareRaw: > +""" Tests verifying capsule-on-disk firmware update for raw images > +""" > + > def test_efi_capsule_fw1( > self, u_boot_config, u_boot_console, efi_capsule_data): > -""" > -Test Case 1 - Update U-Boot and U-Boot environment on SPI Flash > - but with an incorrect GUID value in the capsule > - No update should happen > - 0x10-0x15: U-Boot binary (but dummy) > - 0x15-0x20: U-Boot environment (but dummy) > +""" Test Case 1 > +Update U-Boot and U-Boot environment on SPI Flash > +but with an incorrect GUID value in the capsule > +No update should happen > +0x10-0x15: U-Boot binary (but dummy) > +0x15-0x20: U-Boot environment (but dummy) > """ > > # other tests might have run and the > @@ -106,12 +105,11 @@ class TestEfiCapsuleFirmwareRaw(object): > > def test_efi_capsule_fw2( > self, u_boot_config, u_boot_console, efi_capsule_data): > -""" > -Test Case 2 - Update U-Boot and U-Boot environment on SPI Flash > - but with OsIndications unset > - No update should happen > - 0x10-0x15: U-Boot binary (but dummy) > - 0x15-0x20: U-Boot environment (but dummy) > +""" Test Case 2 > +Update U-Boot and U-Boot environment on SPI Flash but with > OsIndications unset > +No update should happen > +0x10-0x15: U-Boot binary (but dummy) > +0x15-0x20: U-Boot environment (but dummy) > """ > disk_img = efi_capsule_data > with u_boot_console.log.section('Test Case 2-a, before reboot'): > @@ -191,9 +189,9 @@ class TestEfiCapsuleFirmwareRaw(object): > > def test_efi_capsule_fw3( > self, u_boot_config, u_boot_console, efi_capsule_data): > -""" > -Test Case 3 - Update U-Boot on SPI Flash, raw image format > - 0x10-0x15: U-Boot binary (but dummy) > +""" Test Case 3 > +Update U-Boot on SPI Flash, raw image format > +0x10-0x15: U-Boot binary (but dummy) > """ > disk_img = efi_capsule_data > with u_boot_console.log.section('Test Case 3-a, before reboot'): > -- > 2.34.1 >
[PATCH 1/1] Add mmc_set_env_dev to TI AM33xx, using the scratch reg of UART port
Signed-off-by: Dashi Cao --- board/ti/am335x/board.c | 40 common/spl/spl.c| 6 ++ drivers/mmc/mmc.c | 4 include/mmc.h | 1 + 4 files changed, 51 insertions(+) diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c index 7c0545892c..577e4f2b1f 100644 --- a/board/ti/am335x/board.c +++ b/board/ti/am335x/board.c @@ -1010,3 +1010,43 @@ U_BOOT_DRVINFO(am335x_mmc1) = { .plat = &am335x_mmc1_plat, }; #endif + +#if defined(CONFIG_SPL_MMC) && defined(CONFIG_AM33XX) +struct uart_reg { + u16 resv0[4]; + u16 uart_efr; + u16 resv1[3]; + u16 uart_mcr; + u16 resv2[5]; + u16 uart_spr; +}; + +int mmc_get_env_dev(void) +{ + u16 bdev = 0; + u16 efr, mcr; + volatile struct uart_reg *uart = (void *)UART0_BASE; + + efr = uart->uart_efr; + mcr = uart->uart_mcr; + if ((efr & 0x10) == 0 || (mcr & 0x40) == 0) + bdev = uart->uart_spr; + else + printf("Cannot get mmc dev number from uart0 scratch reg\n"); + + return (bdev & 0x0ff); +} + +void mmc_set_env_dev(u16 bdev) +{ + u16 efr, mcr; + volatile struct uart_reg *uart = (void *)UART0_BASE; + + efr = uart->uart_efr; + mcr = uart->uart_mcr; + if ((efr & 0x10) == 0 || (mcr & 0x40) == 0) + uart->uart_spr = (bdev & 0x0ff); + else + printf("Cannot set mmc dev number to uart0 scratch reg\n"); +} +#endif diff --git a/common/spl/spl.c b/common/spl/spl.c index c8c463f80b..a14ae76698 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -37,6 +37,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -723,6 +724,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) }; struct spl_image_info spl_image; int ret; + short bootdev; debug(">>" SPL_TPL_PROMPT "board_init_r()\n"); @@ -798,6 +800,10 @@ void board_init_r(gd_t *dummy1, ulong dummy2) puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n"); hang(); } + bootdev = spl_image.boot_device - BOOT_DEVICE_MMC1; + if (bootdev < 0) + bootdev = -bootdev; + mmc_set_env_dev(bootdev); spl_perform_fixups(&spl_image); if (CONFIG_IS_ENABLED(HANDOFF)) { diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 8a7d073900..8c941b575a 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -3133,3 +3133,7 @@ __weak int mmc_get_env_dev(void) return 0; #endif } + +__weak void mmc_set_env_dev(u16 bootdev) +{ +} diff --git a/include/mmc.h b/include/mmc.h index 9b4dc68311..3c09652382 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -943,6 +943,7 @@ int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr); extern uint mmc_get_env_part(struct mmc *mmc); # endif int mmc_get_env_dev(void); +void mmc_set_env_dev(u16 bootdev); /* Minimum partition switch timeout in units of 10-milliseconds */ #define MMC_MIN_PART_SWITCH_TIME 30 /* 300 ms */ -- 2.20.1
[PATCH 2/2] serial: Remove obsolete CONS_INDEX_n Kconfig options
These were only ever implied by sunxi platforms, and that usage has been removed. Current practice is to specify CONFIG_CONS_INDEX in each board's defconfig. Signed-off-by: Samuel Holland --- drivers/serial/Kconfig | 26 -- 1 file changed, 26 deletions(-) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 1e595d0600..71a0591697 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -74,36 +74,10 @@ config TPL_SERIAL_PRESENT This option enables the full UART in TPL, so if is it disabled, the full UART driver will be omitted, thus saving space. -# Logic to allow us to use the imply keyword to set what the default port -# should be. The default is otherwise 1. -config CONS_INDEX_0 - bool - -config CONS_INDEX_2 - bool - -config CONS_INDEX_3 - bool - -config CONS_INDEX_4 - bool - -config CONS_INDEX_5 - bool - -config CONS_INDEX_6 - bool - config CONS_INDEX int "UART used for console" depends on SPECIFY_CONSOLE_INDEX range 0 6 - default 0 if CONS_INDEX_0 - default 2 if CONS_INDEX_2 - default 3 if CONS_INDEX_3 - default 4 if CONS_INDEX_4 - default 5 if CONS_INDEX_5 - default 6 if CONS_INDEX_6 default 1 help Set this to match the UART number of the serial console. -- 2.35.1
[PATCH 1/2] sunxi: Remove obsolete Kconfig selections
ARCH_SUNXI selects DM_SERIAL, so the condition can never be satisfied. Signed-off-by: Samuel Holland --- arch/arm/mach-sunxi/Kconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 1f43b25324..ee606c5bbc 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -207,7 +207,6 @@ config MACH_SUN5I select PHY_SUN4I_USB select SUNXI_GEN_SUN4I select SUPPORT_SPL - imply CONS_INDEX_2 if !DM_SERIAL imply SPL_SYS_I2C_LEGACY imply SYS_I2C_LEGACY @@ -255,7 +254,6 @@ config MACH_SUN8I_A23 select SUPPORT_SPL select SYS_I2C_SUN8I_RSB select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT - imply CONS_INDEX_5 if !DM_SERIAL config MACH_SUN8I_A33 bool "sun8i (Allwinner A33)" @@ -270,7 +268,6 @@ config MACH_SUN8I_A33 select SUPPORT_SPL select SYS_I2C_SUN8I_RSB select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT - imply CONS_INDEX_5 if !DM_SERIAL config MACH_SUN8I_A83T bool "sun8i (Allwinner A83T)" -- 2.35.1
Re: [PATCH] sunxi: board: Fix UART PortF pinmux setup
On 5/5/22 7:37 PM, Andre Przywara wrote: > When CONFIG_UART0_PORT_F is defined, we try to configure two PortF pins > (usually used for the SD card) as UART0. Some SoCs use the mux value of > 3 for this, while others use 4. > > The combination of Kconfig symbols we currently use was not quite right: > we mis-configure the A31, A64, H6 and H616. > > Going through the list in the pinctrl driver, there are only a few older > SoCs that use a value of 4, so revert the #ifdef clause, and name those > explicitly, instead of the other way around. > > Signed-off-by: Andre Przywara Reviewed-by: Samuel Holland
Re: [PATCH 2/2] clk: sunxi: add and use dummy gate clocks
On 5/5/22 7:33 PM, Andre Przywara wrote: > Some devices enumerate various clocks in their DT, and many drivers > just blanketly try to enable all of them. This creates problems > since we only model a few gate clocks, and the clock driver outputs > a warning when a clock is not described: > = > sunxi_set_gate: (CLK#3) unhandled > = > > Some clocks don't have an enable bit, or are already enabled in a > different way, so we might want to just ignore them. > > Add a CCU_CLK_F_DUMMY_GATE flag that indicates that case, and define > a GATE_DUMMY macro that can be used in the clock description array. > Define a few clocks, used by some pinctrl devices, that way to suppress > the runtime warnings. > > Signed-off-by: Andre Przywara Reviewed-by: Samuel Holland
Re: [PATCH 6/9] dm: core: Support accessing core tags
Hi Simon, On Sun, May 08, 2022 at 04:39:24AM -0600, Simon Glass wrote: > At present tag numbers are only allocated for non-core data, meaning that > the 'core' data, like priv and plat, are accessed through dedicated > functions. > > For debugging and consistency it is convenient to use tags for this 'core' > data too. Add support for this, with new tag numbers and functions to > access the pointer and size for each. > > Update one of the test drivers so that the uclass-private data can be > tested here. > > There is some code duplication with functions like device_alloc_priv() but > this is not addressed for now. At some point, some rationalisation may > help to reduce code size, but more thought it needed on that. > > Signed-off-by: Simon Glass > --- > > drivers/core/device.c | 65 + > drivers/misc/test_drv.c | 4 ++- > include/dm/device.h | 25 + > include/dm/tag.h| 13 ++- > test/dm/core.c | 80 + > tools/dtoc/test_dtoc.py | 4 +++ > 6 files changed, 189 insertions(+), 2 deletions(-) > > diff --git a/drivers/core/device.c b/drivers/core/device.c > index 3ab2583df38..d7936a46732 100644 > --- a/drivers/core/device.c > +++ b/drivers/core/device.c > @@ -680,6 +680,71 @@ void *dev_get_parent_priv(const struct udevice *dev) > return dm_priv_to_rw(dev->parent_priv_); > } > > +void *dev_get_attach_ptr(const struct udevice *dev, enum dm_tag_t tag) Why not (enhance and) re-use dev_tag_get_ptr()? Both functions, at least, share the syntax and even the semantics from user's viewpoint. > +{ > + switch (tag) { > + case DM_TAG_PLAT: > + return dev_get_plat(dev); > + case DM_TAG_PARENT_PLAT: > + return dev_get_parent_plat(dev); > + case DM_TAG_UC_PLAT: > + return dev_get_uclass_plat(dev); > + case DM_TAG_PRIV: > + return dev_get_priv(dev); > + case DM_TAG_PARENT_PRIV: > + return dev_get_parent_priv(dev); > + case DM_TAG_UC_PRIV: > + return dev_get_uclass_priv(dev); > + default: > + return NULL; > + } > +} > + > +int dev_get_attach_size(const struct udevice *dev, enum dm_tag_t tag) > +{ > + const struct udevice *parent = dev_get_parent(dev); > + const struct uclass *uc = dev->uclass; > + const struct uclass_driver *uc_drv = uc->uc_drv; > + const struct driver *parent_drv = NULL; > + int size = 0; > + > + if (parent) > + parent_drv = parent->driver; > + > + switch (tag) { > + case DM_TAG_PLAT: > + size = dev->driver->plat_auto; > + break; > + case DM_TAG_PARENT_PLAT: > + if (parent) { > + size = parent_drv->per_child_plat_auto; > + if (!size) > + size = > parent->uclass->uc_drv->per_child_plat_auto; > + } > + break; > + case DM_TAG_UC_PLAT: > + size = uc_drv->per_device_plat_auto; > + break; > + case DM_TAG_PRIV: > + size = dev->driver->priv_auto; > + break; > + case DM_TAG_PARENT_PRIV: > + if (parent) { > + size = parent_drv->per_child_auto; > + if (!size) > + size = parent->uclass->uc_drv->per_child_auto; > + } > + break; > + case DM_TAG_UC_PRIV: > + size = uc_drv->per_device_auto; > + break; > + default: > + break; > + } > + > + return size; > +} > + > static int device_get_device_tail(struct udevice *dev, int ret, > struct udevice **devp) > { > diff --git a/drivers/misc/test_drv.c b/drivers/misc/test_drv.c > index b6df1189032..927618256f0 100644 > --- a/drivers/misc/test_drv.c > +++ b/drivers/misc/test_drv.c > @@ -108,7 +108,9 @@ UCLASS_DRIVER(testbus) = { > .child_pre_probe = testbus_child_pre_probe_uclass, > .child_post_probe = testbus_child_post_probe_uclass, > > - /* This is for dtoc testing only */ > + .per_device_auto = sizeof(struct dm_test_uclass_priv), > + > + /* Note: this is for dtoc testing as well as tags*/ > .per_device_plat_auto = sizeof(struct dm_test_uclass_plat), > }; > > diff --git a/include/dm/device.h b/include/dm/device.h > index 5bdb10653f8..12c6ba37ff3 100644 > --- a/include/dm/device.h > +++ b/include/dm/device.h > @@ -11,6 +11,7 @@ > #define _DM_DEVICE_H > > #include > +#include > #include > #include > #include > @@ -546,6 +547,30 @@ void *dev_get_parent_priv(const struct udevice *dev); > */ > void *dev_get_uclass_priv(const struct udevice *dev); > > +/** > + * dev_get_attach_ptr() - Get the value of an attached pointed tag > + * > + * The tag is assumed to hold a pointer, if it exists > + * > + * @dev: Device to look at > + * @tag: Tag to access > + * @return value of
Re: Pull request for efi-2022-07-rc3-2
On Sun, May 08, 2022 at 09:37:04AM +0200, Heinrich Schuchardt wrote: > Dear Tom, > > The following changes since commit 145921bdbdcfc24f18ce21d570ff86cc7e1fa3ba: > > Merge https://source.denx.de/u-boot/custodians/u-boot-usb (2022-05-06 > 08:57:15 -0400) > > are available in the Git repository at: > > https://source.denx.de/u-boot/custodians/u-boot-efi.git > tags/efi-2022-07-rc3-2 > > for you to fetch changes up to 4b494770577cc61c3c1a4b57ced2fc98d87957dc: > > test/py: Add more test cases for rejecting an EFI image (2022-05-07 > 23:17:26 +0200) > > Gitlab CI showed no issues: > https://source.denx.de/u-boot/custodians/u-boot-efi/-/pipelines/11957 > Applied to u-boot/master, thanks! -- Tom signature.asc Description: PGP signature
Re: [PATCH 2/3] phy: stm32-usbphyc: usbphyc is a clock provider of ck_usbo_48m clock
On 4/26/22 8:37 AM, Patrick Delaunay wrote: ck_usbo_48m is generated by usbphyc PLL and used by OTG controller for Full-Speed use cases with dedicated Full-Speed transceiver. ck_usbo_48m is available as soon as the PLL is enabled. Signed-off-by: Patrick Delaunay --- drivers/phy/phy-stm32-usbphyc.c | 79 + 1 file changed, 79 insertions(+) diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c index 16c8799eca..e0b8fcb8f2 100644 --- a/drivers/phy/phy-stm32-usbphyc.c +++ b/drivers/phy/phy-stm32-usbphyc.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +51,9 @@ #define PLL_INFF_MIN_RATE 1920 /* in Hz */ #define PLL_INFF_MAX_RATE 3840 /* in Hz */ +/* USBPHYC_CLK48 */ +#define USBPHYC_CLK48_FREQ 4800 /* in Hz */ + struct pll_params { u8 ndiv; u16 frac; @@ -355,6 +360,16 @@ static const struct phy_ops stm32_usbphyc_phy_ops = { .of_xlate = stm32_usbphyc_of_xlate, }; +static int stm32_usbphyc_bind(struct udevice *dev) +{ + int ret; + + ret = device_bind_driver_to_node(dev, "stm32-usbphyc-clk", "ck_usbo_48m", +dev_ofnode(dev), NULL); + + return log_ret(ret); +} + static int stm32_usbphyc_probe(struct udevice *dev) { struct stm32_usbphyc *usbphyc = dev_get_priv(dev); @@ -444,6 +459,70 @@ U_BOOT_DRIVER(stm32_usb_phyc) = { .id = UCLASS_PHY, .of_match = stm32_usbphyc_of_match, .ops = &stm32_usbphyc_phy_ops, + .bind = stm32_usbphyc_bind, .probe = stm32_usbphyc_probe, .priv_auto = sizeof(struct stm32_usbphyc), }; + +struct stm32_usbphyc_clk { + bool enable; +}; + +static ulong stm32_usbphyc_clk48_get_rate(struct clk *clk) +{ + return USBPHYC_CLK48_FREQ; What is the relationship between this clock and the PLL? +} + +static int stm32_usbphyc_clk48_enable(struct clk *clk) +{ + struct stm32_usbphyc_clk *usbphyc_clk = dev_get_priv(clk->dev); + struct stm32_usbphyc *usbphyc; + int ret; + + if (usbphyc_clk->enable) + return 0; + + usbphyc = dev_get_priv(clk->dev->parent); + + /* ck_usbo_48m is generated by usbphyc PLL */ + ret = stm32_usbphyc_pll_enable(usbphyc); + if (ret) + return ret; + + usbphyc_clk->enable = true; + + return 0; +} + +static int stm32_usbphyc_clk48_disable(struct clk *clk) +{ + struct stm32_usbphyc_clk *usbphyc_clk = dev_get_priv(clk->dev); + struct stm32_usbphyc *usbphyc; + int ret; + + if (!usbphyc_clk->enable) + return 0; + + usbphyc = dev_get_priv(clk->dev->parent); + + ret = stm32_usbphyc_pll_disable(usbphyc); + if (ret) + return ret; + + usbphyc_clk->enable = false; + + return 0; +} + +const struct clk_ops usbphyc_clk48_ops = { + .get_rate = stm32_usbphyc_clk48_get_rate, + .enable = stm32_usbphyc_clk48_enable, + .disable = stm32_usbphyc_clk48_disable, +}; + +U_BOOT_DRIVER(stm32_usb_phyc_clk) = { + .name = "stm32-usbphyc-clk", + .id = UCLASS_CLK, + .ops = &usbphyc_clk48_ops, + .priv_auto = sizeof(struct stm32_usbphyc_clk), +}; I see that in the next patch you call this device from drivers/clk/clk_stm32mp1.c Why is this clock a separate driver from the clock driver? --Sean
Re: [PATCH 1/3] phy: stm32-usbphyc: add counter of PLL consumer
On 4/26/22 8:37 AM, Patrick Delaunay wrote: Add the counter of the PLL user n_pll_cons managed by the 2 functions stm32_usbphyc_pll_enable / stm32_usbphyc_pll_disable. This counter allow to remove the function stm32_usbphyc_is_init and it is a preliminary step for ck_usbo_48m introduction. Is it necessary to disable this clock before booting to Linux? If it isn't, then perhaps it is simpler to just not disable the clock. --Sean Signed-off-by: Patrick Delaunay --- drivers/phy/phy-stm32-usbphyc.c | 76 + 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c index 9c1dcfae52..16c8799eca 100644 --- a/drivers/phy/phy-stm32-usbphyc.c +++ b/drivers/phy/phy-stm32-usbphyc.c @@ -65,6 +65,7 @@ struct stm32_usbphyc { bool init; bool powered; } phys[MAX_PHYS]; + int n_pll_cons; }; static void stm32_usbphyc_get_pll_params(u32 clk_rate, @@ -124,18 +125,6 @@ static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc) return 0; } -static bool stm32_usbphyc_is_init(struct stm32_usbphyc *usbphyc) -{ - int i; - - for (i = 0; i < MAX_PHYS; i++) { - if (usbphyc->phys[i].init) - return true; - } - - return false; -} - static bool stm32_usbphyc_is_powered(struct stm32_usbphyc *usbphyc) { int i; @@ -148,18 +137,17 @@ static bool stm32_usbphyc_is_powered(struct stm32_usbphyc *usbphyc) return false; } -static int stm32_usbphyc_phy_init(struct phy *phy) +static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc) { - struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev); - struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; bool pllen = readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN ? true : false; int ret; - dev_dbg(phy->dev, "phy ID = %lu\n", phy->id); - /* Check if one phy port has already configured the pll */ - if (pllen && stm32_usbphyc_is_init(usbphyc)) - goto initialized; + /* Check if one consumer has already configured the pll */ + if (pllen && usbphyc->n_pll_cons) { + usbphyc->n_pll_cons++; + return 0; + } if (usbphyc->vdda1v1) { ret = regulator_set_enable(usbphyc->vdda1v1, true); @@ -190,23 +178,19 @@ static int stm32_usbphyc_phy_init(struct phy *phy) if (!(readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN)) return -EIO; -initialized: - usbphyc_phy->init = true; + usbphyc->n_pll_cons++; return 0; } -static int stm32_usbphyc_phy_exit(struct phy *phy) +static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc) { - struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev); - struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; int ret; - dev_dbg(phy->dev, "phy ID = %lu\n", phy->id); - usbphyc_phy->init = false; + usbphyc->n_pll_cons--; - /* Check if other phy port requires pllen */ - if (stm32_usbphyc_is_init(usbphyc)) + /* Check if other consumer requires pllen */ + if (usbphyc->n_pll_cons) return 0; clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN); @@ -235,6 +219,42 @@ static int stm32_usbphyc_phy_exit(struct phy *phy) return 0; } +static int stm32_usbphyc_phy_init(struct phy *phy) +{ + struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev); + struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; + int ret; + + dev_dbg(phy->dev, "phy ID = %lu\n", phy->id); + if (usbphyc_phy->init) + return 0; + + ret = stm32_usbphyc_pll_enable(usbphyc); + if (ret) + return log_ret(ret); + + usbphyc_phy->init = true; + + return 0; +} + +static int stm32_usbphyc_phy_exit(struct phy *phy) +{ + struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev); + struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; + int ret; + + dev_dbg(phy->dev, "phy ID = %lu\n", phy->id); + if (!usbphyc_phy->init) + return 0; + + ret = stm32_usbphyc_pll_disable(usbphyc); + + usbphyc_phy->init = false; + + return log_ret(ret); +} + static int stm32_usbphyc_phy_power_on(struct phy *phy) { struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
[PATCH 2/2] dts: imx8mp-rsb3720: modify configrations to load fip into memory
From: "Ying-Chun Liu (PaulLiu)" The changes of commit 6a21c695213b ("arm: dts: imx8mp: add of-list support to common imx8mp-u-boot.dtsi") breaks the loading of the fip. This commit fixes the break by modify the configuration properly. Signed-off-by: Ying-Chun Liu (PaulLiu) Cc: Stefano Babic Cc: Fabio Estevam Cc: NXP i.MX U-Boot Team --- arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi b/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi index 2848b24f65..9b650ef77e 100644 --- a/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi @@ -150,12 +150,10 @@ }; }; }; - - configurations { - conf { - loadables = "atf", "fip"; - }; - }; }; }; }; + +&binman_configuration { + loadables = "atf", "fip"; +}; -- 2.35.1
[PATCH 1/2] dts: imx8mp: assign binman_configuration node name to config-SEQ
From: "Ying-Chun Liu (PaulLiu)" assign a node name for config-SEQ so that the board dts can modify the configuration more easily. Signed-off-by: Ying-Chun Liu (PaulLiu) Cc: Stefano Babic Cc: Fabio Estevam Cc: NXP i.MX U-Boot Team --- arch/arm/dts/imx8mp-u-boot.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/dts/imx8mp-u-boot.dtsi b/arch/arm/dts/imx8mp-u-boot.dtsi index 20edd90cfa..2f9fb1aba4 100644 --- a/arch/arm/dts/imx8mp-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-u-boot.dtsi @@ -144,7 +144,7 @@ configurations { default = "@config-DEFAULT-SEQ"; - @config-SEQ { + binman_configuration: @config-SEQ { description = "NAME"; fdt = "fdt-SEQ"; firmware = "uboot"; -- 2.35.1
[PATCH 0/2] dts: imx8mp-rsb3720: modify configrations to load fip into memory
From: "Ying-Chun Liu (PaulLiu)" The changes of commit 6a21c695213b ("arm: dts: imx8mp: add of-list support to common imx8mp-u-boot.dtsi") breaks the loading of the fip. This commit fixes the break by modify the configuration properly. Ying-Chun Liu (PaulLiu) (2): dts: imx8mp: assign binman_configuration node name to config-SEQ dts: imx8mp-rsb3720: modify configrations to load fip into memory arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi | 10 -- arch/arm/dts/imx8mp-u-boot.dtsi| 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) -- 2.35.1
Re: [PATCH 1/1 v2] add support for mws4 board
On Sun, May 08, 2022 at 05:47:58PM +0200, Marian Ulbricht wrote: > Am 08.05.22 um 16:21 schrieb Tom Rini: > > On Sun, May 08, 2022 at 03:46:55PM +0200, Marian Ulbricht wrote: > > > > > mws4 is an arm based nuclear probe hardware used from german government to > > > monitor nuclear activity > > > > > > Signed-off-by: Marian Ulbricht > > > > Thanks for the submission. Have you submitted the board dts files to > > upstream Linux? Also, please remove all of the commented out code in > > the board files, etc. > > > Hi, > not yet, i started from bottom up: u-boot -> buildroot -> kernel OK. We require the board dts itself to be submitted to the kernel first, as we keep that as an unchanged copy of the file in upstream and try and sync them down periodically. > [PATCH 1/1 v2] add support for mws4 board > > mws4 is an arm based nuclear probe hardware used from german government to > monitor nuclear activity > > Signed-off-by: Marian Ulbricht > --- > Changes v2: > > * code cleanup Note that there's a number of whitespace, etc, issues that checkpatch.pl reports. For the dts files, you can set that aside and follow what upstream says there, but the rest need to be addressed. -- Tom signature.asc Description: PGP signature
Re: [PATCH 1/1 v2] add support for mws4 board
Am 08.05.22 um 16:21 schrieb Tom Rini: On Sun, May 08, 2022 at 03:46:55PM +0200, Marian Ulbricht wrote: mws4 is an arm based nuclear probe hardware used from german government to monitor nuclear activity Signed-off-by: Marian Ulbricht Thanks for the submission. Have you submitted the board dts files to upstream Linux? Also, please remove all of the commented out code in the board files, etc. Hi, not yet, i started from bottom up: u-boot -> buildroot -> kernel [PATCH 1/1 v2] add support for mws4 board mws4 is an arm based nuclear probe hardware used from german government to monitor nuclear activity Signed-off-by: Marian Ulbricht --- Changes v2: * code cleanup arch/arm/dts/Makefile | 3 + arch/arm/dts/omap3-mws4-u-boot.dtsi | 14 ++ arch/arm/dts/omap3-mws4.dts | 137 + arch/arm/mach-omap2/omap3/Kconfig | 10 ++ board/ultratronik/mws4/Kconfig | 12 ++ board/ultratronik/mws4/MAINTAINERS | 6 + board/ultratronik/mws4/Makefile | 6 + board/ultratronik/mws4/default.env | 11 ++ board/ultratronik/mws4/mws4.c | 226 board/ultratronik/mws4/mws4.h | 203 + configs/omap3_mws4_defconfig| 74 + include/configs/omap3_mws4.h| 100 12 files changed, 802 insertions(+) create mode 100644 arch/arm/dts/omap3-mws4-u-boot.dtsi create mode 100644 arch/arm/dts/omap3-mws4.dts create mode 100644 board/ultratronik/mws4/Kconfig create mode 100644 board/ultratronik/mws4/MAINTAINERS create mode 100644 board/ultratronik/mws4/Makefile create mode 100644 board/ultratronik/mws4/default.env create mode 100644 board/ultratronik/mws4/mws4.c create mode 100644 board/ultratronik/mws4/mws4.h create mode 100644 configs/omap3_mws4_defconfig create mode 100644 include/configs/omap3_mws4.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 83630af4f6..7b68a49990 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1047,6 +1047,9 @@ dtb-$(CONFIG_TARGET_OMAP3_BEAGLE) += \ omap3-beagle-xm.dtb \ omap3-beagle.dtb +dtb-$(CONFIG_TARGET_OMAP3_MWS4) += \ +omap3-mws4.dtb + dtb-$(CONFIG_TARGET_OMAP3_IGEP00X0) += \ omap3-igep0020.dtb diff --git a/arch/arm/dts/omap3-mws4-u-boot.dtsi b/arch/arm/dts/omap3-mws4-u-boot.dtsi new file mode 100644 index 00..2c03701c89 --- /dev/null +++ b/arch/arm/dts/omap3-mws4-u-boot.dtsi @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * U-Boot additions + * + * (C) Copyright 2017 Derald D. Woods + */ + +#include "omap3-u-boot.dtsi" + +/ { + chosen { + stdout-path = &uart3; + }; +}; diff --git a/arch/arm/dts/omap3-mws4.dts b/arch/arm/dts/omap3-mws4.dts new file mode 100644 index 00..f8a5c3d5b8 --- /dev/null +++ b/arch/arm/dts/omap3-mws4.dts @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * Modified 2015 by Bernhard Gätzschmann, Ultratronik from Beagleboard xM + * + * Modified 2022 Marian Ulbricht ulbri...@innoroute.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "omap34xx.dtsi" + +/ { + model = "Ultratronik BFS MWS4"; + compatible = "ti,omap3-mmi4", "ti,omap3"; + + memory { + device_type = "memory"; + reg = <0x8000 0x1000>; /* 256 MB */ + }; + + hwconfig { + i_enable_mmc = <1>; + i_enable_musb = <1>; + i_musb_mode = <1>;/*0-undefined, 1-HOST, 2-PERIPHERAL, 3-OTG*/ + i_musb_power=<500>; + i_enable_ehci = <0>; + i_usb_reset_gpio = <20>; /* DUMMY Entry */ + i_enable_eth = <1>; + i_eth_irq_gpio = <130>; + i_eth_fifo_gpio = <0>; + i_eth_cs = <4>; + i_gpio_leds_0 = "led0:red", "none", "false", "102", "0"; + i_gpio_leds_1 = "led1:yellow", "none", "false", "103", "0"; + i_gpio_leds_2 = "led2:green", "none", "false", "104", "0"; + i_gpio_leds_3 = "led3:orange", "none", "false", "101", "0"; + i_gpio_leds_4 = "usb:enable", "none", "false", "110", "1"; + i_gpio_leds_5 = "usbhub:reset", "none", "false", "27", "0"; + i_gpio_leds_6 = "iic:reset", "none", "false", "163", "0"; + i_gpio_leds_7 = "rs232:reset", "none", "false", "26", "0"; + i_i2c_bus_hw_2 = "2", "100"; + i_i2c_device_0 = "rtc8564", "0x51", "2"; + i_i2c_bus_hw_3 = "3", "100"; + i_enable_flash = <1>; + i_enable_audio = <0>; + i_enable_video = <0>; + i_enable_can = <0>; + }; + + ue_pinctrl { +/* GPIO: HW ID */ +
Re: [PATCH 3/3] test: py: tests: test_gpt.py: add a simple test for the command gpt repair
On Fri, Apr 22, 2022 at 05:46:50PM +0200, Philippe Reynes wrote: > Adds a simple test for the command gpt repair. > > Signed-off-by: Philippe Reynes Applied to u-boot/master, thanks! -- Tom signature.asc Description: PGP signature
Re: [PATCH 2/3] cmd: gpt: add subcommand repair
On Fri, Apr 22, 2022 at 05:46:49PM +0200, Philippe Reynes wrote: > Adds a sub-command repair to the command gpt > that allow to repair a corrupted gpt table. If > the both gpt table (primary and backup) are > valid, then the command does nothing. > > Signed-off-by: Philippe Reynes Applied to u-boot/master, thanks! -- Tom signature.asc Description: PGP signature
Re: [PATCH 1/3] disk: part_efi: add support to repair gpt table
On Fri, Apr 22, 2022 at 05:46:48PM +0200, Philippe Reynes wrote: > If a gpt table is corrupted (after a power cut > for example), then the gpt table should repaired. > The function gpt_repair_headers check if at least > one gpt table is valid, and then only write the > corrupted gpt table. > > Signed-off-by: Philippe Reynes Applied to u-boot/master, thanks! -- Tom signature.asc Description: PGP signature
Re: [PATCH] fdt: don't set linux,phandle
On Wed, Apr 20, 2022 at 11:31:11AM +0100, John Keeping wrote: > This has been deprecated for over 10 years and everything now uses the > plain "phandle" property in preference. There's no need to set > linux,phandle when creating phandles for nodes that do not have one. > > dtc changed the default to creating just phandle in version 1.4.5 > released in September 2017 with the justification that the new style had > already been supported for 7 years by that point (see dtc commit 0016f8c > ("dtc: change default phandles to ePAPR style instead of both")). > > Signed-off-by: John Keeping Applied to u-boot/master, thanks! -- Tom signature.asc Description: PGP signature
Re: [PATCH V2 7/7] binman_sym: guard with CONFIG_SPL_BINMAN_SYMBOLS
On Sat, May 07, 2022 at 07:04:01PM +0800, Peng Fan (OSS) wrote: > From: Peng Fan > > There is case that CONFIG_BINMAN is defined, but > CONFIG_SPL_BINMAN_SYMBOLS is not defined. In that case, there will be > build failure. So use CONFIG_SPL_BINMAN_SYMBOLS to guard the macros, and > define CONFIG_SPL_BINMAN_SYMBOLS in binman syms test. > > Signed-off-by: Peng Fan Reviewed-by: Tom Rini -- Tom signature.asc Description: PGP signature
Re: [PATCH] boot: image-pre-load: drop unused CONFIG_SYS_BOOTM_LEN
On Sat, May 07, 2022 at 09:23:05PM +0800, Peng Fan (OSS) wrote: > From: Peng Fan > > CONFIG_SYS_BOOTM_LEN is not used in this file, drop it. > > Signed-off-by: Peng Fan Reviewed-by: Tom Rini -- Tom signature.asc Description: PGP signature
Re: [PATCH V2 4/7] tools: binman: section: replace @ with -
On Sat, May 07, 2022 at 07:03:58PM +0800, Peng Fan (OSS) wrote: > From: Peng Fan > > In arch/arm/dts/imx8mp-u-boot.dtsi, there are blob-ext@1, blob-ext@2 and > etc which is for packing ddr phy firmware. However we could not declare > symbol name such as 'binman_sym_declare(ulong, blob_ext@1, image_pos)', > because '@' is not allowed, so we choose to declare the symbol > 'binman_sym_declare(ulong, blob_ext_1, image_pos);' with '@' replaced with > '_'. It does not impact if there is no '@' in section name. > > Signed-off-by: Peng Fan Reviewed-by: Tom Rini -- Tom signature.asc Description: PGP signature
Re: [PATCH] devres: Use the correct devres implementation in SPL builds
On Tue, Apr 19, 2022 at 10:14:04AM +0200, Alban Bedel wrote: > When CONFIG_DEVRES is set, but CONFIG_SPL_DM is not set devres code is > not included in the SPL. But dm/devres.h only check for CONFIG_DEVRES > to select if the full implementation should be used. So if any devres > function is used in the SPL with this config the link fails. > > Fix the ifdef in the dm/devres.h to also check for CONFIG_SPL_DM in > SPL builds. > > Signed-off-by: Alban Bedel I believe this has been fixed with: commit 092d5c2a83b730844aeaa5ac300ddc7f13a75f49 Author: Simon Glass Date: Sun Mar 27 14:26:19 2022 -0600 dm: core: Allow devres to be disabled in SPL At present if devres is enabled in U-Boot proper it is enabled in SPL. We don't normally want it there, so disable it. Signed-off-by: Simon Glass Tested-by: Angus Ainslie -- Tom signature.asc Description: PGP signature
[PATCH v1 16/17] rockchip: rk3066: add recovery mode in spl
Add a recovery button test as condition to enter the recovery mode in spl. Run the rockusb gadget for MMC while connected to a USB host. Allow external user defined functions by labeling these functions as "__weak". Signed-off-by: Johan Jonker --- .../arm/include/asm/arch-rockchip/f_rockusb.h | 1 + arch/arm/mach-rockchip/rk3066/rk3066.c| 86 +++ 2 files changed, 87 insertions(+) diff --git a/arch/arm/include/asm/arch-rockchip/f_rockusb.h b/arch/arm/include/asm/arch-rockchip/f_rockusb.h index e9c7f793..ab1e2c2f 100644 --- a/arch/arm/include/asm/arch-rockchip/f_rockusb.h +++ b/arch/arm/include/asm/arch-rockchip/f_rockusb.h @@ -8,6 +8,7 @@ #ifndef _F_ROCKUSB_H_ #define _F_ROCKUSB_H_ #include +#include #define ROCKUSB_VERSION"0.1" diff --git a/arch/arm/mach-rockchip/rk3066/rk3066.c b/arch/arm/mach-rockchip/rk3066/rk3066.c index 1d1b8687..be19400c 100644 --- a/arch/arm/mach-rockchip/rk3066/rk3066.c +++ b/arch/arm/mach-rockchip/rk3066/rk3066.c @@ -4,9 +4,15 @@ */ #include +#include +#include +#include #include #include #include +#include +#include +#include #define GRF_BASE 0x20008000 @@ -26,6 +32,81 @@ void board_debug_uart_init(void) GPIO1B0_UART2_SIN << GPIO1B0_SHIFT); } +__weak void do_spl(void) +{ + if (CONFIG_IS_ENABLED(OF_PLATDATA)) + return; + +#if IS_ENABLED(CONFIG_SPL_USB_FUNCTION_ROCKUSB) + char *dev_type; + int dev_index; + int ret; + + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + dev_type = "mmc"; + dev_index = 0; + break; + default: + return; + } + + rockusb_dev_init(dev_type, dev_index); + + ret = usb_gadget_initialize(0); + if (ret) { + printf("USB init failed: %d\n", ret); + return; + } + + g_dnl_clear_detach(); + ret = g_dnl_register("usb_dnl_rockusb"); + if (ret) + return; + + if (!g_dnl_board_usb_cable_connected()) { + printf("\rUSB cable not detected\n"); + goto exit; + } + + while (1) { + if (g_dnl_detach()) + break; + if (ctrlc()) + break; + usb_gadget_handle_interrupts(0); + } + +exit: + g_dnl_unregister(); + g_dnl_clear_detach(); + usb_gadget_release(0); +#endif + return; +} + +#define KEY_DOWN_MIN_VAL 0 +#define KEY_DOWN_MAX_VAL 30 + +__weak int rockchip_dnl_key_pressed(void) +{ +#if IS_ENABLED(CONFIG_SPL_SARADC_ROCKCHIP) + unsigned int val; + int ret; + + ret = adc_channel_single_shot("saradc@2006c000", 1, &val); + + if (ret) { + printf("Read adc key val failed\n"); + return false; + } + + if (val >= KEY_DOWN_MIN_VAL && val <= KEY_DOWN_MAX_VAL) + return true; +#endif + return false; +} + void spl_board_init(void) { __maybe_unused struct rk3066_grf * const grf = (void *)GRF_BASE; @@ -49,4 +130,9 @@ void spl_board_init(void) GPIO3B5_SDMMC0_DATA3 << GPIO3B5_SHIFT | GPIO3B6_SDMMC0_DECTN << GPIO3B6_SHIFT); } + + if (rockchip_dnl_key_pressed()) { + printf("Recovery button was pressed!\n"); + do_spl(); + } } -- 2.20.1
Re: Bug in p1_p2_rdb_pc? Caching-inhibited bit for initial L2 SRAM entry in TLB
On Thursday 14 April 2022 23:05:39 Pali Rohár wrote: > + Sinan > > On Wednesday 13 April 2022 11:26:33 Pali Rohár wrote: > > On Tuesday 05 April 2022 10:57:37 Pali Rohár wrote: > > > Hello! > > > > > > I suspect that there is a bug in board/freescale/p1_p2_rdb_pc/tlb.c code > > > which configures TLB entry for initial L2 SRAM. > > > > > > When L2 is 512 kB long (e.g. on P2020) then U-Boot *unsets* MAS2_I bit > > > for first half of L2 and for second half of L2 U-Boot *sets* this bit. > > > > > > See code: > > > https://source.denx.de/u-boot/u-boot/-/blob/v2022.04/board/freescale/p1_p2_rdb_pc/tlb.c#L99-104 > > > > > > I do not think that one part of L2 SRAM should be configured differently > > > as second part. Therefore I think that this is a bug in U-Boot code. > > > > > > Do you know is correct configuration of TLB entries for initial L2 SRAM? > > > > > > MAS2_I is Caching-inhibited bit which is described as: > > > > > > Caching-inhibited: > > > * 0 - Accesses to this page are considered cacheable. > > > * 1 - The page is considered caching-inhibited. All loads and stores to > > > the page bypass the caches and are performed directly to main > > > memory. A read or write to a caching-inhibited page affects only > > > the memory element specified by the operation. > > > > Hello! I found EREF: A Programmer’s Reference Manual for Freescale Power > > Architecture Processors Supports e500 core family (e500v1, e500v2, > > e500mc, e5500, e6500) e200 core family document at NXP web: > > > > https://www.nxp.com/files-static/32bit/doc/ref_manual/EREF_RM.pdf > > > > And section "Cache and MMU Architecture" in part 7.3.1.2.2 Unable to > > Lock Conditions (page 763) contains following information: > > > > If no exceptions occur and no overlocking condition exists, an attempt > > to set a lock can fail if any of the following is true: > > > > • The target address is marked cache-inhibited, or the storage > > attributes of the address uses a coherency protocol that does not > > support locking > > > > So for me it looks like that L2 SRAM (which works at L2 with locked > > cache lines) should not set MA2_I (cache-inhibited) bit. > > > > Any opinion? Or you do have some more information? Hello! I looked at it again and it is more complicated as I initially thought. There are two options how L2 cache on P2020 may be used as SRAM. First option is the classic way with locking lines, like it is done on other architectures. Second option seems to be P1/P2 specific as it is *not* documented in e500 core reference manual, but in P2020 SoC reference manual, and this option changes L2 operation from Cache to Memory-Mapped SRAM mode. Downloading P2020 reference manual (rev2) requires NXP account: https://www.nxp.com/webapp/Download?colCode=P2020RM But some older version (rev0) can be found on internet, e.g.: http://m4udit.dinauz.org/P2020RM_rev0.pdf I checked U-Boot code and it is for L2 SRAM configuration uses second option, therefore not via L2 locked lines, but as L2 memory-mapping. P2020 reference manual in section "Memory-Mapped SRAM Coherency Rules" contains: Accesses to memory-mapped SRAM are cacheable only in the corresponding e500 L1 caches. External accesses must be marked cache-inhibited or be performed with non-caching transactions. So based on the fact that L2 is in U-Boot in memory-mapped SRAM mode, not in cache mode with locked lines and that P2020 RM explicitly says that memory-mapped SRAM can be cacheable in L1, my understanding is that TLB mapping for L2 SRAM should work with Caching-inhibited bit set and also with unset (when unset then caching is disabled at L1 level). Is my deduction correct? Priyanka, Sinan, any idea?
[PATCH v1 17/17] rockchip: configs: mk808: enable usb support
Enable usb support in the mk808_defconfig. Add adc button in full and spl mode to do an action on user demand. Signed-off-by: Johan Jonker --- configs/mk808_defconfig | 21 - 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/configs/mk808_defconfig b/configs/mk808_defconfig index 20bca75a..6ae41a23 100644 --- a/configs/mk808_defconfig +++ b/configs/mk808_defconfig @@ -26,6 +26,7 @@ CONFIG_SPL_FS_FAT=y CONFIG_SYS_LOAD_ADDR=0x70800800 CONFIG_SPL_PAYLOAD="u-boot.bin" CONFIG_DEBUG_UART=y +# CONFIG_ANDROID_BOOT_IMAGE is not set CONFIG_SD_BOOT=y CONFIG_USE_PREBOOT=y CONFIG_DEFAULT_FDT_FILE="rk3066a-mk808.dtb" @@ -35,14 +36,23 @@ CONFIG_BOARD_LATE_INIT=y CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x20 CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SPL_ENV_SUPPORT=y CONFIG_SPL_FS_EXT4=y CONFIG_SYS_MMCSD_FS_BOOT_PARTITION=2 +CONFIG_SPL_MMC_WRITE=y +CONFIG_SPL_USB_HOST=y +CONFIG_SPL_USB_STORAGE=y +CONFIG_SPL_USB_GADGET=y CONFIG_TPL_NEEDS_SEPARATE_STACK=y # CONFIG_BOOTM_PLAN9 is not set # CONFIG_BOOTM_RTEMS is not set # CONFIG_BOOTM_VXWORKS is not set +CONFIG_CMD_ADC=y CONFIG_CMD_GPT=y CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +CONFIG_CMD_ROCKUSB=y +CONFIG_CMD_USB_MASS_STORAGE=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_CACHE=y CONFIG_CMD_TIME=y @@ -51,7 +61,6 @@ CONFIG_SPL_OF_CONTROL=y CONFIG_TPL_OF_CONTROL=y CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" CONFIG_OF_DTB_PROPS_REMOVE=y -CONFIG_SPL_OF_PLATDATA=y CONFIG_TPL_OF_PLATDATA=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set @@ -65,10 +74,13 @@ CONFIG_SPL_SYSCON=y CONFIG_TPL_SYSCON=y # CONFIG_SIMPLE_BUS is not set # CONFIG_SPL_SIMPLE_BUS is not set +CONFIG_SPL_ADC=y +CONFIG_SPL_SARADC_ROCKCHIP=y # CONFIG_TPL_BLK is not set CONFIG_CLK=y CONFIG_SPL_CLK=y CONFIG_TPL_CLK=y +CONFIG_FASTBOOT_BUF_ADDR=0x8000 CONFIG_ROCKCHIP_GPIO=y # CONFIG_SPL_DM_I2C is not set CONFIG_LED=y @@ -97,6 +109,13 @@ CONFIG_TIMER=y CONFIG_SPL_TIMER=y CONFIG_TPL_TIMER=y CONFIG_DESIGNWARE_APB_TIMER=y +CONFIG_USB=y +CONFIG_USB_DWC2=y +CONFIG_ROCKCHIP_USB2_PHY=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_USB_FUNCTION_ROCKUSB=y +CONFIG_SPL_USB_FUNCTION_ROCKUSB=y CONFIG_SPL_TINY_MEMSET=y CONFIG_ERRNO_STR=y # CONFIG_TPL_OF_LIBFDT is not set -- 2.20.1
[PATCH v1 15/17] rockchip: rk3066: config nand data pins in spl
From: Paweł Jarosz The rk3066 grf_soc_con0 allows interchangeable data pin configuration for emmc and nand. Use rockchip_nand_board_early_init function to config nand data pins in spl as bootrom leaves it in default state. Signed-off-by: Paweł Jarosz Signed-off-by: Johan Jonker --- arch/arm/mach-rockchip/rk3066/rk3066.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-rockchip/rk3066/rk3066.c b/arch/arm/mach-rockchip/rk3066/rk3066.c index 78c7d894..1d1b8687 100644 --- a/arch/arm/mach-rockchip/rk3066/rk3066.c +++ b/arch/arm/mach-rockchip/rk3066/rk3066.c @@ -28,12 +28,15 @@ void board_debug_uart_init(void) void spl_board_init(void) { + __maybe_unused struct rk3066_grf * const grf = (void *)GRF_BASE; + if (!IS_ENABLED(CONFIG_SPL_BUILD)) return; - if (IS_ENABLED(CONFIG_SPL_DM_MMC)) { - struct rk3066_grf * const grf = (void *)GRF_BASE; + if (IS_ENABLED(CONFIG_NAND_BOOT)) + rk_clrreg(&grf->soc_con0, EMMC_FLASH_SEL_MASK); + if (IS_ENABLED(CONFIG_SPL_DM_MMC)) { rk_clrsetreg(&grf->gpio3b_iomux, GPIO3B0_MASK | GPIO3B1_MASK | GPIO3B2_MASK | GPIO3B3_MASK | GPIO3B4_MASK | GPIO3B5_MASK | -- 2.20.1
[PATCH v1 12/17] rockchip: adc: fix the hangups
The Rockchip saradc behaves strange when doing an "adc scan" with hang ups. Fix by adding an adc power down before the settings are made. Similair to what TRM recommands follow this flow below: Power-down A/D Converter in SARADC_CTRL[3] Power-up A/D Converter in SARADC_CTRL[3] and select input channel of A/D Converter in SARADC_CTRL[2:0] bit Wait an A/D interrupt or poll the SARADC_STAS register to determine when the conversion is completed Read the conversion result in the SARADC_DATA register Signed-off-by: Johan Jonker --- drivers/adc/rockchip-saradc.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/adc/rockchip-saradc.c b/drivers/adc/rockchip-saradc.c index e6a0341d..fb0f2e03 100644 --- a/drivers/adc/rockchip-saradc.c +++ b/drivers/adc/rockchip-saradc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -82,6 +83,10 @@ int rockchip_saradc_start_channel(struct udevice *dev, int channel) return -EINVAL; } + writel(0, &priv->regs->ctrl); + + udelay(1); + /* 8 clock periods as delay between power up and start cmd */ writel(8, &priv->regs->dly_pu_soc); -- 2.20.1
[PATCH v1 13/17] rockchip: adc: make adc branch compile in SPL
Make the ADC branch compile in SPL. Signed-off-by: Johan Jonker --- drivers/Makefile | 3 ++- drivers/adc/Kconfig | 29 + drivers/adc/Makefile | 4 ++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index 4e7cf284..e79bbe29 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_$(SPL_)FPGA) += fpga/ ifndef CONFIG_TPL_BUILD ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_SPL_ADC) += adc/ obj-$(CONFIG_SPL_CPU) += cpu/ obj-$(CONFIG_SPL_CRYPTO) += crypto/ obj-$(CONFIG_SPL_MPC8XXX_INIT_DDR) += ddr/fsl/ @@ -71,7 +72,7 @@ endif ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TPL_BUILD),) -obj-y += adc/ +obj-$(CONFIG_ADC) += adc/ obj-y += ata/ obj-y += bus/ obj-$(CONFIG_DM_DEMO) += demo/ diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig index e719c38b..68e0d2d3 100644 --- a/drivers/adc/Kconfig +++ b/drivers/adc/Kconfig @@ -1,5 +1,6 @@ config ADC bool "Enable ADC drivers using Driver Model" + depends on DM help This enables ADC API for drivers, which allows driving ADC features by single and multi-channel methods for: @@ -11,8 +12,23 @@ config ADC - support supply's phandle with auto-enable - supply polarity setting in fdt +config SPL_ADC + bool "Enable ADC drivers using Driver Model in SPL" + depends on SPL_DM + help + This enables ADC API for drivers, which allows driving ADC features + by single and multi-channel methods in SPL for: + - start/stop/get data for conversion of a single-channel selected by + a number or multi-channels selected by a bitmask + - get data mask (ADC resolution) + ADC reference Voltage supply options: + - methods for get Vdd/Vss reference Voltage values with polarity + - support supply's phandle with auto-enable + - supply polarity setting in fdt + config ADC_EXYNOS bool "Enable Exynos 54xx ADC driver" + depends on ADC help This enables basic driver for Exynos ADC compatible with Exynos54xx. It provides: @@ -22,6 +38,7 @@ config ADC_EXYNOS config ADC_SANDBOX bool "Enable Sandbox ADC test driver" + depends on ADC help This enables driver for Sandbox ADC device emulation. It provides: @@ -31,6 +48,7 @@ config ADC_SANDBOX config SARADC_MESON bool "Enable Amlogic Meson SARADC driver" + depends on ADC imply REGMAP help This enables driver for Amlogic Meson SARADC. @@ -41,6 +59,7 @@ config SARADC_MESON config SARADC_ROCKCHIP bool "Enable Rockchip SARADC driver" + depends on ADC help This enables driver for Rockchip SARADC. It provides: @@ -48,6 +67,16 @@ config SARADC_ROCKCHIP - 1O or 12 bits resolution - Up to 1MSPS of sample rate +config SPL_SARADC_ROCKCHIP + bool "Enable Rockchip SARADC driver in SPL" + depends on SPL_ADC + help + This enables driver for Rockchip SARADC in SPL. + It provides: + - 2~6 analog input channels + - 1O or 12 bits resolution + - Up to 1MSPS of sample rate + config STM32_ADC bool "Enable STMicroelectronics STM32 ADC driver" depends on ADC && (STM32H7 || ARCH_STM32MP) diff --git a/drivers/adc/Makefile b/drivers/adc/Makefile index c1387f3a..43788c48 100644 --- a/drivers/adc/Makefile +++ b/drivers/adc/Makefile @@ -4,9 +4,9 @@ # Przemyslaw Marczak # -obj-$(CONFIG_ADC) += adc-uclass.o +obj-y += adc-uclass.o obj-$(CONFIG_ADC_EXYNOS) += exynos-adc.o obj-$(CONFIG_ADC_SANDBOX) += sandbox.o -obj-$(CONFIG_SARADC_ROCKCHIP) += rockchip-saradc.o +obj-$(CONFIG_$(SPL_)SARADC_ROCKCHIP) += rockchip-saradc.o obj-$(CONFIG_SARADC_MESON) += meson-saradc.o obj-$(CONFIG_STM32_ADC) += stm32-adc.o stm32-adc-core.o -- 2.20.1
[PATCH v1 14/17] rockchip: adc: move config items in a sub menu
There are multiple ADC config items in the main menu. Move them out of sight in a sub menu. Signed-off-by: Johan Jonker --- drivers/adc/Kconfig | 4 1 file changed, 4 insertions(+) diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig index 68e0d2d3..ba07754a 100644 --- a/drivers/adc/Kconfig +++ b/drivers/adc/Kconfig @@ -1,3 +1,5 @@ +menu "ADC support" + config ADC bool "Enable ADC drivers using Driver Model" depends on DM @@ -92,3 +94,5 @@ config STM32_ADC - core driver to deal with common resources - child driver to deal with individual ADC resources (declare ADC device and associated channels, start/stop conversions) + +endmenu # menu "ADC suupport" -- 2.20.1
[PATCH v1 11/17] rockchip: adc: fix adc timer
Replace adc timer counter by SoC timer to prevent EBUSY notifications. Signed-off-by: Johan Jonker --- drivers/adc/adc-uclass.c | 10 ++ drivers/adc/rockchip-saradc.c | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/adc/adc-uclass.c b/drivers/adc/adc-uclass.c index 3dbdfa6f..a539f999 100644 --- a/drivers/adc/adc-uclass.c +++ b/drivers/adc/adc-uclass.c @@ -146,6 +146,7 @@ int adc_channel_data(struct udevice *dev, int channel, unsigned int *data) struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); const struct adc_ops *ops = dev_get_driver_ops(dev); unsigned int timeout_us = uc_pdata->data_timeout_us; + unsigned long start_time; int ret; if (!ops->channel_data) @@ -155,14 +156,14 @@ int adc_channel_data(struct udevice *dev, int channel, unsigned int *data) if (ret) return ret; + start_time = get_timer(0); do { ret = ops->channel_data(dev, channel, data); if (!ret || ret != -EBUSY) break; - /* TODO: use timer uclass (for early calls). */ sdelay(5); - } while (timeout_us--); + } while (get_timer(start_time) < timeout_us); return ret; } @@ -173,6 +174,7 @@ int adc_channels_data(struct udevice *dev, unsigned int channel_mask, struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); unsigned int timeout_us = uc_pdata->multidata_timeout_us; const struct adc_ops *ops = dev_get_driver_ops(dev); + unsigned long start_time; int ret; if (!ops->channels_data) @@ -182,14 +184,14 @@ int adc_channels_data(struct udevice *dev, unsigned int channel_mask, if (ret) return ret; + start_time = get_timer(0); do { ret = ops->channels_data(dev, channel_mask, channels); if (!ret || ret != -EBUSY) break; - /* TODO: use timer uclass (for early calls). */ sdelay(5); - } while (timeout_us--); + } while (get_timer(start_time) < timeout_us); return ret; } diff --git a/drivers/adc/rockchip-saradc.c b/drivers/adc/rockchip-saradc.c index f61cfe4b..e6a0341d 100644 --- a/drivers/adc/rockchip-saradc.c +++ b/drivers/adc/rockchip-saradc.c @@ -183,7 +183,7 @@ int rockchip_saradc_of_to_plat(struct udevice *dev) uc_pdata->data_mask = (1 << priv->data->num_bits) - 1; uc_pdata->data_format = ADC_DATA_FORMAT_BIN; - uc_pdata->data_timeout_us = SARADC_TIMEOUT / 5; + uc_pdata->data_timeout_us = SARADC_TIMEOUT; uc_pdata->channel_mask = (1 << priv->data->num_channels) - 1; return 0; -- 2.20.1
[PATCH v1 10/17] rockchip: adc: enable spl compile rockchip-saradc driver
Enable spl compile rockchip-saradc driver. When OF_PLATDATA is selected the "vdd-microvolts" property is used instead of vref from regulator to reduze size from the regulator and the gpio class. Signed-off-by: Johan Jonker --- drivers/adc/rockchip-saradc.c | 64 +++ 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/drivers/adc/rockchip-saradc.c b/drivers/adc/rockchip-saradc.c index 760f8fe6..f61cfe4b 100644 --- a/drivers/adc/rockchip-saradc.c +++ b/drivers/adc/rockchip-saradc.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,12 @@ struct rockchip_saradc_priv { const struct rockchip_saradc_data *data; }; +struct rockchip_adc_plat { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_rockchip_adc dtplat; +#endif +}; + int rockchip_saradc_channel_data(struct udevice *dev, int channel, unsigned int *data) { @@ -101,30 +108,48 @@ int rockchip_saradc_stop(struct udevice *dev) int rockchip_saradc_probe(struct udevice *dev) { +#if CONFIG_IS_ENABLED(OF_PLATDATA) || !IS_ENABLED(CONFIG_SPL_BUILD) struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); +#endif struct rockchip_saradc_priv *priv = dev_get_priv(dev); - struct udevice *vref; struct clk clk; - int vref_uv; int ret; - ret = clk_get_by_index(dev, 0, &clk); - if (ret) +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct rockchip_adc_plat *plat = dev_get_plat(dev); + struct dtd_rockchip_adc *dtplat = &plat->dtplat; + + priv->regs = (struct rockchip_saradc_regs *)dtplat->reg[0]; + + ret = clk_get_by_phandle(dev, &dtplat->clocks[0], &clk); + if (ret < 0) return ret; + uc_pdata->vdd_microvolts = dtplat->vdd_microvolts; + uc_pdata->vss_microvolts = 0; +#endif + if (CONFIG_IS_ENABLED(OF_REAL)) { + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return ret; + } + ret = clk_set_rate(&clk, priv->data->clk_rate); if (IS_ERR_VALUE(ret)) return ret; priv->active_channel = -1; +#if !IS_ENABLED(CONFIG_SPL_BUILD) + struct udevice *vref; + ret = device_get_supply_regulator(dev, "vref-supply", &vref); if (ret) { printf("can't get vref-supply: %d\n", ret); return ret; } - vref_uv = regulator_get_value(vref); + int vref_uv = regulator_get_value(vref); if (vref_uv < 0) { printf("can't get vref-supply value: %d\n", vref_uv); return vref_uv; @@ -134,6 +159,7 @@ int rockchip_saradc_probe(struct udevice *dev) uc_pdata->vdd_supply = vref; uc_pdata->vdd_microvolts = vref_uv; uc_pdata->vss_microvolts = 0; +#endif return 0; } @@ -142,16 +168,19 @@ int rockchip_saradc_of_to_plat(struct udevice *dev) { struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); struct rockchip_saradc_priv *priv = dev_get_priv(dev); - struct rockchip_saradc_data *data; - data = (struct rockchip_saradc_data *)dev_get_driver_data(dev); - priv->regs = (struct rockchip_saradc_regs *)dev_read_addr(dev); - if (priv->regs == (struct rockchip_saradc_regs *)FDT_ADDR_T_NONE) { - pr_err("Dev: %s - can't get address!", dev->name); - return -ENODATA; + if (CONFIG_IS_ENABLED(OF_REAL)) { + priv->regs = (struct rockchip_saradc_regs *)dev_read_addr(dev); + if (priv->regs == (struct rockchip_saradc_regs *)FDT_ADDR_T_NONE) { + pr_err("Dev: %s - can't get address!", dev->name); + return -ENODATA; + } + } else { + dev->driver_data = dev->driver->of_match->data; } - priv->data = data; + priv->data = (struct rockchip_saradc_data *)dev_get_driver_data(dev); + uc_pdata->data_mask = (1 << priv->data->num_bits) - 1; uc_pdata->data_format = ADC_DATA_FORMAT_BIN; uc_pdata->data_timeout_us = SARADC_TIMEOUT / 5; @@ -194,12 +223,17 @@ static const struct udevice_id rockchip_saradc_ids[] = { { } }; -U_BOOT_DRIVER(rockchip_saradc) = { - .name = "rockchip_saradc", +U_BOOT_DRIVER(rockchip_adc) = { + .name = "rockchip_adc", .id = UCLASS_ADC, .of_match = rockchip_saradc_ids, .ops= &rockchip_saradc_ops, .probe = rockchip_saradc_probe, - .of_to_plat = rockchip_saradc_of_to_plat, + .of_to_plat = rockchip_saradc_of_to_plat, .priv_auto = sizeof(struct rockchip_saradc_priv), + .plat_auto = sizeof(struct rockchip_adc_plat), + }; +DM_DRIVER_ALIAS(rockchip_adc, rockchip_saradc) +DM_DRIVER_ALIAS(rockchip_adc, rockchip_rk3066_tsadc) +DM_DRIVER_AL
[PATCH v1 08/17] rockchip: adc: enable spl compile class driver
Enable spl compile of the class driver for other compile modes then OF_REAL, so that at least it doesn't break the process. Use #if because code review shows that IS_ENABLED() and device_get_supply_regulator() results in probe failure. Signed-off-by: Johan Jonker --- drivers/adc/adc-uclass.c | 33 +++-- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/adc/adc-uclass.c b/drivers/adc/adc-uclass.c index 67137ffb..e8ce638d 100644 --- a/drivers/adc/adc-uclass.c +++ b/drivers/adc/adc-uclass.c @@ -199,7 +199,11 @@ int adc_channel_single_shot(const char *name, int channel, unsigned int *data) struct udevice *dev; int ret; +#if IS_ENABLED(CONFIG_SPL_BUILD) + ret = uclass_get_device(UCLASS_ADC, 0, &dev); +#else ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev); +#endif if (ret) return ret; @@ -248,7 +252,11 @@ int adc_channels_single_shot(const char *name, unsigned int channel_mask, struct udevice *dev; int ret; +#if IS_ENABLED(CONFIG_SPL_BUILD) + ret = uclass_get_device(UCLASS_ADC, 0, &dev); +#else ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev); +#endif if (ret) return ret; @@ -372,20 +380,26 @@ int adc_raw_to_uV(struct udevice *dev, unsigned int raw, int *uV) static int adc_vdd_plat_set(struct udevice *dev) { struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); - int ret; char *prop; + uc_pdata->vdd_microvolts = -ENODATA; + + if (CONFIG_IS_ENABLED(OF_PLATDATA)) + return 0; + prop = "vdd-polarity-negative"; uc_pdata->vdd_polarity_negative = dev_read_bool(dev, prop); /* Optionally get regulators */ - ret = device_get_supply_regulator(dev, "vdd-supply", - &uc_pdata->vdd_supply); +#if !IS_ENABLED(CONFIG_SPL_BUILD) + int ret = device_get_supply_regulator(dev, "vdd-supply", + &uc_pdata->vdd_supply); if (!ret) return adc_vdd_plat_update(dev); if (ret != -ENOENT) return ret; +#endif /* No vdd-supply phandle. */ prop = "vdd-microvolts"; @@ -397,19 +411,26 @@ static int adc_vdd_plat_set(struct udevice *dev) static int adc_vss_plat_set(struct udevice *dev) { struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); - int ret; char *prop; + uc_pdata->vss_microvolts = -ENODATA; + + if (CONFIG_IS_ENABLED(OF_PLATDATA)) + return 0; + prop = "vss-polarity-negative"; uc_pdata->vss_polarity_negative = dev_read_bool(dev, prop); - ret = device_get_supply_regulator(dev, "vss-supply", - &uc_pdata->vss_supply); + /* Optionally get regulators */ +#if !IS_ENABLED(CONFIG_SPL_BUILD) + int ret = device_get_supply_regulator(dev, "vss-supply", + &uc_pdata->vss_supply); if (!ret) return adc_vss_plat_update(dev); if (ret != -ENOENT) return ret; +#endif /* No vss-supply phandle. */ prop = "vss-microvolts"; -- 2.20.1
[PATCH v1 09/17] rockchip: adc: reduce error notifications from class driver
The adc class driver reads optional "vss-supply" and "vdd-supply" properties. The SoC adc driver can parse for vref, so reduce error notifications when not found. Signed-off-by: Johan Jonker --- drivers/adc/adc-uclass.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/adc/adc-uclass.c b/drivers/adc/adc-uclass.c index e8ce638d..3dbdfa6f 100644 --- a/drivers/adc/adc-uclass.c +++ b/drivers/adc/adc-uclass.c @@ -446,12 +446,12 @@ static int adc_pre_probe(struct udevice *dev) /* Set ADC VDD plat: polarity, uV, regulator (phandle). */ ret = adc_vdd_plat_set(dev); if (ret) - pr_err("%s: Can't update Vdd. Error: %d", dev->name, ret); + pr_debug("%s: Can't update Vdd: %d", dev->name, ret); /* Set ADC VSS plat: polarity, uV, regulator (phandle). */ ret = adc_vss_plat_set(dev); if (ret) - pr_err("%s: Can't update Vss. Error: %d", dev->name, ret); + pr_debug("%s: Can't update Vss: %d", dev->name, ret); return 0; } -- 2.20.1
[PATCH v1 07/17] arm: dts: rockchip: mk808: add adc usb required properties for spl
Add adc and usb required properties for spl to rk3066a-mk808-u-boot.dtsi Signed-off-by: Johan Jonker --- arch/arm/dts/rk3066a-mk808-u-boot.dtsi | 29 ++ 1 file changed, 29 insertions(+) diff --git a/arch/arm/dts/rk3066a-mk808-u-boot.dtsi b/arch/arm/dts/rk3066a-mk808-u-boot.dtsi index e0aa929f..60b39026 100644 --- a/arch/arm/dts/rk3066a-mk808-u-boot.dtsi +++ b/arch/arm/dts/rk3066a-mk808-u-boot.dtsi @@ -6,6 +6,10 @@ config { u-boot,boot-led = "mk808:blue:power"; }; + + chosen { + u-boot,spl-boot-order = &mmc0, &usb_host; + }; }; &cru { @@ -39,6 +43,11 @@ compatible = "rockchip,rk3066-noc", "syscon"; }; +&saradc { + vdd-microvolts = <250>; + u-boot,dm-spl; +}; + &timer2 { clock-frequency = <2400>; u-boot,dm-pre-reloc; @@ -47,3 +56,23 @@ &uart2 { u-boot,dm-pre-reloc; }; + +&usb_host { + u-boot,dm-spl; +}; + +&usb_otg { + u-boot,dm-spl; +}; + +&usbphy { + u-boot,dm-spl; +}; + +&usbphy0 { + u-boot,dm-spl; +}; + +&usbphy1 { + u-boot,dm-spl; +}; -- 2.20.1
[PATCH v1 06/17] rockchip: configs: mk808: add spl usb configs
Add usb spl configs for mk808. Signed-off-by: Johan Jonker --- include/configs/mk808.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/configs/mk808.h b/include/configs/mk808.h index e2ab2b51..5a0c7fbc 100644 --- a/include/configs/mk808.h +++ b/include/configs/mk808.h @@ -6,4 +6,7 @@ #define ROCKCHIP_DEVICE_SETTINGS #include +#define CONFIG_SYS_USB_FAT_BOOT_PARTITION 1 +#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME"u-boot.img" + #endif -- 2.20.1
[PATCH v1 03/17] rockchip: spl-boot-order: add usb boot option
Add usb boot option to spl-boot-order.c Signed-off-by: Johan Jonker --- arch/arm/mach-rockchip/spl-boot-order.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-rockchip/spl-boot-order.c b/arch/arm/mach-rockchip/spl-boot-order.c index 93b8e7de..c4ba369b 100644 --- a/arch/arm/mach-rockchip/spl-boot-order.c +++ b/arch/arm/mach-rockchip/spl-boot-order.c @@ -77,6 +77,9 @@ static int spl_node_to_boot_device(int node) if (!uclass_get_device_by_of_offset(UCLASS_SPI_FLASH, node, &parent)) return BOOT_DEVICE_SPI; + if (!uclass_get_device_by_of_offset(UCLASS_USB, node, &parent)) + return BOOT_DEVICE_USB; + return -1; } -- 2.20.1
[PATCH v1 04/17] rockchip: board: allow spl compile for usb init functions
The usb init functions in board.c are needed in SPL during boot, so allow SPL compile for board.c Signed-off-by: Johan Jonker --- arch/arm/mach-rockchip/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 6c1c7b8a..ebe0afa2 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -22,10 +22,11 @@ ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TPL_BUILD),) # we can have the preprocessor correctly recognise both 0x0 and 0 # meaning "turn it off". obj-y += boot_mode.o -obj-$(CONFIG_ROCKCHIP_COMMON_BOARD) += board.o obj-$(CONFIG_MISC_INIT_R) += misc.o endif +obj-$(CONFIG_ROCKCHIP_COMMON_BOARD) += board.o + ifeq ($(CONFIG_TPL_BUILD),) obj-$(CONFIG_DISPLAY_CPUINFO) += cpu-info.o endif -- 2.20.1
[PATCH v1 05/17] rockchip: usb: gadget: rockusb: enable spl compile
Enable spl compile for rockusb. Signed-off-by: Johan Jonker --- drivers/usb/gadget/Kconfig | 10 ++ drivers/usb/gadget/Makefile | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 8c6cf474..b10f1956 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -164,6 +164,16 @@ config USB_FUNCTION_MASS_STORAGE config USB_FUNCTION_ROCKUSB bool "Enable USB rockusb gadget" + depends on BLK +help + Rockusb protocol is widely used by Rockchip SoC based devices. It can + read/write info, image to/from devices. This enables the USB part of + the rockusb gadget.for more detail about Rockusb protocol, please see + doc/README.rockusb + +config SPL_USB_FUNCTION_ROCKUSB +bool "Enable USB rockusb gadget in SPL" + depends on SPL_BLK help Rockusb protocol is widely used by Rockchip SoC based devices. It can read/write info, image to/from devices. This enables the USB part of diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index d5d891b2..095d1faa 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_USB_GADGET_DWC2_OTG) += dwc2_udc_otg.o obj-$(CONFIG_USB_GADGET_DWC2_OTG_PHY) += dwc2_udc_otg_phy.o obj-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o obj-$(CONFIG_USB_GADGET_MAX3420) += max3420_udc.o +obj-$(CONFIG_$(SPL_)USB_FUNCTION_ROCKUSB) += f_rockusb.o obj-$(CONFIG_CI_UDC) += ci_udc.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_USB_GADGET_DOWNLOAD) += g_dnl.o @@ -29,7 +30,6 @@ obj-$(CONFIG_DFU_OVER_USB) += f_dfu.o obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o obj-$(CONFIG_USB_FUNCTION_SDP) += f_sdp.o -obj-$(CONFIG_USB_FUNCTION_ROCKUSB) += f_rockusb.o obj-$(CONFIG_USB_FUNCTION_ACM) += f_acm.o endif endif -- 2.20.1
[PATCH v1 01/17] rockchip: spl: fix reloc gd and FDT blob pointer
When the Rockchip function dram_init() is called in the spl.c board_init_f() the variable gd->ram_base returns 0. This is problematic for functions after the gd relocation. Fix by adding ram.base to gd->ram_base in sdram.c. After the function spl_relocate_stack_gd is called in crt0.S the pointer gd might be relocated and BSS with the FDT blob is erased. The pointer gd->fdt_blob is no longer valid when enabled SPL_OF_REAL and SPL_MMC, SPL_USB_HOST or SPL_USB_GADGET. This patch makes that FDT properties can be parsed in the board_init_r() function. Fix by setting this pointers simulair to board_f.c and copy the FDT to it's new location at the end of DRAM. Signed-off-by: Johan Jonker --- arch/arm/mach-rockchip/sdram.c | 1 + arch/arm/mach-rockchip/spl.c | 16 2 files changed, 17 insertions(+) diff --git a/arch/arm/mach-rockchip/sdram.c b/arch/arm/mach-rockchip/sdram.c index 705ec7ba..b5972269 100644 --- a/arch/arm/mach-rockchip/sdram.c +++ b/arch/arm/mach-rockchip/sdram.c @@ -198,6 +198,7 @@ int dram_init(void) debug("Cannot get DRAM size: %d\n", ret); return ret; } + gd->ram_base = ram.base; gd->ram_size = ram.size; debug("SDRAM base=%lx, size=%lx\n", (unsigned long)ram.base, (unsigned long)ram.size); diff --git a/arch/arm/mach-rockchip/spl.c b/arch/arm/mach-rockchip/spl.c index 30be6404..ceef9d91 100644 --- a/arch/arm/mach-rockchip/spl.c +++ b/arch/arm/mach-rockchip/spl.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -149,6 +150,21 @@ void board_init_f(ulong dummy) } gd->ram_top = gd->ram_base + get_effective_memsize(); gd->ram_top = board_get_usable_ram_top(gd->ram_size); + + /* Copy FDT blob from BSS to the end of DRAM */ + if (gd->fdt_blob) { + gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob), 32); + unsigned long fdt_addr = ALIGN_DOWN(gd->ram_top - gd->fdt_size, 16); + + gd->new_fdt = map_sysmem(fdt_addr, gd->fdt_size); + + debug("Reserved %lu bytes for FDT at: %08lx\n", gd->fdt_size, fdt_addr); + + if (gd->new_fdt) { + memcpy(gd->new_fdt, gd->fdt_blob, fdt_totalsize(gd->fdt_blob)); + gd->fdt_blob = gd->new_fdt; + } + } #endif preloader_console_init(); } -- 2.20.1
[PATCH v1 02/17] rockchip: spl: allow more boot devices
Rockchip SoCs have more boot device options then currently included in the function spl_boot_device(). Make this function generic for SPI and NAND. Signed-off-by: Johan Jonker --- arch/arm/mach-rockchip/spl.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-rockchip/spl.c b/arch/arm/mach-rockchip/spl.c index ceef9d91..968f896a 100644 --- a/arch/arm/mach-rockchip/spl.c +++ b/arch/arm/mach-rockchip/spl.c @@ -53,13 +53,16 @@ u32 spl_boot_device(void) { u32 boot_device = BOOT_DEVICE_MMC1; -#if defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \ +#if defined(CONFIG_SPI_BOOT) || \ + defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \ defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \ defined(CONFIG_TARGET_CHROMEBOOK_MINNIE) || \ defined(CONFIG_TARGET_CHROMEBOOK_SPEEDY) || \ defined(CONFIG_TARGET_CHROMEBOOK_BOB) || \ defined(CONFIG_TARGET_CHROMEBOOK_KEVIN) return BOOT_DEVICE_SPI; +#elseif defined(CONFIG_NAND_BOOT) + return BOOT_DEVICE_NAND; #endif if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)) return BOOT_DEVICE_BOOTROM; -- 2.20.1
[PATCH v1 00/17] Add rk3066 ADC and USB support
Add rk3066 ADC and USB support. The Rockchip SoC rk3066 has no support for MMC and USB in the BootROM. The TPL/SPL parts are mostly stored on NAND. With U-boot stored on an external media the moment a user wants to start a recovery action it has to be done in SPL. Some boards only have one ADC switch for the user and no serial console. The U-boot USB drivers only works in combination with OF_REAL enabled. For current ARM SoCs the FDT stored in BBS is erased after SPL relocation in the crt0.S main function. So for drivers to work in SPL, FDT is move to the end of DRAM. The global_data must update there pointers. The common Rockchip functions must also become available in SPL. Most work has to be done on the ADC driver that has recently had a "upgrade" for a vref regulator. For Rockchip this regulator are mostly fixed. As we are in SPL that would introduce 2 extra U-boot classes UCLASS_REGULATOR and UCLASS_GPIO. In SPL there's no pin control yet, so reduce code and read these ADC properties from the DT in SPL. While testing some improvement had to be made for reliability. Fixup SPL compile and the way the ADC section is shown in U-boot's main menu. Add a __weak recovery button function as condition to enter the recovery mode in spl. It then looks for a boot_device to select a storage function method. And finally run the rockusb gadget while connected to a USB host. Enable all new futures by adding them to the mk808_defconfig. Johan Jonker (16): rockchip: spl: fix reloc gd and FDT blob pointer rockchip: spl: allow more boot devices rockchip: spl-boot-order: add usb boot option rockchip: board: allow spl compile for usb init functions rockchip: usb: gadget: rockusb: enable spl compile rockchip: configs: mk808: add spl usb configs arm: dts: rockchip: mk808: add adc usb required properties for spl rockchip: adc: enable spl compile class driver rockchip: adc: reduce error notifications from class driver rockchip: adc: enable spl compile rockchip-saradc driver rockchip: adc: fix adc timer rockchip: adc: fix the hangups rockchip: adc: make adc branch compile in SPL rockchip: adc: move config items in a sub menu rockchip: rk3066: add recovery mode in spl rockchip: configs: mk808: enable usb support Paweł Jarosz (1): rockchip: rk3066: config nand data pins in spl arch/arm/dts/rk3066a-mk808-u-boot.dtsi| 29 ++ .../arm/include/asm/arch-rockchip/f_rockusb.h | 1 + arch/arm/mach-rockchip/Makefile | 3 +- arch/arm/mach-rockchip/rk3066/rk3066.c| 93 ++- arch/arm/mach-rockchip/sdram.c| 1 + arch/arm/mach-rockchip/spl-boot-order.c | 3 + arch/arm/mach-rockchip/spl.c | 21 - configs/mk808_defconfig | 21 - drivers/Makefile | 3 +- drivers/adc/Kconfig | 33 +++ drivers/adc/Makefile | 4 +- drivers/adc/adc-uclass.c | 47 +++--- drivers/adc/rockchip-saradc.c | 71 ++ drivers/usb/gadget/Kconfig| 10 ++ drivers/usb/gadget/Makefile | 2 +- include/configs/mk808.h | 3 + 16 files changed, 308 insertions(+), 37 deletions(-) -- 2.20.1
Re: [PATCH 1/1] add support for mws4 board
On Sun, May 08, 2022 at 03:46:55PM +0200, Marian Ulbricht wrote: > mws4 is an arm based nuclear probe hardware used from german government to > monitor nuclear activity > > Signed-off-by: Marian Ulbricht Thanks for the submission. Have you submitted the board dts files to upstream Linux? Also, please remove all of the commented out code in the board files, etc. -- Tom signature.asc Description: PGP signature
[PATCH 1/1] add support for mws4 board
mws4 is an arm based nuclear probe hardware used from german government to monitor nuclear activity Signed-off-by: Marian Ulbricht --- arch/arm/dts/Makefile | 3 + arch/arm/dts/omap3-mws4-u-boot.dtsi | 14 ++ arch/arm/dts/omap3-mws4.dts | 137 ++ arch/arm/mach-omap2/omap3/Kconfig | 10 + board/ultratronik/mws4/Kconfig | 12 ++ board/ultratronik/mws4/MAINTAINERS | 6 + board/ultratronik/mws4/Makefile | 6 + board/ultratronik/mws4/default.env | 11 ++ board/ultratronik/mws4/mws4.c | 283 board/ultratronik/mws4/mws4.h | 203 configs/omap3_mws4_defconfig| 74 include/configs/omap3_mws4.h| 103 ++ 12 files changed, 862 insertions(+) create mode 100644 arch/arm/dts/omap3-mws4-u-boot.dtsi create mode 100644 arch/arm/dts/omap3-mws4.dts create mode 100644 board/ultratronik/mws4/Kconfig create mode 100644 board/ultratronik/mws4/MAINTAINERS create mode 100644 board/ultratronik/mws4/Makefile create mode 100644 board/ultratronik/mws4/default.env create mode 100644 board/ultratronik/mws4/mws4.c create mode 100644 board/ultratronik/mws4/mws4.h create mode 100644 configs/omap3_mws4_defconfig create mode 100644 include/configs/omap3_mws4.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 83630af4f6..7b68a49990 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1047,6 +1047,9 @@ dtb-$(CONFIG_TARGET_OMAP3_BEAGLE) += \ omap3-beagle-xm.dtb \ omap3-beagle.dtb +dtb-$(CONFIG_TARGET_OMAP3_MWS4) += \ +omap3-mws4.dtb + dtb-$(CONFIG_TARGET_OMAP3_IGEP00X0) += \ omap3-igep0020.dtb diff --git a/arch/arm/dts/omap3-mws4-u-boot.dtsi b/arch/arm/dts/omap3-mws4-u-boot.dtsi new file mode 100644 index 00..2c03701c89 --- /dev/null +++ b/arch/arm/dts/omap3-mws4-u-boot.dtsi @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * U-Boot additions + * + * (C) Copyright 2017 Derald D. Woods + */ + +#include "omap3-u-boot.dtsi" + +/ { + chosen { + stdout-path = &uart3; + }; +}; diff --git a/arch/arm/dts/omap3-mws4.dts b/arch/arm/dts/omap3-mws4.dts new file mode 100644 index 00..f8a5c3d5b8 --- /dev/null +++ b/arch/arm/dts/omap3-mws4.dts @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * Modified 2015 by Bernhard Gätzschmann, Ultratronik from Beagleboard xM + * + * Modified 2022 Marian Ulbricht ulbri...@innoroute.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "omap34xx.dtsi" + +/ { + model = "Ultratronik BFS MWS4"; + compatible = "ti,omap3-mmi4", "ti,omap3"; + + memory { + device_type = "memory"; + reg = <0x8000 0x1000>; /* 256 MB */ + }; + + hwconfig { + i_enable_mmc = <1>; + i_enable_musb = <1>; + i_musb_mode = <1>;/*0-undefined, 1-HOST, 2-PERIPHERAL, 3-OTG*/ + i_musb_power=<500>; + i_enable_ehci = <0>; + i_usb_reset_gpio = <20>; /* DUMMY Entry */ + i_enable_eth = <1>; + i_eth_irq_gpio = <130>; + i_eth_fifo_gpio = <0>; + i_eth_cs = <4>; + i_gpio_leds_0 = "led0:red", "none", "false", "102", "0"; + i_gpio_leds_1 = "led1:yellow", "none", "false", "103", "0"; + i_gpio_leds_2 = "led2:green", "none", "false", "104", "0"; + i_gpio_leds_3 = "led3:orange", "none", "false", "101", "0"; + i_gpio_leds_4 = "usb:enable", "none", "false", "110", "1"; + i_gpio_leds_5 = "usbhub:reset", "none", "false", "27", "0"; + i_gpio_leds_6 = "iic:reset", "none", "false", "163", "0"; + i_gpio_leds_7 = "rs232:reset", "none", "false", "26", "0"; + i_i2c_bus_hw_2 = "2", "100"; + i_i2c_device_0 = "rtc8564", "0x51", "2"; + i_i2c_bus_hw_3 = "3", "100"; + i_enable_flash = <1>; + i_enable_audio = <0>; + i_enable_video = <0>; + i_enable_can = <0>; + }; + + ue_pinctrl { +/* GPIO: HW ID */ + pin_94 = "cam_hs.gpio_94", "IEN", "PTU", "DIS"; /* GPIO_94 */ + pin_95 = "cam_vs.gpio_95", "IEN", "PTU", "DIS"; /* GPIO_95 */ + pin_96 = "cam_xclka.gpio_96", "IEN", "PTU", "DIS"; /* GPIO_96 */ + +/* GPIO: Digital Out */ + pin_156 = "mcbsp1_clkr.gpio_156", "IEN", "PTU", "DIS"; /* GPIO_156 */ + pin_157 = "mcbsp1_fsr.gpio_157", "IEN", "PTU", "DIS"; /* GPIO_157 */ + pin_158 = "mcbsp1_dx.gpio_158", "IEN", "PTU", "DIS"; /* GPIO_158 */ +
Re: [PATCH V2] ARM: imx: imx8m: Adjust thermal trip points for Industrial parts
On 5/8/22 04:59, Adam Ford wrote: On Sat, May 7, 2022 at 5:00 PM Marek Vasut wrote: On 5/7/22 14:04, Adam Ford wrote: If the thermal sensor is enabled in U-Boot, adjust the cpu-thermal trip points for industrial rated parts. This should apply to 8MQ, 8MM, 8MN, and 8MP. Signed-off-by: Adam Ford Reviewed-by: Tim Harvey --- V2: Switch the check from looking for industrial or checkoing for anything but commerical. This expands the trip point updates other grades as well. Are the industrial and automotive trip points identical ? I do not know nor do I have any to test, but Francisco asked for the change. I would expect the corresponding values would be fetched with get_cpu_temp_grade() Ah, I see. But then I have to wonder, why are we updating only non-commercial trip points ? Why not update them always ?
[PATCH 9/9] dm: spl: Allow SPL to show memory usage
Add an option to tell SPL to show memory usage for driver model just before it boots into the next phase. Signed-off-by: Simon Glass --- common/spl/spl.c | 9 + drivers/core/Kconfig | 10 ++ 2 files changed, 19 insertions(+) diff --git a/common/spl/spl.c b/common/spl/spl.c index c8c463f80bd..540e1925577 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -780,6 +781,14 @@ void board_init_r(gd_t *dummy1, ulong dummy2) bootcount_inc(); + /* Dump driver model states to aid analysis */ + if (CONFIG_IS_ENABLED(DM_STATS)) { + struct dm_stats mem; + + dm_get_mem(&mem); + dm_dump_mem(&mem); + } + memset(&spl_image, '\0', sizeof(spl_image)); #ifdef CONFIG_SYS_SPL_ARGS_ADDR spl_image.arg = (void *)CONFIG_SYS_SPL_ARGS_ADDR; diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index fa2811af83c..5c35914d30b 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -86,6 +86,16 @@ config DM_STATS To display the memory stats, use the 'dm mem' command. +config SPL_DM_STATS + bool "Collect and show driver model stats in SPL" + depends on DM_SPL + help + Enable this to collect and display memory statistics about driver + model. This can help to figure out where all the memory is going and + to find optimisations. + + The stats are displayed just before SPL boots to the next phase. + config DM_DEVICE_REMOVE bool "Support device removal" depends on DM -- 2.36.0.512.ge40c2bad7a-goog
[PATCH 8/9] dm: core: Add a command to show driver model statistics
This command shows the memory used by driver model along with various hints as to what it might be if some 'core' tags were moved to use the tag list instead of a core (i.e. always-there) pointer. This may help with future work to reduce memory usage. Signed-off-by: Simon Glass --- cmd/dm.c | 23 ++ drivers/core/Kconfig | 11 +++ drivers/core/dump.c | 73 drivers/core/tag.c | 18 +++ include/dm/root.h| 2 +- include/dm/tag.h | 8 + include/dm/util.h| 9 ++ 7 files changed, 143 insertions(+), 1 deletion(-) diff --git a/cmd/dm.c b/cmd/dm.c index 4c0a8a53ced..3814dcd20f1 100644 --- a/cmd/dm.c +++ b/cmd/dm.c @@ -40,6 +40,19 @@ static int do_dm_dump_drivers(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } +#if CONFIG_IS_ENABLED(DM_STATS) +static int do_dm_dump_mem(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct dm_stats mem; + + dm_get_mem(&mem); + dm_dump_mem(&mem); + + return 0; +} +#endif /* DM_STATS */ + static int do_dm_dump_static_driver_info(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) { @@ -68,6 +81,9 @@ static struct cmd_tbl test_commands[] = { U_BOOT_CMD_MKENT(compat, 1, 1, do_dm_dump_driver_compat, "", ""), U_BOOT_CMD_MKENT(devres, 1, 1, do_dm_dump_devres, "", ""), U_BOOT_CMD_MKENT(drivers, 1, 1, do_dm_dump_drivers, "", ""), +#if CONFIG_IS_ENABLED(DM_STATS) + U_BOOT_CMD_MKENT(mem, 1, 1, do_dm_dump_mem, "", ""), +#endif U_BOOT_CMD_MKENT(static, 1, 1, do_dm_dump_static_driver_info, "", ""), U_BOOT_CMD_MKENT(tree, 0, 1, do_dm_dump_tree, "", ""), U_BOOT_CMD_MKENT(uclass, 1, 1, do_dm_dump_uclass, "", ""), @@ -106,12 +122,19 @@ static int do_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return cmd_process_error(test_cmd, ret); } +#if CONFIG_IS_ENABLED(DM_STATS) +#define DM_MEM_HELP"dm mem Provide a summary of memory usage\n" +#else +#define DM_MEM_HELP +#endif + U_BOOT_CMD( dm, 3, 1, do_dm, "Driver model low level access", "compatDump list of drivers with compatibility strings\n" "dm devresDump list of device resources for each device\n" "dm drivers Dump list of drivers with uclass and instances\n" + DM_MEM_HELP "dm staticDump list of drivers with static platform data\n" "dm tree Dump tree of driver model devices ('*' = activated)\n" "dm uclassDump list of instances for each uclass" diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 408a8d8e28b..fa2811af83c 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -75,6 +75,17 @@ config DM_DEBUG help Say Y here if you want to compile in debug messages in DM core. +config DM_STATS + bool "Collect and show driver model stats" + depends on DM + default y if SANDBOX + help + Enable this to collect and display memory statistics about driver + model. This can help to figure out where all the memory is going and + to find optimisations. + + To display the memory stats, use the 'dm mem' command. + config DM_DEVICE_REMOVE bool "Support device removal" depends on DM diff --git a/drivers/core/dump.c b/drivers/core/dump.c index ce679e26290..43d1349635b 100644 --- a/drivers/core/dump.c +++ b/drivers/core/dump.c @@ -174,3 +174,76 @@ void dm_dump_static_driver_info(void) for (entry = drv; entry != drv + n_ents; entry++) printf("%-25.25s %p\n", entry->name, entry->plat); } + +void dm_dump_mem(struct dm_stats *stats) +{ + int total, total_delta; + int i; + + /* Support SPL printf() */ + printf("Struct sizes: udevice %x, driver %x, uclass %x, uc_driver %x\n", + (int)sizeof(struct udevice), (int)sizeof(struct driver), + (int)sizeof(struct uclass), (int)sizeof(struct uclass_driver)); + printf("Memory: device %x:%x, device names %x, uclass %x:%x\n", + stats->dev_count, stats->dev_size, stats->dev_name_size, + stats->uc_count, stats->uc_size); + printf("\n"); + printf("%-15s %5s %5s %5s %5s %5s\n", "Attached type", "Count", + "Size", "Cur", "Tags", "Save"); + printf("%-15s %5s %5s %5s %5s %5s\n", "---", "-", + "-", "-", "-", "-"); + total_delta = 0; + for (i = 0; i < DM_TAG_ATTACH_COUNT; i++) { + int cur_size, new_size, delta; + + cur_size = stats->dev_count * sizeof(struct udevice); + new_size = stats->dev_count * (sizeof(struct udevice) - + sizeof(void *)); + /* +* Let's assume we
[PATCH 7/9] dm: core: Add a way to collect memory usage
Add a function for collecting the amount of memory used by driver model, including devices, uclasses and attached data and tags. This information can provide insights into how to reduce the memory required by driver model. Future work may look at execution speed also. Signed-off-by: Simon Glass --- drivers/core/root.c | 53 + drivers/core/tag.c | 11 ++ include/dm/root.h | 45 ++ include/dm/tag.h| 11 ++ test/dm/core.c | 11 ++ 5 files changed, 131 insertions(+) diff --git a/drivers/core/root.c b/drivers/core/root.c index 17dd1205a32..f24ddfa5218 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -449,6 +449,59 @@ void dm_get_stats(int *device_countp, int *uclass_countp) *uclass_countp = uclass_get_count(); } +void dev_collect_stats(struct dm_stats *stats, const struct udevice *parent) +{ + const struct udevice *dev; + int i; + + stats->dev_count++; + stats->dev_size += sizeof(struct udevice); + stats->dev_name_size += strlen(parent->name) + 1; + for (i = 0; i < DM_TAG_ATTACH_COUNT; i++) { + int size = dev_get_attach_size(parent, i); + + if (size || + (i == DM_TAG_DRIVER_DATA && parent->driver_data)) { + stats->attach_count[i]++; + stats->attach_size[i] += size; + stats->attach_count_total++; + stats->attach_size_total += size; + } + } + + list_for_each_entry(dev, &parent->child_head, sibling_node) + dev_collect_stats(stats, dev); +} + +void uclass_collect_stats(struct dm_stats *stats) +{ + struct uclass *uc; + + list_for_each_entry(uc, gd->uclass_root, sibling_node) { + int size; + + stats->uc_count++; + stats->uc_size += sizeof(struct uclass); + size = uc->uc_drv->priv_auto; + if (size) { + stats->uc_attach_count++; + stats->uc_attach_size += size; + } + } +} + +void dm_get_mem(struct dm_stats *stats) +{ + memset(stats, '\0', sizeof(*stats)); + dev_collect_stats(stats, gd->dm_root); + uclass_collect_stats(stats); + dev_tag_collect_stats(stats); + + stats->total_size = stats->dev_size + stats->uc_size + + stats->attach_size_total + stats->uc_attach_size + + stats->tag_size; +} + #ifdef CONFIG_ACPIGEN static int root_acpi_get_name(const struct udevice *dev, char *out_name) { diff --git a/drivers/core/tag.c b/drivers/core/tag.c index 22999193a5a..2961725b658 100644 --- a/drivers/core/tag.c +++ b/drivers/core/tag.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -137,3 +138,13 @@ int dev_tag_del_all(struct udevice *dev) return -ENOENT; } + +void dev_tag_collect_stats(struct dm_stats *stats) +{ + struct dmtag_node *node; + + list_for_each_entry(node, &gd->dmtag_list, sibling) { + stats->tag_count++; + stats->tag_size += sizeof(struct dmtag_node); + } +} diff --git a/include/dm/root.h b/include/dm/root.h index e888fb993c0..382f83c7f5b 100644 --- a/include/dm/root.h +++ b/include/dm/root.h @@ -9,11 +9,49 @@ #ifndef _DM_ROOT_H_ #define _DM_ROOT_H_ +#include + struct udevice; /* Head of the uclass list if CONFIG_OF_PLATDATA_INST is enabled */ extern struct list_head uclass_head; +/** + * struct dm_stats - Information about driver model memory usage + * + * @total_size: All data + * @dev_count: Number of devices + * @dev_size: Size of all devices (just the struct udevice) + * @dev_name_size: Bytes used by device names + * @uc_count: Number of uclasses + * @uc_size: Size of all uclasses (just the struct uclass) + * @tag_count: Number of tags + * @tag_size: Bytes used by all tags + * @uc_attach_count: Number of uclasses with attached data (priv) + * @uc_attach_size: Total size of that attached data + * @attach_count_total: Total number of attached data items for all udevices and + * uclasses + * @attach_size_total: Total number of bytes of attached data + * @attach_count: Number of devices with attached, for each type + * @attach_size: Total number of bytes of attached data, for each type + */ +struct dm_stats { + int total_size; + int dev_count; + int dev_size; + int dev_name_size; + int uc_count; + int uc_size; + int tag_count; + int tag_size; + int uc_attach_count; + int uc_attach_size; + int attach_count_total; + int attach_size_total; + int attach_count[DM_TAG_ATTACH_COUNT]; + int attach_size[DM_TAG_ATTACH_COUNT]; +}; + /** * dm_root() - Return pointer to the top of the driver tree * @@ -141,4 +179,11 @@ static inline int dm_remove_devices_flags(uint flags) { re
[PATCH 5/9] dm: core: Switch the testbus driver to use a new struct
At present this driver uses 'priv' struct to hold 'plat' data, which is confusing. The contents of the strct don't matter, since only dtoc is using it. Create a new struct with the correct name. Signed-off-by: Simon Glass --- drivers/misc/test_drv.c | 2 +- include/dm/test.h | 7 +++ tools/dtoc/test_dtoc.py | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/misc/test_drv.c b/drivers/misc/test_drv.c index 5d72982f258..b6df1189032 100644 --- a/drivers/misc/test_drv.c +++ b/drivers/misc/test_drv.c @@ -109,7 +109,7 @@ UCLASS_DRIVER(testbus) = { .child_post_probe = testbus_child_post_probe_uclass, /* This is for dtoc testing only */ - .per_device_plat_auto = sizeof(struct dm_test_uclass_priv), + .per_device_plat_auto = sizeof(struct dm_test_uclass_plat), }; static int testfdt_drv_ping(struct udevice *dev, int pingval, int *pingret) diff --git a/include/dm/test.h b/include/dm/test.h index 4919064cc02..b5937509212 100644 --- a/include/dm/test.h +++ b/include/dm/test.h @@ -92,6 +92,13 @@ struct dm_test_uclass_priv { int total_add; }; +/** + * struct dm_test_uclass_plat - private plat data for test uclass + */ +struct dm_test_uclass_plat { + char dummy[32]; +}; + /** * struct dm_test_parent_data - parent's information on each child * diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index c81bcc9c32f..8bac2076214 100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -616,7 +616,7 @@ struct dm_test_pdata __attribute__ ((section (".priv_data"))) u8 _denx_u_boot_test_bus_priv_some_bus[sizeof(struct dm_test_priv)] \t__attribute__ ((section (".priv_data"))); #include -u8 _denx_u_boot_test_bus_ucplat_some_bus[sizeof(struct dm_test_uclass_priv)] +u8 _denx_u_boot_test_bus_ucplat_some_bus[sizeof(struct dm_test_uclass_plat)] \t__attribute__ ((section (".priv_data"))); #include -- 2.36.0.512.ge40c2bad7a-goog
[PATCH 4/9] dm: core: Add documentation for the dm command
Add a description and examples for the dm subcommands. Signed-off-by: Simon Glass --- doc/usage/cmd/dm.rst | 487 +++ doc/usage/index.rst | 1 + 2 files changed, 488 insertions(+) create mode 100644 doc/usage/cmd/dm.rst diff --git a/doc/usage/cmd/dm.rst b/doc/usage/cmd/dm.rst new file mode 100644 index 000..7bc1962a754 --- /dev/null +++ b/doc/usage/cmd/dm.rst @@ -0,0 +1,487 @@ +.. SPDX-License-Identifier: GPL-2.0+: + +dm command +== + +Synopis +--- + +:: + +dm compat +dm devres +dm drivers +dm static +dm tree +dm uclass + +Description +--- + +The *dm* command allows viewing information about driver model, including the +tree of devices and list of available uclasses. + + +dm compat +~ + +This shows the compatible strings associated with each driver. Often there +is only one, but multiple strings are shown on their own line. These strings +can be looked up in the device tree files for each board, to see which driver is +used for each node. + +dm devres +~ + +This shows a list of a `devres` (device resource) records for a device. Some +drivers use the devres API to allocate memory, so that it can be freed +automatically (without any code needed in the driver's remove() method) when the +device is removed. + +This feature is controlled by CONFIG_DEVRES so no useful output is obtained if +this option is disabled. + +dm drivers +~~ + +This shows all the available drivers, their uclass and a list of devices that +use that driver, each on its own line. Drivers with no devices are shown with +`` as the driver name. + + +dm mem +~~ + +This subcommand is really just for debugging and exploration. It can be enabled +with the `CONFIG_DM_STATS` option. + +All output is in hex except that in brackets which is decimal. + +The output consists of a header shows the size of the main device model +structures (struct udevice, struct driver, struct uclass and struct uc_driver) +and the count and memory used by each (number of devices, memory used by +devices, memory used by device names, number of uclasses, memory used by +uclasses). + +After that is a table of information about each type of data that can be +attached to a device, showing the number that have non-null data for that type, +the total size of all that data, the amount of memory used in total, the +amount that would be used if this type uses tags instead and the amount that +would be thus saved. + +The `driver_data` line shows the number of devices which have non-NULL driver +data. + +The `tags` line shows the number of tags and the memory used by those. + +At the bottom is an indication of the total memory usage obtained by undertaking +various changes, none of which is currently implemented in U-Boot: + +With tags +Using tags instead of all attached types + +Singly linked +Using a singly linked list + +driver index +Using a driver index instead of a pointer + +uclass index +Using a uclass index instead of a pointer + +Drop device name +Using empty device names + + +dm static +~ + +This shows devices bound by platform data, i.e. not from the device tree. There +are normally none of these, but some boards may use static devices for space +reasons. + + +dm tree +~~~ + +This shows the full tree of devices including the following fields: + +uclass +Shows the name of the uclass for the device + +Index +Shows the index number of the device, within the uclass. This shows the +ordering within the uclass, but not the sequence number. + +Probed +Shows `+` if the device is active + +Driver +Shows the name of the driver that this device uses + +Name +Shows the device name as well as the tree structure, since child devices are +shown attached to their parent. + + +dm uclass +~ + +This shows each uclass along with a list of devices in that uclass. The uclass +ID is shown (e.g. uclass 7) and its name. + +For each device, the format is:: + +nname @ a, seq s + +where `n` is the index within the uclass, `a` is the address of the device in +memory and `s` is the sequence number of the device. + + +Examples + + +dm compat +~ + +This example shows an abridged version of the sandbox output:: + +=> dm compat +DriverCompatible + +act8846_reg +sandbox_adder sandbox,adder +axi_sandbox_bus sandbox,axi +blk_partition +bootcount-rtc u-boot,bootcount-rtc +... +rockchip_rk805rockchip,rk805 + rockchip,rk808 + rockchip,rk809 + rockchip,rk816 + rockchip,rk817 + rockchip,rk818 +root_driver +rtc-rv8803microcrystal,rv8803 + epson,rx8803 + epson,rx8900 +... +wdt_gp
[PATCH 6/9] dm: core: Support accessing core tags
At present tag numbers are only allocated for non-core data, meaning that the 'core' data, like priv and plat, are accessed through dedicated functions. For debugging and consistency it is convenient to use tags for this 'core' data too. Add support for this, with new tag numbers and functions to access the pointer and size for each. Update one of the test drivers so that the uclass-private data can be tested here. There is some code duplication with functions like device_alloc_priv() but this is not addressed for now. At some point, some rationalisation may help to reduce code size, but more thought it needed on that. Signed-off-by: Simon Glass --- drivers/core/device.c | 65 + drivers/misc/test_drv.c | 4 ++- include/dm/device.h | 25 + include/dm/tag.h| 13 ++- test/dm/core.c | 80 + tools/dtoc/test_dtoc.py | 4 +++ 6 files changed, 189 insertions(+), 2 deletions(-) diff --git a/drivers/core/device.c b/drivers/core/device.c index 3ab2583df38..d7936a46732 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -680,6 +680,71 @@ void *dev_get_parent_priv(const struct udevice *dev) return dm_priv_to_rw(dev->parent_priv_); } +void *dev_get_attach_ptr(const struct udevice *dev, enum dm_tag_t tag) +{ + switch (tag) { + case DM_TAG_PLAT: + return dev_get_plat(dev); + case DM_TAG_PARENT_PLAT: + return dev_get_parent_plat(dev); + case DM_TAG_UC_PLAT: + return dev_get_uclass_plat(dev); + case DM_TAG_PRIV: + return dev_get_priv(dev); + case DM_TAG_PARENT_PRIV: + return dev_get_parent_priv(dev); + case DM_TAG_UC_PRIV: + return dev_get_uclass_priv(dev); + default: + return NULL; + } +} + +int dev_get_attach_size(const struct udevice *dev, enum dm_tag_t tag) +{ + const struct udevice *parent = dev_get_parent(dev); + const struct uclass *uc = dev->uclass; + const struct uclass_driver *uc_drv = uc->uc_drv; + const struct driver *parent_drv = NULL; + int size = 0; + + if (parent) + parent_drv = parent->driver; + + switch (tag) { + case DM_TAG_PLAT: + size = dev->driver->plat_auto; + break; + case DM_TAG_PARENT_PLAT: + if (parent) { + size = parent_drv->per_child_plat_auto; + if (!size) + size = parent->uclass->uc_drv->per_child_plat_auto; + } + break; + case DM_TAG_UC_PLAT: + size = uc_drv->per_device_plat_auto; + break; + case DM_TAG_PRIV: + size = dev->driver->priv_auto; + break; + case DM_TAG_PARENT_PRIV: + if (parent) { + size = parent_drv->per_child_auto; + if (!size) + size = parent->uclass->uc_drv->per_child_auto; + } + break; + case DM_TAG_UC_PRIV: + size = uc_drv->per_device_auto; + break; + default: + break; + } + + return size; +} + static int device_get_device_tail(struct udevice *dev, int ret, struct udevice **devp) { diff --git a/drivers/misc/test_drv.c b/drivers/misc/test_drv.c index b6df1189032..927618256f0 100644 --- a/drivers/misc/test_drv.c +++ b/drivers/misc/test_drv.c @@ -108,7 +108,9 @@ UCLASS_DRIVER(testbus) = { .child_pre_probe = testbus_child_pre_probe_uclass, .child_post_probe = testbus_child_post_probe_uclass, - /* This is for dtoc testing only */ + .per_device_auto = sizeof(struct dm_test_uclass_priv), + + /* Note: this is for dtoc testing as well as tags*/ .per_device_plat_auto = sizeof(struct dm_test_uclass_plat), }; diff --git a/include/dm/device.h b/include/dm/device.h index 5bdb10653f8..12c6ba37ff3 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -11,6 +11,7 @@ #define _DM_DEVICE_H #include +#include #include #include #include @@ -546,6 +547,30 @@ void *dev_get_parent_priv(const struct udevice *dev); */ void *dev_get_uclass_priv(const struct udevice *dev); +/** + * dev_get_attach_ptr() - Get the value of an attached pointed tag + * + * The tag is assumed to hold a pointer, if it exists + * + * @dev: Device to look at + * @tag: Tag to access + * @return value of tag, or NULL if there is no tag of this type + */ +void *dev_get_attach_ptr(const struct udevice *dev, enum dm_tag_t tag); + +/** + * dev_get_attach_size() - Get the size of an attached tag + * + * Core tags have an automatic-allocation mechanism where the allocated size is + * defined by the device, parent or uclass. This returns the size associated + * with a partic
[PATCH 3/9] dm: core: Fix addresses in the dm static command
This command converts pointers to addresses, but the pointers being converted are in the image's rodata region. For sandbox this means it is not in DRAM so it does not make sense to do this conversion. Fix this by showing a simple pointer instead. Drop the unnecessary @ and hex prefixes. Signed-off-by: Simon Glass --- drivers/core/dump.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/core/dump.c b/drivers/core/dump.c index 606883ac941..ce679e26290 100644 --- a/drivers/core/dump.c +++ b/drivers/core/dump.c @@ -171,8 +171,6 @@ void dm_dump_static_driver_info(void) puts("DriverAddress\n"); puts("-\n"); - for (entry = drv; entry != drv + n_ents; entry++) { - printf("%-25.25s @%08lx\n", entry->name, - (ulong)map_to_sysmem(entry->plat)); - } + for (entry = drv; entry != drv + n_ents; entry++) + printf("%-25.25s %p\n", entry->name, entry->plat); } -- 2.36.0.512.ge40c2bad7a-goog
[PATCH 2/9] dm: core: Sort dm subcommands
Put these in alphabetic order, both in the help and in the implementation, as there are quite a few subcommands now. Tweak the help for 'dm tree' to better explain what it does. Signed-off-by: Simon Glass --- cmd/dm.c | 48 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/cmd/dm.c b/cmd/dm.c index cb4c358e942..4c0a8a53ced 100644 --- a/cmd/dm.c +++ b/cmd/dm.c @@ -16,18 +16,10 @@ #include #include -static int do_dm_dump_tree(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - dm_dump_tree(); - - return 0; -} - -static int do_dm_dump_uclass(struct cmd_tbl *cmdtp, int flag, int argc, -char *const argv[]) +static int do_dm_dump_driver_compat(struct cmd_tbl *cmdtp, int flag, int argc, + char * const argv[]) { - dm_dump_uclass(); + dm_dump_driver_compat(); return 0; } @@ -48,29 +40,37 @@ static int do_dm_dump_drivers(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } -static int do_dm_dump_driver_compat(struct cmd_tbl *cmdtp, int flag, int argc, - char * const argv[]) +static int do_dm_dump_static_driver_info(struct cmd_tbl *cmdtp, int flag, +int argc, char * const argv[]) { - dm_dump_driver_compat(); + dm_dump_static_driver_info(); return 0; } -static int do_dm_dump_static_driver_info(struct cmd_tbl *cmdtp, int flag, int argc, -char * const argv[]) +static int do_dm_dump_tree(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { - dm_dump_static_driver_info(); + dm_dump_tree(); + + return 0; +} + +static int do_dm_dump_uclass(struct cmd_tbl *cmdtp, int flag, int argc, +char *const argv[]) +{ + dm_dump_uclass(); return 0; } static struct cmd_tbl test_commands[] = { - U_BOOT_CMD_MKENT(tree, 0, 1, do_dm_dump_tree, "", ""), - U_BOOT_CMD_MKENT(uclass, 1, 1, do_dm_dump_uclass, "", ""), + U_BOOT_CMD_MKENT(compat, 1, 1, do_dm_dump_driver_compat, "", ""), U_BOOT_CMD_MKENT(devres, 1, 1, do_dm_dump_devres, "", ""), U_BOOT_CMD_MKENT(drivers, 1, 1, do_dm_dump_drivers, "", ""), - U_BOOT_CMD_MKENT(compat, 1, 1, do_dm_dump_driver_compat, "", ""), U_BOOT_CMD_MKENT(static, 1, 1, do_dm_dump_static_driver_info, "", ""), + U_BOOT_CMD_MKENT(tree, 0, 1, do_dm_dump_tree, "", ""), + U_BOOT_CMD_MKENT(uclass, 1, 1, do_dm_dump_uclass, "", ""), }; static __maybe_unused void dm_reloc(void) @@ -109,10 +109,10 @@ static int do_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) U_BOOT_CMD( dm, 3, 1, do_dm, "Driver model low level access", - "tree Dump driver model tree ('*' = activated)\n" - "dm uclassDump list of instances for each uclass\n" + "compatDump list of drivers with compatibility strings\n" "dm devresDump list of device resources for each device\n" "dm drivers Dump list of drivers with uclass and instances\n" - "dm compatDump list of drivers with compatibility strings\n" - "dm staticDump list of drivers with static platform data" + "dm staticDump list of drivers with static platform data\n" + "dm tree Dump tree of driver model devices ('*' = activated)\n" + "dm uclassDump list of instances for each uclass" ); -- 2.36.0.512.ge40c2bad7a-goog
[PATCH 1/9] dm: core: Rename dm_dump_all()
This is not a good name anymore as it does not dump everything. Rename it to dm_dump_tree() to avoid confusion. Signed-off-by: Simon Glass --- cmd/dm.c| 8 drivers/core/dump.c | 2 +- include/dm/util.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/dm.c b/cmd/dm.c index 1dd19fe45b5..cb4c358e942 100644 --- a/cmd/dm.c +++ b/cmd/dm.c @@ -16,10 +16,10 @@ #include #include -static int do_dm_dump_all(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) +static int do_dm_dump_tree(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { - dm_dump_all(); + dm_dump_tree(); return 0; } @@ -65,7 +65,7 @@ static int do_dm_dump_static_driver_info(struct cmd_tbl *cmdtp, int flag, int ar } static struct cmd_tbl test_commands[] = { - U_BOOT_CMD_MKENT(tree, 0, 1, do_dm_dump_all, "", ""), + U_BOOT_CMD_MKENT(tree, 0, 1, do_dm_dump_tree, "", ""), U_BOOT_CMD_MKENT(uclass, 1, 1, do_dm_dump_uclass, "", ""), U_BOOT_CMD_MKENT(devres, 1, 1, do_dm_dump_devres, "", ""), U_BOOT_CMD_MKENT(drivers, 1, 1, do_dm_dump_drivers, "", ""), diff --git a/drivers/core/dump.c b/drivers/core/dump.c index f2f9cacc56c..606883ac941 100644 --- a/drivers/core/dump.c +++ b/drivers/core/dump.c @@ -45,7 +45,7 @@ static void show_devices(struct udevice *dev, int depth, int last_flag) } } -void dm_dump_all(void) +void dm_dump_tree(void) { struct udevice *root; diff --git a/include/dm/util.h b/include/dm/util.h index 4428f045b72..c52daa87ef3 100644 --- a/include/dm/util.h +++ b/include/dm/util.h @@ -25,7 +25,7 @@ struct list_head; int list_count_items(struct list_head *head); /* Dump out a tree of all devices */ -void dm_dump_all(void); +void dm_dump_tree(void); /* Dump out a list of uclasses and their devices */ void dm_dump_uclass(void); -- 2.36.0.512.ge40c2bad7a-goog
[PATCH 0/9] dm: core: Support collecting and reporting stats
Driver model can use a lot of memory, as it is the core of all drivers and devices in U-Boot. Add a command to show how much is in use, along with the sizes of various data structures. This patch can be used to analyse the impact of various potential changes to driver model for SPL, none of which has been implemented. Most involve shrinking the size of struct udevice, which is a particular problem on 64-bit machines since their pointers are so unnecessarily large in SPL. To try this out, enable SPL_DM_STATS and then build and run on your board. You should see output for SPL and U-Boot proper, like this: Struct sizes: udevice 90, driver 78, uclass 30, uc_driver 78 Memory: device 11:990, device names 111, uclass a:1e0 Attached typeCount SizeCur Tags Save --- - - - - - plat 3 e0990914 7c (124) parent_plat 2 40990910 80 (128) uclass_plat 1 1099090c 84 (132) priv 613d990920 70 (112) parent_priv 0 0990908 88 (136) uclass_priv 3 38990914 7c (124) driver_data 0 0990908 88 (136) uclass 0 0 Attached total f2a5 37c (892) tags 0 0 Total size: e15 (3605) With tags: a99 (2713) - singly-linked: 901 (2305) - driver index: 88a (2186) - uclass index: 813 (2067) Drop device name (not SRAM): 111 (273) Simon Glass (9): dm: core: Rename dm_dump_all() dm: core: Sort dm subcommands dm: core: Fix addresses in the dm static command dm: core: Add documentation for the dm command dm: core: Switch the testbus driver to use a new struct dm: core: Support accessing core tags dm: core: Add a way to collect memory usage dm: core: Add a command to show driver model statistics dm: spl: Allow SPL to show memory usage cmd/dm.c| 69 -- common/spl/spl.c| 9 + doc/usage/cmd/dm.rst| 487 doc/usage/index.rst | 1 + drivers/core/Kconfig| 21 ++ drivers/core/device.c | 65 ++ drivers/core/dump.c | 79 ++- drivers/core/root.c | 53 + drivers/core/tag.c | 29 +++ drivers/misc/test_drv.c | 6 +- include/dm/device.h | 25 +++ include/dm/root.h | 45 include/dm/tag.h| 32 ++- include/dm/test.h | 7 + include/dm/util.h | 11 +- test/dm/core.c | 91 tools/dtoc/test_dtoc.py | 6 +- 17 files changed, 1004 insertions(+), 32 deletions(-) create mode 100644 doc/usage/cmd/dm.rst -- 2.36.0.512.ge40c2bad7a-goog
[PATCH] cmd: dm: migrate dm command to use U_BOOT_CMD_WITH_SUBCMDS()
Migrate dm command to use U_BOOT_CMD_WITH_SUBCMDS() helper macro, to reduce duplicated code. We can also drop the CONFIG_NEEDS_MANUAL_RELOC exception, as the command list is updated post relocation in board_r.c initcall initr_manual_reloc_cmdtable(). Signed-off-by: Ovidiu Panait --- cmd/dm.c | 64 +++- 1 file changed, 12 insertions(+), 52 deletions(-) diff --git a/cmd/dm.c b/cmd/dm.c index 1dd19fe45b..ca609224f5 100644 --- a/cmd/dm.c +++ b/cmd/dm.c @@ -8,12 +8,6 @@ #include #include -#include -#include -#include -#include -#include -#include #include static int do_dm_dump_all(struct cmd_tbl *cmdtp, int flag, int argc, @@ -64,55 +58,21 @@ static int do_dm_dump_static_driver_info(struct cmd_tbl *cmdtp, int flag, int ar return 0; } -static struct cmd_tbl test_commands[] = { - U_BOOT_CMD_MKENT(tree, 0, 1, do_dm_dump_all, "", ""), - U_BOOT_CMD_MKENT(uclass, 1, 1, do_dm_dump_uclass, "", ""), - U_BOOT_CMD_MKENT(devres, 1, 1, do_dm_dump_devres, "", ""), - U_BOOT_CMD_MKENT(drivers, 1, 1, do_dm_dump_drivers, "", ""), - U_BOOT_CMD_MKENT(compat, 1, 1, do_dm_dump_driver_compat, "", ""), - U_BOOT_CMD_MKENT(static, 1, 1, do_dm_dump_static_driver_info, "", ""), -}; - -static __maybe_unused void dm_reloc(void) -{ - static int relocated; - - if (!relocated) { - fixup_cmdtable(test_commands, ARRAY_SIZE(test_commands)); - relocated = 1; - } -} - -static int do_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct cmd_tbl *test_cmd; - int ret; - -#ifdef CONFIG_NEEDS_MANUAL_RELOC - dm_reloc(); -#endif - - if (argc < 2) - return CMD_RET_USAGE; - test_cmd = find_cmd_tbl(argv[1], test_commands, - ARRAY_SIZE(test_commands)); - argc -= 2; - argv += 2; - if (!test_cmd || argc > test_cmd->maxargs) - return CMD_RET_USAGE; - - ret = test_cmd->cmd(test_cmd, flag, argc, argv); - - return cmd_process_error(test_cmd, ret); -} - -U_BOOT_CMD( - dm, 3, 1, do_dm, - "Driver model low level access", +#if CONFIG_IS_ENABLED(SYS_LONGHELP) +static char dm_help_text[] = "tree Dump driver model tree ('*' = activated)\n" "dm uclassDump list of instances for each uclass\n" "dm devresDump list of device resources for each device\n" "dm drivers Dump list of drivers with uclass and instances\n" "dm compatDump list of drivers with compatibility strings\n" "dm staticDump list of drivers with static platform data" -); + ; +#endif + +U_BOOT_CMD_WITH_SUBCMDS(dm, "Driver model low level access", dm_help_text, + U_BOOT_SUBCMD_MKENT(tree, 1, 1, do_dm_dump_all), + U_BOOT_SUBCMD_MKENT(uclass, 1, 1, do_dm_dump_uclass), + U_BOOT_SUBCMD_MKENT(devres, 1, 1, do_dm_dump_devres), + U_BOOT_SUBCMD_MKENT(drivers, 1, 1, do_dm_dump_drivers), + U_BOOT_SUBCMD_MKENT(compat, 1, 1, do_dm_dump_driver_compat), + U_BOOT_SUBCMD_MKENT(static, 1, 1, do_dm_dump_static_driver_info)); -- 2.25.1
Re: [PATCH 1/5] phy: adin: remove broken support for adi,phy-mode-override
Hi Nate, Maintainers, This patch is now superseded by Nate's [PATCH] phy: adin: fix broken support for adi,phy-mode-override submitted yesterday. The remainder of this patchset cleanly applies on top of it though, so I won't roll v2. Let me know if there is any further feedback on this series, or if it can be applied. Am 05.05.22 um 18:30 schrieb Josua Mayer: \o/ Am 04.05.22 um 15:46 schrieb Nate Drude: Hi Josua, On Wed, 2022-05-04 at 11:51 +0300, Josua Mayer wrote: Hi Nate, Am 02.05.22 um 16:25 schrieb Nate Drude: Hi Josua, On Sun, 2022-05-01 at 15:41 +0300, Josua Mayer wrote: The adin_get_phy_mode_override function does not compile, because it is missing both declaration and implementation of phy_get_interface_by_name. Remove the whole function for now, since the missing implementation is not included in mainline Linux - and thus can not be copied. Signed-off-by: Josua Mayer --- drivers/net/phy/adin.c | 34 -- 1 file changed, 34 deletions(-) diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c index cff841ab3d..2433e76fea 100644 --- a/drivers/net/phy/adin.c +++ b/drivers/net/phy/adin.c @@ -94,35 +94,6 @@ static u32 adin_get_reg_value(struct phy_device *phydev, return rc; } -/** - * adin_get_phy_mode_override - Get phy-mode override for adin PHY - * - * The function gets phy-mode string from property 'adi,phy- mode- override' - * and return its index in phy_interface_strings table, or -1 in error case. - */ -int adin_get_phy_mode_override(struct phy_device *phydev) -{ - ofnode node = phy_get_ofnode(phydev); - const char *phy_mode_override; - const char *prop_phy_mode_override = "adi,phy-mode- override"; - int override_interface; - - phy_mode_override = ofnode_read_string(node, prop_phy_mode_override); - if (!phy_mode_override) - return -ENODEV; - - debug("%s: %s = '%s'\n", - __func__, prop_phy_mode_override, phy_mode_override); - - override_interface = phy_get_interface_by_name(phy_mode_override); - - if (override_interface < 0) - printf("%s: %s = '%s' is not valid\n", - __func__, prop_phy_mode_override, phy_mode_override); - - return override_interface; -} - static u16 adin_ext_read(struct phy_device *phydev, const u32 regnum) { u16 val; @@ -148,11 +119,6 @@ static int adin_config_rgmii_mode(struct phy_device *phydev) { u16 reg_val; u32 val; - int phy_mode_override = adin_get_phy_mode_override(phydev); - - if (phy_mode_override >= 0) { - phydev->interface = (phy_interface_t) phy_mode_override; - } reg_val = adin_ext_read(phydev, ADIN1300_GE_RGMII_CFG); The patch that introduced adin_get_phy_mode_override was tested against the U-Boot master branch. Unfortunately, phy_get_interface_by_name was removed just a few days before by: https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fu-boot%2Fu-boot%2Fcommit%2F123ca114e07ecf28aa2538748d733e2b22d8b8b5&data=05%7C01%7CNate.D%40variscite.com%7C467af650626f4902ae2b08da2dab6225%7C399ae6ac38f44ef094a8440b0ad581de%7C1%7C0%7C637872511359995609%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=Ok3YOO8rheEZuRa%2Fn04NZf37TsPQ7hzArUojFZ4QDUg%3D&reserved=0 :( Can we fix adin_get_phy_mode_override instead of removing it? I will take a look in the coming days and see if I understand how to fix this. I don't really mind if we fix it, or remove it - removing was the faster If you prefer, I can submit a separate patch to fix it. I'll wait to hear from you to avoid duplicated work. I won't be able to look at this before Sunday, so feel free to work on it. way getting my patch-set out of course ... We can implement part of ofnode_read_phy_mode. This needs to be tested, but for example: diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c index cff841ab3d..6a05b9fd05 100644 --- a/drivers/net/phy/adin.c +++ b/drivers/net/phy/adin.c @@ -100,27 +100,28 @@ static u32 adin_get_reg_value(struct phy_device *phydev, * The function gets phy-mode string from property 'adi,phy-mode- override' * and return its index in phy_interface_strings table, or -1 in error case. */ -int adin_get_phy_mode_override(struct phy_device *phydev) +phy_interface_t adin_get_phy_mode_override(struct phy_device *phydev) { ofnode node = phy_get_ofnode(phydev); const char *phy_mode_override; const char *prop_phy_mode_override = "adi,phy-mode- override"; - int override_interface; + int i; phy_mode_override = ofnode_read_string(node, prop_phy_mode_override); + if (!phy_mode_override) - return -ENODEV; + return PHY_INTERFACE_MODE_NA; debug("%s: %s = '%s'\n", __func__, prop_phy_mode_override, phy_mo
Re: [PATCH] phy: adin: fix broken support for adi,phy-mode-override
Hi Nate, That was quick! I have rebased my changes on top of this patch, and can confirm that the adin phy driver compiles, and still works. I did not test setting adi,[rt]x-internal-delay-ps in dts though. So, I guess you can add my superficial Tested-By: Josua Mayer [PATCH 0/5] mx6cuboxi: add eth support for SoMs revision 1.9+ patches 2-5 apply cleanly, so I won't immediately roll a v2. Am 07.05.22 um 00:52 schrieb Nate Drude: Currently, the adin driver fails to compile. The original patch introducing the adin driver used the function phy_get_interface_by_name to support the adi,phy-mode-override property. Unfortunately, a few days before the adin patch was accepted, another patch removed support for phy_get_interface_by_name: https://github.com/u-boot/u-boot/commit/123ca114e07ecf28aa2538748d733e2b22d8b8b5 This patch refactors adin_get_phy_mode_override, implementing the logic in the new function, ofnode_read_phy_mode, from the patch above. Signed-off-by: Nate Drude --- drivers/net/phy/adin.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c index cff841ab3d..e60f288b9b 100644 --- a/drivers/net/phy/adin.c +++ b/drivers/net/phy/adin.c @@ -100,27 +100,27 @@ static u32 adin_get_reg_value(struct phy_device *phydev, * The function gets phy-mode string from property 'adi,phy-mode-override' * and return its index in phy_interface_strings table, or -1 in error case. */ -int adin_get_phy_mode_override(struct phy_device *phydev) +phy_interface_t adin_get_phy_mode_override(struct phy_device *phydev) { ofnode node = phy_get_ofnode(phydev); const char *phy_mode_override; const char *prop_phy_mode_override = "adi,phy-mode-override"; - int override_interface; + int i; phy_mode_override = ofnode_read_string(node, prop_phy_mode_override); if (!phy_mode_override) - return -ENODEV; + return PHY_INTERFACE_MODE_NA; debug("%s: %s = '%s'\n", __func__, prop_phy_mode_override, phy_mode_override); - override_interface = phy_get_interface_by_name(phy_mode_override); + for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) + if (!strcmp(phy_mode_override, phy_interface_strings[i])) + return (phy_interface_t) i; - if (override_interface < 0) - printf("%s: %s = '%s' is not valid\n", - __func__, prop_phy_mode_override, phy_mode_override); + printf("%s: Invalid PHY interface '%s'\n", __func__, phy_mode_override); - return override_interface; + return PHY_INTERFACE_MODE_NA; } static u16 adin_ext_read(struct phy_device *phydev, const u32 regnum) @@ -148,10 +148,10 @@ static int adin_config_rgmii_mode(struct phy_device *phydev) { u16 reg_val; u32 val; - int phy_mode_override = adin_get_phy_mode_override(phydev); + phy_interface_t phy_mode_override = adin_get_phy_mode_override(phydev); - if (phy_mode_override >= 0) { - phydev->interface = (phy_interface_t) phy_mode_override; + if (phy_mode_override != PHY_INTERFACE_MODE_NA) { + phydev->interface = phy_mode_override; } reg_val = adin_ext_read(phydev, ADIN1300_GE_RGMII_CFG); - Josua Mayer
Pull request for efi-2022-07-rc3-2
Dear Tom, The following changes since commit 145921bdbdcfc24f18ce21d570ff86cc7e1fa3ba: Merge https://source.denx.de/u-boot/custodians/u-boot-usb (2022-05-06 08:57:15 -0400) are available in the Git repository at: https://source.denx.de/u-boot/custodians/u-boot-efi.git tags/efi-2022-07-rc3-2 for you to fetch changes up to 4b494770577cc61c3c1a4b57ced2fc98d87957dc: test/py: Add more test cases for rejecting an EFI image (2022-05-07 23:17:26 +0200) Gitlab CI showed no issues: https://source.denx.de/u-boot/custodians/u-boot-efi/-/pipelines/11957 Pull request for efi-2022-07-rc3-2 UEFI: * Fix build errors due to - using sed with non-standard extension for regular expression - target architecture not recognized for CROSS_COMPILE=armv7a-* - CONFIG_EVENT not selected * add sha384/512 on certificate revocation Others: * factor out the user input handling in bootmenu command Heinrich Schuchardt (2): Makefile: support CROSS_COMPILE=armv7a-* tools: mkimage: set OPENSSL_API_COMPAT Ilias Apalodimas (2): efi_loader: add sha384/512 on certificate revocation test/py: Add more test cases for rejecting an EFI image Jan Kiszka (1): efi_loader: Select EVENT as well Mark Kettenis (1): Makefile: Avoid non-portable GNU sed extension Masahisa Kojima (1): bootmenu: factor out the user input handling Sean Anderson (1): mkimage: Document misc options Makefile | 4 +- cmd/bootmenu.c| 141 -- common/menu.c | 128 +++ doc/mkimage.1 | 36 ++- include/efi_api.h | 6 ++ include/efi_loader.h | 6 ++ include/menu.h| 20 lib/efi_loader/Kconfig| 1 + lib/efi_loader/efi_helper.c | 66 lib/efi_loader/efi_signature.c| 76 +- test/py/tests/test_efi_secboot/conftest.py| 6 ++ test/py/tests/test_efi_secboot/test_signed.py | 51 ++ tools/mkimage.c | 15 ++- tools/sunxi_toc0.c| 3 + 14 files changed, 388 insertions(+), 171 deletions(-)