/* Copyright 2013-2014 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <skiboot.h>
#include <xscom.h>
#include <lock.h>
#include <timebase.h>
#include <chip.h>
#include <fsi-master.h>

/*
 * FSI Masters sit on OPB busses behind PIB2OPB bridges
 *
 * There are two cMFSI behind two different bridges at
 * different XSCOM addresses. For now we don't have them in
 * the device-tree so we hard code the address
 */
#define PIB2OPB_MFSI0_ADDR	0x20000
#define PIB2OPB_MFSI1_ADDR	0x30000

/*
 * Bridge registers on XSCOM that allow generatoin
 * of OPB cycles
 */
#define PIB2OPB_REG_CMD		0x0
#define   OPB_CMD_WRITE		0x80000000
#define   OPB_CMD_READ		0x00000000
#define   OPB_CMD_8BIT		0x00000000
#define   OPB_CMD_16BIT		0x20000000
#define   OPB_CMD_32BIT		0x60000000
#define PIB2OPB_REG_STAT	0x1
#define   OPB_STAT_ANY_ERR	0x80000000
#define   OPB_STAT_ERR_OPB      0x7FEC0000
#define   OPB_STAT_ERRACK       0x00100000
#define   OPB_STAT_BUSY		0x00010000
#define   OPB_STAT_READ_VALID   0x00020000
#define   OPB_STAT_ERR_CMFSI    0x0000FC00
#define   OPB_STAT_ERR_HMFSI    0x000000FC
#define   OPB_STAT_ERR_BASE	(OPB_STAT_ANY_ERR | \
				 OPB_STAT_ERR_OPB | \
				 OPB_STAT_ERRACK)
#define PIB2OPB_REG_LSTAT	0x2
#define PIB2OPB_REG_RESET	0x4
#define PIB2OPB_REG_cRSIC	0x5
#define PIB2OPB_REG_cRSIM       0x6
#define PIB2OPB_REG_cRSIS	0x7
#define PIB2OPB_REG_hRSIC	0x8
#define PIB2OPB_REG_hRSIM	0x9
#define PIB2OPB_REG_hRSIS	0xA

/* Low level errors from OPB contain the status in the bottom 32-bit
 * and one of these in the top 32-bit
 */
#define OPB_ERR_XSCOM_ERR	0x100000000ull
#define OPB_ERR_TIMEOUT_ERR	0x200000000ull
#define OPB_ERR_BAD_OPB_ADDR	0x400000000ull

/*
 * PIB2OPB 0 has 2 MFSIs, cMFSI and hMFSI, PIB2OPB 1 only
 * has cMFSI
 */
#define cMFSI_OPB_PORTS_BASE	0x40000
#define cMFSI_OPB_REG_BASE	0x03000
#define hMFSI_OPB_PORTS_BASE	0x80000
#define hMFSI_OPB_REG_BASE	0x03400
#define MFSI_OPB_PORT_STRIDE	0x08000

/* MFSI control registers */
#define MFSI_REG_MSTAP(__n)	(0x0D0 + (__n) * 4)
#define MFSI_REG_MATRB0		0x1D8
#define MFSI_REG_MDTRB0		0x1DC
#define MFSI_REG_MESRB0		0x1D0
#define MFSI_REG_MAESP0		0x050
#define MFSI_REG_MAEB		0x070
#define MFSI_REG_MSCSB0		0x1D4

/* FSI Slave registers */
#define FSI_SLAVE_REGS		0x000800	/**< FSI Slave Register */
#define FSI_SMODE		(FSI_SLAVE_REGS | 0x00)
#define FSI_SLBUS         	(FSI_SLAVE_REGS | 0x30)
#define FSI_SLRES		(FSI_SLAVE_REGS | 0x34)

