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. > 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 > + 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 > + > +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 > 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()? > +#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