All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400
@ 2020-11-17 20:59 Lubomir Rintel
  2020-11-17 20:59 ` [PATCH RFC 01/20] config: Remove CONFIG_SYS_ID_EEPROM Lubomir Rintel
                   ` (19 more replies)
  0 siblings, 20 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 20:59 UTC (permalink / raw)
  To: u-boot

Hi,

chained to his message are patches that implement support for the Ingenic
JZ4730 MIPS SoC and a laptop that's based around it.

Please consider this RFC-quality: there are some known issues that need to be
resolved before some of the patches could be applied (indicated in some of the
patches themselves) and there are also certainly issues unknown to me that
would be obvious to others given I haven't really submitted code to U-Boot
apart from some very trifial stuff. I'll be very thankful for any feeback.

The hardware support added by this patch set is essentially equivalent to
vendor U-Boot that's shipped with the machine: boot off NAND works, MMC,
UART and Ethernet are supported. LCD, GPIO matrix keyboard and OHCI USB
don't work at this point. CONFIG_DISTRO_DEFAULT makes it convenient to
run custom kernels in place of the vendor's one, but the compatibility with
the vendor kernels is retained.

The first three patches are not actually JZ4730 specific, but they are
dependend on by the JZ4730 work:

  [PATCH RFC 01/20] config: Remove CONFIG_SYS_ID_EEPROM
  [PATCH RFC 02/20] mtd: Allow building nand_spl_simple w/o SPL_NAND_ECC
  [PATCH RFC 03/20] cmd/mac: Don't build unless CONFIG_CMD_MAC is enabled

The rest of the patches implement JZ4730 hardware support:

  [PATCH RFC 04/20] mips: Don't access CP0_EBASE on JZ47XX
  [PATCH RFC 05/20] ns16550: Turn on the UME bit if on ARCH_JZ47XX
  [PATCH RFC 06/20] clk: Add driver for Ingenic JZ4730 CGU
  [PATCH RFC 07/20] timer-uclass: Tolerate failure to get clock rate in
  [PATCH RFC 08/20] timer: Add Ingenic JZ4730 timer driver
  [PATCH RFC 09/20] mmc: Default to JZ47XX_MMC=y on ARCH_JZ47XX
  [PATCH RFC 10/20] mmc/jz_mmc: Add a JZ4740 compatible string
  [PATCH RFC 11/20] mmc/jz_mmc: Support wp-gpio/cd-gpio
  [PATCH RFC 12/20] pinctrl: Add Ingenic JZ4730 pin control and GPIO driver
  [PATCH RFC 13/20] nand: Use correct prototype of board_nand_init() with
  [PATCH RFC 14/20] nand/raw: Add Ingenic JZ4730 NAND flash driver
  [PATCH RFC 15/20] watchdog: Add Ingenic JZ4730 watchdog timer driver
  [PATCH RFC 16/20] net: Add Ingenic JZ4730 Ethernet driver
  [PATCH RFC 17/20] mips: dts: Add Ingenic JZ4730
  [PATCH RFC 18/20] mips/mach-jz47xx: Add Ingenic JZ4730 support
  [PATCH RFC 19/20] mips: dts: Add Skytone Alpha 400
  [PATCH RFC 20/20] board: Add Skytone Alpha 400

In case someone finds git more convenient to work with than e-mail, here
you go:

  git pull git://git.kernel.org/pub/scm/linux/kernel/git/lkundrak/u-boot.git lr/alpha400

Thank you
Lubo

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC 01/20] config: Remove CONFIG_SYS_ID_EEPROM
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
@ 2020-11-17 20:59 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 02/20] mtd: Allow building nand_spl_simple w/o SPL_NAND_ECC Lubomir Rintel
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 20:59 UTC (permalink / raw)
  To: u-boot

It seems to be a vestige of a somewhat messed up attempt to rename
CFG_ID_EEPROM -- the name that actually got used is CONFIG_ID_EEPROM.
Remove it.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 include/configs/MPC8541CDS.h | 1 -
 include/configs/MPC8548CDS.h | 1 -
 include/configs/MPC8555CDS.h | 1 -
 scripts/config_whitelist.txt | 1 -
 4 files changed, 4 deletions(-)

diff --git a/include/configs/MPC8541CDS.h b/include/configs/MPC8541CDS.h
index b1c8917f216..58d5ed158a3 100644
--- a/include/configs/MPC8541CDS.h
+++ b/include/configs/MPC8541CDS.h
@@ -241,7 +241,6 @@ extern unsigned long get_clock_freq(void);
 /* EEPROM */
 #define CONFIG_ID_EEPROM
 #define CONFIG_SYS_I2C_EEPROM_CCID
-#define CONFIG_SYS_ID_EEPROM
 #define CONFIG_SYS_I2C_EEPROM_ADDR     0x57
 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
 
diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h
index 4efc182ef83..4fce6be8407 100644
--- a/include/configs/MPC8548CDS.h
+++ b/include/configs/MPC8548CDS.h
@@ -312,7 +312,6 @@ extern unsigned long get_clock_freq(void);
 /* EEPROM */
 #define CONFIG_ID_EEPROM
 #define CONFIG_SYS_I2C_EEPROM_CCID
-#define CONFIG_SYS_ID_EEPROM
 #define CONFIG_SYS_I2C_EEPROM_ADDR     0x57
 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
 
diff --git a/include/configs/MPC8555CDS.h b/include/configs/MPC8555CDS.h
index 88999ef2b85..8e4ba3601ab 100644
--- a/include/configs/MPC8555CDS.h
+++ b/include/configs/MPC8555CDS.h
@@ -239,7 +239,6 @@ extern unsigned long get_clock_freq(void);
 /* EEPROM */
 #define CONFIG_ID_EEPROM
 #define CONFIG_SYS_I2C_EEPROM_CCID
-#define CONFIG_SYS_ID_EEPROM
 #define CONFIG_SYS_I2C_EEPROM_ADDR     0x57
 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
 
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 0aabe7a4516..291de2a65ac 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -2789,7 +2789,6 @@ CONFIG_SYS_ICACHE_INV
 CONFIG_SYS_ICS8N3QV01_I2C
 CONFIG_SYS_IDE_MAXBUS
 CONFIG_SYS_IDE_MAXDEVICE
-CONFIG_SYS_ID_EEPROM
 CONFIG_SYS_IFC_ADDR
 CONFIG_SYS_IFC_CCR
 CONFIG_SYS_INIT_DBCR
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 02/20] mtd: Allow building nand_spl_simple w/o SPL_NAND_ECC
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
  2020-11-17 20:59 ` [PATCH RFC 01/20] config: Remove CONFIG_SYS_ID_EEPROM Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 03/20] cmd/mac: Don't build unless CONFIG_CMD_MAC is enabled Lubomir Rintel
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

The Skytone Alpha 400 boards don't use ECC.

It's probably and oversignt and certainly a bad idea, nevertheless
enforcing ECC on existing boards would break boot. Sigh.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/mtd/nand/raw/nand_spl_simple.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_spl_simple.c b/drivers/mtd/nand/raw/nand_spl_simple.c
index 09e053541a9..ea5bcaf3982 100644
--- a/drivers/mtd/nand/raw/nand_spl_simple.c
+++ b/drivers/mtd/nand/raw/nand_spl_simple.c
@@ -9,14 +9,16 @@
 #include <asm/io.h>
 #include <linux/mtd/nand_ecc.h>
 
-static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
 static struct mtd_info *mtd;
 static struct nand_chip nand_chip;
 
+#if IS_ENABLED(CONFIG_SPL_NAND_ECC)
+static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
+
 #define ECCSTEPS	(CONFIG_SYS_NAND_PAGE_SIZE / \
 					CONFIG_SYS_NAND_ECCSIZE)
 #define ECCTOTAL	(ECCSTEPS * CONFIG_SYS_NAND_ECCBYTES)
-
+#endif
 
 #if (CONFIG_SYS_NAND_PAGE_SIZE <= 512)
 /*
@@ -166,7 +168,7 @@ static int nand_read_page(int block, int page, uchar *dst)
 
 	return 0;
 }
-#else
+#elif IS_ENABLED(CONFIG_SPL_NAND_ECC)
 static int nand_read_page(int block, int page, void *dst)
 {
 	struct nand_chip *this = mtd_to_nand(mtd);
@@ -206,6 +208,16 @@ static int nand_read_page(int block, int page, void *dst)
 
 	return 0;
 }
+#else
+static int nand_read_page(int block, int page, void *dst)
+{
+	struct nand_chip *this = mtd_to_nand(mtd);
+
+	nand_command(block, page, 0, NAND_CMD_READ0);
+	this->read_buf(mtd, dst, CONFIG_SYS_NAND_PAGE_SIZE);
+
+	return 0;
+}
 #endif
 
 /* nand_init() - initialize data to make nand usable by SPL */
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 03/20] cmd/mac: Don't build unless CONFIG_CMD_MAC is enabled
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
  2020-11-17 20:59 ` [PATCH RFC 01/20] config: Remove CONFIG_SYS_ID_EEPROM Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 02/20] mtd: Allow building nand_spl_simple w/o SPL_NAND_ECC Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 22:17   ` Daniel Schwierzeck
  2020-11-17 21:00 ` [PATCH RFC 04/20] mips: Don't access CP0_EBASE on JZ47XX Lubomir Rintel
                   ` (16 subsequent siblings)
  19 siblings, 1 reply; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

This allows us to enable CONFIG_ID_EEPROM to add a hook to read ethaddr
off a ROM without having to implement do_mac().

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 arch/arm/Kconfig                 | 19 +++++++++++++++++++
 arch/powerpc/cpu/mpc85xx/Kconfig | 17 +++++++++++++++++
 cmd/Kconfig                      |  3 +++
 cmd/Makefile                     |  2 +-
 4 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b2f7fcbd6ec..884e6f11365 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1245,6 +1245,7 @@ config TARGET_LS1088AQDS
 	select BOARD_LATE_INIT
 	select SUPPORT_SPL
 	select FSL_DDR_INTERACTIVE if !SD_BOOT
+	select CMD_MAC
 	help
 	  Support for NXP LS1088AQDS platform.
 	  The LS1088A Development System (QDS) is a high-performance
@@ -1263,6 +1264,7 @@ config TARGET_LS2080AQDS
 	imply SCSI_AHCI
 	select FSL_DDR_BIST
 	select FSL_DDR_INTERACTIVE if !SPL
+	select CMD_MAC
 	help
 	  Support for Freescale LS2080AQDS platform.
 	  The LS2080A Development System (QDS) is a high-performance
@@ -1279,6 +1281,7 @@ config TARGET_LS2080ARDB
 	select SUPPORT_SPL
 	select FSL_DDR_BIST
 	select FSL_DDR_INTERACTIVE if !SPL
+	select CMD_MAC
 	imply SCSI
 	imply SCSI_AHCI
 	help
@@ -1294,6 +1297,7 @@ config TARGET_LS2081ARDB
 	select ARMV8_MULTIENTRY
 	select BOARD_LATE_INIT
 	select SUPPORT_SPL
+	select CMD_MAC
 	help
 	  Support for Freescale LS2081ARDB platform.
 	  The LS2081A Reference design board (RDB) is a high-performance
@@ -1307,6 +1311,7 @@ config TARGET_LX2160ARDB
 	select ARMV8_MULTIENTRY
 	select ARCH_SUPPORT_TFABOOT
 	select BOARD_LATE_INIT
+	select CMD_MAC
 	help
 	  Support for NXP LX2160ARDB platform.
 	  The lx2160ardb (LX2160A Reference design board (RDB)
@@ -1320,6 +1325,7 @@ config TARGET_LX2160AQDS
 	select ARMV8_MULTIENTRY
 	select ARCH_SUPPORT_TFABOOT
 	select BOARD_LATE_INIT
+	select CMD_MAC
 	help
 	  Support for NXP LX2160AQDS platform.
 	  The lx2160aqds (LX2160A QorIQ Development System (QDS)
@@ -1373,6 +1379,7 @@ config TARGET_LS1012AQDS
 	select ARM64
 	select ARCH_SUPPORT_TFABOOT
 	select BOARD_LATE_INIT
+	select CMD_MAC
 	help
 	  Support for Freescale LS1012AQDS platform.
 	  The LS1012A Development System (QDS) is a high-performance
@@ -1438,6 +1445,7 @@ config TARGET_LS1028AQDS
 	select ARMV8_MULTIENTRY
 	select ARCH_SUPPORT_TFABOOT
 	select BOARD_LATE_INIT
+	select CMD_MAC
 	help
 	  Support for Freescale LS1028AQDS platform
 	  The LS1028A Development System (QDS) is a high-performance
@@ -1451,6 +1459,7 @@ config TARGET_LS1028ARDB
 	select ARMV8_MULTIENTRY
 	select ARCH_SUPPORT_TFABOOT
 	select BOARD_LATE_INIT
+	select CMD_MAC
 	help
 	  Support for Freescale LS1028ARDB platform
 	  The LS1028A Development System (RDB) is a high-performance
@@ -1466,6 +1475,7 @@ config TARGET_LS1088ARDB
 	select BOARD_LATE_INIT
 	select SUPPORT_SPL
 	select FSL_DDR_INTERACTIVE if !SD_BOOT
+	select CMD_MAC
 	help
 	  Support for NXP LS1088ARDB platform.
 	  The LS1088A Reference design board (RDB) is a high-performance
@@ -1487,6 +1497,7 @@ config TARGET_LS1021AQDS
 	select FSL_DDR_INTERACTIVE
 	select DM_SPI_FLASH if FSL_DSPI || FSL_QSPI
 	select SPI_FLASH_DATAFLASH if FSL_DSPI || FSL_QSPI
+	select CMD_MAC
 	imply SCSI
 
 config TARGET_LS1021ATWR
@@ -1501,6 +1512,7 @@ config TARGET_LS1021ATWR
 	select LS1_DEEP_SLEEP
 	select SUPPORT_SPL
 	select DM_SPI_FLASH if FSL_DSPI || FSL_QSPI
+	select CMD_MAC
 	imply SCSI
 
 config TARGET_LS1021ATSN
@@ -1514,6 +1526,7 @@ config TARGET_LS1021ATSN
 	select CPU_V7_HAS_VIRT
 	select LS1_DEEP_SLEEP
 	select SUPPORT_SPL
+	select CMD_MAC
 	imply SCSI
 
 config TARGET_LS1021AIOT
@@ -1526,6 +1539,7 @@ config TARGET_LS1021AIOT
 	select CPU_V7_HAS_VIRT
 	select SUPPORT_SPL
 	select DM_SPI_FLASH if FSL_DSPI || FSL_QSPI
+	select CMD_MAC
 	imply SCSI
 	help
 	  Support for Freescale LS1021AIOT platform.
@@ -1545,6 +1559,7 @@ config TARGET_LS1043AQDS
 	select FSL_DDR_INTERACTIVE if !SPL
 	select FSL_DSPI if !SPL_NO_DSPI
 	select DM_SPI_FLASH if FSL_DSPI
+	select CMD_MAC
 	imply SCSI
 	imply SCSI_AHCI
 	help
@@ -1561,6 +1576,7 @@ config TARGET_LS1043ARDB
 	select SUPPORT_SPL
 	select FSL_DSPI if !SPL_NO_DSPI
 	select DM_SPI_FLASH if FSL_DSPI
+	select CMD_MAC
 	help
 	  Support for Freescale LS1043ARDB platform.
 
@@ -1577,6 +1593,7 @@ config TARGET_LS1046AQDS
 	select FSL_DDR_BIST if !SPL
 	select FSL_DDR_INTERACTIVE  if !SPL
 	select FSL_DDR_INTERACTIVE if !SPL
+	select CMD_MAC
 	imply SCSI
 	help
 	  Support for Freescale LS1046AQDS platform.
@@ -1597,6 +1614,7 @@ config TARGET_LS1046ARDB
 	select SUPPORT_SPL
 	select FSL_DDR_BIST
 	select FSL_DDR_INTERACTIVE if !SPL
+	select CMD_MAC
 	imply SCSI
 	help
 	  Support for Freescale LS1046ARDB platform.
@@ -1613,6 +1631,7 @@ config TARGET_LS1046AFRWY
 	select BOARD_EARLY_INIT_F
 	select BOARD_LATE_INIT
 	select DM_SPI_FLASH if DM_SPI
+	select CMD_MAC
 	imply SCSI
 	help
 	  Support for Freescale LS1046AFRWY platform.
diff --git a/arch/powerpc/cpu/mpc85xx/Kconfig b/arch/powerpc/cpu/mpc85xx/Kconfig
index 54c7fd9522a..a1bbab64991 100644
--- a/arch/powerpc/cpu/mpc85xx/Kconfig
+++ b/arch/powerpc/cpu/mpc85xx/Kconfig
@@ -29,6 +29,7 @@ config TARGET_P3041DS
 	select PHYS_64BIT
 	select ARCH_P3041
 	select BOARD_LATE_INIT if CHAIN_OF_TRUST
+	select CMD_MAC
 	imply CMD_SATA
 	imply PANIC_HANG
 
@@ -37,6 +38,7 @@ config TARGET_P4080DS
 	select PHYS_64BIT
 	select ARCH_P4080
 	select BOARD_LATE_INIT if CHAIN_OF_TRUST
+	select CMD_MAC
 	imply CMD_SATA
 	imply PANIC_HANG
 
@@ -45,12 +47,14 @@ config TARGET_P5040DS
 	select PHYS_64BIT
 	select ARCH_P5040
 	select BOARD_LATE_INIT if CHAIN_OF_TRUST
+	select CMD_MAC
 	imply CMD_SATA
 	imply PANIC_HANG
 
 config TARGET_MPC8541CDS
 	bool "Support MPC8541CDS"
 	select ARCH_MPC8541
+	select CMD_MAC
 
 config TARGET_MPC8544DS
 	bool "Support MPC8544DS"
@@ -60,10 +64,12 @@ config TARGET_MPC8544DS
 config TARGET_MPC8548CDS
 	bool "Support MPC8548CDS"
 	select ARCH_MPC8548
+	select CMD_MAC
 
 config TARGET_MPC8555CDS
 	bool "Support MPC8555CDS"
 	select ARCH_MPC8555
+	select CMD_MAC
 
 config TARGET_MPC8568MDS
 	bool "Support MPC8568MDS"
@@ -72,12 +78,14 @@ config TARGET_MPC8568MDS
 config TARGET_MPC8569MDS
 	bool "Support MPC8569MDS"
 	select ARCH_MPC8569
+	select CMD_MAC
 
 config TARGET_MPC8572DS
 	bool "Support MPC8572DS"
 	select ARCH_MPC8572
 # Use DDR3 controller with DDR2 DIMMs on this board
 	select SYS_FSL_DDRC_GEN3
+	select CMD_MAC
 	imply SCSI
 	imply PANIC_HANG
 
@@ -97,6 +105,7 @@ config TARGET_P1010RDB_PB
 	select BOARD_LATE_INIT if CHAIN_OF_TRUST
 	select SUPPORT_SPL
 	select SUPPORT_TPL
+	select CMD_MAC
 	imply CMD_EEPROM
 	imply CMD_SATA
 	imply PANIC_HANG
@@ -133,6 +142,7 @@ config TARGET_P2041RDB
 	select ARCH_P2041
 	select BOARD_LATE_INIT if CHAIN_OF_TRUST
 	select PHYS_64BIT
+	select CMD_MAC
 	imply CMD_SATA
 	imply FSL_SATA
 
@@ -148,6 +158,7 @@ config TARGET_T1023RDB
 	select SUPPORT_SPL
 	select PHYS_64BIT
 	select FSL_DDR_INTERACTIVE
+	select CMD_MAC
 	imply CMD_EEPROM
 	imply PANIC_HANG
 
@@ -158,6 +169,7 @@ config TARGET_T1024RDB
 	select SUPPORT_SPL
 	select PHYS_64BIT
 	select FSL_DDR_INTERACTIVE
+	select CMD_MAC
 	imply CMD_EEPROM
 	imply PANIC_HANG
 
@@ -213,6 +225,7 @@ config TARGET_T2080QDS
 	select PHYS_64BIT
 	select FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
 	select FSL_DDR_INTERACTIVE
+	select CMD_MAC
 	imply CMD_SATA
 
 config TARGET_T2080RDB
@@ -221,6 +234,7 @@ config TARGET_T2080RDB
 	select BOARD_LATE_INIT if CHAIN_OF_TRUST
 	select SUPPORT_SPL
 	select PHYS_64BIT
+	select CMD_MAC
 	imply CMD_SATA
 	imply PANIC_HANG
 
@@ -231,6 +245,7 @@ config TARGET_T2081QDS
 	select PHYS_64BIT
 	select FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
 	select FSL_DDR_INTERACTIVE
+	select CMD_MAC
 
 config TARGET_T4160RDB
 	bool "Support T4160RDB"
@@ -280,12 +295,14 @@ config TARGET_CYRUS_P5020
 	bool "Support Varisys Cyrus P5020"
 	select ARCH_P5020
 	select PHYS_64BIT
+	select CMD_MAC
 	imply PANIC_HANG
 
 config TARGET_CYRUS_P5040
 	 bool "Support Varisys Cyrus P5040"
 	select ARCH_P5040
 	select PHYS_64BIT
+	select CMD_MAC
 	imply PANIC_HANG
 
 endchoice
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 1595de999b5..652e9cc4f88 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1696,6 +1696,9 @@ config CMD_LED
 	  with led on/off/togle/blink. Any LED drivers can be controlled with
 	  this command, e.g. led_gpio.
 
+config CMD_MAC
+	bool
+
 config CMD_DATE
 	bool "date"
 	default y if DM_RTC
diff --git a/cmd/Makefile b/cmd/Makefile
index dd86675bf2a..9d85217b544 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -88,7 +88,7 @@ obj-$(CONFIG_CMD_LICENSE) += license.o
 obj-y += load.o
 obj-$(CONFIG_CMD_LOG) += log.o
 obj-$(CONFIG_CMD_LSBLK) += lsblk.o
-obj-$(CONFIG_ID_EEPROM) += mac.o
+obj-$(CONFIG_CMD_MAC) += mac.o
 obj-$(CONFIG_CMD_MD5SUM) += md5sum.o
 obj-$(CONFIG_CMD_MEMORY) += mem.o
 obj-$(CONFIG_CMD_IO) += io.o
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 04/20] mips: Don't access CP0_EBASE on JZ47XX
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (2 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 03/20] cmd/mac: Don't build unless CONFIG_CMD_MAC is enabled Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 05/20] ns16550: Turn on the UME bit if on ARCH_JZ47XX Lubomir Rintel
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

On JZ4730 (and I guess all Ingenic/XBurst cores), the CP0 register 15
doesn't support a selector 1 or, for that matter, any selector and always
behaves as if the selector is zero.

We don't need it anyways, these SoCs have just a single processor core.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 arch/mips/cpu/start.S | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S
index d0c412236dd..1402fa3d176 100644
--- a/arch/mips/cpu/start.S
+++ b/arch/mips/cpu/start.S
@@ -136,6 +136,8 @@ reset:
 #ifdef CONFIG_ARCH_BMIPS
 1:	mfc0	t0, CP0_DIAGNOSTIC, 3
 	and	t0, t0, (1 << 31)
+#elif CONFIG_ARCH_JZ47XX
+1:	and	t0, t0, zero
 #else
 1:	mfc0	t0, CP0_EBASE
 	and	t0, t0, MIPS_EBASE_CPUNUM
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 05/20] ns16550: Turn on the UME bit if on ARCH_JZ47XX
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (3 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 04/20] mips: Don't access CP0_EBASE on JZ47XX Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 22:29   ` Daniel Schwierzeck
  2020-11-17 21:00 ` [PATCH RFC 06/20] clk: Add driver for Ingenic JZ4730 CGU Lubomir Rintel
                   ` (14 subsequent siblings)
  19 siblings, 1 reply; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

The jz47xx serial port is essentially a ns16550 with an extra bit that
needs to be turned on. The driver already takes care of it, but not in
the early debug config path.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/serial/ns16550.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 702109b23b6..0cf667c2731 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -326,6 +326,7 @@ static inline void _debug_uart_init(void)
 {
 	struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
 	int baud_divisor;
+	int fcr = UART_FCR_DEFVAL;
 
 	/*
 	 * We copy the code from above because it is already horribly messy.
@@ -335,9 +336,13 @@ static inline void _debug_uart_init(void)
 	 */
 	baud_divisor = ns16550_calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK,
 					    CONFIG_BAUDRATE);
+
+	if (IS_ENABLED(CONFIG_ARCH_JZ47XX))
+		fcr |= UART_FCR_UME;
+
 	serial_dout(&com_port->ier, CONFIG_SYS_NS16550_IER);
 	serial_dout(&com_port->mcr, UART_MCRVAL);
