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 >