Refine libgram architecture
authorJean THOMAS <git0@pub.jeanthomas.me>
Tue, 9 Jun 2020 12:52:25 +0000 (14:52 +0200)
committerJean THOMAS <git0@pub.jeanthomas.me>
Tue, 9 Jun 2020 12:52:25 +0000 (14:52 +0200)
libgram/Makefile
libgram/include/gram.h
libgram/src/dfii.c [new file with mode: 0644]
libgram/src/dfii.h
libgram/src/helpers.h
libgram/src/hw_regs.h
libgram/src/init.c
libgram/src/memtest.c
libgram/tools/csv2c [deleted file]

index cf7ee3f1e9694f415fe43d19814a8ebd336174a3..530e83a006be57bae1887ca9f0a9d0819488b175 100644 (file)
@@ -1,4 +1,4 @@
-OBJS := src/init.o src/memtest.o
+OBJS := src/init.o src/memtest.o src/dfii.o
 
 TRIPLE := riscv64-unknown-elf
 
index a16f5b8cd9c90f8e74d29668a0bd56f107911d48..7440c576eb7d1fc96676971d544f87eb02f31738 100644 (file)
@@ -5,10 +5,17 @@ enum GramError {
        GRAM_ERR_NONE = 0,
        GRAM_ERR_UNDOCUMENTED,
        GRAM_ERR_MEMTEST,
-       
 };
 
-int gram_init(void);
-int gram_memtest(void);
+struct gramCoreRegs;
+struct gramPHYRegs;
+struct gramCtx {
+       volatile void *ddr_base;
+       volatile struct gramCoreRegs *core;
+       volatile struct gramPHYRegs *phy;
+};
+
+int gram_init(struct gramCtx *ctx, void *ddr_base, void *core_base, void *phy_base);
+int gram_memtest(struct gramCtx *ctx);
 
 #endif /* GRAM_H */
