/* SPDX-License-Identifier: GPL-2.0-only */

#include <device/pci_ops.h>
#include <assert.h>
#include <cbmem.h>
#include <commonlib/sdhci.h>
#include <commonlib/storage.h>
#include <console/console.h>
#include <lib.h>
#include <soc/iomap.h>
#include <soc/pci_devs.h>
#include <soc/storage_test.h>
#include <timer.h>
#include <string.h>

#if CONFIG(STORAGE_LOG)
struct log_entry log[LOG_ENTRIES];
uint8_t log_index;
int log_full;
long log_start_time;
#endif

static uint8_t drivers_storage[256];

#define STORAGE_DEBUG  BIOS_DEBUG
#define LOG_DEBUG  (CONFIG(STORAGE_LOG) ? STORAGE_DEBUG : BIOS_NEVER)

#ifdef __SIMPLE_DEVICE__
uint32_t storage_test_init(pci_devfn_t dev, uint32_t *previous_bar,
	uint16_t *previous_command)
#else
uint32_t storage_test_init(struct device *dev, uint32_t *previous_bar,
	uint16_t *previous_command)
#endif
{
	uint32_t bar;

	/* Display the vendor/device IDs */
	printk(LOG_DEBUG, "Vendor ID: 0x%04x, Device ID: 0x%04x\n",
		pci_read_config16(dev, PCI_VENDOR_ID),
		pci_read_config16(dev, PCI_DEVICE_ID));

	/* Set the temporary base address */
	bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
	*previous_bar = bar;
	bar &= ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
	if (!bar) {
		bar = SD_BASE_ADDRESS;
		pci_write_config32(dev, PCI_BASE_ADDRESS_0, bar);
	}

	/* Enable the SD/MMC controller */
	*previous_command = pci_read_config16(dev, PCI_COMMAND);
	pci_write_config16(dev, PCI_COMMAND, *previous_command
		| PCI_COMMAND_MEMORY);

	/* Return the controller address */
	return bar;
}

#ifdef __SIMPLE_DEVICE__
void storage_test_complete(pci_devfn_t dev, uint32_t previous_bar,
	uint16_t previous_command)
#else
void storage_test_complete(struct device *dev, uint32_t previous_bar,
	uint16_t previous_command)
#endif
{
	pci_write_config16(dev, PCI_COMMAND, previous_command);
	pci_write_config32(dev, PCI_BASE_ADDRESS_0, previous_bar);
}

#if !ENV_BOOTBLOCK
static void display_log(void)
{
	/* Determine the array bounds */
	if (CONFIG(STORAGE_LOG)) {
		long delta;
		uint8_t end;
		uint8_t index;
		uint8_t start;

		end = log_index;
		start = log_full ? log_index : 0;
		for (index = start; (log_full || (index != end)); index++) {
			log_full = 0;
			delta = log[index].time.microseconds - log_start_time;
			printk(BIOS_DEBUG, "%3ld.%03ld mSec, cmd: %2d 0x%08x%s",
				delta / 1000, delta % 1000,
				log[index].cmd.cmdidx,
				log[index].cmd.cmdarg,
				log[index].cmd_issued ? "" : "(not issued)");
			if (log[index].response_entries == 1)
				printk(BIOS_DEBUG, ", rsp: 0x%08x",
					log[index].response[0]);
			else if (log[index].response_entries == 4)
				printk(BIOS_DEBUG,
					", rsp: 0x%08x.%08x.%08x.%08x",
					log[index].response[3],
					log[index].response[2],
					log[index].response[1],
					log[index].response[0]);
			printk(BIOS_DEBUG, ", ret: %d\n", log[index].ret);
		}
	}
}

void sdhc_log_command(struct mmc_command *cmd)
{
	if (CONFIG(STORAGE_LOG)) {
		timer_monotonic_get(&log[log_index].time);
		log[log_index].cmd = *cmd;
		log[log_index].cmd_issued = 0;
		log[log_index].response_entries = 0;
		if ((log_index == 0) && (!log_full))
			log_start_time = log[0].time.microseconds;
	}
}

