hi,
On Thu, Mar 31, 2022 at 01:24:31AM +0200, Daniel Schwierzeck wrote:
> Am Mittwoch, dem 30.03.2022 um 03:30 +0800 schrieb 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 Techinical 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 <d...@hodcarrier.org>
> 
> Sean already addressed most points, so only just some additional
> comments below.
> 
> > ---
> >  arch/mips/Kconfig                             |  25 +++
> >  arch/mips/Makefile                            |   1 +
> >  arch/mips/dts/Makefile                        |   1 +
> >  arch/mips/dts/loongson32-ls1c300b.dtsi        | 138
> > +++++++++++++++++
> >  arch/mips/dts/ls1c300-eval.dts                |  27 ++++
> >  arch/mips/mach-lsmips/Kconfig                 |  77 ++++++++++
> >  arch/mips/mach-lsmips/Makefile                |   6 +
> >  arch/mips/mach-lsmips/cpu.c                   |  24 +++
> >  arch/mips/mach-lsmips/include/mach/serial.h   |  16 ++
> >  arch/mips/mach-lsmips/ls1c300/Makefile        |   6 +
> >  arch/mips/mach-lsmips/ls1c300/gpio.c          |  60 ++++++++
> >  arch/mips/mach-lsmips/ls1c300/init.c          |  60 ++++++++
> >  arch/mips/mach-lsmips/ls1c300/lowlevel_init.S | 123 +++++++++++++++
> >  arch/mips/mach-lsmips/ls1c300/ls1c300.h       |  52 +++++++
> >  arch/mips/mach-lsmips/ls1c300/serial.c        | 112 ++++++++++++++
> >  arch/mips/mach-lsmips/spl.c                   |  47 ++++++
> 
> you should use mach-loongson. If you copied the naming from mtmips,
> then don't ;) mtmips only exists because mediatek was already used for
> the ARM specific SoC's and we needed some different Kconfig symbols for
> the MIPS SoC's.
I copied from mediatek, loongson also has mips and one other architecture...

> 
> >  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                     |  65 ++++++++
> >  drivers/clk/Makefile                          |   1 +
> >  drivers/clk/lsmips/Makefile                   |   3 +
> >  drivers/clk/lsmips/clk-ls1c300.c              | 145
> > ++++++++++++++++++
> >  drivers/watchdog/Kconfig                      |   8 +
> >  drivers/watchdog/Makefile                     |   1 +
> >  drivers/watchdog/lsmips_wdt.c                 | 126 +++++++++++++++
> >  include/configs/ls1c300.h                     |  61 ++++++++
> >  include/dt-bindings/clock/ls1c300-clk.h       |  48 ++++++
> >  29 files changed, 1275 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/ls1c300.h
> >  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/arch/mips/Kconfig b/arch/mips/Kconfig
> > index 28234aa0bb..d95868ef4b 100644
> > --- a/arch/mips/Kconfig
> > +++ b/arch/mips/Kconfig
> > @@ -93,6 +93,30 @@ config ARCH_MTMIPS
> >     select SUPPORTS_LITTLE_ENDIAN
> >     select SUPPORT_SPL
> >  
> > +config ARCH_LSMIPS
> > +   bool "Support Loongson MIPS platforms"
> > +   select CLK
> > +   imply CMD_DM
> > +   select DISPLAY_CPUINFO
> 
> the user should be able to disable this
> 
> > +   select DM
> 
> > +   imply DM_ETH
> > +   imply DM_GPIO
> 
> only add this when you add GPIO or ethernet drivers
> 
> > +   select DM_RESET
> > +   select DM_SERIAL
> > +   select PINCTRL
> > +   select PINMUX
> > +   select PINCONF
> > +   select RESET_LSMIPS
> 
> I don't see any pinctrl or reset drivers in this patch
> 
> > +   imply DM_SPI
> > +   imply DM_SPI_FLASH
> > +   select OF_CONTROL
> > +   select ROM_EXCEPTION_VECTORS
> 
> you probably don't need this. This only makes sense on older CPUs
> booting from parallel NOR flash or other XiP capable memory
bfc0_0000 is mapped to nor flash or nand. mine mapped to spi nor flash.
it has 1MB size of memory supports XiP. I changed it to user
configureable.

