Skip to contentSkip to conversation

Add support for keystone2 SoC and K2HK EVM

PATCH Superseded Murali Karicheri 5 participants 17 messages Mar 21, 2014 – Apr 1, 2014

Subsystems (6)

v3 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

v3 cover Add support for keystone2 SoC and K2HK EVM

Change history:
v3
- Seperated network driver patches from the original series and and is now a different set as there are outstanding issues to be discussed and sorted out. Also the original series is ready for merge to upstream IMO.
- Review comments incorporated. Following are the major comments addressed
- Added KBUILD target for u-boot-spi.gph
- Added bootup and flashing instructions in README
- Cleaned up manually replacing #define <tab> with #define <space>
- Cleaned up k2hk_evm.h include file to remove unnecessary options
v2
- Review comments incorporated. Following are major comments addressed
- split network driver to navigator driver + ethernet driver
- replaced register base + offset implemenation with struct based register access implementation
- Added Readme for NAND no subpage write option
- re-use code for davinci i2c driver on keystone2 with updates
- clock-k2hk.c merged to clock.c
- currently keeping board specific getclk() command. See the thread for the rational.
- Added update to davinci spi driver to re-use on keystone

v1
- added separate patch for sorting tools/Makefile entries
- reworked gpimage patch to allow more re-use across omapimage/gpimage
- dropped patch related to ubifs file size
- added keystone SoC and K2HK EVM support

v0
- preparatory patch for keystone

Murali Karicheri (6):
tools: mkimage: add support for gpimage format
NAND: DaVinci: allow forced disable of subpage writes i2c, davinci: move i2c_defs.h to the drivers/i2c directory
k2hk: add support for k2hk SOC and EVM
spi: davinci: add support for multiple bus and chip select
k2hk-evm: add configuration for spi1 and spi2 support

Vitaly Andrianov (3):
fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
arm: add support for arch timer
i2c, davinci: add support for multiple i2c buses

 Makefile                                           |   10 +
 README                                             |    5 +
 arch/arm/cpu/armv7/keystone/Makefile               |   17 +
 arch/arm/cpu/armv7/keystone/aemif.c                |   71 ++++
 arch/arm/cpu/armv7/keystone/clock.c                |  318 ++++++++++++++++++
 arch/arm/cpu/armv7/keystone/cmd_clock.c            |  124 +++++++
 arch/arm/cpu/armv7/keystone/cmd_mon.c              |  131 ++++++++
 arch/arm/cpu/armv7/keystone/ddr3.c                 |   69 ++++
 arch/arm/cpu/armv7/keystone/init.c                 |   56 ++++
 arch/arm/cpu/armv7/keystone/msmc.c                 |   68 ++++
 arch/arm/cpu/armv7/keystone/psc.c                  |  238 ++++++++++++++
 arch/arm/cpu/armv7/keystone/spl.c                  |   45 +++
 arch/arm/include/asm/arch-davinci/i2c_defs.h       |   71 +---
 arch/arm/include/asm/arch-keystone/clock-k2hk.h    |  109 +++++++
 arch/arm/include/asm/arch-keystone/clock.h         |   17 +
 arch/arm/include/asm/arch-keystone/clock_defs.h    |  121 +++++++
 arch/arm/include/asm/arch-keystone/emif_defs.h     |   73 +++++
 arch/arm/include/asm/arch-keystone/hardware-k2hk.h |  150 +++++++++
 arch/arm/include/asm/arch-keystone/hardware.h      |  175 ++++++++++
 arch/arm/include/asm/arch-keystone/i2c_defs.h      |   17 +
 arch/arm/include/asm/arch-keystone/nand_defs.h     |   25 ++
 arch/arm/include/asm/arch-keystone/psc_defs.h      |   90 +++++
 arch/arm/include/asm/arch-keystone/spl.h           |   12 +
 arch/arm/lib/Makefile                              |    1 +
 arch/arm/lib/arch_timer.c                          |   58 ++++
 board/ti/k2hk_evm/Makefile                         |    9 +
 board/ti/k2hk_evm/README                           |  122 +++++++
 board/ti/k2hk_evm/board.c                          |  236 ++++++++++++++
 board/ti/k2hk_evm/ddr3.c                           |  269 +++++++++++++++
 boards.cfg                                         |    1 +
 common/image-fdt.c                                 |    5 +
 common/image.c                                     |    1 +
 drivers/i2c/davinci_i2c.c                          |  344 ++++++++++++--------
 drivers/i2c/davinci_i2c.h                          |   78 +++++
 drivers/mtd/nand/davinci_nand.c                    |    3 +
 drivers/serial/ns16550.c                           |    8 +
 drivers/spi/davinci_spi.c                          |   60 +++-
 drivers/spi/davinci_spi.h                          |   33 ++
 include/configs/k2hk_evm.h                         |  218 +++++++++++++
 include/fdt_support.h                              |    1 +
 include/image.h                                    |    1 +
 tools/Makefile                                     |    2 +
 tools/gpheader.h                                   |   40 +++
 tools/gpimage-common.c                             |   80 +++++
 tools/gpimage.c                                    |   77 +++++
 tools/imagetool.c                                  |    2 +
 tools/imagetool.h                                  |    1 +
 tools/omapimage.c                                  |  104 +-----
 tools/omapimage.h                                  |    5 -
 49 files changed, 3467 insertions(+), 304 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/keystone/Makefile
 create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c
 create mode 100644 arch/arm/cpu/armv7/keystone/clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c
 create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c
 create mode 100644 arch/arm/cpu/armv7/keystone/init.c
 create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/psc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/spl.c
 create mode 100644 arch/arm/include/asm/arch-keystone/clock-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h
 create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/spl.h
 create mode 100644 arch/arm/lib/arch_timer.c
 create mode 100644 board/ti/k2hk_evm/Makefile
 create mode 100644 board/ti/k2hk_evm/README
 create mode 100644 board/ti/k2hk_evm/board.c
 create mode 100644 board/ti/k2hk_evm/ddr3.c
 create mode 100644 drivers/i2c/davinci_i2c.h
 create mode 100644 include/configs/k2hk_evm.h
 create mode 100644 tools/gpheader.h
 create mode 100644 tools/gpimage-common.c
 create mode 100644 tools/gpimage.c
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH v3 1/9 fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()

From: Vitaly Andrianov <[email protected]>

The keystone2 SOC requires to fix all 32 bit aliased addresses to their 36 physical format. This has to happen after all fdt nodes are added or modified.

---
 common/image-fdt.c    |    5 +++++
 include/fdt_support.h |    1 +
 2 files changed, 6 insertions(+)
common/image-fdt.c +5 -0
index a54a919..5d64009 100644
@@ -487,5 +487,10 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,
 	if (!ft_verify_fdt(blob))
 		return -1;
 
+#ifdef CONFIG_SOC_K2HK
+	if (IMAGE_OF_BOARD_SETUP)
+		ft_board_setup_ex(blob, gd->bd);
+#endif
+
 	return 0;
 }
include/fdt_support.h +1 -0
index 9871e2f..4c1416d 100644
@@ -63,6 +63,7 @@ int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose);
 #endif
 
 void ft_board_setup(void *blob, bd_t *bd);
+void ft_board_setup_ex(void *blob, bd_t *bd);
 void ft_cpu_setup(void *blob, bd_t *bd);
 void ft_pci_setup(void *blob, bd_t *bd);
 
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH v3 1/9 fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()

Hi,

Quoted 34 lines · Murali Karicheri

From: Vitaly Andrianov <[email protected]>

The keystone2 SOC requires to fix all 32 bit aliased addresses to their 36 physical format. This has to happen after all fdt nodes are added or modified.

---
 common/image-fdt.c    |    5 +++++
 include/fdt_support.h |    1 +
 2 files changed, 6 insertions(+)
common/image-fdt.c +5 -0
index a54a919..5d64009 100644
@@ -487,5 +487,10 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,
        if (!ft_verify_fdt(blob))
                return -1;
 
+#ifdef CONFIG_SOC_K2HK
+       if (IMAGE_OF_BOARD_SETUP)
+               ft_board_setup_ex(blob, gd->bd);
+#endif
+
        return 0;
 }
include/fdt_support.h +0 -0
index 9871e2f..4c1416d 100644

include/fdt_support.h int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose); · line 66

Quoted 4 lines
include/fdt_support.h +1 -0
@@ -63,6 +63,7 @@ int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose);
 #endif
 
 void ft_board_setup(void *blob, bd_t *bd);
+void ft_board_setup_ex(void *blob, bd_t *bd);

Please can we get a comment added to this function explaining what it is for?

include/fdt_support.h int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose); · line 68

Quoted 2 lines
include/fdt_support.h +0 -0
 void ft_cpu_setup(void *blob, bd_t *bd);
 void ft_pci_setup(void *blob, bd_t *bd);

Regards,
Simon

#3 lore raw

PATCH v3 2/9 tools: mkimage: add support for gpimage format

In reply to Murali Karicheri

This patch add support for gpimage format as a preparatory patch for porting u-boot for keystone2 devices and is based on omapimage format. It re-uses gph header to store the size and loadaddr as done in omapimage.c

---
 common/image.c         |    1 +
 include/image.h        |    1 +
 tools/Makefile         |    2 +
 tools/gpheader.h       |   40 +++++++++++++++++++
 tools/gpimage-common.c |   80 +++++++++++++++++++++++++++++++++++++
 tools/gpimage.c        |   77 +++++++++++++++++++++++++++++++++++
 tools/imagetool.c      |    2 +
 tools/imagetool.h      |    1 +
 tools/omapimage.c      |  104 ++++++++----------------------------------------
 tools/omapimage.h      |    5 ---
 10 files changed, 220 insertions(+), 93 deletions(-)
 create mode 100644 tools/gpheader.h
 create mode 100644 tools/gpimage-common.c
 create mode 100644 tools/gpimage.c
