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    ------------------------------------------------------------------------- */
pri_ram_offset(ADAPTER * a)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    ------------------------------------------------------------------------- */
pri_cpu_trapped(PISDN_ADAPTER IoAdapter)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    ------------------------------------------------------------------------- */
reset_pri_hardware(PISDN_ADAPTER IoAdapter)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    ------------------------------------------------------------------------- */
stop_pri_hardware(PISDN_ADAPTER IoAdapter)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 }
load_pri_hardware(PISDN_ADAPTER IoAdapter)125 static int load_pri_hardware(PISDN_ADAPTER IoAdapter) {
126 	return (0);
127 }
128 /* --------------------------------------------------------------------------
129    PRI Adapter interrupt Service Routine
130    -------------------------------------------------------------------------- */
pri_ISR(struct _ISDN_ADAPTER * IoAdapter)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    ------------------------------------------------------------------------- */
disable_pri_interrupt(PISDN_ADAPTER IoAdapter)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    ------------------------------------------------------------------------- */
prepare_common_pri_functions(PISDN_ADAPTER IoAdapter)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    ------------------------------------------------------------------------- */
prepare_pri_functions(PISDN_ADAPTER IoAdapter)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    ------------------------------------------------------------------------- */
prepare_pri2_functions(PISDN_ADAPTER IoAdapter)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 /* ------------------------------------------------------------------------- */
206