Skip to contentSkip to conversation

arm: add Faraday A36x SoC platform support

PATCH Superseded Kuo-Jung Su 12 participants 311 messages Mar 29, 2013 – Apr 7, 2014 Page 1 of 3

Subsystems (16)
lore
Share & tools
lore
#0 lore raw

cover arm: add Faraday A36x SoC platform support

From: Kuo-Jung Su <[email protected]>

These patches introduce Faraday A36x SoC platform support.

Here are some public documents for your reference.

http://www.faraday-tech.com/html/documentation/index.html

There is also a A369 QEMU emulator available at my github account:

    https://github.com/dantesu1218/qemu.git

Here is quick start for QEMU:

1. Download the QEMU source tree

    $ git clone -b qemu-1.3.0 https://github.com/dantesu1218/qemu.git

2. Build & Install the QEMU:

    $ ./configure --target-list=arm-softmmu
    $ make
    $ make install

3. Launch u-boot with QEMU:

    $ qemu-system-arm -M a369 -m 512M -nographic -kernel ~/u-boot-2012.10/u-boot

Kuo-Jung Su (11):
arm: add MMU/d-cache support for Faraday cores net/ftgmac100: add MMU/D-cache support
net: add FTMAC110 10/100Mbps ethernet support
usb-ehci: add Faraday USB 2.0 EHCI controller support
usb-gadget: add FOTG210 USB gadget support
i2c: add FTI2C010 I2C controller support
spi: add FTSPI010 SPI controller support mtd/nand: add FTNANDC021 NAND flash controller support mtd/spi: add FTSPI020 SPI Flash controller support
mmc: add an alternative FTSDC010 driver support
arm: add Faraday A36x SoC platform support

 arch/arm/cpu/faraday/Makefile             |   57 ++
 arch/arm/cpu/faraday/a360/Makefile        |   49 ++
 arch/arm/cpu/faraday/a360/reset.c         |   22 +
 arch/arm/cpu/faraday/a369/Makefile        |   50 ++
 arch/arm/cpu/faraday/a369/cmd_fa606.c     |   74 +++
 arch/arm/cpu/faraday/a369/reset.c         |   22 +
 arch/arm/cpu/faraday/cmd_bootfa.c         |  121 ++++
 arch/arm/cpu/faraday/config.mk            |   33 +
 arch/arm/cpu/faraday/cpu.c                |  230 +++++++
 arch/arm/cpu/faraday/ftpwmtmr010.c        |  165 +++++
 arch/arm/cpu/faraday/fttmr010.c           |  155 +++++
 arch/arm/cpu/faraday/fwimage.h            |   38 ++
 arch/arm/cpu/faraday/fwimage2.h           |   70 +++
 arch/arm/cpu/faraday/interrupts.c         |  169 ++++++
 arch/arm/cpu/faraday/start.S              |  535 +++++++++++++++++
 arch/arm/cpu/u-boot.lds                   |   11 +
 arch/arm/include/asm/arch-a360/hardware.h |   80 +++
 arch/arm/include/asm/arch-a369/hardware.h |  106 ++++
 arch/arm/include/asm/dma-mapping.h        |   55 +-
 arch/arm/include/asm/global_data.h        |    4 +
 arch/arm/include/asm/io.h                 |   75 +++
 arch/arm/include/asm/mach-types.h         |    1 +
 arch/arm/lib/cache-cp15.c                 |   44 ++
 board/faraday/a360evb/Makefile            |   49 ++
 board/faraday/a360evb/board.c             |   65 ++
 board/faraday/a360evb/clk.c               |   48 ++
 board/faraday/a360evb/config.mk           |   33 +
 board/faraday/a360evb/lowlevel_init.S     |   33 +
 board/faraday/a369evb/Makefile            |   49 ++
 board/faraday/a369evb/board.c             |  182 ++++++
 board/faraday/a369evb/clk.c               |   80 +++
 board/faraday/a369evb/config.mk           |   33 +
 board/faraday/a369evb/lowlevel_init.S     |  133 +++++
 boards.cfg                                |    3 +
 common/cmd_boot.c                         |    4 +
 common/usb_hub.c                          |    5 +
 drivers/i2c/Makefile                      |    1 +
 drivers/i2c/fti2c010.c                    |  360 +++++++++++
 drivers/i2c/fti2c010.h                    |   68 +++
 drivers/mmc/Makefile                      |    1 +
 drivers/mmc/ftsdc010_mci.c                |  362 +++++++++++
 drivers/mmc/ftsdc010_mci.h                |   91 +++
 drivers/mtd/nand/Makefile                 |    1 +
 drivers/mtd/nand/ftnandc021.c             |  550 +++++++++++++++++
 drivers/mtd/nand/ftnandc021.h             |  165 +++++
 drivers/mtd/spi/Makefile                  |    4 +
 drivers/mtd/spi/ftspi020.c                |  589 ++++++++++++++++++
 drivers/mtd/spi/ftspi020.h                |  118 ++++
 drivers/mtd/spi/winbond.c                 |   17 +-
 drivers/net/Makefile                      |    1 +
 drivers/net/ftgmac100.c                   |   83 ++-
 drivers/net/ftmac110.c                    |  484 +++++++++++++++
 drivers/net/ftmac110.h                    |  131 ++++
 drivers/spi/Makefile                      |    1 +
 drivers/spi/ftssp010_spi.c                |  333 +++++++++++
 drivers/spi/ftssp010_spi.h                |   85 +++
 drivers/usb/gadget/Makefile               |    1 +
 drivers/usb/gadget/fotg210.c              |  926 +++++++++++++++++++++++++++++
 drivers/usb/gadget/fotg210.h              |   99 +++
 drivers/usb/gadget/gadget_chips.h         |    8 +
 drivers/usb/host/Makefile                 |    1 +
 drivers/usb/host/ehci-faraday.c           |  157 +++++
 drivers/usb/host/ehci-hcd.c               |   11 +
 drivers/usb/host/ehci.h                   |    5 +
 include/common.h                          |   13 +
 include/configs/a360.h                    |  180 ++++++
 include/configs/a369.h                    |   40 ++
 include/configs/a369_defaults.h           |  285 +++++++++
 include/configs/a369_fa606te.h            |   32 +
 include/faraday/fttmr010.h                |   51 +-
 include/faraday/ftwdt010_wdt.h            |    8 +
 71 files changed, 8110 insertions(+), 35 deletions(-)
 create mode 100644 arch/arm/cpu/faraday/Makefile
 create mode 100644 arch/arm/cpu/faraday/a360/Makefile
 create mode 100644 arch/arm/cpu/faraday/a360/reset.c
 create mode 100644 arch/arm/cpu/faraday/a369/Makefile
 create mode 100644 arch/arm/cpu/faraday/a369/cmd_fa606.c
 create mode 100644 arch/arm/cpu/faraday/a369/reset.c
 create mode 100644 arch/arm/cpu/faraday/cmd_bootfa.c
 create mode 100644 arch/arm/cpu/faraday/config.mk
 create mode 100644 arch/arm/cpu/faraday/cpu.c
 create mode 100644 arch/arm/cpu/faraday/ftpwmtmr010.c
 create mode 100644 arch/arm/cpu/faraday/fttmr010.c
 create mode 100644 arch/arm/cpu/faraday/fwimage.h
 create mode 100644 arch/arm/cpu/faraday/fwimage2.h
 create mode 100644 arch/arm/cpu/faraday/interrupts.c
 create mode 100644 arch/arm/cpu/faraday/start.S
 create mode 100644 arch/arm/include/asm/arch-a360/hardware.h
 create mode 100644 arch/arm/include/asm/arch-a369/hardware.h
 create mode 100644 board/faraday/a360evb/Makefile
 create mode 100644 board/faraday/a360evb/board.c
 create mode 100644 board/faraday/a360evb/clk.c
 create mode 100644 board/faraday/a360evb/config.mk
 create mode 100644 board/faraday/a360evb/lowlevel_init.S
 create mode 100644 board/faraday/a369evb/Makefile
 create mode 100644 board/faraday/a369evb/board.c
 create mode 100644 board/faraday/a369evb/clk.c
 create mode 100644 board/faraday/a369evb/config.mk
 create mode 100644 board/faraday/a369evb/lowlevel_init.S
 create mode 100644 drivers/i2c/fti2c010.c
 create mode 100644 drivers/i2c/fti2c010.h
 create mode 100644 drivers/mmc/ftsdc010_mci.c
 create mode 100644 drivers/mmc/ftsdc010_mci.h
 create mode 100644 drivers/mtd/nand/ftnandc021.c
 create mode 100644 drivers/mtd/nand/ftnandc021.h
 create mode 100644 drivers/mtd/spi/ftspi020.c
 create mode 100644 drivers/mtd/spi/ftspi020.h
 create mode 100644 drivers/net/ftmac110.c
 create mode 100644 drivers/net/ftmac110.h
 create mode 100644 drivers/spi/ftssp010_spi.c
 create mode 100644 drivers/spi/ftssp010_spi.h
 create mode 100644 drivers/usb/gadget/fotg210.c
 create mode 100644 drivers/usb/gadget/fotg210.h
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/configs/a360.h
 create mode 100644 include/configs/a369.h
 create mode 100644 include/configs/a369_defaults.h
 create mode 100644 include/configs/a369_fa606te.h

--
1.7.9.5

#1 lore raw

PATCH 1/11 arm: add MMU/d-cache support for Faraday cores

From: Kuo-Jung Su <[email protected]>

This patch would enable MMU for Faraday ARMv5TE cores.

Here is the abstract of the MMU design.

Assume SDRAM memory region starts at 0x10000000, and its size = 0x800000.

0x00000000 +-------------------+

           |                   |
           |     UN-CACHED     |
           |                   |
           |                   |
0x10000000 +-------------------+
           |  CACHED (SDRAM)   | <- It's where data/bss/stack lived.
           |                   |
           |                   |
0x10800000 +-------------------+
           |                   |
           |                   |
           |     UN-CACHED     |
           |                   |
           |                   |
0xFF800000 +-------------------+
           | UN-CACHED (SDRAM) | <- An un-cached shadow of the SDRAM.
           |                   |    dma_alloc_coherent() always returns
           |                   |    an address in this region.

0xFFFFFFFF +-------------------+

---
 arch/arm/include/asm/dma-mapping.h |   55 ++++++++++++++++++++++++--
 arch/arm/include/asm/global_data.h |    4 ++
 arch/arm/include/asm/io.h          |   75 ++++++++++++++++++++++++++++++++++++
 arch/arm/lib/cache-cp15.c          |   44 +++++++++++++++++++++
 common/cmd_boot.c                  |    4 ++
 5 files changed, 179 insertions(+), 3 deletions(-)
arch/arm/include/asm/dma-mapping.h +52 -3
index 5bbb0a0..d4f779e 100644
@@ -2,6 +2,8 @@
  * (C) Copyright 2007
  * Stelian Pop <[email protected]>
  * Lead Tech Design <www.leadtechdesign.com>
+ * (C) Copyright 2010
+ * Dante Su <[email protected]>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -24,22 +26,69 @@
 #ifndef __ASM_ARM_DMA_MAPPING_H
 #define __ASM_ARM_DMA_MAPPING_H
 
+#include <asm/io.h>
+#include <malloc.h>
+
 enum dma_data_direction {
 	DMA_BIDIRECTIONAL	= 0,
 	DMA_TO_DEVICE		= 1,
 	DMA_FROM_DEVICE		= 2,
 };
 
-static void *dma_alloc_coherent(size_t len, unsigned long *handle)
+static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
 {
-	*handle = (unsigned long)malloc(len);
-	return (void *)*handle;
+	void *va = memalign(ARCH_DMA_MINALIGN, len);
+	if (va && handle)
+		*handle = virt_to_phys(va);
+
+#ifdef CONFIG_FARADAY
+# ifndef CONFIG_SYS_DCACHE_OFF
+#include <asm/u-boot.h> /* boot information for Linux kernel */
+#include <asm/global_data.h>	/* global data used for startup functions */
+	DECLARE_GLOBAL_DATA_PTR;
+
+	if (gd->arch.cpu_mmu) {
+		/* invalidate the buffer, and change to un-cached memory address */
+		if (va != NULL) {
+			invalidate_dcache_range((ulong)va, (ulong)va + len);
+			va = __uncached(va);
+		}
+	}
+# endif
+#endif	/* CONFIG_FARADAY */
+
+	return va;
+}
+
+static inline void dma_free_coherent(void *va)
+{
+	free(__cached(va));
 }
 
 static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
 					   enum dma_data_direction dir)
 {
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+#include <asm/u-boot.h> /* boot information for Linux kernel */
+#include <asm/global_data.h>	/* global data used for startup functions */
+	DECLARE_GLOBAL_DATA_PTR;
+
+	if (gd->arch.cpu_mmu) {
+		switch (dir) {
+		case DMA_BIDIRECTIONAL:
+		case DMA_TO_DEVICE:
+			flush_dcache_range((unsigned long)vaddr, (unsigned long)vaddr + len);
+			break;
+
+		case DMA_FROM_DEVICE:
+			invalidate_dcache_range((unsigned long)vaddr, (unsigned long)vaddr + len);
+			break;
+		}
+	}
+	return virt_to_phys((void *)vaddr);
+#else
 	return (unsigned long)vaddr;
+#endif
 }
 
 static inline void dma_unmap_single(volatile void *vaddr, size_t len,
arch/arm/include/asm/global_data.h +4 -0
index 37ac0da..bd18ff7 100644
@@ -38,6 +38,10 @@ struct arch_global_data {
 	unsigned long	pllb_rate_hz;
 	unsigned long	at91_pllb_usb_init;
 #endif
+#ifdef CONFIG_FARADAY
+	unsigned long   cpu_id;
+	unsigned long   cpu_mmu;	/* has mmu */
+#endif
 	/* "static data" needed by most of timer.c on ARM platforms */
 	unsigned long timer_rate_hz;
 	unsigned long tbu;
arch/arm/include/asm/io.h +75 -0

90 lines not on this page · raw message

arch/arm/lib/cache-cp15.c +44 -0

77 lines not on this page · raw message

common/cmd_boot.c +4 -0
index d3836fd..b2477e8 100644
@@ -50,6 +50,10 @@ static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 	printf ("## Starting application at 0x%08lX ...\n", addr);
 
+#if defined(__ARM__) && !defined(CONFIG_SYS_DCACHE_OFF)
+	cleanup_before_linux();
+#endif
+
 	/*
 	 * pass address parameter as argv[0] (aka command name),
 	 * and all remaining args

--
1.7.9.5

#2 lore raw

v2 cover arm: add Faraday A36x SoC platform support

From: Kuo-Jung Su <[email protected]>

These patches introduce Faraday A36x SoC platform support.

Here are some public documents for your reference.

http://www.faraday-tech.com/html/documentation/index.html

There is also a A369 QEMU emulator available at my github account:

    https://github.com/dantesu1218/qemu.git

Here is quick start for QEMU:

1. Download the QEMU source tree

    $ git clone -b qemu-1.3.0 https://github.com/dantesu1218/qemu.git

2. Build & Install the QEMU:

    $ ./configure --target-list=arm-softmmu
    $ make
    $ make install

3. Launch u-boot with QEMU:

    $ qemu-system-arm -M a369 -m 512M -nographic -kernel ~/u-boot-devel/u-boot

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.
- ftmac110: Remove debug codes.
- cache-cp15: Enable write buffer in write-through mode.

Kuo-Jung Su (12):
mtd: spi: winbond: add W25PXX support
net: ftgmac100: add MMU/D-cache support
net: add Faraday FTMAC110 10/100Mbps ethernet support
i2c: add Faraday FTI2C010 I2C controller support
spi: add Faraday FTSPI010 SPI controller support
mmc: add an alternative driver to Faraday FTSDC010
mtd: nand: add Faraday FTNANDC021 NAND controller support
mtd: spi: add FTSPI020 SPI Flash controller support
usb: ehci: add Faraday USB 2.0 EHCI controller support
usb: gadget: add Faraday FOTG210 USB gadget support
arm: add MMU/d-cache support for Faraday cores
arm: add Faraday A36x SoC platform support

 arch/arm/cpu/faraday/Makefile             |   57 ++
 arch/arm/cpu/faraday/a360/Makefile        |   49 ++
 arch/arm/cpu/faraday/a360/reset.c         |   26 +
 arch/arm/cpu/faraday/a369/Makefile        |   50 ++
 arch/arm/cpu/faraday/a369/cmd_fa606.c     |   75 +++
 arch/arm/cpu/faraday/a369/reset.c         |   26 +
 arch/arm/cpu/faraday/cmd_bootfa.c         |  132 +++++
 arch/arm/cpu/faraday/config.mk            |   33 ++
 arch/arm/cpu/faraday/cpu.c                |  238 ++++++++
 arch/arm/cpu/faraday/ftintc020.h          |   37 ++
 arch/arm/cpu/faraday/ftpwmtmr010.c        |  156 +++++
 arch/arm/cpu/faraday/ftpwmtmr010.h        |   41 ++
 arch/arm/cpu/faraday/fttmr010.c           |  159 +++++
 arch/arm/cpu/faraday/fwimage.h            |   38 ++
 arch/arm/cpu/faraday/fwimage2.h           |   70 +++
 arch/arm/cpu/faraday/interrupts.c         |  155 +++++
 arch/arm/cpu/faraday/start.S              |  523 ++++++++++++++++
 arch/arm/cpu/u-boot.lds                   |   11 +
 arch/arm/include/asm/arch-a360/hardware.h |   72 +++
 arch/arm/include/asm/arch-a369/hardware.h |   98 +++
 arch/arm/include/asm/dma-mapping.h        |   56 +-
 arch/arm/include/asm/global_data.h        |    4 +
 arch/arm/include/asm/io.h                 |   84 ++-
 arch/arm/include/asm/mach-types.h         |    1 +
 arch/arm/lib/cache-cp15.c                 |   42 ++
 board/faraday/a360evb/Makefile            |   49 ++
 board/faraday/a360evb/board.c             |   67 +++
 board/faraday/a360evb/clk.c               |   52 ++
 board/faraday/a360evb/config.mk           |   33 ++
 board/faraday/a360evb/lowlevel_init.S     |   33 ++
 board/faraday/a369evb/Makefile            |   49 ++
 board/faraday/a369evb/board.c             |  178 ++++++
 board/faraday/a369evb/clk.c               |   81 +++
 board/faraday/a369evb/config.mk           |   33 ++
 board/faraday/a369evb/lowlevel_init.S     |  136 +++++
 boards.cfg                                |    3 +
 common/cmd_boot.c                         |    4 +
 common/usb_hub.c                          |    5 +
 drivers/i2c/Makefile                      |    1 +
 drivers/i2c/fti2c010.c                    |  363 ++++++++++++
 drivers/i2c/fti2c010.h                    |   71 +++
 drivers/mmc/Makefile                      |    1 +
 drivers/mmc/ftsdc010_mci.c                |  373 ++++++++++++
 drivers/mtd/nand/Makefile                 |    1 +
 drivers/mtd/nand/ftnandc021.c             |  544 +++++++++++++++++
 drivers/mtd/nand/ftnandc021.h             |  132 +++++
 drivers/mtd/spi/Makefile                  |    4 +
 drivers/mtd/spi/ftspi020.c                |  691 +++++++++++++++++++++
 drivers/mtd/spi/ftspi020.h                |  109 ++++
 drivers/mtd/spi/winbond.c                 |   17 +-
 drivers/net/Makefile                      |    1 +
 drivers/net/ftgmac100.c                   |   70 ++-
 drivers/net/ftmac110.c                    |  452 ++++++++++++++
 drivers/net/ftmac110.h                    |  159 +++++
 drivers/spi/Makefile                      |    1 +
 drivers/spi/ftssp010_spi.c                |  337 +++++++++++
 drivers/spi/ftssp010_spi.h                |   86 +++
 drivers/usb/gadget/Makefile               |    1 +
 drivers/usb/gadget/fotg210.c              |  922 +++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h         |    8 +
 drivers/usb/host/Makefile                 |    1 +
 drivers/usb/host/ehci-faraday.c           |  139 +++++
 drivers/usb/host/ehci-hcd.c               |   11 +
 drivers/usb/host/ehci.h                   |    5 +
 include/common.h                          |   13 +
 include/configs/a360.h                    |  185 ++++++
 include/configs/a369.h                    |   41 ++
 include/configs/a369_defaults.h           |  295 +++++++++
 include/configs/a369_fa606te.h            |   32 +
 include/faraday/ftsdc010.h                |   16 +-
 include/faraday/fttmr010.h                |   17 +
 include/faraday/mmc.h                     |   16 +
 include/faraday/nand.h                    |   16 +
 include/netdev.h                          |    1 +
 include/usb/fotg210.h                     |   71 +++
 include/usb/fusbh200.h                    |   28 +
 76 files changed, 8158 insertions(+), 29 deletions(-)
 create mode 100644 arch/arm/cpu/faraday/Makefile
 create mode 100644 arch/arm/cpu/faraday/a360/Makefile
 create mode 100644 arch/arm/cpu/faraday/a360/reset.c
 create mode 100644 arch/arm/cpu/faraday/a369/Makefile
 create mode 100644 arch/arm/cpu/faraday/a369/cmd_fa606.c
 create mode 100644 arch/arm/cpu/faraday/a369/reset.c
 create mode 100644 arch/arm/cpu/faraday/cmd_bootfa.c
 create mode 100644 arch/arm/cpu/faraday/config.mk
 create mode 100644 arch/arm/cpu/faraday/cpu.c
 create mode 100644 arch/arm/cpu/faraday/ftintc020.h
 create mode 100644 arch/arm/cpu/faraday/ftpwmtmr010.c
 create mode 100644 arch/arm/cpu/faraday/ftpwmtmr010.h
 create mode 100644 arch/arm/cpu/faraday/fttmr010.c
 create mode 100644 arch/arm/cpu/faraday/fwimage.h
 create mode 100644 arch/arm/cpu/faraday/fwimage2.h
 create mode 100644 arch/arm/cpu/faraday/interrupts.c
 create mode 100644 arch/arm/cpu/faraday/start.S
 create mode 100644 arch/arm/include/asm/arch-a360/hardware.h
 create mode 100644 arch/arm/include/asm/arch-a369/hardware.h
 create mode 100644 board/faraday/a360evb/Makefile
 create mode 100644 board/faraday/a360evb/board.c
 create mode 100644 board/faraday/a360evb/clk.c
 create mode 100644 board/faraday/a360evb/config.mk
 create mode 100644 board/faraday/a360evb/lowlevel_init.S
 create mode 100644 board/faraday/a369evb/Makefile
 create mode 100644 board/faraday/a369evb/board.c
 create mode 100644 board/faraday/a369evb/clk.c
 create mode 100644 board/faraday/a369evb/config.mk
 create mode 100644 board/faraday/a369evb/lowlevel_init.S
 create mode 100644 drivers/i2c/fti2c010.c
 create mode 100644 drivers/i2c/fti2c010.h
 create mode 100644 drivers/mmc/ftsdc010_mci.c
 create mode 100644 drivers/mtd/nand/ftnandc021.c
 create mode 100644 drivers/mtd/nand/ftnandc021.h
 create mode 100644 drivers/mtd/spi/ftspi020.c
 create mode 100644 drivers/mtd/spi/ftspi020.h
 create mode 100644 drivers/net/ftmac110.c
 create mode 100644 drivers/net/ftmac110.h
 create mode 100644 drivers/spi/ftssp010_spi.c
 create mode 100644 drivers/spi/ftssp010_spi.h
 create mode 100644 drivers/usb/gadget/fotg210.c
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/configs/a360.h
 create mode 100644 include/configs/a369.h
 create mode 100644 include/configs/a369_defaults.h
 create mode 100644 include/configs/a369_fa606te.h
 create mode 100644 include/faraday/mmc.h
 create mode 100644 include/faraday/nand.h
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h

--
1.7.9.5

#3 lore raw

PATCH v2 1/12 mtd: spi: winbond: add W25PXX support

From: Kuo-Jung Su <[email protected]>

---
 drivers/mtd/spi/winbond.c |   17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
drivers/mtd/spi/winbond.c +16 -1
index 2716209..2a27837 100644
@@ -18,6 +18,21 @@ struct winbond_spi_flash_params {
 
 static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
 	{
+		.id			= 0x2014,
+		.nr_blocks		= 16,
+		.name			= "W25P80",
+	},
+	{
+		.id			= 0x2015,
+		.nr_blocks		= 32,
+		.name			= "W25P16",
+	},
+	{
+		.id			= 0x2016,
+		.nr_blocks		= 64,
+		.name			= "W25P32",
+	},
+	{
 		.id			= 0x3013,
 		.nr_blocks		= 8,
 		.name			= "W25X40",
@@ -104,7 +119,7 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
 	}
 
 	flash->page_size = 256;
-	flash->sector_size = 4096;
+	flash->sector_size = (idcode[1] == 0x20) ? 65536 : 4096;
 	flash->size = 4096 * 16 * params->nr_blocks;
 
 	return flash;
Signature · 1 line
1.7.9.5
#4 lore raw

v3 cover arm: add Faraday A36x SoC platform support

From: Kuo-Jung Su <[email protected]>

To: u-boot at lists.denx.de
CC: Albert Aribaud <[email protected]>

These patches introduce Faraday A36x SoC platform support.

Here are some public documents for your reference.

http://www.faraday-tech.com/html/documentation/index.html

There is also a A369 QEMU emulator available at my github account:

    https://github.com/dantesu1218/qemu.git

Here is quick start for QEMU:

1. Download the QEMU source tree

    $ git clone -b qemu-1.3.0 https://github.com/dantesu1218/qemu.git

2. Build & Install the QEMU:

    $ ./configure --target-list=arm-softmmu
    $ make
    $ make install

3. Launch u-boot with QEMU:

    $ qemu-system-arm -M a369 -m 512M -nographic -kernel ~/u-boot-devel/u-boot

Changes for v3:
- Coding Style cleanup.
There is still one warnning reported by checkpatch.pl, however it's too deep for me to fix it.
Here is the shapshot for it:
-----------------------------------------------------
WARNING: do not add new typedefs
#9735: FILE: include/lcd.h:258:
+typedef struct vidinfo {
-----------------------------------------------------
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.
- cmd_boot.c: Make it a separate stand-alone patch.
- ftspi020: Make it a separate stand-alone patch.
- dma-mapping.h: Have the global data ptr declared outside functions.
- dma-mapping.h: Add #if...#else...#endif to dma_free_coherent().
- MMU/D-Cache: Drop static non-cached region, now we use map_physmem()/unmap_physmem() for dynamic mappings.
- ftmac110: Make a correction to multi-line comment style
- ftmac110: Use random MAC address while having trouble to get one from environment variables.
- ftmac110: Add comments to timing control registers.
- ftnandc021: Re-write this driver with ECC enabled and correct column address handling for OOB read/write,
and fixing issused addressed by Scott.
- a36x_config: No more static global network configurations.
- a36x_config: Add a common file for the redundant configurations.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.
- ftmac110: Remove debug codes.
- cache-cp15: Enable write buffer in write-through mode.

Kuo-Jung Su (11):
arm: add MMU/D-Cache support for Faraday cores
net: ftgmac100: add MMU/D-cache support
net: add Faraday FTMAC110 10/100Mbps ethernet support
i2c: add Faraday FTI2C010 I2C controller support
spi: add Faraday FTSPI010 SPI controller support
mmc: update the Faraday FTSDC010 driver to fix performance issue
mtd: nand: add Faraday FTNANDC021 NAND controller support
usb: ehci: add Faraday USB 2.0 EHCI support
usb: gadget: add Faraday FOTG210 USB gadget support
video: add Faraday FTLCDC200 LCD controller support
arm: add Faraday A36x SoC platform support

 README                                    |    7 +
 arch/arm/cpu/faraday/Makefile             |   57 ++
 arch/arm/cpu/faraday/a360/Makefile        |   49 ++
 arch/arm/cpu/faraday/a369/Makefile        |   50 ++
 arch/arm/cpu/faraday/a369/cmd_fa606.c     |   72 +++
 arch/arm/cpu/faraday/cmd_bootfa.c         |  132 ++++
 arch/arm/cpu/faraday/config.mk            |   33 +
 arch/arm/cpu/faraday/cpu.c                |  238 +++++++
 arch/arm/cpu/faraday/ftintc020.h          |   37 ++
 arch/arm/cpu/faraday/ftpwmtmr010.c        |  156 +++++
 arch/arm/cpu/faraday/ftpwmtmr010.h        |   41 ++
 arch/arm/cpu/faraday/fttmr010.c           |  156 +++++
 arch/arm/cpu/faraday/fwimage.h            |   38 ++
 arch/arm/cpu/faraday/fwimage2.h           |   70 +++
 arch/arm/cpu/faraday/interrupts.c         |  151 +++++
 arch/arm/cpu/faraday/reset.c              |   38 ++
 arch/arm/cpu/faraday/start.S              |  523 ++++++++++++++++
 arch/arm/cpu/u-boot.lds                   |   11 +
 arch/arm/include/asm/arch-a360/hardware.h |   73 +++
 arch/arm/include/asm/arch-a360/pmu.h      |   39 ++
 arch/arm/include/asm/arch-a360/scu.h      |   27 +
 arch/arm/include/asm/arch-a369/hardware.h |   88 +++
 arch/arm/include/asm/arch-a369/scu.h      |   48 ++
 arch/arm/include/asm/dma-mapping.h        |   60 +-
 arch/arm/include/asm/global_data.h        |    4 +
 arch/arm/include/asm/io.h                 |  154 ++++-
 arch/arm/include/asm/mach-types.h         |    1 +
 arch/arm/include/asm/system.h             |    7 +-
 arch/arm/lib/cache-cp15.c                 |   30 +
 board/faraday/a360evb/Makefile            |   49 ++
 board/faraday/a360evb/board.c             |   65 ++
 board/faraday/a360evb/clk.c               |   57 ++
 board/faraday/a360evb/config.mk           |   33 +
 board/faraday/a360evb/lowlevel_init.S     |   33 +
 board/faraday/a369evb/Makefile            |   49 ++
 board/faraday/a369evb/board.c             |  188 ++++++
 board/faraday/a369evb/clk.c               |   72 +++
 board/faraday/a369evb/config.mk           |   33 +
 board/faraday/a369evb/lowlevel_init.S     |  136 ++++
 boards.cfg                                |    3 +
 common/usb_hub.c                          |    5 +
 drivers/i2c/Makefile                      |    1 +
 drivers/i2c/fti2c010.c                    |  360 +++++++++++
 drivers/i2c/fti2c010.h                    |   71 +++
 drivers/mmc/Makefile                      |    2 +-
 drivers/mmc/ftsdc010_esdhc.c              |  687 ---------------------
 drivers/mmc/ftsdc010_mci.c                |  375 ++++++++++++
 drivers/mtd/cfi_flash.c                   |    2 +-
 drivers/mtd/nand/Makefile                 |    1 +
 drivers/mtd/nand/ftnandc021.c             |  724 ++++++++++++++++++++++
 drivers/mtd/nand/ftnandc021.h             |  137 +++++
 drivers/net/Makefile                      |    1 +
 drivers/net/ftgmac100.c                   |   70 ++-
 drivers/net/ftmac110.c                    |  471 ++++++++++++++
 drivers/net/ftmac110.h                    |  126 ++++
 drivers/spi/Makefile                      |    1 +
 drivers/spi/ftssp010_spi.c                |  385 ++++++++++++
 drivers/spi/ftssp010_spi.h                |   86 +++
 drivers/usb/gadget/Makefile               |    1 +
 drivers/usb/gadget/fotg210.c              |  953 +++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h         |    8 +
 drivers/usb/host/Makefile                 |    1 +
 drivers/usb/host/ehci-faraday.c           |  122 ++++
 drivers/usb/host/ehci-hcd.c               |   11 +
 drivers/usb/host/ehci.h                   |    5 +
 drivers/video/Makefile                    |    1 +
 drivers/video/ftlcdc200.c                 |  144 +++++
 drivers/video/ftlcdc200_panel.c           |  210 +++++++
 include/common.h                          |   13 +
 include/configs/a360.h                    |   63 ++
 include/configs/a369-common.h             |   74 +++
 include/configs/a369.h                    |   33 +
 include/configs/a369_fa606te.h            |   26 +
 include/configs/a36x-common.h             |  303 +++++++++
 include/faraday/ftgpio010.h               |   25 +
 include/faraday/ftlcdc200.h               |  179 ++++++
 include/faraday/ftsdc010.h                |   16 +-
 include/faraday/fttmr010.h                |   17 +
 include/faraday/mmc.h                     |   16 +
 include/faraday/nand.h                    |   34 +
 include/lcd.h                             |   33 +
 include/netdev.h                          |    1 +
 include/usb/fotg210.h                     |   71 +++
 include/usb/fusbh200.h                    |   28 +
 84 files changed, 8275 insertions(+), 726 deletions(-)
 create mode 100644 arch/arm/cpu/faraday/Makefile
 create mode 100644 arch/arm/cpu/faraday/a360/Makefile
 create mode 100644 arch/arm/cpu/faraday/a369/Makefile
 create mode 100644 arch/arm/cpu/faraday/a369/cmd_fa606.c
 create mode 100644 arch/arm/cpu/faraday/cmd_bootfa.c
 create mode 100644 arch/arm/cpu/faraday/config.mk
 create mode 100644 arch/arm/cpu/faraday/cpu.c
 create mode 100644 arch/arm/cpu/faraday/ftintc020.h
 create mode 100644 arch/arm/cpu/faraday/ftpwmtmr010.c
 create mode 100644 arch/arm/cpu/faraday/ftpwmtmr010.h
 create mode 100644 arch/arm/cpu/faraday/fttmr010.c
 create mode 100644 arch/arm/cpu/faraday/fwimage.h
 create mode 100644 arch/arm/cpu/faraday/fwimage2.h
 create mode 100644 arch/arm/cpu/faraday/interrupts.c
 create mode 100644 arch/arm/cpu/faraday/reset.c
 create mode 100644 arch/arm/cpu/faraday/start.S
 create mode 100644 arch/arm/include/asm/arch-a360/hardware.h
 create mode 100644 arch/arm/include/asm/arch-a360/pmu.h
 create mode 100644 arch/arm/include/asm/arch-a360/scu.h
 create mode 100644 arch/arm/include/asm/arch-a369/hardware.h
 create mode 100644 arch/arm/include/asm/arch-a369/scu.h
 create mode 100644 board/faraday/a360evb/Makefile
 create mode 100644 board/faraday/a360evb/board.c
 create mode 100644 board/faraday/a360evb/clk.c
 create mode 100644 board/faraday/a360evb/config.mk
 create mode 100644 board/faraday/a360evb/lowlevel_init.S
 create mode 100644 board/faraday/a369evb/Makefile
 create mode 100644 board/faraday/a369evb/board.c
 create mode 100644 board/faraday/a369evb/clk.c
 create mode 100644 board/faraday/a369evb/config.mk
 create mode 100644 board/faraday/a369evb/lowlevel_init.S
 create mode 100644 drivers/i2c/fti2c010.c
 create mode 100644 drivers/i2c/fti2c010.h
 delete mode 100644 drivers/mmc/ftsdc010_esdhc.c
 create mode 100644 drivers/mmc/ftsdc010_mci.c
 create mode 100644 drivers/mtd/nand/ftnandc021.c
 create mode 100644 drivers/mtd/nand/ftnandc021.h
 create mode 100644 drivers/net/ftmac110.c
 create mode 100644 drivers/net/ftmac110.h
 create mode 100644 drivers/spi/ftssp010_spi.c
 create mode 100644 drivers/spi/ftssp010_spi.h
 create mode 100644 drivers/usb/gadget/fotg210.c
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 drivers/video/ftlcdc200.c
 create mode 100644 drivers/video/ftlcdc200_panel.c
 create mode 100644 include/configs/a360.h
 create mode 100644 include/configs/a369-common.h
 create mode 100644 include/configs/a369.h
 create mode 100644 include/configs/a369_fa606te.h
 create mode 100644 include/configs/a36x-common.h
 create mode 100644 include/faraday/ftgpio010.h
 create mode 100644 include/faraday/ftlcdc200.h
 create mode 100644 include/faraday/mmc.h
 create mode 100644 include/faraday/nand.h
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h

--
1.7.9.5

#5 lore raw

PATCH v3 1/11 arm: add MMU/D-Cache support for Faraday cores

From: Kuo-Jung Su <[email protected]>

This patch updates the map_physmem()/unmap_physmem(), and use them to implement dma_alloc_coherent(), dma_free_coherent().

It uses 1MB section for each mapping, and thus waste lots of address space, however this should still be good enough for tiny systems (i.e. u-boot).

CC Albert Aribaud <[email protected]>
---
 arch/arm/include/asm/dma-mapping.h |   60 +++++++++++++-
 arch/arm/include/asm/global_data.h |    4 +
 arch/arm/include/asm/io.h          |  154 ++++++++++++++++++++++++++++++++++--
 arch/arm/include/asm/system.h      |    7 +-
 arch/arm/lib/cache-cp15.c          |   30 +++++++
 drivers/mtd/cfi_flash.c            |    2 +-
 6 files changed, 243 insertions(+), 14 deletions(-)
arch/arm/include/asm/dma-mapping.h +58 -2
index 5bbb0a0..9b56d79 100644
@@ -3,6 +3,9 @@
  * Stelian Pop <[email protected]>
  * Lead Tech Design <www.leadtechdesign.com>
  *
+ * (C) Copyright 2010
+ * Dante Su <[email protected]>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -24,22 +27,75 @@
 #ifndef __ASM_ARM_DMA_MAPPING_H
 #define __ASM_ARM_DMA_MAPPING_H
 
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+#include <asm/u-boot.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+#endif /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+
 enum dma_data_direction {
 	DMA_BIDIRECTIONAL	= 0,
 	DMA_TO_DEVICE		= 1,
 	DMA_FROM_DEVICE		= 2,
 };
 
-static void *dma_alloc_coherent(size_t len, unsigned long *handle)
+static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
 {
-	*handle = (unsigned long)malloc(len);
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+	void *map, *va = memalign(ARCH_DMA_MINALIGN, len);
+
+	if (va && gd->arch.cpu_mmu) {
+		invalidate_dcache_range((ulong)va, (ulong)va + len);
+		map = map_physmem((phys_addr_t)va, len, MAP_NOCACHE);
+		if (!map)
+			free(va);
+		va = map;
+	}
+
+	if (handle)
+		*handle = virt_to_phys(va);
+
+	return va;
+#else  /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+	*handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len);
 	return (void *)*handle;
+#endif /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+}
+
+static inline void dma_free_coherent(void *vaddr, ulong len)
+{
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+	unmap_physmem(vaddr, len);
+	vaddr = (void *)virt_to_phys(vaddr);
+#endif
+	free(vaddr);
 }
 
 static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
 					   enum dma_data_direction dir)
 {
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+	if (gd->arch.cpu_mmu) {
+		switch (dir) {
+		case DMA_BIDIRECTIONAL:
+		case DMA_TO_DEVICE:
+			flush_dcache_range((ulong)vaddr,
+				(ulong)vaddr + len);
+			break;
+
+		case DMA_FROM_DEVICE:
+			invalidate_dcache_range((ulong)vaddr,
+				(ulong)vaddr + len);
+			break;
+		}
+	}
+	return virt_to_phys((void *)vaddr);
+#else  /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
 	return (unsigned long)vaddr;
+#endif /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
 }
 
 static inline void dma_unmap_single(volatile void *vaddr, size_t len,
arch/arm/include/asm/global_data.h +4 -0
index 37ac0da..bd18ff7 100644
@@ -38,6 +38,10 @@ struct arch_global_data {
 	unsigned long	pllb_rate_hz;
 	unsigned long	at91_pllb_usb_init;
 #endif
+#ifdef CONFIG_FARADAY
+	unsigned long   cpu_id;
+	unsigned long   cpu_mmu;	/* has mmu */
+#endif
 	/* "static data" needed by most of timer.c on ARM platforms */
 	unsigned long timer_rate_hz;
 	unsigned long tbu;
arch/arm/include/asm/io.h +146 -8

188 lines not on this page · raw message

arch/arm/include/asm/system.h +4 -3
index 760345f..050b707 100644
@@ -97,9 +97,10 @@ static inline void set_dacr(unsigned int val)
 
 /* options available for data cache on each page */
 enum dcache_option {
-	DCACHE_OFF = 0x12,
-	DCACHE_WRITETHROUGH = 0x1a,
-	DCACHE_WRITEBACK = 0x1e,
+	DCACHE_OFF = 0x12,          /* non-cached + non-buffered */
+	DCACHE_WRITECOMBINE = 0x16, /* non-cached + buffered */
+	DCACHE_WRITETHROUGH = 0x1a, /* cached + non-buffered */
+	DCACHE_WRITEBACK = 0x1e,    /* cached + buffered */
 };
 
 /* Size of an MMU section */
arch/arm/lib/cache-cp15.c +30 -0
index 4abe1cf..ea29e83 100644
@@ -1,6 +1,8 @@
 /*
  * (C) Copyright 2002
  * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ * (C) Copyright 2010
+ * Dante Su <[email protected]>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -98,6 +100,24 @@ __weak void dram_bank_mmu_setup(int bank)
 		set_section_dcache(i, DCACHE_WRITEBACK);
 #endif
 	}
+
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+
+# ifdef CONFIG_USE_IRQ
+	/* make sure the exception table is at 0x00000000 */
+	if (!bank && bd->bi_dram[bank].start) {
+		u32 pa = bd->bi_dram[bank].start;
+		u32 *page_table = (u32 *)gd->arch.tlb_addr;
+
+#  ifdef CONFIG_SYS_ARM_CACHE_WRITETHROUGH
+		page_table[0] = pa | (3 << 10) | DCACHE_WRITETHROUGH;
+#  else
+		page_table[0] = pa | (3 << 10) | DCACHE_WRITEBACK;
+#  endif
+	}
+# endif /* # ifdef CONFIG_USE_IRQ */
+
+#endif /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
 }
 
 /* to activate the MMU we need to set up virtual memory: use 1M areas */
@@ -126,6 +146,10 @@ static inline void mmu_setup(void)
 
 	/* and enable the mmu */
 	reg = get_cr();	/* get control reg. */
+#ifdef CONFIG_FARADAY
+	reg |= CR_W;	/* enable write buffer */
+	reg |= CR_Z;	/* enable branch prediction */
+#endif
 	cp_delay();
 	set_cr(reg | CR_M);
 }
@@ -140,9 +164,15 @@ static void cache_enable(uint32_t cache_bit)
 {
 	uint32_t reg;
 
+#ifdef CONFIG_FARADAY
+	if (!gd->arch.cpu_mmu && (cache_bit == CR_C))
+		return;
+#endif
+
 	/* The data cache is not active unless the mmu is enabled too */
 	if ((cache_bit == CR_C) && !mmu_enabled())
 		mmu_setup();
+
 	reg = get_cr();	/* get control reg. */
 	cp_delay();
 	set_cr(reg | cache_bit);
drivers/mtd/cfi_flash.c +1 -1
index 22d8440..49bdcff 100644
@@ -1818,7 +1818,7 @@ static int flash_detect_legacy(phys_addr_t base, int banknum)
 					break;
 				else
 					unmap_physmem((void *)info->start[0],
-						      MAP_NOCACHE);
+						      info->portwidth);
 			}
 		}
 
Signature · 1 line
1.7.9.5
#6 lore raw

v4 cover arm: add Faraday A36x SoC platform support

From: Kuo-Jung Su <[email protected]>

These patches introduce Faraday A36x SoC platform support.

Here are some public documents for your reference.

http://www.faraday-tech.com/html/documentation/index.html

There is also a A369 QEMU emulator available at my github account:

    https://github.com/dantesu1218/qemu.git

Here is quick start for QEMU:

1. Download the QEMU source tree

    $ git clone -b qemu-1.3.0 https://github.com/dantesu1218/qemu.git

2. Build & Install the QEMU:

    $ ./configure --target-list=arm-softmmu
    $ make
    $ make install

3. Launch u-boot with QEMU:

    $ qemu-system-arm -M a369 -m 512M -nographic -kernel ~/u-boot-devel/u-boot

Changes for v4:
- Coding Style cleanup.
- Break down the patch series:
- Patches without hard dependency to this series are now seperate patches.
- Split up the patch into more logical changesets (i.e. interrupt & timers are now split up)
- Drop the faraday/nand.h to remove dependency to ftnandc021
- Drop the faraday/mmc.h to remove dependency to ftsdc010
- Add change logs to each part of the patch series to make patchwork be able to grab comments.

Changes for v3:
- Coding Style cleanup.
There is still one warnning reported by checkpatch.pl, however it's too deep for me to fix it.
Here is the shapshot for it:
-----------------------------------------------------
WARNING: do not add new typedefs
#9735: FILE: include/lcd.h:258:
+typedef struct vidinfo {
-----------------------------------------------------
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.
- cmd_boot.c: Make it a separate stand-alone patch.
- ftspi020: Make it a separate stand-alone patch.
- dma-mapping.h: Have the global data ptr declared outside functions.
- dma-mapping.h: Add #if...#else...#endif to dma_free_coherent().
- MMU/D-Cache: Drop static non-cached region, now we use map_physmem()/unmap_physmem() for dynamic mappings.
- ftmac110: Make a correction to multi-line comment style
- ftmac110: Use random MAC address while having trouble to get one from environment variables.
- ftmac110: Add comments to timing control registers.
- ftnandc021: Re-write this driver with ECC enabled and correct column address handling for OOB read/write,
and fixing issused addressed by Scott.
- a36x_config: No more static global network configurations.
- a36x_config: Add a common file for the redundant configurations.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.
- ftmac110: Remove debug codes.
- cache-cp15: Enable write buffer in write-through mode.

Kuo-Jung Su (7):
arm: add MMU/D-Cache support for Faraday cores
arm: add Faraday common utilities
arm: add Faraday FTINTC020 interrupt controller support
arm: add Faraday FTTMR010 timer support
arm: add Faraday FTPWMTMR010 timer support
arm: add Faraday firmware image utility
arm: add Faraday A36x SoC platform support

 arch/arm/cpu/faraday/Makefile             |   57 ++++
 arch/arm/cpu/faraday/a360/Makefile        |   49 +++
 arch/arm/cpu/faraday/a369/Makefile        |   50 +++
 arch/arm/cpu/faraday/a369/cmd_fa606.c     |   77 +++++
 arch/arm/cpu/faraday/cmd_bootfa.c         |  132 ++++++++
 arch/arm/cpu/faraday/config.mk            |   33 ++
 arch/arm/cpu/faraday/cpu.c                |  280 +++++++++++++++
 arch/arm/cpu/faraday/ftpwmtmr010.c        |  160 +++++++++
 arch/arm/cpu/faraday/fttmr010.c           |  160 +++++++++
 arch/arm/cpu/faraday/fwimage.h            |   38 +++
 arch/arm/cpu/faraday/fwimage2.h           |   70 ++++
 arch/arm/cpu/faraday/interrupts.c         |  151 +++++++++
 arch/arm/cpu/faraday/start.S              |  523 +++++++++++++++++++++++++++++
 arch/arm/cpu/u-boot.lds                   |   11 +
 arch/arm/include/asm/arch-a360/hardware.h |   73 ++++
 arch/arm/include/asm/arch-a360/pmu.h      |   39 +++
 arch/arm/include/asm/arch-a360/scu.h      |   27 ++
 arch/arm/include/asm/arch-a369/ahbc.h     |   23 ++
 arch/arm/include/asm/arch-a369/hardware.h |   88 +++++
 arch/arm/include/asm/arch-a369/scu.h      |  213 ++++++++++++
 arch/arm/include/asm/dma-mapping.h        |   61 +++-
 arch/arm/include/asm/global_data.h        |    4 +
 arch/arm/include/asm/io.h                 |  160 ++++++++-
 arch/arm/include/asm/mach-types.h         |    1 +
 arch/arm/include/asm/system.h             |    7 +-
 arch/arm/lib/cache-cp15.c                 |   30 ++
 board/faraday/a360evb/Makefile            |   49 +++
 board/faraday/a360evb/board.c             |   73 ++++
 board/faraday/a360evb/clk.c               |   57 ++++
 board/faraday/a360evb/config.mk           |   33 ++
 board/faraday/a360evb/lowlevel_init.S     |   33 ++
 board/faraday/a369evb/Makefile            |   49 +++
 board/faraday/a369evb/board.c             |  184 ++++++++++
 board/faraday/a369evb/clk.c               |   80 +++++
 board/faraday/a369evb/config.mk           |   33 ++
 board/faraday/a369evb/lowlevel_init.S     |  136 ++++++++
 boards.cfg                                |    3 +
 drivers/mtd/cfi_flash.c                   |    2 +-
 include/common.h                          |   13 +
 include/configs/a360.h                    |   63 ++++
 include/configs/a369-common.h             |   74 ++++
 include/configs/a369.h                    |   33 ++
 include/configs/a369_fa606te.h            |   29 ++
 include/configs/faraday-common.h          |  304 +++++++++++++++++
 include/faraday/ftintc020.h               |   37 ++
 include/faraday/ftpwmtmr010.h             |   41 +++
 include/faraday/ftsmc020.h                |    1 +
 include/faraday/fttmr010.h                |   17 +
 48 files changed, 3847 insertions(+), 14 deletions(-)
 create mode 100644 arch/arm/cpu/faraday/Makefile
 create mode 100644 arch/arm/cpu/faraday/a360/Makefile
 create mode 100644 arch/arm/cpu/faraday/a369/Makefile
 create mode 100644 arch/arm/cpu/faraday/a369/cmd_fa606.c
 create mode 100644 arch/arm/cpu/faraday/cmd_bootfa.c
 create mode 100644 arch/arm/cpu/faraday/config.mk
 create mode 100644 arch/arm/cpu/faraday/cpu.c
 create mode 100644 arch/arm/cpu/faraday/ftpwmtmr010.c
 create mode 100644 arch/arm/cpu/faraday/fttmr010.c
 create mode 100644 arch/arm/cpu/faraday/fwimage.h
 create mode 100644 arch/arm/cpu/faraday/fwimage2.h
 create mode 100644 arch/arm/cpu/faraday/interrupts.c
 create mode 100644 arch/arm/cpu/faraday/start.S
 create mode 100644 arch/arm/include/asm/arch-a360/hardware.h
 create mode 100644 arch/arm/include/asm/arch-a360/pmu.h
 create mode 100644 arch/arm/include/asm/arch-a360/scu.h
 create mode 100644 arch/arm/include/asm/arch-a369/ahbc.h
 create mode 100644 arch/arm/include/asm/arch-a369/hardware.h
 create mode 100644 arch/arm/include/asm/arch-a369/scu.h
 create mode 100644 board/faraday/a360evb/Makefile
 create mode 100644 board/faraday/a360evb/board.c
 create mode 100644 board/faraday/a360evb/clk.c
 create mode 100644 board/faraday/a360evb/config.mk
 create mode 100644 board/faraday/a360evb/lowlevel_init.S
 create mode 100644 board/faraday/a369evb/Makefile
 create mode 100644 board/faraday/a369evb/board.c
 create mode 100644 board/faraday/a369evb/clk.c
 create mode 100644 board/faraday/a369evb/config.mk
 create mode 100644 board/faraday/a369evb/lowlevel_init.S
 create mode 100644 include/configs/a360.h
 create mode 100644 include/configs/a369-common.h
 create mode 100644 include/configs/a369.h
 create mode 100644 include/configs/a369_fa606te.h
 create mode 100644 include/configs/faraday-common.h
 create mode 100644 include/faraday/ftintc020.h
 create mode 100644 include/faraday/ftpwmtmr010.h

--
1.7.9.5

#7 lore raw

PATCH v4 1/7 arm: add MMU/D-Cache support for Faraday cores

From: Kuo-Jung Su <[email protected]>

This patch updates the map_physmem()/unmap_physmem(), and use them to implement dma_alloc_coherent(), dma_free_coherent().

It uses 1MB section for each mapping, and thus waste lots of address space, however this should still be good enough for tiny systems (i.e. u-boot).

CC Albert Aribaud <[email protected]>

---
Changes for v4:
- Coding Style cleanup.

Changes for v3:
- Coding Style cleanup.
- Always insert a blank line between declarations and code.
- dma-mapping.h: Have the global data ptr declared outside functions.
- dma-mapping.h: Add #if...#else...#endif to dma_free_coherent().
- Drop static non-cached region, now we use map_physmem()/unmap_physmem() for dynamic mappings.

Changes for v2:
- Coding Style cleanup.
- cache-cp15: Enable write buffer in write-through mode.

 arch/arm/include/asm/dma-mapping.h |   61 +++++++++++++-
 arch/arm/include/asm/global_data.h |    4 +
 arch/arm/include/asm/io.h          |  160 ++++++++++++++++++++++++++++++++++--
 arch/arm/include/asm/system.h      |    7 +-
 arch/arm/lib/cache-cp15.c          |   30 +++++++
 drivers/mtd/cfi_flash.c            |    2 +-
 6 files changed, 250 insertions(+), 14 deletions(-)
arch/arm/include/asm/dma-mapping.h +59 -2
index 5bbb0a0..5a13af5 100644
@@ -3,6 +3,9 @@
  * Stelian Pop <[email protected]>
  * Lead Tech Design <www.leadtechdesign.com>
  *
+ * (C) Copyright 2010
+ * Dante Su <[email protected]>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -24,22 +27,76 @@
 #ifndef __ASM_ARM_DMA_MAPPING_H
 #define __ASM_ARM_DMA_MAPPING_H
 
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+#include <asm/u-boot.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+#endif /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+
 enum dma_data_direction {
 	DMA_BIDIRECTIONAL	= 0,
 	DMA_TO_DEVICE		= 1,
 	DMA_FROM_DEVICE		= 2,
 };
 
-static void *dma_alloc_coherent(size_t len, unsigned long *handle)
+static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
 {
-	*handle = (unsigned long)malloc(len);
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+	void *map, *va = memalign(ARCH_DMA_MINALIGN, len);
+
+	if (va && gd->arch.cpu_mmu) {
+		invalidate_dcache_range((ulong)va, (ulong)va + len);
+		map = map_physmem((phys_addr_t)va, len, MAP_NOCACHE);
+		if (!map)
+			free(va);
+		va = map;
+	}
+
+	if (handle)
+		*handle = virt_to_phys(va);
+
+	return va;
+#else  /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+	*handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len);
 	return (void *)*handle;
+#endif /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+}
+
+static inline void dma_free_coherent(void *vaddr, ulong len)
+{
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+	void *tmp = (void *)virt_to_phys(vaddr);
+	unmap_physmem(vaddr, len);
+	vaddr = tmp;
+#endif
+	free(vaddr);
 }
 
 static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
 					   enum dma_data_direction dir)
 {
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+	if (gd->arch.cpu_mmu) {
+		switch (dir) {
+		case DMA_BIDIRECTIONAL:
+		case DMA_TO_DEVICE:
+			flush_dcache_range((ulong)vaddr,
+				(ulong)vaddr + len);
+			break;
+
+		case DMA_FROM_DEVICE:
+			invalidate_dcache_range((ulong)vaddr,
+				(ulong)vaddr + len);
+			break;
+		}
+	}
+	return virt_to_phys((void *)vaddr);
+#else  /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
 	return (unsigned long)vaddr;
+#endif /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
 }
 
 static inline void dma_unmap_single(volatile void *vaddr, size_t len,
arch/arm/include/asm/global_data.h +4 -0
index 37ac0da..bd18ff7 100644
@@ -38,6 +38,10 @@ struct arch_global_data {
 	unsigned long	pllb_rate_hz;
 	unsigned long	at91_pllb_usb_init;
 #endif
+#ifdef CONFIG_FARADAY
+	unsigned long   cpu_id;
+	unsigned long   cpu_mmu;	/* has mmu */
+#endif
 	/* "static data" needed by most of timer.c on ARM platforms */
 	unsigned long timer_rate_hz;
 	unsigned long tbu;
arch/arm/include/asm/io.h +152 -8

194 lines not on this page · raw message

arch/arm/include/asm/system.h +4 -3
index 760345f..050b707 100644
@@ -97,9 +97,10 @@ static inline void set_dacr(unsigned int val)
 
 /* options available for data cache on each page */
 enum dcache_option {
-	DCACHE_OFF = 0x12,
-	DCACHE_WRITETHROUGH = 0x1a,
-	DCACHE_WRITEBACK = 0x1e,
+	DCACHE_OFF = 0x12,          /* non-cached + non-buffered */
+	DCACHE_WRITECOMBINE = 0x16, /* non-cached + buffered */
+	DCACHE_WRITETHROUGH = 0x1a, /* cached + non-buffered */
+	DCACHE_WRITEBACK = 0x1e,    /* cached + buffered */
 };
 
 /* Size of an MMU section */
arch/arm/lib/cache-cp15.c +30 -0
index 4abe1cf..ea29e83 100644
@@ -1,6 +1,8 @@
 /*
  * (C) Copyright 2002
  * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ * (C) Copyright 2010
+ * Dante Su <[email protected]>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -98,6 +100,24 @@ __weak void dram_bank_mmu_setup(int bank)
 		set_section_dcache(i, DCACHE_WRITEBACK);
 #endif
 	}
+
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+
+# ifdef CONFIG_USE_IRQ
+	/* make sure the exception table is at 0x00000000 */
+	if (!bank && bd->bi_dram[bank].start) {
+		u32 pa = bd->bi_dram[bank].start;
+		u32 *page_table = (u32 *)gd->arch.tlb_addr;
+
+#  ifdef CONFIG_SYS_ARM_CACHE_WRITETHROUGH
+		page_table[0] = pa | (3 << 10) | DCACHE_WRITETHROUGH;
+#  else
+		page_table[0] = pa | (3 << 10) | DCACHE_WRITEBACK;
+#  endif
+	}
+# endif /* # ifdef CONFIG_USE_IRQ */
+
+#endif /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
 }
 
 /* to activate the MMU we need to set up virtual memory: use 1M areas */
@@ -126,6 +146,10 @@ static inline void mmu_setup(void)
 
 	/* and enable the mmu */
 	reg = get_cr();	/* get control reg. */
+#ifdef CONFIG_FARADAY
+	reg |= CR_W;	/* enable write buffer */
+	reg |= CR_Z;	/* enable branch prediction */
+#endif
 	cp_delay();
 	set_cr(reg | CR_M);
 }
@@ -140,9 +164,15 @@ static void cache_enable(uint32_t cache_bit)
 {
 	uint32_t reg;
 
+#ifdef CONFIG_FARADAY
+	if (!gd->arch.cpu_mmu && (cache_bit == CR_C))
+		return;
+#endif
+
 	/* The data cache is not active unless the mmu is enabled too */
 	if ((cache_bit == CR_C) && !mmu_enabled())
 		mmu_setup();
+
 	reg = get_cr();	/* get control reg. */
 	cp_delay();
 	set_cr(reg | cache_bit);
drivers/mtd/cfi_flash.c +1 -1
index 22d8440..49bdcff 100644
@@ -1818,7 +1818,7 @@ static int flash_detect_legacy(phys_addr_t base, int banknum)
 					break;
 				else
 					unmap_physmem((void *)info->start[0],
-						      MAP_NOCACHE);
+						      info->portwidth);
 			}
 		}
 

--
1.7.9.5

#8 lore raw

PATCH v4 1/7 arm: add MMU/D-Cache support for Faraday cores

Hi Kuo-Jung,

arch/arm/include/asm/dma-mapping.h line 7

Quoted 10 lines · Kuo-Jung Su
arch/arm/include/asm/dma-mapping.h +2 -0
index 5bbb0a0..5a13af5 100644
@@ -3,6 +3,9 @@
  * Stelian Pop <[email protected]>
  * Lead Tech Design <www.leadtechdesign.com>
  *
+ * (C) Copyright 2010
+ * Dante Su <[email protected]>

Fix Copyright notices (dates) throughout the patch (and series as needed).

Quoted 34 lines
arch/arm/include/asm/dma-mapping.h +18 -2
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -24,22 +27,76 @@
 #ifndef __ASM_ARM_DMA_MAPPING_H
 #define __ASM_ARM_DMA_MAPPING_H
 
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+#include <asm/u-boot.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+#endif /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+
 enum dma_data_direction {
 	DMA_BIDIRECTIONAL	= 0,
 	DMA_TO_DEVICE		= 1,
 	DMA_FROM_DEVICE		= 2,
 };
 
-static void *dma_alloc_coherent(size_t len, unsigned long *handle)
+static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
 {
-	*handle = (unsigned long)malloc(len);
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+	void *map, *va = memalign(ARCH_DMA_MINALIGN, len);
+
+	if (va && gd->arch.cpu_mmu) {
+		invalidate_dcache_range((ulong)va, (ulong)va + len);
+		map = map_physmem((phys_addr_t)va, len, MAP_NOCACHE);
+		if (!map)
+			free(va);

arch/arm/include/asm/dma-mapping.h line 64

Quoted 10 lines
arch/arm/include/asm/dma-mapping.h +9 -0
+		va = map;
+	}
+
+	if (handle)
+		*handle = virt_to_phys(va);
+
+	return va;
+#else  /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+	*handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len);
 	return (void *)*handle;

This is not identical to what the code was before the patch. Why the difference?

Quoted 1 line

1.7.9.5

Amicalement,

Signature · 1 line
Albert.
#9 lore raw

PATCH v4 1/7 arm: add MMU/D-Cache support for Faraday cores

2013/6/11 Albert ARIBAUD <[email protected]>:

Quoted 5 lines

Hi Kuo-Jung,

On Tue, 7 May 2013 14:25:07 +0800, Kuo-Jung Su <[email protected]> wrote:

Quoted 14 lines

arch/arm/include/asm/dma-mapping.h line 7

Quoted 10 lines
arch/arm/include/asm/dma-mapping.h +2 -0
index 5bbb0a0..5a13af5 100644
@@ -3,6 +3,9 @@
  * Stelian Pop <[email protected]>
  * Lead Tech Design <www.leadtechdesign.com>
  *
+ * (C) Copyright 2010
+ * Dante Su <[email protected]>

Fix Copyright notices (dates) throughout the patch (and series as needed).

Got it, thanks.

Quoted 39 lines
Quoted 39 lines
arch/arm/include/asm/dma-mapping.h +23 -2
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -24,22 +27,76 @@
 #ifndef __ASM_ARM_DMA_MAPPING_H
 #define __ASM_ARM_DMA_MAPPING_H
 
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+#include <asm/u-boot.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+#endif /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+
 enum dma_data_direction {
      DMA_BIDIRECTIONAL       = 0,
      DMA_TO_DEVICE           = 1,
      DMA_FROM_DEVICE         = 2,
 };
 
-static void *dma_alloc_coherent(size_t len, unsigned long *handle)
+static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
 {
-     *handle = (unsigned long)malloc(len);
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+     void *map, *va = memalign(ARCH_DMA_MINALIGN, len);
+
+     if (va && gd->arch.cpu_mmu) {
+             invalidate_dcache_range((ulong)va, (ulong)va + len);
+             map = map_physmem((phys_addr_t)va, len, MAP_NOCACHE);
+             if (!map)
+                     free(va);
+             va = map;
+     }
+
+     if (handle)
+             *handle = virt_to_phys(va);
Quoted 9 lines

arch/arm/include/asm/dma-mapping.h line 64

Quoted 5 lines
arch/arm/include/asm/dma-mapping.h +4 -0
+
+     return va;
+#else  /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+     *handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len);
      return (void *)*handle;

This is not identical to what the code was before the patch. Why the difference?

Yes, it's not identical to what the code was.

It was:

    *handle = (unsigned long)malloc(len);
But I think it should be
    *handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len);

Because even though the MMU/D-cache is off, some DMA engines still requires strict address alignment.

For example, the Faraday FTMAC110 & FTGMAC100 ether-net controllers expect the descriptors are always aligned to 16-bytes boundary.

--
Best wishes,
Kuo-Jung Su

#10 lore raw

PATCH v4 1/7 arm: add MMU/D-Cache support for Faraday cores

Hi Kuo-Jung,

Quoted 79 lines · Kuo-Jung Su

2013/6/11 Albert ARIBAUD <[email protected]>:

Quoted 5 lines

Hi Kuo-Jung,

On Tue, 7 May 2013 14:25:07 +0800, Kuo-Jung Su <[email protected]> wrote:

Quoted 14 lines

arch/arm/include/asm/dma-mapping.h line 7

Quoted 10 lines
arch/arm/include/asm/dma-mapping.h +2 -0
index 5bbb0a0..5a13af5 100644
@@ -3,6 +3,9 @@
  * Stelian Pop <[email protected]>
  * Lead Tech Design <www.leadtechdesign.com>
  *
+ * (C) Copyright 2010
+ * Dante Su <[email protected]>

Fix Copyright notices (dates) throughout the patch (and series as needed).

Got it, thanks.

Quoted 39 lines
Quoted 39 lines
arch/arm/include/asm/dma-mapping.h +23 -2
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -24,22 +27,76 @@
 #ifndef __ASM_ARM_DMA_MAPPING_H
 #define __ASM_ARM_DMA_MAPPING_H
 
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+#include <asm/u-boot.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+#endif /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+
 enum dma_data_direction {
      DMA_BIDIRECTIONAL       = 0,
      DMA_TO_DEVICE           = 1,
      DMA_FROM_DEVICE         = 2,
 };
 
-static void *dma_alloc_coherent(size_t len, unsigned long *handle)
+static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
 {
-     *handle = (unsigned long)malloc(len);
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+     void *map, *va = memalign(ARCH_DMA_MINALIGN, len);
+
+     if (va && gd->arch.cpu_mmu) {
+             invalidate_dcache_range((ulong)va, (ulong)va + len);
+             map = map_physmem((phys_addr_t)va, len, MAP_NOCACHE);
+             if (!map)
+                     free(va);
+             va = map;
+     }
+
+     if (handle)
+             *handle = virt_to_phys(va);
Quoted 9 lines

arch/arm/include/asm/dma-mapping.h line 64

Quoted 5 lines
arch/arm/include/asm/dma-mapping.h +4 -0
+
+     return va;
+#else  /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+     *handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len);
      return (void *)*handle;

This is not identical to what the code was before the patch. Why the difference?

Yes, it's not identical to what the code was.

It was:

    *handle = (unsigned long)malloc(len);
But I think it should be
    *handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len);
Quoted 5 lines

Because even though the MMU/D-cache is off, some DMA engines still requires strict address alignment.

For example, the Faraday FTMAC110 & FTGMAC100 ether-net controllers expect the descriptors are always aligned to 16-bytes boundary.

Unless there exists an actual case where the current form causes an issue, please leave it unchanged. And if it is needed, then please make it a separate patch.

Quoted 2 lines

Best wishes,
Kuo-Jung Su

Amicalement,

Signature · 1 line
Albert.
#11 lore raw

PATCH v4 1/7 arm: add MMU/D-Cache support for Faraday cores

2013/6/11 Albert ARIBAUD <[email protected]>:

Quoted 87 lines

Hi Kuo-Jung,

Quoted 82 lines · Kuo-Jung Su

2013/6/11 Albert ARIBAUD <[email protected]>:

Quoted 5 lines

Hi Kuo-Jung,

On Tue, 7 May 2013 14:25:07 +0800, Kuo-Jung Su <[email protected]> wrote:

Quoted 14 lines

arch/arm/include/asm/dma-mapping.h line 7

Quoted 10 lines
arch/arm/include/asm/dma-mapping.h +2 -0
index 5bbb0a0..5a13af5 100644
@@ -3,6 +3,9 @@
  * Stelian Pop <[email protected]>
  * Lead Tech Design <www.leadtechdesign.com>
  *
+ * (C) Copyright 2010
+ * Dante Su <[email protected]>

Fix Copyright notices (dates) throughout the patch (and series as needed).

Got it, thanks.

Quoted 39 lines
Quoted 39 lines
arch/arm/include/asm/dma-mapping.h +23 -2
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -24,22 +27,76 @@
 #ifndef __ASM_ARM_DMA_MAPPING_H
 #define __ASM_ARM_DMA_MAPPING_H
 
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+#include <asm/u-boot.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+#endif /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+
 enum dma_data_direction {
      DMA_BIDIRECTIONAL       = 0,
      DMA_TO_DEVICE           = 1,
      DMA_FROM_DEVICE         = 2,
 };
 
-static void *dma_alloc_coherent(size_t len, unsigned long *handle)
+static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
 {
-     *handle = (unsigned long)malloc(len);
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+     void *map, *va = memalign(ARCH_DMA_MINALIGN, len);
+
+     if (va && gd->arch.cpu_mmu) {
+             invalidate_dcache_range((ulong)va, (ulong)va + len);
+             map = map_physmem((phys_addr_t)va, len, MAP_NOCACHE);
+             if (!map)
+                     free(va);
+             va = map;
+     }
+
+     if (handle)
+             *handle = virt_to_phys(va);
Quoted 9 lines

arch/arm/include/asm/dma-mapping.h line 64

Quoted 5 lines
arch/arm/include/asm/dma-mapping.h +4 -0
+
+     return va;
+#else  /* CONFIG_FARADAY && !CONFIG_SYS_DCACHE_OFF */
+     *handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len);
      return (void *)*handle;

This is not identical to what the code was before the patch. Why the difference?

Yes, it's not identical to what the code was.

It was:

    *handle = (unsigned long)malloc(len);
But I think it should be
    *handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len);

Because even though the MMU/D-cache is off, some DMA engines still requires strict address alignment.

Quoted 7 lines
Quoted 2 lines

For example, the Faraday FTMAC110 & FTGMAC100 ether-net controllers expect the descriptors are always aligned to 16-bytes boundary.

Unless there exists an actual case where the current form causes an issue, please leave it unchanged. And if it is needed, then please make it a separate patch.

Got it, thanks.
I'll make it a separate patch.

--
Best wishes,
Kuo-Jung Su

#12 lore raw

PATCH v4 2/7 arm: add Faraday common utilities

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

CC Albert Aribaud <[email protected]>

---
Changes for v4:
- Coding Style cleanup.
- Break up from [arm: add Faraday A36x SoC platform support]
- Drop reset.c and get the reset_cpu() merged into cpu.c
- Add macro constants & bit/mask for cpu ids.
- Disable MMU/D-cache only when FA606TE(no-mmu) detected.

Changes for v3:
- Coding Style cleanup.
- Always insert a blank line between declarations and code.

Changes for v2:
- Coding Style cleanup.

 arch/arm/cpu/faraday/Makefile     |   55 ++++
 arch/arm/cpu/faraday/config.mk    |   33 +++
 arch/arm/cpu/faraday/cpu.c        |  280 ++++++++++++++++++++
 arch/arm/cpu/faraday/start.S      |  523 +++++++++++++++++++++++++++++++++++++
 arch/arm/include/asm/mach-types.h |    1 +
 include/common.h                  |    8 +
 6 files changed, 900 insertions(+)
 create mode 100644 arch/arm/cpu/faraday/Makefile
 create mode 100644 arch/arm/cpu/faraday/config.mk
 create mode 100644 arch/arm/cpu/faraday/cpu.c
 create mode 100644 arch/arm/cpu/faraday/start.S
arch/arm/cpu/faraday/Makefile new file +55 -0
new file mode 100644
index 0000000..ecb240a
@@ -0,0 +1,55 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(CPU).o
+
+src-y  := cpu.o
+
+START	= start.o
+COBJS	= $(src-y)
+
+ifdef	CONFIG_SPL_BUILD
+ifdef	CONFIG_SPL_NO_CPU_SUPPORT_CODE
+START	:=
+endif
+endif
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
arch/arm/cpu/faraday/config.mk new file +33 -0
new file mode 100644
index 0000000..f03030a
@@ -0,0 +1,33 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <[email protected]>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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
+#
+
+PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
+
+PLATFORM_CPPFLAGS += -march=armv4
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
+PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT)
arch/arm/cpu/faraday/cpu.c new file +280 -0

280 lines not on this page · raw message

arch/arm/cpu/faraday/start.S new file +523 -0

523 lines not on this page · raw message

arch/arm/include/asm/mach-types.h +1 -0
index 440b041..a103922 100644
@@ -144,6 +144,7 @@ extern unsigned int __machine_arch_type;
 #define MACH_TYPE_AKITA                744
 #define MACH_TYPE_E330                 753
 #define MACH_TYPE_NOKIA770             755
+#define MACH_TYPE_FARADAY              758
 #define MACH_TYPE_CARMEVA              769
 #define MACH_TYPE_EDB9315A             772
 #define MACH_TYPE_STARGATE2            774
include/common.h +8 -0
index 8a1f3e4..17d9043 100644
@@ -112,6 +112,9 @@ typedef volatile unsigned char	vu_char;
 #ifdef CONFIG_SOC_DA8XX
 #include <asm/arch/hardware.h>
 #endif
+#ifdef CONFIG_FARADAY
+#include <asm/arch/hardware.h>
+#endif
 
 #include <part.h>
 #include <flash.h>
@@ -257,6 +260,11 @@ typedef void (interrupt_handler_t)(void *);
 	const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
 	(type *)( (char *)__mptr - offsetof(type,member) );})
 
+#ifdef CONFIG_FARADAY
+/* board/faraday/xxx/clk.c */
+ulong clk_get_rate(char *id);
+#endif
+
 /*
  * Function Prototypes
  */

--
1.7.9.5

#13 lore raw

PATCH v4 2/7 arm: add Faraday common utilities

Hi Kuo-Jung,

arch/arm/include/asm/mach-types.h

Quoted 4 lines · Kuo-Jung Su
arch/arm/include/asm/mach-types.h +0 -0
index 440b041..a103922 100644

Do not assign to mach-types. If mach-type was assigned in the ARM machine base, then request for an update of mach-types, or define your specific machine type in your board's config header file.

Quoted 1 line

1.7.9.5

Amicalement,

Signature · 1 line
Albert.
#14 lore raw

PATCH v4 2/7 arm: add Faraday common utilities

2013/6/11 Albert ARIBAUD <[email protected]>:

Quoted 6 lines

Hi Kuo-Jung,

On Tue, 7 May 2013 14:25:08 +0800, Kuo-Jung Su <[email protected]> wrote:

Quoted 9 lines

arch/arm/include/asm/mach-types.h

Quoted 4 lines
arch/arm/include/asm/mach-types.h +0 -0
index 440b041..a103922 100644

Do not assign to mach-types. If mach-type was assigned in the ARM machine base, then request for an update of mach-types, or define your specific machine type in your board's config header file.

Got it, thanks

--
Best wishes,
Kuo-Jung Su

#15 lore raw

PATCH v4 3/7 arm: add Faraday interrupt controller support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

CC Albert Aribaud <[email protected]>

---
Changes for v4:
- Coding Style cleanup.
- Break up from [arm: add Faraday A36x SoC platform support]

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

 arch/arm/cpu/faraday/Makefile     |    2 +-
 arch/arm/cpu/faraday/interrupts.c |  151 +++++++++++++++++++++++++++++++++++++
 include/common.h                  |    5 ++
 include/faraday/ftintc020.h       |   37 +++++++++
 4 files changed, 194 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/faraday/interrupts.c
 create mode 100644 include/faraday/ftintc020.h
arch/arm/cpu/faraday/Makefile +1 -1
index ecb240a..77cc373 100644
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)lib$(CPU).o
 
-src-y  := cpu.o
+src-y  := cpu.o interrupts.o
 
 START	= start.o
 COBJS	= $(src-y)
arch/arm/cpu/faraday/interrupts.c new file +151 -0

151 lines not on this page · raw message

include/common.h +5 -0
index 17d9043..2cdb7f3 100644
@@ -263,6 +263,11 @@ typedef void (interrupt_handler_t)(void *);
 #ifdef CONFIG_FARADAY
 /* board/faraday/xxx/clk.c */
 ulong clk_get_rate(char *id);
+
+/* arch/arm/cpu/faraday/xxx/interrupt.c */
+void irq_set_trigger(int irq, int edge, int low);
+void irq_enable(int irq);
+void irq_disable(int irq);
 #endif
 
 /*
include/faraday/ftintc020.h new file +37 -0
new file mode 100644
index 0000000..e23d1e7
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/cpu/faraday/ftintc020.h
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef ARCH_ARM_CPU_FARADAY_FTINTC020_H
+#define ARCH_ARM_CPU_FARADAY_FTINTC020_H
+
+struct ftintc020_pic_regs {
+	uint32_t src; /* source register */
+	uint32_t ena; /* enable register */
+	uint32_t scr; /* status clear register */
+	uint32_t tmr; /* trigger mode register */
+	uint32_t tlr; /* trigger level register */
+	uint32_t sr;  /* status register */
+	uint32_t rsvd[2];
+};
+
+struct ftintc020_regs {
+	/* IRQ/FIQ:  0 ~ 31 */
+	struct ftintc020_pic_regs irq32; /* 0x00 - 0x1C: IRQ 0 ~ 31 */
+	struct ftintc020_pic_regs fiq32; /* 0x20 - 0x3C: FIQ 0 ~ 31 */
+	uint32_t rsvd1[4];               /* 0x40 - 0x4C: Reserved */
+	uint32_t revision;               /* 0x50: Revision Register */
+	uint32_t feature;                /* 0x54: Feature Register */
+	uint32_t rsvd2[2];               /* 0x58 - 0x5C: Reserved */
+	/* IRQ/FIQ: 32 ~ 63 */
+	struct ftintc020_pic_regs irq64; /* 0x60 - 0x7C: IRQ 32 ~ 63 */
+	struct ftintc020_pic_regs fiq64; /* 0x80 - 0x9C: FIQ 32 ~ 63 */
+};
+
+#endif

--
1.7.9.5

#16 lore raw

PATCH v4 4/7 arm: add Faraday FTTMR010 timer support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

CC Albert Aribaud <[email protected]>

---
Changes for v4:
- Coding Style cleanup.
- Break up from [arm: add Faraday A36x SoC platform support]

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

 arch/arm/cpu/faraday/Makefile   |    1 +
 arch/arm/cpu/faraday/fttmr010.c |  160 +++++++++++++++++++++++++++++++++++++++
 include/faraday/fttmr010.h      |   17 +++++
 3 files changed, 178 insertions(+)
 create mode 100644 arch/arm/cpu/faraday/fttmr010.c
arch/arm/cpu/faraday/Makefile +1 -0
index 77cc373..5de417c 100644
@@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(CPU).o
 
 src-y  := cpu.o interrupts.o
+src-$(CONFIG_FTTMR010)    += fttmr010.o
 
 START	= start.o
 COBJS	= $(src-y)
arch/arm/cpu/faraday/fttmr010.c new file +160 -0

160 lines not on this page · raw message

include/faraday/fttmr010.h +17 -0
index 72abcb3..ef10f31 100644
@@ -57,6 +57,16 @@ struct fttmr010 {
 #define FTTMR010_TM1_CLOCK	(1 << 1)
 #define FTTMR010_TM1_ENABLE	(1 << 0)
 
+#define FTTMR010_TM1_CRMASK \
+	(FTTMR010_TM1_UPDOWN | FTTMR010_TM1_OFENABLE \
+	| FTTMR010_TM1_CLOCK | FTTMR010_TM1_ENABLE)
+#define FTTMR010_TM2_CRMASK \
+	(FTTMR010_TM2_UPDOWN | FTTMR010_TM2_OFENABLE \
+	| FTTMR010_TM2_CLOCK | FTTMR010_TM2_ENABLE)
+#define FTTMR010_TM3_CRMASK \
+	(FTTMR010_TM3_UPDOWN | FTTMR010_TM3_OFENABLE \
+	| FTTMR010_TM3_CLOCK | FTTMR010_TM3_ENABLE)
+
 /*
  * Timer Interrupt State & Mask Registers
  */
@@ -70,4 +80,11 @@ struct fttmr010 {
 #define FTTMR010_TM1_MATCH2	(1 << 1)
 #define FTTMR010_TM1_MATCH1	(1 << 0)
 
+#define FTTMR010_TM1_ISRMASK \
+	(FTTMR010_TM1_OVERFLOW | FTTMR010_TM1_MATCH2 | FTTMR010_TM1_MATCH1)
+#define FTTMR010_TM2_ISRMASK \
+	(FTTMR010_TM2_OVERFLOW | FTTMR010_TM2_MATCH2 | FTTMR010_TM2_MATCH1)
+#define FTTMR010_TM3_ISRMASK \
+	(FTTMR010_TM3_OVERFLOW | FTTMR010_TM3_MATCH2 | FTTMR010_TM3_MATCH1)
+
 #endif	/* __FTTMR010_H */

--
1.7.9.5

#17 lore raw

PATCH v4 5/7 arm: add Faraday FTPWMTMR010 timer support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

CC Albert Aribaud <[email protected]>

---
Changes for v4:
- Coding Style cleanup.
- Break up from [arm: add Faraday A36x SoC platform support]

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

 arch/arm/cpu/faraday/Makefile      |    1 +
 arch/arm/cpu/faraday/ftpwmtmr010.c |  160 ++++++++++++++++++++++++++++++++++++
 include/faraday/ftpwmtmr010.h      |   41 +++++++++
 3 files changed, 202 insertions(+)
 create mode 100644 arch/arm/cpu/faraday/ftpwmtmr010.c
 create mode 100644 include/faraday/ftpwmtmr010.h
arch/arm/cpu/faraday/Makefile +1 -0
index 5de417c..290400a 100644
@@ -27,6 +27,7 @@ LIB	= $(obj)lib$(CPU).o
 
 src-y  := cpu.o interrupts.o
 src-$(CONFIG_FTTMR010)    += fttmr010.o
+src-$(CONFIG_FTPWMTMR010) += ftpwmtmr010.o
 
 START	= start.o
 COBJS	= $(src-y)
arch/arm/cpu/faraday/ftpwmtmr010.c new file +160 -0

160 lines not on this page · raw message

include/faraday/ftpwmtmr010.h new file +41 -0

41 lines not on this page · raw message

--
1.7.9.5

#18 lore raw

PATCH v4 6/7 arm: add Faraday firmware image utility

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

CC Albert Aribaud <[email protected]>

---
Changes for v4:
- Coding Style cleanup.
- Break up from [arm: add Faraday A36x SoC platform support]

Changes for v3:
- Coding Style cleanup.
- Always insert a blank line between declarations and code.

Changes for v2:
- Coding Style cleanup.

 arch/arm/cpu/faraday/Makefile     |    2 +-
 arch/arm/cpu/faraday/cmd_bootfa.c |  132 +++++++++++++++++++++++++++++++++++++
 arch/arm/cpu/faraday/fwimage.h    |   38 +++++++++++
 arch/arm/cpu/faraday/fwimage2.h   |   70 ++++++++++++++++++++
 arch/arm/cpu/u-boot.lds           |   11 ++++
 5 files changed, 252 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/faraday/cmd_bootfa.c
 create mode 100644 arch/arm/cpu/faraday/fwimage.h
 create mode 100644 arch/arm/cpu/faraday/fwimage2.h
arch/arm/cpu/faraday/Makefile +1 -1
index 290400a..77899d9 100644
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)lib$(CPU).o
 
-src-y  := cpu.o interrupts.o
+src-y  := cpu.o interrupts.o cmd_bootfa.o
 src-$(CONFIG_FTTMR010)    += fttmr010.o
 src-$(CONFIG_FTPWMTMR010) += ftpwmtmr010.o
 
arch/arm/cpu/faraday/cmd_bootfa.c new file +132 -0

132 lines not on this page · raw message

arch/arm/cpu/faraday/fwimage.h new file +38 -0
new file mode 100644
index 0000000..af4f2f9
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/cpu/faraday/fwimage.h
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef ARCH_ARM_CPU_FARADAY_FWIMAGE_H
+#define ARCH_ARM_CPU_FARADAY_FWIMAGE_H
+
+struct fwparam {
+	uint32_t	count;
+	uint32_t	version; /* ycmo100525: for firmware image version */
+	uint32_t	addr[31];
+	uint32_t	data[31];
+};
+
+struct fwfile {
+	char		name[64];
+	uint32_t	size;
+	/* uint32_t	block[1]; */
+};
+
+struct fwimage {
+	/* 8 bytes */
+	uint32_t		magic;	/* Magic number */
+	uint32_t		length;	/* It shall not be greater than 2048 */
+
+	/* 256 bytes, embedded paramters area */
+	struct fwparam	param;
+
+	struct fwfile	file[1];
+};
+
+#endif
arch/arm/cpu/faraday/fwimage2.h new file +70 -0

70 lines not on this page · raw message

arch/arm/cpu/u-boot.lds +11 -0
index d9bbee3..ac59fec 100644
@@ -23,6 +23,8 @@
  * MA 02111-1307 USA
  */
 
+#include <config.h>
+
 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
 OUTPUT_ARCH(arm)
 ENTRY(_start)
@@ -35,6 +37,15 @@ SECTIONS
 	{
 		__image_copy_start = .;
 		CPUDIR/start.o (.text*)
+#ifdef CONFIG_FARADAY
+		/*
+		 * Dante Su 2012.10.09:
+		 * Reserved for the faimage v2.1.
+		 * 1. CPUDIR/start.o: It shall never be > 4KB.
+		 * 2. faimage header: It shall always be stored at 0x1000, and <= 1KB.
+		 */
+		. = 0x00001400;
+#endif
 		*(.text*)
 	}
 

--
1.7.9.5

#19 lore raw

PATCH v4 6/7 arm: add Faraday firmware image utility

Hi Kuo-Jung,

Quoted 16 lines · Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

CC Albert Aribaud <[email protected]>

---
Changes for v4:
- Coding Style cleanup.
- Break up from [arm: add Faraday A36x SoC platform support]

Changes for v3:
- Coding Style cleanup.
- Always insert a blank line between declarations and code.

Changes for v2:
- Coding Style cleanup.

Quoted 9 lines
 arch/arm/cpu/faraday/Makefile     |    2 +-
 arch/arm/cpu/faraday/cmd_bootfa.c |  132 +++++++++++++++++++++++++++++++++++++
 arch/arm/cpu/faraday/fwimage.h    |   38 +++++++++++
 arch/arm/cpu/faraday/fwimage2.h   |   70 ++++++++++++++++++++
 arch/arm/cpu/u-boot.lds           |   11 ++++
 5 files changed, 252 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/faraday/cmd_bootfa.c
 create mode 100644 arch/arm/cpu/faraday/fwimage.h
 create mode 100644 arch/arm/cpu/faraday/fwimage2.h

What is the rationale behind a specific boot command? What prevents using the existing tools and formats?

Amicalement,

Signature · 1 line
Albert.
#20 lore raw

PATCH v4 6/7 arm: add Faraday firmware image utility

2013/6/11 Albert ARIBAUD <[email protected]>:

Quoted 31 lines

Hi Kuo-Jung,

Quoted 16 lines · Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

CC Albert Aribaud <[email protected]>

---
Changes for v4:
- Coding Style cleanup.
- Break up from [arm: add Faraday A36x SoC platform support]

Changes for v3:
- Coding Style cleanup.
- Always insert a blank line between declarations and code.

Changes for v2:
- Coding Style cleanup.

Quoted 9 lines
 arch/arm/cpu/faraday/Makefile     |    2 +-
 arch/arm/cpu/faraday/cmd_bootfa.c |  132 +++++++++++++++++++++++++++++++++++++
 arch/arm/cpu/faraday/fwimage.h    |   38 +++++++++++
 arch/arm/cpu/faraday/fwimage2.h   |   70 ++++++++++++++++++++
 arch/arm/cpu/u-boot.lds           |   11 ++++
 5 files changed, 252 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/faraday/cmd_bootfa.c
 create mode 100644 arch/arm/cpu/faraday/fwimage.h
 create mode 100644 arch/arm/cpu/faraday/fwimage2.h
Quoted 1 line

What is the rationale behind a specific boot command?

Got it, thanks.
I'll add the rationale at next patch.

Quoted 3 lines

What prevents
using the existing tools and formats?

The private firmware image format is designed for better backward compatibility to the hard-wired ROM code for Faraday A36x SoC.

I'll try to revise the design and see if it's possible to adapt it to existing u-boot tools and formats.

Quoted 3 lines

Amicalement,
--
Albert.

--
Best wishes,
Kuo-Jung Su

#21 lore raw

PATCH v4 7/7 arm: add Faraday A36x SoC platform support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

The Faraday A36x EVB is a Faraday SoC platform evalution board used for Faraday IP functional verification based on the well-known ARM AMBA 2.0 architecture.

Faraday A360 EVB:
CPU: FA626TE
NET: FTMAC110
USB: FUSBH200, FOTG210
LCD: FTLCDC200
I2C: FTI2C010
SPI: FTSSP010 v1.18.0
MMC: FTSDC010
RTC: FTRTC010
WDT: FTWDT010
TMR: FTTMR010
PIC: FTINTC020
UART: FTUART010
NAND: FTNANDC020

Faraday A369 EVB:
CPU: FA626TE(Master)/FA606TE(Slave)
NET: FTGMAC100
USB: FUSBH200, FOTG210
LCD: FTLCDC200
I2C: FTI2C010
SPI: FTSSP010 v1.18.0
MMC: FTSDC010
RTC: FTRTC011
WDT: FTWDT010
TMR: FTPWMTMR010
PIC: FTINTC020
UART: FTUART010
NAND: FTNANDC021

CC Albert Aribaud <[email protected]>

---
Changes for v4:
- Coding Style cleanup.
- Break-down the interrupt, timers and common utilties.

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Add '__iomem' to all the declaration of HW register pointers.
- a36x_config: No more static global network configurations.
- a36x_config: Add a common file for the redundant configurations.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

 arch/arm/cpu/faraday/a360/Makefile        |   49 +++++
 arch/arm/cpu/faraday/a369/Makefile        |   50 +++++
 arch/arm/cpu/faraday/a369/cmd_fa606.c     |   77 ++++++++
 arch/arm/include/asm/arch-a360/hardware.h |   73 +++++++
 arch/arm/include/asm/arch-a360/pmu.h      |   39 ++++
 arch/arm/include/asm/arch-a360/scu.h      |   27 +++
 arch/arm/include/asm/arch-a369/ahbc.h     |   23 +++
 arch/arm/include/asm/arch-a369/hardware.h |   88 +++++++++
 arch/arm/include/asm/arch-a369/scu.h      |  213 ++++++++++++++++++++
 board/faraday/a360evb/Makefile            |   49 +++++
 board/faraday/a360evb/board.c             |   73 +++++++
 board/faraday/a360evb/clk.c               |   57 ++++++
 board/faraday/a360evb/config.mk           |   33 ++++
 board/faraday/a360evb/lowlevel_init.S     |   33 ++++
 board/faraday/a369evb/Makefile            |   49 +++++
 board/faraday/a369evb/board.c             |  184 +++++++++++++++++
 board/faraday/a369evb/clk.c               |   80 ++++++++
 board/faraday/a369evb/config.mk           |   33 ++++
 board/faraday/a369evb/lowlevel_init.S     |  136 +++++++++++++
 boards.cfg                                |    3 +
 include/configs/a360.h                    |   63 ++++++
 include/configs/a369-common.h             |   74 +++++++
 include/configs/a369.h                    |   33 ++++
 include/configs/a369_fa606te.h            |   29 +++
 include/configs/faraday-common.h          |  304 +++++++++++++++++++++++++++++
 include/faraday/ftsmc020.h                |    1 +
 26 files changed, 1873 insertions(+)
 create mode 100644 arch/arm/cpu/faraday/a360/Makefile
 create mode 100644 arch/arm/cpu/faraday/a369/Makefile
 create mode 100644 arch/arm/cpu/faraday/a369/cmd_fa606.c
 create mode 100644 arch/arm/include/asm/arch-a360/hardware.h
 create mode 100644 arch/arm/include/asm/arch-a360/pmu.h
 create mode 100644 arch/arm/include/asm/arch-a360/scu.h
 create mode 100644 arch/arm/include/asm/arch-a369/ahbc.h
 create mode 100644 arch/arm/include/asm/arch-a369/hardware.h
 create mode 100644 arch/arm/include/asm/arch-a369/scu.h
 create mode 100644 board/faraday/a360evb/Makefile
 create mode 100644 board/faraday/a360evb/board.c
 create mode 100644 board/faraday/a360evb/clk.c
 create mode 100644 board/faraday/a360evb/config.mk
 create mode 100644 board/faraday/a360evb/lowlevel_init.S
 create mode 100644 board/faraday/a369evb/Makefile
 create mode 100644 board/faraday/a369evb/board.c
 create mode 100644 board/faraday/a369evb/clk.c
 create mode 100644 board/faraday/a369evb/config.mk
 create mode 100644 board/faraday/a369evb/lowlevel_init.S
 create mode 100644 include/configs/a360.h
 create mode 100644 include/configs/a369-common.h
 create mode 100644 include/configs/a369.h
 create mode 100644 include/configs/a369_fa606te.h
 create mode 100644 include/configs/faraday-common.h
arch/arm/cpu/faraday/a360/Makefile new file +49 -0
new file mode 100644
index 0000000..7113f66
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).o
+
+obj-y   :=
+
+COBJS	:= $(obj-y)
+SOBJS	:=
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
arch/arm/cpu/faraday/a369/Makefile new file +50 -0

50 lines not on this page · raw message

arch/arm/cpu/faraday/a369/cmd_fa606.c new file +77 -0

77 lines not on this page · raw message

arch/arm/include/asm/arch-a360/hardware.h new file +73 -0

73 lines not on this page · raw message

arch/arm/include/asm/arch-a360/pmu.h new file +39 -0
new file mode 100644
index 0000000..51b9391
@@ -0,0 +1,39 @@
+/*
+ * asm/arch-a360/pmu.h
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef __ASM_ARCH_PMU_H
+#define __ASM_ARCH_PMU_H
+
+struct a360pmu_regs {
+	uint32_t idr;      /* ID register */
+	uint32_t rsvd0;
+	uint32_t osccr;    /* OSC control register */
+	uint32_t pmr;      /* Power mode register */
+
+	uint32_t pmcr;     /* Power manager control register */
+	uint32_t peer;     /* Power manager edge detect enable register */
+	uint32_t pesr;     /* Power manager edge detect status register */
+	uint32_t rsvd1;
+
+	uint32_t pmsr;     /* Power manager status register */
+	uint32_t pgsr;     /* Power manager GPIO sleep state register */
+	uint32_t rsvd2;
+	uint32_t mcr;      /* Misc. control register */
+
+	uint32_t pdcr;     /* PLL/DLL control register */
+	uint32_t rsvd3[7];
+
+	uint32_t pspr[16]; /* Power manager scratch pad register */
+
+	uint32_t rsvd4[3];
+	uint32_t jssr;     /* Jumper setting status register */
+};
+
+#endif
arch/arm/include/asm/arch-a360/scu.h new file +27 -0
new file mode 100644
index 0000000..6fbd1b8
@@ -0,0 +1,27 @@
+/*
+ * asm/arch-a360/scu.h
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef __ASM_ARCH_SCU_H
+#define __ASM_ARCH_SCU_H
+
+struct a360scu_regs {
+	uint32_t idr;      /* 0x00: ID Register */
+	uint32_t gcr;      /* 0x04: General Control Register */
+	uint32_t ccr;      /* 0x08: Clock Configuration Register */
+	uint32_t hcer;     /* 0x0C: AHB Clock Enable Register */
+	uint32_t pcer;     /* 0x10: APB Clock Enable Register */
+	uint32_t csr;      /* 0x14: Configuration Strap Register */
+	uint32_t iomcr[4]; /* IO Mux Control Register */
+	uint32_t iopcr[2]; /* IO Parameter Control Register */
+	uint32_t cescr;    /* CPU Edge Sync Control Register */
+	uint32_t expcr[3]; /* PCI-Express Control Register */
+};
+
+#endif
arch/arm/include/asm/arch-a369/ahbc.h new file +23 -0
new file mode 100644
index 0000000..606cedc
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/include/asm/arch-a369/ahbc.h
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef __ASM_ARCH_AHBC_H
+#define __ASM_ARCH_AHBC_H
+
+struct a369ahbc_regs {
+	uint32_t slave[32];/* Slave Device Configurations */
+	uint32_t priority; /* Priority */
+	uint32_t idle_cnt; /* IDLE Counter */
+	uint32_t control;  /* Control Register */
+	uint32_t revision; /* Revision ID */
+	uint32_t cpusao;   /* CPUS (FA606TE) Address Offset */
+};
+
+#endif
arch/arm/include/asm/arch-a369/hardware.h new file +88 -0

88 lines not on this page · raw message

arch/arm/include/asm/arch-a369/scu.h new file +213 -0

213 lines not on this page · raw message

board/faraday/a360evb/Makefile new file +49 -0

49 lines not on this page · raw message

board/faraday/a360evb/board.c new file +73 -0

73 lines not on this page · raw message

board/faraday/a360evb/clk.c new file +57 -0

57 lines not on this page · raw message

board/faraday/a360evb/config.mk new file +33 -0
new file mode 100644
index 0000000..eb1a258
@@ -0,0 +1,33 @@
+#
+# (C) Copyright 2010
+# Dante Su <[email protected]>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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
+#
+
+#########################################################################
+
+ALL += $(obj)u-boot.img
+
+# Environment variables in NAND
+#ifeq ($(ENV),NAND)
+#PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_NAND
+#else
+#PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_FLASH
+#endif
board/faraday/a360evb/lowlevel_init.S new file +33 -0
new file mode 100644
index 0000000..1ead608
@@ -0,0 +1,33 @@
+/*
+ * Board specific setup info
+ *
+ * (C) Copyright 2010
+ * Faraday Technology Inc. <www.faraday-tech.com>
+ * Dante Su <[email protected]>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#include <config.h>
+#include <version.h>
+
+/* Set up the platform, once the cpu has been initialized */
+.globl lowlevel_init
+lowlevel_init:
+	mov	pc,lr
board/faraday/a369evb/Makefile new file +49 -0

49 lines not on this page · raw message

board/faraday/a369evb/board.c new file +184 -0

184 lines not on this page · raw message

board/faraday/a369evb/clk.c new file +80 -0

80 lines not on this page · raw message

board/faraday/a369evb/config.mk new file +33 -0
new file mode 100644
index 0000000..eb1a258
@@ -0,0 +1,33 @@
+#
+# (C) Copyright 2010
+# Dante Su <[email protected]>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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
+#
+
+#########################################################################
+
+ALL += $(obj)u-boot.img
+
+# Environment variables in NAND
+#ifeq ($(ENV),NAND)
+#PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_NAND
+#else
+#PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_FLASH
+#endif
board/faraday/a369evb/lowlevel_init.S new file +136 -0

136 lines not on this page · raw message

boards.cfg +3 -0
index 5d78064..891f7f3 100644
@@ -73,6 +73,9 @@ mini2440                     arm         arm920t     mini2440            friendl
 VCMA9                        arm         arm920t     vcma9               mpl            s3c24x0
 smdk2410                     arm         arm920t     -                   samsung        s3c24x0
 omap1510inn                  arm         arm925t     -                   ti
+a360                         arm         faraday     a360evb             faraday        a360
+a369                         arm         faraday     a369evb             faraday        a369
+a369_fa606te                 arm         faraday     a369evb             faraday        a369
 integratorap_cm926ejs        arm         arm926ejs   integrator          armltd         -           integratorap:CM926EJ_S
 integratorcp_cm926ejs        arm         arm926ejs   integrator          armltd         -           integratorcp:CM924EJ_S
 aspenite                     arm         arm926ejs   -                   Marvell        armada100
include/configs/a360.h new file +63 -0

63 lines not on this page · raw message

include/configs/a369-common.h new file +74 -0

74 lines not on this page · raw message

include/configs/a369.h new file +33 -0
new file mode 100644
index 0000000..d4bb39a
@@ -0,0 +1,33 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_A369_PLATFORM
+
+/* Support external AHB */
+/* #define CONFIG_SUPP_EXTAHB */
+
+/* Support USB RNDIS Ethernet */
+/* #define CONFIG_SUPP_USB_RNDIS */
+
+/* Support VGA Console */
+/* #define CONFIG_SUPP_VGA_CONSOLE */
+
+/* Support interrupt */
+/* #define CONFIG_USE_IRQ */
+
+/* Disable MMU/D-CACHE */
+/* #define CONFIG_SYS_DCACHE_OFF */
+
+/* Support runtime switching to built-in slave core: FA606TE */
+#define CONFIG_CMD_FA606
+
+/* Autoboot */
+#define CONFIG_BOOTDELAY            3
+#define CONFIG_BOOTCOMMAND          "bootfa nand linux"
+
+/*
+ * A369 Common Configuration
+ */
+#include "a369-common.h"
+
+#endif
include/configs/a369_fa606te.h new file +29 -0
new file mode 100644
index 0000000..ec29d50
@@ -0,0 +1,29 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_A369_FA606TE_PLATFORM
+
+/* Support external AHB */
+/* #define CONFIG_SUPP_EXTAHB */
+
+/* Support USB RNDIS Ethernet */
+/* #define CONFIG_SUPP_USB_RNDIS */
+
+/* Support VGA Console */
+/* #define CONFIG_SUPP_VGA_CONSOLE */
+
+/* Support interrupt */
+/* #define CONFIG_USE_IRQ */
+
+/* Disable MMU/D-CACHE */
+#define CONFIG_SYS_DCACHE_OFF
+
+/* Disable I-CACHE */
+#define CONFIG_SYS_ICACHE_OFF
+
+/*
+ * A369 Common Configuration
+ */
+#include "a369-common.h"
+
+#endif
include/configs/faraday-common.h new file +304 -0

304 lines not on this page · raw message

include/faraday/ftsmc020.h +1 -0
index 59c6f8e..aa02717 100644
@@ -82,5 +82,6 @@ void ftsmc020_init(void);
 #define FTSMC020_TPR_WTC(x)	(((x) & 0x3) << 6)
 #define FTSMC020_TPR_AHT(x)	(((x) & 0x3) << 4)
 #define FTSMC020_TPR_TRNA(x)	(((x) & 0xf) << 0)
+#define FTSMC020_TPR_WORST	0x0f1ff3ff /* worst but safe */
 
 #endif	/* __FTSMC020_H */

--
1.7.9.5

#22 lore raw

PATCH v4 7/7 arm: add Faraday A36x SoC platform support

Hi Kuo-Jung,

Quoted 19 lines · Kuo-Jung Su
 arch/arm/cpu/faraday/a360/Makefile        |   49 +++++
 arch/arm/cpu/faraday/a369/Makefile        |   50 +++++
 arch/arm/cpu/faraday/a369/cmd_fa606.c     |   77 ++++++++
 arch/arm/include/asm/arch-a360/hardware.h |   73 +++++++
 arch/arm/include/asm/arch-a360/pmu.h      |   39 ++++
 arch/arm/include/asm/arch-a360/scu.h      |   27 +++
 arch/arm/include/asm/arch-a369/ahbc.h     |   23 +++
 arch/arm/include/asm/arch-a369/hardware.h |   88 +++++++++
 arch/arm/include/asm/arch-a369/scu.h      |  213 ++++++++++++++++++++
 board/faraday/a360evb/Makefile            |   49 +++++
 board/faraday/a360evb/board.c             |   73 +++++++
 board/faraday/a360evb/clk.c               |   57 ++++++
 board/faraday/a360evb/config.mk           |   33 ++++
 board/faraday/a360evb/lowlevel_init.S     |   33 ++++
 board/faraday/a369evb/Makefile            |   49 +++++
 board/faraday/a369evb/board.c             |  184 +++++++++++++++++
 board/faraday/a369evb/clk.c               |   80 ++++++++
 board/faraday/a369evb/config.mk           |   33 ++++
 board/faraday/a369evb/lowlevel_init.S     |  136 +++++++++++++
Quoted 8 lines
 boards.cfg                                |    3 +
 include/configs/a360.h                    |   63 ++++++
 include/configs/a369-common.h             |   74 +++++++
 include/configs/a369.h                    |   33 ++++
 include/configs/a369_fa606te.h            |   29 +++
 include/configs/faraday-common.h          |  304 +++++++++++++++++++++++++++++
 include/faraday/ftsmc020.h                |    1 +
 26 files changed, 1873 insertions(+)

Please add entries in MAINTAINERS file.

Amicalement,

Signature · 1 line
Albert.
#23 lore raw

PATCH v4 7/7 arm: add Faraday A36x SoC platform support

2013/6/11 Albert ARIBAUD <[email protected]>:

Quoted 33 lines

Hi Kuo-Jung,

Quoted 19 lines · Kuo-Jung Su
 arch/arm/cpu/faraday/a360/Makefile        |   49 +++++
 arch/arm/cpu/faraday/a369/Makefile        |   50 +++++
 arch/arm/cpu/faraday/a369/cmd_fa606.c     |   77 ++++++++
 arch/arm/include/asm/arch-a360/hardware.h |   73 +++++++
 arch/arm/include/asm/arch-a360/pmu.h      |   39 ++++
 arch/arm/include/asm/arch-a360/scu.h      |   27 +++
 arch/arm/include/asm/arch-a369/ahbc.h     |   23 +++
 arch/arm/include/asm/arch-a369/hardware.h |   88 +++++++++
 arch/arm/include/asm/arch-a369/scu.h      |  213 ++++++++++++++++++++
 board/faraday/a360evb/Makefile            |   49 +++++
 board/faraday/a360evb/board.c             |   73 +++++++
 board/faraday/a360evb/clk.c               |   57 ++++++
 board/faraday/a360evb/config.mk           |   33 ++++
 board/faraday/a360evb/lowlevel_init.S     |   33 ++++
 board/faraday/a369evb/Makefile            |   49 +++++
 board/faraday/a369evb/board.c             |  184 +++++++++++++++++
 board/faraday/a369evb/clk.c               |   80 ++++++++
 board/faraday/a369evb/config.mk           |   33 ++++
 board/faraday/a369evb/lowlevel_init.S     |  136 +++++++++++++
Quoted 8 lines
 boards.cfg                                |    3 +
 include/configs/a360.h                    |   63 ++++++
 include/configs/a369-common.h             |   74 +++++++
 include/configs/a369.h                    |   33 ++++
 include/configs/a369_fa606te.h            |   29 +++
 include/configs/faraday-common.h          |  304 +++++++++++++++++++++++++++++
 include/faraday/ftsmc020.h                |    1 +
 26 files changed, 1873 insertions(+)
Quoted 2 lines

Please add entries in MAINTAINERS file.

Got it, thanks

Quoted 3 lines

Amicalement,
--
Albert.

--
Best wishes,
Kuo-Jung Su

#24 lore raw

PATCH v3 2/11 net: ftgmac100: add MMU/D-cache support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

CC Joe Hershberger <[email protected]>
---
 drivers/net/ftgmac100.c |   70 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 49 insertions(+), 21 deletions(-)
drivers/net/ftgmac100.c +49 -21
index 69ba57d..2dbb328 100644
@@ -27,11 +27,13 @@
 #include <malloc.h>
 #include <net.h>
 #include <asm/io.h>
+#include <asm/dma-mapping.h>
 #include <linux/mii.h>
 
 #include "ftgmac100.h"
 
 #define ETH_ZLEN	60
+#define CFG_XBUF_SIZE	1536
 
 /* RBSR - hw default init value is also 0x640 */
 #define RBSR_DEFAULT_VALUE	0x640
@@ -40,8 +42,10 @@
 #define PKTBUFSTX	4	/* must be power of 2 */
 
 struct ftgmac100_data {
-	struct ftgmac100_txdes txdes[PKTBUFSTX];
-	struct ftgmac100_rxdes rxdes[PKTBUFSRX];
+	ulong txdes_dma;
+	struct ftgmac100_txdes *txdes;
+	ulong rxdes_dma;
+	struct ftgmac100_rxdes *rxdes;
 	int tx_index;
 	int rx_index;
 	int phy_addr;
@@ -375,13 +379,34 @@ static int ftgmac100_init(struct eth_device *dev, bd_t *bd)
 {
 	struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
 	struct ftgmac100_data *priv = dev->priv;
-	struct ftgmac100_txdes *txdes = priv->txdes;
-	struct ftgmac100_rxdes *rxdes = priv->rxdes;
+	struct ftgmac100_txdes *txdes;
+	struct ftgmac100_rxdes *rxdes;
 	unsigned int maccr;
+	void *buf;
 	int i;
 
 	debug("%s()\n", __func__);
 
+	if (!priv->txdes) {
+		txdes = dma_alloc_coherent(
+			sizeof(*txdes) * PKTBUFSTX, &priv->txdes_dma);
+		if (!txdes)
+			panic("ftgmac100: out of memory\n");
+		memset(txdes, 0, sizeof(*txdes) * PKTBUFSTX);
+		priv->txdes = txdes;
+	}
+	txdes = priv->txdes;
+
+	if (!priv->rxdes) {
+		rxdes = dma_alloc_coherent(
+			sizeof(*rxdes) * PKTBUFSRX, &priv->rxdes_dma);
+		if (!rxdes)
+			panic("ftgmac100: out of memory\n");
+		memset(rxdes, 0, sizeof(*rxdes) * PKTBUFSRX);
+		priv->rxdes = rxdes;
+	}
+	rxdes = priv->rxdes;
+
 	/* set the ethernet address */
 	ftgmac100_set_mac_from_env(dev);
 
@@ -397,21 +422,31 @@ static int ftgmac100_init(struct eth_device *dev, bd_t *bd)
 
 	for (i = 0; i < PKTBUFSTX; i++) {
 		/* TXBUF_BADR */
-		txdes[i].txdes3 = 0;
+		if (!txdes[i].txdes2) {
+			buf = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE);
+			if (!buf)
+				panic("ftgmac100: out of memory\n");
+			txdes[i].txdes3 = virt_to_phys(buf);
+			txdes[i].txdes2 = (uint)buf;
+		}
 		txdes[i].txdes1 = 0;
 	}
 
 	for (i = 0; i < PKTBUFSRX; i++) {
 		/* RXBUF_BADR */
-		rxdes[i].rxdes3 = (unsigned int)NetRxPackets[i];
+		if (!rxdes[i].rxdes2) {
+			buf = NetRxPackets[i];
+			rxdes[i].rxdes3 = virt_to_phys(buf);
+			rxdes[i].rxdes2 = (uint)buf;
+		}
 		rxdes[i].rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
 	}
 
 	/* transmit ring */
-	writel((unsigned int)txdes, &ftgmac100->txr_badr);
+	writel(priv->txdes_dma, &ftgmac100->txr_badr);
 
 	/* receive ring */
-	writel((unsigned int)rxdes, &ftgmac100->rxr_badr);
+	writel(priv->rxdes_dma, &ftgmac100->rxr_badr);
 
 	/* poll receive descriptor automatically */
 	writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc);
@@ -466,8 +501,11 @@ static int ftgmac100_recv(struct eth_device *dev)
 	debug("%s(): RX buffer %d, %x received\n",
 	       __func__, priv->rx_index, rxlen);
 
+	/* invalidate d-cache */
+	dma_map_single((void *)curr_des->rxdes2, rxlen, DMA_FROM_DEVICE);
+
 	/* pass the packet up to the protocol layers. */
-	NetReceive((void *)curr_des->rxdes3, rxlen);
+	NetReceive((void *)curr_des->rxdes2, rxlen);
 
 	/* release buffer to DMA */
 	curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
@@ -485,7 +523,6 @@ static int ftgmac100_send(struct eth_device *dev, void *packet, int length)
 	struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
 	struct ftgmac100_data *priv = dev->priv;
 	struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index];
-	int start;
 
 	if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) {
 		debug("%s(): no TX descriptor available\n", __func__);
@@ -496,8 +533,8 @@ static int ftgmac100_send(struct eth_device *dev, void *packet, int length)
 
 	length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
 
-	/* initiate a transmit sequence */
-	curr_des->txdes3 = (unsigned int)packet;	/* TXBUF_BADR */
+	memcpy((void *)curr_des->txdes2, (void *)packet, length);
+	dma_map_single((void *)curr_des->txdes2, length, DMA_TO_DEVICE);
 
 	/* only one descriptor on TXBUF */
 	curr_des->txdes0 &= FTGMAC100_TXDES0_EDOTR;
@@ -509,15 +546,6 @@ static int ftgmac100_send(struct eth_device *dev, void *packet, int length)
 	/* start transmit */
 	writel(1, &ftgmac100->txpd);
 
-	/* wait for transfer to succeed */
-	start = get_timer(0);
-	while (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) {
-		if (get_timer(0) >= 5) {
-			debug("%s(): timed out\n", __func__);
-			return -1;
-		}
-	}
-
 	debug("%s(): packet sent\n", __func__);
 
 	priv->tx_index = (priv->tx_index + 1) % PKTBUFSTX;
Signature · 1 line
1.7.9.5
#25 lore raw

PATCH v4 1/1 net: update FTGMAC100 for MMU/D-cache support

From: Kuo-Jung Su <[email protected]>

CC Joe Hershberger <[email protected]>
CC Tom Rini <[email protected]>

---
Changes for v4:
- Make it a separate patch, rather then a part of Faraday A36x patch series

Changes for v3:
- Coding Style cleanup

Changes for v2:
- Coding Style cleanup
- Cleanup (Drop cosmetic patch)

 drivers/net/ftgmac100.c |   70 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 49 insertions(+), 21 deletions(-)
drivers/net/ftgmac100.c +49 -21
index 69ba57d..2dbb328 100644
@@ -27,11 +27,13 @@
 #include <malloc.h>
 #include <net.h>
 #include <asm/io.h>
+#include <asm/dma-mapping.h>
 #include <linux/mii.h>
 
 #include "ftgmac100.h"
 
 #define ETH_ZLEN	60
+#define CFG_XBUF_SIZE	1536
 
 /* RBSR - hw default init value is also 0x640 */
 #define RBSR_DEFAULT_VALUE	0x640
@@ -40,8 +42,10 @@
 #define PKTBUFSTX	4	/* must be power of 2 */
 
 struct ftgmac100_data {
-	struct ftgmac100_txdes txdes[PKTBUFSTX];
-	struct ftgmac100_rxdes rxdes[PKTBUFSRX];
+	ulong txdes_dma;
+	struct ftgmac100_txdes *txdes;
+	ulong rxdes_dma;
+	struct ftgmac100_rxdes *rxdes;
 	int tx_index;
 	int rx_index;
 	int phy_addr;
@@ -375,13 +379,34 @@ static int ftgmac100_init(struct eth_device *dev, bd_t *bd)
 {
 	struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
 	struct ftgmac100_data *priv = dev->priv;
-	struct ftgmac100_txdes *txdes = priv->txdes;
-	struct ftgmac100_rxdes *rxdes = priv->rxdes;
+	struct ftgmac100_txdes *txdes;
+	struct ftgmac100_rxdes *rxdes;
 	unsigned int maccr;
+	void *buf;
 	int i;
 
 	debug("%s()\n", __func__);
 
+	if (!priv->txdes) {
+		txdes = dma_alloc_coherent(
+			sizeof(*txdes) * PKTBUFSTX, &priv->txdes_dma);
+		if (!txdes)
+			panic("ftgmac100: out of memory\n");
+		memset(txdes, 0, sizeof(*txdes) * PKTBUFSTX);
+		priv->txdes = txdes;
+	}
+	txdes = priv->txdes;
+
+	if (!priv->rxdes) {
+		rxdes = dma_alloc_coherent(
+			sizeof(*rxdes) * PKTBUFSRX, &priv->rxdes_dma);
+		if (!rxdes)
+			panic("ftgmac100: out of memory\n");
+		memset(rxdes, 0, sizeof(*rxdes) * PKTBUFSRX);
+		priv->rxdes = rxdes;
+	}
+	rxdes = priv->rxdes;
+
 	/* set the ethernet address */
 	ftgmac100_set_mac_from_env(dev);
 
@@ -397,21 +422,31 @@ static int ftgmac100_init(struct eth_device *dev, bd_t *bd)
 
 	for (i = 0; i < PKTBUFSTX; i++) {
 		/* TXBUF_BADR */
-		txdes[i].txdes3 = 0;
+		if (!txdes[i].txdes2) {
+			buf = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE);
+			if (!buf)
+				panic("ftgmac100: out of memory\n");
+			txdes[i].txdes3 = virt_to_phys(buf);
+			txdes[i].txdes2 = (uint)buf;
+		}
 		txdes[i].txdes1 = 0;
 	}
 
 	for (i = 0; i < PKTBUFSRX; i++) {
 		/* RXBUF_BADR */
-		rxdes[i].rxdes3 = (unsigned int)NetRxPackets[i];
+		if (!rxdes[i].rxdes2) {
+			buf = NetRxPackets[i];
+			rxdes[i].rxdes3 = virt_to_phys(buf);
+			rxdes[i].rxdes2 = (uint)buf;
+		}
 		rxdes[i].rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
 	}
 
 	/* transmit ring */
-	writel((unsigned int)txdes, &ftgmac100->txr_badr);
+	writel(priv->txdes_dma, &ftgmac100->txr_badr);
 
 	/* receive ring */
-	writel((unsigned int)rxdes, &ftgmac100->rxr_badr);
+	writel(priv->rxdes_dma, &ftgmac100->rxr_badr);
 
 	/* poll receive descriptor automatically */
 	writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc);
@@ -466,8 +501,11 @@ static int ftgmac100_recv(struct eth_device *dev)
 	debug("%s(): RX buffer %d, %x received\n",
 	       __func__, priv->rx_index, rxlen);
 
+	/* invalidate d-cache */
+	dma_map_single((void *)curr_des->rxdes2, rxlen, DMA_FROM_DEVICE);
+
 	/* pass the packet up to the protocol layers. */
-	NetReceive((void *)curr_des->rxdes3, rxlen);
+	NetReceive((void *)curr_des->rxdes2, rxlen);
 
 	/* release buffer to DMA */
 	curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
@@ -485,7 +523,6 @@ static int ftgmac100_send(struct eth_device *dev, void *packet, int length)
 	struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
 	struct ftgmac100_data *priv = dev->priv;
 	struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index];
-	int start;
 
 	if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) {
 		debug("%s(): no TX descriptor available\n", __func__);
@@ -496,8 +533,8 @@ static int ftgmac100_send(struct eth_device *dev, void *packet, int length)
 
 	length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
 
-	/* initiate a transmit sequence */
-	curr_des->txdes3 = (unsigned int)packet;	/* TXBUF_BADR */
+	memcpy((void *)curr_des->txdes2, (void *)packet, length);
+	dma_map_single((void *)curr_des->txdes2, length, DMA_TO_DEVICE);
 
 	/* only one descriptor on TXBUF */
 	curr_des->txdes0 &= FTGMAC100_TXDES0_EDOTR;
@@ -509,15 +546,6 @@ static int ftgmac100_send(struct eth_device *dev, void *packet, int length)
 	/* start transmit */
 	writel(1, &ftgmac100->txpd);
 
-	/* wait for transfer to succeed */
-	start = get_timer(0);
-	while (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) {
-		if (get_timer(0) >= 5) {
-			debug("%s(): timed out\n", __func__);
-			return -1;
-		}
-	}
-
 	debug("%s(): packet sent\n", __func__);
 
 	priv->tx_index = (priv->tx_index + 1) % PKTBUFSTX;

--
1.7.9.5

#27 lore raw

PATCH v3 3/11 net: add Faraday FTMAC110 10/100Mbps ethernet support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTMAC110 10/100Mbps supports half-word data transfer for Linux. However it has a weird DMA alignment issue:

(1) Tx DMA Buffer Address:
1 bytes aligned: Invalid
2 bytes aligned: O.K
4 bytes aligned: O.K

(2) Rx DMA Buffer Address:
1 bytes aligned: Invalid
2 bytes aligned: O.K
4 bytes aligned: Invalid!!!

CC Joe Hershberger <[email protected]>
---
 drivers/net/Makefile   |    1 +
 drivers/net/ftmac110.c |  471 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/ftmac110.h |  126 +++++++++++++
 include/netdev.h       |    1 +
 4 files changed, 599 insertions(+)
 create mode 100644 drivers/net/ftmac110.c
 create mode 100644 drivers/net/ftmac110.h
drivers/net/Makefile +1 -0
index 786a656..0e23817 100644
@@ -46,6 +46,7 @@ COBJS-$(CONFIG_ETHOC) += ethoc.o
 COBJS-$(CONFIG_FEC_MXC) += fec_mxc.o
 COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o
 COBJS-$(CONFIG_FTGMAC100) += ftgmac100.o
+COBJS-$(CONFIG_FTMAC110) += ftmac110.o
 COBJS-$(CONFIG_FTMAC100) += ftmac100.o
 COBJS-$(CONFIG_GRETH) += greth.o
 COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
drivers/net/ftmac110.c new file +471 -0

471 lines not on this page · raw message

drivers/net/ftmac110.h new file +126 -0

126 lines not on this page · raw message

include/netdev.h +1 -0
index fd3e243..48c2fe5 100644
@@ -67,6 +67,7 @@ int fecmxc_initialize(bd_t *bis);
 int fecmxc_initialize_multi(bd_t *bis, int dev_id, int phy_id, uint32_t addr);
 int ftgmac100_initialize(bd_t *bits);
 int ftmac100_initialize(bd_t *bits);
+int ftmac110_initialize(bd_t *bits);
 int greth_initialize(bd_t *bis);
 void gt6426x_eth_initialize(bd_t *bis);
 int inca_switch_initialize(bd_t *bis);
Signature · 1 line
1.7.9.5
#28 lore raw

PATCH v3 3/11 net: add Faraday FTMAC110 10/100Mbps ethernet support

Quoted 1 line · Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

[snip]

drivers/net/ftmac110.c line 76

Quoted 3 lines
drivers/net/ftmac110.c new file +3 -0
+		| (phyaddr << PHYCR_ADDR_SHIFT)
+		| (phyreg  << PHYCR_REG_SHIFT)
+		| 0x30000000;

Magic number.

drivers/net/ftmac110.c line 80

Quoted 4 lines
drivers/net/ftmac110.c new file +4 -0
+
+	writel(tmp, &regs->phycr);
+
+	for (ts = get_timer(0); get_timer(ts) < 1000; ) {

Please define a TIMEOUT and use that insteadof 1000 all the time.

[snip]

drivers/net/ftmac110.c line 249

Quoted 8 lines
drivers/net/ftmac110.c new file +8 -0
+	/* interrupt at every packet transmit/receive */
+	writel(0x00001010, &regs->itc);
+	/* tx/rx poll interval=5.12us; rx_poll_cnt=1 */
+	writel(0x00000001, &regs->aptc);
+	/* rx fifo: high=1536, low=512 */
+	writel(0x00000390, &regs->dblac);
+	/* clear all interrupt status */
+	writel(0x000003FF, &regs->isr);

More magic numbers. Please fix globally. Thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130502/4b731b9a/attachment.pgp>
#29 lore raw

PATCH v3 3/11 net: add Faraday FTMAC110 10/100Mbps ethernet support

2013/5/3 Tom Rini <[email protected]>:

Quoted 10 lines · Kuo-Jung Su
Quoted 2 lines

From: Kuo-Jung Su <[email protected]>

[snip]

drivers/net/ftmac110.c line 76

Quoted 3 lines
drivers/net/ftmac110.c new file +3 -0
+             | (phyaddr << PHYCR_ADDR_SHIFT)
+             | (phyreg  << PHYCR_REG_SHIFT)
+             | 0x30000000;

Magic number.

It's the HW debug function, it would be removed at next version.

Quoted 7 lines

drivers/net/ftmac110.c line 80

Quoted 4 lines
drivers/net/ftmac110.c new file +4 -0
+
+     writel(tmp, &regs->phycr);
+
+     for (ts = get_timer(0); get_timer(ts) < 1000; ) {

Please define a TIMEOUT and use that insteadof 1000 all the time.

Got it, thanks

Quoted 10 lines

[snip]

drivers/net/ftmac110.c line 249

Quoted 8 lines
drivers/net/ftmac110.c new file +8 -0
+     /* interrupt at every packet transmit/receive */
+     writel(0x00001010, &regs->itc);
+     /* tx/rx poll interval=5.12us; rx_poll_cnt=1 */
+     writel(0x00000001, &regs->aptc);
+     /* rx fifo: high=1536, low=512 */
+     writel(0x00000390, &regs->dblac);
+     /* clear all interrupt status */
+     writel(0x000003FF, &regs->isr);
Quoted 2 lines

More magic numbers. Please fix globally. Thanks!

Got it, thanks

Quoted 2 lines

--
Tom

--
Best wishes,
Kuo-Jung Su

#30 lore raw

PATCH v4 1/1 net: add Faraday FTMAC110 10/100Mbps ethernet support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTMAC110 10/100Mbps supports half-word data transfer for Linux. However it has a weird DMA alignment issue:

(1) Tx DMA Buffer Address:
1 bytes aligned: Invalid
2 bytes aligned: O.K
4 bytes aligned: O.K

(2) Rx DMA Buffer Address:
1 bytes aligned: Invalid
2 bytes aligned: O.K
4 bytes aligned: Invalid!!!

CC Joe Hershberger <[email protected]>
CC Tom Rini <[email protected]>

---
Changes for v4:
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Use macro constants for timeout control
- Use only named constants for bit mask/shift and values
- Drop the magic number from mdio read/write.

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.
- Make a correction to multi-line comment style
- Use random MAC address while having trouble
to get one from environment variables.
- Add comments to timing control registers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- ftmac110: Remove debug codes.

 drivers/net/Makefile   |    1 +
 drivers/net/ftmac110.c |  473 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/ftmac110.h |  177 ++++++++++++++++++
 include/netdev.h       |    1 +
 4 files changed, 652 insertions(+)
 create mode 100644 drivers/net/ftmac110.c
 create mode 100644 drivers/net/ftmac110.h
drivers/net/Makefile +1 -0
index 786a656..0e23817 100644
@@ -46,6 +46,7 @@ COBJS-$(CONFIG_ETHOC) += ethoc.o
 COBJS-$(CONFIG_FEC_MXC) += fec_mxc.o
 COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o
 COBJS-$(CONFIG_FTGMAC100) += ftgmac100.o
+COBJS-$(CONFIG_FTMAC110) += ftmac110.o
 COBJS-$(CONFIG_FTMAC100) += ftmac100.o
 COBJS-$(CONFIG_GRETH) += greth.o
 COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
drivers/net/ftmac110.c new file +473 -0

473 lines not on this page · raw message

drivers/net/ftmac110.h new file +177 -0

177 lines not on this page · raw message

include/netdev.h +1 -0
index fd3e243..48c2fe5 100644
@@ -67,6 +67,7 @@ int fecmxc_initialize(bd_t *bis);
 int fecmxc_initialize_multi(bd_t *bis, int dev_id, int phy_id, uint32_t addr);
 int ftgmac100_initialize(bd_t *bits);
 int ftmac100_initialize(bd_t *bits);
+int ftmac110_initialize(bd_t *bits);
 int greth_initialize(bd_t *bis);
 void gt6426x_eth_initialize(bd_t *bis);
 int inca_switch_initialize(bd_t *bis);

--
1.7.9.5

#31 lore raw

PATCH v4 1/1 net: add Faraday FTMAC110 10/100Mbps ethernet support

Quoted 10 lines · Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTMAC110 10/100Mbps supports half-word data transfer for Linux. However it has a weird DMA alignment issue:

(1) Tx DMA Buffer Address:
1 bytes aligned: Invalid
2 bytes aligned: O.K
4 bytes aligned: O.K

Quoted 8 lines

(2) Rx DMA Buffer Address:
1 bytes aligned: Invalid
2 bytes aligned: O.K
4 bytes aligned: Invalid!!!

CC Joe Hershberger <[email protected]>
CC Tom Rini <[email protected]>

Applied, Thanks.
-Joe

#32 lore raw

PATCH v3 4/11 i2c: add Faraday FTI2C010 I2C controller support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTI2C010 is a multi-function I2C controller which supports both master and slave mode. This patch simplily implements the master mode only.

CC Heiko Schocher <[email protected]>
---
 drivers/i2c/Makefile   |    1 +
 drivers/i2c/fti2c010.c |  360 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/fti2c010.h |   71 ++++++++++
 3 files changed, 432 insertions(+)
 create mode 100644 drivers/i2c/fti2c010.c
 create mode 100644 drivers/i2c/fti2c010.h
drivers/i2c/Makefile +1 -0
index 5dbdbe3..ed2b8c0 100644
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_DW_I2C) += designware_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
+COBJS-$(CONFIG_FTI2C010) += fti2c010.o
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
 COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
drivers/i2c/fti2c010.c new file +360 -0

360 lines not on this page · raw message

drivers/i2c/fti2c010.h new file +71 -0

71 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#33 lore raw

PATCH v3 4/11 i2c: add Faraday FTI2C010 I2C controller support

Hello Su,

Quoted 8 lines · Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTI2C010 is a multi-function I2C controller which supports both master and slave mode. This patch simplily implements the master mode only.

CC Heiko Schocher <[email protected]>
Quoted 7 lines
---
 drivers/i2c/Makefile   |    1 +
 drivers/i2c/fti2c010.c |  360 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/fti2c010.h |   71 ++++++++++
 3 files changed, 432 insertions(+)
 create mode 100644 drivers/i2c/fti2c010.c
 create mode 100644 drivers/i2c/fti2c010.h

As this is in a patchserie I just Ack this patch:

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
#34 lore raw

PATCH v4 3/16 i2c: add Faraday FTI2C010 I2C controller support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTI2C010 is a multi-function I2C controller which supports both master and slave mode. This patch simplily implements the master mode only.

CC Heiko Schocher <[email protected]>

---
Changes for v4:
- Coding Style cleanup.
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Use macro constants for timeout control

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

 drivers/i2c/Makefile   |    1 +
 drivers/i2c/fti2c010.c |  371 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/fti2c010.h |   81 +++++++++++
 3 files changed, 453 insertions(+)
 create mode 100644 drivers/i2c/fti2c010.c
 create mode 100644 drivers/i2c/fti2c010.h
drivers/i2c/Makefile +1 -0
index 5dbdbe3..ed2b8c0 100644
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_DW_I2C) += designware_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
+COBJS-$(CONFIG_FTI2C010) += fti2c010.o
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
 COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
drivers/i2c/fti2c010.c new file +371 -0

371 lines not on this page · raw message

drivers/i2c/fti2c010.h new file +81 -0

81 lines not on this page · raw message

--
1.7.9.5

#35 lore raw

PATCH v4 3/16 i2c: add Faraday FTI2C010 I2C controller support

Hello Kuo-Jung,

Am 07.05.2013 08:32, schrieb Kuo-Jung Su:

Quoted 28 lines

From: Kuo-Jung Su <[email protected]>

Faraday FTI2C010 is a multi-function I2C controller which supports both master and slave mode. This patch simplily implements the master mode only.

CC Heiko Schocher <[email protected]>

---
Changes for v4:
- Coding Style cleanup.
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Use macro constants for timeout control

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

Quoted 6 lines
 drivers/i2c/Makefile   |    1 +
 drivers/i2c/fti2c010.c |  371 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/fti2c010.h |   81 +++++++++++
 3 files changed, 453 insertions(+)
 create mode 100644 drivers/i2c/fti2c010.c
 create mode 100644 drivers/i2c/fti2c010.h

As I posted the new i2c multibus/multiadapter framework:

http://lists.denx.de/pipermail/u-boot/2013-May/153452.html

maybe it is possible you can adapt your i2c driver based on this patches?

drivers/i2c/Makefile COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o · line 32

Quoted 9 lines
drivers/i2c/Makefile +1 -0
index 5dbdbe3..ed2b8c0 100644
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_DW_I2C) += designware_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
+COBJS-$(CONFIG_FTI2C010) += fti2c010.o

For the new framework this should be something like CONFIG_SYS_I2C_FTI2C010 ... and as I think, this name would be good also for the old framework.

drivers/i2c/Makefile COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o · line 35

Quoted 3 lines
drivers/i2c/Makefile +0 -0
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
 COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o

[...]

Rest of your patch looks good to me ...

bye,
Heiko

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

PATCH v4 3/16 i2c: add Faraday FTI2C010 I2C controller support

2013/5/7 Heiko Schocher <[email protected]>:

Quoted 38 lines

Hello Kuo-Jung,

Am 07.05.2013 08:32, schrieb Kuo-Jung Su:

Quoted 28 lines

From: Kuo-Jung Su <[email protected]>

Faraday FTI2C010 is a multi-function I2C controller which supports both master and slave mode. This patch simplily implements the master mode only.

CC Heiko Schocher <[email protected]>

---
Changes for v4:
- Coding Style cleanup.
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Use macro constants for timeout control

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

Quoted 6 lines
 drivers/i2c/Makefile   |    1 +
 drivers/i2c/fti2c010.c |  371 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/fti2c010.h |   81 +++++++++++
 3 files changed, 453 insertions(+)
 create mode 100644 drivers/i2c/fti2c010.c
 create mode 100644 drivers/i2c/fti2c010.h
Quoted 7 lines

As I posted the new i2c multibus/multiadapter framework:

http://lists.denx.de/pipermail/u-boot/2013-May/153452.html

maybe it is possible you can adapt your i2c driver based on this patches?

Sure, why not?
But it looks to me that the new i2c framework has not yet committed into the mainline u-boot git repository, so I'll only update the fti2c010 driver and postpone the board related stuff until the new i2c framework get accepted.

Quoted 5 lines
Quoted 5 lines
drivers/i2c/Makefile +0 -0
index 5dbdbe3..ed2b8c0 100644
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
Quoted 9 lines

drivers/i2c/Makefile COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o · line 32

Quoted 4 lines
drivers/i2c/Makefile +1 -0
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_DW_I2C) += designware_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
+COBJS-$(CONFIG_FTI2C010) += fti2c010.o

For the new framework this should be something like CONFIG_SYS_I2C_FTI2C010 ... and as I think, this name would be good also for the old framework.

Got it, thanks

Quoted 7 lines

drivers/i2c/Makefile COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o · line 35

Quoted 3 lines
drivers/i2c/Makefile +0 -0
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
 COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o

[...]

Rest of your patch looks good to me ...

I think it would be better to update the 'CONFIG_HARD_I2C' ifdef statement of the fti2c010 as bellow:

#if !defined(CONFIG_SYS_I2C) && !defined(CONFIG_HARD_I2C)
#error "fti2c010: either CONFIG_SYS_I2C or CONFIG_HARD_I2C would be defined" #endif

Quoted 5 lines

bye,
Heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

--
Best wishes,
Kuo-Jung Su

#37 lore raw

PATCH v4 3/16 i2c: add Faraday FTI2C010 I2C controller support

Hello Kuo-Jung,

Am 08.05.2013 03:51, schrieb Kuo-Jung Su:

Quoted 13 lines

2013/5/7 Heiko Schocher <[email protected]>:

Quoted 12 lines

Hello Kuo-Jung,

Am 07.05.2013 08:32, schrieb Kuo-Jung Su:

Quoted 9 lines

From: Kuo-Jung Su <[email protected]>

Faraday FTI2C010 is a multi-function I2C controller which supports both master and slave mode. This patch simplily implements the master mode only.

CC Heiko Schocher <[email protected]>

---

[...]

Quoted 11 lines
Quoted 11 lines
Quoted 6 lines
 drivers/i2c/Makefile   |    1 +
 drivers/i2c/fti2c010.c |  371 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/fti2c010.h |   81 +++++++++++
 3 files changed, 453 insertions(+)
 create mode 100644 drivers/i2c/fti2c010.c
 create mode 100644 drivers/i2c/fti2c010.h

As I posted the new i2c multibus/multiadapter framework:

http://lists.denx.de/pipermail/u-boot/2013-May/153452.html

Quoted 8 lines
Quoted 3 lines

maybe it is possible you can adapt your i2c driver based on this patches?

Sure, why not?
But it looks to me that the new i2c framework has not yet committed into the mainline u-boot git repository, so I'll only update the fti2c010 driver and postpone the board related stuff until the new i2c framework get accepted.

Ok, thanks! Hope to get the new framework ASAP into mainline.

[...]

Quoted 8 lines
Quoted 7 lines
Quoted 3 lines

COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o

[...]

Rest of your patch looks good to me ...

Quoted 6 lines

I think it would be better to update the 'CONFIG_HARD_I2C' ifdef statement of the fti2c010 as bellow:

#if !defined(CONFIG_SYS_I2C) && !defined(CONFIG_HARD_I2C)
#error "fti2c010: either CONFIG_SYS_I2C or CONFIG_HARD_I2C would be defined" #endif

No! If you convert to the new i2c framework, you not longer need the old (CONFIG_HARD_I2C) style. If all i2c drivers are ported to the new framework, CONFIG_HARD_I2C will be dropped. So please delete the CONFIG_HARD_I2C define completely when switching to the new framework. Also the CONFIG_I2C_MULTI_BUS define is no longer needed.

bye,
Heiko

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

PATCH v4 3/16 i2c: add Faraday FTI2C010 I2C controller support

2013/5/8 Heiko Schocher <[email protected]>:

Quoted 56 lines

Hello Kuo-Jung,

Am 08.05.2013 03:51, schrieb Kuo-Jung Su:

Quoted 13 lines

2013/5/7 Heiko Schocher <[email protected]>:

Quoted 12 lines

Hello Kuo-Jung,

Am 07.05.2013 08:32, schrieb Kuo-Jung Su:

Quoted 9 lines

From: Kuo-Jung Su <[email protected]>

Faraday FTI2C010 is a multi-function I2C controller which supports both master and slave mode. This patch simplily implements the master mode only.

CC Heiko Schocher <[email protected]>

---

[...]

Quoted 11 lines
Quoted 11 lines
Quoted 6 lines
 drivers/i2c/Makefile   |    1 +
 drivers/i2c/fti2c010.c |  371 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/fti2c010.h |   81 +++++++++++
 3 files changed, 453 insertions(+)
 create mode 100644 drivers/i2c/fti2c010.c
 create mode 100644 drivers/i2c/fti2c010.h

As I posted the new i2c multibus/multiadapter framework:

http://lists.denx.de/pipermail/u-boot/2013-May/153452.html

Quoted 8 lines
Quoted 3 lines

maybe it is possible you can adapt your i2c driver based on this patches?

Sure, why not?
But it looks to me that the new i2c framework has not yet committed into the mainline u-boot git repository, so I'll only update the fti2c010 driver and postpone the board related stuff until the new i2c framework get accepted.

Ok, thanks! Hope to get the new framework ASAP into mainline.

[...]

Quoted 8 lines
Quoted 7 lines
Quoted 3 lines

COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o

[...]

Rest of your patch looks good to me ...

Quoted 6 lines

I think it would be better to update the 'CONFIG_HARD_I2C' ifdef statement of the fti2c010 as bellow:

#if !defined(CONFIG_SYS_I2C) && !defined(CONFIG_HARD_I2C)
#error "fti2c010: either CONFIG_SYS_I2C or CONFIG_HARD_I2C would be defined" #endif

Quoted 6 lines

No! If you convert to the new i2c framework, you not longer need the old (CONFIG_HARD_I2C) style. If all i2c drivers are ported to the new framework, CONFIG_HARD_I2C will be dropped. So please delete the CONFIG_HARD_I2C define completely when switching to the new framework. Also the CONFIG_I2C_MULTI_BUS define is no longer needed.

Got it, thanks.
So I'll leave the CONFIG_HARD_I2C & CONFIG_I2C_MULTI_BUS ifdef statement untouched until the new i2c framework get accepted.

Quoted 5 lines

bye,
Heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

--
Best wishes,
Kuo-Jung Su

#39 lore raw

PATCH v5 1/1 i2c: add Faraday FTI2C010 I2C controller support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTI2C010 is a multi-function I2C controller which supports both master and slave mode. This patch simplily implements the master mode only.

CC Heiko Schocher <[email protected]>

---
Changes for v5:
- Coding Style cleanup.
- Use CONFIG_SYS_I2C_SPEED for default speed.
- Put a permanent 100 ms delay to chip reset.
- Makefile: CONFIG_FTI2C010 -> CONFIG_SYS_I2C_FTI2C010

Changes for v4:
- Coding Style cleanup.
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Use macro constants for timeout control

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

 drivers/i2c/Makefile   |    1 +
 drivers/i2c/fti2c010.c |  369 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/fti2c010.h |   81 +++++++++++
 3 files changed, 451 insertions(+)
 create mode 100644 drivers/i2c/fti2c010.c
 create mode 100644 drivers/i2c/fti2c010.h
drivers/i2c/Makefile +1 -0
index 5dbdbe3..9654607 100644
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_DW_I2C) += designware_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
+COBJS-$(CONFIG_SYS_I2C_FTI2C010) += fti2c010.o
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
 COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
drivers/i2c/fti2c010.c new file +369 -0

369 lines not on this page · raw message

drivers/i2c/fti2c010.h new file +81 -0

81 lines not on this page · raw message

--
1.7.9.5

#40 lore raw

PATCH v3 5/11 spi: add Faraday FTSPI010 SPI controller support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

The Faraday FTSSP010 is a multi-function controller which supports I2S/SPI/SSP/AC97/SPDIF.
This patch simpily implements the SPI mode only. BTW the DMA and CS/Clock control logic has been altered since revision 1.19.0. So this patch would 1st detects the revision id of the underlying chip, and then switch to the corresponding control routines.

---
 drivers/spi/Makefile        |    1 +
 drivers/spi/ftssp010_spi.c  |  385 +++++++++++++++++++++++++++++++++++++++++++
 drivers/spi/ftssp010_spi.h  |   86 ++++++++++
 include/faraday/ftgpio010.h |   25 +++
 4 files changed, 497 insertions(+)
 create mode 100644 drivers/spi/ftssp010_spi.c
 create mode 100644 drivers/spi/ftssp010_spi.h
 create mode 100644 include/faraday/ftgpio010.h
drivers/spi/Makefile +1 -0
index d08609e..947d60e 100644
@@ -38,6 +38,7 @@ COBJS-$(CONFIG_BFIN_SPI6XX) += bfin_spi6xx.o
 COBJS-$(CONFIG_CF_SPI) += cf_spi.o
 COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o
 COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
+COBJS-$(CONFIG_FTSSP010_SPI) += ftssp010_spi.o
 COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
 COBJS-$(CONFIG_ICH_SPI) +=  ich.o
 COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
drivers/spi/ftssp010_spi.c new file +385 -0

385 lines not on this page · raw message

drivers/spi/ftssp010_spi.h new file +86 -0

86 lines not on this page · raw message

include/faraday/ftgpio010.h new file +25 -0
new file mode 100644
index 0000000..2dc45f2
@@ -0,0 +1,25 @@
+/*
+ * Faraday GPIO Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef __FTGPIO010_H
+#define __FTGPIO010_H
+
+struct ftgpio010_regs {
+	uint32_t out;     /* 0x00: Data Output */
+	uint32_t in;      /* 0x04: Data Input */
+	uint32_t dir;     /* 0x08: Pin Direction */
+	uint32_t bypass;  /* 0x0c: Bypass */
+	uint32_t set;     /* 0x10: Data Set */
+	uint32_t clr;     /* 0x14: Data Clear */
+	uint32_t pull_up; /* 0x18: Pull-Up Enabled */
+	uint32_t pull_st; /* 0x1c: Pull State (0=pull-down, 1=pull-up) */
+};
+
+#endif /* __FTGPIO010_H */
Signature · 1 line
1.7.9.5
#41 lore raw

PATCH v4 1/1 spi: add Faraday FTSPI010 SPI controller support

From: Kuo-Jung Su <[email protected]>

The Faraday FTSSP010 is a multi-function controller which supports I2S/SPI/SSP/AC97/SPDIF. However This patch implements only the SPI mode.

NOTE:
The DMA and CS/Clock control logic has been altered since hardware revision 1.19.0. So this patch would first detects the revision id of the underlying chip, and then switch to the corresponding software control routines.

---
Changes for v4:
- Coding Style cleanup.
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Use macro constants for timeout control

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

 drivers/spi/Makefile        |    1 +
 drivers/spi/ftssp010_spi.c  |  385 +++++++++++++++++++++++++++++++++++++++++++
 drivers/spi/ftssp010_spi.h  |   86 ++++++++++
 include/faraday/ftgpio010.h |   25 +++
 4 files changed, 497 insertions(+)
 create mode 100644 drivers/spi/ftssp010_spi.c
 create mode 100644 drivers/spi/ftssp010_spi.h
 create mode 100644 include/faraday/ftgpio010.h
drivers/spi/Makefile +1 -0
index d08609e..947d60e 100644
@@ -38,6 +38,7 @@ COBJS-$(CONFIG_BFIN_SPI6XX) += bfin_spi6xx.o
 COBJS-$(CONFIG_CF_SPI) += cf_spi.o
 COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o
 COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
+COBJS-$(CONFIG_FTSSP010_SPI) += ftssp010_spi.o
 COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
 COBJS-$(CONFIG_ICH_SPI) +=  ich.o
 COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
drivers/spi/ftssp010_spi.c new file +385 -0

385 lines not on this page · raw message

drivers/spi/ftssp010_spi.h new file +86 -0

86 lines not on this page · raw message

include/faraday/ftgpio010.h new file +25 -0
new file mode 100644
index 0000000..2dc45f2
@@ -0,0 +1,25 @@
+/*
+ * Faraday GPIO Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef __FTGPIO010_H
+#define __FTGPIO010_H
+
+struct ftgpio010_regs {
+	uint32_t out;     /* 0x00: Data Output */
+	uint32_t in;      /* 0x04: Data Input */
+	uint32_t dir;     /* 0x08: Pin Direction */
+	uint32_t bypass;  /* 0x0c: Bypass */
+	uint32_t set;     /* 0x10: Data Set */
+	uint32_t clr;     /* 0x14: Data Clear */
+	uint32_t pull_up; /* 0x18: Pull-Up Enabled */
+	uint32_t pull_st; /* 0x1c: Pull State (0=pull-down, 1=pull-up) */
+};
+
+#endif /* __FTGPIO010_H */

--
1.7.9.5

#42 lore raw

PATCH v4 1/1 spi: add Faraday FTSPI010 SPI controller support

Hi,

Few comments, please get back your inputs.

Use commit header as "spi: ftssp010_spi: "

Quoted 53 lines · Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

The Faraday FTSSP010 is a multi-function controller which supports I2S/SPI/SSP/AC97/SPDIF. However This patch implements only the SPI mode.

NOTE:
The DMA and CS/Clock control logic has been altered since hardware revision 1.19.0. So this patch would first detects the revision id of the underlying chip, and then switch to the corresponding software control routines.

---
Changes for v4:
- Coding Style cleanup.
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Use macro constants for timeout control

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

  drivers/spi/Makefile        |    1 +
  drivers/spi/ftssp010_spi.c  |  385 +++++++++++++++++++++++++++++++++++++++++++
  drivers/spi/ftssp010_spi.h  |   86 ++++++++++
  include/faraday/ftgpio010.h |   25 +++
  4 files changed, 497 insertions(+)

create mode 100644 drivers/spi/ftssp010_spi.c
create mode 100644 drivers/spi/ftssp010_spi.h
create mode 100644 include/faraday/ftgpio010.h

--
1.7.9.5

drivers/spi/Makefile +0 -0
index d08609e..947d60e 100644

drivers/spi/Makefile COBJS-$(CONFIG_BFIN_SPI6XX) += bfin_spi6xx.o · line 41

Quoted 4 lines
drivers/spi/Makefile +1 -0
@@ -38,6 +38,7 @@ COBJS-$(CONFIG_BFIN_SPI6XX) += bfin_spi6xx.o
  COBJS-$(CONFIG_CF_SPI) += cf_spi.o
  COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o
  COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
+COBJS-$(CONFIG_FTSSP010_SPI) += ftssp010_spi.o

Place into in alphabetic order, to make sure some kind of coding style.

Quoted 9 lines
drivers/spi/Makefile +0 -0
  COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
  COBJS-$(CONFIG_ICH_SPI) +=  ich.o
  COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
drivers/spi/ftssp010_spi.c new file +0 -0
new file mode 100644
index 0000000..d401ecc

drivers/spi/ftssp010_spi.c line 9

Quoted 9 lines
drivers/spi/ftssp010_spi.c new file +9 -0
@@ -0,0 +1,385 @@
+/*
+ * Faraday Multi-function Controller - SPI Mode
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */

Little bit uneasy with the above license note, any reason for this GPL w.r.t your company style. refer license note on drivers/spi/exynos_spi.c

drivers/spi/ftssp010_spi.c line 15

Quoted 6 lines
drivers/spi/ftssp010_spi.c new file +6 -0
+
+#include <common.h>
+#include <asm/io.h>
+#include <spi.h>
+#include <malloc.h>
+#include <faraday/ftgpio010.h>

Does this include file is an arch' specific, means struct ftgpio010_regs is used by some other drivers on ur board?

drivers/spi/ftssp010_spi.c line 16

Quoted 1 line
drivers/spi/ftssp010_spi.c new file +1 -0
+#include "ftssp010_spi.h"

Please don't use extra include file, use the same structure's in driver it self, IMHO.

drivers/spi/ftssp010_spi.c line 20

Quoted 4 lines
drivers/spi/ftssp010_spi.c new file +4 -0
+
+#define CFG_PIO_TIMEOUT (CONFIG_SYS_HZ >> 3) /* 125 ms */
+#define CFG_CS_TIMEOUT  (CONFIG_SYS_HZ >> 2) /* 250 ms */
+

----- TAG+

Quoted 43 lines
drivers/spi/ftssp010_spi.c new file +43 -0
+struct ftssp010_chip {
+	void __iomem *regs;
+	uint32_t fifo;
+	uint32_t rev;
+	uint32_t div;
+	uint32_t mode;
+
+	struct {
+		void __iomem *regs;
+		uint32_t      pin;
+	} gpio;
+};
+
+static struct ftssp010_chip chip_list[] = {
+#ifdef CONFIG_FTSSP010_BASE
+	{
+		.regs = (void __iomem *)CONFIG_FTSSP010_BASE,
+# ifdef CONFIG_FTSSP010_GPIO_BASE
+		.gpio = {
+			(void __iomem *)CONFIG_FTSSP010_GPIO_BASE,
+			CONFIG_FTSSP010_GPIO_PIN
+		},
+# endif
+	},
+#endif /* #ifdef CONFIG_FTSSP010_BASE */
+#ifdef CONFIG_FTSSP010_BASE1
+	{ .regs = (void __iomem *)CONFIG_FTSSP010_BASE1, },
+# ifdef CONFIG_FTSSP010_GPIO_BASE1
+		.gpio = {
+			(void __iomem *)CONFIG_FTSSP010_GPIO_BASE1,
+			CONFIG_FTSSP010_GPIO_PIN1
+		},
+# endif
+#endif
+#ifdef CONFIG_FTSSP010_BASE2
+	{ .regs = (void __iomem *)CONFIG_FTSSP010_BASE2, },
+# ifdef CONFIG_FTSSP010_GPIO_BASE2
+		.gpio = {
+			(void __iomem *)CONFIG_FTSSP010_GPIO_BASE2,
+			CONFIG_FTSSP010_GPIO_PIN2
+		},
+# endif
+#endif

drivers/spi/ftssp010_spi.c line 73

Quoted 10 lines
drivers/spi/ftssp010_spi.c new file +10 -0
+#ifdef CONFIG_FTSSP010_BASE3
+	{ .regs = (void __iomem *)CONFIG_FTSSP010_BASE3, },
+# ifdef CONFIG_FTSSP010_GPIO_BASE3
+		.gpio = {
+			(void __iomem *)CONFIG_FTSSP010_GPIO_BASE3,
+			CONFIG_FTSSP010_GPIO_PIN3
+		},
+# endif
+#endif
+};

---- TAG-

TAG+ ... TAG- this type of assignment is old way.
please use the structure macro assignment instead of void __iomem *

ex:
#define CONFIG_MY_REG_BASE 0xF1000000

struct my_reg {
	u32 r1;
	u32 r2;
	u32 r3;
	u32 r4;
}

#define my_reg_base ((struct my_reg *) CONFIG_MY_REG_BASE)

then use readl(&my_reg_base->r3);

see the example usage on
http://patchwork.ozlabs.org/patch/246468/
https://github.com/Xilinx/u-boot-xlnx/blob/master/drivers/spi/zynq_qspips.c

Quoted 216 lines
drivers/spi/ftssp010_spi.c new file +216 -0
+
+static inline int ftssp010_wait_tx(struct ftssp010_chip *chip)
+{
+	struct ftssp010_regs __iomem *regs = chip->regs;
+	int ret = -1;
+	ulong ts;
+
+	for (ts = get_timer(0); get_timer(ts) < CFG_PIO_TIMEOUT; ) {
+		if (!(readl(&regs->sr) & SR_TFNF))
+			continue;
+		ret = 0;
+		break;
+	}
+
+	if (ret)
+		printf("ftssp010: tx timeout\n");
+
+	return ret;
+}
+
+static inline int ftssp010_wait_rx(struct ftssp010_chip *chip)
+{
+	struct ftssp010_regs __iomem *regs = chip->regs;
+	int ret = -1;
+	ulong ts;
+
+	for (ts = get_timer(0); get_timer(ts) < CFG_PIO_TIMEOUT; ) {
+		if (!SR_RFVE(readl(&regs->sr)))
+			continue;
+		ret = 0;
+		break;
+	}
+
+	if (ret)
+		printf("ftssp010: rx timeout\n");
+
+	return ret;
+}
+
+static int ftssp010_spi_work_transfer_v1_19(struct ftssp010_chip *chip,
+	const void *tx_buf, void *rx_buf, int len, uint flags)
+{
+	struct ftssp010_regs __iomem *regs = chip->regs;
+	const uint8_t *txb = tx_buf;
+	uint8_t       *rxb = rx_buf;
+
+	while (len > 0) {
+		int i, depth = min(chip->fifo >> 2, len);
+		uint32_t xmsk = 0;
+
+		if (tx_buf) {
+			for (i = 0; i < depth; ++i) {
+				ftssp010_wait_tx(chip);
+				writel(*txb++, &regs->dr);
+			}
+			xmsk |= CR2_TXEN | CR2_TXDOE;
+			if ((readl(&regs->cr[2]) & xmsk) != xmsk)
+				setbits_le32(&regs->cr[2], xmsk);
+		}
+		if (rx_buf) {
+			xmsk |= CR2_RXEN;
+			if ((readl(&regs->cr[2]) & xmsk) != xmsk)
+				setbits_le32(&regs->cr[2], xmsk);
+			for (i = 0; i < depth; ++i) {
+				ftssp010_wait_rx(chip);
+				*rxb++ = (uint8_t)readl(&regs->dr);
+			}
+		}
+
+		len -= depth;
+	}
+
+	return 0;
+}
+
+static int ftssp010_spi_work_transfer(struct ftssp010_chip *chip,
+	const void *tx_buf, void *rx_buf, int len, uint flags)
+{
+	struct ftssp010_regs __iomem *regs = chip->regs;
+	const uint8_t *txb = tx_buf;
+	uint8_t       *rxb = rx_buf;
+
+	while (len > 0) {
+		int i, depth = min(chip->fifo >> 2, len);
+		uint32_t tmp;
+
+		for (i = 0; i < depth; ++i) {
+			ftssp010_wait_tx(chip);
+			writel(txb ? (*txb++) : 0, &regs->dr);
+		}
+		for (i = 0; i < depth; ++i) {
+			ftssp010_wait_rx(chip);
+			tmp = readl(&regs->dr);
+			if (rxb)
+				*rxb++ = (uint8_t)tmp;
+		}
+
+		len -= depth;
+	}
+
+	return 0;
+}
+
+/*
+ * Determine if a SPI chipselect is valid.
+ * This function is provided by the board if the low-level SPI driver
+ * needs it to determine if a given chipselect is actually valid.
+ *
+ * Returns: 1 if bus:cs identifies a valid chip on this board, 0
+ * otherwise.
+ */
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+	int ret = 0;
+	struct ftssp010_chip *chip;
+	struct ftssp010_regs __iomem *regs;
+	uint32_t txfifo, rxfifo;
+
+	if (bus >= ARRAY_SIZE(chip_list))
+		return ret;
+
+	chip = chip_list + bus;
+	regs = chip->regs;
+	chip->rev = readl(&regs->revr);
+	txfifo = FEAR_TXFIFO(readl(&regs->fear));
+	rxfifo = FEAR_RXFIFO(readl(&regs->fear));
+	chip->fifo = min(txfifo, rxfifo);
+
+	debug("ftssp010: rev=0x%08X, fifo=%d\n", chip->rev, chip->fifo);
+
+	if (chip->rev >= 0x00011900) {
+		if (cs < 4)
+			ret = 1;
+	} else if (!cs) {
+		struct ftgpio010_regs *gpio = chip->gpio.regs;
+		uint32_t mask = BIT_MASK(chip->gpio.pin);
+
+		if (gpio) {
+			/* setup gpio pin as an output pin */
+			setbits_le32(&gpio->dir, mask);
+			ret = 1;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * Activate a SPI chipselect.
+ * This function is provided by the board code when using a driver
+ * that can't control its chipselects automatically (e.g.
+ * common/soft_spi.c). When called, it should activate the chip select
+ * to the device identified by "slave".
+ */
+void spi_cs_activate(struct spi_slave *slave)
+{
+	struct ftssp010_chip *chip = chip_list + slave->bus;
+	struct ftssp010_regs __iomem *regs = chip->regs;
+
+	/* cs pull low */
+	if (chip->rev >= 0x00011900) {
+		writel((slave->cs << 10) | CR2_SSPEN | CR2_TXFCLR
+			| CR2_RXFCLR, &regs->cr[2]);
+	} else {
+		struct ftgpio010_regs *gpio = chip->gpio.regs;
+		uint32_t mask = BIT_MASK(chip->gpio.pin);
+
+		if (gpio)
+			setbits_le32(&gpio->clr, mask);
+	}
+	udelay_masked(1);
+}
+
+/*
+ * Deactivate a SPI chipselect.
+ * This function is provided by the board code when using a driver
+ * that can't control its chipselects automatically (e.g.
+ * common/soft_spi.c). When called, it should deactivate the chip
+ * select to the device identified by "slave".
+ */
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+	struct ftssp010_chip *chip = chip_list + slave->bus;
+	struct ftssp010_regs __iomem *regs = chip->regs;
+	ulong ts;
+
+	/* wait until device idle */
+	for (ts = get_timer(0); get_timer(ts) < CFG_CS_TIMEOUT; ) {
+		if (readl(&regs->sr) & SR_BUSY)
+			continue;
+		break;
+	}
+	if (readl(&regs->sr) & SR_BUSY)
+		printf("ftspi010: busy timeout at cs deactivate\n");
+
+	/* cs pull high */
+	if (chip->rev >= 0x00011900) {
+		writel((slave->cs << 10) | CR2_FS, &regs->cr[2]);
+	} else {
+		struct ftgpio010_regs *gpio = chip->gpio.regs;
+		uint32_t mask = BIT_MASK(chip->gpio.pin);
+
+		if (gpio)
+			setbits_le32(&gpio->set, mask);
+	}
+	udelay_masked(1);
+}
+
+void spi_init(void)
+{
+}
+
+struct spi_slave *spi_setup_slave(uint bus, uint cs, uint max_hz, uint mode)
+{
+	uint32_t clk, div;
+	struct spi_slave *ss;

drivers/spi/ftssp010_spi.c line 299

Quoted 10 lines
drivers/spi/ftssp010_spi.c new file +10 -0
+	struct ftssp010_chip *chip;
+
+	if (!spi_cs_is_valid(bus, cs))
+		return NULL;
+
+	if (mode != SPI_MODE_0) {
+		printf("ftssp010: MODE%d is not supported\n", mode);
+		return NULL;
+	}
+

----- TAG+

drivers/spi/ftssp010_spi.c line 305

Quoted 6 lines
drivers/spi/ftssp010_spi.c new file +6 -0
+	ss = malloc(sizeof(struct spi_slave));
+	if (!ss)
+		return NULL;
+
+	ss->bus = bus;
+	ss->cs  = cs;

----- TAG-
Pleas use spi_alloc_slave() instead of malloc()
see the sample code on "drivers/spi/exynos_spi.c"

Quoted 70 lines
drivers/spi/ftssp010_spi.c new file +70 -0
+
+#ifdef CONFIG_FTSSP010_SCLK
+	clk = CONFIG_FTSSP010_SCLK;
+#else
+	clk = clk_get_rate("SSP");
+#endif
+	if (max_hz > 0) {
+		for (div = 0; div < 0xFFFF; ++div) {
+			if ((clk / (2 * (div + 1))) <= max_hz)
+				break;
+		}
+	} else {
+		div = 7;
+	}
+
+	chip = chip_list + bus;
+	chip->div  = div;
+	chip->mode = mode;
+
+	debug("ftssp010: bus=%d, hz=%u\n", bus, (clk / (2 * (div + 1))));
+
+	return ss;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+	free(slave);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+	struct ftssp010_chip *chip = chip_list + slave->bus;
+	struct ftssp010_regs __iomem *regs = chip->regs;
+
+	writel(CR1_SDL(8) | CR1_CLKDIV(chip->div), &regs->cr[1]);
+
+	if (chip->rev >= 0x00011900) {
+		writel(CR0_OPM_MASTER | CR0_FFMT_SPI | CR0_FSPO | CR0_FLASH,
+			&regs->cr[0]);
+		writel(CR2_TXFCLR | CR2_RXFCLR,
+			&regs->cr[2]);
+	} else {
+		writel(CR0_OPM_MASTER | CR0_FFMT_SPI | CR0_FSPO,
+			&regs->cr[0]);
+		writel(CR2_TXFCLR | CR2_RXFCLR | CR2_SSPEN | CR2_TXDOE,
+			&regs->cr[2]);
+	}
+
+	spi_cs_deactivate(slave);
+
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+	struct ftssp010_chip *chip = chip_list + slave->bus;
+	struct ftssp010_regs __iomem *regs = chip->regs;
+
+	writel(0, &regs->cr[2]);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+			 const void *dout, void *din, unsigned long flags)
+{
+	struct ftssp010_chip *chip = chip_list + slave->bus;
+	uint32_t len = bitlen >> 3;
+
+	if (flags & SPI_XFER_BEGIN)
+		spi_cs_activate(slave);
+

drivers/spi/ftssp010_spi.c line 385

Quoted 10 lines
drivers/spi/ftssp010_spi.c new file +10 -0
+	if (chip->rev >= 0x00011900)
+		ftssp010_spi_work_transfer_v1_19(chip, dout, din, len, flags);
+	else
+		ftssp010_spi_work_transfer(chip, dout, din, len, flags);
+
+	if (flags & SPI_XFER_END)
+		spi_cs_deactivate(slave);
+
+	return 0;
+}

---- TAG+

Quoted 82 lines
drivers/spi/ftssp010_spi.h new file +76 -0
new file mode 100644
index 0000000..5258edc
@@ -0,0 +1,86 @@
+/*
+ * Faraday Multi-function Controller - SPI Mode
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef _FTSSP010_H
+#define _FTSSP010_H
+
+/* FTSSP010 HW Registers */
+struct ftssp010_regs {
+	uint32_t cr[3];/* control register */
+	uint32_t sr;   /* status register */
+	uint32_t icr;  /* interrupt control register */
+	uint32_t isr;  /* interrupt status register */
+	uint32_t dr;   /* data register */
+	uint32_t rsvd[17];
+	uint32_t revr; /* revision register */
+	uint32_t fear; /* feature register */
+};
+
+/* Control Register 0  */
+#define CR0_FFMT_MASK       (7 << 12)
+#define CR0_FFMT_SSP        (0 << 12)
+#define CR0_FFMT_SPI        (1 << 12)
+#define CR0_FFMT_MICROWIRE  (2 << 12)
+#define CR0_FFMT_I2S        (3 << 12)
+#define CR0_FFMT_AC97       (4 << 12)
+#define CR0_FLASH           (1 << 11)
+#define CR0_FSDIST(x)       (((x) & 0x03) << 8)
+#define CR0_LBM             (1 << 7)  /* Loopback mode */
+#define CR0_LSB             (1 << 6)  /* LSB first */
+#define CR0_FSPO            (1 << 5)  /* Frame sync atcive low */
+#define CR0_FSJUSTIFY       (1 << 4)
+#define CR0_OPM_SLAVE       (0 << 2)
+#define CR0_OPM_MASTER      (3 << 2)
+#define CR0_OPM_I2S_MSST    (3 << 2)  /* Master stereo mode */
+#define CR0_OPM_I2S_MSMO    (2 << 2)  /* Master mono mode */
+#define CR0_OPM_I2S_SLST    (1 << 2)  /* Slave stereo mode */
+#define CR0_OPM_I2S_SLMO    (0 << 2)  /* Slave mono mode */
+#define CR0_SCLKPO          (1 << 1)  /* SCLK Remain HIGH */
+#define CR0_SCLKPH          (1 << 0)  /* Half CLK cycle */
+
+/* Control Register 1 */
+
+#define CR1_PDL(x)          (((x) & 0xff) << 24) /* padding length */
+#define CR1_SDL(x)          ((((x) - 1) & 0x1f) << 16) /* data length */
+#define CR1_CLKDIV(x)       ((x) & 0xffff) /*  clk divider */
+
+/* Control Register 2 */
+#define CR2_FSOS(x)         (((x) & 0x03) << 10)	/* FS/CS Select */
+#define CR2_FS              (1 << 9)	/* FS/CS Signal Level */
+#define CR2_TXEN            (1 << 8)	/* Tx Enable */
+#define CR2_RXEN            (1 << 7)	/* Rx Enable */
+#define CR2_SSPRST          (1 << 6)	/* SSP reset */
+#define CR2_TXFCLR          (1 << 3)	/* TX FIFO Clear */
+#define CR2_RXFCLR          (1 << 2)	/* RX FIFO Clear */
+#define CR2_TXDOE           (1 << 1)	/* TX Data Output Enable */
+#define CR2_SSPEN           (1 << 0)	/* SSP Enable */
+
+/*
+ * Status Register
+ */
+#define SR_RFF       (1 << 0) /* receive FIFO full */
+#define SR_TFNF      (1 << 1) /* transmit FIFO not full */
+#define SR_BUSY      (1 << 2) /* bus is busy */
+#define SR_RFVE(reg) (((reg) >> 4) & 0x1f)  /* receive  FIFO valid entries */
+#define SR_TFVE(reg) (((reg) >> 12) & 0x1f) /* transmit FIFO valid entries */
+
+/*
+ * Feature Register
+ */

drivers/spi/ftssp010_spi.h line 86

Quoted 10 lines
drivers/spi/ftssp010_spi.h new file +10 -0
+#define FEAR_WIDTH(reg)  ((((reg) >>  0) & 0xff) + 1)
+#define FEAR_RXFIFO(reg) ((((reg) >>  8) & 0xff) + 1)
+#define FEAR_TXFIFO(reg) ((((reg) >> 16) & 0xff) + 1)
+#define FEAR_AC97        (1 << 24)
+#define FEAR_I2S         (1 << 25)
+#define FEAR_SPI_MWR     (1 << 26)
+#define FEAR_SSP         (1 << 27)
+#define FEAR_SPDIF       (1 << 28)
+
+#endif /* EOF */

---- TAG-

Please use the same defination on driver code itself.

Thanks,
Jagan.

#43 lore raw

PATCH v4 1/1 spi: add Faraday FTSPI010 SPI controller support

2013/6/13 Jagan Teki <[email protected]>:

Quoted 6 lines

Hi,

Few comments, please get back your inputs.

Use commit header as "spi: ftssp010_spi: "

Got it, thanks

Quoted 54 lines · Kuo-Jung Su
Quoted 52 lines

From: Kuo-Jung Su <[email protected]>

The Faraday FTSSP010 is a multi-function controller which supports I2S/SPI/SSP/AC97/SPDIF. However This patch implements only the SPI mode.

NOTE:
The DMA and CS/Clock control logic has been altered since hardware revision 1.19.0. So this patch would first detects the revision id of the underlying chip, and then switch to the corresponding software control routines.

---
Changes for v4:
- Coding Style cleanup.
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Use macro constants for timeout control

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro
constants.
- Replace BIT() with BIT_MASK().

  drivers/spi/Makefile        |    1 +
  drivers/spi/ftssp010_spi.c  |  385
+++++++++++++++++++++++++++++++++++++++++++
  drivers/spi/ftssp010_spi.h  |   86 ++++++++++
  include/faraday/ftgpio010.h |   25 +++
  4 files changed, 497 insertions(+)

create mode 100644 drivers/spi/ftssp010_spi.c
create mode 100644 drivers/spi/ftssp010_spi.h
create mode 100644 include/faraday/ftgpio010.h

--
1.7.9.5

Quoted 14 lines

drivers/spi/Makefile COBJS-$(CONFIG_BFIN_SPI6XX) += bfin_spi6xx.o · line 41

Quoted 9 lines
drivers/spi/Makefile +1 -0
index d08609e..947d60e 100644
@@ -38,6 +38,7 @@ COBJS-$(CONFIG_BFIN_SPI6XX) += bfin_spi6xx.o
  COBJS-$(CONFIG_CF_SPI) += cf_spi.o
  COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o
  COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
+COBJS-$(CONFIG_FTSSP010_SPI) += ftssp010_spi.o

Place into in alphabetic order, to make sure some kind of coding style.

Got it, thanks

Quoted 14 lines
Quoted 14 lines
drivers/spi/Makefile +0 -0
  COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
  COBJS-$(CONFIG_ICH_SPI) +=  ich.o
  COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
drivers/spi/ftssp010_spi.c new file +5 -0
new file mode 100644
index 0000000..d401ecc
@@ -0,0 +1,385 @@
+/*
+ * Faraday Multi-function Controller - SPI Mode
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
Quoted 9 lines
Quoted 5 lines
drivers/spi/ftssp010_spi.c new file +3 -0
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for

details.
+ */

Little bit uneasy with the above license note, any reason for this GPL w.r.t your company style. refer license note on drivers/spi/exynos_spi.c

Got it, thanks

Quoted 11 lines

drivers/spi/ftssp010_spi.c line 15

Quoted 7 lines
drivers/spi/ftssp010_spi.c new file +6 -0
+
+#include <common.h>
+#include <asm/io.h>
+#include <spi.h>
+#include <malloc.h>
+#include <faraday/ftgpio010.h>

Does this include file is an arch' specific, means struct ftgpio010_regs is used by some other drivers on ur board?

No, it's not.
I'll merge it into the ftssp010_spi.c.

Quoted 5 lines
Quoted 1 line

+#include "ftssp010_spi.h"

Please don't use extra include file, use the same structure's in driver it self, IMHO.

Got it, thanks

Quoted 78 lines

drivers/spi/ftssp010_spi.c line 20

Quoted 5 lines
drivers/spi/ftssp010_spi.c new file +4 -0
+
+#define CFG_PIO_TIMEOUT (CONFIG_SYS_HZ >> 3) /* 125 ms */
+#define CFG_CS_TIMEOUT  (CONFIG_SYS_HZ >> 2) /* 250 ms */
+

----- TAG+

Quoted 43 lines
drivers/spi/ftssp010_spi.c new file +43 -0
+struct ftssp010_chip {
+       void __iomem *regs;
+       uint32_t fifo;
+       uint32_t rev;
+       uint32_t div;
+       uint32_t mode;
+
+       struct {
+               void __iomem *regs;
+               uint32_t      pin;
+       } gpio;
+};
+
+static struct ftssp010_chip chip_list[] = {
+#ifdef CONFIG_FTSSP010_BASE
+       {
+               .regs = (void __iomem *)CONFIG_FTSSP010_BASE,
+# ifdef CONFIG_FTSSP010_GPIO_BASE
+               .gpio = {
+                       (void __iomem *)CONFIG_FTSSP010_GPIO_BASE,
+                       CONFIG_FTSSP010_GPIO_PIN
+               },
+# endif
+       },
+#endif /* #ifdef CONFIG_FTSSP010_BASE */
+#ifdef CONFIG_FTSSP010_BASE1
+       { .regs = (void __iomem *)CONFIG_FTSSP010_BASE1, },
+# ifdef CONFIG_FTSSP010_GPIO_BASE1
+               .gpio = {
+                       (void __iomem *)CONFIG_FTSSP010_GPIO_BASE1,
+                       CONFIG_FTSSP010_GPIO_PIN1
+               },
+# endif
+#endif
+#ifdef CONFIG_FTSSP010_BASE2
+       { .regs = (void __iomem *)CONFIG_FTSSP010_BASE2, },
+# ifdef CONFIG_FTSSP010_GPIO_BASE2
+               .gpio = {
+                       (void __iomem *)CONFIG_FTSSP010_GPIO_BASE2,
+                       CONFIG_FTSSP010_GPIO_PIN2
+               },
+# endif
+#endif

drivers/spi/ftssp010_spi.c line 73

Quoted 10 lines
drivers/spi/ftssp010_spi.c new file +10 -0
+#ifdef CONFIG_FTSSP010_BASE3
+       { .regs = (void __iomem *)CONFIG_FTSSP010_BASE3, },
+# ifdef CONFIG_FTSSP010_GPIO_BASE3
+               .gpio = {
+                       (void __iomem *)CONFIG_FTSSP010_GPIO_BASE3,
+                       CONFIG_FTSSP010_GPIO_PIN3
+               },
+# endif
+#endif
+};

---- TAG-

TAG+ ... TAG- this type of assignment is old way.
please use the structure macro assignment instead of void __iomem *

ex:
#define CONFIG_MY_REG_BASE 0xF1000000

struct my_reg {
        u32 r1;
        u32 r2;
        u32 r3;
        u32 r4;
}
Quoted 9 lines

#define my_reg_base ((struct my_reg *) CONFIG_MY_REG_BASE)

then use readl(&my_reg_base->r3);

see the example usage on
http://patchwork.ozlabs.org/patch/246468/
https://github.com/Xilinx/u-boot-xlnx/blob/master/drivers/spi/zynq_qspips.c

Got it, thanks

Quoted 238 lines
Quoted 217 lines
drivers/spi/ftssp010_spi.c new file +213 -0
+
+static inline int ftssp010_wait_tx(struct ftssp010_chip *chip)
+{
+       struct ftssp010_regs __iomem *regs = chip->regs;
+       int ret = -1;
+       ulong ts;
+
+       for (ts = get_timer(0); get_timer(ts) < CFG_PIO_TIMEOUT; ) {
+               if (!(readl(&regs->sr) & SR_TFNF))
+                       continue;
+               ret = 0;
+               break;
+       }
+
+       if (ret)
+               printf("ftssp010: tx timeout\n");
+
+       return ret;
+}
+
+static inline int ftssp010_wait_rx(struct ftssp010_chip *chip)
+{
+       struct ftssp010_regs __iomem *regs = chip->regs;
+       int ret = -1;
+       ulong ts;
+
+       for (ts = get_timer(0); get_timer(ts) < CFG_PIO_TIMEOUT; ) {
+               if (!SR_RFVE(readl(&regs->sr)))
+                       continue;
+               ret = 0;
+               break;
+       }
+
+       if (ret)
+               printf("ftssp010: rx timeout\n");
+
+       return ret;
+}
+
+static int ftssp010_spi_work_transfer_v1_19(struct ftssp010_chip *chip,
+       const void *tx_buf, void *rx_buf, int len, uint flags)
+{
+       struct ftssp010_regs __iomem *regs = chip->regs;
+       const uint8_t *txb = tx_buf;
+       uint8_t       *rxb = rx_buf;
+
+       while (len > 0) {
+               int i, depth = min(chip->fifo >> 2, len);
+               uint32_t xmsk = 0;
+
+               if (tx_buf) {
+                       for (i = 0; i < depth; ++i) {
+                               ftssp010_wait_tx(chip);
+                               writel(*txb++, &regs->dr);
+                       }
+                       xmsk |= CR2_TXEN | CR2_TXDOE;
+                       if ((readl(&regs->cr[2]) & xmsk) != xmsk)
+                               setbits_le32(&regs->cr[2], xmsk);
+               }
+               if (rx_buf) {
+                       xmsk |= CR2_RXEN;
+                       if ((readl(&regs->cr[2]) & xmsk) != xmsk)
+                               setbits_le32(&regs->cr[2], xmsk);
+                       for (i = 0; i < depth; ++i) {
+                               ftssp010_wait_rx(chip);
+                               *rxb++ = (uint8_t)readl(&regs->dr);
+                       }
+               }
+
+               len -= depth;
+       }
+
+       return 0;
+}
+
+static int ftssp010_spi_work_transfer(struct ftssp010_chip *chip,
+       const void *tx_buf, void *rx_buf, int len, uint flags)
+{
+       struct ftssp010_regs __iomem *regs = chip->regs;
+       const uint8_t *txb = tx_buf;
+       uint8_t       *rxb = rx_buf;
+
+       while (len > 0) {
+               int i, depth = min(chip->fifo >> 2, len);
+               uint32_t tmp;
+
+               for (i = 0; i < depth; ++i) {
+                       ftssp010_wait_tx(chip);
+                       writel(txb ? (*txb++) : 0, &regs->dr);
+               }
+               for (i = 0; i < depth; ++i) {
+                       ftssp010_wait_rx(chip);
+                       tmp = readl(&regs->dr);
+                       if (rxb)
+                               *rxb++ = (uint8_t)tmp;
+               }
+
+               len -= depth;
+       }
+
+       return 0;
+}
+
+/*
+ * Determine if a SPI chipselect is valid.
+ * This function is provided by the board if the low-level SPI driver
+ * needs it to determine if a given chipselect is actually valid.
+ *
+ * Returns: 1 if bus:cs identifies a valid chip on this board, 0
+ * otherwise.
+ */
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+       int ret = 0;
+       struct ftssp010_chip *chip;
+       struct ftssp010_regs __iomem *regs;
+       uint32_t txfifo, rxfifo;
+
+       if (bus >= ARRAY_SIZE(chip_list))
+               return ret;
+
+       chip = chip_list + bus;
+       regs = chip->regs;
+       chip->rev = readl(&regs->revr);
+       txfifo = FEAR_TXFIFO(readl(&regs->fear));
+       rxfifo = FEAR_RXFIFO(readl(&regs->fear));
+       chip->fifo = min(txfifo, rxfifo);
+
+       debug("ftssp010: rev=0x%08X, fifo=%d\n", chip->rev, chip->fifo);
+
+       if (chip->rev >= 0x00011900) {
+               if (cs < 4)
+                       ret = 1;
+       } else if (!cs) {
+               struct ftgpio010_regs *gpio = chip->gpio.regs;
+               uint32_t mask = BIT_MASK(chip->gpio.pin);
+
+               if (gpio) {
+                       /* setup gpio pin as an output pin */
+                       setbits_le32(&gpio->dir, mask);
+                       ret = 1;
+               }
+       }
+
+       return ret;
+}
+
+/*
+ * Activate a SPI chipselect.
+ * This function is provided by the board code when using a driver
+ * that can't control its chipselects automatically (e.g.
+ * common/soft_spi.c). When called, it should activate the chip select
+ * to the device identified by "slave".
+ */
+void spi_cs_activate(struct spi_slave *slave)
+{
+       struct ftssp010_chip *chip = chip_list + slave->bus;
+       struct ftssp010_regs __iomem *regs = chip->regs;
+
+       /* cs pull low */
+       if (chip->rev >= 0x00011900) {
+               writel((slave->cs << 10) | CR2_SSPEN | CR2_TXFCLR
+                       | CR2_RXFCLR, &regs->cr[2]);
+       } else {
+               struct ftgpio010_regs *gpio = chip->gpio.regs;
+               uint32_t mask = BIT_MASK(chip->gpio.pin);
+
+               if (gpio)
+                       setbits_le32(&gpio->clr, mask);
+       }
+       udelay_masked(1);
+}
+
+/*
+ * Deactivate a SPI chipselect.
+ * This function is provided by the board code when using a driver
+ * that can't control its chipselects automatically (e.g.
+ * common/soft_spi.c). When called, it should deactivate the chip
+ * select to the device identified by "slave".
+ */
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+       struct ftssp010_chip *chip = chip_list + slave->bus;
+       struct ftssp010_regs __iomem *regs = chip->regs;
+       ulong ts;
+
+       /* wait until device idle */
+       for (ts = get_timer(0); get_timer(ts) < CFG_CS_TIMEOUT; ) {
+               if (readl(&regs->sr) & SR_BUSY)
+                       continue;
+               break;
+       }
+       if (readl(&regs->sr) & SR_BUSY)
+               printf("ftspi010: busy timeout at cs deactivate\n");
+
+       /* cs pull high */
+       if (chip->rev >= 0x00011900) {
+               writel((slave->cs << 10) | CR2_FS, &regs->cr[2]);
+       } else {
+               struct ftgpio010_regs *gpio = chip->gpio.regs;
+               uint32_t mask = BIT_MASK(chip->gpio.pin);
+
+               if (gpio)
+                       setbits_le32(&gpio->set, mask);
+       }
+       udelay_masked(1);
+}
+
+void spi_init(void)
+{
+}
+
+struct spi_slave *spi_setup_slave(uint bus, uint cs, uint max_hz, uint

mode)

drivers/spi/ftssp010_spi.c new file +3 -0
+{
+       uint32_t clk, div;
+       struct spi_slave *ss;

drivers/spi/ftssp010_spi.c line 299

Quoted 10 lines
drivers/spi/ftssp010_spi.c new file +10 -0
+       struct ftssp010_chip *chip;
+
+       if (!spi_cs_is_valid(bus, cs))
+               return NULL;
+
+       if (mode != SPI_MODE_0) {
+               printf("ftssp010: MODE%d is not supported\n", mode);
+               return NULL;
+       }
+

----- TAG+

drivers/spi/ftssp010_spi.c line 305

Quoted 6 lines
drivers/spi/ftssp010_spi.c new file +6 -0
+       ss = malloc(sizeof(struct spi_slave));
+       if (!ss)
+               return NULL;
+
+       ss->bus = bus;
+       ss->cs  = cs;
Quoted 5 lines

----- TAG-
Pleas use spi_alloc_slave() instead of malloc()
see the sample code on "drivers/spi/exynos_spi.c"

Got it, thanks

Quoted 184 lines
Quoted 74 lines
drivers/spi/ftssp010_spi.c new file +38 -0
+
+#ifdef CONFIG_FTSSP010_SCLK
+       clk = CONFIG_FTSSP010_SCLK;
+#else
+       clk = clk_get_rate("SSP");
+#endif
+       if (max_hz > 0) {
+               for (div = 0; div < 0xFFFF; ++div) {
+                       if ((clk / (2 * (div + 1))) <= max_hz)
+                               break;
+               }
+       } else {
+               div = 7;
+       }
+
+       chip = chip_list + bus;
+       chip->div  = div;
+       chip->mode = mode;
+
+       debug("ftssp010: bus=%d, hz=%u\n", bus, (clk / (2 * (div + 1))));
+
+       return ss;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+       free(slave);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+       struct ftssp010_chip *chip = chip_list + slave->bus;
+       struct ftssp010_regs __iomem *regs = chip->regs;
+
+       writel(CR1_SDL(8) | CR1_CLKDIV(chip->div), &regs->cr[1]);
+
+       if (chip->rev >= 0x00011900) {
+               writel(CR0_OPM_MASTER | CR0_FFMT_SPI | CR0_FSPO |

CR0_FLASH,

drivers/spi/ftssp010_spi.c new file +34 -0
+                       &regs->cr[0]);
+               writel(CR2_TXFCLR | CR2_RXFCLR,
+                       &regs->cr[2]);
+       } else {
+               writel(CR0_OPM_MASTER | CR0_FFMT_SPI | CR0_FSPO,
+                       &regs->cr[0]);
+               writel(CR2_TXFCLR | CR2_RXFCLR | CR2_SSPEN | CR2_TXDOE,
+                       &regs->cr[2]);
+       }
+
+       spi_cs_deactivate(slave);
+
+       return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+       struct ftssp010_chip *chip = chip_list + slave->bus;
+       struct ftssp010_regs __iomem *regs = chip->regs;
+
+       writel(0, &regs->cr[2]);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+                        const void *dout, void *din, unsigned long flags)
+{
+       struct ftssp010_chip *chip = chip_list + slave->bus;
+       uint32_t len = bitlen >> 3;
+
+       if (flags & SPI_XFER_BEGIN)
+               spi_cs_activate(slave);
+
+       if (chip->rev >= 0x00011900)
+               ftssp010_spi_work_transfer_v1_19(chip, dout, din, len,

flags);

drivers/spi/ftssp010_spi.c line 385

Quoted 8 lines
drivers/spi/ftssp010_spi.c new file +8 -0
+       else
+               ftssp010_spi_work_transfer(chip, dout, din, len, flags);
+
+       if (flags & SPI_XFER_END)
+               spi_cs_deactivate(slave);
+
+       return 0;
+}

---- TAG+

Quoted 85 lines
drivers/spi/ftssp010_spi.h new file +8 -0
new file mode 100644
index 0000000..5258edc
@@ -0,0 +1,86 @@
+/*
+ * Faraday Multi-function Controller - SPI Mode
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for

details.
+ */

drivers/spi/ftssp010_spi.h new file +62 -0
+
+#ifndef _FTSSP010_H
+#define _FTSSP010_H
+
+/* FTSSP010 HW Registers */
+struct ftssp010_regs {
+       uint32_t cr[3];/* control register */
+       uint32_t sr;   /* status register */
+       uint32_t icr;  /* interrupt control register */
+       uint32_t isr;  /* interrupt status register */
+       uint32_t dr;   /* data register */
+       uint32_t rsvd[17];
+       uint32_t revr; /* revision register */
+       uint32_t fear; /* feature register */
+};
+
+/* Control Register 0  */
+#define CR0_FFMT_MASK       (7 << 12)
+#define CR0_FFMT_SSP        (0 << 12)
+#define CR0_FFMT_SPI        (1 << 12)
+#define CR0_FFMT_MICROWIRE  (2 << 12)
+#define CR0_FFMT_I2S        (3 << 12)
+#define CR0_FFMT_AC97       (4 << 12)
+#define CR0_FLASH           (1 << 11)
+#define CR0_FSDIST(x)       (((x) & 0x03) << 8)
+#define CR0_LBM             (1 << 7)  /* Loopback mode */
+#define CR0_LSB             (1 << 6)  /* LSB first */
+#define CR0_FSPO            (1 << 5)  /* Frame sync atcive low */
+#define CR0_FSJUSTIFY       (1 << 4)
+#define CR0_OPM_SLAVE       (0 << 2)
+#define CR0_OPM_MASTER      (3 << 2)
+#define CR0_OPM_I2S_MSST    (3 << 2)  /* Master stereo mode */
+#define CR0_OPM_I2S_MSMO    (2 << 2)  /* Master mono mode */
+#define CR0_OPM_I2S_SLST    (1 << 2)  /* Slave stereo mode */
+#define CR0_OPM_I2S_SLMO    (0 << 2)  /* Slave mono mode */
+#define CR0_SCLKPO          (1 << 1)  /* SCLK Remain HIGH */
+#define CR0_SCLKPH          (1 << 0)  /* Half CLK cycle */
+
+/* Control Register 1 */
+
+#define CR1_PDL(x)          (((x) & 0xff) << 24) /* padding length */
+#define CR1_SDL(x)          ((((x) - 1) & 0x1f) << 16) /* data length */
+#define CR1_CLKDIV(x)       ((x) & 0xffff) /*  clk divider */
+
+/* Control Register 2 */
+#define CR2_FSOS(x)         (((x) & 0x03) << 10)       /* FS/CS Select */
+#define CR2_FS              (1 << 9)   /* FS/CS Signal Level */
+#define CR2_TXEN            (1 << 8)   /* Tx Enable */
+#define CR2_RXEN            (1 << 7)   /* Rx Enable */
+#define CR2_SSPRST          (1 << 6)   /* SSP reset */
+#define CR2_TXFCLR          (1 << 3)   /* TX FIFO Clear */
+#define CR2_RXFCLR          (1 << 2)   /* RX FIFO Clear */
+#define CR2_TXDOE           (1 << 1)   /* TX Data Output Enable */
+#define CR2_SSPEN           (1 << 0)   /* SSP Enable */
+
+/*
+ * Status Register
+ */
+#define SR_RFF       (1 << 0) /* receive FIFO full */
+#define SR_TFNF      (1 << 1) /* transmit FIFO not full */
+#define SR_BUSY      (1 << 2) /* bus is busy */
+#define SR_RFVE(reg) (((reg) >> 4) & 0x1f)  /* receive  FIFO valid

entries */
+#define SR_TFVE(reg) (((reg) >> 12) & 0x1f) /* transmit FIFO valid entries */

drivers/spi/ftssp010_spi.h new file +4 -0
+
+/*
+ * Feature Register
+ */

drivers/spi/ftssp010_spi.h line 86

Quoted 10 lines
drivers/spi/ftssp010_spi.h new file +10 -0
+#define FEAR_WIDTH(reg)  ((((reg) >>  0) & 0xff) + 1)
+#define FEAR_RXFIFO(reg) ((((reg) >>  8) & 0xff) + 1)
+#define FEAR_TXFIFO(reg) ((((reg) >> 16) & 0xff) + 1)
+#define FEAR_AC97        (1 << 24)
+#define FEAR_I2S         (1 << 25)
+#define FEAR_SPI_MWR     (1 << 26)
+#define FEAR_SSP         (1 << 27)
+#define FEAR_SPDIF       (1 << 28)
+
+#endif /* EOF */

---- TAG-

Quoted 2 lines

Please use the same defination on driver code itself.

Got it, thanks

--
Best wishes,
Kuo-Jung Su

#44 lore raw

PATCH v5 1/1 spi: ftssp010_spi: add Faraday SPI controller support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

The Faraday FTSSP010 is a multi-function controller which supports I2S/SPI/SSP/AC97/SPDIF. However This patch implements only the SPI mode.

NOTE:
The DMA and CS/Clock control logic has been altered since hardware revision 1.19.0. So this patch would first detects the revision id of the underlying chip, and then switch to the corresponding software control routines.

---
Changes for v5:
- Use SPDX-License-Identifier
- Add SPI mode checking & setup
- Coding Style cleanup

Changes for v4:
- Coding Style cleanup.
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Use macro constants for timeout control

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

 drivers/spi/Makefile       |    1 +
 drivers/spi/ftssp010_spi.c |  513 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 514 insertions(+)
 create mode 100644 drivers/spi/ftssp010_spi.c
drivers/spi/Makefile +1 -0
index 27902fe..ccc8f2f 100644
@@ -19,6 +19,7 @@ obj-$(CONFIG_CF_SPI) += cf_spi.o
 obj-$(CONFIG_CF_QSPI) += cf_qspi.o
 obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
 obj-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
+obj-$(CONFIG_FTSSP010_SPI) += ftssp010_spi.o
 obj-$(CONFIG_ICH_SPI) +=  ich.o
 obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
 obj-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
drivers/spi/ftssp010_spi.c new file +513 -0

513 lines not on this page · raw message

--
1.7.9.5

#45 lore raw

PATCH v6 1/1 spi: ftssp010_spi: add Faraday SPI controller support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

The Faraday FTSSP010 is a multi-function controller which supports I2S/SPI/SSP/AC97/SPDIF. However This patch implements only the SPI mode.

NOTE:
The DMA and CS/Clock control logic has been altered since hardware revision 1.19.0. So this patch would first detects the revision id of the underlying chip, and then switch to the corresponding software control routines.

---
Changes for v6:
- Drop SPI_LSB_FIRST support, because this driver supports only 8-bit mode access.
- Bug fix: Move chip enable from ftssp010_cs_set() to spi_cs_activate(), because ftssp010_cs_set() is supposed to update only the cs signal.

Changes for v5:
- Use SPDX-License-Identifier
- Add SPI mode checking & setup
- Coding Style cleanup

Changes for v4:
- Coding Style cleanup.
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Use macro constants for timeout control

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

 drivers/spi/Makefile       |    1 +
 drivers/spi/ftssp010_spi.c |  509 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 510 insertions(+)
 create mode 100644 drivers/spi/ftssp010_spi.c
drivers/spi/Makefile +1 -0
index 27902fe..ccc8f2f 100644
@@ -19,6 +19,7 @@ obj-$(CONFIG_CF_SPI) += cf_spi.o
 obj-$(CONFIG_CF_QSPI) += cf_qspi.o
 obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
 obj-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
+obj-$(CONFIG_FTSSP010_SPI) += ftssp010_spi.o
 obj-$(CONFIG_ICH_SPI) +=  ich.o
 obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
 obj-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
drivers/spi/ftssp010_spi.c new file +509 -0

509 lines not on this page · raw message

--
1.7.9.5

#46 lore raw

PATCH v3 6/11 mmc: update the Faraday FTSDC010 driver to fix performance issue

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTSDC010 is a MMC/SD host controller. Although there is already a driver in current u-boot release, which is modified from eSHDC and contributed by Andes Tech.

Its performance is too terrible on Faraday A36x SoC platforms, so I turn to implement this new version of driver which is 10+ times faster than the old one.

It's carefully designed to be compatible to Andes chips, so it should be safe to replace it.

---
 drivers/mmc/Makefile         |    2 +-
 drivers/mmc/ftsdc010_esdhc.c |  687 ------------------------------------------
 drivers/mmc/ftsdc010_mci.c   |  375 +++++++++++++++++++++++
 include/faraday/ftsdc010.h   |   16 +-
 include/faraday/mmc.h        |   16 +
 5 files changed, 405 insertions(+), 691 deletions(-)
 delete mode 100644 drivers/mmc/ftsdc010_esdhc.c
 create mode 100644 drivers/mmc/ftsdc010_mci.c
 create mode 100644 include/faraday/mmc.h
drivers/mmc/Makefile +1 -1
index 1d6faa2..2f07168 100644
@@ -32,7 +32,7 @@ endif
 COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
 COBJS-$(CONFIG_DAVINCI_MMC) += davinci_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
-COBJS-$(CONFIG_FTSDC010) += ftsdc010_esdhc.o
+COBJS-$(CONFIG_FTSDC010) += ftsdc010_mci.o
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
 COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
drivers/mmc/ftsdc010_esdhc.c deleted +0 -687

687 lines not on this page · raw message

drivers/mmc/ftsdc010_mci.c new file +375 -0

375 lines not on this page · raw message

include/faraday/ftsdc010.h +13 -3
index c34dde7..d8c289c 100644
@@ -23,6 +23,9 @@
 #define __FTSDC010_H
 
 #ifndef __ASSEMBLY__
+
+#include "mmc.h"
+
 /* sd controller register */
 struct ftsdc010_mmc {
 	unsigned int	cmd;		/* 0x00 - command reg		*/
@@ -67,9 +70,6 @@ struct mmc_host {
 	unsigned int card_type;		/* Card type */
 };
 
-/* functions */
-int ftsdc010_mmc_init(int dev_index);
-
 #endif	/* __ASSEMBLY__ */
 
 /* global defines */
@@ -143,6 +143,15 @@ int ftsdc010_mmc_init(int dev_index);
 #define FTSDC010_STATUS_SDIO_IRPT		(1 << 16) /* SDIO card intr */
 #define FTSDC010_STATUS_DATA0_STATUS		(1 << 17)
 #endif /* CONFIG_FTSDC010_SDIO */
+#define FTSDC010_STATUS_RSP_ERROR	\
+	(FTSDC010_STATUS_RSP_CRC_FAIL | FTSDC010_STATUS_RSP_TIMEOUT)
+#define FTSDC010_STATUS_RSP_MASK	\
+	(FTSDC010_STATUS_RSP_ERROR | FTSDC010_STATUS_RSP_CRC_OK)
+#define FTSDC010_STATUS_DATA_ERROR	\
+	(FTSDC010_STATUS_DATA_CRC_FAIL | FTSDC010_STATUS_DATA_TIMEOUT)
+#define FTSDC010_STATUS_DATA_MASK	\
+	(FTSDC010_STATUS_DATA_ERROR | FTSDC010_STATUS_DATA_CRC_OK \
+	| FTSDC010_STATUS_DATA_END)
 
 /* 0x2c - clear register */
 #define FTSDC010_CLR_RSP_CRC_FAIL		(1 << 0)
@@ -192,6 +201,7 @@ int ftsdc010_mmc_init(int dev_index);
 #define FTSDC010_CCR_CLK_DIV(x)			(((x) & 0x7f) << 0)
 #define FTSDC010_CCR_CLK_SD			(1 << 7) /* 0: MMC, 1: SD */
 #define FTSDC010_CCR_CLK_DIS			(1 << 8)
+#define FTSDC010_CCR_CLK_HISPD			(1 << 9) /* high speed */
 
 /* card type */
 #define FTSDC010_CARD_TYPE_SD			FTSDC010_CLOCK_REG_CARD_TYPE
include/faraday/mmc.h new file +16 -0
new file mode 100644
index 0000000..7c7bfaf
@@ -0,0 +1,16 @@
+/*
+ * Faraday MMC/SD Host Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef __FARADAY_MMC_H
+#define __FARADAY_MMC_H
+
+int ftsdc010_mmc_init(int dev_index);
+
+#endif /* _FARADAY_MMC_H */
Signature · 1 line
1.7.9.5
#47 lore raw

PATCH v3 6/11 mmc: update the Faraday FTSDC010 driver to fix performance issue

Quoted 25 lines · Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTSDC010 is a MMC/SD host controller. Although there is already a driver in current u-boot release, which is modified from eSHDC and contributed by Andes Tech.

Its performance is too terrible on Faraday A36x SoC platforms, so I turn to implement this new version of driver which is 10+ times faster than the old one.

It's carefully designed to be compatible to Andes chips, so it should be safe to replace it.

drivers/mmc/ftsdc010_mci.c new file +5 -0
+
+       if (chip->acmd) {
+               cmd |= FTSDC010_CMD_APP_CMD;
+               chip->acmd = 0;
+       }

[...]

drivers/mmc/ftsdc010_mci.c line 95

Quoted 7 lines
drivers/mmc/ftsdc010_mci.c new file +6 -0
+       if (ret) {
+               debug("ftsdc010: cmd timeout (op code=%d)\n",
+                       mmc_cmd->cmdidx);
+       } else if (mmc_cmd->cmdidx == MMC_CMD_APP_CMD) {
+               chip->acmd = 1;
+       }

Interesting. I've not seen any other devices that needed to have the sub command of the APP command flagged as such. I can't think of a better way to do this right now, so it's fine. Perhaps if there were other examples, we could implement a separate callback for APP cmds? Or we could modify the higher-level code to set a flag for the subcommands? I feel like maintaining this kind of state shouldn't be necessary, but possibly this hardware is strange.

drivers/mmc/ftsdc010_mci.c line 259

Quoted 12 lines
drivers/mmc/ftsdc010_mci.c new file +11 -0
+static void ftsdc010_set_ios(struct mmc *mmc)
+{
+       struct ftsdc010_chip *chip = mmc->priv;
+       struct ftsdc010_mmc __iomem *regs = chip->regs;
+
+       ftsdc010_clkset(chip, mmc->clock);
+
+       if (mmc->clock > 25000000)
+               setbits_le32(&regs->ccr, FTSDC010_CCR_CLK_HISPD);
+       else
+               clrbits_le32(&regs->ccr, FTSDC010_CCR_CLK_HISPD);

Why not put this part in ftsdc010_clkset, and set ccr all at once?

Quoted 3 lines
drivers/mmc/ftsdc010_mci.c new file +2 -0
+int ftsdc010_mmc_init(int devid)
+{

[...]

drivers/mmc/ftsdc010_mci.c line 347

Quoted 8 lines
drivers/mmc/ftsdc010_mci.c new file +7 -0
+
+       sprintf(mmc->name, "ftsdc010");
+       mmc->send_cmd = ftsdc010_request;
+       mmc->set_ios  = ftsdc010_set_ios;
+       mmc->init     = ftsdc010_init;
+
+       switch ((readl(&regs->bwr) >> 3) & 3) {

Could we get named constants for those mask/shift numbers?

drivers/mmc/ftsdc010_mci.c line 352

Quoted 6 lines
drivers/mmc/ftsdc010_mci.c new file +5 -0
+       case 1:
+               mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz
+                       | MMC_MODE_4BIT;
+               break;
+       case 2:

Andy

#48 lore raw

PATCH v3 6/11 mmc: update the Faraday FTSDC010 driver to fix performance issue

2013/5/4 Andy Fleming <[email protected]>:

Quoted 54 lines · Kuo-Jung Su
Quoted 26 lines

From: Kuo-Jung Su <[email protected]>

Faraday FTSDC010 is a MMC/SD host controller. Although there is already a driver in current u-boot release, which is modified from eSHDC and contributed by Andes Tech.

Its performance is too terrible on Faraday A36x SoC platforms, so I turn to implement this new version of driver which is 10+ times faster than the old one.

It's carefully designed to be compatible to Andes chips, so it should be safe to replace it.

drivers/mmc/ftsdc010_mci.c new file +5 -0
+
 
+       if (chip->acmd) {
+               cmd |= FTSDC010_CMD_APP_CMD;
+               chip->acmd = 0;
+       }

[...]

drivers/mmc/ftsdc010_mci.c line 95

Quoted 7 lines
drivers/mmc/ftsdc010_mci.c new file +6 -0
+       if (ret) {
+               debug("ftsdc010: cmd timeout (op code=%d)\n",
+                       mmc_cmd->cmdidx);
+       } else if (mmc_cmd->cmdidx == MMC_CMD_APP_CMD) {
+               chip->acmd = 1;
+       }

Interesting. I've not seen any other devices that needed to have the sub command of the APP command flagged as such. I can't think of a better way to do this right now, so it's fine. Perhaps if there were other examples, we could implement a separate callback for APP cmds? Or we could modify the higher-level code to set a flag for the subcommands? I feel like maintaining this kind of state shouldn't be necessary, but possibly this hardware is strange.

Quoted 1 line
Quoted 17 lines

drivers/mmc/ftsdc010_mci.c line 259

Quoted 11 lines
drivers/mmc/ftsdc010_mci.c new file +11 -0
+static void ftsdc010_set_ios(struct mmc *mmc)
+{
+       struct ftsdc010_chip *chip = mmc->priv;
+       struct ftsdc010_mmc __iomem *regs = chip->regs;
+
+       ftsdc010_clkset(chip, mmc->clock);
+
+       if (mmc->clock > 25000000)
+               setbits_le32(&regs->ccr, FTSDC010_CCR_CLK_HISPD);
+       else
+               clrbits_le32(&regs->ccr, FTSDC010_CCR_CLK_HISPD);

Why not put this part in ftsdc010_clkset, and set ccr all at once?

Got it, thanks.
I'll merge it into ftsdc010_clkset().

Quoted 8 lines
Quoted 3 lines
drivers/mmc/ftsdc010_mci.c new file +2 -0
+int ftsdc010_mmc_init(int devid)
+{

[...]

Quoted 1 line
Quoted 13 lines

drivers/mmc/ftsdc010_mci.c line 347

Quoted 7 lines
drivers/mmc/ftsdc010_mci.c new file +7 -0
+
+       sprintf(mmc->name, "ftsdc010");
+       mmc->send_cmd = ftsdc010_request;
+       mmc->set_ios  = ftsdc010_set_ios;
+       mmc->init     = ftsdc010_init;
+
+       switch ((readl(&regs->bwr) >> 3) & 3) {

Could we get named constants for those mask/shift numbers?

Sure, it would be fixed in next version.

Quoted 9 lines

drivers/mmc/ftsdc010_mci.c line 352

Quoted 6 lines
drivers/mmc/ftsdc010_mci.c new file +5 -0
+       case 1:
+               mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz
+                       | MMC_MODE_4BIT;
+               break;
+       case 2:

Andy

--
Best wishes,
Kuo-Jung Su

#49 lore raw

PATCH v4 1/1 mmc: update Faraday FTSDC010 for rw performance

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTSDC010 is a MMC/SD host controller. Although there is already a driver in current u-boot release, which is modified from eSHDC and contributed by Andes Tech. Its performance is too terrible on Faraday A36x SoC platforms, so I turn to implement this new version of driver which is 10+ times faster than the old one.

It's carefully designed to be compatible with Andes chips, so it should be safe to replace it.

---
Changes for v4:
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Drop the faraday/mmc.h to remove dependency to Faraday A36x patch series.
- Merge high clock (> 25MHz) setting for SD into ftsdc010_clkset()
- Use only named constants for bit mask/shift
- Use macro constants for timeout control

Changes for v3:
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.
- Replace ftsdc010_esdhc.c with this patch.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

 drivers/mmc/Makefile         |    2 +-
 drivers/mmc/ftsdc010_esdhc.c |  687 ------------------------------------------
 drivers/mmc/ftsdc010_mci.c   |  377 +++++++++++++++++++++++
 include/faraday/ftsdc010.h   |   31 +-
 4 files changed, 400 insertions(+), 697 deletions(-)
 delete mode 100644 drivers/mmc/ftsdc010_esdhc.c
 create mode 100644 drivers/mmc/ftsdc010_mci.c
drivers/mmc/Makefile +1 -1
index 1d6faa2..2f07168 100644
@@ -32,7 +32,7 @@ endif
 COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
 COBJS-$(CONFIG_DAVINCI_MMC) += davinci_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
-COBJS-$(CONFIG_FTSDC010) += ftsdc010_esdhc.o
+COBJS-$(CONFIG_FTSDC010) += ftsdc010_mci.o
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
 COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
drivers/mmc/ftsdc010_esdhc.c deleted +0 -687

687 lines not on this page · raw message

drivers/mmc/ftsdc010_mci.c new file +377 -0

377 lines not on this page · raw message

include/faraday/ftsdc010.h +22 -9
index c34dde7..8284f53 100644
@@ -23,6 +23,7 @@
 #define __FTSDC010_H
 
 #ifndef __ASSEMBLY__
+
 /* sd controller register */
 struct ftsdc010_mmc {
 	unsigned int	cmd;		/* 0x00 - command reg		*/
@@ -143,6 +144,15 @@ int ftsdc010_mmc_init(int dev_index);
 #define FTSDC010_STATUS_SDIO_IRPT		(1 << 16) /* SDIO card intr */
 #define FTSDC010_STATUS_DATA0_STATUS		(1 << 17)
 #endif /* CONFIG_FTSDC010_SDIO */
+#define FTSDC010_STATUS_RSP_ERROR	\
+	(FTSDC010_STATUS_RSP_CRC_FAIL | FTSDC010_STATUS_RSP_TIMEOUT)
+#define FTSDC010_STATUS_RSP_MASK	\
+	(FTSDC010_STATUS_RSP_ERROR | FTSDC010_STATUS_RSP_CRC_OK)
+#define FTSDC010_STATUS_DATA_ERROR	\
+	(FTSDC010_STATUS_DATA_CRC_FAIL | FTSDC010_STATUS_DATA_TIMEOUT)
+#define FTSDC010_STATUS_DATA_MASK	\
+	(FTSDC010_STATUS_DATA_ERROR | FTSDC010_STATUS_DATA_CRC_OK \
+	| FTSDC010_STATUS_DATA_END)
 
 /* 0x2c - clear register */
 #define FTSDC010_CLR_RSP_CRC_FAIL		(1 << 0)
@@ -192,21 +202,24 @@ int ftsdc010_mmc_init(int dev_index);
 #define FTSDC010_CCR_CLK_DIV(x)			(((x) & 0x7f) << 0)
 #define FTSDC010_CCR_CLK_SD			(1 << 7) /* 0: MMC, 1: SD */
 #define FTSDC010_CCR_CLK_DIS			(1 << 8)
+#define FTSDC010_CCR_CLK_HISPD			(1 << 9) /* high speed */
 
 /* card type */
 #define FTSDC010_CARD_TYPE_SD			FTSDC010_CLOCK_REG_CARD_TYPE
 #define FTSDC010_CARD_TYPE_MMC			0x0
 
 /* 0x3c - bus width register */
-#define FTSDC010_BWR_SINGLE_BUS			(1 << 0)
-#define FTSDC010_BWR_WIDE_8_BUS			(1 << 1)
-#define FTSDC010_BWR_WIDE_4_BUS			(1 << 2)
-#define FTSDC010_BWR_WIDE_BUS_SUPPORT(x)	(((x) >> 3) & 0x3)
-#define FTSDC010_BWR_CARD_DETECT		(1 << 5)
-
-#define FTSDC010_BWR_1_BUS_SUPPORT		0x0
-#define FTSDC010_BWR_4_BUS_SUPPORT		0x1
-#define FTSDC010_BWR_8_BUS_SUPPORT		0x2
+#define FTSDC010_BWR_MODE_1BIT      (1 << 0) /* 1 bit mode enabled */
+#define FTSDC010_BWR_MODE_8BIT      (1 << 1) /* 8 bit mode enabled */
+#define FTSDC010_BWR_MODE_4BIT      (1 << 2) /* 4 bit mode enabled */
+#define FTSDC010_BWR_MODE_MASK      (7 << 0)
+#define FTSDC010_BWR_MODE_SHIFT     (0)
+#define FTSDC010_BWR_CAPS_1BIT      (0 << 3) /* 1 bits mode supported */
+#define FTSDC010_BWR_CAPS_4BIT      (1 << 3) /* 1,4 bits mode supported */
+#define FTSDC010_BWR_CAPS_8BIT      (2 << 3) /* 1,4,8 bits mode supported */
+#define FTSDC010_BWR_CAPS_MASK      (3 << 3)
+#define FTSDC010_BWR_CAPS_SHIFT     (3)
+#define FTSDC010_BWR_CARD_DETECT    (1 << 5)
 
 /* 0x44 or 0x9c - feature register */
 #define FTSDC010_FEATURE_FIFO_DEPTH(x)		(((x) >> 0) & 0xff)

--
1.7.9.5

#50 lore raw

PATCH v3 7/11 mtd: nand: add Faraday FTNANDC021 NAND controller support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTNANDC021 is a integrated NAND flash controller. It use a build-in command table to abstract the underlying NAND flash control logic.

For example:

Issuing a command 0x10 to FTNANDC021 would result in a page write + a read status operation.

---
 README                        |    7 +
 drivers/mtd/nand/Makefile     |    1 +
 drivers/mtd/nand/ftnandc021.c |  724 +++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/nand/ftnandc021.h |  137 ++++++++
 include/faraday/nand.h        |   34 ++
 5 files changed, 903 insertions(+)
 create mode 100644 drivers/mtd/nand/ftnandc021.c
 create mode 100644 drivers/mtd/nand/ftnandc021.h
 create mode 100644 include/faraday/nand.h
README +7 -0
index 862bb3e..adc198f 100644
@@ -3872,6 +3872,13 @@ Low Level (hardware related) configuration options:
 		- drivers/mtd/nand/ndfc.c
 		- drivers/mtd/nand/mxc_nand.c
 
+- CONFIG_SYS_NAND_TIMING
+		Defined to tell the NAND controller that the NAND chip is using
+		a customized timing parameters.
+		Not all NAND drivers use this symbol.
+		Example of drivers that use it:
+		- drivers/mtd/nand/ftnandc021.c
+
 - CONFIG_SYS_NDFC_EBC0_CFG
 		Sets the EBC0_CFG register for the NDFC. If not defined
 		a default value will be used.
drivers/mtd/nand/Makefile +1 -0
index 35769c5..f6f89f0 100644
@@ -63,6 +63,7 @@ COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
 COBJS-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o
 COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
 COBJS-$(CONFIG_NAND_FSMC) += fsmc_nand.o
+COBJS-$(CONFIG_NAND_FTNANDC021) += ftnandc021.o
 COBJS-$(CONFIG_NAND_JZ4740) += jz4740_nand.o
 COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o
 COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
drivers/mtd/nand/ftnandc021.c new file +724 -0

724 lines not on this page · raw message

drivers/mtd/nand/ftnandc021.h new file +137 -0

137 lines not on this page · raw message

include/faraday/nand.h new file +34 -0
new file mode 100644
index 0000000..144ec13
@@ -0,0 +1,34 @@
+/*
+ * Faraday NAND Flash Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef __FARADAY_NAND_H
+#define __FARADAY_NAND_H
+
+#include <nand.h>
+
+/**
+ * struct faraday_nand_chip - chip level device structure
+ * @regs: base address of hardware registers
+ * @priv: hardware controller specific settings
+ * @alen: address length/cycle
+ * @pgsz: page size (byte)
+ * @bksz: block size (byte)
+ */
+struct faraday_nand_chip {
+	void __iomem *regs;
+	void *priv;
+	uint32_t alen;
+	uint32_t pgsz;
+	uint32_t bksz;
+};
+
+int ftnandc021_init(struct nand_chip *chip);
+
+#endif /* _FARADAY_NAND_H */
Signature · 1 line
1.7.9.5
#51 lore raw

PATCH v3 7/11 mtd: nand: add Faraday FTNANDC021 NAND controller support

Quoted 37 lines · Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTNANDC021 is a integrated NAND flash controller. It use a build-in command table to abstract the underlying NAND flash control logic.

For example:

Issuing a command 0x10 to FTNANDC021 would result in a page write + a read status operation.

---
 README                        |    7 +
 drivers/mtd/nand/Makefile     |    1 +
 drivers/mtd/nand/ftnandc021.c |  724  
+++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/nand/ftnandc021.h |  137 ++++++++
 include/faraday/nand.h        |   34 ++
 5 files changed, 903 insertions(+)
 create mode 100644 drivers/mtd/nand/ftnandc021.c
 create mode 100644 drivers/mtd/nand/ftnandc021.h
 create mode 100644 include/faraday/nand.h
README +0 -0
index 862bb3e..adc198f 100644
@@ -3872,6 +3872,13 @@ Low Level (hardware related) configuration  

options:

README +2 -0
 		- drivers/mtd/nand/ndfc.c
 		- drivers/mtd/nand/mxc_nand.c
 
+- CONFIG_SYS_NAND_TIMING
+		Defined to tell the NAND controller that the NAND chip  

is using

README Low Level (hardware related) configuration options: · line 3880

Quoted 4 lines
README +4 -0
+		a customized timing parameters.
+		Not all NAND drivers use this symbol.
+		Example of drivers that use it:
+		- drivers/mtd/nand/ftnandc021.c

This doesn't seem to have any standardized meaning (even if that meaning is applicable to only a subset of controllers), so please call it CONFIG_SYS_FTNANDC021_TIMING and document the ftnandc021-specific semantics.

Quoted 20 lines
drivers/mtd/nand/ftnandc021.c new file +7 -0
new file mode 100644
index 0000000..39c181f
@@ -0,0 +1,724 @@
+/*
+ * Faraday NAND Flash Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later  

version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */

drivers/mtd/nand/ftnandc021.c new file +2 -0
+
+#include <common.h>

drivers/mtd/nand/ftnandc021.c line 21

Quoted 10 lines
drivers/mtd/nand/ftnandc021.c new file +10 -0
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/unaligned.h>
+#include <nand.h>
+#include <malloc.h>
+#include <faraday/nand.h>
+
+#include "ftnandc021.h"
+
+#define CFG_HWECC	/* Enable hardware ECC */

If this is really to be optional, call it CONFIG_FTNANDC021_ECC (HWECC suggests the alternative is SW ECC, not no ECC) and define it in the board config file (or better, invert it to CONFIG_FTNANDC021_NO_ECC so ECC is the default).

If it's not meant to be optional, just remove the non-ECC code.

If the ECC doesn't cause major problems in a reasonable use case, I'd rather see the non-ECC code just removed.

Quoted 36 lines
drivers/mtd/nand/ftnandc021.c new file +36 -0
+static struct nand_ecclayout ftnandc021_ecclayout[] = {
+	{ /* page size = 512 (oob size = 16) */
+		.eccbytes = 6,
+		.eccpos = { 0, 1, 2, 3, 6, 7 },
+		.oobfree = {
+#ifdef CFG_HWECC
+			{ 9, 3 },
+#else
+			{ 8, 4 },
+#endif
+		}
+	},
+	{ /* page size = 2048 (oob size = 64) */
+		.eccbytes = 24,
+		.eccpos = {
+			40, 41, 42, 43, 44, 45, 46, 47,
+			48, 49, 50, 51, 52, 53, 54, 55,
+			56, 57, 58, 59, 60, 61, 62, 63
+		},
+		.oobfree = {
+#ifdef CFG_HWECC
+			{ 9, 3 },
+#else
+			{ 8, 4 },
+#endif
+		},
+	},
+	{ /* page size = 4096 (oob size = 128) */
+		.eccbytes = 48,
+		.eccpos = {
+			80, 81, 82, 83, 84, 85, 86, 87,
+			88, 89, 90, 91, 92, 93, 94, 95,
+			96, 97, 98, 99, 100, 101, 102, 103,
+			104, 105, 106, 107, 108, 109, 110, 111,
+			112, 113, 114, 115, 116, 117, 118, 119,
+			120, 121, 122, 123, 124, 125, 126, 127

drivers/mtd/nand/ftnandc021.c line 82

Quoted 10 lines
drivers/mtd/nand/ftnandc021.c new file +10 -0
+		},
+		.oobfree = {
+#ifdef CFG_HWECC
+			{ 9, 7 },
+#else
+			{ 8, 8 },
+#endif
+		},
+	},
+};

Shouldn't .eccpos depend on HWECC?

Quoted 9 lines
drivers/mtd/nand/ftnandc021.c new file +9 -0
+static int ftnandc021_ecc_correct(struct mtd_info *mtd, uint8_t *dat,
+	uint8_t *read_ecc, uint8_t *calc_ecc)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct faraday_nand_chip *info = chip->priv;
+	struct ftnandc021_chip *priv = info->priv;
+	struct ftnandc021_regs __iomem *regs = priv->regs;
+	uint32_t st = readl(&regs->ecc_sr);
+	int ret = 0;

drivers/mtd/nand/ftnandc021.c line 170

Quoted 10 lines
drivers/mtd/nand/ftnandc021.c new file +10 -0
+
+	if (st & ECC_SR_CERR) {
+		printf("ftnandc021: ecc corection error\n");
+		ret = -EIO;
+	} else if (st & ECC_SR_ERR) {
+		printf("ftnandc021: ecc error\n");
+		ret = -EIO;
+	}
+
+	return ret;

Can you detect correctable errors?

drivers/mtd/nand/ftnandc021.c line 280

Quoted 4 lines
drivers/mtd/nand/ftnandc021.c new file +4 -0
+#ifdef CFG_HWECC
+	chip->ecc.bytes          = chip->ecc.layout->eccbytes;
+	chip->ecc.size           = info->pgsz;
+	chip->ecc.steps          = 1;

Is it really all in one step, regardless of page size?

-Scott

#52 lore raw

PATCH v3 7/11 mtd: nand: add Faraday FTNANDC021 NAND controller support

2013/4/27 Scott Wood <[email protected]>:

Quoted 35 lines · Kuo-Jung Su
Quoted 34 lines

From: Kuo-Jung Su <[email protected]>

Faraday FTNANDC021 is a integrated NAND flash controller. It use a build-in command table to abstract the underlying NAND flash control logic.

For example:

Issuing a command 0x10 to FTNANDC021 would result in a page write + a read status operation.

---
 README                        |    7 +
 drivers/mtd/nand/Makefile     |    1 +
 drivers/mtd/nand/ftnandc021.c |  724
+++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/nand/ftnandc021.h |  137 ++++++++
 include/faraday/nand.h        |   34 ++
 5 files changed, 903 insertions(+)
 create mode 100644 drivers/mtd/nand/ftnandc021.c
 create mode 100644 drivers/mtd/nand/ftnandc021.h
 create mode 100644 include/faraday/nand.h
README +0 -0
index 862bb3e..adc198f 100644
@@ -3872,6 +3872,13 @@ Low Level (hardware related) configuration options:
                - drivers/mtd/nand/ndfc.c
                - drivers/mtd/nand/mxc_nand.c
 
Quoted 15 lines

README Low Level (hardware related) configuration options: · line 3880

Quoted 7 lines
README +2 -0
+- CONFIG_SYS_NAND_TIMING
+               Defined to tell the NAND controller that the NAND chip is

using

README +4 -0
+               a customized timing parameters.
+               Not all NAND drivers use this symbol.
+               Example of drivers that use it:
+               - drivers/mtd/nand/ftnandc021.c

This doesn't seem to have any standardized meaning (even if that meaning is applicable to only a subset of controllers), so please call it CONFIG_SYS_FTNANDC021_TIMING and document the ftnandc021-specific semantics.

Got it, thanks

Quoted 35 lines
Quoted 18 lines
drivers/mtd/nand/ftnandc021.c new file +8 -0
new file mode 100644
index 0000000..39c181f
@@ -0,0 +1,724 @@
+/*
+ * Faraday NAND Flash Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for

details.
+ */

drivers/mtd/nand/ftnandc021.c new file +2 -0
+
+#include <common.h>

drivers/mtd/nand/ftnandc021.c line 21

Quoted 10 lines
drivers/mtd/nand/ftnandc021.c new file +10 -0
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/unaligned.h>
+#include <nand.h>
+#include <malloc.h>
+#include <faraday/nand.h>
+
+#include "ftnandc021.h"
+
+#define CFG_HWECC      /* Enable hardware ECC */

If this is really to be optional, call it CONFIG_FTNANDC021_ECC (HWECC suggests the alternative is SW ECC, not no ECC) and define it in the board config file (or better, invert it to CONFIG_FTNANDC021_NO_ECC so ECC is the default).

Quoted 6 lines

If it's not meant to be optional, just remove the non-ECC code.

If the ECC doesn't cause major problems in a reasonable use case, I'd rather see the non-ECC code just removed.

Got it, thanks
I'll just remove the non-ECC codes later

Quoted 41 lines
Quoted 41 lines
drivers/mtd/nand/ftnandc021.c new file +41 -0
+static struct nand_ecclayout ftnandc021_ecclayout[] = {
+       { /* page size = 512 (oob size = 16) */
+               .eccbytes = 6,
+               .eccpos = { 0, 1, 2, 3, 6, 7 },
+               .oobfree = {
+#ifdef CFG_HWECC
+                       { 9, 3 },
+#else
+                       { 8, 4 },
+#endif
+               }
+       },
+       { /* page size = 2048 (oob size = 64) */
+               .eccbytes = 24,
+               .eccpos = {
+                       40, 41, 42, 43, 44, 45, 46, 47,
+                       48, 49, 50, 51, 52, 53, 54, 55,
+                       56, 57, 58, 59, 60, 61, 62, 63
+               },
+               .oobfree = {
+#ifdef CFG_HWECC
+                       { 9, 3 },
+#else
+                       { 8, 4 },
+#endif
+               },
+       },
+       { /* page size = 4096 (oob size = 128) */
+               .eccbytes = 48,
+               .eccpos = {
+                       80, 81, 82, 83, 84, 85, 86, 87,
+                       88, 89, 90, 91, 92, 93, 94, 95,
+                       96, 97, 98, 99, 100, 101, 102, 103,
+                       104, 105, 106, 107, 108, 109, 110, 111,
+                       112, 113, 114, 115, 116, 117, 118, 119,
+                       120, 121, 122, 123, 124, 125, 126, 127
+               },
+               .oobfree = {
+#ifdef CFG_HWECC
+                       { 9, 7 },
+#else
Quoted 10 lines

drivers/mtd/nand/ftnandc021.c line 82

Quoted 5 lines
drivers/mtd/nand/ftnandc021.c new file +5 -0
+                       { 8, 8 },
+#endif
+               },
+       },
+};

Shouldn't .eccpos depend on HWECC?

Actually it means nothing here, the ECC function is designed to be some kind of a blackbox to users (i.e softwares), the actual position of ECC codes are not documented
in the datasheet, I have to dig it out from RTL which I do not have permission to access.

And there are only 5 bytes are free to users in 2K page flash, users actually could only
control the 'value' of the 5 bytes, the actual position of these data are hard-coded in RTL level.

P.S: The 5-bytes are: 1-byte Bad Block Info + 4-bytes data in OOB.

Quoted 14 lines
Quoted 14 lines
drivers/mtd/nand/ftnandc021.c new file +14 -0
+static int ftnandc021_ecc_correct(struct mtd_info *mtd, uint8_t *dat,
+       uint8_t *read_ecc, uint8_t *calc_ecc)
+{
+       struct nand_chip *chip = mtd->priv;
+       struct faraday_nand_chip *info = chip->priv;
+       struct ftnandc021_chip *priv = info->priv;
+       struct ftnandc021_regs __iomem *regs = priv->regs;
+       uint32_t st = readl(&regs->ecc_sr);
+       int ret = 0;
+
+       if (st & ECC_SR_CERR) {
+               printf("ftnandc021: ecc corection error\n");
+               ret = -EIO;
+       } else if (st & ECC_SR_ERR) {
Quoted 10 lines

drivers/mtd/nand/ftnandc021.c line 170

Quoted 5 lines
drivers/mtd/nand/ftnandc021.c new file +5 -0
+               printf("ftnandc021: ecc error\n");
+               ret = -EIO;
+       }
+
+       return ret;

Can you detect correctable errors?

No, the FTNANDC021 does not have this function.
Like I said, it was designed for SSD applications, which usually uses some sort of
bare-metal software, and cares nothing about if it has encounter correctable ECC error.

Quoted 8 lines

drivers/mtd/nand/ftnandc021.c line 280

Quoted 4 lines
drivers/mtd/nand/ftnandc021.c new file +4 -0
+#ifdef CFG_HWECC
+       chip->ecc.bytes          = chip->ecc.layout->eccbytes;
+       chip->ecc.size           = info->pgsz;
+       chip->ecc.steps          = 1;

Is it really all in one step, regardless of page size?

Theoretical, NO.
It uses R-S or BCH for Forwarding Error Correction, which is selected at RTL level.
Which means it actually 522 bytes per step at RS and 528 bytes per step at BCH.

However it's all blackbox to software, the FTNANDC021 simply supports only page read, so looks like everything is done at 1 step.

Quoted 1 line

-Scott

--
Best wishes,
Kuo-Jung Su

#53 lore raw

PATCH v3 7/11 mtd: nand: add Faraday FTNANDC021 NAND controller support

Quoted 11 lines · Kuo-Jung Su

2013/4/27 Scott Wood <[email protected]>:

Quoted 3 lines

Shouldn't .eccpos depend on HWECC?

Actually it means nothing here, the ECC function is designed to be some kind of
a blackbox to users (i.e softwares), the actual position of ECC codes are not documented
in the datasheet, I have to dig it out from RTL which I do not have permission to access.

Maybe get rid of .eccpos altogether, and supply your own (much simpler) hwecc read/write_page functions -- similar to what fsl_elbc_nand, which also has transparent (but not hidden) ECC, does? This would also let you get rid of hwctl/calculate/correct.

Quoted 9 lines
Quoted 2 lines

Is it really all in one step, regardless of page size?

Theoretical, NO.
It uses R-S or BCH for Forwarding Error Correction, which is selected at RTL level.
Which means it actually 522 bytes per step at RS and 528 bytes per step at BCH.

Quoted 3 lines

However it's all blackbox to software, the FTNANDC021 simply supports only
page read, so looks like everything is done at 1 step.

It would matter if you could detect correctable errors, but since you can't, it doesn't.

-Scott

#54 lore raw

PATCH v3 7/11 mtd: nand: add Faraday FTNANDC021 NAND controller support

2013/4/30 Scott Wood <[email protected]>:

Quoted 16 lines · Kuo-Jung Su
Quoted 7 lines

2013/4/27 Scott Wood <[email protected]>:

Quoted 3 lines

Shouldn't .eccpos depend on HWECC?

Quoted 6 lines

Actually it means nothing here, the ECC function is designed to be some kind of
a blackbox to users (i.e softwares), the actual position of ECC codes are not documented
in the datasheet, I have to dig it out from RTL which I do not have permission to access.

Quoted 6 lines

Maybe get rid of .eccpos altogether, and supply your own (much simpler) hwecc read/write_page functions -- similar to what fsl_elbc_nand, which also has transparent (but not hidden) ECC, does? This would also let you get rid of hwctl/calculate/correct.

Got it, thanks
I'll check it later.

Quoted 9 lines
Quoted 9 lines
Quoted 2 lines

Is it really all in one step, regardless of page size?

Theoretical, NO.
It uses R-S or BCH for Forwarding Error Correction, which is selected at RTL level.
Which means it actually 522 bytes per step at RS and 528 bytes per step at BCH.

Quoted 7 lines
Quoted 2 lines

However it's all blackbox to software, the FTNANDC021 simply supports only page read, so looks like everything is done at 1 step.

It would matter if you could detect correctable errors, but since you can't, it doesn't.

Got it, thanks

Quoted 1 line

-Scott

--
Best wishes,
Kuo-Jung Su

#55 lore raw

PATCH v4 1/1 nand: add Faraday FTNANDC021 NAND controller support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTNANDC021 is a integrated NAND flash controller. It use a build-in command table to abstract the underlying NAND flash control logic.

For example:

Issuing a command 0x10 to FTNANDC021 would result in a page write + a read status operation.

---
Changes for v4:
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Drop the faraday/nand.h to remove dependency to Faraday A36x patch series.
- CONFIG_SYS_NAND_TIMING -> CONFIG_SYS_FTNANDC021_TIMING
- Remove non-ECC code.
- Implement private hwecc read/write_page functions to get rid of .eccpos & .eccbytes.
- Use macro constants for timeout control

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.
- Re-write this driver with ECC enabled and correct column address handling for OOB read/write,
- Fix issuses addressed by Scott.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

 README                        |    4 +
 drivers/mtd/nand/Makefile     |    1 +
 drivers/mtd/nand/ftnandc021.c |  607 +++++++++++++++++++++++++++++++++++++++++
 include/faraday/ftnandc021.h  |  146 ++++++++++
 4 files changed, 758 insertions(+)
 create mode 100644 drivers/mtd/nand/ftnandc021.c
 create mode 100644 include/faraday/ftnandc021.h
README +4 -0
index 0d37d56..883182d 100644
@@ -3879,6 +3879,10 @@ Low Level (hardware related) configuration options:
 		- drivers/mtd/nand/ndfc.c
 		- drivers/mtd/nand/mxc_nand.c
 
+- CONFIG_SYS_FTNANDC021_TIMING
+		Defined to tell the FTNANDC021 controller that the NAND chip is
+		using customized timing parameters.
+
 - CONFIG_SYS_NDFC_EBC0_CFG
 		Sets the EBC0_CFG register for the NDFC. If not defined
 		a default value will be used.
drivers/mtd/nand/Makefile +1 -0
index 35769c5..f6f89f0 100644
@@ -63,6 +63,7 @@ COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
 COBJS-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o
 COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
 COBJS-$(CONFIG_NAND_FSMC) += fsmc_nand.o
+COBJS-$(CONFIG_NAND_FTNANDC021) += ftnandc021.o
 COBJS-$(CONFIG_NAND_JZ4740) += jz4740_nand.o
 COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o
 COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
drivers/mtd/nand/ftnandc021.c new file +607 -0

607 lines not on this page · raw message

include/faraday/ftnandc021.h new file +146 -0

146 lines not on this page · raw message

--
1.7.9.5

#56 lore raw

PATCH v4 1/1 nand: add Faraday FTNANDC021 NAND controller support

Quoted 6 lines · Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTNANDC021 is a integrated NAND flash controller. It use a build-in command table to abstract the underlying NAND flash control logic.

Quoted 7 lines

For example:

Issuing a command 0x10 to FTNANDC021 would result in a page write + a read status operation.

Looks mostly OK, just a couple nits:

README Low Level (hardware related) configuration options: · line 3884

Quoted 13 lines
README +0 -0
index 0d37d56..883182d 100644
@@ -3879,6 +3879,10 @@ Low Level (hardware related) configuration  

options:

README +2 -0
 		- drivers/mtd/nand/ndfc.c
 		- drivers/mtd/nand/mxc_nand.c
 
+- CONFIG_SYS_FTNANDC021_TIMING
+		Defined to tell the FTNANDC021 controller that the NAND  

chip is

README +1 -0
+		using customized timing parameters.

This makes it sound like a boolean option, but it's actually an array -- would be nice to mention what's actually expected.

README

Quoted 1 line
README +1 -0
+	if (mtd->writesize >=  4096) {

Whitespace

-Scott

#57 lore raw

PATCH v4 1/1 nand: add Faraday FTNANDC021 NAND controller support

2013/5/9 Scott Wood <[email protected]>:

Quoted 28 lines · Kuo-Jung Su
Quoted 7 lines

From: Kuo-Jung Su <[email protected]>

Faraday FTNANDC021 is a integrated NAND flash controller. It use a build-in command table to abstract the underlying NAND flash control logic.

Quoted 7 lines

For example:

Issuing a command 0x10 to FTNANDC021 would result in a page write + a read status operation.

Looks mostly OK, just a couple nits:

Quoted 8 lines
README +0 -0
index 0d37d56..883182d 100644
@@ -3879,6 +3879,10 @@ Low Level (hardware related) configuration options:
                - drivers/mtd/nand/ndfc.c
                - drivers/mtd/nand/mxc_nand.c
 
Quoted 10 lines
Quoted 4 lines
README +2 -0
+- CONFIG_SYS_FTNANDC021_TIMING
+               Defined to tell the FTNANDC021 controller that the NAND

chip is
+ using customized timing parameters.

This makes it sound like a boolean option, but it's actually an array -- would be nice to mention what's actually expected.

Got it, thanks

Quoted 2 lines
Quoted 1 line

+ if (mtd->writesize >= 4096) {

Got it, thanks

Quoted 4 lines

Whitespace

-Scott

--
Best wishes,
Kuo-Jung Su

#58 lore raw

PATCH v5 1/1 nand: add Faraday FTNANDC021 NAND controller support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTNANDC021 is a integrated NAND flash controller. It use a build-in command table to abstract the underlying NAND flash control logic.

For example:

Issuing a command 0x10 to FTNANDC021 would result in a page write + a read status operation.

---
Changes for v5:
- Update README for the description of CONFIG_SYS_FTNANDC021_TIMING.
- Drop redundant white space. (i.e. if (mtd->writesize >= ' '4096))

Changes for v4:
- Make it a separate patch, rather then a part of Faraday A36x patch series
- Drop the faraday/nand.h to remove dependency to Faraday A36x patch series.
- CONFIG_SYS_NAND_TIMING -> CONFIG_SYS_FTNANDC021_TIMING
- Remove non-ECC code.
- Implement private hwecc read/write_page functions to get rid of .eccpos & .eccbytes.
- Use macro constants for timeout control

Changes for v3:
- Coding Style cleanup.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.
- Re-write this driver with ECC enabled and correct column address handling for OOB read/write,
- Fix issuses addressed by Scott.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().

 README                        |    6 +
 drivers/mtd/nand/Makefile     |    1 +
 drivers/mtd/nand/ftnandc021.c |  607 +++++++++++++++++++++++++++++++++++++++++
 include/faraday/ftnandc021.h  |  146 ++++++++++
 4 files changed, 760 insertions(+)
 create mode 100644 drivers/mtd/nand/ftnandc021.c
 create mode 100644 include/faraday/ftnandc021.h
README +6 -0
index 0d37d56..94c15e0 100644
@@ -3879,6 +3879,12 @@ Low Level (hardware related) configuration options:
 		- drivers/mtd/nand/ndfc.c
 		- drivers/mtd/nand/mxc_nand.c
 
+- CONFIG_SYS_FTNANDC021_TIMING
+		This option specifies an array of customized timing parameters
+		for Faraday FTNANDC021 NAND flash controller.
+		e.g.
+		#define CONFIG_SYS_FTNANDC021_TIMING { 0x02240264, 0x42054209 }
+
 - CONFIG_SYS_NDFC_EBC0_CFG
 		Sets the EBC0_CFG register for the NDFC. If not defined
 		a default value will be used.
drivers/mtd/nand/Makefile +1 -0
index 35769c5..f6f89f0 100644
@@ -63,6 +63,7 @@ COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
 COBJS-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o
 COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
 COBJS-$(CONFIG_NAND_FSMC) += fsmc_nand.o
+COBJS-$(CONFIG_NAND_FTNANDC021) += ftnandc021.o
 COBJS-$(CONFIG_NAND_JZ4740) += jz4740_nand.o
 COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o
 COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
drivers/mtd/nand/ftnandc021.c new file +607 -0

607 lines not on this page · raw message

include/faraday/ftnandc021.h new file +146 -0

146 lines not on this page · raw message

--
1.7.9.5

#59 lore raw

PATCH v3 8/11 usb: ehci: add Faraday USB 2.0 EHCI support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

This patch add supports to both Faraday FUSBH200 and FOTG210, these controllers slightly differ from standard EHCI specification.

---
 common/usb_hub.c                |    5 ++
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-faraday.c |  122 +++++++++++++++++++++++++++++++++++++++
 drivers/usb/host/ehci-hcd.c     |   11 ++++
 drivers/usb/host/ehci.h         |    5 ++
 include/usb/fotg210.h           |   71 +++++++++++++++++++++++
 include/usb/fusbh200.h          |   28 +++++++++
 7 files changed, 243 insertions(+)
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h
common/usb_hub.c +5 -0
index b5eeb62..26d66b8 100644
@@ -375,6 +375,11 @@ static int usb_hub_configure(struct usb_device *dev)
 		return -1;
 	}
 
+#ifdef CONFIG_USB_EHCI_FARADAY
+	/* Faraday USB 2.0 EHCI chips need a long long delay here */
+	mdelay(250);
+#endif
+
 	if (usb_get_hub_status(dev, buffer) < 0) {
 		USB_HUB_PRINTF("usb_hub_configure: failed to get Status %lX\n",
 				dev->status);
drivers/usb/host/Makefile +1 -0
index 87a5970..98f2a10 100644
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o
 else
 COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
 endif
+COBJS-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o
 COBJS-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
 COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
 COBJS-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o
drivers/usb/host/ehci-faraday.c new file +122 -0

122 lines not on this page · raw message

drivers/usb/host/ehci-hcd.c +11 -0
index c816878..450d217 100644
@@ -149,8 +149,10 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
 static int ehci_reset(int index)
 {
 	uint32_t cmd;
+#ifndef CONFIG_USB_EHCI_FARADAY
 	uint32_t tmp;
 	uint32_t *reg_ptr;
+#endif
 	int ret = 0;
 
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
@@ -163,6 +165,7 @@ static int ehci_reset(int index)
 		goto out;
 	}
 
+#ifndef CONFIG_USB_EHCI_FARADAY
 	if (ehci_is_TDI()) {
 		reg_ptr = (uint32_t *)((u8 *)ehcic[index].hcor + USBMODE);
 		tmp = ehci_readl(reg_ptr);
@@ -172,6 +175,7 @@ static int ehci_reset(int index)
 #endif
 		ehci_writel(reg_ptr, tmp);
 	}
+#endif	/* !CONFIG_USB_EHCI_FARADAY */
 
 #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
 	cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
@@ -711,6 +715,9 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
 
 		if (ehci_is_TDI()) {
+#ifdef CONFIG_USB_EHCI_FARADAY
+			tmpbuf[1] |= ehci_hcd_port_speed(ctrl->hccr) >> 8;
+#else
 			switch (PORTSC_PSPD(reg)) {
 			case PORTSC_PSPD_FS:
 				break;
@@ -722,6 +729,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 				tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
 				break;
 			}
+#endif
 		} else {
 			tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
 		}
@@ -950,10 +958,13 @@ int usb_lowlevel_init(int index, void **controller)
 	cmd |= CMD_RUN;
 	ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
 
+#ifndef CONFIG_USB_EHCI_FARADAY
 	/* take control over the ports */
 	cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
 	cmd |= FLAG_CF;
 	ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
+#endif
+
 	/* unblock posted write */
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
 	mdelay(5);
drivers/usb/host/ehci.h +5 -0
index d090f0a..9309ede 100644
@@ -82,6 +82,7 @@ struct ehci_hcor {
 	uint32_t or_periodiclistbase;
 	uint32_t or_asynclistaddr;
 	uint32_t _reserved_0_;
+#ifndef CONFIG_USB_EHCI_FARADAY
 	uint32_t or_burstsize;
 	uint32_t or_txfilltuning;
 #define TXFIFO_THRESH_MASK		(0x3f << 16)
@@ -89,6 +90,7 @@ struct ehci_hcor {
 	uint32_t _reserved_1_[6];
 	uint32_t or_configflag;
 #define FLAG_CF		(1 << 0)	/* true:  we'll support "high speed" */
+#endif  /* #ifndef CONFIG_USB_EHCI_FARADAY */
 	uint32_t or_portsc[CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS];
 #define PORTSC_PSPD(x)		(((x) >> 26) & 0x3)
 #define PORTSC_PSPD_FS			0x0
@@ -255,5 +257,8 @@ struct QH {
 /* Low level init functions */
 int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor);
 int ehci_hcd_stop(int index);
+#ifdef CONFIG_USB_EHCI_FARADAY
+int ehci_hcd_port_speed(struct ehci_hccr *hccr);
+#endif
 
 #endif /* USB_EHCI_H */
include/usb/fotg210.h new file +71 -0

71 lines not on this page · raw message

include/usb/fusbh200.h new file +28 -0
new file mode 100644
index 0000000..2d514b8
@@ -0,0 +1,28 @@
+/*
+ * Faraday USB 2.0 EHCI Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef _FUSBH200_H
+#define _FUSBH200_H
+
+struct fusbh200_regs {
+	struct {
+		uint32_t data[4];
+	} hccr;			/* 0x00 - 0x0f: hccr */
+	struct {
+		uint32_t data[9];
+	} hcor;			/* 0x10 - 0x33: hcor */
+	uint32_t easstr;/* 0x34: EOF&Async. Schedule Sleep Timer Register */
+	uint32_t rsvd[2];
+	uint32_t bmcsr;	/* 0x40: Bus Monitor Control Status Register */
+	uint32_t bmisr;	/* 0x44: Bus Monitor Interrupt Status Register */
+	uint32_t bmier; /* 0x48: Bus Monitor Interrupt Enable Register */
+};
+
+#endif
Signature · 1 line
1.7.9.5
#60 lore raw

PATCH v3 8/11 usb: ehci: add Faraday USB 2.0 EHCI support

Dear Kuo-Jung Su,

Quoted 4 lines

From: Kuo-Jung Su <[email protected]>

This patch add supports to both Faraday FUSBH200 and FOTG210, these controllers slightly differ from standard EHCI specification.

How do they differ?

Quoted 21 lines
---
 common/usb_hub.c                |    5 ++
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-faraday.c |  122
+++++++++++++++++++++++++++++++++++++++ drivers/usb/host/ehci-hcd.c     | 
 11 ++++
 drivers/usb/host/ehci.h         |    5 ++
 include/usb/fotg210.h           |   71 +++++++++++++++++++++++
 include/usb/fusbh200.h          |   28 +++++++++
 7 files changed, 243 insertions(+)
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h
common/usb_hub.c +0 -0
index b5eeb62..26d66b8 100644

common/usb_hub.c static int usb_hub_configure(struct usb_device *dev) · line 379

Quoted 5 lines
common/usb_hub.c +2 -0
@@ -375,6 +375,11 @@ static int usb_hub_configure(struct usb_device *dev)
 		return -1;
 	}
 
+#ifdef CONFIG_USB_EHCI_FARADAY
+	/* Faraday USB 2.0 EHCI chips need a long long delay here */

Why? Do they need it only for root hub or for all the hub down the road as well?

Quoted 69 lines
common/usb_hub.c +3 -0
+	mdelay(250);
+#endif
+
 	if (usb_get_hub_status(dev, buffer) < 0) {
 		USB_HUB_PRINTF("usb_hub_configure: failed to get Status %lX\n",
 				dev->status);
drivers/usb/host/Makefile +1 -0
index 87a5970..98f2a10 100644
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o
 else
 COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
 endif
+COBJS-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o
 COBJS-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
 COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
 COBJS-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o
(quoted diff) +0 -0

b/drivers/usb/host/ehci-faraday.c new file mode 100644 index 0000000..adf57d1

drivers/usb/host/ehci-faraday.c new file +8 -0
@@ -0,0 +1,122 @@
+/*
+ * Faraday USB 2.0 EHCI Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for

details. + */

drivers/usb/host/ehci-faraday.c new file +36 -0
+
+#include <common.h>
+#include <asm/io.h>
+#include <usb.h>
+#include <usb/fusbh200.h>
+#include <usb/fotg210.h>
+
+#include "ehci.h"
+
+union ehci_faraday_regs {
+	struct fusbh200_regs usb;
+	struct fotg210_regs  otg;
+};
+
+static inline int ehci_hci_fotg2xx(struct ehci_hccr *hccr)
+{
+	union ehci_faraday_regs __iomem *regs = (void *)hccr;
+	return !readl(&regs->usb.easstr);
+}
+
+/*
+ * Create the appropriate control structures to manage
+ * a new EHCI host controller.
+ */
+int ehci_hcd_init(int index, struct ehci_hccr **ret_hccr,
+		struct ehci_hcor **ret_hcor)
+{
+	struct ehci_hccr *hccr;
+	struct ehci_hcor *hcor;
+	union ehci_faraday_regs __iomem *regs;
+#ifdef CONFIG_USB_EHCI_BASE_LIST
+	uint32_t base_list[] = CONFIG_USB_EHCI_BASE_LIST;
+#else
+	uint32_t base_list[] = { CONFIG_USB_EHCI_BASE };
+#endif
+

drivers/usb/host/ehci-faraday.c line 55

Quoted 10 lines
drivers/usb/host/ehci-faraday.c new file +10 -0
+	if (index < 0 || index >= ARRAY_SIZE(base_list))
+		return -1;
+	regs = (void __iomem *)base_list[index];
+	hccr = (struct ehci_hccr *)&regs->usb.hccr;
+	hcor = (struct ehci_hcor *)&regs->usb.hcor;
+
+	if (ehci_hci_fotg2xx(hccr)) {
+		/* A-device bus reset */
+		/* ... Power off A-device */
+		setbits_le32(&regs->otg.otgcsr, BIT_MASK(5));

Do these bits not have names?

[...]

drivers/usb/host/ehci-faraday.c line 102

Quoted 10 lines
drivers/usb/host/ehci-faraday.c new file +10 -0
+int ehci_hcd_port_speed(struct ehci_hccr *hccr)
+{
+	int ret = 0;
+	int speed;
+	union ehci_faraday_regs __iomem *regs = (void *)hccr;
+
+	if (ehci_hci_fotg2xx(hccr))
+		speed = (readl(&regs->otg.otgcsr) >> 22) & 0x03;
+	else
+		speed = (readl(&regs->usb.bmcsr) >>  9) & 0x03;

Same here, what're these magic numbers?

Quoted 35 lines
drivers/usb/host/ehci-faraday.c new file +19 -0
+	switch (speed) {
+	case 0:    /* full speed */
+		break;
+
+	case 1:    /* low  speed */
+		ret = USB_PORT_STAT_LOW_SPEED;
+		break;
+
+	case 2:    /* high speed */
+		ret = USB_PORT_STAT_HIGH_SPEED;
+		break;
+
+	default:
+		printf("ehci-faraday: invalid device speed\n");
+		break;
+	}
+
+	return ret;
+}
drivers/usb/host/ehci-hcd.c +2 -0
index c816878..450d217 100644
@@ -149,8 +149,10 @@ static int handshake(uint32_t *ptr, uint32_t mask,
 uint32_t done, int usec) static int ehci_reset(int index)
 {
 	uint32_t cmd;
+#ifndef CONFIG_USB_EHCI_FARADAY
 	uint32_t tmp;
 	uint32_t *reg_ptr;
+#endif
 	int ret = 0;
 
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);

drivers/usb/host/ehci-hcd.c static int ehci_reset(int index) · line 168

Quoted 4 lines
drivers/usb/host/ehci-hcd.c +1 -0
@@ -163,6 +165,7 @@ static int ehci_reset(int index)
 		goto out;
 	}
 
+#ifndef CONFIG_USB_EHCI_FARADAY

Wouldn't it suffice to set your EHCI is not TDI ?

Quoted 8 lines
drivers/usb/host/ehci-hcd.c +1 -0
 	if (ehci_is_TDI()) {
 		reg_ptr = (uint32_t *)((u8 *)ehcic[index].hcor + USBMODE);
 		tmp = ehci_readl(reg_ptr);
@@ -172,6 +175,7 @@ static int ehci_reset(int index)
 #endif
 		ehci_writel(reg_ptr, tmp);
 	}
+#endif	/* !CONFIG_USB_EHCI_FARADAY */

[...]

#61 lore raw

PATCH v3 8/11 usb: ehci: add Faraday USB 2.0 EHCI support

2013/4/26 Marek Vasut <[email protected]>:

Quoted 9 lines

Dear Kuo-Jung Su,

Quoted 4 lines

From: Kuo-Jung Su <[email protected]>

This patch add supports to both Faraday FUSBH200 and FOTG210, these controllers slightly differ from standard EHCI specification.

How do they differ?

1. The reserved registers (0x1C - 0x3F) and CONFIGFLAG (0x40) register are not only un-implemented, but also removed from its register address space, which means we have to update the 'struct ehci_hcor' of ehci.h

2. FUSBH200/FOTG210 doesn't properly follow the ECHI for ISOC implementations. (It should be a hardware bug, but no one wants to fix it.)

I'll add these description to commit log at next patch.

Quoted 24 lines
Quoted 24 lines
---
 common/usb_hub.c                |    5 ++
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-faraday.c |  122
+++++++++++++++++++++++++++++++++++++++ drivers/usb/host/ehci-hcd.c     |
 11 ++++
 drivers/usb/host/ehci.h         |    5 ++
 include/usb/fotg210.h           |   71 +++++++++++++++++++++++
 include/usb/fusbh200.h          |   28 +++++++++
 7 files changed, 243 insertions(+)
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h
common/usb_hub.c +0 -0
index b5eeb62..26d66b8 100644
@@ -375,6 +375,11 @@ static int usb_hub_configure(struct usb_device *dev)
              return -1;
      }
 
Quoted 5 lines

common/usb_hub.c static int usb_hub_configure(struct usb_device *dev) · line 379

Quoted 2 lines
common/usb_hub.c +2 -0
+#ifdef CONFIG_USB_EHCI_FARADAY
+     /* Faraday USB 2.0 EHCI chips need a long long delay here */

Why? Do they need it only for root hub or for all the hub down the road as well?

root hub only.

Quoted 82 lines
Quoted 69 lines
common/usb_hub.c +3 -0
+     mdelay(250);
+#endif
+
      if (usb_get_hub_status(dev, buffer) < 0) {
              USB_HUB_PRINTF("usb_hub_configure: failed to get Status %lX\n",
                              dev->status);
drivers/usb/host/Makefile +1 -0
index 87a5970..98f2a10 100644
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o
 else
 COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
 endif
+COBJS-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o
 COBJS-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
 COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
 COBJS-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o
(quoted diff) +0 -0

b/drivers/usb/host/ehci-faraday.c new file mode 100644 index 0000000..adf57d1

drivers/usb/host/ehci-faraday.c new file +8 -0
@@ -0,0 +1,122 @@
+/*
+ * Faraday USB 2.0 EHCI Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for

details. + */

drivers/usb/host/ehci-faraday.c new file +36 -0
+
+#include <common.h>
+#include <asm/io.h>
+#include <usb.h>
+#include <usb/fusbh200.h>
+#include <usb/fotg210.h>
+
+#include "ehci.h"
+
+union ehci_faraday_regs {
+     struct fusbh200_regs usb;
+     struct fotg210_regs  otg;
+};
+
+static inline int ehci_hci_fotg2xx(struct ehci_hccr *hccr)
+{
+     union ehci_faraday_regs __iomem *regs = (void *)hccr;
+     return !readl(&regs->usb.easstr);
+}
+
+/*
+ * Create the appropriate control structures to manage
+ * a new EHCI host controller.
+ */
+int ehci_hcd_init(int index, struct ehci_hccr **ret_hccr,
+             struct ehci_hcor **ret_hcor)
+{
+     struct ehci_hccr *hccr;
+     struct ehci_hcor *hcor;
+     union ehci_faraday_regs __iomem *regs;
+#ifdef CONFIG_USB_EHCI_BASE_LIST
+     uint32_t base_list[] = CONFIG_USB_EHCI_BASE_LIST;
+#else
+     uint32_t base_list[] = { CONFIG_USB_EHCI_BASE };
+#endif
+

drivers/usb/host/ehci-faraday.c line 55

Quoted 10 lines
drivers/usb/host/ehci-faraday.c new file +10 -0
+     if (index < 0 || index >= ARRAY_SIZE(base_list))
+             return -1;
+     regs = (void __iomem *)base_list[index];
+     hccr = (struct ehci_hccr *)&regs->usb.hccr;
+     hcor = (struct ehci_hcor *)&regs->usb.hcor;
+
+     if (ehci_hci_fotg2xx(hccr)) {
+             /* A-device bus reset */
+             /* ... Power off A-device */
+             setbits_le32(&regs->otg.otgcsr, BIT_MASK(5));

Do these bits not have names?

Quoted 2 lines

[...]

Sorry for my laziness, they'll be fixed later.

Quoted 4 lines
Quoted 4 lines
drivers/usb/host/ehci-faraday.c new file +4 -0
+int ehci_hcd_port_speed(struct ehci_hccr *hccr)
+{
+     int ret = 0;
+     int speed;
Quoted 9 lines

drivers/usb/host/ehci-faraday.c line 102

Quoted 6 lines
drivers/usb/host/ehci-faraday.c new file +6 -0
+     union ehci_faraday_regs __iomem *regs = (void *)hccr;
+
+     if (ehci_hci_fotg2xx(hccr))
+             speed = (readl(&regs->otg.otgcsr) >> 22) & 0x03;
+     else
+             speed = (readl(&regs->usb.bmcsr) >>  9) & 0x03;

Same here, what're these magic numbers?

Sorry for my laziness, they'll be fixed later.

Quoted 33 lines
Quoted 33 lines
drivers/usb/host/ehci-faraday.c new file +19 -0
+     switch (speed) {
+     case 0:    /* full speed */
+             break;
+
+     case 1:    /* low  speed */
+             ret = USB_PORT_STAT_LOW_SPEED;
+             break;
+
+     case 2:    /* high speed */
+             ret = USB_PORT_STAT_HIGH_SPEED;
+             break;
+
+     default:
+             printf("ehci-faraday: invalid device speed\n");
+             break;
+     }
+
+     return ret;
+}
drivers/usb/host/ehci-hcd.c +2 -0
index c816878..450d217 100644
@@ -149,8 +149,10 @@ static int handshake(uint32_t *ptr, uint32_t mask,
 uint32_t done, int usec) static int ehci_reset(int index)
 {
      uint32_t cmd;
+#ifndef CONFIG_USB_EHCI_FARADAY
      uint32_t tmp;
      uint32_t *reg_ptr;
+#endif
      int ret = 0;
 
Quoted 9 lines

drivers/usb/host/ehci-hcd.c static int ehci_reset(int index) · line 168

Quoted 6 lines
drivers/usb/host/ehci-hcd.c +1 -0
      cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
@@ -163,6 +165,7 @@ static int ehci_reset(int index)
              goto out;
      }
 
+#ifndef CONFIG_USB_EHCI_FARADAY

Wouldn't it suffice to set your EHCI is not TDI ?

No, it's surely a TDI design, although we use private registers for speed detection
(see ehci_hcd_port_speed()) rather then BIT26-27 of PORTSC registers.

Quoted 10 lines
Quoted 8 lines
drivers/usb/host/ehci-hcd.c +1 -0
      if (ehci_is_TDI()) {
              reg_ptr = (uint32_t *)((u8 *)ehcic[index].hcor + USBMODE);
              tmp = ehci_readl(reg_ptr);
@@ -172,6 +175,7 @@ static int ehci_reset(int index)
 #endif
              ehci_writel(reg_ptr, tmp);
      }
+#endif       /* !CONFIG_USB_EHCI_FARADAY */

[...]

--
Best wishes,
Kuo-Jung Su

#62 lore raw

PATCH v3 8/11 usb: ehci: add Faraday USB 2.0 EHCI support

Dear Kuo-Jung Su,

Quoted 14 lines

2013/4/26 Marek Vasut <[email protected]>:

Quoted 8 lines

Dear Kuo-Jung Su,

Quoted 4 lines

From: Kuo-Jung Su <[email protected]>

This patch add supports to both Faraday FUSBH200 and FOTG210, these controllers slightly differ from standard EHCI specification.

How do they differ?

1. The reserved registers (0x1C - 0x3F) and CONFIGFLAG (0x40) register are not only un-implemented, but also removed from its register address space, which means we have to update the 'struct ehci_hcor' of ehci.h

Quoted 5 lines

2. FUSBH200/FOTG210 doesn't properly follow the ECHI for ISOC implementations. (It should be a hardware bug, but no one wants to fix it.)

I'll add these description to commit log at next patch.

Mhmmm ... maybe you can add some hooks into ehci-hcd driver instead of poluting it with ifdefs ? Weak-aliased functions would probably work best to contain your weird stuff in your driver only.

Best regards,
Marek Vasut

#63 lore raw

PATCH v3 8/11 usb: ehci: add Faraday USB 2.0 EHCI support

2013/4/30 Marek Vasut <[email protected]>:

Quoted 20 lines

Dear Kuo-Jung Su,

Quoted 18 lines

2013/4/26 Marek Vasut <[email protected]>:

Quoted 8 lines

Dear Kuo-Jung Su,

Quoted 4 lines

From: Kuo-Jung Su <[email protected]>

This patch add supports to both Faraday FUSBH200 and FOTG210, these controllers slightly differ from standard EHCI specification.

How do they differ?

1. The reserved registers (0x1C - 0x3F) and CONFIGFLAG (0x40) register are not only un-implemented, but also removed from its register address space, which means we have to update the 'struct ehci_hcor' of ehci.h

2. FUSBH200/FOTG210 doesn't properly follow the ECHI for ISOC implementations. (It should be a hardware bug, but no one wants to fix it.)

Quoted 6 lines
Quoted 1 line

I'll add these description to commit log at next patch.

Mhmmm ... maybe you can add some hooks into ehci-hcd driver instead of poluting it with ifdefs ? Weak-aliased functions would probably work best to contain your weird stuff in your driver only.

Did you mean 'Not poluting ehci.h with ifdefs' ?

It looks to me that the best way is to leave ehci.h untouched, and update the ehci_submit_root() as following:
----------------------------
ehci_submit_root()
{
......

#ifdef CONFIG_USB_EHCI_FARADAY
    status_reg = (uint32_t *)((uint8_t *)&ctrl->hcor + 0x30);
#else
    status_reg = (uint32_t *)&ctrl->hcor->or_portsc[
                 le16_to_cpu(req->index) - 1];

#endif
......
}
------------------------------

Would it be acceptable in this way?

If it's not, I'll make this patch as a separate patch with some hooks into ehci-hcd.

Quoted 2 lines

Best regards,
Marek Vasut

--
Best wishes,
Kuo-Jung Su

#64 lore raw

PATCH v3 8/11 usb: ehci: add Faraday USB 2.0 EHCI support

Dear Kuo-Jung Su,

Quoted 47 lines

2013/4/30 Marek Vasut <[email protected]>:

Quoted 22 lines

Dear Kuo-Jung Su,

Quoted 20 lines

2013/4/26 Marek Vasut <[email protected]>:

Quoted 8 lines

Dear Kuo-Jung Su,

Quoted 4 lines

From: Kuo-Jung Su <[email protected]>

This patch add supports to both Faraday FUSBH200 and FOTG210, these controllers slightly differ from standard EHCI specification.

How do they differ?

1. The reserved registers (0x1C - 0x3F) and CONFIGFLAG (0x40) register

are not only un-implemented, but also removed from its register address space, which means we have to update the 'struct ehci_hcor' of ehci.h

2. FUSBH200/FOTG210 doesn't properly follow the ECHI for ISOC implementations. (It should be a hardware bug, but no one wants to fix it.)

Quoted 5 lines
Quoted 1 line

I'll add these description to commit log at next patch.

Mhmmm ... maybe you can add some hooks into ehci-hcd driver instead of poluting it with ifdefs ? Weak-aliased functions would probably work best to contain your weird stuff in your driver only.

Did you mean 'Not poluting ehci.h with ifdefs' ?

It looks to me that the best way is to leave ehci.h untouched, and update the ehci_submit_root() as following:
----------------------------
ehci_submit_root()
{
......

#ifdef CONFIG_USB_EHCI_FARADAY
    status_reg = (uint32_t *)((uint8_t *)&ctrl->hcor + 0x30);
#else
    status_reg = (uint32_t *)&ctrl->hcor->or_portsc[
                 le16_to_cpu(req->index) - 1];

#endif
......
}
------------------------------

Quoted 4 lines

Would it be acceptable in this way?

If it's not, I'll make this patch as a separate patch with some hooks into ehci-hcd.

What about defining a

__weak uint32_t get_status_register()
{
...
}

function and override it's implementation in your driver?

Best regards,
Marek Vasut

#65 lore raw

PATCH v3 8/11 usb: ehci: add Faraday USB 2.0 EHCI support

2013/5/2 Marek Vasut <[email protected]>:

Quoted 54 lines

Dear Kuo-Jung Su,

Quoted 47 lines

2013/4/30 Marek Vasut <[email protected]>:

Quoted 22 lines

Dear Kuo-Jung Su,

Quoted 20 lines

2013/4/26 Marek Vasut <[email protected]>:

Quoted 8 lines

Dear Kuo-Jung Su,

Quoted 4 lines

From: Kuo-Jung Su <[email protected]>

This patch add supports to both Faraday FUSBH200 and FOTG210, these controllers slightly differ from standard EHCI specification.

How do they differ?

1. The reserved registers (0x1C - 0x3F) and CONFIGFLAG (0x40) register

are not only un-implemented, but also removed from its register address space, which means we have to update the 'struct ehci_hcor' of ehci.h

2. FUSBH200/FOTG210 doesn't properly follow the ECHI for ISOC implementations. (It should be a hardware bug, but no one wants to fix it.)

Quoted 5 lines
Quoted 1 line

I'll add these description to commit log at next patch.

Mhmmm ... maybe you can add some hooks into ehci-hcd driver instead of poluting it with ifdefs ? Weak-aliased functions would probably work best to contain your weird stuff in your driver only.

Did you mean 'Not poluting ehci.h with ifdefs' ?

It looks to me that the best way is to leave ehci.h untouched, and update the ehci_submit_root() as following:
----------------------------
ehci_submit_root()
{
......

#ifdef CONFIG_USB_EHCI_FARADAY
    status_reg = (uint32_t *)((uint8_t *)&ctrl->hcor + 0x30);
#else
    status_reg = (uint32_t *)&ctrl->hcor->or_portsc[
                 le16_to_cpu(req->index) - 1];

#endif
......
}
------------------------------

Quoted 4 lines

Would it be acceptable in this way?

If it's not, I'll make this patch as a separate patch with some hooks into ehci-hcd.

Quoted 9 lines

What about defining a

__weak uint32_t get_status_register()
{
...
}

function and override it's implementation in your driver?

That's a great idea, I'll update it in this way at next version.

Thanks

Quoted 2 lines

Best regards,
Marek Vasut

--
Best wishes,
Kuo-Jung Su

#66 lore raw

v4 cover usb: ehci: add Faraday USB EHCI&Gadget support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

This patch add supports to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI as listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differs from standard EHCI in several ways. Since U-boot doesn't support ISOC, we don't have to worry that.

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device as a time.

Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

Kuo-Jung Su (2):
usb: ehci: add Faraday USB 2.0 EHCI support
usb: gadget: add Faraday FOTG210 USB gadget support

 common/usb_hub.c                  |   13 +-
 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  961 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 drivers/usb/host/Makefile         |    1 +
 drivers/usb/host/ehci-faraday.c   |  146 ++++++
 drivers/usb/host/ehci-hcd.c       |  104 ++--
 include/usb/fotg210.h             |  358 ++++++++++++++
 include/usb/fusbh200.h            |   61 +++
 9 files changed, 1616 insertions(+), 37 deletions(-)
 create mode 100644 drivers/usb/gadget/fotg210.c
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h

--
1.7.9.5

#67 lore raw

PATCH v4 1/2 usb: ehci: add Faraday USB 2.0 EHCI support

From: Kuo-Jung Su <[email protected]>

This patch add supports to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI as listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differs from standard EHCI in several ways. Since U-boot doesn't support ISOC, we don't have to worry that.

---
Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 common/usb_hub.c                |   13 +-
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-faraday.c |  146 ++++++++++++++++
 drivers/usb/host/ehci-hcd.c     |  104 ++++++++----
 include/usb/fotg210.h           |  358 +++++++++++++++++++++++++++++++++++++++
 include/usb/fusbh200.h          |   61 +++++++
 6 files changed, 646 insertions(+), 37 deletions(-)
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h
common/usb_hub.c +12 -1
index b5eeb62..3c6cb69 100644
@@ -419,6 +419,14 @@ static int usb_hub_configure(struct usb_device *dev)
 			portstatus = le16_to_cpu(portsts->wPortStatus);
 			portchange = le16_to_cpu(portsts->wPortChange);
 
+#ifdef CONFIG_USB_EHCI_FARADAY
+			/* Faraday EHCI needs a long long delay here */
+			if (!portchange && !portstatus) {
+				if (get_timer(start) < 250)
+					continue;
+			}
+#endif
+
 			if ((portchange & USB_PORT_STAT_C_CONNECTION) ==
 				(portstatus & USB_PORT_STAT_CONNECTION))
 				break;
@@ -441,7 +449,9 @@ static int usb_hub_configure(struct usb_device *dev)
 					i + 1, portstatus);
 			usb_clear_port_feature(dev, i + 1,
 						USB_PORT_FEAT_C_ENABLE);
-
+			/* The following hack causes a ghost device problem
+			 * to Faraday EHCI */
+#ifndef CONFIG_USB_EHCI_FARADAY
 			/* EM interference sometimes causes bad shielded USB
 			 * devices to be shutdown by the hub, this hack enables
 			 * them again. Works at least with mouse driver */
@@ -453,6 +463,7 @@ static int usb_hub_configure(struct usb_device *dev)
 						"re-enabling...\n", i + 1);
 					usb_hub_port_connect_change(dev, i);
 			}
+#endif
 		}
 		if (portstatus & USB_PORT_STAT_SUSPEND) {
 			USB_HUB_PRINTF("port %d suspend change\n", i + 1);
drivers/usb/host/Makefile +1 -0
index 87a5970..98f2a10 100644
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o
 else
 COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
 endif
+COBJS-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o
 COBJS-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
 COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
 COBJS-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o
drivers/usb/host/ehci-faraday.c new file +146 -0

146 lines not on this page · raw message

drivers/usb/host/ehci-hcd.c +68 -36

163 lines not on this page · raw message

include/usb/fotg210.h new file +358 -0

358 lines not on this page · raw message

include/usb/fusbh200.h new file +61 -0

61 lines not on this page · raw message

--
1.7.9.5

#68 lore raw

PATCH v4 1/2 usb: ehci: add Faraday USB 2.0 EHCI support

Dear Kuo-Jung Su,

common/usb_hub.c

Quoted 53 lines

From: Kuo-Jung Su <[email protected]>

This patch add supports to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI as listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differs from standard EHCI in several ways. Since U-boot doesn't support ISOC, we don't have to worry that.

---
Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 common/usb_hub.c                |   13 +-
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-faraday.c |  146 ++++++++++++++++
 drivers/usb/host/ehci-hcd.c     |  104 ++++++++----
 include/usb/fotg210.h           |  358
+++++++++++++++++++++++++++++++++++++++ include/usb/fusbh200.h          | 
 61 +++++++
 6 files changed, 646 insertions(+), 37 deletions(-)
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h
common/usb_hub.c +0 -0
index b5eeb62..3c6cb69 100644

Please split the EHCI changes from this patch.

common/usb_hub.c static int usb_hub_configure(struct usb_device *dev) · line 428

Quoted 13 lines
common/usb_hub.c +7 -0
@@ -419,6 +419,14 @@ static int usb_hub_configure(struct usb_device *dev)
 			portstatus = le16_to_cpu(portsts->wPortStatus);
 			portchange = le16_to_cpu(portsts->wPortChange);
 
+#ifdef CONFIG_USB_EHCI_FARADAY
+			/* Faraday EHCI needs a long long delay here */
+			if (!portchange && !portstatus) {
+				if (get_timer(start) < 250)
+					continue;
+			}
+#endif

I'd say just call a weak function here, in case some other non-EHCI compliant controller happened to need this too. btw. does it need to be 250 ms or can you poll for readiness somehow ?

common/usb_hub.c static int usb_hub_configure(struct usb_device *dev) · line 453

Quoted 10 lines
common/usb_hub.c +2 -1
 			if ((portchange & USB_PORT_STAT_C_CONNECTION) ==
 				(portstatus & USB_PORT_STAT_CONNECTION))
 				break;
@@ -441,7 +449,9 @@ static int usb_hub_configure(struct usb_device *dev)
 					i + 1, portstatus);
 			usb_clear_port_feature(dev, i + 1,
 						USB_PORT_FEAT_C_ENABLE);
-
+			/* The following hack causes a ghost device problem
+			 * to Faraday EHCI */

Invalid multiline comment style (not that the one right below is a shining example of a valid one :-( ).

/*
* This is how you
* do multiline comments.
*/

Quoted 12 lines
common/usb_hub.c +2 -0
+#ifndef CONFIG_USB_EHCI_FARADAY
 			/* EM interference sometimes causes bad shielded USB
 			 * devices to be shutdown by the hub, this hack enables
 			 * them again. Works at least with mouse driver */
@@ -453,6 +463,7 @@ static int usb_hub_configure(struct usb_device *dev)
 						"re-enabling...\n", i + 1);
 					usb_hub_port_connect_change(dev, i);
 			}
+#endif
 		}
 		if (portstatus & USB_PORT_STAT_SUSPEND) {
 			USB_HUB_PRINTF("port %d suspend change\n", i + 1);

[...]

#69 lore raw

PATCH v4 1/2 usb: ehci: add Faraday USB 2.0 EHCI support

2013/5/8 Marek Vasut <[email protected]>:

Quoted 53 lines

Dear Kuo-Jung Su,

Quoted 51 lines

From: Kuo-Jung Su <[email protected]>

This patch add supports to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI as listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differs from standard EHCI in several ways. Since U-boot doesn't support ISOC, we don't have to worry that.

---
Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 common/usb_hub.c                |   13 +-
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-faraday.c |  146 ++++++++++++++++
 drivers/usb/host/ehci-hcd.c     |  104 ++++++++----
 include/usb/fotg210.h           |  358
+++++++++++++++++++++++++++++++++++++++ include/usb/fusbh200.h          |
 61 +++++++
 6 files changed, 646 insertions(+), 37 deletions(-)
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h
Quoted 5 lines

common/usb_hub.c

Quoted 2 lines
common/usb_hub.c +0 -0
index b5eeb62..3c6cb69 100644

Please split the EHCI changes from this patch.

Got it, thanks

Quoted 6 lines
Quoted 6 lines
common/usb_hub.c +0 -0
@@ -419,6 +419,14 @@ static int usb_hub_configure(struct usb_device *dev)
                      portstatus = le16_to_cpu(portsts->wPortStatus);
                      portchange = le16_to_cpu(portsts->wPortChange);
 
Quoted 12 lines

common/usb_hub.c static int usb_hub_configure(struct usb_device *dev) · line 428

Quoted 7 lines
common/usb_hub.c +7 -0
+#ifdef CONFIG_USB_EHCI_FARADAY
+                     /* Faraday EHCI needs a long long delay here */
+                     if (!portchange && !portstatus) {
+                             if (get_timer(start) < 250)
+                                     continue;
+                     }
+#endif

I'd say just call a weak function here, in case some other non-EHCI compliant controller happened to need this too. btw. does it need to be 250 ms or can you poll for readiness somehow ?

Got it, thanks. I'll add a weak function later,
and about the 250 ms is actually an estimated value. The delay time is actually board specific, it looks to me that it's somehow related to the number of usb host controllers and the attached usb flash drivers.

For example:

1. A369 - FUSBH200: a usb flash driver attached
A369 - FOTG210: nothing attached
=> no extra delay required.

2. A369 - FUSBH200: nothing attached
A369 - FOTG210: a usb flash driver attached
=> no extra delay required.

3. A369 - FUSBH200: a usb flash driver attached
A369 - FOTG210: a usb flash driver attached
=> The 2nd ehci host requires 200 ms extra delay to detect the attached device.
So I put a 250ms here for safe.

Quoted 14 lines

common/usb_hub.c static int usb_hub_configure(struct usb_device *dev) · line 453

Quoted 10 lines
common/usb_hub.c +2 -1
                      if ((portchange & USB_PORT_STAT_C_CONNECTION) ==
                              (portstatus & USB_PORT_STAT_CONNECTION))
                              break;
@@ -441,7 +449,9 @@ static int usb_hub_configure(struct usb_device *dev)
                                      i + 1, portstatus);
                      usb_clear_port_feature(dev, i + 1,
                                              USB_PORT_FEAT_C_ENABLE);
-
+                     /* The following hack causes a ghost device problem
+                      * to Faraday EHCI */

Invalid multiline comment style (not that the one right below is a shining example of a valid one :-( ).

Quoted 5 lines

/*
* This is how you
* do multiline comments.
*/

Got it, thanks!

Quoted 6 lines
Quoted 6 lines
common/usb_hub.c +1 -0
+#ifndef CONFIG_USB_EHCI_FARADAY
                      /* EM interference sometimes causes bad shielded USB
                       * devices to be shutdown by the hub, this hack enables
                       * them again. Works at least with mouse driver */
@@ -453,6 +463,7 @@ static int usb_hub_configure(struct usb_device *dev)
                                              "re-enabling...\n", i + 1);
Quoted 8 lines
Quoted 6 lines
common/usb_hub.c +1 -0
                                      usb_hub_port_connect_change(dev, i);
                      }
+#endif
              }
              if (portstatus & USB_PORT_STAT_SUSPEND) {
                      USB_HUB_PRINTF("port %d suspend change\n", i + 1);

[...]

--
Best wishes,
Kuo-Jung Su

#70 lore raw

PATCH v4 1/2 usb: ehci: add Faraday USB 2.0 EHCI support

Dear Kuo-Jung Su,

[...]

Quoted 32 lines
Quoted 8 lines
Quoted 8 lines
common/usb_hub.c +0 -0
@@ -419,6 +419,14 @@ static int usb_hub_configure(struct usb_device
 *dev)
 
                      portstatus = le16_to_cpu(portsts->wPortStatus);
                      portchange = le16_to_cpu(portsts->wPortChange);
 
Quoted 11 lines

common/usb_hub.c static int usb_hub_configure(struct usb_device *dev) · line 428

Quoted 7 lines
common/usb_hub.c +7 -0
+#ifdef CONFIG_USB_EHCI_FARADAY
+                     /* Faraday EHCI needs a long long delay here */
+                     if (!portchange && !portstatus) {
+                             if (get_timer(start) < 250)
+                                     continue;
+                     }
+#endif

I'd say just call a weak function here, in case some other non-EHCI compliant controller happened to need this too. btw. does it need to be 250 ms or can you poll for readiness somehow ?

Got it, thanks. I'll add a weak function later,
and about the 250 ms is actually an estimated value. The delay time is actually board specific, it looks to me that it's somehow related to the number of usb host controllers and the attached usb flash drivers.

For example:

1. A369 - FUSBH200: a usb flash driver attached
A369 - FOTG210: nothing attached
=> no extra delay required.

Quoted 8 lines

2. A369 - FUSBH200: nothing attached
A369 - FOTG210: a usb flash driver attached
=> no extra delay required.

3. A369 - FUSBH200: a usb flash driver attached
A369 - FOTG210: a usb flash driver attached
=> The 2nd ehci host requires 200 ms extra delay to detect the attached device. So I put a 250ms here for safe.

Urgh, isn't it a PHY problem then? Or can this not be solved like board/genesi/mx51_efikamx/efikamx-usb.c board_ehci_hcd_postinit() or such function?

[...]

Best regards,
Marek Vasut

#71 lore raw

PATCH v4 1/2 usb: ehci: add Faraday USB 2.0 EHCI support

2013/5/8 Marek Vasut <[email protected]>:

Quoted 40 lines

Dear Kuo-Jung Su,

[...]

Quoted 36 lines
Quoted 8 lines
Quoted 8 lines
common/usb_hub.c +0 -0
@@ -419,6 +419,14 @@ static int usb_hub_configure(struct usb_device
 *dev)
 
                      portstatus = le16_to_cpu(portsts->wPortStatus);
                      portchange = le16_to_cpu(portsts->wPortChange);
 
Quoted 11 lines

common/usb_hub.c static int usb_hub_configure(struct usb_device *dev) · line 428

Quoted 7 lines
common/usb_hub.c +7 -0
+#ifdef CONFIG_USB_EHCI_FARADAY
+                     /* Faraday EHCI needs a long long delay here */
+                     if (!portchange && !portstatus) {
+                             if (get_timer(start) < 250)
+                                     continue;
+                     }
+#endif

I'd say just call a weak function here, in case some other non-EHCI compliant controller happened to need this too. btw. does it need to be 250 ms or can you poll for readiness somehow ?

Got it, thanks. I'll add a weak function later,
and about the 250 ms is actually an estimated value. The delay time is actually board specific, it looks to me that it's somehow related to the number of usb host controllers and the attached usb flash drivers.

For example:

1. A369 - FUSBH200: a usb flash driver attached
A369 - FOTG210: nothing attached
=> no extra delay required.

2. A369 - FUSBH200: nothing attached
A369 - FOTG210: a usb flash driver attached
=> no extra delay required.

Quoted 9 lines
Quoted 4 lines

3. A369 - FUSBH200: a usb flash driver attached
A369 - FOTG210: a usb flash driver attached
=> The 2nd ehci host requires 200 ms extra delay to detect the attached device. So I put a 250ms here for safe.

Urgh, isn't it a PHY problem then? Or can this not be solved like board/genesi/mx51_efikamx/efikamx-usb.c board_ehci_hcd_postinit() or such function?

It looks to me that it's something related to root hub reset. And now I've found that adding a extra delay to usb_hub_power_on() would help to resolve this issue.
So I plan to add a new macro constant for it.
For example:

1. Add this to README:
CONFIG_USB_HUB_MIN_POWER_ON_DELAY defines the minimum interval for usb hub power-on delay.(minimum 100msec)

2. Update usb_hub.c as bellow:
static void usb_hub_power_on(struct usb_hub_device *hub) {
......

    /* Wait at least 100 msec for power to become stable */
    mdelay(max(pgood_delay, USB_HUB_MIN_POWER_ON_DELAY));
}
Quoted 4 lines

[...]

Best regards,
Marek Vasut

--
Best wishes,
Kuo-Jung Su

#72 lore raw

PATCH v4 1/2 usb: ehci: add Faraday USB 2.0 EHCI support

Dear Kuo-Jung Su,

Quoted 66 lines

2013/5/8 Marek Vasut <[email protected]>:

Quoted 46 lines

Dear Kuo-Jung Su,

[...]

Quoted 42 lines
Quoted 8 lines
Quoted 8 lines
common/usb_hub.c +0 -0
@@ -419,6 +419,14 @@ static int usb_hub_configure(struct usb_device
 *dev)
 
                      portstatus = le16_to_cpu(portsts->wPortStatus);
                      portchange = le16_to_cpu(portsts->wPortChange);
 
Quoted 11 lines

common/usb_hub.c static int usb_hub_configure(struct usb_device *dev) · line 428

Quoted 7 lines
common/usb_hub.c +7 -0
+#ifdef CONFIG_USB_EHCI_FARADAY
+                     /* Faraday EHCI needs a long long delay here */
+                     if (!portchange && !portstatus) {
+                             if (get_timer(start) < 250)
+                                     continue;
+                     }
+#endif

I'd say just call a weak function here, in case some other non-EHCI compliant controller happened to need this too. btw. does it need to be 250 ms or can you poll for readiness somehow ?

Got it, thanks. I'll add a weak function later,
and about the 250 ms is actually an estimated value. The delay time is actually board specific, it looks to me that it's somehow related to the number of usb host controllers and the attached usb flash drivers.

For example:

1. A369 - FUSBH200: a usb flash driver attached

A369 - FOTG210: nothing attached

=> no extra delay required.

2. A369 - FUSBH200: nothing attached

A369 - FOTG210: a usb flash driver attached

=> no extra delay required.

3. A369 - FUSBH200: a usb flash driver attached

Quoted 8 lines
Quoted 4 lines

A369 - FOTG210: a usb flash driver attached

=> The 2nd ehci host requires 200 ms extra delay to detect the attached device. So I put a 250ms here for safe.

Urgh, isn't it a PHY problem then? Or can this not be solved like board/genesi/mx51_efikamx/efikamx-usb.c board_ehci_hcd_postinit() or such function?

It looks to me that it's something related to root hub reset. And now I've found that adding a extra delay to usb_hub_power_on() would help to resolve this issue.
So I plan to add a new macro constant for it.
For example:

1. Add this to README:
CONFIG_USB_HUB_MIN_POWER_ON_DELAY defines the minimum interval for usb hub power-on delay.(minimum 100msec)

Quoted 7 lines

2. Update usb_hub.c as bellow:
static void usb_hub_power_on(struct usb_hub_device *hub) {
......

    /* Wait at least 100 msec for power to become stable */
    mdelay(max(pgood_delay, USB_HUB_MIN_POWER_ON_DELAY));
}

Let's try it.

Best regards,
Marek Vasut

#73 lore raw

PATCH v4 1/2 usb: ehci: add Faraday USB 2.0 EHCI support

2013/5/8 Marek Vasut <[email protected]>:

Quoted 76 lines

Dear Kuo-Jung Su,

Quoted 66 lines

2013/5/8 Marek Vasut <[email protected]>:

Quoted 46 lines

Dear Kuo-Jung Su,

[...]

Quoted 42 lines
Quoted 8 lines
Quoted 8 lines
common/usb_hub.c +0 -0
@@ -419,6 +419,14 @@ static int usb_hub_configure(struct usb_device
 *dev)
 
                      portstatus = le16_to_cpu(portsts->wPortStatus);
                      portchange = le16_to_cpu(portsts->wPortChange);
 
Quoted 11 lines

common/usb_hub.c static int usb_hub_configure(struct usb_device *dev) · line 428

Quoted 7 lines
common/usb_hub.c +7 -0
+#ifdef CONFIG_USB_EHCI_FARADAY
+                     /* Faraday EHCI needs a long long delay here */
+                     if (!portchange && !portstatus) {
+                             if (get_timer(start) < 250)
+                                     continue;
+                     }
+#endif

I'd say just call a weak function here, in case some other non-EHCI compliant controller happened to need this too. btw. does it need to be 250 ms or can you poll for readiness somehow ?

Got it, thanks. I'll add a weak function later,
and about the 250 ms is actually an estimated value. The delay time is actually board specific, it looks to me that it's somehow related to the number of usb host controllers and the attached usb flash drivers.

For example:

1. A369 - FUSBH200: a usb flash driver attached

A369 - FOTG210: nothing attached

=> no extra delay required.

2. A369 - FUSBH200: nothing attached

A369 - FOTG210: a usb flash driver attached

=> no extra delay required.

3. A369 - FUSBH200: a usb flash driver attached

Quoted 8 lines
Quoted 4 lines

A369 - FOTG210: a usb flash driver attached

=> The 2nd ehci host requires 200 ms extra delay to detect the attached device. So I put a 250ms here for safe.

Urgh, isn't it a PHY problem then? Or can this not be solved like board/genesi/mx51_efikamx/efikamx-usb.c board_ehci_hcd_postinit() or such function?

It looks to me that it's something related to root hub reset. And now I've found that adding a extra delay to usb_hub_power_on() would help to resolve this issue.
So I plan to add a new macro constant for it.
For example:

1. Add this to README:
CONFIG_USB_HUB_MIN_POWER_ON_DELAY defines the minimum interval for usb hub power-on delay.(minimum 100msec)

Quoted 7 lines

2. Update usb_hub.c as bellow:
static void usb_hub_power_on(struct usb_hub_device *hub) {
......

    /* Wait at least 100 msec for power to become stable */
    mdelay(max(pgood_delay, USB_HUB_MIN_POWER_ON_DELAY));
}
Quoted 2 lines

Let's try it.

Got it, thanks

Quoted 2 lines

Best regards,
Marek Vasut

--
Best wishes,
Kuo-Jung Su

#74 lore raw

v5 cover usb: add Faraday EHCI & Gadget support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

This patch adds support to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI are listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differs from standard EHCI in several ways. And since U-boot doesn't support ISOC, we don't have to worry about that.

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device as a time.

Changes for v5:
- Split up EHCI changeset
- usb_hub: replace the Faraday EHCI ifdef for the long delay in usb_hub_configure() with the new configuration option:
USB_HUB_MIN_POWER_ON_DELAY, which is used in usb_hub_power_on() to control the minimum usb hub power-on delay.
- ehci-faraday: fix the invalid multi-line comment style.
- gadget-fotg210: coding style cleanup.
- gadget-fotg210: drop postfix '__iomem' from struct fotg210_regs
- gadget-fotg210: use permanent delay for hardware reset
- gadget-fotg210: drop '#ifndef CONFIG_SYS_DCACHE_OFF'
- gadget-fotg210: drop magic numbers

Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

Kuo-Jung Su (4):
usb: make usb hub minimum power-on delay configurable
usb: add weak-aliased functions EHCI portsc & tdi routines
usb: ehci: add Faraday USB 2.0 EHCI support
usb: gadget: add Faraday FOTG210 USB gadget support

 README                            |    3 +
 common/usb_hub.c                  |   15 +-
 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  948 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 drivers/usb/host/Makefile         |    1 +
 drivers/usb/host/ehci-faraday.c   |  146 ++++++
 drivers/usb/host/ehci-hcd.c       |  104 ++--
 include/usb/fotg210.h             |  364 ++++++++++++++
 include/usb/fusbh200.h            |   61 +++
 10 files changed, 1613 insertions(+), 38 deletions(-)
 create mode 100644 drivers/usb/gadget/fotg210.c
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h

--
1.7.9.5

#75 lore raw

PATCH v5 1/4 usb: hub: make minimum power-on delay configurable

From: Kuo-Jung Su <[email protected]>

This patch makes the minimum power-on delay for USB HUB become configurable. The original design waits at least 100 msec here, but some EHCI controlers(e.g. Faraday EHCI) are known to require much longer delay interval.

NOTE:
The minimal delay is still 100 msec, a small value defined in CONFIG_USB_HUB_MIN_POWER_ON_DELAY would be automatically justified in common/usb_hub.c.

---
Changes for v5:
- Split up from Faraday EHCI patch
- Replace the Faraday EHCI ifdef for the long delay
in usb_hub_configure() with the new configuration option:
USB_HUB_MIN_POWER_ON_DELAY, which is used in usb_hub_power_on() to control the minimum usb hub power-on delay.

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 README           |    3 +++
 common/usb_hub.c |    8 +++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)
README +3 -0
index 0d37d56..c70a59b 100644
@@ -1244,6 +1244,9 @@ The following options need to be configured:
 		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
 		txfilltuning field in the EHCI controller on reset.
 
+		CONFIG_USB_HUB_MIN_POWER_ON_DELAY defines the minimum
+		interval for usb hub power-on delay.(minimum 100msec)
+
 - USB Device:
 		Define the below if you wish to use the USB console.
 		Once firmware is rebuilt from a serial console issue the
common/usb_hub.c +7 -1
index b5eeb62..0db3530 100644
@@ -61,6 +61,12 @@
 #define USB_HUB_DEBUG	0
 #endif
 
+#if CONFIG_USB_HUB_MIN_POWER_ON_DELAY > 100
+# define USB_HUB_MIN_POWER_ON_DELAY	CONFIG_USB_HUB_MIN_POWER_ON_DELAY
+#else
+# define USB_HUB_MIN_POWER_ON_DELAY	100
+#endif
+
 #define USB_PRINTF(fmt, args...)	debug_cond(USB_DEBUG, fmt, ##args)
 #define USB_HUB_PRINTF(fmt, args...)	debug_cond(USB_HUB_DEBUG, fmt, ##args)
 
@@ -121,7 +127,7 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
 	}
 
 	/* Wait at least 100 msec for power to become stable */
-	mdelay(max(pgood_delay, (unsigned)100));
+	mdelay(max(pgood_delay, USB_HUB_MIN_POWER_ON_DELAY));
 }
 
 void usb_hub_reset(void)

--
1.7.9.5

#76 lore raw

PATCH v5 1/4 usb: hub: make minimum power-on delay configurable

Dear Kuo-Jung Su,

Quoted 48 lines

From: Kuo-Jung Su <[email protected]>

This patch makes the minimum power-on delay for USB HUB become configurable. The original design waits at least 100 msec here, but some EHCI controlers(e.g. Faraday EHCI) are known to require much longer delay interval.

NOTE:
The minimal delay is still 100 msec, a small value defined in CONFIG_USB_HUB_MIN_POWER_ON_DELAY would be automatically justified in common/usb_hub.c.

---
Changes for v5:
- Split up from Faraday EHCI patch
- Replace the Faraday EHCI ifdef for the long delay
in usb_hub_configure() with the new configuration option:
USB_HUB_MIN_POWER_ON_DELAY, which is used in usb_hub_power_on() to control the minimum usb hub power-on delay.

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 README           |    3 +++
 common/usb_hub.c |    8 +++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)
README +3 -0
index 0d37d56..c70a59b 100644
@@ -1244,6 +1244,9 @@ The following options need to be configured:
 		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
 		txfilltuning field in the EHCI controller on reset.
 
+		CONFIG_USB_HUB_MIN_POWER_ON_DELAY defines the minimum
+		interval for usb hub power-on delay.(minimum 100msec)
+
 - USB Device:
 		Define the below if you wish to use the USB console.
 		Once firmware is rebuilt from a serial console issue the
common/usb_hub.c +0 -0
index b5eeb62..0db3530 100644

common/usb_hub.c line 68

Quoted 8 lines
common/usb_hub.c +5 -0
@@ -61,6 +61,12 @@
 #define USB_HUB_DEBUG	0
 #endif
 
+#if CONFIG_USB_HUB_MIN_POWER_ON_DELAY > 100
+# define USB_HUB_MIN_POWER_ON_DELAY	CONFIG_USB_HUB_MIN_POWER_ON_DELAY
+#else
+# define USB_HUB_MIN_POWER_ON_DELAY	100
+#endif

Even better (and easier) solution here would be:

ifndef CONFIG_USB_HUB_MIN_POWER_ON_DELAY
#define CONFIG_USB_HUB_MIN_POWER_ON_DELAY 100
#endif

no ? ;-)

Quoted 14 lines
common/usb_hub.c +1 -2
 #define USB_PRINTF(fmt, args...)	debug_cond(USB_DEBUG, fmt, ##args)
 #define USB_HUB_PRINTF(fmt, args...)	debug_cond(USB_HUB_DEBUG, fmt,
 ##args)
@@ -121,7 +127,7 @@ static void usb_hub_power_on(struct usb_hub_device
 *hub) }
 
 	/* Wait at least 100 msec for power to become stable */
-	mdelay(max(pgood_delay, (unsigned)100));
+	mdelay(max(pgood_delay, USB_HUB_MIN_POWER_ON_DELAY));
 }
 
 void usb_hub_reset(void)
--
Quoted 1 line

1.7.9.5

Best regards,
Marek Vasut

#77 lore raw

PATCH v5 1/4 usb: hub: make minimum power-on delay configurable

2013/5/10 Marek Vasut <[email protected]>:

Quoted 61 lines

Dear Kuo-Jung Su,

Quoted 48 lines

From: Kuo-Jung Su <[email protected]>

This patch makes the minimum power-on delay for USB HUB become configurable. The original design waits at least 100 msec here, but some EHCI controlers(e.g. Faraday EHCI) are known to require much longer delay interval.

NOTE:
The minimal delay is still 100 msec, a small value defined in CONFIG_USB_HUB_MIN_POWER_ON_DELAY would be automatically justified in common/usb_hub.c.

---
Changes for v5:
- Split up from Faraday EHCI patch
- Replace the Faraday EHCI ifdef for the long delay
in usb_hub_configure() with the new configuration option:
USB_HUB_MIN_POWER_ON_DELAY, which is used in usb_hub_power_on() to control the minimum usb hub power-on delay.

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 README           |    3 +++
 common/usb_hub.c |    8 +++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)
README +3 -0
index 0d37d56..c70a59b 100644
@@ -1244,6 +1244,9 @@ The following options need to be configured:
              CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
              txfilltuning field in the EHCI controller on reset.
 
+             CONFIG_USB_HUB_MIN_POWER_ON_DELAY defines the minimum
+             interval for usb hub power-on delay.(minimum 100msec)
+
 - USB Device:
              Define the below if you wish to use the USB console.
              Once firmware is rebuilt from a serial console issue the
common/usb_hub.c +0 -0
index b5eeb62..0db3530 100644

common/usb_hub.c line 68

Quoted 8 lines
common/usb_hub.c +5 -0
@@ -61,6 +61,12 @@
 #define USB_HUB_DEBUG        0
 #endif
 
+#if CONFIG_USB_HUB_MIN_POWER_ON_DELAY > 100
+# define USB_HUB_MIN_POWER_ON_DELAY  CONFIG_USB_HUB_MIN_POWER_ON_DELAY
+#else
+# define USB_HUB_MIN_POWER_ON_DELAY  100
+#endif

Even better (and easier) solution here would be:

Quoted 6 lines

ifndef CONFIG_USB_HUB_MIN_POWER_ON_DELAY
#define CONFIG_USB_HUB_MIN_POWER_ON_DELAY 100
#endif

no ? ;-)

Yep, it looks better, I'll have it fixed.

Quoted 12 lines
Quoted 12 lines
common/usb_hub.c +1 -1
 #define USB_PRINTF(fmt, args...)     debug_cond(USB_DEBUG, fmt, ##args)
 #define USB_HUB_PRINTF(fmt, args...) debug_cond(USB_HUB_DEBUG, fmt,
 ##args)
@@ -121,7 +127,7 @@ static void usb_hub_power_on(struct usb_hub_device
 *hub) }
 
      /* Wait at least 100 msec for power to become stable */
-     mdelay(max(pgood_delay, (unsigned)100));
+     mdelay(max(pgood_delay, USB_HUB_MIN_POWER_ON_DELAY));
 }
 
Quoted 6 lines
Quoted 3 lines
common/usb_hub.c +0 -1
 void usb_hub_reset(void)
--

1.7.9.5

Best regards,
Marek Vasut

--
Best wishes,
Kuo-Jung Su

#78 lore raw

v6 cover usb: add Faraday EHCI & Gadget support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

This patch adds support to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI are listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differs from standard EHCI in several ways. But since U-boot doesn't support ISOC, we don't have to worry about that.

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device at a time.

Changes for v6:
- usb_hub: Simplify CONFIG_USB_HUB_MIN_POWER_ON_DELAY default value setup.
- ehci-hcd: Simplify weak aliased function declaration
- ehci-hcd: Drop redundant line feed

Changes for v5:
- Split up EHCI changeset
- usb_hub: replace the Faraday EHCI ifdef for the long delay in usb_hub_configure() with the new configuration option:
USB_HUB_MIN_POWER_ON_DELAY, which is used in usb_hub_power_on() to control the minimum usb hub power-on delay.
- ehci-faraday: fix the invalid multi-line comment style.
- gadget-fotg210: coding style cleanup.
- gadget-fotg210: drop postfix '__iomem' from struct fotg210_regs
- gadget-fotg210: use permanent delay for hardware reset
- gadget-fotg210: drop '#ifndef CONFIG_SYS_DCACHE_OFF'
- gadget-fotg210: drop magic numbers

Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

Kuo-Jung Su (4):
usb: hub: make minimum power-on delay configurable
usb: ehci: add weak-aliased functions to portsc & tdi
usb: ehci: add Faraday USB 2.0 EHCI support
usb: gadget: add Faraday FOTG210 USB gadget support

 README                            |    3 +
 common/usb_hub.c                  |   15 +-
 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  948 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 drivers/usb/host/Makefile         |    1 +
 drivers/usb/host/ehci-faraday.c   |  146 ++++++
 drivers/usb/host/ehci-hcd.c       |   96 ++--
 include/usb/fotg210.h             |  364 ++++++++++++++
 include/usb/fusbh200.h            |   61 +++
 10 files changed, 1604 insertions(+), 39 deletions(-)
 create mode 100644 drivers/usb/gadget/fotg210.c
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h

--
1.7.9.5

#79 lore raw

PATCH v6 1/4 usb: hub: make minimum power-on delay configurable

From: Kuo-Jung Su <[email protected]>

This patch makes the minimum power-on delay for USB HUB become configurable. The original design waits at least 100 msec here, but some EHCI controlers(e.g. Faraday EHCI) are known to require much longer delay interval.

---
Changes for v6:
- Simplify CONFIG_USB_HUB_MIN_POWER_ON_DELAY default value setup.

Changes for v5:
- Split up from Faraday EHCI patch
- Replace the Faraday EHCI ifdef for the long delay
in usb_hub_configure() with the new configuration option:
USB_HUB_MIN_POWER_ON_DELAY, which is used in usb_hub_power_on() to control the minimum usb hub power-on delay.

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 README           |    3 +++
 common/usb_hub.c |    8 ++++++--
 2 files changed, 9 insertions(+), 2 deletions(-)
README +3 -0
index 0d37d56..455163b 100644
@@ -1244,6 +1244,9 @@ The following options need to be configured:
 		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
 		txfilltuning field in the EHCI controller on reset.
 
+		CONFIG_USB_HUB_MIN_POWER_ON_DELAY defines the minimum
+		interval for usb hub power-on delay.(100msec by default)
+
 - USB Device:
 		Define the below if you wish to use the USB console.
 		Once firmware is rebuilt from a serial console issue the
common/usb_hub.c +6 -2
index b5eeb62..f240d8c 100644
@@ -61,6 +61,10 @@
 #define USB_HUB_DEBUG	0
 #endif
 
+#ifndef CONFIG_USB_HUB_MIN_POWER_ON_DELAY
+#define CONFIG_USB_HUB_MIN_POWER_ON_DELAY	100
+#endif
+
 #define USB_PRINTF(fmt, args...)	debug_cond(USB_DEBUG, fmt, ##args)
 #define USB_HUB_PRINTF(fmt, args...)	debug_cond(USB_HUB_DEBUG, fmt, ##args)
 
@@ -120,8 +124,8 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
 		USB_HUB_PRINTF("port %d returns %lX\n", i + 1, dev->status);
 	}
 
-	/* Wait at least 100 msec for power to become stable */
-	mdelay(max(pgood_delay, (unsigned)100));
+	/* Wait for power to become stable */
+	mdelay(max(pgood_delay, CONFIG_USB_HUB_MIN_POWER_ON_DELAY));
 }
 
 void usb_hub_reset(void)

--
1.7.9.5

#80 lore raw

PATCH v6 1/4 usb: hub: make minimum power-on delay configurable

Dear Kuo-Jung Su,

Quoted 9 lines

From: Kuo-Jung Su <[email protected]>

This patch makes the minimum power-on delay for USB HUB become configurable. The original design waits at least 100 msec here, but some EHCI controlers(e.g. Faraday EHCI) are known to require much longer delay interval.

The rest of the patches are good, just 2/4 needs minor tweak.

I'd do it myself, but they don't apply to u-boot-usb/master , can you please adjust, rebase them and repost? Then I'll pick them.

Thanks!

Best regards,
Marek Vasut

#81 lore raw

PATCH v6 1/4 usb: hub: make minimum power-on delay configurable

2013/5/13 Marek Vasut <[email protected]>:

Quoted 9 lines

Dear Kuo-Jung Su,

Quoted 7 lines

From: Kuo-Jung Su <[email protected]>

This patch makes the minimum power-on delay for USB HUB become configurable. The original design waits at least 100 msec here, but some EHCI controlers(e.g. Faraday EHCI) are known to require much longer delay interval.

Quoted 8 lines
Quoted 2 lines

The rest of the patches are good, just 2/4 needs minor tweak.

I'd do it myself, but they don't apply to u-boot-usb/master , can you please adjust, rebase them and repost? Then I'll pick them.

Sorry about that, I didn't notice that the usb ehci had been updated 7 days ago. I'll rebase my patches and repost later.

Quoted 4 lines

Thanks!

Best regards,
Marek Vasut

--
Best wishes,
Kuo-Jung Su

#82 lore raw

v7 cover usb: add Faraday EHCI & Gadget support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

This patch adds support to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI are listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differs from standard EHCI in several ways. But since U-boot doesn't support ISOC, we don't have to worry about that.

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device at a time.

Changes for v7:
- Rebase with u-boot-bbd0f7e3ba66d288a2f146f1c7797801e04598ae, and also make sure it's compatible with u-boot-usb-dc69e46302a36e60e2417bba8c6ea78761a37ebf.
- Update TDI aliased functions, since there is another similar patch had been committed and acceptted.
- ehci-hcd: ehci_get_portsc_register(): make sure port is always >= 0

Changes for v6:
- usb_hub: Simplify CONFIG_USB_HUB_MIN_POWER_ON_DELAY default value setup.
- ehci-hcd: Simplify weak aliased function declaration
- ehci-hcd: Drop redundant line feed

Changes for v5:
- Split up EHCI changeset
- usb_hub: replace the Faraday EHCI ifdef for the long delay in usb_hub_configure() with the new configuration option:
USB_HUB_MIN_POWER_ON_DELAY, which is used in usb_hub_power_on() to control the minimum usb hub power-on delay.
- ehci-faraday: fix the invalid multi-line comment style.
- gadget-fotg210: coding style cleanup.
- gadget-fotg210: drop postfix '__iomem' from struct fotg210_regs
- gadget-fotg210: use permanent delay for hardware reset
- gadget-fotg210: drop '#ifndef CONFIG_SYS_DCACHE_OFF'
- gadget-fotg210: drop magic numbers

Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

Kuo-Jung Su (4):
usb: hub: make minimum power-on delay configurable
usb: ehci: add weak-aliased function for PORTSC
usb: ehci: add Faraday USB 2.0 EHCI support
usb: gadget: add Faraday FOTG210 USB gadget support

 README                            |    3 +
 common/usb_hub.c                  |   15 +-
 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  948 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 drivers/usb/host/Makefile         |    1 +
 drivers/usb/host/ehci-faraday.c   |  154 ++++++
 drivers/usb/host/ehci-hcd.c       |   28 +-
 include/usb/fotg210.h             |  364 ++++++++++++++
 include/usb/fusbh200.h            |   61 +++
 10 files changed, 1576 insertions(+), 7 deletions(-)
 create mode 100644 drivers/usb/gadget/fotg210.c
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h

--
1.7.9.5

#83 lore raw

PATCH v7 1/4 usb: hub: make minimum power-on delay configurable

From: Kuo-Jung Su <[email protected]>

This patch makes the minimum power-on delay for USB HUB become configurable. The original design waits at least 100 msec here, but some EHCI controlers(e.g. Faraday EHCI) are known to require much longer delay interval.

---
Changes for v7:
- Rebase to u-boot-bbd0f7e3ba66d288a2f146f1c7797801e04598ae

Changes for v6:
- Simplify CONFIG_USB_HUB_MIN_POWER_ON_DELAY default value setup.

Changes for v5:
- Split up from Faraday EHCI patch
- Replace the Faraday EHCI ifdef for the long delay
in usb_hub_configure() with the new configuration option:
USB_HUB_MIN_POWER_ON_DELAY, which is used in usb_hub_power_on() to control the minimum usb hub power-on delay.

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 README           |    3 +++
 common/usb_hub.c |    8 ++++++--
 2 files changed, 9 insertions(+), 2 deletions(-)
README +3 -0
index 0d37d56..c70a59b 100644
@@ -1244,6 +1244,9 @@ The following options need to be configured:
 		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
 		txfilltuning field in the EHCI controller on reset.
 
+		CONFIG_USB_HUB_MIN_POWER_ON_DELAY defines the minimum
+		interval for usb hub power-on delay.(minimum 100msec)
+
 - USB Device:
 		Define the below if you wish to use the USB console.
 		Once firmware is rebuilt from a serial console issue the
common/usb_hub.c +6 -2
index 0d79ec3..fc3a8c1 100644
@@ -53,6 +53,10 @@
 #include <asm/4xx_pci.h>
 #endif
 
+#ifndef CONFIG_USB_HUB_MIN_POWER_ON_DELAY
+#define CONFIG_USB_HUB_MIN_POWER_ON_DELAY	100
+#endif
+
 #define USB_BUFSIZ	512
 
 static struct usb_hub_device hub_dev[USB_MAX_HUB];
@@ -148,8 +152,8 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
 		debug("port %d returns %lX\n", i + 1, dev->status);
 	}
 
-	/* Wait at least 100 msec for power to become stable */
-	mdelay(max(pgood_delay, (unsigned)100));
+	/* Wait for power to become stable */
+	mdelay(max(pgood_delay, CONFIG_USB_HUB_MIN_POWER_ON_DELAY));
 }
 
 void usb_hub_reset(void)

--
1.7.9.5

#84 lore raw

v8 cover usb: add Faraday EHCI & Gadget support

From: Kuo-Jung Su <[email protected]>

This patch adds support to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI are listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differs from standard EHCI in several ways. But since U-boot doesn't support ISOC, we don't have to worry about that.

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device at a time.

Changes for v8:
- ehci-faraday: ehci_get_portsc_register():
Bug fixed, only port=0 is accepted.

Changes for v7:
- Rebase to u-boot-bbd0f7e3ba66d288a2f146f1c7797801e04598ae, and also make sure it's compatible to u-boot-usb-dc69e46302a36e60e2417bba8c6ea78761a37ebf.
- Update TDI aliased functions, since there is another similar patch had been committed and acceptted.
- ehci-hcd: ehci_get_portsc_register(): make sure port is always >= 0

Changes for v6:
- usb_hub: Simplify CONFIG_USB_HUB_MIN_POWER_ON_DELAY default value setup.
- ehci-hcd: Simplify weak aliased function declaration
- ehci-hcd: Drop redundant line feed

Changes for v5:
- Split up EHCI changeset
- usb_hub: replace the Faraday EHCI ifdef for the long delay in usb_hub_configure() with the new configuration option:
USB_HUB_MIN_POWER_ON_DELAY, which is used in usb_hub_power_on() to control the minimum usb hub power-on delay.
- ehci-faraday: fix the invalid multi-line comment style.
- gadget-fotg210: coding style cleanup.
- gadget-fotg210: drop postfix '__iomem' from struct fotg210_regs
- gadget-fotg210: use permanent delay for hardware reset
- gadget-fotg210: drop '#ifndef CONFIG_SYS_DCACHE_OFF'
- gadget-fotg210: drop magic numbers

Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

Kuo-Jung Su (4):
usb: hub: make minimum power-on delay configurable
usb: ehci: add weak-aliased function for PORTSC
usb: ehci: add Faraday USB 2.0 EHCI support
usb: gadget: add Faraday FOTG210 USB gadget support

 README                            |    3 +
 common/usb_hub.c                  |   15 +-
 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  948 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 drivers/usb/host/Makefile         |    1 +
 drivers/usb/host/ehci-faraday.c   |  154 ++++++
 drivers/usb/host/ehci-hcd.c       |   28 +-
 include/usb/fotg210.h             |  364 ++++++++++++++
 include/usb/fusbh200.h            |   61 +++
 10 files changed, 1576 insertions(+), 7 deletions(-)
 create mode 100644 drivers/usb/gadget/fotg210.c
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h

--
1.7.9.5

#85 lore raw

PATCH v8 1/4 usb: hub: make minimum power-on delay configurable

From: Kuo-Jung Su <[email protected]>

This patch makes the minimum power-on delay for USB HUB become configurable. The original design waits at least 100 msec here, but some EHCI controlers(e.g. Faraday EHCI) are known to require much longer delay interval.

---
Changes for v8:
- Nothing updates

Changes for v7:
- Rebase to u-boot-bbd0f7e3ba66d288a2f146f1c7797801e04598ae

Changes for v6:
- Simplify CONFIG_USB_HUB_MIN_POWER_ON_DELAY default value setup.

Changes for v5:
- Split up from Faraday EHCI patch
- Replace the Faraday EHCI ifdef for the long delay
in usb_hub_configure() with the new configuration option:
USB_HUB_MIN_POWER_ON_DELAY, which is used in usb_hub_power_on() to control the minimum usb hub power-on delay.

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 README           |    3 +++
 common/usb_hub.c |    8 ++++++--
 2 files changed, 9 insertions(+), 2 deletions(-)
README +3 -0
index 0d37d56..c70a59b 100644
@@ -1244,6 +1244,9 @@ The following options need to be configured:
 		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
 		txfilltuning field in the EHCI controller on reset.
 
+		CONFIG_USB_HUB_MIN_POWER_ON_DELAY defines the minimum
+		interval for usb hub power-on delay.(minimum 100msec)
+
 - USB Device:
 		Define the below if you wish to use the USB console.
 		Once firmware is rebuilt from a serial console issue the
common/usb_hub.c +6 -2
index 0d79ec3..fc3a8c1 100644
@@ -53,6 +53,10 @@
 #include <asm/4xx_pci.h>
 #endif
 
+#ifndef CONFIG_USB_HUB_MIN_POWER_ON_DELAY
+#define CONFIG_USB_HUB_MIN_POWER_ON_DELAY	100
+#endif
+
 #define USB_BUFSIZ	512
 
 static struct usb_hub_device hub_dev[USB_MAX_HUB];
@@ -148,8 +152,8 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
 		debug("port %d returns %lX\n", i + 1, dev->status);
 	}
 
-	/* Wait at least 100 msec for power to become stable */
-	mdelay(max(pgood_delay, (unsigned)100));
+	/* Wait for power to become stable */
+	mdelay(max(pgood_delay, CONFIG_USB_HUB_MIN_POWER_ON_DELAY));
 }
 
 void usb_hub_reset(void)

--
1.7.9.5

#86 lore raw

v9 cover usb: add Faraday EHCI & Gadget support

From: Kuo-Jung Su <[email protected]>

This patch adds support to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI are listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differs from standard EHCI in several ways. But since U-boot doesn't support ISOC, we don't have to worry about that.

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device at a time.

Changes for v9:
- ehci-hcd: prevent bad PORTSC register access in ehci_submit_root()
- ehci-hcd: drop the quick fix to 'port=-1' from ehci_get_portsc_register().
- ehci-faraday: drop the quick fix to 'port=-1'

Changes for v8:
- ehci-faraday: ehci_get_portsc_register():
Bug fixed, only port=0 is accepted.

Changes for v7:
- Rebase to u-boot-bbd0f7e3ba66d288a2f146f1c7797801e04598ae, and also make sure it's compatible to u-boot-usb-dc69e46302a36e60e2417bba8c6ea78761a37ebf.
- Update TDI aliased functions, since there is another similar patch had been committed and acceptted.
- ehci-hcd: ehci_get_portsc_register(): make sure port is always >= 0

Changes for v6:
- usb_hub: Simplify CONFIG_USB_HUB_MIN_POWER_ON_DELAY default value setup.
- ehci-hcd: Simplify weak aliased function declaration
- ehci-hcd: Drop redundant line feed

Changes for v5:
- Split up EHCI changeset
- usb_hub: replace the Faraday EHCI ifdef for the long delay in usb_hub_configure() with the new configuration option:
USB_HUB_MIN_POWER_ON_DELAY, which is used in usb_hub_power_on() to control the minimum usb hub power-on delay.
- ehci-faraday: fix the invalid multi-line comment style.
- gadget-fotg210: coding style cleanup.
- gadget-fotg210: drop postfix '__iomem' from struct fotg210_regs
- gadget-fotg210: use permanent delay for hardware reset
- gadget-fotg210: drop '#ifndef CONFIG_SYS_DCACHE_OFF'
- gadget-fotg210: drop magic numbers

Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

Kuo-Jung Su (5):
usb: ehci: prevent bad PORTSC register access
usb: ehci: add weak-aliased function for PORTSC
usb: hub: make minimum power-on delay configurable
usb: ehci: add Faraday USB 2.0 EHCI support
usb: gadget: add Faraday FOTG210 USB gadget support

 README                            |    3 +
 common/usb_hub.c                  |   15 +-
 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  948 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 drivers/usb/host/Makefile         |    1 +
 drivers/usb/host/ehci-faraday.c   |  148 ++++++
 drivers/usb/host/ehci-hcd.c       |   34 +-
 include/usb/fotg210.h             |  364 ++++++++++++++
 include/usb/fusbh200.h            |   61 +++
 10 files changed, 1575 insertions(+), 8 deletions(-)
 create mode 100644 drivers/usb/gadget/fotg210.c
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h

--
1.7.9.5

#87 lore raw

PATCH v9 1/5 usb: ehci: prevent bad PORTSC register access

From: Kuo-Jung Su <[email protected]>

1. The 'index' of ehci_submit_root() is not always > 0.

e.g.
While it gets invoked from usb_get_descriptor(), the 'index' is always a '0'. (See ch.9 of USB2.0)

2. The PORTSC register is not always required, and thus it should only report a port error when necessary.
It would cause a port scan failure if the ehci_submit_root() always gets terminated by a port error.

---
Changes for v9:
- 1st edition

 drivers/usb/host/ehci-hcd.c |   20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)
drivers/usb/host/ehci-hcd.c +15 -5
index e0f3e4b..6022049 100644
@@ -616,11 +616,6 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 	int port = le16_to_cpu(req->index) & 0xff;
 	struct ehci_ctrl *ctrl = dev->controller;
 
-	if (port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-		printf("The request port(%d) is not configured\n", port - 1);
-		return -1;
-	}
-	status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
 	srclen = 0;
 
 	debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
@@ -631,6 +626,21 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 	typeReq = req->request | req->requesttype << 8;
 
 	switch (typeReq) {
+	case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
+	case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
+	case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
+		if (!port || port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+			printf("The request port(%d) is not configured\n", port - 1);
+			return -1;
+		}
+		status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
+		break;
+	default:
+		status_reg = NULL;
+		break;
+	}
+
+	switch (typeReq) {
 	case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
 		switch (le16_to_cpu(req->value) >> 8) {
 		case USB_DT_DEVICE:

--
1.7.9.5

#88 lore raw

PATCH v9 1/5 usb: ehci: prevent bad PORTSC register access

Dear Kuo-Jung Su,

Works fine, thanks!

Best regards,
Marek Vasut

#89 lore raw

PATCH v9 2/5 usb: ehci: add weak-aliased function for PORTSC

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) not only leave RESERVED and CONFIGFLAG registers un-implemented but also has their address spaces removed.

As an result, the PORTSC register of Faraday EHCI always starts from 0x30 instead of 0x44 in standard EHCI.

So that we'll need a weak-aliased function for abstraction.

---
Changes for v9:
- Drop the quick fix to 'port=-1' from ehci_get_portsc_register().

Changes for v8:
- Nothing updates

Changes for v7:
- Rebase to u-boot-bbd0f7e3ba66d288a2f146f1c7797801e04598ae
- Drop TDI weak-aliased functions, since there is another similar patch had been committed and acceptted.
- ehci_get_portsc_register(): make sure port is always >= 0

Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
drivers/usb/host/ehci-hcd.c +13 -4
index 6022049..cfb2097 100644
@@ -603,6 +603,17 @@ fail:
 	return -1;
 }
 
+__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+{
+	if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+		/* Printing the message would cause a scan failure! */
+		debug("The request port(%u) is not configured\n", port);
+		return NULL;
+	}
+
+	return (uint32_t *)&hcor->or_portsc[port];
+}
+
 int
 ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 		 int length, struct devrequest *req)
@@ -629,11 +640,9 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 	case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
 	case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
 	case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
-		if (!port || port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-			printf("The request port(%d) is not configured\n", port - 1);
+		status_reg = ehci_get_portsc_register(ctrl->hcor, port - 1);
+		if (!status_reg)
 			return -1;
-		}
-		status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
 		break;
 	default:
 		status_reg = NULL;

--
1.7.9.5

#90 lore raw

PATCH v9 3/5 usb: hub: make minimum power-on delay configurable

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

This patch makes the minimum power-on delay for USB HUB become configurable. The original design waits at least 100 msec here, but some EHCI controlers(e.g. Faraday EHCI) are known to require much longer delay interval.

---
Changes for v9:
- Nothing updates

Changes for v8:
- Nothing updates

Changes for v7:
- Rebase to u-boot-bbd0f7e3ba66d288a2f146f1c7797801e04598ae

Changes for v6:
- Simplify CONFIG_USB_HUB_MIN_POWER_ON_DELAY default value setup.

Changes for v5:
- Split up from Faraday EHCI patch
- Replace the Faraday EHCI ifdef for the long delay
in usb_hub_configure() with the new configuration option:
USB_HUB_MIN_POWER_ON_DELAY, which is used in usb_hub_power_on() to control the minimum usb hub power-on delay.

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 README           |    3 +++
 common/usb_hub.c |    8 ++++++--
 2 files changed, 9 insertions(+), 2 deletions(-)
README +3 -0
index defdedb..5bf4791 100644
@@ -1245,6 +1245,9 @@ The following options need to be configured:
 		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
 		txfilltuning field in the EHCI controller on reset.
 
+		CONFIG_USB_HUB_MIN_POWER_ON_DELAY defines the minimum
+		interval for usb hub power-on delay.(minimum 100msec)
+
 - USB Device:
 		Define the below if you wish to use the USB console.
 		Once firmware is rebuilt from a serial console issue the
common/usb_hub.c +6 -2
index 0d79ec3..fc3a8c1 100644
@@ -53,6 +53,10 @@
 #include <asm/4xx_pci.h>
 #endif
 
+#ifndef CONFIG_USB_HUB_MIN_POWER_ON_DELAY
+#define CONFIG_USB_HUB_MIN_POWER_ON_DELAY	100
+#endif
+
 #define USB_BUFSIZ	512
 
 static struct usb_hub_device hub_dev[USB_MAX_HUB];
@@ -148,8 +152,8 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
 		debug("port %d returns %lX\n", i + 1, dev->status);
 	}
 
-	/* Wait at least 100 msec for power to become stable */
-	mdelay(max(pgood_delay, (unsigned)100));
+	/* Wait for power to become stable */
+	mdelay(max(pgood_delay, CONFIG_USB_HUB_MIN_POWER_ON_DELAY));
 }
 
 void usb_hub_reset(void)

--
1.7.9.5

#91 lore raw

PATCH v9 4/5 usb: ehci: add Faraday USB 2.0 EHCI support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

This patch adds support to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI are listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address space removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differ from standard EHCI in several ways. But since U-boot doesn't support ISOC, we don't have to worry about that.

---
Changes for v9:
- Drop the quick fix to 'port=-1' from ehci_get_portsc_register().

Changes for v8:
- ehci-faraday: ehci_get_portsc_register():
Bug fixed, only port=0 is accepted.

Changes for v7:
- Nothing updates

Changes for v6:
- Nothing updates

Changes for v5:
- Break down EHCI changes as seperate changesets.
- Fix the invalid multi-line comment style.

Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 common/usb_hub.c                |    7 +-
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-faraday.c |  148 ++++++++++++++++
 drivers/usb/host/ehci-hcd.c     |    5 +
 include/usb/fotg210.h           |  364 +++++++++++++++++++++++++++++++++++++++
 include/usb/fusbh200.h          |   61 +++++++
 6 files changed, 585 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h
common/usb_hub.c +6 -1
index fc3a8c1..774ba63 100644
@@ -489,7 +489,11 @@ static int usb_hub_configure(struct usb_device *dev)
 			      i + 1, portstatus);
 			usb_clear_port_feature(dev, i + 1,
 						USB_PORT_FEAT_C_ENABLE);
-
+			/*
+			 * The following hack causes a ghost device problem
+			 * to Faraday EHCI
+			 */
+#ifndef CONFIG_USB_EHCI_FARADAY
 			/* EM interference sometimes causes bad shielded USB
 			 * devices to be shutdown by the hub, this hack enables
 			 * them again. Works at least with mouse driver */
@@ -501,6 +505,7 @@ static int usb_hub_configure(struct usb_device *dev)
 				      "re-enabling...\n", i + 1);
 				      usb_hub_port_connect_change(dev, i);
 			}
+#endif
 		}
 		if (portstatus & USB_PORT_STAT_SUSPEND) {
 			debug("port %d suspend change\n", i + 1);
drivers/usb/host/Makefile +1 -0
index 87a5970..98f2a10 100644
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o
 else
 COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
 endif
+COBJS-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o
 COBJS-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
 COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
 COBJS-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o
drivers/usb/host/ehci-faraday.c new file +148 -0

148 lines not on this page · raw message

drivers/usb/host/ehci-hcd.c +5 -0
index cfb2097..f6b4854 100644
@@ -589,10 +589,12 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		dev->act_len = length - QT_TOKEN_GET_TOTALBYTES(token);
 	} else {
 		dev->act_len = 0;
+#ifndef CONFIG_USB_EHCI_FARADAY
 		debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n",
 		      dev->devnum, ehci_readl(&ctrl->hcor->or_usbsts),
 		      ehci_readl(&ctrl->hcor->or_portsc[0]),
 		      ehci_readl(&ctrl->hcor->or_portsc[1]));
+#endif
 	}
 
 	free(qtd);
@@ -978,10 +980,13 @@ int usb_lowlevel_init(int index, void **controller)
 	cmd |= CMD_RUN;
 	ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
 
+#ifndef CONFIG_USB_EHCI_FARADAY
 	/* take control over the ports */
 	cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
 	cmd |= FLAG_CF;
 	ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
+#endif
+
 	/* unblock posted write */
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
 	mdelay(5);
include/usb/fotg210.h new file +364 -0

364 lines not on this page · raw message

include/usb/fusbh200.h new file +61 -0

61 lines not on this page · raw message

--
1.7.9.5

#92 lore raw

PATCH v9 5/5 usb: gadget: add Faraday FOTG210 USB gadget support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device at a time.

---
Changes for v9:
- Nothing updates

Changes for v8:
- Nothing updates

Changes for v7:
- Nothing updates

Changes for v6:
- Nothing updates

Changes for v5:
- Coding Style cleanup.
- Drop postfix '__iomem' from struct fotg210_regs
- Use permanent delay for hardware reset
- Drop '#ifndef CONFIG_SYS_DCACHE_OFF'
- Drop magic numbers

Changes for v4:
- Use only macro constants and named bit/mask
- Remove dcache_enable() from usb_gadget_register_driver()

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  948 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 3 files changed, 957 insertions(+)
 create mode 100644 drivers/usb/gadget/fotg210.c
drivers/usb/gadget/Makefile +1 -0
index e545b6b..432cf17 100644
@@ -35,6 +35,7 @@ endif
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
 endif
drivers/usb/gadget/fotg210.c new file +948 -0

948 lines not on this page · raw message

drivers/usb/gadget/gadget_chips.h +8 -0
index e570142..f038747 100644
@@ -150,6 +150,12 @@
 #define gadget_is_mv(g)        0
 #endif
 
+#ifdef CONFIG_USB_GADGET_FOTG210
+#define gadget_is_fotg210(g)        (!strcmp("fotg210_udc", (g)->name))
+#else
+#define gadget_is_fotg210(g)        0
+#endif
+
 /*
  * CONFIG_USB_GADGET_SX2
  * CONFIG_USB_GADGET_AU1X00
@@ -215,5 +221,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
 		return 0x20;
 	else if (gadget_is_mv(gadget))
 		return 0x21;
+	else if (gadget_is_fotg210(gadget))
+		return 0x22;
 	return -ENOENT;
 }

--
1.7.9.5

#94 lore raw

PATCH v9 5/5 usb: gadget: add Faraday FOTG210 USB gadget support

2013/5/20 Marek Vasut <[email protected]>:

Quoted 7 lines

Dear Kuo-Jung Su,

Quoted 5 lines

From: Kuo-Jung Su <[email protected]>

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device at a time.

Quoted 7 lines
Quoted 2 lines

I'll test those on monday on EHCI system.

Best regards,
Marek Vasut

Got it, thanks!

--
Best wishes,
Kuo-Jung Su

#95 lore raw

PATCH v8 2/4 usb: ehci: add weak-aliased function for PORTSC

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) not only leave RESERVED and CONFIGFLAG registers un-implemented but also has their address spaces removed.

As an result, the PORTSC register of Faraday EHCI always starts from 0x30 instead of 0x44 in standard EHCI.

So that we'll need a weak-aliased function for abstraction.

---
Changes for v8:
- Nothing updates

Changes for v7:
- Rebase to u-boot-bbd0f7e3ba66d288a2f146f1c7797801e04598ae
- Drop TDI weak-aliased functions, since there is another similar patch had been committed and acceptted.
- ehci_get_portsc_register(): make sure port is always >= 0

Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)
drivers/usb/host/ehci-hcd.c +19 -4
index e0f3e4b..316de15 100644
@@ -603,6 +603,23 @@ fail:
 	return -1;
 }
 
+__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+{
+	/*
+	 * The u-boot would somehow set port=-1 at usb start-up,
+	 * so this quick fix is necessary.
+	 */
+	if (port < 0)
+		port = 0;
+
+	if (port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+		printf("The request port(%u) is not configured\n", port);
+		return NULL;
+	}
+
+	return (uint32_t *)&hcor->or_portsc[port];
+}
+
 int
 ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 		 int length, struct devrequest *req)
@@ -616,11 +633,9 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 	int port = le16_to_cpu(req->index) & 0xff;
 	struct ehci_ctrl *ctrl = dev->controller;
 
-	if (port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-		printf("The request port(%d) is not configured\n", port - 1);
+	status_reg = ehci_get_portsc_register(ctrl->hcor, port - 1);
+	if (!status_reg)
 		return -1;
-	}
-	status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
 	srclen = 0;
 
 	debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",

--
1.7.9.5

#96 lore raw

PATCH v8 3/4 usb: ehci: add Faraday USB 2.0 EHCI support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

This patch adds support to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI are listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address space removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differ from standard EHCI in several ways. But since U-boot doesn't support ISOC, we don't have to worry about that.

---
Changes for v8:
- ehci-faraday: ehci_get_portsc_register():
Bug fixed, only port=0 is accepted.

Changes for v7:
- Nothing updates

Changes for v6:
- Nothing updates

Changes for v5:
- Break down EHCI changes as seperate changesets.
- Fix the invalid multi-line comment style.

Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 common/usb_hub.c                |    7 +-
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-faraday.c |  154 +++++++++++++++++
 drivers/usb/host/ehci-hcd.c     |    5 +
 include/usb/fotg210.h           |  364 +++++++++++++++++++++++++++++++++++++++
 include/usb/fusbh200.h          |   61 +++++++
 6 files changed, 591 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h
common/usb_hub.c +6 -1
index fc3a8c1..774ba63 100644
@@ -489,7 +489,11 @@ static int usb_hub_configure(struct usb_device *dev)
 			      i + 1, portstatus);
 			usb_clear_port_feature(dev, i + 1,
 						USB_PORT_FEAT_C_ENABLE);
-
+			/*
+			 * The following hack causes a ghost device problem
+			 * to Faraday EHCI
+			 */
+#ifndef CONFIG_USB_EHCI_FARADAY
 			/* EM interference sometimes causes bad shielded USB
 			 * devices to be shutdown by the hub, this hack enables
 			 * them again. Works at least with mouse driver */
@@ -501,6 +505,7 @@ static int usb_hub_configure(struct usb_device *dev)
 				      "re-enabling...\n", i + 1);
 				      usb_hub_port_connect_change(dev, i);
 			}
+#endif
 		}
 		if (portstatus & USB_PORT_STAT_SUSPEND) {
 			debug("port %d suspend change\n", i + 1);
drivers/usb/host/Makefile +1 -0
index 87a5970..98f2a10 100644
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o
 else
 COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
 endif
+COBJS-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o
 COBJS-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
 COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
 COBJS-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o
drivers/usb/host/ehci-faraday.c new file +154 -0

154 lines not on this page · raw message

drivers/usb/host/ehci-hcd.c +5 -0
index 316de15..be18a02 100644
@@ -589,10 +589,12 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		dev->act_len = length - QT_TOKEN_GET_TOTALBYTES(token);
 	} else {
 		dev->act_len = 0;
+#ifndef CONFIG_USB_EHCI_FARADAY
 		debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n",
 		      dev->devnum, ehci_readl(&ctrl->hcor->or_usbsts),
 		      ehci_readl(&ctrl->hcor->or_portsc[0]),
 		      ehci_readl(&ctrl->hcor->or_portsc[1]));
+#endif
 	}
 
 	free(qtd);
@@ -974,10 +976,13 @@ int usb_lowlevel_init(int index, void **controller)
 	cmd |= CMD_RUN;
 	ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
 
+#ifndef CONFIG_USB_EHCI_FARADAY
 	/* take control over the ports */
 	cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
 	cmd |= FLAG_CF;
 	ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
+#endif
+
 	/* unblock posted write */
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
 	mdelay(5);
include/usb/fotg210.h new file +364 -0

364 lines not on this page · raw message

include/usb/fusbh200.h new file +61 -0

61 lines not on this page · raw message

--
1.7.9.5

#97 lore raw

PATCH v8 4/4 usb: gadget: add Faraday FOTG210 USB gadget support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device at a time.

---
Changes for v8:
- Nothing updates

Changes for v7:
- Nothing updates

Changes for v6:
- Nothing updates

Changes for v5:
- Coding Style cleanup.
- Drop postfix '__iomem' from struct fotg210_regs
- Use permanent delay for hardware reset
- Drop '#ifndef CONFIG_SYS_DCACHE_OFF'
- Drop magic numbers

Changes for v4:
- Use only macro constants and named bit/mask
- Remove dcache_enable() from usb_gadget_register_driver()

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  948 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 3 files changed, 957 insertions(+)
 create mode 100644 drivers/usb/gadget/fotg210.c
drivers/usb/gadget/Makefile +1 -0
index e545b6b..432cf17 100644
@@ -35,6 +35,7 @@ endif
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
 endif
drivers/usb/gadget/fotg210.c new file +948 -0

948 lines not on this page · raw message

drivers/usb/gadget/gadget_chips.h +8 -0
index e570142..f038747 100644
@@ -150,6 +150,12 @@
 #define gadget_is_mv(g)        0
 #endif
 
+#ifdef CONFIG_USB_GADGET_FOTG210
+#define gadget_is_fotg210(g)        (!strcmp("fotg210_udc", (g)->name))
+#else
+#define gadget_is_fotg210(g)        0
+#endif
+
 /*
  * CONFIG_USB_GADGET_SX2
  * CONFIG_USB_GADGET_AU1X00
@@ -215,5 +221,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
 		return 0x20;
 	else if (gadget_is_mv(gadget))
 		return 0x21;
+	else if (gadget_is_fotg210(gadget))
+		return 0x22;
 	return -ENOENT;
 }

--
1.7.9.5

#98 lore raw

PATCH v7 2/4 usb: ehci: add weak-aliased function for PORTSC

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) not only leave RESERVED and CONFIGFLAG registers un-implemented but also has their address spaces removed.

As an result, the PORTSC register of Faraday EHCI always starts from 0x30 instead of 0x44 in standard EHCI.

So that we'll need a weak-aliased function for abstraction.

---
Changes for v7:
- Rebase to u-boot-bbd0f7e3ba66d288a2f146f1c7797801e04598ae
- Drop TDI weak-aliased functions, since there is another similar patch had been committed and acceptted.
- ehci_get_portsc_register(): make sure port is always >= 0

Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)
drivers/usb/host/ehci-hcd.c +19 -4
index e0f3e4b..316de15 100644
@@ -603,6 +603,23 @@ fail:
 	return -1;
 }
 
+__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+{
+	/*
+	 * The u-boot would somehow set port=-1 at usb start-up,
+	 * so this quick fix is necessary.
+	 */
+	if (port < 0)
+		port = 0;
+
+	if (port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+		printf("The request port(%u) is not configured\n", port);
+		return NULL;
+	}
+
+	return (uint32_t *)&hcor->or_portsc[port];
+}
+
 int
 ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 		 int length, struct devrequest *req)
@@ -616,11 +633,9 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 	int port = le16_to_cpu(req->index) & 0xff;
 	struct ehci_ctrl *ctrl = dev->controller;
 
-	if (port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-		printf("The request port(%d) is not configured\n", port - 1);
+	status_reg = ehci_get_portsc_register(ctrl->hcor, port - 1);
+	if (!status_reg)
 		return -1;
-	}
-	status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
 	srclen = 0;
 
 	debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",

--
1.7.9.5

#99 lore raw

PATCH v7 3/4 usb: ehci: add Faraday USB 2.0 EHCI support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

This patch adds support to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI are listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address space removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differ from standard EHCI in several ways. But since U-boot doesn't support ISOC, we don't have to worry about that.

---
Changes for v7:
- Nothing updates

Changes for v6:
- Nothing updates

Changes for v5:
- Break down EHCI changes as seperate changesets.
- Fix the invalid multi-line comment style.

Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 common/usb_hub.c                |    7 +-
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-faraday.c |  154 +++++++++++++++++
 drivers/usb/host/ehci-hcd.c     |    5 +
 include/usb/fotg210.h           |  364 +++++++++++++++++++++++++++++++++++++++
 include/usb/fusbh200.h          |   61 +++++++
 6 files changed, 591 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h
common/usb_hub.c +6 -1
index fc3a8c1..774ba63 100644
@@ -489,7 +489,11 @@ static int usb_hub_configure(struct usb_device *dev)
 			      i + 1, portstatus);
 			usb_clear_port_feature(dev, i + 1,
 						USB_PORT_FEAT_C_ENABLE);
-
+			/*
+			 * The following hack causes a ghost device problem
+			 * to Faraday EHCI
+			 */
+#ifndef CONFIG_USB_EHCI_FARADAY
 			/* EM interference sometimes causes bad shielded USB
 			 * devices to be shutdown by the hub, this hack enables
 			 * them again. Works at least with mouse driver */
@@ -501,6 +505,7 @@ static int usb_hub_configure(struct usb_device *dev)
 				      "re-enabling...\n", i + 1);
 				      usb_hub_port_connect_change(dev, i);
 			}
+#endif
 		}
 		if (portstatus & USB_PORT_STAT_SUSPEND) {
 			debug("port %d suspend change\n", i + 1);
drivers/usb/host/Makefile +1 -0
index 87a5970..98f2a10 100644
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o
 else
 COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
 endif
+COBJS-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o
 COBJS-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
 COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
 COBJS-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o
drivers/usb/host/ehci-faraday.c new file +154 -0

154 lines not on this page · raw message

drivers/usb/host/ehci-hcd.c +5 -0
index 316de15..be18a02 100644
@@ -589,10 +589,12 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		dev->act_len = length - QT_TOKEN_GET_TOTALBYTES(token);
 	} else {
 		dev->act_len = 0;
+#ifndef CONFIG_USB_EHCI_FARADAY
 		debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n",
 		      dev->devnum, ehci_readl(&ctrl->hcor->or_usbsts),
 		      ehci_readl(&ctrl->hcor->or_portsc[0]),
 		      ehci_readl(&ctrl->hcor->or_portsc[1]));
+#endif
 	}
 
 	free(qtd);
@@ -974,10 +976,13 @@ int usb_lowlevel_init(int index, void **controller)
 	cmd |= CMD_RUN;
 	ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
 
+#ifndef CONFIG_USB_EHCI_FARADAY
 	/* take control over the ports */
 	cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
 	cmd |= FLAG_CF;
 	ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
+#endif
+
 	/* unblock posted write */
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
 	mdelay(5);
include/usb/fotg210.h new file +364 -0

364 lines not on this page · raw message

include/usb/fusbh200.h new file +61 -0

61 lines not on this page · raw message

--
1.7.9.5

#100 lore raw

PATCH v7 4/4 usb: gadget: add Faraday FOTG210 USB gadget support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device at a time.

---
Changes for v7:
- Nothing updates

Changes for v6:
- Nothing updates

Changes for v5:
- Coding Style cleanup.
- Drop postfix '__iomem' from struct fotg210_regs
- Use permanent delay for hardware reset
- Drop '#ifndef CONFIG_SYS_DCACHE_OFF'
- Drop magic numbers

Changes for v4:
- Use only macro constants and named bit/mask
- Remove dcache_enable() from usb_gadget_register_driver()

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  948 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 3 files changed, 957 insertions(+)
 create mode 100644 drivers/usb/gadget/fotg210.c
drivers/usb/gadget/Makefile +1 -0
index e545b6b..432cf17 100644
@@ -35,6 +35,7 @@ endif
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
 endif
drivers/usb/gadget/fotg210.c new file +948 -0

948 lines not on this page · raw message

drivers/usb/gadget/gadget_chips.h +8 -0
index e570142..f038747 100644
@@ -150,6 +150,12 @@
 #define gadget_is_mv(g)        0
 #endif
 
+#ifdef CONFIG_USB_GADGET_FOTG210
+#define gadget_is_fotg210(g)        (!strcmp("fotg210_udc", (g)->name))
+#else
+#define gadget_is_fotg210(g)        0
+#endif
+
 /*
  * CONFIG_USB_GADGET_SX2
  * CONFIG_USB_GADGET_AU1X00
@@ -215,5 +221,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
 		return 0x20;
 	else if (gadget_is_mv(gadget))
 		return 0x21;
+	else if (gadget_is_fotg210(gadget))
+		return 0x22;
 	return -ENOENT;
 }

--
1.7.9.5

#101 lore raw

PATCH v6 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff.
Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---
Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   91 ++++++++++++++++++++++++++-----------------
 1 file changed, 55 insertions(+), 36 deletions(-)
drivers/usb/host/ehci-hcd.c +55 -36
index c816878..ae3f2a4 100644
@@ -117,10 +117,44 @@ static struct descriptor {
 };
 
 #if defined(CONFIG_EHCI_IS_TDI)
-#define ehci_is_TDI()	(1)
-#else
-#define ehci_is_TDI()	(0)
+# define ehci_is_TDI()	(1)
+
+/* put TDI/ARC silicon into EHCI mode */
+__weak void ehci_tdi_reset(struct ehci_hcor *hcor)
+{
+	uint32_t tmp, *reg_ptr;
+
+	reg_ptr = (uint32_t *)((uint8_t *) + USBMODE);
+	tmp = ehci_readl(reg_ptr);
+	tmp |= USBMODE_CM_HC;
+#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
+	tmp |= USBMODE_BE;
 #endif
+	ehci_writel(reg_ptr, tmp);
+}
+
+__weak int ehci_port_speed(struct ehci_hcor *hcor, unsigned int portsc)
+{
+	int ret = 0;
+
+	switch (PORTSC_PSPD(portsc)) {
+	case PORTSC_PSPD_FS:
+		break;
+	case PORTSC_PSPD_LS:
+		ret = USB_PORT_STAT_LOW_SPEED;
+		break;
+	case PORTSC_PSPD_HS:
+	default:
+		ret = USB_PORT_STAT_HIGH_SPEED;
+		break;
+	}
+
+	return ret;
+}
+
+#else  /* CONFIG_EHCI_IS_TDI */
+# define ehci_is_TDI()	(0)
+#endif /* CONFIG_EHCI_IS_TDI */
 
 void __ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
 {
@@ -149,8 +183,6 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
 static int ehci_reset(int index)
 {
 	uint32_t cmd;
-	uint32_t tmp;
-	uint32_t *reg_ptr;
 	int ret = 0;
 
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
@@ -163,15 +195,8 @@ static int ehci_reset(int index)
 		goto out;
 	}
 
-	if (ehci_is_TDI()) {
-		reg_ptr = (uint32_t *)((u8 *)ehcic[index].hcor + USBMODE);
-		tmp = ehci_readl(reg_ptr);
-		tmp |= USBMODE_CM_HC;
-#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
-		tmp |= USBMODE_BE;
-#endif
-		ehci_writel(reg_ptr, tmp);
-	}
+	if (ehci_is_TDI())
+		ehci_tdi_reset(ehcic[index].hcor);
 
 #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
 	cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
@@ -597,6 +622,16 @@ static inline int min3(int a, int b, int c)
 	return a;
 }
 
+__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+{
+	if (port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+		printf("The request port(%d) is not configured\n", port);
+		return NULL;
+	}
+
+	return (uint32_t *)&hcor->or_portsc[port];
+}
+
 int
 ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 		 int length, struct devrequest *req)
@@ -609,13 +644,10 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 	uint32_t *status_reg;
 	struct ehci_ctrl *ctrl = dev->controller;
 
-	if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-		printf("The request port(%d) is not configured\n",
-			le16_to_cpu(req->index) - 1);
+	status_reg = ehci_get_portsc_register(ctrl->hcor,
+		le16_to_cpu(req->index) - 1);
+	if (!status_reg)
 		return -1;
-	}
-	status_reg = (uint32_t *)&ctrl->hcor->or_portsc[
-						le16_to_cpu(req->index) - 1];
 	srclen = 0;
 
 	debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
@@ -709,23 +741,10 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			tmpbuf[0] |= USB_PORT_STAT_RESET;
 		if (reg & EHCI_PS_PP)
 			tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
-
-		if (ehci_is_TDI()) {
-			switch (PORTSC_PSPD(reg)) {
-			case PORTSC_PSPD_FS:
-				break;
-			case PORTSC_PSPD_LS:
-				tmpbuf[1] |= USB_PORT_STAT_LOW_SPEED >> 8;
-				break;
-			case PORTSC_PSPD_HS:
-			default:
-				tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
-				break;
-			}
-		} else {
+		if (ehci_is_TDI())
+			tmpbuf[1] |= ehci_port_speed(ctrl->hcor, reg) >> 8;
+		else
 			tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
-		}
-
 		if (reg & EHCI_PS_CSC)
 			tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
 		if (reg & EHCI_PS_PEC)

--
1.7.9.5

#102 lore raw

PATCH v6 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

Dear Kuo-Jung Su,

Quoted 32 lines

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff.
Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---
Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   91

++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 36 deletions(-)

drivers/usb/host/ehci-hcd.c +0 -0
index c816878..ae3f2a4 100644

drivers/usb/host/ehci-hcd.c static struct descriptor { · line 120

Quoted 7 lines
drivers/usb/host/ehci-hcd.c +1 -3
@@ -117,10 +117,44 @@ static struct descriptor {
 };
 
 #if defined(CONFIG_EHCI_IS_TDI)
-#define ehci_is_TDI()	(1)
-#else
-#define ehci_is_TDI()	(0)
+# define ehci_is_TDI()	(1)

btw you can remove those braces around (1) and (0) below. But I have one more question ...

[...]

drivers/usb/host/ehci-hcd.c ehci_submit_root(struct usb_device *dev, unsigned · line 649

Quoted 10 lines
drivers/usb/host/ehci-hcd.c +3 -3
@@ -609,13 +644,10 @@ ehci_submit_root(struct usb_device *dev, unsigned
 long pipe, void *buffer, uint32_t *status_reg;
 	struct ehci_ctrl *ctrl = dev->controller;
 
-	if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-		printf("The request port(%d) is not configured\n",
-			le16_to_cpu(req->index) - 1);
+	status_reg = ehci_get_portsc_register(ctrl->hcor,
+		le16_to_cpu(req->index) - 1);
+	if (!status_reg)

What happens here if req->index is zero ?

Hint: the above code always does unsigned comparison ...

I think you should make the second argument of ehci_get_portsc_register() unsigned short too (as is req->index in struct devrequest).

drivers/usb/host/ehci-hcd.c ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, · line 653

Quoted 7 lines
drivers/usb/host/ehci-hcd.c +0 -3
 		return -1;
-	}
-	status_reg = (uint32_t *)&ctrl->hcor->or_portsc[
-						le16_to_cpu(req->index) - 1];
 	srclen = 0;
 
 	debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",

[...]

Best regards,
Marek Vasut

#103 lore raw

PATCH v6 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

2013/5/13 Marek Vasut <[email protected]>:

Quoted 36 lines

Dear Kuo-Jung Su,

Quoted 34 lines

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff.
Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---
Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   91

++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 36 deletions(-)

drivers/usb/host/ehci-hcd.c +0 -0
index c816878..ae3f2a4 100644
@@ -117,10 +117,44 @@ static struct descriptor {
 };
 
Quoted 9 lines

drivers/usb/host/ehci-hcd.c static struct descriptor { · line 120

Quoted 5 lines
drivers/usb/host/ehci-hcd.c +1 -3
 #if defined(CONFIG_EHCI_IS_TDI)
-#define ehci_is_TDI()        (1)
-#else
-#define ehci_is_TDI()        (0)
+# define ehci_is_TDI()       (1)

btw you can remove those braces around (1) and (0) below. But I have one more question ...

Got it, thanks

Quoted 15 lines

[...]

drivers/usb/host/ehci-hcd.c ehci_submit_root(struct usb_device *dev, unsigned · line 649

Quoted 10 lines
drivers/usb/host/ehci-hcd.c +3 -3
@@ -609,13 +644,10 @@ ehci_submit_root(struct usb_device *dev, unsigned
 long pipe, void *buffer, uint32_t *status_reg;
      struct ehci_ctrl *ctrl = dev->controller;
 
-     if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-             printf("The request port(%d) is not configured\n",
-                     le16_to_cpu(req->index) - 1);
+     status_reg = ehci_get_portsc_register(ctrl->hcor,
+             le16_to_cpu(req->index) - 1);
+     if (!status_reg)

What happens here if req->index is zero ?

Quoted 5 lines

Hint: the above code always does unsigned comparison ...

I think you should make the second argument of ehci_get_portsc_register() unsigned short too (as is req->index in struct devrequest).

Sorry, but I'll prefer 'int' over 'unsigned short', since it looks to me that the u-boot would set 'req->index' to 0 at startup, which results in a 'port = -1' to be passed to ehci_get_portsc_register().

And I think '-1' is a better self-explain value, so I'd like to stick with 'int'

Quoted 6 lines
Quoted 6 lines
drivers/usb/host/ehci-hcd.c +0 -3
              return -1;
-     }
-     status_reg = (uint32_t *)&ctrl->hcor->or_portsc[
-                                             le16_to_cpu(req->index) - 1];
      srclen = 0;
 
Quoted 6 lines

drivers/usb/host/ehci-hcd.c ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, · line 653

Quoted 1 line
drivers/usb/host/ehci-hcd.c +0 -0
      debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",

[...]

Best regards,
Marek Vasut

--
Best wishes,
Kuo-Jung Su

#104 lore raw

PATCH v6 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

Dear Kuo-Jung Su,

Quoted 73 lines

2013/5/13 Marek Vasut <[email protected]>:

Quoted 41 lines

Dear Kuo-Jung Su,

Quoted 39 lines

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff.
Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---

Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   91

++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 36 deletions(-)

drivers/usb/host/ehci-hcd.c +0 -0
index c816878..ae3f2a4 100644
@@ -117,10 +117,44 @@ static struct descriptor {
 
 };
 
 #if defined(CONFIG_EHCI_IS_TDI)
 
Quoted 7 lines

drivers/usb/host/ehci-hcd.c static struct descriptor { · line 120

Quoted 4 lines
drivers/usb/host/ehci-hcd.c +1 -3
-#define ehci_is_TDI()        (1)
-#else
-#define ehci_is_TDI()        (0)
+# define ehci_is_TDI()       (1)

btw you can remove those braces around (1) and (0) below. But I have one more question ...

Got it, thanks

Quoted 16 lines

[...]

drivers/usb/host/ehci-hcd.c ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, · line 649

Quoted 11 lines
drivers/usb/host/ehci-hcd.c +0 -1
@@ -609,13 +644,10 @@ ehci_submit_root(struct usb_device *dev, unsigned
 long pipe, void *buffer, uint32_t *status_reg;
 
      struct ehci_ctrl *ctrl = dev->controller;
 
-     if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS)

{ - printf("The request port(%d) is not configured\n", -

                 le16_to_cpu(req->index) - 1);
drivers/usb/host/ehci-hcd.c +3 -0
+     status_reg = ehci_get_portsc_register(ctrl->hcor,
+             le16_to_cpu(req->index) - 1);
+     if (!status_reg)

What happens here if req->index is zero ?

Quoted 4 lines

Hint: the above code always does unsigned comparison ...

I think you should make the second argument of ehci_get_portsc_register() unsigned short too (as is req->index in struct devrequest).

Quoted 6 lines

Sorry, but I'll prefer 'int' over 'unsigned short', since it looks to me that the u-boot would set 'req->index' to 0 at startup, which results in a 'port = -1' to be passed to ehci_get_portsc_register().

And I think '-1' is a better self-explain value, so I'd like to stick with 'int'

Sure, but then the comparison is signed, not unsigned. Besides, it's unnecessary change to the logic of the code. Or did I miss something ?

Best regards,
Marek Vasut

#105 lore raw

PATCH v6 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

2013/5/13 Marek Vasut <[email protected]>:

Quoted 79 lines

Dear Kuo-Jung Su,

Quoted 77 lines

2013/5/13 Marek Vasut <[email protected]>:

Quoted 41 lines

Dear Kuo-Jung Su,

Quoted 39 lines

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff.
Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---

Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   91

++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 36 deletions(-)

drivers/usb/host/ehci-hcd.c +0 -0
index c816878..ae3f2a4 100644
@@ -117,10 +117,44 @@ static struct descriptor {
 
 };
 
 #if defined(CONFIG_EHCI_IS_TDI)
 
Quoted 7 lines

drivers/usb/host/ehci-hcd.c static struct descriptor { · line 120

Quoted 4 lines
drivers/usb/host/ehci-hcd.c +1 -3
-#define ehci_is_TDI()        (1)
-#else
-#define ehci_is_TDI()        (0)
+# define ehci_is_TDI()       (1)

btw you can remove those braces around (1) and (0) below. But I have one more question ...

Got it, thanks

Quoted 16 lines

[...]

drivers/usb/host/ehci-hcd.c ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, · line 649

Quoted 11 lines
drivers/usb/host/ehci-hcd.c +0 -1
@@ -609,13 +644,10 @@ ehci_submit_root(struct usb_device *dev, unsigned
 long pipe, void *buffer, uint32_t *status_reg;
 
      struct ehci_ctrl *ctrl = dev->controller;
 
-     if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS)

{ - printf("The request port(%d) is not configured\n", -

                 le16_to_cpu(req->index) - 1);
drivers/usb/host/ehci-hcd.c +3 -0
+     status_reg = ehci_get_portsc_register(ctrl->hcor,
+             le16_to_cpu(req->index) - 1);
+     if (!status_reg)

What happens here if req->index is zero ?

Quoted 4 lines

Hint: the above code always does unsigned comparison ...

I think you should make the second argument of ehci_get_portsc_register() unsigned short too (as is req->index in struct devrequest).

Sorry, but I'll prefer 'int' over 'unsigned short', since it looks to me that the u-boot would set 'req->index' to 0 at startup, which results in a 'port = -1' to be passed to ehci_get_portsc_register().

Quoted 6 lines
Quoted 2 lines

And I think '-1' is a better self-explain value, so I'd like to stick with 'int'

Sure, but then the comparison is signed, not unsigned. Besides, it's unnecessary change to the logic of the code. Or did I miss something ?

1. There is a bug in ehci_submit_root() of usb ehci:

    int ehci_submit_root()
    {
         ......
         if (port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
            printf("The request port(%d) is not configured\n", port - 1);
            return -1;
         }
         status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
         ......
    }

    The 'port' is actually a '0' at start-up, so we actually accessed

a wrong register.
But fortunately the wrong register actually points to CONFIGFLAG(0x40) with a safe value for the following codes.

2. One of Vivek Gautam's usb patches has altered the logic of usb host upon launching 'usb start', if we report a error upon (port - 1 < 0), the current u-boot usb would failed to scan ports. (At least it
failed at Faraday platforms.)
However it looks to me that it's o.k to report a error upon (port
- 1 < 0) at old usb ehci stack.
(i.e. 10 days ago, in master branch of u-boot)

And thus I add a quick check to PATCH v7.

__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port) {
/*
* The u-boot would somehow set port=-1@usb start-up,
* so this quick fix is necessary.
*/
if (port < 0)
port = 0;

if (port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
printf("The request port(%u) is not configured\n", port); return NULL;
}

return (uint32_t *)&hcor->or_portsc[port];
}

However I found that I've stupidly copied the logic

' if (port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) '

into ehci-faraday.c, so I'll post a v8 for this few minutes later....

Quoted 2 lines

Best regards,
Marek Vasut

--
Best wishes,
Kuo-Jung Su

#106 lore raw

PATCH v6 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

Dear Kuo-Jung Su,

Quoted 118 lines

2013/5/13 Marek Vasut <[email protected]>:

Quoted 83 lines

Dear Kuo-Jung Su,

Quoted 81 lines

2013/5/13 Marek Vasut <[email protected]>:

Quoted 41 lines

Dear Kuo-Jung Su,

Quoted 39 lines

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff. Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---

Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   91

++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 36 deletions(-)

(quoted diff) +0 -0

b/drivers/usb/host/ehci-hcd.c index c816878..ae3f2a4 100644

drivers/usb/host/ehci-hcd.c +0 -0
@@ -117,10 +117,44 @@ static struct descriptor {
 
 };
 
 #if defined(CONFIG_EHCI_IS_TDI)
 
Quoted 7 lines

drivers/usb/host/ehci-hcd.c static struct descriptor { · line 120

Quoted 4 lines
drivers/usb/host/ehci-hcd.c +1 -3
-#define ehci_is_TDI()        (1)
-#else
-#define ehci_is_TDI()        (0)
+# define ehci_is_TDI()       (1)

btw you can remove those braces around (1) and (0) below. But I have one more question ...

Got it, thanks

Quoted 19 lines

[...]

Quoted 11 lines
drivers/usb/host/ehci-hcd.c +0 -1
@@ -609,13 +644,10 @@ ehci_submit_root(struct usb_device *dev,
 unsigned long pipe, void *buffer, uint32_t *status_reg;
 
      struct ehci_ctrl *ctrl = dev->controller;
 
-     if (le16_to_cpu(req->index) >

CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) { - printf("The
request port(%d) is not configured\n", -

                 le16_to_cpu(req->index) - 1);

drivers/usb/host/ehci-hcd.c ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, · line 649

Quoted 3 lines
drivers/usb/host/ehci-hcd.c +3 -0
+     status_reg = ehci_get_portsc_register(ctrl->hcor,
+             le16_to_cpu(req->index) - 1);
+     if (!status_reg)

What happens here if req->index is zero ?

Quoted 5 lines

Hint: the above code always does unsigned comparison ...

I think you should make the second argument of ehci_get_portsc_register() unsigned short too (as is req->index in struct devrequest).

Sorry, but I'll prefer 'int' over 'unsigned short', since it looks to me that the u-boot would set 'req->index' to 0 at startup, which results in a 'port = -1' to be passed to ehci_get_portsc_register().

Quoted 5 lines
Quoted 2 lines

And I think '-1' is a better self-explain value, so I'd like to stick with 'int'

Sure, but then the comparison is signed, not unsigned. Besides, it's unnecessary change to the logic of the code. Or did I miss something ?

1. There is a bug in ehci_submit_root() of usb ehci:

    int ehci_submit_root()
    {
         ......
         if (port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
            printf("The request port(%d) is not configured\n", port - 1);
            return -1;
         }
         status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
         ......
    }

    The 'port' is actually a '0' at start-up, so we actually accessed
a wrong register.
    But fortunately the wrong register actually points to CONFIGFLAG(0x40)

with a safe value for the following codes.

2. One of Vivek Gautam's usb patches has altered the logic of usb host upon launching 'usb start', if we report a error upon (port - 1 < 0), the current u-boot usb would failed to scan ports. (At least it
failed at Faraday platforms.)
However it looks to me that it's o.k to report a error upon (port
- 1 < 0)@old usb ehci stack.
(i.e. 10 days ago, in master branch of u-boot)

And thus I add a quick check to PATCH v7.

Quoted 8 lines

__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port) {
/*
* The u-boot would somehow set port=-1 at usb start-up,
* so this quick fix is necessary.
*/
if (port < 0)
port = 0;

Maybe we should return fail, no ? Can you pinpoint where does the req->index (resp. port) get set to -1 ? And which commit introduced this breakage ?

Best regards,
Marek Vasut

#107 lore raw

PATCH v6 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

2013/5/14 Marek Vasut <[email protected]>:

Quoted 129 lines

Dear Kuo-Jung Su,

Quoted 118 lines

2013/5/13 Marek Vasut <[email protected]>:

Quoted 83 lines

Dear Kuo-Jung Su,

Quoted 81 lines

2013/5/13 Marek Vasut <[email protected]>:

Quoted 41 lines

Dear Kuo-Jung Su,

Quoted 39 lines

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff. Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---

Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   91

++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 36 deletions(-)

(quoted diff) +0 -0

b/drivers/usb/host/ehci-hcd.c index c816878..ae3f2a4 100644

drivers/usb/host/ehci-hcd.c +0 -0
@@ -117,10 +117,44 @@ static struct descriptor {
 
 };
 
 #if defined(CONFIG_EHCI_IS_TDI)
 
Quoted 7 lines

drivers/usb/host/ehci-hcd.c static struct descriptor { · line 120

Quoted 4 lines
drivers/usb/host/ehci-hcd.c +1 -3
-#define ehci_is_TDI()        (1)
-#else
-#define ehci_is_TDI()        (0)
+# define ehci_is_TDI()       (1)

btw you can remove those braces around (1) and (0) below. But I have one more question ...

Got it, thanks

Quoted 19 lines

[...]

Quoted 11 lines
drivers/usb/host/ehci-hcd.c +0 -1
@@ -609,13 +644,10 @@ ehci_submit_root(struct usb_device *dev,
 unsigned long pipe, void *buffer, uint32_t *status_reg;
 
      struct ehci_ctrl *ctrl = dev->controller;
 
-     if (le16_to_cpu(req->index) >

CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) { - printf("The
request port(%d) is not configured\n", -

                 le16_to_cpu(req->index) - 1);

drivers/usb/host/ehci-hcd.c ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, · line 649

Quoted 3 lines
drivers/usb/host/ehci-hcd.c +3 -0
+     status_reg = ehci_get_portsc_register(ctrl->hcor,
+             le16_to_cpu(req->index) - 1);
+     if (!status_reg)

What happens here if req->index is zero ?

Quoted 5 lines

Hint: the above code always does unsigned comparison ...

I think you should make the second argument of ehci_get_portsc_register() unsigned short too (as is req->index in struct devrequest).

Sorry, but I'll prefer 'int' over 'unsigned short', since it looks to me that the u-boot would set 'req->index' to 0 at startup, which results in a 'port = -1' to be passed to ehci_get_portsc_register().

Quoted 5 lines
Quoted 2 lines

And I think '-1' is a better self-explain value, so I'd like to stick with 'int'

Sure, but then the comparison is signed, not unsigned. Besides, it's unnecessary change to the logic of the code. Or did I miss something ?

1. There is a bug in ehci_submit_root() of usb ehci:

    int ehci_submit_root()
    {
         ......
         if (port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
            printf("The request port(%d) is not configured\n", port - 1);
            return -1;
         }
         status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
         ......
    }

    The 'port' is actually a '0' at start-up, so we actually accessed
a wrong register.
    But fortunately the wrong register actually points to CONFIGFLAG(0x40)

with a safe value for the following codes.

2. One of Vivek Gautam's usb patches has altered the logic of usb host upon launching 'usb start', if we report a error upon (port - 1 < 0), the current u-boot usb would failed to scan ports. (At least it
failed at Faraday platforms.)
However it looks to me that it's o.k to report a error upon (port
- 1 < 0)@old usb ehci stack.
(i.e. 10 days ago, in master branch of u-boot)

And thus I add a quick check to PATCH v7.

Quoted 8 lines

__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port) {
/*
* The u-boot would somehow set port=-1 at usb start-up,
* so this quick fix is necessary.
*/
if (port < 0)
port = 0;

Quoted 1 line

Maybe we should return fail, no ?

No, it would make the 'usb start' to terminate immediately, and results in a port scan failure to at least Faraday EHCI.

Quoted 2 lines

Can you pinpoint where does the req->index
(resp. port) get set to -1 ?

Later I'll try to find out where we have 'req->index' set as a '0' in 'usb start'.

Quoted 1 line

And which commit introduced this breakage ?

I believe it's there long ago, we just fortunately bypass the error at old day, and now one of Vivek Gautam's USB patch make us face up to this issue.

Quoted 3 lines

Best regards,
Marek Vasut

--
Best wishes,
Kuo-Jung Su

#108 lore raw

PATCH v6 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

2013/5/15 Kuo-Jung Su <[email protected]>:

Quoted 132 lines

2013/5/14 Marek Vasut <[email protected]>:

Quoted 129 lines

Dear Kuo-Jung Su,

Quoted 118 lines

2013/5/13 Marek Vasut <[email protected]>:

Quoted 83 lines

Dear Kuo-Jung Su,

Quoted 81 lines

2013/5/13 Marek Vasut <[email protected]>:

Quoted 41 lines

Dear Kuo-Jung Su,

Quoted 39 lines

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff. Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---

Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   91

++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 36 deletions(-)

(quoted diff) +0 -0

b/drivers/usb/host/ehci-hcd.c index c816878..ae3f2a4 100644

drivers/usb/host/ehci-hcd.c +0 -0
@@ -117,10 +117,44 @@ static struct descriptor {
 
 };
 
 #if defined(CONFIG_EHCI_IS_TDI)
 
Quoted 7 lines

drivers/usb/host/ehci-hcd.c static struct descriptor { · line 122

Quoted 4 lines
drivers/usb/host/ehci-hcd.c +1 -3
-#define ehci_is_TDI()        (1)
-#else
-#define ehci_is_TDI()        (0)
+# define ehci_is_TDI()       (1)

btw you can remove those braces around (1) and (0) below. But I have one more question ...

Got it, thanks

Quoted 19 lines

[...]

Quoted 11 lines
drivers/usb/host/ehci-hcd.c +0 -1
@@ -609,13 +644,10 @@ ehci_submit_root(struct usb_device *dev,
 unsigned long pipe, void *buffer, uint32_t *status_reg;
 
      struct ehci_ctrl *ctrl = dev->controller;
 
-     if (le16_to_cpu(req->index) >

CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) { - printf("The
request port(%d) is not configured\n", -

                 le16_to_cpu(req->index) - 1);

drivers/usb/host/ehci-hcd.c

Quoted 3 lines
drivers/usb/host/ehci-hcd.c +3 -0
+     status_reg = ehci_get_portsc_register(ctrl->hcor,
+             le16_to_cpu(req->index) - 1);
+     if (!status_reg)

What happens here if req->index is zero ?

Quoted 5 lines

Hint: the above code always does unsigned comparison ...

I think you should make the second argument of ehci_get_portsc_register() unsigned short too (as is req->index in struct devrequest).

Sorry, but I'll prefer 'int' over 'unsigned short', since it looks to me that the u-boot would set 'req->index' to 0 at startup, which results in a 'port = -1' to be passed to ehci_get_portsc_register().

Quoted 5 lines
Quoted 2 lines

And I think '-1' is a better self-explain value, so I'd like to stick with 'int'

Sure, but then the comparison is signed, not unsigned. Besides, it's unnecessary change to the logic of the code. Or did I miss something ?

1. There is a bug in ehci_submit_root() of usb ehci:

    int ehci_submit_root()
    {
         ......
         if (port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
            printf("The request port(%d) is not configured\n", port - 1);
            return -1;
         }
         status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
         ......
    }

    The 'port' is actually a '0' at start-up, so we actually accessed
a wrong register.
    But fortunately the wrong register actually points to CONFIGFLAG(0x40)

with a safe value for the following codes.

2. One of Vivek Gautam's usb patches has altered the logic of usb host upon launching 'usb start', if we report a error upon (port - 1 < 0), the current u-boot usb would failed to scan ports. (At least it
failed at Faraday platforms.)
However it looks to me that it's o.k to report a error upon (port
- 1 < 0)@old usb ehci stack.
(i.e. 10 days ago, in master branch of u-boot)

And thus I add a quick check to PATCH v7.

Quoted 8 lines

__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port) {
/*
* The u-boot would somehow set port=-1 at usb start-up,
* so this quick fix is necessary.
*/
if (port < 0)
port = 0;

Quoted 1 line

Maybe we should return fail, no ?

Quoted 9 lines

No, it would make the 'usb start' to terminate immediately, and results in a port scan failure to at least Faraday EHCI.

Quoted 2 lines

Can you pinpoint where does the req->index
(resp. port) get set to -1 ?

Later I'll try to find out where we have 'req->index' set as a '0' in 'usb start'.

It's from usb_new_device() --> usb_get_descriptor(), and thus it's definitely correct to set index = 0 right here.
The only problem is 'We shall not always report an portsc error for all request!'
Please refer to the patch attached at the tail of this mail.

Quoted 5 lines
Quoted 1 line

And which commit introduced this breakage ?

I believe it's there long ago, we just fortunately bypass the error at old day, and now one of Vivek Gautam's USB patch make us face up to this issue.

Shame on me....
It's nothing to do with Vivek Gautam's USB patch or the old USB ehci stack, it's only mattered while reporting an portsc error. :P

Quoted 5 lines
Quoted 3 lines

Best regards,
Marek Vasut

Here is the quick fix to this issue:

drivers/usb/host/ehci-faraday.c +0 -0
index 2cf8b15..14f0894 100644
@@ -136,16 +136,10 @@ int ehci_get_port_speed(struct ehci_hcor *hcor,

uint32_t reg)
*/
uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port) {
- /*
- * The u-boot would somehow set port=-1 at usb start-up,
- * so this quick fix is necessary.
- */
- if (port < 0)
- port = 0;
-
/* Faraday EHCI has one and only one portsc register */ if (port) {
- printf("The request port(%d) is not configured\n", port);
+ /* ! Enable the print would lead to a timing issue ! */
+ debug("The request port(%d) is not configured\n", port); return NULL;
}

drivers/usb/host/ehci-hcd.c +3 -9
index be18a02..67d7d3f 100644
@@ -607,15 +607,9 @@ fail:
 
 __weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
 {
- /*
- * The u-boot would somehow set port=-1@usb start-up,
- * so this quick fix is necessary.
- */
- if (port < 0)
- port = 0;
-
- if (port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
- printf("The request port(%u) is not configured\n", port);
+ if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+ /* ! Enable the print would lead to a timing issue ! */
+ debug("The request port(%u) is not configured\n", port);
  return NULL;
  }
 
@@ -636,8 +630,6 @@ ehci_submit_root(struct usb_device *dev, unsigned

long pipe, void *buffer,
struct ehci_ctrl *ctrl = dev->controller;

status_reg = ehci_get_portsc_register(ctrl->hcor, port - 1);
- if (!status_reg)
- return -1;
srclen = 0;

debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
@@ -717,6 +709,8 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
srclen = 2;
break;
case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
+ if (!status_reg)
+ return -1;
memset(tmpbuf, 0, 4);
reg = ehci_readl(status_reg);
if (reg & EHCI_PS_CS)
@@ -761,6 +755,8 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
srclen = 4;
break;
case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
+ if (!status_reg)
+ return -1;
reg = ehci_readl(status_reg);
reg &= ~EHCI_PS_CLEAR;
switch (le16_to_cpu(req->value)) {
@@ -825,6 +821,8 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
(void) ehci_readl(&ctrl->hcor->or_usbcmd);
break;
case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
+ if (!status_reg)
+ return -1;
reg = ehci_readl(status_reg);
switch (le16_to_cpu(req->value)) {
case USB_PORT_FEAT_ENABLE:

#109 lore raw

PATCH v6 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

Dear Kuo-Jung Su,

Quoted 169 lines

2013/5/15 Kuo-Jung Su <[email protected]>:

Quoted 151 lines

2013/5/14 Marek Vasut <[email protected]>:

Quoted 144 lines

Dear Kuo-Jung Su,

Quoted 142 lines

2013/5/13 Marek Vasut <[email protected]>:

Quoted 84 lines

Dear Kuo-Jung Su,

Quoted 82 lines

2013/5/13 Marek Vasut <[email protected]>:

Quoted 41 lines

Dear Kuo-Jung Su,

Quoted 39 lines

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff. Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---

Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   91

++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 36 deletions(-)

(quoted diff) +0 -0

b/drivers/usb/host/ehci-hcd.c index c816878..ae3f2a4 100644

drivers/usb/host/ehci-hcd.c +0 -0
@@ -117,10 +117,44 @@ static struct descriptor {
 
 };
 
 #if defined(CONFIG_EHCI_IS_TDI)
 
Quoted 7 lines

drivers/usb/host/ehci-hcd.c static struct descriptor { · line 122

Quoted 4 lines
drivers/usb/host/ehci-hcd.c +1 -3
-#define ehci_is_TDI()        (1)
-#else
-#define ehci_is_TDI()        (0)
+# define ehci_is_TDI()       (1)

btw you can remove those braces around (1) and (0) below. But I have one more question ...

Got it, thanks

Quoted 19 lines

[...]

Quoted 11 lines
drivers/usb/host/ehci-hcd.c +0 -1
@@ -609,13 +644,10 @@ ehci_submit_root(struct usb_device *dev,
 unsigned long pipe, void *buffer, uint32_t *status_reg;
 
      struct ehci_ctrl *ctrl = dev->controller;
 
-     if (le16_to_cpu(req->index) >

CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) { - printf("The
request port(%d) is not configured\n", -

                 le16_to_cpu(req->index) - 1);

drivers/usb/host/ehci-hcd.c

Quoted 3 lines
drivers/usb/host/ehci-hcd.c +3 -0
+     status_reg = ehci_get_portsc_register(ctrl->hcor,
+             le16_to_cpu(req->index) - 1);
+     if (!status_reg)

What happens here if req->index is zero ?

Quoted 5 lines

Hint: the above code always does unsigned comparison ...

I think you should make the second argument of ehci_get_portsc_register() unsigned short too (as is req->index in struct devrequest).

Sorry, but I'll prefer 'int' over 'unsigned short', since it looks to me that the u-boot would set 'req->index' to 0 at startup, which results in a 'port = -1' to be passed to ehci_get_portsc_register().

Quoted 6 lines
Quoted 2 lines

And I think '-1' is a better self-explain value, so I'd like to stick with 'int'

Sure, but then the comparison is signed, not unsigned. Besides, it's unnecessary change to the logic of the code. Or did I miss something ?

1. There is a bug in ehci_submit_root() of usb ehci:

    int ehci_submit_root()
    {
    
         ......
         if (port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
         
            printf("The request port(%d) is not configured\n", port -
            1); return -1;
         
         }
         status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
         ......
    
    }
    
    The 'port' is actually a '0' at start-up, so we actually accessed

a wrong register.

But fortunately the wrong register actually points to CONFIGFLAG(0x40)

with a safe value for the following codes.

2. One of Vivek Gautam's usb patches has altered the logic of usb host

upon launching 'usb start', if we report a error upon (port - 1 < 0), the current u-boot usb would failed to scan ports. (At least it

failed at Faraday platforms.)

However it looks to me that it's o.k to report a error upon (port

- 1 < 0)@old usb ehci stack.

(i.e. 10 days ago, in master branch of u-boot)

And thus I add a quick check to PATCH v7.

__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port) {

/*

* The u-boot would somehow set port=-1 at usb start-up,
* so this quick fix is necessary.
*/

Quoted 5 lines
Quoted 3 lines

if (port < 0)

  port = 0;

Maybe we should return fail, no ?

Quoted 8 lines

No, it would make the 'usb start' to terminate immediately, and results in a port scan failure to at least Faraday EHCI.

Quoted 2 lines

Can you pinpoint where does the req->index
(resp. port) get set to -1 ?

Later I'll try to find out where we have 'req->index' set as a '0' in 'usb start'.

It's from usb_new_device() --> usb_get_descriptor(), and thus it's definitely correct to set index = 0 right here.
The only problem is 'We shall not always report an portsc error for all request!'
Please refer to the patch attached at the tail of this mail.

Quoted 2 lines
Quoted 1 line

And which commit introduced this breakage ?

Quoted 10 lines
Quoted 3 lines

I believe it's there long ago, we just fortunately bypass the error at old day, and now one of Vivek Gautam's USB patch make us face up to this issue.

Shame on me....
It's nothing to do with Vivek Gautam's USB patch or the old USB ehci stack, it's only mattered while reporting an portsc error. :P

Quoted 2 lines
Quoted 2 lines

Best regards,
Marek Vasut

Ok, I think I almost see it there. Can you just make a patchset out of this stuff so I can digest it a little bit easier? Maybe stick the fixes first so I can pick them ASAP and the FHCI stuff after that.

#110 lore raw

PATCH v6 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

2013/5/15 Marek Vasut <[email protected]>:

Quoted 179 lines

Dear Kuo-Jung Su,

Quoted 177 lines

2013/5/15 Kuo-Jung Su <[email protected]>:

Quoted 151 lines

2013/5/14 Marek Vasut <[email protected]>:

Quoted 144 lines

Dear Kuo-Jung Su,

Quoted 142 lines

2013/5/13 Marek Vasut <[email protected]>:

Quoted 84 lines

Dear Kuo-Jung Su,

Quoted 82 lines

2013/5/13 Marek Vasut <[email protected]>:

Quoted 41 lines

Dear Kuo-Jung Su,

Quoted 39 lines

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff. Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---

Changes for v6:
- Simplify weak aliased function declaration
- Drop redundant line feed

Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |   91

++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 36 deletions(-)

(quoted diff) +0 -0

b/drivers/usb/host/ehci-hcd.c index c816878..ae3f2a4 100644

drivers/usb/host/ehci-hcd.c +0 -0
@@ -117,10 +117,44 @@ static struct descriptor {
 
 };
 
 #if defined(CONFIG_EHCI_IS_TDI)
 
Quoted 7 lines

drivers/usb/host/ehci-hcd.c static struct descriptor { · line 122

Quoted 4 lines
drivers/usb/host/ehci-hcd.c +1 -3
-#define ehci_is_TDI()        (1)
-#else
-#define ehci_is_TDI()        (0)
+# define ehci_is_TDI()       (1)

btw you can remove those braces around (1) and (0) below. But I have one more question ...

Got it, thanks

Quoted 19 lines

[...]

Quoted 11 lines
drivers/usb/host/ehci-hcd.c +0 -1
@@ -609,13 +644,10 @@ ehci_submit_root(struct usb_device *dev,
 unsigned long pipe, void *buffer, uint32_t *status_reg;
 
      struct ehci_ctrl *ctrl = dev->controller;
 
-     if (le16_to_cpu(req->index) >

CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) { - printf("The
request port(%d) is not configured\n", -

                 le16_to_cpu(req->index) - 1);

drivers/usb/host/ehci-hcd.c

Quoted 3 lines
drivers/usb/host/ehci-hcd.c +3 -0
+     status_reg = ehci_get_portsc_register(ctrl->hcor,
+             le16_to_cpu(req->index) - 1);
+     if (!status_reg)

What happens here if req->index is zero ?

Quoted 5 lines

Hint: the above code always does unsigned comparison ...

I think you should make the second argument of ehci_get_portsc_register() unsigned short too (as is req->index in struct devrequest).

Sorry, but I'll prefer 'int' over 'unsigned short', since it looks to me that the u-boot would set 'req->index' to 0 at startup, which results in a 'port = -1' to be passed to ehci_get_portsc_register().

Quoted 6 lines
Quoted 2 lines

And I think '-1' is a better self-explain value, so I'd like to stick with 'int'

Sure, but then the comparison is signed, not unsigned. Besides, it's unnecessary change to the logic of the code. Or did I miss something ?

1. There is a bug in ehci_submit_root() of usb ehci:

    int ehci_submit_root()
    {

         ......
         if (port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {

            printf("The request port(%d) is not configured\n", port -
            1); return -1;

         }
         status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
         ......

    }

    The 'port' is actually a '0' at start-up, so we actually accessed

a wrong register.

But fortunately the wrong register actually points to CONFIGFLAG(0x40)

with a safe value for the following codes.

2. One of Vivek Gautam's usb patches has altered the logic of usb host

upon launching 'usb start', if we report a error upon (port - 1 < 0), the current u-boot usb would failed to scan ports. (At least it

failed at Faraday platforms.)

However it looks to me that it's o.k to report a error upon (port

- 1 < 0)@old usb ehci stack.

(i.e. 10 days ago, in master branch of u-boot)

And thus I add a quick check to PATCH v7.

__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port) {

/*

* The u-boot would somehow set port=-1 at usb start-up,
* so this quick fix is necessary.
*/

Quoted 5 lines
Quoted 3 lines

if (port < 0)

  port = 0;

Maybe we should return fail, no ?

Quoted 8 lines

No, it would make the 'usb start' to terminate immediately, and results in a port scan failure to at least Faraday EHCI.

Quoted 2 lines

Can you pinpoint where does the req->index
(resp. port) get set to -1 ?

Later I'll try to find out where we have 'req->index' set as a '0' in 'usb start'.

It's from usb_new_device() --> usb_get_descriptor(), and thus it's definitely correct to set index = 0 right here.
The only problem is 'We shall not always report an portsc error for all request!'
Please refer to the patch attached at the tail of this mail.

Quoted 5 lines
Quoted 1 line

And which commit introduced this breakage ?

I believe it's there long ago, we just fortunately bypass the error at old day, and now one of Vivek Gautam's USB patch make us face up to this issue.

Shame on me....
It's nothing to do with Vivek Gautam's USB patch or the old USB ehci stack, it's only mattered while reporting an portsc error. :P

Quoted 6 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

Best regards,
Marek Vasut

Ok, I think I almost see it there. Can you just make a patchset out of this stuff so I can digest it a little bit easier? Maybe stick the fixes first so I can pick them ASAP and the FHCI stuff after that.

Sure, I'll post a new patchset with this as 1st part.

--
Best wishes,
Kuo-Jung Su

#111 lore raw

PATCH v6 3/4 usb: ehci: add Faraday USB 2.0 EHCI support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

This patch adds support to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI are listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address space removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differ from standard EHCI in several ways. But since U-boot doesn't support ISOC, we don't have to worry about that.

---
Changes for v6:
- Nothing updates

Changes for v5:
- Break down EHCI changes as seperate changesets.
- Fix the invalid multi-line comment style.

Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 common/usb_hub.c                |    7 +-
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-faraday.c |  146 ++++++++++++++++
 drivers/usb/host/ehci-hcd.c     |    5 +
 include/usb/fotg210.h           |  364 +++++++++++++++++++++++++++++++++++++++
 include/usb/fusbh200.h          |   61 +++++++
 6 files changed, 583 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h
common/usb_hub.c +6 -1
index f240d8c..25821a5 100644
@@ -445,7 +445,11 @@ static int usb_hub_configure(struct usb_device *dev)
 					i + 1, portstatus);
 			usb_clear_port_feature(dev, i + 1,
 						USB_PORT_FEAT_C_ENABLE);
-
+			/*
+			 * The following hack causes a ghost device problem
+			 * to Faraday EHCI
+			 */
+#ifndef CONFIG_USB_EHCI_FARADAY
 			/* EM interference sometimes causes bad shielded USB
 			 * devices to be shutdown by the hub, this hack enables
 			 * them again. Works at least with mouse driver */
@@ -457,6 +461,7 @@ static int usb_hub_configure(struct usb_device *dev)
 						"re-enabling...\n", i + 1);
 					usb_hub_port_connect_change(dev, i);
 			}
+#endif
 		}
 		if (portstatus & USB_PORT_STAT_SUSPEND) {
 			USB_HUB_PRINTF("port %d suspend change\n", i + 1);
drivers/usb/host/Makefile +1 -0
index 87a5970..98f2a10 100644
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o
 else
 COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
 endif
+COBJS-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o
 COBJS-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
 COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
 COBJS-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o
drivers/usb/host/ehci-faraday.c new file +146 -0

146 lines not on this page · raw message

drivers/usb/host/ehci-hcd.c +5 -0
index ae3f2a4..37e5424 100644
@@ -598,10 +598,12 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		dev->act_len = length - QT_TOKEN_GET_TOTALBYTES(token);
 	} else {
 		dev->act_len = 0;
+#ifndef CONFIG_USB_EHCI_FARADAY
 		debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n",
 		      dev->devnum, ehci_readl(&ctrl->hcor->or_usbsts),
 		      ehci_readl(&ctrl->hcor->or_portsc[0]),
 		      ehci_readl(&ctrl->hcor->or_portsc[1]));
+#endif
 	}
 
 	free(qtd);
@@ -969,10 +971,13 @@ int usb_lowlevel_init(int index, void **controller)
 	cmd |= CMD_RUN;
 	ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
 
+#ifndef CONFIG_USB_EHCI_FARADAY
 	/* take control over the ports */
 	cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
 	cmd |= FLAG_CF;
 	ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
+#endif
+
 	/* unblock posted write */
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
 	mdelay(5);
include/usb/fotg210.h new file +364 -0

364 lines not on this page · raw message

include/usb/fusbh200.h new file +61 -0

61 lines not on this page · raw message

--
1.7.9.5

#112 lore raw

PATCH v6 4/4 usb: gadget: add Faraday FOTG210 USB gadget support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device at a time.

---
Changes for v6:
- Nothing updates

Changes for v5:
- Coding Style cleanup.
- Drop postfix '__iomem' from struct fotg210_regs
- Use permanent delay for hardware reset
- Drop '#ifndef CONFIG_SYS_DCACHE_OFF'
- Drop magic numbers

Changes for v4:
- Use only macro constants and named bit/mask
- Remove dcache_enable() from usb_gadget_register_driver()

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  948 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 3 files changed, 957 insertions(+)
 create mode 100644 drivers/usb/gadget/fotg210.c
drivers/usb/gadget/Makefile +1 -0
index e545b6b..432cf17 100644
@@ -35,6 +35,7 @@ endif
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
 endif
drivers/usb/gadget/fotg210.c new file +948 -0

948 lines not on this page · raw message

drivers/usb/gadget/gadget_chips.h +8 -0
index e570142..f038747 100644
@@ -150,6 +150,12 @@
 #define gadget_is_mv(g)        0
 #endif
 
+#ifdef CONFIG_USB_GADGET_FOTG210
+#define gadget_is_fotg210(g)        (!strcmp("fotg210_udc", (g)->name))
+#else
+#define gadget_is_fotg210(g)        0
+#endif
+
 /*
  * CONFIG_USB_GADGET_SX2
  * CONFIG_USB_GADGET_AU1X00
@@ -215,5 +221,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
 		return 0x20;
 	else if (gadget_is_mv(gadget))
 		return 0x21;
+	else if (gadget_is_fotg210(gadget))
+		return 0x22;
 	return -ENOENT;
 }

--
1.7.9.5

#113 lore raw

PATCH v5 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff.
Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---
Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |  100 +++++++++++++++++++++++++++----------------
 1 file changed, 64 insertions(+), 36 deletions(-)
drivers/usb/host/ehci-hcd.c +64 -36
index c816878..b334173 100644
@@ -117,10 +117,50 @@ static struct descriptor {
 };
 
 #if defined(CONFIG_EHCI_IS_TDI)
-#define ehci_is_TDI()	(1)
-#else
-#define ehci_is_TDI()	(0)
+# define ehci_is_TDI()	(1)
+
+/* put TDI/ARC silicon into EHCI mode */
+void __ehci_tdi_reset(struct ehci_hcor *hcor)
+{
+	uint32_t tmp, *reg_ptr;
+
+	reg_ptr = (uint32_t *)((uint8_t *) + USBMODE);
+	tmp = ehci_readl(reg_ptr);
+	tmp |= USBMODE_CM_HC;
+#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
+	tmp |= USBMODE_BE;
 #endif
+	ehci_writel(reg_ptr, tmp);
+}
+
+void ehci_tdi_reset(struct ehci_hcor *hcor)
+	__attribute__((weak, alias("__ehci_tdi_reset")));
+
+int __ehci_port_speed(struct ehci_hcor *hcor, unsigned int portsc)
+{
+	int ret = 0;
+
+	switch (PORTSC_PSPD(portsc)) {
+	case PORTSC_PSPD_FS:
+		break;
+	case PORTSC_PSPD_LS:
+		ret = USB_PORT_STAT_LOW_SPEED;
+		break;
+	case PORTSC_PSPD_HS:
+	default:
+		ret = USB_PORT_STAT_HIGH_SPEED;
+		break;
+	}
+
+	return ret;
+}
+
+int ehci_port_speed(struct ehci_hcor *hcor, unsigned int portsc)
+	__attribute__((weak, alias("__ehci_port_speed")));
+
+#else  /* CONFIG_EHCI_IS_TDI */
+# define ehci_is_TDI()	(0)
+#endif /* CONFIG_EHCI_IS_TDI */
 
 void __ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
 {
@@ -149,8 +189,6 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
 static int ehci_reset(int index)
 {
 	uint32_t cmd;
-	uint32_t tmp;
-	uint32_t *reg_ptr;
 	int ret = 0;
 
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
@@ -163,15 +201,8 @@ static int ehci_reset(int index)
 		goto out;
 	}
 
-	if (ehci_is_TDI()) {
-		reg_ptr = (uint32_t *)((u8 *)ehcic[index].hcor + USBMODE);
-		tmp = ehci_readl(reg_ptr);
-		tmp |= USBMODE_CM_HC;
-#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
-		tmp |= USBMODE_BE;
-#endif
-		ehci_writel(reg_ptr, tmp);
-	}
+	if (ehci_is_TDI())
+		ehci_tdi_reset(ehcic[index].hcor);
 
 #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
 	cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
@@ -597,6 +628,18 @@ static inline int min3(int a, int b, int c)
 	return a;
 }
 
+uint32_t *__ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+{
+	if (port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+		printf("The request port(%d) is not configured\n", port);
+		return NULL;
+	}
+
+	return (uint32_t *)&hcor->or_portsc[port];
+}
+uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+	__attribute__((weak, alias("__ehci_get_portsc_register")));
+
 int
 ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 		 int length, struct devrequest *req)
@@ -609,13 +652,10 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 	uint32_t *status_reg;
 	struct ehci_ctrl *ctrl = dev->controller;
 
-	if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-		printf("The request port(%d) is not configured\n",
-			le16_to_cpu(req->index) - 1);
+	status_reg = ehci_get_portsc_register(ctrl->hcor,
+		le16_to_cpu(req->index) - 1);
+	if (!status_reg)
 		return -1;
-	}
-	status_reg = (uint32_t *)&ctrl->hcor->or_portsc[
-						le16_to_cpu(req->index) - 1];
 	srclen = 0;
 
 	debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
@@ -709,23 +749,10 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			tmpbuf[0] |= USB_PORT_STAT_RESET;
 		if (reg & EHCI_PS_PP)
 			tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
-
-		if (ehci_is_TDI()) {
-			switch (PORTSC_PSPD(reg)) {
-			case PORTSC_PSPD_FS:
-				break;
-			case PORTSC_PSPD_LS:
-				tmpbuf[1] |= USB_PORT_STAT_LOW_SPEED >> 8;
-				break;
-			case PORTSC_PSPD_HS:
-			default:
-				tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
-				break;
-			}
-		} else {
+		if (ehci_is_TDI())
+			tmpbuf[1] |= ehci_port_speed(ctrl->hcor, reg) >> 8;
+		else
 			tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
-		}
-
 		if (reg & EHCI_PS_CSC)
 			tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
 		if (reg & EHCI_PS_PEC)
@@ -954,6 +981,7 @@ int usb_lowlevel_init(int index, void **controller)
 	cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
 	cmd |= FLAG_CF;
 	ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
+
 	/* unblock posted write */
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
 	mdelay(5);

--
1.7.9.5

#114 lore raw

PATCH v5 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

Dear Kuo-Jung Su,

Quoted 42 lines

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff.
Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---
Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |  100

+++++++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 36 deletions(-)

drivers/usb/host/ehci-hcd.c +8 -3
index c816878..b334173 100644
@@ -117,10 +117,50 @@ static struct descriptor {
 };
 
 #if defined(CONFIG_EHCI_IS_TDI)
-#define ehci_is_TDI()	(1)
-#else
-#define ehci_is_TDI()	(0)
+# define ehci_is_TDI()	(1)
+
+/* put TDI/ARC silicon into EHCI mode */
+void __ehci_tdi_reset(struct ehci_hcor *hcor)
+{
+	uint32_t tmp, *reg_ptr;
+
+	reg_ptr = (uint32_t *)((uint8_t *) + USBMODE);

drivers/usb/host/ehci-hcd.c static struct descriptor { · line 137

Quoted 10 lines
drivers/usb/host/ehci-hcd.c +9 -0
+	tmp = ehci_readl(reg_ptr);
+	tmp |= USBMODE_CM_HC;
+#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
+	tmp |= USBMODE_BE;
 #endif
+	ehci_writel(reg_ptr, tmp);
+}
+
+void ehci_tdi_reset(struct ehci_hcor *hcor)
+	__attribute__((weak, alias("__ehci_tdi_reset")));

Just wrap this into simple

__weak void ehci_tdi_reset(struct ehci_hcor *hcor)

{
	...body of __ehci_tdi_reset() above ...
}

it's the same thing as those two functions above, but without so much code ;-)

if it doesn't work, include <linux/compiler.h>, same below.

Quoted 119 lines
drivers/usb/host/ehci-hcd.c +45 -33
+int __ehci_port_speed(struct ehci_hcor *hcor, unsigned int portsc)
+{
+	int ret = 0;
+
+	switch (PORTSC_PSPD(portsc)) {
+	case PORTSC_PSPD_FS:
+		break;
+	case PORTSC_PSPD_LS:
+		ret = USB_PORT_STAT_LOW_SPEED;
+		break;
+	case PORTSC_PSPD_HS:
+	default:
+		ret = USB_PORT_STAT_HIGH_SPEED;
+		break;
+	}
+
+	return ret;
+}
+
+int ehci_port_speed(struct ehci_hcor *hcor, unsigned int portsc)
+	__attribute__((weak, alias("__ehci_port_speed")));
+
+#else  /* CONFIG_EHCI_IS_TDI */
+# define ehci_is_TDI()	(0)
+#endif /* CONFIG_EHCI_IS_TDI */
 
 void __ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
 {
@@ -149,8 +189,6 @@ static int handshake(uint32_t *ptr, uint32_t mask,
 uint32_t done, int usec) static int ehci_reset(int index)
 {
 	uint32_t cmd;
-	uint32_t tmp;
-	uint32_t *reg_ptr;
 	int ret = 0;
 
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
@@ -163,15 +201,8 @@ static int ehci_reset(int index)
 		goto out;
 	}
 
-	if (ehci_is_TDI()) {
-		reg_ptr = (uint32_t *)((u8 *)ehcic[index].hcor + USBMODE);
-		tmp = ehci_readl(reg_ptr);
-		tmp |= USBMODE_CM_HC;
-#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
-		tmp |= USBMODE_BE;
-#endif
-		ehci_writel(reg_ptr, tmp);
-	}
+	if (ehci_is_TDI())
+		ehci_tdi_reset(ehcic[index].hcor);
 
 #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
 	cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
@@ -597,6 +628,18 @@ static inline int min3(int a, int b, int c)
 	return a;
 }
 
+uint32_t *__ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+{
+	if (port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+		printf("The request port(%d) is not configured\n", port);
+		return NULL;
+	}
+
+	return (uint32_t *)&hcor->or_portsc[port];
+}
+uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+	__attribute__((weak, alias("__ehci_get_portsc_register")));
+
 int
 ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 		 int length, struct devrequest *req)
@@ -609,13 +652,10 @@ ehci_submit_root(struct usb_device *dev, unsigned
 long pipe, void *buffer, uint32_t *status_reg;
 	struct ehci_ctrl *ctrl = dev->controller;
 
-	if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-		printf("The request port(%d) is not configured\n",
-			le16_to_cpu(req->index) - 1);
+	status_reg = ehci_get_portsc_register(ctrl->hcor,
+		le16_to_cpu(req->index) - 1);
+	if (!status_reg)
 		return -1;
-	}
-	status_reg = (uint32_t *)&ctrl->hcor->or_portsc[
-						le16_to_cpu(req->index) - 1];
 	srclen = 0;
 
 	debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
@@ -709,23 +749,10 @@ ehci_submit_root(struct usb_device *dev, unsigned
 long pipe, void *buffer, tmpbuf[0] |= USB_PORT_STAT_RESET;
 		if (reg & EHCI_PS_PP)
 			tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
-
-		if (ehci_is_TDI()) {
-			switch (PORTSC_PSPD(reg)) {
-			case PORTSC_PSPD_FS:
-				break;
-			case PORTSC_PSPD_LS:
-				tmpbuf[1] |= USB_PORT_STAT_LOW_SPEED >> 8;
-				break;
-			case PORTSC_PSPD_HS:
-			default:
-				tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
-				break;
-			}
-		} else {
+		if (ehci_is_TDI())
+			tmpbuf[1] |= ehci_port_speed(ctrl->hcor, reg) >> 8;
+		else
 			tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
-		}
-
 		if (reg & EHCI_PS_CSC)
 			tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
 		if (reg & EHCI_PS_PEC)

drivers/usb/host/ehci-hcd.c int usb_lowlevel_init(int index, void **controller) · line 984

Quoted 4 lines
drivers/usb/host/ehci-hcd.c +1 -0
@@ -954,6 +981,7 @@ int usb_lowlevel_init(int index, void **controller)
 	cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
 	cmd |= FLAG_CF;
 	ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
+

This is redundant ;-)

Quoted 5 lines
drivers/usb/host/ehci-hcd.c +0 -1
 	/* unblock posted write */
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
 	mdelay(5);
--

1.7.9.5

Best regards,
Marek Vasut

#115 lore raw

PATCH v5 2/4 usb: ehci: add weak-aliased functions to portsc & tdi

2013/5/10 Marek Vasut <[email protected]>:

Quoted 57 lines

Dear Kuo-Jung Su,

Quoted 42 lines

From: Kuo-Jung Su <[email protected]>

There is at least one non-EHCI compliant controller (i.e. Faraday EHCI) known to implement a non-standard TDI stuff.
Futhermore, it not only leave reserved and CONFIGFLAG registers un-implemented but also has their address spaces removed.

And thus, we need weak-aliased functions to both TDI stuff and PORTSC registers for interface abstraction.

---
Changes for v5:
- Split up from Faraday EHCI patch

Changes for v2 - v4:
- See 'usb: ehci: add Faraday USB 2.0 EHCI support'

 drivers/usb/host/ehci-hcd.c |  100

+++++++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 36 deletions(-)

drivers/usb/host/ehci-hcd.c +8 -3
index c816878..b334173 100644
@@ -117,10 +117,50 @@ static struct descriptor {
 };
 
 #if defined(CONFIG_EHCI_IS_TDI)
-#define ehci_is_TDI()        (1)
-#else
-#define ehci_is_TDI()        (0)
+# define ehci_is_TDI()       (1)
+
+/* put TDI/ARC silicon into EHCI mode */
+void __ehci_tdi_reset(struct ehci_hcor *hcor)
+{
+     uint32_t tmp, *reg_ptr;
+
+     reg_ptr = (uint32_t *)((uint8_t *) + USBMODE);

drivers/usb/host/ehci-hcd.c static struct descriptor { · line 137

Quoted 10 lines
drivers/usb/host/ehci-hcd.c +9 -0
+     tmp = ehci_readl(reg_ptr);
+     tmp |= USBMODE_CM_HC;
+#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
+     tmp |= USBMODE_BE;
 #endif
+     ehci_writel(reg_ptr, tmp);
+}
+
+void ehci_tdi_reset(struct ehci_hcor *hcor)
+     __attribute__((weak, alias("__ehci_tdi_reset")));

Just wrap this into simple

Quoted 9 lines

__weak void ehci_tdi_reset(struct ehci_hcor *hcor)

{
        ...body of __ehci_tdi_reset() above ...
}

it's the same thing as those two functions above, but without so much code ;-)

if it doesn't work, include <linux/compiler.h>, same below.

Got it, thanks

Quoted 117 lines
Quoted 117 lines
drivers/usb/host/ehci-hcd.c +45 -33
+int __ehci_port_speed(struct ehci_hcor *hcor, unsigned int portsc)
+{
+     int ret = 0;
+
+     switch (PORTSC_PSPD(portsc)) {
+     case PORTSC_PSPD_FS:
+             break;
+     case PORTSC_PSPD_LS:
+             ret = USB_PORT_STAT_LOW_SPEED;
+             break;
+     case PORTSC_PSPD_HS:
+     default:
+             ret = USB_PORT_STAT_HIGH_SPEED;
+             break;
+     }
+
+     return ret;
+}
+
+int ehci_port_speed(struct ehci_hcor *hcor, unsigned int portsc)
+     __attribute__((weak, alias("__ehci_port_speed")));
+
+#else  /* CONFIG_EHCI_IS_TDI */
+# define ehci_is_TDI()       (0)
+#endif /* CONFIG_EHCI_IS_TDI */
 
 void __ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
 {
@@ -149,8 +189,6 @@ static int handshake(uint32_t *ptr, uint32_t mask,
 uint32_t done, int usec) static int ehci_reset(int index)
 {
      uint32_t cmd;
-     uint32_t tmp;
-     uint32_t *reg_ptr;
      int ret = 0;
 
      cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
@@ -163,15 +201,8 @@ static int ehci_reset(int index)
              goto out;
      }
 
-     if (ehci_is_TDI()) {
-             reg_ptr = (uint32_t *)((u8 *)ehcic[index].hcor + USBMODE);
-             tmp = ehci_readl(reg_ptr);
-             tmp |= USBMODE_CM_HC;
-#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
-             tmp |= USBMODE_BE;
-#endif
-             ehci_writel(reg_ptr, tmp);
-     }
+     if (ehci_is_TDI())
+             ehci_tdi_reset(ehcic[index].hcor);
 
 #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
      cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
@@ -597,6 +628,18 @@ static inline int min3(int a, int b, int c)
      return a;
 }
 
+uint32_t *__ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+{
+     if (port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+             printf("The request port(%d) is not configured\n", port);
+             return NULL;
+     }
+
+     return (uint32_t *)&hcor->or_portsc[port];
+}
+uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+     __attribute__((weak, alias("__ehci_get_portsc_register")));
+
 int
 ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
               int length, struct devrequest *req)
@@ -609,13 +652,10 @@ ehci_submit_root(struct usb_device *dev, unsigned
 long pipe, void *buffer, uint32_t *status_reg;
      struct ehci_ctrl *ctrl = dev->controller;
 
-     if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-             printf("The request port(%d) is not configured\n",
-                     le16_to_cpu(req->index) - 1);
+     status_reg = ehci_get_portsc_register(ctrl->hcor,
+             le16_to_cpu(req->index) - 1);
+     if (!status_reg)
              return -1;
-     }
-     status_reg = (uint32_t *)&ctrl->hcor->or_portsc[
-                                             le16_to_cpu(req->index) - 1];
      srclen = 0;
 
      debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
@@ -709,23 +749,10 @@ ehci_submit_root(struct usb_device *dev, unsigned
 long pipe, void *buffer, tmpbuf[0] |= USB_PORT_STAT_RESET;
              if (reg & EHCI_PS_PP)
                      tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
-
-             if (ehci_is_TDI()) {
-                     switch (PORTSC_PSPD(reg)) {
-                     case PORTSC_PSPD_FS:
-                             break;
-                     case PORTSC_PSPD_LS:
-                             tmpbuf[1] |= USB_PORT_STAT_LOW_SPEED >> 8;
-                             break;
-                     case PORTSC_PSPD_HS:
-                     default:
-                             tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
-                             break;
-                     }
-             } else {
+             if (ehci_is_TDI())
+                     tmpbuf[1] |= ehci_port_speed(ctrl->hcor, reg) >> 8;
+             else
                      tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
-             }
-
              if (reg & EHCI_PS_CSC)
                      tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
Quoted 9 lines

drivers/usb/host/ehci-hcd.c int usb_lowlevel_init(int index, void **controller) · line 984

Quoted 6 lines
drivers/usb/host/ehci-hcd.c +1 -0
              if (reg & EHCI_PS_PEC)
@@ -954,6 +981,7 @@ int usb_lowlevel_init(int index, void **controller)
      cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
      cmd |= FLAG_CF;
      ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
+

This is redundant ;-)

Got it, thanks

Quoted 8 lines
Quoted 5 lines
drivers/usb/host/ehci-hcd.c +0 -1
      /* unblock posted write */
      cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
      mdelay(5);
--

1.7.9.5

Best regards,
Marek Vasut

--
Best wishes,
Kuo-Jung Su

#116 lore raw

PATCH v5 3/4 usb: ehci: add Faraday USB 2.0 EHCI support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

This patch adds support to both Faraday FUSBH200 and FOTG210, the differences between Faraday EHCI and standard EHCI are listed bellow:

1. The PORTSC starts at 0x30 instead of 0x44.
2. The CONFIGFLAG(0x40) is not only un-implemented, and also has its address space removed.
3. Faraday EHCI is a TDI design, but it doesn't compatible with the general TDI implementation found at both U-Boot and Linux.
4. The ISOC descriptors differs from standard EHCI in several ways. And since U-boot doesn't support ISOC, we don't have to worry about that.

---
Changes for v5:
- Break down EHCI changes as seperate changesets.
- Fix the invalid multi-line comment style.

Changes for v4:
- Use only macro constants and named bit/mask
- Use weak-aliased functions for tdi implementation and also portsc registers to avoid poluting ehci.h with ifdefs

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 common/usb_hub.c                |    7 +-
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-faraday.c |  146 ++++++++++++++++
 drivers/usb/host/ehci-hcd.c     |    4 +
 include/usb/fotg210.h           |  364 +++++++++++++++++++++++++++++++++++++++
 include/usb/fusbh200.h          |   61 +++++++
 6 files changed, 582 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/host/ehci-faraday.c
 create mode 100644 include/usb/fotg210.h
 create mode 100644 include/usb/fusbh200.h
common/usb_hub.c +6 -1
index 0db3530..6513abe 100644
@@ -447,7 +447,11 @@ static int usb_hub_configure(struct usb_device *dev)
 					i + 1, portstatus);
 			usb_clear_port_feature(dev, i + 1,
 						USB_PORT_FEAT_C_ENABLE);
-
+			/*
+			 * The following hack causes a ghost device problem
+			 * to Faraday EHCI
+			 */
+#ifndef CONFIG_USB_EHCI_FARADAY
 			/* EM interference sometimes causes bad shielded USB
 			 * devices to be shutdown by the hub, this hack enables
 			 * them again. Works at least with mouse driver */
@@ -459,6 +463,7 @@ static int usb_hub_configure(struct usb_device *dev)
 						"re-enabling...\n", i + 1);
 					usb_hub_port_connect_change(dev, i);
 			}
+#endif
 		}
 		if (portstatus & USB_PORT_STAT_SUSPEND) {
 			USB_HUB_PRINTF("port %d suspend change\n", i + 1);
drivers/usb/host/Makefile +1 -0
index 87a5970..98f2a10 100644
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o
 else
 COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
 endif
+COBJS-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o
 COBJS-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
 COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
 COBJS-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o
drivers/usb/host/ehci-faraday.c new file +146 -0

146 lines not on this page · raw message

drivers/usb/host/ehci-hcd.c +4 -0
index b334173..36ad897 100644
@@ -604,10 +604,12 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		dev->act_len = length - QT_TOKEN_GET_TOTALBYTES(token);
 	} else {
 		dev->act_len = 0;
+#ifndef CONFIG_USB_EHCI_FARADAY
 		debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n",
 		      dev->devnum, ehci_readl(&ctrl->hcor->or_usbsts),
 		      ehci_readl(&ctrl->hcor->or_portsc[0]),
 		      ehci_readl(&ctrl->hcor->or_portsc[1]));
+#endif
 	}
 
 	free(qtd);
@@ -977,10 +979,12 @@ int usb_lowlevel_init(int index, void **controller)
 	cmd |= CMD_RUN;
 	ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
 
+#ifndef CONFIG_USB_EHCI_FARADAY
 	/* take control over the ports */
 	cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
 	cmd |= FLAG_CF;
 	ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
+#endif
 
 	/* unblock posted write */
 	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
include/usb/fotg210.h new file +364 -0

364 lines not on this page · raw message

include/usb/fusbh200.h new file +61 -0

61 lines not on this page · raw message

--
1.7.9.5

#117 lore raw

PATCH v5 4/4 usb: gadget: add Faraday FOTG210 USB gadget support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device as a time.

---
Changes for v5:
- Coding Style cleanup.
- Drop postfix '__iomem' from struct fotg210_regs
- Use permanent delay for hardware reset
- Drop '#ifndef CONFIG_SYS_DCACHE_OFF'
- Drop magic numbers

Changes for v4:
- Use only macro constants and named bit/mask
- Remove dcache_enable() from usb_gadget_register_driver()

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  948 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 3 files changed, 957 insertions(+)
 create mode 100644 drivers/usb/gadget/fotg210.c
drivers/usb/gadget/Makefile +1 -0
index e545b6b..432cf17 100644
@@ -35,6 +35,7 @@ endif
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
 endif
drivers/usb/gadget/fotg210.c new file +948 -0

948 lines not on this page · raw message

drivers/usb/gadget/gadget_chips.h +8 -0
index e570142..f038747 100644
@@ -150,6 +150,12 @@
 #define gadget_is_mv(g)        0
 #endif
 
+#ifdef CONFIG_USB_GADGET_FOTG210
+#define gadget_is_fotg210(g)        (!strcmp("fotg210_udc", (g)->name))
+#else
+#define gadget_is_fotg210(g)        0
+#endif
+
 /*
  * CONFIG_USB_GADGET_SX2
  * CONFIG_USB_GADGET_AU1X00
@@ -215,5 +221,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
 		return 0x20;
 	else if (gadget_is_mv(gadget))
 		return 0x21;
+	else if (gadget_is_fotg210(gadget))
+		return 0x22;
 	return -ENOENT;
 }

--
1.7.9.5

#118 lore raw

PATCH v4 2/2 usb: gadget: add Faraday FOTG210 USB gadget support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device as a time.

---
Changes for v4:
- Use only macro constants and named bit/mask
- Remove dcache_enable() from usb_gadget_register_driver()

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  961 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 3 files changed, 970 insertions(+)
 create mode 100644 drivers/usb/gadget/fotg210.c
drivers/usb/gadget/Makefile +1 -0
index e545b6b..432cf17 100644
@@ -35,6 +35,7 @@ endif
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
 endif
drivers/usb/gadget/fotg210.c new file +961 -0

961 lines not on this page · raw message

drivers/usb/gadget/gadget_chips.h +8 -0
index e570142..f038747 100644
@@ -150,6 +150,12 @@
 #define gadget_is_mv(g)        0
 #endif
 
+#ifdef CONFIG_USB_GADGET_FOTG210
+#define gadget_is_fotg210(g)        (!strcmp("fotg210_udc", (g)->name))
+#else
+#define gadget_is_fotg210(g)        0
+#endif
+
 /*
  * CONFIG_USB_GADGET_SX2
  * CONFIG_USB_GADGET_AU1X00
@@ -215,5 +221,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
 		return 0x20;
 	else if (gadget_is_mv(gadget))
 		return 0x21;
+	else if (gadget_is_fotg210(gadget))
+		return 0x22;
 	return -ENOENT;
 }

--
1.7.9.5

#119 lore raw

PATCH v4 2/2 usb: gadget: add Faraday FOTG210 USB gadget support

Dear Kuo-Jung Su,

Quoted 71 lines

From: Kuo-Jung Su <[email protected]>

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device as a time.

---
Changes for v4:
- Use only macro constants and named bit/mask
- Remove dcache_enable() from usb_gadget_register_driver()

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  961
+++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/gadget_chips.h | 
  8 +
 3 files changed, 970 insertions(+)
 create mode 100644 drivers/usb/gadget/fotg210.c
drivers/usb/gadget/Makefile +1 -0
index e545b6b..432cf17 100644
@@ -35,6 +35,7 @@ endif
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
 endif
drivers/usb/gadget/fotg210.c new file +8 -0
new file mode 100644
index 0000000..70797ae
@@ -0,0 +1,961 @@
+/*
+ * Faraday USB 2.0 OTG Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for

details. + */

drivers/usb/gadget/fotg210.c new file +10 -0
+
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <net.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <linux/types.h>
+#include <linux/usb/ch9.h>

drivers/usb/gadget/fotg210.c line 29

Quoted 10 lines
drivers/usb/gadget/fotg210.c new file +10 -0
+#include <linux/usb/gadget.h>
+
+#include <usb/fotg210.h>
+
+#define CFG_NUM_ENDPOINTS		4
+#define CFG_EP0_MAX_PACKET_SIZE	64
+#define CFG_EPX_MAX_PACKET_SIZE	512
+
+#define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 2) /* 250 ms */
+#define CFG_RST_TIMEOUT (CONFIG_SYS_HZ >> 2) /* 250 ms */

Uh, how's this supposed to work? Why don't you just use mdelay(250) with those?

[...]

drivers/usb/gadget/fotg210.c line 82

Quoted 4 lines
drivers/usb/gadget/fotg210.c new file +4 -0
+static inline int ep_reset(struct fotg210_chip *chip, uint8_t ep_addr)
+{
+	int ep = ep_addr & USB_ENDPOINT_NUMBER_MASK;
+	struct fotg210_regs __iomem *regs = chip->regs;

No need for __iomem here.

[...]

drivers/usb/gadget/fotg210.c line 256

Quoted 7 lines
drivers/usb/gadget/fotg210.c new file +7 -0
+	/* 3. DMA target setup */
+#ifndef CONFIG_SYS_DCACHE_OFF
+	if (ep->desc->bEndpointAddress & USB_DIR_IN)
+		flush_dcache_range((uint32_t)buf, (uint32_t)buf + len);
+	else
+		invalidate_dcache_range((uint32_t)buf, (uint32_t)buf + len);
+#endif

The cache stuff will be optimized out anyway, no ?

[...]

drivers/usb/gadget/fotg210.c line 355

Quoted 8 lines
drivers/usb/gadget/fotg210.c new file +8 -0
+			if (readl(&regs->dev_ctrl) & DEVCTRL_HS) {
+				puts("fotg210: HS\n");
+				chip->gadget.speed = USB_SPEED_HIGH;
+				writel(0x044c, &regs->sof_mtr);
+			} else {
+				puts("fotg210: FS\n");
+				chip->gadget.speed = USB_SPEED_FULL;
+				writel(0x2710, &regs->sof_mtr);

Magic values, please fix globally as previously asked.

[...]

#120 lore raw

PATCH v4 2/2 usb: gadget: add Faraday FOTG210 USB gadget support

2013/5/8 Marek Vasut <[email protected]>:

Quoted 77 lines

Dear Kuo-Jung Su,

Quoted 75 lines

From: Kuo-Jung Su <[email protected]>

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device as a time.

---
Changes for v4:
- Use only macro constants and named bit/mask
- Remove dcache_enable() from usb_gadget_register_driver()

Changes for v3:
- Coding Style cleanup.
- Drop bit fields from c struct.
- Drop macros for wirtel()/readl(), call them directly.
- Always insert a blank line between declarations and code.
- Replace all the infinite wait loop with a timeout.
- Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
- Coding Style cleanup.
- Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
- Use structure based hardware registers to replace the macro constants.
- Replace BIT() with BIT_MASK().
- echi-faraday: Remove debug codes.

 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  961
+++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/gadget_chips.h |
  8 +
 3 files changed, 970 insertions(+)
 create mode 100644 drivers/usb/gadget/fotg210.c
drivers/usb/gadget/Makefile +1 -0
index e545b6b..432cf17 100644
@@ -35,6 +35,7 @@ endif
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
 endif
drivers/usb/gadget/fotg210.c new file +8 -0
new file mode 100644
index 0000000..70797ae
@@ -0,0 +1,961 @@
+/*
+ * Faraday USB 2.0 OTG Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <[email protected]>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for

details. + */

drivers/usb/gadget/fotg210.c new file +14 -0
+
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <net.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <linux/types.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+#include <usb/fotg210.h>
+
Quoted 9 lines

drivers/usb/gadget/fotg210.c line 29

Quoted 6 lines
drivers/usb/gadget/fotg210.c new file +6 -0
+#define CFG_NUM_ENDPOINTS            4
+#define CFG_EP0_MAX_PACKET_SIZE      64
+#define CFG_EPX_MAX_PACKET_SIZE      512
+
+#define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 2) /* 250 ms */
+#define CFG_RST_TIMEOUT (CONFIG_SYS_HZ >> 2) /* 250 ms */

Uh, how's this supposed to work? Why don't you just use mdelay(250) with those?

1. The CFG_CMD_TIMEOUT is used for polling dma or ep0 fifo ready, put a permanent delay (i.e. mdelay()) here would slow down the overall performance.

2. The CFG_RST_TIMEOUT is used for polling chip reset or fifo reset. It's definitely O.K to replace it with a permanent delay, so I'll
do it later

Quoted 9 lines

[...]

drivers/usb/gadget/fotg210.c line 82

Quoted 4 lines
drivers/usb/gadget/fotg210.c new file +4 -0
+static inline int ep_reset(struct fotg210_chip *chip, uint8_t ep_addr)
+{
+     int ep = ep_addr & USB_ENDPOINT_NUMBER_MASK;
+     struct fotg210_regs __iomem *regs = chip->regs;

No need for __iomem here.

Got it, thanks

Quoted 12 lines

[...]

drivers/usb/gadget/fotg210.c line 256

Quoted 7 lines
drivers/usb/gadget/fotg210.c new file +7 -0
+     /* 3. DMA target setup */
+#ifndef CONFIG_SYS_DCACHE_OFF
+     if (ep->desc->bEndpointAddress & USB_DIR_IN)
+             flush_dcache_range((uint32_t)buf, (uint32_t)buf + len);
+     else
+             invalidate_dcache_range((uint32_t)buf, (uint32_t)buf + len);
+#endif

The cache stuff will be optimized out anyway, no ?

That's right, I'll have the #ifdef statement removed later

Quoted 11 lines

[...]

drivers/usb/gadget/fotg210.c line 355

Quoted 8 lines
drivers/usb/gadget/fotg210.c new file +8 -0
+                     if (readl(&regs->dev_ctrl) & DEVCTRL_HS) {
+                             puts("fotg210: HS\n");
+                             chip->gadget.speed = USB_SPEED_HIGH;
+                             writel(0x044c, &regs->sof_mtr);
+                     } else {
+                             puts("fotg210: FS\n");
+                             chip->gadget.speed = USB_SPEED_FULL;
+                             writel(0x2710, &regs->sof_mtr);
Quoted 2 lines

Magic values, please fix globally as previously asked.

Sorry, I forget to fix this one.

Quoted 2 lines

[...]

--
Best wishes,
Kuo-Jung Su

#121 lore raw

PATCH v4 2/2 usb: gadget: add Faraday FOTG210 USB gadget support

Dear Kuo-Jung Su,

[...]

Quoted 6 lines
Quoted 2 lines

Uh, how's this supposed to work? Why don't you just use mdelay(250) with those?

1. The CFG_CMD_TIMEOUT is used for polling dma or ep0 fifo ready, put a permanent delay (i.e. mdelay()) here would slow down the overall performance.

Understood

Quoted 3 lines

2. The CFG_RST_TIMEOUT is used for polling chip reset or fifo reset. It's definitely O.K to replace it with a permanent delay, so I'll
do it later

Agreed, nice to see we're getting real close with this patchset.

[...]

Best regards,
Marek Vasut

#122 lore raw

PATCH v3 9/11 usb: gadget: add Faraday FOTG210 USB gadget support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device as a time.

---
 drivers/usb/gadget/Makefile       |    1 +
 drivers/usb/gadget/fotg210.c      |  953 +++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/gadget_chips.h |    8 +
 3 files changed, 962 insertions(+)
 create mode 100644 drivers/usb/gadget/fotg210.c
drivers/usb/gadget/Makefile +1 -0
index e545b6b..432cf17 100644
@@ -35,6 +35,7 @@ endif
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
 endif
drivers/usb/gadget/fotg210.c new file +953 -0

953 lines not on this page · raw message

drivers/usb/gadget/gadget_chips.h +8 -0
index e570142..f038747 100644
@@ -150,6 +150,12 @@
 #define gadget_is_mv(g)        0
 #endif
 
+#ifdef CONFIG_USB_GADGET_FOTG210
+#define gadget_is_fotg210(g)        (!strcmp("fotg210_udc", (g)->name))
+#else
+#define gadget_is_fotg210(g)        0
+#endif
+
 /*
  * CONFIG_USB_GADGET_SX2
  * CONFIG_USB_GADGET_AU1X00
@@ -215,5 +221,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
 		return 0x20;
 	else if (gadget_is_mv(gadget))
 		return 0x21;
+	else if (gadget_is_fotg210(gadget))
+		return 0x22;
 	return -ENOENT;
 }
Signature · 1 line
1.7.9.5
#123 lore raw

PATCH v3 9/11 usb: gadget: add Faraday FOTG210 USB gadget support

Dear Kuo-Jung Su,

Quoted 7 lines

From: Kuo-Jung Su <[email protected]>

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device as a time.

Same rambling as for the other patch, bits should have proper names defined in the fotg_....h header file. You should avoid calling dcache_enable()/dcache_disable() throughout the driver, why do you need to do that? Rather implement proper cacheline flushing/invalidation.

Best regards,
Marek Vasut

#124 lore raw

PATCH v3 9/11 usb: gadget: add Faraday FOTG210 USB gadget support

2013/4/26 Marek Vasut <[email protected]>:

Quoted 4 lines

Dear Kuo-Jung Su,

Quoted 2 lines

From: Kuo-Jung Su <[email protected]>

Quoted 8 lines
Quoted 5 lines

The Faraday FOTG210 is an OTG chip which could operate as either an EHCI Host or a USB Device as a time.

Same rambling as for the other patch, bits should have proper names defined in the fotg_....h header file.

Got it, thanks

Quoted 4 lines

You should avoid calling
dcache_enable()/dcache_disable() throughout the driver, why do you need to do that? Rather implement proper cacheline flushing/invalidation.

Sorry, it's my debug codes in the old days, it would be cleanup later

Quoted 2 lines

Best regards,
Marek Vasut

--
Best wishes,
Kuo-Jung Su

#125 lore raw

PATCH v3 10/11 video: add Faraday FTLCDC200 LCD controller support

In reply to Kuo-Jung Su

From: Kuo-Jung Su <[email protected]>

Faraday FTLCDC200 Color LCD controller performs translation of pixel-coded data into the required formats and timings to drive a variety of single/dual mono and color LCDs.

Depending on the LCD type and mode, the unpacked data can represent:
1. an actual true display gray or color value
2. an address to a 256 x 16 bit wide palette RAM gray or color value.

The FTLCDC200 generates 4 individual interrupts for:
1. DMA FIFO underflow
2. base address update
3. vertical status
4. bus error.

There is also a single combined interrupt that is raised when any of the individual interrupts become active.

CC Anatolij Gustschin <[email protected]>
---
 drivers/video/Makefile          |    1 +
 drivers/video/ftlcdc200.c       |  144 +++++++++++++++++++++++++++
 drivers/video/ftlcdc200_panel.c |  210 +++++++++++++++++++++++++++++++++++++++
 include/faraday/ftlcdc200.h     |  179 +++++++++++++++++++++++++++++++++
 include/lcd.h                   |   33 ++++++
 5 files changed, 567 insertions(+)
 create mode 100644 drivers/video/ftlcdc200.c
 create mode 100644 drivers/video/ftlcdc200_panel.c
 create mode 100644 include/faraday/ftlcdc200.h
drivers/video/Makefile +1 -0
index 53952ab..ec8df26 100644
@@ -35,6 +35,7 @@ COBJS-$(CONFIG_EXYNOS_MIPI_DSIM) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \
 				exynos_mipi_dsi_lowlevel.o
 COBJS-$(CONFIG_EXYNOS_PWM_BL) += exynos_pwm_bl.o
 COBJS-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o videomodes.o
+COBJS-$(CONFIG_FTLCDC200) += ftlcdc200.o ftlcdc200_panel.o
 COBJS-$(CONFIG_MPC8XX_LCD) += mpc8xx_lcd.o
 COBJS-$(CONFIG_PXA_LCD) += pxa_lcd.o
 COBJS-$(CONFIG_S6E8AX0) += s6e8ax0.o
drivers/video/ftlcdc200.c new file +144 -0

144 lines not on this page · raw message

drivers/video/ftlcdc200_panel.c new file +210 -0

210 lines not on this page · raw message

include/faraday/ftlcdc200.h new file +179 -0

179 lines not on this page · raw message

include/lcd.h +33 -0
index c6e7fc5..1d9e584 100644
@@ -253,6 +253,39 @@ typedef struct vidinfo {
 
 void init_panel_info(vidinfo_t *vid);
 
+#elif defined(CONFIG_FTLCDC200)
+
+typedef struct vidinfo {
+	ushort	vl_col;		/* Number of columns (i.e. 800) */
+	ushort	vl_row;		/* Number of rows (i.e. 600) */
+
+	u_char	vl_bpix;	/* Bits per pixel, 0 = 1, 1 = 2 ... 4 = 16 */
+
+	/* Timing Parameters */
+	u_char	vl_fps;		/* Frame per second */
+
+	u_char	vl_hsw;
+	u_char	vl_hbp;
+	u_char	vl_hfp;
+
+	u_char	vl_vsw;
+	u_char	vl_vbp;
+	u_char	vl_vfp;
+
+	/* Pre-defined FTLCDC200 register values */
+	u_long	vl_enable;	/* LCDEnable */
+	u_long	vl_pixel;	/* PanelPixel */
+	u_long	vl_polarity;/* Polarity */
+	u_long	vl_serial;	/* SerialPanelPixel */
+	u_long	vl_ccir656;	/* CCIR656 */
+
+	/* Panel name */
+	char	*vl_name;
+
+	ushort	*cmap;		/* Pointer to the colormap */
+	void	*priv;		/* Pointer to driver-specific data */
+} vidinfo_t;
+
 #else
 
 typedef struct vidinfo {
Signature · 1 line
1.7.9.5
#126 lore raw

PATCH v3 10/11 video: add Faraday FTLCDC200 LCD controller support

Hi,

Quoted 16 lines · On Fri, 26 Apr 2013 16:02:39 +0800 Kuo-Jung Su <[email protected]> wrote:

From: Kuo-Jung Su <[email protected]>

Faraday FTLCDC200 Color LCD controller performs translation of pixel-coded data into the required formats and timings to drive a variety of single/dual mono and color LCDs.

Depending on the LCD type and mode, the unpacked data can represent:
1. an actual true display gray or color value
2. an address to a 256 x 16 bit wide palette RAM gray or color value.

The FTLCDC200 generates 4 individual interrupts for:
1. DMA FIFO underflow
2. base address update
3. vertical status
4. bus error.

Quoted 5 lines

There is also a single combined interrupt that is raised when any of the individual interrupts become active.

CC Anatolij Gustschin <[email protected]>