/*
 * (C) Copyright 2008
 * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de.
 *
 * Based in part on cpu/mpc8xx/scc.c.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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>	/* commproc.h is included here */
#include <malloc.h>
#include <net.h>

#ifdef CONFIG_KEYMILE_HDLC_ENET

#include "../common/keymile_hdlc_enet.h"

char keymile_slot;	/* our slot number in the backplane */

/*
 * Since, except during initialization, ethact is always HDLC ETHERNET
 * while we're in the driver, just use serial_printf() everywhere for
 * output.  This avoids possible conflicts when netconsole is being
 * used.
 */
#define dprintf(fmt, args...)	serial_printf(fmt, ##args)

static int already_inited;

/*
  * SCC Ethernet Tx and Rx buffer descriptors allocated at the
  *  immr->udata_bd address on Dual-Port RAM
  * Provide for Double Buffering
  */
typedef volatile struct CommonBufferDescriptor {
    cbd_t txbd;			/* Tx BD */
    cbd_t rxbd[HDLC_PKTBUFSRX];	/* Rx BD */
} RTXBD;

static RTXBD *rtx;

int keymile_hdlc_enet_init(struct eth_device *, bd_t *);
void keymile_hdlc_enet_halt(struct eth_device *);
extern void keymile_hdlc_enet_init_bds(RTXBD *);
extern void initCachedNumbers(int);

/* Use SCC4 */
#define MGS_CPM_CR_HDLC	CPM_CR_CH_SCC4
#define MGS_PROFF_HDLC	PROFF_SCC4
#define MGS_SCC_HDLC	3	/* Index, not number! */

int keymile_hdlc_enet_init(struct eth_device *dev, bd_t *bis)
{
	/* int i; */
	/* volatile cbd_t *bdp; */
	volatile cpm8xx_t *cp;
	volatile scc_t *sccp;
	volatile hdlc_pram_t *hpr;
	volatile iop8xx_t *iop;

	if (already_inited)
		return 0;

	cp = (cpm8xx_t *)&(((volatile immap_t *)CONFIG_SYS_IMMR)->im_cpm);
	hpr = (hdlc_pram_t *)(&cp->cp_dparam[MGS_PROFF_HDLC]);
	sccp = (volatile scc_t *)(&cp->cp_scc[MGS_SCC_HDLC]);
	iop = (iop8xx_t *)&(((volatile immap_t *)CONFIG_SYS_IMMR)->im_ioport);

	/*
	 * Disable receive and transmit just in case.
	 */
	sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);

#ifndef CONFIG_SYS_ALLOC_DPRAM
#error "CONFIG_SYS_ALLOC_DPRAM must be defined"
#else
	/*
	 * Avoid exhausting DPRAM, which would cause a panic.
	 * Actually this isn't really necessary, but leave it here
	 * for safety's sake.
	 */
	if (rtx == NULL) {
		rtx = (RTXBD *) (cp->cp_dpmem +
			 dpram_alloc_align(sizeof(RTXBD), 8));
		if (rtx == (RTXBD *)CPM_DP_NOSPACE)
			return -1;
		memset((void *)rtx, 0, sizeof(RTXBD));
	}
#endif /* !CONFIG_SYS_ALLOC_DPRAM */

	/* We need the slot number for addressing. */
	keymile_slot = *(char *)(CONFIG_SYS_SLOT_ID_BASE +
		CONFIG_SYS_SLOT_ID_OFF) & CONFIG_SYS_SLOT_ID_MASK;
	/*
	 * Be consistent with the Linux driver and set
	 * only enetaddr[0].
	 *
	 * Always add 1 to the slot number so that
	 * there are no problems with an ethaddr which
	 * is all 0s.  This should be acceptable because
	 * a board should never have a slot number of 255,
	 * which is the broadcast address.  The HDLC addressing
	 * uses only the slot number.
	 */
	dev->enetaddr[0] = keymile_slot + 1;

#ifdef TEST_IT
	dprintf("slot %d\n", keymile_slot);
