x86: quark: Implement mrc cache
authorBin Meng <bmeng.cn@gmail.com>
Mon, 12 Oct 2015 08:30:42 +0000 (01:30 -0700)
committerSimon Glass <sjg@chromium.org>
Wed, 21 Oct 2015 13:46:27 +0000 (07:46 -0600)
Using existing mrccache library to implement mrc cache support
for Intel Quark.

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

index 1b89376..40c830a 100644 (file)
@@ -7,6 +7,8 @@
 #include <common.h>
 #include <errno.h>
 #include <fdtdec.h>
+#include <malloc.h>
+#include <asm/mrccache.h>
 #include <asm/mtrr.h>
 #include <asm/post.h>
 #include <asm/arch/mrc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static __maybe_unused int prepare_mrc_cache(struct mrc_params *mrc_params)
+{
+       struct mrc_data_container *cache;
+       struct mrc_region entry;
+       int ret;
+
+       ret = mrccache_get_region(NULL, &entry);
+       if (ret)
+               return ret;
+
+       cache = mrccache_find_current(&entry);
+       if (!cache)
+               return -ENOENT;
+
+       debug("%s: mrc cache at %p, size %x checksum %04x\n", __func__,
+             cache->data, cache->data_size, cache->checksum);
+
+       /* copy mrc cache to the mrc_params */
+       memcpy(&mrc_params->timings, cache->data, cache->data_size);
+
+       return 0;
+}
+
 static int mrc_configure_params(struct mrc_params *mrc_params)
 {
        const void *blob = gd->fdt_blob;
@@ -27,14 +52,15 @@ static int mrc_configure_params(struct mrc_params *mrc_params)
                return -EINVAL;
        }
 
-       /*
-        * TODO:
-        *
-        * We need support fast boot (MRC cache) in the future.
-        *
-        * Set boot mode to cold boot for now
-        */
+#ifdef CONFIG_ENABLE_MRC_CACHE
+       mrc_params->boot_mode = prepare_mrc_cache(mrc_params);
+       if (mrc_params->boot_mode)
+               mrc_params->boot_mode = BM_COLD;
+       else
+               mrc_params->boot_mode = BM_FAST;
+#else
        mrc_params->boot_mode = BM_COLD;
+#endif
 
        /*
         * TODO:
@@ -98,6 +124,9 @@ static int mrc_configure_params(struct mrc_params *mrc_params)
 int dram_init(void)
 {
        struct mrc_params mrc_params;
+#ifdef CONFIG_ENABLE_MRC_CACHE
+       char *cache;
+#endif
        int ret;
 
        memset(&mrc_params, 0, sizeof(struct mrc_params));
@@ -121,6 +150,15 @@ int dram_init(void)
                       (~(gd->ram_size - 1)) | MTRR_PHYS_MASK_VALID);
        enable_caches();
 
+#ifdef CONFIG_ENABLE_MRC_CACHE
+       cache = malloc(sizeof(struct mrc_timings));
+       if (cache) {
+               memcpy(cache, &mrc_params.timings, sizeof(struct mrc_timings));
+               gd->arch.mrc_output = cache;
+               gd->arch.mrc_output_len = sizeof(struct mrc_timings);
+       }
+#endif
+
        return 0;
 }
 
index 77d644a..f737e19 100644 (file)
@@ -8,6 +8,7 @@
 #include <mmc.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/mrccache.h>
 #include <asm/mtrr.h>
 #include <asm/pci.h>
 #include <asm/post.h>
@@ -368,6 +369,15 @@ void cpu_irq_init(void)
 
 int arch_misc_init(void)
 {
+#ifdef CONFIG_ENABLE_MRC_CACHE
+       /*
+        * We intend not to check any return value here, as even MRC cache
+        * is not saved successfully, it is not a severe error that will
+        * prevent system from continuing to boot.
+        */
+       mrccache_save();
+#endif
+
        return pirq_init();
 }
 
@@ -390,3 +400,12 @@ void board_final_cleanup(void)
 
        return;
 }
+
+int reserve_arch(void)
+{
+#ifdef CONFIG_ENABLE_MRC_CACHE
+       return mrccache_reserve();
+#else
+       return 0;
+#endif
+}