OpenCores
URL https://opencores.org/ocsvn/spacewiresystemc/spacewiresystemc/trunk

Subversion Repositories spacewiresystemc

[/] [spacewiresystemc/] [trunk/] [altera_work/] [spw_fifo_ulight/] [ulight_fifo/] [synthesis/] [submodules/] [sequencer/] [sequencer.pre.c] - Blame information for rev 32

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 32 redbear
/*
2
* Copyright Altera Corporation (C) 2012-2014. All rights reserved
3
*
4
* SPDX-License-Identifier:  BSD-3-Clause
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions are met:
8
*  * Redistributions of source code must retain the above copyright
9
*  notice, this list of conditions and the following disclaimer.
10
*  * Redistributions in binary form must reproduce the above copyright
11
*  notice, this list of conditions and the following disclaimer in the
12
*  documentation and/or other materials provided with the distribution.
13
*  * Neither the name of Altera Corporation nor the
14
*  names of its contributors may be used to endorse or promote products
15
*  derived from this software without specific prior written permission.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
* DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
21
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
*/
28
 
29
 
30
#include "sequencer_defines.h"
31
 
32
#include "alt_types.h"
33
#include "system.h"
34
#if HPS_HW
35
#include "sdram_io.h"
36
#else
37
#include "io.h"
38
#endif
39
#include "sequencer.h"
40
#include "tclrpt.h"
41
#include "sequencer_auto.h"
42
 
43
#if HHP_HPS_SIMULATION
44
#include "hps_controller.h"
45
#endif
46
 
47
 
48
/******************************************************************************
49
 ******************************************************************************
50
 ** NOTE: Special Rules for Globale Variables                                **
51
 **                                                                          **
52
 ** All global variables that are explicitly initialized (including          **
53
 ** explicitly initialized to zero), are only initialized once, during       **
54
 ** configuration time, and not again on reset.  This means that they        **
55
 ** preserve their current contents across resets, which is needed for some  **
56
 ** special cases involving communication with external modules.  In         **
57
 ** addition, this avoids paying the price to have the memory initialized,   **
58
 ** even for zeroed data, provided it is explicitly set to zero in the code, **
59
 ** and doesn't rely on implicit initialization.                             **
60
 ******************************************************************************
61
 ******************************************************************************/
62
 
63
#ifndef ARMCOMPILER
64
#if ARRIAV
65
// Temporary workaround to place the initial stack pointer at a safe offset from end
66
#define STRINGIFY(s)            STRINGIFY_STR(s)
67
#define STRINGIFY_STR(s)        #s
68
asm(".global __alt_stack_pointer");
69
asm("__alt_stack_pointer = " STRINGIFY(STACK_POINTER));
70
#endif
71
 
72
#if CYCLONEV
73
// Temporary workaround to place the initial stack pointer at a safe offset from end
74
#define STRINGIFY(s)            STRINGIFY_STR(s)
75
#define STRINGIFY_STR(s)        #s
76
asm(".global __alt_stack_pointer");
77
asm("__alt_stack_pointer = " STRINGIFY(STACK_POINTER));
78
#endif
79
#endif
80
 
81
#if ENABLE_PRINTF_LOG
82
#include <stdio.h>
83
#include <string.h>
84
 
85
typedef struct {
86
        alt_u32 v;
87
        alt_u32 p;
88
        alt_u32 d;
89
        alt_u32 ps;
90
} dqs_pos_t;
91
 
92
/*
93
The parameters that were previously here are now supplied by generation, until the new data manager is working.
94
*/
95
 
96
struct {
97
        const char *stage;
98
 
99
        alt_u32 vfifo_idx;
100
 
101
        dqs_pos_t gwrite_pos[RW_MGR_MEM_IF_WRITE_DQS_WIDTH];
102
 
103
        dqs_pos_t dqs_enable_left_edge[RW_MGR_MEM_IF_READ_DQS_WIDTH];
104
        dqs_pos_t dqs_enable_right_edge[RW_MGR_MEM_IF_READ_DQS_WIDTH];
105
        dqs_pos_t dqs_enable_mid[RW_MGR_MEM_IF_READ_DQS_WIDTH];
106
 
107
        dqs_pos_t dqs_wlevel_left_edge[RW_MGR_MEM_IF_WRITE_DQS_WIDTH];
108
        dqs_pos_t dqs_wlevel_right_edge[RW_MGR_MEM_IF_WRITE_DQS_WIDTH];
109
        dqs_pos_t dqs_wlevel_mid[RW_MGR_MEM_IF_WRITE_DQS_WIDTH];
110
 
111
        alt_32 dq_read_left_edge[RW_MGR_MEM_IF_READ_DQS_WIDTH][RW_MGR_MEM_DQ_PER_READ_DQS];
112
        alt_32 dq_read_right_edge[RW_MGR_MEM_IF_READ_DQS_WIDTH][RW_MGR_MEM_DQ_PER_READ_DQS];
113
        alt_32 dq_write_left_edge[RW_MGR_MEM_IF_WRITE_DQS_WIDTH][RW_MGR_MEM_DQ_PER_READ_DQS];
114
        alt_32 dq_write_right_edge[RW_MGR_MEM_IF_WRITE_DQS_WIDTH][RW_MGR_MEM_DQ_PER_READ_DQS];
115
        alt_32 dm_left_edge[RW_MGR_MEM_IF_WRITE_DQS_WIDTH][RW_MGR_NUM_DM_PER_WRITE_GROUP];
116
        alt_32 dm_right_edge[RW_MGR_MEM_IF_WRITE_DQS_WIDTH][RW_MGR_NUM_DM_PER_WRITE_GROUP];
117
} bfm_gbl;
118
 
119
#endif
120
 
121
#if HPS_HW
122
#include <sdram.h>
123
#endif // HPS_HW
124
 
125
#if BFM_MODE
126
#include <stdio.h>
127
 
128
// DPI access function via library
129
extern long long get_sim_time(void);
130
 
131
typedef struct {
132
        alt_u32 v;
133
        alt_u32 p;
134
        alt_u32 d;
135
        alt_u32 ps;
136
} dqs_pos_t;
137
 
138
/*
139
The parameters that were previously here are now supplied by generation, until the new data manager is working.
140
*/
141
 
142
struct {
143
        FILE *outfp;
144
        int bfm_skip_guaranteed_write;
145
        int trk_sample_count;
146
        int trk_long_idle_updates;
147
        int lfifo_margin;
148
        const char *stage;
149
 
150
        alt_u32 vfifo_idx;
151
 
152
        dqs_pos_t gwrite_pos[RW_MGR_MEM_IF_WRITE_DQS_WIDTH];
153
 
154
        dqs_pos_t dqs_enable_left_edge[RW_MGR_MEM_IF_READ_DQS_WIDTH];
155
        dqs_pos_t dqs_enable_right_edge[RW_MGR_MEM_IF_READ_DQS_WIDTH];
156
        dqs_pos_t dqs_enable_mid[RW_MGR_MEM_IF_READ_DQS_WIDTH];
157
 
158
        dqs_pos_t dqs_wlevel_left_edge[RW_MGR_MEM_IF_WRITE_DQS_WIDTH];
159
        dqs_pos_t dqs_wlevel_right_edge[RW_MGR_MEM_IF_WRITE_DQS_WIDTH];
160
        dqs_pos_t dqs_wlevel_mid[RW_MGR_MEM_IF_WRITE_DQS_WIDTH];
161
 
162
        alt_32 dq_read_left_edge[RW_MGR_MEM_IF_READ_DQS_WIDTH][RW_MGR_MEM_DQ_PER_READ_DQS];
163
        alt_32 dq_read_right_edge[RW_MGR_MEM_IF_READ_DQS_WIDTH][RW_MGR_MEM_DQ_PER_READ_DQS];
164
        alt_32 dq_write_left_edge[RW_MGR_MEM_IF_WRITE_DQS_WIDTH][RW_MGR_MEM_DQ_PER_WRITE_DQS];
165
        alt_32 dq_write_right_edge[RW_MGR_MEM_IF_WRITE_DQS_WIDTH][RW_MGR_MEM_DQ_PER_WRITE_DQS];
166
        alt_32 dm_left_edge[RW_MGR_MEM_IF_WRITE_DQS_WIDTH][RW_MGR_NUM_DM_PER_WRITE_GROUP];
167
        alt_32 dm_right_edge[RW_MGR_MEM_IF_WRITE_DQS_WIDTH][RW_MGR_NUM_DM_PER_WRITE_GROUP];
168
} bfm_gbl;
169
 
170
 
171
#endif
172
 
173
#if ENABLE_TCL_DEBUG
174
debug_data_t my_debug_data;
175
#endif
176
 
177
#define NEWVERSION_RDDESKEW 1
178
#define NEWVERSION_WRDESKEW 1
179
#define NEWVERSION_GW 1
180
#define NEWVERSION_WL 1
181
#define NEWVERSION_DQSEN 1
182
 
183
// Just to make the debugging code more uniform
184
#ifndef RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM
185
#define RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM 0
186
#endif
187
 
188
#if HALF_RATE
189
#define HALF_RATE_MODE 1
190
#else
191
#define HALF_RATE_MODE 0
192
#endif
193
 
194
#if QUARTER_RATE
195
#define QUARTER_RATE_MODE 1
196
#else
197
#define QUARTER_RATE_MODE 0
198
#endif
199
#define DELTA_D 1
200
 
201
// case:56390
202
// VFIFO_CONTROL_WIDTH_PER_DQS is the number of VFIFOs actually instantiated per DQS. This is always one except:
203
// AV QDRII where it is 2 for x18 and x18w2, and 4 for x36 and x36w2
204
// RLDRAMII x36 and x36w2 where it is 2.
205
// In 12.0sp1 we set this to 4 for all of the special cases above to keep it simple.
206
// In 12.0sp2 or 12.1 this should get moved to generation and unified with the same constant used in the phy mgr
207
 
208
#define VFIFO_CONTROL_WIDTH_PER_DQS 1
209
 
210
#if ARRIAV
211
 
212
#if QDRII 
213
 #if RW_MGR_MEM_DQ_PER_READ_DQS > 9
214
  #undef VFIFO_CONTROL_WIDTH_PER_DQS
215
  #define VFIFO_CONTROL_WIDTH_PER_DQS 4
216
 #endif
217
#endif // protocol check
218
 
219
#if RLDRAMII
220
 #if RW_MGR_MEM_DQ_PER_READ_DQS > 9
221
  #undef VFIFO_CONTROL_WIDTH_PER_DQS
222
  #define VFIFO_CONTROL_WIDTH_PER_DQS 2
223
 #endif
224
#endif // protocol check
225
 
226
#endif // family check
227
 
228
// In order to reduce ROM size, most of the selectable calibration steps are
229
// decided at compile time based on the user's calibration mode selection,
230
// as captured by the STATIC_CALIB_STEPS selection below.
231
//
232
// However, to support simulation-time selection of fast simulation mode, where
233
// we skip everything except the bare minimum, we need a few of the steps to
234
// be dynamic.  In those cases, we either use the DYNAMIC_CALIB_STEPS for the
235
// check, which is based on the rtl-supplied value, or we dynamically compute the
236
// value to use based on the dynamically-chosen calibration mode
237
 
238
#if QDRII
239
#define BTFLD_FMT "%llx"
240
#else
241
#define BTFLD_FMT "%lx"
242
#endif
243
 
244
#if BFM_MODE // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
245
 
246
 
247
// TODO: should make this configurable; could even have it read from config file or env at startup
248
#define DLEVEL 2
249
// space around comma is required for varargs macro to remove comma if args is empty
250
#define DPRINT(level, fmt, args...)     if (DLEVEL >= (level)) printf("[%lld] SEQ.C: " fmt "\n" , get_sim_time(), ## args)
251
#define IPRINT(fmt, args...)    printf("[%lld] SEQ.C: " fmt "\n" , get_sim_time(), ## args)
252
#define BFM_GBL_SET(field,value)        bfm_gbl.field = value
253
#define BFM_GBL_GET(field)              bfm_gbl.field
254
#define BFM_STAGE(label)                BFM_GBL_SET(stage,label)
255
#define BFM_INC_VFIFO                   bfm_gbl.vfifo_idx = (bfm_gbl.vfifo_idx + 1) % VFIFO_SIZE
256
#define COV(label)                      getpid() /* no-op marker for coverage */
257
 
258
#elif ENABLE_PRINTF_LOG // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
259
 
260
#define DLEVEL 2
261
 
