/*
 * (C) Copyright 2011
 * Akira Tosa, Allied Telesis R&D center K.K.
 */

/*
 * MII management I/F access
 */
#include <common.h>
#include "miim.h"

#define	CMIC_MIIM_ADDRESS	0x04A0 >> 2
#define	CMIC_MIIM_PARAM		0x0158 >> 2
#define	CMIC_MIIM_READ_DATA	0x015C >> 2
#define	CMIC_SCHAN_CTRL		0x0050 >> 2
#define MIIM_OP_DONE	0x00040000
#define	C22_WR	0x1 << 29
#define	C22_RD	0x2 << 29
#define	C45_AD	0x4 << 29
#define	C45_WR	0x5 << 29
#define	C45_RD	0x7 << 29
#define	MIIM_TIMEOUT	10

int bcm5331x_miiphy_read (char *devname, unsigned char addr,
				   unsigned char reg, unsigned short *value)
{
	volatile ulong * cmic_base_p	= (volatile ulong *)0xA8000000;
	int	i;

	cmic_base_p[CMIC_MIIM_ADDRESS]	= (ulong)reg;
	cmic_base_p[CMIC_MIIM_PARAM]	= C22_RD | (addr << 16);
	cmic_base_p[CMIC_SCHAN_CTRL]	= 0x12;	/* clear MIIM_OP_DONE */
	cmic_base_p[CMIC_SCHAN_CTRL]	= 0x90;	/* set MIIM_RD_START */
	for (i=0;i<MIIM_TIMEOUT;i++)	{
		udelay(1);
		if (cmic_base_p[CMIC_SCHAN_CTRL]&MIIM_OP_DONE)	{
			*value	= (ushort)cmic_base_p[CMIC_MIIM_READ_DATA];
			return	0;
		}
	}
	return	1;
}

int bcm5331x_miiphy_write (char *devname, unsigned char addr,
				   unsigned char reg, unsigned short value)
{
	volatile ulong * cmic_base_p	= (volatile ulong *)0xA8000000;
	int	i;

	cmic_base_p[CMIC_MIIM_ADDRESS]	= (ulong)reg;
	cmic_base_p[CMIC_MIIM_PARAM]	= C22_WR | (addr << 16) | value;
	cmic_base_p[CMIC_SCHAN_CTRL]	= 0x12;	/* clear MIIM_OP_DONE */
	cmic_base_p[CMIC_SCHAN_CTRL]	= 0x91;	/* set MIIM_WR_START */
	for (i=0;i<MIIM_TIMEOUT;i++)	{
		udelay(1);
		if (cmic_base_p[CMIC_SCHAN_CTRL]&MIIM_OP_DONE)	{
			return	0;
		}
	}
	return	1;
}
