2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
20 #include "ah_internal.h"
22 #include "ar9300/ar9300.h"
23 #include "ar9300/ar9300reg.h"
24 #include "ar9300/ar9300desc.h"
26 typedef struct gen_timer_configuation {
28 u_int32_t period_addr;
31 } GEN_TIMER_CONFIGURATION;
33 #define AR_GEN_TIMERS2_CFG(num) \
34 AR_GEN_TIMERS2_ ## num ## _NEXT, \
35 AR_GEN_TIMERS2_ ## num ## _PERIOD, \
36 AR_GEN_TIMERS2_MODE, \
38 static const GEN_TIMER_CONFIGURATION gen_timer_configuration[] =
40 {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
41 {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
42 {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
43 {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
44 {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
45 {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
46 {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
47 {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
48 {AR_GEN_TIMERS2_CFG(0)},
49 {AR_GEN_TIMERS2_CFG(1)},
50 {AR_GEN_TIMERS2_CFG(2)},
51 {AR_GEN_TIMERS2_CFG(3)},
52 {AR_GEN_TIMERS2_CFG(4)},
53 {AR_GEN_TIMERS2_CFG(5)},
54 {AR_GEN_TIMERS2_CFG(6)},
55 {AR_GEN_TIMERS2_CFG(7)}
58 #define AR_GENTMR_BIT(_index) (1 << (_index))
61 ar9300_alloc_generic_timer(struct ath_hal *ah, HAL_GEN_TIMER_DOMAIN tsf)
63 struct ath_hal_9300 *ahp = AH9300(ah);
65 u_int32_t avail_timer_start, avail_timer_end;
67 if (tsf == HAL_GEN_TIMER_TSF) {
68 avail_timer_start = AR_FIRST_NDP_TIMER;
69 avail_timer_end = AR_GEN_TIMER_BANK_1_LEN;
71 avail_timer_start = AR_GEN_TIMER_BANK_1_LEN;
72 avail_timer_end = AR_NUM_GEN_TIMERS;
75 /* Find the first availabe timer index */
76 i = avail_timer_start;
77 mask = ahp->ah_avail_gen_timers >> i;
78 for ( ; mask && (i < avail_timer_end) ; mask >>= 1, i++ ) {
80 ahp->ah_avail_gen_timers &= ~(AR_GENTMR_BIT(i));
82 if ((tsf == HAL_GEN_TIMER_TSF2) && !ahp->ah_enable_tsf2) {
83 ahp->ah_enable_tsf2 = AH_TRUE;
84 ar9300_start_tsf2(ah);
92 void ar9300_start_tsf2(struct ath_hal *ah)
94 struct ath_hal_9300 *ahp = AH9300(ah);
96 if (ahp->ah_enable_tsf2) {
97 /* Delay might be needed after TSF2 reset */
98 OS_REG_SET_BIT(ah, AR_DIRECT_CONNECT, AR_DC_AP_STA_EN);
99 OS_REG_SET_BIT(ah, AR_RESET_TSF, AR_RESET_TSF2_ONCE);
104 ar9300_free_generic_timer(struct ath_hal *ah, int index)
106 struct ath_hal_9300 *ahp = AH9300(ah);
108 ar9300_stop_generic_timer(ah, index);
109 ahp->ah_avail_gen_timers |= AR_GENTMR_BIT(index);
113 ar9300_start_generic_timer(
116 u_int32_t timer_next,
117 u_int32_t timer_period)
119 if ((index < AR_FIRST_NDP_TIMER) || (index >= AR_NUM_GEN_TIMERS)) {
124 * Program generic timer registers
126 OS_REG_WRITE(ah, gen_timer_configuration[index].next_addr, timer_next);
127 OS_REG_WRITE(ah, gen_timer_configuration[index].period_addr, timer_period);
129 gen_timer_configuration[index].mode_addr,
130 gen_timer_configuration[index].mode_mask);
132 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
134 * Starting from Jupiter, each generic timer can select which tsf to
135 * use. But we still follow the old rule, 0 - 7 use tsf and 8 - 15
138 if ((index < AR_GEN_TIMER_BANK_1_LEN)) {
139 OS_REG_CLR_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, (1 << index));
142 OS_REG_SET_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, (1 << index));
146 /* Enable both trigger and thresh interrupt masks */
147 OS_REG_SET_BIT(ah, AR_IMR_S5,
148 (SM(AR_GENTMR_BIT(index), AR_IMR_S5_GENTIMER_THRESH) |
149 SM(AR_GENTMR_BIT(index), AR_IMR_S5_GENTIMER_TRIG)));
153 ar9300_stop_generic_timer(struct ath_hal *ah, int index)
155 if ((index < AR_FIRST_NDP_TIMER) || (index >= AR_NUM_GEN_TIMERS)) {
160 * Clear generic timer enable bits.
163 gen_timer_configuration[index].mode_addr,
164 gen_timer_configuration[index].mode_mask);
166 /* Disable both trigger and thresh interrupt masks */
167 OS_REG_CLR_BIT(ah, AR_IMR_S5,
168 (SM(AR_GENTMR_BIT(index), AR_IMR_S5_GENTIMER_THRESH) |
169 SM(AR_GENTMR_BIT(index), AR_IMR_S5_GENTIMER_TRIG)));
173 ar9300_get_gen_timer_interrupts(
178 struct ath_hal_9300 *ahp = AH9300(ah);
179 *trigger = ahp->ah_intr_gen_timer_trigger;
180 *thresh = ahp->ah_intr_gen_timer_thresh;