mips: jz47xx: Add JZ4780 SoC support
authorPaul Burton <paul.burton@imgtec.com>
Sun, 16 Dec 2018 22:25:22 +0000 (19:25 -0300)
committerDaniel Schwierzeck <daniel.schwierzeck@gmail.com>
Wed, 19 Dec 2018 14:23:01 +0000 (15:23 +0100)
Add initial support for the Ingenic JZ47xx MIPS SoC.

Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Marek Vasut <marex@denx.de>
20 files changed:
MAINTAINERS
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/dts/jz4780.dtsi [new file with mode: 0644]
arch/mips/mach-jz47xx/Kconfig [new file with mode: 0644]
arch/mips/mach-jz47xx/Makefile [new file with mode: 0644]
arch/mips/mach-jz47xx/include/mach/jz4780.h [new file with mode: 0644]
arch/mips/mach-jz47xx/include/mach/jz4780_dram.h [new file with mode: 0644]
arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/Makefile [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/TODO [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/gpio.c [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/jz4780.c [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/pll.c [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/reset.c [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/sdram.c [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/timer.c [new file with mode: 0644]
arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds [new file with mode: 0644]
arch/mips/mach-jz47xx/start.S [new file with mode: 0644]
include/dt-bindings/clock/jz4780-cgu.h [new file with mode: 0644]

index bb0a107db5be1bb15c74c27e1738b9f1442cbbaf..ae825014bda9edd2f5ea80f4be0b7163ac4f2ebc 100644 (file)
@@ -525,6 +525,11 @@ F: board/mscc/
 F:     configs/mscc*
 F:     include/configs/vcoreiii.h
 
+MIPS JZ4780
+M:     Ezequiel Garcia <ezequiel@collabora.com>
+S:     Maintained
+F:     arch/mips/mach-jz47xx/
+
 MMC
 M:     Jaehoon Chung <jh80.chung@samsung.com>
 S:     Maintained
index fe041f0b78bf9fe5799d37379080c7510230e592..194f4f349ed5bbb14f08c6ceee5ae4d2116f9f25 100644 (file)
@@ -93,6 +93,12 @@ config ARCH_MT7620
        select SUPPORTS_LITTLE_ENDIAN
        select SYSRESET
 
+config ARCH_JZ47XX
+       bool "Support Ingenic JZ47xx"
+       select SUPPORT_SPL
+       select OF_CONTROL
+       select DM
+
 config MACH_PIC32
        bool "Support Microchip PIC32"
        select DM
@@ -145,6 +151,7 @@ source "board/qemu-mips/Kconfig"
 source "arch/mips/mach-ath79/Kconfig"
 source "arch/mips/mach-mscc/Kconfig"
 source "arch/mips/mach-bmips/Kconfig"
+source "arch/mips/mach-jz47xx/Kconfig"
 source "arch/mips/mach-pic32/Kconfig"
 source "arch/mips/mach-mt7620/Kconfig"
 
index 124e93fa26c5987390953dd47e7301f057629056..029d290f1e06665869b80efdfe64c3e64047f73a 100644 (file)
@@ -13,6 +13,7 @@ libs-y += arch/mips/lib/
 
 machine-$(CONFIG_ARCH_ATH79) += ath79
 machine-$(CONFIG_ARCH_BMIPS) += bmips
+machine-$(CONFIG_ARCH_JZ47XX) += jz47xx
 machine-$(CONFIG_MACH_PIC32) += pic32
 machine-$(CONFIG_ARCH_MT7620) += mt7620
 machine-$(CONFIG_ARCH_MSCC) += mscc
diff --git a/arch/mips/dts/jz4780.dtsi b/arch/mips/dts/jz4780.dtsi
new file mode 100644 (file)
index 0000000..f62a7a9
--- /dev/null
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <dt-bindings/clock/jz4780-cgu.h>
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "ingenic,jz4780";
+
+       cpuintc: interrupt-controller {
+               #address-cells = <0>;
+               #interrupt-cells = <1>;
+               interrupt-controller;
+               compatible = "mti,cpu-interrupt-controller";
+       };
+
+       intc: interrupt-controller@10001000 {
+               compatible = "ingenic,jz4780-intc";
+               reg = <0x10001000 0x50>;
+
+               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>;
+       };
+
+       cgu: jz4780-cgu@10000000 {
+               compatible = "ingenic,jz4780-cgu";
+               reg = <0x10000000 0x100>;
+
+               clocks = <&ext>, <&rtc>;
+               clock-names = "ext", "rtc";
+
+               #clock-cells = <1>;
+       };
+
+       mmc0: mmc@13450000 {
+               compatible = "ingenic,jz4780-mmc";
+               reg = <0x13450000 0x1000>;
+
+               status = "disabled";
+
+               clocks = <&cgu JZ4780_CLK_MSC0>;
+               clock-names = "mmc";
+       };
+
+       mmc1: mmc@13460000 {
+               compatible = "ingenic,jz4780-mmc";
+               reg = <0x13460000 0x1000>;
+
+               clocks = <&cgu JZ4780_CLK_MSC1>;
+               clock-names = "mmc";
+
+               status = "disabled";
+       };
+
+       uart0: serial@10030000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10030000 0x100>;
+               reg-shift = <2>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <51>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART0>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       uart1: serial@10031000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10031000 0x100>;
+               reg-shift = <2>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <50>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART1>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       uart2: serial@10032000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10032000 0x100>;
+               reg-shift = <2>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <49>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART2>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       uart3: serial@10033000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10033000 0x100>;
+               reg-shift = <2>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <48>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART3>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       uart4: serial@10034000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10034000 0x100>;
+               reg-shift = <2>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <34>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART4>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       nemc: nemc@13410000 {
+               compatible = "ingenic,jz4780-nemc";
+               reg = <0x13410000 0x10000>;
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges = <1 0 0x1b000000 0x1000000
+                         2 0 0x1a000000 0x1000000
+                         3 0 0x19000000 0x1000000
+                         4 0 0x18000000 0x1000000
+                         5 0 0x17000000 0x1000000
+                         6 0 0x16000000 0x1000000>;
+
+               clocks = <&cgu JZ4780_CLK_NEMC>;
+
+               status = "disabled";
+       };
+
+       bch: bch@134d0000 {
+               compatible = "ingenic,jz4780-bch";
+               reg = <0x134d0000 0x10000>;
+
+               clocks = <&cgu JZ4780_CLK_BCH>;
+
+               status = "disabled";
+       };
+};
diff --git a/arch/mips/mach-jz47xx/Kconfig b/arch/mips/mach-jz47xx/Kconfig
new file mode 100644 (file)
index 0000000..cd6944c
--- /dev/null
@@ -0,0 +1,15 @@
+menu "Ingenic JZ47xx platforms"
+       depends on ARCH_JZ47XX
+
+config SYS_SOC
+       default "jz47xx"
+
+config SOC_JZ4780
+       bool
+       select SUPPORTS_LITTLE_ENDIAN
+       select SUPPORTS_CPU_MIPS32_R1
+       select SUPPORTS_CPU_MIPS32_R2
+       help
+         Support for Ingenic JZ4780 family SoCs.
+
+endmenu
diff --git a/arch/mips/mach-jz47xx/Makefile b/arch/mips/mach-jz47xx/Makefile
new file mode 100644 (file)
index 0000000..dbb8229
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+extra-$(CONFIG_SPL_BUILD)      := start.o
+
+obj-$(CONFIG_SOC_JZ4780)       += jz4780/
diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780.h b/arch/mips/mach-jz47xx/include/mach/jz4780.h
new file mode 100644 (file)
index 0000000..4422e50
--- /dev/null
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * JZ4780 definitions
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#ifndef __JZ4780_H__
+#define __JZ4780_H__
+
+/* AHB0 BUS Devices */
+#define DDRC_BASE      0xb3010000
+
+/* AHB2 BUS Devices */
+#define NEMC_BASE      0xb3410000
+#define BCH_BASE       0xb34d0000
+
+/* APB BUS Devices */
+#define CPM_BASE       0xb0000000
+#define TCU_BASE       0xb0002000
+#define WDT_BASE       0xb0002000
+#define GPIO_BASE      0xb0010000
+#define UART0_BASE     0xb0030000
+#define UART1_BASE     0xb0031000
+#define UART2_BASE     0xb0032000
+#define UART3_BASE     0xb0033000
+#define MSC0_BASE      0xb3450000
+#define MSC1_BASE      0xb3460000
+#define MSC2_BASE      0xb3470000
+
+/*
+ * GPIO
+ */
+/* n = 0,1,2,3,4,5 */
+#define GPIO_PXPIN(n)  (0x00 + (n) * 0x100)
+#define GPIO_PXINT(n)  (0x10 + (n) * 0x100)
+#define GPIO_PXINTS(n) (0x14 + (n) * 0x100)
+#define GPIO_PXINTC(n) (0x18 + (n) * 0x100)
+#define GPIO_PXMASK(n) (0x20 + (n) * 0x100)
+#define GPIO_PXMASKS(n)        (0x24 + (n) * 0x100)
+#define GPIO_PXMASKC(n)        (0x28 + (n) * 0x100)
+#define GPIO_PXPAT1(n) (0x30 + (n) * 0x100)
+#define GPIO_PXPAT1S(n)        (0x34 + (n) * 0x100)
+#define GPIO_PXPAT1C(n)        (0x38 + (n) * 0x100)
+#define GPIO_PXPAT0(n) (0x40 + (n) * 0x100)
+#define GPIO_PXPAT0S(n)        (0x44 + (n) * 0x100)
+#define GPIO_PXPAT0C(n)        (0x48 + (n) * 0x100)
+#define GPIO_PXFLG(n)  (0x50 + (n) * 0x100)
+#define GPIO_PXFLGC(n) (0x54 + (n) * 0x100)
+#define GPIO_PXOEN(n)  (0x60 + (n) * 0x100)
+#define GPIO_PXOENS(n) (0x64 + (n) * 0x100)
+#define GPIO_PXOENC(n) (0x68 + (n) * 0x100)
+#define GPIO_PXPEN(n)  (0x70 + (n) * 0x100)
+#define GPIO_PXPENS(n) (0x74 + (n) * 0x100)
+#define GPIO_PXPENC(n) (0x78 + (n) * 0x100)
+#define GPIO_PXDS(n)   (0x80 + (n) * 0x100)
+#define GPIO_PXDSS(n)  (0x84 + (n) * 0x100)
+#define GPIO_PXDSC(n)  (0x88 + (n) * 0x100)
+
+/* PLL setup */
+#define JZ4780_SYS_EXTAL       48000000
+#define JZ4780_SYS_MEM_SPEED   (CONFIG_SYS_MHZ * 1000000)
+#define JZ4780_SYS_MEM_DIV     3
+#define JZ4780_SYS_AUDIO_SPEED (768 * 1000000)
+
+#define JZ4780_APLL_M  1
+#define JZ4780_APLL_N  1
+#define JZ4780_APLL_OD 1
+
+#define JZ4780_MPLL_M  (JZ4780_SYS_MEM_SPEED / JZ4780_SYS_EXTAL * 2)
+#define JZ4780_MPLL_N  2
+#define JZ4780_MPLL_OD 1
+
+#define JZ4780_EPLL_M  (JZ4780_SYS_AUDIO_SPEED * 2 / JZ4780_SYS_EXTAL)
+#define JZ4780_EPLL_N  1
+#define JZ4780_EPLL_OD 2
+
+#define JZ4780_VPLL_M  ((888 * 1000000) * 2 / JZ4780_SYS_EXTAL)
+#define JZ4780_VPLL_N  1
+#define JZ4780_VPLL_OD 2
+
+#ifndef __ASSEMBLY__
+
+u32 sdram_size(int bank);
+
+const u32 jz4780_clk_get_efuse_clk(void);
+void jz4780_clk_ungate_ethernet(void);
+void jz4780_clk_ungate_mmc(void);
+void jz4780_clk_ungate_uart(const unsigned int uart);
+
+void jz4780_efuse_read(size_t addr, size_t count, u8 *buf);
+void jz4780_efuse_init(u32 ahb2_rate);
+
+void jz4780_tcu_wdt_start(void);
+
+#ifdef CONFIG_SPL_BUILD
+int jz_mmc_init(void __iomem *base);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __JZ4780_H__ */
diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h b/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h
new file mode 100644 (file)
index 0000000..92d431b
--- /dev/null
@@ -0,0 +1,456 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * JZ4780 DDR initialization - parameters definitions
+ *
+ * Copyright (c) 2015 Imagination Technologies
+ * Author: Matt Redfearn <matt.redfearn.com>
+ */
+
+#ifndef __JZ4780_DRAM_H__
+#define __JZ4780_DRAM_H__
+
+/*
+ * DDR
+ */
+#define DDRC_ST                                0x0
+#define DDRC_CFG                       0x4
+#define DDRC_CTRL                      0x8
+#define DDRC_LMR                       0xc
+#define DDRC_REFCNT                    0x18
+#define DDRC_DQS                       0x1c
+#define DDRC_DQS_ADJ                   0x20
+#define DDRC_MMAP0                     0x24
+#define DDRC_MMAP1                     0x28
+#define DDRC_MDELAY                    0x2c
+#define DDRC_CKEL                      0x30
+#define DDRC_PMEMCTRL0                 0x54
+#define DDRC_PMEMCTRL1                 0x50
+#define DDRC_PMEMCTRL2                 0x58
+#define DDRC_PMEMCTRL3                 0x5c
+
+#define DDRC_TIMING(n)                 (0x60 + 4 * (n))
+#define DDRC_REMMAP(n)                 (0x9c + 4 * (n))
+
+/*
+ * DDR PHY
+ */
+#define DDR_MEM_PHY_BASE               0x20000000
+#define DDR_PHY_OFFSET                 0x1000
+
+#define DDRP_PIR                       0x4
+#define DDRP_PGCR                      0x8
+#define DDRP_PGSR                      0xc
+
+#define DDRP_PTR0                      0x18
+#define DDRP_PTR1                      0x1c
+#define DDRP_PTR2                      0x20
+
+#define DDRP_ACIOCR                    0x24
+#define DDRP_DXCCR                     0x28
+#define DDRP_DSGCR                     0x2c
+#define DDRP_DCR                       0x30
+
+#define DDRP_DTPR0                     0x34
+#define DDRP_DTPR1                     0x38
+#define DDRP_DTPR2                     0x3c
+#define DDRP_MR0                       0x40
+#define DDRP_MR1                       0x44
+#define DDRP_MR2                       0x48
+#define DDRP_MR3                       0x4c
+
+#define DDRP_ODTCR                     0x50
+#define DDRP_DTAR                      0x54
+#define DDRP_DTDR0                     0x58
+#define DDRP_DTDR1                     0x5c
+
+#define DDRP_DCUAR                     0xc0
+#define DDRP_DCUDR                     0xc4
+#define DDRP_DCURR                     0xc8
+#define DDRP_DCULR                     0xcc
+#define DDRP_DCUGCR                    0xd0
+#define DDRP_DCUTPR                    0xd4
+#define DDRP_DCUSR0                    0xd8
+#define DDRP_DCUSR1                    0xdc
+
+#define DDRP_ZQXCR0(n)                 (0x180 + ((n) * 0x10))
+#define DDRP_ZQXCR1(n)                 (0x184 + ((n) * 0x10))
+#define DDRP_ZQXSR0(n)                 (0x188 + ((n) * 0x10))
+#define DDRP_ZQXSR1(n)                 (0x18c + ((n) * 0x10))
+
+#define DDRP_DXGCR(n)                  (0x1c0 + ((n) * 0x40))
+#define DDRP_DXGSR0(n)                 (0x1c4 + ((n) * 0x40))
+#define DDRP_DXGSR1(n)                 (0x1c8 + ((n) * 0x40))
+#define DDRP_DXDQSTR(n)                        (0x1d4 + ((n) * 0x40))
+
+/* DDRC Status Register */
+#define DDRC_ST_ENDIAN                 BIT(7)
+#define DDRC_ST_DPDN                   BIT(5)
+#define DDRC_ST_PDN                    BIT(4)
+#define DDRC_ST_AREF                   BIT(3)
+#define DDRC_ST_SREF                   BIT(2)
+#define DDRC_ST_CKE1                   BIT(1)
+#define DDRC_ST_CKE0                   BIT(0)
+
+/* DDRC Configure Register */
+#define DDRC_CFG_ROW1_BIT              27
+#define DDRC_CFG_ROW1_MASK             (0x7 << DDRC_CFG_ROW1_BIT)
+#define DDRC_CFG_COL1_BIT              24
+#define DDRC_CFG_COL1_MASK             (0x7 << DDRC_CFG_COL1_BIT)
+#define DDRC_CFG_BA1                   BIT(23)
+#define DDRC_CFG_IMBA                  BIT(22)
+#define DDRC_CFG_BL_8                  BIT(21)
+
+#define DDRC_CFG_TYPE_BIT              17
+#define DDRC_CFG_TYPE_MASK             (0x7 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR1             (2 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_MDDR             (3 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR2             (4 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_LPDDR2           (5 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR3             (6 << DDRC_CFG_TYPE_BIT)
+
+#define DDRC_CFG_ODT_EN                        BIT(16)
+
+#define DDRC_CFG_MPRT                  BIT(15)
+
+#define DDRC_CFG_ROW_BIT               11
+#define DDRC_CFG_ROW_MASK              (0x7 << DDRC_CFG_ROW_BIT)
+#define DDRC_CFG_ROW_12                        (0 << DDRC_CFG_ROW_BIT)
+#define DDRC_CFG_ROW_13                        (1 << DDRC_CFG_ROW_BIT)
+#define DDRC_CFG_ROW_14                        (2 << DDRC_CFG_ROW_BIT)
+
+#define DDRC_CFG_COL_BIT               8
+#define DDRC_CFG_COL_MASK              (0x7 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_8                 (0 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_9                 (1 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_10                        (2 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_11                        (3 << DDRC_CFG_COL_BIT)
+
+#define DDRC_CFG_CS1EN                 BIT(7)
+#define DDRC_CFG_CS0EN                 BIT(6)
+#define DDRC_CFG_CL_BIT                        2
+#define DDRC_CFG_CL_MASK               (0xf << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_3                  (0 << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_4                  (1 << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_5                  (2 << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_6                  (3 << DDRC_CFG_CL_BIT)
+
+#define DDRC_CFG_BA                    BIT(1)
+#define DDRC_CFG_DW                    BIT(0)
+
+/* DDRC Control Register */
+#define DDRC_CTRL_DFI_RST              BIT(23)
+#define DDRC_CTRL_DLL_RST              BIT(22)
+#define DDRC_CTRL_CTL_RST              BIT(21)
+#define DDRC_CTRL_CFG_RST              BIT(20)
+#define DDRC_CTRL_ACTPD                        BIT(15)
+#define DDRC_CTRL_PDT_BIT              12
+#define DDRC_CTRL_PDT_MASK             (0x7 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_DIS              (0 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_8                        (1 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_16               (2 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_32               (3 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_64               (4 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_128              (5 << DDRC_CTRL_PDT_BIT)
+
+#define DDRC_CTRL_PRET_BIT             8
+#define DDRC_CTRL_PRET_MASK            (0x7 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_DIS             (0 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_8               (1 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_16              (2 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_32              (3 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_64              (4 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_128             (5 << DDRC_CTRL_PRET_BIT)
+
+#define DDRC_CTRL_DPD                  BIT(6)
+#define DDRC_CTRL_SR                   BIT(5)
+#define DDRC_CTRL_UNALIGN              BIT(4)
+#define DDRC_CTRL_ALH                  BIT(3)
+#define DDRC_CTRL_RDC                  BIT(2)
+#define DDRC_CTRL_CKE                  BIT(1)
+#define DDRC_CTRL_RESET                        BIT(0)
+
+/* DDRC Load-Mode-Register */
+#define DDRC_LMR_DDR_ADDR_BIT          16
+#define DDRC_LMR_DDR_ADDR_MASK         (0x3fff << DDRC_LMR_DDR_ADDR_BIT)
+
+#define DDRC_LMR_BA_BIT                        8
+#define DDRC_LMR_BA_MASK               (0x7 << DDRC_LMR_BA_BIT)
+/* For DDR2 */
+#define DDRC_LMR_BA_MRS                        (0 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_EMRS1              (1 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_EMRS2              (2 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_EMRS3              (3 << DDRC_LMR_BA_BIT)
+/* For mobile DDR */
+#define DDRC_LMR_BA_M_MRS              (0 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_M_EMRS             (2 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_M_SR               (1 << DDRC_LMR_BA_BIT)
+/* For Normal DDR1 */
+#define DDRC_LMR_BA_N_MRS              (0 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_N_EMRS             (1 << DDRC_LMR_BA_BIT)
+
+#define DDRC_LMR_CMD_BIT               4
+#define DDRC_LMR_CMD_MASK              (0x3 << DDRC_LMR_CMD_BIT)
+#define DDRC_LMR_CMD_PREC              (0 << DDRC_LMR_CMD_BIT)
+#define DDRC_LMR_CMD_AUREF             (1 << DDRC_LMR_CMD_BIT)
+#define DDRC_LMR_CMD_LMR               (2 << DDRC_LMR_CMD_BIT)
+
+#define DDRC_LMR_START                 BIT(0)
+
+/* DDRC Timing Config Register 1 */
+#define DDRC_TIMING1_TRTP_BIT          24
+#define DDRC_TIMING1_TRTP_MASK         (0x3f << DDRC_TIMING1_TRTP_BIT)
+#define DDRC_TIMING1_TWTR_BIT          16
+#define DDRC_TIMING1_TWTR_MASK         (0x3f << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_1            (0 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_2            (1 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_3            (2 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_4            (3 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWR_BIT           8
+#define DDRC_TIMING1_TWR_MASK          (0x3f << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_1             (0 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_2             (1 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_3             (2 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_4             (3 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_5             (4 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_6             (5 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWL_BIT           0
+#define DDRC_TIMING1_TWL_MASK          (0x3f << DDRC_TIMING1_TWL_BIT)
+
+/* DDRC Timing Config Register 2 */
+#define DDRC_TIMING2_TCCD_BIT          24
+#define DDRC_TIMING2_TCCD_MASK         (0x3f << DDRC_TIMING2_TCCD_BIT)
+#define DDRC_TIMING2_TRAS_BIT          16
+#define DDRC_TIMING2_TRAS_MASK         (0x3f << DDRC_TIMING2_TRAS_BIT)
+#define DDRC_TIMING2_TRCD_BIT          8
+#define DDRC_TIMING2_TRCD_MASK         (0x3f << DDRC_TIMING2_TRCD_BIT)
+#define DDRC_TIMING2_TRL_BIT           0
+#define DDRC_TIMING2_TRL_MASK          (0x3f << DDRC_TIMING2_TRL_BIT)
+
+/* DDRC Timing Config Register 3 */
+#define DDRC_TIMING3_ONUM              27
+#define DDRC_TIMING3_TCKSRE_BIT                24
+#define DDRC_TIMING3_TCKSRE_MASK       (0x3f << DDRC_TIMING3_TCKSRE_BIT)
+#define DDRC_TIMING3_TRP_BIT           16
+#define DDRC_TIMING3_TRP_MASK          (0x3f << DDRC_TIMING3_TRP_BIT)
+#define DDRC_TIMING3_TRRD_BIT          8
+#define DDRC_TIMING3_TRRD_MASK         (0x3f << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_DISABLE      (0 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_2            (1 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_3            (2 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_4            (3 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRC_BIT           0
+#define DDRC_TIMING3_TRC_MASK          (0x3f << DDRC_TIMING3_TRC_BIT)
+
+/* DDRC Timing Config Register 4 */
+#define DDRC_TIMING4_TRFC_BIT          24
+#define DDRC_TIMING4_TRFC_MASK         (0x3f << DDRC_TIMING4_TRFC_BIT)
+#define DDRC_TIMING4_TEXTRW_BIT                21
+#define DDRC_TIMING4_TEXTRW_MASK       (0x7 << DDRC_TIMING4_TEXTRW_BIT)
+#define DDRC_TIMING4_TRWCOV_BIT                19
+#define DDRC_TIMING4_TRWCOV_MASK       (0x3 << DDRC_TIMING4_TRWCOV_BIT)
+#define DDRC_TIMING4_TCKE_BIT          16
+#define DDRC_TIMING4_TCKE_MASK         (0x7 << DDRC_TIMING4_TCKE_BIT)
+#define DDRC_TIMING4_TMINSR_BIT                8
+#define DDRC_TIMING4_TMINSR_MASK       (0xf << DDRC_TIMING4_TMINSR_BIT)
+#define DDRC_TIMING4_TXP_BIT           4
+#define DDRC_TIMING4_TXP_MASK          (0x7 << DDRC_TIMING4_TXP_BIT)
+#define DDRC_TIMING4_TMRD_BIT          0
+#define DDRC_TIMING4_TMRD_MASK         (0x3 << DDRC_TIMING4_TMRD_BIT)
+
+/* DDRC Timing Config Register 5 */
+#define DDRC_TIMING5_TCTLUPD_BIT       24
+#define DDRC_TIMING4_TCTLUPD_MASK      (0x3f << DDRC_TIMING5_TCTLUDP_BIT)
+#define DDRC_TIMING5_TRTW_BIT          16
+#define DDRC_TIMING5_TRTW_MASK         (0x3f << DDRC_TIMING5_TRTW_BIT)
+#define DDRC_TIMING5_TRDLAT_BIT                8
+#define DDRC_TIMING5_TRDLAT_MASK       (0x3f << DDRC_TIMING5_TRDLAT_BIT)
+#define DDRC_TIMING5_TWDLAT_BIT                0
+#define DDRC_TIMING5_TWDLAT_MASK       (0x3f << DDRC_TIMING5_TWDLAT_BIT)
+
+/* DDRC Timing Config Register 6 */
+#define DDRC_TIMING6_TXSRD_BIT         24
+#define DDRC_TIMING6_TXSRD_MASK                (0x3f << DDRC_TIMING6_TXSRD_BIT)
+#define DDRC_TIMING6_TFAW_BIT          16
+#define DDRC_TIMING6_TFAW_MASK         (0x3f << DDRC_TIMING6_TFAW_BIT)
+#define DDRC_TIMING6_TCFGW_BIT         8
+#define DDRC_TIMING6_TCFGW_MASK                (0x3f << DDRC_TIMING6_TCFGW_BIT)
+#define DDRC_TIMING6_TCFGR_BIT         0
+#define DDRC_TIMING6_TCFGR_MASK                (0x3f << DDRC_TIMING6_TCFGR_BIT)
+
+/* DDRC  Auto-Refresh Counter */
+#define DDRC_REFCNT_CON_BIT            16
+#define DDRC_REFCNT_CON_MASK           (0xff << DDRC_REFCNT_CON_BIT)
+#define DDRC_REFCNT_CNT_BIT            8
+#define DDRC_REFCNT_CNT_MASK           (0xff << DDRC_REFCNT_CNT_BIT)
+#define DDRC_REFCNT_CLKDIV_BIT         1
+#define DDRC_REFCNT_CLKDIV_MASK                (0x7 << DDRC_REFCNT_CLKDIV_BIT)
+#define DDRC_REFCNT_REF_EN             BIT(0)
+
+/* DDRC DQS Delay Control Register */
+#define DDRC_DQS_ERROR                 BIT(29)
+#define DDRC_DQS_READY                 BIT(28)
+#define DDRC_DQS_AUTO                  BIT(23)
+#define DDRC_DQS_DET                   BIT(24)
+#define DDRC_DQS_SRDET                 BIT(25)
+#define DDRC_DQS_CLKD_BIT              16
+#define DDRC_DQS_CLKD_MASK             (0x3f << DDRC_DQS_CLKD_BIT)
+#define DDRC_DQS_WDQS_BIT              8
+#define DDRC_DQS_WDQS_MASK             (0x3f << DDRC_DQS_WDQS_BIT)
+#define DDRC_DQS_RDQS_BIT              0
+#define DDRC_DQS_RDQS_MASK             (0x3f << DDRC_DQS_RDQS_BIT)
+
+/* DDRC DQS Delay Adjust Register */
+#define DDRC_DQS_ADJWDQS_BIT           8
+#define DDRC_DQS_ADJWDQS_MASK          (0x1f << DDRC_DQS_ADJWDQS_BIT)
+#define DDRC_DQS_ADJRDQS_BIT           0
+#define DDRC_DQS_ADJRDQS_MASK          (0x1f << DDRC_DQS_ADJRDQS_BIT)
+
+/* DDRC Memory Map Config Register */
+#define DDRC_MMAP_BASE_BIT             8
+#define DDRC_MMAP_BASE_MASK            (0xff << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP_MASK_BIT             0
+#define DDRC_MMAP_MASK_MASK            (0xff << DDRC_MMAP_MASK_BIT)
+
+#define DDRC_MMAP0_BASE                        (0x20 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_64M            (0x24 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_128M           (0x28 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_256M           (0x30 << DDRC_MMAP_BASE_BIT)
+
+#define DDRC_MMAP_MASK_64_64           (0xfc << DDRC_MMAP_MASK_BIT)
+#define DDRC_MMAP_MASK_128_128         (0xf8 << DDRC_MMAP_MASK_BIT)
+#define DDRC_MMAP_MASK_256_256         (0xf0 << DDRC_MMAP_MASK_BIT)
+
+/* DDRP PHY Initialization Register */
+#define DDRP_PIR_INIT                  BIT(0)
+#define DDRP_PIR_DLLSRST               BIT(1)
+#define DDRP_PIR_DLLLOCK               BIT(2)
+#define DDRP_PIR_ZCAL                  BIT(3)
+#define DDRP_PIR_ITMSRST               BIT(4)
+#define DDRP_PIR_DRAMRST               BIT(5)
+#define DDRP_PIR_DRAMINT               BIT(6)
+#define DDRP_PIR_QSTRN                 BIT(7)
+#define DDRP_PIR_EYETRN                        BIT(8)
+#define DDRP_PIR_DLLBYP                        BIT(17)
+/* DDRP PHY General Configurate Register */
+#define DDRP_PGCR_ITMDMD               BIT(0)
+#define DDRP_PGCR_DQSCFG               BIT(1)
+#define DDRP_PGCR_DFTCMP               BIT(2)
+#define DDRP_PGCR_DFTLMT_BIT           3
+#define DDRP_PGCR_DTOSEL_BIT           5
+#define DDRP_PGCR_CKEN_BIT             9
+#define DDRP_PGCR_CKDV_BIT             12
+#define DDRP_PGCR_CKINV                        BIT(14)
+#define DDRP_PGCR_RANKEN_BIT           18
+#define DDRP_PGCR_ZCKSEL_32            (2 << 22)
+#define DDRP_PGCR_PDDISDX              BIT(24)
+/* DDRP PHY General Status Register */
+#define DDRP_PGSR_IDONE                        BIT(0)
+#define DDRP_PGSR_DLDONE               BIT(1)
+#define DDRP_PGSR_ZCDONE               BIT(2)
+#define DDRP_PGSR_DIDONE               BIT(3)
+#define DDRP_PGSR_DTDONE               BIT(4)
+#define DDRP_PGSR_DTERR                        BIT(5)
+#define DDRP_PGSR_DTIERR               BIT(6)
+#define DDRP_PGSR_DFTEERR              BIT(7)
+/* DDRP DRAM Configuration Register */
+#define DDRP_DCR_TYPE_BIT              0
+#define DDRP_DCR_TYPE_MASK             (0x7 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_MDDR             (0 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_DDR              (1 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_DDR2             (2 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_DDR3             (3 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_LPDDR2           (4 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_DDR8BNK_BIT           3
+#define DDRP_DCR_DDR8BNK_MASK          (1 << DDRP_DCR_DDR8BNK_BIT)
+#define DDRP_DCR_DDR8BNK               (1 << DDRP_DCR_DDR8BNK_BIT)
+#define DDRP_DCR_DDR8BNK_DIS           (0 << DDRP_DCR_DDR8BNK_BIT)
+
+#define DRP_DTRP1_RTODT                        BIT(11)
+
+#define DDRP_DXGCR_DXEN                        BIT(0)
+
+#define DDRP_ZQXCR_ZDEN_BIT            28
+#define DDRP_ZQXCR_ZDEN                        (1 << DDRP_ZQXCR_ZDEN_BIT)
+#define DDRP_ZQXCR_PULLUP_IMPE_BIT     5
+#define DDRP_ZQXCR_PULLDOWN_IMPE_BIT   0
+
+/* DDR3 Mode Register Set */
+#define DDR3_MR0_BL_BIT                        0
+#define DDR3_MR0_BL_MASK               (3 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BL_8                  (0 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BL_fly                        (1 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BL_4                  (2 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BT_BIT                        3
+#define DDR3_MR0_BT_MASK               (1 << DDR3_MR0_BT_BIT)
+#define DDR3_MR0_BT_SEQ                        (0 << DDR3_MR0_BT_BIT)
+#define DDR3_MR0_BT_INTER              (1 << DDR3_MR0_BT_BIT)
+#define DDR3_MR0_WR_BIT                        9
+
+#define DDR3_MR1_DLL_DISABLE           1
+#define DDR3_MR1_DIC_6                 (0 << 5 | 0 << 1)
+#define DDR3_MR1_DIC_7                 (0 << 5 | BIT(1))
+#define DDR3_MR1_RTT_DIS               (0 << 9 | 0 << 6 | 0 << 2)
+#define DDR3_MR1_RTT_4                 (0 << 9 | 0 << 6 | BIT(2))
+#define DDR3_MR1_RTT_2                 (0 << 9 | BIT(6) | 0 << 2)
+#define DDR3_MR1_RTT_6                 (0 << 9 | BIT(6) | BIT(2))
+#define DDR3_MR1_RTT_12                        (BIT(9) | 0 << 6 | 0 << 2)
+#define DDR3_MR1_RTT_8                 (BIT(9) | 0 << 6 | BIT(2))
+
+#define DDR3_MR2_CWL_BIT               3
+
+/* Parameters common to all RAM devices used */
+
+/* Chip Select */
+/* CSEN : whether a ddr chip exists 0 - un-used, 1 - used */
+#define DDR_CS0EN      1
+/* CSEN : whether a ddr chip exists 0 - un-used, 1 - used */
+#define DDR_CS1EN      0
+
+/* ROW : 12 to 18 row address, 1G only 512MB */
+#define DDR_ROW                15
+/* COL :  8 to 14 column address */
+#define DDR_COL                10
+/* Banks each chip: 0-4bank, 1-8bank */
+#define DDR_BANK8      1
+/* 0 - 16-bit data width, 1 - 32-bit data width */
+#define DDR_DW32       1
+
+/* Refresh period: 64ms / 32768 = 1.95 us , 2 ^ 15 = 32768 */
+#define DDR_tREFI      7800
+/* Clock Divider */
+#define DDR_CLK_DIV    1
+
+/* DDR3 Burst length: 0 - 8 burst, 2 - 4 burst , 1 - 4 or 8 (on the fly) */
+#define DDR_BL         8
+
+/* CAS latency: 5 to 14, tCK */
+#define DDR_CL         6
+/* DDR3 only: CAS Write Latency, 5 to 8 */
+#define DDR_tCWL       (DDR_CL - 1)
+
+/* Structure representing per-RAM type configuration */
+
+struct jz4780_ddr_config {
+       u32     timing[6];      /* Timing1..6 register value */
+
+       /* DDR PHY control */
+       u16     mr0;    /* Mode Register 0 */
+       u16     mr1;    /* Mode Register 1 */
+
+       u32     ptr0;   /* PHY Timing Register 0 */
+       u32     ptr1;   /* PHY Timing Register 1 */
+       u32     ptr2;   /* PHY Timing Register 1 */
+
+       u32     dtpr0;  /* DRAM Timing Parameters Register 0 */
+       u32     dtpr1;  /* DRAM Timing Parameters Register 1 */
+       u32     dtpr2;  /* DRAM Timing Parameters Register 2 */
+
+       u8      pullup; /* PHY pullup impedance */
+       u8      pulldn; /* PHY pulldown impedance */
+};
+
+void pll_init(void);
+void sdram_init(void);
+
+#endif /* __JZ4780_DRAM_H__ */
+
diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h b/arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h
new file mode 100644 (file)
index 0000000..37f0892
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __JZ4780_GPIO_H__
+#define __JZ4780_GPIO_H__
+
+#define JZ_GPIO(bank, pin) ((32 * (bank)) + (pin))
+
+int jz47xx_gpio_get_value(unsigned int gpio);
+void jz47xx_gpio_direction_input(unsigned int gpio);
+void jz47xx_gpio_direction_output(unsigned int gpio, int value);
+
+#endif
diff --git a/arch/mips/mach-jz47xx/jz4780/Makefile b/arch/mips/mach-jz47xx/jz4780/Makefile
new file mode 100644 (file)
index 0000000..5b3c354
--- /dev/null
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y := gpio.o jz4780.o pll.o reset.o sdram.o timer.o
diff --git a/arch/mips/mach-jz47xx/jz4780/TODO b/arch/mips/mach-jz47xx/jz4780/TODO
new file mode 100644 (file)
index 0000000..99ad622
--- /dev/null
@@ -0,0 +1,4 @@
+- dm gpio driver
+- ethernet driver for the dm9000
+- reduce the hundreds of definitions of register addresses to the ones really needed in assembly or SPL.
+- define the remaining register base addresses as physical addresses and establish a mapping with ioremap_nocache()
diff --git a/arch/mips/mach-jz47xx/jz4780/gpio.c b/arch/mips/mach-jz47xx/jz4780/gpio.c
new file mode 100644 (file)
index 0000000..cee2328
--- /dev/null
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+
+int jz47xx_gpio_get_value(unsigned int gpio)
+{
+       void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+       int port = gpio / 32;
+       int pin = gpio % 32;
+
+       return readl(gpio_regs + GPIO_PXPIN(port)) & BIT(pin);
+}
+
+void jz47xx_gpio_direction_input(unsigned int gpio)
+{
+       void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+       int port = gpio / 32;
+       int pin = gpio % 32;
+
+       writel(BIT(pin), gpio_regs + GPIO_PXINTC(port));
+       writel(BIT(pin), gpio_regs + GPIO_PXMASKS(port));
+       writel(BIT(pin), gpio_regs + GPIO_PXPAT1S(port));
+}
+
+void jz47xx_gpio_direction_output(unsigned int gpio, int value)
+{
+       void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+       int port = gpio / 32;
+       int pin = gpio % 32;
+
+       writel(BIT(pin), gpio_regs + GPIO_PXINTC(port));
+       writel(BIT(pin), gpio_regs + GPIO_PXMASKS(port));
+       writel(BIT(pin), gpio_regs + GPIO_PXPAT1C(port));
+       writel(BIT(pin), gpio_regs +
+                        (value ? GPIO_PXPAT0S(port) : GPIO_PXPAT0C(port)));
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/jz4780.c b/arch/mips/mach-jz47xx/jz4780/jz4780.c
new file mode 100644 (file)
index 0000000..dbd328c
--- /dev/null
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 common routines
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/sections.h>
+#include <mach/jz4780.h>
+#include <mach/jz4780_dram.h>
+#include <mmc.h>
+#include <spl.h>
+
+#ifdef CONFIG_SPL_BUILD
+/* Pointer to the global data structure for SPL */
+DECLARE_GLOBAL_DATA_PTR;
+gd_t gdata __attribute__ ((section(".bss")));
+
+void board_init_f(ulong dummy)
+{
+       typedef void __noreturn (*image_entry_noargs_t)(void);
+       struct mmc *mmc;
+       unsigned long count;
+       struct image_header *header;
+       int ret;
+
+       /* Set global data pointer */
+       gd = &gdata;
+
+       timer_init();
+       pll_init();
+       sdram_init();
+       enable_caches();
+
+       /* Clear the BSS */
+       memset(__bss_start, 0, (char *)&__bss_end - __bss_start);
+
+       gd->flags |= GD_FLG_SPL_INIT;
+
+       ret = mmc_initialize(NULL);
+       if (ret)
+               hang();
+
+       mmc = find_mmc_device(BOOT_DEVICE_MMC1);
+       if (ret)
+               hang();
+
+       ret = mmc_init(mmc);
+       if (ret)
+               hang();
+
+       header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
+                                        sizeof(struct image_header));
+
+       count = blk_dread(mmc_get_blk_desc(mmc),
+                         CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
+               0x800, header);
+       if (count == 0)
+               hang();
+
+       image_entry_noargs_t image_entry =
+               (image_entry_noargs_t)CONFIG_SYS_TEXT_BASE;
+
+       image_entry();
+
+       hang();
+}
+#endif /* CONFIG_SPL_BUILD */
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+       return CONFIG_SYS_SDRAM_BASE + (256 * 1024 * 1024);
+}
+
+int print_cpuinfo(void)
+{
+       printf("CPU:   Ingenic JZ4780\n");
+       return 0;
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/pll.c b/arch/mips/mach-jz47xx/jz4780/pll.c
new file mode 100644 (file)
index 0000000..9a46198
--- /dev/null
@@ -0,0 +1,530 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 PLL setup
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+
+#define CPM_CPCCR              0x00
+#define CPM_LCR                        0x04
+#define CPM_RSR                        0x08
+#define CPM_CPPCR              0x0c
+#define CPM_CPAPCR             0x10
+#define CPM_CPMPCR             0x14
+#define CPM_CPEPCR             0x18
+#define CPM_CPVPCR             0x1c
+#define CPM_CLKGR0             0x20
+#define CPM_OPCR               0x24
+#define CPM_CLKGR1             0x28
+#define CPM_DDCDR              0x2c
+#define CPM_VPUCDR             0x30
+#define CPM_CPSPR              0x34
+#define CPM_CPSPPR             0x38
+#define CPM_USBPCR             0x3c
+#define CPM_USBRDT             0x40
+#define CPM_USBVBFIL           0x44
+#define CPM_USBPCR1            0x48
+#define CPM_USBCDR             0x50
+#define CPM_LPCDR              0x54
+#define CPM_I2SCDR             0x60
+#define CPM_LPCDR1             0x64
+#define CPM_MSCCDR             0x68
+#define CPM_UHCCDR             0x6c
+#define CPM_SSICDR             0x74
+#define CPM_CIMCDR             0x7c
+#define CPM_PCMCDR             0x84
+#define CPM_GPUCDR             0x88
+#define CPM_HDMICDR            0x8c
+#define CPM_I2S1CDR            0xa0
+#define CPM_MSCCDR1            0xa4
+#define CPM_MSCCDR2            0xa8
+#define CPM_BCHCDR             0xac
+#define CPM_SPCR0              0xb8
+#define CPM_SPCR1              0xbc
+#define CPM_CPCSR              0xd4
+#define CPM_PSWCST(n)          ((0x4 * (n)) + 0x90)
+
+/* Clock control register */
+#define CPM_CPCCR_SEL_SRC_BIT          30
+#define CPM_CPCCR_SEL_SRC_MASK         (0x3 << CPM_CPCCR_SEL_SRC_BIT)
+#define CPM_SRC_SEL_STOP               0
+#define CPM_SRC_SEL_APLL               1
+#define CPM_SRC_SEL_EXCLK              2
+#define CPM_SRC_SEL_RTCLK              3
+#define CPM_CPCCR_SEL_CPLL_BIT         28
+#define CPM_CPCCR_SEL_CPLL_MASK                (0x3 << CPM_CPCCR_SEL_CPLL_BIT)
+#define CPM_CPCCR_SEL_H0PLL_BIT                26
+#define CPM_CPCCR_SEL_H0PLL_MASK       (0x3 << CPM_CPCCR_SEL_H0PLL_BIT)
+#define CPM_CPCCR_SEL_H2PLL_BIT                24
+#define CPM_CPCCR_SEL_H2PLL_MASK       (0x3 << CPM_CPCCR_SEL_H2PLL_BIT)
+#define CPM_PLL_SEL_STOP               0
+#define CPM_PLL_SEL_SRC                        1
+#define CPM_PLL_SEL_MPLL               2
+#define CPM_PLL_SEL_EPLL               3
+#define CPM_CPCCR_CE_CPU               (0x1 << 22)
+#define CPM_CPCCR_CE_AHB0              (0x1 << 21)
+#define CPM_CPCCR_CE_AHB2              (0x1 << 20)
+#define CPM_CPCCR_PDIV_BIT             16
+#define CPM_CPCCR_PDIV_MASK            (0xf << CPM_CPCCR_PDIV_BIT)
+#define CPM_CPCCR_H2DIV_BIT            12
+#define CPM_CPCCR_H2DIV_MASK           (0xf << CPM_CPCCR_H2DIV_BIT)
+#define CPM_CPCCR_H0DIV_BIT            8
+#define CPM_CPCCR_H0DIV_MASK           (0x0f << CPM_CPCCR_H0DIV_BIT)
+#define CPM_CPCCR_L2DIV_BIT            4
+#define CPM_CPCCR_L2DIV_MASK           (0x0f << CPM_CPCCR_L2DIV_BIT)
+#define CPM_CPCCR_CDIV_BIT             0
+#define CPM_CPCCR_CDIV_MASK            (0x0f << CPM_CPCCR_CDIV_BIT)
+
+/* Clock Status register */
+#define CPM_CPCSR_H2DIV_BUSY           BIT(2)
+#define CPM_CPCSR_H0DIV_BUSY           BIT(1)
+#define CPM_CPCSR_CDIV_BUSY            BIT(0)
+
+/* PLL control register */
+#define CPM_CPPCR_PLLST_BIT            0
+#define CPM_CPPCR_PLLST_MASK           (0xff << CPM_CPPCR_PLLST_BIT)
+
+/* XPLL control register */
+#define CPM_CPXPCR_XPLLM_BIT           19
+#define CPM_CPXPCR_XPLLM_MASK          (0x1fff << CPM_CPXPCR_XPLLM_BIT)
+#define CPM_CPXPCR_XPLLN_BIT           13
+#define CPM_CPXPCR_XPLLN_MASK          (0x3f << CPM_CPXPCR_XPLLN_BIT)
+#define CPM_CPXPCR_XPLLOD_BIT          9
+#define CPM_CPXPCR_XPLLOD_MASK         (0xf << CPM_CPXPCR_XPLLOD_BIT)
+#define CPM_CPXPCR_XLOCK               BIT(6)
+#define CPM_CPXPCR_XPLL_ON             BIT(4)
+#define CPM_CPXPCR_XF_MODE             BIT(3)
+#define CPM_CPXPCR_XPLLBP              BIT(1)
+#define CPM_CPXPCR_XPLLEN              BIT(0)
+
+/* CPM scratch protected register */
+#define CPM_CPSPPR_BIT                 0
+#define CPM_CPSPPR_MASK                        (0xffff << CPM_CPSPPR_BIT)
+
+/* USB parameter control register */
+#define CPM_USBPCR_USB_MODE            BIT(31)  /* 1: OTG, 0: UDC*/
+#define CPM_USBPCR_AVLD_REG            BIT(30)
+#define CPM_USBPCR_IDPULLUP_MASK_BIT   28
+#define CPM_USBPCR_IDPULLUP_MASK_MASK  (0x02 << IDPULLUP_MASK_BIT)
+#define CPM_USBPCR_INCR_MASK           BIT(27)
+#define CPM_USBPCR_CLK12_EN            BIT(26)
+#define CPM_USBPCR_COMMONONN           BIT(25)
+#define CPM_USBPCR_VBUSVLDEXT          BIT(24)
+#define CPM_USBPCR_VBUSVLDEXTSEL       BIT(23)
+#define CPM_USBPCR_POR                 BIT(22)
+#define CPM_USBPCR_SIDDQ               BIT(21)
+#define CPM_USBPCR_OTG_DISABLE         BIT(20)
+#define CPM_USBPCR_COMPDISTUNE_BIT     17
+#define CPM_USBPCR_COMPDISTUNE_MASK    (0x07 << COMPDISTUNE_BIT)
+#define CPM_USBPCR_OTGTUNE_BIT         14
+#define CPM_USBPCR_OTGTUNE_MASK                (0x07 << OTGTUNE_BIT)
+#define CPM_USBPCR_SQRXTUNE_BIT                11
+#define CPM_USBPCR_SQRXTUNE_MASK       (0x7x << SQRXTUNE_BIT)
+#define CPM_USBPCR_TXFSLSTUNE_BIT      7
+#define CPM_USBPCR_TXFSLSTUNE_MASK     (0x0f << TXFSLSTUNE_BIT)
+#define CPM_USBPCR_TXPREEMPHTUNE       BIT(6)
+#define CPM_USBPCR_TXRISETUNE_BIT      4
+#define CPM_USBPCR_TXRISETUNE_MASK     (0x03 << TXRISETUNE_BIT)
+#define CPM_USBPCR_TXVREFTUNE_BIT      0
+#define CPM_USBPCR_TXVREFTUNE_MASK     (0x0f << TXVREFTUNE_BIT)
+
+/* DDR memory clock divider register */
+#define CPM_DDRCDR_DCS_BIT             30
+#define CPM_DDRCDR_DCS_MASK            (0x3 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_DCS_STOP            (0x0 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_DCS_SRC             (0x1 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_DCS_MPLL            (0x2 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_CE_DDR              BIT(29)
+#define CPM_DDRCDR_DDR_BUSY            BIT(28)
+#define CPM_DDRCDR_DDR_STOP            BIT(27)
+#define CPM_DDRCDR_DDRDIV_BIT          0
+#define CPM_DDRCDR_DDRDIV_MASK         (0xf << CPM_DDRCDR_DDRDIV_BIT)
+
+/* USB reset detect timer register */
+#define CPM_USBRDT_VBFIL_LD_EN         BIT(25)
+#define CPM_USBRDT_IDDIG_EN            BIT(24)
+#define CPM_USBRDT_IDDIG_REG           BIT(23)
+#define CPM_USBRDT_USBRDT_BIT          0
+#define CPM_USBRDT_USBRDT_MASK         (0x7fffff << CPM_USBRDT_USBRDT_BIT)
+
+/* USB OTG PHY clock divider register */
+#define CPM_USBCDR_UCS                 BIT(31)
+#define CPM_USBCDR_UPCS                        BIT(30)
+#define CPM_USBCDR_CEUSB               BIT(29)
+#define CPM_USBCDR_USB_BUSY            BIT(28)
+#define CPM_USBCDR_OTGDIV_BIT          0
+#define CPM_USBCDR_OTGDIV_MASK         (0xff << CPM_USBCDR_OTGDIV_BIT)
+
+/* I2S device clock divider register */
+#define CPM_I2SCDR_I2CS                        BIT(31)
+#define CPM_I2SCDR_I2PCS               BIT(30)
+#define CPM_I2SCDR_I2SDIV_BIT          0
+#define CPM_I2SCDR_I2SDIV_MASK         (0x1ff << CPM_I2SCDR_I2SDIV_BIT)
+
+/* LCD0 pix clock divider register */
+#define CPM_LPCDR_LPCS_BIT             30
+#define CPM_LPCDR_LPCS_MASK            (0x3 << CPM_LPCDR_LPCS_BIT)
+#define CPM_LPCDR_CELCD                        BIT(28)
+#define CPM_LPCDR_LCD_BUSY             BIT(27)
+#define CPM_LPCDR_LCD_STOP             BIT(26)
+#define CPM_LPCDR_PIXDIV_BIT           0
+#define CPM_LPCDR_PIXDIV_MASK          (0xff << CPM_LPCDR_PIXDIV_BIT)
+
+/* MSC clock divider register */
+#define CPM_MSCCDR_MPCS_BIT            30
+#define CPM_MSCCDR_MPCS_MASK           (3 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_MPCS_STOP           (0x0 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_MPCS_SRC            (0x1 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_MPCS_MPLL           (0x2 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_CE                  BIT(29)
+#define CPM_MSCCDR_MSC_BUSY            BIT(28)
+#define CPM_MSCCDR_MSC_STOP            BIT(27)
+#define CPM_MSCCDR_MSC_CLK0_SEL                BIT(15)
+#define CPM_MSCCDR_MSCDIV_BIT          0
+#define CPM_MSCCDR_MSCDIV_MASK         (0xff << CPM_MSCCDR_MSCDIV_BIT)
+
+/* UHC 48M clock divider register */
+#define CPM_UHCCDR_UHCS_BIT            30
+#define CPM_UHCCDR_UHCS_MASK           (0x3 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_SRC            (0x0 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_MPLL           (0x1 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_EPLL           (0x2 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_OTG            (0x3 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_CE_UHC              BIT(29)
+#define CPM_UHCCDR_UHC_BUSY            BIT(28)
+#define CPM_UHCCDR_UHC_STOP            BIT(27)
+#define CPM_UHCCDR_UHCDIV_BIT          0
+#define CPM_UHCCDR_UHCDIV_MASK         (0xff << CPM_UHCCDR_UHCDIV_BIT)
+
+/* SSI clock divider register */
+#define CPM_SSICDR_SCS                 BIT(31)
+#define CPM_SSICDR_SSIDIV_BIT          0
+#define CPM_SSICDR_SSIDIV_MASK         (0x3f << CPM_SSICDR_SSIDIV_BIT)
+
+/* CIM MCLK clock divider register */
+#define CPM_CIMCDR_CIMDIV_BIT          0
+#define CPM_CIMCDR_CIMDIV_MASK         (0xff << CPM_CIMCDR_CIMDIV_BIT)
+
+/* GPS clock divider register */
+#define CPM_GPSCDR_GPCS                        BIT(31)
+#define CPM_GPSCDR_GPSDIV_BIT          0
+#define CPM_GSPCDR_GPSDIV_MASK         (0xf << CPM_GPSCDR_GPSDIV_BIT)
+
+/* PCM device clock divider register */
+#define CPM_PCMCDR_PCMS                        BIT(31)
+#define CPM_PCMCDR_PCMPCS              BIT(30)
+#define CPM_PCMCDR_PCMDIV_BIT          0
+#define CPM_PCMCDR_PCMDIV_MASK         (0x1ff << CPM_PCMCDR_PCMDIV_BIT)
+
+/* GPU clock divider register */
+#define CPM_GPUCDR_GPCS                        BIT(31)
+#define CPM_GPUCDR_GPUDIV_BIT          0
+#define CPM_GPUCDR_GPUDIV_MASK         (0x7 << CPM_GPUCDR_GPUDIV_BIT)
+
+/* HDMI clock divider register */
+#define CPM_HDMICDR_HPCS_BIT           30
+#define CPM_HDMICDR_HPCS_MASK          (0x3 << CPM_HDMICDR_HPCS_BIT)
+#define CPM_HDMICDR_CEHDMI             BIT(29)
+#define CPM_HDMICDR_HDMI_BUSY          BIT(28)
+#define CPM_HDMICDR_HDMI_STOP          BIT(26)
+#define CPM_HDMICDR_HDMIDIV_BIT                0
+#define CPM_HDMICDR_HDMIDIV_MASK       (0xff << CPM_HDMICDR_HDMIDIV_BIT)
+
+/* Low Power Control Register */
+#define CPM_LCR_PD_SCPU                        BIT(31)
+#define CPM_LCR_PD_VPU                 BIT(30)
+#define CPM_LCR_PD_GPU                 BIT(29)
+#define CPM_LCR_PD_GPS                 BIT(28)
+#define CPM_LCR_SCPUS                  BIT(27)
+#define CPM_LCR_VPUS                   BIT(26)
+#define CPM_LCR_GPUS                   BIT(25)
+#define CPM_LCR_GPSS                   BIT(24)
+#define CPM_LCR_GPU_IDLE               BIT(20)
+#define CPM_LCR_PST_BIT                        8
+#define CPM_LCR_PST_MASK               (0xfff << CPM_LCR_PST_BIT)
+#define CPM_LCR_DOZE_DUTY_BIT          3
+#define CPM_LCR_DOZE_DUTY_MASK         (0x1f << CPM_LCR_DOZE_DUTY_BIT)
+#define CPM_LCR_DOZE_ON                        BIT(2)
+#define CPM_LCR_LPM_BIT                        0
+#define CPM_LCR_LPM_MASK               (0x3 << CPM_LCR_LPM_BIT)
+#define CPM_LCR_LPM_IDLE               (0x0 << CPM_LCR_LPM_BIT)
+#define CPM_LCR_LPM_SLEEP              (0x1 << CPM_LCR_LPM_BIT)
+
+/* Clock Gate Register0 */
+#define CPM_CLKGR0_DDR1                        BIT(31)
+#define CPM_CLKGR0_DDR0                        BIT(30)
+#define CPM_CLKGR0_IPU                 BIT(29)
+#define CPM_CLKGR0_LCD1                        BIT(28)
+#define CPM_CLKGR0_LCD                 BIT(27)
+#define CPM_CLKGR0_CIM                 BIT(26)
+#define CPM_CLKGR0_I2C2                        BIT(25)
+#define CPM_CLKGR0_UHC                 BIT(24)
+#define CPM_CLKGR0_MAC                 BIT(23)
+#define CPM_CLKGR0_GPS                 BIT(22)
+#define CPM_CLKGR0_PDMAC               BIT(21)
+#define CPM_CLKGR0_SSI2                        BIT(20)
+#define CPM_CLKGR0_SSI1                        BIT(19)
+#define CPM_CLKGR0_UART3               BIT(18)
+#define CPM_CLKGR0_UART2               BIT(17)
+#define CPM_CLKGR0_UART1               BIT(16)
+#define CPM_CLKGR0_UART0               BIT(15)
+#define CPM_CLKGR0_SADC                        BIT(14)
+#define CPM_CLKGR0_KBC                 BIT(13)
+#define CPM_CLKGR0_MSC2                        BIT(12)
+#define CPM_CLKGR0_MSC1                        BIT(11)
+#define CPM_CLKGR0_OWI                 BIT(10)
+#define CPM_CLKGR0_TSSI                        BIT(9)
+#define CPM_CLKGR0_AIC                 BIT(8)
+#define CPM_CLKGR0_SCC                 BIT(7)
+#define CPM_CLKGR0_I2C1                        BIT(6)
+#define CPM_CLKGR0_I2C0                        BIT(5)
+#define CPM_CLKGR0_SSI0                        BIT(4)
+#define CPM_CLKGR0_MSC0                        BIT(3)
+#define CPM_CLKGR0_OTG                 BIT(2)
+#define CPM_CLKGR0_BCH                 BIT(1)
+#define CPM_CLKGR0_NEMC                        BIT(0)
+
+/* Clock Gate Register1 */
+#define CPM_CLKGR1_P1                  BIT(15)
+#define CPM_CLKGR1_X2D                 BIT(14)
+#define CPM_CLKGR1_DES                 BIT(13)
+#define CPM_CLKGR1_I2C4                        BIT(12)
+#define CPM_CLKGR1_AHB                 BIT(11)
+#define CPM_CLKGR1_UART4               BIT(10)
+#define CPM_CLKGR1_HDMI                        BIT(9)
+#define CPM_CLKGR1_OTG1                        BIT(8)
+#define CPM_CLKGR1_GPVLC               BIT(7)
+#define CPM_CLKGR1_AIC1                        BIT(6)
+#define CPM_CLKGR1_COMPRES             BIT(5)
+#define CPM_CLKGR1_GPU                 BIT(4)
+#define CPM_CLKGR1_PCM                 BIT(3)
+#define CPM_CLKGR1_VPU                 BIT(2)
+#define CPM_CLKGR1_TSSI1               BIT(1)
+#define CPM_CLKGR1_I2C3                        BIT(0)
+
+/* Oscillator and Power Control Register */
+#define CPM_OPCR_O1ST_BIT              8
+#define CPM_OPCR_O1ST_MASK             (0xff << CPM_OPCR_O1ST_BIT)
+#define CPM_OPCR_SPENDN                        BIT(7)
+#define CPM_OPCR_GPSEN                 BIT(6)
+#define CPM_OPCR_SPENDH                        BIT(5)
+#define CPM_OPCR_O1SE                  BIT(4)
+#define CPM_OPCR_ERCS                  BIT(2) /* 0: select EXCLK/512 clock, 1: RTCLK clock */
+#define CPM_OPCR_USBM                  BIT(0) /* 0: select EXCLK/512 clock, 1: RTCLK clock */
+
+/* Reset Status Register */
+#define CPM_RSR_P0R                    BIT(2)
+#define CPM_RSR_WR                     BIT(1)
+#define CPM_RSR_PR                     BIT(0)
+
+/* BCH clock divider register */
+#define CPM_BCHCDR_BPCS_BIT            30
+#define CPM_BCHCDR_BPCS_MASK           (0x3 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_STOP           (0X0 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_SRC_CLK                (0x1 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_MPLL           (0x2 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_EPLL           (0x3 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_CE_BCH              BIT(29)
+#define CPM_BCHCDR_BCH_BUSY            BIT(28)
+#define CPM_BCHCDR_BCH_STOP            BIT(27)
+#define CPM_BCHCDR_BCHCDR_BIT          0
+#define CPM_BCHCDR_BCHCDR_MASK         (0x7 << CPM_BCHCDR_BCHCDR_BIT)
+
+/* CPM scratch pad protected register(CPSPPR) */
+#define CPSPPR_CPSPR_WRITABLE          0x00005a5a
+#define RECOVERY_SIGNATURE             0x1a1a  /* means "RECY" */
+#define RECOVERY_SIGNATURE_SEC         0x800   /* means "RECY" */
+
+#define REBOOT_SIGNATURE               0x3535  /* means reboot */
+
+/* XPLL control register */
+#define XLOCK          (1 << 6)
+#define XPLL_ON                (1 << 4)
+#define XF_MODE                (1 << 3)
+#define XPLLBP         (1 << 1)
+#define XPLLEN         (1 << 0)
+
+enum PLLS {
+       EXTCLK = 0,
+       APLL,
+       MPLL,
+       EPLL,
+       VPLL,
+};
+
+#define M_N_OD(m, n, od)               \
+               ((((m) - 1) << 19) | (((n) - 1) << 13) | (((od) - 1) << 9))
+
+struct cgu_pll_select {
+       u8      reg;
+       u8      pll;
+       u8      pll_shift;
+};
+
+static void pll_init_one(int pll, int m, int n, int od)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       void __iomem *pll_reg = cpm_regs + CPM_CPAPCR + ((pll - 1) * 4);
+
+       setbits_le32(pll_reg, M_N_OD(m, n, od) | XPLLEN);
+
+       /* FIXME */
+       while (!(readl(pll_reg) & XPLL_ON))
+               ;
+}
+
+static void cpu_mux_select(int pll)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       u32 clk_ctrl;
+       unsigned int selectplls[] = {
+               CPM_PLL_SEL_STOP,
+               CPM_PLL_SEL_SRC,
+               CPM_PLL_SEL_MPLL,
+               CPM_PLL_SEL_EPLL
+       };
+
+       /* Init CPU, L2CACHE, AHB0, AHB2, APB clock */
+       clk_ctrl = CPM_CPCCR_CE_CPU | CPM_CPCCR_CE_AHB0 | CPM_CPCCR_CE_AHB2 |
+                       ((6 - 1) << CPM_CPCCR_H2DIV_BIT) |
+                       ((3 - 1) << CPM_CPCCR_H0DIV_BIT) |
+                       ((2 - 1) << CPM_CPCCR_L2DIV_BIT) |
+                       ((1 - 1) << CPM_CPCCR_CDIV_BIT);
+
+       if (CONFIG_SYS_MHZ >= 1000)
+               clk_ctrl |= (12 - 1) << CPM_CPCCR_PDIV_BIT;
+       else
+               clk_ctrl |= (6 - 1) << CPM_CPCCR_PDIV_BIT;
+
+       clrsetbits_le32(cpm_regs + CPM_CPCCR, 0x00ffffff, clk_ctrl);
+
+       while (readl(cpm_regs + CPM_CPCSR) & (CPM_CPCSR_CDIV_BUSY |
+              CPM_CPCSR_H0DIV_BUSY | CPM_CPCSR_H2DIV_BUSY))
+               ;
+
+       clk_ctrl = (selectplls[pll] << CPM_CPCCR_SEL_CPLL_BIT) |
+                  (selectplls[MPLL] << CPM_CPCCR_SEL_H0PLL_BIT) |
+                  (selectplls[MPLL] << CPM_CPCCR_SEL_H2PLL_BIT);
+       if (pll == APLL)
+               clk_ctrl |= CPM_PLL_SEL_SRC << CPM_CPCCR_SEL_SRC_BIT;
+       else
+               clk_ctrl |= CPM_SRC_SEL_EXCLK << CPM_CPCCR_SEL_SRC_BIT;
+
+       clrsetbits_le32(cpm_regs + CPM_CPCCR, 0xff << 24, clk_ctrl);
+}
+
+static void ddr_mux_select(int pll)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       int selectplls[] = { CPM_DDRCDR_DCS_STOP,
+                            CPM_DDRCDR_DCS_SRC,
+                            CPM_DDRCDR_DCS_MPLL};
+
+       writel(selectplls[pll] | CPM_DDRCDR_CE_DDR | (JZ4780_SYS_MEM_DIV - 1),
+              cpm_regs + CPM_DDCDR);
+
+       while (readl(cpm_regs + CPM_DDCDR) & CPM_DDRCDR_DDR_BUSY)
+               ;
+
+       clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_DDR0);
+
+       mdelay(200);
+}
+
+static void cgu_mux_init(struct cgu_pll_select *cgu, unsigned int num)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       unsigned int selectplls[] = {0, 1, 2, 3, 2, 6};
+       int i;
+
+       for (i = 0; i < num; i++)
+               writel(selectplls[cgu[i].pll] << cgu[i].pll_shift,
+                      cpm_regs + cgu[i].reg);
+}
+
+void pll_init(void)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       struct cgu_pll_select cgu_mux[] = {
+               { CPM_MSCCDR,  MPLL, 30 },
+               { CPM_LPCDR,   VPLL, 30 },
+               { CPM_LPCDR1,  VPLL, 30 },
+               { CPM_GPUCDR,  MPLL, 30 },
+               { CPM_HDMICDR, VPLL, 30 },
+               { CPM_I2SCDR,  EPLL, 30 },
+               { CPM_BCHCDR,  MPLL, 30 },
+               { CPM_VPUCDR,  0x1,  30 },
+               { CPM_UHCCDR,  0x3,  30 },
+               { CPM_CIMCDR,  0x1,  31 },
+               { CPM_PCMCDR,  0x5,  29 },
+               { CPM_SSICDR,  0x3,  30 },
+       };
+
+       /* PLL stable time set to default -- 1ms */
+       clrsetbits_le32(cpm_regs + CPM_CPPCR, 0xfffff, (16 << 8) | 0x20);
+
+       pll_init_one(APLL, JZ4780_APLL_M, JZ4780_APLL_N, JZ4780_APLL_OD);
+       pll_init_one(MPLL, JZ4780_MPLL_M, JZ4780_MPLL_N, JZ4780_MPLL_OD);
+       pll_init_one(VPLL, JZ4780_VPLL_M, JZ4780_VPLL_N, JZ4780_VPLL_OD);
+       pll_init_one(EPLL, JZ4780_EPLL_M, JZ4780_EPLL_N, JZ4780_EPLL_OD);
+
+       cpu_mux_select(MPLL);
+       ddr_mux_select(MPLL);
+       cgu_mux_init(cgu_mux, ARRAY_SIZE(cgu_mux));
+}
+
+const u32 jz4780_clk_get_efuse_clk(void)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       u32 cpccr = readl(cpm_regs + CPM_CPCCR);
+       u32 ahb2_div = ((cpccr & CPM_CPCCR_H2DIV_MASK) >>
+                       CPM_CPCCR_H2DIV_BIT) + 1;
+       return JZ4780_SYS_MEM_SPEED / ahb2_div;
+}
+
+void jz4780_clk_ungate_ethernet(void)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+
+       clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_MAC);
+       clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_NEMC);
+}
+
+void jz4780_clk_ungate_mmc(void)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       u32 msc_cdr = JZ4780_SYS_MEM_SPEED / 24000000 / 2 - 1;
+
+       msc_cdr |= CPM_MSCCDR_MPCS_MPLL | CPM_MSCCDR_CE;
+       writel(msc_cdr, cpm_regs + CPM_MSCCDR);
+       writel(msc_cdr, cpm_regs + CPM_MSCCDR1);
+       writel(msc_cdr, cpm_regs + CPM_MSCCDR2);
+
+       /* The wait_for_bit() won't fit, thus unbounded loop here. */
+       while (readl(cpm_regs + CPM_MSCCDR1) & CPM_MSCCDR_MSC_BUSY)
+               ;
+}
+
+void jz4780_clk_ungate_uart(const unsigned int uart)
+{
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+
+       if (uart == 0)
+               clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART0);
+       else if (uart == 1)
+               clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART1);
+       else if (uart == 2)
+               clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART2);
+       else if (uart == 3)
+               clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART3);
+       else if (uart == 4)
+               clrbits_le32(cpm_regs + CPM_CLKGR1, CPM_CLKGR1_UART4);
+       else
+               printf("%s[%i]: Invalid UART %d\n", __func__, __LINE__, uart);
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/reset.c b/arch/mips/mach-jz47xx/jz4780/reset.c
new file mode 100644 (file)
index 0000000..73af347
--- /dev/null
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 common routines
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+
+/* WDT */
+#define WDT_TDR                0x00
+#define WDT_TCER       0x04
+#define WDT_TCNT       0x08
+#define WDT_TCSR       0x0C
+
+/* Register definition */
+#define WDT_TCSR_PRESCALE_BIT  3
+#define WDT_TCSR_PRESCALE_MASK (0x7 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE1   (0x0 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE4   (0x1 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE16  (0x2 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE64  (0x3 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE256 (0x4 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE1024        (0x5 << WDT_TCSR_PRESCALE_BIT)
+#define WDT_TCSR_EXT_EN                BIT(2)
+#define WDT_TCSR_RTC_EN                BIT(1)
+#define WDT_TCSR_PCK_EN                BIT(0)
+
+#define WDT_TCER_TCEN          BIT(0)
+
+void _machine_restart(void)
+{
+       void __iomem *wdt_regs = (void __iomem *)WDT_BASE;
+
+       /* EXTAL as the timer clock input. */
+       writew(WDT_TCSR_PRESCALE1 | WDT_TCSR_EXT_EN, wdt_regs + WDT_TCSR);
+
+       /* Reset the WDT counter and timeout. */
+       writew(0, wdt_regs + WDT_TCNT);
+       writew(0, wdt_regs + WDT_TDR);
+
+       jz4780_tcu_wdt_start();
+
+       /* WDT start */
+       writeb(WDT_TCER_TCEN, wdt_regs + WDT_TCER);
+
+       for (;;)
+               ;
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/sdram.c b/arch/mips/mach-jz47xx/jz4780/sdram.c
new file mode 100644 (file)
index 0000000..5b25c8d
--- /dev/null
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 DDR initialization
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * Based on spl/common/{jz4780_ddr,jz_ddr3_init}.c from X-Boot
+ * Copyright (c) 2006-2013 Ingenic Semiconductor
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+#include <mach/jz4780_dram.h>
+
+static const u32 get_mem_clk(void)
+{
+       const u32 mpll_out = ((u64)JZ4780_SYS_EXTAL * JZ4780_MPLL_M) /
+                            (JZ4780_MPLL_N * JZ4780_MPLL_OD);
+       return mpll_out / JZ4780_SYS_MEM_DIV;
+}
+
+u32 sdram_size(int cs)
+{
+       u32 dw = DDR_DW32 ? 4 : 2;
+       u32 banks = DDR_BANK8 ? 8 : 4;
+       u32 size = 0;
+
+       if ((cs == 0) && DDR_CS0EN) {
+               size = (1 << (DDR_ROW + DDR_COL)) * dw * banks;
+               if (DDR_CS1EN && (size > 0x20000000))
+                       size = 0x20000000;
+       } else if ((cs == 1) && DDR_CS1EN) {
+               size = (1 << (DDR_ROW + DDR_COL)) * dw * banks;
+       }
+
+       return size;
+}
+
+static void ddr_cfg_init(void)
+{
+       void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+       u32 ddrc_cfg, tmp;
+
+       tmp = DDR_CL;
+       if (tmp)
+               tmp--;
+       if (tmp > 4)
+               tmp = 4;
+
+       ddrc_cfg = DDRC_CFG_TYPE_DDR3 | DDRC_CFG_IMBA |
+                  DDR_DW32 | DDRC_CFG_MPRT | ((tmp | 0x8) << 2) |
+                  ((DDR_ROW - 12) << 11) | ((DDR_COL - 8) << 8) |
+                  (DDR_CS0EN << 6) | (DDR_BANK8 << 1) |
+                  ((DDR_ROW - 12) << 27) | ((DDR_COL - 8) << 24) |
+                  (DDR_CS1EN << 7) | (DDR_BANK8 << 23);
+
+       if (DDR_BL > 4)
+               ddrc_cfg |= BIT(21);
+
+       writel(ddrc_cfg, ddr_ctl_regs + DDRC_CFG);
+}
+
+static void ddr_phy_init(const struct jz4780_ddr_config *ddr_config)
+{
+       void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+       void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET;
+       unsigned int count = 0, i;
+       u32 reg, mask;
+
+       writel(DDRP_DCR_TYPE_DDR3 | (DDR_BANK8 << 3), ddr_phy_regs + DDRP_DCR);
+
+       writel(ddr_config->mr0, ddr_phy_regs + DDRP_MR0);
+       writel(ddr_config->mr1, ddr_phy_regs + DDRP_MR1);
+       writel(0, ddr_phy_regs + DDRP_ODTCR);
+       writel(0, ddr_phy_regs + DDRP_MR2);
+
+       writel(ddr_config->ptr0, ddr_phy_regs + DDRP_PTR0);
+       writel(ddr_config->ptr1, ddr_phy_regs + DDRP_PTR1);
+       writel(ddr_config->ptr2, ddr_phy_regs + DDRP_PTR2);
+
+       writel(ddr_config->dtpr0, ddr_phy_regs + DDRP_DTPR0);
+       writel(ddr_config->dtpr1, ddr_phy_regs + DDRP_DTPR1);
+       writel(ddr_config->dtpr2, ddr_phy_regs + DDRP_DTPR2);
+
+       writel(DDRP_PGCR_DQSCFG | (7 << DDRP_PGCR_CKEN_BIT) |
+              (2 << DDRP_PGCR_CKDV_BIT) |
+              (DDR_CS0EN | (DDR_CS1EN << 1)) << DDRP_PGCR_RANKEN_BIT |
+              DDRP_PGCR_ZCKSEL_32 | DDRP_PGCR_PDDISDX,
+              ddr_phy_regs + DDRP_PGCR);
+
+       for (i = 0; i < 8; i++)
+               clrbits_le32(ddr_phy_regs + DDRP_DXGCR(i), 0x3 << 9);
+
+       count = 0;
+       mask = DDRP_PGSR_IDONE | DDRP_PGSR_DLDONE | DDRP_PGSR_ZCDONE;
+       for (;;) {
+               reg = readl(ddr_phy_regs + DDRP_PGSR);
+               if ((reg == mask) || (reg == 0x1f))
+                       break;
+               if (count++ == 10000)
+                       hang();
+       }
+
+       /* DQS extension and early set to 1 */
+       clrsetbits_le32(ddr_phy_regs + DDRP_DSGCR, 0x7E << 4, 0x12 << 4);
+
+       /* 500 pull up and 500 pull down */
+       clrsetbits_le32(ddr_phy_regs + DDRP_DXCCR, 0xFF << 4, 0xC4 << 4);
+
+       /* Initialise phy */
+       writel(DDRP_PIR_INIT | DDRP_PIR_DRAMINT | DDRP_PIR_DRAMRST,
+              ddr_phy_regs + DDRP_PIR);
+
+       count = 0;
+       mask |= DDRP_PGSR_DIDONE;
+       for (;;) {
+               reg = readl(ddr_phy_regs + DDRP_PGSR);
+               if ((reg == mask) || (reg == 0x1f))
+                       break;
+               if (count++ == 20000)
+                       hang();
+       }
+
+       writel(DDRP_PIR_INIT | DDRP_PIR_QSTRN, ddr_phy_regs + DDRP_PIR);
+
+       count = 0;
+       mask |= DDRP_PGSR_DTDONE;
+       for (;;) {
+               reg = readl(ddr_phy_regs + DDRP_PGSR);
+               if (reg == mask)
+                       break;
+               if (count++ != 50000)
+                       continue;
+               reg &= DDRP_PGSR_DTDONE | DDRP_PGSR_DTERR | DDRP_PGSR_DTIERR;
+               if (reg)
+                       hang();
+               count = 0;
+       }
+
+       /* Override impedance */
+       clrsetbits_le32(ddr_phy_regs + DDRP_ZQXCR0(0), 0x3ff,
+               ((ddr_config->pullup & 0x1f) << DDRP_ZQXCR_PULLUP_IMPE_BIT) |
+               ((ddr_config->pulldn & 0x1f) << DDRP_ZQXCR_PULLDOWN_IMPE_BIT) |
+               DDRP_ZQXCR_ZDEN);
+}
+
+#define JZBIT(bit) ((bit % 4) * 8)
+#define JZMASK(bit) (0x1f << JZBIT(bit))
+
+static void remap_swap(int a, int b)
+{
+       void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+       u32 remmap[2], tmp[2];
+
+       remmap[0] = readl(ddr_ctl_regs + DDRC_REMMAP(a / 4));
+       remmap[1] = readl(ddr_ctl_regs + DDRC_REMMAP(b / 4));
+
+       tmp[0] = (remmap[0] & JZMASK(a)) >> JZBIT(a);
+       tmp[1] = (remmap[1] & JZMASK(b)) >> JZBIT(b);
+
+       remmap[0] &= ~JZMASK(a);
+       remmap[1] &= ~JZMASK(b);
+
+       writel(remmap[0] | (tmp[1] << JZBIT(a)),
+              ddr_ctl_regs + DDRC_REMMAP(a / 4));
+       writel(remmap[1] | (tmp[0] << JZBIT(b)),
+              ddr_ctl_regs + DDRC_REMMAP(b / 4));
+}
+
+static void mem_remap(void)
+{
+       u32 start = (DDR_ROW + DDR_COL + (DDR_DW32 ? 4 : 2) / 2) - 12;
+       u32 num = DDR_BANK8 ? 3 : 2;
+
+       if (DDR_CS0EN && DDR_CS1EN)
+               num++;
+
+       for (; num > 0; num--)
+               remap_swap(0 + num - 1, start + num - 1);
+}
+
+/* Fetch DRAM config from board file */
+__weak const struct jz4780_ddr_config *jz4780_get_ddr_config(void)
+{
+       return NULL;
+}
+
+void sdram_init(void)
+{
+       const struct jz4780_ddr_config *ddr_config = jz4780_get_ddr_config();
+       void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+       void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET;
+       void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+       u32 mem_clk, tmp, i;
+       u32 mem_base0, mem_base1;
+       u32 mem_mask0, mem_mask1;
+       u32 mem_size0, mem_size1;
+
+       if (!ddr_config)
+               hang();
+
+       /* Reset DLL in DDR PHY */
+       writel(0x3, cpm_regs + 0xd0);
+       mdelay(400);
+       writel(0x1, cpm_regs + 0xd0);
+       mdelay(400);
+
+       /* Enter reset */
+       writel(0xf << 20, ddr_ctl_regs + DDRC_CTRL);
+
+       mem_clk = get_mem_clk();
+
+       tmp = 1000000000 / mem_clk;
+       if (1000000000 % mem_clk)
+               tmp++;
+       tmp = DDR_tREFI / tmp;
+       tmp = tmp / (16 * (1 << DDR_CLK_DIV)) - 1;
+       if (tmp > 0xff)
+               tmp = 0xff;
+       if (tmp < 1)
+               tmp = 1;
+
+       writel(0x0, ddr_ctl_regs + DDRC_CTRL);
+
+       writel(0x150000, ddr_phy_regs + DDRP_DTAR);
+       ddr_phy_init(ddr_config);
+
+       writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL);
+       writel(0x0, ddr_ctl_regs + DDRC_CTRL);
+
+       ddr_cfg_init();
+
+       for (i = 0; i < 6; i++)
+               writel(ddr_config->timing[i], ddr_ctl_regs + DDRC_TIMING(i));
+
+       mem_size0 = sdram_size(0);
+       mem_size1 = sdram_size(1);
+
+       if (!mem_size1 && mem_size0 > 0x20000000) {
+               mem_base0 = 0x0;
+               mem_mask0 = ~(((mem_size0 * 2) >> 24) - 1) & DDRC_MMAP_MASK_MASK;
+       } else {
+               mem_base0 = (DDR_MEM_PHY_BASE >> 24) & 0xff;
+               mem_mask0 = ~((mem_size0 >> 24) - 1) & DDRC_MMAP_MASK_MASK;
+       }
+
+       if (mem_size1) {
+               mem_mask1 = ~((mem_size1 >> 24) - 1) & DDRC_MMAP_MASK_MASK;
+               mem_base1 = ((DDR_MEM_PHY_BASE + mem_size0) >> 24) & 0xff;
+       } else {
+               mem_mask1 = 0;
+               mem_base1 = 0xff;
+       }
+
+       writel(mem_base0 << DDRC_MMAP_BASE_BIT | mem_mask0,
+              ddr_ctl_regs + DDRC_MMAP0);
+       writel(mem_base1 << DDRC_MMAP_BASE_BIT | mem_mask1,
+              ddr_ctl_regs + DDRC_MMAP1);
+       writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL);
+       writel((DDR_CLK_DIV << 1) | DDRC_REFCNT_REF_EN |
+              (tmp << DDRC_REFCNT_CON_BIT),
+              ddr_ctl_regs + DDRC_REFCNT);
+       writel((1 << 15) | (4 << 12) | (1 << 11) | (1 << 8) | (0 << 6) |
+              (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1),
+              ddr_ctl_regs + DDRC_CTRL);
+       mem_remap();
+       clrbits_le32(ddr_ctl_regs + DDRC_ST, 0x40);
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/timer.c b/arch/mips/mach-jz47xx/jz4780/timer.c
new file mode 100644 (file)
index 0000000..a689b9d
--- /dev/null
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * JZ4780 timer
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <div64.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <mach/jz4780.h>
+
+#define TCU_TSR                0x1C    /* Timer Stop Register */
+#define TCU_TSSR       0x2C    /* Timer Stop Set Register */
+#define TCU_TSCR       0x3C    /* Timer Stop Clear Register */
+#define TCU_TER                0x10    /* Timer Counter Enable Register */
+#define TCU_TESR       0x14    /* Timer Counter Enable Set Register */
+#define TCU_TECR       0x18    /* Timer Counter Enable Clear Register */
+#define TCU_TFR                0x20    /* Timer Flag Register */
+#define TCU_TFSR       0x24    /* Timer Flag Set Register */
+#define TCU_TFCR       0x28    /* Timer Flag Clear Register */
+#define TCU_TMR                0x30    /* Timer Mask Register */
+#define TCU_TMSR       0x34    /* Timer Mask Set Register */
+#define TCU_TMCR       0x38    /* Timer Mask Clear Register */
+/* n = 0,1,2,3,4,5 */
+#define TCU_TDFR(n)    (0x40 + (n) * 0x10)     /* Timer Data Full Reg */
+#define TCU_TDHR(n)    (0x44 + (n) * 0x10)     /* Timer Data Half Reg */
+#define TCU_TCNT(n)    (0x48 + (n) * 0x10)     /* Timer Counter Reg */
+#define TCU_TCSR(n)    (0x4C + (n) * 0x10)     /* Timer Control Reg */
+
+#define TCU_OSTCNTL    0xe4
+#define TCU_OSTCNTH    0xe8
+#define TCU_OSTCSR     0xec
+#define TCU_OSTCNTHBUF 0xfc
+
+/* Register definitions */
+#define TCU_TCSR_PWM_SD                BIT(9)
+#define TCU_TCSR_PWM_INITL_HIGH        BIT(8)
+#define TCU_TCSR_PWM_EN                BIT(7)
+#define TCU_TCSR_PRESCALE_BIT  3
+#define TCU_TCSR_PRESCALE_MASK (0x7 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE1     (0x0 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE4     (0x1 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE16    (0x2 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE64    (0x3 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE256   (0x4 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE1024  (0x5 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_EXT_EN                BIT(2)
+#define TCU_TCSR_RTC_EN                BIT(1)
+#define TCU_TCSR_PCK_EN                BIT(0)
+
+#define TCU_TER_TCEN5          BIT(5)
+#define TCU_TER_TCEN4          BIT(4)
+#define TCU_TER_TCEN3          BIT(3)
+#define TCU_TER_TCEN2          BIT(2)
+#define TCU_TER_TCEN1          BIT(1)
+#define TCU_TER_TCEN0          BIT(0)
+
+#define TCU_TESR_TCST5         BIT(5)
+#define TCU_TESR_TCST4         BIT(4)
+#define TCU_TESR_TCST3         BIT(3)
+#define TCU_TESR_TCST2         BIT(2)
+#define TCU_TESR_TCST1         BIT(1)
+#define TCU_TESR_TCST0         BIT(0)
+
+#define TCU_TECR_TCCL5         BIT(5)
+#define TCU_TECR_TCCL4         BIT(4)
+#define TCU_TECR_TCCL3         BIT(3)
+#define TCU_TECR_TCCL2         BIT(2)
+#define TCU_TECR_TCCL1         BIT(1)
+#define TCU_TECR_TCCL0         BIT(0)
+
+#define TCU_TFR_HFLAG5         BIT(21)
+#define TCU_TFR_HFLAG4         BIT(20)
+#define TCU_TFR_HFLAG3         BIT(19)
+#define TCU_TFR_HFLAG2         BIT(18)
+#define TCU_TFR_HFLAG1         BIT(17)
+#define TCU_TFR_HFLAG0         BIT(16)
+#define TCU_TFR_FFLAG5         BIT(5)
+#define TCU_TFR_FFLAG4         BIT(4)
+#define TCU_TFR_FFLAG3         BIT(3)
+#define TCU_TFR_FFLAG2         BIT(2)
+#define TCU_TFR_FFLAG1         BIT(1)
+#define TCU_TFR_FFLAG0         BIT(0)
+
+#define TCU_TFSR_HFLAG5                BIT(21)
+#define TCU_TFSR_HFLAG4                BIT(20)
+#define TCU_TFSR_HFLAG3                BIT(19)
+#define TCU_TFSR_HFLAG2                BIT(18)
+#define TCU_TFSR_HFLAG1                BIT(17)
+#define TCU_TFSR_HFLAG0                BIT(16)
+#define TCU_TFSR_FFLAG5                BIT(5)
+#define TCU_TFSR_FFLAG4                BIT(4)
+#define TCU_TFSR_FFLAG3                BIT(3)
+#define TCU_TFSR_FFLAG2                BIT(2)
+#define TCU_TFSR_FFLAG1                BIT(1)
+#define TCU_TFSR_FFLAG0                BIT(0)
+
+#define TCU_TFCR_HFLAG5                BIT(21)
+#define TCU_TFCR_HFLAG4                BIT(20)
+#define TCU_TFCR_HFLAG3                BIT(19)
+#define TCU_TFCR_HFLAG2                BIT(18)
+#define TCU_TFCR_HFLAG1                BIT(17)
+#define TCU_TFCR_HFLAG0                BIT(16)
+#define TCU_TFCR_FFLAG5                BIT(5)
+#define TCU_TFCR_FFLAG4                BIT(4)
+#define TCU_TFCR_FFLAG3                BIT(3)
+#define TCU_TFCR_FFLAG2                BIT(2)
+#define TCU_TFCR_FFLAG1                BIT(1)
+#define TCU_TFCR_FFLAG0                BIT(0)
+
+#define TCU_TMR_HMASK5         BIT(21)
+#define TCU_TMR_HMASK4         BIT(20)
+#define TCU_TMR_HMASK3         BIT(19)
+#define TCU_TMR_HMASK2         BIT(18)
+#define TCU_TMR_HMASK1         BIT(17)
+#define TCU_TMR_HMASK0         BIT(16)
+#define TCU_TMR_FMASK5         BIT(5)
+#define TCU_TMR_FMASK4         BIT(4)
+#define TCU_TMR_FMASK3         BIT(3)
+#define TCU_TMR_FMASK2         BIT(2)
+#define TCU_TMR_FMASK1         BIT(1)
+#define TCU_TMR_FMASK0         BIT(0)
+
+#define TCU_TMSR_HMST5         BIT(21)
+#define TCU_TMSR_HMST4         BIT(20)
+#define TCU_TMSR_HMST3         BIT(19)
+#define TCU_TMSR_HMST2         BIT(18)
+#define TCU_TMSR_HMST1         BIT(17)
+#define TCU_TMSR_HMST0         BIT(16)
+#define TCU_TMSR_FMST5         BIT(5)
+#define TCU_TMSR_FMST4         BIT(4)
+#define TCU_TMSR_FMST3         BIT(3)
+#define TCU_TMSR_FMST2         BIT(2)
+#define TCU_TMSR_FMST1         BIT(1)
+#define TCU_TMSR_FMST0         BIT(0)
+
+#define TCU_TMCR_HMCL5         BIT(21)
+#define TCU_TMCR_HMCL4         BIT(20)
+#define TCU_TMCR_HMCL3         BIT(19)
+#define TCU_TMCR_HMCL2         BIT(18)
+#define TCU_TMCR_HMCL1         BIT(17)
+#define TCU_TMCR_HMCL0         BIT(16)
+#define TCU_TMCR_FMCL5         BIT(5)
+#define TCU_TMCR_FMCL4         BIT(4)
+#define TCU_TMCR_FMCL3         BIT(3)
+#define TCU_TMCR_FMCL2         BIT(2)
+#define TCU_TMCR_FMCL1         BIT(1)
+#define TCU_TMCR_FMCL0         BIT(0)
+
+#define TCU_TSR_WDTS           BIT(16)
+#define TCU_TSR_STOP5          BIT(5)
+#define TCU_TSR_STOP4          BIT(4)
+#define TCU_TSR_STOP3          BIT(3)
+#define TCU_TSR_STOP2          BIT(2)
+#define TCU_TSR_STOP1          BIT(1)
+#define TCU_TSR_STOP0          BIT(0)
+
+#define TCU_TSSR_WDTSS         BIT(16)
+#define TCU_TSSR_STPS5         BIT(5)
+#define TCU_TSSR_STPS4         BIT(4)
+#define TCU_TSSR_STPS3         BIT(3)
+#define TCU_TSSR_STPS2         BIT(2)
+#define TCU_TSSR_STPS1         BIT(1)
+#define TCU_TSSR_STPS0         BIT(0)
+
+#define TCU_TSSR_WDTSC         BIT(16)
+#define TCU_TSSR_STPC5         BIT(5)
+#define TCU_TSSR_STPC4         BIT(4)
+#define TCU_TSSR_STPC3         BIT(3)
+#define TCU_TSSR_STPC2         BIT(2)
+#define TCU_TSSR_STPC1         BIT(1)
+#define TCU_TSSR_STPC0         BIT(0)
+
+#define TER_OSTEN              BIT(15)
+
+#define OSTCSR_CNT_MD          BIT(15)
+#define OSTCSR_SD              BIT(9)
+#define OSTCSR_PRESCALE_16     (0x2 << 3)
+#define OSTCSR_EXT_EN          BIT(2)
+
+int timer_init(void)
+{
+       void __iomem *regs = (void __iomem *)TCU_BASE;
+
+       writel(OSTCSR_SD, regs + TCU_OSTCSR);
+       reset_timer();
+       writel(OSTCSR_CNT_MD | OSTCSR_EXT_EN | OSTCSR_PRESCALE_16,
+              regs + TCU_OSTCSR);
+       writew(TER_OSTEN, regs + TCU_TESR);
+       return 0;
+}
+
+void reset_timer(void)
+{
+       void __iomem *regs = (void __iomem *)TCU_BASE;
+
+       writel(0, regs + TCU_OSTCNTH);
+       writel(0, regs + TCU_OSTCNTL);
+}
+
+static u64 get_timer64(void)
+{
+       void __iomem *regs = (void __iomem *)TCU_BASE;
+       u32 low = readl(regs + TCU_OSTCNTL);
+       u32 high = readl(regs + TCU_OSTCNTHBUF);
+
+       return ((u64)high << 32) | low;
+}
+
+ulong get_timer(ulong base)
+{
+       return lldiv(get_timer64(), 3000) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+       /* OST count increments at 3MHz */
+       u64 end = get_timer64() + ((u64)usec * 3);
+
+       while (get_timer64() < end)
+               ;
+}
+
+unsigned long long get_ticks(void)
+{
+       return get_timer64();
+}
+
+void jz4780_tcu_wdt_start(void)
+{
+       void __iomem *tcu_regs = (void __iomem *)TCU_BASE;
+
+       /* Enable WDT clock */
+       writel(TCU_TSSR_WDTSC, tcu_regs + TCU_TSCR);
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds b/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds
new file mode 100644 (file)
index 0000000..347cabc
--- /dev/null
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
+               LENGTH = CONFIG_SPL_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+               LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_ARCH(mips)
+ENTRY(_start)
+SECTIONS
+{
+       .text :
+       {
+               __image_copy_start = .;
+               arch/mips/mach-jz47xx/start.o   (.text*)
+               *(.text*)
+       } >.sram
+
+       . = ALIGN(4);
+       .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
+
+       . = ALIGN(4);
+       .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
+
+       . = ALIGN(4);
+       __image_copy_end = .;
+
+       .bss : {
+               . = ALIGN(4);
+               __bss_start = .;
+               *(.sbss.*)
+               *(.bss.*)
+               *(COMMON)
+               . = ALIGN(4);
+               __bss_end = .;
+       } >.sdram
+
+       /DISCARD/ : {
+               *(.dynbss)
+               *(.dynstr)
+               *(.dynamic)
+               *(.interp)
+               *(.hash)
+               *(.gnu.*)
+               *(.plt)
+               *(.got.plt)
+               *(.rel.plt)
+               *(.rel.dyn)
+       }
+}
diff --git a/arch/mips/mach-jz47xx/start.S b/arch/mips/mach-jz47xx/start.S
new file mode 100644 (file)
index 0000000..760d021
--- /dev/null
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  Startup Code for MIPS32 XBURST CPU-core
+ *
+ *  Copyright (c) 2010 Xiangfu Liu <xiangfu@sharism.cc>
+ */
+
+#include <config.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/cacheops.h>
+#include <asm/cache.h>
+#include <mach/jz4780.h>
+
+       .set noreorder
+
+       .globl _start
+       .text
+_start:
+#ifdef CONFIG_SPL_BUILD
+
+       /* magic value ("MSPL") */
+       .word 0x4d53504c
+
+       /* 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
+
+#ifdef CONFIG_SOC_JZ4780
+       /* enable bridge radical mode */
+       la      t0, CPM_BASE
+       lw      t1, 0x24(t0)
+       ori     t1, t1, 0x22
+       sw      t1, 0x24(t0)
+#endif
+
+       /* Set up stack */
+       li      sp, CONFIG_SPL_STACK
+
+       b               board_init_f
+        nop
+
+#ifdef CONFIG_SOC_JZ4780
+
+       .globl enable_caches
+       .ent enable_caches
+enable_caches:
+       mtc0    zero, CP0_TAGLO
+       mtc0    zero, CP0_TAGHI
+
+       li      t0, KSEG0
+       addu    t1, t0, CONFIG_SYS_DCACHE_SIZE
+1:
+       cache   INDEX_STORE_TAG_D, 0(t0)
+       bne     t0, t1, 1b
+       addiu   t0, t0, CONFIG_SYS_CACHELINE_SIZE
+
+       li      t0, KSEG0
+       addu    t1, t0, CONFIG_SYS_ICACHE_SIZE
+2:
+       cache   INDEX_STORE_TAG_I, 0(t0)
+       bne     t0, t1, 2b
+       addiu   t0, t0, CONFIG_SYS_CACHELINE_SIZE
+
+       /* Invalidate BTB */
+       mfc0    t0, CP0_CONFIG, 7
+       nop
+       ori     t0, 2
+       mtc0    t0, CP0_CONFIG, 7
+       nop
+
+       /* Enable caches */
+       li      t0, CONF_CM_CACHABLE_NONCOHERENT
+       mtc0    t0, CP0_CONFIG
+       nop
+
+       jr      ra
+        nop
+
+       .end enable_caches
+
+#endif /* CONFIG_SOC_JZ4780 */
+#endif /* !CONFIG_SPL_BUILD */
diff --git a/include/dt-bindings/clock/jz4780-cgu.h b/include/dt-bindings/clock/jz4780-cgu.h
new file mode 100644 (file)
index 0000000..73214c5
--- /dev/null
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * This header provides clock numbers for the ingenic,jz4780-cgu DT binding.
+ *
+ * They are roughly ordered as:
+ *   - external clocks
+ *   - PLLs
+ *   - muxes/dividers in the order they appear in the jz4780 programmers manual
+ *   - gates in order of their bit in the CLKGR* registers
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
+
+#define JZ4780_CLK_EXCLK       0
+#define JZ4780_CLK_RTCLK       1
+#define JZ4780_CLK_APLL                2
+#define JZ4780_CLK_MPLL                3
+#define JZ4780_CLK_EPLL                4
+#define JZ4780_CLK_VPLL                5
+#define JZ4780_CLK_OTGPHY      6
+#define JZ4780_CLK_SCLKA       7
+#define JZ4780_CLK_CPUMUX      8
+#define JZ4780_CLK_CPU         9
+#define JZ4780_CLK_L2CACHE     10
+#define JZ4780_CLK_AHB0                11
+#define JZ4780_CLK_AHB2PMUX    12
+#define JZ4780_CLK_AHB2                13
+#define JZ4780_CLK_PCLK                14
+#define JZ4780_CLK_DDR         15
+#define JZ4780_CLK_VPU         16
+#define JZ4780_CLK_I2SPLL      17
+#define JZ4780_CLK_I2S         18
+#define JZ4780_CLK_LCD0PIXCLK  19
+#define JZ4780_CLK_LCD1PIXCLK  20
+#define JZ4780_CLK_MSCMUX      21
+#define JZ4780_CLK_MSC0                22
+#define JZ4780_CLK_MSC1                23
+#define JZ4780_CLK_MSC2                24
+#define JZ4780_CLK_UHC         25
+#define JZ4780_CLK_SSIPLL      26
+#define JZ4780_CLK_SSI         27
+#define JZ4780_CLK_CIMMCLK     28
+#define JZ4780_CLK_PCMPLL      29
+#define JZ4780_CLK_PCM         30
+#define JZ4780_CLK_GPU         31
+#define JZ4780_CLK_HDMI                32
+#define JZ4780_CLK_BCH         33
+#define JZ4780_CLK_NEMC                34
+#define JZ4780_CLK_OTG0                35
+#define JZ4780_CLK_SSI0                36
+#define JZ4780_CLK_SMB0                37
+#define JZ4780_CLK_SMB1                38
+#define JZ4780_CLK_SCC         39
+#define JZ4780_CLK_AIC         40
+#define JZ4780_CLK_TSSI0       41
+#define JZ4780_CLK_OWI         42
+#define JZ4780_CLK_KBC         43
+#define JZ4780_CLK_SADC                44
+#define JZ4780_CLK_UART0       45
+#define JZ4780_CLK_UART1       46
+#define JZ4780_CLK_UART2       47
+#define JZ4780_CLK_UART3       48
+#define JZ4780_CLK_SSI1                49
+#define JZ4780_CLK_SSI2                50
+#define JZ4780_CLK_PDMA                51
+#define JZ4780_CLK_GPS         52
+#define JZ4780_CLK_MAC         53
+#define JZ4780_CLK_SMB2                54
+#define JZ4780_CLK_CIM         55
+#define JZ4780_CLK_LCD         56
+#define JZ4780_CLK_TVE         57
+#define JZ4780_CLK_IPU         58
+#define JZ4780_CLK_DDR0                59
+#define JZ4780_CLK_DDR1                60
+#define JZ4780_CLK_SMB3                61
+#define JZ4780_CLK_TSSI1       62
+#define JZ4780_CLK_COMPRESS    63
+#define JZ4780_CLK_AIC1                64
+#define JZ4780_CLK_GPVLC       65
+#define JZ4780_CLK_OTG1                66
+#define JZ4780_CLK_UART4       67
+#define JZ4780_CLK_AHBMON      68
+#define JZ4780_CLK_SMB4                69
+#define JZ4780_CLK_DES         70
+#define JZ4780_CLK_X2D         71
+#define JZ4780_CLK_CORE1       72
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ */