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:
commit
e4a94ce4ac
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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:
|
||||
|
@ -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";
|
||||
};
|
||||
|
21
arch/sandbox/include/asm/mbox.h
Normal file
21
arch/sandbox/include/asm/mbox.h
Normal 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
|
@ -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 */
|
||||
|
62
cmd/mmc.c
62
cmd/mmc.c
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
32
doc/device-tree-bindings/mailbox/mailbox.txt
Normal file
32
doc/device-tree-bindings/mailbox/mailbox.txt
Normal 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>;
|
||||
};
|
@ -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
|
||||
|
@ -30,6 +30,8 @@ source "drivers/input/Kconfig"
|
||||
|
||||
source "drivers/led/Kconfig"
|
||||
|
||||
source "drivers/mailbox/Kconfig"
|
||||
|
||||
source "drivers/memory/Kconfig"
|
||||
|
||||
source "drivers/misc/Kconfig"
|
||||
|
@ -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/
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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
20
drivers/mailbox/Kconfig
Normal 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
7
drivers/mailbox/Makefile
Normal 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
|
145
drivers/mailbox/mailbox-uclass.c
Normal file
145
drivers/mailbox/mailbox-uclass.c
Normal 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",
|
||||
};
|
54
drivers/mailbox/sandbox-mbox-test.c
Normal file
54
drivers/mailbox/sandbox-mbox-test.c
Normal 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),
|
||||
};
|
104
drivers/mailbox/sandbox-mbox.c
Normal file
104
drivers/mailbox/sandbox-mbox.c
Normal 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,
|
||||
};
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
};
|
@ -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",
|
||||
};
|
101
drivers/misc/sysreset_sandbox.c
Normal file
101
drivers/misc/sysreset_sandbox.c
Normal 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",
|
||||
};
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -326,6 +326,7 @@ static int rk_vop_probe(struct udevice *dev)
|
||||
if (!ret)
|
||||
break;
|
||||
}
|
||||
video_set_flush_dcache(dev, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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
149
include/mailbox_client.h
Normal 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
83
include/mailbox_uclass.h
Normal 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
|
@ -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);
|
||||
|
@ -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
71
include/sysreset.h
Normal 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
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
31
test/dm/mailbox.c
Normal 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);
|
@ -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
74
test/dm/sysreset.c
Normal 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);
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user