// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdint.h>
#include <stdlib.h>

#include "hwdefs/km/rgxdefs_km.h"
#include "msd_img_connection.h"
#include "msd_img_context.h"
#include "msd_img_device.h"
#include "msd_img_driver.h"

msd_driver_t*
msd_driver_create(void)
{
	return MsdImgDriver::Create().release();
}

void
msd_driver_configure(msd_driver_t* drv, uint32_t flags)
{
	MsdImgDriver::cast(drv)->configure(flags);
}

void
msd_driver_destroy(msd_driver_t* drv)
{
	MsdImgDriver::Destroy(MsdImgDriver::cast(drv));
}

msd_device_t*
msd_driver_create_device(msd_driver_t* drv, void* device)
{
	if (!device)
	{
		return DRETP(nullptr, "device is null");
	}
	return MsdImgDevice::Create(drv, device).release();
}

void
msd_device_destroy(msd_device_t* dev)
{
	MsdImgDevice::Destroy(MsdImgDevice::cast(dev));
}

magma_status_t
msd_device_query(msd_device_t* device, uint64_t id, uint64_t* value_out)
{
	switch (id)
	{
		case MAGMA_QUERY_VENDOR_ID:
			// Generally listed as "Video Logic" - the original name of Imagination. This value
			// matches what the Vulkan driver reports.
			*value_out = 0x1010;
			return MAGMA_STATUS_OK;

		case MAGMA_QUERY_DEVICE_ID:
			// Pack BVNC into 32 bits.
			*value_out = (((uint32_t)RGX_BVNC_KM_B & 0xFF) << 24) | (((uint32_t)RGX_BVNC_KM_V & 0xFF) << 16) |
				     (((uint32_t)RGX_BVNC_KM_N & 0xFF) << 8) | ((uint32_t)RGX_BVNC_KM_C & 0xFF);
			return MAGMA_STATUS_OK;
	}
	return MAGMA_STATUS_OK;
}

void
msd_device_dump_status(msd_device_t* dev, uint32_t dump_flags)
{
	MsdImgDevice::cast(dev)->DumpStatus(dump_flags);
}

msd_connection_t*
msd_device_open(msd_device_t* dev, msd_client_id_t client_id)
{
	MsdImgDevice* device = MsdImgDevice::cast(dev);
	auto connection = std::make_unique<MsdImgConnection>(device, client_id);
	if (!connection->Init())
	{
		return DRETP(nullptr, "Failed to initialize connection");
	}

	return connection.release();
}

void
msd_connection_close(msd_connection_t* connection)
{
	delete MsdImgConnection::Cast(connection);
}

magma_status_t
msd_connection_map_buffer_gpu(msd_connection_t* connection,
			      msd_buffer_t* buffer,
			      uint64_t gpu_va,
			      uint64_t page_offset,
			      uint64_t page_count,
			      uint64_t flags)
{
	return MAGMA_STATUS_OK;
}
magma_status_t
msd_connection_unmap_buffer_gpu(msd_connection_t* connection, msd_buffer_t* buffer, uint64_t gpu_va)
{
	return MAGMA_STATUS_OK;
}
magma_status_t
msd_connection_commit_buffer(msd_connection_t* connection, msd_buffer_t* buffer, uint64_t page_offset, uint64_t page_count)
{
	return MAGMA_STATUS_OK;
}

void
msd_connection_set_notification_callback(msd_connection_t* connection,
					 msd_connection_notification_callback_t callback,
					 void* token)
{
}

msd_context_t*
msd_connection_create_context(msd_connection_t* connection)
{
	return new MsdImgContext(MsdImgConnection::Cast(connection));
}

void
msd_context_destroy(msd_context_t* ctx)
{
	delete MsdImgContext::cast(ctx);
}

magma_status_t msd_context_execute_command_buffer_with_resources(
    struct msd_context_t* ctx, struct magma_system_command_buffer* command_buffer,
    struct magma_system_exec_resource* exec_resources,
    struct msd_buffer_t** buffers, struct msd_semaphore_t** wait_semaphores,
    struct msd_semaphore_t** signal_semaphores)
{
	MsdImgConnection* connection = MsdImgContext::cast(ctx)->connection();

	return connection->ExecuteCommandBuffer(command_buffer, exec_resources, buffers, signal_semaphores);
}

magma_status_t
msd_context_execute_immediate_commands(msd_context_t* ctx,
				       uint64_t commands_size,
				       void* commands,
				       uint64_t semaphore_count,
				       msd_semaphore_t** semaphores)
{
	return MAGMA_STATUS_OK;
}

void
msd_context_release_buffer(msd_context_t* context, msd_buffer_t* buffer)
{
}

void
msd_connection_release_buffer(msd_connection_t* connection, msd_buffer_t* buffer)
{
}

magma_status_t
msd_device_query_returns_buffer(struct msd_device_t* device, uint64_t id, uint32_t* buffer_out)
{
	return MAGMA_STATUS_UNIMPLEMENTED;
}
