/*
 * VFIO platform driver specialized for AMD xgbe reset
 * reset code is inherited from AMD xgbe native driver
 *
 * Copyright (c) 2015 Linaro Ltd.
 *              www.linaro.org
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <uapi/linux/mdio.h>
#include <linux/delay.h>

#include "vfio_platform_private.h"

#define DMA_MR			0x3000
#define MAC_VR			0x0110
#define DMA_ISR			0x3008
#define MAC_ISR			0x00b0
#define PCS_MMD_SELECT		0xff
#define MDIO_AN_INT		0x8002
#define MDIO_AN_INTMASK		0x8001

static unsigned int xmdio_read(void *ioaddr, unsigned int mmd,
			       unsigned int reg)
{
	unsigned int mmd_address, value;

	mmd_address = (mmd << 16) | ((reg) & 0xffff);
	iowrite32(mmd_address >> 8, ioaddr + (PCS_MMD_SELECT << 2));
	value = ioread32(ioaddr + ((mmd_address & 0xff) << 2));
	return value;
}

static void xmdio_write(void *ioaddr, unsigned int mmd,
			unsigned int reg, unsigned int value)
{
	unsigned int mmd_address;

	mmd_address = (mmd << 16) | ((reg) & 0xffff);
	iowrite32(mmd_address >> 8, ioaddr + (PCS_MMD_SELECT << 2));
	iowrite32(value, ioaddr + ((mmd_address & 0xff) << 2));
}

int vfio_platform_amdxgbe_reset(struct vfio_platform_device *vdev)
{
	struct vfio_platform_region *xgmac_regs = &vdev->regions[0];
	struct vfio_platform_region *xpcs_regs = &vdev->regions[1];
	u32 dma_mr_value, pcs_value, value;
	unsigned int count;

	if (!xgmac_regs->ioaddr) {
		xgmac_regs->ioaddr =
			ioremap_nocache(xgmac_regs->addr, xgmac_regs->size);
		if (!xgmac_regs->ioaddr)
			return -ENOMEM;
	}
	if (!xpcs_regs->ioaddr) {
		xpcs_regs->ioaddr =
			ioremap_nocache(xpcs_regs->addr, xpcs_regs->size);
		if (!xpcs_regs->ioaddr)
			return -ENOMEM;
	}

	/* reset the PHY through MDIO*/
	pcs_value = xmdio_read(xpcs_regs->ioaddr, MDIO_MMD_PCS, MDIO_CTRL1);
	pcs_value |= MDIO_CTRL1_RESET;
	xmdio_write(xpcs_regs->ioaddr, MDIO_MMD_PCS, MDIO_CTRL1, pcs_value);

	count = 50;
	do {
		msleep(20);
		pcs_value = xmdio_read(xpcs_regs->ioaddr, MDIO_MMD_PCS,
					MDIO_CTRL1);
	} while ((pcs_value & MDIO_CTRL1_RESET) && --count);

	if (pcs_value & MDIO_CTRL1_RESET)
		pr_warn("%s XGBE PHY reset timeout\n", __func__);

	/* disable auto-negotiation */
	value = xmdio_read(xpcs_regs->ioaddr, MDIO_MMD_AN, MDIO_CTRL1);
	value &= ~MDIO_AN_CTRL1_ENABLE;
	xmdio_write(xpcs_regs->ioaddr, MDIO_MMD_AN, MDIO_CTRL1, value);

	/* disable AN IRQ */
	xmdio_write(xpcs_regs->ioaddr, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);

	/* clear AN IRQ */
	xmdio_write(xpcs_regs->ioaddr, MDIO_MMD_AN, MDIO_AN_INT, 0);

	/* MAC software reset */
	dma_mr_value = ioread32(xgmac_regs->ioaddr + DMA_MR);
	dma_mr_value |= 0x1;
	iowrite32(dma_mr_value, xgmac_regs->ioaddr + DMA_MR);

	usleep_range(10, 15);

	count = 2000;
	while (--count && (ioread32(xgmac_regs->ioaddr + DMA_MR) & 1))
		usleep_range(500, 600);

	if (!count)
		pr_warn("%s MAC SW reset failed\n", __func__);

	return 0;
}

module_vfio_reset_handler("amd,xgbe-seattle-v1a", vfio_platform_amdxgbe_reset);

MODULE_VERSION("0.1");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Eric Auger <eric.auger@linaro.org>");
MODULE_DESCRIPTION("Reset support for AMD xgbe vfio platform device");
