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 "./cpu_rev.c"
21 static void mcf3_read_resources(device_t dev)
23 struct resource *resource;
25 /* Read the generic PCI resources */
26 pci_dev_read_resources(dev);
28 /* If we are not the first processor don't allocate the gart apeture */
29 if (dev->path.u.pci.devfn != PCI_DEVFN(0x18, 0x3)) {
33 /* Add a 64M Gart apeture resource */
34 if (dev->resources < MAX_RESOURCES) {
35 resource = &dev->resource[dev->resources];
38 resource->size = AGP_APERTURE_SIZE;
39 resource->align = log2(resource->size);
40 resource->gran = log2(resource->size);
41 resource->limit = 0xffffffff; /* 4G */
42 resource->flags = IORESOURCE_MEM;
43 resource->index = 0x94;
45 printk_err("%s Unexpeted resource shortage\n", dev_path(dev));
49 static void mcf3_set_resources(device_t dev)
51 struct resource *resource, *last;
52 last = &dev->resource[dev->resources];
53 for (resource = &dev->resource[0]; resource < last; resource++) {
54 if (resource->index == 0x94) {
59 size = (0<<6)|(0<<5)|(0<<4)|
60 ((log2(resource->size) - 25) << 1)|(0<<0);
61 base = ((resource->base) >> 25) & 0x00007fff;
63 while (pdev = dev_find_device(PCI_VENDOR_ID_AMD, 0x1103, pdev)) {
64 /* I want a 64M GART apeture */
65 pci_write_config32(pdev, 0x90, (0<<6)|(0<<5)|(0<<4)|(1<<1)|(0<<0));
66 /* Store the GART base address */
67 pci_write_config32(pdev, 0x94, base);
68 /* Don't set the GART Table base address */
69 pci_write_config32(pdev, 0x98, 0);
71 printk_debug("%s %02x <- [0x%08lx - 0x%08lx] mem <gart>\n",
72 dev_path(pdev), resource->index, resource->base,
73 resource->base + resource->size - 1);
75 /* Remember this resource has been stored */
76 resource->flags |= IORESOURCE_STORED;
79 /* Set the generic PCI resources */
80 pci_dev_set_resources(dev);
83 static void misc_control_init(struct device *dev)
85 uint32_t cmd, cmd_ref;
87 struct device *f0_dev, *f2_dev;
89 printk_debug("NB: Function 3 Misc Control.. ");
92 /* Disable Machine checks from Invalid Locations.
93 * This is needed for PC backwards compatibility.
95 cmd = pci_read_config32(dev, 0x44);
96 cmd |= (1<<6) | (1<<25);
97 pci_write_config32(dev, 0x44, cmd );
98 if (is_cpu_pre_c0()) {
101 * Disable CPU low power states C2, C1 and throttling
103 cmd = pci_read_config32(dev, 0x80);
105 pci_write_config32(dev, 0x80, cmd );
106 cmd = pci_read_config32(dev, 0x84);
109 pci_write_config32(dev, 0x84, cmd );
112 * Limit the number of downstream posted requests to 1
114 cmd = pci_read_config32(dev, 0x70);
115 if ((cmd & (3 << 0)) != 2) {
118 pci_write_config32(dev, 0x70, cmd );
121 cmd = pci_read_config32(dev, 0x7c);
122 if ((cmd & (3 << 4)) != 0) {
125 pci_write_config32(dev, 0x7c, cmd );
128 /* Clock Power/Timing Low */
129 cmd = pci_read_config32(dev, 0xd4);
130 if (cmd != 0x000D0001) {
132 pci_write_config32(dev, 0xd4, cmd);
133 needs_reset = 1; /* Needed? */
138 f2_dev = dev_find_slot(0, dev->path.u.pci.devfn - 3 + 2);
140 * Set Clk Ramp Hystersis to 7
141 * Clock Power/Timing Low
143 cmd_ref = 0x04e20707; /* Registered */
144 dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW);
145 if (dcl & DCL_UnBufDimm) {
146 cmd_ref = 0x000D0701; /* Unbuffered */
148 cmd = pci_read_config32(dev, 0xd4);
150 pci_write_config32(dev, 0xd4, cmd_ref );
151 needs_reset = 1; /* Needed? */
154 #if CONFIG_MAX_CPUS > 1
155 /* Single CPU systems don't seem to need this. It might cause resets? (YhLu) */
156 /* Optimize the Link read pointers */
157 f0_dev = dev_find_slot(0, dev->path.u.pci.devfn - 3);
160 cmd_ref = cmd = pci_read_config32(dev, 0xdc);
161 for(link = 0; link < 3; link++) {
164 /* This works on an Athlon64 because unimplemented links return 0 */
165 reg = 0x98 + (link * 0x20);
166 link_type = pci_read_config32(f0_dev, reg);
167 if (link_type & LinkConnected) {
168 cmd &= 0xff << (link *8);
169 /* FIXME this assumes the device on the other side is an AMD device */
170 cmd |= 0x25 << (link *8);
173 if (cmd != cmd_ref) {
174 pci_write_config32(dev, 0xdc, cmd);
179 printk_err("Missing f0 device!\n");
183 printk_debug("resetting cpu\n");
186 printk_debug("done.\n");
190 static struct device_operations mcf3_ops = {
191 .read_resources = mcf3_read_resources,
192 .set_resources = mcf3_set_resources,
193 .enable_resources = pci_dev_enable_resources,
194 .init = misc_control_init,
198 static struct pci_driver mcf3_driver __pci_driver = {
200 .vendor = PCI_VENDOR_ID_AMD,