/* * For testing SSCR1 changes that require SSP restart, basically * everything except the service and interrupt enables, the PXA270 developer * manual says only SSCR1_SCFR, SSCR1_SPH, SSCR1_SPO need to be in this * list, but the PXA255 developer manual says all bits without really meaning * the service and interrupt enables.
*/ #define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_SCFR \
| SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \
| SSCR1_SFRMDIR | SSCR1_RWOT | SSCR1_TRAIL \
| SSCR1_IFS | SSCR1_STRF | SSCR1_EFWR \
| SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \
| SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
staticbool is_lpss_ssp(conststruct driver_data *drv_data)
{ switch (drv_data->ssp_type) { case LPSS_LPT_SSP: case LPSS_BYT_SSP: case LPSS_BSW_SSP: case LPSS_SPT_SSP: case LPSS_BXT_SSP: case LPSS_CNL_SSP: returntrue; default: returnfalse;
}
}
/* * Read and write LPSS SSP private registers. Caller must first check that * is_lpss_ssp() returns true before these can be called.
*/ static u32 __lpss_ssp_read_priv(struct driver_data *drv_data, unsigned offset)
{
WARN_ON(!drv_data->lpss_base); return readl(drv_data->lpss_base + offset);
}
/* * lpss_ssp_setup - perform LPSS SSP specific setup * @drv_data: pointer to the driver private data * * Perform LPSS SSP specific setup. This function must be called first if * one is going to use LPSS SSP private registers.
*/ staticvoid lpss_ssp_setup(struct driver_data *drv_data)
{ conststruct lpss_config *config;
u32 value;
/* * When switching another chip select output active the output must be * selected first and wait 2 ssp_clk cycles before changing state to * active. Otherwise a short glitch will occur on the previous chip * select since output select is latched but state control is not.
*/
ndelay(1000000000 / (drv_data->controller->max_speed_hz / 2));
}
mask = LPSS_CS_CONTROL_CS_HIGH;
__lpss_ssp_update_priv(drv_data, config->reg_cs_ctrl, mask, enable ? 0 : mask); if (config->cs_clk_stays_gated) { /* * Changing CS alone when dynamic clock gating is on won't * actually flip CS at that time. This ruins SPI transfers * that specify delays, or have no data. Toggle the clock mode * to force on briefly to poke the CS pin to move.
*/
mask = LPSS_PRIV_CLOCK_GATE_CLK_CTL_MASK; if (__lpss_ssp_update_priv(drv_data, LPSS_PRIV_CLOCK_GATE, mask,
LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_ON))
__lpss_ssp_update_priv(drv_data, LPSS_PRIV_CLOCK_GATE, mask,
LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_OFF);
}
}
if (irq_status & SSSR_TINT) {
pxa2xx_spi_write(drv_data, SSSR, SSSR_TINT); if (drv_data->read(drv_data)) {
int_transfer_complete(drv_data); return IRQ_HANDLED;
}
}
/* Drain Rx FIFO, Fill Tx FIFO and prevent overruns */ do { if (drv_data->read(drv_data)) {
int_transfer_complete(drv_data); return IRQ_HANDLED;
}
} while (drv_data->write(drv_data));
if (drv_data->read(drv_data)) {
int_transfer_complete(drv_data); return IRQ_HANDLED;
}
if (drv_data->tx == drv_data->tx_end) {
u32 bytes_left;
u32 sccr1_reg;
/* * The IRQ might be shared with other peripherals so we must first * check that are we RPM suspended or not. If we are we assume that * the IRQ was not for us (we shouldn't be RPM suspended when the * interrupt is enabled).
*/ if (pm_runtime_suspended(drv_data->ssp->dev)) return IRQ_NONE;
/* * If the device is not yet in RPM suspended state and we get an * interrupt that is meant for another device, check if status bits * are all set to one. That means that the device is already * powered off.
*/
status = pxa2xx_spi_read(drv_data, SSSR); if (status == ~0) return IRQ_NONE;
sccr1_reg = pxa2xx_spi_read(drv_data, SSCR1);
/* Ignore possible writes if we don't need to write */ if (!(sccr1_reg & SSCR1_TIE))
mask &= ~SSSR_TFS;
/* Ignore RX timeout interrupt if it is disabled */ if (!(sccr1_reg & SSCR1_TINTE))
mask &= ~SSSR_TINT;
if (!drv_data->controller->cur_msg) {
handle_bad_msg(drv_data); /* Never fail */ return IRQ_HANDLED;
}
return drv_data->transfer_handler(drv_data);
}
/* * The Quark SPI has an additional 24 bit register (DDS_CLK_RATE) to multiply * input frequency by fractions of 2^24. It also has a divider by 5. * * There are formulas to get baud rate value for given input frequency and * divider parameters, such as DDS_CLK_RATE and SCR: * * Fsys = 200MHz * * Fssp = Fsys * DDS_CLK_RATE / 2^24 (1) * Baud rate = Fsclk = Fssp / (2 * (SCR + 1)) (2) * * DDS_CLK_RATE either 2^n or 2^n / 5. * SCR is in range 0 .. 255 * * Divisor = 5^i * 2^j * 2 * k * i = [0, 1] i = 1 iff j = 0 or j > 3 * j = [0, 23] j = 0 iff i = 1 * k = [1, 256] * Special case: j = 0, i = 1: Divisor = 2 / 5 * * Accordingly to the specification the recommended values for DDS_CLK_RATE * are: * Case 1: 2^n, n = [0, 23] * Case 2: 2^24 * 2 / 5 (0x666666) * Case 3: less than or equal to 2^24 / 5 / 16 (0x33333) * * In all cases the lowest possible value is better. * * The function calculates parameters for all cases and chooses the one closest * to the asked baud rate.
*/ staticunsignedint quark_x1000_get_clk_div(int rate, u32 *dds)
{ unsignedlong xtal = 200000000; unsignedlong fref = xtal / 2; /* mandatory division by 2,
see (2) */ /* case 3 */ unsignedlong fref1 = fref / 2; /* case 1 */ unsignedlong fref2 = fref * 2 / 5; /* case 2 */ unsignedlong scale; unsignedlong q, q1, q2; long r, r1, r2;
u32 mul;
/* Case 1 */
/* Set initial value for DDS_CLK_RATE */
mul = (1 << 24) >> 1;
/* * Choose the best between two: less remainder we have the better. We * can't go case 2 if q2 is greater than 256 since SCR register can * hold only values 0 .. 255.
*/ if (r2 >= r1 || q2 > 256) { /* case 1 is better */
r = r1;
q = q1;
} else { /* case 2 is better */
r = r2;
q = q2;
mul = (1 << 24) * 2 / 5;
}
/* Check case 3 only if the divisor is big enough */ if (fref / rate >= 80) {
u64 fssp;
u32 m;
/* Check if we can DMA this transfer */ if (transfer->len > MAX_DMA_LEN && drv_data->controller_info->enable_dma) { /* Warn ... we force this to PIO mode */
dev_warn_ratelimited(&spi->dev, "DMA disabled for transfer length %u greater than %d\n",
transfer->len, MAX_DMA_LEN);
}
/* Setup the transfer state based on the type of transfer */ if (pxa2xx_spi_flush(drv_data) == 0) {
dev_err(&spi->dev, "Flush failed\n"); return -EIO;
}
drv_data->tx = (void *)transfer->tx_buf;
drv_data->tx_end = drv_data->tx + transfer->len;
drv_data->rx = transfer->rx_buf;
drv_data->rx_end = drv_data->rx + transfer->len;
/* Change speed and bit per word on a per transfer */
bits = transfer->bits_per_word;
speed = transfer->speed_hz;
/* * Stop the DMA if running. Note DMA callback handler may have unset * the dma_running already, which is fine as stopping is not needed * then but we shouldn't rely this flag for anything else than * stopping. For instance to differentiate between PIO and DMA * transfers.
*/ if (atomic_read(&drv_data->dma_running))
pxa2xx_spi_dma_stop(drv_data);
}
switch (drv_data->ssp_type) { case QUARK_X1000_SSP:
tx_thres = TX_THRESH_QUARK_X1000_DFLT;
tx_hi_thres = 0;
rx_thres = RX_THRESH_QUARK_X1000_DFLT; break; case MRFLD_SSP:
tx_thres = TX_THRESH_MRFLD_DFLT;
tx_hi_thres = 0;
rx_thres = RX_THRESH_MRFLD_DFLT; break; case CE4100_SSP:
tx_thres = TX_THRESH_CE4100_DFLT;
tx_hi_thres = 0;
rx_thres = RX_THRESH_CE4100_DFLT; break; case LPSS_LPT_SSP: case LPSS_BYT_SSP: case LPSS_BSW_SSP: case LPSS_SPT_SSP: case LPSS_BXT_SSP: case LPSS_CNL_SSP:
config = lpss_get_config(drv_data);
tx_thres = config->tx_threshold_lo;
tx_hi_thres = config->tx_threshold_hi;
rx_thres = config->rx_threshold; break; default:
tx_hi_thres = 0; if (spi_controller_is_target(drv_data->controller)) {
tx_thres = 1;
rx_thres = 2;
} else {
tx_thres = TX_THRESH_DFLT;
rx_thres = RX_THRESH_DFLT;
} break;
}
if (drv_data->ssp_type == CE4100_SSP) { if (spi_get_chipselect(spi, 0) > 4) {
dev_err(&spi->dev, "failed setup: cs number must not be > 4.\n"); return -EINVAL;
}
}
/* Only allocate on the first setup */
chip = spi_get_ctldata(spi); if (!chip) {
chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); if (!chip) return -ENOMEM;
}
switch (drv_data->ssp_type) { /* * For some of Intel Atoms the ACPI DeviceSelection used by the Windows * driver starts from 1 instead of 0 so translate it here to match what * Linux expects.
*/ case LPSS_BYT_SSP: case LPSS_BSW_SSP: return cs - 1;
status = request_irq(ssp->irq, ssp_int, IRQF_SHARED, dev_name(dev),
drv_data); if (status < 0) return dev_err_probe(dev, status, "cannot get IRQ %d\n", ssp->irq);
/* Setup DMA if requested */ if (platform_info->enable_dma) {
status = pxa2xx_spi_dma_setup(drv_data); if (status) {
dev_warn(dev, "no DMA channels available, using PIO\n");
platform_info->enable_dma = false;
} else {
controller->can_dma = pxa2xx_spi_can_dma;
controller->max_dma_len = MAX_DMA_LEN;
controller->max_transfer_size =
pxa2xx_spi_max_dma_transfer_size;
dev_dbg(dev, "DMA burst size set to %u\n", platform_info->dma_burst_size);
}
}
/* Enable SOC clock */
status = clk_prepare_enable(ssp->clk); if (status) goto out_error_dma_irq_alloc;
controller->max_speed_hz = clk_get_rate(ssp->clk); /* * Set minimum speed for all other platforms than Intel Quark which is * able do under 1 Hz transfers.
*/ if (!pxa25x_ssp_comp(drv_data))
controller->min_speed_hz =
DIV_ROUND_UP(controller->max_speed_hz, 4096); elseif (!is_quark_x1000_ssp(drv_data))
controller->min_speed_hz =
DIV_ROUND_UP(controller->max_speed_hz, 512);
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.