/*
 * drivers/net/ibm_emac/ibm_emac_zmii.c
 *
 * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
 *
 * Copyright (c) 2004, 2005 Zultys Technologies.
 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
 *
 * Based on original work by
 *      Armin Kuster <akuster@mvista.com>
 * 	Copyright 2001 MontaVista Softare 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/kernel.h>
#include <linux/ethtool.h>
#include <asm/io.h>

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

/* ZMIIx_FER */
#define ZMII_FER_MDI(idx)	(0x80000000 >> ((idx) * 4))
#define ZMII_FER_MDI_ALL	(ZMII_FER_MDI(0) | ZMII_FER_MDI(1) | \
				 ZMII_FER_MDI(2) | ZMII_FER_MDI(3))

#define ZMII_FER_SMII(idx)	(0x40000000 >> ((idx) * 4))
#define ZMII_FER_RMII(idx)	(0x20000000 >> ((idx) * 4))
#define ZMII_FER_MII(idx)	(0x10000000 >> ((idx) * 4))

/* ZMIIx_SSR */
#define ZMII_SSR_SCI(idx)	(0x40000000 >> ((idx) * 4))
#define ZMII_SSR_FSS(idx)	(0x20000000 >> ((idx) * 4))
#define ZMII_SSR_SP(idx)	(0x10000000 >> ((idx) * 4))

/* ZMII only supports MII, RMII and SMII 
 * we also support autodetection for backward compatibility
 */
static inline int zmii_valid_mode(int mode)
{
	return  mode == PHY_MODE_MII ||
		mode == PHY_MODE_RMII ||
		mode == PHY_MODE_SMII ||
		mode == PHY_MODE_NA;
}

static inline const char *zmii_mode_name(int mode)
{
	switch (mode) {
	case PHY_MODE_MII:
		return "MII";
	case PHY_MODE_RMII:
		return "RMII";
	case PHY_MODE_SMII:
		return "SMII";
	default:
		BUG();
	}
}

static inline u32 zmii_mode_mask(int mode, int input)
{
	switch (mode) {
	case PHY_MODE_MII:
		return ZMII_FER_MII(input);
	case PHY_MODE_RMII:
		return ZMII_FER_RMII(input);
	case PHY_MODE_SMII:
		return ZMII_FER_SMII(input);
	default:
		return 0;
	}
}

static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode)
{
	struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
	struct zmii_regs __iomem *p;

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

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

		p = ioremap(ocpdev->def->paddr, sizeof(struct zmii_regs));
		if (!p) {
			printk(KERN_ERR
			       "zmii%d: could not ioremap device registers!\n",
			       ocpdev->def->index);
			kfree(dev);
			return -ENOMEM;
		}
		dev->base = p;
		ocp_set_drvdata(ocpdev, dev);
		
		/* We may need FER value for autodetection later */
		dev->fer_save = in_be32(&p->fer);

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

	if (!zmii_valid_mode(*mode)) {
		/* Probably an EMAC connected to RGMII, 
		 * but it still may need ZMII for MDIO 
		 */
		goto out;
	}

	/* Autodetect ZMII mode if not specified.
	 * This is only for backward compatibility with the old driver.
	 * Please, always specify PHY mode in your board port to avoid
	 * any surprises.
	 */
	if (dev->mode == PHY_MODE_NA) {
		if (*mode == PHY_MODE_NA) {
			u32 r = dev->fer_save;

			ZMII_DBG("%d: autodetecting mode, FER = 0x%08x" NL,
				 ocpdev->def->index, r);
			
			if (r & (ZMII_FER_MII(0) | ZMII_FER_MII(1)))
				dev->mode = PHY_MODE_MII;
			else if (r & (ZMII_FER_RMII(0) | ZMII_FER_RMII(1)))
				dev->mode = PHY_MODE_RMII;
			else
				dev->mode = PHY_MODE_SMII;
		} else
			dev->mode = *mode;

		printk(KERN_NOTICE "zmii%d: bridge in %s mode\n",
		       ocpdev->def->index, zmii_mode_name(dev->mode));
	} else {
		/* All inputs must use the same mode */
		if (*mode != PHY_MODE_NA && *mode != dev->mode) {
			printk(KERN_ERR
			       "zmii%d: invalid mode %d specified for input %d\n",
			       ocpdev->def->index, *mode, input);
			return -EINVAL;
		}
	}

	/* Report back correct PHY mode, 
	 * it may be used during PHY initialization.
	 */
	*mode = dev->mode;

	/* Enable this input */
	out_be32(&p->fer, in_be32(&p->fer) | zmii_mode_mask(dev->mode, input));
      out:
	++dev->users;
	return 0;
}

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

	if (emacdata->zmii_idx >= 0) {
		dev->zmii_input = emacdata->zmii_mux;
		dev->zmii_dev =
		    ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_ZMII,
				    emacdata->zmii_idx);
		if (!dev->zmii_dev) {
			printk(KERN_ERR "emac%d: unknown zmii%d!\n",
			       dev->def->index, emacdata->zmii_idx);
			return -ENODEV;
		}
		if (zmii_init
		    (dev->zmii_dev, dev->zmii_input, &emacdata->phy_mode)) {
			printk(KERN_ERR
			       "emac%d: zmii%d initialization failed!\n",
			       dev->def->index, emacdata->zmii_idx);
			return -ENODEV;
		}
	}
	return 0;
}

void __zmii_enable_mdio(struct ocp_device *ocpdev, int input)
{
	struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
	u32 fer = in_be32(&dev->base->fer) & ~ZMII_FER_MDI_ALL;

	ZMII_DBG2("%d: mdio(%d)" NL, ocpdev->def->index, input);

	out_be32(&dev->base->fer, fer | ZMII_FER_MDI(input));
}

void __zmii_set_speed(struct ocp_device *ocpdev, int input, int speed)
{
	struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
	u32 ssr = in_be32(&dev->base->ssr);

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

	if (speed == SPEED_100)
		ssr |= ZMII_SSR_SP(input);
	else
		ssr &= ~ZMII_SSR_SP(input);

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

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

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

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

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

int __zmii_get_regs_len(struct ocp_device *ocpdev)
{
	return sizeof(struct emac_ethtool_regs_subhdr) +
	    sizeof(struct zmii_regs);
}

void *zmii_dump_regs(struct ocp_device *ocpdev, void *buf)
{
	struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
	struct emac_ethtool_regs_subhdr *hdr = buf;
	struct zmii_regs *regs = (struct zmii_regs *)(hdr + 1);

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