/*
 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
#include "priv.h"

#include <subdev/mc.h>
#include <subdev/timer.h>

static const char *
managed_falcons_names[] = {
	[NVKM_SECBOOT_FALCON_PMU] = "PMU",
	[NVKM_SECBOOT_FALCON_RESERVED] = "<reserved>",
	[NVKM_SECBOOT_FALCON_FECS] = "FECS",
	[NVKM_SECBOOT_FALCON_GPCCS] = "GPCCS",
	[NVKM_SECBOOT_FALCON_END] = "<invalid>",
};

/*
 * Helper falcon functions
 */

static int
falcon_clear_halt_interrupt(struct nvkm_device *device, u32 base)
{
	int ret;

	/* clear halt interrupt */
	nvkm_mask(device, base + 0x004, 0x10, 0x10);
	/* wait until halt interrupt is cleared */
	ret = nvkm_wait_msec(device, 10, base + 0x008, 0x10, 0x0);
	if (ret < 0)
		return ret;

	return 0;
}

static int
falcon_wait_idle(struct nvkm_device *device, u32 base)
{
	int ret;

	ret = nvkm_wait_msec(device, 10, base + 0x04c, 0xffff, 0x0);
	if (ret < 0)
		return ret;

	return 0;
}

static int
nvkm_secboot_falcon_enable(struct nvkm_secboot *sb)
{
	struct nvkm_device *device = sb->subdev.device;
	int ret;

	/* enable engine */
	nvkm_mc_enable(device, sb->devidx);
	ret = nvkm_wait_msec(device, 10, sb->base + 0x10c, 0x6, 0x0);
	if (ret < 0) {
		nvkm_error(&sb->subdev, "Falcon mem scrubbing timeout\n");
		nvkm_mc_disable(device, sb->devidx);
		return ret;
	}

	ret = falcon_wait_idle(device, sb->base);
	if (ret)
		return ret;

	/* enable IRQs */
	nvkm_wr32(device, sb->base + 0x010, 0xff);
	nvkm_mc_intr_mask(device, sb->devidx, true);

	return 0;
}

static int
nvkm_secboot_falcon_disable(struct nvkm_secboot *sb)
{
	struct nvkm_device *device = sb->subdev.device;

	/* disable IRQs and wait for any previous code to complete */
	nvkm_mc_intr_mask(device, sb->devidx, false);
	nvkm_wr32(device, sb->base + 0x014, 0xff);

	falcon_wait_idle(device, sb->base);

	/* disable engine */
	nvkm_mc_disable(device, sb->devidx);

	return 0;
}

int
nvkm_secboot_falcon_reset(struct nvkm_secboot *sb)
{
	int ret;

	ret = nvkm_secboot_falcon_disable(sb);
	if (ret)
		return ret;

	ret = nvkm_secboot_falcon_enable(sb);
	if (ret)
		return ret;

	return 0;
}

/**
 * nvkm_secboot_falcon_run - run the falcon that will perform secure boot
 *
 * This function is to be called after all chip-specific preparations have
 * been completed. It will start the falcon to perform secure boot, wait for
 * it to halt, and report if an error occurred.
 */
int
nvkm_secboot_falcon_run(struct nvkm_secboot *sb)
{
	struct nvkm_device *device = sb->subdev.device;
	int ret;

	/* Start falcon */
	nvkm_wr32(device, sb->base + 0x100, 0x2);

	/* Wait for falcon halt */
	ret = nvkm_wait_msec(device, 100, sb->base + 0x100, 0x10, 0x10);
	if (ret < 0)
		return ret;

	/* If mailbox register contains an error code, then ACR has failed */
	ret = nvkm_rd32(device, sb->base + 0x040);
	if (ret) {
		nvkm_error(&sb->subdev, "ACR boot failed, ret 0x%08x", ret);
		falcon_clear_halt_interrupt(device, sb->base);
		return -EINVAL;
	}

	return 0;
}


/**
 * nvkm_secboot_reset() - reset specified falcon
 */
int
nvkm_secboot_reset(struct nvkm_secboot *sb, u32 falcon)
{
	/* Unmanaged falcon? */
	if (!(BIT(falcon) & sb->func->managed_falcons)) {
		nvkm_error(&sb->subdev, "cannot reset unmanaged falcon!\n");
		return -EINVAL;
	}

	return sb->func->reset(sb, falcon);
}

/**
 * nvkm_secboot_start() - start specified falcon
 */
int
nvkm_secboot_start(struct nvkm_secboot *sb, u32 falcon)
{
	/* Unmanaged falcon? */
	if (!(BIT(falcon) & sb->func->managed_falcons)) {
		nvkm_error(&sb->subdev, "cannot start unmanaged falcon!\n");
		return -EINVAL;
	}

	return sb->func->start(sb, falcon);
}

/**
 * nvkm_secboot_is_managed() - check whether a given falcon is securely-managed
 */
bool
nvkm_secboot_is_managed(struct nvkm_secboot *secboot,
			enum nvkm_secboot_falcon fid)
{
	if (!secboot)
		return false;

	return secboot->func->managed_falcons & BIT(fid);
}

static int
nvkm_secboot_oneinit(struct nvkm_subdev *subdev)
{
	struct nvkm_secboot *sb = nvkm_secboot(subdev);
	int ret = 0;

	/* Call chip-specific init function */
	if (sb->func->init)
		ret = sb->func->init(sb);
	if (ret) {
		nvkm_error(subdev, "Secure Boot initialization failed: %d\n",
			   ret);
		return ret;
	}

	return 0;
}

static int
nvkm_secboot_fini(struct nvkm_subdev *subdev, bool suspend)
{
	struct nvkm_secboot *sb = nvkm_secboot(subdev);
	int ret = 0;

	if (sb->func->fini)
		ret = sb->func->fini(sb, suspend);

	return ret;
}

static void *
nvkm_secboot_dtor(struct nvkm_subdev *subdev)
{
	struct nvkm_secboot *sb = nvkm_secboot(subdev);
	void *ret = NULL;

	if (sb->func->dtor)
		ret = sb->func->dtor(sb);

	return ret;
}

static const struct nvkm_subdev_func
nvkm_secboot = {
	.oneinit = nvkm_secboot_oneinit,
	.fini = nvkm_secboot_fini,
	.dtor = nvkm_secboot_dtor,
};

int
nvkm_secboot_ctor(const struct nvkm_secboot_func *func,
		  struct nvkm_device *device, int index,
		  struct nvkm_secboot *sb)
{
	unsigned long fid;

	nvkm_subdev_ctor(&nvkm_secboot, device, index, &sb->subdev);
	sb->func = func;

	/* setup the performing falcon's base address and masks */
	switch (func->boot_falcon) {
	case NVKM_SECBOOT_FALCON_PMU:
		sb->devidx = NVKM_SUBDEV_PMU;
		sb->base = 0x10a000;
		break;
	default:
		nvkm_error(&sb->subdev, "invalid secure boot falcon\n");
		return -EINVAL;
	};

	nvkm_debug(&sb->subdev, "securely managed falcons:\n");
	for_each_set_bit(fid, &sb->func->managed_falcons,
			 NVKM_SECBOOT_FALCON_END)
		nvkm_debug(&sb->subdev, "- %s\n", managed_falcons_names[fid]);

	return 0;
}
