1 /* Turn off machine check triggers when reading
2 * pci space where there are no devices.
3 * This is necessary when scaning the bus for
4 * devices which is done by the kernel
6 * written in 2003 by Eric Biederman
8 * - Athlon64 workarounds by Stefan Reinauer
9 * - "reset once" logic by Yinghai Lu
12 #include <console/console.h>
13 #include <device/device.h>
14 #include <device/pci.h>
15 #include <device/pci_ids.h>
16 #include <device/pci_ops.h>
17 #include <part/hard_reset.h>
18 #include <pc80/mc146818rtc.h>
20 #include "./cpu_rev.c"
24 * @brief Read resources for AGP aperture
28 * There is only one AGP aperture resource needed. The resoruce is added to
29 * the northbridge of BSP.
31 * The same trick can be used to augment legacy VGA resources which can
32 * be detect by generic pci reousrce allocator for VGA devices.
33 * BAD: it is more tricky than I think, the resource allocation code is
34 * implemented in a way to NOT DOING legacy VGA resource allcation on
37 static void mcf3_read_resources(device_t dev)
39 struct resource *resource;
41 /* Read the generic PCI resources */
42 pci_dev_read_resources(dev);
44 /* If we are not the first processor don't allocate the gart apeture */
45 if (dev->path.u.pci.devfn != PCI_DEVFN(0x18, 0x3)) {
50 get_option(&iommu, "iommu");
53 /* Add a Gart apeture resource */
54 resource = new_resource(dev, 0x94);
55 resource->size = iommu?AGP_APERTURE_SIZE:1;
56 resource->align = log2(resource->size);
57 resource->gran = log2(resource->size);
58 resource->limit = 0xffffffff; /* 4G */
59 resource->flags = IORESOURCE_MEM;
63 static void set_agp_aperture(device_t dev)
65 struct resource *resource;
67 resource = probe_resource(dev, 0x94);
70 uint32_t gart_base, gart_acr;
71 /* Remember this resource has been stored */
72 resource->flags |= IORESOURCE_STORED;
74 /*Find the size of the GART aperture */
75 gart_acr = (0<<6)|(0<<5)|(0<<4)| ((log2(resource->size) - 25) << 1)|(0<<0);
77 /* Get the base address */
78 gart_base = ((resource->base) >> 25) & 0x00007fff;
80 /* Update the other northbriges */
82 while (pdev = dev_find_device(PCI_VENDOR_ID_AMD, 0x1103, pdev)) {
83 /* Store GART size but don't enable it */
84 pci_write_config32(pdev, 0x90, gart_acr);
86 /* Store the GART base address */
87 pci_write_config32(pdev, 0x94, gart_base);
89 /* Don't set the GART Table base address */
90 pci_write_config32(pdev, 0x98, 0);
92 /* Report the resource has been stored... */
93 report_resource_stored(pdev, resource, " <gart>");
98 static void mcf3_set_resources(device_t dev)
100 /* Set the gart apeture */
101 set_agp_aperture(dev);
103 /* Set the generic PCI resources */
104 pci_dev_set_resources(dev);
107 static void misc_control_init(struct device *dev)
109 uint32_t cmd, cmd_ref;
111 struct device *f0_dev, *f2_dev;
113 printk_debug("NB: Function 3 Misc Control.. ");
116 /* Disable Machine checks from Invalid Locations.
117 * This is needed for PC backwards compatibility.
119 cmd = pci_read_config32(dev, 0x44);
120 cmd |= (1<<6) | (1<<25);
121 pci_write_config32(dev, 0x44, cmd );
122 if (is_cpu_pre_c0()) {
125 * Disable CPU low power states C2, C1 and throttling
127 cmd = pci_read_config32(dev, 0x80);
129 pci_write_config32(dev, 0x80, cmd );
130 cmd = pci_read_config32(dev, 0x84);
133 pci_write_config32(dev, 0x84, cmd );
136 * Limit the number of downstream posted requests to 1
138 cmd = pci_read_config32(dev, 0x70);
139 if ((cmd & (3 << 0)) != 2) {
142 pci_write_config32(dev, 0x70, cmd );
145 cmd = pci_read_config32(dev, 0x7c);
146 if ((cmd & (3 << 4)) != 0) {
149 pci_write_config32(dev, 0x7c, cmd );
152 /* Clock Power/Timing Low */
153 cmd = pci_read_config32(dev, 0xd4);
154 if (cmd != 0x000D0001) {
156 pci_write_config32(dev, 0xd4, cmd);
157 needs_reset = 1; /* Needed? */
162 f2_dev = dev_find_slot(0, dev->path.u.pci.devfn - 3 + 2);
164 * Set Clk Ramp Hystersis to 7
165 * Clock Power/Timing Low
167 cmd_ref = 0x04e20707; /* Registered */
168 dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW);
169 if (dcl & DCL_UnBufDimm) {
170 cmd_ref = 0x000D0701; /* Unbuffered */
172 cmd = pci_read_config32(dev, 0xd4);
174 pci_write_config32(dev, 0xd4, cmd_ref );
175 needs_reset = 1; /* Needed? */
178 #if CONFIG_MAX_CPUS > 1
179 /* Single CPU systems don't seem to need this. It might cause resets? (YhLu) */
180 /* Optimize the Link read pointers */
181 f0_dev = dev_find_slot(0, dev->path.u.pci.devfn - 3);
184 cmd_ref = cmd = pci_read_config32(dev, 0xdc);
185 for(link = 0; link < 3; link++) {
188 /* This works on an Athlon64 because unimplemented links return 0 */
189 reg = 0x98 + (link * 0x20);
190 link_type = pci_read_config32(f0_dev, reg);
191 if (link_type & LinkConnected) {
192 cmd &= 0xff << (link *8);
193 /* FIXME this assumes the device on the other side is an AMD device */
194 cmd |= 0x25 << (link *8);
197 if (cmd != cmd_ref) {
198 pci_write_config32(dev, 0xdc, cmd);
203 printk_err("Missing f0 device!\n");
207 printk_debug("resetting cpu\n");
210 printk_debug("done.\n");
214 static struct device_operations mcf3_ops = {
215 .read_resources = mcf3_read_resources,
216 .set_resources = mcf3_set_resources,
217 .enable_resources = pci_dev_enable_resources,
218 .init = misc_control_init,
222 static struct pci_driver mcf3_driver __pci_driver = {
224 .vendor = PCI_VENDOR_ID_AMD,