/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2010 Mark Marshall
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 */

#include <stdlib.h>
#include <string.h>
#include "flash.h"
#include "programmer.h"
#include "hwaccess.h"

#define PCI_VENDOR_ID_OGP 0x1227

/* These are the register addresses for the OGD1 / OGA1.  If they are
 * different for later versions of the hardware then we will need
 * logic to select between the different hardware versions. */
#define OGA1_XP10_BPROM_SI			     0x0040 /*	W */
#define OGA1_XP10_BPROM_SO			     0x0040 /*	R */
#define OGA1_XP10_BPROM_CE_BAR			     0x0044 /*	W */
#define OGA1_XP10_BPROM_SCK			     0x0048 /*	W */
#define OGA1_XP10_BPROM_REG_SEL			     0x004C /*	W */
#define OGA1_XP10_CPROM_SI			     0x0050 /*	W */
#define OGA1_XP10_CPROM_SO			     0x0050 /*	R */
#define OGA1_XP10_CPROM_CE_BAR			     0x0054 /*	W */
#define OGA1_XP10_CPROM_SCK			     0x0058 /*	W */
#define OGA1_XP10_CPROM_REG_SEL			     0x005C /*	W */

static uint8_t *ogp_spibar;

static uint32_t ogp_reg_sel;
static uint32_t ogp_reg_siso;
static uint32_t ogp_reg__ce;
static uint32_t ogp_reg_sck;

const struct pcidev_status ogp_spi[] = {
	{PCI_VENDOR_ID_OGP, 0x0000, OK, "Open Graphics Project", "Development Board OGD1"},
	{},
};

static void ogp_request_spibus(void)
{
	pci_mmio_writel(1, ogp_spibar + ogp_reg_sel);
}

static void ogp_release_spibus(void)
{
	pci_mmio_writel(0, ogp_spibar + ogp_reg_sel);
}

static void ogp_bitbang_set_cs(int val)
{
	pci_mmio_writel(val, ogp_spibar + ogp_reg__ce);
}

static void ogp_bitbang_set_sck(int val)
{
	pci_mmio_writel(val, ogp_spibar + ogp_reg_sck);
}

static void ogp_bitbang_set_mosi(int val)
{
	pci_mmio_writel(val, ogp_spibar + ogp_reg_siso);
}

static int ogp_bitbang_get_miso(void)
{
	uint32_t tmp;

	tmp = pci_mmio_readl(ogp_spibar + ogp_reg_siso);
	return tmp & 0x1;
}

static const struct bitbang_spi_master bitbang_spi_master_ogp = {
	.type = BITBANG_SPI_MASTER_OGP,
	.set_cs = ogp_bitbang_set_cs,
	.set_sck = ogp_bitbang_set_sck,
	.set_mosi = ogp_bitbang_set_mosi,
	.get_miso = ogp_bitbang_get_miso,
	.request_bus = ogp_request_spibus,
	.release_bus = ogp_release_spibus,
	.half_period = 0,
};

static int ogp_spi_shutdown(void *data)
{
	physunmap(ogp_spibar, 4096);
	pci_cleanup(pacc);

	return 0;
}

int ogp_spi_init(void)
{
	char *type;

	type = extract_programmer_param("rom");

	if (!type) {
		msg_perr("Please use flashrom -p ogp_spi:rom=... to specify "
			 "which flashchip you want to access.\n");
		return 1;
	} else if (!strcasecmp(type, "bprom") || !strcasecmp(type, "bios")) {
		ogp_reg_sel  = OGA1_XP10_BPROM_REG_SEL;
		ogp_reg_siso = OGA1_XP10_BPROM_SI;
		ogp_reg__ce  = OGA1_XP10_BPROM_CE_BAR;
		ogp_reg_sck  = OGA1_XP10_BPROM_SCK;
	} else if (!strcasecmp(type, "cprom") || !strcasecmp(type, "s3")) {
		ogp_reg_sel  = OGA1_XP10_CPROM_REG_SEL;
		ogp_reg_siso = OGA1_XP10_CPROM_SI;
		ogp_reg__ce  = OGA1_XP10_CPROM_CE_BAR;
		ogp_reg_sck  = OGA1_XP10_CPROM_SCK;
	} else {
		msg_perr("Invalid or missing rom= parameter.\n");
		return 1;
	}

	if (rget_io_perms())
		return 1;

	io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, ogp_spi);

	ogp_spibar = physmap("OGP registers", io_base_addr, 4096);

	if (register_shutdown(ogp_spi_shutdown, NULL))
		return 1;

	if (bitbang_spi_init(&bitbang_spi_master_ogp))
		return 1;

	return 0;
}
