// 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); }