diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c
index 9cac846c693114a9e303234b7979dd7ffe1c7223..1b89376387977fd3b9b4d9acb1c829b5dca16c0b 100644
--- a/arch/x86/cpu/quark/dram.c
+++ b/arch/x86/cpu/quark/dram.c
@@ -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;
 }
 
diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c
index 8b78a867efe3cf8b06e4bc5bf05188cc5a3cad31..77d644a4914937172ffd6645c603386ab5a4afc1 100644
--- a/arch/x86/cpu/quark/quark.c
+++ b/arch/x86/cpu/quark/quark.c
@@ -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
diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h
index f6009f67d82e5831e2d40d42139b1a36c328d87c..7a864c7c5308ddb8ca0b7627b3cfa7ca2c5bb804 100644
--- a/arch/x86/include/asm/arch-quark/quark.h
+++ b/arch/x86/include/asm/arch-quark/quark.h
@@ -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 */