// SPDX-License-Identifier: GPL-2.0
/*
 * ip30-xtalk.c - Very basic Crosstalk (XIO) detection support.
 *   Copyright (C) 2004-2007 Stanislaw Skowronek <skylark@unaligned.org>
 *   Copyright (C) 2009 Johannes Dickgreber <tanzy@gmx.de>
 *   Copyright (C) 2007, 2014-2016 Joshua Kinard <kumba@gentoo.org>
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/platform_data/sgi-w1.h>
#include <linux/platform_data/xtalk-bridge.h>

#include <asm/xtalk/xwidget.h>
#include <asm/pci/bridge.h>

#define IP30_SWIN_BASE(widget) \
		(0x0000000010000000 | (((unsigned long)(widget)) << 24))

#define IP30_RAW_SWIN_BASE(widget)	(IO_BASE + IP30_SWIN_BASE(widget))

#define IP30_SWIN_SIZE		(1 << 24)

#define IP30_WIDGET_XBOW        _AC(0x0, UL)    /* XBow is always 0 */
#define IP30_WIDGET_HEART       _AC(0x8, UL)    /* HEART is always 8 */
#define IP30_WIDGET_PCI_BASE    _AC(0xf, UL)    /* BaseIO PCI is always 15 */

#define XTALK_NODEV             0xffffffff

#define XBOW_REG_LINK_STAT_0    0x114
#define XBOW_REG_LINK_BLK_SIZE  0x40
#define XBOW_REG_LINK_ALIVE     0x80000000

#define HEART_INTR_ADDR		0x00000080

#define xtalk_read	__raw_readl

static void bridge_platform_create(int widget, int masterwid)
{
	struct xtalk_bridge_platform_data *bd;
	struct sgi_w1_platform_data *wd;
	struct platform_device *pdev_wd;
	struct platform_device *pdev_bd;
	struct resource w1_res;

	wd = kzalloc(sizeof(*wd), GFP_KERNEL);
	if (!wd) {
		pr_warn("xtalk:%x bridge create out of memory\n", widget);
		return;
	}

	snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx",
		 IP30_SWIN_BASE(widget));

	memset(&w1_res, 0, sizeof(w1_res));
	w1_res.start = IP30_SWIN_BASE(widget) +
				offsetof(struct bridge_regs, b_nic);
	w1_res.end = w1_res.start + 3;
	w1_res.flags = IORESOURCE_MEM;

	pdev_wd = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
	if (!pdev_wd) {
		pr_warn("xtalk:%x bridge create out of memory\n", widget);
		goto err_kfree_wd;
	}
	if (platform_device_add_resources(pdev_wd, &w1_res, 1)) {
		pr_warn("xtalk:%x bridge failed to add platform resources.\n", widget);
		goto err_put_pdev_wd;
	}
	if (platform_device_add_data(pdev_wd, wd, sizeof(*wd))) {
		pr_warn("xtalk:%x bridge failed to add platform data.\n", widget);
		goto err_put_pdev_wd;
	}
	if (platform_device_add(pdev_wd)) {
		pr_warn("xtalk:%x bridge failed to add platform device.\n", widget);
		goto err_put_pdev_wd;
	}
	/* platform_device_add_data() duplicates the data */
	kfree(wd);

	bd = kzalloc(sizeof(*bd), GFP_KERNEL);
	if (!bd) {
		pr_warn("xtalk:%x bridge create out of memory\n", widget);
		goto err_unregister_pdev_wd;
	}
	pdev_bd = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
	if (!pdev_bd) {
		pr_warn("xtalk:%x bridge create out of memory\n", widget);
		goto err_kfree_bd;
	}

	bd->bridge_addr	= IP30_RAW_SWIN_BASE(widget);
	bd->intr_addr	= HEART_INTR_ADDR;
	bd->nasid	= 0;
	bd->masterwid	= masterwid;

	bd->mem.name	= "Bridge PCI MEM";
	bd->mem.start	= IP30_SWIN_BASE(widget) + BRIDGE_DEVIO0;
	bd->mem.end	= IP30_SWIN_BASE(widget) + IP30_SWIN_SIZE - 1;
	bd->mem.flags	= IORESOURCE_MEM;
	bd->mem_offset	= IP30_SWIN_BASE(widget);

	bd->io.name	= "Bridge PCI IO";
	bd->io.start	= IP30_SWIN_BASE(widget) + BRIDGE_DEVIO0;
	bd->io.end	= IP30_SWIN_BASE(widget) + IP30_SWIN_SIZE - 1;
	bd->io.flags	= IORESOURCE_IO;
	bd->io_offset	= IP30_SWIN_BASE(widget);

	if (platform_device_add_data(pdev_bd, bd, sizeof(*bd))) {
		pr_warn("xtalk:%x bridge failed to add platform data.\n", widget);
		goto err_put_pdev_bd;
	}
	if (platform_device_add(pdev_bd)) {
		pr_warn("xtalk:%x bridge failed to add platform device.\n", widget);
		goto err_put_pdev_bd;
	}
	/* platform_device_add_data() duplicates the data */
	kfree(bd);
	pr_info("xtalk:%x bridge widget\n", widget);
	return;

err_put_pdev_bd:
	platform_device_put(pdev_bd);
err_kfree_bd:
	kfree(bd);
err_unregister_pdev_wd:
	platform_device_unregister(pdev_wd);
	return;
err_put_pdev_wd:
	platform_device_put(pdev_wd);
err_kfree_wd:
	kfree(wd);
	return;
}

static unsigned int __init xbow_widget_active(s8 wid)
{
	unsigned int link_stat;

	link_stat = xtalk_read((void *)(IP30_RAW_SWIN_BASE(IP30_WIDGET_XBOW) +
					XBOW_REG_LINK_STAT_0 +
					XBOW_REG_LINK_BLK_SIZE *
					(wid - 8)));

	return (link_stat & XBOW_REG_LINK_ALIVE) ? 1 : 0;
}

static void __init xtalk_init_widget(s8 wid, s8 masterwid)
{
	xwidget_part_num_t partnum;
	widgetreg_t widget_id;

	if (!xbow_widget_active(wid))
		return;

	widget_id = xtalk_read((void *)(IP30_RAW_SWIN_BASE(wid) + WIDGET_ID));

	partnum = XWIDGET_PART_NUM(widget_id);

	switch (partnum) {
	case BRIDGE_WIDGET_PART_NUM:
	case XBRIDGE_WIDGET_PART_NUM:
		bridge_platform_create(wid, masterwid);
		break;
	default:
		pr_info("xtalk:%x unknown widget (0x%x)\n", wid, partnum);
		break;
	}
}

static int __init ip30_xtalk_init(void)
{
	int i;

	/*
	 * Walk widget IDs backwards so that BaseIO is probed first.  This
	 * ensures that the BaseIO IOC3 is always detected as eth0.
	 */
	for (i = IP30_WIDGET_PCI_BASE; i > IP30_WIDGET_HEART; i--)
		xtalk_init_widget(i, IP30_WIDGET_HEART);

	return 0;
}

arch_initcall(ip30_xtalk_init);
