diff options
Diffstat (limited to 'drivers/spi/spi-qup.c')
-rw-r--r-- | drivers/spi/spi-qup.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index c08da380cb23..9f83d2950748 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c | |||
@@ -142,6 +142,7 @@ struct spi_qup { | |||
142 | int w_size; /* bytes per SPI word */ | 142 | int w_size; /* bytes per SPI word */ |
143 | int tx_bytes; | 143 | int tx_bytes; |
144 | int rx_bytes; | 144 | int rx_bytes; |
145 | int qup_v1; | ||
145 | }; | 146 | }; |
146 | 147 | ||
147 | 148 | ||
@@ -420,7 +421,9 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer) | |||
420 | config |= QUP_CONFIG_SPI_MODE; | 421 | config |= QUP_CONFIG_SPI_MODE; |
421 | writel_relaxed(config, controller->base + QUP_CONFIG); | 422 | writel_relaxed(config, controller->base + QUP_CONFIG); |
422 | 423 | ||
423 | writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK); | 424 | /* only write to OPERATIONAL_MASK when register is present */ |
425 | if (!controller->qup_v1) | ||
426 | writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK); | ||
424 | return 0; | 427 | return 0; |
425 | } | 428 | } |
426 | 429 | ||
@@ -486,7 +489,7 @@ static int spi_qup_probe(struct platform_device *pdev) | |||
486 | struct resource *res; | 489 | struct resource *res; |
487 | struct device *dev; | 490 | struct device *dev; |
488 | void __iomem *base; | 491 | void __iomem *base; |
489 | u32 data, max_freq, iomode; | 492 | u32 max_freq, iomode; |
490 | int ret, irq, size; | 493 | int ret, irq, size; |
491 | 494 | ||
492 | dev = &pdev->dev; | 495 | dev = &pdev->dev; |
@@ -529,15 +532,6 @@ static int spi_qup_probe(struct platform_device *pdev) | |||
529 | return ret; | 532 | return ret; |
530 | } | 533 | } |
531 | 534 | ||
532 | data = readl_relaxed(base + QUP_HW_VERSION); | ||
533 | |||
534 | if (data < QUP_HW_VERSION_2_1_1) { | ||
535 | clk_disable_unprepare(cclk); | ||
536 | clk_disable_unprepare(iclk); | ||
537 | dev_err(dev, "v.%08x is not supported\n", data); | ||
538 | return -ENXIO; | ||
539 | } | ||
540 | |||
541 | master = spi_alloc_master(dev, sizeof(struct spi_qup)); | 535 | master = spi_alloc_master(dev, sizeof(struct spi_qup)); |
542 | if (!master) { | 536 | if (!master) { |
543 | clk_disable_unprepare(cclk); | 537 | clk_disable_unprepare(cclk); |
@@ -570,6 +564,10 @@ static int spi_qup_probe(struct platform_device *pdev) | |||
570 | controller->cclk = cclk; | 564 | controller->cclk = cclk; |
571 | controller->irq = irq; | 565 | controller->irq = irq; |
572 | 566 | ||
567 | /* set v1 flag if device is version 1 */ | ||
568 | if (of_device_is_compatible(dev->of_node, "qcom,spi-qup-v1.1.1")) | ||
569 | controller->qup_v1 = 1; | ||
570 | |||
573 | spin_lock_init(&controller->lock); | 571 | spin_lock_init(&controller->lock); |
574 | init_completion(&controller->done); | 572 | init_completion(&controller->done); |
575 | 573 | ||
@@ -593,8 +591,8 @@ static int spi_qup_probe(struct platform_device *pdev) | |||
593 | size = QUP_IO_M_INPUT_FIFO_SIZE(iomode); | 591 | size = QUP_IO_M_INPUT_FIFO_SIZE(iomode); |
594 | controller->in_fifo_sz = controller->in_blk_sz * (2 << size); | 592 | controller->in_fifo_sz = controller->in_blk_sz * (2 << size); |
595 | 593 | ||
596 | dev_info(dev, "v.%08x IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n", | 594 | dev_info(dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n", |
597 | data, controller->in_blk_sz, controller->in_fifo_sz, | 595 | controller->in_blk_sz, controller->in_fifo_sz, |
598 | controller->out_blk_sz, controller->out_fifo_sz); | 596 | controller->out_blk_sz, controller->out_fifo_sz); |
599 | 597 | ||
600 | writel_relaxed(1, base + QUP_SW_RESET); | 598 | writel_relaxed(1, base + QUP_SW_RESET); |
@@ -607,10 +605,19 @@ static int spi_qup_probe(struct platform_device *pdev) | |||
607 | 605 | ||
608 | writel_relaxed(0, base + QUP_OPERATIONAL); | 606 | writel_relaxed(0, base + QUP_OPERATIONAL); |
609 | writel_relaxed(0, base + QUP_IO_M_MODES); | 607 | writel_relaxed(0, base + QUP_IO_M_MODES); |
610 | writel_relaxed(0, base + QUP_OPERATIONAL_MASK); | 608 | |
609 | if (!controller->qup_v1) | ||
610 | writel_relaxed(0, base + QUP_OPERATIONAL_MASK); | ||
611 | |||
611 | writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN, | 612 | writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN, |
612 | base + SPI_ERROR_FLAGS_EN); | 613 | base + SPI_ERROR_FLAGS_EN); |
613 | 614 | ||
615 | /* if earlier version of the QUP, disable INPUT_OVERRUN */ | ||
616 | if (controller->qup_v1) | ||
617 | writel_relaxed(QUP_ERROR_OUTPUT_OVER_RUN | | ||
618 | QUP_ERROR_INPUT_UNDER_RUN | QUP_ERROR_OUTPUT_UNDER_RUN, | ||
619 | base + QUP_ERROR_FLAGS_EN); | ||
620 | |||
614 | writel_relaxed(0, base + SPI_CONFIG); | 621 | writel_relaxed(0, base + SPI_CONFIG); |
615 | writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL); | 622 | writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL); |
616 | 623 | ||
@@ -732,6 +739,7 @@ static int spi_qup_remove(struct platform_device *pdev) | |||
732 | } | 739 | } |
733 | 740 | ||
734 | static const struct of_device_id spi_qup_dt_match[] = { | 741 | static const struct of_device_id spi_qup_dt_match[] = { |
742 | { .compatible = "qcom,spi-qup-v1.1.1", }, | ||
735 | { .compatible = "qcom,spi-qup-v2.1.1", }, | 743 | { .compatible = "qcom,spi-qup-v2.1.1", }, |
736 | { .compatible = "qcom,spi-qup-v2.2.1", }, | 744 | { .compatible = "qcom,spi-qup-v2.2.1", }, |
737 | { } | 745 | { } |