// SPDX-License-Identifier: GPL-2.0-only
/* sun_esp.c: ESP front-end for Sparc SBUS systems.
 *
 * Copyright (C) 2007, 2008 David S. Miller (davem@davemloft.net)
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/gfp.h>

#include <asm/irq.h>
#include <asm/io.h>
#include <asm/dma.h>

#include <scsi/scsi_host.h>

#include "esp_scsi.h"

#define DRV_MODULE_NAME		"sun_esp"
#define PFX DRV_MODULE_NAME	": "
#define DRV_VERSION		"1.100"
#define DRV_MODULE_RELDATE	"August 27, 2008"

#define dma_read32(REG) \
	sbus_readl(esp->dma_regs + (REG))
#define dma_write32(VAL, REG) \
	sbus_writel((VAL), esp->dma_regs + (REG))

/* DVMA chip revisions */
enum dvma_rev {
	dvmarev0,
	dvmaesc1,
	dvmarev1,
	dvmarev2,
	dvmarev3,
	dvmarevplus,
	dvmahme
};

static int esp_sbus_setup_dma(struct esp *esp, struct platform_device *dma_of)
{
	esp->dma = dma_of;

	esp->dma_regs = of_ioremap(&dma_of->resource[0], 0,
				   resource_size(&dma_of->resource[0]),
				   "espdma");
	if (!esp->dma_regs)
		return -ENOMEM;

	switch (dma_read32(DMA_CSR) & DMA_DEVICE_ID) {
	case DMA_VERS0:
		esp->dmarev = dvmarev0;
		break;
	case DMA_ESCV1:
		esp->dmarev = dvmaesc1;
		break;
	case DMA_VERS1:
		esp->dmarev = dvmarev1;
		break;
	case DMA_VERS2:
		esp->dmarev = dvmarev2;
		break;
	case DMA_VERHME:
		esp->dmarev = dvmahme;
		break;
	case DMA_VERSPLUS:
		esp->dmarev = dvmarevplus;
		break;
	}

	return 0;

}

static int esp_sbus_map_regs(struct esp *esp, int hme)
{
	struct platform_device *op = to_platform_device(esp->dev);
	struct resource *res;

	/* On HME, two reg sets exist, first is DVMA,
	 * second is ESP registers.
	 */
	if (hme)
		res = &op->resource[1];
	else
		res = &op->resource[0];

	esp->regs = of_ioremap(res, 0, SBUS_ESP_REG_SIZE, "ESP");
	if (!esp->regs)
		return -ENOMEM;

	return 0;
}

static int esp_sbus_map_command_block(struct esp *esp)
{
	esp->command_block = dma_alloc_coherent(esp->dev, 16,
						&esp->command_block_dma,
						GFP_KERNEL);
	if (!esp->command_block)
		return -ENOMEM;
	return 0;
}

static int esp_sbus_register_irq(struct esp *esp)
{
	struct Scsi_Host *host = esp->host;
	struct platform_device *op = to_platform_device(esp->dev);

	host->irq = op->archdata.irqs[0];
	return request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp);
}

static void esp_get_scsi_id(struct esp *esp, struct platform_device *espdma)
{
	struct platform_device *op = to_platform_device(esp->dev);
	struct device_node *dp;

	dp = op->dev.of_node;
	esp->scsi_id = of_getintprop_default(dp, "initiator-id", 0xff);
	if (esp->scsi_id != 0xff)
		goto done;

	esp->scsi_id = of_getintprop_default(dp, "scsi-initiator-id", 0xff);
	if (esp->scsi_id != 0xff)
		goto done;

	esp->scsi_id = of_getintprop_default(espdma->dev.of_node,
					     "scsi-initiator-id", 7);

done:
	esp->host->this_id = esp->scsi_id;
	esp->scsi_id_mask = (1 << esp->scsi_id);
}

static void esp_get_differential(struct esp *esp)
{
	struct platform_device *op = to_platform_device(esp->dev);
	struct device_node *dp;

	dp = op->dev.of_node;
	if (of_find_property(dp, "differential", NULL))
		esp->flags |= ESP_FLAG_DIFFERENTIAL;
	else
		esp->flags &= ~ESP_FLAG_DIFFERENTIAL;
}

static void esp_get_clock_params(struct esp *esp)
{
	struct platform_device *op = to_platform_device(esp->dev);
	struct device_node *bus_dp, *dp;
	int fmhz;

	dp = op->dev.of_node;
	bus_dp = dp->parent;

	fmhz = of_getintprop_default(dp, "clock-frequency", 0);
	if (fmhz == 0)
		fmhz = of_getintprop_default(bus_dp, "clock-frequency", 0);

	esp->cfreq = fmhz;
}

