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

	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),
};
