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
|
||||
* and matches the PCI vendor and device ID.
|
||||
*
|
||||
* @param socket The socket where to search for the device.
|
||||
* @param vendor A PCI vendor ID (e.g. 0x8086 for Intel).
|
||||
* @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 *domain, *dev = NULL;
|
||||
union xeon_domain_path dn;
|
||||
return dev_find_all_devices_on_socket(socket, vendor, device, NULL);
|
||||
}
|
||||
|
||||
while ((dev = dev_find_device(vendor, device, dev))) {
|
||||
domain = dev_get_pci_domain(dev);
|
||||
static int filter_device_on_stack(struct device *dev, uint8_t socket, uint8_t stack,
|
||||
u16 vendor, u16 device)
|
||||
{
|
||||
struct device *domain = dev_get_pci_domain(dev);
|
||||
if (!domain)
|
||||
continue;
|
||||
return 0;
|
||||
if (dev->path.type != DEVICE_PATH_PCI)
|
||||
return 0;
|
||||
|
||||
union xeon_domain_path dn;
|
||||
dn.domain_path = domain->path.domain.domain;
|
||||
if (dn.socket != socket)
|
||||
|
||||
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;
|
||||
return dev;
|
||||
if (device != XEONSP_DEVICE_MAX && dev->device != device)
|
||||
continue;
|
||||
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,
|
||||
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_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_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_stack_from_dev(struct device *dev);
|
||||
|
||||
|
Reference in New Issue
Block a user