Since some people disapprove of white space cleanups mixed in regular commits
[coreboot.git] / src / northbridge / via / cx700 / cx700_vga.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2007-2009 coresystems GmbH
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18  */
19
20 #include <console/console.h>
21 #include <arch/io.h>
22 #include <stdint.h>
23 #include <device/device.h>
24 #include <device/pci.h>
25 #include <device/pci_ids.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <bitops.h>
29 #include <cpu/cpu.h>
30 #include <cpu/x86/mtrr.h>
31 #include <cpu/x86/msr.h>
32 #include <arch/interrupt.h>
33 #include "cx700_registers.h"
34 #include "chip.h"
35 #include "northbridge.h"
36
37 /* PCI Domain 1 Device 0 Function 0 */
38
39 #define SR_INDEX        0x3c4
40 #define SR_DATA         0x3c5
41 #define CRTM_INDEX      0x3b4
42 #define CRTM_DATA       0x3b5
43 #define CRTC_INDEX      0x3d4
44 #define CRTC_DATA       0x3d5
45
46 static int via_cx700_int15_handler(struct eregs *regs)
47 {
48         int res=-1;
49         u8 mem_speed;
50
51 #define MEMORY_SPEED_66MHZ      (0 << 4)
52 #define MEMORY_SPEED_100MHZ     (1 << 4)
53 #define MEMORY_SPEED_133MHZ     (1 << 4)
54 #define MEMORY_SPEED_200MHZ     (3 << 4) // DDR200
55 #define MEMORY_SPEED_266MHZ     (4 << 4) // DDR266
56 #define MEMORY_SPEED_333MHZ     (5 << 4) // DDR333
57 #define MEMORY_SPEED_400MHZ     (6 << 4) // DDR400
58 #define MEMORY_SPEED_533MHZ     (7 << 4) // DDR533
59 #define MEMORY_SPEED_667MHZ     (8 << 4) // DDR667
60
61         const u8 memory_mapping[6] = {
62                 MEMORY_SPEED_200MHZ, MEMORY_SPEED_266MHZ,
63                 MEMORY_SPEED_333MHZ, MEMORY_SPEED_400MHZ,
64                 MEMORY_SPEED_533MHZ, MEMORY_SPEED_667MHZ
65         };
66
67         printk(BIOS_DEBUG, "via_cx700_int15_handler\n");
68
69         switch(regs->eax & 0xffff) {
70         case 0x5f00:    /* VGA POST Initialization Signal */
71                 regs->eax = (regs->eax & 0xffff0000 ) | 0x5f;
72                 res = 0;
73                 break;
74
75         case 0x5f01:    /* Software Panel Type Configuration */
76                 regs->eax = (regs->eax & 0xffff0000 ) | 0x5f;
77                 // panel type =  2 = 1024 * 768
78                 regs->ecx = (regs->ecx & 0xffffff00 ) | 2;
79                 res = 0;
80                 break;
81
82         case 0x5f27:    /* Boot Device Selection */
83                 regs->eax = (regs->eax & 0xffff0000 ) | 0x5f;
84
85                 regs->ebx = 0x00000000; // 0 -> default
86                 regs->ecx = 0x00000000; // 0 -> default
87                 // TV Layout - default
88                 regs->edx = (regs->edx & 0xffffff00) | 0;
89                 res=0;
90                 break;
91
92         case 0x5f0b:    /* Get Expansion Setting */
93                 regs->eax = (regs->eax & 0xffff0000 ) | 0x5f;
94
95                 regs->ecx = regs->ecx & 0xffffff00; // non-expansion
96                 // regs->ecx = regs->ecx & 0xffffff00 | 1; // expansion
97                 res=0;
98                 break;
99
100         case 0x5f0f:    /* VGA Post Completion */
101                 regs->eax = (regs->eax & 0xffff0000 ) | 0x5f;
102                 res=0;
103                 break;
104
105         case 0x5f18:
106                 regs->eax = (regs->eax & 0xffff0000 ) | 0x5f;
107 #define UMA_SIZE_8MB            (3 << 0)
108 #define UMA_SIZE_16MB           (4 << 0)
109 #define UMA_SIZE_32MB           (5 << 0)
110
111                 regs->ebx = (regs->ebx & 0xffff0000 ) | MEMORY_SPEED_533MHZ | UMA_SIZE_32MB;
112
113                 mem_speed = pci_read_config8(dev_find_slot(0, PCI_DEVFN(0, 4)), SCRATCH_DRAM_FREQ);
114                 if (mem_speed > 5)
115                         mem_speed = 5;
116
117                 regs->ebx |= memory_mapping[mem_speed];
118
119                 res=0;
120                 break;
121
122         default:
123                 printk(BIOS_DEBUG, "Unknown INT15 function %04x!\n",
124                                 regs->eax & 0xffff);
125                 break;
126         }
127         return res;
128 }
129
130 #ifdef UNUSED_CODE
131 static void write_protect_vgabios(void)
132 {
133         device_t dev;
134
135         printk(BIOS_DEBUG, "write_protect_vgabios\n");
136
137         dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x3324, 0);
138         if (dev)
139                 pci_write_config8(dev, 0x80, 0xff);
140
141         dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x7324, 0);
142         if (dev)
143                 pci_write_config8(dev, 0x61, 0xff);
144 }
145 #endif
146
147 static void vga_init(device_t dev)
148 {
149         u8 reg8;
150
151         mainboard_interrupt_handlers(0x15, &via_cx700_int15_handler);
152
153         //*
154         pci_write_config8(dev, 0x04, 0x07);
155         pci_write_config8(dev, 0x3e, 0x02);
156         pci_write_config8(dev, 0x0d, 0x40);
157         pci_write_config32(dev, 0x10, 0xa0000008);
158         pci_write_config32(dev, 0x14, 0xdd000000);
159         pci_write_config8(dev, 0x3c, 0x0b);
160         //*/
161
162         printk(BIOS_DEBUG, "Initializing VGA...\n");
163
164         pci_dev_init(dev);
165
166         if (pci_read_config32(dev, PCI_ROM_ADDRESS) != 0xc0000) return;
167
168         printk(BIOS_DEBUG, "Enable VGA console\n");
169         // this is how it should look:
170         //   call_bios_interrupt(0x10,0x4f1f,0x8003,1,0);
171         // this is how it looks:
172         vga_enable_console();
173
174         /* It's not clear if these need to be programmed before or after
175          * the VGA bios runs. Try both, clean up later */
176         /* Set memory rate to 200MHz */
177         outb(0x3d, CRTM_INDEX);
178         reg8 = inb(CRTM_DATA);
179         reg8 &= 0x0f;
180         reg8 |= (0x3 << 4);
181         outb(0x3d, CRTM_INDEX);
182         outb(reg8, CRTM_DATA);
183
184         /* Set framebuffer size to 32mb */
185         reg8 = (32 / 4);
186         outb(0x39, SR_INDEX);
187         outb(reg8, SR_DATA);
188 }
189
190 static struct device_operations vga_operations = {
191         .read_resources = pci_dev_read_resources,
192         .set_resources = pci_dev_set_resources,
193         .enable_resources = pci_dev_enable_resources,
194         .init = vga_init,
195         .ops_pci = 0,
196 };
197
198 static const struct pci_driver vga_driver __pci_driver = {
199         .ops = &vga_operations,
200         .vendor = PCI_VENDOR_ID_VIA,
201         .device = 0x3157,
202 };