common/image.c +1 -0
index 9c6bec5..fcc5a9c 100644
@@ -125,6 +125,7 @@ static const table_entry_t uimage_type[] = {
 	{	IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",	},
 	{	IH_TYPE_FIRMWARE,   "firmware",	  "Firmware",		},
 	{	IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",	},
+	{	IH_TYPE_GPIMAGE,    "gpimage",    "TI Keystone SPL Image",},
 	{	IH_TYPE_KERNEL,	    "kernel",	  "Kernel Image",	},
 	{	IH_TYPE_KERNEL_NOLOAD, "kernel_noload",  "Kernel Image (no loading done)", },
 	{	IH_TYPE_KWBIMAGE,   "kwbimage",   "Kirkwood Boot Image",},
include/image.h +1 -0
index 6afd57b..8095bc8 100644
@@ -215,6 +215,7 @@ struct lmb;
 #define IH_TYPE_KERNEL_NOLOAD	14	/* OS Kernel Image, can run from any load address */
 #define IH_TYPE_PBLIMAGE	15	/* Freescale PBL Boot Image	*/
 #define IH_TYPE_MXSIMAGE	16	/* Freescale MXSBoot Image	*/
+#define IH_TYPE_GPIMAGE		17	/* TI Keystone GPHeader Image	*/
 
 /*
  * Compression Types
tools/Makefile +2 -0
index dcd49f8..56587c9 100644
@@ -73,6 +73,8 @@ dumpimage-mkimage-objs := aisimage.o \
 			crc32.o \
 			default_image.o \
 			fit_image.o \
+			gpimage.o \
+			gpimage-common.o \
 			image-fit.o \
 			image-host.o \
 			image.o \
tools/gpheader.h new file +40 -0
new file mode 100644
index 0000000..63a28a2
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Refactored common functions in to gpimage-common.c. Include this common
+ * header file
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <[email protected]>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _GPIMAGE_H_
+#define _GPIMAGE_H_
+
+/* common headers for gpimage and omapimage formats */
+struct gp_header {
+	uint32_t size;
+	uint32_t load_addr;
+};
+#define GPIMAGE_HDR_SIZE (sizeof(struct gp_header))
+
+/* common functions across gpimage and omapimage handlers */
+int valid_gph_size(uint32_t size);
+int valid_gph_load_addr(uint32_t load_addr);
+int gph_verify_header(struct gp_header *gph, int be);
+void gph_print_header(const struct gp_header *gph, int be);
+void gph_set_header(struct gp_header *gph, uint32_t size, uint32_t load_addr,
+			int be);
+int gpimage_check_params(struct image_tool_params *params);
+#endif
tools/gpimage-common.c new file +80 -0

80 lines not on this page · raw message

tools/gpimage.c new file +77 -0

77 lines not on this page · raw message

tools/imagetool.c +2 -0
index 29d2189..da72115 100644
@@ -45,6 +45,8 @@ void register_image_tool(imagetool_register_t image_register)
 	init_ubl_image_type();
 	/* Init Davinci AIS support */
 	init_ais_image_type();
+	/* Init TI Keystone boot image generation/list support */
+	init_gpimage_type();
 }
 
 /*
tools/imagetool.h +1 -0
index c2c9aea..a3e9d30 100644
@@ -167,6 +167,7 @@ void init_mxs_image_type(void);
 void init_fit_image_type(void);
 void init_ubl_image_type(void);
 void init_omap_image_type(void);
+void init_gpimage_type(void);
 
 void pbl_load_uboot(int fd, struct image_tool_params *mparams);
 
tools/omapimage.c +16 -88

180 lines not on this page · raw message

tools/omapimage.h +0 -5
index 45d14ea..8744ae7 100644
@@ -25,10 +25,5 @@ struct ch_settings {
 	uint32_t flags;
 };
 
-struct gp_header {
-	uint32_t size;
-	uint32_t load_addr;
-};
-
 #define KEY_CHSETTINGS 0xC0C0C0C1
 #endif /* _OMAPIMAGE_H_ */
Signature · 1 line
1.7.9.5
#4 lore raw

PATCH v3 3/9 arm: add support for arch timer

In reply to Murali Karicheri

From: Vitaly Andrianov <[email protected]>

This patch add basic support for the architecture timer found on recent ARMv7 based SoCs.

---
 arch/arm/lib/Makefile     |    1 +
 arch/arm/lib/arch_timer.c |   58 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 arch/arm/lib/arch_timer.c
arch/arm/lib/Makefile +1 -0
index 45febcf..a1d774a 100644
@@ -41,6 +41,7 @@ obj-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o
 else
 obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
 endif
+obj-$(CONFIG_SYS_ARCH_TIMER) += arch_timer.o
 
 obj-y	+= sections.o
 ifdef CONFIG_ARM64
arch/arm/lib/arch_timer.c new file +58 -0

58 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#5 lore raw

PATCH v3 4/9 NAND: DaVinci: allow forced disable of subpage writes

In reply to Murali Karicheri

This patch introduces a configurable mechanism to disable subpage writes in the DaVinci NAND driver.

---
 README                          |    5 +++++
 drivers/mtd/nand/davinci_nand.c |    3 +++
 2 files changed, 8 insertions(+)
README +5 -0
index ff49260..faec8ef 100644
@@ -4473,6 +4473,11 @@ Low Level (hardware related) configuration options:
 - CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC:
 		Enables the RTC32K OSC on AM33xx based plattforms
 
+- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+		Option to disable subpage write in NAND driver
+		driver that uses this:
+		drivers/mtd/nand/davinci_nand.c
+
 Freescale QE/FMAN Firmware Support:
 -----------------------------------
 
drivers/mtd/nand/davinci_nand.c +3 -0
index 5b17d7b..75b03a7 100644
@@ -609,6 +609,9 @@ void davinci_nand_init(struct nand_chip *nand)
 #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
 	nand->bbt_options	  |= NAND_BBT_USE_FLASH;
 #endif
+#ifdef CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+	nand->options	  |= NAND_NO_SUBPAGE_WRITE;
+#endif
 #ifdef CONFIG_SYS_NAND_HW_ECC
 	nand->ecc.mode = NAND_ECC_HW;
 	nand->ecc.size = 512;
Signature · 1 line
1.7.9.5
#6 lore raw

PATCH v3 5/9 i2c, davinci: move i2c_defs.h to the drivers/i2c directory

In reply to Murali Karicheri

This patch moves the davinci i2c_defs.h file to drivers.i2c directory. It will allow to reuse the davinci_i2c driver for TI Keystone2 SOCs.

Not used "git mv" command to move the file because small part of it with definitions specific for Davinci SOCs has to remain in the arch/arm/include/asm/arch-davinci.

---
 arch/arm/include/asm/arch-davinci/i2c_defs.h |   71 ++----------------------
 drivers/i2c/davinci_i2c.c                    |    1 +
 drivers/i2c/davinci_i2c.h                    |   75 ++++++++++++++++++++++++++
 3 files changed, 79 insertions(+), 68 deletions(-)
 create mode 100644 drivers/i2c/davinci_i2c.h
arch/arm/include/asm/arch-davinci/i2c_defs.h +3 -68
index c388dc0..06da894 100644
@@ -1,16 +1,13 @@
 /*
- * (C) Copyright 2004
+ * (C) Copyright 2004-2014
  * Texas Instruments, <www.ti.com>
  *
  * Some changes copyright (C) 2007 Sergey Kubushyn <[email protected]>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
-#ifndef _DAVINCI_I2C_H_
-#define _DAVINCI_I2C_H_
-
-#define I2C_WRITE		0
-#define I2C_READ		1
+#ifndef _I2C_DEFS_H_
+#define _I2C_DEFS_H_
 
 #ifndef CONFIG_SOC_DA8XX
 #define I2C_BASE		0x01c21000
@@ -18,66 +15,4 @@
 #define I2C_BASE		0x01c22000
 #endif
 
-#define	I2C_OA			(I2C_BASE + 0x00)
-#define I2C_IE			(I2C_BASE + 0x04)
-#define I2C_STAT		(I2C_BASE + 0x08)
-#define I2C_SCLL		(I2C_BASE + 0x0c)
-#define I2C_SCLH		(I2C_BASE + 0x10)
-#define I2C_CNT			(I2C_BASE + 0x14)
-#define I2C_DRR			(I2C_BASE + 0x18)
-#define I2C_SA			(I2C_BASE + 0x1c)
-#define I2C_DXR			(I2C_BASE + 0x20)
-#define I2C_CON			(I2C_BASE + 0x24)
-#define I2C_IV			(I2C_BASE + 0x28)
-#define I2C_PSC			(I2C_BASE + 0x30)
-
-/* I2C masks */
-
-/* I2C Interrupt Enable Register (I2C_IE): */
-#define I2C_IE_SCD_IE	(1 << 5)	/* Stop condition detect interrupt enable */
-#define I2C_IE_XRDY_IE	(1 << 4)	/* Transmit data ready interrupt enable */
-#define I2C_IE_RRDY_IE	(1 << 3)	/* Receive data ready interrupt enable */
-#define I2C_IE_ARDY_IE	(1 << 2)	/* Register access ready interrupt enable */
-#define I2C_IE_NACK_IE	(1 << 1)	/* No acknowledgment interrupt enable */
-#define I2C_IE_AL_IE	(1 << 0)	/* Arbitration lost interrupt enable */
-
-/* I2C Status Register (I2C_STAT): */
-
-#define I2C_STAT_BB	(1 << 12)	/* Bus busy */
-#define I2C_STAT_ROVR	(1 << 11)	/* Receive overrun */
-#define I2C_STAT_XUDF	(1 << 10)	/* Transmit underflow */
-#define I2C_STAT_AAS	(1 << 9)	/* Address as slave */
-#define I2C_STAT_SCD	(1 << 5)	/* Stop condition detect */
-#define I2C_STAT_XRDY	(1 << 4)	/* Transmit data ready */
-#define I2C_STAT_RRDY	(1 << 3)	/* Receive data ready */
-#define I2C_STAT_ARDY	(1 << 2)	/* Register access ready */
-#define I2C_STAT_NACK	(1 << 1)	/* No acknowledgment interrupt enable */
-#define I2C_STAT_AL	(1 << 0)	/* Arbitration lost interrupt enable */
-
-
-/* I2C Interrupt Code Register (I2C_INTCODE): */
-
-#define I2C_INTCODE_MASK	7
-#define I2C_INTCODE_NONE	0
-#define I2C_INTCODE_AL		1	/* Arbitration lost */
-#define I2C_INTCODE_NAK		2	/* No acknowledgement/general call */
-#define I2C_INTCODE_ARDY	3	/* Register access ready */
-#define I2C_INTCODE_RRDY	4	/* Rcv data ready */
-#define I2C_INTCODE_XRDY	5	/* Xmit data ready */
-#define I2C_INTCODE_SCD		6	/* Stop condition detect */
-
-
-/* I2C Configuration Register (I2C_CON): */
-
-#define I2C_CON_EN	(1 << 5)	/* I2C module enable */
-#define I2C_CON_STB	(1 << 4)	/* Start byte mode (master mode only) */
-#define I2C_CON_MST	(1 << 10)	/* Master/slave mode */
-#define I2C_CON_TRX	(1 << 9)	/* Transmitter/receiver mode (master mode only) */
-#define I2C_CON_XA	(1 << 8)	/* Expand address */
-#define I2C_CON_STP	(1 << 11)	/* Stop condition (master mode only) */
-#define I2C_CON_STT	(1 << 13)	/* Start condition (master mode only) */
-#define I2C_CON_FREE	(1 << 14)	/* Free run on emulation */
-
-#define I2C_TIMEOUT	0xffff0000	/* Timeout mask for poll_i2c_irq() */
-
 #endif
drivers/i2c/davinci_i2c.c +1 -0
index e56fe75..6e5260c 100644
@@ -12,6 +12,7 @@
 #include <i2c.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/i2c_defs.h>
+#include "davinci_i2c.h"
 
 #define CHECK_NACK() \
 	do {\
drivers/i2c/davinci_i2c.h new file +75 -0

75 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#7 lore raw

PATCH v3 6/9 i2c, davinci: add support for multiple i2c buses

In reply to Murali Karicheri

From: Vitaly Andrianov <[email protected]>

---
 drivers/i2c/davinci_i2c.c |  343 +++++++++++++++++++++++++++------------------
 drivers/i2c/davinci_i2c.h |   27 ++--
 2 files changed, 218 insertions(+), 152 deletions(-)
drivers/i2c/davinci_i2c.c +203 -140
index 6e5260c..c4a6c4d 100644
@@ -1,8 +1,9 @@
 /*
  * TI DaVinci (TMS320DM644x) I2C driver.
  *
- * Copyright (C) 2007 Sergey Kubushyn <[email protected]>
- *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <[email protected]>
  * --------------------------------------------------------
  *
  * SPDX-License-Identifier:	GPL-2.0+
@@ -12,14 +13,26 @@
 #include <i2c.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/i2c_defs.h>
+#include <asm/io.h>
 #include "davinci_i2c.h"
 
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct i2c_regs __attribute__((section(".data"))) *i2c_base =
+						(struct i2c_regs *)I2C_BASE;
+
+#ifdef CONFIG_I2C_MULTI_BUS
+static unsigned int __attribute__((section(".data")))
+		bus_initialized[I2C_BUS_MAX] = { [0 ... (I2C_BUS_MAX-1)] = 0 };
+static unsigned int __attribute__((section(".data"))) current_bus;
+#endif
+
 #define CHECK_NACK() \
 	do {\
 		if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
-			REG(I2C_CON) = 0;\
-			return(1);\
-		}\
+			REG(&(i2c_base->i2c_con)) = 0;\
+			return 1;\
+		} \
 	} while (0)
 
 
@@ -27,20 +40,21 @@ static int wait_for_bus(void)
 {
 	int	stat, timeout;
 
-	REG(I2C_STAT) = 0xffff;
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
 
 	for (timeout = 0; timeout < 10; timeout++) {
-		if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) {
-			REG(I2C_STAT) = 0xffff;
-			return(0);
+		stat = REG(&(i2c_base->i2c_stat));
+		if (!((stat) & I2C_STAT_BB)) {
+			REG(&(i2c_base->i2c_stat)) = 0xffff;
+			return 0;
 		}
 
-		REG(I2C_STAT) = stat;
+		REG(&(i2c_base->i2c_stat)) = stat;
 		udelay(50000);
 	}
 
-	REG(I2C_STAT) = 0xffff;
-	return(1);
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	return 1;
 }
 
 
@@ -50,25 +64,23 @@ static int poll_i2c_irq(int mask)
 
 	for (timeout = 0; timeout < 10; timeout++) {
 		udelay(1000);
-		stat = REG(I2C_STAT);
-		if (stat & mask) {
-			return(stat);
-		}
+		stat = REG(&(i2c_base->i2c_stat));
+		if (stat & mask)
+			return stat;
 	}
 
-	REG(I2C_STAT) = 0xffff;
-	return(stat | I2C_TIMEOUT);
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	return stat | I2C_TIMEOUT;
 }
 
-
 void flush_rx(void)
 {
 	while (1) {
-		if (!(REG(I2C_STAT) & I2C_STAT_RRDY))
+		if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_RRDY))
 			break;
 
-		REG(I2C_DRR);
-		REG(I2C_STAT) = I2C_STAT_RRDY;
+		REG(&(i2c_base->i2c_drr));
+		REG(&(i2c_base->i2c_stat)) = I2C_STAT_RRDY;
 		udelay(1000);
 	}
 }
@@ -78,28 +90,34 @@ void i2c_init(int speed, int slaveadd)
 {
 	u_int32_t	div, psc;
 
-	if (REG(I2C_CON) & I2C_CON_EN) {
-		REG(I2C_CON) = 0;
-		udelay (50000);
+	if (REG(&(i2c_base->i2c_con)) & I2C_CON_EN) {
+		REG(&(i2c_base->i2c_con)) = 0;
+		udelay(50000);
 	}
 
 	psc = 2;
-	div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;	/* SCLL + SCLH */
-	REG(I2C_PSC) = psc;			/* 27MHz / (2 + 1) = 9MHz */
-	REG(I2C_SCLL) = (div * 50) / 100;	/* 50% Duty */
-	REG(I2C_SCLH) = div - REG(I2C_SCLL);
+	/* SCLL + SCLH */
+	div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;
+	REG(&(i2c_base->i2c_psc)) = psc; /* 27MHz / (2 + 1) = 9MHz */
+	REG(&(i2c_base->i2c_scll)) = (div * 50) / 100; /* 50% Duty */
+	REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll));
 
-	REG(I2C_OA) = slaveadd;
-	REG(I2C_CNT) = 0;
+	REG(&(i2c_base->i2c_oa)) = slaveadd;
+	REG(&(i2c_base->i2c_cnt)) = 0;
 
 	/* Interrupts must be enabled or I2C module won't work */
-	REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
+	REG(&(i2c_base->i2c_ie)) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
 		I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
 
 	/* Now enable I2C controller (get it out of reset) */
-	REG(I2C_CON) = I2C_CON_EN;
+	REG(&(i2c_base->i2c_con)) = I2C_CON_EN;
 
 	udelay(1000);
+
+#ifdef CONFIG_I2C_MULTI_BUS
+	if (gd->flags & GD_FLG_RELOC)
+		bus_initialized[current_bus] = 1;
+#endif
 }
 
 int i2c_set_bus_speed(unsigned int speed)
