Merge git://git.denx.de/u-boot-dm

For odroid-c2 (arch-meson) for now disable designware eth as meson
now needs to do some harder GPIO work.

Signed-off-by: Tom Rini <trini@konsulko.com>

Conflicts:
	lib/efi_loader/efi_disk.c

Modified:
	configs/odroid-c2_defconfig
This commit is contained in:
Tom Rini 2016-05-27 15:49:43 -04:00
commit e4a94ce4ac
64 changed files with 1277 additions and 515 deletions

View File

@ -46,7 +46,7 @@ obj-y += interrupts_64.o
else
obj-y += interrupts.o
endif
ifndef CONFIG_RESET
ifndef CONFIG_SYSRESET
obj-y += reset.o
endif

View File

@ -41,6 +41,9 @@ config DM_I2C
config DM_GPIO
default y
config BLK
default y
source "arch/arm/mach-rockchip/rk3288/Kconfig"
source "arch/arm/mach-rockchip/rk3036/Kconfig"
endif

View File

@ -7,24 +7,24 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <reset.h>
#include <sysreset.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3036.h>
#include <asm/arch/hardware.h>
#include <linux/err.h>
int rk3036_reset_request(struct udevice *dev, enum reset_t type)
int rk3036_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
struct rk3036_cru *cru = rockchip_get_cru();
if (IS_ERR(cru))
return PTR_ERR(cru);
switch (type) {
case RESET_WARM:
case SYSRESET_WARM:
writel(0xeca8, &cru->cru_glb_srst_snd_value);
break;
case RESET_COLD:
case SYSRESET_COLD:
writel(0xfdb9, &cru->cru_glb_srst_fst_value);
break;
default:
@ -34,12 +34,12 @@ int rk3036_reset_request(struct udevice *dev, enum reset_t type)
return -EINPROGRESS;
}
static struct reset_ops rk3036_reset = {
.request = rk3036_reset_request,
static struct sysreset_ops rk3036_sysreset = {
.request = rk3036_sysreset_request,
};
U_BOOT_DRIVER(reset_rk3036) = {
.name = "rk3036_reset",
.id = UCLASS_RESET,
.ops = &rk3036_reset,
U_BOOT_DRIVER(sysreset_rk3036) = {
.name = "rk3036_sysreset",
.id = UCLASS_SYSRESET,
.ops = &rk3036_sysreset,
};

View File

@ -7,25 +7,25 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <reset.h>
#include <sysreset.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3288.h>
#include <asm/arch/hardware.h>
#include <linux/err.h>
int rk3288_reset_request(struct udevice *dev, enum reset_t type)
int rk3288_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
struct rk3288_cru *cru = rockchip_get_cru();
if (IS_ERR(cru))
return PTR_ERR(cru);
switch (type) {
case RESET_WARM:
case SYSRESET_WARM:
rk_clrreg(&cru->cru_mode_con, 0xffff);
writel(0xeca8, &cru->cru_glb_srst_snd_value);
break;
case RESET_COLD:
case SYSRESET_COLD:
rk_clrreg(&cru->cru_mode_con, 0xffff);
writel(0xfdb9, &cru->cru_glb_srst_fst_value);
break;
@ -36,12 +36,12 @@ int rk3288_reset_request(struct udevice *dev, enum reset_t type)
return -EINPROGRESS;
}
static struct reset_ops rk3288_reset = {
.request = rk3288_reset_request,
static struct sysreset_ops rk3288_sysreset = {
.request = rk3288_sysreset_request,
};
U_BOOT_DRIVER(reset_rk3288) = {
.name = "rk3288_reset",
.id = UCLASS_RESET,
.ops = &rk3288_reset,
U_BOOT_DRIVER(sysreset_rk3288) = {
.name = "rk3288_sysreset",
.id = UCLASS_SYSRESET,
.ops = &rk3288_sysreset,
};

View File

@ -9,12 +9,12 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <reset.h>
#include <sysreset.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
static int msm_reset_request(struct udevice *dev, enum reset_t type)
static int msm_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
phys_addr_t addr = dev_get_addr(dev);
if (!addr)
@ -23,18 +23,18 @@ static int msm_reset_request(struct udevice *dev, enum reset_t type)
return -EINPROGRESS;
}
static struct reset_ops msm_reset_ops = {
.request = msm_reset_request,
static struct sysreset_ops msm_sysreset_ops = {
.request = msm_sysreset_request,
};
static const struct udevice_id msm_reset_ids[] = {
static const struct udevice_id msm_sysreset_ids[] = {
{ .compatible = "qcom,pshold" },
{ }
};
U_BOOT_DRIVER(msm_reset) = {
.name = "msm_reset",
.id = UCLASS_RESET,
.of_match = msm_reset_ids,
.ops = &msm_reset_ops,
.name = "msm_sysreset",
.id = UCLASS_SYSRESET,
.of_match = msm_sysreset_ids,
.ops = &msm_sysreset_ops,
};

View File

@ -360,8 +360,8 @@ int state_init(void)
assert(state->ram_buf);
/* No reset yet, so mark it as such. Always allow power reset */
state->last_reset = RESET_COUNT;
state->reset_allowed[RESET_POWER] = true;
state->last_sysreset = SYSRESET_COUNT;
state->sysreset_allowed[SYSRESET_POWER] = true;
/*
* Example of how to use GPIOs:

View File

@ -216,6 +216,17 @@
};
};
mbox: mbox {
compatible = "sandbox,mbox";
#mbox-cells = <1>;
};
mbox-test {
compatible = "sandbox,mbox-test";
mboxes = <&mbox 100>, <&mbox 1>;
mbox-names = "other", "test";
};
mmc {
compatible = "sandbox,mmc";
};

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2016, NVIDIA CORPORATION.
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef __SANDBOX_MBOX_H
#define __SANDBOX_MBOX_H
#include <common.h>
#define SANDBOX_MBOX_PING_XOR 0x12345678
struct udevice;
int sandbox_mbox_test_get(struct udevice *dev);
int sandbox_mbox_test_send(struct udevice *dev, uint32_t msg);
int sandbox_mbox_test_recv(struct udevice *dev, uint32_t *msg);
int sandbox_mbox_test_free(struct udevice *dev);
#endif

View File

@ -7,7 +7,7 @@
#define __SANDBOX_STATE_H
#include <config.h>
#include <reset.h>
#include <sysreset.h>
#include <stdbool.h>
#include <linux/stringify.h>
@ -60,8 +60,8 @@ struct sandbox_state {
bool write_state; /* Write sandbox state on exit */
bool ignore_missing_state_on_read; /* No error if state missing */
bool show_lcd; /* Show LCD on start-up */
enum reset_t last_reset; /* Last reset type */
bool reset_allowed[RESET_COUNT]; /* Allowed reset types */
enum sysreset_t last_sysreset; /* Last system reset type */
bool sysreset_allowed[SYSRESET_COUNT]; /* Allowed system reset types */
enum state_terminal_raw term_raw; /* Terminal raw/cooked */
bool skip_delays; /* Ignore any time delays (for test) */
bool show_test_output; /* Don't suppress stdout in tests */

View File

@ -11,66 +11,6 @@
#include <mmc.h>
static int curr_device = -1;
#ifndef CONFIG_GENERIC_MMC
int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int dev;
if (argc < 2)
return CMD_RET_USAGE;
if (strcmp(argv[1], "init") == 0) {
if (argc == 2) {
if (curr_device < 0)
dev = 1;
else
dev = curr_device;
} else if (argc == 3) {
dev = (int)simple_strtoul(argv[2], NULL, 10);
} else {
return CMD_RET_USAGE;
}
if (mmc_legacy_init(dev) != 0) {
puts("No MMC card found\n");
return 1;
}
curr_device = dev;
printf("mmc%d is available\n", curr_device);
} else if (strcmp(argv[1], "device") == 0) {
if (argc == 2) {
if (curr_device < 0) {
puts("No MMC device available\n");
return 1;
}
} else if (argc == 3) {
dev = (int)simple_strtoul(argv[2], NULL, 10);
#ifdef CONFIG_SYS_MMC_SET_DEV
if (mmc_set_dev(dev) != 0)
return 1;
#endif
curr_device = dev;
} else {
return CMD_RET_USAGE;
}
printf("mmc%d is current device\n", curr_device);
} else {
return CMD_RET_USAGE;
}
return 0;
}
U_BOOT_CMD(
mmc, 3, 1, do_mmc,
"MMC sub-system",
"init [dev] - init MMC sub system\n"
"mmc device [dev] - show or set current device"
);
#else /* !CONFIG_GENERIC_MMC */
static void print_mmcinfo(struct mmc *mmc)
{
@ -881,5 +821,3 @@ U_BOOT_CMD(
"display MMC info",
"- display info of the current MMC device"
);
#endif /* !CONFIG_GENERIC_MMC */

View File

@ -128,12 +128,12 @@ static inline int write_env(struct mmc *mmc, unsigned long size,
unsigned long offset, const void *buffer)
{
uint blk_start, blk_cnt, n;
struct blk_desc *desc = mmc_get_blk_desc(mmc);
blk_start = ALIGN(offset, mmc->write_bl_len) / mmc->write_bl_len;
blk_cnt = ALIGN(size, mmc->write_bl_len) / mmc->write_bl_len;
n = mmc->block_dev.block_write(&mmc->block_dev, blk_start,
blk_cnt, (u_char *)buffer);
n = blk_dwrite(desc, blk_start, blk_cnt, (u_char *)buffer);
return (n == blk_cnt) ? 0 : -1;
}
@ -197,12 +197,12 @@ static inline int read_env(struct mmc *mmc, unsigned long size,
unsigned long offset, const void *buffer)
{
uint blk_start, blk_cnt, n;
struct blk_desc *desc = mmc_get_blk_desc(mmc);
blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
n = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
(uchar *)buffer);
n = blk_dread(desc, blk_start, blk_cnt, (uchar *)buffer);
return (n == blk_cnt) ? 0 : -1;
}

View File

@ -34,9 +34,8 @@ static int mmc_load_legacy(struct mmc *mmc, ulong sector,
mmc->read_bl_len;
/* Read the header too to avoid extra memcpy */
count = mmc->block_dev.block_read(&mmc->block_dev, sector,
image_size_sectors,
(void *)(ulong)spl_image.load_addr);
count = blk_dread(mmc_get_blk_desc(mmc), sector, image_size_sectors,
(void *)(ulong)spl_image.load_addr);
debug("read %x sectors to %x\n", image_size_sectors,
spl_image.load_addr);
if (count != image_size_sectors)
@ -50,7 +49,7 @@ static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
{
struct mmc *mmc = load->dev;
return mmc->block_dev.block_read(&mmc->block_dev, sector, count, buf);
return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf);
}
static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector)
@ -63,7 +62,7 @@ static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector)
sizeof(struct image_header));
/* read image header to find the image size & load address */
count = mmc->block_dev.block_read(&mmc->block_dev, sector, 1, header);
count = blk_dread(mmc_get_blk_desc(mmc), sector, 1, header);
debug("hdr read sector %lx, count=%lu\n", sector, count);
if (count == 0) {
ret = -EIO;

View File

@ -47,7 +47,7 @@ CONFIG_CMD_CROS_EC=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_SPI=y
CONFIG_PWRSEQ=y
CONFIG_RESET=y
CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_ROCKCHIP_DWMMC=y
CONFIG_PINCTRL=y

View File

@ -23,7 +23,7 @@ CONFIG_MSM_GPIO=y
CONFIG_PM8916_GPIO=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_RESET=y
CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_MSM_SDHCI=y
CONFIG_DM_PMIC=y

View File

@ -28,7 +28,7 @@ CONFIG_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_LED=y
CONFIG_RESET=y
CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_ROCKCHIP_DWMMC=y
CONFIG_PINCTRL=y

View File

@ -28,7 +28,7 @@ CONFIG_CMD_EXT4=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent"
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
CONFIG_REGMAP=y
CONFIG_SPL_REGMAP=y
CONFIG_SYSCON=y
@ -40,7 +40,7 @@ CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_RESET=y
CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_ROCKCHIP_DWMMC=y
CONFIG_PINCTRL=y

View File

@ -28,7 +28,7 @@ CONFIG_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_LED=y
CONFIG_RESET=y
CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_ROCKCHIP_DWMMC=y
CONFIG_PINCTRL=y

View File

@ -13,7 +13,6 @@ CONFIG_DEFAULT_DEVICE_TREE="meson-gxbb-odroidc2"
CONFIG_OF_CONTROL=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_MESON=y
CONFIG_DEBUG_UART_BASE=0xc81004c0

View File

@ -38,7 +38,7 @@ CONFIG_CLK=y
CONFIG_SPL_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_RESET=y
CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_ROCKCHIP_DWMMC=y
CONFIG_PINCTRL=y

View File

@ -97,7 +97,7 @@ CONFIG_CROS_EC_SANDBOX=y
CONFIG_CROS_EC_SPI=y
CONFIG_PWRSEQ=y
CONFIG_SPL_PWRSEQ=y
CONFIG_RESET=y
CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_SANDBOX_MMC=y
CONFIG_SPI_FLASH_SANDBOX=y
@ -170,3 +170,6 @@ CONFIG_UNIT_TEST=y
CONFIG_UT_TIME=y
CONFIG_UT_DM=y
CONFIG_UT_ENV=y
CONFIG_MISC=y
CONFIG_DM_MAILBOX=y
CONFIG_SANDBOX_MBOX=y

View File

@ -94,7 +94,7 @@ CONFIG_CROS_EC_SANDBOX=y
CONFIG_CROS_EC_SPI=y
CONFIG_PWRSEQ=y
CONFIG_SPL_PWRSEQ=y
CONFIG_RESET=y
CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_SPI_FLASH_SANDBOX=y
CONFIG_SPI_FLASH=y

View File

@ -0,0 +1,32 @@
* Generic Mailbox Controller and client driver bindings
Generic binding to provide a way for Mailbox controller drivers to
assign appropriate mailbox channel to client drivers.
* Mailbox Controller
Required property:
- #mbox-cells: Must be at least 1. Number of cells in a mailbox
specifier.
Example:
mailbox: mailbox {
...
#mbox-cells = <1>;
};
* Mailbox Client
Required property:
- mboxes: List of phandle and mailbox channel specifiers.
Optional property:
- mbox-names: List of identifier strings for each mailbox channel.
Example:
pwr_cntrl: power {
...
mbox-names = "pwr-ctrl", "rpc";
mboxes = <&mailbox 0 &mailbox 1>;
};

View File

@ -606,19 +606,24 @@ methods actually defined.
1. Bind stage
A device and its driver are bound using one of these two methods:
U-Boot discovers devices using one of these two methods:
- Scan the U_BOOT_DEVICE() definitions. U-Boot It looks up the
name specified by each, to find the appropriate driver. It then calls
device_bind() to create a new device and bind' it to its driver. This will
call the device's bind() method.
- Scan the U_BOOT_DEVICE() definitions. U-Boot looks up the name specified
by each, to find the appropriate U_BOOT_DRIVER() definition. In this case,
there is no path by which driver_data may be provided, but the U_BOOT_DEVICE()
may provide platdata.
- Scan through the device tree definitions. U-Boot looks at top-level
nodes in the the device tree. It looks at the compatible string in each node
and uses the of_match part of the U_BOOT_DRIVER() structure to find the
right driver for each node. It then calls device_bind() to bind the
newly-created device to its driver (thereby creating a device structure).
This will also call the device's bind() method.
and uses the of_match table of the U_BOOT_DRIVER() structure to find the
right driver for each node. In this case, the of_match table may provide a
driver_data value, but platdata cannot be provided until later.
For each device that is discovered, U-Boot then calls device_bind() to create a
new device, initializes various core fields of the device object such as name,
uclass & driver, initializes any optional fields of the device object that are
applicable such as of_offset, driver_data & platdata, and finally calls the
driver's bind() method if one is defined.
At this point all the devices are known, and bound to their drivers. There
is a 'struct udevice' allocated for all devices. However, nothing has been

View File

@ -30,6 +30,8 @@ source "drivers/input/Kconfig"
source "drivers/led/Kconfig"
source "drivers/mailbox/Kconfig"
source "drivers/memory/Kconfig"
source "drivers/misc/Kconfig"

View File

@ -64,6 +64,7 @@ obj-y += video/
obj-y += watchdog/
obj-$(CONFIG_QE) += qe/
obj-$(CONFIG_U_QE) += qe/
obj-y += mailbox/
obj-y += memory/
obj-y += pwm/
obj-y += input/

View File

@ -407,7 +407,7 @@ static int rk3036_clk_bind(struct udevice *dev)
}
/* The reset driver does not have a device node, so bind it here */
ret = device_bind_driver(gd->dm_root, "rk3036_reset", "reset", &dev);
ret = device_bind_driver(gd->dm_root, "rk3036_sysreset", "reset", &dev);
if (ret)
debug("Warning: No RK3036 reset driver: ret=%d\n", ret);

View File

@ -891,7 +891,7 @@ static int rk3288_clk_bind(struct udevice *dev)
}
/* The reset driver does not have a device node, so bind it here */
ret = device_bind_driver(gd->dm_root, "rk3288_reset", "reset", &dev);
ret = device_bind_driver(gd->dm_root, "rk3288_sysreset", "reset", &dev);
if (ret)
debug("Warning: No RK3288 reset driver: ret=%d\n", ret);

