Path: blob/master/drivers/cdx/controller/mcdi_functions.c
29281 views
// SPDX-License-Identifier: GPL-2.01/*2* Copyright (C) 2022-2023, Advanced Micro Devices, Inc.3*/45#include <linux/module.h>67#include "mcdi_functions.h"89int cdx_mcdi_get_num_buses(struct cdx_mcdi *cdx)10{11MCDI_DECLARE_BUF(outbuf, MC_CMD_CDX_BUS_ENUM_BUSES_OUT_LEN);12size_t outlen;13int ret;1415ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_BUS_ENUM_BUSES, NULL, 0,16outbuf, sizeof(outbuf), &outlen);17if (ret)18return ret;1920if (outlen != MC_CMD_CDX_BUS_ENUM_BUSES_OUT_LEN)21return -EIO;2223return MCDI_DWORD(outbuf, CDX_BUS_ENUM_BUSES_OUT_BUS_COUNT);24}2526int cdx_mcdi_get_num_devs(struct cdx_mcdi *cdx, int bus_num)27{28MCDI_DECLARE_BUF(outbuf, MC_CMD_CDX_BUS_ENUM_DEVICES_OUT_LEN);29MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_BUS_ENUM_DEVICES_IN_LEN);30size_t outlen;31int ret;3233MCDI_SET_DWORD(inbuf, CDX_BUS_ENUM_DEVICES_IN_BUS, bus_num);3435ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_BUS_ENUM_DEVICES, inbuf, sizeof(inbuf),36outbuf, sizeof(outbuf), &outlen);37if (ret)38return ret;3940if (outlen != MC_CMD_CDX_BUS_ENUM_DEVICES_OUT_LEN)41return -EIO;4243return MCDI_DWORD(outbuf, CDX_BUS_ENUM_DEVICES_OUT_DEVICE_COUNT);44}4546int cdx_mcdi_get_dev_config(struct cdx_mcdi *cdx,47u8 bus_num, u8 dev_num,48struct cdx_dev_params *dev_params)49{50MCDI_DECLARE_BUF(outbuf, MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_V2_LEN);51MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_IN_LEN);52struct resource *res = &dev_params->res[0];53size_t outlen;54u32 req_id;55int ret;5657MCDI_SET_DWORD(inbuf, CDX_BUS_GET_DEVICE_CONFIG_IN_BUS, bus_num);58MCDI_SET_DWORD(inbuf, CDX_BUS_GET_DEVICE_CONFIG_IN_DEVICE, dev_num);5960ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_BUS_GET_DEVICE_CONFIG, inbuf, sizeof(inbuf),61outbuf, sizeof(outbuf), &outlen);62if (ret)63return ret;6465if (outlen != MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_V2_LEN)66return -EIO;6768dev_params->bus_num = bus_num;69dev_params->dev_num = dev_num;7071req_id = MCDI_DWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_REQUESTER_ID);72dev_params->req_id = req_id;7374dev_params->msi_dev_id = MCDI_DWORD(outbuf,75CDX_BUS_GET_DEVICE_CONFIG_OUT_V2_REQUESTER_DEVICE_ID);7677dev_params->res_count = 0;78if (MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION0_SIZE) != 0) {79res[dev_params->res_count].start =80MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION0_BASE);81res[dev_params->res_count].end =82MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION0_BASE) +83MCDI_QWORD(outbuf,84CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION0_SIZE) - 1;85res[dev_params->res_count].flags = IORESOURCE_MEM;86dev_params->res_count++;87}8889if (MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION1_SIZE) != 0) {90res[dev_params->res_count].start =91MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION1_BASE);92res[dev_params->res_count].end =93MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION1_BASE) +94MCDI_QWORD(outbuf,95CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION1_SIZE) - 1;96res[dev_params->res_count].flags = IORESOURCE_MEM;97dev_params->res_count++;98}99100if (MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION2_SIZE) != 0) {101res[dev_params->res_count].start =102MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION2_BASE);103res[dev_params->res_count].end =104MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION2_BASE) +105MCDI_QWORD(outbuf,106CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION2_SIZE) - 1;107res[dev_params->res_count].flags = IORESOURCE_MEM;108dev_params->res_count++;109}110111if (MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION3_SIZE) != 0) {112res[dev_params->res_count].start =113MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION3_BASE);114res[dev_params->res_count].end =115MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION3_BASE) +116MCDI_QWORD(outbuf,117CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION3_SIZE) - 1;118res[dev_params->res_count].flags = IORESOURCE_MEM;119dev_params->res_count++;120}121122dev_params->vendor = MCDI_WORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_VENDOR_ID);123dev_params->device = MCDI_WORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_DEVICE_ID);124dev_params->subsys_vendor = MCDI_WORD(outbuf,125CDX_BUS_GET_DEVICE_CONFIG_OUT_SUBSYS_VENDOR_ID);126dev_params->subsys_device = MCDI_WORD(outbuf,127CDX_BUS_GET_DEVICE_CONFIG_OUT_SUBSYS_DEVICE_ID);128dev_params->class = MCDI_DWORD(outbuf,129CDX_BUS_GET_DEVICE_CONFIG_OUT_DEVICE_CLASS) & 0xFFFFFF;130dev_params->revision = MCDI_BYTE(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_DEVICE_REVISION);131dev_params->num_msi = MCDI_DWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MSI_COUNT);132133return 0;134}135136int cdx_mcdi_bus_enable(struct cdx_mcdi *cdx, u8 bus_num)137{138MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_BUS_UP_IN_LEN);139int ret;140141MCDI_SET_DWORD(inbuf, CDX_BUS_UP_IN_BUS, bus_num);142ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_BUS_UP, inbuf, sizeof(inbuf),143NULL, 0, NULL);144145return ret;146}147148int cdx_mcdi_bus_disable(struct cdx_mcdi *cdx, u8 bus_num)149{150MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_BUS_DOWN_IN_LEN);151int ret;152153MCDI_SET_DWORD(inbuf, CDX_BUS_DOWN_IN_BUS, bus_num);154ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_BUS_DOWN, inbuf, sizeof(inbuf),155NULL, 0, NULL);156157return ret;158}159160int cdx_mcdi_write_msi(struct cdx_mcdi *cdx, u8 bus_num, u8 dev_num,161u32 msi_vector, u64 msi_address, u32 msi_data)162{163MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_LEN);164int ret;165166MCDI_SET_DWORD(inbuf, CDX_DEVICE_WRITE_MSI_MSG_IN_BUS, bus_num);167MCDI_SET_DWORD(inbuf, CDX_DEVICE_WRITE_MSI_MSG_IN_DEVICE, dev_num);168MCDI_SET_DWORD(inbuf, CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_VECTOR, msi_vector);169MCDI_SET_QWORD(inbuf, CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_ADDRESS, msi_address);170MCDI_SET_DWORD(inbuf, CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_DATA, msi_data);171172ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_WRITE_MSI_MSG, inbuf, sizeof(inbuf),173NULL, 0, NULL);174175return ret;176}177178int cdx_mcdi_reset_device(struct cdx_mcdi *cdx, u8 bus_num, u8 dev_num)179{180MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_RESET_IN_LEN);181int ret;182183MCDI_SET_DWORD(inbuf, CDX_DEVICE_RESET_IN_BUS, bus_num);184MCDI_SET_DWORD(inbuf, CDX_DEVICE_RESET_IN_DEVICE, dev_num);185186ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_RESET, inbuf, sizeof(inbuf),187NULL, 0, NULL);188189return ret;190}191192static int cdx_mcdi_ctrl_flag_get(struct cdx_mcdi *cdx, u8 bus_num,193u8 dev_num, u32 *flags)194{195MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_CONTROL_GET_IN_LEN);196MCDI_DECLARE_BUF(outbuf, MC_CMD_CDX_DEVICE_CONTROL_GET_OUT_LEN);197size_t outlen;198int ret;199200MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_GET_IN_BUS, bus_num);201MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_GET_IN_DEVICE, dev_num);202ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_CONTROL_GET, inbuf,203sizeof(inbuf), outbuf, sizeof(outbuf), &outlen);204if (ret)205return ret;206207if (outlen != MC_CMD_CDX_DEVICE_CONTROL_GET_OUT_LEN)208return -EIO;209210*flags = MCDI_DWORD(outbuf, CDX_DEVICE_CONTROL_GET_OUT_FLAGS);211212return 0;213}214215static int cdx_mcdi_ctrl_flag_set(struct cdx_mcdi *cdx, u8 bus_num,216u8 dev_num, bool enable, int bit_pos)217{218MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_CONTROL_SET_IN_LEN);219u32 flags;220int ret;221222/*223* Get flags and then set/reset bit at bit_pos according to224* the input params.225*/226ret = cdx_mcdi_ctrl_flag_get(cdx, bus_num, dev_num, &flags);227if (ret)228return ret;229230flags = flags & (u32)(~(BIT(bit_pos)));231if (enable)232flags |= (1 << bit_pos);233234MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_BUS, bus_num);235MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_DEVICE, dev_num);236MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_FLAGS, flags);237ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_CONTROL_SET, inbuf,238sizeof(inbuf), NULL, 0, NULL);239240return ret;241}242243int cdx_mcdi_bus_master_enable(struct cdx_mcdi *cdx, u8 bus_num,244u8 dev_num, bool enable)245{246return cdx_mcdi_ctrl_flag_set(cdx, bus_num, dev_num, enable,247MC_CMD_CDX_DEVICE_CONTROL_SET_IN_BUS_MASTER_ENABLE_LBN);248}249250int cdx_mcdi_msi_enable(struct cdx_mcdi *cdx, u8 bus_num,251u8 dev_num, bool enable)252{253return cdx_mcdi_ctrl_flag_set(cdx, bus_num, dev_num, enable,254MC_CMD_CDX_DEVICE_CONTROL_SET_IN_MSI_ENABLE_LBN);255}256257258