coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
cirrus.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <stdint.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pci.h>
7 #include <device/pci_ops.h>
8 #include <pc80/vga.h>
9 #include <pc80/vga_io.h>
10 #include <framebuffer_info.h>
11 
12 static int width = CONFIG_DRIVERS_EMULATION_QEMU_BOCHS_XRES;
13 static int height = CONFIG_DRIVERS_EMULATION_QEMU_BOCHS_YRES;
14 static u32 addr = 0;
15 
16 enum
17  {
18  VGA_CR_HTOTAL = 0x00,
37  VGA_CR_PITCH = 0x13,
41  VGA_CR_MODE = 0x17,
43  };
44 
45 #define VGA_IO_MISC_COLOR 0x01
46 
47 #define VGA_CR_WIDTH_DIVISOR 8
48 
49 #define VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_SHIFT 7
50 #define VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_MASK 0x02
51 #define VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_SHIFT 3
52 #define VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_MASK 0x40
53 
54 #define VGA_CR_OVERFLOW_VERT_TOTAL1_SHIFT 8
55 #define VGA_CR_OVERFLOW_VERT_TOTAL1_MASK 0x01
56 #define VGA_CR_OVERFLOW_VERT_TOTAL2_SHIFT 4
57 #define VGA_CR_OVERFLOW_VERT_TOTAL2_MASK 0x20
58 
59 #define VGA_CR_OVERFLOW_VSYNC_START1_SHIFT 6
60 #define VGA_CR_OVERFLOW_VSYNC_START1_MASK 0x04
61 #define VGA_CR_OVERFLOW_VSYNC_START2_SHIFT 2
62 #define VGA_CR_OVERFLOW_VSYNC_START2_MASK 0x80
63 
64 #define VGA_CR_OVERFLOW_HEIGHT1_SHIFT 7
65 #define VGA_CR_OVERFLOW_HEIGHT1_MASK 0x02
66 #define VGA_CR_OVERFLOW_HEIGHT2_SHIFT 3
67 #define VGA_CR_OVERFLOW_HEIGHT2_MASK 0xc0
68 #define VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT 4
69 #define VGA_CR_OVERFLOW_LINE_COMPARE_MASK 0x10
70 
71 #define VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK 0x40
72 #define VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT 3
73 #define VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_MASK 0x20
74 #define VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_SHIFT 4
75 #define VGA_CR_CELL_HEIGHT_DOUBLE_SCAN 0x80
76 enum
77  {
79  };
80 
81 #define VGA_CR_PITCH_DIVISOR 8
82 
83 enum
84  {
90  };
91 
92 enum
93  {
99  };
100 
101 enum
102  {
105  };
106 
107 enum
108  {
110  };
111 
112 enum
113  {
118  };
119 
120 enum
121  {
130  VGA_GR_MAX
131  };
132 
133 enum
134  {
138  };
139 
140 enum
141  {
143  VGA_GR_GR6_MMAP_A0 = (1 << 2),
144  VGA_GR_GR6_MMAP_CGA = (3 << 2)
145  };
146 
147 enum
148  {
152  VGA_GR_MODE_256_COLOR = 0x40
153  };
154 
155 #define CIRRUS_CR_EXTENDED_DISPLAY 0x1b
156 #define CIRRUS_CR_EXTENDED_OVERLAY 0x1d
157 
158 #define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK 0x10
159 #define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT 4
160 #define CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1 0x1
161 #define CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT1 16
162 #define CIRRUS_CR_EXTENDED_DISPLAY_START_MASK2 0xc
163 #define CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT2 15
164 
165 #define CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK 0x80
166 #define CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_SHIFT 12
167 #define CIRRUS_SR_EXTENDED_MODE 7
168 #define CIRRUS_SR_EXTENDED_MODE_LFB_ENABLE 0xf0
169 #define CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT 0x01
170 #define CIRRUS_SR_EXTENDED_MODE_32BPP 0x08
171 #define CIRRUS_HIDDEN_DAC_888COLOR 0xc5
172 
173 static void
175 {
176  inb (0x3c8);
177  inb (0x3c6);
178  inb (0x3c6);
179  inb (0x3c6);
180  inb (0x3c6);
181  outb (data, 0x3c6);
182 }
183 
184 static void cirrus_init_linear_fb(struct device *dev)
185 {
186  uint8_t cr_ext, cr_overlay;
187  unsigned int pitch = (width * 4) / VGA_CR_PITCH_DIVISOR;
188  uint8_t sr_ext = 0, hidden_dac = 0;
189  unsigned int vdisplay_end = height - 2;
190  unsigned int line_compare = 0x3ff;
191  uint8_t overflow, cell_height_reg;
192  unsigned int horizontal_end = width / VGA_CR_WIDTH_DIVISOR;
193  unsigned int horizontal_total = horizontal_end + 40;
194  unsigned int horizontal_blank_start = horizontal_end;
195  unsigned int horizontal_sync_pulse_start = horizontal_end + 3;
196  unsigned int horizontal_sync_pulse_end = 0;
197 
198  unsigned int horizontal_blank_end = 0;
199  unsigned int vertical_blank_start = height + 1;
200  unsigned int vertical_blank_end = 0;
201  unsigned int vertical_sync_start = height + 3;
202  unsigned int vertical_sync_end = 0;
203  unsigned int vertical_total = height + 40;
204 
205  /* find lfb pci bar */
208  printk(BIOS_DEBUG, "QEMU VGA: cirrus framebuffer @ %x (pci bar 0)\n",
209  addr);
210 
212 
215 
217  (1 << VGA_TEXT_TEXT_PLANE)
218  | (1 << VGA_TEXT_ATTR_PLANE));
219 
222 
224 
225  /* Disable CR0-7 write protection. */
227 
228  overflow = ((vertical_total >> VGA_CR_OVERFLOW_VERT_TOTAL1_SHIFT)
230  | ((vertical_total >> VGA_CR_OVERFLOW_VERT_TOTAL2_SHIFT)
232  | ((vertical_sync_start >> VGA_CR_OVERFLOW_VSYNC_START2_SHIFT)
234  | ((vertical_sync_start >> VGA_CR_OVERFLOW_VSYNC_START1_SHIFT)
240  | ((vertical_sync_start >> VGA_CR_OVERFLOW_VSYNC_START1_SHIFT)
242  | ((line_compare >> VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT)
244 
245  cell_height_reg = ((vertical_blank_start
248  | ((line_compare >> VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT)
250 
251  vga_cr_write (VGA_CR_HTOTAL, horizontal_total - 1);
252  vga_cr_write (VGA_CR_HORIZ_END, horizontal_end - 1);
253  vga_cr_write (VGA_CR_HBLANK_START, horizontal_blank_start - 1);
254  vga_cr_write (VGA_CR_HBLANK_END, horizontal_blank_end);
256  horizontal_sync_pulse_start);
258  horizontal_sync_pulse_end);
259  vga_cr_write (VGA_CR_VERT_TOTAL, vertical_total & 0xff);
260  vga_cr_write (VGA_CR_OVERFLOW, overflow);
261  vga_cr_write (VGA_CR_CELL_HEIGHT, cell_height_reg);
262  vga_cr_write (VGA_CR_VSYNC_START, vertical_sync_start & 0xff);
263  vga_cr_write (VGA_CR_VSYNC_END, vertical_sync_end & 0x0f);
264  vga_cr_write (VGA_CR_VDISPLAY_END, vdisplay_end & 0xff);
265  vga_cr_write (VGA_CR_PITCH, pitch & 0xff);
266  vga_cr_write (VGA_CR_VERTICAL_BLANK_START, vertical_blank_start & 0xff);
267  vga_cr_write (VGA_CR_VERTICAL_BLANK_END, vertical_blank_end & 0xff);
268  vga_cr_write (VGA_CR_LINE_COMPARE, line_compare & 0xff);
269 
272 
274 
278 
282 
285 
290 
294 
298  hidden_dac = CIRRUS_HIDDEN_DAC_888COLOR;
300  write_hidden_dac (hidden_dac);
301 
303 }
304 
305 static void cirrus_init_text_mode(struct device *dev)
306 {
307  vga_misc_write(0x1);
309 }
310 
311 static void cirrus_init(struct device *dev)
312 {
313  if (CONFIG(LINEAR_FRAMEBUFFER))
315  else if (CONFIG(VGA_TEXT_FRAMEBUFFER))
317 }
318 
321  .set_resources = pci_dev_set_resources,
322  .enable_resources = pci_dev_enable_resources,
323  .init = cirrus_init,
324 };
325 
326 static const struct pci_driver qemu_cirrus_driver __pci_driver = {
327  .ops = &qemu_cirrus_graph_ops,
328  .vendor = 0x1013,
329  .device = 0x00b8,
330 };
#define VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT
Definition: cirrus.c:68
#define CIRRUS_SR_EXTENDED_MODE
Definition: cirrus.c:167
#define CIRRUS_SR_EXTENDED_MODE_LFB_ENABLE
Definition: cirrus.c:168
@ VGA_SR_RESET_SYNC
Definition: cirrus.c:104
@ VGA_SR_RESET_ASYNC
Definition: cirrus.c:103
#define VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_MASK
Definition: cirrus.c:50
#define VGA_CR_OVERFLOW_VERT_TOTAL1_MASK
Definition: cirrus.c:55
@ VGA_SR_MAP_MASK_REGISTER
Definition: cirrus.c:96
@ VGA_SR_CHAR_MAP_SELECT
Definition: cirrus.c:97
@ VGA_SR_CLOCKING_MODE
Definition: cirrus.c:95
@ VGA_SR_RESET
Definition: cirrus.c:94
@ VGA_SR_MEMORY_MODE
Definition: cirrus.c:98
#define CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1
Definition: cirrus.c:160
#define VGA_CR_OVERFLOW_LINE_COMPARE_MASK
Definition: cirrus.c:69
@ VGA_GR_MODE_READ_MODE1
Definition: cirrus.c:149
@ VGA_GR_MODE_ODD_EVEN_SHIFT
Definition: cirrus.c:151
@ VGA_GR_MODE_256_COLOR
Definition: cirrus.c:152
@ VGA_GR_MODE_ODD_EVEN
Definition: cirrus.c:150
#define VGA_CR_OVERFLOW_VSYNC_START2_MASK
Definition: cirrus.c:62
static int width
Definition: cirrus.c:12
#define CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT
Definition: cirrus.c:169
#define VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT
Definition: cirrus.c:72
#define VGA_CR_OVERFLOW_VERT_TOTAL2_SHIFT
Definition: cirrus.c:56
#define CIRRUS_CR_EXTENDED_OVERLAY
Definition: cirrus.c:156
#define VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_SHIFT
Definition: cirrus.c:74
#define VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_SHIFT
Definition: cirrus.c:51
#define VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_MASK
Definition: cirrus.c:52
#define CIRRUS_CR_EXTENDED_DISPLAY
Definition: cirrus.c:155
@ VGA_GR_GR6_MMAP_CGA
Definition: cirrus.c:144
@ VGA_GR_GR6_MMAP_A0
Definition: cirrus.c:143
@ VGA_GR_GR6_GRAPHICS_MODE
Definition: cirrus.c:142
@ VGA_SR_CLOCKING_MODE_8_DOT_CLOCK
Definition: cirrus.c:109
@ VGA_SR_MEMORY_MODE_CHAIN4
Definition: cirrus.c:117
@ VGA_SR_MEMORY_MODE_EXTERNAL_VIDEO_MEMORY
Definition: cirrus.c:115
@ VGA_SR_MEMORY_MODE_NORMAL
Definition: cirrus.c:114
@ VGA_SR_MEMORY_MODE_SEQUENTIAL_ADDRESSING
Definition: cirrus.c:116
#define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK
Definition: cirrus.c:158
#define VGA_IO_MISC_COLOR
Definition: cirrus.c:45
#define VGA_CR_PITCH_DIVISOR
Definition: cirrus.c:81
@ VGA_CR_CURSOR_START_DISABLE
Definition: cirrus.c:78
#define VGA_CR_OVERFLOW_VERT_TOTAL1_SHIFT
Definition: cirrus.c:54
#define VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_MASK
Definition: cirrus.c:73
#define VGA_CR_OVERFLOW_VSYNC_START1_MASK
Definition: cirrus.c:60
#define VGA_CR_OVERFLOW_VSYNC_START1_SHIFT
Definition: cirrus.c:59
#define VGA_CR_WIDTH_DIVISOR
Definition: cirrus.c:47
@ VGA_GR_COLOR_COMPARE
Definition: cirrus.c:124
@ VGA_GR_GR6
Definition: cirrus.c:127
@ VGA_GR_MAX
Definition: cirrus.c:130
@ VGA_GR_SET_RESET_PLANE
Definition: cirrus.c:122
@ VGA_GR_MODE
Definition: cirrus.c:126
@ VGA_GR_COLOR_COMPARE_DISABLE
Definition: cirrus.c:128
@ VGA_GR_BITMASK
Definition: cirrus.c:129
@ VGA_GR_READ_MAP_REGISTER
Definition: cirrus.c:125
@ VGA_GR_SET_RESET_PLANE_ENABLE
Definition: cirrus.c:123
static u32 addr
Definition: cirrus.c:14
static void cirrus_init(struct device *dev)
Definition: cirrus.c:311
@ VGA_CR_VSYNC_END
Definition: cirrus.c:35
@ VGA_CR_UNDERLINE_LOCATION
Definition: cirrus.c:38
@ VGA_CR_START_ADDR_LOW_REGISTER
Definition: cirrus.c:31
@ VGA_CR_CURSOR_ADDR_HIGH
Definition: cirrus.c:32
@ VGA_CR_HORIZ_SYNC_PULSE_END
Definition: cirrus.c:23
@ VGA_CR_VSYNC_START
Definition: cirrus.c:34
@ VGA_CR_HORIZ_END
Definition: cirrus.c:19
@ VGA_CR_VERTICAL_BLANK_START
Definition: cirrus.c:39
@ VGA_CR_PITCH
Definition: cirrus.c:37
@ VGA_CR_HBLANK_END
Definition: cirrus.c:21
@ VGA_CR_START_ADDR_HIGH_REGISTER
Definition: cirrus.c:30
@ VGA_CR_CURSOR_END
Definition: cirrus.c:29
@ VGA_CR_VERT_TOTAL
Definition: cirrus.c:24
@ VGA_CR_HORIZ_SYNC_PULSE_START
Definition: cirrus.c:22
@ VGA_CR_CURSOR_START
Definition: cirrus.c:28
@ VGA_CR_OVERFLOW
Definition: cirrus.c:25
@ VGA_CR_BYTE_PANNING
Definition: cirrus.c:26
@ VGA_CR_CELL_HEIGHT
Definition: cirrus.c:27
@ VGA_CR_HTOTAL
Definition: cirrus.c:18
@ VGA_CR_VDISPLAY_END
Definition: cirrus.c:36
@ VGA_CR_LINE_COMPARE
Definition: cirrus.c:42
@ VGA_CR_VERTICAL_BLANK_END
Definition: cirrus.c:40
@ VGA_CR_HBLANK_START
Definition: cirrus.c:20
@ VGA_CR_MODE
Definition: cirrus.c:41
@ VGA_CR_CURSOR_ADDR_LOW
Definition: cirrus.c:33
@ VGA_CR_MODE_NO_CGA
Definition: cirrus.c:85
@ VGA_CR_MODE_ADDRESS_WRAP
Definition: cirrus.c:87
@ VGA_CR_MODE_TIMING_ENABLE
Definition: cirrus.c:89
@ VGA_CR_MODE_BYTE_MODE
Definition: cirrus.c:88
@ VGA_CR_MODE_NO_HERCULES
Definition: cirrus.c:86
@ VGA_TEXT_ATTR_PLANE
Definition: cirrus.c:136
@ VGA_TEXT_FONT_PLANE
Definition: cirrus.c:137
@ VGA_TEXT_TEXT_PLANE
Definition: cirrus.c:135
#define VGA_CR_OVERFLOW_VSYNC_START2_SHIFT
Definition: cirrus.c:61
#define CIRRUS_HIDDEN_DAC_888COLOR
Definition: cirrus.c:171
static int height
Definition: cirrus.c:13
static void write_hidden_dac(uint8_t data)
Definition: cirrus.c:174
#define VGA_CR_OVERFLOW_VERT_TOTAL2_MASK
Definition: cirrus.c:57
#define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT
Definition: cirrus.c:159
#define VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_SHIFT
Definition: cirrus.c:49
static void cirrus_init_text_mode(struct device *dev)
Definition: cirrus.c:305
#define CIRRUS_CR_EXTENDED_DISPLAY_START_MASK2
Definition: cirrus.c:162
static const struct pci_driver qemu_cirrus_driver __pci_driver
Definition: cirrus.c:326
#define CIRRUS_SR_EXTENDED_MODE_32BPP
Definition: cirrus.c:170
#define CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK
Definition: cirrus.c:165
static struct device_operations qemu_cirrus_graph_ops
Definition: cirrus.c:319
static void cirrus_init_linear_fb(struct device *dev)
Definition: cirrus.c:184
#define VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK
Definition: cirrus.c:71
#define printk(level,...)
Definition: stdlib.h:16
u8 inb(u16 port)
void outb(u8 val, u16 port)
@ CONFIG
Definition: dsi_common.h:201
struct fb_info * fb_add_framebuffer_info(uintptr_t fb_addr, uint32_t x_resolution, uint32_t y_resolution, uint32_t bytes_per_line, uint8_t bits_per_pixel)
Definition: edid_fill_fb.c:89
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define PCI_BASE_ADDRESS_MEM_ATTR_MASK
Definition: pci_def.h:77
#define PCI_BASE_ADDRESS_0
Definition: pci_def.h:63
void pci_dev_enable_resources(struct device *dev)
Definition: pci_device.c:721
void pci_dev_read_resources(struct device *dev)
Definition: pci_device.c:534
void pci_dev_set_resources(struct device *dev)
Definition: pci_device.c:691
uint32_t u32
Definition: stdint.h:51
unsigned char uint8_t
Definition: stdint.h:8
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107
void vga_textmode_init(void)
Definition: vga.c:280
void vga_misc_write(unsigned char value)
Definition: vga_io.c:70
void vga_palette_disable(void)
Definition: vga_io.c:218
void vga_gr_write(unsigned char index, unsigned char value)
Definition: vga_io.c:189
void vga_cr_write(unsigned char index, unsigned char value)
Definition: vga_io.c:125
unsigned char vga_cr_read(unsigned char index)
Definition: vga_io.c:118
void vga_sr_write(unsigned char index, unsigned char value)
Definition: vga_io.c:97