blob: 6040eacb594f42efd4a095b083466b7cc298b13d [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass70778bc2015-03-05 12:25:26 -07002/*
3 * Copyright (c) 2014 Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
Simon Glass70778bc2015-03-05 12:25:26 -07005 */
6
7/*
8 * IO space access commands.
9 */
10
Simon Glass70778bc2015-03-05 12:25:26 -070011#include <command.h>
12#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -060013#include <log.h>
Simon Glass70778bc2015-03-05 12:25:26 -070014#include <asm/io.h>
15
16int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
17 struct udevice **devp, void **ptrp)
18{
19 struct udevice *dev;
20 int ret;
21
22 *ptrp = 0;
23 for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
24 dev;
25 uclass_next_device(&dev)) {
26 struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
27
28 if (!ops || !ops->map_physmem)
29 continue;
30 ret = (ops->map_physmem)(dev, paddr, lenp, ptrp);
31 if (ret)
32 continue;
33 *devp = dev;
34 return 0;
35 }
36
Thierry Reding82222602019-03-12 11:38:02 +010037 debug("%s: failed: addr=%pap\n", __func__, &paddr);
Simon Glass70778bc2015-03-05 12:25:26 -070038 return -ENOSYS;
39}
40
41int pci_unmap_physmem(const void *vaddr, unsigned long len,
42 struct udevice *dev)
43{
44 struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
45
46 if (!ops || !ops->unmap_physmem)
47 return -ENOSYS;
48 return (ops->unmap_physmem)(dev, vaddr, len);
49}
50
51static int pci_io_read(unsigned int addr, ulong *valuep, pci_size_t size)
52{
53 struct udevice *dev;
54 int ret;
55
56 *valuep = pci_get_ff(size);
57 for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
58 dev;
59 uclass_next_device(&dev)) {
60 struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
61
62 if (ops && ops->read_io) {
63 ret = (ops->read_io)(dev, addr, valuep, size);
64 if (!ret)
65 return 0;
66 }
67 }
68
69 debug("%s: failed: addr=%x\n", __func__, addr);
70 return -ENOSYS;
71}
72
73static int pci_io_write(unsigned int addr, ulong value, pci_size_t size)
74{
75 struct udevice *dev;
76 int ret;
77
78 for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
79 dev;
80 uclass_next_device(&dev)) {
81 struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
82
83 if (ops && ops->write_io) {
84 ret = (ops->write_io)(dev, addr, value, size);
85 if (!ret)
86 return 0;
87 }
88 }
89
90 debug("%s: failed: addr=%x, value=%lx\n", __func__, addr, value);
91 return -ENOSYS;
92}
93
Simon Glassca6f1212019-09-25 08:56:02 -060094int _inl(unsigned int addr)
Simon Glass70778bc2015-03-05 12:25:26 -070095{
96 unsigned long value;
97 int ret;
98
99 ret = pci_io_read(addr, &value, PCI_SIZE_32);
100
101 return ret ? 0 : value;
102}
103
Simon Glassca6f1212019-09-25 08:56:02 -0600104int _inw(unsigned int addr)
Simon Glass70778bc2015-03-05 12:25:26 -0700105{
106 unsigned long value;
107 int ret;
108
109 ret = pci_io_read(addr, &value, PCI_SIZE_16);
110
111 return ret ? 0 : value;
112}
113
Simon Glassca6f1212019-09-25 08:56:02 -0600114int _inb(unsigned int addr)
Simon Glass70778bc2015-03-05 12:25:26 -0700115{
116 unsigned long value;
117 int ret;
118
119 ret = pci_io_read(addr, &value, PCI_SIZE_8);
120
121 return ret ? 0 : value;
122}
123
Simon Glassca6f1212019-09-25 08:56:02 -0600124void _outl(unsigned int value, unsigned int addr)
Simon Glass70778bc2015-03-05 12:25:26 -0700125{
126 pci_io_write(addr, value, PCI_SIZE_32);
127}
128
Simon Glassca6f1212019-09-25 08:56:02 -0600129void _outw(unsigned int value, unsigned int addr)
Simon Glass70778bc2015-03-05 12:25:26 -0700130{
131 pci_io_write(addr, value, PCI_SIZE_16);
132}
133
Simon Glassca6f1212019-09-25 08:56:02 -0600134void _outb(unsigned int value, unsigned int addr)
Simon Glass70778bc2015-03-05 12:25:26 -0700135{
136 pci_io_write(addr, value, PCI_SIZE_8);
137}