/*
 * drivers/net/ibm_emac/ibm_emac_rgmii.c
 *
 * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
 *
 * Copyright (c) 2004, 2005 Zultys Technologies.
 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
 *
 * Based on original work by
 * 	Matt Porter <mporter@kernel.crashing.org>
 * 	Copyright 2004 MontaVista Software, 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.
 *
 */
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/ethtool.h>
#include <asm/io.h>

#include "ibm_emac_core.h"
#include "ibm_emac_debug.h"

/* RGMIIx_FER */
#define RGMII_FER_MASK(idx)	(0x7 << ((idx) * 4))
#define RGMII_FER_RTBI(idx)	(0x4 << ((idx) * 4))
#define RGMII_FER_RGMII(idx)	(0x5 << ((idx) * 4))
#define RGMII_FER_TBI(idx)	(0x6 << ((idx) * 4))
#define RGMII_FER_GMII(idx)	(0x7 << ((idx) * 4))

/* RGMIIx_SSR */
#define RGMII_SSR_MASK(idx)	(0x7 << ((idx) * 8))
#define RGMII_SSR_100(idx)	(0x2 << ((idx) * 8))
#define RGMII_SSR_1000(idx)	(0x4 << ((idx) * 8))

/* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */
static inline int rgmii_valid_mode(int phy_mode)
{
	return  phy_mode == PHY_MODE_GMII ||
		phy_mode == PHY_MODE_RGMII ||
		phy_mode == PHY_MODE_TBI ||
		phy_mode == PHY_MODE_RTBI;
}

static inline const char *rgmii_mode_name(int mode)
{
	switch (mode) {
	case PHY_MODE_RGMII:
		return "RGMII";
	case PHY_MODE_TBI:
		return "TBI";
	case PHY_MODE_GMII:
		return "GMII";
	case PHY_MODE_RTBI:
		return "RTBI";
	default:
		BUG();
	}
}

static inline u32 rgmii_mode_mask(int mode, int input)
{
	switch (mode) {
	case PHY_MODE_RGMII:
		return RGMII_FER_RGMII(input);
	case PHY_MODE_TBI:
		return RGMII_FER_TBI(input);
	case PHY_MODE_GMII:
		return RGMII_FER_GMII(input);
	case PHY_MODE_RTBI:
		return RGMII_FER_RTBI(input);
	default:
		BUG();
	}
}

static int __init rgmii_init(struct ocp_device *ocpdev, int input, int mode)
{
	struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
	struct rgmii_regs *p;

	RGMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, mode);

	if (!dev) {
		dev = kzalloc(sizeof(struct ibm_ocp_rgmii), GFP_KERNEL);
		if (!dev) {
			printk(KERN_ERR
			       "rgmii%d: couldn't allocate device structure!\n",
			       ocpdev->def->index);
			return -ENOMEM;
		}

		p = (struct rgmii_regs *)ioremap(ocpdev->def->paddr,
						 sizeof(struct rgmii_regs));
		if (!p) {
			printk(KERN_ERR
			       "rgmii%d: could not ioremap device registers!\n",
			       ocpdev->def->index);
			kfree(dev);
			return -ENOMEM;
		}

		dev->base = p;
		ocp_set_drvdata(ocpdev, dev);

		/* Disable all inputs by default */
		out_be32(&p->fer, 0);
	} else
		p = dev->base;

	/* Enable this input */
	out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input));

	printk(KERN_NOTICE "rgmii%d: input %d in %s mode\n",
	       ocpdev->def->index, input, rgmii_mode_name(mode));

	++dev->users;
	return 0;
}

int __init rgmii_attach(void *emac)
{
	struct ocp_enet_private *dev = emac;
	struct ocp_func_emac_data *emacdata = dev->def->additions;

	/* Check if we need to attach to a RGMII */
	if (emacdata->rgmii_idx >= 0 && rgmii_valid_mode(emacdata->phy_mode)) {
		dev->rgmii_input = emacdata->rgmii_mux;
		dev->rgmii_dev =
		    ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_RGMII,
				    emacdata->rgmii_idx);
		if (!dev->rgmii_dev) {
			printk(KERN_ERR "emac%d: unknown rgmii%d!\n",
			       dev->def->index, emacdata->rgmii_idx);
			return -ENODEV;
		}
		if (rgmii_init
		    (dev->rgmii_dev, dev->rgmii_input, emacdata->phy_mode)) {
			printk(KERN_ERR
			       "emac%d: rgmii%d initialization failed!\n",
			       dev->def->index, emacdata->rgmii_idx);
			return -ENODEV;
		}
	}
	return 0;
}

void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed)
{
	struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
	u32 ssr = in_be32(&dev->base->ssr) & ~RGMII_SSR_MASK(input);

	RGMII_DBG("%d: speed(%d, %d)" NL, ocpdev->def->index, input, speed);

	if (speed == SPEED_1000)
		ssr |= RGMII_SSR_1000(input);
	else if (speed == SPEED_100)
		ssr |= RGMII_SSR_100(input);

	out_be32(&dev->base->ssr, ssr);
}

void __exit __rgmii_fini(struct ocp_device *ocpdev, int input)
{
	struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
	BUG_ON(!dev || dev->users == 0);

	RGMII_DBG("%d: fini(%d)" NL, ocpdev->def->index, input);

	/* Disable this input */
	out_be32(&dev->base->fer,
		 in_be32(&dev->base->fer) & ~RGMII_FER_MASK(input));

	if (!--dev->users) {
		/* Free everything if this is the last user */
		ocp_set_drvdata(ocpdev, NULL);
		iounmap((void *)dev->base);
		kfree(dev);
	}
}

int __rgmii_get_regs_len(struct ocp_device *ocpdev)
{
	return sizeof(struct emac_ethtool_regs_subhdr) +
	    sizeof(struct rgmii_regs);
}

void *rgmii_dump_regs(struct ocp_device *ocpdev, void *buf)
{
	struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
	struct emac_ethtool_regs_subhdr *hdr = buf;
	struct rgmii_regs *regs = (struct rgmii_regs *)(hdr + 1);

	hdr->version = 0;
	hdr->index = ocpdev->def->index;
	memcpy_fromio(regs, dev->base, sizeof(struct rgmii_regs));
	return regs + 1;
}