static void esp_get_bursts(struct esp *esp, struct platform_device *dma_of)
{
	struct device_node *dma_dp = dma_of->dev.of_node;
	struct platform_device *op = to_platform_device(esp->dev);
	struct device_node *dp;
	u8 bursts, val;

	dp = op->dev.of_node;
	bursts = of_getintprop_default(dp, "burst-sizes", 0xff);
	val = of_getintprop_default(dma_dp, "burst-sizes", 0xff);
	if (val != 0xff)
		bursts &= val;

	val = of_getintprop_default(dma_dp->parent, "burst-sizes", 0xff);
	if (val != 0xff)
		bursts &= val;

	if (bursts == 0xff ||
	    (bursts & DMA_BURST16) == 0 ||
	    (bursts & DMA_BURST32) == 0)
		bursts = (DMA_BURST32 - 1);

	esp->bursts = bursts;
}

static void esp_sbus_get_props(struct esp *esp, struct platform_device *espdma)
{
	esp_get_scsi_id(esp, espdma);
	esp_get_differential(esp);
	esp_get_clock_params(esp);
	esp_get_bursts(esp, espdma);
}

static void sbus_esp_write8(struct esp *esp, u8 val, unsigned long reg)
{
	sbus_writeb(val, esp->regs + (reg * 4UL));
}

static u8 sbus_esp_read8(struct esp *esp, unsigned long reg)
{
	return sbus_readb(esp->regs + (reg * 4UL));
}

static int sbus_esp_irq_pending(struct esp *esp)
{
	if (dma_read32(DMA_CSR) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))
		return 1;
	return 0;
}

static void sbus_esp_reset_dma(struct esp *esp)
{
	int can_do_burst16, can_do_burst32, can_do_burst64;
	int can_do_sbus64, lim;
	struct platform_device *op = to_platform_device(esp->dev);
	u32 val;

	can_do_burst16 = (esp->bursts & DMA_BURST16) != 0;
	can_do_burst32 = (esp->bursts & DMA_BURST32) != 0;
	can_do_burst64 = 0;
	can_do_sbus64 = 0;
	if (sbus_can_dma_64bit())
		can_do_sbus64 = 1;
	if (sbus_can_burst64())
		can_do_burst64 = (esp->bursts & DMA_BURST64) != 0;

	/* Put the DVMA into a known state. */
	if (esp->dmarev != dvmahme) {
		val = dma_read32(DMA_CSR);
		dma_write32(val | DMA_RST_SCSI, DMA_CSR);
		dma_write32(val & ~DMA_RST_SCSI, DMA_CSR);
	}
	switch (esp->dmarev) {
	case dvmahme:
		dma_write32(DMA_RESET_FAS366, DMA_CSR);
		dma_write32(DMA_RST_SCSI, DMA_CSR);

		esp->prev_hme_dmacsr = (DMA_PARITY_OFF | DMA_2CLKS |
					DMA_SCSI_DISAB | DMA_INT_ENAB);

		esp->prev_hme_dmacsr &= ~(DMA_ENABLE | DMA_ST_WRITE |
					  DMA_BRST_SZ);

		if (can_do_burst64)
			esp->prev_hme_dmacsr |= DMA_BRST64;
		else if (can_do_burst32)
			esp->prev_hme_dmacsr |= DMA_BRST32;

		if (can_do_sbus64) {
			esp->prev_hme_dmacsr |= DMA_SCSI_SBUS64;
			sbus_set_sbus64(&op->dev, esp->bursts);
		}

		lim = 1000;
		while (dma_read32(DMA_CSR) & DMA_PEND_READ) {
			if (--lim == 0) {
				printk(KERN_ALERT PFX "esp%d: DMA_PEND_READ "
				       "will not clear!\n",
				       esp->host->unique_id);
				break;
			}
			udelay(1);
		}

		dma_write32(0, DMA_CSR);
		dma_write32(esp->prev_hme_dmacsr, DMA_CSR);

		dma_write32(0, DMA_ADDR);
		break;

	case dvmarev2:
		if (esp->rev != ESP100) {
			val = dma_read32(DMA_CSR);
			dma_write32(val | DMA_3CLKS, DMA_CSR);
		}
		break;

	case dvmarev3:
		val = dma_read32(DMA_CSR);
		val &= ~DMA_3CLKS;
		val |= DMA_2CLKS;
		if (can_do_burst32) {
			val &= ~DMA_BRST_SZ;
			val |= DMA_BRST32;
		}
		dma_write32(val, DMA_CSR);
		break;

	case dvmaesc1:
		val = dma_read32(DMA_CSR);
		val |= DMA_ADD_ENABLE;
		val &= ~DMA_BCNT_ENAB;
		if (!can_do_burst32 && can_do_burst16) {
			val |= DMA_ESC_BURST;
		} else {
			val &= ~(DMA_ESC_BURST);
		}
		dma_write32(val, DMA_CSR);
		break;

	default:
		break;
	}

	/* Enable interrupts.  */
	val = dma_read32(DMA_CSR);
	dma_write32(val | DMA_INT_ENAB, DMA_CSR);
}