#define FSI2PIB_ENGINE		0x001000	/**< FSI2PIB Engine (SCOM) */
#define FSI2PIB_RESET		(FSI2PIB_ENGINE | 0x18)
#define FSI2PIB_STATUS		(FSI2PIB_ENGINE | 0x1C)
#define FSI2PIB_COMPMASK	(FSI2PIB_ENGINE | 0x30)
#define FSI2PIB_TRUEMASK	(FSI2PIB_ENGINE | 0x34)

struct mfsi {
	uint32_t chip_id;
	uint32_t unit;
	uint32_t xscom_base;
	uint32_t ports_base;
	uint32_t reg_base;
	uint32_t err_bits;
};

#define mfsi_log(__lev, __m, __fmt, ...) \
	prlog(__lev, "MFSI %x:%x: " __fmt, __m->chip_id, __m->unit, ##__VA_ARGS__)
/*
 * Use a global FSI lock for now. Beware of re-entrancy
 * if we ever add support for normal chip XSCOM via FSI, in
 * which case we'll probably have to consider either per chip
 * lock (which can have AB->BA deadlock issues) or a re-entrant
 * global lock or something else. ...
 */
static struct lock fsi_lock = LOCK_UNLOCKED;

/*
 * OPB accessors
 */

/* We try up to 1.2ms for an OPB access */
#define MFSI_OPB_MAX_TRIES	1200

static uint64_t mfsi_opb_poll(struct mfsi *mfsi, uint32_t *read_data)
{
	unsigned long retries = MFSI_OPB_MAX_TRIES;
	uint64_t sval;
	uint32_t stat;
	int64_t rc;

	/* We try again every 10us for a bit more than 1ms */
	for (;;) {
		/* Read OPB status register */
		rc = xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_STAT, &sval);
		if (rc) {
			/* Do something here ? */
			mfsi_log(PR_ERR, mfsi, "XSCOM error %lld read OPB STAT\n", rc);
			return OPB_ERR_XSCOM_ERR;
		}
		mfsi_log(PR_INSANE, mfsi, "  STAT=0x%16llx...\n", sval);

		stat = sval >> 32;

		/* Complete */
		if (!(stat & OPB_STAT_BUSY))
			break;
		if (retries-- == 0) {
			/* This isn't supposed to happen (HW timeout) */
			mfsi_log(PR_ERR, mfsi, "OPB POLL timeout !\n");
			return OPB_ERR_TIMEOUT_ERR | (stat & mfsi->err_bits);
		}
		time_wait_us(1);
	}

	/* Did we have an error ? */
	if (stat & mfsi->err_bits)
		return stat & mfsi->err_bits;

	if (read_data) {
		if (!(stat & OPB_STAT_READ_VALID)) {
			mfsi_log(PR_ERR, mfsi, "Read successful but no data !\n");

			/* What do do here ? can it actually happen ? */
			sval = 0xffffffff;
		}
		*read_data = sval & 0xffffffff;
	}

	return 0;
}

static uint64_t mfsi_opb_read(struct mfsi *mfsi, uint32_t opb_addr, uint32_t *data)
{
	uint64_t opb_cmd = OPB_CMD_READ | OPB_CMD_32BIT;
	int64_t rc;

	if (opb_addr > 0x00ffffff)
		return OPB_ERR_BAD_OPB_ADDR;

	opb_cmd |= opb_addr;
	opb_cmd <<= 32;

	mfsi_log(PR_INSANE, mfsi, "MFSI_OPB_READ: Writing 0x%16llx to XSCOM %x\n",
		 opb_cmd, mfsi->xscom_base);

	rc = xscom_write(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_CMD, opb_cmd);
	if (rc) {
		mfsi_log(PR_ERR, mfsi, "XSCOM error %lld writing OPB CMD\n", rc);
		return OPB_ERR_XSCOM_ERR;
	}
	return mfsi_opb_poll(mfsi, data);
}

