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