#endif

	/* use pa8, pa9 pins for TXD4, RXD4 respectively */
	iop->iop_papar |= ((0x8000 >> 8) | (0x8000 >> 9));
	iop->iop_padir &= ~((0x8000 >> 8) | (0x8000 >> 9));
	iop->iop_paodr &= ~((0x8000 >> 8) | (0x8000 >> 9));

	/* also use pa0 as CLK8 */
	iop->iop_papar |= 0x8000;
	iop->iop_padir &= ~0x8000;
	iop->iop_paodr &= ~0x8000;

	/* use pc5 as CTS4 */
	iop->iop_pcpar &= ~(0x8000 >> 5);
	iop->iop_pcdir &= ~(0x8000 >> 5);
	iop->iop_pcso  |= (0x8000 >> 5);

	/*
	 * SI clock routing
	 * use CLK8
	 * this also connects SCC4 to NMSI
	 */
	cp->cp_sicr = (cp->cp_sicr & ~0xff000000) | 0x3f000000;

	/* keymile_rxIdx = 0; */

	/*
	 * Initialize function code registers for big-endian.
	 */
	hpr->rfcr = SCC_EB;
	hpr->tfcr = SCC_EB;

	/*
	 * Set maximum bytes per receive buffer.
	 */
	hpr->mrblr = MAX_FRAME_LENGTH;

	/* Setup CRC generator values for HDLC */
	hpr->c_mask = 0x0000F0B8;
	hpr->c_pres = 0x0000FFFF;

	/* Initialize all error counters to 0 */
	hpr->disfc = 0;
	hpr->crcec = 0;
	hpr->abtsc = 0;
	hpr->nmarc = 0;
	hpr->retrc = 0;

	/* Set maximum frame length size */
	hpr->mflr = MAX_FRAME_LENGTH;

	/* set to 1 for per frame processing change later if needed */
	hpr->rfthr = 1;

	hpr->hmask = 0xff;

	hpr->haddr2 = SET_HDLC_UUA(keymile_slot);
	hpr->haddr3 = hpr->haddr2;
	hpr->haddr4 = hpr->haddr2;
	/* broadcast */
	hpr->haddr1 = HDLC_BCAST;

	hpr->rbase = (unsigned int) &rtx->rxbd[0];
	hpr->tbase = (unsigned int) &rtx->txbd;

#if 0
	/*
	 * Initialize the buffer descriptors.
	 */
	bdp = &rtx->txbd;
	bdp->cbd_sc = 0;
	bdp->cbd_bufaddr = 0;
	bdp->cbd_sc = BD_SC_WRAP;

	/*
	 *	Setup RX packet buffers, aligned correctly.
	 *	Borrowed from net/net.c.
	 */
	MyRxPackets[0] = &MyPktBuf[0] + (PKTALIGN - 1);
	MyRxPackets[0] -= (ulong)MyRxPackets[0] % PKTALIGN;
	for (i = 1; i < HDLC_PKTBUFSRX; i++)
		MyRxPackets[i] = MyRxPackets[0] + i * PKT_MAXBLR_SIZE;

	bdp = &rtx->rxbd[0];
	for (i = 0; i < HDLC_PKTBUFSRX; i++) {
		bdp->cbd_sc = BD_SC_EMPTY;
		/* Leave space at the start for INET header. */
		bdp->cbd_bufaddr = (unsigned int)(MyRxPackets[i] +
			INET_HDR_ALIGN);
		bdp++;
	}
	bdp--;
	bdp->cbd_sc |= BD_SC_WRAP;
#else
	keymile_hdlc_enet_init_bds(rtx);
#endif

	/* Let's re-initialize the channel now.	 We have to do it later
	 * than the manual describes because we have just now finished
	 * the BD initialization.
	 */
	cp->cp_cpcr = mk_cr_cmd(MGS_CPM_CR_HDLC, CPM_CR_INIT_TRX) | CPM_CR_FLG;
	while (cp->cp_cpcr & CPM_CR_FLG);

	sccp->scc_gsmrl = SCC_GSMRL_MODE_HDLC;
	/* CTSS=1 */
	sccp->scc_gsmrh = SCC_GSMRH_CTSS;
	/* NOF=0, RTE=1, DRT=0, BUS=1 */
	sccp->scc_psmr = ((0x8000 >> 6) | (0x8000 >> 10));

/* loopback for local testing */
#ifdef GJTEST
	dprintf("LOOPBACK!\n");
	sccp->scc_gsmrl |= SCC_GSMRL_DIAG_LOOP;
#endif

	/*
	 * Disable all interrupts and clear all pending
	 * events.
	 */
	sccp->scc_sccm = 0;
	sccp->scc_scce = 0xffff;

	/*
	 * And last, enable the transmit and receive processing.
	 */
	sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	dprintf("%s: HDLC ENET Version 0.3 on SCC%d\n", dev->name,
		MGS_SCC_HDLC + 1);

	/*
	 * We may not get an ARP packet because ARP was already done on
	 * a different interface, so initialize the cached values now.
	 */
	initCachedNumbers(1);

	already_inited = 1;

	return 0;
}

void keymile_hdlc_enet_halt(struct eth_device *dev)
{
#if 0 /* just return, but keep this for reference */
	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;

	/* maybe should do a graceful stop here? */
	immr->im_cpm.cp_scc[MGS_SCC_HDLC].scc_gsmrl &=
		~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
#endif
}

#endif /* CONFIG_KEYMILE_HDLC_ENET */