static uint64_t mfsi_opb_write(struct mfsi *mfsi, uint32_t opb_addr, uint32_t data)
{
	uint64_t opb_cmd = OPB_CMD_WRITE | OPB_CMD_32BIT;
	int64_t rc;

	if (opb_addr > 0x00ffffff)
		return OPB_ERR_BAD_OPB_ADDR;

	opb_cmd |= opb_addr;
	opb_cmd <<= 32;
	opb_cmd |= data;

	mfsi_log(PR_INSANE, mfsi, "MFSI_OPB_WRITE: Writing 0x%16llx to XSCOM %x\n",
		 opb_cmd, mfsi->xscom_base);

	rc = xscom_write(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_CMD, opb_cmd);
	if (rc) {
		mfsi_log(PR_ERR, mfsi, "XSCOM error %lld writing OPB CMD\n", rc);
		return OPB_ERR_XSCOM_ERR;
	}
	return mfsi_opb_poll(mfsi, NULL);
}

static struct mfsi *mfsi_get(uint32_t chip_id, uint32_t unit)
{
	struct proc_chip *chip = get_chip(chip_id);
	struct mfsi *mfsi;

	if (!chip || unit > MFSI_hMFSI0)
		return NULL;
	mfsi = &chip->fsi_masters[unit];
	if (mfsi->xscom_base == 0)
		return NULL;
	return mfsi;
}

static int64_t mfsi_reset_pib2opb(struct mfsi *mfsi)
{
	uint64_t stat;
	int64_t rc;

	rc = xscom_write(mfsi->chip_id,
			 mfsi->xscom_base + PIB2OPB_REG_RESET, (1ul << 63));
	if (rc) {
		mfsi_log(PR_ERR, mfsi, "XSCOM error %lld resetting PIB2OPB\n", rc);
		return rc;
	}
	rc = xscom_write(mfsi->chip_id,
			 mfsi->xscom_base + PIB2OPB_REG_STAT, (1ul << 63));
	if (rc) {
		mfsi_log(PR_ERR, mfsi, "XSCOM error %lld resetting status\n", rc);
		return rc;
	}
	rc = xscom_read(mfsi->chip_id,
			mfsi->xscom_base + PIB2OPB_REG_STAT, &stat);
	if (rc) {
		mfsi_log(PR_ERR, mfsi, "XSCOM error %lld reading status\n", rc);
		return rc;
	}
	return 0;
}


static void mfsi_dump_pib2opb_state(struct mfsi *mfsi)
{
	uint64_t val;

	/* Dump a bunch of registers */
	if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_CMD, &val))
		goto xscom_error;
	mfsi_log(PR_ERR, mfsi, " PIB2OPB CMD   = %016llx\n", val);
	if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_STAT, &val))
		goto xscom_error;
	mfsi_log(PR_ERR, mfsi, " PIB2OPB STAT  = %016llx\n", val);
	if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_LSTAT, &val))
		goto xscom_error;
	mfsi_log(PR_ERR, mfsi, " PIB2OPB LSTAT = %016llx\n", val);

	if (mfsi->unit == MFSI_cMFSI0 || mfsi->unit == MFSI_cMFSI1) {
		if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_cRSIC, &val))
			goto xscom_error;
		mfsi_log(PR_ERR, mfsi, " PIB2OPB cRSIC = %016llx\n", val);
		if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_cRSIM, &val))
			goto xscom_error;
		mfsi_log(PR_ERR, mfsi, " PIB2OPB cRSIM = %016llx\n", val);
		if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_cRSIS, &val))
			goto xscom_error;
		mfsi_log(PR_ERR, mfsi, " PIB2OPB cRSIS = %016llx\n", val);
	} else if (mfsi->unit == MFSI_hMFSI0) {
		if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_hRSIC, &val))
			goto xscom_error;
		mfsi_log(PR_ERR, mfsi, " PIB2OPB hRSIC = %016llx\n", val);
		if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_hRSIM, &val))
			goto xscom_error;
		mfsi_log(PR_ERR, mfsi, " PIB2OPB hRSIM = %016llx\n", val);
		if (xscom_read(mfsi->chip_id, mfsi->xscom_base + PIB2OPB_REG_hRSIS, &val))
			goto xscom_error;
		mfsi_log(PR_ERR, mfsi, " PIB2OPB hRSIS = %016llx\n", val);
	}
	return;
 xscom_error:
	mfsi_log(PR_ERR, mfsi, "XSCOM error reading PIB2OPB registers\n");
}