-	serial_dout(&com_port->fcr, UART_FCR_DEFVAL);
+	serial_dout(&com_port->fcr, fcr);
 
 	serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL);
 	serial_dout(&com_port->dll, baud_divisor & 0xff);
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 06/20] clk: Add driver for Ingenic JZ4730 CGU
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (4 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 05/20] ns16550: Turn on the UME bit if on ARCH_JZ47XX Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 07/20] timer-uclass: Tolerate failure to get clock rate in pre_probe Lubomir Rintel
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

A rather minimal driver for that reads back configured clock rates for
hardware we support.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/clk/Kconfig      |   8 +++
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-jz4730.c | 121 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 130 insertions(+)
 create mode 100644 drivers/clk/clk-jz4730.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 4dfbad7986b..a138c6ebcde 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -113,6 +113,14 @@ config CLK_HSDK
 	  Enable this to support the cgu clocks on Synopsys ARC HSDK and
 	  Synopsys ARC HSDK-4xD boards
 
+config CLK_JZ4730
+	bool "Enable clock driver for Ingenic JZ4730 cgu"
+	depends on CLK && SOC_JZ4730
+	default y
+	help
+	  This clock driver adds support for clock generators present on
+	  Ingenic JZ4730 SoC.
+
 config CLK_VERSAL
 	bool "Enable clock driver support for Versal"
 	depends on ARCH_VERSAL
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d1e295ac7c1..daad6333b36 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
 obj-$(CONFIG_CLK_EXYNOS) += exynos/
 obj-$(CONFIG_$(SPL_TPL_)CLK_INTEL) += intel/
 obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o
+obj-$(CONFIG_CLK_JZ4730) += clk-jz4730.o
 obj-$(CONFIG_CLK_K210) += kendryte/
 obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o
 obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o
diff --git a/drivers/clk/clk-jz4730.c b/drivers/clk/clk-jz4730.c
new file mode 100644
index 00000000000..332b1ea82d6
--- /dev/null
+++ b/drivers/clk/clk-jz4730.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4730 Clock Generation Unit driver.
+ *
+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+#include <dt-bindings/clock/jz4730-cgu.h>
+#include <common.h>
+#include <dm.h>
+#include <clk-uclass.h>
+#include <div64.h>
+#include <linux/bitops.h>
+#include <asm/io.h>
+
+#define CPM_CFCR	0x00
+#define CPM_PLCR1	0x10
+#define CPM_OCR		0x1c
+
+#define CPM_OCR_EXT_RTC_CLK	BIT(8)
+
+#define CPM_PLCR1_PLL1EN	BIT(8)
+
+#define CPM_CFCR_PFR_SHIFT	8
+
+#define CPM_PLCR1_PLL1FD_SHIFT	23
+#define CPM_PLCR1_PLL1FD_MASK	(0x1ff << CPM_PLCR1_PLL1FD_SHIFT)
+#define CPM_PLCR1_PLL1RD_SHIFT	18
+#define CPM_PLCR1_PLL1RD_MASK	(0x1f << CPM_PLCR1_PLL1RD_SHIFT)
+#define CPM_PLCR1_PLL1OD_SHIFT	16
+#define CPM_PLCR1_PLL1OD_MASK	(0x03 << CPM_PLCR1_PLL1OD_SHIFT)
+
+struct jz4730_cgu_priv {
+	void __iomem *base;
+	unsigned long ext_rate;
+};
+
+static inline unsigned int pdiv(u32 cfcr, u32 shift)
+{
+	static unsigned int pdiv_table[] = { 1, 2, 3, 4, 6, 8, 12, 16, 24, 32 };
+
+	return pdiv_table[cfcr >> shift & 0xf];
+}
+
+static inline unsigned long pll_rate(u32 plcr1, unsigned long ext_rate)
+{
+	unsigned long long rate;
+
+	rate = ext_rate;
+	rate *= ((plcr1 & CPM_PLCR1_PLL1FD_MASK) >> CPM_PLCR1_PLL1FD_SHIFT) + 2;
+	do_div(rate, ((plcr1 & CPM_PLCR1_PLL1RD_MASK) >> CPM_PLCR1_PLL1RD_SHIFT) + 2);
+
+	return rate;
+}
+
+static ulong jz4730_cgu_clk_get_rate(struct clk *clk)
+{
+	struct jz4730_cgu_priv *priv = dev_get_priv(clk->dev);
+	u32 cfcr, plcr1, ocr;
+
+	switch (clk->id) {
+	case JZ4730_CLK_PCLK:
+		plcr1 = readl(priv->base + CPM_PLCR1);
+		if (plcr1 & CPM_PLCR1_PLL1EN) {
+			cfcr = readl(priv->base + CPM_CFCR);
+			return pll_rate(plcr1, priv->ext_rate) /
+				pdiv(cfcr, CPM_CFCR_PFR_SHIFT);
+		}
+		return priv->ext_rate;
+	case JZ4730_CLK_WDT:
+		ocr = readl(priv->base + CPM_OCR);
+		if (ocr & CPM_OCR_EXT_RTC_CLK)
+			return -EINVAL;
+		return priv->ext_rate / 128;
+	case JZ4730_CLK_UART0:
+	case JZ4730_CLK_UART1:
+	case JZ4730_CLK_UART2:
+	case JZ4730_CLK_UART3:
+	case JZ4730_CLK_I2C:
+	case JZ4730_CLK_TCU:
+		return priv->ext_rate;
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct clk_ops jz4730_cgu_clk_ops = {
+	.get_rate = jz4730_cgu_clk_get_rate,
+};
+
+static int jz4730_cgu_clk_probe(struct udevice *dev)
+{
+	struct jz4730_cgu_priv *priv = dev_get_priv(dev);
+	struct clk clk;
+	int ret;
+
+	priv->base = dev_remap_addr(dev);
+	if (!priv->base)
+		return -EINVAL;
+
+	ret = clk_get_by_name(dev, "ext", &clk);
+	if (ret)
+		return ret;
+	priv->ext_rate = clk_get_rate(&clk);
+
+	return 0;
+}
+
+static const struct udevice_id jz4730_cgu_clk_of_match[] = {
+	{ .compatible = "ingenic,jz4730-cgu" },
+	{ },
+};
+
+U_BOOT_DRIVER(jz4730_cgu_clk) = {
+	.name = "jz4730-cgu",
+	.id = UCLASS_CLK,
+	.of_match = jz4730_cgu_clk_of_match,
+	.probe = jz4730_cgu_clk_probe,
+	.priv_auto_alloc_size = sizeof(struct jz4730_cgu_priv),
+	.ops = &jz4730_cgu_clk_ops,
+};
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 07/20] timer-uclass: Tolerate failure to get clock rate in pre_probe
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (5 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 06/20] clk: Add driver for Ingenic JZ4730 CGU Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 08/20] timer: Add Ingenic JZ4730 timer driver Lubomir Rintel
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

Pre-probe merely guesses that the first clock is the right one -- a
different one might actually be picked by probe(). In case it does not,
post_probe() already has a check that will fail.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/timer/timer-uclass.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c
index 62d0e860e80..f734fa8b405 100644
--- a/drivers/timer/timer-uclass.c
+++ b/drivers/timer/timer-uclass.c
@@ -61,9 +61,11 @@ static int timer_pre_probe(struct udevice *dev)
 	if (!err) {
 		ret = clk_get_rate(&timer_clk);
 		if (IS_ERR_VALUE(ret))
-			return ret;
-		uc_priv->clock_rate = ret;
-	} else {
+			err = ret;
+		else
+			uc_priv->clock_rate = ret;
+	}
+	if (err) {
 		uc_priv->clock_rate =
 			dev_read_u32_default(dev, "clock-frequency", 0);
 	}
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 08/20] timer: Add Ingenic JZ4730 timer driver
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (6 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 07/20] timer-uclass: Tolerate failure to get clock rate in pre_probe Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 09/20] mmc: Default to JZ47XX_MMC=y on ARCH_JZ47XX Lubomir Rintel
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

This adds support for a timer block on JZ4730 SoC.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/timer/Kconfig        |  8 ++++
 drivers/timer/Makefile       |  1 +
 drivers/timer/jz4730_timer.c | 83 ++++++++++++++++++++++++++++++++++++
 3 files changed, 92 insertions(+)
 create mode 100644 drivers/timer/jz4730_timer.c

diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 80743a25519..9d5a84c03ea 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -110,6 +110,14 @@ config DESIGNWARE_APB_TIMER
 	  Enables support for the Designware APB Timer driver. This timer is
 	  present on Altera SoCFPGA SoCs.
 
+config JZ4730_TIMER
+	bool "Ingenic JZ4730 timer support"
+	depends on TIMER
+	default y if SOC_JZ4730
+	help
+	  Select this to enable support for the timer found on
+	  devices based on the Ingenic JZ4730 SoC.
+
 config MPC83XX_TIMER
 	bool "MPC83xx timer support"
 	depends on TIMER
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index eb5c48cc6ce..67529c78e59 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o
 obj-$(CONFIG_ATMEL_PIT_TIMER) += atmel_pit_timer.o
 obj-$(CONFIG_CADENCE_TTC_TIMER)	+= cadence-ttc.o
 obj-$(CONFIG_DESIGNWARE_APB_TIMER)	+= dw-apb-timer.o
+obj-$(CONFIG_JZ4730_TIMER) += jz4730_timer.o
 obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o
 obj-$(CONFIG_NOMADIK_MTU_TIMER)	+= nomadik-mtu-timer.o
 obj-$(CONFIG_OMAP_TIMER)	+= omap-timer.o
diff --git a/drivers/timer/jz4730_timer.c b/drivers/timer/jz4730_timer.c
new file mode 100644
index 00000000000..d2c77a20993
--- /dev/null
+++ b/drivers/timer/jz4730_timer.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4730 Timer driver.
+ *
+ * Copyright (c) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+#include <common.h>
+#include <config.h>
+#include <clk.h>
+#include <dm.h>
+#include <timer.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+
+#define CHANNEL_ID  0
+
+#define OST_TER		(0x00)
+#define OST_TRDR(n)	(0x10 + ((n) * 0x20))
+#define OST_TCNT(n)	(0x14 + ((n) * 0x20))
+#define OST_TCSR(n)	(0x18 + ((n) * 0x20))
+#define OST_TCRB(n)	(0x1c + ((n) * 0x20))
+
+#define OST_TCSR_CKS_PCLK_256	0x0003
+
+struct jz4730_timer_priv {
+	void __iomem *base;
+};
+
+static u64 jz4730_timer_get_count(struct udevice *dev)
+{
+	struct jz4730_timer_priv *priv = dev_get_priv(dev);
+	u32 val = readl(priv->base + OST_TCNT(CHANNEL_ID));
+
+	return timer_conv_64(U32_MAX - val);
+}
+
+static int jz4730_timer_probe(struct udevice *dev)
+{
+	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct jz4730_timer_priv *priv = dev_get_priv(dev);
+	struct clk clk;
+	int ret;
+
+	priv->base = dev_remap_addr(dev);
+	if (!priv->base)
+		return -EINVAL;
+
+	ret = clk_get_by_name(dev, "pclk", &clk);
+	if (ret)
+		return ret;
+
+	uc_priv->clock_rate = clk_get_rate(&clk);
+	uc_priv->clock_rate /= 256;
+
+	writew(OST_TCSR_CKS_PCLK_256, priv->base + OST_TCSR(CHANNEL_ID));
+	writel(U32_MAX, priv->base + OST_TRDR(CHANNEL_ID));
+	writel(U32_MAX, priv->base + OST_TCNT(CHANNEL_ID));
+	writeb(BIT(CHANNEL_ID), priv->base + OST_TER);
+
+	return 0;
+}
+
+static const struct timer_ops jz4730_timer_ops = {
+	.get_count = jz4730_timer_get_count,
+};
+
+static const struct udevice_id jz4730_timer_ids[] = {
+	{ .compatible = "ingenic,jz4730-tcu" },
+	{ }
+};
+
+U_BOOT_DRIVER(jz4730_timer) = {
+	.name = "jz4730_timer",
+	.id = UCLASS_TIMER,
+	.of_match = jz4730_timer_ids,
+	.priv_auto_alloc_size = sizeof(struct jz4730_timer_priv),
+	.probe = jz4730_timer_probe,
+	.ops = &jz4730_timer_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 09/20] mmc: Default to JZ47XX_MMC=y on ARCH_JZ47XX
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (7 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 08/20] timer: Add Ingenic JZ4730 timer driver Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 10/20] mmc/jz_mmc: Add a JZ4740 compatible string Lubomir Rintel
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

It's basically certain we want this MMC driver if we have MMC support turned
on JZ47XX. A sane default here will keep the defconfig cleaner.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/mmc/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 14d79139864..4ad166a15ad 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -407,6 +407,7 @@ config MMC_BCM2835
 config JZ47XX_MMC
 	bool "Ingenic JZ47xx SD/MMC Host Controller support"
 	depends on ARCH_JZ47XX
+	default y
 	help
 	  This selects support for the SD Card Controller on Ingenic JZ47xx SoCs.
 
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 10/20] mmc/jz_mmc: Add a JZ4740 compatible string
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (8 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 09/20] mmc: Default to JZ47XX_MMC=y on ARCH_JZ47XX Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-18 13:56   ` Ezequiel Garcia
  2020-11-17 21:00 ` [PATCH RFC 11/20] mmc/jz_mmc: Support wp-gpio/cd-gpio Lubomir Rintel
                   ` (9 subsequent siblings)
  19 siblings, 1 reply; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

The driver doesn't use the jz4780's extra DMA channels and handles jz4740
just fine.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/mmc/jz_mmc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
index b33f0850738..d4b9d15ef2e 100644
--- a/drivers/mmc/jz_mmc.c
+++ b/drivers/mmc/jz_mmc.c
@@ -490,6 +490,7 @@ static int jz_mmc_probe(struct udevice *dev)
 }
 
 static const struct udevice_id jz_mmc_ids[] = {
+	{ .compatible = "ingenic,jz4740-mmc" },
 	{ .compatible = "ingenic,jz4780-mmc" },
 	{ }
 };
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 11/20] mmc/jz_mmc: Support wp-gpio/cd-gpio
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (9 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 10/20] mmc/jz_mmc: Add a JZ4740 compatible string Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 12/20] pinctrl: Add Ingenic JZ4730 pin control and GPIO driver Lubomir Rintel
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

This adds support for using GPIO lines for detecting Write-Protect and
Card-Detect status.

This way the driver can fail fast if there's no card inserted.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/mmc/jz_mmc.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
index d4b9d15ef2e..03fb506e571 100644
--- a/drivers/mmc/jz_mmc.c
+++ b/drivers/mmc/jz_mmc.c
@@ -9,6 +9,7 @@
 #include <common.h>
 #include <malloc.h>
 #include <mmc.h>
+#include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/unaligned.h>
 #include <errno.h>
@@ -130,6 +131,11 @@ struct jz_mmc_priv {
 #define JZ_MMC_BUS_WIDTH_4	0x2
 #define JZ_MMC_BUS_WIDTH_8	0x3
 #define JZ_MMC_SENT_INIT	BIT(2)
+
+#if CONFIG_IS_ENABLED(DM_GPIO)
+	struct gpio_desc gpio_wp;
+	struct gpio_desc gpio_cd;
+#endif
 };
 
 static int jz_mmc_clock_rate(void)
@@ -438,9 +444,33 @@ static int jz_mmc_dm_set_ios(struct udevice *dev)
 	return jz_mmc_set_ios(mmc, priv);
 };
 
+#if CONFIG_IS_ENABLED(DM_GPIO)
+static int jz_mmc_dm_get_cd(struct udevice *dev)
+{
+	struct jz_mmc_priv *priv = dev_get_priv(dev);
+
+	if (priv->gpio_cd.dev)
+		return dm_gpio_get_value(&priv->gpio_cd);
+	return -ENOSYS;
+}
+
+static int jz_mmc_dm_get_wp(struct udevice *dev)
+{
+	struct jz_mmc_priv *priv = dev_get_priv(dev);
+
+	if (priv->gpio_wp.dev)
+		dm_gpio_get_value(&priv->gpio_wp);
+	return -ENOSYS;
+}
+#endif
+
 static const struct dm_mmc_ops jz_msc_ops = {
 	.send_cmd	= jz_mmc_dm_send_cmd,
 	.set_ios	= jz_mmc_dm_set_ios,
+#if CONFIG_IS_ENABLED(DM_GPIO)
+	.get_cd		= jz_mmc_dm_get_cd,
+	.get_wp		= jz_mmc_dm_get_wp,
+#endif
 };
 
 static int jz_mmc_ofdata_to_platdata(struct udevice *dev)
@@ -484,6 +514,11 @@ static int jz_mmc_probe(struct udevice *dev)
 	struct jz_mmc_priv *priv = dev_get_priv(dev);
 	struct jz_mmc_plat *plat = dev_get_platdata(dev);
 
+#if CONFIG_IS_ENABLED(DM_GPIO)
+	gpio_request_by_name(dev, "wp-gpios", 0, &priv->gpio_wp, GPIOD_IS_IN);
+	gpio_request_by_name(dev, "cd-gpios", 0, &priv->gpio_cd, GPIOD_IS_IN);
+#endif
+
 	plat->mmc.priv = priv;
 	upriv->mmc = &plat->mmc;
 	return jz_mmc_core_init(&plat->mmc);
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 12/20] pinctrl: Add Ingenic JZ4730 pin control and GPIO driver
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (10 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 11/20] mmc/jz_mmc: Support wp-gpio/cd-gpio Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 22:39   ` Daniel Schwierzeck
  2020-11-17 21:00 ` [PATCH RFC 13/20] nand: Use correct prototype of board_nand_init() with SPL_NAND_SIMPLE Lubomir Rintel
                   ` (7 subsequent siblings)
  19 siblings, 1 reply; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

This is a fairly minimal driver for the pin controller on JZ4730 SoC.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/pinctrl/Kconfig          |   8 +
 drivers/pinctrl/Makefile         |   1 +
 drivers/pinctrl/pinctrl-jz4730.c | 346 +++++++++++++++++++++++++++++++
 3 files changed, 355 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-jz4730.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 77fb8511144..3bd9552d931 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -177,6 +177,14 @@ config PINCTRL_AT91PIO4
 	  This option is to enable the AT91 pinctrl driver for AT91 PIO4
 	  controller which is available on SAMA5D2 SoC.
 
+config PINCTRL_JZ4730
+	bool "Ingenic JZ4730 pinctrl driver"
+	depends on DM && SOC_JZ4730
+	default y
+	help
+	  This option is to enable the driver for pinctrl and GPIO
+	  controller which is available on Ingenic JZ4730 SoC.
+
 config PINCTRL_INTEL
 	bool "Standard Intel pin-control and pin-mux driver"
 	help
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 05b71f2f134..27d0ac7735f 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_$(SPL_)PINCTRL_GENERIC)	+= pinctrl-generic.o
 
 obj-$(CONFIG_PINCTRL_AT91)		+= pinctrl-at91.o
 obj-$(CONFIG_PINCTRL_AT91PIO4)		+= pinctrl-at91-pio4.o
+obj-$(CONFIG_PINCTRL_JZ4730)		+= pinctrl-jz4730.o
 obj-y					+= nxp/
 obj-$(CONFIG_$(SPL_)PINCTRL_ROCKCHIP)	+= rockchip/
 obj-$(CONFIG_ARCH_ASPEED) += aspeed/
