/*
 * drivers/net/titan_mdio.c - Driver for Titan ethernet ports
 *
 * Copyright (C) 2003 PMC-Sierra Inc.
 * Author : Manish Lachwani (lachwani@pmc-sierra.com)
 *
 * 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.
 *
 * Management Data IO (MDIO) driver for the Titan GMII. Interacts with the Marvel PHY
 * on the Titan. No support for the TBI as yet.
 *
 */

#include	"titan_mdio.h"

#define MDIO_DEBUG

/*
 * Local constants
 */
#define MAX_CLKA            1023
#define MAX_PHY_DEV         31
#define MAX_PHY_REG         31
#define WRITEADDRS_OPCODE   0x0
#define	READ_OPCODE	    0x2
#define WRITE_OPCODE        0x1
#define MAX_MDIO_POLL       100

/*
 * Titan MDIO and SCMB registers
 */
#define TITAN_GE_SCMB_CONTROL                0x01c0  /* SCMB Control */
#define TITAN_GE_SCMB_CLKA	             0x01c4  /* SCMB Clock A */
#define TITAN_GE_MDIO_COMMAND                0x01d0  /* MDIO Command */
#define TITAN_GE_MDIO_DEVICE_PORT_ADDRESS    0x01d4  /* MDIO Device and Port addrs */
#define TITAN_GE_MDIO_DATA                   0x01d8  /* MDIO Data */
#define TITAN_GE_MDIO_INTERRUPTS             0x01dC  /* MDIO Interrupts */

/*
 * Function to poll the MDIO
 */
static int titan_ge_mdio_poll(void)
{
	int	i, val;

	for (i = 0; i < MAX_MDIO_POLL; i++) {
		val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);

		if (!(val & 0x8000))
			return TITAN_GE_MDIO_GOOD;
	}

	return TITAN_GE_MDIO_ERROR;
}


/*
 * Initialize and configure the MDIO
 */
int titan_ge_mdio_setup(titan_ge_mdio_config *titan_mdio)
{
	unsigned long	val;

	/* Reset the SCMB and program into MDIO mode*/
	TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x9000);
	TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x1000);

	/* CLK A */
	val = TITAN_GE_MDIO_READ(TITAN_GE_SCMB_CLKA);
	val = ( (val & ~(0x03ff)) | (titan_mdio->clka & 0x03ff));
	TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CLKA, val);

	/* Preamble Suppresion */
	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
	val = ( (val & ~(0x0001)) | (titan_mdio->mdio_spre & 0x0001));
	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);

	/* MDIO mode */
	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
	val = ( (val & ~(0x4000)) | (titan_mdio->mdio_mode & 0x4000));
	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);

	return TITAN_GE_MDIO_GOOD;
}

/*
 * Set the PHY address in indirect mode
 */
int titan_ge_mdio_inaddrs(int dev_addr, int reg_addr)
{
	volatile unsigned long	val;

	/* Setup the PHY device */
	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
	val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
	val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);

	/* Write the new address */
	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
	val = ( (val & ~(0x0300)) | ( (WRITEADDRS_OPCODE << 8) & 0x0300));
	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);

	return TITAN_GE_MDIO_GOOD;
}

/*
 * Read the MDIO register. This is what the individual parametes mean:
 *
 * dev_addr : PHY ID
 * reg_addr : register offset
 *
 * See the spec for the Titan MAC. We operate in the Direct Mode.
 */

#define MAX_RETRIES	2

int titan_ge_mdio_read(int dev_addr, int reg_addr, unsigned int *pdata)
{
	volatile unsigned long	val;
	int retries = 0;

	/* Setup the PHY device */

again:
	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
	val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
	val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
	val |= 0x4000;
	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);

	udelay(30);

	/* Issue the read command */
	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
	val = ( (val & ~(0x0300)) | ( (READ_OPCODE << 8) & 0x0300));
	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);

	udelay(30);

	if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
		return TITAN_GE_MDIO_ERROR;

	*pdata = (unsigned int)TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DATA);
	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS);

	udelay(30);

	if (val & 0x2) {
		if (retries == MAX_RETRIES)
			return TITAN_GE_MDIO_ERROR;
		else {
			retries++;
			goto again;
		}
	}

	return TITAN_GE_MDIO_GOOD;
}

/*
 * Write to the MDIO register
 *
 * dev_addr : PHY ID
 * reg_addr : register that needs to be written to
 *
 */
int titan_ge_mdio_write(int dev_addr, int reg_addr, unsigned int data)
{
	volatile unsigned long	val;

	if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
		return TITAN_GE_MDIO_ERROR;

	/* Setup the PHY device */
	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
	val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
	val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
	val |= 0x4000;
	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);

	udelay(30);

	/* Setup the data to write */
	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DATA, data);

	udelay(30);

	/* Issue the write command */
	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
	val = ( (val & ~(0x0300)) | ( (WRITE_OPCODE << 8) & 0x0300));
	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);

	udelay(30);

	if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
		return TITAN_GE_MDIO_ERROR;

	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS);
	if (val & 0x2)
		return TITAN_GE_MDIO_ERROR;

	return TITAN_GE_MDIO_GOOD;
}

