/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2010 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * Neither the name of Google or the names of contributors or
 * licensors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any kind.
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
 * GOOGLE INC AND ITS LICENSORS SHALL NOT BE LIABLE
 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
 * GOOGLE OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
 * EVEN IF GOOGLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 */

#if defined(__i386__) || defined(__x86_64__)
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "flash.h"
#include "chipdrivers.h"
#include "programmer.h"
#include "spi.h"

#define MEC1308_SIO_PORT1	0x2e
#define MEC1308_SIO_PORT2	0x4e
#define MEC1308_SIO_ENTRY_KEY	0x55
#define MEC1308_SIO_EXIT_KEY	0xaa

#define MEC1308_SIOCFG_LDN	0x07	/* LDN Bank Selector */
#define MEC1308_DEVICE_ID_REG	0x20	/* Device ID Register */
#define MEC1308_DEVICE_ID_VAL	0x4d	/* Device ID Value for MEC1308 */
#define MEC1310_DEVICE_ID_VAL	0x04	/* Device ID Value for MEC1310 */
#define MEC1308_DEVICE_REV	0x21	/* Device Revision ID Register */

static unsigned int in_sio_cfgmode;

#define MEC1308_MBX_CMD		0x82	/* mailbox command register offset */
#define MEC1308_MBX_EXT_CMD	0x83	/* mailbox ext. command reg offset */
#define MEC1308_MBX_DATA_START	0x84	/* first mailbox data register offset */
#define MEC1308_MBX_DATA_END	0x91	/* last mailbox data register offset */

static unsigned int mbx_idx;	/* Mailbox register interface index address */
static unsigned int mbx_data;	/* Mailbox register interface data address*/

/*
 * These command codes depend on EC firmware. The ones listed below are input
 * using the mailbox interface, though others may be input using the ACPI
 * interface. Some commands also have an output value (ie pass/failure code)
 * which EC writes to the mailbox command register after completion.
 */
#define MEC1308_CMD_SMI_ENABLE		0x84
#define MEC1308_CMD_SMI_DISABLE		0x85
#define MEC1308_CMD_ACPI_ENABLE		0x86
#define MEC1308_CMD_ACPI_DISABLE	0x87

/*
 * Passthru commands are also input using the mailbox interface. Passthru mode
 * enter/start/end commands are special since they require a command word to
 * be written to the data registers. Other passthru commands are performed
 * after passthru mode has been started.
 *
 * Multiple passthru mode commands may be issued before ending passthru mode.
 * You do not need to enter, start, and end passthru mode for each SPI
 * command. However, other mailbox commands might not work when passthru mode
 * is enabled. For example, you may read all SPI chip content while in passthru
 * mode, but you should exit passthru mode before performing other EC commands
 * such as reading fan speed.
 */
#define MEC1308_CMD_PASSTHRU		0x55	/* force EC to process word */
#define MEC1308_CMD_PASSTHRU_SUCCESS	0xaa	/* success code for passthru */
#define MEC1308_CMD_PASSTHRU_FAIL	0xfe	/* failure code for passthru */
#define MEC1308_CMD_PASSTHRU_ENTER	"PathThruMode"	/* not a typo... */
#define MEC1308_CMD_PASSTHRU_START	"Start"
#define MEC1308_CMD_PASSTHRU_EXIT	"End_Mode"
#define MEC1308_CMD_PASSTHRU_CS_EN	0xf0	/* chip-select enable */
#define MEC1308_CMD_PASSTHRU_CS_DIS	0xf1	/* chip-select disable */
#define MEC1308_CMD_PASSTHRU_SEND	0xf2	/* send byte from data0 */
#define MEC1308_CMD_PASSTHRU_READ	0xf3	/* read byte, place in data0 */

static void mec1308_sio_enter(uint16_t port)
{
	if (in_sio_cfgmode)
		return;

	OUTB(MEC1308_SIO_ENTRY_KEY, port);
	in_sio_cfgmode = 1;
}

static void mec1308_sio_exit(uint16_t port)
{
	if (!in_sio_cfgmode)
		return;

	OUTB(MEC1308_SIO_EXIT_KEY, port);
	in_sio_cfgmode = 0;
}

/** probe for super i/o index
 * @port: allocated buffer to store port
 *
 * returns 0 to indicate success, <0 to indicate error
 */
