/* 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 <gx.h>
#include <xscom.h>

/*
 * Note: This file os only used on P7/P7+
 */

/* Configuration of the PSI BUID, see the explanation in
 * interrupts.h
 */
static int gx_p7_configure_psi_buid(uint32_t chip, uint32_t buid)
{
	uint64_t mode1;
	int rc;

	rc = xscom_read(chip, GX_P7_MODE1_REG, &mode1);
	if (rc) {
		prerror("GX: XSCOM error %d reading GX MODE1 REG\n", rc);
		return rc;
	}

	mode1 = SETFIELD(GX_P7_MODE1_PSI_BUID, mode1, buid);
	mode1 &= ~GX_P7_MODE1_PSI_BUID_DISABLE;

	printf("GX: MODE1_REG set to 0x%llx\n", mode1);
	rc = xscom_write(chip, GX_P7_MODE1_REG, mode1);
	if (rc) {
		prerror("GX: XSCOM error %d writing GX MODE1 REG\n", rc);
		return rc;
	}

	return 0;
}

static int gx_p7p_configure_psi_buid(uint32_t chip, uint32_t buid)
{
	uint64_t mode4;
	int rc;

	rc = xscom_read(chip, GX_P7P_MODE4_REG, &mode4);
	if (rc) {
		prerror("GX: XSCOM error %d reading GX MODE1 REG\n", rc);
		return rc;
	}

	mode4 = SETFIELD(GX_P7P_MODE4_PSI_BUID, mode4, buid);
	mode4 &= ~GX_P7P_MODE4_PSI_BUID_DISABLE;

	rc = xscom_write(chip, GX_P7P_MODE4_REG, mode4);
	if (rc) {
		prerror("GX: XSCOM error %d writing GX MODE1 REG\n", rc);
		return rc;
	}

	return 0;
}

/* Configure the BUID of the PSI interrupt in the GX
 * controller.
 *
 * @chip: Chip number (0..31)
 * @buid: 9-bit BUID value
 */
int gx_configure_psi_buid(uint32_t chip, uint32_t buid)
{
	uint32_t pvr = mfspr(SPR_PVR);

	printf("GX: PSI BUID for PVR %x (type %x) chip %d BUID 0x%x\n",
	       pvr, PVR_TYPE(pvr), chip, buid);

	switch (PVR_TYPE(pvr)) {
	case PVR_TYPE_P7:
		return gx_p7_configure_psi_buid(chip, buid);
	case PVR_TYPE_P7P:
		return gx_p7p_configure_psi_buid(chip, buid);
	}
	return -1;
}


static int gx_p7_configure_tce_bar(uint32_t chip, uint32_t gx, uint64_t addr,
				   uint64_t size)
{
	uint32_t areg, mreg;
	int rc;

	switch (gx) {
	case 0:
		areg = GX_P7_GX0_TCE_BAR;
		mreg = GX_P7_GX0_TCE_MASK;
		break;
	case 1:
		areg = GX_P7_GX1_TCE_BAR;
		mreg = GX_P7_GX1_TCE_MASK;
		break;
	default:
		return -EINVAL;
	}

	if (addr) {
		uint64_t taddr, tmask;

		/* The address field contains bits 18 to 43 of the address */
		taddr = SETFIELD(GX_P7_TCE_BAR_ADDR, 0ul,
				 (addr >> GX_P7_TCE_BAR_ADDR_SHIFT));
		taddr |= GX_P7_TCE_BAR_ENABLE;
		tmask = SETFIELD(GX_P7_TCE_MASK, 0ul,
				 ~((size - 1) >> GX_P7_TCE_BAR_ADDR_SHIFT));
		rc = xscom_write(chip, areg, 0);
		rc |= xscom_write(chip, mreg, tmask);
		rc |= xscom_write(chip, areg, taddr);
	} else {
		rc = xscom_write(chip, areg, 0);
	}
	return rc ? -EIO : 0;
}

/* Configure the TCE BAR of a given GX bus
 *
 * @chip: Chip number (0..31)
 * @gx  : GX bus index
 * @addr: base address of TCE table
 * @size: size of TCE table
 */
int gx_configure_tce_bar(uint32_t chip, uint32_t gx, uint64_t addr,
			 uint64_t size)
{
	uint32_t pvr = mfspr(SPR_PVR);

	printf("GX: TCE BAR for PVR %x (type %x) chip %d gx %d\n",
	       pvr, PVR_TYPE(pvr), chip, gx);

	/* We only support P7... is there a P7+ with P5IOC2 ? */
	switch (PVR_TYPE(pvr)) {
	case PVR_TYPE_P7:
		return gx_p7_configure_tce_bar(chip, gx, addr, size);
	}
	return -EINVAL;
}