View File

@ -26,9 +26,10 @@
DECLARE_GLOBAL_DATA_PTR;
int device_bind(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata, int of_offset,
struct udevice **devp)
static int device_bind_common(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata,
ulong driver_data, int of_offset,
struct udevice **devp)
{
struct udevice *dev;
struct uclass *uc;
@ -56,6 +57,7 @@ int device_bind(struct udevice *parent, const struct driver *drv,
INIT_LIST_HEAD(&dev->devres_head);
#endif
dev->platdata = platdata;
dev->driver_data = driver_data;
dev->name = name;
dev->of_offset = of_offset;
dev->parent = parent;
@ -193,6 +195,23 @@ fail_alloc1:
return ret;
}
int device_bind_with_driver_data(struct udevice *parent,
const struct driver *drv, const char *name,
ulong driver_data, int of_offset,
struct udevice **devp)
{
return device_bind_common(parent, drv, name, NULL, driver_data,
of_offset, devp);
}
int device_bind(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata, int of_offset,
struct udevice **devp)
{
return device_bind_common(parent, drv, name, platdata, 0, of_offset,
devp);
}
int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
const struct driver_info *info, struct udevice **devp)
{

View File

@ -170,7 +170,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
}
dm_dbg(" - found match at '%s'\n", entry->name);
ret = device_bind(parent, entry, name, NULL, offset, &dev);
ret = device_bind_with_driver_data(parent, entry, name,
id->data, offset, &dev);
if (ret == -ENODEV) {
dm_dbg("Driver '%s' refuses to bind\n", entry->name);
continue;
@ -180,7 +181,6 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
ret);
return ret;
} else {
dev->driver_data = id->data;
found = true;
if (devp)
*devp = dev;

View File

@ -258,43 +258,30 @@ static int gpio_sunxi_probe(struct udevice *dev)
return 0;
}
struct sunxi_gpio_soc_data {
int start;
int no_banks;
};
/**
* We have a top-level GPIO device with no actual GPIOs. It has a child
* device for each Sunxi bank.
*/
static int gpio_sunxi_bind(struct udevice *parent)
{
struct sunxi_gpio_soc_data *soc_data =
(struct sunxi_gpio_soc_data *)dev_get_driver_data(parent);
struct sunxi_gpio_platdata *plat = parent->platdata;
struct sunxi_gpio_reg *ctlr;
int bank, no_banks, ret, start;
int bank, ret;
/* If this is a child device, there is nothing to do here */
if (plat)
return 0;
if (fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
"allwinner,sun6i-a31-r-pinctrl") == 0) {
start = 'L' - 'A';
no_banks = 2; /* L & M */
} else if (fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
"allwinner,sun8i-a23-r-pinctrl") == 0 ||
fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
"allwinner,sun8i-a83t-r-pinctrl") == 0 ||
fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
"allwinner,sun8i-h3-r-pinctrl") == 0) {
start = 'L' - 'A';
no_banks = 1; /* L only */
} else if (fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
"allwinner,sun9i-a80-r-pinctrl") == 0) {
start = 'L' - 'A';
no_banks = 3; /* L, M & N */
} else {
start = 0;
no_banks = SUNXI_GPIO_BANKS;
}
ctlr = (struct sunxi_gpio_reg *)dev_get_addr(parent);
for (bank = 0; bank < no_banks; bank++) {
for (bank = 0; bank < soc_data->no_banks; bank++) {
struct sunxi_gpio_platdata *plat;
struct udevice *dev;
@ -302,7 +289,7 @@ static int gpio_sunxi_bind(struct udevice *parent)
if (!plat)
return -ENOMEM;
plat->regs = &ctlr->gpio_bank[bank];
plat->bank_name = gpio_bank_name(start + bank);
plat->bank_name = gpio_bank_name(soc_data->start + bank);
plat->gpio_count = SUNXI_GPIOS_PER_BANK;
ret = device_bind(parent, parent->driver,
@ -315,23 +302,46 @@ static int gpio_sunxi_bind(struct udevice *parent)
return 0;
}
static const struct sunxi_gpio_soc_data soc_data_a_all = {
.start = 0,
.no_banks = SUNXI_GPIO_BANKS,
};
static const struct sunxi_gpio_soc_data soc_data_l_1 = {
.start = 'L' - 'A',
.no_banks = 1,
};
static const struct sunxi_gpio_soc_data soc_data_l_2 = {
.start = 'L' - 'A',
.no_banks = 2,
};
static const struct sunxi_gpio_soc_data soc_data_l_3 = {
.start = 'L' - 'A',
.no_banks = 3,
};
#define ID(_compat_, _soc_data_) \
{ .compatible = _compat_, .data = (ulong)&soc_data_##_soc_data_ }
static const struct udevice_id sunxi_gpio_ids[] = {
{ .compatible = "allwinner,sun4i-a10-pinctrl" },
{ .compatible = "allwinner,sun5i-a10s-pinctrl" },
{ .compatible = "allwinner,sun5i-a13-pinctrl" },
{ .compatible = "allwinner,sun6i-a31-pinctrl" },
{ .compatible = "allwinner,sun6i-a31s-pinctrl" },
{ .compatible = "allwinner,sun7i-a20-pinctrl" },
{ .compatible = "allwinner,sun8i-a23-pinctrl" },
{ .compatible = "allwinner,sun8i-a33-pinctrl" },
{ .compatible = "allwinner,sun8i-a83t-pinctrl", },
{ .compatible = "allwinner,sun8i-h3-pinctrl" },
{ .compatible = "allwinner,sun9i-a80-pinctrl" },
{ .compatible = "allwinner,sun6i-a31-r-pinctrl" },
{ .compatible = "allwinner,sun8i-a23-r-pinctrl" },
{ .compatible = "allwinner,sun8i-a83t-r-pinctrl" },
{ .compatible = "allwinner,sun8i-h3-r-pinctrl", },
{ .compatible = "allwinner,sun9i-a80-r-pinctrl", },
ID("allwinner,sun4i-a10-pinctrl", a_all),
ID("allwinner,sun5i-a10s-pinctrl", a_all),
ID("allwinner,sun5i-a13-pinctrl", a_all),
ID("allwinner,sun6i-a31-pinctrl", a_all),
ID("allwinner,sun6i-a31s-pinctrl", a_all),
ID("allwinner,sun7i-a20-pinctrl", a_all),
ID("allwinner,sun8i-a23-pinctrl", a_all),
ID("allwinner,sun8i-a33-pinctrl", a_all),
ID("allwinner,sun8i-a83t-pinctrl", a_all),
ID("allwinner,sun8i-h3-pinctrl", a_all),
ID("allwinner,sun9i-a80-pinctrl", a_all),
ID("allwinner,sun6i-a31-r-pinctrl", l_2),
ID("allwinner,sun8i-a23-r-pinctrl", l_1),
ID("allwinner,sun8i-a83t-r-pinctrl", l_1),
ID("allwinner,sun8i-h3-r-pinctrl", l_1),
ID("allwinner,sun9i-a80-r-pinctrl", l_3),
{ }
};

20
drivers/mailbox/Kconfig Normal file
View File

@ -0,0 +1,20 @@
menu "Mailbox Controller Support"
config DM_MAILBOX
bool "Enable mailbox controllers using Driver Model"
depends on DM && OF_CONTROL
help
Enable support for the mailbox driver class. Mailboxes provide the
ability to transfer small messages and/or notifications from one
CPU to another CPU, or sometimes to dedicated HW modules. They form
the basis of a variety of inter-process/inter-CPU communication
protocols.
config SANDBOX_MBOX
bool "Enable the sandbox mailbox test driver"
depends on DM_MAILBOX && SANDBOX
help
Enable support for a test mailbox implementation, which simply echos
back a modified version of any message that is sent.
endmenu

7
drivers/mailbox/Makefile Normal file
View File

@ -0,0 +1,7 @@
# Copyright (c) 2016, NVIDIA CORPORATION.
#
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_DM_MAILBOX) += mailbox-uclass.o
obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox.o
obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox-test.o

View File

@ -0,0 +1,145 @@
/*
* Copyright (c) 2016, NVIDIA CORPORATION.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <dm.h>
#include <fdtdec.h>
#include <mailbox_client.h>
#include <mailbox_uclass.h>
DECLARE_GLOBAL_DATA_PTR;
static inline struct mbox_ops *mbox_dev_ops(struct udevice *dev)
{
return (struct mbox_ops *)dev->driver->ops;
}
static int mbox_of_xlate_default(struct mbox_chan *chan,
struct fdtdec_phandle_args *args)
{
debug("%s(chan=%p)\n", __func__, chan);
if (args->args_count != 1) {
debug("Invaild args_count: %d\n", args->args_count);
return -EINVAL;
}
chan->id = args->args[0];
return 0;
}
int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan)
{
struct fdtdec_phandle_args args;
int ret;
struct udevice *dev_mbox;
struct mbox_ops *ops;
debug("%s(dev=%p, index=%d, chan=%p)\n", __func__, dev, index, chan);
ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
"mboxes", "#mbox-cells", 0,
index, &args);
if (ret) {
debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
__func__, ret);
return ret;
}
ret = uclass_get_device_by_of_offset(UCLASS_MAILBOX, args.node,
&dev_mbox);
if (ret) {
debug("%s: uclass_get_device_by_of_offset failed: %d\n",
__func__, ret);
return ret;
}
ops = mbox_dev_ops(dev_mbox);
chan->dev = dev_mbox;
if (ops->of_xlate)
ret = ops->of_xlate(chan, &args);
else
ret = mbox_of_xlate_default(chan, &args);
if (ret) {
debug("of_xlate() failed: %d\n", ret);
return ret;
}
ret = ops->request(chan);
if (ret) {
debug("ops->request() failed: %d\n", ret);
return ret;
}
return 0;
}
int mbox_get_by_name(struct udevice *dev, const char *name,
struct mbox_chan *chan)
{
int index;
debug("%s(dev=%p, name=%s, chan=%p)\n", __func__, dev, name, chan);
index = fdt_find_string(gd->fdt_blob, dev->of_offset, "mbox-names",
name);
if (index < 0) {
debug("fdt_find_string() failed: %d\n", index);
return index;
}
return mbox_get_by_index(dev, index, chan);
}
int mbox_free(struct mbox_chan *chan)
{
struct mbox_ops *ops = mbox_dev_ops(chan->dev);
debug("%s(chan=%p)\n", __func__, chan);
return ops->free(chan);
}
int mbox_send(struct mbox_chan *chan, const void *data)
{
struct mbox_ops *ops = mbox_dev_ops(chan->dev);
debug("%s(chan=%p, data=%p)\n", __func__, chan, data);
return ops->send(chan, data);
}
int mbox_recv(struct mbox_chan *chan, void *data, ulong timeout_us)
{
struct mbox_ops *ops = mbox_dev_ops(chan->dev);
ulong start_time;
int ret;
debug("%s(chan=%p, data=%p, timeout_us=%ld)\n", __func__, chan, data,
timeout_us);
start_time = timer_get_us();
/*
* Account for partial us ticks, but if timeout_us is 0, ensure we
* still don't wait at all.
*/
if (timeout_us)
timeout_us++;
for (;;) {
ret = ops->recv(chan, data);
if (ret != -ENODATA)
return ret;
if ((timer_get_us() - start_time) >= timeout_us)
return -ETIMEDOUT;
}
}
UCLASS_DRIVER(mailbox) = {
.id = UCLASS_MAILBOX,
.name = "mailbox",
};

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2016, NVIDIA CORPORATION.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <dm.h>
#include <mailbox_client.h>
#include <asm/io.h>
struct sandbox_mbox_test {
struct mbox_chan chan;
};
int sandbox_mbox_test_get(struct udevice *dev)
{
struct sandbox_mbox_test *sbmt = dev_get_priv(dev);
return mbox_get_by_name(dev, "test", &sbmt->chan);
}
int sandbox_mbox_test_send(struct udevice *dev, uint32_t msg)
{
struct sandbox_mbox_test *sbmt = dev_get_priv(dev);
return mbox_send(&sbmt->chan, &msg);
}
int sandbox_mbox_test_recv(struct udevice *dev, uint32_t *msg)
{
struct sandbox_mbox_test *sbmt = dev_get_priv(dev);
return mbox_recv(&sbmt->chan, msg, 100);
}
int sandbox_mbox_test_free(struct udevice *dev)
{
struct sandbox_mbox_test *sbmt = dev_get_priv(dev);
return mbox_free(&sbmt->chan);
}
static const struct udevice_id sandbox_mbox_test_ids[] = {
{ .compatible = "sandbox,mbox-test" },
{ }
};
U_BOOT_DRIVER(sandbox_mbox_test) = {
.name = "sandbox_mbox_test",
.id = UCLASS_MISC,
.of_match = sandbox_mbox_test_ids,
.priv_auto_alloc_size = sizeof(struct sandbox_mbox_test),
};

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2016, NVIDIA CORPORATION.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <dm.h>
#include <mailbox_uclass.h>
#include <asm/io.h>
#include <asm/mbox.h>
#define SANDBOX_MBOX_CHANNELS 2
struct sandbox_mbox_chan {
bool rx_msg_valid;
uint32_t rx_msg;
};
struct sandbox_mbox {
struct sandbox_mbox_chan chans[SANDBOX_MBOX_CHANNELS];
};
static int sandbox_mbox_request(struct mbox_chan *chan)
{
debug("%s(chan=%p)\n", __func__, chan);
if (chan->id >= SANDBOX_MBOX_CHANNELS)
return -EINVAL;
return 0;
}
static int sandbox_mbox_free(struct mbox_chan *chan)
{
debug("%s(chan=%p)\n", __func__, chan);
return 0;
}
static int sandbox_mbox_send(struct mbox_chan *chan, const void *data)
{
struct sandbox_mbox *sbm = dev_get_priv(chan->dev);
const uint32_t *pmsg = data;
debug("%s(chan=%p, data=%p)\n", __func__, chan, data);
sbm->chans[chan->id].rx_msg = *pmsg ^ SANDBOX_MBOX_PING_XOR;
sbm->chans[chan->id].rx_msg_valid = true;
return 0;
}
static int sandbox_mbox_recv(struct mbox_chan *chan, void *data)
{
struct sandbox_mbox *sbm = dev_get_priv(chan->dev);
uint32_t *pmsg = data;
debug("%s(chan=%p, data=%p)\n", __func__, chan, data);
if (!sbm->chans[chan->id].rx_msg_valid)
return -ENODATA;
*pmsg = sbm->chans[chan->id].rx_msg;
sbm->chans[chan->id].rx_msg_valid = false;
return 0;
}
static int sandbox_mbox_bind(struct udevice *dev)
{
debug("%s(dev=%p)\n", __func__, dev);
return 0;
}
static int sandbox_mbox_probe(struct udevice *dev)
{
debug("%s(dev=%p)\n", __func__, dev);
return 0;
}
static const struct udevice_id sandbox_mbox_ids[] = {
{ .compatible = "sandbox,mbox" },
{ }
};
struct mbox_ops sandbox_mbox_mbox_ops = {
.request = sandbox_mbox_request,
.free = sandbox_mbox_free,
.send = sandbox_mbox_send,
.recv = sandbox_mbox_recv,
};
U_BOOT_DRIVER(sandbox_mbox) = {
.name = "sandbox_mbox",
.id = UCLASS_MAILBOX,
.of_match = sandbox_mbox_ids,
.bind = sandbox_mbox_bind,
.probe = sandbox_mbox_probe,
.priv_auto_alloc_size = sizeof(struct sandbox_mbox),
.ops = &sandbox_mbox_mbox_ops,
};

View File

@ -121,13 +121,13 @@ config PCA9551_I2C_ADDR
help
The I2C address of the PCA9551 LED controller.
config RESET
bool "Enable support for reset drivers"
config SYSRESET
bool "Enable support for system reset drivers"
depends on DM
help
Enable reset drivers which can be used to reset the CPU or board.
Each driver can provide a reset method which will be called to
effect a reset. The uclass will try all available drivers when
Enable system reset drivers which can be used to reset the CPU or
board. Each driver can provide a reset method which will be called
to effect a reset. The uclass will try all available drivers when
reset_walk() is called.
config WINBOND_W83627

View File

@ -27,7 +27,7 @@ obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
obj-$(CONFIG_NS87308) += ns87308.o
obj-$(CONFIG_PDSP188x) += pdsp188x.o
obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
obj-$(CONFIG_SANDBOX) += reset_sandbox.o
obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
ifdef CONFIG_DM_I2C
obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o
endif
@ -40,7 +40,7 @@ obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o
obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
obj-$(CONFIG_RESET) += reset-uclass.o
obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o
obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
obj-$(CONFIG_QFW) += qfw.o

View File

@ -1,100 +0,0 @@
/*
* Copyright (c) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <reset.h>
#include <asm/state.h>
#include <asm/test.h>
DECLARE_GLOBAL_DATA_PTR;
static int sandbox_warm_reset_request(struct udevice *dev, enum reset_t type)
{
struct sandbox_state *state = state_get_current();
switch (type) {
case RESET_WARM:
state->last_reset = type;
break;
default:
return -ENOSYS;
}
if (!state->reset_allowed[type])
return -EACCES;
return -EINPROGRESS;
}
static int sandbox_reset_request(struct udevice *dev, enum reset_t type)
{
struct sandbox_state *state = state_get_current();
/*
* If we have a device tree, the device we created from platform data
* (see the U_BOOT_DEVICE() declaration below) should not do anything.
* If we are that device, return an error.
*/
if (state->fdt_fname && dev->of_offset == -1)
return -ENODEV;
switch (type) {
case RESET_COLD:
state->last_reset = type;
break;
case RESET_POWER:
state->last_reset = type;
if (!state->reset_allowed[type])
return -EACCES;
sandbox_exit();
break;
default:
return -ENOSYS;
}
if (!state->reset_allowed[type])
return -EACCES;
return -EINPROGRESS;
}
static struct reset_ops sandbox_reset_ops = {
.request = sandbox_reset_request,
};
static const struct udevice_id sandbox_reset_ids[] = {
{ .compatible = "sandbox,reset" },
{ }
};
U_BOOT_DRIVER(reset_sandbox) = {
.name = "reset_sandbox",
.id = UCLASS_RESET,
.of_match = sandbox_reset_ids,
.ops = &sandbox_reset_ops,
};
static struct reset_ops sandbox_warm_reset_ops = {
.request = sandbox_warm_reset_request,
};
static const struct udevice_id sandbox_warm_reset_ids[] = {
{ .compatible = "sandbox,warm-reset" },
{ }
};
U_BOOT_DRIVER(warm_reset_sandbox) = {
.name = "warm_reset_sandbox",
.id = UCLASS_RESET,
.of_match = sandbox_warm_reset_ids,
.ops = &sandbox_warm_reset_ops,
};
/* This is here in case we don't have a device tree */
U_BOOT_DEVICE(reset_sandbox_non_fdt) = {
.name = "reset_sandbox",
};

