Skip to content

Commit a7e9be6

Browse files
dnikodemaescolar
authored andcommitted
driver: ssp: reorganize ssp ip acquired flow
The previous port acquire/release functions have been removed, and a new IP acquire/release mechanism has been introduced. Additionally, the RX FIFO clearing function for PTL has been corrected. Signed-off-by: Damian Nikodem <[email protected]>
1 parent 7c64a8b commit a7e9be6

File tree

1 file changed

+75
-104
lines changed
  • drivers/dai/intel/ssp

1 file changed

+75
-104
lines changed

drivers/dai/intel/ssp/ssp.c

Lines changed: 75 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -112,24 +112,6 @@ static struct dai_intel_ssp_plat_data *ssp_get_device_instance(uint32_t ssp_inde
112112
return NULL;
113113
}
114114

115-
static void ssp_acquire_port(struct dai_intel_ssp_plat_data *ssp)
116-
{
117-
ssp->acquire_count++;
118-
}
119-
120-
static void ssp_release_port(struct dai_intel_ssp_plat_data *ssp)
121-
{
122-
if (ssp->acquire_count == 0) {
123-
return;
124-
}
125-
126-
--ssp->acquire_count;
127-
}
128-
129-
static bool ssp_is_acquired(struct dai_intel_ssp_plat_data *ssp)
130-
{
131-
return (ssp->acquire_count != 0);
132-
}
133115

134116
static void dai_ssp_update_bits(struct dai_intel_ssp *dp, uint32_t reg, uint32_t mask, uint32_t val)
135117
{
@@ -1009,43 +991,38 @@ static void ssp_empty_rx_fifo_on_stop(struct dai_intel_ssp *dp)
1009991
uint32_t i, sssr, ssmidycs;
1010992
uint32_t entries[2];
1011993

1012-
if (ssp_is_acquired(dp->ssp_plat_data)) {
1013-
return;
1014-
}
1015-
1016994
sssr = sys_read32(dai_base(dp) + SSSR);
1017995

1018-
for (uint32_t idx = 0; idx < I2SIPCMC; ++idx) {
1019-
entries[0] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(idx)));
996+
entries[0] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(dp->tdm_slot_group)));
1020997

1021-
while ((sys_read32(dai_base(dp) + SSMIDyCS(idx)) & SSMIDyCS_RNE) && retry--) {
1022-
/* Wait one sample time */
1023-
k_busy_wait(sample_ticks);
998+
while ((sys_read32(dai_base(dp) + SSMIDyCS(dp->tdm_slot_group)) &
999+
SSMIDyCS_RNE) && retry--) {
1000+
/* Wait one sample time */
1001+
k_busy_wait(sample_ticks);
10241002

1025-
entries[1] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(idx)));
1026-
sssr = sys_read32(dai_base(dp) + SSSR);
1027-
ssmidycs = sys_read32(dai_base(dp) + SSMIDyCS(idx));
1028-
1029-
if (entries[0] > entries[1]) {
1030-
/*
1031-
* The DMA is reading the FIFO, check the status in the
1032-
* next loop
1033-
*/
1034-
entries[0] = entries[1];
1035-
} else if (!(ssmidycs & SSMIDyCS_RFS)) {
1036-
/*
1037-
* The DMA request is not asserted, read the FIFO
1038-
* directly, otherwise let the next loop iteration to
1039-
* check the status
1040-
*/
1041-
for (i = 0; i < entries[1] + 1; i++)
1042-
sys_read32(dai_base(dp) + SSMIDyD(idx));
1043-
}
1003+
entries[1] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) +
1004+
SSMIDyCS(dp->tdm_slot_group)));
1005+
sssr = sys_read32(dai_base(dp) + SSSR);
1006+
ssmidycs = sys_read32(dai_base(dp) + SSMIDyCS(dp->tdm_slot_group));
10441007