@@ -112,34 +130,36 @@ int i2c_probe(u_int8_t chip)
 {
 	int	rc = 1;
 
-	if (chip == REG(I2C_OA)) {
-		return(rc);
-	}
+	if (chip == REG(&(i2c_base->i2c_oa)))
+		return rc;
 
-	REG(I2C_CON) = 0;
-	if (wait_for_bus()) {return(1);}
+	REG(&(i2c_base->i2c_con)) = 0;
+	if (wait_for_bus())
+		return 1;
 
 	/* try to read one byte from current (or only) address */
-	REG(I2C_CNT) = 1;
-	REG(I2C_SA) = chip;
-	REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP);
-	udelay (50000);
+	REG(&(i2c_base->i2c_cnt)) = 1;
+	REG(&(i2c_base->i2c_sa))  = chip;
+	REG(&(i2c_base->i2c_con)) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+				     I2C_CON_STP);
+	udelay(50000);
 
-	if (!(REG(I2C_STAT) & I2C_STAT_NACK)) {
+	if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_NACK)) {
 		rc = 0;
 		flush_rx();
-		REG(I2C_STAT) = 0xffff;
+		REG(&(i2c_base->i2c_stat)) = 0xffff;
 	} else {
-		REG(I2C_STAT) = 0xffff;
-		REG(I2C_CON) |= I2C_CON_STP;
+		REG(&(i2c_base->i2c_stat)) = 0xffff;
+		REG(&(i2c_base->i2c_con)) |= I2C_CON_STP;
 		udelay(20000);
-		if (wait_for_bus()) {return(1);}
+		if (wait_for_bus())
+			return 1;
 	}
 
 	flush_rx();
-	REG(I2C_STAT) = 0xffff;
-	REG(I2C_CNT) = 0;
-	return(rc);
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+	return rc;
 }
 
 
@@ -149,73 +169,76 @@ int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
 	int		i;
 
 	if ((alen < 0) || (alen > 2)) {
-		printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
-		return(1);
+		printf("%s(): bogus address length %x\n", __func__, alen);
+		return 1;
 	}
 
-	if (wait_for_bus()) {return(1);}
+	if (wait_for_bus())
+		return 1;
 
 	if (alen != 0) {
 		/* Start address phase */
 		tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX;
-		REG(I2C_CNT) = alen;
-		REG(I2C_SA) = chip;
-		REG(I2C_CON) = tmp;
+		REG(&(i2c_base->i2c_cnt)) = alen;
+		REG(&(i2c_base->i2c_sa)) = chip;
+		REG(&(i2c_base->i2c_con)) = tmp;
 
 		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
 
 		CHECK_NACK();
 
 		switch (alen) {
-			case 2:
-				/* Send address MSByte */
-				if (tmp & I2C_STAT_XRDY) {
-					REG(I2C_DXR) = (addr >> 8) & 0xff;
-				} else {
-					REG(I2C_CON) = 0;
-					return(1);
-				}
-
-				tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
-
-				CHECK_NACK();
-				/* No break, fall through */
-			case 1:
-				/* Send address LSByte */
-				if (tmp & I2C_STAT_XRDY) {
-					REG(I2C_DXR) = addr & 0xff;
-				} else {
-					REG(I2C_CON) = 0;
-					return(1);
-				}
-
-				tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | I2C_STAT_ARDY);
-
-				CHECK_NACK();
-
-				if (!(tmp & I2C_STAT_ARDY)) {
-					REG(I2C_CON) = 0;
-					return(1);
-				}
+		case 2:
+			/* Send address MSByte */
+			if (tmp & I2C_STAT_XRDY) {
+				REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
+			} else {
+				REG(&(i2c_base->i2c_con)) = 0;
+				return 1;
+			}
+
+			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+			CHECK_NACK();
+			/* No break, fall through */
+		case 1:
+			/* Send address LSByte */
+			if (tmp & I2C_STAT_XRDY) {
+				REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
+			} else {
+				REG(&(i2c_base->i2c_con)) = 0;
+				return 1;
+			}
+
+			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK |
+					   I2C_STAT_ARDY);
+
+			CHECK_NACK();
+
+			if (!(tmp & I2C_STAT_ARDY)) {
+				REG(&(i2c_base->i2c_con)) = 0;
+				return 1;
+			}
 		}
 	}
 
 	/* Address phase is over, now read 'len' bytes and stop */
 	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP;
-	REG(I2C_CNT) = len & 0xffff;
-	REG(I2C_SA) = chip;
-	REG(I2C_CON) = tmp;
+	REG(&(i2c_base->i2c_cnt)) = len & 0xffff;
+	REG(&(i2c_base->i2c_sa)) = chip;
+	REG(&(i2c_base->i2c_con)) = tmp;
 
 	for (i = 0; i < len; i++) {
-		tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | I2C_STAT_ROVR);
+		tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK |
+				   I2C_STAT_ROVR);
 
 		CHECK_NACK();
 
 		if (tmp & I2C_STAT_RRDY) {
-			buf[i] = REG(I2C_DRR);
+			buf[i] = REG(&(i2c_base->i2c_drr));
 		} else {
-			REG(I2C_CON) = 0;
-			return(1);
+			REG(&(i2c_base->i2c_con)) = 0;
+			return 1;
 		}
 	}
 
@@ -224,16 +247,16 @@ int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
 	CHECK_NACK();
 
 	if (!(tmp & I2C_STAT_SCD)) {
-		REG(I2C_CON) = 0;
-		return(1);
+		REG(&(i2c_base->i2c_con)) = 0;
+		return 1;
 	}
 
 	flush_rx();
-	REG(I2C_STAT) = 0xffff;
-	REG(I2C_CNT) = 0;
-	REG(I2C_CON) = 0;
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+	REG(&(i2c_base->i2c_con)) = 0;
 
-	return(0);
+	return 0;
 }
 
 
@@ -243,48 +266,51 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
 	int		i;
 
 	if ((alen < 0) || (alen > 2)) {
-		printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
-		return(1);
+		printf("%s(): bogus address length %x\n", __func__, alen);
+		return 1;
 	}
 	if (len < 0) {
-		printf("%s(): bogus length %x\n", __FUNCTION__, len);
-		return(1);
+		printf("%s(): bogus length %x\n", __func__, len);
+		return 1;
 	}
 
