
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 dhu@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 dhu@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 sr@denx.de
- */
+#include <common.h> +#include <init.h> +#include <malloc.h> +#include <linux/bitops.h> +#include <linux/io.h> +#include <linux/sizes.h>
+DECLARE_GLOBAL_DATA_PTR;
+int dram_init(void) +{ +#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.gao@mediatek.com
- Copyright (C) 2022 Du Huanpeng dhu@hodcarrier.org
- */
+#ifndef __LSMIPS_SERIAL_H_ +#define __LSMIPS_SERIAL_H_
+void lsmips_spl_serial_init(void); +int gpio_set_alternate(int gpio, int func);
+#endif /* __LSMIPS_SERIAL_H_ */ diff --git a/arch/mips/mach-lsmips/ls1c300/Makefile b/arch/mips/mach- lsmips/ls1c300/Makefile new file mode 100644 index 0000000000..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 dhu@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.gao@mediatek.com
- based on: arch/mips/mach-mtmips/mt7628/init.c
- Copyright (C) 2020-2022 Du Huanpeng dhu@hodcarrier.org
- */
+#include <common.h> +#include <clk.h> +#include <dm.h> +#include <dm/uclass.h> +#include <dt-bindings/clock/ls1c300-clk.h> +#include <linux/io.h> +#include <linux/sizes.h> +#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.gao@mediatek.com
- Copyright (C) 2020-2022 Du Huanpeng dhu@hodcarrier.org
- */
+#include <config.h> +#include <asm-offsets.h> +#include <asm/cacheops.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/asm.h> +#include <linux/sizes.h>
+/* PLL */ +#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 dhu@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.gao@mediatek.com
- Copyright (C) 2020-2022 Du Huanpeng dhu@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.gao@mediatek.com
- Copyright (C) 2022 Du Huanpeng dhu@hodcarrier.org
- */
+#include <common.h> +#include <init.h> +#include <spl.h> +#include <asm/sections.h> +#include <linux/libfdt.h> +#include <linux/sizes.h> +#include <mach/serial.h>
+void __noreturn board_init_f(ulong dummy) +{
- spl_init();
+#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 Huanpengdhu@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 dhu@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 dhu@hodcarrier.org
- */
+#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <dt-bindings/clock/ls1c300-clk.h> +#include <linux/bitops.h> +#include <linux/bitfield.h> +#include <linux/io.h> +#include <linux/clk-provider.h>
+/* 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.lee@mediatek.com
- based on: drivers/watchdog/mtk_wdt.c
- Copyright (C) 2020-2022 Du Huanpeng dhu@hodcarrier.org
- */
+#include <common.h> +#include <dm.h> +#include <hang.h> +#include <wdt.h> +#include <asm/io.h> +#include <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.gao@mediatek.com
- based on: include/configs/mt7628.h
- Copyright (C) 2022 Du Huanpeng dhu@hodcarrier.org
- */
+#ifndef __CONFIG_LS1C300_H__ +#define __CONFIG_LS1C300_H__
+#define CONFIG_SYS_HZ 1000
+#define CONFIG_SYS_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 dhu@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