1045-
sssr = sys_read32(dai_base(dp) + SSSR);
1008+
if (entries[0] > entries[1]) {
1009+
/*
1010+
* The DMA is reading the FIFO, check the status in the
1011+
* next loop
1012+
*/
1013+
entries[0] = entries[1];
1014+
} else if (!(ssmidycs & SSMIDyCS_RFS)) {
1015+
/*
1016+
* The DMA request is not asserted, read the FIFO
1017+
* directly, otherwise let the next loop iteration to
1018+
* check the status
1019+
*/
1020+
for (i = 0; i < entries[1] + 1; i++)
1021+
sys_read32(dai_base(dp) + SSMIDyD(dp->tdm_slot_group));
10461022
}
1047-
1023+
sssr = sys_read32(dai_base(dp) + SSSR);
10481024
}
1025+
10491026
/* Just in case clear the overflow status */
10501027
dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR);
10511028
}
@@ -1787,10 +1764,6 @@ static int dai_ssp_set_config_tplg(struct dai_intel_ssp *dp, const struct dai_co
17871764
SSMIDyCS_RSRE, SSMIDyCS_RSRE);
17881765
dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group),
17891766
SSMODyCS_TSRE, SSMODyCS_TSRE);
1790-
#else
1791-
dai_ssp_update_bits(dp, SSCR1,
1792-
SSCR1_TSRE | SSCR1_RSRE,
1793-
SSCR1_TSRE | SSCR1_RSRE);
17941767
#endif
17951768
/* enable port */
17961769
dai_ssp_update_bits(dp, SSCR0, SSCR0_SSE, SSCR0_SSE);
@@ -1823,10 +1796,6 @@ static int dai_ssp_set_config_tplg(struct dai_intel_ssp *dp, const struct dai_co
18231796
for (uint32_t idx = 0; idx < I2SIPCMC; ++idx) {
18241797
dai_ssp_update_bits(dp, SSMIDyCS(idx), SSMIDyCS_RSRE, 0);
18251798
}
1826-
#else
1827-
dai_ssp_update_bits(dp, SSCR1,
1828-
SSCR1_TSRE | SSCR1_RSRE,
1829-
0);
18301799
#endif
18311800
dai_ssp_update_bits(dp, SSCR0, SSCR0_SSE, 0);
18321801
LOG_INF("SSE clear for SSP%d", dp->dai_index);
@@ -2260,7 +2229,6 @@ static void dai_ssp_start(struct dai_intel_ssp *dp, int direction)
22602229
#endif
22612230

22622231
dp->state[direction] = DAI_STATE_RUNNING;
2263-
ssp_acquire_port(dp->ssp_plat_data);
22642232

22652233
/*
22662234
* Wait to get valid fifo status in clock consumer mode. TODO it's
@@ -2284,7 +2252,6 @@ static void dai_ssp_start(struct dai_intel_ssp *dp, int direction)
22842252
static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction)
22852253
{
22862254
struct dai_intel_ssp_pdata *ssp = dai_get_drvdata(dp);
2287-
struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp);
22882255
k_spinlock_key_t key;
22892256

22902257
key = k_spin_lock(&dp->lock);
@@ -2316,7 +2283,6 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction)
23162283
#endif
23172284
ssp_empty_rx_fifo_on_stop(dp);
23182285
dp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING;
2319-
ssp_release_port(ssp_plat_data);
23202286
}
23212287

23222288
/* stop Tx if needed */
@@ -2333,22 +2299,6 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction)
23332299
dai_ssp_update_bits(dp, SSTSA, SSTSA_TXEN, 0);
23342300
#endif
23352301
dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_PRE_RUNNING;
2336-
ssp_release_port(ssp_plat_data);
2337-
}
2338-
2339-
/* disable SSP port if no users */
2340-
if (dp->state[DAI_DIR_CAPTURE] == DAI_STATE_PRE_RUNNING &&
2341-
dp->state[DAI_DIR_PLAYBACK] == DAI_STATE_PRE_RUNNING &&
2342-
COND_CODE_1(CONFIG_INTEL_ADSP_CAVS,
2343-
(!(ssp_plat_data->clk_active & SSP_CLK_BCLK_ES_REQ)), (true))) {
2344-
if (!ssp_is_acquired(ssp_plat_data)) {
2345-
dai_ssp_update_bits(dp, SSCR0, SSCR0_SSE, 0);
2346-
LOG_INF("%s SSE clear SSP%d", __func__, ssp_plat_data->ssp_index);
2347-
}
2348-
}
2349-
2350-
if (!ssp_is_acquired(ssp_plat_data)) {
2351-
dai_ssp_post_stop(dp);
23522302
}
23532303

23542304
k_spin_unlock(&dp->lock, key);
@@ -2468,6 +2418,54 @@ static const struct dai_properties *dai_ssp_get_properties(const struct device *
24682418
return prop;
24692419
}
24702420

