xref: /freebsd/sys/contrib/alpine-hal/al_hal_udma_iofic.c (revision 2414e86439f4c53aff73d1afe0453fb48145d9e5)
1*49b49cdaSZbigniew Bodek /*-
2*49b49cdaSZbigniew Bodek *******************************************************************************
3*49b49cdaSZbigniew Bodek Copyright (C) 2015 Annapurna Labs Ltd.
4*49b49cdaSZbigniew Bodek 
5*49b49cdaSZbigniew Bodek This file may be licensed under the terms of the Annapurna Labs Commercial
6*49b49cdaSZbigniew Bodek License Agreement.
7*49b49cdaSZbigniew Bodek 
8*49b49cdaSZbigniew Bodek Alternatively, this file can be distributed under the terms of the GNU General
9*49b49cdaSZbigniew Bodek Public License V2 as published by the Free Software Foundation and can be
10*49b49cdaSZbigniew Bodek found at http://www.gnu.org/licenses/gpl-2.0.html
11*49b49cdaSZbigniew Bodek 
12*49b49cdaSZbigniew Bodek Alternatively, redistribution and use in source and binary forms, with or
13*49b49cdaSZbigniew Bodek without modification, are permitted provided that the following conditions are
14*49b49cdaSZbigniew Bodek met:
15*49b49cdaSZbigniew Bodek 
16*49b49cdaSZbigniew Bodek     *     Redistributions of source code must retain the above copyright notice,
17*49b49cdaSZbigniew Bodek this list of conditions and the following disclaimer.
18*49b49cdaSZbigniew Bodek 
19*49b49cdaSZbigniew Bodek     *     Redistributions in binary form must reproduce the above copyright
20*49b49cdaSZbigniew Bodek notice, this list of conditions and the following disclaimer in
21*49b49cdaSZbigniew Bodek the documentation and/or other materials provided with the
22*49b49cdaSZbigniew Bodek distribution.
23*49b49cdaSZbigniew Bodek 
24*49b49cdaSZbigniew Bodek THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25*49b49cdaSZbigniew Bodek ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26*49b49cdaSZbigniew Bodek WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27*49b49cdaSZbigniew Bodek DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28*49b49cdaSZbigniew Bodek ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29*49b49cdaSZbigniew Bodek (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30*49b49cdaSZbigniew Bodek LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31*49b49cdaSZbigniew Bodek ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32*49b49cdaSZbigniew Bodek (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33*49b49cdaSZbigniew Bodek SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*49b49cdaSZbigniew Bodek 
35*49b49cdaSZbigniew Bodek *******************************************************************************/
36*49b49cdaSZbigniew Bodek 
37*49b49cdaSZbigniew Bodek /**
38*49b49cdaSZbigniew Bodek  *  @{
39*49b49cdaSZbigniew Bodek  * @file   al_hal_udma_iofic.c
40*49b49cdaSZbigniew Bodek  *
41*49b49cdaSZbigniew Bodek  * @brief  unit interrupts configurations
42*49b49cdaSZbigniew Bodek  *
43*49b49cdaSZbigniew Bodek  */
44*49b49cdaSZbigniew Bodek 
45*49b49cdaSZbigniew Bodek #include "al_hal_udma_iofic.h"
46*49b49cdaSZbigniew Bodek #include "al_hal_udma_regs.h"
47*49b49cdaSZbigniew Bodek 
48*49b49cdaSZbigniew Bodek /*
49*49b49cdaSZbigniew Bodek  * configure the interrupt registers, interrupts will are kept masked
50*49b49cdaSZbigniew Bodek  */
al_udma_main_iofic_config(struct al_iofic_regs __iomem * base,enum al_iofic_mode mode)51*49b49cdaSZbigniew Bodek static int al_udma_main_iofic_config(struct al_iofic_regs __iomem *base,
52*49b49cdaSZbigniew Bodek 				    enum al_iofic_mode mode)
53*49b49cdaSZbigniew Bodek {
54*49b49cdaSZbigniew Bodek 	switch (mode) {
55*49b49cdaSZbigniew Bodek 	case AL_IOFIC_MODE_LEGACY:
56*49b49cdaSZbigniew Bodek 		al_iofic_config(base, AL_INT_GROUP_A,
57*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_SET_ON_POSEDGE |
58*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_MASK_MSI_X |
59*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_CLEAR_ON_READ);
60*49b49cdaSZbigniew Bodek 		al_iofic_config(base, AL_INT_GROUP_B,
61*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_CLEAR_ON_READ |
62*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_MASK_MSI_X);
63*49b49cdaSZbigniew Bodek 		al_iofic_config(base, AL_INT_GROUP_C,
64*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_CLEAR_ON_READ |
65*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_MASK_MSI_X);
66*49b49cdaSZbigniew Bodek 		al_iofic_config(base, AL_INT_GROUP_D,
67*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_SET_ON_POSEDGE |
68*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_MASK_MSI_X |
69*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_CLEAR_ON_READ);
70*49b49cdaSZbigniew Bodek 		break;
71*49b49cdaSZbigniew Bodek 	case AL_IOFIC_MODE_MSIX_PER_Q:
72*49b49cdaSZbigniew Bodek 		al_iofic_config(base, AL_INT_GROUP_A,
73*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_SET_ON_POSEDGE |
74*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_AUTO_MASK |
75*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_AUTO_CLEAR);
76*49b49cdaSZbigniew Bodek 		al_iofic_config(base, AL_INT_GROUP_B,
77*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_AUTO_CLEAR |
78*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_AUTO_MASK |
79*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_CLEAR_ON_READ);
80*49b49cdaSZbigniew Bodek 		al_iofic_config(base, AL_INT_GROUP_C,
81*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_AUTO_CLEAR |
82*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_AUTO_MASK |
83*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_CLEAR_ON_READ);
84*49b49cdaSZbigniew Bodek 		al_iofic_config(base, AL_INT_GROUP_D,
85*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_SET_ON_POSEDGE |
86*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_CLEAR_ON_READ |
87*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_MASK_MSI_X);
88*49b49cdaSZbigniew Bodek 		break;
89*49b49cdaSZbigniew Bodek 	case AL_IOFIC_MODE_MSIX_PER_GROUP:
90*49b49cdaSZbigniew Bodek 		al_iofic_config(base, AL_INT_GROUP_A,
91*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_SET_ON_POSEDGE |
92*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_AUTO_CLEAR |
93*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_AUTO_MASK);
94*49b49cdaSZbigniew Bodek 		al_iofic_config(base, AL_INT_GROUP_B,
95*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_CLEAR_ON_READ |
96*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_MASK_MSI_X);
97*49b49cdaSZbigniew Bodek 		al_iofic_config(base, AL_INT_GROUP_C,
98*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_CLEAR_ON_READ |
99*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_MASK_MSI_X);
100*49b49cdaSZbigniew Bodek 		al_iofic_config(base, AL_INT_GROUP_D,
101*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_SET_ON_POSEDGE |
102*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_CLEAR_ON_READ |
103*49b49cdaSZbigniew Bodek 				INT_CONTROL_GRP_MASK_MSI_X);
104*49b49cdaSZbigniew Bodek 		break;
105*49b49cdaSZbigniew Bodek 	default:
106*49b49cdaSZbigniew Bodek 		al_err("%s: invalid mode (%d)\n", __func__, mode);
107*49b49cdaSZbigniew Bodek 		return -EINVAL;
108*49b49cdaSZbigniew Bodek 	}
109*49b49cdaSZbigniew Bodek 
110*49b49cdaSZbigniew Bodek 	al_dbg("%s: base.%p mode %d\n", __func__, base, mode);
111*49b49cdaSZbigniew Bodek 	return 0;
112*49b49cdaSZbigniew Bodek }
113*49b49cdaSZbigniew Bodek 
114*49b49cdaSZbigniew Bodek /*
115*49b49cdaSZbigniew Bodek  * configure the UDMA interrupt registers, interrupts are kept masked
116*49b49cdaSZbigniew Bodek  */
al_udma_iofic_config(struct unit_regs __iomem * regs,enum al_iofic_mode mode,uint32_t m2s_errors_disable,uint32_t m2s_aborts_disable,uint32_t s2m_errors_disable,uint32_t s2m_aborts_disable)117*49b49cdaSZbigniew Bodek int al_udma_iofic_config(struct unit_regs __iomem *regs, enum al_iofic_mode mode,
118*49b49cdaSZbigniew Bodek 			uint32_t	m2s_errors_disable,
119*49b49cdaSZbigniew Bodek 			uint32_t	m2s_aborts_disable,
120*49b49cdaSZbigniew Bodek 			uint32_t	s2m_errors_disable,
121*49b49cdaSZbigniew Bodek 			uint32_t	s2m_aborts_disable)
122*49b49cdaSZbigniew Bodek {
123*49b49cdaSZbigniew Bodek 	int rc;
124*49b49cdaSZbigniew Bodek 
125*49b49cdaSZbigniew Bodek 	rc = al_udma_main_iofic_config(&regs->gen.interrupt_regs.main_iofic, mode);
126*49b49cdaSZbigniew Bodek 	if (rc != 0)
127*49b49cdaSZbigniew Bodek 		return rc;
128*49b49cdaSZbigniew Bodek 
129*49b49cdaSZbigniew Bodek 	al_iofic_unmask(&regs->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_A, ~m2s_errors_disable);
130*49b49cdaSZbigniew Bodek 	al_iofic_abort_mask(&regs->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_A, m2s_aborts_disable);
131*49b49cdaSZbigniew Bodek 
132*49b49cdaSZbigniew Bodek 	al_iofic_unmask(&regs->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_B, ~s2m_errors_disable);
133*49b49cdaSZbigniew Bodek 	al_iofic_abort_mask(&regs->gen.interrupt_regs.secondary_iofic_ctrl, AL_INT_GROUP_B, s2m_aborts_disable);
134*49b49cdaSZbigniew Bodek 
135*49b49cdaSZbigniew Bodek 	al_dbg("%s base.%p mode %d\n", __func__, regs, mode);
136*49b49cdaSZbigniew Bodek 	return 0;
137*49b49cdaSZbigniew Bodek }
138*49b49cdaSZbigniew Bodek 
139*49b49cdaSZbigniew Bodek /*
140*49b49cdaSZbigniew Bodek  * return the offset of the unmask register for a given group
141*49b49cdaSZbigniew Bodek  */
al_udma_iofic_unmask_offset_get(struct unit_regs __iomem * regs,enum al_udma_iofic_level level,int group)142*49b49cdaSZbigniew Bodek uint32_t __iomem * al_udma_iofic_unmask_offset_get(
143*49b49cdaSZbigniew Bodek 	struct unit_regs __iomem	*regs,
144*49b49cdaSZbigniew Bodek 	enum al_udma_iofic_level	level,
145*49b49cdaSZbigniew Bodek 	int				group)
146*49b49cdaSZbigniew Bodek {
147*49b49cdaSZbigniew Bodek 	al_assert(al_udma_iofic_level_and_group_valid(level, group));
148*49b49cdaSZbigniew Bodek 	return al_iofic_unmask_offset_get(al_udma_iofic_reg_base_get(regs, level), group);
149*49b49cdaSZbigniew Bodek }
150*49b49cdaSZbigniew Bodek 
151*49b49cdaSZbigniew Bodek /** @} end of UDMA group */
152