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.
PreMemInit(MRCParams_t * mrc_params)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