/*
 * 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.
 */

#include <stdlib.h>
#include <strings.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;

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

	{0},
};

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 = {
	.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_init(void)
{
	struct pci_dev *dev = NULL;
	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");
		free(type);
		return 1;
	}
	free(type);

	if (rget_io_perms())
		return 1;

	dev = pcidev_init(ogp_spi, PCI_BASE_ADDRESS_0);
	if (!dev)
		return 1;

	uint32_t io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
	if (!io_base_addr)
		return 1;

	ogp_spibar = rphysmap("OGP registers", io_base_addr, 4096);
	if (ogp_spibar == ERROR_PTR)
		return 1;

	if (register_spi_bitbang_master(&bitbang_spi_master_ogp))
		return 1;

	return 0;
}

const struct programmer_entry programmer_ogp_spi = {
	.name			= "ogp_spi",
	.type			= PCI,
	.devs.dev		= ogp_spi,
	.init			= ogp_spi_init,
	.map_flash_region	= fallback_map,
	.unmap_flash_region	= fallback_unmap,
	.delay			= internal_delay,
};