static int64_t mfsi_dump_ctrl_regs(struct mfsi *mfsi)
{
	uint64_t opb_stat;
	uint32_t i;

	/* List of registers to dump (from HB) */
	static uint32_t dump_regs[] = {
		MFSI_REG_MATRB0,
		MFSI_REG_MDTRB0,
		MFSI_REG_MESRB0,
		MFSI_REG_MAESP0,
		MFSI_REG_MAEB,
		MFSI_REG_MSCSB0,
	};
	static const char * dump_regs_names[] = {
		"MFSI_REG_MATRB0",
		"MFSI_REG_MDTRB0",
		"MFSI_REG_MESRB0",
		"MFSI_REG_MAESP0",
		"MFSI_REG_MAEB  ",
		"MFSI_REG_MSCSB0",
        };
	for (i = 0; i < ARRAY_SIZE(dump_regs); i++) {
		uint32_t val;

		opb_stat = mfsi_opb_read(mfsi, mfsi->reg_base + dump_regs[i], &val);
		if (opb_stat) {
			/* Error on dump, give up */
			mfsi_log(PR_ERR, mfsi, " OPB stat 0x%016llx dumping reg %x\n",
				 opb_stat, dump_regs[i]);
			return OPAL_HARDWARE;
		}
		mfsi_log(PR_ERR, mfsi, " %s = %08x\n", dump_regs_names[i], val);
	}
	for (i = 0; i < 8; i++) {
		uint32_t val;

		opb_stat = mfsi_opb_read(mfsi, mfsi->reg_base + MFSI_REG_MSTAP(i), &val);
		if (opb_stat) {
			/* Error on dump, give up */
			mfsi_log(PR_ERR, mfsi, " OPB stat 0x%016llx dumping reg %x\n",
				 opb_stat, MFSI_REG_MSTAP(i));
			return OPAL_HARDWARE;
		}
		mfsi_log(PR_ERR, mfsi, " MFSI_REG_MSTAP%d = %08x\n", i, val);
	}
	return OPAL_SUCCESS;
}

static int64_t mfsi_master_cleanup(struct mfsi *mfsi, uint32_t port)
{
	uint64_t opb_stat;
	uint32_t port_base, compmask, truemask;

	/* Reset the bridge to clear up the residual errors */

	/* bit0 = Bridge: General reset */
	opb_stat = mfsi_opb_write(mfsi, mfsi->reg_base + MFSI_REG_MESRB0, 0x80000000u);
	if (opb_stat) {
		mfsi_log(PR_ERR, mfsi, " OPB stat 0x%016llx writing reset to MESRB0\n",
			 opb_stat);
		return OPAL_HARDWARE;
	}

	/* Calculate base address of port */
	port_base = mfsi->ports_base + port * MFSI_OPB_PORT_STRIDE;

	/* Perform error reset on Centaur fsi slave: */
	/*  write 0x4000000 to addr=834 */
  	opb_stat = mfsi_opb_write(mfsi, port_base + FSI_SLRES, 0x04000000);
	if (opb_stat) {
		mfsi_log(PR_ERR, mfsi,
			 " OPB stat 0x%016llx writing reset to FSI slave\n",
			 opb_stat);
		return OPAL_HARDWARE;
	}

	/* Further step is to issue a PIB reset to the FSI2PIB engine
	 * in busy state, i.e. write arbitrary data to 101c
         * (putcfam 1007) register of the previously failed FSI2PIB
         * engine on Centaur.
	 *
	 * XXX BenH: Should that be done by the upper FSI XSCOM layer ?
	 */
  	opb_stat = mfsi_opb_write(mfsi, port_base + FSI2PIB_STATUS, 0xFFFFFFFF);
	if (opb_stat) {
		mfsi_log(PR_ERR, mfsi,
			 " OPB stat 0x%016llx clearing FSI2PIB_STATUS\n",
			 opb_stat);
		return OPAL_HARDWARE;
	}

	/* Need to save/restore the true/comp masks or the FSP (PRD ?) will
	 * get annoyed
	 */
     	opb_stat = mfsi_opb_read(mfsi, port_base + FSI2PIB_COMPMASK, &compmask);
	if (opb_stat) {
		mfsi_log(PR_ERR, mfsi,
			 " OPB stat 0x%016llx reading FSI2PIB_COMPMASK\n",
			 opb_stat);
		return OPAL_HARDWARE;
	}
     	opb_stat = mfsi_opb_read(mfsi, port_base + FSI2PIB_TRUEMASK, &truemask);
	if (opb_stat) {
		mfsi_log(PR_ERR, mfsi,
			 " OPB stat 0x%016llx reading FSI2PIB_TRUEMASK\n",
			 opb_stat);
		return OPAL_HARDWARE;
	}

	/* Then, write arbitrary data to 1018  (putcfam 1006) to
         * reset any pending FSI2PIB errors.
	 */
  	opb_stat = mfsi_opb_write(mfsi, port_base + FSI2PIB_RESET, 0xFFFFFFFF);
	if (opb_stat) {
		mfsi_log(PR_ERR, mfsi,
			 " OPB stat 0x%016llx writing FSI2PIB_RESET\n",
			 opb_stat);
		return OPAL_HARDWARE;
	}

	/* Restore the true/comp masks */
  	opb_stat = mfsi_opb_write(mfsi, port_base + FSI2PIB_COMPMASK, compmask);
	if (opb_stat) {
		mfsi_log(PR_ERR, mfsi,
			 " OPB stat 0x%016llx writing FSI2PIB_COMPMASK\n",
			 opb_stat);
		return OPAL_HARDWARE;
	}
  	opb_stat = mfsi_opb_write(mfsi, port_base + FSI2PIB_TRUEMASK, truemask);
	if (opb_stat) {
		mfsi_log(PR_ERR, mfsi,
			 " OPB stat 0x%016llx writing FSI2PIB_TRUEMASK\n",
			 opb_stat);
		return OPAL_HARDWARE;
	}
	return OPAL_SUCCESS;
}

static int64_t mfsi_analyse_fsi_error(struct mfsi *mfsi)
{
	uint64_t opb_stat;
	uint32_t mesrb0;

	/* Most of the code below is adapted from HB. The main difference is
	 * that we don't gard
	 */

	/* Read MESRB0 */
	opb_stat = mfsi_opb_read(mfsi, mfsi->reg_base + MFSI_REG_MESRB0, &mesrb0);
	if (opb_stat) {
		mfsi_log(PR_ERR, mfsi, " OPB stat 0x%016llx reading MESRB0\n", opb_stat);
		return OPAL_HARDWARE;
	}
	mfsi_log(PR_ERR, mfsi, " MESRB0=%08x\n", mesrb0);

	/* bits 8:15 are internal parity errors in the master */
	if (mesrb0 & 0x00FF0000) {
		mfsi_log(PR_ERR, mfsi, " Master parity error !\n");
	} else {
		/* bits 0:3 are a specific error code */
		switch ((mesrb0 & 0xF0000000) >> 28 ) {
		case 0x1: /* OPB error	*/
		case 0x2: /* Invalid state of OPB state machine */
			/* error is inside the OPB logic */
			mfsi_log(PR_ERR, mfsi, " OPB logic error !\n");
			break;
		case 0x3: /* Port access error */
			/* probably some kind of code collision */
			/* could also be something weird in the chip */
			mfsi_log(PR_ERR, mfsi, " Port access error !\n");
			break;
		case 0x4: /* ID mismatch */
			mfsi_log(PR_ERR, mfsi, " Port ID mismatch !\n");
			break;
		case 0x6: /* port timeout error */
			mfsi_log(PR_ERR, mfsi, " Port timeout !\n");
			break;
		case 0x7: /* master timeout error */
			mfsi_log(PR_ERR, mfsi, " Master timeout !\n");
			break;
		case 0x9: /* Any error response from Slave */
			mfsi_log(PR_ERR, mfsi, " Slave error response !\n");
			break;
		case 0xC: /* bridge parity error */
			mfsi_log(PR_ERR, mfsi, " Bridge parity error !\n");
			break;
		case 0xB: /* protocol error */
			mfsi_log(PR_ERR, mfsi, " Protocol error !\n");
			break;
		case 0x8: /* master CRC error */
			mfsi_log(PR_ERR, mfsi, " Master CRC error !\n");
			break;
		case 0xA: /* Slave CRC error */
			mfsi_log(PR_ERR, mfsi, " Slave CRC error !\n");
			break;
		default:
			mfsi_log(PR_ERR, mfsi, " Unknown error !\n");
			break;
		}
	}
	return OPAL_SUCCESS;
}

