xref: /linux/drivers/soundwire/intel_ace2x_debugfs.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
1312316d5SPierre-Louis Bossart // SPDX-License-Identifier: GPL-2.0-only
2*b96f16bdSPierre-Louis Bossart // Copyright(c) 2023 Intel Corporation
3312316d5SPierre-Louis Bossart 
4312316d5SPierre-Louis Bossart #include <linux/acpi.h>
5312316d5SPierre-Louis Bossart #include <linux/debugfs.h>
6312316d5SPierre-Louis Bossart #include <linux/delay.h>
7312316d5SPierre-Louis Bossart #include <linux/device.h>
8312316d5SPierre-Louis Bossart #include <linux/io.h>
9312316d5SPierre-Louis Bossart #include <linux/pm_runtime.h>
10312316d5SPierre-Louis Bossart #include <linux/soundwire/sdw.h>
11312316d5SPierre-Louis Bossart #include <linux/soundwire/sdw_intel.h>
12312316d5SPierre-Louis Bossart #include <linux/soundwire/sdw_registers.h>
13312316d5SPierre-Louis Bossart #include "bus.h"
14312316d5SPierre-Louis Bossart #include "cadence_master.h"
15312316d5SPierre-Louis Bossart #include "intel.h"
16312316d5SPierre-Louis Bossart 
17312316d5SPierre-Louis Bossart /*
18312316d5SPierre-Louis Bossart  * debugfs
19312316d5SPierre-Louis Bossart  */
20312316d5SPierre-Louis Bossart #ifdef CONFIG_DEBUG_FS
21312316d5SPierre-Louis Bossart 
22312316d5SPierre-Louis Bossart #define RD_BUF (2 * PAGE_SIZE)
23312316d5SPierre-Louis Bossart 
intel_sprintf(void __iomem * mem,bool l,char * buf,size_t pos,unsigned int reg)24312316d5SPierre-Louis Bossart static ssize_t intel_sprintf(void __iomem *mem, bool l,
25312316d5SPierre-Louis Bossart 			     char *buf, size_t pos, unsigned int reg)
26312316d5SPierre-Louis Bossart {
27312316d5SPierre-Louis Bossart 	int value;
28312316d5SPierre-Louis Bossart 
29312316d5SPierre-Louis Bossart 	if (l)
30312316d5SPierre-Louis Bossart 		value = intel_readl(mem, reg);
31312316d5SPierre-Louis Bossart 	else
32312316d5SPierre-Louis Bossart 		value = intel_readw(mem, reg);
33312316d5SPierre-Louis Bossart 
34312316d5SPierre-Louis Bossart 	return scnprintf(buf + pos, RD_BUF - pos, "%4x\t%4x\n", reg, value);
35312316d5SPierre-Louis Bossart }
36312316d5SPierre-Louis Bossart 
intel_reg_show(struct seq_file * s_file,void * data)37312316d5SPierre-Louis Bossart static int intel_reg_show(struct seq_file *s_file, void *data)
38312316d5SPierre-Louis Bossart {
39312316d5SPierre-Louis Bossart 	struct sdw_intel *sdw = s_file->private;
40312316d5SPierre-Louis Bossart 	void __iomem *s = sdw->link_res->shim;
41312316d5SPierre-Louis Bossart 	void __iomem *vs_s = sdw->link_res->shim_vs;
42312316d5SPierre-Louis Bossart 	ssize_t ret;
43312316d5SPierre-Louis Bossart 	u32 pcm_cap;
44312316d5SPierre-Louis Bossart 	int pcm_bd;
45312316d5SPierre-Louis Bossart 	char *buf;
46312316d5SPierre-Louis Bossart 	int j;
47312316d5SPierre-Louis Bossart 
48312316d5SPierre-Louis Bossart 	buf = kzalloc(RD_BUF, GFP_KERNEL);
49312316d5SPierre-Louis Bossart 	if (!buf)
50312316d5SPierre-Louis Bossart 		return -ENOMEM;
51312316d5SPierre-Louis Bossart 
52312316d5SPierre-Louis Bossart 	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
53312316d5SPierre-Louis Bossart 	ret += scnprintf(buf + ret, RD_BUF - ret, "\nShim\n");
54312316d5SPierre-Louis Bossart 
55312316d5SPierre-Louis Bossart 	ret += intel_sprintf(s, true, buf, ret, SDW_SHIM2_LECAP);
56312316d5SPierre-Louis Bossart 	ret += intel_sprintf(s, false, buf, ret, SDW_SHIM2_PCMSCAP);
57312316d5SPierre-Louis Bossart 
58312316d5SPierre-Louis Bossart 	pcm_cap = intel_readw(s, SDW_SHIM2_PCMSCAP);
59312316d5SPierre-Louis Bossart 	pcm_bd = FIELD_GET(SDW_SHIM2_PCMSCAP_BSS, pcm_cap);
60312316d5SPierre-Louis Bossart 
61312316d5SPierre-Louis Bossart 	for (j = 0; j < pcm_bd; j++) {
62312316d5SPierre-Louis Bossart 		ret += intel_sprintf(s, false, buf, ret,
63312316d5SPierre-Louis Bossart 				SDW_SHIM2_PCMSYCHM(j));
64312316d5SPierre-Louis Bossart 		ret += intel_sprintf(s, false, buf, ret,
65312316d5SPierre-Louis Bossart 				SDW_SHIM2_PCMSYCHC(j));
66312316d5SPierre-Louis Bossart 	}
67312316d5SPierre-Louis Bossart 
68312316d5SPierre-Louis Bossart 	ret += scnprintf(buf + ret, RD_BUF - ret, "\nVS CLK controls\n");
69312316d5SPierre-Louis Bossart 	ret += intel_sprintf(vs_s, true, buf, ret, SDW_SHIM2_INTEL_VS_LVSCTL);
70312316d5SPierre-Louis Bossart 
71312316d5SPierre-Louis Bossart 	ret += scnprintf(buf + ret, RD_BUF - ret, "\nVS Wake registers\n");
72312316d5SPierre-Louis Bossart 	ret += intel_sprintf(vs_s, false, buf, ret, SDW_SHIM2_INTEL_VS_WAKEEN);
73312316d5SPierre-Louis Bossart 	ret += intel_sprintf(vs_s, false, buf, ret, SDW_SHIM2_INTEL_VS_WAKESTS);
74312316d5SPierre-Louis Bossart 
75312316d5SPierre-Louis Bossart 	ret += scnprintf(buf + ret, RD_BUF - ret, "\nVS IOCTL, ACTMCTL\n");
76312316d5SPierre-Louis Bossart 	ret += intel_sprintf(vs_s, false, buf, ret, SDW_SHIM2_INTEL_VS_IOCTL);
77312316d5SPierre-Louis Bossart 	ret += intel_sprintf(vs_s, false, buf, ret, SDW_SHIM2_INTEL_VS_ACTMCTL);
78312316d5SPierre-Louis Bossart 
79312316d5SPierre-Louis Bossart 	seq_printf(s_file, "%s", buf);
80312316d5SPierre-Louis Bossart 	kfree(buf);
81312316d5SPierre-Louis Bossart 
82312316d5SPierre-Louis Bossart 	return 0;
83312316d5SPierre-Louis Bossart }
84312316d5SPierre-Louis Bossart DEFINE_SHOW_ATTRIBUTE(intel_reg);
85312316d5SPierre-Louis Bossart 
intel_set_m_datamode(void * data,u64 value)86312316d5SPierre-Louis Bossart static int intel_set_m_datamode(void *data, u64 value)
87312316d5SPierre-Louis Bossart {
88312316d5SPierre-Louis Bossart 	struct sdw_intel *sdw = data;
89312316d5SPierre-Louis Bossart 	struct sdw_bus *bus = &sdw->cdns.bus;
90312316d5SPierre-Louis Bossart 
91312316d5SPierre-Louis Bossart 	if (value > SDW_PORT_DATA_MODE_STATIC_1)
92312316d5SPierre-Louis Bossart 		return -EINVAL;
93312316d5SPierre-Louis Bossart 
94312316d5SPierre-Louis Bossart 	/* Userspace changed the hardware state behind the kernel's back */
95312316d5SPierre-Louis Bossart 	add_taint(TAINT_USER, LOCKDEP_STILL_OK);
96312316d5SPierre-Louis Bossart 
97312316d5SPierre-Louis Bossart 	bus->params.m_data_mode = value;
98312316d5SPierre-Louis Bossart 
99312316d5SPierre-Louis Bossart 	return 0;
100312316d5SPierre-Louis Bossart }
101312316d5SPierre-Louis Bossart DEFINE_DEBUGFS_ATTRIBUTE(intel_set_m_datamode_fops, NULL,
102312316d5SPierre-Louis Bossart 			 intel_set_m_datamode, "%llu\n");
103312316d5SPierre-Louis Bossart 
intel_set_s_datamode(void * data,u64 value)104312316d5SPierre-Louis Bossart static int intel_set_s_datamode(void *data, u64 value)
105312316d5SPierre-Louis Bossart {
106312316d5SPierre-Louis Bossart 	struct sdw_intel *sdw = data;
107312316d5SPierre-Louis Bossart 	struct sdw_bus *bus = &sdw->cdns.bus;
108312316d5SPierre-Louis Bossart 
109312316d5SPierre-Louis Bossart 	if (value > SDW_PORT_DATA_MODE_STATIC_1)
110312316d5SPierre-Louis Bossart 		return -EINVAL;
111312316d5SPierre-Louis Bossart 
112312316d5SPierre-Louis Bossart 	/* Userspace changed the hardware state behind the kernel's back */
113312316d5SPierre-Louis Bossart 	add_taint(TAINT_USER, LOCKDEP_STILL_OK);
114312316d5SPierre-Louis Bossart 
115312316d5SPierre-Louis Bossart 	bus->params.s_data_mode = value;
116312316d5SPierre-Louis Bossart 
117312316d5SPierre-Louis Bossart 	return 0;
118312316d5SPierre-Louis Bossart }
119312316d5SPierre-Louis Bossart DEFINE_DEBUGFS_ATTRIBUTE(intel_set_s_datamode_fops, NULL,
120312316d5SPierre-Louis Bossart 			 intel_set_s_datamode, "%llu\n");
121312316d5SPierre-Louis Bossart 
intel_ace2x_debugfs_init(struct sdw_intel * sdw)122312316d5SPierre-Louis Bossart void intel_ace2x_debugfs_init(struct sdw_intel *sdw)
123312316d5SPierre-Louis Bossart {
124312316d5SPierre-Louis Bossart 	struct dentry *root = sdw->cdns.bus.debugfs;
125312316d5SPierre-Louis Bossart 
126312316d5SPierre-Louis Bossart 	if (!root)
127312316d5SPierre-Louis Bossart 		return;
128312316d5SPierre-Louis Bossart 
129312316d5SPierre-Louis Bossart 	sdw->debugfs = debugfs_create_dir("intel-sdw", root);
130312316d5SPierre-Louis Bossart 
131312316d5SPierre-Louis Bossart 	debugfs_create_file("intel-registers", 0400, sdw->debugfs, sdw,
132312316d5SPierre-Louis Bossart 			    &intel_reg_fops);
133312316d5SPierre-Louis Bossart 
134312316d5SPierre-Louis Bossart 	debugfs_create_file("intel-m-datamode", 0200, sdw->debugfs, sdw,
135312316d5SPierre-Louis Bossart 			    &intel_set_m_datamode_fops);
136312316d5SPierre-Louis Bossart 
137312316d5SPierre-Louis Bossart 	debugfs_create_file("intel-s-datamode", 0200, sdw->debugfs, sdw,
138312316d5SPierre-Louis Bossart 			    &intel_set_s_datamode_fops);
139312316d5SPierre-Louis Bossart 
140312316d5SPierre-Louis Bossart 	sdw_cdns_debugfs_init(&sdw->cdns, sdw->debugfs);
141312316d5SPierre-Louis Bossart }
142312316d5SPierre-Louis Bossart 
intel_ace2x_debugfs_exit(struct sdw_intel * sdw)143312316d5SPierre-Louis Bossart void intel_ace2x_debugfs_exit(struct sdw_intel *sdw)
144312316d5SPierre-Louis Bossart {
145312316d5SPierre-Louis Bossart 	debugfs_remove_recursive(sdw->debugfs);
146312316d5SPierre-Louis Bossart }
147312316d5SPierre-Louis Bossart #endif /* CONFIG_DEBUG_FS */
148