/*
 * Copyright 2011 Freescale Semiconductor, Inc.
 *
 * 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; either version 2 of the License, or (at your option)
 * any later version.
 *
 * 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <config.h>
#include <asm/fsl_law.h>
#include <asm/fsl_serdes.h>
#include <asm/fsl_srio.h>
#include <asm/errno.h>

#ifdef CONFIG_SRIO_PCIE_BOOT_MASTER
#define SRIO_PORT_ACCEPT_ALL 0x10000001
#define SRIO_IB_ATMU_AR 0x80f55000
#define SRIO_OB_ATMU_AR_MAINT 0x80077000
#define SRIO_OB_ATMU_AR_RW 0x80045000
#define SRIO_LCSBA1CSR_OFFSET 0x5c
#define SRIO_MAINT_WIN_SIZE 0x1000000 /* 16M */
#define SRIO_RW_WIN_SIZE 0x100000 /* 1M */
#define SRIO_LCSBA1CSR 0x60000000
#endif

#if defined(CONFIG_FSL_CORENET)
#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
	#define _DEVDISR_SRIO1 FSL_CORENET_DEVDISR3_SRIO1
	#define _DEVDISR_SRIO2 FSL_CORENET_DEVDISR3_SRIO2
#else
	#define _DEVDISR_SRIO1 FSL_CORENET_DEVDISR_SRIO1
	#define _DEVDISR_SRIO2 FSL_CORENET_DEVDISR_SRIO2
#endif
	#define _DEVDISR_RMU   FSL_CORENET_DEVDISR_RMU
	#define CONFIG_SYS_MPC8xxx_GUTS_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR
#elif defined(CONFIG_MPC85xx)
	#define _DEVDISR_SRIO1 MPC85xx_DEVDISR_SRIO
	#define _DEVDISR_SRIO2 MPC85xx_DEVDISR_SRIO
	#define _DEVDISR_RMU   MPC85xx_DEVDISR_RMSG
	#define CONFIG_SYS_MPC8xxx_GUTS_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR
#elif defined(CONFIG_MPC86xx)
	#define _DEVDISR_SRIO1 MPC86xx_DEVDISR_SRIO
	#define _DEVDISR_SRIO2 MPC86xx_DEVDISR_SRIO
	#define _DEVDISR_RMU   MPC86xx_DEVDISR_RMSG
	#define CONFIG_SYS_MPC8xxx_GUTS_ADDR \
		(&((immap_t *)CONFIG_SYS_IMMR)->im_gur)
#else
#error "No defines for DEVDISR_SRIO"
#endif

#ifdef CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
/*
 * Erratum A-004034
 * Affects: SRIO
 * Description: During port initialization, the SRIO port performs
 * lane synchronization (detecting valid symbols on a lane) and
 * lane alignment (coordinating multiple lanes to receive valid data
 * across lanes). Internal errors in lane synchronization and lane
 * alignment may cause failure to achieve link initialization at
 * the configured port width.
 * An SRIO port configured as a 4x port may see one of these scenarios:
 * 1. One or more lanes fails to achieve lane synchronization. Depending
 * on which lanes fail, this may result in downtraining from 4x to 1x
 * on lane 0, 4x to 1x on lane R (redundant lane).
 * 2. The link may fail to achieve lane alignment as a 4x, even though
 * all 4 lanes achieve lane synchronization, and downtrain to a 1x.
 * An SRIO port configured as a 1x port may fail to complete port
 * initialization (PnESCSR[PU] never deasserts) because of scenario 1.
 * Impact: SRIO port may downtrain to 1x, or may fail to complete
 * link initialization. Once a port completes link initialization
 * successfully, it will operate normally.
 */
