// 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 <mapmem.h>
#include <p2sb.h>
#include <spl.h>
#include <asm/io.h>
#include <dm/uclass-internal.h>

#define PCR_COMMON_IOSF_1_0	1

static 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;

	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.
	 * TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc
	 */
	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),
};
