source: mainline/kernel/genarch/include/genarch/drivers/amdm37x/gpt.h@ 59a72f8

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 59a72f8 was 59a72f8, checked in by Jan Vesely <jano.vesely@…>, 13 years ago

arm32, bbxm: Ingore ghost interrupt

  • Property mode set to 100644
File size: 8.6 KB
Line 
1/*
2 * Copyright (c) 2012 Jan Vesely
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28/** @addtogroup genarch
29 * @{
30 */
31/**
32 * @file
33 * @brief Texas Instruments AM/DM37x MPU general purpose timer driver.
34 */
35
36#ifndef KERN_AMDM37x_GPT_H_
37#define KERN_AMDM37x_GPT_H_
38
39#include <typedefs.h>
40#include <mm/km.h>
41#include <time/clock.h>
42
43/* AMDM37x TRM p. 2740 */
44#define AMDM37x_GPT1_BASE_ADDRESS 0x48318000
45#define AMDM37x_GPT1_SIZE 4096
46#define AMDM37x_GPT1_IRQ 37
47#define AMDM37x_GPT2_BASE_ADDRESS 0x49032000
48#define AMDM37x_GPT2_SIZE 4096
49#define AMDM37x_GPT2_IRQ 38
50#define AMDM37x_GPT3_BASE_ADDRESS 0x49034000
51#define AMDM37x_GPT3_SIZE 4096
52#define AMDM37x_GPT3_IRQ 39
53#define AMDM37x_GPT4_BASE_ADDRESS 0x49036000
54#define AMDM37x_GPT4_SIZE 4096
55#define AMDM37x_GPT4_IRQ 40
56#define AMDM37x_GPT5_BASE_ADDRESS 0x49038000
57#define AMDM37x_GPT5_SIZE 4096
58#define AMDM37x_GPT5_IRQ 41
59#define AMDM37x_GPT6_BASE_ADDRESS 0x4903a000
60#define AMDM37x_GPT6_SIZE 4096
61#define AMDM37x_GPT6_IRQ 42
62#define AMDM37x_GPT7_BASE_ADDRESS 0x4903c000
63#define AMDM37x_GPT7_SIZE 4096
64#define AMDM37x_GPT7_IRQ 43
65#define AMDM37x_GPT8_BASE_ADDRESS 0x4903e000
66#define AMDM37x_GPT8_SIZE 4096
67#define AMDM37x_GPT8_IRQ 44
68#define AMDM37x_GPT9_BASE_ADDRESS 0x49040000
69#define AMDM37x_GPT9_SIZE 4096
70#define AMDM37x_GPT9_IRQ 45
71#define AMDM37x_GPT10_BASE_ADDRESS 0x48086000
72#define AMDM37x_GPT10_SIZE 4096
73#define AMDM37x_GPT10_IRQ 46
74#define AMDM37x_GPT11_BASE_ADDRESS 0x48088000
75#define AMDM37x_GPT11_SIZE 4096
76#define AMDM37x_GPT11_IRQ 47
77
78
79/** GPT register map AMDM37x TRM p. 2740 */
80typedef struct {
81 /** IP revision */
82 const ioport32_t tidr;
83#define AMDM37x_GPT_TIDR_MINOR_MASK (0xf)
84#define AMDM37x_GPT_TIDR_MINOR_SHIFT (0)
85#define AMDM37x_GPT_TIDR_MAJOR_MASK (0xf)
86#define AMDM37x_GPT_TIDR_MAJOR_SHIFT (4)
87 uint32_t padd0_[3];
88
89 /** L4 Interface parameters */
90 ioport32_t tiocp_cfg;
91#define AMDM37x_GPT_TIOCP_CFG_AUTOIDLE_FLAG (1 << 0)
92#define AMDM37x_GPT_TIOCP_CFG_SOFTRESET_FLAG (1 << 1)
93#define AMDM37x_GPT_TIOCP_CFG_ENWAKEUP_FLAG (1 << 2)
94#define AMDM37x_GPT_TIOCP_CFG_IDLEMODE_MASK (0x3)
95#define AMDM37x_GPT_TIOCP_CFG_IDLEMODE_SHIFT (3)
96#define AMDM37x_GPT_TIOCP_CFG_EMUFREE_FlAG (1 << 5)
97#define AMDM37x_GPT_TIOCP_CFG_CLOCKACTIVITY_MASK (0x3)
98#define AMDM37x_GPT_TIOCP_CFG_CLOCKACTIVITY_SHIFT (8)
99
100 /** Module status information, excluding irq */
101 const ioport32_t tistat;
102#define AMDM37x_GPT_TISTAT_RESET_DONE_FLAG (1 << 0)
103
104 /** Interrupt status register */
105 ioport32_t tisr;
106#define AMDM37x_GPT_TISR_MAT_IRQ_FLAG (1 << 0)
107#define AMDM37x_GPT_TISR_OVF_IRQ_FLAG (1 << 1)
108#define AMDM37x_GPT_TISR_TCAR_IRQ_FLAG (1 << 2)
109
110 /* Interrupt enable register */
111 ioport32_t tier;
112#define AMDM37x_GPT_TIER_MAT_IRQ_FLAG (1 << 0)
113#define AMDM37x_GPT_TIER_OVF_IRQ_FLAG (1 << 1)
114#define AMDM37x_GPT_TIER_TCAR_IRQ_FLAG (1 << 2)
115
116 /** Wakeup enable register */
117 ioport32_t twer;
118#define AMDM37x_GPT_TWER_MAT_IRQ_FLAG (1 << 0)
119#define AMDM37x_GPT_TWER_OVF_IRQ_FLAG (1 << 1)
120#define AMDM37x_GPT_TWER_TCAR_IRQ_FLAG (1 << 2)
121
122 /** Optional features control register */
123 ioport32_t tclr;
124#define AMDM37x_GPT_TCLR_ST_FLAG (1 << 0)
125#define AMDM37x_GPT_TCLR_AR_FLAG (1 << 1)
126#define AMDM37x_GPT_TCLR_PTV_MASK (0x7)
127#define AMDM37x_GPT_TCLR_PTV_SHIFT (2)
128#define AMDM37x_GPT_TCLR_PRE_FLAG (1 << 5)
129#define AMDM37x_GPT_TCLR_CE_FLAG (1 << 6)
130#define AMDM37x_GPT_TCLR_SCPWM (1 << 7)
131#define AMDM37x_GPT_TCLR_TCM_MASK (0x3 << 8)
132#define AMDM37x_GPT_TCLR_TCM_NO_CAPTURE (0x0 << 8)
133#define AMDM37x_GPT_TCLR_TCM_RAISE_CAPTURE (0x1 << 8)
134#define AMDM37x_GPT_TCLR_TCM_FALL_CAPTURE (0x2 << 8)
135#define AMDM37x_GPT_TCLR_TCM_BOTH_CAPTURE (0x3 << 8)
136#define AMDM37x_GPT_TCLR_TRG_MASK (0x3 << 10)
137#define AMDM37x_GPT_TCLR_TRG_NO (0x0 << 10)
138#define AMDM37x_GPT_TCLR_TRG_OVERFLOW (0x1 << 10)
139#define AMDM37x_GPT_TCLR_TRG_OVERMATCH (0x2 << 10)
140#define AMDM37x_GPT_TCLR_PT_FLAG (1 << 12)
141#define AMDM37x_GPT_TCLR_CAPT_MODE_FLAG (1 << 13)
142#define AMDM37x_GPT_TCLR_GPO_CFG_FLAG (1 << 14)
143
144 /** Value of timer counter */
145 ioport32_t tccr;
146
147 /** Timer load register */
148 ioport32_t tldr;
149
150 /** Timer trigger register */
151 ioport32_t ttgr;
152
153 /** Write-posted pending register */
154 const ioport32_t twps;
155#define AMDM37x_GPT_TWPS_TCLR_FLAG (1 << 0)
156#define AMDM37x_GPT_TWPS_TCRR_FLAG (1 << 1)
157#define AMDM37x_GPT_TWPS_TLDR_FLAG (1 << 2)
158#define AMDM37x_GPT_TWPS_TTGR_FLAG (1 << 3)
159#define AMDM37x_GPT_TWPS_TMAR_FLAG (1 << 4)
160#define AMDM37x_GPT_TWPS_TPIR_FLAG (1 << 5)
161#define AMDM37x_GPT_TWPS_TNIR_FLAG (1 << 6)
162#define AMDM37x_GPT_TWPS_TCVR_FLAG (1 << 7)
163#define AMDM37x_GPT_TWPS_TOCR_FLAG (1 << 8)
164#define AMDM37x_GPT_TWPS_TOWR_FLAG (1 << 9)
165
166 /** Timer match register */
167 ioport32_t tmar;
168
169 /** Capture value 1 register */
170 const ioport32_t tcar1;
171
172 /** Software interface control register */
173 ioport32_t tsicr;
174#define AMDM37x_GPT_TSICR_SFT_FLAG (1 << 1)
175#define AMDM37x_GPT_TSICR_POSTED_FLAG (1 << 2)
176
177 /** Capture value 2 register */
178 const ioport32_t tcar2;
179
180 /* GPT1,2,10 only (used for 1ms time period generation)*/
181
182 /** Positive increment register */
183 ioport32_t tpir;
184
185 /** Negative increment register */
186 ioport32_t tnir;
187
188 /** Counter value register */
189 ioport32_t tcvr;
190
191 /** Mask the tick interrupt for selected number of ticks */
192 ioport32_t tocr;
193
194 /** Number of masked overflow interrupts */
195 ioport32_t towr;
196} amdm37x_gpt_regs_t;
197
198typedef struct {
199 amdm37x_gpt_regs_t *regs;
200 bool special_available;
201} amdm37x_gpt_t;
202
203static inline void amdm37x_gpt_timer_ticks_init(
204 amdm37x_gpt_t* timer, uintptr_t ioregs, size_t iosize, unsigned hz)
205{
206 /* Set 32768 Hz clock as source */
207 // TODO find a nicer way to setup 32kHz clock source for timer1
208 // reg 0x48004C40 is CM_CLKSEL_WKUP see page 485 of the manual
209 ioport32_t *clksel = (void*) km_map(0x48004C40, 4, PAGE_NOT_CACHEABLE);
210 *clksel &= ~1;
211 km_unmap((uintptr_t)clksel, 4);
212
213 ASSERT(timer);
214 /* Map control register */
215 timer->regs = (void*) km_map(ioregs, iosize, PAGE_NOT_CACHEABLE);
216
217 /* Reset the timer */
218 timer->regs->tiocp_cfg |= AMDM37x_GPT_TIOCP_CFG_SOFTRESET_FLAG;
219
220 while (timer->regs->tistat & AMDM37x_GPT_TISTAT_RESET_DONE_FLAG);
221
222 /* Set autoreload */
223 timer->regs->tclr |= AMDM37x_GPT_TCLR_AR_FLAG;
224
225 timer->special_available = (
226 (ioregs == AMDM37x_GPT1_BASE_ADDRESS) ||
227 (ioregs == AMDM37x_GPT2_BASE_ADDRESS) ||
228 (ioregs == AMDM37x_GPT10_BASE_ADDRESS));
229 /* Select reload value */
230 timer->regs->tldr = 0xffffffff - (32768 / hz) + 1;
231 /* Set current counter value */
232 timer->regs->tccr = 0xffffffff - (32768 / hz) + 1;
233
234 if (timer->special_available) {
235 /* Set values according to formula (manual p. 2733) */
236 /* Use temporary variables for easier debugging */
237 const uint32_t tpir =
238 ((32768 / hz + 1) * 1000000) - (32768000L * (1000 / hz));
239 const uint32_t tnir =
240 ((32768 / hz) * 1000000) - (32768000L * (1000 / hz));
241 timer->regs->tpir = tpir;
242 timer->regs->tnir = tnir;
243 }
244
245}
246
247static inline void amdm37x_gpt_timer_ticks_start(amdm37x_gpt_t* timer)
248{
249 ASSERT(timer);
250 ASSERT(timer->regs);
251 /* Enable overflow interrupt */
252 timer->regs->tier |= AMDM37x_GPT_TIER_OVF_IRQ_FLAG;
253 /* Start timer */
254 timer->regs->tclr |= AMDM37x_GPT_TCLR_ST_FLAG;
255}
256
257static inline bool amdm37x_gpt_irq_ack(amdm37x_gpt_t* timer)
258{
259 ASSERT(timer);
260 ASSERT(timer->regs);
261 /* Clear all pending interrupts */
262 const uint32_t tisr = timer->regs->tisr;
263 timer->regs->tisr = tisr;
264 return tisr != 0;
265}
266
267#endif
268
269/**
270 * @}
271 */
Note: See TracBrowser for help on using the repository browser.