
Hi, Sean, thank you for the comments, I have fix most issues and sent a v2 patch.
> See Techinical Reference Manual for details: https://www.loongson.cn/ Can you provide a direct link please? I looked around a bit but I don't read Chinese and I was unable to figure out where to find more documentation on this CPU.
I can't find direct link too, register is required to access this documents.
How does this boot? JTAG?
use a flash programer and write the u-boot-with-spl.bin to the spi nor flash. or load the ELF file `u-boot' by the shipped bootloader via tftp.
> +#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) > + > + ori t2, 1 > + sw t2, 0x34 (t0) > +#endif > +/* TODO: recalc rate to v0 */ > + li v0, 132000000 > + jr ra > + nop > +END(ls1c300_pll_init) Why does this need to be done in assembly? Ditto for the rest.
this SoC don't have onchip sram to use for initial stack. assembly code prepare a working ram for C stack and heap use. stack is needed in C nested call and the heap is needed in lzma decompress. the spi runs at clock about 0.75MHz on reset, this is very slow, I tweat it to 33MHz.
> + > +/* 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/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 ; > +} Please use a pinctrl driver for this. In particular, you may be able to use pinctrl-simple, which can be configured through the device tree.
this muxing is used in SPL at the very beginning. DM is not avaiable.
> 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); > +} > +#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 Do you have normal uart working?
the normal uart works with ns16550 uart driver. so no extra serial driver for this SoC.
> +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=y > +# 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 Where is the spi flash driver?
TODO :).
> +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); why not start with this? Also, please multiply first for better precision. And use MSEC_PER_SEC instead of 1000.
I want to avoid overflow first, so I do the division first. the macro MSEC_PER_SEC seems not defined in public header, I find it is private defined in multiple place, so I don't want to use this macro this time.
> +#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 So are these different clocks? Why do they all have the same id?
they are all the same clock, the apb bus clock.
> +#endif /* __DT_BINDINGS_LS1C300_CLK_H__ */ >
--- du huanpeng