262
void wait_printf_queue()
263
{
264
        alt_u32 next_entry;
265
 
266
        while (debug_printf_output->count == PRINTF_READ_BUFFER_FIFO_WORDS || debug_printf_output->slave_lock != 0)
267
        {}
268
 
269
        debug_printf_output->master_lock = 1;
270
        next_entry = (debug_printf_output->head + debug_printf_output->count) % PRINTF_READ_BUFFER_FIFO_WORDS;
271
        strcpy((char*)(&(debug_printf_output->read_buffer[next_entry])), (char*)(debug_printf_output->active_word));
272
        debug_printf_output->count++;
273
        debug_printf_output->master_lock = 0;
274
}
275
#define DPRINT(level, fmt, args...) \
276
        if (DLEVEL >= (level)) { \
277
                snprintf((char*)(debug_printf_output->active_word), PRINTF_READ_BUFFER_SIZE*4, "DEBUG:" fmt, ## args); \
278
                wait_printf_queue(); \
279
        }
280
#define IPRINT(fmt, args...) \
281
                snprintf((char*)(debug_printf_output->active_word), PRINTF_READ_BUFFER_SIZE*4, "INFO:" fmt, ## args); \
282
                wait_printf_queue();
283
 
284
#define BFM_GBL_SET(field,value)        bfm_gbl.field = value
285
#define BFM_GBL_GET(field)              bfm_gbl.field
286
#define BFM_STAGE(label)                BFM_GBL_SET(stage,label)
287
#define BFM_INC_VFIFO                   bfm_gbl.vfifo_idx = (bfm_gbl.vfifo_idx + 1) % VFIFO_SIZE
288
#define COV(label)
289
 
290
#elif HPS_HW // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
291
 
292
// For HPS running on actual hardware
293
 
294
#define DLEVEL 0
295
#ifdef HPS_HW_SERIAL_SUPPORT
296
// space around comma is required for varargs macro to remove comma if args is empty
297
#define DPRINT(level, fmt, args...)     if (DLEVEL >= (level)) printf("SEQ.C: " fmt "\n" , ## args)
298
#define IPRINT(fmt, args...)            printf("SEQ.C: " fmt "\n" , ## args)
299
#if RUNTIME_CAL_REPORT
300
#define RPRINT(fmt, args...)            printf("SEQ.C: " fmt "\n" , ## args)
301
#endif 
302
#else
303
#define DPRINT(level, fmt, args...)
304
#define IPRINT(fmt, args...)
305
#endif
306
#define BFM_GBL_SET(field,value)
307
#define BFM_GBL_GET(field)              ((long unsigned int)0)
308
#define BFM_STAGE(stage)        
309
#define BFM_INC_VFIFO
310
#define COV(label)
311
 
312
#else // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-----------------------------------
313
 
314
// Default mode
315
#define DPRINT(level, fmt, args...) 
316
#define IPRINT(fmt, args...)
317
#define BFM_GBL_SET(field,value)
318
#define BFM_GBL_GET(field) 0
319
#define BFM_STAGE(stage)        
320
#define BFM_INC_VFIFO
321
#define COV(label)
322
 
323
#endif // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~----------------------------------
324
 
325
#if BFM_MODE
326
#define TRACE_FUNC(fmt, args...) DPRINT(1, "%s[%ld]: " fmt, __func__, __LINE__ , ## args)
327
#else
328
#define TRACE_FUNC(fmt, args...) DPRINT(1, "%s[%d]: " fmt, __func__, __LINE__ , ## args)
329
#endif
330
 
331
#if BFM_MODE
332
// In BFM mode, we do full calibration as for real-rtl
333
#define DYNAMIC_CALIB_STEPS STATIC_CALIB_STEPS
334
#else
335
#define DYNAMIC_CALIB_STEPS (dyn_calib_steps)
336
#endif
337
 
338
#if STATIC_SIM_FILESET
339
#define STATIC_IN_RTL_SIM CALIB_IN_RTL_SIM
340
#else
341
#define STATIC_IN_RTL_SIM 0
342
#endif
343
 
344
#if STATIC_SKIP_MEM_INIT
345
#define STATIC_SKIP_DELAY_LOOPS CALIB_SKIP_DELAY_LOOPS
346
#else
347
#define STATIC_SKIP_DELAY_LOOPS 0
348
#endif
349
 
350
#if STATIC_FULL_CALIBRATION
351
#define STATIC_CALIB_STEPS (STATIC_IN_RTL_SIM | CALIB_SKIP_FULL_TEST | STATIC_SKIP_DELAY_LOOPS)
352
#elif STATIC_QUICK_CALIBRATION
353
#define STATIC_CALIB_STEPS (STATIC_IN_RTL_SIM | CALIB_SKIP_FULL_TEST | CALIB_SKIP_WRITES | CALIB_SKIP_DELAY_SWEEPS | CALIB_SKIP_ALL_BITS_CHK | STATIC_SKIP_DELAY_LOOPS)
354
#elif STATIC_SKIP_CALIBRATION
355
#define STATIC_CALIB_STEPS (STATIC_IN_RTL_SIM | CALIB_SKIP_FULL_TEST | CALIB_SKIP_WRITES | CALIB_SKIP_WLEVEL | CALIB_SKIP_LFIFO | CALIB_SKIP_VFIFO | CALIB_SKIP_DELAY_SWEEPS | CALIB_SKIP_ALL_BITS_CHK | STATIC_SKIP_DELAY_LOOPS)
356
#else
357
#undef STATIC_CALIB_STEPS
358
// This should force an error
359
#endif
360
 
361
// calibration steps requested by the rtl
362
alt_u16 dyn_calib_steps = 0;
363
 
364
// To make CALIB_SKIP_DELAY_LOOPS a dynamic conditional option
365
// instead of static, we use boolean logic to select between
366
// non-skip and skip values
367
//
368
// The mask is set to include all bits when not-skipping, but is
369
// zero when skipping
370
 
371
alt_u16 skip_delay_mask = 0;     // mask off bits when skipping/not-skipping
372
 
373
#define SKIP_DELAY_LOOP_VALUE_OR_ZERO(non_skip_value) \
374
        ((non_skip_value) & skip_delay_mask)
375
 
376
 
377
// TODO: The skip group strategy is completely missing
378
 
379
gbl_t *gbl = 0;
380
param_t *param = 0;
381
 
382
alt_u32 curr_shadow_reg = 0;
383
 
384
#if ENABLE_DELAY_CHAIN_WRITE
385
alt_u32 vfifo_settings[RW_MGR_MEM_IF_READ_DQS_WIDTH];
386
#endif // ENABLE_DELAY_CHAIN_WRITE
387
 
388
#if ENABLE_NON_DESTRUCTIVE_CALIB
389
// Technically, the use of these variables could be separated from ENABLE_NON_DESTRUCTIVE_CALIB
390
// but currently they are part of a single feature which is not fully validated, so we're keeping
391
// them together
392
 
393
// These variables can be modified by external rtl modules, and hence are "volatile"
394
volatile alt_u32 no_init = 0;
395
volatile alt_u32 abort_cal = 0;
396
#endif
397
 
398
alt_u32 rw_mgr_mem_calibrate_write_test (alt_u32 rank_bgn, alt_u32 write_group, alt_u32 use_dm, alt_u32 all_correct, t_btfld *bit_chk, alt_u32 all_ranks);
399
 
400
#if ENABLE_BRINGUP_DEBUGGING
401
 
402
#define DI_BUFFER_DEBUG_SIZE   64
403
 
404
alt_u8 di_buf_gbl[DI_BUFFER_DEBUG_SIZE*4] = {0};
405
 
406
void load_di_buf_gbl(void)
407
{
408
        int i;
409
        int j;
410
 
411
        for (i = 0; i < DI_BUFFER_DEBUG_SIZE; i++) {
412
                alt_u32 val = IORD_32DIRECT(RW_MGR_DI_BASE + i*4, 0);
413
                for (j = 0; j < 4; j++) {
414
                        alt_u8 byte = (val >> (8*j)) & 0xff;
415
                        di_buf_gbl[i*4 + j] = byte;
416
                }
417
        }
418
}
419
 
420
#endif  /* ENABLE_BRINGUP_DEBUGGING */
421
 
422
 
423
#if ENABLE_DQSEN_SWEEP
424
void init_di_buffer(void)
425
{
426
        alt_u32 i;
427
 
428
        debug_data->di_report.flags = 0;
429
        debug_data->di_report.cur_samples = 0;
430
 
431
        for (i = 0; i < NUM_DI_SAMPLE; i++)
432
        {
433
                debug_data->di_report.di_buffer[i].bit_chk = 0;
434
                debug_data->di_report.di_buffer[i].delay = 0;
435
                debug_data->di_report.di_buffer[i].d = 0;
436
                debug_data->di_report.di_buffer[i].v = 0;
437
                debug_data->di_report.di_buffer[i].p = 0;
438
                debug_data->di_report.di_buffer[i].di_buffer_0a = 0;
439
                debug_data->di_report.di_buffer[i].di_buffer_0b = 0;
440
                debug_data->di_report.di_buffer[i].di_buffer_1a = 0;
441
                debug_data->di_report.di_buffer[i].di_buffer_1b = 0;
442
                debug_data->di_report.di_buffer[i].di_buffer_2a = 0;
443
                debug_data->di_report.di_buffer[i].di_buffer_2b = 0;
444
                debug_data->di_report.di_buffer[i].di_buffer_3a = 0;
445
                debug_data->di_report.di_buffer[i].di_buffer_3b = 0;
446
                debug_data->di_report.di_buffer[i].di_buffer_4a = 0;
447
                debug_data->di_report.di_buffer[i].di_buffer_4b = 0;
448
        }
449
}
450
 
451
inline void flag_di_buffer_ready()
452
{
453
        debug_data->di_report.flags |= DI_REPORT_FLAGS_READY;
454
}
455
 
456
inline void flag_di_buffer_done()
457
{
458
        debug_data->di_report.flags |= DI_REPORT_FLAGS_READY;
459
        debug_data->di_report.flags |= DI_REPORT_FLAGS_DONE;
460
}
461
 
462
void wait_di_buffer(void)
463
{
464
        if (debug_data->di_report.cur_samples == NUM_DI_SAMPLE)
465
        {
466
                flag_di_buffer_ready();
467
                while (debug_data->di_report.cur_samples != 0)
468
                {
469
                }
470
                debug_data->di_report.flags = 0;
471
        }
472
}
473
 
474
void sample_di_data(alt_u32 bit_chk, alt_u32 delay, alt_u32 d, alt_u32 v, alt_u32 p)
475
{
476
        alt_u32 k;
477
        alt_u32 di_status_word;
478
        alt_u32 di_word_avail;
479
        alt_u32 di_write_to_read_ratio;
480
        alt_u32 di_write_to_read_ratio_2_exp;
481
 
482
        wait_di_buffer();
483
 
484
        k = debug_data->di_report.cur_samples;
485
 
486
        debug_data->di_report.di_buffer[k].bit_chk = bit_chk;
487
        debug_data->di_report.di_buffer[k].delay = delay;
488
        debug_data->di_report.di_buffer[k].d = d;
489
        debug_data->di_report.di_buffer[k].v = v;
490
        debug_data->di_report.di_buffer[k].p = p;
491
 
492
        di_status_word = IORD_32DIRECT(BASE_RW_MGR + 8, 0);
493
        di_word_avail = di_status_word & 0x0000FFFF;
494
        di_write_to_read_ratio = (di_status_word & 0x00FF0000) >> 16;
495
        di_write_to_read_ratio_2_exp = (di_status_word & 0xFF000000) >> 24;
496
 
497
        debug_data->di_report.di_buffer[k].di_buffer_0a = IORD_32DIRECT(BASE_RW_MGR + 16 + 0*4, 0);
498
        debug_data->di_report.di_buffer[k].di_buffer_0b = IORD_32DIRECT(BASE_RW_MGR + 16 + 1*4, 0);
499
        debug_data->di_report.di_buffer[k].di_buffer_1a = IORD_32DIRECT(BASE_RW_MGR + 16 + 2*4, 0);
500
        debug_data->di_report.di_buffer[k].di_buffer_1b = IORD_32DIRECT(BASE_RW_MGR + 16 + 3*4, 0);
501
        debug_data->di_report.di_buffer[k].di_buffer_2a = IORD_32DIRECT(BASE_RW_MGR + 16 + 4*4, 0);
502
        debug_data->di_report.di_buffer[k].di_buffer_2b = IORD_32DIRECT(BASE_RW_MGR + 16 + 5*4, 0);
503
        debug_data->di_report.di_buffer[k].di_buffer_3a = IORD_32DIRECT(BASE_RW_MGR + 16 + 6*4, 0);
504
        debug_data->di_report.di_buffer[k].di_buffer_3b = IORD_32DIRECT(BASE_RW_MGR + 16 + 7*4, 0);
505
        debug_data->di_report.di_buffer[k].di_buffer_4a = IORD_32DIRECT(BASE_RW_MGR + 16 + 8*4, 0);
506
        debug_data->di_report.di_buffer[k].di_buffer_4b = IORD_32DIRECT(BASE_RW_MGR + 16 + 9*4, 0);
507
 
508
        debug_data->di_report.cur_samples = debug_data->di_report.cur_samples + 1;
509
}
510
#endif
511
 
512
// This (TEST_SIZE) is used to test handling of large roms, to make
513
// sure we are sizing things correctly
514
// Note, the initialized data takes up twice the space in rom, since
515
// there needs to be a copy with the initial value and a copy that is
516
// written too, since on soft-reset, it needs to have the initial values
517
// without reloading the memory from external sources
518
 
519
// #define TEST_SIZE    (6*1024)
520
 
521
#ifdef TEST_SIZE
522
 
523
#define PRE_POST_TEST_SIZE 3
524
 
525
unsigned int pre_test_size_mem[PRE_POST_TEST_SIZE] = { 1, 2, 3};
526
 
527
unsigned int test_size_mem[TEST_SIZE/sizeof(unsigned int)] = { 100, 200, 300 };
528
 
529
unsigned int post_test_size_mem[PRE_POST_TEST_SIZE] = {10, 20, 30};
530
 
531
void write_test_mem(void)
532
{
533
        int i;
534
 
535
        for (i = 0; i < PRE_POST_TEST_SIZE; i++) {
536
                pre_test_size_mem[i] = (i+1)*10;
537
                post_test_size_mem[i] = (i+1);
538
        }
539
 
540
        for (i = 0; i < sizeof(test_size_mem)/sizeof(unsigned int); i++) {
541
                test_size_mem[i] = i;
542
        }
543
 
544
}
545
 
546
int check_test_mem(int start)
547
{
548
        int i;
549
 
550
        for (i = 0; i < PRE_POST_TEST_SIZE; i++) {
551
                if (start) {
552
                        if (pre_test_size_mem[i] != (i+1)) {
553
                                return 0;
554
                        }
555
                        if (post_test_size_mem[i] != (i+1)*10) {
556
                                return 0;
557
                        }
558
                } else {
559
                        if (pre_test_size_mem[i] != (i+1)*10) {
560
                                return 0;
561
                        }
562
                        if (post_test_size_mem[i] != (i+1)) {
563
                                return 0;
564
                        }
565
                }
566
        }
567
 
568
        for (i = 0; i < sizeof(test_size_mem)/sizeof(unsigned int); i++) {
569
                if (start) {
570
                        if (i < 3) {
571
                                if (test_size_mem[i] != (i+1)*100) {
572
                                        return 0;
573
                                }
574
                        } else {
575
                                if (test_size_mem[i] != 0) {
576
                                        return 0;
577
                                }
578
                        }
579
                } else {
580
                        if (test_size_mem[i] != i) {
581
                                return 0;
582
                        }
583
                }
584
        }
585
 
586
        return 1;
587
}
588
 
589
#endif // TEST_SIZE
590
 
591
static void set_failing_group_stage(alt_u32 group, alt_u32 stage, alt_u32 substage)
592
{
593
        ALTERA_ASSERT(group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
594
 
595
        // Only set the global stage if there was not been any other failing group
596
        if (gbl->error_stage == CAL_STAGE_NIL)
597
        {
598
                gbl->error_substage = substage;
599
                gbl->error_stage = stage;
600
                gbl->error_group = group;
601
                TCLRPT_SET(debug_summary_report->error_sub_stage, substage);
602
                TCLRPT_SET(debug_summary_report->error_stage, stage);
603
                TCLRPT_SET(debug_summary_report->error_group, group);
604
 
605
        }
606
 
607
        // Always set the group specific errors
608
        TCLRPT_SET(debug_cal_report->cal_status_per_group[curr_shadow_reg][group].error_stage, stage);
609
        TCLRPT_SET(debug_cal_report->cal_status_per_group[curr_shadow_reg][group].error_sub_stage, substage);
610
 
611
}
612
 
613
static inline void reg_file_set_group(alt_u32 set_group)
614
{
615
        // Read the current group and stage
616
        alt_u32 cur_stage_group = IORD_32DIRECT (REG_FILE_CUR_STAGE, 0);
617
 
618
        // Clear the group
619
        cur_stage_group &= 0x0000FFFF;
620
 
621
        // Set the group
622
        cur_stage_group |= (set_group << 16);
623
 
624
        // Write the data back
625
        IOWR_32DIRECT (REG_FILE_CUR_STAGE, 0, cur_stage_group);
626
}
627
 
628
static inline void reg_file_set_stage(alt_u32 set_stage)
629
{
630
        // Read the current group and stage
631
        alt_u32 cur_stage_group = IORD_32DIRECT (REG_FILE_CUR_STAGE, 0);
632
 
633
        // Clear the stage and substage
634
        cur_stage_group &= 0xFFFF0000;
635
 
636
        // Set the stage
637
        cur_stage_group |= (set_stage & 0x000000FF);
638
 
639
        // Write the data back
640
        IOWR_32DIRECT (REG_FILE_CUR_STAGE, 0, cur_stage_group);
641
}
642
 
643
static inline void reg_file_set_sub_stage(alt_u32 set_sub_stage)
644
{
645
        // Read the current group and stage
646
        alt_u32 cur_stage_group = IORD_32DIRECT (REG_FILE_CUR_STAGE, 0);
647
 
648
        // Clear the substage
649
        cur_stage_group &= 0xFFFF00FF;
650
 
651
        // Set the sub stage
652
        cur_stage_group |= ((set_sub_stage << 8) & 0x0000FF00);
653
 
654
        // Write the data back
655
        IOWR_32DIRECT (REG_FILE_CUR_STAGE, 0, cur_stage_group);
656
}
657
 
658
static inline alt_u32 is_write_group_enabled_for_dm(alt_u32 write_group)
659
{
660
#if DM_PINS_ENABLED
661
 #if RLDRAMII
662
        alt_32 decrement_counter = write_group + 1;
663
 
664
        while (decrement_counter > 0)
665
        {
666
                decrement_counter -= RW_MGR_MEM_IF_WRITE_DQS_WIDTH/RW_MGR_MEM_DATA_MASK_WIDTH;
667
        }
668
 
669
        if (decrement_counter == 0)
670
        {
671
                return 1;
672
        }
673
        else
674
        {
675
                return 0;
676
        }
677
 #else
678
        return 1;
679
 #endif
680
#else
681
        return 0;
682
#endif
683
}
684
 
685
static inline void select_curr_shadow_reg_using_rank(alt_u32 rank)
686
{
687
#if USE_SHADOW_REGS
688
        //USER Map the rank to its shadow reg and set the global variable
689
        curr_shadow_reg = (rank >> (NUM_RANKS_PER_SHADOW_REG - 1));
690
#endif
691
}
692
 
693
void initialize(void)
694
{
695
        TRACE_FUNC();
696
 
697
        //USER calibration has control over path to memory 
698
 
699
#if HARD_PHY
700
        // In Hard PHY this is a 2-bit control:
701
        // 0: AFI Mux Select
702
        // 1: DDIO Mux Select
703
        IOWR_32DIRECT (PHY_MGR_MUX_SEL, 0, 0x3);
704
#else
705
        IOWR_32DIRECT (PHY_MGR_MUX_SEL, 0, 1);
706
#endif
707
 
708
        //USER memory clock is not stable we begin initialization 
709
 
710
        IOWR_32DIRECT (PHY_MGR_RESET_MEM_STBL, 0, 0);
711
 
712
        //USER calibration status all set to zero 
713
 
714
        IOWR_32DIRECT (PHY_MGR_CAL_STATUS, 0, 0);
715
        IOWR_32DIRECT (PHY_MGR_CAL_DEBUG_INFO, 0, 0);
716
 
717
        if (((DYNAMIC_CALIB_STEPS) & CALIB_SKIP_ALL) != CALIB_SKIP_ALL) {
718
                param->read_correct_mask_vg  = ((t_btfld)1 << (RW_MGR_MEM_DQ_PER_READ_DQS / RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS)) - 1;
719
                param->write_correct_mask_vg = ((t_btfld)1 << (RW_MGR_MEM_DQ_PER_READ_DQS / RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS)) - 1;
720
                param->read_correct_mask     = ((t_btfld)1 << RW_MGR_MEM_DQ_PER_READ_DQS) - 1;
721
                param->write_correct_mask    = ((t_btfld)1 << RW_MGR_MEM_DQ_PER_WRITE_DQS) - 1;
722
                param->dm_correct_mask       = ((t_btfld)1 << (RW_MGR_MEM_DATA_WIDTH / RW_MGR_MEM_DATA_MASK_WIDTH)) - 1;
723
        }
724
}
725
 
726
 
727
#if MRS_MIRROR_PING_PONG_ATSO
728
// This code is specific to the ATSO setup.  There are two ways to set
729
// the cs/odt mask:
730
// 1. the normal way (set_rank_and_odt_mask)
731
//  This method will be used in general.  The behavior will be to unmask
732
//  BOTH CS (i.e. broadcast to both sides as if calibrating one large interface).
733
// 2. this function
734
//  This method will be used for MRS settings only.  This allows us to do settings
735
//  on a per-side basis.  This is needed because Slot 1 Rank 1 needs a mirrored MRS.
736
// This function is specific to our setup ONLY.
737
void set_rank_and_odt_mask_for_ping_pong_atso(alt_u32 side, alt_u32 odt_mode)
738
{
739
        alt_u32 odt_mask_0 = 0;
740
        alt_u32 odt_mask_1 = 0;
741
        alt_u32 cs_and_odt_mask;
742
 
743
        if(odt_mode == RW_MGR_ODT_MODE_READ_WRITE)
744
        {
745
                //USER 1 Rank
746
                //USER Read: ODT = 0
747
                //USER Write: ODT = 1
748
                odt_mask_0 = 0x0;
749
                odt_mask_1 = 0x1;
750
        }
751
        else
752
        {
753
                odt_mask_0 = 0x0;
754
                odt_mask_1 = 0x0;
755
        }
756
 
757
        cs_and_odt_mask =
758
                (0xFF & ~(1 << side)) |
759
                ((0xFF & odt_mask_0) << 8) |
760
                ((0xFF & odt_mask_1) << 16);
761
 
762
        IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, cs_and_odt_mask);
763
}
764
#endif
765
 
766
#if DDR3
767
void set_rank_and_odt_mask(alt_u32 rank, alt_u32 odt_mode)
768
{
769
        alt_u32 odt_mask_0 = 0;
770
        alt_u32 odt_mask_1 = 0;
771
        alt_u32 cs_and_odt_mask;
772
 
773
        if(odt_mode == RW_MGR_ODT_MODE_READ_WRITE)
774
        {
775
#if USE_SHADOW_REGS     
776
                alt_u32 rank_one_hot = (0xFF & (1 << rank));
777
                select_curr_shadow_reg_using_rank(rank);
778
 
779
                //USER Assert afi_rrank and afi_wrank. These signals ultimately drive
780
                //USER the read/write rank select signals which select the shadow register.
781
                IOWR_32DIRECT (RW_MGR_SET_ACTIVE_RANK, 0, rank_one_hot);
782
#endif  
783
 
784
                if ( LRDIMM ) {
785
                        // USER LRDIMMs have two cases to consider: single-slot and dual-slot.
786
                        // USER In single-slot, assert ODT for write only.
787
                        // USER In dual-slot, assert ODT for both slots for write,
788
                        // USER and on the opposite slot only for reads.
789
                        // USER
790
                        // USER Further complicating this is that both DIMMs have either 1 or 2 ODT
791
                        // USER inputs, which do the same thing (only one is actually required).
792
                        if ((RW_MGR_MEM_CHIP_SELECT_WIDTH/RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM) == 1) {
793
                                // USER Single-slot case
794
                                if (RW_MGR_MEM_ODT_WIDTH == 1) {
795
                                        // USER Read = 0, Write = 1
796
                                        odt_mask_0 = 0x0;
797
                                        odt_mask_1 = 0x1;
798
                                } else if (RW_MGR_MEM_ODT_WIDTH == 2) {
799
                                        // USER Read = 00, Write = 11
800
                                        odt_mask_0 = 0x0;
801
                                        odt_mask_1 = 0x3;
802
                                }
803
                        } else if ((RW_MGR_MEM_CHIP_SELECT_WIDTH/RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM) == 2) {
804
                                // USER Dual-slot case
805
                                if (RW_MGR_MEM_ODT_WIDTH == 2) {
806
                                        // USER Read: asserted for opposite slot, Write: asserted for both
807
                                        odt_mask_0 = (rank < 2) ? 0x2 : 0x1;
808
                                        odt_mask_1 = 0x3;
809
                                } else if (RW_MGR_MEM_ODT_WIDTH == 4) {
810
                                        // USER Read: asserted for opposite slot, Write: asserted for both
811
                                        odt_mask_0 = (rank < 2) ? 0xC : 0x3;
812
                                        odt_mask_1 = 0xF;
813
                                }
814
                        }
815
                } else if(RW_MGR_MEM_NUMBER_OF_RANKS == 1) {
816
                        //USER 1 Rank
817
                        //USER Read: ODT = 0
818
                        //USER Write: ODT = 1
819
                        odt_mask_0 = 0x0;
820
                        odt_mask_1 = 0x1;
821
                } else if(RW_MGR_MEM_NUMBER_OF_RANKS == 2) {
822
                        //USER 2 Ranks
823
                        if(RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM == 1 ||
824
                           (RDIMM && RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM == 2
825
                           && RW_MGR_MEM_CHIP_SELECT_WIDTH == 4)) {
826
                                //USER - Dual-Slot , Single-Rank (1 chip-select per DIMM)
827
                                //USER OR
828
                                //USER - RDIMM, 4 total CS (2 CS per DIMM) means 2 DIMM
829
                                //USER Since MEM_NUMBER_OF_RANKS is 2 they are both single rank
830
                                //USER with 2 CS each (special for RDIMM)
831
                                //USER Read: Turn on ODT on the opposite rank
832
                                //USER Write: Turn on ODT on all ranks
833
                                odt_mask_0 = 0x3 & ~(1 << rank);
834
                                odt_mask_1 = 0x3;
835
                        } else {
836
                                //USER - Single-Slot , Dual-rank DIMMs (2 chip-selects per DIMM)
837
                                //USER Read: Turn on ODT off on all ranks
838
                                //USER Write: Turn on ODT on active rank
839
                                odt_mask_0 = 0x0;
840
                                odt_mask_1 = 0x3 & (1 << rank);
841
                        }
842
                                } else {
843
                        //USER 4 Ranks
844
                        //USER Read:
845
                        //USER ----------+-----------------------+
846
                        //USER           |                       |
847
                        //USER           |         ODT           |
848
                        //USER Read From +-----------------------+
849
                        //USER   Rank    |  3  |  2  |  1  |  0  |
850
                        //USER ----------+-----+-----+-----+-----+
851
                        //USER     0     |  0  |  1  |  0  |  0  |
852
                        //USER     1     |  1  |  0  |  0  |  0  |
853
                        //USER     2     |  0  |  0  |  0  |  1  |
854
                        //USER     3     |  0  |  0  |  1  |  0  |
855
                        //USER ----------+-----+-----+-----+-----+
856
                        //USER
857
                        //USER Write:
858
                        //USER ----------+-----------------------+
859
                        //USER           |                       |
860
                        //USER           |         ODT           |
861
                        //USER Write To  +-----------------------+
862
                        //USER   Rank    |  3  |  2  |  1  |  0  |
863
                        //USER ----------+-----+-----+-----+-----+
864
                        //USER     0     |  0  |  1  |  0  |  1  |
865
                        //USER     1     |  1  |  0  |  1  |  0  |
866
                        //USER     2     |  0  |  1  |  0  |  1  |
867
                        //USER     3     |  1  |  0  |  1  |  0  |
868
                        //USER ----------+-----+-----+-----+-----+
869
                        switch(rank)
870
                        {
871
                                case 0:
872
                                        odt_mask_0 = 0x4;
873
                                        odt_mask_1 = 0x5;
874
                                break;
875
                                case 1:
876
                                        odt_mask_0 = 0x8;
877
                                        odt_mask_1 = 0xA;
878
                                break;
879
                                case 2:
880
                                        odt_mask_0 = 0x1;
881
                                        odt_mask_1 = 0x5;
882
                                break;
883
                                case 3:
884
                                        odt_mask_0 = 0x2;
885
                                        odt_mask_1 = 0xA;
886
                                break;
887
                        }
888
                }
889
        }
890
        else
891
        {
892
                odt_mask_0 = 0x0;
893
                odt_mask_1 = 0x0;
894
        }
895
 
896
#if ADVANCED_ODT_CONTROL
897
        // odt_mask_0 = read
898
        // odt_mask_1 = write
899
        odt_mask_0  = (CFG_READ_ODT_CHIP  >> (RW_MGR_MEM_ODT_WIDTH * rank));
900
        odt_mask_1  = (CFG_WRITE_ODT_CHIP >> (RW_MGR_MEM_ODT_WIDTH * rank));
901
        odt_mask_0 &= ((1 << RW_MGR_MEM_ODT_WIDTH) - 1);
902
        odt_mask_1 &= ((1 << RW_MGR_MEM_ODT_WIDTH) - 1);
903
#endif
904
 
905
#if MRS_MIRROR_PING_PONG_ATSO
906
        // See set_cs_and_odt_mask_for_ping_pong_atso
907
        cs_and_odt_mask =
908
                        (0xFC) |
909
                        ((0xFF & odt_mask_0) << 8) |
910
                        ((0xFF & odt_mask_1) << 16);
911
#else
912
        if(RDIMM && RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM == 2
913
           && RW_MGR_MEM_CHIP_SELECT_WIDTH == 4 && RW_MGR_MEM_NUMBER_OF_RANKS == 2) {
914
                //USER See RDIMM special case above
915
                cs_and_odt_mask =
916
                        (0xFF & ~(1 << (2*rank))) |
917
                        ((0xFF & odt_mask_0) << 8) |
918
                        ((0xFF & odt_mask_1) << 16);
919
        } else if (LRDIMM) {
920
#if LRDIMM
921
                // USER LRDIMM special cases - When RM=2, CS[2] is remapped to A[16] so skip it,
922
                // USER and when RM=4, CS[3:2] are remapped to A[17:16] so skip them both.
923
                alt_u32 lrdimm_rank = 0;
924
                alt_u32 lrdimm_rank_mask = 0;
925
 
926
                //USER When rank multiplication is active, the remapped CS pins must be forced low
927
                //USER instead of high for proper targetted RTT_NOM programming.
928
                if (LRDIMM_RANK_MULTIPLICATION_FACTOR == 2) {
929
                        // USER Mask = CS[5:0] = 011011
930
                        lrdimm_rank_mask = (0x3 | (0x3 << 3));
931
                } else if (LRDIMM_RANK_MULTIPLICATION_FACTOR == 4) {
932
                        // USER Mask = CS[7:0] = 00110011
933
                        lrdimm_rank_mask = (0x3 | (0x3 << 4));
934
                }
935
 
936
                // USER Handle LRDIMM cases where Rank multiplication may be active
937
                if (((RW_MGR_MEM_CHIP_SELECT_WIDTH/RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM) == 1)) {
938
                        // USER Single-DIMM case
939
                        lrdimm_rank = ~(1 << rank);
940
                } else if ((RW_MGR_MEM_CHIP_SELECT_WIDTH/RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM) == 2) {
941
                        if (rank < (RW_MGR_MEM_NUMBER_OF_RANKS >> 1)) {
942
                        // USER Dual-DIMM case, accessing first slot
943
                                lrdimm_rank = ~(1 << rank);
944
                        } else {
945
                        // USER Dual-DIMM case, accessing second slot
946
                                lrdimm_rank = ~(1 << (rank + RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM - (RW_MGR_MEM_NUMBER_OF_RANKS>>1)));
947
                        }
948
                }
949
                cs_and_odt_mask =
950
                        (lrdimm_rank_mask & lrdimm_rank) |
951
                        ((0xFF & odt_mask_0) << 8) |
952
                        ((0xFF & odt_mask_1) << 16);
953
#endif // LRDIMM
954
        } else {
955
                cs_and_odt_mask =
956
                        (0xFF & ~(1 << rank)) |
957
                        ((0xFF & odt_mask_0) << 8) |
958
                        ((0xFF & odt_mask_1) << 16);
959
        }
960
#endif
961
 
962
        IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, cs_and_odt_mask);
963
}
964
#else
965
#if DDR2
966
void set_rank_and_odt_mask(alt_u32 rank, alt_u32 odt_mode)
967
{
968
        alt_u32 odt_mask_0 = 0;
969
        alt_u32 odt_mask_1 = 0;
970
        alt_u32 cs_and_odt_mask;
971
 
972
        if(odt_mode == RW_MGR_ODT_MODE_READ_WRITE)
973
        {
974
                if(RW_MGR_MEM_NUMBER_OF_RANKS == 1) {
975
                        //USER 1 Rank
976
                        //USER Read: ODT = 0
977
                        //USER Write: ODT = 1
978
                        odt_mask_0 = 0x0;
979
                        odt_mask_1 = 0x1;
980
                } else if(RW_MGR_MEM_NUMBER_OF_RANKS == 2) {
981
                        //USER 2 Ranks
982
                        if(RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM == 1 ||
983
                           (RDIMM && RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM == 2
984
                           && RW_MGR_MEM_CHIP_SELECT_WIDTH == 4)) {
985
                                //USER - Dual-Slot , Single-Rank (1 chip-select per DIMM)
986
                                //USER OR
987
                                //USER - RDIMM, 4 total CS (2 CS per DIMM) means 2 DIMM
988
                                //USER Since MEM_NUMBER_OF_RANKS is 2 they are both single rank
989
                                //USER with 2 CS each (special for RDIMM)
990
                                //USER Read/Write: Turn on ODT on the opposite rank
991
                                odt_mask_0 = 0x3 & ~(1 << rank);
992
                                odt_mask_1 = 0x3 & ~(1 << rank);
993
                        } else {
994
                                //USER - Single-Slot , Dual-rank DIMMs (2 chip-selects per DIMM)
995
                                //USER Read: Turn on ODT off on all ranks
996
                                //USER Write: Turn on ODT on active rank
997
                                odt_mask_0 = 0x0;
998
                                odt_mask_1 = 0x3 & (1 << rank);
999
                        }
1000
                } else {
1001
                        //USER 4 Ranks
1002
                        //USER Read/Write:
1003
                        //USER -----------+-----------------------+
1004
                        //USER            |                       |
1005
                        //USER            |         ODT           |
1006
                        //USER Read/Write |                       |
1007
                        //USER   From     +-----------------------+
1008
                        //USER   Rank     |  3  |  2  |  1  |  0  |
1009
                        //USER -----------+-----+-----+-----+-----+
1010
                        //USER     0      |  0  |  1  |  0  |  0  |
1011
                        //USER     1      |  1  |  0  |  0  |  0  |
1012
                        //USER     2      |  0  |  0  |  0  |  1  |
1013
                        //USER     3      |  0  |  0  |  1  |  0  |
1014
                        //USER -----------+-----+-----+-----+-----+
1015
                        switch(rank)
1016
                        {
1017
                                case 0:
1018
                                        odt_mask_0 = 0x4;
1019
                                        odt_mask_1 = 0x4;
1020
                                break;
1021
                                case 1:
1022
                                        odt_mask_0 = 0x8;
1023
                                        odt_mask_1 = 0x8;
1024
                                break;
1025
                                case 2:
1026
                                        odt_mask_0 = 0x1;
1027
                                        odt_mask_1 = 0x1;
1028
                                break;
1029
                                case 3:
1030
                                        odt_mask_0 = 0x2;
1031
                                        odt_mask_1 = 0x2;
1032
                                break;
1033
                        }
1034
                }
1035
        }
1036
        else
1037
        {
1038
                odt_mask_0 = 0x0;
1039
                odt_mask_1 = 0x0;
1040
        }
1041
 
1042
        if(RDIMM && RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM == 2
1043
           && RW_MGR_MEM_CHIP_SELECT_WIDTH == 4 && RW_MGR_MEM_NUMBER_OF_RANKS == 2) {
1044
                //USER See RDIMM/LRDIMM special case above
1045
                cs_and_odt_mask =
1046
                        (0xFF & ~(1 << (2*rank))) |
1047
                        ((0xFF & odt_mask_0) << 8) |
1048
                        ((0xFF & odt_mask_1) << 16);
1049
        } else {
1050
                cs_and_odt_mask =
1051
                        (0xFF & ~(1 << rank)) |
1052
                        ((0xFF & odt_mask_0) << 8) |
1053
                        ((0xFF & odt_mask_1) << 16);
1054
        }
1055
 
1056
        IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, cs_and_odt_mask);
1057
}
1058
#else // QDRII and RLDRAMx
1059
void set_rank_and_odt_mask(alt_u32 rank, alt_u32 odt_mode)
1060
{
1061
        alt_u32 cs_and_odt_mask =
1062
                (0xFF & ~(1 << rank));
1063
 
1064
        IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, cs_and_odt_mask);
