// SPDX-License-Identifier: GPL-2.0
/*
 * Intel(R) Trace Hub Software Trace Hub support
 *
 * Copyright (C) 2014-2015 Intel Corporation.
 */

#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt

#include <linux/types.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/stm.h>

#include "intel_th.h"
#include "sth.h"

struct sth_device {
	void __iomem	*base;
	void __iomem	*channels;
	phys_addr_t	channels_phys;
	struct device	*dev;
	struct stm_data	stm;
	unsigned int	sw_nmasters;
};

static struct intel_th_channel __iomem *
sth_channel(struct sth_device *sth, unsigned int master, unsigned int channel)
{
	struct intel_th_channel __iomem *sw_map = sth->channels;

	return &sw_map[(master - sth->stm.sw_start) * sth->stm.sw_nchannels +
		       channel];
}

static void sth_iowrite(void __iomem *dest, const unsigned char *payload,
			unsigned int size)
{
	switch (size) {
#ifdef CONFIG_64BIT
	case 8:
		writeq_relaxed(*(u64 *)payload, dest);
		break;
#endif
	case 4:
		writel_relaxed(*(u32 *)payload, dest);
		break;
	case 2:
		writew_relaxed(*(u16 *)payload, dest);
		break;
	case 1:
		writeb_relaxed(*(u8 *)payload, dest);
		break;
	default:
		break;
	}
}

static ssize_t notrace sth_stm_packet(struct stm_data *stm_data,
				      unsigned int master,
				      unsigned int channel,
				      unsigned int packet,
				      unsigned int flags,
				      unsigned int size,
				      const unsigned char *payload)
{
	struct sth_device *sth = container_of(stm_data, struct sth_device, stm);
	struct intel_th_channel __iomem *out =
		sth_channel(sth, master, channel);
	u64 __iomem *outp = &out->Dn;
	unsigned long reg = REG_STH_TRIG;

#ifndef CONFIG_64BIT
	if (size > 4)
		size = 4;
#endif

	size = rounddown_pow_of_two(size);

	switch (packet) {
	/* Global packets (GERR, XSYNC, TRIG) are sent with register writes */
	case STP_PACKET_GERR:
		reg += 4;
		/* fall through */

	case STP_PACKET_XSYNC:
		reg += 8;
		/* fall through */

	case STP_PACKET_TRIG:
		if (flags & STP_PACKET_TIMESTAMPED)
			reg += 4;
		writeb_relaxed(*payload, sth->base + reg);
		break;

	case STP_PACKET_MERR:
		if (size > 4)
			size = 4;

		sth_iowrite(&out->MERR, payload, size);
		break;

	case STP_PACKET_FLAG:
		if (flags & STP_PACKET_TIMESTAMPED)
			outp = (u64 __iomem *)&out->FLAG_TS;
		else
			outp = (u64 __iomem *)&out->FLAG;

		size = 0;
		writeb_relaxed(0, outp);
		break;

	case STP_PACKET_USER:
		if (flags & STP_PACKET_TIMESTAMPED)
			outp = &out->USER_TS;
		else
			outp = &out->USER;
		sth_iowrite(outp, payload, size);
		break;

	case STP_PACKET_DATA:
		outp = &out->Dn;

		if (flags & STP_PACKET_TIMESTAMPED)
			outp += 2;
		if (flags & STP_PACKET_MARKED)
			outp++;

		sth_iowrite(outp, payload, size);
		break;
	default:
		return -ENOTSUPP;
	}

	return size;
}

static phys_addr_t
sth_stm_mmio_addr(struct stm_data *stm_data, unsigned int master,
		  unsigned int channel, unsigned int nr_chans)
{
	struct sth_device *sth = container_of(stm_data, struct sth_device, stm);
	phys_addr_t addr;

	master -= sth->stm.sw_start;
	addr = sth->channels_phys + (master * sth->stm.sw_nchannels + channel) *
		sizeof(struct intel_th_channel);

	if (offset_in_page(addr) ||
	    offset_in_page(nr_chans * sizeof(struct intel_th_channel)))
		return 0;

	return addr;
}

static int sth_stm_link(struct stm_data *stm_data, unsigned int master,
			 unsigned int channel)
{
	struct sth_device *sth = container_of(stm_data, struct sth_device, stm);

	intel_th_set_output(to_intel_th_device(sth->dev), master);

	return 0;
}

static int intel_th_sw_init(struct sth_device *sth)
{
	u32 reg;

	reg = ioread32(sth->base + REG_STH_STHCAP1);
	sth->stm.sw_nchannels = reg & 0xff;

	reg = ioread32(sth->base + REG_STH_STHCAP0);
	sth->stm.sw_start = reg & 0xffff;
	sth->stm.sw_end = reg >> 16;

	sth->sw_nmasters = sth->stm.sw_end - sth->stm.sw_start;
	dev_dbg(sth->dev, "sw_start: %x sw_end: %x masters: %x nchannels: %x\n",
		sth->stm.sw_start, sth->stm.sw_end, sth->sw_nmasters,
		sth->stm.sw_nchannels);

	return 0;
}

static int intel_th_sth_probe(struct intel_th_device *thdev)
{
	struct device *dev = &thdev->dev;
	struct sth_device *sth;
	struct resource *res;
	void __iomem *base, *channels;
	int err;

	res = intel_th_device_get_resource(thdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

	base = devm_ioremap(dev, res->start, resource_size(res));
	if (!base)
		return -ENOMEM;

	res = intel_th_device_get_resource(thdev, IORESOURCE_MEM, 1);
	if (!res)
		return -ENODEV;

	channels = devm_ioremap(dev, res->start, resource_size(res));
	if (!channels)
		return -ENOMEM;

	sth = devm_kzalloc(dev, sizeof(*sth), GFP_KERNEL);
	if (!sth)
		return -ENOMEM;

	sth->dev = dev;
	sth->base = base;
	sth->channels = channels;
	sth->channels_phys = res->start;
	sth->stm.name = dev_name(dev);
	sth->stm.packet = sth_stm_packet;
	sth->stm.mmio_addr = sth_stm_mmio_addr;
	sth->stm.sw_mmiosz = sizeof(struct intel_th_channel);
	sth->stm.link = sth_stm_link;

	err = intel_th_sw_init(sth);
	if (err)
		return err;

	err = stm_register_device(dev, &sth->stm, THIS_MODULE);
	if (err) {
		dev_err(dev, "stm_register_device failed\n");
		return err;
	}

	dev_set_drvdata(dev, sth);

	return 0;
}

static void intel_th_sth_remove(struct intel_th_device *thdev)
{
	struct sth_device *sth = dev_get_drvdata(&thdev->dev);

	stm_unregister_device(&sth->stm);
}

static struct intel_th_driver intel_th_sth_driver = {
	.probe	= intel_th_sth_probe,
	.remove	= intel_th_sth_remove,
	.driver	= {
		.name	= "sth",
		.owner	= THIS_MODULE,
	},
};

module_driver(intel_th_sth_driver,
	      intel_th_driver_register,
	      intel_th_driver_unregister);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel(R) Trace Hub Software Trace Hub driver");
MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>");
