00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 #include "local.h"
00105
00106
00107 #include <assert.h>
00108 #include "llif.h"
00109
00110 #include <stdio.h>
00111 #include <stdlib.h>
00112
00113 #include <errno.h>
00114 #include <fcntl.h>
00115 #include <signal.h>
00116 #include <sys/ioctl.h>
00117 #include <sys/mman.h>
00118 #include <sys/stat.h>
00119 #include <sys/types.h>
00120 #include <stdio.h>
00121 #include <unistd.h>
00122
00123
00124 #include "acq32busprot.h"
00125
00126
00127 #include "llprotocol.h"
00128
00129 sigjmp_buf G_env;
00130
00131 int pollAck( struct MU* m )
00132
00133 {
00134 int ipoll = 0;
00135
00136 while( (getMbox( m, BP_MB_COMMAND )&MASK(BP_CI_ACK_BIT) ) == 0 ){
00137 if ( (++ipoll&0xfffff) == 0 ){
00138 fprintf( stderr, "pollAck %6d looking for 0x%08x got 0x%08x\n",
00139 ipoll, MASK(BP_CI_ACK_BIT), getMbox(m,BP_MB_COMMAND) );
00140 }
00141 }
00142
00143 PRINTF(4)( "pollAck() done 0x%08x\n", getMbox(m,BP_MB_COMMAND) );
00144
00145 return 0;
00146 }
00147
00148
00149 static int enterLLC(
00150 struct MU* m,
00151 unsigned mode,
00152 unsigned a3,
00153 int clkpos,
00154 int trpos
00155 )
00156 {
00157 u32 command = MASK(BP_CI_DONE_BIT)+
00158 MASK(BP_CI_COMMAND_BIT)+
00159 BP_SET_FUNCODE(BP_FC_SET_MODE_LLC)+
00160 mode;
00161
00162 if ( clkpos ){
00163 command |= BP_SET_A1(BP_FC_SET_MODE_LLC_CLKPOL_POS);
00164 }
00165 if ( trpos ) {
00166 command |= BP_SET_A1(BP_FC_SET_MODE_LLC_TRPOL_POS);
00167 }
00168
00169 PRINTF(1)("enterLLC()\n");
00170
00171 setMbox( m, BP_MB_A3, a3 );
00172 setMbox( m, BP_MB_COMMAND, command );
00173 pollAck( m );
00174 pollMboxBits( m, BP_MB_COMMAND, LLC_CSR_READY, LLC_CSR_READY );
00175 return 0;
00176 }
00177
00178 int enterLLCSoftClock(
00179 struct MU* m, int clkpos, int trpos, int internal_loopback,
00180 u32 command_mods)
00181 {
00182 u32 command = BP_FC_SET_MODE_LLC_SOFTCLOCK;
00183
00184 command |= command_mods;
00185
00186 if ( internal_loopback ){
00187 command += BP_FC_SET_MODE_LLC_INTSOFT_CLK;
00188 }
00189 return enterLLC(
00190 m,
00191 BP_SET_A1(command),
00192 0,
00193 clkpos,
00194 trpos
00195 );
00196 }
00197
00198 int enterLLCExtClock(
00199 struct MU* m, int clkpos, int trpos,
00200 unsigned short divisor,
00201 int internal_loopback,
00202 u32 command_mods
00203 )
00204 {
00205 unsigned command = BP_FC_SET_MODE_LLC_EXTCLOCK;
00206
00207 command |= command_mods;
00208
00209 if ( internal_loopback ){
00210 command += BP_FC_SET_MODE_LLC_INTDIV_CLK;
00211 }
00212 return enterLLC(
00213 m,
00214 BP_SET_A1(command),
00215 divisor,
00216 clkpos,
00217 trpos
00218 );
00219 }
00220
00221 int enterLLC_SYNC_ECM(
00222 struct MU* m, int clkpos, int trpos,
00223 unsigned short divisor,
00224 int internal_loopback,
00225 u32 command_mods,
00226 u32 init_buf_baddr
00227 )
00228 {
00229 setMbox( m, BP_MB_A4, init_buf_baddr);
00230 return enterLLCExtClock(m, clkpos, trpos,
00231 divisor, internal_loopback,
00232 command_mods|BP_FC_SET_LLCV2_INIT);
00233 }
00234
00235 int leaveLLC( struct MU* m )
00236 {
00237 llSetCmd( m,LLC_CSR_M_ESC );
00238 fprintf( stderr, "leave LLC\n" );
00239 return 0;
00240 }
00241
00242
00243 u32 llWaitDmaDone(struct MU* m)
00244
00245
00246
00247
00248 {
00249 u32 old_tlatch = getMboxShadow(m, BP_MB_LLC_TADC);
00250 u32 tlatch;
00251 int ipoll = 0;
00252
00253 do {
00254 tlatch = llGetTlatch( m );
00255 ++ipoll;
00256 }
00257 while (tlatch == old_tlatch);
00258
00259 setMboxPollcount(m, ipoll);
00260 return tlatch;
00261 }
00262
00263
00264
00265
00266
00267
00268
00269 #define ACQ196_TCR_MASK 0xfff
00270
00271 #define SERVICE_ROLLOVER(tim, reg, mask, temp) \
00272 temp = (reg) & (mask); \
00273 if (((tim) & (mask)) > (temp)){ \
00274 (tim) = (((tim) & ~(mask)) | (temp)) + ((mask)+1); \
00275 }else{ \
00276 (tim) = (((tim) & ~(mask)) | (temp)); \
00277 }
00278
00279
00280
00281 u32 llv2_extend32(u32 old32, u32 new12)
00282
00283 {
00284 u32 y = old32;
00285 u32 t;
00286
00287 SERVICE_ROLLOVER(y, new12, ACQ196_TCR_MASK, t);
00288 return y;
00289 }
00290
00291 #define LLCV2_POISON 0xf0000001
00292
00293 u32 llv2WaitDmaDone(struct MU *m, volatile u32* hstats)
00294
00295
00296
00297
00298
00299 {
00300 unsigned pollcat = 0;
00301 unsigned mask = 0xffffff;
00302
00303 while (hstats[LLCV2_STATUS_BDR] == LLCV2_POISON){
00304 if ((++pollcat&mask) == 0){
00305 fprintf(stderr,
00306 "polling[%08x] %p current 0x%08x wait poison\n",
00307 pollcat,
00308 &hstats[LLCV2_STATUS_BDR],
00309 hstats[LLCV2_STATUS_BDR]);
00310 mask = (mask << 1) | 1;
00311 }
00312 }
00313 while (hstats[LLCV2_STATUS_BDR] != 0xdeadbeef){
00314 if ((++pollcat&mask) == 0){
00315 fprintf(stderr, "polling[%08x] %p current 0x%08x\n",
00316 pollcat,
00317 &hstats[LLCV2_STATUS_BDR],
00318 hstats[LLCV2_STATUS_BDR]);
00319 mask = (mask << 1) | 1;
00320 }
00321 }
00322 hstats[LLCV2_STATUS_BDR] = LLCV2_POISON;
00323
00324 setMboxPollcount(m, pollcat);
00325
00326 return llv2_extend32(hstats[BP_MB_LLC_TADC],
00327 hstats[LLCV2_STATUS_TLATCH]);
00328 }
00329
00330
00331 u32 llv2WaitDmaDone_2v(struct MU *m, volatile u32* hstats, unsigned tlatch)
00332
00333
00334
00335
00336
00337 {
00338 unsigned pollcat = 0;
00339 unsigned mask = tlatch==0? 0x3fffffff: 0xffffff;
00340
00341 while (hstats[LLC_SYNC2V_IN_LAST] == LLCV2_POISON){
00342 if ((++pollcat&mask) == 0){
00343 fprintf(stderr,
00344 "polling[%08x] %p current 0x%08x\n",
00345 pollcat,
00346 &hstats[LLC_SYNC2V_IN_LAST],
00347 hstats[LLC_SYNC2V_IN_LAST]);
00348 mask = (mask << 1) | 1;
00349 }
00350 if (tlatch != 0 && pollcat > 0x7fffffff){
00351 fprintf(stderr, "ERROR: timeout\n");
00352 kill(getpid(), 1);
00353 return 0;
00354 }
00355 }
00356 hstats[LLC_SYNC2V_IN_LAST] = LLCV2_POISON;
00357
00358 setMboxPollcount(m, pollcat);
00359 return llv2_extend32(tlatch, hstats[LLCV2_STATUS_TLATCH]);
00360 }
00361
00362
00363 void llv2InitDmaDone(volatile u32* hstats) {
00364 hstats[LLCV2_STATUS_BDR] = LLCV2_POISON;
00365 hstats[LLC_SYNC2V_IN_LAST] = LLCV2_POISON;
00366 }