diff --git a/drivers/pinctrl/pinctrl-jz4730.c b/drivers/pinctrl/pinctrl-jz4730.c
new file mode 100644
index 00000000000..1b69ecf17f1
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-jz4730.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4730 Pin control and GPIO driver.
+ *
+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/pinctrl.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+
+#define PINCTRL_DR(n)	(0x00 + (n) * 0x30)
+#define PINCTRL_DIR(n)	(0x04 + (n) * 0x30)
+#define PINCTRL_ODR(n)	(0x08 + (n) * 0x30)
+#define PINCTRL_PUR(n)	(0x0c + (n) * 0x30)
+#define PINCTRL_ALR(n)	(0x10 + (n) * 0x30)
+#define PINCTRL_AUR(n)	(0x14 + (n) * 0x30)
+#define PINCTRL_IDLR(n)	(0x18 + (n) * 0x30)
+#define PINCTRL_IDUR(n)	(0x1c + (n) * 0x30)
+#define PINCTRL_IER(n)	(0x20 + (n) * 0x30)
+#define PINCTRL_IMR(n)	(0x24 + (n) * 0x30)
+#define PINCTRL_FR(n)	(0x28 + (n) * 0x30)
+
+struct jz4730_pinctrl_priv {
+	void __iomem *base;
+};
+
+struct jz4730_gpio_priv {
+	unsigned int bank;
+};
+
+static int jz4730_gpio_get_value(struct udevice *dev, unsigned int offset)
+{
+	struct jz4730_gpio_priv *priv = dev_get_priv(dev);
+	struct jz4730_pinctrl_priv *pc_priv = dev_get_priv(dev->parent);
+
+	return !!(readl(pc_priv->base + PINCTRL_DR(priv->bank)) & BIT(offset));
+}
+
+static int jz4730_gpio_set_value(struct udevice *dev, unsigned int offset, int value)
+{
+	struct jz4730_gpio_priv *priv = dev_get_priv(dev);
+	struct jz4730_pinctrl_priv *pc_priv = dev_get_priv(dev->parent);
+	u32 gpdr = readl(pc_priv->base + PINCTRL_DR(priv->bank));
+
+	if (value)
+		gpdr |= BIT(offset);
+	else
+		gpdr &= ~BIT(offset);
+	writel(gpdr, pc_priv->base + PINCTRL_DR(priv->bank));
+
+	return 0;
+}
+
+static int jz4730_gpio_get_direction(struct udevice *dev, unsigned int offset)
+{
+	struct jz4730_gpio_priv *priv = dev_get_priv(dev);
+	struct jz4730_pinctrl_priv *pc_priv = dev_get_priv(dev->parent);
+
+	if (offset < 16) {
+		if (readl(pc_priv->base + PINCTRL_ALR(priv->bank)) & (3 << (offset * 2)))
+			return GPIOF_FUNC;
+	} else {
+		if (readl(pc_priv->base + PINCTRL_AUR(priv->bank)) & (3 << ((offset - 16) * 2)))
+			return GPIOF_FUNC;
+	}
+	if (readl(pc_priv->base + PINCTRL_DIR(priv->bank)) & BIT(offset))
+		return GPIOF_OUTPUT;
+
+	return GPIOF_INPUT;
+}
+
+static int jz4730_gpio_direction_input(struct udevice *dev, unsigned int offset)
+{
+	struct jz4730_gpio_priv *priv = dev_get_priv(dev);
+	struct jz4730_pinctrl_priv *pc_priv = dev_get_priv(dev->parent);
+
+	clrbits_32(pc_priv->base + PINCTRL_IER(priv->bank), BIT(offset));
+	clrbits_32(pc_priv->base + PINCTRL_DIR(priv->bank), BIT(offset));
+	if (offset < 16)
+		clrbits_32(pc_priv->base + PINCTRL_ALR(priv->bank), (3 << (offset << 1)));
+	else
+		clrbits_32(pc_priv->base + PINCTRL_AUR(priv->bank), (3 << ((offset - 16) << 1)));
+
+	return 0;
+}
+
+static int jz4730_gpio_direction_output(struct udevice *dev, unsigned int offset, int value)
+{
+	struct jz4730_gpio_priv *priv = dev_get_priv(dev);
+	struct jz4730_pinctrl_priv *pc_priv = dev_get_priv(dev->parent);
+
+	jz4730_gpio_set_value(dev, offset, value);
+
+	clrbits_32(pc_priv->base + PINCTRL_IER(priv->bank), BIT(offset));
+	setbits_32(pc_priv->base + PINCTRL_DIR(priv->bank), BIT(offset));
+	if (offset < 16)
+		clrbits_32(pc_priv->base + PINCTRL_ALR(priv->bank), (3 << (offset << 1)));
+	else
+		clrbits_32(pc_priv->base + PINCTRL_AUR(priv->bank), (3 << ((offset - 16) << 1)));
+
+	return 0;
+}
+
+static int jz4730_gpio_probe(struct udevice *dev)
+{
+	struct jz4730_gpio_priv *priv = dev_get_priv(dev);
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	int ret;
+
+	ret = ofnode_read_u32(dev_ofnode(dev), "reg", &priv->bank);
+	if (ret)
+		return ret;
+
+	uc_priv->bank_name  = strdup(dev->name);
+	uc_priv->gpio_count = 32;
+	return 0;
+}
+
+static const struct dm_gpio_ops jz4730_gpio_ops = {
+	.set_value = jz4730_gpio_set_value,
+	.get_value = jz4730_gpio_get_value,
+	.get_function = jz4730_gpio_get_direction,
+	.direction_input = jz4730_gpio_direction_input,
+	.direction_output = jz4730_gpio_direction_output,
+};
+
+static struct driver jz4730_gpio_driver = {
+	.name = "jz4730-gpio",
+	.id = UCLASS_GPIO,
+	.probe = jz4730_gpio_probe,
+	.priv_auto_alloc_size = sizeof(struct jz4730_gpio_priv),
+	.ops = &jz4730_gpio_ops,
+};
+
+static const char * const pin_names[] = {
+	"PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7",
+	"PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15",
+	"PA16", "PA17", "PA18", "PA19", "PA20", "PA21", "PA22", "PA23",
+	"PA24", "PA25", "PA26", "PA27", "PA28", "PA29", "PA30", "PA31",
+	"PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7",
+	"PB8", "PB9", "PB10", "PB11", "PB12", "PB13", "PB14", "PB15",
+	"PB16", "PB17", "PB18", "PB19", "PB20", "PB21", "PB22", "PB23",
+	"PB24", "PB25", "PB26", "PB27", "PB28", "PB29", "PB30", "PB31",
+	"PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6", "PC7",
+	"PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", "PC15",
+	"PC16", "PC17", "PC18", "PC19", "PC20", "PC21", "PC22", "PC23",
+	"PC24", "PC25", "PC26", "PC27", "PC28", "PC29", "PC30", "PC31",
+	"PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7",
+	"PD8", "PD9", "PD10", "PD11", "PD12", "PD13", "PD14", "PD15",
+	"PD16", "PD17", "PD18", "PD19", "PD20", "PD21", "PD22", "PD23",
+	"PD24", "PD25", "PD26", "PD27", "PD28", "PD29", "PD30", "PD31",
+};
+
+static int jz4730_pinctrl_get_pins_count(struct udevice *dev)
+{
+	return ARRAY_SIZE(pin_names);
+}
+
+static const char *jz4730_pinctrl_get_pin_name(struct udevice *dev,
+					       unsigned int selector)
+{
+	return pin_names[selector];
+}
+
+static const struct {
+	const char *name;
+	struct { u32 gpalr, gpaur; } mask[4];
+} groups[] = {
+	{ "lcd-16bit",		{ { 0, }, { 0x00000000, 0x00c0ffff }, { 0, }, { 0, 0, } } },
+	{ "lcd-16bit-tft",	{ { 0, }, { 0x00000000, 0xff000000 }, { 0, }, { 0, 0, } } },
+	{ "lcd-8bit",		{ { 0, }, { 0xffff0000, 0x003f0000 }, { 0, }, { 0, 0, } } },
+	{ "lcd-no-pins",	{ { 0, }, { 0, }, { 0, }, { 0, 0, } } },
+	{ "mac",		{ { 0, }, { 0, }, { 0, }, { 0, 0x03ffffff, } } },
+	{ "mmc-1bit",		{ { 0, }, { 0x0000f030, 0 }, { 0, }, { 0, 0, } } },
+	{ "mmc-4bit",		{ { 0, }, { 0x00000fc0, 0 }, { 0, }, { 0, 0, } } },
+	{ "nand-cs1",		{ { 0, }, { 0, }, { 0, 0x000000c0 }, { 0, 0, } } },
+	{ "nand-cs2",		{ { 0, }, { 0, }, { 0, 0x00000300 }, { 0, 0, } } },
+	{ "nand-cs3",		{ { 0, }, { 0, }, { 0, 0x00000c00 }, { 0, 0, } } },
+	{ "nand-cs4",		{ { 0, }, { 0, }, { 0, 0x00003000 }, { 0, 0, } } },
+	{ "nand-cs5",		{ { 0, }, { 0, }, { 0, 0x0000c000 }, { 0, 0, } } },
+	{ "pwm0",		{ { 0, }, { 0, }, { 0, 0x30000000 }, { 0, 0, } } },
+	{ "pwm1",		{ { 0, }, { 0, }, { 0, 0xc0000000 }, { 0, 0, } } },
+	{ "uart0-data",		{ { 0, }, { 0, }, { 0, }, { 0, 0xf0000000 } } },
+};
+
+static int jz4730_pinctrl_get_groups_count(struct udevice *dev)
+{
+	return ARRAY_SIZE(groups);
+}
+
+static const char *jz4730_pinctrl_get_group_name(struct udevice *dev,
+						 unsigned int group_selector)
+{
+	return groups[group_selector].name;
+}
+
+static const struct {
+	const char *name;
+	struct { u32 gpalr, gpaur; } val[4];
+} funcs[] = {
+	{ "lcd",	{ { 0, }, { 0x55550000, 0x556a5555 }, { 0, }, { 0, 0, } } },
+	{ "mac",	{ { 0, }, { 0, }, { 0, }, { 0, 0x01555555, } } },
+	{ "mmc",	{ { 0, }, { 0x00005550, 0 }, { 0, }, { 0, 0, } } },
+	{ "nand",	{ { 0, }, { 0, }, { 0, 0x000055c0 }, { 0, 0, } } },
+	{ "pwm0",	{ { 0, }, { 0, }, { 0, 0x10000000 }, { 0, 0, } } },
+	{ "pwm1",	{ { 0, }, { 0, }, { 0, 0x40000000 }, { 0, 0, } } },
+	{ "sleep",	{ { 0, }, { 0, }, { 0, 0 }, { 0, 0, } } },
+	{ "uart0",	{ { 0, }, { 0, }, { 0, }, { 0, 0x50000000 } } },
+};
+
+static int jz4730_pinctrl_get_funcs_count(struct udevice *dev)
+{
+	return ARRAY_SIZE(funcs);
+}
+
+static const char *jz4730_pinctrl_get_func_name(struct udevice *dev,
+						unsigned int func_selector)
+{
+	return funcs[func_selector].name;
+}
+
+static inline void update_bits(void __iomem *reg, u32 mask, u32 val)
+{
+	if (mask)
+		writel((readl(reg) & ~mask) | val, reg);
+}
+
+static int jz4730_pinctrl_set(struct udevice *dev,
+			      unsigned int selector,
+			      unsigned int func_selector)
+{
+	struct jz4730_pinctrl_priv *priv = dev_get_priv(dev);
+	int bank = selector / 32;
+	int pin = selector % 32;
+
+	if (pin < 16) {
+		update_bits(priv->base + PINCTRL_ALR(bank),
+			    funcs[func_selector].val[bank].gpalr,
+			    3 << (pin * 2));
+	} else {
+		update_bits(priv->base + PINCTRL_AUR(bank),
+			    funcs[func_selector].val[bank].gpaur,
+			    3 << ((pin - 16) * 2));
+	}
+
+	return 0;
+}
+
+static int jz4730_pinctrl_group_set(struct udevice *dev,
+				    unsigned int group_selector,
+				    unsigned int func_selector)
+{
+	struct jz4730_pinctrl_priv *priv = dev_get_priv(dev);
+	int bank;
+
+	for (bank = 0; bank < ARRAY_SIZE(groups[0].mask); bank++) {
+		update_bits(priv->base + PINCTRL_ALR(bank),
+			    groups[group_selector].mask[bank].gpalr,
+			    funcs[func_selector].val[bank].gpalr);
+		update_bits(priv->base + PINCTRL_AUR(bank),
+			    groups[group_selector].mask[bank].gpaur,
+			    funcs[func_selector].val[bank].gpaur);
+	}
+
+	return 0;
+}
+
+const int jz4730_pinctrl_get_pin_muxing(struct udevice *dev,
+					unsigned int selector,
+					char *buf, int size)
+{
+	struct jz4730_pinctrl_priv *priv = dev_get_priv(dev);
+	int bank = selector / 32;
+	int pin = selector % 32;
+
+	snprintf(buf, size, "%3d D%d DI%d OD%d PU%d A%d ID%d IE%d IM%d F%d",
+		 selector,
+		 (readl(priv->base + PINCTRL_DR(bank)) >> pin) & 1,
+		 (readl(priv->base + PINCTRL_DIR(bank)) >> pin) & 1,
+		 (readl(priv->base + PINCTRL_ODR(bank)) >> pin) & 1,
+		 (readl(priv->base + PINCTRL_PUR(bank)) >> pin) & 1,
+		 pin < 16
+			? (readl(priv->base + PINCTRL_ALR(bank)) >> pin * 2) & 3
+			: (readl(priv->base + PINCTRL_AUR(bank)) >> (pin - 16) * 2) & 3,
+		 pin < 16
+			? (readl(priv->base + PINCTRL_IDLR(bank)) >> pin * 2) & 3
+			: (readl(priv->base + PINCTRL_IDUR(bank)) >> (pin - 16) * 2) & 3,
+		 (readl(priv->base + PINCTRL_IER(bank)) >> pin) & 1,
+		 (readl(priv->base + PINCTRL_IMR(bank)) >> pin) & 1,
+		 (readl(priv->base + PINCTRL_FR(bank)) >> pin) & 1);
+
+	return 0;
+}
+
+const struct pinctrl_ops jz4730_pinctrl_ops  = {
+	.get_pins_count = jz4730_pinctrl_get_pins_count,
+	.get_pin_name = jz4730_pinctrl_get_pin_name,
+	.get_groups_count = jz4730_pinctrl_get_groups_count,
+	.get_group_name = jz4730_pinctrl_get_group_name,
+	.get_functions_count = jz4730_pinctrl_get_funcs_count,
+	.get_function_name = jz4730_pinctrl_get_func_name,
+	.pinmux_set = jz4730_pinctrl_set,
+	.pinmux_group_set = jz4730_pinctrl_group_set,
+	.set_state = pinctrl_generic_set_state,
+	.get_pin_muxing = jz4730_pinctrl_get_pin_muxing,
+};
+
+int jz4730_pinctrl_probe(struct udevice *dev)
+{
+	struct jz4730_pinctrl_priv *priv = dev_get_priv(dev);
+	ofnode node;
+
+	priv->base = dev_remap_addr(dev);
+	if (!priv->base)
+		return -EINVAL;
+
+	dev_for_each_subnode(node, dev) {
+		struct udevice *cdev;
+
+		if (!ofnode_read_bool(node, "gpio-controller"))
+			continue;
+
+		device_bind_ofnode(dev, &jz4730_gpio_driver, ofnode_get_name(node),
+				   priv, node, &cdev);
+	}
+
+	return 0;
+}
+
+static const struct udevice_id jz4730_pinctrl_of_match[] = {
+	{ .compatible = "ingenic,jz4730-pinctrl", },
+	{ }
+};
+
+U_BOOT_DRIVER(jz4730_pinctrl) = {
+	.name = "jz4730-pinctrl",
+	.id = UCLASS_PINCTRL,
+	.of_match = of_match_ptr(jz4730_pinctrl_of_match),
+	.probe = jz4730_pinctrl_probe,
+	.priv_auto_alloc_size = sizeof(struct jz4730_pinctrl_priv),
+	.ops = &jz4730_pinctrl_ops,
+};
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 13/20] nand: Use correct prototype of board_nand_init() with SPL_NAND_SIMPLE
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (11 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 12/20] pinctrl: Add Ingenic JZ4730 pin control and GPIO driver Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 14/20] nand/raw: Add Ingenic JZ4730 NAND flash driver Lubomir Rintel
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

nand_spl_simple.c machinery allways passes a nand_chip argument to
board_nand_init() even if the main u-boot proper uses the
SYS_NAND_SELF_INIT version.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 include/nand.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/nand.h b/include/nand.h
index 80dd6469bc0..cf3a5e91368 100644
--- a/include/nand.h
+++ b/include/nand.h
@@ -35,7 +35,7 @@ unsigned long nand_size(void);
 
 int nand_mtd_to_devnum(struct mtd_info *mtd);
 
-#ifdef CONFIG_SYS_NAND_SELF_INIT
+#if defined(CONFIG_SYS_NAND_SELF_INIT) && !CONFIG_IS_ENABLED(NAND_SIMPLE)
 void board_nand_init(void);
 int nand_register(int devnum, struct mtd_info *mtd);
 #else
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 14/20] nand/raw: Add Ingenic JZ4730 NAND flash driver
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (12 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 13/20] nand: Use correct prototype of board_nand_init() with SPL_NAND_SIMPLE Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 15/20] watchdog: Add Ingenic JZ4730 watchdog timer driver Lubomir Rintel
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

This adds driver for the NAND flash driver for JZ4730 SoC.

Can also be used in the NAND SPL that is too constrained (needs to fit in
4K) to be DT-driven.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/mtd/nand/raw/Kconfig       |  10 ++
 drivers/mtd/nand/raw/Makefile      |   1 +
 drivers/mtd/nand/raw/jz4730_nand.c | 212 +++++++++++++++++++++++++++++
 3 files changed, 223 insertions(+)
 create mode 100644 drivers/mtd/nand/raw/jz4730_nand.c

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 3cf3b14f05b..be6146a71f2 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -121,6 +121,16 @@ config NAND_DENALI_DT
 	  Enable the driver for NAND flash on platforms using a Denali NAND
 	  controller as a DT device.
 
+config NAND_JZ4730
+	bool "Support JZ4730 NAND controller"
+	select SYS_NAND_SELF_INIT
+	depends on DM_MTD && SOC_JZ4730
+	imply CMD_NAND
+	default y
+	help
+	  Enable this driver for NAND flash controllers available in
+	  Ingenic JZ4730 SoCs.
+
 config NAND_LPC32XX_SLC
 	bool "Support LPC32XX_SLC controller"
 	help
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index 24c51b6924a..8a4b18728eb 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
 obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o
 obj-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
 obj-$(CONFIG_NAND_FSMC) += fsmc_nand.o
+obj-$(CONFIG_NAND_JZ4730) += jz4730_nand.o
 obj-$(CONFIG_NAND_KB9202) += kb9202_nand.o
 obj-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
 obj-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
diff --git a/drivers/mtd/nand/raw/jz4730_nand.c b/drivers/mtd/nand/raw/jz4730_nand.c
new file mode 100644
index 00000000000..aa4631971fc
--- /dev/null
+++ b/drivers/mtd/nand/raw/jz4730_nand.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4730 NAND flash driver.
+ *
+ * Copyright (c) 2007 Ingenic Semiconductor Inc.
+ * Author: <jlwei@ingenic.cn>
+ *
+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+#include <asm/io.h>
+#include <common.h>
+#include <dm.h>
+#include <nand.h>
+
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/rawnand.h>
+
+#define EMC_SMCR3	0x1c
+#define EMC_NFCSR	0x50
+#define EMC_NFECC	0x54
+
+#define EMC_NFCSR_NFE	BIT(0)
+#define EMC_NFCSR_FCE	BIT(1)
+#define EMC_NFCSR_ECCE	BIT(2)
+#define EMC_NFCSR_ERST	BIT(3)
+#define EMC_NFCSR_RB	BIT(7)
+
+struct jz4730_nand_priv {
+	void __iomem *base;
+	struct nand_chip nand;
+};
+
+static inline void __iomem *mtd_to_base(struct mtd_info *mtd);
+
+static void jz4730_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, uint ctrl)
+{
+	struct nand_chip *nand = mtd_to_nand(mtd);
+	void __iomem *base = mtd_to_base(mtd);
+	unsigned long IO_ADDR_W;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		IO_ADDR_W = (unsigned long)nand->IO_ADDR_W;
+
+		if (ctrl & NAND_NCE)
+			setbits_32(base + EMC_NFCSR, EMC_NFCSR_FCE);
+		else
+			clrbits_32(base + EMC_NFCSR, EMC_NFCSR_FCE);
+
+		IO_ADDR_W &= ~(BIT(18) | BIT(19));
+		if (ctrl & NAND_CLE)
+			IO_ADDR_W |= BIT(18);
+		if (ctrl & NAND_ALE)
+			IO_ADDR_W |= BIT(19);
+
+		nand->IO_ADDR_W = (void *)IO_ADDR_W;
+	}
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, nand->IO_ADDR_W);
+}
+
+static int jz4730_nand_dev_ready(struct mtd_info *mtd)
+{
+	void __iomem *base = mtd_to_base(mtd);
+
+	return (readl(base + EMC_NFCSR) & EMC_NFCSR_RB) ? 1 : 0;
+}
+
+static void jz4730_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+	struct nand_chip *nand = mtd_to_nand(mtd);
+	unsigned long IO_ADDR_R = (unsigned long)nand->IO_ADDR_R;
+	unsigned long IO_ADDR_W = (unsigned long)nand->IO_ADDR_W;
+
+	if (chip == 0) {
+		IO_ADDR_R &= ~(BIT(16) | BIT(17));
+		IO_ADDR_W &= ~(BIT(16) | BIT(17));
+	} else if (chip == 1) {
+		IO_ADDR_R |= (BIT(16) | BIT(17));
+		IO_ADDR_W |= (BIT(16) | BIT(17));
+	}
+
+	nand->IO_ADDR_R = (void *)IO_ADDR_R;
+	nand->IO_ADDR_W = (void *)IO_ADDR_W;
+}
+
+static void jz4730_nand_ecc_hwctl(struct mtd_info *mtd, int mode)
+{
+	void __iomem *base = mtd_to_base(mtd);
+
+	setbits_32(base + EMC_NFCSR, EMC_NFCSR_ECCE | EMC_NFCSR_ERST);
+}
+
+static int jz4730_nand_ecc_calculate(struct mtd_info *mtd,
+				     const u_char *dat, u_char *ecc)
+{
+	void __iomem *base = mtd_to_base(mtd);
+	u32 val = readl(base + EMC_NFECC);
+
+	clrbits_32(base + EMC_NFCSR, EMC_NFCSR_ECCE);
+	val = readl(base + EMC_NFECC);
+	val = ~val | 0x00030000;
+
+	ecc[0] = val >> 8;
+	ecc[1] = val;
+	ecc[2] = val >> 16;
+
+	return 0;
+}
+
+void jz4730_nand_chip_init(struct nand_chip *nand)
+{
+	struct mtd_info *mtd = nand_to_mtd(nand);
+	void __iomem *base = mtd_to_base(mtd);
+
+	if (!IS_ENABLED(SPL_BUILD) || IS_ENABLED(SPL_NAND_ECC)) {
+		nand->ecc.mode = NAND_ECC_HW;
+		nand->ecc.hwctl = jz4730_nand_ecc_hwctl;
+		nand->ecc.calculate = jz4730_nand_ecc_calculate;
+		nand->ecc.correct = nand_correct_data;
+		nand->ecc.bytes = 3;
+	}
+
+	nand->cmd_ctrl = jz4730_nand_cmd_ctrl;
+	nand->dev_ready = jz4730_nand_dev_ready;
+	nand->select_chip = jz4730_nand_select_chip;
+	nand->IO_ADDR_R = (void __iomem *)CONFIG_SYS_NAND_BASE;
+	nand->IO_ADDR_W = (void __iomem *)CONFIG_SYS_NAND_BASE;
+	nand->chip_delay = 20;
+
+	/* Enable the NAND functionality. */
+	setbits_32(base + EMC_NFCSR, EMC_NFCSR_NFE);
+
+	/* Nobody knows what does this do. */
+	writel(0x06644400, base + EMC_SMCR3);
+}
+
+#if !defined(CONFIG_SPL_BUILD)
+
+static inline void __iomem *mtd_to_base(struct mtd_info *mtd)
+{
+	struct nand_chip *nand = mtd_to_nand(mtd);
+
+	return container_of(nand, struct jz4730_nand_priv, nand)->base;
+}
+
+static int jz4730_nand_probe(struct udevice *dev)
+{
+	struct jz4730_nand_priv *priv = dev_get_priv(dev);
+	struct nand_chip *nand = &priv->nand;
+	struct mtd_info *mtd = nand_to_mtd(nand);
+	ofnode node;
+	int ret;
+
+	priv->base = dev_remap_addr(dev->parent);
+	if (!priv->base)
+		return -EINVAL;
+
+	jz4730_nand_chip_init(nand);
+
+	ofnode_for_each_subnode(node, dev->node)
+		nand_set_flash_node(nand, node);
+
+	ret = nand_scan(mtd, CONFIG_SYS_NAND_MAX_CHIPS);
+	if (ret)
+		return ret;
+
+	return nand_register(0, mtd);
+}
+
+static const struct udevice_id jz4730_nand_dt_ids[] = {
+	{ .compatible = "ingenic,jz4730-nand", },
+	{ }
+};
+
+U_BOOT_DRIVER(jz4730_nand_dt) = {
+	.name = "jz4730-nand",
+	.id = UCLASS_MTD,
+	.of_match = jz4730_nand_dt_ids,
+	.probe = jz4730_nand_probe,
+	.priv_auto_alloc_size = sizeof(struct jz4730_nand_priv),
+};
+
+void board_nand_init(void)
+{
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_MTD,
+					  DM_GET_DRIVER(jz4730_nand_dt),
+					  &dev);
+	if (ret && ret != -ENODEV)
+		pr_err("Failed to initialize %s. (error %d)\n", dev->name, ret);
+}
+
+#else /* CONFIG_SPL_BUILD */
+
+static inline void __iomem *mtd_to_base(struct mtd_info *mtd)
+{
+	return (void __iomem *)KSEG1 + 0x13010000;
+}
+
+int board_nand_init(struct nand_chip *nand)
+{
+	jz4730_nand_chip_init(nand);
+	nand->read_buf = nand_read_buf;
+
+	return 0;
+}
+
+#endif /* CONFIG_SPL_BUILD */
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 15/20] watchdog: Add Ingenic JZ4730 watchdog timer driver
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (13 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 14/20] nand/raw: Add Ingenic JZ4730 NAND flash driver Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 16/20] net: Add Ingenic JZ4730 Ethernet driver Lubomir Rintel
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

This adds support for the watchdog timer on JZ4730 SoC.

Once started, the hardware can't be told to stop counting. It is
especially inconvenient given the stock kernel on Skytone Alpha 400
(a JZ4730-based laptop) won't poke the watchdog.

We nevertheless want to keep the driver around in order to be able to
reset the processor. For now, the driver uses a timeout of 0 to mean it
shouldn't set a timout, which should be good enough for the Alpha 400
boards. There's probaby a nicer solution.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/watchdog/Kconfig      |  8 ++++
 drivers/watchdog/Makefile     |  1 +
 drivers/watchdog/jz4730_wdt.c | 86 +++++++++++++++++++++++++++++++++++
 3 files changed, 95 insertions(+)
 create mode 100644 drivers/watchdog/jz4730_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 4532a40e458..ff81344b337 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -118,6 +118,14 @@ config WDT_CORTINA
 	  This driver support all CPU ISAs supported by Cortina
 	  Access CAxxxx SoCs.
 
+config WDT_JZ4730
+	bool "Ingenic JZ4730 watchdog timer support"
+	depends on WDT && SOC_JZ4730
+	default y
+	help
+	  Select this to enable watchdog timer, which can be found on
+	  Ingenic JZ4730 chips.
+
 config WDT_MPC8xx
 	bool "MPC8xx watchdog timer support"
 	depends on WDT && MPC8xx
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 01b8231f2bf..ca46befe29d 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o
 obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o
 obj-$(CONFIG_WDT_ORION) += orion_wdt.o
 obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
+obj-$(CONFIG_WDT_JZ4730) += jz4730_wdt.o
 obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
 obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
 obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
diff --git a/drivers/watchdog/jz4730_wdt.c b/drivers/watchdog/jz4730_wdt.c
new file mode 100644
index 00000000000..6a63f3cbb6f
--- /dev/null
+++ b/drivers/watchdog/jz4730_wdt.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4730 Watchdog Timer driver.
+ *
+ * Copyright (c) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <wdt.h>
+#include <div64.h>
+#include <linux/bitops.h>
+#include <asm/io.h>
+
+#define WDT_WTCSR	0x00
+#define WDT_WTCNT	0x04
+
+#define WDT_WTCSR_START BIT(4)
+
+struct jz4730_wdt_priv {
+	void __iomem *base;
+	unsigned long clk_rate;
+	u32 timeout;
+};
+
+static int jz4730_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
+{
+	struct jz4730_wdt_priv *priv = dev_get_priv(dev);
+	u64 timeout = timeout_ms * priv->clk_rate;
+
+	do_div(timeout, 1000);
+	priv->timeout = U32_MAX - max_t(u32, timeout, 32);
+	wdt_reset(dev);
+	if (timeout)
+		writeb(WDT_WTCSR_START, priv->base + WDT_WTCSR);
+
+	return 0;
+}
+
+static int jz4730_wdt_reset(struct udevice *dev)
+{
+	struct jz4730_wdt_priv *priv = dev_get_priv(dev);
+
+	writel(priv->timeout, priv->base + WDT_WTCNT);
+
+	return 0;
+}
+
+static const struct wdt_ops jz4730_wdt_ops = {
+	.start = jz4730_wdt_start,
+	.reset = jz4730_wdt_reset,
+};
+
+static int jz4730_wdt_probe(struct udevice *dev)
+{
+	struct jz4730_wdt_priv *priv = dev_get_priv(dev);
+	struct clk clk;
+	int ret;
+
+	priv->base = dev_remap_addr(dev);
+	if (!priv->base)
+		return -EINVAL;
+
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret)
+		return ret;
+
+	priv->clk_rate = clk_get_rate(&clk);
+
+	return 0;
+}
+
+static const struct udevice_id jz4730_wdt_ids[] = {
+	{ .compatible = "ingenic,jz4730-watchdog" },
+	{ }
+};
+
+U_BOOT_DRIVER(wdt_jz4730) = {
+	.name = "wdt_jz4730",
+	.id = UCLASS_WDT,
+	.of_match = jz4730_wdt_ids,
+	.ops = &jz4730_wdt_ops,
+	.priv_auto_alloc_size = sizeof(struct jz4730_wdt_priv),
+	.probe = jz4730_wdt_probe,
+};
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 16/20] net: Add Ingenic JZ4730 Ethernet driver
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (14 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 15/20] watchdog: Add Ingenic JZ4730 watchdog timer driver Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 17/20] mips: dts: Add Ingenic JZ4730 Lubomir Rintel
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

