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