static int srio_erratum_a004034(u8 port)
{
	serdes_corenet_t *srds_regs;
	u32 conf_lane;
	u32 init_lane;
	int idx, first, last;
	u32 i;
	unsigned long long end_tick;
	struct ccsr_rio *srio_regs = (void *)CONFIG_SYS_FSL_SRIO_ADDR;

	srds_regs = (void *)(CONFIG_SYS_FSL_CORENET_SERDES_ADDR);
	conf_lane = (in_be32((void *)&srds_regs->srdspccr0)
			>> (12 - port * 4)) & 0x3;
	init_lane = (in_be32((void *)&srio_regs->lp_serial
			.port[port].pccsr) >> 27) & 0x7;

	/*
	 * Start a counter set to ~2 ms after the SERDES reset is
	 * complete (SERDES SRDSBnRSTCTL[RST_DONE]=1 for n
	 * corresponding to the SERDES bank/PLL for the SRIO port).
	 */
	 if (in_be32((void *)&srds_regs->bank[0].rstctl)
		& SRDS_RSTCTL_RSTDONE) {
		/*
		 * Poll the port uninitialized status (SRIO PnESCSR[PO]) until
		 * PO=1 or the counter expires. If the counter expires, the
		 * port has failed initialization: go to recover steps. If PO=1
		 * and the desired port width is 1x, go to normal steps. If
		 * PO = 1 and the desired port width is 4x, go to recover steps.
		 */
		end_tick = usec2ticks(2000) + get_ticks();
		do {
			if (in_be32((void *)&srio_regs->lp_serial
				.port[port].pescsr) & 0x2) {
				if (conf_lane == 0x1)
					goto host_ok;
				else {
					if (init_lane == 0x2)
						goto host_ok;
					else
						break;
				}
			}
		} while (end_tick > get_ticks());

		/* recover at most 3 times */
		for (i = 0; i < 3; i++) {
			/* Set SRIO PnCCSR[PD]=1 */
			setbits_be32((void *)&srio_regs->lp_serial
					.port[port].pccsr,
					0x800000);
			/*
			* Set SRIO PnPCR[OBDEN] on the host to
			* enable the discarding of any pending packets.
			*/
			setbits_be32((void *)&srio_regs->impl.port[port].pcr,
				0x04);
			/* Wait 50 us */
			udelay(50);
			/* Run sync command */
			isync();

			if (port)
				first = serdes_get_first_lane(SRIO2);
			else
				first = serdes_get_first_lane(SRIO1);
			if (unlikely(first < 0))
				return -ENODEV;
			if (conf_lane == 0x1)
				last = first;
			else
				last = first + 3;
			/*
			 * Set SERDES BnGCRm0[RRST]=0 for each SRIO
			 * bank n and lane m.
			 */
			for (idx = first; idx <= last; idx++)
				clrbits_be32(&srds_regs->lane[idx].gcr0,
				SRDS_GCR0_RRST);
			/*
			 * Read SERDES BnGCRm0 for each SRIO
			 * bank n and lane m
			 */
			for (idx = first; idx <= last; idx++)
				in_be32(&srds_regs->lane[idx].gcr0);
			/* Run sync command */
			isync();
			/* Wait >= 100 ns */
			udelay(1);
			/*
			 * Set SERDES BnGCRm0[RRST]=1 for each SRIO
			 * bank n and lane m.
			 */
			for (idx = first; idx <= last; idx++)
				setbits_be32(&srds_regs->lane[idx].gcr0,
				SRDS_GCR0_RRST);
			/*
			 * Read SERDES BnGCRm0 for each SRIO
			 * bank n and lane m
			 */
			for (idx = first; idx <= last; idx++)
				in_be32(&srds_regs->lane[idx].gcr0);
			/* Run sync command */
			isync();
			/* Wait >= 300 ns */
			udelay(1);

			/* Write 1 to clear all bits in SRIO PnSLCSR */
			out_be32((void *)&srio_regs->impl.port[port].slcsr,
				0xffffffff);
			/* Clear SRIO PnPCR[OBDEN] on the host */
			clrbits_be32((void *)&srio_regs->impl.port[port].pcr,
				0x04);
			/* Set SRIO PnCCSR[PD]=0 */
			clrbits_be32((void *)&srio_regs->lp_serial
				.port[port].pccsr,
				0x800000);
			/* Wait >= 24 ms */
			udelay(24000);
			/* Poll the state of the port again */
			init_lane =
				(in_be32((void *)&srio_regs->lp_serial
					.port[port].pccsr) >> 27) & 0x7;
			if (in_be32((void *)&srio_regs->lp_serial
				.port[port].pescsr) & 0x2) {
				if (conf_lane == 0x1)
					goto host_ok;
				else {
					if (init_lane == 0x2)
						goto host_ok;
				}
			}
			if (i == 2)
				return -ENODEV;
		}
	} else
		return -ENODEV;

host_ok:
	/* Poll PnESCSR[OES] on the host until it is clear */
	end_tick = usec2ticks(1000000) + get_ticks();
	do {
		if (!(in_be32((void *)&srio_regs->lp_serial.port[port].pescsr)
			& 0x10000)) {
			out_be32(((void *)&srio_regs->lp_serial
				.port[port].pescsr), 0xffffffff);
			out_be32(((void *)&srio_regs->phys_err
				.port[port].edcsr), 0);
			out_be32(((void *)&srio_regs->logical_err.ltledcsr), 0);
			return 0;
		}
	} while (end_tick > get_ticks());

	return -ENODEV;
}
#endif

