Skip to contentSkip to conversation

EXYNOS5: Enable SPI support

PATCH New Hatim Ali 2 participants 7 messages Nov 2, 2012 – Nov 5, 2012

Subsystems (3)
lore
Share & tools
lore

Hatim Ali

author
#0 lore raw

v9 cover EXYNOS5: Enable SPI support

This patch set adds SPI driver for EXYNOS5 and enables same. This patch set is based on latest u-boot-samsung.git tree.

Changes in V2:
- Correted the Commit message.
Changes in V3:
- Removed SPI_SLAVE Flag.
- Corrected warning messages.
Changes in V4:
- Rebased on mainline u-boot.git
- Incorporated review comments for SPI driver.
Changes in V5:
- Rebased on u-boot-samsung.git
- Incorporated review comments by Simon Glass
Changes in V6:
- Incorporated review comments by Minkyu Kang
Changes in V7:
- Incorporated review comments by Minkyu Kang & Simon Glass
Changes in V8:
- Rebased on u-boot-samsung.git
Changes in V9:
- Rebased on u-boot-samsung.git

Hatim Ali (3):
EXYNOS: Add clock for SPI
EXYNOS5: Add base address for SPI
EXYNOS5: Enable SPI

Rajeshwari Shinde (2):
SPI: Add SPI Driver for EXYNOS.
EXYNOS5: Enable SPI booting.

 arch/arm/cpu/armv7/exynos/clock.c      |  125 +++++++++++
 arch/arm/include/asm/arch-exynos/clk.h |    1 +
 arch/arm/include/asm/arch-exynos/cpu.h |    6 +
 arch/arm/include/asm/arch-exynos/spi.h |   78 +++++++
 board/samsung/smdk5250/Makefile        |    2 +-
 board/samsung/smdk5250/mmc_boot.c      |   58 -----
 board/samsung/smdk5250/smdk5250.c      |    4 +
 board/samsung/smdk5250/spl_boot.c      |   85 ++++++++
 drivers/spi/Makefile                   |    1 +
 drivers/spi/exynos_spi.c               |  367 ++++++++++++++++++++++++++++++++
 include/configs/smdk5250.h             |   27 +++-
 11 files changed, 694 insertions(+), 60 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-exynos/spi.h
 delete mode 100644 board/samsung/smdk5250/mmc_boot.c
 create mode 100644 board/samsung/smdk5250/spl_boot.c
 create mode 100644 drivers/spi/exynos_spi.c
Signature · 1 line
1.7.2.3
author
#1 lore raw

PATCH v9 1/5 EXYNOS: Add clock for SPI

Add api to calculate and set the clock for SPI channels

---
Changes since v4:
Added Signed-off-by of James Miller
Changes since v5:
Incorporated review comments by Minkyu Kang
Changes since v6:
Based on the review by Minkyu Kang, moved the include periph.h define to clock.c file
Changes since v7:
Rebased on u-boot-samsung.git
Added Acked-by Simon Glass
Changes since v8:
Rebased on u-boot-samsung.git

arch/arm/cpu/armv7/exynos/clock.c +125 -0
index 40a8c71..fe61f88 100644
@@ -25,6 +25,7 @@
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/clk.h>
+#include <asm/arch/periph.h>
 
 /* Epll Clock division values to achive different frequency output */
 static struct set_epll_con_val exynos5_epll_div[] = {
@@ -804,6 +805,122 @@ int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
 	return 0;
 }
 