static int mec1308_get_sio_index(uint16_t *port)
{
	uint16_t ports[] = { MEC1308_SIO_PORT1,
	                     MEC1308_SIO_PORT2,
	};
	int i;
	static uint16_t port_internal, port_found = 0;

	if (port_found) {
		*port = port_internal;
		return 0;
	}

	if (rget_io_perms())
		return -1;

	for (i = 0; i < ARRAY_SIZE(ports); i++) {
		uint8_t tmp8;

		/*
		 * Only after config mode has been successfully entered will the
		 * index port will read back the last value written to it.
		 * So we will attempt to enter config mode, set the index
		 * register, and see if the index register retains the value.
		 *
		 * Note: It seems to work "best" when using a device ID register
		 * as the index and reading from the data port before reading
		 * the index port.
		 */
		mec1308_sio_enter(ports[i]);
		OUTB(MEC1308_DEVICE_ID_REG, ports[i]);
		tmp8 = INB(ports[i] + 1);
		tmp8 = INB(ports[i]);
		if ((tmp8 != MEC1308_DEVICE_ID_REG)) {
			in_sio_cfgmode = 0;
			continue;
		}

		port_internal = ports[i];
		port_found = 1;
		break;
	}

	if (!port_found) {
		msg_cdbg("\nfailed to obtain super i/o index");
		return -1;
	}

	msg_cdbg("\nsuper i/o index = 0x%04x\n", port_internal);
	*port = port_internal;
	return 0;
}

static uint8_t mbx_read(uint8_t idx)
{
	OUTB(idx, mbx_idx);
	return INB(mbx_data);
}

static int mbx_wait(void)
{
	int i;
	int max_attempts = 10000;
	int rc = 0;

	for (i = 0; mbx_read(MEC1308_MBX_CMD); i++) {
		if (i == max_attempts) {
			rc = 1;
			break;
		}
		/* FIXME: This delay adds determinism to the delay period. It
		   was chosen arbitrarily thru some experiments. */
		programmer_delay(2);
	}

	return rc;
}

static int mbx_write(uint8_t idx, uint8_t data)
{
	int rc = 0;

	if (idx == MEC1308_MBX_CMD && mbx_wait()) {
		msg_perr("%s: command register not clear\n", __func__);
		return 1;
	}

	OUTB(idx, mbx_idx);
	OUTB(data, mbx_data);

	if (idx == MEC1308_MBX_CMD)
		rc = mbx_wait();

	return rc;
}

static void mbx_clear()
{
	int reg;

	for (reg = MEC1308_MBX_DATA_START; reg < MEC1308_MBX_DATA_END; reg++)
		mbx_write(reg, 0x00);
	mbx_write(MEC1308_MBX_CMD, 0x00);
}

static int mec1308_exit_passthru_mode(void)
{
	uint8_t tmp8;
	int i;

	/* exit passthru mode */
	for (i = 0; i < strlen(MEC1308_CMD_PASSTHRU_EXIT); i++) {
		mbx_write(MEC1308_MBX_DATA_START + i,
		MEC1308_CMD_PASSTHRU_EXIT[i]);
	}

	if (mbx_write(MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU)) {
		msg_pdbg("%s(): exit passthru command timed out\n", __func__);
		return 1;
	}

	tmp8 = mbx_read(MEC1308_MBX_DATA_START);
	msg_pdbg("%s: result: 0x%02x ", __func__, tmp8);
	if (tmp8 == MEC1308_CMD_PASSTHRU_SUCCESS) {
		msg_pdbg("(exited passthru mode)\n");
	} else if (tmp8 == MEC1308_CMD_PASSTHRU_FAIL) {
		msg_pdbg("(failed to exit passthru mode)\n");
	}

	return 0;
}

