diff mbox

[U-Boot,01/11] arm: add MMU/d-cache support for Faraday cores

Message ID 1364540788-13943-2-git-send-email-dantesu@gmail.com
State Superseded
Delegated to: Albert ARIBAUD
Headers show

Commit Message

Kuo-Jung Su March 29, 2013, 7:06 a.m. UTC
From: Kuo-Jung Su <dantesu@faraday-tech.com>

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 +-------------------+

Signed-off-by: Kuo-Jung Su <dantesu@faraday-tech.com>
---
 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(-)

--
1.7.9.5

Comments

Kuo-Jung Su April 18, 2013, 9:25 a.m. UTC | #1
From: Kuo-Jung Su <dantesu@faraday-tech.com>

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
Wolfgang Denk April 18, 2013, 10:43 a.m. UTC | #2
Dear Kuo-Jung Su,

In message <1366277139-29728-1-git-send-email-dantesu@gmail.com> you wrote:
> 
> These patches introduce Faraday A36x SoC platform support.

Please run all your patches through checkpatch and clean up thew
reported warnings and errors before you resubmit.

Best regards,

Wolfgang Denk
Kuo-Jung Su April 22, 2013, 1:27 a.m. UTC | #3
2013/4/18 Wolfgang Denk <wd@denx.de>:
> Dear Kuo-Jung Su,
>
> In message <1366277139-29728-1-git-send-email-dantesu@gmail.com> you wrote:
>>
>> These patches introduce Faraday A36x SoC platform support.
>
> Please run all your patches through checkpatch and clean up thew
> reported warnings and errors before you resubmit.
>

Got it, thanks

> Best regards,
>
> Wolfgang Denk
>
> --
> DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
> "The algorithm to do that is extremely nasty. You might want  to  mug
> someone with it."                   - M. Devine, Computer Science 340



--
Best wishes,
Kuo-Jung Su
diff mbox

Patch

diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 5bbb0a0..d4f779e 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -2,6 +2,8 @@ 
  * (C) Copyright 2007
  * Stelian Pop <stelian@popies.net>
  * Lead Tech Design <www.leadtechdesign.com>
+ * (C) Copyright 2010
+ * Dante Su <dantesu@faraday-tech.com>
  *
  * 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,
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index 37ac0da..bd18ff7 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -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;
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 1fbc531..4659439 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -2,6 +2,7 @@ 
  *  linux/include/asm-arm/io.h
  *
  *  Copyright (C) 1996-2000 Russell King
+ *  Copyright (C) 2009-2010 Dante Su <dantesu@faraday-tech.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -57,9 +58,83 @@  static inline void unmap_physmem(void *vaddr, unsigned long flags)

 }

+#if defined(CONFIG_FARADAY)
+
+#include <asm/u-boot.h> /* boot information for Linux kernel */
+#include <asm/global_data.h>
+
+static inline void *__cached(void *va)
+{
+# if !defined(CONFIG_SYS_DCACHE_OFF)
+	DECLARE_GLOBAL_DATA_PTR;
+	unsigned long base = (4096 - (gd->ram_size >> 20)) << 20;	/* un-cached base address */
+
+	if (!gd->arch.cpu_mmu)
+		return va;
+
+	if ((unsigned long)va >= base &&
+		(unsigned long)va < (base + gd->ram_size))
+		va = (void *)((unsigned long)va - base + CONFIG_SYS_SDRAM_BASE);
+# endif	/* !CONFIG_SYS_DCACHE_OFF */
+
+	return va;
+}
+
+static inline void *__uncached(void *va)
+{
+# if !defined(CONFIG_SYS_DCACHE_OFF)
+	DECLARE_GLOBAL_DATA_PTR;
+	unsigned long base = (4096 - (gd->ram_size >> 20)) << 20;	/* un-cached base address */
+
+	if (!gd->arch.cpu_mmu)
+		return va;
+
+# ifdef CONFIG_USE_IRQ
+	if ((unsigned long)va < SZ_1M)
+		return (void *)(base + (unsigned long)va);
+# endif
+
+	if ((unsigned long)va >= CONFIG_SYS_SDRAM_BASE &&
+		(unsigned long)va < (CONFIG_SYS_SDRAM_BASE + gd->ram_size))
+		return (void *)(base + ((unsigned long)va - CONFIG_SYS_SDRAM_BASE));
+# endif	/* !CONFIG_SYS_DCACHE_OFF */
+
+	return va;
+}
+
+#endif	/* CONFIG_FARADAY */
+
 static inline phys_addr_t virt_to_phys(void * vaddr)
 {
+#if defined(CONFIG_FARADAY) && !defined(CONFIG_SYS_DCACHE_OFF)
+
+	DECLARE_GLOBAL_DATA_PTR;
+	bd_t *bd = gd->bd;
+	unsigned long base = (4096 - (gd->ram_size >> 20)) << 20;	/* un-cached base address */
+	unsigned long phys = (unsigned long)(vaddr);
+
+	if (!gd->arch.cpu_mmu)
+		return (phys_addr_t)phys;
+
+	if (phys >= base) {
+		unsigned long bank;
+		unsigned long off = phys - base;
+		for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; ++bank) {
+			if (bd->bi_dram[bank].size > off)
+				break;
+			off -= bd->bi_dram[bank].size;
+		}
+		phys = bd->bi_dram[bank].start + off;
+	}
+# ifdef CONFIG_USE_IRQ
+	else if (phys < SZ_1M && bd->bi_dram[0].start != 0)
+		phys = bd->bi_dram[0].start + phys;
+# endif
+
+	return (phys_addr_t)phys;
+#else
 	return (phys_addr_t)(vaddr);
