Convert some comments to proper Doxygen syntax.
[coreboot.git] / src / northbridge / amd / amdht / AsPsNb.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2007 Advanced Micro Devices, Inc.
5  *
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.
9  *
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.
14  *
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
18  */
19
20 #undef FILECODE
21 #define FILECODE 0xCCCC
22
23 #include "comlib.h"
24 #include "AsPsDefs.h"
25 #include "AsPsNb.h"
26
27 u8 getNumOfNodeNb(void);
28 u8 translateNodeIdToDeviceIdNb(u8 nodeId);
29
30 /**
31  * Return the minimum possible NbCOF (in 100MHz) for the system.
32  *
33  * This function can be run on any core and is used by the HT & Memory init
34  * code in Phase 1.
35  *
36  * @return minNbCOF (in multiple of half of CLKIN, 100MHz).
37  */
38 u8 getMinNbCOF(void)
39 {
40         u8 numOfNode, i, j, deviceId, nbDid, nbFid, nextNbFid;
41         u32 dtemp;
42
43         nbDid = 0;
44         nbFid = 0;
45
46         /* get number of node in the system */
47         numOfNode = getNumOfNodeNb();
48
49         /* go through each node for the minimum NbCOF (in multiple of CLKIN/2) */
50         for(i=0; i < numOfNode; i++)
51         {
52                 /* stub function for APIC ID virtualization for large MP system later */
53                 deviceId = translateNodeIdToDeviceIdNb(i);
54
55                 /* read all P-state spec registers for NbDid=1 */
56                 for(j=0; j < 5; j++)
57                 {
58                         AmdPCIRead(MAKE_SBDFO(0,0,deviceId,FN_4,PS_SPEC_REG+(j*PCI_REG_LEN)), &dtemp); /*F4x1E0 + j*4 */
59                         /* get NbDid */
60                         if(dtemp & NB_DID_MASK)
61                                 nbDid = 1;
62                 }
63                 /* if F3x1FC[NbCofVidUpdate]=0, NbFid =  default value */
64                 AmdPCIRead(MAKE_SBDFO(0,0,deviceId,FN_3,PRCT_INFO), &dtemp); /*F3x1FC*/
65                 if(!(dtemp & NB_CV_UPDATE)) /* F3x1FC[NbCofVidUpdated]=0, use default VID */
66                 {
67                         AmdPCIRead(MAKE_SBDFO(0,0,deviceId,FN_3,CPTC0), &dtemp); /*F3xD4*/
68                         nextNbFid = (u8) (dtemp & BIT_MASK_5);
69                         if(nbDid)
70                                 nextNbFid = (u8) (nextNbFid >> 1);
71                 }
72                 else
73                 {
74                         /* check PVI/SPI */
75                         AmdPCIRead(MAKE_SBDFO(0,0,deviceId,FN_3,PW_CTL_MISC), &dtemp); /*F3xA0*/
76                         if(dtemp & PVI_MODE) /* PVI */
77                         {
78                                 AmdPCIRead(MAKE_SBDFO(0,0,deviceId,FN_3,PRCT_INFO), &dtemp); /*F3x1FC*/
79                                 nextNbFid = (u8) (dtemp >> UNI_NB_FID_BIT);
80                                 nextNbFid &= BIT_MASK_5;
81                                 /* if(nbDid)
82                                         nextNbFid = nextNbFid  >> 1; */
83                         }
84                         else /* SVI */
85                         {
86                                 AmdPCIRead(MAKE_SBDFO(0,0,deviceId,FN_3,PRCT_INFO), &dtemp); /*F3x1FC*/
87                                 nextNbFid = (u8) ((dtemp >> UNI_NB_FID_BIT) & BIT_MASK_5);
88                                 nextNbFid = (u8) (nextNbFid + ((dtemp >> SPLT_NB_FID_OFFSET) & BIT_MASK_3));
89                                 /* if(nbDid)
90                                         nextNbFid = nextNbFid >> 1; */
91                         }
92                 }
93                 if( i == 0)
94                         nbFid = nextNbFid;
95                 else if( nbFid > nextNbFid )
96                 nbFid = nextNbFid;
97         }
98
99         /* add the base and convert to 100MHz divide by 2 if DID=1 */
100         if(nbDid)
101                 nbFid = (u8) (nbFid + 4);
102         else
103                 nbFid = (u8) ((nbFid + 4) << 1);
104         return nbFid;
105 }
106
107 u8 getNumOfNodeNb(void)
108 {
109         u32 dtemp;
110
111         AmdPCIRead(MAKE_SBDFO(0,0,24,0,0x60), &dtemp);
112         dtemp = (dtemp >> 4) & BIT_MASK_3;
113         dtemp++;
114         return (u8)dtemp;
115 }
116
117 /**
118  * Return the PCI device ID for PCI access using node ID.
119  *
120  * This function may need to change node ID to device ID in big MP systems.
121  *
122  * @param nodeId Node ID of the node.
123  * @return PCI device ID of the node.
124  */
125 u8 translateNodeIdToDeviceIdNb(u8 nodeId)
126 {
127         return (u8) (nodeId+PCI_DEV_BASE);
128 }