// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
 * Core driver for the Ocelot chip family.
 *
 * The VSC7511, 7512, 7513, and 7514 can be controlled internally via an
 * on-chip MIPS processor, or externally via SPI, I2C, PCIe. This core driver is
 * intended to be the bus-agnostic glue between, for example, the SPI bus and
 * the child devices.
 *
 * Copyright 2021-2022 Innovative Advantage Inc.
 *
 * Author: Colin Foster <colin.foster@in-advantage.com>
 */

#include <linux/bits.h>
#include <linux/device.h>
#include <linux/export.h>
#include <linux/iopoll.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mfd/ocelot.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/types.h>

#include <soc/mscc/ocelot.h>

#include "ocelot.h"

#define REG_GCB_SOFT_RST		0x0008

#define BIT_SOFT_CHIP_RST		BIT(0)

#define VSC7512_MIIM0_RES_START		0x7107009c
#define VSC7512_MIIM1_RES_START		0x710700c0
#define VSC7512_MIIM_RES_SIZE		0x00000024

#define VSC7512_PHY_RES_START		0x710700f0
#define VSC7512_PHY_RES_SIZE		0x00000004

#define VSC7512_GPIO_RES_START		0x71070034
#define VSC7512_GPIO_RES_SIZE		0x0000006c

#define VSC7512_SIO_CTRL_RES_START	0x710700f8
#define VSC7512_SIO_CTRL_RES_SIZE	0x00000100

#define VSC7512_HSIO_RES_START		0x710d0000
#define VSC7512_HSIO_RES_SIZE		0x00000128

#define VSC7512_ANA_RES_START		0x71880000
#define VSC7512_ANA_RES_SIZE		0x00010000

#define VSC7512_QS_RES_START		0x71080000
#define VSC7512_QS_RES_SIZE		0x00000100

#define VSC7512_QSYS_RES_START		0x71800000
#define VSC7512_QSYS_RES_SIZE		0x00200000

#define VSC7512_REW_RES_START		0x71030000
#define VSC7512_REW_RES_SIZE		0x00010000

#define VSC7512_SYS_RES_START		0x71010000
#define VSC7512_SYS_RES_SIZE		0x00010000

#define VSC7512_S0_RES_START		0x71040000
#define VSC7512_S1_RES_START		0x71050000
#define VSC7512_S2_RES_START		0x71060000
#define VCAP_RES_SIZE			0x00000400

#define VSC7512_PORT_0_RES_START	0x711e0000
#define VSC7512_PORT_1_RES_START	0x711f0000
#define VSC7512_PORT_2_RES_START	0x71200000
#define VSC7512_PORT_3_RES_START	0x71210000
#define VSC7512_PORT_4_RES_START	0x71220000
#define VSC7512_PORT_5_RES_START	0x71230000
#define VSC7512_PORT_6_RES_START	0x71240000
#define VSC7512_PORT_7_RES_START	0x71250000
#define VSC7512_PORT_8_RES_START	0x71260000
#define VSC7512_PORT_9_RES_START	0x71270000
#define VSC7512_PORT_10_RES_START	0x71280000
#define VSC7512_PORT_RES_SIZE		0x00010000

#define VSC7512_GCB_RST_SLEEP_US	100
#define VSC7512_GCB_RST_TIMEOUT_US	100000

static int ocelot_gcb_chip_rst_status(struct ocelot_ddata *ddata)
{
	int val, err;

	err = regmap_read(ddata->gcb_regmap, REG_GCB_SOFT_RST, &val);
	if (err)
		return err;

	return val;
}

int ocelot_chip_reset(struct device *dev)
{
	struct ocelot_ddata *ddata = dev_get_drvdata(dev);
	int ret, val;

	/*
	 * Reset the entire chip here to put it into a completely known state.
	 * Other drivers may want to reset their own subsystems. The register
	 * self-clears, so one write is all that is needed and wait for it to
	 * clear.
	 */
	ret = regmap_write(ddata->gcb_regmap, REG_GCB_SOFT_RST, BIT_SOFT_CHIP_RST);
	if (ret)
		return ret;

	return readx_poll_timeout(ocelot_gcb_chip_rst_status, ddata, val, !val,
				  VSC7512_GCB_RST_SLEEP_US, VSC7512_GCB_RST_TIMEOUT_US);
}
EXPORT_SYMBOL_NS(ocelot_chip_reset, MFD_OCELOT);

static const struct resource vsc7512_miim0_resources[] = {
	DEFINE_RES_REG_NAMED(VSC7512_MIIM0_RES_START, VSC7512_MIIM_RES_SIZE, "gcb_miim0"),
	DEFINE_RES_REG_NAMED(VSC7512_PHY_RES_START, VSC7512_PHY_RES_SIZE, "gcb_phy"),
};

static const struct resource vsc7512_miim1_resources[] = {
	DEFINE_RES_REG_NAMED(VSC7512_MIIM1_RES_START, VSC7512_MIIM_RES_SIZE, "gcb_miim1"),
};

static const struct resource vsc7512_pinctrl_resources[] = {
	DEFINE_RES_REG_NAMED(VSC7512_GPIO_RES_START, VSC7512_GPIO_RES_SIZE, "gcb_gpio"),
};

static const struct resource vsc7512_sgpio_resources[] = {
	DEFINE_RES_REG_NAMED(VSC7512_SIO_CTRL_RES_START, VSC7512_SIO_CTRL_RES_SIZE, "gcb_sio"),
};

static const struct resource vsc7512_serdes_resources[] = {
	DEFINE_RES_REG_NAMED(VSC7512_HSIO_RES_START, VSC7512_HSIO_RES_SIZE, "hsio"),
};

