-OBJS := src/init.o src/memtest.o
+OBJS := src/init.o src/memtest.o src/dfii.o
TRIPLE := riscv64-unknown-elf
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 */
--- /dev/null
+#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);
+}
#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)
#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 */
#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 */
#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;
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
#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
#include <gram.h>
-int gram_memtest(void) {
+int gram_memtest(struct gramCtx *ctx) {
return 0;
}
+++ /dev/null
-#!/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))