1/*-
2 * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * This software is derived from software provide by Kwikbyte who specifically
25 * disclaimed copyright on the code.
26 *
27 * $FreeBSD$
28 */
29
30#ifndef __LIBAT91RM9200_H
31#define __LIBAT91RM9200_H
32
33#include "at91rm9200.h"
34
35//*----------------------------------------------------------------------------
36//* \fn    AT91F_PMC_EnablePeriphClock
37//* \brief Enable peripheral clock
38//*----------------------------------------------------------------------------
39static inline void
40AT91F_PMC_EnablePeriphClock (
41       AT91PS_PMC pPMC, // \arg pointer to PMC controller
42       unsigned int periphIds)  // \arg IDs of peripherals to enable
43{
44       pPMC->PMC_PCER = periphIds;
45}
46
47/* *****************************************************************************
48                SOFTWARE API FOR PIO
49   ***************************************************************************** */
50//*----------------------------------------------------------------------------
51//* \fn    AT91F_PIO_CfgPeriph
52//* \brief Enable pins to be drived by peripheral
53//*----------------------------------------------------------------------------
54static inline
55void AT91F_PIO_CfgPeriph(
56	AT91PS_PIO pPio,             // \arg pointer to a PIO controller
57	unsigned int periphAEnable,  // \arg PERIPH A to enable
58	unsigned int periphBEnable)  // \arg PERIPH B to enable
59
60{
61	if (periphAEnable)
62		pPio->PIO_ASR = periphAEnable;
63	if (periphBEnable)
64		pPio->PIO_BSR = periphBEnable;
65	pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode
66}
67
68/* *****************************************************************************
69                SOFTWARE API FOR MCI
70   ***************************************************************************** */
71//* Classic MCI Data Timeout Register Configuration with 1048576 MCK cycles between 2 data transfer
72#define AT91C_MCI_DTOR_1MEGA_CYCLES	(AT91C_MCI_DTOCYC | AT91C_MCI_DTOMUL)
73
74//* Classic MCI SDCard Register Configuration with 1-bit data bus on slot A
75#define AT91C_MCI_MMC_SLOTA	(AT91C_MCI_SCDSEL & 0x0)
76
77//* Classic MCI SDCard Register Configuration with 1-bit data bus on slot B
78#define AT91C_MCI_MMC_SLOTB	(AT91C_MCI_SCDSEL)
79
80//* Classic MCI SDCard Register Configuration with 4-bit data bus on slot A
81#define AT91C_MCI_SDCARD_4BITS_SLOTA	( (AT91C_MCI_SCDSEL & 0x0) | AT91C_MCI_SCDBUS )
82
83//* Classic MCI SDCard Register Configuration with 4-bit data bus on slot B
84#define AT91C_MCI_SDCARD_4BITS_SLOTB	(AT91C_MCI_SCDSEL | AT91C_MCI_SCDBUS)
85
86
87
88//*----------------------------------------------------------------------------
89//* \fn    AT91F_MCI_Configure
90//* \brief Configure the MCI
91//*----------------------------------------------------------------------------
92static inline
93void AT91F_MCI_Configure(
94        AT91PS_MCI pMCI,  			 // \arg pointer to a MCI controller
95        unsigned int DTOR_register,  // \arg Data Timeout Register to be programmed
96        unsigned int MR_register,  	 // \arg Mode Register to be programmed
97        unsigned int SDCR_register)  // \arg SDCard Register to be programmed
98{
99    //* Reset the MCI
100    pMCI->MCI_CR = AT91C_MCI_MCIEN | AT91C_MCI_PWSEN;
101
102    //* Disable all the interrupts
103    pMCI->MCI_IDR = 0xFFFFFFFF;
104
105    //* Set the Data Timeout Register
106    pMCI->MCI_DTOR = DTOR_register;
107
108    //* Set the Mode Register
109    pMCI->MCI_MR = MR_register;
110
111    //* Set the SDCard Register
112    pMCI->MCI_SDCR = SDCR_register;
113}
114
115//*----------------------------------------------------------------------------
116//* \fn    AT91F_MCI_CfgPMC
117//* \brief Enable Peripheral clock in PMC for  MCI
118//*----------------------------------------------------------------------------
119static inline void
120AT91F_MCI_CfgPMC(void)
121{
122	AT91F_PMC_EnablePeriphClock(
123		AT91C_BASE_PMC, // PIO controller base address
124		((unsigned int) 1 << AT91C_ID_MCI));
125}
126
127//*----------------------------------------------------------------------------
128//* \fn    AT91F_MCI_CfgPIO
129//* \brief Configure PIO controllers to drive MCI signals
130//*----------------------------------------------------------------------------
131static inline void
132AT91F_MCI_CfgPIO(void)
133{
134	// Configure PIO controllers to periph mode
135	AT91F_PIO_CfgPeriph(
136		AT91C_BASE_PIOA, // PIO controller base address
137		((unsigned int) AT91C_PIO_PA28   ) |
138		((unsigned int) AT91C_PIO_PA29   ) |
139		((unsigned int) AT91C_PIO_PA27    ), // Peripheral A
140		0); // Peripheral B
141	// Configure PIO controllers to periph mode
142	AT91F_PIO_CfgPeriph(
143		AT91C_BASE_PIOB, // PIO controller base address
144		0, // Peripheral A
145		((unsigned int) AT91C_PIO_PB5   ) |
146		((unsigned int) AT91C_PIO_PB3   ) |
147		((unsigned int) AT91C_PIO_PB4   )); // Peripheral B
148}
149
150
151/* *****************************************************************************
152                SOFTWARE API FOR PDC
153   ***************************************************************************** */
154//*----------------------------------------------------------------------------
155//* \fn    AT91F_PDC_SetNextRx
156//* \brief Set the next receive transfer descriptor
157//*----------------------------------------------------------------------------
158static inline void
159AT91F_PDC_SetNextRx (
160	AT91PS_PDC pPDC,     // \arg pointer to a PDC controller
161	char *address,       // \arg address to the next bloc to be received
162	unsigned int bytes)  // \arg number of bytes to be received
163{
164	pPDC->PDC_RNPR = (unsigned int) address;
165	pPDC->PDC_RNCR = bytes;
166}
167
168//*----------------------------------------------------------------------------
169//* \fn    AT91F_PDC_SetNextTx
170//* \brief Set the next transmit transfer descriptor
171//*----------------------------------------------------------------------------
172static inline void
173AT91F_PDC_SetNextTx(
174	AT91PS_PDC pPDC,       // \arg pointer to a PDC controller
175	char *address,         // \arg address to the next bloc to be transmitted
176	unsigned int bytes)    // \arg number of bytes to be transmitted
177{
178	pPDC->PDC_TNPR = (unsigned int) address;
179	pPDC->PDC_TNCR = bytes;
180}
181
182//*----------------------------------------------------------------------------
183//* \fn    AT91F_PDC_SetRx
184//* \brief Set the receive transfer descriptor
185//*----------------------------------------------------------------------------
186static inline void
187AT91F_PDC_SetRx(
188	AT91PS_PDC pPDC,       // \arg pointer to a PDC controller
189	char *address,         // \arg address to the next bloc to be received
190	unsigned int bytes)    // \arg number of bytes to be received
191{
192	pPDC->PDC_RPR = (unsigned int) address;
193	pPDC->PDC_RCR = bytes;
194}
195
196//*----------------------------------------------------------------------------
197//* \fn    AT91F_PDC_SetTx
198//* \brief Set the transmit transfer descriptor
199//*----------------------------------------------------------------------------
200static inline void
201AT91F_PDC_SetTx(
202	AT91PS_PDC pPDC,       // \arg pointer to a PDC controller
203	char *address,         // \arg address to the next bloc to be transmitted
204	unsigned int bytes)    // \arg number of bytes to be transmitted
205{
206	pPDC->PDC_TPR = (unsigned int) address;
207	pPDC->PDC_TCR = bytes;
208}
209
210//*----------------------------------------------------------------------------
211//* \fn    AT91F_PDC_EnableTx
212//* \brief Enable transmit
213//*----------------------------------------------------------------------------
214static inline void
215AT91F_PDC_EnableTx(
216	AT91PS_PDC pPDC )       // \arg pointer to a PDC controller
217{
218	pPDC->PDC_PTCR = AT91C_PDC_TXTEN;
219}
220
221//*----------------------------------------------------------------------------
222//* \fn    AT91F_PDC_EnableRx
223//* \brief Enable receive
224//*----------------------------------------------------------------------------
225static inline void
226AT91F_PDC_EnableRx(
227	AT91PS_PDC pPDC )       // \arg pointer to a PDC controller
228{
229	pPDC->PDC_PTCR = AT91C_PDC_RXTEN;
230}
231
232//*----------------------------------------------------------------------------
233//* \fn    AT91F_PDC_DisableTx
234//* \brief Disable transmit
235//*----------------------------------------------------------------------------
236static inline void
237AT91F_PDC_DisableTx(
238	AT91PS_PDC pPDC )       // \arg pointer to a PDC controller
239{
240	pPDC->PDC_PTCR = AT91C_PDC_TXTDIS;
241}
242
243//*----------------------------------------------------------------------------
244//* \fn    AT91F_PDC_DisableRx
245//* \brief Disable receive
246//*----------------------------------------------------------------------------
247static inline void
248AT91F_PDC_DisableRx(
249	AT91PS_PDC pPDC )       // \arg pointer to a PDC controller
250{
251	pPDC->PDC_PTCR = AT91C_PDC_RXTDIS;
252}
253
254//*----------------------------------------------------------------------------
255//* \fn    AT91F_PDC_Open
256//* \brief Open PDC: disable TX and RX reset transfer descriptors, re-enable RX and TX
257//*----------------------------------------------------------------------------
258static inline void
259AT91F_PDC_Open(
260	AT91PS_PDC pPDC)       // \arg pointer to a PDC controller
261{
262    //* Disable the RX and TX PDC transfer requests
263	AT91F_PDC_DisableRx(pPDC);
264	AT91F_PDC_DisableTx(pPDC);
265
266	//* Reset all Counter register Next buffer first
267	AT91F_PDC_SetNextTx(pPDC, (char *) 0, 0);
268	AT91F_PDC_SetNextRx(pPDC, (char *) 0, 0);
269	AT91F_PDC_SetTx(pPDC, (char *) 0, 0);
270	AT91F_PDC_SetRx(pPDC, (char *) 0, 0);
271
272    //* Enable the RX and TX PDC transfer requests
273	AT91F_PDC_EnableRx(pPDC);
274	AT91F_PDC_EnableTx(pPDC);
275}
276
277#endif
278