[RFC PATCH] mips: dts: add initial support for ls1c300 SoC

dhu at hodcarrier.org dhu at hodcarrier.org
Wed Apr 6 11:22:18 CEST 2022


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 at 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 at 132MHzCPU at 297MHzSPI at 33MHz
> > + *	SDRAM at 100MHzCPU at 300MHzSPI at 50MHz
> > + *	SDRAM at 66MHzCPU at 132MHzSPI at 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 at 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 at mediatek.com>
> > + *
> > + * Copyright (C) 2020-2022 Du Huanpeng <dhu at 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 at mediatek.com>
> > + *
> > + * Copyright (C) 2022 Du Huanpeng <dhu at 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<dhu at 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 at 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




More information about the U-Boot mailing list