static const struct resource vsc7512_switch_resources[] = {
	DEFINE_RES_REG_NAMED(VSC7512_ANA_RES_START, VSC7512_ANA_RES_SIZE, "ana"),
	DEFINE_RES_REG_NAMED(VSC7512_HSIO_RES_START, VSC7512_HSIO_RES_SIZE, "hsio"),
	DEFINE_RES_REG_NAMED(VSC7512_QS_RES_START, VSC7512_QS_RES_SIZE, "qs"),
	DEFINE_RES_REG_NAMED(VSC7512_QSYS_RES_START, VSC7512_QSYS_RES_SIZE, "qsys"),
	DEFINE_RES_REG_NAMED(VSC7512_REW_RES_START, VSC7512_REW_RES_SIZE, "rew"),
	DEFINE_RES_REG_NAMED(VSC7512_SYS_RES_START, VSC7512_SYS_RES_SIZE, "sys"),
	DEFINE_RES_REG_NAMED(VSC7512_S0_RES_START, VCAP_RES_SIZE, "s0"),
	DEFINE_RES_REG_NAMED(VSC7512_S1_RES_START, VCAP_RES_SIZE, "s1"),
	DEFINE_RES_REG_NAMED(VSC7512_S2_RES_START, VCAP_RES_SIZE, "s2"),
	DEFINE_RES_REG_NAMED(VSC7512_PORT_0_RES_START, VSC7512_PORT_RES_SIZE, "port0"),
	DEFINE_RES_REG_NAMED(VSC7512_PORT_1_RES_START, VSC7512_PORT_RES_SIZE, "port1"),
	DEFINE_RES_REG_NAMED(VSC7512_PORT_2_RES_START, VSC7512_PORT_RES_SIZE, "port2"),
	DEFINE_RES_REG_NAMED(VSC7512_PORT_3_RES_START, VSC7512_PORT_RES_SIZE, "port3"),
	DEFINE_RES_REG_NAMED(VSC7512_PORT_4_RES_START, VSC7512_PORT_RES_SIZE, "port4"),
	DEFINE_RES_REG_NAMED(VSC7512_PORT_5_RES_START, VSC7512_PORT_RES_SIZE, "port5"),
	DEFINE_RES_REG_NAMED(VSC7512_PORT_6_RES_START, VSC7512_PORT_RES_SIZE, "port6"),
	DEFINE_RES_REG_NAMED(VSC7512_PORT_7_RES_START, VSC7512_PORT_RES_SIZE, "port7"),
	DEFINE_RES_REG_NAMED(VSC7512_PORT_8_RES_START, VSC7512_PORT_RES_SIZE, "port8"),
	DEFINE_RES_REG_NAMED(VSC7512_PORT_9_RES_START, VSC7512_PORT_RES_SIZE, "port9"),
	DEFINE_RES_REG_NAMED(VSC7512_PORT_10_RES_START, VSC7512_PORT_RES_SIZE, "port10")
};

static const struct mfd_cell vsc7512_devs[] = {
	{
		.name = "ocelot-pinctrl",
		.of_compatible = "mscc,ocelot-pinctrl",
		.num_resources = ARRAY_SIZE(vsc7512_pinctrl_resources),
		.resources = vsc7512_pinctrl_resources,
	}, {
		.name = "ocelot-sgpio",
		.of_compatible = "mscc,ocelot-sgpio",
		.num_resources = ARRAY_SIZE(vsc7512_sgpio_resources),
		.resources = vsc7512_sgpio_resources,
	}, {
		.name = "ocelot-miim0",
		.of_compatible = "mscc,ocelot-miim",
		.of_reg = VSC7512_MIIM0_RES_START,
		.use_of_reg = true,
		.num_resources = ARRAY_SIZE(vsc7512_miim0_resources),
		.resources = vsc7512_miim0_resources,
	}, {
		.name = "ocelot-miim1",
		.of_compatible = "mscc,ocelot-miim",
		.of_reg = VSC7512_MIIM1_RES_START,
		.use_of_reg = true,
		.num_resources = ARRAY_SIZE(vsc7512_miim1_resources),
		.resources = vsc7512_miim1_resources,
	}, {
		.name = "ocelot-serdes",
		.of_compatible = "mscc,vsc7514-serdes",
		.num_resources = ARRAY_SIZE(vsc7512_serdes_resources),
		.resources = vsc7512_serdes_resources,
	}, {
		.name = "ocelot-ext-switch",
		.of_compatible = "mscc,vsc7512-switch",
		.num_resources = ARRAY_SIZE(vsc7512_switch_resources),
		.resources = vsc7512_switch_resources,
	},
};

static void ocelot_core_try_add_regmap(struct device *dev,
				       const struct resource *res)
{
	if (dev_get_regmap(dev, res->name))
		return;

	ocelot_spi_init_regmap(dev, res);
}

static void ocelot_core_try_add_regmaps(struct device *dev,
					const struct mfd_cell *cell)
{
	int i;

	for (i = 0; i < cell->num_resources; i++)
		ocelot_core_try_add_regmap(dev, &cell->resources[i]);
}

int ocelot_core_init(struct device *dev)
{
	int i, ndevs;

	ndevs = ARRAY_SIZE(vsc7512_devs);

	for (i = 0; i < ndevs; i++)
		ocelot_core_try_add_regmaps(dev, &vsc7512_devs[i]);

	return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, vsc7512_devs, ndevs, NULL, 0, NULL);
}
EXPORT_SYMBOL_NS(ocelot_core_init, MFD_OCELOT);

MODULE_DESCRIPTION("Externally Controlled Ocelot Chip Driver");
MODULE_AUTHOR("Colin Foster <colin.foster@in-advantage.com>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(MFD_OCELOT_SPI);