1065
}
1066
#endif
1067
#endif
1068
 
1069
//USER Given a rank, select the set of shadow registers that is responsible for the
1070
//USER delays of such rank, so that subsequent SCC updates will go to those shadow
1071
//USER registers. 
1072
void select_shadow_regs_for_update (alt_u32 rank, alt_u32 group, alt_u32 update_scan_chains)
1073
{
1074
#if USE_SHADOW_REGS
1075
        alt_u32 rank_one_hot = (0xFF & (1 << rank));
1076
 
1077
        //USER Assert afi_rrank and afi_wrank. These signals ultimately drive
1078
        //USER the read/write rank select signals which select the shadow register.
1079
        IOWR_32DIRECT (RW_MGR_SET_ACTIVE_RANK, 0, rank_one_hot);
1080
 
1081
        //USER Cause the SCC manager to switch its register file, which is used as
1082
        //USER local cache of the various dtap/ptap settings. There's one register file
1083
        //USER per shadow register set.
1084
        IOWR_32DIRECT (SCC_MGR_ACTIVE_RANK, 0, rank_one_hot);
1085
 
1086
        if (update_scan_chains) {
1087
                alt_u32 i;
1088
 
1089
                //USER On the read side, a memory read is required because the read rank
1090
                //USER select signal (as well as the postamble delay chain settings) is clocked
1091
                //USER into the periphery by the postamble signal. Simply asserting afi_rrank
1092
                //USER is not enough. If update_scc_regfile is not set, we assume there'll be a 
1093
                //USER subsequent read that'll handle this.
1094
                for (i = 0; i < RW_MGR_MEM_NUMBER_OF_RANKS; ++i) {
1095
 
1096
                        //USER The dummy read can go to any non-skipped rank.
1097
                        //USER Skipped ranks are uninitialized and their banks are un-activated.
1098
                        //USER Accessing skipped ranks can lead to bad behavior.
1099
                        if (! param->skip_ranks[i]) {
1100
 
1101
                                set_rank_and_odt_mask(i, RW_MGR_ODT_MODE_READ_WRITE);
1102
 
1103
                                // must re-assert afi_wrank/afi_rrank prior to issuing read 
1104
                                // because set_rank_and_odt_mask may have changed the signals.
1105
                                IOWR_32DIRECT (RW_MGR_SET_ACTIVE_RANK, 0, rank_one_hot);
1106
 
1107
                                IOWR_32DIRECT (RW_MGR_LOAD_CNTR_1, 0, 0x10);
1108
                                IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_1, 0, __RW_MGR_READ_B2B_WAIT1);
1109
 
1110
                                IOWR_32DIRECT (RW_MGR_LOAD_CNTR_2, 0, 0x10);
1111
                                IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_2, 0, __RW_MGR_READ_B2B_WAIT2);
1112
 
1113
                                IOWR_32DIRECT (RW_MGR_LOAD_CNTR_0, 0, 0x0);
1114
                                IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_0, 0, __RW_MGR_READ_B2B);
1115
 
1116
                                IOWR_32DIRECT (RW_MGR_LOAD_CNTR_3, 0, 0x0);
1117
                                IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_3, 0, __RW_MGR_READ_B2B);
1118
 
1119
                                IOWR_32DIRECT (RW_MGR_RUN_ALL_GROUPS, 0, __RW_MGR_READ_B2B);
1120
 
1121
                                //USER The dummy read above may cause the DQS enable signal to be stuck high.
1122
                                //USER The following corrects this.
1123
                                IOWR_32DIRECT (RW_MGR_RUN_ALL_GROUPS, 0, __RW_MGR_CLEAR_DQS_ENABLE);
1124
 
1125
                                set_rank_and_odt_mask(i, RW_MGR_ODT_MODE_OFF);
1126
 
1127
                                break;
1128
                        }
1129
                }
1130
 
1131
                //USER Reset the fifos to get pointers to known state 
1132
                IOWR_32DIRECT (PHY_MGR_CMD_FIFO_RESET, 0, 0);
1133
                IOWR_32DIRECT (RW_MGR_RESET_READ_DATAPATH, 0, 0);
1134
 
1135
                //USER On the write side the afi_wrank signal eventually propagates to the I/O 
1136
                //USER through the write datapath. We need to make sure we wait long enough for
1137
                //USER this to happen. The operations above should be enough, hence no extra delay
1138
                //USER inserted here.
1139
 
1140
                //USER Make sure the data in the I/O scan chains are in-sync with the register
1141
                //USER file inside the SCC manager. If we don't do this, a subsequent SCC_UPDATE
1142
                //USER may cause stale data for the other shadow register to be loaded. This must
1143
                //USER be done for every scan chain of the current group. Note that in shadow
1144
                //USER register mode, the SCC_UPDATE signal is per-group.
1145
                IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, group);
1146
 
1147
                IOWR_32DIRECT (SCC_MGR_DQS_ENA, 0, group);
1148
                IOWR_32DIRECT (SCC_MGR_DQS_IO_ENA, 0, 0);
1149
 
1150
                for (i = 0; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++) {
1151
                        IOWR_32DIRECT (SCC_MGR_DQ_ENA, 0, i);
1152
                }
1153
                for (i = 0; i < RW_MGR_NUM_DM_PER_WRITE_GROUP; i++) {
1154
                        IOWR_32DIRECT (SCC_MGR_DM_ENA, 0, i);
1155
                }
1156
        }
1157
 
1158
        //USER Map the rank to its shadow reg
1159
        select_curr_shadow_reg_using_rank(rank);
1160
#endif
1161
}
1162
 
