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