static int enter_passthru_mode(void)
{
	uint8_t tmp8;
	int i;

	/*
	 * Enter passthru mode. If the EC does not successfully enter passthru
	 * mode the first time, we'll clear the mailbox and issue the "exit
	 * passthru mode" command sequence up to 3 times or until it arrives in
	 * a known state.
	 *
	 * Note: This workaround was developed experimentally.
	 */
	for (i = 0; i < 3; i++) {
		int j;

		msg_pdbg("%s(): entering passthru mode, attempt %d out of 3\n",
		         __func__, i + 1);
		for (j = 0; j < strlen(MEC1308_CMD_PASSTHRU_ENTER); j++) {
			mbx_write(MEC1308_MBX_DATA_START + j,
			          MEC1308_CMD_PASSTHRU_ENTER[j]);
		}

		if (mbx_write(MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU))
			msg_pdbg("%s(): enter passthru command timed out\n",
			         __func__);

		tmp8 = mbx_read(MEC1308_MBX_DATA_START);
		if (tmp8 == MEC1308_CMD_PASSTHRU_SUCCESS)
			break;

		msg_pdbg("%s(): command failed, clearing data registers and "
		         "issuing full exit passthru command...\n", __func__);
		mbx_clear();
		mec1308_exit_passthru_mode();
	}

	if (tmp8 != MEC1308_CMD_PASSTHRU_SUCCESS) {
		msg_perr("%s(): failed to enter passthru mode, result=0x%02x\n",
		         __func__, tmp8);
		return 1;
	}

	msg_pdbg("%s(): enter passthru mode return code: 0x%02x\n",
	         __func__, tmp8);

	/* start passthru mode */
	for (i = 0; i < strlen(MEC1308_CMD_PASSTHRU_START); i++)
		mbx_write(MEC1308_MBX_DATA_START + i,
		          MEC1308_CMD_PASSTHRU_START[i]);
	if (mbx_write(MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU)) {
		msg_pdbg("%s(): start passthru command timed out\n", __func__);
		return 1;
	}
	tmp8 = mbx_read(MEC1308_MBX_DATA_START);
	if (tmp8 != MEC1308_CMD_PASSTHRU_SUCCESS) {
		msg_perr("%s(): failed to enter passthru mode, result=%02x\n",
		         __func__, tmp8);
		return 1;
	}
	msg_pdbg("%s(): start passthru mode return code: 0x%02x\n",
	         __func__, tmp8);

	return 0;
}

static int mec1308_shutdown(void *data)
{
	/* Exit passthru mode before performing commands which do not affect
	   the SPI ROM */
	mec1308_exit_passthru_mode();

	/* Re-enable SMI and ACPI.
	   FIXME: is there an ordering dependency? */
	if (mbx_write(MEC1308_MBX_CMD, MEC1308_CMD_SMI_ENABLE))
		msg_pdbg("%s: unable to re-enable SMI\n", __func__);
	if (mbx_write(MEC1308_MBX_CMD, MEC1308_CMD_ACPI_ENABLE))
		msg_pdbg("%s: unable to re-enable ACPI\n", __func__);

	return 0;
}

int mec1308_spi_read(struct flashctx *flash, uint8_t * buf, int start, int len)
{
	return spi_read_chunked(flash, buf, start, len,
				flash->chip->page_size);
}

int mec1308_spi_write_256(struct flashctx *flash,
                          uint8_t *buf, int start, int len)
{
	return spi_write_chunked(flash, buf, start, len,
				 flash->chip->page_size);
}

static int mec1308_chip_select(void)
{
	return mbx_write(MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU_CS_EN);
}

static int mec1308_chip_deselect(void)
{
	return mbx_write(MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU_CS_DIS);
}

/*
 * MEC1308 will not allow direct access to SPI chip from host if EC is
 * connected to LPC bus. This function will forward commands issued thru
 * mailbox interface to the SPI flash chip.
 */
int mec1308_spi_send_command(const struct flashctx *flash, unsigned int writecnt,
                             unsigned int readcnt,
                             const unsigned char *writearr,
                             unsigned char *readarr)
{
	int i, rc = 0;

	if (mec1308_chip_select())
		return 1;

	for (i = 0; i < writecnt; i++) {
		if (mbx_write(MEC1308_MBX_DATA_START, writearr[i]) ||
		    mbx_write(MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU_SEND)) {
			msg_pdbg("%s: failed to issue send command\n",__func__);
			rc = 1;
			goto mec1308_spi_send_command_exit;
		}
	}

	for (i = 0; i < readcnt; i++) {
		if (mbx_write(MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU_READ)) {
			msg_pdbg("%s: failed to issue read command\n",__func__);
			rc = 1;
			goto mec1308_spi_send_command_exit;
		}
		readarr[i] = mbx_read(MEC1308_MBX_DATA_START);
	}

mec1308_spi_send_command_exit:
	rc |= mec1308_chip_deselect();
	return rc;
}

static const struct spi_master spi_master_mec1308 = {
	.type = SPI_CONTROLLER_MEC1308,
	.max_data_read = 256,	/* FIXME: should be MAX_DATA_READ_UNLIMITED? */
	.max_data_write = 256,	/* FIXME: should be MAX_DATA_WRITE_UNLIMITED? */
	.command = mec1308_spi_send_command,
	.multicommand = default_spi_send_multicommand,
	.read = default_spi_read,
	.write_256 = default_spi_write_256,
};