static void sbus_esp_dma_drain(struct esp *esp)
{
	u32 csr;
	int lim;

	if (esp->dmarev == dvmahme)
		return;

	csr = dma_read32(DMA_CSR);
	if (!(csr & DMA_FIFO_ISDRAIN))
		return;

	if (esp->dmarev != dvmarev3 && esp->dmarev != dvmaesc1)
		dma_write32(csr | DMA_FIFO_STDRAIN, DMA_CSR);

	lim = 1000;
	while (dma_read32(DMA_CSR) & DMA_FIFO_ISDRAIN) {
		if (--lim == 0) {
			printk(KERN_ALERT PFX "esp%d: DMA will not drain!\n",
			       esp->host->unique_id);
			break;
		}
		udelay(1);
	}
}

static void sbus_esp_dma_invalidate(struct esp *esp)
{
	if (esp->dmarev == dvmahme) {
		dma_write32(DMA_RST_SCSI, DMA_CSR);

		esp->prev_hme_dmacsr = ((esp->prev_hme_dmacsr |
					 (DMA_PARITY_OFF | DMA_2CLKS |
					  DMA_SCSI_DISAB | DMA_INT_ENAB)) &
					~(DMA_ST_WRITE | DMA_ENABLE));

		dma_write32(0, DMA_CSR);
		dma_write32(esp->prev_hme_dmacsr, DMA_CSR);

		/* This is necessary to avoid having the SCSI channel
		 * engine lock up on us.
		 */
		dma_write32(0, DMA_ADDR);
	} else {
		u32 val;
		int lim;

		lim = 1000;
		while ((val = dma_read32(DMA_CSR)) & DMA_PEND_READ) {
			if (--lim == 0) {
				printk(KERN_ALERT PFX "esp%d: DMA will not "
				       "invalidate!\n", esp->host->unique_id);
				break;
			}
			udelay(1);
		}

		val &= ~(DMA_ENABLE | DMA_ST_WRITE | DMA_BCNT_ENAB);
		val |= DMA_FIFO_INV;
		dma_write32(val, DMA_CSR);
		val &= ~DMA_FIFO_INV;
		dma_write32(val, DMA_CSR);
	}
}

static void sbus_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count,
				  u32 dma_count, int write, u8 cmd)
{
	u32 csr;

	BUG_ON(!(cmd & ESP_CMD_DMA));

	sbus_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
	sbus_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
	if (esp->rev == FASHME) {
		sbus_esp_write8(esp, (esp_count >> 16) & 0xff, FAS_RLO);
		sbus_esp_write8(esp, 0, FAS_RHI);

		scsi_esp_cmd(esp, cmd);

		csr = esp->prev_hme_dmacsr;
		csr |= DMA_SCSI_DISAB | DMA_ENABLE;
		if (write)
			csr |= DMA_ST_WRITE;
		else
			csr &= ~DMA_ST_WRITE;
		esp->prev_hme_dmacsr = csr;

		dma_write32(dma_count, DMA_COUNT);
		dma_write32(addr, DMA_ADDR);
		dma_write32(csr, DMA_CSR);
	} else {
		csr = dma_read32(DMA_CSR);
		csr |= DMA_ENABLE;
		if (write)
			csr |= DMA_ST_WRITE;
		else
			csr &= ~DMA_ST_WRITE;
		dma_write32(csr, DMA_CSR);
		if (esp->dmarev == dvmaesc1) {
			u32 end = PAGE_ALIGN(addr + dma_count + 16U);
			dma_write32(end - addr, DMA_COUNT);
		}
		dma_write32(addr, DMA_ADDR);

		scsi_esp_cmd(esp, cmd);
	}

}

static int sbus_esp_dma_error(struct esp *esp)
{
	u32 csr = dma_read32(DMA_CSR);

	if (csr & DMA_HNDL_ERROR)
		return 1;

	return 0;
}

static const struct esp_driver_ops sbus_esp_ops = {
	.esp_write8	=	sbus_esp_write8,
	.esp_read8	=	sbus_esp_read8,
	.irq_pending	=	sbus_esp_irq_pending,
	.reset_dma	=	sbus_esp_reset_dma,
	.dma_drain	=	sbus_esp_dma_drain,
	.dma_invalidate	=	sbus_esp_dma_invalidate,
	.send_dma_cmd	=	sbus_esp_send_dma_cmd,
	.dma_error	=	sbus_esp_dma_error,
};

