/*
 * Copyright (c) 2021 Carlo Caione <ccaione@baylibre.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ipc/ipc_static_vrings.h>
#include <cache.h>

#define SHM_DEVICE_NAME		"sram0.shm"

#define RPMSG_VQ_0		(0) /* TX virtqueue queue index */
#define RPMSG_VQ_1		(1) /* RX virtqueue queue index */

static void virtio_notify(struct virtqueue *vq)
{
	struct ipc_static_vrings *vr;

	vr = CONTAINER_OF(vq->vq_dev, struct ipc_static_vrings, vdev);

	if (vr->notify_cb) {
		vr->notify_cb(vq, vr->priv);
	}
}

static void virtio_set_features(struct virtio_device *vdev, uint32_t features)
{
	/* No need for implementation */
}

static void virtio_set_status(struct virtio_device *p_vdev, unsigned char status)
{
	struct ipc_static_vrings *vr;

	if (p_vdev->role != VIRTIO_DEV_MASTER) {
		return;
	}

	vr = CONTAINER_OF(p_vdev, struct ipc_static_vrings, vdev);

	sys_write8(status, vr->status_reg_addr);
	sys_cache_data_range((void *) vr->status_reg_addr,
			     sizeof(status), K_CACHE_WB);
}

static uint32_t virtio_get_features(struct virtio_device *vdev)
{
	return BIT(VIRTIO_RPMSG_F_NS);
}

static unsigned char virtio_get_status(struct virtio_device *p_vdev)
{
	struct ipc_static_vrings *vr;
	uint8_t ret;

	vr = CONTAINER_OF(p_vdev, struct ipc_static_vrings, vdev);

	ret = VIRTIO_CONFIG_STATUS_DRIVER_OK;

	if (p_vdev->role == VIRTIO_DEV_SLAVE) {
		sys_cache_data_range((void *) vr->status_reg_addr,
				     sizeof(ret), K_CACHE_INVD);
		ret = sys_read8(vr->status_reg_addr);
	}

	return ret;
}

const static struct virtio_dispatch dispatch = {
	.get_status = virtio_get_status,
	.get_features = virtio_get_features,
	.set_status = virtio_set_status,
	.set_features = virtio_set_features,
	.notify = virtio_notify,
};

static int libmetal_setup(struct ipc_static_vrings *vr)
{
	struct metal_init_params metal_params = METAL_INIT_DEFAULTS;
	struct metal_device *device;
	int err;

	err = metal_init(&metal_params);
	if (err != 0) {
		return err;
	}

	err = metal_register_generic_device(&vr->shm_device);
	if (err != 0) {
		return err;
	}

	err = metal_device_open("generic", SHM_DEVICE_NAME, &device);
	if (err != 0) {
		return err;
	}

	vr->shm_io = metal_device_io_region(device, 0);
	if (vr->shm_io == NULL) {
		return err;
	}

	return 0;
}

static int vq_setup(struct ipc_static_vrings *vr, unsigned int role)
{
	vr->vq[RPMSG_VQ_0] = virtqueue_allocate(vr->vring_size);
	if (vr->vq[RPMSG_VQ_0] == NULL) {
		return -ENOMEM;
	}

	vr->vq[RPMSG_VQ_1] = virtqueue_allocate(vr->vring_size);
	if (vr->vq[RPMSG_VQ_1] == NULL) {
		return -ENOMEM;
	}

	vr->rvrings[RPMSG_VQ_0].io = vr->shm_io;
	vr->rvrings[RPMSG_VQ_0].info.vaddr = (void *) vr->tx_addr;
	vr->rvrings[RPMSG_VQ_0].info.num_descs = vr->vring_size;
	vr->rvrings[RPMSG_VQ_0].info.align = VRING_ALIGNMENT;
	vr->rvrings[RPMSG_VQ_0].vq = vr->vq[RPMSG_VQ_0];

	vr->rvrings[RPMSG_VQ_1].io = vr->shm_io;
	vr->rvrings[RPMSG_VQ_1].info.vaddr = (void *) vr->rx_addr;
	vr->rvrings[RPMSG_VQ_1].info.num_descs = vr->vring_size;
	vr->rvrings[RPMSG_VQ_1].info.align = VRING_ALIGNMENT;
	vr->rvrings[RPMSG_VQ_1].vq = vr->vq[RPMSG_VQ_1];

	vr->vdev.role = role;

	vr->vdev.vrings_num = VRING_COUNT;
	vr->vdev.func = &dispatch;
	vr->vdev.vrings_info = &vr->rvrings[0];

	return 0;
}

int ipc_static_vrings_init(struct ipc_static_vrings *vr, unsigned int role)
{
	int err = 0;

	if (!vr) {
		return -EINVAL;
	}

	vr->shm_device.name = SHM_DEVICE_NAME;
	vr->shm_device.num_regions = 1;
	vr->shm_physmap[0] = vr->shm_addr;

	metal_io_init(vr->shm_device.regions, (void *) vr->shm_addr,
		      vr->shm_physmap, vr->shm_size, -1, 0, NULL);

	err = libmetal_setup(vr);
	if (err != 0) {
		return err;
	}

	return vq_setup(vr, role);
}
