18961b524SStephen Warren /*
28961b524SStephen Warren * Copyright (c) 2016, NVIDIA CORPORATION.
38961b524SStephen Warren *
48961b524SStephen Warren * SPDX-License-Identifier: GPL-2.0
58961b524SStephen Warren */
68961b524SStephen Warren
78961b524SStephen Warren #include <common.h>
88961b524SStephen Warren #include <dm.h>
9*769d52efSStephen Warren #include <mailbox-uclass.h>
108961b524SStephen Warren #include <asm/io.h>
118961b524SStephen Warren #include <asm/mbox.h>
128961b524SStephen Warren
138961b524SStephen Warren #define SANDBOX_MBOX_CHANNELS 2
148961b524SStephen Warren
158961b524SStephen Warren struct sandbox_mbox_chan {
168961b524SStephen Warren bool rx_msg_valid;
178961b524SStephen Warren uint32_t rx_msg;
188961b524SStephen Warren };
198961b524SStephen Warren
208961b524SStephen Warren struct sandbox_mbox {
218961b524SStephen Warren struct sandbox_mbox_chan chans[SANDBOX_MBOX_CHANNELS];
228961b524SStephen Warren };
238961b524SStephen Warren
sandbox_mbox_request(struct mbox_chan * chan)248961b524SStephen Warren static int sandbox_mbox_request(struct mbox_chan *chan)
258961b524SStephen Warren {
268961b524SStephen Warren debug("%s(chan=%p)\n", __func__, chan);
278961b524SStephen Warren
288961b524SStephen Warren if (chan->id >= SANDBOX_MBOX_CHANNELS)
298961b524SStephen Warren return -EINVAL;
308961b524SStephen Warren
318961b524SStephen Warren return 0;
328961b524SStephen Warren }
338961b524SStephen Warren
sandbox_mbox_free(struct mbox_chan * chan)348961b524SStephen Warren static int sandbox_mbox_free(struct mbox_chan *chan)
358961b524SStephen Warren {
368961b524SStephen Warren debug("%s(chan=%p)\n", __func__, chan);
378961b524SStephen Warren
388961b524SStephen Warren return 0;
398961b524SStephen Warren }
408961b524SStephen Warren
sandbox_mbox_send(struct mbox_chan * chan,const void * data)418961b524SStephen Warren static int sandbox_mbox_send(struct mbox_chan *chan, const void *data)
428961b524SStephen Warren {
438961b524SStephen Warren struct sandbox_mbox *sbm = dev_get_priv(chan->dev);
448961b524SStephen Warren const uint32_t *pmsg = data;
458961b524SStephen Warren
468961b524SStephen Warren debug("%s(chan=%p, data=%p)\n", __func__, chan, data);
478961b524SStephen Warren
488961b524SStephen Warren sbm->chans[chan->id].rx_msg = *pmsg ^ SANDBOX_MBOX_PING_XOR;
498961b524SStephen Warren sbm->chans[chan->id].rx_msg_valid = true;
508961b524SStephen Warren
518961b524SStephen Warren return 0;
528961b524SStephen Warren }
538961b524SStephen Warren
sandbox_mbox_recv(struct mbox_chan * chan,void * data)548961b524SStephen Warren static int sandbox_mbox_recv(struct mbox_chan *chan, void *data)
558961b524SStephen Warren {
568961b524SStephen Warren struct sandbox_mbox *sbm = dev_get_priv(chan->dev);
578961b524SStephen Warren uint32_t *pmsg = data;
588961b524SStephen Warren
598961b524SStephen Warren debug("%s(chan=%p, data=%p)\n", __func__, chan, data);
608961b524SStephen Warren
618961b524SStephen Warren if (!sbm->chans[chan->id].rx_msg_valid)
628961b524SStephen Warren return -ENODATA;
638961b524SStephen Warren
648961b524SStephen Warren *pmsg = sbm->chans[chan->id].rx_msg;
658961b524SStephen Warren sbm->chans[chan->id].rx_msg_valid = false;
668961b524SStephen Warren
678961b524SStephen Warren return 0;
688961b524SStephen Warren }
698961b524SStephen Warren
sandbox_mbox_bind(struct udevice * dev)708961b524SStephen Warren static int sandbox_mbox_bind(struct udevice *dev)
718961b524SStephen Warren {
728961b524SStephen Warren debug("%s(dev=%p)\n", __func__, dev);
738961b524SStephen Warren
748961b524SStephen Warren return 0;
758961b524SStephen Warren }
768961b524SStephen Warren
sandbox_mbox_probe(struct udevice * dev)778961b524SStephen Warren static int sandbox_mbox_probe(struct udevice *dev)
788961b524SStephen Warren {
798961b524SStephen Warren debug("%s(dev=%p)\n", __func__, dev);
808961b524SStephen Warren
818961b524SStephen Warren return 0;
828961b524SStephen Warren }
838961b524SStephen Warren
848961b524SStephen Warren static const struct udevice_id sandbox_mbox_ids[] = {
858961b524SStephen Warren { .compatible = "sandbox,mbox" },
868961b524SStephen Warren { }
878961b524SStephen Warren };
888961b524SStephen Warren
898961b524SStephen Warren struct mbox_ops sandbox_mbox_mbox_ops = {
908961b524SStephen Warren .request = sandbox_mbox_request,
918961b524SStephen Warren .free = sandbox_mbox_free,
928961b524SStephen Warren .send = sandbox_mbox_send,
938961b524SStephen Warren .recv = sandbox_mbox_recv,
948961b524SStephen Warren };
958961b524SStephen Warren
968961b524SStephen Warren U_BOOT_DRIVER(sandbox_mbox) = {
978961b524SStephen Warren .name = "sandbox_mbox",
988961b524SStephen Warren .id = UCLASS_MAILBOX,
998961b524SStephen Warren .of_match = sandbox_mbox_ids,
1008961b524SStephen Warren .bind = sandbox_mbox_bind,
1018961b524SStephen Warren .probe = sandbox_mbox_probe,
1028961b524SStephen Warren .priv_auto_alloc_size = sizeof(struct sandbox_mbox),
1038961b524SStephen Warren .ops = &sandbox_mbox_mbox_ops,
1048961b524SStephen Warren };
105