# HG changeset patch
# User Dmitriy Taychenachev <dimichxp@gmail.com>
# Date 1248614209 -32400

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -118,7 +118,7 @@
 
 config SPI_IMX
 	tristate "Freescale iMX SPI controller"
-	depends on ARCH_MX1 && EXPERIMENTAL
+	depends on (ARCH_MX1 || ARCH_SCMA11) && EXPERIMENTAL
 	help
 	  This enables using the Freescale iMX SPI controller in master
 	  mode.
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -35,6 +35,10 @@
 #include <asm/irq.h>
 #include <asm/delay.h>
 
+#ifdef CONFIG_ARCH_SCMA11
+#define SPI_DISABLE_DMA
+#endif
+
 #include <mach/hardware.h>
 #ifndef SPI_DISABLE_DMA
 #include <mach/imx-dma.h>
@@ -43,6 +47,7 @@
 
 /*-------------------------------------------------------------------------*/
 /* SPI Registers offsets from peripheral base address */
+#ifndef CONFIG_ARCH_SCMA11
 #define SPI_RXDATA		(0x00)
 #define SPI_TXDATA		(0x04)
 #define SPI_CONTROL		(0x08)
@@ -52,8 +57,20 @@
 #define SPI_PERIOD		(0x14)
 #define SPI_DMA			(0x18)
 #define SPI_RESET		(0x1C)
+#else
+#define SPI_RXDATA              (0x00)
+#define SPI_TXDATA              (0x04)
+#define SPI_CONTROL             (0x08)
+#define SPI_INT                 (0x0C)
+#define SPI_DMA                 (0x10)
+#define SPI_STAT                (0x14)
+#define SPI_PERIOD              (0x18)
+#define SPI_TEST                (0x1C)
+#endif /* CONFIG_ARCH_SCMA11 */
 
 /* SPI Control Register Bit Fields & Masks */
+#ifndef CONFIG_ARCH_SCMA11
+
 #define SPI_CONTROL_BITCOUNT_MASK	(0xF)		/* Bit Count Mask */
 #define SPI_CONTROL_BITCOUNT(n)		(((n) - 1) & SPI_CONTROL_BITCOUNT_MASK)
 #define SPI_CONTROL_POL			(0x1 << 4)      /* Clock Polarity Mask */
@@ -80,6 +97,7 @@
 #define SPI_CONTROL_DRCTL_1		(0x1 << 11)     /* /SPI_RDY falling edge triggers input */
 #define SPI_CONTROL_DRCTL_2		(0x2 << 11)     /* /SPI_RDY active low level triggers input */
 #define SPI_CONTROL_DATARATE		(0x7 << 13)     /* Data Rate Mask */
+#define SPI_CONTROL_DATARATE_OFFSET	(13)		/* Data Rate Offset */
 #define SPI_PERCLK2_DIV_MIN		(0)		/* PERCLK2:4 */
 #define SPI_PERCLK2_DIV_MAX		(7)		/* PERCLK2:512 */
 #define SPI_CONTROL_DATARATE_MIN	(SPI_PERCLK2_DIV_MAX << 13)
@@ -106,6 +124,68 @@
 #define SPI_INTEN_BO	(0x1 << 15)     /* Bit Count Overflow Interrupt Enable */
 #define SPI_INTEN	(0xFF << 8)	/* SPI Interrupt Enable Mask */
 
