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