1163
#if HHP_HPS
1164
void scc_mgr_initialize(void)
1165
{
1166
        // Clear register file for HPS
1167
        // 16 (2^4) is the size of the full register file in the scc mgr:
1168
        //      RFILE_DEPTH = log2(MEM_DQ_PER_DQS + 1 + MEM_DM_PER_DQS + MEM_IF_READ_DQS_WIDTH - 1) + 1;
1169
        alt_u32 i;
1170
        for (i = 0; i < 16; i++) {
1171
                DPRINT(1, "Clearing SCC RFILE index %lu", i);
1172
                IOWR_32DIRECT(SCC_MGR_HHP_RFILE, i << 2, 0);
1173
        }
1174
}
1175
#endif
1176
 
1177
inline void scc_mgr_set_dqs_bus_in_delay(alt_u32 read_group, alt_u32 delay)
1178
{
1179
        ALTERA_ASSERT(read_group < RW_MGR_MEM_IF_READ_DQS_WIDTH);
1180
 
1181
        // Load the setting in the SCC manager
1182
        WRITE_SCC_DQS_IN_DELAY(read_group, delay);
1183
 
1184
        // Make the setting in the TCL report
1185
        TCLRPT_SET(debug_cal_report->cal_dqs_in_settings[curr_shadow_reg][read_group].dqs_bus_in_delay, delay);
1186
 
1187
}
1188
 
1189
static inline void scc_mgr_set_dqs_io_in_delay(alt_u32 write_group, alt_u32 delay)
1190
{
1191
        ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
1192
 
1193
        // Load the setting in the SCC manager
1194
        WRITE_SCC_DQS_IO_IN_DELAY(delay);
1195
 
1196
        // Make the setting in the TCL report
1197
        TCLRPT_SET(debug_cal_report->cal_dqs_out_settings[curr_shadow_reg][write_group].dqs_io_in_delay, delay);
1198
 
1199
}
1200
 
1201
static inline void scc_mgr_set_dqs_en_phase(alt_u32 read_group, alt_u32 phase)
1202
{
1203
        ALTERA_ASSERT(read_group < RW_MGR_MEM_IF_READ_DQS_WIDTH);
1204
 
1205
        // Load the setting in the SCC manager
1206
        WRITE_SCC_DQS_EN_PHASE(read_group, phase);
1207
 
1208
        // Make the setting in the TCL report
1209
        TCLRPT_SET(debug_cal_report->cal_dqs_in_settings[curr_shadow_reg][read_group].dqs_en_phase, phase);
1210
 
1211
}
1212
 
1213
void scc_mgr_set_dqs_en_phase_all_ranks (alt_u32 read_group, alt_u32 phase)
1214
{
1215
        alt_u32 r;
1216
        alt_u32 update_scan_chains;
1217
 
1218
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r += NUM_RANKS_PER_SHADOW_REG) {
1219
                //USER although the h/w doesn't support different phases per shadow register,
1220
                //USER for simplicity our scc manager modeling keeps different phase settings per 
1221
                //USER shadow reg, and it's important for us to keep them in sync to match h/w.
1222
                //USER for efficiency, the scan chain update should occur only once to sr0.
1223
                update_scan_chains = (r == 0) ? 1 : 0;
1224
 
1225
                select_shadow_regs_for_update(r, read_group, update_scan_chains);
1226
                scc_mgr_set_dqs_en_phase(read_group, phase);
1227
 
1228
                if (update_scan_chains) {
1229
                        IOWR_32DIRECT (SCC_MGR_DQS_ENA, 0, read_group);
1230
                        IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
1231
                }
1232
        }
1233
}
1234
 
1235
 
1236
static inline void scc_mgr_set_dqdqs_output_phase(alt_u32 write_group, alt_u32 phase)
1237
{
1238
        ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
1239
 
1240
        #if CALIBRATE_BIT_SLIPS
1241
        alt_u32 num_fr_slips = 0;
1242
        while (phase > IO_DQDQS_OUT_PHASE_MAX) {
1243
                phase -= IO_DLL_CHAIN_LENGTH;
1244
                num_fr_slips++;
1245
        }
1246
        IOWR_32DIRECT (PHY_MGR_FR_SHIFT, write_group*4, num_fr_slips);
1247
#endif
1248
 
1249
        // Load the setting in the SCC manager
1250
        WRITE_SCC_DQDQS_OUT_PHASE(write_group, phase);
1251
 
1252
        // Make the setting in the TCL report
1253
        TCLRPT_SET(debug_cal_report->cal_dqs_out_settings[curr_shadow_reg][write_group].dqdqs_out_phase, phase);
1254
 
1255
}
1256
 
1257
void scc_mgr_set_dqdqs_output_phase_all_ranks (alt_u32 write_group, alt_u32 phase)
1258
{
1259
        alt_u32 r;
1260
        alt_u32 update_scan_chains;
1261
 
1262
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r += NUM_RANKS_PER_SHADOW_REG) {
1263
                //USER although the h/w doesn't support different phases per shadow register,
1264
                //USER for simplicity our scc manager modeling keeps different phase settings per 
1265
                //USER shadow reg, and it's important for us to keep them in sync to match h/w.
1266
                //USER for efficiency, the scan chain update should occur only once to sr0.
1267
                update_scan_chains = (r == 0) ? 1 : 0;
1268
 
1269
                select_shadow_regs_for_update(r, write_group, update_scan_chains);
1270
                scc_mgr_set_dqdqs_output_phase(write_group, phase);
1271
 
1272
                if (update_scan_chains) {
1273
                        IOWR_32DIRECT (SCC_MGR_DQS_ENA, 0, write_group);
1274
                        IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
1275
                }
1276
        }
1277
}
1278
 
1279
 
1280
static inline void scc_mgr_set_dqs_en_delay(alt_u32 read_group, alt_u32 delay)
1281
{
1282
        ALTERA_ASSERT(read_group < RW_MGR_MEM_IF_READ_DQS_WIDTH);
1283
 
1284
        // Load the setting in the SCC manager
1285
        WRITE_SCC_DQS_EN_DELAY(read_group, delay);
1286
 
1287
        // Make the setting in the TCL report
1288
        TCLRPT_SET(debug_cal_report->cal_dqs_in_settings[curr_shadow_reg][read_group].dqs_en_delay, delay);
1289
 
1290
}
1291
 
1292
void scc_mgr_set_dqs_en_delay_all_ranks (alt_u32 read_group, alt_u32 delay)
1293
{
1294
        alt_u32 r;
1295
 
1296
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r += NUM_RANKS_PER_SHADOW_REG) {
1297
 
1298
                select_shadow_regs_for_update(r, read_group, 0);
1299
 
1300
                scc_mgr_set_dqs_en_delay(read_group, delay);
1301
 
1302
                IOWR_32DIRECT (SCC_MGR_DQS_ENA, 0, read_group);
1303
 
1304
#if !USE_SHADOW_REGS            
1305
                // In shadow register mode, the T11 settings are stored in registers
1306
                // in the core, which are updated by the DQS_ENA signals. Not issuing
1307
                // the SCC_MGR_UPD command allows us to save lots of rank switching
1308
                // overhead, by calling select_shadow_regs_for_update with update_scan_chains
1309
                // set to 0.
1310
                IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
1311
#endif          
1312
        }
1313
}
1314
 
1315
static void scc_mgr_set_oct_out1_delay(alt_u32 write_group, alt_u32 delay)
1316
{
1317
        alt_u32 read_group;
1318
 
1319
        ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
1320
 
1321
        // Load the setting in the SCC manager
1322
        // Although OCT affects only write data, the OCT delay is controlled by the DQS logic block
1323
        // which is instantiated once per read group. For protocols where a write group consists
1324
        // of multiple read groups, the setting must be set multiple times.
1325
        for (read_group = write_group * RW_MGR_MEM_IF_READ_DQS_WIDTH / RW_MGR_MEM_IF_WRITE_DQS_WIDTH;
1326
                 read_group < (write_group + 1) * RW_MGR_MEM_IF_READ_DQS_WIDTH / RW_MGR_MEM_IF_WRITE_DQS_WIDTH;
1327
                 ++read_group) {
1328
 
1329
                WRITE_SCC_OCT_OUT1_DELAY(read_group, delay);
1330
        }
1331
 
1332
        // Make the setting in the TCL report
1333
        TCLRPT_SET(debug_cal_report->cal_dqs_out_settings[curr_shadow_reg][write_group].oct_out_delay1, delay);
1334
 
1335
}
1336
 
1337
static void scc_mgr_set_oct_out2_delay(alt_u32 write_group, alt_u32 delay)
1338
{
1339
        alt_u32 read_group;
1340
 
1341
        ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
1342
 
1343
        // Load the setting in the SCC manager
1344
        // Although OCT affects only write data, the OCT delay is controlled by the DQS logic block
1345
        // which is instantiated once per read group. For protocols where a write group consists
1346
        // of multiple read groups, the setting must be set multiple times.
1347
        for (read_group = write_group * RW_MGR_MEM_IF_READ_DQS_WIDTH / RW_MGR_MEM_IF_WRITE_DQS_WIDTH;
1348
                 read_group < (write_group + 1) * RW_MGR_MEM_IF_READ_DQS_WIDTH / RW_MGR_MEM_IF_WRITE_DQS_WIDTH;
1349
                 ++read_group) {
1350
 
1351
                WRITE_SCC_OCT_OUT2_DELAY(read_group, delay);
1352
        }
1353
 
1354
        // Make the setting in the TCL report
1355
        TCLRPT_SET(debug_cal_report->cal_dqs_out_settings[curr_shadow_reg][write_group].oct_out_delay2, delay);
1356
 
1357
}
1358
 
1359
static inline void scc_mgr_set_dqs_bypass(alt_u32 write_group, alt_u32 bypass)
1360
{
1361
        // Load the setting in the SCC manager
1362
        WRITE_SCC_DQS_BYPASS(write_group, bypass);
1363
}
1364
 
1365
inline void scc_mgr_set_dq_out1_delay(alt_u32 write_group, alt_u32 dq_in_group, alt_u32 delay)
1366
{
1367
#if ENABLE_TCL_DEBUG || ENABLE_ASSERT
1368
        alt_u32 dq = write_group*RW_MGR_MEM_DQ_PER_WRITE_DQS + dq_in_group;
1369
#endif
1370
 
1371
        ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
1372
        ALTERA_ASSERT(dq < RW_MGR_MEM_DATA_WIDTH);
1373
 
1374
        // Load the setting in the SCC manager
1375
        WRITE_SCC_DQ_OUT1_DELAY(dq_in_group, delay);
1376
 
1377
        // Make the setting in the TCL report
1378
        TCLRPT_SET(debug_cal_report->cal_dq_settings[curr_shadow_reg][dq].dq_out_delay1, delay);
1379
 
1380
}
1381
 
1382
inline void scc_mgr_set_dq_out2_delay(alt_u32 write_group, alt_u32 dq_in_group, alt_u32 delay)
1383
{
1384
#if ENABLE_TCL_DEBUG || ENABLE_ASSERT
1385
        alt_u32 dq = write_group*RW_MGR_MEM_DQ_PER_WRITE_DQS + dq_in_group;
1386
#endif
1387
 
1388
        ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
1389
        ALTERA_ASSERT(dq < RW_MGR_MEM_DATA_WIDTH);
1390
 
1391
        // Load the setting in the SCC manager
1392
        WRITE_SCC_DQ_OUT2_DELAY(dq_in_group, delay);
1393
 
1394
        // Make the setting in the TCL report
1395
        TCLRPT_SET(debug_cal_report->cal_dq_settings[curr_shadow_reg][dq].dq_out_delay2, delay);
1396
 
1397
}
1398
 
1399
inline void scc_mgr_set_dq_in_delay(alt_u32 write_group, alt_u32 dq_in_group, alt_u32 delay)
1400
{
1401
#if ENABLE_TCL_DEBUG || ENABLE_ASSERT
1402
        alt_u32 dq = write_group*RW_MGR_MEM_DQ_PER_WRITE_DQS + dq_in_group;
1403
#endif
1404
 
1405
        ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
1406
        ALTERA_ASSERT(dq < RW_MGR_MEM_DATA_WIDTH);
1407
 
1408
        // Load the setting in the SCC manager
1409
        WRITE_SCC_DQ_IN_DELAY(dq_in_group, delay);
1410
 
1411
        // Make the setting in the TCL report
1412
        TCLRPT_SET(debug_cal_report->cal_dq_settings[curr_shadow_reg][dq].dq_in_delay, delay);
1413
 
1414
}
1415
 
1416
static inline void scc_mgr_set_dq_bypass(alt_u32 write_group, alt_u32 dq_in_group, alt_u32 bypass)
1417
{
1418
        // Load the setting in the SCC manager
1419
        WRITE_SCC_DQ_BYPASS(dq_in_group, bypass);
1420
}
1421
 
1422
static inline void scc_mgr_set_rfifo_mode(alt_u32 write_group, alt_u32 dq_in_group, alt_u32 mode)
1423
{
1424
        // Load the setting in the SCC manager
1425
        WRITE_SCC_RFIFO_MODE(dq_in_group, mode);
1426
}
1427
 
1428
static inline void scc_mgr_set_hhp_extras(void)
1429
{
1430
        // Load the fixed setting in the SCC manager
1431
        // bits: 0:0 = 1'b1   - dqs bypass
1432
        // bits: 1:1 = 1'b1   - dq bypass
1433
        // bits: 4:2 = 3'b001   - rfifo_mode
1434
        // bits: 6:5 = 2'b01  - rfifo clock_select
1435
        // bits: 7:7 = 1'b0  - separate gating from ungating setting
1436
        // bits: 8:8 = 1'b0  - separate OE from Output delay setting
1437
        alt_u32 value = (0<<8) | (0<<7) | (1<<5) | (1<<2) | (1<<1) | (1<<0);
1438
        WRITE_SCC_HHP_EXTRAS(value);
1439
}
1440
 
1441
static inline void scc_mgr_set_hhp_dqse_map(void)
1442
{
1443
        // Load the fixed setting in the SCC manager
1444
        WRITE_SCC_HHP_DQSE_MAP(0);
1445
}
1446
 
1447
static inline void scc_mgr_set_dqs_out1_delay(alt_u32 write_group, alt_u32 delay)
1448
{
1449
        ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
1450
 
1451
        // Load the setting in the SCC manager
1452
        WRITE_SCC_DQS_IO_OUT1_DELAY(delay);
1453
 
1454
        // Make the setting in the TCL report
1455
        TCLRPT_SET(debug_cal_report->cal_dqs_out_settings[curr_shadow_reg][write_group].dqs_out_delay1, delay);
1456
 
1457
}
1458
 
1459
static inline void scc_mgr_set_dqs_out2_delay(alt_u32 write_group, alt_u32 delay)
1460
{
1461
        ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
1462
 
1463
        // Load the setting in the SCC manager
1464
        WRITE_SCC_DQS_IO_OUT2_DELAY(delay);
1465
 
1466
        // Make the setting in the TCL report
1467
        TCLRPT_SET(debug_cal_report->cal_dqs_out_settings[curr_shadow_reg][write_group].dqs_out_delay2, delay);
1468
 
1469
}
1470
 
1471
inline void scc_mgr_set_dm_out1_delay(alt_u32 write_group, alt_u32 dm, alt_u32 delay)
1472
{
1473
        ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
1474
        ALTERA_ASSERT(dm < RW_MGR_NUM_DM_PER_WRITE_GROUP);
1475
 
1476
        // Load the setting in the SCC manager
1477
        WRITE_SCC_DM_IO_OUT1_DELAY(dm, delay);
1478
 
1479
        // Make the setting in the TCL report
1480
 
1481
        if (RW_MGR_NUM_TRUE_DM_PER_WRITE_GROUP > 0)
1482
        {
1483
                TCLRPT_SET(debug_cal_report->cal_dm_settings[curr_shadow_reg][write_group][dm].dm_out_delay1, delay);
1484
        }
1485
}
1486
 
1487
inline void scc_mgr_set_dm_out2_delay(alt_u32 write_group, alt_u32 dm, alt_u32 delay)
1488
{
1489
        ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
1490
        ALTERA_ASSERT(dm < RW_MGR_NUM_DM_PER_WRITE_GROUP);
1491
 
1492
        // Load the setting in the SCC manager
1493
        WRITE_SCC_DM_IO_OUT2_DELAY(dm, delay);
1494
 
1495
        // Make the setting in the TCL report
1496
 
1497
        if (RW_MGR_NUM_TRUE_DM_PER_WRITE_GROUP > 0)
1498
        {
1499
                TCLRPT_SET(debug_cal_report->cal_dm_settings[curr_shadow_reg][write_group][dm].dm_out_delay2, delay);
1500
        }
1501
}
1502
 
1503
static inline void scc_mgr_set_dm_in_delay(alt_u32 write_group, alt_u32 dm, alt_u32 delay)
1504
{
1505
        ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
1506
        ALTERA_ASSERT(dm < RW_MGR_NUM_DM_PER_WRITE_GROUP);
1507
 
1508
        // Load the setting in the SCC manager
1509
        WRITE_SCC_DM_IO_IN_DELAY(dm, delay);
1510
 
1511
        // Make the setting in the TCL report
1512
 
1513
        if (RW_MGR_NUM_TRUE_DM_PER_WRITE_GROUP > 0)
1514
        {
1515
                TCLRPT_SET(debug_cal_report->cal_dm_settings[curr_shadow_reg][write_group][dm].dm_in_delay, delay);
1516
        }
1517
}
1518
 
1519
static inline void scc_mgr_set_dm_bypass(alt_u32 write_group, alt_u32 dm, alt_u32 bypass)
1520
{
1521
        // Load the setting in the SCC manager
1522
        WRITE_SCC_DM_BYPASS(dm, bypass);
1523
}
1524
 
1525
//USER Zero all DQS config
1526
// TODO: maybe rename to scc_mgr_zero_dqs_config (or something)
1527
void scc_mgr_zero_all (void)
1528
{
1529
        alt_u32 i, r;
1530
 
1531
        //USER Zero all DQS config settings, across all groups and all shadow registers
1532
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r += NUM_RANKS_PER_SHADOW_REG) {
1533
 
1534
                // Strictly speaking this should be called once per group to make
1535
                // sure each group's delay chain is refreshed from the SCC register file,
1536
                // but since we're resetting all delay chains anyway, we can save some
1537
                // runtime by calling select_shadow_regs_for_update just once to switch
1538
                // rank.
1539
                select_shadow_regs_for_update(r, 0, 1);
1540
 
1541
                for (i = 0; i < RW_MGR_MEM_IF_READ_DQS_WIDTH; i++) {
1542
                        // The phases actually don't exist on a per-rank basis, but there's
1543
                        // no harm updating them several times, so let's keep the code simple.
1544
                        scc_mgr_set_dqs_bus_in_delay(i, IO_DQS_IN_RESERVE);
1545
                        scc_mgr_set_dqs_en_phase(i, 0);
1546
                        scc_mgr_set_dqs_en_delay(i, 0);
1547
                }
1548
 
1549
                for (i = 0; i < RW_MGR_MEM_IF_WRITE_DQS_WIDTH; i++) {
1550
                        scc_mgr_set_dqdqs_output_phase(i, 0);
1551
#if ARRIAV || CYCLONEV
1552
                        // av/cv don't have out2
1553
                        scc_mgr_set_oct_out1_delay(i, IO_DQS_OUT_RESERVE);
1554
#else
1555
                        scc_mgr_set_oct_out1_delay(i, 0);
1556
                        scc_mgr_set_oct_out2_delay(i, IO_DQS_OUT_RESERVE);
1557
#endif
1558
                }
1559
 
1560
                //USER multicast to all DQS group enables
1561
                IOWR_32DIRECT (SCC_MGR_DQS_ENA, 0, 0xff);
1562
 
1563
#if USE_SHADOW_REGS             
1564
                //USER in shadow-register mode, SCC_UPDATE is done on a per-group basis
1565
                //USER unless we explicitly ask for a multicast via the group counter
1566
                IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, 0xFF);
