1 #include <console/console.h>
5 #include <part/sizeram.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <device/pci_ids.h>
9 #include <device/hypertransport.h>
10 #include <device/chip.h>
15 #include "northbridge.h"
18 struct mem_range *sizeram(void)
20 unsigned long mmio_basek;
21 static struct mem_range mem[10];
25 #warning "FIXME handle interleaved nodes"
26 dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
28 printk_err("Cannot find PCI: 0:18.1\n");
31 mmio_basek = (dev_root.resource[1].base >> 10);
32 /* Round mmio_basek to something the processor can support */
33 mmio_basek &= ~((1 << 6) -1);
36 #warning "FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M MMIO hole"
37 /* Round the mmio hold to 256M */
38 mmio_basek &= ~((256*1024) - 1);
42 printk_debug("mmio_base: %dKB\n", mmio_basek);
45 for (idx = i = 0; i < 8; i++) {
47 unsigned basek, limitk, sizek;
48 base = pci_read_config32(dev, 0x40 + (i<<3));
49 limit = pci_read_config32(dev, 0x44 + (i<<3));
50 if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
53 basek = (base & 0xffff0000) >> 2;
54 limitk = ((limit + 0x00010000) & 0xffff0000) >> 2;
55 sizek = limitk - basek;
57 ((mem[idx - 1].basek + mem[idx - 1].sizek) == basek)) {
58 mem[idx -1].sizek += sizek;
60 mem[idx].basek = basek;
61 mem[idx].sizek = sizek;
65 /* see if we need a hole from 0xa0000 to 0xbffff */
66 if ((mem[idx-1].basek < ((8*64)+(8*16))) /* 640 */ &&
67 (mem[idx-1].sizek > ((8*64)+(16*16))) /* 768 */ ) {
68 #warning "FIXME: this left 0xA0000 to 0xBFFFF undefined"
69 mem[idx].basek = (8*64)+(16*16);
70 mem[idx].sizek = mem[idx-1].sizek - ((8*64)+(16*16));
71 mem[idx-1].sizek = ((8*64)+(8*16)) - mem[idx-1].basek;
75 /* See if I need to split the region to accomodate pci memory space */
76 if ((mem[idx - 1].basek <= mmio_basek) &&
77 ((mem[idx - 1].basek + mem[idx - 1].sizek) > mmio_basek)) {
78 if (mem[idx - 1].basek < mmio_basek) {
80 pre_sizek = mmio_basek - mem[idx - 1].basek;
81 mem[idx].basek = mmio_basek;
82 mem[idx].sizek = mem[idx - 1].sizek - pre_sizek;
83 mem[idx - 1].sizek = pre_sizek;
86 if ((mem[idx - 1].basek + mem[idx - 1].sizek) <= 4*1024*1024) {
89 mem[idx - 1].basek = 4*1024*1024;
90 mem[idx - 1].sizek -= (4*1024*1024 - mmio_basek);
95 for (i = 0; i < idx; i++) {
96 printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n",
97 i, mem[i].basek, i, mem[i].sizek);
100 while (idx < sizeof(mem)/sizeof(mem[0])) {
109 static device_t __f1_dev[F1_DEVS];
112 static void debug_f1_devs(void)
115 for (i = 0; i < F1_DEVS; i++) {
119 printk_debug("__f1_dev[%d]: %s bus: %p\n",
120 i, dev_path(dev), dev->bus);
126 static void get_f1_devs(void)
132 for (i = 0; i < F1_DEVS; i++) {
133 __f1_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 1));
136 die("Cannot find 0:0x18.1\n");
140 static uint32_t f1_read_config32(unsigned reg)
143 return pci_read_config32(__f1_dev[0], reg);
146 static void f1_write_config32(unsigned reg, uint32_t value)
150 for (i = 0; i < F1_DEVS; i++) {
154 pci_write_config32(dev, reg, value);
159 static unsigned int amdk8_nodeid(device_t dev)
161 return (dev->path.u.pci.devfn >> 3) - 0x18;
164 static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
169 nodeid = amdk8_nodeid(dev);
171 printk_spew("amdk8_scan_chains max: %d starting...\n", max);
173 for (link = 0; link < dev->links; link++) {
175 uint32_t busses, config_busses;
176 unsigned free_reg, config_reg;
177 dev->link[link].cap = 0x80 + (link *0x20);
179 link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
180 } while(link_type & ConnectionPending);
181 if (!(link_type & LinkConnected)) {
185 link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
186 } while(!(link_type & InitComplete));
187 if (!(link_type & NonCoherent)) {
190 /* See if there is an available configuration space mapping register
193 for (config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) {
195 config = f1_read_config32(config_reg);
196 if (!free_reg && ((config & 3) == 0)) {
197 free_reg = config_reg;
200 if (((config & 3) == 3) &&
201 (((config >> 4) & 7) == nodeid) &&
202 (((config >> 8) & 3) == link)) {
206 if (free_reg && (config_reg > 0xec)) {
207 config_reg = free_reg;
209 /* If we can't find an available configuration space mapping
210 * register skip this bus */
211 if (config_reg > 0xec) {
215 /* Set up the primary, secondary and subordinate bus numbers.
216 * We have no idea how many busses are behind this bridge yet,
217 * so we set the subordinate bus number to 0xff for the moment.
219 dev->link[link].secondary = ++max;
220 dev->link[link].subordinate = 0xff;
222 /* Read the existing primary/secondary/subordinate bus
223 * number configuration.
225 busses = pci_read_config32(dev, dev->link[link].cap + 0x14);
226 config_busses = f1_read_config32(config_reg);
228 /* Configure the bus numbers for this bridge: the configuration
229 * transactions will not be propagates by the bridge if it is
230 * not correctly configured
232 busses &= 0xff000000;
233 busses |= (((unsigned int)(dev->bus->secondary) << 0) |
234 ((unsigned int)(dev->link[link].secondary) << 8) |
235 ((unsigned int)(dev->link[link].subordinate) << 16));
236 pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
238 config_busses &= 0x000fc88;
240 (3 << 0) | /* rw enable, no device compare */
241 (( nodeid & 7) << 4) |
242 (( link & 3 ) << 8) |
243 ((dev->link[link].secondary) << 16) |
244 ((dev->link[link].subordinate) << 24);
245 f1_write_config32(config_reg, config_busses);
247 printk_spew("Hyper transport scan link: %d max: %d\n",
250 /* Now we can scan all of the subordinate busses i.e. the
251 * chain on the hypertranport link */
252 max = hypertransport_scan_chain(&dev->link[link], max);
254 printk_spew("Hyper transport scan link: %d new max: %d\n",
257 /* We know the number of busses behind this bridge. Set the
258 * subordinate bus number to it's real value
260 dev->link[link].subordinate = max;
261 busses = (busses & 0xff00ffff) |
262 ((unsigned int) (dev->link[link].subordinate) << 16);
263 pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
265 config_busses = (config_busses & 0x00ffffff) |
266 (dev->link[link].subordinate << 24);
267 f1_write_config32(config_reg, config_busses);
268 printk_spew("Hypertransport scan link done\n");
271 printk_spew("amdk8_scan_chains max: %d done\n", max);
275 static unsigned amdk8_find_iopair(unsigned nodeid, unsigned link)
277 unsigned free_reg, reg;
280 for (reg = 0xc0; reg <= 0xd8; reg += 0x8) {
281 uint32_t base, limit;
282 base = f1_read_config32(reg);
283 limit = f1_read_config32(reg + 0x4);
284 /* Do I have a free register */
285 if (!free_reg && ((base & 3) == 0)) {
288 /* Do I have a match for this node and link? */
289 if (((base & 3) == 3) &&
290 ((limit & 7) == nodeid) &&
291 (((limit >> 4) & 3) == link)) {
295 /* If I didn't find an exact match return a free register */
299 /* Return an available I/O pair or 0 on failure */
303 static unsigned amdk8_find_mempair(unsigned nodeid, unsigned link)
305 unsigned free_reg, reg;
308 for (reg = 0x80; reg <= 0xb8; reg += 0x8) {
309 uint32_t base, limit;
310 base = f1_read_config32(reg);
311 limit = f1_read_config32(reg + 0x4);
312 /* Do I have a free register */
313 if (!free_reg && ((base & 3) == 0)) {
316 /* Do I have a match for this node and link? */
317 if (((base & 3) == 3) &&
318 ((limit & 7) == nodeid) &&
319 (((limit >> 4) & 3) == link)) {
323 /* If I didn't find an exact match return a free register */
327 /* Return an available I/O pair or 0 on failure */
331 static void amdk8_link_read_bases(device_t dev, unsigned nodeid, unsigned link)
333 unsigned int reg = dev->resources;
336 /* Initialize the io space constraints on the current bus */
337 index = amdk8_find_iopair(nodeid, link);
339 dev->resource[reg].base = 0;
340 dev->resource[reg].size = 0;
341 dev->resource[reg].align = log2(HT_IO_HOST_ALIGN);
342 dev->resource[reg].gran = log2(HT_IO_HOST_ALIGN);
343 dev->resource[reg].limit = 0xffffUL;
344 dev->resource[reg].flags = IORESOURCE_IO;
345 dev->resource[reg].index = index | (link & 0x3);
346 compute_allocate_resource(&dev->link[link], &dev->resource[reg],
347 IORESOURCE_IO, IORESOURCE_IO);
351 /* Initialize the memory constraints on the current bus */
352 index = amdk8_find_mempair(nodeid, link);
354 dev->resource[reg].base = 0;
355 dev->resource[reg].size = 0;
356 dev->resource[reg].align = log2(HT_MEM_HOST_ALIGN);
357 dev->resource[reg].gran = log2(HT_MEM_HOST_ALIGN);
358 dev->resource[reg].limit = 0xffffffffUL;
359 dev->resource[reg].flags = IORESOURCE_MEM;
360 dev->resource[reg].index = index | (link & 0x3);
361 compute_allocate_resource(&dev->link[link], &dev->resource[reg],
362 IORESOURCE_MEM, IORESOURCE_MEM);
365 dev->resources = reg;
368 static void amdk8_read_resources(device_t dev)
370 unsigned nodeid, link;
371 nodeid = amdk8_nodeid(dev);
373 memset(&dev->resource, 0, sizeof(dev->resource));
374 for (link = 0; link < dev->links; link++) {
375 if (dev->link[link].children) {
376 amdk8_link_read_bases(dev, nodeid, link);
381 static void amdk8_set_resource(device_t dev, struct resource *resource,
384 unsigned long rbase, rlimit;
387 /* Make certain the resource has actually been set */
388 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
392 /* If I have already stored this resource don't worry about it */
393 if (resource->flags & IORESOURCE_STORED) {
397 /* Only handle PCI memory and IO resources */
398 if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
401 /* Get the base address */
402 rbase = resource->base;
404 /* Get the limit (rounded up) */
405 rlimit = rbase + ((resource->size + resource->align - 1UL) &
406 ~(resource->align -1)) - 1UL;
408 /* Get the register and link */
409 reg = resource->index & ~3;
410 link = resource->index & 3;
412 if (resource->flags & IORESOURCE_IO) {
413 uint32_t base, limit;
414 compute_allocate_resource(&dev->link[link], resource,
415 IORESOURCE_IO, IORESOURCE_IO);
416 base = f1_read_config32(reg);
417 limit = f1_read_config32(reg + 0x4);
419 base |= rbase & 0x01fff000;
422 limit |= rlimit & 0x01fff000;
423 limit |= (link & 3) << 4;
424 limit |= (nodeid & 7);
426 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
427 base |= PCI_IO_BASE_VGA_EN;
429 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) {
430 base |= PCI_IO_BASE_NO_ISA;
432 f1_write_config32(reg + 0x4, limit);
433 f1_write_config32(reg, base);
434 } else if (resource->flags & IORESOURCE_MEM) {
435 uint32_t base, limit;
436 compute_allocate_resource(&dev->link[link], resource,
437 IORESOURCE_MEM, IORESOURCE_MEM);
438 base = f1_read_config32(reg);
439 limit = f1_read_config32(reg + 0x4);
441 base |= (rbase & 0xffff0000) >> 8;
444 limit |= (rlimit & 0xffff0000) >> 8;
445 limit |= (link & 3) << 4;
446 limit |= (nodeid & 7);
447 f1_write_config32(reg + 0x4, limit);
448 f1_write_config32(reg, base);
450 resource->flags |= IORESOURCE_STORED;
451 printk_debug("%s %02x <- [0x%08lx - 0x%08lx] node %d link %d %s\n",
452 dev_path(dev), reg, rbase, rlimit, nodeid, link,
453 (resource->flags & IORESOURCE_IO)? "io": "mem");
456 static void amdk8_set_resources(device_t dev)
458 unsigned nodeid, link;
461 /* Find the nodeid */
462 nodeid = amdk8_nodeid(dev);
464 /* Set each resource we have found */
465 for (i = 0; i < dev->resources; i++) {
466 amdk8_set_resource(dev, &dev->resource[i], nodeid);
469 for (link = 0; link < dev->links; link++) {
471 bus = &dev->link[link];
473 assign_resources(bus);
479 * @brief Scan root bus for AMD K8 systems
481 * @param root the root device structure
482 * @max the current bus number scanned so far, usually 0x00
484 * The root device in a AMD K8 system is not at Bus 0, Device 0, Fun 0
485 * as other PCI based systems. The northbridge is at Bus 0, Device 0x18,
486 * Fun 0. We have to call the pci_scan_bus() with PCI_DEVFN(0x18,0) as
487 * the starting device instead of PCI_DEVFN(0x00, 0) as in the default
488 * root_dev_scan_pci_bus().
490 * This function is set up as the default scan_bus() method for mainboards'
491 * device_operations for AMD K8 mainboards in mainboard.c
493 * @see device_operation()
494 * @see root_dev_scan_pci_bus()
496 unsigned int amdk8_scan_root_bus(device_t root, unsigned int max)
500 printk_spew("amdk8_scan_root_bus\n");
502 /* Unmap all of the HT chains by clearing the Configuration
504 for (reg = 0xe0; reg <= 0xec; reg += 4) {
505 f1_write_config32(reg, 0);
508 max = pci_scan_bus(&root->link[0], PCI_DEVFN(0x18, 0), 0xff, max);
510 printk_spew("amdk8_scan_root_bus: done\n");
514 static void mcf0_control_init(struct device *dev)
519 printk_spew("NB: Function 0 Misc Control.. ");
520 /* improve latency and bandwith on HT */
521 cmd = pci_read_config32(dev, 0x68);
524 pci_write_config32(dev, 0x68, cmd );
528 /* over drive the ht port to 1000 Mhz */
529 cmd = pci_read_config32(dev, 0xa8);
532 pci_write_config32(dev, 0xdc, cmd );
535 printk_spew("done.\n");
539 static void amdk8_enable_resources(struct device *dev)
543 unsigned int vgalink = -1;
545 ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
546 ctrl |= dev->link[0].bridge_ctrl;
547 printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
548 pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
551 /* No, don;t do it here, we should create phantom PCI resource
552 * for leagcy VGA resources in VGA device driver and use the
553 * generic resource allocation/assignment code to do it
555 * TOO BAD, the generic resource allcation code refuses to do
556 * abything with VGA and the AMDK8 resource code does want
557 * more than one discontinous IO/MEM regions */
559 /* let's see what link VGA is on */
560 for (link = 0; link < dev->links; link++) {
562 printk_err("Kid %d of k8: bridge ctrl says: 0x%x\n",
563 link, dev->link[link].bridge_ctrl);
564 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA)
569 uint32_t base, limit;
571 /* now allocate an MMPAIR and point it to the CPU0,
574 * FIXME: add amdk8_find_free_mempair() */
575 //reg = amdk8_find_mempair(0, vgalink);
577 /* Set base of 0xa0000 */
579 limit = 0xd00 | (vgalink << 4);
580 printk_debug("setting MMIO routing for VGA reg:0x%x, base: 0x%x, limit 0x%x\n",
582 f1_write_config32(reg, base);
583 f1_write_config32(reg + 4, limit);
587 pci_dev_enable_resources(dev);
590 static struct device_operations northbridge_operations = {
591 .read_resources = amdk8_read_resources,
592 .set_resources = amdk8_set_resources,
593 .enable_resources = amdk8_enable_resources,
594 .init = mcf0_control_init,
595 .scan_bus = amdk8_scan_chains,
599 static struct pci_driver mcf0_driver __pci_driver = {
600 .ops = &northbridge_operations,
601 .vendor = PCI_VENDOR_ID_AMD,
605 static void enumerate(struct chip *chip)
607 chip_enumerate(chip);
608 chip->dev->ops = &northbridge_operations;
611 struct chip_control northbridge_amd_amdk8_control = {
612 .name = "AMD K8 Northbridge",
613 .enumerate = enumerate,