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