1567
#endif          
1568
                IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
1569
        }
1570
}
1571
 
1572
void scc_set_bypass_mode(alt_u32 write_group, alt_u32 mode)
1573
{
1574
        // mode = 0 : Do NOT bypass - Half Rate Mode
1575
        // mode = 1 : Bypass - Full Rate Mode
1576
 
1577
#if !HHP_HPS
1578
        alt_u32 i;
1579
#endif
1580
 
1581
#if HHP_HPS
1582
        // only need to set once for all groups, pins, dq, dqs, dm
1583
        if (write_group == 0) {
1584
                DPRINT(1, "Setting HHP Extras");
1585
                scc_mgr_set_hhp_extras();
1586
                DPRINT(1, "Done Setting HHP Extras");
1587
        }
1588
#endif
1589
 
1590
#if !HHP_HPS
1591
        for (i = 0; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++)
1592
        {
1593
                scc_mgr_set_dq_bypass(write_group, i, mode);
1594
                scc_mgr_set_rfifo_mode(write_group, i, mode);
1595
        }
1596
#endif
1597
 
1598
        //USER multicast to all DQ enables 
1599
        IOWR_32DIRECT (SCC_MGR_DQ_ENA, 0, 0xff);
1600
 
1601
#if !HHP_HPS
1602
        for (i = 0; i < RW_MGR_NUM_DM_PER_WRITE_GROUP; i++)
1603
        {
1604
                scc_mgr_set_dm_bypass(write_group, i, mode);
1605
        }
1606
#endif
1607
 
1608
        IOWR_32DIRECT (SCC_MGR_DM_ENA, 0, 0xff);
1609
 
1610
#if !HHP_HPS
1611
        scc_mgr_set_dqs_bypass(write_group, mode);
1612
#endif
1613
 
1614
        //USER update current DQS IO enable
1615
        IOWR_32DIRECT (SCC_MGR_DQS_IO_ENA, 0, 0);
1616
 
1617
        //USER update the DQS logic
1618
        IOWR_32DIRECT (SCC_MGR_DQS_ENA, 0, write_group);
1619
 
1620
        //USER hit update
1621
        IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
1622
}
1623
 
1624
// Moving up to avoid warnings
1625
void scc_mgr_load_dqs_for_write_group (alt_u32 write_group)
1626
{
1627
        alt_u32 read_group;
1628
 
1629
        // Although OCT affects only write data, the OCT delay is controlled by the DQS logic block
1630
        // which is instantiated once per read group. For protocols where a write group consists
1631
        // of multiple read groups, the setting must be scanned multiple times.
1632
        for (read_group = write_group * RW_MGR_MEM_IF_READ_DQS_WIDTH / RW_MGR_MEM_IF_WRITE_DQS_WIDTH;
1633
                 read_group < (write_group + 1) * RW_MGR_MEM_IF_READ_DQS_WIDTH / RW_MGR_MEM_IF_WRITE_DQS_WIDTH;
1634
                 ++read_group) {
1635
 
1636
                IOWR_32DIRECT (SCC_MGR_DQS_ENA, 0, read_group);
1637
        }
1638
}
1639
 
1640
void scc_mgr_zero_group (alt_u32 write_group, alt_u32 test_begin, alt_32 out_only)
1641
{
1642
        alt_u32 i, r;
1643
 
1644
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r += NUM_RANKS_PER_SHADOW_REG) {
1645
 
1646
                select_shadow_regs_for_update(r, write_group, 1);
1647
 
1648
                //USER Zero all DQ config settings
1649
                for (i = 0; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++)
1650
                {
1651
                        scc_mgr_set_dq_out1_delay(write_group, i, 0);
1652
                        scc_mgr_set_dq_out2_delay(write_group, i, IO_DQ_OUT_RESERVE);
1653
                        if (!out_only) {
1654
                                scc_mgr_set_dq_in_delay(write_group, i, 0);
1655
                        }
1656
                }
1657
 
1658
                //USER multicast to all DQ enables
1659
                IOWR_32DIRECT (SCC_MGR_DQ_ENA, 0, 0xff);
1660
 
1661
                //USER Zero all DM config settings 
1662
                for (i = 0; i < RW_MGR_NUM_DM_PER_WRITE_GROUP; i++)
1663
                {
1664
                        if (!out_only) {
1665
                                // Do we really need this?
1666
                                scc_mgr_set_dm_in_delay(write_group, i, 0);
1667
                        }
1668
                        scc_mgr_set_dm_out1_delay(write_group, i, 0);
1669
                        scc_mgr_set_dm_out2_delay(write_group, i, IO_DM_OUT_RESERVE);
1670
                }
1671
 
1672
                //USER multicast to all DM enables
1673
                IOWR_32DIRECT (SCC_MGR_DM_ENA, 0, 0xff);
1674
 
1675
                //USER zero all DQS io settings 
1676
                if (!out_only) {
1677
                        scc_mgr_set_dqs_io_in_delay(write_group, 0);
1678
                }
1679
#if ARRIAV || CYCLONEV
1680
                // av/cv don't have out2
1681
                scc_mgr_set_dqs_out1_delay(write_group, IO_DQS_OUT_RESERVE);
1682
                scc_mgr_set_oct_out1_delay(write_group, IO_DQS_OUT_RESERVE);
1683
                scc_mgr_load_dqs_for_write_group (write_group);
1684
#else
1685
                scc_mgr_set_dqs_out1_delay(write_group, 0);
1686
                scc_mgr_set_dqs_out2_delay(write_group, IO_DQS_OUT_RESERVE);
1687
                scc_mgr_set_oct_out1_delay(write_group, 0);
1688
                scc_mgr_set_oct_out2_delay(write_group, IO_DQS_OUT_RESERVE);
1689
                scc_mgr_load_dqs_for_write_group (write_group);
1690
#endif
1691
 
1692
                //USER multicast to all DQS IO enables (only 1)
1693
                IOWR_32DIRECT (SCC_MGR_DQS_IO_ENA, 0, 0);
1694
 
1695
#if USE_SHADOW_REGS             
1696
                //USER in shadow-register mode, SCC_UPDATE is done on a per-group basis
1697
                //USER unless we explicitly ask for a multicast via the group counter
1698
                IOWR_32DIRECT (SCC_MGR_GROUP_COUNTER, 0, 0xFF);
1699
#endif                          
1700
                //USER hit update to zero everything 
1701
                IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
1702
        }
1703
}
1704
 
1705
//USER load up dqs config settings 
1706
 
1707
void scc_mgr_load_dqs (alt_u32 dqs)
1708
{
1709
        IOWR_32DIRECT (SCC_MGR_DQS_ENA, 0, dqs);
1710
}
1711
 
1712
 
1713
//USER load up dqs io config settings 
1714
 
1715
void scc_mgr_load_dqs_io (void)
1716
{
1717
        IOWR_32DIRECT (SCC_MGR_DQS_IO_ENA, 0, 0);
1718
}
1719
 
1720
//USER load up dq config settings 
1721
 
1722
void scc_mgr_load_dq (alt_u32 dq_in_group)
1723
{
1724
        IOWR_32DIRECT (SCC_MGR_DQ_ENA, 0, dq_in_group);
1725
}
1726
 
1727
//USER load up dm config settings 
1728
 
1729
void scc_mgr_load_dm (alt_u32 dm)
1730
{
1731
        IOWR_32DIRECT (SCC_MGR_DM_ENA, 0, dm);
1732
}
1733
 
1734
//USER apply and load a particular input delay for the DQ pins in a group
1735
//USER group_bgn is the index of the first dq pin (in the write group)
1736
 
1737
void scc_mgr_apply_group_dq_in_delay (alt_u32 write_group, alt_u32 group_bgn, alt_u32 delay)
1738
{
1739
        alt_u32 i, p;
1740
 
1741
        for (i = 0, p = group_bgn; i < RW_MGR_MEM_DQ_PER_READ_DQS; i++, p++) {
1742
                scc_mgr_set_dq_in_delay(write_group, p, delay);
1743
                scc_mgr_load_dq (p);
1744
        }
1745
}
1746
 
1747
//USER apply and load a particular output delay for the DQ pins in a group
1748
 
1749
void scc_mgr_apply_group_dq_out1_delay (alt_u32 write_group, alt_u32 group_bgn, alt_u32 delay1)
1750
{
1751
        alt_u32 i, p;
1752
 
1753
        for (i = 0, p = group_bgn; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++, p++) {
1754
                scc_mgr_set_dq_out1_delay(write_group, i, delay1);
1755
                scc_mgr_load_dq (i);
1756
        }
1757
}
1758
 
1759
void scc_mgr_apply_group_dq_out2_delay (alt_u32 write_group, alt_u32 group_bgn, alt_u32 delay2)
1760
{
1761
        alt_u32 i, p;
1762
 
1763
        for (i = 0, p = group_bgn; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++, p++) {
1764
                scc_mgr_set_dq_out2_delay(write_group, i, delay2);
1765
                scc_mgr_load_dq (i);
1766
        }
1767
}
1768
 
1769
//USER apply and load a particular output delay for the DM pins in a group
1770
 
1771
void scc_mgr_apply_group_dm_out1_delay (alt_u32 write_group, alt_u32 delay1)
1772
{
1773
        alt_u32 i;
1774
 
1775
        for (i = 0; i < RW_MGR_NUM_DM_PER_WRITE_GROUP; i++) {
1776
                scc_mgr_set_dm_out1_delay(write_group, i, delay1);
1777
                scc_mgr_load_dm (i);
1778
        }
1779
}
1780
 
1781
 
1782
//USER apply and load delay on both DQS and OCT out1
1783
void scc_mgr_apply_group_dqs_io_and_oct_out1 (alt_u32 write_group, alt_u32 delay)
1784
{
1785
        scc_mgr_set_dqs_out1_delay(write_group, delay);
1786
        scc_mgr_load_dqs_io ();
1787
 
1788
        scc_mgr_set_oct_out1_delay(write_group, delay);
1789
        scc_mgr_load_dqs_for_write_group (write_group);
1790
}
1791
 
1792
//USER apply and load delay on both DQS and OCT out2
1793
void scc_mgr_apply_group_dqs_io_and_oct_out2 (alt_u32 write_group, alt_u32 delay)
1794
{
1795
        scc_mgr_set_dqs_out2_delay(write_group, delay);
1796
        scc_mgr_load_dqs_io ();
1797
 
1798
        scc_mgr_set_oct_out2_delay(write_group, delay);
1799
        scc_mgr_load_dqs_for_write_group (write_group);
1800
}
1801
 
1802
//USER set delay on both DQS and OCT out1 by incrementally changing
1803
//USER the settings one dtap at a time towards the target value, to avoid
1804
//USER breaking the lock of the DLL/PLL on the memory device.
1805
void scc_mgr_set_group_dqs_io_and_oct_out1_gradual (alt_u32 write_group, alt_u32 delay)
1806
{
1807
        alt_u32 d = READ_SCC_DQS_IO_OUT1_DELAY();
1808
 
1809
        while (d > delay) {
1810
                --d;
1811
                scc_mgr_apply_group_dqs_io_and_oct_out1 (write_group, d);
1812
                IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
1813
                if (QDRII)
1814
                {
1815
                        rw_mgr_mem_dll_lock_wait();
1816
                }
1817
        }
1818
        while (d < delay) {
1819
                ++d;
1820
                scc_mgr_apply_group_dqs_io_and_oct_out1 (write_group, d);
1821
                IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
1822
                if (QDRII)
1823
                {
1824
                        rw_mgr_mem_dll_lock_wait();
1825
                }
1826
        }
1827
}
1828
 
1829
//USER set delay on both DQS and OCT out2 by incrementally changing
1830
//USER the settings one dtap at a time towards the target value, to avoid
1831
//USER breaking the lock of the DLL/PLL on the memory device.
1832
void scc_mgr_set_group_dqs_io_and_oct_out2_gradual (alt_u32 write_group, alt_u32 delay)
1833
{
1834
        alt_u32 d = READ_SCC_DQS_IO_OUT2_DELAY();
1835
 
1836
        while (d > delay) {
1837
                --d;
1838
                scc_mgr_apply_group_dqs_io_and_oct_out2 (write_group, d);
1839
                IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
1840
                if (QDRII)
1841
                {
1842
                        rw_mgr_mem_dll_lock_wait();
1843
                }
1844
        }
1845
        while (d < delay) {
1846
                ++d;
1847
                scc_mgr_apply_group_dqs_io_and_oct_out2 (write_group, d);
1848
                IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
1849
                if (QDRII)
1850
                {
1851
                        rw_mgr_mem_dll_lock_wait();
1852
                }
1853
        }
1854
}
1855
 
1856
//USER apply a delay to the entire output side: DQ, DM, DQS, OCT 
1857
 
1858
void scc_mgr_apply_group_all_out_delay (alt_u32 write_group, alt_u32 group_bgn, alt_u32 delay)
1859
{
1860
        //USER dq shift 
1861
 
1862
        scc_mgr_apply_group_dq_out1_delay (write_group, group_bgn, delay);
1863
 
1864
        //USER dm shift 
1865
 
1866
        scc_mgr_apply_group_dm_out1_delay (write_group, delay);
1867
 
1868
        //USER dqs and oct shift 
1869
 
1870
        scc_mgr_apply_group_dqs_io_and_oct_out1 (write_group, delay);
1871
}
1872
 
1873
//USER apply a delay to the entire output side (DQ, DM, DQS, OCT) and to all ranks
1874
void scc_mgr_apply_group_all_out_delay_all_ranks (alt_u32 write_group, alt_u32 group_bgn, alt_u32 delay)
1875
{
1876
        alt_u32 r;
1877
 
1878
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r += NUM_RANKS_PER_SHADOW_REG) {
1879
 
1880
                select_shadow_regs_for_update(r, write_group, 1);
1881
 
1882
                scc_mgr_apply_group_all_out_delay (write_group, group_bgn, delay);
1883
 
1884
                IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
1885
        }
1886
}
1887
 
1888
//USER apply a delay to the entire output side: DQ, DM, DQS, OCT 
1889
 
1890
void scc_mgr_apply_group_all_out_delay_add (alt_u32 write_group, alt_u32 group_bgn, alt_u32 delay)
1891
{
1892
        alt_u32 i, p, new_delay;
1893
 
1894
        //USER dq shift 
1895
 
1896
        for (i = 0, p = group_bgn; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++, p++) {
1897
 
1898
                new_delay = READ_SCC_DQ_OUT2_DELAY(i);
1899
                new_delay += delay;
1900
 
1901
                if (new_delay > IO_IO_OUT2_DELAY_MAX) {
1902
                        DPRINT(1, "%s(%lu, %lu, %lu) DQ[%lu,%lu]: %lu > %lu => %lu",
1903
                               __func__, write_group, group_bgn, delay, i, p,
1904
                               new_delay, (long unsigned int)IO_IO_OUT2_DELAY_MAX, (long unsigned int)IO_IO_OUT2_DELAY_MAX);
1905
                        new_delay = IO_IO_OUT2_DELAY_MAX;
1906
                }
1907
 
1908
                scc_mgr_set_dq_out2_delay(write_group, i, new_delay);
1909
                scc_mgr_load_dq (i);
1910
        }
1911
 
1912
        //USER dm shift 
1913
 
1914
        for (i = 0; i < RW_MGR_NUM_DM_PER_WRITE_GROUP; i++) {
1915
                new_delay = READ_SCC_DM_IO_OUT2_DELAY(i);
1916
                new_delay += delay;
1917
 
1918
                if (new_delay > IO_IO_OUT2_DELAY_MAX) {
1919
                        DPRINT(1, "%s(%lu, %lu, %lu) DM[%lu]: %lu > %lu => %lu",
1920
                               __func__, write_group, group_bgn, delay, i,
1921
                               new_delay, (long unsigned int)IO_IO_OUT2_DELAY_MAX, (long unsigned int)IO_IO_OUT2_DELAY_MAX);
1922
                        new_delay = IO_IO_OUT2_DELAY_MAX;
1923
                }
1924
 
1925
                scc_mgr_set_dm_out2_delay(write_group, i, new_delay);
1926
                scc_mgr_load_dm (i);
1927
        }
1928
 
1929
        //USER dqs shift 
1930
 
1931
        new_delay = READ_SCC_DQS_IO_OUT2_DELAY();
1932
        new_delay += delay;
1933
 
1934
        if (new_delay > IO_IO_OUT2_DELAY_MAX) {
1935
                DPRINT(1, "%s(%lu, %lu, %lu) DQS: %lu > %d => %d; adding %lu to OUT1",
1936
                       __func__, write_group, group_bgn, delay,
1937
                       new_delay, IO_IO_OUT2_DELAY_MAX, IO_IO_OUT2_DELAY_MAX,
1938
                        new_delay - IO_IO_OUT2_DELAY_MAX);
1939
                scc_mgr_set_dqs_out1_delay(write_group, new_delay - IO_IO_OUT2_DELAY_MAX);
1940
                new_delay = IO_IO_OUT2_DELAY_MAX;
1941
        }
1942
 
1943
        scc_mgr_set_dqs_out2_delay(write_group, new_delay);
1944
        scc_mgr_load_dqs_io ();
1945
 
1946
        //USER oct shift 
1947
 
1948
        new_delay = READ_SCC_OCT_OUT2_DELAY(write_group);
1949
        new_delay += delay;
1950
 
1951
        if (new_delay > IO_IO_OUT2_DELAY_MAX) {
1952
                DPRINT(1, "%s(%lu, %lu, %lu) DQS: %lu > %d => %d; adding %lu to OUT1",
1953
                       __func__, write_group, group_bgn, delay,
1954
                       new_delay, IO_IO_OUT2_DELAY_MAX, IO_IO_OUT2_DELAY_MAX,
1955
                        new_delay - IO_IO_OUT2_DELAY_MAX);
1956
                scc_mgr_set_oct_out1_delay(write_group, new_delay - IO_IO_OUT2_DELAY_MAX);
1957
                new_delay = IO_IO_OUT2_DELAY_MAX;
1958
        }
1959
 
1960
        scc_mgr_set_oct_out2_delay(write_group, new_delay);
1961
        scc_mgr_load_dqs_for_write_group (write_group);
1962
}
1963
 