-	if (wait_for_bus()) {return(1);}
+	if (wait_for_bus())
+		return 1;
 
 	/* Start address phase */
-	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP;
-	REG(I2C_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen;
-	REG(I2C_SA) = chip;
-	REG(I2C_CON) = tmp;
+	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+		I2C_CON_TRX | I2C_CON_STP;
+	REG(&(i2c_base->i2c_cnt)) = (alen == 0) ?
+		len & 0xffff : (len & 0xffff) + alen;
+	REG(&(i2c_base->i2c_sa)) = chip;
+	REG(&(i2c_base->i2c_con)) = tmp;
 
 	switch (alen) {
-		case 2:
-			/* Send address MSByte */
-			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+	case 2:
+		/* Send address MSByte */
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
 
-			CHECK_NACK();
+		CHECK_NACK();
 
-			if (tmp & I2C_STAT_XRDY) {
-				REG(I2C_DXR) = (addr >> 8) & 0xff;
-			} else {
-				REG(I2C_CON) = 0;
-				return(1);
-			}
-			/* No break, fall through */
-		case 1:
-			/* Send address LSByte */
-			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+		if (tmp & I2C_STAT_XRDY) {
+			REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
+		} else {
+			REG(&(i2c_base->i2c_con)) = 0;
+			return 1;
+		}
+		/* No break, fall through */
+	case 1:
+		/* Send address LSByte */
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
 
-			CHECK_NACK();
+		CHECK_NACK();
 
-			if (tmp & I2C_STAT_XRDY) {
-				REG(I2C_DXR) = addr & 0xff;
-			} else {
-				REG(I2C_CON) = 0;
-				return(1);
-			}
+		if (tmp & I2C_STAT_XRDY) {
+			REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
+		} else {
+			REG(&(i2c_base->i2c_con)) = 0;
+			return 1;
+		}
 	}
 
 	for (i = 0; i < len; i++) {
@@ -292,11 +318,10 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
 
 		CHECK_NACK();
 
-		if (tmp & I2C_STAT_XRDY) {
-			REG(I2C_DXR) = buf[i];
-		} else {
-			return(1);
-		}
+		if (tmp & I2C_STAT_XRDY)
+			REG(&(i2c_base->i2c_dxr)) = buf[i];
+		else
+			return 1;
 	}
 
 	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
@@ -304,14 +329,52 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
 	CHECK_NACK();
 
 	if (!(tmp & I2C_STAT_SCD)) {
-		REG(I2C_CON) = 0;
-		return(1);
+		REG(&(i2c_base->i2c_con)) = 0;
+		return 1;
 	}
 
 	flush_rx();
-	REG(I2C_STAT) = 0xffff;
-	REG(I2C_CNT) = 0;
-	REG(I2C_CON) = 0;
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+	REG(&(i2c_base->i2c_con)) = 0;
+
+	return 0;
+}
+
+#ifdef CONFIG_I2C_MULTI_BUS
+int i2c_set_bus_num(unsigned int bus)
+{
+	if ((bus < 0) || (bus >= I2C_BUS_MAX)) {
+		printf("Bad bus: %d\n", bus);
+		return -1;
+	}
+
+	switch (bus) {
+#if I2C_BUS_MAX == 3
+	case 2:
+		i2c_base = (struct i2c_regs *)I2C2_BASE;
+		break;
+#endif
+#if I2C_BUS_MAX >= 2
+	case 1:
+		i2c_base = (struct i2c_regs *)I2C1_BASE;
+		break;
+#endif
+	default:
+		i2c_base = (struct i2c_regs *)I2C0_BASE;
+		bus = 0;
+	}
+
+	current_bus = bus;
+
+	if (!bus_initialized[current_bus])
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
 
-	return(0);
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return (int) current_bus;
 }
+#endif
drivers/i2c/davinci_i2c.h +15 -12
index 79ff7a3..20d4342 100644
@@ -12,18 +12,21 @@
 #define I2C_WRITE		0
 #define I2C_READ		1
 
-#define	I2C_OA			(I2C_BASE + 0x00)
-#define I2C_IE			(I2C_BASE + 0x04)
-#define I2C_STAT		(I2C_BASE + 0x08)
-#define I2C_SCLL		(I2C_BASE + 0x0c)
-#define I2C_SCLH		(I2C_BASE + 0x10)
-#define I2C_CNT			(I2C_BASE + 0x14)
-#define I2C_DRR			(I2C_BASE + 0x18)
-#define I2C_SA			(I2C_BASE + 0x1c)
-#define I2C_DXR			(I2C_BASE + 0x20)
-#define I2C_CON			(I2C_BASE + 0x24)
-#define I2C_IV			(I2C_BASE + 0x28)
-#define I2C_PSC			(I2C_BASE + 0x30)
+struct i2c_regs {
+	u32	i2c_oa;
+	u32	i2c_ie;
+	u32	i2c_stat;
+	u32	i2c_scll;
+	u32	i2c_sclh;
+	u32	i2c_cnt;
+	u32	i2c_drr;
+	u32	i2c_sa;
+	u32	i2c_dxr;
+	u32	i2c_con;
+	u32	i2c_iv;
+	u32	res_2c;
+	u32	i2c_psc;
+};
 
 /* I2C masks */
 
Signature · 1 line
1.7.9.5
#8 lore raw

PATCH v3 6/9 i2c, davinci: add support for multiple i2c buses

Hello Murali,

Am 21.03.2014 21:51, schrieb Murali Karicheri:

Quoted 33 lines

From: Vitaly Andrianov<[email protected]>

---
  drivers/i2c/davinci_i2c.c |  343 +++++++++++++++++++++++++++------------------
  drivers/i2c/davinci_i2c.h |   27 ++--
  2 files changed, 218 insertions(+), 152 deletions(-)
