1*769d52efSStephen Warren /* 2*769d52efSStephen Warren * Copyright (c) 2016, NVIDIA CORPORATION. 3*769d52efSStephen Warren * 4*769d52efSStephen Warren * SPDX-License-Identifier: GPL-2.0 5*769d52efSStephen Warren */ 6*769d52efSStephen Warren 7*769d52efSStephen Warren #ifndef _MAILBOX_H 8*769d52efSStephen Warren #define _MAILBOX_H 9*769d52efSStephen Warren 10*769d52efSStephen Warren /** 11*769d52efSStephen Warren * A mailbox is a hardware mechanism for transferring small fixed-size messages 12*769d52efSStephen Warren * and/or notifications between the CPU on which U-Boot runs and some other 13*769d52efSStephen Warren * device such as an auxiliary CPU running firmware or a hardware module. 14*769d52efSStephen Warren * 15*769d52efSStephen Warren * Data transfer is optional; a mailbox may consist solely of a notification 16*769d52efSStephen Warren * mechanism. When data transfer is implemented, it is via HW registers or 17*769d52efSStephen Warren * FIFOs, rather than via RAM-based buffers. The mailbox API generally 18*769d52efSStephen Warren * implements any communication protocol enforced solely by hardware, and 19*769d52efSStephen Warren * leaves any higher-level protocols to other layers. 20*769d52efSStephen Warren * 21*769d52efSStephen Warren * A mailbox channel is a bi-directional mechanism that can send a message or 22*769d52efSStephen Warren * notification to a single specific remote entity, and receive messages or 23*769d52efSStephen Warren * notifications from that entity. The size, content, and format of such 24*769d52efSStephen Warren * messages is defined by the mailbox implementation, or the remote entity with 25*769d52efSStephen Warren * which it communicates; there is no general standard at this API level. 26*769d52efSStephen Warren * 27*769d52efSStephen Warren * A driver that implements UCLASS_MAILBOX is a mailbox provider. A provider 28*769d52efSStephen Warren * will often implement multiple separate mailbox channels, since the hardware 29*769d52efSStephen Warren * it manages often has this capability. mailbox-uclass.h describes the 30*769d52efSStephen Warren * interface which mailbox providers must implement. 31*769d52efSStephen Warren * 32*769d52efSStephen Warren * Mailbox consumers/clients generate and send, or receive and process, 33*769d52efSStephen Warren * messages. This header file describes the API used by clients. 34*769d52efSStephen Warren */ 35*769d52efSStephen Warren 36*769d52efSStephen Warren struct udevice; 37*769d52efSStephen Warren 38*769d52efSStephen Warren /** 39*769d52efSStephen Warren * struct mbox_chan - A handle to a single mailbox channel. 40*769d52efSStephen Warren * 41*769d52efSStephen Warren * Clients provide storage for channels. The content of the channel structure 42*769d52efSStephen Warren * is managed solely by the mailbox API and mailbox drivers. A mailbox channel 43*769d52efSStephen Warren * is initialized by "get"ing the mailbox. The channel struct is passed to all 44*769d52efSStephen Warren * other mailbox APIs to identify which mailbox to operate upon. 45*769d52efSStephen Warren * 46*769d52efSStephen Warren * @dev: The device which implements the mailbox. 47*769d52efSStephen Warren * @id: The mailbox channel ID within the provider. 48*769d52efSStephen Warren * 49*769d52efSStephen Warren * Currently, the mailbox API assumes that a single integer ID is enough to 50*769d52efSStephen Warren * identify and configure any mailbox channel for any mailbox provider. If this 51*769d52efSStephen Warren * assumption becomes invalid in the future, the struct could be expanded to 52*769d52efSStephen Warren * either (a) add more fields to allow mailbox providers to store additional 53*769d52efSStephen Warren * information, or (b) replace the id field with an opaque pointer, which the 54*769d52efSStephen Warren * provider would dynamically allocated during its .of_xlate op, and process 55*769d52efSStephen Warren * during is .request op. This may require the addition of an extra op to clean 56*769d52efSStephen Warren * up the allocation. 57*769d52efSStephen Warren */ 58*769d52efSStephen Warren struct mbox_chan { 59*769d52efSStephen Warren struct udevice *dev; 60*769d52efSStephen Warren /* 61*769d52efSStephen Warren * Written by of_xlate. We assume a single id is enough for now. In the 62*769d52efSStephen Warren * future, we might add more fields here. 63*769d52efSStephen Warren */ 64*769d52efSStephen Warren unsigned long id; 65*769d52efSStephen Warren }; 66*769d52efSStephen Warren 67*769d52efSStephen Warren /** 68*769d52efSStephen Warren * mbox_get_by_index - Get/request a mailbox by integer index 69*769d52efSStephen Warren * 70*769d52efSStephen Warren * This looks up and requests a mailbox channel. The index is relative to the 71*769d52efSStephen Warren * client device; each device is assumed to have n mailbox channels associated 72*769d52efSStephen Warren * with it somehow, and this function finds and requests one of them. The 73*769d52efSStephen Warren * mapping of client device channel indices to provider channels may be via 74*769d52efSStephen Warren * device-tree properties, board-provided mapping tables, or some other 75*769d52efSStephen Warren * mechanism. 76*769d52efSStephen Warren * 77*769d52efSStephen Warren * @dev: The client device. 78*769d52efSStephen Warren * @index: The index of the mailbox channel to request, within the 79*769d52efSStephen Warren * client's list of channels. 80*769d52efSStephen Warren * @chan A pointer to a channel object to initialize. 81*769d52efSStephen Warren * @return 0 if OK, or a negative error code. 82*769d52efSStephen Warren */ 83*769d52efSStephen Warren int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan); 84*769d52efSStephen Warren 85*769d52efSStephen Warren /** 86*769d52efSStephen Warren * mbox_get_by_name - Get/request a mailbox by name 87*769d52efSStephen Warren * 88*769d52efSStephen Warren * This looks up and requests a mailbox channel. The name is relative to the 89*769d52efSStephen Warren * client device; each device is assumed to have n mailbox channels associated 90*769d52efSStephen Warren * with it somehow, and this function finds and requests one of them. The 91*769d52efSStephen Warren * mapping of client device channel names to provider channels may be via 92*769d52efSStephen Warren * device-tree properties, board-provided mapping tables, or some other 93*769d52efSStephen Warren * mechanism. 94*769d52efSStephen Warren * 95*769d52efSStephen Warren * @dev: The client device. 96*769d52efSStephen Warren * @name: The name of the mailbox channel to request, within the client's 97*769d52efSStephen Warren * list of channels. 98*769d52efSStephen Warren * @chan A pointer to a channel object to initialize. 99*769d52efSStephen Warren * @return 0 if OK, or a negative error code. 100*769d52efSStephen Warren */ 101*769d52efSStephen Warren int mbox_get_by_name(struct udevice *dev, const char *name, 102*769d52efSStephen Warren struct mbox_chan *chan); 103*769d52efSStephen Warren 104*769d52efSStephen Warren /** 105*769d52efSStephen Warren * mbox_free - Free a previously requested mailbox channel. 106*769d52efSStephen Warren * 107*769d52efSStephen Warren * @chan: A channel object that was previously successfully requested by 108*769d52efSStephen Warren * calling mbox_get_by_*(). 109*769d52efSStephen Warren * @return 0 if OK, or a negative error code. 110*769d52efSStephen Warren */ 111*769d52efSStephen Warren int mbox_free(struct mbox_chan *chan); 112*769d52efSStephen Warren 113*769d52efSStephen Warren /** 114*769d52efSStephen Warren * mbox_send - Send a message over a mailbox channel 115*769d52efSStephen Warren * 116*769d52efSStephen Warren * This function will send a message to the remote entity. It may return before 117*769d52efSStephen Warren * the remote entity has received and/or processed the message. 118*769d52efSStephen Warren * 119*769d52efSStephen Warren * @chan: A channel object that was previously successfully requested by 120*769d52efSStephen Warren * calling mbox_get_by_*(). 121*769d52efSStephen Warren * @data: A pointer to the message to transfer. The format and size of 122*769d52efSStephen Warren * the memory region pointed at by @data is determined by the 123*769d52efSStephen Warren * mailbox provider. Providers that solely transfer notifications 124*769d52efSStephen Warren * will ignore this parameter. 125*769d52efSStephen Warren * @return 0 if OK, or a negative error code. 126*769d52efSStephen Warren */ 127*769d52efSStephen Warren int mbox_send(struct mbox_chan *chan, const void *data); 128*769d52efSStephen Warren 129*769d52efSStephen Warren /** 130*769d52efSStephen Warren * mbox_recv - Receive any available message from a mailbox channel 131*769d52efSStephen Warren * 132*769d52efSStephen Warren * This function will wait (up to the specified @timeout_us) for a message to 133*769d52efSStephen Warren * be sent by the remote entity, and write the content of any such message 134*769d52efSStephen Warren * into a caller-provided buffer. 135*769d52efSStephen Warren * 136*769d52efSStephen Warren * @chan: A channel object that was previously successfully requested by 137*769d52efSStephen Warren * calling mbox_get_by_*(). 138*769d52efSStephen Warren * @data: A pointer to the buffer to receive the message. The format and 139*769d52efSStephen Warren * size of the memory region pointed at by @data is determined by 140*769d52efSStephen Warren * the mailbox provider. Providers that solely transfer 141*769d52efSStephen Warren * notifications will ignore this parameter. 142*769d52efSStephen Warren * @timeout_us: The maximum time to wait for a message to be available, in 143*769d52efSStephen Warren * micro-seconds. A value of 0 does not wait at all. 144*769d52efSStephen Warren * @return 0 if OK, -ENODATA if no message was available, or a negative error 145*769d52efSStephen Warren * code. 146*769d52efSStephen Warren */ 147*769d52efSStephen Warren int mbox_recv(struct mbox_chan *chan, void *data, ulong timeout_us); 148*769d52efSStephen Warren 149*769d52efSStephen Warren #endif 150