View File

@ -6,7 +6,7 @@
*/
#include <common.h>
#include <reset.h>
#include <sysreset.h>
#include <dm.h>
#include <errno.h>
#include <regmap.h>
@ -15,9 +15,9 @@
#include <dm/root.h>
#include <linux/err.h>
int reset_request(struct udevice *dev, enum reset_t type)
int sysreset_request(struct udevice *dev, enum sysreset_t type)
{
struct reset_ops *ops = reset_get_ops(dev);
struct sysreset_ops *ops = sysreset_get_ops(dev);
if (!ops->request)
return -ENOSYS;
@ -25,16 +25,16 @@ int reset_request(struct udevice *dev, enum reset_t type)
return ops->request(dev, type);
}
int reset_walk(enum reset_t type)
int sysreset_walk(enum sysreset_t type)
{
struct udevice *dev;
int ret = -ENOSYS;
while (ret != -EINPROGRESS && type < RESET_COUNT) {
for (uclass_first_device(UCLASS_RESET, &dev);
while (ret != -EINPROGRESS && type < SYSRESET_COUNT) {
for (uclass_first_device(UCLASS_SYSRESET, &dev);
dev;
uclass_next_device(&dev)) {
ret = reset_request(dev, type);
ret = sysreset_request(dev, type);
if (ret == -EINPROGRESS)
break;
}
@ -44,38 +44,38 @@ int reset_walk(enum reset_t type)
return ret;
}
void reset_walk_halt(enum reset_t type)
void sysreset_walk_halt(enum sysreset_t type)
{
int ret;
ret = reset_walk(type);
ret = sysreset_walk(type);
/* Wait for the reset to take effect */
if (ret == -EINPROGRESS)
mdelay(100);
/* Still no reset? Give up */
printf("Reset not supported on this platform\n");
debug("System reset not supported on this platform\n");
hang();
}
/**
* reset_cpu() - calls reset_walk(RESET_WARM)
* reset_cpu() - calls sysreset_walk(SYSRESET_WARM)
*/
void reset_cpu(ulong addr)
{
reset_walk_halt(RESET_WARM);
sysreset_walk_halt(SYSRESET_WARM);
}
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
reset_walk_halt(RESET_WARM);
sysreset_walk_halt(SYSRESET_WARM);
return 0;
}
UCLASS_DRIVER(reset) = {
.id = UCLASS_RESET,
.name = "reset",
UCLASS_DRIVER(sysreset) = {
.id = UCLASS_SYSRESET,
.name = "sysreset",
};

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <sysreset.h>
#include <asm/state.h>
#include <asm/test.h>
DECLARE_GLOBAL_DATA_PTR;
static int sandbox_warm_sysreset_request(struct udevice *dev,
enum sysreset_t type)
{
struct sandbox_state *state = state_get_current();
switch (type) {
case SYSRESET_WARM:
state->last_sysreset = type;
break;
default:
return -ENOSYS;
}
if (!state->sysreset_allowed[type])
return -EACCES;
return -EINPROGRESS;
}
static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
struct sandbox_state *state = state_get_current();
/*
* If we have a device tree, the device we created from platform data
* (see the U_BOOT_DEVICE() declaration below) should not do anything.
* If we are that device, return an error.
*/
if (state->fdt_fname && dev->of_offset == -1)
return -ENODEV;
switch (type) {
case SYSRESET_COLD:
state->last_sysreset = type;
break;
case SYSRESET_POWER:
state->last_sysreset = type;
if (!state->sysreset_allowed[type])
return -EACCES;
sandbox_exit();
break;
default:
return -ENOSYS;
}
if (!state->sysreset_allowed[type])
return -EACCES;
return -EINPROGRESS;
}
static struct sysreset_ops sandbox_sysreset_ops = {
.request = sandbox_sysreset_request,
};
static const struct udevice_id sandbox_sysreset_ids[] = {
{ .compatible = "sandbox,reset" },
{ }
};
U_BOOT_DRIVER(sysreset_sandbox) = {
.name = "sysreset_sandbox",
.id = UCLASS_SYSRESET,
.of_match = sandbox_sysreset_ids,
.ops = &sandbox_sysreset_ops,
};
static struct sysreset_ops sandbox_warm_sysreset_ops = {
.request = sandbox_warm_sysreset_request,
};
static const struct udevice_id sandbox_warm_sysreset_ids[] = {
{ .compatible = "sandbox,warm-reset" },
{ }
};
U_BOOT_DRIVER(warm_sysreset_sandbox) = {
.name = "warm_sysreset_sandbox",
.id = UCLASS_SYSRESET,
.of_match = sandbox_warm_sysreset_ids,
.ops = &sandbox_warm_sysreset_ops,
};
/* This is here in case we don't have a device tree */
U_BOOT_DEVICE(sysreset_sandbox_non_fdt) = {
.name = "sysreset_sandbox",
};

View File

@ -454,27 +454,40 @@ static const struct mmc_ops dwmci_ops = {
.init = dwmci_init,
};
void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
uint caps, u32 max_clk, u32 min_clk)
{
cfg->name = name;
cfg->ops = &dwmci_ops;
cfg->f_min = min_clk;
cfg->f_max = max_clk;
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
cfg->host_caps = caps;
if (buswidth == 8) {
cfg->host_caps |= MMC_MODE_8BIT;
cfg->host_caps &= ~MMC_MODE_4BIT;
} else {
cfg->host_caps |= MMC_MODE_4BIT;
cfg->host_caps &= ~MMC_MODE_8BIT;
}
cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
}
#ifdef CONFIG_BLK
int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg)
{
return mmc_bind(dev, mmc, cfg);
}
#else
int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
{
host->cfg.name = host->name;
host->cfg.ops = &dwmci_ops;
host->cfg.f_min = min_clk;
host->cfg.f_max = max_clk;
host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
host->cfg.host_caps = host->caps;
if (host->buswidth == 8) {
host->cfg.host_caps |= MMC_MODE_8BIT;
host->cfg.host_caps &= ~MMC_MODE_4BIT;
} else {
host->cfg.host_caps |= MMC_MODE_4BIT;
host->cfg.host_caps &= ~MMC_MODE_8BIT;
}
host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
dwmci_setup_cfg(&host->cfg, host->name, host->buswidth, host->caps,
max_clk, min_clk);
host->mmc = mmc_create(&host->cfg, host);
if (host->mmc == NULL)
@ -482,3 +495,4 @@ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
return 0;
}
#endif

