remove trailing whitespace
[coreboot.git] / src / northbridge / amd / agesa / family12 / amdfam12_conf.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2011 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 /*
21  * No includes in this file because it is included into northbridge.c.
22  */
23
24 struct dram_base_mask_t {
25         u32 base; //[47:27] at [28:8]
26         u32 mask; //[47:27] at [28:8] and enable at bit 0
27 };
28
29 static struct dram_base_mask_t get_dram_base_mask(u32 nodeid)
30 {
31         device_t dev;
32         struct dram_base_mask_t d;
33 #if defined(__PRE_RAM__)
34         dev = PCI_DEV(CONFIG_CBB, CONFIG_CDB, 1);
35 #else
36         dev = __f1_dev[0];
37 #endif  // defined(__PRE_RAM__)
38
39         u32 temp;
40         temp = pci_read_config32(dev, 0x44); //[39:24] at [31:16]
41         d.mask = (temp & 0xffff0000); // mask out  DramMask [26:24] too
42
43         temp = pci_read_config32(dev, 0x40); //[35:24] at [27:16]
44         d.mask |= (temp & 1); // read enable bit
45
46         d.base = (temp & 0x0fff0000); // mask out DramBase [26:24) too
47
48         return d;
49 }
50
51 #if CONFIG_EXT_CONF_SUPPORT
52 static void set_addr_map_reg_4_6_in_one_node(u32 nodeid, u32 cfg_map_dest,
53                                                 u32 busn_min, u32 busn_max,
54                                                 u32 type)
55 {
56         device_t dev;
57         u32 i;
58         u32 tempreg;
59         u32 index_min, index_max;
60         u32 dest_min, dest_max;
61         index_min = busn_min>>2; dest_min = busn_min - (index_min<<2);
62         index_max = busn_max>>2; dest_max = busn_max - (index_max<<2);
63
64         // three case: index_min==index_max, index_min+1=index_max; index_min+1<index_max
65 #if defined(__PRE_RAM__)
66         dev = NODE_PCI(nodeid, 1);
67 #else
68         dev = __f1_dev[nodeid];
69 #endif  // defined(__PRE_RAM__)
70         if(index_min== index_max) {
71                 pci_write_config32(dev, 0x110, index_min | (type<<28));
72                 tempreg = pci_read_config32(dev, 0x114);
73                 for(i=dest_min; i<=dest_max; i++) {
74                         tempreg &= ~(0xff<<(i*8));
75                         tempreg |= (cfg_map_dest<<(i*8));
76                 }
77                 pci_write_config32(dev, 0x110, index_min | (type<<28)); // do i need to write it again
78                 pci_write_config32(dev, 0x114, tempreg);
79         } else if(index_min<index_max) {
80                 pci_write_config32(dev, 0x110, index_min | (type<<28));
81                 tempreg = pci_read_config32(dev, 0x114);
82                 for(i=dest_min; i<=3; i++) {
83                         tempreg &= ~(0xff<<(i*8));
84                         tempreg |= (cfg_map_dest<<(i*8));
85                 }
86                 pci_write_config32(dev, 0x110, index_min | (type<<28)); // do i need to write it again
87                 pci_write_config32(dev, 0x114, tempreg);
88
89                 pci_write_config32(dev, 0x110, index_max | (type<<28));
90                 tempreg = pci_read_config32(dev, 0x114);
91                 for(i=0; i<=dest_max; i++) {
92                         tempreg &= ~(0xff<<(i*8));
93                         tempreg |= (cfg_map_dest<<(i*8));
94                 }
95                 pci_write_config32(dev, 0x110, index_max | (type<<28)); // do i need to write it again
96                 pci_write_config32(dev, 0x114, tempreg);
97                 if((index_max-index_min)>1) {
98                         tempreg = 0;
99                         for(i=0; i<=3; i++) {
100                                 tempreg &= ~(0xff<<(i*8));
101                                 tempreg |= (cfg_map_dest<<(i*8));
102                         }
103                         for(i=index_min+1; i<index_max;i++) {
104                                 pci_write_config32(dev, 0x110, i | (type<<28));
105                                 pci_write_config32(dev, 0x114, tempreg);
106                         }
107                 }
108         }
109 }
110 #endif  // CONFIG_EXT_CONF_SUPPORT
111
112 #if defined(__PRE_RAM__)
113 static void set_ht_c_io_addr_reg(u32 nodeid, u32 linkn, u32 ht_c_index,
114                                         u32 io_min, u32 io_max, u32 nodes)
115 {
116         u32 i;
117         u32 tempreg;
118         device_t dev;
119
120 #if CONFIG_EXT_CONF_SUPPORT
121         if(ht_c_index<4) {
122 #endif
123                 /* io range allocation */
124                 tempreg = (nodeid&0xf) | ((nodeid & 0x30)<<(8-4)) | (linkn<<4) |  ((io_max&0xf0)<<(12-4)); //limit
125                 for(i=0; i<nodes; i++) {
126                         dev = NODE_PCI(i, 1);
127                         pci_write_config32(dev, 0xC4 + ht_c_index * 8, tempreg);
128                 }
129                 tempreg = 3 /*| ( 3<<4)*/ | ((io_min&0xf0)<<(12-4));         //base :ISA and VGA ?
130                 for(i=0; i<nodes; i++){
131                         dev = NODE_PCI(i, 1);
132                         pci_write_config32(dev, 0xC0 + ht_c_index * 8, tempreg);
133                 }
134 #if CONFIG_EXT_CONF_SUPPORT
135                 return;
136         }
137
138         u32 cfg_map_dest;
139         u32 j;
140
141         // if ht_c_index > 3, We should use extend space
142
143         if(io_min>io_max) return;
144
145         // for nodeid at first
146         cfg_map_dest = (1<<7) | (1<<6) | (linkn<<0);
147
148         set_addr_map_reg_4_6_in_one_node(nodeid, cfg_map_dest, io_min, io_max, 4);
149
150         // all other nodes
151         cfg_map_dest = (1<<7) | (0<<6) | (nodeid<<0);
152         for(j = 0; j< nodes; j++) {
153                 if(j== nodeid) continue;
154                 set_addr_map_reg_4_6_in_one_node(j,cfg_map_dest, io_min, io_max, 4);
155         }
156 #endif  // CONFIG_EXT_CONF_SUPPORT
157 }
158
159
160 static void clear_ht_c_io_addr_reg(u32 nodeid, u32 linkn, u32 ht_c_index,
161                                         u32 io_min, u32 io_max, u32 nodes)
162 {
163         u32 i;
164         device_t dev;
165 #if CONFIG_EXT_CONF_SUPPORT
166         if(ht_c_index<4) {
167 #endif
168                  /* io range allocation */
169                 for(i=0; i<nodes; i++) {
170                         dev = NODE_PCI(i, 1);
171                         pci_write_config32(dev, 0xC4 + ht_c_index * 8, 0);
172                         pci_write_config32(dev, 0xC0 + ht_c_index * 8, 0);
173                 }
174 #if CONFIG_EXT_CONF_SUPPORT
175                 return;
176         }
177         // : if hc_c_index > 3, We should use io_min, io_max to clear extend space
178         u32 cfg_map_dest;
179         u32 j;
180
181
182         // all nodes
183         cfg_map_dest = 0;
184         for(j = 0; j< nodes; j++) {
185                 set_addr_map_reg_4_6_in_one_node(j,cfg_map_dest, io_min, io_max, 4);
186         }
187 #endif
188 }
189 #endif // defined(__PRE_RAM__)
190
191 #if !defined(__PRE_RAM__)
192 static u32 get_io_addr_index(u32 nodeid, u32 linkn)
193 {
194 #if 0
195         u32 index;
196
197         for(index=0; index<256; index++) {
198                 if((sysconf.conf_io_addrx[index+4] == 0)){
199                         sysconf.conf_io_addr[index+4] =  (nodeid & 0x3f)  ;
200                         sysconf.conf_io_addrx[index+4] = 1 | ((linkn & 0x7)<<4);
201                         return index;
202                  }
203          }
204 #endif
205          return  0;
206 }
207
208 static u32 get_mmio_addr_index(u32 nodeid, u32 linkn)
209 {
210 #if 0
211         u32 index;
212
213         for(index=0; index<64; index++) {
214                 if((sysconf.conf_mmio_addrx[index+8] == 0)){
215                         sysconf.conf_mmio_addr[index+8] = (nodeid & 0x3f) ;
216                         sysconf.conf_mmio_addrx[index+8] = 1 | ((linkn & 0x7)<<4);
217                         return index;
218                 }
219         }
220 #endif
221
222         return   0;
223 }
224
225 static void set_io_addr_reg(device_t dev, u32 nodeid, u32 linkn, u32 reg,
226                                 u32 io_min, u32 io_max)
227 {
228
229         u32 tempreg;
230 #if CONFIG_EXT_CONF_SUPPORT
231         if(reg!=0x110) {
232 #endif
233                 /* io range allocation */
234                 tempreg = (nodeid&0xf) | ((nodeid & 0x30)<<(8-4)) | (linkn<<4) |  ((io_max&0xf0)<<(12-4)); //limit
235                 pci_write_config32(__f1_dev[0], reg+4, tempreg);
236
237                 tempreg = 3 /*| ( 3<<4)*/ | ((io_min&0xf0)<<(12-4));          //base :ISA and VGA ?
238 #if 0
239                 // FIXME: can we use VGA reg instead?
240                 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
241                         printk(BIOS_SPEW, "%s, enabling legacy VGA IO forwarding for %s link %s\n",
242                                 __func__, dev_path(dev), link);
243                         tempreg |= PCI_IO_BASE_VGA_EN;
244                 }
245                 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) {
246                         tempreg |= PCI_IO_BASE_NO_ISA;
247                 }
248 #endif
249                 pci_write_config32(__f1_dev[0], reg, tempreg);
250 #if CONFIG_EXT_CONF_SUPPORT
251                 return;
252         }
253
254         u32 cfg_map_dest;
255         u32 j;
256         // if ht_c_index > 3, We should use extend space
257         if(io_min>io_max) return;
258         // for nodeid at first
259         cfg_map_dest = (1<<7) | (1<<6) | (linkn<<0);
260
261         set_addr_map_reg_4_6_in_one_node(nodeid, cfg_map_dest, io_min, io_max, 4);
262 #endif // CONFIG_EXT_CONF_SUPPORT
263 }
264
265
266 static void set_mmio_addr_reg(u32 nodeid, u32 linkn, u32 reg, u32 index, u32 mmio_min, u32 mmio_max, u32 nodes)
267 {
268
269         u32 tempreg;
270 #if CONFIG_EXT_CONF_SUPPORT
271         if(reg!=0x110) {
272 #endif
273                 /* io range allocation */
274                 tempreg = (nodeid&0xf) | (linkn<<4) |    (mmio_max&0xffffff00); //limit
275                 pci_write_config32(__f1_dev[0], reg+4, tempreg);
276                 tempreg = 3 | (nodeid & 0x30) | (mmio_min&0xffffff00);
277                 pci_write_config32(__f1_dev[0], reg, tempreg);
278 #if CONFIG_EXT_CONF_SUPPORT
279                 return;
280         }
281
282         device_t dev;
283         u32 j;
284         // if ht_c_index > 3, We should use extend space
285         // for nodeid at first
286         u32 enable;
287
288         if(mmio_min>mmio_max) {
289                 return;
290         }
291
292         enable = 1;
293
294         dev = __f1_dev[nodeid];
295         tempreg = ((mmio_min>>3) & 0x1fffff00)| (1<<6) | (linkn<<0);
296         pci_write_config32(dev, 0x110, index | (2<<28));
297         pci_write_config32(dev, 0x114, tempreg);
298
299         tempreg = ((mmio_max>>3) & 0x1fffff00) | enable;
300         pci_write_config32(dev, 0x110, index | (3<<28));
301         pci_write_config32(dev, 0x114, tempreg);
302 #endif  // CONFIG_EXT_CONF_SUPPORT
303 }
304
305 #endif // !defined(__PRE_RAM__)