2019-05-01 18:57:25 +03:00
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* Copyright(c) 2015-17 Intel Corporation. */
2018-04-26 16:08:53 +03:00
# include <sound/soc.h>
2017-12-14 08:49:41 +03:00
# ifndef __SDW_CADENCE_H
# define __SDW_CADENCE_H
2020-03-17 19:33:22 +03:00
# define SDW_CADENCE_GSYNC_KHZ 4 /* 4 kHz */
# define SDW_CADENCE_GSYNC_HZ (SDW_CADENCE_GSYNC_KHZ * 1000)
2022-12-02 19:18:11 +03:00
/*
* The Cadence IP supports up to 32 entries in the FIFO , though implementations
* can configure the IP to have a smaller FIFO .
*/
# define CDNS_MCP_IP_MAX_CMD_LEN 32
2018-04-26 16:08:48 +03:00
/**
* struct sdw_cdns_pdi : PDI ( Physical Data Interface ) instance
*
* @ num : pdi number
* @ intel_alh_id : link identifier
* @ l_ch_num : low channel for PDI
* @ h_ch_num : high channel for PDI
* @ ch_count : total channel count for PDI
* @ dir : data direction
2021-12-24 05:10:34 +03:00
* @ type : stream type , ( only PCM supported )
2018-04-26 16:08:48 +03:00
*/
struct sdw_cdns_pdi {
int num ;
int intel_alh_id ;
int l_ch_num ;
int h_ch_num ;
int ch_count ;
enum sdw_data_direction dir ;
enum sdw_stream_type type ;
} ;
/**
* struct sdw_cdns_streams : Cadence stream data structure
*
* @ num_bd : number of bidirectional streams
* @ num_in : number of input streams
* @ num_out : number of output streams
* @ num_ch_bd : number of bidirectional stream channels
* @ num_ch_bd : number of input stream channels
* @ num_ch_bd : number of output stream channels
* @ num_pdi : total number of PDIs
* @ bd : bidirectional streams
* @ in : input streams
* @ out : output streams
*/
struct sdw_cdns_streams {
unsigned int num_bd ;
unsigned int num_in ;
unsigned int num_out ;
unsigned int num_ch_bd ;
unsigned int num_ch_in ;
unsigned int num_ch_out ;
unsigned int num_pdi ;
struct sdw_cdns_pdi * bd ;
struct sdw_cdns_pdi * in ;
struct sdw_cdns_pdi * out ;
} ;
/**
* struct sdw_cdns_stream_config : stream configuration
*
* @ pcm_bd : number of bidirectional PCM streams supported
* @ pcm_in : number of input PCM streams supported
* @ pcm_out : number of output PCM streams supported
*/
struct sdw_cdns_stream_config {
unsigned int pcm_bd ;
unsigned int pcm_in ;
unsigned int pcm_out ;
} ;
2018-04-26 16:08:53 +03:00
/**
2022-11-01 05:35:20 +03:00
* struct sdw_cdns_dai_runtime : Cadence DAI runtime data
2018-04-26 16:08:53 +03:00
*
* @ name : SoundWire stream name
2019-09-16 22:23:46 +03:00
* @ stream : stream runtime
* @ pdi : PDI used for this dai
2018-04-26 16:08:53 +03:00
* @ bus : Bus handle
* @ stream_type : Stream type
* @ link_id : Master link id
soundwire: intel: reinitialize IP+DSP in .prepare(), but only when resuming
The .prepare() callback is invoked for normal streaming, underflows or
during the system resume transition. In the latter case, the context
for the ALH PDIs is lost, and the DSP is not initialized properly
either, but the bus parameters don't need to be recomputed.
Conversely, when doing a regular .prepare() during an underflow, the
ALH/SHIM registers shall not be changed as the hardware cannot be
reprogrammed after the DMA started (hardware spec requirement).
This patch adds storage of PDI and hw_params in the DAI dma context,
and the difference between the types of .prepare() usages is handled
via a simple boolean, updated when suspending, and tested for in the
.prepare() case.
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200817152923.3259-6-yung-chuan.liao@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
2020-08-17 18:29:16 +03:00
* @ suspended : status set when suspended , to be used in . prepare
2021-12-24 05:10:30 +03:00
* @ paused : status set in . trigger , to be used in suspend
2022-11-01 05:35:21 +03:00
* @ direction : stream direction
2018-04-26 16:08:53 +03:00
*/
2022-11-01 05:35:20 +03:00
struct sdw_cdns_dai_runtime {
2018-04-26 16:08:53 +03:00
char * name ;
struct sdw_stream_runtime * stream ;
2019-09-16 22:23:46 +03:00
struct sdw_cdns_pdi * pdi ;
2018-04-26 16:08:53 +03:00
struct sdw_bus * bus ;
enum sdw_stream_type stream_type ;
int link_id ;
soundwire: intel: reinitialize IP+DSP in .prepare(), but only when resuming
The .prepare() callback is invoked for normal streaming, underflows or
during the system resume transition. In the latter case, the context
for the ALH PDIs is lost, and the DSP is not initialized properly
either, but the bus parameters don't need to be recomputed.
Conversely, when doing a regular .prepare() during an underflow, the
ALH/SHIM registers shall not be changed as the hardware cannot be
reprogrammed after the DMA started (hardware spec requirement).
This patch adds storage of PDI and hw_params in the DAI dma context,
and the difference between the types of .prepare() usages is handled
via a simple boolean, updated when suspending, and tested for in the
.prepare() case.
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200817152923.3259-6-yung-chuan.liao@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
2020-08-17 18:29:16 +03:00
bool suspended ;
2021-12-24 05:10:30 +03:00
bool paused ;
2022-11-01 05:35:21 +03:00
int direction ;
2018-04-26 16:08:53 +03:00
} ;
2017-12-14 08:49:41 +03:00
/**
* struct sdw_cdns - Cadence driver context
* @ dev : Linux device
* @ bus : Bus handle
* @ instance : instance number
2023-03-14 04:54:06 +03:00
* @ ip_offset : version - dependent offset to access IP_MCP registers and fields
2017-12-14 08:49:42 +03:00
* @ response_buf : SoundWire response buffer
* @ tx_complete : Tx completion
2018-04-26 16:08:48 +03:00
* @ ports : Data ports
* @ num_ports : Total number of data ports
* @ pcm : PCM streams
2017-12-14 08:49:41 +03:00
* @ registers : Cadence registers
* @ link_up : Link status
2017-12-14 08:49:42 +03:00
* @ msg_count : Messages sent on bus
2022-11-01 05:35:21 +03:00
* @ dai_runtime_array : runtime context for each allocated DAI .
2017-12-14 08:49:41 +03:00
*/
struct sdw_cdns {
struct device * dev ;
struct sdw_bus bus ;
unsigned int instance ;
2023-03-14 04:54:06 +03:00
u32 ip_offset ;
2022-12-02 19:18:11 +03:00
/*
* The datasheet says the RX FIFO AVAIL can be 2 entries more
* than the FIFO capacity , so allow for this .
*/
u32 response_buf [ CDNS_MCP_IP_MAX_CMD_LEN + 2 ] ;
2017-12-14 08:49:42 +03:00
struct completion tx_complete ;
2018-04-26 16:08:48 +03:00
struct sdw_cdns_port * ports ;
int num_ports ;
struct sdw_cdns_streams pcm ;
2021-07-14 06:22:08 +03:00
int pdi_loopback_source ;
int pdi_loopback_target ;
2017-12-14 08:49:41 +03:00
void __iomem * registers ;
bool link_up ;
2017-12-14 08:49:42 +03:00
unsigned int msg_count ;
2020-08-18 01:23:40 +03:00
bool interrupt_enabled ;
2020-07-16 18:09:45 +03:00
struct work_struct work ;
struct list_head list ;
2022-11-01 05:35:21 +03:00
struct sdw_cdns_dai_runtime * * dai_runtime_array ;
2017-12-14 08:49:41 +03:00
} ;
# define bus_to_cdns(_bus) container_of(_bus, struct sdw_cdns, bus)
/* Exported symbols */
2017-12-14 08:49:42 +03:00
int sdw_cdns_probe ( struct sdw_cdns * cdns ) ;
2017-12-14 08:49:41 +03:00
irqreturn_t sdw_cdns_irq ( int irq , void * dev_id ) ;
irqreturn_t sdw_cdns_thread ( int irq , void * dev_id ) ;
2020-03-17 19:33:14 +03:00
int sdw_cdns_init ( struct sdw_cdns * cdns ) ;
2018-04-26 16:08:48 +03:00
int sdw_cdns_pdi_init ( struct sdw_cdns * cdns ,
2019-05-01 18:57:26 +03:00
struct sdw_cdns_stream_config config ) ;
2019-10-23 02:54:44 +03:00
int sdw_cdns_exit_reset ( struct sdw_cdns * cdns ) ;
2019-10-23 02:54:47 +03:00
int sdw_cdns_enable_interrupt ( struct sdw_cdns * cdns , bool state ) ;
2017-12-14 08:49:42 +03:00
2020-03-17 19:33:15 +03:00
bool sdw_cdns_is_clock_stop ( struct sdw_cdns * cdns ) ;
2020-03-17 19:33:17 +03:00
int sdw_cdns_clock_stop ( struct sdw_cdns * cdns , bool block_wake ) ;
int sdw_cdns_clock_restart ( struct sdw_cdns * cdns , bool bus_reset ) ;
2020-03-17 19:33:15 +03:00
2019-08-21 21:58:19 +03:00
# ifdef CONFIG_DEBUG_FS
void sdw_cdns_debugfs_init ( struct sdw_cdns * cdns , struct dentry * root ) ;
# endif
2019-09-16 22:23:46 +03:00
struct sdw_cdns_pdi * sdw_cdns_alloc_pdi ( struct sdw_cdns * cdns ,
struct sdw_cdns_streams * stream ,
2019-09-16 22:23:48 +03:00
u32 ch , u32 dir , int dai_id ) ;
2019-09-16 22:23:46 +03:00
void sdw_cdns_config_stream ( struct sdw_cdns * cdns ,
2019-05-01 18:57:26 +03:00
u32 ch , u32 dir , struct sdw_cdns_pdi * pdi ) ;
2018-04-26 16:08:53 +03:00
2018-04-26 16:08:43 +03:00
enum sdw_command_response
cdns_xfer_msg ( struct sdw_bus * bus , struct sdw_msg * msg ) ;
2017-12-14 08:49:41 +03:00
2018-04-26 16:08:43 +03:00
enum sdw_command_response
2023-01-19 10:32:11 +03:00
cdns_xfer_msg_defer ( struct sdw_bus * bus ) ;
2018-04-26 16:08:43 +03:00
2022-07-14 04:10:41 +03:00
u32 cdns_read_ping_status ( struct sdw_bus * bus ) ;
2018-04-26 16:08:48 +03:00
int cdns_bus_conf ( struct sdw_bus * bus , struct sdw_bus_params * params ) ;
2018-04-26 16:08:53 +03:00
int cdns_set_sdw_stream ( struct snd_soc_dai * dai ,
2021-12-24 05:10:34 +03:00
void * stream , int direction ) ;
2021-07-14 08:13:49 +03:00
void sdw_cdns_check_self_clearing_bits ( struct sdw_cdns * cdns , const char * string ,
bool initial_delay , int reset_iterations ) ;
2017-12-14 08:49:41 +03:00
# endif /* __SDW_CADENCE_H */