View File

@ -984,7 +984,7 @@ static const int fbase[] = {
/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
* to platforms without floating point.
*/
static const int multipliers[] = {
static const u8 multipliers[] = {
0, /* reserved */
10,
12,
@ -1531,15 +1531,6 @@ static int mmc_send_if_cond(struct mmc *mmc)
return 0;
}
/* not used any more */
int __deprecated mmc_register(struct mmc *mmc)
{
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf("%s is deprecated! use mmc_create() instead.\n", __func__);
#endif
return -1;
}
#ifdef CONFIG_BLK
int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
{
@ -1566,7 +1557,7 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
bdesc->removable = 1;
/* setup initial part type */
bdesc->part_type = mmc->cfg->part_type;
bdesc->part_type = cfg->part_type;
mmc->dev = dev;
return 0;

View File

@ -37,6 +37,19 @@ ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
/* SPL will never write or erase, declare dummies to reduce code size. */
#ifdef CONFIG_BLK
static inline unsigned long mmc_berase(struct udevice *dev,
lbaint_t start, lbaint_t blkcnt)
{
return 0;
}
static inline ulong mmc_bwrite(struct udevice *dev, lbaint_t start,
lbaint_t blkcnt, const void *src)
{
return 0;
}
#else
static inline unsigned long mmc_berase(struct blk_desc *block_dev,
lbaint_t start, lbaint_t blkcnt)
{
@ -48,6 +61,7 @@ static inline ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
{
return 0;
}
#endif
#endif /* CONFIG_SPL_BUILD */

View File

@ -18,6 +18,11 @@
DECLARE_GLOBAL_DATA_PTR;
struct rockchip_mmc_plat {
struct mmc_config cfg;
struct mmc mmc;
};
struct rockchip_dwmmc_priv {
struct udevice *clk;
int periph;
@ -62,6 +67,9 @@ static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
static int rockchip_dwmmc_probe(struct udevice *dev)
{
#ifdef CONFIG_BLK
struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
#endif
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
struct dwmci_host *host = &priv->host;
@ -100,16 +108,37 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
return ret;
}
#endif
#ifdef CONFIG_BLK
dwmci_setup_cfg(&plat->cfg, dev->name, host->buswidth, host->caps,
minmax[1], minmax[0]);
host->mmc = &plat->mmc;
#else
ret = add_dwmci(host, minmax[1], minmax[0]);
if (ret)
return ret;
#endif
host->mmc->priv = &priv->host;
host->mmc->dev = dev;
upriv->mmc = host->mmc;
return 0;
}
static int rockchip_dwmmc_bind(struct udevice *dev)
{
#ifdef CONFIG_BLK
struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
int ret;
ret = dwmci_bind(dev, &plat->mmc, &plat->cfg);
if (ret)
return ret;
#endif
return 0;
}
static const struct udevice_id rockchip_dwmmc_ids[] = {
{ .compatible = "rockchip,rk3288-dw-mshc" },
{ }
@ -120,8 +149,10 @@ U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
.id = UCLASS_MMC,
.of_match = rockchip_dwmmc_ids,
.ofdata_to_platdata = rockchip_dwmmc_ofdata_to_platdata,
.bind = rockchip_dwmmc_bind,
.probe = rockchip_dwmmc_probe,
.priv_auto_alloc_size = sizeof(struct rockchip_dwmmc_priv),
.platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat),
};
#ifdef CONFIG_PWRSEQ

View File

@ -137,7 +137,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
int trans_bytes = 0, is_aligned = 1;
u32 mask, flags, mode;
unsigned int time = 0, start_addr = 0;
int mmc_dev = mmc->block_dev.devnum;
int mmc_dev = mmc_get_blk_desc(mmc)->devnum;
unsigned start = get_timer(0);
/* Timeout unit - ms */

View File

@ -326,6 +326,7 @@ static int rk_vop_probe(struct udevice *dev)
if (!ret)
break;
}
video_set_flush_dcache(dev, 1);
return ret;
}

View File

@ -69,7 +69,6 @@
#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img"
#define CONFIG_SPL_PINCTRL_SUPPORT
#define CONFIG_SPL_GPIO_SUPPORT
#define CONFIG_SPL_RAM_SUPPORT
#define CONFIG_SPL_DRIVERS_MISC_SUPPORT

View File

@ -106,6 +106,7 @@
#define CONFIG_USB_STORAGE
#define CONFIG_USB_HOST_ETHER
#define CONFIG_USB_ETHER_SMSC95XX
#define CONFIG_TFTP_TSIZE
#define CONFIG_MISC_INIT_R
#define CONFIG_USB_KEYBOARD
#define CONFIG_SYS_USB_EVENT_POLL

View File

@ -38,6 +38,30 @@ int device_bind(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata, int of_offset,
struct udevice **devp);
/**
* device_bind_with_driver_data() - Create a device and bind it to a driver
*
* Called to set up a new device attached to a driver, in the case where the
* driver was matched to the device by means of a match table that provides
* driver_data.
*
* Once bound a device exists but is not yet active until device_probe() is
* called.
*
* @parent: Pointer to device's parent, under which this driver will exist
* @drv: Device's driver
* @name: Name of device (e.g. device tree node name)
* @driver_data: The driver_data field from the driver's match table.
* @of_offset: Offset of device tree node for this device. This is -1 for
* devices which don't use device tree.
* @devp: if non-NULL, returns a pointer to the bound device
* @return 0 if OK, -ve on error
*/
int device_bind_with_driver_data(struct udevice *parent,
const struct driver *drv, const char *name,
ulong driver_data, int of_offset,
struct udevice **devp);
/**
* device_bind_by_name: Create a device and bind it to a driver
*

View File

@ -44,6 +44,7 @@ enum uclass_id {
UCLASS_KEYBOARD, /* Keyboard input device */
UCLASS_LED, /* Light-emitting diode (LED) */
UCLASS_LPC, /* x86 'low pin count' interface */
UCLASS_MAILBOX, /* Mailbox controller */
UCLASS_MASS_STORAGE, /* Mass storage device */
UCLASS_MISC, /* Miscellaneous device */
UCLASS_MMC, /* SD / MMC card or chip */
@ -61,7 +62,6 @@ enum uclass_id {
UCLASS_PWM, /* Pulse-width modulator */
UCLASS_PWRSEQ, /* Power sequence device */
UCLASS_REGULATOR, /* Regulator device */
UCLASS_RESET, /* Reset device */
UCLASS_REMOTEPROC, /* Remote Processor device */
UCLASS_RTC, /* Real time clock device */
UCLASS_SERIAL, /* Serial UART */
@ -70,6 +70,7 @@ enum uclass_id {
UCLASS_SPI_FLASH, /* SPI flash */
UCLASS_SPI_GENERIC, /* Generic SPI flash target */
UCLASS_SYSCON, /* System configuration device */
UCLASS_SYSRESET, /* System reset device */
UCLASS_THERMAL, /* Thermal sensor */
UCLASS_TIMER, /* Timer device */
UCLASS_TPM, /* Trusted Platform Module TIS interface */

View File

@ -180,8 +180,9 @@ struct dwmci_host {
* @freq: Frequency the host is trying to achieve
*/
unsigned int (*get_mmc_clk)(struct dwmci_host *host, uint freq);
#ifndef CONFIG_BLK
struct mmc_config cfg;
#endif
/* use fifo mode to read and write data */
bool fifo_mode;
@ -223,5 +224,9 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg)
return readb(host->ioaddr + reg);
}
void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
uint caps, u32 max_clk, u32 min_clk);
int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk);
#endif /* __DWMMC_HW_H */

