Merge branch '2023-01-12-further-assorted-general-updates'

- Bring in a number of assorted updates, some of which have been waiting
  around for a bit.  Make silent console really be silent, get rid of
  gpio_hog_probe_all, add RNG for imx6, make net/fm use fs_loader, get
  rid of a bad __weak usage and set distro_bootpart_uuid in another case.
This commit is contained in:
Tom Rini 2023-01-12 17:05:41 -05:00
commit 87c9e117bf
26 changed files with 340 additions and 83 deletions

View File

@ -746,6 +746,16 @@ int arch_misc_init(void)
if (ret)
printf("Failed to initialize caam_jr: %d\n", ret);
}
if (IS_ENABLED(CONFIG_FSL_DCP_RNG)) {
struct udevice *dev;
int ret;
ret = uclass_get_device_by_driver(UCLASS_RNG, DM_DRIVER_GET(dcp_rng), &dev);
if (ret)
printf("Failed to initialize dcp rng: %d\n", ret);
}
setup_serial_number();
return 0;
}

View File

@ -181,7 +181,7 @@ int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr)
if (!*loadaddr)
return 0;
if (!uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &fsdev)) {
if (!get_fs_loader(&fsdev)) {
size = request_firmware_into_buf(fsdev, name, (void *)*loadaddr,
0, 0);
}

View File

@ -214,7 +214,7 @@ int load_firmware(char *name_fw, u32 *loadaddr)
if (!*loadaddr)
return 0;
if (!uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &fsdev)) {
if (!get_fs_loader(&fsdev)) {
size = request_firmware_into_buf(fsdev, name_fw,
(void *)*loadaddr, 0, 0);
}

View File

@ -112,6 +112,9 @@ int do_spi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
if ((flag & CMD_FLAG_REPEAT) == 0)
{
if (argc < 2)
return CMD_RET_USAGE;
if (argc >= 2) {
mode = CONFIG_DEFAULT_SPI_MODE;
bus = dectoul(argv[1], &cp);

View File

@ -164,6 +164,16 @@ config SILENT_CONSOLE_UPDATE_ON_RELOC
(e.g. NAND). This option makes the value of the 'silent'
environment variable take effect at relocation.
config SILENT_CONSOLE_UNTIL_ENV
bool "Keep console silent until environment is loaded"
depends on SILENT_CONSOLE
help
This option makes sure U-Boot will never use the console unless the
environment from flash does not contain the 'silent' variable. If
set, the console is kept silent until after the environment was
loaded. Use this in combination with PRE_CONSOLE_BUFFER to print out
earlier messages after loading the environment when allowed.
config PRE_CONSOLE_BUFFER
bool "Buffer characters before the console is available"
help

View File

@ -756,9 +756,6 @@ static init_fnc_t init_sequence_r[] = {
initr_status_led,
#endif
/* PPC has a udelay(20) here dating from 2002. Why? */
#if defined(CONFIG_GPIO_HOG)
gpio_hog_probe_all,
#endif
#ifdef CONFIG_BOARD_LATE_INIT
board_late_init,
#endif

View File

@ -970,6 +970,11 @@ static bool console_update_silent(void)
if (!IS_ENABLED(CONFIG_SILENT_CONSOLE))
return false;
if (IS_ENABLED(CONFIG_SILENT_CONSOLE_UNTIL_ENV) && !(gd->flags & GD_FLG_ENV_READY)) {
gd->flags |= GD_FLG_SILENT;
return false;
}
if (env_get("silent")) {
gd->flags |= GD_FLG_SILENT;
return false;

View File

@ -786,9 +786,6 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
}
}
if (CONFIG_IS_ENABLED(GPIO_HOG))
gpio_hog_probe_all();
#if CONFIG_IS_ENABLED(BOARD_INIT)
spl_board_init();
#endif

View File

@ -38,12 +38,13 @@ static int spl_ram_load_image(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev)
{
struct legacy_img_hdr *header;
int ret;
header = (struct legacy_img_hdr *)CONFIG_SPL_LOAD_FIT_ADDRESS;
if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD)) {
unsigned long addr = (unsigned long)header;
int ret = image_pre_load(addr);
ret = image_pre_load(addr);
if (ret)
return ret;
@ -64,7 +65,7 @@ static int spl_ram_load_image(struct spl_image_info *spl_image,
debug("Found FIT\n");
load.bl_len = 1;
load.read = spl_ram_load_read;
spl_load_simple_fit(spl_image, &load, 0, header);
ret = spl_load_simple_fit(spl_image, &load, 0, header);
} else {
ulong u_boot_pos = spl_get_image_pos();
@ -85,10 +86,10 @@ static int spl_ram_load_image(struct spl_image_info *spl_image,
}
header = (struct legacy_img_hdr *)map_sysmem(u_boot_pos, 0);
spl_parse_image_header(spl_image, bootdev, header);
ret = spl_parse_image_header(spl_image, bootdev, header);
}
return 0;
return ret;
}
#if CONFIG_IS_ENABLED(RAM_DEVICE)
SPL_LOAD_IMAGE_METHOD("RAM", 0, BOOT_DEVICE_RAM, spl_ram_load_image);

View File

@ -65,3 +65,7 @@ CONFIG_DM_SPI=y
CONFIG_FSL_QSPI=y
CONFIG_SOFT_SPI=y
CONFIG_IMX_THERMAL=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_DM_RNG=y
CONFIG_CMD_RNG=y
CONFIG_FSL_DCP_RNG=y

View File

@ -64,3 +64,7 @@ CONFIG_DM_SPI=y
CONFIG_FSL_QSPI=y
CONFIG_SOFT_SPI=y
CONFIG_IMX_THERMAL=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_DM_RNG=y
CONFIG_CMD_RNG=y
CONFIG_FSL_DCP_RNG=y

View File

@ -2,10 +2,8 @@
GPIO hog (CONFIG_GPIO_HOG)
--------
All the GPIO hog are initialized in gpio_hog_probe_all() function called in
board_r.c just before board_late_init() but you can also acces directly to
the gpio with gpio_hog_lookup_name().
All the GPIO hog are initialized using DM_FLAG_PROBE_AFTER_BIND DM flag
after bind().
Example, for the device tree:

View File

@ -363,20 +363,22 @@ void *dm_priv_to_rw(void *priv)
static int dm_probe_devices(struct udevice *dev, bool pre_reloc_only)
{
u32 mask = DM_FLAG_PROBE_AFTER_BIND;
u32 flags = dev_get_flags(dev);
ofnode node = dev_ofnode(dev);
struct udevice *child;
int ret;
if (pre_reloc_only)
mask |= DM_FLAG_PRE_RELOC;
if (pre_reloc_only &&
(!ofnode_valid(node) || !ofnode_pre_reloc(node)) &&
!(dev->driver->flags & DM_FLAG_PRE_RELOC))
goto probe_children;
if ((flags & mask) == mask) {
if (dev_get_flags(dev) & DM_FLAG_PROBE_AFTER_BIND) {
ret = device_probe(dev);
if (ret)
return ret;
}
probe_children:
list_for_each_entry(child, &dev->child_head, sibling_node)
dm_probe_devices(child, pre_reloc_only);

View File

@ -73,3 +73,13 @@ config FSL_CAAM_RNG
reseeded from the TRNG every time random data is generated.
endif
config FSL_DCP_RNG
bool "Enable Random Number Generator support"
depends on DM_RNG
default n
help
Enable support for the hardware based random number generator
module of the DCP. It uses the True Random Number Generator (TRNG)
and a Pseudo-Random Number Generator (PRNG) to achieve a true
randomness and cryptographic strength.

View File

@ -7,4 +7,5 @@ obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
obj-$(CONFIG_CMD_BLOB)$(CONFIG_IMX_CAAM_DEK_ENCAP) += fsl_blob.o
obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
obj-$(CONFIG_FSL_CAAM_RNG) += rng.o
obj-$(CONFIG_FSL_DCP_RNG) += dcp_rng.o
obj-$(CONFIG_FSL_MFGPROT) += fsl_mfgprot.o

View File

@ -0,0 +1,182 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* RNG driver for Freescale RNGC
*
* Copyright 2022 NXP
*
* Based on RNGC driver in drivers/char/hw_random/imx-rngc.c in Linux
*/
#include <common.h>
#include <cpu_func.h>
#include <dm.h>
#include <rng.h>
#include <asm/cache.h>
#include <asm/io.h>
#include <dm/root.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#define DCP_RNG_MAX_FIFO_STORE_SIZE 4
#define RNGC_VER_ID 0x0
#define RNGC_COMMAND 0x4
#define RNGC_CONTROL 0x8
#define RNGC_STATUS 0xC
#define RNGC_ERROR 0x10
#define RNGC_FIFO 0x14
/* the fields in the ver id register */
#define RNGC_TYPE_SHIFT 28
/* the rng_type field */
#define RNGC_TYPE_RNGB 0x1
#define RNGC_TYPE_RNGC 0x2
#define RNGC_CMD_CLR_ERR 0x20
#define RNGC_CMD_SEED 0x2
#define RNGC_CTRL_AUTO_SEED 0x10
#define RNGC_STATUS_ERROR 0x10000
#define RNGC_STATUS_FIFO_LEVEL_MASK 0xf00
#define RNGC_STATUS_FIFO_LEVEL_SHIFT 8
#define RNGC_STATUS_SEED_DONE 0x20
#define RNGC_STATUS_ST_DONE 0x10
#define RNGC_ERROR_STATUS_STAT_ERR 0x8
#define RNGC_TIMEOUT 3000000U /* 3 sec */
struct imx_rngc_priv {
unsigned long base;
};
static int rngc_read(struct udevice *dev, void *data, size_t len)
{
struct imx_rngc_priv *priv = dev_get_priv(dev);
u8 buffer[DCP_RNG_MAX_FIFO_STORE_SIZE];
u32 status, level;
size_t size;
while (len) {
status = readl(priv->base + RNGC_STATUS);
/* is there some error while reading this random number? */
if (status & RNGC_STATUS_ERROR)
break;
/* how many random numbers are in FIFO? [0-16] */
level = (status & RNGC_STATUS_FIFO_LEVEL_MASK) >>
RNGC_STATUS_FIFO_LEVEL_SHIFT;
if (level) {
/* retrieve a random number from FIFO */
*(u32 *)buffer = readl(priv->base + RNGC_FIFO);
size = min(len, sizeof(u32));
memcpy(data, buffer, size);
data += size;
len -= size;
}
}
return len ? -EIO : 0;
}
static int rngc_init(struct imx_rngc_priv *priv)
{
u32 cmd, ctrl, status, err_reg = 0;
unsigned long long timeval = 0;
unsigned long long timeout = RNGC_TIMEOUT;
/* clear error */
cmd = readl(priv->base + RNGC_COMMAND);
writel(cmd | RNGC_CMD_CLR_ERR, priv->base + RNGC_COMMAND);
/* create seed, repeat while there is some statistical error */
do {
/* seed creation */
cmd = readl(priv->base + RNGC_COMMAND);
writel(cmd | RNGC_CMD_SEED, priv->base + RNGC_COMMAND);
udelay(1);
timeval += 1;
status = readl(priv->base + RNGC_STATUS);
err_reg = readl(priv->base + RNGC_ERROR);
if (status & (RNGC_STATUS_SEED_DONE | RNGC_STATUS_ST_DONE))
break;
if (timeval > timeout) {
debug("rngc timed out\n");
return -ETIMEDOUT;
}
} while (err_reg == RNGC_ERROR_STATUS_STAT_ERR);
if (err_reg)
return -EIO;
/*
* enable automatic seeding, the rngc creates a new seed automatically
* after serving 2^20 random 160-bit words
*/
ctrl = readl(priv->base + RNGC_CONTROL);
ctrl |= RNGC_CTRL_AUTO_SEED;
writel(ctrl, priv->base + RNGC_CONTROL);
return 0;
}
static int rngc_probe(struct udevice *dev)
{
struct imx_rngc_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
u32 ver_id;
u8 rng_type;
int ret;
addr = dev_read_addr(dev);
if (addr == FDT_ADDR_T_NONE) {
ret = -EINVAL;
goto err;
}
priv->base = addr;
ver_id = readl(priv->base + RNGC_VER_ID);
rng_type = ver_id >> RNGC_TYPE_SHIFT;
/*
* This driver supports only RNGC and RNGB. (There's a different
* driver for RNGA.)
*/
if (rng_type != RNGC_TYPE_RNGC && rng_type != RNGC_TYPE_RNGB) {
ret = -ENODEV;
goto err;
}
ret = rngc_init(priv);
if (ret)
goto err;
return 0;
err:
printf("%s error = %d\n", __func__, ret);
return ret;
}
static const struct dm_rng_ops rngc_ops = {
.read = rngc_read,
};
static const struct udevice_id rngc_dt_ids[] = {
{ .compatible = "fsl,imx25-rngb" },
{ }
};
U_BOOT_DRIVER(dcp_rng) = {
.name = "dcp_rng",
.id = UCLASS_RNG,
.of_match = rngc_dt_ids,
.ops = &rngc_ops,
.probe = rngc_probe,
.priv_auto = sizeof(struct imx_rngc_priv),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};

View File

@ -777,42 +777,20 @@ int socfpga_loadfs(fpga_fs_info *fpga_fsinfo, const void *buf, size_t bsize,
{
struct fpga_loadfs_info fpga_loadfs;
struct udevice *dev;
int status, ret, size;
int status, ret;
u32 buffer = (uintptr_t)buf;
size_t buffer_sizebytes = bsize;
size_t buffer_sizebytes_ori = bsize;
size_t total_sizeof_image = 0;
ofnode node;
const fdt32_t *phandle_p;
u32 phandle;
node = get_fpga_mgr_ofnode(ofnode_null());
if (ofnode_valid(node)) {
phandle_p = ofnode_get_property(node, "firmware-loader", &size);
if (!phandle_p) {
node = ofnode_path("/chosen");
if (!ofnode_valid(node)) {
debug("FPGA: /chosen node was not found.\n");
return -ENOENT;
}
phandle_p = ofnode_get_property(node, "firmware-loader",
&size);
if (!phandle_p) {
debug("FPGA: firmware-loader property was not");
debug(" found.\n");
return -ENOENT;
}
}
} else {
debug("FPGA: FPGA manager node was not found.\n");
return -ENOENT;
}
phandle = fdt32_to_cpu(*phandle_p);
ret = uclass_get_device_by_phandle_id(UCLASS_FS_FIRMWARE_LOADER,
phandle, &dev);
ret = get_fs_loader(&dev);
if (ret)
return ret;

View File

@ -311,34 +311,11 @@ static int gpio_hog_probe(struct udevice *dev)
return 0;
}
int gpio_hog_probe_all(void)
{
struct udevice *dev;
int ret;
int retval = 0;
for (uclass_first_device(UCLASS_NOP, &dev);
dev;
uclass_find_next_device(&dev)) {
if (dev->driver == DM_DRIVER_GET(gpio_hog)) {
ret = device_probe(dev);
if (ret) {
printf("Failed to probe device %s err: %d\n",
dev->name, ret);
retval = ret;
}
}
}
return retval;
}
int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
{
struct udevice *dev;
*desc = NULL;
gpio_hog_probe_all();
if (!uclass_get_device_by_name(UCLASS_NOP, name, &dev)) {
struct gpio_hog_priv *priv = dev_get_priv(dev);
@ -1505,9 +1482,17 @@ static int gpio_post_bind(struct udevice *dev)
&child);
if (ret)
return ret;
/*
* Make sure gpio-hogs are probed after bind
* since hogs can be essential to the hardware
* system.
*/
dev_or_flags(child, DM_FLAG_PROBE_AFTER_BIND);
}
}
}
return 0;
}

View File

@ -15,6 +15,8 @@
#include <fs_loader.h>
#include <log.h>
#include <asm/global_data.h>
#include <dm/device-internal.h>
#include <dm/root.h>
#include <linux/string.h>
#include <mapmem.h>
#include <malloc.h>
@ -297,6 +299,31 @@ U_BOOT_DRIVER(fs_loader) = {
.priv_auto = sizeof(struct firmware),
};
static struct device_plat default_plat = { 0 };
int get_fs_loader(struct udevice **dev)
{
int ret;
ofnode node = ofnode_get_chosen_node("firmware-loader");
if (ofnode_valid(node))
return uclass_get_device_by_ofnode(UCLASS_FS_FIRMWARE_LOADER,
node, dev);
/* Try the first device if none was chosen */
ret = uclass_first_device_err(UCLASS_FS_FIRMWARE_LOADER, dev);
if (ret != -ENODEV)
return ret;
/* Just create a new device */
ret = device_bind(dm_root(), DM_DRIVER_GET(fs_loader), "default-loader",
&default_plat, ofnode_null(), dev);
if (ret)
return ret;
return device_probe(*dev);
}
UCLASS_DRIVER(fs_loader) = {
.id = UCLASS_FS_FIRMWARE_LOADER,
.name = "fs-loader",

View File

@ -5,9 +5,11 @@
*/
#include <common.h>
#include <env.h>
#include <fs_loader.h>
#include <image.h>
#include <malloc.h>
#include <asm/io.h>
#include <dm/device_compat.h>
#include <linux/errno.h>
#include <u-boot/crc.h>
#include <dm.h>
@ -353,7 +355,7 @@ static void fm_init_qmi(struct fm_qmi_common *qmi)
/* Init common part of FM, index is fm num# like fm as above */
#ifdef CONFIG_TFABOOT
int fm_init_common(int index, struct ccsr_fman *reg)
int fm_init_common(int index, struct ccsr_fman *reg, const char *firmware_name)
{
int rc;
void *addr = NULL;
@ -448,10 +450,32 @@ int fm_init_common(int index, struct ccsr_fman *reg)
return fm_init_bmi(index, &reg->fm_bmi_common);
}
#else
int fm_init_common(int index, struct ccsr_fman *reg)
int fm_init_common(int index, struct ccsr_fman *reg, const char *firmware_name)
{
int rc;
#if defined(CONFIG_SYS_QE_FMAN_FW_IN_NOR)
#if defined(CONFIG_SYS_QE_FMAN_FW_IN_FS)
struct udevice *fs_loader;
void *addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH);
if (!addr)
return -ENOMEM;
rc = get_fs_loader(&fs_loader);
if (rc) {
debug("could not get fs loader: %d\n", rc);
return rc;
}
if (!firmware_name)
firmware_name = "fman.itb";
rc = request_firmware_into_buf(fs_loader, firmware_name, addr,
CONFIG_SYS_QE_FMAN_FW_LENGTH, 0);
if (rc < 0) {
debug("could not request %s: %d\n", firmware_name, rc);
return rc;
}
#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_NOR)
void *addr = (void *)CONFIG_SYS_FMAN_FW_ADDR;
#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_NAND)
size_t fw_length = CONFIG_SYS_QE_FMAN_FW_LENGTH;
@ -561,6 +585,8 @@ static const struct udevice_id fman_ids[] = {
static int fman_probe(struct udevice *dev)
{
const char *firmware_name = NULL;
int ret;
struct fman_priv *priv = dev_get_priv(dev);
priv->reg = (struct ccsr_fman *)(uintptr_t)dev_read_addr(dev);
@ -570,7 +596,13 @@ static int fman_probe(struct udevice *dev)
return -EINVAL;
}
return fm_init_common(priv->fman_id, priv->reg);
ret = dev_read_string_index(dev, "firmware-name", 0, &firmware_name);
if (ret && ret != -EINVAL) {
dev_dbg(dev, "Could not read firmware-name\n");
return ret;
}
return fm_init_common(priv->fman_id, priv->reg, firmware_name);
}
static int fman_remove(struct udevice *dev)

View File

@ -106,7 +106,7 @@ struct fm_port_global_pram {
void *fm_muram_alloc(int fm_idx, size_t size, ulong align);
void *fm_muram_base(int fm_idx);
int fm_init_common(int index, struct ccsr_fman *reg);
int fm_init_common(int index, struct ccsr_fman *reg, const char *firmware_name);
int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info);
phy_interface_t fman_port_enet_if(enum fm_port port);
void fman_disable_port(enum fm_port port);

View File

@ -27,6 +27,10 @@ choice
depends on FMAN_ENET || QE
default SYS_QE_FMAN_FW_IN_ROM
config SYS_QE_FMAN_FW_IN_FS
depends on FS_LOADER && FMAN_ENET
bool "Filesystem"
config SYS_QE_FMAN_FW_IN_NOR
bool "NOR flash"

View File

@ -461,14 +461,6 @@ int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc);
*/
int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc);
/**
* gpio_hog_probe_all() - probe all gpio devices with
* gpio-hog subnodes.
*
* @return: Returns return value from device_probe()
*/
int gpio_hog_probe_all(void);
/**
* gpio_lookup_name - Look up a GPIO name and return its details
*

View File

@ -521,6 +521,9 @@
"if fstype ${devtype} " \
"${devnum}:${distro_bootpart} " \
"bootfstype; then " \
"part uuid ${devtype} " \
"${devnum}:${distro_bootpart} " \
"distro_bootpart_uuid ; " \
"run scan_dev_for_boot; " \
"fi; " \
"done; " \

View File

@ -52,4 +52,16 @@ struct device_plat {
int request_firmware_into_buf(struct udevice *dev,
const char *name,
void *buf, size_t size, u32 offset);
/**
* get_fs_loader() - Get the chosen filesystem loader
* @dev: Where to store the device
*
* This gets a filesystem loader device based on the value of
* /chosen/firmware-loader. If no such property exists, it returns a
* firmware loader which is configured by environmental variables.
*
* Return: 0 on success, negative value on error
*/
int get_fs_loader(struct udevice **dev);
#endif

View File

@ -63,7 +63,7 @@ ulong timer_get_boot_us(void)
}
#else
extern unsigned long __weak timer_read_counter(void);
extern unsigned long timer_read_counter(void);
#endif
#if CONFIG_IS_ENABLED(TIMER)