// 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;
	case STP_PACKET_XSYNC:
		reg += 8;
	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>");