static int64_t mfsi_handle_error(struct mfsi *mfsi, uint32_t port,
				 uint64_t opb_stat, uint32_t fsi_addr)
{
	int rc;
	bool found_root_cause = false;

	mfsi_log(PR_ERR, mfsi, "Access error on port %d, stat=%012llx\n",
		 port, opb_stat);

	/* First handle stat codes we synthetized */
	if (opb_stat & OPB_ERR_XSCOM_ERR)
		return OPAL_HARDWARE;
	if (opb_stat & OPB_ERR_BAD_OPB_ADDR)
		return OPAL_PARAMETER;

	/* Dump a bunch of regisers from PIB2OPB and reset it */
	mfsi_dump_pib2opb_state(mfsi);

	/* Reset PIB2OPB */
	mfsi_reset_pib2opb(mfsi);

	/* This one is not supposed to happen but ... */
	if (opb_stat & OPB_ERR_TIMEOUT_ERR)
		return OPAL_HARDWARE;

	/* Dump some FSI control registers */
	rc = mfsi_dump_ctrl_regs(mfsi);

	/* If that failed, reset PIB2OPB again and return */
	if (rc) {
		mfsi_dump_pib2opb_state(mfsi);
		mfsi_reset_pib2opb(mfsi);
		return OPAL_HARDWARE;
	}

	/* Now check for known root causes (from HB) */

	/* First check if it's a ctrl register access error and we got an OPB NACK,
	 * which means an out of bounds control reg
	 */
	if ((opb_stat & OPB_STAT_ERRACK) &&
	    ((fsi_addr & ~0x2ffu) == mfsi->reg_base)) {
		mfsi_log(PR_ERR, mfsi, " Error appears to be out of bounds reg %08x\n",
			 fsi_addr);
		found_root_cause = true;
	}
	/* Else check for other OPB errors */
	else if (opb_stat & OPB_STAT_ERR_OPB) {
		mfsi_log(PR_ERR, mfsi, " Error appears to be an OPB error\n");
		found_root_cause = true;
	}

	/* Root cause not found, dig into FSI logic */
	if (!found_root_cause) {
		rc = mfsi_analyse_fsi_error(mfsi);
		if (!rc) {
			/* If that failed too, reset the PIB2OPB again */
			mfsi_reset_pib2opb(mfsi);
		}
	}

	/* Cleanup MFSI master */
	mfsi_master_cleanup(mfsi, port);

	return OPAL_HARDWARE;
}