1964
//USER apply a delay to the entire output side (DQ, DM, DQS, OCT) and to all ranks
1965
void scc_mgr_apply_group_all_out_delay_add_all_ranks (alt_u32 write_group, alt_u32 group_bgn, alt_u32 delay)
1966
{
1967
        alt_u32 r;
1968
 
1969
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r += NUM_RANKS_PER_SHADOW_REG) {
1970
 
1971
                select_shadow_regs_for_update(r, write_group, 1);
1972
 
1973
                scc_mgr_apply_group_all_out_delay_add (write_group, group_bgn, delay);
1974
 
1975
                IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
1976
        }
1977
}
1978
 
1979
static inline void scc_mgr_spread_out2_delay_all_ranks (alt_u32 write_group, alt_u32 test_bgn)
1980
{
1981
#if STRATIXV || ARRIAVGZ
1982
        alt_u32 found;
1983
        alt_u32 i;
1984
        alt_u32 p;
1985
        alt_u32 d;
1986
        alt_u32 r;
1987
 
1988
        const alt_u32 delay_step = IO_IO_OUT2_DELAY_MAX/(RW_MGR_MEM_DQ_PER_WRITE_DQS-1); /* we start at zero, so have one less dq to devide among */
1989
 
1990
        TRACE_FUNC("(%lu,%lu)", write_group, test_bgn);
1991
 
1992
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r += NUM_RANKS_PER_SHADOW_REG) {
1993
                select_shadow_regs_for_update(r, write_group, 1);
1994
                for (i = 0, p = test_bgn, d = 0; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++, p++, d += delay_step) {
1995
                        DPRINT(1, "rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase_sweep_dq_in_delay: g=%lu r=%lu, i=%lu p=%lu d=%lu",
1996
                               write_group, r, i, p, d);
1997
                        scc_mgr_set_dq_out2_delay(write_group, i, d);
1998
                        scc_mgr_load_dq (i);
1999
                }
2000
                IOWR_32DIRECT (SCC_MGR_UPD, 0, 0);
2001
        }
2002
#endif
2003
}
2004
 
2005
#if DDR3
2006
// optimization used to recover some slots in ddr3 inst_rom
2007
// could be applied to other protocols if we wanted to
2008
void set_jump_as_return(void)
2009
{
2010
        // to save space, we replace return with jump to special shared RETURN instruction
2011
        // so we set the counter to large value so that we always jump
2012
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_0, 0, 0xFF);
2013
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_0, 0, __RW_MGR_RETURN);
2014
 
2015
}
2016
#endif
2017
 
2018
// should always use constants as argument to ensure all computations are performed at compile time
2019
static inline void delay_for_n_mem_clocks(const alt_u32 clocks)
2020
{
2021
        alt_u32 afi_clocks;
2022
        alt_u8 inner;
2023
        alt_u8 outer;
2024
        alt_u16 c_loop;
2025
 
2026
        TRACE_FUNC("clocks=%lu ... start", clocks);
2027
 
2028
        afi_clocks = (clocks + AFI_RATE_RATIO-1) / AFI_RATE_RATIO; /* scale (rounding up) to get afi clocks */
2029
 
2030
        // Note, we don't bother accounting for being off a little bit because of a few extra instructions in outer loops
2031
        // Note, the loops have a test at the end, and do the test before the decrement, and so always perform the loop
2032
        // 1 time more than the counter value
2033
        if (afi_clocks == 0) {
2034
                inner = outer = c_loop = 0;
2035
        } else if (afi_clocks <= 0x100) {
2036
                inner = afi_clocks-1;
2037
                outer = 0;
2038
                c_loop = 0;
2039
        } else if (afi_clocks <= 0x10000) {
2040
                inner = 0xff;
2041
                outer = (afi_clocks-1) >> 8;
2042
                c_loop = 0;
2043
        } else {
2044
                inner = 0xff;
2045
                outer = 0xff;
2046
                c_loop = (afi_clocks-1) >> 16;
2047
        }
2048
 
2049
        // rom instructions are structured as follows:
2050
        //
2051
        //    IDLE_LOOP2: jnz cntr0, TARGET_A
2052
        //    IDLE_LOOP1: jnz cntr1, TARGET_B
2053
        //                return
2054
        //
2055
        // so, when doing nested loops, TARGET_A is set to IDLE_LOOP2, and TARGET_B is
2056
        // set to IDLE_LOOP2 as well
2057
        //
2058
        // if we have no outer loop, though, then we can use IDLE_LOOP1 only, and set
2059
        // TARGET_B to IDLE_LOOP1 and we skip IDLE_LOOP2 entirely
2060
        //
2061
        // a little confusing, but it helps save precious space in the inst_rom and sequencer rom
2062
        // and keeps the delays more accurate and reduces overhead
2063
        if (afi_clocks <= 0x100) {
2064
 
2065
                IOWR_32DIRECT (RW_MGR_LOAD_CNTR_1, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(inner));
2066
                IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_1, 0, __RW_MGR_IDLE_LOOP1);
2067
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_IDLE_LOOP1);
2068
 
2069
        } else {
2070
                IOWR_32DIRECT (RW_MGR_LOAD_CNTR_0, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(inner));
2071
                IOWR_32DIRECT (RW_MGR_LOAD_CNTR_1, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(outer));
2072
 
2073
                IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_0, 0, __RW_MGR_IDLE_LOOP2);
2074
                IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_1, 0, __RW_MGR_IDLE_LOOP2);
2075
 
2076
                // hack to get around compiler not being smart enough
2077
                if (afi_clocks <= 0x10000) {
2078
                        // only need to run once
2079
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_IDLE_LOOP2);
2080
                } else {
2081
                        do {
2082
                                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_IDLE_LOOP2);
2083
                        } while (c_loop-- != 0);
2084
                }
2085
        }
2086
 
2087
        TRACE_FUNC("clocks=%lu ... end", clocks);
2088
}
2089
 
2090
// should always use constants as argument to ensure all computations are performed at compile time
2091
static inline void delay_for_n_ns(const alt_u32 nanoseconds)
2092
{
2093
        TRACE_FUNC("nanoseconds=%lu ... end", nanoseconds);
2094
        delay_for_n_mem_clocks((1000*nanoseconds) / (1000000/AFI_CLK_FREQ) * AFI_RATE_RATIO);
2095
}
2096
 
2097
#if RLDRAM3
2098
// Special routine to recover memory device from illegal state after
2099
// ck/dk relationship is potentially violated.
2100
static inline void recover_mem_device_after_ck_dqs_violation(void)
2101
{
2102
        //USER Issue MRS0 command. For some reason this is required once we
2103
        //USER violate tCKDK. Without this all subsequent write tests will fail
2104
        //USER even with known good delays.
2105
 
2106
   //USER Load MR0
2107
        if ( RW_MGR_MEM_NUMBER_OF_RANKS == 1 ) {
2108
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xFE);
2109
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0);
2110
        } else if ( RW_MGR_MEM_NUMBER_OF_RANKS == 2 ) {
2111
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xFC);
2112
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0);
2113
        } else if ( RW_MGR_MEM_NUMBER_OF_RANKS == 4 ) {
2114
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xFC);
2115
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0);
2116
                //USER Wait MRSC
2117
                delay_for_n_mem_clocks(12);
2118
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xF3);
2119
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0_QUAD_RANK);
2120
        }
2121
        else {
2122
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xFE);
2123
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0);
2124
        }
2125
 
2126
        //USER Wait MRSC
2127
        delay_for_n_mem_clocks(12);
2128
}
2129
#else
2130
// Special routine to recover memory device from illegal state after
2131
// ck/dqs relationship is violated.
2132
static inline void recover_mem_device_after_ck_dqs_violation(void)
2133
{
2134
        // Current protocol doesn't require any special recovery
2135
}
2136
#endif
2137
 
2138
#if (LRDIMM && DDR3)
2139
// Routine to program specific LRDIMM control words.
2140
static void rw_mgr_lrdimm_rc_program(alt_u32 fscw, alt_u32 rc_addr, alt_u32 rc_val)
2141
{
2142
        alt_u32 i;
2143
        const alt_u32 AC_BASE_CONTENT = __RW_MGR_CONTENT_ac_rdimm;
2144
        //USER These values should be dynamically loaded instead of hard-coded
2145
        const alt_u32 AC_ADDRESS_POSITION = 0x0;
2146
        const alt_u32 AC_BANK_ADDRESS_POSITION = 0xD;
2147
        alt_u32 ac_content;
2148
        alt_u32 lrdimm_cs_msk = RW_MGR_RANK_NONE;
2149
 
2150
        TRACE_FUNC();
2151
 
2152
        //USER Turn on only CS0 and CS1 for each DIMM.
2153
        for (i = 0; i < RW_MGR_MEM_CHIP_SELECT_WIDTH; i+= RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM)
2154
        {
2155
                lrdimm_cs_msk &= (~(3 << i));
2156
        }
2157
 
2158
        IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, lrdimm_cs_msk);
2159
 
2160
        // Program the fscw first (RC7), followed by the actual value
2161
        for (i = 0; i < 2; i++)
2162
        {
2163
                alt_u32 addr;
2164
                alt_u32 val;
2165
 
2166
                addr = (i == 0) ? 7 : rc_addr;
2167
                val = (i == 0) ? fscw : rc_val;
2168
 
2169
                ac_content =
2170
                        AC_BASE_CONTENT |
2171
                        //USER Word address
2172
                        ((addr & 0x7) << AC_ADDRESS_POSITION) |
2173
                        (((addr >> 3) & 0x1) << (AC_BANK_ADDRESS_POSITION + 2)) |
2174
                        //USER Configuration Word
2175
                        (((val >> 2) & 0x3) << (AC_BANK_ADDRESS_POSITION)) |
2176
                        ((val & 0x3) << (AC_ADDRESS_POSITION + 3));
2177
 
2178
                //USER Override the AC row with the RDIMM command
2179
                IOWR_32DIRECT(BASE_RW_MGR, 0x1C00 + (__RW_MGR_ac_rdimm << 2), ac_content);
2180
 
2181
                set_jump_as_return();
2182
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_RDIMM_CMD);
2183
        }
2184
 
2185
        // USER The following registers require a delay of tSTAB (6us) for proper functionality.
2186
        // USER F0RC2, F0RC10, F0RC11, F1RC8, F1RC11-F1RC15
2187
        // USER Note that it is only necessary to wait tSTAB after all of these
2188
        // USER control words have been written, not after each one. Only F0RC0-F0RC15
2189
        // USER are guaranteed to be written (and in order), but F1* are not so
2190
        // USER wait after each.
2191
        if (    ((fscw == 0) && ((rc_addr==2) || (rc_addr==10) || (rc_addr==11)))
2192
                  || ((fscw == 1) && (rc_addr >= 8)))
2193
        {
2194
                delay_for_n_ns(6000);
2195
        }
2196
}
2197
#endif
2198
#if (RDIMM || LRDIMM) && DDR3
2199
void rw_mgr_rdimm_initialize(void)
2200
{
2201
        alt_u32 i;
2202
        alt_u32 conf_word;
2203
#if RDIMM
2204
        const alt_u32 AC_BASE_CONTENT = __RW_MGR_CONTENT_ac_rdimm;
2205
        //USER These values should be dynamically loaded instead of hard-coded
2206
        const alt_u32 AC_ADDRESS_POSITION = 0x0;
2207
        const alt_u32 AC_BANK_ADDRESS_POSITION = 0xD;
2208
        alt_u32 ac_content;
2209
#endif
2210
 
2211
        TRACE_FUNC();
2212
 
2213
        //USER RDIMM registers are programmed by writing 16 configuration words
2214
        //USER 1. An RDIMM command is a NOP with all CS asserted
2215
        //USER 2. The 4-bit address of the configuration words is 
2216
        //USER    * { mem_ba[2] , mem_a[2] , mem_a[1] , mem_a[0] }
2217
        //USER 3. The 4-bit configuration word is
2218
        //USER    * { mem_ba[1] , mem_ba[0] , mem_a[4] , mem_a[3] }
2219
 
2220
#if RDIMM
2221
        //USER Turn on all ranks
2222
        IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, RW_MGR_RANK_ALL);
2223
#endif
2224
 
2225
        for(i = 0; i < 16; i++)
2226
        {
2227
 
2228
 
2229
                if(i < 8)
2230
                {
2231
#if ENABLE_TCL_DEBUG && USE_USER_RDIMM_VALUE
2232
                        conf_word = (my_debug_data.command_parameters[0] >> (i * 4)) & 0xF;
2233
#else                   
2234
                        conf_word = (RDIMM_CONFIG_WORD_LOW >> (i * 4)) & 0xF;
2235
#endif                  
2236
                }
2237
                else
2238
                {
2239
#if ENABLE_TCL_DEBUG && USE_USER_RDIMM_VALUE    
2240
                        conf_word = (my_debug_data.command_parameters[1] >> ((i - 8) * 4)) & 0xF;
2241
#else                   
2242
                        conf_word = (RDIMM_CONFIG_WORD_HIGH >> ((i - 8) * 4)) & 0xF;
2243
#endif          
2244
                }
2245
 
2246
#if RDIMM
2247
                ac_content =
2248
                        AC_BASE_CONTENT |
2249
                        //USER Word address
2250
                        ((i & 0x7) << AC_ADDRESS_POSITION) |
2251
                        (((i >> 3) & 0x1) << (AC_BANK_ADDRESS_POSITION + 2)) |
2252
                        //USER Configuration Word
2253
                        (((conf_word >> 2) & 0x3) << (AC_BANK_ADDRESS_POSITION)) |
2254
                        ((conf_word & 0x3) << (AC_ADDRESS_POSITION + 3));
2255
 
2256
                //USER Override the AC row with the RDIMM command
2257
                IOWR_32DIRECT(BASE_RW_MGR, 0x1C00 + (__RW_MGR_ac_rdimm << 2), ac_content);
2258
 
2259
                set_jump_as_return();
2260
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_RDIMM_CMD);
2261
                //USER When sending the RC2 or RC10 word, tSTAB time must elapse before the next command
2262
                //USER is sent out. tSTAB is currently hard-coded to 6us.
2263
                if((i == 2) || (i == 10))
2264
                {
2265
                        //USER tSTAB = 6 us
2266
                        delay_for_n_ns(6000);
2267
                }
2268
 
2269
#endif
2270
#if LRDIMM
2271
                // USER Program configuration word with FSCW set to zero.
2272
                rw_mgr_lrdimm_rc_program(0, i, conf_word);
2273
#endif
2274
        }
2275
}
2276
#else
2277
void rw_mgr_rdimm_initialize(void) { }
2278
#endif
2279
 
2280
#if DDR3
2281
 
2282
#if (ADVANCED_ODT_CONTROL || LRDIMM)
2283
alt_u32 ddr3_mirror_mrs_cmd(alt_u32 bit_vector) {
2284
        // This function performs address mirroring of an AC ROM command, which
2285
        // requires swapping the following DDR3 bits:
2286
        //     A[3] <=> A[4]
2287
        //     A[5] <=> A[6]
2288
        //     A[7] <=> A[8]
2289
        //    BA[0] <=>BA[1]
2290
        // We assume AC_ROM_ENTRY = {BA[2:0], A[15:0]}.
2291
        alt_u32 unchanged_bits;
2292
        alt_u32 mask_a;
2293
        alt_u32 mask_b;
2294
        alt_u32 retval;
2295
 
2296
        unchanged_bits = (~(DDR3_AC_MIRR_MASK | (DDR3_AC_MIRR_MASK << 1))) & bit_vector;
2297
        mask_a = DDR3_AC_MIRR_MASK & bit_vector;
2298
        mask_b = (DDR3_AC_MIRR_MASK << 1) & bit_vector;
2299
 
2300
        retval = unchanged_bits | (mask_a << 1) | (mask_b >> 1);
2301
 
2302
        return retval;
2303
}
2304
 
2305
void rtt_change_MRS1_MRS2_NOM_WR (alt_u32 prev_ac_mr , alt_u32 odt_ac_mr, alt_u32 mirr_on, alt_u32 mr_cmd ) {
2306
        // This function updates the ODT-specific Mode Register bits (MRS1 or MRS2) in the AC ROM.
2307
        // Parameters:  prev_ac_mr - Original, *un-mirrored* AC ROM Entry
2308
        //              odt_ac_mr  - ODT bits to update (un-mirrored)
2309
        //              mirr_on    - boolean flag indicating if the regular or mirrored entry is updated
2310
        //              mr_cmd     - Mode register command (only MR1 and MR2 are supported for DDR3)
2311
        alt_u32 new_ac_mr;
2312
        alt_u32 ac_rom_entry = 0;
2313
        alt_u32 ac_rom_mask;
2314
 
2315
        switch (mr_cmd) {
2316
                case 1: {
2317
                        // USER MRS1 = RTT_NOM, RTT_DRV
2318
                        ac_rom_mask = DDR3_MR1_ODT_MASK;
2319
                        ac_rom_entry = mirr_on ? (0x1C00 | (__RW_MGR_ac_mrs1_mirr << 2))
2320
                                               : (0x1C00 | (__RW_MGR_ac_mrs1 << 2));
2321
                } break;
2322
                case 2: {
2323
                        // USER MRS2 = RTT_WR
2324
                        ac_rom_mask = DDR3_MR2_ODT_MASK;
2325
                        ac_rom_entry = mirr_on ? (0x1C00 | (__RW_MGR_ac_mrs2_mirr << 2))
2326
                                               : (0x1C00 | (__RW_MGR_ac_mrs2 << 2));
2327
                } break;
2328
        }
2329
 
2330
        // USER calculate new AC values and update ROM
2331
        new_ac_mr  = odt_ac_mr;
2332
        new_ac_mr |= (prev_ac_mr & ac_rom_mask);
2333
        if (mirr_on) {
2334
                new_ac_mr = ddr3_mirror_mrs_cmd(new_ac_mr);
2335
        }
2336
        IOWR_32DIRECT(BASE_RW_MGR, ac_rom_entry, new_ac_mr);
2337
}
2338
#endif //(ADVANCED_ODT_CONTROL || LRDIMM)
2339
 
