*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "qemu/log.h"
+#include "qemu/module.h"
#include "hw/display/xlnx_dp.h"
+#include "hw/irq.h"
+#include "migration/vmstate.h"
#ifndef DEBUG_DP
#define DEBUG_DP 0
if (DEBUG_DP) { \
qemu_log("xlnx_dp: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/*
* Register offset for DP.
written = AUD_write(s->amixer_output_stream,
&s->out_buffer[s->data_ptr], s->byte_left);
} else {
+ int len_to_copy;
/*
* There is nothing to play.. We don't have any data! Fill the
* buffer with zero's and send it.
*/
written = 0;
- memset(s->out_buffer, 0, 1024);
- AUD_write(s->amixer_output_stream, s->out_buffer, 1024);
+ while (avail) {
+ len_to_copy = MIN(AUD_CHBUF_MAX_DEPTH, avail);
+ memset(s->out_buffer, 0, len_to_copy);
+ avail -= AUD_write(s->amixer_output_stream, s->out_buffer,
+ len_to_copy);
+ }
}
} else {
written = AUD_write(s->amixer_output_stream,
uint8_t ret;
if (fifo8_is_empty(&s->rx_fifo)) {
- DPRINTF("rx_fifo underflow..\n");
- abort();
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Reading empty RX_FIFO\n",
+ __func__);
+ /*
+ * The datasheet is not clear about the reset value, it seems
+ * to be unspecified. We choose to return '0'.
+ */
+ ret = 0;
+ } else {
+ ret = fifo8_pop(&s->rx_fifo);
+ DPRINTF("pop 0x%" PRIX8 " from rx_fifo.\n", ret);
}
- ret = fifo8_pop(&s->rx_fifo);
- DPRINTF("pop 0x%" PRIX8 " from rx_fifo.\n", ret);
return ret;
}
s->core_registers[DP_INTERRUPT_SIGNAL_STATE] |= 0x04;
}
-static void xlnx_dp_set_dpdma(Object *obj, const char *name, Object *val,
+static void xlnx_dp_set_dpdma(const Object *obj, const char *name, Object *val,
Error **errp)
{
XlnxDPState *s = XLNX_DP(obj);
if ((width != 0) && (height != 0)) {
/*
* As dpy_gfx_replace_surface calls qemu_free_displaysurface on the
- * surface we need to be carefull and don't free the surface associated
+ * surface we need to be careful and don't free the surface associated
* to the console or double free will happen.
*/
if (s->bout_plane.surface != current_console_surface) {
case 0:
s->v_plane.format = PIXMAN_x8b8g8r8;
break;
+ case DP_NL_VID_Y0_CB_Y1_CR:
+ s->v_plane.format = PIXMAN_yuy2;
+ break;
case DP_NL_VID_RGBA8880:
s->v_plane.format = PIXMAN_x8b8g8r8;
break;
case AV_BUF_STC_SNAPSHOT1:
case AV_BUF_HCOUNT_VCOUNT_INT0:
case AV_BUF_HCOUNT_VCOUNT_INT1:
- qemu_log_mask(LOG_UNIMP, "avbufm: unimplmented");
+ qemu_log_mask(LOG_UNIMP, "avbufm: unimplemented register 0x%04"
+ PRIx64 "\n",
+ offset << 2);
break;
default:
s->avbufm_registers[offset] = value;
*/
if (!xlnx_dpdma_start_operation(s->dpdma, 3, false)) {
/*
- * An error occured don't do anything with the data..
+ * An error occurred don't do anything with the data..
* Trigger an underflow interrupt.
*/
s->core_registers[DP_INT_STATUS] |= (1 << 21);
/*
* XXX: We might want to update only what changed.
*/
- dpy_gfx_update(s->console, 0, 0, surface_width(s->g_plane.surface),
- surface_height(s->g_plane.surface));
+ dpy_gfx_update_full(s->console);
}
static const GraphicHwOps xlnx_dp_gfx_ops = {
object_property_add_link(obj, "dpdma", TYPE_XLNX_DPDMA,
(Object **) &s->dpdma,
xlnx_dp_set_dpdma,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
+ OBJ_PROP_LINK_STRONG);
/*
* Initialize AUX Bus.
/*
* Initialize DPCD and EDID..
*/
- s->dpcd = DPCD(aux_create_slave(s->aux_bus, "dpcd", 0x00000));
+ s->dpcd = DPCD(aux_create_slave(s->aux_bus, "dpcd"));
+ object_property_add_child(OBJECT(s), "dpcd", OBJECT(s->dpcd));
+
s->edid = I2CDDC(qdev_create(BUS(aux_get_i2c_bus(s->aux_bus)), "i2c-ddc"));
i2c_set_slave_address(I2C_SLAVE(s->edid), 0x50);
+ object_property_add_child(OBJECT(s), "edid", OBJECT(s->edid));
fifo8_create(&s->rx_fifo, 16);
fifo8_create(&s->tx_fifo, 16);
DisplaySurface *surface;
struct audsettings as;
+ qdev_init_nofail(DEVICE(s->dpcd));
+ aux_map_slave(AUX_SLAVE(s->dpcd), 0x0000);
+
s->console = graphic_console_init(dev, 0, &xlnx_dp_gfx_ops, s);
surface = qemu_console_surface(s->console);
xlnx_dpdma_set_host_data_location(s->dpdma, DP_GRAPHIC_DMA_CHANNEL,
as.freq = 44100;
as.nchannels = 2;
- as.fmt = AUD_FMT_S16;
+ as.fmt = AUDIO_FORMAT_S16;
as.endianness = 0;
AUD_register_card("xlnx_dp.audio", &s->aud_card);