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   ------------------------------------------------------------------------- */
43static dword pri_ram_offset(ADAPTER *a) {
44	return ((dword)MP_SHARED_RAM_OFFSET);
45}
46/* -------------------------------------------------------------------------
47   Recovery XLOG buffer from the card
48   ------------------------------------------------------------------------- */
49static 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   ------------------------------------------------------------------------- */
91static 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   ------------------------------------------------------------------------- */
102static 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}
125static int load_pri_hardware(PISDN_ADAPTER IoAdapter) {
126	return (0);
127}
128/* --------------------------------------------------------------------------
129   PRI Adapter interrupt Service Routine
130   -------------------------------------------------------------------------- */
131static 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   ------------------------------------------------------------------------- */
152static 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   ------------------------------------------------------------------------- */
162static 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   ------------------------------------------------------------------------- */
192void 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   ------------------------------------------------------------------------- */
200void 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