View File

@ -145,7 +145,7 @@ extern void *efi_bounce_buffer;
#endif
/* Convert strings from normal C strings to uEFI strings */
static inline void ascii2unicode(u16 *unicode, char *ascii)
static inline void ascii2unicode(u16 *unicode, const char *ascii)
{
while (*ascii)
*(unicode++) = *(ascii++);

149
include/mailbox_client.h Normal file
View File

@ -0,0 +1,149 @@
/*
* Copyright (c) 2016, NVIDIA CORPORATION.
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef _MAILBOX_CLIENT_H
#define _MAILBOX_CLIENT_H
/**
* A mailbox is a hardware mechanism for transferring small fixed-size messages
* and/or notifications between the CPU on which U-Boot runs and some other
* device such as an auxiliary CPU running firmware or a hardware module.
*
* Data transfer is optional; a mailbox may consist solely of a notification
* mechanism. When data transfer is implemented, it is via HW registers or
* FIFOs, rather than via RAM-based buffers. The mailbox API generally
* implements any communication protocol enforced solely by hardware, and
* leaves any higher-level protocols to other layers.
*
* A mailbox channel is a bi-directional mechanism that can send a message or
* notification to a single specific remote entity, and receive messages or
* notifications from that entity. The size, content, and format of such
* messages is defined by the mailbox implementation, or the remote entity with
* which it communicates; there is no general standard at this API level.
*
* A driver that implements UCLASS_MAILBOX is a mailbox provider. A provider
* will often implement multiple separate mailbox channels, since the hardware
* it manages often has this capability. mailbox_uclass.h describes the
* interface which mailbox providers must implement.
*
* Mailbox consumers/clients generate and send, or receive and process,
* messages. This header file describes the API used by clients.
*/
struct udevice;
/**
* struct mbox_chan - A handle to a single mailbox channel.
*
* Clients provide storage for channels. The content of the channel structure
* is managed solely by the mailbox API and mailbox drivers. A mailbox channel
* is initialized by "get"ing the mailbox. The channel struct is passed to all
* other mailbox APIs to identify which mailbox to operate upon.
*
* @dev: The device which implements the mailbox.
* @id: The mailbox channel ID within the provider.
*
* Currently, the mailbox API assumes that a single integer ID is enough to
* identify and configure any mailbox channel for any mailbox provider. If this
* assumption becomes invalid in the future, the struct could be expanded to
* either (a) add more fields to allow mailbox providers to store additional
* information, or (b) replace the id field with an opaque pointer, which the
* provider would dynamically allocated during its .of_xlate op, and process
* during is .request op. This may require the addition of an extra op to clean
* up the allocation.
*/
struct mbox_chan {
struct udevice *dev;
/*
* Written by of_xlate. We assume a single id is enough for now. In the
* future, we might add more fields here.
*/
unsigned long id;
};
/**
* mbox_get_by_index - Get/request a mailbox by integer index
*
* This looks up and requests a mailbox channel. The index is relative to the
* client device; each device is assumed to have n mailbox channels associated
* with it somehow, and this function finds and requests one of them. The
* mapping of client device channel indices to provider channels may be via
* device-tree properties, board-provided mapping tables, or some other
* mechanism.
*
* @dev: The client device.
* @index: The index of the mailbox channel to request, within the
* client's list of channels.
* @chan A pointer to a channel object to initialize.
* @return 0 if OK, or a negative error code.
*/
int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan);
/**
* mbox_get_by_name - Get/request a mailbox by name
*
* This looks up and requests a mailbox channel. The name is relative to the
* client device; each device is assumed to have n mailbox channels associated
* with it somehow, and this function finds and requests one of them. The
* mapping of client device channel names to provider channels may be via
* device-tree properties, board-provided mapping tables, or some other
* mechanism.
*
* @dev: The client device.
* @name: The name of the mailbox channel to request, within the client's
* list of channels.
* @chan A pointer to a channel object to initialize.
* @return 0 if OK, or a negative error code.
*/
int mbox_get_by_name(struct udevice *dev, const char *name,
struct mbox_chan *chan);
/**
* mbox_free - Free a previously requested mailbox channel.
*
* @chan: A channel object that was previously successfully requested by
* calling mbox_get_by_*().
* @return 0 if OK, or a negative error code.
*/
int mbox_free(struct mbox_chan *chan);
/**
* mbox_send - Send a message over a mailbox channel
*
* This function will send a message to the remote entity. It may return before
* the remote entity has received and/or processed the message.
*
* @chan: A channel object that was previously successfully requested by
* calling mbox_get_by_*().
* @data: A pointer to the message to transfer. The format and size of
* the memory region pointed at by @data is determined by the
* mailbox provider. Providers that solely transfer notifications
* will ignore this parameter.
* @return 0 if OK, or a negative error code.
*/
int mbox_send(struct mbox_chan *chan, const void *data);
/**
* mbox_recv - Receive any available message from a mailbox channel
*
* This function will wait (up to the specified @timeout_us) for a message to
* be sent by the remote entity, and write the content of any such message
* into a caller-provided buffer.
*
* @chan: A channel object that was previously successfully requested by
* calling mbox_get_by_*().
* @data: A pointer to the buffer to receive the message. The format and
* size of the memory region pointed at by @data is determined by
* the mailbox provider. Providers that solely transfer
* notifications will ignore this parameter.
* @timeout_us: The maximum time to wait for a message to be available, in
* micro-seconds. A value of 0 does not wait at all.
* @return 0 if OK, -ENODATA if no message was available, or a negative error
* code.
*/
int mbox_recv(struct mbox_chan *chan, void *data, ulong timeout_us);
#endif

