Commit e5262d05 authored by Weike Chen's avatar Weike Chen Committed by Mark Brown

spi: spi-pxa2xx: SPI support for Intel Quark X1000

There are two SPI controllers exported by PCI subsystem for Intel Quark X1000.
The SPI memory mapped I/O registers supported by Quark are different from
the current implementation, and Quark only supports the registers of 'SSCR0',
'SSCR1', 'SSSR', 'SSDR', and 'DDS_RATE'. This patch is to enable the SPI for
Intel Quark X1000.

This piece of work is derived from Dan O'Donovan's initial work for Intel Quark
X1000 SPI enabling.
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarWeike Chen <alvin.chen@intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4fdb2424
...@@ -19,6 +19,7 @@ enum { ...@@ -19,6 +19,7 @@ enum {
PORT_BSW0, PORT_BSW0,
PORT_BSW1, PORT_BSW1,
PORT_BSW2, PORT_BSW2,
PORT_QUARK_X1000,
}; };
struct pxa_spi_info { struct pxa_spi_info {
...@@ -92,6 +93,12 @@ static struct pxa_spi_info spi_info_configs[] = { ...@@ -92,6 +93,12 @@ static struct pxa_spi_info spi_info_configs[] = {
.tx_param = &bsw2_tx_param, .tx_param = &bsw2_tx_param,
.rx_param = &bsw2_rx_param, .rx_param = &bsw2_rx_param,
}, },
[PORT_QUARK_X1000] = {
.type = QUARK_X1000_SSP,
.port_id = -1,
.num_chipselect = 1,
.max_clk_rate = 50000000,
},
}; };
static int pxa2xx_spi_pci_probe(struct pci_dev *dev, static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
...@@ -191,6 +198,7 @@ static void pxa2xx_spi_pci_remove(struct pci_dev *dev) ...@@ -191,6 +198,7 @@ static void pxa2xx_spi_pci_remove(struct pci_dev *dev)
static const struct pci_device_id pxa2xx_spi_pci_devices[] = { static const struct pci_device_id pxa2xx_spi_pci_devices[] = {
{ PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 },
{ PCI_VDEVICE(INTEL, 0x0935), PORT_QUARK_X1000 },
{ PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT }, { PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT },
{ PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 }, { PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 },
{ PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 }, { PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 },
......
...@@ -63,10 +63,64 @@ MODULE_ALIAS("platform:pxa2xx-spi"); ...@@ -63,10 +63,64 @@ MODULE_ALIAS("platform:pxa2xx-spi");
| SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \ | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \
| SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
#define QUARK_X1000_SSCR1_CHANGE_MASK (QUARK_X1000_SSCR1_STRF \
| QUARK_X1000_SSCR1_EFWR \
| QUARK_X1000_SSCR1_RFT \
| QUARK_X1000_SSCR1_TFT \
| SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
#define LPSS_RX_THRESH_DFLT 64 #define LPSS_RX_THRESH_DFLT 64
#define LPSS_TX_LOTHRESH_DFLT 160 #define LPSS_TX_LOTHRESH_DFLT 160
#define LPSS_TX_HITHRESH_DFLT 224 #define LPSS_TX_HITHRESH_DFLT 224
struct quark_spi_rate {
u32 bitrate;
u32 dds_clk_rate;
u32 clk_div;
};
/*
* 'rate', 'dds', 'clk_div' lookup table, which is defined in
* the Quark SPI datasheet.
*/
static const struct quark_spi_rate quark_spi_rate_table[] = {
/* bitrate, dds_clk_rate, clk_div */
{50000000, 0x800000, 0},
{40000000, 0x666666, 0},
{25000000, 0x400000, 0},
{20000000, 0x666666, 1},
{16667000, 0x800000, 2},
{13333000, 0x666666, 2},
{12500000, 0x200000, 0},
{10000000, 0x800000, 4},
{8000000, 0x666666, 4},
{6250000, 0x400000, 3},
{5000000, 0x400000, 4},
{4000000, 0x666666, 9},
{3125000, 0x80000, 0},
{2500000, 0x400000, 9},
{2000000, 0x666666, 19},
{1563000, 0x40000, 0},
{1250000, 0x200000, 9},
{1000000, 0x400000, 24},
{800000, 0x666666, 49},
{781250, 0x20000, 0},
{625000, 0x200000, 19},
{500000, 0x400000, 49},
{400000, 0x666666, 99},
{390625, 0x10000, 0},
{250000, 0x400000, 99},
{200000, 0x666666, 199},
{195313, 0x8000, 0},
{125000, 0x100000, 49},
{100000, 0x200000, 124},
{50000, 0x100000, 124},
{25000, 0x80000, 124},
{10016, 0x20000, 77},
{5040, 0x20000, 154},
{1002, 0x8000, 194},
};
/* Offset from drv_data->lpss_base */ /* Offset from drv_data->lpss_base */
#define GENERAL_REG 0x08 #define GENERAL_REG 0x08
#define GENERAL_REG_RXTO_HOLDOFF_DISABLE BIT(24) #define GENERAL_REG_RXTO_HOLDOFF_DISABLE BIT(24)
...@@ -80,9 +134,16 @@ static bool is_lpss_ssp(const struct driver_data *drv_data) ...@@ -80,9 +134,16 @@ static bool is_lpss_ssp(const struct driver_data *drv_data)
return drv_data->ssp_type == LPSS_SSP; return drv_data->ssp_type == LPSS_SSP;
} }
static bool is_quark_x1000_ssp(const struct driver_data *drv_data)
{
return drv_data->ssp_type == QUARK_X1000_SSP;
}
static u32 pxa2xx_spi_get_ssrc1_change_mask(const struct driver_data *drv_data) static u32 pxa2xx_spi_get_ssrc1_change_mask(const struct driver_data *drv_data)
{ {
switch (drv_data->ssp_type) { switch (drv_data->ssp_type) {
case QUARK_X1000_SSP:
return QUARK_X1000_SSCR1_CHANGE_MASK;
default: default:
return SSCR1_CHANGE_MASK; return SSCR1_CHANGE_MASK;
} }
...@@ -92,6 +153,8 @@ static u32 ...@@ -92,6 +153,8 @@ static u32
pxa2xx_spi_get_rx_default_thre(const struct driver_data *drv_data) pxa2xx_spi_get_rx_default_thre(const struct driver_data *drv_data)
{ {
switch (drv_data->ssp_type) { switch (drv_data->ssp_type) {
case QUARK_X1000_SSP:
return RX_THRESH_QUARK_X1000_DFLT;
default: default:
return RX_THRESH_DFLT; return RX_THRESH_DFLT;
} }
...@@ -103,6 +166,9 @@ static bool pxa2xx_spi_txfifo_full(const struct driver_data *drv_data) ...@@ -103,6 +166,9 @@ static bool pxa2xx_spi_txfifo_full(const struct driver_data *drv_data)
u32 mask; u32 mask;
switch (drv_data->ssp_type) { switch (drv_data->ssp_type) {
case QUARK_X1000_SSP:
mask = QUARK_X1000_SSSR_TFL_MASK;
break;
default: default:
mask = SSSR_TFL_MASK; mask = SSSR_TFL_MASK;
break; break;
...@@ -117,6 +183,9 @@ static void pxa2xx_spi_clear_rx_thre(const struct driver_data *drv_data, ...@@ -117,6 +183,9 @@ static void pxa2xx_spi_clear_rx_thre(const struct driver_data *drv_data,
u32 mask; u32 mask;
switch (drv_data->ssp_type) { switch (drv_data->ssp_type) {
case QUARK_X1000_SSP:
mask = QUARK_X1000_SSCR1_RFT;
break;
default: default:
mask = SSCR1_RFT; mask = SSCR1_RFT;
break; break;
...@@ -128,6 +197,9 @@ static void pxa2xx_spi_set_rx_thre(const struct driver_data *drv_data, ...@@ -128,6 +197,9 @@ static void pxa2xx_spi_set_rx_thre(const struct driver_data *drv_data,
u32 *sccr1_reg, u32 threshold) u32 *sccr1_reg, u32 threshold)
{ {
switch (drv_data->ssp_type) { switch (drv_data->ssp_type) {
case QUARK_X1000_SSP:
*sccr1_reg |= QUARK_X1000_SSCR1_RxTresh(threshold);
break;
default: default:
*sccr1_reg |= SSCR1_RxTresh(threshold); *sccr1_reg |= SSCR1_RxTresh(threshold);
break; break;
...@@ -138,6 +210,11 @@ static u32 pxa2xx_configure_sscr0(const struct driver_data *drv_data, ...@@ -138,6 +210,11 @@ static u32 pxa2xx_configure_sscr0(const struct driver_data *drv_data,
u32 clk_div, u8 bits) u32 clk_div, u8 bits)
{ {
switch (drv_data->ssp_type) { switch (drv_data->ssp_type) {
case QUARK_X1000_SSP:
return clk_div
| QUARK_X1000_SSCR0_Motorola
| QUARK_X1000_SSCR0_DataSize(bits > 32 ? 8 : bits)
| SSCR0_SSE;
default: default:
return clk_div return clk_div
| SSCR0_Motorola | SSCR0_Motorola
...@@ -654,6 +731,28 @@ static irqreturn_t ssp_int(int irq, void *dev_id) ...@@ -654,6 +731,28 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
return drv_data->transfer_handler(drv_data); return drv_data->transfer_handler(drv_data);
} }
/*
* The Quark SPI data sheet gives a table, and for the given 'rate',
* the 'dds' and 'clk_div' can be found in the table.
*/
static u32 quark_x1000_set_clk_regvals(u32 rate, u32 *dds, u32 *clk_div)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(quark_spi_rate_table); i++) {
if (rate >= quark_spi_rate_table[i].bitrate) {
*dds = quark_spi_rate_table[i].dds_clk_rate;
*clk_div = quark_spi_rate_table[i].clk_div;
return quark_spi_rate_table[i].bitrate;
}
}
*dds = quark_spi_rate_table[i-1].dds_clk_rate;
*clk_div = quark_spi_rate_table[i-1].clk_div;
return quark_spi_rate_table[i-1].bitrate;
}
static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate) static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
{ {
unsigned long ssp_clk = drv_data->max_clk_rate; unsigned long ssp_clk = drv_data->max_clk_rate;
...@@ -667,6 +766,20 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate) ...@@ -667,6 +766,20 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
return ((ssp_clk / rate - 1) & 0xfff) << 8; return ((ssp_clk / rate - 1) & 0xfff) << 8;
} }
static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data,
struct chip_data *chip, int rate)
{
u32 clk_div;
switch (drv_data->ssp_type) {
case QUARK_X1000_SSP:
quark_x1000_set_clk_regvals(rate, &chip->dds_rate, &clk_div);
return clk_div << 8;
default:
return ssp_get_clk_div(drv_data, rate);
}
}
static void pump_transfers(unsigned long data) static void pump_transfers(unsigned long data)
{ {
struct driver_data *drv_data = (struct driver_data *)data; struct driver_data *drv_data = (struct driver_data *)data;
...@@ -769,7 +882,7 @@ static void pump_transfers(unsigned long data) ...@@ -769,7 +882,7 @@ static void pump_transfers(unsigned long data)
if (transfer->bits_per_word) if (transfer->bits_per_word)
bits = transfer->bits_per_word; bits = transfer->bits_per_word;
clk_div = ssp_get_clk_div(drv_data, speed); clk_div = pxa2xx_ssp_get_clk_div(drv_data, chip, speed);
if (bits <= 8) { if (bits <= 8) {
drv_data->n_bytes = 1; drv_data->n_bytes = 1;
...@@ -837,6 +950,10 @@ static void pump_transfers(unsigned long data) ...@@ -837,6 +950,10 @@ static void pump_transfers(unsigned long data)
write_SSITF(chip->lpss_tx_threshold, reg); write_SSITF(chip->lpss_tx_threshold, reg);
} }
if (is_quark_x1000_ssp(drv_data) &&
(read_DDS_RATE(reg) != chip->dds_rate))
write_DDS_RATE(chip->dds_rate, reg);
/* see if we need to reload the config registers */ /* see if we need to reload the config registers */
if ((read_SSCR0(reg) != cr0) || if ((read_SSCR0(reg) != cr0) ||
(read_SSCR1(reg) & change_mask) != (cr1 & change_mask)) { (read_SSCR1(reg) & change_mask) != (cr1 & change_mask)) {
...@@ -940,14 +1057,22 @@ static int setup(struct spi_device *spi) ...@@ -940,14 +1057,22 @@ static int setup(struct spi_device *spi)
unsigned int clk_div; unsigned int clk_div;
uint tx_thres, tx_hi_thres, rx_thres; uint tx_thres, tx_hi_thres, rx_thres;
if (is_lpss_ssp(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 LPSS_SSP:
tx_thres = LPSS_TX_LOTHRESH_DFLT; tx_thres = LPSS_TX_LOTHRESH_DFLT;
tx_hi_thres = LPSS_TX_HITHRESH_DFLT; tx_hi_thres = LPSS_TX_HITHRESH_DFLT;
rx_thres = LPSS_RX_THRESH_DFLT; rx_thres = LPSS_RX_THRESH_DFLT;
} else { break;
default:
tx_thres = TX_THRESH_DFLT; tx_thres = TX_THRESH_DFLT;
tx_hi_thres = 0; tx_hi_thres = 0;
rx_thres = RX_THRESH_DFLT; rx_thres = RX_THRESH_DFLT;
break;
} }
/* Only alloc on first setup */ /* Only alloc on first setup */
...@@ -1000,9 +1125,6 @@ static int setup(struct spi_device *spi) ...@@ -1000,9 +1125,6 @@ static int setup(struct spi_device *spi)
chip->enable_dma = drv_data->master_info->enable_dma; chip->enable_dma = drv_data->master_info->enable_dma;
} }
chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) |
(SSCR1_TxTresh(tx_thres) & SSCR1_TFT);
chip->lpss_rx_threshold = SSIRF_RxThresh(rx_thres); chip->lpss_rx_threshold = SSIRF_RxThresh(rx_thres);
chip->lpss_tx_threshold = SSITF_TxLoThresh(tx_thres) chip->lpss_tx_threshold = SSITF_TxLoThresh(tx_thres)
| SSITF_TxHiThresh(tx_hi_thres); | SSITF_TxHiThresh(tx_hi_thres);
...@@ -1021,11 +1143,24 @@ static int setup(struct spi_device *spi) ...@@ -1021,11 +1143,24 @@ static int setup(struct spi_device *spi)
} }
} }
clk_div = ssp_get_clk_div(drv_data, spi->max_speed_hz); clk_div = pxa2xx_ssp_get_clk_div(drv_data, chip, spi->max_speed_hz);
chip->speed_hz = spi->max_speed_hz; chip->speed_hz = spi->max_speed_hz;
chip->cr0 = pxa2xx_configure_sscr0(drv_data, clk_div, chip->cr0 = pxa2xx_configure_sscr0(drv_data, clk_div,
spi->bits_per_word); spi->bits_per_word);
switch (drv_data->ssp_type) {
case QUARK_X1000_SSP:
chip->threshold = (QUARK_X1000_SSCR1_RxTresh(rx_thres)
& QUARK_X1000_SSCR1_RFT)
| (QUARK_X1000_SSCR1_TxTresh(tx_thres)
& QUARK_X1000_SSCR1_TFT);
break;
default:
chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) |
(SSCR1_TxTresh(tx_thres) & SSCR1_TFT);
break;
}
chip->cr1 &= ~(SSCR1_SPO | SSCR1_SPH); chip->cr1 &= ~(SSCR1_SPO | SSCR1_SPH);
chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) ? SSCR1_SPH : 0) chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) ? SSCR1_SPH : 0)
| (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0); | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0);
...@@ -1054,7 +1189,8 @@ static int setup(struct spi_device *spi) ...@@ -1054,7 +1189,8 @@ static int setup(struct spi_device *spi)
chip->read = u16_reader; chip->read = u16_reader;
chip->write = u16_writer; chip->write = u16_writer;
} else if (spi->bits_per_word <= 32) { } else if (spi->bits_per_word <= 32) {
chip->cr0 |= SSCR0_EDSS; if (!is_quark_x1000_ssp(drv_data))
chip->cr0 |= SSCR0_EDSS;
chip->n_bytes = 4; chip->n_bytes = 4;
chip->read = u32_reader; chip->read = u32_reader;
chip->write = u32_writer; chip->write = u32_writer;
...@@ -1205,7 +1341,15 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) ...@@ -1205,7 +1341,15 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
drv_data->ioaddr = ssp->mmio_base; drv_data->ioaddr = ssp->mmio_base;
drv_data->ssdr_physical = ssp->phys_base + SSDR; drv_data->ssdr_physical = ssp->phys_base + SSDR;
if (pxa25x_ssp_comp(drv_data)) { if (pxa25x_ssp_comp(drv_data)) {
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); switch (drv_data->ssp_type) {
case QUARK_X1000_SSP:
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
break;
default:
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
break;
}
drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE; drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE;
drv_data->dma_cr1 = 0; drv_data->dma_cr1 = 0;
drv_data->clear_sr = SSSR_ROR; drv_data->clear_sr = SSSR_ROR;
...@@ -1243,16 +1387,35 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) ...@@ -1243,16 +1387,35 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
/* Load default SSP configuration */ /* Load default SSP configuration */
write_SSCR0(0, drv_data->ioaddr); write_SSCR0(0, drv_data->ioaddr);
write_SSCR1(SSCR1_RxTresh(RX_THRESH_DFLT) | switch (drv_data->ssp_type) {
SSCR1_TxTresh(TX_THRESH_DFLT), case QUARK_X1000_SSP:
drv_data->ioaddr); write_SSCR1(QUARK_X1000_SSCR1_RxTresh(
write_SSCR0(SSCR0_SCR(2) RX_THRESH_QUARK_X1000_DFLT) |
| SSCR0_Motorola QUARK_X1000_SSCR1_TxTresh(
| SSCR0_DataSize(8), TX_THRESH_QUARK_X1000_DFLT),
drv_data->ioaddr); drv_data->ioaddr);
/* using the Motorola SPI protocol and use 8 bit frame */
write_SSCR0(QUARK_X1000_SSCR0_Motorola
| QUARK_X1000_SSCR0_DataSize(8),
drv_data->ioaddr);
break;
default:
write_SSCR1(SSCR1_RxTresh(RX_THRESH_DFLT) |
SSCR1_TxTresh(TX_THRESH_DFLT),
drv_data->ioaddr);
write_SSCR0(SSCR0_SCR(2)
| SSCR0_Motorola
| SSCR0_DataSize(8),
drv_data->ioaddr);
break;
}
if (!pxa25x_ssp_comp(drv_data)) if (!pxa25x_ssp_comp(drv_data))
write_SSTO(0, drv_data->ioaddr); write_SSTO(0, drv_data->ioaddr);
write_SSPSP(0, drv_data->ioaddr);
if (!is_quark_x1000_ssp(drv_data))
write_SSPSP(0, drv_data->ioaddr);
lpss_ssp_setup(drv_data); lpss_ssp_setup(drv_data);
......
...@@ -93,6 +93,7 @@ struct driver_data { ...@@ -93,6 +93,7 @@ struct driver_data {
struct chip_data { struct chip_data {
u32 cr0; u32 cr0;
u32 cr1; u32 cr1;
u32 dds_rate;
u32 psp; u32 psp;
u32 timeout; u32 timeout;
u8 n_bytes; u8 n_bytes;
...@@ -126,6 +127,7 @@ DEFINE_SSP_REG(SSCR1, 0x04) ...@@ -126,6 +127,7 @@ DEFINE_SSP_REG(SSCR1, 0x04)
DEFINE_SSP_REG(SSSR, 0x08) DEFINE_SSP_REG(SSSR, 0x08)
DEFINE_SSP_REG(SSITR, 0x0c) DEFINE_SSP_REG(SSITR, 0x0c)
DEFINE_SSP_REG(SSDR, 0x10) DEFINE_SSP_REG(SSDR, 0x10)
DEFINE_SSP_REG(DDS_RATE, 0x28) /* DDS Clock Rate */
DEFINE_SSP_REG(SSTO, 0x28) DEFINE_SSP_REG(SSTO, 0x28)
DEFINE_SSP_REG(SSPSP, 0x2c) DEFINE_SSP_REG(SSPSP, 0x2c)
DEFINE_SSP_REG(SSITF, SSITF) DEFINE_SSP_REG(SSITF, SSITF)
...@@ -141,18 +143,22 @@ DEFINE_SSP_REG(SSIRF, SSIRF) ...@@ -141,18 +143,22 @@ DEFINE_SSP_REG(SSIRF, SSIRF)
static inline int pxa25x_ssp_comp(struct driver_data *drv_data) static inline int pxa25x_ssp_comp(struct driver_data *drv_data)
{ {
if (drv_data->ssp_type == PXA25x_SSP) switch (drv_data->ssp_type) {
case PXA25x_SSP:
case CE4100_SSP:
case QUARK_X1000_SSP:
return 1; return 1;
if (drv_data->ssp_type == CE4100_SSP) default:
return 1; return 0;
return 0; }
} }
static inline void write_SSSR_CS(struct driver_data *drv_data, u32 val) static inline void write_SSSR_CS(struct driver_data *drv_data, u32 val)
{ {
void __iomem *reg = drv_data->ioaddr; void __iomem *reg = drv_data->ioaddr;
if (drv_data->ssp_type == CE4100_SSP) if (drv_data->ssp_type == CE4100_SSP ||
drv_data->ssp_type == QUARK_X1000_SSP)
val |= read_SSSR(reg) & SSSR_ALT_FRM_MASK; val |= read_SSSR(reg) & SSSR_ALT_FRM_MASK;
write_SSSR(val, reg); write_SSSR(val, reg);
......
...@@ -108,6 +108,25 @@ ...@@ -108,6 +108,25 @@
#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */ #define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */
#endif #endif
/* QUARK_X1000 SSCR0 bit definition */
#define QUARK_X1000_SSCR0_DSS (0x1F) /* Data Size Select (mask) */
#define QUARK_X1000_SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..32] */
#define QUARK_X1000_SSCR0_FRF (0x3 << 5) /* FRame Format (mask) */
#define QUARK_X1000_SSCR0_Motorola (0x0 << 5) /* Motorola's Serial Peripheral Interface (SPI) */
#define RX_THRESH_QUARK_X1000_DFLT 1
#define TX_THRESH_QUARK_X1000_DFLT 16
#define QUARK_X1000_SSSR_TFL_MASK (0x1F << 8) /* Transmit FIFO Level mask */
#define QUARK_X1000_SSSR_RFL_MASK (0x1F << 13) /* Receive FIFO Level mask */
#define QUARK_X1000_SSCR1_TFT (0x1F << 6) /* Transmit FIFO Threshold (mask) */
#define QUARK_X1000_SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..32] */
#define QUARK_X1000_SSCR1_RFT (0x1F << 11) /* Receive FIFO Threshold (mask) */
#define QUARK_X1000_SSCR1_RxTresh(x) (((x) - 1) << 11) /* level [1..32] */
#define QUARK_X1000_SSCR1_STRF (1 << 17) /* Select FIFO or EFWR */
#define QUARK_X1000_SSCR1_EFWR (1 << 16) /* Enable FIFO Write/Read */
/* extra bits in PXA255, PXA26x and PXA27x SSP ports */ /* extra bits in PXA255, PXA26x and PXA27x SSP ports */
#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ #define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */
#define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */ #define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */
...@@ -175,6 +194,7 @@ enum pxa_ssp_type { ...@@ -175,6 +194,7 @@ enum pxa_ssp_type {
PXA910_SSP, PXA910_SSP,
CE4100_SSP, CE4100_SSP,
LPSS_SSP, LPSS_SSP,
QUARK_X1000_SSP,
}; };
struct ssp_device { struct ssp_device {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment