soc/intel/xeon_sp: Add device find utils
For Xeon-SP, it's common pattern to find devices under specific socket, stack and domain. This patch adds util function for these operations. TEST=intel/archercity CRB Change-Id: I163eacae363334919fd66d571b7e0415e77bd52d Signed-off-by: Shuo Liu <shuo.liu@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/81043 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
This commit is contained in:
@ -25,31 +25,115 @@ static const STACK_RES *domain_to_stack_res(const struct device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a device of a given vendor and type for the specified socket.
|
* Find all device of a given vendor and type for the specified socket.
|
||||||
* The function iterates over all PCI domains of the specified socket
|
* The function iterates over all PCI domains of the specified socket
|
||||||
* and matches the PCI vendor and device ID.
|
* and matches the PCI vendor and device ID.
|
||||||
*
|
*
|
||||||
* @param socket The socket where to search for the device.
|
* @param socket The socket where to search for the device.
|
||||||
* @param vendor A PCI vendor ID (e.g. 0x8086 for Intel).
|
* @param vendor A PCI vendor ID (e.g. 0x8086 for Intel).
|
||||||
* @param device A PCI device ID.
|
* @param device A PCI device ID.
|
||||||
* @return Pointer to the device struct.
|
* @param from The device pointer to start search from.
|
||||||
|
*
|
||||||
|
* @return Pointer to the device struct. When there are multiple device
|
||||||
|
* instances, the caller should continue search upon a non-NULL match.
|
||||||
|
*/
|
||||||
|
struct device *dev_find_all_devices_on_socket(uint8_t socket, u16 vendor, u16 device,
|
||||||
|
struct device *from)
|
||||||
|
{
|
||||||
|
return dev_find_all_devices_on_stack(socket, XEONSP_STACK_MAX, vendor, device, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find device of a given vendor and type for the specified socket.
|
||||||
|
* The function will return at the 1st match.
|
||||||
*/
|
*/
|
||||||
struct device *dev_find_device_on_socket(uint8_t socket, u16 vendor, u16 device)
|
struct device *dev_find_device_on_socket(uint8_t socket, u16 vendor, u16 device)
|
||||||
{
|
{
|
||||||
struct device *domain, *dev = NULL;
|
return dev_find_all_devices_on_socket(socket, vendor, device, NULL);
|
||||||
union xeon_domain_path dn;
|
}
|
||||||
|
|
||||||
while ((dev = dev_find_device(vendor, device, dev))) {
|
static int filter_device_on_stack(struct device *dev, uint8_t socket, uint8_t stack,
|
||||||
domain = dev_get_pci_domain(dev);
|
u16 vendor, u16 device)
|
||||||
if (!domain)
|
{
|
||||||
|
struct device *domain = dev_get_pci_domain(dev);
|
||||||
|
if (!domain)
|
||||||
|
return 0;
|
||||||
|
if (dev->path.type != DEVICE_PATH_PCI)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
union xeon_domain_path dn;
|
||||||
|
dn.domain_path = domain->path.domain.domain;
|
||||||
|
|
||||||
|
if (socket != XEONSP_SOCKET_MAX && dn.socket != socket)
|
||||||
|
return 0;
|
||||||
|
if (stack != XEONSP_STACK_MAX && dn.stack != stack)
|
||||||
|
return 0;
|
||||||
|
if (vendor != XEONSP_VENDOR_MAX && dev->vendor != vendor)
|
||||||
|
return 0;
|
||||||
|
if (device != XEONSP_DEVICE_MAX && dev->device != device)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all device of a given vendor and type for the specified socket and stack.
|
||||||
|
*
|
||||||
|
* @param socket The socket where to search for the device.
|
||||||
|
* XEONSP_SOCKET_MAX indicates any socket.
|
||||||
|
* @param stack The stack where to search for the device.
|
||||||
|
* XEONSP_STACK_MAX indicates any stack.
|
||||||
|
* @param vendor A PCI vendor ID (e.g. 0x8086 for Intel).
|
||||||
|
* XEONSP_VENDOR_MAX indicates any vendor.
|
||||||
|
* @param device A PCI device ID.
|
||||||
|
* XEONSP_DEVICE_MAX indicates any device.
|
||||||
|
* @param from The device pointer to start search from.
|
||||||
|
*
|
||||||
|
* @return Pointer to the device struct. When there are multiple device
|
||||||
|
* instances, the caller should continue search upon a non-NULL match.
|
||||||
|
*/
|
||||||
|
struct device *dev_find_all_devices_on_stack(uint8_t socket, uint8_t stack,
|
||||||
|
u16 vendor, u16 device, struct device *from)
|
||||||
|
{
|
||||||
|
if (!from)
|
||||||
|
from = all_devices;
|
||||||
|
else
|
||||||
|
from = from->next;
|
||||||
|
|
||||||
|
while (from && (!filter_device_on_stack(from, socket, stack,
|
||||||
|
vendor, device)))
|
||||||
|
from = from->next;
|
||||||
|
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all device of a given vendor and type for the specific domain
|
||||||
|
* Only the direct child of the input domain is iterated
|
||||||
|
*
|
||||||
|
* @param domain Pointer to the input domain
|
||||||
|
* @param vendor A PCI vendor ID
|
||||||
|
* XEONSP_VENDOR_MAX indicates any vendor
|
||||||
|
* @param vendor A PCI device ID
|
||||||
|
* XEONSP_DEVICE_MAX indicates any vendor
|
||||||
|
* @param from The device pointer to start search from.
|
||||||
|
*
|
||||||
|
* @return Pointer to the device struct. When there are multiple device
|
||||||
|
* instances, the caller should continue search upon a non-NULL match.
|
||||||
|
*/
|
||||||
|
struct device *dev_find_all_devices_on_domain(struct device *domain, u16 vendor,
|
||||||
|
u16 device, struct device *from)
|
||||||
|
{
|
||||||
|
struct device *dev = from;
|
||||||
|
while ((dev = dev_bus_each_child(domain->downstream, dev))) {
|
||||||
|
if (vendor != XEONSP_VENDOR_MAX && dev->vendor != vendor)
|
||||||
continue;
|
continue;
|
||||||
dn.domain_path = domain->path.domain.domain;
|
if (device != XEONSP_DEVICE_MAX && dev->device != device)
|
||||||
if (dn.socket != socket)
|
|
||||||
continue;
|
continue;
|
||||||
return dev;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +16,10 @@ union xeon_domain_path {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define XEONSP_STACK_MAX UINT8_MAX
|
||||||
|
#define XEONSP_SOCKET_MAX UINT8_MAX
|
||||||
|
#define XEONSP_DEVICE_MAX UINT16_MAX
|
||||||
|
#define XEONSP_VENDOR_MAX UINT16_MAX
|
||||||
|
|
||||||
static inline void init_xeon_domain_path(struct device_path *path, int socket,
|
static inline void init_xeon_domain_path(struct device_path *path, int socket,
|
||||||
int stack, int bus)
|
int stack, int bus)
|
||||||
@ -50,7 +54,15 @@ void attach_iio_stacks(void);
|
|||||||
|
|
||||||
void soc_create_ioat_domains(union xeon_domain_path path, struct bus *bus, const STACK_RES *sr);
|
void soc_create_ioat_domains(union xeon_domain_path path, struct bus *bus, const STACK_RES *sr);
|
||||||
void soc_create_cxl_domains(const union xeon_domain_path dp, struct bus *bus, const STACK_RES *sr);
|
void soc_create_cxl_domains(const union xeon_domain_path dp, struct bus *bus, const STACK_RES *sr);
|
||||||
|
|
||||||
struct device *dev_find_device_on_socket(uint8_t socket, u16 vendor, u16 device);
|
struct device *dev_find_device_on_socket(uint8_t socket, u16 vendor, u16 device);
|
||||||
|
struct device *dev_find_all_devices_on_socket(uint8_t socket,
|
||||||
|
u16 vendor, u16 device, struct device *from);
|
||||||
|
struct device *dev_find_all_devices_on_stack(uint8_t socket, uint8_t stack,
|
||||||
|
u16 vendor, u16 device, struct device *from);
|
||||||
|
struct device *dev_find_all_devices_on_domain(struct device *domain,
|
||||||
|
u16 vendor, u16 device, struct device *from);
|
||||||
|
|
||||||
int iio_pci_domain_socket_from_dev(struct device *dev);
|
int iio_pci_domain_socket_from_dev(struct device *dev);
|
||||||
int iio_pci_domain_stack_from_dev(struct device *dev);
|
int iio_pci_domain_stack_from_dev(struct device *dev);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user