// SPDX-License-Identifier: GPL-2.0-or-later /* * au1550 psc spi controller driver * may work also with au1200, au1210, au1250 * will not work on au1000, au1100 and au1500 (no full spi controller there) * * Copyright (c) 2006 ATRON electronic GmbH * Author: Jan Nikitenko <jan.nikitenko@gmail.com>
*/
staticint ddma_memid; /* id to above mem dma device */
staticvoid au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw);
/* * compute BRG and DIV bits to setup spi clock based on main input clock rate * that was specified in platform data structure * according to au1550 datasheet: * psc_tempclk = psc_mainclk / (2 << DIV) * spiclk = psc_tempclk / (2 * (BRG + 1)) * BRG valid range is 4..63 * DIV valid range is 0..3
*/ static u32 au1550_spi_baudcfg(struct au1550_spi *hw, unsignedint speed_hz)
{
u32 mainclk_hz = hw->pdata->mainclk_hz;
u32 div, brg;
for (div = 0; div < 4; div++) {
brg = mainclk_hz / speed_hz / (4 << div); /* now we have BRG+1 in brg, so count with that */ if (brg < (4 + 1)) {
brg = (4 + 1); /* speed_hz too big */ break; /* set lowest brg (div is == 0) */
} if (brg <= (63 + 1)) break; /* we have valid brg and div */
} if (div == 4) {
div = 3; /* speed_hz too small */
brg = (63 + 1); /* set highest brg and div */
}
brg--; return PSC_SPICFG_SET_BAUD(brg) | PSC_SPICFG_SET_DIV(div);
}
/* * dma transfers are used for the most common spi word size of 8-bits * we cannot easily change already set up dma channels' width, so if we wanted * dma support for more than 8-bit words (up to 24 bits), we would need to * setup dma channels from scratch on each spi transfer, based on bits_per_word * instead we have pre set up 8 bit dma channels supporting spi 4 to 8 bits * transfers, and 9 to 24 bits spi transfers will be done in pio irq based mode * callbacks to handle dma or pio are set up in au1550_spi_bits_handlers_set()
*/ staticvoid au1550_spi_chipsel(struct spi_device *spi, int value)
{ struct au1550_spi *hw = spi_controller_get_devdata(spi->controller); unsignedint cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;
u32 cfg, stat;
switch (value) { case BITBANG_CS_INACTIVE: if (hw->pdata->deactivate_cs)
hw->pdata->deactivate_cs(hw->pdata, spi_get_chipselect(spi, 0),
cspol); break;
case BITBANG_CS_ACTIVE:
au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
/* * for dma spi transfers, we have to setup rx channel, otherwise there is * no reliable way how to recognize that spi transfer is done * dma complete callbacks are called before real spi transfer is finished * and if only tx dma channel is set up (and rx fifo overflow event masked) * spi host done event irq is not generated unless rx fifo is empty (emptied) * so we need rx tmp buffer to use for rx dma if user does not provide one
*/ staticint au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsignedint size)
{
hw->dma_rx_tmpbuf = kmalloc(size, GFP_KERNEL); if (!hw->dma_rx_tmpbuf) return -ENOMEM;
hw->dma_rx_tmpbuf_size = size;
hw->dma_rx_tmpbuf_addr = dma_map_single(hw->dev, hw->dma_rx_tmpbuf,
size, DMA_FROM_DEVICE); if (dma_mapping_error(hw->dev, hw->dma_rx_tmpbuf_addr)) {
kfree(hw->dma_rx_tmpbuf);
hw->dma_rx_tmpbuf = 0;
hw->dma_rx_tmpbuf_size = 0; return -EFAULT;
} return 0;
}
/* * - first map the TX buffer, so cache data gets written to memory * - then map the RX buffer, so that cache entries (with * soon-to-be-stale data) get removed * use rx buffer in place of tx if tx buffer was not provided * use temp rx buffer (preallocated or realloc to fit) for rx dma
*/ if (t->tx_buf) {
dma_tx_addr = dma_map_single(hw->dev, (void *)t->tx_buf,
t->len, DMA_TO_DEVICE); if (dma_mapping_error(hw->dev, dma_tx_addr))
dev_err(hw->dev, "tx dma map error\n");
}
if (t->rx_buf) {
dma_rx_addr = dma_map_single(hw->dev, (void *)t->rx_buf,
t->len, DMA_FROM_DEVICE); if (dma_mapping_error(hw->dev, dma_rx_addr))
dev_err(hw->dev, "rx dma map error\n");
} else { if (t->len > hw->dma_rx_tmpbuf_size) { int ret;
/* put buffers on the ring */
res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, virt_to_phys(hw->rx),
t->len, DDMA_FLAGS_IE); if (!res)
dev_err(hw->dev, "rx dma put dest error\n");
res = au1xxx_dbdma_put_source(hw->dma_tx_ch, virt_to_phys(hw->tx),
t->len, DDMA_FLAGS_IE); if (!res)
dev_err(hw->dev, "tx dma put source error\n");
if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO
| PSC_SPIEVNT_RU | PSC_SPIEVNT_TO
| PSC_SPIEVNT_TU | PSC_SPIEVNT_SD))
!= 0) { /* * due to an spi error we consider transfer as done, * so mask all events until before next transfer start * and stop the possibly running dma immediately
*/
au1550_spi_mask_ack_all(hw);
au1xxx_dbdma_stop(hw->dma_rx_ch);
au1xxx_dbdma_stop(hw->dma_tx_ch);
/* get number of transferred bytes */
hw->rx_count = hw->len - au1xxx_get_dma_residue(hw->dma_rx_ch);
hw->tx_count = hw->len - au1xxx_get_dma_residue(hw->dma_tx_ch);
if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO
| PSC_SPIEVNT_RU | PSC_SPIEVNT_TO
| PSC_SPIEVNT_SD))
!= 0) { /* * due to an error we consider transfer as done, * so mask all events until before next transfer start
*/
au1550_spi_mask_ack_all(hw);
au1550_spi_reset_fifos(hw);
dev_err(hw->dev, "pio transfer: unexpected SPI error (event=0x%x stat=0x%x)!\n",
evnt, stat);
complete(&hw->host_done); return IRQ_HANDLED;
}
/* * while there is something to read from rx fifo * or there is a space to write to tx fifo:
*/ do {
busy = 0;
stat = hw->regs->psc_spistat;
wmb(); /* drain writebuffer */
/* * Take care to not let the Rx FIFO overflow. * * We only write a byte if we have read one at least. Initially, * the write fifo is full, so we should read from the read fifo * first. * In case we miss a word from the read fifo, we should get a * RO event and should back out.
*/ if (!(stat & PSC_SPISTAT_RE) && hw->rx_count < hw->len) {
hw->rx_word(hw);
busy = 1;
if (!(stat & PSC_SPISTAT_TF) && hw->tx_count < hw->len)
hw->tx_word(hw);
}
} while (busy);
/* * Restart the SPI transmission in case of a transmit underflow. * This seems to work despite the notes in the Au1550 data book * of Figure 8-4 with flowchart for SPI host operation: * * """Note 1: An XFR Error Interrupt occurs, unless masked, * for any of the following events: Tx FIFO Underflow, * Rx FIFO Overflow, or Multiple-host Error * Note 2: In case of a Tx Underflow Error, all zeroes are * transmitted.""" * * By simply restarting the spi transfer on Tx Underflow Error, * we assume that spi transfer was paused instead of zeroes * transmittion mentioned in the Note 2 of Au1550 data book.
*/ if (evnt & PSC_SPIEVNT_TU) {
hw->regs->psc_spievent = PSC_SPIEVNT_TU | PSC_SPIEVNT_MD;
wmb(); /* drain writebuffer */
hw->regs->psc_spipcr = PSC_SPIPCR_MS;
wmb(); /* drain writebuffer */
}
if (hw->rx_count >= hw->len) { /* transfer completed successfully */
au1550_spi_mask_ack_all(hw);
complete(&hw->host_done);
} return IRQ_HANDLED;
}
/* * precompute valid range for spi freq - from au1550 datasheet: * psc_tempclk = psc_mainclk / (2 << DIV) * spiclk = psc_tempclk / (2 * (BRG + 1)) * BRG valid range is 4..63 * DIV valid range is 0..3 * round the min and max frequencies to values that would still * produce valid brg and div
*/
{ int min_div = (2 << 0) * (2 * (4 + 1)); int max_div = (2 << 3) * (2 * (63 + 1));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.