diff options
author | andy.hu <andy.hu@starfivetech.com> | 2023-11-29 12:13:51 +0300 |
---|---|---|
committer | andy.hu <andy.hu@starfivetech.com> | 2023-11-29 12:13:51 +0300 |
commit | 918eb904cfbc79a48552fe4c842938a94fd3c1d5 (patch) | |
tree | b8370976a4fb56985bd6a974b1e864ae1240922e | |
parent | b9ea242a49cd2e7d84ca0ea9086e8a76cd92e485 (diff) | |
parent | 4bf24b47175bd55813612f0d162defcb65b94d13 (diff) | |
download | u-boot-918eb904cfbc79a48552fe4c842938a94fd3c1d5.tar.xz |
Merge branch 'CR_6790_MergeUboot_hal.feng' into 'jh7110-master'
CR_6790_MergeUboot_hal.feng
See merge request sdk/u-boot!74
63 files changed, 7021 insertions, 771 deletions
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 2cff0d9536..b8adf6ba36 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -23,8 +23,11 @@ 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_DEVKITS + bool "Support StarFive DevKits Board" + +config TARGET_STARFIVE_VISIONFIVE2 + bool "Support StarFive VisionFive2 Board" config TARGET_STARFIVE_EVB bool "Support StarFive Evb Board" @@ -71,7 +74,8 @@ 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/devkits/Kconfig" +source "board/starfive/visionfive2/Kconfig" source "board/starfive/evb/Kconfig" # platform-specific options below diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index d433afa6f4..79679c91ad 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -7,7 +7,8 @@ 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_DEVKITS) += starfive_devkits.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/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 3f3098b96b..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"; @@ -856,13 +882,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 +925,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"; diff --git a/arch/riscv/dts/starfive_visionfive-u-boot.dtsi b/arch/riscv/dts/starfive_devkits-u-boot.dtsi index a3efa43b5e..f508ab3554 100644 --- a/arch/riscv/dts/starfive_visionfive-u-boot.dtsi +++ b/arch/riscv/dts/starfive_devkits-u-boot.dtsi @@ -27,12 +27,3 @@ }; }; -&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_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 <dt-bindings/pinctrl/pinctrl-starfive-jh7110.h> +#include <dt-bindings/gpio/gpio.h> +/ { + #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 = <GPIOMUX(3, GPOUT_LOW, + GPOEN_SYS_I2C2_CLK, + GPI_SYS_I2C2_CLK)>, + <GPIOMUX(2, GPOUT_LOW, + GPOEN_SYS_I2C2_DATA, + GPI_SYS_I2C2_DATA)>; + bias-disable; /* external pull-up */ + input-enable; + input-schmitt-enable; + }; + }; + + i2c5_pins: i2c5-0 { + i2c-pins { + pinmux = <GPIOMUX(19, GPOUT_LOW, + GPOEN_SYS_I2C5_CLK, + GPI_SYS_I2C5_CLK)>, + <GPIOMUX(20, GPOUT_LOW, + GPOEN_SYS_I2C5_DATA, + GPI_SYS_I2C5_DATA)>; + bias-disable; /* external pull-up */ + input-enable; + input-schmitt-enable; + }; + }; + + mmc0_pins: mmc0-pins { + mmc0-pins-rest { + pinmux = <GPIOMUX(22, GPOUT_SYS_SDIO0_RST, + GPOEN_ENABLE, GPI_NONE)>; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + sdcard1_pins: sdcard1-pins { + sdcard1-pins0 { + pinmux = <GPIOMUX(10, GPOUT_SYS_SDIO1_CLK, + GPOEN_ENABLE, GPI_NONE)>; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + + sdcard1-pins1 { + pinmux = <GPIOMUX(9, GPOUT_SYS_SDIO1_CMD, + GPOEN_SYS_SDIO1_CMD, GPI_SYS_SDIO1_CMD)>; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins2 { + pinmux = <GPIOMUX(11, GPOUT_SYS_SDIO1_DATA0, + GPOEN_SYS_SDIO1_DATA0, GPI_SYS_SDIO1_DATA0)>; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins3 { + pinmux = <GPIOMUX(12, GPOUT_SYS_SDIO1_DATA1, + GPOEN_SYS_SDIO1_DATA1, GPI_SYS_SDIO1_DATA1)>; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins4 { + pinmux = <GPIOMUX(7, GPOUT_SYS_SDIO1_DATA2, + GPOEN_SYS_SDIO1_DATA2, GPI_SYS_SDIO1_DATA2)>; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins5 { + pinmux = <GPIOMUX(8, GPOUT_SYS_SDIO1_DATA3, + GPOEN_SYS_SDIO1_DATA3, GPI_SYS_SDIO1_DATA3)>; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + }; + + hdmi_pins: hdmi-0 { + i2c-pins { + pinmux = <GPIOMUX(0, GPOUT_SYS_HDMI_DDC_SCL, + GPOEN_SYS_HDMI_DDC_SCL, + GPI_SYS_HDMI_DDC_SCL)>, + <GPIOMUX(1, GPOUT_SYS_HDMI_DDC_SDA, + GPOEN_SYS_HDMI_DDC_SDA, + GPI_SYS_HDMI_DDC_SDA)>; + bias-pull-up; + input-enable; + }; + + cec-pins { + pinmux = <GPIOMUX(14, GPOUT_SYS_HDMI_CEC_SDA, + GPOEN_SYS_HDMI_CEC_SDA, + GPI_SYS_HDMI_CEC_SDA)>; + bias-pull-up; + input-enable; + }; + + hpd-pins { + pinmux = <GPIOMUX(15, GPOUT_LOW, + GPOEN_DISABLE, + GPI_SYS_HDMI_HPD)>; + 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"; +}; 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_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..ec8538d9dd --- /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 <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pinctrl/pinctrl-starfive-jh7110.h> +/ { + #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 = <GPIOMUX(5, GPOUT_SYS_UART0_TX, + GPOEN_ENABLE, GPI_NONE)>; + bias-disable; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + + rx-pins { + pinmux = <GPIOMUX(6, GPOUT_LOW, + GPOEN_DISABLE, GPI_SYS_UART0_RX)>; + bias-pull-up; + drive-strength = <2>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + }; + + mmc0_pins: mmc0-pins { + mmc0-pins-rest { + pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST, + GPOEN_ENABLE, GPI_NONE)>; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + sdcard1_pins: sdcard1-pins { + sdcard1-pins0 { + pinmux = <GPIOMUX(10, GPOUT_SYS_SDIO1_CLK, + GPOEN_ENABLE, GPI_NONE)>; + bias-pull-up; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + + sdcard1-pins1 { + pinmux = <GPIOMUX(9, GPOUT_SYS_SDIO1_CMD, + GPOEN_SYS_SDIO1_CMD, GPI_SYS_SDIO1_CMD)>; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins2 { + pinmux = <GPIOMUX(11, GPOUT_SYS_SDIO1_DATA0, + GPOEN_SYS_SDIO1_DATA0, GPI_SYS_SDIO1_DATA0)>; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins3 { + pinmux = <GPIOMUX(12, GPOUT_SYS_SDIO1_DATA1, + GPOEN_SYS_SDIO1_DATA1, GPI_SYS_SDIO1_DATA1)>; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins4 { + pinmux = <GPIOMUX(7, GPOUT_SYS_SDIO1_DATA2, + GPOEN_SYS_SDIO1_DATA2, GPI_SYS_SDIO1_DATA2)>; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + + sdcard1-pins5 { + pinmux = <GPIOMUX(8, GPOUT_SYS_SDIO1_DATA3, + GPOEN_SYS_SDIO1_DATA3, GPI_SYS_SDIO1_DATA3)>; + bias-pull-up; + drive-strength = <12>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + }; + + pcie0_perst_default: pcie0_perst_default { + perst-pins { + pinmux = <GPIOMUX(26, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>; + drive-strength = <2>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie0_perst_active: pcie0_perst_active { + perst-pins { + pinmux = <GPIOMUX(26, GPOUT_LOW, GPOEN_ENABLE, GPI_NONE)>; + drive-strength = <2>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie0_wake_default: pcie0_wake_default { + wake-pins { + pinmux = <GPIOMUX(32, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>; + drive-strength = <2>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie0_clkreq_default: pcie0_clkreq_default { + clkreq-pins { + pinmux = <GPIOMUX(27, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>; + drive-strength = <2>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie1_perst_default: pcie1_perst_default { + perst-pins { + pinmux = <GPIOMUX(28, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>; + drive-strength = <2>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie1_perst_active: pcie1_perst_active { + perst-pins { + pinmux = <GPIOMUX(28, GPOUT_LOW, GPOEN_ENABLE, GPI_NONE)>; + drive-strength = <2>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie1_wake_default: pcie1_wake_default { + wake-pins { + pinmux = <GPIOMUX(21, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>; + drive-strength = <2>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pcie1_clkreq_default: pcie1_clkreq_default { + clkreq-pins { + pinmux = <GPIOMUX(29, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>; + drive-strength = <2>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + i2c2_pins: i2c2-0 { + i2c-pins { + pinmux = <GPIOMUX(3, GPOUT_LOW, + GPOEN_SYS_I2C2_CLK, + GPI_SYS_I2C2_CLK)>, + <GPIOMUX(2, GPOUT_LOW, + GPOEN_SYS_I2C2_DATA, + GPI_SYS_I2C2_DATA)>; + bias-disable; /* external pull-up */ + input-enable; + input-schmitt-enable; + }; + }; + + i2c5_pins: i2c5-0 { + i2c-pins { + pinmux = <GPIOMUX(19, GPOUT_LOW, + GPOEN_SYS_I2C5_CLK, + GPI_SYS_I2C5_CLK)>, + <GPIOMUX(20, GPOUT_LOW, + GPOEN_SYS_I2C5_DATA, + GPI_SYS_I2C5_DATA)>; + bias-disable; /* external pull-up */ + input-enable; + input-schmitt-enable; + }; + }; + + hdmi_pins: hdmi-0 { + + + cec-pins { + pinmux = <GPIOMUX(14, GPOUT_SYS_HDMI_CEC_SDA, + GPOEN_SYS_HDMI_CEC_SDA, + GPI_SYS_HDMI_CEC_SDA)>; + bias-pull-up; + input-enable; + }; + + hpd-pins { + pinmux = <GPIOMUX(15, GPOUT_LOW, + GPOEN_DISABLE, + GPI_SYS_HDMI_HPD)>; + 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 = "starfive,seeed"; + reg = <0x45>; + + }; + + +}; + 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 <jianlong.huang@starfivetech.com> + */ + +#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 */ diff --git a/board/starfive/visionfive/Kconfig b/board/starfive/devkits/Kconfig index d0ed065307..b5db828ae2 100644 --- a/board/starfive/visionfive/Kconfig +++ b/board/starfive/devkits/Kconfig @@ -1,16 +1,16 @@ -if TARGET_STARFIVE_VISIONFIVE +if TARGET_STARFIVE_DEVKITS config SYS_CPU default "jh7110" config SYS_BOARD - default "visionfive" + default "devkits" config SYS_VENDOR default "starfive" config SYS_CONFIG_NAME - default "starfive-visionfive" + default "starfive-devkits" config ENV_SIZE default 0x2000 if ENV_IS_IN_SPI_FLASH 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 <yanhong.wang@starfivetech.com> +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 <common.h> +#include <command.h> +#include <env.h> +#include <i2c.h> +#include <init.h> +#include <linux/ctype.h> +#include <linux/delay.h> +//#include <u-boot/crc.h> +/* + * 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 <xx:xx:xx:xx:xx:xx>\n" + " - stores a MAC0 address into the local EEPROM copy\n" + "mac mac1_address <xx:xx:xx:xx:xx:xx>\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 <A>\n" + " - stores a StarFive BOM revision into the local EEPROM copy\n" + "mac product_id <DK7110B1-2150-D104EC32-xxxxxxxx>\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;" + * "<product>-<date>-<DDR&eMMC>-<serial_number>" + * <date>: 4Byte, should be the output of `date +%y%W` + * <DDR&eMMC>: 8Byte, "D008" means 8GB, "D01T" means 1TB; + * "E000" means no eMMC,"E032" means 32GB, "E01T" means 1TB. + * <serial_number>: 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 <yanhong.wang@starfivetech.com> + * + */ + +#include <common.h> +#include <init.h> +#include <asm/arch/spl.h> +#include <asm/io.h> +#include <asm/arch/gpio.h> +#include <asm/arch/jh7110-regs.h> +#include <asm/arch/clk.h> +#include <image.h> +#include <log.h> +#include <spl.h> + +#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 <yanhong.wang@starfivetech.com> + * + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/jh7110-regs.h> +#include <asm/gpio.h> +#include <cpu_func.h> +#include <dm/uclass.h> +#include <dm/device.h> +#include <env.h> +#include <i2c.h> +#include <inttypes.h> +#include <misc.h> +#include <linux/bitops.h> +#include <asm/arch/gpio.h> +#include <bmp_logo.h> +#include <video.h> +#include <splash.h> +#include <asm/gpio.h> +#include <linux/err.h> + + +#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<<USB_MODE_STRAP_SHIFT) & + USB_MODE_STRAP_MASK);/*2:host mode, 4:device mode*/ + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, + USB_OTG_SUSPENDM_BYPS_MASK, + BIT(USB_OTG_SUSPENDM_BYPS_SHIFT) + & USB_OTG_SUSPENDM_BYPS_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, + USB_OTG_SUSPENDM_MASK, + BIT(USB_OTG_SUSPENDM_SHIFT) & + USB_OTG_SUSPENDM_MASK);/*HOST = 1. DEVICE = 0;*/ + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, + USB_PLL_EN_MASK, + BIT(USB_PLL_EN_SHIFT) & USB_PLL_EN_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, + USB_REFCLK_MODE_MASK, + BIT(USB_REFCLK_MODE_SHIFT) & USB_REFCLK_MODE_MASK); + /* usb 2.0 phy mode,REPLACE USB3.0 PHY module = 1;else = 0*/ + clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_24, + PDRSTN_SPLIT_MASK, + BIT(PDRSTN_SPLIT_SHIFT) & + PDRSTN_SPLIT_MASK); + } else { + /*usb 3.0 pipe phy config*/ + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_196, + PCIE_CKREF_SRC_MASK, + (0<<PCIE_CKREF_SRC_SHIFT) & PCIE_CKREF_SRC_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_196, + PCIE_CLK_SEL_MASK, + (0<<PCIE_CLK_SEL_SHIFT) & PCIE_CLK_SEL_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_328, + PCIE_PHY_MODE_MASK, + BIT(PCIE_PHY_MODE_SHIFT) & PCIE_PHY_MODE_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_500, + PCIE_USB3_BUS_WIDTH_MASK, + (0 << PCIE_USB3_BUS_WIDTH_SHIFT) & + PCIE_USB3_BUS_WIDTH_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_500, + PCIE_USB3_RATE_MASK, + (0 << PCIE_USB3_RATE_SHIFT) & PCIE_USB3_RATE_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_500, + PCIE_USB3_RX_STANDBY_MASK, + (0 << PCIE_USB3_RX_STANDBY_SHIFT) + & PCIE_USB3_RX_STANDBY_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_500, + PCIE_USB3_PHY_ENABLE_MASK, + BIT(PCIE_USB3_PHY_ENABLE_SHIFT) + & PCIE_USB3_PHY_ENABLE_MASK); + + /* usb 3.0 phy mode,REPLACE USB3.0 PHY module = 1;else = 0*/ + clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_24, + PDRSTN_SPLIT_MASK, + (0 << PDRSTN_SPLIT_SHIFT) & PDRSTN_SPLIT_MASK); + } +} + +#if CONFIG_IS_ENABLED(STARFIVE_OTP) +static void get_cpu_voltage_type(struct udevice *dev) +{ + int ret; + u32 buf = CPU_VOL_1040; + + ret = misc_read(dev, CPU_VOL_BINNING_OFFSET, &buf, sizeof(buf)); + if (ret != sizeof(buf)) + printf("%s: error reading CPU vol from OTP\n", __func__); + else { + switch ((buf & CPU_VOL_MASK)) { + case CPU_VOL_1000: + env_set("cpu_max_vol", "1000000"); + break; + case CPU_VOL_1060: + env_set("cpu_max_vol", "1060000"); + break; + case CPU_VOL_1020: + env_set("cpu_max_vol", "1020000"); + break; + default: + env_set("cpu_max_vol", "1040000"); + break; + } + } +} +#endif + +static void get_boot_mode(void) +{ + u32 value; + + value = in_le32(AON_IOMUX_BASE + AON_GPIO_DIN_REG); + switch (value & 0x03) { + case BOOT_FLASH: + env_set("bootmode", "flash"); + env_set("devnum", "1"); + break; + + case BOOT_SD: + env_set("bootmode", "sd"); + env_set("devnum", "1"); + break; + + case BOOT_EMMC: + env_set("bootmode", "emmc"); + env_set("devnum", "0"); + break; + + default: + env_set("bootmode", "uart"); + env_set("devnum", "1"); + break; + } +} + +#define CONFIG_SYS_PMIC_BUS_NUM 5 +#define CONFIG_SYS_I2C_PMIC_ADDR 0x36 +#define CONFIG_SYS_I2C_PMIC_ADDR_LEN 1 +#define AXP15060_DCDC_MODE_CTRL_2 0x1b +#define AXP15060_DCDC5_MODE_BIT BIT(4) +#define AXP15060_PWR_SEQUENCE_CTRL 0X32 +#define AXP15060_RST_PMIC_BY_PWROK_BIT BIT(4) + +int set_pmic(void) +{ + int ret; + struct udevice *dev; + u8 temp_buf; + + ret = i2c_get_chip_for_busnum(CONFIG_SYS_PMIC_BUS_NUM, + CONFIG_SYS_I2C_PMIC_ADDR, + CONFIG_SYS_I2C_PMIC_ADDR_LEN, + &dev); + + if (!ret) { + /* Set Pmic DCDC5 Mode as PWM */ + ret = dm_i2c_read(dev, + AXP15060_DCDC_MODE_CTRL_2, + &temp_buf, + sizeof(temp_buf)); + if (ret) + printf("%s: can't read pmic dcdc5 mode register\n", + __func__); + + temp_buf = temp_buf | AXP15060_DCDC5_MODE_BIT; + ret = dm_i2c_write(dev, + AXP15060_DCDC_MODE_CTRL_2, + &temp_buf, + sizeof(temp_buf)); + if (ret) + printf("%s: can't write pmic dcdc5 mode register\n", + __func__); + + /* Enable PWROK in PMIC */ + ret = dm_i2c_read(dev, + AXP15060_PWR_SEQUENCE_CTRL, + &temp_buf, + sizeof(temp_buf)); + if (ret) + printf("%s: can't read pmic power disbale & down sequence register\n", + __func__); + + temp_buf = temp_buf | AXP15060_RST_PMIC_BY_PWROK_BIT; + ret = dm_i2c_write(dev, + AXP15060_PWR_SEQUENCE_CTRL, + &temp_buf, + sizeof(temp_buf)); + if (ret) + printf("%s: can't write pmic power disbale & down sequence register\n", + __func__); + + } + + return 0; +} + +int board_init(void) +{ + enable_caches(); + + jh7110_timer_init(); + jh7110_usb_init(true); + jh7110_gmac_init(0); + jh7110_gmac_init(1); + jh7110_i2c_init(5); + + return 0; +} + +#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); + +#if CONFIG_IS_ENABLED(STARFIVE_OTP) + get_cpu_voltage_type(dev); +#endif + return 0; +} +#endif + +int board_late_init(void) +{ + struct udevice *dev; + int ret; + + get_boot_mode(); + + env_set("chip_vision", "B"); + + /* + * save the memory info by environment variable in u-boot, + * It will used to update the memory configuration in dts, + * which passed to kernel lately. + */ + env_set_hex("memory_addr", gd->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/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/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 <yanhong.wang@starfivetech.com> - * - */ - -#include <common.h> -#include <init.h> -#include <spl.h> -#include <log.h> -#include <linux/delay.h> -#include <image.h> -#include <asm/arch/spl.h> -#include <asm/io.h> - -#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 <yanhong.wang@starfivetech.com> - * - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/arch/jh7110-regs.h> -#include <cpu_func.h> -#include <dm/uclass.h> -#include <dm/device.h> -#include <env.h> -#include <inttypes.h> -#include <misc.h> -#include <linux/bitops.h> -#include <asm/arch/gpio.h> - -#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<<USB_MODE_STRAP_SHIFT) & USB_MODE_STRAP_MASK); - clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, - USB_OTG_SUSPENDM_BYPS_MASK, - BIT(USB_OTG_SUSPENDM_BYPS_SHIFT) - & USB_OTG_SUSPENDM_BYPS_MASK); - - clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, - USB_OTG_SUSPENDM_MASK, - BIT(USB_OTG_SUSPENDM_SHIFT) & USB_OTG_SUSPENDM_MASK); - clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, - USB_PLL_EN_MASK, - BIT(USB_PLL_EN_SHIFT) & USB_PLL_EN_MASK); - clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, - USB_REFCLK_MODE_MASK, - BIT(USB_REFCLK_MODE_SHIFT) & USB_REFCLK_MODE_MASK); - - clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_24, - PDRSTN_SPLIT_MASK, - BIT(PDRSTN_SPLIT_SHIFT) & PDRSTN_SPLIT_MASK); - clrsetbits_le32(SYS_IOMUX_BASE + SYS_IOMUX_32, - IOMUX_USB_MASK, - BIT(IOMUX_USB_SHIFT) & IOMUX_USB_MASK); -} - -static void jh7110_mmc_init(int id) -{ - if (id == 0) { - SYS_IOMUX_DOEN(62, LOW); - SYS_IOMUX_DOUT(62, 19); - } else { - SYS_IOMUX_DOEN(10, LOW); - SYS_IOMUX_DOUT(10, 55); - SYS_IOMUX_COMPLEX(9, 44, 57, 19); - SYS_IOMUX_COMPLEX(11, 45, 58, 20); - SYS_IOMUX_COMPLEX(12, 46, 59, 21); - SYS_IOMUX_COMPLEX(7, 47, 60, 22); - SYS_IOMUX_COMPLEX(8, 48, 61, 23); - } -} - -/*enable U74-mc hart1~hart4 prefetcher*/ -static void enable_prefetcher(void) -{ - u32 hart; - u32 *reg; -#define L2_PREFETCHER_BASE_ADDR 0x2030000 -#define L2_PREFETCHER_OFFSET 0x2000 - - /*hart1~hart4*/ - for (hart = 1; hart < 5; hart++) { - reg = (u32 *)((u64)(L2_PREFETCHER_BASE_ADDR - + hart*L2_PREFETCHER_OFFSET)); - - mb(); /* memory barrier */ - setbits_le32(reg, 0x1); - mb(); /* memory barrier */ - } -} - -int board_init(void) -{ - enable_caches(); - - /*enable hart1-hart4 prefetcher*/ -// enable_prefetcher(); - - jh7110_gmac_init(0); - jh7110_gmac_init(1); - jh7110_timer_init(); - - jh7110_usb_init(); - - jh7110_mmc_init(0); - jh7110_mmc_init(1); - - return 0; -} - -#ifdef CONFIG_MISC_INIT_R - -int misc_init_r(void) -{ - char mac[6] = {0x66, 0x34, 0xb0, 0x6c, 0xde, 0xad }; - -#if CONFIG_IS_ENABLED(STARFIVE_OTP) - struct udevice *dev; - char buf[8]; - 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(mac, buf, 6); -err: -#endif - eth_env_set_enetaddr("ethaddr", mac); - - return 0; -} -#endif - diff --git a/board/starfive/visionfive2/Kconfig b/board/starfive/visionfive2/Kconfig new file mode 100644 index 0000000000..28bde2a09b --- /dev/null +++ b/board/starfive/visionfive2/Kconfig @@ -0,0 +1,52 @@ +if TARGET_STARFIVE_VISIONFIVE2 + +config SYS_CPU + default "jh7110" + +config SYS_BOARD + default "visionfive2" + +config SYS_VENDOR + default "starfive" + +config SYS_CONFIG_NAME + default "starfive-visionfive2" + +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/visionfive2/MAINTAINERS b/board/starfive/visionfive2/MAINTAINERS new file mode 100644 index 0000000000..600ff9575b --- /dev/null +++ b/board/starfive/visionfive2/MAINTAINERS @@ -0,0 +1,7 @@ +STARFIVE JH7110 VISIONFIVE2 BOARD +M: Yanhong Wang <yanhong.wang@starfivetech.com> +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/visionfive/Makefile b/board/starfive/visionfive2/Makefile index 841d5d9b2d..080eed87b2 100644 --- a/board/starfive/visionfive/Makefile +++ b/board/starfive/visionfive2/Makefile @@ -3,7 +3,7 @@ # Copyright (C) 2022-2023 StarFive Technology Co., Ltd. # -obj-y := starfive_visionfive.o +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 <yanhong.wang@starfivetech.com> + * + */ + +#include <common.h> +#include <init.h> +#include <asm/arch/spl.h> +#include <asm/io.h> +#include <asm/arch/gpio.h> +#include <asm/arch/jh7110-regs.h> +#include <asm/arch/clk.h> +#include <image.h> +#include <log.h> +#include <spl.h> + +#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 <yanhong.wang@starfivetech.com> + * + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/eeprom.h> +#include <asm/arch/jh7110-regs.h> +#include <cpu_func.h> +#include <dm/uclass.h> +#include <dm/device.h> +#include <env.h> +#include <inttypes.h> +#include <misc.h> +#include <linux/bitops.h> +#include <asm/arch/gpio.h> +#include <bmp_logo.h> +#include <video.h> +#include <splash.h> + +#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<<USB_MODE_STRAP_SHIFT) & + USB_MODE_STRAP_MASK);/*2:host mode, 4:device mode*/ + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, + USB_OTG_SUSPENDM_BYPS_MASK, + BIT(USB_OTG_SUSPENDM_BYPS_SHIFT) + & USB_OTG_SUSPENDM_BYPS_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, + USB_OTG_SUSPENDM_MASK, + BIT(USB_OTG_SUSPENDM_SHIFT) & + USB_OTG_SUSPENDM_MASK);/*HOST = 1. DEVICE = 0;*/ + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, + USB_PLL_EN_MASK, + BIT(USB_PLL_EN_SHIFT) & USB_PLL_EN_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4, + USB_REFCLK_MODE_MASK, + BIT(USB_REFCLK_MODE_SHIFT) & USB_REFCLK_MODE_MASK); + /* usb 2.0 phy mode,REPLACE USB3.0 PHY module = 1;else = 0*/ + clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_24, + PDRSTN_SPLIT_MASK, + BIT(PDRSTN_SPLIT_SHIFT) & + PDRSTN_SPLIT_MASK); + } else { + /*usb 3.0 pipe phy config*/ + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_196, + PCIE_CKREF_SRC_MASK, + (0<<PCIE_CKREF_SRC_SHIFT) & PCIE_CKREF_SRC_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_196, + PCIE_CLK_SEL_MASK, + (0<<PCIE_CLK_SEL_SHIFT) & PCIE_CLK_SEL_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_328, + PCIE_PHY_MODE_MASK, + BIT(PCIE_PHY_MODE_SHIFT) & PCIE_PHY_MODE_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_500, + PCIE_USB3_BUS_WIDTH_MASK, + (0 << PCIE_USB3_BUS_WIDTH_SHIFT) & + PCIE_USB3_BUS_WIDTH_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_500, + PCIE_USB3_RATE_MASK, + (0 << PCIE_USB3_RATE_SHIFT) & PCIE_USB3_RATE_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_500, + PCIE_USB3_RX_STANDBY_MASK, + (0 << PCIE_USB3_RX_STANDBY_SHIFT) + & PCIE_USB3_RX_STANDBY_MASK); + clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_500, + PCIE_USB3_PHY_ENABLE_MASK, + BIT(PCIE_USB3_PHY_ENABLE_SHIFT) + & PCIE_USB3_PHY_ENABLE_MASK); + + /* usb 3.0 phy mode,REPLACE USB3.0 PHY module = 1;else = 0*/ + clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_24, + PDRSTN_SPLIT_MASK, + (0 << PDRSTN_SPLIT_SHIFT) & PDRSTN_SPLIT_MASK); + } + SYS_IOMUX_DOEN(25, LOW); + SYS_IOMUX_DOUT(25, 7); +} + +#if CONFIG_IS_ENABLED(STARFIVE_OTP) +static void get_cpu_voltage_type(struct udevice *dev) +{ + int ret; + u32 buf = CPU_VOL_1040; + + ret = misc_read(dev, CPU_VOL_BINNING_OFFSET, &buf, sizeof(buf)); + if (ret != sizeof(buf)) + printf("%s: error reading CPU vol from OTP\n", __func__); + else { + switch ((buf & CPU_VOL_MASK)) { + case CPU_VOL_1000: + env_set("cpu_max_vol", "1000000"); + break; + case CPU_VOL_1060: + env_set("cpu_max_vol", "1060000"); + break; + case CPU_VOL_1020: + env_set("cpu_max_vol", "1020000"); + break; + default: + env_set("cpu_max_vol", "1040000"); + break; + } + } +} +#endif + +static void jh7110_jtag_init(void) +{ + /*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); +} + +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 get_boot_mode(void) +{ + u32 value; + + value = in_le32(AON_IOMUX_BASE + AON_GPIO_DIN_REG); + switch (value & 0x03) { + case BOOT_FLASH: + env_set("bootmode", "flash"); + env_set("devnum", "1"); + break; + + case BOOT_SD: + env_set("bootmode", "sd"); + env_set("devnum", "1"); + break; + + case BOOT_EMMC: + env_set("bootmode", "emmc"); + env_set("devnum", "0"); + break; + + default: + env_set("bootmode", "uart"); + env_set("devnum", "1"); + break; + } +} + +static void jh7110_gpio_init(void) +{ + /* This is for fixing don't detect wm8960 occasionally. + * Set scl/sda gpio output enable + * Set drive strength to 12mA + * Set gpio pull up + */ + SYS_IOMUX_COMPLEX(57, 9, 0, 1); + SYS_IOMUX_SET_DS(57, 3); + SYS_IOMUX_SET_PULL(57, GPIO_PULL_UP); + + SYS_IOMUX_COMPLEX(58, 10, 0, 1); + SYS_IOMUX_SET_DS(58, 3); + SYS_IOMUX_SET_PULL(58, GPIO_PULL_UP); +} + +int board_init(void) +{ + enable_caches(); + + jh7110_jtag_init(); + jh7110_timer_init(); + + jh7110_usb_init(true); + + jh7110_i2c_init(5); + jh7110_gpio_init(); + + return 0; +} + +#ifdef CONFIG_BOARD_LATE_INIT +int board_late_init(void) +{ + struct udevice *dev; + int ret; + + get_boot_mode(); + + jh7110_gmac_init(get_chip_type(), get_board_type()); + /* + * save the memory info by environment variable in u-boot, + * It will used to update the memory configuration in dts, + * which passed to kernel lately. + */ + env_set_hex("memory_addr", gd->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 <asm/arch/eeprom.h> +#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 <common.h> +#include <command.h> +#include <env.h> +#include <i2c.h> +#include <init.h> +#include <linux/ctype.h> +#include <linux/delay.h> + +#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 <xx:xx:xx:xx:xx:xx>\n" + " - stores a MAC0 address into the local EEPROM copy\n" + "mac mac1_address <xx:xx:xx:xx:xx:xx>\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 <A>\n" + " - stores a StarFive BOM revision into the local EEPROM copy\n" + "mac product_id <VF7110A1-2228-D008E000-xxxxxxxx>\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;" + * "<product>-<date>-<DDR&eMMC>-<serial_number>" + * <date>: 4Byte, should be the output of `date +%y%W` + * <DDR&eMMC>: 8Byte, "D008" means 8GB, "D01T" means 1TB; + * "E000" means no eMMC,"E032" means 32GB, "E01T" means 1TB. + * <serial_number>: 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/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 efd6f3ac03..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; } @@ -218,10 +203,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; } @@ -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; } @@ -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) 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 @@ -690,6 +690,9 @@ static init_fnc_t init_sequence_r[] = { #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 initr_flash, 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 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 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, 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 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; } 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); 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; } diff --git a/drivers/pci/pcie_starfive.c b/drivers/pci/pcie_starfive.c index d5a812d36a..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,15 +373,32 @@ static int starfive_pcie_init_port(struct udevice *dev) goto err_deassert_clk; } +#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); - 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; +#endif + } + dm_gpio_set_value(priv->reset_gpio, 1); } /* Disable physical functions except #0 */ @@ -440,14 +459,20 @@ 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) || CONFIG_IS_ENABLED(TARGET_STARFIVE_DEVKITS) err_release_power_pin: pinctrl_select_state(dev, "power-default"); +#endif err_deassert_reset: reset_assert_bulk(&priv->rsts); err_deassert_clk: 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 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[] = { 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..bfab1e3d9c 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -57,7 +57,8 @@ 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 obj-$(CONFIG_VIDEO_MCDE_SIMPLE) += mcde_simple.o 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 4521f7c869..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); @@ -159,12 +165,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); @@ -246,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); @@ -264,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; } @@ -279,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; } @@ -293,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; } @@ -433,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; } @@ -499,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 e786032429..a167341cd9 100644 --- a/drivers/video/starfive/sf_vop.c +++ b/drivers/video/starfive/sf_vop.c @@ -29,6 +29,7 @@ #include <panel.h> #include "sf_vop.h" +#include "sf_mipi.h" DECLARE_GLOBAL_DATA_PTR; @@ -43,7 +44,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 +76,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 +110,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 +123,7 @@ static int sf_vop_power(struct udevice *dev) pr_err("failed to update SD control register: %d", ret); return ret; } +#endif return 0; } @@ -395,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) @@ -576,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) @@ -592,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) { @@ -600,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 @@ -660,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; } 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 <yannick.fertre@st.com> for STMicroelectronics. + * Philippe Cornu <philippe.cornu@st.com> for STMicroelectronics. + * + * This edp panel driver is inspired from the Linux Kernel driver + * drivers/gpu/drm/panel/panel-raydium-edp.c. + */ +#include <common.h> +#include <backlight.h> +#include <dm.h> +#include <mipi_dsi.h> +#include <panel.h> +#include <asm/gpio.h> +#include <dm/device_compat.h> +#include <linux/delay.h> +#include <power/regulator.h> +#include <i2c.h> +#include <asm/arch/gpio.h> +#include <asm/arch/jh7110-regs.h> +#include <asm/io.h> + + +#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), +}; diff --git a/drivers/video/raydium-rm68200-starfive.c b/drivers/video/starfive_seeed_panel.c index c4234d58f2..636974fd7e 100644 --- a/drivers/video/raydium-rm68200-starfive.c +++ b/drivers/video/starfive_seeed_panel.c @@ -4,8 +4,8 @@ * Author(s): Yannick Fertre <yannick.fertre@st.com> for STMicroelectronics. * Philippe Cornu <philippe.cornu@st.com> for STMicroelectronics. * - * This rm68200 panel driver is inspired from the Linux Kernel driver - * drivers/gpu/drm/panel/panel-raydium-rm68200.c. + * This seeed panel driver is inspired from the Linux Kernel driver + * drivers/gpu/drm/panel/panel-raydium-seeed.c. */ #include <common.h> #include <backlight.h> @@ -145,15 +145,16 @@ enum REG_ADDR { /* Chip/Rev Registers */ #define IDREG 0x04A0 -/* Debug Registers */ +/* printf Registers */ #define WCMDQUEUE 0x0500 #define RCMDQUEUE 0x0504 -struct rm68200_panel_priv { +struct seeed_panel_priv { struct udevice *reg; struct udevice *backlight; - struct gpio_desc reset; + struct gpio_desc *sel_gpio; //select + }; static const struct display_timing default_timing = { @@ -292,6 +293,9 @@ static int rm68200_panel_of_to_plat(struct udevice *dev) 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; @@ -315,6 +319,17 @@ static int rm68200_panel_probe(struct udevice *dev) 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; } @@ -324,17 +339,17 @@ static const struct panel_ops rm68200_panel_ops = { }; static const struct udevice_id rm68200_panel_ids[] = { - { .compatible = "raydium,rm68200" }, + { .compatible = "starfive,seeed" }, { } }; -U_BOOT_DRIVER(rm68200_panel) = { - .name = "rm68200_panel", +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 rm68200_panel_priv), + .priv_auto = sizeof(struct seeed_panel_priv), }; 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), 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 <yanhong.wang@starfivetech.com> + */ + +#ifndef _STARFIVE_DEVKITS_H +#define _STARFIVE_DEVKITS_H + +#include <version.h> +#include <linux/sizes.h> + +#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 <config_distro_bootcmd.h> + + +#include <environment/distro/sf.h> + +#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 */ 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 <yanhong.wang@starfivetech.com> - */ - - -#ifndef _STARFIVE_VISIONFIVE_H -#define _STARFIVE_VISIONFIVE_H - -#include <version.h> -#include <linux/sizes.h> - -#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 <config_distro_bootcmd.h> - - -#include <environment/distro/sf.h> - -#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 <yanhong.wang@starfivetech.com> + */ + + +#ifndef _STARFIVE_VISIONFIVE2_H +#define _STARFIVE_VISIONFIVE2_H + +#include <version.h> +#include <linux/sizes.h> + +#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 <config_distro_bootcmd.h> + + +#include <environment/distro/sf.h> + +#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 */ + 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 <efi_api.h> + +#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/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); 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 <common.h> +#include <efi_loader.h> +#include <efi_variable.h> +#include <log.h> +#include <asm/global_data.h> +#include <efi_riscv.h> + +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) |