void srio_init(void)
{
	ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC8xxx_GUTS_ADDR;
	int srio1_used = 0, srio2_used = 0;
	u32 *devdisr;

#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
	devdisr = &gur->devdisr3;
#else
	devdisr = &gur->devdisr;
#endif
	if (is_serdes_configured(SRIO1)) {
		set_next_law(CONFIG_SYS_SRIO1_MEM_PHYS,
				law_size_bits(CONFIG_SYS_SRIO1_MEM_SIZE),
				LAW_TRGT_IF_RIO_1);
		srio1_used = 1;
#ifdef CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
		if (srio_erratum_a004034(0) < 0)
			printf("SRIO1: enabled but port error\n");
		else
#endif
		printf("SRIO1: enabled\n");
	} else {
		printf("SRIO1: disabled\n");
	}

#ifdef CONFIG_SRIO2
	if (is_serdes_configured(SRIO2)) {
		set_next_law(CONFIG_SYS_SRIO2_MEM_PHYS,
				law_size_bits(CONFIG_SYS_SRIO2_MEM_SIZE),
				LAW_TRGT_IF_RIO_2);
		srio2_used = 1;
#ifdef CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
		if (srio_erratum_a004034(1) < 0)
			printf("SRIO2: enabled but port error\n");
		else
#endif
		printf("SRIO2: enabled\n");

	} else {
		printf("SRIO2: disabled\n");
	}
#endif

#ifdef CONFIG_FSL_CORENET
	/* On FSL_CORENET devices we can disable individual ports */
	if (!srio1_used)
		setbits_be32(devdisr, _DEVDISR_SRIO1);
	if (!srio2_used)
		setbits_be32(devdisr, _DEVDISR_SRIO2);
#endif

	/* neither port is used - disable everything */
	if (!srio1_used && !srio2_used) {
		setbits_be32(devdisr, _DEVDISR_SRIO1);
		setbits_be32(devdisr, _DEVDISR_SRIO2);
		setbits_be32(devdisr, _DEVDISR_RMU);
	}
}

#ifdef CONFIG_SRIO_PCIE_BOOT_MASTER
void srio_boot_master(int port)
{
	struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR;

	/* set port accept-all */
	out_be32((void *)&srio->impl.port[port - 1].ptaacr,
				SRIO_PORT_ACCEPT_ALL);

	debug("SRIOBOOT - MASTER: Master port [ %d ] for srio boot.\n", port);
	/* configure inbound window for slave's u-boot image */
	debug("SRIOBOOT - MASTER: Inbound window for slave's image; "
			"Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n",
			(u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS,
			(u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1,
			CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE);
	out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwtar,
			CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12);
	out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwbar,
			CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 >> 12);
	out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwar,
			SRIO_IB_ATMU_AR
			| atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE));

	/* configure inbound window for slave's u-boot image */
	debug("SRIOBOOT - MASTER: Inbound window for slave's image; "
			"Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n",
			(u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS,
			(u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2,
			CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE);
	out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwtar,
			CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12);
	out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwbar,
			CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 >> 12);
	out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwar,
			SRIO_IB_ATMU_AR
			| atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE));

	/* configure inbound window for slave's ucode and ENV */
	debug("SRIOBOOT - MASTER: Inbound window for slave's ucode and ENV; "
			"Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n",
			(u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS,
			(u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS,
			CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE);
	out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwtar,
			CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS >> 12);
	out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwbar,
			CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS >> 12);
	out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwar,
			SRIO_IB_ATMU_AR
			| atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE));
}

