source: drsdaq/VME/struck/sis1100/V2.02/dev/pci/sis1100_init.c@ 23

Last change on this file since 23 was 22, checked in by ogrimm, 16 years ago
First commit of drsdaq program
File size: 9.0 KB
Line 
1/* $ZEL: sis1100_init.c,v 1.5 2004/05/27 23:10:20 wuestner Exp $ */
2
3/*
4 * Copyright (c) 2001-2004
5 * Peter Wuestner. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include "sis1100_sc.h"
30
31void
32sis1100_dump_glink_status(struct sis1100_softc* sc, char* text, int locked)
33{
34 u_int32_t v;
35 if (!locked) SEM_LOCK(sc->sem_hw);
36 pINFO(sc, "%s:", text);
37 pINFO(sc, " ident =%08x", sis1100readreg(sc, ident));
38 pINFO(sc, " sr =%08x", sis1100readreg(sc, sr));
39 pINFO(sc, " cr =%08x", sis1100readreg(sc, cr));
40 pINFO(sc, " t_hdr =%08x", sis1100readreg(sc, t_hdr));
41 pINFO(sc, " t_am =%08x", sis1100readreg(sc, t_am));
42 pINFO(sc, " t_adl =%08x", sis1100readreg(sc, t_adl));
43 pINFO(sc, " t_dal =%08x", sis1100readreg(sc, t_dal));
44 pINFO(sc, " tc_hdr =%08x", sis1100readreg(sc, tc_hdr));
45 pINFO(sc, " tc_dal =%08x", sis1100readreg(sc, tc_dal));
46 pINFO(sc, " p_balance =%08x", sis1100readreg(sc, p_balance));
47 pINFO(sc, " prot_error =%08x", sis1100readreg(sc, prot_error));
48 pINFO(sc, " d0_bc =%08x", sis1100readreg(sc, d0_bc));
49 pINFO(sc, " d0_bc_buf =%08x", sis1100readreg(sc, d0_bc_buf));
50 pINFO(sc, " d0_bc_blen =%08x", sis1100readreg(sc, d0_bc_blen));
51 pINFO(sc, " d_hdr =%08x", sis1100readreg(sc, d_hdr));
52 pINFO(sc, " d_am =%08x", sis1100readreg(sc, d_am));
53 pINFO(sc, " d_adl =%08x", sis1100readreg(sc, d_adl));
54 pINFO(sc, " d_bc =%08x", sis1100readreg(sc, d_bc));
55 pINFO(sc, " rd_pipe_buf =%08x", sis1100readreg(sc, rd_pipe_buf));
56 pINFO(sc, " rd_pipe_blen=%08x", sis1100readreg(sc, rd_pipe_blen));
57 pINFO(sc, "");
58 v=sis1100readreg(sc, opt_csr);
59 pINFO(sc, " opt_csr =%08x", v);
60 sis1100writereg(sc, opt_csr, v&0xc0f50000);
61 pINFO(sc, " opt_csr =%08x", sis1100readreg(sc, opt_csr));
62 if (!locked) SEM_UNLOCK(sc->sem_hw);
63}
64
65int
66sis1100_flush_fifo(struct sis1100_softc* sc, const char* text, int silent)
67{
68 u_int32_t sr, special, data;
69 int count=0;
70
71 sis1100writereg(sc, cr, cr_transparent);
72 mb_reg();
73 sr=sis1100readreg(sc, sr);
74 while (sr&(sr_tp_special|sr_tp_data)) {
75 while (sr&sr_tp_data) {
76 data=sis1100readreg(sc, tp_data);
77 if (!silent) pINFO(sc, "data = 0x%08x\n", data);
78 sr=sis1100readreg(sc, sr);
79 count++;
80 if (count>100) {
81 sis1100writereg(sc, cr, cr_transparent<<16);
82 pINFO(sc, "too many data in fifo; giving up");
83 return -1;
84 }
85 }
86 while ((sr&(sr_tp_special|sr_tp_data))==sr_tp_special) {
87 special=sis1100readreg(sc, tp_special);
88 if (!silent) pINFO(sc, "special=0x%08x\n", special);
89 sr=sis1100readreg(sc, sr);
90 count++;
91 if (count>100) {
92 sis1100writereg(sc, cr, cr_transparent<<16);
93 pINFO(sc, "too many data in fifo; giving up");
94 return -1;
95 }
96 }
97 if ((!silent) && (count>100)) {
98 pINFO(sc, "too many data in fifo; switching to 'silent'");
99 silent=1;
100 }
101 if (count>10000) {
102 sis1100writereg(sc, cr, cr_transparent<<16);
103 pINFO(sc, "too many data in fifo; giving up");
104 return -1;
105 }
106 }
107 sis1100writereg(sc, cr, cr_transparent<<16);
108 if (count && silent)
109 pINFO(sc, "flushed %d words from fifo", count);
110 return 0;
111}
112
113static void
114sis1100_set_swapping(struct sis1100_softc* sc, int swap)
115{
116 u_int32_t tmp;
117
118 /*pINFO(sc, "set swap to %d", swap);*/
119 tmp=plxreadreg(sc, BIGEND_LMISC_PROT_AREA);
120 if (swap) {
121 sis1100writereg(sc, cr, 0x8);
122 plxwritereg(sc, BIGEND_LMISC_PROT_AREA, tmp|(3<<6));
123 } else {
124 sis1100writereg(sc, cr, 0x80000);
125 plxwritereg(sc, BIGEND_LMISC_PROT_AREA, tmp&~(3<<6));
126 }
127}
128
129void
130sis1100_update_swapping(struct sis1100_softc* sc, const char* caller)
131{
132 int swap;
133#if defined(__LITTLE_ENDIAN)
134 int local_endian=0;
135#elif defined(__BIG_ENDIAN)
136 int local_endian=1;
137#else
138# error UNKNOWN ENDIAN
139#endif
140
141 /*
142 pINFO(sc, "local endian is %s; remote endian is %s; user swap is %d "
143 "(called from %s)",
144 local_endian?"big":"little",
145 sc->remote_endian?"big":"little",
146 sc->user_wants_swap,
147 caller);
148 */
149
150 swap=0;
151 if (local_endian) swap=!swap;
152 if (sc->remote_endian) swap=!swap;
153 if (sc->user_wants_swap) swap=!swap;
154 sis1100_set_swapping(sc, swap);
155}
156
157int
158sis1100_init(struct sis1100_softc* sc)
159{
160#define MIN_FV 5
161#define MAX_FV 7
162
163 u_int32_t typ, hv, fk, fv;
164 int res, i;
165
166 sc->local_ident=sis1100readreg(sc, ident);
167 typ=sc->local_ident&0xff;
168 hv=(sc->local_ident>>8)&0xff;
169 fk=(sc->local_ident>>16)&0xff;
170 fv=(sc->local_ident>>24)&0xff;
171
172 if (typ!=1) {
173 pERROR(sc, "ident=08x%x; claims not to be a PCI Device", typ);
174 res=ENXIO;
175 goto raus;
176 }
177 pINFO(sc, "HW version %d; FW code %d; FW version %d", hv, fk, fv);
178 /*pINFO(sc, "LAS1RR=0x%08x LAS1BA=0x%08x LBRD1=0x%08x\n",
179 plxreadreg(sc, LAS1RR), plxreadreg(sc, LAS1BA),
180 plxreadreg(sc, LBRD1));*/
181 switch (sc->local_ident&0xffff00) { /* HW version and FW code */
182 case 0x010100: {
183 if (fv<MIN_FV) {
184 pERROR(sc, "Firmware version too old;"
185 " at least version %d is required.",
186 MIN_FV);
187 res=ENXIO;
188 goto raus;
189 }
190 if (fv>MAX_FV)
191 pINFO(sc, "Driver not tested with"
192 " firmware versions greater than %d.",
193 MAX_FV);
194 if (sc->reg_size!=0x1000) {
195 pERROR(sc, "wrong size of space 0: 0x%lx instead of 0x1000",
196 (unsigned long)sc->reg_size);
197 res=ENXIO;
198 goto raus;
199 }
200 pINFO(sc, "size of space 1: 0x%lx (%ld MByte)",
201 (u_long)sc->rem_size, (u_long)sc->rem_size>>20);
202 } break;
203 default:
204 pERROR(sc, "Hard- or Firmware not known");
205 res=ENXIO;
206 goto raus;
207 }
208
209 /* reset all we can */
210 sis1100writereg(sc, cr, cr_reset); /* master reset */
211 sis1100writereg(sc, cr, cr_rem_reset); /* reset remote, ignore wether it exists */
212 if (sis1100_flush_fifo(sc, "init", 0)) { /* clear local fifo */
213 res=EIO;
214 goto raus;
215 }
216 sis1100writereg(sc, cr, cr_reset); /* master reset again */
217 sis1100_reset_plx(sc); /* reset PLX */
218 sis1100writereg(sc, p_balance, 0);
219 sis1100readreg(sc, prot_error);
220
221 /* sis1100_dump_glink_status(sc, "INITIAL DUMP"); */
222
223 /* enable PCI Initiator-to-PCI Memory */
224 plxwritereg(sc, DMRR, 0);
225 plxwritereg(sc, DMLBAM, 0);
226 plxwritereg(sc, DMPBAM, 1);
227
228 sis1100writereg(sc, cr, 8); /* big endian */
229
230 sc->got_irqs=0;
231 for (i=0; i<=7; i++) sc->irq_vects[i].valid=0;
232 sc->pending_irqs=0;
233 sc->doorbell=0;
234 sc->lemo_status=0;
235
236 /* enable IRQs */
237 sis1100_disable_irq(sc, 0xffffffff, 0xffffffff);
238 sis1100_enable_irq(sc, plxirq_pci|plxirq_mbox|plxirq_doorbell|plxirq_local,
239 irq_synch_chg|irq_inh_chg|irq_sema_chg|
240 irq_rec_violation|irq_reset_req);
241
242 sc->user_wants_swap=0;
243 sc->dsp_present=0;
244 sc->ram_size=0;
245 sc->remote_ident=0;
246 sc->old_remote_hw=sis1100_hw_invalid;
247 sc->remote_hw=sis1100_hw_invalid;
248 sc->remote_endian=1;
249
250 if ((sis1100readreg(sc, sr)&sr_synch)==sr_synch) {
251 sis1100_init_remote(sc);
252 } else {
253 pINFO(sc, "init: remote interface not reachable");
254 }
255 res=0;
256
257 raus:
258 return res;
259#undef MIN_FV
260#undef MAX_FV
261}
262
263void
264sis1100_done(struct sis1100_softc* sc)
265{
266 /* DMA Ch. 0/1: not enabled */
267 plxwritereg(sc, DMACSR0_DMACSR1, 0);
268 /* disable interrupts */
269 plxwritereg(sc, INTCSR, 0);
270}
Note: See TracBrowser for help on using the repository browser.