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

#include <zephyr/ipc/ipc_static_vrings.h>
#include <zephyr/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_DRIVER) {
		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_DEVICE) {
		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);
}
