2 * This file is part of the coreboot project.
4 * Copyright (C) 2010 Advanced Micro Devices, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 /* This file contains functions for common utility functions */
23 *-----------------------------------------------------------------------------
26 *-----------------------------------------------------------------------------
30 *-----------------------------------------------------------------------------
33 *-----------------------------------------------------------------------------
36 static void AmdMemPCIReadBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue)
38 /* ASSERT(highbit < 32 && lowbit < 32 && highbit >= lowbit && (loc & 3) == 0); */
40 AmdMemPCIRead(loc, pValue);
41 *pValue = *pValue >> lowbit; /* Shift */
43 /* A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case */
44 if ((highbit-lowbit) != 31)
45 *pValue &= (((u32)1 << (highbit-lowbit+1))-1);
48 static void AmdMemPCIWriteBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue)
52 /* ASSERT(highbit < 32 && lowbit < 32 && highbit >= lowbit && (loc & 3) == 0); */
54 /* A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case */
55 if ((highbit-lowbit) != 31)
56 mask = (((u32)1 << (highbit-lowbit+1))-1);
58 mask = (u32)0xFFFFFFFF;
60 AmdMemPCIRead(loc, &temp);
61 temp &= ~(mask << lowbit);
62 temp |= (*pValue & mask) << lowbit;
63 AmdMemPCIWrite(loc, &temp);
66 /*-----------------------------------------------------------------------------
68 * u32 bitTestSet(u32 csMask,u32 tempD)
71 * This routine sets a bit in a u32
74 * IN csMask = Target value in which the bit will be set
75 * IN tempD = Bit that will be set
76 * OUT value = Target value with the bit set
77 *-----------------------------------------------------------------------------
79 static u32 bitTestSet(u32 csMask,u32 tempD)
82 /* ASSERT(tempD < 32); */
84 csMask |= localTemp << tempD;
88 /*-----------------------------------------------------------------------------
90 * u32 bitTestReset(u32 csMask,u32 tempD)
93 * This routine re-sets a bit in a u32
96 * IN csMask = Target value in which the bit will be re-set
97 * IN tempD = Bit that will be re-set
98 * OUT value = Target value with the bit re-set
99 *-----------------------------------------------------------------------------
101 static u32 bitTestReset(u32 csMask,u32 tempD)
104 /* ASSERT(tempD < 32); */
106 temp = localTemp << tempD;
112 /*-----------------------------------------------------------------------------
114 * u32 get_Bits(DCTStruct *DCTData, u8 DCT, u8 Node, u8 func, u16 offset,
118 * This routine Gets the PCT bits from the specidfied Node, DCT and PCI address
121 * IN OUT *DCTData - Pointer to buffer with information about each DCT
122 * IN DCT - DCT number
123 * - 1 indicates DCT 1
124 * - 0 indicates DCT 0
127 * Func - PCI Function number
128 * Offset - PCI register number
129 * Low - Low bit of the bit field
130 * High - High bit of the bit field
132 * OUT value = Value read from PCI space
133 *-----------------------------------------------------------------------------
135 static u32 get_Bits(sDCTStruct *pDCTData,
136 u8 dct, u8 node, u8 func,
137 u16 offset, u8 low, u8 high)
140 /* ASSERT(node < MAX_NODES); */
141 if (dct == BOTH_DCTS)
143 /* Registers exist on DCT0 only */
144 AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
152 AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
157 AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
163 /*-----------------------------------------------------------------------------
165 * void set_Bits(DCTStruct *DCTData,u8 DCT,u8 Node,u8 func, u16 offset,
166 * u8 low, u8 high, u32 value)
169 * This routine Sets the PCT bits from the specidfied Node, DCT and PCI address
172 * IN OUT *DCTData - Pointer to buffer with information about each DCT
173 * IN DCT - DCT number
174 * - 1 indicates DCT 1
175 * - 0 indicates DCT 0
178 * Func - PCI Function number
179 * Offset - PCI register number
180 * Low - Low bit of the bit field
181 * High - High bit of the bit field
184 *-----------------------------------------------------------------------------
186 static void set_Bits(sDCTStruct *pDCTData,
187 u8 dct, u8 node, u8 func,
188 u16 offset, u8 low, u8 high, u32 value)
193 if (dct == BOTH_DCTS)
195 /* Registers exist on DCT0 only */
196 AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
204 AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
209 AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
214 /*-------------------------------------------------
216 * u32 get_ADD_DCT_Bits(DCTStruct *DCTData,u8 DCT,u8 Node,u8 func,
217 * u16 offset,u8 low, u8 high)
220 * This routine gets the Additional PCT register from Function 2 by specidfied
221 * Node, DCT and PCI address
224 * IN OUT *DCTData - Pointer to buffer with information about each DCT
225 * IN DCT - DCT number
226 * - 1 indicates DCT 1
227 * - 0 indicates DCT 0
230 * Func - PCI Function number
231 * Offset - Additional PCI register number
232 * Low - Low bit of the bit field
233 * High - High bit of the bit field
236 *-------------------------------------------------
238 static u32 get_ADD_DCT_Bits(sDCTStruct *pDCTData,
239 u8 dct, u8 node, u8 func,
240 u16 offset, u8 low, u8 high)
244 tempD = bitTestReset(tempD,DctAccessWrite);
245 set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
246 PCI_MIN_LOW, PCI_MAX_HIGH, offset);
247 while ((get_Bits(pDCTData,dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
248 DctAccessDone, DctAccessDone)) == 0);
249 return (get_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_PORT_REG,
253 /*-------------------------------------------------
255 * void set_DCT_ADDR_Bits(DCTStruct *DCTData, u8 DCT,u8 Node,u8 func,
256 * u16 offset,u8 low, u8 high, u32 value)
259 * This routine sets the Additional PCT register from Function 2 by specidfied
260 * Node, DCT and PCI address
263 * IN OUT *DCTData - Pointer to buffer with information about each DCT
264 * IN DCT - DCT number
265 * - 1 indicates DCT 1
266 * - 0 indicates DCT 0
269 * Func - PCI Function number
270 * Offset - Additional PCI register number
271 * Low - Low bit of the bit field
272 * High - High bit of the bit field
275 *-------------------------------------------------
277 static void set_DCT_ADDR_Bits(sDCTStruct *pDCTData,
278 u8 dct, u8 node, u8 func,
279 u16 offset, u8 low, u8 high, u32 value)
283 set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
284 PCI_MIN_LOW, PCI_MAX_HIGH, offset);
285 while ((get_Bits(pDCTData,dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
286 DctAccessDone, DctAccessDone)) == 0);
288 set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_PORT_REG,
291 tempD = bitTestSet(tempD,DctAccessWrite);
292 set_Bits(pDCTData, dct, node, FUN_DCT,DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
293 PCI_MIN_LOW, PCI_MAX_HIGH, tempD);
294 while ((get_Bits(pDCTData,dct, pDCTData->NodeId, FUN_DCT,
295 DRAM_CONTROLLER_ADD_DATA_OFFSET_REG, DctAccessDone,
296 DctAccessDone)) == 0);
299 /*-------------------------------------------------
301 * BOOL bitTest(u32 value, u8 bitLoc)
304 * This routine tests the value to determine if the bitLoc is set
307 * IN Value - value to be tested
308 * bitLoc - bit location to be tested
309 * OUT TRUE - bit is set
310 * FALSE - bit is clear
311 *-------------------------------------------------
313 static BOOL bitTest(u32 value, u8 bitLoc)
318 compD = bitTestSet(compD,bitLoc);