The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/ath/ath_hal/ar9300/ar9300_timer.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
    3  *
    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.
    7  *
    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.
   15  */
   16 
   17 #include "opt_ah.h"
   18 
   19 #include "ah.h"
   20 #include "ah_internal.h"
   21 
   22 #include "ar9300/ar9300.h"
   23 #include "ar9300/ar9300reg.h"
   24 #include "ar9300/ar9300desc.h"
   25 
   26 typedef struct gen_timer_configuation {
   27     u_int32_t   next_addr;
   28     u_int32_t   period_addr;
   29     u_int32_t   mode_addr;
   30     u_int32_t   mode_mask;
   31 }  GEN_TIMER_CONFIGURATION;
   32 
   33 #define AR_GEN_TIMERS2_CFG(num) \
   34     AR_GEN_TIMERS2_ ## num ## _NEXT, \
   35     AR_GEN_TIMERS2_ ## num ## _PERIOD, \
   36     AR_GEN_TIMERS2_MODE, \
   37     (1 << num)
   38 static const GEN_TIMER_CONFIGURATION gen_timer_configuration[] =
   39 {
   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)}
   56 };
   57 
   58 #define AR_GENTMR_BIT(_index)   (1 << (_index))
   59 
   60 int
   61 ar9300_alloc_generic_timer(struct ath_hal *ah, HAL_GEN_TIMER_DOMAIN tsf)
   62 {
   63     struct ath_hal_9300 *ahp = AH9300(ah);
   64     u_int32_t           i, mask;
   65     u_int32_t           avail_timer_start, avail_timer_end;
   66 
   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;
   70     } else {
   71         avail_timer_start = AR_GEN_TIMER_BANK_1_LEN;
   72         avail_timer_end = AR_NUM_GEN_TIMERS;
   73     }
   74 
   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++ ) {
   79         if (mask & 0x1) {
   80             ahp->ah_avail_gen_timers &= ~(AR_GENTMR_BIT(i));
   81 
   82             if ((tsf == HAL_GEN_TIMER_TSF2) && !ahp->ah_enable_tsf2) {
   83                 ahp->ah_enable_tsf2 = AH_TRUE;
   84                 ar9300_start_tsf2(ah);
   85             }
   86             return i;
   87         }
   88     }
   89     return -1;
   90 }
   91 
   92 void ar9300_start_tsf2(struct ath_hal *ah)
   93 {
   94     struct ath_hal_9300 *ahp = AH9300(ah);
   95 
   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);
  100     }
  101 }
  102 
  103 void
  104 ar9300_free_generic_timer(struct ath_hal *ah, int index)
  105 {
  106     struct ath_hal_9300 *ahp = AH9300(ah);
  107 
  108     ar9300_stop_generic_timer(ah, index);
  109     ahp->ah_avail_gen_timers |= AR_GENTMR_BIT(index);
  110 }
  111 
  112 void
  113 ar9300_start_generic_timer(
  114     struct ath_hal *ah,
  115     int index,
  116     u_int32_t timer_next,
  117     u_int32_t timer_period)
  118 {
  119     if ((index < AR_FIRST_NDP_TIMER) || (index >= AR_NUM_GEN_TIMERS)) {
  120         return;
  121     }
  122 
  123     /*
  124      * Program generic timer registers
  125      */
  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);
  128     OS_REG_SET_BIT(ah,
  129         gen_timer_configuration[index].mode_addr,
  130         gen_timer_configuration[index].mode_mask);
  131 
  132     if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
  133         /*
  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
  136          * use tsf2.
  137          */
  138         if ((index < AR_GEN_TIMER_BANK_1_LEN)) {
  139             OS_REG_CLR_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, (1 << index));
  140         }
  141         else {
  142             OS_REG_SET_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, (1 << index));
  143         }
  144     }
  145 
  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)));
  150 }
  151 
  152 void
  153 ar9300_stop_generic_timer(struct ath_hal *ah, int index)
  154 {
  155     if ((index < AR_FIRST_NDP_TIMER) || (index >= AR_NUM_GEN_TIMERS)) {
  156         return;
  157     }
  158 
  159     /*
  160      * Clear generic timer enable bits.
  161      */
  162     OS_REG_CLR_BIT(ah,
  163         gen_timer_configuration[index].mode_addr,
  164         gen_timer_configuration[index].mode_mask);
  165 
  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)));
  170 }
  171 
  172 void
  173 ar9300_get_gen_timer_interrupts(
  174     struct ath_hal *ah,
  175     u_int32_t *trigger,
  176     u_int32_t *thresh)
  177 {
  178     struct ath_hal_9300 *ahp = AH9300(ah);
  179     *trigger = ahp->ah_intr_gen_timer_trigger;
  180     *thresh = ahp->ah_intr_gen_timer_thresh;
  181 }

Cache object: b7ca7df11782734bcc8c4a57e63047db


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.