drivers/i2c/davinci_i2c.c +5 -2
index 6e5260c..c4a6c4d 100644
@@ -1,8 +1,9 @@
  /*
   * TI DaVinci (TMS320DM644x) I2C driver.
   *
- * Copyright (C) 2007 Sergey Kubushyn<[email protected]>
- *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated,<www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn<[email protected]>
   * --------------------------------------------------------
   *
   * SPDX-License-Identifier:	GPL-2.0+
@@ -12,14 +13,26 @@
  #include<i2c.h>
  #include<asm/arch/hardware.h>
  #include<asm/arch/i2c_defs.h>
+#include<asm/io.h>
  #include "davinci_i2c.h"
 
+DECLARE_GLOBAL_DATA_PTR;

drivers/i2c/davinci_i2c.c line 29

Quoted 10 lines
drivers/i2c/davinci_i2c.c +10 -0
+
+static struct i2c_regs __attribute__((section(".data"))) *i2c_base =
+						(struct i2c_regs *)I2C_BASE;
+
+#ifdef CONFIG_I2C_MULTI_BUS
+static unsigned int __attribute__((section(".data")))
+		bus_initialized[I2C_BUS_MAX] = { [0 ... (I2C_BUS_MAX-1)] = 0 };
+static unsigned int __attribute__((section(".data"))) current_bus;
+#endif
+

NACK. Please convert this driver to the new i2c multibus/multiadapter framework, please use CONFIG_SYS_I2C, thanks!

bye,
Heiko

Signature · 2 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#9 lore raw

PATCH v3 7/9 k2hk: add support for k2hk SOC and EVM

In reply to Murali Karicheri

k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer the ti/k2hk_evm/README for details on the board, build and other information.

This patch add support for keystone architecture and k2hk evm.

---
 Makefile                                           |   10 +
 arch/arm/cpu/armv7/keystone/Makefile               |   17 ++
 arch/arm/cpu/armv7/keystone/aemif.c                |   71 +++++
 arch/arm/cpu/armv7/keystone/clock.c                |  318 ++++++++++++++++++++
 arch/arm/cpu/armv7/keystone/cmd_clock.c            |  124 ++++++++
 arch/arm/cpu/armv7/keystone/cmd_mon.c              |  131 ++++++++
 arch/arm/cpu/armv7/keystone/ddr3.c                 |   69 +++++
 arch/arm/cpu/armv7/keystone/init.c                 |   56 ++++
 arch/arm/cpu/armv7/keystone/msmc.c                 |   68 +++++
 arch/arm/cpu/armv7/keystone/psc.c                  |  238 +++++++++++++++
 arch/arm/cpu/armv7/keystone/spl.c                  |   45 +++
 arch/arm/include/asm/arch-keystone/clock-k2hk.h    |  109 +++++++
 arch/arm/include/asm/arch-keystone/clock.h         |   17 ++
 arch/arm/include/asm/arch-keystone/clock_defs.h    |  121 ++++++++
 arch/arm/include/asm/arch-keystone/emif_defs.h     |   73 +++++
 arch/arm/include/asm/arch-keystone/hardware-k2hk.h |  150 +++++++++
 arch/arm/include/asm/arch-keystone/hardware.h      |  175 +++++++++++
 arch/arm/include/asm/arch-keystone/i2c_defs.h      |   17 ++
 arch/arm/include/asm/arch-keystone/nand_defs.h     |   25 ++
 arch/arm/include/asm/arch-keystone/psc_defs.h      |   90 ++++++
 arch/arm/include/asm/arch-keystone/spl.h           |   12 +
 board/ti/k2hk_evm/Makefile                         |    9 +
 board/ti/k2hk_evm/README                           |  122 ++++++++
 board/ti/k2hk_evm/board.c                          |  236 +++++++++++++++
 board/ti/k2hk_evm/ddr3.c                           |  269 +++++++++++++++++
 boards.cfg                                         |    1 +
 drivers/serial/ns16550.c                           |    8 +
 include/configs/k2hk_evm.h                         |  209 +++++++++++++
 28 files changed, 2790 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/keystone/Makefile
 create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c
 create mode 100644 arch/arm/cpu/armv7/keystone/clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c
 create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c
 create mode 100644 arch/arm/cpu/armv7/keystone/init.c
 create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/psc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/spl.c
 create mode 100644 arch/arm/include/asm/arch-keystone/clock-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h
 create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/spl.h
 create mode 100644 board/ti/k2hk_evm/Makefile
 create mode 100644 board/ti/k2hk_evm/README
 create mode 100644 board/ti/k2hk_evm/board.c
 create mode 100644 board/ti/k2hk_evm/ddr3.c
 create mode 100644 include/configs/k2hk_evm.h
Makefile +10 -0
index 0281171..c497b15 100644
@@ -875,6 +875,16 @@ OBJCOPYFLAGS_u-boot.spr = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) \
 u-boot.spr: spl/u-boot-spl.img u-boot.img FORCE
 	$(call if_changed,pad_cat)
 
+MKIMAGEFLAGS_u-boot-spl.gph = -A $(ARCH) -T gpimage -C none \
+	-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) -n SPL
+spl/u-boot-spl.gph: spl/u-boot-spl.bin FORCE
+	$(call if_changed,mkimage)
+
+OBJCOPYFLAGS_u-boot-spi.gph = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) \
+			  --gap-fill=0
+u-boot-spi.gph: spl/u-boot-spl.gph u-boot.img FORCE
+	$(call if_changed,pad_cat)
+
 ifneq ($(CONFIG_TEGRA),)
 OBJCOPYFLAGS_u-boot-nodtb-tegra.bin = -O binary --pad-to=$(CONFIG_SYS_TEXT_BASE)
 u-boot-nodtb-tegra.bin: spl/u-boot-spl u-boot.bin FORCE
arch/arm/cpu/armv7/keystone/Makefile new file +17 -0
new file mode 100644
index 0000000..7924cfa
@@ -0,0 +1,17 @@
+#
+# (C) Copyright 2012-2014
+#     Texas Instruments Incorporated, <www.ti.com>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= aemif.o
+obj-y	+= init.o
+obj-y	+= psc.o
+obj-y	+= clock.o
+obj-y	+= cmd_clock.o
+obj-y	+= cmd_mon.o
+obj-y	+= msmc.o
+obj-$(CONFIG_SPL_BUILD)	+= spl.o
+obj-y	+= ddr3.o
+
arch/arm/cpu/armv7/keystone/aemif.c new file +71 -0

71 lines not on this page · raw message

arch/arm/cpu/armv7/keystone/clock.c new file +318 -0

318 lines not on this page · raw message

arch/arm/cpu/armv7/keystone/cmd_clock.c new file +124 -0

124 lines not on this page · raw message

arch/arm/cpu/armv7/keystone/cmd_mon.c new file +131 -0

131 lines not on this page · raw message

arch/arm/cpu/armv7/keystone/ddr3.c new file +69 -0

69 lines not on this page · raw message

arch/arm/cpu/armv7/keystone/init.c new file +56 -0

56 lines not on this page · raw message

arch/arm/cpu/armv7/keystone/msmc.c new file +68 -0

68 lines not on this page · raw message

arch/arm/cpu/armv7/keystone/psc.c new file +238 -0

238 lines not on this page · raw message

arch/arm/cpu/armv7/keystone/spl.c new file +45 -0

45 lines not on this page · raw message

arch/arm/include/asm/arch-keystone/clock-k2hk.h new file +109 -0

109 lines not on this page · raw message

arch/arm/include/asm/arch-keystone/clock.h new file +17 -0
new file mode 100644
index 0000000..324501b
@@ -0,0 +1,17 @@
+/*
+ * keystone2: common clock header file
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_CLOCK_H
+#define __ASM_ARCH_CLOCK_H
+
+#ifdef CONFIG_SOC_K2HK
+#include <asm/arch/clock-k2hk.h>
+#endif
+
+#endif
arch/arm/include/asm/arch-keystone/clock_defs.h new file +121 -0

121 lines not on this page · raw message

arch/arm/include/asm/arch-keystone/emif_defs.h new file +73 -0

73 lines not on this page · raw message

arch/arm/include/asm/arch-keystone/hardware-k2hk.h new file +150 -0

150 lines not on this page · raw message

arch/arm/include/asm/arch-keystone/hardware.h new file +175 -0

175 lines not on this page · raw message

arch/arm/include/asm/arch-keystone/i2c_defs.h new file +17 -0
new file mode 100644
index 0000000..d425652
@@ -0,0 +1,17 @@
+/*
+ * keystone: i2c driver definitions
+ *
+ * (C) Copyright 2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _I2C_DEFS_H_
+#define _I2C_DEFS_H_
+
+#define I2C0_BASE		0x02530000
+#define I2C1_BASE		0x02530400
+#define I2C2_BASE		0x02530800
+#define I2C_BASE		I2C0_BASE
+
+#endif
arch/arm/include/asm/arch-keystone/nand_defs.h new file +25 -0
new file mode 100644
index 0000000..272f4af
@@ -0,0 +1,25 @@
+/*
+ * nand driver definitions to re-use davinci nand driver on Keystone2
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <[email protected]>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _NAND_DEFS_H_
+#define _NAND_DEFS_H_
+
+#include <asm/arch/hardware.h>
+#include <linux/mtd/nand.h>
+
+#define MASK_CLE         0x4000
+#define	MASK_ALE         0x2000
+
+#define NAND_READ_START  0x00
+#define NAND_READ_END    0x30
+#define NAND_STATUS      0x70
+
+extern void davinci_nand_init(struct nand_chip *nand);
+
+#endif
arch/arm/include/asm/arch-keystone/psc_defs.h new file +90 -0

90 lines not on this page · raw message

arch/arm/include/asm/arch-keystone/spl.h new file +12 -0
new file mode 100644
index 0000000..7012ea7
@@ -0,0 +1,12 @@
+/*
+ * (C) Copyright 2012-2014
+ * Texas Instruments, <www.ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_SPL_H_
+#define _ASM_SPL_H_
+
+#define BOOT_DEVICE_SPI        2
+
+#endif
board/ti/k2hk_evm/Makefile new file +9 -0
new file mode 100644
index 0000000..3645f2f
@@ -0,0 +1,9 @@
+#
+# K2HK-EVM: board Makefile
+# (C) Copyright 2012-2014
+#     Texas Instruments Incorporated, <www.ti.com>
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= board.o
+obj-y	+= ddr3.o
board/ti/k2hk_evm/README new file +122 -0

122 lines not on this page · raw message

board/ti/k2hk_evm/board.c new file +236 -0

236 lines not on this page · raw message

board/ti/k2hk_evm/ddr3.c new file +269 -0

269 lines not on this page · raw message

boards.cfg +1 -0
index d28e09b..c61dbbd 100644
@@ -292,6 +292,7 @@ Active  arm         armv7          exynos      samsung         trats
 Active  arm         armv7          exynos      samsung         trats2              trats2                               -                                                                                                                                 Piotr Wilczek <[email protected]>
 Active  arm         armv7          exynos      samsung         universal_c210      s5pc210_universal                    -                                                                                                                                 Przemyslaw Marczak <[email protected]>
 Active  arm         armv7          highbank    -               highbank            highbank                             -                                                                                                                                 Rob Herring <[email protected]>
+Active  arm         armv7          keystone    ti              k2hk_evm            k2hk_evm                             -                                                                                                                                 Vitaly Andrianov <[email protected]>
 Active  arm         armv7          mx5         denx            m53evk              m53evk                               m53evk:IMX_CONFIG=board/denx/m53evk/imximage.cfg                                                                                  Marek Vasut <[email protected]>
 Active  arm         armv7          mx5         esg             ima3-mx53           ima3-mx53                            ima3-mx53:IMX_CONFIG=board/esg/ima3-mx53/imximage.cfg                                                                             -
 Active  arm         armv7          mx5         freescale       mx51evk             mx51evk                              mx51evk:IMX_CONFIG=board/freescale/mx51evk/imximage.cfg                                                                           Stefano Babic <[email protected]>
drivers/serial/ns16550.c +8 -0
index fbc37b2..8a13454 100644
@@ -30,6 +30,11 @@
 #define serial_in(y)		readb(y)
 #endif
 
+#if defined(CONFIG_K2HK_EVM)
+#define UART_REG_VAL_PWREMU_MGMT_UART_DISABLE   0
+#define UART_REG_VAL_PWREMU_MGMT_UART_ENABLE ((1 << 14) | (1 << 13) | (1 << 0))
+#endif
+
 #ifndef CONFIG_SYS_NS16550_IER
 #define CONFIG_SYS_NS16550_IER  0x00
 #endif /* CONFIG_SYS_NS16550_IER */
@@ -77,6 +82,9 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
 	/* /16 is proper to hit 115200 with 48MHz */
 	serial_out(0, &com_port->mdr1);
 #endif /* CONFIG_OMAP */
+#if defined(CONFIG_K2HK_EVM)
+	serial_out(UART_REG_VAL_PWREMU_MGMT_UART_ENABLE, &com_port->regC);
+#endif
 }
 
 #ifndef CONFIG_NS16550_MIN_FUNCTIONS
include/configs/k2hk_evm.h new file +209 -0

209 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#10 lore raw

PATCH v3 8/9 spi: davinci: add support for multiple bus and chip select

In reply to Murali Karicheri

Currently davinci spi driver supports only bus 0 cs 0. This patch allows driver to support bus 1 and bus 2 with configurable number of chip selects. Also defaults are selected in a way to avoid regression on other platforms that uses davinci spi driver and has only one spi bus.

---
 drivers/spi/davinci_spi.c |   60 ++++++++++++++++++++++++++++++++++++++++++---
 drivers/spi/davinci_spi.h |   33 +++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 3 deletions(-)
drivers/spi/davinci_spi.c +57 -3
index e3fb321..b682bc4 100644
@@ -32,7 +32,27 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 	if (!ds)
 		return NULL;
 
-	ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
+	ds->slave.bus = bus;
+	ds->slave.cs = cs;
+
+	switch (bus) {
+	case SPI0_BUS:
+		ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+		break;
+#ifdef CONFIG_SYS_SPI1
+	case SPI1_BUS:
+		ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+		break;
+#endif
+#ifdef CONFIG_SYS_SPI2
+	case SPI2_BUS:
+		ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
+		break;
+#endif
+	default: /* Invalid bus number */
+		return NULL;
+	}
+
 	ds->freq = max_hz;
 
 	return &ds->slave;
@@ -59,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave)
 	writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
 
 	/* CS, CLK, SIMO and SOMI are functional pins */
-	writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
+	writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
 		SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
 
 	/* setup format */
@@ -262,9 +282,43 @@ out:
 	return 0;
 }
 