> 
> > +   select SUPPORTS_CPU_MIPS32_R1
> > +   select SUPPORTS_CPU_MIPS32_R2
> > +   select SUPPORTS_LITTLE_ENDIAN
> > +   select SYSRESET
> > +   select SUPPORT_SPL
> > +
> >  config ARCH_JZ47XX
> >     bool "Support Ingenic JZ47xx"
> >     select SUPPORT_SPL
> > @@ -174,6 +198,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..a574495301
> > --- /dev/null
> > +++ b/arch/mips/dts/loongson32-ls1c300b.dtsi
> > @@ -0,0 +1,138 @@
> > +// 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>;
> > +           };
> > +   };
> > +
> > +   xtal: oscillator@0 {
> > +           compatible = "fixed-clock";
> > +           clock-frequency = <24000000>;
> > +           #clock-cells = <0>;
> > +   };
> > +
> > +   soc {
> > +           #address-cells = <1>;
> > +           #size-cells = <1>;
> > +           compatible = "simple-bus";
> > +           ranges;
> > +
> > +           // TODO: add more device.
> > +
> > +           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 = "ns16550a";
> > +                   clocks = <&acc CLK_UART0>;
> > +                   reg = <0x1fe40000 0x100>;
> > +                   reg-shift = <0>;
> > +           };
> > +
> > +           uart1: serial@1fe44000 {
> > +                   compatible = "ns16550a";
> > +                   clocks = <&acc CLK_UART1>;
> > +                   reg = <0x1fe44000 0x100>;
> > +                   reg-shift = <0>;
> > +           };
> > +
> > +           uart2: serial@bfe48000 {
> > +                   compatible = "ns16550a";
> > +                   clocks = <&acc CLK_UART2>;
> > +                   reg = <0xbfe48000 0x100>;
> > +                   reg-shift = <0>;
> > +           };
> > +
> > +           uart3: serial@1fe4c000 {
> > +                   compatible = "ns16550a";
> > +                   clocks = <&acc CLK_UART3>;
> > +                   reg = <0x1fe4c000 0x100>;
> > +                   reg-shift = <0>;
> > +           };
> > +
> > +           uart4:  serial@1fe4c400 {
> > +                   compatible = "ns16550a";
> > +                   clocks = <&acc CLK_UART4>;
> > +                   reg = <0x1fe4c400 0x100>;
> > +                   reg-shift = <0>;
> > +           };
> > +
> > +           uart5:  serial@1fe4c500 {
> > +                   compatible = "ns16550a";
> > +                   clocks = <&acc CLK_UART5>;
> > +                   reg = <0x1fe4c500 0x100>;
> > +                   reg-shift = <0>;
> > +           };
> > +
> > +           uart6:  serial@1fe4c600 {
> > +                   compatible = "ns16550a";
> > +                   clocks = <&acc CLK_UART6>;
> > +                   reg = <0x1fe4c600 0x100>;
> > +                   reg-shift = <0>;
> > +           };
> > +
> > +           uart7:  serial@1fe4c700 {
> > +                   compatible = "ns16550a";
> > +                   clocks = <&acc CLK_UART7>;
> > +                   reg = <0x1fe4c700 0x100>;
> > +                   reg-shift = <0>;
> > +           };
> > +
> > +           uart8:  serial@1fe4c800 {
> > +                   compatible = "ns16550a";
> > +                   clocks = <&acc CLK_UART8>;
> > +                   reg = <0x1fe4c800 0x100>;
> > +                   reg-shift = <0>;
> > +           };
> > +
> > +           uart9:  serial@1fe4c900 {
> > +                   compatible = "ns16550a";
> > +                   clocks = <&acc CLK_UART9>;
> > +                   reg = <0x1fe4c900 0x100>;
> > +                   reg-shift = <0>;
> > +           };
> > +
> > +           uart10: serial@1fe4ca00 {
> > +                   compatible = "ns16550a";
> > +                   clocks = <&acc CLK_UART10>;
> > +                   reg = <0x1fe4ca00 0x100>;
> > +                   reg-shift = <0>;
> > +           };
> > +
> > +           uart11: serial@1fe4cb00 {
> > +                   compatible = "ns16550a";
> > +                   clocks = <&acc CLK_UART11>;
> > +                   reg = <0x1fe4cb00 0x100>;
> > +                   reg-shift = <0>;
> > +           };
> 
> those nodes should be disabled by default and just one picked and
> enabled by the board.
> 
> 
> > +
> > +           wdt: watchdog@1fe5c060 {
> > +                   compatible = "loongson,ls1c300-wdt";
> > +                   clocks = <&acc CLK_WDT>;
> > +                   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..5bf1ec0985
> > --- /dev/null
> > +++ b/arch/mips/dts/ls1c300-eval.dts
> > @@ -0,0 +1,27 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2022 Du Huanpeng <d...@hodcarrier.org>
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "loongson32-ls1c300b.dtsi"
> > +
> > +/ {
> > +   compatible = "lsmips,ls1c300-soc";
> > +   model = "ls1c300-eval";
> > +
> > +   aliases {
> > +           console = &uart2;
> > +   };
> > +
> > +   chosen {
> > +           bootargs = "console=ttyS0,115200";
> 
> this is not needed and will be overwritten anyway by bootm
> 
> > +           stdout-path = &uart2;
> > +   };
> > +};
> > +
> > +&uart2 {
> > +   status = "okay";
> > +};
> > +
> > diff --git a/arch/mips/mach-lsmips/Kconfig b/arch/mips/mach-
> > lsmips/Kconfig
> > new file mode 100644
> > index 0000000000..cb679875a7
> > --- /dev/null
> > +++ b/arch/mips/mach-lsmips/Kconfig
> > @@ -0,0 +1,77 @@
> > +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
> > +
> > +choice
> > +   prompt "Loongson MIPS SoC select"
> > +
> > +config SOC_LS1C300
> > +   bool "LS1C300"
> > +   select MIPS_L1_CACHE_SHIFT_5
> > +   select PINCTRL_LS1C300
> 
> I don't see amy pinctrl driver in this patch
> 
> > +   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_SELECT
> > +   int "pin group used in uart"
> > +   default 0
> > +   help
> > +     Select pin group connected to UART for your board.
> 
> this should be selected by the DT uart nodes via pinctrl
this is used in SPL.

> 
> > +
> > +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..00513253e8
> > --- /dev/null
> > +++ b/arch/mips/mach-lsmips/cpu.c
> > @@ -0,0 +1,24 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2018 Stefan Roese <s...@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)
> > +{
> > +#ifdef CONFIG_SKIP_LOWLEVEL_INIT
> > +   gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
> > SZ_256M);
> > +#else
> > +   gd->ram_size = SZ_64M;
> > +#endif
> 
> either you can detect the RAM size from the memory controller settings
> or just use a fixed value. Better to make that configurable for a
> board.
> 
> > +
> > +   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....@mediatek.com>
> > + *
> > + * Copyright (C) 2022 Du Huanpeng <d...@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..d30069e67e
> > --- /dev/null
> > +++ b/arch/mips/mach-lsmips/ls1c300/Makefile
> > @@ -0,0 +1,6 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +obj-y += lowlevel_init.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..cca91aed93
> > --- /dev/null
> > +++ b/arch/mips/mach-lsmips/ls1c300/gpio.c
> > @@ -0,0 +1,60 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2022 Du Huanpeng <d...@hodcarrier.org>
> > + */
> > +
> > +#include <linux/errno.h>
> > +#include <linux/bitops.h>
> > +#include <asm/bitops.h>
> > +#include <asm/io.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
> > +
> > +int gpio_set_alternate(int gpio, int func)
> > +{
> > +   volatile void __iomem *addr;
> > +   int i;
> > +
> > +   if (gpio < 0 || gpio > 104)
> > +           return -ENODEV;
> > +   if (func < 0)
> > +           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;
> > +}
> 
> use a pinctrl driver and device-tree for pin muxing
this is use for debug_uart_init and spl.
the debug_uart_init call is called from ''start.S''.
> 
> > diff --git a/arch/mips/mach-lsmips/ls1c300/init.c b/arch/mips/mach-
> > lsmips/ls1c300/init.c
> > new file mode 100644
> > index 0000000000..457beeedca
> > --- /dev/null
> > +++ b/arch/mips/mach-lsmips/ls1c300/init.c
> > @@ -0,0 +1,60 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2020 MediaTek Inc.
> > + *
> > + * Author:  Gao Weijie <weijie....@mediatek.com>
> > + *
> > + * based on: arch/mips/mach-mtmips/mt7628/init.c
> > + * Copyright (C) 2020-2022 Du Huanpeng <d...@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>
> > +#include "ls1c300.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;
> > +
> > +   clk.id = CLK_XTAL;
> > +   xtal = clk_get_rate(&clk);
> > +
> > +   clk.id = CLK_CPU_THROT;
> > +   gd->cpu_clk = clk_get_rate(&clk);
> > +
> > +   clk.id = CLK_SDRAM;
> > +   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;
> > +}
> > 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..f9e2f94e83
> > --- /dev/null
> > +++ b/arch/mips/mach-lsmips/ls1c300/lowlevel_init.S
> > @@ -0,0 +1,123 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (C) 2020 MediaTek Inc.
> > + *
> > + * Author:  Gao Weijie <weijie....@mediatek.com>
> > + *
> > + * Copyright (C) 2020-2022 Du Huanpeng <d...@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 */
> > +#define NAND_BASE  0xbfe78000
> > +#define START_FREQ 0xbfe78030
> > +#define CLK_DIV_PARAM      0xbfe78034
> > +
> > +/* SPI */
> > +#define SPI0_BASE  0xbfe80000
> > +
> > +/* SDRAM */
> > +#define    SD_CONFIG       0xbfd00000
> > +#define    SD_CONFIGL      0xbfd00410
> > +#define    SD_CONFIGH      0xbfd00414
> > +
> > +   .set noreorder
> > +
> > +/* PLL: 264MHz     CPU: 132MHz     SDRAM: 66MHz    */
> > +LEAF(ls1c300_pll_init)
> > +#ifndef CONFIG_SKIP_LOWLEVEL_INIT
> > +   li      t0, NAND_BASE
> > +   li      t2, 555844098
> > +   sw      t2, 0x34 (t0)
> > +
> > +   li      t1, 2147494924
> > +   sw      t1, 0x30 (t0)
> 
> don't use magic values for register values and offset. Use defines for
> this to make that readable. And add some comments about what you are
> configuring.
> 
> > +
> > +   ori     t2, 1
> > +   sw      t2, 0x34 (t0)
> > +#endif
> > +/* TODO: recalc rate to v0 */
> > +   li      v0, 132000000
> > +   jr      ra
> > +     nop
> > +END(ls1c300_pll_init)
> > +
> > +/* SPI: Dual IO@33MHz */
> > +LEAF(ls1c300_spi_init)
> > +#ifndef CONFIG_SKIP_LOWLEVEL_INIT
> > +   li      t0, SPI0_BASE
> > +   li      t1, 0x07
> > +   li      t2, 0x05
> > +   sb      t1, 0x4(t0)
> > +   sb      t1, 0x6(t0)
> > +#endif
> > +   jr      ra
> > +     nop
> > +END(ls1c300_spi_init)
> > +
> > +/* SDRAM: 66MHz */
> > +// 8M x 16Bit x 4 Banks */
> > +// Organization | Row Address | Column Address
> > +// 32Mx16       | A0~A12      | A0-A9
> > +
> > +// 128Mx4       | A0~A12      | A0-A9, A11, A12
> > +// 64Mx8        | A0~A12      | A0-A9, A11
> > +// 32Mx16       | A0~A12      | A0-A9
> > +
> > +LEAF(ls1c300_sdram_init)
> > +#ifndef CONFIG_SKIP_LOWLEVEL_INIT
> > +   li      t0, SD_CONFIG
> > +   li      t1, 0x028A924A
> > +   li      t2, 0x00000028
> > +sdram_cfg:
> > +   sw      t1, 0x410(t0)
> > +   sw      t2, 0x414(t0)
> > +   nop
> > +   sw      t1, 0x410(t0)
> > +   sw      t2, 0x414(t0)
> > +   ori     t2, 0x200
> > +   sw      t1, 0x410(t0)
> > +   sw      t2, 0x414(t0)
> > +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
> > +   li      v0, SZ_64M
> > +   jr      ra
> > +    nop
> > +END(ls1c300_sdram_init)
> > +
> > +
> > +/*
> > + * SDRAM@132MHz, CPU@297MHz, SPI@33MHz
> > + * SDRAM@100MHz, CPU@300MHz, SPI@50MHz
> > + * SDRAM@66MHz, CPU@132MHz, SPI@33MHz  <--
> > + */
> > +
> > +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/ls1c300.h
> > b/arch/mips/mach-lsmips/ls1c300/ls1c300.h
> > new file mode 100644
> > index 0000000000..70a5def841
> > --- /dev/null
> > +++ b/arch/mips/mach-lsmips/ls1c300/ls1c300.h
> > @@ -0,0 +1,52 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (C) 2022 Du Huanpeng <d...@hodcarrier.org>
> > + */
> > +
> > +#ifndef __LS1C300_H__
> > +#define __LS1C300_H__
> > +
> > +/* generated, don't edit */
> > +
> > +#define    SDRAM_BASE      0x00000000
> > +#define    CAMERA_BASE     0x1c280000
> > +#define    DC_BASE         0x1c300000
> > +#define    AXIMUX_BASE     0x1f000000
> > +
> > +#define    SPI0MEM_BASE    0x1d000000
> > +#define    SPI1MEM_BASE    0x1e000000
> > +#define    Boot_BASE       0xbfc00000
> > +#define    CONFREG_BASE    0x1fd00000
> > +#define    OTG_BASE        0x1fe00000
> > +#define    MAC_BASE        0x1fe10000
> > +#define    USB_BASE        0x1fe20000
> > +#define    APB_BASE        0x1fe40000
> > +#define    SPI0_BASE       0x1fe80000
> > +#define    SPI1_BASE       0x1fec0000
> > +
> > +#define    UART0_BASE      0x1fe40000
> > +#define    UART1_BASE      0x1fe44000
> > +#define    UART2_BASE      0x1fe48000
> > +#define    UART3_BASE      0x1fe4c000
> > +#define    UART4_BASE      0x1fe4c400
> > +#define    UART5_BASE      0x1fe4c500
> > +#define    UART6_BASE      0x1fe4c600
> > +#define    UART7_BASE      0x1fe4c700
> > +#define    UART8_BASE      0x1fe4c800
> > +#define    UART9_BASE      0x1fe4c900
> > +#define    UART10_BASE     0x1fe4ca00
> > +#define    UART11_BASE     0x1fe4cb00
> > +#define    CAN0_BASE       0x1fe50000
> > +#define    CAN1_BASE       0x1fe54000
> > +#define    I2C0_BASE       0x1fe58000
> > +#define    PWM_BASE        0x1fe5c000
> > +#define    I2S_BASE        0x1fe60000
> > +#define    RTC_BASE        0x1fe64000
> > +#define    I2C1_BASE       0x1fe68000
> > +#define    SDIO_BASE       0x1fe6c000
> > +#define    I2C2_BASE       0x1fe70000
> > +#define    ADC_BASE        0x1fe74000
> > +#define    NAND_BASE       0x1fe78000
> > +#define    HCNTR_BASE      0x1fe7c000
> > +
> > +#endif /* __LS1C300_H__ */
> > diff --git a/arch/mips/mach-lsmips/ls1c300/serial.c b/arch/mips/mach-
> > lsmips/ls1c300/serial.c
> > new file mode 100644
> > index 0000000000..88bc18ef85
> > --- /dev/null
> > +++ b/arch/mips/mach-lsmips/ls1c300/serial.c
> > @@ -0,0 +1,112 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2020 MediaTek Inc.
> > + *
> > + * Author:  Gao Weijie <weijie....@mediatek.com>
> > + *
> > + * Copyright (C) 2020-2022 Du Huanpeng <d...@hodcarrier.org>
> > + */
> > +
> > +#include <common.h>
> > +#include <asm/io.h>
> > +#include <mach/serial.h>
> > +#include <linux/kernel.h>
> > +#include "ls1c300.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)
> > +{
> > +#ifdef CONFIG_SPL_SERIAL
> > +   int pin_rx, pin_tx;
> > +   int afunc;
> > +
> > +   if (CONFIG_CONS_PIN_SELECT < ARRAY_SIZE(con)) {
> > +           pin_rx = con[CONFIG_CONS_PIN_SELECT].rx;
> > +           pin_tx = con[CONFIG_CONS_PIN_SELECT].tx;
> > +           afunc = con[CONFIG_CONS_PIN_SELECT].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..c7c28989f2
> > --- /dev/null
> > +++ b/arch/mips/mach-lsmips/spl.c
> > @@ -0,0 +1,47 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
> > + *
> > + * Author: Gao Weijie <weijie....@mediatek.com>
> > + *
> > + * Copyright (C) 2022 Du Huanpeng <d...@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();
> > +
> > +#ifdef 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<d...@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..2f588a0dcb
> > --- /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 <d...@hodcarrier.org>
> > + */
> > +
> > +#include <common.h>
> > +#include <mach/serial.h>
> > +
> > +#ifdef 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);
> > +}
> 
> isn't that redundant to lsmips_spl_serial_init()?
... seems no, when CONFIG_DEBUG_UART=y is disabled, spl have to do the
mux for it's serial port.
> 
> > +#endif
> > diff --git a/configs/ls1c300_defconfig b/configs/ls1c300_defconfig
> > new file mode 100644
> > index 0000000000..c47fe5b98f
> > --- /dev/null
> > +++ b/configs/ls1c300_defconfig
> > @@ -0,0 +1,65 @@
> > +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_ENV_OFFSET=0x30000
> > +CONFIG_ENV_SECT_SIZE=0x10000
> > +CONFIG_DEFAULT_DEVICE_TREE="ls1c300-eval"
> > +CONFIG_SPL_SERIAL=y
> > +CONFIG_SPL_SIZE_LIMIT=0x100000
> > +CONFIG_SPL=y
> > +CONFIG_DEBUG_UART_BOARD_INIT=y
> > +CONFIG_DEBUG_UART_BASE=0xbfe48000
> > +CONFIG_DEBUG_UART_CLOCK=66000000
> > +CONFIG_ARCH_LSMIPS=y
> > +CONFIG_SPL_PAYLOAD="u-boot.img"
> > +# 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_DEBUG_UART=y
> > +CONFIG_SYS_LOAD_ADDR=0x80010000
> > +CONFIG_FIT=y
> > +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
> > +CONFIG_LOGLEVEL=9
> > +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=ylsmips_spl_serial_init
> > +# CONFIG_CMD_DM is not set
> > +CONFIG_CMD_GPIO=y
> > +# CONFIG_CMD_LOADS is not set
> > +CONFIG_CMD_SPI=y
> > +CONFIG_CMD_WDT=y
> > +# CONFIG_PARTITIONS is not set
> > +CONFIG_OF_EMBED=y
> > +CONFIG_ENV_IS_IN_SPI_FLASH=y
> > +CONFIG_SYS_RELOC_GD_ENV_ADDR=y
> > +# CONFIG_NET is not set
> > +# CONFIG_INPUT is not set
> > +CONFIG_SPI_FLASH_EON=y
> > +CONFIG_SPI_FLASH_GIGADEVICE=y
> > +CONFIG_SPI_FLASH_ISSI=y
> > +CONFIG_SPI_FLASH_MACRONIX=y
> > +CONFIG_SPI_FLASH_SPANSION=y
> > +CONFIG_SPI_FLASH_STMICRO=y
> > +CONFIG_SPI_FLASH_WINBOND=y
> > +CONFIG_SPI_FLASH_XMC=y
> > +CONFIG_CONS_INDEX=2
> > +CONFIG_DEBUG_UART_ANNOUNCE=y
> > +CONFIG_SYS_NS16550=y
> > +CONFIG_SPI=y
> > +CONFIG_SYSRESET_WATCHDOG=y
> > +CONFIG_SYSRESET_WATCHDOG_AUTO=y
> > +CONFIG_WATCHDOG_TIMEOUT_MSECS=3000
> > +CONFIG_WDT_LSMIPS=y
> > +CONFIG_REGEX=y
> > +CONFIG_LZMA=y
> > +CONFIG_SPL_LZMA=y
> > +CONFIG_SPL_GZIP=y
> 
> this needs to be generated with "make savedefconfig; cp defconfig
> configs/ls1c300_defconfig" to just list options different from their
> default values
> 
> > 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..c78e23d695
> > --- /dev/null
> > +++ b/drivers/clk/lsmips/clk-ls1c300.c
> > @@ -0,0 +1,145 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * reference:
> > + *   drivers/clk/microchip/mpfs_clk.c
> > + *   drivers/clk/clk_octeon.c
> > + *
> > + * Copyright (C) 2020-2022 Du Huanpeng <d...@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>
> > +
> > +/* 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},
> > +};
> > +
> > +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_enable(struct clk *clk)
> > +{
> > +   /* Nothing to do on Octeon */
> > +   return 0;
> > +}
> > +
> > +static const struct clk_ops ls1c300_clk_ops = {
> > +   .enable = ls1c300_clk_enable,
> > +   .get_rate = ls1c300_clk_get_rate,
> > +};
> > +
> > +static int ls1c300_clk_probe(struct udevice *dev)
> > +{
> > +   void __iomem *base;
> > +   void __iomem *cpu_throt;
> > +   void __iomem *addr;
> > +
> > +   struct clk *cl, clk;
> > +
> > +   int ret;
> > +   const char *parent_name;
> > +   unsigned int mult, div;
> > +   unsigned int val;
> > +   int flags;
> > +
> > +   base = (void *)dev_remap_addr_index(dev, 0);
> > +#define START_FREQ (0)
> > +#define CLK_DIV_PARAM      (4)
> > +   cpu_throt  = (void *)dev_remap_addr_index(dev, 1);
> > +
> > +   debug("     base: %p\n", base);
> > +   debug("cpu_throt: %p\n", cpu_throt);
> > +
> > +   val = readl(base + START_FREQ);
> > +   debug("   START_FREQ: [%08x]\n", val);
> > +   val = readl(base + CLK_DIV_PARAM);
> > +   debug("CLK_DIV_PARAM: [%08x]\n", val);
> > +
> > +   ret = clk_get_by_index(dev, 0, &clk);
> > +   if (ret)
> > +           return ret;
> > +
> > +   ret = clk_get_rate(&clk);
> > +
> > +   parent_name = clk.dev->name;
> > +   val = readl(base + START_FREQ);
> > +   mult = FIELD_GET(FRAC_N, val) + FIELD_GET(M_PLL, val); div = 4;
> > +   cl = clk_register_fixed_factor(NULL, "pll", parent_name, 0,
> > mult, div);
> > +   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);
> > +
> > +   mult = FIELD_GET(CPU_THROT, readl(cpu_throt)) + 1; div = 16;
> > +   cl = clk_register_fixed_factor(NULL, "cpu_throt_factor",
> > "cpu_div", CLK_GET_RATE_NOCACHE, mult, 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_SDRAM, cl);
> > +
> > +   return 0;
> > +}
> > +
> > +static const struct udevice_id ls1c300_clk_ids[] = {
> > +   { .compatible = "loongson,ls1c300-clk" },
> > +   { }
> > +};
> > +
> > +U_BOOT_DRIVER(ls1c300_clk) = {
> > +   .name = "ls1c300-clk",
> > +   .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 f90f0ca02b..289b568188 100644
> > --- a/drivers/watchdog/Kconfig
> > +++ b/drivers/watchdog/Kconfig
> > @@ -167,6 +167,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..ef91cae349
> > --- /dev/null
> > +++ b/drivers/watchdog/lsmips_wdt.c
> > @@ -0,0 +1,126 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Watchdog driver for MediaTek SoCs
> > + *
> > + * Copyright (C) 2018 MediaTek Inc.
> > + * Author: Ryder Lee <ryder....@mediatek.com>
> > + *
> > + * based on: drivers/watchdog/mtk_wdt.c
> > + * Copyright (C) 2020-2022 Du Huanpeng <d...@hodcarrier.org>
> > + */
> > +
> > +#include <common.h>
> > +#include <dm.h>
> > +#include <hang.h>
> > +#include <wdt.h>
> > +#include <asm/io.h>
> > +#include <linux/bitops.h>
> > +#include <clk.h>
> > +
> > +#define WDT_EN             (priv->base + 0)
> > +#define WDT_TIMER  (priv->base + 4)
> > +#define WDT_SET            (priv->base + 8)
> > +
> > +struct lsmips_wdt_priv {
> > +   void __iomem *base;
> > +   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, WDT_TIMER);
> > +   writel(1, WDT_SET);
> > +
> > +   return 0;
> > +}
> > +
> > +static int lsmips_wdt_stop(struct udevice *dev)
> > +{
> > +   struct lsmips_wdt_priv *priv = dev_get_priv(dev);
> > +
> > +   writel(0, 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, WDT_EN);
> > +   writel(1, WDT_TIMER);
> > +   writel(1, 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;
> > +
> > +   timeout = U32_MAX / (priv->clock / 1000);
> > +
> > +   if (timeout < timeout_ms)
> > +           timeout = U32_MAX;
> > +   else
> > +           timeout = timeout_ms * (priv->clock / 1000);
> > +
> > +   debug("WDT: reload  = %08x\n", timeout);
> > +
> > +   writel(1, WDT_EN);
> > +   writel(timeout, WDT_TIMER);
> > +   writel(1, 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 < 33000000 || priv->clock > 150000000) {
> > +           /* assume 67MHz by default */
> > +           priv->clock = 67108864;
> > +   }
> > +
> > +   debug("WDT: clock = %ld\n", priv->clock);
> > +
> > +   writel(0, 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..a96deb6bb2
> > --- /dev/null
> > +++ b/include/configs/ls1c300.h
> > @@ -0,0 +1,61 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (C) 2020 MediaTek Inc.
> > + *
> > + * Author: Gao Weijie <weijie....@mediatek.com>
> > + * based on: include/configs/mt7628.h
> > + * Copyright (C) 2022 Du Huanpeng <d...@hodcarrier.org>
> > + */
> > +
> > +#ifndef __CONFIG_LS1C300_H__
> > +#define __CONFIG_LS1C300_H__
> > +
> > +#define CONFIG_SYS_HZ                      1000
> > +
> > +#define CONFIG_SYS_MONITOR_BASE            CONFIG_SYS_TEXT_BASE
> > +
> > +#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
> > +#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..735fa61789
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/ls1c300-clk.h
> > @@ -0,0 +1,48 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (C) 2022 Du Huanpeng <d...@hodcarrier.org>
> > + */
> > +
> > +#ifndef __DT_BINDINGS_LS1C300_CLK_H__
> > +#define __DT_BINDINGS_LS1C300_CLK_H__
> > +
> > +/* Base clocks */
> > +#define CLK_XTAL   0
> > +#define CLK_PLL            1
> > +#define CLK_CPU            2
> > +#define CLK_CPU_THROT      7
> > +#define CLK_SDRAM  3
> > +
> > +#define CLK_CAMERA 4
> > +#define CLK_DC             5
> > +#define CLK_PIX            5
> > +#define CLK_AXIMUX 6
> > +
> > +/* Peripheral clocks */
> > +#define CLK_UART0  3
> > +#define CLK_UART1  3
> > +#define CLK_UART2  3
> > +#define CLK_UART3  3
> > +#define CLK_UART4  3
> > +#define CLK_UART5  3
> > +#define CLK_UART6  3
> > +#define CLK_UART7  3
> > +#define CLK_UART8  3
> > +#define CLK_UART9  3
> > +#define CLK_UART10 3
> > +#define CLK_UART11 3
> > +#define CLK_CAN0   3
> > +#define CLK_CAN1   3
> > +#define CLK_I2C0   3
> > +#define CLK_PWM            3
> > +#define CLK_I2S            3
> > +#define CLK_RTC            3
> > +#define CLK_I2C1   3
> > +#define CLK_SDIO   3
> > +#define CLK_I2C2   3
> > +#define CLK_ADC            3
> > +#define CLK_NAND   3
> > +
> > +#define CLK_WDT            3
> > +
> > +#endif /* __DT_BINDINGS_LS1C300_CLK_H__ */
> -- 
> - Daniel
> 

Reply via email to