void sdhc_log_command_issued(void)
{
	if (CONFIG(STORAGE_LOG)) {
		log[log_index].cmd_issued = 1;
	}
}

void sdhc_log_response(uint32_t entries, uint32_t *response)
{
	unsigned int entry;

	if (CONFIG(STORAGE_LOG)) {
		log[log_index].response_entries = entries;
		for (entry = 0; entry < entries; entry++)
			log[log_index].response[entry] = response[entry];
	}
}

void sdhc_log_ret(int ret)
{
	if (CONFIG(STORAGE_LOG)) {
		log[log_index].ret = ret;
		if (++log_index == 0)
			log_full = 1;
	}
}

void storage_test(uint32_t bar, int full_initialization)
{
	uint64_t blocks_read;
	uint8_t buffer[512];
	int err;
	struct storage_media *media;
	const char *name;
	unsigned int partition;
	unsigned int previous_partition;
	struct sdhci_ctrlr *sdhci_ctrlr;

	ASSERT(sizeof(struct sdhci_ctrlr) <= sizeof(drivers_storage));

	/* Get the structure addresses */
	media = NULL;
	if (ENV_ROMSTAGE)
		media = (struct storage_media *)drivers_storage;
	else
		media = cbmem_find(CBMEM_ID_STORAGE_DATA);
	sdhci_ctrlr = (void *)(((uintptr_t)(media + 1) + 0x7) & ~7);
	media->ctrlr = (struct sd_mmc_ctrlr *)sdhci_ctrlr;
	sdhci_ctrlr->ioaddr = (void *)bar;

	/* Initialize the controller */
	if (!full_initialization) {
		/* Perform fast initialization */
		sdhci_update_pointers(sdhci_ctrlr);
		sdhci_display_setup(sdhci_ctrlr);
		storage_display_setup(media);
	} else {
		/* Initialize the log */
		if (CONFIG(STORAGE_LOG)) {
			log_index = 0;
			log_full = 0;
		}

		printk(LOG_DEBUG, "Initializing the SD/MMC controller\n");
		err = sdhci_controller_init(sdhci_ctrlr, (void *)bar);
		if (err) {
			display_log();
			printk(BIOS_ERR,
				"ERROR - Controller failed to initialize, err = %d\n",
				err);
			return;
		}

		/* Initialize the SD/MMC/eMMC card or device */
		printk(LOG_DEBUG, "Initializing the device\n");
		err = storage_setup_media(media, &sdhci_ctrlr->sd_mmc_ctrlr);
		if (err) {
			display_log();
			printk(BIOS_ERR,
				"ERROR: Device failed to initialize, err = %d\n",
				err);
			return;
		}
		display_log();
	}

	/* Save the current partition */
	previous_partition = storage_get_current_partition(media);

	/* Read block 0 from each partition */
	for (partition = 0; partition < ARRAY_SIZE(media->capacity);
		partition++) {
		if (media->capacity[partition] == 0)
			continue;
		name = storage_partition_name(media, partition);
		printk(STORAGE_DEBUG, "%s%sReading block 0\n", name,
			name[0] ? ": " : "");
		err = storage_set_partition(media, partition);
		if (err)
			continue;
		blocks_read = storage_block_read(media, 0, 1, &buffer);
		if (blocks_read)
			hexdump(buffer, sizeof(buffer));
	}

	/* Restore the previous partition */
	storage_set_partition(media, previous_partition);
}
#endif

#if ENV_ROMSTAGE
static void copy_storage_structures(int is_recovery)
{
	struct storage_media *media;
	struct sdhci_ctrlr *sdhci_ctrlr;
	size_t size = sizeof(drivers_storage);

	/* Locate the data structures in CBMEM */
	media = cbmem_add(CBMEM_ID_STORAGE_DATA, size);
	ASSERT(media != NULL);
	sdhci_ctrlr = (void *)(((uintptr_t)(media + 1) + 0x7) & ~7);

	/* Migrate the data into CBMEM */
	memcpy(media, drivers_storage, size);
	media->ctrlr = &sdhci_ctrlr->sd_mmc_ctrlr;
}

ROMSTAGE_CBMEM_INIT_HOOK(copy_storage_structures);
#endif
