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