int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip, struct spi_device *spi, u8 bits_per_word, u32 *burst_code, u32 *threshold) { struct pxa2xx_spi_chip *chip_info = spi->controller_data; /* * If the DMA burst size is given in chip_info we use that, * otherwise we use the default. Also we use the default FIFO * thresholds for now. */ *burst_code = chip_info ? chip_info->dma_burst_size : 1; *threshold = SSCR1_RxTresh(RX_THRESH_DFLT) | SSCR1_TxTresh(TX_THRESH_DFLT); return 0; }
/** * calculate_sscr1_psp - separate function that calculate sscr1 register * @ps_settings : pointer of the settings struct * * this function is to simplify/clarify set_ssp_i2s_hw function * * Output parameters * u32 : calculated SSCR1 register */ u32 calculate_sscr1_psp(const struct intel_mid_i2s_settings *ps_settings) { u32 sscr1; sscr1 = SSCR1_reg(SFRMDIR, ps_settings->sspsfrm_direction) |SSCR1_reg(SCLKDIR, ps_settings->sspslclk_direction) |SSCR1_reg(TTELP, ps_settings->tx_tristate_phase) |SSCR1_reg(TTE, ps_settings->tx_tristate_enable) |SSCR1_reg(TRAIL, ps_settings->ssp_trailing_byte_mode) |SSCR1_reg(TINTE, ps_settings->ssp_rx_timeout_interrupt_status) |SSCR1_reg(PINTE, ps_settings->ssp_trailing_byte_interrupt_status) |SSCR1_reg(LBM, ps_settings->ssp_loopback_mode_status) |SSCR1_reg(RWOT, ps_settings->ssp_duplex_mode) |SSCR1_reg(RFT, SSCR1_RxTresh(ps_settings->ssp_rx_fifo_threshold)) |SSCR1_reg(TFT, SSCR1_TxTresh(ps_settings->ssp_tx_fifo_threshold)); return sscr1; }
/* * Set up the SSP DAI format. * The SSP Port must be inactive before calling this function as the * physical interface format is changed. */ static int pxa3xx_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { struct ssp_device *ssp = cpu_dai->private_data; int dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; u32 sscr0, sscr1, sspsp; sscr0 = __raw_readl(ssp->mmio_base + SSCR0); if (sscr0 & SSCR0_SSE) return 0; ssp_clk[cpu_dai->id].dai_fmt = dai_fmt; /* * reset port settings * PXA3xx docs say to use RxThresh = 8 and TxThresh = 7 with * DMA bursts of 32 */ __raw_writel(0, ssp->mmio_base + SSCR0); sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7); __raw_writel(sscr1, ssp->mmio_base + SSCR1); __raw_writel(0, ssp->mmio_base + SSPSP); switch (dai_fmt) { case SND_SOC_DAIFMT_I2S: sscr0 = SSCR0_MOD | SSCR0_PSP; __raw_writel(sscr0, ssp->mmio_base + SSCR0); sscr1 = __raw_readl(ssp->mmio_base + SSCR1); sscr1 |= SSCR1_RWOT | SSCR1_TRAIL; __raw_writel(sscr1, ssp->mmio_base + SSCR1); switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: sspsp = __raw_readl(ssp->mmio_base + SSPSP); sspsp |= SSPSP_FSRT; __raw_writel(sspsp, ssp->mmio_base + SSPSP); break; case SND_SOC_DAIFMT_NB_IF: sspsp = __raw_readl(ssp->mmio_base + SSPSP); sspsp |= SSPSP_SFRMP | SSPSP_FSRT; __raw_writel(sspsp, ssp->mmio_base + SSPSP); break; case SND_SOC_DAIFMT_IB_IF: sspsp = __raw_readl(ssp->mmio_base + SSPSP); sspsp |= SSPSP_SFRMP; __raw_writel(sspsp, ssp->mmio_base + SSPSP); break; default: return -EINVAL; } break; case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_B: sscr0 = SSCR0_MOD | SSCR0_PSP; __raw_writel(sscr0, ssp->mmio_base + SSCR0); sscr1 = __raw_readl(ssp->mmio_base + SSCR1); sscr1 |= SSCR1_TRAIL | SSCR1_RWOT; __raw_writel(sscr1, ssp->mmio_base + SSCR1); if (dai_fmt == SND_SOC_DAIFMT_DSP_A) __raw_writel(SSPSP_FSRT, ssp->mmio_base + SSPSP); switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: sspsp = __raw_readl(ssp->mmio_base + SSPSP); sspsp |= SSPSP_SFRMP; __raw_writel(sspsp, ssp->mmio_base + SSPSP); break; case SND_SOC_DAIFMT_IB_IF: break; default: return -EINVAL; } break; default: return -EINVAL; } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: sscr1 = __raw_readl(ssp->mmio_base + SSCR1); sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR; __raw_writel(sscr1, ssp->mmio_base + SSCR1); break; case SND_SOC_DAIFMT_CBM_CFS: sscr1 = __raw_readl(ssp->mmio_base + SSCR1); sscr1 |= SSCR1_SCLKDIR; __raw_writel(sscr1, ssp->mmio_base + SSCR1); break; case SND_SOC_DAIFMT_CBS_CFS: break; default: return -EINVAL; } return 0; }
int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip, struct spi_device *spi, u8 bits_per_word, u32 *burst_code, u32 *threshold) { struct pxa2xx_spi_chip *chip_info = (struct pxa2xx_spi_chip *)spi->controller_data; int bytes_per_word; int burst_bytes; int thresh_words; int req_burst_size; int retval = 0; /* Set the threshold (in registers) to equal the same amount of data * as represented by burst size (in bytes). The computation below * is (burst_size rounded up to nearest 8 byte, word or long word) * divided by (bytes/register); the tx threshold is the inverse of * the rx, so that there will always be enough data in the rx fifo * to satisfy a burst, and there will always be enough space in the * tx fifo to accept a burst (a tx burst will overwrite the fifo if * there is not enough space), there must always remain enough empty * space in the rx fifo for any data loaded to the tx fifo. * Whenever burst_size (in bytes) equals bits/word, the fifo threshold * will be 8, or half the fifo; * The threshold can only be set to 2, 4 or 8, but not 16, because * to burst 16 to the tx fifo, the fifo would have to be empty; * however, the minimum fifo trigger level is 1, and the tx will * request service when the fifo is at this level, with only 15 spaces. */ /* find bytes/word */ if (bits_per_word <= 8) bytes_per_word = 1; else if (bits_per_word <= 16) bytes_per_word = 2; else bytes_per_word = 4; /* use struct pxa2xx_spi_chip->dma_burst_size if available */ if (chip_info) req_burst_size = chip_info->dma_burst_size; else { switch (chip->dma_burst_size) { default: /* if the default burst size is not set, * do it now */ chip->dma_burst_size = DCMD_BURST8; case DCMD_BURST8: req_burst_size = 8; break; case DCMD_BURST16: req_burst_size = 16; break; case DCMD_BURST32: req_burst_size = 32; break; } } if (req_burst_size <= 8) { *burst_code = DCMD_BURST8; burst_bytes = 8; } else if (req_burst_size <= 16) { if (bytes_per_word == 1) { /* don't burst more than 1/2 the fifo */ *burst_code = DCMD_BURST8; burst_bytes = 8; retval = 1; } else { *burst_code = DCMD_BURST16; burst_bytes = 16; } } else { if (bytes_per_word == 1) { /* don't burst more than 1/2 the fifo */ *burst_code = DCMD_BURST8; burst_bytes = 8; retval = 1; } else if (bytes_per_word == 2) { /* don't burst more than 1/2 the fifo */ *burst_code = DCMD_BURST16; burst_bytes = 16; retval = 1; } else { *burst_code = DCMD_BURST32; burst_bytes = 32; } } thresh_words = burst_bytes / bytes_per_word; /* thresh_words will be between 2 and 8 */ *threshold = (SSCR1_RxTresh(thresh_words) & SSCR1_RFT) | (SSCR1_TxTresh(16-thresh_words) & SSCR1_TFT); return retval; }