+#else /* CONFIG_ARCH_SCMA11 */
+
+#define SPI_CONTROL_SPIEN		(0x1 << 0)      /* SPI Module Enable */
+#define SPI_CONTROL_MODE		(0x1 << 1)      /* SPI Mode Select Mask */
+#define SPI_CONTROL_MODE_SLAVE		(0x0 << 1)      /* SPI Mode Slave */
+#define SPI_CONTROL_MODE_MASTER		(0x1 << 1)      /* SPI Mode Master */
+#define SPI_CONTROL_XCH			(0x1 << 2)      /* Exchange */
+#define SPI_CONTROL_SMC			(0x1 << 3)      /* Start Mode Control */
+#define SPI_CONTROL_SMC_XCH		(0x0 << 3)      /* XCH controls burst start */
+#define SPI_CONTROL_SMC_IMMEDIATE	(0x1 << 3)      /* Start burst immediately */
+#define SPI_CONTROL_POL			(0x1 << 4)      /* Clock Polarity Mask */
+#define SPI_CONTROL_POL_ACT_HIGH	(0x0 << 4)      /* Active high pol. (0=idle) */
+#define SPI_CONTROL_POL_ACT_LOW		(0x1 << 4)      /* Active low pol. (1=idle) */
+#define SPI_CONTROL_PHA			(0x1 << 5)      /* Clock Phase Mask */
+#define SPI_CONTROL_PHA_0		(0x0 << 5)      /* Clock Phase 0 */
+#define SPI_CONTROL_PHA_1		(0x1 << 5)      /* Clock Phase 1 */
+#define SPI_CONTROL_SSCTL		(0x1 << 6)      /* /SS Waveform Select Mask */
+#define SPI_CONTROL_SSCTL_0		(0x0 << 6)      /* Master: /SS stays low between SPI burst
+							   Slave: RXFIFO advanced by BIT_COUNT */
+#define SPI_CONTROL_SSCTL_1		(0x1 << 6)      /* Master: /SS insert pulse between SPI burst
+							   Slave: RXFIFO advanced by /SS rising edge */
+#define SPI_CONTROL_SSPOL		(0x1 << 7)      /* /SS Polarity Select Mask */
+#define SPI_CONTROL_SSPOL_ACT_LOW	(0x0 << 7)      /* /SS Active low */
+#define SPI_CONTROL_SSPOL_ACT_HIGH	(0x1 << 7)      /* /SS Active high */
+#define SPI_CONTROL_DRCTL		(0x3 << 8)      /* /SPI_RDY Control Mask */
+#define SPI_CONTROL_DRCTL_0		(0x0 << 8)      /* Ignore /SPI_RDY */
+#define SPI_CONTROL_DRCTL_1		(0x1 << 8)      /* /SPI_RDY falling edge triggers input */
+#define SPI_CONTROL_DRCTL_2		(0x2 << 8)      /* /SPI_RDY active low level triggers input */
+#define SPI_CONTROL_CHIPSELECT_MASK	(0x3 << 12)	/* Chip Select mask */
+#define SPI_CONTROL_CHIPSELECT(n)	((n) << 12 & SPI_CONTROL_CHIPSELECT_MASK)
+#define SPI_CONTROL_DATARATE		(0x7 << 16)     /* Data Rate Mask */
+#define SPI_CONTROL_DATARATE_OFFSET	(16)		/* Data Rate Offset */
+#define SPI_PERCLK2_DIV_MIN		(0)		/* PERCLK2:4 */
+#define SPI_PERCLK2_DIV_MAX		(7)		/* PERCLK2:512 */
+#define SPI_CONTROL_DATARATE_MIN	(SPI_PERCLK2_DIV_MAX << 16)
+#define SPI_CONTROL_DATARATE_MAX	(SPI_PERCLK2_DIV_MIN << 16)
+#define SPI_CONTROL_DATARATE_BAD	(SPI_CONTROL_DATARATE_MIN + 1)
+#define SPI_CONTROL_BITCOUNT_MASK	(0x1F << 20)	/* Bit Count Mask */
+#define SPI_CONTROL_BITCOUNT(n)		(((n) - 1) << 20 & SPI_CONTROL_BITCOUNT_MASK)
+
+/* SPI Interrupt/Status Register Bit Fields & Masks */
+#define SPI_STATUS_TE	(0x1 << 0)	/* TXFIFO Empty Status */
+#define SPI_STATUS_TH	(0x1 << 1)      /* TXFIFO Half Status */
+#define SPI_STATUS_TF	(0x1 << 2)      /* TXFIFO Full Status */
+#define SPI_STATUS_RR	(0x1 << 3)      /* RXFIFO Data Ready Status */
+#define SPI_STATUS_RH	(0x1 << 4)      /* RXFIFO Half Status */
+#define SPI_STATUS_RF	(0x1 << 5)      /* RXFIFO Full Status */
+#define SPI_STATUS_RO	(0x1 << 6)      /* RXFIFO Overflow */
+#define SPI_STATUS_TC	(0x1 << 7)      /* Transfer Completed */
+#define SPI_STATUS	(0xFF)		/* SPI Status Mask */
+#define SPI_INTEN_TE	(0x1 << 0)      /* TXFIFO Empty Interrupt Enable */
+#define SPI_INTEN_TH	(0x1 << 1)      /* TXFIFO Half Interrupt Enable */
+#define SPI_INTEN_TF	(0x1 << 2)      /* TXFIFO Full Interrupt Enable */
+#define SPI_INTEN_RE	(0x1 << 3)      /* RXFIFO Data Ready Interrupt Enable */
+#define SPI_INTEN_RH	(0x1 << 4)      /* RXFIFO Half Interrupt Enable */
+#define SPI_INTEN_RF	(0x1 << 5)      /* RXFIFO Full Interrupt Enable */
+#define SPI_INTEN_RO	(0x1 << 6)      /* RXFIFO Overflow Interrupt Enable */
+#define SPI_INTEN_TC	(0x1 << 7)      /* Transfer Completed Interrupt Enable */
+#define SPI_INTEN	(0xFF)		/* SPI Interrupt Enable Mask */
+
+#endif /* CONFIG_ARCH_SCMA11 */
+
 /* SPI Test Register Bit Fields & Masks */
 #define SPI_TEST_TXCNT		(0xF << 0)	/* TXFIFO Counter */
 #define SPI_TEST_RXCNT_LSB	(4)		/* RXFIFO Counter LSB */