83
include/mailbox_uclass.h Normal file
View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2016, NVIDIA CORPORATION.
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef _MAILBOX_UCLASS_H
#define _MAILBOX_UCLASS_H
/* See mailbox_client.h for background documentation. */
#include <mailbox_client.h>
struct udevice;
/**
* struct mbox_ops - The functions that a mailbox driver must implement.
*/
struct mbox_ops {
/**
* of_xlate - Translate a client's device-tree (OF) mailbox specifier.
*
* The mailbox core calls this function as the first step in
* implementing a client's mbox_get_by_*() call.
*
* If this function pointer is set to NULL, the mailbox core will use
* a default implementation, which assumes #mbox-cells = <1>, and that
* the DT cell contains a simple integer channel ID.
*
* At present, the mailbox API solely supports device-tree. If this
* changes, other xxx_xlate() functions may be added to support those
* other mechanisms.
*
* @chan: The channel to hold the translation result.
* @args: The mailbox specifier values from device tree.
* @return 0 if OK, or a negative error code.
*/
int (*of_xlate)(struct mbox_chan *chan,
struct fdtdec_phandle_args *args);
/**
* request - Request a translated channel.
*
* The mailbox core calls this function as the second step in
* implementing a client's mbox_get_by_*() call, following a successful
* xxx_xlate() call.
*
* @chan: The channel to request; this has been filled in by a
* previoux xxx_xlate() function call.
* @return 0 if OK, or a negative error code.
*/
int (*request)(struct mbox_chan *chan);
/**
* free - Free a previously requested channel.
*
* This is the implementation of the client mbox_free() API.
*
* @chan: The channel to free.
* @return 0 if OK, or a negative error code.
*/
int (*free)(struct mbox_chan *chan);
/**
* send - Send a message over a mailbox channel
*
* @chan: The channel to send to the message to.
* @data: A pointer to the message to send.
* @return 0 if OK, or a negative error code.
*/
int (*send)(struct mbox_chan *chan, const void *data);
/**
* recv - Receive any available message from the channel.
*
* This function does not block. If not message is immediately
* available, the function should return an error.
*
* @chan: The channel to receive to the message from.
* @data: A pointer to the buffer to hold the received message.
* @return 0 if OK, -ENODATA if no message was available, or a negative
* error code.
*/
int (*recv)(struct mbox_chan *chan, void *data);
};
#endif

View File

@ -411,7 +411,6 @@ enum mmc_hwpart_conf_mode {
MMC_HWPART_CONF_COMPLETE,
};
int mmc_register(struct mmc *mmc);
struct mmc *mmc_create(const struct mmc_config *cfg, void *priv);
/**
@ -492,16 +491,12 @@ int mmc_start_init(struct mmc *mmc);
*/
void mmc_set_preinit(struct mmc *mmc, int preinit);
#ifdef CONFIG_GENERIC_MMC
#ifdef CONFIG_MMC_SPI
#define mmc_host_is_spi(mmc) ((mmc)->cfg->host_caps & MMC_MODE_SPI)
#else
#define mmc_host_is_spi(mmc) 0
#endif
struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
#else
int mmc_legacy_init(int verbose);
#endif
void board_mmc_power_init(void);
int board_mmc_init(bd_t *bis);

View File

@ -1,71 +0,0 @@
/*
* Copyright (c) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __RESET_H
#define __RESET_H
enum reset_t {
RESET_WARM, /* Reset CPU, keep GPIOs active */
RESET_COLD, /* Reset CPU and GPIOs */
RESET_POWER, /* Reset PMIC (remove and restore power) */
RESET_COUNT,
};
struct reset_ops {
/**
* request() - request a reset of the given type
*
* Note that this function may return before the reset takes effect.
*
* @type: Reset type to request
* @return -EINPROGRESS if the reset has been started and
* will complete soon, -EPROTONOSUPPORT if not supported
* by this device, 0 if the reset has already happened
* (in which case this method will not actually return)
*/
int (*request)(struct udevice *dev, enum reset_t type);
};
#define reset_get_ops(dev) ((struct reset_ops *)(dev)->driver->ops)
/**
* reset_request() - request a reset
*
* @type: Reset type to request
* @return 0 if OK, -EPROTONOSUPPORT if not supported by this device
*/
int reset_request(struct udevice *dev, enum reset_t type);
/**
* reset_walk() - cause a reset
*
* This works through the available reset devices until it finds one that can
* perform a reset. If the provided reset type is not available, the next one
* will be tried.
*
* If this function fails to reset, it will display a message and halt
*
* @type: Reset type to request
* @return -EINPROGRESS if a reset is in progress, -ENOSYS if not available
*/
int reset_walk(enum reset_t type);
/**
* reset_walk_halt() - try to reset, otherwise halt
*
* This calls reset_walk(). If it returns, indicating that reset is not
* supported, it prints a message and halts.
*/
void reset_walk_halt(enum reset_t type);
/**
* reset_cpu() - calls reset_walk(RESET_WARM)
*/
void reset_cpu(ulong addr);
#endif

71
include/sysreset.h Normal file
View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __SYSRESET_H
#define __SYSRESET_H
enum sysreset_t {
SYSRESET_WARM, /* Reset CPU, keep GPIOs active */
SYSRESET_COLD, /* Reset CPU and GPIOs */
SYSRESET_POWER, /* Reset PMIC (remove and restore power) */
SYSRESET_COUNT,
};
struct sysreset_ops {
/**
* request() - request a sysreset of the given type
*
* Note that this function may return before the reset takes effect.
*
* @type: Reset type to request
* @return -EINPROGRESS if the reset has been started and
* will complete soon, -EPROTONOSUPPORT if not supported
* by this device, 0 if the reset has already happened
* (in which case this method will not actually return)
*/
int (*request)(struct udevice *dev, enum sysreset_t type);
};
#define sysreset_get_ops(dev) ((struct sysreset_ops *)(dev)->driver->ops)
/**
* sysreset_request() - request a sysreset
*
* @type: Reset type to request
* @return 0 if OK, -EPROTONOSUPPORT if not supported by this device
*/
int sysreset_request(struct udevice *dev, enum sysreset_t type);
/**
* sysreset_walk() - cause a system reset
*
* This works through the available sysreset devices until it finds one that can
* perform a reset. If the provided sysreset type is not available, the next one
* will be tried.
*
* If this function fails to reset, it will display a message and halt
*
* @type: Reset type to request
* @return -EINPROGRESS if a reset is in progress, -ENOSYS if not available
*/
int sysreset_walk(enum sysreset_t type);
/**
* sysreset_walk_halt() - try to reset, otherwise halt
*
* This calls sysreset_walk(). If it returns, indicating that reset is not
* supported, it prints a message and halts.
*/
void sysreset_walk_halt(enum sysreset_t type);
/**
* reset_cpu() - calls sysreset_walk(SYSRESET_WARM)
*/
void reset_cpu(ulong addr);
#endif

View File