+#endif
 }

 /*
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index b6e5e95..cf45d31 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -1,6 +1,8 @@ 
 /*
  * (C) Copyright 2002
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * (C) Copyright 2010
+ * Dante Su <dantesu@faraday-tech.com>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -81,6 +83,10 @@  static inline void dram_bank_mmu_setup(int bank)
 {
 	bd_t *bd = gd->bd;
 	int	i;
+#ifdef CONFIG_FARADAY
+	ulong ubase, off;
+	u32 *page_table = (u32 *)gd->arch.tlb_addr;
+#endif

 	debug("%s: bank: %d\n", __func__, bank);
 	for (i = bd->bi_dram[bank].start >> 20;
@@ -92,6 +98,32 @@  static inline void dram_bank_mmu_setup(int bank)
 		set_section_dcache(i, DCACHE_WRITEBACK);
 #endif
 	}
+#ifdef CONFIG_FARADAY
+# ifdef CONFIG_USE_IRQ
+	/* map the exception table to 0x00000000 if necessary */
+	if (bank == 0 && bd->bi_dram[bank].start != 0) {
+		u32 pa = bd->bi_dram[bank].start;
+#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+		page_table[0] = pa | (3 << 10) | DCACHE_WRITETHROUGH;
+#else
+		page_table[0] = pa | (3 << 10) | DCACHE_WRITEBACK;
+#endif
+	}
+# endif
+	/* calculate address offset */
+	off  = 0;
+	for (i = 0; i < bank; ++i)
+		off += bd->bi_dram[bank].size;
+
+	/* create memory map */
+	ubase = (4096 - (gd->ram_size >> 20)) << 20;
+	for (i = 0; i < bd->bi_dram[bank].size >> 20; ++i) {
+		u32 pa = bd->bi_dram[bank].start + (i << 20);
+		/* create un-cached address map */
+		u32 va = ubase + off + (i << 20);
+		page_table[va >> 20] = pa | (3 << 10) | DCACHE_OFF;
+	}
+#endif
 }

 /* to activate the MMU we need to set up virtual memory: use 1M areas */
@@ -117,6 +149,12 @@  static inline void mmu_setup(void)
 		     : : "r" (~0));
 	/* and enable the mmu */
 	reg = get_cr();	/* get control reg. */
+#if !defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+	reg |= CR_W;
+#endif
+#ifdef CONFIG_FARADAY
+	reg |= CR_Z;	/* Branch Prediction */
+#endif
 	cp_delay();
 	set_cr(reg | CR_M);
 }
@@ -131,9 +169,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);
diff --git a/common/cmd_boot.c b/common/cmd_boot.c
index d3836fd..b2477e8 100644
--- a/common/cmd_boot.c
+++ b/common/cmd_boot.c
@@ -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