pci@1,0 {
compatible = "pci-generic";
/* reg 0 is at 0x14, using FDT_PCI_SPACE_MEM32 */
- reg = <0x02000814 0 0 0 0
- 0x01000810 0 0 0 0>;
+ reg = <0x02000814 0 0 0x80 0
+ 0x01000810 0 0 0xc0 0>;
sandbox,emul = <&swap_case_emul0_1>;
};
p2sb-pci@2,0 {
pci@1f,0 {
compatible = "pci-generic";
/* reg 0 is at 0x10, using FDT_PCI_SPACE_IO */
- reg = <0x0100f810 0 0 0 0>;
+ reg = <0x0100f810 0 0 0x100 0>;
sandbox,emul = <&swap_case_emul0_1f>;
};
};
return map_physmem(addr, size, MAP_NOCACHE);
}
-fdt_addr_t devfdt_get_addr_pci(const struct udevice *dev)
+fdt_addr_t devfdt_get_addr_pci(const struct udevice *dev, fdt_size_t *sizep)
{
ulong addr;
int ret;
ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_MEM32,
- "reg", &pci_addr);
+ "reg", &pci_addr, sizep);
if (ret) {
/* try if there is any i/o-mapped register */
ret = ofnode_read_pci_addr(dev_ofnode(dev),
FDT_PCI_SPACE_IO, "reg",
- &pci_addr);
+ &pci_addr, sizep);
if (ret)
return FDT_ADDR_T_NONE;
}
}
int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
- const char *propname, struct fdt_pci_addr *addr)
+ const char *propname, struct fdt_pci_addr *addr,
+ fdt_size_t *size)
{
const fdt32_t *cell;
int len;
(ulong)fdt32_to_cpu(cell[1]),
(ulong)fdt32_to_cpu(cell[2]));
if ((fdt32_to_cpu(*cell) & type) == type) {
+ const unaligned_fdt64_t *ptr;
+
addr->phys_hi = fdt32_to_cpu(cell[0]);
addr->phys_mid = fdt32_to_cpu(cell[1]);
addr->phys_lo = fdt32_to_cpu(cell[2]);
+ ptr = (const unaligned_fdt64_t *)(cell + 3);
+ if (size)
+ *size = fdt64_to_cpu(*ptr);
break;
}
- cell += (FDT_PCI_ADDR_CELLS +
- FDT_PCI_SIZE_CELLS);
+ cell += FDT_PCI_ADDR_CELLS + FDT_PCI_SIZE_CELLS;
}
if (i == num) {
return fdtdec_get_alias_highest_id(gd->fdt_blob, stem);
}
-fdt_addr_t dev_read_addr_pci(const struct udevice *dev)
+fdt_addr_t dev_read_addr_pci(const struct udevice *dev, fdt_size_t *sizep)
{
ulong addr;
addr = dev_read_addr(dev);
+ if (sizep)
+ *sizep = 0;
if (addr == FDT_ADDR_T_NONE && !of_live_active())
- addr = devfdt_get_addr_pci(dev);
+ addr = devfdt_get_addr_pci(dev, sizep);
return addr;
}
/* Extract the devfn from fdt_pci_addr */
ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG,
- "reg", &addr);
+ "reg", &addr, NULL);
if (ret) {
if (ret != -ENOENT)
return -EINVAL;
dev_for_each_subnode(node, bus) {
ret = ofnode_read_pci_addr(node, FDT_PCI_SPACE_CONFIG, "reg",
- &addr);
+ &addr, NULL);
if (ret)
continue;
pcie->is_x4 = true;
/* devfn is in bits [15:8], see PCI_DEV usage */
- ret = ofnode_read_pci_addr(node, FDT_PCI_SPACE_CONFIG, "reg", &pci_addr);
+ ret = ofnode_read_pci_addr(node, FDT_PCI_SPACE_CONFIG, "reg", &pci_addr,
+ NULL);
if (ret < 0) {
printf("%s: property \"reg\" is invalid\n", pcie->name);
goto err;
*lanes = err;
- err = ofnode_read_pci_addr(node, 0, "reg", &addr);
+ err = ofnode_read_pci_addr(node, 0, "reg", &addr, NULL);
if (err < 0) {
pr_err("failed to parse \"reg\" property\n");
return err;
if (!ofnode_is_enabled(subnode))
continue;
- err = ofnode_read_pci_addr(subnode, 0, "reg", &addr);
+ err = ofnode_read_pci_addr(subnode, 0, "reg", &addr, NULL);
if (err)
return err;
if (!ofnode_is_enabled(subnode))
continue;
- err = ofnode_read_pci_addr(subnode, 0, "reg", &addr);
+ err = ofnode_read_pci_addr(subnode, 0, "reg", &addr, NULL);
if (err)
return err;
info->addr_space = SERIAL_ADDRESS_SPACE_MEMORY;
#endif
info->addr = plat->base;
+ info->size = plat->size;
info->reg_width = plat->reg_width;
info->reg_shift = plat->reg_shift;
info->reg_offset = plat->reg_offset;
return 0;
}
-static int ns16550_serial_assign_base(struct ns16550_plat *plat, fdt_addr_t base)
+static int ns16550_serial_assign_base(struct ns16550_plat *plat,
+ fdt_addr_t base, fdt_size_t size)
{
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
#else
plat->base = (unsigned long)map_physmem(base, 0, MAP_NOCACHE);
#endif
+ plat->size = size;
return 0;
}
struct ns16550 *const com_port = dev_get_priv(dev);
struct reset_ctl_bulk reset_bulk;
fdt_addr_t addr;
+ fdt_addr_t size;
int ret;
/*
* or via a PCI bridge, assign plat->base before probing hardware.
*/
if (device_is_on_pci_bus(dev)) {
- addr = devfdt_get_addr_pci(dev);
- ret = ns16550_serial_assign_base(plat, addr);
+ addr = devfdt_get_addr_pci(dev, &size);
+ ret = ns16550_serial_assign_base(plat, addr, size);
if (ret)
return ret;
}
{
struct ns16550_plat *plat = dev_get_plat(dev);
const u32 port_type = dev_get_driver_data(dev);
+ fdt_size_t size = 0;
fdt_addr_t addr;
struct clk clk;
int err;
- addr = dev_read_addr(dev);
- err = ns16550_serial_assign_base(plat, addr);
+ addr = spl_in_proper() ? dev_read_addr_size(dev, &size) :
+ dev_read_addr(dev);
+ err = ns16550_serial_assign_base(plat, addr, size);
if (err && !device_is_on_pci_bus(dev))
return err;
* devfdt_get_addr_pci() - Read an address and handle PCI address translation
*
* @dev: Device to read from
+ * @sizep: If non-NULL, returns size of address space
* Return: address or FDT_ADDR_T_NONE if not found
*/
-fdt_addr_t devfdt_get_addr_pci(const struct udevice *dev);
+fdt_addr_t devfdt_get_addr_pci(const struct udevice *dev, fdt_size_t *sizep);
#endif
* @type: pci address type (FDT_PCI_SPACE_xxx)
* @propname: name of property to find
* @addr: returns pci address in the form of fdt_pci_addr
+ * @size: if non-null, returns register-space size
* Return:
* 0 if ok, -ENOENT if the property did not exist, -EINVAL if the
* format of the property was invalid, -ENXIO if the requested
* address type was not found
*/
int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
- const char *propname, struct fdt_pci_addr *addr);
+ const char *propname, struct fdt_pci_addr *addr,
+ fdt_size_t *size);
/**
* ofnode_read_pci_vendev() - look up PCI vendor and device id
* fdtdec_get_addr() and friends.
*
* @dev: Device to read from
+ * @sizep: If non-NULL, returns size of address space found
* Return: address or FDT_ADDR_T_NONE if not found
*/
-fdt_addr_t dev_read_addr_pci(const struct udevice *dev);
+fdt_addr_t dev_read_addr_pci(const struct udevice *dev, fdt_size_t *sizep);
/**
* dev_remap_addr() - Get the reg property of a device as a
return devfdt_get_addr_ptr(dev);
}
-static inline fdt_addr_t dev_read_addr_pci(const struct udevice *dev)
+static inline fdt_addr_t dev_read_addr_pci(const struct udevice *dev,
+ fdt_size_t *sizep)
{
- return devfdt_get_addr_pci(dev);
+ return devfdt_get_addr_pci(dev, sizep);
}
static inline void *dev_remap_addr(const struct udevice *dev)
* struct ns16550_plat - information about a NS16550 port
*
* @base: Base register address
+ * @size: Size of register area in bytes
* @reg_width: IO accesses size of registers (in bytes, 1 or 4)
* @reg_shift: Shift size of registers (0=byte, 1=16bit, 2=32bit...)
* @reg_offset: Offset to start of registers (normally 0)
* @bdf: PCI slot/function (pci_dev_t)
*/
struct ns16550_plat {
- unsigned long base;
+ ulong base;
+ ulong size;
int reg_width;
int reg_shift;
int reg_offset;
* @type: type of the UART chip
* @addr_space: address space to access the registers
* @addr: physical address of the registers
+ * @size: size of the register area in bytes
* @reg_width: size (in bytes) of the IO accesses to the registers
* @reg_offset: offset to apply to the @addr from the start of the registers
* @reg_shift: quantity to shift the register offsets by
enum serial_chip_type type;
enum adr_space_type addr_space;
ulong addr;
+ ulong size;
u8 reg_width;
u8 reg_offset;
u8 reg_shift;
{
struct udevice *swap1f, *swap1;
ulong io_addr, mem_addr;
+ fdt_addr_t size;
ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap1f));
io_addr = dm_pci_read_bar32(swap1f, 0);
- ut_asserteq(io_addr, dev_read_addr_pci(swap1f));
+ ut_asserteq(io_addr, dev_read_addr_pci(swap1f, &size));
+ ut_asserteq(0, size);
/*
* This device has both I/O and MEM spaces but the MEM space appears
*/
ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1, 0), &swap1));
mem_addr = dm_pci_read_bar32(swap1, 1);
- ut_asserteq(mem_addr, dev_read_addr_pci(swap1));
+ ut_asserteq(mem_addr, dev_read_addr_pci(swap1, &size));
+ ut_asserteq(0, size);
return 0;
}
static int dm_test_pci_addr_live(struct unit_test_state *uts)
{
struct udevice *swap1f, *swap1;
+ fdt_size_t size;
ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap1f));
- ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr_pci(swap1f));
+ ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr_pci(swap1f, &size));
+ ut_asserteq(0, size);
ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1, 0), &swap1));
- ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr_pci(swap1));
+ ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr_pci(swap1, &size));
+ ut_asserteq(0, size);
return 0;
}