source: umon/ports/beagleboneblack/cpuio.c

Last change on this file was 63834b9, checked in by Jarielle Catbagan <jcatbagan93@…>, on Aug 21, 2015 at 5:05:59 PM

BBB: Add proper attributions to the files modified

  • Property mode set to 100644
File size: 18.7 KB
Line 
1/*
2 * General notice:
3 * This code is part of a boot-monitor package developed as a generic base
4 * platform for embedded system designs.  As such, it is likely to be
5 * distributed to various projects beyond the control of the original
6 * author.  Please notify the author of any enhancements made or bugs found
7 * so that all may benefit from the changes.  In addition, notification back
8 * to the author will allow the new user to pick up changes that may have
9 * been made by other users after this version of the code was distributed.
10 *
11 * Author:  Ed Sutter
12 * email:   esutter@lucent.com
13 * phone:   908-582-2351
14 *
15 *
16 * Adapted by Jarielle Catbagan for the Beaglebone Black
17 * email: jcatbagan93@gmail.com
18 */
19
20#include "config.h"
21#include "stddefs.h"
22#include "cpuio.h"
23#include "genlib.h"
24#include "cache.h"
25#include "warmstart.h"
26#include "timer.h"
27#include "am335x.h"
28#include "uart16550.h"
29#include "cli.h"
30
31int
32getUartDivisor(int baud, unsigned char *hi, unsigned char *lo)
33{
34    *lo = ((48000000/16)/baud) & 0x00ff;
35    *hi = (((48000000/16)/baud) & 0xff00) >> 8;
36    return(0);
37}
38
39/* devInit():
40 * As a bare minimum, initialize the console UART here using the
41 * incoming 'baud' value as the baud rate.
42 */
43int
44devInit(int baud)
45{
46    return(0);
47}
48
49/* ConsoleBaudSet():
50 * Provide a means to change the baud rate of the running
51 * console interface.  If the incoming value is not a valid
52 * baud rate, then default to 9600.
53 * In the early stages of a new port this can be left empty.
54 * Return 0 if successful; else -1.
55 */
56/*int
57ConsoleBaudSet(int baud)
58{
59    // ADD_CODE_HERE
60    return(0);
61}*/
62
63/* target_console_empty():
64 * Target-specific portion of flush_console() in chario.c.
65 * This function returns 1 if there are no characters waiting to
66 * be put out on the UART; else return 0 indicating that the UART
67 * is still busy outputting characters from its FIFO.
68 * In the early stages of a new port this can simply return 1.
69 */
70/*int
71target_console_empty(void)
72{
73    // if (UART_OUTPUT_BUFFER_IS_EMPTY())  <- FIX CODE HERE
74        return(0);
75    return(1);
76}*/
77
78/* intsoff():
79 * Disable all system interrupts here and return a value that can
80 * be used by intsrestore() (later) to restore the interrupt state.
81 */
82ulong
83intsoff(void)
84{
85    ulong status = 0;
86
87    /* ADD_CODE_HERE */
88    return(status);
89}
90
91/* intsrestore():
92 * Re-establish system interrupts here by using the status value
93 * that was returned by an earlier call to intsoff().
94 */
95void
96intsrestore(ulong status)
97{
98    /* ADD_CODE_HERE */
99}
100
101/* cacheInitForTarget():
102 * Establish target specific function pointers and
103 * enable i-cache...
104 * Refer to $core/cache.c for a description of the function pointers.
105 * NOTE:
106 * If cache (either I or D or both) is enabled, then it is important
107 * that the appropriate cacheflush/invalidate function be established.
108 * This is very important because programs (i.e. cpu instructions) are
109 * transferred to memory using data memory accesses and could
110 * potentially result in cache coherency problems.
111 */
112void
113cacheInitForTarget(void)
114{
115    /* ADD_CODE_HERE */
116}
117
118/* target_reset():
119 * The default (absolute minimum) action to be taken by this function
120 * is to call monrestart(INITIALIZE).  It would be better if there was
121 * some target-specific function that would really cause the target
122 * to reset...
123 */
124void
125target_reset(void)
126{
127//  flushDcache(0,0);
128//  disableDcache();
129//  invalidateIcache(0,0);
130//  disableIcache();
131    monrestart(INITIALIZE);
132}
133
134/* Override the default exception handlers provided by the AM335x
135 * internal ROM code with uMon's custom exception handlers
136 */
137void
138ram_vector_install(void)
139{
140    extern unsigned long abort_data;
141    extern unsigned long abort_prefetch;
142    extern unsigned long undefined_instruction;
143    extern unsigned long software_interrupt;
144    extern unsigned long interrupt_request;
145    extern unsigned long fast_interrupt_request;
146    extern unsigned long not_assigned;
147
148    *(ulong **)0x4030ce24 = &undefined_instruction;
149    *(ulong **)0x4030ce28 = &software_interrupt;
150    *(ulong **)0x4030ce2c = &abort_prefetch;
151    *(ulong **)0x4030ce30 = &abort_data;
152    *(ulong **)0x4030ce34 = &not_assigned;
153    *(ulong **)0x4030ce38 = &interrupt_request;
154    *(ulong **)0x4030ce3c = &fast_interrupt_request;
155}
156
157void
158pinMuxInit(void)
159{
160    // Set pin mux configuration for UART0 RX/TX pins
161    CNTL_MODULE_REG(CONF_UART0_RXD) = SLEWSLOW | RX_ON |
162                                      PULL_OFF | MUXMODE_0;
163    CNTL_MODULE_REG(CONF_UART0_TXD) = SLEWSLOW | RX_OFF |
164                                      PULL_OFF | MUXMODE_0;
165
166    // Configure GPIO pins tied to four USR LEDS...
167    // GPIO1_21: USER0 LED (D2)
168    CNTL_MODULE_REG(CONF_GPMC_A5) = SLEWSLOW | RX_ON |
169                                    PULL_OFF | MUXMODE_7;
170    // GPIO1_22: USER1 LED (D3)
171    CNTL_MODULE_REG(CONF_GPMC_A6) = SLEWSLOW | RX_ON |
172                                    PULL_OFF | MUXMODE_7;
173    // GPIO1_23: USER2 LED (D4)
174    CNTL_MODULE_REG(CONF_GPMC_A7) = SLEWSLOW | RX_ON |
175                                    PULL_OFF | MUXMODE_7;
176    // GPIO1_24: USER3 LED (D5)
177    CNTL_MODULE_REG(CONF_GPMC_A8) = SLEWSLOW | RX_ON |
178                                    PULL_OFF | MUXMODE_7;
179
180    // Configure the pins for the MMC0 interface
181    CNTL_MODULE_REG(CONF_MMC0_DAT0) = RX_ON | PULL_ON |
182                                      PULLUP | MUXMODE_0;
183    CNTL_MODULE_REG(CONF_MMC0_DAT1) = RX_ON | PULL_ON |
184                                      PULLUP | MUXMODE_0;
185    CNTL_MODULE_REG(CONF_MMC0_DAT2) = RX_ON | PULL_ON |
186                                      PULLUP | MUXMODE_0;
187    CNTL_MODULE_REG(CONF_MMC0_DAT3) = RX_ON | PULL_ON |
188                                      PULLUP | MUXMODE_0;
189    CNTL_MODULE_REG(CONF_MMC0_CLK) = RX_ON | PULL_OFF |
190                                     MUXMODE_0;
191    CNTL_MODULE_REG(CONF_MMC0_CMD) = RX_ON | PULL_ON |
192                                     PULLUP | MUXMODE_0;
193    CNTL_MODULE_REG(CONF_SPI0_CS1) = RX_ON | PULL_ON |
194                                     PULLUP | MUXMODE_5;
195
196    // Configure the pins for the MMC1 interface
197    /* MMC1_DAT0 */
198    CNTL_MODULE_REG(CONF_GPMC_AD0) = RX_ON | PULL_ON |
199                                     PULLUP | MUXMODE_1;
200    /* MMC1_DAT1 */
201    CNTL_MODULE_REG(CONF_GPMC_AD1) = RX_ON | PULL_ON |
202                                     PULLUP | MUXMODE_1;
203    /* MMC1_DAT2 */
204    CNTL_MODULE_REG(CONF_GPMC_AD2) = RX_ON | PULL_ON |
205                                     PULLUP | MUXMODE_1;
206    /* MMC1_DAT3 */
207    CNTL_MODULE_REG(CONF_GPMC_AD3) = RX_ON | PULL_ON |
208                                     PULLUP | MUXMODE_1;
209    /* MMC1_DAT4 */
210    CNTL_MODULE_REG(CONF_GPMC_AD4) = RX_ON | PULL_ON |
211                                     PULLUP | MUXMODE_1;
212    /* MMC1_DAT5 */
213    CNTL_MODULE_REG(CONF_GPMC_AD5) = RX_ON | PULL_ON |
214                                     PULLUP | MUXMODE_1;
215    /* MMC1_DAT6 */
216    CNTL_MODULE_REG(CONF_GPMC_AD6) = RX_ON | PULL_ON |
217                                     PULLUP | MUXMODE_1;
218    /* MMC1_DAT7 */
219    CNTL_MODULE_REG(CONF_GPMC_AD7) = RX_ON | PULL_ON |
220                                     PULLUP | MUXMODE_1;
221    /* MMC1_CLK */
222    CNTL_MODULE_REG(CONF_GPMC_CSN1) = RX_ON | PULL_OFF |
223                                      MUXMODE_2;
224    /* MMC1_CMD */
225    CNTL_MODULE_REG(CONF_GPMC_CSN2) = RX_ON | PULL_ON |
226                                      PULLUP | MUXMODE_2;
227}
228
229void
230InitGPIO1(void)
231{
232    // GPIO_CTRL: Enable GPIO1 module
233    GPIO1_REG(0x130) = 0;
234
235    // GPIO_OE: 25-24 are outputs...
236    GPIO1_REG(0x134) &= ~(USR0_LED | USR1_LED | USR2_LED | USR3_LED);
237
238    // All LEDs off...
239    GPIO1_REG(0x13c) &= ~(USR0_LED | USR1_LED | USR2_LED | USR3_LED);
240}
241
242/* If any CPU IO wasn't initialized in reset.S, do it here...
243 * This just provides a "C-level" IO init opportunity.
244 */
245void
246initCPUio(void)
247{
248    ram_vector_install();
249
250    // Enable the control module:
251    CM_WKUP_REG(CM_WKUP_CONTROL_CLKCTRL) |= 2;
252
253    // Enable clock for UART0:
254    CM_WKUP_REG(CM_WKUP_UART0_CLKCTRL) |= 2;
255
256    // Enable clock for GPIO1:
257    CM_PER_REG(CM_PER_GPIO1_CLKCTRL) |= 2;
258
259    /* Enable MMC0 clocks */
260    CM_PER_REG(CM_PER_MMC0_CLKCTRL) |= CM_PER_MMC0_CLKCTRL_MODULEMODE_ENABLE;
261    while(CM_PER_REG(CM_PER_MMC0_CLKCTRL) & CM_PER_MMC0_CLKCTRL_IDLEST);
262
263    /* Enable MMC1 clocks */
264    CM_PER_REG(CM_PER_MMC1_CLKCTRL) |= CM_PER_MMC1_CLKCTRL_MODULEMODE_ENABLE;
265    while(CM_PER_REG(CM_PER_MMC1_CLKCTRL) & CM_PER_MMC0_CLKCTRL_IDLEST);
266
267    pinMuxInit();
268
269    InitUART(DEFAULT_BAUD_RATE);
270    InitGPIO1();
271
272    // Set UART0 mode to 16x
273    UART0_REG(UART_MDR1) &= ~7;
274}
275
276int
277led(int num, int on)
278{
279    unsigned long bit;
280
281    switch(num) {
282    case 0: // D0
283        bit = USR0_LED;
284        break;
285    case 1: // D1
286        bit = USR1_LED;
287        break;
288    case 2: // D2
289        bit = USR2_LED;
290        break;
291    case 3: // D3
292        bit = USR3_LED;
293        break;
294    default:
295        return(-1);
296    }
297
298    // GPIO21-24:
299    if(on) {
300        GPIO1_REG(0x13c) |= bit;
301    } else {
302        GPIO1_REG(0x13c) &= ~bit;
303    }
304    return(0);
305}
306
307void
308target_blinkled(void)
309{
310#if INCLUDE_BLINKLED
311    static uint8_t ledstate;
312    static struct elapsed_tmr tmr;
313
314#define STATLED_ON()    led(0,1)
315#define STATLED_OFF()   led(0,0)
316#ifndef BLINKON_MSEC
317#define BLINKON_MSEC 10000
318#define BLINKOFF_MSEC 10000
319#endif
320
321    switch(ledstate) {
322    case 0:
323        startElapsedTimer(&tmr,BLINKON_MSEC);
324        STATLED_ON();
325        ledstate = 1;
326        break;
327    case 1:
328        if(msecElapsed(&tmr)) {
329            STATLED_OFF();
330            ledstate = 2;
331            startElapsedTimer(&tmr,BLINKOFF_MSEC);
332        }
333        break;
334    case 2:
335        if(msecElapsed(&tmr)) {
336            STATLED_ON();
337            ledstate = 1;
338            startElapsedTimer(&tmr,BLINKON_MSEC);
339        }
340        break;
341    }
342#endif
343}
344
345void
346mpu_pll_init(void)
347{
348    uint32_t cm_clkmode_dpll_mpu;
349    uint32_t cm_clksel_dpll_mpu;
350    uint32_t cm_div_m2_dpll_mpu;
351
352    // Put MPU PLL in MN Bypass mode
353    cm_clkmode_dpll_mpu = CM_WKUP_REG(CM_CLKMODE_DPLL_MPU);
354    cm_clkmode_dpll_mpu &= ~0x00000007;
355    cm_clkmode_dpll_mpu |= 0x00000004;
356    CM_WKUP_REG(CM_CLKMODE_DPLL_MPU) = cm_clkmode_dpll_mpu;
357    // Wait for MPU PLL to enter MN Bypass mode
358    while((CM_WKUP_REG(CM_IDLEST_DPLL_MPU) & 0x00000101) != 0x00000100);
359
360    // Set the ARM core frequency to 1 GHz
361    cm_clksel_dpll_mpu = CM_WKUP_REG(CM_CLKSEL_DPLL_MPU);
362    cm_clksel_dpll_mpu &= ~0x0007FF7F;
363    cm_clksel_dpll_mpu |= 1000 << 8;
364    cm_clksel_dpll_mpu |= 23;
365    CM_WKUP_REG(CM_CLKSEL_DPLL_MPU) = cm_clksel_dpll_mpu;
366    cm_div_m2_dpll_mpu = CM_WKUP_REG(CM_DIV_M2_DPLL_MPU);
367    cm_div_m2_dpll_mpu &= ~0x0000001F;
368    cm_div_m2_dpll_mpu |= 0x00000001;
369    CM_WKUP_REG(CM_DIV_M2_DPLL_MPU) = cm_div_m2_dpll_mpu;
370
371    // Lock MPU PLL
372    cm_clkmode_dpll_mpu = CM_WKUP_REG(CM_CLKMODE_DPLL_MPU);
373    cm_clkmode_dpll_mpu &= ~0x00000007;
374    cm_clkmode_dpll_mpu |= 0x00000007;
375    CM_WKUP_REG(CM_CLKMODE_DPLL_MPU) = cm_clkmode_dpll_mpu;
376    // Wait for MPU PLL to lock
377    while((CM_WKUP_REG(CM_IDLEST_DPLL_MPU) & 0x00000001) != 0x00000001);
378}
379
380void
381core_pll_init(void)
382{
383    uint32_t cm_clkmode_dpll_core;
384    uint32_t cm_clksel_dpll_core;
385    uint32_t cm_div_m4_dpll_core;
386    uint32_t cm_div_m5_dpll_core;
387    uint32_t cm_div_m6_dpll_core;
388
389    // Put Core PLL in MN Bypass mode
390    cm_clkmode_dpll_core = CM_WKUP_REG(CM_CLKMODE_DPLL_CORE);
391    cm_clkmode_dpll_core &= ~0x00000007;
392    cm_clkmode_dpll_core |= 0x00000004;
393    CM_WKUP_REG(CM_CLKMODE_DPLL_CORE) = cm_clkmode_dpll_core;
394    // Wait for Core PLL to enter MN Bypass mode
395    while((CM_WKUP_REG(CM_IDLEST_DPLL_CORE) & 0x00000101) != 0x00000100);
396
397    // Configure the multiplier and divider
398    cm_clksel_dpll_core = CM_WKUP_REG(CM_CLKSEL_DPLL_CORE);
399    cm_clksel_dpll_core &= ~0x0007FF7F;
400    cm_clksel_dpll_core |= 1000 << 8;
401    cm_clksel_dpll_core |= 23;
402    CM_WKUP_REG(CM_CLKSEL_DPLL_CORE) = cm_clksel_dpll_core;
403    // Configure the M4, M5, and M6 dividers
404    cm_div_m4_dpll_core = CM_WKUP_REG(CM_DIV_M4_DPLL_CORE);
405    cm_div_m4_dpll_core &= ~0x0000001F;
406    cm_div_m4_dpll_core |= 10;
407    CM_WKUP_REG(CM_DIV_M4_DPLL_CORE) = cm_div_m4_dpll_core;
408    cm_div_m5_dpll_core = CM_WKUP_REG(CM_DIV_M5_DPLL_CORE);
409    cm_div_m5_dpll_core &= ~0x0000001F;
410    cm_div_m5_dpll_core |= 8;
411    CM_WKUP_REG(CM_DIV_M5_DPLL_CORE) = cm_div_m5_dpll_core;
412    cm_div_m6_dpll_core = CM_WKUP_REG(CM_DIV_M6_DPLL_CORE);
413    cm_div_m6_dpll_core &= ~0x0000001F;
414    cm_div_m6_dpll_core |= 4;
415    CM_WKUP_REG(CM_DIV_M6_DPLL_CORE) = cm_div_m6_dpll_core;
416
417    // Lock Core PLL
418    cm_clkmode_dpll_core = CM_WKUP_REG(CM_CLKMODE_DPLL_CORE);
419    cm_clkmode_dpll_core &= ~0x00000007;
420    cm_clkmode_dpll_core |= 0x00000007;
421    CM_WKUP_REG(CM_CLKMODE_DPLL_CORE) = cm_clkmode_dpll_core;
422    // Wait for Core PLL to lock
423    while((CM_WKUP_REG(CM_IDLEST_DPLL_CORE) & 0x00000001) != 0x00000001);
424}
425
426void
427ddr_pll_init(void)
428{
429    uint32_t cm_clkmode_dpll_ddr;
430    uint32_t cm_clksel_dpll_ddr;
431    uint32_t cm_div_m2_dpll_ddr;
432
433    // Put DDR PLL in MN Bypass mode
434    cm_clkmode_dpll_ddr = CM_WKUP_REG(CM_CLKMODE_DPLL_DDR);
435    cm_clkmode_dpll_ddr &= ~0x00000007;
436    cm_clkmode_dpll_ddr |= 0x00000004;
437    CM_WKUP_REG(CM_CLKMODE_DPLL_DDR) = cm_clkmode_dpll_ddr;
438    // Wait for DDR PLL to enter MN Bypass mode
439    while((CM_WKUP_REG(CM_IDLEST_DPLL_DDR) & 0x00000101) != 0x00000100);
440
441    // Set the DDR frequency to 400 MHz
442    cm_clksel_dpll_ddr = CM_WKUP_REG(CM_CLKSEL_DPLL_DDR);
443    cm_clksel_dpll_ddr &= ~0x0007FF7F;
444    cm_clksel_dpll_ddr |= 400 << 8;
445    cm_clksel_dpll_ddr |= 23;
446    CM_WKUP_REG(CM_CLKSEL_DPLL_DDR) = cm_clksel_dpll_ddr;
447    // Set M2 divider
448    cm_div_m2_dpll_ddr = CM_WKUP_REG(CM_DIV_M2_DPLL_DDR);
449    cm_div_m2_dpll_ddr &= ~0x0000001F;
450    cm_div_m2_dpll_ddr |= 1;
451    CM_WKUP_REG(CM_DIV_M2_DPLL_DDR) = cm_div_m2_dpll_ddr;
452
453    // Lock the DDR PLL
454    cm_clkmode_dpll_ddr = CM_WKUP_REG(CM_CLKMODE_DPLL_DDR);
455    cm_clkmode_dpll_ddr &= ~0x00000007;
456    cm_clkmode_dpll_ddr |= 0x00000007;
457    CM_WKUP_REG(CM_CLKMODE_DPLL_DDR) = cm_clkmode_dpll_ddr;
458    // Wait for DDR PLL to lock
459    while((CM_WKUP_REG(CM_IDLEST_DPLL_DDR) & 0x00000001) != 0x00000001);
460}
461
462void
463per_pll_init(void)
464{
465    uint32_t cm_clkmode_dpll_per;
466    uint32_t cm_clksel_dpll_per;
467    uint32_t cm_div_m2_dpll_per;
468
469    // Put Per PLL in MN Bypass mode
470    cm_clkmode_dpll_per = CM_WKUP_REG(CM_CLKMODE_DPLL_PER);
471    cm_clkmode_dpll_per &= ~0x00000007;
472    cm_clkmode_dpll_per |= 0x00000004;
473    CM_WKUP_REG(CM_CLKMODE_DPLL_PER) = cm_clkmode_dpll_per;
474    // Wait for Per PLL to enter MN Bypass mode
475    while((CM_WKUP_REG(CM_IDLEST_DPLL_PER) & 0x00000101) != 0x00000100);
476
477    // Configure the multiplier and divider
478    cm_clksel_dpll_per = CM_WKUP_REG(CM_CLKSEL_DPLL_PER);
479    cm_clksel_dpll_per &= ~0xFF0FFFFF;
480    cm_clksel_dpll_per |= CM_CLKSEL_DPLL_PER_DPLL_SD_DIV | CM_CLKSEL_DPLL_PER_DPLL_MULT |
481                          CM_CLKSEL_DPLL_PER_DPLL_DIV;
482    CM_WKUP_REG(CM_CLKSEL_DPLL_PER) = cm_clksel_dpll_per;
483    // Set M2 divider
484    cm_div_m2_dpll_per = CM_WKUP_REG(CM_DIV_M2_DPLL_PER);
485    cm_div_m2_dpll_per &= ~0x0000007F;
486    cm_div_m2_dpll_per |= 5;
487    CM_WKUP_REG(CM_DIV_M2_DPLL_PER) = cm_div_m2_dpll_per;
488
489    // Lock the Per PLL
490    cm_clkmode_dpll_per = CM_WKUP_REG(CM_CLKMODE_DPLL_PER);
491    cm_clkmode_dpll_per &= ~0x00000007;
492    cm_clkmode_dpll_per |= 0x00000007;
493    CM_WKUP_REG(CM_CLKMODE_DPLL_PER) = cm_clkmode_dpll_per;
494    // Wait for Per PLL to lock
495    while((CM_WKUP_REG(CM_IDLEST_DPLL_PER) & 0x00000001) != 0x00000001);
496}
497
498void
499pll_init(void)
500{
501    mpu_pll_init();
502    core_pll_init();
503    ddr_pll_init();
504    per_pll_init();
505}
506
507void
508ddr_init(void)
509{
510    uint32_t reg;
511
512    // Enable the control module:
513    CM_WKUP_REG(CM_WKUP_CONTROL_CLKCTRL) |= 2;
514
515    // Enable EMIF module
516    reg = CM_PER_REG(CM_PER_EMIF_CLKCTRL);
517    reg &= ~3;
518    reg |= 2;
519    CM_PER_REG(CM_PER_EMIF_CLKCTRL) = reg;
520    while((CM_PER_REG(CM_PER_L3_CLKSTCTRL) & 0x00000004) != 0x00000004);
521
522    // Configure VTP control
523    CNTL_MODULE_REG(VTP_CTRL) |= 0x00000040;
524    CNTL_MODULE_REG(VTP_CTRL) &= ~1;
525    CNTL_MODULE_REG(VTP_CTRL) |= 1;
526    // Wait for VTP control to be ready
527    while((CNTL_MODULE_REG(VTP_CTRL) & 0x00000020) != 0x00000020);
528
529    // Configure the DDR PHY CMDx/DATAx registers
530    DDR_PHY_REG(CMD0_REG_PHY_CTRL_SLAVE_RATIO_0) = 0x80;
531    DDR_PHY_REG(CMD0_REG_PHY_INVERT_CLKOUT_0) = 0;
532    DDR_PHY_REG(CMD1_REG_PHY_CTRL_SLAVE_RATIO_0) = 0x80;
533    DDR_PHY_REG(CMD1_REG_PHY_INVERT_CLKOUT_0) = 0;
534    DDR_PHY_REG(CMD2_REG_PHY_CTRL_SLAVE_RATIO_0) = 0x80;
535    DDR_PHY_REG(CMD2_REG_PHY_INVERT_CLKOUT_0) = 0;
536
537    DDR_PHY_REG(DATA0_REG_PHY_RD_DQS_SLAVE_RATIO_0) = 0x3A;
538    DDR_PHY_REG(DATA0_REG_PHY_WR_DQS_SLAVE_RATIO_0) = 0x45;
539    DDR_PHY_REG(DATA0_REG_PHY_WR_DATA_SLAVE_RATIO_0) = 0x7C;
540    DDR_PHY_REG(DATA0_REG_PHY_FIFO_WE_SLAVE_RATIO_0) = 0x96;
541
542    DDR_PHY_REG(DATA1_REG_PHY_RD_DQS_SLAVE_RATIO_0) = 0x3A;
543    DDR_PHY_REG(DATA1_REG_PHY_WR_DQS_SLAVE_RATIO_0) = 0x45;
544    DDR_PHY_REG(DATA1_REG_PHY_WR_DATA_SLAVE_RATIO_0) = 0x7C;
545    DDR_PHY_REG(DATA1_REG_PHY_FIFO_WE_SLAVE_RATIO_0) = 0x96;
546
547    CNTL_MODULE_REG(DDR_CMD0_IOCTRL) = 0x018B;
548    CNTL_MODULE_REG(DDR_CMD1_IOCTRL) = 0x018B;
549    CNTL_MODULE_REG(DDR_CMD2_IOCTRL) = 0x018B;
550    CNTL_MODULE_REG(DDR_DATA0_IOCTRL) = 0x018B;
551    CNTL_MODULE_REG(DDR_DATA1_IOCTRL) = 0x018B;
552
553    CNTL_MODULE_REG(DDR_IO_CTRL) &= ~0x10000000;
554
555    CNTL_MODULE_REG(DDR_CKE_CTRL) |= 0x00000001;
556
557    // Enable dynamic power down when no read is being performed and set read latency
558    // to CAS Latency + 2 - 1
559    EMIF0_REG(DDR_PHY_CTRL_1) = 0x00100007;
560    EMIF0_REG(DDR_PHY_CTRL_1_SHDW) = 0x00100007;
561
562    // Configure the AC timing characteristics
563    EMIF0_REG(SDRAM_TIM_1) = 0x0AAAD4DB;
564    EMIF0_REG(SDRAM_TIM_1_SHDW) = 0x0AAAD4DB;
565    EMIF0_REG(SDRAM_TIM_2) = 0x266B7FDA;
566    EMIF0_REG(SDRAM_TIM_2_SHDW) = 0x266B7FDA;
567    EMIF0_REG(SDRAM_TIM_3) = 0x501F867F;
568    EMIF0_REG(SDRAM_TIM_3_SHDW) = 0x501F867F;
569
570    // Set the refresh rate, 400,000,000 * 7.8 * 10^-6 = 3120 = 0x0C30
571    EMIF0_REG(SDRAM_REF_CTRL) = 0x00000C30;
572    // set the referesh rate shadow register to the same value as previous
573    EMIF0_REG(SDRAM_REF_CTRL_SHDW) = 0x00000C30;
574
575    // Configure the ZQ Calibration
576    EMIF0_REG(ZQ_CONFIG) = 0x50074BE4;
577
578    // Configure the SDRAM characteristics
579    reg |= SDRAM_CONFIG_REG_SDRAM_TYPE_DDR3 | SDRAM_CONFIG_REG_IBANK_POS_0 |
580           SDRAM_CONFIG_REG_DDR_TERM_DDR3_RZQ_4 | SDRAM_CONFIG_REG_DDR2_DDQS_DIFF_DQS |
581           SDRAM_CONFIG_REG_DYN_ODT_RZQ_2 | SDRAM_CONFIG_REG_DDR_DISABLE_DLL_ENABLE |
582           SDRAM_CONFIG_REG_SDRAM_DRIVE_RZQ_6 | SDRAM_CONFIG_REG_CAS_WR_LATENCY_5 |
583           SDRAM_CONFIG_REG_NARROW_MODE_16BIT | SDRAM_CONFIG_REG_CAS_LATENCY_6 |
584           SDRAM_CONFIG_REG_ROWSIZE_15BIT | SDRAM_CONFIG_REG_IBANK_8 |
585           SDRAM_CONFIG_REG_EBANK_1 | SDRAM_CONFIG_REG_PAGESIZE_1024_WORD;
586    EMIF0_REG(SDRAM_CONFIG) = reg;
587    CNTL_MODULE_REG(CONTROL_EMIF_SDRAM_CONFIG) = reg;
588
589    // Set the external bank position to 0
590    EMIF0_REG(SDRAM_CONFIG_2) |= SDRAM_CONFIG_2_REG_EBANK_POS_0;
591}
Note: See TracBrowser for help on using the repository browser.