diff options
Diffstat (limited to 'drivers/cdx/controller')
-rw-r--r-- | drivers/cdx/controller/cdx_controller.c | 7 | ||||
-rw-r--r-- | drivers/cdx/controller/cdx_rpmsg.c | 3 | ||||
-rw-r--r-- | drivers/cdx/controller/mcdi_functions.c | 58 | ||||
-rw-r--r-- | drivers/cdx/controller/mcdi_functions.h | 13 |
4 files changed, 79 insertions, 2 deletions
diff --git a/drivers/cdx/controller/cdx_controller.c b/drivers/cdx/controller/cdx_controller.c index dc52f95f8978..7828dac8edb1 100644 --- a/drivers/cdx/controller/cdx_controller.c +++ b/drivers/cdx/controller/cdx_controller.c @@ -5,7 +5,8 @@ * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. */ -#include <linux/of_platform.h> +#include <linux/mod_devicetable.h> +#include <linux/platform_device.h> #include <linux/slab.h> #include <linux/cdx/cdx_bus.h> @@ -55,6 +56,10 @@ static int cdx_configure_device(struct cdx_controller *cdx, case CDX_DEV_RESET_CONF: ret = cdx_mcdi_reset_device(cdx->priv, bus_num, dev_num); break; + case CDX_DEV_BUS_MASTER_CONF: + ret = cdx_mcdi_bus_master_enable(cdx->priv, bus_num, dev_num, + dev_config->bus_master_enable); + break; default: ret = -EINVAL; } diff --git a/drivers/cdx/controller/cdx_rpmsg.c b/drivers/cdx/controller/cdx_rpmsg.c index f37e639d6ce3..04b578a0be17 100644 --- a/drivers/cdx/controller/cdx_rpmsg.c +++ b/drivers/cdx/controller/cdx_rpmsg.c @@ -7,7 +7,8 @@ #include <linux/rpmsg.h> #include <linux/remoteproc.h> -#include <linux/of_platform.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/cdx/cdx_bus.h> #include <linux/module.h> diff --git a/drivers/cdx/controller/mcdi_functions.c b/drivers/cdx/controller/mcdi_functions.c index 0158f26533dd..fc82435d5dea 100644 --- a/drivers/cdx/controller/mcdi_functions.c +++ b/drivers/cdx/controller/mcdi_functions.c @@ -137,3 +137,61 @@ int cdx_mcdi_reset_device(struct cdx_mcdi *cdx, u8 bus_num, u8 dev_num) return ret; } + +static int cdx_mcdi_ctrl_flag_get(struct cdx_mcdi *cdx, u8 bus_num, + u8 dev_num, u32 *flags) +{ + MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_CONTROL_GET_IN_LEN); + MCDI_DECLARE_BUF(outbuf, MC_CMD_CDX_DEVICE_CONTROL_GET_OUT_LEN); + size_t outlen; + int ret; + + MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_GET_IN_BUS, bus_num); + MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_GET_IN_DEVICE, dev_num); + ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_CONTROL_GET, inbuf, + sizeof(inbuf), outbuf, sizeof(outbuf), &outlen); + if (ret) + return ret; + + if (outlen != MC_CMD_CDX_DEVICE_CONTROL_GET_OUT_LEN) + return -EIO; + + *flags = MCDI_DWORD(outbuf, CDX_DEVICE_CONTROL_GET_OUT_FLAGS); + + return 0; +} + +static int cdx_mcdi_ctrl_flag_set(struct cdx_mcdi *cdx, u8 bus_num, + u8 dev_num, bool enable, int bit_pos) +{ + MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_CONTROL_SET_IN_LEN); + u32 flags; + int ret; + + /* + * Get flags and then set/reset bit at bit_pos according to + * the input params. + */ + ret = cdx_mcdi_ctrl_flag_get(cdx, bus_num, dev_num, &flags); + if (ret) + return ret; + + flags = flags & (u32)(~(BIT(bit_pos))); + if (enable) + flags |= (1 << bit_pos); + + MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_BUS, bus_num); + MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_DEVICE, dev_num); + MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_FLAGS, flags); + ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_CONTROL_SET, inbuf, + sizeof(inbuf), NULL, 0, NULL); + + return ret; +} + +int cdx_mcdi_bus_master_enable(struct cdx_mcdi *cdx, u8 bus_num, + u8 dev_num, bool enable) +{ + return cdx_mcdi_ctrl_flag_set(cdx, bus_num, dev_num, enable, + MC_CMD_CDX_DEVICE_CONTROL_SET_IN_BUS_MASTER_ENABLE_LBN); +} diff --git a/drivers/cdx/controller/mcdi_functions.h b/drivers/cdx/controller/mcdi_functions.h index 7440ace5539a..a448d6581eb4 100644 --- a/drivers/cdx/controller/mcdi_functions.h +++ b/drivers/cdx/controller/mcdi_functions.h @@ -58,4 +58,17 @@ int cdx_mcdi_get_dev_config(struct cdx_mcdi *cdx, int cdx_mcdi_reset_device(struct cdx_mcdi *cdx, u8 bus_num, u8 dev_num); +/** + * cdx_mcdi_bus_master_enable - Set/Reset bus mastering for cdx device + * represented by bus_num:dev_num + * @cdx: pointer to MCDI interface. + * @bus_num: Bus number. + * @dev_num: Device number. + * @enable: Enable bus mastering if set, disable otherwise. + * + * Return: 0 on success, <0 on failure + */ +int cdx_mcdi_bus_master_enable(struct cdx_mcdi *cdx, u8 bus_num, + u8 dev_num, bool enable); + #endif /* CDX_MCDI_FUNCTIONS_H */ |