From 93cc1e2b6d33b9fd588a640ba161f6db377d6181 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 9 Aug 2023 14:06:59 +0800 Subject: board: starfive: Add StarFive VisionFive 2 board support Add board support for StarFive VisionFive 2. The code is ported from tag JH7110_VF2_515_v3.9.3 of VF2 repo. Signed-off-by: Hal Feng --- board/starfive/visionfive/Kconfig | 52 -- board/starfive/visionfive/MAINTAINERS | 7 - board/starfive/visionfive/Makefile | 9 - board/starfive/visionfive/spl.c | 85 --- board/starfive/visionfive/starfive_visionfive.c | 207 ----- board/starfive/visionfive2/Kconfig | 52 ++ board/starfive/visionfive2/MAINTAINERS | 7 + board/starfive/visionfive2/Makefile | 9 + board/starfive/visionfive2/spl.c | 189 +++++ board/starfive/visionfive2/starfive_visionfive2.c | 547 ++++++++++++++ .../starfive/visionfive2/visionfive2-i2c-eeprom.c | 832 +++++++++++++++++++++ include/configs/starfive-visionfive.h | 151 ---- include/configs/starfive-visionfive2.h | 374 +++++++++ 13 files changed, 2010 insertions(+), 511 deletions(-) delete mode 100644 board/starfive/visionfive/Kconfig delete mode 100644 board/starfive/visionfive/MAINTAINERS delete mode 100644 board/starfive/visionfive/Makefile delete mode 100644 board/starfive/visionfive/spl.c delete mode 100755 board/starfive/visionfive/starfive_visionfive.c create mode 100644 board/starfive/visionfive2/Kconfig create mode 100644 board/starfive/visionfive2/MAINTAINERS create mode 100644 board/starfive/visionfive2/Makefile create mode 100644 board/starfive/visionfive2/spl.c create mode 100644 board/starfive/visionfive2/starfive_visionfive2.c create mode 100644 board/starfive/visionfive2/visionfive2-i2c-eeprom.c delete mode 100644 include/configs/starfive-visionfive.h create mode 100644 include/configs/starfive-visionfive2.h diff --git a/board/starfive/visionfive/Kconfig b/board/starfive/visionfive/Kconfig deleted file mode 100644 index d0ed065307..0000000000 --- a/board/starfive/visionfive/Kconfig +++ /dev/null @@ -1,52 +0,0 @@ -if TARGET_STARFIVE_VISIONFIVE - -config SYS_CPU - default "jh7110" - -config SYS_BOARD - default "visionfive" - -config SYS_VENDOR - default "starfive" - -config SYS_CONFIG_NAME - default "starfive-visionfive" - -config ENV_SIZE - default 0x2000 if ENV_IS_IN_SPI_FLASH - -config ENV_OFFSET - default 0x140000 if ENV_IS_IN_SPI_FLASH - -config SYS_TEXT_BASE - default 0x40200000 if SPL - default 0x40000000 if !RISCV_SMODE - default 0x40200000 if RISCV_SMODE - -config SPL_TEXT_BASE - default 0x08000000 - -config SPL_OPENSBI_LOAD_ADDR - default 0x80000000 - -config BOARD_SPECIFIC_OPTIONS # dummy - def_bool y - select STARFIVE_JH7110 - imply CMD_DHCP - imply CMD_EXT2 - imply CMD_EXT4 - imply CMD_FAT - imply CMD_FS_GENERIC - imply CMD_GPT - imply PARTITION_TYPE_GUID - imply CMD_NET - imply CMD_PING - imply CMD_SF - imply DOS_PARTITION - imply EFI_PARTITION - imply IP_DYN - imply ISO_PARTITION - imply PHY_LIB - imply PHY_MSCC - -endif diff --git a/board/starfive/visionfive/MAINTAINERS b/board/starfive/visionfive/MAINTAINERS deleted file mode 100644 index 437f6c2d24..0000000000 --- a/board/starfive/visionfive/MAINTAINERS +++ /dev/null @@ -1,7 +0,0 @@ -STARFIVE JH7110 VISIONFIVE BOARD -M: startfive -S: Maintained -F: arch/riscv/include/asm/arch-jh7110/ -F: board/starfive/visionfive/ -F: include/configs/starfive-visionfive.h -F: configs/starfive_visionfive_defconfig diff --git a/board/starfive/visionfive/Makefile b/board/starfive/visionfive/Makefile deleted file mode 100644 index 841d5d9b2d..0000000000 --- a/board/starfive/visionfive/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# Copyright (C) 2022-2023 StarFive Technology Co., Ltd. -# - -obj-y := starfive_visionfive.o - -obj-$(CONFIG_SPL_BUILD) += spl.o - diff --git a/board/starfive/visionfive/spl.c b/board/starfive/visionfive/spl.c deleted file mode 100644 index 13e934de4b..0000000000 --- a/board/starfive/visionfive/spl.c +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2022-2023 StarFive Technology Co., Ltd. - * Author: yanhong - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define MODE_SELECT_REG 0x1702002c - -int spl_board_init_f(void) -{ - int ret; - - ret = spl_soc_init(); - if (ret) { - debug("JH7110 SPL init failed: %d\n", ret); - return ret; - } - - return 0; -} - -u32 spl_boot_device(void) -{ - int boot_mode = 0; - - boot_mode = readl((const volatile void *)MODE_SELECT_REG) & 0xF; - switch (boot_mode) { - case 0: - return BOOT_DEVICE_SPI; - case 1: - return BOOT_DEVICE_MMC2; - case 2: - return BOOT_DEVICE_MMC1; - case 4: - return BOOT_DEVICE_UART; - default: - debug("Unsupported boot device 0x%x.\n", - boot_mode); - return BOOT_DEVICE_NONE; - } -} - -struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) -{ - return (struct image_header *)(STARFIVE_SPL_BOOT_LOAD_ADDR); -} - -void board_init_f(ulong dummy) -{ - int ret; - - ret = spl_early_init(); - if (ret) - panic("spl_early_init() failed: %d\n", ret); - - arch_cpu_init_dm(); - - preloader_console_init(); - - ret = spl_board_init_f(); - if (ret) { - debug("spl_board_init_f init failed: %d\n", ret); - return; - } -} - -#ifdef CONFIG_SPL_LOAD_FIT -int board_fit_config_name_match(const char *name) -{ - /* boot using first FIT config */ - return 0; -} -#endif - - diff --git a/board/starfive/visionfive/starfive_visionfive.c b/board/starfive/visionfive/starfive_visionfive.c deleted file mode 100755 index 462781a526..0000000000 --- a/board/starfive/visionfive/starfive_visionfive.c +++ /dev/null @@ -1,207 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2021-2023 StarFive Technology Co., Ltd. - * Author: yanhong - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SYS_IOMUX_DOEN(gpio, oen) \ - clrsetbits_le32(SYS_IOMUX_BASE+GPIO_OFFSET(gpio), \ - GPIO_DOEN_MASK << GPIO_SHIFT(gpio), \ - (oen) << GPIO_SHIFT(gpio)) - -#define SYS_IOMUX_DOUT(gpio, gpo) \ - clrsetbits_le32(SYS_IOMUX_BASE + GPIO_DOUT + GPIO_OFFSET(gpio),\ - GPIO_DOUT_MASK << GPIO_SHIFT(gpio),\ - ((gpo) & GPIO_DOUT_MASK) << GPIO_SHIFT(gpio)) - -#define SYS_IOMUX_DIN(gpio, gpi)\ - clrsetbits_le32(SYS_IOMUX_BASE + GPIO_DIN + GPIO_OFFSET(gpi),\ - GPIO_DIN_MASK << GPIO_SHIFT(gpi),\ - ((gpio+2) & GPIO_DIN_MASK) << GPIO_SHIFT(gpi)) - -#define SYS_IOMUX_COMPLEX(gpio, gpi, gpo, oen) do {\ - SYS_IOMUX_DOEN(gpio, oen);\ - SYS_IOMUX_DOUT(gpio, gpo);\ - SYS_IOMUX_DIN(gpio, gpi); }while(0) - -#define SYS_CLOCK_ENABLE(clk) \ - setbits_le32(SYS_CRG_BASE + clk, CLK_ENABLE_MASK) - -static void sys_reset_clear(ulong assert, ulong status, u32 rst) -{ - volatile u32 value; - - clrbits_le32(SYS_CRG_BASE + assert, BIT(rst)); - do{ - value = in_le32(SYS_CRG_BASE + status); - }while((value & BIT(rst)) != BIT(rst)); -} - -static void jh7110_timer_init(void) -{ - SYS_CLOCK_ENABLE(TIMER_CLK_APB_SHIFT); - SYS_CLOCK_ENABLE(TIMER_CLK_TIMER0_SHIFT); - SYS_CLOCK_ENABLE(TIMER_CLK_TIMER1_SHIFT); - SYS_CLOCK_ENABLE(TIMER_CLK_TIMER2_SHIFT); - SYS_CLOCK_ENABLE(TIMER_CLK_TIMER3_SHIFT); - - sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, - SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_APB_SHIFT); - sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, - SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER0_SHIFT); - sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, - SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER1_SHIFT); - sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, - SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER2_SHIFT); - sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, - SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER3_SHIFT); -} - -static void jh7110_gmac_init(int id) -{ - switch (id) { - case 0: - clrsetbits_le32(AON_SYSCON_BASE + AON_SYSCFG_12, - GMAC5_0_SEL_I_MASK, - BIT(GMAC5_0_SEL_I_SHIFT) & GMAC5_0_SEL_I_MASK); - break; - - case 1: - clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_144, - GMAC5_1_SEL_I_MASK, - BIT(GMAC5_1_SEL_I_SHIFT) & GMAC5_1_SEL_I_MASK); - break; - - default: - break; - } -} - -static void jh7110_usb_init(void) -{ - clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, - USB_MODE_STRAP_MASK, - (2< +S: Maintained +F: arch/riscv/include/asm/arch-jh7110/ +F: board/starfive/visionfive2/ +F: include/configs/starfive-visionfive2.h +F: configs/starfive_visionfive2_defconfig diff --git a/board/starfive/visionfive2/Makefile b/board/starfive/visionfive2/Makefile new file mode 100644 index 0000000000..080eed87b2 --- /dev/null +++ b/board/starfive/visionfive2/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2022-2023 StarFive Technology Co., Ltd. +# + +obj-y := starfive_visionfive2.o + +obj-$(CONFIG_SPL_BUILD) += spl.o +obj-$(CONFIG_ID_EEPROM) += visionfive2-i2c-eeprom.o diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c new file mode 100644 index 0000000000..2149fc519f --- /dev/null +++ b/board/starfive/visionfive2/spl.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Starfive, Inc. + * Author: yanhong + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODE_SELECT_REG 0x1702002c + +int spl_board_init_f(void) +{ + int ret; + + ret = spl_soc_init(); + if (ret) { + debug("JH7110 SPL init failed: %d\n", ret); + return ret; + } + + return 0; +} + +u32 spl_boot_device(void) +{ + int boot_mode = 0; + + boot_mode = readl((const volatile void *)MODE_SELECT_REG) & 0x3; + switch (boot_mode) { + case 0: + return BOOT_DEVICE_SPI; + case 1: + return BOOT_DEVICE_MMC2; + case 2: + return BOOT_DEVICE_MMC1; + case 3: + return BOOT_DEVICE_UART; + default: + debug("Unsupported boot device 0x%x.\n", + boot_mode); + return BOOT_DEVICE_NONE; + } +} + +struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +{ + return (struct image_header *)(STARFIVE_SPL_BOOT_LOAD_ADDR); +} + +void board_init_f(ulong dummy) +{ + int ret; + + /* Set pll0 cpufreq to 1000M */ + starfive_jh7110_pll_set_rate(PLL0, 1000000000); + + /*change pll2 to 1188MHz*/ + starfive_jh7110_pll_set_rate(PLL2, 1188000000); + + /*DDR control depend clk init*/ + clrsetbits_le32(SYS_CRG_BASE, CLK_CPU_ROOT_SW_MASK, + BIT(CLK_CPU_ROOT_SW_SHIFT) & CLK_CPU_ROOT_SW_MASK); + + clrsetbits_le32(SYS_CRG_BASE + CLK_BUS_ROOT_OFFSET, + CLK_BUS_ROOT_SW_MASK, + BIT(CLK_BUS_ROOT_SW_SHIFT) & CLK_BUS_ROOT_SW_MASK); + + /*Set clk_perh_root clk default mux sel to pll2*/ + clrsetbits_le32(SYS_CRG_BASE + CLK_PERH_ROOT_OFFSET, + CLK_PERH_ROOT_MASK, + BIT(CLK_PERH_ROOT_SHIFT) & CLK_PERH_ROOT_MASK); + + clrsetbits_le32(SYS_CRG_BASE + CLK_NOC_BUS_STG_AXI_OFFSET, + CLK_NOC_BUS_STG_AXI_EN_MASK, + BIT(CLK_NOC_BUS_STG_AXI_EN_SHIFT) + & CLK_NOC_BUS_STG_AXI_EN_MASK); + + clrsetbits_le32(AON_CRG_BASE + CLK_AON_APB_FUNC_OFFSET, + CLK_AON_APB_FUNC_SW_MASK, + BIT(CLK_AON_APB_FUNC_SW_SHIFT) & CLK_AON_APB_FUNC_SW_MASK); + + clrsetbits_le32(SYS_CRG_BASE + CLK_QSPI_REF_OFFSET, + CLK_QSPI_REF_SW_MASK, + (1 << CLK_QSPI_REF_SW_SHIFT) & CLK_QSPI_REF_SW_MASK); + + /* Improved GMAC0 TX I/O PAD capability */ + clrsetbits_le32(AON_IOMUX_BASE + 0x78, 0x3, BIT(0) & 0x3); + clrsetbits_le32(AON_IOMUX_BASE + 0x7c, 0x3, BIT(0) & 0x3); + clrsetbits_le32(AON_IOMUX_BASE + 0x80, 0x3, BIT(0) & 0x3); + clrsetbits_le32(AON_IOMUX_BASE + 0x84, 0x3, BIT(0) & 0x3); + clrsetbits_le32(AON_IOMUX_BASE + 0x88, 0x3, BIT(0) & 0x3); + + /* Improved GMAC1 TX I/O PAD capability */ + clrsetbits_le32(SYS_IOMUX_BASE + 0x26c, 0x3, BIT(0) & 0x3); + clrsetbits_le32(SYS_IOMUX_BASE + 0x270, 0x3, BIT(0) & 0x3); + clrsetbits_le32(SYS_IOMUX_BASE + 0x274, 0x3, BIT(0) & 0x3); + clrsetbits_le32(SYS_IOMUX_BASE + 0x278, 0x3, BIT(0) & 0x3); + clrsetbits_le32(SYS_IOMUX_BASE + 0x27c, 0x3, BIT(0) & 0x3); + + /*set GPIO to 3.3v*/ + setbits_le32(SYS_SYSCON_BASE + 0xC, 0x0); + + /*uart0 tx*/ + SYS_IOMUX_DOEN(5, LOW); + SYS_IOMUX_DOUT(5, 20); + /*uart0 rx*/ + SYS_IOMUX_DOEN(6, HIGH); + SYS_IOMUX_DIN(6, 14); + + /*jtag*/ + SYS_IOMUX_DOEN(36, HIGH); + SYS_IOMUX_DIN(36, 4); + SYS_IOMUX_DOEN(61, HIGH); + SYS_IOMUX_DIN(61, 19); + SYS_IOMUX_DOEN(63, HIGH); + SYS_IOMUX_DIN(63, 20); + SYS_IOMUX_DOEN(60, HIGH); + SYS_IOMUX_DIN(60, 29); + SYS_IOMUX_DOEN(44, 8); + SYS_IOMUX_DOUT(44, 22); + + /* reset emmc */ + SYS_IOMUX_DOEN(62, LOW); + SYS_IOMUX_DOUT(62, 19); + SYS_IOMUX_SET_DS(64, 2); + SYS_IOMUX_SET_SLEW(64, 1); + SYS_IOMUX_SET_DS(65, 1); + SYS_IOMUX_SET_DS(66, 1); + SYS_IOMUX_SET_DS(67, 1); + SYS_IOMUX_SET_DS(68, 1); + SYS_IOMUX_SET_DS(69, 1); + SYS_IOMUX_SET_DS(70, 1); + SYS_IOMUX_SET_DS(71, 1); + SYS_IOMUX_SET_DS(72, 1); + SYS_IOMUX_SET_DS(73, 1); + /* reset sdio */ + SYS_IOMUX_DOEN(10, LOW); + SYS_IOMUX_DOUT(10, 55); + SYS_IOMUX_SET_DS(10, 2); + SYS_IOMUX_SET_SLEW(10, 1); + SYS_IOMUX_COMPLEX(9, 44, 57, 19); + SYS_IOMUX_SET_DS(9, 1); + SYS_IOMUX_COMPLEX(11, 45, 58, 20); + SYS_IOMUX_SET_DS(11, 1); + SYS_IOMUX_COMPLEX(12, 46, 59, 21); + SYS_IOMUX_SET_DS(12, 1); + SYS_IOMUX_COMPLEX(7, 47, 60, 22); + SYS_IOMUX_SET_DS(7, 1); + SYS_IOMUX_COMPLEX(8, 48, 61, 23); + SYS_IOMUX_SET_DS(8, 1); + + /*i2c5*/ + SYS_IOMUX_COMPLEX(19, 79, 0, 42);//scl + SYS_IOMUX_COMPLEX(20, 80, 0, 43);//sda + + ret = spl_early_init(); + if (ret) + panic("spl_early_init() failed: %d\n", ret); + + arch_cpu_init_dm(); + + preloader_console_init(); + + ret = spl_board_init_f(); + if (ret) { + debug("spl_board_init_f init failed: %d\n", ret); + return; + } +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* boot using first FIT config */ + return 0; +} +#endif + + diff --git a/board/starfive/visionfive2/starfive_visionfive2.c b/board/starfive/visionfive2/starfive_visionfive2.c new file mode 100644 index 0000000000..1d14c618dc --- /dev/null +++ b/board/starfive/visionfive2/starfive_visionfive2.c @@ -0,0 +1,547 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Starfive, Inc. + * Author: yanhong + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SYS_CLOCK_ENABLE(clk) \ + setbits_le32(SYS_CRG_BASE + clk, CLK_ENABLE_MASK) + +#define PCB_REVISION_MASK 0xF0 +#define PCB_REVISION_SHIFT 4 +#define PCB_REVISION_A 0x0A +#define PCB_REVISION_B 0x0B +#define CHIP_REVISION_SHIFT 80 + +#define CPU_VOL_BINNING_OFFSET 0x7fc + +enum { + BOOT_FLASH = 0, + BOOT_SD, + BOOT_EMMC, + BOOT_UART, +}; + +enum chip_type_t { + CHIP_A = 0, + CHIP_B, + CHIP_MAX, +}; + +enum board_type_t { + BOARD_1000M_1000M = 0, + BOARD_1000M_100M, + BOARD_TYPE_MAX, +}; + + +enum cpu_voltage_type_t { + CPU_VOL_1020 = 0xef0, + CPU_VOL_1040 = 0xfff, + CPU_VOL_1060 = 0xff0, + CPU_VOL_1000 = 0x8f0, +}; +#define CPU_VOL_MASK 0xfff + +static void sys_reset_clear(ulong assert, ulong status, u32 rst) +{ + u32 value; + + clrbits_le32(SYS_CRG_BASE + assert, BIT(rst)); + do { + value = in_le32(SYS_CRG_BASE + status); + } while ((value & BIT(rst)) != BIT(rst)); +} + +static void jh7110_timer_init(void) +{ + SYS_CLOCK_ENABLE(TIMER_CLK_APB_SHIFT); + SYS_CLOCK_ENABLE(TIMER_CLK_TIMER0_SHIFT); + SYS_CLOCK_ENABLE(TIMER_CLK_TIMER1_SHIFT); + SYS_CLOCK_ENABLE(TIMER_CLK_TIMER2_SHIFT); + SYS_CLOCK_ENABLE(TIMER_CLK_TIMER3_SHIFT); + + sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, + SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_APB_SHIFT); + sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, + SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER0_SHIFT); + sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, + SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER1_SHIFT); + sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, + SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER2_SHIFT); + sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, + SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER3_SHIFT); +} + +static void jh7110_gmac_init_1000M(int id) +{ + switch (id) { + case 0: + clrsetbits_le32(AON_SYSCON_BASE + AON_SYSCFG_12, + GMAC5_0_SEL_I_MASK, + BIT(GMAC5_0_SEL_I_SHIFT) & GMAC5_0_SEL_I_MASK); + break; + + case 1: + clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_144, + GMAC5_1_SEL_I_MASK, + BIT(GMAC5_1_SEL_I_SHIFT) & GMAC5_1_SEL_I_MASK); + break; + + default: + break; + } +} + +static void jh7110_gmac_init_100M(int id) +{ + switch (id) { + case 0: + clrsetbits_le32(AON_SYSCON_BASE + AON_SYSCFG_12, + GMAC5_0_SEL_I_MASK, + (4 << GMAC5_0_SEL_I_SHIFT) & GMAC5_0_SEL_I_MASK); + setbits_le32(AON_CRG_BASE + GMAC5_0_CLK_TX_SHIFT, 0x1000000); + setbits_le32(AON_CRG_BASE + GMAC5_0_CLK_RX_SHIFT, 0x1000000); + break; + + case 1: + clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_144, + GMAC5_1_SEL_I_MASK, + (4 << GMAC5_1_SEL_I_SHIFT) & GMAC5_1_SEL_I_MASK); + setbits_le32(SYS_CRG_BASE + GMAC5_1_CLK_TX_SHIFT, 0x1000000); + setbits_le32(SYS_CRG_BASE + GMAC5_1_CLK_RX_SHIFT, 0x1000000); + break; + + default: + break; + } +} + +static void jh7110_gmac_sel_tx_to_rgmii(int id) +{ + switch (id) { + case 0: + clrsetbits_le32(AON_CRG_BASE + GMAC5_0_CLK_TX_SHIFT, + GMAC5_0_CLK_TX_MASK, + BIT(GMAC5_0_CLK_TX_BIT) & GMAC5_0_CLK_TX_MASK); + break; + + case 1: + clrsetbits_le32(SYS_CRG_BASE + GMAC5_1_CLK_TX_SHIFT, + GMAC5_1_CLK_TX_MASK, + BIT(GMAC5_1_CLK_TX_BIT) & GMAC5_1_CLK_TX_MASK); + break; + + default: + break; + } +} + +static void set_uboot_fdt_addr_env(void) +{ + char str[17]; + ulong fdt_addr = (ulong)gd->fdt_blob; + + sprintf(str, "0x%lx", fdt_addr); + env_set("uboot_fdt_addr", str); +} + +static int get_chip_type(void) +{ + int type; + int len = -1; + u8 data; + + len = get_data_from_eeprom(CHIP_REVISION_SHIFT, 1, &data); + if (len <= 0) { + env_set("chip_vision", "UNKOWN"); + return -EINVAL; + } + + switch (data) { + case 'a': + case 'A': + type = CHIP_A; + env_set("chip_vision", "A"); + break; + case 'b': + case 'B': + type = CHIP_B; + env_set("chip_vision", "B"); + break; + default: + type = CHIP_MAX; + env_set("chip_vision", "UNKOWN"); + break; + } + return type; +} +static int get_board_type(void) +{ + u8 pv; + int type; + + pv = get_pcb_revision_from_eeprom(); + pv = (pv & PCB_REVISION_MASK) >> PCB_REVISION_SHIFT; + + if (pv == PCB_REVISION_A) { + type = BOARD_1000M_100M; + } else if (pv == PCB_REVISION_B) { + type = BOARD_1000M_1000M; + } else { + type = BOARD_TYPE_MAX; + } + + return type; +} + +static void jh7110_gmac_init(int chip_type, int pcb_type) +{ + switch (chip_type) { + case CHIP_A: + break; + case CHIP_B: + default: + jh7110_gmac_sel_tx_to_rgmii(0); + jh7110_gmac_sel_tx_to_rgmii(1); + break; + } + + switch (pcb_type) { + case BOARD_1000M_100M: + jh7110_gmac_init_1000M(0); + jh7110_gmac_init_100M(1); + break; + + case BOARD_1000M_1000M: + default: + jh7110_gmac_init_1000M(0); + jh7110_gmac_init_1000M(1); + break; + } +} + +static void jh7110_usb_init(bool usb2_enable) +{ + if (usb2_enable) { + /*usb 2.0 utmi phy init*/ + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, + USB_MODE_STRAP_MASK, + (2<ram_base); + env_set_hex("memory_size", gd->ram_size); + + ret = uclass_get_device(UCLASS_VIDEO, 0, &dev); + if (ret) + return ret; + + ret = video_bmp_display(dev, (ulong)&bmp_logo_bitmap[0], BMP_ALIGN_CENTER, BMP_ALIGN_CENTER, true); + if (ret) + goto err; + +err: + return 0; +} +#endif + +#ifdef CONFIG_MISC_INIT_R + +int misc_init_r(void) +{ + char mac0[6] = {0x6c, 0xcf, 0x39, 0x6c, 0xde, 0xad}; + char mac1[6] = {0x6c, 0xcf, 0x39, 0x7c, 0xae, 0x5d}; + +#if CONFIG_IS_ENABLED(STARFIVE_OTP) + struct udevice *dev; + char buf[16]; + int ret; +#define MACADDR_OFFSET 0x8 + + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_DRIVER_GET(starfive_otp), &dev); + if (ret) { + debug("%s: could not find otp device\n", __func__); + goto err; + } + + ret = misc_read(dev, MACADDR_OFFSET, buf, sizeof(buf)); + if (ret != sizeof(buf)) + printf("%s: error reading mac from OTP\n", __func__); + else + if (buf[0] != 0xff) { + memcpy(mac0, buf, 6); + memcpy(mac1, &buf[8], 6); + } +err: +#endif + eth_env_set_enetaddr("eth0addr", mac0); + eth_env_set_enetaddr("eth1addr", mac1); + + get_chip_type(); + set_uboot_fdt_addr_env(); +#if CONFIG_IS_ENABLED(STARFIVE_OTP) + get_cpu_voltage_type(dev); +#endif + return 0; +} +#endif + +#ifdef CONFIG_ID_EEPROM + +#include +#define STARFIVE_JH7110_EEPROM_DDRINFO_OFFSET 91 + +static bool check_eeprom_dram_info(ulong size) +{ + switch (size) { + case 1: + case 2: + case 4: + case 8: + case 16: + return true; + default: + return false; + } +} + +static int resize_ddr_from_eeprom(void) +{ + struct udevice *dev; + ulong size; + u32 len = 1; + u8 data = 0; + int ret; + + /* I2C init */ + ret = uclass_get_device(UCLASS_I2C, 0, &dev); + if (ret) { + debug("I2C init failed: %d\n", ret); + return 0; + } + + /* read memory size info */ + ret = get_data_from_eeprom(STARFIVE_JH7110_EEPROM_DDRINFO_OFFSET, len, &data); + if (ret == len) { + size = hextoul(&data, NULL); + if (check_eeprom_dram_info(size)) + return size; + } + return 0; +} +#else +static int resize_ddr_from_eeprom(void) +{ + return 0; +} +#endif /* CONFIG_ID_EEPROM */ + +int board_ddr_size(void) +{ + return resize_ddr_from_eeprom(); +} diff --git a/board/starfive/visionfive2/visionfive2-i2c-eeprom.c b/board/starfive/visionfive2/visionfive2-i2c-eeprom.c new file mode 100644 index 0000000000..5f2e698ad9 --- /dev/null +++ b/board/starfive/visionfive2/visionfive2-i2c-eeprom.c @@ -0,0 +1,832 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. + * Written by Wei Fu (wefu@redhat.com) + */ + + +#include +#include +#include +#include +#include +#include +#include + +#define CONFIG_SYS_EEPROM_BUS_NUM 0 + +#define FORMAT_VERSION 0x2 +#define PCB_VERSION 0xB1 +#define BOM_VERSION 'A' +/* + * BYTES_PER_EEPROM_PAGE: the 24FC04H datasheet says that data can + * only be written in page mode, which means 16 bytes at a time: + * 16-Byte Page Write Buffer + */ +#define BYTES_PER_EEPROM_PAGE 16 + +/* + * EEPROM_WRITE_DELAY_MS: the 24FC04H datasheet says it takes up to + * 5ms to complete a given write: + * Write Cycle Time (byte or page) ro Page Write Time 5 ms, Maximum + */ +#define EEPROM_WRITE_DELAY_MS 5000 +/* + * StarFive OUI. Registration Date is 20xx-xx-xx + */ +#define STARFIVE_OUI_PREFIX "6C:CF:39:" +#define STARFIVE_DEFAULT_MAC0 {0x6c, 0xcf, 0x39, 0x6c, 0xde, 0xad} +#define STARFIVE_DEFAULT_MAC1 {0x6c, 0xcf, 0x39, 0x7c, 0xae, 0x5d} + +/* Magic number at the first four bytes of EEPROM HATs */ +#define STARFIVE_EEPROM_HATS_SIG "SFVF" /* StarFive VisionFive */ + +#define STARFIVE_EEPROM_HATS_SIZE_MAX 256 /* Header + Atom1&4(v1) */ +#define STARFIVE_EEPROM_WP_OFFSET 0 /* Read only field */ +#define STARFIVE_EEPROM_ATOM1_PSTR "VF7110A1-2228-D008E000-00000001\0" +#define STARFIVE_EEPROM_ATOM1_PSTR_SIZE 32 +#define STARFIVE_EEPROM_ATOM1_SN_OFFSET 23 +#define STARFIVE_EEPROM_ATOM1_VSTR "StarFive Technology Co., Ltd.\0\0\0" +#define STARFIVE_EEPROM_ATOM1_VSTR_SIZE 32 + +/* + * MAGIC_NUMBER_BYTES: number of bytes used by the magic number + */ +#define MAGIC_NUMBER_BYTES 4 + +/* + * MAC_ADDR_BYTES: number of bytes used by the Ethernet MAC address + */ +#define MAC_ADDR_BYTES 6 + +/* + * MAC_ADDR_STRLEN: length of mac address string + */ +#define MAC_ADDR_STRLEN 17 + +/* + * Atom Types + * 0x0000 = invalid + * 0x0001 = vendor info + * 0x0002 = GPIO map + * 0x0003 = Linux device tree blob + * 0x0004 = manufacturer custom data + * 0x0005-0xfffe = reserved for future use + * 0xffff = invalid + */ + +#define HATS_ATOM_INVALID 0x0000 +#define HATS_ATOM_VENDOR 0x0001 +#define HATS_ATOM_GPIO 0x0002 +#define HATS_ATOM_DTB 0x0003 +#define HATS_ATOM_CUSTOM 0x0004 +#define HATS_ATOM_INVALID_END 0xffff + +struct eeprom_hats_header { + char signature[MAGIC_NUMBER_BYTES]; /* ASCII table signature */ + u8 version; /* EEPROM data format version */ + /* (0x00 reserved, 0x01 = first version) */ + u8 reversed; /* 0x00, Reserved field */ + u16 numatoms; /* total atoms in EEPROM */ + u32 eeplen; /* total length in bytes of all eeprom data */ + /* (including this header) */ +}; + +struct eeprom_hats_atom_header { + u16 type; + u16 count; + u32 dlen; +}; + +/** + * static eeprom: EEPROM layout for the StarFive platform I2C format + */ +struct starfive_eeprom_atom1_data { + u8 uuid[16]; + u16 pid; + u16 pver; + u8 vslen; + u8 pslen; + uchar vstr[STARFIVE_EEPROM_ATOM1_VSTR_SIZE]; + uchar pstr[STARFIVE_EEPROM_ATOM1_PSTR_SIZE]; /* product SN */ +}; + +struct starfive_eeprom_atom1 { + struct eeprom_hats_atom_header header; + struct starfive_eeprom_atom1_data data; + u16 crc16; +}; + +struct starfive_eeprom_atom4_v1_data { + u16 version; + u8 pcb_revision; /* PCB version */ + u8 bom_revision; /* BOM version */ + u8 mac0_addr[MAC_ADDR_BYTES]; /* Ethernet0 MAC */ + u8 mac1_addr[MAC_ADDR_BYTES]; /* Ethernet1 MAC */ + u8 reserved[2]; +}; + +struct starfive_eeprom_atom4_v1 { + struct eeprom_hats_atom_header header; + struct starfive_eeprom_atom4_v1_data data; + u16 crc16; +}; + +/* Set to 1 if we've read EEPROM into memory + * Set to -1 if EEPROM data is wrong + */ +static int has_been_read; + +/** + * helper struct for getting info from the local EEPROM copy. + * most of the items are pointers to the eeprom_wp_buff. + * ONLY serialnum is the u32 from the last 8 Bytes of product string + */ +struct starfive_eeprom_info { + char *vstr; /* Vendor string in ATOM1 */ + char *pstr; /* product string in ATOM1 */ + u32 serialnum; /* serial number from in product string*/ + u16 *version; /* custom data version in ATOM4 */ + u8 *pcb_revision; /* PCB version in ATOM4 */ + u8 *bom_revision; /* BOM version in ATOM4 */ + u8 *mac0_addr; /* Ethernet0 MAC in ATOM4 */ + u8 *mac1_addr; /* Ethernet1 MAC in ATOM4 */ +}; +static struct starfive_eeprom_info einfo; + + +static uchar eeprom_wp_buff[STARFIVE_EEPROM_HATS_SIZE_MAX]; +static struct eeprom_hats_header starfive_eeprom_hats_header_default = { + .signature = STARFIVE_EEPROM_HATS_SIG, + .version = FORMAT_VERSION, + .numatoms = 2, + .eeplen = sizeof(struct eeprom_hats_header) + + sizeof(struct starfive_eeprom_atom1) + + sizeof(struct starfive_eeprom_atom4_v1) +}; +static struct starfive_eeprom_atom1 starfive_eeprom_atom1_default = { + .header = { + .type = HATS_ATOM_VENDOR, + .count = 1, + .dlen = sizeof(struct starfive_eeprom_atom1_data) + sizeof(u16) + }, + .data = { + .uuid = {0}, + .pid = 0, + .pver = 0, + .vslen = STARFIVE_EEPROM_ATOM1_VSTR_SIZE, + .pslen = STARFIVE_EEPROM_ATOM1_PSTR_SIZE, + .vstr = STARFIVE_EEPROM_ATOM1_VSTR, + .pstr = STARFIVE_EEPROM_ATOM1_PSTR + } +}; +static struct starfive_eeprom_atom4_v1 starfive_eeprom_atom4_v1_default = { + .header = { + .type = HATS_ATOM_CUSTOM, + .count = 2, + .dlen = sizeof(struct starfive_eeprom_atom4_v1_data) + sizeof(u16) + }, + .data = { + .version = FORMAT_VERSION, + .pcb_revision = PCB_VERSION, + .bom_revision = BOM_VERSION, + .mac0_addr = STARFIVE_DEFAULT_MAC0, + .mac1_addr = STARFIVE_DEFAULT_MAC1, + .reserved = {0} + } +}; + +//static u8 starfive_default_mac[MAC_ADDR_BYTES] = STARFIVE_DEFAULT_MAC; + +/** + * is_match_magic() - Does the magic number match that of a StarFive EEPROM? + * + * @hats: the pointer of eeprom_hats_header + * Return: status code, 0: Yes, non-0: NO + */ +static inline int is_match_magic(char *hats) +{ + return strncmp(hats, STARFIVE_EEPROM_HATS_SIG, MAGIC_NUMBER_BYTES); +} + +/** + * calculate_crc16() - Calculate the current CRC for atom + * Porting from https://github.com/raspberrypi/hats, getcrc + * @data: the pointer of eeprom_hats_atom_header + * @size: total length in bytes of the entire atom + * (type, count, dlen, data) + * Return: result: crc16 code + */ +#define CRC16 0x8005 +static u16 calculate_crc16(uchar* data, unsigned int size) +{ + int i, j = 0x0001; + u16 out = 0, crc = 0; + int bits_read = 0, bit_flag; + + /* Sanity check: */ + if((data == NULL) || size == 0) + return 0; + + while(size > 0) { + bit_flag = out >> 15; + + /* Get next bit: */ + out <<= 1; + // item a) work from the least significant bits + out |= (*data >> bits_read) & 1; + + /* Increment bit counter: */ + bits_read++; + if(bits_read > 7) { + bits_read = 0; + data++; + size--; + } + + /* Cycle check: */ + if(bit_flag) + out ^= CRC16; + } + + // item b) "push out" the last 16 bits + for (i = 0; i < 16; ++i) { + bit_flag = out >> 15; + out <<= 1; + if(bit_flag) + out ^= CRC16; + } + + // item c) reverse the bits + for (i = 0x8000; i != 0; i >>=1, j <<= 1) { + if (i & out) + crc |= j; + } + + return crc; +} + +/* This function should be called after each update to any EEPROM ATOM */ +static inline void update_crc(struct eeprom_hats_atom_header *atom) +{ + uint atom_crc_offset = sizeof(struct eeprom_hats_atom_header) + + atom->dlen - sizeof(u16); + u16 *atom_crc_p = (void *) atom + atom_crc_offset; + *atom_crc_p = calculate_crc16((uchar*) atom, atom_crc_offset); +} + +/** + * dump_raw_eeprom - display the raw contents of the EEPROM + */ +static void dump_raw_eeprom(u8 *e, unsigned int size) +{ + unsigned int i; + + printf("EEPROM dump: (0x%x bytes)\n", size); + + for (i = 0; i < size; i++) { + if (!(i % 0x10)) + printf("%02X: ", i); + + printf("%02X ", e[i]); + + if (((i % 16) == 15) || (i == size - 1)) + printf("\n"); + } + + return; +} + +static int hats_atom_crc_check(struct eeprom_hats_atom_header *atom) +{ + u16 atom_crc, data_crc; + uint atom_crc_offset = sizeof(struct eeprom_hats_atom_header) + + atom->dlen - sizeof(atom_crc); + u16 *atom_crc_p = (void *) atom + atom_crc_offset; + + atom_crc = *atom_crc_p; + data_crc = calculate_crc16((uchar *) atom, atom_crc_offset); + if (atom_crc == data_crc) + return 0; + + printf("EEPROM HATs: CRC ERROR in atom %x type %x, (%x!=%x)\n", + atom->count, atom->type, atom_crc, data_crc); + return -1; +} + +static void *hats_get_atom(struct eeprom_hats_header *header, u16 type) + { + struct eeprom_hats_atom_header *atom; + void *hats_eeprom_max = (void *)header + header->eeplen; + void *temp = (void *)header + sizeof(struct eeprom_hats_header); + + for (int numatoms = (int)header->numatoms; numatoms > 0; numatoms--) { + atom = (struct eeprom_hats_atom_header *)temp; + if (hats_atom_crc_check(atom)) + return NULL; + if (atom->type == type) + return (void *)atom; + /* go to next atom */ + temp = (void *)atom + sizeof(struct eeprom_hats_atom_header) + + atom->dlen; + if (temp > hats_eeprom_max) { + printf("EEPROM HATs: table overflow next@%p, max@%p\n", + temp, hats_eeprom_max); + break; + } + } + + /* fail to get atom */ + return NULL; +} + +/** + * show_eeprom - display the contents of the EEPROM + */ +static void show_eeprom(struct starfive_eeprom_info *einfo) +{ + if (has_been_read != 1) + return; + + printf("\n--------EEPROM INFO--------\n"); + printf("Vendor : %s\n", einfo->vstr); + printf("Product full SN: %s\n", einfo->pstr); + printf("data version: 0x%x\n", *einfo->version); + if (2 == *einfo->version) { + printf("PCB revision: 0x%x\n", *einfo->pcb_revision); + printf("BOM revision: %c\n", *einfo->bom_revision); + printf("Ethernet MAC0 address: %02x:%02x:%02x:%02x:%02x:%02x\n", + einfo->mac0_addr[0], einfo->mac0_addr[1], + einfo->mac0_addr[2], einfo->mac0_addr[3], + einfo->mac0_addr[4], einfo->mac0_addr[5]); + printf("Ethernet MAC1 address: %02x:%02x:%02x:%02x:%02x:%02x\n", + einfo->mac1_addr[0], einfo->mac1_addr[1], + einfo->mac1_addr[2], einfo->mac1_addr[3], + einfo->mac1_addr[4], einfo->mac1_addr[5]); + } else { + printf("Custom data v%d is not Supported\n", *einfo->version); + } + printf("--------EEPROM INFO--------\n\n"); +} + +/** + * parse_eeprom_info - parse the contents of the EEPROM + * If everthing gose right, + * 1, set has_been_read to 1 + * 2, display info + * + * If anything goes wrong, + * 1, set has_been_read to -1 + * 2, dump data by hex for debug + * + * @buf: the pointer of eeprom_hats_header in memory + * Return: status code, 0: Success, non-0: Fail + * + */ +static int parse_eeprom_info(struct eeprom_hats_header *buf) +{ + struct eeprom_hats_atom_header *atom; + void *atom_data; + struct starfive_eeprom_atom1_data *atom1 = NULL; + struct starfive_eeprom_atom4_v1_data *atom4_v1 = NULL; + + if (is_match_magic((char *)buf)) { + printf("Not a StarFive EEPROM data format - magic error\n"); + goto error; + }; + + // parse atom1(verdor) + atom = (struct eeprom_hats_atom_header *) + hats_get_atom(buf, HATS_ATOM_VENDOR); + if (atom) { + atom_data = (void *)atom + + sizeof(struct eeprom_hats_atom_header); + atom1 = (struct starfive_eeprom_atom1_data *)atom_data; + einfo.vstr = atom1->vstr; + einfo.pstr = atom1->pstr; + einfo.serialnum = (u32)hextoul((void *)atom1->pstr + + STARFIVE_EEPROM_ATOM1_SN_OFFSET, + NULL); + } else { + printf("fail to get vendor atom\n"); + goto error; + }; + + // parse atom4(custom) + atom = (struct eeprom_hats_atom_header *) + hats_get_atom(buf, HATS_ATOM_CUSTOM); + if (atom) { + atom_data = (void *)atom + + sizeof(struct eeprom_hats_atom_header); + atom4_v1 = (struct starfive_eeprom_atom4_v1_data *)atom_data; + einfo.version = &atom4_v1->version; + if (*einfo.version == 2) { + einfo.pcb_revision = &atom4_v1->pcb_revision; + einfo.bom_revision = &atom4_v1->bom_revision; + einfo.mac0_addr = atom4_v1->mac0_addr; + einfo.mac1_addr = atom4_v1->mac1_addr; + } + } else { + printf("fail to get custom data atom\n"); + goto error; + }; + + // everthing gose right + has_been_read = 1; + + return 0; + +error: + has_been_read = -1; + return -1; +} + +/** + * read_eeprom() - read the EEPROM into memory, if it hasn't been read yet + * @buf: the pointer of eeprom data buff + * Return: status code, 0: Success, non-0: Fail + * Note: depend on CONFIG_SYS_EEPROM_BUS_NUM + * CONFIG_SYS_I2C_EEPROM_ADDR + * STARFIVE_EEPROM_WP_OFFSET + * STARFIVE_EEPROM_HATS_SIZE_MAX + */ +static int read_eeprom(uint8_t *buf) +{ + int ret; + struct udevice *dev; + + if (has_been_read == 1) + return 0; + + ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM, + CONFIG_SYS_I2C_EEPROM_ADDR, + CONFIG_SYS_I2C_EEPROM_ADDR_LEN, + &dev); + if (!ret) { + ret = dm_i2c_read(dev, STARFIVE_EEPROM_WP_OFFSET, + buf, STARFIVE_EEPROM_HATS_SIZE_MAX); + } + + if (ret) { + printf("fail to read EEPROM.\n"); + return ret; + } + + return parse_eeprom_info((struct eeprom_hats_header *)buf); +} + +/** + * prog_eeprom() - write the EEPROM from memory + */ +static int prog_eeprom(uint8_t *buf, unsigned int size) +{ + unsigned int i; + void *p; + uchar tmp_buff[STARFIVE_EEPROM_HATS_SIZE_MAX]; + struct udevice *dev; + int ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM, + CONFIG_SYS_I2C_EEPROM_ADDR, + CONFIG_SYS_I2C_EEPROM_ADDR_LEN, + &dev); + + if (is_match_magic(buf)) { + printf("MAGIC ERROR, Please check the data@%p.\n", buf); + return -1; + } + + for (i = 0, p = buf; i < size; + i += BYTES_PER_EEPROM_PAGE, p += BYTES_PER_EEPROM_PAGE) { + if (!ret) + ret = dm_i2c_write(dev, + i + STARFIVE_EEPROM_WP_OFFSET, + p, min((int)(size - i), + BYTES_PER_EEPROM_PAGE)); + if (ret) + break; + udelay(EEPROM_WRITE_DELAY_MS); + } + + if (!ret) { + /* Verify the write by reading back the EEPROM and comparing */ + ret = dm_i2c_read(dev, + STARFIVE_EEPROM_WP_OFFSET, + tmp_buff, + STARFIVE_EEPROM_HATS_SIZE_MAX); + if (!ret && memcmp((void *)buf, (void *)tmp_buff, + STARFIVE_EEPROM_HATS_SIZE_MAX)) + ret = -1; + } + + if (ret) { + has_been_read = -1; + printf("Programming failed.Temp buff:\n"); + dump_raw_eeprom(tmp_buff, + STARFIVE_EEPROM_HATS_SIZE_MAX); + return -1; + } + + printf("Programming passed.\n"); + return 0; +} + +/** + * set_mac_address() - stores a MAC address into the local EEPROM copy + * + * This function takes a pointer to MAC address string + * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number), + * stores it in the MAC address field of the EEPROM local copy, and + * updates the local copy of the CRC. + */ +static void set_mac_address(char *string, int index) +{ + unsigned int i; + struct eeprom_hats_atom_header *atom4; + atom4 = (struct eeprom_hats_atom_header *) + hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff, + HATS_ATOM_CUSTOM); + + if (strncasecmp(STARFIVE_OUI_PREFIX, string, + strlen(STARFIVE_OUI_PREFIX))) { + printf("The MAC address doesn't match StarFive OUI %s\n", + STARFIVE_OUI_PREFIX); + return; + } + + for (i = 0; *string && (i < MAC_ADDR_BYTES); i++) { + if (index == 0) { + einfo.mac0_addr[i] = hextoul(string, &string); + } else { + einfo.mac1_addr[i] = hextoul(string, &string); + } + if (*string == ':') + string++; + } + + update_crc(atom4); +} + +/** + * set_pcb_revision() - stores a StarFive PCB revision into the local EEPROM copy + * + * Takes a pointer to a string representing the numeric PCB revision in + * decimal ("0" - "255"), stores it in the pcb_revision field of the + * EEPROM local copy, and updates the CRC of the local copy. + */ +static void set_pcb_revision(char *string) +{ + u8 p; + uint base = 16; + struct eeprom_hats_atom_header *atom4; + atom4 = (struct eeprom_hats_atom_header *) + hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff, + HATS_ATOM_CUSTOM); + + p = (u8)simple_strtoul(string, NULL, base); + if (p > U8_MAX) { + printf("%s must not be greater than %d\n", "PCB revision", + U8_MAX); + return; + } + + *einfo.pcb_revision = p; + + update_crc(atom4); +} + +/** + * set_bom_revision() - stores a StarFive BOM revision into the local EEPROM copy + * + * Takes a pointer to a uppercase ASCII character representing the BOM + * revision ("A" - "Z"), stores it in the bom_revision field of the + * EEPROM local copy, and updates the CRC of the local copy. + */ +static void set_bom_revision(char *string) +{ + struct eeprom_hats_atom_header *atom4; + atom4 = (struct eeprom_hats_atom_header *) + hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff, + HATS_ATOM_CUSTOM); + + if (string[0] < 'A' || string[0] > 'Z') { + printf("BOM revision must be an uppercase letter between A and Z\n"); + return; + } + + *einfo.bom_revision = string[0]; + + update_crc(atom4); +} + +/** + * set_product_id() - stores a StarFive product ID into the local EEPROM copy + * + * Takes a pointer to a string representing the numeric product ID in + * string ("VF7100A1-2150-D008E000-00000001\0"), stores it in the product string + * field of the EEPROM local copy, and updates the CRC of the local copy. + */ +static void set_product_id(char *string) +{ + struct eeprom_hats_atom_header *atom1; + atom1 = (struct eeprom_hats_atom_header *) + hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff, + HATS_ATOM_VENDOR); + + memcpy((void *)einfo.pstr, (void *)string, + STARFIVE_EEPROM_ATOM1_PSTR_SIZE); + + update_crc(atom1); +} + +/** + * init_local_copy() - initialize the in-memory EEPROM copy + * + * Initialize the in-memory EEPROM copy with the magic number. Must + * be done when preparing to initialize a blank EEPROM, or overwrite + * one with a corrupted magic number. + */ +static void init_local_copy(uchar *buff) +{ + struct eeprom_hats_header *hats = (struct eeprom_hats_header *)buff; + struct eeprom_hats_atom_header *atom1 = (void *)hats + + sizeof(struct eeprom_hats_header); + struct eeprom_hats_atom_header *atom4_v1 = (void *)atom1 + + sizeof(struct starfive_eeprom_atom1); + + memcpy((void *)hats, (void *)&starfive_eeprom_hats_header_default, + sizeof(struct eeprom_hats_header)); + memcpy((void *)atom1, (void *)&starfive_eeprom_atom1_default, + sizeof(struct starfive_eeprom_atom1)); + memcpy((void *)atom4_v1, (void *)&starfive_eeprom_atom4_v1_default, + sizeof(struct starfive_eeprom_atom4_v1)); + + update_crc(atom1); + update_crc(atom4_v1); +} + +static int print_usage(void) +{ + printf("display and program the system ID and MAC addresses in EEPROM\n" + "[read_eeprom|initialize|write_eeprom|mac_address|pcb_revision|bom_revision|product_id]\n" + "mac read_eeprom\n" + " - read EEPROM content into memory data structure\n" + "mac write_eeprom\n" + " - save memory data structure to the EEPROM\n" + "mac initialize\n" + " - initialize the in-memory EEPROM copy with default data\n" + "mac mac0_address \n" + " - stores a MAC0 address into the local EEPROM copy\n" + "mac mac1_address \n" + " - stores a MAC1 address into the local EEPROM copy\n" + "mac pcb_revision \n" + " - stores a StarFive PCB revision into the local EEPROM copy\n" + "mac bom_revision \n" + " - stores a StarFive BOM revision into the local EEPROM copy\n" + "mac product_id \n" + " - stores a StarFive product ID into the local EEPROM copy\n"); + return 0; +} + +int do_mac(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + char *cmd; + + if (argc == 1) { + show_eeprom(&einfo); + return 0; + } + + if (argc > 3) + return print_usage(); + + cmd = argv[1]; + + /* Commands with no argument */ + if (!strcmp(cmd, "read_eeprom")) { + has_been_read = 0; + return read_eeprom(eeprom_wp_buff); + } else if (!strcmp(cmd, "initialize")) { + init_local_copy(eeprom_wp_buff); + return 0; + } else if (!strcmp(cmd, "write_eeprom")) { + return prog_eeprom(eeprom_wp_buff, + STARFIVE_EEPROM_HATS_SIZE_MAX); + } + + if (argc != 3) + return print_usage(); + + if (is_match_magic(eeprom_wp_buff)) { + printf("Please read the EEPROM ('read_eeprom') and/or initialize the EEPROM ('initialize') first.\n"); + return 0; + } + + if (!strcmp(cmd, "mac0_address")) { + set_mac_address(argv[2], 0); + return 0; + } else if (!strcmp(cmd, "mac1_address")) { + set_mac_address(argv[2], 1); + return 0; + } else if (!strcmp(cmd, "pcb_revision")) { + set_pcb_revision(argv[2]); + return 0; + } else if (!strcmp(cmd, "bom_revision")) { + set_bom_revision(argv[2]); + return 0; + } else if (!strcmp(cmd, "product_id")) { + set_product_id(argv[2]); + return 0; + } + + return print_usage(); +} + +/** + * mac_read_from_eeprom() - read the MAC address & the serial number in EEPROM + * + * This function reads the MAC address and the serial number from EEPROM and + * sets the appropriate environment variables for each one read. + * + * The environment variables are only set if they haven't been set already. + * This ensures that any user-saved variables are never overwritten. + * + * If CONFIG_ID_EEPROM is enabled, this function will be called in + * "static init_fnc_t init_sequence_r[]" of u-boot/common/board_r.c. + */ +int mac_read_from_eeprom(void) +{ + /** + * try to fill the buff from EEPROM, + * always return SUCCESS, even some error happens. + */ + if (read_eeprom(eeprom_wp_buff)) { + dump_raw_eeprom(eeprom_wp_buff, STARFIVE_EEPROM_HATS_SIZE_MAX); + return 0; + } + + // 1, setup ethaddr env + eth_env_set_enetaddr("eth0addr", einfo.mac0_addr); + eth_env_set_enetaddr("eth1addr", einfo.mac1_addr); + + /** + * 2, setup serial# env, reference to hifive-platform-i2c-eeprom.c, + * serial# can be a ASCII string, but not just a hex number, so we + * setup serial# in the 32Byte format: + * "VF7100A1-2201-D008E000-00000001;" + * "---" + * : 4Byte, should be the output of `date +%y%W` + * : 8Byte, "D008" means 8GB, "D01T" means 1TB; + * "E000" means no eMMC,"E032" means 32GB, "E01T" means 1TB. + * : 8Byte, the Unique Identifier of board in hex. + */ + if (!env_get("serial#")) + env_set("serial#", einfo.pstr); + + printf("StarFive EEPROM format v%u\n", *einfo.version); + show_eeprom(&einfo); + return 0; +} + +/** + * get_pcb_revision_from_eeprom - get the PCB revision + * + * Read the EEPROM to determine the board revision. + */ +u8 get_pcb_revision_from_eeprom(void) +{ + u8 pv = 0xFF; + + if (read_eeprom(eeprom_wp_buff)) + return pv; + + if (einfo.pcb_revision) { + pv = *einfo.pcb_revision; + } + return pv; +} + +/** + * get_data_from_eeprom + * + * Read data from eeprom, must use int mac_read_from_eeprom(void) first + * + * offset: offset of eeprom + * len: count of data + * data: return data + * + * return the len of valid data + */ +int get_data_from_eeprom(int offset, int len, unsigned char *data) +{ + int cp_len = -1; + + if (read_eeprom(eeprom_wp_buff)) + return cp_len; + + if (offset < STARFIVE_EEPROM_HATS_SIZE_MAX) { + cp_len = (offset + len > STARFIVE_EEPROM_HATS_SIZE_MAX) ? + (offset + len - STARFIVE_EEPROM_HATS_SIZE_MAX) : len; + memcpy(data, &eeprom_wp_buff[offset], cp_len); + } + + return cp_len; +} diff --git a/include/configs/starfive-visionfive.h b/include/configs/starfive-visionfive.h deleted file mode 100644 index 956c6a7d12..0000000000 --- a/include/configs/starfive-visionfive.h +++ /dev/null @@ -1,151 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2021-2023 StarFive Technology Co., Ltd. - * YanHong Wang - */ - - -#ifndef _STARFIVE_VISIONFIVE_H -#define _STARFIVE_VISIONFIVE_H - -#include -#include - -#ifdef CONFIG_SPL - -#define CONFIG_SPL_MAX_SIZE 0x00040000 -#define CONFIG_SPL_BSS_START_ADDR 0x08040000 -#define CONFIG_SPL_BSS_MAX_SIZE 0x00010000 -#define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SPL_BSS_START_ADDR + \ - CONFIG_SPL_BSS_MAX_SIZE) -#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00100000 - -#define CONFIG_SPL_STACK (0x08000000 + 0x00180000 - \ - GENERATED_GBL_DATA_SIZE) - -#define STARFIVE_SPL_BOOT_LOAD_ADDR 0xa0000000 -#endif - - -#define CONFIG_SYS_CACHELINE_SIZE 64 - -/* - * Miscellaneous configurable options - */ -#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */ -#define CONFIG_SYS_BOOTM_LEN (32 << 20) /* 32MB */ - -/* - * Print Buffer Size - */ -#define CONFIG_SYS_PBSIZE \ - (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) - -/* - * max number of command args - */ -#define CONFIG_SYS_MAXARGS 16 - -/* - * Boot Argument Buffer Size - */ -#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE - -/* - * Size of malloc() pool - * 512kB is suggested, (CONFIG_ENV_SIZE + 128 * 1024) was not enough - */ -#define CONFIG_SYS_MALLOC_LEN SZ_8M - -#define CONFIG_NR_DRAM_BANKS 1 - -#define PHYS_SDRAM_0 0x40000000 /* SDRAM Bank #1 */ -#define PHYS_SDRAM_0_SIZE 0x100000000 /* 8 GB */ - -#define CONFIG_SYS_SDRAM_BASE (PHYS_SDRAM_0) - - -/* Init Stack Pointer */ -#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M) - -#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_16M) -#define CONFIG_STANDALONE_LOAD_ADDR 0x41000000 - -/* - * Ethernet - */ -#ifdef CONFIG_CMD_NET -#define CONFIG_DW_ALTDESCRIPTOR -#define DWC_NET_PHYADDR 0 -#define CONFIG_ARP_TIMEOUT 500 -#define CONFIG_NETMASK 255.255.255.0 -#define CONFIG_IPADDR 192.168.120.230 -#define CONFIG_IP_DEFRAG -#ifndef CONFIG_NET_MAXDEFRAG -#define CONFIG_NET_MAXDEFRAG 16384 -#endif -#endif - -/* allow to overwrite serial and ethaddr */ -#define CONFIG_ENV_OVERWRITE - -/* HACK these should have '#if defined (stuff) around them like zynqp*/ -#define BOOT_TARGET_DEVICES(func) func(DHCP, dhcp, na) func(MMC, mmc, 0) - -#include - - -#include - -#define TYPE_GUID_LOADER1 "5B193300-FC78-40CD-8002-E86C45580B47" -#define TYPE_GUID_LOADER2 "2E54B353-1271-4842-806F-E436D6AF6985" -#define TYPE_GUID_SYSTEM "0FC63DAF-8483-4772-8E79-3D69D8477DE4" - -#define PARTS_DEFAULT \ - "name=loader1,start=17K,size=1M,type=${type_guid_gpt_loader1};" \ - "name=loader2,size=4MB,type=${type_guid_gpt_loader2};" \ - "name=system,size=-,bootable,type=${type_guid_gpt_system};" - -#define CONFIG_EXTRA_ENV_SETTINGS \ - "fdt_high=0xffffffffffffffff\0" \ - "initrd_high=0xffffffffffffffff\0" \ - "kernel_addr_r=0x44000000\0" \ - "fdt_addr_r=0x46000000\0" \ - "scriptaddr=0x88100000\0" \ - "script_offset_f=0x1fff000\0" \ - "script_size_f=0x1000\0" \ - "pxefile_addr_r=0x88200000\0" \ - "ramdisk_addr_r=0x88300000\0" \ - "type_guid_gpt_loader1=" TYPE_GUID_LOADER1 "\0" \ - "type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \ - "type_guid_gpt_system=" TYPE_GUID_SYSTEM "\0" \ - "partitions=" PARTS_DEFAULT "\0" \ - BOOTENV \ - BOOTENV_SF - -/* - * memtest works on 1.9 MB in DRAM - */ -#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM_0 -#define CONFIG_SYS_MEMTEST_END (PHYS_SDRAM_0 + PHYS_SDRAM_0_SIZE) - -#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600} -#define CONFIG_SYS_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ - -/* 6.25MHz RTC clock, StarFive JH7110*/ -#define CONFIG_SYS_HZ_CLOCK 4000000 - -#define __io - -#define memset_io(c, v, l) memset((c), (v), (l)) -#define memcpy_fromio(a, c, l) memcpy((a), (c), (l)) -#define memcpy_toio(c, a, l) memcpy((c), (a), (l)) - -#define CONFIG_VIDEO_BMP_LOGO -#define CONFIG_VIDEO_LOGO -#define CONFIG_BMP_16BPP -#define CONFIG_BMP_24BPP -#define CONFIG_BMP_32BPP - -#endif /* _STARFIVE_EVB_H */ - diff --git a/include/configs/starfive-visionfive2.h b/include/configs/starfive-visionfive2.h new file mode 100644 index 0000000000..37a51004ca --- /dev/null +++ b/include/configs/starfive-visionfive2.h @@ -0,0 +1,374 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Shanghai StarFive Technology Co., Ltd. + * YanHong Wang + */ + + +#ifndef _STARFIVE_VISIONFIVE2_H +#define _STARFIVE_VISIONFIVE2_H + +#include +#include + +#ifdef CONFIG_SPL + +#define CONFIG_SPL_MAX_SIZE 0x00040000 +#define CONFIG_SPL_BSS_START_ADDR 0x08040000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x00010000 +#define CONFIG_SYS_SPL_MALLOC_START 0x42000000 + +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00800000 + +#define CONFIG_SPL_STACK (0x08000000 + 0x00180000 - \ + GENERATED_GBL_DATA_SIZE) +#define STARFIVE_SPL_BOOT_LOAD_ADDR 0x60000000 +#endif + +#define CONFIG_SYS_BOOTM_LEN SZ_64M + + +#define CONFIG_SYS_CACHELINE_SIZE 64 + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */ + +/* + * Print Buffer Size + */ +#define CONFIG_SYS_PBSIZE \ + (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) + +/* + * max number of command args + */ +#define CONFIG_SYS_MAXARGS 16 + +/* + * Boot Argument Buffer Size + */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + +/* + * Size of malloc() pool + * 512kB is suggested, (CONFIG_ENV_SIZE + 128 * 1024) was not enough + */ +#define CONFIG_SYS_MALLOC_LEN SZ_8M + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 + +/* Init Stack Pointer */ +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_8M) + +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_16M) +#define CONFIG_STANDALONE_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_16M) + +#define CONFIG_SYS_PCI_64BIT /* enable 64-bit PCI resources */ + +/* + * Ethernet + */ +#ifdef CONFIG_CMD_NET +#define CONFIG_DW_ALTDESCRIPTOR +#define CONFIG_ARP_TIMEOUT 500 +#define CONFIG_NETMASK 255.255.255.0 +#define CONFIG_IPADDR 192.168.120.230 +#define CONFIG_IP_DEFRAG +#ifndef CONFIG_NET_MAXDEFRAG +#define CONFIG_NET_MAXDEFRAG 16384 +#endif +#endif + +/* HACK these should have '#if defined (stuff) around them like zynqp*/ +#define BOOT_TARGET_DEVICES(func) func(MMC, mmc, 0) func(DHCP, dhcp, na) + +#include + + +#include + +#define TYPE_GUID_LOADER1 "5B193300-FC78-40CD-8002-E86C45580B47" +#define TYPE_GUID_LOADER2 "2E54B353-1271-4842-806F-E436D6AF6985" +#define TYPE_GUID_SYSTEM "0FC63DAF-8483-4772-8E79-3D69D8477DE4" + +#define CPU_VOL_1020_SET \ + "cpu_vol_1020_set=" \ + "fdt set /opp-table-0/opp-1500000000 opp-microvolt <1020000>;\0" + +#define CPU_VOL_1040_SET \ + "cpu_vol_1040_set=" \ + "fdt set /opp-table-0/opp-1500000000 opp-microvolt <1040000>;\0" + +#define CPU_VOL_1060_SET \ + "cpu_vol_1060_set=" \ + "fdt set /opp-table-0/opp-1500000000 opp-microvolt <1060000>;\0" + +#define CPU_SPEED_1250_SET \ + "cpu_speed_1250_set=" \ + "fdt rm /opp-table-0/opp-375000000;" \ + "fdt rm /opp-table-0/opp-500000000;" \ + "fdt rm /opp-table-0/opp-750000000;" \ + "fdt rm /opp-table-0/opp-1500000000;\0" + +#define CPU_SPEED_1500_SET \ + "cpu_speed_1500_set=" \ + "fdt rm /opp-table-0/opp-312500000;" \ + "fdt rm /opp-table-0/opp-417000000;" \ + "fdt rm /opp-table-0/opp-625000000;" \ + "fdt rm /opp-table-0/opp-1250000000;\0" + +#define CPU_FREQ_VOL_SET \ + "cpu_vol_set=" \ + "if test ${cpu_max_vol} = 1000000; then " \ + "run cpu_speed_1250_set; " \ + "else " \ + "run cpu_speed_1500_set; " \ + "if test ${cpu_max_vol} = 1060000; then " \ + "run cpu_vol_1060_set; " \ + "elif test ${cpu_max_vol} = 1020000; then " \ + "run cpu_vol_1020_set; " \ + "else " \ + "run cpu_vol_1040_set; " \ + "fi; " \ + "fi; \0" + +#define CMA_SIZE_SET \ + "cma_start=70000000\0" \ + "cma_1g=b000000\0" \ + "cma_2g=20000000\0" \ + "cma_4g=40000000\0" \ + "cma_8g=60000000\0" \ + "cma_node=/reserved-memory/linux,cma\0" \ + "cma_ddr1g_set=" \ + "fdt set ${cma_node} size <0x0 0x${cma_1g}>;" \ + "fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_1g}>;\0" \ + "cma_ddr2g_set=" \ + "fdt set ${cma_node} size <0x0 0x${cma_2g}>;" \ + "fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_2g}>;\0" \ + "cma_ddr4g_set=" \ + "fdt set ${cma_node} size <0x0 0x${cma_4g}>;" \ + "fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_4g}>;\0" \ + "cma_ddr8g_set=" \ + "fdt set ${cma_node} size <0x0 0x${cma_8g}>;" \ + "fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_8g}>;\0" \ + "cma_resize=" \ + "if test ${memory_size} -eq 40000000; then " \ + "run cma_ddr1g_set;" \ + "elif test ${memory_size} -eq 80000000; then " \ + "run cma_ddr2g_set;" \ + "elif test ${memory_size} -eq 100000000; then " \ + "run cma_ddr4g_set;" \ + "elif test ${memory_size} -ge 200000000; then " \ + "run cma_ddr8g_set;" \ + "fi; \0 " + +#define PARTS_DEFAULT \ + "name=loader1,start=17K,size=1M,type=${type_guid_gpt_loader1};" \ + "name=loader2,size=4MB,type=${type_guid_gpt_loader2};" \ + "name=system,size=-,bootable,type=${type_guid_gpt_system};" + +#define CHIPA_GMAC_SET \ + "chipa_gmac_set=" \ + "fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_10 <0x0>;" \ + "fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_100 <0x0>;" \ + "fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_1000 <0x0>;" \ + "fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_delay_sel <0x9>;" \ + "fdt set /soc/ethernet@16040000/ethernet-phy@1 tx_inverted_10 <0x0>;" \ + "fdt set /soc/ethernet@16040000/ethernet-phy@1 tx_inverted_100 <0x0>;" \ + "fdt set /soc/ethernet@16040000/ethernet-phy@1 tx_inverted_1000 <0x0>;" \ + "fdt set /soc/ethernet@16040000/ethernet-phy@1 tx_delay_sel <0x9> \0" + +#define VISIONFIVE2_MEM_SET \ + "visionfive2_mem_set=" \ + "fdt memory ${memory_addr} ${memory_size};" \ + "run cma_resize; \0" + +#define CHIPA_SET \ + "chipa_set=" \ + "if test ${chip_vision} = A; then " \ + "run chipa_gmac_set;" \ + "fi; \0" \ + "chipa_set_uboot=" \ + "fdt addr ${uboot_fdt_addr};" \ + "run chipa_set;\0" \ + "chipa_set_linux=" \ + "fdt addr ${fdt_addr_r};" \ + "run visionfive2_mem_set;" \ + "run chipa_set;\0" + +#define VF2_SDK_BOOTENV \ + "bootenv=uEnv.txt\0" \ + "bootenv_sdk=vf2_uEnv.txt\0" \ + "boot_devs=mmc nvme\0" \ + "emmc_devnum=0\0" \ + "sd_devnum=1\0" \ + "mmc_devnum_l=1 0\0" \ + "nvme_devnum_l=0 0\0" + +#define JH7110_SDK_BOOTENV \ + "bootdir=/boot\0" \ + "bootpart=3\0" \ + "rootpart=4\0" \ + "load_sdk_uenv=" \ + "fatload ${bootdev} ${devnum}:${bootpart} ${loadaddr} ${bootenv_sdk};" \ + "env import -t ${loadaddr} ${filesize}; \0" \ + "mmc_test_and_boot=" \ + "if mmc dev ${devnum}; then " \ + "echo Try booting from MMC${devnum} ...; " \ + "setenv sdev_blk mmcblk${devnum}p${rootpart};" \ + "run load_sdk_uenv; run boot2;" \ + "fi;\0" \ + "bootenv_mmc=" \ + "setenv bootdev mmc;" \ + "if test ${bootmode} = flash; then " \ + "for mmc_devnum in ${mmc_devnum_l}; do " \ + "setenv devnum ${mmc_devnum}; " \ + "run mmc_test_and_boot;" \ + "done;" \ + "fi; " \ + "if test ${bootmode} = sd; then " \ + "setenv devnum ${sd_devnum};" \ + "run mmc_test_and_boot;" \ + "fi; " \ + "if test ${bootmode} = emmc; then " \ + "setenv devnum ${emmc_devnum};"\ + "run mmc_test_and_boot;" \ + "fi; \0" \ + "bootenv_nvme=" \ + "if test ${bootmode} = flash; then " \ + "for nvme_devnum in ${nvme_devnum_l}; do " \ + "setenv devnum ${nvme_devnum};" \ + "if pci enum; then " \ + "nvme scan; " \ + "fi; " \ + "if nvme dev ${devnum}; then " \ + "echo Try booting from NVME${devnum} ...; " \ + "setenv bootdev nvme;" \ + "setenv sdev_blk nvme${devnum}n1p${rootpart};" \ + "run load_sdk_uenv; run boot2;" \ + "fi; " \ + "done; " \ + "fi; \0" \ + "sdk_boot_env=" \ + "for bootdev_s in ${boot_devs}; do " \ + "run bootenv_${bootdev_s}; " \ + "done;\0" \ + "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" + +#define JH7110_DISTRO_BOOTENV \ + "bootdir=/boot\0" \ + "bootpart=3\0" \ + "rootpart=4\0" \ + "load_distro_uenv=" \ + "fatload ${bootdev} ${devnum}:${bootpart} ${loadaddr} /${bootenv}; " \ + "env import ${loadaddr} ${filesize}; \0" \ + "fdt_loaddtb=" \ + "fatload ${bootdev} ${devnum}:${bootpart} ${fdt_addr_r} /dtbs/${fdtfile}; fdt addr ${fdt_addr_r}; \0" \ + "fdt_sizecheck=" \ + "fatsize ${bootdev} ${devnum}:${bootpart} /dtbs/${fdtfile}; \0" \ + "set_fdt_distro=" \ + "run chipa_set_linux; run cpu_vol_set;" \ + "fatwrite ${bootdev} ${devnum}:${bootpart} ${fdt_addr_r} /dtbs/${fdtfile} ${filesize}; \0" \ + "bootcmd_distro=" \ + "run load_distro_uenv; " \ + "run fdt_loaddtb; run fdt_sizecheck; run set_fdt_distro; " \ + "sysboot ${bootdev} ${devnum}:${bootpart} fat ${scriptaddr} /${boot_syslinux_conf}; \0" \ + "distro_mmc_test_and_boot=" \ + "if mmc dev ${devnum}; then " \ + "echo Try booting from MMC${devnum} ...; " \ + "run bootcmd_distro;" \ + "fi;\0" \ + "distro_bootenv_mmc=" \ + "setenv bootdev mmc;" \ + "if test ${bootmode} = flash; then " \ + "for mmc_devnum in ${mmc_devnum_l}; do "\ + "setenv devnum ${mmc_devnum}; " \ + "run distro_mmc_test_and_boot;" \ + "done;" \ + "fi; " \ + "if test ${bootmode} = sd; then " \ + "setenv devnum ${sd_devnum};" \ + "run distro_mmc_test_and_boot;" \ + "fi; " \ + "if test ${bootmode} = emmc; then " \ + "setenv devnum ${emmc_devnum};"\ + "run distro_mmc_test_and_boot;" \ + "fi; \0" \ + "distro_bootenv_nvme=" \ + "if test ${bootmode} = flash; then " \ + "for nvme_devnum in ${nvme_devnum_l}; do " \ + "setenv devnum ${nvme_devnum};" \ + "if pci enum; then " \ + "nvme scan; " \ + "fi; " \ + "if nvme dev ${devnum}; then " \ + "echo Try booting from NVME${devnum} ...; " \ + "setenv bootdev nvme;" \ + "run bootcmd_distro; " \ + "fi; " \ + "done; " \ + "fi; \0" \ + "distro_boot_env=" \ + "echo Tring booting distro ...;" \ + "for bootdev_s in ${boot_devs}; do " \ + "run distro_bootenv_${bootdev_s}; " \ + "done; \0" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "fdt_high=0xffffffffffffffff\0" \ + "initrd_high=0xffffffffffffffff\0" \ + "kernel_addr_r=0x40200000\0" \ + "kernel_comp_addr_r=0x5a000000\0" \ + "kernel_comp_size=0x4000000\0" \ + "fdt_addr_r=0x46000000\0" \ + "scriptaddr=0x43900000\0" \ + "script_offset_f=0x1fff000\0" \ + "script_size_f=0x1000\0" \ + "pxefile_addr_r=0x45900000\0" \ + "ramdisk_addr_r=0x46100000\0" \ + "fdtoverlay_addr_r=0x4f000000\0" \ + "loadaddr=0x60000000\0" \ + VF2_SDK_BOOTENV \ + JH7110_SDK_BOOTENV \ + JH7110_DISTRO_BOOTENV \ + CHIPA_GMAC_SET \ + CHIPA_SET \ + CPU_VOL_1020_SET \ + CPU_VOL_1040_SET \ + CPU_VOL_1060_SET \ + CPU_SPEED_1250_SET \ + CPU_SPEED_1500_SET \ + CPU_FREQ_VOL_SET \ + CMA_SIZE_SET \ + VISIONFIVE2_MEM_SET \ + "type_guid_gpt_loader1=" TYPE_GUID_LOADER1 "\0" \ + "type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \ + "type_guid_gpt_system=" TYPE_GUID_SYSTEM "\0" \ + "partitions=" PARTS_DEFAULT "\0" \ + BOOTENV \ + BOOTENV_SF + +#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600} +#define CONFIG_SYS_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + +/* 6.25MHz RTC clock, StarFive JH7110*/ +#define CONFIG_SYS_HZ_CLOCK 4000000 + +#define __io + +#define memset_io(c, v, l) memset((c), (v), (l)) +#define memcpy_fromio(a, c, l) memcpy((a), (c), (l)) +#define memcpy_toio(c, a, l) memcpy((c), (a), (l)) + +#define CONFIG_VIDEO_BMP_LOGO +#define CONFIG_VIDEO_LOGO +#define CONFIG_BMP_16BPP +#define CONFIG_BMP_24BPP +#define CONFIG_BMP_32BPP + +#define CONFIG_ID_EEPROM + +#endif /* _STARFIVE_VISIONFIVE2_H */ + -- cgit v1.2.3 From d5c8e632a1416092f93cfc3989d9969166292398 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 9 Aug 2023 14:18:33 +0800 Subject: riscv: cpu: jh7110: Add EEPROM support Add a header to easily use the EEPROM interface. The code is ported from tag JH7110_VF2_515_v3.9.3 of VF2 repo. Signed-off-by: Hal Feng --- arch/riscv/include/asm/arch-jh7110/eeprom.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 arch/riscv/include/asm/arch-jh7110/eeprom.h diff --git a/arch/riscv/include/asm/arch-jh7110/eeprom.h b/arch/riscv/include/asm/arch-jh7110/eeprom.h new file mode 100644 index 0000000000..bae918f153 --- /dev/null +++ b/arch/riscv/include/asm/arch-jh7110/eeprom.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2021 StarFive Technology Co., Ltd. + * + * Author: Jianlong Huang + */ + +#ifndef _ASM_RISCV_EEPROM_H +#define _ASM_RISCV_EEPROM_H + +u8 get_pcb_revision_from_eeprom(void); +int get_data_from_eeprom(int offset, int len, unsigned char *data); + +#endif /* _ASM_RISCV_EEPROM_H */ -- cgit v1.2.3 From 4f914dd6f7fc3daf7821d3be07954e95f2b9d3f0 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 9 Aug 2023 15:34:36 +0800 Subject: board: starfive: Add TARGET_STARFIVE_VISIONFIVE2 to Kconfig Add board support for StarFive VisionFive 2. The code is ported from tag JH7110_VF2_515_v3.9.3 of VF2 repo. Signed-off-by: Hal Feng --- arch/riscv/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 2cff0d9536..25ed0ba1cf 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -23,8 +23,8 @@ config TARGET_SIFIVE_UNLEASHED config TARGET_SIFIVE_UNMATCHED bool "Support SiFive Unmatched Board" -config TARGET_STARFIVE_VISIONFIVE - bool "Support StarFive VisionFive Board" +config TARGET_STARFIVE_VISIONFIVE2 + bool "Support StarFive VisionFive2 Board" config TARGET_STARFIVE_EVB bool "Support StarFive Evb Board" @@ -71,7 +71,7 @@ source "board/sifive/unleashed/Kconfig" source "board/sifive/unmatched/Kconfig" source "board/openpiton/riscv64/Kconfig" source "board/sipeed/maix/Kconfig" -source "board/starfive/visionfive/Kconfig" +source "board/starfive/visionfive2/Kconfig" source "board/starfive/evb/Kconfig" # platform-specific options below -- cgit v1.2.3 From 4b07186e8ec0980867e1dc611574a8ca591b125c Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 9 Aug 2023 16:02:50 +0800 Subject: riscv: dts: jh7110: Add a new clock input to gmac To be compatible with the VisionFive 2 board. The code is ported from tag JH7110_VF2_515_v3.9.3 of VF2 repo. Signed-off-by: Hal Feng --- arch/riscv/dts/jh7110.dtsi | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/riscv/dts/jh7110.dtsi b/arch/riscv/dts/jh7110.dtsi index 3f3098b96b..de5289cff5 100644 --- a/arch/riscv/dts/jh7110.dtsi +++ b/arch/riscv/dts/jh7110.dtsi @@ -856,13 +856,15 @@ "ptp_ref", "stmmaceth", "pclk", - "gtxc"; + "gtxc", + "rmii_rtx"; clocks = <&clkgen JH7110_GMAC0_GTXCLK>, <&clkgen JH7110_U0_GMAC5_CLK_TX>, <&clkgen JH7110_GMAC0_PTP>, <&clkgen JH7110_U0_GMAC5_CLK_AHB>, <&clkgen JH7110_U0_GMAC5_CLK_AXI>, - <&clkgen JH7110_GMAC0_GTXC>; + <&clkgen JH7110_GMAC0_GTXC>, + <&clkgen JH7110_GMAC0_RMII_RTX>; resets = <&rstgen RSTN_U0_DW_GMAC5_AXI64_AHB>, <&rstgen RSTN_U0_DW_GMAC5_AXI64_AXI>; reset-names = "ahb", "stmmaceth"; @@ -897,13 +899,15 @@ "ptp_ref", "stmmaceth", "pclk", - "gtxc"; + "gtxc", + "rmii_rtx"; clocks = <&clkgen JH7110_GMAC1_GTXCLK>, <&clkgen JH7110_GMAC5_CLK_TX>, <&clkgen JH7110_GMAC5_CLK_PTP>, <&clkgen JH7110_GMAC5_CLK_AHB>, <&clkgen JH7110_GMAC5_CLK_AXI>, - <&clkgen JH7110_GMAC1_GTXC>; + <&clkgen JH7110_GMAC1_GTXC>, + <&clkgen JH7110_GMAC1_RMII_RTX>; resets = <&rstgen RSTN_U1_DW_GMAC5_AXI64_H_N>, <&rstgen RSTN_U1_DW_GMAC5_AXI64_A_I>; reset-names = "ahb", "stmmaceth"; -- cgit v1.2.3 From 580270489bf99365f96401f7babd8a087a3f2a59 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 9 Aug 2023 16:23:02 +0800 Subject: riscv: dts: Add StarFive VisionFive 2 board device tree Add device tree for StarFive VisionFive 2 board. The code is ported from tag JH7110_VF2_515_v3.9.3 of VF2 repo. Signed-off-by: Hal Feng --- arch/riscv/dts/Makefile | 2 +- arch/riscv/dts/starfive_visionfive-u-boot.dtsi | 38 -- arch/riscv/dts/starfive_visionfive.dts | 104 ------ arch/riscv/dts/starfive_visionfive2-u-boot.dtsi | 45 +++ arch/riscv/dts/starfive_visionfive2.dts | 477 ++++++++++++++++++++++++ 5 files changed, 523 insertions(+), 143 deletions(-) delete mode 100644 arch/riscv/dts/starfive_visionfive-u-boot.dtsi delete mode 100644 arch/riscv/dts/starfive_visionfive.dts create mode 100644 arch/riscv/dts/starfive_visionfive2-u-boot.dtsi create mode 100644 arch/riscv/dts/starfive_visionfive2.dts diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index d433afa6f4..e8bcd0e23d 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -7,7 +7,7 @@ dtb-$(CONFIG_TARGET_OPENPITON_RISCV64) += openpiton-riscv64.dtb dtb-$(CONFIG_TARGET_SIFIVE_UNLEASHED) += hifive-unleashed-a00.dtb dtb-$(CONFIG_TARGET_SIFIVE_UNMATCHED) += hifive-unmatched-a00.dtb dtb-$(CONFIG_TARGET_SIPEED_MAIX) += k210-maix-bit.dtb -dtb-$(CONFIG_TARGET_STARFIVE_VISIONFIVE) += starfive_visionfive.dtb +dtb-$(CONFIG_TARGET_STARFIVE_VISIONFIVE2) += starfive_visionfive2.dtb dtb-$(CONFIG_TARGET_STARFIVE_EVB) += starfive_evb.dtb targets += $(dtb-y) diff --git a/arch/riscv/dts/starfive_visionfive-u-boot.dtsi b/arch/riscv/dts/starfive_visionfive-u-boot.dtsi deleted file mode 100644 index a3efa43b5e..0000000000 --- a/arch/riscv/dts/starfive_visionfive-u-boot.dtsi +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 OR MIT -/* - * Copyright (C) 2022 StarFive Technology Co., Ltd. - */ - -#include "jh7110-u-boot.dtsi" -/ { - chosen { - stdout-path = "/soc/serial@10000000:115200"; - u-boot,dm-spl; - }; - - firmware { - spi0="/soc/qspi@11860000"; - u-boot,dm-spl; - }; - - config { - u-boot,dm-spl; - u-boot,spl-payload-offset = <0x100000>; /* loader2 @1044KB */ - }; - - memory@80000000 { - u-boot,dm-spl; - device_type = "memory"; - reg = <0x0 0x40000000 0x1 0x0>; - }; -}; - -&sdio0 { - clock-frequency = <4000000>; - max-frequency = <1000000>; -}; - -&sdio1 { - clock-frequency = <4000000>; - max-frequency = <1000000>; -}; \ No newline at end of file diff --git a/arch/riscv/dts/starfive_visionfive.dts b/arch/riscv/dts/starfive_visionfive.dts deleted file mode 100644 index 70eb2567b8..0000000000 --- a/arch/riscv/dts/starfive_visionfive.dts +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 OR MIT -/* - * Copyright (C) 2022 StarFive Technology Co., Ltd. - */ - -/dts-v1/; - -#include "jh7110.dtsi" -/ { - #address-cells = <2>; - #size-cells = <2>; - model = "StarFive VisionFive V2"; - compatible = "starfive,jh7110"; - - aliases { - spi0="/soc/spi@13010000"; - gpio0="/soc/gpio@13040000"; - ethernet0="/soc/ethernet@16030000"; - mmc0="/soc/sdio0@16010000"; - mmc1="/soc/sdio1@16020000"; - }; - - chosen { - stdout-path = "/soc/serial@10000000:115200"; - }; - - - memory@80000000 { - device_type = "memory"; - reg = <0x0 0x40000000 0x1 0x0>; - }; - - soc { - }; -}; - -&cpu0 { - status = "okay"; -}; - -&clkgen { - clocks = <&osc>, <&gmac1_rmii_refin>, - <&stg_apb>, <&gmac0_rmii_refin>; - clock-names = "osc", "gmac1_rmii_refin", - "stg_apb", "gmac0_rmii_refin"; -}; - -&sdio0 { - clock-frequency = <4000000>; - max-frequency = <1000000>; - bus-width = <8>; - status = "okay"; -}; - -&sdio1 { - clock-frequency = <4000000>; - max-frequency = <1000000>; - bus-width = <4>; - status = "okay"; -}; - -&gmac0 { - phy-reset-gpios = <&gpio 63 0>; - status = "okay"; -}; - -&gpio { - compatible = "starfive,jh7110-gpio"; - gpio-controller; -}; - -&uart0 { - reg-offset = <0>; - current-speed = <115200>; - status = "okay"; -}; - -&gpioa { - status = "disabled"; -}; - -&usbdrd30 { - status = "okay"; -}; - -&usbdrd_cdns3 { - dr_mode = "host"; -}; - -&timer { - status = "disabled"; -}; - -&wdog { - status = "disabled"; -}; - -&clkvout { - status = "disabled"; -}; - -&pdm { - status = "disabled"; -}; diff --git a/arch/riscv/dts/starfive_visionfive2-u-boot.dtsi b/arch/riscv/dts/starfive_visionfive2-u-boot.dtsi new file mode 100644 index 0000000000..7da12cf29f --- /dev/null +++ b/arch/riscv/dts/starfive_visionfive2-u-boot.dtsi @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2022 StarFive Technology Co., Ltd. + */ + +#include "jh7110-u-boot.dtsi" +/ { + chosen { + stdout-path = "/soc/serial@10000000:115200"; + u-boot,dm-spl; + }; + + firmware { + spi0="/soc/qspi@11860000"; + u-boot,dm-spl; + }; + + config { + u-boot,dm-spl; + u-boot,spl-payload-offset = <0x100000>; /* loader2 @1044KB */ + }; + + memory@80000000 { + u-boot,dm-spl; + device_type = "memory"; + reg = <0x0 0x40000000 0x1 0x0>; + }; +}; + +&i2c5 { + clock-frequency = <100000>; + i2c-sda-hold-time-ns = <300>; + i2c-sda-falling-time-ns = <3000>; + i2c-scl-falling-time-ns = <3000>; + auto_calc_scl_lhcnt; + status = "okay"; + u-boot,dm-spl; + + eeprom@50 { + compatible = "atmel,24c04"; + reg = <0x50>; + pagesize = <16>; + u-boot,dm-spl; + }; +}; diff --git a/arch/riscv/dts/starfive_visionfive2.dts b/arch/riscv/dts/starfive_visionfive2.dts new file mode 100644 index 0000000000..61fb42f987 --- /dev/null +++ b/arch/riscv/dts/starfive_visionfive2.dts @@ -0,0 +1,477 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2022 StarFive Technology Co., Ltd. + */ + +/dts-v1/; + +#include "jh7110.dtsi" +#include +#include +/ { + #address-cells = <2>; + #size-cells = <2>; + model = "StarFive VisionFive V2"; + compatible = "starfive,jh7110"; + + aliases { + spi0="/soc/spi@13010000"; + gpio0="/soc/gpio@13040000"; + ethernet0=&gmac0; + ethernet1=&gmac1; + mmc0=&sdio0; + mmc1=&sdio1; + i2c0 = &i2c5; + }; + + chosen { + stdout-path = "/soc/serial@10000000:115200"; + starfive,boot-hart-id = <1>; + }; + + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x40000000 0x1 0x0>; + }; + + reserved-memory { + #size-cells = <2>; + #address-cells = <2>; + ranges; + + opensbi { + reg = <0x00 0x40000000 0x00 0x80000>; + no-map; + }; + }; + + soc { + }; + + gpio-restart { + compatible = "gpio-restart"; + gpios = <&gpio 35 GPIO_ACTIVE_HIGH>; + }; +}; + +&cpu0 { + status = "okay"; +}; + +&clkgen { + clocks = <&osc>, <&gmac1_rmii_refin>, + <&stg_apb>, <&gmac0_rmii_refin>; + clock-names = "osc", "gmac1_rmii_refin", + "stg_apb", "gmac0_rmii_refin"; +}; + +&gpio { + status = "okay"; + gpio-controller; + uart0_pins: uart0-0 { + tx-pins { + pinmux = ; + bias-disable; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + + rx-pins { + pinmux = ; + bias-pull-up; + drive-strength = <2>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + }; + + mmc0_pins: mmc0-pins { + mmc0-pins-rest { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + sdcard1_pins: sdcard1-pins { + sdcard1-pins0 { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + + sdcard1-pins1 { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins2 { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins3 { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins4 { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins5 { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + }; + + pcie0_perst_default: pcie0_perst_default { + perst-pins { + pinmux = ; + drive-strength = <2>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie0_perst_active: pcie0_perst_active { + perst-pins { + pinmux = ; + drive-strength = <2>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie0_wake_default: pcie0_wake_default { + wake-pins { + pinmux = ; + drive-strength = <2>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie0_clkreq_default: pcie0_clkreq_default { + clkreq-pins { + pinmux = ; + drive-strength = <2>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie1_perst_default: pcie1_perst_default { + perst-pins { + pinmux = ; + drive-strength = <2>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie1_perst_active: pcie1_perst_active { + perst-pins { + pinmux = ; + drive-strength = <2>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie1_wake_default: pcie1_wake_default { + wake-pins { + pinmux = ; + drive-strength = <2>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie1_clkreq_default: pcie1_clkreq_default { + clkreq-pins { + pinmux = ; + drive-strength = <2>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + i2c2_pins: i2c2-0 { + i2c-pins { + pinmux = , + ; + bias-disable; /* external pull-up */ + input-enable; + input-schmitt-enable; + }; + }; + + i2c5_pins: i2c5-0 { + i2c-pins { + pinmux = , + ; + bias-disable; /* external pull-up */ + input-enable; + input-schmitt-enable; + }; + }; + + hdmi_pins: hdmi-0 { + + + cec-pins { + pinmux = ; + bias-pull-up; + input-enable; + }; + + hpd-pins { + pinmux = ; + input-enable; + }; + }; +}; + +&sdio0 { + assigned-clocks = <&clkgen JH7110_SDIO0_CLK_SDCARD>; + assigned-clock-rates = <50000000>; + fifo-depth = <32>; + bus-width = <8>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + status = "okay"; +}; + +&sdio1 { + assigned-clocks = <&clkgen JH7110_SDIO1_CLK_SDCARD>; + assigned-clock-rates = <50000000>; + fifo-depth = <32>; + bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&sdcard1_pins>; + status = "okay"; +}; + +&gmac0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@0 { + rgmii_sw_dr_2 = <0x0>; + rgmii_sw_dr = <0x3>; + rgmii_sw_dr_rxc = <0x6>; + rxc_dly_en = <0>; + rx_delay_sel = <0xa>; + tx_delay_sel_fe = <5>; + tx_delay_sel = <0xa>; + tx_inverted_10 = <0x1>; + tx_inverted_100 = <0x1>; + tx_inverted_1000 = <0x1>; + }; +}; + +&gmac1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + phy1: ethernet-phy@1 { + rgmii_sw_dr_2 = <0x0>; + rgmii_sw_dr = <0x3>; + rgmii_sw_dr_rxc = <0x6>; + tx_delay_sel_fe = <5>; + tx_delay_sel = <0>; + rxc_dly_en = <0>; + rx_delay_sel = <0x2>; + tx_inverted_10 = <0x1>; + tx_inverted_100 = <0x1>; + tx_inverted_1000 = <0x0>; + }; +}; + +&uart0 { + reg-offset = <0>; + current-speed = <115200>; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&i2c5 { + clock-frequency = <100000>; + i2c-sda-hold-time-ns = <300>; + i2c-sda-falling-time-ns = <3000>; + i2c-scl-falling-time-ns = <3000>; + auto_calc_scl_lhcnt; + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c04"; + reg = <0x50>; + pagesize = <16>; + }; + + pmic: axp15060_reg@36 { + compatible = "stf,axp15060-regulator"; + reg = <0x36>; + }; + +}; + +&gpioa { + status = "disabled"; +}; + +&usbdrd30 { + starfive,usb2-only = <1>; + status = "okay"; +}; + +&usbdrd_cdns3 { + dr_mode = "peripheral"; +}; + +&pcie0 { + pinctrl-names = "perst-default", "perst-active", "wake-default", "clkreq-default"; + pinctrl-0 = <&pcie0_perst_default>; + pinctrl-1 = <&pcie0_perst_active>; + pinctrl-2 = <&pcie0_wake_default>; + pinctrl-3 = <&pcie0_clkreq_default>; + status = "okay"; +}; + +&pcie1 { + pinctrl-names = "perst-default", "perst-active", "wake-default", "clkreq-default"; + pinctrl-0 = <&pcie1_perst_default>; + pinctrl-1 = <&pcie1_perst_active>; + pinctrl-2 = <&pcie1_wake_default>; + pinctrl-3 = <&pcie1_clkreq_default>; + status = "okay"; +}; + +&timer { + status = "disabled"; +}; + +&wdog { + status = "disabled"; +}; + +&clkvout { + status = "okay"; +}; + +&pdm { + status = "disabled"; +}; + +&mipi_dsi0 { + status = "okay"; + rockchip,panel = <&rm68200_panel>; + data-lanes-num = <1>; + display-timings { + timing0 { + bits-per-pixel = <24>; + clock-frequency = <160000000>; + hfront-porch = <120>; + hsync-len = <20>; + hback-porch = <21>; + hactive = <1200>; + vfront-porch = <21>; + vsync-len = <3>; + vback-porch = <18>; + vactive = <1920>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + +}; + +&hdmi{ + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_pins>; + status = "okay"; +}; + +&i2c2 { + clock-frequency = <100000>; + i2c-sda-hold-time-ns = <300>; + i2c-sda-falling-time-ns = <3000>; + i2c-scl-falling-time-ns = <3000>; + auto_calc_scl_lhcnt; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + status = "okay"; + + rm68200_panel: rm68200_panel@45 { + compatible = "raydium,rm68200"; + reg = <0x45>; + + }; + + +}; + -- cgit v1.2.3 From 3adcafc929ced658e704e5c215425e009c61e2bf Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 9 Aug 2023 16:28:35 +0800 Subject: configs: starfive: Add starfive_visionfive2_defconfig Add a defconfig file for StarFive VisionFive 2 board. The code is ported from tag JH7110_VF2_515_v3.9.3 of VF2 repo. Signed-off-by: Hal Feng --- configs/starfive_visionfive2_defconfig | 168 +++++++++++++++++++++++++++++++++ configs/starfive_visionfive_defconfig | 75 --------------- 2 files changed, 168 insertions(+), 75 deletions(-) create mode 100644 configs/starfive_visionfive2_defconfig delete mode 100644 configs/starfive_visionfive_defconfig diff --git a/configs/starfive_visionfive2_defconfig b/configs/starfive_visionfive2_defconfig new file mode 100644 index 0000000000..07bb1955d9 --- /dev/null +++ b/configs/starfive_visionfive2_defconfig @@ -0,0 +1,168 @@ +CONFIG_RISCV=y +CONFIG_SYS_MALLOC_F_LEN=0x10000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x10000 +CONFIG_ENV_OFFSET=0xF0000 +CONFIG_SPL_DM_SPI=y +CONFIG_DEFAULT_DEVICE_TREE="starfive_visionfive2" +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI_SUPPORT=y +CONFIG_BUILD_TARGET="" +CONFIG_TARGET_STARFIVE_VISIONFIVE2=y +CONFIG_SPL_OPENSBI_LOAD_ADDR=0x40000000 +CONFIG_NR_CPUS=5 +CONFIG_FPGA_GMAC_SPEED_AUTO=y +CONFIG_STARFIVE_JH7110_L2CC_FLUSH=y +CONFIG_ARCH_RV64I=y +CONFIG_CMODEL_MEDANY=y +CONFIG_RISCV_SMODE=y +CONFIG_SHOW_REGS=y +# CONFIG_ANDROID_BOOT_IMAGE is not set +CONFIG_FIT=y +CONFIG_SPL_FIT_SOURCE="jh7110-uboot-fit-image.its" +CONFIG_SUPPORT_RAW_INITRD=y +CONFIG_QSPI_BOOT=y +CONFIG_SD_BOOT=y +CONFIG_SPI_BOOT=y +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="console=tty1 console=ttyS0,115200 debug rootwait earlycon=sbi" +CONFIG_USE_BOOTCOMMAND=y +CONFIG_BOOTCOMMAND="run sdk_boot_env; run distro_boot_env" +CONFIG_USE_PREBOOT=y +CONFIG_PREBOOT="run chipa_set_uboot;" +CONFIG_DEFAULT_FDT_FILE="starfive/jh7110-visionfive-v2.dtb" +CONFIG_LOG_MAX_LEVEL=4 +CONFIG_SPL_LOG=y +CONFIG_DISPLAY_CPUINFO=y +CONFIG_DISPLAY_BOARDINFO=y +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_BOARD_LATE_INIT=y +CONFIG_MISC_INIT_R=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x2 +CONFIG_SPL_I2C=y +CONFIG_SPL_DM_SPI_FLASH=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="StarFive # " +CONFIG_CMD_CONFIG=y +CONFIG_CMD_SBI=y +CONFIG_CMD_ERASEENV=y +CONFIG_CMD_NVEDIT_EFI=y +CONFIG_CMD_EEPROM=y +CONFIG_SYS_EEPROM_SIZE=512 +CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=4 +CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=5 +CONFIG_CMD_GPT_RENAME=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MISC=y +CONFIG_CMD_PART=y +CONFIG_CMD_PCI=y +CONFIG_CMD_USB=y +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_EFIDEBUG=y +CONFIG_CMD_SYSBOOT=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FS_UUID=y +CONFIG_CMD_LOG=y +CONFIG_OF_EMBED=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_VERSION_VARIABLE=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_CLK_COMPOSITE_CCF=y +CONFIG_CLK_CCF=y +CONFIG_CLK_COMPOSITE_CCF=y +CONFIG_SPL_CLK_JH7110=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x60000000 +CONFIG_FASTBOOT_BUF_SIZE=0x80000000 +CONFIG_FASTBOOT_USB_DEV=1 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_UUU_SUPPORT=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_MMC_BOOT_SUPPORT=y +CONFIG_FASTBOOT_MMC_USER_SUPPORT=y +CONFIG_FASTBOOT_CMD_OEM_FORMAT=y +CONFIG_FASTBOOT_STARFIVE_MAX_BLK_WRITE=8192 +CONFIG_SYS_I2C_DW=y +CONFIG_SPL_SYS_I2C_DW=y +CONFIG_I2C_EEPROM=y +CONFIG_SPL_I2C_EEPROM=y +CONFIG_SYS_I2C_EEPROM_ADDR=0x50 +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_SPL_MMC_HS200_SUPPORT=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_SNPS=y +CONFIG_SF_DEFAULT_MODE=0x0 +CONFIG_SF_DEFAULT_SPEED=100000000 +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_PHY_MARVELL=y +CONFIG_PHY_MICREL=y +CONFIG_PHY_MICREL_KSZ90X1=y +# CONFIG_PHY_MSCC is not set +CONFIG_PHY_YUTAI=y +CONFIG_DM_ETH_PHY=y +CONFIG_DWC_ETH_QOS=y +CONFIG_DWC_ETH_QOS_STARFIVE=y +CONFIG_RGMII=y +CONFIG_RTL8169=y +CONFIG_NVME=y +CONFIG_PCI=y +CONFIG_DM_PCI_COMPAT=y +CONFIG_PCI_REGION_MULTI_ENTRY=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_STARFIVE=y +CONFIG_PINCTRL_STARFIVE_JH7110=y +CONFIG_POWER_DOMAIN=y +CONFIG_STARFIVE_POWER_DOMAIN=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_STARFIVE=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_STARFIVE=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +# CONFIG_RAM_SIFIVE is not set +CONFIG_SPL_STARFIVE_DDR=y +CONFIG_DM_RESET=y +CONFIG_SPECIFY_CONSOLE_INDEX=y +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_SBI=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +# CONFIG_USB_CDNS3_TI is not set +CONFIG_USB_CDNS3_STARFIVE=y +CONFIG_USB_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VENDOR_NUM=0x18d1 +CONFIG_USB_GADGET_PRODUCT_NUM=0x0d02 +CONFIG_DM_VIDEO=y +CONFIG_VIDEO_PCI_DEFAULT_FB_SIZE=0x8000000 +CONFIG_VIDEO_COPY=y +CONFIG_VIDEO_LCD_STARFIVE_SEEED=y +CONFIG_DISPLAY=y +CONFIG_NXP_TDA19988=y +CONFIG_VIDEO_BRIDGE=y +CONFIG_VIDEO_STARFIVE=y +CONFIG_DISPLAY_STARFIVE_EDP=y +CONFIG_DISPLAY_STARFIVE_LVDS=y +CONFIG_DISPLAY_STARFIVE_HDMI=y +CONFIG_DISPLAY_STARFIVE_MIPI=y +CONFIG_VIDEO_NW_MIPI_DSI=y +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/starfive_visionfive_defconfig b/configs/starfive_visionfive_defconfig deleted file mode 100644 index 94a190cbb5..0000000000 --- a/configs/starfive_visionfive_defconfig +++ /dev/null @@ -1,75 +0,0 @@ -CONFIG_RISCV=y -CONFIG_SYS_MALLOC_F_LEN=0x8000 -CONFIG_NR_DRAM_BANKS=1 -CONFIG_SPL_DM_SPI=y -CONFIG_DEFAULT_DEVICE_TREE="starfive_visionfive" -CONFIG_SPL_MMC_SUPPORT=y -CONFIG_SPL=y -CONFIG_SPL_SPI_FLASH_SUPPORT=y -CONFIG_SPL_SPI_SUPPORT=y -CONFIG_BUILD_TARGET="" -CONFIG_TARGET_STARFIVE_VISIONFIVE=y -CONFIG_NR_CPUS=5 -CONFIG_ARCH_RV64I=y -CONFIG_CMODEL_MEDANY=y -CONFIG_RISCV_SMODE=y -CONFIG_SHOW_REGS=y -CONFIG_FIT=y -CONFIG_SPL_FIT_SOURCE="jh7110-uboot-fit-image.its" -CONFIG_SUPPORT_RAW_INITRD=y -CONFIG_QSPI_BOOT=y -CONFIG_SD_BOOT=y -CONFIG_SPI_BOOT=y -CONFIG_USE_BOOTARGS=y -CONFIG_BOOTARGS="console=tty1 console=ttyS0,115200 debug rootwait earlycon=sbi" -CONFIG_USE_BOOTCOMMAND=y -CONFIG_LOG_MAX_LEVEL=4 -CONFIG_SPL_LOG=y -CONFIG_DISPLAY_CPUINFO=y -CONFIG_DISPLAY_BOARDINFO=y -CONFIG_DISPLAY_BOARDINFO_LATE=y -CONFIG_MISC_INIT_R=y -CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y -CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1800 -CONFIG_SPL_DM_SPI_FLASH=y -CONFIG_SPL_SPI_LOAD=y -CONFIG_HUSH_PARSER=y -CONFIG_SYS_PROMPT="StarFive # " -CONFIG_CMD_CONFIG=y -CONFIG_CMD_GPT_RENAME=y -CONFIG_CMD_MISC=y -CONFIG_CMD_PART=y -CONFIG_CMD_USB=y -CONFIG_CMD_TFTPPUT=y -CONFIG_CMD_SYSBOOT=y -CONFIG_CMD_EXT4_WRITE=y -CONFIG_CMD_FS_UUID=y -CONFIG_CMD_LOG=y -CONFIG_OF_EMBED=y -CONFIG_VERSION_VARIABLE=y -CONFIG_NET_RANDOM_ETHADDR=y -CONFIG_SPL_CLK_COMPOSITE_CCF=y -CONFIG_CLK_CCF=y -CONFIG_CLK_COMPOSITE_CCF=y -CONFIG_SPL_CLK_JH7110=y -CONFIG_MMC_DW=y -CONFIG_MMC_DW_SNPS=y -CONFIG_SF_DEFAULT_MODE=0x0 -CONFIG_SF_DEFAULT_SPEED=50000000 -CONFIG_SPI_FLASH_GIGADEVICE=y -CONFIG_SPI_FLASH_SPANSION=y -CONFIG_PHY_MARVELL=y -CONFIG_DWC_ETH_QOS=y -CONFIG_DWC_ETH_QOS_STARFIVE=y -CONFIG_RGMII=y -CONFIG_DM_RESET=y -CONFIG_SPECIFY_CONSOLE_INDEX=y -CONFIG_SYS_NS16550=y -CONFIG_SPI=y -CONFIG_CADENCE_QSPI=y -CONFIG_USB=y -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_CDNS3=y -CONFIG_USB_CDNS3_HOST=y -CONFIG_USB_STORAGE=y -CONFIG_OF_LIBFDT_OVERLAY=y -- cgit v1.2.3 From f1428044084cf04e545cd4f5d67ad68adf3f7873 Mon Sep 17 00:00:00 2001 From: Sunil V L Date: Fri, 28 Jan 2022 20:48:44 +0530 Subject: efi_loader: Enable RISCV_EFI_BOOT_PROTOCOL support This adds support for new RISCV_EFI_BOOT_PROTOCOL to communicate the boot hart ID to bootloader/kernel on RISC-V UEFI platforms. The specification of the protocol is hosted at: https://github.com/riscv-non-isa/riscv-uefi Signed-off-by: Sunil V L Reviewed-by: Heinrich Schuchardt --- include/efi_api.h | 25 +++++++++++++++++++ include/efi_loader.h | 4 ++++ include/efi_riscv.h | 24 +++++++++++++++++++ lib/efi_loader/Kconfig | 10 ++++++++ lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_riscv.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++ lib/efi_loader/efi_setup.c | 6 +++++ 7 files changed, 130 insertions(+) create mode 100644 include/efi_riscv.h create mode 100644 lib/efi_loader/efi_riscv.c diff --git a/include/efi_api.h b/include/efi_api.h index c8f959bb72..4b9b8112e1 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -417,6 +417,31 @@ struct efi_runtime_services { EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, \ 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25) +#define EFI_RNG_PROTOCOL_GUID \ + EFI_GUID(0x3152bca5, 0xeade, 0x433d, 0x86, 0x2e, \ + 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44) + +#define EFI_DT_FIXUP_PROTOCOL_GUID \ + EFI_GUID(0xe617d64c, 0xfe08, 0x46da, 0xf4, 0xdc, \ + 0xbb, 0xd5, 0x87, 0x0c, 0x73, 0x00) + +#define EFI_TCG2_PROTOCOL_GUID \ + EFI_GUID(0x607f766c, 0x7455, 0x42be, 0x93, \ + 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f) + +#define RISCV_EFI_BOOT_PROTOCOL_GUID \ + EFI_GUID(0xccd15fec, 0x6f73, 0x4eec, 0x83, \ + 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf) + +/** + * struct efi_configuration_table - EFI Configuration Table + * + * This table contains a set of GUID/pointer pairs. + * The EFI Configuration Table may contain at most one instance of each table type. + * + * @guid: GUID that uniquely identifies the system configuration table + * @table: A pointer to the table associated with guid + */ struct efi_configuration_table { efi_guid_t guid; void *table; diff --git a/include/efi_loader.h b/include/efi_loader.h index c440962fe5..432a57e7ea 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -523,6 +523,10 @@ efi_status_t efi_disk_register(void); efi_status_t efi_rng_register(void); /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */ efi_status_t efi_tcg2_register(void); +/* Called by efi_init_obj_list() to install RISCV_EFI_BOOT_PROTOCOL */ +efi_status_t efi_riscv_register(void); +/* Called by efi_init_obj_list() to do initial measurement */ +efi_status_t efi_tcg2_do_initial_measurement(void); /* measure the pe-coff image, extend PCR and add Event Log */ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size, struct efi_loaded_image_obj *handle, diff --git a/include/efi_riscv.h b/include/efi_riscv.h new file mode 100644 index 0000000000..4bd39c4366 --- /dev/null +++ b/include/efi_riscv.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * RISCV_EFI_BOOT_PROTOCOL + * + * Copyright (c) 2022 Ventana Micro Systems Inc + */ + +#include + +#define RISCV_EFI_BOOT_PROTOCOL_REVISION 0x00010000 + +/** + * struct riscv_efi_boot_protocol - RISCV_EFI_BOOT_PROTOCOL + * @revision: Version of the protocol implemented + * @get_boot_hartid: Get the boot hart ID + */ +struct riscv_efi_boot_protocol { + u64 revision; + + efi_status_t (EFIAPI * get_boot_hartid) (struct riscv_efi_boot_protocol *this, + efi_uintn_t *boot_hartid); +}; + +extern struct riscv_efi_boot_protocol riscv_efi_boot_prot; diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index f48d9e8b51..3e910921d0 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -374,4 +374,14 @@ config EFI_ESRT help Enabling this option creates the ESRT UEFI system table. +config EFI_RISCV_BOOT_PROTOCOL + bool "RISCV_EFI_BOOT_PROTOCOL support" + default y + depends on RISCV + help + The EFI_RISCV_BOOT_PROTOCOL is used to transfer the boot hart ID + to the next boot stage. It should be enabled as it is meant to + replace the transfer via the device-tree. The latter is not + possible on systems using ACPI. + endif diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index fd344cea29..b2c664d108 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_GENERATE_ACPI_TABLE) += efi_acpi.o obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_rng.o obj-$(CONFIG_EFI_TCG2_PROTOCOL) += efi_tcg2.o +obj-$(CONFIG_EFI_RISCV_BOOT_PROTOCOL) += efi_riscv.o obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o obj-$(CONFIG_EFI_SIGNATURE_SUPPORT) += efi_signature.o diff --git a/lib/efi_loader/efi_riscv.c b/lib/efi_loader/efi_riscv.c new file mode 100644 index 0000000000..bccfefd8fb --- /dev/null +++ b/lib/efi_loader/efi_riscv.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Defines APIs that allow an OS to interact with UEFI firmware to query + * information about the boot hart ID. + * + * Copyright (c) 2022, Ventana Micro Systems Inc + */ + +#define LOG_CATEGORY LOGC_EFI +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static const efi_guid_t efi_guid_riscv_boot_protocol = RISCV_EFI_BOOT_PROTOCOL_GUID; + +/** + * efi_riscv_get_boot_hartid() - return boot hart ID + * @this: RISCV_EFI_BOOT_PROTOCOL instance + * @boot_hartid: caller allocated memory to return boot hart id + * Return: status code + */ +static efi_status_t EFIAPI +efi_riscv_get_boot_hartid(struct riscv_efi_boot_protocol *this, + efi_uintn_t *boot_hartid) +{ + EFI_ENTRY("%p, %p", this, boot_hartid); + + if (this != &riscv_efi_boot_prot || !boot_hartid) + return EFI_INVALID_PARAMETER; + + *boot_hartid = gd->arch.boot_hart; + + return EFI_EXIT(EFI_SUCCESS); +} + +struct riscv_efi_boot_protocol riscv_efi_boot_prot = { + .revision = RISCV_EFI_BOOT_PROTOCOL_REVISION, + .get_boot_hartid = efi_riscv_get_boot_hartid +}; + +/** + * efi_riscv_register() - register RISCV_EFI_BOOT_PROTOCOL + * + * Return: status code + */ +efi_status_t efi_riscv_register(void) +{ + efi_status_t ret = EFI_SUCCESS; + + ret = efi_add_protocol(efi_root, &efi_guid_riscv_boot_protocol, + (void *)&riscv_efi_boot_prot); + if (ret != EFI_SUCCESS) + log_err("Cannot install RISCV_EFI_BOOT_PROTOCOL\n"); + return ret; +} diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index a2338d74af..7c6f032651 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -273,6 +273,12 @@ efi_status_t efi_init_obj_list(void) goto out; } + if (IS_ENABLED(CONFIG_EFI_RISCV_BOOT_PROTOCOL)) { + ret = efi_riscv_register(); + if (ret != EFI_SUCCESS) + goto out; + } + /* Secure boot */ ret = efi_init_secure_boot(); if (ret != EFI_SUCCESS) -- cgit v1.2.3 From b2edbe9c9edf1fd7be1a399e15128874dd7db341 Mon Sep 17 00:00:00 2001 From: Yanhong Wang Date: Thu, 13 Oct 2022 09:00:01 +0800 Subject: i2c: designware: support SYS_I2C_DW in SPL Add SYS_I2C_DW driver to support in SPL. Signed-off-by: Yanhong Wang --- drivers/i2c/Kconfig | 7 +++++++ drivers/i2c/Makefile | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 63d03a3ceb..a19370c8a1 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -158,6 +158,13 @@ config SYS_I2C_DW controller is used in various SoCs, e.g. the ST SPEAr, Altera SoCFPGA, Synopsys ARC700 and some Intel x86 SoCs. +config SPL_SYS_I2C_DW + bool "Designware I2C Controller in SPL" + default n + help + Say yes here to select the Designware I2C Host Controller in SPL. This + controller is used in StarFive JH7110 SoC. + config SYS_I2C_ASPEED bool "Aspeed I2C Controller" depends on DM_I2C && ARCH_ASPEED diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 69bd27c7cd..d25ddbe05d 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -17,7 +17,7 @@ obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o obj-$(CONFIG_SYS_I2C_CA) += i2c-cortina.o obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o -obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o +obj-$(CONFIG_$(SPL_)SYS_I2C_DW) += designware_i2c.o ifdef CONFIG_ACPIGEN ifdef CONFIG_PCI obj-$(CONFIG_SYS_I2C_DW) += designware_i2c_pci.o -- cgit v1.2.3 From 295685561ef1aacb6359a3e658640154e6a40a34 Mon Sep 17 00:00:00 2001 From: "Jianlong.Huang" Date: Wed, 27 Oct 2021 09:17:57 +0800 Subject: cmd/eeprom: fix data type issue for parse_numeric_param This patch fixs parse_numeric_param issue on some platfrom which has different sizes of int and long, like riscv64. On riscv64, int is 4 bytes, but long is 8 bytes. on this situation: ulong addr = parse_numeric_param(argv[index]); if argv[index] is "0x80000000", this "ulong addr" will be 0xffffffff80000000. Signed-off-by: Jianlong.Huang Co-developed-by: Wei Fu Signed-off-by: Wei Fu --- cmd/eeprom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/eeprom.c b/cmd/eeprom.c index efd6f3ac03..d316392f87 100644 --- a/cmd/eeprom.c +++ b/cmd/eeprom.c @@ -218,10 +218,10 @@ int eeprom_write(unsigned dev_addr, unsigned offset, return ret; } -static int parse_numeric_param(char *str) +static long parse_numeric_param(char *str) { char *endptr; - int value = simple_strtol(str, &endptr, 16); + long value = simple_strtol(str, &endptr, 16); return (*endptr != '\0') ? -1 : value; } -- cgit v1.2.3 From 77a08d507b6c1efe75b46312394e2f4dd24cc31c Mon Sep 17 00:00:00 2001 From: Jianlong Huang Date: Tue, 19 Jul 2022 14:14:00 +0800 Subject: cmd: eeprom: Add StarFive VisionFive 2 board support Rename CONFIG_SYS_DEF_EEPROM_ADDR to CONFIG_SYS_I2C_EEPROM_ADDR based on current usage. Convert CONFIG_SYS_I2C_EEPROM_BUS, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, CONFIG_SYS_EEPROM_SIZE, CONFIG_SYS_EEPROM_PAGE_WRITE_BITS and CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS to Kconfig. Signed-off-by: Jianlong Huang Signed-off-by: Hal Feng --- cmd/Kconfig | 31 +++++++++++++++++++++++++++++++ cmd/eeprom.c | 39 ++++++++++++--------------------------- cmd/i2c.c | 2 +- 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 3a857b3f6e..b2ea74de8e 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -614,6 +614,37 @@ config EEPROM_LAYOUT_HELP_STRING Help printed with the LAYOUT VERSIONS part of the 'eeprom' command's help. +config SYS_I2C_EEPROM_BUS + int "I2C bus of the EEPROM device." + depends on CMD_EEPROM + default 0 + +config SYS_I2C_EEPROM_ADDR_LEN + int "Length in bytes of the EEPROM memory array address" + depends on CMD_EEPROM || ID_EEPROM + default 1 + range 1 2 + help + Note: This is NOT the chip address length! + +config SYS_EEPROM_SIZE + depends on CMD_EEPROM + int "Size in bytes of the EEPROM device" + default 256 + +config SYS_EEPROM_PAGE_WRITE_BITS + int "Number of bits used to address bytes in a single page" + depends on CMD_EEPROM + default 8 + help + The EEPROM page size is 2^SYS_EEPROM_PAGE_WRITE_BITS. + A 64 byte page, for example would require six bits. + +config SYS_EEPROM_PAGE_WRITE_DELAY_MS + int "Number of milliseconds to delay between page writes" + depends on CMD_EEPROM || CMD_I2C + default 0 + config LOOPW bool "loopw" help diff --git a/cmd/eeprom.c b/cmd/eeprom.c index d316392f87..60b30a6946 100644 --- a/cmd/eeprom.c +++ b/cmd/eeprom.c @@ -15,7 +15,7 @@ * degradation (typical for EEPROM) is incured for FRAM memory: * * #define CONFIG_SYS_I2C_FRAM - * #undef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS + * Set CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS to 0 * */ @@ -31,14 +31,6 @@ #define CONFIG_SYS_I2C_SPEED 50000 #endif -#ifndef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS -#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 0 -#endif - -#ifndef CONFIG_SYS_EEPROM_PAGE_WRITE_BITS -#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 8 -#endif - #ifndef I2C_RXTX_LEN #define I2C_RXTX_LEN 128 #endif @@ -46,21 +38,6 @@ #define EEPROM_PAGE_SIZE (1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS) #define EEPROM_PAGE_OFFSET(x) ((x) & (EEPROM_PAGE_SIZE - 1)) -/* - * for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 2 (16-bit EEPROM address) offset is - * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM. - * - * for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 (8-bit EEPROM page address) offset is - * 0x00000nxx for EEPROM address selectors and page number at n. - */ -#if !defined(CONFIG_SPI) || defined(CONFIG_ENV_EEPROM_IS_ON_I2C) -#if !defined(CONFIG_SYS_I2C_EEPROM_ADDR_LEN) || \ - (CONFIG_SYS_I2C_EEPROM_ADDR_LEN < 1) || \ - (CONFIG_SYS_I2C_EEPROM_ADDR_LEN > 2) -#error CONFIG_SYS_I2C_EEPROM_ADDR_LEN must be 1 or 2 -#endif -#endif - #if CONFIG_IS_ENABLED(DM_I2C) static int eeprom_i2c_bus; #endif @@ -82,6 +59,13 @@ void eeprom_init(int bus) #endif } +/* + * for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 2 (16-bit EEPROM address) offset is + * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM. + * + * for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 (8-bit EEPROM page address) offset is + * 0x00000nxx for EEPROM address selectors and page number at n. + */ static int eeprom_addr(unsigned dev_addr, unsigned offset, uchar *addr) { unsigned blk_off; @@ -183,10 +167,11 @@ static int eeprom_rw(unsigned dev_addr, unsigned offset, uchar *buffer, buffer += len; offset += len; +#if CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS > 0 if (!read) udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); } - +#endif return rcode; } @@ -243,10 +228,10 @@ static int parse_i2c_bus_addr(int *i2c_bus, ulong *i2c_addr, int argc, int argc_no_bus = argc_no_bus_addr + 1; int argc_bus_addr = argc_no_bus_addr + 2; -#ifdef CONFIG_SYS_DEF_EEPROM_ADDR +#ifdef CONFIG_SYS_I2C_EEPROM_ADDR if (argc == argc_no_bus_addr) { *i2c_bus = -1; - *i2c_addr = CONFIG_SYS_DEF_EEPROM_ADDR; + *i2c_addr = CONFIG_SYS_I2C_EEPROM_ADDR; return 0; } diff --git a/cmd/i2c.c b/cmd/i2c.c index c7c08c4e32..cbc8bd008b 100644 --- a/cmd/i2c.c +++ b/cmd/i2c.c @@ -922,7 +922,7 @@ static int mod_i2c_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, if (ret) return i2c_report_err(ret, I2C_ERR_WRITE); -#ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS +#if CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS > 0 udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); #endif if (incrflag) -- cgit v1.2.3 From 7a6dd69c9d1591c564ec7f516989aad3a9c3d7ce Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Thu, 17 Aug 2023 10:17:28 +0800 Subject: mmc: dw_mmc: Add StarFive VisionFive 2 board support Make the code be compatible with the StarFive VisionFive 2 board. The code is ported from tag JH7110_VF2_515_v3.9.3 of VF2 repo. Signed-off-by: William Qiu Signed-off-by: Hal Feng --- drivers/mmc/dw_mmc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index b3b69fabd4..c3236967f7 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -685,7 +685,11 @@ void dwmci_setup_cfg(struct mmc_config *cfg, struct dwmci_host *host, cfg->host_caps |= MMC_MODE_4BIT; cfg->host_caps &= ~MMC_MODE_8BIT; } +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) + cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_HS200; +#else cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS200; +#endif cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; } -- cgit v1.2.3 From 3dec8563acd3be6580467ab856c21907b8865e1f Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Thu, 17 Aug 2023 11:08:07 +0800 Subject: net: dwc_eth_qos: Add StarFive VisionFive 2 board support Make the code be compatible with the StarFive VisionFive 2 board. The code is ported from tag JH7110_VF2_515_v3.9.3 of VF2 repo. Signed-off-by: Samin Guo Signed-off-by: Hal Feng --- drivers/net/dwc_eth_qos.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 84ad47d5bc..2910affc0c 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -321,6 +321,7 @@ struct eqos_priv { bool clk_ck_enabled; struct reset_ctl_bulk reset_bulk; struct clk_bulk clk_bulk; + struct clk rmii_rtx; }; /* @@ -1006,6 +1007,10 @@ static int eqos_set_tx_clk_speed_jh7110(struct udevice *dev) return ret; } +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) + clk_set_rate(&eqos->rmii_rtx, rate); +#endif + return 0; } @@ -1909,6 +1914,14 @@ static int eqos_probe_resources_jh7110(struct udevice *dev) goto err_free_reset_eqos; } +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) + ret = clk_get_by_name(dev, "rmii_rtx", &eqos->rmii_rtx); + if (ret) { + pr_err("clk_get_by_name(rmii_rtx) failed: %d", ret); + goto err_free_reset_eqos; + } +#endif + ret = clk_get_bulk(dev, &eqos->clk_bulk); if (ret) { pr_err("clk_get_bulk failed: %d", ret); -- cgit v1.2.3 From 2f2f662785269d4402bfd57145515e8d73ef3068 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Thu, 17 Aug 2023 11:51:57 +0800 Subject: pci: starfive: Add StarFive VisionFive 2 board support Make the code be compatible with the StarFive VisionFive 2 board. The code is ported from tag JH7110_VF2_515_v3.9.3 of VF2 repo. Signed-off-by: Mason Huo Signed-off-by: Minda Chen Signed-off-by: Hal Feng --- drivers/pci/pcie_starfive.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/pci/pcie_starfive.c b/drivers/pci/pcie_starfive.c index d5a812d36a..d02cffe9d4 100644 --- a/drivers/pci/pcie_starfive.c +++ b/drivers/pci/pcie_starfive.c @@ -371,15 +371,22 @@ static int starfive_pcie_init_port(struct udevice *dev) goto err_deassert_clk; } +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) ret = pinctrl_select_state(dev, "power-active"); if (ret) { dev_err(dev, "Set power-acvtive pinctrl failed: %d\n", ret); goto err_deassert_reset; } +#endif + ret = pinctrl_select_state(dev, "perst-active"); if (ret) { dev_err(dev, "Set perst-active pinctrl failed: %d\n", ret); +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) goto err_release_power_pin; +#else + goto err_deassert_reset; +#endif } /* Disable physical functions except #0 */ @@ -446,8 +453,10 @@ static int starfive_pcie_init_port(struct udevice *dev) return 0; +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) err_release_power_pin: pinctrl_select_state(dev, "power-default"); +#endif err_deassert_reset: reset_assert_bulk(&priv->rsts); err_deassert_clk: -- cgit v1.2.3 From 60884ca5ec70d8f03d342c69e5f807a76a2a4f47 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 16 Aug 2023 21:30:56 +0800 Subject: video: starfive: Add StarFive VisionFive 2 board support Make the code be compatible with the StarFive VisionFive 2 board. The code is ported from tag JH7110_VF2_515_v3.9.3 of VF2 repo. Signed-off-by: Keith Zhao Signed-off-by: Hal Feng --- drivers/video/starfive/sf_mipi.c | 9 +++++++++ drivers/video/starfive/sf_vop.c | 5 ++++- drivers/video/video-uclass.c | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/video/starfive/sf_mipi.c b/drivers/video/starfive/sf_mipi.c index 4521f7c869..ee5fbe7359 100644 --- a/drivers/video/starfive/sf_mipi.c +++ b/drivers/video/starfive/sf_mipi.c @@ -159,12 +159,21 @@ static void dsi_phy_post_set_mode(void *priv_data, unsigned long mode_flags) CFG_L0_SWAP_SEL_SHIFT, CFG_L0_SWAP_SEL_MASK);//Lane setting sf_dphy_set_reg(priv->phy_reg, 0x1, CFG_L1_SWAP_SEL_SHIFT, CFG_L1_SWAP_SEL_MASK); +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) sf_dphy_set_reg(priv->phy_reg, 0x4, CFG_L2_SWAP_SEL_SHIFT, CFG_L2_SWAP_SEL_MASK); sf_dphy_set_reg(priv->phy_reg, 0x2, CFG_L3_SWAP_SEL_SHIFT, CFG_L3_SWAP_SEL_MASK); sf_dphy_set_reg(priv->phy_reg, 0x3, CFG_L4_SWAP_SEL_SHIFT, CFG_L4_SWAP_SEL_MASK); +#else + sf_dphy_set_reg(priv->phy_reg, 0x2, + CFG_L2_SWAP_SEL_SHIFT, CFG_L2_SWAP_SEL_MASK); + sf_dphy_set_reg(priv->phy_reg, 0x3, + CFG_L3_SWAP_SEL_SHIFT, CFG_L3_SWAP_SEL_MASK); + sf_dphy_set_reg(priv->phy_reg, 0x4, + CFG_L4_SWAP_SEL_SHIFT, CFG_L4_SWAP_SEL_MASK); +#endif //PLL setting sf_dphy_set_reg(priv->phy_reg + 0x1c, 0x0, RG_CDTX_PLL_SSC_EN_SHIFT, RG_CDTX_PLL_SSC_EN_MASK); diff --git a/drivers/video/starfive/sf_vop.c b/drivers/video/starfive/sf_vop.c index e786032429..5f91ed7bde 100644 --- a/drivers/video/starfive/sf_vop.c +++ b/drivers/video/starfive/sf_vop.c @@ -43,7 +43,6 @@ static void iotrace_writel(ulong value, void *ptr) static int sf_vop_power_off(struct udevice *dev) { struct udevice *dev_power; - struct udevice *dev_pmic; struct power_domain_ops *ops; struct power_domain power_domain; int ret; @@ -76,7 +75,9 @@ static int sf_vop_power_off(struct udevice *dev) static int sf_vop_power(struct udevice *dev) { struct udevice *dev_power; +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) struct udevice *dev_pmic; +#endif struct power_domain_ops *ops; struct power_domain power_domain; int ret; @@ -108,6 +109,7 @@ static int sf_vop_power(struct udevice *dev) return ret; } +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) ret = uclass_get_device_by_driver(UCLASS_PMIC, DM_DRIVER_GET(pmic_starfive), &dev_pmic); if (ret) { @@ -120,6 +122,7 @@ static int sf_vop_power(struct udevice *dev) pr_err("failed to update SD control register: %d", ret); return ret; } +#endif return 0; } diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index 52a1d94743..f1fdabdfae 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -265,7 +265,7 @@ int video_sync_copy(struct udevice *dev, void *from, void *to) * frame buffer */ if (offset < -priv->fb_size || offset > 2 * priv->fb_size) { -#if DEBUG +#ifdef DEBUG char str[80]; snprintf(str, sizeof(str), -- cgit v1.2.3 From 4d348e3fb479c1462f408db1ae6f6ba124ec6b17 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 9 Aug 2023 14:06:59 +0800 Subject: board: starfive: Add StarFive Devkits board support Add board support for StarFive Devkits. The code is ported from tag JH7110_DVK_515_v3.9.3 of Devkits repo. Signed-off-by: Hal Feng --- board/starfive/devkits/Kconfig | 52 ++ board/starfive/devkits/MAINTAINERS | 7 + board/starfive/devkits/Makefile | 10 + board/starfive/devkits/devkits-i2c-eeprom.c | 758 ++++++++++++++++++++++++++++ board/starfive/devkits/spl.c | 166 ++++++ board/starfive/devkits/starfive_devkits.c | 482 ++++++++++++++++++ include/configs/starfive-devkits.h | 405 +++++++++++++++ 7 files changed, 1880 insertions(+) create mode 100644 board/starfive/devkits/Kconfig create mode 100644 board/starfive/devkits/MAINTAINERS create mode 100644 board/starfive/devkits/Makefile create mode 100644 board/starfive/devkits/devkits-i2c-eeprom.c create mode 100644 board/starfive/devkits/spl.c create mode 100644 board/starfive/devkits/starfive_devkits.c create mode 100644 include/configs/starfive-devkits.h diff --git a/board/starfive/devkits/Kconfig b/board/starfive/devkits/Kconfig new file mode 100644 index 0000000000..b5db828ae2 --- /dev/null +++ b/board/starfive/devkits/Kconfig @@ -0,0 +1,52 @@ +if TARGET_STARFIVE_DEVKITS + +config SYS_CPU + default "jh7110" + +config SYS_BOARD + default "devkits" + +config SYS_VENDOR + default "starfive" + +config SYS_CONFIG_NAME + default "starfive-devkits" + +config ENV_SIZE + default 0x2000 if ENV_IS_IN_SPI_FLASH + +config ENV_OFFSET + default 0x140000 if ENV_IS_IN_SPI_FLASH + +config SYS_TEXT_BASE + default 0x40200000 if SPL + default 0x40000000 if !RISCV_SMODE + default 0x40200000 if RISCV_SMODE + +config SPL_TEXT_BASE + default 0x08000000 + +config SPL_OPENSBI_LOAD_ADDR + default 0x80000000 + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select STARFIVE_JH7110 + imply CMD_DHCP + imply CMD_EXT2 + imply CMD_EXT4 + imply CMD_FAT + imply CMD_FS_GENERIC + imply CMD_GPT + imply PARTITION_TYPE_GUID + imply CMD_NET + imply CMD_PING + imply CMD_SF + imply DOS_PARTITION + imply EFI_PARTITION + imply IP_DYN + imply ISO_PARTITION + imply PHY_LIB + imply PHY_MSCC + +endif diff --git a/board/starfive/devkits/MAINTAINERS b/board/starfive/devkits/MAINTAINERS new file mode 100644 index 0000000000..f6eee7e833 --- /dev/null +++ b/board/starfive/devkits/MAINTAINERS @@ -0,0 +1,7 @@ +STARFIVE JH7110 DevKits BOARD +M: Yanhong Wang +S: Maintained +F: arch/riscv/include/asm/arch-jh7110/ +F: board/starfive/devkits/ +F: include/configs/starfive-devkits.h +F: configs/starfive_devkits_defconfig diff --git a/board/starfive/devkits/Makefile b/board/starfive/devkits/Makefile new file mode 100644 index 0000000000..40dc09b706 --- /dev/null +++ b/board/starfive/devkits/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2021 Shanghai StarFive Technology Co., Ltd. +# + +obj-y := starfive_devkits.o + +obj-$(CONFIG_SPL_BUILD) += spl.o + +obj-$(CONFIG_ID_EEPROM) += devkits-i2c-eeprom.o diff --git a/board/starfive/devkits/devkits-i2c-eeprom.c b/board/starfive/devkits/devkits-i2c-eeprom.c new file mode 100644 index 0000000000..55fbda3bcf --- /dev/null +++ b/board/starfive/devkits/devkits-i2c-eeprom.c @@ -0,0 +1,758 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. + * Written by Wei Fu (wefu@redhat.com) + */ + + +#include +#include +#include +#include +#include +#include +#include +//#include +/* + * MAGIC_NUMBER_BYTES: number of bytes used by the magic number + */ +#define MAGIC_NUMBER_BYTES 4 + +/* + * SERIAL_NUMBER_BYTES: number of bytes used by the board serial + * number + */ +//#define SERIAL_NUMBER_BYTES 16 + +/* + * MAC_ADDR_BYTES: number of bytes used by the Ethernet MAC address + */ +#define MAC_ADDR_BYTES 6 + +/* + * MAC_ADDR_STRLEN: length of mac address string + */ +#define MAC_ADDR_STRLEN 17 + +/* + * Atom Types + * 0x0000 = invalid + * 0x0001 = vendor info + * 0x0002 = GPIO map + * 0x0003 = Linux device tree blob + * 0x0004 = manufacturer custom data + * 0x0005-0xfffe = reserved for future use + * 0xffff = invalid + */ + +#define HATS_ATOM_INVALID 0x0000 +#define HATS_ATOM_VENDOR 0x0001 +#define HATS_ATOM_GPIO 0x0002 +#define HATS_ATOM_DTB 0x0003 +#define HATS_ATOM_CUSTOM 0x0004 +#define HATS_ATOM_INVALID_END 0xffff + +struct eeprom_hats_header { + char signature[MAGIC_NUMBER_BYTES]; /* ASCII table signature */ + u8 version; /* EEPROM data format version */ + /* (0x00 reserved, 0x01 = first version) */ + u8 reversed; /* 0x00, Reserved field */ + u16 numatoms; /* total atoms in EEPROM */ + u32 eeplen; /* total length in bytes of all eeprom data */ + /* (including this header) */ +}; + +struct eeprom_hats_atom_header { + u16 type; + u16 count; + u32 dlen; +}; + +/** + * static eeprom: EEPROM layout for the StarFive platform I2C format + */ +struct starfive_eeprom_atom1_data { + u8 uuid[16]; + u16 pid; + u16 pver; + u8 vslen; + u8 pslen; + uchar vstr[STARFIVE_EEPROM_ATOM1_VSTR_SIZE]; + uchar pstr[STARFIVE_EEPROM_ATOM1_PSTR_SIZE]; /* product SN */ +}; + +struct starfive_eeprom_atom1 { + struct eeprom_hats_atom_header header; + struct starfive_eeprom_atom1_data data; + u16 crc16; +}; + +struct starfive_eeprom_atom4_v1_data { + u16 version; + u8 pcb_revision; /* PCB version */ + u8 bom_revision; /* BOM version */ + u8 mac0_addr[MAC_ADDR_BYTES]; /* Ethernet0 MAC */ + u8 mac1_addr[MAC_ADDR_BYTES]; /* Ethernet1 MAC */ + u8 reserved[2]; +}; + +struct starfive_eeprom_atom4_v1 { + struct eeprom_hats_atom_header header; + struct starfive_eeprom_atom4_v1_data data; + u16 crc16; +}; + +/* Set to 1 if we've read EEPROM into memory + * Set to -1 if EEPROM data is wrong + */ +static int has_been_read; + +/** + * helper struct for getting info from the local EEPROM copy. + * most of the items are pointers to the eeprom_wp_buff. + * ONLY serialnum is the u32 from the last 8 Bytes of product string + */ +struct starfive_eeprom_info { + char *vstr; /* Vendor string in ATOM1 */ + char *pstr; /* product string in ATOM1 */ + u32 serialnum; /* serial number from in product string*/ + u16 *version; /* custom data version in ATOM4 */ + u8 *pcb_revision; /* PCB version in ATOM4 */ + u8 *bom_revision; /* BOM version in ATOM4 */ + u8 *mac0_addr; /* Ethernet0 MAC in ATOM4 */ + u8 *mac1_addr; /* Ethernet1 MAC in ATOM4 */ +}; +static struct starfive_eeprom_info einfo; + + +static uchar eeprom_wp_buff[STARFIVE_EEPROM_HATS_SIZE_MAX]; +static struct eeprom_hats_header starfive_eeprom_hats_header_default = { + .signature = STARFIVE_EEPROM_HATS_SIG, + .version = FORMAT_VERSION, + .numatoms = 2, + .eeplen = sizeof(struct eeprom_hats_header) + + sizeof(struct starfive_eeprom_atom1) + + sizeof(struct starfive_eeprom_atom4_v1) +}; +static struct starfive_eeprom_atom1 starfive_eeprom_atom1_default = { + .header = { + .type = HATS_ATOM_VENDOR, + .count = 1, + .dlen = sizeof(struct starfive_eeprom_atom1_data) + sizeof(u16) + }, + .data = { + .uuid = {0}, + .pid = 0, + .pver = 0, + .vslen = STARFIVE_EEPROM_ATOM1_VSTR_SIZE, + .pslen = STARFIVE_EEPROM_ATOM1_PSTR_SIZE, + .vstr = STARFIVE_EEPROM_ATOM1_VSTR, + .pstr = STARFIVE_EEPROM_ATOM1_PSTR + } +}; +static struct starfive_eeprom_atom4_v1 starfive_eeprom_atom4_v1_default = { + .header = { + .type = HATS_ATOM_CUSTOM, + .count = 2, + .dlen = sizeof(struct starfive_eeprom_atom4_v1_data) + sizeof(u16) + }, + .data = { + .version = FORMAT_VERSION, + .pcb_revision = PCB_VERSION, + .bom_revision = BOM_VERSION, + .mac0_addr = STARFIVE_DEFAULT_MAC0, + .mac1_addr = STARFIVE_DEFAULT_MAC1, + .reserved = {0} + } +}; + +//static u8 starfive_default_mac[MAC_ADDR_BYTES] = STARFIVE_DEFAULT_MAC; + +/** + * is_match_magic() - Does the magic number match that of a StarFive EEPROM? + * + * @hats: the pointer of eeprom_hats_header + * Return: status code, 0: Yes, non-0: NO + */ +static inline int is_match_magic(char *hats) +{ + return strncmp(hats, STARFIVE_EEPROM_HATS_SIG, MAGIC_NUMBER_BYTES); +} + +/** + * calculate_crc16() - Calculate the current CRC for atom + * Porting from https://github.com/raspberrypi/hats, getcrc + * @data: the pointer of eeprom_hats_atom_header + * @size: total length in bytes of the entire atom + * (type, count, dlen, data) + * Return: result: crc16 code + */ +#define CRC16 0x8005 +static u16 calculate_crc16(uchar* data, unsigned int size) +{ + int i, j = 0x0001; + u16 out = 0, crc = 0; + int bits_read = 0, bit_flag; + + /* Sanity check: */ + if((data == NULL) || size == 0) + return 0; + + while(size > 0) { + bit_flag = out >> 15; + + /* Get next bit: */ + out <<= 1; + // item a) work from the least significant bits + out |= (*data >> bits_read) & 1; + + /* Increment bit counter: */ + bits_read++; + if(bits_read > 7) { + bits_read = 0; + data++; + size--; + } + + /* Cycle check: */ + if(bit_flag) + out ^= CRC16; + } + + // item b) "push out" the last 16 bits + for (i = 0; i < 16; ++i) { + bit_flag = out >> 15; + out <<= 1; + if(bit_flag) + out ^= CRC16; + } + + // item c) reverse the bits + for (i = 0x8000; i != 0; i >>=1, j <<= 1) { + if (i & out) + crc |= j; + } + + return crc; +} + +/* This function should be called after each update to any EEPROM ATOM */ +static inline void update_crc(struct eeprom_hats_atom_header *atom) +{ + uint atom_crc_offset = sizeof(struct eeprom_hats_atom_header) + + atom->dlen - sizeof(u16); + u16 *atom_crc_p = (void *) atom + atom_crc_offset; + *atom_crc_p = calculate_crc16((uchar*) atom, atom_crc_offset); +} + +/** + * dump_raw_eeprom - display the raw contents of the EEPROM + */ +static void dump_raw_eeprom(u8 *e, unsigned int size) +{ + unsigned int i; + + printf("EEPROM dump: (0x%x bytes)\n", size); + + for (i = 0; i < size; i++) { + if (!(i % 0x10)) + printf("%02X: ", i); + + printf("%02X ", e[i]); + + if (((i % 16) == 15) || (i == size - 1)) + printf("\n"); + } + + return; +} + +static int hats_atom_crc_check(struct eeprom_hats_atom_header *atom) +{ + u16 atom_crc, data_crc; + uint atom_crc_offset = sizeof(struct eeprom_hats_atom_header) + + atom->dlen - sizeof(atom_crc); + u16 *atom_crc_p = (void *) atom + atom_crc_offset; + + atom_crc = *atom_crc_p; + data_crc = calculate_crc16((uchar *) atom, atom_crc_offset); + if (atom_crc == data_crc) + return 0; + + printf("EEPROM HATs: CRC ERROR in atom %x type %x, (%x!=%x)\n", + atom->count, atom->type, atom_crc, data_crc); + return -1; +} + +static void *hats_get_atom(struct eeprom_hats_header *header, u16 type) + { + struct eeprom_hats_atom_header *atom; + void *hats_eeprom_max = (void *)header + header->eeplen; + void *temp = (void *)header + sizeof(struct eeprom_hats_header); + + for (int numatoms = (int)header->numatoms; numatoms > 0; numatoms--) { + atom = (struct eeprom_hats_atom_header *)temp; + if (hats_atom_crc_check(atom)) + return NULL; + if (atom->type == type) + return (void *)atom; + /* go to next atom */ + temp = (void *)atom + sizeof(struct eeprom_hats_atom_header) + + atom->dlen; + if (temp > hats_eeprom_max) { + printf("EEPROM HATs: table overflow next@%p, max@%p\n", + temp, hats_eeprom_max); + break; + } + } + + /* fail to get atom */ + return NULL; +} + +/** + * show_eeprom - display the contents of the EEPROM + */ +static void show_eeprom(struct starfive_eeprom_info *einfo) +{ + if (has_been_read != 1) + return; + + printf("\n--------EEPROM INFO--------\n"); + printf("Vendor : %s\n", einfo->vstr); + printf("Product full SN: %s\n", einfo->pstr); + printf("data version: 0x%x\n", *einfo->version); + if (1 == *einfo->version) { + printf("PCB revision: 0x%x\n", *einfo->pcb_revision); + printf("BOM revision: %c\n", *einfo->bom_revision); + printf("Ethernet MAC0 address: %02x:%02x:%02x:%02x:%02x:%02x\n", + einfo->mac0_addr[0], einfo->mac0_addr[1], + einfo->mac0_addr[2], einfo->mac0_addr[3], + einfo->mac0_addr[4], einfo->mac0_addr[5]); + printf("Ethernet MAC1 address: %02x:%02x:%02x:%02x:%02x:%02x\n", + einfo->mac1_addr[0], einfo->mac1_addr[1], + einfo->mac1_addr[2], einfo->mac1_addr[3], + einfo->mac1_addr[4], einfo->mac1_addr[5]); + } else { + printf("Custom data v%d is not Supported\n", *einfo->version); + } + printf("--------EEPROM INFO--------\n\n"); +} + +/** + * parse_eeprom_info - parse the contents of the EEPROM + * If everthing gose right, + * 1, set has_been_read to 1 + * 2, display info + * + * If anything goes wrong, + * 1, set has_been_read to -1 + * 2, dump data by hex for debug + * + * @buf: the pointer of eeprom_hats_header in memory + * Return: status code, 0: Success, non-0: Fail + * + */ +static int parse_eeprom_info(struct eeprom_hats_header *buf) +{ + struct eeprom_hats_atom_header *atom; + void *atom_data; + struct starfive_eeprom_atom1_data *atom1 = NULL; + struct starfive_eeprom_atom4_v1_data *atom4_v1 = NULL; + + if (is_match_magic((char *)buf)) { + printf("Not a StarFive EEPROM data format - magic error\n"); + goto error; + }; + + printf("StarFive EEPROM format v%u\n", buf->version); + + // parse atom1(verdor) + atom = (struct eeprom_hats_atom_header *) + hats_get_atom(buf, HATS_ATOM_VENDOR); + if (atom) { + atom_data = (void *)atom + + sizeof(struct eeprom_hats_atom_header); + atom1 = (struct starfive_eeprom_atom1_data *)atom_data; + einfo.vstr = atom1->vstr; + einfo.pstr = atom1->pstr; + einfo.serialnum = (u32)hextoul((void *)atom1->pstr + + STARFIVE_EEPROM_ATOM1_SN_OFFSET, + NULL); + } else { + printf("fail to get vendor atom\n"); + goto error; + }; + + // parse atom4(custom) + atom = (struct eeprom_hats_atom_header *) + hats_get_atom(buf, HATS_ATOM_CUSTOM); + if (atom) { + atom_data = (void *)atom + + sizeof(struct eeprom_hats_atom_header); + atom4_v1 = (struct starfive_eeprom_atom4_v1_data *)atom_data; + einfo.version = &atom4_v1->version; + if (*einfo.version == 1) { + einfo.pcb_revision = &atom4_v1->pcb_revision; + einfo.bom_revision = &atom4_v1->bom_revision; + einfo.mac0_addr = atom4_v1->mac0_addr; + einfo.mac1_addr = atom4_v1->mac1_addr; + } + } else { + printf("fail to get custom data atom\n"); + goto error; + }; + + // everthing gose right + has_been_read = 1; + show_eeprom(&einfo); + return 0; + +error: + has_been_read = -1; + dump_raw_eeprom(eeprom_wp_buff, + STARFIVE_EEPROM_HATS_SIZE_MAX); + return -1; +} + +/** + * read_eeprom() - read the EEPROM into memory, if it hasn't been read yet + * @buf: the pointer of eeprom data buff + * Return: status code, 0: Success, non-0: Fail + * Note: depend on CONFIG_SYS_EEPROM_BUS_NUM + * CONFIG_SYS_I2C_EEPROM_ADDR + * STARFIVE_EEPROM_WP_OFFSET + * STARFIVE_EEPROM_HATS_SIZE_MAX + */ +static int read_eeprom(uint8_t *buf) +{ + int ret; + struct udevice *dev; + + if (has_been_read == 1) + return 0; + + ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM, + CONFIG_SYS_I2C_EEPROM_ADDR, + CONFIG_SYS_I2C_EEPROM_ADDR_LEN, + &dev); + if (!ret) { + ret = dm_i2c_read(dev, STARFIVE_EEPROM_WP_OFFSET, + buf, STARFIVE_EEPROM_HATS_SIZE_MAX); + } + + if (ret) { + printf("fail to read EEPROM.\n"); + return ret; + } + + return parse_eeprom_info((struct eeprom_hats_header *)buf); +} + +/** + * prog_eeprom() - write the EEPROM from memory + */ +static int prog_eeprom(uint8_t *buf, unsigned int size) +{ + unsigned int i; + void *p; + uchar tmp_buff[STARFIVE_EEPROM_HATS_SIZE_MAX]; + struct udevice *dev; + int ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM, + CONFIG_SYS_I2C_EEPROM_ADDR, + CONFIG_SYS_I2C_EEPROM_ADDR_LEN, + &dev); + + if (is_match_magic(buf)) { + printf("MAGIC ERROR, Please check the data@%p.\n", buf); + return -1; + } + + for (i = 0, p = buf; i < size; + i += BYTES_PER_EEPROM_PAGE, p += BYTES_PER_EEPROM_PAGE) { + if (!ret) + ret = dm_i2c_write(dev, + i + STARFIVE_EEPROM_WP_OFFSET, + p, min((int)(size - i), + BYTES_PER_EEPROM_PAGE)); + if (ret) + break; + udelay(EEPROM_WRITE_DELAY_MS); + } + + if (!ret) { + /* Verify the write by reading back the EEPROM and comparing */ + ret = dm_i2c_read(dev, + STARFIVE_EEPROM_WP_OFFSET, + tmp_buff, + STARFIVE_EEPROM_HATS_SIZE_MAX); + if (!ret && memcmp((void *)buf, (void *)tmp_buff, + STARFIVE_EEPROM_HATS_SIZE_MAX)) + ret = -1; + } + + if (ret) { + has_been_read = -1; + printf("Programming failed.Temp buff:\n"); + dump_raw_eeprom(tmp_buff, + STARFIVE_EEPROM_HATS_SIZE_MAX); + return -1; + } + + printf("Programming passed.\n"); + return 0; +} + +/** + * set_mac_address() - stores a MAC address into the local EEPROM copy + * + * This function takes a pointer to MAC address string + * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number), + * stores it in the MAC address field of the EEPROM local copy, and + * updates the local copy of the CRC. + */ +static void set_mac_address(char *string, int index) +{ + unsigned int i; + struct eeprom_hats_atom_header *atom4; + atom4 = (struct eeprom_hats_atom_header *) + hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff, + HATS_ATOM_CUSTOM); + + if (strncasecmp(STARFIVE_OUI_PREFIX, string, + strlen(STARFIVE_OUI_PREFIX))) { + printf("The MAC address doesn't match StarFive OUI %s\n", + STARFIVE_OUI_PREFIX); + return; + } + + for (i = 0; *string && (i < MAC_ADDR_BYTES); i++) { + if (index == 0) { + einfo.mac0_addr[i] = hextoul(string, &string); + } else { + einfo.mac1_addr[i] = hextoul(string, &string); + } + if (*string == ':') + string++; + } + + update_crc(atom4); +} + +/** + * set_pcb_revision() - stores a StarFive PCB revision into the local EEPROM copy + * + * Takes a pointer to a string representing the numeric PCB revision in + * decimal ("0" - "255"), stores it in the pcb_revision field of the + * EEPROM local copy, and updates the CRC of the local copy. + */ +static void set_pcb_revision(char *string) +{ + u8 p; + uint base = 16; + struct eeprom_hats_atom_header *atom4; + atom4 = (struct eeprom_hats_atom_header *) + hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff, + HATS_ATOM_CUSTOM); + + p = (u8)simple_strtoul(string, NULL, base); + if (p > U8_MAX) { + printf("%s must not be greater than %d\n", "PCB revision", + U8_MAX); + return; + } + + *einfo.pcb_revision = p; + + update_crc(atom4); +} + +/** + * set_bom_revision() - stores a StarFive BOM revision into the local EEPROM copy + * + * Takes a pointer to a uppercase ASCII character representing the BOM + * revision ("A" - "Z"), stores it in the bom_revision field of the + * EEPROM local copy, and updates the CRC of the local copy. + */ +static void set_bom_revision(char *string) +{ + struct eeprom_hats_atom_header *atom4; + atom4 = (struct eeprom_hats_atom_header *) + hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff, + HATS_ATOM_CUSTOM); + + if (string[0] < 'A' || string[0] > 'Z') { + printf("BOM revision must be an uppercase letter between A and Z\n"); + return; + } + + *einfo.bom_revision = string[0]; + + update_crc(atom4); +} + +/** + * set_product_id() - stores a StarFive product ID into the local EEPROM copy + * + * Takes a pointer to a string representing the numeric product ID in + * string ("DK7110B1-2150-D104EC32-00000001\0"), stores it in the product string + * field of the EEPROM local copy, and updates the CRC of the local copy. + */ +static void set_product_id(char *string) +{ + struct eeprom_hats_atom_header *atom1; + atom1 = (struct eeprom_hats_atom_header *) + hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff, + HATS_ATOM_VENDOR); + + memcpy((void *)einfo.pstr, (void *)string, + STARFIVE_EEPROM_ATOM1_PSTR_SIZE); + + update_crc(atom1); +} + +/** + * init_local_copy() - initialize the in-memory EEPROM copy + * + * Initialize the in-memory EEPROM copy with the magic number. Must + * be done when preparing to initialize a blank EEPROM, or overwrite + * one with a corrupted magic number. + */ +static void init_local_copy(uchar *buff) +{ + struct eeprom_hats_header *hats = (struct eeprom_hats_header *)buff; + struct eeprom_hats_atom_header *atom1 = (void *)hats + + sizeof(struct eeprom_hats_header); + struct eeprom_hats_atom_header *atom4_v1 = (void *)atom1 + + sizeof(struct starfive_eeprom_atom1); + + memcpy((void *)hats, (void *)&starfive_eeprom_hats_header_default, + sizeof(struct eeprom_hats_header)); + memcpy((void *)atom1, (void *)&starfive_eeprom_atom1_default, + sizeof(struct starfive_eeprom_atom1)); + memcpy((void *)atom4_v1, (void *)&starfive_eeprom_atom4_v1_default, + sizeof(struct starfive_eeprom_atom4_v1)); + + update_crc(atom1); + update_crc(atom4_v1); +} + +static int print_usage(void) +{ + printf("display and program the system ID and MAC addresses in EEPROM\n" + "[read_eeprom|initialize|write_eeprom|mac_address|pcb_revision|bom_revision|product_id]\n" + "mac read_eeprom\n" + " - read EEPROM content into memory data structure\n" + "mac write_eeprom\n" + " - save memory data structure to the EEPROM\n" + "mac initialize\n" + " - initialize the in-memory EEPROM copy with default data\n" + "mac mac0_address \n" + " - stores a MAC0 address into the local EEPROM copy\n" + "mac mac1_address \n" + " - stores a MAC1 address into the local EEPROM copy\n" + "mac pcb_revision \n" + " - stores a StarFive PCB revision into the local EEPROM copy\n" + "mac bom_revision \n" + " - stores a StarFive BOM revision into the local EEPROM copy\n" + "mac product_id \n" + " - stores a StarFive product ID into the local EEPROM copy\n"); + return 0; +} + +int do_mac(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + char *cmd; + + if (argc == 1) { + show_eeprom(&einfo); + return 0; + } + + if (argc > 3) + return print_usage(); + + cmd = argv[1]; + + /* Commands with no argument */ + if (!strcmp(cmd, "read_eeprom")) { + has_been_read = 0; + return read_eeprom(eeprom_wp_buff); + } else if (!strcmp(cmd, "initialize")) { + init_local_copy(eeprom_wp_buff); + return 0; + } else if (!strcmp(cmd, "write_eeprom")) { + return prog_eeprom(eeprom_wp_buff, + STARFIVE_EEPROM_HATS_SIZE_MAX); + } + + if (argc != 3) + return print_usage(); + + if (is_match_magic(eeprom_wp_buff)) { + printf("Please read the EEPROM ('read_eeprom') and/or initialize the EEPROM ('initialize') first.\n"); + return 0; + } + + if (!strcmp(cmd, "mac0_address")) { + set_mac_address(argv[2], 0); + return 0; + } else if (!strcmp(cmd, "mac1_address")) { + set_mac_address(argv[2], 1); + return 0; + } else if (!strcmp(cmd, "pcb_revision")) { + set_pcb_revision(argv[2]); + return 0; + } else if (!strcmp(cmd, "bom_revision")) { + set_bom_revision(argv[2]); + return 0; + } else if (!strcmp(cmd, "product_id")) { + set_product_id(argv[2]); + return 0; + } + + return print_usage(); +} + +/** + * mac_read_from_eeprom() - read the MAC address & the serial number in EEPROM + * + * This function reads the MAC address and the serial number from EEPROM and + * sets the appropriate environment variables for each one read. + * + * The environment variables are only set if they haven't been set already. + * This ensures that any user-saved variables are never overwritten. + * + * If CONFIG_ID_EEPROM is enabled, this function will be called in + * "static init_fnc_t init_sequence_r[]" of u-boot/common/board_r.c. + */ +int mac_read_from_eeprom(void) +{ + /** + * try to fill the buff from EEPROM, + * always return SUCCESS, even some error happens. + */ + if (read_eeprom(eeprom_wp_buff)) + return 0; + + // 1, setup ethaddr env + eth_env_set_enetaddr("eth0addr", einfo.mac0_addr); + eth_env_set_enetaddr("eth1addr", einfo.mac1_addr); + + /** + * 2, setup serial# env, reference to hifive-platform-i2c-eeprom.c, + * serial# can be a ASCII string, but not just a hex number, so we + * setup serial# in the 32Byte format: + * "DK7110B1-2150-D104EC32-00000001\0;" + * "---" + * : 4Byte, should be the output of `date +%y%W` + * : 8Byte, "D008" means 8GB, "D01T" means 1TB; + * "E000" means no eMMC,"E032" means 32GB, "E01T" means 1TB. + * : 8Byte, the Unique Identifier of board in hex. + */ + if (!env_get("serial#")) + env_set("serial#", einfo.pstr); + + return 0; +} + diff --git a/board/starfive/devkits/spl.c b/board/starfive/devkits/spl.c new file mode 100644 index 0000000000..d5f43b4747 --- /dev/null +++ b/board/starfive/devkits/spl.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022-2023 StarFive Technology Co., Ltd. + * Author: yanhong + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODE_SELECT_REG 0x1702002c + +int spl_board_init_f(void) +{ + int ret; + + ret = spl_soc_init(); + if (ret) { + debug("JH7110 SPL init failed: %d\n", ret); + return ret; + } + + return 0; +} + +u32 spl_boot_device(void) +{ + int boot_mode = 0; + + boot_mode = readl((const volatile void *)MODE_SELECT_REG) & 0x3; + switch (boot_mode) { + case 0: + return BOOT_DEVICE_SPI; + case 1: + return BOOT_DEVICE_MMC2; + case 2: + return BOOT_DEVICE_MMC1; + case 3: + return BOOT_DEVICE_UART; + default: + debug("Unsupported boot device 0x%x.\n", + boot_mode); + return BOOT_DEVICE_NONE; + } +} + +struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +{ + return (struct image_header *)(STARFIVE_SPL_BOOT_LOAD_ADDR); +} + +void board_init_f(ulong dummy) +{ + int ret; + + /* Adjust cpu frequency, the default is 1.0GHz */ + starfive_jh7110_pll_set_rate(PLL0, 1000000000); + + /*change pll2 to 1188MHz*/ + starfive_jh7110_pll_set_rate(PLL2, 1188000000); + + /*DDR control depend clk init*/ + clrsetbits_le32(SYS_CRG_BASE, CLK_CPU_ROOT_SW_MASK, + BIT(CLK_CPU_ROOT_SW_SHIFT) & CLK_CPU_ROOT_SW_MASK); + + clrsetbits_le32(SYS_CRG_BASE + CLK_BUS_ROOT_OFFSET, + CLK_BUS_ROOT_SW_MASK, + BIT(CLK_BUS_ROOT_SW_SHIFT) & CLK_BUS_ROOT_SW_MASK); + + /*Set clk_perh_root clk default mux sel to pll2*/ + clrsetbits_le32(SYS_CRG_BASE + CLK_PERH_ROOT_OFFSET, + CLK_PERH_ROOT_MASK, + BIT(CLK_PERH_ROOT_SHIFT) & CLK_PERH_ROOT_MASK); + + clrsetbits_le32(SYS_CRG_BASE + CLK_NOC_BUS_STG_AXI_OFFSET, + CLK_NOC_BUS_STG_AXI_EN_MASK, + BIT(CLK_NOC_BUS_STG_AXI_EN_SHIFT) + & CLK_NOC_BUS_STG_AXI_EN_MASK); + + clrsetbits_le32(AON_CRG_BASE + CLK_AON_APB_FUNC_OFFSET, + CLK_AON_APB_FUNC_SW_MASK, + BIT(CLK_AON_APB_FUNC_SW_SHIFT) & CLK_AON_APB_FUNC_SW_MASK); + + /* switch qspi clk to pll0 */ + clrsetbits_le32(SYS_CRG_BASE + CLK_QSPI_REF_OFFSET, + CLK_QSPI_REF_SW_MASK, + BIT(CLK_QSPI_REF_SW_SHIFT) & CLK_QSPI_REF_SW_MASK); + + /*set GPIO to 3.3v*/ + setbits_le32(SYS_SYSCON_BASE + 0xC, 0x0); + + /* Improved GMAC0 TX I/O PAD capability */ + clrsetbits_le32(AON_IOMUX_BASE + 0x78, 0x3, BIT(0) & 0x3); + clrsetbits_le32(AON_IOMUX_BASE + 0x7c, 0x3, BIT(0) & 0x3); + clrsetbits_le32(AON_IOMUX_BASE + 0x80, 0x3, BIT(0) & 0x3); + clrsetbits_le32(AON_IOMUX_BASE + 0x84, 0x3, BIT(0) & 0x3); + clrsetbits_le32(AON_IOMUX_BASE + 0x88, 0x3, BIT(0) & 0x3); + + /* Improved GMAC1 TX I/O PAD capability */ + clrsetbits_le32(SYS_IOMUX_BASE + 0x26c, 0x3, BIT(0) & 0x3); + clrsetbits_le32(SYS_IOMUX_BASE + 0x270, 0x3, BIT(0) & 0x3); + clrsetbits_le32(SYS_IOMUX_BASE + 0x274, 0x3, BIT(0) & 0x3); + clrsetbits_le32(SYS_IOMUX_BASE + 0x278, 0x3, BIT(0) & 0x3); + clrsetbits_le32(SYS_IOMUX_BASE + 0x27c, 0x3, BIT(0) & 0x3); + + SYS_IOMUX_DOEN(62, LOW); + SYS_IOMUX_DOUT(62, 19); + SYS_IOMUX_SET_DS(64, 2); + SYS_IOMUX_SET_SLEW(64, 1); + SYS_IOMUX_SET_DS(65, 1); + SYS_IOMUX_SET_DS(66, 1); + SYS_IOMUX_SET_DS(67, 1); + SYS_IOMUX_SET_DS(68, 1); + SYS_IOMUX_SET_DS(69, 1); + SYS_IOMUX_SET_DS(70, 1); + SYS_IOMUX_SET_DS(71, 1); + SYS_IOMUX_SET_DS(72, 1); + SYS_IOMUX_SET_DS(73, 1); + + SYS_IOMUX_DOEN(10, LOW); + SYS_IOMUX_DOUT(10, 55); + SYS_IOMUX_SET_SLEW(10, 1); + SYS_IOMUX_SET_DS(10, 2); + SYS_IOMUX_COMPLEX(9, 44, 57, 19); + SYS_IOMUX_SET_DS(9, 1); + SYS_IOMUX_COMPLEX(11, 45, 58, 20); + SYS_IOMUX_SET_DS(11, 1); + SYS_IOMUX_COMPLEX(12, 46, 59, 21); + SYS_IOMUX_SET_DS(12, 1); + SYS_IOMUX_COMPLEX(7, 47, 60, 22); + SYS_IOMUX_SET_DS(7, 1); + SYS_IOMUX_COMPLEX(8, 48, 61, 23); + SYS_IOMUX_SET_DS(8, 1); + + ret = spl_early_init(); + if (ret) + panic("spl_early_init() failed: %d\n", ret); + + arch_cpu_init_dm(); + + preloader_console_init(); + + ret = spl_board_init_f(); + if (ret) { + debug("spl_board_init_f init failed: %d\n", ret); + return; + } +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* boot using first FIT config */ + return 0; +} +#endif + + diff --git a/board/starfive/devkits/starfive_devkits.c b/board/starfive/devkits/starfive_devkits.c new file mode 100644 index 0000000000..741c190d2e --- /dev/null +++ b/board/starfive/devkits/starfive_devkits.c @@ -0,0 +1,482 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022-2023 StarFive Technology Co., Ltd. + * Author: yanhong + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define SYS_CLOCK_ENABLE(clk) \ + setbits_le32(SYS_CRG_BASE + clk, CLK_ENABLE_MASK) + +#define CPU_VOL_BINNING_OFFSET 0x7fc +enum { + BOOT_FLASH = 0, + BOOT_SD, + BOOT_EMMC, + BOOT_UART, +}; +enum cpu_voltage_type_t { + CPU_VOL_1020 = 0xef0, + CPU_VOL_1040 = 0xfff, + CPU_VOL_1060 = 0xff0, + CPU_VOL_1000 = 0x8f0, +}; +#define CPU_VOL_MASK 0xfff + +static void sys_reset_clear(ulong assert, ulong status, u32 rst) +{ + u32 value; + + clrbits_le32(SYS_CRG_BASE + assert, BIT(rst)); + do { + value = in_le32(SYS_CRG_BASE + status); + } while ((value & BIT(rst)) != BIT(rst)); +} + +static void jh7110_timer_init(void) +{ + SYS_CLOCK_ENABLE(TIMER_CLK_APB_SHIFT); + SYS_CLOCK_ENABLE(TIMER_CLK_TIMER0_SHIFT); + SYS_CLOCK_ENABLE(TIMER_CLK_TIMER1_SHIFT); + SYS_CLOCK_ENABLE(TIMER_CLK_TIMER2_SHIFT); + SYS_CLOCK_ENABLE(TIMER_CLK_TIMER3_SHIFT); + + sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, + SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_APB_SHIFT); + sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, + SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER0_SHIFT); + sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, + SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER1_SHIFT); + sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, + SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER2_SHIFT); + sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT, + SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER3_SHIFT); +} + +static void jh7110_i2c_init (int id) +{ + switch (id) { + case 5: + //scl + SYS_IOMUX_COMPLEX(19, 79, 0, 42); + //sda + SYS_IOMUX_COMPLEX(20, 80, 0, 43); + + break; + + default: + break; + } +} + +static void jh7110_gmac_sel_tx_to_rgmii(int id) +{ + switch (id) { + case 0: + clrsetbits_le32(AON_CRG_BASE + GMAC5_0_CLK_TX_SHIFT, + GMAC5_0_CLK_TX_MASK, + BIT(GMAC5_0_CLK_TX_BIT) & GMAC5_0_CLK_TX_MASK); + break; + case 1: + clrsetbits_le32(SYS_CRG_BASE + GMAC5_1_CLK_TX_SHIFT, + GMAC5_1_CLK_TX_MASK, + BIT(GMAC5_1_CLK_TX_BIT) & GMAC5_1_CLK_TX_MASK); + break; + default: + break; + } +} + +static void jh7110_gmac_io_pad(int id) +{ + u32 cap = BIT(0); /* 2.5V */ + + switch (id) { + case 0: + /* Improved GMAC0 TX I/O PAD capability */ + clrsetbits_le32(AON_IOMUX_BASE + 0x78, 0x3, cap & 0x3); + clrsetbits_le32(AON_IOMUX_BASE + 0x7c, 0x3, cap & 0x3); + clrsetbits_le32(AON_IOMUX_BASE + 0x80, 0x3, cap & 0x3); + clrsetbits_le32(AON_IOMUX_BASE + 0x84, 0x3, cap & 0x3); + clrsetbits_le32(AON_IOMUX_BASE + 0x88, 0x3, cap & 0x3); + break; + case 1: + /* Improved GMAC1 TX I/O PAD capability */ + clrsetbits_le32(SYS_IOMUX_BASE + 0x26c, 0x3, cap & 0x3); + clrsetbits_le32(SYS_IOMUX_BASE + 0x270, 0x3, cap & 0x3); + clrsetbits_le32(SYS_IOMUX_BASE + 0x274, 0x3, cap & 0x3); + clrsetbits_le32(SYS_IOMUX_BASE + 0x278, 0x3, cap & 0x3); + clrsetbits_le32(SYS_IOMUX_BASE + 0x27c, 0x3, cap & 0x3); + break; + } +} + +static void jh7110_gmac_init(int id) +{ + jh7110_gmac_sel_tx_to_rgmii(id); + jh7110_gmac_io_pad(id); +} + +static void jh7110_usb_init(bool usb2_enable) +{ + if (usb2_enable) { + /*usb 2.0 utmi phy init*/ + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, + USB_MODE_STRAP_MASK, + (2<ram_base); + env_set_hex("memory_size", gd->ram_size); + + ret = uclass_get_device(UCLASS_VIDEO, 0, &dev); + if (ret) + return ret; + + ret = video_bmp_display(dev, (ulong)&bmp_logo_bitmap[0], BMP_ALIGN_CENTER, BMP_ALIGN_CENTER, true); + if (ret) + goto err; + +err: + return 0; + +} + +static int jh7110_get_gpio_val(u32 gpio) +{ + int ret; + + ret = gpio_request(gpio, "ddr_gpio"); + if (!ret) { + ret = gpio_direction_input(gpio); + if (!ret) + ret = gpio_get_value(gpio); + + gpio_free(gpio); + } + + return ret; +} + +int board_ddr_size(void) +{ + int val, ret; + + val = jh7110_get_gpio_val(21); + if (IS_ERR_VALUE(val)) + return val; + + ret = jh7110_get_gpio_val(22); + if (IS_ERR_VALUE(ret)) + return ret; + + val |= (ret << 1); + + switch (val) { + case 0x0: + ret = 8; //8GB + break; + case 0x1: + ret = 4; //4GB + break; + case 0x2: + ret = 2; //2GB + break; + case 0x3: + ret = 1; //1GB + break; + default: + ret = -EINVAL; + break; + }; + + return ret; +} + +static int starfive_get_gpio_val(u32 gpio) +{ + int ret; + + ret = gpio_request(gpio, "ddr_gpio"); + if (!ret) { + ret = gpio_direction_input(gpio); + if (!ret) + ret = gpio_get_value(gpio); + + gpio_free(gpio); + } + + return ret; +} + +/* get ddr type from GPIO23,GPIO24 DDR4 or LPDDR4 */ +int starfive_get_ddr_type(void) +{ + int val, ret; + + val = starfive_get_gpio_val(23); + if (IS_ERR_VALUE(val)) + return val; + + ret = starfive_get_gpio_val(24); + if (IS_ERR_VALUE(ret)) + return ret; + + return val | (ret << 1); +} diff --git a/include/configs/starfive-devkits.h b/include/configs/starfive-devkits.h new file mode 100644 index 0000000000..b7547d8064 --- /dev/null +++ b/include/configs/starfive-devkits.h @@ -0,0 +1,405 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Shanghai StarFive Technology Co., Ltd. + * YanHong Wang + */ + +#ifndef _STARFIVE_DEVKITS_H +#define _STARFIVE_DEVKITS_H + +#include +#include + +#ifdef CONFIG_SPL + +#define CONFIG_SPL_MAX_SIZE 0x00040000 +#define CONFIG_SPL_BSS_START_ADDR 0x08040000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x00010000 +#define CONFIG_SYS_SPL_MALLOC_START 0x42000000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00800000 + +#define CONFIG_SPL_STACK (0x08000000 + 0x00180000 - \ + GENERATED_GBL_DATA_SIZE) + +#define STARFIVE_SPL_BOOT_LOAD_ADDR 0x60000000 +#endif + +#define CONFIG_SYS_BOOTM_LEN SZ_64M + +#define CONFIG_SYS_CACHELINE_SIZE 64 + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */ + +/* + * Print Buffer Size + */ +#define CONFIG_SYS_PBSIZE \ + (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) + +/* + * max number of command args + */ +#define CONFIG_SYS_MAXARGS 16 + +/* + * Boot Argument Buffer Size + */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + +/* + * Size of malloc() pool + * 512kB is suggested, (CONFIG_ENV_SIZE + 128 * 1024) was not enough + */ +#define CONFIG_SYS_MALLOC_LEN SZ_8M + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 + +/* Init Stack Pointer */ +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_8M) + +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_16M) +#define CONFIG_STANDALONE_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_16M) + +/* + * Ethernet + */ +#ifdef CONFIG_CMD_NET +#define CONFIG_DW_ALTDESCRIPTOR +#define DWC_NET_PHYADDR 0 +#define CONFIG_ARP_TIMEOUT 500 +#define PHY_ANEG_TIMEOUT 8000 /* PHY needs longer aneg time */ +#define CONFIG_NETMASK 255.255.255.0 +#define CONFIG_IPADDR 192.168.120.230 +#define CONFIG_IP_DEFRAG +#ifndef CONFIG_NET_MAXDEFRAG +#define CONFIG_NET_MAXDEFRAG 16384 +#endif +#endif + +/* HACK these should have '#if defined (stuff) around them like zynqp*/ +#define BOOT_TARGET_DEVICES(func) func(DHCP, dhcp, na) func(MMC, mmc, 0) + +#include + + +#include + +#define TYPE_GUID_LOADER1 "5B193300-FC78-40CD-8002-E86C45580B47" +#define TYPE_GUID_LOADER2 "2E54B353-1271-4842-806F-E436D6AF6985" +#define TYPE_GUID_SYSTEM "0FC63DAF-8483-4772-8E79-3D69D8477DE4" + +#define CPU_VOL_1020_SET \ + "cpu_vol_1020_set=" \ + "fdt set /opp-table-0/opp-1500000000 opp-microvolt <1020000>;\0" + +#define CPU_VOL_1040_SET \ + "cpu_vol_1040_set=" \ + "fdt set /opp-table-0/opp-1500000000 opp-microvolt <1040000>;\0" + +#define CPU_VOL_1060_SET \ + "cpu_vol_1060_set=" \ + "fdt set /opp-table-0/opp-1500000000 opp-microvolt <1060000>;\0" + +#define CPU_SPEED_1250_SET \ + "cpu_speed_1250_set=" \ + "fdt rm /opp-table-0/opp-375000000;" \ + "fdt rm /opp-table-0/opp-500000000;" \ + "fdt rm /opp-table-0/opp-750000000;" \ + "fdt rm /opp-table-0/opp-1500000000;\0" + +#define CPU_SPEED_1500_SET \ + "cpu_speed_1500_set=" \ + "fdt rm /opp-table-0/opp-312500000;" \ + "fdt rm /opp-table-0/opp-417000000;" \ + "fdt rm /opp-table-0/opp-625000000;" \ + "fdt rm /opp-table-0/opp-1250000000;\0" + +#define CMA_SIZE_SET \ + "cma_start=70000000\0" \ + "cma_1g=b000000\0" \ + "cma_2g=20000000\0" \ + "cma_4g=40000000\0" \ + "cma_8g=60000000\0" \ + "cma_node=/reserved-memory/linux,cma\0" \ + "cma_ddr1g_set=" \ + "fdt set ${cma_node} size <0x0 0x${cma_1g}>;" \ + "fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_1g}>;\0" \ + "cma_ddr2g_set=" \ + "fdt set ${cma_node} size <0x0 0x${cma_2g}>;" \ + "fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_2g}>;\0" \ + "cma_ddr4g_set=" \ + "fdt set ${cma_node} size <0x0 0x${cma_4g}>;" \ + "fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_4g}>;\0" \ + "cma_ddr8g_set=" \ + "fdt set ${cma_node} size <0x0 0x${cma_8g}>;" \ + "fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_8g}>;\0" \ + "cma_resize=" \ + "if test ${memory_size} -eq 40000000; then " \ + "run cma_ddr1g_set;" \ + "elif test ${memory_size} -eq 80000000; then " \ + "run cma_ddr2g_set;" \ + "elif test ${memory_size} -eq 100000000; then " \ + "run cma_ddr4g_set;" \ + "elif test ${memory_size} -ge 200000000; then " \ + "run cma_ddr8g_set;" \ + "fi; \0 " + +#define CPU_FREQ_VOL_SET \ + "cpu_vol_set=" \ + "if test ${cpu_max_vol} = 1000000; then " \ + "run cpu_speed_1250_set; " \ + "else " \ + "run cpu_speed_1500_set; " \ + "if test ${cpu_max_vol} = 1060000; then " \ + "run cpu_vol_1060_set; " \ + "elif test ${cpu_max_vol} = 1020000; then " \ + "run cpu_vol_1020_set; " \ + "else " \ + "run cpu_vol_1040_set; " \ + "fi; " \ + "fi; \0" + +#define DEVKITS_MEM_SET \ + "devkits_mem_set=" \ + "fdt memory ${memory_addr} ${memory_size};" \ + "run cma_resize; \0" + +#define CHIPA_GMAC_SET \ + "chipa_gmac_set=" \ + "fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_10 <0x1>;" \ + "fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_100 <0x1>;" \ + "fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_1000 <0x1>;\0" + +#define CHIPA_SET \ + "chipa_set=" \ + "if test ${chip_vision} = B; then " \ + "run chipa_gmac_set;" \ + "fi; \0" \ + "chipa_set_uboot=" \ + "fdt addr ${fdtcontroladdr};" \ + "run chipa_set;\0" \ + "chipa_set_linux=" \ + "fdt addr ${fdt_addr_r};" \ + "run devkits_mem_set;" \ + "run chipa_set;\0" + +#define PARTS_DEFAULT \ + "name=loader1,start=17K,size=1M,type=${type_guid_gpt_loader1};" \ + "name=loader2,size=4MB,type=${type_guid_gpt_loader2};" \ + "name=system,size=-,bootable,type=${type_guid_gpt_system};" + +#define JH7110_SDK_BOOTENV \ + "bootdir=/boot\0" \ + "bootpart=3\0" \ + "rootpart=4\0" \ + "load_sdk_uenv=" \ + "fatload ${bootdev} ${devnum}:${bootpart} ${loadaddr} ${bootenv_sdk};" \ + "env import -t ${loadaddr} ${filesize}; \0" \ + "mmc_test_and_boot=" \ + "if mmc dev ${devnum}; then " \ + "echo Try booting from MMC${devnum} ...; " \ + "setenv sdev_blk mmcblk${devnum}p${rootpart};" \ + "run load_sdk_uenv; run boot2;" \ + "fi;\0" \ + "bootenv_mmc=" \ + "setenv bootdev mmc;" \ + "if test ${bootmode} = flash; then " \ + "for mmc_devnum in ${mmc_devnum_l}; do " \ + "setenv devnum ${mmc_devnum}; " \ + "run mmc_test_and_boot;" \ + "done;" \ + "fi; " \ + "if test ${bootmode} = sd; then " \ + "setenv devnum ${sd_devnum};" \ + "run mmc_test_and_boot;" \ + "fi; " \ + "if test ${bootmode} = emmc; then " \ + "setenv devnum ${emmc_devnum};"\ + "run mmc_test_and_boot;" \ + "fi; \0" \ + "bootenv_nvme=" \ + "if test ${bootmode} = flash; then " \ + "for nvme_devnum in ${nvme_devnum_l}; do " \ + "setenv devnum ${nvme_devnum};" \ + "if pci enum; then " \ + "nvme scan; " \ + "fi; " \ + "if nvme dev ${devnum}; then " \ + "echo Try booting from NVME${devnum} ...; " \ + "setenv bootdev nvme;" \ + "setenv sdev_blk nvme${devnum}n1p${rootpart};" \ + "run load_sdk_uenv; run boot2;" \ + "fi; " \ + "done; " \ + "fi; \0" \ + "sdk_boot_env=" \ + "for bootdev_s in ${boot_devs}; do " \ + "run bootenv_${bootdev_s}; " \ + "done;\0" \ + "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" + +#define DEVKITS_SDK_BOOTENV \ + "bootenv=uEnv.txt\0" \ + "bootenv_sdk=devkits_uEnv.txt\0"\ + "boot_devs=mmc nvme\0" \ + "emmc_devnum=0\0" \ + "sd_devnum=1\0" \ + "mmc_devnum_l=1 0\0" \ + "nvme_devnum_l=0 0\0" + +#define JH7110_DISTRO_BOOTENV \ + "bootdir=/boot\0" \ + "bootpart=3\0" \ + "rootpart=4\0" \ + "load_distro_uenv=" \ + "fatload ${bootdev} ${devnum}:${bootpart} ${loadaddr} /${bootenv}; " \ + "env import ${loadaddr} ${filesize}; \0" \ + "fdt_loaddtb=" \ + "fatload ${bootdev} ${devnum}:${bootpart} ${fdt_addr_r} /dtbs/${fdtfile}; fdt addr ${fdt_addr_r}; \0" \ + "fdt_sizecheck=" \ + "fatsize ${bootdev} ${devnum}:${bootpart} /dtbs/${fdtfile}; \0" \ + "set_fdt_distro=" \ + "run chipa_set_linux; run cpu_vol_set;" \ + "fatwrite ${bootdev} ${devnum}:${bootpart} ${fdt_addr_r} /dtbs/${fdtfile} ${filesize}; \0" \ + "bootcmd_distro=" \ + "run load_distro_uenv; " \ + "run fdt_loaddtb; run fdt_sizecheck; run set_fdt_distro; " \ + "sysboot ${bootdev} ${devnum}:${bootpart} fat ${scriptaddr} /${boot_syslinux_conf}; \0" \ + "distro_mmc_test_and_boot=" \ + "if mmc dev ${devnum}; then " \ + "echo Try booting from MMC${devnum} ...; " \ + "run bootcmd_distro;" \ + "fi;\0" \ + "distro_bootenv_mmc=" \ + "setenv bootdev mmc;" \ + "if test ${bootmode} = flash; then " \ + "for mmc_devnum in ${mmc_devnum_l}; do "\ + "setenv devnum ${mmc_devnum}; " \ + "run distro_mmc_test_and_boot;" \ + "done;" \ + "fi; " \ + "if test ${bootmode} = sd; then " \ + "setenv devnum ${sd_devnum};" \ + "run distro_mmc_test_and_boot;" \ + "fi; " \ + "if test ${bootmode} = emmc; then " \ + "setenv devnum ${emmc_devnum};"\ + "run distro_mmc_test_and_boot;" \ + "fi; \0" \ + "distro_bootenv_nvme=" \ + "if test ${bootmode} = flash; then " \ + "for nvme_devnum in ${nvme_devnum_l}; do " \ + "setenv devnum ${nvme_devnum};" \ + "if pci enum; then " \ + "nvme scan; " \ + "fi; " \ + "if nvme dev ${devnum}; then " \ + "echo Try booting from NVME${devnum} ...; " \ + "setenv bootdev nvme;" \ + "run bootcmd_distro; " \ + "fi; " \ + "done; " \ + "fi; \0" \ + "distro_boot_env=" \ + "echo Tring booting distro ...;" \ + "for bootdev_s in ${boot_devs}; do " \ + "run distro_bootenv_${bootdev_s}; " \ + "done; \0" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "fdt_high=0xffffffffffffffff\0" \ + "initrd_high=0xffffffffffffffff\0" \ + "kernel_addr_r=0x40200000\0" \ + "kernel_comp_addr_r=0x5a000000\0" \ + "kernel_comp_size=0x4000000\0" \ + "fdt_addr_r=0x46000000\0" \ + "scriptaddr=0x43900000\0" \ + "script_offset_f=0x1fff000\0" \ + "script_size_f=0x1000\0" \ + "pxefile_addr_r=0x45900000\0" \ + "ramdisk_addr_r=0x46100000\0" \ + "fdtoverlay_addr_r=0x4f000000\0" \ + "loadaddr=0x60000000\0" \ + CHIPA_GMAC_SET \ + CHIPA_SET \ + CPU_VOL_1020_SET \ + CPU_VOL_1040_SET \ + CPU_VOL_1060_SET \ + CPU_SPEED_1250_SET \ + CPU_SPEED_1500_SET \ + CPU_FREQ_VOL_SET \ + DEVKITS_MEM_SET \ + DEVKITS_SDK_BOOTENV \ + CMA_SIZE_SET \ + JH7110_SDK_BOOTENV \ + JH7110_DISTRO_BOOTENV \ + "type_guid_gpt_loader1=" TYPE_GUID_LOADER1 "\0" \ + "type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \ + "type_guid_gpt_system=" TYPE_GUID_SYSTEM "\0" \ + "partitions=" PARTS_DEFAULT "\0" \ + BOOTENV \ + BOOTENV_SF + +#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600} +#define CONFIG_SYS_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + +/* 6.25MHz RTC clock, StarFive JH7110*/ +#define CONFIG_SYS_HZ_CLOCK 4000000 + +#define __io + +#define memset_io(c, v, l) memset((c), (v), (l)) +#define memcpy_fromio(a, c, l) memcpy((a), (c), (l)) +#define memcpy_toio(c, a, l) memcpy((c), (a), (l)) + +#define CONFIG_ID_EEPROM + +#ifdef CONFIG_ID_EEPROM /* EEPROM for SN and MAC */ +#define CONFIG_SYS_EEPROM_BUS_NUM 5 + +#define FORMAT_VERSION 0x01 +#define PCB_VERSION 0xB0 +#define BOM_VERSION 'A' +/* + * BYTES_PER_EEPROM_PAGE: the 24FC04H datasheet says that data can + * only be written in page mode, which means 16 bytes at a time: + * 16-Byte Page Write Buffer + */ +#define BYTES_PER_EEPROM_PAGE 16 + +/* + * EEPROM_WRITE_DELAY_MS: the 24FC04H datasheet says it takes up to + * 5ms to complete a given write: + * Write Cycle Time (byte or page) ro Page Write Time 5 ms, Maximum + */ +#define EEPROM_WRITE_DELAY_MS 5000 +/* + * StarFive OUI. Registration Date is 20xx-xx-xx + */ +#define STARFIVE_OUI_PREFIX "6C:CF:39:" +#define STARFIVE_DEFAULT_MAC0 {0x6c, 0xcf, 0x39, 0x6c, 0xde, 0xad} +#define STARFIVE_DEFAULT_MAC1 {0x6c, 0xcf, 0x39, 0x7c, 0xae, 0x5d} + +/* Magic number at the first four bytes of EEPROM HATs */ +#define STARFIVE_EEPROM_HATS_SIG "SFDK" /* StarFive VisionFive */ + +#define STARFIVE_EEPROM_HATS_SIZE_MAX 256 /* Header + Atom1&4(v1) */ +#define STARFIVE_EEPROM_WP_OFFSET 0 /* Read only field */ +#define STARFIVE_EEPROM_ATOM1_PSTR "DK7110B1-2150-D104EC32-00000001\0" + +#define STARFIVE_EEPROM_ATOM1_PSTR_SIZE 32 +#define STARFIVE_EEPROM_ATOM1_SN_OFFSET 23 +#define STARFIVE_EEPROM_ATOM1_VSTR "StarFive Technology Co., Ltd.\0\0\0" +#define STARFIVE_EEPROM_ATOM1_VSTR_SIZE 32 +#endif + +#define CONFIG_VIDEO_BMP_LOGO +#define CONFIG_VIDEO_LOGO +#define CONFIG_BMP_16BPP +#define CONFIG_BMP_24BPP +#define CONFIG_BMP_32BPP + +#endif /* _STARFIVE_DEVKITS_H */ -- cgit v1.2.3 From e4f8517ebf5ae7a80540f11dde02868c85d21a24 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 9 Aug 2023 15:34:36 +0800 Subject: board: starfive: Add TARGET_STARFIVE_DEVKITS to Kconfig Add board support for StarFive Devkits. The code is ported from tag JH7110_DVK_515_v3.9.3 of Devkits repo. Signed-off-by: Hal Feng --- arch/riscv/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 25ed0ba1cf..b8adf6ba36 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -23,6 +23,9 @@ config TARGET_SIFIVE_UNLEASHED config TARGET_SIFIVE_UNMATCHED bool "Support SiFive Unmatched Board" +config TARGET_STARFIVE_DEVKITS + bool "Support StarFive DevKits Board" + config TARGET_STARFIVE_VISIONFIVE2 bool "Support StarFive VisionFive2 Board" @@ -71,6 +74,7 @@ source "board/sifive/unleashed/Kconfig" source "board/sifive/unmatched/Kconfig" source "board/openpiton/riscv64/Kconfig" source "board/sipeed/maix/Kconfig" +source "board/starfive/devkits/Kconfig" source "board/starfive/visionfive2/Kconfig" source "board/starfive/evb/Kconfig" -- cgit v1.2.3 From 55255733cfcd7735b9390c324d5f451f4ebbac23 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 9 Aug 2023 16:02:50 +0800 Subject: riscv: dts: jh7110: Sync with Devkits repo To be compatible with the Devkits board. The code is ported from tag JH7110_DVK_515_v3.9.3 of Devkits repo. Signed-off-by: Hal Feng --- arch/riscv/dts/jh7110-u-boot.dtsi | 8 ++++++ arch/riscv/dts/jh7110.dtsi | 52 +++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/arch/riscv/dts/jh7110-u-boot.dtsi b/arch/riscv/dts/jh7110-u-boot.dtsi index e45b6cde3b..37586fdc15 100644 --- a/arch/riscv/dts/jh7110-u-boot.dtsi +++ b/arch/riscv/dts/jh7110-u-boot.dtsi @@ -129,3 +129,11 @@ &gmac0_rmii_refin { u-boot,dm-spl; }; + +&gpio { + u-boot,dm-spl; +}; + +&gpioa { + u-boot,dm-spl; +}; diff --git a/arch/riscv/dts/jh7110.dtsi b/arch/riscv/dts/jh7110.dtsi index de5289cff5..d8f62454fd 100644 --- a/arch/riscv/dts/jh7110.dtsi +++ b/arch/riscv/dts/jh7110.dtsi @@ -623,19 +623,6 @@ status = "disabled"; }; - i2c6: i2c@12060000 { - compatible = "snps,designware-i2c"; - reg = <0x0 0x12060000 0x0 0x10000>; - clocks = <&clkgen JH7110_I2C6_CLK_CORE>, - <&clkgen JH7110_I2C6_CLK_APB>; - clock-names = "ref", "pclk"; - resets = <&rstgen RSTN_U6_DW_I2C_APB>; - interrupts = <51>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - i2c0: i2c@10030000 { compatible = "snps,designware-i2c"; reg = <0x0 0x10030000 0x0 0x10000>; @@ -675,6 +662,32 @@ status = "disabled"; }; + i2c3: i2c@12030000 { + compatible = "snps,designware-i2c"; + reg = <0x0 0x12030000 0x0 0x10000>; + clocks = <&clkgen JH7110_I2C3_CLK_CORE>, + <&clkgen JH7110_I2C3_CLK_APB>; + clock-names = "ref", "pclk"; + resets = <&rstgen RSTN_U3_DW_I2C_APB>; + interrupts = <48>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c4: i2c@12040000 { + compatible = "snps,designware-i2c"; + reg = <0x0 0x12040000 0x0 0x10000>; + clocks = <&clkgen JH7110_I2C4_CLK_CORE>, + <&clkgen JH7110_I2C4_CLK_APB>; + clock-names = "ref", "pclk"; + resets = <&rstgen RSTN_U4_DW_I2C_APB>; + interrupts = <49>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + i2c5: i2c@12050000 { compatible = "snps,designware-i2c"; reg = <0x0 0x12050000 0x0 0x10000>; @@ -688,6 +701,19 @@ status = "disabled"; }; + i2c6: i2c@12060000 { + compatible = "snps,designware-i2c"; + reg = <0x0 0x12060000 0x0 0x10000>; + clocks = <&clkgen JH7110_I2C6_CLK_CORE>, + <&clkgen JH7110_I2C6_CLK_APB>; + clock-names = "ref", "pclk"; + resets = <&rstgen RSTN_U6_DW_I2C_APB>; + interrupts = <51>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + /* unremovable emmc as mmcblk0 */ sdio0: sdio0@16010000 { compatible = "snps,dw-mshc"; -- cgit v1.2.3 From 8d2695797ec60e86d42aff8c47e79c741b3b2542 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 9 Aug 2023 16:23:02 +0800 Subject: riscv: dts: Add StarFive JH7110 Devkits board device tree Add device tree for StarFive JH7110 Devkits board. The code is ported from tag JH7110_DVK_515_v3.9.3 of Devkits repo. Signed-off-by: Hal Feng --- arch/riscv/dts/Makefile | 1 + arch/riscv/dts/starfive_devkits-u-boot.dtsi | 29 +++ arch/riscv/dts/starfive_devkits.dts | 371 ++++++++++++++++++++++++++++ 3 files changed, 401 insertions(+) create mode 100644 arch/riscv/dts/starfive_devkits-u-boot.dtsi create mode 100644 arch/riscv/dts/starfive_devkits.dts diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index e8bcd0e23d..79679c91ad 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -7,6 +7,7 @@ dtb-$(CONFIG_TARGET_OPENPITON_RISCV64) += openpiton-riscv64.dtb dtb-$(CONFIG_TARGET_SIFIVE_UNLEASHED) += hifive-unleashed-a00.dtb dtb-$(CONFIG_TARGET_SIFIVE_UNMATCHED) += hifive-unmatched-a00.dtb dtb-$(CONFIG_TARGET_SIPEED_MAIX) += k210-maix-bit.dtb +dtb-$(CONFIG_TARGET_STARFIVE_DEVKITS) += starfive_devkits.dtb dtb-$(CONFIG_TARGET_STARFIVE_VISIONFIVE2) += starfive_visionfive2.dtb dtb-$(CONFIG_TARGET_STARFIVE_EVB) += starfive_evb.dtb diff --git a/arch/riscv/dts/starfive_devkits-u-boot.dtsi b/arch/riscv/dts/starfive_devkits-u-boot.dtsi new file mode 100644 index 0000000000..f508ab3554 --- /dev/null +++ b/arch/riscv/dts/starfive_devkits-u-boot.dtsi @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2022 StarFive Technology Co., Ltd. + */ + +#include "jh7110-u-boot.dtsi" +/ { + chosen { + stdout-path = "/soc/serial@10000000:115200"; + u-boot,dm-spl; + }; + + firmware { + spi0="/soc/qspi@11860000"; + u-boot,dm-spl; + }; + + config { + u-boot,dm-spl; + u-boot,spl-payload-offset = <0x100000>; /* loader2 @1044KB */ + }; + + memory@80000000 { + u-boot,dm-spl; + device_type = "memory"; + reg = <0x0 0x40000000 0x1 0x0>; + }; +}; + diff --git a/arch/riscv/dts/starfive_devkits.dts b/arch/riscv/dts/starfive_devkits.dts new file mode 100644 index 0000000000..489a8f90be --- /dev/null +++ b/arch/riscv/dts/starfive_devkits.dts @@ -0,0 +1,371 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2022 StarFive Technology Co., Ltd. + */ + +/dts-v1/; + +#include "jh7110.dtsi" +#include +#include +/ { + #address-cells = <2>; + #size-cells = <2>; + model = "StarFive JH7110 DevKits"; + compatible = "starfive,jh7110"; + + aliases { + spi0="/soc/spi@13010000"; + gpio0="/soc/gpio@13040000"; + ethernet0=&gmac0; + ethernet1=&gmac1; + mmc0=&sdio0; + mmc1=&sdio1; + i2c5=&i2c5; + }; + + chosen { + stdout-path = "/soc/serial@10000000:115200"; + starfive,boot-hart-id = <1>; + }; + + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x40000000 0x1 0x0>; + }; + + soc { + }; + + gpio-restart { + compatible = "gpio-restart"; + gpios = <&gpio 35 GPIO_ACTIVE_HIGH>; + }; +}; + +&cpu0 { + status = "okay"; +}; + +&clkgen { + clocks = <&osc>, <&gmac1_rmii_refin>, + <&stg_apb>, <&gmac0_rmii_refin>; + clock-names = "osc", "gmac1_rmii_refin", + "stg_apb", "gmac0_rmii_refin"; +}; + +&gpio { + status = "okay"; + gpio-controller; + + i2c2_pins: i2c2-0 { + i2c-pins { + pinmux = , + ; + bias-disable; /* external pull-up */ + input-enable; + input-schmitt-enable; + }; + }; + + i2c5_pins: i2c5-0 { + i2c-pins { + pinmux = , + ; + bias-disable; /* external pull-up */ + input-enable; + input-schmitt-enable; + }; + }; + + mmc0_pins: mmc0-pins { + mmc0-pins-rest { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + sdcard1_pins: sdcard1-pins { + sdcard1-pins0 { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + + sdcard1-pins1 { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins2 { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins3 { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins4 { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins5 { + pinmux = ; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + }; + + hdmi_pins: hdmi-0 { + i2c-pins { + pinmux = , + ; + bias-pull-up; + input-enable; + }; + + cec-pins { + pinmux = ; + bias-pull-up; + input-enable; + }; + + hpd-pins { + pinmux = ; + input-enable; + }; + }; +}; + +&i2c2 { + clock-frequency = <100000>; + i2c-sda-hold-time-ns = <300>; + i2c-sda-falling-time-ns = <510>; + i2c-scl-falling-time-ns = <510>; + auto_calc_scl_lhcnt; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + status = "okay"; + + seeed_panel: seeed_panel@45 { + compatible = "starfive,seeed"; + reg = <0x45>; + sel-gpios = <&ext_gpio 5 GPIO_ACTIVE_LOW>; + }; + + lt8911exb_i2c@29 { + compatible = "lontium,lt8911exb"; + reg = <0x29>; + reset-gpios = <&gpio 41 1>; + pwm-gpios = <&gpio 33 1>; + bl-gpios = <&ext_gpio 6 GPIO_ACTIVE_LOW>; + + }; +}; + +&i2c5 { + clock-frequency = <100000>; + i2c-sda-hold-time-ns = <300>; + i2c-sda-falling-time-ns = <510>; + i2c-scl-falling-time-ns = <510>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c5_pins>; + status = "okay"; + + pmic_axp15060: axp15060_reg@36 { + compatible = "stf,axp15060-regulator"; + reg = <0x36>; + }; + + eeprom@50 { + compatible = "atmel,24c04"; + reg = <0x50>; + pagesize = <16>; + }; + + ext_gpio: ext_gpio@74 { + compatible = "ti,tca9539"; + reg = <0x74>; + gpio-controller; + #gpio-cells = <2>; + }; +}; + +&sdio0 { + assigned-clocks = <&clkgen JH7110_SDIO0_CLK_SDCARD>; + assigned-clock-rates = <50000000>; + fifo-depth = <32>; + bus-width = <4>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; +}; + +&sdio1 { + assigned-clocks = <&clkgen JH7110_SDIO1_CLK_SDCARD>; + assigned-clock-rates = <50000000>; + fifo-depth = <32>; + bus-width = <4>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&sdcard1_pins>; +}; + +&gmac0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@0 { + rxc_dly_en = <0>; + rx_delay_sel = <0xb>; + tx_delay_sel_fe = <5>; + tx_delay_sel = <0xa>; + tx_inverted_10 = <0x1>; + tx_inverted_100 = <0x1>; + tx_inverted_1000 = <0x1>; + }; +}; + +&gmac1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + phy1: ethernet-phy@1 { + rgmii_sw_dr_2 = <0x0>; + rgmii_sw_dr = <0x3>; + rgmii_sw_dr_rxc = <0x7>; + tx_delay_sel_fe = <5>; + tx_delay_sel = <0>; + rxc_dly_en = <0>; + rx_delay_sel = <0x2>; + tx_inverted_10 = <0x1>; + tx_inverted_100 = <0x1>; + tx_inverted_1000 = <0x0>; + }; +}; + +&uart0 { + reg-offset = <0>; + current-speed = <115200>; + status = "okay"; +}; + +&gpioa { + status = "disabled"; +}; + +&usbdrd30 { + clocks = <&clkgen JH7110_USB_125M>, + <&clkgen JH7110_USB0_CLK_APP_125>, + <&clkgen JH7110_USB0_CLK_LPM>, + <&clkgen JH7110_USB0_CLK_STB>, + <&clkgen JH7110_USB0_CLK_USB_APB>, + <&clkgen JH7110_USB0_CLK_AXI>, + <&clkgen JH7110_USB0_CLK_UTMI_APB>, + <&clkgen JH7110_PCIE0_CLK_APB>; + clock-names = "125m","app","lpm","stb","apb","axi","utmi", "phy"; + resets = <&rstgen RSTN_U0_CDN_USB_PWRUP>, + <&rstgen RSTN_U0_CDN_USB_APB>, + <&rstgen RSTN_U0_CDN_USB_AXI>, + <&rstgen RSTN_U0_CDN_USB_UTMI_APB>, + <&rstgen RSTN_U0_PLDA_PCIE_APB>; + reset-names = "pwrup","apb","axi","utmi", "phy"; + starfive,usb2-only = <0>; + status = "okay"; +}; + +&usbdrd_cdns3 { + dr_mode = "unknown"; + dr_num_mode = <1>; +}; + +&timer { + status = "disabled"; +}; + +&wdog { + status = "disabled"; +}; + +&clkvout { + status = "okay"; +}; + +&pdm { + status = "disabled"; +}; + +&dc8200 { + status = "okay"; +}; +&mipi_dsi0 { + status = "okay"; + rockchip,panel = <&seeed_panel>; + data-lanes-num = <1>; + status = "okay"; +}; + +&hdmi{ + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_pins>; + status = "okay"; +}; + +&pcie1 { + power-gpios = <&ext_gpio 0 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + status = "okay"; +}; -- cgit v1.2.3 From d006806e64b0120df0c28272e4cb0c2e5c15bd9b Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 9 Aug 2023 16:28:35 +0800 Subject: configs: starfive: Add starfive_devkits_defconfig Add a defconfig file for StarFive JH7110 Devkits board. The code is ported from tag JH7110_DVK_515_v3.9.3 of Devkits repo. Signed-off-by: Hal Feng --- configs/starfive_devkits_defconfig | 171 +++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 configs/starfive_devkits_defconfig diff --git a/configs/starfive_devkits_defconfig b/configs/starfive_devkits_defconfig new file mode 100644 index 0000000000..26483b9690 --- /dev/null +++ b/configs/starfive_devkits_defconfig @@ -0,0 +1,171 @@ +CONFIG_RISCV=y +CONFIG_SPL_GPIO=y +CONFIG_SYS_MALLOC_F_LEN=0x10000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x10000 +CONFIG_ENV_OFFSET=0xF0000 +CONFIG_SPL_DM_SPI=y +CONFIG_DEFAULT_DEVICE_TREE="starfive_devkits" +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_SPL=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI_SUPPORT=y +CONFIG_BUILD_TARGET="" +CONFIG_TARGET_STARFIVE_DEVKITS=y +CONFIG_SPL_OPENSBI_LOAD_ADDR=0x40000000 +CONFIG_NR_CPUS=5 +CONFIG_FPGA_GMAC_SPEED_AUTO=y +CONFIG_STARFIVE_JH7110_L2CC_FLUSH=y +CONFIG_ARCH_RV64I=y +CONFIG_CMODEL_MEDANY=y +CONFIG_RISCV_SMODE=y +CONFIG_SHOW_REGS=y +# CONFIG_OF_BOARD_FIXUP is not set +# CONFIG_ANDROID_BOOT_IMAGE is not set +CONFIG_FIT=y +CONFIG_SUPPORT_RAW_INITRD=y +CONFIG_QSPI_BOOT=y +CONFIG_SD_BOOT=y +CONFIG_SPI_BOOT=y +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="console=tty1 console=ttyS0,115200 debug rootwait earlycon=sbi" +CONFIG_USE_BOOTCOMMAND=y +CONFIG_BOOTCOMMAND="run sdk_boot_env; run distro_boot_env;" +CONFIG_USE_PREBOOT=y +CONFIG_PREBOOT="run chipa_set_uboot" +CONFIG_DEFAULT_FDT_FILE="starfive/jh7110-devkits.dtb" +CONFIG_LOG_MAX_LEVEL=4 +CONFIG_SPL_LOG=y +CONFIG_DISPLAY_CPUINFO=y +CONFIG_DISPLAY_BOARDINFO=y +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_BOARD_LATE_INIT=y +CONFIG_MISC_INIT_R=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x2 +CONFIG_SPL_DM_SPI_FLASH=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="StarFive # " +CONFIG_CMD_CONFIG=y +CONFIG_CMD_ERASEENV=y +CONFIG_CMD_EEPROM=y +CONFIG_SYS_I2C_EEPROM_BUS=5 +CONFIG_SYS_EEPROM_SIZE=512 +CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=4 +CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=5 +CONFIG_CMD_GPT_RENAME=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MISC=y +CONFIG_CMD_PART=y +CONFIG_CMD_PCI=y +CONFIG_CMD_USB=y +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_SYSBOOT=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FS_UUID=y +CONFIG_CMD_LOG=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_VERSION_VARIABLE=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_CLK_COMPOSITE_CCF=y +CONFIG_CLK_CCF=y +CONFIG_CLK_COMPOSITE_CCF=y +CONFIG_SPL_CLK_JH7110=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x60000000 +CONFIG_FASTBOOT_BUF_SIZE=0x80000000 +CONFIG_FASTBOOT_USB_DEV=1 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_UUU_SUPPORT=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_MMC_BOOT_SUPPORT=y +CONFIG_FASTBOOT_MMC_USER_SUPPORT=y +CONFIG_FASTBOOT_CMD_OEM_FORMAT=y +CONFIG_FASTBOOT_STARFIVE_MAX_BLK_WRITE=8192 +# CONFIG_STARFIVE_GPIO is not set +CONFIG_DM_PCA953X=y +CONFIG_SYS_I2C_DW=y +CONFIG_I2C_EEPROM=y +CONFIG_SYS_I2C_EEPROM_ADDR=0x50 +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_SPL_MMC_HS200_SUPPORT=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_SNPS=y +CONFIG_SF_DEFAULT_MODE=0x0 +CONFIG_SF_DEFAULT_SPEED=100000000 +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_PHY_MARVELL=y +CONFIG_PHY_MICREL=y +CONFIG_PHY_MICREL_KSZ90X1=y +# CONFIG_PHY_MSCC is not set +CONFIG_PHY_YUTAI=y +CONFIG_DWC_ETH_QOS=y +CONFIG_DWC_ETH_QOS_STARFIVE=y +CONFIG_RGMII=y +CONFIG_RTL8169=y +CONFIG_NVME=y +CONFIG_PCI=y +CONFIG_DM_PCI_COMPAT=y +CONFIG_PCI_REGION_MULTI_ENTRY=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_SPL_PINCTRL=y +CONFIG_SPL_PINCONF=y +CONFIG_SPL_PINCTRL_STARFIVE=y +CONFIG_SPL_PINCTRL_STARFIVE_JH7110=y +CONFIG_PINCTRL_STARFIVE=y +CONFIG_PINCTRL_STARFIVE_JH7110=y +CONFIG_POWER_DOMAIN=y +CONFIG_STARFIVE_POWER_DOMAIN=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_STARFIVE=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_STARFIVE=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +# CONFIG_RAM_SIFIVE is not set +CONFIG_SPL_STARFIVE_DDR=y +CONFIG_DM_RESET=y +CONFIG_SPECIFY_CONSOLE_INDEX=y +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_SBI=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_USB_CDNS3_HOST=y +# CONFIG_USB_CDNS3_TI is not set +CONFIG_USB_CDNS3_STARFIVE=y +CONFIG_USB_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VENDOR_NUM=0x18d1 +CONFIG_USB_GADGET_PRODUCT_NUM=0x0d02 +CONFIG_DM_VIDEO=y +CONFIG_VIDEO_PCI_DEFAULT_FB_SIZE=0x8000000 +CONFIG_VIDEO_COPY=y +CONFIG_VIDEO_LCD_STARFIVE_SEEED=y +CONFIG_VIDEO_SF_MIPI2EDP=y +CONFIG_DISPLAY=y +CONFIG_NXP_TDA19988=y +CONFIG_VIDEO_BRIDGE=y +CONFIG_VIDEO_STARFIVE=y +CONFIG_DISPLAY_STARFIVE_EDP=y +CONFIG_DISPLAY_STARFIVE_LVDS=y +CONFIG_DISPLAY_STARFIVE_HDMI=y +CONFIG_DISPLAY_STARFIVE_MIPI=y +CONFIG_VIDEO_NW_MIPI_DSI=y +CONFIG_OF_LIBFDT_OVERLAY=y +# CONFIG_EFI_UNICODE_COLLATION_PROTOCOL2 is not set +# CONFIG_EFI_LOAD_FILE2_INITRD is not set -- cgit v1.2.3 From 65a9e044bdbec0119d78efe1ab5464614bb2a698 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Tue, 22 Aug 2023 09:58:05 +0800 Subject: common: board_r: Enable set_pmic() The code is ported from tag JH7110_DVK_515_v3.9.3 of Devkits repo. Signed-off-by: ziv.xu Signed-off-by: Hal Feng --- common/board_r.c | 3 +++ include/init.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/common/board_r.c b/common/board_r.c index 630c2451a2..e75efc97ad 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -689,6 +689,9 @@ static init_fnc_t init_sequence_r[] = { #endif #ifdef CONFIG_ARCH_EARLY_INIT_R arch_early_init_r, +#endif +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_DEVKITS) + set_pmic, #endif power_init_board, #ifdef CONFIG_MTD_NOR_FLASH diff --git a/include/init.h b/include/init.h index c781789e36..b29b6ecd98 100644 --- a/include/init.h +++ b/include/init.h @@ -267,6 +267,9 @@ int cpu_init_r(void); int last_stage_init(void); int mac_read_from_eeprom(void); int set_cpu_clk_info(void); +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_DEVKITS) +int set_pmic(void); +#endif int update_flash_size(int flash_size); int arch_early_init_r(void); int misc_init_r(void); -- cgit v1.2.3 From 96ee0021ad55ae469d3f337f1995084c11b88c57 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Tue, 22 Aug 2023 11:10:23 +0800 Subject: clk: starfive: jh7110: Add full i2c clocks Correct the parent of i2c clocks and add full i2c clocks. The code mainly is ported from tag JH7110_DVK_515_v3.9.3 of Devkits repo. Signed-off-by: Hal Feng --- drivers/clk/starfive/clk-jh7110.c | 70 +++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/drivers/clk/starfive/clk-jh7110.c b/drivers/clk/starfive/clk-jh7110.c index 249eb130f1..5311633c4f 100644 --- a/drivers/clk/starfive/clk-jh7110.c +++ b/drivers/clk/starfive/clk-jh7110.c @@ -425,6 +425,58 @@ static int jh7110_clk_init(struct udevice *dev) starfive_clk_divider(priv->sys, "nocstg_bus", "bus_root", SYS_OFFSET(JH7110_NOCSTG_BUS), 3)); + + /*I2C*/ + clk_dm(JH7110_I2C0_CLK_APB, + starfive_clk_gate(priv->sys, + "u0_dw_i2c_clk_apb", "apb0", + SYS_OFFSET(JH7110_I2C0_CLK_APB))); + clk_dm(JH7110_I2C0_CLK_CORE, + starfive_clk_fix_factor(priv->sys, + "u0_dw_i2c_clk_core", "u0_dw_i2c_clk_apb", 1, 1)); + clk_dm(JH7110_I2C1_CLK_APB, + starfive_clk_gate(priv->sys, + "u1_dw_i2c_clk_apb", "apb0", + SYS_OFFSET(JH7110_I2C1_CLK_APB))); + clk_dm(JH7110_I2C1_CLK_CORE, + starfive_clk_fix_factor(priv->sys, + "u1_dw_i2c_clk_core", "u1_dw_i2c_clk_apb", 1, 1)); + clk_dm(JH7110_I2C2_CLK_APB, + starfive_clk_gate(priv->sys, + "u2_dw_i2c_clk_apb", "apb0", + SYS_OFFSET(JH7110_I2C2_CLK_APB))); + clk_dm(JH7110_I2C2_CLK_CORE, + starfive_clk_fix_factor(priv->sys, + "u2_dw_i2c_clk_core", "u2_dw_i2c_clk_apb", 1, 1)); + clk_dm(JH7110_I2C3_CLK_APB, + starfive_clk_gate(priv->sys, + "u3_dw_i2c_clk_apb", "apb12", + SYS_OFFSET(JH7110_I2C3_CLK_APB))); + clk_dm(JH7110_I2C3_CLK_CORE, + starfive_clk_fix_factor(priv->sys, + "u3_dw_i2c_clk_core", "u3_dw_i2c_clk_apb", 1, 1)); + clk_dm(JH7110_I2C4_CLK_APB, + starfive_clk_gate(priv->sys, + "u4_dw_i2c_clk_apb", "apb12", + SYS_OFFSET(JH7110_I2C4_CLK_APB))); + clk_dm(JH7110_I2C4_CLK_CORE, + starfive_clk_fix_factor(priv->sys, + "u4_dw_i2c_clk_core", "u4_dw_i2c_clk_apb", 1, 1)); + clk_dm(JH7110_I2C5_CLK_APB, + starfive_clk_gate(priv->sys, + "u5_dw_i2c_clk_apb", "apb12", + SYS_OFFSET(JH7110_I2C5_CLK_APB))); + clk_dm(JH7110_I2C5_CLK_CORE, + starfive_clk_fix_factor(priv->sys, + "u5_dw_i2c_clk_core", "u5_dw_i2c_clk_apb", 1, 1)); + clk_dm(JH7110_I2C6_CLK_APB, + starfive_clk_gate(priv->sys, + "u6_dw_i2c_clk_apb", "apb12", + SYS_OFFSET(JH7110_I2C6_CLK_APB))); + clk_dm(JH7110_I2C6_CLK_CORE, + starfive_clk_fix_factor(priv->sys, + "u6_dw_i2c_clk_core", "u6_dw_i2c_clk_apb", 1, 1)); + /*QSPI*/ clk_dm(JH7110_QSPI_CLK_AHB, starfive_clk_gate(priv->sys, @@ -699,24 +751,6 @@ static int jh7110_clk_init(struct udevice *dev) "u0_dom_vout_top_clk_mipiphy_ref", "osc", SYS_OFFSET(JH7110_MCLK_INNER), 2)); - /*i2c5*/ - clk_dm(JH7110_I2C5_CLK_APB, - starfive_clk_gate(priv->sys, - "u5_dw_i2c_clk_apb", "apb0", - SYS_OFFSET(JH7110_I2C5_CLK_APB))); - clk_dm(JH7110_I2C5_CLK_CORE, - starfive_clk_fix_factor(priv->sys, - "u5_dw_i2c_clk_core", "u5_dw_i2c_clk_apb", 1, 1)); - - /*i2c2*/ - clk_dm(JH7110_I2C2_CLK_APB, - starfive_clk_gate(priv->sys, - "u2_dw_i2c_clk_apb", "apb0", - SYS_OFFSET(JH7110_I2C2_CLK_APB))); - clk_dm(JH7110_I2C2_CLK_CORE, - starfive_clk_fix_factor(priv->sys, - "u2_dw_i2c_clk_core", "u2_dw_i2c_clk_apb", 1, 1)); - /*pcie0*/ clk_dm(JH7110_PCIE0_CLK_TL, starfive_clk_gate(priv->stg, -- cgit v1.2.3 From da983c661a998a9ffd0a20445bdf3585b0380f43 Mon Sep 17 00:00:00 2001 From: Yanhong Wang Date: Mon, 8 May 2023 13:58:28 +0800 Subject: pinctrl: starfive: jh7110: Added suppport for pinctrl in SPL Added support for pinctrl driver in SPL. Signed-off-by: Yanhong Wang --- drivers/pinctrl/starfive/Kconfig | 15 +++++++++++++-- drivers/pinctrl/starfive/Makefile | 7 ++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/starfive/Kconfig b/drivers/pinctrl/starfive/Kconfig index 4a3afadec3..1b859c863e 100644 --- a/drivers/pinctrl/starfive/Kconfig +++ b/drivers/pinctrl/starfive/Kconfig @@ -1,8 +1,20 @@ # SPDX-License-Identifier: GPL-2.0-only +config SPL_PINCTRL_STARFIVE + bool "Support Pinctrl driver for StarFive SoC in SPL" + depends on SPL_PINCTRL_FULL && STARFIVE_JH7110 + help + Enable support pin control driver for StarFive SoC. + +config SPL_PINCTRL_STARFIVE_JH7110 + bool "Support Pinctrl and GPIO driver for StarFive JH7110 SoC in SPL" + depends on SPL_PINCTRL_STARFIVE + help + Enable support pinctrl and gpio driver for StarFive JH7110 in SPL. + config PINCTRL_STARFIVE bool "Pinctrl driver for StarFive SoC" - depends on PINCTRL_FULL + depends on PINCTRL_FULL && STARFIVE_JH7110 help Say yes here to support pin control on the StarFive RISC-V SoC. This also provides an interface to the GPIO pins not used by other @@ -14,4 +26,3 @@ config PINCTRL_STARFIVE_JH7110 depends on PINCTRL_STARFIVE help This selects the pinctrl driver for JH7110 starfive. - diff --git a/drivers/pinctrl/starfive/Makefile b/drivers/pinctrl/starfive/Makefile index 2eac219d36..a4a12069b3 100644 --- a/drivers/pinctrl/starfive/Makefile +++ b/drivers/pinctrl/starfive/Makefile @@ -1,9 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 # Core -obj-$(CONFIG_PINCTRL_STARFIVE) += pinctrl-starfive.o +obj-$(CONFIG_$(SPL_TPL_)PINCTRL_STARFIVE) += pinctrl-starfive.o # SoC Drivers -obj-$(CONFIG_PINCTRL_STARFIVE_JH7110) += pinctrl-jh7110-sys.o pinctrl-jh7110-aon.o - - - +obj-$(CONFIG_$(SPL_TPL_)PINCTRL_STARFIVE_JH7110) += pinctrl-jh7110-sys.o pinctrl-jh7110-aon.o -- cgit v1.2.3 From 9572aaa97604dfc8b46f778e63c15b5ecde34250 Mon Sep 17 00:00:00 2001 From: Mason Huo Date: Wed, 22 Mar 2023 13:33:31 +0800 Subject: pinctrl: starfive: Set up usb overcurrent signal For devkit HW design, there is not GPIO specific for the usb controller overcurrent signal. Config the sys iomux register to hardwire this signal, so that the usb controller can work normally. Signed-off-by: Mason Huo --- drivers/pinctrl/starfive/pinctrl-jh7110-sys.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/starfive/pinctrl-jh7110-sys.c b/drivers/pinctrl/starfive/pinctrl-jh7110-sys.c index 4e761641eb..13c1a81e92 100755 --- a/drivers/pinctrl/starfive/pinctrl-jh7110-sys.c +++ b/drivers/pinctrl/starfive/pinctrl-jh7110-sys.c @@ -376,10 +376,23 @@ const struct starfive_pinctrl_soc_info jh7110_sys_pinctrl_info = { static int jh7110_sys_pinctrl_probe(struct udevice *dev) { + u32 value; + int ret; struct starfive_pinctrl_soc_info *info = (struct starfive_pinctrl_soc_info *)dev_get_driver_data(dev); + struct starfive_pinctrl_priv *priv = dev_get_priv(dev); + + ret = starfive_pinctrl_probe(dev, info); + + /* Set up the usb controller overcurrent signal. */ + if (!ret) { + value = readl(priv->base + JH7110_SYS_GPI); + value &= ~(0x7f << 16); + value |= BIT(16); + writel(value, priv->base + JH7110_SYS_GPI); + } - return starfive_pinctrl_probe(dev, info); + return ret; } static const struct udevice_id jh7110_sys_pinctrl_ids[] = { -- cgit v1.2.3 From 4542b17102eac99de0eb8801392dfe57c30225d0 Mon Sep 17 00:00:00 2001 From: Yanhong Wang Date: Fri, 24 Mar 2023 10:28:48 +0800 Subject: net: phy: motorcomm: Move ytphy_of_config function call to startup function In order to dynamically adjust the phy clock delay configuration, so move ytphy_of_config function call to startup function. Signed-off-by: Yanhong Wang --- drivers/net/phy/motorcomm.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c index 94142a5a5a..6e8beac30e 100644 --- a/drivers/net/phy/motorcomm.c +++ b/drivers/net/phy/motorcomm.c @@ -96,6 +96,8 @@ static const struct ytphy_reg_field ytphy_rxden_grp[] = { { "rxc_dly_en", 1, 8, 0x1 } }; +static int ytphy_of_config(struct phy_device *phydev); + static int ytphy_read_ext(struct phy_device *phydev, u32 regnum) { int ret; @@ -194,6 +196,11 @@ static int ytphy_startup(struct phy_device *phydev) { int retval; + /*set delay config*/ + retval = ytphy_of_config(phydev); + if (retval < 0) + return retval; + retval = genphy_update_link(phydev); if (retval) return retval; @@ -256,6 +263,7 @@ static int ytphy_of_config(struct phy_device *phydev) cfg = ofnode_read_u32_default(node, ytphy_rxtxd_grp[i].name, ~0); + cfg = (cfg != -1) ? cfg : ytphy_rxtxd_grp[i].dflt; /*check the cfg overflow or not*/ @@ -369,10 +377,6 @@ static int yt8531_config(struct phy_device *phydev) ret = 0; genphy_config_aneg(phydev); - /*set delay config*/ - ret = ytphy_of_config(phydev); - if (ret < 0) - return ret; return 0; } -- cgit v1.2.3 From 10e12b90654622997c2564b956fefc824b4bc3c5 Mon Sep 17 00:00:00 2001 From: Mason Huo Date: Fri, 8 Sep 2023 18:30:59 +0800 Subject: pci: Add external gpio control for sideband signal For the devkit board, PCIe sideband signals are controled by external gpios, use gpio direct control instead of pinctrl. Signed-off-by: Mason Huo Signed-off-by: Hal Feng --- drivers/pci/pcie_starfive.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/pci/pcie_starfive.c b/drivers/pci/pcie_starfive.c index d02cffe9d4..d8de9a5997 100644 --- a/drivers/pci/pcie_starfive.c +++ b/drivers/pci/pcie_starfive.c @@ -103,6 +103,8 @@ struct starfive_pcie { int atr_table_num; int first_busno; + struct gpio_desc *power_gpio; + struct gpio_desc *reset_gpio; }; static int starfive_pcie_addr_valid(pci_dev_t bdf, int first_busno) @@ -371,22 +373,32 @@ static int starfive_pcie_init_port(struct udevice *dev) goto err_deassert_clk; } -#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_DEVKITS) ret = pinctrl_select_state(dev, "power-active"); if (ret) { - dev_err(dev, "Set power-acvtive pinctrl failed: %d\n", ret); - goto err_deassert_reset; + priv->power_gpio = + devm_gpiod_get_optional(dev, "power", GPIOD_IS_OUT); + if (IS_ERR(priv->power_gpio)) { + dev_err(dev, "Get power-acvtive gpio failed: %d\n", ret); + goto err_deassert_reset; + } + dm_gpio_set_value(priv->power_gpio, 1); } #endif ret = pinctrl_select_state(dev, "perst-active"); if (ret) { - dev_err(dev, "Set perst-active pinctrl failed: %d\n", ret); -#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) - goto err_release_power_pin; + priv->reset_gpio = + devm_gpiod_get_optional(dev, "reset", GPIOD_IS_OUT); + if (IS_ERR(priv->reset_gpio)) { + dev_err(dev, "Set perst-active gpio failed: %d\n", ret); +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_DEVKITS) + goto err_release_power_pin; #else - goto err_deassert_reset; + goto err_deassert_reset; #endif + } + dm_gpio_set_value(priv->reset_gpio, 1); } /* Disable physical functions except #0 */ @@ -447,13 +459,17 @@ static int starfive_pcie_init_port(struct udevice *dev) mdelay(100); ret = pinctrl_select_state(dev, "perst-default"); if (ret) { - dev_err(dev, "Set perst-default pinctrl failed: %d\n", ret); + if (priv->reset_gpio) { + dm_gpio_set_value(priv->reset_gpio, 0); + return 0; + } else + dev_err(dev, "Set perst-default pinctrl failed: %d\n", ret); return ret; } return 0; -#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_DEVKITS) err_release_power_pin: pinctrl_select_state(dev, "power-default"); #endif -- cgit v1.2.3 From 493ae680a34dc739736ac05171d387e0e967a1a5 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 16 Aug 2023 21:30:56 +0800 Subject: video: Add StarFive MIPI2EDP support The code is ported from tag JH7110_DVK_515_v3.9.3 of Devkits repo. Signed-off-by: Keith Zhao Signed-off-by: Shengyang Chen Signed-off-by: Hal Feng --- drivers/video/Kconfig | 9 + drivers/video/Makefile | 1 + drivers/video/starfive_edp.c | 1302 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1312 insertions(+) create mode 100644 drivers/video/starfive_edp.c diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 41d11e5daa..5116ade32a 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -439,6 +439,15 @@ config VIDEO_LCD_STARFIVE_SEEED Say Y here if you want to enable support for seeed 800X480 DSI video mode panel. +config VIDEO_SF_MIPI2EDP + bool "mipi to edp LCD panel support" + depends on DM_VIDEO + select VIDEO_MIPI_DSI + default n + help + Say Y here if you want to enable support for edp + 1920X1080 DSI video mode panel. + config VIDEO_LCD_SSD2828 bool "SSD2828 bridge chip" default n diff --git a/drivers/video/Makefile b/drivers/video/Makefile index e84280a04f..33066e2d7f 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o obj-$(CONFIG_VIDEO_LCD_ORISETECH_OTM8009A) += orisetech_otm8009a.o obj-$(CONFIG_VIDEO_LCD_RAYDIUM_RM68200) += raydium-rm68200.o obj-$(CONFIG_VIDEO_LCD_STARFIVE_SEEED) += raydium-rm68200-starfive.o +obj-$(CONFIG_VIDEO_SF_MIPI2EDP) += starfive_edp.o obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o obj-$(CONFIG_VIDEO_LCD_TDO_TL070WSH30) += tdo-tl070wsh30.o obj-$(CONFIG_VIDEO_MCDE_SIMPLE) += mcde_simple.o diff --git a/drivers/video/starfive_edp.c b/drivers/video/starfive_edp.c new file mode 100644 index 0000000000..67f63235b4 --- /dev/null +++ b/drivers/video/starfive_edp.c @@ -0,0 +1,1302 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 STMicroelectronics - All Rights Reserved + * Author(s): Yannick Fertre for STMicroelectronics. + * Philippe Cornu for STMicroelectronics. + * + * This edp panel driver is inspired from the Linux Kernel driver + * drivers/gpu/drm/panel/panel-raydium-edp.c. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define UART_DEBUG +#define TEST_EDID // read eDP panel EDID +#define EDP_2G7 +#define LINK_TRAIN_ENABLE +#define LT8911EXB_RST_PIN GPIO41 +#define BOE_14INCH_MAX_LANES 4 + +#define _1080P_eDP_Panel_ +#define _MIPI_Lane_ 4 // 3 /2 / 1 +#define _MIPI_data_PN_Swap_En 0xF0 +#define _MIPI_data_PN_Swap_Dis 0x00 +#define _MIPI_data_PN_ _MIPI_data_PN_Swap_Dis + +#define NO_SWAP 0x00 // 3210 default +#define MIPI_DATA_3210 0 // default +#define MIPI_DATA_0123 21 +#define MIPI_DATA_2103 20 + +#define MIPI_DATA_SEQ NO_SWAP + +#define _Nvid 0 // 0: 0x0080,default +static int Nvid_Val[] = { 0x0080, 0x0800 }; +#define usleep_range(a, b) udelay((b)) + +#ifdef _1080P_eDP_Panel_ + +#define eDP_lane 2 +#define PCR_PLL_PREDIV 0x40 + +static int MIPI_Timing[] = +{ 88, 44, 148, 1920, 2200, 4, 5, 36, 1080, 1125, 14850 }; // VESA + + +//#define _6bit_ // eDP panel Color Depth,262K color +#define _8bit_ // eDP panel Color Depth,16.7M color + +#endif + +enum { + hfp = 0, + hs, + hbp, + hact, + htotal, + vfp, + vs, + vbp, + vact, + vtotal, + pclk_10khz +}; + +u8 Read_DPCD010A = 0x00; +bool ScrambleMode = 0; +bool flag_mipi_on = 0; +#ifdef TEST_EDID // read eDP panel EDID +u8 EDID_DATA[128] = { 0 }; +u16 EDID_Timing[11] = { 0 }; +bool EDID_Reply = 0; +#endif + +static inline void sys_modl(void *addr, uint32_t mask, uint32_t val) +{ + uint32_t tmp; + + tmp = readl(addr); + tmp &= ~mask; + tmp |= (val & mask); + + debug("tmp 0x%x\n", tmp); + writel(tmp, addr); +} + +struct edp_panel_priv { + struct udevice *reg; + struct udevice *backlight; + + struct gpio_desc *reset_gpio; //reset + struct gpio_desc *pwm_gpio; //power + struct gpio_desc *bl_gpio; //backlight +}; + +static const struct display_timing default_timing = { + .pixelclock.typ = 148500000, + .hactive.typ = 1920, + .hfront_porch.typ = 88, + .hback_porch.typ = 148, + .hsync_len.typ = 44, + .vactive.typ = 1080, + .vfront_porch.typ = 34, + .vback_porch.typ = 6, + .vsync_len.typ = 5, +}; + +static int edp_panel_i2c_write(struct udevice *dev, uint addr, uint8_t data) +{ + uint8_t valb; + int err; + valb = data; + + err = dm_i2c_write(dev, addr, &valb, 1); + return err; +} + +static int edp_panel_i2c_read(struct udevice *dev, uint8_t addr, uint8_t *data) +{ + uint8_t valb; + int err; + + err = dm_i2c_read(dev, addr, &valb, 1); + if (err) + return err; + + *data = (int)valb; + return 0; +} + +static u8 LT8911EXB_IIC_Read_byte(struct udevice *dev, u8 reg) +{ + uint8_t valb; + int err; + + err = dm_i2c_read(dev, reg, &valb, 1); + if (err) + return err; + udelay(10); + + return (int)valb; + +} + +static void LT8911EXB_IIC_Write_byte(struct udevice *dev,u8 reg, u8 val) +{ + dm_i2c_write(dev, reg, &val, 1); + udelay(10); +} + +u8 boe_i2c_read(struct udevice *dev,u8 reg){ + return LT8911EXB_IIC_Read_byte(dev,reg); +} + +void boe_i2c_write(struct udevice *dev,u8 reg, u8 val){ + LT8911EXB_IIC_Write_byte(dev,reg,val); +} + +void Reset_LT8911EXB(struct udevice *dev) +{ + struct edp_panel_priv *priv = dev_get_priv(dev); + + dm_gpio_set_value(priv->pwm_gpio, 0); + dm_gpio_set_value(priv->bl_gpio, 0); + + dm_gpio_set_value(priv->reset_gpio, 0); + +} + +void LT8911EX_ChipID(struct udevice *dev) +{ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); + LT8911EXB_IIC_Write_byte(dev, 0x08, 0x7f ); + +#ifdef UART_DEBUG + debug( "\r\nLT8911EXB chip ID: 0x%x", LT8911EXB_IIC_Read_byte(dev, 0x00 ) ); + debug( ",0x%x", LT8911EXB_IIC_Read_byte(dev, 0x01 ) ); + debug( ",0x%x", LT8911EXB_IIC_Read_byte(dev, 0x02 ) ); +#endif +} + +void LT8911EXB_read_edid(struct udevice *dev) +{ +#ifdef TEST_EDID + u8 reg, i, j; +// bool aux_reply, aux_ack, aux_nack, aux_defer; + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xac ); + LT8911EXB_IIC_Write_byte(dev, 0x00, 0x20 ); //Soft Link train + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa6 ); + LT8911EXB_IIC_Write_byte(dev, 0x2a, 0x01 ); + + /*set edid offset addr*/ + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x40 ); //CMD + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x00 ); //addr[15:8] + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x50 ); //addr[7:0] + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x00 ); //data lenth + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x00 ); //data lenth + LT8911EXB_IIC_Write_byte(dev, 0x2c, 0x00 ); //start Aux read edid + +#ifdef UART_DEBUG + debug( "\r\n" ); + debug( "\r\nRead eDP EDID......" ); +#endif + + mdelay( 20 ); //more than 10ms + reg = LT8911EXB_IIC_Read_byte(dev, 0x25); + + debug( "\r\nRead eDP EDID.reg = %02x.....\n", reg); + if( ( reg & 0x0f ) == 0x0c ) + { + for( j = 0; j < 8; j++ ) + { + if( j == 7 ) + { + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x10 ); //MOT + }else + { + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x50 ); + } + + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x50 ); + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x0f ); + LT8911EXB_IIC_Write_byte(dev, 0x2c, 0x00 ); //start Aux read edid + mdelay( 50 ); //more than 50ms + + if( LT8911EXB_IIC_Read_byte(dev, 0x39 ) == 0x31 ) + { + LT8911EXB_IIC_Read_byte(dev, 0x2b ); + for( i = 0; i < 16; i++ ) + { + EDID_DATA[j * 16 + i] = LT8911EXB_IIC_Read_byte(dev, 0x2b ); + } + + EDID_Reply = 1; + }else + { + EDID_Reply = 0; +#ifdef UART_DEBUG + debug( "\r\nno_reply" ); + debug( "\r\n" ); +#endif + debug("\r\n*************End***************"); + return; + } + } + +#ifdef UART_DEBUG + + for( i = 0; i < 128; i++ ) //print edid data + { + if( ( i % 16 ) == 0 ) + { + debug( "\r\n" ); + } + debug( "%d, ", EDID_DATA[i] ); + } + + EDID_Timing[hfp] = ( ( EDID_DATA[0x41] & 0xC0 ) * 4 + EDID_DATA[0x3e] ); + + EDID_Timing[hs] = ( ( EDID_DATA[0x41] & 0x30 ) * 16 + EDID_DATA[0x3f] ); + + EDID_Timing[hbp] = ( ( ( EDID_DATA[0x3a] & 0x0f ) * 0x100 + EDID_DATA[0x39] ) - ( ( EDID_DATA[0x41] & 0x30 ) * 16 + EDID_DATA[0x3f] ) - ( ( EDID_DATA[0x41] & 0xC0 ) * 4 + EDID_DATA[0x3e] ) ); + + EDID_Timing[hact] = ( ( EDID_DATA[0x3a] & 0xf0 ) * 16 + EDID_DATA[0x38] ); + + EDID_Timing[htotal] = ( ( EDID_DATA[0x3a] & 0xf0 ) * 16 + EDID_DATA[0x38] + ( ( EDID_DATA[0x3a] & 0x0f ) * 0x100 + EDID_DATA[0x39] ) ); + + EDID_Timing[vfp] = ( ( EDID_DATA[0x41] & 0x0c ) * 4 + ( EDID_DATA[0x40] & 0xf0 ) / 16 ); + + EDID_Timing[vs] = ( ( EDID_DATA[0x41] & 0x03 ) * 16 + (EDID_DATA[0x40] & 0x0f) ); + + EDID_Timing[vbp] = ( ( ( EDID_DATA[0x3d] & 0x03 ) * 0x100 + EDID_DATA[0x3c] ) - ( ( EDID_DATA[0x41] & 0x03 ) * 16 + ( EDID_DATA[0x40] & 0x0f ) ) - ( ( EDID_DATA[0x41] & 0x0c ) * 4 + ( EDID_DATA[0x40] & 0xf0 ) / 16 ) ); + + EDID_Timing[vact] = ( ( EDID_DATA[0x3d] & 0xf0 ) * 16 + EDID_DATA[0x3b] ); + + EDID_Timing[vtotal] = ( ( EDID_DATA[0x3d] & 0xf0 ) * 16 + EDID_DATA[0x3b] + ( ( EDID_DATA[0x3d] & 0x03 ) * 0x100 + EDID_DATA[0x3c] ) ); + + EDID_Timing[pclk_10khz] = ( EDID_DATA[0x37] * 0x100 + EDID_DATA[0x36] ); +#endif + } + + return; + +#endif +} + +void LT8911EXB_MIPI_Video_Timing(struct udevice *dev) // ( struct video_timing *video_format ) +{ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xd0 ); + LT8911EXB_IIC_Write_byte(dev, 0x0d, (u8)( MIPI_Timing[vtotal] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x0e, (u8)( MIPI_Timing[vtotal] % 256 ) ); //vtotal + LT8911EXB_IIC_Write_byte(dev, 0x0f, (u8)( MIPI_Timing[vact] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x10, (u8)( MIPI_Timing[vact] % 256 ) ); //vactive + + LT8911EXB_IIC_Write_byte(dev, 0x11, (u8)( MIPI_Timing[htotal] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x12, (u8)( MIPI_Timing[htotal] % 256 ) ); //htotal + LT8911EXB_IIC_Write_byte(dev, 0x13, (u8)( MIPI_Timing[hact] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x14, (u8)( MIPI_Timing[hact] % 256 ) ); //hactive + + LT8911EXB_IIC_Write_byte(dev, 0x15, (u8)( MIPI_Timing[vs] % 256 ) ); //vsa + LT8911EXB_IIC_Write_byte(dev, 0x16, (u8)( MIPI_Timing[hs] % 256 ) ); //hsa + LT8911EXB_IIC_Write_byte(dev, 0x17, (u8)( MIPI_Timing[vfp] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x18, (u8)( MIPI_Timing[vfp] % 256 ) ); //vfp + + LT8911EXB_IIC_Write_byte(dev, 0x19, (u8)( MIPI_Timing[hfp] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x1a, (u8)( MIPI_Timing[hfp] % 256 ) ); //hfp +} + +void LT8911EXB_eDP_Video_cfg(struct udevice *dev) // ( struct video_timing *video_format ) +{ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa8 ); + LT8911EXB_IIC_Write_byte(dev, 0x2d, 0x88 ); // MSA from register + +#ifdef _Msa_Active_Only_ + LT8911EXB_IIC_Write_byte(dev, 0x05, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x06, 0x00 ); //htotal + LT8911EXB_IIC_Write_byte(dev, 0x07, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x08, 0x00 ); //h_start + + LT8911EXB_IIC_Write_byte(dev, 0x09, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x0a, 0x00 ); //hsa + LT8911EXB_IIC_Write_byte(dev, 0x0b, (u8)( MIPI_Timing[hact] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x0c, (u8)( MIPI_Timing[hact] % 256 ) ); //hactive + + LT8911EXB_IIC_Write_byte(dev, 0x0d, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x0e, 0x00 ); //vtotal + + LT8911EXB_IIC_Write_byte(dev, 0x11, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x12, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x15, (u8)( MIPI_Timing[vact] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x16, (u8)( MIPI_Timing[vact] % 256 ) ); //vactive + +#else + + LT8911EXB_IIC_Write_byte(dev, 0x05, (u8)( MIPI_Timing[htotal] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x06, (u8)( MIPI_Timing[htotal] % 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x07, (u8)( ( MIPI_Timing[hs] + MIPI_Timing[hbp] ) / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x08, (u8)( ( MIPI_Timing[hs] + MIPI_Timing[hbp] ) % 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x09, (u8)( MIPI_Timing[hs] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x0a, (u8)( MIPI_Timing[hs] % 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x0b, (u8)( MIPI_Timing[hact] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x0c, (u8)( MIPI_Timing[hact] % 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x0d, (u8)( MIPI_Timing[vtotal] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x0e, (u8)( MIPI_Timing[vtotal] % 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x11, (u8)( ( MIPI_Timing[vs] + MIPI_Timing[vbp] ) / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x12, (u8)( ( MIPI_Timing[vs] + MIPI_Timing[vbp] ) % 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x14, (u8)( MIPI_Timing[vs] % 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x15, (u8)( MIPI_Timing[vact] / 256 ) ); + LT8911EXB_IIC_Write_byte(dev, 0x16, (u8)( MIPI_Timing[vact] % 256 ) ); +#endif +} + +void LT8911EXB_init(struct udevice *dev) +{ + u8 i; + u8 pcr_pll_postdiv; + u8 pcr_m; + u16 Temp16; + + /* init */ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0x08, 0x7f ); // i2c over aux issue + LT8911EXB_IIC_Write_byte(dev, 0x49, 0xff ); // enable 0x87xx + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x82 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0x5a, 0x0e ); // GPIO test output + + //for power consumption// + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); + LT8911EXB_IIC_Write_byte(dev, 0x05, 0x06 ); + LT8911EXB_IIC_Write_byte(dev, 0x43, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x44, 0x1f ); + LT8911EXB_IIC_Write_byte(dev, 0x45, 0xf7 ); + LT8911EXB_IIC_Write_byte(dev, 0x46, 0xf6 ); + LT8911EXB_IIC_Write_byte(dev, 0x49, 0x7f ); + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x82 ); +#if ( eDP_lane == 2 ) + { + LT8911EXB_IIC_Write_byte(dev, 0x12, 0x33 ); + } +#elif ( eDP_lane == 1 ) + { + LT8911EXB_IIC_Write_byte(dev, 0x12, 0x11 ); + } +#endif + + /* mipi Rx analog */ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x82 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0x32, 0x51 ); + LT8911EXB_IIC_Write_byte(dev, 0x35, 0x22 ); //EQ current 0x22/0x42/0x62/0x82/0xA2/0xC2/0xe2 + LT8911EXB_IIC_Write_byte(dev, 0x3a, 0x77 ); //EQ 12.5db + LT8911EXB_IIC_Write_byte(dev, 0x3b, 0x77 ); //EQ 12.5db + + LT8911EXB_IIC_Write_byte(dev, 0x4c, 0x0c ); + LT8911EXB_IIC_Write_byte(dev, 0x4d, 0x00 ); + + /* dessc_pcr pll analog */ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x82 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0x6a, 0x40 ); + LT8911EXB_IIC_Write_byte(dev, 0x6b, PCR_PLL_PREDIV ); + + Temp16 = MIPI_Timing[pclk_10khz]; + + if( MIPI_Timing[pclk_10khz] < 8800 ) + { + LT8911EXB_IIC_Write_byte(dev, 0x6e, 0x82 ); //0x44:pre-div = 2 ,pixel_clk=44~ 88MHz + pcr_pll_postdiv = 0x08; + }else + if( MIPI_Timing[pclk_10khz] < 17600 ) + { + LT8911EXB_IIC_Write_byte(dev, 0x6e, 0x81 ); //0x40:pre-div = 1, pixel_clk =88~176MHz + pcr_pll_postdiv = 0x04; + }else + { + LT8911EXB_IIC_Write_byte(dev, 0x6e, 0x80 ); //0x40:pre-div = 0, pixel_clk =176~200MHz + pcr_pll_postdiv = 0x02; + } + + pcr_m = (u8)( Temp16 * pcr_pll_postdiv / 25 / 100 ); + + /* dessc pll digital */ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x85 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0xa9, 0x31 ); + LT8911EXB_IIC_Write_byte(dev, 0xaa, 0x17 ); + LT8911EXB_IIC_Write_byte(dev, 0xab, 0xba ); + LT8911EXB_IIC_Write_byte(dev, 0xac, 0xe1 ); + LT8911EXB_IIC_Write_byte(dev, 0xad, 0x47 ); + LT8911EXB_IIC_Write_byte(dev, 0xae, 0x01 ); + LT8911EXB_IIC_Write_byte(dev, 0xae, 0x11 ); + + /* Digital Top */ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x85 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0xc0, 0x01 ); //select mipi Rx +#ifdef _6bit_ + LT8911EXB_IIC_Write_byte(dev, 0xb0, 0xd0 ); //enable dither +#else + LT8911EXB_IIC_Write_byte(dev, 0xb0, 0x00 ); // disable dither +#endif + + /* mipi Rx Digital */ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xd0 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0x00, _MIPI_data_PN_ + _MIPI_Lane_ % 4 ); // 0: 4 Lane / 1: 1 Lane / 2 : 2 Lane / 3: 3 Lane + LT8911EXB_IIC_Write_byte(dev, 0x02, 0x08 ); //settle + LT8911EXB_IIC_Write_byte(dev, 0x03, MIPI_DATA_SEQ ); // default is 0x00 + LT8911EXB_IIC_Write_byte(dev, 0x08, 0x00 ); +// LT8911EXB_IIC_Write_byte(dev, 0x0a, 0x12 ); //pcr mode + + LT8911EXB_IIC_Write_byte(dev, 0x0c, 0x80 ); //fifo position + LT8911EXB_IIC_Write_byte(dev, 0x1c, 0x80 ); //fifo position + + // hs mode:MIPI行采样;vs mode:MIPI帧采样 + LT8911EXB_IIC_Write_byte(dev, 0x24, 0x70 ); // 0x30 [3:0] line limit //pcr mode( de hs vs) + + LT8911EXB_IIC_Write_byte(dev, 0x31, 0x0a ); + + /*stage1 hs mode*/ + LT8911EXB_IIC_Write_byte(dev, 0x25, 0x90 ); // 0x80 // line limit + LT8911EXB_IIC_Write_byte(dev, 0x2a, 0x3a ); // 0x04 // step in limit + LT8911EXB_IIC_Write_byte(dev, 0x21, 0x4f ); // hs_step + LT8911EXB_IIC_Write_byte(dev, 0x22, 0xff ); + + /*stage2 de mode*/ + LT8911EXB_IIC_Write_byte(dev, 0x0a, 0x02 ); //de adjust pre line + LT8911EXB_IIC_Write_byte(dev, 0x38, 0x02 ); //de_threshold 1 + LT8911EXB_IIC_Write_byte(dev, 0x39, 0x04 ); //de_threshold 2 + LT8911EXB_IIC_Write_byte(dev, 0x3a, 0x08 ); //de_threshold 3 + LT8911EXB_IIC_Write_byte(dev, 0x3b, 0x10 ); //de_threshold 4 + + LT8911EXB_IIC_Write_byte(dev, 0x3f, 0x04 ); //de_step 1 + LT8911EXB_IIC_Write_byte(dev, 0x40, 0x08 ); //de_step 2 + LT8911EXB_IIC_Write_byte(dev, 0x41, 0x10 ); //de_step 3 + LT8911EXB_IIC_Write_byte(dev, 0x42, 0x60 ); //de_step 4 + + /*stage2 hs mode*/ + LT8911EXB_IIC_Write_byte(dev, 0x1e, 0x0A );//LT8911EXB_IIC_Write_byte(dev, 0x1e, 0x01 ); // 0x11 + LT8911EXB_IIC_Write_byte(dev, 0x23, 0xf0 ); // 0x80 // + + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x80 ); // 0xa0 + +#ifdef _Test_Pattern_ + LT8911EXB_IIC_Write_byte(dev, 0x26, ( pcr_m | 0x80 ) ); +#else + + LT8911EXB_IIC_Write_byte(dev, 0x26, pcr_m ); + +#endif + + LT8911EXB_MIPI_Video_Timing(dev); //defualt setting is 1080P + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0x03, 0x7b ); //PCR reset + LT8911EXB_IIC_Write_byte(dev, 0x03, 0xff ); + +#ifdef EDP_2G7 + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x87 ); + LT8911EXB_IIC_Write_byte(dev, 0x19, 0x31 ); + LT8911EXB_IIC_Write_byte(dev, 0x1a, 0x36 ); // sync m + LT8911EXB_IIC_Write_byte(dev, 0x1b, 0x00 ); // sync_k [7:0] + LT8911EXB_IIC_Write_byte(dev, 0x1c, 0x00 ); // sync_k [13:8] + + // txpll Analog + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x82 ); + LT8911EXB_IIC_Write_byte(dev, 0x09, 0x00 ); // div hardware mode, for ssc. + +// LT8911EXB_IIC_Write_byte(dev, 0x01, 0x18 );// default : 0x18 + LT8911EXB_IIC_Write_byte(dev, 0x02, 0x42 ); + LT8911EXB_IIC_Write_byte(dev, 0x03, 0x00 ); // txpll en = 0 + LT8911EXB_IIC_Write_byte(dev, 0x03, 0x01 ); // txpll en = 1 +// LT8911EXB_IIC_Write_byte(dev, 0x04, 0x3a );// default : 0x3A + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x87 ); + LT8911EXB_IIC_Write_byte(dev, 0x0c, 0x10 ); // cal en = 0 + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); + LT8911EXB_IIC_Write_byte(dev, 0x09, 0xfc ); + LT8911EXB_IIC_Write_byte(dev, 0x09, 0xfd ); + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x87 ); + LT8911EXB_IIC_Write_byte(dev, 0x0c, 0x11 ); // cal en = 1 + + // ssc + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x87 ); + LT8911EXB_IIC_Write_byte(dev, 0x13, 0x83 ); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0x41 ); + LT8911EXB_IIC_Write_byte(dev, 0x16, 0x0a ); + LT8911EXB_IIC_Write_byte(dev, 0x18, 0x0a ); + LT8911EXB_IIC_Write_byte(dev, 0x19, 0x33 ); +#endif + +#ifdef _eDP_1G62_ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x87 ); + LT8911EXB_IIC_Write_byte(dev, 0x19, 0x31 ); + LT8911EXB_IIC_Write_byte(dev, 0x1a, 0x20 ); // sync m + LT8911EXB_IIC_Write_byte(dev, 0x1b, 0x19 ); // sync_k [7:0] + LT8911EXB_IIC_Write_byte(dev, 0x1c, 0x99 ); // sync_k [13:8] + + // txpll Analog + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x82 ); + LT8911EXB_IIC_Write_byte(dev, 0x09, 0x00 ); // div hardware mode, for ssc. + // LT8911EXB_IIC_Write_byte(dev, 0x01, 0x18 );// default : 0x18 + LT8911EXB_IIC_Write_byte(dev, 0x02, 0x42 ); + LT8911EXB_IIC_Write_byte(dev, 0x03, 0x00 ); // txpll en = 0 + LT8911EXB_IIC_Write_byte(dev, 0x03, 0x01 ); // txpll en = 1 + // LT8911EXB_IIC_Write_byte(dev, 0x04, 0x3a );// default : 0x3A + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x87 ); + LT8911EXB_IIC_Write_byte(dev, 0x0c, 0x10 ); // cal en = 0 + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); + LT8911EXB_IIC_Write_byte(dev, 0x09, 0xfc ); + LT8911EXB_IIC_Write_byte(dev, 0x09, 0xfd ); + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x87 ); + LT8911EXB_IIC_Write_byte(dev, 0x0c, 0x11 ); // cal en = 1 + + //ssc + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x87 ); + LT8911EXB_IIC_Write_byte(dev, 0x13, 0x83 ); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0x41 ); + LT8911EXB_IIC_Write_byte(dev, 0x16, 0x0a ); + LT8911EXB_IIC_Write_byte(dev, 0x18, 0x0a ); + LT8911EXB_IIC_Write_byte(dev, 0x19, 0x33 ); +#endif + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x87 ); + + for( i = 0; i < 5; i++ ) //Check Tx PLL + { + mdelay( 5 ); + if( LT8911EXB_IIC_Read_byte(dev, 0x37 ) & 0x02 ) + { + debug( "\r\nLT8911 tx pll locked" ); + break; + }else + { + debug( "\r\nLT8911 tx pll unlocked" ); + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); + LT8911EXB_IIC_Write_byte(dev, 0x09, 0xfc ); + LT8911EXB_IIC_Write_byte(dev, 0x09, 0xfd ); + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x87 ); + LT8911EXB_IIC_Write_byte(dev, 0x0c, 0x10 ); + LT8911EXB_IIC_Write_byte(dev, 0x0c, 0x11 ); + } + } + + // AUX reset + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0x07, 0xfe ); + LT8911EXB_IIC_Write_byte(dev, 0x07, 0xff ); + LT8911EXB_IIC_Write_byte(dev, 0x0a, 0xfc ); + LT8911EXB_IIC_Write_byte(dev, 0x0a, 0xfe ); + + /* tx phy */ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x82 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0x11, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x13, 0x10 ); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0x0c ); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0x08 ); + LT8911EXB_IIC_Write_byte(dev, 0x13, 0x20 ); + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x82 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0x0e, 0x35 ); +// LT8911EXB_IIC_Write_byte(dev, 0x12, 0xff ); +// LT8911EXB_IIC_Write_byte(dev, 0xff, 0x80 ); +// LT8911EXB_IIC_Write_byte(dev, 0x40, 0x22 ); + + /*eDP Tx Digital */ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa8 ); // Change Reg bank + +#ifdef _Test_Pattern_ + + LT8911EXB_IIC_Write_byte(dev, 0x24, 0x50 ); // bit2 ~ bit 0 : test panttern image mode + LT8911EXB_IIC_Write_byte(dev, 0x25, 0x70 ); // bit6 ~ bit 4 : test Pattern color + LT8911EXB_IIC_Write_byte(dev, 0x27, 0x50 ); //0x50:Pattern; 0x10:mipi video + +// LT8911EXB_IIC_Write_byte(dev, 0x2d, 0x00 ); // pure color setting +// LT8911EXB_IIC_Write_byte(dev, 0x2d, 0x84 ); // black color + LT8911EXB_IIC_Write_byte(dev, 0x2d, 0x88 ); // block + +#else + LT8911EXB_IIC_Write_byte(dev, 0x27, 0x10 ); //0x50:Pattern; 0x10:mipi video +#endif + +#ifdef _6bit_ + LT8911EXB_IIC_Write_byte(dev, 0x17, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x18, 0x00 ); +#else + // _8bit_ + LT8911EXB_IIC_Write_byte(dev, 0x17, 0x10 ); + LT8911EXB_IIC_Write_byte(dev, 0x18, 0x20 ); +#endif + + /* nvid */ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa0 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0x00, (u8)( Nvid_Val[_Nvid] / 256 ) ); // 0x08 + LT8911EXB_IIC_Write_byte(dev, 0x01, (u8)( Nvid_Val[_Nvid] % 256 ) ); // 0x00 +} + +void LT8911EXB_video_check(struct udevice *dev) +{ + u32 reg = 0x00; + /* mipi byte clk check*/ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x85 ); // Change Reg bank + LT8911EXB_IIC_Write_byte(dev, 0x1d, 0x00 ); //FM select byte clk + LT8911EXB_IIC_Write_byte(dev, 0x40, 0xf7 ); + LT8911EXB_IIC_Write_byte(dev, 0x41, 0x30 ); + + //#ifdef _eDP_scramble_ + if( ScrambleMode ) + { + LT8911EXB_IIC_Write_byte(dev, 0xa1, 0x82 ); //eDP scramble mode; + } + //#else + else + { + LT8911EXB_IIC_Write_byte(dev, 0xa1, 0x02 ); // DP scramble mode; + } + //#endif + +// LT8911EXB_IIC_Write_byte(dev, 0x17, 0xf0 ); // 0xf0:Close scramble; 0xD0 : Open scramble + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); + LT8911EXB_IIC_Write_byte(dev, 0x09, 0x7d ); + LT8911EXB_IIC_Write_byte(dev, 0x09, 0xfd ); + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x85 ); + mdelay(20); + if( LT8911EXB_IIC_Read_byte(dev, 0x50 ) == 0x03 ) + { + reg = LT8911EXB_IIC_Read_byte(dev, 0x4d ); + reg = reg * 256 + LT8911EXB_IIC_Read_byte(dev, 0x4e ); + reg = reg * 256 + LT8911EXB_IIC_Read_byte(dev, 0x4f ); + + debug( "\r\nvideo check: mipi byteclk = %d ", reg ); // mipi byteclk = reg * 1000 + debug( "\r\nvideo check: mipi bitrate = %d ", reg * 8 ); // mipi byteclk = reg * 1000 + debug( "\r\nvideo check: mipi pclk = %d ", reg /3 * 4 * 1000 ); // mipi byteclk = reg * 1000 + }else + { + debug( "\r\nvideo check: mipi clk unstable" ); + } + + /* mipi vtotal check*/ + reg = LT8911EXB_IIC_Read_byte(dev, 0x76 ); + reg = reg * 256 + LT8911EXB_IIC_Read_byte(dev, 0x77 ); + + debug( "\r\nvideo check: Vtotal = %d", reg); + + /* mipi word count check*/ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xd0 ); + reg = LT8911EXB_IIC_Read_byte(dev, 0x82 ); + reg = reg * 256 + LT8911EXB_IIC_Read_byte(dev, 0x83 ); + reg = reg / 3; + + debug( "\r\nvideo check: Hact(word counter) = %d", reg); + + /* mipi Vact check*/ + reg = LT8911EXB_IIC_Read_byte(dev, 0x85 ); + reg = reg * 256 + LT8911EXB_IIC_Read_byte(dev, 0x86 ); + + debug( "\r\nvideo check: Vact = %d", reg); +} + +void DpcdWrite(struct udevice *dev, u32 Address, u8 Data ) +{ + /*************************** + 注意大小端的问题! + 这里默认是大端模式 + + Pay attention to the Big-Endian and Little-Endian! + The default mode is Big-Endian here. + + ****************************/ + u8 AddressH = 0x0f & ( Address >> 16 ); + u8 AddressM = 0xff & ( Address >> 8 ); + u8 AddressL = 0xff & Address; + + u8 reg; + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa6 ); + LT8911EXB_IIC_Write_byte(dev, 0x2b, ( 0x80 | AddressH ) ); //CMD + LT8911EXB_IIC_Write_byte(dev, 0x2b, AddressM ); //addr[15:8] + LT8911EXB_IIC_Write_byte(dev, 0x2b, AddressL ); //addr[7:0] + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x00 ); //data lenth + LT8911EXB_IIC_Write_byte(dev, 0x2b, Data ); //data + LT8911EXB_IIC_Write_byte(dev, 0x2c, 0x00 ); //start Aux + + mdelay( 20 ); //more than 10ms + reg = LT8911EXB_IIC_Read_byte(dev, 0x25 ); + + if( ( reg & 0x0f ) == 0x0c ) + { + return; + } +} + +u8 DpcdRead(struct udevice *dev, u32 Address ) +{ + /*************************** + 注意大小端的问题! + 这里默认是大端模式 + + Pay attention to the Big-Endian and Little-Endian! + The default mode is Big-Endian here. + + ****************************/ + + u8 DpcdValue = 0x00; + u8 AddressH = 0x0f & ( Address >> 16 ); + u8 AddressM = 0xff & ( Address >> 8 ); + u8 AddressL = 0xff & Address; + u8 reg; + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xac ); + LT8911EXB_IIC_Write_byte(dev, 0x00, 0x20 ); //Soft Link train + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa6 ); + LT8911EXB_IIC_Write_byte(dev, 0x2a, 0x01 ); + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa6 ); + LT8911EXB_IIC_Write_byte(dev, 0x2b, ( 0x90 | AddressH ) ); //CMD + LT8911EXB_IIC_Write_byte(dev, 0x2b, AddressM ); //addr[15:8] + LT8911EXB_IIC_Write_byte(dev, 0x2b, AddressL ); //addr[7:0] + LT8911EXB_IIC_Write_byte(dev, 0x2b, 0x00 ); //data lenth + LT8911EXB_IIC_Write_byte(dev, 0x2c, 0x00 ); //start Aux read edid + + mdelay( 50 ); //more than 10ms + reg = LT8911EXB_IIC_Read_byte(dev, 0x25 ); + if( ( reg & 0x0f ) == 0x0c ) + { + if( LT8911EXB_IIC_Read_byte(dev, 0x39 ) == 0x22 ) + { + LT8911EXB_IIC_Read_byte(dev, 0x2b ); + DpcdValue = LT8911EXB_IIC_Read_byte(dev, 0x2b ); + } + + + /* + else + { + // goto no_reply; + // DpcdValue = 0xff; + return DpcdValue; + }//*/ + }else + { + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); // change bank + LT8911EXB_IIC_Write_byte(dev, 0x07, 0xfe ); + LT8911EXB_IIC_Write_byte(dev, 0x07, 0xff ); + LT8911EXB_IIC_Write_byte(dev, 0x0a, 0xfc ); + LT8911EXB_IIC_Write_byte(dev, 0x0a, 0xfe ); + } + + return DpcdValue; +} + +void LT8911EX_link_train(struct udevice *dev) +{ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); + LT8911EXB_IIC_Write_byte(dev, 0x06, 0xdf ); // rset VID TX + LT8911EXB_IIC_Write_byte(dev, 0x06, 0xff ); + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x85 ); + + if( ScrambleMode ) + { + LT8911EXB_IIC_Write_byte(dev, 0xa1, 0x82 ); // eDP scramble mode; + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xac ); + LT8911EXB_IIC_Write_byte(dev, 0x00, 0x20 ); //Soft Link train + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa6 ); + LT8911EXB_IIC_Write_byte(dev, 0x2a, 0x01 ); + + DpcdWrite(dev, 0x010a, 0x01 ); + mdelay(10); + DpcdWrite(dev, 0x0102, 0x00 ); + mdelay(10); + DpcdWrite(dev, 0x010a, 0x01 ); + + mdelay(10); + //*/ + } +//#else + else + { + LT8911EXB_IIC_Write_byte(dev, 0xa1, 0x02 ); // DP scramble mode; + } +//#endif + + /* Aux setup */ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xac ); + LT8911EXB_IIC_Write_byte(dev, 0x00, 0x60 ); //Soft Link train + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa6 ); + LT8911EXB_IIC_Write_byte(dev, 0x2a, 0x00 ); + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); + LT8911EXB_IIC_Write_byte(dev, 0x07, 0xfe ); + LT8911EXB_IIC_Write_byte(dev, 0x07, 0xff ); + LT8911EXB_IIC_Write_byte(dev, 0x0a, 0xfc ); + LT8911EXB_IIC_Write_byte(dev, 0x0a, 0xfe ); + + /* link train */ + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x85 ); + LT8911EXB_IIC_Write_byte(dev, 0x1a, eDP_lane ); + +#ifdef LINK_TRAIN_ENABLE + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xac ); + LT8911EXB_IIC_Write_byte(dev, 0x00, 0x64 ); + LT8911EXB_IIC_Write_byte(dev, 0x01, 0x0a ); + LT8911EXB_IIC_Write_byte(dev, 0x0c, 0x85 ); + LT8911EXB_IIC_Write_byte(dev, 0x0c, 0xc5 ); +#else + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xac ); + LT8911EXB_IIC_Write_byte(dev, 0x00, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x01, 0x0a ); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0x80 ); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0x81 ); + mdelay( 50 ); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0x84 ); + mdelay( 50 ); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0xc0 ); +#endif +} + +static int LT8911EX_link_train_result(struct udevice *dev) +{ + u8 i, reg; + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xac ); + for( i = 0; i < 10; i++ ) + { + reg = LT8911EXB_IIC_Read_byte(dev, 0x82 ); + // Debug_DispStrNum( "\r\n0x82 = ", reg ); + if( reg & 0x20 ) + { + if( ( reg & 0x1f ) == 0x1e ) + { + debug( "\r\nLink train success, 0x82 = 0x%x", reg ); + debug( "\r\npanel link rate: 0x%x", LT8911EXB_IIC_Read_byte(dev, 0x83 ) ); + debug( "\r\npanel link count: 0x%x", LT8911EXB_IIC_Read_byte(dev, 0x84 ) ); + mdelay( 10 ); + return 0; + } else{ + debug( "\r\nLink train fail, 0x82 = 0x%x", reg ); + debug( "\r\npanel link rate: 0x%x", LT8911EXB_IIC_Read_byte(dev, 0x83 ) ); + debug( "\r\npanel link count: 0x%x", LT8911EXB_IIC_Read_byte(dev, 0x84 ) ); + mdelay( 10 ); + return -1; + } + + } + else{ + debug( "\r\nlink trian on going..." ); + mdelay( 1 ); + } + + } + return -1; +} + +void LT8911EXB_MainLoop(struct udevice *dev) +{ +#ifndef _Test_Pattern_ + u16 reg; + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x85 ); + //LT8911EXB_IIC_Write_byte(0x1d,0x00); //FM select byte clk + //LT8911EXB_IIC_Write_byte(0x40,0xf7); + //LT8911EXB_IIC_Write_byte(0x41,0x30); + + if( ScrambleMode ) + { + LT8911EXB_IIC_Write_byte(dev, 0xa1, 0x82 ); // + }else + { + LT8911EXB_IIC_Write_byte(dev, 0xa1, 0x02 ); // + } + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); //video check rst + LT8911EXB_IIC_Write_byte(dev, 0x09, 0x7d ); + LT8911EXB_IIC_Write_byte(dev, 0x09, 0xfd ); + mdelay(10); + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x85 ); + reg = LT8911EXB_IIC_Read_byte(dev, 0x76 ); + reg = reg * 256 + LT8911EXB_IIC_Read_byte(dev, 0x77 ); + +// if( reg == MIPI_Timing[vtotal] ) + if( ( reg > ( MIPI_Timing[vtotal] - 5 ) ) && ( reg < ( MIPI_Timing[vtotal] + 5 ) ) ) + { + if( !flag_mipi_on ) + { + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); //PCR reset + LT8911EXB_IIC_Write_byte(dev, 0x03, 0x7b ); + LT8911EXB_IIC_Write_byte(dev, 0x03, 0xff ); + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa8 ); + LT8911EXB_IIC_Write_byte(dev, 0x2d, 0x88 ); + flag_mipi_on = 1; + debug( "\r\nPCR reset" ); + } + }else + { + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa8 ); + LT8911EXB_IIC_Write_byte(dev, 0x2d, 0x8c ); //edp output idle pattern; + flag_mipi_on = 0; + } + +#ifdef UART_DEBUG + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xd0 ); + reg = LT8911EXB_IIC_Read_byte(dev, 0x87 ); +// reg = reg * 256 + HDMI_ReadI2C_Byte( 0x77 ); + if( reg & 0x10 ) + { + debug( "\r\nPCR Clock stable" ); + }else + { + debug( "\r\nPCR Clock unstable" ); + } + debug( "\r\n " ); +#endif + +#endif +} + +enum +{ + _Level0_ = 0, // 27.8 mA 0x83/0x00 + _Level1_, // 26.2 mA 0x82/0xe0 + _Level2_, // 24.6 mA 0x82/0xc0 + _Level3_, // 23 mA 0x82/0xa0 + _Level4_, // 21.4 mA 0x82/0x80 + _Level5_, // 18.2 mA 0x82/0x40 + _Level6_, // 16.6 mA 0x82/0x20 + _Level7_, // 15mA 0x82/0x00 // level 1 + _Level8_, // 12.8mA 0x81/0x00 // level 2 + _Level9_, // 11.2mA 0x80/0xe0 // level 3 + _Level10_, // 9.6mA 0x80/0xc0 // level 4 + _Level11_, // 8mA 0x80/0xa0 // level 5 + _Level12_, // 6mA 0x80/0x80 // level 6 +}; + +u8 Swing_Setting1[] = { 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x80, 0x80, 0x80, 0x80 }; +u8 Swing_Setting2[] = { 0x00, 0xe0, 0xc0, 0xa0, 0x80, 0x40, 0x20, 0x00, 0x00, 0xe0, 0xc0, 0xa0, 0x80 }; + +u8 Level = _Level7_; + +void LT8911EX_TxSwingPreSet(struct udevice *dev) +{ + LT8911EXB_IIC_Write_byte(dev, 0xFF, 0x82 ); + LT8911EXB_IIC_Write_byte(dev, 0x22, Swing_Setting1[Level] ); //lane 0 tap0 + LT8911EXB_IIC_Write_byte(dev, 0x23, Swing_Setting2[Level] ); + LT8911EXB_IIC_Write_byte(dev, 0x24, 0x80 ); //lane 0 tap1 + LT8911EXB_IIC_Write_byte(dev, 0x25, 0x00 ); + +#if ( eDP_lane == 2 ) + LT8911EXB_IIC_Write_byte(dev, 0x26, Swing_Setting1[Level] ); //lane 1 tap0 + LT8911EXB_IIC_Write_byte(dev, 0x27, Swing_Setting2[Level] ); + LT8911EXB_IIC_Write_byte(dev, 0x28, 0x80 ); //lane 1 tap1 + LT8911EXB_IIC_Write_byte(dev, 0x29, 0x00 ); +#endif +} + +void PCR_Status(struct udevice *dev) // for debug +{ +#ifdef UART_DEBUG + u8 reg; + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xd0 ); + reg = LT8911EXB_IIC_Read_byte(dev, 0x87 ); + + debug( "\r\nReg0xD087 = "); + debug( " 0x%x ", reg ); + debug( "\r\n " ); + if( reg & 0x10 ) + { + debug( "\r\nPCR Clock stable" ); + }else + { + debug( "\r\nPCR Clock unstable" ); + } + debug( "\r\n " ); +#endif +} + +void LT8911_MainLoop(struct udevice *dev) +{ + u16 reg, H_act, V_act; +// bool flag_mipi_on = 0; + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x85 ); + + if( ScrambleMode ) + { + LT8911EXB_IIC_Write_byte(dev, 0xa1, 0x82 ); //video check from mipi + }else + { + LT8911EXB_IIC_Write_byte(dev, 0xa1, 0x02 ); + } + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); //video check rst + LT8911EXB_IIC_Write_byte(dev, 0x09, 0x7d ); + LT8911EXB_IIC_Write_byte(dev, 0x09, 0xfd ); + mdelay(10); + + /* mipi word count check*/ + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xd0 ); + reg = LT8911EXB_IIC_Read_byte(dev, 0x82 ); + reg = reg * 256 + LT8911EXB_IIC_Read_byte(dev, 0x83 ); + H_act = reg / 3; + +#ifdef UART_DEBUG + + debug( "\r\nHact(word counter) = %d\r\n", H_act ); // H active = word counter / 3 + +#endif + + /* mipi Vact check*/ + reg = LT8911EXB_IIC_Read_byte(dev, 0x85 ); + V_act = reg * 256 + LT8911EXB_IIC_Read_byte(dev, 0x86 ); + +#ifdef UART_DEBUG + + debug( "\r\nVact = %d\r\n ",V_act ); +#endif + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x85 ); + reg = LT8911EXB_IIC_Read_byte(dev, 0x76 ); + reg = reg * 256 + LT8911EXB_IIC_Read_byte(dev, 0x77 ); + +#ifdef UART_DEBUG + debug( "\r\nvideo check: Vtotal = %d\r\n ",reg ); +#endif + +// if( reg == MIPI_Timing[vtotal] ) + if( ( reg > ( MIPI_Timing[vtotal] - 5 ) ) && ( reg < ( MIPI_Timing[vtotal] + 5 ) ) ) + { + if( !flag_mipi_on ) + { + LT8911EXB_IIC_Write_byte(dev, 0xff, 0x81 ); //PCR reset + LT8911EXB_IIC_Write_byte(dev, 0x03, 0x7b ); + LT8911EXB_IIC_Write_byte(dev, 0x03, 0xff ); + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa8 ); + LT8911EXB_IIC_Write_byte(dev, 0x2d, 0x88 ); + flag_mipi_on = 1; +#ifdef UART_DEBUG + debug( "\r\nPCR reset" ); +#endif + } + }else + { + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xa8 ); + LT8911EXB_IIC_Write_byte(dev, 0x2d, 0x8c ); //edp output idle pattern; + flag_mipi_on = 0; + } + +#ifdef UART_DEBUG + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xd0 ); + reg = LT8911EXB_IIC_Read_byte(dev, 0x87 ); + + debug( "\r\nReg0xD087 = 0x%x\r\n ",reg ); + + if( reg & 0x10 ) + { + debug( "\r\nPCR Clock stable" ); + }else + { + debug( "\r\nPCR Clock unstable" ); + } + debug( "\r\n " ); +#endif +} + +/***********************************************************/ + +void LT8911EXB_LinkTrainResultCheck(struct udevice *dev) +{ +#ifdef LINK_TRAIN_ENABLE + u8 i; + u8 val; + //int ret; + + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xac ); + for( i = 0; i < 10; i++ ) + { + val = LT8911EXB_IIC_Read_byte(dev, 0x82 ); + if( val & 0x20 ) + { + if( ( val & 0x1f ) == 0x1e ) + { +#ifdef UART_DEBUG + // debug("\r\nLT8911_LinkTrainResultCheck: edp link train successed: 0x%bx", val); + debug( "\r\nedp link train successed: 0x%x", val ); +#endif + return; + }else + { +#ifdef UART_DEBUG + //debug("\r\nLT8911_LinkTrainResultCheck: edp link train failed: 0x%bx", val); + debug( "\r\nedp link train failed: 0x%x", val ); +#endif + LT8911EXB_IIC_Write_byte(dev, 0xff, 0xac ); + LT8911EXB_IIC_Write_byte(dev, 0x00, 0x00 ); + LT8911EXB_IIC_Write_byte(dev, 0x01, 0x0a ); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0x80 ); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0x81 ); + mdelay(10); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0x84 ); + mdelay(10); + LT8911EXB_IIC_Write_byte(dev, 0x14, 0xc0 ); + //debug("\r\nLT8911_LinkTrainResultCheck: Enable eDP video output while linktrian fail"); + } + +#ifdef UART_DEBUG + + val = LT8911EXB_IIC_Read_byte(dev, 0x83 ); + //debug("\r\nLT8911_LinkTrainResultCheck: panel link rate: 0x%bx",val); + debug( "\r\npanel link rate: 0x%x", val ); + val = LT8911EXB_IIC_Read_byte(dev, 0x84 ); + //debug("\r\nLT8911_LinkTrainResultCheck: panel link count: 0x%bx",val); + debug( "\r\npanel link count:0x%x ", val ); +#endif + mdelay( 10 ); // return; + }else + { + //debug("\r\nLT8911_LinkTrainResultCheck: link trian on going..."); + mdelay( 10 ); + } + } +#endif +} + +static int edp_panel_enable_backlight(struct udevice *dev) +{ + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); + struct mipi_dsi_device *device = plat->device; + int ret; + + debug("\r\nedp_panel_enable_backlight\r\n"); + + ret = mipi_dsi_attach(device); + if (ret < 0) + return ret; + Reset_LT8911EXB(dev); // 先Reset LT8911EXB ,用GPIO 先拉低LT8911EXB的复位脚 100ms左右,再拉高,保持100ms。 + + LT8911EX_ChipID(dev); // read Chip ID + + LT8911EXB_eDP_Video_cfg(dev); + + LT8911EXB_init(dev); + + ScrambleMode = 0; + + LT8911EX_TxSwingPreSet(dev); + + LT8911EX_link_train(dev); + + LT8911EXB_LinkTrainResultCheck(dev); +//======================================// + ret = LT8911EX_link_train_result(dev); // for debug + if (ret < 0) + return ret; + + LT8911EXB_video_check(dev); // just for Check MIPI Input + + debug("\r\nDpcdRead(0x0202) = 0x%x\r\n",DpcdRead(dev,0x0202)); + + PCR_Status(dev); // just for Check PCR CLK + + return 0; +} + +static int edp_panel_get_display_timing(struct udevice *dev, + struct display_timing *timings) +{ + memcpy(timings, &default_timing, sizeof(*timings)); + return 0; +} + +static int edp_panel_of_to_plat(struct udevice *dev) +{ + return 0; +} + +static int edp_panel_probe(struct udevice *dev) +{ + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); + struct edp_panel_priv *priv = dev_get_priv(dev); + u8 regval; + + /* fill characteristics of DSI data link */ + plat->lanes = 4; + plat->format = MIPI_DSI_FMT_RGB888; + plat->mode_flags = MIPI_DSI_MODE_VIDEO | + MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_LPM; + + priv->reset_gpio = devm_gpiod_get_optional(dev, "reset", + GPIOD_IS_IN); + if (IS_ERR(priv->reset_gpio)) { + pr_err("Failed get reset gpio41\n"); + return PTR_ERR(priv->reset_gpio); + } + + priv->pwm_gpio = devm_gpiod_get_optional(dev, "pwm", + GPIOD_IS_OUT); + if (IS_ERR(priv->pwm_gpio)) { + pr_err("Failed get power gpio33\n"); + return PTR_ERR(priv->pwm_gpio); + } + + priv->bl_gpio = devm_gpiod_get_optional(dev, "bl", + GPIOD_IS_OUT); + if (IS_ERR(priv->bl_gpio)) { + pr_err("Failed get bl\n"); + return PTR_ERR(priv->bl_gpio); + } + + LT8911EXB_init(dev); + regval = DpcdRead(dev, 0x0101); + debug("0x0101 DpcdRead regval = 0x%x\n", regval); + if (regval == 0x00 || regval == 0xff ){ + pr_err("no screen connected\n"); + return -1; + } + + return 0; +} + +static const struct panel_ops edp_panel_ops = { + .enable_backlight = edp_panel_enable_backlight, + .get_display_timing = edp_panel_get_display_timing, +}; + +static const struct udevice_id edp_panel_ids[] = { + { .compatible = "lontium,lt8911exb" }, + { } +}; + +U_BOOT_DRIVER(edp_panel) = { + .name = "edp_panel", + .id = UCLASS_PANEL, + .of_match = edp_panel_ids, + .ops = &edp_panel_ops, + .of_to_plat = edp_panel_of_to_plat, + .probe = edp_panel_probe, + .plat_auto = sizeof(struct mipi_dsi_panel_plat), + .priv_auto = sizeof(struct edp_panel_priv), +}; -- cgit v1.2.3 From 9338dd6190d43bfa59df24ec6b0920eab34967fd Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Tue, 22 Aug 2023 16:13:50 +0800 Subject: video: Rename raydium-rm68200-starfive.c to starfive_seeed_panel.c The code is ported from tag JH7110_DVK_515_v3.9.3 of Devkits repo. Signed-off-by: Keith Zhao Signed-off-by: Shengyang Chen Signed-off-by: Hal Feng --- drivers/video/Makefile | 2 +- drivers/video/raydium-rm68200-starfive.c | 340 ----------------------------- drivers/video/starfive_seeed_panel.c | 355 +++++++++++++++++++++++++++++++ 3 files changed, 356 insertions(+), 341 deletions(-) delete mode 100644 drivers/video/raydium-rm68200-starfive.c create mode 100644 drivers/video/starfive_seeed_panel.c diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 33066e2d7f..bfab1e3d9c 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -57,7 +57,7 @@ obj-$(CONFIG_VIDEO_LCD_ANX9804) += anx9804.o obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o obj-$(CONFIG_VIDEO_LCD_ORISETECH_OTM8009A) += orisetech_otm8009a.o obj-$(CONFIG_VIDEO_LCD_RAYDIUM_RM68200) += raydium-rm68200.o -obj-$(CONFIG_VIDEO_LCD_STARFIVE_SEEED) += raydium-rm68200-starfive.o +obj-$(CONFIG_VIDEO_LCD_STARFIVE_SEEED) += starfive_seeed_panel.o obj-$(CONFIG_VIDEO_SF_MIPI2EDP) += starfive_edp.o obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o obj-$(CONFIG_VIDEO_LCD_TDO_TL070WSH30) += tdo-tl070wsh30.o diff --git a/drivers/video/raydium-rm68200-starfive.c b/drivers/video/raydium-rm68200-starfive.c deleted file mode 100644 index c4234d58f2..0000000000 --- a/drivers/video/raydium-rm68200-starfive.c +++ /dev/null @@ -1,340 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2019 STMicroelectronics - All Rights Reserved - * Author(s): Yannick Fertre for STMicroelectronics. - * Philippe Cornu for STMicroelectronics. - * - * This rm68200 panel driver is inspired from the Linux Kernel driver - * drivers/gpu/drm/panel/panel-raydium-rm68200.c. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* I2C registers of the Atmel microcontroller. */ -enum REG_ADDR { - REG_ID = 0x80, - REG_PORTA, /* BIT(2) for horizontal flip, BIT(3) for vertical flip */ - REG_PORTB, - REG_PORTC, - REG_PORTD, - REG_POWERON, - REG_PWM, - REG_DDRA, - REG_DDRB, - REG_DDRC, - REG_DDRD, - REG_TEST, - REG_WR_ADDRL, - REG_WR_ADDRH, - REG_READH, - REG_READL, - REG_WRITEH, - REG_WRITEL, - REG_ID2, -}; - -/* DSI D-PHY Layer Registers */ -#define D0W_DPHYCONTTX 0x0004 -#define CLW_DPHYCONTRX 0x0020 -#define D0W_DPHYCONTRX 0x0024 -#define D1W_DPHYCONTRX 0x0028 -#define COM_DPHYCONTRX 0x0038 -#define CLW_CNTRL 0x0040 -#define D0W_CNTRL 0x0044 -#define D1W_CNTRL 0x0048 -#define DFTMODE_CNTRL 0x0054 - -/* DSI PPI Layer Registers */ -#define PPI_STARTPPI 0x0104 -#define PPI_BUSYPPI 0x0108 -#define PPI_LINEINITCNT 0x0110 -#define PPI_LPTXTIMECNT 0x0114 -#define PPI_CLS_ATMR 0x0140 -#define PPI_D0S_ATMR 0x0144 -#define PPI_D1S_ATMR 0x0148 -#define PPI_D0S_CLRSIPOCOUNT 0x0164 -#define PPI_D1S_CLRSIPOCOUNT 0x0168 -#define CLS_PRE 0x0180 -#define D0S_PRE 0x0184 -#define D1S_PRE 0x0188 -#define CLS_PREP 0x01A0 -#define D0S_PREP 0x01A4 -#define D1S_PREP 0x01A8 -#define CLS_ZERO 0x01C0 -#define D0S_ZERO 0x01C4 -#define D1S_ZERO 0x01C8 -#define PPI_CLRFLG 0x01E0 -#define PPI_CLRSIPO 0x01E4 -#define HSTIMEOUT 0x01F0 -#define HSTIMEOUTENABLE 0x01F4 - -/* DSI Protocol Layer Registers */ -#define DSI_STARTDSI 0x0204 -#define DSI_BUSYDSI 0x0208 -#define DSI_LANEENABLE 0x0210 -#define DSI_LANEENABLE_CLOCK BIT(0) -#define DSI_LANEENABLE_D0 BIT(1) -#define DSI_LANEENABLE_D1 BIT(2) - -#define DSI_LANESTATUS0 0x0214 -#define DSI_LANESTATUS1 0x0218 -#define DSI_INTSTATUS 0x0220 -#define DSI_INTMASK 0x0224 -#define DSI_INTCLR 0x0228 -#define DSI_LPTXTO 0x0230 -#define DSI_MODE 0x0260 -#define DSI_PAYLOAD0 0x0268 -#define DSI_PAYLOAD1 0x026C -#define DSI_SHORTPKTDAT 0x0270 -#define DSI_SHORTPKTREQ 0x0274 -#define DSI_BTASTA 0x0278 -#define DSI_BTACLR 0x027C - -/* DSI General Registers */ -#define DSIERRCNT 0x0300 -#define DSISIGMOD 0x0304 - -/* DSI Application Layer Registers */ -#define APLCTRL 0x0400 -#define APLSTAT 0x0404 -#define APLERR 0x0408 -#define PWRMOD 0x040C -#define RDPKTLN 0x0410 -#define PXLFMT 0x0414 -#define MEMWRCMD 0x0418 - -/* LCDC/DPI Host Registers */ -#define LCDCTRL 0x0420 -#define HSR 0x0424 -#define HDISPR 0x0428 -#define VSR 0x042C -#define VDISPR 0x0430 -#define VFUEN 0x0434 - -/* DBI-B Host Registers */ -#define DBIBCTRL 0x0440 - -/* SPI Master Registers */ -#define SPICMR 0x0450 -#define SPITCR 0x0454 - -/* System Controller Registers */ -#define SYSSTAT 0x0460 -#define SYSCTRL 0x0464 -#define SYSPLL1 0x0468 -#define SYSPLL2 0x046C -#define SYSPLL3 0x0470 -#define SYSPMCTRL 0x047C - -/* GPIO Registers */ -#define GPIOC 0x0480 -#define GPIOO 0x0484 -#define GPIOI 0x0488 - -/* I2C Registers */ -#define I2CCLKCTRL 0x0490 - -/* Chip/Rev Registers */ -#define IDREG 0x04A0 - -/* Debug Registers */ -#define WCMDQUEUE 0x0500 -#define RCMDQUEUE 0x0504 - - -struct rm68200_panel_priv { - struct udevice *reg; - struct udevice *backlight; - struct gpio_desc reset; -}; - -static const struct display_timing default_timing = { - .pixelclock.typ = 29700000, - .hactive.typ = 800, - .hfront_porch.typ = 90, - .hback_porch.typ = 5, - .hsync_len.typ = 5, - .vactive.typ = 480, - .vfront_porch.typ = 60, - .vback_porch.typ = 5, - .vsync_len.typ = 5, -}; - -static int seeed_panel_i2c_write(struct udevice *dev, uint addr, uint mask, uint data) -{ - uint8_t valb; - int err = 0; - - if (mask != 0xff){ - err = dm_i2c_read(dev, addr, &valb, 1); - if (err) - return err; - } - valb &= ~mask; - valb |= data; - - err = dm_i2c_write(dev, addr, &valb, 1); - return err; -} - -static int seeed_panel_i2c_read(struct udevice *dev, uint8_t addr, uint8_t *data) -{ - uint8_t valb; - int err; - - err = dm_i2c_read(dev, addr, &valb, 1); - if (err) - return err; - - *data = (int)valb; - return 0; -} - -static void rpi_touchscreen_write(struct udevice *dev, u16 reg, u32 val) -{ - struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); - struct mipi_dsi_device *device = plat->device; - int err; - - u8 msg[] = { - reg, - reg >> 8, - val, - val >> 8, - val >> 16, - val >> 24, - }; - - err = mipi_dsi_dcs_write_buffer(device, msg, sizeof(msg)); - if (err < 0) - dev_err(dev, "MIPI DSI DCS write buffer failed: %d\n", err); - - return; -} - -static int rm68200_panel_enable_backlight(struct udevice *dev) -{ - struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); - struct mipi_dsi_device *device = plat->device; - int ret; - int i; - u8 reg_value = 0; - - ret = mipi_dsi_attach(device); - if (ret < 0) - return ret; - - seeed_panel_i2c_write(dev, REG_POWERON, 0xff, 1); - - mdelay(100); - /* Wait for nPWRDWN to go low to indicate poweron is done. */ - for (i = 0; i < 100; i++) { - seeed_panel_i2c_read(dev, REG_PORTB, ®_value); - if (reg_value & 1) - break; - } - - rpi_touchscreen_write(dev, DSI_LANEENABLE, - DSI_LANEENABLE_CLOCK | - DSI_LANEENABLE_D0); - - rpi_touchscreen_write(dev,PPI_D0S_CLRSIPOCOUNT, 0x05); - rpi_touchscreen_write(dev,PPI_D1S_CLRSIPOCOUNT, 0x05); - rpi_touchscreen_write(dev,PPI_D0S_ATMR, 0x00); - rpi_touchscreen_write(dev,PPI_D1S_ATMR, 0x00); - rpi_touchscreen_write(dev,PPI_LPTXTIMECNT, 0x03); - - rpi_touchscreen_write(dev,SPICMR, 0x00); - rpi_touchscreen_write(dev,LCDCTRL, 0x00100150); - rpi_touchscreen_write(dev,SYSCTRL, 0x040f); - mdelay(100); - - rpi_touchscreen_write(dev,PPI_STARTPPI, 0x01); - rpi_touchscreen_write(dev,DSI_STARTDSI, 0x01); - mdelay(100); - - /* Turn on the backlight. */ - seeed_panel_i2c_write(dev,REG_PWM, 255, 255); - mdelay(100); - - /* Default to the same orientation as the closed source - * firmware used for the panel. Runtime rotation - * configuration will be supported using VC4's plane - * orientation bits. - */ - seeed_panel_i2c_write(dev,REG_PORTA,255, BIT(2)); - mdelay(100); - - - return 0; -} - -static int rm68200_panel_get_display_timing(struct udevice *dev, - struct display_timing *timings) -{ - memcpy(timings, &default_timing, sizeof(*timings)); - return 0; -} - -static int rm68200_panel_of_to_plat(struct udevice *dev) -{ - return 0; -} - -static int rm68200_panel_probe(struct udevice *dev) -{ - struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); - - u8 reg_value = 0; - - /* fill characteristics of DSI data link */ - plat->lanes = 1; - plat->format = MIPI_DSI_FMT_RGB888; - plat->mode_flags = MIPI_DSI_MODE_VIDEO | - MIPI_DSI_MODE_VIDEO_BURST | - MIPI_DSI_MODE_LPM; - - seeed_panel_i2c_read(dev, 0x80, ®_value); - - debug("%s,reg_value = %d\n", __func__,reg_value); - switch (reg_value) { - case 0xde: /* ver 1 */ - case 0xc3: /* ver 2 */ - break; - - default: - debug("Unknown Atmel firmware revision: 0x%02x\n", reg_value); - return -ENODEV; - } - - return 0; -} - -static const struct panel_ops rm68200_panel_ops = { - .enable_backlight = rm68200_panel_enable_backlight, - .get_display_timing = rm68200_panel_get_display_timing, -}; - -static const struct udevice_id rm68200_panel_ids[] = { - { .compatible = "raydium,rm68200" }, - { } -}; - -U_BOOT_DRIVER(rm68200_panel) = { - .name = "rm68200_panel", - .id = UCLASS_PANEL, - .of_match = rm68200_panel_ids, - .ops = &rm68200_panel_ops, - .of_to_plat = rm68200_panel_of_to_plat, - .probe = rm68200_panel_probe, - .plat_auto = sizeof(struct mipi_dsi_panel_plat), - .priv_auto = sizeof(struct rm68200_panel_priv), -}; diff --git a/drivers/video/starfive_seeed_panel.c b/drivers/video/starfive_seeed_panel.c new file mode 100644 index 0000000000..636974fd7e --- /dev/null +++ b/drivers/video/starfive_seeed_panel.c @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 STMicroelectronics - All Rights Reserved + * Author(s): Yannick Fertre for STMicroelectronics. + * Philippe Cornu for STMicroelectronics. + * + * This seeed panel driver is inspired from the Linux Kernel driver + * drivers/gpu/drm/panel/panel-raydium-seeed.c. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* I2C registers of the Atmel microcontroller. */ +enum REG_ADDR { + REG_ID = 0x80, + REG_PORTA, /* BIT(2) for horizontal flip, BIT(3) for vertical flip */ + REG_PORTB, + REG_PORTC, + REG_PORTD, + REG_POWERON, + REG_PWM, + REG_DDRA, + REG_DDRB, + REG_DDRC, + REG_DDRD, + REG_TEST, + REG_WR_ADDRL, + REG_WR_ADDRH, + REG_READH, + REG_READL, + REG_WRITEH, + REG_WRITEL, + REG_ID2, +}; + +/* DSI D-PHY Layer Registers */ +#define D0W_DPHYCONTTX 0x0004 +#define CLW_DPHYCONTRX 0x0020 +#define D0W_DPHYCONTRX 0x0024 +#define D1W_DPHYCONTRX 0x0028 +#define COM_DPHYCONTRX 0x0038 +#define CLW_CNTRL 0x0040 +#define D0W_CNTRL 0x0044 +#define D1W_CNTRL 0x0048 +#define DFTMODE_CNTRL 0x0054 + +/* DSI PPI Layer Registers */ +#define PPI_STARTPPI 0x0104 +#define PPI_BUSYPPI 0x0108 +#define PPI_LINEINITCNT 0x0110 +#define PPI_LPTXTIMECNT 0x0114 +#define PPI_CLS_ATMR 0x0140 +#define PPI_D0S_ATMR 0x0144 +#define PPI_D1S_ATMR 0x0148 +#define PPI_D0S_CLRSIPOCOUNT 0x0164 +#define PPI_D1S_CLRSIPOCOUNT 0x0168 +#define CLS_PRE 0x0180 +#define D0S_PRE 0x0184 +#define D1S_PRE 0x0188 +#define CLS_PREP 0x01A0 +#define D0S_PREP 0x01A4 +#define D1S_PREP 0x01A8 +#define CLS_ZERO 0x01C0 +#define D0S_ZERO 0x01C4 +#define D1S_ZERO 0x01C8 +#define PPI_CLRFLG 0x01E0 +#define PPI_CLRSIPO 0x01E4 +#define HSTIMEOUT 0x01F0 +#define HSTIMEOUTENABLE 0x01F4 + +/* DSI Protocol Layer Registers */ +#define DSI_STARTDSI 0x0204 +#define DSI_BUSYDSI 0x0208 +#define DSI_LANEENABLE 0x0210 +#define DSI_LANEENABLE_CLOCK BIT(0) +#define DSI_LANEENABLE_D0 BIT(1) +#define DSI_LANEENABLE_D1 BIT(2) + +#define DSI_LANESTATUS0 0x0214 +#define DSI_LANESTATUS1 0x0218 +#define DSI_INTSTATUS 0x0220 +#define DSI_INTMASK 0x0224 +#define DSI_INTCLR 0x0228 +#define DSI_LPTXTO 0x0230 +#define DSI_MODE 0x0260 +#define DSI_PAYLOAD0 0x0268 +#define DSI_PAYLOAD1 0x026C +#define DSI_SHORTPKTDAT 0x0270 +#define DSI_SHORTPKTREQ 0x0274 +#define DSI_BTASTA 0x0278 +#define DSI_BTACLR 0x027C + +/* DSI General Registers */ +#define DSIERRCNT 0x0300 +#define DSISIGMOD 0x0304 + +/* DSI Application Layer Registers */ +#define APLCTRL 0x0400 +#define APLSTAT 0x0404 +#define APLERR 0x0408 +#define PWRMOD 0x040C +#define RDPKTLN 0x0410 +#define PXLFMT 0x0414 +#define MEMWRCMD 0x0418 + +/* LCDC/DPI Host Registers */ +#define LCDCTRL 0x0420 +#define HSR 0x0424 +#define HDISPR 0x0428 +#define VSR 0x042C +#define VDISPR 0x0430 +#define VFUEN 0x0434 + +/* DBI-B Host Registers */ +#define DBIBCTRL 0x0440 + +/* SPI Master Registers */ +#define SPICMR 0x0450 +#define SPITCR 0x0454 + +/* System Controller Registers */ +#define SYSSTAT 0x0460 +#define SYSCTRL 0x0464 +#define SYSPLL1 0x0468 +#define SYSPLL2 0x046C +#define SYSPLL3 0x0470 +#define SYSPMCTRL 0x047C + +/* GPIO Registers */ +#define GPIOC 0x0480 +#define GPIOO 0x0484 +#define GPIOI 0x0488 + +/* I2C Registers */ +#define I2CCLKCTRL 0x0490 + +/* Chip/Rev Registers */ +#define IDREG 0x04A0 + +/* printf Registers */ +#define WCMDQUEUE 0x0500 +#define RCMDQUEUE 0x0504 + + +struct seeed_panel_priv { + struct udevice *reg; + struct udevice *backlight; + struct gpio_desc *sel_gpio; //select + +}; + +static const struct display_timing default_timing = { + .pixelclock.typ = 29700000, + .hactive.typ = 800, + .hfront_porch.typ = 90, + .hback_porch.typ = 5, + .hsync_len.typ = 5, + .vactive.typ = 480, + .vfront_porch.typ = 60, + .vback_porch.typ = 5, + .vsync_len.typ = 5, +}; + +static int seeed_panel_i2c_write(struct udevice *dev, uint addr, uint mask, uint data) +{ + uint8_t valb; + int err = 0; + + if (mask != 0xff){ + err = dm_i2c_read(dev, addr, &valb, 1); + if (err) + return err; + } + valb &= ~mask; + valb |= data; + + err = dm_i2c_write(dev, addr, &valb, 1); + return err; +} + +static int seeed_panel_i2c_read(struct udevice *dev, uint8_t addr, uint8_t *data) +{ + uint8_t valb; + int err; + + err = dm_i2c_read(dev, addr, &valb, 1); + if (err) + return err; + + *data = (int)valb; + return 0; +} + +static void rpi_touchscreen_write(struct udevice *dev, u16 reg, u32 val) +{ + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); + struct mipi_dsi_device *device = plat->device; + int err; + + u8 msg[] = { + reg, + reg >> 8, + val, + val >> 8, + val >> 16, + val >> 24, + }; + + err = mipi_dsi_dcs_write_buffer(device, msg, sizeof(msg)); + if (err < 0) + dev_err(dev, "MIPI DSI DCS write buffer failed: %d\n", err); + + return; +} + +static int rm68200_panel_enable_backlight(struct udevice *dev) +{ + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); + struct mipi_dsi_device *device = plat->device; + int ret; + int i; + u8 reg_value = 0; + + ret = mipi_dsi_attach(device); + if (ret < 0) + return ret; + + seeed_panel_i2c_write(dev, REG_POWERON, 0xff, 1); + + mdelay(100); + /* Wait for nPWRDWN to go low to indicate poweron is done. */ + for (i = 0; i < 100; i++) { + seeed_panel_i2c_read(dev, REG_PORTB, ®_value); + if (reg_value & 1) + break; + } + + rpi_touchscreen_write(dev, DSI_LANEENABLE, + DSI_LANEENABLE_CLOCK | + DSI_LANEENABLE_D0); + + rpi_touchscreen_write(dev,PPI_D0S_CLRSIPOCOUNT, 0x05); + rpi_touchscreen_write(dev,PPI_D1S_CLRSIPOCOUNT, 0x05); + rpi_touchscreen_write(dev,PPI_D0S_ATMR, 0x00); + rpi_touchscreen_write(dev,PPI_D1S_ATMR, 0x00); + rpi_touchscreen_write(dev,PPI_LPTXTIMECNT, 0x03); + + rpi_touchscreen_write(dev,SPICMR, 0x00); + rpi_touchscreen_write(dev,LCDCTRL, 0x00100150); + rpi_touchscreen_write(dev,SYSCTRL, 0x040f); + mdelay(100); + + rpi_touchscreen_write(dev,PPI_STARTPPI, 0x01); + rpi_touchscreen_write(dev,DSI_STARTDSI, 0x01); + mdelay(100); + + /* Turn on the backlight. */ + seeed_panel_i2c_write(dev,REG_PWM, 255, 255); + mdelay(100); + + /* Default to the same orientation as the closed source + * firmware used for the panel. Runtime rotation + * configuration will be supported using VC4's plane + * orientation bits. + */ + seeed_panel_i2c_write(dev,REG_PORTA,255, BIT(2)); + mdelay(100); + + + return 0; +} + +static int rm68200_panel_get_display_timing(struct udevice *dev, + struct display_timing *timings) +{ + memcpy(timings, &default_timing, sizeof(*timings)); + return 0; +} + +static int rm68200_panel_of_to_plat(struct udevice *dev) +{ + return 0; +} + +static int rm68200_panel_probe(struct udevice *dev) +{ + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_DEVKITS) + struct seeed_panel_priv *priv = dev_get_priv(dev); +#endif + + u8 reg_value = 0; + + /* fill characteristics of DSI data link */ + plat->lanes = 1; + plat->format = MIPI_DSI_FMT_RGB888; + plat->mode_flags = MIPI_DSI_MODE_VIDEO | + MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_LPM; + + seeed_panel_i2c_read(dev, 0x80, ®_value); + + debug("%s,reg_value = %d\n", __func__,reg_value); + switch (reg_value) { + case 0xde: /* ver 1 */ + case 0xc3: /* ver 2 */ + break; + + default: + debug("Unknown Atmel firmware revision: 0x%02x\n", reg_value); + return -ENODEV; + } + +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_DEVKITS) + priv->sel_gpio = devm_gpiod_get_optional(dev, "sel", GPIOD_IS_OUT); + + if (IS_ERR(priv->sel_gpio)) { + pr_err("Failed get reset sel gpio\n"); + return PTR_ERR(priv->sel_gpio); + } + + dm_gpio_set_value(priv->sel_gpio, 0); +#endif + + return 0; +} + +static const struct panel_ops rm68200_panel_ops = { + .enable_backlight = rm68200_panel_enable_backlight, + .get_display_timing = rm68200_panel_get_display_timing, +}; + +static const struct udevice_id rm68200_panel_ids[] = { + { .compatible = "starfive,seeed" }, + { } +}; + +U_BOOT_DRIVER(seeed_panel) = { + .name = "seeed_panel", + .id = UCLASS_PANEL, + .of_match = rm68200_panel_ids, + .ops = &rm68200_panel_ops, + .of_to_plat = rm68200_panel_of_to_plat, + .probe = rm68200_panel_probe, + .plat_auto = sizeof(struct mipi_dsi_panel_plat), + .priv_auto = sizeof(struct seeed_panel_priv), +}; -- cgit v1.2.3 From b5cb74c2609a6d5baaf9f6eab7575f0daa2b1f5a Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Tue, 22 Aug 2023 16:20:05 +0800 Subject: riscv: dts: Change compatible "raydium,rm68200" to "starfive,seeed" As drivers/video/raydium-rm68200-starfive.c is renamed to drivers/video/starfive_seeed_panel.c, change the dts accordingly. Signed-off-by: Hal Feng --- arch/riscv/dts/starfive_evb.dts | 2 +- arch/riscv/dts/starfive_visionfive2.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/dts/starfive_evb.dts b/arch/riscv/dts/starfive_evb.dts index b62f79b362..2241073470 100644 --- a/arch/riscv/dts/starfive_evb.dts +++ b/arch/riscv/dts/starfive_evb.dts @@ -399,7 +399,7 @@ status = "okay"; rm68200_panel: rm68200_panel@45 { - compatible = "raydium,rm68200"; + compatible = "starfive,seeed"; reg = <0x45>; }; diff --git a/arch/riscv/dts/starfive_visionfive2.dts b/arch/riscv/dts/starfive_visionfive2.dts index 61fb42f987..ec8538d9dd 100644 --- a/arch/riscv/dts/starfive_visionfive2.dts +++ b/arch/riscv/dts/starfive_visionfive2.dts @@ -467,7 +467,7 @@ status = "okay"; rm68200_panel: rm68200_panel@45 { - compatible = "raydium,rm68200"; + compatible = "starfive,seeed"; reg = <0x45>; }; -- cgit v1.2.3 From 4bf24b47175bd55813612f0d162defcb65b94d13 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 16 Aug 2023 21:30:56 +0800 Subject: video: starfive: Add StarFive JH7110 Devkits board support Make the code be compatible with the StarFive Devkits board. The code is ported from tag JH7110_DVK_515_v3.9.3 of Devkits repo. Signed-off-by: Keith Zhao Signed-off-by: Shengyang Chen Signed-off-by: Hal Feng --- drivers/video/starfive/mipi_dsi_host.c | 51 ++++++++---- drivers/video/starfive/sf_mipi.c | 38 ++++++--- drivers/video/starfive/sf_mipi.h | 1 + drivers/video/starfive/sf_vop.c | 137 ++++++++++++++++++++++++++++++++- 4 files changed, 199 insertions(+), 28 deletions(-) diff --git a/drivers/video/starfive/mipi_dsi_host.c b/drivers/video/starfive/mipi_dsi_host.c index 2736eb329f..4960a22ee5 100644 --- a/drivers/video/starfive/mipi_dsi_host.c +++ b/drivers/video/starfive/mipi_dsi_host.c @@ -220,7 +220,7 @@ static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host, ret = wait_for_send_done(dsi, MIPI_FIFO_TIMEOUT); if (!ret) { - printf("wait tx done timeout!\n"); + debug("wait tx done timeout!\n"); return -ETIMEDOUT; } udelay(10); @@ -285,7 +285,7 @@ static int mipi_dsi_northwest_init(struct udevice *dev, priv->phy_base = (void *)dev_read_addr_name(device->dev, "phy"); if ((fdt_addr_t)priv->dsi_base == FDT_ADDR_T_NONE || (fdt_addr_t)priv->phy_base == FDT_ADDR_T_NONE) { - printf("dsi dt register address error\n"); + debug("dsi dt register address error\n"); return -EINVAL; } priv->link_initialized = false; @@ -300,21 +300,38 @@ static int mipi_dsi_enable(struct udevice *dev) priv->phy_ops->init(priv->device); priv->phy_ops->post_set_mode(priv->device, MIPI_DSI_MODE_VIDEO); cdns_dsi_init_link(priv, priv->device); - - writel(0x00670067, priv->dsi_base + 0x000000c0); - writel(0x00cb0960, priv->dsi_base + 0x000000c4); - writel(0x0003b145, priv->dsi_base + 0x000000b4); - writel(0x000001e0, priv->dsi_base + 0x000000b8); - writel(0x00000a9e, priv->dsi_base + 0x000000d0); - writel(0x0a980000, priv->dsi_base + 0x000000f8); - writel(0x00000b0f, priv->dsi_base + 0x000000cc); - writel(0x7c3c0aae, priv->dsi_base + 0x000000dc); - writel(0x0032dcd3, priv->dsi_base + 0x00000014); - writel(0x00032dcd, priv->dsi_base + 0x00000018); - writel(0x80b8fe00, priv->dsi_base + 0x000000b0); - writel(0x00020027, priv->dsi_base + 0x00000004); - writel(0x00004018, priv->dsi_base + 0x0000000c); - + debug("priv->timings.hactive.typ %d----\n",priv->timings.hactive.typ); + debug("priv->timings.vactive.typ %d----\n",priv->timings.vactive.typ); + if (priv->timings.hactive.typ == 800) + { + writel(0x00670067, priv->dsi_base + 0x000000c0); + writel(0x00cb0960, priv->dsi_base + 0x000000c4); + writel(0x0003b145, priv->dsi_base + 0x000000b4); + writel(0x000001e0, priv->dsi_base + 0x000000b8); + writel(0x00000a9e, priv->dsi_base + 0x000000d0); + writel(0x0a980000, priv->dsi_base + 0x000000f8); + writel(0x00000b0f, priv->dsi_base + 0x000000cc); + writel(0x7c3c0aae, priv->dsi_base + 0x000000dc); + writel(0x0032dcd3, priv->dsi_base + 0x00000014); + writel(0x00032dcd, priv->dsi_base + 0x00000018); + writel(0x80b8fe00, priv->dsi_base + 0x000000b0); + writel(0x00020027, priv->dsi_base + 0x00000004); + writel(0x00004018, priv->dsi_base + 0x0000000c); + }else if (priv->timings.hactive.typ == 1920){ + writel(0x01d30081, priv->dsi_base + 0x000000c0); + writel(0x01171680, priv->dsi_base + 0x000000c4); + writel(0x00003905, priv->dsi_base + 0x000000b4); + writel(0x00000438, priv->dsi_base + 0x000000b8); + writel(0x00001976, priv->dsi_base + 0x000000d0); + writel(0x19700000, priv->dsi_base + 0x000000f8); + writel(0x00001a01, priv->dsi_base + 0x000000cc); + writel(0x98900661, priv->dsi_base + 0x000000dc); + writel(0x003f9403, priv->dsi_base + 0x00000014); + writel(0x0003f940, priv->dsi_base + 0x00000018); + writel(0x80b8fe00, priv->dsi_base + 0x000000b0); + writel(0x00020027, priv->dsi_base + 0x00000004); + writel(0x000040f8, priv->dsi_base + 0x0000000c); + } return 0; } diff --git a/drivers/video/starfive/sf_mipi.c b/drivers/video/starfive/sf_mipi.c index ee5fbe7359..d9300c5879 100644 --- a/drivers/video/starfive/sf_mipi.c +++ b/drivers/video/starfive/sf_mipi.c @@ -114,7 +114,13 @@ static void dsi_phy_post_set_mode(void *priv_data, unsigned long mode_flags) if (!priv) return; - bitrate = 750000000;//1188M 60fps + // bitrate = 750000000;//1188M 60fps + debug("dsi_phy_post_set_mode priv->timings.hactive.typ %d----\n",priv->timings.hactive.typ); + debug("dsi_phy_post_set_mode priv->timings.vactive.typ %d----\n",priv->timings.vactive.typ); + if (priv->timings.hactive.typ == 800) + bitrate = 750000000; + else if(priv->timings.hactive.typ == 1920) + bitrate = 900000000;//1188M 60fps sf_dphy_set_reg(priv->phy_reg + 0x8, 0x10, RG_CDTX_L0N_HSTX_RES_SHIFT, RG_CDTX_L0N_HSTX_RES_MASK); @@ -255,11 +261,24 @@ static int dsi_sf_attach(struct udevice *dev) struct display_timing timings; int ret; +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_DEVKITS) + ret = uclass_get_device_by_name(UCLASS_PANEL, "seeed_panel@45", &priv->panel); + if (ret) { + debug("Could not get seeed_panel@45: %d\n", ret); + ret = uclass_get_device_by_name(UCLASS_PANEL, "lt8911exb_i2c@29", &priv->panel); + if (ret) { + debug("Could not get lt8911exb_i2c@29: %d\n", ret); + return ret; + } + } +#else ret = uclass_first_device(UCLASS_PANEL, &priv->panel); if (ret) { debug("panel device error %d\n", ret); return ret; } +#endif + debug("%s,priv->panel->name = %s\n", __func__,priv->panel->name); mplat = dev_get_plat(priv->panel); @@ -273,14 +292,15 @@ static int dsi_sf_attach(struct udevice *dev) ret = ofnode_decode_display_timing(dev_ofnode(priv->panel), 0, &timings); if (ret) { - printf("decode display timing error %d\n", ret); + debug("decode display timing error %d\n", ret); return ret; } } + priv->timings = timings; ret = uclass_get_device(UCLASS_DSI_HOST, 0, &priv->dsi_host); if (ret) { - printf("No video dsi host detected %d\n", ret); + debug("No video dsi host detected %d\n", ret); return ret; } @@ -288,7 +308,7 @@ static int dsi_sf_attach(struct udevice *dev) mplat->lanes, &dsi_stm_phy_ops); if (ret) { - printf("failed to initialize mipi dsi host\n"); + debug("failed to initialize mipi dsi host\n"); return ret; } @@ -302,13 +322,13 @@ static int dsi_sf_set_backlight(struct udevice *dev, int percent) ret = dsi_host_enable(priv->dsi_host); if (ret) { - printf("failed to enable mipi dsi host\n"); + debug("failed to enable mipi dsi host\n"); return ret; } ret = panel_enable_backlight(priv->panel); if (ret) { - printf("panel %s enable backlight error %d\n", + debug("panel %s enable backlight error %d\n", priv->panel->name, ret); return ret; } @@ -442,7 +462,7 @@ static int dsi_sf_probe(struct udevice *dev) ret = dev_read_u32(dev, "data-lanes-num", &priv->data_lanes); if (ret) { - printf("fail to get data lanes property %d\n", ret); + debug("fail to get data lanes property %d\n", ret); return 0; } @@ -508,13 +528,13 @@ static int dsi_sf_probe(struct udevice *dev) debug("%s ok: ID_REG val = %08x\n", __func__, val); if (REV_VENDOR_ID(val) != 0xcad) { - printf("invalid vendor id\n"); + debug("invalid vendor id\n"); ret = -EINVAL; } ret = cdns_check_register_access(dev); if (ret) { - printf("error: r/w test generic reg failed\n"); + debug("error: r/w test generic reg failed\n"); } val = readl(priv->dsi_reg + IP_CONF); diff --git a/drivers/video/starfive/sf_mipi.h b/drivers/video/starfive/sf_mipi.h index 21c82340ba..dbf7f0d246 100644 --- a/drivers/video/starfive/sf_mipi.h +++ b/drivers/video/starfive/sf_mipi.h @@ -786,6 +786,7 @@ struct dsi_sf_priv { struct udevice *panel; struct udevice *dsi_host; unsigned int data_lanes; + struct display_timing timings; struct clk dsi_sys_clk; struct clk apb_clk; diff --git a/drivers/video/starfive/sf_vop.c b/drivers/video/starfive/sf_vop.c index 5f91ed7bde..a167341cd9 100644 --- a/drivers/video/starfive/sf_vop.c +++ b/drivers/video/starfive/sf_vop.c @@ -29,6 +29,7 @@ #include #include "sf_vop.h" +#include "sf_mipi.h" DECLARE_GLOBAL_DATA_PTR; @@ -398,7 +399,9 @@ static int sf_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) debug("%s(%s, 0x%lx, %s)\n", __func__, dev_read_name(dev), fbbase, ofnode_get_name(ep_node)); +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) struct udevice *panel = NULL; +#endif ret = ofnode_read_u32(ep_node, "remote-endpoint", &remote_phandle); if (ret) @@ -579,6 +582,7 @@ static int sf_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) return ret; } +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) ret = uclass_first_device_err(UCLASS_PANEL, &panel); if (ret) { if (ret != -ENODEV) @@ -595,6 +599,7 @@ static int sf_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) return ret; } } +#endif int err = clk_set_parent(&priv->dc_pix0, &priv->dc_pix_src); if (err) { @@ -603,17 +608,40 @@ static int sf_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) return err; } +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) ulong new_rate = clk_set_rate(&priv->dc_pix_src, timing.pixelclock.typ); debug("new_rate %ld\n", new_rate); +#endif dc_hw_init(dev); +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) uc_priv->xsize = timing.hactive.typ; uc_priv->ysize = timing.vactive.typ; if (IS_ENABLED(CONFIG_VIDEO_COPY)) uc_plat->copy_base = uc_plat->base - uc_plat->size / 2; +#else + struct dsi_sf_priv *private = dev_get_priv(disp); + + uc_priv->xsize = private->timings.hactive.typ; + uc_priv->ysize = private->timings.vactive.typ; + debug("uc_priv->xsize %d\n", uc_priv->xsize); + debug("uc_priv->ysize %d\n", uc_priv->ysize); + + if(uc_priv->xsize == 800) + { + ulong new_rate = clk_set_rate(&priv->dc_pix_src, 29700000); + debug("new_rate %ld\n", new_rate); + } + if(uc_priv->xsize == 1920) + { + ulong new_rate = clk_set_rate(&priv->dc_pix_src, 148500000); + debug("new_rate %ld\n", new_rate); + } +#endif +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) writel(0xc0001fff, priv->regs_hi+0x00000014); //csr_reg writel(0x000000e8, priv->regs_hi+0x00001a38); //csr_reg writel(0x00002000, priv->regs_hi+0x00001cc0); //csr_reg @@ -663,10 +691,115 @@ static int sf_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) writel(0x00000000, priv->regs_hi+0x000024fc); //csr_reg writel(0x00011b25, priv->regs_hi+0x000024e8); //csr_reg writel(0x00000001, priv->regs_hi+0x00001ccc); //csr_reg - priv->mipi_logo = true; - return 0; +#else + if(uc_priv->xsize == 800) + { + writel(0xc0001fff, priv->regs_hi+0x00000014); //csr_reg + writel(0x000000e8, priv->regs_hi+0x00001a38); //csr_reg + writel(0x00002000, priv->regs_hi+0x00001cc0); //csr_reg + writel(0x00000000, priv->regs_hi+0x000024d8); //csr_reg + writel(0x03c00438, priv->regs_hi+0x000024e0); //csr_reg + writel(0x03c00438, priv->regs_hi+0x00001810); //csr_reg + writel(uc_plat->base, priv->regs_hi+0x00001400); + writel(0x000010e0, priv->regs_hi+0x00001408); //csr_reg + writel(0x000fb00b, priv->regs_hi+0x00001ce8); //csr_reg + writel(0x0000a9a3, priv->regs_hi+0x00002510); //csr_reg + writel(0x2c4e6f06, priv->regs_hi+0x00002508); //csr_reg + writel(0xe6daec4f, priv->regs_hi+0x00002500); //csr_reg + writel(0x18220000, priv->regs_hi+0x00001518); //csr_reg + writel(0x00003000, priv->regs_hi+0x00001cc0); //csr_reg + writel(0x00030000, priv->regs_hi+0x00001cc4); //csr_reg + writel(0x00030000, priv->regs_hi+0x00001cc4); //csr_reg + writel(0x00050c1a, priv->regs_hi+0x00001540); //csr_reg + writel(0x00000001, priv->regs_hi+0x00002540); //csr_reg + writel(0x00050c1a, priv->regs_hi+0x00001540); //csr_reg + writel(0x4016120c, priv->regs_hi+0x00001544); //csr_reg + writel(0x00000002, priv->regs_hi+0x00002544); //csr_reg + writel(0x4016120c, priv->regs_hi+0x00001544); //csr_reg + writel(0x001b1208, priv->regs_hi+0x00001548); //csr_reg + writel(0x00000004, priv->regs_hi+0x00002548); //csr_reg + writel(0x001b1208, priv->regs_hi+0x00001548); //csr_reg + writel(0x0016110e, priv->regs_hi+0x0000154c); //csr_reg + writel(0x00000005, priv->regs_hi+0x0000254c); //csr_reg + writel(0x0016110e, priv->regs_hi+0x0000154c); //csr_reg + writel(0x00000001, priv->regs_hi+0x00002518); //csr_reg + writel(0x00000000, priv->regs_hi+0x00001a28); //csr_reg + writel(0x03840320, priv->regs_hi+0x00001430); //csr_reg, hsize, htotal + writel(0xc1bf837a, priv->regs_hi+0x00001438); //csr_reg, hsize blanking + writel(0x022601e0, priv->regs_hi+0x00001440); //csr_reg, vsize + writel(0xc110021c, priv->regs_hi+0x00001448); //csr_reg, vsize blanking + writel(0x00000000, priv->regs_hi+0x000014b0); //csr_reg + writel(0x000000e2, priv->regs_hi+0x00001cd0); //csr_reg + writel(0x000000af, priv->regs_hi+0x000014d0); //csr_reg + writel(0x00000005, priv->regs_hi+0x000014b8); //csr_reg + writel(0x8dd0b774, priv->regs_hi+0x00001528); //csr_reg + writel(0x00001111, priv->regs_hi+0x00001418); //csr_reg + writel(0x00000000, priv->regs_hi+0x00001410); //csr_reg + writel(0x00000000, priv->regs_hi+0x00002518); //csr_reg + writel(0x00000006, priv->regs_hi+0x00001468); //csr_reg + writel(0x00000000, priv->regs_hi+0x00001484); //csr_reg + writel(0x00000006, priv->regs_hi+0x00001468); //csr_reg + writel(0x00011b25, priv->regs_hi+0x000024e8); //csr_reg + writel(0x00000000, priv->regs_hi+0x000024fc); //csr_reg + writel(0x00011b25, priv->regs_hi+0x000024e8); //csr_reg + writel(0x00000001, priv->regs_hi+0x00001ccc); //csr_reg + } + if(uc_priv->xsize == 1920) + { + writel(0xc0001fff, priv->regs_hi+0x00000014); + writel(0x000000e8, priv->regs_hi+0x00001a38); + writel(0x00002000, priv->regs_hi+0x00001cc0); + writel(0x00000000, priv->regs_hi+0x000024d8); + writel(0x04380780, priv->regs_hi+0x000024e0); + writel(0x04380780, priv->regs_hi+0x00001810); + writel(uc_plat->base, priv->regs_hi+0x00001400); + writel(0x00001e00, priv->regs_hi+0x00001408); + writel(0x00000000, priv->regs_hi+0x00001ce8); + writel(0x0000a9a3, priv->regs_hi+0x00002510); + writel(0x2c4e6f06, priv->regs_hi+0x00002508); + writel(0xe6daec4f, priv->regs_hi+0x00002500); + writel(0x18220000, priv->regs_hi+0x00001518); + writel(0x00003000, priv->regs_hi+0x00001cc0); + writel(0x00030000, priv->regs_hi+0x00001cc4); + writel(0x00030000, priv->regs_hi+0x00001cc4); + writel(0x00050c1a, priv->regs_hi+0x00001540); + writel(0x00000001, priv->regs_hi+0x00002540); + writel(0x00050c1a, priv->regs_hi+0x00001540); + writel(0x4016120c, priv->regs_hi+0x00001544); + writel(0x00000002, priv->regs_hi+0x00002544); + writel(0x4016120c, priv->regs_hi+0x00001544); + writel(0x001b1208, priv->regs_hi+0x00001548); + writel(0x00000004, priv->regs_hi+0x00002548); + writel(0x001b1208, priv->regs_hi+0x00001548); + writel(0x0016110e, priv->regs_hi+0x0000154c); + writel(0x00000005, priv->regs_hi+0x0000254c); + writel(0x0016110e, priv->regs_hi+0x0000154c); + writel(0x00000001, priv->regs_hi+0x00002518); + writel(0x00000000, priv->regs_hi+0x00001a28); + writel(0x08980780, priv->regs_hi+0x00001430); + writel(0xc40207d8, priv->regs_hi+0x00001438); + writel(0x04650438, priv->regs_hi+0x00001440); + writel(0xc220843c, priv->regs_hi+0x00001448); + writel(0x00000000, priv->regs_hi+0x000014b0); + writel(0x000000e2, priv->regs_hi+0x00001cd0); + writel(0x000000af, priv->regs_hi+0x000014d0); + writel(0x00000005, priv->regs_hi+0x000014b8); + writel(0x8dd0b774, priv->regs_hi+0x00001528); + writel(0x00001111, priv->regs_hi+0x00001418); + writel(0x00000000, priv->regs_hi+0x00001410); + writel(0x00000000, priv->regs_hi+0x00002518); + writel(0x00000006, priv->regs_hi+0x00001468); + writel(0x00000000, priv->regs_hi+0x00001484); + writel(0x00000006, priv->regs_hi+0x00001468); + writel(0x00011b25, priv->regs_hi+0x000024e8); + writel(0x00000000, priv->regs_hi+0x000024fc); + writel(0x00011b25, priv->regs_hi+0x000024e8); + writel(0x00000001, priv->regs_hi+0x00001ccc); + } +#endif } + priv->mipi_logo = true; return 0; } -- cgit v1.2.3