drivers/virtio: add virtio gpu driver
This patch provides basic framebuffer display support for virtio. Multiple displays are supported. Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
This commit is contained in:
parent
fc354a1446
commit
78b993c4e8
5 changed files with 1290 additions and 0 deletions
|
@ -27,6 +27,12 @@ config DRIVERS_VIRTIO_BLK
|
|||
depends on !DISABLE_MOUNTPOINT
|
||||
default n
|
||||
|
||||
config DRIVERS_VIRTIO_GPU
|
||||
bool "Virtio gpu support"
|
||||
default n
|
||||
depends on VIDEO_FB
|
||||
select FB_UPDATE
|
||||
|
||||
config DRIVERS_VIRTIO_NET
|
||||
bool "Virtio network support"
|
||||
depends on NETDEVICES
|
||||
|
|
|
@ -32,6 +32,10 @@ ifeq ($(CONFIG_DRIVERS_VIRTIO_BLK),y)
|
|||
CSRCS += virtio-blk.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DRIVERS_VIRTIO_GPU),y)
|
||||
CSRCS += virtio-gpu.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DRIVERS_VIRTIO_NET),y)
|
||||
CSRCS += virtio-net.c
|
||||
endif
|
||||
|
|
741
drivers/virtio/virtio-gpu.c
Normal file
741
drivers/virtio/virtio-gpu.c
Normal file
|
@ -0,0 +1,741 @@
|
|||
/****************************************************************************
|
||||
* drivers/virtio/virtio-gpu.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/video/fb.h>
|
||||
#include <nuttx/virtio/virtio.h>
|
||||
|
||||
#include "virtio-gpu.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define VIRTIO_GPU_BPP 32
|
||||
#define VIRTIO_GPU_FB_FMT FB_FMT_RGB32
|
||||
#define VIRTIO_GPU_FMT VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM
|
||||
|
||||
#define VIRTIO_GPU_CTL 0
|
||||
#define VIRTIO_GPU_NUM 1
|
||||
|
||||
#define VIRTIO_GPU_MAX_DISP 4
|
||||
#define VIRTIO_GPU_MAX_PLANE 1
|
||||
#define VIRTIO_GPU_MAX_NENTS 4
|
||||
|
||||
#define VIRTIO_GPU_MAP_ERR(e) ((e) == VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY ? \
|
||||
-ENOMEM : -EINVAL)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct virtio_gpu_priv_s
|
||||
{
|
||||
struct fb_vtable_s vtable; /* Must be cast compatible with virtio_gpu_priv_s */
|
||||
FAR struct virtio_device *vdev; /* Contained virtio device */
|
||||
FAR uint8_t *fbmem; /* Allocated framebuffer */
|
||||
size_t fblen; /* Size of the framebuffer in bytes */
|
||||
fb_coord_t xres; /* Horizontal resolution in pixel columns */
|
||||
fb_coord_t yres; /* Vertical resolution in pixel rows */
|
||||
fb_coord_t stride; /* Width of a row in bytes */
|
||||
uint8_t display; /* Display number */
|
||||
};
|
||||
|
||||
struct virtio_gpu_cookie_s
|
||||
{
|
||||
bool blocking;
|
||||
FAR void *p;
|
||||
};
|
||||
|
||||
struct virtio_gpu_backing_s
|
||||
{
|
||||
struct virtio_gpu_resource_attach_backing cmd;
|
||||
struct virtio_gpu_mem_entry ents[VIRTIO_GPU_MAX_NENTS];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_send_cmd(FAR struct virtqueue *vq,
|
||||
FAR struct virtqueue_buf *buf_list,
|
||||
int readable, int writable, FAR void *cookie);
|
||||
static void virtio_gpu_done(FAR struct virtqueue *vq);
|
||||
static int virtio_gpu_init(FAR struct virtio_gpu_priv_s *priv,
|
||||
FAR struct virtio_device *vdev);
|
||||
static int virtio_gpu_get_display_info(FAR struct virtio_gpu_priv_s *priv);
|
||||
static int virtio_gpu_create_2d(FAR struct virtio_gpu_priv_s *priv,
|
||||
int resource_id, int width, int height);
|
||||
static int virtio_gpu_attach_backing(FAR struct virtio_gpu_priv_s *priv,
|
||||
int resource_id,
|
||||
FAR struct virtio_gpu_mem_entry *ents,
|
||||
uint32_t nents);
|
||||
static int virtio_gpu_set_scanout(FAR struct virtio_gpu_priv_s *priv,
|
||||
int scanout_id, int resource_id,
|
||||
int width, int height);
|
||||
static int virtio_gpu_transfer_to_host_2d(FAR struct virtio_gpu_priv_s *priv,
|
||||
int resource_id, int x, int y,
|
||||
int width, int height);
|
||||
static int virtio_gpu_flush_resource(FAR struct virtio_gpu_priv_s *priv,
|
||||
int resource_id, int x, int y,
|
||||
int width, int height);
|
||||
static int virtio_gpu_probe(FAR struct virtio_device *vdev);
|
||||
static void virtio_gpu_remove(FAR struct virtio_device *vdev);
|
||||
static int virtio_gpu_getvideoinfo(FAR struct fb_vtable_s *vtable,
|
||||
FAR struct fb_videoinfo_s *vinfo);
|
||||
static int virtio_gpu_getplaneinfo(FAR struct fb_vtable_s *vtable,
|
||||
int planeno,
|
||||
FAR struct fb_planeinfo_s *pinfo);
|
||||
static int virtio_gpu_updatearea(FAR struct fb_vtable_s *vtable,
|
||||
FAR const struct fb_area_s *area);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct virtio_driver g_virtio_gpu_driver =
|
||||
{
|
||||
.node = LIST_INITIAL_VALUE(g_virtio_gpu_driver.node), /* node */
|
||||
.device = VIRTIO_ID_GPU, /* device id */
|
||||
.probe = virtio_gpu_probe, /* probe */
|
||||
.remove = virtio_gpu_remove, /* remove */
|
||||
};
|
||||
|
||||
static FAR struct virtio_gpu_priv_s *g_virtio_gpu[VIRTIO_GPU_MAX_DISP];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_send_cmd
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_send_cmd(FAR struct virtqueue *vq,
|
||||
FAR struct virtqueue_buf *buf_list,
|
||||
int readable, int writable, FAR void *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (writable > 0)
|
||||
{
|
||||
sem_t sem;
|
||||
struct virtio_gpu_cookie_s cookie;
|
||||
|
||||
sem_init(&sem, 0, 0);
|
||||
cookie.blocking = true;
|
||||
cookie.p = &sem;
|
||||
ret = virtqueue_add_buffer(vq, buf_list, readable, writable, &cookie);
|
||||
if (ret >= 0)
|
||||
{
|
||||
virtqueue_kick(vq);
|
||||
sem_wait(&sem);
|
||||
}
|
||||
|
||||
sem_destroy(&sem);
|
||||
}
|
||||
else
|
||||
{
|
||||
FAR struct virtio_gpu_cookie_s *cookie;
|
||||
|
||||
cookie = kmm_malloc(sizeof(*cookie));
|
||||
if (cookie == NULL)
|
||||
{
|
||||
vrterr("ERROR: Failed to allocate cookie memory");
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
cookie->blocking = false;
|
||||
cookie->p = buf;
|
||||
ret = virtqueue_add_buffer(vq, buf_list, readable, writable,
|
||||
cookie);
|
||||
if (ret >= 0)
|
||||
{
|
||||
virtqueue_kick(vq);
|
||||
}
|
||||
else
|
||||
{
|
||||
virtio_free_buf(vq->vq_dev, buf);
|
||||
kmm_free(cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_done
|
||||
****************************************************************************/
|
||||
|
||||
static void virtio_gpu_done(FAR struct virtqueue *vq)
|
||||
{
|
||||
FAR struct virtio_gpu_cookie_s *cookie;
|
||||
|
||||
while ((cookie = virtqueue_get_buffer(vq, NULL, NULL)) != NULL)
|
||||
{
|
||||
if (cookie->blocking)
|
||||
{
|
||||
sem_post((FAR sem_t *)cookie->p);
|
||||
}
|
||||
else
|
||||
{
|
||||
virtio_free_buf(vq->vq_dev, cookie->p);
|
||||
kmm_free(cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_init
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_init(FAR struct virtio_gpu_priv_s *priv,
|
||||
FAR struct virtio_device *vdev)
|
||||
{
|
||||
FAR const char *vqnames[VIRTIO_GPU_NUM];
|
||||
vq_callback callbacks[VIRTIO_GPU_NUM];
|
||||
int ret;
|
||||
|
||||
priv->vdev = vdev;
|
||||
vdev->priv = priv;
|
||||
|
||||
/* Initialize the virtio device */
|
||||
|
||||
virtio_set_status(vdev, VIRTIO_CONFIG_STATUS_DRIVER);
|
||||
virtio_set_features(vdev, 0);
|
||||
virtio_set_status(vdev, VIRTIO_CONFIG_FEATURES_OK);
|
||||
|
||||
vqnames[VIRTIO_GPU_CTL] = "virtio_gpu_ctl";
|
||||
callbacks[VIRTIO_GPU_CTL] = virtio_gpu_done;
|
||||
ret = virtio_create_virtqueues(vdev, 0, VIRTIO_GPU_NUM, vqnames,
|
||||
callbacks);
|
||||
if (ret < 0)
|
||||
{
|
||||
vrterr("virtio_device_create_virtqueue failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtio_set_status(vdev, VIRTIO_CONFIG_STATUS_DRIVER_OK);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_get_display_info
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_get_display_info(FAR struct virtio_gpu_priv_s *priv)
|
||||
{
|
||||
FAR struct virtqueue *vq = priv->vdev->vrings_info[VIRTIO_GPU_CTL].vq;
|
||||
struct virtio_gpu_ctrl_hdr cmd;
|
||||
struct virtio_gpu_resp_display_info info;
|
||||
struct virtqueue_buf vb[2];
|
||||
int ret;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.type = VIRTIO_GPU_CMD_GET_DISPLAY_INFO;
|
||||
|
||||
vb[0].buf = &cmd;
|
||||
vb[0].len = sizeof(cmd);
|
||||
vb[1].buf = &info;
|
||||
vb[1].len = sizeof(info);
|
||||
|
||||
ret = virtio_gpu_send_cmd(vq, vb, 1, 1, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (info.hdr.type != VIRTIO_GPU_RESP_OK_DISPLAY_INFO)
|
||||
{
|
||||
return VIRTIO_GPU_MAP_ERR(info.hdr.type);
|
||||
}
|
||||
|
||||
priv->xres = info.pmodes[0].r.width;
|
||||
priv->yres = info.pmodes[0].r.height;
|
||||
vrtinfo("Setting resolution: (%d,%d)", priv->xres, priv->yres);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_create_2d
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_create_2d(FAR struct virtio_gpu_priv_s *priv,
|
||||
int resource_id, int width, int height)
|
||||
{
|
||||
FAR struct virtqueue *vq = priv->vdev->vrings_info[VIRTIO_GPU_CTL].vq;
|
||||
struct virtio_gpu_resource_create_2d cmd;
|
||||
struct virtio_gpu_ctrl_hdr resp;
|
||||
struct virtqueue_buf vb[2];
|
||||
int ret;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.type = VIRTIO_GPU_CMD_RESOURCE_CREATE_2D;
|
||||
cmd.resource_id = resource_id;
|
||||
cmd.format = VIRTIO_GPU_FMT;
|
||||
cmd.width = width;
|
||||
cmd.height = height;
|
||||
|
||||
vb[0].buf = &cmd;
|
||||
vb[0].len = sizeof(cmd);
|
||||
vb[1].buf = &resp;
|
||||
vb[1].len = sizeof(resp);
|
||||
|
||||
ret = virtio_gpu_send_cmd(vq, vb, 1, 1, NULL);
|
||||
if (ret >= 0 && resp.type != VIRTIO_GPU_RESP_OK_NODATA)
|
||||
{
|
||||
ret = VIRTIO_GPU_MAP_ERR(resp.type);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_attach_backing
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_attach_backing(FAR struct virtio_gpu_priv_s *priv,
|
||||
int resource_id,
|
||||
FAR struct virtio_gpu_mem_entry *ents,
|
||||
uint32_t nents)
|
||||
{
|
||||
FAR struct virtqueue *vq = priv->vdev->vrings_info[VIRTIO_GPU_CTL].vq;
|
||||
struct virtio_gpu_backing_s backing;
|
||||
struct virtio_gpu_ctrl_hdr resp;
|
||||
struct virtqueue_buf vb[2];
|
||||
size_t i;
|
||||
int ret;
|
||||
|
||||
if (nents > VIRTIO_GPU_MAX_NENTS)
|
||||
{
|
||||
vrterr("ERROR: Backing memory entries count %" PRId32 "exceeds %d",
|
||||
nents, VIRTIO_GPU_MAX_NENTS);
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
memset(&backing.cmd, 0, sizeof(backing.cmd));
|
||||
backing.cmd.hdr.type = VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING;
|
||||
backing.cmd.resource_id = resource_id;
|
||||
backing.cmd.nr_entries = nents;
|
||||
|
||||
for (i = 0; i < nents; i++)
|
||||
{
|
||||
backing.ents[i] = ents[i];
|
||||
}
|
||||
|
||||
vb[0].buf = &backing;
|
||||
vb[0].len = sizeof(backing.cmd) + nents * sizeof(backing.ents[0]);
|
||||
vb[1].buf = &resp;
|
||||
vb[1].len = sizeof(resp);
|
||||
|
||||
ret = virtio_gpu_send_cmd(vq, vb, 1, 1, NULL);
|
||||
if (ret >= 0 && resp.type != VIRTIO_GPU_RESP_OK_NODATA)
|
||||
{
|
||||
ret = VIRTIO_GPU_MAP_ERR(resp.type);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_set_scanout
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_set_scanout(FAR struct virtio_gpu_priv_s *priv,
|
||||
int scanout_id, int resource_id,
|
||||
int width, int height)
|
||||
{
|
||||
FAR struct virtqueue *vq = priv->vdev->vrings_info[VIRTIO_GPU_CTL].vq;
|
||||
struct virtio_gpu_set_scanout cmd;
|
||||
struct virtio_gpu_ctrl_hdr resp;
|
||||
struct virtqueue_buf vb[2];
|
||||
int ret;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.type = VIRTIO_GPU_CMD_SET_SCANOUT;
|
||||
cmd.scanout_id = scanout_id;
|
||||
cmd.resource_id = resource_id;
|
||||
cmd.r.width = width;
|
||||
cmd.r.height = height;
|
||||
|
||||
vb[0].buf = &cmd;
|
||||
vb[0].len = sizeof(cmd);
|
||||
vb[1].buf = &resp;
|
||||
vb[1].len = sizeof(resp);
|
||||
|
||||
ret = virtio_gpu_send_cmd(vq, vb, 1, 1, NULL);
|
||||
if (ret >= 0 && resp.type != VIRTIO_GPU_RESP_OK_NODATA)
|
||||
{
|
||||
ret = VIRTIO_GPU_MAP_ERR(resp.type);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_transfer_to_host_2d
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_transfer_to_host_2d(FAR struct virtio_gpu_priv_s *priv,
|
||||
int resource_id, int x, int y,
|
||||
int width, int height)
|
||||
{
|
||||
FAR struct virtqueue *vq = priv->vdev->vrings_info[VIRTIO_GPU_CTL].vq;
|
||||
struct virtio_gpu_transfer_to_host_2d cmd;
|
||||
struct virtio_gpu_ctrl_hdr resp;
|
||||
struct virtqueue_buf vb[2];
|
||||
int ret;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.hdr.type = VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D;
|
||||
cmd.resource_id = resource_id;
|
||||
cmd.offset = y * priv->stride + x * (VIRTIO_GPU_BPP >> 3);
|
||||
cmd.r.x = x;
|
||||
cmd.r.y = y;
|
||||
cmd.r.width = width;
|
||||
cmd.r.height = height;
|
||||
|
||||
vb[0].buf = &cmd;
|
||||
vb[0].len = sizeof(cmd);
|
||||
vb[1].buf = &resp;
|
||||
vb[1].len = sizeof(resp);
|
||||
|
||||
ret = virtio_gpu_send_cmd(vq, vb, 1, 1, NULL);
|
||||
if (ret >= 0 && resp.type != VIRTIO_GPU_RESP_OK_NODATA)
|
||||
{
|
||||
ret = VIRTIO_GPU_MAP_ERR(resp.type);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_flush_resource
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_flush_resource(FAR struct virtio_gpu_priv_s *priv,
|
||||
int resource_id, int x, int y,
|
||||
int width, int height)
|
||||
{
|
||||
FAR struct virtqueue *vq = priv->vdev->vrings_info[VIRTIO_GPU_CTL].vq;
|
||||
FAR struct virtio_gpu_resource_flush *cmd;
|
||||
struct virtqueue_buf vb;
|
||||
|
||||
cmd = virtio_zalloc_buf(priv->vdev, sizeof(*cmd), 16);
|
||||
if (cmd == NULL)
|
||||
{
|
||||
vrterr("ERROR: Failed to allocate cmd buffer");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->hdr.type = VIRTIO_GPU_CMD_RESOURCE_FLUSH;
|
||||
cmd->resource_id = resource_id;
|
||||
cmd->r.x = x;
|
||||
cmd->r.y = y;
|
||||
cmd->r.width = width;
|
||||
cmd->r.height = height;
|
||||
|
||||
vb.buf = cmd;
|
||||
vb.len = sizeof(*cmd);
|
||||
|
||||
return virtio_gpu_send_cmd(vq, &vb, 1, 0, cmd);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_probe
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_probe(FAR struct virtio_device *vdev)
|
||||
{
|
||||
FAR struct virtio_gpu_priv_s *priv;
|
||||
struct virtio_gpu_mem_entry ent;
|
||||
int disp;
|
||||
int ret;
|
||||
|
||||
for (disp = 0; disp < VIRTIO_GPU_MAX_DISP; disp++)
|
||||
{
|
||||
if (g_virtio_gpu[disp] == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (disp == VIRTIO_GPU_MAX_DISP)
|
||||
{
|
||||
return -EMFILE;
|
||||
}
|
||||
|
||||
priv = kmm_zalloc(sizeof(*priv));
|
||||
if (priv == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = virtio_gpu_init(priv, vdev);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
ret = virtio_gpu_get_display_info(priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto err_init;
|
||||
}
|
||||
|
||||
/* Initialize the LCD-independent fields of the state structure */
|
||||
|
||||
priv->vtable.getvideoinfo = virtio_gpu_getvideoinfo,
|
||||
priv->vtable.getplaneinfo = virtio_gpu_getplaneinfo,
|
||||
priv->vtable.updatearea = virtio_gpu_updatearea,
|
||||
|
||||
/* Allocate (and clear) the framebuffer */
|
||||
|
||||
priv->stride = priv->xres * VIRTIO_GPU_BPP >> 3;
|
||||
priv->fblen = priv->stride * priv->yres;
|
||||
|
||||
priv->fbmem = (FAR uint8_t *)virtio_zalloc_buf(vdev, priv->fblen, 16);
|
||||
if (priv->fbmem == NULL)
|
||||
{
|
||||
vrterr("ERROR: Failed to allocate frame buffer memory");
|
||||
ret = -ENOMEM;
|
||||
goto err_init_fb;
|
||||
}
|
||||
|
||||
ret = virtio_gpu_create_2d(priv, 1, priv->xres, priv->yres);
|
||||
if (ret < 0)
|
||||
{
|
||||
vrterr("virtio_gpu_create_2d error");
|
||||
goto err_init_fb;
|
||||
}
|
||||
|
||||
ent.addr = (uintptr_t)priv->fbmem;
|
||||
ent.length = priv->fblen;
|
||||
ret = virtio_gpu_attach_backing(priv, 1, &ent, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
vrterr("virtio_gpu_attach_backing error");
|
||||
goto err_init_fb;
|
||||
}
|
||||
|
||||
ret = virtio_gpu_set_scanout(priv, 0, 1, priv->xres, priv->yres);
|
||||
if (ret < 0)
|
||||
{
|
||||
vrterr("virtio_gpu_set_scanout error");
|
||||
goto err_init_fb;
|
||||
}
|
||||
|
||||
ret = virtio_gpu_transfer_to_host_2d(priv, 1, 0, 0, priv->xres,
|
||||
priv->yres);
|
||||
if (ret < 0)
|
||||
{
|
||||
vrterr("virtio_gpu_transfer_to_host_2d error");
|
||||
goto err_init_fb;
|
||||
}
|
||||
|
||||
ret = virtio_gpu_flush_resource(priv, 1, 0, 0, priv->xres, priv->yres);
|
||||
if (ret < 0)
|
||||
{
|
||||
vrterr("virtio_gpu_flush_resource error");
|
||||
goto err_init_fb;
|
||||
}
|
||||
|
||||
g_virtio_gpu[disp] = priv;
|
||||
priv->display = disp;
|
||||
|
||||
ret = fb_register(disp, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
vrterr("ERROR: Failed to initialize framebuffer driver, ret=%d",
|
||||
ret);
|
||||
g_virtio_gpu[disp] = NULL;
|
||||
goto err_init_fb;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err_init_fb:
|
||||
virtio_free_buf(vdev, priv->fbmem);
|
||||
err_init:
|
||||
virtio_reset_device(vdev);
|
||||
virtio_delete_virtqueues(vdev);
|
||||
err_out:
|
||||
kmm_free(priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_remove
|
||||
****************************************************************************/
|
||||
|
||||
static void virtio_gpu_remove(FAR struct virtio_device *vdev)
|
||||
{
|
||||
FAR struct virtio_gpu_priv_s *priv = vdev->priv;
|
||||
|
||||
virtio_reset_device(vdev);
|
||||
virtio_delete_virtqueues(vdev);
|
||||
g_virtio_gpu[priv->display] = NULL;
|
||||
virtio_free_buf(vdev, priv->fbmem);
|
||||
kmm_free(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_getvideoinfo
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_getvideoinfo(FAR struct fb_vtable_s *vtable,
|
||||
FAR struct fb_videoinfo_s *vinfo)
|
||||
{
|
||||
FAR struct virtio_gpu_priv_s *priv =
|
||||
(FAR struct virtio_gpu_priv_s *)vtable;
|
||||
|
||||
vinfo->fmt = VIRTIO_GPU_FB_FMT;
|
||||
vinfo->nplanes = VIRTIO_GPU_MAX_PLANE;
|
||||
vinfo->xres = priv->xres;
|
||||
vinfo->yres = priv->yres;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_getplaneinfo
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_getplaneinfo(FAR struct fb_vtable_s *vtable,
|
||||
int planeno,
|
||||
FAR struct fb_planeinfo_s *pinfo)
|
||||
{
|
||||
FAR struct virtio_gpu_priv_s *priv =
|
||||
(FAR struct virtio_gpu_priv_s *)vtable;
|
||||
|
||||
if (planeno >= VIRTIO_GPU_MAX_PLANE)
|
||||
{
|
||||
vrterr("ERROR: plane number %d exceeds %d",
|
||||
planeno, VIRTIO_GPU_MAX_PLANE - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(pinfo, 0, sizeof(*pinfo));
|
||||
pinfo->bpp = VIRTIO_GPU_BPP;
|
||||
pinfo->display = priv->display;
|
||||
pinfo->fblen = priv->fblen;
|
||||
pinfo->fbmem = priv->fbmem;
|
||||
pinfo->stride = priv->stride;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_gpu_updatearea
|
||||
****************************************************************************/
|
||||
|
||||
static int virtio_gpu_updatearea(FAR struct fb_vtable_s *vtable,
|
||||
FAR const struct fb_area_s *area)
|
||||
{
|
||||
FAR struct virtio_gpu_priv_s *priv =
|
||||
(FAR struct virtio_gpu_priv_s *)vtable;
|
||||
int ret = OK;
|
||||
|
||||
vrtinfo("update disp %d:(%d %d)[%d %d]", priv->display,
|
||||
area->x, area->y, area->w, area->h);
|
||||
ret = virtio_gpu_transfer_to_host_2d(priv, 1, area->x, area->y,
|
||||
area->w, area->h);
|
||||
if (ret < 0)
|
||||
{
|
||||
vrterr("virtio_gpu_transfer_to_host_2d failed: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = virtio_gpu_flush_resource(priv, 1, area->x, area->y,
|
||||
area->w, area->h);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: virtio_register_gpu_driver
|
||||
****************************************************************************/
|
||||
|
||||
int virtio_register_gpu_driver(void)
|
||||
{
|
||||
return virtio_register_driver(&g_virtio_gpu_driver);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the framebuffer video hardware associated with the display.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - In the case of hardware with multiple displays, this
|
||||
* specifies the display. Normally this is zero.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success; a negated errno value is returned on any
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_fbinitialize(int display)
|
||||
{
|
||||
return display < VIRTIO_GPU_MAX_DISP ? OK : -EINVAL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbgetvplane
|
||||
*
|
||||
* Description:
|
||||
* Return a reference to the framebuffer object for the specified video
|
||||
* plane of the specified plane.
|
||||
* Many OSDs support multiple planes of video.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - In the case of hardware with multiple displays, this
|
||||
* specifies the display. Normally this is zero.
|
||||
* vplane - Identifies the plane being queried.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL pointer to the frame buffer access structure is returned on
|
||||
* success; NULL is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct fb_vtable_s *up_fbgetvplane(int display, int vplane)
|
||||
{
|
||||
if (display < 0 || display >= VIRTIO_GPU_MAX_DISP ||
|
||||
vplane < 0 || vplane >= VIRTIO_GPU_MAX_PLANE || !g_virtio_gpu[display])
|
||||
{
|
||||
vrterr("get vplane (%d,%d) failed", display, vplane);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &g_virtio_gpu[display]->vtable;
|
||||
}
|
530
drivers/virtio/virtio-gpu.h
Normal file
530
drivers/virtio/virtio-gpu.h
Normal file
|
@ -0,0 +1,530 @@
|
|||
/****************************************************************************
|
||||
* drivers/virtio/virtio-gpu.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __DRIVERS_VIRTIO_VIRTIO_GPU_H
|
||||
#define __DRIVERS_VIRTIO_VIRTIO_GPU_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/compiler.h>
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef CONFIG_DRIVERS_VIRTIO_GPU
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Definitions from viogpu.h in OpenBSD src */
|
||||
|
||||
#define VIRTIO_GPU_F_VIRGL (1u << 0)
|
||||
#define VIRTIO_GPU_F_EDID (1u << 1)
|
||||
#define VIRTIO_GPU_F_RESOURCE_UUID (1u << 2)
|
||||
#define VIRTIO_GPU_F_RESOURCE_BLOB (1u << 3)
|
||||
|
||||
enum virtio_gpu_ctrl_type
|
||||
{
|
||||
VIRTIO_GPU_UNDEFINED = 0,
|
||||
|
||||
/* 2d commands */
|
||||
|
||||
VIRTIO_GPU_CMD_GET_DISPLAY_INFO = 0x0100,
|
||||
VIRTIO_GPU_CMD_RESOURCE_CREATE_2D,
|
||||
VIRTIO_GPU_CMD_RESOURCE_UNREF,
|
||||
VIRTIO_GPU_CMD_SET_SCANOUT,
|
||||
VIRTIO_GPU_CMD_RESOURCE_FLUSH,
|
||||
VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D,
|
||||
VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING,
|
||||
VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING,
|
||||
VIRTIO_GPU_CMD_GET_CAPSET_INFO,
|
||||
VIRTIO_GPU_CMD_GET_CAPSET,
|
||||
VIRTIO_GPU_CMD_GET_EDID,
|
||||
VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID,
|
||||
VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB,
|
||||
VIRTIO_GPU_CMD_SET_SCANOUT_BLOB,
|
||||
|
||||
/* 3d commands */
|
||||
|
||||
VIRTIO_GPU_CMD_CTX_CREATE = 0x0200,
|
||||
VIRTIO_GPU_CMD_CTX_DESTROY,
|
||||
VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE,
|
||||
VIRTIO_GPU_CMD_CTX_DETACH_RESOURCE,
|
||||
VIRTIO_GPU_CMD_RESOURCE_CREATE_3D,
|
||||
VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D,
|
||||
VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D,
|
||||
VIRTIO_GPU_CMD_SUBMIT_3D,
|
||||
VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB,
|
||||
VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB,
|
||||
|
||||
/* Cursor commands */
|
||||
|
||||
VIRTIO_GPU_CMD_UPDATE_CURSOR = 0x0300,
|
||||
VIRTIO_GPU_CMD_MOVE_CURSOR,
|
||||
|
||||
/* Success responses */
|
||||
|
||||
VIRTIO_GPU_RESP_OK_NODATA = 0x1100,
|
||||
VIRTIO_GPU_RESP_OK_DISPLAY_INFO,
|
||||
VIRTIO_GPU_RESP_OK_CAPSET_INFO,
|
||||
VIRTIO_GPU_RESP_OK_CAPSET,
|
||||
VIRTIO_GPU_RESP_OK_EDID,
|
||||
VIRTIO_GPU_RESP_OK_RESOURCE_UUID,
|
||||
VIRTIO_GPU_RESP_OK_MAP_INFO,
|
||||
|
||||
/* Error responses */
|
||||
|
||||
VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200,
|
||||
VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY,
|
||||
VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID,
|
||||
VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID,
|
||||
VIRTIO_GPU_RESP_ERR_INVALID_CONTEXT_ID,
|
||||
VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER,
|
||||
};
|
||||
|
||||
enum virtio_gpu_shm_id
|
||||
{
|
||||
VIRTIO_GPU_SHM_ID_UNDEFINED = 0,
|
||||
VIRTIO_GPU_SHM_ID_HOST_VISIBLE
|
||||
};
|
||||
|
||||
#define VIRTIO_GPU_FLAG_FENCE (1 << 0)
|
||||
#define VIRTIO_GPU_FLAG_INFO_RING_IDX (1 << 1)
|
||||
|
||||
begin_packed_struct struct virtio_gpu_ctrl_hdr
|
||||
{
|
||||
uint32_t type;
|
||||
uint32_t flags;
|
||||
uint64_t fence_id;
|
||||
uint32_t ctx_id;
|
||||
uint8_t ring_idx;
|
||||
uint8_t padding[3];
|
||||
} end_packed_struct;
|
||||
|
||||
/* Data passed in the cursor vq */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_cursor_pos
|
||||
{
|
||||
uint32_t scanout_id;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_UPDATE_CURSOR, VIRTIO_GPU_CMD_MOVE_CURSOR */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_update_cursor
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
struct virtio_gpu_cursor_pos pos; /* Update & move */
|
||||
uint32_t resource_id; /* Update only */
|
||||
uint32_t hot_x; /* Update only */
|
||||
uint32_t hot_y; /* Update only */
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* Data passed in the control vq, 2d related */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_rect
|
||||
{
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_RESOURCE_UNREF */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resource_unref
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t resource_id;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_RESOURCE_CREATE_2D: create a 2d resource with a format */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resource_create_2d
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t resource_id;
|
||||
uint32_t format;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_SET_SCANOUT */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_set_scanout
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
struct virtio_gpu_rect r;
|
||||
uint32_t scanout_id;
|
||||
uint32_t resource_id;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_RESOURCE_FLUSH */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resource_flush
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
struct virtio_gpu_rect r;
|
||||
uint32_t resource_id;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D: simple transfer to_host */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_transfer_to_host_2d
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
struct virtio_gpu_rect r;
|
||||
uint64_t offset;
|
||||
uint32_t resource_id;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_mem_entry
|
||||
{
|
||||
uint64_t addr;
|
||||
uint32_t length;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resource_attach_backing
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t resource_id;
|
||||
uint32_t nr_entries;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resource_detach_backing
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t resource_id;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_RESP_OK_DISPLAY_INFO */
|
||||
|
||||
#define VIRTIO_GPU_MAX_SCANOUTS 16
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resp_display_info
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
struct virtio_gpu_display_one
|
||||
{
|
||||
struct virtio_gpu_rect r;
|
||||
uint32_t enabled;
|
||||
uint32_t flags;
|
||||
}
|
||||
pmodes[VIRTIO_GPU_MAX_SCANOUTS];
|
||||
} end_packed_struct;
|
||||
|
||||
/* Data passed in the control vq, 3d related */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_box
|
||||
{
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t z;
|
||||
uint32_t w;
|
||||
uint32_t h;
|
||||
uint32_t d;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D, VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_transfer_host_3d
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
struct virtio_gpu_box box;
|
||||
uint64_t offset;
|
||||
uint32_t resource_id;
|
||||
uint32_t level;
|
||||
uint32_t stride;
|
||||
uint32_t layer_stride;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_RESOURCE_CREATE_3D */
|
||||
|
||||
#define VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP (1 << 0)
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resource_create_3d
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t resource_id;
|
||||
uint32_t target;
|
||||
uint32_t format;
|
||||
uint32_t bind;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t depth;
|
||||
uint32_t array_size;
|
||||
uint32_t last_level;
|
||||
uint32_t nr_samples;
|
||||
uint32_t flags;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_CTX_CREATE */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_ctx_create
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t nlen;
|
||||
uint32_t padding;
|
||||
char debug_name[64];
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_CTX_DESTROY */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_ctx_destroy
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE, VIRTIO_GPU_CMD_CTX_DETACH_RESOURCE */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_ctx_resource
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t resource_id;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_SUBMIT_3D */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_cmd_submit
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t size;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_GET_CAPSET_INFO */
|
||||
|
||||
#define VIRTIO_GPU_CAPSET_VIRGL 1
|
||||
#define VIRTIO_GPU_CAPSET_VIRGL2 2
|
||||
|
||||
begin_packed_struct struct virtio_gpu_get_capset_info
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t capset_index;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_RESP_OK_CAPSET_INFO */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resp_capset_info
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t capset_id;
|
||||
uint32_t capset_max_version;
|
||||
uint32_t capset_max_size;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_GET_CAPSET */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_get_capset
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t capset_id;
|
||||
uint32_t capset_version;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_RESP_OK_CAPSET */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resp_capset
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint8_t capset_data[];
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_GET_EDID */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_cmd_get_edid
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t scanout;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_RESP_OK_EDID */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resp_edid
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t size;
|
||||
uint32_t padding;
|
||||
uint8_t edid[1024];
|
||||
} end_packed_struct;
|
||||
|
||||
#define VIRTIO_GPU_EVENT_DISPLAY (1 << 0)
|
||||
|
||||
begin_packed_struct struct virtio_gpu_config
|
||||
{
|
||||
uint32_t events_read;
|
||||
uint32_t events_clear;
|
||||
uint32_t num_scanouts;
|
||||
uint32_t num_capsets;
|
||||
} end_packed_struct;
|
||||
|
||||
/* simple formats for fbcon/X use */
|
||||
|
||||
enum virtio_gpu_formats
|
||||
{
|
||||
VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM = 1,
|
||||
VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM = 2,
|
||||
VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM = 3,
|
||||
VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM = 4,
|
||||
|
||||
VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM = 67,
|
||||
VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM = 68,
|
||||
|
||||
VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM = 121,
|
||||
VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM = 134,
|
||||
};
|
||||
|
||||
/* VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resource_assign_uuid
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t resource_id;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_RESP_OK_RESOURCE_UUID */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resp_resource_uuid
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint8_t uuid[16];
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB */
|
||||
|
||||
#define VIRTIO_GPU_BLOB_MEM_GUEST 0x0001
|
||||
#define VIRTIO_GPU_BLOB_MEM_HOST3D 0x0002
|
||||
#define VIRTIO_GPU_BLOB_MEM_HOST3D_GUEST 0x0003
|
||||
|
||||
#define VIRTIO_GPU_BLOB_FLAG_USE_MAPPABLE 0x0001
|
||||
#define VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE 0x0002
|
||||
#define VIRTIO_GPU_BLOB_FLAG_USE_CROSS_DEVICE 0x0004
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resource_create_blob
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t resource_id;
|
||||
|
||||
/* Zero is invalid blob mem */
|
||||
|
||||
uint32_t blob_mem;
|
||||
uint32_t blob_flags;
|
||||
uint32_t nr_entries;
|
||||
uint64_t blob_id;
|
||||
uint64_t size;
|
||||
|
||||
/* sizeof(nr_entries * virtio_gpu_mem_entry) bytes follow */
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_SET_SCANOUT_BLOB */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_set_scanout_blob
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
struct virtio_gpu_rect r;
|
||||
uint32_t scanout_id;
|
||||
uint32_t resource_id;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t format;
|
||||
uint32_t padding;
|
||||
uint32_t strides[4];
|
||||
uint32_t offsets[4];
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resource_map_blob
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t resource_id;
|
||||
uint32_t padding;
|
||||
uint64_t offset;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_RESP_OK_MAP_INFO */
|
||||
|
||||
#define VIRTIO_GPU_MAP_CACHE_MASK 0x0f
|
||||
#define VIRTIO_GPU_MAP_CACHE_NONE 0x00
|
||||
#define VIRTIO_GPU_MAP_CACHE_CACHED 0x01
|
||||
#define VIRTIO_GPU_MAP_CACHE_UNCACHED 0x02
|
||||
#define VIRTIO_GPU_MAP_CACHE_WC 0x03
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resp_map_info
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t map_info;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/* VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB */
|
||||
|
||||
begin_packed_struct struct virtio_gpu_resource_unmap_blob
|
||||
{
|
||||
struct virtio_gpu_ctrl_hdr hdr;
|
||||
uint32_t resource_id;
|
||||
uint32_t padding;
|
||||
} end_packed_struct;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
int virtio_register_gpu_driver(void);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_DRIVERS_VIRTIO_GPU */
|
||||
#endif /* __DRIVERS_VIRTIO_VIRTIO_GPU_H */
|
|
@ -29,6 +29,7 @@
|
|||
#include <nuttx/virtio/virtio.h>
|
||||
|
||||
#include "virtio-blk.h"
|
||||
#include "virtio-gpu.h"
|
||||
#include "virtio-net.h"
|
||||
#include "virtio-rng.h"
|
||||
#include "virtio-serial.h"
|
||||
|
@ -125,6 +126,14 @@ void virtio_register_drivers(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DRIVERS_VIRTIO_GPU
|
||||
ret = virtio_register_gpu_driver();
|
||||
if (ret < 0)
|
||||
{
|
||||
vrterr("virtio_register_gpu_driver failed, ret=%d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DRIVERS_VIRTIO_NET
|
||||
ret = virtio_register_net_driver();
|
||||
if (ret < 0)
|
||||
|
|
Loading…
Reference in a new issue