1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright(c) 2023 Intel Corporation
4 #include <linux/acpi.h>
5 #include <linux/debugfs.h>
6 #include <linux/delay.h>
7 #include <linux/device.h>
9 #include <linux/pm_runtime.h>
10 #include <linux/soundwire/sdw.h>
11 #include <linux/soundwire/sdw_intel.h>
12 #include <linux/soundwire/sdw_registers.h>
14 #include "cadence_master.h"
20 #ifdef CONFIG_DEBUG_FS
22 #define RD_BUF (2 * PAGE_SIZE)
24 static ssize_t
intel_sprintf(void __iomem
*mem
, bool l
,
25 char *buf
, size_t pos
, unsigned int reg
)
30 value
= intel_readl(mem
, reg
);
32 value
= intel_readw(mem
, reg
);
34 return scnprintf(buf
+ pos
, RD_BUF
- pos
, "%4x\t%4x\n", reg
, value
);
37 static int intel_reg_show(struct seq_file
*s_file
, void *data
)
39 struct sdw_intel
*sdw
= s_file
->private;
40 void __iomem
*s
= sdw
->link_res
->shim
;
41 void __iomem
*vs_s
= sdw
->link_res
->shim_vs
;
48 buf
= kzalloc(RD_BUF
, GFP_KERNEL
);
52 ret
= scnprintf(buf
, RD_BUF
, "Register Value\n");
53 ret
+= scnprintf(buf
+ ret
, RD_BUF
- ret
, "\nShim\n");
55 ret
+= intel_sprintf(s
, true, buf
, ret
, SDW_SHIM2_LECAP
);
56 ret
+= intel_sprintf(s
, false, buf
, ret
, SDW_SHIM2_PCMSCAP
);
58 pcm_cap
= intel_readw(s
, SDW_SHIM2_PCMSCAP
);
59 pcm_bd
= FIELD_GET(SDW_SHIM2_PCMSCAP_BSS
, pcm_cap
);
61 for (j
= 0; j
< pcm_bd
; j
++) {
62 ret
+= intel_sprintf(s
, false, buf
, ret
,
63 SDW_SHIM2_PCMSYCHM(j
));
64 ret
+= intel_sprintf(s
, false, buf
, ret
,
65 SDW_SHIM2_PCMSYCHC(j
));
68 ret
+= scnprintf(buf
+ ret
, RD_BUF
- ret
, "\nVS CLK controls\n");
69 ret
+= intel_sprintf(vs_s
, true, buf
, ret
, SDW_SHIM2_INTEL_VS_LVSCTL
);
71 ret
+= scnprintf(buf
+ ret
, RD_BUF
- ret
, "\nVS Wake registers\n");
72 ret
+= intel_sprintf(vs_s
, false, buf
, ret
, SDW_SHIM2_INTEL_VS_WAKEEN
);
73 ret
+= intel_sprintf(vs_s
, false, buf
, ret
, SDW_SHIM2_INTEL_VS_WAKESTS
);
75 ret
+= scnprintf(buf
+ ret
, RD_BUF
- ret
, "\nVS IOCTL, ACTMCTL\n");
76 ret
+= intel_sprintf(vs_s
, false, buf
, ret
, SDW_SHIM2_INTEL_VS_IOCTL
);
77 ret
+= intel_sprintf(vs_s
, false, buf
, ret
, SDW_SHIM2_INTEL_VS_ACTMCTL
);
79 seq_printf(s_file
, "%s", buf
);
84 DEFINE_SHOW_ATTRIBUTE(intel_reg
);
86 static int intel_set_m_datamode(void *data
, u64 value
)
88 struct sdw_intel
*sdw
= data
;
89 struct sdw_bus
*bus
= &sdw
->cdns
.bus
;
91 if (value
> SDW_PORT_DATA_MODE_STATIC_1
)
94 /* Userspace changed the hardware state behind the kernel's back */
95 add_taint(TAINT_USER
, LOCKDEP_STILL_OK
);
97 bus
->params
.m_data_mode
= value
;
101 DEFINE_DEBUGFS_ATTRIBUTE(intel_set_m_datamode_fops
, NULL
,
102 intel_set_m_datamode
, "%llu\n");
104 static int intel_set_s_datamode(void *data
, u64 value
)
106 struct sdw_intel
*sdw
= data
;
107 struct sdw_bus
*bus
= &sdw
->cdns
.bus
;
109 if (value
> SDW_PORT_DATA_MODE_STATIC_1
)
112 /* Userspace changed the hardware state behind the kernel's back */
113 add_taint(TAINT_USER
, LOCKDEP_STILL_OK
);
115 bus
->params
.s_data_mode
= value
;
119 DEFINE_DEBUGFS_ATTRIBUTE(intel_set_s_datamode_fops
, NULL
,
120 intel_set_s_datamode
, "%llu\n");
122 void intel_ace2x_debugfs_init(struct sdw_intel
*sdw
)
124 struct dentry
*root
= sdw
->cdns
.bus
.debugfs
;
129 sdw
->debugfs
= debugfs_create_dir("intel-sdw", root
);
131 debugfs_create_file("intel-registers", 0400, sdw
->debugfs
, sdw
,
134 debugfs_create_file("intel-m-datamode", 0200, sdw
->debugfs
, sdw
,
135 &intel_set_m_datamode_fops
);
137 debugfs_create_file("intel-s-datamode", 0200, sdw
->debugfs
, sdw
,
138 &intel_set_s_datamode_fops
);
140 sdw_cdns_debugfs_init(&sdw
->cdns
, sdw
->debugfs
);
143 void intel_ace2x_debugfs_exit(struct sdw_intel
*sdw
)
145 debugfs_remove_recursive(sdw
->debugfs
);
147 #endif /* CONFIG_DEBUG_FS */