Commit 15f8c9af authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'spi/topic/loopback', 'spi/topic/meson-spicc',...

Merge remote-tracking branches 'spi/topic/loopback', 'spi/topic/meson-spicc', 'spi/topic/mtk' and 'spi/topic/omap2-mcspi' into spi-next
...@@ -20,3 +20,34 @@ Required properties: ...@@ -20,3 +20,34 @@ Required properties:
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
}; };
* SPICC (SPI Communication Controller)
The Meson SPICC is generic SPI controller for general purpose Full-Duplex
communications with dedicated 16 words RX/TX PIO FIFOs.
Required properties:
- compatible: should be "amlogic,meson-gx-spicc" on Amlogic GX SoCs.
- reg: physical base address and length of the controller registers
- interrupts: The interrupt specifier
- clock-names: Must contain "core"
- clocks: phandle of the input clock for the baud rate generator
- #address-cells: should be 1
- #size-cells: should be 0
Optional properties:
- resets: phandle of the internal reset line
See ../spi/spi-bus.txt for more details on SPI bus master and slave devices
required and optional properties.
Example :
spi@c1108d80 {
compatible = "amlogic,meson-gx-spicc";
reg = <0xc1108d80 0x80>;
interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "core";
clocks = <&clk81>;
#address-cells = <1>;
#size-cells = <0>;
};
...@@ -3,7 +3,9 @@ Binding for MTK SPI controller ...@@ -3,7 +3,9 @@ Binding for MTK SPI controller
Required properties: Required properties:
- compatible: should be one of the following. - compatible: should be one of the following.
- mediatek,mt2701-spi: for mt2701 platforms - mediatek,mt2701-spi: for mt2701 platforms
- mediatek,mt2712-spi: for mt2712 platforms
- mediatek,mt6589-spi: for mt6589 platforms - mediatek,mt6589-spi: for mt6589 platforms
- mediatek,mt7622-spi: for mt7622 platforms
- mediatek,mt8135-spi: for mt8135 platforms - mediatek,mt8135-spi: for mt8135 platforms
- mediatek,mt8173-spi: for mt8173 platforms - mediatek,mt8173-spi: for mt8173 platforms
......
...@@ -393,6 +393,13 @@ config SPI_FSL_ESPI ...@@ -393,6 +393,13 @@ config SPI_FSL_ESPI
From MPC8536, 85xx platform uses the controller, and all P10xx, From MPC8536, 85xx platform uses the controller, and all P10xx,
P20xx, P30xx,P40xx, P50xx uses this controller. P20xx, P30xx,P40xx, P50xx uses this controller.
config SPI_MESON_SPICC
tristate "Amlogic Meson SPICC controller"
depends on ARCH_MESON || COMPILE_TEST
help
This enables master mode support for the SPICC (SPI communication
controller) available in Amlogic Meson SoCs.
config SPI_MESON_SPIFC config SPI_MESON_SPIFC
tristate "Amlogic Meson SPIFC controller" tristate "Amlogic Meson SPIFC controller"
depends on ARCH_MESON || COMPILE_TEST depends on ARCH_MESON || COMPILE_TEST
......
...@@ -53,6 +53,7 @@ obj-$(CONFIG_SPI_LANTIQ_SSC) += spi-lantiq-ssc.o ...@@ -53,6 +53,7 @@ obj-$(CONFIG_SPI_LANTIQ_SSC) += spi-lantiq-ssc.o
obj-$(CONFIG_SPI_JCORE) += spi-jcore.o obj-$(CONFIG_SPI_JCORE) += spi-jcore.o
obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o
obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o
obj-$(CONFIG_SPI_MESON_SPICC) += spi-meson-spicc.o
obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o
obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o
obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o
......
...@@ -894,7 +894,7 @@ int spi_test_execute_msg(struct spi_device *spi, struct spi_test *test, ...@@ -894,7 +894,7 @@ int spi_test_execute_msg(struct spi_device *spi, struct spi_test *test,
test->elapsed_time = ktime_to_ns(ktime_sub(ktime_get(), start)); test->elapsed_time = ktime_to_ns(ktime_sub(ktime_get(), start));
if (ret == -ETIMEDOUT) { if (ret == -ETIMEDOUT) {
dev_info(&spi->dev, dev_info(&spi->dev,
"spi-message timed out - reruning...\n"); "spi-message timed out - rerunning...\n");
/* rerun after a few explicit schedules */ /* rerun after a few explicit schedules */
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
schedule(); schedule();
...@@ -1021,10 +1021,9 @@ int spi_test_run_tests(struct spi_device *spi, ...@@ -1021,10 +1021,9 @@ int spi_test_run_tests(struct spi_device *spi,
rx = vmalloc(SPI_TEST_MAX_SIZE_PLUS); rx = vmalloc(SPI_TEST_MAX_SIZE_PLUS);
else else
rx = kzalloc(SPI_TEST_MAX_SIZE_PLUS, GFP_KERNEL); rx = kzalloc(SPI_TEST_MAX_SIZE_PLUS, GFP_KERNEL);
if (!rx) { if (!rx)
ret = -ENOMEM; return -ENOMEM;
goto out;
}
if (use_vmalloc) if (use_vmalloc)
tx = vmalloc(SPI_TEST_MAX_SIZE_PLUS); tx = vmalloc(SPI_TEST_MAX_SIZE_PLUS);
...@@ -1032,7 +1031,7 @@ int spi_test_run_tests(struct spi_device *spi, ...@@ -1032,7 +1031,7 @@ int spi_test_run_tests(struct spi_device *spi,
tx = kzalloc(SPI_TEST_MAX_SIZE_PLUS, GFP_KERNEL); tx = kzalloc(SPI_TEST_MAX_SIZE_PLUS, GFP_KERNEL);
if (!tx) { if (!tx) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto err_tx;
} }
/* now run the individual tests in the table */ /* now run the individual tests in the table */
...@@ -1057,8 +1056,9 @@ int spi_test_run_tests(struct spi_device *spi, ...@@ -1057,8 +1056,9 @@ int spi_test_run_tests(struct spi_device *spi,
} }
out: out:
kvfree(rx);
kvfree(tx); kvfree(tx);
err_tx:
kvfree(rx);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(spi_test_run_tests); EXPORT_SYMBOL_GPL(spi_test_run_tests);
This diff is collapsed.
...@@ -35,11 +35,15 @@ ...@@ -35,11 +35,15 @@
#define SPI_CMD_REG 0x0018 #define SPI_CMD_REG 0x0018
#define SPI_STATUS0_REG 0x001c #define SPI_STATUS0_REG 0x001c
#define SPI_PAD_SEL_REG 0x0024 #define SPI_PAD_SEL_REG 0x0024
#define SPI_CFG2_REG 0x0028
#define SPI_CFG0_SCK_HIGH_OFFSET 0 #define SPI_CFG0_SCK_HIGH_OFFSET 0
#define SPI_CFG0_SCK_LOW_OFFSET 8 #define SPI_CFG0_SCK_LOW_OFFSET 8
#define SPI_CFG0_CS_HOLD_OFFSET 16 #define SPI_CFG0_CS_HOLD_OFFSET 16
#define SPI_CFG0_CS_SETUP_OFFSET 24 #define SPI_CFG0_CS_SETUP_OFFSET 24
#define SPI_ADJUST_CFG0_SCK_LOW_OFFSET 16
#define SPI_ADJUST_CFG0_CS_HOLD_OFFSET 0
#define SPI_ADJUST_CFG0_CS_SETUP_OFFSET 16
#define SPI_CFG1_CS_IDLE_OFFSET 0 #define SPI_CFG1_CS_IDLE_OFFSET 0
#define SPI_CFG1_PACKET_LOOP_OFFSET 8 #define SPI_CFG1_PACKET_LOOP_OFFSET 8
...@@ -55,6 +59,8 @@ ...@@ -55,6 +59,8 @@
#define SPI_CMD_RST BIT(2) #define SPI_CMD_RST BIT(2)
#define SPI_CMD_PAUSE_EN BIT(4) #define SPI_CMD_PAUSE_EN BIT(4)
#define SPI_CMD_DEASSERT BIT(5) #define SPI_CMD_DEASSERT BIT(5)
#define SPI_CMD_SAMPLE_SEL BIT(6)
#define SPI_CMD_CS_POL BIT(7)
#define SPI_CMD_CPHA BIT(8) #define SPI_CMD_CPHA BIT(8)
#define SPI_CMD_CPOL BIT(9) #define SPI_CMD_CPOL BIT(9)
#define SPI_CMD_RX_DMA BIT(10) #define SPI_CMD_RX_DMA BIT(10)
...@@ -80,6 +86,8 @@ struct mtk_spi_compatible { ...@@ -80,6 +86,8 @@ struct mtk_spi_compatible {
bool need_pad_sel; bool need_pad_sel;
/* Must explicitly send dummy Tx bytes to do Rx only transfer */ /* Must explicitly send dummy Tx bytes to do Rx only transfer */
bool must_tx; bool must_tx;
/* some IC design adjust cfg register to enhance time accuracy */
bool enhance_timing;
}; };
struct mtk_spi { struct mtk_spi {
...@@ -96,6 +104,16 @@ struct mtk_spi { ...@@ -96,6 +104,16 @@ struct mtk_spi {
}; };
static const struct mtk_spi_compatible mtk_common_compat; static const struct mtk_spi_compatible mtk_common_compat;
static const struct mtk_spi_compatible mt2712_compat = {
.must_tx = true,
};
static const struct mtk_spi_compatible mt7622_compat = {
.must_tx = true,
.enhance_timing = true,
};
static const struct mtk_spi_compatible mt8173_compat = { static const struct mtk_spi_compatible mt8173_compat = {
.need_pad_sel = true, .need_pad_sel = true,
.must_tx = true, .must_tx = true,
...@@ -108,15 +126,23 @@ static const struct mtk_spi_compatible mt8173_compat = { ...@@ -108,15 +126,23 @@ static const struct mtk_spi_compatible mt8173_compat = {
static const struct mtk_chip_config mtk_default_chip_info = { static const struct mtk_chip_config mtk_default_chip_info = {
.rx_mlsb = 1, .rx_mlsb = 1,
.tx_mlsb = 1, .tx_mlsb = 1,
.cs_pol = 0,
.sample_sel = 0,
}; };
static const struct of_device_id mtk_spi_of_match[] = { static const struct of_device_id mtk_spi_of_match[] = {
{ .compatible = "mediatek,mt2701-spi", { .compatible = "mediatek,mt2701-spi",
.data = (void *)&mtk_common_compat, .data = (void *)&mtk_common_compat,
}, },
{ .compatible = "mediatek,mt2712-spi",
.data = (void *)&mt2712_compat,
},
{ .compatible = "mediatek,mt6589-spi", { .compatible = "mediatek,mt6589-spi",
.data = (void *)&mtk_common_compat, .data = (void *)&mtk_common_compat,
}, },
{ .compatible = "mediatek,mt7622-spi",
.data = (void *)&mt7622_compat,
},
{ .compatible = "mediatek,mt8135-spi", { .compatible = "mediatek,mt8135-spi",
.data = (void *)&mtk_common_compat, .data = (void *)&mtk_common_compat,
}, },
...@@ -182,6 +208,17 @@ static int mtk_spi_prepare_message(struct spi_master *master, ...@@ -182,6 +208,17 @@ static int mtk_spi_prepare_message(struct spi_master *master,
reg_val |= SPI_CMD_RX_ENDIAN; reg_val |= SPI_CMD_RX_ENDIAN;
#endif #endif
if (mdata->dev_comp->enhance_timing) {
if (chip_config->cs_pol)
reg_val |= SPI_CMD_CS_POL;
else
reg_val &= ~SPI_CMD_CS_POL;
if (chip_config->sample_sel)
reg_val |= SPI_CMD_SAMPLE_SEL;
else
reg_val &= ~SPI_CMD_SAMPLE_SEL;
}
/* set finish and pause interrupt always enable */ /* set finish and pause interrupt always enable */
reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_IE; reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_IE;
...@@ -233,11 +270,25 @@ static void mtk_spi_prepare_transfer(struct spi_master *master, ...@@ -233,11 +270,25 @@ static void mtk_spi_prepare_transfer(struct spi_master *master,
sck_time = (div + 1) / 2; sck_time = (div + 1) / 2;
cs_time = sck_time * 2; cs_time = sck_time * 2;
reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET); if (mdata->dev_comp->enhance_timing) {
reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET); reg_val |= (((sck_time - 1) & 0xffff)
reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET); << SPI_CFG0_SCK_HIGH_OFFSET);
reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET); reg_val |= (((sck_time - 1) & 0xffff)
writel(reg_val, mdata->base + SPI_CFG0_REG); << SPI_ADJUST_CFG0_SCK_LOW_OFFSET);
writel(reg_val, mdata->base + SPI_CFG2_REG);
reg_val |= (((cs_time - 1) & 0xffff)
<< SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
reg_val |= (((cs_time - 1) & 0xffff)
<< SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
writel(reg_val, mdata->base + SPI_CFG0_REG);
} else {
reg_val |= (((sck_time - 1) & 0xff)
<< SPI_CFG0_SCK_HIGH_OFFSET);
reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
writel(reg_val, mdata->base + SPI_CFG0_REG);
}
reg_val = readl(mdata->base + SPI_CFG1_REG); reg_val = readl(mdata->base + SPI_CFG1_REG);
reg_val &= ~SPI_CFG1_CS_IDLE_MASK; reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
......
...@@ -1412,9 +1412,6 @@ static int omap2_mcspi_probe(struct platform_device *pdev) ...@@ -1412,9 +1412,6 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
sprintf(mcspi->dma_channels[i].dma_tx_ch_name, "tx%d", i); sprintf(mcspi->dma_channels[i].dma_tx_ch_name, "tx%d", i);
} }
if (status < 0)
goto free_master;
pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
......
...@@ -16,5 +16,7 @@ ...@@ -16,5 +16,7 @@
struct mtk_chip_config { struct mtk_chip_config {
u32 tx_mlsb; u32 tx_mlsb;
u32 rx_mlsb; u32 rx_mlsb;
u32 cs_pol;
u32 sample_sel;
}; };
#endif #endif
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