speed up QSPI by putting it into way-faster mode
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 11 Apr 2022 13:19:21 +0000 (14:19 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 11 Apr 2022 13:19:21 +0000 (14:19 +0100)
coldboot/coldboot.c

index 6ed7b34544a783b23391b8088731f56d5c401889..782049b672dd608b565f743b6493887b527b9c0e 100644 (file)
@@ -54,7 +54,7 @@ void memcpy(void *dest, void *src, size_t n) {
     char *dest_char = (char *)dest;
     for (i=0; i<n; i++) {
 #if 1
-        if ((i % 1024) == 1023) {
+        if ((i % 4096) == 0) {
             puts("memcpy ");
             uart_writeuint32(i);
             puts("\r\n");
@@ -68,6 +68,24 @@ void isr(void) {
 
 }
 
+// WARNING
+// KESTREL SPECIFIC
+#define TERCEL_SPI_REG_SYS_PHY_CFG1     0x10
+#define TERCEL_SPI_REG_SYS_FLASH_CFG5       0x24
+#define TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK   0xff
+#define TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT  0
+#define TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK   0x1
+#define TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT  0
+static inline uint32_t read_tercel_register(uint8_t reg)
+{
+       return readl((unsigned long)(SPI_FCTRL_BASE+reg));
+}
+
+static inline void write_tercel_register(uint8_t reg, uint32_t value)
+{
+       writel(value, (unsigned long)(SPI_FCTRL_BASE+reg));
+}
+
 // TODO: need to use this
 // https://gitlab.raptorengineering.com/kestrel-collaboration/kestrel-litex/litex/-/blob/master/litex/soc/software/bios/boot.c#L575
 static bool fl_read(void *dst, uint32_t offset, uint32_t size)
@@ -84,6 +102,22 @@ static unsigned long copy_flash(unsigned int offset)
     unsigned int i, poff, size, off;
     void *addr;
 
+    // WARNING
+    // KESTREL SPECIFIC
+    // Set SPI clock cycle divider to 1
+    uint32_t dword;
+    dword = read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1);
+    dword &= ~(TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK <<
+               TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT);
+    dword |= ((1 & TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK) <<
+                   TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT);
+    write_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1, dword);
+    // Enable read merging
+    dword = read_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG5);
+    dword |= (TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK <<
+              TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT);
+    write_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG5, dword);
+
     puts("Trying flash...\r\n");
     if (!fl_read(&ehdr, offset, sizeof(ehdr)))
         return -1ul;