/*
 * Copyright (c) 2014 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 *
 * SPDX-License-Identifier:     GPL-2.0+
 */

/*
 * IO space access commands.
 */

#include <common.h>
#include <command.h>
#include <dm.h>
#include <asm/io.h>

int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
		    struct udevice **devp, void **ptrp)
{
	struct udevice *dev;
	int ret;

	*ptrp = 0;
	for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
	     dev;
	     uclass_next_device(&dev)) {
		struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);

		if (!ops || !ops->map_physmem)
			continue;
		ret = (ops->map_physmem)(dev, paddr, lenp, ptrp);
		if (ret)
			continue;
		*devp = dev;
		return 0;
	}

	debug("%s: failed: addr=%x\n", __func__, paddr);
	return -ENOSYS;
}

int pci_unmap_physmem(const void *vaddr, unsigned long len,
		      struct udevice *dev)
{
	struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);

	if (!ops || !ops->unmap_physmem)
		return -ENOSYS;
	return (ops->unmap_physmem)(dev, vaddr, len);
}

static int pci_io_read(unsigned int addr, ulong *valuep, pci_size_t size)
{
	struct udevice *dev;
	int ret;

	*valuep = pci_get_ff(size);
	for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
	     dev;
	     uclass_next_device(&dev)) {
		struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);

		if (ops && ops->read_io) {
			ret = (ops->read_io)(dev, addr, valuep, size);
			if (!ret)
				return 0;
		}
	}

	debug("%s: failed: addr=%x\n", __func__, addr);
	return -ENOSYS;
}

static int pci_io_write(unsigned int addr, ulong value, pci_size_t size)
{
	struct udevice *dev;
	int ret;

	for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
	     dev;
	     uclass_next_device(&dev)) {
		struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);

		if (ops && ops->write_io) {
			ret = (ops->write_io)(dev, addr, value, size);
			if (!ret)
				return 0;
		}
	}

	debug("%s: failed: addr=%x, value=%lx\n", __func__, addr, value);
	return -ENOSYS;
}

int inl(unsigned int addr)
{
	unsigned long value;
	int ret;

	ret = pci_io_read(addr, &value, PCI_SIZE_32);

	return ret ? 0 : value;
}

int inw(unsigned int addr)
{
	unsigned long value;
	int ret;

	ret = pci_io_read(addr, &value, PCI_SIZE_16);

	return ret ? 0 : value;
}

int inb(unsigned int addr)
{
	unsigned long value;
	int ret;

	ret = pci_io_read(addr, &value, PCI_SIZE_8);

	return ret ? 0 : value;
}

void outl(unsigned int value, unsigned int addr)
{
	pci_io_write(addr, value, PCI_SIZE_32);
}

void outw(unsigned int value, unsigned int addr)
{
	pci_io_write(addr, value, PCI_SIZE_16);
}

void outb(unsigned int value, unsigned int addr)
{
	pci_io_write(addr, value, PCI_SIZE_8);
}
