x86: quark: Configure MTRR to enable cache
authorBin Meng <bmeng.cn@gmail.com>
Mon, 14 Sep 2015 07:07:41 +0000 (00:07 -0700)
committerSimon Glass <sjg@chromium.org>
Thu, 17 Sep 2015 01:53:53 +0000 (19:53 -0600)
Quark SoC does not support MSR MTRRs. Fixed and variable range MTRRs
are accessed indirectly via the message port and not the traditional
MSR mechanism. Only UC, WT and WB cache types are supported.

We configure all the fixed range MTRRs with common values (VGA RAM
as UC, others as WB) and 3 variable range MTRRs for ROM/eSRAM/RAM as
WB, which significantly improves the boot time performance.

With this commit, it takes only 2 seconds for U-Boot to boot to shell
on Intel Galileo board. Previously it took about 6 seconds.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
arch/x86/cpu/quark/dram.c
arch/x86/cpu/quark/quark.c
arch/x86/include/asm/arch-quark/quark.h

index 9cac846..1b89376 100644 (file)
@@ -7,8 +7,10 @@
 #include <common.h>
 #include <errno.h>
 #include <fdtdec.h>
+#include <asm/mtrr.h>
 #include <asm/post.h>
 #include <asm/arch/mrc.h>
+#include <asm/arch/msg_port.h>
 #include <asm/arch/quark.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -111,6 +113,14 @@ int dram_init(void)
        gd->ram_size = mrc_params.mem_size;
        post_code(POST_DRAM);
 
+       /* variable range MTRR#2: RAM area */
+       disable_caches();
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYBASE(MTRR_VAR_RAM),
+                      0 | MTRR_TYPE_WRBACK);
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYMASK(MTRR_VAR_RAM),
+                      (~(gd->ram_size - 1)) | MTRR_PHYS_MASK_VALID);
+       enable_caches();
+
        return 0;
 }
 
index 8b78a86..77d644a 100644 (file)
@@ -8,6 +8,7 @@
 #include <mmc.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/mtrr.h>
 #include <asm/pci.h>
 #include <asm/post.h>
 #include <asm/processor.h>
@@ -34,6 +35,55 @@ static void unprotect_spi_flash(void)
        qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, 0xd8, bc);
 }
 
+static void quark_setup_mtrr(void)
+{
+       u32 base, mask;
+       int i;
+
+       disable_caches();
+
+       /* mark the VGA RAM area as uncacheable */
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_16K_A0000,
+                      MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE));
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_16K_B0000,
+                      MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE));
+
+       /* mark other fixed range areas as cacheable */
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_64K_00000,
+                      MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_64K_40000,
+                      MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_16K_80000,
+                      MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_16K_90000,
+                      MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+       for (i = MTRR_FIX_4K_C0000; i <= MTRR_FIX_4K_FC000; i++)
+               msg_port_write(MSG_PORT_HOST_BRIDGE, i,
+                              MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+
+       /* variable range MTRR#0: ROM area */
+       mask = ~(CONFIG_SYS_MONITOR_LEN - 1);
+       base = CONFIG_SYS_TEXT_BASE & mask;
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYBASE(MTRR_VAR_ROM),
+                      base | MTRR_TYPE_WRBACK);
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYMASK(MTRR_VAR_ROM),
+                      mask | MTRR_PHYS_MASK_VALID);
+
+       /* variable range MTRR#1: eSRAM area */
+       mask = ~(ESRAM_SIZE - 1);
+       base = CONFIG_ESRAM_BASE & mask;
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYBASE(MTRR_VAR_ESRAM),
+                      base | MTRR_TYPE_WRBACK);
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYMASK(MTRR_VAR_ESRAM),
+                      mask | MTRR_PHYS_MASK_VALID);
+
+       /* enable both variable and fixed range MTRRs */
+       msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_DEF_TYPE,
+                      MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN);
+
+       enable_caches();
+}
+
 static void quark_setup_bars(void)
 {
        /* GPIO - D31:F0:R44h */
@@ -191,6 +241,13 @@ int arch_cpu_init(void)
                return ret;
 
        /*
+        * Quark SoC does not support MSR MTRRs. Fixed and variable range MTRRs
+        * are accessed indirectly via the message port and not the traditional
+        * MSR mechanism. Only UC, WT and WB cache types are supported.
+        */
+       quark_setup_mtrr();
+
+       /*
         * Quark SoC has some non-standard BARs (excluding PCI standard BARs)
         * which need be initialized with suggested values
         */
index f6009f6..7a864c7 100644 (file)
 /* Extended Configuration Space */
 #define HEC_REG                        0x09
 
+/* MTRR Registers */
+#define MTRR_CAP               0x40
+#define MTRR_DEF_TYPE          0x41
+
+#define MTRR_FIX_64K_00000     0x42
+#define MTRR_FIX_64K_40000     0x43
+#define MTRR_FIX_16K_80000     0x44
+#define MTRR_FIX_16K_90000     0x45
+#define MTRR_FIX_16K_A0000     0x46
+#define MTRR_FIX_16K_B0000     0x47
+#define MTRR_FIX_4K_C0000      0x48
+#define MTRR_FIX_4K_C4000      0x49
+#define MTRR_FIX_4K_C8000      0x4a
+#define MTRR_FIX_4K_CC000      0x4b
+#define MTRR_FIX_4K_D0000      0x4c
+#define MTRR_FIX_4K_D4000      0x4d
+#define MTRR_FIX_4K_D8000      0x4e
+#define MTRR_FIX_4K_DC000      0x4f
+#define MTRR_FIX_4K_E0000      0x50
+#define MTRR_FIX_4K_E4000      0x51
+#define MTRR_FIX_4K_E8000      0x52
+#define MTRR_FIX_4K_EC000      0x53
+#define MTRR_FIX_4K_F0000      0x54
+#define MTRR_FIX_4K_F4000      0x55
+#define MTRR_FIX_4K_F8000      0x56
+#define MTRR_FIX_4K_FC000      0x57
+
+#define MTRR_SMRR_PHYBASE      0x58
+#define MTRR_SMRR_PHYMASK      0x59
+
+#define MTRR_VAR_PHYBASE(n)    (0x5a + 2 * (n))
+#define MTRR_VAR_PHYMASK(n)    (0x5b + 2 * (n))
+
+#ifndef __ASSEMBLY__
+
+/* variable range MTRR usage */
+enum {
+       MTRR_VAR_ROM,
+       MTRR_VAR_ESRAM,
+       MTRR_VAR_RAM
+};
+
+#endif /* __ASSEMBLY__ */
+
 /* Port 0x04: Remote Management Unit Message Port Registers */
 
 /* ACPI PBLK Base Address Register */