This adds support for Ethernet MAC block on Ingenic JZ4730 SoC.

Based on old Ingenic GPL code dump, but significantly cleaned up and
reworked (e.g. to plug into the MAC framework).

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/net/Kconfig      |  11 +
 drivers/net/Makefile     |   1 +
 drivers/net/jz4730_eth.c | 447 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 459 insertions(+)
 create mode 100644 drivers/net/jz4730_eth.c

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 3a5e0368805..41dd5951981 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -342,6 +342,17 @@ config FSLDMAFEC
 	  This driver supports the network interface units in the
 	  ColdFire family.
 
+
+config JZ4730_ETH
+        bool "Ingenic JZ4730 Ethernet Support"
+	depends on DM_ETH && SOC_JZ4730
+	select PHYLIB
+	select MII
+	default y
+	help
+	  This driver supports the network interface units in the
+	  Ingenic JZ4730 SoC.
+
 config KS8851_MLL
 	bool "Microchip KS8851-MLL controller driver"
 	help
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index e3bdda359dc..67297066bc6 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_FTGMAC100) += ftgmac100.o
 obj-$(CONFIG_FTMAC110) += ftmac110.o
 obj-$(CONFIG_FTMAC100) += ftmac100.o
 obj-$(CONFIG_GMAC_ROCKCHIP) += gmac_rockchip.o
+obj-$(CONFIG_JZ4730_ETH) += jz4730_eth.o
 obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
 obj-$(CONFIG_LAN91C96) += lan91c96.o
 obj-$(CONFIG_LPC32XX_ETH) += lpc32xx_eth.o
diff --git a/drivers/net/jz4730_eth.c b/drivers/net/jz4730_eth.c
new file mode 100644
index 00000000000..99b9b68a5a0
--- /dev/null
+++ b/drivers/net/jz4730_eth.c
@@ -0,0 +1,447 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4730 Ethernet MAC driver.
+ *
+ * Copyright (C) 2005 Ingenic Semiconductor <jlwei@ingenic.cn>
+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <malloc.h>
+#include <net.h>
+#include <phy.h>
+#include <eth_phy.h>
+#include <miiphy.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#define ETH_BMR		0x1000
+#define ETH_TPDR	0x1004
+#define ETH_RAR		0x100C
+#define ETH_TAR		0x1010
+#define ETH_SR		0x1014
+#define ETH_OMR		0x1018
+#define ETH_IER		0x101C
+#define ETH_MFCR	0x1020
+#define ETH_MCR		0x0000
+#define ETH_MAHR	0x0004
+#define ETH_MALR	0x0008
+#define ETH_HTHR	0x000C
+#define ETH_HTLR	0x0010
+#define ETH_MIAR	0x0014
+#define ETH_MIDR	0x0018
+
+/* Bus Mode Register (DMA_BMR) */
+#define BMR_SWR		0x00000001	/* Software Reset */
+
+#define DMA_BURST	4
+
+/* Operation Mode Register (DMA_OMR) */
+#define OMR_TTM		0x00400000	/* Transmit Threshold Mode */
+#define OMR_SF		0x00200000	/* Store and Forward */
+#define OMR_ST		0x00002000	/* Start/Stop Transmission Command */
+#define OMR_SR		0x00000002	/* Start/Stop Receive */
+
+/* Mac control	Register (MAC_MCR) */
+#define MCR_FDX		0x00100000	/* Full Duplex Mode */
+#define MCR_LCC		0x00001000	/* Late Collision control */
+#define MCR_DBF		0x00000800	/* Broadcast frame Disable */
+#define MCR_TE		0x00000008	/* Transmitter enable */
+#define MCR_RE		0x00000004	/* Receiver enable */
+
+/* Constants for the intr mask and intr status registers. (DMA_SIS and DMA_IER) */
+#define DMA_INT_FB	0x00002000	/* Fatal bus error */
+#define DMA_INT_RW	0x00000200	/* Receive watchdog timeout */
+#define DMA_INT_RS	0x00000100	/* Receive stop */
+#define DMA_INT_RU	0x00000080	/* Receive buffer unavailble */
+#define DMA_INT_RI	0x00000040	/* Receive interrupt */
+#define DMA_INT_TJ	0x00000008	/* Transmit jabber timeout */
+#define DMA_INT_TU	0x00000004	/* Transmit buffer unavailble */
+#define DMA_INT_TS	0x00000002	/* Transmit stop */
+#define DMA_INT_TI	0x00000001	/* Transmit interrupt */
+
+/* Receive Descriptor Bit Summary */
+#define R_OWN		0x80000000	/* Own Bit */
+#define RD_FL		0x3fff0000	/* Frame Length */
+#define RD_ES		0x00008000	/* Error Summary */
+
+#define RD_RER		0x02000000	/* Receive End Of Ring */
+#define RD_RCH		0x01000000	/* Second Address Chained */
+
+/* Transmit Descriptor Bit Summary */
+#define T_OWN		0x80000000	/* Own Bit */
+
+#define TD_LS		0x40000000	/* Last Segment */
+#define TD_FS		0x20000000	/* First Segment */
+#define TD_TER		0x02000000	/* Transmit End Of Ring */
+#define TD_TCH		0x01000000	/* Second Address Chained */
+
+#define MAX_WAIT 1000
+
+/* Tx and Rx Descriptor */
+struct jz4730_eth_desc {
+	u32 status;
+	u32 ctrl;
+	u32 addr;
+	u32 next;
+};
+
+#define NUM_TX_DESCS 4
+
+struct jz4730_eth_priv {
+	void __iomem *base;
+	struct mii_dev *bus;
+	struct phy_device *phy;
+
+	int next_rx;
+	int next_tx;
+
+	struct jz4730_eth_desc rx_desc[PKTBUFSRX];
+	struct jz4730_eth_desc tx_desc[NUM_TX_DESCS];
+};
+
+#define MII_CMD_ADDR(id, offset) (((id) << 11) | ((offset) << 6))
+#define MII_CMD_READ(id, offset) (MII_CMD_ADDR(id, offset))
+#define MII_CMD_WRITE(id, offset) (MII_CMD_ADDR(id, offset) | 0x2)
+
+static int jz4730_eth_mdio_read(struct mii_dev *bus, int addr,
+				int devad, int reg)
+{
+	struct jz4730_eth_priv *priv = bus->priv;
+	u32 mii_cmd = MII_CMD_READ(addr, reg);
+	int i;
+
+	writel(mii_cmd, priv->base + ETH_MIAR);
+
+	/* wait for completion */
+	for (i = 0; i < MAX_WAIT; i++) {
+		if (!(readl(priv->base + ETH_MIAR) & 0x1))
+			break;
+		udelay(1);
+	}
+
+	if (i == MAX_WAIT) {
+		printf("MII wait timeout\n");
+		return -EIO;
+	}
+
+	return readl(priv->base + ETH_MIDR) & 0x0000ffff;
+}
+
+static int jz4730_eth_mdio_write(struct mii_dev *bus, int addr,
+				 int devad, int reg, u16 value)
+{
+	struct jz4730_eth_priv *priv = bus->priv;
+	u32 mii_cmd = MII_CMD_WRITE(addr, reg);
+	int i;
+
+	writel(value, priv->base + ETH_MIDR);
+	writel(mii_cmd, priv->base + ETH_MIAR);
+
+	/* wait for completion */
+	for (i = 0; i < MAX_WAIT; i++) {
+		if (!(readl(priv->base + ETH_MIAR) & 0x1))
+			break;
+		udelay(1);
+	}
+
+	if (i == MAX_WAIT) {
+		printf("MII wait timeout\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int jz4730_eth_probe(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_platdata(dev);
+	struct jz4730_eth_priv *priv = dev_get_priv(dev);
+	int addr = eth_phy_get_addr(dev);
+	int ret;
+
+	priv->base = dev_remap_addr(dev);
+	if (!priv->base)
+		return -EINVAL;
+	pdata->iobase = (phys_addr_t)priv->base;
+
+	priv->bus = mdio_alloc();
+	if (!priv->bus)
+		return -ENOMEM;
+
+	priv->bus->read = jz4730_eth_mdio_read;
+	priv->bus->write = jz4730_eth_mdio_write;
+	priv->bus->priv = priv;
+	strcpy(priv->bus->name, "jz4730_eth");
+
+	ret = mdio_register(priv->bus);
+	if (ret)
+		goto free_mdio;
+
+	priv->phy = phy_connect(priv->bus, addr, dev, PHY_INTERFACE_MODE_MII);
+	if (!priv->phy) {
+		ret = -EIO;
+		goto unregister_mdio;
+	}
+
+	phy_config(priv->phy);
+
+	return 0;
+
+unregister_mdio:
+	mdio_unregister(priv->bus);
+free_mdio:
+	mdio_free(priv->bus);
+	return ret;
+}
+
+static int jz4730_eth_remove(struct udevice *dev)
+{
+	struct jz4730_eth_priv *priv = dev_get_priv(dev);
+
+	phy_shutdown(priv->phy);
+	free(priv->phy);
+	mdio_unregister(priv->bus);
+	mdio_free(priv->bus);
+
+	return 0;
+}
+
+static void config_mac(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_platdata(dev);
+	struct jz4730_eth_priv *priv = dev_get_priv(dev);
+	u32 omr, mcr;
+
+	/* Set MAC address */
+#define ea pdata->enetaddr
+	writel((ea[3] << 24) | (ea[2] << 16) | (ea[1] << 8) | ea[0], priv->base + ETH_MALR);
+	writel((ea[5] << 8) | ea[4], priv->base + ETH_MAHR);
+
+	writel(0, priv->base + ETH_HTLR);
+	writel(0, priv->base + ETH_HTHR);
+
+	/* Assert the MCR_PS bit in CSR */
+	if (priv->phy->speed == SPEED_100)
+		omr = OMR_SF;
+	else
+		omr = OMR_TTM | OMR_SF;
+
+	mcr = MCR_TE | MCR_RE | MCR_DBF | MCR_LCC;
+
+	if (priv->phy->duplex == DUPLEX_FULL)
+		mcr |= MCR_FDX;
+
+	/* Set the Operation Mode (OMR) and Mac Control (MCR) registers */
+	writel(omr, priv->base + ETH_OMR);
+	writel(mcr, priv->base + ETH_MCR);
+
+	/* Set the Programmable Burst Length (BMR.PBL, value 1 or 4 is validate) */
+	writel(DMA_BURST << 8, priv->base + ETH_BMR);
+
+	/* Reset csr8 */
+	readl(priv->base + ETH_MFCR); /* missed frams counter */
+}
+
+static int jz4730_eth_start(struct udevice *dev)
+{
+	struct jz4730_eth_priv *priv = dev_get_priv(dev);
+	int i;
+
+	/* Reset ethernet unit */
+	writel(readl(priv->base + ETH_BMR) | BMR_SWR, priv->base + ETH_BMR);
+
+	for (i = 0; i < MAX_WAIT; i++) {
+		if (!(readl(priv->base + ETH_BMR) & BMR_SWR))
+			break;
+		udelay(1);
+	}
+
+	if (i == MAX_WAIT) {
+		printf("Reset eth timeout\n");
+		return -EIO;
+	}
+
+	/* Disable interrupts: we don't use ethernet interrupts */
+	writel(0, priv->base + ETH_IER);
+
+	/* Configure PHY */
+	phy_startup(priv->phy);
+
+	/* Configure MAC */
+	config_mac(dev);
+
+	/* Setup the Rx&Tx descriptors */
+	for (i = 0; i < PKTBUFSRX; i++) {
+		priv->rx_desc[i].status = R_OWN;
+		priv->rx_desc[i].ctrl = PKTSIZE_ALIGN | RD_RCH;
+		priv->rx_desc[i].addr = virt_to_phys(net_rx_packets[i]);
+		priv->rx_desc[i].next = virt_to_phys(priv->rx_desc + i + 1);
+
+		flush_dcache_range((ulong)net_rx_packets[i],
+				   (ulong)net_rx_packets[i] + PKTSIZE_ALIGN);
+	}
+	priv->rx_desc[PKTBUFSRX - 1].next = virt_to_phys(priv->rx_desc);
+	priv->rx_desc[PKTBUFSRX - 1].ctrl |= RD_RER;
+
+	flush_dcache_range((ulong)priv->rx_desc,
+			   (ulong)priv->rx_desc + sizeof(priv->rx_desc));
+
+	for (i = 0; i < NUM_TX_DESCS; i++) {
+		priv->tx_desc[i].status = 0;
+		priv->tx_desc[i].ctrl  = TD_TCH;
+		priv->tx_desc[i].addr = 0;
+		priv->tx_desc[i].next = virt_to_phys(priv->tx_desc + i + 1);
+	}
+	priv->tx_desc[NUM_TX_DESCS - 1].next = virt_to_phys(priv->tx_desc);
+	priv->tx_desc[NUM_TX_DESCS - 1].ctrl |= TD_TER;
+
+	flush_dcache_range((ulong)priv->tx_desc,
+			   (ulong)priv->tx_desc + sizeof(priv->tx_desc));
+
+	writel(virt_to_phys(priv->rx_desc), priv->base + ETH_RAR);
+	writel(virt_to_phys(priv->tx_desc), priv->base + ETH_TAR);
+
+	priv->next_rx = 0;
+	priv->next_tx = 0;
+
+	/* Enable ETH */
+	writel(readl(priv->base + ETH_OMR) | OMR_ST | OMR_SR, priv->base + ETH_OMR);
+
+	return 0;
+}
+
+static int jz4730_eth_send(struct udevice *dev, void *packet, int length)
+{
+	struct jz4730_eth_priv *priv = dev_get_priv(dev);
+	struct jz4730_eth_desc *desc = &priv->tx_desc[priv->next_tx];
+	int i;
+
+	/* tx fifo should always be idle */
+	desc->addr = virt_to_phys(packet);
+	desc->ctrl |= TD_LS | TD_FS | length;
+	desc->status = T_OWN;
+
+	flush_dcache_range((ulong)packet, (ulong)packet + length);
+	flush_dcache_range((ulong)desc, (ulong)desc + sizeof(*desc));
+
+	/* Start the tx */
+	writel(1, priv->base + ETH_TPDR);
+
+	i = 0;
+	while (desc->status & T_OWN) {
+		if (i > MAX_WAIT) {
+			printf("ETH TX timeout\n");
+			break;
+		}
+		udelay(1);
+		i++;
+
+		flush_dcache_range((ulong)desc, (ulong)desc + sizeof(*desc));
+	}
+
+	writel(DMA_INT_TI | DMA_INT_TS | DMA_INT_TU |
+	       DMA_INT_TJ | DMA_INT_FB, priv->base + ETH_SR);
+
+	desc->status = 0;
+	desc->addr = 0;
+	desc->ctrl &= ~(TD_LS | TD_FS);
+
+	flush_dcache_range((ulong)desc, (ulong)desc + sizeof(*desc));
+
+	priv->next_tx++;
+	if (priv->next_tx >= NUM_TX_DESCS)
+		priv->next_tx = 0;
+
+	return 0;
+}
+
+static int jz4730_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+	struct jz4730_eth_priv *priv = dev_get_priv(dev);
+	struct jz4730_eth_desc *desc = &priv->rx_desc[priv->next_rx];
+	int length;
+	u32 status;
+
+	flush_dcache_range((ulong)desc, (ulong)desc + sizeof(*desc));
+
+	status = desc->status;
+
+	if (status & R_OWN) {
+		/* Nothing has been received */
+		return -EINVAL;
+	}
+
+	length = ((status & RD_FL) >> 16); /* with 4-byte CRC value */
+
+	if (status & RD_ES) {
+		printf("ETH RX error 0x%x\n", status);
+		return 0;
+	}
+
+	if (length < 4) {
+		printf("ETH RX buffer too short\n");
+		return 0;
+	}
+
+	flush_dcache_range((ulong)net_rx_packets[priv->next_rx],
+			   (ulong)net_rx_packets[priv->next_rx] + PKTSIZE_ALIGN);
+	*packetp = net_rx_packets[priv->next_rx];
+
+	return length - 4;
+}
+
+static int jz4730_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
+{
+	struct jz4730_eth_priv *priv = dev_get_priv(dev);
+	struct jz4730_eth_desc *desc = &priv->rx_desc[priv->next_rx];
+
+	/* Clear done bits */
+	writel(DMA_INT_RI | DMA_INT_RS | DMA_INT_RU |
+	       DMA_INT_RW | DMA_INT_FB, priv->base + ETH_SR);
+
+	desc->status = R_OWN;
+
+	flush_dcache_range((ulong)desc, (ulong)desc + sizeof(*desc));
+
+	priv->next_rx++;
+	if (priv->next_rx >= PKTBUFSRX)
+		priv->next_rx = 0;
+
+	return 0;
+}
+
+static void jz4730_eth_stop(struct udevice *dev)
+{
+	struct jz4730_eth_priv *priv = dev_get_priv(dev);
+
+	phy_shutdown(priv->phy);
+	writel(readl(priv->base + ETH_OMR) & ~(OMR_ST | OMR_SR), priv->base + ETH_OMR);
+}
+
+static const struct eth_ops jz4730_eth_ops = {
+	.start		= jz4730_eth_start,
+	.send		= jz4730_eth_send,
+	.recv		= jz4730_eth_recv,
+	.free_pkt	= jz4730_eth_free_pkt,
+	.stop		= jz4730_eth_stop,
+};
+
+static const struct udevice_id jz4730_eth_ids[] = {
+	{ .compatible = "ingenic,jz4730-ethernet" },
+	{ }
+};
+
+U_BOOT_DRIVER(jz4730_eth) = {
+	.name		= "jz4730_eth",
+	.id		= UCLASS_ETH,
+	.of_match	= jz4730_eth_ids,
+	.probe		= jz4730_eth_probe,
+	.remove		= jz4730_eth_remove,
+	.ops		= &jz4730_eth_ops,
+	.priv_auto_alloc_size = sizeof(struct jz4730_eth_priv),
+	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 17/20] mips: dts: Add Ingenic JZ4730
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (15 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 16/20] net: Add Ingenic JZ4730 Ethernet driver Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 18/20] mips/mach-jz47xx: Add Ingenic JZ4730 support Lubomir Rintel
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

This generally comes from a mipsbook400 Letux git repository [1], not
mainline. It seems to be the work of Paul Boddie and H. Nikolaus Schaller.

[1] https://git.goldelico.com/?p=letux-kernel.git;a=shortlog;h=refs/heads/letux/dt-mipsbook400

Some more things need to be addressed here:

1.) Linux upstream review of the bindings.
    The tree is generally very nice and complete and bindings look good,
    but an upstream review could still cut off some rough edges. In
    particular I think the gpio/pinctrl bindings don't seem to describe
    the hardware in a very useful way (GPIO split into multiple nodes for
    ports slaves to the pinctrl node).

2.) Missing copyright/license notices.
    Probably an oversignt.

3.) I've made some changes that I need to split out into separate patches
    for upstream and document.

Cc: Paul Boddie <paul@boddie.org.uk>
Cc: H. Nikolaus Schaller <hns@goldelico.com>
Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 arch/mips/dts/jz4730.dtsi              | 340 +++++++++++++++++++++++++
 include/dt-bindings/clock/jz4730-cgu.h |  47 ++++
 2 files changed, 387 insertions(+)
 create mode 100644 arch/mips/dts/jz4730.dtsi
 create mode 100644 include/dt-bindings/clock/jz4730-cgu.h

