Merge pull request #181 from plbossart/fix/mdivc
apl-ssp: do not override common MDIVCTRL register
diff --git a/src/drivers/apl-ssp.c b/src/drivers/apl-ssp.c
index 36bb02c..1dd1386 100644
--- a/src/drivers/apl-ssp.c
+++ b/src/drivers/apl-ssp.c
@@ -576,8 +576,10 @@
goto out;
}
- tft = MIN(8, sample_width * active_tx_slots);
- rft = MIN(8, sample_width * active_rx_slots);
+ tft = MIN(SSP_FIFO_DEPTH - SSP_FIFO_WATERMARK,
+ sample_width * active_tx_slots);
+ rft = MIN(SSP_FIFO_DEPTH - SSP_FIFO_WATERMARK,
+ sample_width * active_rx_slots);
sscr3 |= SSCR3_TX(tft) | SSCR3_RX(rft);
diff --git a/src/drivers/byt-ssp.c b/src/drivers/byt-ssp.c
index a940ff9..4759d29 100644
--- a/src/drivers/byt-ssp.c
+++ b/src/drivers/byt-ssp.c
@@ -54,6 +54,32 @@
return count;
}
+/* empty SSP receive FIFO */
+static void ssp_empty_rx_fifo(struct dai *dai)
+{
+ struct ssp_pdata *ssp = dai_get_drvdata(dai);
+ uint32_t sssr;
+ uint32_t entries;
+ uint32_t i;
+
+ spin_lock(&ssp->lock);
+
+ sssr = ssp_read(dai, SSSR);
+
+ /* clear interrupt */
+ if (sssr & SSSR_ROR)
+ ssp_write(dai, SSSR, sssr);
+
+ /* empty fifo */
+ if (sssr & SSSR_RNE) {
+ entries = SFIFOL_RFL(ssp_read(dai, SFIFOL));
+ for (i = 0; i < entries + 1; i++)
+ ssp_read(dai, SSDR);
+ }
+
+ spin_unlock(&ssp->lock);
+}
+
/* save SSP context prior to entering D3 */
static int ssp_context_store(struct dai *dai)
{
@@ -500,6 +526,7 @@
if (direction == DAI_DIR_CAPTURE &&
ssp->state[SOF_IPC_STREAM_CAPTURE] == COMP_STATE_ACTIVE) {
ssp_update_bits(dai, SSCR1, SSCR1_RSRE, 0);
+ ssp_empty_rx_fifo(dai);
ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PAUSED;
trace_ssp("Ss0");
}
@@ -598,6 +625,7 @@
platform_interrupt_unmask(ssp_irq(dai), 1);
interrupt_enable(ssp_irq(dai));
+ ssp_empty_rx_fifo(dai);
return 0;
}
diff --git a/src/drivers/dmic.c b/src/drivers/dmic.c
index 47c966d..69ee2fd 100644
--- a/src/drivers/dmic.c
+++ b/src/drivers/dmic.c
@@ -1150,6 +1150,18 @@
goto finish;
}
+ if (prm->fifo_bits_a != 16 && prm->fifo_bits_a != 32) {
+ trace_dmic_error("fba");
+ ret = -EINVAL;
+ goto finish;
+ }
+
+ if (prm->fifo_bits_b != 16 && prm->fifo_bits_b != 32) {
+ trace_dmic_error("fbb");
+ ret = -EINVAL;
+ goto finish;
+ }
+
/* Match and select optimal decimators configuration for FIFOs A and B
* paths. This setup phase is still abstract. Successful completion
* points struct cfg to FIR coefficients and contains the scale value
diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c
index 46988dc..d4f13bf 100644
--- a/src/drivers/dw-dma.c
+++ b/src/drivers/dw-dma.c
@@ -1188,6 +1188,8 @@
switch (next.size) {
case DMA_RELOAD_END:
p->chan[i].status = COMP_STATE_PREPARE;
+ p->chan[i].lli_current =
+ (struct dw_lli2 *)p->chan[i].lli_current->llp;
break;
case DMA_RELOAD_LLI:
dw_dma_chan_reload_lli(dma, i);
diff --git a/src/include/sof/ssp.h b/src/include/sof/ssp.h
index 8fa0df7..b5e8175 100644
--- a/src/include/sof/ssp.h
+++ b/src/include/sof/ssp.h
@@ -61,6 +61,7 @@
defined CONFIG_CHERRYTRAIL ||\
defined CONFIG_BROADWELL ||\
defined CONFIG_HASWELL
+#define SFIFOL 0x68
#define SFIFOTT 0x6C
#define SSCR3 0x70
#define SSCR4 0x74
@@ -198,6 +199,10 @@
#define SFIFOTT_TX(x) ((x) - 1)
#define SFIFOTT_RX(x) (((x) - 1) << 16)
+/* SFIFOL bits */
+#define SFIFOL_TFL(x) ((x) & 0xFFFF)
+#define SFIFOL_RFL(x) ((x) >> 16)
+
#if defined CONFIG_APOLLOLAKE || defined CONFIG_CANNONLAKE ||\
defined CONFIG_HASWELL || defined CONFIG_BROADWELL
#define SSTSA_TSEN BIT(8)
diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h
index 62310d6..4cf569f 100644
--- a/src/include/uapi/ipc.h
+++ b/src/include/uapi/ipc.h
@@ -329,8 +329,8 @@
uint32_t fifo_fs_a; /* FIFO A sample rate in Hz (8000..96000) */
uint32_t fifo_fs_b; /* FIFO B sample rate in Hz (8000..96000) */
/* TODO: FIFO word lengths can be retrieved from SOF_DAI_FMT */
- uint16_t fifo_bits_a; /* FIFO A word length (16 or 24) */
- uint16_t fifo_bits_b; /* FIFO B word length (16 or 24) */
+ uint16_t fifo_bits_a; /* FIFO A word length (16 or 32) */
+ uint16_t fifo_bits_b; /* FIFO B word length (16 or 32) */
uint16_t duty_min; /* Min. mic clock duty cycle in % (20..80) */
uint16_t duty_max; /* Max. mic clock duty cycle in % (min..80) */
uint32_t num_pdm_active; /* Number of active controllers */
diff --git a/src/ipc/ipc.c b/src/ipc/ipc.c
index 3e23d9c..25d4471 100644
--- a/src/ipc/ipc.c
+++ b/src/ipc/ipc.c
@@ -333,8 +333,10 @@
int ipc_comp_dai_config(struct ipc *ipc, struct sof_ipc_dai_config *config)
{
+ struct sof_ipc_comp_dai *dai;
struct ipc_comp_dev *icd;
struct list_item *clist;
+ struct comp_dev *dev;
int ret = 0;
/* for each component */
@@ -347,10 +349,20 @@
switch (icd->cd->comp.type) {
case SOF_COMP_DAI:
case SOF_COMP_SG_DAI:
- ret = comp_dai_config(icd->cd, config);
- if (ret < 0) {
- trace_ipc_error("eCD");
- return ret;
+ dev = icd->cd;
+ dai = (struct sof_ipc_comp_dai *)&dev->comp;
+
+ /*
+ * set config if comp dai_index matches
+ * config dai_index.
+ */
+ if (dai->dai_index == config->dai_index &&
+ dai->type == config->type) {
+ ret = comp_dai_config(dev, config);
+ if (ret < 0) {
+ trace_ipc_error("eCD");
+ return ret;
+ }
}
break;
default:
diff --git a/src/platform/apollolake/include/platform/platform.h b/src/platform/apollolake/include/platform/platform.h
index aa78732..d611a1c 100644
--- a/src/platform/apollolake/include/platform/platform.h
+++ b/src/platform/apollolake/include/platform/platform.h
@@ -121,6 +121,12 @@
/* minimal L1 exit time in cycles */
#define PLATFORM_FORCE_L1_EXIT_TIME 585
+/* the SSP port fifo depth */
+#define SSP_FIFO_DEPTH 16
+
+/* the watermark for the SSP fifo depth setting */
+#define SSP_FIFO_WATERMARK 8
+
/* Platform defined panic code */
static inline void platform_panic(uint32_t p)
{
diff --git a/src/platform/apollolake/include/platform/shim.h b/src/platform/apollolake/include/platform/shim.h
index 598f1c8..b18bb94 100644
--- a/src/platform/apollolake/include/platform/shim.h
+++ b/src/platform/apollolake/include/platform/shim.h
@@ -158,6 +158,19 @@
#define SHIM_L2_MECS (SHIM_BASE + 0xd0)
+#define SHIM_LPGPDMAC(x) (0x1110 + (2 * x))
+#define SHIM_LPGPDMAC_CTLOSEL (1 << 15)
+#define SHIM_LPGPDMAC_CHOSEL (0xFF)
+
+#define SHIM_DSPIOPO 0x1118
+#define SHIM_DSPIOPO_DMICOSEL (1 << 0)
+#define SHIM_DSPIOPO_I2SOSEL (0x3F << 8)
+
+#define SHIM_GENO 0x111C
+#define SHIM_GENO_SHIMOSEL (1 << 0)
+#define SHIM_GENO_MDIVOSEL (1 << 1)
+#define SHIM_GENO_DIOPTOSEL (1 << 2)
+
#define SHIM_L2_CACHE_CTRL (SHIM_BASE + 0x500)
#define SHIM_L2_PREF_CFG (SHIM_BASE + 0x508)
#define SHIM_L2_CACHE_PREF (SHIM_BASE + 0x510)
diff --git a/src/platform/apollolake/platform.c b/src/platform/apollolake/platform.c
index 684cc74..4c5173f 100644
--- a/src/platform/apollolake/platform.c
+++ b/src/platform/apollolake/platform.c
@@ -194,12 +194,30 @@
dcache_writeback_region((void *)HP_SRAM_WIN3_BASE, HP_SRAM_WIN3_SIZE);
}
+/* init HW */
+static void platform_init_hw(void)
+{
+ io_reg_write(SHIM_GENO, SHIM_GENO_SHIMOSEL |
+ SHIM_GENO_MDIVOSEL | SHIM_GENO_DIOPTOSEL);
+
+ io_reg_write(SHIM_DSPIOPO,
+ SHIM_DSPIOPO_DMICOSEL | SHIM_DSPIOPO_I2SOSEL);
+
+ io_reg_write(SHIM_LPGPDMAC(0),
+ SHIM_LPGPDMAC_CHOSEL | SHIM_LPGPDMAC_CTLOSEL);
+ io_reg_write(SHIM_LPGPDMAC(1),
+ SHIM_LPGPDMAC_CHOSEL | SHIM_LPGPDMAC_CTLOSEL);
+}
+
int platform_init(struct sof *sof)
{
struct dai *ssp;
struct dai *dmic0;
int i, ret;
+ trace_point(TRACE_BOOT_PLATFORM_ENTRY);
+ platform_init_hw();
+
platform_interrupt_init();
trace_point(TRACE_BOOT_PLATFORM_MBOX);
diff --git a/src/platform/cannonlake/include/platform/platform.h b/src/platform/cannonlake/include/platform/platform.h
index 67566b2..69b06e9 100644
--- a/src/platform/cannonlake/include/platform/platform.h
+++ b/src/platform/cannonlake/include/platform/platform.h
@@ -118,6 +118,12 @@
/* minimal L1 exit time in cycles */
#define PLATFORM_FORCE_L1_EXIT_TIME 482
+/* the SSP port fifo depth */
+#define SSP_FIFO_DEPTH 16
+
+/* the watermark for the SSP fifo depth setting */
+#define SSP_FIFO_WATERMARK 8
+
/* Platform defined trace code */
static inline void platform_panic(uint32_t p)
{