+/**
+ * Linearly searches for the most accurate main and fine stage clock scalars
+ * (divisors) for a specified target frequency and scalar bit sizes by checking
+ * all multiples of main_scalar_bits values. Will always return scalars up to or
+ * slower than target.
+ *
+ * @param main_scalar_bits	Number of main scalar bits, must be > 0 and < 32
+ * @param fine_scalar_bits	Number of fine scalar bits, must be > 0 and < 32
+ * @param input_freq		Clock frequency to be scaled in Hz
+ * @param target_freq		Desired clock frequency in Hz
+ * @param best_fine_scalar	Pointer to store the fine stage divisor
+ *
+ * @return best_main_scalar	Main scalar for desired frequency or -1 if none
+ * found
+ */
+static int clock_calc_best_scalar(unsigned int main_scaler_bits,
+	unsigned int fine_scalar_bits, unsigned int input_rate,
+	unsigned int target_rate, unsigned int *best_fine_scalar)
+{
+	int i;
+	int best_main_scalar = -1;
+	unsigned int best_error = target_rate;
+	const unsigned int cap = (1 << fine_scalar_bits) - 1;
+	const unsigned int loops = 1 << main_scaler_bits;
+
+	debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
+			target_rate, cap);
+
+	assert(best_fine_scalar != NULL);
+	assert(main_scaler_bits <= fine_scalar_bits);
+
+	*best_fine_scalar = 1;
+
+	if (input_rate == 0 || target_rate == 0)
+		return -1;
+
+	if (target_rate >= input_rate)
+		return 1;
+
+	for (i = 1; i <= loops; i++) {
+		const unsigned int effective_div = max(min(input_rate / i /
+							target_rate, cap), 1);
+		const unsigned int effective_rate = input_rate / i /
+							effective_div;
+		const int error = target_rate - effective_rate;
+
+		debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
+				effective_rate, error);
+
+		if (error >= 0 && error <= best_error) {
+			best_error = error;
+			best_main_scalar = i;
+			*best_fine_scalar = effective_div;
+		}
+	}
+
+	return best_main_scalar;
+}
+
+static int exynos5_set_spi_clk(enum periph_id periph_id,
+					unsigned int rate)
+{
+	struct exynos5_clock *clk =
+		(struct exynos5_clock *)samsung_get_base_clock();
+	int main;
+	unsigned int fine;
+	unsigned shift, pre_shift;
+	unsigned mask = 0xff;
+	u32 *reg;
+
+	main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
+	if (main < 0) {
+		debug("%s: Cannot set clock rate for periph %d",
+				__func__, periph_id);
+		return -1;
+	}
+	main = main - 1;
+	fine = fine - 1;
+
+	switch (periph_id) {
+	case PERIPH_ID_SPI0:
+		reg = &clk->div_peric1;
+		shift = 0;
+		pre_shift = 8;
+		break;
+	case PERIPH_ID_SPI1:
+		reg = &clk->div_peric1;
+		shift = 16;
+		pre_shift = 24;
+		break;
+	case PERIPH_ID_SPI2:
+		reg = &clk->div_peric2;
+		shift = 0;
+		pre_shift = 8;
+		break;
+	case PERIPH_ID_SPI3:
+		reg = &clk->sclk_div_isp;
+		shift = 0;
+		pre_shift = 4;
+		break;
+	case PERIPH_ID_SPI4:
+		reg = &clk->sclk_div_isp;
+		shift = 12;
+		pre_shift = 16;
+		break;
+	default:
+		debug("%s: Unsupported peripheral ID %d\n", __func__,
+		      periph_id);
+		return -1;
+	}
+	clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
+	clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
+
+	return 0;
+}
+
 unsigned long get_pll_clk(int pllreg)
 {
 	if (cpu_is_exynos5())
@@ -876,6 +993,14 @@ void set_mipi_clk(void)
 		exynos4_set_mipi_clk();
 }
 
+int set_spi_clk(int periph_id, unsigned int rate)
+{
+	if (cpu_is_exynos5())
+		return exynos5_set_spi_clk(periph_id, rate);
+	else
+		return 0;
+}
+
 int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq)
 {
 
arch/arm/include/asm/arch-exynos/clk.h +1 -0
index 2bf2c10..cd12323 100644
@@ -41,5 +41,6 @@ void set_mipi_clk(void);
 void set_i2s_clk_source(void);
 int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq);
 int set_epll_clk(unsigned long rate);
+int set_spi_clk(int periph_id, unsigned int rate);
 
 #endif
Signature · 1 line
1.7.2.3
author
#2 lore raw

PATCH v9 2/5 EXYNOS5: Add base address for SPI

In reply to Hatim Ali

Add base address definition for SPI device on Exynos.

---
Changes since v4:
- Rebased on u-boot-samsung.git
- Added Acked-by Simon Glass
Changes since v5:
No Change
Changes since v6:
No Change
Changes since v7:
No Change
Changes since v8:
- Rebased on u-boot-samsung.git

