/*
 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch_helpers.h>
#include <assert.h>
#include <io/io_block.h>
#include <mmio.h>
#include <platform_def.h>
#include <sys/types.h>
#include <utils_def.h>

#include "uniphier.h"

#define UNIPHIER_LD11_USB_DESC_BASE	0x30010000
#define UNIPHIER_LD20_USB_DESC_BASE	0x30014000

#define UNIPHIER_SRB_OCM_CONT		0x61200000

struct uniphier_ld11_trans_op {
	uint8_t __pad[48];
};

struct uniphier_ld11_op {
	uint8_t __pad[56];
	struct uniphier_ld11_trans_op *trans_op;
	void *__pad2;
	void *dev_desc;
};

struct uniphier_ld20_trans_op {
	uint8_t __pad[40];
};

struct uniphier_ld20_op {
	uint8_t __pad[192];
	struct uniphier_ld20_trans_op *trans_op;
	void *__pad2;
	void *dev_desc;
};

static int (*__uniphier_usb_read)(int lba, uintptr_t buf, size_t size);

static void uniphier_ld11_usb_init(void)
{
	struct uniphier_ld11_op *op = (void *)UNIPHIER_LD11_USB_DESC_BASE;

	op->trans_op = (void *)(op + 1);

	op->dev_desc = op->trans_op + 1;
}

static int uniphier_ld11_usb_read(int lba, uintptr_t buf, size_t size)
{
	static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
				   unsigned int size, uintptr_t buf);
	uintptr_t func_addr;

	func_addr = uniphier_get_soc_revision() == 1 ? 0x3880 : 0x3958;
	rom_usb_read = (__typeof(rom_usb_read))func_addr;

	return rom_usb_read(UNIPHIER_LD11_USB_DESC_BASE, lba, size, buf);
}

static void uniphier_ld20_usb_init(void)
{
	struct uniphier_ld20_op *op = (void *)UNIPHIER_LD20_USB_DESC_BASE;

	op->trans_op = (void *)(op + 1);

	op->dev_desc = op->trans_op + 1;
}

static int uniphier_ld20_usb_read(int lba, uintptr_t buf, size_t size)
{
	static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
				   unsigned int size, uintptr_t buf);
	int ret;

	rom_usb_read = (__typeof(rom_usb_read))0x37f0;

	mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0x1ff);

	/* ROM-API - return 1 on success, 0 on error */
	ret = rom_usb_read(UNIPHIER_LD20_USB_DESC_BASE, lba, size, buf);

	mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0);

	return ret ? 0 : -1;
}

static int uniphier_pxs3_usb_read(int lba, uintptr_t buf, size_t size)
{
	static int (*rom_usb_read)(unsigned int lba, unsigned int size,
				   uintptr_t buf);

	rom_usb_read = (__typeof(rom_usb_read))0x100c;

	return rom_usb_read(lba, size, buf);
}

struct uniphier_usb_rom_param {
	void (*init)(void);
	int (*read)(int lba, uintptr_t buf, size_t size);
};

static const struct uniphier_usb_rom_param uniphier_usb_rom_params[] = {
	[UNIPHIER_SOC_LD11] = {
		.init = uniphier_ld11_usb_init,
		.read = uniphier_ld11_usb_read,
	},
	[UNIPHIER_SOC_LD20] = {
		.init = uniphier_ld20_usb_init,
		.read = uniphier_ld20_usb_read,
	},
	[UNIPHIER_SOC_PXS3] = {
		.read = uniphier_pxs3_usb_read,
	},
};

static size_t uniphier_usb_read(int lba, uintptr_t buf, size_t size)
{
	int ret;

	inv_dcache_range(buf, size);

	ret = __uniphier_usb_read(lba, buf, size);

	inv_dcache_range(buf, size);

	return ret ? 0 : size;
}

static struct io_block_dev_spec uniphier_usb_dev_spec = {
	.buffer = {
		.offset = UNIPHIER_BLOCK_BUF_BASE,
		.length = UNIPHIER_BLOCK_BUF_SIZE,
	},
	.ops = {
		.read = uniphier_usb_read,
	},
	.block_size = 512,
};

int uniphier_usb_init(unsigned int soc, uintptr_t *block_dev_spec)
{
	const struct uniphier_usb_rom_param *param;

	assert(soc < ARRAY_SIZE(uniphier_usb_rom_params));
	param = &uniphier_usb_rom_params[soc];

	if (param->init)
		param->init();

	__uniphier_usb_read = param->read;

	*block_dev_spec = (uintptr_t)&uniphier_usb_dev_spec;

	return 0;
}
