
Hi Simon,
On Tue, Nov 17, 2015 at 11:53 AM, Simon Glass sjg@chromium.org wrote:
At present the PCI address map functions use the old API. Add new functions for this so that drivers can be converted.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/pci/pci-uclass.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ include/pci.h | 59 ++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+)
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 4e37972..9c54e6c 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -11,6 +11,7 @@ #include <fdtdec.h> #include <inttypes.h> #include <pci.h> +#include <asm/io.h> #include <dm/lists.h> #include <dm/root.h> #include <dm/device-internal.h> @@ -1066,6 +1067,87 @@ u32 dm_pci_read_bar32(struct udevice *dev, int barnum) return addr & PCI_BASE_ADDRESS_MEM_MASK; }
+static int _dm_pci_hose_bus_to_phys(struct udevice *ctlr,
Why underscore? I understand this is an internal function, but we don't use underscore for many other internal function names. Also it takes udevice as the parameter, I think we should avoid using 'hose' in the function name.
pci_addr_t bus_addr, unsigned long flags,
unsigned long skip_mask, phys_addr_t *pa)
+{
struct pci_controller *hose = dev_get_uclass_priv(ctlr);
struct pci_region *res;
int i;
for (i = 0; i < hose->region_count; i++) {
res = &hose->regions[i];
if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
continue;
if (res->flags & skip_mask)
continue;
if (bus_addr >= res->bus_start &&
(bus_addr - res->bus_start) < res->size) {
*pa = (bus_addr - res->bus_start + res->phys_start);
return 0;
}
}
return 1;
+}
+phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t bus_addr,
unsigned long flags)
+{
phys_addr_t phys_addr = 0;
struct udevice *ctlr;
int ret;
/* The root controller has the region information */
ctlr = pci_get_controller(dev);
/*
* if PCI_REGION_MEM is set we do a two pass search with preference
* on matches that don't have PCI_REGION_SYS_MEMORY set
*/
if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) {
ret = _dm_pci_hose_bus_to_phys(ctlr, bus_addr,
flags, PCI_REGION_SYS_MEMORY,
&phys_addr);
if (!ret)
return phys_addr;
}
ret = _dm_pci_hose_bus_to_phys(ctlr, bus_addr, flags, 0, &phys_addr);
if (ret)
puts("pci_hose_bus_to_phys: invalid physical address\n");
return phys_addr;
+}
+pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr,
unsigned long flags)
+{
return 0;
Why returning 0? This looks wrong to me as every physical address will be mapped to pci address zero?
+}
+void *dm_pci_map_bar(struct udevice *dev, int bar, int flags) +{
pci_addr_t pci_bus_addr;
u32 bar_response;
/* read BAR address */
dm_pci_read_config32(dev, bar, &bar_response);
pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
/*
* Pass "0" as the length argument to pci_bus_to_virt. The arg
* isn't actualy used on any platform because u-boot assumes a static
* linear mapping. In the future, this could read the BAR size
* and pass that as the size if needed.
*/
return dm_pci_bus_to_virt(dev, pci_bus_addr, flags, 0, MAP_NOCACHE);
+}
UCLASS_DRIVER(pci) = { .id = UCLASS_PCI, .name = "pci", diff --git a/include/pci.h b/include/pci.h index f1c0d71..ddf6b66 100644 --- a/include/pci.h +++ b/include/pci.h @@ -1183,6 +1183,65 @@ void dm_pciauto_region_init(struct pci_region *res); u32 dm_pci_read_bar32(struct udevice *dev, int barnum);
/**
- dm_pci_bus_to_phys() - convert a PCI bus address to a physical address
- @dev: Device containing the PCI address
- @addr: PCI address to convert
- @flags: Flags for the region type (PCI_REGION_...)
- @return physical address corresponding to that PCI bus address
- */
+phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t addr,
unsigned long flags);
+/**
- dm_pci_phys_to_bus() - convert a physical address to a PCI bus address
- @dev: Device containing the bus address
- @addr: Physical address to convert
- @flags: Flags for the region type (PCI_REGION_...)
- @return PCI bus address corresponding to that physical address
- */
+pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr,
unsigned long flags);
+/**
- dm_pci_map_bar() - get a physical address associated with a BAR region
- Looks up a base address register and finds the physical memory address
- that corresponds to it
- @dev: Device to check
- @bar: Bar number to read (numbered from 0)
- @flags: Flags for the region type (PCI_REGION_...)
- @return: pointer to the physical address to use
- */
+void *dm_pci_map_bar(struct udevice *dev, int bar, int flags);
+#define dm_pci_virt_to_bus(dev, addr, flags) \
dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
+#define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \
map_physmem(dm_pci_bus_to_phys(dev, (addr), (flags)), \
(len), (map_flags))
+#define dm_pci_phys_to_mem(dev, addr) \
dm_pci_phys_to_bus((dev), (addr), PCI_REGION_MEM)
+#define dm_pci_mem_to_phys(dev, addr) \
dm_pci_bus_to_phys((dev), (addr), PCI_REGION_MEM)
+#define dm_pci_phys_to_io(dev, addr) \
dm_pci_phys_to_bus((dev), (addr), PCI_REGION_IO)
+#define dm_pci_io_to_phys(dev, addr) \
dm_pci_bus_to_phys((dev), (addr), PCI_REGION_IO)
+#define dm_pci_virt_to_mem(dev, addr) \
dm_pci_virt_to_bus((dev), (addr), PCI_REGION_MEM)
+#define dm_pci_mem_to_virt(dev, addr, len, map_flags) \
dm_pci_bus_to_virt((dev), (addr), PCI_REGION_MEM, (len), (map_flags))
+#define dm_pci_virt_to_io(dev, addr) \
dm_dm_pci_virt_to_bus((dev), (addr), PCI_REGION_IO)
+#define dm_pci_io_to_virt(dev, addr, len, map_flags) \
dm_dm_pci_bus_to_virt((dev), (addr), PCI_REGION_IO, (len), (map_flags))
+/**
- dm_pci_find_device() - find a device by vendor/device ID
- @vendor: Vendor ID
--
Regards, Bin