void srio_boot_master_release_slave(int port)
{
	struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR;
	u32 escsr;
	debug("SRIOBOOT - MASTER: "
			"Check the port status and release slave core ...\n");

	escsr = in_be32((void *)&srio->lp_serial.port[port - 1].pescsr);
	if (escsr & 0x2) {
		if (escsr & 0x10100) {
			debug("SRIOBOOT - MASTER: Port [ %d ] is error.\n",
				port);
		} else {
			debug("SRIOBOOT - MASTER: "
				"Port [ %d ] is ready, now release slave's core ...\n",
				port);
			/*
			 * configure outbound window
			 * with maintenance attribute to set slave's LCSBA1CSR
			 */
			out_be32((void *)&srio->atmu.port[port - 1]
				.outbw[1].rowtar, 0);
			out_be32((void *)&srio->atmu.port[port - 1]
				.outbw[1].rowtear, 0);
			if (port - 1)
				out_be32((void *)&srio->atmu.port[port - 1]
					.outbw[1].rowbar,
					CONFIG_SYS_SRIO2_MEM_PHYS >> 12);
			else
				out_be32((void *)&srio->atmu.port[port - 1]
					.outbw[1].rowbar,
					CONFIG_SYS_SRIO1_MEM_PHYS >> 12);
			out_be32((void *)&srio->atmu.port[port - 1]
					.outbw[1].rowar,
					SRIO_OB_ATMU_AR_MAINT
					| atmu_size_mask(SRIO_MAINT_WIN_SIZE));

			/*
			 * configure outbound window
			 * with R/W attribute to set slave's BRR
			 */
			out_be32((void *)&srio->atmu.port[port - 1]
				.outbw[2].rowtar,
				SRIO_LCSBA1CSR >> 9);
			out_be32((void *)&srio->atmu.port[port - 1]
				.outbw[2].rowtear, 0);
			if (port - 1)
				out_be32((void *)&srio->atmu.port[port - 1]
					.outbw[2].rowbar,
					(CONFIG_SYS_SRIO2_MEM_PHYS
					+ SRIO_MAINT_WIN_SIZE) >> 12);
			else
				out_be32((void *)&srio->atmu.port[port - 1]
					.outbw[2].rowbar,
					(CONFIG_SYS_SRIO1_MEM_PHYS
					+ SRIO_MAINT_WIN_SIZE) >> 12);
			out_be32((void *)&srio->atmu.port[port - 1]
				.outbw[2].rowar,
				SRIO_OB_ATMU_AR_RW
				| atmu_size_mask(SRIO_RW_WIN_SIZE));

			/*
			 * Set the LCSBA1CSR register in slave
			 * by the maint-outbound window
			 */
			if (port - 1) {
				out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT
					+ SRIO_LCSBA1CSR_OFFSET,
					SRIO_LCSBA1CSR);
				while (in_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT
					+ SRIO_LCSBA1CSR_OFFSET)
					!= SRIO_LCSBA1CSR)
					;
				/*
				 * And then set the BRR register
				 * to release slave core
				 */
				out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT
					+ SRIO_MAINT_WIN_SIZE
					+ CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET,
					CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK);
			} else {
				out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT
					+ SRIO_LCSBA1CSR_OFFSET,
					SRIO_LCSBA1CSR);
				while (in_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT
					+ SRIO_LCSBA1CSR_OFFSET)
					!= SRIO_LCSBA1CSR)
					;
				/*
				 * And then set the BRR register
				 * to release slave core
				 */
				out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT
					+ SRIO_MAINT_WIN_SIZE
					+ CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET,
					CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK);
			}
			debug("SRIOBOOT - MASTER: "
					"Release slave successfully! Now the slave should start up!\n");
		}
	} else
		debug("SRIOBOOT - MASTER: Port [ %d ] is not ready.\n", port);
}
#endif
