All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] mips: dts: add initial support for ls1c300 SoC
@ 2022-04-18 20:45 Du Huanpeng
  2022-04-22  0:31 ` Sean Anderson
  0 siblings, 1 reply; 4+ messages in thread
From: Du Huanpeng @ 2022-04-18 20:45 UTC (permalink / raw)
  To: u-boot
  Cc: seanga2, daniel.schwierzeck, weijie.gao, jiaxun.yang, lukma, Du Huanpeng

Loongson 1C is a cost-effective SOC chip for industrial control and
the Internet of Things. The Loongson 1C includes a floating-point
processing unit, supports multiple types of memory, and supports
high-capacity MLC NAND Flash. Loongson 1C provides developers with a
wealth of peripheral interfaces and on-chip modules, including Camera
controller, USB OTG and USB HOST interfaces, AC97/I2S controller, LCD
controller, SPI interface, UART interface, etc., providing sufficient
computing power and multi-application connectivity.

Some highlights of this SoC are:
- Single core LS232, MIPS32 instruction set compatible, main frequency
300MHZ
- 16KB data cache and 16KB instruction cache
- 64 bit float unit, hardware division
- 8/16 bit SDRAM controller, 45 ~ 133MHz
- 8/16 bit SRAM, NAND
- I2S/AC97, LCD, MAC, USB, OTG, SPI, I2C, PWM, CAN, SDIO, ADC
- 12 UARTs

See Technical Reference Manual for details: https://www.loongson.cn/

introduce base support for the ls1c300 SoC.
- debug UART2
- serial console
- clock
- watchdog
- sysreset
- many uarts

Signed-off-by: Du Huanpeng <dhu@hodcarrier.org>
---
Changelog for v3:
   - change cpu clock id from CLK_CPU to CLK_CPU_THROT
   - migrate all APB dev's clock id to CLK_APB
   - remove uarts' <reg-shift> property to use default value <0>
   - move /clocks/acc node to /soc/acc
   - call clk_request() before use a clk
   - make get_tbclk() return 1/2 clock of cpu
   - disable debug_uart by default
   - add ops for cpu_throt_factor clk
   - declare MSEC_PER_SEC for converting between sec and msec
   - return a error code when the wdt clock is out of range
   - minor format and codingstyle fixes
   - rebase to [9859465bfe838bc8264d45e1a1bed847bba74bad]

Changelog for v2:
1. dtsi:
	add status disabled for uart0 ~ uart11
	remove bootargs from chosen
	make serial0 alias for uart2
	oscillator remove @0 unit-address
	change uart2 address to kuseg

2. cleanup Kconfig and update defconfig
- make these options configurable, disabled by default:
	CMD_DM
	DM_ETH
	DM_GPIO
	DM_SPI
	DM_SPI_FLASH
	DM_RESET
	PINCONF
	PINCTRL
	PINMUX
	RESET_LSMIPS
- make these options configurable, enabled by default:
	CLK
	DISPLAY_CPUINFO
	SYSRESET
	ROM_EXCEPTION_VECTORS
- disabled:
	CONFIG_ENV_IS_IN_SPI_FLASH

3. fix codingstyle drivers/watchdog/lsmips-wdt.c
- priv->base + offset
- add comment for default clock value

4. remove address base definition header
- remove arch/mips/mach-lsmips/ls1c300/ls1c300.h
- clean up files uses this header

5. spl and debug uart
- add comment for spl & debug uart pinmuxing
- cleanup unused registers base header

6.  dtsi
- add "loongson,ls1c300-uart" to all uart node

7. board dts
- add memory node to board dts, start at 0x80000000, size 64MB

8. Kconfig
- make ROM_EXCEPTION_VECTORS user configureable
- enable ROM_EXCEPTION_VECTORS in defconfig

9.
- seperate sdram_init to sdram_init.S
- add macro helpers to do sdram, pll lowlevel init

10. dtsi
- move clock nodes to /clocks/xxx

11.
- define CONFIG_SKIP_LOWLEVEL_INIT to 1

12.
- remove option PINCTRL_LS1C300 from Kconfig

13.
- dram_init, use get_ram_size() to detect ram size.

14. clk driver
- create custom clock ops for PLL
- remove debug code

15.
- rebase to 59bffec43a657598b194b9eb30dc01eec06078c7
- remove CONFIG_SYS_MONITOR_BASE from include/configs/

> commit e4d741f8abc4a92426d3a826f99390c3abe02d61
> Author: Tom Rini <trini@konsulko.com>
> Date:   Thu Mar 24 17:18:05 2022 -0400
>
>     Convert CONFIG_SYS_MONITOR_BASE to Kconfig


 MAINTAINERS                                   |  13 ++
 arch/mips/Kconfig                             |  11 ++
 arch/mips/Makefile                            |   1 +
 arch/mips/dts/Makefile                        |   1 +
 arch/mips/dts/loongson32-ls1c300b.dtsi        | 141 ++++++++++++++
 arch/mips/dts/ls1c300-eval.dts                |  31 +++
 arch/mips/mach-lsmips/Kconfig                 |  76 ++++++++
 arch/mips/mach-lsmips/Makefile                |   6 +
 arch/mips/mach-lsmips/cpu.c                   |  19 ++
 arch/mips/mach-lsmips/include/mach/serial.h   |  16 ++
 arch/mips/mach-lsmips/ls1c300/Makefile        |   7 +
 arch/mips/mach-lsmips/ls1c300/gpio.c          |  66 +++++++
 arch/mips/mach-lsmips/ls1c300/init.c          |  63 ++++++
 arch/mips/mach-lsmips/ls1c300/lowlevel_init.S | 136 +++++++++++++
 arch/mips/mach-lsmips/ls1c300/sdram.S         |  94 +++++++++
 arch/mips/mach-lsmips/ls1c300/serial.c        | 109 +++++++++++
 arch/mips/mach-lsmips/spl.c                   |  46 +++++
 board/loongson/ls1c300-eval/Kconfig           |  12 ++
 board/loongson/ls1c300-eval/MAINTAINERS       |   7 +
 board/loongson/ls1c300-eval/Makefile          |   3 +
 board/loongson/ls1c300-eval/board.c           |  20 ++
 configs/ls1c300_defconfig                     |  49 +++++
 drivers/clk/Makefile                          |   1 +
 drivers/clk/lsmips/Makefile                   |   3 +
 drivers/clk/lsmips/clk-ls1c300.c              | 180 ++++++++++++++++++
 drivers/watchdog/Kconfig                      |   8 +
 drivers/watchdog/Makefile                     |   1 +
 drivers/watchdog/lsmips_wdt.c                 | 123 ++++++++++++
 include/configs/ls1c300.h                     |  59 ++++++
 include/dt-bindings/clock/ls1c300-clk.h       |  18 ++
 30 files changed, 1320 insertions(+)
 create mode 100644 arch/mips/dts/loongson32-ls1c300b.dtsi
 create mode 100644 arch/mips/dts/ls1c300-eval.dts
 create mode 100644 arch/mips/mach-lsmips/Kconfig
 create mode 100644 arch/mips/mach-lsmips/Makefile
 create mode 100644 arch/mips/mach-lsmips/cpu.c
 create mode 100644 arch/mips/mach-lsmips/include/mach/serial.h
 create mode 100644 arch/mips/mach-lsmips/ls1c300/Makefile
 create mode 100644 arch/mips/mach-lsmips/ls1c300/gpio.c
 create mode 100644 arch/mips/mach-lsmips/ls1c300/init.c
 create mode 100644 arch/mips/mach-lsmips/ls1c300/lowlevel_init.S
 create mode 100644 arch/mips/mach-lsmips/ls1c300/sdram.S
 create mode 100644 arch/mips/mach-lsmips/ls1c300/serial.c
 create mode 100644 arch/mips/mach-lsmips/spl.c
 create mode 100644 board/loongson/ls1c300-eval/Kconfig
 create mode 100644 board/loongson/ls1c300-eval/MAINTAINERS
 create mode 100644 board/loongson/ls1c300-eval/Makefile
 create mode 100644 board/loongson/ls1c300-eval/board.c
 create mode 100644 configs/ls1c300_defconfig
 create mode 100644 drivers/clk/lsmips/Makefile
 create mode 100644 drivers/clk/lsmips/clk-ls1c300.c
 create mode 100644 drivers/watchdog/lsmips_wdt.c
 create mode 100644 include/configs/ls1c300.h
 create mode 100644 include/dt-bindings/clock/ls1c300-clk.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 34446127d4..e1714fb1fc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -967,6 +967,19 @@ F:	drivers/net/cortina_ni.c
 F:	drivers/net/cortina_ni.h
 F:	drivers/net/phy/ca_phy.c
 
+MIPS LOONGSON LS1C300
+M:	Du Huanpeng <dhu@hodcarrier.org>
+S:	Maintained
+F:	arch/mips/dts/loongson32-ls1c300b.dtsi
+F:	arch/mips/dts/ls1c300-eval.dts
+F:	arch/mips/mach-lsmips/
+F:	board/loongson/ls1c300-eval/
+F:	configs/ls1c300_defconfig
+F:	drivers/clk/lsmips/
+F:	drivers/watchdog/lsmips_wdt.c
+F:	include/configs/ls1c300.h
+F:	include/dt-bindings/clock/ls1c300-clk.h
+
 MIPS MEDIATEK
 M:	Weijie Gao <weijie.gao@mediatek.com>
 R:	GSS_MTK_Uboot_upstream <GSS_MTK_Uboot_upstream@mediatek.com>
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 06cae68ee5..461bb2a99b 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -93,6 +93,16 @@ config ARCH_MTMIPS
 	select SUPPORTS_LITTLE_ENDIAN
 	select SUPPORT_SPL
 
+config ARCH_LSMIPS
+	bool "Support Loongson MIPS platforms"
+	select DM
+	select DM_SERIAL
+	select OF_CONTROL
+	select SUPPORTS_CPU_MIPS32_R1
+	select SUPPORTS_CPU_MIPS32_R2
+	select SUPPORTS_LITTLE_ENDIAN
+	select SUPPORT_SPL
+
 config ARCH_JZ47XX
 	bool "Support Ingenic JZ47xx"
 	select SUPPORT_SPL
@@ -175,6 +185,7 @@ source "arch/mips/mach-bmips/Kconfig"
 source "arch/mips/mach-jz47xx/Kconfig"
 source "arch/mips/mach-pic32/Kconfig"
 source "arch/mips/mach-mtmips/Kconfig"
+source "arch/mips/mach-lsmips/Kconfig"
 source "arch/mips/mach-octeon/Kconfig"
 
 if MIPS
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 6502aebd29..e944502497 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -16,6 +16,7 @@ machine-$(CONFIG_ARCH_BMIPS) += bmips
 machine-$(CONFIG_ARCH_JZ47XX) += jz47xx
 machine-$(CONFIG_MACH_PIC32) += pic32
 machine-$(CONFIG_ARCH_MTMIPS) += mtmips
+machine-$(CONFIG_ARCH_LSMIPS) += lsmips
 machine-$(CONFIG_ARCH_MSCC) += mscc
 machine-${CONFIG_ARCH_OCTEON} += octeon
 
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
index 95144b24dc..915acfd573 100644
--- a/arch/mips/dts/Makefile
+++ b/arch/mips/dts/Makefile
@@ -19,6 +19,7 @@ dtb-$(CONFIG_BOARD_MT7620_MT7530_RFB) += mediatek,mt7620-mt7530-rfb.dtb
 dtb-$(CONFIG_BOARD_MT7628_RFB) += mediatek,mt7628-rfb.dtb
 dtb-$(CONFIG_BOARD_GARDENA_SMART_GATEWAY_MT7688) += gardena-smart-gateway-mt7688.dtb
 dtb-$(CONFIG_BOARD_LINKIT_SMART_7688) += linkit-smart-7688.dtb
+dtb-$(CONFIG_BOARD_LS1C300) += ls1c300-eval.dtb
 dtb-$(CONFIG_TARGET_OCTEON_EBB7304) += mrvl,octeon-ebb7304.dtb
 dtb-$(CONFIG_TARGET_OCTEON_NIC23) += mrvl,octeon-nic23.dtb
 dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb
diff --git a/arch/mips/dts/loongson32-ls1c300b.dtsi b/arch/mips/dts/loongson32-ls1c300b.dtsi
new file mode 100644
index 0000000000..b13bdf189d
--- /dev/null
+++ b/arch/mips/dts/loongson32-ls1c300b.dtsi
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <dt-bindings/clock/ls1c300-clk.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "loongson,ls1c300-soc";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu@0 {
+			device_type = "cpu";
+			reg = <0>;
+			compatible = "loongson,gs232", "mips,mips4Kc";
+			clocks = <&acc CLK_CPU_THROT>;
+		};
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		u-boot,dm-pre-reloc;
+
+		xtal: oscillator {
+			compatible = "fixed-clock";
+			clock-frequency = <24000000>;
+			#clock-cells = <0>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges;
+
+		acc: clock-controller@1fe78030 {
+			compatible = "loongson,ls1c300-clk";
+			clocks = <&xtal>;
+			#clock-cells = <1>;
+			reg = <0x1fe78030 0x8>, <0x1fe7c010 0x4>;
+			u-boot,dm-pre-reloc;
+		};
+
+		uart0: serial@1fe40000 {
+			compatible = "loongson,ls1c300-uart", "ns16550a";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe40000 0x100>;
+			status = "disabled";
+		};
+
+		uart1: serial@1fe44000 {
+			compatible = "loongson,ls1c300-uart", "ns16550a";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe44000 0x100>;
+			status = "disabled";
+		};
+
+		uart2: serial@1fe48000 {
+			compatible = "loongson,ls1c300-uart", "ns16550a";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe48000 0x100>;
+			status = "disabled";
+		};
+
+		uart3: serial@1fe4c000 {
+			compatible = "loongson,ls1c300-uart", "ns16550a";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe4c000 0x100>;
+			status = "disabled";
+		};
+
+		uart4:  serial@1fe4c400 {
+			compatible = "loongson,ls1c300-uart", "ns16550a";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe4c400 0x100>;
+			status = "disabled";
+		};
+
+		uart5:  serial@1fe4c500 {
+			compatible = "loongson,ls1c300-uart", "ns16550a";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe4c500 0x100>;
+			status = "disabled";
+		};
+
+		uart6:  serial@1fe4c600 {
+			compatible = "loongson,ls1c300-uart", "ns16550a";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe4c600 0x100>;
+			status = "disabled";
+		};
+
+		uart7:  serial@1fe4c700 {
+			compatible = "loongson,ls1c300-uart", "ns16550a";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe4c700 0x100>;
+			status = "disabled";
+		};
+
+		uart8:  serial@1fe4c800 {
+			compatible = "loongson,ls1c300-uart", "ns16550a";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe4c800 0x100>;
+			status = "disabled";
+		};
+
+		uart9:  serial@1fe4c900 {
+			compatible = "loongson,ls1c300-uart", "ns16550a";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe4c900 0x100>;
+			status = "disabled";
+		};
+
+		uart10: serial@1fe4ca00 {
+			compatible = "loongson,ls1c300-uart", "ns16550a";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe4ca00 0x100>;
+			status = "disabled";
+		};
+
+		uart11: serial@1fe4cb00 {
+			compatible = "loongson,ls1c300-uart", "ns16550a";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe4cb00 0x100>;
+			status = "disabled";
+		};
+
+		wdt: watchdog@1fe5c060 {
+			compatible = "loongson,ls1c300-wdt";
+			clocks = <&acc CLK_APB>;
+			reg = <0x1fe5c060 0x10>;
+		};
+
+		reset-controller {
+			compatible = "wdt-reboot";
+			wdt = <&wdt>;
+		};
+	};
+};
diff --git a/arch/mips/dts/ls1c300-eval.dts b/arch/mips/dts/ls1c300-eval.dts
new file mode 100644
index 0000000000..eaf65b2d96
--- /dev/null
+++ b/arch/mips/dts/ls1c300-eval.dts
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+/dts-v1/;
+
+#include "loongson32-ls1c300b.dtsi"
+
+/ {
+	compatible = "lsmips,ls1c300-soc";
+	model = "ls1c300-eval";
+
+	aliases {
+		serial0 = &uart2;
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x4000000>;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart2 {
+	status = "okay";
+};
+
diff --git a/arch/mips/mach-lsmips/Kconfig b/arch/mips/mach-lsmips/Kconfig
new file mode 100644
index 0000000000..2092e6ef35
--- /dev/null
+++ b/arch/mips/mach-lsmips/Kconfig
@@ -0,0 +1,76 @@
+menu "Loongson MIPS platforms"
+	depends on ARCH_LSMIPS
+
+config SYS_MALLOC_F_LEN
+	default 0x1000
+
+config SYS_SOC
+	default "ls1c300" if SOC_LS1C300
+
+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_TEXT_BASE
+	default 0xbfc00000 if !SPL
+	default 0x80200000 if SPL
+
+config SPL_TEXT_BASE
+	default 0xbfc00000
+
+config SPL_PAYLOAD
+	default "u-boot-lzma.img" if SPL_LZMA
+
+config BUILD_TARGET
+	default "u-boot-with-spl.bin" if SPL
+	default "u-boot.bin" if !SPL
+
+choice
+	prompt "Loongson MIPS SoC select"
+
+config SOC_LS1C300
+	bool "LS1C300"
+	select CLK_CCF
+	select SPL_SEPARATE_BSS if SPL
+	select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL
+	select SPL_LOADER_SUPPORT if SPL
+	select SPL_OF_CONTROL if SPL_DM
+	select SPL_SIMPLE_BUS if SPL_DM
+	select SPL_DM_SERIAL if SPL_DM
+	select SPL_CLK if SPL_DM && SPL_SERIAL
+	select SPL_SYSRESET if SPL_DM
+	select SPL_OF_LIBFDT if SPL_OF_CONTROL
+	help
+	  This supports Loongson LS1C300
+
+endchoice
+
+choice
+	prompt "Board select"
+
+config BOARD_LS1C300
+	bool "Loongson LS1C300 Eval"
+	depends on SOC_LS1C300
+	help
+	  ls1c300-eval board has a LS1C300 SoC with 64MiB of SDRAM
+	  and 512KiB of flash (SPI NOR) and additional NAND storage.
+
+endchoice
+
+config CONS_PIN
+	int "pin group used in uart"
+	default 0
+	help
+	  Select pin group connected to UART for your board.
+
+source "board/loongson/ls1c300-eval/Kconfig"
+
+endmenu
diff --git a/arch/mips/mach-lsmips/Makefile b/arch/mips/mach-lsmips/Makefile
new file mode 100644
index 0000000000..654143a5f7
--- /dev/null
+++ b/arch/mips/mach-lsmips/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += cpu.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
+
+obj-$(CONFIG_SOC_LS1C300) += ls1c300/
diff --git a/arch/mips/mach-lsmips/cpu.c b/arch/mips/mach-lsmips/cpu.c
new file mode 100644
index 0000000000..4205d8ef83
--- /dev/null
+++ b/arch/mips/mach-lsmips/cpu.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <malloc.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M);
+	return 0;
+}
diff --git a/arch/mips/mach-lsmips/include/mach/serial.h b/arch/mips/mach-lsmips/include/mach/serial.h
new file mode 100644
index 0000000000..4da1cb434c
--- /dev/null
+++ b/arch/mips/mach-lsmips/include/mach/serial.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Gao Weijie <weijie.gao@mediatek.com>
+ *
+ * Copyright (C) 2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+#ifndef __LSMIPS_SERIAL_H_
+#define __LSMIPS_SERIAL_H_
+
+void lsmips_spl_serial_init(void);
+int gpio_set_alternate(int gpio, int func);
+
+#endif /* __LSMIPS_SERIAL_H_ */
diff --git a/arch/mips/mach-lsmips/ls1c300/Makefile b/arch/mips/mach-lsmips/ls1c300/Makefile
new file mode 100644
index 0000000000..17b9d6fb9c
--- /dev/null
+++ b/arch/mips/mach-lsmips/ls1c300/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += lowlevel_init.o
+obj-y += sdram.o
+obj-y += init.o
+obj-y += gpio.o
+obj-$(CONFIG_SPL_BUILD) += serial.o
diff --git a/arch/mips/mach-lsmips/ls1c300/gpio.c b/arch/mips/mach-lsmips/ls1c300/gpio.c
new file mode 100644
index 0000000000..2195738b2b
--- /dev/null
+++ b/arch/mips/mach-lsmips/ls1c300/gpio.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+#include <linux/errno.h>
+#include <asm/bitops.h>
+
+#define CBUS_FIRST0	0xbfd011c0
+#define CBUS_SECOND0	0xbfd011d0
+#define CBUS_THIRD0	0xbfd011e0
+#define CBUS_FOURTHT0	0xbfd011f0
+#define CBUS_FIFTHT0	0xbfd01200
+
+#define CBUS_FIRST1	0xbfd011c4
+#define CBUS_SECOND1	0xbfd011d4
+#define CBUS_THIRD1	0xbfd011e4
+#define CBUS_FOURTHT1	0xbfd011f4
+#define CBUS_FIFTHT1	0xbfd01204
+
+#define CBUS_FIRST2	0xbfd011c8
+#define CBUS_SECOND2	0xbfd011d8
+#define CBUS_THIRD2	0xbfd011e8
+#define CBUS_FOURTHT2	0xbfd011f8
+#define CBUS_FIFTHT2	0xbfd01208
+
+#define CBUS_FIRST3	0xbfd011cc
+#define CBUS_SECOND3	0xbfd011dc
+#define CBUS_THIRD3	0xbfd011ec
+#define CBUS_FOURTHT3	0xbfd011fc
+#define CBUS_FIFTHT3	0xbfd0120c
+
+/*
+ * pinmux for debug uart and spl only, for others, please
+ * use a pinctrl driver and device-tree for pin muxing.
+ *
+ * @gpio: gpio number
+ * @func: alternate function 1 to 5, 0 for GPIO.
+ */
+
+int gpio_set_alternate(int gpio, int func)
+{
+	volatile void __iomem *addr;
+	int i;
+
+	if (gpio < 0 || gpio > 104)
+		return -ENODEV;
+	if (func < 0 || func > 5)
+		return -EINVAL;
+
+	if (func) {
+		i = func - 1;
+		addr = (void *)CBUS_FIRST0 + i * 16;
+		set_bit(gpio, addr);
+	} else {
+		/* GPIO, clear CBUS 1 ~ 5 */
+		i = 5;
+	}
+
+	while (i--) {
+		addr = (void *)CBUS_FIRST0 + 16 * i;
+		clear_bit(gpio, addr);
+	}
+
+	return 0;
+}
diff --git a/arch/mips/mach-lsmips/ls1c300/init.c b/arch/mips/mach-lsmips/ls1c300/init.c
new file mode 100644
index 0000000000..d515bd2f86
--- /dev/null
+++ b/arch/mips/mach-lsmips/ls1c300/init.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Gao Weijie <weijie.gao@mediatek.com>
+ *
+ * based on: arch/mips/mach-mtmips/mt7628/init.c
+ * Copyright (C) 2020-2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/uclass.h>
+#include <dt-bindings/clock/ls1c300-clk.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int print_cpuinfo(void)
+{
+	struct udevice *udev;
+	struct clk clk;
+	int ret;
+	ulong xtal;
+	char buf[SZ_32];
+
+	printf("CPU: Loongson ls1c300b\n");
+
+	ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(ls1c300_clk), &udev);
+
+	if (ret) {
+		printf("error: clock driver not found.\n");
+		return 0;
+	}
+
+	clk.dev = udev;
+
+	ret = clk_request(udev, &clk);
+	if (ret < 0)
+		return ret;
+
+	clk.id = CLK_XTAL;
+	xtal = clk_get_rate(&clk);
+
+	clk.id = CLK_CPU_THROT;
+	gd->cpu_clk = clk_get_rate(&clk);
+
+	clk.id = CLK_APB;
+	gd->mem_clk = clk_get_rate(&clk);
+
+	printf("Clock: CPU: %sMHz, ", strmhz(buf, gd->cpu_clk));
+	printf("SDRAM: %sMHz, ", strmhz(buf, gd->mem_clk));
+	printf("XTAL: %sMHz\n", strmhz(buf, xtal));
+
+	return 0;
+}
+
+ulong notrace get_tbclk(void)
+{
+	return gd->cpu_clk / 2;
+}
diff --git a/arch/mips/mach-lsmips/ls1c300/lowlevel_init.S b/arch/mips/mach-lsmips/ls1c300/lowlevel_init.S
new file mode 100644
index 0000000000..a8d1359cf5
--- /dev/null
+++ b/arch/mips/mach-lsmips/ls1c300/lowlevel_init.S
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Gao Weijie <weijie.gao@mediatek.com>
+ *
+ * Copyright (C) 2020-2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+#include <config.h>
+#include <asm-offsets.h>
+#include <asm/cacheops.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <linux/sizes.h>
+
+/* PLL control register */
+#define NAND_BASE	0xbfe70000
+#define START_FREQ	0x8030
+#define CLK_DIV_PARAM	0x8034
+#define CPU_THROT	0xc010
+
+/* START_FREQ */
+#define PLL_VALID	31
+#define Reserved_24	24
+#define FRAC_N		16
+#define M_PLL		8
+#define Reserved_4	4
+#define RST_TIME	2
+#define SDRAM_DIV	0
+ #define SDRAM_DIV2	0
+ #define SDRAM_DIV4	1
+ #define SDRAM_DIV3	2
+
+/* CLK_DIV_PARAM */
+#define PIX_DIV		24
+#define CAM_DIV		16
+#define CPU_DIV		8
+#define PIX_DIV_VALID	5
+#define PIX_SEL		4
+#define CAM_DIV_VALID	3
+#define CAM_SEL		2
+#define CPU_DIV_VALID	1
+#define CPU_SEL		0
+
+/* Document:
+ * Freq_PLL = XIN *(M_PLL + FRAC_N)/4
+ */
+#define XIN			24000000
+#define PLL_VALID_1		(1<<PLL_VALID)
+#define PREP_M_PLL(Freq_PLL)	(((Freq_PLL * 4) / XIN) << M_PLL)
+#define PREP_SDRAM_DIV(div)	(div<<SDRAM_DIV)
+#define PREP_CPU_DIV(div1)	((0x80|div1)<<CPU_DIV | (div1&&div1)<<CPU_DIV_VALID)
+#define PREP_PIX_DIV(div2)	(div2<<PIX_DIV)
+#define PREP_CAM_DIV(div3)	(div3<<CAM_DIV)
+
+/* PLL @264MHz, CPU @132MHz, SDRAM @66MHz */
+#define CFG_START_FREQ		(PLL_VALID_1 | PREP_M_PLL(264000000) | SDRAM_DIV2)
+#define CFG_CLK_DIV_PARAM	(PREP_CPU_DIV(2) | PREP_PIX_DIV(0x24) | PREP_CAM_DIV(0x24))
+#define CFG_CPU_THROT		15
+
+/* SPI0 control register */
+#define SPI0_BASE		0xbfe80000
+#define SPCR			0
+#define SPSR			1
+#define TxFIFO			2
+#define RxFIFO			2
+#define SPER			3
+#define SFC_PARAM		4
+    #define CLK_DIV		4
+    #define DUAL_IO		3
+    #define FAST_READ		2
+    #define BURST_EN		1
+    #define MEMORY_EN		0
+#define SFC_SOFTCS		5
+#define SFC_TIMING		6
+    #define T_FAST		2
+    #define T_CSH		0
+
+	.set noreorder
+LEAF(ls1c300_pll_init)
+#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
+	li	t0, NAND_BASE
+	li	t1, CFG_START_FREQ
+	li	t2, CFG_CLK_DIV_PARAM
+	li	t3, CFG_CPU_THROT
+
+	sw	t3, CPU_THROT (t0)
+	sw	t2, CLK_DIV_PARAM (t0)
+	sw	t1, START_FREQ (t0)
+	  nop
+
+	ori	t2, 1<<CPU_SEL
+	sw	t2, CLK_DIV_PARAM (t0)
+#endif
+	li	v0, 264000000
+	jr	ra
+	nop
+END(ls1c300_pll_init)
+
+LEAF(ls1c300_spi_init)
+#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
+	li	t0, SPI0_BASE
+	li	t1, (1<<MEMORY_EN) | (1<<BURST_EN) | (1<<FAST_READ) | (1<<DUAL_IO)
+	sb	t1, SFC_PARAM (t0)
+	li	t2, (1<<T_FAST) | (1<<T_CSH)
+	sb	t2, SFC_TIMING (t0)
+#endif
+	jr	ra
+	  nop
+END(ls1c300_spi_init)
+
+NESTED(lowlevel_init, 0, ra)
+	/* Save ra and do real lowlevel initialization */
+	move	s0, ra
+	/* Setup PLL @264MHz */
+	PTR_LA	t9, ls1c300_pll_init
+	jalr	t9
+	  nop
+
+	/* Setup SPI Dual IO@33MHz */
+	PTR_LA	t9, ls1c300_spi_init
+	jalr	t9
+	  nop
+
+	/* Setup external SDRAM @66MHz */
+	PTR_LA	t9, ls1c300_sdram_init
+	jalr	t9
+	  nop
+
+	move	ra, s0
+	jr	ra
+	 nop
+END(lowlevel_init)
diff --git a/arch/mips/mach-lsmips/ls1c300/sdram.S b/arch/mips/mach-lsmips/ls1c300/sdram.S
new file mode 100644
index 0000000000..95d21f0093
--- /dev/null
+++ b/arch/mips/mach-lsmips/ls1c300/sdram.S
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+#include <config.h>
+#include <asm-offsets.h>
+#include <asm/cacheops.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <linux/sizes.h>
+
+/* sdram control 64 bit register */
+#define SD_CONFIG	0xbfd00000
+#define SD_CONFIGHI	0x414
+#define SD_CONFIGLO	0x410
+
+#define CONFIG_VALID	41
+#define HANG_UP		40
+#define DEF_SEL		39
+#define TWR		37
+#define TREF		25
+#define TRAS		21
+#define TRFC		17
+#define TRP		14
+#define TCL		11
+#define TRCD		8
+
+#define SD_BIT		6
+  #define SD_8BIT       (0<<SD_BIT)
+  #define SD_16BIT      (1<<SD_BIT)
+  #define SD_32BIT      (2<<SD_BIT)
+#define SD_CSIZE	3
+  #define SD_CSIZE_512	(0<<SD_CSIZE)
+  #define SD_CSIZE_1K	(1<<SD_CSIZE)
+  #define SD_CSIZE_2K	(2<<SD_CSIZE)
+  #define SD_CSIZE_4K	(3<<SD_CSIZE)
+  #define SD_CSIZE_256	(7<<SD_CSIZE)
+#define SD_RSIZE	0
+  #define SD_RSIZE_2K	(0<<SD_RSIZE)
+  #define SD_RSIZE_4K	(1<<SD_RSIZE)
+  #define SD_RSIZE_8K	(2<<SD_RSIZE)
+  #define SD_RSIZE_16K	(3<<SD_RSIZE)
+
+#define SD_CFG_1(tWR, tREF, tRAS, tRFC, tRP, tCL, tRCD) \
+	((tWR<<TWR)|(tREF<<TREF)|(tRAS<<TRAS)|(tRFC<<TRFC)|(tRP<<TRP)|(tCL<<TCL)|(tRCD<<TRCD))
+#define CFG_SD_0(b, c, r) \
+	((b<<SD_BIT)|(c<<SD_CSIZE)|(r<<SD_RSIZE))
+/*
+ * recommended values by ls1c300 user manual,
+ * tweat to fit your board.
+ */
+#define SD_CONFIG_133MHz	SD_CFG_1(2, 0x818, 6, 8, 3, 3, 3)
+#define SD_CONFIG_100MHz	SD_CFG_1(2, 0x620, 5, 6, 2, 3, 2)
+#define SD_CONFIG_75MHz		SD_CFG_1(1, 0x494, 4, 5, 2, 2, 2)
+#define SD_CONFIG_33MHz		SD_CFG_1(1, 0x204, 2, 2, 1, 2, 1)
+
+#define SD_CONFIG_66MHz		SD_CFG_1(1, 0x401, 4, 4, 2, 2, 2)
+
+#define SD_CONFIG64	(SD_CONFIG_66MHz | SD_16BIT | SD_CSIZE_1K | SD_RSIZE_8K)
+#define CFG_SDCONFIGHI	(SD_CONFIG64 /(1<<32))
+#define CFG_SDCONFIGLO	(SD_CONFIG64 %(1<<32))
+
+	.set noreorder
+/*
+ * Loongson ls1c300 SoC do not have onchip sram for initial stack,
+ * initialize the external sdram on reset as early as possiable.
+ */
+LEAF(ls1c300_sdram_init)
+#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
+	li	t0, SD_CONFIG
+	li	t1, CFG_SDCONFIGLO
+	li	t2, CFG_SDCONFIGHI
+
+	sw	t1, SD_CONFIGLO (t0)
+	sw	t2, SD_CONFIGHI (t0)
+	nop
+
+	sw	t1, SD_CONFIGLO (t0)
+	sw	t2, SD_CONFIGHI (t0)
+	nop
+
+	ori	t2, 1<<(CONFIG_VALID-32)
+	sw	t1, SD_CONFIGLO (t0)
+	sw	t2, SD_CONFIGHI (t0)
+#endif
+	li	v0, SZ_64M
+	jr	ra
+	 nop
+END(ls1c300_sdram_init)
+
+
diff --git a/arch/mips/mach-lsmips/ls1c300/serial.c b/arch/mips/mach-lsmips/ls1c300/serial.c
new file mode 100644
index 0000000000..93fd653385
--- /dev/null
+++ b/arch/mips/mach-lsmips/ls1c300/serial.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Gao Weijie <weijie.gao@mediatek.com>
+ *
+ * Copyright (C) 2020-2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+#include <mach/serial.h>
+#include <linux/kernel.h>
+
+struct uart_pin_config {
+	char port;
+	char af;
+	char rx;
+	char tx;
+};
+
+struct uart_pin_config con[] = {
+#if CONFIG_CONS_INDEX == 0
+	{ 0, 2, 74, 75 },
+	{ 0, 3, 23, 24 },
+	{ 0, 3, 99, 100 },
+
+#elif CONFIG_CONS_INDEX == 1
+	{ 1, 1, 17, 18 },
+	{ 1, 1, 101, 102 },
+	{ 1, 2, 40, 41 },
+	{ 1, 4, 2, 3 },
+
+#elif CONFIG_CONS_INDEX == 2
+	{ 2, 2, 36, 37 },
+	{ 2, 2, 42, 43 },
+	{ 2, 3, 27, 28 },
+	{ 2, 3, 103, 104 },
+	{ 2, 4, 4, 5 },
+
+#elif CONFIG_CONS_INDEX == 3
+	{ 3, 2, 17, 18 },
+	{ 3, 2, 33, 34 },
+	{ 3, 2, 44, 45 },
+	{ 3, 4, 0, 1 },
+
+#elif CONFIG_CONS_INDEX == 4
+	{ 4, 5, 23, 24 },
+	{ 4, 5, 58, 59 },
+	{ 4, 5, 80, 79 },
+
+#elif CONFIG_CONS_INDEX == 5
+	{ 5, 5, 25, 26 },
+	{ 5, 5, 60, 61 },
+	{ 5, 5, 81, 78 },
+
+#elif CONFIG_CONS_INDEX == 6
+	{ 6, 5, 27, 46 },
+	{ 6, 5, 62, 63 },
+
+#elif CONFIG_CONS_INDEX == 7
+	{ 7, 5, 57, 56 },
+	{ 7, 5, 64, 65 },
+	{ 7, 5, 87, 88 },
+
+#elif CONFIG_CONS_INDEX == 8
+	{ 8, 5, 55, 54 },
+	{ 8, 5, 66, 67 },
+	{ 8, 5, 89, 90 },
+
+#elif CONFIG_CONS_INDEX == 9
+	{ 9, 5, 53, 52 },
+	{ 9, 5, 68, 69 },
+	{ 9, 5, 85, 86 },
+
+#elif CONFIG_CONS_INDEX == 10
+	{ 10, 5, 51, 50 },
+	{ 10, 5, 70, 71 },
+	{ 10, 5, 84, 82 },
+
+#elif CONFIG_CONS_INDEX == 11
+	{ 11, 5, 49, 48 },
+	{ 11, 5, 72, 73 },
+#endif /* CONFIG_CONS_INDEX */
+};
+
+#define UART2_RX	36
+#define UART2_TX	37
+#define AFUNC		2
+
+void lsmips_spl_serial_init(void)
+{
+#if defined(CONFIG_SPL_SERIAL)
+	int pin_rx, pin_tx;
+	int afunc;
+
+	if (CONFIG_CONS_PIN < ARRAY_SIZE(con)) {
+		pin_rx = con[CONFIG_CONS_PIN].rx;
+		pin_tx = con[CONFIG_CONS_PIN].tx;
+		afunc = con[CONFIG_CONS_PIN].af;
+	} else {
+		pin_rx = UART2_RX;
+		pin_tx = UART2_TX;
+		afunc = AFUNC;
+	}
+
+	gpio_set_alternate(pin_rx, afunc);
+	gpio_set_alternate(pin_tx, afunc);
+#endif /* CONFIG_SPL_SERIAL */
+	return;
+}
diff --git a/arch/mips/mach-lsmips/spl.c b/arch/mips/mach-lsmips/spl.c
new file mode 100644
index 0000000000..21c49197ae
--- /dev/null
+++ b/arch/mips/mach-lsmips/spl.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Gao Weijie <weijie.gao@mediatek.com>
+ *
+ * Copyright (C) 2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <spl.h>
+#include <asm/sections.h>
+#include <linux/libfdt.h>
+#include <linux/sizes.h>
+#include <mach/serial.h>
+
+void __noreturn board_init_f(ulong dummy)
+{
+	spl_init();
+
+#if defined(CONFIG_SPL_SERIAL)
+	/*
+	 * lsmips_spl_serial_init() is useful if debug uart is enabled,
+	 * or DM based serial is not enabled.
+	 */
+	lsmips_spl_serial_init();
+	preloader_console_init();
+#endif
+	board_init_r(NULL, 0);
+}
+
+void board_boot_order(u32 *spl_boot_list)
+{
+	spl_boot_list[0] = BOOT_DEVICE_NOR;
+}
+
+unsigned long spl_nor_get_uboot_base(void)
+{
+	void *uboot_base = __image_copy_end;
+
+	if (fdt_magic(uboot_base) == FDT_MAGIC)
+		return (unsigned long)uboot_base + fdt_totalsize(uboot_base);
+
+	return (unsigned long)uboot_base;
+}
diff --git a/board/loongson/ls1c300-eval/Kconfig b/board/loongson/ls1c300-eval/Kconfig
new file mode 100644
index 0000000000..e427570a83
--- /dev/null
+++ b/board/loongson/ls1c300-eval/Kconfig
@@ -0,0 +1,12 @@
+if BOARD_LS1C300
+
+config SYS_BOARD
+	default "ls1c300-eval"
+
+config SYS_VENDOR
+	default "loongson"
+
+config SYS_CONFIG_NAME
+	default "ls1c300"
+
+endif
diff --git a/board/loongson/ls1c300-eval/MAINTAINERS b/board/loongson/ls1c300-eval/MAINTAINERS
new file mode 100644
index 0000000000..5420198dab
--- /dev/null
+++ b/board/loongson/ls1c300-eval/MAINTAINERS
@@ -0,0 +1,7 @@
+LS1C300_EVAL BOARD
+M:	Du Huanpeng<dhu@hodcarrier.org>
+S:	Maintained
+F:	board/loongson/ls1c300-eval
+F:	include/configs/ls1c300.h
+F:	configs/ls1c300_defconfig
+F:	arch/mips/dts/ls1c300-eval.dts
diff --git a/board/loongson/ls1c300-eval/Makefile b/board/loongson/ls1c300-eval/Makefile
new file mode 100644
index 0000000000..db129c5aba
--- /dev/null
+++ b/board/loongson/ls1c300-eval/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += board.o
diff --git a/board/loongson/ls1c300-eval/board.c b/board/loongson/ls1c300-eval/board.c
new file mode 100644
index 0000000000..6809d66515
--- /dev/null
+++ b/board/loongson/ls1c300-eval/board.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020-2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+#include <common.h>
+#include <mach/serial.h>
+
+#if defined(CONFIG_DEBUG_UART_BOARD_INIT)
+
+#define UART2_RX	36
+#define UART2_TX	37
+#define AFUNC		2
+
+void board_debug_uart_init(void)
+{
+	gpio_set_alternate(UART2_TX, AFUNC);
+	gpio_set_alternate(UART2_RX, AFUNC);
+}
+#endif
diff --git a/configs/ls1c300_defconfig b/configs/ls1c300_defconfig
new file mode 100644
index 0000000000..3e630a0c0e
--- /dev/null
+++ b/configs/ls1c300_defconfig
@@ -0,0 +1,49 @@
+CONFIG_MIPS=y
+CONFIG_SYS_MALLOC_F_LEN=0x40000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+CONFIG_DEFAULT_DEVICE_TREE="ls1c300-eval"
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_SIZE_LIMIT=0x100000
+CONFIG_SPL=y
+CONFIG_SYS_LOAD_ADDR=0x80010000
+CONFIG_ARCH_LSMIPS=y
+CONFIG_SPL_PAYLOAD="u-boot.img"
+CONFIG_ROM_EXCEPTION_VECTORS=y
+# CONFIG_MIPS_CACHE_SETUP is not set
+# CONFIG_MIPS_CACHE_DISABLE is not set
+CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_FIT=y
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_LOGLEVEL=9
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_NOR_SUPPORT=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_CLK=y
+# CONFIG_CMD_LOADS is not set
+# CONFIG_PARTITIONS is not set
+CONFIG_OF_EMBED=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+CONFIG_CLK=y
+CONFIG_SPL_CLK_CCF=y
+# CONFIG_INPUT is not set
+# CONFIG_POWER is not set
+CONFIG_CONS_INDEX=2
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_SYSRESET_WATCHDOG_AUTO=y
+CONFIG_WATCHDOG_TIMEOUT_MSECS=3000
+CONFIG_WDT_LSMIPS=y
+CONFIG_REGEX=y
+# CONFIG_GZIP is not set
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index bb4eee5d99..51562ca4a6 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -17,6 +17,7 @@ obj-y += tegra/
 obj-y += ti/
 obj-$(CONFIG_$(SPL_TPL_)CLK_INTEL) += intel/
 obj-$(CONFIG_ARCH_ASPEED) += aspeed/
+obj-$(CONFIG_ARCH_LSMIPS) += lsmips/
 obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
 obj-$(CONFIG_ARCH_MESON) += meson/
 obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
diff --git a/drivers/clk/lsmips/Makefile b/drivers/clk/lsmips/Makefile
new file mode 100644
index 0000000000..0a47269cd3
--- /dev/null
+++ b/drivers/clk/lsmips/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SOC_LS1C300) += clk-ls1c300.o
diff --git a/drivers/clk/lsmips/clk-ls1c300.c b/drivers/clk/lsmips/clk-ls1c300.c
new file mode 100644
index 0000000000..46a94e9748
--- /dev/null
+++ b/drivers/clk/lsmips/clk-ls1c300.c
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * reference:
+ *   drivers/clk/microchip/mpfs_clk.c
+ *   drivers/clk/clk_octeon.c
+ *
+ * Copyright (C) 2020-2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dt-bindings/clock/ls1c300-clk.h>
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+
+/* PLL/SDRAM Frequency Configuration Register */
+#define START_FREQ	0
+#define CLK_DIV_PARAM	4
+
+/* START_FREQ */
+#define	PLL_VALID	BIT(31)
+#define	RESERVED0	GENMASK(30, 24)
+#define	FRAC_N		GENMASK(23, 16)
+#define	M_PLL		GENMASK(15, 8)
+#define	RESERVED1	GENMASK(7, 4)
+#define	RST_TIME	GENMASK(3, 2)
+#define	SDRAM_DIV	GENMASK(1, 0)
+/* CLK_DIV_PARAM */
+#define	PIX_DIV		GENMASK(31, 24)
+#define	CAM_DIV		GENMASK(23, 16)
+#define	CPU_DIV		GENMASK(15, 8)
+#define	RESERVED2	GENMASK(7, 6)
+#define	PIX_DIV_VALID	BIT(5)
+#define	PIX_SEL		BIT(4)
+#define	CAM_DIV_VALID	BIT(3)
+#define	CAM_SEL		BIT(2)
+#define	CPU_DIV_VALID	BIT(1)
+#define	CPU_SEL		BIT(0)
+/* CPU_THROT */
+#define	CPU_THROT	GENMASK(3, 0)
+
+static const struct clk_div_table sdram_div_table[] = {
+	{.val = 0, .div = 2},
+	{.val = 1, .div = 4},
+	{.val = 2, .div = 3},
+	{.val = 3, .div = 3},
+};
+
+ulong ls1c300_pll_get_rate(struct clk *clk)
+{
+	unsigned int mult;
+	long long parent_rate;
+	void *base;
+	unsigned int val;
+
+	parent_rate = clk_get_parent_rate(clk);
+	base = (void *)clk->data;
+
+	val = readl(base + START_FREQ);
+	mult = FIELD_GET(FRAC_N, val) + FIELD_GET(M_PLL, val);
+	return (mult * parent_rate) / 4;
+}
+
+static ulong ls1c300_clk_get_rate(struct clk *clk)
+{
+	struct clk *cl;
+	ulong rate;
+	int err;
+
+	err = clk_get_by_id(clk->id, &cl);
+	if (err)
+		return err;
+
+	rate = clk_get_rate(cl);
+	return rate;
+}
+
+static int ls1c300_clk_probe(struct udevice *dev)
+{
+	void __iomem *base;
+	void __iomem *cpu_throt;
+	void __iomem *addr;
+
+	struct clk *cl, clk;
+	const char *parent_name;
+	int flags;
+	int ret;
+
+	base = (void *)dev_remap_addr_index(dev, 0);
+	cpu_throt  = (void *)dev_remap_addr_index(dev, 1);
+
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret)
+		return ret;
+
+	ret = clk_get_rate(&clk);
+
+	parent_name = clk.dev->name;
+
+	cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+	cl->data = (unsigned long)base;
+	ret = clk_register(cl, "clk_ls1c300_pll", "pll", parent_name);
+	clk_dm(CLK_PLL, cl);
+
+	addr = base + CLK_DIV_PARAM;
+	flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
+	cl = clk_register_divider(NULL, "cpu_div", "pll", 0, addr,  8, 7, flags);
+	clk_dm(CLK_CPU, cl);
+	cl = clk_register_divider(NULL, "cam_div", "pll", 0, addr, 16, 7, flags);
+	clk_dm(CLK_CAMERA, cl);
+	cl = clk_register_divider(NULL, "pix_div", "pll", 0, addr, 24, 7, flags);
+	clk_dm(CLK_PIX, cl);
+
+	cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+	cl->data = (unsigned long)cpu_throt;
+	ret = clk_register(cl, "clk_cpu_throt", "cpu_throt_factor", "cpu_div");
+	clk_dm(CLK_CPU_THROT, cl);
+
+	addr = base + START_FREQ;
+	cl = clk_register_divider(NULL, "sdram_div", "cpu_div", 0, addr, 0, 2, 0);
+	to_clk_divider(cl)->table = sdram_div_table;
+	clk_dm(CLK_APB, cl);
+
+	return 0;
+}
+
+static ulong cpu_throt_get_rate(struct clk *clk)
+{
+	void __iomem *cpu_throt;
+	long long parent_rate;
+	ulong ret;
+
+	parent_rate = clk_get_parent_rate(clk);
+	cpu_throt = (void *)clk->data;
+
+	ret = readl(cpu_throt) + 1;
+	ret = parent_rate * ret / 16;
+	return ret;
+}
+
+static const struct udevice_id ls1c300_clk_ids[] = {
+	{ .compatible = "loongson,ls1c300-clk" },
+	{ }
+};
+
+static const struct clk_ops clk_cpu_throt_ops = {
+	.get_rate = cpu_throt_get_rate,
+};
+
+static const struct clk_ops clk_ls1c300_pll_ops = {
+	.get_rate = ls1c300_pll_get_rate,
+};
+
+static const struct clk_ops ls1c300_clk_ops = {
+	.get_rate = ls1c300_clk_get_rate,
+};
+
+U_BOOT_DRIVER(clk_ls1c300_cpu_throt) = {
+	.name	= "clk_cpu_throt",
+	.id	= UCLASS_CLK,
+	.ops	= &clk_cpu_throt_ops,
+};
+
+U_BOOT_DRIVER(clk_ls1c300_pll) = {
+	.name	= "clk_ls1c300_pll",
+	.id	= UCLASS_CLK,
+	.ops	= &clk_ls1c300_pll_ops,
+};
+
+U_BOOT_DRIVER(ls1c300_clk) = {
+	.name = "clk_ls1c300",
+	.id = UCLASS_CLK,
+	.of_match = ls1c300_clk_ids,
+	.probe = ls1c300_clk_probe,
+	.priv_auto = sizeof(struct clk),
+	.ops = &ls1c300_clk_ops,
+};
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 5b614cfa6e..a9af5e5eb6 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -168,6 +168,14 @@ config WDT_GPIO
 	  doc/device-tree-bindings/watchdog/gpio-wdt.txt for
 	  information on how to describe the watchdog in device tree.
 
+config WDT_LSMIPS
+	bool "Loongson MIPS watchdog timer support"
+	depends on WDT
+	help
+	  Select this to enable watchdog timer for Loongson SoCs.
+	  The watchdog timer is stopped when initialized.
+	  It performs full SoC reset.
+
 config WDT_MPC8xx
 	bool "MPC8xx watchdog timer support"
 	depends on WDT && MPC8xx
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index a35bd559f5..cb596af904 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o
 obj-$(CONFIG_WDT_ORION) += orion_wdt.o
 obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
 obj-$(CONFIG_WDT_GPIO) += gpio_wdt.o
+obj-$(CONFIG_WDT_LSMIPS) += lsmips_wdt.o
 obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
 obj-$(CONFIG_WDT_MT7620) += mt7620_wdt.o
 obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
diff --git a/drivers/watchdog/lsmips_wdt.c b/drivers/watchdog/lsmips_wdt.c
new file mode 100644
index 0000000000..65e60ae656
--- /dev/null
+++ b/drivers/watchdog/lsmips_wdt.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Watchdog driver for MediaTek SoCs
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ *
+ * based on: drivers/watchdog/mtk_wdt.c
+ * Copyright (C) 2020-2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <hang.h>
+#include <wdt.h>
+#include <asm/io.h>
+#include <clk.h>
+
+struct lsmips_wdt_priv {
+	void __iomem *base;
+#define WDT_EN		0
+#define WDT_TIMER	4
+#define WDT_SET		8
+	ulong clock;
+	unsigned long timeout;
+};
+
+static int lsmips_wdt_reset(struct udevice *dev)
+{
+	struct lsmips_wdt_priv *priv = dev_get_priv(dev);
+
+	writel(priv->timeout, priv->base + WDT_TIMER);
+	writel(1, priv->base + WDT_SET);
+
+	return 0;
+}
+
+static int lsmips_wdt_stop(struct udevice *dev)
+{
+	struct lsmips_wdt_priv *priv = dev_get_priv(dev);
+
+	writel(0, priv->base + WDT_EN);
+	return 0;
+}
+
+static int lsmips_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+	struct lsmips_wdt_priv *priv = dev_get_priv(dev);
+
+	writel(1, priv->base + WDT_EN);
+	writel(1, priv->base + WDT_TIMER);
+	writel(1, priv->base + WDT_SET);
+
+	hang();
+	return 0;
+}
+
+static int lsmips_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
+{
+	struct lsmips_wdt_priv *priv = dev_get_priv(dev);
+	unsigned int timeout;
+	const unsigned int MSEC_PER_SEC = 1000;
+
+	timeout = U32_MAX / (priv->clock / MSEC_PER_SEC);
+
+	if (timeout < timeout_ms)
+		timeout = U32_MAX;
+	else
+		timeout = timeout_ms * (priv->clock / MSEC_PER_SEC);
+
+	debug("WDT: reload  = %08x\n", timeout);
+
+	writel(1, priv->base + WDT_EN);
+	writel(timeout, priv->base + WDT_TIMER);
+	writel(1, priv->base + WDT_SET);
+
+	priv->timeout = timeout;
+
+	return 0;
+}
+
+static int lsmips_wdt_probe(struct udevice *dev)
+{
+	struct lsmips_wdt_priv *priv = dev_get_priv(dev);
+	struct clk cl;
+
+	priv->base = dev_remap_addr(dev);
+	if (!priv->base)
+		return -ENOENT;
+
+	if (clk_get_by_index(dev, 0, &cl) == 0)
+		priv->clock = clk_get_rate(&cl);
+
+	if (priv->clock < 45000000 || priv->clock > 133000000)
+		return -EAGAIN;
+
+	debug("WDT: clock = %ld\n", priv->clock);
+
+	writel(0, priv->base + WDT_EN);
+	return 0;
+}
+
+static const struct wdt_ops lsmips_wdt_ops = {
+	.start = lsmips_wdt_start,
+	.reset = lsmips_wdt_reset,
+	.stop = lsmips_wdt_stop,
+	.expire_now = lsmips_wdt_expire_now,
+};
+
+static const struct udevice_id lsmips_wdt_ids[] = {
+	{ .compatible = "loongson,ls1c300-wdt"},
+	{}
+};
+
+U_BOOT_DRIVER(lsmips_wdt) = {
+	.name = "lsmips_wdt",
+	.id = UCLASS_WDT,
+	.of_match = lsmips_wdt_ids,
+	.priv_auto = sizeof(struct lsmips_wdt_priv),
+	.probe = lsmips_wdt_probe,
+	.ops = &lsmips_wdt_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/include/configs/ls1c300.h b/include/configs/ls1c300.h
new file mode 100644
index 0000000000..c460b4564b
--- /dev/null
+++ b/include/configs/ls1c300.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Gao Weijie <weijie.gao@mediatek.com>
+ * based on: include/configs/mt7628.h
+ * Copyright (C) 2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+#ifndef __CONFIG_LS1C300_H__
+#define __CONFIG_LS1C300_H__
+
+#define CONFIG_SYS_HZ			1000
+
+#define CONFIG_SYS_BOOTPARAMS_LEN	0x20000
+
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+#define CONFIG_SYS_LOAD_ADDR		0x80010000
+
+#define CONFIG_SYS_INIT_SP_OFFSET	0x80000
+
+#define CONFIG_SYS_BOOTM_LEN		0x1000000
+
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_SYS_CBSIZE		1024
+
+/* Serial SPL */
+#define CONFIG_SYS_NS16550_SERIAL
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL)
+#define CONFIG_SYS_NS16550_CLK		66000000
+#define CONFIG_SYS_NS16550_REG_SIZE	(-1)
+#define CONFIG_SYS_NS16550_COM1		0xbfe44000
+#define CONFIG_SYS_NS16550_COM2		0xbfe48000
+#define CONFIG_SYS_NS16550_COM3		0xbfe4c000
+#define CONFIG_SYS_NS16550_COM4		0xbfe4c400
+#define CONFIG_SYS_NS16550_COM5		0xbfe4c500
+#define CONFIG_SYS_NS16550_COM6		0xbfe4c600
+#endif
+
+/* Serial common */
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 }
+
+/* SPL */
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+#define CONFIG_SKIP_LOWLEVEL_INIT	1
+#endif
+
+#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
+#define CONFIG_SPL_BSS_START_ADDR	0x80010000
+#define CONFIG_SPL_BSS_MAX_SIZE		0x10000
+#define CONFIG_SPL_MAX_SIZE		0x10000
+#define CONFIG_SPL_PAD_TO		0
+
+#define CONFIG_MALLOC_F_ADDR		0x80100000	/* FIXME: find a proper place */
+
+/* Dummy value */
+#define CONFIG_SYS_UBOOT_BASE		0
+
+#endif /* __CONFIG_LS1C300_H__ */
diff --git a/include/dt-bindings/clock/ls1c300-clk.h b/include/dt-bindings/clock/ls1c300-clk.h
new file mode 100644
index 0000000000..66798f40c7
--- /dev/null
+++ b/include/dt-bindings/clock/ls1c300-clk.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 Du Huanpeng <dhu@hodcarrier.org>
+ */
+
+#ifndef __DT_BINDINGS_LS1C300_CLK_H__
+#define __DT_BINDINGS_LS1C300_CLK_H__
+
+#define CLK_XTAL	0
+#define CLK_PLL		1
+#define CLK_CPU		2
+#define CLK_APB         3
+#define CLK_CAMERA	4
+#define CLK_PIX		5
+#define CLK_AXIMUX	6
+#define CLK_CPU_THROT	7
+
+#endif /* __DT_BINDINGS_LS1C300_CLK_H__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread
* Re: [PATCH v3] mips: dts: add initial support for ls1c300 SoC
@ 2023-07-22  9:03 dhu
  0 siblings, 0 replies; 4+ messages in thread
From: dhu @ 2023-07-22  9:03 UTC (permalink / raw)
  To: u-boot

> sorry for the late response but I was on vacation ;)
long time no see. :)

> 
> Am Donnerstag, dem 21.04.2022 um 20:31 -0400 schrieb Sean Anderson:
> > On 4/18/22 4:45 PM, Du Huanpeng wrote:
> > > Loongson 1C is a cost-effective SOC chip for industrial control and
> > > the Internet of Things. The Loongson 1C includes a floating-point
> > > processing unit, supports multiple types of memory, and supports
> > > high-capacity MLC NAND Flash. Loongson 1C provides developers with
> > > a
> > > wealth of peripheral interfaces and on-chip modules, including
> > > Camera
> > > controller, USB OTG and USB HOST interfaces, AC97/I2S controller,
> > > LCD
> > > controller, SPI interface, UART interface, etc., providing
> > > sufficient
> > > computing power and multi-application connectivity.
> > > 
> > > Some highlights of this SoC are:
> > > - Single core LS232, MIPS32 instruction set compatible, main
> > > frequency
> > > 300MHZ
> > > - 16KB data cache and 16KB instruction cache
> > > - 64 bit float unit, hardware division
> > > - 8/16 bit SDRAM controller, 45 ~ 133MHz
> > > - 8/16 bit SRAM, NAND
> > > - I2S/AC97, LCD, MAC, USB, OTG, SPI, I2C, PWM, CAN, SDIO, ADC
> > > - 12 UARTs
> > > 
> > > See Technical Reference Manual for details: 
> > > https://www.loongson.cn/
> > > 
> > > introduce base support for the ls1c300 SoC.
> > > - debug UART2
> > > - serial console
> > > - clock
> > > - watchdog
> > > - sysreset
> > > - many uarts
> > > 
> > > Signed-off-by: Du Huanpeng <dhu at hodcarrier.org>
> > > ---
> > > Changelog for v3:
> > >     - change cpu clock id from CLK_CPU to CLK_CPU_THROT
> > >     - migrate all APB dev's clock id to CLK_APB
> > >     - remove uarts' <reg-shift> property to use default value <0>
> > >     - move /clocks/acc node to /soc/acc
> > >     - call clk_request() before use a clk
> > >     - make get_tbclk() return 1/2 clock of cpu
> > >     - disable debug_uart by default
> > >     - add ops for cpu_throt_factor clk
> > >     - declare MSEC_PER_SEC for converting between sec and msec
> > >     - return a error code when the wdt clock is out of range
> > >     - minor format and codingstyle fixes
> > >     - rebase to [9859465bfe838bc8264d45e1a1bed847bba74bad]
> > > 
> > > Changelog for v2:
> > > 1. dtsi:
> > > 	add status disabled for uart0 ~ uart11
> > > 	remove bootargs from chosen
> > > 	make serial0 alias for uart2
> > > 	oscillator remove @0 unit-address
> > > 	change uart2 address to kuseg
> > > 
> > > 2. cleanup Kconfig and update defconfig
> > > - make these options configurable, disabled by default:
> > > 	CMD_DM
> > > 	DM_ETH
> > > 	DM_GPIO
> > > 	DM_SPI
> > > 	DM_SPI_FLASH
> > > 	DM_RESET
> > > 	PINCONF
> > > 	PINCTRL
> > > 	PINMUX
> > > 	RESET_LSMIPS
> > > - make these options configurable, enabled by default:
> > > 	CLK
> > > 	DISPLAY_CPUINFO
> > > 	SYSRESET
> > > 	ROM_EXCEPTION_VECTORS
> > > - disabled:
> > > 	CONFIG_ENV_IS_IN_SPI_FLASH
> > > 
> > > 3. fix codingstyle drivers/watchdog/lsmips-wdt.c
> > > - priv->base + offset
> > > - add comment for default clock value
> > > 
> > > 4. remove address base definition header
> > > - remove arch/mips/mach-lsmips/ls1c300/ls1c300.h
> > > - clean up files uses this header
> > > 
> > > 5. spl and debug uart
> > > - add comment for spl & debug uart pinmuxing
> > > - cleanup unused registers base header
> > > 
> > > 6.  dtsi
> > > - add "loongson,ls1c300-uart" to all uart node
> > > 
> > > 7. board dts
> > > - add memory node to board dts, start at 0x80000000, size 64MB
> > > 
> > > 8. Kconfig
> > > - make ROM_EXCEPTION_VECTORS user configureable
> > > - enable ROM_EXCEPTION_VECTORS in defconfig
> > > 
> > > 9.
> > > - seperate sdram_init to sdram_init.S
> > > - add macro helpers to do sdram, pll lowlevel init
> > > 
> > > 10. dtsi
> > > - move clock nodes to /clocks/xxx
> > > 
> > > 11.
> > > - define CONFIG_SKIP_LOWLEVEL_INIT to 1
> > > 
> > > 12.
> > > - remove option PINCTRL_LS1C300 from Kconfig
> > > 
> > > 13.
> > > - dram_init, use get_ram_size() to detect ram size.
> > > 
> > > 14. clk driver
> > > - create custom clock ops for PLL
> > > - remove debug code
> > > 
> > > 15.
> > > - rebase to 59bffec43a657598b194b9eb30dc01eec06078c7
> > > - remove CONFIG_SYS_MONITOR_BASE from include/configs/
> > > 
> > > > commit e4d741f8abc4a92426d3a826f99390c3abe02d61
> > > > Author: Tom Rini <trini at konsulko.com>
> > > > Date:   Thu Mar 24 17:18:05 2022 -0400
> > > > 
> > > >      Convert CONFIG_SYS_MONITOR_BASE to Kconfig
> > > 
> > >   MAINTAINERS                                   |  13 ++
> > >   arch/mips/Kconfig                             |  11 ++
> > >   arch/mips/Makefile                            |   1 +
> > >   arch/mips/dts/Makefile                        |   1 +
> > >   arch/mips/dts/loongson32-ls1c300b.dtsi        | 141
> > > ++++++++++++++
> > >   arch/mips/dts/ls1c300-eval.dts                |  31 +++
> > >   arch/mips/mach-lsmips/Kconfig                 |  76 ++++++++
> > >   arch/mips/mach-lsmips/Makefile                |   6 +
> > >   arch/mips/mach-lsmips/cpu.c                   |  19 ++
> > >   arch/mips/mach-lsmips/include/mach/serial.h   |  16 ++
> > >   arch/mips/mach-lsmips/ls1c300/Makefile        |   7 +
> > >   arch/mips/mach-lsmips/ls1c300/gpio.c          |  66 +++++++
> > >   arch/mips/mach-lsmips/ls1c300/init.c          |  63 ++++++
> > >   arch/mips/mach-lsmips/ls1c300/lowlevel_init.S | 136 +++++++++++++
> > >   arch/mips/mach-lsmips/ls1c300/sdram.S         |  94 +++++++++
> > >   arch/mips/mach-lsmips/ls1c300/serial.c        | 109 +++++++++++
> > >   arch/mips/mach-lsmips/spl.c                   |  46 +++++
> > >   board/loongson/ls1c300-eval/Kconfig           |  12 ++
> > >   board/loongson/ls1c300-eval/MAINTAINERS       |   7 +
> > >   board/loongson/ls1c300-eval/Makefile          |   3 +
> > >   board/loongson/ls1c300-eval/board.c           |  20 ++
> > >   configs/ls1c300_defconfig                     |  49 +++++
> > >   drivers/clk/Makefile                          |   1 +
> > >   drivers/clk/lsmips/Makefile                   |   3 +
> > >   drivers/clk/lsmips/clk-ls1c300.c              | 180
> > > ++++++++++++++++++
> > >   drivers/watchdog/Kconfig                      |   8 +
> > >   drivers/watchdog/Makefile                     |   1 +
> > >   drivers/watchdog/lsmips_wdt.c                 | 123 ++++++++++++
> > >   include/configs/ls1c300.h                     |  59 ++++++
> > >   include/dt-bindings/clock/ls1c300-clk.h       |  18 ++
> > >   30 files changed, 1320 insertions(+)
> > >   create mode 100644 arch/mips/dts/loongson32-ls1c300b.dtsi
> > >   create mode 100644 arch/mips/dts/ls1c300-eval.dts
> > >   create mode 100644 arch/mips/mach-lsmips/Kconfig
> > >   create mode 100644 arch/mips/mach-lsmips/Makefile
> > >   create mode 100644 arch/mips/mach-lsmips/cpu.c
> > >   create mode 100644 arch/mips/mach-lsmips/include/mach/serial.h
> > >   create mode 100644 arch/mips/mach-lsmips/ls1c300/Makefile
> > >   create mode 100644 arch/mips/mach-lsmips/ls1c300/gpio.c
> > >   create mode 100644 arch/mips/mach-lsmips/ls1c300/init.c
> > >   create mode 100644 arch/mips/mach-lsmips/ls1c300/lowlevel_init.S
> > >   create mode 100644 arch/mips/mach-lsmips/ls1c300/sdram.S
> > >   create mode 100644 arch/mips/mach-lsmips/ls1c300/serial.c
> > >   create mode 100644 arch/mips/mach-lsmips/spl.c
> > >   create mode 100644 board/loongson/ls1c300-eval/Kconfig
> > >   create mode 100644 board/loongson/ls1c300-eval/MAINTAINERS
> > >   create mode 100644 board/loongson/ls1c300-eval/Makefile
> > >   create mode 100644 board/loongson/ls1c300-eval/board.c
> > >   create mode 100644 configs/ls1c300_defconfig
> > >   create mode 100644 drivers/clk/lsmips/Makefile
> > >   create mode 100644 drivers/clk/lsmips/clk-ls1c300.c
> > >   create mode 100644 drivers/watchdog/lsmips_wdt.c
> > >   create mode 100644 include/configs/ls1c300.h
> > >   create mode 100644 include/dt-bindings/clock/ls1c300-clk.h
> > 
> > Once again, please split this up into multiple patches. This makes
> > the
> > series much easier to review.
> 
> Sean is right. Please create separate patches for the SoC, the drivers
> and finally for adding the board. For each driver patch also CC the
> according driver subsystem maintainers.
:) thanks, i will split it and send patch v4.
> 
> > 
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 34446127d4..e1714fb1fc 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -967,6 +967,19 @@ F:	drivers/net/cortina_ni.c
> > >   F:	drivers/net/cortina_ni.h
> > >   F:	drivers/net/phy/ca_phy.c
> > >   
> > > +MIPS LOONGSON LS1C300
> > > +M:	Du Huanpeng <dhu at hodcarrier.org>
> > > +S:	Maintained
> > > +F:	arch/mips/dts/loongson32-ls1c300b.dtsi
> > > +F:	arch/mips/dts/ls1c300-eval.dts
> > > +F:	arch/mips/mach-lsmips/
> > > +F:	board/loongson/ls1c300-eval/
> > > +F:	configs/ls1c300_defconfig
> > > +F:	drivers/clk/lsmips/
> > > +F:	drivers/watchdog/lsmips_wdt.c
> > > +F:	include/configs/ls1c300.h
> > > +F:	include/dt-bindings/clock/ls1c300-clk.h
> > > +
> > >   MIPS MEDIATEK
> > >   M:	Weijie Gao <weijie.gao at mediatek.com>
> > >   R:	GSS_MTK_Uboot_upstream <
> > > GSS_MTK_Uboot_upstream at mediatek.com>
> > > diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> > > index 06cae68ee5..461bb2a99b 100644
> > > --- a/arch/mips/Kconfig
> > > +++ b/arch/mips/Kconfig
> > > @@ -93,6 +93,16 @@ config ARCH_MTMIPS
> > >   	select SUPPORTS_LITTLE_ENDIAN
> > >   	select SUPPORT_SPL
> > >   
> > > +config ARCH_LSMIPS
> > > +	bool "Support Loongson MIPS platforms"
> > > +	select DM
> > > +	select DM_SERIAL
> > > +	select OF_CONTROL
> > > +	select SUPPORTS_CPU_MIPS32_R1
> > > +	select SUPPORTS_CPU_MIPS32_R2
> > > +	select SUPPORTS_LITTLE_ENDIAN
> > > +	select SUPPORT_SPL
> > > +
> > >   config ARCH_JZ47XX
> > >   	bool "Support Ingenic JZ47xx"
> > >   	select SUPPORT_SPL
> > > @@ -175,6 +185,7 @@ source "arch/mips/mach-bmips/Kconfig"
> > >   source "arch/mips/mach-jz47xx/Kconfig"
> > >   source "arch/mips/mach-pic32/Kconfig"
> > >   source "arch/mips/mach-mtmips/Kconfig"
> > > +source "arch/mips/mach-lsmips/Kconfig"
> > >   source "arch/mips/mach-octeon/Kconfig"
> > >   
> > >   if MIPS
> > > diff --git a/arch/mips/Makefile b/arch/mips/Makefile
> > > index 6502aebd29..e944502497 100644
> > > --- a/arch/mips/Makefile
> > > +++ b/arch/mips/Makefile
> > > @@ -16,6 +16,7 @@ machine-$(CONFIG_ARCH_BMIPS) += bmips
> > >   machine-$(CONFIG_ARCH_JZ47XX) += jz47xx
> > >   machine-$(CONFIG_MACH_PIC32) += pic32
> > >   machine-$(CONFIG_ARCH_MTMIPS) += mtmips
> > > +machine-$(CONFIG_ARCH_LSMIPS) += lsmips
> > >   machine-$(CONFIG_ARCH_MSCC) += mscc
> > >   machine-${CONFIG_ARCH_OCTEON} += octeon
> > >   
> > > diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
> > > index 95144b24dc..915acfd573 100644
> > > --- a/arch/mips/dts/Makefile
> > > +++ b/arch/mips/dts/Makefile
> > > @@ -19,6 +19,7 @@ dtb-$(CONFIG_BOARD_MT7620_MT7530_RFB) +=
> > > mediatek,mt7620-mt7530-rfb.dtb
> > >   dtb-$(CONFIG_BOARD_MT7628_RFB) += mediatek,mt7628-rfb.dtb
> > >   dtb-$(CONFIG_BOARD_GARDENA_SMART_GATEWAY_MT7688) += gardena-
> > > smart-gateway-mt7688.dtb
> > >   dtb-$(CONFIG_BOARD_LINKIT_SMART_7688) += linkit-smart-7688.dtb
> > > +dtb-$(CONFIG_BOARD_LS1C300) += ls1c300-eval.dtb
> > >   dtb-$(CONFIG_TARGET_OCTEON_EBB7304) += mrvl,octeon-ebb7304.dtb
> > >   dtb-$(CONFIG_TARGET_OCTEON_NIC23) += mrvl,octeon-nic23.dtb
> > >   dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb
> > > diff --git a/arch/mips/dts/loongson32-ls1c300b.dtsi
> > > b/arch/mips/dts/loongson32-ls1c300b.dtsi
> > > new file mode 100644
> > > index 0000000000..b13bdf189d
> > > --- /dev/null
> > > +++ b/arch/mips/dts/loongson32-ls1c300b.dtsi
> > > @@ -0,0 +1,141 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +#include <dt-bindings/clock/ls1c300-clk.h>
> > > +
> > > +/ {
> > > +	#address-cells = <1>;
> > > +	#size-cells = <1>;
> > > +	compatible = "loongson,ls1c300-soc";
> > > +
> > > +	cpus {
> > > +		#address-cells = <1>;
> > > +		#size-cells = <0>;
> > > +		cpu at 0 {
> > > +			device_type = "cpu";
> > > +			reg = <0>;
> > > +			compatible = "loongson,gs232", "mips,mips4Kc";
> > > +			clocks = <&acc CLK_CPU_THROT>;
> > > +		};
> > > +	};
> > > +
> > > +	clocks {
> > > +		#address-cells = <1>;
> > > +		#size-cells = <1>;
> > > +		u-boot,dm-pre-reloc;
> > > +
> > > +		xtal: oscillator {
> > > +			compatible = "fixed-clock";
> > > +			clock-frequency = <24000000>;
> > > +			#clock-cells = <0>;
> > > +		};
> > > +	};
> > > +
> > > +	soc {
> > > +		#address-cells = <1>;
> > > +		#size-cells = <1>;
> > > +		compatible = "simple-bus";
> > > +		ranges;
> > > +
> > > +		acc: clock-controller at 1fe78030 {
> > > +			compatible = "loongson,ls1c300-clk";
> > > +			clocks = <&xtal>;
> > > +			#clock-cells = <1>;
> > > +			reg = <0x1fe78030 0x8>, <0x1fe7c010 0x4>;
> > > +			u-boot,dm-pre-reloc;
> > > +		};
> > > +
> > > +		uart0: serial at 1fe40000 {
> > > +			compatible = "loongson,ls1c300-uart",
> > > "ns16550a";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe40000 0x100>;
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		uart1: serial at 1fe44000 {
> > > +			compatible = "loongson,ls1c300-uart",
> > > "ns16550a";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe44000 0x100>;
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		uart2: serial at 1fe48000 {
> > > +			compatible = "loongson,ls1c300-uart",
> > > "ns16550a";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe48000 0x100>;
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		uart3: serial at 1fe4c000 {
> > > +			compatible = "loongson,ls1c300-uart",
> > > "ns16550a";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe4c000 0x100>;
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		uart4:  serial at 1fe4c400 {
> > > +			compatible = "loongson,ls1c300-uart",
> > > "ns16550a";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe4c400 0x100>;
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		uart5:  serial at 1fe4c500 {
> > > +			compatible = "loongson,ls1c300-uart",
> > > "ns16550a";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe4c500 0x100>;
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		uart6:  serial at 1fe4c600 {
> > > +			compatible = "loongson,ls1c300-uart",
> > > "ns16550a";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe4c600 0x100>;
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		uart7:  serial at 1fe4c700 {
> > > +			compatible = "loongson,ls1c300-uart",
> > > "ns16550a";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe4c700 0x100>;
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		uart8:  serial at 1fe4c800 {
> > > +			compatible = "loongson,ls1c300-uart",
> > > "ns16550a";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe4c800 0x100>;
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		uart9:  serial at 1fe4c900 {
> > > +			compatible = "loongson,ls1c300-uart",
> > > "ns16550a";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe4c900 0x100>;
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		uart10: serial at 1fe4ca00 {
> > > +			compatible = "loongson,ls1c300-uart",
> > > "ns16550a";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe4ca00 0x100>;
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		uart11: serial at 1fe4cb00 {
> > > +			compatible = "loongson,ls1c300-uart",
> > > "ns16550a";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe4cb00 0x100>;
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		wdt: watchdog at 1fe5c060 {
> > > +			compatible = "loongson,ls1c300-wdt";
> > > +			clocks = <&acc CLK_APB>;
> > > +			reg = <0x1fe5c060 0x10>;
> > > +		};
> > > +
> > > +		reset-controller {
> > > +			compatible = "wdt-reboot";
> > > +			wdt = <&wdt>;
> > > +		};
> > > +	};
> > > +};
> > > diff --git a/arch/mips/dts/ls1c300-eval.dts
> > > b/arch/mips/dts/ls1c300-eval.dts
> > > new file mode 100644
> > > index 0000000000..eaf65b2d96
> > > --- /dev/null
> > > +++ b/arch/mips/dts/ls1c300-eval.dts
> > > @@ -0,0 +1,31 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright (C) 2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +/dts-v1/;
> > > +
> > > +#include "loongson32-ls1c300b.dtsi"
> > > +
> > > +/ {
> > > +	compatible = "lsmips,ls1c300-soc";
> > > +	model = "ls1c300-eval";
> > > +
> > > +	aliases {
> > > +		serial0 = &uart2;
> > > +	};
> > > +
> > > +	memory at 80000000 {
> > > +		device_type = "memory";
> > > +		reg = <0x80000000 0x4000000>;
> > > +	};
> > > +
> > > +	chosen {
> > > +		stdout-path = "serial0:115200n8";
> > > +	};
> > > +};
> > > +
> > > +&uart2 {
> > > +	status = "okay";
> > > +};
> > > +
> > > diff --git a/arch/mips/mach-lsmips/Kconfig b/arch/mips/mach-
> > > lsmips/Kconfig
> > > new file mode 100644
> > > index 0000000000..2092e6ef35
> > > --- /dev/null
> > > +++ b/arch/mips/mach-lsmips/Kconfig
> > > @@ -0,0 +1,76 @@
> > > +menu "Loongson MIPS platforms"
> > > +	depends on ARCH_LSMIPS
> > > +
> > > +config SYS_MALLOC_F_LEN
> > > +	default 0x1000
> > > +
> > > +config SYS_SOC
> > > +	default "ls1c300" if SOC_LS1C300
> > > +
> > > +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_TEXT_BASE
> > > +	default 0xbfc00000 if !SPL
> > > +	default 0x80200000 if SPL
> > > +
> > > +config SPL_TEXT_BASE
> > > +	default 0xbfc00000
> > > +
> > > +config SPL_PAYLOAD
> > > +	default "u-boot-lzma.img" if SPL_LZMA
> > > +
> > > +config BUILD_TARGET
> > > +	default "u-boot-with-spl.bin" if SPL
> > > +	default "u-boot.bin" if !SPL
> > > +
> > > +choice
> > > +	prompt "Loongson MIPS SoC select"
> > > +
> > > +config SOC_LS1C300
> > > +	bool "LS1C300"
> > > +	select CLK_CCF
> > > +	select SPL_SEPARATE_BSS if SPL
> > > +	select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL
> > > +	select SPL_LOADER_SUPPORT if SPL
> > > +	select SPL_OF_CONTROL if SPL_DM
> > > +	select SPL_SIMPLE_BUS if SPL_DM
> > > +	select SPL_DM_SERIAL if SPL_DM
> > > +	select SPL_CLK if SPL_DM && SPL_SERIAL
> > > +	select SPL_SYSRESET if SPL_DM
> > > +	select SPL_OF_LIBFDT if SPL_OF_CONTROL
> > > +	help
> > > +	  This supports Loongson LS1C300
> > 
> > I just want to state for the record here that the size constraint on
> > this processor is 1MiB XIP, so there is no need to use SPL AFAICT. If
> > you insist on SPL you can enable SPL_DM. That way you can use pinctrl
> > drivers.
> 
> I guess this is inspired from Mediatek MIPS baords, where a small SPL +
> LZMA compressed U-Boot decreases the boot time. But I agree with
> pinctrl and SPL_DM.
I SPL because I need a RAM version u-boot for debug easier. I load the u-boot
from tftp server by shiped bootloader. later I also want to load u-boot from
tftp server by u-boot. this avoids burn the binary to flash everytime.

pinmux and uart setup is needed by debug uart(debug_uart_init), which is
called from arch/mips/cpu/start.S, so I want to make the code can works without
C environment.
the SPL u-boot uart shares these code.
it seems the SPL u-boot will do nothing but load the u-boot(ram version), 
is it very necessary to add SPL_DM? :) 
pinctrl driver, I wall add it later for the u-boot(ram version).

> 
> > 
> > > +endchoice
> > > +
> > > +choice
> > > +	prompt "Board select"
> > > +
> > > +config BOARD_LS1C300
> > > +	bool "Loongson LS1C300 Eval"
> > > +	depends on SOC_LS1C300
> > > +	help
> > > +	  ls1c300-eval board has a LS1C300 SoC with 64MiB of SDRAM
> > > +	  and 512KiB of flash (SPI NOR) and additional NAND storage.
> > > +
> > > +endchoice
> > > +
> > > +config CONS_PIN
> > > +	int "pin group used in uart"
> > > +	default 0
> > > +	help
> > > +	  Select pin group connected to UART for your board.
> > > +
> > > +source "board/loongson/ls1c300-eval/Kconfig"
> > > +
> > > +endmenu
> > > diff --git a/arch/mips/mach-lsmips/Makefile b/arch/mips/mach-
> > > lsmips/Makefile
> > > new file mode 100644
> > > index 0000000000..654143a5f7
> > > --- /dev/null
> > > +++ b/arch/mips/mach-lsmips/Makefile
> > > @@ -0,0 +1,6 @@
> > > +# SPDX-License-Identifier: GPL-2.0+
> > > +
> > > +obj-y += cpu.o
> > > +obj-$(CONFIG_SPL_BUILD) += spl.o
> > > +
> > > +obj-$(CONFIG_SOC_LS1C300) += ls1c300/
> > > diff --git a/arch/mips/mach-lsmips/cpu.c b/arch/mips/mach-
> > > lsmips/cpu.c
> > > new file mode 100644
> > > index 0000000000..4205d8ef83
> > > --- /dev/null
> > > +++ b/arch/mips/mach-lsmips/cpu.c
> > > @@ -0,0 +1,19 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +/*
> > > + * Copyright (C) 2018 Stefan Roese <sr at denx.de>
> > > + */
> > > +
> > > +#include <common.h>
> > > +#include <init.h>
> > > +#include <malloc.h>
> > > +#include <linux/bitops.h>
> > > +#include <linux/io.h>
> > > +#include <linux/sizes.h>
> > > +
> > > +DECLARE_GLOBAL_DATA_PTR;
> > > +
> > > +int dram_init(void)
> > > +{
> > > +	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
> > > SZ_256M);
> > > +	return 0;
> > > +}
> > > diff --git a/arch/mips/mach-lsmips/include/mach/serial.h
> > > b/arch/mips/mach-lsmips/include/mach/serial.h
> > > new file mode 100644
> > > index 0000000000..4da1cb434c
> > > --- /dev/null
> > > +++ b/arch/mips/mach-lsmips/include/mach/serial.h
> > > @@ -0,0 +1,16 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/*
> > > + * Copyright (C) 2020 MediaTek Inc.
> > > + *
> > > + * Author:  Gao Weijie <weijie.gao at mediatek.com>
> > > + *
> > > + * Copyright (C) 2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +#ifndef __LSMIPS_SERIAL_H_
> > > +#define __LSMIPS_SERIAL_H_
> > > +
> > > +void lsmips_spl_serial_init(void);
> > > +int gpio_set_alternate(int gpio, int func);
> > > +
> > > +#endif /* __LSMIPS_SERIAL_H_ */
> > > diff --git a/arch/mips/mach-lsmips/ls1c300/Makefile
> > > b/arch/mips/mach-lsmips/ls1c300/Makefile
> > > new file mode 100644
> > > index 0000000000..17b9d6fb9c
> > > --- /dev/null
> > > +++ b/arch/mips/mach-lsmips/ls1c300/Makefile
> > > @@ -0,0 +1,7 @@
> > > +# SPDX-License-Identifier: GPL-2.0
> > > +
> > > +obj-y += lowlevel_init.o
> > > +obj-y += sdram.o
> > > +obj-y += init.o
> > > +obj-y += gpio.o
> > > +obj-$(CONFIG_SPL_BUILD) += serial.o
> > > diff --git a/arch/mips/mach-lsmips/ls1c300/gpio.c b/arch/mips/mach-
> > > lsmips/ls1c300/gpio.c
> > > new file mode 100644
> > > index 0000000000..2195738b2b
> > > --- /dev/null
> > > +++ b/arch/mips/mach-lsmips/ls1c300/gpio.c
> > > @@ -0,0 +1,66 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +/*
> > > + * Copyright (C) 2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +#include <linux/errno.h>
> > > +#include <asm/bitops.h>
> > > +
> > > +#define CBUS_FIRST0	0xbfd011c0
> > > +#define CBUS_SECOND0	0xbfd011d0
> > > +#define CBUS_THIRD0	0xbfd011e0
> > > +#define CBUS_FOURTHT0	0xbfd011f0
> > > +#define CBUS_FIFTHT0	0xbfd01200
> > > +
> > > +#define CBUS_FIRST1	0xbfd011c4
> > > +#define CBUS_SECOND1	0xbfd011d4
> > > +#define CBUS_THIRD1	0xbfd011e4
> > > +#define CBUS_FOURTHT1	0xbfd011f4
> > > +#define CBUS_FIFTHT1	0xbfd01204
> > > +
> > > +#define CBUS_FIRST2	0xbfd011c8
> > > +#define CBUS_SECOND2	0xbfd011d8
> > > +#define CBUS_THIRD2	0xbfd011e8
> > > +#define CBUS_FOURTHT2	0xbfd011f8
> > > +#define CBUS_FIFTHT2	0xbfd01208
> > > +
> > > +#define CBUS_FIRST3	0xbfd011cc
> > > +#define CBUS_SECOND3	0xbfd011dc
> > > +#define CBUS_THIRD3	0xbfd011ec
> > > +#define CBUS_FOURTHT3	0xbfd011fc
> > > +#define CBUS_FIFTHT3	0xbfd0120c
> > > +
> > > +/*
> > > + * pinmux for debug uart and spl only, for others, please
> > > + * use a pinctrl driver and device-tree for pin muxing.
> > > + *
> > > + * @gpio: gpio number
> > > + * @func: alternate function 1 to 5, 0 for GPIO.
> > > + */
> > > +
> > > +int gpio_set_alternate(int gpio, int func)
> > > +{
> > > +	volatile void __iomem *addr;
> > > +	int i;
> > > +
> > > +	if (gpio < 0 || gpio > 104)
> > > +		return -ENODEV;
> > > +	if (func < 0 || func > 5)
> > > +		return -EINVAL;
> > > +
> > > +	if (func) {
> > > +		i = func - 1;
> > > +		addr = (void *)CBUS_FIRST0 + i * 16;
> > > +		set_bit(gpio, addr);
> > > +	} else {
> > > +		/* GPIO, clear CBUS 1 ~ 5 */
> > > +		i = 5;
> > > +	}
> > > +
> > > +	while (i--) {
> > > +		addr = (void *)CBUS_FIRST0 + 16 * i;
> > > +		clear_bit(gpio, addr);
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > 
> > So this can e.g. be in a pinctrl driver.
> > 
> > > diff --git a/arch/mips/mach-lsmips/ls1c300/init.c b/arch/mips/mach-
> > > lsmips/ls1c300/init.c
> > > new file mode 100644
> > > index 0000000000..d515bd2f86
> > > --- /dev/null
> > > +++ b/arch/mips/mach-lsmips/ls1c300/init.c
> > > @@ -0,0 +1,63 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright (C) 2020 MediaTek Inc.
> > > + *
> > > + * Author:  Gao Weijie <weijie.gao at mediatek.com>
> > > + *
> > > + * based on: arch/mips/mach-mtmips/mt7628/init.c
> > > + * Copyright (C) 2020-2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +#include <common.h>
> > > +#include <clk.h>
> > > +#include <dm.h>
> > > +#include <dm/uclass.h>
> > > +#include <dt-bindings/clock/ls1c300-clk.h>
> > > +#include <linux/io.h>
> > > +#include <linux/sizes.h>
> > > +
> > > +DECLARE_GLOBAL_DATA_PTR;
> > > +
> > > +int print_cpuinfo(void)
> > > +{
> > > +	struct udevice *udev;
> > > +	struct clk clk;
> > > +	int ret;
> > > +	ulong xtal;
> > > +	char buf[SZ_32];
> > > +
> > > +	printf("CPU: Loongson ls1c300b\n");
> > > +
> > > +	ret = uclass_get_device_by_driver(UCLASS_CLK,
> > > DM_DRIVER_GET(ls1c300_clk), &udev);
> > > +
> > 
> > nit: no blank line here
> > 
> > > +	if (ret) {
> > > +		printf("error: clock driver not found.\n");
> > > +		return 0;
> > > +	}
> > > +
> > > +	clk.dev = udev;
> > > +
> > > +	ret = clk_request(udev, &clk);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	clk.id = CLK_XTAL;
> > > +	xtal = clk_get_rate(&clk);
> > > +
> > > +	clk.id = CLK_CPU_THROT;
> > > +	gd->cpu_clk = clk_get_rate(&clk);
> > > +
> > > +	clk.id = CLK_APB;
> > > +	gd->mem_clk = clk_get_rate(&clk);
> > 
> > Again, all these clocks must be requested first.
> > 
> > > +
> > > +	printf("Clock: CPU: %sMHz, ", strmhz(buf, gd->cpu_clk));
> > > +	printf("SDRAM: %sMHz, ", strmhz(buf, gd->mem_clk));
> > > +	printf("XTAL: %sMHz\n", strmhz(buf, xtal));
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +ulong notrace get_tbclk(void)
> > > +{
> > > +	return gd->cpu_clk / 2;
> > > +}
> > > diff --git a/arch/mips/mach-lsmips/ls1c300/lowlevel_init.S
> > > b/arch/mips/mach-lsmips/ls1c300/lowlevel_init.S
> > > new file mode 100644
> > > index 0000000000..a8d1359cf5
> > > --- /dev/null
> > > +++ b/arch/mips/mach-lsmips/ls1c300/lowlevel_init.S
> > > @@ -0,0 +1,136 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/*
> > > + * Copyright (C) 2020 MediaTek Inc.
> > > + *
> > > + * Author:  Gao Weijie <weijie.gao at mediatek.com>
> > > + *
> > > + * Copyright (C) 2020-2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +#include <config.h>
> > > +#include <asm-offsets.h>
> > > +#include <asm/cacheops.h>
> > > +#include <asm/regdef.h>
> > > +#include <asm/mipsregs.h>
> > > +#include <asm/addrspace.h>
> > > +#include <asm/asm.h>
> > > +#include <linux/sizes.h>
> > > +
> > > +/* PLL control register */
> > > +#define NAND_BASE	0xbfe70000
> > > +#define START_FREQ	0x8030
> > > +#define CLK_DIV_PARAM	0x8034
> > > +#define CPU_THROT	0xc010
> > > +
> > > +/* START_FREQ */
> > > +#define PLL_VALID	31
> > > +#define Reserved_24	24
> > > +#define FRAC_N		16
> > > +#define M_PLL		8
> > > +#define Reserved_4	4
> > > +#define RST_TIME	2
> > > +#define SDRAM_DIV	0
> > > + #define SDRAM_DIV2	0
> > > + #define SDRAM_DIV4	1
> > > + #define SDRAM_DIV3	2
> > > +
> > > +/* CLK_DIV_PARAM */
> > > +#define PIX_DIV		24
> > > +#define CAM_DIV		16
> > > +#define CPU_DIV		8
> > > +#define PIX_DIV_VALID	5
> > > +#define PIX_SEL		4
> > > +#define CAM_DIV_VALID	3
> > > +#define CAM_SEL		2
> > > +#define CPU_DIV_VALID	1
> > > +#define CPU_SEL		0
> > > +
> > > +/* Document:
> > > + * Freq_PLL = XIN *(M_PLL + FRAC_N)/4
> > > + */
> > > +#define XIN			24000000
> > > +#define PLL_VALID_1		(1<<PLL_VALID)
> > > +#define PREP_M_PLL(Freq_PLL)	(((Freq_PLL * 4) / XIN) <<
> > > M_PLL)
> > > +#define PREP_SDRAM_DIV(div)	(div<<SDRAM_DIV)
> > > +#define PREP_CPU_DIV(div1)	((0x80|div1)<<CPU_DIV |
> > > (div1&&div1)<<CPU_DIV_VALID)
> > > +#define PREP_PIX_DIV(div2)	(div2<<PIX_DIV)
> > > +#define PREP_CAM_DIV(div3)	(div3<<CAM_DIV)
> > > +
> > > +/* PLL @264MHz, CPU @132MHz, SDRAM @66MHz */
> > > +#define CFG_START_FREQ		(PLL_VALID_1 |
> > > PREP_M_PLL(264000000) | SDRAM_DIV2)
> > > +#define CFG_CLK_DIV_PARAM	(PREP_CPU_DIV(2) | PREP_PIX_DIV(0x24) |
> > > PREP_CAM_DIV(0x24))
> > > +#define CFG_CPU_THROT		15
> > > +
> > > +/* SPI0 control register */
> > > +#define SPI0_BASE		0xbfe80000
> > > +#define SPCR			0
> > > +#define SPSR			1
> > > +#define TxFIFO			2
> > > +#define RxFIFO			2
> > > +#define SPER			3
> > > +#define SFC_PARAM		4
> > > +    #define CLK_DIV		4
> > > +    #define DUAL_IO		3
> > > +    #define FAST_READ		2
> > > +    #define BURST_EN		1
> > > +    #define MEMORY_EN		0
> > > +#define SFC_SOFTCS		5
> > > +#define SFC_TIMING		6
> > > +    #define T_FAST		2
> > > +    #define T_CSH		0
> > > +
> > > +	.set noreorder
> 
> as a general rule for MIPS assembly:
> - don't use noreorder if not really required to let the assembler
> optimize the instructions in the branch delay slots. For your
> lowlevel_init code I don't see any reason for noreorder
> - if you use noreorder, indent all instructins in the delay slot by 1
> space to make the code more readable. If there are no useful
> instructions, always add a nop
> 
> > > +LEAF(ls1c300_pll_init)
> > > +#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
> > > +	li	t0, NAND_BASE
> > > +	li	t1, CFG_START_FREQ
> > > +	li	t2, CFG_CLK_DIV_PARAM
> > > +	li	t3, CFG_CPU_THROT
> > > +
> > > +	sw	t3, CPU_THROT (t0)
> > > +	sw	t2, CLK_DIV_PARAM (t0)
> > > +	sw	t1, START_FREQ (t0)
> > > +	  nop
> 
> superfluous nop
fixed.
> 
> > > +
> > > +	ori	t2, 1<<CPU_SEL
> > > +	sw	t2, CLK_DIV_PARAM (t0)
> > > +#endif
> > > +	li	v0, 264000000
> > > +	jr	ra
> > > +	nop
> 
> the "li	v0, 264000000" could be put in the delay slot or just don't use
> noreorder to let the assembler do that
I am not sure if the "li v0, 264000000" can be capable put a delay slot,
but I am sure if I change the value for example 0xfbc5200,
it will assembly into two instructions,
  lui v0, 0xfbc
  ori v0, 0x5200
so, i take the lazy way to avoid mistake, don't use delay slot here.

> 
> > > +END(ls1c300_pll_init)
> > > +
> > > +LEAF(ls1c300_spi_init)
> > > +#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
> > > +	li	t0, SPI0_BASE
> > > +	li	t1, (1<<MEMORY_EN) | (1<<BURST_EN) | (1<<FAST_READ) |
> > > (1<<DUAL_IO)
> > > +	sb	t1, SFC_PARAM (t0)
> > > +	li	t2, (1<<T_FAST) | (1<<T_CSH)
> > > +	sb	t2, SFC_TIMING (t0)
> > > +#endif
> > > +	jr	ra
> > > +	  nop
> > > +END(ls1c300_spi_init)
> > > +
> > > +NESTED(lowlevel_init, 0, ra)
> > > +	/* Save ra and do real lowlevel initialization */
> > > +	move	s0, ra
> > > +	/* Setup PLL @264MHz */
> > > +	PTR_LA	t9, ls1c300_pll_init
> > > +	jalr	t9
> > > +	  nop
> > > +
> > > +	/* Setup SPI Dual IO at 33MHz */
> > > +	PTR_LA	t9, ls1c300_spi_init
> > > +	jalr	t9
> > > +	  nop
> > > +
> > > +	/* Setup external SDRAM @66MHz */
> > > +	PTR_LA	t9, ls1c300_sdram_init
> > > +	jalr	t9
> > > +	  nop
> > > +
> > > +	move	ra, s0
> > > +	jr	ra
> > > +	 nop
> 
> the "move	ra, s0" could be put in the delay slot
> 
> > > +END(lowlevel_init)
> > > diff --git a/arch/mips/mach-lsmips/ls1c300/sdram.S
> > > b/arch/mips/mach-lsmips/ls1c300/sdram.S
> > > new file mode 100644
> > > index 0000000000..95d21f0093
> > > --- /dev/null
> > > +++ b/arch/mips/mach-lsmips/ls1c300/sdram.S
> > > @@ -0,0 +1,94 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/*
> > > + * Copyright (C) 2020-2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +#include <config.h>
> > > +#include <asm-offsets.h>
> > > +#include <asm/cacheops.h>
> > > +#include <asm/regdef.h>
> > > +#include <asm/mipsregs.h>
> > > +#include <asm/addrspace.h>
> > > +#include <asm/asm.h>
> > > +#include <linux/sizes.h>
> > > +
> > > +/* sdram control 64 bit register */
> > > +#define SD_CONFIG	0xbfd00000
> > > +#define SD_CONFIGHI	0x414
> > > +#define SD_CONFIGLO	0x410
> > > +
> > > +#define CONFIG_VALID	41
> > > +#define HANG_UP		40
> > > +#define DEF_SEL		39
> > > +#define TWR		37
> > > +#define TREF		25
> > > +#define TRAS		21
> > > +#define TRFC		17
> > > +#define TRP		14
> > > +#define TCL		11
> > > +#define TRCD		8
> > > +
> > > +#define SD_BIT		6
> > > +  #define SD_8BIT       (0<<SD_BIT)
> > > +  #define SD_16BIT      (1<<SD_BIT)
> > > +  #define SD_32BIT      (2<<SD_BIT)
> > > +#define SD_CSIZE	3
> > > +  #define SD_CSIZE_512	(0<<SD_CSIZE)
> > > +  #define SD_CSIZE_1K	(1<<SD_CSIZE)
> > > +  #define SD_CSIZE_2K	(2<<SD_CSIZE)
> > > +  #define SD_CSIZE_4K	(3<<SD_CSIZE)
> > > +  #define SD_CSIZE_256	(7<<SD_CSIZE)
> > > +#define SD_RSIZE	0
> > > +  #define SD_RSIZE_2K	(0<<SD_RSIZE)
> > > +  #define SD_RSIZE_4K	(1<<SD_RSIZE)
> > > +  #define SD_RSIZE_8K	(2<<SD_RSIZE)
> > > +  #define SD_RSIZE_16K	(3<<SD_RSIZE)
> > > +
> > > +#define SD_CFG_1(tWR, tREF, tRAS, tRFC, tRP, tCL, tRCD) \
> > > +	((tWR<<TWR)|(tREF<<TREF)|(tRAS<<TRAS)|(tRFC<<TRFC)|(tRP<<TRP)|(
> > > tCL<<TCL)|(tRCD<<TRCD))
> > > +#define CFG_SD_0(b, c, r) \
> > > +	((b<<SD_BIT)|(c<<SD_CSIZE)|(r<<SD_RSIZE))
> > > +/*
> > > + * recommended values by ls1c300 user manual,
> > > + * tweat to fit your board.
> > 
> > nit: tweak
> > 
> > > + */
> > > +#define SD_CONFIG_133MHz	SD_CFG_1(2, 0x818, 6, 8, 3, 3, 3)
> > > +#define SD_CONFIG_100MHz	SD_CFG_1(2, 0x620, 5, 6, 2, 3, 2)
> > > +#define SD_CONFIG_75MHz		SD_CFG_1(1, 0x494, 4, 5, 2, 2,
> > > 2)
> > > +#define SD_CONFIG_33MHz		SD_CFG_1(1, 0x204, 2, 2, 1, 2,
> > > 1)
> > > +
> > > +#define SD_CONFIG_66MHz		SD_CFG_1(1, 0x401, 4, 4, 2, 2,
> > > 2)
> > > +
> > > +#define SD_CONFIG64	(SD_CONFIG_66MHz | SD_16BIT |
> > > SD_CSIZE_1K | SD_RSIZE_8K)
> > > +#define CFG_SDCONFIGHI	(SD_CONFIG64 /(1<<32))
> > > +#define CFG_SDCONFIGLO	(SD_CONFIG64 %(1<<32))
> > > +
> > > +	.set noreorder
> > > +/*
> > > + * Loongson ls1c300 SoC do not have onchip sram for initial stack,
> > > + * initialize the external sdram on reset as early as possiable.
> > > + */
> > > +LEAF(ls1c300_sdram_init)
> > > +#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
> > > +	li	t0, SD_CONFIG
> > > +	li	t1, CFG_SDCONFIGLO
> > > +	li	t2, CFG_SDCONFIGHI
> > > +
> > > +	sw	t1, SD_CONFIGLO (t0)
> > > +	sw	t2, SD_CONFIGHI (t0)
> > > +	nop
> > > +
> > > +	sw	t1, SD_CONFIGLO (t0)
> > > +	sw	t2, SD_CONFIGHI (t0)
> > > +	nop
> 
> superfluous nop and why storing twice?
I do as the hardware manual describe, now I added a comment for this.

> 
> > > +
> > > +	ori	t2, 1<<(CONFIG_VALID-32)
> > > +	sw	t1, SD_CONFIGLO (t0)
> > > +	sw	t2, SD_CONFIGHI (t0)
> > > +#endif
> > > +	li	v0, SZ_64M
> > > +	jr	ra
> > > +	 nop
> > > +END(ls1c300_sdram_init)
> > > +
> > > +
> > > diff --git a/arch/mips/mach-lsmips/ls1c300/serial.c
> > > b/arch/mips/mach-lsmips/ls1c300/serial.c
> > > new file mode 100644
> > > index 0000000000..93fd653385
> > > --- /dev/null
> > > +++ b/arch/mips/mach-lsmips/ls1c300/serial.c
> > > @@ -0,0 +1,109 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright (C) 2020 MediaTek Inc.
> > > + *
> > > + * Author:  Gao Weijie <weijie.gao at mediatek.com>
> > > + *
> > > + * Copyright (C) 2020-2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +#include <mach/serial.h>
> > > +#include <linux/kernel.h>
> > > +
> > > +struct uart_pin_config {
> > > +	char port;
> > > +	char af;
> > > +	char rx;
> > > +	char tx;
> > > +};
> > > +
> > > +struct uart_pin_config con[] = {
> > > +#if CONFIG_CONS_INDEX == 0
> > > +	{ 0, 2, 74, 75 },
> > > +	{ 0, 3, 23, 24 },
> > > +	{ 0, 3, 99, 100 },
> > > +
> > > +#elif CONFIG_CONS_INDEX == 1
> > > +	{ 1, 1, 17, 18 },
> > > +	{ 1, 1, 101, 102 },
> > > +	{ 1, 2, 40, 41 },
> > > +	{ 1, 4, 2, 3 },
> > > +
> > > +#elif CONFIG_CONS_INDEX == 2
> > > +	{ 2, 2, 36, 37 },
> > > +	{ 2, 2, 42, 43 },
> > > +	{ 2, 3, 27, 28 },
> > > +	{ 2, 3, 103, 104 },
> > > +	{ 2, 4, 4, 5 },
> > > +
> > > +#elif CONFIG_CONS_INDEX == 3
> > > +	{ 3, 2, 17, 18 },
> > > +	{ 3, 2, 33, 34 },
> > > +	{ 3, 2, 44, 45 },
> > > +	{ 3, 4, 0, 1 },
> > > +
> > > +#elif CONFIG_CONS_INDEX == 4
> > > +	{ 4, 5, 23, 24 },
> > > +	{ 4, 5, 58, 59 },
> > > +	{ 4, 5, 80, 79 },
> > > +
> > > +#elif CONFIG_CONS_INDEX == 5
> > > +	{ 5, 5, 25, 26 },
> > > +	{ 5, 5, 60, 61 },
> > > +	{ 5, 5, 81, 78 },
> > > +
> > > +#elif CONFIG_CONS_INDEX == 6
> > > +	{ 6, 5, 27, 46 },
> > > +	{ 6, 5, 62, 63 },
> > > +
> > > +#elif CONFIG_CONS_INDEX == 7
> > > +	{ 7, 5, 57, 56 },
> > > +	{ 7, 5, 64, 65 },
> > > +	{ 7, 5, 87, 88 },
> > > +
> > > +#elif CONFIG_CONS_INDEX == 8
> > > +	{ 8, 5, 55, 54 },
> > > +	{ 8, 5, 66, 67 },
> > > +	{ 8, 5, 89, 90 },
> > > +
> > > +#elif CONFIG_CONS_INDEX == 9
> > > +	{ 9, 5, 53, 52 },
> > > +	{ 9, 5, 68, 69 },
> > > +	{ 9, 5, 85, 86 },
> > > +
> > > +#elif CONFIG_CONS_INDEX == 10
> > > +	{ 10, 5, 51, 50 },
> > > +	{ 10, 5, 70, 71 },
> > > +	{ 10, 5, 84, 82 },
> > > +
> > > +#elif CONFIG_CONS_INDEX == 11
> > > +	{ 11, 5, 49, 48 },
> > > +	{ 11, 5, 72, 73 },
> > > +#endif /* CONFIG_CONS_INDEX */
> > > +};
> > > +
> > > +#define UART2_RX	36
> > > +#define UART2_TX	37
> > > +#define AFUNC		2
> > > +
> > > +void lsmips_spl_serial_init(void)
> > > +{
> > > +#if defined(CONFIG_SPL_SERIAL)
> > > +	int pin_rx, pin_tx;
> > > +	int afunc;
> > > +
> > > +	if (CONFIG_CONS_PIN < ARRAY_SIZE(con)) {
> > > +		pin_rx = con[CONFIG_CONS_PIN].rx;
> > > +		pin_tx = con[CONFIG_CONS_PIN].tx;
> > > +		afunc = con[CONFIG_CONS_PIN].af;
> > > +	} else {
> > > +		pin_rx = UART2_RX;
> > > +		pin_tx = UART2_TX;
> > > +		afunc = AFUNC;
> > > +	}
> > > +
> > > +	gpio_set_alternate(pin_rx, afunc);
> > > +	gpio_set_alternate(pin_tx, afunc);
> > > +#endif /* CONFIG_SPL_SERIAL */
> > > +	return;
> > > +}
> > 
> > This can also be pinctrl.
> > 
> > > diff --git a/arch/mips/mach-lsmips/spl.c b/arch/mips/mach-
> > > lsmips/spl.c
> > > new file mode 100644
> > > index 0000000000..21c49197ae
> > > --- /dev/null
> > > +++ b/arch/mips/mach-lsmips/spl.c
> > > @@ -0,0 +1,46 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
> > > + *
> > > + * Author: Gao Weijie <weijie.gao at mediatek.com>
> > > + *
> > > + * Copyright (C) 2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +#include <common.h>
> > > +#include <init.h>
> > > +#include <spl.h>
> > > +#include <asm/sections.h>
> > > +#include <linux/libfdt.h>
> > > +#include <linux/sizes.h>
> > > +#include <mach/serial.h>
> > > +
> > > +void __noreturn board_init_f(ulong dummy)
> > > +{
> > > +	spl_init();
> > > +
> > > +#if defined(CONFIG_SPL_SERIAL)
> > > +	/*
> > > +	 * lsmips_spl_serial_init() is useful if debug uart is enabled,
> > > +	 * or DM based serial is not enabled.
> > > +	 */
> > > +	lsmips_spl_serial_init();
> > > +	preloader_console_init();
> > > +#endif
> > > +	board_init_r(NULL, 0);
> > > +}
> > > +
> > > +void board_boot_order(u32 *spl_boot_list)
> > > +{
> > > +	spl_boot_list[0] = BOOT_DEVICE_NOR;
> > > +}
> > > +
> > > +unsigned long spl_nor_get_uboot_base(void)
> > > +{
> > > +	void *uboot_base = __image_copy_end;
> > > +
> > > +	if (fdt_magic(uboot_base) == FDT_MAGIC)
> > > +		return (unsigned long)uboot_base +
> > > fdt_totalsize(uboot_base);
> > > +
> > > +	return (unsigned long)uboot_base;
> > > +}
> > > diff --git a/board/loongson/ls1c300-eval/Kconfig
> > > b/board/loongson/ls1c300-eval/Kconfig
> > > new file mode 100644
> > > index 0000000000..e427570a83
> > > --- /dev/null
> > > +++ b/board/loongson/ls1c300-eval/Kconfig
> > > @@ -0,0 +1,12 @@
> > > +if BOARD_LS1C300
> > > +
> > > +config SYS_BOARD
> > > +	default "ls1c300-eval"
> > > +
> > > +config SYS_VENDOR
> > > +	default "loongson"
> > > +
> > > +config SYS_CONFIG_NAME
> > > +	default "ls1c300"
> > > +
> > > +endif
> > > diff --git a/board/loongson/ls1c300-eval/MAINTAINERS
> > > b/board/loongson/ls1c300-eval/MAINTAINERS
> > > new file mode 100644
> > > index 0000000000..5420198dab
> > > --- /dev/null
> > > +++ b/board/loongson/ls1c300-eval/MAINTAINERS
> > > @@ -0,0 +1,7 @@
> > > +LS1C300_EVAL BOARD
> > > +M:	Du Huanpeng<dhu at hodcarrier.org>
> > > +S:	Maintained
> > > +F:	board/loongson/ls1c300-eval
> > > +F:	include/configs/ls1c300.h
> > > +F:	configs/ls1c300_defconfig
> > > +F:	arch/mips/dts/ls1c300-eval.dts
> > > diff --git a/board/loongson/ls1c300-eval/Makefile
> > > b/board/loongson/ls1c300-eval/Makefile
> > > new file mode 100644
> > > index 0000000000..db129c5aba
> > > --- /dev/null
> > > +++ b/board/loongson/ls1c300-eval/Makefile
> > > @@ -0,0 +1,3 @@
> > > +# SPDX-License-Identifier: GPL-2.0
> > > +
> > > +obj-y += board.o
> > > diff --git a/board/loongson/ls1c300-eval/board.c
> > > b/board/loongson/ls1c300-eval/board.c
> > > new file mode 100644
> > > index 0000000000..6809d66515
> > > --- /dev/null
> > > +++ b/board/loongson/ls1c300-eval/board.c
> > > @@ -0,0 +1,20 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright (C) 2020-2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +#include <common.h>
> > > +#include <mach/serial.h>
> > > +
> > > +#if defined(CONFIG_DEBUG_UART_BOARD_INIT)
> > > +
> > > +#define UART2_RX	36
> > > +#define UART2_TX	37
> > > +#define AFUNC		2
> > > +
> > > +void board_debug_uart_init(void)
> > > +{
> > > +	gpio_set_alternate(UART2_TX, AFUNC);
> > > +	gpio_set_alternate(UART2_RX, AFUNC);
> > > +}
> > > +#endif
> > > diff --git a/configs/ls1c300_defconfig b/configs/ls1c300_defconfig
> > > new file mode 100644
> > > index 0000000000..3e630a0c0e
> > > --- /dev/null
> > > +++ b/configs/ls1c300_defconfig
> > > @@ -0,0 +1,49 @@
> > > +CONFIG_MIPS=y
> > > +CONFIG_SYS_MALLOC_F_LEN=0x40000
> > > +CONFIG_SPL_LIBCOMMON_SUPPORT=y
> > > +CONFIG_SPL_LIBGENERIC_SUPPORT=y
> > > +CONFIG_NR_DRAM_BANKS=1
> > > +CONFIG_ENV_SIZE=0x1000
> > > +CONFIG_DEFAULT_DEVICE_TREE="ls1c300-eval"
> > > +CONFIG_SPL_SERIAL=y
> > > +CONFIG_SPL_SIZE_LIMIT=0x100000
> > > +CONFIG_SPL=y
> > > +CONFIG_SYS_LOAD_ADDR=0x80010000
> > > +CONFIG_ARCH_LSMIPS=y
> > > +CONFIG_SPL_PAYLOAD="u-boot.img"
> > > +CONFIG_ROM_EXCEPTION_VECTORS=y
> > > +# CONFIG_MIPS_CACHE_SETUP is not set
> > > +# CONFIG_MIPS_CACHE_DISABLE is not set
> > > +CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
> > > +CONFIG_MIPS_BOOT_FDT=y
> > > +CONFIG_FIT=y
> > > +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
> > > +CONFIG_LOGLEVEL=9
> > > +CONFIG_DISPLAY_CPUINFO=y
> > > +CONFIG_DISPLAY_BOARDINFO_LATE=y
> > > +CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK=y
> > > +CONFIG_SPL_SYS_MALLOC_SIMPLE=y
> > > +CONFIG_SPL_NOR_SUPPORT=y
> > > +# CONFIG_CMD_ELF is not set
> > > +# CONFIG_CMD_XIMG is not set
> > > +# CONFIG_CMD_CRC32 is not set
> > > +CONFIG_CMD_CLK=y
> > > +# CONFIG_CMD_LOADS is not set
> > > +# CONFIG_PARTITIONS is not set
> > > +CONFIG_OF_EMBED=y
> > > +CONFIG_SYS_RELOC_GD_ENV_ADDR=y
> > > +# CONFIG_NET is not set
> > > +CONFIG_CLK=y
> > > +CONFIG_SPL_CLK_CCF=y
> > > +# CONFIG_INPUT is not set
> > > +# CONFIG_POWER is not set
> > > +CONFIG_CONS_INDEX=2
> > > +CONFIG_SYS_NS16550=y
> > > +CONFIG_SPI=y
> > > +CONFIG_SYSRESET=y
> > > +CONFIG_SYSRESET_WATCHDOG=y
> > > +CONFIG_SYSRESET_WATCHDOG_AUTO=y
> > > +CONFIG_WATCHDOG_TIMEOUT_MSECS=3000
> > > +CONFIG_WDT_LSMIPS=y
> > > +CONFIG_REGEX=y
> > > +# CONFIG_GZIP is not set
> > > diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> > > index bb4eee5d99..51562ca4a6 100644
> > > --- a/drivers/clk/Makefile
> > > +++ b/drivers/clk/Makefile
> > > @@ -17,6 +17,7 @@ obj-y += tegra/
> > >   obj-y += ti/
> > >   obj-$(CONFIG_$(SPL_TPL_)CLK_INTEL) += intel/
> > >   obj-$(CONFIG_ARCH_ASPEED) += aspeed/
> > > +obj-$(CONFIG_ARCH_LSMIPS) += lsmips/
> > >   obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
> > >   obj-$(CONFIG_ARCH_MESON) += meson/
> > >   obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
> > > diff --git a/drivers/clk/lsmips/Makefile
> > > b/drivers/clk/lsmips/Makefile
> > > new file mode 100644
> > > index 0000000000..0a47269cd3
> > > --- /dev/null
> > > +++ b/drivers/clk/lsmips/Makefile
> > > @@ -0,0 +1,3 @@
> > > +# SPDX-License-Identifier: GPL-2.0
> > > +
> > > +obj-$(CONFIG_SOC_LS1C300) += clk-ls1c300.o
> > > diff --git a/drivers/clk/lsmips/clk-ls1c300.c
> > > b/drivers/clk/lsmips/clk-ls1c300.c
> > > new file mode 100644
> > > index 0000000000..46a94e9748
> > > --- /dev/null
> > > +++ b/drivers/clk/lsmips/clk-ls1c300.c
> > > @@ -0,0 +1,180 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * reference:
> > > + *   drivers/clk/microchip/mpfs_clk.c
> > > + *   drivers/clk/clk_octeon.c
> > > + *
> > > + * Copyright (C) 2020-2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +#include <common.h>
> > > +#include <clk-uclass.h>
> > > +#include <dm.h>
> > > +#include <dt-bindings/clock/ls1c300-clk.h>
> > > +#include <linux/bitops.h>
> > > +#include <linux/bitfield.h>
> > > +#include <linux/io.h>
> > > +#include <linux/clk-provider.h>
> > > +
> > > +/* PLL/SDRAM Frequency Configuration Register */
> > > +#define START_FREQ	0
> > > +#define CLK_DIV_PARAM	4
> > > +
> > > +/* START_FREQ */
> > > +#define	PLL_VALID	BIT(31)
> > > +#define	RESERVED0	GENMASK(30, 24)
> > > +#define	FRAC_N		GENMASK(23, 16)
> > > +#define	M_PLL		GENMASK(15, 8)
> > > +#define	RESERVED1	GENMASK(7, 4)
> > > +#define	RST_TIME	GENMASK(3, 2)
> > > +#define	SDRAM_DIV	GENMASK(1, 0)
> > > +/* CLK_DIV_PARAM */
> > > +#define	PIX_DIV		GENMASK(31, 24)
> > > +#define	CAM_DIV		GENMASK(23, 16)
> > > +#define	CPU_DIV		GENMASK(15, 8)
> > > +#define	RESERVED2	GENMASK(7, 6)
> > > +#define	PIX_DIV_VALID	BIT(5)
> > > +#define	PIX_SEL		BIT(4)
> > > +#define	CAM_DIV_VALID	BIT(3)
> > > +#define	CAM_SEL		BIT(2)
> > > +#define	CPU_DIV_VALID	BIT(1)
> > > +#define	CPU_SEL		BIT(0)
> > > +/* CPU_THROT */
> > > +#define	CPU_THROT	GENMASK(3, 0)
> > > +
> > > +static const struct clk_div_table sdram_div_table[] = {
> > > +	{.val = 0, .div = 2},
> > > +	{.val = 1, .div = 4},
> > > +	{.val = 2, .div = 3},
> > > +	{.val = 3, .div = 3},
> > > +};
> > > +
> > > +ulong ls1c300_pll_get_rate(struct clk *clk)
> > > +{
> > > +	unsigned int mult;
> > > +	long long parent_rate;
> > > +	void *base;
> > > +	unsigned int val;
> > > +
> > > +	parent_rate = clk_get_parent_rate(clk);
> > > +	base = (void *)clk->data;
> > > +
> > > +	val = readl(base + START_FREQ);
> > > +	mult = FIELD_GET(FRAC_N, val) + FIELD_GET(M_PLL, val);
> > 
> > For those following along at home:
> > 
> > c.f. 
> > https://lore.kernel.org/all/20220419051114.1569291-1-seanga2@gmail.com/
I followed the SoC's technical manual and write a excel table to calculate clock.
https://github.com/hodcarrier/ls1c300_bsp/blob/master/clk-ls1c300.xlsx

> > 
> > > +	return (mult * parent_rate) / 4;
> > > +}
> > > +
> > > +static ulong ls1c300_clk_get_rate(struct clk *clk)
> > > +{
> > > +	struct clk *cl;
> > > +	ulong rate;
> > > +	int err;
> > > +
> > > +	err = clk_get_by_id(clk->id, &cl);
> > > +	if (err)
> > > +		return err;
> > > +
> > > +	rate = clk_get_rate(cl);
> > > +	return rate;
> > > +}
> > > +
> > > +static int ls1c300_clk_probe(struct udevice *dev)
> > > +{
> > > +	void __iomem *base;
> > > +	void __iomem *cpu_throt;
> > > +	void __iomem *addr;
> > > +
> > > +	struct clk *cl, clk;
> > > +	const char *parent_name;
> > > +	int flags;
> > > +	int ret;
> > > +
> > > +	base = (void *)dev_remap_addr_index(dev, 0);
> > > +	cpu_throt  = (void *)dev_remap_addr_index(dev, 1);
> > > +
> > > +	ret = clk_get_by_index(dev, 0, &clk);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	ret = clk_get_rate(&clk);
> > > +
> > > +	parent_name = clk.dev->name;
> > > +
> > > +	cl = kzalloc(sizeof(*cl), GFP_KERNEL);
> > > +	cl->data = (unsigned long)base;
> > > +	ret = clk_register(cl, "clk_ls1c300_pll", "pll", parent_name);
> > > +	clk_dm(CLK_PLL, cl);
> > > +
> > > +	addr = base + CLK_DIV_PARAM;
> > > +	flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
> > > +	cl = clk_register_divider(NULL, "cpu_div", "pll", 0, addr,  8,
> > > 7, flags);
> > > +	clk_dm(CLK_CPU, cl);
> > > +	cl = clk_register_divider(NULL, "cam_div", "pll", 0, addr, 16,
> > > 7, flags);
> > > +	clk_dm(CLK_CAMERA, cl);
> > > +	cl = clk_register_divider(NULL, "pix_div", "pll", 0, addr, 24,
> > > 7, flags);
> > > +	clk_dm(CLK_PIX, cl);
> > > +
> > > +	cl = kzalloc(sizeof(*cl), GFP_KERNEL);
> > > +	cl->data = (unsigned long)cpu_throt;
> > > +	ret = clk_register(cl, "clk_cpu_throt", "cpu_throt_factor",
> > > "cpu_div");
> > > +	clk_dm(CLK_CPU_THROT, cl);
> > > +
> > > +	addr = base + START_FREQ;
> > > +	cl = clk_register_divider(NULL, "sdram_div", "cpu_div", 0,
> > > addr, 0, 2, 0);
> > > +	to_clk_divider(cl)->table = sdram_div_table;
> > > +	clk_dm(CLK_APB, cl);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static ulong cpu_throt_get_rate(struct clk *clk)
> > > +{
> > > +	void __iomem *cpu_throt;
> > > +	long long parent_rate;
> > > +	ulong ret;
> > > +
> > > +	parent_rate = clk_get_parent_rate(clk);
> > > +	cpu_throt = (void *)clk->data;
> > > +
> > > +	ret = readl(cpu_throt) + 1;
> > > +	ret = parent_rate * ret / 16;
> > > +	return ret;
> > > +}
> > > +
> > > +static const struct udevice_id ls1c300_clk_ids[] = {
> > > +	{ .compatible = "loongson,ls1c300-clk" },
> > > +	{ }
> > > +};
> > > +
> > > +static const struct clk_ops clk_cpu_throt_ops = {
> > > +	.get_rate = cpu_throt_get_rate,
> > > +};
> > > +
> > > +static const struct clk_ops clk_ls1c300_pll_ops = {
> > > +	.get_rate = ls1c300_pll_get_rate,
> > > +};
> > > +
> > > +static const struct clk_ops ls1c300_clk_ops = {
> > > +	.get_rate = ls1c300_clk_get_rate,
> > > +};
> > > +
> > > +U_BOOT_DRIVER(clk_ls1c300_cpu_throt) = {
> > > +	.name	= "clk_cpu_throt",
> > > +	.id	= UCLASS_CLK,
> > > +	.ops	= &clk_cpu_throt_ops,
> > > +};
> > > +
> > > +U_BOOT_DRIVER(clk_ls1c300_pll) = {
> > > +	.name	= "clk_ls1c300_pll",
> > > +	.id	= UCLASS_CLK,
> > > +	.ops	= &clk_ls1c300_pll_ops,
> > > +};
> > > +
> > > +U_BOOT_DRIVER(ls1c300_clk) = {
> > > +	.name = "clk_ls1c300",
> > > +	.id = UCLASS_CLK,
> > > +	.of_match = ls1c300_clk_ids,
> > > +	.probe = ls1c300_clk_probe,
> > > +	.priv_auto = sizeof(struct clk),
> > > +	.ops = &ls1c300_clk_ops,
> > > +};
> > > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> > > index 5b614cfa6e..a9af5e5eb6 100644
> > > --- a/drivers/watchdog/Kconfig
> > > +++ b/drivers/watchdog/Kconfig
> > > @@ -168,6 +168,14 @@ config WDT_GPIO
> > >   	  doc/device-tree-bindings/watchdog/gpio-wdt.txt for
> > >   	  information on how to describe the watchdog in device tree.
> > >   
> > > +config WDT_LSMIPS
> > > +	bool "Loongson MIPS watchdog timer support"
> > > +	depends on WDT
> > > +	help
> > > +	  Select this to enable watchdog timer for Loongson SoCs.
> > > +	  The watchdog timer is stopped when initialized.
> > > +	  It performs full SoC reset.
> > > +
> > >   config WDT_MPC8xx
> > >   	bool "MPC8xx watchdog timer support"
> > >   	depends on WDT && MPC8xx
> > > diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> > > index a35bd559f5..cb596af904 100644
> > > --- a/drivers/watchdog/Makefile
> > > +++ b/drivers/watchdog/Makefile
> > > @@ -27,6 +27,7 @@ obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o
> > >   obj-$(CONFIG_WDT_ORION) += orion_wdt.o
> > >   obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
> > >   obj-$(CONFIG_WDT_GPIO) += gpio_wdt.o
> > > +obj-$(CONFIG_WDT_LSMIPS) += lsmips_wdt.o
> > >   obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
> > >   obj-$(CONFIG_WDT_MT7620) += mt7620_wdt.o
> > >   obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
> > > diff --git a/drivers/watchdog/lsmips_wdt.c
> > > b/drivers/watchdog/lsmips_wdt.c
> > > new file mode 100644
> > > index 0000000000..65e60ae656
> > > --- /dev/null
> > > +++ b/drivers/watchdog/lsmips_wdt.c
> > > @@ -0,0 +1,123 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Watchdog driver for MediaTek SoCs
> > > + *
> > > + * Copyright (C) 2018 MediaTek Inc.
> > > + * Author: Ryder Lee <ryder.lee at mediatek.com>
> > > + *
> > > + * based on: drivers/watchdog/mtk_wdt.c
> > > + * Copyright (C) 2020-2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +#include <common.h>
> > > +#include <dm.h>
> > > +#include <hang.h>
> > > +#include <wdt.h>
> > > +#include <asm/io.h>
> > > +#include <clk.h>
> > > +
> > > +struct lsmips_wdt_priv {
> > > +	void __iomem *base;
> > > +#define WDT_EN		0
> > > +#define WDT_TIMER	4
> > > +#define WDT_SET		8
> > > +	ulong clock;
> > > +	unsigned long timeout;
> > > +};
> > > +
> > > +static int lsmips_wdt_reset(struct udevice *dev)
> > > +{
> > > +	struct lsmips_wdt_priv *priv = dev_get_priv(dev);
> > > +
> > > +	writel(priv->timeout, priv->base + WDT_TIMER);
> > > +	writel(1, priv->base + WDT_SET);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int lsmips_wdt_stop(struct udevice *dev)
> > > +{
> > > +	struct lsmips_wdt_priv *priv = dev_get_priv(dev);
> > > +
> > > +	writel(0, priv->base + WDT_EN);
> > > +	return 0;
> > > +}
> > > +
> > > +static int lsmips_wdt_expire_now(struct udevice *dev, ulong flags)
> > > +{
> > > +	struct lsmips_wdt_priv *priv = dev_get_priv(dev);
> > > +
> > > +	writel(1, priv->base + WDT_EN);
> > > +	writel(1, priv->base + WDT_TIMER);
> > > +	writel(1, priv->base + WDT_SET);
> > > +
> > > +	hang();
> > > +	return 0;
> > > +}
> > > +
> > > +static int lsmips_wdt_start(struct udevice *dev, u64 timeout_ms,
> > > ulong flags)
> > > +{
> > > +	struct lsmips_wdt_priv *priv = dev_get_priv(dev);
> > > +	unsigned int timeout;
> > > +	const unsigned int MSEC_PER_SEC = 1000;
> > > +
> > > +	timeout = U32_MAX / (priv->clock / MSEC_PER_SEC);
> > > +
> > > +	if (timeout < timeout_ms)
> > > +		timeout = U32_MAX;
> > > +	else
> > > +		timeout = timeout_ms * (priv->clock / MSEC_PER_SEC);
> > > +
> > > +	debug("WDT: reload  = %08x\n", timeout);
> > > +
> > > +	writel(1, priv->base + WDT_EN);
> > > +	writel(timeout, priv->base + WDT_TIMER);
> > > +	writel(1, priv->base + WDT_SET);
> > > +
> > > +	priv->timeout = timeout;
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int lsmips_wdt_probe(struct udevice *dev)
> > > +{
> > > +	struct lsmips_wdt_priv *priv = dev_get_priv(dev);
> > > +	struct clk cl;
> > > +
> > > +	priv->base = dev_remap_addr(dev);
> > > +	if (!priv->base)
> > > +		return -ENOENT;
> > > +
> > > +	if (clk_get_by_index(dev, 0, &cl) == 0)
> > > +		priv->clock = clk_get_rate(&cl);
> > > +
> > > +	if (priv->clock < 45000000 || priv->clock > 133000000)
> > > +		return -EAGAIN;
> > 
> > Please don't do this.
fixed, thanks.

> > 
> > > +
> > > +	debug("WDT: clock = %ld\n", priv->clock);
> > > +
> > > +	writel(0, priv->base + WDT_EN);
> > > +	return 0;
> > > +}
> > > +
> > > +static const struct wdt_ops lsmips_wdt_ops = {
> > > +	.start = lsmips_wdt_start,
> > > +	.reset = lsmips_wdt_reset,
> > > +	.stop = lsmips_wdt_stop,
> > > +	.expire_now = lsmips_wdt_expire_now,
> > > +};
> > > +
> > > +static const struct udevice_id lsmips_wdt_ids[] = {
> > > +	{ .compatible = "loongson,ls1c300-wdt"},
> > > +	{}
> > > +};
> > > +
> > > +U_BOOT_DRIVER(lsmips_wdt) = {
> > > +	.name = "lsmips_wdt",
> > > +	.id = UCLASS_WDT,
> > > +	.of_match = lsmips_wdt_ids,
> > > +	.priv_auto = sizeof(struct lsmips_wdt_priv),
> > > +	.probe = lsmips_wdt_probe,
> > > +	.ops = &lsmips_wdt_ops,
> > > +	.flags = DM_FLAG_PRE_RELOC,
> > > +};
> > > diff --git a/include/configs/ls1c300.h b/include/configs/ls1c300.h
> > > new file mode 100644
> > > index 0000000000..c460b4564b
> > > --- /dev/null
> > > +++ b/include/configs/ls1c300.h
> > > @@ -0,0 +1,59 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/*
> > > + * Copyright (C) 2020 MediaTek Inc.
> > > + *
> > > + * Author: Gao Weijie <weijie.gao at mediatek.com>
> > > + * based on: include/configs/mt7628.h
> > > + * Copyright (C) 2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +#ifndef __CONFIG_LS1C300_H__
> > > +#define __CONFIG_LS1C300_H__
> > > +
> > > +#define CONFIG_SYS_HZ			1000
> > > +
> > > +#define CONFIG_SYS_BOOTPARAMS_LEN	0x20000
> > > +
> > > +#define CONFIG_SYS_SDRAM_BASE		0x80000000
> > > +#define CONFIG_SYS_LOAD_ADDR		0x80010000
> > > +
> > > +#define CONFIG_SYS_INIT_SP_OFFSET	0x80000
> > > +
> > > +#define CONFIG_SYS_BOOTM_LEN		0x1000000
> > > +
> > > +#define CONFIG_SYS_MAXARGS		16
> > > +#define CONFIG_SYS_CBSIZE		1024
> > > +
> > > +/* Serial SPL */
> > > +#define CONFIG_SYS_NS16550_SERIAL
> > > +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL)
> > > +#define CONFIG_SYS_NS16550_CLK		66000000
> > > +#define CONFIG_SYS_NS16550_REG_SIZE	(-1)
> > > +#define CONFIG_SYS_NS16550_COM1		0xbfe44000
> > > +#define CONFIG_SYS_NS16550_COM2		0xbfe48000
> > > +#define CONFIG_SYS_NS16550_COM3		0xbfe4c000
> > > +#define CONFIG_SYS_NS16550_COM4		0xbfe4c400
> > > +#define CONFIG_SYS_NS16550_COM5		0xbfe4c500
> > > +#define CONFIG_SYS_NS16550_COM6		0xbfe4c600
> > > +#endif
> > > +
> > > +/* Serial common */
> > > +#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600,
> > > 115200, 230400, 460800, 921600 }
> > > +
> > > +/* SPL */
> > > +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
> > > +#define CONFIG_SKIP_LOWLEVEL_INIT	1
> > > +#endif
> > > +
> > > +#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
> > > +#define CONFIG_SPL_BSS_START_ADDR	0x80010000
> > > +#define CONFIG_SPL_BSS_MAX_SIZE		0x10000
> > > +#define CONFIG_SPL_MAX_SIZE		0x10000
> > > +#define CONFIG_SPL_PAD_TO		0
> > > +
> > > +#define CONFIG_MALLOC_F_ADDR		0x80100000	/* FIXME:
> > > find a proper place */
> > > +
> > > +/* Dummy value */
> > > +#define CONFIG_SYS_UBOOT_BASE		0
> > > +
> > > +#endif /* __CONFIG_LS1C300_H__ */
> > > diff --git a/include/dt-bindings/clock/ls1c300-clk.h b/include/dt-
> > > bindings/clock/ls1c300-clk.h
> > > new file mode 100644
> > > index 0000000000..66798f40c7
> > > --- /dev/null
> > > +++ b/include/dt-bindings/clock/ls1c300-clk.h
> > > @@ -0,0 +1,18 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/*
> > > + * Copyright (C) 2022 Du Huanpeng <dhu at hodcarrier.org>
> > > + */
> > > +
> > > +#ifndef __DT_BINDINGS_LS1C300_CLK_H__
> > > +#define __DT_BINDINGS_LS1C300_CLK_H__
> > > +
> > > +#define CLK_XTAL	0
> > > +#define CLK_PLL		1
> > > +#define CLK_CPU		2
> > > +#define CLK_APB         3
> > > +#define CLK_CAMERA	4
> > > +#define CLK_PIX		5
> > > +#define CLK_AXIMUX	6
> > > +#define CLK_CPU_THROT	7
> > > +
> > > +#endif /* __DT_BINDINGS_LS1C300_CLK_H__ */
> > > 
> > 
> > --Sean
> -- 
> - Daniel
> 
- Du Huanpeng

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

end of thread, other threads:[~2023-07-23 12:25 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-18 20:45 [PATCH v3] mips: dts: add initial support for ls1c300 SoC Du Huanpeng
2022-04-22  0:31 ` Sean Anderson
2022-04-25 16:59   ` Daniel Schwierzeck
2023-07-22  9:03 dhu

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.