arch/arm/include/asm/arch-exynos/cpu.h +6 -0
index e289e9e..d1b2ea8 100644
@@ -51,6 +51,7 @@
 #define EXYNOS4_UART_BASE		0x13800000
 #define EXYNOS4_I2C_BASE		0x13860000
 #define EXYNOS4_ADC_BASE		0x13910000
+#define EXYNOS4_SPI_BASE		0x13920000
 #define EXYNOS4_PWMTIMER_BASE		0x139D0000
 #define EXYNOS4_MODEM_BASE		0x13A00000
 #define EXYNOS4_USBPHY_CONTROL		0x10020704
@@ -58,6 +59,7 @@
 
 #define EXYNOS4_GPIO_PART4_BASE		DEVICE_NOT_AVAILABLE
 #define EXYNOS4_DP_BASE			DEVICE_NOT_AVAILABLE
+#define EXYNOS4_SPI_ISP_BASE		DEVICE_NOT_AVAILABLE
 
 /* EXYNOS5 */
 #define EXYNOS5_I2C_SPACING		0x10000
@@ -82,8 +84,10 @@
 #define EXYNOS5_SROMC_BASE		0x12250000
 #define EXYNOS5_UART_BASE		0x12C00000
 #define EXYNOS5_I2C_BASE		0x12C60000
+#define EXYNOS5_SPI_BASE		0x12D20000
 #define EXYNOS5_I2S_BASE		0x12D60000
 #define EXYNOS5_PWMTIMER_BASE		0x12DD0000
+#define EXYNOS5_SPI_ISP_BASE		0x131A0000
 #define EXYNOS5_GPIO_PART2_BASE		0x13400000
 #define EXYNOS5_FIMD_BASE		0x14400000
 #define EXYNOS5_DP_BASE			0x145B0000
@@ -185,6 +189,8 @@ SAMSUNG_BASE(usb_ehci, USB_HOST_EHCI_BASE)
 SAMSUNG_BASE(usb_otg, USBOTG_BASE)
 SAMSUNG_BASE(watchdog, WATCHDOG_BASE)
 SAMSUNG_BASE(power, POWER_BASE)
+SAMSUNG_BASE(spi, SPI_BASE)
+SAMSUNG_BASE(spi_isp, SPI_ISP_BASE)
 #endif
 
 #endif	/* _EXYNOS4_CPU_H */
Signature · 1 line
1.7.2.3
author
#3 lore raw

PATCH v9 3/5 SPI: Add SPI Driver for EXYNOS.

In reply to Hatim Ali

From: Rajeshwari Shinde <[email protected]>

This patch adds SPI driver for EXYNOS.

---
Changes since V4:
- Changed SPI bus frequency to 10 Mhz
Changes since V5:
- Incorporated changes by Minkyu Kang
Changes since V6:
- No Change
Changes since V7:
- Incorporated minor nit as suggested by Simon Glass (added blank line)
- Added Acked-by Simon Glass
Changes since V8:
- No Change

arch/arm/include/asm/arch-exynos/spi.h new file +78 -0
new file mode 100644
index 0000000..7cab1e9
@@ -0,0 +1,78 @@
+/*
+ * (C) Copyright 2012 SAMSUNG Electronics
+ * Padmavathi Venna <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_EXYNOS_COMMON_SPI_H_
+#define __ASM_ARCH_EXYNOS_COMMON_SPI_H_
+
+#ifndef __ASSEMBLY__
+
+/* SPI peripheral register map; padded to 64KB */
+struct exynos_spi {
+	unsigned int		ch_cfg;		/* 0x00 */
+	unsigned char		reserved0[4];
+	unsigned int		mode_cfg;	/* 0x08 */
+	unsigned int		cs_reg;		/* 0x0c */
+	unsigned char		reserved1[4];
+	unsigned int		spi_sts;	/* 0x14 */
+	unsigned int		tx_data;	/* 0x18 */
+	unsigned int		rx_data;	/* 0x1c */
+	unsigned int		pkt_cnt;	/* 0x20 */
+	unsigned char		reserved2[4];
+	unsigned char		reserved3[4];
+	unsigned int		fb_clk;		/* 0x2c */
+	unsigned char		padding[0xffd0];
+};
+
+#define EXYNOS_SPI_MAX_FREQ	50000000
+
+#define SPI_TIMEOUT_MS		10
+
+/* SPI_CHCFG */
+#define SPI_CH_HS_EN		(1 << 6)
+#define SPI_CH_RST		(1 << 5)
+#define SPI_SLAVE_MODE		(1 << 4)
+#define SPI_CH_CPOL_L		(1 << 3)
+#define SPI_CH_CPHA_B		(1 << 2)
+#define SPI_RX_CH_ON		(1 << 1)
+#define SPI_TX_CH_ON		(1 << 0)
+
+/* SPI_MODECFG */
+#define SPI_MODE_CH_WIDTH_WORD	(0x2 << 29)
+#define SPI_MODE_BUS_WIDTH_WORD	(0x2 << 17)
+
+/* SPI_CSREG */
+#define SPI_SLAVE_SIG_INACT	(1 << 0)
+
+/* SPI_STS */
+#define SPI_ST_TX_DONE		(1 << 25)
+#define SPI_FIFO_LVL_MASK	0x1ff
+#define SPI_TX_LVL_OFFSET	6
+#define SPI_RX_LVL_OFFSET	15
+
+/* Feedback Delay */
+#define SPI_CLK_BYPASS		(0 << 0)
+#define SPI_FB_DELAY_90		(1 << 0)
+#define SPI_FB_DELAY_180	(2 << 0)
+#define SPI_FB_DELAY_270	(3 << 0)
+
+/* Packet Count */
+#define SPI_PACKET_CNT_EN	(1 << 16)
+
+#endif /* __ASSEMBLY__ */
+#endif
drivers/spi/Makefile +1 -0
index f0b82c6..824d357 100644
@@ -34,6 +34,7 @@ COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o
 COBJS-$(CONFIG_CF_SPI) += cf_spi.o
 COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o
 COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
+COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
 COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
 COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
 COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
drivers/spi/exynos_spi.c new file +367 -0

367 lines not on this page · raw message

Signature · 1 line
1.7.2.3
author
#4 lore raw

PATCH v9 4/5 EXYNOS5: Enable SPI

In reply to Hatim Ali

This patch enables SPI driver for EXYNOS5.

---
Changes since v4:
- Rebased on u-boot-samsung.git
Changes since v5:
No change
Changes since v6:
Removed unused define from the config file
Changes since v7:
- Rebased on u-boot-samsung.git
- Added Acked by Simon Glass
Changes since v8:
No change

board/samsung/smdk5250/smdk5250.c +4 -0
index 18dd5d2..4c50342 100644
@@ -24,6 +24,7 @@
 #include <asm/io.h>
 #include <i2c.h>
 #include <netdev.h>
+#include <spi.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
@@ -67,6 +68,9 @@ int board_init(void)
 #if defined(CONFIG_PMIC)
 	pmic_init();
 #endif
+#ifdef CONFIG_EXYNOS_SPI
+	spi_init();
+#endif
 	return 0;
 }
 
include/configs/smdk5250.h +21 -1
index 819493a..4973c33 100644
@@ -163,7 +163,6 @@
 #undef CONFIG_CMD_IMLS
 #define CONFIG_IDENT_STRING		" for SMDK5250"
 
-#define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV		0
 
 #define CONFIG_SECURE_BL1_ONLY
@@ -209,6 +208,27 @@
 #define CONFIG_PMIC_I2C
 #define CONFIG_PMIC_MAX77686
 
+/* SPI */
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_SPI_FLASH
+
+#ifdef CONFIG_SPI_FLASH
+#define CONFIG_EXYNOS_SPI
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SPI
+#define CONFIG_SPI_FLASH_WINBOND
+#define CONFIG_SF_DEFAULT_MODE		SPI_MODE_0
+#define CONFIG_SF_DEFAULT_SPEED		50000000
+#define EXYNOS5_SPI_NUM_CONTROLLERS	5
+#endif
+
+#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_SPI_MODE	SPI_MODE_0
+#define CONFIG_ENV_SECT_SIZE	CONFIG_ENV_SIZE
+#define CONFIG_ENV_SPI_BUS	1
+#define CONFIG_ENV_SPI_MAX_HZ	50000000
+#endif
+
 /* Ethernet Controllor Driver */
 #ifdef CONFIG_CMD_NET
 #define CONFIG_SMC911X
Signature · 1 line
1.7.2.3
author
#5 lore raw

PATCH v9 5/5 EXYNOS5: Enable SPI booting.

In reply to Hatim Ali

From: Rajeshwari Shinde <[email protected]>

This patch enables SPI Booting for EXYNOS5

---
Changes since v4:
No Change
Changes since v5:
No Change
Changes since v6:
No Change
Changes since v7:
No Change
Changes since v8:
No Change

board/samsung/smdk5250/Makefile +1 -1
index 1474fa8..47c6a5a 100644
@@ -36,7 +36,7 @@ COBJS	+= smdk5250.o
 endif
 
 ifdef CONFIG_SPL_BUILD
-COBJS	+= mmc_boot.o
+COBJS	+= spl_boot.o
 endif
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
board/samsung/smdk5250/mmc_boot.c deleted +0 -58

58 lines not on this page · raw message

board/samsung/smdk5250/spl_boot.c new file +85 -0

85 lines not on this page · raw message

include/configs/smdk5250.h +5 -0
index 4973c33..e412da8 100644
@@ -187,6 +187,11 @@
 /* U-boot copy size from boot Media to DRAM.*/
 #define BL2_START_OFFSET	(CONFIG_BL2_OFFSET/512)
 #define BL2_SIZE_BLOC_COUNT	(CONFIG_BL2_SIZE/512)
+
+#define OM_STAT				(0x1f << 1)
+#define EXYNOS_COPY_SPI_FNPTR_ADDR	0x02020058
+#define SPI_FLASH_UBOOT_POS		(CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE)
+
 #define CONFIG_DOS_PARTITION
 
 #define CONFIG_IRAM_STACK	0x02050000
Signature · 1 line
1.7.2.3
#6 lore raw

v9 cover EXYNOS5: Enable SPI support

In reply to Hatim Ali
Quoted 32 lines · Hatim Ali

This patch set adds SPI driver for EXYNOS5 and enables same. This patch set is based on latest u-boot-samsung.git tree.

Changes in V2:
- Correted the Commit message.
Changes in V3:
- Removed SPI_SLAVE Flag.
- Corrected warning messages.
Changes in V4:
- Rebased on mainline u-boot.git
- Incorporated review comments for SPI driver.
Changes in V5:
- Rebased on u-boot-samsung.git
- Incorporated review comments by Simon Glass
Changes in V6:
- Incorporated review comments by Minkyu Kang
Changes in V7:
- Incorporated review comments by Minkyu Kang & Simon Glass
Changes in V8:
- Rebased on u-boot-samsung.git
Changes in V9:
- Rebased on u-boot-samsung.git

Hatim Ali (3):
EXYNOS: Add clock for SPI
EXYNOS5: Add base address for SPI
EXYNOS5: Enable SPI

Rajeshwari Shinde (2):
SPI: Add SPI Driver for EXYNOS.
EXYNOS5: Enable SPI booting.

Quoted 17 lines
 arch/arm/cpu/armv7/exynos/clock.c      |  125 +++++++++++
 arch/arm/include/asm/arch-exynos/clk.h |    1 +
 arch/arm/include/asm/arch-exynos/cpu.h |    6 +
 arch/arm/include/asm/arch-exynos/spi.h |   78 +++++++
 board/samsung/smdk5250/Makefile        |    2 +-
 board/samsung/smdk5250/mmc_boot.c      |   58 -----
 board/samsung/smdk5250/smdk5250.c      |    4 +
 board/samsung/smdk5250/spl_boot.c      |   85 ++++++++
 drivers/spi/Makefile                   |    1 +
 drivers/spi/exynos_spi.c               |  367 ++++++++++++++++++++++++++++++++
 include/configs/smdk5250.h             |   27 +++-
 11 files changed, 694 insertions(+), 60 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-exynos/spi.h
 delete mode 100644 board/samsung/smdk5250/mmc_boot.c
 create mode 100644 board/samsung/smdk5250/spl_boot.c
 create mode 100644 drivers/spi/exynos_spi.c

applied to u-boot-samsung.

Thanks.
Minkyu Kang.