+#ifdef CONFIG_SYS_SPI1
+static int bus1_cs_valid(unsigned int bus, unsigned int cs)
+{
+	if ((bus == SPI1_BUS) && (cs < SPI1_NUM_CS))
+		return 1;
+	return 0;
+}
+#else
+static int bus1_cs_valid(unsigned int bus, unsigned int cs)
+{
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_SPI2
+static int bus2_cs_valid(unsigned int bus, unsigned int cs)
+{
+	if ((bus == SPI2_BUS) && (cs < SPI2_NUM_CS))
+		return 1;
+	return 0;
+}
+#else
+static int bus2_cs_valid(unsigned int bus, unsigned int cs)
+{
+	return 0;
+}
+#endif
+
 int spi_cs_is_valid(unsigned int bus, unsigned int cs)
 {
-	return bus == 0 && cs == 0;
+	if ((bus == SPI0_BUS) && (cs < SPI0_NUM_CS))
+		return 1;
+	else if (bus1_cs_valid(bus, cs))
+		return 1;
+	else if (bus2_cs_valid(bus, cs))
+		return 1;
+	return 0;
 }
 
 void spi_cs_activate(struct spi_slave *slave)
drivers/spi/davinci_spi.h +33 -0
index 33f69b5..d4612d3 100644
@@ -74,6 +74,39 @@ struct davinci_spi_regs {
 /* SPIDEF */
 #define SPIDEF_CSDEF0_MASK	BIT(0)
 
+#define SPI0_BUS		0
+#define SPI0_BASE		CONFIG_SYS_SPI_BASE
+/*
+ * Define default SPI0_NUM_CS as 1 for existing platforms that uses this
+ * driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS
+ * if more than one CS is supported and by defining CONFIG_SYS_SPI0.
+ */
+#ifndef CONFIG_SYS_SPI0
+#define SPI0_NUM_CS		1
+#else
+#define SPI0_NUM_CS		CONFIG_SYS_SPI0_NUM_CS
+#endif
+
+/*
+ * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and
+ * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus
+ */
+#ifdef CONFIG_SYS_SPI1
+#define SPI1_BUS		1
+#define SPI1_NUM_CS		CONFIG_SYS_SPI1_NUM_CS
+#define SPI1_BASE		CONFIG_SYS_SPI1_BASE
+#endif
+
+/*
+ * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and
+ * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus
+ */
+#ifdef CONFIG_SYS_SPI2
+#define SPI2_BUS		2
+#define SPI2_NUM_CS		CONFIG_SYS_SPI2_NUM_CS
+#define SPI2_BASE		CONFIG_SYS_SPI2_BASE
+#endif
+
 struct davinci_spi_slave {
 	struct spi_slave slave;
 	struct davinci_spi_regs *regs;
Signature · 1 line
1.7.9.5
#11 lore raw

PATCH v3 8/9 spi: davinci: add support for multiple bus and chip select

Hi,

Quoted 146 lines · Murali Karicheri

Currently davinci spi driver supports only bus 0 cs 0. This patch allows driver to support bus 1 and bus 2 with configurable number of chip selects. Also defaults are selected in a way to avoid regression on other platforms that uses davinci spi driver and has only one spi bus.

---
 drivers/spi/davinci_spi.c |   60 ++++++++++++++++++++++++++++++++++++++++++---
 drivers/spi/davinci_spi.h |   33 +++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 3 deletions(-)
drivers/spi/davinci_spi.c +57 -3
index e3fb321..b682bc4 100644
@@ -32,7 +32,27 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!ds)
                return NULL;
 
-       ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
+       ds->slave.bus = bus;
+       ds->slave.cs = cs;
+
+       switch (bus) {
+       case SPI0_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+               break;
+#ifdef CONFIG_SYS_SPI1
+       case SPI1_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+               break;
+#endif
+#ifdef CONFIG_SYS_SPI2
+       case SPI2_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
+               break;
+#endif
+       default: /* Invalid bus number */
+               return NULL;
+       }
+
        ds->freq = max_hz;
 
        return &ds->slave;
@@ -59,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave)
        writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
 
        /* CS, CLK, SIMO and SOMI are functional pins */
-       writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
+       writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
                SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
 
        /* setup format */
@@ -262,9 +282,43 @@ out:
        return 0;
 }
 
+#ifdef CONFIG_SYS_SPI1
+static int bus1_cs_valid(unsigned int bus, unsigned int cs)
+{
+       if ((bus == SPI1_BUS) && (cs < SPI1_NUM_CS))
+               return 1;
+       return 0;
+}
+#else
+static int bus1_cs_valid(unsigned int bus, unsigned int cs)
+{
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_SPI2
+static int bus2_cs_valid(unsigned int bus, unsigned int cs)
+{
+       if ((bus == SPI2_BUS) && (cs < SPI2_NUM_CS))
+               return 1;
+       return 0;
+}
+#else
+static int bus2_cs_valid(unsigned int bus, unsigned int cs)
+{
+       return 0;
+}
+#endif
+
 int spi_cs_is_valid(unsigned int bus, unsigned int cs)
 {
-       return bus == 0 && cs == 0;
+       if ((bus == SPI0_BUS) && (cs < SPI0_NUM_CS))
+               return 1;
+       else if (bus1_cs_valid(bus, cs))
+               return 1;
+       else if (bus2_cs_valid(bus, cs))
+               return 1;
+       return 0;
 }
 
 void spi_cs_activate(struct spi_slave *slave)
drivers/spi/davinci_spi.h +33 -1
index 33f69b5..d4612d3 100644
@@ -74,6 +74,39 @@ struct davinci_spi_regs {
 /* SPIDEF */
 #define SPIDEF_CSDEF0_MASK     BIT(0)
 
+#define SPI0_BUS               0
+#define SPI0_BASE              CONFIG_SYS_SPI_BASE
+/*
+ * Define default SPI0_NUM_CS as 1 for existing platforms that uses this
+ * driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS
+ * if more than one CS is supported and by defining CONFIG_SYS_SPI0.
+ */
+#ifndef CONFIG_SYS_SPI0
+#define SPI0_NUM_CS            1
+#else
+#define SPI0_NUM_CS            CONFIG_SYS_SPI0_NUM_CS
+#endif
+
+/*
+ * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and
+ * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus
+ */
+#ifdef CONFIG_SYS_SPI1
+#define SPI1_BUS               1
+#define SPI1_NUM_CS            CONFIG_SYS_SPI1_NUM_CS
+#define SPI1_BASE              CONFIG_SYS_SPI1_BASE
+#endif
+
+/*
+ * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and
+ * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus
+ */
+#ifdef CONFIG_SYS_SPI2
+#define SPI2_BUS               2
+#define SPI2_NUM_CS            CONFIG_SYS_SPI2_NUM_CS
+#define SPI2_BASE              CONFIG_SYS_SPI2_BASE
+#endif
+
 struct davinci_spi_slave {
        struct spi_slave slave;
        struct davinci_spi_regs *regs;
--
Quoted 1 line

1.7.9.5

This code looks more static, can you try get the bus and cs from sf probe and according assign the reg_base.

fyi: look at drivers/spi/zynq_spi.c where based on the bus number we assign the reg_base and prior to that we can do the same for bus and cs.

Let me know for any more info.

thanks!

Signature · 1 line
Jagan.
#12 lore raw

PATCH v3 8/9 spi: davinci: add support for multiple bus and chip select

Quoted 161 lines

-----Original Message-----
From: Jagan Teki [mailto:jagannadh.teki at gmail.com]
Sent: Sunday, March 23, 2014 7:07 AM
To: Karicheri, Muralidharan
Cc: Rini, Tom; u-boot at lists.denx.de; Chang, Rex
Subject: Re: [U-Boot] [PATCH v3 8/9] spi: davinci: add support for multiple bus and chip select

Hi,

Quoted 11 lines · Murali Karicheri

Currently davinci spi driver supports only bus 0 cs 0. This patch allows driver to support bus 1 and bus 2 with configurable number of chip selects. Also defaults are selected in a way to avoid regression on other platforms that uses davinci spi driver and has only one spi bus.

---
 drivers/spi/davinci_spi.c |   60

++++++++++++++++++++++++++++++++++++++++++---

drivers/spi/davinci_spi.c struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int

Quoted 8 lines
 drivers/spi/davinci_spi.h |   33 +++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 3 deletions(-)
drivers/spi/davinci_spi.c +0 -0
index e3fb321..b682bc4 100644
@@ -32,7 +32,27 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int

cs,

Quoted 124 lines
drivers/spi/davinci_spi.c +22 -2
        if (!ds)
                return NULL;
 
-       ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
+       ds->slave.bus = bus;
+       ds->slave.cs = cs;
+
+       switch (bus) {
+       case SPI0_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+               break;
+#ifdef CONFIG_SYS_SPI1
+       case SPI1_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+               break;
+#endif
+#ifdef CONFIG_SYS_SPI2
+       case SPI2_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
+               break;
+#endif
+       default: /* Invalid bus number */
+               return NULL;
+       }
+
        ds->freq = max_hz;
 
        return &ds->slave;
@@ -59,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave)
        writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK,
 &ds->regs->gcr1);
 
        /* CS, CLK, SIMO and SOMI are functional pins */
-       writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
+       writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
                SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK),
 &ds->regs->pc0);
        /* setup format */
drivers/spi/davinci_spi.c +31 -1
@@ -262,9 +282,43 @@ out:
        return 0;
 }
 
+#ifdef CONFIG_SYS_SPI1
+static int bus1_cs_valid(unsigned int bus, unsigned int cs) {
+       if ((bus == SPI1_BUS) && (cs < SPI1_NUM_CS))
+               return 1;
+       return 0;
+}
+#else
+static int bus1_cs_valid(unsigned int bus, unsigned int cs) {
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_SPI2
+static int bus2_cs_valid(unsigned int bus, unsigned int cs) {
+       if ((bus == SPI2_BUS) && (cs < SPI2_NUM_CS))
+               return 1;
+       return 0;
+}
+#else
+static int bus2_cs_valid(unsigned int bus, unsigned int cs) {
+       return 0;
+}
+#endif
+
 int spi_cs_is_valid(unsigned int bus, unsigned int cs)  {
-       return bus == 0 && cs == 0;
+       if ((bus == SPI0_BUS) && (cs < SPI0_NUM_CS))
+               return 1;
+       else if (bus1_cs_valid(bus, cs))
+               return 1;
+       else if (bus2_cs_valid(bus, cs))
+               return 1;
+       return 0;
 }
 
 void spi_cs_activate(struct spi_slave *slave) diff --git

a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h index 33f69b5..d4612d3 100644

drivers/spi/davinci_spi.h +33 -1
@@ -74,6 +74,39 @@ struct davinci_spi_regs {
 /* SPIDEF */
 #define SPIDEF_CSDEF0_MASK     BIT(0)
 
+#define SPI0_BUS               0
+#define SPI0_BASE              CONFIG_SYS_SPI_BASE
+/*
+ * Define default SPI0_NUM_CS as 1 for existing platforms that uses
+this
+ * driver. Platform can configure number of CS using
+CONFIG_SYS_SPI0_NUM_CS
+ * if more than one CS is supported and by defining CONFIG_SYS_SPI0.
+ */
+#ifndef CONFIG_SYS_SPI0
+#define SPI0_NUM_CS            1
+#else
+#define SPI0_NUM_CS            CONFIG_SYS_SPI0_NUM_CS
+#endif
+
+/*
+ * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and
+ * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus  */ #ifdef
+CONFIG_SYS_SPI1
+#define SPI1_BUS               1
+#define SPI1_NUM_CS            CONFIG_SYS_SPI1_NUM_CS
+#define SPI1_BASE              CONFIG_SYS_SPI1_BASE
+#endif
+
+/*
+ * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and
+ * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus  */ #ifdef
+CONFIG_SYS_SPI2
+#define SPI2_BUS               2
+#define SPI2_NUM_CS            CONFIG_SYS_SPI2_NUM_CS
+#define SPI2_BASE              CONFIG_SYS_SPI2_BASE
+#endif
+
 struct davinci_spi_slave {
        struct spi_slave slave;
        struct davinci_spi_regs *regs;
--
Quoted 1 line

1.7.9.5

This code looks more static, can you try get the bus and cs from sf probe and according assign the reg_base.

Quoted 3 lines

fyi: look at drivers/spi/zynq_spi.c where based on the bus number we assign the reg_base and prior to that we can do the same for bus and cs.

Jagan,

Thanks for your comments.

I looked at the driver code. In the example driver you provided the reg_base is chosen based on device number and the hardware.h define the base0 and base1 address and assign it based on device number. davinci_spi is re-used on many devices. All of the DaVinci devices such as dm644x, dm355, dm365 etc that mostly has one SPI device vs keystone devices such k2h/k that has 3 devices. If I follow this approach, I need to define BASE1 and BASE2 in the hardware.h of all devices that this software must run. This is not right since DaVinci devices has only one SPI device

I think this is what best we can do given that the driver needs to be re-used across multiple devices and static is the way to go unless you have better suggestion to handle this scenario.

Thanks.

Murali

Quoted 5 lines

Let me know for any more info.

thanks!
--
Jagan.

#13 lore raw

PATCH v3 8/9 spi: davinci: add support for multiple bus and chip select

Quoted 179 lines · Muralidharan
Quoted 161 lines

-----Original Message-----
From: Jagan Teki [mailto:jagannadh.teki at gmail.com]
Sent: Sunday, March 23, 2014 7:07 AM
To: Karicheri, Muralidharan
Cc: Rini, Tom; u-boot at lists.denx.de; Chang, Rex
Subject: Re: [U-Boot] [PATCH v3 8/9] spi: davinci: add support for multiple bus and chip select

Hi,

Quoted 11 lines · Murali Karicheri

Currently davinci spi driver supports only bus 0 cs 0. This patch allows driver to support bus 1 and bus 2 with configurable number of chip selects. Also defaults are selected in a way to avoid regression on other platforms that uses davinci spi driver and has only one spi bus.

---
 drivers/spi/davinci_spi.c |   60

++++++++++++++++++++++++++++++++++++++++++---

drivers/spi/davinci_spi.c struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int

Quoted 8 lines
 drivers/spi/davinci_spi.h |   33 +++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 3 deletions(-)
drivers/spi/davinci_spi.c +0 -0
index e3fb321..b682bc4 100644
@@ -32,7 +32,27 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int

cs,

Quoted 124 lines
drivers/spi/davinci_spi.c +22 -2
        if (!ds)
                return NULL;
 
-       ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
+       ds->slave.bus = bus;
+       ds->slave.cs = cs;
+
+       switch (bus) {
+       case SPI0_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+               break;
+#ifdef CONFIG_SYS_SPI1
+       case SPI1_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+               break;
+#endif
+#ifdef CONFIG_SYS_SPI2
+       case SPI2_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
+               break;
+#endif
+       default: /* Invalid bus number */
+               return NULL;
+       }
+
        ds->freq = max_hz;
 
        return &ds->slave;
@@ -59,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave)
        writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK,
 &ds->regs->gcr1);
 
        /* CS, CLK, SIMO and SOMI are functional pins */
-       writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
+       writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
                SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK),
 &ds->regs->pc0);
        /* setup format */
