xref: /linux/include/linux/fsl/bestcomm/bestcomm.h (revision d3e81989)
19a322993SPhilippe De Muyter /*
29a322993SPhilippe De Muyter  * Public header for the MPC52xx processor BestComm driver
39a322993SPhilippe De Muyter  *
49a322993SPhilippe De Muyter  *
59a322993SPhilippe De Muyter  * Copyright (C) 2006      Sylvain Munaut <tnt@246tNt.com>
69a322993SPhilippe De Muyter  * Copyright (C) 2005      Varma Electronics Oy,
79a322993SPhilippe De Muyter  *                         ( by Andrey Volkov <avolkov@varma-el.com> )
89a322993SPhilippe De Muyter  * Copyright (C) 2003-2004 MontaVista, Software, Inc.
99a322993SPhilippe De Muyter  *                         ( by Dale Farnsworth <dfarnsworth@mvista.com> )
109a322993SPhilippe De Muyter  *
119a322993SPhilippe De Muyter  * This file is licensed under the terms of the GNU General Public License
129a322993SPhilippe De Muyter  * version 2. This program is licensed "as is" without any warranty of any
139a322993SPhilippe De Muyter  * kind, whether express or implied.
149a322993SPhilippe De Muyter  */
159a322993SPhilippe De Muyter 
169a322993SPhilippe De Muyter #ifndef __BESTCOMM_H__
179a322993SPhilippe De Muyter #define __BESTCOMM_H__
189a322993SPhilippe De Muyter 
199a322993SPhilippe De Muyter /**
209a322993SPhilippe De Muyter  * struct bcom_bd - Structure describing a generic BestComm buffer descriptor
219a322993SPhilippe De Muyter  * @status: The current status of this buffer. Exact meaning depends on the
229a322993SPhilippe De Muyter  *          task type
239a322993SPhilippe De Muyter  * @data: An array of u32 extra data.  Size of array is task dependent.
249a322993SPhilippe De Muyter  *
259a322993SPhilippe De Muyter  * Note: Don't dereference a bcom_bd pointer as an array.  The size of the
269a322993SPhilippe De Muyter  *       bcom_bd is variable.  Use bcom_get_bd() instead.
279a322993SPhilippe De Muyter  */
289a322993SPhilippe De Muyter struct bcom_bd {
299a322993SPhilippe De Muyter 	u32	status;
30*d3e81989SGustavo A. R. Silva 	u32	data[];	/* variable payload size */
319a322993SPhilippe De Muyter };
329a322993SPhilippe De Muyter 
339a322993SPhilippe De Muyter /* ======================================================================== */
349a322993SPhilippe De Muyter /* Generic task management                                                   */
359a322993SPhilippe De Muyter /* ======================================================================== */
369a322993SPhilippe De Muyter 
379a322993SPhilippe De Muyter /**
389a322993SPhilippe De Muyter  * struct bcom_task - Structure describing a loaded BestComm task
399a322993SPhilippe De Muyter  *
409a322993SPhilippe De Muyter  * This structure is never built by the driver it self. It's built and
419a322993SPhilippe De Muyter  * filled the intermediate layer of the BestComm API, the task dependent
429a322993SPhilippe De Muyter  * support code.
439a322993SPhilippe De Muyter  *
449a322993SPhilippe De Muyter  * Most likely you don't need to poke around inside this structure. The
459a322993SPhilippe De Muyter  * fields are exposed in the header just for the sake of inline functions
469a322993SPhilippe De Muyter  */
479a322993SPhilippe De Muyter struct bcom_task {
489a322993SPhilippe De Muyter 	unsigned int	tasknum;
499a322993SPhilippe De Muyter 	unsigned int	flags;
509a322993SPhilippe De Muyter 	int		irq;
519a322993SPhilippe De Muyter 
529a322993SPhilippe De Muyter 	struct bcom_bd	*bd;
539a322993SPhilippe De Muyter 	phys_addr_t	bd_pa;
549a322993SPhilippe De Muyter 	void		**cookie;
559a322993SPhilippe De Muyter 	unsigned short	index;
569a322993SPhilippe De Muyter 	unsigned short	outdex;
579a322993SPhilippe De Muyter 	unsigned int	num_bd;
589a322993SPhilippe De Muyter 	unsigned int	bd_size;
599a322993SPhilippe De Muyter 
609a322993SPhilippe De Muyter 	void*		priv;
619a322993SPhilippe De Muyter };
629a322993SPhilippe De Muyter 
639a322993SPhilippe De Muyter #define BCOM_FLAGS_NONE         0x00000000ul
649a322993SPhilippe De Muyter #define BCOM_FLAGS_ENABLE_TASK  (1ul <<  0)
659a322993SPhilippe De Muyter 
669a322993SPhilippe De Muyter /**
679a322993SPhilippe De Muyter  * bcom_enable - Enable a BestComm task
689a322993SPhilippe De Muyter  * @tsk: The BestComm task structure
699a322993SPhilippe De Muyter  *
709a322993SPhilippe De Muyter  * This function makes sure the given task is enabled and can be run
719a322993SPhilippe De Muyter  * by the BestComm engine as needed
729a322993SPhilippe De Muyter  */
739a322993SPhilippe De Muyter extern void bcom_enable(struct bcom_task *tsk);
749a322993SPhilippe De Muyter 
759a322993SPhilippe De Muyter /**
769a322993SPhilippe De Muyter  * bcom_disable - Disable a BestComm task
779a322993SPhilippe De Muyter  * @tsk: The BestComm task structure
789a322993SPhilippe De Muyter  *
799a322993SPhilippe De Muyter  * This function disable a given task, making sure it's not executed
809a322993SPhilippe De Muyter  * by the BestComm engine.
819a322993SPhilippe De Muyter  */
829a322993SPhilippe De Muyter extern void bcom_disable(struct bcom_task *tsk);
839a322993SPhilippe De Muyter 
849a322993SPhilippe De Muyter 
859a322993SPhilippe De Muyter /**
869a322993SPhilippe De Muyter  * bcom_get_task_irq - Returns the irq number of a BestComm task
879a322993SPhilippe De Muyter  * @tsk: The BestComm task structure
889a322993SPhilippe De Muyter  */
899a322993SPhilippe De Muyter static inline int
bcom_get_task_irq(struct bcom_task * tsk)909a322993SPhilippe De Muyter bcom_get_task_irq(struct bcom_task *tsk) {
919a322993SPhilippe De Muyter 	return tsk->irq;
929a322993SPhilippe De Muyter }
939a322993SPhilippe De Muyter 
949a322993SPhilippe De Muyter /* ======================================================================== */
959a322993SPhilippe De Muyter /* BD based tasks helpers                                                   */
969a322993SPhilippe De Muyter /* ======================================================================== */
979a322993SPhilippe De Muyter 
989a322993SPhilippe De Muyter #define BCOM_BD_READY	0x40000000ul
999a322993SPhilippe De Muyter 
1009a322993SPhilippe De Muyter /** _bcom_next_index - Get next input index.
1019a322993SPhilippe De Muyter  * @tsk: pointer to task structure
1029a322993SPhilippe De Muyter  *
1039a322993SPhilippe De Muyter  * Support function; Device drivers should not call this
1049a322993SPhilippe De Muyter  */
1059a322993SPhilippe De Muyter static inline int
_bcom_next_index(struct bcom_task * tsk)1069a322993SPhilippe De Muyter _bcom_next_index(struct bcom_task *tsk)
1079a322993SPhilippe De Muyter {
1089a322993SPhilippe De Muyter 	return ((tsk->index + 1) == tsk->num_bd) ? 0 : tsk->index + 1;
1099a322993SPhilippe De Muyter }
1109a322993SPhilippe De Muyter 
1119a322993SPhilippe De Muyter /** _bcom_next_outdex - Get next output index.
1129a322993SPhilippe De Muyter  * @tsk: pointer to task structure
1139a322993SPhilippe De Muyter  *
1149a322993SPhilippe De Muyter  * Support function; Device drivers should not call this
1159a322993SPhilippe De Muyter  */
1169a322993SPhilippe De Muyter static inline int
_bcom_next_outdex(struct bcom_task * tsk)1179a322993SPhilippe De Muyter _bcom_next_outdex(struct bcom_task *tsk)
1189a322993SPhilippe De Muyter {
1199a322993SPhilippe De Muyter 	return ((tsk->outdex + 1) == tsk->num_bd) ? 0 : tsk->outdex + 1;
1209a322993SPhilippe De Muyter }
1219a322993SPhilippe De Muyter 
1229a322993SPhilippe De Muyter /**
1239a322993SPhilippe De Muyter  * bcom_queue_empty - Checks if a BestComm task BD queue is empty
1249a322993SPhilippe De Muyter  * @tsk: The BestComm task structure
1259a322993SPhilippe De Muyter  */
1269a322993SPhilippe De Muyter static inline int
bcom_queue_empty(struct bcom_task * tsk)1279a322993SPhilippe De Muyter bcom_queue_empty(struct bcom_task *tsk)
1289a322993SPhilippe De Muyter {
1299a322993SPhilippe De Muyter 	return tsk->index == tsk->outdex;
1309a322993SPhilippe De Muyter }
1319a322993SPhilippe De Muyter 
1329a322993SPhilippe De Muyter /**
1339a322993SPhilippe De Muyter  * bcom_queue_full - Checks if a BestComm task BD queue is full
1349a322993SPhilippe De Muyter  * @tsk: The BestComm task structure
1359a322993SPhilippe De Muyter  */
1369a322993SPhilippe De Muyter static inline int
bcom_queue_full(struct bcom_task * tsk)1379a322993SPhilippe De Muyter bcom_queue_full(struct bcom_task *tsk)
1389a322993SPhilippe De Muyter {
1399a322993SPhilippe De Muyter 	return tsk->outdex == _bcom_next_index(tsk);
1409a322993SPhilippe De Muyter }
1419a322993SPhilippe De Muyter 
1429a322993SPhilippe De Muyter /**
1439a322993SPhilippe De Muyter  * bcom_get_bd - Get a BD from the queue
1449a322993SPhilippe De Muyter  * @tsk: The BestComm task structure
1459a322993SPhilippe De Muyter  * index: Index of the BD to fetch
1469a322993SPhilippe De Muyter  */
1479a322993SPhilippe De Muyter static inline struct bcom_bd
bcom_get_bd(struct bcom_task * tsk,unsigned int index)1489a322993SPhilippe De Muyter *bcom_get_bd(struct bcom_task *tsk, unsigned int index)
1499a322993SPhilippe De Muyter {
1509a322993SPhilippe De Muyter 	/* A cast to (void*) so the address can be incremented by the
1519a322993SPhilippe De Muyter 	 * real size instead of by sizeof(struct bcom_bd) */
1529a322993SPhilippe De Muyter 	return ((void *)tsk->bd) + (index * tsk->bd_size);
1539a322993SPhilippe De Muyter }
1549a322993SPhilippe De Muyter 
1559a322993SPhilippe De Muyter /**
1569a322993SPhilippe De Muyter  * bcom_buffer_done - Checks if a BestComm
1579a322993SPhilippe De Muyter  * @tsk: The BestComm task structure
1589a322993SPhilippe De Muyter  */
1599a322993SPhilippe De Muyter static inline int
bcom_buffer_done(struct bcom_task * tsk)1609a322993SPhilippe De Muyter bcom_buffer_done(struct bcom_task *tsk)
1619a322993SPhilippe De Muyter {
1629a322993SPhilippe De Muyter 	struct bcom_bd *bd;
1639a322993SPhilippe De Muyter 	if (bcom_queue_empty(tsk))
1649a322993SPhilippe De Muyter 		return 0;
1659a322993SPhilippe De Muyter 
1669a322993SPhilippe De Muyter 	bd = bcom_get_bd(tsk, tsk->outdex);
1679a322993SPhilippe De Muyter 	return !(bd->status & BCOM_BD_READY);
1689a322993SPhilippe De Muyter }
1699a322993SPhilippe De Muyter 
1709a322993SPhilippe De Muyter /**
1719a322993SPhilippe De Muyter  * bcom_prepare_next_buffer - clear status of next available buffer.
1729a322993SPhilippe De Muyter  * @tsk: The BestComm task structure
1739a322993SPhilippe De Muyter  *
1749a322993SPhilippe De Muyter  * Returns pointer to next buffer descriptor
1759a322993SPhilippe De Muyter  */
1769a322993SPhilippe De Muyter static inline struct bcom_bd *
bcom_prepare_next_buffer(struct bcom_task * tsk)1779a322993SPhilippe De Muyter bcom_prepare_next_buffer(struct bcom_task *tsk)
1789a322993SPhilippe De Muyter {
1799a322993SPhilippe De Muyter 	struct bcom_bd *bd;
1809a322993SPhilippe De Muyter 
1819a322993SPhilippe De Muyter 	bd = bcom_get_bd(tsk, tsk->index);
1829a322993SPhilippe De Muyter 	bd->status = 0;	/* cleanup last status */
1839a322993SPhilippe De Muyter 	return bd;
1849a322993SPhilippe De Muyter }
1859a322993SPhilippe De Muyter 
1869a322993SPhilippe De Muyter static inline void
bcom_submit_next_buffer(struct bcom_task * tsk,void * cookie)1879a322993SPhilippe De Muyter bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
1889a322993SPhilippe De Muyter {
1899a322993SPhilippe De Muyter 	struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index);
1909a322993SPhilippe De Muyter 
1919a322993SPhilippe De Muyter 	tsk->cookie[tsk->index] = cookie;
1929a322993SPhilippe De Muyter 	mb();	/* ensure the bd is really up-to-date */
1939a322993SPhilippe De Muyter 	bd->status |= BCOM_BD_READY;
1949a322993SPhilippe De Muyter 	tsk->index = _bcom_next_index(tsk);
1959a322993SPhilippe De Muyter 	if (tsk->flags & BCOM_FLAGS_ENABLE_TASK)
1969a322993SPhilippe De Muyter 		bcom_enable(tsk);
1979a322993SPhilippe De Muyter }
1989a322993SPhilippe De Muyter 
1999a322993SPhilippe De Muyter static inline void *
bcom_retrieve_buffer(struct bcom_task * tsk,u32 * p_status,struct bcom_bd ** p_bd)2009a322993SPhilippe De Muyter bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
2019a322993SPhilippe De Muyter {
2029a322993SPhilippe De Muyter 	void *cookie = tsk->cookie[tsk->outdex];
2039a322993SPhilippe De Muyter 	struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex);
2049a322993SPhilippe De Muyter 
2059a322993SPhilippe De Muyter 	if (p_status)
2069a322993SPhilippe De Muyter 		*p_status = bd->status;
2079a322993SPhilippe De Muyter 	if (p_bd)
2089a322993SPhilippe De Muyter 		*p_bd = bd;
2099a322993SPhilippe De Muyter 	tsk->outdex = _bcom_next_outdex(tsk);
2109a322993SPhilippe De Muyter 	return cookie;
2119a322993SPhilippe De Muyter }
2129a322993SPhilippe De Muyter 
2139a322993SPhilippe De Muyter #endif /* __BESTCOMM_H__ */
214