cl_dsp.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. /* SPDX-License-Identifier: GPL-2.0
  2. *
  3. * cl_dsp.h -- DSP control for non-ALSA Cirrus Logic devices
  4. *
  5. * Copyright 2022 Cirrus Logic, Inc.
  6. *
  7. * Author: Fred Treven <[email protected]>
  8. */
  9. #include <linux/firmware.h>
  10. #include <linux/module.h>
  11. #include <linux/version.h>
  12. #include <linux/kernel.h>
  13. #include <linux/init.h>
  14. #include <linux/list.h>
  15. #include <linux/regmap.h>
  16. #include <linux/of_device.h>
  17. #include <linux/slab.h>
  18. #include <linux/mm.h>
  19. #include <linux/debugfs.h>
  20. #include <linux/pm_runtime.h>
  21. #ifndef __CL_DSP_H__
  22. #define __CL_DSP_H__
  23. #define CL_DSP_BYTES_PER_WORD 4
  24. #define CL_DSP_BITS_PER_BYTE 8
  25. #define CL_DSP_BYTE_MASK GENMASK(7, 0)
  26. #define CL_DSP_NIBBLE_MASK GENMASK(15, 0)
  27. #define CL_DSP_FW_FILE_HEADER_SIZE 40
  28. #define CL_DSP_COEFF_FILE_HEADER_SIZE 16
  29. #define CL_DSP_MAGIC_ID_SIZE 4
  30. #define CL_DSP_WMFW_MAGIC_ID "WMFW"
  31. #define CL_DSP_WMDR_MAGIC_ID "WMDR"
  32. #define CL_DSP_DBLK_HEADER_SIZE 8
  33. #define CL_DSP_COEFF_DBLK_HEADER_SIZE 20
  34. #define CL_DSP_ALIGN 0x00000003
  35. #define CL_DSP_TARGET_CORE_ADSP1 0x01
  36. #define CL_DSP_TARGET_CORE_ADSP2 0x02
  37. #define CL_DSP_TARGET_CORE_HALO 0x04
  38. #define CL_DSP_TARGET_CORE_WARP2 0x12
  39. #define CL_DSP_TARGET_CORE_MCU 0x45
  40. #define CL_DSP_MIN_FORMAT_VERSION 0x03
  41. #define CL_DSP_API_REVISION 0x0300
  42. #define CL_DSP_ALGO_NAME_LEN_SIZE 1
  43. #define CL_DSP_ALGO_DESC_LEN_SIZE 2
  44. #define CL_DSP_ALGO_ID_SIZE 4
  45. #define CL_DSP_COEFF_COUNT_SIZE 4
  46. #define CL_DSP_COEFF_OFFSET_SIZE 2
  47. #define CL_DSP_COEFF_TYPE_SIZE 2
  48. #define CL_DSP_COEFF_NAME_LEN_SIZE 1
  49. #define CL_DSP_COEFF_FULLNAME_LEN_SIZE 1
  50. #define CL_DSP_COEFF_DESC_LEN_SIZE 2
  51. #define CL_DSP_COEFF_LEN_SIZE 4
  52. #define CL_DSP_COEFF_FLAGS_SIZE 4
  53. #define CL_DSP_COEFF_FLAGS_SHIFT 16
  54. #define CL_DSP_COEFF_NAME_LEN_MAX 32
  55. #define CL_DSP_COEFF_MIN_FORMAT_VERSION 0x01
  56. #define CL_DSP_COEFF_API_REV_HALO 0x030000
  57. #define CL_DSP_COEFF_API_REV_ADSP2 0x000500
  58. #define CL_DSP_ALGO_LIST_TERM 0xBEDEAD
  59. #define CL_DSP_REV_OFFSET_SHIFT 8
  60. #define CL_DSP_REV_MAJOR_MASK GENMASK(23, 16)
  61. #define CL_DSP_REV_MAJOR_SHIFT 16
  62. #define CL_DSP_REV_MINOR_MASK GENMASK(15, 8)
  63. #define CL_DSP_REV_MINOR_SHIFT 8
  64. #define CL_DSP_REV_PATCH_MASK GENMASK(7, 0)
  65. #define CL_DSP_NUM_ALGOS_MAX 32
  66. #ifndef CONFIG_CS40L26_SAMSUNG_USE_MAX_DATA_TX_SIZE
  67. #define CL_DSP_MAX_WLEN 32
  68. #else
  69. #define CL_DSP_MAX_WLEN 4096
  70. #endif
  71. #define CL_DSP_XM_UNPACKED_TYPE 0x0005
  72. #define CL_DSP_YM_UNPACKED_TYPE 0x0006
  73. #define CL_DSP_PM_PACKED_TYPE 0x0010
  74. #define CL_DSP_XM_PACKED_TYPE 0x0011
  75. #define CL_DSP_YM_PACKED_TYPE 0x0012
  76. #define CL_DSP_ALGO_INFO_TYPE 0x00F2
  77. #define CL_DSP_WMFW_INFO_TYPE 0x00FF
  78. #define CL_DSP_MEM_REG_TYPE_MASK GENMASK(27, 20)
  79. #define CL_DSP_MEM_REG_TYPE_SHIFT 20
  80. #define CL_DSP_PM_NUM_BYTES 5
  81. #define CL_DSP_PACKED_NUM_BYTES 3
  82. #define CL_DSP_UNPACKED_NUM_BYTES 4
  83. #define CL_DSP_WMDR_DBLK_OFFSET_SIZE 2
  84. #define CL_DSP_WMDR_DBLK_TYPE_SIZE 2
  85. #define CL_DSP_WMDR_ALGO_ID_SIZE 4
  86. #define CL_DSP_WMDR_ALGO_REV_SIZE 4
  87. #define CL_DSP_WMDR_SAMPLE_RATE_SIZE 4
  88. #define CL_DSP_WMDR_DBLK_LEN_SIZE 4
  89. #define CL_DSP_WMDR_NAME_LEN 32
  90. #define CL_DSP_WMDR_DATE_LEN 16
  91. #define CL_DSP_WMDR_HEADER_LEN_SIZE 4
  92. #define CL_DSP_WMDR_DATE_PREFIX "Date: "
  93. #define CL_DSP_WMDR_DATE_PREFIX_LEN 6
  94. #define CL_DSP_WMDR_FILE_NAME_MISSING "N/A"
  95. #define CL_DSP_WMDR_FILE_DATE_MISSING "N/A"
  96. #define CL_DSP_WMDR_NAME_TYPE 0xFE00
  97. #define CL_DSP_WMDR_INFO_TYPE 0xFF00
  98. //HALO core specific registers
  99. #define CL_DSP_HALO_XMEM_PACKED_BASE 0x02000000
  100. #define CL_DSP_HALO_XROM_PACKED_BASE 0x02006000
  101. #define CL_DSP_HALO_XMEM_UNPACKED32_BASE 0x02400000
  102. #define CL_DSP_HALO_XMEM_UNPACKED24_BASE 0x02800000
  103. #define CL_DSP_HALO_XROM_UNPACKED24_BASE 0x02808000
  104. #define CL_DSP_HALO_YMEM_PACKED_BASE 0x02C00000
  105. #define CL_DSP_HALO_YMEM_UNPACKED32_BASE 0x03000000
  106. #define CL_DSP_HALO_YMEM_UNPACKED24_BASE 0x03400000
  107. #define CL_DSP_HALO_PMEM_BASE 0x03800000
  108. #define CL_DSP_HALO_PROM_BASE 0x03C60000
  109. #define CL_DSP_HALO_XM_FW_ID_REG 0x0280000C
  110. #define CL_DSP_HALO_NUM_ALGOS_REG 0x02800024
  111. #define CL_DSP_HALO_ALGO_REV_OFFSET 4
  112. #define CL_DSP_HALO_ALGO_XM_BASE_OFFSET 8
  113. #define CL_DSP_HALO_ALGO_XM_SIZE_OFFSET 12
  114. #define CL_DSP_HALO_ALGO_YM_BASE_OFFSET 16
  115. #define CL_DSP_HALO_ALGO_YM_SIZE_OFFSET 20
  116. #define CL_DSP_ALGO_ENTRY_SIZE 24
  117. /* open wavetable */
  118. #define CL_DSP_OWT_HEADER_MAX_LEN 254
  119. #define CL_DSP_OWT_HEADER_ENTRY_SIZE 12
  120. /* macros */
  121. #define CL_DSP_WORD_ALIGN(n) (CL_DSP_BYTES_PER_WORD +\
  122. (((n) / CL_DSP_BYTES_PER_WORD) *\
  123. CL_DSP_BYTES_PER_WORD))
  124. #define CL_DSP_GET_MAJOR(n) (((n) & CL_DSP_REV_MAJOR_MASK) >>\
  125. CL_DSP_REV_MAJOR_SHIFT)
  126. #define CL_DSP_GET_MINOR(n) (((n) & CL_DSP_REV_MINOR_MASK) >>\
  127. CL_DSP_REV_MINOR_SHIFT)
  128. #define CL_DSP_GET_PATCH(n) ((n) & CL_DSP_REV_PATCH_MASK)
  129. enum cl_dsp_wt_type {
  130. WT_TYPE_V4_PCM = 0,
  131. WT_TYPE_V4_PWLE = 1,
  132. WT_TYPE_V4_PCM_F0_REDC = 2,
  133. WT_TYPE_V4_PCM_F0_REDC_VAR = 3,
  134. WT_TYPE_V4_COMPOSITE = 4,
  135. WT_TYPE_V5_PCM_PCM_F0_REDC_Q = 5,
  136. WT_TYPE_V5_PWLE_LONG = 6,
  137. WT_TYPE_V5_PWLE_LINEAR = 7,
  138. WT_TYPE_V6_PCM_F0_REDC = 8,
  139. WT_TYPE_V6_PCM_F0_REDC_VAR = 9,
  140. WT_TYPE_V6_COMPOSITE = 10,
  141. WT_TYPE_V6_PCM_F0_REDC_Q = 11,
  142. WT_TYPE_V6_PWLE = 12,
  143. WT_TYPE_TERMINATOR = 0xFF,
  144. };
  145. union cl_dsp_wmdr_header {
  146. struct {
  147. char magic[CL_DSP_BYTES_PER_WORD];
  148. u32 header_len;
  149. u32 fw_revision : 24;
  150. u8 file_format_version;
  151. u32 api_revision : 24;
  152. u8 target_core;
  153. } __attribute__((__packed__));
  154. u8 data[CL_DSP_COEFF_FILE_HEADER_SIZE];
  155. };
  156. union cl_dsp_wmfw_header {
  157. struct {
  158. char magic[CL_DSP_BYTES_PER_WORD];
  159. u32 header_len;
  160. u16 api_revision;
  161. u8 target_core;
  162. u8 file_format_version;
  163. u32 xm_size;
  164. u32 ym_size;
  165. u32 pm_size;
  166. u32 zm_size;
  167. u32 timestamp[2];
  168. u32 checksum;
  169. } __attribute__((__packed__));
  170. u8 data[CL_DSP_FW_FILE_HEADER_SIZE];
  171. };
  172. union cl_dsp_data_block_header {
  173. struct {
  174. u32 start_offset : 24;
  175. u8 block_type;
  176. u32 data_len;
  177. } __attribute__((__packed__));
  178. u8 data[CL_DSP_DBLK_HEADER_SIZE];
  179. };
  180. union cl_dsp_coeff_data_block_header {
  181. struct {
  182. u16 start_offset;
  183. u16 block_type;
  184. u32 algo_id;
  185. u32 algo_rev;
  186. u32 sample_rate;
  187. u32 data_len;
  188. } __attribute__((__packed__));
  189. u8 data[CL_DSP_COEFF_DBLK_HEADER_SIZE];
  190. };
  191. struct cl_dsp_data_block {
  192. union cl_dsp_data_block_header header;
  193. u8 *payload;
  194. };
  195. struct cl_dsp_coeff_data_block {
  196. union cl_dsp_coeff_data_block_header header;
  197. u8 *payload;
  198. };
  199. struct cl_dsp_coeff_desc {
  200. u32 parent_id;
  201. char *parent_name;
  202. u16 block_offset;
  203. u16 block_type;
  204. unsigned char name[CL_DSP_COEFF_NAME_LEN_MAX];
  205. unsigned int reg;
  206. unsigned int flags;
  207. unsigned int length;
  208. struct list_head list;
  209. };
  210. struct cl_dsp_memchunk {
  211. u8 *data;
  212. u8 *max;
  213. int bytes;
  214. u32 cache;
  215. int cachebits;
  216. };
  217. struct cl_dsp_owt_header {
  218. enum cl_dsp_wt_type type;
  219. u16 flags;
  220. u32 offset;
  221. u32 size;
  222. void *data;
  223. };
  224. struct cl_dsp_owt_desc {
  225. struct cl_dsp_owt_header waves[CL_DSP_OWT_HEADER_MAX_LEN];
  226. int nwaves;
  227. int bytes;
  228. u8 *raw_data;
  229. };
  230. struct cl_dsp_wt_desc {
  231. unsigned int id;
  232. char wt_name_xm[CL_DSP_WMDR_NAME_LEN];
  233. char wt_name_ym[CL_DSP_WMDR_NAME_LEN];
  234. unsigned int wt_limit_xm;
  235. unsigned int wt_limit_ym;
  236. char wt_file[CL_DSP_WMDR_NAME_LEN];
  237. char wt_date[CL_DSP_WMDR_DATE_LEN];
  238. struct cl_dsp_owt_desc owt;
  239. bool is_xm;
  240. };
  241. struct cl_dsp_algo_info {
  242. unsigned int id;
  243. unsigned int rev;
  244. unsigned int xm_base;
  245. unsigned int xm_size;
  246. unsigned int ym_base;
  247. unsigned int ym_size;
  248. };
  249. struct cl_dsp {
  250. struct device *dev;
  251. struct regmap *regmap;
  252. struct list_head coeff_desc_head;
  253. unsigned int num_algos;
  254. struct cl_dsp_algo_info algo_info[CL_DSP_NUM_ALGOS_MAX + 1];
  255. const struct cl_dsp_fw_desc *fw_desc;
  256. const struct cl_dsp_mem_reg_desc *mem_reg_desc;
  257. const struct cl_dsp_algo_params *algo_params;
  258. struct cl_dsp_wt_desc *wt_desc;
  259. };
  260. #ifdef CONFIG_DEBUG_FS
  261. /* Debug Logger */
  262. struct cl_dsp_host_buffer {
  263. __be32 buf1_base;
  264. __be32 buf1_size;
  265. __be32 buf2_base;
  266. __be32 buf1_buf2_size;
  267. __be32 buf3_base;
  268. __be32 buf_total_size;
  269. __be32 high_water_mark;
  270. __be32 irq_count;
  271. __be32 irq_ack;
  272. __be32 next_write_index;
  273. __be32 next_read_index;
  274. __be32 error;
  275. __be32 oldest_block_index;
  276. __be32 requested_rewind;
  277. __be32 reserved_space;
  278. __be32 min_free;
  279. __be32 blocks_written[2];
  280. __be32 words_written[2];
  281. } __packed;
  282. struct cl_dsp_logger {
  283. u32 *buf_data;
  284. u32 buf_data_size;
  285. u32 algo_id;
  286. u32 host_buf_ptr;
  287. u32 host_buf_base;
  288. int host_buf_size_words;
  289. u32 high_watermark;
  290. };
  291. struct cl_dsp_debugfs {
  292. struct cl_dsp *core;
  293. struct dentry *debugfs_root;
  294. struct dentry *debugfs_node;
  295. struct mutex lock;
  296. struct cl_dsp_logger dl;
  297. };
  298. #define CL_DSP_DEBUGFS_NUM_CONTROLS 3
  299. #define CL_DSP_DEBUGFS_RW_FILE_MODE 0600
  300. #define CL_DSP_DEBUGFS_RO_FILE_MODE 0400
  301. #define CL_DSP_DEBUGFS_WO_FILE_MOADE 0200
  302. #define CL_DSP_DEBUGFS_TRACE_LOG_STRING_SIZE 3
  303. #define CL_DSP_DEBUGFS_TRACE_LOG_DISABLE 0
  304. #define CL_DSP_DEBUGFS_TRACE_LOG_ENABLE 1
  305. #define CL_DSP_HOST_BUFFER_DATA_MASK 0x00FFFFFFu
  306. #define CL_DSP_HOST_BUFFER_ERROR_OVERFLOW BIT(0)
  307. #define CL_DSP_HOST_BUFFER_READ_INDEX_RESET 0x00FFFFFF
  308. #define CL_DSP_HOST_BUFFER_IRQ_MASK BIT(0)
  309. #define CL_DSP_HOST_BUFFER_DATA_SLOT_SIZE 10
  310. #define HOST_BUFFER_FIELD(field) \
  311. (offsetof(struct cl_dsp_host_buffer, field) / sizeof(__be32))
  312. int cl_dsp_logger_update(struct cl_dsp_debugfs *db);
  313. struct cl_dsp_debugfs *cl_dsp_debugfs_create(struct cl_dsp *dsp,
  314. struct dentry *parent_node, u32 event_log_algo_id);
  315. void cl_dsp_debugfs_destroy(struct cl_dsp_debugfs *db);
  316. #endif /* CONFIG_DEBUG_FS */
  317. /* Exported Functions */
  318. struct cl_dsp *cl_dsp_create(struct device *dev, struct regmap *regmap);
  319. int cl_dsp_destroy(struct cl_dsp *dsp);
  320. int cl_dsp_wavetable_create(struct cl_dsp *dsp, unsigned int id,
  321. const char *wt_name_xm, const char *wt_name_ym,
  322. const char *wt_file);
  323. int cl_dsp_firmware_parse(struct cl_dsp *dsp, const struct firmware *fw,
  324. bool write_fw);
  325. int cl_dsp_coeff_file_parse(struct cl_dsp *dsp, const struct firmware *fw);
  326. int cl_dsp_get_reg(struct cl_dsp *dsp, const char *coeff_name,
  327. const unsigned int block_type, const unsigned int algo_id,
  328. unsigned int *reg);
  329. bool cl_dsp_algo_is_present(struct cl_dsp *dsp, const unsigned int algo_id);
  330. struct cl_dsp_memchunk cl_dsp_memchunk_create(void *data, int size);
  331. int cl_dsp_memchunk_write(struct cl_dsp_memchunk *ch, int nbits, u32 val);
  332. int cl_dsp_memchunk_read(struct cl_dsp *dsp, struct cl_dsp_memchunk *ch,
  333. int nbits, void *val);
  334. int cl_dsp_memchunk_flush(struct cl_dsp_memchunk *ch);
  335. int cl_dsp_raw_write(struct cl_dsp *dsp, unsigned int reg,
  336. const void *val, size_t val_len, size_t limit);
  337. int cl_dsp_fw_id_get(struct cl_dsp *dsp, unsigned int *id);
  338. int cl_dsp_fw_rev_get(struct cl_dsp *dsp, unsigned int *rev);
  339. #endif /* __CL_DSP_H */