intel_ace2x_debugfs.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. // Copyright(c) 2023 Intel Corporation
  3. #include <linux/acpi.h>
  4. #include <linux/debugfs.h>
  5. #include <linux/delay.h>
  6. #include <linux/device.h>
  7. #include <linux/io.h>
  8. #include <linux/pm_runtime.h>
  9. #include <linux/soundwire/sdw.h>
  10. #include <linux/soundwire/sdw_intel.h>
  11. #include <linux/soundwire/sdw_registers.h>
  12. #include "bus.h"
  13. #include "cadence_master.h"
  14. #include "intel.h"
  15. /*
  16. * debugfs
  17. */
  18. #ifdef CONFIG_DEBUG_FS
  19. #define RD_BUF (2 * PAGE_SIZE)
  20. static ssize_t intel_sprintf(void __iomem *mem, bool l,
  21. char *buf, size_t pos, unsigned int reg)
  22. {
  23. int value;
  24. if (l)
  25. value = intel_readl(mem, reg);
  26. else
  27. value = intel_readw(mem, reg);
  28. return scnprintf(buf + pos, RD_BUF - pos, "%4x\t%4x\n", reg, value);
  29. }
  30. static int intel_reg_show(struct seq_file *s_file, void *data)
  31. {
  32. struct sdw_intel *sdw = s_file->private;
  33. void __iomem *s = sdw->link_res->shim;
  34. void __iomem *vs_s = sdw->link_res->shim_vs;
  35. ssize_t ret;
  36. u32 pcm_cap;
  37. int pcm_bd;
  38. char *buf;
  39. int j;
  40. buf = kzalloc(RD_BUF, GFP_KERNEL);
  41. if (!buf)
  42. return -ENOMEM;
  43. ret = scnprintf(buf, RD_BUF, "Register Value\n");
  44. ret += scnprintf(buf + ret, RD_BUF - ret, "\nShim\n");
  45. ret += intel_sprintf(s, true, buf, ret, SDW_SHIM2_LECAP);
  46. ret += intel_sprintf(s, false, buf, ret, SDW_SHIM2_PCMSCAP);
  47. pcm_cap = intel_readw(s, SDW_SHIM2_PCMSCAP);
  48. pcm_bd = FIELD_GET(SDW_SHIM2_PCMSCAP_BSS, pcm_cap);
  49. for (j = 0; j < pcm_bd; j++) {
  50. ret += intel_sprintf(s, false, buf, ret,
  51. SDW_SHIM2_PCMSYCHM(j));
  52. ret += intel_sprintf(s, false, buf, ret,
  53. SDW_SHIM2_PCMSYCHC(j));
  54. }
  55. ret += scnprintf(buf + ret, RD_BUF - ret, "\nVS CLK controls\n");
  56. ret += intel_sprintf(vs_s, true, buf, ret, SDW_SHIM2_INTEL_VS_LVSCTL);
  57. ret += scnprintf(buf + ret, RD_BUF - ret, "\nVS Wake registers\n");
  58. ret += intel_sprintf(vs_s, false, buf, ret, SDW_SHIM2_INTEL_VS_WAKEEN);
  59. ret += intel_sprintf(vs_s, false, buf, ret, SDW_SHIM2_INTEL_VS_WAKESTS);
  60. ret += scnprintf(buf + ret, RD_BUF - ret, "\nVS IOCTL, ACTMCTL\n");
  61. ret += intel_sprintf(vs_s, false, buf, ret, SDW_SHIM2_INTEL_VS_IOCTL);
  62. ret += intel_sprintf(vs_s, false, buf, ret, SDW_SHIM2_INTEL_VS_ACTMCTL);
  63. if (sdw->link_res->mic_privacy) {
  64. ret += scnprintf(buf + ret, RD_BUF - ret, "\nVS PVCCS\n");
  65. ret += intel_sprintf(vs_s, false, buf, ret,
  66. SDW_SHIM2_INTEL_VS_PVCCS);
  67. }
  68. seq_printf(s_file, "%s", buf);
  69. kfree(buf);
  70. return 0;
  71. }
  72. DEFINE_SHOW_ATTRIBUTE(intel_reg);
  73. static int intel_set_m_datamode(void *data, u64 value)
  74. {
  75. struct sdw_intel *sdw = data;
  76. struct sdw_bus *bus = &sdw->cdns.bus;
  77. if (value > SDW_PORT_DATA_MODE_STATIC_1)
  78. return -EINVAL;
  79. /* Userspace changed the hardware state behind the kernel's back */
  80. add_taint(TAINT_USER, LOCKDEP_STILL_OK);
  81. bus->params.m_data_mode = value;
  82. return 0;
  83. }
  84. DEFINE_DEBUGFS_ATTRIBUTE(intel_set_m_datamode_fops, NULL,
  85. intel_set_m_datamode, "%llu\n");
  86. static int intel_set_s_datamode(void *data, u64 value)
  87. {
  88. struct sdw_intel *sdw = data;
  89. struct sdw_bus *bus = &sdw->cdns.bus;
  90. if (value > SDW_PORT_DATA_MODE_STATIC_1)
  91. return -EINVAL;
  92. /* Userspace changed the hardware state behind the kernel's back */
  93. add_taint(TAINT_USER, LOCKDEP_STILL_OK);
  94. bus->params.s_data_mode = value;
  95. return 0;
  96. }
  97. DEFINE_DEBUGFS_ATTRIBUTE(intel_set_s_datamode_fops, NULL,
  98. intel_set_s_datamode, "%llu\n");
  99. void intel_ace2x_debugfs_init(struct sdw_intel *sdw)
  100. {
  101. struct dentry *root = sdw->cdns.bus.debugfs;
  102. if (!root)
  103. return;
  104. sdw->debugfs = debugfs_create_dir("intel-sdw", root);
  105. debugfs_create_file("intel-registers", 0400, sdw->debugfs, sdw,
  106. &intel_reg_fops);
  107. debugfs_create_file("intel-m-datamode", 0200, sdw->debugfs, sdw,
  108. &intel_set_m_datamode_fops);
  109. debugfs_create_file("intel-s-datamode", 0200, sdw->debugfs, sdw,
  110. &intel_set_s_datamode_fops);
  111. sdw_cdns_debugfs_init(&sdw->cdns, sdw->debugfs);
  112. }
  113. void intel_ace2x_debugfs_exit(struct sdw_intel *sdw)
  114. {
  115. debugfs_remove_recursive(sdw->debugfs);
  116. }
  117. #endif /* CONFIG_DEBUG_FS */