diff --git a/libgram/src/dfii.c b/libgram/src/dfii.c
new file mode 100644 (file)
index 0000000..b9367ba
--- /dev/null
@@ -0,0 +1,74 @@
+#include <stdint.h>
+
+#include "hw_regs.h"
+#include <gram.h>
+#include "dfii.h"
+#include "helpers.h"
+
+static void dfii_setcontrol(struct gramCtx *ctx, uint8_t val) {
+       ctx->core->control = val;
+}
+
+void dfii_setsw(struct gramCtx *ctx, bool software_control) {
+       if (software_control) {
+               dfii_setcontrol(ctx, DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N);
+       } else {
+               dfii_setcontrol(ctx, DFII_CONTROL_SEL);
+       }
+}
+
+static void dfii_set_p0_address(struct gramCtx *ctx, uint32_t val) {
+       ctx->core->phases[0].address = val;
+}
+
+static void dfii_set_p0_baddress(struct gramCtx *ctx, uint32_t val) {
+       ctx->core->phases[0].baddress = val;
+}
+
+static void dfii_p0_command(struct gramCtx *ctx, uint32_t cmd) {
+       ctx->core->phases[0].command = cmd;
+       ctx->core->phases[0].command_issue = 1;
+}
+
+/* TODO: those values are hardcoded for ECPIX-5's RAM */
+/* Should add the capacity to generate MRx from RAM spec */
+void dfii_initseq(struct gramCtx *ctx) {
+       /* Release reset */
+       dfii_set_p0_address(ctx, 0x0);
+       dfii_set_p0_baddress(ctx, 0);
+       dfii_setcontrol(ctx, DFII_CONTROL_ODT|DFII_CONTROL_RESET_N);
+       cdelay(50000);
+
+       /* Bring CKE high */
+       dfii_set_p0_address(ctx, 0x0);
+       dfii_set_p0_baddress(ctx, 0);
+       dfii_setcontrol(ctx, DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N);
+       cdelay(10000);
+
+       /* Load Mode Register 2, CWL=5 */
+       dfii_set_p0_address(ctx, 0x200);
+       dfii_set_p0_baddress(ctx, 2);
+       dfii_p0_command(ctx, DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
+
+       /* Load Mode Register 3 */
+       dfii_set_p0_address(ctx, 0x0);
+       dfii_set_p0_baddress(ctx, 3);
+       dfii_p0_command(ctx, DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
+
+       /* Load Mode Register 1 */
+       dfii_set_p0_address(ctx, 0x6);
+       dfii_set_p0_baddress(ctx, 1);
+       dfii_p0_command(ctx, DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
+
+       /* Load Mode Register 0, CL=6, BL=8 */
+       dfii_set_p0_address(ctx, 0x320);
+       dfii_set_p0_baddress(ctx, 0);
+       dfii_p0_command(ctx, DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
+       cdelay(200);
+
+       /* ZQ Calibration */
+       dfii_set_p0_address(ctx, 0x400);
+       dfii_set_p0_baddress(ctx, 0);
+       dfii_p0_command(ctx, DFII_COMMAND_WE|DFII_COMMAND_CS);
+       cdelay(200);
+}
index f4d3e2347e417cd88f30a89c18db73b45a731817..ff0d9128a87618acfb1ff8f3701194cc3ac87e7f 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef DFII_H
 #define DFII_H
 
+#include <stdbool.h>
+
 #define DFII_CONTROL_SEL (1 << 1)
 #define DFII_CONTROL_CKE (1 << 2)
 #define DFII_CONTROL_ODT (1 << 3)
@@ -11,6 +13,8 @@
 #define DFII_COMMAND_CAS (1 << 3)
 #define DFII_COMMAND_RAS (1 << 4)
 #define DFII_COMMAND_WRDATA (1 << 5)
-#define DFII_COMMAND_WRDATA (1 << 6)
+
+void dfii_setsw(struct gramCtx *ctx, bool software_control);
+void dfii_initseq(struct gramCtx *ctx);
 
 #endif /* DFII_H */
index 3418f72f89e6f61767ca9833c92a774b46636dc7..e0f6b0fa067c99f0ae64090a4c38fff0db75a760 100644 (file)
@@ -1,6 +1,11 @@
 #ifndef HELPERS_H
 #define HELPERS_H
 
+__attribute__((unused)) static inline void cdelay(int i) {
+       while(i > 0) {
+               __asm__ volatile("nop");
+               i--;
+       }
+}
 
-
-#endif HELPERS_H
+#endif /* HELPERS_H */
index 93ef450226c48ff3a008b3a9e947c57ed3732256..6adb338b6d6b125549ac2d5f7dbef6ad851b53ff 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef HW_REGS_H
 #define HW_REGS_H
 
-struct ECP5PHY {
+struct gramPHYRegs {
        uint32_t dly_sel;
        uint32_t rdly_dq_rst;
        uint32_t rdly_dq_inc;
@@ -20,9 +20,9 @@ struct DFII_Phase {
        uint32_t rddata;
 } __attribute__((packed));
 
-struct DFII {
+struct gramCoreRegs {
        uint32_t control;
-
+       struct DFII_Phase phases[4];
 } __attribute__((packed));
 
 #endif /* HW_REGS_H */
\ No newline at end of file
index 4c517f4ddc5c47ec6f37c4d9db9b9853d00cbd77..839079f24f4545698b48c2567aa768aebd805b02 100644 (file)
@@ -1,40 +1,12 @@
 #include <gram.h>
+#include "dfii.h"
 
-int gram_init(void) {
-#ifdef CSR_DDRCTRL_BASE
-       ddrctrl_init_done_write(0);
-       ddrctrl_init_error_write(0);
-#endif
+int gram_init(struct gramCtx *ctx, void *ddr_base, void *core_base, void *phy_base) {
+       ctx->ddr_base = ddr_base;
+       ctx->core = core_base;
+       ctx->phy = phy_base;
 
-       sdrsw();
-       init_sequence();
-
-#ifdef CSR_DDRPHY_BASE
-#ifdef DDRPHY_CMD_DELAY
-       ddrphy_cdly(DDRPHY_CMD_DELAY);
-#endif
-#if CSR_DDRPHY_EN_VTC_ADDR
-       ddrphy_en_vtc_write(0);
-#endif
-#if defined(SDRAM_PHY_WRITE_LEVELING_CAPABLE) || defined(SDRAM_PHY_READ_LEVELING_CAPABLE)
-       sdrlevel();
-#endif
-#if CSR_DDRPHY_EN_VTC_ADDR
-       ddrphy_en_vtc_write(1);
-#endif
-#endif
-       sdrhw();
-
-       if(!memtest()) {
-#ifdef CSR_DDRCTRL_BASE
-               ddrctrl_init_done_write(1);
-               ddrctrl_init_error_write(1);
-#endif
-               return GRAM_ERR_MEMTEST;
-       }
-#ifdef CSR_DDRCTRL_BASE
-       ddrctrl_init_done_write(1);
-#endif
-
-       return GRAM_ERR_NONE;
-}
+       dfii_setsw(ctx, true);
+       dfii_initseq(ctx);
+       dfii_setsw(ctx, false);
+}
\ No newline at end of file
index 69da9b1876fe6635f0a87c490ae8042449db83b0..55a5fc04f5c8b0cf1fe1d7381423fac130966619 100644 (file)
@@ -1,5 +1,5 @@
 #include <gram.h>
 
-int gram_memtest(void) {
+int gram_memtest(struct gramCtx *ctx) {
        return 0;
 }
diff --git a/libgram/tools/csv2c b/libgram/tools/csv2c
deleted file mode 100755 (executable)
index d9c16f8..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env python3
-import csv
-import argparse
-
-def generateHeader(input_file, output_file):
-       constant = output_file.replace('.', '_').upper()
-       header = "#ifndef {}\n#define {}\n".format(constant, constant)
-
-       with open('test.csv', newline='\n') as csvfile:
-               csrreader = csv.reader(filter(lambda row: row[0]!='#', csvfile), delimiter=',')
-               for row in csrreader:
-                       header += "volatile uint32_t *{} = {};\n".format(row[0].strip(), row[1].strip())
-
-       header += "#endif /* {} */\n".format(constant)
-
-       return header
-
-if __name__ == "__main__":
-       parser = argparse.ArgumentParser()
-       parser.add_argument("in_csv", help="input csv file")
-       parser.add_argument("out_h", help="output header file")
-       args = parser.parse_args()
-
-       print(generateHeader(args.in_csv, args.out_h))