1 /* 2 * Copyright (c) 2022 Intel Corporation. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef __INTEL_DAI_DRIVER_SSP_H__ 8 #define __INTEL_DAI_DRIVER_SSP_H__ 9 10 #include <stdint.h> 11 #include <zephyr/drivers/dai.h> 12 #include "dai-params-intel-ipc3.h" 13 #include "dai-params-intel-ipc4.h" 14 15 #define DAI_INTEL_SSP_MASK(b_hi, b_lo) \ 16 (((1ULL << ((b_hi) - (b_lo) + 1ULL)) - 1ULL) << (b_lo)) 17 #define DAI_INTEL_SSP_SET_BIT(b, x) (((x) & 1) << (b)) 18 #define DAI_INTEL_SSP_SET_BITS(b_hi, b_lo, x) \ 19 (((x) & ((1ULL << ((b_hi) - (b_lo) + 1ULL)) - 1ULL)) << (b_lo)) 20 #define DAI_INTEL_SSP_GET_BIT(b, x) \ 21 (((x) & (1ULL << (b))) >> (b)) 22 #define DAI_INTEL_SSP_GET_BITS(b_hi, b_lo, x) \ 23 (((x) & MASK(b_hi, b_lo)) >> (b_lo)) 24 #define DAI_INTEL_SSP_IS_BIT_SET(reg, bit) (((reg >> bit) & (0x1)) != 0) 25 26 /* ssp_freq array constants */ 27 #define DAI_INTEL_SSP_NUM_FREQ 3 28 #define DAI_INTEL_SSP_MAX_FREQ_INDEX (DAI_INTEL_SSP_NUM_FREQ - 1) 29 #define DAI_INTEL_SSP_DEFAULT_IDX 1 30 31 /* the SSP port fifo depth */ 32 #define DAI_INTEL_SSP_FIFO_DEPTH 32 33 34 /* the watermark for the SSP fifo depth setting */ 35 #define DAI_INTEL_SSP_FIFO_WATERMARK 8 36 37 /* minimal SSP port delay in cycles */ 38 #define DAI_INTEL_SSP_PLATFORM_DELAY 1600 39 /* minimal SSP port delay in useconds */ 40 #define DAI_INTEL_SSP_PLATFORM_DELAY_US 42 41 #define DAI_INTEL_SSP_PLATFORM_DEFAULT_DELAY 12 42 #define DAI_INTEL_SSP_DEFAULT_TRY_TIMES 8 43 44 /** \brief Number of SSP MCLKs available */ 45 #define DAI_INTEL_SSP_NUM_MCLK 2 46 47 #define DAI_INTEL_SSP_CLOCK_XTAL_OSCILLATOR 0x0 48 #define DAI_INTEL_SSP_CLOCK_AUDIO_CARDINAL 0x1 49 #define DAI_INTEL_SSP_CLOCK_PLL_FIXED 0x2 50 51 #if defined(CONFIG_SOC_INTEL_ACE15_MTPM) || defined(CONFIG_SOC_SERIES_INTEL_ADSP_CAVS) 52 #include "ssp_regs_v1.h" 53 #elif defined(CONFIG_SOC_INTEL_ACE20_LNL) 54 #include "ssp_regs_v2.h" 55 #elif defined(CONFIG_SOC_INTEL_ACE30_PTL) 56 #include "ssp_regs_v3.h" 57 #else 58 #error "Missing ssp definitions" 59 #endif 60 61 #if CONFIG_INTEL_MN 62 /** \brief BCLKs can be driven by multiple sources - M/N or XTAL directly. 63 * Even in the case of M/N, the actual clock source can be XTAL, 64 * Audio cardinal clock (24.576) or 96 MHz PLL. 65 * The MN block is not really the source of clocks, but rather 66 * an intermediate component. 67 * Input for source is shared by all outputs coming from that source 68 * and once it's in use, it can be adjusted only with dividers. 69 * In order to change input, the source should not be in use, that's why 70 * it's necessary to keep track of BCLKs sources to know when it's safe 71 * to change shared input clock. 72 */ 73 enum bclk_source { 74 MN_BCLK_SOURCE_NONE = 0, /**< port is not using any clock */ 75 MN_BCLK_SOURCE_MN, /**< port is using clock driven by M/N */ 76 MN_BCLK_SOURCE_XTAL, /**< port is using XTAL directly */ 77 }; 78 #endif 79 80 struct dai_intel_ssp_mn { 81 uint32_t base; 82 /**< keep track of which MCLKs are in use to know when it's safe to 83 * change shared clock 84 */ 85 int mclk_sources_ref[DAI_INTEL_SSP_NUM_MCLK]; 86 int mclk_rate[DAI_INTEL_SSP_NUM_MCLK]; 87 int mclk_source_clock; 88 89 #if CONFIG_INTEL_MN 90 enum bclk_source bclk_sources[(CONFIG_DAI_INTEL_SSP_NUM_BASE + 91 CONFIG_DAI_INTEL_SSP_NUM_EXT)]; 92 int bclk_source_mn_clock; 93 #endif 94 95 struct k_spinlock lock; /**< lock mechanism */ 96 }; 97 98 struct dai_intel_ssp_freq_table { 99 uint32_t freq; 100 uint32_t ticks_per_msec; 101 }; 102 103 struct dai_intel_ssp_plat_fifo_data { 104 uint32_t offset; 105 uint32_t width; 106 uint32_t depth; 107 uint32_t watermark; 108 uint32_t handshake; 109 }; 110 111 struct dai_intel_ssp_plat_data { 112 uint32_t ssp_index; 113 int acquire_count; 114 bool is_initialized; 115 bool is_power_en; 116 uint32_t base; 117 uint32_t ip_base; 118 uint32_t shim_base; 119 #if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL) 120 uint32_t hdamlssp_base; 121 uint32_t i2svss_base; 122 #endif 123 int irq; 124 const char *irq_name; 125 uint32_t flags; 126 struct dai_intel_ssp_plat_fifo_data fifo[2]; 127 struct dai_intel_ssp_mn *mn_inst; 128 struct dai_intel_ssp_freq_table *ftable; 129 uint32_t *fsources; 130 uint32_t clk_active; 131 struct dai_intel_ipc3_ssp_params params; 132 }; 133 134 struct dai_intel_ssp_pdata { 135 uint32_t sscr0; 136 uint32_t sscr1; 137 uint32_t psp; 138 struct dai_config config; 139 struct dai_properties props; 140 }; 141 142 struct dai_intel_ssp { 143 uint32_t dai_index; 144 uint32_t ssp_index; 145 uint32_t tdm_slot_group; 146 uint32_t state[2]; 147 struct k_spinlock lock; /**< locking mechanism */ 148 int sref; /**< simple ref counter, guarded by lock */ 149 struct dai_intel_ssp_plat_data *ssp_plat_data; 150 void *priv_data; 151 }; 152 153 #endif 154