xref: /illumos-gate/usr/src/uts/common/sys/dcopy.h (revision eca2601c)
117169044Sbrutus /*
217169044Sbrutus  * CDDL HEADER START
317169044Sbrutus  *
417169044Sbrutus  * The contents of this file are subject to the terms of the
517169044Sbrutus  * Common Development and Distribution License (the "License").
617169044Sbrutus  * You may not use this file except in compliance with the License.
717169044Sbrutus  *
817169044Sbrutus  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
917169044Sbrutus  * or http://www.opensolaris.org/os/licensing.
1017169044Sbrutus  * See the License for the specific language governing permissions
1117169044Sbrutus  * and limitations under the License.
1217169044Sbrutus  *
1317169044Sbrutus  * When distributing Covered Code, include this CDDL HEADER in each
1417169044Sbrutus  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1517169044Sbrutus  * If applicable, add the following below this CDDL HEADER, with the
1617169044Sbrutus  * fields enclosed by brackets "[]" replaced with your own identifying
1717169044Sbrutus  * information: Portions Copyright [yyyy] [name of copyright owner]
1817169044Sbrutus  *
1917169044Sbrutus  * CDDL HEADER END
2017169044Sbrutus  */
2117169044Sbrutus 
2217169044Sbrutus /*
23*eca2601cSRandy Fishel  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2417169044Sbrutus  * Use is subject to license terms.
2517169044Sbrutus  */
2617169044Sbrutus 
2717169044Sbrutus #ifndef _SYS_DCOPY_H
2817169044Sbrutus #define	_SYS_DCOPY_H
2917169044Sbrutus 
3017169044Sbrutus #ifdef __cplusplus
3117169044Sbrutus extern "C" {
3217169044Sbrutus #endif
3317169044Sbrutus 
3417169044Sbrutus #include <sys/types.h>
3517169044Sbrutus 
3617169044Sbrutus /*
3717169044Sbrutus  * *** This interface is for private use by the IP stack only ***
3817169044Sbrutus  */
3917169044Sbrutus 
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 
4417169044Sbrutus /* Function return status */
4517169044Sbrutus #define	DCOPY_FAILURE		(-1)
4617169044Sbrutus #define	DCOPY_SUCCESS		(0)
4717169044Sbrutus #define	DCOPY_NORESOURCES	(1) /* _alloc & _cmd_alloc, _cmd_post only */
4817169044Sbrutus #define	DCOPY_PENDING		(0x10) /* dcopy_poll(), dcopy_unregister() */
4917169044Sbrutus #define	DCOPY_COMPLETED		(0x20) /* dcopy_poll() only */
5017169044Sbrutus 
5117169044Sbrutus 
5217169044Sbrutus /* dq_version */
5317169044Sbrutus #define	DCOPY_QUERY_V0	0
5417169044Sbrutus 
5517169044Sbrutus typedef struct dcopy_query_s {
5617169044Sbrutus 	int		dq_version; /* DCOPY_QUERY_V0 */
5717169044Sbrutus 	uint_t		dq_num_channels; /* number of dma channels */
5817169044Sbrutus } dcopy_query_t;
5917169044Sbrutus 
6017169044Sbrutus /*
6117169044Sbrutus  * dcopy_query()
6217169044Sbrutus  *   query for the number of DMA engines usable in the system.
6317169044Sbrutus  */
6417169044Sbrutus void dcopy_query(dcopy_query_t *query);
6517169044Sbrutus 
6617169044Sbrutus 
6717169044Sbrutus typedef struct dcopy_channel_s *dcopy_handle_t;
6817169044Sbrutus 
6917169044Sbrutus /* dcopy_alloc() and dcopy_cmd_alloc() common flags */
7017169044Sbrutus #define	DCOPY_SLEEP	(0)
7117169044Sbrutus #define	DCOPY_NOSLEEP	(1 << 0)
7217169044Sbrutus 
7317169044Sbrutus /*
7417169044Sbrutus  * dcopy_alloc()
7517169044Sbrutus  *   Allocate a DMA channel which is used for posting DMA requests. Note: this
7617169044Sbrutus  *   does not give the caller exclusive access to the DMA engine. Commands
7717169044Sbrutus  *   posted to a channel will complete in order.
7817169044Sbrutus  *     flags - (DCOPY_SLEEP, DCOPY_NOSLEEP)
7917169044Sbrutus  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
8017169044Sbrutus  */
8117169044Sbrutus int dcopy_alloc(int flags, dcopy_handle_t *handle);
8217169044Sbrutus 
8317169044Sbrutus /*
8417169044Sbrutus  * dcopy_free()
8517169044Sbrutus  *   Free the DMA channel. The client can no longer use the handle to post or
8617169044Sbrutus  *   poll for status on posts which were previously done on this channel.
8717169044Sbrutus  */
8817169044Sbrutus void dcopy_free(dcopy_handle_t *handle);
8917169044Sbrutus 
9017169044Sbrutus /* dq_version */
9117169044Sbrutus #define	DCOPY_QUERY_CHANNEL_V0	0
9217169044Sbrutus 
9317169044Sbrutus /* Per DMA channel info */
9417169044Sbrutus typedef struct dcopy_query_channel_s {
9517169044Sbrutus 	int		qc_version; /* DCOPY_QUERY_CHANNEL_V0 */
9617169044Sbrutus 
9717169044Sbrutus 	/* Does DMA channel support DCA */
9817169044Sbrutus 	boolean_t	qc_dca_supported;
9917169044Sbrutus 
10017169044Sbrutus 	/* device id and device specific capabilities */
10117169044Sbrutus 	uint64_t	qc_id;
10217169044Sbrutus 	uint64_t	qc_capabilities;
10317169044Sbrutus 
10417169044Sbrutus 	/*
10517169044Sbrutus 	 * DMA channel size. This may not be the same as the number of posts
10617169044Sbrutus 	 * that the DMA channel can handle since a post may consume 1 or more
10717169044Sbrutus 	 * entries.
10817169044Sbrutus 	 */
10917169044Sbrutus 	uint64_t	qc_channel_size;
11017169044Sbrutus 
11117169044Sbrutus 	/* DMA channel number within the device. Not unique across devices */
11217169044Sbrutus 	uint64_t	qc_chan_num;
11317169044Sbrutus } dcopy_query_channel_t;
11417169044Sbrutus 
11517169044Sbrutus /*
11617169044Sbrutus  * dcopy_query_channel()
11717169044Sbrutus  *   query DMA engines capabilities
11817169044Sbrutus  */
11917169044Sbrutus void dcopy_query_channel(dcopy_handle_t handle, dcopy_query_channel_t *query);
12017169044Sbrutus 
12117169044Sbrutus 
12217169044Sbrutus /* dp_version */
12317169044Sbrutus #define	DCOPY_CMD_V0	0
12417169044Sbrutus 
12517169044Sbrutus /* dp_cmd */
12617169044Sbrutus #define	DCOPY_CMD_COPY	0x1
12717169044Sbrutus 
12817169044Sbrutus /* dp_flags */
12917169044Sbrutus /*
13017169044Sbrutus  * DCOPY_CMD_QUEUE
13117169044Sbrutus  *    Hint to queue up the post but don't notify the DMA engine. This can be
13217169044Sbrutus  *    used as an optimization when multiple posts are going to be queued up and
13317169044Sbrutus  *    you only want notify the DMA engine after the last post. Note, this does
13417169044Sbrutus  *    not mean the DMA engine won't process the request since it could notice
13517169044Sbrutus  *    it anyway.
13617169044Sbrutus  * DCOPY_CMD_NOSTAT
13717169044Sbrutus  *    Don't generate a status. If this flag is used, You cannot poll for
13817169044Sbrutus  *    completion status on this command. This can be a useful performance
13917169044Sbrutus  *    optimization if your posting multiple commands and just want to poll on
14017169044Sbrutus  *    the last command.
14117169044Sbrutus  * DCOPY_CMD_DCA
14217169044Sbrutus  *    If DCA is supported, direct this and all future command data (until the
14317169044Sbrutus  *    next command with DCOPY_POST_DCA set) to the processor specified in
14417169044Sbrutus  *    dp_dca_id. This flag is ignored if DCA is not supported.
14517169044Sbrutus  * DCOPY_CMD_INTR
14617169044Sbrutus  *    Generate an interrupt when command completes. This flag is required if
14717169044Sbrutus  *    the caller is going to call dcopy_cmd_poll(() with DCOPY_POLL_BLOCK set
14817169044Sbrutus  *    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.
15917169044Sbrutus  */
16017169044Sbrutus #define	DCOPY_CMD_NOFLAGS	(0)
16117169044Sbrutus #define	DCOPY_CMD_QUEUE		(1 << 0)
16217169044Sbrutus #define	DCOPY_CMD_NOSTAT	(1 << 1)
16317169044Sbrutus #define	DCOPY_CMD_DCA		(1 << 2)
16417169044Sbrutus #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)
17017169044Sbrutus 
17117169044Sbrutus typedef struct dcopy_cmd_copy_s {
17217169044Sbrutus 	uint64_t	cc_source; /* Source physical address */
17317169044Sbrutus 	uint64_t	cc_dest; /* Destination physical address */
17417169044Sbrutus 	size_t		cc_size;
17517169044Sbrutus } dcopy_cmd_copy_t;
17617169044Sbrutus 
17717169044Sbrutus typedef union dcopy_cmd_u {
17817169044Sbrutus 	dcopy_cmd_copy_t	copy;
17917169044Sbrutus } dcopy_cmd_u_t;
18017169044Sbrutus 
18117169044Sbrutus typedef struct dcopy_cmd_priv_s *dcopy_cmd_priv_t;
18217169044Sbrutus 
18317169044Sbrutus struct dcopy_cmd_s {
18417169044Sbrutus 	uint_t			dp_version; /* DCOPY_CMD_V0 */
18517169044Sbrutus 	uint_t			dp_flags;
18617169044Sbrutus 	uint64_t		dp_cmd;
18717169044Sbrutus 	dcopy_cmd_u_t   	dp;
18817169044Sbrutus 	uint32_t		dp_dca_id;
18917169044Sbrutus 	dcopy_cmd_priv_t	dp_private;
19017169044Sbrutus };
19117169044Sbrutus typedef struct dcopy_cmd_s *dcopy_cmd_t;
19217169044Sbrutus 
19317169044Sbrutus 
19417169044Sbrutus /*
19517169044Sbrutus  * dcopy_cmd_alloc() specific flags
19617169044Sbrutus  *   DCOPY_ALLOC_LINK - when set, the caller passes in a previously alloced
19717169044Sbrutus  *     command in cmd. dcopy_cmd_alloc() will allocate a new command and
19817169044Sbrutus  *     link it to the old command. The caller can use this to build a
19917169044Sbrutus  *     chain of commands, keeping only the last cmd alloced. calling
20017169044Sbrutus  *     dcopy_cmd_free() with the last cmd alloced in the chain will free all of
20117169044Sbrutus  *     the commands in the chain. dcopy_cmd_post() and dcopy_cmd_poll() have
20217169044Sbrutus  *     no knowledge of a chain of commands.  It's only used for alloc/free.
20317169044Sbrutus  */
20417169044Sbrutus #define	DCOPY_ALLOC_LINK	(1 << 16)
20517169044Sbrutus 
20617169044Sbrutus /*
20717169044Sbrutus  * dcopy_cmd_alloc()
20817169044Sbrutus  *   allocate a command. A command can be re-used after it completes.
20917169044Sbrutus  *     flags - (DCOPY_SLEEP || DCOPY_NOSLEEP), DCOPY_ALLOC_LINK
21017169044Sbrutus  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
21117169044Sbrutus  */
21217169044Sbrutus int dcopy_cmd_alloc(dcopy_handle_t handle, int flags, dcopy_cmd_t *cmd);
21317169044Sbrutus 
21417169044Sbrutus /*
21517169044Sbrutus  * dcopy_cmd_free()
21617169044Sbrutus  *   free the command. This call cannot be called after dcopy_free().
21717169044Sbrutus  */
21817169044Sbrutus void dcopy_cmd_free(dcopy_cmd_t *cmd);
21917169044Sbrutus 
22017169044Sbrutus /*
22117169044Sbrutus  * dcopy_cmd_post()
22217169044Sbrutus  *   post a command (allocated from dcopy_cmd_alloc()) to the DMA channel
22317169044Sbrutus  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
22417169044Sbrutus  */
22517169044Sbrutus int dcopy_cmd_post(dcopy_cmd_t cmd);
22617169044Sbrutus 
22717169044Sbrutus /* dcopy_cmd_poll() flags */
22817169044Sbrutus #define	DCOPY_POLL_NOFLAGS	(0)
22917169044Sbrutus #define	DCOPY_POLL_BLOCK	(1 << 0)
23017169044Sbrutus 
23117169044Sbrutus /*
23217169044Sbrutus  * dcopy_cmd_poll()
23317169044Sbrutus  *   poll on completion status of a previous post. This call cannot be called
23417169044Sbrutus  *   after dcopy_free().
23517169044Sbrutus  *
23617169044Sbrutus  *   if flags == DCOPY_POLL_NOFLAGS, return status can be DCOPY_FAILURE,
23717169044Sbrutus  *   DCOPY_PENDING, or DCOPY_COMPLETED.
23817169044Sbrutus  *
23917169044Sbrutus  *   if flags & DCOPY_POLL_BLOCK, return status can be DCOPY_FAILURE or
24017169044Sbrutus  *   DCOPY_COMPLETED. DCOPY_POLL_BLOCK can only be set in base context.
24117169044Sbrutus  *
24217169044Sbrutus  *   The command cannot be re-used or freed until the command has completed
24317169044Sbrutus  *   (e.g. DCOPY_FAILURE or DCOPY_COMPLETED).
24417169044Sbrutus  */
24517169044Sbrutus int dcopy_cmd_poll(dcopy_cmd_t cmd, int flags);
24617169044Sbrutus 
24717169044Sbrutus 
24817169044Sbrutus #ifdef __cplusplus
24917169044Sbrutus }
25017169044Sbrutus #endif
25117169044Sbrutus 
25217169044Sbrutus #endif /* _SYS_DCOPY_H */
253