[PATCH v6 2/2] fpga: zynqmp-fpga: Adds status interface

From: Nava kishore Manne
Date: Fri Feb 17 2023 - 06:51:02 EST


Adds status interface for zynqmp-fpga, It's a read only interface
which allows the user to get the Programmable Logic(PL) configuration
status.

Usage:
To read the Programmable Logic(PL) configuration status
cat /sys/bus/platform/drivers/zynqmp_fpga_manager/
firmware:zynqmp-firmware:pcap/status

Signed-off-by: Nava kishore Manne <nava.kishore.manne@xxxxxxx>
---
hanges for v2:
- Updated status messages handling logic as suggested by Xu Yilun.

Changes for v3:
- Updated status interface handling logic (Restrict the status
interface to the device-specific instead of handled by the core)
as suggested by Xu Yilun.

Changes for v4:
- Limit the error strings to one word for each as suggested by
Xu Yilun

Changes for v5:
- Added new sysfs-driver-zynqmp-fpga file.

Changes for v6:
- Updated the sysfs interface to cat /sys/bus/platform/drivers/...
as suggested by Xu Yilun.
- Exported raw hex value instead of multiple error strings
as suggested by Greg.

.../ABI/testing/sysfs-driver-zynqmp-fpga | 72 +++++++++++++++++++
drivers/fpga/zynqmp-fpga.c | 23 ++++++
2 files changed, 95 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-driver-zynqmp-fpga

diff --git a/Documentation/ABI/testing/sysfs-driver-zynqmp-fpga b/Documentation/ABI/testing/sysfs-driver-zynqmp-fpga
new file mode 100644
index 000000000000..af5d42916dd1
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-zynqmp-fpga
@@ -0,0 +1,72 @@
+What: /sys/bus/platform/drivers/zynqmp_fpga_manager/firmware:zynqmp-firmware:pcap/status
+Date: Jan 2023
+KernelVersion: 6.2
+Contact: Nava kishore Manne <nava.kishore.manne@xxxxxxx>
+Description: (RO) Read fpga status.
+ Read returns a hexadecimal value that tells the current status
+ of the FPGA device. Each bit position in the status value is
+ described Below(see ug570 chapter 9).
+
+ ====================== ==============================================
+ BIT(0) 0: No CRC error
+ 1: CRC error
+
+ BIT(1) 0: Decryptor security not set
+ 1: Decryptor security set
+
+ BIT(2) 0: MMCMs/PLLs are not locked
+ 1: MMCMs/PLLs are locked
+
+ BIT(3) 0: DCI not matched
+ 1: DCI matched
+
+ BIT(4) 0: Start-up sequence has not finished
+ 1: Start-up sequence has finished
+
+ BIT(5) 0: All I/Os are placed in High-Z state
+ 1: All I/Os behave as configured
+
+ BIT(6) 0: Flip-flops and block RAM are write disabled
+ 1: Flip-flops and block RAM are write enabled
+
+ BIT(7) 0: GHIGH_B_STATUS asserted
+ 1: GHIGH_B_STATUS deasserted
+
+ BIT(8) to BIT(10) Status of the mode pins
+
+ BIT(11) 0: Initialization has not finished
+ 1: Initialization finished
+
+ BIT(12) Value on INIT_B_PIN pin
+
+ BIT(13) 0: Signal not released
+ 1: Signal released
+
+ BIT(14) Value on DONE_PIN pin.
+
+ BIT(15) 0: No IDCODE_ERROR
+ 1: IDCODE_ERROR
+
+ BIT(16) 0: No SECURITY_ERROR
+ 1: SECURITY_ERROR
+
+ BIT(17) System Monitor over-temperature if set
+
+ BIT(18) to BIT(20) Start-up state machine (0 to 7)
+ Phase 0 = 000
+ Phase 1 = 001
+ Phase 2 = 011
+ Phase 3 = 010
+ Phase 4 = 110
+ Phase 5 = 111
+ Phase 6 = 101
+ Phase 7 = 100
+
+ BIT(25) to BIT(26) Indicates the detected bus width
+ 00 = x1
+ 01 = x8
+ 10 = x16
+ 11 = x32
+ ====================== ==============================================
+
+ The other bits are reserved.
diff --git a/drivers/fpga/zynqmp-fpga.c b/drivers/fpga/zynqmp-fpga.c
index c60f20949c47..0c58ca27319f 100644
--- a/drivers/fpga/zynqmp-fpga.c
+++ b/drivers/fpga/zynqmp-fpga.c
@@ -77,6 +77,28 @@ static enum fpga_mgr_states zynqmp_fpga_ops_state(struct fpga_manager *mgr)
return FPGA_MGR_STATE_UNKNOWN;
}

+static ssize_t status_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u32 status;
+ int ret;
+
+ ret = zynqmp_pm_fpga_get_config_status(&status);
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "0x%x\n", status);
+}
+
+static DEVICE_ATTR_RO(status);
+
+static struct attribute *zynqmp_fpga_attrs[] = {
+ &dev_attr_status.attr,
+ NULL,
+};
+
+ATTRIBUTE_GROUPS(zynqmp_fpga);
+
static const struct fpga_manager_ops zynqmp_fpga_ops = {
.state = zynqmp_fpga_ops_state,
.write_init = zynqmp_fpga_ops_write_init,
@@ -113,6 +135,7 @@ static struct platform_driver zynqmp_fpga_driver = {
.driver = {
.name = "zynqmp_fpga_manager",
.of_match_table = of_match_ptr(zynqmp_fpga_of_match),
+ .dev_groups = zynqmp_fpga_groups,
},
};

--
2.25.1