2340
void rw_mgr_mem_initialize (void)
2341
{
2342
        alt_u32 r;
2343
 
2344
#if LRDIMM
2345
        alt_u32 rtt_nom;
2346
        alt_u32 rtt_drv;
2347
        alt_u32 rtt_wr;
2348
#endif // LRDIMM
2349
 
2350
        TRACE_FUNC();
2351
 
2352
        //USER The reset / cke part of initialization is broadcasted to all ranks
2353
        IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, RW_MGR_RANK_ALL);
2354
 
2355
        // Here's how you load register for a loop
2356
        //USER Counters are located @ 0x800
2357
        //USER Jump address are located @ 0xC00
2358
        //USER For both, registers 0 to 3 are selected using bits 3 and 2, like in
2359
        //USER 0x800, 0x804, 0x808, 0x80C and 0xC00, 0xC04, 0xC08, 0xC0C
2360
        // I know this ain't pretty, but Avalon bus throws away the 2 least significant bits
2361
 
2362
        //USER start with memory RESET activated
2363
 
2364
        //USER tINIT is typically 200us (but can be adjusted in the GUI)
2365
        //USER The total number of cycles required for this nested counter structure to
2366
        //USER complete is defined by:
2367
        //USER        num_cycles = (CTR2 + 1) * [(CTR1 + 1) * (2 * (CTR0 + 1) + 1) + 1] + 1
2368
 
2369
        //USER Load counters
2370
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_0, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(SEQ_TINIT_CNTR0_VAL));
2371
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_1, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(SEQ_TINIT_CNTR1_VAL));
2372
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_2, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(SEQ_TINIT_CNTR2_VAL));
2373
 
2374
        //USER Load jump address
2375
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_0, 0, __RW_MGR_INIT_RESET_0_CKE_0);
2376
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_1, 0, __RW_MGR_INIT_RESET_0_CKE_0);
2377
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_2, 0, __RW_MGR_INIT_RESET_0_CKE_0);
2378
 
2379
        //USER Execute count instruction
2380
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_INIT_RESET_0_CKE_0);
2381
 
2382
        //USER indicate that memory is stable
2383
        IOWR_32DIRECT (PHY_MGR_RESET_MEM_STBL, 0, 1);
2384
 
2385
        //USER transition the RESET to high 
2386
        //USER Wait for 500us
2387
        //USER        num_cycles = (CTR2 + 1) * [(CTR1 + 1) * (2 * (CTR0 + 1) + 1) + 1] + 1
2388
        //USER Load counters
2389
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_0, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(SEQ_TRESET_CNTR0_VAL));
2390
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_1, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(SEQ_TRESET_CNTR1_VAL));
2391
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_2, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(SEQ_TRESET_CNTR2_VAL));
2392
 
2393
        //USER Load jump address
2394
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_0, 0, __RW_MGR_INIT_RESET_1_CKE_0);
2395
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_1, 0, __RW_MGR_INIT_RESET_1_CKE_0);
2396
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_2, 0, __RW_MGR_INIT_RESET_1_CKE_0);
2397
 
2398
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_INIT_RESET_1_CKE_0);
2399
 
2400
        //USER bring up clock enable 
2401
 
2402
        //USER tXRP < 250 ck cycles
2403
        delay_for_n_mem_clocks(250);
2404
 
2405
#ifdef RDIMM
2406
        // USER initialize RDIMM buffer so MRS and RZQ Calibrate commands will be 
2407
        // USER propagated to discrete memory devices
2408
        rw_mgr_rdimm_initialize();
2409
#endif
2410
 
2411
#if LRDIMM
2412
        // USER initialize LRDIMM MB so MRS and RZQ Calibrate commands will be 
2413
        // USER propagated to all sub-ranks.  Per LRDIMM spec, all LRDIMM ranks must have
2414
        // USER RTT_WR set, but only physical ranks 0 and 1 should have RTT_NOM set.
2415
        // USER Therefore RTT_NOM=0 is broadcast to all ranks, and the non-zero value is 
2416
        // USER programmed directly into Ranks 0 and 1 using physical MRS targetting.
2417
        rw_mgr_rdimm_initialize();
2418
 
2419
        rtt_nom = LRDIMM_SPD_MR_RTT_NOM(LRDIMM_SPD_MR);
2420
        rtt_drv = LRDIMM_SPD_MR_RTT_DRV(LRDIMM_SPD_MR);
2421
        rtt_wr  = LRDIMM_SPD_MR_RTT_WR(LRDIMM_SPD_MR);
2422
 
2423
        // USER Configure LRDIMM to broadcast LRDIMM MRS commands to all ranks
2424
        rw_mgr_lrdimm_rc_program(0, 14, (((RDIMM_CONFIG_WORD_HIGH >> 24) & 0xF) & (~0x4)));
2425
 
2426
        // USER Update contents of AC ROM with new RTT WR, DRV values only (NOM = Off)
2427
        rtt_change_MRS1_MRS2_NOM_WR(__RW_MGR_CONTENT_ac_mrs1, rtt_drv, 0, 1);
2428
        rtt_change_MRS1_MRS2_NOM_WR(__RW_MGR_CONTENT_ac_mrs1, rtt_drv, 1, 1);
2429
        rtt_change_MRS1_MRS2_NOM_WR(__RW_MGR_CONTENT_ac_mrs2, rtt_wr,  0, 2);
2430
        rtt_change_MRS1_MRS2_NOM_WR(__RW_MGR_CONTENT_ac_mrs2, rtt_wr,  1, 2);
2431
#endif
2432
#if RDIMM
2433
        // USER initialize RDIMM buffer so MRS and RZQ Calibrate commands will be 
2434
        // USER propagated to discrete memory devices
2435
        rw_mgr_rdimm_initialize();
2436
#endif
2437
 
2438
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r++) {
2439
                if (param->skip_ranks[r]) {
2440
                        //USER request to skip the rank
2441
 
2442
                        continue;
2443
                }
2444
 
2445
#if ADVANCED_ODT_CONTROL
2446
                alt_u32 rtt_nom = 0;
2447
                alt_u32 rtt_wr  = 0;
2448
                alt_u32 rtt_drv = 0;
2449
 
2450
                switch (r) {
2451
                        case 0: {
2452
                                rtt_nom = MR1_RTT_RANK0;
2453
                                rtt_wr  = MR2_RTT_WR_RANK0;
2454
                                rtt_drv = MR1_RTT_DRV_RANK0;
2455
                        } break;
2456
                        case 1: {
2457
                                rtt_nom = MR1_RTT_RANK1;
2458
                                rtt_wr  = MR2_RTT_WR_RANK1;
2459
                                rtt_drv = MR1_RTT_DRV_RANK1;
2460
                        } break;
2461
                        case 2: {
2462
                                rtt_nom = MR1_RTT_RANK2;
2463
                                rtt_wr  = MR2_RTT_WR_RANK2;
2464
                                rtt_drv = MR1_RTT_DRV_RANK2;
2465
                        } break;
2466
                        case 3: {
2467
                                rtt_nom = MR1_RTT_RANK3;
2468
                                rtt_wr  = MR2_RTT_WR_RANK3;
2469
                                rtt_drv = MR1_RTT_DRV_RANK3;
2470
                        } break;
2471
                }
2472
                rtt_change_MRS1_MRS2_NOM_WR (__RW_MGR_CONTENT_ac_mrs1, (rtt_nom|rtt_drv),
2473
                                             ((RW_MGR_MEM_ADDRESS_MIRRORING>>r)&0x1), 1);
2474
                rtt_change_MRS1_MRS2_NOM_WR (__RW_MGR_CONTENT_ac_mrs2, rtt_wr,
2475
                                             ((RW_MGR_MEM_ADDRESS_MIRRORING>>r)&0x1), 2);
2476
#endif //ADVANCED_ODT_CONTROL
2477
 
2478
                //USER set rank 
2479
#if MRS_MIRROR_PING_PONG_ATSO
2480
                // Special case
2481
                // SIDE 0
2482
                set_rank_and_odt_mask_for_ping_pong_atso(0, RW_MGR_ODT_MODE_OFF);
2483
                set_jump_as_return();
2484
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS2);
2485
                delay_for_n_mem_clocks(4);
2486
                set_jump_as_return();
2487
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS3);
2488
                delay_for_n_mem_clocks(4);
2489
                set_jump_as_return();
2490
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS1);
2491
                set_jump_as_return();
2492
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0_DLL_RESET);
2493
 
2494
                // SIDE 1
2495
                set_rank_and_odt_mask_for_ping_pong_atso(1, RW_MGR_ODT_MODE_OFF);
2496
                set_jump_as_return();
2497
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS2_MIRR);
2498
                delay_for_n_mem_clocks(4);
2499
                set_jump_as_return();
2500
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS3_MIRR);
2501
                delay_for_n_mem_clocks(4);
2502
                set_jump_as_return();
2503
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS1_MIRR);
2504
                delay_for_n_mem_clocks(4);
2505
                set_jump_as_return();
2506
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0_DLL_RESET_MIRR);
2507
 
2508
                // Unmask all CS
2509
                set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_OFF);
2510
#else
2511
                set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_OFF);
2512
 
2513
                //USER Use Mirror-ed commands for odd ranks if address mirrorring is on
2514
                if((RW_MGR_MEM_ADDRESS_MIRRORING >> r) & 0x1) {
2515
                        set_jump_as_return();
2516
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS2_MIRR);
2517
                        delay_for_n_mem_clocks(4);
2518
                        set_jump_as_return();
2519
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS3_MIRR);
2520
                        delay_for_n_mem_clocks(4);
2521
                        set_jump_as_return();
2522
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS1_MIRR);
2523
                        delay_for_n_mem_clocks(4);
2524
                        set_jump_as_return();
2525
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0_DLL_RESET_MIRR);
2526
                } else {
2527
                        set_jump_as_return();
2528
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS2);
2529
                        delay_for_n_mem_clocks(4);
2530
                        set_jump_as_return();
2531
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS3);
2532
                        delay_for_n_mem_clocks(4);
2533
                        set_jump_as_return();
2534
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS1);
2535
                        set_jump_as_return();
2536
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0_DLL_RESET);
2537
                }
2538
#endif
2539
 
2540
                set_jump_as_return();
2541
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_ZQCL);
2542
 
2543
                //USER tZQinit = tDLLK = 512 ck cycles
2544
                delay_for_n_mem_clocks(512);
2545
        }
2546
#if LRDIMM
2547
        // USER Configure LRDIMM to target physical ranks decoded by RM bits only (ranks 0,1 only)
2548
        // USER Set bit F0RC14.DBA0 to '1' so MRS commands target physical ranks only
2549
        rw_mgr_lrdimm_rc_program(0, 14, (((RDIMM_CONFIG_WORD_HIGH >> 24) & 0xF) | 0x4));
2550
        // USER update AC ROM MR1 entry to include RTT_NOM
2551
        rtt_change_MRS1_MRS2_NOM_WR(__RW_MGR_CONTENT_ac_mrs1, (rtt_drv|rtt_nom), 0, 1);
2552
        rtt_change_MRS1_MRS2_NOM_WR(__RW_MGR_CONTENT_ac_mrs1, (rtt_drv|rtt_nom), 1, 1);
2553
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r++) {
2554
                if (param->skip_ranks[r]) {
2555
                        //USER request to skip the rank
2556
                        continue;
2557
                }
2558
 
2559
                //USER set rank 
2560
                set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_OFF);
2561
 
2562
                //USER Use Mirror-ed commands for odd ranks if address mirrorring is on
2563
                if((RW_MGR_MEM_ADDRESS_MIRRORING >> r) & 0x1) {
2564
                        delay_for_n_mem_clocks(4);
2565
                        set_jump_as_return();
2566
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS1_MIRR);
2567
                        delay_for_n_mem_clocks(4);
2568
                } else {
2569
                        delay_for_n_mem_clocks(4);
2570
                        set_jump_as_return();
2571
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS1);
2572
                        delay_for_n_mem_clocks(4);
2573
                }
2574
        }
2575
 
2576
        // USER Initiate LRDIMM MB->Physical Rank training here
2577
        // USER -> Set minimum skew mode for levelling - F3RC6 = 0001
2578
        rw_mgr_lrdimm_rc_program(3, 6, 0x1);
2579
        // USER -> Set error status output in register F2RC3 for debugging purposes
2580
        rw_mgr_lrdimm_rc_program(2, 3, 0x8);
2581
 
2582
#ifdef LRDIMM_EXT_CONFIG_ARRAY
2583
        // USER Configure LRDIMM ODT/Drive parameters using SPD information
2584
        {
2585
                static const alt_u8 lrdimm_cfg_array[][3] = LRDIMM_EXT_CONFIG_ARRAY;
2586
                alt_u32 cfg_reg_ctr;
2587
 
2588
                for (cfg_reg_ctr = 0; cfg_reg_ctr < (sizeof(lrdimm_cfg_array)/sizeof(lrdimm_cfg_array[0])); cfg_reg_ctr++)
2589
                {
2590
                        alt_u32 lrdimm_fp  = (alt_u32)lrdimm_cfg_array[cfg_reg_ctr][0];
2591
                        alt_u32 lrdimm_rc  = (alt_u32)lrdimm_cfg_array[cfg_reg_ctr][1];
2592
                        alt_u32 lrdimm_val = (alt_u32)lrdimm_cfg_array[cfg_reg_ctr][2];
2593
 
2594
                        rw_mgr_lrdimm_rc_program(lrdimm_fp, lrdimm_rc, lrdimm_val);
2595
                }
2596
        }
2597
#endif // LRDIMM_EXT_CONFIG_ARRAY
2598
 
2599
        // USER -> Initiate MB->DIMM training on the LRDIMM
2600
        rw_mgr_lrdimm_rc_program(0, 12, 0x2);
2601
#if (!STATIC_SKIP_DELAY_LOOPS)
2602
        // USER Wait for max(tcal) * number of physical ranks. Tcal is approx. 10ms.
2603
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS * RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM; r++)
2604
        {
2605
                delay_for_n_ns(80000000UL);
2606
        }
2607
#endif // !STATIC_SKIP_DELAY_LOOPS
2608
        // USER Place MB back in normal operating mode
2609
        rw_mgr_lrdimm_rc_program(0, 12, 0x0);
2610
#endif // LRDIMM
2611
}
2612
 
2613
 
2614
#if (ENABLE_NON_DESTRUCTIVE_CALIB || ENABLE_NON_DES_CAL)
2615
void rw_mgr_mem_initialize_no_init (void)
2616
{
2617
        alt_u32 r;
2618
        alt_u32 mem_refresh_all_ranks(alt_u32 no_validate);
2619
        TRACE_FUNC();
2620
        rw_mgr_rdimm_initialize();
2621
        IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, RW_MGR_RANK_ALL);
2622
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_RETURN);
2623
        delay_for_n_mem_clocks(512);
2624
        mem_refresh_all_ranks(1);
2625
        IOWR_32DIRECT (PHY_MGR_RESET_MEM_STBL, 0, 1);
2626
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r++) {
2627
                if (param->skip_ranks[r]) {
2628
                        continue;
2629
                }
2630
                set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_OFF);
2631
                set_jump_as_return();
2632
                if((RW_MGR_MEM_ADDRESS_MIRRORING >> r) & 0x1) {
2633
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0_DLL_RESET_MIRR);
2634
                } else {
2635
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0_DLL_RESET);
2636
                }
2637
 
2638
// Reprogramming these is not really required but....
2639
                        set_jump_as_return();
2640
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS2);
2641
                        delay_for_n_mem_clocks(4);
2642
                        set_jump_as_return();
2643
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS3);
2644
                        delay_for_n_mem_clocks(4);
2645
                        set_jump_as_return();
2646
                        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS1);
2647
 
2648
 
2649
 
2650
                delay_for_n_mem_clocks(4);
2651
                set_jump_as_return();
2652
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_ZQCL);
2653
                delay_for_n_mem_clocks(512);
2654
        }
2655
 
2656
        IOWR_32DIRECT (RW_MGR_ENABLE_REFRESH, 0, 1);  // Enable refresh engine  
2657
 
2658
}
2659
#endif
2660
#endif // DDR3
2661
 
2662
#if DDR2
2663
void rw_mgr_mem_initialize (void)
2664
{
2665
        alt_u32 r;
2666
 
2667
        TRACE_FUNC();
2668
 
2669
        //USER *** NOTE ***
2670
        //USER The following STAGE (n) notation refers to the corresponding stage in the Micron datasheet
2671
 
2672
        // Here's how you load register for a loop
2673
        //USER Counters are located @ 0x800
2674
        //USER Jump address are located @ 0xC00
2675
        //USER For both, registers 0 to 3 are selected using bits 3 and 2, like in
2676
        //USER 0x800, 0x804, 0x808, 0x80C and 0xC00, 0xC04, 0xC08, 0xC0C
2677
        // I know this ain't pretty, but Avalon bus throws away the 2 least significant bits
2678
 
2679
        //USER *** STAGE (1, 2, 3) ***
2680
 
2681
        //USER start with CKE low 
2682
 
2683
        //USER tINIT is typically 200us (but can be adjusted in the GUI)
2684
        //USER The total number of cycles required for this nested counter structure to
2685
        //USER complete is defined by:
2686
        //USER        num_cycles = (CTR0 + 1) * [(CTR1 + 1) * (2 * (CTR2 + 1) + 1) + 1] + 1
2687
 
2688
        //TODO: Need to manage multi-rank
2689
 
2690
        //USER Load counters
2691
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_0, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(SEQ_TINIT_CNTR0_VAL));
2692
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_1, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(SEQ_TINIT_CNTR1_VAL));
2693
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_2, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(SEQ_TINIT_CNTR2_VAL));
2694
 
2695
        //USER Load jump address
2696
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_0, 0, __RW_MGR_INIT_CKE_0);
2697
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_1, 0, __RW_MGR_INIT_CKE_0);
2698
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_2, 0, __RW_MGR_INIT_CKE_0);
2699
 
2700
        //USER Execute count instruction
2701
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_INIT_CKE_0);
2702
 
2703
        //USER indicate that memory is stable 
2704
        IOWR_32DIRECT (PHY_MGR_RESET_MEM_STBL, 0, 1);
2705
 
2706
        //USER Bring up CKE 
2707
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_NOP);
2708
 
2709
        //USER *** STAGE (4)
2710
 
2711
        //USER Wait for 400ns 
2712
        delay_for_n_ns(400);
2713
 
2714
        //USER Multi-rank section begins here
2715
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r++) {
2716
                if (param->skip_ranks[r]) {
2717
                        //USER request to skip the rank
2718
 
2719
                        continue;
2720
                }
2721
 
2722
                //USER set rank 
2723
                set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_OFF);
2724
 
2725
                //USER * **** *
2726
                //USER * NOTE *
2727
                //USER * **** *