drivers/spi/davinci_spi.c +31 -1
@@ -262,9 +282,43 @@ out:
        return 0;
 }
 
+#ifdef CONFIG_SYS_SPI1
+static int bus1_cs_valid(unsigned int bus, unsigned int cs) {
+       if ((bus == SPI1_BUS) && (cs < SPI1_NUM_CS))
+               return 1;
+       return 0;
+}
+#else
+static int bus1_cs_valid(unsigned int bus, unsigned int cs) {
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_SPI2
+static int bus2_cs_valid(unsigned int bus, unsigned int cs) {
+       if ((bus == SPI2_BUS) && (cs < SPI2_NUM_CS))
+               return 1;
+       return 0;
+}
+#else
+static int bus2_cs_valid(unsigned int bus, unsigned int cs) {
+       return 0;
+}
+#endif
+
 int spi_cs_is_valid(unsigned int bus, unsigned int cs)  {
-       return bus == 0 && cs == 0;
+       if ((bus == SPI0_BUS) && (cs < SPI0_NUM_CS))
+               return 1;
+       else if (bus1_cs_valid(bus, cs))
+               return 1;
+       else if (bus2_cs_valid(bus, cs))
+               return 1;
+       return 0;
 }
 
 void spi_cs_activate(struct spi_slave *slave) diff --git

a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h index 33f69b5..d4612d3 100644

drivers/spi/davinci_spi.h +33 -1
@@ -74,6 +74,39 @@ struct davinci_spi_regs {
 /* SPIDEF */
 #define SPIDEF_CSDEF0_MASK     BIT(0)
 
+#define SPI0_BUS               0
+#define SPI0_BASE              CONFIG_SYS_SPI_BASE
+/*
+ * Define default SPI0_NUM_CS as 1 for existing platforms that uses
+this
+ * driver. Platform can configure number of CS using
+CONFIG_SYS_SPI0_NUM_CS
+ * if more than one CS is supported and by defining CONFIG_SYS_SPI0.
+ */
+#ifndef CONFIG_SYS_SPI0
+#define SPI0_NUM_CS            1
+#else
+#define SPI0_NUM_CS            CONFIG_SYS_SPI0_NUM_CS
+#endif
+
+/*
+ * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and
+ * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus  */ #ifdef
+CONFIG_SYS_SPI1
+#define SPI1_BUS               1
+#define SPI1_NUM_CS            CONFIG_SYS_SPI1_NUM_CS
+#define SPI1_BASE              CONFIG_SYS_SPI1_BASE
+#endif
+
+/*
+ * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and
+ * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus  */ #ifdef
+CONFIG_SYS_SPI2
+#define SPI2_BUS               2
+#define SPI2_NUM_CS            CONFIG_SYS_SPI2_NUM_CS
+#define SPI2_BASE              CONFIG_SYS_SPI2_BASE
+#endif
+
 struct davinci_spi_slave {
        struct spi_slave slave;
        struct davinci_spi_regs *regs;
--
Quoted 1 line

1.7.9.5

This code looks more static, can you try get the bus and cs from sf probe and according assign the reg_base.

Quoted 3 lines

fyi: look at drivers/spi/zynq_spi.c where based on the bus number we assign the reg_base and prior to that we can do the same for bus and cs.

Jagan,

Thanks for your comments.

I looked at the driver code. In the example driver you provided the reg_base is chosen based on device number and the hardware.h define the base0 and base1 address and assign it based on device number. davinci_spi is re-used on many devices. All of the DaVinci devices such as dm644x, dm355, dm365 etc that mostly has one SPI device vs keystone devices such k2h/k that has 3 devices. If I follow this approach, I need to define BASE1 and BASE2 in the hardware.h of all devices that this software must run. This is not right since DaVinci devices has only one SPI device

Quoted 3 lines

I think this is what best we can do given that the driver needs to be re-used across multiple devices and static is the way to go unless you have better suggestion to handle this scenario.

Agree with your comments as reg_base is not possible to define at one place due to this you may not try as I suggested.

OK, atleast can you aviod using busx_cs_valid() calls, try to manage spi_cs_is_valid() itself.

thanks!

Signature · 1 line
Jagan.
#14 lore raw

PATCH v3 8/9 spi: davinci: add support for multiple bus and chip select

Quoted 197 lines

-----Original Message-----
From: Jagan Teki [mailto:jagannadh.teki at gmail.com]
Sent: Thursday, March 27, 2014 1:47 PM
To: Karicheri, Muralidharan
Cc: Rini, Tom; u-boot at lists.denx.de; Chang, Rex
Subject: Re: [U-Boot] [PATCH v3 8/9] spi: davinci: add support for multiple bus and chip select

Quoted 184 lines · Muralidharan
Quoted 166 lines

-----Original Message-----
From: Jagan Teki [mailto:jagannadh.teki at gmail.com]
Sent: Sunday, March 23, 2014 7:07 AM
To: Karicheri, Muralidharan
Cc: Rini, Tom; u-boot at lists.denx.de; Chang, Rex
Subject: Re: [U-Boot] [PATCH v3 8/9] spi: davinci: add support for multiple bus and chip select

Hi,

Quoted 11 lines · Murali Karicheri

Currently davinci spi driver supports only bus 0 cs 0. This patch allows driver to support bus 1 and bus 2 with configurable number of chip selects. Also defaults are selected in a way to avoid regression on other platforms that uses davinci spi driver and has only one spi bus.

---
 drivers/spi/davinci_spi.c |   60

++++++++++++++++++++++++++++++++++++++++++---

Quoted 9 lines
 drivers/spi/davinci_spi.h |   33 +++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 3 deletions(-)
drivers/spi/davinci_spi.c +0 -0
index e3fb321..b682bc4 100644
@@ -32,7 +32,27 @@ struct spi_slave *spi_setup_slave(unsigned int

bus, unsigned int

cs,

Quoted 128 lines
        if (!ds)
                return NULL;
drivers/spi/davinci_spi.c +22 -2
-       ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
+       ds->slave.bus = bus;
+       ds->slave.cs = cs;
+
+       switch (bus) {
+       case SPI0_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+               break;
+#ifdef CONFIG_SYS_SPI1
+       case SPI1_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+               break;
+#endif
+#ifdef CONFIG_SYS_SPI2
+       case SPI2_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
+               break;
+#endif
+       default: /* Invalid bus number */
+               return NULL;
+       }
+
        ds->freq = max_hz;
 
        return &ds->slave;
@@ -59,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave)
        writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK,
 &ds->regs->gcr1);
 
        /* CS, CLK, SIMO and SOMI are functional pins */
-       writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
+       writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
                SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK),
 &ds->regs->pc0);
        /* setup format */
drivers/spi/davinci_spi.c +31 -1
@@ -262,9 +282,43 @@ out:
        return 0;
 }
 
