Commit 2959ab24 authored by Nipun Gupta's avatar Nipun Gupta Committed by Greg Kroah-Hartman

cdx: add the cdx bus driver

Introduce AMD CDX bus, which provides a mechanism for scanning
and probing CDX devices. These devices are memory mapped on
system bus for Application Processors(APUs).

CDX devices can be changed dynamically in the Fabric and CDX
bus interacts with CDX controller to rescan the bus and
rediscover the devices.
Signed-off-by: default avatarNipun Gupta <nipun.gupta@amd.com>
Reviewed-by: default avatarPieter Jansen van Vuuren <pieter.jansen-van-vuuren@amd.com>
Tested-by: default avatarNikhil Agarwal <nikhil.agarwal@amd.com>
Link: https://lore.kernel.org/r/20230313132636.31850-2-nipun.gupta@amd.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 71d74aaa
What: /sys/bus/cdx/rescan
Date: March 2023
Contact: nipun.gupta@amd.com
Description:
Writing y/1/on to this file will cause rescan of the bus
and devices on the CDX bus. Any new devices are scanned and
added to the list of Linux devices and any devices removed are
also deleted from Linux.
For example::
# echo 1 > /sys/bus/cdx/rescan
......@@ -964,6 +964,13 @@ Q: https://patchwork.kernel.org/project/linux-rdma/list/
F: drivers/infiniband/hw/efa/
F: include/uapi/rdma/efa-abi.h
AMD CDX BUS DRIVER
M: Nipun Gupta <nipun.gupta@amd.com>
M: Nikhil Agarwal <nikhil.agarwal@amd.com>
S: Maintained
F: drivers/cdx/*
F: include/linux/cdx/*
AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER
M: Tom Lendacky <thomas.lendacky@amd.com>
M: John Allen <john.allen@amd.com>
......
......@@ -241,4 +241,6 @@ source "drivers/peci/Kconfig"
source "drivers/hte/Kconfig"
source "drivers/cdx/Kconfig"
endmenu
......@@ -194,3 +194,4 @@ obj-$(CONFIG_MOST) += most/
obj-$(CONFIG_PECI) += peci/
obj-$(CONFIG_HTE) += hte/
obj-$(CONFIG_DRM_ACCEL) += accel/
obj-$(CONFIG_CDX_BUS) += cdx/
# SPDX-License-Identifier: GPL-2.0
#
# CDX bus configuration
#
# Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
#
config CDX_BUS
bool "CDX Bus driver"
depends on OF && ARM64
help
Driver to enable Composable DMA Transfer(CDX) Bus. CDX bus
exposes Fabric devices which uses composable DMA IP to the
APU. CDX bus provides a mechanism for scanning and probing
of CDX devices. CDX devices are memory mapped on system bus
for embedded CPUs. CDX bus uses CDX controller and firmware
to scan these CDX devices.
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for CDX
#
# Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
#
obj-$(CONFIG_CDX_BUS) += cdx.o
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0
*
* Header file for the CDX Bus
*
* Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
*/
#ifndef _CDX_H_
#define _CDX_H_
#include <linux/cdx/cdx_bus.h>
/**
* struct cdx_dev_params - CDX device parameters
* @cdx: CDX controller associated with the device
* @parent: Associated CDX controller
* @vendor: Vendor ID for CDX device
* @device: Device ID for CDX device
* @bus_num: Bus number for this CDX device
* @dev_num: Device number for this device
* @res: array of MMIO region entries
* @res_count: number of valid MMIO regions
* @req_id: Requestor ID associated with CDX device
*/
struct cdx_dev_params {
struct cdx_controller *cdx;
u16 vendor;
u16 device;
u8 bus_num;
u8 dev_num;
struct resource res[MAX_CDX_DEV_RESOURCES];
u8 res_count;
u32 req_id;
};
/**
* cdx_register_controller - Register a CDX controller and its ports
* on the CDX bus.
* @cdx: The CDX controller to register
*
* Return: -errno on failure, 0 on success.
*/
int cdx_register_controller(struct cdx_controller *cdx);
/**
* cdx_unregister_controller - Unregister a CDX controller
* @cdx: The CDX controller to unregister
*/
void cdx_unregister_controller(struct cdx_controller *cdx);
/**
* cdx_device_add - Add a CDX device. This function adds a CDX device
* on the CDX bus as per the device parameters provided
* by caller. It also creates and registers an associated
* Linux generic device.
* @dev_params: device parameters associated with the device to be created.
*
* Return: -errno on failure, 0 on success.
*/
int cdx_device_add(struct cdx_dev_params *dev_params);
#endif /* _CDX_H_ */
/* SPDX-License-Identifier: GPL-2.0
*
* CDX bus public interface
*
* Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
*
*/
#ifndef _CDX_BUS_H_
#define _CDX_BUS_H_
#include <linux/device.h>
#include <linux/list.h>
#include <linux/mod_devicetable.h>
#define MAX_CDX_DEV_RESOURCES 4
#define CDX_ANY_ID (0xFFFF)
#define CDX_CONTROLLER_ID_SHIFT 4
#define CDX_BUS_NUM_MASK 0xF
/* Forward declaration for CDX controller */
struct cdx_controller;
typedef int (*cdx_scan_cb)(struct cdx_controller *cdx);
/**
* CDX_DEVICE_DRIVER_OVERRIDE - macro used to describe a CDX device with
* override_only flags.
* @vend: the 16 bit CDX Vendor ID
* @dev: the 16 bit CDX Device ID
* @driver_override: the 32 bit CDX Device override_only
*
* This macro is used to create a struct cdx_device_id that matches only a
* driver_override device.
*/
#define CDX_DEVICE_DRIVER_OVERRIDE(vend, dev, driver_override) \
.vendor = (vend), .device = (dev), .override_only = (driver_override)
/**
* struct cdx_ops - Callbacks supported by CDX controller.
* @scan: scan the devices on the controller
*/
struct cdx_ops {
cdx_scan_cb scan;
};
/**
* struct cdx_controller: CDX controller object
* @dev: Linux device associated with the CDX controller.
* @priv: private data
* @id: Controller ID
* @ops: CDX controller ops
*/
struct cdx_controller {
struct device *dev;
void *priv;
u32 id;
struct cdx_ops *ops;
};
/**
* struct cdx_device - CDX device object
* @dev: Linux driver model device object
* @cdx: CDX controller associated with the device
* @vendor: Vendor ID for CDX device
* @device: Device ID for CDX device
* @bus_num: Bus number for this CDX device
* @dev_num: Device number for this device
* @res: array of MMIO region entries
* @res_attr: resource binary attribute
* @res_count: number of valid MMIO regions
* @dma_mask: Default DMA mask
* @flags: CDX device flags
* @req_id: Requestor ID associated with CDX device
* @driver_override: driver name to force a match; do not set directly,
* because core frees it; use driver_set_override() to
* set or clear it.
*/
struct cdx_device {
struct device dev;
struct cdx_controller *cdx;
u16 vendor;
u16 device;
u8 bus_num;
u8 dev_num;
struct resource res[MAX_CDX_DEV_RESOURCES];
u8 res_count;
u64 dma_mask;
u16 flags;
u32 req_id;
const char *driver_override;
};
#define to_cdx_device(_dev) \
container_of(_dev, struct cdx_device, dev)
/**
* struct cdx_driver - CDX device driver
* @driver: Generic device driver
* @match_id_table: table of supported device matching Ids
* @probe: Function called when a device is added
* @remove: Function called when a device is removed
* @shutdown: Function called at shutdown time to quiesce the device
* @driver_managed_dma: Device driver doesn't use kernel DMA API for DMA.
* For most device drivers, no need to care about this flag
* as long as all DMAs are handled through the kernel DMA API.
* For some special ones, for example VFIO drivers, they know
* how to manage the DMA themselves and set this flag so that
* the IOMMU layer will allow them to setup and manage their
* own I/O address space.
*/
struct cdx_driver {
struct device_driver driver;
const struct cdx_device_id *match_id_table;
int (*probe)(struct cdx_device *dev);
int (*remove)(struct cdx_device *dev);
void (*shutdown)(struct cdx_device *dev);
bool driver_managed_dma;
};
#define to_cdx_driver(_drv) \
container_of(_drv, struct cdx_driver, driver)
/* Macro to avoid include chaining to get THIS_MODULE */
#define cdx_driver_register(drv) \
__cdx_driver_register(drv, THIS_MODULE)
/**
* __cdx_driver_register - registers a CDX device driver
* @cdx_driver: CDX driver to register
* @owner: module owner
*
* Return: -errno on failure, 0 on success.
*/
int __must_check __cdx_driver_register(struct cdx_driver *cdx_driver,
struct module *owner);
/**
* cdx_driver_unregister - unregisters a device driver from the
* CDX bus.
* @cdx_driver: CDX driver to register
*/
void cdx_driver_unregister(struct cdx_driver *cdx_driver);
extern struct bus_type cdx_bus_type;
#endif /* _CDX_BUS_H_ */
......@@ -912,4 +912,19 @@ struct ishtp_device_id {
kernel_ulong_t driver_data;
};
/**
* struct cdx_device_id - CDX device identifier
* @vendor: Vendor ID
* @device: Device ID
* @override_only: Match only when dev->driver_override is this driver.
*
* Type of entries in the "device Id" table for CDX devices supported by
* a CDX device driver.
*/
struct cdx_device_id {
__u16 vendor;
__u16 device;
__u32 override_only;
};
#endif /* LINUX_MOD_DEVICETABLE_H */
......@@ -262,5 +262,9 @@ int main(void)
DEVID(ishtp_device_id);
DEVID_FIELD(ishtp_device_id, guid);
DEVID(cdx_device_id);
DEVID_FIELD(cdx_device_id, vendor);
DEVID_FIELD(cdx_device_id, device);
return 0;
}
......@@ -1452,6 +1452,17 @@ static int do_dfl_entry(const char *filename, void *symval, char *alias)
return 1;
}
/* Looks like: cdx:vNdN */
static int do_cdx_entry(const char *filename, void *symval,
char *alias)
{
DEF_FIELD(symval, cdx_device_id, vendor);
DEF_FIELD(symval, cdx_device_id, device);
sprintf(alias, "cdx:v%08Xd%08Xd", vendor, device);
return 1;
}
/* Does namelen bytes of name exactly match the symbol? */
static bool sym_is(const char *name, unsigned namelen, const char *symbol)
{
......@@ -1531,6 +1542,7 @@ static const struct devtable devtable[] = {
{"ssam", SIZE_ssam_device_id, do_ssam_entry},
{"dfl", SIZE_dfl_device_id, do_dfl_entry},
{"ishtp", SIZE_ishtp_device_id, do_ishtp_entry},
{"cdx", SIZE_cdx_device_id, do_cdx_entry},
};
/* Create MODULE_ALIAS() statements.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment