diff options
author | Tom Rini <trini@konsulko.com> | 2016-05-27 15:49:43 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-05-27 20:34:12 -0400 |
commit | e4a94ce4ac77396b181663c0493c50bc2d5b9143 (patch) | |
tree | 7564e2d5e7e24841a763460f7eaf91409abd0312 /drivers/mailbox | |
parent | 378f9134eba4665ea94a63653393d25418665fda (diff) | |
parent | 3c27b6ad540828c44a62d209030df5ba86896df0 (diff) | |
download | u-boot-imx-e4a94ce4ac77396b181663c0493c50bc2d5b9143.zip u-boot-imx-e4a94ce4ac77396b181663c0493c50bc2d5b9143.tar.gz u-boot-imx-e4a94ce4ac77396b181663c0493c50bc2d5b9143.tar.bz2 |
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
Diffstat (limited to 'drivers/mailbox')
-rw-r--r-- | drivers/mailbox/Kconfig | 20 | ||||
-rw-r--r-- | drivers/mailbox/Makefile | 7 | ||||
-rw-r--r-- | drivers/mailbox/mailbox-uclass.c | 145 | ||||
-rw-r--r-- | drivers/mailbox/sandbox-mbox-test.c | 54 | ||||
-rw-r--r-- | drivers/mailbox/sandbox-mbox.c | 104 |
5 files changed, 330 insertions, 0 deletions
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig new file mode 100644 index 0000000..9087512 --- /dev/null +++ b/drivers/mailbox/Kconfig @@ -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 diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile new file mode 100644 index 0000000..bbae4de --- /dev/null +++ b/drivers/mailbox/Makefile @@ -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 diff --git a/drivers/mailbox/mailbox-uclass.c b/drivers/mailbox/mailbox-uclass.c new file mode 100644 index 0000000..73fa328 --- /dev/null +++ b/drivers/mailbox/mailbox-uclass.c @@ -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", +}; diff --git a/drivers/mailbox/sandbox-mbox-test.c b/drivers/mailbox/sandbox-mbox-test.c new file mode 100644 index 0000000..02d161a --- /dev/null +++ b/drivers/mailbox/sandbox-mbox-test.c @@ -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), +}; diff --git a/drivers/mailbox/sandbox-mbox.c b/drivers/mailbox/sandbox-mbox.c new file mode 100644 index 0000000..1b7ac23 --- /dev/null +++ b/drivers/mailbox/sandbox-mbox.c @@ -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, +}; |