1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright(c) 2025 Intel Corporation */
3#include <linux/dma-mapping.h>
4#include <linux/export.h>
5#include <linux/string_helpers.h>
6
7#include "adf_admin.h"
8#include "adf_common_drv.h"
9#include "adf_gen6_pm.h"
10#include "adf_pm_dbgfs_utils.h"
11#include "icp_qat_fw_init_admin.h"
12
13#define PM_INFO_REGSET_ENTRY(_reg_, _field_) \
14 PM_INFO_REGSET_ENTRY_MASK(_reg_, _field_, ADF_GEN6_PM_##_field_##_MASK)
15
16static struct pm_status_row pm_fuse_rows[] = {
17 PM_INFO_REGSET_ENTRY(fusectl0, ENABLE_PM),
18 PM_INFO_REGSET_ENTRY(fusectl0, ENABLE_PM_IDLE),
19 PM_INFO_REGSET_ENTRY(fusectl0, ENABLE_DEEP_PM_IDLE),
20};
21
22static struct pm_status_row pm_info_rows[] = {
23 PM_INFO_REGSET_ENTRY(pm.status, CPM_PM_STATE),
24 PM_INFO_REGSET_ENTRY(pm.fw_init, IDLE_ENABLE),
25 PM_INFO_REGSET_ENTRY(pm.fw_init, IDLE_FILTER),
26};
27
28static struct pm_status_row pm_ssm_rows[] = {
29 PM_INFO_REGSET_ENTRY(ssm.pm_enable, SSM_PM_ENABLE),
30 PM_INFO_REGSET_ENTRY(ssm.pm_domain_status, DOMAIN_POWERED_UP),
31};
32
33static struct pm_status_row pm_csrs_rows[] = {
34 PM_INFO_REGSET_ENTRY32(pm.fw_init, CPM_PM_FW_INIT),
35 PM_INFO_REGSET_ENTRY32(pm.status, CPM_PM_STATUS),
36};
37
38static_assert(sizeof(struct icp_qat_fw_init_admin_pm_info) < PAGE_SIZE);
39
40static ssize_t adf_gen6_print_pm_status(struct adf_accel_dev *accel_dev,
41 char __user *buf, size_t count,
42 loff_t *pos)
43{
44 void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
45 struct icp_qat_fw_init_admin_pm_info *pm_info;
46 dma_addr_t p_state_addr;
47 u32 *pm_info_regs;
48 size_t len = 0;
49 char *pm_kv;
50 u32 val;
51 int ret;
52
53 pm_info = kzalloc(PAGE_SIZE, GFP_KERNEL);
54 if (!pm_info)
55 return -ENOMEM;
56
57 pm_kv = kzalloc(PAGE_SIZE, GFP_KERNEL);
58 if (!pm_kv) {
59 kfree(objp: pm_info);
60 return -ENOMEM;
61 }
62
63 p_state_addr = dma_map_single(&GET_DEV(accel_dev), pm_info, PAGE_SIZE,
64 DMA_FROM_DEVICE);
65 ret = dma_mapping_error(dev: &GET_DEV(accel_dev), dma_addr: p_state_addr);
66 if (ret)
67 goto out_free;
68
69 /* Query power management information from QAT FW */
70 ret = adf_get_pm_info(accel_dev, p_state_addr, PAGE_SIZE);
71 dma_unmap_single(&GET_DEV(accel_dev), p_state_addr, PAGE_SIZE,
72 DMA_FROM_DEVICE);
73 if (ret)
74 goto out_free;
75
76 pm_info_regs = (u32 *)pm_info;
77
78 /* Fuse control register */
79 len += scnprintf(buf: &pm_kv[len], PAGE_SIZE - len,
80 fmt: "----------- PM Fuse info ---------\n");
81 len += adf_pm_scnprint_table_lower_keys(buff: &pm_kv[len], table: pm_fuse_rows,
82 pm_info_regs, PAGE_SIZE - len,
83 ARRAY_SIZE(pm_fuse_rows));
84
85 /* Power management */
86 len += scnprintf(buf: &pm_kv[len], PAGE_SIZE - len,
87 fmt: "----------- PM Info --------------\n");
88
89 len += adf_pm_scnprint_table_lower_keys(buff: &pm_kv[len], table: pm_info_rows,
90 pm_info_regs, PAGE_SIZE - len,
91 ARRAY_SIZE(pm_info_rows));
92 len += scnprintf(buf: &pm_kv[len], PAGE_SIZE - len, fmt: "pm_mode: ACTIVE\n");
93
94 /* Shared Slice Module */
95 len += scnprintf(buf: &pm_kv[len], PAGE_SIZE - len,
96 fmt: "----------- SSM_PM Info ----------\n");
97 len += adf_pm_scnprint_table_lower_keys(buff: &pm_kv[len], table: pm_ssm_rows,
98 pm_info_regs, PAGE_SIZE - len,
99 ARRAY_SIZE(pm_ssm_rows));
100
101 /* Control status register content */
102 len += scnprintf(buf: &pm_kv[len], PAGE_SIZE - len,
103 fmt: "----------- HW PM CSRs -----------\n");
104 len += adf_pm_scnprint_table_upper_keys(buff: &pm_kv[len], table: pm_csrs_rows,
105 pm_info_regs, PAGE_SIZE - len,
106 ARRAY_SIZE(pm_csrs_rows));
107
108 val = ADF_CSR_RD(pmisc, ADF_GEN6_PM_INTERRUPT);
109 len += scnprintf(buf: &pm_kv[len], PAGE_SIZE - len, fmt: "CPM_PM_INTERRUPT: %#x\n", val);
110 ret = simple_read_from_buffer(to: buf, count, ppos: pos, from: pm_kv, available: len);
111
112out_free:
113 kfree(objp: pm_info);
114 kfree(objp: pm_kv);
115
116 return ret;
117}
118
119void adf_gen6_init_dev_pm_data(struct adf_accel_dev *accel_dev)
120{
121 accel_dev->power_management.print_pm_status = adf_gen6_print_pm_status;
122 accel_dev->power_management.present = true;
123}
124EXPORT_SYMBOL_GPL(adf_gen6_init_dev_pm_data);
125

source code of linux/drivers/crypto/intel/qat/qat_common/adf_gen6_pm_dbgfs.c