0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <asm/cpm.h>
0015 #include <soc/fsl/qe/qe.h>
0016 #include <linux/dma-mapping.h>
0017 #include <linux/fsl_devices.h>
0018 #include <linux/kernel.h>
0019 #include <linux/module.h>
0020 #include <linux/of_address.h>
0021 #include <linux/spi/spi.h>
0022 #include <linux/types.h>
0023 #include <linux/platform_device.h>
0024
0025 #include "spi-fsl-cpm.h"
0026 #include "spi-fsl-lib.h"
0027 #include "spi-fsl-spi.h"
0028
0029
0030 #ifdef CONFIG_CPM1
0031 #include <asm/cpm1.h>
0032 #define CPM_SPI_CMD mk_cr_cmd(CPM_CR_CH_SPI, 0)
0033 #else
0034 #include <asm/cpm2.h>
0035 #define CPM_SPI_CMD mk_cr_cmd(CPM_CR_SPI_PAGE, CPM_CR_SPI_SBLOCK, 0, 0)
0036 #endif
0037
0038 #define SPIE_TXB 0x00000200
0039 #define SPIE_RXB 0x00000100
0040
0041
0042 #define SPCOM_STR (1 << 23)
0043
0044 #define SPI_PRAM_SIZE 0x100
0045 #define SPI_MRBLR ((unsigned int)PAGE_SIZE)
0046
0047 static void *fsl_dummy_rx;
0048 static DEFINE_MUTEX(fsl_dummy_rx_lock);
0049 static int fsl_dummy_rx_refcnt;
0050
0051 void fsl_spi_cpm_reinit_txrx(struct mpc8xxx_spi *mspi)
0052 {
0053 if (mspi->flags & SPI_QE) {
0054 qe_issue_cmd(QE_INIT_TX_RX, mspi->subblock,
0055 QE_CR_PROTOCOL_UNSPECIFIED, 0);
0056 } else {
0057 if (mspi->flags & SPI_CPM1) {
0058 out_be32(&mspi->pram->rstate, 0);
0059 out_be16(&mspi->pram->rbptr,
0060 in_be16(&mspi->pram->rbase));
0061 out_be32(&mspi->pram->tstate, 0);
0062 out_be16(&mspi->pram->tbptr,
0063 in_be16(&mspi->pram->tbase));
0064 } else {
0065 cpm_command(CPM_SPI_CMD, CPM_CR_INIT_TRX);
0066 }
0067 }
0068 }
0069 EXPORT_SYMBOL_GPL(fsl_spi_cpm_reinit_txrx);
0070
0071 static void fsl_spi_cpm_bufs_start(struct mpc8xxx_spi *mspi)
0072 {
0073 struct cpm_buf_desc __iomem *tx_bd = mspi->tx_bd;
0074 struct cpm_buf_desc __iomem *rx_bd = mspi->rx_bd;
0075 unsigned int xfer_len = min(mspi->count, SPI_MRBLR);
0076 unsigned int xfer_ofs;
0077 struct fsl_spi_reg *reg_base = mspi->reg_base;
0078
0079 xfer_ofs = mspi->xfer_in_progress->len - mspi->count;
0080
0081 if (mspi->rx_dma == mspi->dma_dummy_rx)
0082 out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma);
0083 else
0084 out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs);
0085 out_be16(&rx_bd->cbd_datlen, 0);
0086 out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP);
0087
0088 if (mspi->tx_dma == mspi->dma_dummy_tx)
0089 out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma);
0090 else
0091 out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs);
0092 out_be16(&tx_bd->cbd_datlen, xfer_len);
0093 out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP |
0094 BD_SC_LAST);
0095
0096
0097 mpc8xxx_spi_write_reg(®_base->command, SPCOM_STR);
0098 }
0099
0100 int fsl_spi_cpm_bufs(struct mpc8xxx_spi *mspi,
0101 struct spi_transfer *t, bool is_dma_mapped)
0102 {
0103 struct device *dev = mspi->dev;
0104 struct fsl_spi_reg *reg_base = mspi->reg_base;
0105
0106 if (is_dma_mapped) {
0107 mspi->map_tx_dma = 0;
0108 mspi->map_rx_dma = 0;
0109 } else {
0110 mspi->map_tx_dma = 1;
0111 mspi->map_rx_dma = 1;
0112 }
0113
0114 if (!t->tx_buf) {
0115 mspi->tx_dma = mspi->dma_dummy_tx;
0116 mspi->map_tx_dma = 0;
0117 }
0118
0119 if (!t->rx_buf) {
0120 mspi->rx_dma = mspi->dma_dummy_rx;
0121 mspi->map_rx_dma = 0;
0122 }
0123
0124 if (mspi->map_tx_dma) {
0125 void *nonconst_tx = (void *)mspi->tx;
0126
0127 mspi->tx_dma = dma_map_single(dev, nonconst_tx, t->len,
0128 DMA_TO_DEVICE);
0129 if (dma_mapping_error(dev, mspi->tx_dma)) {
0130 dev_err(dev, "unable to map tx dma\n");
0131 return -ENOMEM;
0132 }
0133 } else if (t->tx_buf) {
0134 mspi->tx_dma = t->tx_dma;
0135 }
0136
0137 if (mspi->map_rx_dma) {
0138 mspi->rx_dma = dma_map_single(dev, mspi->rx, t->len,
0139 DMA_FROM_DEVICE);
0140 if (dma_mapping_error(dev, mspi->rx_dma)) {
0141 dev_err(dev, "unable to map rx dma\n");
0142 goto err_rx_dma;
0143 }
0144 } else if (t->rx_buf) {
0145 mspi->rx_dma = t->rx_dma;
0146 }
0147
0148
0149 mpc8xxx_spi_write_reg(®_base->mask, SPIE_RXB);
0150
0151 mspi->xfer_in_progress = t;
0152 mspi->count = t->len;
0153
0154
0155 fsl_spi_cpm_bufs_start(mspi);
0156
0157 return 0;
0158
0159 err_rx_dma:
0160 if (mspi->map_tx_dma)
0161 dma_unmap_single(dev, mspi->tx_dma, t->len, DMA_TO_DEVICE);
0162 return -ENOMEM;
0163 }
0164 EXPORT_SYMBOL_GPL(fsl_spi_cpm_bufs);
0165
0166 void fsl_spi_cpm_bufs_complete(struct mpc8xxx_spi *mspi)
0167 {
0168 struct device *dev = mspi->dev;
0169 struct spi_transfer *t = mspi->xfer_in_progress;
0170
0171 if (mspi->map_tx_dma)
0172 dma_unmap_single(dev, mspi->tx_dma, t->len, DMA_TO_DEVICE);
0173 if (mspi->map_rx_dma)
0174 dma_unmap_single(dev, mspi->rx_dma, t->len, DMA_FROM_DEVICE);
0175 mspi->xfer_in_progress = NULL;
0176 }
0177 EXPORT_SYMBOL_GPL(fsl_spi_cpm_bufs_complete);
0178
0179 void fsl_spi_cpm_irq(struct mpc8xxx_spi *mspi, u32 events)
0180 {
0181 u16 len;
0182 struct fsl_spi_reg *reg_base = mspi->reg_base;
0183
0184 dev_dbg(mspi->dev, "%s: bd datlen %d, count %d\n", __func__,
0185 in_be16(&mspi->rx_bd->cbd_datlen), mspi->count);
0186
0187 len = in_be16(&mspi->rx_bd->cbd_datlen);
0188 if (len > mspi->count) {
0189 WARN_ON(1);
0190 len = mspi->count;
0191 }
0192
0193
0194 mpc8xxx_spi_write_reg(®_base->event, events);
0195
0196 mspi->count -= len;
0197 if (mspi->count)
0198 fsl_spi_cpm_bufs_start(mspi);
0199 else
0200 complete(&mspi->done);
0201 }
0202 EXPORT_SYMBOL_GPL(fsl_spi_cpm_irq);
0203
0204 static void *fsl_spi_alloc_dummy_rx(void)
0205 {
0206 mutex_lock(&fsl_dummy_rx_lock);
0207
0208 if (!fsl_dummy_rx)
0209 fsl_dummy_rx = kmalloc(SPI_MRBLR, GFP_KERNEL);
0210 if (fsl_dummy_rx)
0211 fsl_dummy_rx_refcnt++;
0212
0213 mutex_unlock(&fsl_dummy_rx_lock);
0214
0215 return fsl_dummy_rx;
0216 }
0217
0218 static void fsl_spi_free_dummy_rx(void)
0219 {
0220 mutex_lock(&fsl_dummy_rx_lock);
0221
0222 switch (fsl_dummy_rx_refcnt) {
0223 case 0:
0224 WARN_ON(1);
0225 break;
0226 case 1:
0227 kfree(fsl_dummy_rx);
0228 fsl_dummy_rx = NULL;
0229 fallthrough;
0230 default:
0231 fsl_dummy_rx_refcnt--;
0232 break;
0233 }
0234
0235 mutex_unlock(&fsl_dummy_rx_lock);
0236 }
0237
0238 static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi)
0239 {
0240 struct device *dev = mspi->dev;
0241 struct device_node *np = dev->of_node;
0242 const u32 *iprop;
0243 int size;
0244 void __iomem *spi_base;
0245 unsigned long pram_ofs = -ENOMEM;
0246
0247
0248 iprop = of_get_property(np, "reg", &size);
0249
0250
0251 if (mspi->flags & SPI_QE && iprop && size == sizeof(*iprop) * 4)
0252 return cpm_muram_alloc_fixed(iprop[2], SPI_PRAM_SIZE);
0253
0254
0255 if (mspi->flags & SPI_QE) {
0256 pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
0257 qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, mspi->subblock,
0258 QE_CR_PROTOCOL_UNSPECIFIED, pram_ofs);
0259 return pram_ofs;
0260 }
0261
0262 spi_base = of_iomap(np, 1);
0263 if (spi_base == NULL)
0264 return -EINVAL;
0265
0266 if (mspi->flags & SPI_CPM2) {
0267 pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
0268 out_be16(spi_base, pram_ofs);
0269 }
0270
0271 iounmap(spi_base);
0272 return pram_ofs;
0273 }
0274
0275 int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
0276 {
0277 struct device *dev = mspi->dev;
0278 struct device_node *np = dev->of_node;
0279 const u32 *iprop;
0280 int size;
0281 unsigned long bds_ofs;
0282
0283 if (!(mspi->flags & SPI_CPM_MODE))
0284 return 0;
0285
0286 if (!fsl_spi_alloc_dummy_rx())
0287 return -ENOMEM;
0288
0289 if (mspi->flags & SPI_QE) {
0290 iprop = of_get_property(np, "cell-index", &size);
0291 if (iprop && size == sizeof(*iprop))
0292 mspi->subblock = *iprop;
0293
0294 switch (mspi->subblock) {
0295 default:
0296 dev_warn(dev, "cell-index unspecified, assuming SPI1\n");
0297 fallthrough;
0298 case 0:
0299 mspi->subblock = QE_CR_SUBBLOCK_SPI1;
0300 break;
0301 case 1:
0302 mspi->subblock = QE_CR_SUBBLOCK_SPI2;
0303 break;
0304 }
0305 }
0306
0307 if (mspi->flags & SPI_CPM1) {
0308 void *pram;
0309
0310 pram = devm_platform_ioremap_resource(to_platform_device(dev),
0311 1);
0312 if (IS_ERR(pram))
0313 mspi->pram = NULL;
0314 else
0315 mspi->pram = pram;
0316 } else {
0317 unsigned long pram_ofs = fsl_spi_cpm_get_pram(mspi);
0318
0319 if (IS_ERR_VALUE(pram_ofs))
0320 mspi->pram = NULL;
0321 else
0322 mspi->pram = cpm_muram_addr(pram_ofs);
0323 }
0324 if (mspi->pram == NULL) {
0325 dev_err(dev, "can't allocate spi parameter ram\n");
0326 goto err_pram;
0327 }
0328
0329 bds_ofs = cpm_muram_alloc(sizeof(*mspi->tx_bd) +
0330 sizeof(*mspi->rx_bd), 8);
0331 if (IS_ERR_VALUE(bds_ofs)) {
0332 dev_err(dev, "can't allocate bds\n");
0333 goto err_bds;
0334 }
0335
0336 mspi->dma_dummy_tx = dma_map_single(dev, empty_zero_page, PAGE_SIZE,
0337 DMA_TO_DEVICE);
0338 if (dma_mapping_error(dev, mspi->dma_dummy_tx)) {
0339 dev_err(dev, "unable to map dummy tx buffer\n");
0340 goto err_dummy_tx;
0341 }
0342
0343 mspi->dma_dummy_rx = dma_map_single(dev, fsl_dummy_rx, SPI_MRBLR,
0344 DMA_FROM_DEVICE);
0345 if (dma_mapping_error(dev, mspi->dma_dummy_rx)) {
0346 dev_err(dev, "unable to map dummy rx buffer\n");
0347 goto err_dummy_rx;
0348 }
0349
0350 mspi->tx_bd = cpm_muram_addr(bds_ofs);
0351 mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd));
0352
0353
0354 out_be16(&mspi->pram->tbase, cpm_muram_offset(mspi->tx_bd));
0355 out_be16(&mspi->pram->rbase, cpm_muram_offset(mspi->rx_bd));
0356 out_8(&mspi->pram->tfcr, CPMFCR_EB | CPMFCR_GBL);
0357 out_8(&mspi->pram->rfcr, CPMFCR_EB | CPMFCR_GBL);
0358 out_be16(&mspi->pram->mrblr, SPI_MRBLR);
0359 out_be32(&mspi->pram->rstate, 0);
0360 out_be32(&mspi->pram->rdp, 0);
0361 out_be16(&mspi->pram->rbptr, 0);
0362 out_be16(&mspi->pram->rbc, 0);
0363 out_be32(&mspi->pram->rxtmp, 0);
0364 out_be32(&mspi->pram->tstate, 0);
0365 out_be32(&mspi->pram->tdp, 0);
0366 out_be16(&mspi->pram->tbptr, 0);
0367 out_be16(&mspi->pram->tbc, 0);
0368 out_be32(&mspi->pram->txtmp, 0);
0369
0370 return 0;
0371
0372 err_dummy_rx:
0373 dma_unmap_single(dev, mspi->dma_dummy_tx, PAGE_SIZE, DMA_TO_DEVICE);
0374 err_dummy_tx:
0375 cpm_muram_free(bds_ofs);
0376 err_bds:
0377 if (!(mspi->flags & SPI_CPM1))
0378 cpm_muram_free(cpm_muram_offset(mspi->pram));
0379 err_pram:
0380 fsl_spi_free_dummy_rx();
0381 return -ENOMEM;
0382 }
0383 EXPORT_SYMBOL_GPL(fsl_spi_cpm_init);
0384
0385 void fsl_spi_cpm_free(struct mpc8xxx_spi *mspi)
0386 {
0387 struct device *dev = mspi->dev;
0388
0389 if (!(mspi->flags & SPI_CPM_MODE))
0390 return;
0391
0392 dma_unmap_single(dev, mspi->dma_dummy_rx, SPI_MRBLR, DMA_FROM_DEVICE);
0393 dma_unmap_single(dev, mspi->dma_dummy_tx, PAGE_SIZE, DMA_TO_DEVICE);
0394 cpm_muram_free(cpm_muram_offset(mspi->tx_bd));
0395 if (!(mspi->flags & SPI_CPM1))
0396 cpm_muram_free(cpm_muram_offset(mspi->pram));
0397 fsl_spi_free_dummy_rx();
0398 }
0399 EXPORT_SYMBOL_GPL(fsl_spi_cpm_free);
0400
0401 MODULE_LICENSE("GPL");