452166ba288025d6cfae03349e2110aa376619ee
[coreboot.git] / src / northbridge / intel / e7501 / northbridge.c
1 #include <console/console.h>
2 #include <arch/io.h>
3 #include <stdint.h>
4 #include <mem.h>
5 #include <part/sizeram.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <device/chip.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <bitops.h>
12 #include "chip.h"
13
14 struct mem_range *sizeram(void)
15 {
16         static struct mem_range mem[4];
17         /* the units of tolm are 64 KB */
18         /* the units of drb16 are 64 MB */
19         uint16_t tolm, remapbase, remaplimit, drb16;
20         uint16_t tolm_r, remapbase_r, remaplimit_r;
21         uint8_t  drb;
22         int remap_high;
23         device_t dev;
24
25         dev = dev_find_slot(0, 0); // d0f0
26         if (!dev) {
27                 printk_err("Cannot find PCI: 0:0\n");
28                 return 0;
29         }
30         
31         /* Calculate and report the top of low memory and 
32          * any remapping.
33          */
34         /* Test if the remap memory high option is set */
35         remap_high = 0;
36 //        if(get_option(&remap_high, "remap_memory_high")){
37 //                remap_high = 0;
38 //        }
39         printk_debug("remap_high is %d\n", remap_high);
40         /* get out the value of the highest DRB. This tells the end of 
41          * physical memory. The units are ticks of 64 MB i.e. 1 means
42          * 64 MB. 
43          */
44         drb = pci_read_config8(dev, 0x67);
45         drb16 = (uint16_t)drb;
46         if(remap_high && (drb16 > 0x08)) {
47                 /* We only come here if we have at least 512MB of memory,
48                  * so it is safe to hard code tolm.
49                  * 0x2000 means 512MB 
50                  */
51
52                 tolm = 0x2000;
53                 /* i.e 0x40 * 0x40 is 0x1000 which is 4 GB */
54                 if(drb16 > 0x0040) {
55                         /* There is more than 4GB of memory put
56                          * the remap window at the end of ram.
57                          */
58                         remapbase = drb16;
59                         remaplimit = remapbase + 0x38;
60                 }
61                 else {
62                         remapbase = 0x0040;
63                         remaplimit = remapbase + (drb16-8);
64                 }
65         }
66         else {
67                 tolm = (uint16_t)((dev_root.resource[1].base >> 16)&0x0f800);
68                 if((tolm>>8) >= (drb16<<2)) {
69                         tolm = (drb16<<10);
70                         remapbase = 0x3ff;
71                         remaplimit = 0;
72                 }
73                 else {
74                         remapbase = drb16;
75                         remaplimit = remapbase + ((0x0040-(tolm>>10))-1);
76                 }
77         }
78         /* Write the ram configruation registers,
79          * preserving the reserved bits.
80          */
81         tolm_r = pci_read_config16(dev, 0xc4);
82         tolm |= (tolm_r & 0x7ff); 
83         pci_write_config16(dev, 0xc4, tolm);
84         remapbase_r = pci_read_config16(dev, 0xc6);
85         remapbase |= (remapbase_r & 0xfc00);
86         pci_write_config16(dev, 0xc6, remapbase);
87         remaplimit_r = pci_read_config16(dev, 0xc8);
88         remaplimit |= (remaplimit_r & 0xfc00);
89         pci_write_config16(dev, 0xc8, remaplimit);
90
91 #if 0
92     printk_debug("mem info tolm = %x, drb = %x, pci_memory_base = %x, remap = %x-%x\n",tolm,drb,pci_memory_base,remapbase,remaplimit);
93 #endif
94         
95         mem[0].basek = 0;
96         mem[0].sizek = 640;
97         mem[1].basek = 768;
98         /* Convert size in 64K bytes to size in K bytes */
99         mem[1].sizek = (tolm << 6) - mem[1].basek;
100         mem[2].basek = 0;
101         mem[2].sizek = 0;
102         if ((drb << 16) > (tolm << 6)) {
103                 /* We don't need to consider the remap window
104                  * here because we put it immediately after the
105                  * rest of ram.
106                  * All we must do is calculate the amount
107                  * of unused memory and report it at 4GB.
108                  */
109                 mem[2].basek = 4096*1024;
110                 mem[2].sizek = (drb << 16) - (tolm << 6);
111         }
112         mem[3].basek = 0;
113         mem[3].sizek = 0;
114         
115         return mem;
116 }
117 static void enumerate(struct chip *chip)
118 {
119         extern struct device_operations default_pci_ops_bus;
120         chip_enumerate(chip);
121         chip->dev->ops = &default_pci_ops_bus;
122 }
123 #if 0
124 static void northbridge_init(struct chip *chip, enum chip_pass pass)
125 {
126
127         struct northbridge_intel_e7501_config *conf =
128                 (struct northbridge_intel_e7501_config *)chip->chip_info;
129
130         switch (pass) {
131         case CONF_PASS_PRE_PCI:
132                 break;
133
134         case CONF_PASS_POST_PCI:
135                 break;
136
137         case CONF_PASS_PRE_BOOT:
138                 break;
139
140         default:
141                 /* nothing yet */
142                 break;
143         }
144 }
145 #endif
146
147 struct chip_control northbridge_intel_e7501_control = {
148         .enumerate = enumerate,
149 //        .enable    = northbridge_init,
150         .name      = "intel E7501 Northbridge",
151 };