^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright(c) 2015-17 Intel Corporation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #ifndef __SDW_CADENCE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #define __SDW_CADENCE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define SDW_CADENCE_GSYNC_KHZ 4 /* 4 kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define SDW_CADENCE_GSYNC_HZ (SDW_CADENCE_GSYNC_KHZ * 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * @num: pdi number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * @intel_alh_id: link identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * @l_ch_num: low channel for PDI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * @h_ch_num: high channel for PDI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * @ch_count: total channel count for PDI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * @dir: data direction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * @type: stream type, PDM or PCM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct sdw_cdns_pdi {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) int intel_alh_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) int l_ch_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int h_ch_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int ch_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) enum sdw_data_direction dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) enum sdw_stream_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * struct sdw_cdns_streams: Cadence stream data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * @num_bd: number of bidirectional streams
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * @num_in: number of input streams
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * @num_out: number of output streams
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * @num_ch_bd: number of bidirectional stream channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * @num_ch_bd: number of input stream channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * @num_ch_bd: number of output stream channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * @num_pdi: total number of PDIs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * @bd: bidirectional streams
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * @in: input streams
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @out: output streams
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct sdw_cdns_streams {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned int num_bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned int num_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned int num_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) unsigned int num_ch_bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) unsigned int num_ch_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned int num_ch_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned int num_pdi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct sdw_cdns_pdi *bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct sdw_cdns_pdi *in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct sdw_cdns_pdi *out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * struct sdw_cdns_stream_config: stream configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * @pcm_bd: number of bidirectional PCM streams supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @pcm_in: number of input PCM streams supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * @pcm_out: number of output PCM streams supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * @pdm_bd: number of bidirectional PDM streams supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * @pdm_in: number of input PDM streams supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * @pdm_out: number of output PDM streams supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct sdw_cdns_stream_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned int pcm_bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned int pcm_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned int pcm_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned int pdm_bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) unsigned int pdm_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) unsigned int pdm_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * struct sdw_cdns_dma_data: Cadence DMA data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * @name: SoundWire stream name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * @stream: stream runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * @pdi: PDI used for this dai
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * @bus: Bus handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * @stream_type: Stream type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * @link_id: Master link id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @hw_params: hw_params to be applied in .prepare step
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * @suspended: status set when suspended, to be used in .prepare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct sdw_cdns_dma_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct sdw_stream_runtime *stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct sdw_cdns_pdi *pdi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct sdw_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) enum sdw_stream_type stream_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int link_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct snd_pcm_hw_params *hw_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) bool suspended;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * struct sdw_cdns - Cadence driver context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * @dev: Linux device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @bus: Bus handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @instance: instance number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @response_buf: SoundWire response buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @tx_complete: Tx completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * @defer: Defer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * @ports: Data ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * @num_ports: Total number of data ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * @pcm: PCM streams
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @pdm: PDM streams
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @registers: Cadence registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * @link_up: Link status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * @msg_count: Messages sent on bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct sdw_cdns {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct sdw_bus bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) unsigned int instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) u32 response_buf[0x80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct completion tx_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct sdw_defer *defer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct sdw_cdns_port *ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int num_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct sdw_cdns_streams pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct sdw_cdns_streams pdm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) void __iomem *registers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) bool link_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned int msg_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) bool interrupt_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct work_struct work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define bus_to_cdns(_bus) container_of(_bus, struct sdw_cdns, bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Exported symbols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) int sdw_cdns_probe(struct sdw_cdns *cdns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) extern struct sdw_master_ops sdw_cdns_master_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) irqreturn_t sdw_cdns_irq(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int sdw_cdns_init(struct sdw_cdns *cdns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct sdw_cdns_stream_config config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) bool sdw_cdns_is_clock_stop(struct sdw_cdns *cdns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct sdw_cdns_streams *stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u32 ch, u32 dir, int dai_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) void sdw_cdns_config_stream(struct sdw_cdns *cdns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u32 ch, u32 dir, struct sdw_cdns_pdi *pdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) enum sdw_command_response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) enum sdw_command_response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) enum sdw_command_response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) cdns_xfer_msg_defer(struct sdw_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct sdw_msg *msg, struct sdw_defer *defer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) enum sdw_command_response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int cdns_set_sdw_stream(struct snd_soc_dai *dai,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) void *stream, bool pcm, int direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #endif /* __SDW_CADENCE_H */