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/alpine-hal/al_hal_iofic.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 *******************************************************************************
    3 Copyright (C) 2015 Annapurna Labs Ltd.
    4 
    5 This file may be licensed under the terms of the Annapurna Labs Commercial
    6 License Agreement.
    7 
    8 Alternatively, this file can be distributed under the terms of the GNU General
    9 Public License V2 as published by the Free Software Foundation and can be
   10 found at http://www.gnu.org/licenses/gpl-2.0.html
   11 
   12 Alternatively, redistribution and use in source and binary forms, with or
   13 without modification, are permitted provided that the following conditions are
   14 met:
   15 
   16     *     Redistributions of source code must retain the above copyright notice,
   17 this list of conditions and the following disclaimer.
   18 
   19     *     Redistributions in binary form must reproduce the above copyright
   20 notice, this list of conditions and the following disclaimer in
   21 the documentation and/or other materials provided with the
   22 distribution.
   23 
   24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   25 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
   28 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
   31 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   34 
   35 *******************************************************************************/
   36 
   37 /**
   38  *  @{
   39  * @file   al_hal_iofic.c
   40  *
   41  * @brief  interrupt controller hal
   42  *
   43  */
   44 
   45 #include "al_hal_iofic.h"
   46 #include "al_hal_iofic_regs.h"
   47 
   48 /*
   49  * configure the interrupt registers, interrupts will are kept masked
   50  */
   51 int al_iofic_config(void __iomem *regs_base, int group, uint32_t flags)
   52 {
   53         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
   54 
   55         al_assert(regs_base);
   56         al_assert(group < AL_IOFIC_MAX_GROUPS);
   57 
   58         al_reg_write32(&regs->ctrl[group].int_control_grp, flags);
   59 
   60         return 0;
   61 }
   62 
   63 /*
   64  * configure the moderation timer resolution for a given group
   65  */
   66 int al_iofic_moder_res_config(void __iomem *regs_base, int group,
   67                              uint8_t resolution)
   68 
   69 {
   70         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
   71         uint32_t reg;
   72 
   73         al_assert(regs_base);
   74         al_assert(group < AL_IOFIC_MAX_GROUPS);
   75 
   76         reg = al_reg_read32(&regs->ctrl[group].int_control_grp);
   77         AL_REG_FIELD_SET(reg,
   78                          INT_CONTROL_GRP_MOD_RES_MASK,
   79                          INT_CONTROL_GRP_MOD_RES_SHIFT,
   80                          resolution);
   81         al_reg_write32(&regs->ctrl[group].int_control_grp, reg);
   82 
   83         return 0;
   84 }
   85 
   86 /*
   87  * configure the moderation timer interval for a given legacy interrupt group
   88  */
   89 int al_iofic_legacy_moder_interval_config(void __iomem *regs_base, int group,
   90                                      uint8_t interval)
   91 {
   92         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
   93         uint32_t reg;
   94 
   95         al_assert(regs_base);
   96         al_assert(group < AL_IOFIC_MAX_GROUPS);
   97 
   98         reg = al_reg_read32(&regs->ctrl[group].int_control_grp);
   99         AL_REG_FIELD_SET(reg,
  100                          INT_CONTROL_GRP_MOD_INTV_MASK,
  101                          INT_CONTROL_GRP_MOD_INTV_SHIFT,
  102                          interval);
  103         al_reg_write32(&regs->ctrl[group].int_control_grp, reg);
  104 
  105         return 0;
  106 }
  107 
  108 
  109 /*
  110  * configure the moderation timer interval for a given msix vector.
  111  */
  112 int al_iofic_msix_moder_interval_config(void __iomem *regs_base, int group,
  113                                        uint8_t vector, uint8_t interval)
  114 {
  115         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
  116         uint32_t reg;
  117 
  118         al_assert(regs_base);
  119         al_assert(group < AL_IOFIC_MAX_GROUPS);
  120 
  121         reg = al_reg_read32(&regs->grp_int_mod[group][vector].grp_int_mod_reg);
  122         AL_REG_FIELD_SET(reg,
  123                          INT_MOD_INTV_MASK,
  124                          INT_MOD_INTV_SHIFT,
  125                          interval);
  126         al_reg_write32(&regs->grp_int_mod[group][vector].grp_int_mod_reg, reg);
  127 
  128         return 0;
  129 }
  130 
  131 /*
  132  * configure the target-id attributes for a given msix vector.
  133  */
  134 int al_iofic_msix_tgtid_attributes_config(void __iomem *regs_base, int group,
  135                                        uint8_t vector, uint32_t tgtid, uint8_t tgtid_en)
  136 {
  137         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
  138         uint32_t reg = 0;
  139 
  140         al_assert(regs_base);
  141         al_assert(group < AL_IOFIC_MAX_GROUPS);
  142 
  143         AL_REG_FIELD_SET(reg,
  144                          INT_MSIX_TGTID_MASK,
  145                          INT_MSIX_TGTID_SHIFT,
  146                          tgtid);
  147         AL_REG_BIT_VAL_SET(reg,
  148                          INT_MSIX_TGTID_EN_SHIFT,
  149                          tgtid_en);
  150 
  151         al_reg_write32(&regs->grp_int_mod[group][vector].grp_int_tgtid_reg, reg);
  152 
  153         return 0;
  154 }
  155 
  156 /*
  157  * return the offset of the unmask register for a given group
  158  */
  159 uint32_t __iomem * al_iofic_unmask_offset_get(void __iomem *regs_base, int group)
  160 {
  161         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
  162 
  163         al_assert(regs_base);
  164         al_assert(group < AL_IOFIC_MAX_GROUPS);
  165 
  166         return &regs->ctrl[group].int_mask_clear_grp;
  167 }
  168 
  169 
  170 /*
  171  * unmask specific interrupts for a given group
  172  */
  173 void al_iofic_unmask(void __iomem *regs_base, int group, uint32_t mask)
  174 {
  175         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
  176 
  177         al_assert(regs_base);
  178         al_assert(group < AL_IOFIC_MAX_GROUPS);
  179 
  180         /*
  181          * use the mask clear register, no need to read the mask register
  182          * itself. write 0 to unmask, 1 has no effect
  183          */
  184         al_reg_write32_relaxed(&regs->ctrl[group].int_mask_clear_grp, ~mask);
  185 }
  186 
  187 /*
  188  * mask specific interrupts for a given group
  189  */
  190 void al_iofic_mask(void __iomem *regs_base, int group, uint32_t mask)
  191 {
  192         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
  193         uint32_t reg;
  194 
  195         al_assert(regs_base);
  196         al_assert(group < AL_IOFIC_MAX_GROUPS);
  197 
  198         reg = al_reg_read32(&regs->ctrl[group].int_mask_grp);
  199 
  200         al_reg_write32(&regs->ctrl[group].int_mask_grp, reg | mask);
  201 }
  202 
  203 /*
  204  * read the mask for a given group
  205  */
  206 uint32_t al_iofic_read_mask(void __iomem *regs_base, int group)
  207 {
  208         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
  209 
  210         al_assert(regs_base);
  211         al_assert(group < AL_IOFIC_MAX_GROUPS);
  212 
  213         return al_reg_read32(&regs->ctrl[group].int_mask_grp);
  214 }
  215 
  216 /*
  217  * read interrupt cause register for a given group
  218  */
  219 uint32_t al_iofic_read_cause(void __iomem *regs_base, int group)
  220 {
  221         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
  222 
  223         al_assert(regs_base);
  224         al_assert(group < AL_IOFIC_MAX_GROUPS);
  225 
  226         return al_reg_read32(&regs->ctrl[group].int_cause_grp);
  227 }
  228 
  229 /*
  230  * clear bits in the interrupt cause register for a given group
  231  */
  232 void al_iofic_clear_cause(void __iomem *regs_base, int group, uint32_t mask)
  233 {
  234         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
  235 
  236         al_assert(regs_base);
  237         al_assert(group < AL_IOFIC_MAX_GROUPS);
  238 
  239         /* inverse mask, writing 1 has no effect */
  240         al_reg_write32(&regs->ctrl[group].int_cause_grp, ~mask);
  241 }
  242 
  243 /*
  244  * Set the cause register for a given group
  245  */
  246 void al_iofic_set_cause(void __iomem *regs_base, int group, uint32_t mask)
  247 {
  248         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
  249 
  250         al_assert(regs_base);
  251         al_assert(group < AL_IOFIC_MAX_GROUPS);
  252 
  253         al_reg_write32(&regs->ctrl[group].int_cause_set_grp, mask);
  254 }
  255 
  256 
  257 /*
  258  * unmask specific interrupts from aborting the udma a given group
  259  */
  260 void al_iofic_abort_mask(void __iomem *regs_base, int group, uint32_t mask)
  261 {
  262         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
  263 
  264         al_assert(regs_base);
  265         al_assert(group < AL_IOFIC_MAX_GROUPS);
  266 
  267         al_reg_write32(&regs->ctrl[group].int_abort_msk_grp, mask);
  268 
  269 }
  270 
  271 /*
  272  * trigger all interrupts that are waiting for moderation timers to expire
  273  */
  274 void al_iofic_interrupt_moderation_reset(void __iomem *regs_base, int group)
  275 {
  276         struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
  277         uint32_t reg = 0;
  278 
  279         al_assert(regs_base);
  280         al_assert(group < AL_IOFIC_MAX_GROUPS);
  281 
  282         al_assert(regs_base);
  283         al_assert(group < AL_IOFIC_MAX_GROUPS);
  284 
  285         reg = al_reg_read32(&regs->ctrl[group].int_control_grp);
  286         reg |= INT_CONTROL_GRP_MOD_RST;
  287 
  288         al_reg_write32(&regs->ctrl[group].int_control_grp, reg);
  289 }
  290 
  291 /** @} end of interrupt controller group */

Cache object: d0d617ffd53deda27466858eafce46b1


[ 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.