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 #define IOMMU_APETURE_SIZE (64*1024*1024) /* 64M */
22 static void mcf3_read_resources(device_t dev)
24 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(24, 3)) {
33 /* Add a 64M Gart apeture resource */
34 if (dev->resources < MAX_RESOURCES) {
35 resource = &dev->resource[dev->resources];
38 resource->size = IOMMU_APETURE_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;
46 printk_err("%s Unexpeted resource shortage\n", dev_path(dev));
50 static void mcf3_set_resources(device_t dev)
52 struct resource *resource, *last;
53 last = &dev->resource[dev->resources];
54 for(resource = &dev->resource[0]; resource < last; resource++) {
55 if (resource->index == 0x94) {
60 size = (0<<6)|(0<<5)|(0<<4)|((log2(resource->size) - 25) << 1)|(0<<0);
61 base = ((resource->base) >> 25) & 0x00007fff;
64 while(pdev = dev_find_device(PCI_VENDOR_ID_AMD, 0x1103, pdev)) {
65 /* I want a 64M GART apeture */
66 pci_write_config32(pdev, 0x90, (0<<6)|(0<<5)|(0<<4)|(1<<1)|(0<<0));
67 /* Store the GART base address */
68 pci_write_config32(pdev, 0x94, base);
69 /* Don't set the GART Table base address */
70 pci_write_config32(pdev, 0x98, 0);
73 "%s %02x <- [0x%08lx - 0x%08lx] mem <gart>\n",
76 resource->base, resource->base + resource->size - 1);
78 /* Remember this resource has been stored */
79 resource->flags |= IORESOURCE_STORED;
83 /* Set the generic PCI resources */
84 pci_dev_set_resources(dev);
87 static void misc_control_init(struct device *dev)
89 uint32_t cmd, cmd_ref;
91 struct device *f0_dev, *f2_dev;
93 printk_debug("NB: Function 3 Misc Control.. ");
96 /* Disable Machine checks from Invalid Locations.
97 * This is needed for PC backwards compatibility.
99 cmd = pci_read_config32(dev, 0x44);
100 cmd |= (1<<6) | (1<<25);
101 pci_write_config32(dev, 0x44, cmd );
102 if (is_cpu_pre_c0()) {
105 * Disable CPU low power states C2, C1 and throttling
107 cmd = pci_read_config32(dev, 0x80);
109 pci_write_config32(dev, 0x80, cmd );
110 cmd = pci_read_config32(dev, 0x84);
113 pci_write_config32(dev, 0x84, cmd );
116 * Limit the number of downstream posted requests to 1
118 cmd = pci_read_config32(dev, 0x70);
119 if ((cmd & (3 << 0)) != 2) {
122 pci_write_config32(dev, 0x70, cmd );
125 cmd = pci_read_config32(dev, 0x7c);
126 if ((cmd & (3 << 4)) != 0) {
129 pci_write_config32(dev, 0x7c, cmd );
132 /* Clock Power/Timing Low */
133 cmd = pci_read_config32(dev, 0xd4);
134 if (cmd != 0x000D0001) {
136 pci_write_config32(dev, 0xd4, cmd);
137 needs_reset = 1; /* Needed? */
142 f2_dev = dev_find_slot(0, dev->path.u.pci.devfn - 3 + 2);
144 * Set Clk Ramp Hystersis to 7
145 * Clock Power/Timing Low
147 cmd_ref = 0x04e20707; /* Registered */
148 dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW);
149 if (dcl & DCL_UnBufDimm) {
150 cmd_ref = 0x000D0701; /* Unbuffered */
152 cmd = pci_read_config32(dev, 0xd4);
154 pci_write_config32(dev, 0xd4, cmd_ref );
155 needs_reset = 1; /* Needed? */
158 /* Optimize the Link read pointers */
159 f0_dev = dev_find_slot(0, dev->path.u.pci.devfn - 3);
162 cmd_ref = cmd = pci_read_config32(dev, 0xdc);
163 for(link = 0; link < 3; link++) {
166 /* This works on an Athlon64 because unimplemented links return 0 */
167 reg = 0x98 + (link * 0x20);
168 link_type = pci_read_config32(f0_dev, reg);
169 if (link_type & LinkConnected) {
170 cmd &= 0xff << (link *8);
171 /* FIXME this assumes the device on the other side is an AMD device */
172 cmd |= 0x25 << (link *8);
175 if (cmd != cmd_ref) {
176 pci_write_config32(dev, 0xdc, cmd);
181 printk_err("Missing f0 device!\n");
184 printk_debug("resetting cpu\n");
187 printk_debug("done.\n");
191 static struct device_operations mcf3_ops = {
192 .read_resources = mcf3_read_resources,
193 .set_resources = mcf3_set_resources,
194 .enable_resources = pci_dev_enable_resources,
195 .init = misc_control_init,
199 static struct pci_driver mcf3_driver __pci_driver = {
201 .vendor = PCI_VENDOR_ID_AMD,