int64_t mfsi_read(uint32_t chip, uint32_t unit, uint32_t port,
		  uint32_t fsi_addr, uint32_t *data)
{
	struct mfsi *mfsi = mfsi_get(chip, unit);
	uint32_t port_addr;
	uint64_t opb_stat;
	int64_t rc = OPAL_SUCCESS;

	if (!mfsi || port > 7)
		return OPAL_PARAMETER;

	lock(&fsi_lock);

	/* Calculate port address */
	port_addr = mfsi->ports_base + port * MFSI_OPB_PORT_STRIDE;
	port_addr += fsi_addr;

	/* Perform OPB access */
	opb_stat = mfsi_opb_read(mfsi, port_addr, data);
	if (opb_stat)
		rc = mfsi_handle_error(mfsi, port, opb_stat, port_addr);

	unlock(&fsi_lock);

	return rc;
}

int64_t mfsi_write(uint32_t chip, uint32_t unit, uint32_t port,
		   uint32_t fsi_addr, uint32_t data)
{
	struct mfsi *mfsi = mfsi_get(chip, unit);
	uint32_t port_addr;
	uint64_t opb_stat;
	int64_t rc = OPAL_SUCCESS;

	if (!mfsi || port > 7)
		return OPAL_PARAMETER;

	lock(&fsi_lock);

	/* Calculate port address */
	port_addr = mfsi->ports_base + port * MFSI_OPB_PORT_STRIDE;
	port_addr += fsi_addr;

	/* Perform OPB access */
	opb_stat = mfsi_opb_write(mfsi, port_addr, data);
	if (opb_stat)
		rc = mfsi_handle_error(mfsi, port, opb_stat, port_addr);

	unlock(&fsi_lock);

	return rc;
}

static void mfsi_add(struct proc_chip *chip, struct mfsi *mfsi, uint32_t unit)
{
	mfsi->chip_id = chip->id;
	mfsi->unit = unit;

	/* We hard code everything for now */
	switch(unit) {
	case MFSI_cMFSI0:
		mfsi->xscom_base = PIB2OPB_MFSI0_ADDR;
		mfsi->ports_base = cMFSI_OPB_PORTS_BASE;
		mfsi->reg_base = cMFSI_OPB_REG_BASE;
		mfsi->err_bits = OPB_STAT_ERR_BASE | OPB_STAT_ERR_CMFSI;
		break;
	case MFSI_cMFSI1:
		mfsi->xscom_base = PIB2OPB_MFSI1_ADDR;
		mfsi->ports_base = cMFSI_OPB_PORTS_BASE;
		mfsi->reg_base = cMFSI_OPB_REG_BASE;
		mfsi->err_bits = OPB_STAT_ERR_BASE | OPB_STAT_ERR_CMFSI;
		break;
	case MFSI_hMFSI0:
		mfsi->xscom_base = PIB2OPB_MFSI0_ADDR;
		mfsi->ports_base = hMFSI_OPB_PORTS_BASE;
		mfsi->reg_base = hMFSI_OPB_REG_BASE;
		mfsi->err_bits = OPB_STAT_ERR_BASE | OPB_STAT_ERR_HMFSI;
		break;
	default:
		/* ??? */
		return;
	}

	/* Hardware Bug HW222712 on Murano DD1.0 causes the
	 * any_error bit to be un-clearable so we just
	 * have to ignore it. Additionally, HostBoot applies
	 * this to Venice too, though the comment there claims
	 * this is a Simics workaround.
	 *
	 * The doc says that bit can be safely ignored, so let's
	 * just not bother and always take it out.
	 */

	/* 16: cMFSI any-master-error */
	/* 24: hMFSI any-master-error */
	mfsi->err_bits &= 0xFFFF7F7F;

	mfsi_log(PR_INFO, mfsi, "Initialized\n");
}

void mfsi_init(void)
{
	struct proc_chip *chip;

	for_each_chip(chip) {
		chip->fsi_masters = zalloc(sizeof(struct mfsi) * 3);
		mfsi_add(chip, &chip->fsi_masters[MFSI_cMFSI0], MFSI_cMFSI0);
		mfsi_add(chip, &chip->fsi_masters[MFSI_hMFSI0], MFSI_hMFSI0);
		mfsi_add(chip, &chip->fsi_masters[MFSI_cMFSI1], MFSI_cMFSI1);

	}
}

