// SPDX-License-Identifier: GPL-2.0+
/*
 * Uclass for Primary-to-sideband bus, used to access various peripherals
 *
 * Copyright 2019 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */

#include <common.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
#include <p2sb.h>
#include <spl.h>
#include <asm/io.h>
#include <dm/uclass-internal.h>

#define PCR_COMMON_IOSF_1_0	1

int p2sb_set_hide(struct udevice *dev, bool hide)
{
	struct p2sb_ops *ops = p2sb_get_ops(dev);

	if (!ops->set_hide)
		return -ENOSYS;

	return ops->set_hide(dev, hide);
}

void *pcr_reg_address(struct udevice *dev, uint offset)
{
	struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev);
	struct udevice *p2sb = dev_get_parent(dev);
	struct p2sb_uc_priv *upriv = dev_get_uclass_priv(p2sb);
	uintptr_t reg_addr;

	/* Create an address based off of port id and offset */
	reg_addr = upriv->mmio_base;
	reg_addr += pplat->pid << PCR_PORTID_SHIFT;
	reg_addr += offset;

	return map_sysmem(reg_addr, 4);
}

/*
 * The mapping of addresses via the SBREG_BAR assumes the IOSF-SB
 * agents are using 32-bit aligned accesses for their configuration
 * registers. For IOSF versions greater than 1_0, IOSF-SB
 * agents can use any access (8/16/32 bit aligned) for their
 * configuration registers
 */
static inline void check_pcr_offset_align(uint offset, uint size)
{
	const size_t align = PCR_COMMON_IOSF_1_0 ? sizeof(uint32_t) : size;

	assert(IS_ALIGNED(offset, align));
}

uint pcr_read32(struct udevice *dev, uint offset)
{
	void *ptr;
	uint val;

	/* Ensure the PCR offset is correctly aligned */
	assert(IS_ALIGNED(offset, sizeof(uint32_t)));

	ptr = pcr_reg_address(dev, offset);
	val = readl(ptr);
	unmap_sysmem(ptr);

	return val;
}

uint pcr_read16(struct udevice *dev, uint offset)
{
	/* Ensure the PCR offset is correctly aligned */
	check_pcr_offset_align(offset, sizeof(uint16_t));

	return readw(pcr_reg_address(dev, offset));
}

uint pcr_read8(struct udevice *dev, uint offset)
{
	/* Ensure the PCR offset is correctly aligned */
	check_pcr_offset_align(offset, sizeof(uint8_t));

	return readb(pcr_reg_address(dev, offset));
}

/*
 * After every write one needs to perform a read an innocuous register to
 * ensure the writes are completed for certain ports. This is done for
 * all ports so that the callers don't need the per-port knowledge for
 * each transaction.
 */
static void write_completion(struct udevice *dev, uint offset)
{
	readl(pcr_reg_address(dev, ALIGN_DOWN(offset, sizeof(uint32_t))));
}

void pcr_write32(struct udevice *dev, uint offset, uint indata)
{
	/* Ensure the PCR offset is correctly aligned */
	assert(IS_ALIGNED(offset, sizeof(indata)));

	writel(indata, pcr_reg_address(dev, offset));
	/* Ensure the writes complete */
	write_completion(dev, offset);
}

void pcr_write16(struct udevice *dev, uint offset, uint indata)
{
	/* Ensure the PCR offset is correctly aligned */
	check_pcr_offset_align(offset, sizeof(uint16_t));

	writew(indata, pcr_reg_address(dev, offset));
	/* Ensure the writes complete */
	write_completion(dev, offset);
}

void pcr_write8(struct udevice *dev, uint offset, uint indata)
{
	/* Ensure the PCR offset is correctly aligned */
	check_pcr_offset_align(offset, sizeof(uint8_t));

	writeb(indata, pcr_reg_address(dev, offset));
	/* Ensure the writes complete */
	write_completion(dev, offset);
}

void pcr_clrsetbits32(struct udevice *dev, uint offset, uint clr, uint set)
{
	uint data32;

	data32 = pcr_read32(dev, offset);
	data32 &= ~clr;
	data32 |= set;
	pcr_write32(dev, offset, data32);
}

void pcr_clrsetbits16(struct udevice *dev, uint offset, uint clr, uint set)
{
	uint data16;

	data16 = pcr_read16(dev, offset);
	data16 &= ~clr;
	data16 |= set;
	pcr_write16(dev, offset, data16);
}

void pcr_clrsetbits8(struct udevice *dev, uint offset, uint clr, uint set)
{
	uint data8;

	data8 = pcr_read8(dev, offset);
	data8 &= ~clr;
	data8 |= set;
	pcr_write8(dev, offset, data8);
}

int p2sb_get_port_id(struct udevice *dev)
{
	struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev);

	return pplat->pid;
}

int p2sb_set_port_id(struct udevice *dev, int portid)
{
	struct udevice *ps2b;
	struct p2sb_child_platdata *pplat;

	if (!CONFIG_IS_ENABLED(OF_PLATDATA))
		return -ENOSYS;

	if (!CONFIG_IS_ENABLED(OF_PLATDATA_PARENT)) {
		uclass_find_first_device(UCLASS_P2SB, &ps2b);
		if (!ps2b)
			return -EDEADLK;
		dev->parent = ps2b;

		/*
		 * We must allocate this, since when the device was bound it did
		 * not have a parent.
		 */
		dev->parent_platdata = malloc(sizeof(*pplat));
		if (!dev->parent_platdata)
			return -ENOMEM;
	}
	pplat = dev_get_parent_platdata(dev);
	pplat->pid = portid;

	return 0;
}

static int p2sb_child_post_bind(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
	struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev);
	int ret;
	u32 pid;

	ret = dev_read_u32(dev, "intel,p2sb-port-id", &pid);
	if (ret)
		return ret;
	pplat->pid = pid;
#endif

	return 0;
}

static int p2sb_post_bind(struct udevice *dev)
{
	if (spl_phase() > PHASE_TPL && !CONFIG_IS_ENABLED(OF_PLATDATA))
		return dm_scan_fdt_dev(dev);

	return 0;
}

UCLASS_DRIVER(p2sb) = {
	.id		= UCLASS_P2SB,
	.name		= "p2sb",
	.per_device_auto_alloc_size = sizeof(struct p2sb_uc_priv),
	.post_bind	= p2sb_post_bind,
	.child_post_bind = p2sb_child_post_bind,
	.per_child_platdata_auto_alloc_size =
		sizeof(struct p2sb_child_platdata),
};
