#include "vigs_regs.h"
#include <drm/vigs_drm.h>
-static int vigs_comm_prepare(struct vigs_comm *comm,
- vigsp_cmd cmd,
- unsigned long request_size,
- unsigned long response_size,
- void **request,
- void **response)
+static int vigs_comm_alloc(struct vigs_comm *comm,
+ unsigned long size,
+ void **ptr)
{
int ret;
- void *ptr;
- struct vigsp_cmd_batch_header *batch_header;
- struct vigsp_cmd_request_header *request_header;
- unsigned long total_size = sizeof(*batch_header) +
- sizeof(*request_header) +
- request_size +
- sizeof(struct vigsp_cmd_response_header) +
- response_size;
- if (!comm->execbuffer || (vigs_gem_size(&comm->execbuffer->gem) < total_size)) {
+ if (!comm->execbuffer ||
+ (vigs_gem_size(&comm->execbuffer->gem) < size)) {
if (comm->execbuffer) {
drm_gem_object_unreference_unlocked(&comm->execbuffer->gem.base);
comm->execbuffer = NULL;
}
ret = vigs_execbuffer_create(comm->vigs_dev,
- total_size,
+ size,
true,
&comm->execbuffer);
}
}
- ptr = comm->execbuffer->gem.kptr;
+ *ptr = comm->execbuffer->gem.kptr;
+
+ memset(*ptr, 0, vigs_gem_size(&comm->execbuffer->gem));
+
+ return 0;
+}
+
+static int vigs_comm_prepare(struct vigs_comm *comm,
+ vigsp_cmd cmd,
+ unsigned long request_size,
+ unsigned long response_size,
+ void **request,
+ void **response)
+{
+ int ret;
+ void *ptr;
+ struct vigsp_cmd_batch_header *batch_header;
+ struct vigsp_cmd_request_header *request_header;
- memset(ptr, 0, vigs_gem_size(&comm->execbuffer->gem));
+ ret = vigs_comm_alloc(comm,
+ sizeof(*batch_header) +
+ sizeof(*request_header) +
+ request_size +
+ sizeof(struct vigsp_cmd_response_header) +
+ response_size,
+ &ptr);
+
+ if (ret != 0) {
+ return ret;
+ }
batch_header = ptr;
request_header = (struct vigsp_cmd_request_header*)(batch_header + 1);
struct vigsp_cmd_batch_header *batch_header = comm->execbuffer->gem.kptr;
struct vigsp_cmd_request_header *request_header =
(struct vigsp_cmd_request_header*)(batch_header + 1);
- struct vigsp_cmd_response_header *response_header =
- (struct vigsp_cmd_response_header*)((u8*)(request_header + 1) +
- request_header->size);
+ struct vigsp_cmd_response_header *response_header;
+ vigsp_u32 i;
+
+ for (i = 0; i < batch_header->num_requests; ++i) {
+ request_header =
+ (struct vigsp_cmd_request_header*)((uint8_t*)(request_header + 1) +
+ request_header->size);
+ }
+
+ response_header = (struct vigsp_cmd_response_header*)request_header;
vigs_comm_exec_locked(comm, comm->execbuffer);
int vigs_comm_set_root_surface(struct vigs_comm *comm,
vigsp_surface_id id,
- vigsp_offset offset)
+ vigsp_offset offset,
+ bool update_vram)
{
int ret;
- struct vigsp_cmd_set_root_surface_request *request;
+ struct vigsp_cmd_batch_header *batch_header;
+ struct vigsp_cmd_request_header *update_vram_header = NULL;
+ struct vigsp_cmd_update_vram_request *update_vram_request = NULL;
+ struct vigsp_cmd_request_header *set_root_surface_header;
+ struct vigsp_cmd_set_root_surface_request *set_root_surface_request;
+ void *ptr;
DRM_DEBUG_DRIVER("id = %u, offset = %u\n", id, offset);
mutex_lock(&comm->mutex);
- ret = vigs_comm_prepare(comm,
- vigsp_cmd_set_root_surface,
- sizeof(*request),
- 0,
- (void**)&request,
- NULL);
+ ret = vigs_comm_alloc(comm,
+ sizeof(*batch_header) +
+ (update_vram ? sizeof(*update_vram_header) +
+ sizeof(*update_vram_request)
+ : 0) +
+ sizeof(*set_root_surface_header) +
+ sizeof(*set_root_surface_request) +
+ sizeof(struct vigsp_cmd_response_header),
+ &ptr);
if (ret == 0) {
- request->id = id;
- request->offset = offset;
+ batch_header = ptr;
+ ptr = batch_header + 1;
+
+ if (update_vram) {
+ update_vram_header = ptr;
+ ptr = update_vram_header + 1;
+ update_vram_request = ptr;
+ ptr = update_vram_request + 1;
+ }
+
+ set_root_surface_header = ptr;
+ ptr = set_root_surface_header + 1;
+ set_root_surface_request = ptr;
+
+ if (update_vram) {
+ batch_header->num_requests = 2;
+
+ update_vram_header->cmd = vigsp_cmd_update_vram;
+ update_vram_header->size = sizeof(*update_vram_request);
+
+ update_vram_request->sfc_id = id;
+ update_vram_request->offset = offset;
+ } else {
+ batch_header->num_requests = 1;
+ }
+
+ set_root_surface_header->cmd = vigsp_cmd_set_root_surface;
+ set_root_surface_header->size = sizeof(*set_root_surface_request);
+
+ set_root_surface_request->id = id;
+ set_root_surface_request->offset = offset;
ret = vigs_comm_exec_internal(comm);
}