x86: quark: Configure MTRR to enable cache

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>
This commit is contained in:
Bin Meng 2015-09-14 00:07:41 -07:00 committed by Simon Glass
parent 0993fc026b
commit c6d4705f41
3 changed files with 111 additions and 0 deletions

View 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;
}

View 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 */
@ -190,6 +240,13 @@ int arch_cpu_init(void)
if (ret)
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

View File

@ -37,6 +37,50 @@
/* 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 */