@@ -124,6 +204,8 @@
 							32.768 KHz Clock */
 
 /* SPI DMA Register Bit Fields & Masks */
+#ifndef CONFIG_ARCH_SCMA11
+
 #define SPI_DMA_RHDMA	(0x1 << 4)	/* RXFIFO Half Status */
 #define SPI_DMA_RFDMA	(0x1 << 5)      /* RXFIFO Full Status */
 #define SPI_DMA_TEDMA	(0x1 << 6)      /* TXFIFO Empty Status */
@@ -148,6 +230,30 @@
 	SPI_CONTROL_DRCTL_0 |		\
 	SPI_CONTROL_DATARATE_MIN	\
 )
+
+#else /* CONFIG_ARCH_SCMA11 */
+
+#define SPI_DMA_TEDMA	(0x1 << 0)      /* TXFIFO Empty Status */
+#define SPI_DMA_THDMA	(0x1 << 1)      /* TXFIFO Half Status */
+#define SPI_DMA_RHDMA	(0x1 << 4)	/* RXFIFO Half Status */
+#define SPI_DMA_RFDMA	(0x1 << 5)      /* RXFIFO Full Status */
+
+/* Default SPI configuration values */
+#define SPI_DEFAULT_CONTROL		\
+(					\
+	SPI_CONTROL_SPIEN |		\
+	SPI_CONTROL_MODE_MASTER |	\
+	SPI_CONTROL_SMC_XCH |		\
+	SPI_CONTROL_POL_ACT_HIGH |	\
+	SPI_CONTROL_PHA_0 |		\
+	SPI_CONTROL_SSCTL_1 |		\
+	SPI_CONTROL_BITCOUNT(16) | 	\
+	SPI_CONTROL_DATARATE_MIN |	\
+	SPI_CONTROL_DRCTL_0		\
+)
+
+#endif /* CONFIG_ARCH_SCMA11 */
+
 #define SPI_DEFAULT_ENABLE_LOOPBACK	(0)
 #define SPI_DEFAULT_ENABLE_DMA		(0)
 #define SPI_DEFAULT_PERIOD_WAIT		(8)
@@ -871,7 +977,8 @@
 
 static inline u32 spi_speed_hz(struct driver_data *drv_data, u32 data_rate)
 {
-	return clk_get_rate(drv_data->clk) / (4 << ((data_rate) >> 13));
+	return clk_get_rate(drv_data->clk) /
+		(4 << ((data_rate) >> SPI_CONTROL_DATARATE_OFFSET));
 }
 
 static u32 spi_data_rate(struct driver_data *drv_data, u32 speed_hz)
@@ -884,7 +991,7 @@
 		div++, quantized_hz >>= 1) {
 			if (quantized_hz <= speed_hz)
 				/* Max available speed LEQ required speed */
-				return div << 13;
+				return div << SPI_CONTROL_DATARATE_OFFSET;
 	}
 	return SPI_CONTROL_DATARATE_BAD;
 }
@@ -957,7 +1064,8 @@
 	} else
 		/* Use per-transfer setup */
 		drv_data->n_bytes = (tmp <= 8) ? 1 : 2;
-	u32_EDIT(control, SPI_CONTROL_BITCOUNT_MASK, tmp - 1);
+	u32_EDIT(control, SPI_CONTROL_BITCOUNT_MASK,
+		   SPI_CONTROL_BITCOUNT(tmp));
 
 	/* Speed setup (surely valid because already checked) */
 	tmp = transfer->speed_hz;
@@ -1308,7 +1416,8 @@
 		}
 	}
 	chip->bits_per_word = tmp;
-	u32_EDIT(chip->control, SPI_CONTROL_BITCOUNT_MASK, tmp - 1);
+	u32_EDIT(chip->control, SPI_CONTROL_BITCOUNT_MASK,
+		   SPI_CONTROL_BITCOUNT(tmp));
 	chip->n_bytes = (tmp <= 8) ? 1 : 2;
 
 	/* SPI datarate */
@@ -1340,6 +1449,12 @@
 	else
 		chip->cs_control = null_cs_control;
 
+#ifdef SPI_CONTROL_CHIPSELECT
+	/* Select required SPI slave */
+	u32_EDIT(chip->control, SPI_CONTROL_CHIPSELECT_MASK,
+		 SPI_CONTROL_CHIPSELECT(spi->chip_select));
+#endif
+
 	/* Save controller_state */
 	spi_set_ctldata(spi, chip);
 
@@ -1457,6 +1572,16 @@
 	return 0;
 }
 
+static void spi_reset(struct driver_data *drv_data)
+{
+#ifdef CONFIG_ARCH_SCMA11
+	writel(0, drv_data->regs + SPI_CONTROL);
+#else
+	writel(SPI_RESET_START, drv_data->regs + SPI_RESET);
+	writel(0, drv_data->regs + SPI_RESET);
+#endif
+}
+	
 static int __init spi_imx_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1607,8 +1732,7 @@
 #endif /* SPI_DISABLE_DMA */
 
 	/* Load default SPI configuration */
-	writel(SPI_RESET_START, drv_data->regs + SPI_RESET);
-	writel(0, drv_data->regs + SPI_RESET);
+	spi_reset(drv_data);
 	writel(SPI_DEFAULT_CONTROL, drv_data->regs + SPI_CONTROL);
 
 	/* Initial and start queue */
@@ -1685,9 +1809,7 @@
 		return status;
 	}
 
-	/* Reset SPI */
-	writel(SPI_RESET_START, drv_data->regs + SPI_RESET);
-	writel(0, drv_data->regs + SPI_RESET);
+	spi_reset(drv_data);
 
 #ifndef SPI_DISABLE_DMA
 	/* Release DMA */
@@ -1728,9 +1850,7 @@
 {
 	struct driver_data *drv_data = platform_get_drvdata(pdev);
 
-	/* Reset SPI */
-	writel(SPI_RESET_START, drv_data->regs + SPI_RESET);
-	writel(0, drv_data->regs + SPI_RESET);
+	spi_reset(drv_data);
 
 	dev_dbg(&pdev->dev, "shutdown succeded\n");
 }