2421+
static void ssp_acquire_ip(struct dai_intel_ssp *dp)
2422+
{
2423+
struct dai_intel_ssp_plat_data *ssp = dai_get_plat_data(dp);
2424+
2425+
ssp->acquire_count++;
2426+
2427+
if (ssp->acquire_count == 1) {
2428+
/* Enable SSP power */
2429+
dai_ssp_pm_runtime_en_ssp_power(dp, ssp->ssp_index);
2430+
2431+
/* Disable dynamic clock gating before touching any register */
2432+
dai_ssp_pm_runtime_dis_ssp_clk_gating(dp, ssp->ssp_index);
2433+
}
2434+
}
2435+
2436+
static void ssp_release_ip(struct dai_intel_ssp *dp)
2437+
{
2438+
struct dai_intel_ssp_plat_data *ssp = dai_get_plat_data(dp);
2439+
2440+
if (ssp->acquire_count == 0) {
2441+
return;
2442+
}
2443+
2444+
--ssp->acquire_count;
2445+
2446+
if (ssp->acquire_count == 0) {
2447+
/* disable SSP port if no users */
2448+
if (dp->state[DAI_DIR_CAPTURE] == DAI_STATE_PRE_RUNNING &&
2449+
dp->state[DAI_DIR_PLAYBACK] == DAI_STATE_PRE_RUNNING &&
2450+
COND_CODE_1(CONFIG_INTEL_ADSP_CAVS,
2451+
(!(ssp->clk_active & SSP_CLK_BCLK_ES_REQ)), (true))) {
2452+
dai_ssp_update_bits(dp, SSCR0, SSCR0_SSE, 0);
2453+
LOG_INF("%s SSE clear SSP%d", __func__, ssp->ssp_index);
2454+
}
2455+
2456+
dai_ssp_post_stop(dp);
2457+
2458+
dai_ssp_pm_runtime_en_ssp_clk_gating(dp, ssp->ssp_index);
2459+
2460+
dai_ssp_mclk_disable_unprepare(dp);
2461+
dai_ssp_bclk_disable_unprepare(dp);
2462+
2463+
/* Disable SSP power */
2464+
dai_ssp_pm_runtime_dis_ssp_power(dp, ssp->ssp_index);
2465+
ssp->is_initialized = false;
2466+
}
2467+
}
2468+
24712469
static int dai_ssp_probe(struct dai_intel_ssp *dp)
24722470
{
24732471
struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp);
@@ -2488,50 +2486,23 @@ static int dai_ssp_probe(struct dai_intel_ssp *dp)
24882486
dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_READY;
24892487
dp->state[DAI_DIR_CAPTURE] = DAI_STATE_READY;
24902488

2491-
if (ssp_plat_data->is_power_en) {
2492-
return 0;
2493-
}
2494-
24952489
#if CONFIG_INTEL_MN
24962490
/* Reset M/N, power-gating functions need it */
24972491
dai_ssp_mn_reset_bclk_divider(dp, ssp_plat_data->ssp_index);
24982492
#endif
24992493

2500-
/* Enable SSP power */
2501-
dai_ssp_pm_runtime_en_ssp_power(dp, ssp_plat_data->ssp_index);
2502-
2503-
/* Disable dynamic clock gating before touching any register */
2504-
dai_ssp_pm_runtime_dis_ssp_clk_gating(dp, ssp_plat_data->ssp_index);
2505-
2506-
ssp_plat_data->is_power_en = true;
2494+
ssp_acquire_ip(dp);
25072495

25082496
return 0;
25092497
}
25102498

25112499
static int dai_ssp_remove(struct dai_intel_ssp *dp)
25122500
{
2513-
struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp);
2514-
2515-
if (ssp_is_acquired(ssp_plat_data)) {
2516-
k_free(dai_get_drvdata(dp));
2517-
dai_set_drvdata(dp, NULL);
2518-
return 0;
2519-
}
2520-
2521-
dai_ssp_pm_runtime_en_ssp_clk_gating(dp, ssp_plat_data->ssp_index);
2522-
2523-
dai_ssp_mclk_disable_unprepare(dp);
2524-
dai_ssp_bclk_disable_unprepare(dp);
2525-
2526-
/* Disable SSP power */
2527-
dai_ssp_pm_runtime_dis_ssp_power(dp, ssp_plat_data->ssp_index);
2501+
ssp_release_ip(dp);
25282502

25292503
k_free(dai_get_drvdata(dp));
25302504
dai_set_drvdata(dp, NULL);
25312505

2532-
ssp_plat_data->is_initialized = false;
2533-
ssp_plat_data->is_power_en = false;
2534-
25352506
return 0;
25362507
}
25372508

0 commit comments

Comments
 (0)