diff --git a/arch/mips/dts/jz4730.dtsi b/arch/mips/dts/jz4730.dtsi
new file mode 100644
index 00000000000..8a986587d9d
--- /dev/null
+++ b/arch/mips/dts/jz4730.dtsi
@@ -0,0 +1,340 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <dt-bindings/clock/jz4730-cgu.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ingenic,jz4730";
+
+	cpuintc: interrupt-controller {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	intc: interrupt-controller at 10001000 {
+		compatible = "ingenic,jz4730-intc";
+		reg = <0x10001000 0x14>;
+
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <2>;
+	};
+
+	ext: ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+	};
+
+	rtc: rtc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	msc16m: msc16m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <16000000>;
+	};
+
+	msc24m: msc24m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+
+	usb48m: usb48m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <48000000>;
+	};
+
+	cgu: jz4730-cgu at 10000000 {
+		compatible = "ingenic,jz4730-cgu";
+		reg = <0x10000000 0x100>;
+
+		clocks = <&ext>, <&rtc>, <&msc16m>, <&msc24m>, <&usb48m>;
+		clock-names = "ext", "rtc", "msc16m", "msc24m", "usb48m";
+
+		#clock-cells = <1>;
+	};
+
+	tcu: timer at 10002000 {
+		compatible = "ingenic,jz4730-tcu";
+		reg = <0x10002000 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x10002000 0x1000>;
+
+		#clock-cells = <1>;
+
+		clocks = <&cgu JZ4730_CLK_RTC>,
+			 <&cgu JZ4730_CLK_EXT>,
+			 <&cgu JZ4730_CLK_PCLK>,
+			 <&cgu JZ4730_CLK_TCU>;
+		clock-names = "rtc", "ext", "pclk", "tcu";
+
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <24 23 22>;
+	};
+
+	watchdog: watchdog at 10004000 {
+		compatible = "ingenic,jz4730-watchdog";
+		reg = <0x10004000 0x100>;
+
+		clocks = <&cgu JZ4730_CLK_WDT>;
+		clock_names = "wdt";
+	};
+
+	pwm: pwm at 10050000 {
+		compatible = "ingenic,jz4730-pwm";
+		reg = <0x10050000 0x2000>;
+
+		#pwm-cells = <2>;
+
+		clocks = <&ext>;
+		clock-names = "ext";
+	};
+
+	rtc_dev: rtc at 10003000 {
+		compatible = "ingenic,jz4740-rtc";
+		reg = <0x10003000 0x10>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <15>;
+
+		clocks = <&cgu JZ4730_CLK_RTC>;
+		clock-names = "rtc";
+	};
+
+	pinctrl: pin-controller at 10010000 {
+		compatible = "ingenic,jz4730-pinctrl";
+		reg = <0x10010000 0x400>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		gpa: gpio at 0 {
+			compatible = "ingenic,jz4730-gpio";
+			reg = <0>;
+
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 0 32>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <28>;
+		};
+
+		gpb: gpio at 1 {
+			compatible = "ingenic,jz4730-gpio";
+			reg = <1>;
+
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 32 32>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <27>;
+		};
+
+		gpc: gpio at 2 {
+			compatible = "ingenic,jz4730-gpio";
+			reg = <2>;
+
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 64 32>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <26>;
+		};
+
+		gpd: gpio at 3 {
+			compatible = "ingenic,jz4730-gpio";
+			reg = <3>;
+
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 96 32>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <25>;
+		};
+	};
+
+	i2s: i2s {
+		compatible = "ingenic,jt4730-dai";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	i2c: i2c at 10042000 {
+		compatible = "ingenic,jz4730-i2c";
+		reg = <0x10042000 0x10>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <1>;
+
+		clocks = <&cgu JZ4730_CLK_PLL>;
+		clock-names = "i2c";
+
+		clock-frequency = <100000>;
+	};
+
+	mmc: mmc at 10021000 {
+		compatible = "ingenic,jz4740-mmc";
+		reg = <0x10021000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <14>;
+
+		clocks = <&cgu JZ4730_CLK_MMC>;
+		clock-names = "mmc";
+	};
+
+	uart0: serial at 10030000 {
+		compatible = "ingenic,jz4740-uart", "ingenic,jz4780-uart";
+		reg = <0x10030000 0x100>;
+
+		reg-shift = <2>;
+		fifo-size = <16>;
+		tx-threshold = <8>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <9>;
+
+		clocks = <&ext>, <&cgu JZ4730_CLK_UART0>;
+		clock-names = "baud", "module";
+	};
+
+	uart1: serial at 10031000 {
+		compatible = "ingenic,jz4740-uart", "ingenic,jz4780-uart";
+		reg = <0x10031000 0x100>;
+
+		reg-shift = <2>;
+		fifo-size = <16>;
+		tx-threshold = <8>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <8>;
+
+		clocks = <&ext>, <&cgu JZ4730_CLK_UART1>;
+		clock-names = "baud", "module";
+	};
+
+	uart2: serial at 10032000 {
+		compatible = "ingenic,jz4740-uart", "ingenic,jz4780-uart";
+		reg = <0x10032000 0x100>;
+
+		reg-shift = <2>;
+		fifo-size = <16>;
+		tx-threshold = <8>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <7>;
+
+		clocks = <&ext>, <&cgu JZ4730_CLK_UART2>;
+		clock-names = "baud", "module";
+	};
+
+	uart3: serial at 10033000 {
+		compatible = "ingenic,jz4740-uart", "ingenic,jz4780-uart";
+		reg = <0x10033000 0x100>;
+
+		reg-shift = <2>;
+		fifo-size = <16>;
+		tx-threshold = <8>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <6>;
+
+		clocks = <&ext>, <&cgu JZ4730_CLK_UART3>;
+		clock-names = "baud", "module";
+	};
+
+	dma: dma at 10020000 {
+		compatible = "ingenic,jz4730-dma";
+		reg = <0x10020000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <21>;
+
+		clocks = <&cgu JZ4730_CLK_DMA>;
+		clock-names = "dma";
+
+		#dma-cells = <1>;
+		dma-channels = <6>;
+	};
+
+	emc: memory-controller at 13010000 {
+		#address-cells = <0>;
+		#size-cells = <0>;
+		compatible = "ingenic,jz4730-emc", "simple-mfd";
+		reg = <0x13010000 0xf000>;
+
+		nand: nand-controller {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "ingenic,jz4730-nand";
+		};
+	};
+
+	uhc: uhc at 13030000 {
+		compatible = "ingenic,jz4740-ohci", "generic-ohci";
+		reg = <0x13030000 0x1000>;
+
+		clocks = <&cgu JZ4730_CLK_UHC>;
+		assigned-clocks = <&cgu JZ4730_CLK_UHC>;
+		assigned-clock-rates = <48000000>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <13>;
+
+		status = "disabled";
+	};
+
+	ethernet: ethernet at 13100000 {
+		compatible = "ingenic,jz4730-ethernet";
+		reg = <0x13100000 0x1000>;
+
+		mdio: mdio {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
+	lcd: lcd at 10050000 {
+		compatible = "ingenic,jz4740-lcd";
+		reg = <0x10050000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <30>;
+
+		clocks = <&cgu JZ4730_CLK_LCD>, <&cgu JZ4730_CLK_LCD_PCLK>;
+		clock-names = "lcd", "lcd_pclk";
+	};
+};
diff --git a/include/dt-bindings/clock/jz4730-cgu.h b/include/dt-bindings/clock/jz4730-cgu.h
new file mode 100644
index 00000000000..2dbaca52332
--- /dev/null
+++ b/include/dt-bindings/clock/jz4730-cgu.h
@@ -0,0 +1,47 @@
+/*
+ * This header provides clock numbers for the ingenic,jz4730-cgu DT binding.
+ *
+ * They are roughly ordered as:
+ *   - external clocks
+ *   - PLLs
+ *   - muxes/dividers
+ *   - gates in order of their bit in the MSCR* registers
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4730_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4730_CGU_H__
+
+#define JZ4730_CLK_EXT		0
+#define JZ4730_CLK_RTC		1
+#define JZ4730_CLK_MSC16M	2
+#define JZ4730_CLK_MSC24M	3
+#define JZ4730_CLK_USB48M	4
+#define JZ4730_CLK_PLL		5
+#define JZ4730_CLK_PLL_HALF	6
+#define JZ4730_CLK_CCLK_PLL	7
+#define JZ4730_CLK_CCLK		8
+#define JZ4730_CLK_HCLK_PLL	9
+#define JZ4730_CLK_HCLK		10
+#define JZ4730_CLK_PCLK_PLL	11
+#define JZ4730_CLK_PCLK		12
+#define JZ4730_CLK_MCLK_PLL	13
+#define JZ4730_CLK_MCLK		14
+#define JZ4730_CLK_LCD_PLL	15
+#define JZ4730_CLK_LCD		16
+#define JZ4730_CLK_LCD_PCLK	17
+#define JZ4730_CLK_I2S		18
+#define JZ4730_CLK_SPI		19
+#define JZ4730_CLK_DMA		20
+#define JZ4730_CLK_MMC		21
+#define JZ4730_CLK_UHC_IN	22
+#define JZ4730_CLK_UHC		23
+#define JZ4730_CLK_UART0	24
+#define JZ4730_CLK_UART1	25
+#define JZ4730_CLK_UART2	26
+#define JZ4730_CLK_UART3	27
+#define JZ4730_CLK_I2C		28
+#define JZ4730_CLK_TCU		29
+#define JZ4730_CLK_EXT_128	30
+#define JZ4730_CLK_WDT		31
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4730_CGU_H__ */
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 18/20] mips/mach-jz47xx: Add Ingenic JZ4730 support
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (16 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 17/20] mips: dts: Add Ingenic JZ4730 Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 19/20] mips: dts: Add Skytone Alpha 400 Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 20/20] board: " Lubomir Rintel
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

This adds support for the Ingenic JZ4730 SoC. There's not much more than
the build machinery and SPL stage because the main stage is entirely DT
driven.

The SPL is fairly unsophisticated since it has to fit into 4096 bytes. The
serial support didn't fit, and the pinmux and PLL init duplicates some
functionality of full drivers for space reasons. A regular NAND flash
driver is used though.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 arch/mips/mach-jz47xx/Kconfig                |  39 +++
 arch/mips/mach-jz47xx/Makefile               |   2 +
 arch/mips/mach-jz47xx/jz4730/Kconfig         |  87 ++++++
 arch/mips/mach-jz47xx/jz4730/Makefile        |   3 +
 arch/mips/mach-jz47xx/jz4730/lowlevel_init.S |  37 +++
 arch/mips/mach-jz47xx/jz4730/spl.c           | 293 +++++++++++++++++++
 6 files changed, 461 insertions(+)
 create mode 100644 arch/mips/mach-jz47xx/jz4730/Kconfig
 create mode 100644 arch/mips/mach-jz47xx/jz4730/Makefile
 create mode 100644 arch/mips/mach-jz47xx/jz4730/lowlevel_init.S
 create mode 100644 arch/mips/mach-jz47xx/jz4730/spl.c

diff --git a/arch/mips/mach-jz47xx/Kconfig b/arch/mips/mach-jz47xx/Kconfig
index dcaac016286..6fba38c7363 100644
--- a/arch/mips/mach-jz47xx/Kconfig
+++ b/arch/mips/mach-jz47xx/Kconfig
@@ -4,6 +4,41 @@ menu "Ingenic JZ47xx platforms"
 config SYS_SOC
 	default "jz47xx"
 
+config SPL_TEXT_BASE
+	default 0x80000000 if ARCH_JZ47XX
+
+config SYS_TEXT_BASE
+	default 0x80100000 if ARCH_JZ47XX
+
+config SOC_JZ4730
+	bool
+	select MIPS_INIT_STACK_IN_SRAM
+	select SUPPORTS_CPU_MIPS32_R1
+	select SUPPORTS_LITTLE_ENDIAN
+	select SYS_RELOC_GD_ENV_ADDR
+	select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL
+	select SPL_LIBCOMMON_SUPPORT if SPL
+	select SPL_LIBGENERIC_SUPPORT if SPL
+	select SPL_LOADER_SUPPORT if SPL
+	imply CLK
+	imply CMD_DM
+	imply DM_GPIO
+	imply DM_MMC
+	imply DM_MTD
+	imply DM_SERIAL
+	imply FIT
+	imply MMC
+	imply MTD
+	imply MTD_RAW_NAND
+	imply PINCTRL
+	imply SPL
+	imply SYS_NS16550
+	imply SYSRESET
+	imply SYSRESET_WATCHDOG
+	imply TIMER
+	help
+	  Support for Ingenic JZ4730 family SoCs.
+
 config SOC_JZ4780
 	bool
 	select SUPPORTS_LITTLE_ENDIAN
@@ -21,6 +56,10 @@ config TARGET_JZ4780_CI20
 
 endchoice
 
+source "arch/mips/mach-jz47xx/jz4730/Kconfig"
+
+source "board/skytone/alpha400/Kconfig"
+
 source "board/imgtec/ci20/Kconfig"
 
 endmenu
diff --git a/arch/mips/mach-jz47xx/Makefile b/arch/mips/mach-jz47xx/Makefile
index dbb8229f785..9c57577440d 100644
--- a/arch/mips/mach-jz47xx/Makefile
+++ b/arch/mips/mach-jz47xx/Makefile
@@ -2,4 +2,6 @@
 
 extra-$(CONFIG_SPL_BUILD)	:= start.o
 
+obj-$(CONFIG_SOC_JZ4730)	+= jz4730/
+
 obj-$(CONFIG_SOC_JZ4780)	+= jz4780/
