aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-ti-qspi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-ti-qspi.c')
-rw-r--r--drivers/spi/spi-ti-qspi.c138
1 files changed, 87 insertions, 51 deletions
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 0b71270fbf67..3d09265b5133 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -46,6 +46,8 @@ struct ti_qspi {
46 46
47 struct spi_master *master; 47 struct spi_master *master;
48 void __iomem *base; 48 void __iomem *base;
49 void __iomem *ctrl_base;
50 void __iomem *mmap_base;
49 struct clk *fclk; 51 struct clk *fclk;
50 struct device *dev; 52 struct device *dev;
51 53
@@ -54,6 +56,8 @@ struct ti_qspi {
54 u32 spi_max_frequency; 56 u32 spi_max_frequency;
55 u32 cmd; 57 u32 cmd;
56 u32 dc; 58 u32 dc;
59
60 bool ctrl_mod;
57}; 61};
58 62
59#define QSPI_PID (0x0) 63#define QSPI_PID (0x0)
@@ -161,7 +165,7 @@ static int ti_qspi_setup(struct spi_device *spi)
161 qspi->spi_max_frequency, clk_div); 165 qspi->spi_max_frequency, clk_div);
162 166
163 ret = pm_runtime_get_sync(qspi->dev); 167 ret = pm_runtime_get_sync(qspi->dev);
164 if (ret) { 168 if (ret < 0) {
165 dev_err(qspi->dev, "pm_runtime_get_sync() failed\n"); 169 dev_err(qspi->dev, "pm_runtime_get_sync() failed\n");
166 return ret; 170 return ret;
167 } 171 }
@@ -204,53 +208,36 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t)
204 txbuf = t->tx_buf; 208 txbuf = t->tx_buf;
205 cmd = qspi->cmd | QSPI_WR_SNGL; 209 cmd = qspi->cmd | QSPI_WR_SNGL;
206 count = t->len; 210 count = t->len;
207 wlen = t->bits_per_word; 211 wlen = t->bits_per_word >> 3; /* in bytes */
208 212
209 while (count) { 213 while (count) {
210 switch (wlen) { 214 switch (wlen) {
211 case 8: 215 case 1:
212 dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %02x\n", 216 dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %02x\n",
213 cmd, qspi->dc, *txbuf); 217 cmd, qspi->dc, *txbuf);
214 writeb(*txbuf, qspi->base + QSPI_SPI_DATA_REG); 218 writeb(*txbuf, qspi->base + QSPI_SPI_DATA_REG);
215 ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG);
216 ret = wait_for_completion_timeout(&qspi->transfer_complete,
217 QSPI_COMPLETION_TIMEOUT);
218 if (ret == 0) {
219 dev_err(qspi->dev, "write timed out\n");
220 return -ETIMEDOUT;
221 }
222 txbuf += 1;
223 count -= 1;
224 break; 219 break;
225 case 16: 220 case 2:
226 dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %04x\n", 221 dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %04x\n",
227 cmd, qspi->dc, *txbuf); 222 cmd, qspi->dc, *txbuf);
228 writew(*((u16 *)txbuf), qspi->base + QSPI_SPI_DATA_REG); 223 writew(*((u16 *)txbuf), qspi->base + QSPI_SPI_DATA_REG);
229 ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG);
230 ret = wait_for_completion_timeout(&qspi->transfer_complete,
231 QSPI_COMPLETION_TIMEOUT);
232 if (ret == 0) {
233 dev_err(qspi->dev, "write timed out\n");
234 return -ETIMEDOUT;
235 }
236 txbuf += 2;
237 count -= 2;
238 break; 224 break;
239 case 32: 225 case 4:
240 dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %08x\n", 226 dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %08x\n",
241 cmd, qspi->dc, *txbuf); 227 cmd, qspi->dc, *txbuf);
242 writel(*((u32 *)txbuf), qspi->base + QSPI_SPI_DATA_REG); 228 writel(*((u32 *)txbuf), qspi->base + QSPI_SPI_DATA_REG);
243 ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG);
244 ret = wait_for_completion_timeout(&qspi->transfer_complete,
245 QSPI_COMPLETION_TIMEOUT);
246 if (ret == 0) {
247 dev_err(qspi->dev, "write timed out\n");
248 return -ETIMEDOUT;
249 }
250 txbuf += 4;
251 count -= 4;
252 break; 229 break;
253 } 230 }
231
232 ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG);
233 ret = wait_for_completion_timeout(&qspi->transfer_complete,
234 QSPI_COMPLETION_TIMEOUT);
235 if (ret == 0) {
236 dev_err(qspi->dev, "write timed out\n");
237 return -ETIMEDOUT;
238 }
239 txbuf += wlen;
240 count -= wlen;
254 } 241 }
255 242
256 return 0; 243 return 0;
@@ -276,7 +263,7 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t)
276 break; 263 break;
277 } 264 }
278 count = t->len; 265 count = t->len;
279 wlen = t->bits_per_word; 266 wlen = t->bits_per_word >> 3; /* in bytes */
280 267
281 while (count) { 268 while (count) {
282 dev_dbg(qspi->dev, "rx cmd %08x dc %08x\n", cmd, qspi->dc); 269 dev_dbg(qspi->dev, "rx cmd %08x dc %08x\n", cmd, qspi->dc);
@@ -288,22 +275,18 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t)
288 return -ETIMEDOUT; 275 return -ETIMEDOUT;
289 } 276 }
290 switch (wlen) { 277 switch (wlen) {
291 case 8: 278 case 1:
292 *rxbuf = readb(qspi->base + QSPI_SPI_DATA_REG); 279 *rxbuf = readb(qspi->base + QSPI_SPI_DATA_REG);
293 rxbuf += 1;
294 count -= 1;
295 break; 280 break;
296 case 16: 281 case 2:
297 *((u16 *)rxbuf) = readw(qspi->base + QSPI_SPI_DATA_REG); 282 *((u16 *)rxbuf) = readw(qspi->base + QSPI_SPI_DATA_REG);
298 rxbuf += 2;
299 count -= 2;
300 break; 283 break;
301 case 32: 284 case 4:
302 *((u32 *)rxbuf) = readl(qspi->base + QSPI_SPI_DATA_REG); 285 *((u32 *)rxbuf) = readl(qspi->base + QSPI_SPI_DATA_REG);
303 rxbuf += 4;
304 count -= 4;
305 break; 286 break;
306 } 287 }
288 rxbuf += wlen;
289 count -= wlen;
307 } 290 }
308 291
309 return 0; 292 return 0;
@@ -417,10 +400,8 @@ out:
417static int ti_qspi_runtime_resume(struct device *dev) 400static int ti_qspi_runtime_resume(struct device *dev)
418{ 401{
419 struct ti_qspi *qspi; 402 struct ti_qspi *qspi;
420 struct spi_master *master;
421 403
422 master = dev_get_drvdata(dev); 404 qspi = dev_get_drvdata(dev);
423 qspi = spi_master_get_devdata(master);
424 ti_qspi_restore_ctx(qspi); 405 ti_qspi_restore_ctx(qspi);
425 406
426 return 0; 407 return 0;
@@ -437,7 +418,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
437{ 418{
438 struct ti_qspi *qspi; 419 struct ti_qspi *qspi;
439 struct spi_master *master; 420 struct spi_master *master;
440 struct resource *r; 421 struct resource *r, *res_ctrl, *res_mmap;
441 struct device_node *np = pdev->dev.of_node; 422 struct device_node *np = pdev->dev.of_node;
442 u32 max_freq; 423 u32 max_freq;
443 int ret = 0, num_cs, irq; 424 int ret = 0, num_cs, irq;
@@ -459,13 +440,40 @@ static int ti_qspi_probe(struct platform_device *pdev)
459 if (!of_property_read_u32(np, "num-cs", &num_cs)) 440 if (!of_property_read_u32(np, "num-cs", &num_cs))
460 master->num_chipselect = num_cs; 441 master->num_chipselect = num_cs;
461 442
462 platform_set_drvdata(pdev, master);
463
464 qspi = spi_master_get_devdata(master); 443 qspi = spi_master_get_devdata(master);
465 qspi->master = master; 444 qspi->master = master;
466 qspi->dev = &pdev->dev; 445 qspi->dev = &pdev->dev;
446 platform_set_drvdata(pdev, qspi);
447
448 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_base");
449 if (r == NULL) {
450 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
451 if (r == NULL) {
452 dev_err(&pdev->dev, "missing platform data\n");
453 return -ENODEV;
454 }
455 }
467 456
468 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 457 res_mmap = platform_get_resource_byname(pdev,
458 IORESOURCE_MEM, "qspi_mmap");
459 if (res_mmap == NULL) {
460 res_mmap = platform_get_resource(pdev, IORESOURCE_MEM, 1);
461 if (res_mmap == NULL) {
462 dev_err(&pdev->dev,
463 "memory mapped resource not required\n");
464 return -ENODEV;
465 }
466 }
467
468 res_ctrl = platform_get_resource_byname(pdev,
469 IORESOURCE_MEM, "qspi_ctrlmod");
470 if (res_ctrl == NULL) {
471 res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 2);
472 if (res_ctrl == NULL) {
473 dev_dbg(&pdev->dev,
474 "control module resources not required\n");
475 }
476 }
469 477
470 irq = platform_get_irq(pdev, 0); 478 irq = platform_get_irq(pdev, 0);
471 if (irq < 0) { 479 if (irq < 0) {
@@ -481,6 +489,23 @@ static int ti_qspi_probe(struct platform_device *pdev)
481 goto free_master; 489 goto free_master;
482 } 490 }
483 491
492 if (res_ctrl) {
493 qspi->ctrl_mod = true;
494 qspi->ctrl_base = devm_ioremap_resource(&pdev->dev, res_ctrl);
495 if (IS_ERR(qspi->ctrl_base)) {
496 ret = PTR_ERR(qspi->ctrl_base);
497 goto free_master;
498 }
499 }
500
501 if (res_mmap) {
502 qspi->mmap_base = devm_ioremap_resource(&pdev->dev, res_mmap);
503 if (IS_ERR(qspi->mmap_base)) {
504 ret = PTR_ERR(qspi->mmap_base);
505 goto free_master;
506 }
507 }
508
484 ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0, 509 ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0,
485 dev_name(&pdev->dev), qspi); 510 dev_name(&pdev->dev), qspi);
486 if (ret < 0) { 511 if (ret < 0) {
@@ -517,10 +542,20 @@ free_master:
517 542
518static int ti_qspi_remove(struct platform_device *pdev) 543static int ti_qspi_remove(struct platform_device *pdev)
519{ 544{
520 struct ti_qspi *qspi = platform_get_drvdata(pdev); 545 struct ti_qspi *qspi = platform_get_drvdata(pdev);
546 int ret;
547
548 ret = pm_runtime_get_sync(qspi->dev);
549 if (ret < 0) {
550 dev_err(qspi->dev, "pm_runtime_get_sync() failed\n");
551 return ret;
552 }
521 553
522 ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG); 554 ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG);
523 555
556 pm_runtime_put(qspi->dev);
557 pm_runtime_disable(&pdev->dev);
558
524 return 0; 559 return 0;
525} 560}
526 561
@@ -532,7 +567,7 @@ static struct platform_driver ti_qspi_driver = {
532 .probe = ti_qspi_probe, 567 .probe = ti_qspi_probe,
533 .remove = ti_qspi_remove, 568 .remove = ti_qspi_remove,
534 .driver = { 569 .driver = {
535 .name = "ti,dra7xxx-qspi", 570 .name = "ti-qspi",
536 .owner = THIS_MODULE, 571 .owner = THIS_MODULE,
537 .pm = &ti_qspi_pm_ops, 572 .pm = &ti_qspi_pm_ops,
538 .of_match_table = ti_qspi_match, 573 .of_match_table = ti_qspi_match,
@@ -544,3 +579,4 @@ module_platform_driver(ti_qspi_driver);
544MODULE_AUTHOR("Sourav Poddar <sourav.poddar@ti.com>"); 579MODULE_AUTHOR("Sourav Poddar <sourav.poddar@ti.com>");
545MODULE_LICENSE("GPL v2"); 580MODULE_LICENSE("GPL v2");
546MODULE_DESCRIPTION("TI QSPI controller driver"); 581MODULE_DESCRIPTION("TI QSPI controller driver");
582MODULE_ALIAS("platform:ti-qspi");