1294838Szbb/*- 2294838Szbb******************************************************************************* 3294838SzbbCopyright (C) 2015 Annapurna Labs Ltd. 4294838Szbb 5294838SzbbThis file may be licensed under the terms of the Annapurna Labs Commercial 6294838SzbbLicense Agreement. 7294838Szbb 8294838SzbbAlternatively, this file can be distributed under the terms of the GNU General 9294838SzbbPublic License V2 as published by the Free Software Foundation and can be 10294838Szbbfound at http://www.gnu.org/licenses/gpl-2.0.html 11294838Szbb 12294838SzbbAlternatively, redistribution and use in source and binary forms, with or 13294838Szbbwithout modification, are permitted provided that the following conditions are 14294838Szbbmet: 15294838Szbb 16294838Szbb * Redistributions of source code must retain the above copyright notice, 17294838Szbbthis list of conditions and the following disclaimer. 18294838Szbb 19294838Szbb * Redistributions in binary form must reproduce the above copyright 20294838Szbbnotice, this list of conditions and the following disclaimer in 21294838Szbbthe documentation and/or other materials provided with the 22294838Szbbdistribution. 23294838Szbb 24294838SzbbTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 25294838SzbbANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26294838SzbbWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27294838SzbbDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 28294838SzbbANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29294838Szbb(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30294838SzbbLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 31294838SzbbANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32294838Szbb(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33294838SzbbSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34294838Szbb 35294838Szbb*******************************************************************************/ 36294838Szbb 37294838Szbb/** 38294838Szbb * @{ 39294838Szbb * @file al_hal_udma_iofic.c 40294838Szbb * 41294838Szbb * @brief unit interrupts configurations 42294838Szbb * 43294838Szbb */ 44294838Szbb 45294838Szbb#include "al_hal_udma_iofic.h" 46294838Szbb#include "al_hal_udma_regs.h" 47294838Szbb 48294838Szbb/* 49294838Szbb * configure the interrupt registers, interrupts will are kept masked 50294838Szbb */ 51294838Szbbstatic int al_udma_main_iofic_config(struct al_iofic_regs __iomem *base, 52294838Szbb enum al_iofic_mode mode) 53294838Szbb{ 54294838Szbb switch (mode) { 55294838Szbb case AL_IOFIC_MODE_LEGACY: 56294838Szbb al_iofic_config(base, AL_INT_GROUP_A, 57294838Szbb INT_CONTROL_GRP_SET_ON_POSEDGE | 58294838Szbb INT_CONTROL_GRP_MASK_MSI_X | 59294838Szbb INT_CONTROL_GRP_CLEAR_ON_READ); 60294838Szbb al_iofic_config(base, AL_INT_GROUP_B, 61294838Szbb INT_CONTROL_GRP_CLEAR_ON_READ | 62294838Szbb INT_CONTROL_GRP_MASK_MSI_X); 63294838Szbb al_iofic_config(base, AL_INT_GROUP_C, 64294838Szbb INT_CONTROL_GRP_CLEAR_ON_READ | 65294838Szbb INT_CONTROL_GRP_MASK_MSI_X); 66294838Szbb al_iofic_config(base, AL_INT_GROUP_D, 67294838Szbb INT_CONTROL_GRP_SET_ON_POSEDGE | 68294838Szbb INT_CONTROL_GRP_MASK_MSI_X | 69294838Szbb INT_CONTROL_GRP_CLEAR_ON_READ); 70294838Szbb break; 71294838Szbb case AL_IOFIC_MODE_MSIX_PER_Q: 72294838Szbb al_iofic_config(base, AL_INT_GROUP_A, 73294838Szbb INT_CONTROL_GRP_SET_ON_POSEDGE | 74294838Szbb INT_CONTROL_GRP_AUTO_MASK | 75294838Szbb INT_CONTROL_GRP_AUTO_CLEAR); 76294838Szbb al_iofic_config(base, AL_INT_GROUP_B, 77294838Szbb INT_CONTROL_GRP_AUTO_CLEAR | 78294838Szbb INT_CONTROL_GRP_AUTO_MASK | 79294838Szbb INT_CONTROL_GRP_CLEAR_ON_READ); 80294838Szbb al_iofic_config(base, AL_INT_GROUP_C, 81294838Szbb INT_CONTROL_GRP_AUTO_CLEAR | 82294838Szbb INT_CONTROL_GRP_AUTO_MASK | 83294838Szbb INT_CONTROL_GRP_CLEAR_ON_READ); 84294838Szbb al_iofic_config(base, AL_INT_GROUP_D, 85294838Szbb INT_CONTROL_GRP_SET_ON_POSEDGE | 86294838Szbb INT_CONTROL_GRP_CLEAR_ON_READ | 87294838Szbb INT_CONTROL_GRP_MASK_MSI_X); 88294838Szbb break; 89294838Szbb case AL_IOFIC_MODE_MSIX_PER_GROUP: 90294838Szbb al_iofic_config(base, AL_INT_GROUP_A, 91294838Szbb INT_CONTROL_GRP_SET_ON_POSEDGE | 92294838Szbb INT_CONTROL_GRP_AUTO_CLEAR | 93294838Szbb INT_CONTROL_GRP_AUTO_MASK); 94294838Szbb al_iofic_config(base, AL_INT_GROUP_B, 95294838Szbb INT_CONTROL_GRP_CLEAR_ON_READ | 96294838Szbb INT_CONTROL_GRP_MASK_MSI_X); 97294838Szbb al_iofic_config(base, AL_INT_GROUP_C, 98294838Szbb INT_CONTROL_GRP_CLEAR_ON_READ | 99294838Szbb INT_CONTROL_GRP_MASK_MSI_X); 100294838Szbb al_iofic_config(base, AL_INT_GROUP_D, 101294838Szbb INT_CONTROL_GRP_SET_ON_POSEDGE | 102294838Szbb INT_CONTROL_GRP_CLEAR_ON_READ | 103294838Szbb INT_CONTROL_GRP_MASK_MSI_X); 104294838Szbb break; 105294838Szbb default: 106294838Szbb al_err("%s: invalid mode (%d)\n", __func__, mode); 107294838Szbb return -EINVAL; 108294838Szbb } 109294838Szbb 110294838Szbb al_dbg("%s: base.%p mode %d\n", __func__, base, mode); 111294838Szbb return 0; 112294838Szbb} 113294838Szbb 114294838Szbb/* 115294838Szbb * configure the UDMA interrupt registers, interrupts are kept masked 116294838Szbb */ 117294838Szbbint al_udma_iofic_config(struct unit_regs __iomem *regs, enum al_iofic_mode mode, 118294838Szbb uint32_t m2s_errors_disable, 119294838Szbb uint32_t m2s_aborts_disable, 120294838Szbb uint32_t s2m_errors_disable, 121294838Szbb uint32_t s2m_aborts_disable) 122294838Szbb{ 123294838Szbb int rc; 124294838Szbb 125294838Szbb rc = al_udma_main_iofic_config(®s->gen.interrupt_regs.main_iofic, mode); 126294838Szbb if (rc != 0) 127294838Szbb return rc; 128294838Szbb 129294838Szbb al_iofic_unmask(®s->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_A, ~m2s_errors_disable); 130294838Szbb al_iofic_abort_mask(®s->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_A, m2s_aborts_disable); 131294838Szbb 132294838Szbb al_iofic_unmask(®s->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_B, ~s2m_errors_disable); 133294838Szbb al_iofic_abort_mask(®s->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_B, s2m_aborts_disable); 134294838Szbb 135294838Szbb al_dbg("%s base.%p mode %d\n", __func__, regs, mode); 136294838Szbb return 0; 137294838Szbb} 138294838Szbb 139294838Szbb/* 140294838Szbb * return the offset of the unmask register for a given group 141294838Szbb */ 142294838Szbbuint32_t __iomem * al_udma_iofic_unmask_offset_get( 143294838Szbb struct unit_regs __iomem *regs, 144294838Szbb enum al_udma_iofic_level level, 145294838Szbb int group) 146294838Szbb{ 147294838Szbb al_assert(al_udma_iofic_level_and_group_valid(level, group)); 148294838Szbb return al_iofic_unmask_offset_get(al_udma_iofic_reg_base_get(regs, level), group); 149294838Szbb} 150294838Szbb 151294838Szbb/** @} end of UDMA group */ 152