ar9300_timer.c revision 250003
1250003Sadrian/*
2250003Sadrian * Copyright (c) 2013 Qualcomm Atheros, Inc.
3250003Sadrian *
4250003Sadrian * Permission to use, copy, modify, and/or distribute this software for any
5250003Sadrian * purpose with or without fee is hereby granted, provided that the above
6250003Sadrian * copyright notice and this permission notice appear in all copies.
7250003Sadrian *
8250003Sadrian * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9250003Sadrian * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10250003Sadrian * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11250003Sadrian * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12250003Sadrian * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13250003Sadrian * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14250003Sadrian * PERFORMANCE OF THIS SOFTWARE.
15250003Sadrian */
16250003Sadrian
17250003Sadrian#include "opt_ah.h"
18250003Sadrian
19250003Sadrian#ifdef AH_SUPPORT_AR9300
20250003Sadrian
21250003Sadrian#include "ah.h"
22250003Sadrian#include "ah_internal.h"
23250003Sadrian
24250003Sadrian#include "ar9300/ar9300.h"
25250003Sadrian#include "ar9300/ar9300reg.h"
26250003Sadrian#include "ar9300/ar9300desc.h"
27250003Sadrian
28250003Sadriantypedef struct gen_timer_configuation {
29250003Sadrian    u_int32_t   next_addr;
30250003Sadrian    u_int32_t   period_addr;
31250003Sadrian    u_int32_t   mode_addr;
32250003Sadrian    u_int32_t   mode_mask;
33250003Sadrian}  GEN_TIMER_CONFIGURATION;
34250003Sadrian
35250003Sadrian#define AR_GEN_TIMERS2_CFG(num) \
36250003Sadrian    AR_GEN_TIMERS2_ ## num ## _NEXT, \
37250003Sadrian    AR_GEN_TIMERS2_ ## num ## _PERIOD, \
38250003Sadrian    AR_GEN_TIMERS2_MODE, \
39250003Sadrian    (1 << num)
40250003Sadrianstatic const GEN_TIMER_CONFIGURATION gen_timer_configuration[] =
41250003Sadrian{
42250003Sadrian    {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
43250003Sadrian    {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
44250003Sadrian    {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
45250003Sadrian    {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
46250003Sadrian    {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
47250003Sadrian    {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
48250003Sadrian    {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
49250003Sadrian    {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
50250003Sadrian    {AR_GEN_TIMERS2_CFG(0)},
51250003Sadrian    {AR_GEN_TIMERS2_CFG(1)},
52250003Sadrian    {AR_GEN_TIMERS2_CFG(2)},
53250003Sadrian    {AR_GEN_TIMERS2_CFG(3)},
54250003Sadrian    {AR_GEN_TIMERS2_CFG(4)},
55250003Sadrian    {AR_GEN_TIMERS2_CFG(5)},
56250003Sadrian    {AR_GEN_TIMERS2_CFG(6)},
57250003Sadrian    {AR_GEN_TIMERS2_CFG(7)}
58250003Sadrian};
59250003Sadrian
60250003Sadrian#define AR_GENTMR_BIT(_index)   (1 << (_index))
61250003Sadrian
62250003Sadrianint
63250003Sadrianar9300_alloc_generic_timer(struct ath_hal *ah, HAL_GEN_TIMER_DOMAIN tsf)
64250003Sadrian{
65250003Sadrian    struct ath_hal_9300 *ahp = AH9300(ah);
66250003Sadrian    u_int32_t           i, mask;
67250003Sadrian    u_int32_t           avail_timer_start, avail_timer_end;
68250003Sadrian
69250003Sadrian    if (tsf == HAL_GEN_TIMER_TSF) {
70250003Sadrian        avail_timer_start = AR_FIRST_NDP_TIMER;
71250003Sadrian        avail_timer_end = AR_GEN_TIMER_BANK_1_LEN;
72250003Sadrian    } else {
73250003Sadrian        avail_timer_start = AR_GEN_TIMER_BANK_1_LEN;
74250003Sadrian        avail_timer_end = AR_NUM_GEN_TIMERS;
75250003Sadrian    }
76250003Sadrian
77250003Sadrian    /* Find the first availabe timer index */
78250003Sadrian    i = avail_timer_start;
79250003Sadrian    mask = ahp->ah_avail_gen_timers >> i;
80250003Sadrian    for ( ; mask && (i < avail_timer_end) ; mask >>= 1, i++ ) {
81250003Sadrian        if (mask & 0x1) {
82250003Sadrian            ahp->ah_avail_gen_timers &= ~(AR_GENTMR_BIT(i));
83250003Sadrian
84250003Sadrian            if ((tsf == HAL_GEN_TIMER_TSF2) && !ahp->ah_enable_tsf2) {
85250003Sadrian                ahp->ah_enable_tsf2 = AH_TRUE;
86250003Sadrian                ar9300_start_tsf2(ah);
87250003Sadrian            }
88250003Sadrian            return i;
89250003Sadrian        }
90250003Sadrian    }
91250003Sadrian    return -1;
92250003Sadrian}
93250003Sadrian
94250003Sadrianvoid ar9300_start_tsf2(struct ath_hal *ah)
95250003Sadrian{
96250003Sadrian    struct ath_hal_9300 *ahp = AH9300(ah);
97250003Sadrian
98250003Sadrian    if (ahp->ah_enable_tsf2) {
99250003Sadrian        /* Delay might be needed after TSF2 reset */
100250003Sadrian        OS_REG_SET_BIT(ah, AR_DIRECT_CONNECT, AR_DC_AP_STA_EN);
101250003Sadrian        OS_REG_SET_BIT(ah, AR_RESET_TSF, AR_RESET_TSF2_ONCE);
102250003Sadrian    }
103250003Sadrian}
104250003Sadrian
105250003Sadrianvoid
106250003Sadrianar9300_free_generic_timer(struct ath_hal *ah, int index)
107250003Sadrian{
108250003Sadrian    struct ath_hal_9300 *ahp = AH9300(ah);
109250003Sadrian
110250003Sadrian    ar9300_stop_generic_timer(ah, index);
111250003Sadrian    ahp->ah_avail_gen_timers |= AR_GENTMR_BIT(index);
112250003Sadrian}
113250003Sadrian
114250003Sadrianvoid
115250003Sadrianar9300_start_generic_timer(
116250003Sadrian    struct ath_hal *ah,
117250003Sadrian    int index,
118250003Sadrian    u_int32_t timer_next,
119250003Sadrian    u_int32_t timer_period)
120250003Sadrian{
121250003Sadrian    if ((index < AR_FIRST_NDP_TIMER) || (index >= AR_NUM_GEN_TIMERS)) {
122250003Sadrian        return;
123250003Sadrian    }
124250003Sadrian
125250003Sadrian    /*
126250003Sadrian     * Program generic timer registers
127250003Sadrian     */
128250003Sadrian    OS_REG_WRITE(ah, gen_timer_configuration[index].next_addr, timer_next);
129250003Sadrian    OS_REG_WRITE(ah, gen_timer_configuration[index].period_addr, timer_period);
130250003Sadrian    OS_REG_SET_BIT(ah,
131250003Sadrian        gen_timer_configuration[index].mode_addr,
132250003Sadrian        gen_timer_configuration[index].mode_mask);
133250003Sadrian
134250003Sadrian    if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
135250003Sadrian        /*
136250003Sadrian         * Starting from Jupiter, each generic timer can select which tsf to
137250003Sadrian         * use. But we still follow the old rule, 0 - 7 use tsf and 8 - 15
138250003Sadrian         * use tsf2.
139250003Sadrian         */
140250003Sadrian        if ((index < AR_GEN_TIMER_BANK_1_LEN)) {
141250003Sadrian            OS_REG_CLR_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, (1 << index));
142250003Sadrian        }
143250003Sadrian        else {
144250003Sadrian            OS_REG_SET_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, (1 << index));
145250003Sadrian        }
146250003Sadrian    }
147250003Sadrian
148250003Sadrian    /* Enable both trigger and thresh interrupt masks */
149250003Sadrian    OS_REG_SET_BIT(ah, AR_IMR_S5,
150250003Sadrian                   (SM(AR_GENTMR_BIT(index), AR_IMR_S5_GENTIMER_THRESH) |
151250003Sadrian                    SM(AR_GENTMR_BIT(index), AR_IMR_S5_GENTIMER_TRIG)));
152250003Sadrian}
153250003Sadrian
154250003Sadrianvoid
155250003Sadrianar9300_stop_generic_timer(struct ath_hal *ah, int index)
156250003Sadrian{
157250003Sadrian    if ((index < AR_FIRST_NDP_TIMER) || (index >= AR_NUM_GEN_TIMERS)) {
158250003Sadrian        return;
159250003Sadrian    }
160250003Sadrian
161250003Sadrian    /*
162250003Sadrian     * Clear generic timer enable bits.
163250003Sadrian     */
164250003Sadrian    OS_REG_CLR_BIT(ah,
165250003Sadrian        gen_timer_configuration[index].mode_addr,
166250003Sadrian        gen_timer_configuration[index].mode_mask);
167250003Sadrian
168250003Sadrian    /* Disable both trigger and thresh interrupt masks */
169250003Sadrian    OS_REG_CLR_BIT(ah, AR_IMR_S5,
170250003Sadrian                   (SM(AR_GENTMR_BIT(index), AR_IMR_S5_GENTIMER_THRESH) |
171250003Sadrian                    SM(AR_GENTMR_BIT(index), AR_IMR_S5_GENTIMER_TRIG)));
172250003Sadrian}
173250003Sadrian
174250003Sadrianvoid
175250003Sadrianar9300_get_gen_timer_interrupts(
176250003Sadrian    struct ath_hal *ah,
177250003Sadrian    u_int32_t *trigger,
178250003Sadrian    u_int32_t *thresh)
179250003Sadrian{
180250003Sadrian    struct ath_hal_9300 *ahp = AH9300(ah);
181250003Sadrian    *trigger = ahp->ah_intr_gen_timer_trigger;
182250003Sadrian    *thresh = ahp->ah_intr_gen_timer_thresh;
183250003Sadrian}
184250003Sadrian
185250003Sadrian#endif /* AH_SUPPORT_AR9300 */
186