2 * Copyright (c) 2004-2005 Fabrice Bellard
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License V2
6 * as published by the Free Software Foundation
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
20 #include "kernel/kernel.h"
21 #include "libopenbios/bindings.h"
22 #include "drivers/pci.h"
23 #include "drivers/drivers.h"
24 #include "libopenbios/fontdata.h"
26 #include "libc/vsprintf.h"
27 #include "drivers/vga.h"
28 #include "packages/video.h"
29 #include "libopenbios/ofmem.h"
31 /* VGA init. We use the Bochs VESA VBE extensions */
32 #define VBE_DISPI_INDEX_ID 0x0
33 #define VBE_DISPI_INDEX_XRES 0x1
34 #define VBE_DISPI_INDEX_YRES 0x2
35 #define VBE_DISPI_INDEX_BPP 0x3
36 #define VBE_DISPI_INDEX_ENABLE 0x4
37 #define VBE_DISPI_INDEX_BANK 0x5
38 #define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
39 #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
40 #define VBE_DISPI_INDEX_X_OFFSET 0x8
41 #define VBE_DISPI_INDEX_Y_OFFSET 0x9
42 #define VBE_DISPI_INDEX_NB 0xa
44 #define VBE_DISPI_ID0 0xB0C0
45 #define VBE_DISPI_ID1 0xB0C1
46 #define VBE_DISPI_ID2 0xB0C2
48 #define VBE_DISPI_DISABLED 0x00
49 #define VBE_DISPI_ENABLED 0x01
50 #define VBE_DISPI_LFB_ENABLED 0x40
51 #define VBE_DISPI_NOCLEARMEM 0x80
53 static void vbe_outw(int index
, int val
)
59 /* for depth = 8 mode, set a hardware palette entry */
60 void vga_set_color(int i
, unsigned int r
, unsigned int g
, unsigned int b
)
71 /* build standard RGB palette */
72 static void vga_build_rgb_palette(void)
74 static const uint8_t pal_value
[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
78 for(r
= 0; r
< 6; r
++) {
79 for(g
= 0; g
< 6; g
++) {
80 for(b
= 0; b
< 6; b
++) {
81 vga_set_color(i
, pal_value
[r
], pal_value
[g
], pal_value
[b
]);
88 /* depth = 8, 15, 16 or 32 */
89 void vga_vbe_set_mode(int width
, int height
, int depth
)
91 outb(0x00, 0x3c0); /* enable blanking */
92 vbe_outw(VBE_DISPI_INDEX_ENABLE
, VBE_DISPI_DISABLED
);
93 vbe_outw(VBE_DISPI_INDEX_X_OFFSET
, 0);
94 vbe_outw(VBE_DISPI_INDEX_Y_OFFSET
, 0);
95 vbe_outw(VBE_DISPI_INDEX_XRES
, width
);
96 vbe_outw(VBE_DISPI_INDEX_YRES
, height
);
97 vbe_outw(VBE_DISPI_INDEX_BPP
, depth
);
98 vbe_outw(VBE_DISPI_INDEX_ENABLE
, VBE_DISPI_ENABLED
);
100 outb(0x20, 0x3c0); /* disable blanking */
103 vga_build_rgb_palette();
106 #ifdef CONFIG_VGA_WIDTH
107 #define VGA_DEFAULT_WIDTH CONFIG_VGA_WIDTH
109 #define VGA_DEFAULT_WIDTH 800
112 #ifdef CONFIG_VGA_HEIGHT
113 #define VGA_DEFAULT_HEIGHT CONFIG_VGA_HEIGHT
115 #define VGA_DEFAULT_HEIGHT 600
118 #ifdef CONFIG_VGA_DEPTH
119 #define VGA_DEFAULT_DEPTH CONFIG_VGA_DEPTH
121 #define VGA_DEFAULT_DEPTH 8
124 #define VGA_DEFAULT_LINEBYTES (VGA_DEFAULT_WIDTH*((VGA_DEFAULT_DEPTH+7)/8))
126 void vga_vbe_init(const char *path
, unsigned long fb
, uint32_t fb_size
,
127 unsigned long rom
, uint32_t rom_size
)
129 phandle_t ph
, chosen
, aliases
, options
;
131 int width
= VGA_DEFAULT_WIDTH
;
132 int height
= VGA_DEFAULT_HEIGHT
;
133 int depth
= VGA_DEFAULT_DEPTH
;
134 int linebytes
= VGA_DEFAULT_LINEBYTES
;
136 #if defined(CONFIG_QEMU) && (defined(CONFIG_PPC) || defined(CONFIG_SPARC64))
138 w
= fw_cfg_read_i16(FW_CFG_ARCH_WIDTH
);
139 h
= fw_cfg_read_i16(FW_CFG_ARCH_HEIGHT
);
140 d
= fw_cfg_read_i16(FW_CFG_ARCH_DEPTH
);
145 linebytes
= (width
* ((depth
+ 7) / 8));
147 #ifdef CONFIG_SPARC64
148 #define VGA_VADDR 0xfe000000
149 ofmem_claim_phys(fb
, fb_size
, 0);
150 ofmem_claim_virt(VGA_VADDR
, fb_size
, 0);
151 ofmem_map(fb
, VGA_VADDR
, fb_size
, 0x76);
156 vga_vbe_set_mode(width
, height
, depth
);
164 set_int_property(ph
, "width", width
);
165 set_int_property(ph
, "height", height
);
166 set_int_property(ph
, "depth", depth
);
167 set_int_property(ph
, "linebytes", linebytes
);
168 set_int_property(ph
, "address", (u32
)(fb
& ~0x0000000F));
170 chosen
= find_dev("/chosen");
173 set_int_property(chosen
, "display", POP());
175 aliases
= find_dev("/aliases");
176 set_property(aliases
, "screen", path
, strlen(path
) + 1);
178 options
= find_dev("/options");
179 snprintf(buf
, sizeof(buf
), "%d", width
/ FONT_WIDTH
);
180 set_property(options
, "screen-#columns", buf
, strlen(buf
) + 1);
181 snprintf(buf
, sizeof(buf
), "%d", height
/ FONT_HEIGHT
);
182 set_property(options
, "screen-#rows", buf
, strlen(buf
) + 1);
188 p
= (const char *)rom
;
189 if (p
[0] == 'N' && p
[1] == 'D' && p
[2] == 'R' && p
[3] == 'V') {
190 size
= *(uint32_t*)(p
+ 4);
191 set_property(ph
, "driver,AAPL,MacOS,PowerPC",
196 init_video(fb
, width
, height
, depth
, linebytes
);