2728
                //USER The following commands must be spaced by tMRD or tRPA which are in the order
2729
                //USER of 2 to 4 full rate cycles. This is peanuts in the NIOS domain, so for now
2730
                //USER we can avoid redundant wait loops
2731
 
2732
                // Possible FIXME BEN: for HHP, we need to add delay loops to be sure
2733
                // although, the sequencer write interface by itself likely has enough delay
2734
 
2735
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_PRECHARGE_ALL);
2736
 
2737
                //USER *** STAGE (5)
2738
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_EMR2);
2739
 
2740
                //USER *** STAGE (6)
2741
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_EMR3);
2742
 
2743
                //USER *** STAGE (7)
2744
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_EMR);
2745
 
2746
                //USER *** STAGE (8)
2747
                //USER DLL reset
2748
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MR_DLL_RESET);
2749
 
2750
                //USER *** STAGE (9)
2751
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_PRECHARGE_ALL);
2752
 
2753
                //USER *** STAGE (10)
2754
 
2755
                //USER Issue 2 refresh commands spaced by tREF 
2756
 
2757
                //USER First REFRESH
2758
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_REFRESH);
2759
 
2760
                //USER tREF = 200ns
2761
                delay_for_n_ns(200);
2762
 
2763
                //USER Second REFRESH
2764
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_REFRESH);
2765
 
2766
                //USER Second idle loop
2767
                delay_for_n_ns(200);
2768
 
2769
                //USER *** STAGE (11)
2770
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MR_CALIB);
2771
 
2772
                //USER *** STAGE (12)
2773
                //USER OCD defaults
2774
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_EMR_OCD_ENABLE);
2775
 
2776
                //USER *** STAGE (13)
2777
                //USER OCD exit
2778
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_EMR);
2779
 
2780
                //USER *** STAGE (14)
2781
 
2782
                //USER The memory is now initialized. Before being able to use it, we must still
2783
                //USER wait for the DLL to lock, 200 clock cycles after it was reset @ STAGE (8).
2784
                //USER Since we cannot keep track of time in any other way, let's start counting from now
2785
                delay_for_n_mem_clocks(200);
2786
        }
2787
}
2788
#endif // DDR2 
2789
 
2790
#if LPDDR2
2791
void rw_mgr_mem_initialize (void)
2792
{
2793
        alt_u32 r;
2794
 
2795
        //USER *** NOTE ***
2796
        //USER The following STAGE (n) notation refers to the corresponding stage in the Micron datasheet
2797
 
2798
        // Here's how you load register for a loop
2799
        //USER Counters are located @ 0x800
2800
        //USER Jump address are located @ 0xC00
2801
        //USER For both, registers 0 to 3 are selected using bits 3 and 2, like in
2802
        //USER 0x800, 0x804, 0x808, 0x80C and 0xC00, 0xC04, 0xC08, 0xC0C
2803
        // I know this ain't pretty, but Avalon bus throws away the 2 least significant bits
2804
 
2805
        //USER *** STAGE (1, 2, 3) ***
2806
 
2807
        //USER start with CKE low 
2808
 
2809
        //USER tINIT1 = 100ns
2810
 
2811
        //USER 100ns @ 300MHz (3.333 ns) ~ 30 cycles
2812
        //USER If a is the number of iteration in a loop
2813
        //USER it takes the following number of cycles to complete the operation:
2814
        //USER number_of_cycles = (2 + n) * a
2815
        //USER where n is the number of instruction in the inner loop
2816
        //USER One possible solution is n = 0 , a = 15 => a = 0x10
2817
 
2818
        //USER Load counter
2819
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_0, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(0x10));
2820
 
2821
        //USER Load jump address
2822
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_0, 0, __RW_MGR_INIT_CKE_0);
2823
 
2824
        //USER Execute count instruction
2825
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_INIT_CKE_0);
2826
 
2827
        //USER tINIT3 = 200us
2828
        delay_for_n_ns(200000);
2829
 
2830
        //USER indicate that memory is stable 
2831
        IOWR_32DIRECT (PHY_MGR_RESET_MEM_STBL, 0, 1);
2832
 
2833
        //USER Multi-rank section begins here
2834
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r++) {
2835
                if (param->skip_ranks[r]) {
2836
                        //USER request to skip the rank
2837
 
2838
                        continue;
2839
                }
2840
 
2841
                //USER set rank 
2842
                set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_OFF);
2843
 
2844
                //USER MRW RESET
2845
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MR63_RESET);
2846
        }
2847
 
2848
        //USER tINIT5 = 10us
2849
        delay_for_n_ns(10000);
2850
 
2851
        //USER Multi-rank section begins here
2852
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r++) {
2853
                if (param->skip_ranks[r]) {
2854
                        //USER request to skip the rank
2855
 
2856
                        continue;
2857
                }
2858
 
2859
                //USER set rank 
2860
                set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_OFF);
2861
 
2862
                //USER MRW ZQC
2863
                // Note: We cannot calibrate other ranks when the current rank is calibrating for tZQINIT
2864
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MR10_ZQC);
2865
 
2866
                //USER tZQINIT = 1us
2867
                delay_for_n_ns(1000);
2868
 
2869
                //USER * **** *
2870
                //USER * NOTE *
2871
                //USER * **** *
2872
                //USER The following commands must be spaced by tMRW which is in the order
2873
                //USER of 3 to 5 full rate cycles. This is peanuts in the NIOS domain, so for now
2874
                //USER we can avoid redundant wait loops
2875
 
2876
                //USER MRW MR1
2877
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MR1_CALIB);
2878
 
2879
                //USER MRW MR2
2880
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MR2);
2881
 
2882
                //USER MRW MR3
2883
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MR3);
2884
        }
2885
}
2886
#endif // LPDDR2 
2887
 
2888
#if LPDDR1
2889
void rw_mgr_mem_initialize (void)
2890
{
2891
        alt_u32 r;
2892
 
2893
        TRACE_FUNC();
2894
 
2895
        //USER *** NOTE ***
2896
        //USER The following STAGE (n) notation refers to the corresponding stage in the Micron datasheet
2897
 
2898
        // Here's how you load register for a loop
2899
        //USER Counters are located @ 0x800
2900
        //USER Jump address are located @ 0xC00
2901
        //USER For both, registers 0 to 3 are selected using bits 3 and 2, like in
2902
        //USER 0x800, 0x804, 0x808, 0x80C and 0xC00, 0xC04, 0xC08, 0xC0C
2903
        // I know this ain't pretty, but Avalon bus throws away the 2 least significant bits
2904
 
2905
        //USER *** STAGE (1, 2, 3) ***
2906
 
2907
        //USER start with CKE high 
2908
 
2909
        //USER tINIT = 200us
2910
 
2911
        //USER 200us @ 300MHz (3.33 ns) ~ 60000 clock cycles
2912
        //USER If a and b are the number of iteration in 2 nested loops
2913
        //USER it takes the following number of cycles to complete the operation:
2914
        //USER number_of_cycles = ((2 + n) * b + 2) * a
2915
        //USER where n is the number of instruction in the inner loop
2916
        //USER One possible solution is n = 0 , a = 256 , b = 118 => a = FF, b = 76
2917
 
2918
        //TODO: Need to manage multi-rank
2919
 
2920
        //USER Load counters
2921
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_0, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(0xFF));
2922
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_1, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(0x76));
2923
 
2924
        //USER Load jump address
2925
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_0, 0, __RW_MGR_INIT_CKE_1);
2926
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_1, 0, __RW_MGR_INIT_CKE_1_inloop);
2927
 
2928
        //USER Execute count instruction and bring up CKE
2929
        //USER IOWR_32DIRECT (BASE_RW_MGR, 0, __RW_MGR_COUNT_REG_0);
2930
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_INIT_CKE_1);
2931
 
2932
        //USER indicate that memory is stable 
2933
        IOWR_32DIRECT (PHY_MGR_RESET_MEM_STBL, 0, 1);
2934
 
2935
        //USER Multi-rank section begins here
2936
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r++) {
2937
                if (param->skip_ranks[r]) {
2938
                        //USER request to skip the rank
2939
 
2940
                        continue;
2941
                }
2942
 
2943
                //USER set rank 
2944
                set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_OFF);
2945
 
2946
                //USER * **** *
2947
                //USER * NOTE *
2948
                //USER * **** *
2949
                //USER The following commands must be spaced by tMRD or tRPA which are in the order
2950
                //USER of 2 to 4 full rate cycles. This is peanuts in the NIOS domain, so for now
2951
                //USER we can avoid redundant wait loops
2952
 
2953
                // Possible FIXME BEN: for HHP, we need to add delay loops to be sure
2954
                // although, the sequencer write interface by itself likely has enough delay
2955
 
2956
                //USER *** STAGE (9)
2957
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_PRECHARGE_ALL);
2958
 
2959
                //USER *** STAGE (10)
2960
 
2961
                //USER Issue 2 refresh commands spaced by tREF 
2962
 
2963
                //USER First REFRESH
2964
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_REFRESH);
2965
 
2966
                //USER tREF = 200ns
2967
                delay_for_n_ns(200);
2968
 
2969
                //USER Second REFRESH
2970
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_REFRESH);
2971
 
2972
                //USER Second idle loop
2973
                delay_for_n_ns(200);
2974
 
2975
                //USER *** STAGE (11)
2976
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MR_CALIB);
2977
 
2978
                //USER *** STAGE (13)
2979
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_EMR);
2980
 
2981
        }
2982
}
2983
#endif // LPDDR1
2984
 
2985
#if QDRII
2986
void rw_mgr_mem_initialize (void)
2987
{
2988
        TRACE_FUNC();
2989
 
2990
        //USER Turn off QDRII DLL to reset it
2991
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_IDLE);
2992
 
2993
        //USER Turn on QDRII DLL and wait 25us for it to lock
2994
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_NOP);
2995
        delay_for_n_ns(25000);
2996
 
2997
        //USER indicate that memory is stable
2998
        IOWR_32DIRECT (PHY_MGR_RESET_MEM_STBL, 0, 1);
2999
}
3000
#endif
3001
 
3002
#if QDRII
3003
void rw_mgr_mem_dll_lock_wait (void)
3004
{
3005
        //USER The DLL in QDR requires 25us to lock
3006
        delay_for_n_ns(25000);
3007
}
3008
#else
3009
void rw_mgr_mem_dll_lock_wait (void) { }
3010
#endif
3011
 
3012
#if RLDRAMII
3013
void rw_mgr_mem_initialize (void)
3014
{
3015
        TRACE_FUNC();
3016
 
3017
        //USER start with memory RESET activated
3018
 
3019
        //USER tINIT = 200us
3020
        delay_for_n_ns(200000);
3021
 
3022
        //USER indicate that memory is stable 
3023
        IOWR_32DIRECT (PHY_MGR_RESET_MEM_STBL, 0, 1);
3024
 
3025
        //USER Dummy MRS, followed by valid MRS commands to reset the DLL on memory device
3026
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS_INIT);
3027
 
3028
        //USER 8192 memory cycles for DLL to lock. 
3029
        // 8192 cycles are required by Renesas LLDRAM-II, though we don't officially support it
3030
        delay_for_n_mem_clocks(8192);
3031
 
3032
        //USER Refresh all banks
3033
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_REF_X8);
3034
 
3035
        //USER 1024 memory cycles
3036
        delay_for_n_mem_clocks(1024);
3037
}
3038
#endif
3039
 
3040
#if RLDRAM3
3041
void rw_mgr_mem_initialize (void)
3042
{
3043
        TRACE_FUNC();
3044
        alt_u32 r;
3045
 
3046
        // Here's how you load register for a loop
3047
        //USER Counters are located @ 0x800
3048
        //USER Jump address are located @ 0xC00
3049
        //USER For both, registers 0 to 3 are selected using bits 3 and 2, like in
3050
        //USER 0x800, 0x804, 0x808, 0x80C and 0xC00, 0xC04, 0xC08, 0xC0C
3051
        // I know this ain't pretty, but Avalon bus throws away the 2 least significant bits
3052
 
3053
        //USER start with memory RESET activated
3054
 
3055
        //USER tINIT = 200us
3056
 
3057
        //USER 200us @ 266MHz (3.75 ns) ~ 54000 clock cycles
3058
        //USER If a and b are the number of iteration in 2 nested loops
3059
        //USER it takes the following number of cycles to complete the operation:
3060
        //USER number_of_cycles = ((2 + n) * a + 2) * b
3061
        //USER where n is the number of instruction in the inner loop
3062
        //USER One possible solution is n = 0 , a = 256 , b = 106 => a = FF, b = 6A
3063
 
3064
        //USER Load counters
3065
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_0, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(0xFF));
3066
        IOWR_32DIRECT (RW_MGR_LOAD_CNTR_1, 0, SKIP_DELAY_LOOP_VALUE_OR_ZERO(0x6A));
3067
 
3068
        //USER Load jump address
3069
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_0, 0, __RW_MGR_INIT_RESET_0);
3070
        IOWR_32DIRECT (RW_MGR_LOAD_JUMP_ADD_1, 0, __RW_MGR_INIT_RESET_0_inloop);
3071
 
3072
        //USER Execute count instruction
3073
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_INIT_RESET_0);
3074
 
3075
        //USER indicate that memory is stable
3076
        IOWR_32DIRECT (PHY_MGR_RESET_MEM_STBL, 0, 1);
3077
 
3078
        //USER transition the RESET to high 
3079
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_NOP);
3080
 
3081
        //USER Wait for 10000 cycles
3082
        delay_for_n_mem_clocks(10000);
3083
 
3084
        //USER Load MR0
3085
        if ( RW_MGR_MEM_NUMBER_OF_RANKS == 1 ) {
3086
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xFE);
3087
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0);
3088
        } else if ( RW_MGR_MEM_NUMBER_OF_RANKS == 2 ) {
3089
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xFC);
3090
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0);
3091
        } else if ( RW_MGR_MEM_NUMBER_OF_RANKS == 4 ) {
3092
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xFC);
3093
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0);
3094
                //USER Wait MRSC
3095
                delay_for_n_mem_clocks(12);
3096
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xF3);
3097
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0_QUAD_RANK);
3098
        }
3099
        else {
3100
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xFE);
3101
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0);
3102
        }
3103
 
3104
 
3105
        //USER Wait MRSC
3106
        delay_for_n_mem_clocks(12);
3107
 
3108
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r++) {
3109
                if (param->skip_ranks[r]) {
3110
                        //USER request to skip the rank
3111
                        continue;
3112
                }
3113
                set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_OFF);
3114
                //USER Load MR1 (reset DLL reset and kick off long ZQ calibration)
3115
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS1_CALIB);
3116
 
3117
      //USER Wait 512 cycles for DLL to reset and for ZQ calibration to complete
3118
      delay_for_n_mem_clocks(512);
3119
        }
3120
 
3121
        //USER Load MR2 (set write protocol to Single Bank)
3122
        if ( RW_MGR_MEM_NUMBER_OF_RANKS == 1 ) {
3123
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xFE);
3124
        } else if ( RW_MGR_MEM_NUMBER_OF_RANKS == 2 ) {
3125
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xFC);
3126
        } else if ( RW_MGR_MEM_NUMBER_OF_RANKS == 4 ) {
3127
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xF0);
3128
        }
3129
        else {
3130
                IOWR_32DIRECT (RW_MGR_SET_CS_AND_ODT_MASK, 0, 0xFE);
3131
        }
3132
        IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS2_CALIB);
3133
 
3134
        //USER Wait MRSC and a bit more
3135
        delay_for_n_mem_clocks(64);
3136
}
3137
#endif
3138
 
3139
//USER  At the end of calibration we have to program the user settings in, and
3140
//USER  hand off the memory to the user.
3141
 
3142
#if DDR3
3143
void rw_mgr_mem_handoff (void)
3144
{
3145
        alt_u32 r;
3146
#if LRDIMM
3147
        alt_u32 rtt_nom;
3148
        alt_u32 rtt_drv;
3149
        alt_u32 rtt_wr;
3150
#endif // LRDIMM
3151
 
3152
        TRACE_FUNC();
3153
 
3154
#if LRDIMM
3155
        rtt_nom = LRDIMM_SPD_MR_RTT_NOM(LRDIMM_SPD_MR);
3156
        rtt_drv = LRDIMM_SPD_MR_RTT_DRV(LRDIMM_SPD_MR);
3157
        rtt_wr  = LRDIMM_SPD_MR_RTT_WR(LRDIMM_SPD_MR);
3158
 
3159
        // USER Configure LRDIMM to broadcast LRDIMM MRS commands to all ranks
3160
        // USER Set bit F0RC14.DBA0 to '0' so MRS commands target all physical ranks in a logical rank
3161
        rw_mgr_lrdimm_rc_program(0, 14, (((RDIMM_CONFIG_WORD_HIGH >> 24) & 0xF) & (~0x4)));
3162
 
3163
        // USER Update contents of AC ROM with new RTT WR, DRV values
3164
        rtt_change_MRS1_MRS2_NOM_WR (__RW_MGR_CONTENT_ac_mrs1, rtt_drv, 0, 1);
3165
        rtt_change_MRS1_MRS2_NOM_WR (__RW_MGR_CONTENT_ac_mrs1, rtt_drv, 1, 1);
3166
        rtt_change_MRS1_MRS2_NOM_WR (__RW_MGR_CONTENT_ac_mrs2, rtt_wr,  0, 2);
3167
        rtt_change_MRS1_MRS2_NOM_WR (__RW_MGR_CONTENT_ac_mrs2, rtt_wr,  1, 2);
3168
#endif // LRDIMM
3169
 
3170
        for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r++) {
3171
                if (param->skip_ranks[r]) {
3172
                        //USER request to skip the rank
3173
 
3174
                        continue;
3175
                }
3176
 
3177
#if MRS_MIRROR_PING_PONG_ATSO
3178
                // Side 0
3179
                set_rank_and_odt_mask_for_ping_pong_atso(0, RW_MGR_ODT_MODE_OFF);
3180
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_PRECHARGE_ALL);
3181
                set_jump_as_return();
3182
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS2);
3183
                delay_for_n_mem_clocks(4);
3184
                set_jump_as_return();
3185
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS3);
3186
                delay_for_n_mem_clocks(4);
3187
                set_jump_as_return();
3188
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS1);
3189
                delay_for_n_mem_clocks(4);
3190
                set_jump_as_return();
3191
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_MRS0_USER);
3192
 
3193
                // Side 1
3194
                set_rank_and_odt_mask_for_ping_pong_atso(1, RW_MGR_ODT_MODE_OFF);
3195
                IOWR_32DIRECT (RW_MGR_RUN_SINGLE_GROUP, 0, __RW_MGR_PRECHARGE_ALL);
3196
                set_jump_as_return();
</