1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
29569c406SSimon Glass /*
39569c406SSimon Glass * Copyright (c) 2014 Google, Inc
49569c406SSimon Glass * Written by Simon Glass <sjg@chromium.org>
59569c406SSimon Glass */
69569c406SSimon Glass
79569c406SSimon Glass /*
89569c406SSimon Glass * IO space access commands.
99569c406SSimon Glass */
109569c406SSimon Glass
119569c406SSimon Glass #include <common.h>
129569c406SSimon Glass #include <command.h>
139569c406SSimon Glass #include <dm.h>
149569c406SSimon Glass #include <asm/io.h>
159569c406SSimon Glass
pci_map_physmem(phys_addr_t paddr,unsigned long * lenp,struct udevice ** devp,void ** ptrp)169569c406SSimon Glass int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
179569c406SSimon Glass struct udevice **devp, void **ptrp)
189569c406SSimon Glass {
199569c406SSimon Glass struct udevice *dev;
209569c406SSimon Glass int ret;
219569c406SSimon Glass
229569c406SSimon Glass *ptrp = 0;
239569c406SSimon Glass for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
249569c406SSimon Glass dev;
259569c406SSimon Glass uclass_next_device(&dev)) {
269569c406SSimon Glass struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
279569c406SSimon Glass
289569c406SSimon Glass if (!ops || !ops->map_physmem)
299569c406SSimon Glass continue;
309569c406SSimon Glass ret = (ops->map_physmem)(dev, paddr, lenp, ptrp);
319569c406SSimon Glass if (ret)
329569c406SSimon Glass continue;
339569c406SSimon Glass *devp = dev;
349569c406SSimon Glass return 0;
359569c406SSimon Glass }
369569c406SSimon Glass
379569c406SSimon Glass debug("%s: failed: addr=%x\n", __func__, paddr);
389569c406SSimon Glass return -ENOSYS;
399569c406SSimon Glass }
409569c406SSimon Glass
pci_unmap_physmem(const void * vaddr,unsigned long len,struct udevice * dev)419569c406SSimon Glass int pci_unmap_physmem(const void *vaddr, unsigned long len,
429569c406SSimon Glass struct udevice *dev)
439569c406SSimon Glass {
449569c406SSimon Glass struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
459569c406SSimon Glass
469569c406SSimon Glass if (!ops || !ops->unmap_physmem)
479569c406SSimon Glass return -ENOSYS;
489569c406SSimon Glass return (ops->unmap_physmem)(dev, vaddr, len);
499569c406SSimon Glass }
509569c406SSimon Glass
pci_io_read(unsigned int addr,ulong * valuep,pci_size_t size)519569c406SSimon Glass static int pci_io_read(unsigned int addr, ulong *valuep, pci_size_t size)
529569c406SSimon Glass {
539569c406SSimon Glass struct udevice *dev;
549569c406SSimon Glass int ret;
559569c406SSimon Glass
569569c406SSimon Glass *valuep = pci_get_ff(size);
579569c406SSimon Glass for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
589569c406SSimon Glass dev;
599569c406SSimon Glass uclass_next_device(&dev)) {
609569c406SSimon Glass struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
619569c406SSimon Glass
629569c406SSimon Glass if (ops && ops->read_io) {
639569c406SSimon Glass ret = (ops->read_io)(dev, addr, valuep, size);
649569c406SSimon Glass if (!ret)
659569c406SSimon Glass return 0;
669569c406SSimon Glass }
679569c406SSimon Glass }
689569c406SSimon Glass
699569c406SSimon Glass debug("%s: failed: addr=%x\n", __func__, addr);
709569c406SSimon Glass return -ENOSYS;
719569c406SSimon Glass }
729569c406SSimon Glass
pci_io_write(unsigned int addr,ulong value,pci_size_t size)739569c406SSimon Glass static int pci_io_write(unsigned int addr, ulong value, pci_size_t size)
749569c406SSimon Glass {
759569c406SSimon Glass struct udevice *dev;
769569c406SSimon Glass int ret;
779569c406SSimon Glass
789569c406SSimon Glass for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
799569c406SSimon Glass dev;
809569c406SSimon Glass uclass_next_device(&dev)) {
819569c406SSimon Glass struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
829569c406SSimon Glass
839569c406SSimon Glass if (ops && ops->write_io) {
849569c406SSimon Glass ret = (ops->write_io)(dev, addr, value, size);
859569c406SSimon Glass if (!ret)
869569c406SSimon Glass return 0;
879569c406SSimon Glass }
889569c406SSimon Glass }
899569c406SSimon Glass
909569c406SSimon Glass debug("%s: failed: addr=%x, value=%lx\n", __func__, addr, value);
919569c406SSimon Glass return -ENOSYS;
929569c406SSimon Glass }
939569c406SSimon Glass
inl(unsigned int addr)949569c406SSimon Glass int inl(unsigned int addr)
959569c406SSimon Glass {
969569c406SSimon Glass unsigned long value;
979569c406SSimon Glass int ret;
989569c406SSimon Glass
999569c406SSimon Glass ret = pci_io_read(addr, &value, PCI_SIZE_32);
1009569c406SSimon Glass
1019569c406SSimon Glass return ret ? 0 : value;
1029569c406SSimon Glass }
1039569c406SSimon Glass
inw(unsigned int addr)1049569c406SSimon Glass int inw(unsigned int addr)
1059569c406SSimon Glass {
1069569c406SSimon Glass unsigned long value;
1079569c406SSimon Glass int ret;
1089569c406SSimon Glass
1099569c406SSimon Glass ret = pci_io_read(addr, &value, PCI_SIZE_16);
1109569c406SSimon Glass
1119569c406SSimon Glass return ret ? 0 : value;
1129569c406SSimon Glass }
1139569c406SSimon Glass
inb(unsigned int addr)1149569c406SSimon Glass int inb(unsigned int addr)
1159569c406SSimon Glass {
1169569c406SSimon Glass unsigned long value;
1179569c406SSimon Glass int ret;
1189569c406SSimon Glass
1199569c406SSimon Glass ret = pci_io_read(addr, &value, PCI_SIZE_8);
1209569c406SSimon Glass
1219569c406SSimon Glass return ret ? 0 : value;
1229569c406SSimon Glass }
1239569c406SSimon Glass
outl(unsigned int value,unsigned int addr)1249569c406SSimon Glass void outl(unsigned int value, unsigned int addr)
1259569c406SSimon Glass {
1269569c406SSimon Glass pci_io_write(addr, value, PCI_SIZE_32);
1279569c406SSimon Glass }
1289569c406SSimon Glass
outw(unsigned int value,unsigned int addr)1299569c406SSimon Glass void outw(unsigned int value, unsigned int addr)
1309569c406SSimon Glass {
1319569c406SSimon Glass pci_io_write(addr, value, PCI_SIZE_16);
1329569c406SSimon Glass }
1339569c406SSimon Glass
outb(unsigned int value,unsigned int addr)1349569c406SSimon Glass void outb(unsigned int value, unsigned int addr)
1359569c406SSimon Glass {
1369569c406SSimon Glass pci_io_write(addr, value, PCI_SIZE_8);
1379569c406SSimon Glass }
138