1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * AMD Versal SysMon MMIO platform driver 4 * 5 * Copyright (C) 2019 - 2022, Xilinx, Inc. 6 * Copyright (C) 2022 - 2026, Advanced Micro Devices, Inc. 7 */ 8 9 #include <linux/err.h> 10 #include <linux/io.h> 11 #include <linux/mod_devicetable.h> 12 #include <linux/module.h> 13 #include <linux/platform_device.h> 14 #include <linux/regmap.h> 15 #include <linux/types.h> 16 17 #include "versal-sysmon.h" 18 19 struct sysmon_mmio { 20 void __iomem *base; 21 }; 22 23 static int sysmon_mmio_reg_read(void *context, unsigned int reg, unsigned int *val) 24 { 25 struct sysmon_mmio *mmio = context; 26 27 *val = readl(mmio->base + reg); 28 return 0; 29 } 30 31 static int sysmon_mmio_reg_write(void *context, unsigned int reg, unsigned int val) 32 { 33 struct sysmon_mmio *mmio = context; 34 35 /* NPI must be unlocked before any register write except to NPI_LOCK */ 36 if (reg != SYSMON_NPI_LOCK) 37 writel(SYSMON_NPI_UNLOCK_CODE, mmio->base + SYSMON_NPI_LOCK); 38 writel(val, mmio->base + reg); 39 40 return 0; 41 } 42 43 static const struct regmap_config sysmon_mmio_regmap_config = { 44 .reg_bits = 32, 45 .val_bits = 32, 46 .reg_stride = SYSMON_REG_STRIDE, 47 .max_register = SYSMON_MAX_REG, 48 .reg_read = sysmon_mmio_reg_read, 49 .reg_write = sysmon_mmio_reg_write, 50 .fast_io = true, 51 }; 52 53 static int sysmon_platform_probe(struct platform_device *pdev) 54 { 55 struct device *dev = &pdev->dev; 56 struct sysmon_mmio *mmio; 57 struct regmap *regmap; 58 59 mmio = devm_kzalloc(dev, sizeof(*mmio), GFP_KERNEL); 60 if (!mmio) 61 return -ENOMEM; 62 63 mmio->base = devm_platform_ioremap_resource(pdev, 0); 64 if (IS_ERR(mmio->base)) 65 return PTR_ERR(mmio->base); 66 67 regmap = devm_regmap_init(dev, NULL, mmio, &sysmon_mmio_regmap_config); 68 if (IS_ERR(regmap)) 69 return PTR_ERR(regmap); 70 71 return devm_versal_sysmon_core_probe(dev, regmap); 72 } 73 74 static const struct of_device_id sysmon_of_match_table[] = { 75 { .compatible = "xlnx,versal-sysmon" }, 76 { } 77 }; 78 MODULE_DEVICE_TABLE(of, sysmon_of_match_table); 79 80 static struct platform_driver sysmon_platform_driver = { 81 .probe = sysmon_platform_probe, 82 .driver = { 83 .name = "versal-sysmon", 84 .of_match_table = sysmon_of_match_table, 85 }, 86 }; 87 module_platform_driver(sysmon_platform_driver); 88 89 MODULE_LICENSE("GPL"); 90 MODULE_DESCRIPTION("AMD Versal SysMon Platform Driver"); 91 MODULE_IMPORT_NS("VERSAL_SYSMON"); 92 MODULE_AUTHOR("Salih Erim <salih.erim@amd.com>"); 93