154 lines
4.3 KiB
C
154 lines
4.3 KiB
C
/*
|
|
* Copyright (c) 2022 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef __INTEL_DAI_DRIVER_SSP_H__
|
|
#define __INTEL_DAI_DRIVER_SSP_H__
|
|
|
|
#include <stdint.h>
|
|
#include <zephyr/drivers/dai.h>
|
|
#include "dai-params-intel-ipc3.h"
|
|
#include "dai-params-intel-ipc4.h"
|
|
|
|
#define DAI_INTEL_SSP_MASK(b_hi, b_lo) \
|
|
(((1ULL << ((b_hi) - (b_lo) + 1ULL)) - 1ULL) << (b_lo))
|
|
#define DAI_INTEL_SSP_SET_BIT(b, x) (((x) & 1) << (b))
|
|
#define DAI_INTEL_SSP_SET_BITS(b_hi, b_lo, x) \
|
|
(((x) & ((1ULL << ((b_hi) - (b_lo) + 1ULL)) - 1ULL)) << (b_lo))
|
|
#define DAI_INTEL_SSP_GET_BIT(b, x) \
|
|
(((x) & (1ULL << (b))) >> (b))
|
|
#define DAI_INTEL_SSP_GET_BITS(b_hi, b_lo, x) \
|
|
(((x) & MASK(b_hi, b_lo)) >> (b_lo))
|
|
#define DAI_INTEL_SSP_IS_BIT_SET(reg, bit) (((reg >> bit) & (0x1)) != 0)
|
|
|
|
/* ssp_freq array constants */
|
|
#define DAI_INTEL_SSP_NUM_FREQ 3
|
|
#define DAI_INTEL_SSP_MAX_FREQ_INDEX (DAI_INTEL_SSP_NUM_FREQ - 1)
|
|
#define DAI_INTEL_SSP_DEFAULT_IDX 1
|
|
|
|
/* the SSP port fifo depth */
|
|
#define DAI_INTEL_SSP_FIFO_DEPTH 32
|
|
|
|
/* the watermark for the SSP fifo depth setting */
|
|
#define DAI_INTEL_SSP_FIFO_WATERMARK 8
|
|
|
|
/* minimal SSP port delay in cycles */
|
|
#define DAI_INTEL_SSP_PLATFORM_DELAY 1600
|
|
/* minimal SSP port delay in useconds */
|
|
#define DAI_INTEL_SSP_PLATFORM_DELAY_US 42
|
|
#define DAI_INTEL_SSP_PLATFORM_DEFAULT_DELAY 12
|
|
#define DAI_INTEL_SSP_DEFAULT_TRY_TIMES 8
|
|
|
|
/** \brief Number of SSP MCLKs available */
|
|
#define DAI_INTEL_SSP_NUM_MCLK 2
|
|
|
|
#define DAI_INTEL_SSP_CLOCK_XTAL_OSCILLATOR 0x0
|
|
#define DAI_INTEL_SSP_CLOCK_AUDIO_CARDINAL 0x1
|
|
#define DAI_INTEL_SSP_CLOCK_PLL_FIXED 0x2
|
|
|
|
#if defined(CONFIG_SOC_INTEL_ACE15_MTPM) || defined(CONFIG_SOC_SERIES_INTEL_ADSP_CAVS)
|
|
#include "ssp_regs_v1.h"
|
|
#elif defined(CONFIG_SOC_INTEL_ACE20_LNL)
|
|
#include "ssp_regs_v2.h"
|
|
#elif defined(CONFIG_SOC_INTEL_ACE30)
|
|
#include "ssp_regs_v3.h"
|
|
#else
|
|
#error "Missing ssp definitions"
|
|
#endif
|
|
|
|
#if CONFIG_INTEL_MN
|
|
/** \brief BCLKs can be driven by multiple sources - M/N or XTAL directly.
|
|
* Even in the case of M/N, the actual clock source can be XTAL,
|
|
* Audio cardinal clock (24.576) or 96 MHz PLL.
|
|
* The MN block is not really the source of clocks, but rather
|
|
* an intermediate component.
|
|
* Input for source is shared by all outputs coming from that source
|
|
* and once it's in use, it can be adjusted only with dividers.
|
|
* In order to change input, the source should not be in use, that's why
|
|
* it's necessary to keep track of BCLKs sources to know when it's safe
|
|
* to change shared input clock.
|
|
*/
|
|
enum bclk_source {
|
|
MN_BCLK_SOURCE_NONE = 0, /**< port is not using any clock */
|
|
MN_BCLK_SOURCE_MN, /**< port is using clock driven by M/N */
|
|
MN_BCLK_SOURCE_XTAL, /**< port is using XTAL directly */
|
|
};
|
|
#endif
|
|
|
|
struct dai_intel_ssp_mn {
|
|
uint32_t base;
|
|
/**< keep track of which MCLKs are in use to know when it's safe to
|
|
* change shared clock
|
|
*/
|
|
int mclk_sources_ref[DAI_INTEL_SSP_NUM_MCLK];
|
|
int mclk_rate[DAI_INTEL_SSP_NUM_MCLK];
|
|
int mclk_source_clock;
|
|
|
|
#if CONFIG_INTEL_MN
|
|
enum bclk_source bclk_sources[(CONFIG_DAI_INTEL_SSP_NUM_BASE +
|
|
CONFIG_DAI_INTEL_SSP_NUM_EXT)];
|
|
int bclk_source_mn_clock;
|
|
#endif
|
|
|
|
struct k_spinlock lock; /**< lock mechanism */
|
|
};
|
|
|
|
struct dai_intel_ssp_freq_table {
|
|
uint32_t freq;
|
|
uint32_t ticks_per_msec;
|
|
};
|
|
|
|
struct dai_intel_ssp_plat_fifo_data {
|
|
uint32_t offset;
|
|
uint32_t width;
|
|
uint32_t depth;
|
|
uint32_t watermark;
|
|
uint32_t handshake;
|
|
};
|
|
|
|
struct dai_intel_ssp_plat_data {
|
|
uint32_t ssp_index;
|
|
int acquire_count;
|
|
bool is_initialized;
|
|
bool is_power_en;
|
|
uint32_t base;
|
|
uint32_t ip_base;
|
|
uint32_t shim_base;
|
|
#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30)
|
|
uint32_t hdamlssp_base;
|
|
uint32_t i2svss_base;
|
|
#endif
|
|
int irq;
|
|
const char *irq_name;
|
|
uint32_t flags;
|
|
struct dai_intel_ssp_plat_fifo_data fifo[2];
|
|
struct dai_intel_ssp_mn *mn_inst;
|
|
struct dai_intel_ssp_freq_table *ftable;
|
|
uint32_t *fsources;
|
|
uint32_t clk_active;
|
|
struct dai_intel_ipc3_ssp_params params;
|
|
};
|
|
|
|
struct dai_intel_ssp_pdata {
|
|
uint32_t sscr0;
|
|
uint32_t sscr1;
|
|
uint32_t psp;
|
|
struct dai_config config;
|
|
struct dai_properties props;
|
|
};
|
|
|
|
struct dai_intel_ssp {
|
|
uint32_t dai_index;
|
|
uint32_t ssp_index;
|
|
uint32_t tdm_slot_group;
|
|
uint32_t state[2];
|
|
struct k_spinlock lock; /**< locking mechanism */
|
|
int sref; /**< simple ref counter, guarded by lock */
|
|
struct dai_intel_ssp_plat_data *ssp_plat_data;
|
|
void *priv_data;
|
|
};
|
|
|
|
#endif
|