GNU Linux-libre 4.4.284-gnu1
[releases.git] / drivers / isdn / hardware / eicon / s_pri.c
1
2 /*
3  *
4  Copyright (c) Eicon Networks, 2002.
5  *
6  This source file is supplied for the use with
7  Eicon Networks range of DIVA Server Adapters.
8  *
9  Eicon File Revision :    2.1
10  *
11  This program is free software; you can redistribute it and/or modify
12  it under the terms of the GNU General Public License as published by
13  the Free Software Foundation; either version 2, or (at your option)
14  any later version.
15  *
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  See the GNU General Public License for more details.
20  *
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  */
26 #include "platform.h"
27 #include "di_defs.h"
28 #include "pc.h"
29 #include "pr_pc.h"
30 #include "di.h"
31 #include "mi_pc.h"
32 #include "pc_maint.h"
33 #include "divasync.h"
34 #include "io.h"
35 #include "helpers.h"
36 #include "dsrv_pri.h"
37 #include "dsp_defs.h"
38 /*****************************************************************************/
39 #define MAX_XLOG_SIZE  (64 * 1024)
40 /* -------------------------------------------------------------------------
41    Does return offset between ADAPTER->ram and real begin of memory
42    ------------------------------------------------------------------------- */
43 static dword pri_ram_offset(ADAPTER *a) {
44         return ((dword)MP_SHARED_RAM_OFFSET);
45 }
46 /* -------------------------------------------------------------------------
47    Recovery XLOG buffer from the card
48    ------------------------------------------------------------------------- */
49 static void pri_cpu_trapped(PISDN_ADAPTER IoAdapter) {
50         byte  __iomem *base;
51         word *Xlog;
52         dword   regs[4], TrapID, size;
53         Xdesc   xlogDesc;
54 /*
55  * check for trapped MIPS 46xx CPU, dump exception frame
56  */
57         base   = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
58         TrapID = READ_DWORD(&base[0x80]);
59         if ((TrapID == 0x99999999) || (TrapID == 0x99999901))
60         {
61                 dump_trap_frame(IoAdapter, &base[0x90]);
62                 IoAdapter->trapped = 1;
63         }
64         regs[0] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x70]);
65         regs[1] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x74]);
66         regs[2] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x78]);
67         regs[3] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x7c]);
68         regs[0] &= IoAdapter->MemorySize - 1;
69         if ((regs[0] < IoAdapter->MemorySize - 1))
70         {
71                 if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE))) {
72                         DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
73                         return;
74                 }
75                 size = IoAdapter->MemorySize - regs[0];
76                 if (size > MAX_XLOG_SIZE)
77                         size = MAX_XLOG_SIZE;
78                 memcpy_fromio(Xlog, &base[regs[0]], size);
79                 xlogDesc.buf = Xlog;
80                 xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]);
81                 xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]);
82                 dump_xlog_buffer(IoAdapter, &xlogDesc);
83                 diva_os_free(0, Xlog);
84                 IoAdapter->trapped = 2;
85         }
86         DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
87 }
88 /* -------------------------------------------------------------------------
89    Hardware reset of PRI card
90    ------------------------------------------------------------------------- */
91 static void reset_pri_hardware(PISDN_ADAPTER IoAdapter) {
92         byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
93         WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
94         diva_os_wait(50);
95         WRITE_BYTE(p, 0x00);
96         diva_os_wait(50);
97         DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
98 }
99 /* -------------------------------------------------------------------------
100    Stop Card Hardware
101    ------------------------------------------------------------------------- */
102 static void stop_pri_hardware(PISDN_ADAPTER IoAdapter) {
103         dword i;
104         byte __iomem *p;
105         dword volatile __iomem *cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
106         WRITE_DWORD(&cfgReg[3], 0);
107         WRITE_DWORD(&cfgReg[1], 0);
108         DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
109         IoAdapter->a.ram_out(&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU);
110         i = 0;
111         while ((i < 100) && (IoAdapter->a.ram_in(&IoAdapter->a, &RAM->SWReg) != 0))
112         {
113                 diva_os_wait(1);
114                 i++;
115         }
116         DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i))
117                 cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
118         WRITE_DWORD(&cfgReg[0], ((dword)(~0x03E00000)));
119         DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
120         diva_os_wait(1);
121         p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
122         WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
123         DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
124 }
125 static int load_pri_hardware(PISDN_ADAPTER IoAdapter) {
126         return (0);
127 }
128 /* --------------------------------------------------------------------------
129    PRI Adapter interrupt Service Routine
130    -------------------------------------------------------------------------- */
131 static int pri_ISR(struct _ISDN_ADAPTER *IoAdapter) {
132         byte __iomem *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
133         if (!(READ_DWORD(cfg) & 0x80000000)) {
134                 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
135                 return (0);
136         }
137         /*
138           clear interrupt line
139         */
140         WRITE_DWORD(cfg, (dword)~0x03E00000);
141         DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
142         IoAdapter->IrqCount++;
143         if (IoAdapter->Initialized)
144         {
145                 diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr);
146         }
147         return (1);
148 }
149 /* -------------------------------------------------------------------------
150    Disable interrupt in the card hardware
151    ------------------------------------------------------------------------- */
152 static void disable_pri_interrupt(PISDN_ADAPTER IoAdapter) {
153         dword volatile __iomem *cfgReg = (dword volatile __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
154         WRITE_DWORD(&cfgReg[3], 0);
155         WRITE_DWORD(&cfgReg[1], 0);
156         WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000));
157         DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
158 }
159 /* -------------------------------------------------------------------------
160    Install entry points for PRI Adapter
161    ------------------------------------------------------------------------- */
162 static void prepare_common_pri_functions(PISDN_ADAPTER IoAdapter) {
163         ADAPTER *a = &IoAdapter->a;
164         a->ram_in           = mem_in;
165         a->ram_inw          = mem_inw;
166         a->ram_in_buffer    = mem_in_buffer;
167         a->ram_look_ahead   = mem_look_ahead;
168         a->ram_out          = mem_out;
169         a->ram_outw         = mem_outw;
170         a->ram_out_buffer   = mem_out_buffer;
171         a->ram_inc          = mem_inc;
172         a->ram_offset       = pri_ram_offset;
173         a->ram_out_dw    = mem_out_dw;
174         a->ram_in_dw    = mem_in_dw;
175         a->istream_wakeup   = pr_stream;
176         IoAdapter->out      = pr_out;
177         IoAdapter->dpc      = pr_dpc;
178         IoAdapter->tst_irq  = scom_test_int;
179         IoAdapter->clr_irq  = scom_clear_int;
180         IoAdapter->pcm      = (struct pc_maint *)(MIPS_MAINT_OFFS
181                                                   - MP_SHARED_RAM_OFFSET);
182         IoAdapter->load     = load_pri_hardware;
183         IoAdapter->disIrq   = disable_pri_interrupt;
184         IoAdapter->rstFnc   = reset_pri_hardware;
185         IoAdapter->stop     = stop_pri_hardware;
186         IoAdapter->trapFnc  = pri_cpu_trapped;
187         IoAdapter->diva_isr_handler = pri_ISR;
188 }
189 /* -------------------------------------------------------------------------
190    Install entry points for PRI Adapter
191    ------------------------------------------------------------------------- */
192 void prepare_pri_functions(PISDN_ADAPTER IoAdapter) {
193         IoAdapter->MemorySize = MP_MEMORY_SIZE;
194         prepare_common_pri_functions(IoAdapter);
195         diva_os_prepare_pri_functions(IoAdapter);
196 }
197 /* -------------------------------------------------------------------------
198    Install entry points for PRI Rev.2 Adapter
199    ------------------------------------------------------------------------- */
200 void prepare_pri2_functions(PISDN_ADAPTER IoAdapter) {
201         IoAdapter->MemorySize = MP2_MEMORY_SIZE;
202         prepare_common_pri_functions(IoAdapter);
203         diva_os_prepare_pri2_functions(IoAdapter);
204 }
205 /* ------------------------------------------------------------------------- */