@ -8,6 +8,7 @@
#include <common.h>
#include <blk.h>
#include <dm.h>
#include <efi_loader.h>
#include <inttypes.h>
#include <part.h>
@ -92,11 +93,10 @@ static efi_status_t EFIAPI efi_disk_rw_blocks(struct efi_block_io *this,
if (buffer_size & (blksz - 1))
return EFI_EXIT(EFI_DEVICE_ERROR);
if (direction == EFI_DISK_READ) {
n = desc->block_read(desc, lba, blocks, buffer);
} else {
n = desc->block_write(desc, lba, blocks, buffer);
}
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();
@ -194,8 +194,8 @@ static const struct efi_block_io block_io_disk_template = {
.flush_blocks = &efi_disk_flush_blocks,
};
static void efi_disk_add_dev(char *name,
const struct blk_driver *cur_drvr,
static void efi_disk_add_dev(const char *name,
const char *if_typename,
const struct blk_desc *desc,
int dev_index,
lbaint_t offset)
@ -213,7 +213,7 @@ static void efi_disk_add_dev(char *name,
diskobj->parent.protocols[1].open = efi_disk_open_dp;
diskobj->parent.handle = diskobj;
diskobj->ops = block_io_disk_template;
diskobj->ifname = cur_drvr->if_typename;
diskobj->ifname = if_typename;
diskobj->dev_index = dev_index;
diskobj->offset = offset;
@ -242,7 +242,7 @@ static void efi_disk_add_dev(char *name,
}
static int efi_disk_create_eltorito(struct blk_desc *desc,
const struct blk_driver *cur_drvr,
const char *if_typename,
int diskid)
{
int disks = 0;
@ -255,9 +255,10 @@ static int efi_disk_create_eltorito(struct blk_desc *desc,
return 0;
while (!part_get_info(desc, part, &info)) {
snprintf(devname, sizeof(devname), "%s%d:%d",
cur_drvr->if_typename, diskid, part);
efi_disk_add_dev(devname, cur_drvr, desc, diskid, info.start);
snprintf(devname, sizeof(devname), "%s%d:%d", if_typename,
diskid, part);
efi_disk_add_dev(devname, if_typename, desc, diskid,
info.start);
part++;
disks++;
}
@ -271,21 +272,49 @@ static int efi_disk_create_eltorito(struct blk_desc *desc,
* EFI payload, we scan through all of the potentially available ones and
* store them in our object pool.
*
* TODO(sjg@chromium.org): Actually with CONFIG_BLK, U-Boot does have this.
* Consider converting the code to look up devices as needed. The EFI device
* could be a child of the UCLASS_BLK block device, perhaps.
*
* This gets called from do_bootefi_exec().
*/
int efi_disk_register(void)
{
const struct blk_driver *cur_drvr;
int i, if_type;
int disks = 0;
#ifdef CONFIG_BLK
struct udevice *dev;
for (uclass_first_device(UCLASS_BLK, &dev);
dev;
uclass_next_device(&dev)) {
struct blk_desc *desc = dev_get_uclass_platdata(dev);
const char *if_typename = dev->driver->name;
printf("Scanning disk %s...\n", dev->name);
efi_disk_add_dev(dev->name, if_typename, desc, desc->devnum, 0);
disks++;
/*
* El Torito images show up as block devices in an EFI world,
* so let's create them here
*/
disks += efi_disk_create_eltorito(desc, if_typename,
desc->devnum);
}
#else
int i, if_type;
/* Search for all available disk devices */
for (if_type = 0; if_type < IF_TYPE_COUNT; if_type++) {
const struct blk_driver *cur_drvr;
const char *if_typename;
cur_drvr = blk_driver_lookup_type(if_type);
if (!cur_drvr)
continue;
printf("Scanning disks on %s...\n", cur_drvr->if_typename);
if_typename = cur_drvr->if_typename;
printf("Scanning disks on %s...\n", if_typename);
for (i = 0; i < 4; i++) {
struct blk_desc *desc;
char devname[32] = { 0 }; /* dp->str is u16[32] long */
@ -297,17 +326,18 @@ int efi_disk_register(void)
continue;
snprintf(devname, sizeof(devname), "%s%d",
cur_drvr->if_typename, i);
efi_disk_add_dev(devname, cur_drvr, desc, i, 0);
if_typename, i);
efi_disk_add_dev(devname, if_typename, desc, i, 0);
disks++;
/*
* El Torito images show up as block devices
* in an EFI world, so let's create them here
*/
disks += efi_disk_create_eltorito(desc, cur_drvr, i);
disks += efi_disk_create_eltorito(desc, if_typename, i);
}
}
#endif
printf("Found %d disks\n", disks);
return 0;

View File

@ -16,6 +16,9 @@
static char *bf;
static char zs;
/* Current position in sprintf() output string */
static char *outstr;
static void out(char c)
{
*bf++ = c;
@ -40,7 +43,7 @@ static void div_out(unsigned int *num, unsigned int div)
out_dgt(dgt);
}
int vprintf(const char *fmt, va_list va)
int _vprintf(const char *fmt, va_list va, void (*putc)(const char ch))
{
char ch;
char *p;
@ -52,8 +55,8 @@ int vprintf(const char *fmt, va_list va)
if (ch != '%') {
putc(ch);
} else {
char lz = 0;
char w = 0;
bool lz = false;
int width = 0;
ch = *(fmt++);
if (ch == '0') {
@ -62,9 +65,9 @@ int vprintf(const char *fmt, va_list va)
}
if (ch >= '0' && ch <= '9') {
w = 0;
width = 0;
while (ch >= '0' && ch <= '9') {
w = (w * 10) + ch - '0';
width = (width * 10) + ch - '0';
ch = *fmt++;
}
}
@ -73,7 +76,7 @@ int vprintf(const char *fmt, va_list va)
zs = 0;
switch (ch) {
case 0:
case '\0':
goto abort;
case 'u':
case 'd':
@ -112,9 +115,9 @@ int vprintf(const char *fmt, va_list va)
*bf = 0;
bf = p;
while (*bf++ && w > 0)
w--;
while (w-- > 0)
while (*bf++ && width > 0)
width--;
while (width-- > 0)
putc(lz ? '0' : ' ');
if (p) {
while ((ch = *p++))
@ -133,8 +136,28 @@ int printf(const char *fmt, ...)
int ret;
va_start(va, fmt);
ret = vprintf(fmt, va);
ret = _vprintf(fmt, va, putc);
va_end(va);
return ret;
}
static void putc_outstr(char ch)
{
*outstr++ = ch;
}
/* Note that size is ignored */
int snprintf(char *buf, size_t size, const char *fmt, ...)
{
va_list va;
int ret;
va_start(va, fmt);
outstr = buf;
ret = _vprintf(fmt, va, putc_outstr);
va_end(va);
*outstr = '\0';
return ret;
}

View File

@ -21,12 +21,13 @@ obj-$(CONFIG_DM_ETH) += eth.o
obj-$(CONFIG_DM_GPIO) += gpio.o
obj-$(CONFIG_DM_I2C) += i2c.o
obj-$(CONFIG_LED) += led.o
obj-$(CONFIG_DM_MAILBOX) += mailbox.o
obj-$(CONFIG_DM_MMC) += mmc.o
obj-$(CONFIG_DM_PCI) += pci.o
obj-$(CONFIG_RAM) += ram.o
obj-y += regmap.o
obj-$(CONFIG_REMOTEPROC) += remoteproc.o
obj-$(CONFIG_RESET) += reset.o
obj-$(CONFIG_SYSRESET) += sysreset.o
obj-$(CONFIG_DM_RTC) += rtc.o
obj-$(CONFIG_DM_SPI_FLASH) += sf.o
obj-$(CONFIG_DM_SPI) += spi.o

31
test/dm/mailbox.c Normal file
View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2016, NVIDIA CORPORATION.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <dm.h>
#include <dm/test.h>
#include <asm/mbox.h>
#include <test/ut.h>
static int dm_test_mailbox(struct unit_test_state *uts)
{
struct udevice *dev;
uint32_t msg;
ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "mbox-test", &dev));
ut_assertok(sandbox_mbox_test_get(dev));
ut_asserteq(-ETIMEDOUT, sandbox_mbox_test_recv(dev, &msg));
ut_assertok(sandbox_mbox_test_send(dev, 0xaaff9955UL));
ut_assertok(sandbox_mbox_test_recv(dev, &msg));
ut_asserteq(msg, 0xaaff9955UL ^ SANDBOX_MBOX_PING_XOR);
ut_asserteq(-ETIMEDOUT, sandbox_mbox_test_recv(dev, &msg));
ut_assertok(sandbox_mbox_test_free(dev));
return 0;
}
DM_TEST(dm_test_mailbox, DM_TESTF_SCAN_FDT);

View File

@ -1,74 +0,0 @@
/*
* Copyright (C) 2015 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <reset.h>
#include <asm/state.h>
#include <asm/test.h>
#include <dm/test.h>
#include <test/ut.h>
/* Test that we can use particular reset devices */
static int dm_test_reset_base(struct unit_test_state *uts)
{
struct sandbox_state *state = state_get_current();
struct udevice *dev;
/* Device 0 is the platform data device - it should never respond */
ut_assertok(uclass_get_device(UCLASS_RESET, 0, &dev));
ut_asserteq(-ENODEV, reset_request(dev, RESET_WARM));
ut_asserteq(-ENODEV, reset_request(dev, RESET_COLD));
ut_asserteq(-ENODEV, reset_request(dev, RESET_POWER));
/* Device 1 is the warm reset device */
ut_assertok(uclass_get_device(UCLASS_RESET, 1, &dev));
ut_asserteq(-EACCES, reset_request(dev, RESET_WARM));
ut_asserteq(-ENOSYS, reset_request(dev, RESET_COLD));
ut_asserteq(-ENOSYS, reset_request(dev, RESET_POWER));
state->reset_allowed[RESET_WARM] = true;
ut_asserteq(-EINPROGRESS, reset_request(dev, RESET_WARM));
state->reset_allowed[RESET_WARM] = false;
/* Device 2 is the cold reset device */
ut_assertok(uclass_get_device(UCLASS_RESET, 2, &dev));
ut_asserteq(-ENOSYS, reset_request(dev, RESET_WARM));
ut_asserteq(-EACCES, reset_request(dev, RESET_COLD));
state->reset_allowed[RESET_POWER] = false;
ut_asserteq(-EACCES, reset_request(dev, RESET_POWER));
state->reset_allowed[RESET_POWER] = true;
return 0;
}
DM_TEST(dm_test_reset_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
/* Test that we can walk through the reset devices */
static int dm_test_reset_walk(struct unit_test_state *uts)
{
struct sandbox_state *state = state_get_current();
/* If we generate a power reset, we will exit sandbox! */
state->reset_allowed[RESET_POWER] = false;
ut_asserteq(-EACCES, reset_walk(RESET_WARM));
ut_asserteq(-EACCES, reset_walk(RESET_COLD));
ut_asserteq(-EACCES, reset_walk(RESET_POWER));
/*
* Enable cold reset - this should make cold reset work, plus a warm
* reset should be promoted to cold, since this is the next step
* along.
*/
state->reset_allowed[RESET_COLD] = true;
ut_asserteq(-EINPROGRESS, reset_walk(RESET_WARM));
ut_asserteq(-EINPROGRESS, reset_walk(RESET_COLD));
ut_asserteq(-EACCES, reset_walk(RESET_POWER));
state->reset_allowed[RESET_COLD] = false;
state->reset_allowed[RESET_POWER] = true;
return 0;
}
DM_TEST(dm_test_reset_walk, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

74
test/dm/sysreset.c Normal file
View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2015 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <sysreset.h>
#include <asm/state.h>
#include <asm/test.h>
#include <dm/test.h>
#include <test/ut.h>
/* Test that we can use particular sysreset devices */
static int dm_test_sysreset_base(struct unit_test_state *uts)
{
struct sandbox_state *state = state_get_current();
struct udevice *dev;
/* Device 0 is the platform data device - it should never respond */
ut_assertok(uclass_get_device(UCLASS_SYSRESET, 0, &dev));
ut_asserteq(-ENODEV, sysreset_request(dev, SYSRESET_WARM));
ut_asserteq(-ENODEV, sysreset_request(dev, SYSRESET_COLD));
ut_asserteq(-ENODEV, sysreset_request(dev, SYSRESET_POWER));
/* Device 1 is the warm sysreset device */
ut_assertok(uclass_get_device(UCLASS_SYSRESET, 1, &dev));
ut_asserteq(-EACCES, sysreset_request(dev, SYSRESET_WARM));
ut_asserteq(-ENOSYS, sysreset_request(dev, SYSRESET_COLD));
ut_asserteq(-ENOSYS, sysreset_request(dev, SYSRESET_POWER));
state->sysreset_allowed[SYSRESET_WARM] = true;
ut_asserteq(-EINPROGRESS, sysreset_request(dev, SYSRESET_WARM));
state->sysreset_allowed[SYSRESET_WARM] = false;
/* Device 2 is the cold sysreset device */
ut_assertok(uclass_get_device(UCLASS_SYSRESET, 2, &dev));
ut_asserteq(-ENOSYS, sysreset_request(dev, SYSRESET_WARM));
ut_asserteq(-EACCES, sysreset_request(dev, SYSRESET_COLD));
state->sysreset_allowed[SYSRESET_POWER] = false;
ut_asserteq(-EACCES, sysreset_request(dev, SYSRESET_POWER));
state->sysreset_allowed[SYSRESET_POWER] = true;
return 0;
}
DM_TEST(dm_test_sysreset_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
/* Test that we can walk through the sysreset devices */
static int dm_test_sysreset_walk(struct unit_test_state *uts)
{
struct sandbox_state *state = state_get_current();
/* If we generate a power sysreset, we will exit sandbox! */
state->sysreset_allowed[SYSRESET_POWER] = false;
ut_asserteq(-EACCES, sysreset_walk(SYSRESET_WARM));
ut_asserteq(-EACCES, sysreset_walk(SYSRESET_COLD));
ut_asserteq(-EACCES, sysreset_walk(SYSRESET_POWER));
/*
* Enable cold system reset - this should make cold system reset work,
* plus a warm system reset should be promoted to cold, since this is
* the next step along.
*/
state->sysreset_allowed[SYSRESET_COLD] = true;
ut_asserteq(-EINPROGRESS, sysreset_walk(SYSRESET_WARM));
ut_asserteq(-EINPROGRESS, sysreset_walk(SYSRESET_COLD));
ut_asserteq(-EACCES, sysreset_walk(SYSRESET_POWER));
state->sysreset_allowed[SYSRESET_COLD] = false;
state->sysreset_allowed[SYSRESET_POWER] = true;
return 0;
}
DM_TEST(dm_test_sysreset_walk, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

View File

@ -13,11 +13,6 @@
static uint32_t header;
static int rkimage_check_params(struct image_tool_params *params)
{
return 0;
}
static int rkimage_verify_header(unsigned char *buf, int size,
struct image_tool_params *params)
{
@ -56,7 +51,7 @@ U_BOOT_IMAGE_TYPE(
"Rockchip Boot Image support",
4,
&header,
rkimage_check_params,
rkcommon_check_params,
rkimage_verify_header,
rkimage_print_header,
rkimage_set_header,