diff --git a/arch/mips/mach-jz47xx/jz4730/Kconfig b/arch/mips/mach-jz47xx/jz4730/Kconfig
new file mode 100644
index 00000000000..392903d208c
--- /dev/null
+++ b/arch/mips/mach-jz47xx/jz4730/Kconfig
@@ -0,0 +1,87 @@
+if SOC_JZ4730
+
+config SYS_DCACHE_SIZE
+	default 16384
+
+config SYS_DCACHE_LINE_SIZE
+	default 32
+
+config SYS_ICACHE_SIZE
+	default 16384
+
+config SYS_ICACHE_LINE_SIZE
+	default 32
+
+config SYS_MALLOC_F_LEN
+	default 0x1000
+
+config SPL_SIZE_LIMIT
+	default 4096
+
+config MIPS_CACHE_SETUP
+	default n
+
+config MIPS_CACHE_DISABLE
+	default n
+
+config JZ4730_SDRAM_BANK_SIZE
+	int
+	help
+	  Megabytes per bank.
+
+config JZ4730_SDRAM_ROW
+	int
+	help
+	  Row address.
+
+config JZ4730_SDRAM_COL
+	int
+	help
+	  Column address.
+
+config JZ4730_SDRAM_BANKS_PER_CHIP
+	int
+	help
+	  Banks per chip.
+
+config JZ4730_SDRAM_WIDTH
+	int
+	help
+	  Data bus width.
+
+config JZ4730_SDRAM_CAS
+	int
+	help
+	  CAS latency: 2 or 3.
+
+config JZ4730_SDRAM_TRAS
+	int
+	help
+	  RAS# Active Time.
+
+config JZ4730_SDRAM_RCD
+	int
+	help
+	  RAS# to CAS# Delay.
+
+config JZ4730_SDRAM_TPC
+	int
+	help
+	  RAS# Precharge Time.
+
+config JZ4730_SDRAM_TRW
+	int
+	help
+	  Write Latency Time.
+
+config JZ4730_SDRAM_TREF
+	int
+	help
+	  Refresh period: 8192 refresh cycles/64ms.
+
+config JZ4730_SDRAM_CKS
+	int
+	help
+	  CKO Divider.
+
+endif
diff --git a/arch/mips/mach-jz47xx/jz4730/Makefile b/arch/mips/mach-jz47xx/jz4730/Makefile
new file mode 100644
index 00000000000..9a979fa0550
--- /dev/null
+++ b/arch/mips/mach-jz47xx/jz4730/Makefile
@@ -0,0 +1,3 @@
+obj-y += lowlevel_init.o
+
+obj-$(CONFIG_SPL_BUILD) += spl.o
diff --git a/arch/mips/mach-jz47xx/jz4730/lowlevel_init.S b/arch/mips/mach-jz47xx/jz4730/lowlevel_init.S
new file mode 100644
index 00000000000..fa7bfe89a3c
--- /dev/null
+++ b/arch/mips/mach-jz47xx/jz4730/lowlevel_init.S
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ *
+ * Derived from work that's Copyright (c) 2003
+ * Wolfgang Denk <wd@denx.de>
+ */
+
+#include <config.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/asm.h>
+
+LEAF(lowlevel_init)
+
+        /* Invalidate BTB */
+        mfc0    t0, CP0_CONFIG, 7
+        nop
+        ori     t0, 2
+        mtc0    t0, CP0_CONFIG, 7
+        nop
+
+        /*
+         * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1
+         */
+        li      t0, 0x0040FC04
+        mtc0    t0, CP0_STATUS
+
+        /* CAUSE register */
+        /* IV=1, use the specical interrupt vector (0x200) */
+        li      t1, 0x00800000
+        mtc0    t1, CP0_CAUSE
+
+        jr      ra
+         nop
+
+	END(lowlevel_init)
diff --git a/arch/mips/mach-jz47xx/jz4730/spl.c b/arch/mips/mach-jz47xx/jz4730/spl.c
new file mode 100644
index 00000000000..ea823e00f11
--- /dev/null
+++ b/arch/mips/mach-jz47xx/jz4730/spl.c
@@ -0,0 +1,293 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4730 Secondary Program Load.
+ *
+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ *
+ * Based on code that's (C) Copyright 2006
+ * Stefan Roese, DENX Software Engineering, sr at denx.de.
+ */
+
+#include <asm/io.h>
+#include <asm/sections.h>
+#include <common.h>
+#include <cpu_func.h>
+#include <hang.h>
+#include <init.h>
+#include <linux/bitops.h>
+#include <spl.h>
+
+#define C0_CONFIG7_BTBV			BIT(1)
+
+static void early_init(void)
+{
+	/*
+	 * Enable and clear the branch target buffer
+	 */
+	write_c0_config7(read_c0_config7() | C0_CONFIG7_BTBV);
+
+	/*
+	 * Clear the BSS
+	 */
+	memset(__bss_start, 0, (char *)&__bss_end - __bss_start);
+}
+
+#define EMC_BASE			(void __iomem *)0xb3010000
+#define EMC_BCR				0x00
+#define EMC_DMCR			0x80
+#define EMC_RTCSR			0x84
+#define EMC_RTCNT			0x88
+#define EMC_RTCOR			0x8c
+#define EMC_DMAR1			0x90
+#define EMC_DMAR2			0x94
+
+#define EMC_BCR_BRE			BIT(1)
+
+#define EMC_DMCR_BW_SHIFT		31
+#define EMC_DMCR_CA_SHIFT		26
+#define EMC_DMCR_RFSH			BIT(24)
+#define EMC_DMCR_MRSET			BIT(23)
+#define EMC_DMCR_RA_SHIFT		20
+#define EMC_DMCR_BA_SHIFT		19
+#define EMC_DMCR_EPIN			BIT(17)
+#define EMC_DMCR_TRAS_SHIFT		13
+#define EMC_DMCR_RCD_SHIFT		11
+#define EMC_DMCR_TPC_SHIFT		8
+#define EMC_DMCR_TRWL_SHIFT		5
+#define EMC_DMCR_TRC_SHIFT		2
+#define EMC_DMCR_TCL_SHIFT		0
+
+#define EMC_RTCSR_CKS_SHIFT		0
+
+#define EMC_SDMR_CAS_SHIFT		4
+#define EMC_SDMR_BL_SHIFT		0
+
+#define EMC_SDMR0			0xa000
+#define EMC_SDMR1			0xb000
+
+void sdram_init(void)
+{
+	register unsigned int dmcr, sdmode, tmp, ns;
+
+	/*
+	 * Enable SPLIT
+	 */
+	writel(EMC_BCR_BRE, EMC_BASE + EMC_BCR);
+
+	writew(0 << EMC_RTCSR_CKS_SHIFT, EMC_BASE + EMC_RTCSR);
+	writew(0, EMC_BASE + EMC_RTCOR);
+	writew(0, EMC_BASE + EMC_RTCNT);
+
+	/*
+	 * Megabytes per bank
+	 */
+	tmp = 0x20f0;
+	tmp |= CONFIG_JZ4730_SDRAM_BANK_SIZE / 2;
+	writel(tmp, EMC_BASE + EMC_DMAR1);
+	tmp |= (CONFIG_JZ4730_SDRAM_BANK_SIZE / 2) << 8;
+	writel(tmp, EMC_BASE + EMC_DMAR2);
+
+	/*
+	 * Basic DMCR register value
+	 */
+	dmcr = (CONFIG_JZ4730_SDRAM_ROW - 11) << EMC_DMCR_RA_SHIFT;
+	dmcr |= (CONFIG_JZ4730_SDRAM_ROW - 11) << EMC_DMCR_RA_SHIFT;
+	dmcr |= (CONFIG_JZ4730_SDRAM_COL - 8) << EMC_DMCR_CA_SHIFT;
+	dmcr |= (CONFIG_JZ4730_SDRAM_BANKS_PER_CHIP / 2 - 1) << EMC_DMCR_BA_SHIFT;
+	dmcr |= (CONFIG_JZ4730_SDRAM_WIDTH == 32 ? 0 : 1) << EMC_DMCR_BW_SHIFT;
+	dmcr |= EMC_DMCR_EPIN;
+	dmcr |= (CONFIG_JZ4730_SDRAM_CAS - 1) << EMC_DMCR_TCL_SHIFT;
+
+	/*
+	 * SDRAM timimg parameters
+	 */
+	ns = 1000000000 / (CONFIG_CPU_FREQ_HZ / 3);
+	tmp = CONFIG_JZ4730_SDRAM_TRAS / ns;
+	if (tmp < 4)
+		tmp = 4;
+	if (tmp > 11)
+		tmp = 11;
+	dmcr |= (tmp - 4) << EMC_DMCR_TRAS_SHIFT;
+	tmp = CONFIG_JZ4730_SDRAM_RCD / ns;
+	if (tmp > 3)
+		tmp = 3;
+	dmcr |= tmp << EMC_DMCR_RCD_SHIFT;
+	tmp = CONFIG_JZ4730_SDRAM_TPC / ns;
+	if (tmp > 7)
+		tmp = 7;
+	dmcr |= tmp << EMC_DMCR_TPC_SHIFT;
+	tmp = CONFIG_JZ4730_SDRAM_TRW / ns;
+	if (tmp > 3)
+		tmp = 3;
+	dmcr |= tmp << EMC_DMCR_TRWL_SHIFT;
+	tmp = (CONFIG_JZ4730_SDRAM_TRAS + CONFIG_JZ4730_SDRAM_TPC) / ns;
+	if (tmp > 14)
+		tmp = 14;
+	dmcr |= ((tmp + 1) >> 1) << EMC_DMCR_TRC_SHIFT;
+
+	/*
+	 * SDRAM mode values
+	 */
+	sdmode = (generic_ffs(4) - 1) << EMC_SDMR_BL_SHIFT;
+	sdmode |= CONFIG_JZ4730_SDRAM_CAS << EMC_SDMR_CAS_SHIFT;
+	sdmode <<= (CONFIG_JZ4730_SDRAM_WIDTH == 32) ? 2 : 1;
+
+	/*
+	 * Precharge phase
+	 */
+	writel(dmcr, EMC_BASE + EMC_DMCR);
+
+	/*
+	 * Set refresh registers
+	 */
+	tmp = CONFIG_JZ4730_SDRAM_TREF / ns;
+	tmp = tmp / 64 + 1;
+	if (tmp > 0xff)
+		tmp = 0xff;
+
+	writew(tmp, EMC_BASE + EMC_RTCOR);
+
+	/*
+	 * CKO Divisor
+	 */
+	switch (CONFIG_JZ4730_SDRAM_CKS) {
+	case 4:
+		writew(1 << EMC_RTCSR_CKS_SHIFT, EMC_BASE + EMC_RTCSR);
+		break;
+	case 16:
+		writew(2 << EMC_RTCSR_CKS_SHIFT, EMC_BASE + EMC_RTCSR);
+		break;
+	case 64:
+		writew(3 << EMC_RTCSR_CKS_SHIFT, EMC_BASE + EMC_RTCSR);
+		break;
+	case 256:
+		writew(4 << EMC_RTCSR_CKS_SHIFT, EMC_BASE + EMC_RTCSR);
+		break;
+	case 1024:
+		writew(5 << EMC_RTCSR_CKS_SHIFT, EMC_BASE + EMC_RTCSR);
+		break;
+	case 2048:
+		writew(6 << EMC_RTCSR_CKS_SHIFT, EMC_BASE + EMC_RTCSR);
+		break;
+	case 4096:
+		writew(7 << EMC_RTCSR_CKS_SHIFT, EMC_BASE + EMC_RTCSR);
+		break;
+	}
+
+	/*
+	 * Precharge all chip-selects
+	 */
+	writeb(0, EMC_BASE + (EMC_SDMR0 | sdmode));
+	writeb(0, EMC_BASE + (EMC_SDMR1 | sdmode));
+
+	/*
+	 * Wait for precharge, > 200us
+	 */
+	tmp = (CONFIG_CPU_FREQ_HZ / 1000000) * 200;
+	while (tmp--)
+		;
+
+	/*
+	 * Enable refresh and set SDRAM mode
+	 */
+	writel(dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET, EMC_BASE + EMC_DMCR);
+
+	/*
+	 * Write sdram mode register for each chip-select
+	 */
+	writeb(0, EMC_BASE + (EMC_SDMR0 | sdmode));
+	writeb(0, EMC_BASE + (EMC_SDMR1 | sdmode));
+}
+
+#define CPM_BASE			(void __iomem *)0xb0000000
+#define CPM_CFCR			0x00
+#define CPM_PLCR1			0x10
+
+#define CPM_CFCR_CCLK_PLL_SHIFT		0
+#define CPM_CFCR_HCLK_PLL_SHIFT		4
+#define CPM_CFCR_PCLK_PLL_SHIFT		8
+#define CPM_CFCR_LCD_PLL_SHIFT		12
+#define CPM_CFCR_MCLK_PLL_SHIFT		16
+#define CPM_CFCR_MCLK_COKEN1		BIT(22)
+#define CPM_CFCR_UHC_IN_SHIFT		25
+
+#define CPM_PLCR1_PLL_STABLE_TIME_SHIFT	0
+#define CPM_PLCR1_PLL_ENABLE		BIT(8)
+#define CPM_PLCR1_PLL_OD_SHIFT		16
+#define CPM_PLCR1_PLL_N_SHIFT		18
+#define CPM_PLCR1_PLL_M_SHIFT		23
+
+static void clock_init(void)
+{
+	u32 val;
+
+	/*
+	 * Clock divisors
+	 */
+	val = CPM_CFCR_MCLK_COKEN1;
+	val |= 0 << CPM_CFCR_CCLK_PLL_SHIFT;
+	val |= 2 << CPM_CFCR_HCLK_PLL_SHIFT;
+	val |= 2 << CPM_CFCR_PCLK_PLL_SHIFT;
+	val |= 2 << CPM_CFCR_LCD_PLL_SHIFT;
+	val |= 2 << CPM_CFCR_MCLK_PLL_SHIFT;
+	val |= (CONFIG_CPU_FREQ_HZ / 48000000 - 1) << CPM_CFCR_UHC_IN_SHIFT;
+	writel(val, CPM_BASE + CPM_CFCR);
+
+	/*
+	 * Main PLL
+	 */
+	val = (CONFIG_CPU_FREQ_HZ * 2 / CONFIG_SYS_CLK - 2) << CPM_PLCR1_PLL_M_SHIFT;
+	val |= 0 << CPM_PLCR1_PLL_N_SHIFT;
+	val |= 0 << CPM_PLCR1_PLL_OD_SHIFT;
+	val |= 0x20 << CPM_PLCR1_PLL_STABLE_TIME_SHIFT;
+	val |= CPM_PLCR1_PLL_ENABLE;
+	writel(val, CPM_BASE + CPM_PLCR1);
+}
+
+#define PINCTRL_BASE	(void __iomem *)0xb0010000
+#define PINCTRL_ALR(n)	(0x10 + (n) * 0x30)
+#define PINCTRL_AUR(n)	(0x14 + (n) * 0x30)
+
+static void pinmux_init(void)
+{
+	/*
+	 * NAND Read Enable function on GP79
+	 */
+	clrbits_32(PINCTRL_BASE + PINCTRL_ALR(2), 0xc0000000);
+	setbits_32(PINCTRL_BASE + PINCTRL_ALR(2), 0x40000000);
+
+	/*
+	 * NAND Write Enable on GP80, NAND Ready/Busy on GP81 and
+	 * SDRAM CS1 on GP82
+	 */
+	clrbits_32(PINCTRL_BASE + PINCTRL_AUR(2), 0x0000003f);
+	setbits_32(PINCTRL_BASE + PINCTRL_AUR(2), 0x00000015);
+
+	/*
+	 * UART0 RX/TX on GP126/GP127
+	 */
+	clrbits_32(PINCTRL_BASE + PINCTRL_AUR(3), 0xf0000000);
+	setbits_32(PINCTRL_BASE + PINCTRL_AUR(3), 0x50000000);
+}
+
+void __noreturn board_init_f(ulong dummy)
+{
+	early_init();
+
+	spl_init();
+
+	pinmux_init();
+
+	clock_init();
+
+	sdram_init();
+
+	board_init_r(NULL, 0);
+
+	hang();
+}
+
+u32 spl_boot_device(void)
+{
+	return BOOT_DEVICE_NAND;
+}
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 19/20] mips: dts: Add Skytone Alpha 400
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (17 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 18/20] mips/mach-jz47xx: Add Ingenic JZ4730 support Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  2020-11-17 21:00 ` [PATCH RFC 20/20] board: " Lubomir Rintel
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

This generally comes from a mipsbook400 Letux git repository [1], not
mainline. It seems to be the work of Paul Boddie and H. Nikolaus Schaller.

[1] https://git.goldelico.com/?p=letux-kernel.git;a=shortlog;h=refs/heads/letux/dt-mipsbook400

Some more things need to be addressed here:

1.) Linux upstream review of the bindings.
    The tree is generally very nice and complete and bindings look good,
    but an upstream review could still cut off some rough edges. In
    particular I think the gpio/pinctrl bindings don't seem to describe
    the hardware in a very useful way (GPIO split into multiple nodes for
    ports slaves to the pinctrl node).

2.) Missing copyright/license notices.
    Probably an oversignt.

3.) I've made some changes that I need to split out into separate patches
    for upstream and document.

Cc: Paul Boddie <paul@boddie.org.uk>
Cc: H. Nikolaus Schaller <hns@goldelico.com>
Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 arch/mips/dts/Makefile     |   1 +
 arch/mips/dts/alpha400.dts | 542 +++++++++++++++++++++++++++++++++++++
 2 files changed, 543 insertions(+)
 create mode 100644 arch/mips/dts/alpha400.dts

diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
index dc85901dcaa..62ee25ff341 100644
--- a/arch/mips/dts/Makefile
+++ b/arch/mips/dts/Makefile
@@ -25,6 +25,7 @@ dtb-$(CONFIG_BOARD_SAGEM_FAST1704) += sagem,f at st1704.dtb
 dtb-$(CONFIG_BOARD_SFR_NB4_SER) += sfr,nb4-ser.dtb
 dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb
 dtb-$(CONFIG_BOARD_VOCORE2) += vocore_vocore2.dtb
+dtb-$(CONFIG_TARGET_JZ4730_ALPHA400) += alpha400.dtb
 dtb-$(CONFIG_TARGET_JZ4780_CI20) += ci20.dtb
 dtb-$(CONFIG_SOC_LUTON) += luton_pcb090.dtb luton_pcb091.dtb
 dtb-$(CONFIG_SOC_OCELOT) += ocelot_pcb120.dtb ocelot_pcb123.dtb
diff --git a/arch/mips/dts/alpha400.dts b/arch/mips/dts/alpha400.dts
new file mode 100644
index 00000000000..fa02f841d1a
--- /dev/null
+++ b/arch/mips/dts/alpha400.dts
@@ -0,0 +1,542 @@
+/dts-v1/;
+
+#include "jz4730.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "letux400,minipc", "ingenic,jz4730";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	wdt-reboot {
+		compatible = "wdt-reboot";
+		wdt = <&watchdog>;
+	};
+
+	vcc: regulator at 0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc";
+
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+
+	vmmc_reg: regulator at 1 {
+		compatible = "regulator-fixed";
+		regulator-name = "vmmc";
+
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpa 21 GPIO_ACTIVE_LOW>;
+	};
+
+	clk_usb: clk-usb {
+		compatible = "gpio-gate-clock";
+		clocks = <&cgu JZ4730_CLK_UHC>;
+		#clock-cells = <0>;
+		enable-gpios = <&gpa 29 GPIO_ACTIVE_HIGH>;
+	};
+
+	keyboard {
+		linux,wakeup;
+
+		compatible = "gpio-matrix-keypad";
+		debounce-delay-ms = <10>;
+		col-scan-delay-us = <10>;
+
+		row-gpios = <&gpa 0 0 &gpa 1 0 &gpa 2 0 &gpa 3 0
+			     &gpa 4 0 &gpa 5 0 &gpa 6 0 &gpa 7 0>;
+
+		col-gpios = <&gpd 0 0 &gpd 1 0 &gpd 2 0 &gpd 3 0
+			     &gpd 4 0 &gpd 5 0 &gpd 6 0 &gpd 7 0
+			     &gpd 8 0 &gpd 9 0 &gpd 10 0 &gpd 11 0
+			     &gpd 12 0 &gpd 13 0 &gpd 14 0 &gpd 15 0
+			     &gpd 29 0>;
+		gpio-activelow;
+
+		/*
+		 * Keymap column-by-column, based on...
+		 * https://web.archive.org/web/20120214204001/http://projects.kwaak.net/twiki/bin/view/Epc700/KeyBoard
+		 * ...and subsequently verified.
+		 */
+
+		linux,keymap = <
+			MATRIX_KEY(0, 0, KEY_PAUSE)
+			MATRIX_KEY(1, 0, 0)
+			MATRIX_KEY(2, 0, 0)
+			MATRIX_KEY(3, 0, 0)
+			MATRIX_KEY(4, 0, 0)
+			MATRIX_KEY(5, 0, 0)
+			MATRIX_KEY(6, 0, KEY_LEFTCTRL)
+			MATRIX_KEY(7, 0, KEY_F5)
+
+			MATRIX_KEY(0, 1, KEY_Q)
+			MATRIX_KEY(1, 1, KEY_TAB)
+			MATRIX_KEY(2, 1, KEY_A)
+			MATRIX_KEY(3, 1, KEY_ESC)
+			MATRIX_KEY(4, 1, KEY_Z)
+			MATRIX_KEY(5, 1, 0)
+			MATRIX_KEY(6, 1, KEY_GRAVE)
+			MATRIX_KEY(7, 1, KEY_1)
+
+			MATRIX_KEY(0, 2, KEY_W)
+			MATRIX_KEY(1, 2, KEY_CAPSLOCK)
+			MATRIX_KEY(2, 2, KEY_S)
+			MATRIX_KEY(3, 2, KEY_102ND)
+			MATRIX_KEY(4, 2, KEY_X)
+			MATRIX_KEY(5, 2, 0)
+			MATRIX_KEY(6, 2, 0)
+			MATRIX_KEY(7, 2, KEY_2)
+
+			MATRIX_KEY(0, 3, KEY_E)
+			MATRIX_KEY(1, 3, KEY_F3)
+			MATRIX_KEY(2, 3, KEY_D)
+			MATRIX_KEY(3, 3, KEY_F4)
+			MATRIX_KEY(4, 3, KEY_C)
+			MATRIX_KEY(5, 3, 0)
+			MATRIX_KEY(6, 3, 0)
+			MATRIX_KEY(7, 3, KEY_3)
+
+			MATRIX_KEY(0, 4, KEY_R)
+			MATRIX_KEY(1, 4, KEY_T)
+			MATRIX_KEY(2, 4, KEY_F)
+			MATRIX_KEY(3, 4, KEY_G)
+			MATRIX_KEY(4, 4, KEY_V)
+			MATRIX_KEY(5, 4, KEY_B)
+			MATRIX_KEY(6, 4, KEY_5)
+			MATRIX_KEY(7, 4, KEY_4)
+
+			MATRIX_KEY(0, 5, KEY_U)
+			MATRIX_KEY(1, 5, KEY_Y)
+			MATRIX_KEY(2, 5, KEY_J)
+			MATRIX_KEY(3, 5, KEY_H)
+			MATRIX_KEY(4, 5, KEY_M)
+			MATRIX_KEY(5, 5, KEY_N)
+			MATRIX_KEY(6, 5, KEY_6)
+			MATRIX_KEY(7, 5, KEY_7)
+
+			MATRIX_KEY(0, 6, KEY_I)
+			MATRIX_KEY(1, 6, KEY_RIGHTBRACE)
+			MATRIX_KEY(2, 6, KEY_K)
+			MATRIX_KEY(3, 6, KEY_F6)
+			MATRIX_KEY(4, 6, KEY_COMMA)
+			MATRIX_KEY(5, 6, 0)
+			MATRIX_KEY(6, 6, KEY_EQUAL)
+			MATRIX_KEY(7, 6, KEY_8)
+
+			MATRIX_KEY(0, 7, KEY_O)
+			MATRIX_KEY(1, 7, KEY_F7)
+			MATRIX_KEY(2, 7, KEY_L)
+			MATRIX_KEY(3, 7, 0)
+			MATRIX_KEY(4, 7, KEY_DOT)
+			MATRIX_KEY(5, 7, KEY_F19)
+			MATRIX_KEY(6, 7, KEY_F8)
+			MATRIX_KEY(7, 7, KEY_9)
+
+			MATRIX_KEY(0, 8, 0)
+			MATRIX_KEY(1, 8, 0)
+			MATRIX_KEY(2, 8, 0)
+			MATRIX_KEY(3, 8, KEY_SPACE)
+			MATRIX_KEY(4, 8, KEY_NUMLOCK)
+			MATRIX_KEY(5, 8, 0)
+			MATRIX_KEY(6, 8, KEY_DELETE)
+			MATRIX_KEY(7, 8, 0)
+
+			MATRIX_KEY(0, 9, 0)
+			MATRIX_KEY(1, 9, KEY_BACKSPACE)
+			MATRIX_KEY(2, 9, 0)
+			MATRIX_KEY(3, 9, 0)
+			MATRIX_KEY(4, 9, KEY_ENTER)
+			MATRIX_KEY(5, 9, 0)
+			MATRIX_KEY(6, 9, KEY_F9)
+			MATRIX_KEY(7, 9, 0)
+
+			MATRIX_KEY(0, 10, 0)
+			MATRIX_KEY(1, 10, 0)
+			MATRIX_KEY(2, 10, 0)
+			MATRIX_KEY(3, 10, KEY_LEFTALT)
+			MATRIX_KEY(4, 10, 0)
+			MATRIX_KEY(5, 10, 0)
+			MATRIX_KEY(6, 10, 0)
+			MATRIX_KEY(7, 10, KEY_SYSRQ)
+
+			MATRIX_KEY(0, 11, KEY_P)
+			MATRIX_KEY(1, 11, KEY_LEFTBRACE)
+			MATRIX_KEY(2, 11, KEY_SEMICOLON)
+			MATRIX_KEY(3, 11, KEY_APOSTROPHE)
+			MATRIX_KEY(4, 11, KEY_BACKSLASH)
+			MATRIX_KEY(5, 11, KEY_SLASH)
+			MATRIX_KEY(6, 11, KEY_MINUS)
+			MATRIX_KEY(7, 11, KEY_0)
+
+			MATRIX_KEY(0, 12, 0)
+			MATRIX_KEY(1, 12, KEY_F20)
+			MATRIX_KEY(2, 12, 0)
+			MATRIX_KEY(3, 12, 0)
+			MATRIX_KEY(4, 12, 0)
+			MATRIX_KEY(5, 12, 0)
+			MATRIX_KEY(6, 12, 0)
+			MATRIX_KEY(7, 12, KEY_F10)
+
+			MATRIX_KEY(0, 13, 0)
+			MATRIX_KEY(1, 13, 0)
+			MATRIX_KEY(2, 13, 0)
+			MATRIX_KEY(3, 13, 0)
+			MATRIX_KEY(4, 13, 0)
+			MATRIX_KEY(5, 13, 0)
+			MATRIX_KEY(6, 13, KEY_F2)
+			MATRIX_KEY(7, 13, 0)
+
+			MATRIX_KEY(0, 14, 0)
+			MATRIX_KEY(1, 14, 0)
+			MATRIX_KEY(2, 14, 0)
+			MATRIX_KEY(3, 14, 0)
+			MATRIX_KEY(4, 14, 0)
+			MATRIX_KEY(5, 14, 0)
+			MATRIX_KEY(6, 14, KEY_INSERT)
+			MATRIX_KEY(7, 14, 0)
+
+			MATRIX_KEY(0, 15, 0)
+			MATRIX_KEY(1, 15, 0)
+			MATRIX_KEY(2, 15, KEY_UP)
+			MATRIX_KEY(3, 15, KEY_DOWN)
+			MATRIX_KEY(4, 15, KEY_LEFT)
+			MATRIX_KEY(5, 15, KEY_RIGHT)
+			MATRIX_KEY(6, 15, 0)
+			MATRIX_KEY(7, 15, 0)
+
+			MATRIX_KEY(0, 16, 0)
+			MATRIX_KEY(1, 16, KEY_LEFTSHIFT)
+			MATRIX_KEY(2, 16, KEY_RIGHTSHIFT)
+			MATRIX_KEY(3, 16, 0)
+			MATRIX_KEY(4, 16, 0)
+			MATRIX_KEY(5, 16, 0)
+			MATRIX_KEY(6, 16, KEY_F1)
+			MATRIX_KEY(7, 16, KEY_FN)
+			>;
+	};
+
+	buttons {
+		compatible = "gpio-keys";
+
+		#address-cells = <7>;
+		#size-cells = <0>;
+
+		left_touchpad {
+			label = "Touchpad Left";
+			linux,code = <0x110>;	/* BTN_LEFT */
+			gpios = <&gpa 16 GPIO_ACTIVE_LOW>;
+			gpio-key,wakeup;
+		};
+
+		right_touchpad {
+			label = "Touchpad Right";
+			linux,code = <0x111>;	/* BTN_RIGHT */
+			gpios = <&gpa 9 GPIO_ACTIVE_LOW>;
+			gpio-key,wakeup;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		scroll_lock {
+			label = "scroll_lock";
+			gpios = <&gpa 9 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "scroll_lock";
+			default-state = "off";
+		};
+
+		caps_lock {
+			label = "caps_lock";
+			gpios = <&gpa 27 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "caps_lock";
+			default-state = "off";
+		};
+
+		num_lock {
+			label = "num_lock";
+			gpios = <&gpc 22 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "num_lock";
+			default-state = "off";
+		};
+	};
+
+	sound: sound {
+		compatible = "simple-scu-audio-card";
+
+		simple-audio-card,name = "sound";
+		simple-audio-card,format = "left_j";
+		simple-audio-card,bitclock-master = <&sndcodec>;
+		simple-audio-card,frame-master = <&sndcodec>;
+
+		simple-audio-card,convert-rate = <48000>;
+
+		simple-audio-card,prefix = "ak4642";
+		simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
+				"DAI0 Capture", "ak4642 Capture";
+
+		sndcpu: simple-audio-card,cpu {
+			sound-dai = <&i2s>;
+		};
+
+		sndcodec: simple-audio-card,codec {
+			sound-dai = <&ak4642>;
+			system-clock-frequency = <11289600>;
+		};
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+
+		pwms = <&pwm 0 3906250>;
+		power-supply = <&vcc>;
+
+		brightness-levels = <150 200 250 300>;
+		default-brightness-level = <2>;
+
+		default-on;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pins_pwm0>;
+	};
+
+	panel: claa070vc01 {
+		compatible = "chunghwa,claa070vc01", "panel-dpi";
+
+		width-mm = <150>;
+		height-mm = <90>;
+
+		backlight = <&backlight>;
+
+		panel-timing {
+			clock-frequency = <26400000>;
+			hactive = <800>;
+			vactive = <480>;
+			hfront-porch = <0>;
+			hback-porch = <0>;
+			hsync-len = <80>;
+			vfront-porch = <0>;
+			vback-porch = <0>;
+			vsync-len = <20>;
+			hsync-active = <0>;
+			vsync-active = <0>;
+			de-active = <1>;
+			pixelclk-active = <0>;
+		};
+
+		port {
+			panel_input: endpoint {
+				remote-endpoint = <&lcd_output>;
+			};
+		};
+	};
+};
+
+&ext {
+	clock-frequency = <3686400>;
+};
+
+&rtc_dev {
+	system-power-controller;
+};
+
+&lcd {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&pins_lcd0>;
+	pinctrl-1 = <&pins_lcd1>;
+
+	port {
+		lcd_output: endpoint {
+			remote-endpoint = <&panel_input>;
+		};
+	};
+};
+
+&mmc {
+	status = "okay";
+
+	bus-width = <4>;
+	cd-gpios = <&gpc 0 GPIO_ACTIVE_LOW>;
+	wp-gpios = <&gpc 2 GPIO_ACTIVE_LOW>;
+	vmmc-supply = <&vmmc_reg>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pins_mmc>;
+};
+
+&nand {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pins_nand>;
+
+	nand0: nand at 0 {
+		#address-cells = <0>;
+		#size-cells = <0>;
+		reg = <0>;
+		wp-gpios = <&gpc 23 GPIO_ACTIVE_LOW>;
+
+		nand-on-flash-bbt;
+		nand-bus-width = <8>;
+
+		nand-ecc-mode = "none";
+
+		partitions {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fixed-partitions";
+
+			bootloader at 0 {
+				label = "bootloader";
+				reg = <0x00000000 0x00100000>;
+			};
+
+			kernel at 100000 {
+				label = "kernel";
+				reg = <0x00100000 0x00300000>;
+			};
+
+			mac at 400000 {
+				label = "mac";
+				reg = <0x00400000 0x00100000>;
+			};
+
+			recovery at 500000 {
+				label = "mini rootfs";
+				reg = <0x00500000 0x00500000>;
+			};
+
+			root at a00000 {
+				label = "yaffs2 rootfs";
+				reg = <0x00a00000 0x3f600000>;
+			};
+
+			extend at 40000000 {
+				label = "extend 1G flash";
+				reg = <0x40000000 0x40000000>;
+			};
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pins_uart0>;
+};
+
+&pinctrl {
+	pins_lcd0: lcd0 {
+		function = "lcd";
+		groups = "lcd-8bit", "lcd-16bit", "lcd-16bit-tft";
+	};
+
+	pins_lcd1: lcd1 {
+		function = "sleep";
+		groups = "lcd-no-pins";
+	};
+
+	pins_mmc: mmc {
+		mmc {
+			function = "mmc";
+			groups = "mmc-1bit", "mmc-4bit";
+		};
+
+		mmc_ctrl {
+			function = "mmc";
+			pins = "PC0", "PC2", "PA21";
+			bias-disable;
+		};
+	};
+
+	pins_nand: pins_nand {
+		function = "nand";
+		groups = "nand-cs3";
+	};
+
+	pins_pwm0: pwm0 {
+		function = "pwm0";
+		groups = "pwm0";
+	};
+
+	pins_pwm1: pwm1 {
+		function = "pwm1";
+		groups = "pwm1";
+	};
+
+	pins_uart0: uart0 {
+		function = "uart0";
+		groups = "uart0-data";
+		bias-disable;
+	};
+
+	pins_usb_clk: usb {
+		pins = "PA29";
+		bias-disable;
+	};
+
+	pins_mac: pins_mac {
+		function = "mac";
+		groups = "mac";
+	};
+};
+
+&i2c {
+	power_controller at 28 {
+		compatible = "minipc,mcu";
+		reg = <0x28>;
+	};
+
+	ak4642: codec at 12 {
+		compatible = "asahi-kasei,ak4642";
+		reg = <0x12>;
+		#clock-cells = <0>;
+		clock-frequency = <12000000>;
+		clock-output-names = "ak4643_mcko";
+	};
+
+	rtc at 51 {
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+		#clock-cells = <0>;
+	};
+
+};
+
+&uhc {
+	clocks = <&clk_usb>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pins_usb_clk>;
+};
+
+&ethernet {
+	phy-handle = <&ethphy>;
+	phy-mode = "mii";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pins_mac>;
+};
+
+&mdio {
+	ethphy: ethernet-phy at 16 {
+		device_type = "ethernet-phy";
+		compatible = "realtek,rtl8201cl", "ethernet-phy-ieee802.3-c22";
+		reg = <16>;
+	};
+};
+
+/*
+ * TODO:
+ * add LCD
+ * add proper Pinmux
+ * finalize sound / codec setup
+ * add i2c and i2s drivers to the SoC
+ * add special driver to probe two gpios to detect battery charging and AC present
+ */
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 20/20] board: Add Skytone Alpha 400
  2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
                   ` (18 preceding siblings ...)
  2020-11-17 21:00 ` [PATCH RFC 19/20] mips: dts: Add Skytone Alpha 400 Lubomir Rintel
@ 2020-11-17 21:00 ` Lubomir Rintel
  19 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-17 21:00 UTC (permalink / raw)
  To: u-boot

This is a MIPS subnotebook built around Ingenic JZ4730 SoC. It is known
by many names, including CPC400 and Letux 400, but the OEM seems to be
Skytone and use the "Alpha 400" designator.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 arch/mips/mach-jz47xx/Kconfig     | 23 ++++++++
 board/skytone/alpha400/Kconfig    | 60 +++++++++++++++++++
 board/skytone/alpha400/Makefile   |  3 +
 board/skytone/alpha400/alpha400.c | 43 ++++++++++++++
 configs/alpha400_nand_defconfig   | 11 ++++
 include/configs/alpha400.h        | 98 +++++++++++++++++++++++++++++++
 6 files changed, 238 insertions(+)
 create mode 100644 board/skytone/alpha400/Kconfig
 create mode 100644 board/skytone/alpha400/Makefile
 create mode 100644 board/skytone/alpha400/alpha400.c
 create mode 100644 configs/alpha400_nand_defconfig
 create mode 100644 include/configs/alpha400.h

diff --git a/arch/mips/mach-jz47xx/Kconfig b/arch/mips/mach-jz47xx/Kconfig
index 6fba38c7363..6a01394d4e3 100644
--- a/arch/mips/mach-jz47xx/Kconfig
+++ b/arch/mips/mach-jz47xx/Kconfig
@@ -50,6 +50,29 @@ config SOC_JZ4780
 choice
 	prompt "Board select"
 
+config TARGET_JZ4730_ALPHA400
+	bool "Skytone Alpha 400 Mini Notebook"
+	select SOC_JZ4730
+	select CMD_MMC if DISTRO_DEFAULTS
+	select SPL_NAND_BASE if SPL
+	select SPL_NAND_DRIVERS if SPL
+	select SPL_NAND_SIMPLE if SPL
+	select SPL_NAND_SUPPORT if SPL
+	select SYS_NAND_U_BOOT_LOCATIONS
+	imply DISTRO_DEFAULTS
+	imply DM_ETH
+	imply DM_ETH_PHY
+	imply DM_GPIO
+	imply DM_MMC
+	imply DM_MTD
+	imply DM_REGULATOR
+	imply DM_REGULATOR_FIXED
+	imply NET_RANDOM_ETHADDR
+	help
+	  Support for a MIPS subnotebook built around Ingenic JZ4730 SoC.
+	  It is known by many names, including CPC400 and Letux 400, but
+	  the OEM seems to be Skytone and use the "Alpha 400" designator.
+
 config TARGET_JZ4780_CI20
 	bool "Creator CI20 Reference Board"
 	select SOC_JZ4780
