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