]> Git Repo - qemu.git/blob - hw/display/ati.c
Include hw/hw.h exactly where needed
[qemu.git] / hw / display / ati.c
1 /*
2  * QEMU ATI SVGA emulation
3  *
4  * Copyright (c) 2019 BALATON Zoltan
5  *
6  * This work is licensed under the GNU GPL license version 2 or later.
7  */
8
9 /*
10  * WARNING:
11  * This is very incomplete and only enough for Linux console and some
12  * unaccelerated X output at the moment.
13  * Currently it's little more than a frame buffer with minimal functions,
14  * other more advanced features of the hardware are yet to be implemented.
15  * We only aim for Rage 128 Pro (and some RV100) and 2D only at first,
16  * No 3D at all yet (maybe after 2D works, but feel free to improve it)
17  */
18
19 #include "qemu/osdep.h"
20 #include "ati_int.h"
21 #include "ati_regs.h"
22 #include "vga_regs.h"
23 #include "qemu/log.h"
24 #include "qemu/module.h"
25 #include "qemu/error-report.h"
26 #include "qapi/error.h"
27 #include "ui/console.h"
28 #include "hw/display/i2c-ddc.h"
29 #include "trace.h"
30
31 #define ATI_DEBUG_HW_CURSOR 0
32
33 static const struct {
34     const char *name;
35     uint16_t dev_id;
36 } ati_model_aliases[] = {
37     { "rage128p", PCI_DEVICE_ID_ATI_RAGE128_PF },
38     { "rv100", PCI_DEVICE_ID_ATI_RADEON_QY },
39 };
40
41 enum { VGA_MODE, EXT_MODE };
42
43 static void ati_vga_switch_mode(ATIVGAState *s)
44 {
45     DPRINTF("%d -> %d\n",
46             s->mode, !!(s->regs.crtc_gen_cntl & CRTC2_EXT_DISP_EN));
47     if (s->regs.crtc_gen_cntl & CRTC2_EXT_DISP_EN) {
48         /* Extended mode enabled */
49         s->mode = EXT_MODE;
50         if (s->regs.crtc_gen_cntl & CRTC2_EN) {
51             /* CRT controller enabled, use CRTC values */
52             uint32_t offs = s->regs.crtc_offset & 0x07ffffff;
53             int stride = (s->regs.crtc_pitch & 0x7ff) * 8;
54             int bpp = 0;
55             int h, v;
56
57             if (s->regs.crtc_h_total_disp == 0) {
58                 s->regs.crtc_h_total_disp = ((640 / 8) - 1) << 16;
59             }
60             if (s->regs.crtc_v_total_disp == 0) {
61                 s->regs.crtc_v_total_disp = (480 - 1) << 16;
62             }
63             h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8;
64             v = (s->regs.crtc_v_total_disp >> 16) + 1;
65             switch (s->regs.crtc_gen_cntl & CRTC_PIX_WIDTH_MASK) {
66             case CRTC_PIX_WIDTH_4BPP:
67                 bpp = 4;
68                 break;
69             case CRTC_PIX_WIDTH_8BPP:
70                 bpp = 8;
71                 break;
72             case CRTC_PIX_WIDTH_15BPP:
73                 bpp = 15;
74                 break;
75             case CRTC_PIX_WIDTH_16BPP:
76                 bpp = 16;
77                 break;
78             case CRTC_PIX_WIDTH_24BPP:
79                 bpp = 24;
80                 break;
81             case CRTC_PIX_WIDTH_32BPP:
82                 bpp = 32;
83                 break;
84             default:
85                 qemu_log_mask(LOG_UNIMP, "Unsupported bpp value\n");
86             }
87             assert(bpp != 0);
88             DPRINTF("Switching to %dx%d %d %d @ %x\n", h, v, stride, bpp, offs);
89             vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE);
90             vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED);
91             s->vga.big_endian_fb = false;
92             /* reset VBE regs then set up mode */
93             s->vga.vbe_regs[VBE_DISPI_INDEX_XRES] = h;
94             s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] = v;
95             s->vga.vbe_regs[VBE_DISPI_INDEX_BPP] = bpp;
96             /* enable mode via ioport so it updates vga regs */
97             vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE);
98             vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_ENABLED |
99                 VBE_DISPI_LFB_ENABLED | VBE_DISPI_NOCLEARMEM |
100                 (s->regs.dac_cntl & DAC_8BIT_EN ? VBE_DISPI_8BIT_DAC : 0));
101             /* now set offset and stride after enable as that resets these */
102             if (stride) {
103                 vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_VIRT_WIDTH);
104                 vbe_ioport_write_data(&s->vga, 0, stride);
105                 if (offs % stride == 0) {
106                     vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_Y_OFFSET);
107                     vbe_ioport_write_data(&s->vga, 0, offs / stride);
108                 } else {
109                     /* FIXME what to do with this? */
110                     error_report("VGA offset is not multiple of pitch, "
111                                  "expect bad picture");
112                 }
113             }
114         }
115     } else {
116         /* VGA mode enabled */
117         s->mode = VGA_MODE;
118         vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE);
119         vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED);
120     }
121 }
122
123 /* Used by host side hardware cursor */
124 static void ati_cursor_define(ATIVGAState *s)
125 {
126     uint8_t data[1024];
127     uint8_t *src;
128     int i, j, idx = 0;
129
130     if ((s->regs.cur_offset & BIT(31)) || s->cursor_guest_mode) {
131         return; /* Do not update cursor if locked or rendered by guest */
132     }
133     /* FIXME handle cur_hv_offs correctly */
134     src = s->vga.vram_ptr + (s->regs.crtc_offset & 0x07ffffff) +
135           s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) -
136           (s->regs.cur_hv_offs & 0xffff) * 16;
137     for (i = 0; i < 64; i++) {
138         for (j = 0; j < 8; j++, idx++) {
139             data[idx] = src[i * 16 + j];
140             data[512 + idx] = src[i * 16 + j + 8];
141         }
142     }
143     if (!s->cursor) {
144         s->cursor = cursor_alloc(64, 64);
145     }
146     cursor_set_mono(s->cursor, s->regs.cur_color1, s->regs.cur_color0,
147                     &data[512], 1, &data[0]);
148     dpy_cursor_define(s->vga.con, s->cursor);
149 }
150
151 /* Alternatively support guest rendered hardware cursor */
152 static void ati_cursor_invalidate(VGACommonState *vga)
153 {
154     ATIVGAState *s = container_of(vga, ATIVGAState, vga);
155     int size = (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) ? 64 : 0;
156
157     if (s->regs.cur_offset & BIT(31)) {
158         return; /* Do not update cursor if locked */
159     }
160     if (s->cursor_size != size ||
161         vga->hw_cursor_x != s->regs.cur_hv_pos >> 16 ||
162         vga->hw_cursor_y != (s->regs.cur_hv_pos & 0xffff) ||
163         s->cursor_offset != s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) -
164         (s->regs.cur_hv_offs & 0xffff) * 16) {
165         /* Remove old cursor then update and show new one if needed */
166         vga_invalidate_scanlines(vga, vga->hw_cursor_y, vga->hw_cursor_y + 63);
167         vga->hw_cursor_x = s->regs.cur_hv_pos >> 16;
168         vga->hw_cursor_y = s->regs.cur_hv_pos & 0xffff;
169         s->cursor_offset = s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) -
170                            (s->regs.cur_hv_offs & 0xffff) * 16;
171         s->cursor_size = size;
172         if (size) {
173             vga_invalidate_scanlines(vga,
174                                      vga->hw_cursor_y, vga->hw_cursor_y + 63);
175         }
176     }
177 }
178
179 static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
180 {
181     ATIVGAState *s = container_of(vga, ATIVGAState, vga);
182     uint8_t *src;
183     uint32_t *dp = (uint32_t *)d;
184     int i, j, h;
185
186     if (!(s->regs.crtc_gen_cntl & CRTC2_CUR_EN) ||
187         scr_y < vga->hw_cursor_y || scr_y >= vga->hw_cursor_y + 64 ||
188         scr_y > s->regs.crtc_v_total_disp >> 16) {
189         return;
190     }
191     /* FIXME handle cur_hv_offs correctly */
192     src = s->vga.vram_ptr + (s->regs.crtc_offset & 0x07ffffff) +
193           s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16;
194     dp = &dp[vga->hw_cursor_x];
195     h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8;
196     for (i = 0; i < 8; i++) {
197         uint32_t color;
198         uint8_t abits = src[i];
199         uint8_t xbits = src[i + 8];
200         for (j = 0; j < 8; j++, abits <<= 1, xbits <<= 1) {
201             if (abits & BIT(7)) {
202                 if (xbits & BIT(7)) {
203                     color = dp[i * 8 + j] ^ 0xffffffff; /* complement */
204                 } else {
205                     continue; /* transparent, no change */
206                 }
207             } else {
208                 color = (xbits & BIT(7) ? s->regs.cur_color1 :
209                                           s->regs.cur_color0) << 8 | 0xff;
210             }
211             if (vga->hw_cursor_x + i * 8 + j >= h) {
212                 return; /* end of screen, don't span to next line */
213             }
214             dp[i * 8 + j] = color;
215         }
216     }
217 }
218
219 static uint64_t ati_i2c(bitbang_i2c_interface *i2c, uint64_t data, int base)
220 {
221     bool c = (data & BIT(base + 17) ? !!(data & BIT(base + 1)) : 1);
222     bool d = (data & BIT(base + 16) ? !!(data & BIT(base)) : 1);
223
224     bitbang_i2c_set(i2c, BITBANG_I2C_SCL, c);
225     d = bitbang_i2c_set(i2c, BITBANG_I2C_SDA, d);
226
227     data &= ~0xf00ULL;
228     if (c) {
229         data |= BIT(base + 9);
230     }
231     if (d) {
232         data |= BIT(base + 8);
233     }
234     return data;
235 }
236
237 static inline uint64_t ati_reg_read_offs(uint32_t reg, int offs,
238                                          unsigned int size)
239 {
240     if (offs == 0 && size == 4) {
241         return reg;
242     } else {
243         return extract32(reg, offs * BITS_PER_BYTE, size * BITS_PER_BYTE);
244     }
245 }
246
247 static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
248 {
249     ATIVGAState *s = opaque;
250     uint64_t val = 0;
251
252     switch (addr) {
253     case MM_INDEX:
254         val = s->regs.mm_index;
255         break;
256     case MM_DATA ... MM_DATA + 3:
257         /* indexed access to regs or memory */
258         if (s->regs.mm_index & BIT(31)) {
259             uint32_t idx = s->regs.mm_index & ~BIT(31);
260             if (idx <= s->vga.vram_size - size) {
261                 val = ldn_le_p(s->vga.vram_ptr + idx, size);
262             }
263         } else {
264             val = ati_mm_read(s, s->regs.mm_index + addr - MM_DATA, size);
265         }
266         break;
267     case BIOS_0_SCRATCH ... BUS_CNTL - 1:
268     {
269         int i = (addr - BIOS_0_SCRATCH) / 4;
270         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF && i > 3) {
271             break;
272         }
273         val = ati_reg_read_offs(s->regs.bios_scratch[i],
274                                 addr - (BIOS_0_SCRATCH + i * 4), size);
275         break;
276     }
277     case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3:
278         val = ati_reg_read_offs(s->regs.crtc_gen_cntl,
279                                 addr - CRTC_GEN_CNTL, size);
280         break;
281     case CRTC_EXT_CNTL ... CRTC_EXT_CNTL + 3:
282         val = ati_reg_read_offs(s->regs.crtc_ext_cntl,
283                                 addr - CRTC_EXT_CNTL, size);
284         break;
285     case DAC_CNTL:
286         val = s->regs.dac_cntl;
287         break;
288     case GPIO_VGA_DDC:
289         val = s->regs.gpio_vga_ddc;
290         break;
291     case GPIO_DVI_DDC:
292         val = s->regs.gpio_dvi_ddc;
293         break;
294     case GPIO_MONID ... GPIO_MONID + 3:
295         val = ati_reg_read_offs(s->regs.gpio_monid,
296                                 addr - GPIO_MONID, size);
297         break;
298     case PALETTE_INDEX:
299         /* FIXME unaligned access */
300         val = vga_ioport_read(&s->vga, VGA_PEL_IR) << 16;
301         val |= vga_ioport_read(&s->vga, VGA_PEL_IW) & 0xff;
302         break;
303     case PALETTE_DATA:
304         val = vga_ioport_read(&s->vga, VGA_PEL_D);
305         break;
306     case CNFG_MEMSIZE:
307         val = s->vga.vram_size;
308         break;
309     case MC_STATUS:
310         val = 5;
311         break;
312     case RBBM_STATUS:
313     case GUI_STAT:
314         val = 64; /* free CMDFIFO entries */
315         break;
316     case CRTC_H_TOTAL_DISP:
317         val = s->regs.crtc_h_total_disp;
318         break;
319     case CRTC_H_SYNC_STRT_WID:
320         val = s->regs.crtc_h_sync_strt_wid;
321         break;
322     case CRTC_V_TOTAL_DISP:
323         val = s->regs.crtc_v_total_disp;
324         break;
325     case CRTC_V_SYNC_STRT_WID:
326         val = s->regs.crtc_v_sync_strt_wid;
327         break;
328     case CRTC_OFFSET:
329         val = s->regs.crtc_offset;
330         break;
331     case CRTC_OFFSET_CNTL:
332         val = s->regs.crtc_offset_cntl;
333         break;
334     case CRTC_PITCH:
335         val = s->regs.crtc_pitch;
336         break;
337     case 0xf00 ... 0xfff:
338         val = pci_default_read_config(&s->dev, addr - 0xf00, size);
339         break;
340     case CUR_OFFSET:
341         val = s->regs.cur_offset;
342         break;
343     case CUR_HORZ_VERT_POSN:
344         val = s->regs.cur_hv_pos;
345         val |= s->regs.cur_offset & BIT(31);
346         break;
347     case CUR_HORZ_VERT_OFF:
348         val = s->regs.cur_hv_offs;
349         val |= s->regs.cur_offset & BIT(31);
350         break;
351     case CUR_CLR0:
352         val = s->regs.cur_color0;
353         break;
354     case CUR_CLR1:
355         val = s->regs.cur_color1;
356         break;
357     case DST_OFFSET:
358         val = s->regs.dst_offset;
359         break;
360     case DST_PITCH:
361         val = s->regs.dst_pitch;
362         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
363             val &= s->regs.dst_tile << 16;
364         }
365         break;
366     case DST_WIDTH:
367         val = s->regs.dst_width;
368         break;
369     case DST_HEIGHT:
370         val = s->regs.dst_height;
371         break;
372     case SRC_X:
373         val = s->regs.src_x;
374         break;
375     case SRC_Y:
376         val = s->regs.src_y;
377         break;
378     case DST_X:
379         val = s->regs.dst_x;
380         break;
381     case DST_Y:
382         val = s->regs.dst_y;
383         break;
384     case DP_GUI_MASTER_CNTL:
385         val = s->regs.dp_gui_master_cntl;
386         break;
387     case SRC_OFFSET:
388         val = s->regs.src_offset;
389         break;
390     case SRC_PITCH:
391         val = s->regs.src_pitch;
392         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
393             val &= s->regs.src_tile << 16;
394         }
395         break;
396     case DP_BRUSH_BKGD_CLR:
397         val = s->regs.dp_brush_bkgd_clr;
398         break;
399     case DP_BRUSH_FRGD_CLR:
400         val = s->regs.dp_brush_frgd_clr;
401         break;
402     case DP_SRC_FRGD_CLR:
403         val = s->regs.dp_src_frgd_clr;
404         break;
405     case DP_SRC_BKGD_CLR:
406         val = s->regs.dp_src_bkgd_clr;
407         break;
408     case DP_CNTL:
409         val = s->regs.dp_cntl;
410         break;
411     case DP_DATATYPE:
412         val = s->regs.dp_datatype;
413         break;
414     case DP_MIX:
415         val = s->regs.dp_mix;
416         break;
417     case DP_WRITE_MASK:
418         val = s->regs.dp_write_mask;
419         break;
420     case DEFAULT_OFFSET:
421         val = s->regs.default_offset;
422         if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
423             val >>= 10;
424             val |= s->regs.default_pitch << 16;
425             val |= s->regs.default_tile << 30;
426         }
427         break;
428     case DEFAULT_PITCH:
429         val = s->regs.default_pitch;
430         val |= s->regs.default_tile << 16;
431         break;
432     case DEFAULT_SC_BOTTOM_RIGHT:
433         val = s->regs.default_sc_bottom_right;
434         break;
435     default:
436         break;
437     }
438     if (addr < CUR_OFFSET || addr > CUR_CLR1 || ATI_DEBUG_HW_CURSOR) {
439         trace_ati_mm_read(size, addr, ati_reg_name(addr & ~3ULL), val);
440     }
441     return val;
442 }
443
444 static inline void ati_reg_write_offs(uint32_t *reg, int offs,
445                                       uint64_t data, unsigned int size)
446 {
447     if (offs == 0 && size == 4) {
448         *reg = data;
449     } else {
450         *reg = deposit32(*reg, offs * BITS_PER_BYTE, size * BITS_PER_BYTE,
451                          data);
452     }
453 }
454
455 static void ati_mm_write(void *opaque, hwaddr addr,
456                            uint64_t data, unsigned int size)
457 {
458     ATIVGAState *s = opaque;
459
460     if (addr < CUR_OFFSET || addr > CUR_CLR1 || ATI_DEBUG_HW_CURSOR) {
461         trace_ati_mm_write(size, addr, ati_reg_name(addr & ~3ULL), data);
462     }
463     switch (addr) {
464     case MM_INDEX:
465         s->regs.mm_index = data;
466         break;
467     case MM_DATA ... MM_DATA + 3:
468         /* indexed access to regs or memory */
469         if (s->regs.mm_index & BIT(31)) {
470             uint32_t idx = s->regs.mm_index & ~BIT(31);
471             if (idx <= s->vga.vram_size - size) {
472                 stn_le_p(s->vga.vram_ptr + idx, size, data);
473             }
474         } else {
475             ati_mm_write(s, s->regs.mm_index + addr - MM_DATA, data, size);
476         }
477         break;
478     case BIOS_0_SCRATCH ... BUS_CNTL - 1:
479     {
480         int i = (addr - BIOS_0_SCRATCH) / 4;
481         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF && i > 3) {
482             break;
483         }
484         ati_reg_write_offs(&s->regs.bios_scratch[i],
485                            addr - (BIOS_0_SCRATCH + i * 4), data, size);
486         break;
487     }
488     case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3:
489     {
490         uint32_t val = s->regs.crtc_gen_cntl;
491         ati_reg_write_offs(&s->regs.crtc_gen_cntl,
492                            addr - CRTC_GEN_CNTL, data, size);
493         if ((val & CRTC2_CUR_EN) != (s->regs.crtc_gen_cntl & CRTC2_CUR_EN)) {
494             if (s->cursor_guest_mode) {
495                 s->vga.force_shadow = !!(s->regs.crtc_gen_cntl & CRTC2_CUR_EN);
496             } else {
497                 if (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) {
498                     ati_cursor_define(s);
499                 }
500                 dpy_mouse_set(s->vga.con, s->regs.cur_hv_pos >> 16,
501                               s->regs.cur_hv_pos & 0xffff,
502                               (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) != 0);
503             }
504         }
505         if ((val & (CRTC2_EXT_DISP_EN | CRTC2_EN)) !=
506             (s->regs.crtc_gen_cntl & (CRTC2_EXT_DISP_EN | CRTC2_EN))) {
507             ati_vga_switch_mode(s);
508         }
509         break;
510     }
511     case CRTC_EXT_CNTL ... CRTC_EXT_CNTL + 3:
512     {
513         uint32_t val = s->regs.crtc_ext_cntl;
514         ati_reg_write_offs(&s->regs.crtc_ext_cntl,
515                            addr - CRTC_EXT_CNTL, data, size);
516         if (s->regs.crtc_ext_cntl & CRT_CRTC_DISPLAY_DIS) {
517             DPRINTF("Display disabled\n");
518             s->vga.ar_index &= ~BIT(5);
519         } else {
520             DPRINTF("Display enabled\n");
521             s->vga.ar_index |= BIT(5);
522             ati_vga_switch_mode(s);
523         }
524         if ((val & CRT_CRTC_DISPLAY_DIS) !=
525             (s->regs.crtc_ext_cntl & CRT_CRTC_DISPLAY_DIS)) {
526             ati_vga_switch_mode(s);
527         }
528         break;
529     }
530     case DAC_CNTL:
531         s->regs.dac_cntl = data & 0xffffe3ff;
532         s->vga.dac_8bit = !!(data & DAC_8BIT_EN);
533         break;
534     case GPIO_VGA_DDC:
535         if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
536             /* FIXME: Maybe add a property to select VGA or DVI port? */
537         }
538         break;
539     case GPIO_DVI_DDC:
540         if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
541             s->regs.gpio_dvi_ddc = ati_i2c(&s->bbi2c, data, 0);
542         }
543         break;
544     case GPIO_MONID ... GPIO_MONID + 3:
545         /* FIXME What does Radeon have here? */
546         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
547             ati_reg_write_offs(&s->regs.gpio_monid,
548                                addr - GPIO_MONID, data, size);
549             /*
550              * Rage128p accesses DDC used to get EDID via these bits.
551              * Only touch i2c when write overlaps 3rd byte because some
552              * drivers access this reg via multiple partial writes and
553              * without this spurious bits would be sent.
554              */
555             if ((s->regs.gpio_monid & BIT(25)) &&
556                 addr <= GPIO_MONID + 2 && addr + size > GPIO_MONID + 2) {
557                 s->regs.gpio_monid = ati_i2c(&s->bbi2c, s->regs.gpio_monid, 1);
558             }
559         }
560         break;
561     case PALETTE_INDEX ... PALETTE_INDEX + 3:
562         if (size == 4) {
563             vga_ioport_write(&s->vga, VGA_PEL_IR, (data >> 16) & 0xff);
564             vga_ioport_write(&s->vga, VGA_PEL_IW, data & 0xff);
565         } else {
566             if (addr == PALETTE_INDEX) {
567                 vga_ioport_write(&s->vga, VGA_PEL_IW, data & 0xff);
568             } else {
569                 vga_ioport_write(&s->vga, VGA_PEL_IR, data & 0xff);
570             }
571         }
572         break;
573     case PALETTE_DATA ... PALETTE_DATA + 3:
574         data <<= addr - PALETTE_DATA;
575         data = bswap32(data) >> 8;
576         vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff);
577         data >>= 8;
578         vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff);
579         data >>= 8;
580         vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff);
581         break;
582     case CRTC_H_TOTAL_DISP:
583         s->regs.crtc_h_total_disp = data & 0x07ff07ff;
584         break;
585     case CRTC_H_SYNC_STRT_WID:
586         s->regs.crtc_h_sync_strt_wid = data & 0x17bf1fff;
587         break;
588     case CRTC_V_TOTAL_DISP:
589         s->regs.crtc_v_total_disp = data & 0x0fff0fff;
590         break;
591     case CRTC_V_SYNC_STRT_WID:
592         s->regs.crtc_v_sync_strt_wid = data & 0x9f0fff;
593         break;
594     case CRTC_OFFSET:
595         s->regs.crtc_offset = data & 0xc7ffffff;
596         break;
597     case CRTC_OFFSET_CNTL:
598         s->regs.crtc_offset_cntl = data; /* FIXME */
599         break;
600     case CRTC_PITCH:
601         s->regs.crtc_pitch = data & 0x07ff07ff;
602         break;
603     case 0xf00 ... 0xfff:
604         /* read-only copy of PCI config space so ignore writes */
605         break;
606     case CUR_OFFSET:
607         if (s->regs.cur_offset != (data & 0x87fffff0)) {
608             s->regs.cur_offset = data & 0x87fffff0;
609             ati_cursor_define(s);
610         }
611         break;
612     case CUR_HORZ_VERT_POSN:
613         s->regs.cur_hv_pos = data & 0x3fff0fff;
614         if (data & BIT(31)) {
615             s->regs.cur_offset |= data & BIT(31);
616         } else if (s->regs.cur_offset & BIT(31)) {
617             s->regs.cur_offset &= ~BIT(31);
618             ati_cursor_define(s);
619         }
620         if (!s->cursor_guest_mode &&
621             (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) && !(data & BIT(31))) {
622             dpy_mouse_set(s->vga.con, s->regs.cur_hv_pos >> 16,
623                           s->regs.cur_hv_pos & 0xffff, 1);
624         }
625         break;
626     case CUR_HORZ_VERT_OFF:
627         s->regs.cur_hv_offs = data & 0x3f003f;
628         if (data & BIT(31)) {
629             s->regs.cur_offset |= data & BIT(31);
630         } else if (s->regs.cur_offset & BIT(31)) {
631             s->regs.cur_offset &= ~BIT(31);
632             ati_cursor_define(s);
633         }
634         break;
635     case CUR_CLR0:
636         if (s->regs.cur_color0 != (data & 0xffffff)) {
637             s->regs.cur_color0 = data & 0xffffff;
638             ati_cursor_define(s);
639         }
640         break;
641     case CUR_CLR1:
642         /*
643          * Update cursor unconditionally here because some clients set up
644          * other registers before actually writing cursor data to memory at
645          * offset so we would miss cursor change unless always updating here
646          */
647         s->regs.cur_color1 = data & 0xffffff;
648         ati_cursor_define(s);
649         break;
650     case DST_OFFSET:
651         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
652             s->regs.dst_offset = data & 0xfffffff0;
653         } else {
654             s->regs.dst_offset = data & 0xfffffc00;
655         }
656         break;
657     case DST_PITCH:
658         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
659             s->regs.dst_pitch = data & 0x3fff;
660             s->regs.dst_tile = (data >> 16) & 1;
661         } else {
662             s->regs.dst_pitch = data & 0x3ff0;
663         }
664         break;
665     case DST_TILE:
666         if (s->dev_id == PCI_DEVICE_ID_ATI_RADEON_QY) {
667             s->regs.dst_tile = data & 3;
668         }
669         break;
670     case DST_WIDTH:
671         s->regs.dst_width = data & 0x3fff;
672         ati_2d_blt(s);
673         break;
674     case DST_HEIGHT:
675         s->regs.dst_height = data & 0x3fff;
676         break;
677     case SRC_X:
678         s->regs.src_x = data & 0x3fff;
679         break;
680     case SRC_Y:
681         s->regs.src_y = data & 0x3fff;
682         break;
683     case DST_X:
684         s->regs.dst_x = data & 0x3fff;
685         break;
686     case DST_Y:
687         s->regs.dst_y = data & 0x3fff;
688         break;
689     case SRC_PITCH_OFFSET:
690         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
691             s->regs.src_offset = (data & 0x1fffff) << 5;
692             s->regs.src_pitch = (data & 0x7fe00000) >> 21;
693             s->regs.src_tile = data >> 31;
694         } else {
695             s->regs.src_offset = (data & 0x3fffff) << 10;
696             s->regs.src_pitch = (data & 0x3fc00000) >> 16;
697             s->regs.src_tile = (data >> 30) & 1;
698         }
699         break;
700     case DST_PITCH_OFFSET:
701         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
702             s->regs.dst_offset = (data & 0x1fffff) << 5;
703             s->regs.dst_pitch = (data & 0x7fe00000) >> 21;
704             s->regs.dst_tile = data >> 31;
705         } else {
706             s->regs.dst_offset = (data & 0x3fffff) << 10;
707             s->regs.dst_pitch = (data & 0x3fc00000) >> 16;
708             s->regs.dst_tile = data >> 30;
709         }
710         break;
711     case SRC_Y_X:
712         s->regs.src_x = data & 0x3fff;
713         s->regs.src_y = (data >> 16) & 0x3fff;
714         break;
715     case DST_Y_X:
716         s->regs.dst_x = data & 0x3fff;
717         s->regs.dst_y = (data >> 16) & 0x3fff;
718         break;
719     case DST_HEIGHT_WIDTH:
720         s->regs.dst_width = data & 0x3fff;
721         s->regs.dst_height = (data >> 16) & 0x3fff;
722         ati_2d_blt(s);
723         break;
724     case DP_GUI_MASTER_CNTL:
725         s->regs.dp_gui_master_cntl = data & 0xf800000f;
726         s->regs.dp_datatype = (data & 0x0f00) >> 8 | (data & 0x30f0) << 4 |
727                               (data & 0x4000) << 16;
728         s->regs.dp_mix = (data & GMC_ROP3_MASK) | (data & 0x7000000) >> 16;
729         break;
730     case DST_WIDTH_X:
731         s->regs.dst_x = data & 0x3fff;
732         s->regs.dst_width = (data >> 16) & 0x3fff;
733         ati_2d_blt(s);
734         break;
735     case SRC_X_Y:
736         s->regs.src_y = data & 0x3fff;
737         s->regs.src_x = (data >> 16) & 0x3fff;
738         break;
739     case DST_X_Y:
740         s->regs.dst_y = data & 0x3fff;
741         s->regs.dst_x = (data >> 16) & 0x3fff;
742         break;
743     case DST_WIDTH_HEIGHT:
744         s->regs.dst_height = data & 0x3fff;
745         s->regs.dst_width = (data >> 16) & 0x3fff;
746         ati_2d_blt(s);
747         break;
748     case DST_HEIGHT_Y:
749         s->regs.dst_y = data & 0x3fff;
750         s->regs.dst_height = (data >> 16) & 0x3fff;
751         break;
752     case SRC_OFFSET:
753         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
754             s->regs.src_offset = data & 0xfffffff0;
755         } else {
756             s->regs.src_offset = data & 0xfffffc00;
757         }
758         break;
759     case SRC_PITCH:
760         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
761             s->regs.src_pitch = data & 0x3fff;
762             s->regs.src_tile = (data >> 16) & 1;
763         } else {
764             s->regs.src_pitch = data & 0x3ff0;
765         }
766         break;
767     case DP_BRUSH_BKGD_CLR:
768         s->regs.dp_brush_bkgd_clr = data;
769         break;
770     case DP_BRUSH_FRGD_CLR:
771         s->regs.dp_brush_frgd_clr = data;
772         break;
773     case DP_CNTL:
774         s->regs.dp_cntl = data;
775         break;
776     case DP_DATATYPE:
777         s->regs.dp_datatype = data & 0xe0070f0f;
778         break;
779     case DP_MIX:
780         s->regs.dp_mix = data & 0x00ff0700;
781         break;
782     case DP_WRITE_MASK:
783         s->regs.dp_write_mask = data;
784         break;
785     case DEFAULT_OFFSET:
786         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
787             s->regs.default_offset = data & 0xfffffff0;
788         } else {
789             /* Radeon has DEFAULT_PITCH_OFFSET here like DST_PITCH_OFFSET */
790             s->regs.default_offset = (data & 0x3fffff) << 10;
791             s->regs.default_pitch = (data & 0x3fc00000) >> 16;
792             s->regs.default_tile = data >> 30;
793         }
794         break;
795     case DEFAULT_PITCH:
796         if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
797             s->regs.default_pitch = data & 0x3fff;
798             s->regs.default_tile = (data >> 16) & 1;
799         }
800         break;
801     case DEFAULT_SC_BOTTOM_RIGHT:
802         s->regs.default_sc_bottom_right = data & 0x3fff3fff;
803         break;
804     default:
805         break;
806     }
807 }
808
809 static const MemoryRegionOps ati_mm_ops = {
810     .read = ati_mm_read,
811     .write = ati_mm_write,
812     .endianness = DEVICE_LITTLE_ENDIAN,
813 };
814
815 static void ati_vga_realize(PCIDevice *dev, Error **errp)
816 {
817     ATIVGAState *s = ATI_VGA(dev);
818     VGACommonState *vga = &s->vga;
819
820     if (s->model) {
821         int i;
822         for (i = 0; i < ARRAY_SIZE(ati_model_aliases); i++) {
823             if (!strcmp(s->model, ati_model_aliases[i].name)) {
824                 s->dev_id = ati_model_aliases[i].dev_id;
825                 break;
826             }
827         }
828         if (i >= ARRAY_SIZE(ati_model_aliases)) {
829             warn_report("Unknown ATI VGA model name, "
830                         "using default rage128p");
831         }
832     }
833     if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF &&
834         s->dev_id != PCI_DEVICE_ID_ATI_RADEON_QY) {
835         error_setg(errp, "Unknown ATI VGA device id, "
836                    "only 0x5046 and 0x5159 are supported");
837         return;
838     }
839     pci_set_word(dev->config + PCI_DEVICE_ID, s->dev_id);
840
841     if (s->dev_id == PCI_DEVICE_ID_ATI_RADEON_QY &&
842         s->vga.vram_size_mb < 16) {
843         warn_report("Too small video memory for device id");
844         s->vga.vram_size_mb = 16;
845     }
846
847     /* init vga bits */
848     vga_common_init(vga, OBJECT(s));
849     vga_init(vga, OBJECT(s), pci_address_space(dev),
850              pci_address_space_io(dev), true);
851     vga->con = graphic_console_init(DEVICE(s), 0, s->vga.hw_ops, &s->vga);
852     if (s->cursor_guest_mode) {
853         vga->cursor_invalidate = ati_cursor_invalidate;
854         vga->cursor_draw_line = ati_cursor_draw_line;
855     }
856
857     /* ddc, edid */
858     I2CBus *i2cbus = i2c_init_bus(DEVICE(s), "ati-vga.ddc");
859     bitbang_i2c_init(&s->bbi2c, i2cbus);
860     I2CSlave *i2cddc = I2C_SLAVE(qdev_create(BUS(i2cbus), TYPE_I2CDDC));
861     i2c_set_slave_address(i2cddc, 0x50);
862
863     /* mmio register space */
864     memory_region_init_io(&s->mm, OBJECT(s), &ati_mm_ops, s,
865                           "ati.mmregs", 0x4000);
866     /* io space is alias to beginning of mmregs */
867     memory_region_init_alias(&s->io, OBJECT(s), "ati.io", &s->mm, 0, 0x100);
868
869     pci_register_bar(dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram);
870     pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
871     pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mm);
872 }
873
874 static void ati_vga_reset(DeviceState *dev)
875 {
876     ATIVGAState *s = ATI_VGA(dev);
877
878     /* reset vga */
879     vga_common_reset(&s->vga);
880     s->mode = VGA_MODE;
881 }
882
883 static void ati_vga_exit(PCIDevice *dev)
884 {
885     ATIVGAState *s = ATI_VGA(dev);
886
887     graphic_console_close(s->vga.con);
888 }
889
890 static Property ati_vga_properties[] = {
891     DEFINE_PROP_UINT32("vgamem_mb", ATIVGAState, vga.vram_size_mb, 16),
892     DEFINE_PROP_STRING("model", ATIVGAState, model),
893     DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id,
894                        PCI_DEVICE_ID_ATI_RAGE128_PF),
895     DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, false),
896     DEFINE_PROP_END_OF_LIST()
897 };
898
899 static void ati_vga_class_init(ObjectClass *klass, void *data)
900 {
901     DeviceClass *dc = DEVICE_CLASS(klass);
902     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
903
904     dc->reset = ati_vga_reset;
905     dc->props = ati_vga_properties;
906     dc->hotpluggable = false;
907     set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
908
909     k->class_id = PCI_CLASS_DISPLAY_VGA;
910     k->vendor_id = PCI_VENDOR_ID_ATI;
911     k->device_id = PCI_DEVICE_ID_ATI_RAGE128_PF;
912     k->romfile = "vgabios-ati.bin";
913     k->realize = ati_vga_realize;
914     k->exit = ati_vga_exit;
915 }
916
917 static const TypeInfo ati_vga_info = {
918     .name = TYPE_ATI_VGA,
919     .parent = TYPE_PCI_DEVICE,
920     .instance_size = sizeof(ATIVGAState),
921     .class_init = ati_vga_class_init,
922     .interfaces = (InterfaceInfo[]) {
923           { INTERFACE_CONVENTIONAL_PCI_DEVICE },
924           { },
925     },
926 };
927
928 static void ati_vga_register_types(void)
929 {
930     type_register_static(&ati_vga_info);
931 }
932
933 type_init(ati_vga_register_types)
This page took 0.074763 seconds and 4 git commands to generate.