/* Called by internal_init() */
int mec1308_probe_spi_flash(const char *name)
{
	uint16_t sio_port;
	uint8_t device_id;
	uint8_t tmp8;
	int ret = 0;
	char *p = NULL;

	msg_pdbg("%s(): entered\n", __func__);

	if (alias && alias->type != ALIAS_EC)
		return 1;

	p = extract_programmer_param("type");
	if (p && strcmp(p, "ec")) {
		msg_pdbg("mec1308 only supports \"ec\" type devices\n");
		ret = 1;
		goto mec1308_probe_spi_flash_exit;
	}

	if (mec1308_get_sio_index(&sio_port) < 0) {
		msg_pdbg("MEC1308 not found (probe failed).\n");
		ret = 1;
		goto mec1308_probe_spi_flash_exit;
	}
	device_id = sio_read(sio_port, MEC1308_DEVICE_ID_REG);
	switch(device_id) {
	case MEC1308_DEVICE_ID_VAL:
		msg_pdbg("Found EC: MEC1308 (ID:0x%02x,Rev:0x%02x) on "
		         "sio_port:0x%x.\n", device_id,
			 sio_read(sio_port, MEC1308_DEVICE_REV), sio_port);
		break;
	case MEC1310_DEVICE_ID_VAL:
		msg_pdbg("Found EC: MEC1310 (ID:0x%02x,Rev:0x%02x) on "
		         "sio_port:0x%x.\n", device_id,
			 sio_read(sio_port, MEC1308_DEVICE_REV), sio_port);
		break;
	default:
		msg_pdbg("MEC1308 not found\n");
		ret = 1;
		goto mec1308_probe_spi_flash_exit;
	}

	/*
	 * setup mailbox interface at LDN 9
	 */
	sio_write(sio_port, MEC1308_SIOCFG_LDN, 0x09);
	tmp8 = sio_read(sio_port, 0x30);
	tmp8 |= 1;
	sio_write(sio_port, 0x30, tmp8);	/* activate logical device */

	mbx_idx = (unsigned int)sio_read(sio_port, 0x60) << 8 |
	                        sio_read(sio_port, 0x61);
	mbx_data = mbx_idx + 1;
	msg_pdbg("%s: mbx_idx: 0x%04x, mbx_data: 0x%04x\n",
	         __func__, mbx_idx, mbx_data);

	/* Exit Super I/O config mode */
	mec1308_sio_exit(sio_port);

	/* Now that we can read the mailbox, we will wait for any remaining
	 * command to finish.*/
	if (mbx_wait() != 0) {
		msg_perr("%s: mailbox is not available\n", __func__);
		ret = 1;
		goto mec1308_probe_spi_flash_exit;
	}

	/* Further setup -- disable SMI and ACPI.
	   FIXME: is there an ordering dependency? */
	if (mbx_write(MEC1308_MBX_CMD, MEC1308_CMD_ACPI_DISABLE)) {
		msg_pdbg("%s: unable to disable ACPI\n", __func__);
		ret = 1;
		goto mec1308_probe_spi_flash_exit;
	}

	if (mbx_write(MEC1308_MBX_CMD, MEC1308_CMD_SMI_DISABLE)) {
		msg_pdbg("%s: unable to disable SMI\n", __func__);
		ret = 1;
		goto mec1308_probe_spi_flash_exit;
	}

	if (register_shutdown(mec1308_shutdown, NULL)) {
		ret = 1;
		goto mec1308_probe_spi_flash_exit;
	}

	/*
	 * Enter SPI Pass-Thru Mode after commands which do not require access
	 * to SPI ROM are complete. We'll start by doing the exit_passthru_mode
	 * sequence, which is benign if the EC is already in passthru mode.
	 */
	mec1308_exit_passthru_mode();

	if (enter_passthru_mode()) {
		ret = 1;
		goto mec1308_probe_spi_flash_exit;
	}

	buses_supported |= BUS_LPC;	/* for LPC <--> SPI bridging */
	register_spi_master(&spi_master_mec1308);
	msg_pdbg("%s(): successfully initialized mec1308\n", __func__);
mec1308_probe_spi_flash_exit:
	free(p);
	return ret;
}
#endif
