1 /* Turn off machine check triggers when reading
2 * PCI space where there are no devices.
3 * This is necessary when scanning 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>
18 #include <pc80/mc146818rtc.h>
20 #include <cpu/amd/model_fxx_rev.h>
25 * @brief Read resources for AGP aperture
29 * There is only one AGP aperture resource needed. The resource is added to
30 * the northbridge of BSP.
32 * The same trick can be used to augment legacy VGA resources which can
33 * be detect by generic PCI resource allocator for VGA devices.
34 * BAD: it is more tricky than I think, the resource allocation code is
35 * implemented in a way to NOT DOING legacy VGA resource allocation on
38 static void mcf3_read_resources(device_t dev)
40 struct resource *resource;
42 /* Read the generic PCI resources */
43 pci_dev_read_resources(dev);
45 /* If we are not the first processor don't allocate the GART aperture */
46 if (dev->path.pci.devfn != PCI_DEVFN(0x18, 3)) {
51 if( get_option(&iommu, "iommu") < 0 )
57 /* Add a GART aperture resource */
58 resource = new_resource(dev, 0x94);
59 resource->size = CONFIG_AGP_APERTURE_SIZE;
60 resource->align = log2(resource->size);
61 resource->gran = log2(resource->size);
62 resource->limit = 0xffffffff; /* 4G */
63 resource->flags = IORESOURCE_MEM;
67 static void set_agp_aperture(device_t dev)
69 struct resource *resource;
71 resource = probe_resource(dev, 0x94);
74 uint32_t gart_base, gart_acr;
76 /* Remember this resource has been stored */
77 resource->flags |= IORESOURCE_STORED;
79 /* Find the size of the GART aperture */
80 gart_acr = (0<<6)|(0<<5)|(0<<4)|((resource->gran - 25) << 1)|(0<<0);
82 /* Get the base address */
83 gart_base = ((resource->base) >> 25) & 0x00007fff;
85 /* Update the other northbridges */
87 while((pdev = dev_find_device(PCI_VENDOR_ID_AMD, 0x1103, pdev))) {
88 /* Store the GART size but don't enable it */
89 pci_write_config32(pdev, 0x90, gart_acr);
91 /* Store the GART base address */
92 pci_write_config32(pdev, 0x94, gart_base);
94 /* Don't set the GART Table base address */
95 pci_write_config32(pdev, 0x98, 0);
97 /* Report the resource has been stored... */
98 report_resource_stored(pdev, resource, " <gart>");
103 static void mcf3_set_resources(device_t dev)
105 /* Set the gart apeture */
106 set_agp_aperture(dev);
108 /* Set the generic PCI resources */
109 pci_dev_set_resources(dev);
112 static void misc_control_init(struct device *dev)
114 uint32_t cmd, cmd_ref;
116 struct device *f0_dev;
118 printk(BIOS_DEBUG, "NB: Function 3 Misc Control.. ");
121 /* Disable Machine checks from Invalid Locations.
122 * This is needed for PC backwards compatibility.
124 cmd = pci_read_config32(dev, 0x44);
125 cmd |= (1<<6) | (1<<25);
126 pci_write_config32(dev, 0x44, cmd );
127 #if CONFIG_K8_REV_F_SUPPORT == 0
128 if (is_cpu_pre_c0()) {
131 * Disable CPU low power states C2, C1 and throttling
133 cmd = pci_read_config32(dev, 0x80);
135 pci_write_config32(dev, 0x80, cmd );
136 cmd = pci_read_config32(dev, 0x84);
139 pci_write_config32(dev, 0x84, cmd );
142 * Limit the number of downstream posted requests to 1
144 cmd = pci_read_config32(dev, 0x70);
145 if ((cmd & (3 << 0)) != 2) {
148 pci_write_config32(dev, 0x70, cmd );
151 cmd = pci_read_config32(dev, 0x7c);
152 if ((cmd & (3 << 4)) != 0) {
155 pci_write_config32(dev, 0x7c, cmd );
158 /* Clock Power/Timing Low */
159 cmd = pci_read_config32(dev, 0xd4);
160 if (cmd != 0x000D0001) {
162 pci_write_config32(dev, 0xd4, cmd);
163 needs_reset = 1; /* Needed? */
166 else if(is_cpu_pre_d0()) {
167 struct device *f2_dev;
169 f2_dev = dev_find_slot(0, dev->path.pci.devfn - 3 + 2);
171 * Set Clk Ramp Hystersis to 7
172 * Clock Power/Timing Low
174 cmd_ref = 0x04e20707; /* Registered */
175 dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW);
176 if (dcl & DCL_UnBuffDimm) {
177 cmd_ref = 0x000D0701; /* Unbuffered */
179 cmd = pci_read_config32(dev, 0xd4);
181 pci_write_config32(dev, 0xd4, cmd_ref );
182 needs_reset = 1; /* Needed? */
186 /* Optimize the Link read pointers */
187 f0_dev = dev_find_slot(0, dev->path.pci.devfn - 3);
190 cmd_ref = cmd = pci_read_config32(dev, 0xdc);
191 for(link = 0; link < 3; link++) {
194 /* This works on an Athlon64 because unimplemented links return 0 */
195 reg = 0x98 + (link * 0x20);
196 link_type = pci_read_config32(f0_dev, reg);
197 /* Only handle coherent link here please */
198 if ((link_type & (LinkConnected|InitComplete|NonCoherent))
199 == (LinkConnected|InitComplete))
201 cmd &= ~(0xff << (link *8));
202 /* FIXME this assumes the device on the other side is an AMD device */
203 cmd |= 0x25 << (link *8);
206 if (cmd != cmd_ref) {
207 pci_write_config32(dev, 0xdc, cmd);
212 printk(BIOS_ERR, "Missing f0 device!\n");
215 printk(BIOS_DEBUG, "resetting cpu\n");
218 printk(BIOS_DEBUG, "done.\n");
222 static struct device_operations mcf3_ops = {
223 .read_resources = mcf3_read_resources,
224 .set_resources = mcf3_set_resources,
225 .enable_resources = pci_dev_enable_resources,
226 .init = misc_control_init,
231 static const struct pci_driver mcf3_driver __pci_driver = {
233 .vendor = PCI_VENDOR_ID_AMD,