static int esp_sbus_probe_one(struct platform_device *op,
			      struct platform_device *espdma, int hme)
{
	struct scsi_host_template *tpnt = &scsi_esp_template;
	struct Scsi_Host *host;
	struct esp *esp;
	int err;

	host = scsi_host_alloc(tpnt, sizeof(struct esp));

	err = -ENOMEM;
	if (!host)
		goto fail;

	host->max_id = (hme ? 16 : 8);
	esp = shost_priv(host);

	esp->host = host;
	esp->dev = &op->dev;
	esp->ops = &sbus_esp_ops;

	if (hme)
		esp->flags |= ESP_FLAG_WIDE_CAPABLE;

	err = esp_sbus_setup_dma(esp, espdma);
	if (err < 0)
		goto fail_unlink;

	err = esp_sbus_map_regs(esp, hme);
	if (err < 0)
		goto fail_unlink;

	err = esp_sbus_map_command_block(esp);
	if (err < 0)
		goto fail_unmap_regs;

	err = esp_sbus_register_irq(esp);
	if (err < 0)
		goto fail_unmap_command_block;

	esp_sbus_get_props(esp, espdma);

	/* Before we try to touch the ESP chip, ESC1 dma can
	 * come up with the reset bit set, so make sure that
	 * is clear first.
	 */
	if (esp->dmarev == dvmaesc1) {
		u32 val = dma_read32(DMA_CSR);

		dma_write32(val & ~DMA_RST_SCSI, DMA_CSR);
	}

	dev_set_drvdata(&op->dev, esp);

	err = scsi_esp_register(esp);
	if (err)
		goto fail_free_irq;

	return 0;

fail_free_irq:
	free_irq(host->irq, esp);
fail_unmap_command_block:
	dma_free_coherent(&op->dev, 16,
			  esp->command_block,
			  esp->command_block_dma);
fail_unmap_regs:
	of_iounmap(&op->resource[(hme ? 1 : 0)], esp->regs, SBUS_ESP_REG_SIZE);
fail_unlink:
	scsi_host_put(host);
fail:
	return err;
}

static int esp_sbus_probe(struct platform_device *op)
{
	struct device_node *dma_node = NULL;
	struct device_node *dp = op->dev.of_node;
	struct platform_device *dma_of = NULL;
	int hme = 0;
	int ret;

	if (of_node_name_eq(dp->parent, "espdma") ||
	    of_node_name_eq(dp->parent, "dma"))
		dma_node = dp->parent;
	else if (of_node_name_eq(dp, "SUNW,fas")) {
		dma_node = op->dev.of_node;
		hme = 1;
	}
	if (dma_node)
		dma_of = of_find_device_by_node(dma_node);
	if (!dma_of)
		return -ENODEV;

	ret = esp_sbus_probe_one(op, dma_of, hme);
	if (ret)
		put_device(&dma_of->dev);

	return ret;
}

static int esp_sbus_remove(struct platform_device *op)
{
	struct esp *esp = dev_get_drvdata(&op->dev);
	struct platform_device *dma_of = esp->dma;
	unsigned int irq = esp->host->irq;
	bool is_hme;
	u32 val;

	scsi_esp_unregister(esp);

	/* Disable interrupts.  */
	val = dma_read32(DMA_CSR);
	dma_write32(val & ~DMA_INT_ENAB, DMA_CSR);

	free_irq(irq, esp);

	is_hme = (esp->dmarev == dvmahme);

	dma_free_coherent(&op->dev, 16,
			  esp->command_block,
			  esp->command_block_dma);
	of_iounmap(&op->resource[(is_hme ? 1 : 0)], esp->regs,
		   SBUS_ESP_REG_SIZE);
	of_iounmap(&dma_of->resource[0], esp->dma_regs,
		   resource_size(&dma_of->resource[0]));

	scsi_host_put(esp->host);

	dev_set_drvdata(&op->dev, NULL);

	put_device(&dma_of->dev);

	return 0;
}

static const struct of_device_id esp_match[] = {
	{
		.name = "SUNW,esp",
	},
	{
		.name = "SUNW,fas",
	},
	{
		.name = "esp",
	},
	{},
};
MODULE_DEVICE_TABLE(of, esp_match);

static struct platform_driver esp_sbus_driver = {
	.driver = {
		.name = "esp",
		.of_match_table = esp_match,
	},
	.probe		= esp_sbus_probe,
	.remove		= esp_sbus_remove,
};

static int __init sunesp_init(void)
{
	return platform_driver_register(&esp_sbus_driver);
}

static void __exit sunesp_exit(void)
{
	platform_driver_unregister(&esp_sbus_driver);
}

MODULE_DESCRIPTION("Sun ESP SCSI driver");
MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

module_init(sunesp_init);
module_exit(sunesp_exit);