diff --git a/board/skytone/alpha400/Kconfig b/board/skytone/alpha400/Kconfig
new file mode 100644
index 00000000000..a8413826a81
--- /dev/null
+++ b/board/skytone/alpha400/Kconfig
@@ -0,0 +1,60 @@
+if TARGET_JZ4730_ALPHA400
+
+config SYS_BOARD
+	default "alpha400"
+
+config SYS_VENDOR
+	default "skytone"
+
+config SYS_CONFIG_NAME
+	default "alpha400"
+
+config DEFAULT_DEVICE_TREE
+	default "alpha400"
+
+config BUILD_TARGET
+	default "u-boot-with-spl.bin" if SPL
+
+config SYS_NAND_U_BOOT_OFFS
+	default 0x20000
+
+config NR_DRAM_BANKS
+	default 16
+
+config JZ4730_SDRAM_BANK_SIZE
+	default 8
+
+config JZ4730_SDRAM_ROW
+	default 13
+
+config JZ4730_SDRAM_COL
+	default 9
+
+config JZ4730_SDRAM_BANKS_PER_CHIP
+	default 4
+
+config JZ4730_SDRAM_WIDTH
+	default 32
+
+config JZ4730_SDRAM_CAS
+	default 2
+
+config JZ4730_SDRAM_TRAS
+	default 45
+
+config JZ4730_SDRAM_RCD
+	default 20
+
+config JZ4730_SDRAM_TPC
+	default 20
+
+config JZ4730_SDRAM_TRW
+	default 7
+
+config JZ4730_SDRAM_TREF
+	default 7812
+
+config JZ4730_SDRAM_CKS
+	default 64
+
+endif
diff --git a/board/skytone/alpha400/Makefile b/board/skytone/alpha400/Makefile
new file mode 100644
index 00000000000..b892abd88a4
--- /dev/null
+++ b/board/skytone/alpha400/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y := alpha400.o
diff --git a/board/skytone/alpha400/alpha400.c b/board/skytone/alpha400/alpha400.c
new file mode 100644
index 00000000000..a05d078a661
--- /dev/null
+++ b/board/skytone/alpha400/alpha400.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ *
+ * Skytone Alpha 400 board support routines.
+ */
+
+#include <common.h>
+#include <net.h>
+#include <nand.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int mac_read_from_eeprom(void)
+{
+	char ethaddr[ARP_HLEN_ASCII + 1] = { 0, };
+	size_t ethaddr_len = ARP_HLEN_ASCII;
+	int ret;
+
+	nand_init();
+	ret = nand_read(get_nand_dev_by_index(0),
+			0x00400000, &ethaddr_len, (void *)ethaddr);
+	if (ret) {
+		pr_err("Unable to read MAC address from NAND.\n");
+		return 0; /* Not serious enough to fail the boot.  */
+	}
+
+	env_set("ethaddr", ethaddr);
+	return ret;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = SZ_128M;
+	return 0;
+}
+
+int checkboard(void)
+{
+	puts("Board: Skytone Alpha 400\n");
+	return 0;
+}
diff --git a/configs/alpha400_nand_defconfig b/configs/alpha400_nand_defconfig
new file mode 100644
index 00000000000..cd2daccc821
--- /dev/null
+++ b/configs/alpha400_nand_defconfig
@@ -0,0 +1,11 @@
+CONFIG_MIPS=y
+CONFIG_ARCH_JZ47XX=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_JFFS2=y
+CONFIG_MTDIDS_DEFAULT="nand0=jz4730-nand.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=jz4730-nand.0:1m(bootloader),3m(kernel),1m(mac),5m(mini),1014m(yaffs2),-(extend)"
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_MMC_HW_PARTITIONING is not set
+CONFIG_NS16550_DYNAMIC=y
+CONFIG_WATCHDOG_TIMEOUT_MSECS=0
diff --git a/include/configs/alpha400.h b/include/configs/alpha400.h
new file mode 100644
index 00000000000..673b42f372f
--- /dev/null
+++ b/include/configs/alpha400.h
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ *
+ * Configuration settings for Skytone Alpha 400 board.
+ */
+
+#ifndef __CONFIG_ALPHA400_H__
+#define __CONFIG_ALPHA400_H__
+
+#include <linux/sizes.h>
+
+#ifndef CONFIG_SPL_BUILD
+#define BOOTENV_DEV_NAND_LEGACY(devtypeu, devtypel, instance) \
+	"bootcmd_" #devtypel #instance "=" \
+	"nboot ${kernel_addr_r} " #instance " 0x100000; bootm\0"
+
+#define BOOTENV_DEV_NAME_NAND_LEGACY(devtypeu, devtypel, instance) \
+	#devtypel #instance " "
+
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 0) \
+	func(NAND_LEGACY, nand, 0)
+
+#include <config_distro_bootcmd.h>
+#endif
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"bootargs=mem=128M console=ttyS0,115200n8 root=/dev/ssfdca1 rw noatime\0" \
+	"kernel_addr_r=0x80600000\0" \
+	"scriptaddr=0x81000000\0" \
+	"fdt_addr_r=0x81100000\0" \
+	"ramdisk_addr_r=0x81200000\0" \
+	BOOTENV
+
+#define CONFIG_SYS_MALLOC_LEN		SZ_16M
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+#define CONFIG_SYS_INIT_SP_OFFSET	0x00400000
+#define CONFIG_SYS_INIT_SP_ADDR		0x80004000
+#define CONFIG_SYS_LOAD_ADDR		0x81000000
+#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_NAND_U_BOOT_DST	CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_NAND_U_BOOT_SIZE	SZ_512K
+
+#define CONFIG_SPL_MAX_SIZE		SZ_4K
+#define CONFIG_SPL_BSS_MAX_SIZE		SZ_4K
+#define CONFIG_SPL_PAD_TO		0x00020000
+#define CONFIG_SPL_BSS_START_ADDR	0x80001000
+#define CONFIG_SPL_STACK		0x80004000
+
+#define CONFIG_SPL_NAND_LOAD
+#define CONFIG_SPL_NAND_RAW_ONLY
+
+/*
+ * NAND flash.
+ */
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define CONFIG_SYS_NAND_MAX_CHIPS	2
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define CONFIG_SYS_NAND_BASE		0xb4000000
+#define CONFIG_SYS_NAND_PAGE_SIZE	SZ_2K
+#define CONFIG_SYS_NAND_BLOCK_SIZE	SZ_128K
+#define CONFIG_SYS_NAND_PAGE_COUNT	(CONFIG_SYS_NAND_BLOCK_SIZE / \
+					 CONFIG_SYS_NAND_PAGE_SIZE)
+#define CONFIG_SYS_NAND_OOBSIZE		64
+#define CONFIG_SYS_NAND_BAD_BLOCK_POS	NAND_LARGE_BADBLOCK_POS
+
+/*
+ * The MAC address is in a NAND flash partition.
+ */
+#define CONFIG_ID_EEPROM
+#define CONFIG_SYS_RX_ETH_BUFFER	16
+
+/*
+ * The "recovery" partition.
+ */
+#define CONFIG_JFFS2_NAND
+#define CONFIG_JFFS2_DEV		"nand0"
+#define CONFIG_JFFS2_PART_OFFSET	0x00500000
+#define CONFIG_JFFS2_PART_SIZE		0x00500000
+
+/*
+ * Useful for SPL.
+ */
+#define CONFIG_CPU_FREQ_HZ		336000000
+#define CONFIG_SYS_CLK			3686400
+
+/*
+ * These are only useful for CONFIG_DEBUG_UART.
+ * The regular serial driver gets its params from DT.
+ */
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_CLK		CONFIG_SYS_CLK
+#define CONFIG_SYS_NS16550_COM1		0xb0030000
+
+#endif /* __CONFIG_ALPHA400_H__ */
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC 03/20] cmd/mac: Don't build unless CONFIG_CMD_MAC is enabled
  2020-11-17 21:00 ` [PATCH RFC 03/20] cmd/mac: Don't build unless CONFIG_CMD_MAC is enabled Lubomir Rintel
@ 2020-11-17 22:17   ` Daniel Schwierzeck
  0 siblings, 0 replies; 26+ messages in thread
From: Daniel Schwierzeck @ 2020-11-17 22:17 UTC (permalink / raw)
  To: u-boot

Am Dienstag, den 17.11.2020, 22:00 +0100 schrieb Lubomir Rintel:
> This allows us to enable CONFIG_ID_EEPROM to add a hook to read ethaddr
> off a ROM without having to implement do_mac().
> 
> Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
> ---
>  arch/arm/Kconfig                 | 19 +++++++++++++++++++
>  arch/powerpc/cpu/mpc85xx/Kconfig | 17 +++++++++++++++++

you should also cc Tom Rini and Priyanka Jain <priyanka.jain@nxp.com>

>  cmd/Kconfig                      |  3 +++
>  cmd/Makefile                     |  2 +-
>  4 files changed, 40 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index b2f7fcbd6ec..884e6f11365 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1245,6 +1245,7 @@ config TARGET_LS1088AQDS
>  	select BOARD_LATE_INIT
>  	select SUPPORT_SPL
>  	select FSL_DDR_INTERACTIVE if !SD_BOOT
> +	select CMD_MAC

commands should be selected with "imply CMD_XXX" so the user can
deselect them when needed. This also means that CMD_MAC should be
visible to the user:

config CMD_MAC
   bool "mac"

