xref: /illumos-gate/usr/src/uts/common/sys/dcopy.h (revision eca2601c)
18e50dcc9Sbrutus /*
28e50dcc9Sbrutus  * CDDL HEADER START
38e50dcc9Sbrutus  *
48e50dcc9Sbrutus  * The contents of this file are subject to the terms of the
58e50dcc9Sbrutus  * Common Development and Distribution License (the "License").
68e50dcc9Sbrutus  * You may not use this file except in compliance with the License.
78e50dcc9Sbrutus  *
88e50dcc9Sbrutus  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98e50dcc9Sbrutus  * or http://www.opensolaris.org/os/licensing.
108e50dcc9Sbrutus  * See the License for the specific language governing permissions
118e50dcc9Sbrutus  * and limitations under the License.
128e50dcc9Sbrutus  *
138e50dcc9Sbrutus  * When distributing Covered Code, include this CDDL HEADER in each
148e50dcc9Sbrutus  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158e50dcc9Sbrutus  * If applicable, add the following below this CDDL HEADER, with the
168e50dcc9Sbrutus  * fields enclosed by brackets "[]" replaced with your own identifying
178e50dcc9Sbrutus  * information: Portions Copyright [yyyy] [name of copyright owner]
188e50dcc9Sbrutus  *
198e50dcc9Sbrutus  * CDDL HEADER END
208e50dcc9Sbrutus  */
218e50dcc9Sbrutus 
228e50dcc9Sbrutus /*
23*eca2601cSRandy Fishel  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
248e50dcc9Sbrutus  * Use is subject to license terms.
258e50dcc9Sbrutus  */
268e50dcc9Sbrutus 
278e50dcc9Sbrutus #ifndef _SYS_DCOPY_H
288e50dcc9Sbrutus #define	_SYS_DCOPY_H
298e50dcc9Sbrutus 
308e50dcc9Sbrutus #ifdef __cplusplus
318e50dcc9Sbrutus extern "C" {
328e50dcc9Sbrutus #endif
338e50dcc9Sbrutus 
348e50dcc9Sbrutus #include <sys/types.h>
358e50dcc9Sbrutus 
368e50dcc9Sbrutus /*
378e50dcc9Sbrutus  * *** This interface is for private use by the IP stack only ***
388e50dcc9Sbrutus  */
398e50dcc9Sbrutus 
4017169044Sbrutus /* Private dcopy/uioa interface for dcopy to enable/disable dcopy KAPI */
4117169044Sbrutus extern void uioa_dcopy_enable();
4217169044Sbrutus extern void uioa_dcopy_disable();
4317169044Sbrutus 
448e50dcc9Sbrutus /* Function return status */
458e50dcc9Sbrutus #define	DCOPY_FAILURE		(-1)
468e50dcc9Sbrutus #define	DCOPY_SUCCESS		(0)
478e50dcc9Sbrutus #define	DCOPY_NORESOURCES	(1) /* _alloc & _cmd_alloc, _cmd_post only */
488e50dcc9Sbrutus #define	DCOPY_PENDING		(0x10) /* dcopy_poll(), dcopy_unregister() */
498e50dcc9Sbrutus #define	DCOPY_COMPLETED		(0x20) /* dcopy_poll() only */
508e50dcc9Sbrutus 
518e50dcc9Sbrutus 
528e50dcc9Sbrutus /* dq_version */
538e50dcc9Sbrutus #define	DCOPY_QUERY_V0	0
548e50dcc9Sbrutus 
558e50dcc9Sbrutus typedef struct dcopy_query_s {
568e50dcc9Sbrutus 	int		dq_version; /* DCOPY_QUERY_V0 */
578e50dcc9Sbrutus 	uint_t		dq_num_channels; /* number of dma channels */
588e50dcc9Sbrutus } dcopy_query_t;
598e50dcc9Sbrutus 
608e50dcc9Sbrutus /*
618e50dcc9Sbrutus  * dcopy_query()
628e50dcc9Sbrutus  *   query for the number of DMA engines usable in the system.
638e50dcc9Sbrutus  */
648e50dcc9Sbrutus void dcopy_query(dcopy_query_t *query);
658e50dcc9Sbrutus 
668e50dcc9Sbrutus 
678e50dcc9Sbrutus typedef struct dcopy_channel_s *dcopy_handle_t;
688e50dcc9Sbrutus 
698e50dcc9Sbrutus /* dcopy_alloc() and dcopy_cmd_alloc() common flags */
708e50dcc9Sbrutus #define	DCOPY_SLEEP	(0)
718e50dcc9Sbrutus #define	DCOPY_NOSLEEP	(1 << 0)
728e50dcc9Sbrutus 
738e50dcc9Sbrutus /*
748e50dcc9Sbrutus  * dcopy_alloc()
758e50dcc9Sbrutus  *   Allocate a DMA channel which is used for posting DMA requests. Note: this
768e50dcc9Sbrutus  *   does not give the caller exclusive access to the DMA engine. Commands
778e50dcc9Sbrutus  *   posted to a channel will complete in order.
788e50dcc9Sbrutus  *     flags - (DCOPY_SLEEP, DCOPY_NOSLEEP)
798e50dcc9Sbrutus  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
808e50dcc9Sbrutus  */
818e50dcc9Sbrutus int dcopy_alloc(int flags, dcopy_handle_t *handle);
828e50dcc9Sbrutus 
838e50dcc9Sbrutus /*
848e50dcc9Sbrutus  * dcopy_free()
858e50dcc9Sbrutus  *   Free the DMA channel. The client can no longer use the handle to post or
868e50dcc9Sbrutus  *   poll for status on posts which were previously done on this channel.
878e50dcc9Sbrutus  */
888e50dcc9Sbrutus void dcopy_free(dcopy_handle_t *handle);
898e50dcc9Sbrutus 
908e50dcc9Sbrutus /* dq_version */
918e50dcc9Sbrutus #define	DCOPY_QUERY_CHANNEL_V0	0
928e50dcc9Sbrutus 
938e50dcc9Sbrutus /* Per DMA channel info */
948e50dcc9Sbrutus typedef struct dcopy_query_channel_s {
958e50dcc9Sbrutus 	int		qc_version; /* DCOPY_QUERY_CHANNEL_V0 */
968e50dcc9Sbrutus 
978e50dcc9Sbrutus 	/* Does DMA channel support DCA */
988e50dcc9Sbrutus 	boolean_t	qc_dca_supported;
998e50dcc9Sbrutus 
1008e50dcc9Sbrutus 	/* device id and device specific capabilities */
1018e50dcc9Sbrutus 	uint64_t	qc_id;
1028e50dcc9Sbrutus 	uint64_t	qc_capabilities;
1038e50dcc9Sbrutus 
1048e50dcc9Sbrutus 	/*
1058e50dcc9Sbrutus 	 * DMA channel size. This may not be the same as the number of posts
1068e50dcc9Sbrutus 	 * that the DMA channel can handle since a post may consume 1 or more
1078e50dcc9Sbrutus 	 * entries.
1088e50dcc9Sbrutus 	 */
1098e50dcc9Sbrutus 	uint64_t	qc_channel_size;
1108e50dcc9Sbrutus 
1118e50dcc9Sbrutus 	/* DMA channel number within the device. Not unique across devices */
1128e50dcc9Sbrutus 	uint64_t	qc_chan_num;
1138e50dcc9Sbrutus } dcopy_query_channel_t;
1148e50dcc9Sbrutus 
1158e50dcc9Sbrutus /*
1168e50dcc9Sbrutus  * dcopy_query_channel()
1178e50dcc9Sbrutus  *   query DMA engines capabilities
1188e50dcc9Sbrutus  */
1198e50dcc9Sbrutus void dcopy_query_channel(dcopy_handle_t handle, dcopy_query_channel_t *query);
1208e50dcc9Sbrutus 
1218e50dcc9Sbrutus 
1228e50dcc9Sbrutus /* dp_version */
1238e50dcc9Sbrutus #define	DCOPY_CMD_V0	0
1248e50dcc9Sbrutus 
1258e50dcc9Sbrutus /* dp_cmd */
1268e50dcc9Sbrutus #define	DCOPY_CMD_COPY	0x1
1278e50dcc9Sbrutus 
1288e50dcc9Sbrutus /* dp_flags */
1298e50dcc9Sbrutus /*
1308e50dcc9Sbrutus  * DCOPY_CMD_QUEUE
1318e50dcc9Sbrutus  *    Hint to queue up the post but don't notify the DMA engine. This can be
1328e50dcc9Sbrutus  *    used as an optimization when multiple posts are going to be queued up and
1338e50dcc9Sbrutus  *    you only want notify the DMA engine after the last post. Note, this does
1348e50dcc9Sbrutus  *    not mean the DMA engine won't process the request since it could notice
1358e50dcc9Sbrutus  *    it anyway.
1368e50dcc9Sbrutus  * DCOPY_CMD_NOSTAT
1378e50dcc9Sbrutus  *    Don't generate a status. If this flag is used, You cannot poll for
1388e50dcc9Sbrutus  *    completion status on this command. This can be a useful performance
1398e50dcc9Sbrutus  *    optimization if your posting multiple commands and just want to poll on
1408e50dcc9Sbrutus  *    the last command.
1418e50dcc9Sbrutus  * DCOPY_CMD_DCA
1428e50dcc9Sbrutus  *    If DCA is supported, direct this and all future command data (until the
1438e50dcc9Sbrutus  *    next command with DCOPY_POST_DCA set) to the processor specified in
1448e50dcc9Sbrutus  *    dp_dca_id. This flag is ignored if DCA is not supported.
1458e50dcc9Sbrutus  * DCOPY_CMD_INTR
1468e50dcc9Sbrutus  *    Generate an interrupt when command completes. This flag is required if
1478e50dcc9Sbrutus  *    the caller is going to call dcopy_cmd_poll(() with DCOPY_POLL_BLOCK set
1488e50dcc9Sbrutus  *    for this command.
149*eca2601cSRandy Fishel  * DCOPY_CMD_NOWAIT
150*eca2601cSRandy Fishel  *    Return error instead of busy waiting if resource is not available.
151*eca2601cSRandy Fishel  * DCOPY_CMD_NOSRCSNP
152*eca2601cSRandy Fishel  *    Disable source cache snooping.
153*eca2601cSRandy Fishel  * DCOPY_CMD_NODSTSNP
154*eca2601cSRandy Fishel  *    Disable destination cache snooping.
155*eca2601cSRandy Fishel  * DCOPY_CMD_LOOP
156*eca2601cSRandy Fishel  *    For CBv1, generate a loop descriptor list, used to support FIPE driver.
157*eca2601cSRandy Fishel  * DCOPY_CMD_SYNC
158*eca2601cSRandy Fishel  *    Reserved for internal use.
1598e50dcc9Sbrutus  */
1608e50dcc9Sbrutus #define	DCOPY_CMD_NOFLAGS	(0)
1618e50dcc9Sbrutus #define	DCOPY_CMD_QUEUE		(1 << 0)
1628e50dcc9Sbrutus #define	DCOPY_CMD_NOSTAT	(1 << 1)
1638e50dcc9Sbrutus #define	DCOPY_CMD_DCA		(1 << 2)
1648e50dcc9Sbrutus #define	DCOPY_CMD_INTR		(1 << 3)
165*eca2601cSRandy Fishel #define	DCOPY_CMD_NOWAIT	(1 << 4)
166*eca2601cSRandy Fishel #define	DCOPY_CMD_NOSRCSNP	(1 << 5)
167*eca2601cSRandy Fishel #define	DCOPY_CMD_NODSTSNP	(1 << 6)
168*eca2601cSRandy Fishel #define	DCOPY_CMD_LOOP		(1 << 7)
169*eca2601cSRandy Fishel #define	DCOPY_CMD_SYNC		(1 << 30)
1708e50dcc9Sbrutus 
1718e50dcc9Sbrutus typedef struct dcopy_cmd_copy_s {
1728e50dcc9Sbrutus 	uint64_t	cc_source; /* Source physical address */
1738e50dcc9Sbrutus 	uint64_t	cc_dest; /* Destination physical address */
1748e50dcc9Sbrutus 	size_t		cc_size;
1758e50dcc9Sbrutus } dcopy_cmd_copy_t;
1768e50dcc9Sbrutus 
1778e50dcc9Sbrutus typedef union dcopy_cmd_u {
1788e50dcc9Sbrutus 	dcopy_cmd_copy_t	copy;
1798e50dcc9Sbrutus } dcopy_cmd_u_t;
1808e50dcc9Sbrutus 
1818e50dcc9Sbrutus typedef struct dcopy_cmd_priv_s *dcopy_cmd_priv_t;
1828e50dcc9Sbrutus 
1838e50dcc9Sbrutus struct dcopy_cmd_s {
1848e50dcc9Sbrutus 	uint_t			dp_version; /* DCOPY_CMD_V0 */
1858e50dcc9Sbrutus 	uint_t			dp_flags;
1868e50dcc9Sbrutus 	uint64_t		dp_cmd;
1878e50dcc9Sbrutus 	dcopy_cmd_u_t   	dp;
1888e50dcc9Sbrutus 	uint32_t		dp_dca_id;
1898e50dcc9Sbrutus 	dcopy_cmd_priv_t	dp_private;
1908e50dcc9Sbrutus };
1918e50dcc9Sbrutus typedef struct dcopy_cmd_s *dcopy_cmd_t;
1928e50dcc9Sbrutus 
1938e50dcc9Sbrutus 
1948e50dcc9Sbrutus /*
1958e50dcc9Sbrutus  * dcopy_cmd_alloc() specific flags
1968e50dcc9Sbrutus  *   DCOPY_ALLOC_LINK - when set, the caller passes in a previously alloced
1978e50dcc9Sbrutus  *     command in cmd. dcopy_cmd_alloc() will allocate a new command and
1988e50dcc9Sbrutus  *     link it to the old command. The caller can use this to build a
1998e50dcc9Sbrutus  *     chain of commands, keeping only the last cmd alloced. calling
2008e50dcc9Sbrutus  *     dcopy_cmd_free() with the last cmd alloced in the chain will free all of
2018e50dcc9Sbrutus  *     the commands in the chain. dcopy_cmd_post() and dcopy_cmd_poll() have
2028e50dcc9Sbrutus  *     no knowledge of a chain of commands.  It's only used for alloc/free.
2038e50dcc9Sbrutus  */
2048e50dcc9Sbrutus #define	DCOPY_ALLOC_LINK	(1 << 16)
2058e50dcc9Sbrutus 
2068e50dcc9Sbrutus /*
2078e50dcc9Sbrutus  * dcopy_cmd_alloc()
2088e50dcc9Sbrutus  *   allocate a command. A command can be re-used after it completes.
2098e50dcc9Sbrutus  *     flags - (DCOPY_SLEEP || DCOPY_NOSLEEP), DCOPY_ALLOC_LINK
2108e50dcc9Sbrutus  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
2118e50dcc9Sbrutus  */
2128e50dcc9Sbrutus int dcopy_cmd_alloc(dcopy_handle_t handle, int flags, dcopy_cmd_t *cmd);
2138e50dcc9Sbrutus 
2148e50dcc9Sbrutus /*
2158e50dcc9Sbrutus  * dcopy_cmd_free()
2168e50dcc9Sbrutus  *   free the command. This call cannot be called after dcopy_free().
2178e50dcc9Sbrutus  */
2188e50dcc9Sbrutus void dcopy_cmd_free(dcopy_cmd_t *cmd);
2198e50dcc9Sbrutus 
2208e50dcc9Sbrutus /*
2218e50dcc9Sbrutus  * dcopy_cmd_post()
2228e50dcc9Sbrutus  *   post a command (allocated from dcopy_cmd_alloc()) to the DMA channel
2238e50dcc9Sbrutus  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
2248e50dcc9Sbrutus  */
2258e50dcc9Sbrutus int dcopy_cmd_post(dcopy_cmd_t cmd);
2268e50dcc9Sbrutus 
2278e50dcc9Sbrutus /* dcopy_cmd_poll() flags */
2288e50dcc9Sbrutus #define	DCOPY_POLL_NOFLAGS	(0)
2298e50dcc9Sbrutus #define	DCOPY_POLL_BLOCK	(1 << 0)
2308e50dcc9Sbrutus 
2318e50dcc9Sbrutus /*
2328e50dcc9Sbrutus  * dcopy_cmd_poll()
2338e50dcc9Sbrutus  *   poll on completion status of a previous post. This call cannot be called
2348e50dcc9Sbrutus  *   after dcopy_free().
2358e50dcc9Sbrutus  *
2368e50dcc9Sbrutus  *   if flags == DCOPY_POLL_NOFLAGS, return status can be DCOPY_FAILURE,
2378e50dcc9Sbrutus  *   DCOPY_PENDING, or DCOPY_COMPLETED.
2388e50dcc9Sbrutus  *
2398e50dcc9Sbrutus  *   if flags & DCOPY_POLL_BLOCK, return status can be DCOPY_FAILURE or
2408e50dcc9Sbrutus  *   DCOPY_COMPLETED. DCOPY_POLL_BLOCK can only be set in base context.
2418e50dcc9Sbrutus  *
2428e50dcc9Sbrutus  *   The command cannot be re-used or freed until the command has completed
2438e50dcc9Sbrutus  *   (e.g. DCOPY_FAILURE or DCOPY_COMPLETED).
2448e50dcc9Sbrutus  */
2458e50dcc9Sbrutus int dcopy_cmd_poll(dcopy_cmd_t cmd, int flags);
2468e50dcc9Sbrutus 
2478e50dcc9Sbrutus 
2488e50dcc9Sbrutus #ifdef __cplusplus
2498e50dcc9Sbrutus }
2508e50dcc9Sbrutus #endif
2518e50dcc9Sbrutus 
2528e50dcc9Sbrutus #endif /* _SYS_DCOPY_H */
253