Home | History | Annotate | Download | only in Pei
      1 /************************************************************************
      2  *
      3  * Copyright (c) 2013-2015 Intel Corporation.
      4  *
      5 * This program and the accompanying materials
      6 * are licensed and made available under the terms and conditions of the BSD License
      7 * which accompanies this distribution.  The full text of the license may be found at
      8 * http://opensource.org/licenses/bsd-license.php
      9 *
     10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12  *
     13  ************************************************************************/
     14 
     15 #include "mrc.h"
     16 #include "memory_options.h"
     17 
     18 #include "meminit_utils.h"
     19 #include "prememinit.h"
     20 #include "io.h"
     21 
     22 // Read character from serial console
     23 uint8_t mgetc(void);
     24 
     25 extern uint32_t DpfPrintMask;
     26 
     27 // Adjust configuration parameters before initialisation
     28 // sequence.
     29 void PreMemInit(
     30     MRCParams_t *mrc_params)
     31 {
     32   const DRAMParams_t *dram_params;
     33 
     34   uint8_t dram_width;
     35   uint32_t dram_cfg_index;
     36   uint32_t channel_i;
     37 
     38   ENTERFN();
     39 
     40 #ifdef MRC_SV
     41   {
     42     uint8_t ch;
     43 
     44     myloop:
     45 
     46     DPF(D_INFO, "- c - continue\n");
     47     DPF(D_INFO, "- f - boot mode [%d]\n", mrc_params->boot_mode);
     48     DPF(D_INFO, "- r - rank enable [%d]\n", mrc_params->rank_enables);
     49     DPF(D_INFO, "- e - ecc switch [%d]\n", mrc_params->ecc_enables);
     50     DPF(D_INFO, "- b - scrambling switch [%d]\n", mrc_params->scrambling_enables);
     51     DPF(D_INFO, "- a - adr mode [%d]\n", mrc_params->address_mode);
     52     DPF(D_INFO, "- m - menu after mrc [%d]\n", mrc_params->menu_after_mrc);
     53     DPF(D_INFO, "- t - tune to rcvn [%d]\n", mrc_params->tune_rcvn);
     54     DPF(D_INFO, "- o - odt switch [%d]\n", mrc_params->rd_odt_value);
     55     DPF(D_INFO, "- d - dram density [%d]\n", mrc_params->params.DENSITY);
     56     DPF(D_INFO, "- p - power down disable [%d]\n", mrc_params->power_down_disable);
     57     DPF(D_INFO, "- l - log switch 0x%x\n", DpfPrintMask);
     58     ch = mgetc();
     59 
     60     switch (ch)
     61     {
     62     case 'f':
     63       mrc_params->boot_mode >>= 1;
     64       if(mrc_params->boot_mode == bmUnknown)
     65       {
     66          mrc_params->boot_mode = bmWarm;
     67       }
     68       DPF(D_INFO, "Boot mode %d\n", mrc_params->boot_mode);
     69       break;
     70 
     71     case 'p':
     72       mrc_params->power_down_disable ^= 1;
     73       DPF(D_INFO, "Power down disable %d\n", mrc_params->power_down_disable);
     74       break;
     75 
     76     case 'r':
     77       mrc_params->rank_enables ^= 2;
     78       DPF(D_INFO, "Rank enable %d\n", mrc_params->rank_enables);
     79       break;
     80 
     81     case 'e':
     82       mrc_params->ecc_enables ^= 1;
     83       DPF(D_INFO, "Ecc enable %d\n", mrc_params->ecc_enables);
     84       break;
     85 
     86     case 'b':
     87       mrc_params->scrambling_enables ^= 1;
     88       DPF(D_INFO, "Scrambler enable %d\n", mrc_params->scrambling_enables);
     89       break;
     90 
     91     case 'a':
     92       mrc_params->address_mode = (mrc_params->address_mode + 1) % 3;
     93       DPF(D_INFO, "Adr mode %d\n", mrc_params->address_mode);
     94       break;
     95 
     96     case 'm':
     97        mrc_params->menu_after_mrc ^= 1;
     98       DPF(D_INFO, "Menu after mrc %d\n", mrc_params->menu_after_mrc);
     99       break;
    100 
    101     case 't':
    102       mrc_params->tune_rcvn ^= 1;
    103       DPF(D_INFO, "Tune to rcvn %d\n", mrc_params->tune_rcvn);
    104       break;
    105 
    106     case 'o':
    107       mrc_params->rd_odt_value = (mrc_params->rd_odt_value + 1) % 4;
    108       DPF(D_INFO, "Rd_odt_value %d\n", mrc_params->rd_odt_value);
    109       break;
    110 
    111     case 'd':
    112       mrc_params->params.DENSITY = (mrc_params->params.DENSITY + 1) % 4;
    113       DPF(D_INFO, "Dram density %d\n", mrc_params->params.DENSITY);
    114       break;
    115 
    116     case 'l':
    117       DpfPrintMask ^= 0x30;
    118       DPF(D_INFO, "Log mask %x\n", DpfPrintMask);
    119       break;
    120 
    121     default:
    122       break;
    123     }
    124 
    125     if (ch != 'c')
    126       goto myloop;
    127 
    128   }
    129 #endif
    130 
    131   // initially expect success
    132   mrc_params->status = MRC_SUCCESS;
    133 
    134   // todo!!! Setup board layout (must be reviewed as is selecting static timings)
    135   // 0 == R0 (DDR3 x16), 1 == R1 (DDR3 x16), 2 == DV (DDR3 x8), 3 == SV (DDR3 x8)
    136   if (mrc_params->dram_width == x8)
    137   {
    138     mrc_params->board_id = 2;  // select x8 layout
    139   }
    140   else
    141   {
    142     mrc_params->board_id = 0;  // select x16 layout
    143   }
    144 
    145   // initially no memory
    146   mrc_params->mem_size = 0;
    147   channel_i = 0;
    148 
    149   // begin of channel settings
    150   dram_width = mrc_params->dram_width;
    151   dram_params = &mrc_params->params;
    152   dram_cfg_index = 0;
    153 
    154   // Determine Column & Row Bits:
    155   // Column:
    156   // 11 for 8Gbx8, else 10
    157   mrc_params->column_bits[channel_i] = ((dram_params[dram_cfg_index].DENSITY == 4) && (dram_width == x8)) ? (11) : (10);
    158 
    159   // Row:
    160   // 512Mbx16=12 512Mbx8=13
    161   //   1Gbx16=13   1Gbx8=14
    162   //   2Gbx16=14   2Gbx8=15
    163   //   4Gbx16=15   4Gbx8=16
    164   //   8Gbx16=16   8Gbx8=16
    165   mrc_params->row_bits[channel_i] = 12 + (dram_params[dram_cfg_index].DENSITY)
    166       + (((dram_params[dram_cfg_index].DENSITY < 4) && (dram_width == x8)) ? (1) : (0));
    167 
    168   // Determine Per Channel Memory Size:
    169   // (For 2 RANKs, multiply by 2)
    170   // (For 16 bit data bus, divide by 2)
    171   // DENSITY  WIDTH   MEM_AVAILABLE
    172   // 512Mb    x16     0x008000000 ( 128MB)
    173   // 512Mb    x8      0x010000000 ( 256MB)
    174   // 1Gb      x16     0x010000000 ( 256MB)
    175   // 1Gb      x8      0x020000000 ( 512MB)
    176   // 2Gb      x16     0x020000000 ( 512MB)
    177   // 2Gb      x8      0x040000000 (1024MB)
    178   // 4Gb      x16     0x040000000 (1024MB)
    179   // 4Gb      x8      0x080000000 (2048MB)
    180   mrc_params->channel_size[channel_i] = (1 << dram_params[dram_cfg_index].DENSITY);
    181   mrc_params->channel_size[channel_i] *= ((dram_width == x8) ? (2) : (1));
    182   mrc_params->channel_size[channel_i] *= (mrc_params->rank_enables == 0x3) ? (2) : (1);
    183   mrc_params->channel_size[channel_i] *= (mrc_params->channel_width == x16) ? (1) : (2);
    184 
    185   // Determine memory size (convert number of 64MB/512Mb units)
    186   mrc_params->mem_size += mrc_params->channel_size[channel_i] << 26;
    187 
    188   // end of channel settings
    189 
    190   LEAVEFN();
    191   return;
    192 }
    193 
    194