[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 132MHz, CPU at 297MHz, SPI at 33MHz
> > + * SDRAM at 100MHz, CPU at 300MHz, SPI at 50MHz
> > + * SDRAM at 66MHz, CPU at 132MHz, SPI 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