+#ifdef CONFIG_SYS_SPI1
+static int bus1_cs_valid(unsigned int bus, unsigned int cs) {
+       if ((bus == SPI1_BUS) && (cs < SPI1_NUM_CS))
+               return 1;
+       return 0;
+}
+#else
+static int bus1_cs_valid(unsigned int bus, unsigned int cs) {
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_SPI2
+static int bus2_cs_valid(unsigned int bus, unsigned int cs) {
+       if ((bus == SPI2_BUS) && (cs < SPI2_NUM_CS))
+               return 1;
+       return 0;
+}
+#else
+static int bus2_cs_valid(unsigned int bus, unsigned int cs) {
+       return 0;
+}
+#endif
+
 int spi_cs_is_valid(unsigned int bus, unsigned int cs)  {
-       return bus == 0 && cs == 0;
+       if ((bus == SPI0_BUS) && (cs < SPI0_NUM_CS))
+               return 1;
+       else if (bus1_cs_valid(bus, cs))
+               return 1;
+       else if (bus2_cs_valid(bus, cs))
+               return 1;
+       return 0;
 }
 
 void spi_cs_activate(struct spi_slave *slave) diff --git

a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h index 33f69b5..d4612d3 100644

drivers/spi/davinci_spi.h +37 -1
@@ -74,6 +74,39 @@ struct davinci_spi_regs {
 /* SPIDEF */
 #define SPIDEF_CSDEF0_MASK     BIT(0)
 
+#define SPI0_BUS               0
+#define SPI0_BASE              CONFIG_SYS_SPI_BASE
+/*
+ * Define default SPI0_NUM_CS as 1 for existing platforms that uses
+this
+ * driver. Platform can configure number of CS using
+CONFIG_SYS_SPI0_NUM_CS
+ * if more than one CS is supported and by defining CONFIG_SYS_SPI0.
+ */
+#ifndef CONFIG_SYS_SPI0
+#define SPI0_NUM_CS            1
+#else
+#define SPI0_NUM_CS            CONFIG_SYS_SPI0_NUM_CS
+#endif
+
+/*
+ * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1)
+and
+ * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus  */
+#ifdef
+CONFIG_SYS_SPI1
+#define SPI1_BUS               1
+#define SPI1_NUM_CS            CONFIG_SYS_SPI1_NUM_CS
+#define SPI1_BASE              CONFIG_SYS_SPI1_BASE
+#endif
+
+/*
+ * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2)
+and
+ * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus  */
+#ifdef
+CONFIG_SYS_SPI2
+#define SPI2_BUS               2
+#define SPI2_NUM_CS            CONFIG_SYS_SPI2_NUM_CS
+#define SPI2_BASE              CONFIG_SYS_SPI2_BASE
+#endif
+
 struct davinci_spi_slave {
        struct spi_slave slave;
        struct davinci_spi_regs *regs;
--
Quoted 1 line

1.7.9.5

This code looks more static, can you try get the bus and cs from sf probe and according assign the reg_base.

Quoted 3 lines

fyi: look at drivers/spi/zynq_spi.c where based on the bus number we assign the reg_base and prior to that we can do the same for bus and cs.

Jagan,

Thanks for your comments.

I looked at the driver code. In the example driver you provided the reg_base is chosen based on device number and the hardware.h define the base0 and base1 address and assign it based on device number. davinci_spi is re-used on many devices. All of the DaVinci devices such as dm644x, dm355, dm365 etc that mostly has one SPI device vs keystone devices such k2h/k that has 3 devices.
If I follow this approach, I need to define BASE1 and BASE2 in the hardware.h of all devices that this software must run. This is not right since DaVinci devices has only one SPI device

Quoted 3 lines

I think this is what best we can do given that the driver needs to be re-used across multiple devices and static is the way to go unless you have better suggestion to handle this scenario.

Quoted 6 lines

Agree with your comments as reg_base is not possible to define at one place due to this you may not try as I suggested.

OK, atleast can you aviod using busx_cs_valid() calls, try to manage spi_cs_is_valid() itself.

Jagan,

Thanks again. But to me it is just a personal opinion. I would let it go ASIS unless you can give me a strong reason to change the code and provide a sample as well. The if else statement with #ifdef interleaved will make it really messy. I will make it static inline as the function call is unnecessary.

Murali

Quoted 3 lines

thanks!
--
Jagan.

#15 lore raw

PATCH v3 8/9 spi: davinci: add support for multiple bus and chip select

Quoted 1 line

-----Original Message-----

From: [email protected] [mailto:u-boot-bounces at lists.denx.de] On Behalf Of

Quoted 211 lines

Karicheri, Muralidharan
Sent: Monday, March 31, 2014 4:10 PM
To: Jagan Teki
Cc: Rini, Tom; u-boot at lists.denx.de; Chang, Rex
Subject: Re: [U-Boot] [PATCH v3 8/9] spi: davinci: add support for multiple bus and chip select

Quoted 9 lines

-----Original Message-----
From: Jagan Teki [mailto:jagannadh.teki at gmail.com]
Sent: Thursday, March 27, 2014 1:47 PM
To: Karicheri, Muralidharan
Cc: Rini, Tom; u-boot at lists.denx.de; Chang, Rex
Subject: Re: [U-Boot] [PATCH v3 8/9] spi: davinci: add support for multiple bus and chip select

On Thu, Mar 27, 2014 at 1:19 AM, Karicheri, Muralidharan <[email protected]>

Quoted 188 lines · wrote:
Quoted 184 lines
Quoted 166 lines

-----Original Message-----
From: Jagan Teki [mailto:jagannadh.teki at gmail.com]
Sent: Sunday, March 23, 2014 7:07 AM
To: Karicheri, Muralidharan
Cc: Rini, Tom; u-boot at lists.denx.de; Chang, Rex
Subject: Re: [U-Boot] [PATCH v3 8/9] spi: davinci: add support for multiple bus and chip select

Hi,

Quoted 11 lines · Murali Karicheri

Currently davinci spi driver supports only bus 0 cs 0. This patch allows driver to support bus 1 and bus 2 with configurable number of chip selects. Also defaults are selected in a way to avoid regression on other platforms that uses davinci spi driver and has only one spi bus.

---
 drivers/spi/davinci_spi.c |   60

++++++++++++++++++++++++++++++++++++++++++---

Quoted 9 lines
 drivers/spi/davinci_spi.h |   33 +++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 3 deletions(-)
drivers/spi/davinci_spi.c +0 -0
index e3fb321..b682bc4 100644
@@ -32,7 +32,27 @@ struct spi_slave *spi_setup_slave(unsigned int

bus, unsigned int

cs,

Quoted 128 lines
        if (!ds)
                return NULL;
drivers/spi/davinci_spi.c +22 -2
-       ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
+       ds->slave.bus = bus;
+       ds->slave.cs = cs;
+
+       switch (bus) {
+       case SPI0_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+               break;
+#ifdef CONFIG_SYS_SPI1
+       case SPI1_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+               break;
+#endif
+#ifdef CONFIG_SYS_SPI2
+       case SPI2_BUS:
+               ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
+               break;
+#endif
+       default: /* Invalid bus number */
+               return NULL;
+       }
+
        ds->freq = max_hz;
 
        return &ds->slave;
@@ -59,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave)
        writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK,
 &ds->regs->gcr1);
 
        /* CS, CLK, SIMO and SOMI are functional pins */
-       writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
+       writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
                SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK),
 &ds->regs->pc0);
        /* setup format */
drivers/spi/davinci_spi.c +31 -1
@@ -262,9 +282,43 @@ out:
        return 0;
 }
 
+#ifdef CONFIG_SYS_SPI1
+static int bus1_cs_valid(unsigned int bus, unsigned int cs) {
+       if ((bus == SPI1_BUS) && (cs < SPI1_NUM_CS))
+               return 1;
+       return 0;
+}
+#else
+static int bus1_cs_valid(unsigned int bus, unsigned int cs) {
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_SPI2
+static int bus2_cs_valid(unsigned int bus, unsigned int cs) {
+       if ((bus == SPI2_BUS) && (cs < SPI2_NUM_CS))
+               return 1;
+       return 0;
+}
+#else
+static int bus2_cs_valid(unsigned int bus, unsigned int cs) {
+       return 0;
+}
+#endif
+
 int spi_cs_is_valid(unsigned int bus, unsigned int cs)  {
-       return bus == 0 && cs == 0;
+       if ((bus == SPI0_BUS) && (cs < SPI0_NUM_CS))
+               return 1;
+       else if (bus1_cs_valid(bus, cs))
+               return 1;
+       else if (bus2_cs_valid(bus, cs))
+               return 1;
+       return 0;
 }
 
 void spi_cs_activate(struct spi_slave *slave) diff --git

a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h index 33f69b5..d4612d3 100644

drivers/spi/davinci_spi.h +37 -1
@@ -74,6 +74,39 @@ struct davinci_spi_regs {
 /* SPIDEF */
 #define SPIDEF_CSDEF0_MASK     BIT(0)
 
+#define SPI0_BUS               0
+#define SPI0_BASE              CONFIG_SYS_SPI_BASE
+/*
+ * Define default SPI0_NUM_CS as 1 for existing platforms that
+uses this
+ * driver. Platform can configure number of CS using
+CONFIG_SYS_SPI0_NUM_CS
+ * if more than one CS is supported and by defining CONFIG_SYS_SPI0.
+ */
+#ifndef CONFIG_SYS_SPI0
+#define SPI0_NUM_CS            1
+#else
+#define SPI0_NUM_CS            CONFIG_SYS_SPI0_NUM_CS
+#endif
+
+/*
+ * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1)
+and
+ * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus  */
+#ifdef
+CONFIG_SYS_SPI1
+#define SPI1_BUS               1
+#define SPI1_NUM_CS            CONFIG_SYS_SPI1_NUM_CS
+#define SPI1_BASE              CONFIG_SYS_SPI1_BASE
+#endif
+
+/*
+ * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2)
+and
+ * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus  */
+#ifdef
+CONFIG_SYS_SPI2
+#define SPI2_BUS               2
+#define SPI2_NUM_CS            CONFIG_SYS_SPI2_NUM_CS
+#define SPI2_BASE              CONFIG_SYS_SPI2_BASE
+#endif
+
 struct davinci_spi_slave {
        struct spi_slave slave;
        struct davinci_spi_regs *regs;
--
Quoted 1 line

1.7.9.5

This code looks more static, can you try get the bus and cs from sf probe and according assign the reg_base.

Quoted 3 lines

fyi: look at drivers/spi/zynq_spi.c where based on the bus number we assign the reg_base and prior to that we can do the same for bus and cs.

Jagan,

Thanks for your comments.

I looked at the driver code. In the example driver you provided the reg_base is chosen based on device number and the hardware.h define the base0 and base1 address and assign it based on device number. davinci_spi is re-used on many devices. All of the DaVinci devices such as dm644x, dm355, dm365 etc that mostly has one SPI device vs keystone devices such k2h/k that has 3 devices.
If I follow this approach, I need to define BASE1 and BASE2 in the hardware.h of all devices that this software must run. This is not right since DaVinci devices has only one SPI device

Quoted 3 lines

I think this is what best we can do given that the driver needs to be re-used across multiple devices and static is the way to go unless you have better suggestion to handle this scenario.

Quoted 6 lines

Agree with your comments as reg_base is not possible to define at one place due to this you may not try as I suggested.

OK, atleast can you aviod using busx_cs_valid() calls, try to manage spi_cs_is_valid() itself.

Quoted 7 lines

Jagan,

Thanks again. But to me it is just a personal opinion. I would let it go ASIS unless you can give me a strong reason to change the code and provide a sample as well. The if else statement with #ifdef interleaved will make it really messy. I will make it static inline as the function call is unnecessary.

Jagan,

Ok. I found my original code will add additional return statements on platforms that doesn't have more than one SPI device. So reworked the patch as you have suggested. Please see the v5 for the change and I will be sending the same today.

Murali

Quoted 8 lines

Murali

Quoted 3 lines

thanks!
--
Jagan.

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

#16 lore raw

PATCH v3 9/9 k2hk-evm: add configuration for spi1 and spi2 support

In reply to Murali Karicheri

currently only spi0 is enabled on k2hk evm. This configuration update is needed to enable spi1 and spi2.

---
 include/configs/k2hk_evm.h |    9 +++++++++
 1 file changed, 9 insertions(+)
include/configs/k2hk_evm.h +9 -0
index 8db134a..6bdeb90 100644
@@ -81,7 +81,16 @@
 #define CONFIG_SPI_FLASH
 #define CONFIG_SPI_FLASH_STMICRO
 #define CONFIG_DAVINCI_SPI
+#define CONFIG_SYS_SPI0
 #define CONFIG_SYS_SPI_BASE             K2HK_SPI_BASE
+#define CONFIG_SYS_SPI0_NUM_CS          4
+#define CONFIG_SYS_SPI1
+#define CONFIG_SYS_SPI1_BASE            K2HK_SPI1_BASE
+#define CONFIG_SYS_SPI1_NUM_CS          4
+#define CONFIG_SYS_SPI2
+#define CONFIG_SYS_SPI2_NUM_CS          4
+#define CONFIG_SYS_SPI2_BASE            K2HK_SPI2_BASE
+#define CONFIG_CMD_SPI
 #define CONFIG_SYS_SPI_CLK              clk_get_rate(K2HK_LPSC_EMIF25_SPI)
 #define CONFIG_SF_DEFAULT_SPEED         30000000
 #define CONFIG_ENV_SPI_MAX_HZ           CONFIG_SF_DEFAULT_SPEED
Signature · 1 line
1.7.9.5