/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
 * Copyright (C) 2012 Advanced Micro Devices, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <arch/io.h>
#include <console/console.h>
#include <spi-generic.h>
#include <spi_flash.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ops.h>

#define AMD_SB_SPI_TX_LEN 8

static uint32_t get_spi_bar(void)
{
	device_t dev;

	dev = dev_find_slot(0, PCI_DEVFN(0x14, 3));
	return pci_read_config32(dev, 0xa0) & ~0x1f;
}

void spi_init(void)
{
	/* Not needed */
}

unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
{
	return min(AMD_SB_SPI_TX_LEN - cmd_len, buf_len);
}

static void reset_internal_fifo_pointer(void)
{
	uint32_t spibar = get_spi_bar();

	do {
		write8((void *)(spibar + 2),
		read8((void *)(spibar + 2)) | 0x10);
	} while (read8((void *)(spibar + 0xd)) & 0x7);
}

static void execute_command(void)
{
	uint32_t spibar = get_spi_bar();

	write8((void *)(spibar + 2), read8((void *)(spibar + 2)) | 1);

	while ((read8((void *)(spibar + 2)) & 1) &&
		(read8((void *)(spibar+3)) & 0x80));
}

int spi_claim_bus(struct spi_slave *slave)
{
	/* Handled internally by the SB700 */
	return 0;
}

void spi_release_bus(struct spi_slave *slave)
{
	/* Handled internally by the SB700 */
}

struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
{
	struct spi_slave *slave = malloc(sizeof(*slave));

	if (!slave) {
		return NULL;
	}

	memset(slave, 0, sizeof(*slave));

	return slave;
}

int spi_xfer(struct spi_slave *slave, const void *dout,
		unsigned int bytesout, void *din, unsigned int bytesin)
{
	/* First byte is cmd which cannot be sent through the FIFO. */
	u8 cmd = *(u8 *)dout++;
	u8 readoffby1;
	u8 readwrite;
	u8 count;

	uint32_t spibar = get_spi_bar();

	bytesout--;

	/*
	 * Check if this is a write command attempting to transfer more bytes
	 * than the controller can handle. Iterations for writes are not
	 * supported here because each SPI write command needs to be preceded
	 * and followed by other SPI commands, and this sequence is controlled
	 * by the SPI chip driver.
	 */
	if (bytesout > AMD_SB_SPI_TX_LEN) {
		printk(BIOS_DEBUG, "FCH SPI: Too much to write. Does your SPI chip driver use"
		     " spi_crop_chunk()?\n");
		return -1;
	}

	readoffby1 = bytesout ? 0 : 1;

	readwrite = (bytesin + readoffby1) << 4 | bytesout;
	write8((void *)(spibar + 1), readwrite);
	write8((void *)(spibar + 0), cmd);

	reset_internal_fifo_pointer();
	for (count = 0; count < bytesout; count++, dout++) {
		write8((void *)(spibar + 0x0C), *(u8 *)dout);
	}

	reset_internal_fifo_pointer();
	execute_command();

	reset_internal_fifo_pointer();
	/* Skip the bytes we sent. */
	for (count = 0; count < bytesout; count++) {
		cmd = read8((void *)(spibar + 0x0C));
	}

	reset_internal_fifo_pointer();
	for (count = 0; count < bytesin; count++, din++) {
		*(u8 *)din = read8((void *)(spibar + 0x0C));
	}

	return 0;
}