58519bd8ff77f0f7edb030e9bfbfccdd7b6eb226
[gram.git] / libgram / src / dfii.c
1 #include <stdint.h>
2
3 #include "hw_regs.h"
4 #include <gram.h>
5 #include "dfii.h"
6 #include "helpers.h"
7
8 static void dfii_setcontrol(const struct gramCtx *ctx, uint8_t val) {
9 #ifdef GRAM_RW_FUNC
10 gram_write(ctx, (void*)&(ctx->core->control), val);
11 #else
12 ctx->core->control = val;
13 #endif
14 }
15
16 void dfii_setsw(const struct gramCtx *ctx, bool software_control) {
17 if (software_control) {
18 dfii_setcontrol(ctx, DFII_CONTROL_CKE|DFII_CONTROL_ODT);
19 } else {
20 dfii_setcontrol(ctx, DFII_CONTROL_SEL|DFII_CONTROL_RESET);
21 }
22 }
23
24 void dfii_set_p0_address(const struct gramCtx *ctx, uint32_t val) {
25 #ifdef GRAM_RW_FUNC
26 gram_write(ctx, (void*)&(ctx->core->phases[0].address), val);
27 #else
28 ctx->core->phases[0].address = val;
29 #endif
30 }
31
32 void dfii_set_p0_baddress(const struct gramCtx *ctx, uint32_t val) {
33 #ifdef GRAM_RW_FUNC
34 gram_write(ctx, (void*)&(ctx->core->phases[0].baddress), val);
35 #else
36 ctx->core->phases[0].baddress = val;
37 #endif
38 }
39
40 void dfii_p0_command(const struct gramCtx *ctx, uint32_t cmd) {
41 #ifdef GRAM_RW_FUNC
42 gram_write(ctx, (void*)&(ctx->core->phases[0].command), cmd);
43 gram_write(ctx, (void*)&(ctx->core->phases[0].command_issue), 1);
44 #else
45 ctx->core->phases[0].command = cmd;
46 ctx->core->phases[0].command_issue = 1;
47 #endif
48 }
49
50 /* Set MRx register */
51 static void dfii_set_mr(const struct gramCtx *ctx, uint8_t mr, uint16_t val) {
52 dfii_set_p0_address(ctx, val);
53 dfii_set_p0_baddress(ctx, mr);
54 dfii_p0_command(ctx, DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
55 }
56
57 #define MR0_DLL_RESET (1 << 8)
58 void dfii_initseq(const struct gramCtx *ctx, const struct gramProfile *profile) {
59 /* Release reset */
60 dfii_set_p0_address(ctx, 0x0);
61 dfii_set_p0_baddress(ctx, 0);
62 dfii_setcontrol(ctx, DFII_CONTROL_ODT);
63 cdelay(50000);
64
65 /* Bring CKE high */
66 dfii_set_p0_address(ctx, 0x0);
67 dfii_set_p0_baddress(ctx, 0);
68 dfii_setcontrol(ctx, DFII_CONTROL_CKE|DFII_CONTROL_ODT);
69 cdelay(10000);
70
71 /* Load Mode Register 2, CWL=5 */
72 dfii_set_mr(ctx, 2, profile->mode_registers[2]);
73
74 /* Load Mode Register 3 */
75 dfii_set_mr(ctx, 3, profile->mode_registers[3]);
76
77 /* Load Mode Register 1 */
78 dfii_set_mr(ctx, 1, profile->mode_registers[1]);
79
80 /* Load Mode Register 0, CL=6, BL=8 */
81 dfii_set_mr(ctx, 0, profile->mode_registers[0]);
82 if (profile->mode_registers[0] & MR0_DLL_RESET) {
83 cdelay(100);
84 dfii_set_mr(ctx, 0, profile->mode_registers[0] & ~MR0_DLL_RESET);
85 }
86 cdelay(600);
87
88 /* ZQ Calibration */
89 dfii_set_p0_address(ctx, 0x400);
90 dfii_set_p0_baddress(ctx, 0);
91 dfii_p0_command(ctx, DFII_COMMAND_WE|DFII_COMMAND_CS);
92 cdelay(600);
93 }