>  	help
>  	  Support for NXP LS1088AQDS platform.
>  	  The LS1088A Development System (QDS) is a high-performance
> @@ -1263,6 +1264,7 @@ config TARGET_LS2080AQDS
>  	imply SCSI_AHCI
>  	select FSL_DDR_BIST
>  	select FSL_DDR_INTERACTIVE if !SPL
> +	select CMD_MAC
>  	help
>  	  Support for Freescale LS2080AQDS platform.
>  	  The LS2080A Development System (QDS) is a high-performance
> @@ -1279,6 +1281,7 @@ config TARGET_LS2080ARDB
>  	select SUPPORT_SPL
>  	select FSL_DDR_BIST
>  	select FSL_DDR_INTERACTIVE if !SPL
> +	select CMD_MAC
>  	imply SCSI
>  	imply SCSI_AHCI
>  	help
> @@ -1294,6 +1297,7 @@ config TARGET_LS2081ARDB
>  	select ARMV8_MULTIENTRY
>  	select BOARD_LATE_INIT
>  	select SUPPORT_SPL
> +	select CMD_MAC
>  	help
>  	  Support for Freescale LS2081ARDB platform.
>  	  The LS2081A Reference design board (RDB) is a high-performance
> @@ -1307,6 +1311,7 @@ config TARGET_LX2160ARDB
>  	select ARMV8_MULTIENTRY
>  	select ARCH_SUPPORT_TFABOOT
>  	select BOARD_LATE_INIT
> +	select CMD_MAC
>  	help
>  	  Support for NXP LX2160ARDB platform.
>  	  The lx2160ardb (LX2160A Reference design board (RDB)
> @@ -1320,6 +1325,7 @@ config TARGET_LX2160AQDS
>  	select ARMV8_MULTIENTRY
>  	select ARCH_SUPPORT_TFABOOT
>  	select BOARD_LATE_INIT
> +	select CMD_MAC
>  	help
>  	  Support for NXP LX2160AQDS platform.
>  	  The lx2160aqds (LX2160A QorIQ Development System (QDS)
> @@ -1373,6 +1379,7 @@ config TARGET_LS1012AQDS
>  	select ARM64
>  	select ARCH_SUPPORT_TFABOOT
>  	select BOARD_LATE_INIT
> +	select CMD_MAC
>  	help
>  	  Support for Freescale LS1012AQDS platform.
>  	  The LS1012A Development System (QDS) is a high-performance
> @@ -1438,6 +1445,7 @@ config TARGET_LS1028AQDS
>  	select ARMV8_MULTIENTRY
>  	select ARCH_SUPPORT_TFABOOT
>  	select BOARD_LATE_INIT
> +	select CMD_MAC
>  	help
>  	  Support for Freescale LS1028AQDS platform
>  	  The LS1028A Development System (QDS) is a high-performance
> @@ -1451,6 +1459,7 @@ config TARGET_LS1028ARDB
>  	select ARMV8_MULTIENTRY
>  	select ARCH_SUPPORT_TFABOOT
>  	select BOARD_LATE_INIT
> +	select CMD_MAC
>  	help
>  	  Support for Freescale LS1028ARDB platform
>  	  The LS1028A Development System (RDB) is a high-performance
> @@ -1466,6 +1475,7 @@ config TARGET_LS1088ARDB
>  	select BOARD_LATE_INIT
>  	select SUPPORT_SPL
>  	select FSL_DDR_INTERACTIVE if !SD_BOOT
> +	select CMD_MAC
>  	help
>  	  Support for NXP LS1088ARDB platform.
>  	  The LS1088A Reference design board (RDB) is a high-performance
> @@ -1487,6 +1497,7 @@ config TARGET_LS1021AQDS
>  	select FSL_DDR_INTERACTIVE
>  	select DM_SPI_FLASH if FSL_DSPI || FSL_QSPI
>  	select SPI_FLASH_DATAFLASH if FSL_DSPI || FSL_QSPI
> +	select CMD_MAC
>  	imply SCSI
>  
>  config TARGET_LS1021ATWR
> @@ -1501,6 +1512,7 @@ config TARGET_LS1021ATWR
>  	select LS1_DEEP_SLEEP
>  	select SUPPORT_SPL
>  	select DM_SPI_FLASH if FSL_DSPI || FSL_QSPI
> +	select CMD_MAC
>  	imply SCSI
>  
>  config TARGET_LS1021ATSN
> @@ -1514,6 +1526,7 @@ config TARGET_LS1021ATSN
>  	select CPU_V7_HAS_VIRT
>  	select LS1_DEEP_SLEEP
>  	select SUPPORT_SPL
> +	select CMD_MAC
>  	imply SCSI
>  
>  config TARGET_LS1021AIOT
> @@ -1526,6 +1539,7 @@ config TARGET_LS1021AIOT
>  	select CPU_V7_HAS_VIRT
>  	select SUPPORT_SPL
>  	select DM_SPI_FLASH if FSL_DSPI || FSL_QSPI
> +	select CMD_MAC
>  	imply SCSI
>  	help
>  	  Support for Freescale LS1021AIOT platform.
> @@ -1545,6 +1559,7 @@ config TARGET_LS1043AQDS
>  	select FSL_DDR_INTERACTIVE if !SPL
>  	select FSL_DSPI if !SPL_NO_DSPI
>  	select DM_SPI_FLASH if FSL_DSPI
> +	select CMD_MAC
>  	imply SCSI
>  	imply SCSI_AHCI
>  	help
> @@ -1561,6 +1576,7 @@ config TARGET_LS1043ARDB
>  	select SUPPORT_SPL
>  	select FSL_DSPI if !SPL_NO_DSPI
>  	select DM_SPI_FLASH if FSL_DSPI
> +	select CMD_MAC
>  	help
>  	  Support for Freescale LS1043ARDB platform.
>  
> @@ -1577,6 +1593,7 @@ config TARGET_LS1046AQDS
>  	select FSL_DDR_BIST if !SPL
>  	select FSL_DDR_INTERACTIVE  if !SPL
>  	select FSL_DDR_INTERACTIVE if !SPL
> +	select CMD_MAC
>  	imply SCSI
>  	help
>  	  Support for Freescale LS1046AQDS platform.
> @@ -1597,6 +1614,7 @@ config TARGET_LS1046ARDB
>  	select SUPPORT_SPL
>  	select FSL_DDR_BIST
>  	select FSL_DDR_INTERACTIVE if !SPL
> +	select CMD_MAC
>  	imply SCSI
>  	help
>  	  Support for Freescale LS1046ARDB platform.
> @@ -1613,6 +1631,7 @@ config TARGET_LS1046AFRWY
>  	select BOARD_EARLY_INIT_F
>  	select BOARD_LATE_INIT
>  	select DM_SPI_FLASH if DM_SPI
> +	select CMD_MAC
>  	imply SCSI
>  	help
>  	  Support for Freescale LS1046AFRWY platform.
> diff --git a/arch/powerpc/cpu/mpc85xx/Kconfig b/arch/powerpc/cpu/mpc85xx/Kconfig
> index 54c7fd9522a..a1bbab64991 100644
> --- a/arch/powerpc/cpu/mpc85xx/Kconfig
> +++ b/arch/powerpc/cpu/mpc85xx/Kconfig
> @@ -29,6 +29,7 @@ config TARGET_P3041DS
>  	select PHYS_64BIT
>  	select ARCH_P3041
>  	select BOARD_LATE_INIT if CHAIN_OF_TRUST
> +	select CMD_MAC
>  	imply CMD_SATA
>  	imply PANIC_HANG
>  
> @@ -37,6 +38,7 @@ config TARGET_P4080DS
>  	select PHYS_64BIT
>  	select ARCH_P4080
>  	select BOARD_LATE_INIT if CHAIN_OF_TRUST
> +	select CMD_MAC
>  	imply CMD_SATA
>  	imply PANIC_HANG
>  
> @@ -45,12 +47,14 @@ config TARGET_P5040DS
>  	select PHYS_64BIT
>  	select ARCH_P5040
>  	select BOARD_LATE_INIT if CHAIN_OF_TRUST
> +	select CMD_MAC
>  	imply CMD_SATA
>  	imply PANIC_HANG
>  
>  config TARGET_MPC8541CDS
>  	bool "Support MPC8541CDS"
>  	select ARCH_MPC8541
> +	select CMD_MAC
>  
>  config TARGET_MPC8544DS
>  	bool "Support MPC8544DS"
> @@ -60,10 +64,12 @@ config TARGET_MPC8544DS
>  config TARGET_MPC8548CDS
>  	bool "Support MPC8548CDS"
>  	select ARCH_MPC8548
> +	select CMD_MAC
>  
>  config TARGET_MPC8555CDS
>  	bool "Support MPC8555CDS"
>  	select ARCH_MPC8555
> +	select CMD_MAC
>  
>  config TARGET_MPC8568MDS
>  	bool "Support MPC8568MDS"
> @@ -72,12 +78,14 @@ config TARGET_MPC8568MDS
>  config TARGET_MPC8569MDS
>  	bool "Support MPC8569MDS"
>  	select ARCH_MPC8569
> +	select CMD_MAC
>  
>  config TARGET_MPC8572DS
>  	bool "Support MPC8572DS"
>  	select ARCH_MPC8572
>  # Use DDR3 controller with DDR2 DIMMs on this board
>  	select SYS_FSL_DDRC_GEN3
> +	select CMD_MAC
>  	imply SCSI
>  	imply PANIC_HANG
>  
> @@ -97,6 +105,7 @@ config TARGET_P1010RDB_PB
>  	select BOARD_LATE_INIT if CHAIN_OF_TRUST
>  	select SUPPORT_SPL
>  	select SUPPORT_TPL
> +	select CMD_MAC
>  	imply CMD_EEPROM
>  	imply CMD_SATA
>  	imply PANIC_HANG
> @@ -133,6 +142,7 @@ config TARGET_P2041RDB
>  	select ARCH_P2041
>  	select BOARD_LATE_INIT if CHAIN_OF_TRUST
>  	select PHYS_64BIT
> +	select CMD_MAC
>  	imply CMD_SATA
>  	imply FSL_SATA
>  
> @@ -148,6 +158,7 @@ config TARGET_T1023RDB
>  	select SUPPORT_SPL
>  	select PHYS_64BIT
>  	select FSL_DDR_INTERACTIVE
> +	select CMD_MAC
>  	imply CMD_EEPROM
>  	imply PANIC_HANG
>  
> @@ -158,6 +169,7 @@ config TARGET_T1024RDB
>  	select SUPPORT_SPL
>  	select PHYS_64BIT
>  	select FSL_DDR_INTERACTIVE
> +	select CMD_MAC
>  	imply CMD_EEPROM
>  	imply PANIC_HANG
>  
> @@ -213,6 +225,7 @@ config TARGET_T2080QDS
>  	select PHYS_64BIT
>  	select FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
>  	select FSL_DDR_INTERACTIVE
> +	select CMD_MAC
>  	imply CMD_SATA
>  
>  config TARGET_T2080RDB
> @@ -221,6 +234,7 @@ config TARGET_T2080RDB
>  	select BOARD_LATE_INIT if CHAIN_OF_TRUST
>  	select SUPPORT_SPL
>  	select PHYS_64BIT
> +	select CMD_MAC
>  	imply CMD_SATA
>  	imply PANIC_HANG
>  
> @@ -231,6 +245,7 @@ config TARGET_T2081QDS
>  	select PHYS_64BIT
>  	select FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
>  	select FSL_DDR_INTERACTIVE
> +	select CMD_MAC
>  
>  config TARGET_T4160RDB
>  	bool "Support T4160RDB"
> @@ -280,12 +295,14 @@ config TARGET_CYRUS_P5020
>  	bool "Support Varisys Cyrus P5020"
>  	select ARCH_P5020
>  	select PHYS_64BIT
> +	select CMD_MAC
>  	imply PANIC_HANG
>  
>  config TARGET_CYRUS_P5040
>  	 bool "Support Varisys Cyrus P5040"
>  	select ARCH_P5040
>  	select PHYS_64BIT
> +	select CMD_MAC
>  	imply PANIC_HANG
>  
>  endchoice
> diff --git a/cmd/Kconfig b/cmd/Kconfig
> index 1595de999b5..652e9cc4f88 100644
> --- a/cmd/Kconfig
> +++ b/cmd/Kconfig
> @@ -1696,6 +1696,9 @@ config CMD_LED
>  	  with led on/off/togle/blink. Any LED drivers can be controlled with
>  	  this command, e.g. led_gpio.
>  
> +config CMD_MAC
> +	bool
> +
>  config CMD_DATE
>  	bool "date"
>  	default y if DM_RTC
> diff --git a/cmd/Makefile b/cmd/Makefile
> index dd86675bf2a..9d85217b544 100644
> --- a/cmd/Makefile
> +++ b/cmd/Makefile
> @@ -88,7 +88,7 @@ obj-$(CONFIG_CMD_LICENSE) += license.o
>  obj-y += load.o
>  obj-$(CONFIG_CMD_LOG) += log.o
>  obj-$(CONFIG_CMD_LSBLK) += lsblk.o
> -obj-$(CONFIG_ID_EEPROM) += mac.o
> +obj-$(CONFIG_CMD_MAC) += mac.o
>  obj-$(CONFIG_CMD_MD5SUM) += md5sum.o
>  obj-$(CONFIG_CMD_MEMORY) += mem.o
>  obj-$(CONFIG_CMD_IO) += io.o
-- 
- Daniel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC 05/20] ns16550: Turn on the UME bit if on ARCH_JZ47XX
  2020-11-17 21:00 ` [PATCH RFC 05/20] ns16550: Turn on the UME bit if on ARCH_JZ47XX Lubomir Rintel
@ 2020-11-17 22:29   ` Daniel Schwierzeck
  2020-11-18  6:55     ` Lubomir Rintel
  0 siblings, 1 reply; 26+ messages in thread
From: Daniel Schwierzeck @ 2020-11-17 22:29 UTC (permalink / raw)
  To: u-boot

Am Dienstag, den 17.11.2020, 22:00 +0100 schrieb Lubomir Rintel:
> The jz47xx serial port is essentially a ns16550 with an extra bit that
> needs to be turned on. The driver already takes care of it, but not in
> the early debug config path.
> 
> Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
> ---
>  drivers/serial/ns16550.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
> index 702109b23b6..0cf667c2731 100644
> --- a/drivers/serial/ns16550.c
> +++ b/drivers/serial/ns16550.c
> @@ -326,6 +326,7 @@ static inline void _debug_uart_init(void)
>  {
>  	struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
>  	int baud_divisor;
> +	int fcr = UART_FCR_DEFVAL;
>  
>  	/*
>  	 * We copy the code from above because it is already horribly messy.
> @@ -335,9 +336,13 @@ static inline void _debug_uart_init(void)
>  	 */
>  	baud_divisor = ns16550_calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK,
>  					    CONFIG_BAUDRATE);
> +
> +	if (IS_ENABLED(CONFIG_ARCH_JZ47XX))
> +		fcr |= UART_FCR_UME;

do you use that driver without CONFIG_OF_CONTROL?

There is already code for UME bit on JS4780 when you use the compatible
"ingenic,jz4780-uart":

	plat->fcr = UART_FCR_DEFVAL;
	if (port_type == PORT_JZ4780)
		plat->fcr |= UART_FCR_UME;

> +
>  	serial_dout(&com_port->ier, CONFIG_SYS_NS16550_IER);
>  	serial_dout(&com_port->mcr, UART_MCRVAL);
> -	serial_dout(&com_port->fcr, UART_FCR_DEFVAL);
> +	serial_dout(&com_port->fcr, fcr);
>  
>  	serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL);
>  	serial_dout(&com_port->dll, baud_divisor & 0xff);
-- 
- Daniel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC 12/20] pinctrl: Add Ingenic JZ4730 pin control and GPIO driver
  2020-11-17 21:00 ` [PATCH RFC 12/20] pinctrl: Add Ingenic JZ4730 pin control and GPIO driver Lubomir Rintel
@ 2020-11-17 22:39   ` Daniel Schwierzeck
  0 siblings, 0 replies; 26+ messages in thread
From: Daniel Schwierzeck @ 2020-11-17 22:39 UTC (permalink / raw)
  To: u-boot

Am Dienstag, den 17.11.2020, 22:00 +0100 schrieb Lubomir Rintel:
> This is a fairly minimal driver for the pin controller on JZ4730 SoC.
> 
> Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
> ---
>  drivers/pinctrl/Kconfig          |   8 +
>  drivers/pinctrl/Makefile         |   1 +
>  drivers/pinctrl/pinctrl-jz4730.c | 346 +++++++++++++++++++++++++++++++
>  3 files changed, 355 insertions(+)
>  create mode 100644 drivers/pinctrl/pinctrl-jz4730.c
> 
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 77fb8511144..3bd9552d931 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -177,6 +177,14 @@ config PINCTRL_AT91PIO4
>  	  This option is to enable the AT91 pinctrl driver for AT91 PIO4
>  	  controller which is available on SAMA5D2 SoC.
>  
> +config PINCTRL_JZ4730
> +	bool "Ingenic JZ4730 pinctrl driver"
> +	depends on DM && SOC_JZ4730
> +	default y
> +	help
> +	  This option is to enable the driver for pinctrl and GPIO
> +	  controller which is available on Ingenic JZ4730 SoC.
> +
>  config PINCTRL_INTEL
>  	bool "Standard Intel pin-control and pin-mux driver"
>  	help
> diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> index 05b71f2f134..27d0ac7735f 100644
> --- a/drivers/pinctrl/Makefile
> +++ b/drivers/pinctrl/Makefile
> @@ -5,6 +5,7 @@ obj-$(CONFIG_$(SPL_)PINCTRL_GENERIC)	+= pinctrl-generic.o
>  
>  obj-$(CONFIG_PINCTRL_AT91)		+= pinctrl-at91.o
>  obj-$(CONFIG_PINCTRL_AT91PIO4)		+= pinctrl-at91-pio4.o
> +obj-$(CONFIG_PINCTRL_JZ4730)		+= pinctrl-jz4730.o
>  obj-y					+= nxp/
>  obj-$(CONFIG_$(SPL_)PINCTRL_ROCKCHIP)	+= rockchip/
>  obj-$(CONFIG_ARCH_ASPEED) += aspeed/
> diff --git a/drivers/pinctrl/pinctrl-jz4730.c b/drivers/pinctrl/pinctrl-jz4730.c
> new file mode 100644
> index 00000000000..1b69ecf17f1
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-jz4730.c
> @@ -0,0 +1,346 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * JZ4730 Pin control and GPIO driver.
> + *
> + * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
> + */
> +
> +#include <common.h>

don't use common.h in new code and just include the required header
files

> +#include <dm.h>
> +#include <dm/device-internal.h>
> +#include <dm/pinctrl.h>
> +#include <asm/gpio.h>
> +#include <asm/io.h>
> +
> +#define PINCTRL_DR(n)	(0x00 + (n) * 0x30)
> +#define PINCTRL_DIR(n)	(0x04 + (n) * 0x30)
> +#define PINCTRL_ODR(n)	(0x08 + (n) * 0x30)
> +#define PINCTRL_PUR(n)	(0x0c + (n) * 0x30)
> +#define PINCTRL_ALR(n)	(0x10 + (n) * 0x30)
> +#define PINCTRL_AUR(n)	(0x14 + (n) * 0x30)
> +#define PINCTRL_IDLR(n)	(0x18 + (n) * 0x30)
> +#define PINCTRL_IDUR(n)	(0x1c + (n) * 0x30)
> +#define PINCTRL_IER(n)	(0x20 + (n) * 0x30)
> +#define PINCTRL_IMR(n)	(0x24 + (n) * 0x30)
> +#define PINCTRL_FR(n)	(0x28 + (n) * 0x30)
> +
> +struct jz4730_pinctrl_priv {
> +	void __iomem *base;
> +};
> +
> +struct jz4730_gpio_priv {
> +	unsigned int bank;
> +};
> +
> +static int jz4730_gpio_get_value(struct udevice *dev, unsigned int offset)
> +{
> +	struct jz4730_gpio_priv *priv = dev_get_priv(dev);
> +	struct jz4730_pinctrl_priv *pc_priv = dev_get_priv(dev->parent);
> +
> +	return !!(readl(pc_priv->base + PINCTRL_DR(priv->bank)) & BIT(offset));
> +}
> +
> +static int jz4730_gpio_set_value(struct udevice *dev, unsigned int offset, int value)
> +{
> +	struct jz4730_gpio_priv *priv = dev_get_priv(dev);
> +	struct jz4730_pinctrl_priv *pc_priv = dev_get_priv(dev->parent);
> +	u32 gpdr = readl(pc_priv->base + PINCTRL_DR(priv->bank));
> +
> +	if (value)
> +		gpdr |= BIT(offset);
> +	else
> +		gpdr &= ~BIT(offset);
> +	writel(gpdr, pc_priv->base + PINCTRL_DR(priv->bank));
> +
> +	return 0;
> +}
> +
> +static int jz4730_gpio_get_direction(struct udevice *dev, unsigned int offset)
> +{
> +	struct jz4730_gpio_priv *priv = dev_get_priv(dev);
> +	struct jz4730_pinctrl_priv *pc_priv = dev_get_priv(dev->parent);
> +
> +	if (offset < 16) {
> +		if (readl(pc_priv->base + PINCTRL_ALR(priv->bank)) & (3 << (offset * 2)))
> +			return GPIOF_FUNC;
> +	} else {
> +		if (readl(pc_priv->base + PINCTRL_AUR(priv->bank)) & (3 << ((offset - 16) * 2)))
> +			return GPIOF_FUNC;
> +	}
> +	if (readl(pc_priv->base + PINCTRL_DIR(priv->bank)) & BIT(offset))
> +		return GPIOF_OUTPUT;
> +
> +	return GPIOF_INPUT;
> +}
> +
> +static int jz4730_gpio_direction_input(struct udevice *dev, unsigned int offset)
> +{
> +	struct jz4730_gpio_priv *priv = dev_get_priv(dev);
> +	struct jz4730_pinctrl_priv *pc_priv = dev_get_priv(dev->parent);
> +
> +	clrbits_32(pc_priv->base + PINCTRL_IER(priv->bank), BIT(offset));
> +	clrbits_32(pc_priv->base + PINCTRL_DIR(priv->bank), BIT(offset));
> +	if (offset < 16)
> +		clrbits_32(pc_priv->base + PINCTRL_ALR(priv->bank), (3 << (offset << 1)));
> +	else
> +		clrbits_32(pc_priv->base + PINCTRL_AUR(priv->bank), (3 << ((offset - 16) << 1)));
> +
> +	return 0;
> +}
> +
> +static int jz4730_gpio_direction_output(struct udevice *dev, unsigned int offset, int value)
> +{
> +	struct jz4730_gpio_priv *priv = dev_get_priv(dev);
> +	struct jz4730_pinctrl_priv *pc_priv = dev_get_priv(dev->parent);
> +
> +	jz4730_gpio_set_value(dev, offset, value);
> +
> +	clrbits_32(pc_priv->base + PINCTRL_IER(priv->bank), BIT(offset));
> +	setbits_32(pc_priv->base + PINCTRL_DIR(priv->bank), BIT(offset));
> +	if (offset < 16)
> +		clrbits_32(pc_priv->base + PINCTRL_ALR(priv->bank), (3 << (offset << 1)));
> +	else
> +		clrbits_32(pc_priv->base + PINCTRL_AUR(priv->bank), (3 << ((offset - 16) << 1)));
> +
> +	return 0;
> +}
> +
> +static int jz4730_gpio_probe(struct udevice *dev)
> +{
> +	struct jz4730_gpio_priv *priv = dev_get_priv(dev);
> +	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> +	int ret;
> +
> +	ret = ofnode_read_u32(dev_ofnode(dev), "reg", &priv->bank);

you shoud prefer dev_read_u32() respectively the API
in include/dm/read.h

> +	if (ret)
> +		return ret;
> +
> +	uc_priv->bank_name  = strdup(dev->name);
> +	uc_priv->gpio_count = 32;
> +	return 0;
> +}
> +
> +static const struct dm_gpio_ops jz4730_gpio_ops = {
> +	.set_value = jz4730_gpio_set_value,
> +	.get_value = jz4730_gpio_get_value,
> +	.get_function = jz4730_gpio_get_direction,
> +	.direction_input = jz4730_gpio_direction_input,
> +	.direction_output = jz4730_gpio_direction_output,
> +};
> +
> +static struct driver jz4730_gpio_driver = {
> +	.name = "jz4730-gpio",
> +	.id = UCLASS_GPIO,
> +	.probe = jz4730_gpio_probe,
> +	.priv_auto_alloc_size = sizeof(struct jz4730_gpio_priv),
> +	.ops = &jz4730_gpio_ops,
> +};
> +
> +static const char * const pin_names[] = {
> +	"PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7",
> +	"PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15",
> +	"PA16", "PA17", "PA18", "PA19", "PA20", "PA21", "PA22", "PA23",
> +	"PA24", "PA25", "PA26", "PA27", "PA28", "PA29", "PA30", "PA31",
> +	"PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7",
> +	"PB8", "PB9", "PB10", "PB11", "PB12", "PB13", "PB14", "PB15",
> +	"PB16", "PB17", "PB18", "PB19", "PB20", "PB21", "PB22", "PB23",
> +	"PB24", "PB25", "PB26", "PB27", "PB28", "PB29", "PB30", "PB31",
> +	"PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6", "PC7",
> +	"PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", "PC15",
> +	"PC16", "PC17", "PC18", "PC19", "PC20", "PC21", "PC22", "PC23",
> +	"PC24", "PC25", "PC26", "PC27", "PC28", "PC29", "PC30", "PC31",
> +	"PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7",
> +	"PD8", "PD9", "PD10", "PD11", "PD12", "PD13", "PD14", "PD15",
> +	"PD16", "PD17", "PD18", "PD19", "PD20", "PD21", "PD22", "PD23",
> +	"PD24", "PD25", "PD26", "PD27", "PD28", "PD29", "PD30", "PD31",
> +};
> +
> +static int jz4730_pinctrl_get_pins_count(struct udevice *dev)
> +{
> +	return ARRAY_SIZE(pin_names);
> +}
> +
> +static const char *jz4730_pinctrl_get_pin_name(struct udevice *dev,
> +					       unsigned int selector)
> +{
> +	return pin_names[selector];
> +}
> +
> +static const struct {
> +	const char *name;
> +	struct { u32 gpalr, gpaur; } mask[4];
> +} groups[] = {
> +	{ "lcd-16bit",		{ { 0, }, { 0x00000000, 0x00c0ffff }, { 0, }, { 0, 0, } } },
> +	{ "lcd-16bit-tft",	{ { 0, }, { 0x00000000, 0xff000000 }, { 0, }, { 0, 0, } } },
> +	{ "lcd-8bit",		{ { 0, }, { 0xffff0000, 0x003f0000 }, { 0, }, { 0, 0, } } },
> +	{ "lcd-no-pins",	{ { 0, }, { 0, }, { 0, }, { 0, 0, } } },
> +	{ "mac",		{ { 0, }, { 0, }, { 0, }, { 0, 0x03ffffff, } } },
> +	{ "mmc-1bit",		{ { 0, }, { 0x0000f030, 0 }, { 0, }, { 0, 0, } } },
> +	{ "mmc-4bit",		{ { 0, }, { 0x00000fc0, 0 }, { 0, }, { 0, 0, } } },
> +	{ "nand-cs1",		{ { 0, }, { 0, }, { 0, 0x000000c0 }, { 0, 0, } } },
> +	{ "nand-cs2",		{ { 0, }, { 0, }, { 0, 0x00000300 }, { 0, 0, } } },
> +	{ "nand-cs3",		{ { 0, }, { 0, }, { 0, 0x00000c00 }, { 0, 0, } } },
> +	{ "nand-cs4",		{ { 0, }, { 0, }, { 0, 0x00003000 }, { 0, 0, } } },
> +	{ "nand-cs5",		{ { 0, }, { 0, }, { 0, 0x0000c000 }, { 0, 0, } } },
> +	{ "pwm0",		{ { 0, }, { 0, }, { 0, 0x30000000 }, { 0, 0, } } },
> +	{ "pwm1",		{ { 0, }, { 0, }, { 0, 0xc0000000 }, { 0, 0, } } },
> +	{ "uart0-data",		{ { 0, }, { 0, }, { 0, }, { 0, 0xf0000000 } } },
> +};
> +
> +static int jz4730_pinctrl_get_groups_count(struct udevice *dev)
> +{
> +	return ARRAY_SIZE(groups);
> +}
> +
> +static const char *jz4730_pinctrl_get_group_name(struct udevice *dev,
> +						 unsigned int group_selector)
> +{
> +	return groups[group_selector].name;
> +}
> +
> +static const struct {
> +	const char *name;
> +	struct { u32 gpalr, gpaur; } val[4];
> +} funcs[] = {
> +	{ "lcd",	{ { 0, }, { 0x55550000, 0x556a5555 }, { 0, }, { 0, 0, } } },
> +	{ "mac",	{ { 0, }, { 0, }, { 0, }, { 0, 0x01555555, } } },
> +	{ "mmc",	{ { 0, }, { 0x00005550, 0 }, { 0, }, { 0, 0, } } },
> +	{ "nand",	{ { 0, }, { 0, }, { 0, 0x000055c0 }, { 0, 0, } } },
> +	{ "pwm0",	{ { 0, }, { 0, }, { 0, 0x10000000 }, { 0, 0, } } },
> +	{ "pwm1",	{ { 0, }, { 0, }, { 0, 0x40000000 }, { 0, 0, } } },
> +	{ "sleep",	{ { 0, }, { 0, }, { 0, 0 }, { 0, 0, } } },
> +	{ "uart0",	{ { 0, }, { 0, }, { 0, }, { 0, 0x50000000 } } },
> +};
> +
> +static int jz4730_pinctrl_get_funcs_count(struct udevice *dev)
> +{
> +	return ARRAY_SIZE(funcs);
> +}
> +
> +static const char *jz4730_pinctrl_get_func_name(struct udevice *dev,
> +						unsigned int func_selector)
> +{
> +	return funcs[func_selector].name;
> +}
> +
> +static inline void update_bits(void __iomem *reg, u32 mask, u32 val)
> +{
> +	if (mask)
> +		writel((readl(reg) & ~mask) | val, reg);
> +}
> +
> +static int jz4730_pinctrl_set(struct udevice *dev,
> +			      unsigned int selector,
> +			      unsigned int func_selector)
> +{
> +	struct jz4730_pinctrl_priv *priv = dev_get_priv(dev);
> +	int bank = selector / 32;
> +	int pin = selector % 32;
> +
> +	if (pin < 16) {
> +		update_bits(priv->base + PINCTRL_ALR(bank),
> +			    funcs[func_selector].val[bank].gpalr,
> +			    3 << (pin * 2));
> +	} else {
> +		update_bits(priv->base + PINCTRL_AUR(bank),
> +			    funcs[func_selector].val[bank].gpaur,
> +			    3 << ((pin - 16) * 2));
> +	}
> +
> +	return 0;
> +}
> +
> +static int jz4730_pinctrl_group_set(struct udevice *dev,
> +				    unsigned int group_selector,
> +				    unsigned int func_selector)
> +{
> +	struct jz4730_pinctrl_priv *priv = dev_get_priv(dev);
> +	int bank;
> +
> +	for (bank = 0; bank < ARRAY_SIZE(groups[0].mask); bank++) {
> +		update_bits(priv->base + PINCTRL_ALR(bank),
> +			    groups[group_selector].mask[bank].gpalr,
> +			    funcs[func_selector].val[bank].gpalr);
> +		update_bits(priv->base + PINCTRL_AUR(bank),
> +			    groups[group_selector].mask[bank].gpaur,
> +			    funcs[func_selector].val[bank].gpaur);
> +	}
> +
> +	return 0;
> +}
> +
> +const int jz4730_pinctrl_get_pin_muxing(struct udevice *dev,
> +					unsigned int selector,
> +					char *buf, int size)
> +{
> +	struct jz4730_pinctrl_priv *priv = dev_get_priv(dev);
> +	int bank = selector / 32;
> +	int pin = selector % 32;
> +
> +	snprintf(buf, size, "%3d D%d DI%d OD%d PU%d A%d ID%d IE%d IM%d F%d",
> +		 selector,
> +		 (readl(priv->base + PINCTRL_DR(bank)) >> pin) & 1,
> +		 (readl(priv->base + PINCTRL_DIR(bank)) >> pin) & 1,
> +		 (readl(priv->base + PINCTRL_ODR(bank)) >> pin) & 1,
> +		 (readl(priv->base + PINCTRL_PUR(bank)) >> pin) & 1,
> +		 pin < 16
> +			? (readl(priv->base + PINCTRL_ALR(bank)) >> pin * 2) & 3
> +			: (readl(priv->base + PINCTRL_AUR(bank)) >> (pin - 16) * 2) & 3,
> +		 pin < 16
> +			? (readl(priv->base + PINCTRL_IDLR(bank)) >> pin * 2) & 3
> +			: (readl(priv->base + PINCTRL_IDUR(bank)) >> (pin - 16) * 2) & 3,
> +		 (readl(priv->base + PINCTRL_IER(bank)) >> pin) & 1,
> +		 (readl(priv->base + PINCTRL_IMR(bank)) >> pin) & 1,
> +		 (readl(priv->base + PINCTRL_FR(bank)) >> pin) & 1);
> +
> +	return 0;
> +}
> +
> +const struct pinctrl_ops jz4730_pinctrl_ops  = {
> +	.get_pins_count = jz4730_pinctrl_get_pins_count,
> +	.get_pin_name = jz4730_pinctrl_get_pin_name,
> +	.get_groups_count = jz4730_pinctrl_get_groups_count,
> +	.get_group_name = jz4730_pinctrl_get_group_name,
> +	.get_functions_count = jz4730_pinctrl_get_funcs_count,
> +	.get_function_name = jz4730_pinctrl_get_func_name,
> +	.pinmux_set = jz4730_pinctrl_set,
> +	.pinmux_group_set = jz4730_pinctrl_group_set,
> +	.set_state = pinctrl_generic_set_state,
> +	.get_pin_muxing = jz4730_pinctrl_get_pin_muxing,
> +};
> +
> +int jz4730_pinctrl_probe(struct udevice *dev)
> +{
> +	struct jz4730_pinctrl_priv *priv = dev_get_priv(dev);
> +	ofnode node;
> +
> +	priv->base = dev_remap_addr(dev);
> +	if (!priv->base)
> +		return -EINVAL;
> +
> +	dev_for_each_subnode(node, dev) {
> +		struct udevice *cdev;
> +
> +		if (!ofnode_read_bool(node, "gpio-controller"))

you should prefer dev_read_bool()

> +			continue;
> +
> +		device_bind_ofnode(dev, &jz4730_gpio_driver, ofnode_get_name(node),
> +				   priv, node, &cdev);
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct udevice_id jz4730_pinctrl_of_match[] = {
> +	{ .compatible = "ingenic,jz4730-pinctrl", },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(jz4730_pinctrl) = {
> +	.name = "jz4730-pinctrl",
> +	.id = UCLASS_PINCTRL,
> +	.of_match = of_match_ptr(jz4730_pinctrl_of_match),
> +	.probe = jz4730_pinctrl_probe,
> +	.priv_auto_alloc_size = sizeof(struct jz4730_pinctrl_priv),
> +	.ops = &jz4730_pinctrl_ops,
> +};
-- 
- Daniel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC 05/20] ns16550: Turn on the UME bit if on ARCH_JZ47XX
  2020-11-17 22:29   ` Daniel Schwierzeck
@ 2020-11-18  6:55     ` Lubomir Rintel
  0 siblings, 0 replies; 26+ messages in thread
From: Lubomir Rintel @ 2020-11-18  6:55 UTC (permalink / raw)
  To: u-boot

On Tue, Nov 17, 2020 at 11:29:01PM +0100, Daniel Schwierzeck wrote:
> Am Dienstag, den 17.11.2020, 22:00 +0100 schrieb Lubomir Rintel:
> > The jz47xx serial port is essentially a ns16550 with an extra bit that
> > needs to be turned on. The driver already takes care of it, but not in
> > the early debug config path.
> > 
> > Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
> > ---
> >  drivers/serial/ns16550.c | 7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
> > index 702109b23b6..0cf667c2731 100644
> > --- a/drivers/serial/ns16550.c
> > +++ b/drivers/serial/ns16550.c
> > @@ -326,6 +326,7 @@ static inline void _debug_uart_init(void)
> >  {
> >  	struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
> >  	int baud_divisor;
> > +	int fcr = UART_FCR_DEFVAL;
> >  
> >  	/*
> >  	 * We copy the code from above because it is already horribly messy.
> > @@ -335,9 +336,13 @@ static inline void _debug_uart_init(void)
> >  	 */
> >  	baud_divisor = ns16550_calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK,
> >  					    CONFIG_BAUDRATE);
> > +
> > +	if (IS_ENABLED(CONFIG_ARCH_JZ47XX))
> > +		fcr |= UART_FCR_UME;
> 
> do you use that driver without CONFIG_OF_CONTROL?

Yes. This is indeed for the debug uart output only. I needed in SPL which
is too constrained for OF_CONTROL to fit on my board, but I think it
could be used to get debug output very early even if OF_CONTROL is
enabled.

I actually tried to indicate that in the patch description, perhaps I
could reword that somehow to make it clearer.

Thank you
Lubo

> There is already code for UME bit on JS4780 when you use the compatible
> "ingenic,jz4780-uart":
> 
> 	plat->fcr = UART_FCR_DEFVAL;
> 	if (port_type == PORT_JZ4780)
> 		plat->fcr |= UART_FCR_UME;
> 
> > +
> >  	serial_dout(&com_port->ier, CONFIG_SYS_NS16550_IER);
> >  	serial_dout(&com_port->mcr, UART_MCRVAL);
> > -	serial_dout(&com_port->fcr, UART_FCR_DEFVAL);
> > +	serial_dout(&com_port->fcr, fcr);
> >  
> >  	serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL);
> >  	serial_dout(&com_port->dll, baud_divisor & 0xff);
> -- 
> - Daniel
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC 10/20] mmc/jz_mmc: Add a JZ4740 compatible string
  2020-11-17 21:00 ` [PATCH RFC 10/20] mmc/jz_mmc: Add a JZ4740 compatible string Lubomir Rintel
@ 2020-11-18 13:56   ` Ezequiel Garcia
  0 siblings, 0 replies; 26+ messages in thread
From: Ezequiel Garcia @ 2020-11-18 13:56 UTC (permalink / raw)
  To: u-boot

Hi Lubomir,

On Tue, 2020-11-17 at 22:00 +0100, Lubomir Rintel wrote:
> The driver doesn't use the jz4780's extra DMA channels and handles jz4740
> just fine.
> 
> Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
> ---
>  drivers/mmc/jz_mmc.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
> index b33f0850738..d4b9d15ef2e 100644
> --- a/drivers/mmc/jz_mmc.c
> +++ b/drivers/mmc/jz_mmc.c
> @@ -490,6 +490,7 @@ static int jz_mmc_probe(struct udevice *dev)
>  }
>  
>  static const struct udevice_id jz_mmc_ids[] = {
> +	{ .compatible = "ingenic,jz4740-mmc" },

Normally, you don't need to add another compatible
if there's nothing in the implementation to distinguish
them.

However, I'm guessing here you want to add the compatible
so you can support kernel compatibles such as ingenic,jz4740-mmc?

Regards,
Ezequiel

>  	{ .compatible = "ingenic,jz4780-mmc" },
>  	{ }
>  };

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2020-11-18 13:56 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-17 20:59 [PATCH RFC 00/20] MIPS: Add support for JZ4730 and Skytone Alpha 400 Lubomir Rintel
2020-11-17 20:59 ` [PATCH RFC 01/20] config: Remove CONFIG_SYS_ID_EEPROM Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 02/20] mtd: Allow building nand_spl_simple w/o SPL_NAND_ECC Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 03/20] cmd/mac: Don't build unless CONFIG_CMD_MAC is enabled Lubomir Rintel
2020-11-17 22:17   ` Daniel Schwierzeck
2020-11-17 21:00 ` [PATCH RFC 04/20] mips: Don't access CP0_EBASE on JZ47XX Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 05/20] ns16550: Turn on the UME bit if on ARCH_JZ47XX Lubomir Rintel
2020-11-17 22:29   ` Daniel Schwierzeck
2020-11-18  6:55     ` Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 06/20] clk: Add driver for Ingenic JZ4730 CGU Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 07/20] timer-uclass: Tolerate failure to get clock rate in pre_probe Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 08/20] timer: Add Ingenic JZ4730 timer driver Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 09/20] mmc: Default to JZ47XX_MMC=y on ARCH_JZ47XX Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 10/20] mmc/jz_mmc: Add a JZ4740 compatible string Lubomir Rintel
2020-11-18 13:56   ` Ezequiel Garcia
2020-11-17 21:00 ` [PATCH RFC 11/20] mmc/jz_mmc: Support wp-gpio/cd-gpio Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 12/20] pinctrl: Add Ingenic JZ4730 pin control and GPIO driver Lubomir Rintel
2020-11-17 22:39   ` Daniel Schwierzeck
2020-11-17 21:00 ` [PATCH RFC 13/20] nand: Use correct prototype of board_nand_init() with SPL_NAND_SIMPLE Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 14/20] nand/raw: Add Ingenic JZ4730 NAND flash driver Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 15/20] watchdog: Add Ingenic JZ4730 watchdog timer driver Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 16/20] net: Add Ingenic JZ4730 Ethernet driver Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 17/20] mips: dts: Add Ingenic JZ4730 Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 18/20] mips/mach-jz47xx: Add Ingenic JZ4730 support Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 19/20] mips: dts: Add Skytone Alpha 400 Lubomir Rintel
2020-11-17 21:00 ` [PATCH RFC 20/20] board: " Lubomir Rintel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.