summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS2
-rw-r--r--README21
-rw-r--r--arch/arm/Kconfig6
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/spl_boot.c6
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/spl_power_init.c38
-rw-r--r--arch/arm/dts/Makefile4
-rw-r--r--arch/arm/dts/ac5-98dx25xx.dtsi9
-rw-r--r--arch/arm/dts/ac5-98dx35xx-atl-x240.dts212
-rw-r--r--arch/arm/dts/ac5-98dx35xx-rd.dts1
-rw-r--r--arch/arm/dts/armada-385-thecus-n2350.dts223
-rw-r--r--arch/arm/dts/imx28-xea-u-boot.dtsi45
-rw-r--r--arch/arm/dts/imx8mm-beacon-kit-u-boot.dtsi4
-rw-r--r--arch/arm/dts/imx8mm-mx8menlo.dts17
-rw-r--r--arch/arm/dts/imx8mm-verdin-dahlia.dtsi150
-rw-r--r--arch/arm/dts/imx8mm-verdin-dev.dtsi97
-rw-r--r--arch/arm/dts/imx8mm-verdin-wifi-dev-u-boot.dtsi8
-rw-r--r--arch/arm/dts/imx8mm-verdin.dtsi30
-rw-r--r--arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi17
-rw-r--r--arch/arm/dts/imx8mn-var-som-symphony.dts4
-rw-r--r--arch/arm/dts/imx8mn-var-som.dtsi18
-rw-r--r--arch/arm/dts/imx8mp-beacon-kit-u-boot.dtsi2
-rw-r--r--arch/arm/dts/imx8mp-u-boot.dtsi3
-rw-r--r--arch/arm/dts/imx8mp-venice-gw702x-u-boot.dtsi12
-rw-r--r--arch/arm/dts/imx8mp-venice-gw702x.dtsi587
-rw-r--r--arch/arm/dts/imx8mp-venice-gw7905-2x-u-boot.dtsi51
-rw-r--r--arch/arm/dts/imx8mp-venice-gw7905-2x.dts28
-rw-r--r--arch/arm/dts/imx8mp-venice-gw7905.dtsi309
-rw-r--r--arch/arm/dts/imx8mp-verdin-dahlia.dtsi129
-rw-r--r--arch/arm/dts/imx8mp-verdin-dev.dtsi125
-rw-r--r--arch/arm/dts/imx8mp-verdin-wifi-dev-u-boot.dtsi8
-rw-r--r--arch/arm/dts/imx8mp-verdin-wifi.dtsi5
-rw-r--r--arch/arm/dts/imx8mp-verdin.dtsi91
-rw-r--r--arch/arm/dts/imx8mp.dtsi502
-rw-r--r--arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi33
-rw-r--r--arch/arm/include/asm/arch-imx8m/imx-regs.h3
-rw-r--r--arch/arm/include/asm/arch-imx9/ccm_regs.h2
-rw-r--r--arch/arm/include/asm/arch-mx6/imx-regs.h2
-rw-r--r--arch/arm/include/asm/arch-mx7/imx-regs.h2
-rw-r--r--arch/arm/include/asm/arch-npcm8xx/gcr.h1
-rw-r--r--arch/arm/include/asm/global_data.h4
-rw-r--r--arch/arm/include/asm/mach-imx/ahab.h15
-rw-r--r--arch/arm/include/asm/mach-imx/ele_api.h (renamed from arch/arm/include/asm/mach-imx/s400_api.h)53
-rw-r--r--arch/arm/include/asm/mach-imx/sys_proto.h1
-rw-r--r--arch/arm/mach-imx/Kconfig9
-rw-r--r--arch/arm/mach-imx/Makefile5
-rw-r--r--arch/arm/mach-imx/cmd_dek.c89
-rw-r--r--arch/arm/mach-imx/ele_ahab.c91
-rw-r--r--arch/arm/mach-imx/hab.c41
-rw-r--r--arch/arm/mach-imx/image-container.c96
-rw-r--r--arch/arm/mach-imx/imx8/ahab.c161
-rw-r--r--arch/arm/mach-imx/imx8/cpu.c180
-rw-r--r--arch/arm/mach-imx/imx8/fdt.c2
-rw-r--r--arch/arm/mach-imx/imx8/snvs_security_sc.c175
-rw-r--r--arch/arm/mach-imx/imx8m/Kconfig13
-rw-r--r--arch/arm/mach-imx/imx8m/clock_imx8mm.c1
-rw-r--r--arch/arm/mach-imx/imx8m/soc.c4
-rw-r--r--arch/arm/mach-imx/imx8ulp/Makefile1
-rw-r--r--arch/arm/mach-imx/imx8ulp/rdc.c18
-rw-r--r--arch/arm/mach-imx/imx8ulp/soc.c16
-rw-r--r--arch/arm/mach-imx/imx8ulp/upower/upower_hal.c6
-rw-r--r--arch/arm/mach-imx/imx9/clock.c8
-rw-r--r--arch/arm/mach-imx/imx9/clock_root.c2
-rw-r--r--arch/arm/mach-imx/imx9/imx_bootaux.c6
-rw-r--r--arch/arm/mach-imx/imx9/soc.c44
-rw-r--r--arch/arm/mach-imx/imx9/trdc.c14
-rw-r--r--arch/arm/mach-imx/imx_bootaux.c45
-rw-r--r--arch/arm/mach-imx/mx6/module_fuse.c2
-rw-r--r--arch/arm/mach-imx/mxs/Kconfig23
-rw-r--r--arch/arm/mach-imx/parse-container.c119
-rw-r--r--arch/arm/mach-imx/priblob.c10
-rw-r--r--arch/arm/mach-imx/spl_imx_romapi.c32
-rw-r--r--arch/arm/mach-mvebu/Kconfig7
-rw-r--r--arch/arm/mach-mvebu/alleycat5/soc.c6
-rw-r--r--arch/arm/mach-npcm/npcm8xx/cpu.c12
-rw-r--r--arch/powerpc/lib/Kconfig10
-rw-r--r--arch/riscv/Kconfig17
-rw-r--r--arch/riscv/cpu/fu540/Kconfig2
-rw-r--r--arch/riscv/cpu/fu740/Kconfig2
-rw-r--r--arch/riscv/cpu/generic/Kconfig4
-rw-r--r--arch/riscv/cpu/jh7110/Kconfig2
-rw-r--r--arch/riscv/cpu/jh7110/spl.c32
-rw-r--r--arch/riscv/dts/Makefile4
-rw-r--r--arch/riscv/dts/jh7110-starfive-visionfive-2-u-boot.dtsi (renamed from arch/riscv/dts/jh7110-starfive-visionfive-2-v1.3b-u-boot.dtsi)39
-rw-r--r--arch/riscv/dts/jh7110-starfive-visionfive-2-v1.2a-u-boot.dtsi69
-rw-r--r--arch/riscv/dts/jh7110-starfive-visionfive-2-v1.2a.dts12
-rw-r--r--arch/riscv/dts/jh7110-starfive-visionfive-2.dts (renamed from arch/riscv/dts/jh7110-starfive-visionfive-2-v1.3b.dts)3
-rw-r--r--arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi40
-rw-r--r--arch/riscv/dts/jh7110.dtsi69
-rw-r--r--arch/riscv/dts/th1520-lichee-module-4a.dtsi34
-rw-r--r--arch/riscv/dts/th1520-lichee-pi-4a.dts32
-rw-r--r--arch/riscv/dts/th1520.dtsi406
-rw-r--r--arch/riscv/include/asm/arch-jh7110/eeprom.h13
-rw-r--r--arch/riscv/include/asm/global_data.h4
-rw-r--r--arch/riscv/include/asm/syscon.h2
-rw-r--r--arch/riscv/lib/Makefile2
-rw-r--r--arch/riscv/lib/aclint_ipi.c (renamed from arch/riscv/lib/sifive_clint.c)31
-rw-r--r--arch/sandbox/cpu/sdl.c3
-rw-r--r--arch/sandbox/dts/cedit.dtsi64
-rw-r--r--arch/sandbox/dts/sandbox.dtsi6
-rw-r--r--arch/sandbox/dts/test.dts13
-rw-r--r--board/advantech/imx8qm_dmsse20_a1/spl.c6
-rw-r--r--board/advantech/imx8qm_rom7720_a1/spl.c6
-rw-r--r--board/alliedtelesis/x240/MAINTAINERS7
-rw-r--r--board/alliedtelesis/x240/Makefile6
-rw-r--r--board/alliedtelesis/x240/x240.c13
-rw-r--r--board/beacon/imx8mm/MAINTAINERS1
-rw-r--r--board/beacon/imx8mm/README37
-rw-r--r--board/beacon/imx8mm/imx8mm_beacon.env19
-rw-r--r--board/beacon/imx8mm/spl.c7
-rw-r--r--board/beacon/imx8mn/README38
-rw-r--r--board/beacon/imx8mn/imx8mn_beacon.env25
-rw-r--r--board/congatec/cgtqmx8/cgtqmx8.c8
-rw-r--r--board/data_modul/imx8mp_edm_sbc/spl.c14
-rw-r--r--board/freescale/imx8ulp_evk/spl.c20
-rw-r--r--board/freescale/imx93_evk/spl.c1
-rw-r--r--board/freescale/mx7dsabresd/mx7dsabresd.c6
-rw-r--r--board/gateworks/venice/eeprom.c5
-rw-r--r--board/gateworks/venice/lpddr4_timing.h1
-rw-r--r--board/gateworks/venice/lpddr4_timing_imx8mp.c532
-rw-r--r--board/gateworks/venice/spl.c46
-rw-r--r--board/gateworks/venice/venice.c89
-rw-r--r--board/gateworks/venice/venice.env7
-rw-r--r--board/kontron/sl-mx8mm/sl-mx8mm.c2
-rw-r--r--board/kontron/sl-mx8mm/spl.c2
-rw-r--r--board/liebherr/xea/xea.c20
-rw-r--r--board/nuvoton/arbel_evb/Kconfig4
-rw-r--r--board/nuvoton/arbel_evb/arbel_evb.c70
-rw-r--r--board/nuvoton/poleg_evb/poleg_evb.c7
-rw-r--r--board/openpiton/riscv64/Kconfig2
-rw-r--r--board/phytec/phycore_imx8mm/lpddr4_timing.c1486
-rw-r--r--board/siemens/capricorn/board.c12
-rw-r--r--board/sipeed/maix/Kconfig2
-rw-r--r--board/starfive/visionfive2/Makefile1
-rw-r--r--board/starfive/visionfive2/spl.c157
-rw-r--r--board/starfive/visionfive2/starfive_visionfive2.c13
-rw-r--r--board/starfive/visionfive2/visionfive2-i2c-eeprom.c561
-rw-r--r--board/technexion/pico-imx8mq/pico-imx8mq.c2
-rw-r--r--board/technexion/pico-imx8mq/spl.c2
-rw-r--r--board/thead/th1520_lpi4a/Kconfig42
-rw-r--r--board/thead/th1520_lpi4a/MAINTAINERS7
-rw-r--r--board/thead/th1520_lpi4a/Makefile5
-rw-r--r--board/thead/th1520_lpi4a/board.c15
-rw-r--r--board/thecus/n2350/n2350.c2
-rw-r--r--board/toradex/apalis-imx8/apalis-imx8.c10
-rw-r--r--board/toradex/colibri-imx8x/colibri-imx8x.c20
-rw-r--r--board/toradex/colibri_imx6/colibri_imx6.c6
-rw-r--r--board/toradex/common/tdx-cfg-block.c1
-rw-r--r--board/toradex/common/tdx-cfg-block.h2
-rw-r--r--board/toradex/verdin-imx8mm/MAINTAINERS1
-rw-r--r--board/toradex/verdin-imx8mp/MAINTAINERS1
-rw-r--r--board/toradex/verdin-imx8mp/verdin-imx8mp.c3
-rw-r--r--board/variscite/imx8mn_var_som/imx8mn_var_som.c214
-rw-r--r--boot/Kconfig14
-rw-r--r--boot/Makefile3
-rw-r--r--boot/bootflow_menu.c6
-rw-r--r--boot/bootmeth-uclass.c30
-rw-r--r--boot/cedit.c163
-rw-r--r--boot/expo.c102
-rw-r--r--boot/expo_build.c401
-rw-r--r--boot/scene.c361
-rw-r--r--boot/scene_internal.h84
-rw-r--r--boot/scene_menu.c290
-rw-r--r--cmd/Kconfig10
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/bootmenu.c4
-rw-r--r--cmd/cat.c47
-rw-r--r--cmd/cedit.c93
-rw-r--r--cmd/eficonfig.c410
-rw-r--r--common/board_f.c2
-rw-r--r--common/hash.c8
-rw-r--r--common/log.c1
-rw-r--r--configs/10m50_defconfig1
-rw-r--r--configs/3c120_defconfig1
-rw-r--r--configs/CMPC885_defconfig1
-rw-r--r--configs/CMPCPRO_defconfig1
-rw-r--r--configs/apalis-tk1_defconfig1
-rw-r--r--configs/apalis_imx6_defconfig1
-rw-r--r--configs/apalis_t30_defconfig1
-rw-r--r--configs/arbel_evb_defconfig15
-rw-r--r--configs/bayleybay_defconfig1
-rw-r--r--configs/beaver_defconfig1
-rw-r--r--configs/bitmain_antminer_s9_defconfig1
-rw-r--r--configs/brppt1_mmc_defconfig1
-rw-r--r--configs/brppt2_defconfig1
-rw-r--r--configs/brsmarc1_defconfig1
-rw-r--r--configs/brxre1_defconfig1
-rw-r--r--configs/cardhu_defconfig1
-rw-r--r--configs/cei-tk1-som_defconfig1
-rw-r--r--configs/cherryhill_defconfig1
-rw-r--r--configs/chromebook_link64_defconfig1
-rw-r--r--configs/chromebook_link_defconfig1
-rw-r--r--configs/chromebook_samus_defconfig1
-rw-r--r--configs/chromebox_panther_defconfig1
-rw-r--r--configs/cm_t43_defconfig1
-rw-r--r--configs/colibri_imx6_defconfig1
-rw-r--r--configs/colibri_t20_defconfig1
-rw-r--r--configs/colibri_t30_defconfig1
-rw-r--r--configs/colibri_vf_defconfig1
-rw-r--r--configs/conga-qeval20-qa3-e3845-internal-uart_defconfig1
-rw-r--r--configs/conga-qeval20-qa3-e3845_defconfig1
-rw-r--r--configs/coreboot64_defconfig1
-rw-r--r--configs/coreboot_defconfig1
-rw-r--r--configs/corstone1000_defconfig1
-rw-r--r--configs/cougarcanyon2_defconfig1
-rw-r--r--configs/crownbay_defconfig1
-rw-r--r--configs/dalmore_defconfig1
-rw-r--r--configs/dfi-bt700-q7x-151_defconfig1
-rw-r--r--configs/edison_defconfig1
-rw-r--r--configs/efi-x86_payload32_defconfig1
-rw-r--r--configs/efi-x86_payload64_defconfig1
-rw-r--r--configs/galileo_defconfig1
-rw-r--r--configs/gazerbeam_defconfig1
-rw-r--r--configs/ge_bx50v3_defconfig1
-rw-r--r--configs/harmony_defconfig1
-rw-r--r--configs/imx28_xea_defconfig11
-rw-r--r--configs/imx28_xea_sb_defconfig2
-rw-r--r--configs/imx8mm_beacon_defconfig1
-rw-r--r--configs/imx8mm_beacon_fspi_defconfig155
-rw-r--r--configs/imx8mm_venice_defconfig7
-rw-r--r--configs/imx8mn_beacon_2g_defconfig1
-rw-r--r--configs/imx8mn_beacon_defconfig1
-rw-r--r--configs/imx8mn_beacon_fspi_defconfig1
-rw-r--r--configs/imx8mn_var_som_defconfig4
-rw-r--r--configs/imx8mn_venice_defconfig7
-rw-r--r--configs/imx8mp_beacon_defconfig1
-rw-r--r--configs/imx8mp_venice_defconfig9
-rw-r--r--configs/imx93_11x11_evk_defconfig1
-rw-r--r--configs/jetson-tk1_defconfig1
-rw-r--r--configs/malta64_defconfig1
-rw-r--r--configs/malta64el_defconfig1
-rw-r--r--configs/malta_defconfig1
-rw-r--r--configs/maltael_defconfig1
-rw-r--r--configs/medcom-wide_defconfig1
-rw-r--r--configs/minnowmax_defconfig1
-rw-r--r--configs/mscc_jr2_defconfig1
-rw-r--r--configs/mscc_luton_defconfig1
-rw-r--r--configs/mscc_ocelot_defconfig1
-rw-r--r--configs/mscc_serval_defconfig1
-rw-r--r--configs/mscc_servalt_defconfig1
-rw-r--r--configs/mt7620_mt7530_rfb_defconfig1
-rw-r--r--configs/mt7620_rfb_defconfig1
-rw-r--r--configs/mt7621_nand_rfb_defconfig1
-rw-r--r--configs/mt7621_rfb_defconfig1
-rw-r--r--configs/mt7623a_unielec_u7623_02_defconfig1
-rw-r--r--configs/mt7623n_bpir2_defconfig1
-rw-r--r--configs/mt7628_rfb_defconfig1
-rw-r--r--configs/mt7629_rfb_defconfig1
-rw-r--r--configs/mx23_olinuxino_defconfig1
-rw-r--r--configs/mx23evk_defconfig1
-rw-r--r--configs/mx28evk_defconfig2
-rw-r--r--configs/nyan-big_defconfig1
-rw-r--r--configs/odroid_defconfig1
-rw-r--r--configs/omap4_panda_defconfig1
-rw-r--r--configs/omap4_sdp4430_defconfig1
-rw-r--r--configs/p2371-0000_defconfig1
-rw-r--r--configs/p2371-2180_defconfig1
-rw-r--r--configs/p2571_defconfig1
-rw-r--r--configs/p2771-0000-000_defconfig1
-rw-r--r--configs/p2771-0000-500_defconfig1
-rw-r--r--configs/p3450-0000_defconfig1
-rw-r--r--configs/paz00_defconfig1
-rw-r--r--configs/phycore-imx8mm_defconfig1
-rw-r--r--configs/phycore-imx8mp_defconfig1
-rw-r--r--configs/plutux_defconfig1
-rw-r--r--configs/poleg_evb_defconfig3
-rw-r--r--configs/qemu-x86_64_defconfig1
-rw-r--r--configs/qemu-x86_defconfig1
-rw-r--r--configs/sandbox_defconfig1
-rw-r--r--configs/seaboard_defconfig1
-rw-r--r--configs/smdkv310_defconfig1
-rw-r--r--configs/sniper_defconfig1
-rw-r--r--configs/socrates_defconfig1
-rw-r--r--configs/som-db5800-som-6867_defconfig1
-rw-r--r--configs/starfive_visionfive2_defconfig32
-rw-r--r--configs/tec-ng_defconfig1
-rw-r--r--configs/tec_defconfig1
-rw-r--r--configs/th1520_lpi4a_defconfig82
-rw-r--r--configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig1
-rw-r--r--configs/theadorable-x86-conga-qa3-e3845_defconfig1
-rw-r--r--configs/theadorable-x86-dfi-bt700_defconfig1
-rw-r--r--configs/trimslice_defconfig1
-rw-r--r--configs/venice2_defconfig1
-rw-r--r--configs/ventana_defconfig1
-rw-r--r--configs/verdin-imx8mm_defconfig1
-rw-r--r--configs/verdin-imx8mp_defconfig2
-rw-r--r--configs/vexpress_ca9x4_defconfig1
-rw-r--r--configs/x240_defconfig86
-rw-r--r--doc/board/beacon/beacon-imx8mm.rst55
-rw-r--r--doc/board/beacon/beacon-imx8mn.rst53
-rw-r--r--doc/board/beacon/index.rst2
-rw-r--r--doc/board/gateworks/imx8mm_venice.rst4
-rw-r--r--doc/board/gateworks/imx8mn_venice.rst4
-rw-r--r--doc/board/gateworks/imx8mp_venice.rst4
-rw-r--r--doc/board/index.rst2
-rw-r--r--doc/board/phytec/index.rst10
-rw-r--r--doc/board/phytec/phycore-imx8mm.rst60
-rw-r--r--doc/board/phytec/phycore-imx8mp.rst60
-rw-r--r--doc/board/starfive/visionfive2.rst6
-rw-r--r--doc/board/thead/index.rst9
-rw-r--r--doc/board/thead/lpi4a.rst129
-rw-r--r--doc/develop/expo.rst305
-rw-r--r--doc/develop/uefi/uefi.rst7
-rw-r--r--doc/device-tree-bindings/config.txt2
-rw-r--r--doc/device-tree-bindings/spi/brcm,bcm63xx-hsspi.yaml134
-rw-r--r--doc/device-tree-bindings/spi/soft-spi.txt12
-rw-r--r--doc/imx/habv4/csf_examples/mx8m/csf.sh21
-rw-r--r--doc/imx/habv4/csf_examples/mx8m/csf_fit.txt12
-rw-r--r--doc/imx/habv4/csf_examples/mx8m/csf_spl.txt12
-rw-r--r--doc/imx/habv4/guides/mx8m_spl_secure_boot.txt10
-rw-r--r--doc/usage/cmd/cedit.rst31
-rw-r--r--doc/usage/index.rst1
-rw-r--r--drivers/adc/Kconfig8
-rw-r--r--drivers/adc/Makefile1
-rw-r--r--drivers/adc/imx93-adc.c290
-rw-r--r--drivers/clk/Kconfig1
-rw-r--r--drivers/clk/imx/clk-imx8mp.c3
-rw-r--r--drivers/core/ofnode.c27
-rw-r--r--drivers/firmware/scmi/scmi_agent-uclass.c2
-rw-r--r--drivers/gpio/gpio-uclass.c2
-rw-r--r--drivers/led/led_bcm6753.c114
-rw-r--r--drivers/misc/Kconfig4
-rw-r--r--drivers/misc/Makefile2
-rw-r--r--drivers/misc/imx8/scu_api.c78
-rw-r--r--drivers/misc/imx_ele/Makefile (renamed from drivers/misc/sentinel/Makefile)2
-rw-r--r--drivers/misc/imx_ele/ele_api.c (renamed from drivers/misc/sentinel/s400_api.c)333
-rw-r--r--drivers/misc/imx_ele/ele_mu.c (renamed from drivers/misc/sentinel/s4mu.c)38
-rw-r--r--drivers/misc/imx_ele/fuse.c (renamed from drivers/misc/sentinel/fuse.c)40
-rw-r--r--drivers/misc/npcm_host_intf.c6
-rw-r--r--drivers/misc/npcm_otp.c2
-rw-r--r--drivers/mtd/nand/raw/pxa3xx_nand.c20
-rw-r--r--drivers/mtd/spi/spi-nor-ids.c43
-rw-r--r--drivers/net/Kconfig7
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/dwc_eth_qos.c6
-rw-r--r--drivers/net/dwc_eth_qos.h1
-rw-r--r--drivers/net/dwc_eth_qos_starfive.c249
-rw-r--r--drivers/net/phy/Kconfig6
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/motorcomm.c437
-rw-r--r--drivers/net/ti/am65-cpsw-nuss.c9
-rw-r--r--drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c3
-rw-r--r--drivers/power/domain/imx8-power-domain-legacy.c9
-rw-r--r--drivers/power/domain/imx8m-power-domain.c3
-rw-r--r--drivers/ram/starfive/starfive_ddr.c2
-rw-r--r--drivers/serial/serial_pl01x.c16
-rw-r--r--drivers/spi/Kconfig13
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/bcm63xx_hsspi.c277
-rw-r--r--drivers/spi/bcmbca_hsspi.c414
-rw-r--r--drivers/spi/npcm_pspi.c12
-rw-r--r--drivers/spi/pl022_spi.c51
-rw-r--r--drivers/spi/soft_spi.c21
-rw-r--r--drivers/spi/spi-synquacer.c8
-rw-r--r--drivers/timer/Makefile2
-rw-r--r--drivers/timer/riscv_aclint_timer.c74
-rw-r--r--drivers/timer/sifive_clint_timer.c68
-rw-r--r--drivers/ufs/ufs.c2
-rw-r--r--drivers/video/console_truetype.c259
-rw-r--r--drivers/video/stb_truetype.h2257
-rw-r--r--drivers/video/vidconsole-uclass.c42
-rw-r--r--drivers/video/video-uclass.c54
-rw-r--r--env/Kconfig12
-rw-r--r--env/mmc.c5
-rw-r--r--fs/fs.c58
-rw-r--r--include/configs/arbel.h5
-rw-r--r--include/configs/imx8mm_beacon.h59
-rw-r--r--include/configs/imx8mm_venice.h10
-rw-r--r--include/configs/imx8mn_beacon.h61
-rw-r--r--include/configs/imx8mn_venice.h10
-rw-r--r--include/configs/imx8mp_venice.h10
-rw-r--r--include/configs/poleg.h2
-rw-r--r--include/configs/qemu-riscv.h2
-rw-r--r--include/configs/sifive-unleashed.h2
-rw-r--r--include/configs/starfive-visionfive2.h1
-rw-r--r--include/configs/th1520_lpi4a.h22
-rw-r--r--include/configs/x240.h37
-rw-r--r--include/dm/of.h2
-rw-r--r--include/dm/ofnode.h10
-rw-r--r--include/dm/platform_data/serial_pl01x.h4
-rw-r--r--include/dm/platform_data/spi_pl022.h21
-rw-r--r--include/dt-bindings/clock/imx8mp-clock.h14
-rw-r--r--include/efi_config.h5
-rw-r--r--include/efi_loader.h11
-rw-r--r--include/expo.h209
-rw-r--r--include/firmware/imx/sci/rpc.h27
-rw-r--r--include/firmware/imx/sci/sci.h24
-rw-r--r--include/firmware/imx/sci/svc/misc/api.h42
-rw-r--r--include/firmware/imx/sci/svc/pm/api.h94
-rw-r--r--include/firmware/imx/sci/svc/rm/api.h14
-rw-r--r--include/firmware/imx/sci/svc/seco/api.h5
-rw-r--r--include/firmware/imx/sci/svc/timer/api.h33
-rw-r--r--include/fs.h38
-rw-r--r--include/fsl_sec.h4
-rw-r--r--include/imx_sip.h6
-rw-r--r--include/log.h2
-rw-r--r--include/of_live.h10
-rw-r--r--include/test/cedit-test.h29
-rw-r--r--include/test/ut.h36
-rw-r--r--include/video.h22
-rw-r--r--include/video_console.h78
-rw-r--r--lib/efi_loader/efi_bootmgr.c385
-rw-r--r--lib/efi_loader/efi_boottime.c43
-rw-r--r--lib/efi_loader/efi_helper.c25
-rw-r--r--lib/efi_selftest/efi_selftest_controllers.c44
-rw-r--r--lib/lzma/LzmaDec.c18
-rw-r--r--lib/of_live.c11
-rw-r--r--lib/zlib/inflate.c5
-rw-r--r--test/boot/expo.c241
-rw-r--r--test/boot/files/expo_layout.dts84
-rw-r--r--test/cmd/bdinfo.c79
-rw-r--r--test/dm/ofnode.c45
-rw-r--r--test/dm/video.c6
-rw-r--r--test/py/tests/test_ut.py10
-rw-r--r--tools/binman/control.py2
-rwxr-xr-xtools/expo.py130
415 files changed, 15863 insertions, 3715 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 2477923a520..87991cccddb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1330,7 +1330,7 @@ F: doc/arch/riscv.rst
F: doc/usage/sbi.rst
F: drivers/sysreset/sysreset_sbi.c
F: drivers/timer/andes_plmt_timer.c
-F: drivers/timer/sifive_clint_timer.c
+F: drivers/timer/riscv_aclint_timer.c
F: tools/prelink-riscv.c
RISC-V CANAAN KENDRYTE K210
diff --git a/README b/README
index bbf96e64c89..15a19caf740 100644
--- a/README
+++ b/README
@@ -2430,27 +2430,6 @@ Hit 'q':
[q, b, e, ?] ## Application terminated, rc = 0x0
-Minicom warning:
-================
-
-Over time, many people have reported problems when trying to use the
-"minicom" terminal emulation program for serial download. I (wd)
-consider minicom to be broken, and recommend not to use it. Under
-Unix, I recommend to use C-Kermit for general purpose use (and
-especially for kermit binary protocol download ("loadb" command), and
-use "cu" for S-Record download ("loads" command). See
-https://www.denx.de/wiki/view/DULG/SystemSetup#Section_4.3.
-for help with kermit.
-
-
-Nevertheless, if you absolutely want to use it try adding this
-configuration to your "File transfer protocols" section:
-
- Name Program Name U/D FullScr IO-Red. Multi
- X kermit /usr/bin/kermit -i -l %l -s Y U Y N N
- Y kermit /usr/bin/kermit -i -l %l -r N D Y N N
-
-
Implementation Internals:
=========================
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 99264a64780..b3115b054c8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -882,7 +882,7 @@ config ARCH_IMX8ULP
select SUPPORT_SPL
select GPIO_EXTRA_HEADER
select MISC
- select IMX_SENTINEL
+ select IMX_ELE
imply CMD_DM
config ARCH_IMX9
@@ -894,7 +894,7 @@ config ARCH_IMX9
select SUPPORT_SPL
select GPIO_EXTRA_HEADER
select MISC
- select IMX_SENTINEL
+ select IMX_ELE
imply CMD_DM
config ARCH_IMXRT
@@ -912,14 +912,12 @@ config ARCH_MX23
select CPU_ARM926EJS
select GPIO_EXTRA_HEADER
select MACH_IMX
- select PL011_SERIAL
select SUPPORT_SPL
config ARCH_MX28
bool "NXP i.MX28 family"
select CPU_ARM926EJS
select GPIO_EXTRA_HEADER
- select PL011_SERIAL
select MACH_IMX
select SUPPORT_SPL
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
index 763d79e8036..5598c552ab9 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
@@ -128,8 +128,10 @@ void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr,
mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size);
- mxs_spl_console_init();
- debug("SPL: Serial Console Initialised\n");
+ if (!CONFIG_IS_ENABLED(DM_SERIAL)) {
+ mxs_spl_console_init();
+ debug("SPL: Serial Console Initialised\n");
+ }
mxs_power_init();
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
index c33170f06d3..7ea029e3712 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
@@ -41,6 +41,29 @@ static void mxs_power_clock2xtal(void)
&clkctrl_regs->hw_clkctrl_clkseq_set);
}
+static void mxs_power_regs_dump(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("ctrl:\t\t 0x%x\n", readl(&power_regs->hw_power_ctrl));
+ debug("5vctrl:\t\t 0x%x\n", readl(&power_regs->hw_power_5vctrl));
+ debug("minpwr:\t\t 0x%x\n", readl(&power_regs->hw_power_minpwr));
+ debug("charge:\t\t 0x%x\n", readl(&power_regs->hw_power_charge));
+ debug("vddctrl:\t 0x%x\n", readl(&power_regs->hw_power_vdddctrl));
+ debug("vddactrl:\t 0x%x\n", readl(&power_regs->hw_power_vddactrl));
+ debug("vddioctrl:\t 0x%x\n", readl(&power_regs->hw_power_vddioctrl));
+ debug("vddmemctrl:\t 0x%x\n", readl(&power_regs->hw_power_vddmemctrl));
+ debug("dcdc4p2:\t 0x%x\n", readl(&power_regs->hw_power_dcdc4p2));
+ debug("misc:\t\t 0x%x\n", readl(&power_regs->hw_power_misc));
+ debug("dclimits:\t 0x%x\n", readl(&power_regs->hw_power_dclimits));
+ debug("loopctrl:\t 0x%x\n", readl(&power_regs->hw_power_loopctrl));
+ debug("sts:\t\t 0x%x\n", readl(&power_regs->hw_power_sts));
+ debug("speed:\t\t 0x%x\n", readl(&power_regs->hw_power_speed));
+ debug("battmonitor:\t 0x%x\n",
+ readl(&power_regs->hw_power_battmonitor));
+}
+
/**
* mxs_power_clock2pll() - Switch CPU core clock source to PLL
*
@@ -752,7 +775,19 @@ static void mxs_batt_boot(void)
POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
- mxs_power_enable_4p2();
+ if (CONFIG_IS_ENABLED(MXS_PMU_MINIMAL_VDD5V_CURRENT))
+ setbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_ILIMIT_EQ_ZERO);
+
+ if (CONFIG_IS_ENABLED(MXS_PMU_DISABLE_BATT_CHARGE)) {
+ writel(POWER_CHARGE_PWD_BATTCHRG,
+ &power_regs->hw_power_charge_set);
+ writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+ &power_regs->hw_power_5vctrl_set);
+ }
+
+ if (CONFIG_IS_ENABLED(MXS_PMU_ENABLE_4P2_LINEAR_REGULATOR))
+ mxs_power_enable_4p2();
}
/**
@@ -1268,6 +1303,7 @@ void mxs_power_init(void)
POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
+ mxs_power_regs_dump();
early_delay(1000);
}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 17f506a8fa0..07b26df2750 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -305,7 +305,8 @@ dtb-$(CONFIG_ARCH_MVEBU) += \
cn9132-db-B.dtb \
cn9130-crb-A.dtb \
cn9130-crb-B.dtb \
- ac5-98dx35xx-rd.dtb
+ ac5-98dx35xx-rd.dtb \
+ ac5-98dx35xx-atl-x240.dtb
endif
dtb-$(CONFIG_ARCH_SYNQUACER) += synquacer-sc2a11-developerbox.dtb
@@ -1017,6 +1018,7 @@ dtb-$(CONFIG_ARCH_IMX8M) += \
imx8mp-phyboard-pollux-rdk.dtb \
imx8mp-venice.dtb \
imx8mp-venice-gw74xx.dtb \
+ imx8mp-venice-gw7905-2x.dtb \
imx8mp-verdin-wifi-dev.dtb \
imx8mq-pico-pi.dtb \
imx8mq-kontron-pitx-imx8m.dtb \
diff --git a/arch/arm/dts/ac5-98dx25xx.dtsi b/arch/arm/dts/ac5-98dx25xx.dtsi
index 3c68355f323..f53b4781d7f 100644
--- a/arch/arm/dts/ac5-98dx25xx.dtsi
+++ b/arch/arm/dts/ac5-98dx25xx.dtsi
@@ -251,6 +251,15 @@
status = "disabled";
};
+ nand: nand-controller@805b0000 {
+ compatible = "marvell,mvebu-ac5-pxa3xx-nand";
+ reg = <0x0 0x805b0000 0x0 0x54>;
+ #address-cells = <0x00000001>;
+ marvell,nand-enable-arbiter;
+ num-cs = <0x00000001>;
+ status = "disabled";
+ };
+
gic: interrupt-controller@80600000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>;
diff --git a/arch/arm/dts/ac5-98dx35xx-atl-x240.dts b/arch/arm/dts/ac5-98dx35xx-atl-x240.dts
new file mode 100644
index 00000000000..820ec18b435
--- /dev/null
+++ b/arch/arm/dts/ac5-98dx35xx-atl-x240.dts
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "ac5-98dx35xx.dtsi"
+
+/ {
+ model = "Allied Telesis x240";
+ compatible = "alliedtelesis,x240", "marvell,ac5x", "marvell,ac5";
+
+ aliases {
+ serial0 = &uart0;
+ spiflash0 = &spiflash0;
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ spi0 = &spi0;
+ i2c0 = &i2c0;
+ usb0 = &usb0;
+ pinctrl0 = &pinctrl0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ boot-board {
+ compatible = "atl,boot-board";
+ present-gpio = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+ override-gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ fault {
+ label = "fault:red";
+ gpios = <&system_gpio 11 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+ };
+};
+
+&nand {
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_pins>;
+
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ status = "okay";
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@user {
+ reg = <0x00000000 0x10000000>;
+ label = "user";
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ mux@71 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nxp,pca9546";
+ reg = <0x71>;
+ i2c-mux-idle-disconnect;
+ reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; /* MPP36 */
+ status = "okay";
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ hwmon@2e {
+ compatible = "adi,adt7476";
+ reg = <0x2e>;
+ };
+
+ rtc@68 {
+ compatible = "adi,max31331";
+ reg = <0x68>;
+ };
+
+ system_gpio: gpio@27 {
+ compatible = "nxp,pca9555";
+ gpio-controller;
+ #gpio-cells= <2>;
+ reg = <0x27>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <25 IRQ_TYPE_LEVEL_LOW>; /* MPP25 */
+ };
+ };
+ };
+};
+
+&spi0 {
+ status = "okay";
+ spiflash0: flash@0 {
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <50000000>;
+ spi-tx-bus-width = <1>; /* 1-single, 2-dual, 4-quad */
+ spi-rx-bus-width = <1>; /* 1-single, 2-dual, 4-quad */
+ reg = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&gpio0 {
+ phy-reset {
+ gpio-hog;
+ gpios = <19 GPIO_ACTIVE_LOW>;
+ output-high;
+ line-name = "phy-reset";
+ };
+
+ usb-en {
+ gpio-hog;
+ gpios = <28 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "usb-en";
+ };
+
+ led-oe-n {
+ gpio-hog;
+ gpios = <23 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "led-oe-n";
+ };
+};
+
+&gpio1 {
+ nand-protect {
+ gpio-hog;
+ gpios = <8 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "nand-protect";
+ };
+};
+
+&pinctrl0 {
+ /*
+ * MPP Bus: MPP#
+ * NF_IO [0-7]
+ * NF_Wen [8]
+ * NF_ALE [9]
+ * NF_CLE [10]
+ * NF_Cen [11]
+ * QSPI_SCK/SPI0_SCK [12]
+ * QSPI_CSn/SPI0_CSn [13]
+ * QSPI_DIO[0]/SPI0_MOSI [14]
+ * QSPI_DIO[1]/SPI0_MISO [15]
+ * NF_Ren [16]
+ * NF_RBn [17]
+ * WD_INTn [18]
+ * B_B_OVRIDE_N [19]
+ * GREEN_SW_N [20]
+ * PHY_INT_N[0] [21]
+ * SPI_WPn [22]
+ * LED_OE_N [23]
+ * USB_PWR_FLT_N [24]
+ * SFP_INT_N [25]
+ * I2C0_SCL [26]
+ * I2C0_SDA [27]
+ * USB_EN [28]
+ * MONITOR_INT_N [29]
+ * XM1_MDC [30]
+ * XM1_MDIO [31]
+ * UA0_RXD [32]
+ * UA0_TXD [33]
+ * PHY_RST0n [34]
+ * TPM_INT_N [35]
+ * I2CMUX_RESET_N [36]
+ * SPI_SRAM_SEL_N [37]
+ * B_B_PRESENT [38]
+ * SPI_FLASH_SEL_N [39]
+ * NF_WP_N [40]
+ * POE_INT_N [41]
+ * PoE_RST_N [42]
+ * LED0_CLK [43]
+ * LED0_STB [44]
+ * LED0_DATA [45]
+ */
+ /* 0 1 2 3 4 5 6 7 8 9 */
+ pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
+ 0xff 0xff 1 1 1 1 0xff 0xff 0 0
+ 0 0 0 0 0 0 1 1 0 0
+ 1 1 1 1 0 0 0 0 0 0
+ 0 0 0 1 1 1 >;
+
+ nand_pins: nand-pins {
+ marvell,pins = <0 1 2 3 4 5 6 7 8 9 10 11 16 17>;
+ marvell,function = <2>;
+ };
+};
diff --git a/arch/arm/dts/ac5-98dx35xx-rd.dts b/arch/arm/dts/ac5-98dx35xx-rd.dts
index d9f217cd4a5..1dc85bb7ef2 100644
--- a/arch/arm/dts/ac5-98dx35xx-rd.dts
+++ b/arch/arm/dts/ac5-98dx35xx-rd.dts
@@ -31,7 +31,6 @@
usb0 = &usb0;
usb1 = &usb1;
pinctrl0 = &pinctrl0;
- sar-reg0 = "/config-space/sar-reg";
};
usb1phy: usb-phy {
diff --git a/arch/arm/dts/armada-385-thecus-n2350.dts b/arch/arm/dts/armada-385-thecus-n2350.dts
index fc29c4d25a8..253cf011308 100644
--- a/arch/arm/dts/armada-385-thecus-n2350.dts
+++ b/arch/arm/dts/armada-385-thecus-n2350.dts
@@ -23,7 +23,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x00000000 0x40000000>; /* 1GB */
};
@@ -37,43 +37,43 @@
};
- usb3_0_phy: usb3_0_phy {
+ usb3_0_phy: usb-phy {
compatible = "usb-nop-xceiv";
vcc-supply = <&usb3_0_power>;
+ #phy-cells = <0>;
};
- usb3_1_phy: usb3_1_phy {
+ usb3_1_phy: usb-phy {
compatible = "usb-nop-xceiv";
vcc-supply = <&usb3_1_power>;
+ #phy-cells = <0>;
};
- gpio-keys {
+ keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
pinctrl-0 = <&pmx_power_button &pmx_copy_button &pmx_reset_button>;
pinctrl-names = "default";
- button@1 {
+ button-1 {
label = "Power Button";
linux,code = <KEY_POWER>;
gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
};
- button@2 {
+ button-2 {
label = "Copy Button";
linux,code = <KEY_COPY>;
gpios = <&gpio1 20 GPIO_ACTIVE_HIGH>;
};
- button@3 {
+ button-3 {
label = "Reset Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>;
};
};
- gpio-leds {
+ leds {
compatible = "gpio-leds";
pinctrl-0 = <&pmx_sata1_white_led
&pmx_sata1_red_led
@@ -88,142 +88,142 @@
pinctrl-names = "default";
- white_sata1 {
+ led-1 {
label = "n2350:white:sata1";
gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "ide-disk1";
};
- red_sata1 {
+ led-2 {
label = "n2350:red:sata1";
gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
};
- white-sata2 {
+ led-3 {
label = "n2350:white:sata2";
gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
};
- red-sata2 {
+ led-4 {
label = "n2350:red:sata2";
gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
};
- white-sys {
+ led-5 {
label = "n2350:white:sys";
gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "default-on";
};
- red-sys {
+ led-6 {
label = "n2350:red:sys";
gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
};
- blue-pwr {
+ led-7 {
label = "n2350:blue:pwr";
gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
};
- red-pwr {
+ led-8 {
label = "n2350:red:pwr";
gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
};
- white-usb {
+ led-9 {
label = "n2350:white:usb";
gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
};
- red-usb {
+ led-10 {
label = "n2350:red:usb";
gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
};
};
- regulators {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb3_0_power: regulator@1 {
- compatible = "regulator-fixed";
- reg = <1>;
- regulator-name = "USB3_0_Power";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- regulator-always-on;
- regulator-boot-on;
- gpio = <&gpio0 21 GPIO_ACTIVE_HIGH>;
- };
+ fan {
+ compatible = "gpio-fan";
+ gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 600 1
+ 3000 2 >;
+ pinctrl-0 = <&pmx_fan>;
+ pinctrl-names = "default";
+ };
- usb3_1_power: regulator@2 {
- compatible = "regulator-fixed";
- reg = <1>;
- regulator-name = "USB3_1_Power";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- regulator-always-on;
- regulator-boot-on;
- gpio = <&gpio0 24 GPIO_ACTIVE_HIGH>;
- };
+ usb3_0_power: v5-vbus0 {
+ compatible = "regulator-fixed";
+ regulator-name = "USB3_0_Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 21 GPIO_ACTIVE_HIGH>;
+ };
- reg_sata0: regulator@3 {
- compatible = "regulator-fixed";
- regulator-name = "pwr_en_sata0";
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- enable-active-high;
- regulator-always-on;
- regulator-boot-on;
- gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
- };
+ usb3_1_power: v5-vbus1 {
+ compatible = "regulator-fixed";
+ regulator-name = "USB3_1_Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 24 GPIO_ACTIVE_HIGH>;
+ };
- reg_5v_sata0: v5-sata0 {
- compatible = "regulator-fixed";
- regulator-name = "v5.0-sata0";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- vin-supply = <&reg_sata0>;
- };
+ reg_sata0: pwr-sata0 {
+ compatible = "regulator-fixed";
+ regulator-name = "pwr_en_sata0";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ };
- reg_12v_sata0: v12-sata0 {
- compatible = "regulator-fixed";
- regulator-name = "v12.0-sata0";
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- vin-supply = <&reg_sata0>;
- };
+ reg_5v_sata0: v5-sata0 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&reg_sata0>;
+ };
- reg_sata1: regulator@4 {
- regulator-name = "pwr_en_sata1";
- compatible = "regulator-fixed";
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- enable-active-high;
- regulator-always-on;
- regulator-boot-on;
- gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
- };
+ reg_12v_sata0: v12-sata0 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata0";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ vin-supply = <&reg_sata0>;
+ };
- reg_5v_sata1: v5-sata1 {
- compatible = "regulator-fixed";
- regulator-name = "v5.0-sata1";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- vin-supply = <&reg_sata1>;
- };
+ reg_sata1: pwr-sata0 {
+ regulator-name = "pwr_en_sata1";
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ };
- reg_12v_sata1: v12-sata1 {
- compatible = "regulator-fixed";
- regulator-name = "v12.0-sata1";
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- vin-supply = <&reg_sata1>;
- };
+ reg_5v_sata1: v5-sata1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&reg_sata1>;
+ };
+ reg_12v_sata1: v12-sata1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata1";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ vin-supply = <&reg_sata1>;
};
gpio-poweroff {
@@ -267,7 +267,7 @@
};
&mdio {
- phy0: ethernet-phy@0 {
+ phy0: ethernet-phy@1 {
reg = <1>;
};
};
@@ -301,18 +301,14 @@
&pciec {
status = "okay";
- /*
- * The two PCIe units are accessible through
- * standard PCIe slots on the board.
- */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
- pcie@2,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
+};
+
+&pcie1 {
+ status = "okay";
+};
+
+&pcie2 {
+ status = "okay";
};
&pinctrl {
@@ -392,6 +388,11 @@
marvell,pins = "mpp17";
marvell,function = "gpio";
};
+
+ pmx_fan: pmx-fan {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
};
&sdhci {
@@ -408,10 +409,10 @@
status = "okay";
/* spi: 4M Flash Macronix MX25L3205D */
- spi-flash@0 {
+ flash@0 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "macronix,mx25l3205d", "jedec,spi-nor";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <108000000>;
diff --git a/arch/arm/dts/imx28-xea-u-boot.dtsi b/arch/arm/dts/imx28-xea-u-boot.dtsi
index f6488154d8d..bdbeca528c6 100644
--- a/arch/arm/dts/imx28-xea-u-boot.dtsi
+++ b/arch/arm/dts/imx28-xea-u-boot.dtsi
@@ -12,6 +12,11 @@
*/
#include "imx28-u-boot.dtsi"
/ {
+ aliases {
+ /delete-property/ spi1;
+ /delete-property/ usbphy0;
+ /delete-property/ usbphy1;
+ };
apb@80000000 {
bootph-pre-ram;
@@ -27,16 +32,47 @@
&clks {
bootph-pre-ram;
+ status = "disable";
+};
+
+&duart {
+ /delete-property/ clocks;
+ bootph-pre-ram;
+ type = <1>; /* TYPE_PL011 */
};
&gpio0 {
bootph-pre-ram;
};
+&mac0 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a>;
+ phy-supply = <&reg_fec_3v3>;
+ phy-reset-gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+ phy-reset-duration = <1>;
+ phy-reset-post-delay = <1>;
+ status = "okay";
+
+ fixed-link {
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&pinctrl {
+ /delete-property/ pinctrl-names;
+ /delete-property/ pinctrl-0;
bootph-pre-ram;
};
+&reg_fec_3v3 {
+ gpio = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-boot-on;
+};
+
&ssp0 {
bootph-pre-ram;
};
@@ -46,3 +82,12 @@
spi-max-frequency = <40000000>;
bootph-pre-ram;
};
+
+/delete-node/ &ssp2;
+/delete-node/ &usb0;
+/delete-node/ &usbphy0;
+/delete-node/ &usb1;
+/delete-node/ &usbphy1;
+/delete-node/ &hog_pins_a;
+/delete-node/ &hog_pins_tiva;
+/delete-node/ &hog_pins_coding;
diff --git a/arch/arm/dts/imx8mm-beacon-kit-u-boot.dtsi b/arch/arm/dts/imx8mm-beacon-kit-u-boot.dtsi
index fd0061f00fd..00abbeb22fe 100644
--- a/arch/arm/dts/imx8mm-beacon-kit-u-boot.dtsi
+++ b/arch/arm/dts/imx8mm-beacon-kit-u-boot.dtsi
@@ -6,6 +6,10 @@
#include "imx8mm-u-boot.dtsi"
/ {
+ aliases {
+ spi0 = &flexspi;
+ };
+
wdt-reboot {
compatible = "wdt-reboot";
wdt = <&wdog1>;
diff --git a/arch/arm/dts/imx8mm-mx8menlo.dts b/arch/arm/dts/imx8mm-mx8menlo.dts
index 32f6f2f50c1..0b123a84018 100644
--- a/arch/arm/dts/imx8mm-mx8menlo.dts
+++ b/arch/arm/dts/imx8mm-mx8menlo.dts
@@ -10,6 +10,7 @@
/ {
model = "MENLO MX8MM EMBEDDED DEVICE";
compatible = "menlo,mx8menlo",
+ "toradex,verdin-imx8mm-nonwifi",
"toradex,verdin-imx8mm",
"fsl,imx8mm";
@@ -250,21 +251,21 @@
/* SODIMM 96 */
MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4 0x1c4
/* CPLD_D[7] */
- MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x1c4
+ MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x184
/* CPLD_D[6] */
- MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x1c4
+ MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x184
/* CPLD_D[5] */
- MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x1c4
+ MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x184
/* CPLD_D[4] */
- MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x1c4
+ MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x184
/* CPLD_D[3] */
- MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x1c4
+ MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x184
/* CPLD_D[2] */
- MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x1c4
+ MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x184
/* CPLD_D[1] */
- MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x1c4
+ MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x184
/* CPLD_D[0] */
- MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x1c4
+ MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x184
/* KBD_intK */
MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x1c4
/* DISP_reset */
diff --git a/arch/arm/dts/imx8mm-verdin-dahlia.dtsi b/arch/arm/dts/imx8mm-verdin-dahlia.dtsi
deleted file mode 100644
index c2a5c2f7b20..00000000000
--- a/arch/arm/dts/imx8mm-verdin-dahlia.dtsi
+++ /dev/null
@@ -1,150 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-/*
- * Copyright 2022 Toradex
- */
-
-/ {
- sound_card: sound-card {
- compatible = "simple-audio-card";
- simple-audio-card,bitclock-master = <&dailink_master>;
- simple-audio-card,format = "i2s";
- simple-audio-card,frame-master = <&dailink_master>;
- simple-audio-card,name = "imx8mm-wm8904";
- simple-audio-card,routing =
- "Headphone Jack", "HPOUTL",
- "Headphone Jack", "HPOUTR",
- "IN2L", "Line In Jack",
- "IN2R", "Line In Jack",
- "Headphone Jack", "MICBIAS",
- "IN1L", "Headphone Jack";
- simple-audio-card,widgets =
- "Microphone", "Headphone Jack",
- "Headphone", "Headphone Jack",
- "Line", "Line In Jack";
-
- dailink_master: simple-audio-card,codec {
- clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
- sound-dai = <&wm8904_1a>;
- };
-
- simple-audio-card,cpu {
- sound-dai = <&sai2>;
- };
- };
-};
-
-/* Verdin SPI_1 */
-&ecspi2 {
- status = "okay";
-};
-
-/* EEPROM on display adapter boards */
-&eeprom_display_adapter {
- status = "okay";
-};
-
-/* EEPROM on Verdin Development board */
-&eeprom_carrier_board {
- status = "okay";
-};
-
-&fec1 {
- status = "okay";
-};
-
-/* Verdin QSPI_1 */
-&flexspi {
- status = "okay";
-};
-
-/* Current measurement into module VCC */
-&hwmon {
- status = "okay";
-};
-
-&hwmon_temp {
- vs-supply = <&reg_1p8v>;
- status = "okay";
-};
-
-&i2c3 {
- status = "okay";
-};
-
-/* Verdin I2C_1 */
-&i2c4 {
- status = "okay";
-
- /* Audio Codec */
- wm8904_1a: audio-codec@1a {
- compatible = "wlf,wm8904";
- AVDD-supply = <&reg_3p3v>;
- clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
- clock-names = "mclk";
- CPVDD-supply = <&reg_3p3v>;
- DBVDD-supply = <&reg_3p3v>;
- DCVDD-supply = <&reg_3p3v>;
- MICVDD-supply = <&reg_3p3v>;
- reg = <0x1a>;
- #sound-dai-cells = <0>;
- };
-};
-
-/* Verdin PCIE_1 */
-&pcie0 {
- status = "okay";
-};
-
-&pcie_phy {
- status = "okay";
-};
-
-/* Verdin PWM_3_DSI */
-&pwm1 {
- status = "okay";
-};
-
-/* Verdin PWM_1 */
-&pwm2 {
- status = "okay";
-};
-
-/* Verdin PWM_2 */
-&pwm3 {
- status = "okay";
-};
-
-/* Verdin I2S_1 */
-&sai2 {
- status = "okay";
-};
-
-/* Verdin UART_3 */
-&uart1 {
- status = "okay";
-};
-
-/* Verdin UART_1 */
-&uart2 {
- status = "okay";
-};
-
-/* Verdin UART_2 */
-&uart3 {
- status = "okay";
-};
-
-/* Verdin USB_1 */
-&usbotg1 {
- status = "okay";
-};
-
-/* Verdin USB_2 */
-&usbotg2 {
- status = "okay";
-};
-
-/* Verdin SD_1 */
-&usdhc2 {
- status = "okay";
-};
diff --git a/arch/arm/dts/imx8mm-verdin-dev.dtsi b/arch/arm/dts/imx8mm-verdin-dev.dtsi
index 73cc3fafa01..3c4b8ca125e 100644
--- a/arch/arm/dts/imx8mm-verdin-dev.dtsi
+++ b/arch/arm/dts/imx8mm-verdin-dev.dtsi
@@ -3,14 +3,13 @@
* Copyright 2022 Toradex
*/
-#include "imx8mm-verdin-dahlia.dtsi"
-
/ {
sound_card: sound-card {
compatible = "simple-audio-card";
simple-audio-card,bitclock-master = <&dailink_master>;
simple-audio-card,format = "i2s";
simple-audio-card,frame-master = <&dailink_master>;
+ simple-audio-card,mclk-fs = <256>;
simple-audio-card,name = "imx8mm-nau8822";
simple-audio-card,routing =
"Headphones", "LHP",
@@ -41,27 +40,121 @@
};
};
+/* Verdin SPI_1 */
+&ecspi2 {
+ status = "okay";
+};
+
+/* EEPROM on display adapter boards */
+&eeprom_display_adapter {
+ status = "okay";
+};
+
+/* EEPROM on Verdin Development board */
+&eeprom_carrier_board {
+ status = "okay";
+};
+
+&fec1 {
+ status = "okay";
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+ status = "okay";
+};
+
+/* Current measurement into module VCC */
+&hwmon {
+ status = "okay";
+};
+
+&hwmon_temp {
+ vs-supply = <&reg_1p8v>;
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
&gpio_expander_21 {
status = "okay";
};
/* Verdin I2C_1 */
&i2c4 {
+ status = "okay";
+
/* Audio Codec */
nau8822_1a: audio-codec@1a {
compatible = "nuvoton,nau8822";
reg = <0x1a>;
+ #sound-dai-cells = <0>;
};
};
+/* Verdin PCIE_1 */
+&pcie0 {
+ status = "okay";
+};
+
+&pcie_phy {
+ status = "okay";
+};
+
+/* Verdin PWM_3_DSI */
+&pwm1 {
+ status = "okay";
+};
+
+/* Verdin PWM_1 */
+&pwm2 {
+ status = "okay";
+};
+
+/* Verdin PWM_2 */
+&pwm3 {
+ status = "okay";
+};
+
+/* Verdin I2S_1 */
+&sai2 {
+ status = "okay";
+};
+
+/* Verdin UART_3 */
+&uart1 {
+ status = "okay";
+};
+
/* Verdin UART_1, connector X50 through RS485 transceiver */
&uart2 {
linux,rs485-enabled-at-boot-time;
rs485-rts-active-low;
rs485-rx-during-tx;
+ status = "okay";
+};
+
+/* Verdin UART_2 */
+&uart3 {
+ status = "okay";
+};
+
+/* Verdin USB_1 */
+&usbotg1 {
+ disable-over-current;
+ status = "okay";
+};
+
+/* Verdin USB_2 */
+&usbotg2 {
+ disable-over-current;
+ status = "okay";
};
/* Limit frequency on dev board due to long traces and bad signal integrity */
&usdhc2 {
max-frequency = <100000000>;
+ status = "okay";
};
diff --git a/arch/arm/dts/imx8mm-verdin-wifi-dev-u-boot.dtsi b/arch/arm/dts/imx8mm-verdin-wifi-dev-u-boot.dtsi
index 494229e4e62..2b268f55cb9 100644
--- a/arch/arm/dts/imx8mm-verdin-wifi-dev-u-boot.dtsi
+++ b/arch/arm/dts/imx8mm-verdin-wifi-dev-u-boot.dtsi
@@ -56,6 +56,10 @@
&gpio5 {
bootph-pre-ram;
+
+ ctrl-sleep-moci-hog {
+ bootph-pre-ram;
+ };
};
&i2c1 {
@@ -88,6 +92,10 @@
};
};
+&pinctrl_ctrl_sleep_moci {
+ bootph-pre-ram;
+};
+
&pinctrl_i2c1 {
bootph-pre-ram;
};
diff --git a/arch/arm/dts/imx8mm-verdin.dtsi b/arch/arm/dts/imx8mm-verdin.dtsi
index bcab830c6e9..6f081158714 100644
--- a/arch/arm/dts/imx8mm-verdin.dtsi
+++ b/arch/arm/dts/imx8mm-verdin.dtsi
@@ -3,8 +3,8 @@
* Copyright 2022 Toradex
*/
-#include "dt-bindings/phy/phy-imx8-pcie.h"
-#include "dt-bindings/pwm/pwm.h"
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+#include <dt-bindings/pwm/pwm.h>
#include "imx8mm.dtsi"
/ {
@@ -56,7 +56,11 @@
hdmi_connector: hdmi-connector {
compatible = "hdmi-connector";
ddc-i2c-bus = <&i2c2>;
+ /* Verdin PWM_3_DSI (SODIMM 19) */
+ hpd-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
label = "hdmi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_3_dsi_hpd_gpio>;
type = "a";
status = "disabled";
};
@@ -95,9 +99,10 @@
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>; /* PMIC_EN_ETH */
- off-on-delay = <500000>;
+ off-on-delay-us = <500000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_reg_eth>;
+ regulator-always-on;
regulator-boot-on;
regulator-max-microvolt = <3300000>;
regulator-min-microvolt = <3300000>;
@@ -134,7 +139,7 @@
enable-active-high;
/* Verdin SD_1_PWR_EN (SODIMM 76) */
gpio = <&gpio3 5 GPIO_ACTIVE_HIGH>;
- off-on-delay = <100000>;
+ off-on-delay-us = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc2_pwr_en>;
regulator-max-microvolt = <3300000>;
@@ -183,15 +188,15 @@
ddrc_opp_table: opp-table {
compatible = "operating-points-v2";
- opp-25M {
+ opp-25000000 {
opp-hz = /bits/ 64 <25000000>;
};
- opp-100M {
+ opp-100000000 {
opp-hz = /bits/ 64 <100000000>;
};
- opp-750M {
+ opp-750000000 {
opp-hz = /bits/ 64 <750000000>;
};
};
@@ -358,7 +363,6 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pmic>;
reg = <0x25>;
- sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
/*
* The bootloader is expected to switch on the I2C level shifter for the TLA2024 ADC
@@ -598,7 +602,7 @@
hdmi_lontium_lt8912: hdmi@48 {
compatible = "lontium,lt8912b";
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpio_10_dsi>, <&pinctrl_pwm_3_dsi_hpd_gpio>;
+ pinctrl-0 = <&pinctrl_gpio_10_dsi>;
reg = <0x48>;
/* Verdin GPIO_9_DSI (LT8912 INT, SODIMM 17, unused) */
/* Verdin GPIO_10_DSI (SODIMM 21) */
@@ -610,7 +614,7 @@
compatible = "atmel,maxtouch";
/*
* Verdin GPIO_9_DSI
- * (TOUCH_INT#, SODIMM 17, also routed to SN65DSI83 IRQ albeit currently unused)
+ * (TOUCH_INT#, SODIMM 17, also routed to SN65DSI84 IRQ albeit currently unused)
*/
interrupt-parent = <&gpio3>;
interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
@@ -653,9 +657,6 @@
assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
<&clk IMX8MM_SYS_PLL2_250M>;
assigned-clock-rates = <10000000>, <250000000>;
- clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
- <&clk IMX8MM_CLK_PCIE1_PHY>;
- clock-names = "pcie", "pcie_aux", "pcie_bus";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie0>;
/* PCIE_1_RESET# (SODIMM 244) */
@@ -664,6 +665,7 @@
&pcie_phy {
clocks = <&clk IMX8MM_CLK_PCIE1_PHY>;
+ clock-names = "ref";
fsl,clkreq-unsupported;
fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_OUTPUT>;
fsl,tx-deemph-gen1 = <0x2d>;
@@ -739,7 +741,6 @@
adp-disable;
dr_mode = "otg";
hnp-disable;
- over-current-active-low;
samsung,picophy-dc-vol-level-adjust = <7>;
samsung,picophy-pre-emp-curr-control = <3>;
srp-disable;
@@ -749,7 +750,6 @@
/* Verdin USB_2 */
&usbotg2 {
dr_mode = "host";
- over-current-active-low;
samsung,picophy-dc-vol-level-adjust = <7>;
samsung,picophy-pre-emp-curr-control = <3>;
vbus-supply = <&reg_usb_otg2_vbus>;
diff --git a/arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi b/arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi
index af80aaea0b8..e0caf3179ea 100644
--- a/arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi
+++ b/arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi
@@ -13,6 +13,19 @@
bootph-pre-ram;
};
+&eeprom_som {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ eth_mac_address: eth-mac-address@19 {
+ reg = <0x19 0x06>;
+ };
+};
+
+&fec1 {
+ nvmem-cells = <&eth_mac_address>;
+ nvmem-cell-names = "mac-address";
+};
+
&gpio1 {
bootph-pre-ram;
};
@@ -68,3 +81,7 @@
&usdhc3 {
bootph-pre-ram;
};
+
+&eeprom_som {
+ bootph-pre-ram;
+};
diff --git a/arch/arm/dts/imx8mn-var-som-symphony.dts b/arch/arm/dts/imx8mn-var-som-symphony.dts
index 3ed7021a487..5c8e4e81752 100644
--- a/arch/arm/dts/imx8mn-var-som-symphony.dts
+++ b/arch/arm/dts/imx8mn-var-som-symphony.dts
@@ -56,10 +56,6 @@
};
};
-&ethphy {
- reset-gpios = <&pca9534 5 GPIO_ACTIVE_HIGH>;
-};
-
&i2c2 {
clock-frequency = <400000>;
pinctrl-names = "default";
diff --git a/arch/arm/dts/imx8mn-var-som.dtsi b/arch/arm/dts/imx8mn-var-som.dtsi
index 87b5e23c766..4eb578a03fc 100644
--- a/arch/arm/dts/imx8mn-var-som.dtsi
+++ b/arch/arm/dts/imx8mn-var-som.dtsi
@@ -11,6 +11,10 @@
model = "Variscite VAR-SOM-MX8MN module";
compatible = "variscite,var-som-mx8mn", "fsl,imx8mn";
+ aliases {
+ eeprom-som = &eeprom_som;
+ };
+
chosen {
stdout-path = &uart4;
};
@@ -98,11 +102,17 @@
#address-cells = <1>;
#size-cells = <0>;
- ethphy: ethernet-phy@4 {
+ ethphy: ethernet-phy@4 { /* AR8033 or ADIN1300 */
compatible = "ethernet-phy-ieee802.3-c22";
reg = <4>;
reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
reset-assert-us = <10000>;
+ /*
+ * Deassert delay:
+ * ADIN1300 requires 5ms.
+ * AR8033 requires 1ms.
+ */
+ reset-deassert-us = <20000>;
};
};
};
@@ -222,6 +232,12 @@
};
};
};
+
+ eeprom_som: eeprom@52 {
+ compatible = "atmel,24c04";
+ reg = <0x52>;
+ pagesize = <16>;
+ };
};
&i2c3 {
diff --git a/arch/arm/dts/imx8mp-beacon-kit-u-boot.dtsi b/arch/arm/dts/imx8mp-beacon-kit-u-boot.dtsi
index 5ca631e9d8c..b56f3a2bd2e 100644
--- a/arch/arm/dts/imx8mp-beacon-kit-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-beacon-kit-u-boot.dtsi
@@ -185,12 +185,10 @@
&usb3_0 {
dma-ranges = <0x40000000 0x40000000 0xc0000000>;
- /delete-property/ power-domains;
};
&usb3_1 {
dma-ranges = <0x40000000 0x40000000 0xc0000000>;
- /delete-property/ power-domains;
};
&usb_dwc3_0 {
diff --git a/arch/arm/dts/imx8mp-u-boot.dtsi b/arch/arm/dts/imx8mp-u-boot.dtsi
index 68cd0e10f02..36e7444a627 100644
--- a/arch/arm/dts/imx8mp-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-u-boot.dtsi
@@ -44,6 +44,9 @@
&aips3 {
bootph-pre-ram;
+ spba-bus@30800000 {
+ bootph-pre-ram;
+ };
};
&iomuxc {
diff --git a/arch/arm/dts/imx8mp-venice-gw702x-u-boot.dtsi b/arch/arm/dts/imx8mp-venice-gw702x-u-boot.dtsi
new file mode 100644
index 00000000000..b9e3db7de93
--- /dev/null
+++ b/arch/arm/dts/imx8mp-venice-gw702x-u-boot.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2023 Gateworks Corporation
+ */
+
+#include "imx8mp-venice-u-boot.dtsi"
+
+&eqos {
+ /delete-property/ assigned-clocks;
+ /delete-property/ assigned-clock-parents;
+ /delete-property/ assigned-clock-rates;
+};
diff --git a/arch/arm/dts/imx8mp-venice-gw702x.dtsi b/arch/arm/dts/imx8mp-venice-gw702x.dtsi
new file mode 100644
index 00000000000..560c68e4da6
--- /dev/null
+++ b/arch/arm/dts/imx8mp-venice-gw702x.dtsi
@@ -0,0 +1,587 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2023 Gateworks Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/net/ti-dp83867.h>
+
+/ {
+ aliases {
+ ethernet0 = &eqos;
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x0 0x40000000 0 0x80000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key-user-pb {
+ label = "user_pb";
+ gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ };
+
+ key-user-pb1x {
+ label = "user_pb1x";
+ linux,code = <BTN_1>;
+ interrupt-parent = <&gsc>;
+ interrupts = <0>;
+ };
+
+ key-erased {
+ label = "key_erased";
+ linux,code = <BTN_2>;
+ interrupt-parent = <&gsc>;
+ interrupts = <1>;
+ };
+
+ key-eeprom-wp {
+ label = "eeprom_wp";
+ linux,code = <BTN_3>;
+ interrupt-parent = <&gsc>;
+ interrupts = <2>;
+ };
+
+ key-tamper {
+ label = "tamper";
+ linux,code = <BTN_4>;
+ interrupt-parent = <&gsc>;
+ interrupts = <5>;
+ };
+
+ switch-hold {
+ label = "switch_hold";
+ linux,code = <BTN_5>;
+ interrupt-parent = <&gsc>;
+ interrupts = <7>;
+ };
+ };
+};
+
+&A53_0 {
+ cpu-supply = <&buck3_reg>;
+};
+
+&A53_1 {
+ cpu-supply = <&buck3_reg>;
+};
+
+&A53_2 {
+ cpu-supply = <&buck3_reg>;
+};
+
+&A53_3 {
+ cpu-supply = <&buck3_reg>;
+};
+
+&eqos {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eqos>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy0>;
+ status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ pinctrl-0 = <&pinctrl_ethphy0>;
+ pinctrl-names = "default";
+ reg = <0x0>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+ tx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ rx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ scl-gpios = <&gpio5 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ gsc: gsc@20 {
+ compatible = "gw,gsc";
+ reg = <0x20>;
+ pinctrl-0 = <&pinctrl_gsc>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ adc {
+ compatible = "gw,gsc-adc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@6 {
+ gw,mode = <0>;
+ reg = <0x06>;
+ label = "temp";
+ };
+
+ channel@8 {
+ gw,mode = <3>;
+ reg = <0x08>;
+ label = "vdd_bat";
+ };
+
+ channel@16 {
+ gw,mode = <4>;
+ reg = <0x16>;
+ label = "fan_tach";
+ };
+
+ channel@82 {
+ gw,mode = <2>;
+ reg = <0x82>;
+ label = "vdd_vin";
+ gw,voltage-divider-ohms = <22100 1000>;
+ };
+
+ channel@84 {
+ gw,mode = <2>;
+ reg = <0x84>;
+ label = "vdd_adc1";
+ gw,voltage-divider-ohms = <10000 10000>;
+ };
+
+ channel@86 {
+ gw,mode = <2>;
+ reg = <0x86>;
+ label = "vdd_adc2";
+ gw,voltage-divider-ohms = <10000 10000>;
+ };
+
+ channel@88 {
+ gw,mode = <2>;
+ reg = <0x88>;
+ label = "vdd_1p0";
+ };
+
+ channel@8c {
+ gw,mode = <2>;
+ reg = <0x8c>;
+ label = "vdd_1p8";
+ };
+
+ channel@8e {
+ gw,mode = <2>;
+ reg = <0x8e>;
+ label = "vdd_2p5";
+ };
+
+ channel@90 {
+ gw,mode = <2>;
+ reg = <0x90>;
+ label = "vdd_3p3";
+ gw,voltage-divider-ohms = <10000 10000>;
+ };
+
+ channel@92 {
+ gw,mode = <2>;
+ reg = <0x92>;
+ label = "vdd_dram";
+ };
+
+ channel@98 {
+ gw,mode = <2>;
+ reg = <0x98>;
+ label = "vdd_soc";
+ };
+
+ channel@9a {
+ gw,mode = <2>;
+ reg = <0x9a>;
+ label = "vdd_arm";
+ };
+
+ channel@a2 {
+ gw,mode = <2>;
+ reg = <0xa2>;
+ label = "vdd_gsc";
+ gw,voltage-divider-ohms = <10000 10000>;
+ };
+ };
+
+ fan-controller@0 {
+ compatible = "gw,gsc-fan";
+ reg = <0x0a>;
+ };
+ };
+
+ gpio: gpio@23 {
+ compatible = "nxp,pca9555";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&gsc>;
+ interrupts = <4>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+
+ eeprom@51 {
+ compatible = "atmel,24c02";
+ reg = <0x51>;
+ pagesize = <16>;
+ };
+
+ eeprom@52 {
+ compatible = "atmel,24c02";
+ reg = <0x52>;
+ pagesize = <16>;
+ };
+
+ eeprom@53 {
+ compatible = "atmel,24c02";
+ reg = <0x53>;
+ pagesize = <16>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1672";
+ reg = <0x68>;
+ };
+
+ pmic@69 {
+ compatible = "mps,mp5416";
+ reg = <0x69>;
+
+ regulators {
+ /* vdd_soc */
+ buck1 {
+ regulator-name = "buck1";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* vdd_dram */
+ buck2 {
+ regulator-name = "buck2";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* vdd_arm */
+ buck3_reg: buck3 {
+ regulator-name = "buck3";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* vdd_1p8 */
+ buck4 {
+ regulator-name = "buck4";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* OUT2: nvcc_snvs_1p8 */
+ ldo1 {
+ regulator-name = "ldo1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* OUT3: vdd_1p0 */
+ ldo2 {
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* OUT4: vdd_2p5 */
+ ldo3 {
+ regulator-name = "ldo3";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* OUT5: vdd_3p3 */
+ ldo4 {
+ regulator-name = "ldo4";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+};
+
+/* off-board header */
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ pinctrl-1 = <&pinctrl_i2c2_gpio>;
+ scl-gpios = <&gpio5 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ eeprom@52 {
+ compatible = "atmel,24c32";
+ reg = <0x52>;
+ pagesize = <32>;
+ };
+};
+
+/* off-board header */
+&i2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ pinctrl-1 = <&pinctrl_i2c3_gpio>;
+ scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+};
+
+/* off-board header */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+/* console */
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+/* off-board header */
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+/* off-board */
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
+
+/* eMMC */
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_eqos: eqosgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x2
+ MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x2
+ MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x90
+ MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x90
+ MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x90
+ MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x90
+ MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x90
+ MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x90
+ MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x16
+ MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x16
+ MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x16
+ MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x16
+ MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x16
+ MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x16
+ >;
+ };
+
+ pinctrl_ethphy0: ethphy0grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_DQS__GPIO3_IO14 0x140 /* RST# */
+ MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x150 /* IRQ# */
+ >;
+ };
+
+ pinctrl_gsc: gscgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0x150 /* IRQ# */
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c2
+ MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c1_gpio: i2c1gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14 0x400001c2
+ MX8MP_IOMUXC_I2C1_SDA__GPIO5_IO15 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c2
+ MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c2_gpio: i2c2gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16 0x400001c2
+ MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c2
+ MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c3_gpio: i2c3gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C3_SCL__GPIO5_IO18 0x400001c2
+ MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x400001c2
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x140
+ MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140
+ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x140
+ MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190
+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0
+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0
+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0
+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0
+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190
+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d0
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d0
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d0
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d0
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d0
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d0
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d0
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d0
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d0
+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x190
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x194
+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d4
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d4
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d4
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d4
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d4
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d4
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d4
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d4
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d4
+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x194
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x196
+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d6
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d6
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d6
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d6
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d6
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d6
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d6
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d6
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d6
+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x196
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0x166
+ >;
+ };
+};
diff --git a/arch/arm/dts/imx8mp-venice-gw7905-2x-u-boot.dtsi b/arch/arm/dts/imx8mp-venice-gw7905-2x-u-boot.dtsi
new file mode 100644
index 00000000000..981841cee0a
--- /dev/null
+++ b/arch/arm/dts/imx8mp-venice-gw7905-2x-u-boot.dtsi
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2023 Gateworks Corporation
+ */
+#include "imx8mp-venice-gw702x-u-boot.dtsi"
+
+&gpio1 {
+ app_gpioa {
+ gpio-hog;
+ input;
+ gpios = <13 GPIO_ACTIVE_HIGH>;
+ line-name = "gpioa";
+ };
+};
+
+&gpio4 {
+ app_gpiod {
+ gpio-hog;
+ input;
+ gpios = <1 GPIO_ACTIVE_HIGH>;
+ line-name = "gpiod";
+ };
+
+ app_gpiob {
+ gpio-hog;
+ input;
+ gpios = <4 GPIO_ACTIVE_HIGH>;
+ line-name = "gpiob";
+ };
+
+ app_gpioc {
+ gpio-hog;
+ input;
+ gpios = <5 GPIO_ACTIVE_HIGH>;
+ line-name = "gpioc";
+ };
+
+ pci_usb_sel {
+ gpio-hog;
+ output-low;
+ gpios = <26 GPIO_ACTIVE_HIGH>;
+ line-name = "pci_usb_sel";
+ };
+
+ pci_wdis {
+ gpio-hog;
+ output-high;
+ gpios = <28 GPIO_ACTIVE_HIGH>;
+ line-name = "pci_wdis#";
+ };
+};
diff --git a/arch/arm/dts/imx8mp-venice-gw7905-2x.dts b/arch/arm/dts/imx8mp-venice-gw7905-2x.dts
new file mode 100644
index 00000000000..4a1bbbbe19e
--- /dev/null
+++ b/arch/arm/dts/imx8mp-venice-gw7905-2x.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2023 Gateworks Corporation
+ */
+
+/dts-v1/;
+
+#include "imx8mp.dtsi"
+#include "imx8mp-venice-gw702x.dtsi"
+#include "imx8mp-venice-gw7905.dtsi"
+
+/ {
+ model = "Gateworks Venice GW7905-2x i.MX8MP Development Kit";
+ compatible = "gateworks,imx8mp-gw7905-2x", "fsl,imx8mp";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+};
+
+/* Disable SOM interfaces not used on baseboard */
+&eqos {
+ status = "disabled";
+};
+
+&usdhc1 {
+ status = "disabled";
+};
diff --git a/arch/arm/dts/imx8mp-venice-gw7905.dtsi b/arch/arm/dts/imx8mp-venice-gw7905.dtsi
new file mode 100644
index 00000000000..0d40cb0f05f
--- /dev/null
+++ b/arch/arm/dts/imx8mp-venice-gw7905.dtsi
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2023 Gateworks Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+
+/ {
+ led-controller {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ led-0 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+
+ led-1 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio4 27 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
+ pcie0_refclk: pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
+ pps {
+ compatible = "pps-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pps>;
+ gpios = <&gpio4 21 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ reg_usb2_vbus: regulator-usb2-vbus {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usb2_en>;
+ compatible = "regulator-fixed";
+ regulator-name = "usb2_vbus";
+ gpio = <&gpio4 12 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
+ compatible = "regulator-fixed";
+ regulator-name = "SD2_3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+};
+
+/* off-board header */
+&ecspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi2>;
+ cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&gpio4 {
+ gpio-line-names =
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "gpioa", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "";
+};
+
+&gpio4 {
+ gpio-line-names =
+ "", "gpiod", "", "",
+ "gpiob", "gpioc", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "pci_usb_sel", "",
+ "pci_wdis#", "", "", "";
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ eeprom@52 {
+ compatible = "atmel,24c32";
+ reg = <0x52>;
+ pagesize = <32>;
+ };
+};
+
+/* off-board header */
+&i2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
+&pcie_phy {
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ fsl,clkreq-unsupported;
+ clocks = <&pcie0_refclk>;
+ clock-names = "ref";
+ status = "okay";
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ reset-gpio = <&gpio4 29 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+/* GPS */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+/* USB1 - Type C front panel SINK port J14 */
+&usb3_0 {
+ status = "okay";
+};
+
+&usb3_phy0 {
+ status = "okay";
+};
+
+&usb_dwc3_0 {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+/* USB2 4-port USB3.0 HUB:
+ * P1 - USBC connector (host only)
+ * P2 - USB2 test connector
+ * P3 - miniPCIe full card
+ * P4 - miniPCIe half card
+ */
+&usb3_phy1 {
+ vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
+
+&usb3_1 {
+ fsl,permanently-attached;
+ fsl,disable-port-power-control;
+ status = "okay";
+};
+
+&usb_dwc3_1 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+/* microSD */
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO13__GPIO1_IO13 0x40000040 /* GPIOA */
+ MX8MP_IOMUXC_SAI1_RXC__GPIO4_IO01 0x40000040 /* GPIOD */
+ MX8MP_IOMUXC_SAI1_RXD2__GPIO4_IO04 0x40000040 /* GPIOB */
+ MX8MP_IOMUXC_SAI1_RXD3__GPIO4_IO05 0x40000040 /* GPIOC */
+ MX8MP_IOMUXC_SAI2_TXD0__GPIO4_IO26 0x40000106 /* PCI_USBSEL */
+ MX8MP_IOMUXC_SAI3_RXFS__GPIO4_IO28 0x40000106 /* PCI_WDIS# */
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x6 /* LEDG */
+ MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27 0x6 /* LEDR */
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c2
+ MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c2
+ MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c2
+ >;
+ };
+
+ pinctrl_pcie0: pciegrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI3_RXC__GPIO4_IO29 0x106
+ >;
+ };
+
+ pinctrl_pps: ppsgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI2_RXFS__GPIO4_IO21 0x106
+ >;
+ };
+
+ pinctrl_reg_usb2_en: regusb2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI1_TXD0__GPIO4_IO12 0x6 /* USBHUB_RST# (ext p/u) */
+ >;
+ };
+
+ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x40
+ >;
+ };
+
+ pinctrl_spi2: spi2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_ECSPI2_SCLK__ECSPI2_SCLK 0x140
+ MX8MP_IOMUXC_ECSPI2_MOSI__ECSPI2_MOSI 0x140
+ MX8MP_IOMUXC_ECSPI2_MISO__ECSPI2_MISO 0x140
+ MX8MP_IOMUXC_ECSPI2_SS0__GPIO5_IO13 0x140
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x140
+ MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d0
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d0
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x194
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d4
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d4
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x196
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d6
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d6
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d6
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d6
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d6
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x1c4
+ >;
+ };
+};
diff --git a/arch/arm/dts/imx8mp-verdin-dahlia.dtsi b/arch/arm/dts/imx8mp-verdin-dahlia.dtsi
deleted file mode 100644
index 4b8f86f6308..00000000000
--- a/arch/arm/dts/imx8mp-verdin-dahlia.dtsi
+++ /dev/null
@@ -1,129 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-/*
- * Copyright 2022 Toradex
- */
-
-/* TODO: Audio Codec */
-
-&backlight {
- power-supply = <&reg_3p3v>;
-};
-
-/* Verdin SPI_1 */
-&ecspi1 {
- status = "okay";
-};
-
-/* EEPROM on display adapter boards */
-&eeprom_display_adapter {
- status = "okay";
-};
-
-/* EEPROM on Verdin Development board */
-&eeprom_carrier_board {
- status = "okay";
-};
-
-&eqos {
- status = "okay";
-};
-
-&flexcan1 {
- status = "okay";
-};
-
-&flexcan2 {
- status = "okay";
-};
-
-/* Verdin QSPI_1 */
-&flexspi {
- status = "okay";
-};
-
-/* Current measurement into module VCC */
-&hwmon {
- status = "okay";
-};
-
-&hwmon_temp {
- vs-supply = <&reg_1p8v>;
- status = "okay";
-};
-
-/* Verdin I2C_2_DSI */
-&i2c2 {
- status = "okay";
-};
-
-&i2c3 {
- status = "okay";
-};
-
-/* Verdin I2C_1 */
-&i2c4 {
- status = "okay";
-
- /* TODO: Audio Codec */
-};
-
-/* TODO: Verdin PCIE_1 */
-
-/* Verdin PWM_1 */
-&pwm1 {
- status = "okay";
-};
-
-/* Verdin PWM_2 */
-&pwm2 {
- status = "okay";
-};
-
-/* Verdin PWM_3_DSI */
-&pwm3 {
- status = "okay";
-};
-
-&reg_usdhc2_vmmc {
- vin-supply = <&reg_3p3v>;
-};
-
-/* TODO: Verdin I2S_1 */
-
-/* Verdin UART_1 */
-&uart1 {
- status = "okay";
-};
-
-/* Verdin UART_2 */
-&uart2 {
- status = "okay";
-};
-
-/* Verdin UART_3, used as the Linux Console */
-&uart3 {
- status = "okay";
-};
-
-/* Verdin USB_1 */
-&usb3_0 {
- status = "okay";
-};
-
-&usb3_phy0 {
- status = "okay";
-};
-
-/* Verdin USB_2 */
-&usb3_1 {
- status = "okay";
-};
-
-&usb3_phy1 {
- status = "okay";
-};
-
-/* Verdin SD_1 */
-&usdhc2 {
- status = "okay";
-};
diff --git a/arch/arm/dts/imx8mp-verdin-dev.dtsi b/arch/arm/dts/imx8mp-verdin-dev.dtsi
index cefabe65b25..bdfdd4c782f 100644
--- a/arch/arm/dts/imx8mp-verdin-dev.dtsi
+++ b/arch/arm/dts/imx8mp-verdin-dev.dtsi
@@ -3,8 +3,6 @@
* Copyright 2022 Toradex
*/
-#include "imx8mp-verdin-dahlia.dtsi"
-
/ {
/* TODO: Audio Codec */
@@ -12,7 +10,7 @@
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio_expander_21 4 GPIO_ACTIVE_HIGH>; /* ETH_PWR_EN */
- off-on-delay = <500000>;
+ off-on-delay-us = <500000>;
regulator-max-microvolt = <3300000>;
regulator-min-microvolt = <3300000>;
regulator-name = "+V3.3_ETH";
@@ -21,16 +19,106 @@
};
};
+&backlight {
+ power-supply = <&reg_3p3v>;
+};
+
+/* Verdin SPI_1 */
+&ecspi1 {
+ status = "okay";
+};
+
+/* EEPROM on display adapter boards */
+&eeprom_display_adapter {
+ status = "okay";
+};
+
+/* EEPROM on Verdin Development board */
+&eeprom_carrier_board {
+ status = "okay";
+};
+
+&eqos {
+ status = "okay";
+};
+
&fec {
phy-supply = <&reg_eth2phy>;
status = "okay";
};
+&flexcan1 {
+ status = "okay";
+};
+
+&flexcan2 {
+ status = "okay";
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+ status = "okay";
+};
+
&gpio_expander_21 {
status = "okay";
vcc-supply = <&reg_1p8v>;
};
+/* Current measurement into module VCC */
+&hwmon {
+ status = "okay";
+};
+
+&hwmon_temp {
+ vs-supply = <&reg_1p8v>;
+ status = "okay";
+};
+
+/* Verdin I2C_2_DSI */
+&i2c2 {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+ status = "okay";
+
+ /* TODO: Audio Codec */
+};
+
+/* Verdin PCIE_1 */
+&pcie {
+ status = "okay";
+};
+
+&pcie_phy {
+ status = "okay";
+};
+
+/* Verdin PWM_1 */
+&pwm1 {
+ status = "okay";
+};
+
+/* Verdin PWM_2 */
+&pwm2 {
+ status = "okay";
+};
+
+/* Verdin PWM_3_DSI */
+&pwm3 {
+ status = "okay";
+};
+
+&reg_usdhc2_vmmc {
+ vin-supply = <&reg_3p3v>;
+};
+
/* TODO: Verdin I2C_1 with Audio Codec */
/* Verdin UART_1, connector X50 through RS485 transceiver */
@@ -38,9 +126,40 @@
linux,rs485-enabled-at-boot-time;
rs485-rts-active-low;
rs485-rx-during-tx;
+ status = "okay";
+};
+
+/* Verdin UART_2 */
+&uart2 {
+ status = "okay";
+};
+
+/* Verdin UART_3, used as the Linux Console */
+&uart3 {
+ status = "okay";
+};
+
+/* Verdin USB_1 */
+&usb3_0 {
+ status = "okay";
+};
+
+&usb3_phy0 {
+ status = "okay";
+};
+
+/* Verdin USB_2 */
+&usb3_1 {
+ fsl,permanently-attached;
+ status = "okay";
+};
+
+&usb3_phy1 {
+ status = "okay";
};
/* Limit frequency on dev board due to long traces and bad signal integrity */
&usdhc2 {
max-frequency = <100000000>;
+ status = "okay";
};
diff --git a/arch/arm/dts/imx8mp-verdin-wifi-dev-u-boot.dtsi b/arch/arm/dts/imx8mp-verdin-wifi-dev-u-boot.dtsi
index 9c6c417f7ee..0162f9b2da3 100644
--- a/arch/arm/dts/imx8mp-verdin-wifi-dev-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-verdin-wifi-dev-u-boot.dtsi
@@ -62,6 +62,10 @@
&gpio4 {
bootph-pre-ram;
+
+ ctrl-sleep-moci-hog {
+ bootph-pre-ram;
+ };
};
&gpio5 {
@@ -106,6 +110,10 @@
bootph-pre-ram;
};
+&pinctrl_ctrl_sleep_moci {
+ bootph-pre-ram;
+};
+
&pinctrl_i2c1 {
bootph-pre-ram;
};
diff --git a/arch/arm/dts/imx8mp-verdin-wifi.dtsi b/arch/arm/dts/imx8mp-verdin-wifi.dtsi
index 36289c175e6..ef94f9a57e2 100644
--- a/arch/arm/dts/imx8mp-verdin-wifi.dtsi
+++ b/arch/arm/dts/imx8mp-verdin-wifi.dtsi
@@ -65,6 +65,11 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_bt_uart>;
status = "okay";
+
+ bluetooth {
+ compatible = "mrvl,88w8997";
+ max-speed = <921600>;
+ };
};
/* On-module Wi-Fi */
diff --git a/arch/arm/dts/imx8mp-verdin.dtsi b/arch/arm/dts/imx8mp-verdin.dtsi
index 7b712d1888e..e9e4fcb562f 100644
--- a/arch/arm/dts/imx8mp-verdin.dtsi
+++ b/arch/arm/dts/imx8mp-verdin.dtsi
@@ -3,7 +3,8 @@
* Copyright 2022 Toradex
*/
-#include "dt-bindings/pwm/pwm.h"
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+#include <dt-bindings/pwm/pwm.h>
#include "imx8mp.dtsi"
/ {
@@ -49,7 +50,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio_keys>;
- button-wakeup {
+ key-wakeup {
debounce-interval = <10>;
/* Verdin CTRL_WAKE1_MICO# (SODIMM 252) */
gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;
@@ -86,7 +87,7 @@
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>; /* PMIC_EN_ETH */
- off-on-delay = <500000>;
+ off-on-delay-us = <500000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_reg_eth>;
regulator-always-on;
@@ -127,7 +128,7 @@
enable-active-high;
/* Verdin SD_1_PWR_EN (SODIMM 76) */
gpio = <&gpio4 22 GPIO_ACTIVE_HIGH>;
- off-on-delay = <100000>;
+ off-on-delay-us = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc2_pwr_en>;
regulator-max-microvolt = <3300000>;
@@ -354,16 +355,6 @@
"SODIMM_82",
"SODIMM_70",
"SODIMM_72";
-
- ctrl-sleep-moci-hog {
- gpio-hog;
- /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
- gpios = <29 GPIO_ACTIVE_HIGH>;
- line-name = "CTRL_SLEEP_MOCI#";
- output-high;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
- };
};
&gpio3 {
@@ -432,6 +423,16 @@
"SODIMM_256",
"SODIMM_48",
"SODIMM_44";
+
+ ctrl-sleep-moci-hog {
+ gpio-hog;
+ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+ gpios = <29 GPIO_ACTIVE_HIGH>;
+ line-name = "CTRL_SLEEP_MOCI#";
+ output-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+ };
};
/* On-module I2C */
@@ -452,7 +453,6 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pmic>;
reg = <0x25>;
- sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
/*
* The bootloader is expected to switch on LDO4 for the on-module +V3.3_ADC and the
@@ -678,8 +678,8 @@
status = "disabled";
};
- lvds_ti_sn65dsi83: bridge@2c {
- compatible = "ti,sn65dsi83";
+ lvds_ti_sn65dsi84: bridge@2c {
+ compatible = "ti,sn65dsi84";
/* Verdin GPIO_9_DSI (SN65DSI84 IRQ, SODIMM 17, unused) */
/* Verdin GPIO_10_DSI (SODIMM 21) */
enable-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;
@@ -712,7 +712,7 @@
compatible = "atmel,maxtouch";
/*
* Verdin GPIO_9_DSI
- * (TOUCH_INT#, SODIMM 17, also routed to SN65DSI83 IRQ albeit currently unused)
+ * (TOUCH_INT#, SODIMM 17, also routed to SN65DSI84 IRQ albeit currently unused)
*/
interrupt-parent = <&gpio4>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
@@ -748,7 +748,20 @@
};
};
-/* TODO: Verdin PCIE_1 */
+/* Verdin PCIE_1 */
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ /* PCIE_1_RESET# (SODIMM 244) */
+ reset-gpio = <&gpio4 19 GPIO_ACTIVE_LOW>;
+};
+
+&pcie_phy {
+ clocks = <&hsio_blk_ctrl>;
+ clock-names = "ref";
+ fsl,clkreq-unsupported;
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_OUTPUT>;
+};
/* Verdin PWM_1 */
&pwm1 {
@@ -806,28 +819,45 @@
};
/* Verdin USB_1 */
-&usb3_phy0 {
- vbus-supply = <&reg_usb1_vbus>;
+&usb3_0 {
+ fsl,disable-port-power-control;
+ fsl,over-current-active-low;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_1_oc_n>;
};
&usb_dwc3_0 {
+ /* dual role only, not full featured OTG */
adp-disable;
dr_mode = "otg";
hnp-disable;
maximum-speed = "high-speed";
- over-current-active-low;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb_1_id>;
+ role-switch-default-mode = "peripheral";
srp-disable;
+ usb-role-switch;
+
+ connector {
+ compatible = "gpio-usb-b-connector", "usb-b-connector";
+ id-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
+ label = "Type-C";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_1_id>;
+ self-powered;
+ type = "micro";
+ vbus-supply = <&reg_usb1_vbus>;
+ };
};
/* Verdin USB_2 */
+&usb3_1 {
+ fsl,disable-port-power-control;
+};
+
&usb3_phy1 {
vbus-supply = <&reg_usb2_vbus>;
};
&usb_dwc3_1 {
- disable-over-current;
dr_mode = "host";
};
@@ -1045,7 +1075,6 @@
pinctrl_gpio_hog3: gpiohog3grp {
fsl,pins =
- <MX8MP_IOMUXC_GPIO1_IO13__GPIO1_IO13 0x1c4>, /* SODIMM 157 */
/* CSI_1_MCLK */
<MX8MP_IOMUXC_GPIO1_IO15__GPIO1_IO15 0x1c4>; /* SODIMM 91 */
};
@@ -1220,7 +1249,7 @@
pinctrl_usb1_vbus: usb1vbusgrp {
fsl,pins =
- <MX8MP_IOMUXC_GPIO1_IO12__USB1_OTG_PWR 0x19>; /* SODIMM 155 */
+ <MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12 0x106>; /* SODIMM 155 */
};
/* USB_1_ID */
@@ -1229,9 +1258,15 @@
<MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x1c4>; /* SODIMM 161 */
};
+ /* USB_1_OC# */
+ pinctrl_usb_1_oc_n: usb1ocngrp {
+ fsl,pins =
+ <MX8MP_IOMUXC_GPIO1_IO13__USB1_OTG_OC 0x1c4>; /* SODIMM 157 */
+ };
+
pinctrl_usb2_vbus: usb2vbusgrp {
fsl,pins =
- <MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR 0x19>; /* SODIMM 185 */
+ <MX8MP_IOMUXC_GPIO1_IO14__GPIO1_IO14 0x106>; /* SODIMM 185 */
};
/* On-module Wi-Fi */
diff --git a/arch/arm/dts/imx8mp.dtsi b/arch/arm/dts/imx8mp.dtsi
index bb916a0948a..428c60462e3 100644
--- a/arch/arm/dts/imx8mp.dtsi
+++ b/arch/arm/dts/imx8mp.dtsi
@@ -123,6 +123,7 @@
A53_L2: l2-cache0 {
compatible = "cache";
+ cache-unified;
cache-level = <2>;
cache-size = <0x80000>;
cache-line-size = <64>;
@@ -379,6 +380,8 @@
compatible = "fsl,imx8mp-tmu";
reg = <0x30260000 0x10000>;
clocks = <&clk IMX8MP_CLK_TSENSOR_ROOT>;
+ nvmem-cells = <&tmu_calib>;
+ nvmem-cell-names = "calib";
#thermal-sensor-cells = <1>;
};
@@ -406,12 +409,36 @@
status = "disabled";
};
+ gpt1: timer@302d0000 {
+ compatible = "fsl,imx8mp-gpt", "fsl,imx6dl-gpt";
+ reg = <0x302d0000 0x10000>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_GPT1_ROOT>, <&clk IMX8MP_CLK_GPT1>;
+ clock-names = "ipg", "per";
+ };
+
+ gpt2: timer@302e0000 {
+ compatible = "fsl,imx8mp-gpt", "fsl,imx6dl-gpt";
+ reg = <0x302e0000 0x10000>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_GPT2_ROOT>, <&clk IMX8MP_CLK_GPT2>;
+ clock-names = "ipg", "per";
+ };
+
+ gpt3: timer@302f0000 {
+ compatible = "fsl,imx8mp-gpt", "fsl,imx6dl-gpt";
+ reg = <0x302f0000 0x10000>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_GPT3_ROOT>, <&clk IMX8MP_CLK_GPT3>;
+ clock-names = "ipg", "per";
+ };
+
iomuxc: pinctrl@30330000 {
compatible = "fsl,imx8mp-iomuxc";
reg = <0x30330000 0x10000>;
};
- gpr: iomuxc-gpr@30340000 {
+ gpr: syscon@30340000 {
compatible = "fsl,imx8mp-iomuxc-gpr", "syscon";
reg = <0x30340000 0x10000>;
};
@@ -424,27 +451,44 @@
#address-cells = <1>;
#size-cells = <1>;
- imx8mp_uid: unique-id@420 {
+ /*
+ * The register address below maps to the MX8M
+ * Fusemap Description Table entries this way.
+ * Assuming
+ * reg = <ADDR SIZE>;
+ * then
+ * Fuse Address = (ADDR * 4) + 0x400
+ * Note that if SIZE is greater than 4, then
+ * each subsequent fuse is located at offset
+ * +0x10 in Fusemap Description Table (e.g.
+ * reg = <0x8 0x8> describes fuses 0x420 and
+ * 0x430).
+ */
+ imx8mp_uid: unique-id@8 { /* 0x420-0x430 */
reg = <0x8 0x8>;
};
- cpu_speed_grade: speed-grade@10 {
+ cpu_speed_grade: speed-grade@10 { /* 0x440 */
reg = <0x10 4>;
};
- eth_mac1: mac-address@90 {
+ eth_mac1: mac-address@90 { /* 0x640 */
reg = <0x90 6>;
};
- eth_mac2: mac-address@96 {
+ eth_mac2: mac-address@96 { /* 0x658 */
reg = <0x96 6>;
};
+
+ tmu_calib: calib@264 { /* 0xd90-0xdc0 */
+ reg = <0x264 0x10>;
+ };
};
- anatop: anatop@30360000 {
- compatible = "fsl,imx8mp-anatop", "fsl,imx8mm-anatop",
- "syscon";
+ anatop: clock-controller@30360000 {
+ compatible = "fsl,imx8mp-anatop", "fsl,imx8mm-anatop";
reg = <0x30360000 0x10000>;
+ #clock-cells = <1>;
};
snvs: snvs@30370000 {
@@ -523,6 +567,7 @@
compatible = "fsl,imx8mp-gpc";
reg = <0x303a0000 0x1000>;
interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <3>;
@@ -589,7 +634,7 @@
reg = <IMX8MP_POWER_DOMAIN_MIPI_PHY2>;
};
- pgc_hsiomix: power-domains@17 {
+ pgc_hsiomix: power-domain@17 {
#power-domain-cells = <0>;
reg = <IMX8MP_POWER_DOMAIN_HSIOMIX>;
clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
@@ -631,6 +676,14 @@
reg = <IMX8MP_POWER_DOMAIN_VPU_VC8000E>;
clocks = <&clk IMX8MP_CLK_VPU_VC8KE_ROOT>;
};
+
+ pgc_mlmix: power-domain@24 {
+ #power-domain-cells = <0>;
+ reg = <IMX8MP_POWER_DOMAIN_MLMIX>;
+ clocks = <&clk IMX8MP_CLK_ML_AXI>,
+ <&clk IMX8MP_CLK_ML_AHB>,
+ <&clk IMX8MP_CLK_NPU_ROOT>;
+ };
};
};
};
@@ -693,6 +746,30 @@
clocks = <&osc_24m>;
clock-names = "per";
};
+
+ gpt6: timer@306e0000 {
+ compatible = "fsl,imx8mp-gpt", "fsl,imx6dl-gpt";
+ reg = <0x306e0000 0x10000>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_GPT6_ROOT>, <&clk IMX8MP_CLK_GPT6>;
+ clock-names = "ipg", "per";
+ };
+
+ gpt5: timer@306f0000 {
+ compatible = "fsl,imx8mp-gpt", "fsl,imx6dl-gpt";
+ reg = <0x306f0000 0x10000>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_GPT5_ROOT>, <&clk IMX8MP_CLK_GPT5>;
+ clock-names = "ipg", "per";
+ };
+
+ gpt4: timer@30700000 {
+ compatible = "fsl,imx8mp-gpt", "fsl,imx6dl-gpt";
+ reg = <0x30700000 0x10000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_GPT4_ROOT>, <&clk IMX8MP_CLK_GPT4>;
+ clock-names = "ipg", "per";
+ };
};
aips3: bus@30800000 {
@@ -702,112 +779,129 @@
#size-cells = <1>;
ranges;
- ecspi1: spi@30820000 {
+ spba-bus@30800000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ reg = <0x30800000 0x100000>;
#address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,imx8mp-ecspi", "fsl,imx51-ecspi";
- reg = <0x30820000 0x10000>;
- interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk IMX8MP_CLK_ECSPI1_ROOT>,
- <&clk IMX8MP_CLK_ECSPI1_ROOT>;
- clock-names = "ipg", "per";
- dmas = <&sdma1 0 7 1>, <&sdma1 1 7 2>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
+ #size-cells = <1>;
+ ranges;
- ecspi2: spi@30830000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,imx8mp-ecspi", "fsl,imx51-ecspi";
- reg = <0x30830000 0x10000>;
- interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk IMX8MP_CLK_ECSPI2_ROOT>,
- <&clk IMX8MP_CLK_ECSPI2_ROOT>;
- clock-names = "ipg", "per";
- dmas = <&sdma1 2 7 1>, <&sdma1 3 7 2>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
+ ecspi1: spi@30820000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mp-ecspi", "fsl,imx6ul-ecspi";
+ reg = <0x30820000 0x10000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_ECSPI1_ROOT>,
+ <&clk IMX8MP_CLK_ECSPI1_ROOT>;
+ clock-names = "ipg", "per";
+ assigned-clock-rates = <80000000>;
+ assigned-clocks = <&clk IMX8MP_CLK_ECSPI1>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>;
+ dmas = <&sdma1 0 7 1>, <&sdma1 1 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
- ecspi3: spi@30840000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,imx8mp-ecspi", "fsl,imx51-ecspi";
- reg = <0x30840000 0x10000>;
- interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk IMX8MP_CLK_ECSPI3_ROOT>,
- <&clk IMX8MP_CLK_ECSPI3_ROOT>;
- clock-names = "ipg", "per";
- dmas = <&sdma1 4 7 1>, <&sdma1 5 7 2>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
+ ecspi2: spi@30830000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mp-ecspi", "fsl,imx6ul-ecspi";
+ reg = <0x30830000 0x10000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_ECSPI2_ROOT>,
+ <&clk IMX8MP_CLK_ECSPI2_ROOT>;
+ clock-names = "ipg", "per";
+ assigned-clock-rates = <80000000>;
+ assigned-clocks = <&clk IMX8MP_CLK_ECSPI2>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>;
+ dmas = <&sdma1 2 7 1>, <&sdma1 3 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
- uart1: serial@30860000 {
- compatible = "fsl,imx8mp-uart", "fsl,imx6q-uart";
- reg = <0x30860000 0x10000>;
- interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk IMX8MP_CLK_UART1_ROOT>,
- <&clk IMX8MP_CLK_UART1_ROOT>;
- clock-names = "ipg", "per";
- dmas = <&sdma1 22 4 0>, <&sdma1 23 4 0>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
+ ecspi3: spi@30840000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx8mp-ecspi", "fsl,imx6ul-ecspi";
+ reg = <0x30840000 0x10000>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_ECSPI3_ROOT>,
+ <&clk IMX8MP_CLK_ECSPI3_ROOT>;
+ clock-names = "ipg", "per";
+ assigned-clock-rates = <80000000>;
+ assigned-clocks = <&clk IMX8MP_CLK_ECSPI3>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>;
+ dmas = <&sdma1 4 7 1>, <&sdma1 5 7 2>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
- uart3: serial@30880000 {
- compatible = "fsl,imx8mp-uart", "fsl,imx6q-uart";
- reg = <0x30880000 0x10000>;
- interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk IMX8MP_CLK_UART3_ROOT>,
- <&clk IMX8MP_CLK_UART3_ROOT>;
- clock-names = "ipg", "per";
- dmas = <&sdma1 26 4 0>, <&sdma1 27 4 0>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
+ uart1: serial@30860000 {
+ compatible = "fsl,imx8mp-uart", "fsl,imx6q-uart";
+ reg = <0x30860000 0x10000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_UART1_ROOT>,
+ <&clk IMX8MP_CLK_UART1_ROOT>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma1 22 4 0>, <&sdma1 23 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
- uart2: serial@30890000 {
- compatible = "fsl,imx8mp-uart", "fsl,imx6q-uart";
- reg = <0x30890000 0x10000>;
- interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk IMX8MP_CLK_UART2_ROOT>,
- <&clk IMX8MP_CLK_UART2_ROOT>;
- clock-names = "ipg", "per";
- dmas = <&sdma1 24 4 0>, <&sdma1 25 4 0>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
+ uart3: serial@30880000 {
+ compatible = "fsl,imx8mp-uart", "fsl,imx6q-uart";
+ reg = <0x30880000 0x10000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_UART3_ROOT>,
+ <&clk IMX8MP_CLK_UART3_ROOT>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma1 26 4 0>, <&sdma1 27 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
- flexcan1: can@308c0000 {
- compatible = "fsl,imx8mp-flexcan";
- reg = <0x308c0000 0x10000>;
- interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk IMX8MP_CLK_IPG_ROOT>,
- <&clk IMX8MP_CLK_CAN1_ROOT>;
- clock-names = "ipg", "per";
- assigned-clocks = <&clk IMX8MP_CLK_CAN1>;
- assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_40M>;
- assigned-clock-rates = <40000000>;
- fsl,clk-source = /bits/ 8 <0>;
- fsl,stop-mode = <&gpr 0x10 4>;
- status = "disabled";
- };
+ uart2: serial@30890000 {
+ compatible = "fsl,imx8mp-uart", "fsl,imx6q-uart";
+ reg = <0x30890000 0x10000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_UART2_ROOT>,
+ <&clk IMX8MP_CLK_UART2_ROOT>;
+ clock-names = "ipg", "per";
+ dmas = <&sdma1 24 4 0>, <&sdma1 25 4 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
- flexcan2: can@308d0000 {
- compatible = "fsl,imx8mp-flexcan";
- reg = <0x308d0000 0x10000>;
- interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk IMX8MP_CLK_IPG_ROOT>,
- <&clk IMX8MP_CLK_CAN2_ROOT>;
- clock-names = "ipg", "per";
- assigned-clocks = <&clk IMX8MP_CLK_CAN2>;
- assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_40M>;
- assigned-clock-rates = <40000000>;
- fsl,clk-source = /bits/ 8 <0>;
- fsl,stop-mode = <&gpr 0x10 5>;
- status = "disabled";
+ flexcan1: can@308c0000 {
+ compatible = "fsl,imx8mp-flexcan";
+ reg = <0x308c0000 0x10000>;
+ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_IPG_ROOT>,
+ <&clk IMX8MP_CLK_CAN1_ROOT>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8MP_CLK_CAN1>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_40M>;
+ assigned-clock-rates = <40000000>;
+ fsl,clk-source = /bits/ 8 <0>;
+ fsl,stop-mode = <&gpr 0x10 4>;
+ status = "disabled";
+ };
+
+ flexcan2: can@308d0000 {
+ compatible = "fsl,imx8mp-flexcan";
+ reg = <0x308d0000 0x10000>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_IPG_ROOT>,
+ <&clk IMX8MP_CLK_CAN2_ROOT>;
+ clock-names = "ipg", "per";
+ assigned-clocks = <&clk IMX8MP_CLK_CAN2>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_40M>;
+ assigned-clock-rates = <40000000>;
+ fsl,clk-source = /bits/ 8 <0>;
+ fsl,stop-mode = <&gpr 0x10 5>;
+ status = "disabled";
+ };
};
crypto: crypto@30900000 {
@@ -1063,11 +1157,11 @@
noc_opp_table: opp-table {
compatible = "operating-points-v2";
- opp-200M {
+ opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
};
- opp-1000M {
+ opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
};
};
@@ -1080,10 +1174,78 @@
#size-cells = <1>;
ranges;
+ mipi_dsi: dsi@32e60000 {
+ compatible = "fsl,imx8mp-mipi-dsim";
+ reg = <0x32e60000 0x400>;
+ clocks = <&clk IMX8MP_CLK_MEDIA_APB_ROOT>,
+ <&clk IMX8MP_CLK_MEDIA_MIPI_PHY1_REF>;
+ clock-names = "bus_clk", "sclk_mipi";
+ assigned-clocks = <&clk IMX8MP_CLK_MEDIA_APB>,
+ <&clk IMX8MP_CLK_MEDIA_MIPI_PHY1_REF>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>,
+ <&clk IMX8MP_CLK_24M>;
+ assigned-clock-rates = <200000000>, <24000000>;
+ samsung,pll-clock-frequency = <24000000>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&media_blk_ctrl IMX8MP_MEDIABLK_PD_MIPI_DSI_1>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ dsim_from_lcdif1: endpoint {
+ remote-endpoint = <&lcdif1_to_dsim>;
+ };
+ };
+ };
+ };
+
+ lcdif1: display-controller@32e80000 {
+ compatible = "fsl,imx8mp-lcdif";
+ reg = <0x32e80000 0x10000>;
+ clocks = <&clk IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT>,
+ <&clk IMX8MP_CLK_MEDIA_APB_ROOT>,
+ <&clk IMX8MP_CLK_MEDIA_AXI_ROOT>;
+ clock-names = "pix", "axi", "disp_axi";
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&media_blk_ctrl IMX8MP_MEDIABLK_PD_LCDIF_1>;
+ status = "disabled";
+
+ port {
+ lcdif1_to_dsim: endpoint {
+ remote-endpoint = <&dsim_from_lcdif1>;
+ };
+ };
+ };
+
+ lcdif2: display-controller@32e90000 {
+ compatible = "fsl,imx8mp-lcdif";
+ reg = <0x32e90000 0x10000>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT>,
+ <&clk IMX8MP_CLK_MEDIA_APB_ROOT>,
+ <&clk IMX8MP_CLK_MEDIA_AXI_ROOT>;
+ clock-names = "pix", "axi", "disp_axi";
+ power-domains = <&media_blk_ctrl IMX8MP_MEDIABLK_PD_LCDIF_2>;
+ status = "disabled";
+
+ port {
+ lcdif2_to_ldb: endpoint {
+ remote-endpoint = <&ldb_from_lcdif2>;
+ };
+ };
+ };
+
media_blk_ctrl: blk-ctrl@32ec0000 {
compatible = "fsl,imx8mp-media-blk-ctrl",
"syscon";
reg = <0x32ec0000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
power-domains = <&pgc_mediamix>,
<&pgc_mipi_phy1>,
<&pgc_mipi_phy1>,
@@ -1122,12 +1284,55 @@
"disp1", "disp2", "isp", "phy";
assigned-clocks = <&clk IMX8MP_CLK_MEDIA_AXI>,
- <&clk IMX8MP_CLK_MEDIA_APB>;
+ <&clk IMX8MP_CLK_MEDIA_APB>,
+ <&clk IMX8MP_CLK_MEDIA_DISP1_PIX>,
+ <&clk IMX8MP_CLK_MEDIA_DISP2_PIX>,
+ <&clk IMX8MP_VIDEO_PLL1>;
assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_1000M>,
- <&clk IMX8MP_SYS_PLL1_800M>;
- assigned-clock-rates = <500000000>, <200000000>;
-
+ <&clk IMX8MP_SYS_PLL1_800M>,
+ <&clk IMX8MP_VIDEO_PLL1_OUT>,
+ <&clk IMX8MP_VIDEO_PLL1_OUT>;
+ assigned-clock-rates = <500000000>, <200000000>,
+ <0>, <0>, <1039500000>;
#power-domain-cells = <1>;
+
+ lvds_bridge: bridge@5c {
+ compatible = "fsl,imx8mp-ldb";
+ reg = <0x5c 0x4>, <0x128 0x4>;
+ reg-names = "ldb", "lvds";
+ clocks = <&clk IMX8MP_CLK_MEDIA_LDB>;
+ clock-names = "ldb";
+ assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>;
+ assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ ldb_from_lcdif2: endpoint {
+ remote-endpoint = <&lcdif2_to_ldb>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ ldb_lvds_ch0: endpoint {
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ ldb_lvds_ch1: endpoint {
+ };
+ };
+ };
+ };
};
pcie_phy: pcie-phy@32f00000 {
@@ -1158,6 +1363,7 @@
<&noc IMX8MP_ICM_PCIE &noc IMX8MP_ICN_HSIO>;
interconnect-names = "noc-pcie", "usb1", "usb2", "pcie";
#power-domain-cells = <1>;
+ #clock-cells = <0>;
};
};
@@ -1165,6 +1371,13 @@
compatible = "fsl,imx8mp-pcie";
reg = <0x33800000 0x400000>, <0x1ff00000 0x80000>;
reg-names = "dbi", "config";
+ clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
+ <&clk IMX8MP_CLK_HSIO_AXI>,
+ <&clk IMX8MP_CLK_PCIE_ROOT>;
+ clock-names = "pcie", "pcie_bus", "pcie_aux";
+ assigned-clocks = <&clk IMX8MP_CLK_PCIE_AUX>;
+ assigned-clock-rates = <10000000>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_50M>;
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
@@ -1192,6 +1405,32 @@
status = "disabled";
};
+ pcie_ep: pcie-ep@33800000 {
+ compatible = "fsl,imx8mp-pcie-ep";
+ reg = <0x33800000 0x000400000>, <0x18000000 0x08000000>;
+ reg-names = "dbi", "addr_space";
+ clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
+ <&clk IMX8MP_CLK_HSIO_AXI>,
+ <&clk IMX8MP_CLK_PCIE_ROOT>;
+ clock-names = "pcie", "pcie_bus", "pcie_aux";
+ assigned-clocks = <&clk IMX8MP_CLK_PCIE_AUX>;
+ assigned-clock-rates = <10000000>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_50M>;
+ num-lanes = <1>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; /* eDMA */
+ interrupt-names = "dma";
+ fsl,max-link-speed = <3>;
+ power-domains = <&hsio_blk_ctrl IMX8MP_HSIOBLK_PD_PCIE>;
+ resets = <&src IMX8MP_RESET_PCIE_CTRL_APPS_EN>,
+ <&src IMX8MP_RESET_PCIE_CTRL_APPS_TURNOFF>;
+ reset-names = "apps", "turnoff";
+ phys = <&pcie_phy>;
+ phy-names = "pcie-phy";
+ num-ib-windows = <4>;
+ num-ob-windows = <4>;
+ status = "disabled";
+ };
+
gpu3d: gpu@38000000 {
compatible = "vivante,gc";
reg = <0x38000000 0x8000>;
@@ -1223,6 +1462,28 @@
power-domains = <&pgc_gpu2d>;
};
+ vpu_g1: video-codec@38300000 {
+ compatible = "nxp,imx8mm-vpu-g1";
+ reg = <0x38300000 0x10000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_VPU_G1_ROOT>;
+ assigned-clocks = <&clk IMX8MP_CLK_VPU_G1>;
+ assigned-clock-parents = <&clk IMX8MP_VPU_PLL_OUT>;
+ assigned-clock-rates = <600000000>;
+ power-domains = <&vpumix_blk_ctrl IMX8MP_VPUBLK_PD_G1>;
+ };
+
+ vpu_g2: video-codec@38310000 {
+ compatible = "nxp,imx8mq-vpu-g2";
+ reg = <0x38310000 0x10000>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_VPU_G2_ROOT>;
+ assigned-clocks = <&clk IMX8MP_CLK_VPU_G2>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_1000M>;
+ assigned-clock-rates = <500000000>;
+ power-domains = <&vpumix_blk_ctrl IMX8MP_VPUBLK_PD_G2>;
+ };
+
vpumix_blk_ctrl: blk-ctrl@38330000 {
compatible = "fsl,imx8mp-vpu-blk-ctrl", "syscon";
reg = <0x38330000 0x100>;
@@ -1234,6 +1495,9 @@
<&clk IMX8MP_CLK_VPU_G2_ROOT>,
<&clk IMX8MP_CLK_VPU_VC8KE_ROOT>;
clock-names = "g1", "g2", "vc8000e";
+ assigned-clocks = <&clk IMX8MP_CLK_VPU_BUS>, <&clk IMX8MP_VPU_PLL>;
+ assigned-clock-parents = <&clk IMX8MP_VPU_PLL_OUT>;
+ assigned-clock-rates = <600000000>, <600000000>;
interconnects = <&noc IMX8MP_ICM_VPU_G1 &noc IMX8MP_ICN_VIDEO>,
<&noc IMX8MP_ICM_VPU_G2 &noc IMX8MP_ICN_VIDEO>,
<&noc IMX8MP_ICM_VPU_H1 &noc IMX8MP_ICN_VIDEO>;
@@ -1279,7 +1543,7 @@
reg = <0x32f10100 0x8>,
<0x381f0000 0x20>;
clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
- <&clk IMX8MP_CLK_USB_ROOT>;
+ <&clk IMX8MP_CLK_USB_SUSP>;
clock-names = "hsio", "suspend";
interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&hsio_blk_ctrl IMX8MP_HSIOBLK_PD_USB>;
@@ -1292,9 +1556,9 @@
usb_dwc3_0: usb@38100000 {
compatible = "snps,dwc3";
reg = <0x38100000 0x10000>;
- clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
+ clocks = <&clk IMX8MP_CLK_USB_ROOT>,
<&clk IMX8MP_CLK_USB_CORE_REF>,
- <&clk IMX8MP_CLK_USB_ROOT>;
+ <&clk IMX8MP_CLK_USB_SUSP>;
clock-names = "bus_early", "ref", "suspend";
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
phys = <&usb3_phy0>, <&usb3_phy0>;
@@ -1321,7 +1585,7 @@
reg = <0x32f10108 0x8>,
<0x382f0000 0x20>;
clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
- <&clk IMX8MP_CLK_USB_ROOT>;
+ <&clk IMX8MP_CLK_USB_SUSP>;
clock-names = "hsio", "suspend";
interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&hsio_blk_ctrl IMX8MP_HSIOBLK_PD_USB>;
@@ -1334,9 +1598,9 @@
usb_dwc3_1: usb@38200000 {
compatible = "snps,dwc3";
reg = <0x38200000 0x10000>;
- clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
+ clocks = <&clk IMX8MP_CLK_USB_ROOT>,
<&clk IMX8MP_CLK_USB_CORE_REF>,
- <&clk IMX8MP_CLK_USB_ROOT>;
+ <&clk IMX8MP_CLK_USB_SUSP>;
clock-names = "bus_early", "ref", "suspend";
interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
phys = <&usb3_phy1>, <&usb3_phy1>;
diff --git a/arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi b/arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi
index be2ad0cf6cd..e49e564b790 100644
--- a/arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi
+++ b/arch/arm/dts/nuvoton-npcm8xx-u-boot.dtsi
@@ -289,6 +289,23 @@
status = "disable";
};
+ aes: aes@f0858000 {
+ compatible = "nuvoton,npcm845-aes";
+ reg = <0x0 0xf0858000 0x0 0x1000>,
+ <0x0 0xf0851000 0x0 0x1000>;
+ status = "disabled";
+ clocks = <&clk NPCM8XX_CLK_AHB>;
+ clock-names = "clk_ahb";
+ };
+
+ sha:sha@f085a000 {
+ compatible = "nuvoton,npcm845-sha";
+ reg = <0x0 0xf085a000 0x0 0x1000>;
+ status = "disabled";
+ clocks = <&clk NPCM8XX_CLK_AHB>;
+ clock-names = "clk_ahb";
+ };
+
apb {
serial0: serial@0 {
compatible = "nuvoton,npcm845-uart";
@@ -417,22 +434,6 @@
status = "disabled";
};
- aes: aes@f0858000 {
- compatible = "nuvoton,npcm845-aes";
- reg = <0x0 0xf0858000 0x0 0x1000>,
- <0x0 0xf0851000 0x0 0x1000>;
- status = "disabled";
- clocks = <&clk NPCM8XX_CLK_AHB>;
- clock-names = "clk_ahb";
- };
-
- sha:sha@f085a000 {
- compatible = "nuvoton,npcm845-sha";
- reg = <0x0 0xf085a000 0x0 0x1000>;
- status = "disabled";
- clocks = <&clk NPCM8XX_CLK_AHB>;
- clock-names = "clk_ahb";
- };
};
};
pinctrl: pinctrl@f0800000 {
diff --git a/arch/arm/include/asm/arch-imx8m/imx-regs.h b/arch/arm/include/asm/arch-imx8m/imx-regs.h
index 6e2fc82a0e4..f1b7526ac77 100644
--- a/arch/arm/include/asm/arch-imx8m/imx-regs.h
+++ b/arch/arm/include/asm/arch-imx8m/imx-regs.h
@@ -13,7 +13,7 @@
#define ROM_VERSION_A0 IS_ENABLED(CONFIG_IMX8MQ) ? 0x800 : 0x800
#define ROM_VERSION_B0 IS_ENABLED(CONFIG_IMX8MQ) ? 0x83C : 0x800
-#define M4_BOOTROM_BASE_ADDR 0x007E0000
+#define MCU_BOOTROM_BASE_ADDR 0x007E0000
#define GPIO1_BASE_ADDR 0X30200000
#define GPIO2_BASE_ADDR 0x30210000
@@ -40,6 +40,7 @@
#define UART1_BASE_ADDR 0x30860000
#define UART3_BASE_ADDR 0x30880000
#define UART2_BASE_ADDR 0x30890000
+#define CAAM_BASE_ADDR 0x30900000
#define I2C1_BASE_ADDR 0x30A20000
#define I2C2_BASE_ADDR 0x30A30000
#define I2C3_BASE_ADDR 0x30A40000
diff --git a/arch/arm/include/asm/arch-imx9/ccm_regs.h b/arch/arm/include/asm/arch-imx9/ccm_regs.h
index d326a6ea516..f6ec8fda3e6 100644
--- a/arch/arm/include/asm/arch-imx9/ccm_regs.h
+++ b/arch/arm/include/asm/arch-imx9/ccm_regs.h
@@ -12,7 +12,7 @@
#define ARM_A55_MTR_BUS_CLK_ROOT 1
#define ARM_A55_CLK_ROOT 2
#define M33_CLK_ROOT 3
-#define SENTINEL_CLK_ROOT 4
+#define ELE_CLK_ROOT 4
#define BUS_WAKEUP_CLK_ROOT 5
#define BUS_AON_CLK_ROOT 6
#define WAKEUP_AXI_CLK_ROOT 7
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
index 72944af18a4..8fd3dd2df3a 100644
--- a/arch/arm/include/asm/arch-mx6/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
@@ -23,7 +23,7 @@
#define GPU_ARB_END_ADDR 0x01803FFF
#define APBH_DMA_ARB_BASE_ADDR 0x01804000
#define APBH_DMA_ARB_END_ADDR 0x0180BFFF
-#define M4_BOOTROM_BASE_ADDR 0x007F8000
+#define MCU_BOOTROM_BASE_ADDR 0x007F8000
#elif !defined(CONFIG_MX6SLL)
#define CAAM_ARB_BASE_ADDR 0x00100000
diff --git a/arch/arm/include/asm/arch-mx7/imx-regs.h b/arch/arm/include/asm/arch-mx7/imx-regs.h
index c863cd9da36..6f5ae5173c0 100644
--- a/arch/arm/include/asm/arch-mx7/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx7/imx-regs.h
@@ -18,7 +18,7 @@
#define GIC400_ARB_END_ADDR 0x31007FFF
#define APBH_DMA_ARB_BASE_ADDR 0x33000000
#define APBH_DMA_ARB_END_ADDR 0x33007FFF
-#define M4_BOOTROM_BASE_ADDR 0x00180000
+#define MCU_BOOTROM_BASE_ADDR 0x00180000
#define MXS_APBH_BASE APBH_DMA_ARB_BASE_ADDR
#define MXS_GPMI_BASE (APBH_DMA_ARB_BASE_ADDR + 0x02000)
diff --git a/arch/arm/include/asm/arch-npcm8xx/gcr.h b/arch/arm/include/asm/arch-npcm8xx/gcr.h
index ee6677a0e54..20230d64e6b 100644
--- a/arch/arm/include/asm/arch-npcm8xx/gcr.h
+++ b/arch/arm/include/asm/arch-npcm8xx/gcr.h
@@ -12,6 +12,7 @@
/* On-Chip ARBEL NPCM8XX VERSIONS */
#define ARBEL_Z1 0x00A35850
#define ARBEL_A1 0x04a35850
+#define ARBEL_A2 0x08a35850
#define ARBEL_NPCM845 0x00000000
#define ARBEL_NPCM830 0x00300395
#define ARBEL_NPCM810 0x00000220
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index 0c130757110..2a222c53882 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -92,8 +92,8 @@ struct arch_global_data {
struct udevice *scu_dev;
#endif
-#ifdef CONFIG_IMX_SENTINEL
- struct udevice *s400_dev;
+#ifdef CONFIG_IMX_ELE
+ struct udevice *ele_dev;
u32 soc_rev;
u32 lifecycle;
u32 uid[4];
diff --git a/arch/arm/include/asm/mach-imx/ahab.h b/arch/arm/include/asm/mach-imx/ahab.h
new file mode 100644
index 00000000000..4222e3db278
--- /dev/null
+++ b/arch/arm/include/asm/mach-imx/ahab.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2020 NXP
+ */
+
+#ifndef __IMX_AHAB_H__
+#define __IMX_AHAB_H__
+
+#include <asm/mach-imx/image.h>
+
+int ahab_auth_cntr_hdr(struct container_hdr *container, u16 length);
+int ahab_auth_release(void);
+int ahab_verify_cntr_image(struct boot_img_t *img, int image_index);
+
+#endif
diff --git a/arch/arm/include/asm/mach-imx/s400_api.h b/arch/arm/include/asm/mach-imx/ele_api.h
index 5582ff1a254..cfd4ecebb62 100644
--- a/arch/arm/include/asm/mach-imx/s400_api.h
+++ b/arch/arm/include/asm/mach-imx/ele_api.h
@@ -3,12 +3,12 @@
* Copyright 2021 NXP
*/
-#ifndef __S400_API_H__
-#define __S400_API_H__
+#ifndef __ELE_API_H__
+#define __ELE_API_H__
-#define AHAB_VERSION 0x6
-#define AHAB_CMD_TAG 0x17
-#define AHAB_RESP_TAG 0xe1
+#define ELE_VERSION 0x6
+#define ELE_CMD_TAG 0x17
+#define ELE_RESP_TAG 0xe1
/* ELE commands */
#define ELE_PING_REQ (0x01)
@@ -24,6 +24,8 @@
#define ELE_GET_FW_VERSION_REQ (0x9D)
#define ELE_RET_LIFECYCLE_UP_REQ (0xA0)
#define ELE_GET_EVENTS_REQ (0xA2)
+#define ELE_START_RNG (0xA3)
+#define ELE_GENERATE_DEK_BLOB (0xAF)
#define ELE_ENABLE_PATCH_REQ (0xC3)
#define ELE_RELEASE_RDC_REQ (0xC4)
#define ELE_GET_FW_STATUS_REQ (0xC5)
@@ -109,17 +111,17 @@
#define ELE_SUCCESS_IND (0xD6)
#define ELE_FAILURE_IND (0x29)
-#define S400_MAX_MSG 255U
+#define ELE_MAX_MSG 255U
-struct sentinel_msg {
+struct ele_msg {
u8 version;
u8 size;
u8 command;
u8 tag;
- u32 data[(S400_MAX_MSG - 1U)];
+ u32 data[(ELE_MAX_MSG - 1U)];
};
-struct sentinel_get_info_data {
+struct ele_get_info_data {
u32 hdr;
u32 soc;
u32 lc;
@@ -130,19 +132,22 @@ struct sentinel_get_info_data {
u32 state;
};
-int ahab_release_rdc(u8 core_id, u8 xrdc, u32 *response);
-int ahab_auth_oem_ctnr(ulong ctnr_addr, u32 *response);
-int ahab_release_container(u32 *response);
-int ahab_verify_image(u32 img_id, u32 *response);
-int ahab_forward_lifecycle(u16 life_cycle, u32 *response);
-int ahab_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response);
-int ahab_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response);
-int ahab_release_caam(u32 core_did, u32 *response);
-int ahab_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response);
-int ahab_dump_buffer(u32 *buffer, u32 buffer_length);
-int ahab_get_info(struct sentinel_get_info_data *info, u32 *response);
-int ahab_get_fw_status(u32 *status, u32 *response);
-int ahab_release_m33_trout(void);
-int ahab_get_events(u32 *events, u32 *events_cnt, u32 *response);
-
+int ele_release_rdc(u8 core_id, u8 xrdc, u32 *response);
+int ele_auth_oem_ctnr(ulong ctnr_addr, u32 *response);
+int ele_release_container(u32 *response);
+int ele_verify_image(u32 img_id, u32 *response);
+int ele_forward_lifecycle(u16 life_cycle, u32 *response);
+int ele_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response);
+int ele_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response);
+int ele_release_caam(u32 core_did, u32 *response);
+int ele_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response);
+int ele_get_events(u32 *events, u32 *events_cnt, u32 *response);
+int ele_generate_dek_blob(u32 key_id, u32 src_paddr, u32 dst_paddr, u32 max_output_size);
+int ele_dump_buffer(u32 *buffer, u32 buffer_length);
+int ele_get_info(struct ele_get_info_data *info, u32 *response);
+int ele_get_fw_status(u32 *status, u32 *response);
+int ele_release_m33_trout(void);
+int ele_write_secure_fuse(ulong signed_msg_blk, u32 *response);
+int ele_return_lifecycle_update(ulong signed_msg_blk, u32 *response);
+int ele_start_rng(void);
#endif
diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h
index 85d9ca60b14..31ae179b211 100644
--- a/arch/arm/include/asm/mach-imx/sys_proto.h
+++ b/arch/arm/include/asm/mach-imx/sys_proto.h
@@ -236,6 +236,7 @@ void board_mem_get_layout(u64 *phys_sdram_1_start,
u64 *phys_sdram_2_start,
u64 *phys_sdram_2_size);
+int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data);
int arch_auxiliary_core_check_up(u32 core_id);
int board_mmc_get_env_dev(int devno);
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 3266545c266..d94b5828d0d 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -31,7 +31,7 @@ config IMX_RDC
config IMX_BOOTAUX
bool "Support boot auxiliary core"
- depends on ARCH_MX7 || ARCH_MX6 || ARCH_VF610 || ARCH_IMX8M
+ depends on ARCH_MX7 || ARCH_MX6 || ARCH_VF610 || ARCH_IMX8 || ARCH_IMX8M
help
bootaux [addr] to boot auxiliary core.
@@ -86,6 +86,7 @@ config CMD_DEKBLOB
select IMX_CAAM_DEK_ENCAP if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP
select IMX_OPTEE_DEK_ENCAP if ARCH_IMX8M
select IMX_SECO_DEK_ENCAP if ARCH_IMX8
+ select IMX_ELE_DEK_ENCAP if ARCH_IMX8ULP || ARCH_IMX9
help
This enables the 'dek_blob' command which is used with the
Freescale secure boot mechanism. This command encapsulates and
@@ -113,6 +114,12 @@ config IMX_SECO_DEK_ENCAP
This enabled the DEK blob encapsulation with the SECO API. This option
is only available on imx8.
+config IMX_ELE_DEK_ENCAP
+ bool "Support the DEK blob encapsulation with ELE"
+ help
+ This enabled the DEK blob encapsulation with the ELE API. This option
+ is only available on imx8ulp and imx9.
+
config CMD_PRIBLOB
bool "Support the set_priblob_bitfield command"
depends on HAS_CAAM && IMX_HAB
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 00d6ad85c56..aebfa6517bd 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -66,6 +66,11 @@ ifeq ($(SOC),$(filter $(SOC),vf610))
obj-y += ddrmc-vf610.o
obj-$(CONFIG_DDRMC_VF610_CALIBRATION) += ddrmc-vf610-calibration.o
endif
+ifeq ($(SOC),$(filter $(SOC),imx8))
+ifneq ($(CONFIG_SPL_BUILD),y)
+obj-$(CONFIG_IMX_BOOTAUX) += imx_bootaux.o
+endif
+endif
ifneq ($(CONFIG_SPL_BUILD),y)
obj-$(CONFIG_CMD_BMODE) += cmd_bmode.o
obj-$(CONFIG_CMD_HDMIDETECT) += cmd_hdmidet.o
diff --git a/arch/arm/mach-imx/cmd_dek.c b/arch/arm/mach-imx/cmd_dek.c
index 69ed57537b3..6fa5b41fcd3 100644
--- a/arch/arm/mach-imx/cmd_dek.c
+++ b/arch/arm/mach-imx/cmd_dek.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2008-2015 Freescale Semiconductor, Inc.
+ * Copyright 2022 NXP
*
* Command for encapsulating DEK blob
*/
@@ -20,6 +21,11 @@
#include <firmware/imx/sci/sci.h>
#include <asm/mach-imx/image.h>
#endif
+#ifdef CONFIG_IMX_ELE_DEK_ENCAP
+#include <asm/mach-imx/ele_api.h>
+#include <asm/mach-imx/image.h>
+#endif
+
#include <cpu_func.h>
/**
@@ -101,6 +107,7 @@ static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len)
0x0, &shm_output);
if (ret < 0) {
printf("Cannot register output shared memory 0x%X\n", ret);
+ tee_shm_free(shm_input);
goto error;
}
@@ -122,11 +129,11 @@ static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len)
if (ret < 0)
printf("Cannot generate Blob with PTA DEK Blob 0x%X\n", ret);
-error:
/* Free shared memory */
tee_shm_free(shm_input);
tee_shm_free(shm_output);
+error:
/* Close session */
ret = tee_close_session(dev, arg.session);
if (ret < 0)
@@ -154,7 +161,7 @@ error:
static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len)
{
- sc_err_t err;
+ int err;
sc_rm_mr_t mr_input, mr_output;
struct generate_key_blob_hdr hdr;
u8 in_size, out_size;
@@ -283,6 +290,84 @@ error:
}
#endif /* CONFIG_IMX_SECO_DEK_ENCAP */
+#ifdef CONFIG_IMX_ELE_DEK_ENCAP
+
+#define DEK_BLOB_HDR_SIZE 8
+#define AHAB_PRIVATE_KEY 0x81
+#define AHAB_DEK_BLOB 0x01
+#define AHAB_ALG_AES 0x03
+#define AHAB_128_AES_KEY 0x10
+#define AHAB_192_AES_KEY 0x18
+#define AHAB_256_AES_KEY 0x20
+
+static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len)
+{
+ u8 in_size, out_size;
+ u8 *src_ptr, *dst_ptr;
+ struct generate_key_blob_hdr hdr;
+
+ /* Set sizes */
+ in_size = sizeof(struct generate_key_blob_hdr) + len / 8;
+ out_size = BLOB_SIZE(len / 8) + DEK_BLOB_HDR_SIZE;
+
+ /* Get src and dst virtual addresses */
+ src_ptr = map_sysmem(src_addr, in_size);
+ dst_ptr = map_sysmem(dst_addr, out_size);
+
+ /* Check addr input */
+ if (!(src_ptr && dst_ptr)) {
+ debug("src_addr or dst_addr invalid\n");
+ return -1;
+ }
+
+ /* Build key header */
+ hdr.version = 0x0;
+ hdr.length_lsb = in_size;
+ hdr.length_msb = 0x00;
+ hdr.tag = AHAB_PRIVATE_KEY;
+ hdr.flags = AHAB_DEK_BLOB;
+ hdr.algorithm = AHAB_ALG_AES;
+ hdr.mode = 0x0; /* Not used by the ELE */
+
+ switch (len) {
+ case 128:
+ hdr.size = AHAB_128_AES_KEY;
+ break;
+ case 192:
+ hdr.size = AHAB_192_AES_KEY;
+ break;
+ case 256:
+ hdr.size = AHAB_256_AES_KEY;
+ break;
+ default:
+ /* Not supported */
+ debug("Invalid DEK size. Valid sizes are 128, 192 and 256b\n");
+ return -1;
+ }
+
+ /* Move input key and append blob header */
+ memmove((void *)(src_ptr + sizeof(struct generate_key_blob_hdr)),
+ (void *)src_ptr, len / 8);
+ memcpy((void *)src_ptr, (void *)&hdr,
+ sizeof(struct generate_key_blob_hdr));
+
+ /* Flush the cache */
+ flush_dcache_range(src_addr, src_addr + in_size);
+ flush_dcache_range((ulong)dst_ptr, (ulong)(dst_ptr +
+ roundup(out_size, ARCH_DMA_MINALIGN)));
+
+ /* Call ELE */
+ if (ele_generate_dek_blob(0x00, src_addr, dst_addr, out_size))
+ return -1;
+
+ /* Invalidate output buffer */
+ invalidate_dcache_range((ulong)dst_ptr, (ulong)(dst_ptr +
+ roundup(out_size, ARCH_DMA_MINALIGN)));
+
+ return 0;
+}
+#endif /* CONFIG_IMX_ELE_DEK_ENCAP */
+
/**
* do_dek_blob() - Handle the "dek_blob" command-line command
* @cmdtp: Command data struct pointer
diff --git a/arch/arm/mach-imx/ele_ahab.c b/arch/arm/mach-imx/ele_ahab.c
index 99fc5402719..785b0d6ec3c 100644
--- a/arch/arm/mach-imx/ele_ahab.c
+++ b/arch/arm/mach-imx/ele_ahab.c
@@ -7,14 +7,13 @@
#include <command.h>
#include <errno.h>
#include <asm/io.h>
-#include <asm/mach-imx/s400_api.h>
+#include <asm/mach-imx/ele_api.h>
#include <asm/mach-imx/sys_proto.h>
#include <asm/arch-imx/cpu.h>
#include <asm/arch/sys_proto.h>
#include <asm/mach-imx/image.h>
#include <console.h>
#include <cpu_func.h>
-#include <asm/mach-imx/ahab.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -267,7 +266,7 @@ int ahab_auth_cntr_hdr(struct container_hdr *container, u16 length)
flush_dcache_range(IMG_CONTAINER_BASE,
IMG_CONTAINER_BASE + ALIGN(length, CONFIG_SYS_CACHELINE_SIZE) - 1);
- err = ahab_auth_oem_ctnr(IMG_CONTAINER_BASE, &resp);
+ err = ele_auth_oem_ctnr(IMG_CONTAINER_BASE, &resp);
if (err) {
printf("Authenticate container hdr failed, return %d, resp 0x%x\n",
err, resp);
@@ -282,7 +281,7 @@ int ahab_auth_release(void)
int err;
u32 resp;
- err = ahab_release_container(&resp);
+ err = ele_release_container(&resp);
if (err) {
printf("Error: release container failed, resp 0x%x!\n", resp);
display_ahab_auth_ind(resp);
@@ -296,7 +295,7 @@ int ahab_verify_cntr_image(struct boot_img_t *img, int image_index)
int err;
u32 resp;
- err = ahab_verify_image(image_index, &resp);
+ err = ele_verify_image(image_index, &resp);
if (err) {
printf("Authenticate img %d failed, return %d, resp 0x%x\n",
image_index, err, resp);
@@ -403,7 +402,7 @@ static int do_authenticate(struct cmd_tbl *cmdtp, int flag, int argc,
if (argc < 2)
return CMD_RET_USAGE;
- addr = simple_strtoul(argv[1], NULL, 16);
+ addr = hextoul(argv[1], NULL);
printf("Authenticate OS container at 0x%lx\n", addr);
@@ -485,7 +484,7 @@ static int do_ahab_close(struct cmd_tbl *cmdtp, int flag, int argc,
return -EPERM;
}
- err = ahab_forward_lifecycle(8, &resp);
+ err = ele_forward_lifecycle(8, &resp);
if (err != 0) {
printf("Error in forward lifecycle to OEM closed\n");
return -EIO;
@@ -502,7 +501,7 @@ int ahab_dump(void)
int ret, i = 0;
do {
- ret = ahab_dump_buffer(buffer, 32);
+ ret = ele_dump_buffer(buffer, 32);
if (ret < 0) {
printf("Error in dump AHAB log\n");
return -EIO;
@@ -547,7 +546,7 @@ static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc, char *const
display_life_cycle(lc);
- ret = ahab_get_events(events, &cnt, NULL);
+ ret = ele_get_events(events, &cnt, NULL);
if (ret) {
printf("Get ELE EVENTS error %d\n", ret);
return CMD_RET_FAILURE;
@@ -564,6 +563,68 @@ static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc, char *const
return 0;
}
+static int do_sec_fuse_prog(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ ulong addr;
+ u32 header, response;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ addr = hextoul(argv[1], NULL);
+ header = *(u32 *)addr;
+
+ if ((header & 0xff0000ff) != 0x89000000) {
+ printf("Wrong Signed message block format, header 0x%x\n", header);
+ return CMD_RET_FAILURE;
+ }
+
+ header = (header & 0xffff00) >> 8;
+
+ printf("Signed Message block at 0x%lx, size 0x%x\n", addr, header);
+ flush_dcache_range(addr, addr + header - 1);
+
+ if (ele_write_secure_fuse(addr, &response)) {
+ printf("Program secure fuse failed, response 0x%x\n", response);
+ return CMD_RET_FAILURE;
+ }
+
+ printf("Program secure fuse completed, response 0x%x\n", response);
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_ahab_return_lifecycle(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ ulong addr;
+ u32 header, response;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ addr = hextoul(argv[1], NULL);
+ header = *(u32 *)addr;
+
+ if ((header & 0xff0000ff) != 0x89000000) {
+ printf("Wrong Signed message block format, header 0x%x\n", header);
+ return CMD_RET_FAILURE;
+ }
+
+ header = (header & 0xffff00) >> 8;
+
+ printf("Signed Message block at 0x%lx, size 0x%x\n", addr, header);
+ flush_dcache_range(addr, addr + header - 1);
+
+ if (ele_return_lifecycle_update(addr, &response)) {
+ printf("Return lifecycle failed, response 0x%x\n", response);
+ return CMD_RET_FAILURE;
+ }
+
+ printf("Return lifecycle completed, response 0x%x\n", response);
+
+ return CMD_RET_SUCCESS;
+}
+
U_BOOT_CMD(auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate,
"autenticate OS container via AHAB",
"addr\n"
@@ -584,3 +645,15 @@ U_BOOT_CMD(ahab_status, CONFIG_SYS_MAXARGS, 1, do_ahab_status,
"display AHAB lifecycle only",
""
);
+
+U_BOOT_CMD(ahab_sec_fuse_prog, CONFIG_SYS_MAXARGS, 1, do_sec_fuse_prog,
+ "Program secure fuse via signed message block",
+ "addr\n"
+ "addr - Signed message block for secure fuse\n"
+);
+
+U_BOOT_CMD(ahab_return_lifecycle, CONFIG_SYS_MAXARGS, 1, do_ahab_return_lifecycle,
+ "Return lifecycle to OEM field return via signed message block",
+ "addr\n"
+ "addr - Return lifecycle message block signed by OEM SRK\n"
+);
diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index 439cdaf07a7..b3ef36c7973 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -289,9 +289,10 @@ static char *rsn_str[] = {
};
static char *sts_str[] = {
- "STS = HAB_SUCCESS (0xF0)\n",
+ "STS = HAB_STS_ANY (0x00)\n",
"STS = HAB_FAILURE (0x33)\n",
"STS = HAB_WARNING (0x69)\n",
+ "STS = HAB_SUCCESS (0xF0)\n",
"STS = INVALID\n",
NULL
};
@@ -336,8 +337,7 @@ static uint8_t hab_statuses[5] = {
HAB_STS_ANY,
HAB_FAILURE,
HAB_WARNING,
- HAB_SUCCESS,
- -1
+ HAB_SUCCESS
};
static uint8_t hab_reasons[26] = {
@@ -365,8 +365,7 @@ static uint8_t hab_reasons[26] = {
HAB_UNS_ITEM,
HAB_UNS_KEY,
HAB_UNS_PROTOCOL,
- HAB_UNS_STATE,
- -1
+ HAB_UNS_STATE
};
static uint8_t hab_contexts[12] = {
@@ -380,8 +379,7 @@ static uint8_t hab_contexts[12] = {
HAB_CTX_COMMAND,
HAB_CTX_AUT_DAT,
HAB_CTX_ASSERT,
- HAB_CTX_EXIT,
- -1
+ HAB_CTX_EXIT
};
static uint8_t hab_engines[16] = {
@@ -399,30 +397,35 @@ static uint8_t hab_engines[16] = {
HAB_ENG_ROM,
HAB_ENG_HDCP,
HAB_ENG_RTL,
- HAB_ENG_SW,
- -1
+ HAB_ENG_SW
};
-static inline uint8_t get_idx(uint8_t *list, uint8_t tgt)
+static inline u32 get_idx(u8 *list, u8 tgt, u32 size)
{
- uint8_t idx = 0;
- uint8_t element = list[idx];
- while (element != -1) {
+ u32 idx = 0;
+ u8 element;
+
+ while (idx < size) {
+ element = list[idx];
if (element == tgt)
return idx;
- element = list[++idx];
+ ++idx;
}
- return -1;
+ return idx;
}
static void process_event_record(uint8_t *event_data, size_t bytes)
{
struct record *rec = (struct record *)event_data;
- printf("\n\n%s", sts_str[get_idx(hab_statuses, rec->contents[0])]);
- printf("%s", rsn_str[get_idx(hab_reasons, rec->contents[1])]);
- printf("%s", ctx_str[get_idx(hab_contexts, rec->contents[2])]);
- printf("%s", eng_str[get_idx(hab_engines, rec->contents[3])]);
+ printf("\n\n%s", sts_str[get_idx(hab_statuses, rec->contents[0],
+ ARRAY_SIZE(hab_statuses))]);
+ printf("%s", rsn_str[get_idx(hab_reasons, rec->contents[1],
+ ARRAY_SIZE(hab_reasons))]);
+ printf("%s", ctx_str[get_idx(hab_contexts, rec->contents[2],
+ ARRAY_SIZE(hab_contexts))]);
+ printf("%s", eng_str[get_idx(hab_engines, rec->contents[3],
+ ARRAY_SIZE(hab_engines))]);
}
static void display_event(uint8_t *event_data, size_t bytes)
diff --git a/arch/arm/mach-imx/image-container.c b/arch/arm/mach-imx/image-container.c
index 5b059a64292..5f188ab32d1 100644
--- a/arch/arm/mach-imx/image-container.c
+++ b/arch/arm/mach-imx/image-container.c
@@ -22,6 +22,25 @@
#define QSPI_NOR_DEV 3
#define ROM_API_DEV 4
+/* The unit of second image offset number which provision by the fuse bits */
+#define SND_IMG_OFF_UNIT (0x100000UL)
+
+/*
+ * If num = 0, off = (2 ^ 2) * 1MB
+ * else If num = 2, off = (2 ^ 0) * 1MB
+ * else off = (2 ^ num) * 1MB
+ */
+#define SND_IMG_NUM_TO_OFF(num) \
+ ((1UL << ((0 == (num)) ? 2 : (2 == (num)) ? 0 : (num))) * SND_IMG_OFF_UNIT)
+
+#define GET_SND_IMG_NUM(fuse) (((fuse) >> 24) & 0x1F)
+
+#if defined(CONFIG_IMX8QM)
+#define FUSE_IMG_SET_OFF_WORD 464
+#elif defined(CONFIG_IMX8QXP)
+#define FUSE_IMG_SET_OFF_WORD 720
+#endif
+
int get_container_size(ulong addr, u16 *header_length)
{
struct container_hdr *phdr;
@@ -31,7 +50,7 @@ int get_container_size(ulong addr, u16 *header_length)
u32 max_offset = 0, img_end;
phdr = (struct container_hdr *)addr;
- if (phdr->tag != 0x87 && phdr->version != 0x0) {
+ if (phdr->tag != 0x87 || phdr->version != 0x0) {
debug("Wrong container header\n");
return -EFAULT;
}
@@ -136,15 +155,53 @@ static int get_dev_container_size(void *dev, int dev_type, unsigned long offset,
return ret;
}
+static bool check_secondary_cnt_set(unsigned long *set_off)
+{
+#if IS_ENABLED(CONFIG_ARCH_IMX8)
+ int ret;
+ u8 set_id = 1;
+ u32 fuse_val = 0;
+
+ if (!(is_imx8qxp() && is_soc_rev(CHIP_REV_B))) {
+ ret = sc_misc_get_boot_container(-1, &set_id);
+ if (ret)
+ return false;
+ /* Secondary boot */
+ if (set_id == 2) {
+ ret = sc_misc_otp_fuse_read(-1, FUSE_IMG_SET_OFF_WORD, &fuse_val);
+ if (!ret) {
+ if (set_off)
+ *set_off = SND_IMG_NUM_TO_OFF(GET_SND_IMG_NUM(fuse_val));
+ return true;
+ }
+ }
+ }
+#endif
+
+ return false;
+}
+
static unsigned long get_boot_device_offset(void *dev, int dev_type)
{
- unsigned long offset = 0;
+ unsigned long offset = 0, sec_set_off = 0;
+ bool sec_boot = false;
+
+ if (dev_type == ROM_API_DEV) {
+ offset = (unsigned long)dev;
+ return offset;
+ }
+
+ sec_boot = check_secondary_cnt_set(&sec_set_off);
+ if (sec_boot)
+ printf("Secondary set selected\n");
+ else
+ printf("Primary set selected\n");
if (dev_type == MMC_DEV) {
struct mmc *mmc = (struct mmc *)dev;
if (IS_SD(mmc) || mmc->part_config == MMCPART_NOAVAILABLE) {
- offset = CONTAINER_HDR_MMCSD_OFFSET;
+ offset = sec_boot ? sec_set_off : CONTAINER_HDR_MMCSD_OFFSET;
} else {
u8 part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
@@ -154,19 +211,23 @@ static unsigned long get_boot_device_offset(void *dev, int dev_type)
else
offset = CONTAINER_HDR_EMMC_OFFSET;
} else {
- offset = CONTAINER_HDR_MMCSD_OFFSET;
+ offset = sec_boot ? sec_set_off : CONTAINER_HDR_MMCSD_OFFSET;
}
}
} else if (dev_type == QSPI_DEV) {
- offset = CONTAINER_HDR_QSPI_OFFSET;
+ offset = sec_boot ? (sec_set_off + CONTAINER_HDR_QSPI_OFFSET) :
+ CONTAINER_HDR_QSPI_OFFSET;
} else if (dev_type == NAND_DEV) {
- offset = CONTAINER_HDR_NAND_OFFSET;
+ offset = sec_boot ? (sec_set_off + CONTAINER_HDR_NAND_OFFSET) :
+ CONTAINER_HDR_NAND_OFFSET;
} else if (dev_type == QSPI_NOR_DEV) {
offset = CONTAINER_HDR_QSPI_OFFSET + 0x08000000;
- } else if (dev_type == ROM_API_DEV) {
- offset = (unsigned long)dev;
+ } else {
+ printf("Not supported dev_type: %d\n", dev_type);
}
+ debug("container set offset 0x%lx\n", offset);
+
return offset;
}
@@ -227,6 +288,25 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
return end / mmc->read_bl_len;
}
+
+int spl_mmc_emmc_boot_partition(struct mmc *mmc)
+{
+ int part;
+
+ part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
+ if (part == 1 || part == 2) {
+ unsigned long sec_set_off = 0;
+ bool sec_boot = false;
+
+ sec_boot = check_secondary_cnt_set(&sec_set_off);
+ if (sec_boot)
+ part = (part == 1) ? 2 : 1;
+ } else if (part == 7) {
+ part = 0;
+ }
+
+ return part;
+}
#endif
#ifdef CONFIG_SPL_NAND_SUPPORT
diff --git a/arch/arm/mach-imx/imx8/ahab.c b/arch/arm/mach-imx/imx8/ahab.c
index 9addb824b6d..b58b14ca9b4 100644
--- a/arch/arm/mach-imx/imx8/ahab.c
+++ b/arch/arm/mach-imx/imx8/ahab.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2018-2019 NXP
+ * Copyright 2018-2019, 2022 NXP
*/
#include <common.h>
@@ -16,6 +16,8 @@
#include <asm/mach-imx/image.h>
#include <console.h>
#include <cpu_func.h>
+#include "u-boot/sha256.h"
+#include <asm/mach-imx/ahab.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -24,6 +26,86 @@ DECLARE_GLOBAL_DATA_PTR;
#define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE (0x60000000UL)
#define SECO_PT 2U
+#define AHAB_HASH_TYPE_MASK 0x00000700
+#define AHAB_HASH_TYPE_SHA256 0
+
+int ahab_auth_cntr_hdr(struct container_hdr *container, u16 length)
+{
+ int err;
+
+ memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)container,
+ ALIGN(length, CONFIG_SYS_CACHELINE_SIZE));
+
+ err = sc_seco_authenticate(-1, SC_SECO_AUTH_CONTAINER,
+ SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE);
+ if (err)
+ printf("Authenticate container hdr failed, return %d\n", err);
+
+ return err;
+}
+
+int ahab_auth_release(void)
+{
+ int err;
+
+ err = sc_seco_authenticate(-1, SC_SECO_REL_CONTAINER, 0);
+ if (err)
+ printf("Error: release container failed!\n");
+
+ return err;
+}
+
+int ahab_verify_cntr_image(struct boot_img_t *img, int image_index)
+{
+ sc_faddr_t start, end;
+ sc_rm_mr_t mr;
+ int err;
+ int ret = 0;
+
+ debug("img %d, dst 0x%llx, src 0x%x, size 0x%x\n",
+ image_index, img->dst, img->offset, img->size);
+
+ /* Find the memreg and set permission for seco pt */
+ err = sc_rm_find_memreg(-1, &mr,
+ img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1),
+ ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1);
+
+ if (err) {
+ printf("Error: can't find memreg for image load address 0x%llx, error %d\n",
+ img->dst, err);
+ return -ENOMEM;
+ }
+
+ err = sc_rm_get_memreg_info(-1, mr, &start, &end);
+ if (!err)
+ debug("memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
+
+ err = sc_rm_set_memreg_permissions(-1, mr,
+ SECO_PT, SC_RM_PERM_FULL);
+ if (err) {
+ printf("Set permission failed for img %d, error %d\n",
+ image_index, err);
+ return -EPERM;
+ }
+
+ err = sc_seco_authenticate(-1, SC_SECO_VERIFY_IMAGE,
+ 1 << image_index);
+ if (err) {
+ printf("Authenticate img %d failed, return %d\n",
+ image_index, err);
+ ret = -EIO;
+ }
+
+ err = sc_rm_set_memreg_permissions(-1, mr,
+ SECO_PT, SC_RM_PERM_NONE);
+ if (err) {
+ printf("Remove permission failed for img %d, error %d\n",
+ image_index, err);
+ ret = -EPERM;
+ }
+
+ return ret;
+}
static inline bool check_in_dram(ulong addr)
{
@@ -46,11 +128,12 @@ int authenticate_os_container(ulong addr)
struct container_hdr *phdr;
int i, ret = 0;
int err;
- sc_rm_mr_t mr;
- sc_faddr_t start, end;
u16 length;
struct boot_img_t *img;
unsigned long s, e;
+#ifdef CONFIG_ARMV8_CE_SHA256
+ u8 hash_value[SHA256_SUM_LEN];
+#endif
if (addr % 4) {
puts("Error: Image's address is not 4 byte aligned\n");
@@ -76,14 +159,9 @@ int authenticate_os_container(ulong addr)
length = phdr->length_lsb + (phdr->length_msb << 8);
debug("container length %u\n", length);
- memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)addr,
- ALIGN(length, CONFIG_SYS_CACHELINE_SIZE));
- err = sc_seco_authenticate(-1, SC_SECO_AUTH_CONTAINER,
- SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE);
+ err = ahab_auth_cntr_hdr(phdr, length);
if (err) {
- printf("Authenticate container hdr failed, return %d\n",
- err);
ret = -EIO;
goto exit;
}
@@ -105,50 +183,27 @@ int authenticate_os_container(ulong addr)
flush_dcache_range(s, e);
- /* Find the memreg and set permission for seco pt */
- err = sc_rm_find_memreg(-1, &mr, s, e);
- if (err) {
- printf("Error: can't find memreg for image load address 0x%llx, error %d\n", img->dst, err);
- ret = -ENOMEM;
- goto exit;
- }
-
- err = sc_rm_get_memreg_info(-1, mr, &start, &end);
- if (!err)
- debug("memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
-
- err = sc_rm_set_memreg_permissions(-1, mr, SECO_PT,
- SC_RM_PERM_FULL);
- if (err) {
- printf("Set permission failed for img %d, error %d\n",
- i, err);
- ret = -EPERM;
- goto exit;
- }
-
- err = sc_seco_authenticate(-1, SC_SECO_VERIFY_IMAGE,
- (1 << i));
- if (err) {
- printf("Authenticate img %d failed, return %d\n",
- i, err);
- ret = -EIO;
+#ifdef CONFIG_ARMV8_CE_SHA256
+ if (((img->hab_flags & AHAB_HASH_TYPE_MASK) >> 8) == AHAB_HASH_TYPE_SHA256) {
+ sha256_csum_wd((void *)img->dst, img->size, hash_value, CHUNKSZ_SHA256);
+ err = memcmp(&img->hash, &hash_value, SHA256_SUM_LEN);
+ if (err) {
+ printf("img %d hash comparison failed, error %d\n", i, err);
+ ret = -EIO;
+ goto exit;
+ }
+ } else {
+#endif
+ ret = ahab_verify_cntr_image(img, i);
+ if (ret)
+ goto exit;
+#ifdef CONFIG_ARMV8_CE_SHA256
}
-
- err = sc_rm_set_memreg_permissions(-1, mr, SECO_PT,
- SC_RM_PERM_NONE);
- if (err) {
- printf("Remove permission failed for img %d, err %d\n",
- i, err);
- ret = -EPERM;
- }
-
- if (ret)
- goto exit;
+#endif
}
exit:
- if (sc_seco_authenticate(-1, SC_SECO_REL_CONTAINER, 0) != SC_ERR_NONE)
- printf("Error: release container failed!\n");
+ ahab_auth_release();
return ret;
}
@@ -263,7 +318,7 @@ static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc,
u16 lc;
err = sc_seco_chip_info(-1, &lc, NULL, NULL, NULL);
- if (err != SC_ERR_NONE) {
+ if (err) {
printf("Error in get lifecycle\n");
return -EIO;
}
@@ -271,7 +326,7 @@ static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc,
display_life_cycle(lc);
err = sc_seco_get_event(-1, idx, &event);
- while (err == SC_ERR_NONE) {
+ while (!err) {
printf("SECO Event[%u] = 0x%08X\n", idx, event);
display_ahab_auth_event(event);
@@ -312,7 +367,7 @@ static int do_ahab_close(struct cmd_tbl *cmdtp, int flag, int argc,
return -EACCES;
err = sc_seco_chip_info(-1, &lc, NULL, NULL, NULL);
- if (err != SC_ERR_NONE) {
+ if (err) {
printf("Error in get lifecycle\n");
return -EIO;
}
@@ -324,7 +379,7 @@ static int do_ahab_close(struct cmd_tbl *cmdtp, int flag, int argc,
}
err = sc_seco_forward_lifecycle(-1, 16);
- if (err != SC_ERR_NONE) {
+ if (err) {
printf("Error in forward lifecycle to OEM closed\n");
return -EIO;
}
diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c
index 7b292c07ef9..c62357044e0 100644
--- a/arch/arm/mach-imx/imx8/cpu.c
+++ b/arch/arm/mach-imx/imx8/cpu.c
@@ -26,6 +26,8 @@
#include <asm/armv8/mmu.h>
#include <asm/setup.h>
#include <asm/mach-imx/boot_mode.h>
+#include <power-domain.h>
+#include <elf.h>
#include <spl.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -107,6 +109,178 @@ int arch_misc_init(void)
}
#endif
+#ifdef CONFIG_IMX_BOOTAUX
+
+#ifdef CONFIG_IMX8QM
+int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data)
+{
+ sc_rsrc_t core_rsrc, mu_rsrc;
+ sc_faddr_t tcml_addr;
+ u32 tcml_size = SZ_128K;
+ ulong addr;
+
+ switch (core_id) {
+ case 0:
+ core_rsrc = SC_R_M4_0_PID0;
+ tcml_addr = 0x34FE0000;
+ mu_rsrc = SC_R_M4_0_MU_1A;
+ break;
+ case 1:
+ core_rsrc = SC_R_M4_1_PID0;
+ tcml_addr = 0x38FE0000;
+ mu_rsrc = SC_R_M4_1_MU_1A;
+ break;
+ default:
+ printf("Not support this core boot up, ID:%u\n", core_id);
+ return -EINVAL;
+ }
+
+ addr = (sc_faddr_t)boot_private_data;
+
+ if (addr >= tcml_addr && addr <= tcml_addr + tcml_size) {
+ printf("Wrong image address 0x%lx, should not in TCML\n",
+ addr);
+ return -EINVAL;
+ }
+
+ printf("Power on M4 and MU\n");
+
+ if (sc_pm_set_resource_power_mode(-1, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+ return -EIO;
+
+ if (sc_pm_set_resource_power_mode(-1, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+ return -EIO;
+
+ printf("Copy M4 image from 0x%lx to TCML 0x%lx\n", addr, (ulong)tcml_addr);
+
+ if (addr != tcml_addr)
+ memcpy((void *)tcml_addr, (void *)addr, tcml_size);
+
+ printf("Start M4 %u\n", core_id);
+ if (sc_pm_cpu_start(-1, core_rsrc, true, tcml_addr) != SC_ERR_NONE)
+ return -EIO;
+
+ printf("bootaux complete\n");
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_IMX8QXP
+int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data)
+{
+ sc_rsrc_t core_rsrc, mu_rsrc = SC_R_NONE;
+ sc_faddr_t aux_core_ram;
+ u32 size;
+ ulong addr;
+
+ switch (core_id) {
+ case 0:
+ core_rsrc = SC_R_M4_0_PID0;
+ aux_core_ram = 0x34FE0000;
+ mu_rsrc = SC_R_M4_0_MU_1A;
+ size = SZ_128K;
+ break;
+ case 1:
+ core_rsrc = SC_R_DSP;
+ aux_core_ram = 0x596f8000;
+ size = SZ_2K;
+ break;
+ default:
+ printf("Not support this core boot up, ID:%u\n", core_id);
+ return -EINVAL;
+ }
+
+ addr = (sc_faddr_t)boot_private_data;
+
+ if (addr >= aux_core_ram && addr <= aux_core_ram + size) {
+ printf("Wrong image address 0x%lx, should not in aux core ram\n",
+ addr);
+ return -EINVAL;
+ }
+
+ printf("Power on aux core %d\n", core_id);
+
+ if (sc_pm_set_resource_power_mode(-1, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+ return -EIO;
+
+ if (mu_rsrc != SC_R_NONE) {
+ if (sc_pm_set_resource_power_mode(-1, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE)
+ return -EIO;
+ }
+
+ if (core_id == 1) {
+ struct power_domain pd;
+
+ if (sc_pm_clock_enable(-1, core_rsrc, SC_PM_CLK_PER, true, false) != SC_ERR_NONE) {
+ printf("Error enable clock\n");
+ return -EIO;
+ }
+
+ if (!power_domain_lookup_name("audio_sai0", &pd)) {
+ if (power_domain_on(&pd)) {
+ printf("Error power on SAI0\n");
+ return -EIO;
+ }
+ }
+
+ if (!power_domain_lookup_name("audio_ocram", &pd)) {
+ if (power_domain_on(&pd)) {
+ printf("Error power on HIFI RAM\n");
+ return -EIO;
+ }
+ }
+ }
+
+ printf("Copy image from 0x%lx to 0x%lx\n", addr, (ulong)aux_core_ram);
+ if (core_id == 0) {
+ /* M4 use bin file */
+ memcpy((void *)aux_core_ram, (void *)addr, size);
+ } else {
+ /* HIFI use elf file */
+ if (!valid_elf_image(addr))
+ return -1;
+ addr = load_elf_image_shdr(addr);
+ }
+
+ printf("Start %s\n", core_id == 0 ? "M4" : "HIFI");
+
+ if (sc_pm_cpu_start(-1, core_rsrc, true, aux_core_ram) != SC_ERR_NONE)
+ return -EIO;
+
+ printf("bootaux complete\n");
+ return 0;
+}
+#endif
+
+int arch_auxiliary_core_check_up(u32 core_id)
+{
+ sc_rsrc_t core_rsrc;
+ sc_pm_power_mode_t power_mode;
+
+ switch (core_id) {
+ case 0:
+ core_rsrc = SC_R_M4_0_PID0;
+ break;
+#ifdef CONFIG_IMX8QM
+ case 1:
+ core_rsrc = SC_R_M4_1_PID0;
+ break;
+#endif
+ default:
+ printf("Not support this core, ID:%u\n", core_id);
+ return 0;
+ }
+
+ if (sc_pm_get_resource_power_mode(-1, core_rsrc, &power_mode) != SC_ERR_NONE)
+ return 0;
+
+ if (power_mode != SC_PM_PW_MODE_OFF)
+ return 1;
+
+ return 0;
+}
+#endif
+
int print_bootinfo(void)
{
enum boot_device bt_dev = get_boot_device();
@@ -195,7 +369,7 @@ enum boot_device get_boot_device(void)
#define FUSE_UNIQUE_ID_WORD1 17
void get_board_serial(struct tag_serialnr *serialnr)
{
- sc_err_t err;
+ int err;
u32 val1 = 0, val2 = 0;
u32 word1, word2;
@@ -206,13 +380,13 @@ void get_board_serial(struct tag_serialnr *serialnr)
word2 = FUSE_UNIQUE_ID_WORD1;
err = sc_misc_otp_fuse_read(-1, word1, &val1);
- if (err != SC_ERR_NONE) {
+ if (err) {
printf("%s fuse %d read error: %d\n", __func__, word1, err);
return;
}
err = sc_misc_otp_fuse_read(-1, word2, &val2);
- if (err != SC_ERR_NONE) {
+ if (err) {
printf("%s fuse %d read error: %d\n", __func__, word2, err);
return;
}
diff --git a/arch/arm/mach-imx/imx8/fdt.c b/arch/arm/mach-imx/imx8/fdt.c
index 02b3ee5c111..491c8bb8c75 100644
--- a/arch/arm/mach-imx/imx8/fdt.c
+++ b/arch/arm/mach-imx/imx8/fdt.c
@@ -110,7 +110,7 @@ static int config_smmu_resource_sid(int rsrc, int sid)
err = sc_rm_set_master_sid(-1, rsrc, sid);
debug("set_master_sid rsrc=%d sid=0x%x err=%d\n", rsrc, sid, err);
- if (err != SC_ERR_NONE) {
+ if (err) {
if (!check_owned_resource(rsrc)) {
printf("%s rsrc[%d] not owned\n", __func__, rsrc);
return -1;
diff --git a/arch/arm/mach-imx/imx8/snvs_security_sc.c b/arch/arm/mach-imx/imx8/snvs_security_sc.c
index d7b20a1fcbf..1eaa68f8d5f 100644
--- a/arch/arm/mach-imx/imx8/snvs_security_sc.c
+++ b/arch/arm/mach-imx/imx8/snvs_security_sc.c
@@ -286,16 +286,15 @@ static int check_write_secvio_config(u32 id, u32 *_p1, u32 *_p2,
u32 *_p3, u32 *_p4, u32 *_p5,
u32 _cnt)
{
- int scierr = 0;
+ int err;
u32 d1 = ptr_value(_p1);
u32 d2 = ptr_value(_p2);
u32 d3 = ptr_value(_p3);
u32 d4 = ptr_value(_p4);
u32 d5 = ptr_value(_p5);
- scierr = sc_seco_secvio_config(-1, id, SC_WRITE_CONF, &d1, &d2, &d3,
- &d4, &d4, _cnt);
- if (scierr != SC_ERR_NONE) {
+ err = sc_seco_secvio_config(-1, id, SC_WRITE_CONF, &d1, &d2, &d3, &d4, &d4, _cnt);
+ if (err) {
printf("Failed to set secvio configuration\n");
debug("Failed to set conf id 0x%x with values ", id);
debug("0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x (cnt: %d)\n",
@@ -315,7 +314,7 @@ static int check_write_secvio_config(u32 id, u32 *_p1, u32 *_p2,
*(u32 *)_p5 = d5;
exit:
- return scierr;
+ return err;
}
#define SC_CHECK_WRITE1(id, _p1) \
@@ -323,7 +322,7 @@ exit:
static int apply_snvs_config(struct snvs_security_sc_conf *cnf)
{
- int scierr = 0;
+ int err = 0;
debug("%s\n", __func__);
@@ -365,92 +364,88 @@ static int apply_snvs_config(struct snvs_security_sc_conf *cnf)
cnf->lp.act_tamper_routing_ctl1,
cnf->lp.act_tamper_routing_ctl2);
- scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_filt_cfg),
- &cnf->lp.tamper_filt_cfg,
- &cnf->lp.tamper_filt1_cfg,
- &cnf->lp.tamper_filt2_cfg, NULL,
- NULL, 3);
- if (scierr != SC_ERR_NONE)
+ err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_filt_cfg),
+ &cnf->lp.tamper_filt_cfg,
+ &cnf->lp.tamper_filt1_cfg,
+ &cnf->lp.tamper_filt2_cfg,
+ NULL, NULL, 3);
+ if (err)
goto exit;
/* Configure AT */
- scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper1_cfg),
- &cnf->lp.act_tamper1_cfg,
- &cnf->lp.act_tamper2_cfg,
- &cnf->lp.act_tamper2_cfg,
- &cnf->lp.act_tamper2_cfg,
- &cnf->lp.act_tamper2_cfg, 5);
- if (scierr != SC_ERR_NONE)
+ err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper1_cfg),
+ &cnf->lp.act_tamper1_cfg,
+ &cnf->lp.act_tamper2_cfg,
+ &cnf->lp.act_tamper2_cfg,
+ &cnf->lp.act_tamper2_cfg,
+ &cnf->lp.act_tamper2_cfg, 5);
+ if (err)
goto exit;
/* Configure AT routing */
- scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper_routing_ctl1),
- &cnf->lp.act_tamper_routing_ctl1,
- &cnf->lp.act_tamper_routing_ctl2,
- NULL, NULL, NULL, 2);
- if (scierr != SC_ERR_NONE)
+ err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper_routing_ctl1),
+ &cnf->lp.act_tamper_routing_ctl1,
+ &cnf->lp.act_tamper_routing_ctl2,
+ NULL, NULL, NULL, 2);
+ if (err)
goto exit;
/* Configure AT frequency */
- scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_clk_ctl),
- &cnf->lp.act_tamper_clk_ctl);
- if (scierr != SC_ERR_NONE)
+ err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_clk_ctl),
+ &cnf->lp.act_tamper_clk_ctl);
+ if (err)
goto exit;
/* Activate the ATs */
- scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_ctl),
- &cnf->lp.act_tamper_ctl);
- if (scierr != SC_ERR_NONE)
+ err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_ctl), &cnf->lp.act_tamper_ctl);
+ if (err)
goto exit;
/* Activate the detectors */
- scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_cfg),
- &cnf->lp.tamper_det_cfg,
- &cnf->lp.tamper_det_cfg2, NULL, NULL,
- NULL, 2);
- if (scierr != SC_ERR_NONE)
+ err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_cfg),
+ &cnf->lp.tamper_det_cfg,
+ &cnf->lp.tamper_det_cfg2, NULL, NULL, NULL, 2);
+ if (err)
goto exit;
/* Configure LP secvio */
- scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.secvio_ctl),
- &cnf->lp.secvio_ctl);
- if (scierr != SC_ERR_NONE)
+ err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.secvio_ctl), &cnf->lp.secvio_ctl);
+ if (err)
goto exit;
/* Configure HP secvio */
- scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.secvio_ctl),
- &cnf->hp.secvio_ctl);
- if (scierr != SC_ERR_NONE)
+ err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.secvio_ctl), &cnf->hp.secvio_ctl);
+ if (err)
goto exit;
/* Lock access */
- scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.lock), &cnf->hp.lock);
- if (scierr != SC_ERR_NONE)
+ err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.lock), &cnf->hp.lock);
+ if (err)
goto exit;
- scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.lock), &cnf->lp.lock);
- if (scierr != SC_ERR_NONE)
+ err = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.lock), &cnf->lp.lock);
+ if (err)
goto exit;
exit:
- return (scierr == SC_ERR_NONE) ? 0 : -EIO;
+ return err;
}
static int dgo_write(u32 _id, u8 _access, u32 *_pdata)
{
- int scierr = sc_seco_secvio_dgo_config(-1, _id, _access, _pdata);
+ int err = sc_seco_secvio_dgo_config(-1, _id, _access, _pdata);
- if (scierr != SC_ERR_NONE) {
+ if (err) {
printf("Failed to set dgo configuration\n");
debug("Failed to set conf id 0x%x : 0x%.8x", _id, *_pdata);
}
- return scierr;
+ return err;
}
static int apply_snvs_dgo_config(struct snvs_dgo_conf *cnf)
{
- int scierr = 0;
+ int err;
debug("%s\n", __func__);
@@ -468,50 +463,50 @@ static int apply_snvs_dgo_config(struct snvs_dgo_conf *cnf)
cnf->tamper_misc_ctl,
cnf->tamper_core_volt_mon_ctl);
- dgo_write(0x04, 1, &cnf->tamper_offset_ctl);
- if (scierr != SC_ERR_NONE)
+ err = dgo_write(0x04, 1, &cnf->tamper_offset_ctl);
+ if (err)
goto exit;
- dgo_write(0x14, 1, &cnf->tamper_pull_ctl);
- if (scierr != SC_ERR_NONE)
+ err = dgo_write(0x14, 1, &cnf->tamper_pull_ctl);
+ if (err)
goto exit;
- dgo_write(0x24, 1, &cnf->tamper_ana_test_ctl);
- if (scierr != SC_ERR_NONE)
+ err = dgo_write(0x24, 1, &cnf->tamper_ana_test_ctl);
+ if (err)
goto exit;
- dgo_write(0x34, 1, &cnf->tamper_sensor_trim_ctl);
- if (scierr != SC_ERR_NONE)
+ err = dgo_write(0x34, 1, &cnf->tamper_sensor_trim_ctl);
+ if (err)
goto exit;
- dgo_write(0x54, 1, &cnf->tamper_core_volt_mon_ctl);
- if (scierr != SC_ERR_NONE)
+ err = dgo_write(0x54, 1, &cnf->tamper_core_volt_mon_ctl);
+ if (err)
goto exit;
/* Last as it could lock the writes */
- dgo_write(0x44, 1, &cnf->tamper_misc_ctl);
- if (scierr != SC_ERR_NONE)
+ err = dgo_write(0x44, 1, &cnf->tamper_misc_ctl);
+ if (err)
goto exit;
exit:
- return (scierr == SC_ERR_NONE) ? 0 : -EIO;
+ return err;
}
static int pad_write(u32 _pad, u32 _value)
{
- int scierr = sc_pad_set(-1, _pad, _value);
+ int err = sc_pad_set(-1, _pad, _value);
- if (scierr != SC_ERR_NONE) {
+ if (err) {
printf("Failed to set pad configuration\n");
debug("Failed to set conf pad 0x%x : 0x%.8x", _pad, _value);
}
- return scierr;
+ return err;
}
static int apply_tamper_pin_list_config(struct tamper_pin_cfg *confs, u32 size)
{
- int scierr = 0;
+ int err = 0;
u32 idx;
debug("%s\n", __func__);
@@ -519,13 +514,13 @@ static int apply_tamper_pin_list_config(struct tamper_pin_cfg *confs, u32 size)
for (idx = 0; idx < size; idx++) {
debug("\t idx %d: pad %d: 0x%.8x\n", idx, confs[idx].pad,
confs[idx].mux_conf);
- pad_write(confs[idx].pad, 3 << 30 | confs[idx].mux_conf);
- if (scierr != SC_ERR_NONE)
+ err = pad_write(confs[idx].pad, 3 << 30 | confs[idx].mux_conf);
+ if (err)
goto exit;
}
exit:
- return (scierr == SC_ERR_NONE) ? 0 : -EIO;
+ return err;
}
int examples(void)
@@ -753,7 +748,7 @@ static char snvs_clear_status_help_text[] =
static int do_snvs_clear_status(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
- int scierr = 0;
+ int err;
u32 idx = 0;
struct snvs_security_sc_conf conf = {0};
@@ -764,20 +759,18 @@ static int do_snvs_clear_status(struct cmd_tbl *cmdtp, int flag, int argc,
conf.lp.status = hextoul(argv[++idx], NULL);
conf.lp.tamper_det_status = hextoul(argv[++idx], NULL);
- scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.status),
- &conf.lp.status, NULL, NULL, NULL,
- NULL, 1);
- if (scierr != SC_ERR_NONE)
+ err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.status),
+ &conf.lp.status, NULL, NULL, NULL, NULL, 1);
+ if (err)
goto exit;
- scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_status),
- &conf.lp.tamper_det_status, NULL,
- NULL, NULL, NULL, 1);
- if (scierr != SC_ERR_NONE)
+ err = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_status),
+ &conf.lp.tamper_det_status, NULL, NULL, NULL, NULL, 1);
+ if (err)
goto exit;
exit:
- return (scierr == SC_ERR_NONE) ? 0 : 1;
+ return err;
}
U_BOOT_CMD(snvs_clear_status,
@@ -793,7 +786,7 @@ static char snvs_sec_status_help_text[] =
static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
- int scierr;
+ int err;
u32 idx;
u32 data[5];
@@ -864,8 +857,8 @@ static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc,
for (idx = 0; idx < ARRAY_SIZE(pads); idx++) {
u8 pad_id = pads[idx];
- scierr = sc_pad_get(-1, pad_id, &data[0]);
- if (scierr == 0)
+ err = sc_pad_get(-1, pad_id, &data[0]);
+ if (!err)
printf("\t- Pin %d: %.8x\n", pad_id, data[0]);
else
printf("Failed to read Pin %d\n", pad_id);
@@ -876,8 +869,8 @@ static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc,
for (idx = 0; idx < ARRAY_SIZE(fuses); idx++) {
u32 fuse_id = fuses[idx];
- scierr = sc_misc_otp_fuse_read(-1, fuse_id, &data[0]);
- if (scierr == 0)
+ err = sc_misc_otp_fuse_read(-1, fuse_id, &data[0]);
+ if (!err)
printf("\t- Fuse %d: %.8x\n", fuse_id, data[0]);
else
printf("Failed to read Fuse %d\n", fuse_id);
@@ -888,10 +881,10 @@ static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc,
for (idx = 0; idx < ARRAY_SIZE(snvs); idx++) {
struct snvs_reg *reg = &snvs[idx];
- scierr = sc_seco_secvio_config(-1, reg->id, 0, &data[0],
- &data[1], &data[2], &data[3],
- &data[4], reg->nb);
- if (scierr == 0) {
+ err = sc_seco_secvio_config(-1, reg->id, 0, &data[0],
+ &data[1], &data[2], &data[3],
+ &data[4], reg->nb);
+ if (!err) {
int subidx;
printf("\t- SNVS %.2x(%d):", reg->id, reg->nb);
@@ -908,8 +901,8 @@ static int do_snvs_sec_status(struct cmd_tbl *cmdtp, int flag, int argc,
for (idx = 0; idx < ARRAY_SIZE(dgo); idx++) {
u8 dgo_id = dgo[idx];
- scierr = sc_seco_secvio_dgo_config(-1, dgo_id, 0, &data[0]);
- if (scierr == 0)
+ err = sc_seco_secvio_dgo_config(-1, dgo_id, 0, &data[0]);
+ if (!err)
printf("\t- DGO %.2x: %.8x\n", dgo_id, data[0]);
else
printf("Failed to read DGO %d\n", dgo_id);
diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig
index 7639439bdc9..3d62d7052e7 100644
--- a/arch/arm/mach-imx/imx8m/Kconfig
+++ b/arch/arm/mach-imx/imx8m/Kconfig
@@ -124,6 +124,9 @@ config TARGET_IMX8MM_VENICE
select IMX8M_LPDDR4
select GATEWORKS_SC
select MISC
+ select FSL_CAAM
+ select ARCH_MISC_INIT
+ select SPL_CRYPTO if SPL
config TARGET_KONTRON_MX8MM
bool "Kontron Electronics N80xx"
@@ -175,6 +178,9 @@ config TARGET_IMX8MN_VENICE
select IMX8M_LPDDR4
select GATEWORKS_SC
select MISC
+ select FSL_CAAM
+ select ARCH_MISC_INIT
+ select SPL_CRYPTO if SPL
config TARGET_IMX8MP_DATA_MODUL_EDM_SBC
bool "Data Modul eDM SBC i.MX8M Plus"
@@ -232,6 +238,9 @@ config TARGET_IMX8MP_VENICE
select IMX8M_LPDDR4
select GATEWORKS_SC
select MISC
+ select FSL_CAAM
+ select ARCH_MISC_INIT
+ select SPL_CRYPTO if SPL
config TARGET_PICO_IMX8MQ
bool "Support Technexion Pico iMX8MQ"
@@ -245,6 +254,10 @@ config TARGET_IMX8MN_VAR_SOM
select IMX8MN
select SUPPORT_SPL
select IMX8M_DDR4
+ select MISC
+ select I2C_EEPROM
+ select DM_ETH_PHY
+ select NVMEM
config TARGET_KONTRON_PITX_IMX8M
bool "Support Kontron pITX-imx8m"
diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c
index 31c34b6031f..986870799d3 100644
--- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c
+++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c
@@ -90,7 +90,6 @@ static int fracpll_configure(enum pll_clocks pll, u32 freq)
case ANATOP_DRAM_PLL:
setbits_le32(GPC_BASE_ADDR + 0xEC, 1 << 7);
setbits_le32(GPC_BASE_ADDR + 0xF8, 1 << 5);
- writel(SRC_DDR1_ENABLE_MASK, SRC_BASE_ADDR + 0x1004);
pll_base = &ana_pll->dram_pll_gnrl_ctl;
break;
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c
index 5ffdcabbb51..d5254886bed 100644
--- a/arch/arm/mach-imx/imx8m/soc.c
+++ b/arch/arm/mach-imx/imx8m/soc.c
@@ -737,7 +737,7 @@ static int disable_fdt_nodes(void *blob, const char *const nodes_path[], int siz
if (nodeoff < 0)
continue; /* Not found, skip it */
- printf("Found %s node\n", nodes_path[i]);
+ debug("Found %s node\n", nodes_path[i]);
add_status:
rc = fdt_setprop(blob, nodeoff, "status", status, strlen(status) + 1);
@@ -1266,7 +1266,7 @@ int ft_system_setup(void *blob, struct bd_info *bd)
if (nodeoff >= 0) {
const char *speed = "high-speed";
- printf("Found %s node\n", usb_dwc3_path[v]);
+ debug("Found %s node\n", usb_dwc3_path[v]);
usb_modify_speed:
diff --git a/arch/arm/mach-imx/imx8ulp/Makefile b/arch/arm/mach-imx/imx8ulp/Makefile
index f7692cf3a78..2c9938fcdf0 100644
--- a/arch/arm/mach-imx/imx8ulp/Makefile
+++ b/arch/arm/mach-imx/imx8ulp/Makefile
@@ -5,7 +5,6 @@
obj-y += lowlevel_init.o
obj-y += soc.o clock.o iomux.o pcc.o cgc.o rdc.o
-obj-$(CONFIG_AHAB_BOOT) += ahab.o
ifeq ($(CONFIG_SPL_BUILD),y)
obj-y += upower/
diff --git a/arch/arm/mach-imx/imx8ulp/rdc.c b/arch/arm/mach-imx/imx8ulp/rdc.c
index 50b097b035a..cfc09e79cbd 100644
--- a/arch/arm/mach-imx/imx8ulp/rdc.c
+++ b/arch/arm/mach-imx/imx8ulp/rdc.c
@@ -9,7 +9,7 @@
#include <asm/arch/imx-regs.h>
#include <asm/arch/sys_proto.h>
#include <asm/mach-imx/mu_hal.h>
-#include <asm/mach-imx/s400_api.h>
+#include <asm/mach-imx/ele_api.h>
#include <asm/arch/rdc.h>
#include <div64.h>
@@ -203,12 +203,12 @@ int xrdc_config_msc(u32 msc, u32 index, u32 dom, u32 perm)
int release_rdc(enum rdc_type type)
{
ulong s_mu_base = 0x27020000UL;
- struct sentinel_msg msg;
+ struct ele_msg msg;
int ret;
u32 rdc_id = (type == RDC_XRDC) ? 0x78 : 0x74;
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 2;
msg.command = ELE_RELEASE_RDC_REQ;
msg.data[0] = (rdc_id << 8) | 0x2; /* A35 XRDC */
@@ -266,7 +266,7 @@ void xrdc_mrc_region_set_access(int mrc_index, u32 addr, u32 access)
mrgd[4] |= ((access & 0xFFF) << 16);
}
- /* not handle other cases, since S400 only set ACCESS1 and 2 */
+ /* not handle other cases, since ELE only set ACCESS1 and 2 */
writel(mrgd[4], xrdc_base + off + 0x10);
return;
}
@@ -295,7 +295,7 @@ void xrdc_init_mda(void)
void xrdc_init_mrc(void)
{
- /* Re-config MRC3 for SRAM0 in case protected by S400 */
+ /* Re-config MRC3 for SRAM0 in case protected by ELE */
xrdc_config_mrc_w0_w1(3, 0, 0x22010000, 0x10000);
xrdc_config_mrc_dx_perm(3, 0, 0, 1);
xrdc_config_mrc_dx_perm(3, 0, 1, 1);
@@ -320,7 +320,7 @@ void xrdc_init_mrc(void)
xrdc_config_mrc_dx_perm(5, 0, 1, 1);
xrdc_config_mrc_w3_w4(5, 0, 0x0, 0x80000FFF);
- /* Set MRC6 for DDR access from Sentinel */
+ /* Set MRC6 for DDR access from ELE */
xrdc_config_mrc_w0_w1(6, 0, CFG_SYS_SDRAM_BASE, PHYS_SDRAM_SIZE);
xrdc_config_mrc_dx_perm(6, 0, 4, 1);
xrdc_config_mrc_w3_w4(6, 0, 0x0, 0x80000FFF);
@@ -404,7 +404,7 @@ int trdc_mbc_set_access(u32 mbc_x, u32 dom_x, u32 mem_x, u32 blk_x, bool sec_acc
val &= ~(0xFU << offset);
/* MBC0-3
- * Global 0, 0x7777 secure pri/user read/write/execute, S400 has already set it.
+ * Global 0, 0x7777 secure pri/user read/write/execute, ELE has already set it.
* So select MBC0_MEMN_GLBAC0
*/
if (sec_access) {
@@ -445,7 +445,7 @@ int trdc_mrc_region_set_access(u32 mrc_x, u32 dom_x, u32 addr_start, u32 addr_en
continue;
/* MRC0,1
- * Global 0, 0x7777 secure pri/user read/write/execute, S400 has already set it.
+ * Global 0, 0x7777 secure pri/user read/write/execute, ELE has already set it.
* So select MRCx_MEMN_GLBAC0
*/
if (sec_access) {
diff --git a/arch/arm/mach-imx/imx8ulp/soc.c b/arch/arm/mach-imx/imx8ulp/soc.c
index 81eae02b6a8..e23cf60d126 100644
--- a/arch/arm/mach-imx/imx8ulp/soc.c
+++ b/arch/arm/mach-imx/imx8ulp/soc.c
@@ -14,7 +14,7 @@
#include <event.h>
#include <spl.h>
#include <asm/arch/rdc.h>
-#include <asm/mach-imx/s400_api.h>
+#include <asm/mach-imx/ele_api.h>
#include <asm/mach-imx/mu_hal.h>
#include <cpu_func.h>
#include <asm/setup.h>
@@ -70,7 +70,7 @@ int mmc_get_env_dev(void)
}
#endif
-static void set_cpu_info(struct sentinel_get_info_data *info)
+static void set_cpu_info(struct ele_get_info_data *info)
{
gd->arch.soc_rev = info->soc;
gd->arch.lifecycle = info->lc;
@@ -582,9 +582,9 @@ void get_board_serial(struct tag_serialnr *serialnr)
u32 res;
int ret;
- ret = ahab_read_common_fuse(1, uid, 4, &res);
+ ret = ele_read_common_fuse(1, uid, 4, &res);
if (ret)
- printf("ahab read fuse failed %d, 0x%x\n", ret, res);
+ printf("ele read fuse failed %d, 0x%x\n", ret, res);
else
printf("UID 0x%x,0x%x,0x%x,0x%x\n", uid[0], uid[1], uid[2], uid[3]);
@@ -783,7 +783,7 @@ int imx8ulp_dm_post_init(void)
struct udevice *devp;
int ret;
u32 res;
- struct sentinel_get_info_data *info = (struct sentinel_get_info_data *)SRAM0_BASE;
+ struct ele_get_info_data *info = (struct ele_get_info_data *)SRAM0_BASE;
ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(imx8ulp_mu), &devp);
if (ret) {
@@ -791,11 +791,11 @@ int imx8ulp_dm_post_init(void)
return ret;
}
- ret = ahab_get_info(info, &res);
+ ret = ele_get_info(info, &res);
if (ret) {
- printf("ahab_get_info failed %d\n", ret);
+ printf("ele_get_info failed %d\n", ret);
/* fallback to A0.1 revision */
- memset((void *)info, 0, sizeof(struct sentinel_get_info_data));
+ memset((void *)info, 0, sizeof(struct ele_get_info_data));
info->soc = 0xa000084d;
}
diff --git a/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c b/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c
index fcb02ed3af6..b471a75caa1 100644
--- a/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c
+++ b/arch/arm/mach-imx/imx8ulp/upower/upower_hal.c
@@ -217,8 +217,8 @@ int upower_init(void)
* CM33 Cache
* PowerQuad RAM
* ETF RAM
- * Sentinel PKC, Data RAM1, Inst RAM0/1
- * Sentinel ROM
+ * ELE PKC, Data RAM1, Inst RAM0/1
+ * ELE ROM
* uPower IRAM/DRAM
* uPower ROM
* CM33 ROM
@@ -230,7 +230,7 @@ int upower_init(void)
* SSRAM Partition 7_a(128KB)
* SSRAM Partition 7_b(64KB)
* SSRAM Partition 7_c(64KB)
- * Sentinel Data RAM0, Inst RAM2
+ * ELE Data RAM0, Inst RAM2
*/
/* MIPI-CSI FIFO BIT28 not set */
memon = 0x3FFFFFEFFFFFFCUL;
diff --git a/arch/arm/mach-imx/imx9/clock.c b/arch/arm/mach-imx/imx9/clock.c
index a7ecccaf879..766a8811c1f 100644
--- a/arch/arm/mach-imx/imx9/clock.c
+++ b/arch/arm/mach-imx/imx9/clock.c
@@ -709,8 +709,8 @@ struct imx_clk_setting imx_clk_settings[] = {
/* Set A55 mtr bus to 133M */
{ARM_A55_MTR_BUS_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
- /* Sentinel to 133M */
- {SENTINEL_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
+ /* ELE to 133M */
+ {ELE_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
/* Bus_wakeup to 133M */
{BUS_WAKEUP_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
/* Bus_AON to 133M */
@@ -740,8 +740,8 @@ struct imx_clk_setting imx_clk_settings[] = {
{ARM_A55_PERIPH_CLK_ROOT, SYS_PLL_PFD0, 3},
/* Set A55 mtr bus to 133M */
{ARM_A55_MTR_BUS_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
- /* Sentinel to 200M */
- {SENTINEL_CLK_ROOT, SYS_PLL_PFD1_DIV2, 2},
+ /* ELE to 200M */
+ {ELE_CLK_ROOT, SYS_PLL_PFD1_DIV2, 2},
/* Bus_wakeup to 133M */
{BUS_WAKEUP_CLK_ROOT, SYS_PLL_PFD1_DIV2, 3},
/* Bus_AON to 133M */
diff --git a/arch/arm/mach-imx/imx9/clock_root.c b/arch/arm/mach-imx/imx9/clock_root.c
index 06b93f60996..7d7ae865946 100644
--- a/arch/arm/mach-imx/imx9/clock_root.c
+++ b/arch/arm/mach-imx/imx9/clock_root.c
@@ -34,7 +34,7 @@ static struct clk_root_map clk_root_array[] = {
{ ARM_A55_MTR_BUS_CLK_ROOT, 2 },
{ ARM_A55_CLK_ROOT, 0 },
{ M33_CLK_ROOT, 2 },
- { SENTINEL_CLK_ROOT, 2 },
+ { ELE_CLK_ROOT, 2 },
{ BUS_WAKEUP_CLK_ROOT, 2 },
{ BUS_AON_CLK_ROOT, 2 },
{ WAKEUP_AXI_CLK_ROOT, 0 },
diff --git a/arch/arm/mach-imx/imx9/imx_bootaux.c b/arch/arm/mach-imx/imx9/imx_bootaux.c
index 256e6fa1c54..6afb59e0515 100644
--- a/arch/arm/mach-imx/imx9/imx_bootaux.c
+++ b/arch/arm/mach-imx/imx9/imx_bootaux.c
@@ -13,7 +13,7 @@ int arch_auxiliary_core_check_up(u32 core_id)
{
struct arm_smccc_res res;
- arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0,
+ arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STARTED, 0, 0,
0, 0, 0, 0, &res);
return res.a0;
@@ -25,7 +25,7 @@ int arch_auxiliary_core_down(u32 core_id)
printf("## Stopping auxiliary core\n");
- arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_STOP, 0, 0,
+ arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STOP, 0, 0,
0, 0, 0, 0, &res);
return 0;
@@ -40,7 +40,7 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr)
printf("## Starting auxiliary core addr = 0x%08lX...\n", addr);
- arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, addr, 0,
+ arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_START, addr, 0,
0, 0, 0, 0, &res);
return 0;
diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach-imx/imx9/soc.c
index 64e8ac610e5..f43b73a6c21 100644
--- a/arch/arm/mach-imx/imx9/soc.c
+++ b/arch/arm/mach-imx/imx9/soc.c
@@ -34,7 +34,7 @@
#include <asm/setup.h>
#include <asm/bootm.h>
#include <asm/arch-imx/cpu.h>
-#include <asm/mach-imx/s400_api.h>
+#include <asm/mach-imx/ele_api.h>
#include <fuse.h>
#include <asm/arch/ddr.h>
@@ -151,7 +151,7 @@ u32 get_cpu_temp_grade(int *minc, int *maxc)
return val;
}
-static void set_cpu_info(struct sentinel_get_info_data *info)
+static void set_cpu_info(struct ele_get_info_data *info)
{
gd->arch.soc_rev = info->soc;
gd->arch.lifecycle = info->lc;
@@ -557,7 +557,7 @@ int imx9_probe_mu(void *ctx, struct event *event)
struct udevice *devp;
int node, ret;
u32 res;
- struct sentinel_get_info_data info;
+ struct ele_get_info_data info;
node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "fsl,imx93-mu-s4");
@@ -568,7 +568,7 @@ int imx9_probe_mu(void *ctx, struct event *event)
if (gd->flags & GD_FLG_RELOC)
return 0;
- ret = ahab_get_info(&info, &res);
+ ret = ele_get_info(&info, &res);
if (ret)
return ret;
@@ -600,35 +600,31 @@ int timer_init(void)
enum env_location env_get_location(enum env_operation op, int prio)
{
enum boot_device dev = get_boot_device();
- enum env_location env_loc = ENVL_UNKNOWN;
if (prio)
- return env_loc;
+ return ENVL_UNKNOWN;
switch (dev) {
-#if defined(CONFIG_ENV_IS_IN_SPI_FLASH)
case QSPI_BOOT:
- env_loc = ENVL_SPI_FLASH;
- break;
-#endif
-#if defined(CONFIG_ENV_IS_IN_MMC)
+ if (CONFIG_IS_ENABLED(ENV_IS_IN_SPI_FLASH))
+ return ENVL_SPI_FLASH;
+ return ENVL_NOWHERE;
case SD1_BOOT:
case SD2_BOOT:
case SD3_BOOT:
case MMC1_BOOT:
case MMC2_BOOT:
case MMC3_BOOT:
- env_loc = ENVL_MMC;
- break;
-#endif
+ if (CONFIG_IS_ENABLED(ENV_IS_IN_MMC))
+ return ENVL_MMC;
+ else if (CONFIG_IS_ENABLED(ENV_IS_IN_EXT4))
+ return ENVL_EXT4;
+ else if (CONFIG_IS_ENABLED(ENV_IS_IN_FAT))
+ return ENVL_FAT;
+ return ENVL_NOWHERE;
default:
-#if defined(CONFIG_ENV_IS_NOWHERE)
- env_loc = ENVL_NOWHERE;
-#endif
- break;
+ return ENVL_NOWHERE;
}
-
- return env_loc;
}
static int mix_power_init(enum mix_power_domain pd)
@@ -646,7 +642,7 @@ static int mix_power_init(enum mix_power_domain pd)
mem_id = SRC_MEM_MEDIA;
scr = BIT(5);
- /* Enable S400 handshake */
+ /* Enable ELE handshake */
struct blk_ctrl_s_aonmix_regs *s_regs =
(struct blk_ctrl_s_aonmix_regs *)BLK_CTRL_S_ANOMIX_BASE_ADDR;
@@ -763,8 +759,8 @@ int m33_prepare(void)
while (!(val & SRC_MIX_SLICE_FUNC_STAT_RST_STAT))
val = readl(&mix_regs->func_stat);
- /* Release Sentinel TROUT */
- ahab_release_m33_trout();
+ /* Release ELE TROUT */
+ ele_release_m33_trout();
/* Mask WDOG1 IRQ from A55, we use it for M33 reset */
setbits_le32(&s_regs->ca55_irq_mask[1], BIT(6));
@@ -772,7 +768,7 @@ int m33_prepare(void)
/* Turn on WDOG1 clock */
ccm_lpcg_on(CCGR_WDG1, 1);
- /* Set sentinel LP handshake for M33 reset */
+ /* Set ELE LP handshake for M33 reset */
setbits_le32(&s_regs->lp_handshake[0], BIT(6));
/* Clear M33 TCM for ECC */
diff --git a/arch/arm/mach-imx/imx9/trdc.c b/arch/arm/mach-imx/imx9/trdc.c
index e05c7048106..d0f855bb1bc 100644
--- a/arch/arm/mach-imx/imx9/trdc.c
+++ b/arch/arm/mach-imx/imx9/trdc.c
@@ -10,7 +10,7 @@
#include <asm/arch/imx-regs.h>
#include <asm/arch/sys_proto.h>
#include <div64.h>
-#include <asm/mach-imx/s400_api.h>
+#include <asm/mach-imx/ele_api.h>
#include <asm/mach-imx/mu_hal.h>
#define DID_NUM 16
@@ -196,7 +196,7 @@ int trdc_mbc_blk_config(ulong trdc_reg, u32 mbc_x, u32 dom_x, u32 mem_x,
val &= ~(0xFU << offset);
/* MBC0-3
- * Global 0, 0x7777 secure pri/user read/write/execute, S400 has already set it.
+ * Global 0, 0x7777 secure pri/user read/write/execute, ELE has already set it.
* So select MBC0_MEMN_GLBAC0
*/
if (sec_access) {
@@ -266,7 +266,7 @@ int trdc_mrc_region_config(ulong trdc_reg, u32 mrc_x, u32 dom_x, u32 addr_start,
continue;
/* MRC0,1
- * Global 0, 0x7777 secure pri/user read/write/execute, S400 has already set it.
+ * Global 0, 0x7777 secure pri/user read/write/execute, ELE has already set it.
* So select MRCx_MEMN_GLBAC0
*/
if (sec_access) {
@@ -315,7 +315,7 @@ bool trdc_mbc_enabled(ulong trdc_base)
int release_rdc(u8 xrdc)
{
ulong s_mu_base = 0x47520000UL;
- struct sentinel_msg msg;
+ struct ele_msg msg;
int ret;
u32 rdc_id;
@@ -336,8 +336,8 @@ int release_rdc(u8 xrdc)
return -EINVAL;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 2;
msg.command = ELE_RELEASE_RDC_REQ;
msg.data[0] = (rdc_id << 8) | 0x2; /* A55 */
@@ -394,7 +394,7 @@ void trdc_init(void)
/* DDR */
trdc_mrc_set_control(0x49010000, 0, 0, 0x7777);
- /* S400*/
+ /* ELE */
trdc_mrc_region_config(0x49010000, 0, 0, 0x80000000, 0xFFFFFFFF, false, 0);
/* MTR */
diff --git a/arch/arm/mach-imx/imx_bootaux.c b/arch/arm/mach-imx/imx_bootaux.c
index 888c53d6901..f7b14ca38d9 100644
--- a/arch/arm/mach-imx/imx_bootaux.c
+++ b/arch/arm/mach-imx/imx_bootaux.c
@@ -14,6 +14,7 @@
#include <linux/compiler.h>
#include <cpu_func.h>
+#ifndef CONFIG_IMX8
/* Just to avoid build error */
#if IS_ENABLED(CONFIG_IMX8M)
#define SRC_M4C_NON_SCLR_RST_MASK BIT(0)
@@ -45,7 +46,7 @@ static const struct rproc_att *get_host_mapping(unsigned long auxcore)
* is valid, returns the entry point address.
* Translates load addresses in the elf file to the U-Boot address space.
*/
-static unsigned long load_elf_image_m_core_phdr(unsigned long addr, ulong *stack)
+static u32 load_elf_image_m_core_phdr(unsigned long addr, u32 *stack)
{
Elf32_Ehdr *ehdr; /* ELF header structure pointer */
Elf32_Phdr *phdr; /* Program header structure pointer */
@@ -95,7 +96,7 @@ static unsigned long load_elf_image_m_core_phdr(unsigned long addr, ulong *stack
int arch_auxiliary_core_up(u32 core_id, ulong addr)
{
- ulong stack, pc;
+ u32 stack, pc;
if (!addr)
return -EINVAL;
@@ -121,18 +122,18 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr)
pc = *(u32 *)(addr + 4);
}
- printf("## Starting auxiliary core stack = 0x%08lX, pc = 0x%08lX...\n",
+ printf("## Starting auxiliary core stack = 0x%08X, pc = 0x%08X...\n",
stack, pc);
- /* Set the stack and pc to M4 bootROM */
- writel(stack, M4_BOOTROM_BASE_ADDR);
- writel(pc, M4_BOOTROM_BASE_ADDR + 4);
+ /* Set the stack and pc to MCU bootROM */
+ writel(stack, MCU_BOOTROM_BASE_ADDR);
+ writel(pc, MCU_BOOTROM_BASE_ADDR + 4);
flush_dcache_all();
- /* Enable M4 */
+ /* Enable MCU */
if (IS_ENABLED(CONFIG_IMX8M)) {
- arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0, 0, 0, 0, 0, NULL);
+ arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_START, 0, 0, 0, 0, 0, 0, NULL);
} else {
clrsetbits_le32(SRC_BASE_ADDR + SRC_M4_REG_OFFSET,
SRC_M4C_NON_SCLR_RST_MASK, SRC_M4_ENABLE_MASK);
@@ -147,7 +148,7 @@ int arch_auxiliary_core_check_up(u32 core_id)
unsigned int val;
if (IS_ENABLED(CONFIG_IMX8M)) {
- arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0, 0, 0, 0, 0, &res);
+ arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STARTED, 0, 0, 0, 0, 0, 0, &res);
return res.a0;
}
@@ -158,30 +159,34 @@ int arch_auxiliary_core_check_up(u32 core_id)
return 1;
}
-
+#endif
/*
* To i.MX6SX and i.MX7D, the image supported by bootaux needs
* the reset vector at the head for the image, with SP and PC
* as the first two words.
*
- * Per the cortex-M reference manual, the reset vector of M4 needs
- * to exist at 0x0 (TCMUL). The PC and SP are the first two addresses
- * of that vector. So to boot M4, the A core must build the M4's reset
+ * Per the cortex-M reference manual, the reset vector of M4/M7 needs
+ * to exist at 0x0 (TCMUL/IDTCM). The PC and SP are the first two addresses
+ * of that vector. So to boot M4/M7, the A core must build the M4/M7's reset
* vector with getting the PC and SP from image and filling them to
- * TCMUL. When M4 is kicked, it will load the PC and SP by itself.
- * The TCMUL is mapped to (M4_BOOTROM_BASE_ADDR) at A core side for
- * accessing the M4 TCMUL.
+ * TCMUL/IDTCM. When M4/M7 is kicked, it will load the PC and SP by itself.
+ * The TCMUL/IDTCM is mapped to (MCU_BOOTROM_BASE_ADDR) at A core side for
+ * accessing the M4/M7 TCMUL/IDTCM.
*/
static int do_bootaux(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
ulong addr;
int ret, up;
+ u32 core = 0;
if (argc < 2)
return CMD_RET_USAGE;
- up = arch_auxiliary_core_check_up(0);
+ if (argc > 2)
+ core = simple_strtoul(argv[2], NULL, 10);
+
+ up = arch_auxiliary_core_check_up(core);
if (up) {
printf("## Auxiliary core is already up\n");
return CMD_RET_SUCCESS;
@@ -192,7 +197,7 @@ static int do_bootaux(struct cmd_tbl *cmdtp, int flag, int argc,
if (!addr)
return CMD_RET_FAILURE;
- ret = arch_auxiliary_core_up(0, addr);
+ ret = arch_auxiliary_core_up(core, addr);
if (ret)
return CMD_RET_FAILURE;
@@ -202,5 +207,7 @@ static int do_bootaux(struct cmd_tbl *cmdtp, int flag, int argc,
U_BOOT_CMD(
bootaux, CONFIG_SYS_MAXARGS, 1, do_bootaux,
"Start auxiliary core",
- ""
+ "<address> [<core>]\n"
+ " - start auxiliary core [<core>] (default 0),\n"
+ " at address <address>\n"
);
diff --git a/arch/arm/mach-imx/mx6/module_fuse.c b/arch/arm/mach-imx/mx6/module_fuse.c
index 0f4565e3117..b58f11c1e56 100644
--- a/arch/arm/mach-imx/mx6/module_fuse.c
+++ b/arch/arm/mach-imx/mx6/module_fuse.c
@@ -206,7 +206,7 @@ int ft_system_setup(void *blob, struct bd_info *bd)
if (off < 0)
continue; /* Not found, skip it */
add_status:
- rc = fdt_setprop(blob, nodeoff, "status", status,
+ rc = fdt_setprop(blob, off, "status", status,
strlen(status) + 1);
if (rc) {
if (rc == -FDT_ERR_NOSPACE) {
diff --git a/arch/arm/mach-imx/mxs/Kconfig b/arch/arm/mach-imx/mxs/Kconfig
index b2026a3758a..d3233d8d14f 100644
--- a/arch/arm/mach-imx/mxs/Kconfig
+++ b/arch/arm/mach-imx/mxs/Kconfig
@@ -10,10 +10,12 @@ choice
config TARGET_MX23_OLINUXINO
bool "Support mx23_olinuxino"
+ select PL01X_SERIAL
select BOARD_EARLY_INIT_F
config TARGET_MX23EVK
bool "Support mx23evk"
+ select PL01X_SERIAL
select BOARD_EARLY_INIT_F
config TARGET_XFI3
@@ -41,16 +43,37 @@ choice
config TARGET_MX28EVK
bool "Support mx28evk"
+ select PL01X_SERIAL
select BOARD_EARLY_INIT_F
config TARGET_XEA
bool "Support XEA"
+ select PL01X_SERIAL
endchoice
config SYS_SOC
default "mxs"
+config SPL_MXS_PMU_MINIMAL_VDD5V_CURRENT
+ bool "Force minimal current draw from VDD5V by MX28 PMU"
+ default n
+ help
+ After setting this option, the current drawn from VDD5V
+ by the PMU is reduced to zero - the DCDC_BATT is used as
+ the main power source for PMU.
+
+config SPL_MXS_PMU_DISABLE_BATT_CHARGE
+ bool "Disable Battery Charging in MX28 PMU"
+ default n
+
+config SPL_MXS_PMU_ENABLE_4P2_LINEAR_REGULATOR
+ bool "Enable the 4P2 linear regulator in MX28 PMU"
+ default y
+ help
+ This option enables the 4P2 linear regulator (derived
+ from VDD5V) - so the VDD4P2 power source is operational.
+
source "board/freescale/mx28evk/Kconfig"
source "board/liebherr/xea/Kconfig"
diff --git a/arch/arm/mach-imx/parse-container.c b/arch/arm/mach-imx/parse-container.c
index f7582825d6d..e2a9e2b2732 100644
--- a/arch/arm/mach-imx/parse-container.c
+++ b/arch/arm/mach-imx/parse-container.c
@@ -1,75 +1,16 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2018-2019 NXP
+ * Copyright 2018-2021 NXP
*/
#include <common.h>
+#include <stdlib.h>
#include <errno.h>
#include <log.h>
#include <spl.h>
#include <asm/mach-imx/image.h>
#ifdef CONFIG_AHAB_BOOT
-#include <firmware/imx/sci/sci.h>
-#endif
-
-#define SEC_SECURE_RAM_BASE 0x31800000UL
-#define SEC_SECURE_RAM_END_BASE (SEC_SECURE_RAM_BASE + 0xFFFFUL)
-#define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE 0x60000000UL
-
-#define SECO_PT 2U
-
-#ifdef CONFIG_AHAB_BOOT
-static int authenticate_image(struct boot_img_t *img, int image_index)
-{
- sc_faddr_t start, end;
- sc_rm_mr_t mr;
- int err;
- int ret = 0;
-
- debug("img %d, dst 0x%x, src 0x%x, size 0x%x\n",
- image_index, (uint32_t)img->dst, img->offset, img->size);
-
- /* Find the memreg and set permission for seco pt */
- err = sc_rm_find_memreg(-1, &mr,
- img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1),
- ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1);
-
- if (err) {
- printf("can't find memreg for image %d load address 0x%x, error %d\n",
- image_index, img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), err);
- return -ENOMEM;
- }
-
- err = sc_rm_get_memreg_info(-1, mr, &start, &end);
- if (!err)
- debug("memreg %u 0x%x -- 0x%x\n", mr, start, end);
-
- err = sc_rm_set_memreg_permissions(-1, mr,
- SECO_PT, SC_RM_PERM_FULL);
- if (err) {
- printf("set permission failed for img %d, error %d\n",
- image_index, err);
- return -EPERM;
- }
-
- err = sc_seco_authenticate(-1, SC_SECO_VERIFY_IMAGE,
- 1 << image_index);
- if (err) {
- printf("authenticate img %d failed, return %d\n",
- image_index, err);
- ret = -EIO;
- }
-
- err = sc_rm_set_memreg_permissions(-1, mr,
- SECO_PT, SC_RM_PERM_NONE);
- if (err) {
- printf("remove permission failed for img %d, error %d\n",
- image_index, err);
- ret = -EPERM;
- }
-
- return ret;
-}
+#include <asm/mach-imx/ahab.h>
#endif
static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
@@ -110,10 +51,8 @@ static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
}
#ifdef CONFIG_AHAB_BOOT
- if (authenticate_image(&images[image_index], image_index)) {
- printf("Failed to authenticate image %d\n", image_index);
+ if (ahab_verify_cntr_image(&images[image_index], image_index))
return NULL;
- }
#endif
return &images[image_index];
@@ -134,21 +73,27 @@ static int read_auth_container(struct spl_image_info *spl_image,
* It will not override the ATF code, so safe to use it here,
* no need malloc
*/
- container = (struct container_hdr *)spl_get_load_buffer(-size, size);
+ container = malloc(size);
+ if (!container)
+ return -ENOMEM;
debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
container, sector, sectors);
- if (info->read(info, sector, sectors, container) != sectors)
- return -EIO;
+ if (info->read(info, sector, sectors, container) != sectors) {
+ ret = -EIO;
+ goto end;
+ }
if (container->tag != 0x87 && container->version != 0x0) {
- printf("Wrong container header\n");
- return -ENOENT;
+ printf("Wrong container header");
+ ret = -ENOENT;
+ goto end;
}
if (!container->num_images) {
- printf("Wrong container, no image found\n");
- return -ENOENT;
+ printf("Wrong container, no image found");
+ ret = -ENOENT;
+ goto end;
}
length = container->length_lsb + (container->length_msb << 8);
@@ -158,25 +103,24 @@ static int read_auth_container(struct spl_image_info *spl_image,
size = roundup(length, info->bl_len);
sectors = size / info->bl_len;
- container = (struct container_hdr *)spl_get_load_buffer(-size, size);
+ free(container);
+ container = malloc(size);
+ if (!container)
+ return -ENOMEM;
debug("%s: container: %p sector: %lu sectors: %u\n",
__func__, container, sector, sectors);
if (info->read(info, sector, sectors, container) !=
- sectors)
- return -EIO;
+ sectors) {
+ ret = -EIO;
+ goto end;
+ }
}
#ifdef CONFIG_AHAB_BOOT
- memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)container,
- ALIGN(length, CONFIG_SYS_CACHELINE_SIZE));
-
- ret = sc_seco_authenticate(-1, SC_SECO_AUTH_CONTAINER,
- SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE);
- if (ret) {
- printf("authenticate container hdr failed, return %d\n", ret);
- return ret;
- }
+ ret = ahab_auth_cntr_hdr(container, length);
+ if (ret)
+ goto end_auth;
#endif
for (i = 0; i < container->num_images; i++) {
@@ -197,9 +141,12 @@ static int read_auth_container(struct spl_image_info *spl_image,
end_auth:
#ifdef CONFIG_AHAB_BOOT
- if (sc_seco_authenticate(-1, SC_SECO_REL_CONTAINER, 0))
- printf("Error: release container failed!\n");
+ ahab_auth_release();
#endif
+
+end:
+ free(container);
+
return ret;
}
diff --git a/arch/arm/mach-imx/priblob.c b/arch/arm/mach-imx/priblob.c
index 9b92eae7818..5b022d5c820 100644
--- a/arch/arm/mach-imx/priblob.c
+++ b/arch/arm/mach-imx/priblob.c
@@ -13,12 +13,16 @@
#include <asm/io.h>
#include <common.h>
#include <command.h>
-#include "../drivers/crypto/fsl_caam_internal.h"
+#include <fsl_sec.h>
int do_priblob_write(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
{
- writel((readl(CAAM_SCFGR) & 0xFFFFFFFC) | 3, CAAM_SCFGR);
- printf("New priblob setting = 0x%x\n", readl(CAAM_SCFGR) & 0x3);
+ ccsr_sec_t *sec_regs = (ccsr_sec_t *)CAAM_BASE_ADDR;
+ u32 scfgr = sec_in32(&sec_regs->scfgr);
+
+ scfgr |= 0x3;
+ sec_out32(&sec_regs->scfgr, scfgr);
+ printf("New priblob setting = 0x%x\n", sec_in32(&sec_regs->scfgr) & 0x3);
return 0;
}
diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c
index 9164045115f..4af41699678 100644
--- a/arch/arm/mach-imx/spl_imx_romapi.c
+++ b/arch/arm/mach-imx/spl_imx_romapi.c
@@ -76,13 +76,16 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
u32 image_offset;
ret = rom_api_query_boot_infor(QUERY_IVT_OFF, &offset);
- ret |= rom_api_query_boot_infor(QUERY_PAGE_SZ, &pagesize);
- ret |= rom_api_query_boot_infor(QUERY_IMG_OFF, &image_offset);
+ if (ret != ROM_API_OKAY)
+ goto err;
- if (ret != ROM_API_OKAY) {
- puts("ROMAPI: Failure query boot infor pagesize/offset\n");
- return -1;
- }
+ ret = rom_api_query_boot_infor(QUERY_PAGE_SZ, &pagesize);
+ if (ret != ROM_API_OKAY)
+ goto err;
+
+ ret = rom_api_query_boot_infor(QUERY_IMG_OFF, &image_offset);
+ if (ret != ROM_API_OKAY)
+ goto err;
header = (struct legacy_img_hdr *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR);
@@ -124,6 +127,10 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
}
return 0;
+
+err:
+ puts("ROMAPI: Failure query boot infor pagesize/offset\n");
+ return -1;
}
static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector,
@@ -344,12 +351,12 @@ int board_return_to_bootrom(struct spl_image_info *spl_image,
u32 boot, bstage;
ret = rom_api_query_boot_infor(QUERY_BT_DEV, &boot);
- ret |= rom_api_query_boot_infor(QUERY_BT_STAGE, &bstage);
+ if (ret != ROM_API_OKAY)
+ goto err;
- if (ret != ROM_API_OKAY) {
- puts("ROMAPI: failure at query_boot_info\n");
- return -1;
- }
+ ret = rom_api_query_boot_infor(QUERY_BT_STAGE, &bstage);
+ if (ret != ROM_API_OKAY)
+ goto err;
printf("Boot Stage: ");
@@ -374,4 +381,7 @@ int board_return_to_bootrom(struct spl_image_info *spl_image,
return spl_romapi_load_image_stream(spl_image, bootdev);
return spl_romapi_load_image_seekable(spl_image, bootdev, boot);
+err:
+ puts("ROMAPI: failure at query_boot_info\n");
+ return -1;
}
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index ac484c73f62..5c7f4bf964a 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -202,6 +202,10 @@ config TARGET_X530
bool "Support Allied Telesis x530"
select 88F6820
+config TARGET_X240
+ bool "Support Allied Telesis x240"
+ select ALLEYCAT_5
+
config TARGET_DB_XC3_24G4XG
bool "Support DB-XC3-24G4XG"
select 98DX3336
@@ -274,6 +278,7 @@ config SYS_BOARD
default "theadorable" if TARGET_THEADORABLE
default "a38x" if TARGET_CONTROLCENTERDC
default "x530" if TARGET_X530
+ default "x240" if TARGET_X240
default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG
default "crs3xx-98dx3236" if TARGET_CRS3XX_98DX3236
default "mvebu_alleycat-5" if TARGET_MVEBU_ALLEYCAT5
@@ -297,6 +302,7 @@ config SYS_CONFIG_NAME
default "turris_mox" if TARGET_TURRIS_MOX
default "controlcenterdc" if TARGET_CONTROLCENTERDC
default "x530" if TARGET_X530
+ default "x240" if TARGET_X240
default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG
default "crs3xx-98dx3236" if TARGET_CRS3XX_98DX3236
default "mvebu_alleycat-5" if TARGET_MVEBU_ALLEYCAT5
@@ -320,6 +326,7 @@ config SYS_VENDOR
default "CZ.NIC" if TARGET_TURRIS_MOX
default "gdsys" if TARGET_CONTROLCENTERDC
default "alliedtelesis" if TARGET_X530
+ default "alliedtelesis" if TARGET_X240
default "mikrotik" if TARGET_CRS3XX_98DX3236
default "Marvell" if TARGET_MVEBU_ALLEYCAT5
diff --git a/arch/arm/mach-mvebu/alleycat5/soc.c b/arch/arm/mach-mvebu/alleycat5/soc.c
index dc69f46eedb..734b0a87dd4 100644
--- a/arch/arm/mach-mvebu/alleycat5/soc.c
+++ b/arch/arm/mach-mvebu/alleycat5/soc.c
@@ -255,6 +255,12 @@ void soc_print_clock_info(void)
printf("\tMSS %4d MHz\n", 200);
}
+/* Return NAND clock in Hz */
+u32 mvebu_get_nand_clock(void)
+{
+ return 400 * 1000000;
+}
+
/*
* Override of __weak int mach_cpu_init(void) :
* SoC/machine dependent CPU setup
diff --git a/arch/arm/mach-npcm/npcm8xx/cpu.c b/arch/arm/mach-npcm/npcm8xx/cpu.c
index 2d839cfae95..af594526094 100644
--- a/arch/arm/mach-npcm/npcm8xx/cpu.c
+++ b/arch/arm/mach-npcm/npcm8xx/cpu.c
@@ -68,6 +68,9 @@ int print_cpuinfo(void)
case ARBEL_A1:
printf("A1 @ ");
break;
+ case ARBEL_A2:
+ printf("A2 @ ");
+ break;
default:
printf("Unknown\n");
break;
@@ -92,7 +95,7 @@ int arch_cpu_init(void)
return 0;
}
-static struct mm_region npcm_mem_map[1 + CONFIG_NR_DRAM_BANKS + 1] = {
+static struct mm_region npcm_mem_map[] = {
{
/* DRAM */
.phys = 0x0UL,
@@ -110,6 +113,13 @@ static struct mm_region npcm_mem_map[1 + CONFIG_NR_DRAM_BANKS + 1] = {
PTE_BLOCK_PXN | PTE_BLOCK_UXN
},
{
+ .phys = 0x100000000UL,
+ .virt = 0x100000000UL,
+ .size = 0x80000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ },
+ {
/* List terminator */
0,
}
diff --git a/arch/powerpc/lib/Kconfig b/arch/powerpc/lib/Kconfig
index b30b5edf7cf..d38ba45a990 100644
--- a/arch/powerpc/lib/Kconfig
+++ b/arch/powerpc/lib/Kconfig
@@ -1,9 +1,9 @@
config CACHE_FLUSH_WATCHDOG_THRESHOLD
- int "Bytes to flush between WATCHDOG_RESET calls"
- default 0
+ int "Bytes to flush between schedule() calls"
+ default 4096
help
The flush_cache() function periodically, and by default for
- every cache line, calls WATCHDOG_RESET(). When flushing a
- large area, that may add a significant amount of
+ every 4k block, calls schedule() to reset watchdog. When
+ flushing a large area, that may add a significant amount of
overhead. This option allows you to set a threshold for how
- many bytes to flush between each WATCHDOG_RESET call.
+ many bytes to flush between each schedule() call.
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index f6ed05906a2..867cbcbe74e 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -27,6 +27,10 @@ config TARGET_SIFIVE_UNMATCHED
config TARGET_STARFIVE_VISIONFIVE2
bool "Support StarFive VisionFive2 Board"
+config TARGET_TH1520_LPI4A
+ bool "Support Sipeed's TH1520 Lichee PI 4A Board"
+ select SYS_CACHE_SHIFT_6
+
config TARGET_SIPEED_MAIX
bool "Support Sipeed Maix Board"
select SYS_CACHE_SHIFT_6
@@ -66,6 +70,7 @@ source "board/emulation/qemu-riscv/Kconfig"
source "board/microchip/mpfs_icicle/Kconfig"
source "board/sifive/unleashed/Kconfig"
source "board/sifive/unmatched/Kconfig"
+source "board/thead/th1520_lpi4a/Kconfig"
source "board/openpiton/riscv64/Kconfig"
source "board/sipeed/maix/Kconfig"
source "board/starfive/visionfive2/Kconfig"
@@ -185,18 +190,22 @@ config DMA_ADDR_T_64BIT
bool
default y if 64BIT
-config SIFIVE_CLINT
+config RISCV_ACLINT
bool
depends on RISCV_MMODE
+ select REGMAP
+ select SYSCON
help
- The SiFive CLINT block holds memory-mapped control and status registers
+ The RISC-V ACLINT block holds memory-mapped control and status registers
associated with software and timer interrupts.
-config SPL_SIFIVE_CLINT
+config SPL_RISCV_ACLINT
bool
depends on SPL_RISCV_MMODE
+ select SPL_REGMAP
+ select SPL_SYSCON
help
- The SiFive CLINT block holds memory-mapped control and status registers
+ The RISC-V ACLINT block holds memory-mapped control and status registers
associated with software and timer interrupts.
config SIFIVE_CACHE
diff --git a/arch/riscv/cpu/fu540/Kconfig b/arch/riscv/cpu/fu540/Kconfig
index 1604b412b48..c68209d8fb2 100644
--- a/arch/riscv/cpu/fu540/Kconfig
+++ b/arch/riscv/cpu/fu540/Kconfig
@@ -11,7 +11,7 @@ config SIFIVE_FU540
imply CPU
imply CPU_RISCV
imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
- imply SPL_SIFIVE_CLINT
+ imply SPL_RISCV_ACLINT
imply CMD_CPU
imply SPL_CPU
imply SPL_OPENSBI
diff --git a/arch/riscv/cpu/fu740/Kconfig b/arch/riscv/cpu/fu740/Kconfig
index 3e0c1fddc88..d7ca9687171 100644
--- a/arch/riscv/cpu/fu740/Kconfig
+++ b/arch/riscv/cpu/fu740/Kconfig
@@ -11,7 +11,7 @@ config SIFIVE_FU740
imply CPU
imply CPU_RISCV
imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
- imply SPL_SIFIVE_CLINT
+ imply SPL_RISCV_ACLINT
imply CMD_CPU
imply SPL_CPU
imply SPL_OPENSBI
diff --git a/arch/riscv/cpu/generic/Kconfig b/arch/riscv/cpu/generic/Kconfig
index e025134b23c..897765c3c68 100644
--- a/arch/riscv/cpu/generic/Kconfig
+++ b/arch/riscv/cpu/generic/Kconfig
@@ -9,8 +9,8 @@ config GENERIC_RISCV
imply CPU
imply CPU_RISCV
imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
- imply SIFIVE_CLINT if RISCV_MMODE
- imply SPL_SIFIVE_CLINT if SPL_RISCV_MMODE
+ imply RISCV_ACLINT if RISCV_MMODE
+ imply SPL_RISCV_ACLINT if SPL_RISCV_MMODE
imply CMD_CPU
imply SPL_CPU
imply SPL_OPENSBI
diff --git a/arch/riscv/cpu/jh7110/Kconfig b/arch/riscv/cpu/jh7110/Kconfig
index 3f145415eb9..4d9581165bf 100644
--- a/arch/riscv/cpu/jh7110/Kconfig
+++ b/arch/riscv/cpu/jh7110/Kconfig
@@ -25,4 +25,4 @@ config STARFIVE_JH7110
imply SPL_CPU
imply SPL_LOAD_FIT
imply SPL_OPENSBI
- imply SPL_SIFIVE_CLINT
+ imply SPL_RISCV_ACLINT
diff --git a/arch/riscv/cpu/jh7110/spl.c b/arch/riscv/cpu/jh7110/spl.c
index 104f0fe9497..72adcefa0e9 100644
--- a/arch/riscv/cpu/jh7110/spl.c
+++ b/arch/riscv/cpu/jh7110/spl.c
@@ -3,19 +3,49 @@
* Copyright (C) 2022 StarFive Technology Co., Ltd.
* Author: Yanhong Wang<yanhong.wang@starfivetech.com>
*/
-
+#include <common.h>
+#include <asm/arch/eeprom.h>
#include <asm/csr.h>
#include <asm/sections.h>
#include <dm.h>
+#include <linux/sizes.h>
#include <log.h>
+#include <init.h>
#define CSR_U74_FEATURE_DISABLE 0x7c1
#define L2_LIM_MEM_END 0x81FFFFFUL
+DECLARE_GLOBAL_DATA_PTR;
+
+static bool check_ddr_size(phys_size_t size)
+{
+ switch (size) {
+ case SZ_2:
+ case SZ_4:
+ case SZ_8:
+ case SZ_16:
+ return true;
+ default:
+ return false;
+ }
+}
+
int spl_soc_init(void)
{
int ret;
struct udevice *dev;
+ phys_size_t size;
+
+ ret = fdtdec_setup_mem_size_base();
+ if (ret)
+ return ret;
+
+ /* Read the definition of the DDR size from eeprom, and if not,
+ * use the definition in DT
+ */
+ size = (get_ddr_size_from_eeprom() >> 16) & 0xFF;
+ if (check_ddr_size(size))
+ gd->ram_size = size << 30;
/* DDR init */
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index 1d61eb80205..f1525cb6680 100644
--- a/arch/riscv/dts/Makefile
+++ b/arch/riscv/dts/Makefile
@@ -7,8 +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_VISIONFIVE2) += jh7110-starfive-visionfive-2-v1.3b.dtb
-dtb-$(CONFIG_TARGET_STARFIVE_VISIONFIVE2) += jh7110-starfive-visionfive-2-v1.2a.dtb
+dtb-$(CONFIG_TARGET_STARFIVE_VISIONFIVE2) += jh7110-starfive-visionfive-2.dtb
+dtb-$(CONFIG_TARGET_TH1520_LPI4A) += th1520-lichee-pi-4a.dtb
include $(srctree)/scripts/Makefile.dts
targets += $(dtb-y)
diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.3b-u-boot.dtsi b/arch/riscv/dts/jh7110-starfive-visionfive-2-u-boot.dtsi
index 3c322c5c972..13f69da31ec 100644
--- a/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.3b-u-boot.dtsi
+++ b/arch/riscv/dts/jh7110-starfive-visionfive-2-u-boot.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
*/
#include "binman.dtsi"
@@ -67,3 +67,40 @@
};
};
+&i2c5_pins {
+ bootph-pre-ram;
+ i2c-pins {
+ bootph-pre-ram;
+ };
+};
+
+&i2c5 {
+ bootph-pre-ram;
+ eeprom@50 {
+ bootph-pre-ram;
+ };
+};
+
+&binman {
+ itb {
+ fit {
+ images {
+ fdt-1 {
+ description = "NAME";
+ load = <0x40400000>;
+ compression = "none";
+
+ uboot_fdt_blob: blob-ext {
+ filename = "u-boot.dtb";
+ };
+ };
+ };
+
+ configurations {
+ conf-1 {
+ fdt = "fdt-1";
+ };
+ };
+ };
+ };
+};
diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.2a-u-boot.dtsi b/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.2a-u-boot.dtsi
deleted file mode 100644
index 3c322c5c972..00000000000
--- a/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.2a-u-boot.dtsi
+++ /dev/null
@@ -1,69 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR MIT
-/*
- * Copyright (C) 2022 StarFive Technology Co., Ltd.
- */
-
-#include "binman.dtsi"
-#include "jh7110-u-boot.dtsi"
-/ {
- chosen {
- bootph-pre-ram;
- };
-
- firmware {
- spi0 = &qspi;
- bootph-pre-ram;
- };
-
- config {
- bootph-pre-ram;
- u-boot,spl-payload-offset = <0x100000>;
- };
-
- memory@40000000 {
- bootph-pre-ram;
- };
-};
-
-&uart0 {
- bootph-pre-ram;
-};
-
-&mmc0 {
- bootph-pre-ram;
-};
-
-&mmc1 {
- bootph-pre-ram;
-};
-
-&qspi {
- bootph-pre-ram;
-
- nor-flash@0 {
- bootph-pre-ram;
- };
-};
-
-&sysgpio {
- bootph-pre-ram;
-};
-
-&mmc0_pins {
- bootph-pre-ram;
- mmc0-pins-rest {
- bootph-pre-ram;
- };
-};
-
-&mmc1_pins {
- bootph-pre-ram;
- mmc1-pins0 {
- bootph-pre-ram;
- };
-
- mmc1-pins1 {
- bootph-pre-ram;
- };
-};
-
diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.2a.dts b/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.2a.dts
deleted file mode 100644
index b9d26d7af7c..00000000000
--- a/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.2a.dts
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR MIT
-/*
- * Copyright (C) 2022 StarFive Technology Co., Ltd.
- */
-
-/dts-v1/;
-#include "jh7110-starfive-visionfive-2.dtsi"
-
-/ {
- model = "StarFive VisionFive 2 v1.2A";
- compatible = "starfive,visionfive-2-v1.2a", "starfive,jh7110";
-};
diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.3b.dts b/arch/riscv/dts/jh7110-starfive-visionfive-2.dts
index 3b3b3453a17..288ea394939 100644
--- a/arch/riscv/dts/jh7110-starfive-visionfive-2-v1.3b.dts
+++ b/arch/riscv/dts/jh7110-starfive-visionfive-2.dts
@@ -1,12 +1,11 @@
// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
*/
/dts-v1/;
#include "jh7110-starfive-visionfive-2.dtsi"
/ {
- model = "StarFive VisionFive 2 v1.3B";
compatible = "starfive,visionfive-2-v1.3b", "starfive,jh7110";
};
diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
index c6b6dfa9407..710b082766d 100644
--- a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
@@ -17,6 +17,8 @@
i2c2 = &i2c2;
i2c5 = &i2c5;
i2c6 = &i2c6;
+ ethernet0 = &gmac0;
+ ethernet1 = &gmac1;
};
chosen {
@@ -118,6 +120,12 @@
pinctrl-names = "default";
pinctrl-0 = <&i2c5_pins>;
status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c04";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
};
&i2c6 {
@@ -317,3 +325,35 @@
assigned-clock-parents = <&osc>;
assigned-clock-rates = <0>;
};
+
+&gmac0 {
+ phy-handle = <&phy0>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+};
+
+&gmac1 {
+ phy-handle = <&phy1>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ phy1: ethernet-phy@1 {
+ reg = <0>;
+ };
+ };
+};
diff --git a/arch/riscv/dts/jh7110.dtsi b/arch/riscv/dts/jh7110.dtsi
index bd60879615a..58e332e9d71 100644
--- a/arch/riscv/dts/jh7110.dtsi
+++ b/arch/riscv/dts/jh7110.dtsi
@@ -235,6 +235,13 @@
#clock-cells = <0>;
};
+ stmmac_axi_setup: stmmac-axi-config {
+ snps,lpi_en;
+ snps,wr_osr_lmt = <4>;
+ snps,rd_osr_lmt = <4>;
+ snps,blen = <256 128 64 32 0 0 0>;
+ };
+
soc {
compatible = "simple-bus";
interrupt-parent = <&plic>;
@@ -539,6 +546,68 @@
status = "disabled";
};
+ gmac0: ethernet@16030000 {
+ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
+ reg = <0x0 0x16030000 0x0 0x10000>;
+ clocks = <&aoncrg JH7110_AONCLK_GMAC0_AXI>,
+ <&aoncrg JH7110_AONCLK_GMAC0_AHB>,
+ <&syscrg JH7110_SYSCLK_GMAC0_PTP>,
+ <&aoncrg JH7110_AONCLK_GMAC0_TX_INV>,
+ <&syscrg JH7110_SYSCLK_GMAC0_GTXC>;
+ clock-names = "stmmaceth", "pclk", "ptp_ref",
+ "tx", "gtx";
+ resets = <&aoncrg JH7110_AONRST_GMAC0_AXI>,
+ <&aoncrg JH7110_AONRST_GMAC0_AHB>;
+ reset-names = "stmmaceth", "ahb";
+ interrupts = <7>, <6>, <5>;
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+ snps,multicast-filter-bins = <64>;
+ snps,perfect-filter-entries = <8>;
+ rx-fifo-depth = <2048>;
+ tx-fifo-depth = <2048>;
+ snps,fixed-burst;
+ snps,no-pbl-x8;
+ snps,force_thresh_dma_mode;
+ snps,axi-config = <&stmmac_axi_setup>;
+ snps,tso;
+ snps,en-tx-lpi-clockgating;
+ snps,txpbl = <16>;
+ snps,rxpbl = <16>;
+ starfive,syscon = <&aon_syscon 0xc 0x12>;
+ status = "disabled";
+ };
+
+ gmac1: ethernet@16040000 {
+ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
+ reg = <0x0 0x16040000 0x0 0x10000>;
+ clocks = <&syscrg JH7110_SYSCLK_GMAC1_AXI>,
+ <&syscrg JH7110_SYSCLK_GMAC1_AHB>,
+ <&syscrg JH7110_SYSCLK_GMAC1_PTP>,
+ <&syscrg JH7110_SYSCLK_GMAC1_TX_INV>,
+ <&syscrg JH7110_SYSCLK_GMAC1_GTXC>;
+ clock-names = "stmmaceth", "pclk", "ptp_ref",
+ "tx", "gtx";
+ resets = <&syscrg JH7110_SYSRST_GMAC1_AXI>,
+ <&syscrg JH7110_SYSRST_GMAC1_AHB>;
+ reset-names = "stmmaceth", "ahb";
+ interrupts = <78>, <77>, <76>;
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+ snps,multicast-filter-bins = <64>;
+ snps,perfect-filter-entries = <8>;
+ rx-fifo-depth = <2048>;
+ tx-fifo-depth = <2048>;
+ snps,fixed-burst;
+ snps,no-pbl-x8;
+ snps,force_thresh_dma_mode;
+ snps,axi-config = <&stmmac_axi_setup>;
+ snps,tso;
+ snps,en-tx-lpi-clockgating;
+ snps,txpbl = <16>;
+ snps,rxpbl = <16>;
+ starfive,syscon = <&sys_syscon 0x90 0x2>;
+ status = "disabled";
+ };
+
aoncrg: clock-controller@17000000 {
compatible = "starfive,jh7110-aoncrg";
reg = <0x0 0x17000000 0x0 0x10000>;
diff --git a/arch/riscv/dts/th1520-lichee-module-4a.dtsi b/arch/riscv/dts/th1520-lichee-module-4a.dtsi
new file mode 100644
index 00000000000..dc00e3dfa02
--- /dev/null
+++ b/arch/riscv/dts/th1520-lichee-module-4a.dtsi
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ */
+
+/dts-v1/;
+
+#include "th1520.dtsi"
+
+/ {
+ model = "Sipeed Lichee Module 4A";
+ compatible = "sipeed,lichee-module-4a", "thead,th1520";
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x00000000 0x2 0x00000000>;
+ };
+};
+
+&osc {
+ clock-frequency = <24000000>;
+};
+
+&osc_32k {
+ clock-frequency = <32768>;
+};
+
+&apb_clk {
+ clock-frequency = <62500000>;
+};
+
+&uart_sclk {
+ clock-frequency = <100000000>;
+};
diff --git a/arch/riscv/dts/th1520-lichee-pi-4a.dts b/arch/riscv/dts/th1520-lichee-pi-4a.dts
new file mode 100644
index 00000000000..a1248b2ee3a
--- /dev/null
+++ b/arch/riscv/dts/th1520-lichee-pi-4a.dts
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ */
+
+#include "th1520-lichee-module-4a.dtsi"
+
+/ {
+ model = "Sipeed Lichee Pi 4A";
+ compatible = "sipeed,lichee-pi-4a", "sipeed,lichee-module-4a", "thead,th1520";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ serial5 = &uart5;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/riscv/dts/th1520.dtsi b/arch/riscv/dts/th1520.dtsi
new file mode 100644
index 00000000000..f7bfa422439
--- /dev/null
+++ b/arch/riscv/dts/th1520.dtsi
@@ -0,0 +1,406 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited.
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "thead,th1520";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus: cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <3000000>;
+
+ c910_0: cpu@0 {
+ compatible = "thead,c910", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ reg = <0>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache>;
+ mmu-type = "riscv,sv39";
+
+ cpu0_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ c910_1: cpu@1 {
+ compatible = "thead,c910", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ reg = <1>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache>;
+ mmu-type = "riscv,sv39";
+
+ cpu1_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ c910_2: cpu@2 {
+ compatible = "thead,c910", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ reg = <2>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache>;
+ mmu-type = "riscv,sv39";
+
+ cpu2_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ c910_3: cpu@3 {
+ compatible = "thead,c910", "riscv";
+ device_type = "cpu";
+ riscv,isa = "rv64imafdc";
+ reg = <3>;
+ i-cache-block-size = <64>;
+ i-cache-size = <65536>;
+ i-cache-sets = <512>;
+ d-cache-block-size = <64>;
+ d-cache-size = <65536>;
+ d-cache-sets = <512>;
+ next-level-cache = <&l2_cache>;
+ mmu-type = "riscv,sv39";
+
+ cpu3_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ l2_cache: l2-cache {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <1048576>;
+ cache-sets = <1024>;
+ cache-unified;
+ };
+ };
+
+ osc: oscillator {
+ compatible = "fixed-clock";
+ clock-output-names = "osc_24m";
+ #clock-cells = <0>;
+ };
+
+ osc_32k: 32k-oscillator {
+ compatible = "fixed-clock";
+ clock-output-names = "osc_32k";
+ #clock-cells = <0>;
+ };
+
+ apb_clk: apb-clk-clock {
+ compatible = "fixed-clock";
+ clock-output-names = "apb_clk";
+ #clock-cells = <0>;
+ };
+
+ uart_sclk: uart-sclk-clock {
+ compatible = "fixed-clock";
+ clock-output-names = "uart_sclk";
+ #clock-cells = <0>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&plic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ plic: interrupt-controller@ffd8000000 {
+ compatible = "thead,th1520-plic", "thead,c900-plic";
+ reg = <0xff 0xd8000000 0x0 0x01000000>;
+ interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>,
+ <&cpu1_intc 11>, <&cpu1_intc 9>,
+ <&cpu2_intc 11>, <&cpu2_intc 9>,
+ <&cpu3_intc 11>, <&cpu3_intc 9>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ riscv,ndev = <240>;
+ };
+
+ clint: timer@ffdc000000 {
+ compatible = "thead,th1520-clint", "thead,c900-clint";
+ reg = <0xff 0xdc000000 0x0 0x00010000>;
+ interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>,
+ <&cpu1_intc 3>, <&cpu1_intc 7>,
+ <&cpu2_intc 3>, <&cpu2_intc 7>,
+ <&cpu3_intc 3>, <&cpu3_intc 7>;
+ };
+
+ uart0: serial@ffe7014000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xff 0xe7014000 0x0 0x100>;
+ interrupts = <36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uart_sclk>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart1: serial@ffe7f00000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xff 0xe7f00000 0x0 0x100>;
+ interrupts = <37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uart_sclk>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart3: serial@ffe7f04000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xff 0xe7f04000 0x0 0x100>;
+ interrupts = <39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uart_sclk>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ gpio2: gpio@ffe7f34000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xff 0xe7f34000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portc: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <58 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ gpio3: gpio@ffe7f38000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xff 0xe7f38000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portd: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <59 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ gpio0: gpio@ffec005000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xff 0xec005000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porta: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <56 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ gpio1: gpio@ffec006000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xff 0xec006000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portb: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <57 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ uart2: serial@ffec010000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xff 0xec010000 0x0 0x4000>;
+ interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uart_sclk>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ timer0: timer@ffefc32000 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0xff 0xefc32000 0x0 0x14>;
+ clocks = <&apb_clk>;
+ clock-names = "timer";
+ interrupts = <16 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ timer1: timer@ffefc32014 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0xff 0xefc32014 0x0 0x14>;
+ clocks = <&apb_clk>;
+ clock-names = "timer";
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ timer2: timer@ffefc32028 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0xff 0xefc32028 0x0 0x14>;
+ clocks = <&apb_clk>;
+ clock-names = "timer";
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ timer3: timer@ffefc3203c {
+ compatible = "snps,dw-apb-timer";
+ reg = <0xff 0xefc3203c 0x0 0x14>;
+ clocks = <&apb_clk>;
+ clock-names = "timer";
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ uart4: serial@fff7f08000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xff 0xf7f08000 0x0 0x4000>;
+ interrupts = <40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uart_sclk>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart5: serial@fff7f0c000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xff 0xf7f0c000 0x0 0x4000>;
+ interrupts = <41 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uart_sclk>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ timer4: timer@ffffc33000 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0xff 0xffc33000 0x0 0x14>;
+ clocks = <&apb_clk>;
+ clock-names = "timer";
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ timer5: timer@ffffc33014 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0xff 0xffc33014 0x0 0x14>;
+ clocks = <&apb_clk>;
+ clock-names = "timer";
+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ timer6: timer@ffffc33028 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0xff 0xffc33028 0x0 0x14>;
+ clocks = <&apb_clk>;
+ clock-names = "timer";
+ interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ timer7: timer@ffffc3303c {
+ compatible = "snps,dw-apb-timer";
+ reg = <0xff 0xffc3303c 0x0 0x14>;
+ clocks = <&apb_clk>;
+ clock-names = "timer";
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ ao_gpio0: gpio@fffff41000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xff 0xfff41000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porte: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <76 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ ao_gpio1: gpio@fffff52000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xff 0xfff52000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portf: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <55 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+ };
+};
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 00000000000..f354d5c60cd
--- /dev/null
+++ b/arch/riscv/include/asm/arch-jh7110/eeprom.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
+ * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
+ */
+
+#ifndef _ASM_RISCV_EEPROM_H
+#define _ASM_RISCV_EEPROM_H
+
+u8 get_pcb_revision_from_eeprom(void);
+u32 get_ddr_size_from_eeprom(void);
+
+#endif /* _ASM_RISCV_EEPROM_H */
diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
index 31ba72693d7..9d97517e124 100644
--- a/arch/riscv/include/asm/global_data.h
+++ b/arch/riscv/include/asm/global_data.h
@@ -18,8 +18,8 @@
struct arch_global_data {
long boot_hart; /* boot hart id */
phys_addr_t firmware_fdt_addr;
-#if CONFIG_IS_ENABLED(SIFIVE_CLINT)
- void __iomem *clint; /* clint base address */
+#if CONFIG_IS_ENABLED(RISCV_ACLINT)
+ void __iomem *aclint; /* aclint base address */
#endif
#ifdef CONFIG_ANDES_PLICSW
void __iomem *plicsw; /* andes plicsw base address */
diff --git a/arch/riscv/include/asm/syscon.h b/arch/riscv/include/asm/syscon.h
index f2b37975f37..5787702e746 100644
--- a/arch/riscv/include/asm/syscon.h
+++ b/arch/riscv/include/asm/syscon.h
@@ -12,7 +12,7 @@
*/
enum {
RISCV_NONE,
- RISCV_SYSCON_CLINT, /* Core Local Interruptor (CLINT) */
+ RISCV_SYSCON_ACLINT, /* Advanced Core Local Interruptor (ACLINT) */
RISCV_SYSCON_PLICSW, /* Andes PLICSW */
};
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index e5a81ba7223..02c4d8fcc6c 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_CMD_GO) += boot.o
obj-y += cache.o
obj-$(CONFIG_SIFIVE_CACHE) += sifive_cache.o
ifeq ($(CONFIG_$(SPL_)RISCV_MMODE),y)
-obj-$(CONFIG_$(SPL_)SIFIVE_CLINT) += sifive_clint.o
+obj-$(CONFIG_$(SPL_)RISCV_ACLINT) += aclint_ipi.o
obj-$(CONFIG_ANDES_PLICSW) += andes_plicsw.o
else
obj-$(CONFIG_SBI) += sbi.o
diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/aclint_ipi.c
index ab22395c552..90b8e128cb1 100644
--- a/arch/riscv/lib/sifive_clint.c
+++ b/arch/riscv/lib/aclint_ipi.c
@@ -10,9 +10,12 @@
#include <common.h>
#include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/smp.h>
+#include <asm/syscon.h>
#include <linux/err.h>
/* MSIP registers */
@@ -26,12 +29,16 @@ int riscv_init_ipi(void)
struct udevice *dev;
ret = uclass_get_device_by_driver(UCLASS_TIMER,
- DM_DRIVER_GET(sifive_clint), &dev);
+ DM_DRIVER_GET(riscv_aclint_timer), &dev);
if (ret)
return ret;
- gd->arch.clint = dev_read_addr_ptr(dev);
- if (!gd->arch.clint)
+ if (dev_get_driver_data(dev) != 0)
+ gd->arch.aclint = dev_read_addr_ptr(dev);
+ else
+ gd->arch.aclint = syscon_get_first_range(RISCV_SYSCON_ACLINT);
+
+ if (!gd->arch.aclint)
return -EINVAL;
return 0;
@@ -39,21 +46,33 @@ int riscv_init_ipi(void)
int riscv_send_ipi(int hart)
{
- writel(1, (void __iomem *)MSIP_REG(gd->arch.clint, hart));
+ writel(1, (void __iomem *)MSIP_REG(gd->arch.aclint, hart));
return 0;
}
int riscv_clear_ipi(int hart)
{
- writel(0, (void __iomem *)MSIP_REG(gd->arch.clint, hart));
+ writel(0, (void __iomem *)MSIP_REG(gd->arch.aclint, hart));
return 0;
}
int riscv_get_ipi(int hart, int *pending)
{
- *pending = readl((void __iomem *)MSIP_REG(gd->arch.clint, hart));
+ *pending = readl((void __iomem *)MSIP_REG(gd->arch.aclint, hart));
return 0;
}
+
+static const struct udevice_id riscv_aclint_swi_ids[] = {
+ { .compatible = "riscv,aclint-mswi", .data = RISCV_SYSCON_ACLINT },
+ { }
+};
+
+U_BOOT_DRIVER(riscv_aclint_swi) = {
+ .name = "riscv_aclint_swi",
+ .id = UCLASS_SYSCON,
+ .of_match = riscv_aclint_swi_ids,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/arch/sandbox/cpu/sdl.c b/arch/sandbox/cpu/sdl.c
index 2c570ed8d16..590e406517b 100644
--- a/arch/sandbox/cpu/sdl.c
+++ b/arch/sandbox/cpu/sdl.c
@@ -6,6 +6,7 @@
#include <errno.h>
#include <unistd.h>
#include <stdbool.h>
+#include <sysreset.h>
#include <linux/input.h>
#include <SDL2/SDL.h>
#include <asm/state.h>
@@ -81,7 +82,7 @@ static void sandbox_sdl_poll_events(void)
switch (event.type) {
case SDL_QUIT:
puts("LCD window closed - quitting\n");
- reset_cpu();
+ sysreset_walk(SYSRESET_POWER_OFF);
break;
}
}
diff --git a/arch/sandbox/dts/cedit.dtsi b/arch/sandbox/dts/cedit.dtsi
new file mode 100644
index 00000000000..a9eb4c2d594
--- /dev/null
+++ b/arch/sandbox/dts/cedit.dtsi
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Expo definition for the configuration editor
+ *
+ * This used for testing building an expo from a data file. This devicetree
+ * provides a description of the objects to be created.
+ */
+
+#include <test/cedit-test.h>
+
+&cedit {
+ dynamic-start = <ID_DYNAMIC_START>;
+
+ scenes {
+ main {
+ id = <ID_SCENE1>;
+
+ /* value refers to the matching id in /strings */
+ title-id = <ID_SCENE1_TITLE>;
+
+ /* simple string is used as it is */
+ prompt = "UP and DOWN to choose, ENTER to select";
+
+ /* defines a menu within the scene */
+ cpu-speed {
+ type = "menu";
+ id = <ID_CPU_SPEED>;
+
+ /*
+ * has both string and ID. The string is ignored
+ * if the ID is present and points to a string
+ */
+ title = "CPU speed";
+ title-id = <ID_CPU_SPEED_TITLE>;
+
+ /* menu items as simple strings */
+ item-label = "2 GHz", "2.5 GHz", "3 GHz";
+
+ /* IDs for the menu items */
+ item-id = <ID_CPU_SPEED_1 ID_CPU_SPEED_2
+ ID_CPU_SPEED_3>;
+ };
+
+ power-loss {
+ type = "menu";
+ id = <ID_POWER_LOSS>;
+
+ title = "AC Power";
+ item-label = "Always Off", "Always On",
+ "Memory";
+
+ item-id = <ID_AC_OFF ID_AC_ON ID_AC_MEMORY>;
+ };
+ };
+ };
+
+ strings {
+ title {
+ id = <ID_SCENE1_TITLE>;
+ value = "Test Configuration";
+ value-es = "configuración de prueba";
+ };
+ };
+};
diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index 30a305c4d20..f0ee0b3481a 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -16,6 +16,12 @@
stdout-path = "/serial";
};
+ cedit-theme {
+ font-size = <30>;
+ menu-inset = <3>;
+ menuitem-gap-y = <1>;
+ };
+
alarm_wdt: alarm-wdt {
compatible = "sandbox,alarm-wdt";
timeout-sec = <5>;
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index ff9f9222e6f..b5509eee8cf 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -96,6 +96,8 @@
theme {
font-size = <30>;
+ menu-inset = <3>;
+ menuitem-gap-y = <1>;
};
/*
@@ -139,6 +141,15 @@
};
};
+ cedit: cedit {
+ };
+
+ cedit-theme {
+ font-size = <30>;
+ menu-inset = <3>;
+ menuitem-gap-y = <1>;
+ };
+
fuzzing-engine {
compatible = "sandbox,fuzzing-engine";
};
@@ -1828,3 +1839,5 @@
#ifdef CONFIG_SANDBOX_VPL
#include "sandbox_vpl.dtsi"
#endif
+
+#include "cedit.dtsi"
diff --git a/board/advantech/imx8qm_dmsse20_a1/spl.c b/board/advantech/imx8qm_dmsse20_a1/spl.c
index 7f2e972425b..f36caece7d7 100644
--- a/board/advantech/imx8qm_dmsse20_a1/spl.c
+++ b/board/advantech/imx8qm_dmsse20_a1/spl.c
@@ -111,7 +111,7 @@ int board_mmc_init(struct bd_info *bis)
switch (i) {
case 0:
ret = sc_pm_set_resource_power_mode(-1, SC_R_SDHC_0, SC_PM_PW_MODE_ON);
- if (ret != SC_ERR_NONE)
+ if (ret)
return ret;
imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0));
@@ -120,10 +120,10 @@ int board_mmc_init(struct bd_info *bis)
break;
case 1:
ret = sc_pm_set_resource_power_mode(-1, SC_R_SDHC_2, SC_PM_PW_MODE_ON);
- if (ret != SC_ERR_NONE)
+ if (ret)
return ret;
ret = sc_pm_set_resource_power_mode(-1, SC_R_GPIO_4, SC_PM_PW_MODE_ON);
- if (ret != SC_ERR_NONE)
+ if (ret)
return ret;
imx8_iomux_setup_multiple_pads(usdhc2_sd, ARRAY_SIZE(usdhc2_sd));
diff --git a/board/advantech/imx8qm_rom7720_a1/spl.c b/board/advantech/imx8qm_rom7720_a1/spl.c
index b602437c35b..922bb0b7d43 100644
--- a/board/advantech/imx8qm_rom7720_a1/spl.c
+++ b/board/advantech/imx8qm_rom7720_a1/spl.c
@@ -112,7 +112,7 @@ int board_mmc_init(struct bd_info *bis)
switch (i) {
case 0:
ret = sc_pm_set_resource_power_mode(-1, SC_R_SDHC_0, SC_PM_PW_MODE_ON);
- if (ret != SC_ERR_NONE)
+ if (ret)
return ret;
imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0));
@@ -121,10 +121,10 @@ int board_mmc_init(struct bd_info *bis)
break;
case 1:
ret = sc_pm_set_resource_power_mode(-1, SC_R_SDHC_2, SC_PM_PW_MODE_ON);
- if (ret != SC_ERR_NONE)
+ if (ret)
return ret;
ret = sc_pm_set_resource_power_mode(-1, SC_R_GPIO_4, SC_PM_PW_MODE_ON);
- if (ret != SC_ERR_NONE)
+ if (ret)
return ret;
imx8_iomux_setup_multiple_pads(usdhc2_sd, ARRAY_SIZE(usdhc2_sd));
diff --git a/board/alliedtelesis/x240/MAINTAINERS b/board/alliedtelesis/x240/MAINTAINERS
new file mode 100644
index 00000000000..f1f78d96167
--- /dev/null
+++ b/board/alliedtelesis/x240/MAINTAINERS
@@ -0,0 +1,7 @@
+X240 BOARD
+M: Chris Packham <chris.packham@alliedtelesis.co.nz>
+S: Maintained
+F: board/alliedtelesis/x240/
+F: arch/arm/dts/ac5-98dx35xx-rd.dts
+F: include/configs/x240.h
+F: configs/x240_defconfig
diff --git a/board/alliedtelesis/x240/Makefile b/board/alliedtelesis/x240/Makefile
new file mode 100644
index 00000000000..7f20a47d6a7
--- /dev/null
+++ b/board/alliedtelesis/x240/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2022 Allied Telesis
+#
+
+obj-y += x240.o
diff --git a/board/alliedtelesis/x240/x240.c b/board/alliedtelesis/x240/x240.c
new file mode 100644
index 00000000000..0c4f8e03b85
--- /dev/null
+++ b/board/alliedtelesis/x240/x240.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <common.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+ gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100;
+
+ return 0;
+}
diff --git a/board/beacon/imx8mm/MAINTAINERS b/board/beacon/imx8mm/MAINTAINERS
index e887db20a21..d48ba8605bb 100644
--- a/board/beacon/imx8mm/MAINTAINERS
+++ b/board/beacon/imx8mm/MAINTAINERS
@@ -5,3 +5,4 @@ S: Maintained
F: board/beacon/imx8mm/
F: include/configs/imx8mm_beacon.h
F: configs/imx8mm_beacon_defconfig
+F: doc/board/beacon/
diff --git a/board/beacon/imx8mm/README b/board/beacon/imx8mm/README
deleted file mode 100644
index 32b24bc03eb..00000000000
--- a/board/beacon/imx8mm/README
+++ /dev/null
@@ -1,37 +0,0 @@
-U-Boot for the Beacon EmbeddedWorks Devkit
-
-Quick Start
-===========
-- Build the ARM Trusted firmware binary
-- Get ddr firmware
-- Build U-Boot
-- Boot
-
-Get and Build the ARM Trusted firmware
-======================================
-Note: $(srctree) is U-Boot source directory
-
-$ git clone https://github.com/nxp-imx/imx-atf
-$ git lf-5.10.72-2.2.0
-$ make PLAT=imx8mm bl31 CROSS_COMPILE=aarch64-linux-gnu-
-$ cp build/imx8mm/release/bl31.bin $(srctree)
-
-Get the DDR firmware
-====================
-$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.9.bin
-$ chmod +x firmware-imx-8.9.bin
-$ ./firmware-imx-8.9
-$ cp firmware-imx-8.9/firmware/ddr/synopsys/lpddr4*.bin $(srctree)
-
-Build U-Boot
-============
-$ make imx8mm_beacon_defconfig
-$ make CROSS_COMPILE=aarch64-linux-gnu-
-
-Burn U-Boot to microSD Card
-===========================
-$ sudo dd if=flash.bin of=/dev/sd[x] bs=1024 seek=33
-
-Boot
-====
-Set Boot switch to SD boot
diff --git a/board/beacon/imx8mm/imx8mm_beacon.env b/board/beacon/imx8mm/imx8mm_beacon.env
new file mode 100644
index 00000000000..00bf67edd5b
--- /dev/null
+++ b/board/beacon/imx8mm/imx8mm_beacon.env
@@ -0,0 +1,19 @@
+boot_fit=try
+bootscript=echo Running bootscript from mmc ...; source
+console=ttymxc1
+fdt_addr=0x45000000
+fdt_file=imx8mm-beacon-kit.dtb
+finduuid=part uuid mmc ${mmcdev}:2 uuid
+image=Image
+initrd_addr=0x46000000
+loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
+loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
+loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
+mmcargs=setenv bootargs console=${console},${baudrate} root=PARTUUID=${uuid} rootwait rw ${mtdparts} ${optargs}
+mmcautodetect=yes
+mmcboot=echo Booting from mmc ...; run finduuid; run mmcargs; if run loadfdt; then booti ${loadaddr} - ${fdt_addr}; else echo WARN: Cannot load the DT; fi;
+netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
+mmcdev=1
+mmcpart=1
+netboot=echo Booting from net ...; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${loadaddr} ${image}; if test ${boot_fit} = yes || test ${boot_fit} = try; then bootm ${loadaddr}; else if ${get_cmd} ${fdt_addr} ${fdt_file}; then booti ${loadaddr} - ${fdt_addr}; else echo WARN: Cannot load the DT; fi; fi;
+script=boot.scr
diff --git a/board/beacon/imx8mm/spl.c b/board/beacon/imx8mm/spl.c
index a5f337aa17c..b2830c5223a 100644
--- a/board/beacon/imx8mm/spl.c
+++ b/board/beacon/imx8mm/spl.c
@@ -36,6 +36,8 @@ int spl_board_boot_device(enum boot_device boot_dev_spl)
return BOOT_DEVICE_MMC2;
case USB_BOOT:
return BOOT_DEVICE_BOARD;
+ case QSPI_BOOT:
+ return BOOT_DEVICE_NOR;
default:
return BOOT_DEVICE_NONE;
}
@@ -46,6 +48,11 @@ static void spl_dram_init(void)
ddr_init(&dram_timing);
}
+void spl_board_init(void)
+{
+ arch_misc_init();
+}
+
#ifdef CONFIG_SPL_LOAD_FIT
int board_fit_config_name_match(const char *name)
{
diff --git a/board/beacon/imx8mn/README b/board/beacon/imx8mn/README
deleted file mode 100644
index 49da03c8d83..00000000000
--- a/board/beacon/imx8mn/README
+++ /dev/null
@@ -1,38 +0,0 @@
-U-Boot for the Beacon EmbeddedWorks i.MX8M Nano Devkit
-
-Quick Start
-===========
-- Build the ARM Trusted firmware binary
-- Get ddr firmware
-- Build U-Boot
-- Boot
-
-Get and Build the ARM Trusted firmware
-======================================
-Note: $(srctree) is U-Boot source directory
-
-$ git clone https://github.com/nxp-imx/imx-atf
-$ git lf-5.10.72-2.2.0
-$ make PLAT=imx8mn bl31 CROSS_COMPILE=aarch64-linux-gnu-
-$ cp build/imx8mn/release/bl31.bin $(srctree)
-
-Get the DDR firmware
-====================
-$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.9.bin
-$ chmod +x firmware-imx-8.9.bin
-$ ./firmware-imx-8.9
-$ cp firmware-imx-8.9/firmware/ddr/synopsys/lpddr4*.bin $(srctree)
-
-Build U-Boot
-============
-$ make imx8mn_beacon_defconfig
-$ make CROSS_COMPILE=aarch64-linux-gnu-
-
-Burn U-Boot to microSD Card
-===========================
-$ sudo dd if=flash.bin of=/dev/sd[x] bs=1024 seek=32
-
-Boot
-====
-Set baseboard DIP switch:
-S17: 1100XXXX
diff --git a/board/beacon/imx8mn/imx8mn_beacon.env b/board/beacon/imx8mn/imx8mn_beacon.env
new file mode 100644
index 00000000000..ca90053d477
--- /dev/null
+++ b/board/beacon/imx8mn/imx8mn_beacon.env
@@ -0,0 +1,25 @@
+boot_fdt=try
+bootdelay=2
+bootscript=echo Running bootscript from mmc ...; source
+console=ttymxc1
+fdt_addr=0x45000000
+fdt_file=imx8mn-beacon-kit.dtb
+finduuid=part uuid mmc ${mmcdev}:2 uuid
+image=Image
+initrd_addr=0x46000000
+loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
+loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
+loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
+loadramdisk=load mmc ${mmcdev} ${ramdisk_addr} ${ramdiskimage}
+mmcargs=setenv bootargs console=${console},${baudrate} root=PARTUUID=${uuid} rootwait rw ${mtdparts} ${optargs}
+mmcautodetect=yes
+mmcboot=echo Booting from mmc ...; run finduuid; run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then booti ${loadaddr} - ${fdt_addr}; else echo WARN: Cannot load the DT; fi; else echo wait for boot; fi;
+mmcdev=1
+mmcpart=1
+netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
+netboot=echo Booting from net ...; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${loadaddr} ${image}; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then booti ${loadaddr} - ${fdt_addr}; else echo WARN: Cannot load the DT; fi; else booti; fi;
+ramargs=setenv bootargs console=${console},${baudrate} root=/dev/ram rw ${optargs}
+ramboot=echo Booting from RAMdisk...; run loadimage; run loadfdt; fdt addr $fdt_addr; run loadramdisk; run ramargs; booti ${loadaddr} ${ramdisk_addr} ${fdt_addr} ${optargs}
+ramdisk_addr=0x46000000
+ramdiskimage=rootfs.cpio.uboot
+script=boot.scr
diff --git a/board/congatec/cgtqmx8/cgtqmx8.c b/board/congatec/cgtqmx8/cgtqmx8.c
index bedd1e03308..26189ff66f5 100644
--- a/board/congatec/cgtqmx8/cgtqmx8.c
+++ b/board/congatec/cgtqmx8/cgtqmx8.c
@@ -79,7 +79,7 @@ static void setup_iomux_uart(void)
int board_early_init_f(void)
{
/* sc_ipc_t ipcHndl = 0; */
- sc_err_t scierr = 0;
+ int scierr;
/* When start u-boot in XEN VM, directly return */
/* if (IS_ENABLED(CONFIG_XEN)) */
@@ -89,19 +89,19 @@ int board_early_init_f(void)
/* Power up UART0, this is very early while power domain is not working */
scierr = sc_pm_set_resource_power_mode(-1, SC_R_UART_0, SC_PM_PW_MODE_ON);
- if (scierr != SC_ERR_NONE)
+ if (scierr)
return 0;
/* Set UART0 clock root to 80 MHz */
sc_pm_clock_rate_t rate = 80000000;
scierr = sc_pm_set_clock_rate(-1, SC_R_UART_0, 2, &rate);
- if (scierr != SC_ERR_NONE)
+ if (scierr)
return 0;
/* Enable UART0 clock root */
scierr = sc_pm_clock_enable(-1, SC_R_UART_0, 2, true, false);
- if (scierr != SC_ERR_NONE)
+ if (scierr)
return 0;
setup_iomux_uart();
diff --git a/board/data_modul/imx8mp_edm_sbc/spl.c b/board/data_modul/imx8mp_edm_sbc/spl.c
index c30185e48d4..2fdd95a730c 100644
--- a/board/data_modul/imx8mp_edm_sbc/spl.c
+++ b/board/data_modul/imx8mp_edm_sbc/spl.c
@@ -107,6 +107,20 @@ void board_boot_order(u32 *spl_boot_list)
spl_boot_list[4] = BOOT_DEVICE_NONE;
}
+unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc, unsigned long sect)
+{
+ const u32 boot_dev = spl_boot_device();
+ int part;
+
+ if (boot_dev == BOOT_DEVICE_MMC2) { /* eMMC */
+ part = spl_mmc_emmc_boot_partition(mmc);
+ if (part == 1 || part == 2) /* eMMC BOOT1/BOOT2 HW partitions */
+ return sect - 0x40;
+ }
+
+ return sect;
+}
+
static struct dram_timing_info *dram_timing_info[8] = {
&dmo_imx8mp_sbc_dram_timing_32_32, /* 32 Gbit x32 */
NULL, /* 32 Gbit x16 */
diff --git a/board/freescale/imx8ulp_evk/spl.c b/board/freescale/imx8ulp_evk/spl.c
index a0dad5f9831..66d0f68cc62 100644
--- a/board/freescale/imx8ulp_evk/spl.c
+++ b/board/freescale/imx8ulp_evk/spl.c
@@ -19,7 +19,7 @@
#include <asm/arch/ddr.h>
#include <asm/arch/rdc.h>
#include <asm/arch/upower.h>
-#include <asm/mach-imx/s400_api.h>
+#include <asm/mach-imx/ele_api.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -63,9 +63,9 @@ void display_ele_fw_version(void)
u32 fw_version, sha1, res;
int ret;
- ret = ahab_get_fw_version(&fw_version, &sha1, &res);
+ ret = ele_get_fw_version(&fw_version, &sha1, &res);
if (ret) {
- printf("ahab get firmware version failed %d, 0x%x\n", ret, res);
+ printf("ele get firmware version failed %d, 0x%x\n", ret, res);
} else {
printf("ELE firmware version %u.%u.%u-%x",
(fw_version & (0x00ff0000)) >> 16,
@@ -120,9 +120,19 @@ void spl_board_init(void)
set_lpav_qos();
/* Enable A35 access to the CAAM */
- ret = ahab_release_caam(0x7, &res);
+ ret = ele_release_caam(0x7, &res);
if (ret)
- printf("ahab release caam failed %d, 0x%x\n", ret, res);
+ printf("ele release caam failed %d, 0x%x\n", ret, res);
+
+ /*
+ * RNG start only available on the A1 soc revision.
+ * Check some JTAG register for the SoC revision.
+ */
+ if (!is_soc_rev(CHIP_REV_1_0)) {
+ ret = ele_start_rng();
+ if (ret)
+ printf("Fail to start RNG: %d\n", ret);
+ }
}
void board_init_f(ulong dummy)
diff --git a/board/freescale/imx93_evk/spl.c b/board/freescale/imx93_evk/spl.c
index 352ad79cb67..63883b30dd7 100644
--- a/board/freescale/imx93_evk/spl.c
+++ b/board/freescale/imx93_evk/spl.c
@@ -20,7 +20,6 @@
#include <asm/mach-imx/mxc_i2c.h>
#include <asm/arch-mx7ulp/gpio.h>
#include <asm/mach-imx/syscounter.h>
-#include <asm/mach-imx/s400_api.h>
#include <dm/uclass.h>
#include <dm/device.h>
#include <dm/uclass-internal.h>
diff --git a/board/freescale/mx7dsabresd/mx7dsabresd.c b/board/freescale/mx7dsabresd/mx7dsabresd.c
index 2777ae13bce..cff2e6a8717 100644
--- a/board/freescale/mx7dsabresd/mx7dsabresd.c
+++ b/board/freescale/mx7dsabresd/mx7dsabresd.c
@@ -292,6 +292,7 @@ int power_init_board(void)
int board_late_init(void)
{
struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
+ unsigned char eth1addr[6];
imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads));
@@ -303,6 +304,11 @@ int board_late_init(void)
*/
clrsetbits_le16(&wdog->wcr, 0, 0x10);
+ /* Get the second MAC address */
+ imx_get_mac_from_fuse(1, eth1addr);
+ if (!env_get("eth1addr") && is_valid_ethaddr(eth1addr))
+ eth_env_set_enetaddr("eth1addr", eth1addr);
+
return 0;
}
diff --git a/board/gateworks/venice/eeprom.c b/board/gateworks/venice/eeprom.c
index 6aea60ad05c..241be4ee630 100644
--- a/board/gateworks/venice/eeprom.c
+++ b/board/gateworks/venice/eeprom.c
@@ -218,6 +218,11 @@ const char *eeprom_get_dtb_name(int level, char *buf, int sz)
int rev_base_bom = get_bom_rev(base_info.model);
snprintf(buf, sz, "%s%2dxx-%dx", pre, base, som);
+ /* GW79xx baseboards have no build options */
+ if (base == 79) {
+ base = (int)strtoul(base_info.model + 2, NULL, 10);
+ snprintf(buf, sz, "%s%4d-%dx", pre, base, som);
+ }
switch (level) {
case 0: /* full model (ie gw73xx-0x-a1a1) */
if (rev_base_bom)
diff --git a/board/gateworks/venice/lpddr4_timing.h b/board/gateworks/venice/lpddr4_timing.h
index 62b860610c5..d19902f10ec 100644
--- a/board/gateworks/venice/lpddr4_timing.h
+++ b/board/gateworks/venice/lpddr4_timing.h
@@ -16,6 +16,7 @@ extern struct dram_timing_info dram_timing_1gb_single_die;
extern struct dram_timing_info dram_timing_2gb_single_die;
extern struct dram_timing_info dram_timing_2gb_dual_die;
#elif CONFIG_IMX8MP
+extern struct dram_timing_info dram_timing_1gb_single_die;
extern struct dram_timing_info dram_timing_4gb_dual_die;
#endif
diff --git a/board/gateworks/venice/lpddr4_timing_imx8mp.c b/board/gateworks/venice/lpddr4_timing_imx8mp.c
index 2e96332f8b5..7bfd1b556bb 100644
--- a/board/gateworks/venice/lpddr4_timing_imx8mp.c
+++ b/board/gateworks/venice/lpddr4_timing_imx8mp.c
@@ -1315,6 +1315,538 @@ static struct dram_cfg_param ddr_phy_pie[] = {
};
/*
+ * Generated code from MX8M_DDR_tool v3.30 using MX8MP Plus RPAv9
+ * - 1GiB: ixm8mp-gw7020 1x Micron MT53E256M32D2DS 2-ch single-die per channel
+ */
+struct dram_cfg_param ddr_ddrc_cfg_1gb_single_die[] = {
+ /** Initialize DDRC registers **/
+ { 0x3d400304, 0x1 },
+ { 0x3d400030, 0x1 },
+ { 0x3d400000, 0xa1080020 },
+ { 0x3d400020, 0x1203 },
+ { 0x3d400024, 0x16e3600 },
+ { 0x3d400064, 0x5b0087 },
+ { 0x3d400070, 0x7027f90 },
+ { 0x3d400074, 0x790 },
+ { 0x3d4000d0, 0xc00305ba },
+ { 0x3d4000d4, 0x940000 },
+ { 0x3d4000dc, 0xd4002d },
+ { 0x3d4000e0, 0x310000 },
+ { 0x3d4000e8, 0x660048 },
+ { 0x3d4000ec, 0x160048 },
+ { 0x3d400100, 0x191e1920 },
+ { 0x3d400104, 0x60630 },
+ { 0x3d40010c, 0xb0b000 },
+ { 0x3d400110, 0xe04080e },
+ { 0x3d400114, 0x2040c0c },
+ { 0x3d400118, 0x1010007 },
+ { 0x3d40011c, 0x402 },
+ { 0x3d400130, 0x20600 },
+ { 0x3d400134, 0xc100002 },
+ { 0x3d400138, 0x8d },
+ { 0x3d400144, 0x96004b },
+ { 0x3d400180, 0x2ee0017 },
+ { 0x3d400184, 0x2605b8e },
+ { 0x3d400188, 0x0 },
+ { 0x3d400190, 0x497820a },
+ { 0x3d400194, 0x80303 },
+ { 0x3d4001b4, 0x170a },
+ { 0x3d4001a0, 0xe0400018 },
+ { 0x3d4001a4, 0xdf00e4 },
+ { 0x3d4001a8, 0x80000000 },
+ { 0x3d4001b0, 0x11 },
+ { 0x3d4001c0, 0x1 },
+ { 0x3d4001c4, 0x1 },
+ { 0x3d4000f4, 0x699 },
+ { 0x3d400108, 0x70e1617 },
+ { 0x3d400200, 0x1f },
+ { 0x3d400208, 0x0 },
+ { 0x3d40020c, 0x0 },
+ { 0x3d400210, 0x1f1f },
+ { 0x3d400204, 0x80808 },
+ { 0x3d400214, 0x7070707 },
+ { 0x3d400218, 0xf070707 },
+ { 0x3d40021c, 0xf0f },
+ { 0x3d400250, 0x1705 },
+ { 0x3d400254, 0x2c },
+ { 0x3d40025c, 0x4000030 },
+ { 0x3d400264, 0x900093e7 },
+ { 0x3d40026c, 0x2005574 },
+ { 0x3d400400, 0x111 },
+ { 0x3d400404, 0x72ff },
+ { 0x3d400408, 0x72ff },
+ { 0x3d400494, 0x2100e07 },
+ { 0x3d400498, 0x620096 },
+ { 0x3d40049c, 0x1100e07 },
+ { 0x3d4004a0, 0xc8012c },
+ { 0x3d402020, 0x1001 },
+ { 0x3d402024, 0x30d400 },
+ { 0x3d402050, 0x20d000 },
+ { 0x3d402064, 0xc0012 },
+ { 0x3d4020dc, 0x840000 },
+ { 0x3d4020e0, 0x330000 },
+ { 0x3d4020e8, 0x660048 },
+ { 0x3d4020ec, 0x160048 },
+ { 0x3d402100, 0xa040305 },
+ { 0x3d402104, 0x30407 },
+ { 0x3d402108, 0x203060b },
+ { 0x3d40210c, 0x505000 },
+ { 0x3d402110, 0x2040202 },
+ { 0x3d402114, 0x2030202 },
+ { 0x3d402118, 0x1010004 },
+ { 0x3d40211c, 0x302 },
+ { 0x3d402130, 0x20300 },
+ { 0x3d402134, 0xa100002 },
+ { 0x3d402138, 0x13 },
+ { 0x3d402144, 0x14000a },
+ { 0x3d402180, 0x640004 },
+ { 0x3d402190, 0x3818200 },
+ { 0x3d402194, 0x80303 },
+ { 0x3d4021b4, 0x100 },
+ { 0x3d4020f4, 0x599 },
+ { 0x3d403020, 0x1001 },
+ { 0x3d403024, 0xc3500 },
+ { 0x3d403050, 0x20d000 },
+ { 0x3d403064, 0x30005 },
+ { 0x3d4030dc, 0x840000 },
+ { 0x3d4030e0, 0x330000 },
+ { 0x3d4030e8, 0x660048 },
+ { 0x3d4030ec, 0x160048 },
+ { 0x3d403100, 0xa010102 },
+ { 0x3d403104, 0x30404 },
+ { 0x3d403108, 0x203060b },
+ { 0x3d40310c, 0x505000 },
+ { 0x3d403110, 0x2040202 },
+ { 0x3d403114, 0x2030202 },
+ { 0x3d403118, 0x1010004 },
+ { 0x3d40311c, 0x302 },
+ { 0x3d403130, 0x20300 },
+ { 0x3d403134, 0xa100002 },
+ { 0x3d403138, 0x5 },
+ { 0x3d403144, 0x50003 },
+ { 0x3d403180, 0x190004 },
+ { 0x3d403190, 0x3818200 },
+ { 0x3d403194, 0x80303 },
+ { 0x3d4031b4, 0x100 },
+ { 0x3d4030f4, 0x599 },
+ { 0x3d400028, 0x0 },
+};
+
+/* PHY Initialize Configuration */
+struct dram_cfg_param ddr_ddrphy_cfg_1gb_single_die[] = {
+ { 0x100a0, 0x0 },
+ { 0x100a1, 0x1 },
+ { 0x100a2, 0x3 },
+ { 0x100a3, 0x2 },
+ { 0x100a4, 0x5 },
+ { 0x100a5, 0x4 },
+ { 0x100a6, 0x7 },
+ { 0x100a7, 0x6 },
+ { 0x110a0, 0x0 },
+ { 0x110a1, 0x1 },
+ { 0x110a2, 0x2 },
+ { 0x110a3, 0x3 },
+ { 0x110a4, 0x4 },
+ { 0x110a5, 0x5 },
+ { 0x110a6, 0x6 },
+ { 0x110a7, 0x7 },
+ { 0x120a0, 0x0 },
+ { 0x120a1, 0x1 },
+ { 0x120a2, 0x2 },
+ { 0x120a3, 0x3 },
+ { 0x120a4, 0x4 },
+ { 0x120a5, 0x5 },
+ { 0x120a6, 0x6 },
+ { 0x120a7, 0x7 },
+ { 0x130a0, 0x0 },
+ { 0x130a1, 0x1 },
+ { 0x130a2, 0x3 },
+ { 0x130a3, 0x4 },
+ { 0x130a4, 0x5 },
+ { 0x130a5, 0x2 },
+ { 0x130a6, 0x7 },
+ { 0x130a7, 0x6 },
+ { 0x1005f, 0x1ff },
+ { 0x1015f, 0x1ff },
+ { 0x1105f, 0x1ff },
+ { 0x1115f, 0x1ff },
+ { 0x1205f, 0x1ff },
+ { 0x1215f, 0x1ff },
+ { 0x1305f, 0x1ff },
+ { 0x1315f, 0x1ff },
+ { 0x11005f, 0x1ff },
+ { 0x11015f, 0x1ff },
+ { 0x11105f, 0x1ff },
+ { 0x11115f, 0x1ff },
+ { 0x11205f, 0x1ff },
+ { 0x11215f, 0x1ff },
+ { 0x11305f, 0x1ff },
+ { 0x11315f, 0x1ff },
+ { 0x21005f, 0x1ff },
+ { 0x21015f, 0x1ff },
+ { 0x21105f, 0x1ff },
+ { 0x21115f, 0x1ff },
+ { 0x21205f, 0x1ff },
+ { 0x21215f, 0x1ff },
+ { 0x21305f, 0x1ff },
+ { 0x21315f, 0x1ff },
+ { 0x55, 0x1ff },
+ { 0x1055, 0x1ff },
+ { 0x2055, 0x1ff },
+ { 0x3055, 0x1ff },
+ { 0x4055, 0x1ff },
+ { 0x5055, 0x1ff },
+ { 0x6055, 0x1ff },
+ { 0x7055, 0x1ff },
+ { 0x8055, 0x1ff },
+ { 0x9055, 0x1ff },
+ { 0x200c5, 0x19 },
+ { 0x1200c5, 0x7 },
+ { 0x2200c5, 0x7 },
+ { 0x2002e, 0x2 },
+ { 0x12002e, 0x2 },
+ { 0x22002e, 0x2 },
+ { 0x90204, 0x0 },
+ { 0x190204, 0x0 },
+ { 0x290204, 0x0 },
+ { 0x20024, 0x1a3 },
+ { 0x2003a, 0x2 },
+ { 0x120024, 0x1a3 },
+ { 0x2003a, 0x2 },
+ { 0x220024, 0x1a3 },
+ { 0x2003a, 0x2 },
+ { 0x20056, 0x3 },
+ { 0x120056, 0x3 },
+ { 0x220056, 0x3 },
+ { 0x1004d, 0xe00 },
+ { 0x1014d, 0xe00 },
+ { 0x1104d, 0xe00 },
+ { 0x1114d, 0xe00 },
+ { 0x1204d, 0xe00 },
+ { 0x1214d, 0xe00 },
+ { 0x1304d, 0xe00 },
+ { 0x1314d, 0xe00 },
+ { 0x11004d, 0xe00 },
+ { 0x11014d, 0xe00 },
+ { 0x11104d, 0xe00 },
+ { 0x11114d, 0xe00 },
+ { 0x11204d, 0xe00 },
+ { 0x11214d, 0xe00 },
+ { 0x11304d, 0xe00 },
+ { 0x11314d, 0xe00 },
+ { 0x21004d, 0xe00 },
+ { 0x21014d, 0xe00 },
+ { 0x21104d, 0xe00 },
+ { 0x21114d, 0xe00 },
+ { 0x21204d, 0xe00 },
+ { 0x21214d, 0xe00 },
+ { 0x21304d, 0xe00 },
+ { 0x21314d, 0xe00 },
+ { 0x10049, 0xeba },
+ { 0x10149, 0xeba },
+ { 0x11049, 0xeba },
+ { 0x11149, 0xeba },
+ { 0x12049, 0xeba },
+ { 0x12149, 0xeba },
+ { 0x13049, 0xeba },
+ { 0x13149, 0xeba },
+ { 0x110049, 0xeba },
+ { 0x110149, 0xeba },
+ { 0x111049, 0xeba },
+ { 0x111149, 0xeba },
+ { 0x112049, 0xeba },
+ { 0x112149, 0xeba },
+ { 0x113049, 0xeba },
+ { 0x113149, 0xeba },
+ { 0x210049, 0xeba },
+ { 0x210149, 0xeba },
+ { 0x211049, 0xeba },
+ { 0x211149, 0xeba },
+ { 0x212049, 0xeba },
+ { 0x212149, 0xeba },
+ { 0x213049, 0xeba },
+ { 0x213149, 0xeba },
+ { 0x43, 0x63 },
+ { 0x1043, 0x63 },
+ { 0x2043, 0x63 },
+ { 0x3043, 0x63 },
+ { 0x4043, 0x63 },
+ { 0x5043, 0x63 },
+ { 0x6043, 0x63 },
+ { 0x7043, 0x63 },
+ { 0x8043, 0x63 },
+ { 0x9043, 0x63 },
+ { 0x20018, 0x3 },
+ { 0x20075, 0x4 },
+ { 0x20050, 0x0 },
+ { 0x20008, 0x2ee },
+ { 0x120008, 0x64 },
+ { 0x220008, 0x19 },
+ { 0x20088, 0x9 },
+ { 0x200b2, 0x104 },
+ { 0x10043, 0x5a1 },
+ { 0x10143, 0x5a1 },
+ { 0x11043, 0x5a1 },
+ { 0x11143, 0x5a1 },
+ { 0x12043, 0x5a1 },
+ { 0x12143, 0x5a1 },
+ { 0x13043, 0x5a1 },
+ { 0x13143, 0x5a1 },
+ { 0x1200b2, 0x104 },
+ { 0x110043, 0x5a1 },
+ { 0x110143, 0x5a1 },
+ { 0x111043, 0x5a1 },
+ { 0x111143, 0x5a1 },
+ { 0x112043, 0x5a1 },
+ { 0x112143, 0x5a1 },
+ { 0x113043, 0x5a1 },
+ { 0x113143, 0x5a1 },
+ { 0x2200b2, 0x104 },
+ { 0x210043, 0x5a1 },
+ { 0x210143, 0x5a1 },
+ { 0x211043, 0x5a1 },
+ { 0x211143, 0x5a1 },
+ { 0x212043, 0x5a1 },
+ { 0x212143, 0x5a1 },
+ { 0x213043, 0x5a1 },
+ { 0x213143, 0x5a1 },
+ { 0x200fa, 0x1 },
+ { 0x1200fa, 0x1 },
+ { 0x2200fa, 0x1 },
+ { 0x20019, 0x1 },
+ { 0x120019, 0x1 },
+ { 0x220019, 0x1 },
+ { 0x200f0, 0x660 },
+ { 0x200f1, 0x0 },
+ { 0x200f2, 0x4444 },
+ { 0x200f3, 0x8888 },
+ { 0x200f4, 0x5665 },
+ { 0x200f5, 0x0 },
+ { 0x200f6, 0x0 },
+ { 0x200f7, 0xf000 },
+ { 0x20025, 0x0 },
+ { 0x2002d, 0x0 },
+ { 0x12002d, 0x0 },
+ { 0x22002d, 0x0 },
+ { 0x2007d, 0x212 },
+ { 0x12007d, 0x212 },
+ { 0x22007d, 0x212 },
+ { 0x2007c, 0x61 },
+ { 0x12007c, 0x61 },
+ { 0x22007c, 0x61 },
+ { 0x1004a, 0x500 },
+ { 0x1104a, 0x500 },
+ { 0x1204a, 0x500 },
+ { 0x1304a, 0x500 },
+ { 0x2002c, 0x0 },
+};
+
+/* P0 message block paremeter for training firmware */
+struct dram_cfg_param ddr_fsp0_cfg_1gb_single_die[] = {
+ { 0xd0000, 0x0 },
+ { 0x54003, 0xbb8 },
+ { 0x54004, 0x2 },
+ { 0x54005, 0x2228 },
+ { 0x54006, 0x14 },
+ { 0x54008, 0x131f },
+ { 0x54009, 0xc8 },
+ { 0x5400b, 0x2 },
+ { 0x5400f, 0x100 },
+ { 0x54012, 0x110 },
+ { 0x54019, 0x2dd4 },
+ { 0x5401a, 0x31 },
+ { 0x5401b, 0x4866 },
+ { 0x5401c, 0x4800 },
+ { 0x5401e, 0x16 },
+ { 0x5401f, 0x2dd4 },
+ { 0x54020, 0x31 },
+ { 0x54021, 0x4866 },
+ { 0x54022, 0x4800 },
+ { 0x54024, 0x16 },
+ { 0x5402b, 0x1000 },
+ { 0x5402c, 0x1 },
+ { 0x54032, 0xd400 },
+ { 0x54033, 0x312d },
+ { 0x54034, 0x6600 },
+ { 0x54035, 0x48 },
+ { 0x54036, 0x48 },
+ { 0x54037, 0x1600 },
+ { 0x54038, 0xd400 },
+ { 0x54039, 0x312d },
+ { 0x5403a, 0x6600 },
+ { 0x5403b, 0x48 },
+ { 0x5403c, 0x48 },
+ { 0x5403d, 0x1600 },
+ { 0xd0000, 0x1 },
+};
+
+/* P1 message block paremeter for training firmware */
+struct dram_cfg_param ddr_fsp1_cfg_1gb_single_die[] = {
+ { 0xd0000, 0x0 },
+ { 0x54002, 0x101 },
+ { 0x54003, 0x190 },
+ { 0x54004, 0x2 },
+ { 0x54005, 0x2228 },
+ { 0x54006, 0x14 },
+ { 0x54008, 0x121f },
+ { 0x54009, 0xc8 },
+ { 0x5400b, 0x2 },
+ { 0x5400f, 0x100 },
+ { 0x54012, 0x110 },
+ { 0x54019, 0x84 },
+ { 0x5401a, 0x33 },
+ { 0x5401b, 0x4866 },
+ { 0x5401c, 0x4800 },
+ { 0x5401e, 0x16 },
+ { 0x5401f, 0x84 },
+ { 0x54020, 0x33 },
+ { 0x54021, 0x4866 },
+ { 0x54022, 0x4800 },
+ { 0x54024, 0x16 },
+ { 0x5402b, 0x1000 },
+ { 0x5402c, 0x1 },
+ { 0x54032, 0x8400 },
+ { 0x54033, 0x3300 },
+ { 0x54034, 0x6600 },
+ { 0x54035, 0x48 },
+ { 0x54036, 0x48 },
+ { 0x54037, 0x1600 },
+ { 0x54038, 0x8400 },
+ { 0x54039, 0x3300 },
+ { 0x5403a, 0x6600 },
+ { 0x5403b, 0x48 },
+ { 0x5403c, 0x48 },
+ { 0x5403d, 0x1600 },
+ { 0xd0000, 0x1 },
+};
+
+/* P2 message block paremeter for training firmware */
+struct dram_cfg_param ddr_fsp2_cfg_1gb_single_die[] = {
+ { 0xd0000, 0x0 },
+ { 0x54002, 0x102 },
+ { 0x54003, 0x64 },
+ { 0x54004, 0x2 },
+ { 0x54005, 0x2228 },
+ { 0x54006, 0x14 },
+ { 0x54008, 0x121f },
+ { 0x54009, 0xc8 },
+ { 0x5400b, 0x2 },
+ { 0x5400f, 0x100 },
+ { 0x54012, 0x110 },
+ { 0x54019, 0x84 },
+ { 0x5401a, 0x33 },
+ { 0x5401b, 0x4866 },
+ { 0x5401c, 0x4800 },
+ { 0x5401e, 0x16 },
+ { 0x5401f, 0x84 },
+ { 0x54020, 0x33 },
+ { 0x54021, 0x4866 },
+ { 0x54022, 0x4800 },
+ { 0x54024, 0x16 },
+ { 0x5402b, 0x1000 },
+ { 0x5402c, 0x1 },
+ { 0x54032, 0x8400 },
+ { 0x54033, 0x3300 },
+ { 0x54034, 0x6600 },
+ { 0x54035, 0x48 },
+ { 0x54036, 0x48 },
+ { 0x54037, 0x1600 },
+ { 0x54038, 0x8400 },
+ { 0x54039, 0x3300 },
+ { 0x5403a, 0x6600 },
+ { 0x5403b, 0x48 },
+ { 0x5403c, 0x48 },
+ { 0x5403d, 0x1600 },
+ { 0xd0000, 0x1 },
+};
+
+/* P0 2D message block paremeter for training firmware */
+struct dram_cfg_param ddr_fsp0_2d_cfg_1gb_single_die[] = {
+ { 0xd0000, 0x0 },
+ { 0x54003, 0xbb8 },
+ { 0x54004, 0x2 },
+ { 0x54005, 0x2228 },
+ { 0x54006, 0x14 },
+ { 0x54008, 0x61 },
+ { 0x54009, 0xc8 },
+ { 0x5400b, 0x2 },
+ { 0x5400f, 0x100 },
+ { 0x54010, 0x1f7f },
+ { 0x54012, 0x110 },
+ { 0x54019, 0x2dd4 },
+ { 0x5401a, 0x31 },
+ { 0x5401b, 0x4866 },
+ { 0x5401c, 0x4800 },
+ { 0x5401e, 0x16 },
+ { 0x5401f, 0x2dd4 },
+ { 0x54020, 0x31 },
+ { 0x54021, 0x4866 },
+ { 0x54022, 0x4800 },
+ { 0x54024, 0x16 },
+ { 0x5402b, 0x1000 },
+ { 0x5402c, 0x1 },
+ { 0x54032, 0xd400 },
+ { 0x54033, 0x312d },
+ { 0x54034, 0x6600 },
+ { 0x54035, 0x48 },
+ { 0x54036, 0x48 },
+ { 0x54037, 0x1600 },
+ { 0x54038, 0xd400 },
+ { 0x54039, 0x312d },
+ { 0x5403a, 0x6600 },
+ { 0x5403b, 0x48 },
+ { 0x5403c, 0x48 },
+ { 0x5403d, 0x1600 },
+ { 0xd0000, 0x1 },
+};
+
+struct dram_fsp_msg ddr_dram_fsp_msg_1gb_single_die[] = {
+ {
+ /* P0 3000mts 1D */
+ .drate = 3000,
+ .fw_type = FW_1D_IMAGE,
+ .fsp_cfg = ddr_fsp0_cfg_1gb_single_die,
+ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg_1gb_single_die),
+ },
+ {
+ /* P1 400mts 1D */
+ .drate = 400,
+ .fw_type = FW_1D_IMAGE,
+ .fsp_cfg = ddr_fsp1_cfg_1gb_single_die,
+ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg_1gb_single_die),
+ },
+ {
+ /* P2 100mts 1D */
+ .drate = 100,
+ .fw_type = FW_1D_IMAGE,
+ .fsp_cfg = ddr_fsp2_cfg_1gb_single_die,
+ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp2_cfg_1gb_single_die),
+ },
+ {
+ /* P0 3000mts 2D */
+ .drate = 3000,
+ .fw_type = FW_2D_IMAGE,
+ .fsp_cfg = ddr_fsp0_2d_cfg_1gb_single_die,
+ .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_2d_cfg_1gb_single_die),
+ },
+};
+
+/* ddr timing config params */
+struct dram_timing_info dram_timing_1gb_single_die = {
+ .ddrc_cfg = ddr_ddrc_cfg_1gb_single_die,
+ .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_1gb_single_die),
+ .ddrphy_cfg = ddr_ddrphy_cfg_1gb_single_die,
+ .ddrphy_cfg_num = ARRAY_SIZE(ddr_ddrphy_cfg_1gb_single_die),
+ .fsp_msg = ddr_dram_fsp_msg_1gb_single_die,
+ .fsp_msg_num = ARRAY_SIZE(ddr_dram_fsp_msg_1gb_single_die),
+ .ddrphy_trained_csr = ddr_ddrphy_trained_csr,
+ .ddrphy_trained_csr_num = ARRAY_SIZE(ddr_ddrphy_trained_csr),
+ .ddrphy_pie = ddr_phy_pie,
+ .ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie),
+ .fsp_table = { 3000, 400, 100, },
+};
+
+/*
* Generated code from MX8M_DDR_tool v3.30 using MX8M Plus RPAv7
* - 4GiB: imx8mp-gw7401 1x Micron MT53D1024M32D4DT 2-ch dual-die per channel
*/
diff --git a/board/gateworks/venice/spl.c b/board/gateworks/venice/spl.c
index 4eb7bdfcee6..5aa209578b2 100644
--- a/board/gateworks/venice/spl.c
+++ b/board/gateworks/venice/spl.c
@@ -71,6 +71,9 @@ static void spl_dram_init(int size)
dram_timing = &dram_timing_2gb_dual_die;
size = 2048;
#elif CONFIG_IMX8MP
+ case 1024:
+ dram_timing = &dram_timing_1gb_single_die;
+ break;
case 4096:
dram_timing = &dram_timing_4gb_dual_die;
break;
@@ -83,9 +86,12 @@ static void spl_dram_init(int size)
printf("DRAM : LPDDR4 ");
if (size > 512)
- printf("%d GiB\n", size / 1024);
+ printf("%d GiB", size / 1024);
else
- printf("%d MiB\n", size);
+ printf("%d MiB", size);
+ printf(" %dMT/s %dMHz\n",
+ dram_timing->fsp_msg[0].drate,
+ dram_timing->fsp_msg[0].drate / 2);
ddr_init(dram_timing);
}
@@ -121,7 +127,8 @@ static int power_init_board(void)
if ((!strncmp(model, "GW71", 4)) ||
(!strncmp(model, "GW72", 4)) ||
- (!strncmp(model, "GW73", 4))) {
+ (!strncmp(model, "GW73", 4)) ||
+ (!strncmp(model, "GW7905", 6))) {
ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
if (ret) {
printf("PMIC : failed I2C1 probe: %d\n", ret);
@@ -132,11 +139,22 @@ static int power_init_board(void)
printf("PMIC : failed probe: %d\n", ret);
return ret;
}
- puts("PMIC : MP5416\n");
+#ifdef CONFIG_IMX8MM
+ puts("PMIC : MP5416 (IMX8MM)\n");
/* set VDD_ARM SW3 to 0.92V for 1.6GHz */
dm_i2c_reg_write(dev, MP5416_VSET_SW3,
BIT(7) | MP5416_VSET_SW3_SVAL(920000));
+#elif CONFIG_IMX8MP
+ puts("PMIC : MP5416 (IMX8MP)\n");
+
+ /* set VDD_ARM SW3 to 0.95V for 1.6GHz */
+ dm_i2c_reg_write(dev, MP5416_VSET_SW3,
+ BIT(7) | MP5416_VSET_SW3_SVAL(950000));
+ /* set VDD_SOC SW1 to 0.95V for 1.6GHz */
+ dm_i2c_reg_write(dev, MP5416_VSET_SW1,
+ BIT(7) | MP5416_VSET_SW1_SVAL(950000));
+#endif
}
else if (!strncmp(model, "GW74", 4)) {
@@ -327,6 +345,21 @@ int spl_board_boot_device(enum boot_device boot_dev_spl)
}
}
+unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc, unsigned long raw_sect)
+{
+ if (!IS_SD(mmc)) {
+ switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
+ case 1:
+ case 2:
+ if (IS_ENABLED(CONFIG_IMX8MN) || IS_ENABLED(CONFIG_IMX8MP))
+ raw_sect -= 32 * 2;
+ break;
+ }
+ }
+
+ return raw_sect;
+}
+
const char *spl_board_loader_name(u32 boot_device)
{
switch (boot_device) {
@@ -340,3 +373,8 @@ const char *spl_board_loader_name(u32 boot_device)
return NULL;
}
}
+
+void spl_board_init(void)
+{
+ arch_misc_init();
+}
diff --git a/board/gateworks/venice/venice.c b/board/gateworks/venice/venice.c
index ca62f0be6d2..a39ae58c8a0 100644
--- a/board/gateworks/venice/venice.c
+++ b/board/gateworks/venice/venice.c
@@ -6,9 +6,12 @@
#include <fdt_support.h>
#include <init.h>
#include <led.h>
+#include <mmc.h>
#include <miiphy.h>
+#include <mmc.h>
#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
+#include <asm/mach-imx/boot_mode.h>
#include "eeprom.h"
@@ -17,7 +20,7 @@ int board_phys_sdram_size(phys_size_t *size)
if (!size)
return -EINVAL;
- *size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
+ *size = get_ram_size((void *)PHYS_SDRAM, (long)PHYS_SDRAM_SIZE + (long)PHYS_SDRAM_2_SIZE);
return 0;
}
@@ -93,10 +96,12 @@ int board_init(void)
int board_late_init(void)
{
const char *str;
+ struct mmc *mmc = NULL;
char env[32];
int ret, i;
u8 enetaddr[6];
char fdt[64];
+ int bootdev;
/* Set board serial/model */
if (!env_get("serial#"))
@@ -131,6 +136,74 @@ int board_late_init(void)
i++;
} while (!ret);
+ /*
+ * set bootdev/bootblk/bootpart (used in firmware_update script)
+ * dynamically depending on boot device and SoC
+ */
+ bootdev = -1;
+ switch (get_boot_device()) {
+ case SD1_BOOT:
+ case MMC1_BOOT: /* SDHC1 */
+ bootdev = 0;
+ break;
+ case SD2_BOOT:
+ case MMC2_BOOT: /* SDHC2 */
+ bootdev = 1;
+ break;
+ case SD3_BOOT:
+ case MMC3_BOOT: /* SDHC3 */
+ bootdev = 2;
+ break;
+ default:
+ bootdev = 2; /* assume SDHC3 (eMMC) if booting over SDP */
+ break;
+ }
+ if (bootdev != -1)
+ mmc = find_mmc_device(bootdev);
+ if (mmc) {
+ int bootblk;
+
+ if (IS_ENABLED(CONFIG_IMX8MN) || IS_ENABLED(CONFIG_IMX8MP))
+ bootblk = 32 * SZ_1K / 512;
+ else
+ bootblk = 33 * SZ_1K / 512;
+ mmc_init(mmc);
+ if (!IS_SD(mmc)) {
+ int bootpart;
+
+ switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
+ case 1: /* boot0 */
+ bootpart = 1;
+ break;
+ case 2: /* boot1 */
+ bootpart = 2;
+ break;
+ case 7: /* user */
+ default:
+ bootpart = 0;
+ break;
+ }
+ /* IMX8MP/IMX8MN BOOTROM v2 uses offset=0 for boot parts */
+ if ((IS_ENABLED(CONFIG_IMX8MN) || IS_ENABLED(CONFIG_IMX8MP)) &&
+ (bootpart == 1 || bootpart == 2))
+ bootblk = 0;
+ env_set_hex("bootpart", bootpart);
+ env_set_hex("bootblk", bootblk);
+ } else { /* SD */
+ env_set("bootpart", "");
+ env_set_hex("bootblk", bootblk);
+ }
+ env_set_hex("dev", bootdev);
+ }
+
+ /* override soc=imx8m to provide a more specific soc name */
+ if (IS_ENABLED(CONFIG_IMX8MN))
+ env_set("soc", "imx8mn");
+ else if (IS_ENABLED(CONFIG_IMX8MP))
+ env_set("soc", "imx8mp");
+ else if (IS_ENABLED(CONFIG_IMX8MM))
+ env_set("soc", "imx8mm");
+
return 0;
}
@@ -139,6 +212,20 @@ int board_mmc_get_env_dev(int devno)
return devno;
}
+uint mmc_get_env_part(struct mmc *mmc)
+{
+ if (!IS_SD(mmc)) {
+ switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
+ case 1:
+ return 1;
+ case 2:
+ return 2;
+ }
+ }
+
+ return 0;
+}
+
int ft_board_setup(void *fdt, struct bd_info *bd)
{
const char *base_model = eeprom_get_baseboard_model();
diff --git a/board/gateworks/venice/venice.env b/board/gateworks/venice/venice.env
index f81804ca12c..a0d6c43325c 100644
--- a/board/gateworks/venice/venice.env
+++ b/board/gateworks/venice/venice.env
@@ -8,11 +8,11 @@ bootm_size=0x10000000
dev=2
preboot=gsc wd-disable
console=ttymxc1,115200
-update_firmware=tftpboot $loadaddr $image &&
+update_firmware=tftpboot $loadaddr $dir/venice-$soc-flash.bin &&
setexpr blkcnt $filesize + 0x1ff &&
setexpr blkcnt $blkcnt / 0x200 &&
- mmc dev $dev &&
- mmc write $loadaddr $splblk $blkcnt
+ mmc dev $dev $bootpart &&
+ mmc write $loadaddr $bootblk $blkcnt
loadfdt=if $fsload $fdt_addr_r $dir/$fdt_file1;
then echo loaded $fdt_file1;
elif $fsload $fdt_addr_r $dir/$fdt_file2;
@@ -31,4 +31,3 @@ update_rootfs=tftpboot $loadaddr $image &&
gzwrite mmc $dev $loadaddr $filesize 100000 1000000
update_all=tftpboot $loadaddr $image &&
gzwrite mmc $dev $loadaddr $filesize
-erase_env=mmc dev $dev; mmc erase 0x7f08 0x40
diff --git a/board/kontron/sl-mx8mm/sl-mx8mm.c b/board/kontron/sl-mx8mm/sl-mx8mm.c
index ddb509eb66b..8dcc2ea54f6 100644
--- a/board/kontron/sl-mx8mm/sl-mx8mm.c
+++ b/board/kontron/sl-mx8mm/sl-mx8mm.c
@@ -37,7 +37,7 @@ struct efi_capsule_update_info update_info = {
int board_phys_sdram_size(phys_size_t *size)
{
- u32 ddr_size = readl(M4_BOOTROM_BASE_ADDR);
+ u32 ddr_size = readl(MCU_BOOTROM_BASE_ADDR);
if (ddr_size == 4) {
*size = 0x100000000;
diff --git a/board/kontron/sl-mx8mm/spl.c b/board/kontron/sl-mx8mm/spl.c
index 3a919d0a9c3..b49373442a2 100644
--- a/board/kontron/sl-mx8mm/spl.c
+++ b/board/kontron/sl-mx8mm/spl.c
@@ -106,7 +106,7 @@ static void spl_dram_init(void)
}
gd->ram_size = size;
- writel(size, M4_BOOTROM_BASE_ADDR);
+ writel(size, MCU_BOOTROM_BASE_ADDR);
}
int do_board_detect(void)
diff --git a/board/liebherr/xea/xea.c b/board/liebherr/xea/xea.c
index 38e841c5f67..e4d2eb65cc4 100644
--- a/board/liebherr/xea/xea.c
+++ b/board/liebherr/xea/xea.c
@@ -62,6 +62,7 @@ static void init_clocks(void)
void board_init_f(ulong arg)
{
init_clocks();
+ spl_early_init();
preloader_console_init();
}
@@ -203,5 +204,22 @@ int ft_board_setup(void *blob, struct bd_info *bd)
return 0;
}
#endif
-
+/*
+ * NOTE:
+ *
+ * IMX28 clock "stub" DM driver!
+ *
+ * Only used for SPL stage, which is NOT using DM; serial and
+ * eMMC configuration.
+ */
+static const struct udevice_id imx28_clk_ids[] = {
+ { .compatible = "fsl,imx28-clkctrl", },
+ { }
+};
+
+U_BOOT_DRIVER(fsl_imx28_clkctrl) = {
+ .name = "fsl_imx28_clkctrl",
+ .id = UCLASS_CLK,
+ .of_match = imx28_clk_ids,
+};
#endif /* CONFIG_SPL_BUILD */
diff --git a/board/nuvoton/arbel_evb/Kconfig b/board/nuvoton/arbel_evb/Kconfig
index efe85974a29..33c589f1fb3 100644
--- a/board/nuvoton/arbel_evb/Kconfig
+++ b/board/nuvoton/arbel_evb/Kconfig
@@ -11,8 +11,8 @@ config SYS_CONFIG_NAME
config SYS_MEM_TOP_HIDE
hex "Reserved TOP memory"
- default 0xB000000
+ default 0x0
help
- Reserve memory for ECC/GFX/VCD/ECE.
+ Reserve memory for ECC/GFX/OPTEE/TIP/CP.
endif
diff --git a/board/nuvoton/arbel_evb/arbel_evb.c b/board/nuvoton/arbel_evb/arbel_evb.c
index cd12ce38345..e52e0a59abc 100644
--- a/board/nuvoton/arbel_evb/arbel_evb.c
+++ b/board/nuvoton/arbel_evb/arbel_evb.c
@@ -8,6 +8,17 @@
#include <asm/io.h>
#include <asm/arch/gcr.h>
+#define SR_MII_CTRL_SWR_BIT15 15
+
+#define DRAM_512MB_ECC_SIZE 0x1C000000ULL
+#define DRAM_512MB_SIZE 0x20000000ULL
+#define DRAM_1GB_ECC_SIZE 0x38000000ULL
+#define DRAM_1GB_SIZE 0x40000000ULL
+#define DRAM_2GB_ECC_SIZE 0x70000000ULL
+#define DRAM_2GB_SIZE 0x80000000ULL
+#define DRAM_4GB_ECC_SIZE 0xE00000000ULL
+#define DRAM_4GB_SIZE 0x100000000ULL
+
DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
@@ -18,12 +29,65 @@ int board_init(void)
int dram_init(void)
{
struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA;
+ uint64_t delta = 0ULL;
/*
- * Get dram size from bootblock.
- * The value is stored in scrpad_02 register.
+ * get dram active size value from bootblock.
+ * Value sent using scrpad_03 register.
+ * feature available in bootblock 0.0.6 and above.
*/
- gd->ram_size = readl(&gcr->scrpad_b);
+
+ gd->ram_size = readl(&gcr->scrpad_c);
+ debug("%s: scrpad_c: %llx ", __func__, gd->ram_size);
+
+ if (gd->ram_size == 0) {
+ gd->ram_size = readl(&gcr->scrpad_b);
+ debug("%s: scrpad_b: %llx ", __func__, gd->ram_size);
+ } else {
+ gd->ram_size *= 0x100000ULL;
+ }
+
+ gd->bd->bi_dram[0].start = 0;
+ debug("ram_size: %llx ", gd->ram_size);
+
+ switch (gd->ram_size) {
+ case DRAM_512MB_ECC_SIZE:
+ case DRAM_512MB_SIZE:
+ case DRAM_1GB_ECC_SIZE:
+ case DRAM_1GB_SIZE:
+ case DRAM_2GB_ECC_SIZE:
+ case DRAM_2GB_SIZE:
+ gd->bd->bi_dram[0].size = gd->ram_size;
+ gd->bd->bi_dram[1].start = 0;
+ gd->bd->bi_dram[1].size = 0;
+ break;
+ case DRAM_4GB_ECC_SIZE:
+ gd->bd->bi_dram[0].size = DRAM_2GB_ECC_SIZE;
+ gd->bd->bi_dram[1].start = DRAM_4GB_SIZE;
+ gd->bd->bi_dram[1].size = DRAM_2GB_SIZE;
+ delta = DRAM_4GB_SIZE - DRAM_2GB_ECC_SIZE;
+ break;
+ case DRAM_4GB_SIZE:
+ gd->bd->bi_dram[0].size = DRAM_2GB_SIZE;
+ gd->bd->bi_dram[1].start = DRAM_4GB_SIZE;
+ gd->bd->bi_dram[1].size = DRAM_2GB_SIZE;
+ delta = DRAM_4GB_SIZE - DRAM_2GB_SIZE;
+ break;
+ default:
+ gd->bd->bi_dram[0].size = DRAM_1GB_SIZE;
+ gd->bd->bi_dram[1].start = 0;
+ gd->bd->bi_dram[1].size = 0;
+ break;
+ }
+
+ gd->ram_size -= delta;
+
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ dram_init();
return 0;
}
diff --git a/board/nuvoton/poleg_evb/poleg_evb.c b/board/nuvoton/poleg_evb/poleg_evb.c
index aef142a881c..2052af6649a 100644
--- a/board/nuvoton/poleg_evb/poleg_evb.c
+++ b/board/nuvoton/poleg_evb/poleg_evb.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <dm.h>
+#include <env.h>
#include <asm/io.h>
#include <asm/arch/gcr.h>
#include <asm/mach-types.h>
@@ -19,6 +20,7 @@ int board_init(void)
int dram_init(void)
{
+ char value[32];
struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA;
int ramsize = (readl(&gcr->intcr3) >> 8) & 0x7;
@@ -44,5 +46,10 @@ int dram_init(void)
break;
}
+ if (gd->ram_size > 0) {
+ sprintf(value, "%ldM", (gd->ram_size / 0x100000));
+ env_set("mem", value);
+ }
+
return 0;
}
diff --git a/board/openpiton/riscv64/Kconfig b/board/openpiton/riscv64/Kconfig
index eb0db8a64c8..21da1dc346d 100644
--- a/board/openpiton/riscv64/Kconfig
+++ b/board/openpiton/riscv64/Kconfig
@@ -29,7 +29,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select SUPPORT_SPL
imply CPU_RISCV
imply RISCV_TIMER
- imply SPL_SIFIVE_CLINT
+ imply SPL_RISCV_ACLINT
imply CMD_CPU
imply SPL_CPU_SUPPORT
imply SPL_SMP
diff --git a/board/phytec/phycore_imx8mm/lpddr4_timing.c b/board/phytec/phycore_imx8mm/lpddr4_timing.c
index 811ac26415a..f5a2f3268b3 100644
--- a/board/phytec/phycore_imx8mm/lpddr4_timing.c
+++ b/board/phytec/phycore_imx8mm/lpddr4_timing.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (C) 2020 PHYTEC Messtechnik GmbH
+ * Copyright 2019 NXP
+ * Copyright (C) 2023 PHYTEC Messtechnik GmbH
*
* Generated code from MX8M_DDR_tool
*/
@@ -13,22 +14,22 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
{0x3d400304, 0x1},
{0x3d400030, 0x1},
{0x3d400000, 0xa1080020},
- {0x3d400020, 0x223},
+ {0x3d400020, 0x222},
{0x3d400024, 0x3a980},
- {0x3d400064, 0x5b00d2},
+ {0x3d400064, 0x2d00d2},
{0x3d4000d0, 0xc00305ba},
{0x3d4000d4, 0x940000},
{0x3d4000dc, 0xd4002d},
{0x3d4000e0, 0x310000},
{0x3d4000e8, 0x66004d},
{0x3d4000ec, 0x16004d},
- {0x3d400100, 0x191e1920},
+ {0x3d400100, 0x191e0c20},
{0x3d400104, 0x60630},
{0x3d40010c, 0xb0b000},
{0x3d400110, 0xe04080e},
{0x3d400114, 0x2040c0c},
{0x3d400118, 0x1010007},
- {0x3d40011c, 0x401},
+ {0x3d40011c, 0x402},
{0x3d400130, 0x20600},
{0x3d400134, 0xc100002},
{0x3d400138, 0xd8},
@@ -45,7 +46,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
{0x3d4001b0, 0x11},
{0x3d4001c0, 0x1},
{0x3d4001c4, 0x1},
- {0x3d4000f4, 0xc99},
+ {0x3d4000f4, 0x699},
{0x3d400108, 0x70e1617},
{0x3d400200, 0x1f},
{0x3d40020c, 0x0},
@@ -53,6 +54,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
{0x3d400204, 0x80808},
{0x3d400214, 0x7070707},
{0x3d400218, 0x7070707},
+ {0x3d40021c, 0xf0f},
{0x3d400250, 0x29001701},
{0x3d400254, 0x2c},
{0x3d40025c, 0x4000030},
@@ -64,22 +66,22 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
{0x3d400498, 0x620096},
{0x3d40049c, 0x1100e07},
{0x3d4004a0, 0xc8012c},
- {0x3d402020, 0x21},
+ {0x3d402020, 0x20},
{0x3d402024, 0x7d00},
{0x3d402050, 0x20d040},
- {0x3d402064, 0xc001c},
+ {0x3d402064, 0x6001c},
{0x3d4020dc, 0x840000},
{0x3d4020e0, 0x310000},
{0x3d4020e8, 0x66004d},
{0x3d4020ec, 0x16004d},
- {0x3d402100, 0xa040305},
+ {0x3d402100, 0xa040105},
{0x3d402104, 0x30407},
{0x3d402108, 0x203060b},
{0x3d40210c, 0x505000},
{0x3d402110, 0x2040202},
{0x3d402114, 0x2030202},
{0x3d402118, 0x1010004},
- {0x3d40211c, 0x301},
+ {0x3d40211c, 0x302},
{0x3d402130, 0x20300},
{0x3d402134, 0xa100002},
{0x3d402138, 0x1d},
@@ -88,8 +90,8 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
{0x3d402190, 0x3818200},
{0x3d402194, 0x80303},
{0x3d4021b4, 0x100},
- {0x3d4020f4, 0xc99},
- {0x3d403020, 0x21},
+ {0x3d4020f4, 0x599},
+ {0x3d403020, 0x20},
{0x3d403024, 0x1f40},
{0x3d403050, 0x20d040},
{0x3d403064, 0x30007},
@@ -104,7 +106,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
{0x3d403110, 0x2040202},
{0x3d403114, 0x2030202},
{0x3d403118, 0x1010004},
- {0x3d40311c, 0x301},
+ {0x3d40311c, 0x302},
{0x3d403130, 0x20300},
{0x3d403134, 0xa100002},
{0x3d403138, 0x8},
@@ -113,7 +115,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
{0x3d403190, 0x3818200},
{0x3d403194, 0x80303},
{0x3d4031b4, 0x100},
- {0x3d4030f4, 0xc99},
+ {0x3d4030f4, 0x599},
{0x3d400028, 0x0},
};
@@ -201,8 +203,8 @@ static struct dram_cfg_param ddr_ddrphy_cfg[] = {
{0x220024, 0x1ab},
{0x2003a, 0x0},
{0x20056, 0x3},
- {0x120056, 0xa},
- {0x220056, 0xa},
+ {0x120056, 0x3},
+ {0x220056, 0x3},
{0x1004d, 0xe00},
{0x1014d, 0xe00},
{0x1104d, 0xe00},
@@ -323,727 +325,726 @@ static struct dram_cfg_param ddr_ddrphy_cfg[] = {
/* ddr phy trained csr */
static struct dram_cfg_param ddr_ddrphy_trained_csr[] = {
- { 0x200b2, 0x0 },
- { 0x1200b2, 0x0 },
- { 0x2200b2, 0x0 },
- { 0x200cb, 0x0 },
- { 0x10043, 0x0 },
- { 0x110043, 0x0 },
- { 0x210043, 0x0 },
- { 0x10143, 0x0 },
- { 0x110143, 0x0 },
- { 0x210143, 0x0 },
- { 0x11043, 0x0 },
- { 0x111043, 0x0 },
- { 0x211043, 0x0 },
- { 0x11143, 0x0 },
- { 0x111143, 0x0 },
- { 0x211143, 0x0 },
- { 0x12043, 0x0 },
- { 0x112043, 0x0 },
- { 0x212043, 0x0 },
- { 0x12143, 0x0 },
- { 0x112143, 0x0 },
- { 0x212143, 0x0 },
- { 0x13043, 0x0 },
- { 0x113043, 0x0 },
- { 0x213043, 0x0 },
- { 0x13143, 0x0 },
- { 0x113143, 0x0 },
- { 0x213143, 0x0 },
- { 0x80, 0x0 },
- { 0x100080, 0x0 },
- { 0x200080, 0x0 },
- { 0x1080, 0x0 },
- { 0x101080, 0x0 },
- { 0x201080, 0x0 },
- { 0x2080, 0x0 },
- { 0x102080, 0x0 },
- { 0x202080, 0x0 },
- { 0x3080, 0x0 },
- { 0x103080, 0x0 },
- { 0x203080, 0x0 },
- { 0x4080, 0x0 },
- { 0x104080, 0x0 },
- { 0x204080, 0x0 },
- { 0x5080, 0x0 },
- { 0x105080, 0x0 },
- { 0x205080, 0x0 },
- { 0x6080, 0x0 },
- { 0x106080, 0x0 },
- { 0x206080, 0x0 },
- { 0x7080, 0x0 },
- { 0x107080, 0x0 },
- { 0x207080, 0x0 },
- { 0x8080, 0x0 },
- { 0x108080, 0x0 },
- { 0x208080, 0x0 },
- { 0x9080, 0x0 },
- { 0x109080, 0x0 },
- { 0x209080, 0x0 },
- { 0x10080, 0x0 },
- { 0x110080, 0x0 },
- { 0x210080, 0x0 },
- { 0x10180, 0x0 },
- { 0x110180, 0x0 },
- { 0x210180, 0x0 },
- { 0x11080, 0x0 },
- { 0x111080, 0x0 },
- { 0x211080, 0x0 },
- { 0x11180, 0x0 },
- { 0x111180, 0x0 },
- { 0x211180, 0x0 },
- { 0x12080, 0x0 },
- { 0x112080, 0x0 },
- { 0x212080, 0x0 },
- { 0x12180, 0x0 },
- { 0x112180, 0x0 },
- { 0x212180, 0x0 },
- { 0x13080, 0x0 },
- { 0x113080, 0x0 },
- { 0x213080, 0x0 },
- { 0x13180, 0x0 },
- { 0x113180, 0x0 },
- { 0x213180, 0x0 },
- { 0x10081, 0x0 },
- { 0x110081, 0x0 },
- { 0x210081, 0x0 },
- { 0x10181, 0x0 },
- { 0x110181, 0x0 },
- { 0x210181, 0x0 },
- { 0x11081, 0x0 },
- { 0x111081, 0x0 },
- { 0x211081, 0x0 },
- { 0x11181, 0x0 },
- { 0x111181, 0x0 },
- { 0x211181, 0x0 },
- { 0x12081, 0x0 },
- { 0x112081, 0x0 },
- { 0x212081, 0x0 },
- { 0x12181, 0x0 },
- { 0x112181, 0x0 },
- { 0x212181, 0x0 },
- { 0x13081, 0x0 },
- { 0x113081, 0x0 },
- { 0x213081, 0x0 },
- { 0x13181, 0x0 },
- { 0x113181, 0x0 },
- { 0x213181, 0x0 },
- { 0x100d0, 0x0 },
- { 0x1100d0, 0x0 },
- { 0x2100d0, 0x0 },
- { 0x101d0, 0x0 },
- { 0x1101d0, 0x0 },
- { 0x2101d0, 0x0 },
- { 0x110d0, 0x0 },
- { 0x1110d0, 0x0 },
- { 0x2110d0, 0x0 },
- { 0x111d0, 0x0 },
- { 0x1111d0, 0x0 },
- { 0x2111d0, 0x0 },
- { 0x120d0, 0x0 },
- { 0x1120d0, 0x0 },
- { 0x2120d0, 0x0 },
- { 0x121d0, 0x0 },
- { 0x1121d0, 0x0 },
- { 0x2121d0, 0x0 },
- { 0x130d0, 0x0 },
- { 0x1130d0, 0x0 },
- { 0x2130d0, 0x0 },
- { 0x131d0, 0x0 },
- { 0x1131d0, 0x0 },
- { 0x2131d0, 0x0 },
- { 0x100d1, 0x0 },
- { 0x1100d1, 0x0 },
- { 0x2100d1, 0x0 },
- { 0x101d1, 0x0 },
- { 0x1101d1, 0x0 },
- { 0x2101d1, 0x0 },
- { 0x110d1, 0x0 },
- { 0x1110d1, 0x0 },
- { 0x2110d1, 0x0 },
- { 0x111d1, 0x0 },
- { 0x1111d1, 0x0 },
- { 0x2111d1, 0x0 },
- { 0x120d1, 0x0 },
- { 0x1120d1, 0x0 },
- { 0x2120d1, 0x0 },
- { 0x121d1, 0x0 },
- { 0x1121d1, 0x0 },
- { 0x2121d1, 0x0 },
- { 0x130d1, 0x0 },
- { 0x1130d1, 0x0 },
- { 0x2130d1, 0x0 },
- { 0x131d1, 0x0 },
- { 0x1131d1, 0x0 },
- { 0x2131d1, 0x0 },
- { 0x10068, 0x0 },
- { 0x10168, 0x0 },
- { 0x10268, 0x0 },
- { 0x10368, 0x0 },
- { 0x10468, 0x0 },
- { 0x10568, 0x0 },
- { 0x10668, 0x0 },
- { 0x10768, 0x0 },
- { 0x10868, 0x0 },
- { 0x11068, 0x0 },
- { 0x11168, 0x0 },
- { 0x11268, 0x0 },
- { 0x11368, 0x0 },
- { 0x11468, 0x0 },
- { 0x11568, 0x0 },
- { 0x11668, 0x0 },
- { 0x11768, 0x0 },
- { 0x11868, 0x0 },
- { 0x12068, 0x0 },
- { 0x12168, 0x0 },
- { 0x12268, 0x0 },
- { 0x12368, 0x0 },
- { 0x12468, 0x0 },
- { 0x12568, 0x0 },
- { 0x12668, 0x0 },
- { 0x12768, 0x0 },
- { 0x12868, 0x0 },
- { 0x13068, 0x0 },
- { 0x13168, 0x0 },
- { 0x13268, 0x0 },
- { 0x13368, 0x0 },
- { 0x13468, 0x0 },
- { 0x13568, 0x0 },
- { 0x13668, 0x0 },
- { 0x13768, 0x0 },
- { 0x13868, 0x0 },
- { 0x10069, 0x0 },
- { 0x10169, 0x0 },
- { 0x10269, 0x0 },
- { 0x10369, 0x0 },
- { 0x10469, 0x0 },
- { 0x10569, 0x0 },
- { 0x10669, 0x0 },
- { 0x10769, 0x0 },
- { 0x10869, 0x0 },
- { 0x11069, 0x0 },
- { 0x11169, 0x0 },
- { 0x11269, 0x0 },
- { 0x11369, 0x0 },
- { 0x11469, 0x0 },
- { 0x11569, 0x0 },
- { 0x11669, 0x0 },
- { 0x11769, 0x0 },
- { 0x11869, 0x0 },
- { 0x12069, 0x0 },
- { 0x12169, 0x0 },
- { 0x12269, 0x0 },
- { 0x12369, 0x0 },
- { 0x12469, 0x0 },
- { 0x12569, 0x0 },
- { 0x12669, 0x0 },
- { 0x12769, 0x0 },
- { 0x12869, 0x0 },
- { 0x13069, 0x0 },
- { 0x13169, 0x0 },
- { 0x13269, 0x0 },
- { 0x13369, 0x0 },
- { 0x13469, 0x0 },
- { 0x13569, 0x0 },
- { 0x13669, 0x0 },
- { 0x13769, 0x0 },
- { 0x13869, 0x0 },
- { 0x1008c, 0x0 },
- { 0x11008c, 0x0 },
- { 0x21008c, 0x0 },
- { 0x1018c, 0x0 },
- { 0x11018c, 0x0 },
- { 0x21018c, 0x0 },
- { 0x1108c, 0x0 },
- { 0x11108c, 0x0 },
- { 0x21108c, 0x0 },
- { 0x1118c, 0x0 },
- { 0x11118c, 0x0 },
- { 0x21118c, 0x0 },
- { 0x1208c, 0x0 },
- { 0x11208c, 0x0 },
- { 0x21208c, 0x0 },
- { 0x1218c, 0x0 },
- { 0x11218c, 0x0 },
- { 0x21218c, 0x0 },
- { 0x1308c, 0x0 },
- { 0x11308c, 0x0 },
- { 0x21308c, 0x0 },
- { 0x1318c, 0x0 },
- { 0x11318c, 0x0 },
- { 0x21318c, 0x0 },
- { 0x1008d, 0x0 },
- { 0x11008d, 0x0 },
- { 0x21008d, 0x0 },
- { 0x1018d, 0x0 },
- { 0x11018d, 0x0 },
- { 0x21018d, 0x0 },
- { 0x1108d, 0x0 },
- { 0x11108d, 0x0 },
- { 0x21108d, 0x0 },
- { 0x1118d, 0x0 },
- { 0x11118d, 0x0 },
- { 0x21118d, 0x0 },
- { 0x1208d, 0x0 },
- { 0x11208d, 0x0 },
- { 0x21208d, 0x0 },
- { 0x1218d, 0x0 },
- { 0x11218d, 0x0 },
- { 0x21218d, 0x0 },
- { 0x1308d, 0x0 },
- { 0x11308d, 0x0 },
- { 0x21308d, 0x0 },
- { 0x1318d, 0x0 },
- { 0x11318d, 0x0 },
- { 0x21318d, 0x0 },
- { 0x100c0, 0x0 },
- { 0x1100c0, 0x0 },
- { 0x2100c0, 0x0 },
- { 0x101c0, 0x0 },
- { 0x1101c0, 0x0 },
- { 0x2101c0, 0x0 },
- { 0x102c0, 0x0 },
- { 0x1102c0, 0x0 },
- { 0x2102c0, 0x0 },
- { 0x103c0, 0x0 },
- { 0x1103c0, 0x0 },
- { 0x2103c0, 0x0 },
- { 0x104c0, 0x0 },
- { 0x1104c0, 0x0 },
- { 0x2104c0, 0x0 },
- { 0x105c0, 0x0 },
- { 0x1105c0, 0x0 },
- { 0x2105c0, 0x0 },
- { 0x106c0, 0x0 },
- { 0x1106c0, 0x0 },
- { 0x2106c0, 0x0 },
- { 0x107c0, 0x0 },
- { 0x1107c0, 0x0 },
- { 0x2107c0, 0x0 },
- { 0x108c0, 0x0 },
- { 0x1108c0, 0x0 },
- { 0x2108c0, 0x0 },
- { 0x110c0, 0x0 },
- { 0x1110c0, 0x0 },
- { 0x2110c0, 0x0 },
- { 0x111c0, 0x0 },
- { 0x1111c0, 0x0 },
- { 0x2111c0, 0x0 },
- { 0x112c0, 0x0 },
- { 0x1112c0, 0x0 },
- { 0x2112c0, 0x0 },
- { 0x113c0, 0x0 },
- { 0x1113c0, 0x0 },
- { 0x2113c0, 0x0 },
- { 0x114c0, 0x0 },
- { 0x1114c0, 0x0 },
- { 0x2114c0, 0x0 },
- { 0x115c0, 0x0 },
- { 0x1115c0, 0x0 },
- { 0x2115c0, 0x0 },
- { 0x116c0, 0x0 },
- { 0x1116c0, 0x0 },
- { 0x2116c0, 0x0 },
- { 0x117c0, 0x0 },
- { 0x1117c0, 0x0 },
- { 0x2117c0, 0x0 },
- { 0x118c0, 0x0 },
- { 0x1118c0, 0x0 },
- { 0x2118c0, 0x0 },
- { 0x120c0, 0x0 },
- { 0x1120c0, 0x0 },
- { 0x2120c0, 0x0 },
- { 0x121c0, 0x0 },
- { 0x1121c0, 0x0 },
- { 0x2121c0, 0x0 },
- { 0x122c0, 0x0 },
- { 0x1122c0, 0x0 },
- { 0x2122c0, 0x0 },
- { 0x123c0, 0x0 },
- { 0x1123c0, 0x0 },
- { 0x2123c0, 0x0 },
- { 0x124c0, 0x0 },
- { 0x1124c0, 0x0 },
- { 0x2124c0, 0x0 },
- { 0x125c0, 0x0 },
- { 0x1125c0, 0x0 },
- { 0x2125c0, 0x0 },
- { 0x126c0, 0x0 },
- { 0x1126c0, 0x0 },
- { 0x2126c0, 0x0 },
- { 0x127c0, 0x0 },
- { 0x1127c0, 0x0 },
- { 0x2127c0, 0x0 },
- { 0x128c0, 0x0 },
- { 0x1128c0, 0x0 },
- { 0x2128c0, 0x0 },
- { 0x130c0, 0x0 },
- { 0x1130c0, 0x0 },
- { 0x2130c0, 0x0 },
- { 0x131c0, 0x0 },
- { 0x1131c0, 0x0 },
- { 0x2131c0, 0x0 },
- { 0x132c0, 0x0 },
- { 0x1132c0, 0x0 },
- { 0x2132c0, 0x0 },
- { 0x133c0, 0x0 },
- { 0x1133c0, 0x0 },
- { 0x2133c0, 0x0 },
- { 0x134c0, 0x0 },
- { 0x1134c0, 0x0 },
- { 0x2134c0, 0x0 },
- { 0x135c0, 0x0 },
- { 0x1135c0, 0x0 },
- { 0x2135c0, 0x0 },
- { 0x136c0, 0x0 },
- { 0x1136c0, 0x0 },
- { 0x2136c0, 0x0 },
- { 0x137c0, 0x0 },
- { 0x1137c0, 0x0 },
- { 0x2137c0, 0x0 },
- { 0x138c0, 0x0 },
- { 0x1138c0, 0x0 },
- { 0x2138c0, 0x0 },
- { 0x100c1, 0x0 },
- { 0x1100c1, 0x0 },
- { 0x2100c1, 0x0 },
- { 0x101c1, 0x0 },
- { 0x1101c1, 0x0 },
- { 0x2101c1, 0x0 },
- { 0x102c1, 0x0 },
- { 0x1102c1, 0x0 },
- { 0x2102c1, 0x0 },
- { 0x103c1, 0x0 },
- { 0x1103c1, 0x0 },
- { 0x2103c1, 0x0 },
- { 0x104c1, 0x0 },
- { 0x1104c1, 0x0 },
- { 0x2104c1, 0x0 },
- { 0x105c1, 0x0 },
- { 0x1105c1, 0x0 },
- { 0x2105c1, 0x0 },
- { 0x106c1, 0x0 },
- { 0x1106c1, 0x0 },
- { 0x2106c1, 0x0 },
- { 0x107c1, 0x0 },
- { 0x1107c1, 0x0 },
- { 0x2107c1, 0x0 },
- { 0x108c1, 0x0 },
- { 0x1108c1, 0x0 },
- { 0x2108c1, 0x0 },
- { 0x110c1, 0x0 },
- { 0x1110c1, 0x0 },
- { 0x2110c1, 0x0 },
- { 0x111c1, 0x0 },
- { 0x1111c1, 0x0 },
- { 0x2111c1, 0x0 },
- { 0x112c1, 0x0 },
- { 0x1112c1, 0x0 },
- { 0x2112c1, 0x0 },
- { 0x113c1, 0x0 },
- { 0x1113c1, 0x0 },
- { 0x2113c1, 0x0 },
- { 0x114c1, 0x0 },
- { 0x1114c1, 0x0 },
- { 0x2114c1, 0x0 },
- { 0x115c1, 0x0 },
- { 0x1115c1, 0x0 },
- { 0x2115c1, 0x0 },
- { 0x116c1, 0x0 },
- { 0x1116c1, 0x0 },
- { 0x2116c1, 0x0 },
- { 0x117c1, 0x0 },
- { 0x1117c1, 0x0 },
- { 0x2117c1, 0x0 },
- { 0x118c1, 0x0 },
- { 0x1118c1, 0x0 },
- { 0x2118c1, 0x0 },
- { 0x120c1, 0x0 },
- { 0x1120c1, 0x0 },
- { 0x2120c1, 0x0 },
- { 0x121c1, 0x0 },
- { 0x1121c1, 0x0 },
- { 0x2121c1, 0x0 },
- { 0x122c1, 0x0 },
- { 0x1122c1, 0x0 },
- { 0x2122c1, 0x0 },
- { 0x123c1, 0x0 },
- { 0x1123c1, 0x0 },
- { 0x2123c1, 0x0 },
- { 0x124c1, 0x0 },
- { 0x1124c1, 0x0 },
- { 0x2124c1, 0x0 },
- { 0x125c1, 0x0 },
- { 0x1125c1, 0x0 },
- { 0x2125c1, 0x0 },
- { 0x126c1, 0x0 },
- { 0x1126c1, 0x0 },
- { 0x2126c1, 0x0 },
- { 0x127c1, 0x0 },
- { 0x1127c1, 0x0 },
- { 0x2127c1, 0x0 },
- { 0x128c1, 0x0 },
- { 0x1128c1, 0x0 },
- { 0x2128c1, 0x0 },
- { 0x130c1, 0x0 },
- { 0x1130c1, 0x0 },
- { 0x2130c1, 0x0 },
- { 0x131c1, 0x0 },
- { 0x1131c1, 0x0 },
- { 0x2131c1, 0x0 },
- { 0x132c1, 0x0 },
- { 0x1132c1, 0x0 },
- { 0x2132c1, 0x0 },
- { 0x133c1, 0x0 },
- { 0x1133c1, 0x0 },
- { 0x2133c1, 0x0 },
- { 0x134c1, 0x0 },
- { 0x1134c1, 0x0 },
- { 0x2134c1, 0x0 },
- { 0x135c1, 0x0 },
- { 0x1135c1, 0x0 },
- { 0x2135c1, 0x0 },
- { 0x136c1, 0x0 },
- { 0x1136c1, 0x0 },
- { 0x2136c1, 0x0 },
- { 0x137c1, 0x0 },
- { 0x1137c1, 0x0 },
- { 0x2137c1, 0x0 },
- { 0x138c1, 0x0 },
- { 0x1138c1, 0x0 },
- { 0x2138c1, 0x0 },
- { 0x10020, 0x0 },
- { 0x110020, 0x0 },
- { 0x210020, 0x0 },
- { 0x11020, 0x0 },
- { 0x111020, 0x0 },
- { 0x211020, 0x0 },
- { 0x12020, 0x0 },
- { 0x112020, 0x0 },
- { 0x212020, 0x0 },
- { 0x13020, 0x0 },
- { 0x113020, 0x0 },
- { 0x213020, 0x0 },
- { 0x20072, 0x0 },
- { 0x20073, 0x0 },
- { 0x20074, 0x0 },
- { 0x100aa, 0x0 },
- { 0x110aa, 0x0 },
- { 0x120aa, 0x0 },
- { 0x130aa, 0x0 },
- { 0x20010, 0x0 },
- { 0x120010, 0x0 },
- { 0x220010, 0x0 },
- { 0x20011, 0x0 },
- { 0x120011, 0x0 },
- { 0x220011, 0x0 },
- { 0x100ae, 0x0 },
- { 0x1100ae, 0x0 },
- { 0x2100ae, 0x0 },
- { 0x100af, 0x0 },
- { 0x1100af, 0x0 },
- { 0x2100af, 0x0 },
- { 0x110ae, 0x0 },
- { 0x1110ae, 0x0 },
- { 0x2110ae, 0x0 },
- { 0x110af, 0x0 },
- { 0x1110af, 0x0 },
- { 0x2110af, 0x0 },
- { 0x120ae, 0x0 },
- { 0x1120ae, 0x0 },
- { 0x2120ae, 0x0 },
- { 0x120af, 0x0 },
- { 0x1120af, 0x0 },
- { 0x2120af, 0x0 },
- { 0x130ae, 0x0 },
- { 0x1130ae, 0x0 },
- { 0x2130ae, 0x0 },
- { 0x130af, 0x0 },
- { 0x1130af, 0x0 },
- { 0x2130af, 0x0 },
- { 0x20020, 0x0 },
- { 0x120020, 0x0 },
- { 0x220020, 0x0 },
- { 0x100a0, 0x0 },
- { 0x100a1, 0x0 },
- { 0x100a2, 0x0 },
- { 0x100a3, 0x0 },
- { 0x100a4, 0x0 },
- { 0x100a5, 0x0 },
- { 0x100a6, 0x0 },
- { 0x100a7, 0x0 },
- { 0x110a0, 0x0 },
- { 0x110a1, 0x0 },
- { 0x110a2, 0x0 },
- { 0x110a3, 0x0 },
- { 0x110a4, 0x0 },
- { 0x110a5, 0x0 },
- { 0x110a6, 0x0 },
- { 0x110a7, 0x0 },
- { 0x120a0, 0x0 },
- { 0x120a1, 0x0 },
- { 0x120a2, 0x0 },
- { 0x120a3, 0x0 },
- { 0x120a4, 0x0 },
- { 0x120a5, 0x0 },
- { 0x120a6, 0x0 },
- { 0x120a7, 0x0 },
- { 0x130a0, 0x0 },
- { 0x130a1, 0x0 },
- { 0x130a2, 0x0 },
- { 0x130a3, 0x0 },
- { 0x130a4, 0x0 },
- { 0x130a5, 0x0 },
- { 0x130a6, 0x0 },
- { 0x130a7, 0x0 },
- { 0x2007c, 0x0 },
- { 0x12007c, 0x0 },
- { 0x22007c, 0x0 },
- { 0x2007d, 0x0 },
- { 0x12007d, 0x0 },
- { 0x22007d, 0x0 },
- { 0x400fd, 0x0 },
- { 0x400c0, 0x0 },
- { 0x90201, 0x0 },
- { 0x190201, 0x0 },
- { 0x290201, 0x0 },
- { 0x90202, 0x0 },
- { 0x190202, 0x0 },
- { 0x290202, 0x0 },
- { 0x90203, 0x0 },
- { 0x190203, 0x0 },
- { 0x290203, 0x0 },
- { 0x90204, 0x0 },
- { 0x190204, 0x0 },
- { 0x290204, 0x0 },
- { 0x90205, 0x0 },
- { 0x190205, 0x0 },
- { 0x290205, 0x0 },
- { 0x90206, 0x0 },
- { 0x190206, 0x0 },
- { 0x290206, 0x0 },
- { 0x90207, 0x0 },
- { 0x190207, 0x0 },
- { 0x290207, 0x0 },
- { 0x90208, 0x0 },
- { 0x190208, 0x0 },
- { 0x290208, 0x0 },
- { 0x10062, 0x0 },
- { 0x10162, 0x0 },
- { 0x10262, 0x0 },
- { 0x10362, 0x0 },
- { 0x10462, 0x0 },
- { 0x10562, 0x0 },
- { 0x10662, 0x0 },
- { 0x10762, 0x0 },
- { 0x10862, 0x0 },
- { 0x11062, 0x0 },
- { 0x11162, 0x0 },
- { 0x11262, 0x0 },
- { 0x11362, 0x0 },
- { 0x11462, 0x0 },
- { 0x11562, 0x0 },
- { 0x11662, 0x0 },
- { 0x11762, 0x0 },
- { 0x11862, 0x0 },
- { 0x12062, 0x0 },
- { 0x12162, 0x0 },
- { 0x12262, 0x0 },
- { 0x12362, 0x0 },
- { 0x12462, 0x0 },
- { 0x12562, 0x0 },
- { 0x12662, 0x0 },
- { 0x12762, 0x0 },
- { 0x12862, 0x0 },
- { 0x13062, 0x0 },
- { 0x13162, 0x0 },
- { 0x13262, 0x0 },
- { 0x13362, 0x0 },
- { 0x13462, 0x0 },
- { 0x13562, 0x0 },
- { 0x13662, 0x0 },
- { 0x13762, 0x0 },
- { 0x13862, 0x0 },
- { 0x20077, 0x0 },
- { 0x10001, 0x0 },
- { 0x11001, 0x0 },
- { 0x12001, 0x0 },
- { 0x13001, 0x0 },
- { 0x10040, 0x0 },
- { 0x10140, 0x0 },
- { 0x10240, 0x0 },
- { 0x10340, 0x0 },
- { 0x10440, 0x0 },
- { 0x10540, 0x0 },
- { 0x10640, 0x0 },
- { 0x10740, 0x0 },
- { 0x10840, 0x0 },
- { 0x10030, 0x0 },
- { 0x10130, 0x0 },
- { 0x10230, 0x0 },
- { 0x10330, 0x0 },
- { 0x10430, 0x0 },
- { 0x10530, 0x0 },
- { 0x10630, 0x0 },
- { 0x10730, 0x0 },
- { 0x10830, 0x0 },
- { 0x11040, 0x0 },
- { 0x11140, 0x0 },
- { 0x11240, 0x0 },
- { 0x11340, 0x0 },
- { 0x11440, 0x0 },
- { 0x11540, 0x0 },
- { 0x11640, 0x0 },
- { 0x11740, 0x0 },
- { 0x11840, 0x0 },
- { 0x11030, 0x0 },
- { 0x11130, 0x0 },
- { 0x11230, 0x0 },
- { 0x11330, 0x0 },
- { 0x11430, 0x0 },
- { 0x11530, 0x0 },
- { 0x11630, 0x0 },
- { 0x11730, 0x0 },
- { 0x11830, 0x0 },
- { 0x12040, 0x0 },
- { 0x12140, 0x0 },
- { 0x12240, 0x0 },
- { 0x12340, 0x0 },
- { 0x12440, 0x0 },
- { 0x12540, 0x0 },
- { 0x12640, 0x0 },
- { 0x12740, 0x0 },
- { 0x12840, 0x0 },
- { 0x12030, 0x0 },
- { 0x12130, 0x0 },
- { 0x12230, 0x0 },
- { 0x12330, 0x0 },
- { 0x12430, 0x0 },
- { 0x12530, 0x0 },
- { 0x12630, 0x0 },
- { 0x12730, 0x0 },
- { 0x12830, 0x0 },
- { 0x13040, 0x0 },
- { 0x13140, 0x0 },
- { 0x13240, 0x0 },
- { 0x13340, 0x0 },
- { 0x13440, 0x0 },
- { 0x13540, 0x0 },
- { 0x13640, 0x0 },
- { 0x13740, 0x0 },
- { 0x13840, 0x0 },
- { 0x13030, 0x0 },
- { 0x13130, 0x0 },
- { 0x13230, 0x0 },
- { 0x13330, 0x0 },
- { 0x13430, 0x0 },
- { 0x13530, 0x0 },
- { 0x13630, 0x0 },
- { 0x13730, 0x0 },
- { 0x13830, 0x0 },
+ {0x200b2, 0x0},
+ {0x1200b2, 0x0},
+ {0x2200b2, 0x0},
+ {0x200cb, 0x0},
+ {0x10043, 0x0},
+ {0x110043, 0x0},
+ {0x210043, 0x0},
+ {0x10143, 0x0},
+ {0x110143, 0x0},
+ {0x210143, 0x0},
+ {0x11043, 0x0},
+ {0x111043, 0x0},
+ {0x211043, 0x0},
+ {0x11143, 0x0},
+ {0x111143, 0x0},
+ {0x211143, 0x0},
+ {0x12043, 0x0},
+ {0x112043, 0x0},
+ {0x212043, 0x0},
+ {0x12143, 0x0},
+ {0x112143, 0x0},
+ {0x212143, 0x0},
+ {0x13043, 0x0},
+ {0x113043, 0x0},
+ {0x213043, 0x0},
+ {0x13143, 0x0},
+ {0x113143, 0x0},
+ {0x213143, 0x0},
+ {0x80, 0x0},
+ {0x100080, 0x0},
+ {0x200080, 0x0},
+ {0x1080, 0x0},
+ {0x101080, 0x0},
+ {0x201080, 0x0},
+ {0x2080, 0x0},
+ {0x102080, 0x0},
+ {0x202080, 0x0},
+ {0x3080, 0x0},
+ {0x103080, 0x0},
+ {0x203080, 0x0},
+ {0x4080, 0x0},
+ {0x104080, 0x0},
+ {0x204080, 0x0},
+ {0x5080, 0x0},
+ {0x105080, 0x0},
+ {0x205080, 0x0},
+ {0x6080, 0x0},
+ {0x106080, 0x0},
+ {0x206080, 0x0},
+ {0x7080, 0x0},
+ {0x107080, 0x0},
+ {0x207080, 0x0},
+ {0x8080, 0x0},
+ {0x108080, 0x0},
+ {0x208080, 0x0},
+ {0x9080, 0x0},
+ {0x109080, 0x0},
+ {0x209080, 0x0},
+ {0x10080, 0x0},
+ {0x110080, 0x0},
+ {0x210080, 0x0},
+ {0x10180, 0x0},
+ {0x110180, 0x0},
+ {0x210180, 0x0},
+ {0x11080, 0x0},
+ {0x111080, 0x0},
+ {0x211080, 0x0},
+ {0x11180, 0x0},
+ {0x111180, 0x0},
+ {0x211180, 0x0},
+ {0x12080, 0x0},
+ {0x112080, 0x0},
+ {0x212080, 0x0},
+ {0x12180, 0x0},
+ {0x112180, 0x0},
+ {0x212180, 0x0},
+ {0x13080, 0x0},
+ {0x113080, 0x0},
+ {0x213080, 0x0},
+ {0x13180, 0x0},
+ {0x113180, 0x0},
+ {0x213180, 0x0},
+ {0x10081, 0x0},
+ {0x110081, 0x0},
+ {0x210081, 0x0},
+ {0x10181, 0x0},
+ {0x110181, 0x0},
+ {0x210181, 0x0},
+ {0x11081, 0x0},
+ {0x111081, 0x0},
+ {0x211081, 0x0},
+ {0x11181, 0x0},
+ {0x111181, 0x0},
+ {0x211181, 0x0},
+ {0x12081, 0x0},
+ {0x112081, 0x0},
+ {0x212081, 0x0},
+ {0x12181, 0x0},
+ {0x112181, 0x0},
+ {0x212181, 0x0},
+ {0x13081, 0x0},
+ {0x113081, 0x0},
+ {0x213081, 0x0},
+ {0x13181, 0x0},
+ {0x113181, 0x0},
+ {0x213181, 0x0},
+ {0x100d0, 0x0},
+ {0x1100d0, 0x0},
+ {0x2100d0, 0x0},
+ {0x101d0, 0x0},
+ {0x1101d0, 0x0},
+ {0x2101d0, 0x0},
+ {0x110d0, 0x0},
+ {0x1110d0, 0x0},
+ {0x2110d0, 0x0},
+ {0x111d0, 0x0},
+ {0x1111d0, 0x0},
+ {0x2111d0, 0x0},
+ {0x120d0, 0x0},
+ {0x1120d0, 0x0},
+ {0x2120d0, 0x0},
+ {0x121d0, 0x0},
+ {0x1121d0, 0x0},
+ {0x2121d0, 0x0},
+ {0x130d0, 0x0},
+ {0x1130d0, 0x0},
+ {0x2130d0, 0x0},
+ {0x131d0, 0x0},
+ {0x1131d0, 0x0},
+ {0x2131d0, 0x0},
+ {0x100d1, 0x0},
+ {0x1100d1, 0x0},
+ {0x2100d1, 0x0},
+ {0x101d1, 0x0},
+ {0x1101d1, 0x0},
+ {0x2101d1, 0x0},
+ {0x110d1, 0x0},
+ {0x1110d1, 0x0},
+ {0x2110d1, 0x0},
+ {0x111d1, 0x0},
+ {0x1111d1, 0x0},
+ {0x2111d1, 0x0},
+ {0x120d1, 0x0},
+ {0x1120d1, 0x0},
+ {0x2120d1, 0x0},
+ {0x121d1, 0x0},
+ {0x1121d1, 0x0},
+ {0x2121d1, 0x0},
+ {0x130d1, 0x0},
+ {0x1130d1, 0x0},
+ {0x2130d1, 0x0},
+ {0x131d1, 0x0},
+ {0x1131d1, 0x0},
+ {0x2131d1, 0x0},
+ {0x10068, 0x0},
+ {0x10168, 0x0},
+ {0x10268, 0x0},
+ {0x10368, 0x0},
+ {0x10468, 0x0},
+ {0x10568, 0x0},
+ {0x10668, 0x0},
+ {0x10768, 0x0},
+ {0x10868, 0x0},
+ {0x11068, 0x0},
+ {0x11168, 0x0},
+ {0x11268, 0x0},
+ {0x11368, 0x0},
+ {0x11468, 0x0},
+ {0x11568, 0x0},
+ {0x11668, 0x0},
+ {0x11768, 0x0},
+ {0x11868, 0x0},
+ {0x12068, 0x0},
+ {0x12168, 0x0},
+ {0x12268, 0x0},
+ {0x12368, 0x0},
+ {0x12468, 0x0},
+ {0x12568, 0x0},
+ {0x12668, 0x0},
+ {0x12768, 0x0},
+ {0x12868, 0x0},
+ {0x13068, 0x0},
+ {0x13168, 0x0},
+ {0x13268, 0x0},
+ {0x13368, 0x0},
+ {0x13468, 0x0},
+ {0x13568, 0x0},
+ {0x13668, 0x0},
+ {0x13768, 0x0},
+ {0x13868, 0x0},
+ {0x10069, 0x0},
+ {0x10169, 0x0},
+ {0x10269, 0x0},
+ {0x10369, 0x0},
+ {0x10469, 0x0},
+ {0x10569, 0x0},
+ {0x10669, 0x0},
+ {0x10769, 0x0},
+ {0x10869, 0x0},
+ {0x11069, 0x0},
+ {0x11169, 0x0},
+ {0x11269, 0x0},
+ {0x11369, 0x0},
+ {0x11469, 0x0},
+ {0x11569, 0x0},
+ {0x11669, 0x0},
+ {0x11769, 0x0},
+ {0x11869, 0x0},
+ {0x12069, 0x0},
+ {0x12169, 0x0},
+ {0x12269, 0x0},
+ {0x12369, 0x0},
+ {0x12469, 0x0},
+ {0x12569, 0x0},
+ {0x12669, 0x0},
+ {0x12769, 0x0},
+ {0x12869, 0x0},
+ {0x13069, 0x0},
+ {0x13169, 0x0},
+ {0x13269, 0x0},
+ {0x13369, 0x0},
+ {0x13469, 0x0},
+ {0x13569, 0x0},
+ {0x13669, 0x0},
+ {0x13769, 0x0},
+ {0x13869, 0x0},
+ {0x1008c, 0x0},
+ {0x11008c, 0x0},
+ {0x21008c, 0x0},
+ {0x1018c, 0x0},
+ {0x11018c, 0x0},
+ {0x21018c, 0x0},
+ {0x1108c, 0x0},
+ {0x11108c, 0x0},
+ {0x21108c, 0x0},
+ {0x1118c, 0x0},
+ {0x11118c, 0x0},
+ {0x21118c, 0x0},
+ {0x1208c, 0x0},
+ {0x11208c, 0x0},
+ {0x21208c, 0x0},
+ {0x1218c, 0x0},
+ {0x11218c, 0x0},
+ {0x21218c, 0x0},
+ {0x1308c, 0x0},
+ {0x11308c, 0x0},
+ {0x21308c, 0x0},
+ {0x1318c, 0x0},
+ {0x11318c, 0x0},
+ {0x21318c, 0x0},
+ {0x1008d, 0x0},
+ {0x11008d, 0x0},
+ {0x21008d, 0x0},
+ {0x1018d, 0x0},
+ {0x11018d, 0x0},
+ {0x21018d, 0x0},
+ {0x1108d, 0x0},
+ {0x11108d, 0x0},
+ {0x21108d, 0x0},
+ {0x1118d, 0x0},
+ {0x11118d, 0x0},
+ {0x21118d, 0x0},
+ {0x1208d, 0x0},
+ {0x11208d, 0x0},
+ {0x21208d, 0x0},
+ {0x1218d, 0x0},
+ {0x11218d, 0x0},
+ {0x21218d, 0x0},
+ {0x1308d, 0x0},
+ {0x11308d, 0x0},
+ {0x21308d, 0x0},
+ {0x1318d, 0x0},
+ {0x11318d, 0x0},
+ {0x21318d, 0x0},
+ {0x100c0, 0x0},
+ {0x1100c0, 0x0},
+ {0x2100c0, 0x0},
+ {0x101c0, 0x0},
+ {0x1101c0, 0x0},
+ {0x2101c0, 0x0},
+ {0x102c0, 0x0},
+ {0x1102c0, 0x0},
+ {0x2102c0, 0x0},
+ {0x103c0, 0x0},
+ {0x1103c0, 0x0},
+ {0x2103c0, 0x0},
+ {0x104c0, 0x0},
+ {0x1104c0, 0x0},
+ {0x2104c0, 0x0},
+ {0x105c0, 0x0},
+ {0x1105c0, 0x0},
+ {0x2105c0, 0x0},
+ {0x106c0, 0x0},
+ {0x1106c0, 0x0},
+ {0x2106c0, 0x0},
+ {0x107c0, 0x0},
+ {0x1107c0, 0x0},
+ {0x2107c0, 0x0},
+ {0x108c0, 0x0},
+ {0x1108c0, 0x0},
+ {0x2108c0, 0x0},
+ {0x110c0, 0x0},
+ {0x1110c0, 0x0},
+ {0x2110c0, 0x0},
+ {0x111c0, 0x0},
+ {0x1111c0, 0x0},
+ {0x2111c0, 0x0},
+ {0x112c0, 0x0},
+ {0x1112c0, 0x0},
+ {0x2112c0, 0x0},
+ {0x113c0, 0x0},
+ {0x1113c0, 0x0},
+ {0x2113c0, 0x0},
+ {0x114c0, 0x0},
+ {0x1114c0, 0x0},
+ {0x2114c0, 0x0},
+ {0x115c0, 0x0},
+ {0x1115c0, 0x0},
+ {0x2115c0, 0x0},
+ {0x116c0, 0x0},
+ {0x1116c0, 0x0},
+ {0x2116c0, 0x0},
+ {0x117c0, 0x0},
+ {0x1117c0, 0x0},
+ {0x2117c0, 0x0},
+ {0x118c0, 0x0},
+ {0x1118c0, 0x0},
+ {0x2118c0, 0x0},
+ {0x120c0, 0x0},
+ {0x1120c0, 0x0},
+ {0x2120c0, 0x0},
+ {0x121c0, 0x0},
+ {0x1121c0, 0x0},
+ {0x2121c0, 0x0},
+ {0x122c0, 0x0},
+ {0x1122c0, 0x0},
+ {0x2122c0, 0x0},
+ {0x123c0, 0x0},
+ {0x1123c0, 0x0},
+ {0x2123c0, 0x0},
+ {0x124c0, 0x0},
+ {0x1124c0, 0x0},
+ {0x2124c0, 0x0},
+ {0x125c0, 0x0},
+ {0x1125c0, 0x0},
+ {0x2125c0, 0x0},
+ {0x126c0, 0x0},
+ {0x1126c0, 0x0},
+ {0x2126c0, 0x0},
+ {0x127c0, 0x0},
+ {0x1127c0, 0x0},
+ {0x2127c0, 0x0},
+ {0x128c0, 0x0},
+ {0x1128c0, 0x0},
+ {0x2128c0, 0x0},
+ {0x130c0, 0x0},
+ {0x1130c0, 0x0},
+ {0x2130c0, 0x0},
+ {0x131c0, 0x0},
+ {0x1131c0, 0x0},
+ {0x2131c0, 0x0},
+ {0x132c0, 0x0},
+ {0x1132c0, 0x0},
+ {0x2132c0, 0x0},
+ {0x133c0, 0x0},
+ {0x1133c0, 0x0},
+ {0x2133c0, 0x0},
+ {0x134c0, 0x0},
+ {0x1134c0, 0x0},
+ {0x2134c0, 0x0},
+ {0x135c0, 0x0},
+ {0x1135c0, 0x0},
+ {0x2135c0, 0x0},
+ {0x136c0, 0x0},
+ {0x1136c0, 0x0},
+ {0x2136c0, 0x0},
+ {0x137c0, 0x0},
+ {0x1137c0, 0x0},
+ {0x2137c0, 0x0},
+ {0x138c0, 0x0},
+ {0x1138c0, 0x0},
+ {0x2138c0, 0x0},
+ {0x100c1, 0x0},
+ {0x1100c1, 0x0},
+ {0x2100c1, 0x0},
+ {0x101c1, 0x0},
+ {0x1101c1, 0x0},
+ {0x2101c1, 0x0},
+ {0x102c1, 0x0},
+ {0x1102c1, 0x0},
+ {0x2102c1, 0x0},
+ {0x103c1, 0x0},
+ {0x1103c1, 0x0},
+ {0x2103c1, 0x0},
+ {0x104c1, 0x0},
+ {0x1104c1, 0x0},
+ {0x2104c1, 0x0},
+ {0x105c1, 0x0},
+ {0x1105c1, 0x0},
+ {0x2105c1, 0x0},
+ {0x106c1, 0x0},
+ {0x1106c1, 0x0},
+ {0x2106c1, 0x0},
+ {0x107c1, 0x0},
+ {0x1107c1, 0x0},
+ {0x2107c1, 0x0},
+ {0x108c1, 0x0},
+ {0x1108c1, 0x0},
+ {0x2108c1, 0x0},
+ {0x110c1, 0x0},
+ {0x1110c1, 0x0},
+ {0x2110c1, 0x0},
+ {0x111c1, 0x0},
+ {0x1111c1, 0x0},
+ {0x2111c1, 0x0},
+ {0x112c1, 0x0},
+ {0x1112c1, 0x0},
+ {0x2112c1, 0x0},
+ {0x113c1, 0x0},
+ {0x1113c1, 0x0},
+ {0x2113c1, 0x0},
+ {0x114c1, 0x0},
+ {0x1114c1, 0x0},
+ {0x2114c1, 0x0},
+ {0x115c1, 0x0},
+ {0x1115c1, 0x0},
+ {0x2115c1, 0x0},
+ {0x116c1, 0x0},
+ {0x1116c1, 0x0},
+ {0x2116c1, 0x0},
+ {0x117c1, 0x0},
+ {0x1117c1, 0x0},
+ {0x2117c1, 0x0},
+ {0x118c1, 0x0},
+ {0x1118c1, 0x0},
+ {0x2118c1, 0x0},
+ {0x120c1, 0x0},
+ {0x1120c1, 0x0},
+ {0x2120c1, 0x0},
+ {0x121c1, 0x0},
+ {0x1121c1, 0x0},
+ {0x2121c1, 0x0},
+ {0x122c1, 0x0},
+ {0x1122c1, 0x0},
+ {0x2122c1, 0x0},
+ {0x123c1, 0x0},
+ {0x1123c1, 0x0},
+ {0x2123c1, 0x0},
+ {0x124c1, 0x0},
+ {0x1124c1, 0x0},
+ {0x2124c1, 0x0},
+ {0x125c1, 0x0},
+ {0x1125c1, 0x0},
+ {0x2125c1, 0x0},
+ {0x126c1, 0x0},
+ {0x1126c1, 0x0},
+ {0x2126c1, 0x0},
+ {0x127c1, 0x0},
+ {0x1127c1, 0x0},
+ {0x2127c1, 0x0},
+ {0x128c1, 0x0},
+ {0x1128c1, 0x0},
+ {0x2128c1, 0x0},
+ {0x130c1, 0x0},
+ {0x1130c1, 0x0},
+ {0x2130c1, 0x0},
+ {0x131c1, 0x0},
+ {0x1131c1, 0x0},
+ {0x2131c1, 0x0},
+ {0x132c1, 0x0},
+ {0x1132c1, 0x0},
+ {0x2132c1, 0x0},
+ {0x133c1, 0x0},
+ {0x1133c1, 0x0},
+ {0x2133c1, 0x0},
+ {0x134c1, 0x0},
+ {0x1134c1, 0x0},
+ {0x2134c1, 0x0},
+ {0x135c1, 0x0},
+ {0x1135c1, 0x0},
+ {0x2135c1, 0x0},
+ {0x136c1, 0x0},
+ {0x1136c1, 0x0},
+ {0x2136c1, 0x0},
+ {0x137c1, 0x0},
+ {0x1137c1, 0x0},
+ {0x2137c1, 0x0},
+ {0x138c1, 0x0},
+ {0x1138c1, 0x0},
+ {0x2138c1, 0x0},
+ {0x10020, 0x0},
+ {0x110020, 0x0},
+ {0x210020, 0x0},
+ {0x11020, 0x0},
+ {0x111020, 0x0},
+ {0x211020, 0x0},
+ {0x12020, 0x0},
+ {0x112020, 0x0},
+ {0x212020, 0x0},
+ {0x13020, 0x0},
+ {0x113020, 0x0},
+ {0x213020, 0x0},
+ {0x20072, 0x0},
+ {0x20073, 0x0},
+ {0x20074, 0x0},
+ {0x100aa, 0x0},
+ {0x110aa, 0x0},
+ {0x120aa, 0x0},
+ {0x130aa, 0x0},
+ {0x20010, 0x0},
+ {0x120010, 0x0},
+ {0x220010, 0x0},
+ {0x20011, 0x0},
+ {0x120011, 0x0},
+ {0x220011, 0x0},
+ {0x100ae, 0x0},
+ {0x1100ae, 0x0},
+ {0x2100ae, 0x0},
+ {0x100af, 0x0},
+ {0x1100af, 0x0},
+ {0x2100af, 0x0},
+ {0x110ae, 0x0},
+ {0x1110ae, 0x0},
+ {0x2110ae, 0x0},
+ {0x110af, 0x0},
+ {0x1110af, 0x0},
+ {0x2110af, 0x0},
+ {0x120ae, 0x0},
+ {0x1120ae, 0x0},
+ {0x2120ae, 0x0},
+ {0x120af, 0x0},
+ {0x1120af, 0x0},
+ {0x2120af, 0x0},
+ {0x130ae, 0x0},
+ {0x1130ae, 0x0},
+ {0x2130ae, 0x0},
+ {0x130af, 0x0},
+ {0x1130af, 0x0},
+ {0x2130af, 0x0},
+ {0x20020, 0x0},
+ {0x120020, 0x0},
+ {0x220020, 0x0},
+ {0x100a0, 0x0},
+ {0x100a1, 0x0},
+ {0x100a2, 0x0},
+ {0x100a3, 0x0},
+ {0x100a4, 0x0},
+ {0x100a5, 0x0},
+ {0x100a6, 0x0},
+ {0x100a7, 0x0},
+ {0x110a0, 0x0},
+ {0x110a1, 0x0},
+ {0x110a2, 0x0},
+ {0x110a3, 0x0},
+ {0x110a4, 0x0},
+ {0x110a5, 0x0},
+ {0x110a6, 0x0},
+ {0x110a7, 0x0},
+ {0x120a0, 0x0},
+ {0x120a1, 0x0},
+ {0x120a2, 0x0},
+ {0x120a3, 0x0},
+ {0x120a4, 0x0},
+ {0x120a5, 0x0},
+ {0x120a6, 0x0},
+ {0x120a7, 0x0},
+ {0x130a0, 0x0},
+ {0x130a1, 0x0},
+ {0x130a2, 0x0},
+ {0x130a3, 0x0},
+ {0x130a4, 0x0},
+ {0x130a5, 0x0},
+ {0x130a6, 0x0},
+ {0x130a7, 0x0},
+ {0x2007c, 0x0},
+ {0x12007c, 0x0},
+ {0x22007c, 0x0},
+ {0x2007d, 0x0},
+ {0x12007d, 0x0},
+ {0x22007d, 0x0},
+ {0x400fd, 0x0},
+ {0x400c0, 0x0},
+ {0x90201, 0x0},
+ {0x190201, 0x0},
+ {0x290201, 0x0},
+ {0x90202, 0x0},
+ {0x190202, 0x0},
+ {0x290202, 0x0},
+ {0x90203, 0x0},
+ {0x190203, 0x0},
+ {0x290203, 0x0},
+ {0x90204, 0x0},
+ {0x190204, 0x0},
+ {0x290204, 0x0},
+ {0x90205, 0x0},
+ {0x190205, 0x0},
+ {0x290205, 0x0},
+ {0x90206, 0x0},
+ {0x190206, 0x0},
+ {0x290206, 0x0},
+ {0x90207, 0x0},
+ {0x190207, 0x0},
+ {0x290207, 0x0},
+ {0x90208, 0x0},
+ {0x190208, 0x0},
+ {0x290208, 0x0},
+ {0x10062, 0x0},
+ {0x10162, 0x0},
+ {0x10262, 0x0},
+ {0x10362, 0x0},
+ {0x10462, 0x0},
+ {0x10562, 0x0},
+ {0x10662, 0x0},
+ {0x10762, 0x0},
+ {0x10862, 0x0},
+ {0x11062, 0x0},
+ {0x11162, 0x0},
+ {0x11262, 0x0},
+ {0x11362, 0x0},
+ {0x11462, 0x0},
+ {0x11562, 0x0},
+ {0x11662, 0x0},
+ {0x11762, 0x0},
+ {0x11862, 0x0},
+ {0x12062, 0x0},
+ {0x12162, 0x0},
+ {0x12262, 0x0},
+ {0x12362, 0x0},
+ {0x12462, 0x0},
+ {0x12562, 0x0},
+ {0x12662, 0x0},
+ {0x12762, 0x0},
+ {0x12862, 0x0},
+ {0x13062, 0x0},
+ {0x13162, 0x0},
+ {0x13262, 0x0},
+ {0x13362, 0x0},
+ {0x13462, 0x0},
+ {0x13562, 0x0},
+ {0x13662, 0x0},
+ {0x13762, 0x0},
+ {0x13862, 0x0},
+ {0x20077, 0x0},
+ {0x10001, 0x0},
+ {0x11001, 0x0},
+ {0x12001, 0x0},
+ {0x13001, 0x0},
+ {0x10040, 0x0},
+ {0x10140, 0x0},
+ {0x10240, 0x0},
+ {0x10340, 0x0},
+ {0x10440, 0x0},
+ {0x10540, 0x0},
+ {0x10640, 0x0},
+ {0x10740, 0x0},
+ {0x10840, 0x0},
+ {0x10030, 0x0},
+ {0x10130, 0x0},
+ {0x10230, 0x0},
+ {0x10330, 0x0},
+ {0x10430, 0x0},
+ {0x10530, 0x0},
+ {0x10630, 0x0},
+ {0x10730, 0x0},
+ {0x10830, 0x0},
+ {0x11040, 0x0},
+ {0x11140, 0x0},
+ {0x11240, 0x0},
+ {0x11340, 0x0},
+ {0x11440, 0x0},
+ {0x11540, 0x0},
+ {0x11640, 0x0},
+ {0x11740, 0x0},
+ {0x11840, 0x0},
+ {0x11030, 0x0},
+ {0x11130, 0x0},
+ {0x11230, 0x0},
+ {0x11330, 0x0},
+ {0x11430, 0x0},
+ {0x11530, 0x0},
+ {0x11630, 0x0},
+ {0x11730, 0x0},
+ {0x11830, 0x0},
+ {0x12040, 0x0},
+ {0x12140, 0x0},
+ {0x12240, 0x0},
+ {0x12340, 0x0},
+ {0x12440, 0x0},
+ {0x12540, 0x0},
+ {0x12640, 0x0},
+ {0x12740, 0x0},
+ {0x12840, 0x0},
+ {0x12030, 0x0},
+ {0x12130, 0x0},
+ {0x12230, 0x0},
+ {0x12330, 0x0},
+ {0x12430, 0x0},
+ {0x12530, 0x0},
+ {0x12630, 0x0},
+ {0x12730, 0x0},
+ {0x12830, 0x0},
+ {0x13040, 0x0},
+ {0x13140, 0x0},
+ {0x13240, 0x0},
+ {0x13340, 0x0},
+ {0x13440, 0x0},
+ {0x13540, 0x0},
+ {0x13640, 0x0},
+ {0x13740, 0x0},
+ {0x13840, 0x0},
+ {0x13030, 0x0},
+ {0x13130, 0x0},
+ {0x13230, 0x0},
+ {0x13330, 0x0},
+ {0x13430, 0x0},
+ {0x13530, 0x0},
+ {0x13630, 0x0},
+ {0x13730, 0x0},
+ {0x13830, 0x0},
};
-
/* P0 message block paremeter for training firmware */
struct dram_cfg_param ddr_fsp0_cfg[] = {
{0xd0000, 0x0},
@@ -1054,7 +1055,6 @@ struct dram_cfg_param ddr_fsp0_cfg[] = {
{0x54008, 0x131f},
{0x54009, 0xc8},
{0x5400b, 0x2},
- {0x5400d, 0x100},
{0x54012, 0x110},
{0x54019, 0x2dd4},
{0x5401a, 0x31},
@@ -1094,7 +1094,6 @@ static struct dram_cfg_param ddr_fsp1_cfg[] = {
{0x54008, 0x121f},
{0x54009, 0xc8},
{0x5400b, 0x2},
- {0x5400d, 0x100},
{0x54012, 0x110},
{0x54019, 0x84},
{0x5401a, 0x31},
@@ -1134,7 +1133,6 @@ static struct dram_cfg_param ddr_fsp2_cfg[] = {
{0x54008, 0x121f},
{0x54009, 0xc8},
{0x5400b, 0x2},
- {0x5400d, 0x100},
{0x54012, 0x110},
{0x54019, 0x84},
{0x5401a, 0x31},
@@ -1200,7 +1198,7 @@ static struct dram_cfg_param ddr_fsp0_2d_cfg[] = {
{0x5403b, 0x4d},
{0x5403c, 0x4d},
{0x5403d, 0x1600},
- { 0xd0000, 0x1 },
+ {0xd0000, 0x1},
};
/* DRAM PHY init engine image */
@@ -1693,15 +1691,15 @@ static struct dram_cfg_param ddr_phy_pie[] = {
{0x400d6, 0x20a},
{0x400d7, 0x20b},
{0x2003a, 0x2},
- {0x2000b, 0x5d},
+ {0x2000b, 0x34b},
{0x2000c, 0xbb},
{0x2000d, 0x753},
{0x2000e, 0x2c},
- {0x12000b, 0xc},
+ {0x12000b, 0x70},
{0x12000c, 0x19},
{0x12000d, 0xfa},
{0x12000e, 0x10},
- {0x22000b, 0x3},
+ {0x22000b, 0x1c},
{0x22000c, 0x6},
{0x22000d, 0x3e},
{0x22000e, 0x10},
@@ -1842,5 +1840,5 @@ struct dram_timing_info dram_timing = {
.ddrphy_trained_csr_num = ARRAY_SIZE(ddr_ddrphy_trained_csr),
.ddrphy_pie = ddr_phy_pie,
.ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie),
- .fsp_table = { 3000, 400, 100, },
+ .fsp_table = { 3000, 400, 100,},
};
diff --git a/board/siemens/capricorn/board.c b/board/siemens/capricorn/board.c
index a0c62e0fc4c..924c88e8fab 100644
--- a/board/siemens/capricorn/board.c
+++ b/board/siemens/capricorn/board.c
@@ -147,7 +147,7 @@ static void enet_device_phy_reset(void)
int setup_gpr_fec(void)
{
sc_ipc_t ipc_handle = -1;
- sc_err_t err = 0;
+ int err = 0;
unsigned int test;
/*
@@ -175,35 +175,35 @@ int setup_gpr_fec(void)
*/
err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_TXCLK, 1);
- if (err != SC_ERR_NONE)
+ if (err)
printf("Error in setting up SC_C %d\n\r", SC_C_TXCLK);
sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_TXCLK, &test);
debug("TEST SC_C %d-->%d\n\r", SC_C_TXCLK, test);
err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_CLKDIV, 0);
- if (err != SC_ERR_NONE)
+ if (err)
printf("Error in setting up SC_C %d\n\r", SC_C_CLKDIV);
sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_CLKDIV, &test);
debug("TEST SC_C %d-->%d\n\r", SC_C_CLKDIV, test);
err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_DISABLE_50, 0);
- if (err != SC_ERR_NONE)
+ if (err)
printf("Error in setting up SC_C %d\n\r", SC_C_DISABLE_50);
sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_TXCLK, &test);
debug("TEST SC_C %d-->%d\n\r", SC_C_DISABLE_50, test);
err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_DISABLE_125, 1);
- if (err != SC_ERR_NONE)
+ if (err)
printf("Error in setting up SC_C %d\n\r", SC_C_DISABLE_125);
sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_TXCLK, &test);
debug("TEST SC_C %d-->%d\n\r", SC_C_DISABLE_125, test);
err = sc_misc_set_control(ipc_handle, SC_R_ENET_1, SC_C_SEL_125, 1);
- if (err != SC_ERR_NONE)
+ if (err)
printf("Error in setting up SC_C %d\n\r", SC_C_SEL_125);
sc_misc_get_control(ipc_handle, SC_R_ENET_1, SC_C_SEL_125, &test);
diff --git a/board/sipeed/maix/Kconfig b/board/sipeed/maix/Kconfig
index 2d212ec5a34..d34ea4be71f 100644
--- a/board/sipeed/maix/Kconfig
+++ b/board/sipeed/maix/Kconfig
@@ -34,7 +34,7 @@ config BOARD_SPECIFIC_OPTIONS
imply SMP
imply DM_SERIAL
imply SIFIVE_SERIAL
- imply SIFIVE_CLINT
+ imply RISCV_ACLINT
imply POWER_DOMAIN
imply SIMPLE_PM_BUS
imply CLK_K210
diff --git a/board/starfive/visionfive2/Makefile b/board/starfive/visionfive2/Makefile
index 66c854df390..c7ba4f7ed67 100644
--- a/board/starfive/visionfive2/Makefile
+++ b/board/starfive/visionfive2/Makefile
@@ -5,3 +5,4 @@
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
index db0b4cb4335..7acd3995aad 100644
--- a/board/starfive/visionfive2/spl.c
+++ b/board/starfive/visionfive2/spl.c
@@ -5,16 +5,173 @@
*/
#include <common.h>
+#include <asm/arch/eeprom.h>
#include <asm/arch/regs.h>
#include <asm/arch/spl.h>
#include <asm/io.h>
+#include <dt-bindings/clock/starfive,jh7110-crg.h>
+#include <fdt_support.h>
+#include <linux/libfdt.h>
#include <log.h>
#include <spl.h>
+DECLARE_GLOBAL_DATA_PTR;
#define JH7110_CLK_CPU_ROOT_OFFSET 0x0U
#define JH7110_CLK_CPU_ROOT_SHIFT 24
#define JH7110_CLK_CPU_ROOT_MASK GENMASK(29, 24)
+struct starfive_vf2_pro {
+ const char *path;
+ const char *name;
+ const char *value;
+};
+
+static const struct starfive_vf2_pro starfive_vera[] = {
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "rx-internal-delay-ps",
+ "1900"},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "tx-internal-delay-ps",
+ "1350"}
+};
+
+static const struct starfive_vf2_pro starfive_verb[] = {
+ {"/soc/ethernet@16030000", "starfive,tx-use-rgmii-clk", NULL},
+ {"/soc/ethernet@16040000", "starfive,tx-use-rgmii-clk", NULL},
+
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "motorcomm,tx-clk-adj-enabled", NULL},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "motorcomm,tx-clk-100-inverted", NULL},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "motorcomm,tx-clk-1000-inverted", NULL},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "rx-internal-delay-ps", "1900"},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "tx-internal-delay-ps", "1500"},
+
+ {"/soc/ethernet@16040000/mdio/ethernet-phy@1",
+ "motorcomm,tx-clk-adj-enabled", NULL},
+ { "/soc/ethernet@16040000/mdio/ethernet-phy@1",
+ "motorcomm,tx-clk-100-inverted", NULL},
+ {"/soc/ethernet@16040000/mdio/ethernet-phy@1",
+ "rx-internal-delay-ps", "0"},
+ {"/soc/ethernet@16040000/mdio/ethernet-phy@1",
+ "tx-internal-delay-ps", "0"},
+};
+
+void spl_fdt_fixup_version_a(void *fdt)
+{
+ u32 phandle;
+ u8 i;
+ int offset;
+ int ret;
+
+ fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
+ "StarFive VisionFive 2 v1.2A");
+
+ offset = fdt_path_offset(fdt, "/soc/clock-controller@13020000");
+ phandle = fdt_get_phandle(fdt, offset);
+ offset = fdt_path_offset(fdt, "/soc/ethernet@16040000");
+
+ fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
+ fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_TX);
+ fdt_appendprop_u32(fdt, offset, "assigned-clocks", phandle);
+ fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_RX);
+
+ fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
+ fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
+ JH7110_SYSCLK_GMAC1_RMII_RTX);
+ fdt_appendprop_u32(fdt, offset, "assigned-clock-parents", phandle);
+ fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
+ JH7110_SYSCLK_GMAC1_RMII_RTX);
+
+ fdt_setprop_string(fdt, fdt_path_offset(fdt, "/soc/ethernet@16040000"),
+ "phy-mode", "rmii");
+
+ for (i = 0; i < ARRAY_SIZE(starfive_vera); i++) {
+ offset = fdt_path_offset(fdt, starfive_vera[i].path);
+
+ if (starfive_vera[i].value)
+ ret = fdt_setprop_u32(fdt, offset, starfive_vera[i].name,
+ dectoul(starfive_vera[i].value, NULL));
+ else
+ ret = fdt_setprop_empty(fdt, offset, starfive_vera[i].name);
+
+ if (ret) {
+ pr_err("%s set prop %s fail.\n", __func__, starfive_vera[i].name);
+ break;
+ }
+ }
+}
+
+void spl_fdt_fixup_version_b(void *fdt)
+{
+ u32 phandle;
+ u8 i;
+ int offset;
+ int ret;
+
+ fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
+ "StarFive VisionFive 2 v1.3B");
+
+ /* gmac0 */
+ offset = fdt_path_offset(fdt, "/soc/clock-controller@17000000");
+ phandle = fdt_get_phandle(fdt, offset);
+ offset = fdt_path_offset(fdt, "/soc/ethernet@16030000");
+
+ fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
+ fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_AONCLK_GMAC0_TX);
+ fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
+ fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
+ JH7110_AONCLK_GMAC0_RMII_RTX);
+
+ /* gmac1 */
+ offset = fdt_path_offset(fdt, "/soc/clock-controller@13020000");
+ phandle = fdt_get_phandle(fdt, offset);
+ offset = fdt_path_offset(fdt, "/soc/ethernet@16040000");
+
+ fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
+ fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_TX);
+ fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
+ fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
+ JH7110_SYSCLK_GMAC1_RMII_RTX);
+
+ for (i = 0; i < ARRAY_SIZE(starfive_verb); i++) {
+ offset = fdt_path_offset(fdt, starfive_verb[i].path);
+
+ if (starfive_verb[i].value)
+ ret = fdt_setprop_u32(fdt, offset, starfive_verb[i].name,
+ dectoul(starfive_verb[i].value, NULL));
+ else
+ ret = fdt_setprop_empty(fdt, offset, starfive_verb[i].name);
+
+ if (ret) {
+ pr_err("%s set prop %s fail.\n", __func__, starfive_verb[i].name);
+ break;
+ }
+ }
+}
+
+void spl_perform_fixups(struct spl_image_info *spl_image)
+{
+ u8 version;
+
+ version = get_pcb_revision_from_eeprom();
+ switch (version) {
+ case 'a':
+ case 'A':
+ spl_fdt_fixup_version_a(spl_image->fdt_addr);
+ break;
+
+ case 'b':
+ case 'B':
+ default:
+ spl_fdt_fixup_version_b(spl_image->fdt_addr);
+ break;
+ };
+
+ /* Update the memory size which read form eeprom or DT */
+ fdt_fixup_memory(spl_image->fdt_addr, 0x40000000, gd->ram_size);
+}
int spl_board_init_f(void)
{
int ret;
diff --git a/board/starfive/visionfive2/starfive_visionfive2.c b/board/starfive/visionfive2/starfive_visionfive2.c
index 613fe793c43..07dcca26b30 100644
--- a/board/starfive/visionfive2/starfive_visionfive2.c
+++ b/board/starfive/visionfive2/starfive_visionfive2.c
@@ -6,7 +6,9 @@
#include <common.h>
#include <asm/io.h>
+#include <asm/sections.h>
#include <cpu_func.h>
+#include <dm.h>
#include <linux/bitops.h>
#define JH7110_L2_PREFETCHER_BASE_ADDR 0x2030000
@@ -38,3 +40,14 @@ int board_init(void)
return 0;
}
+
+void *board_fdt_blob_setup(int *err)
+{
+ *err = 0;
+ if (IS_ENABLED(CONFIG_OF_SEPARATE) || IS_ENABLED(CONFIG_OF_BOARD)) {
+ if (gd->arch.firmware_fdt_addr)
+ return (ulong *)(uintptr_t)gd->arch.firmware_fdt_addr;
+ }
+
+ return (ulong *)&_end;
+}
diff --git a/board/starfive/visionfive2/visionfive2-i2c-eeprom.c b/board/starfive/visionfive2/visionfive2-i2c-eeprom.c
new file mode 100644
index 00000000000..befe7888c40
--- /dev/null
+++ b/board/starfive/visionfive2/visionfive2-i2c-eeprom.c
@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
+ * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <env.h>
+#include <i2c.h>
+#include <init.h>
+#include <u-boot/crc.h>
+#include <linux/delay.h>
+
+#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 "6C:CF:39:6C:DE:AD"
+#define STARFIVE_DEFAULT_MAC1 "6C:CF:39:6C:DE:AE"
+
+/* 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
+
+#define MAGIC_NUMBER_BYTES 4
+#define MAC_ADDR_BYTES 6
+#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_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_atom_header {
+ u16 type;
+ u16 count;
+ u32 dlen;
+};
+
+struct 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_atom_header header;
+ struct eeprom_atom1_data data;
+ u16 crc;
+};
+
+struct eeprom_atom4_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 {
+ struct eeprom_atom_header header;
+ struct eeprom_atom4_data data;
+ u16 crc;
+};
+
+struct starfive_eeprom {
+ struct eeprom_header header;
+ struct starfive_eeprom_atom1 atom1;
+ struct starfive_eeprom_atom4 atom4;
+};
+
+static union {
+ struct starfive_eeprom eeprom;
+ uchar buf[STARFIVE_EEPROM_HATS_SIZE_MAX];
+} pbuf __section(".data");
+
+/* Set to 1 if we've read EEPROM into memory */
+static int has_been_read __section(".data");
+
+static inline int is_match_magic(void)
+{
+ return strncmp(pbuf.eeprom.header.signature, STARFIVE_EEPROM_HATS_SIG,
+ MAGIC_NUMBER_BYTES);
+}
+
+/* Calculate the current CRC */
+static inline u32 calculate_crc16(struct eeprom_atom_header *head)
+{
+ uint len = sizeof(struct eeprom_atom_header) + head->dlen - sizeof(u16);
+
+ return crc16(0, (void *)head, len);
+}
+
+/* This function should be called after each update to the EEPROM structure */
+static inline void update_crc(void)
+{
+ pbuf.eeprom.atom1.crc = calculate_crc16(&pbuf.eeprom.atom1.header);
+ pbuf.eeprom.atom4.crc = calculate_crc16(&pbuf.eeprom.atom4.header);
+}
+
+static void dump_raw_eeprom(void)
+{
+ unsigned int i;
+ u32 len;
+
+ len = sizeof(struct starfive_eeprom);
+ for (i = 0; i < len; i++) {
+ if ((i % 16) == 0)
+ printf("%02X: ", i);
+ printf("%02X ", ((u8 *)pbuf.buf)[i]);
+ if (((i % 16) == 15) || (i == len - 1))
+ printf("\n");
+ }
+}
+
+/**
+ * show_eeprom - display the contents of the EEPROM
+ */
+static void show_eeprom(void)
+{
+ if (has_been_read != 1)
+ return;
+
+ printf("\n--------EEPROM INFO--------\n");
+ printf("Vendor : %s\n", pbuf.eeprom.atom1.data.vstr);
+ printf("Product full SN: %s\n", pbuf.eeprom.atom1.data.pstr);
+ printf("data version: 0x%x\n", pbuf.eeprom.atom4.data.version);
+ if (pbuf.eeprom.atom4.data.version == 2) {
+ printf("PCB revision: 0x%x\n", pbuf.eeprom.atom4.data.pcb_revision);
+ printf("BOM revision: %c\n", pbuf.eeprom.atom4.data.bom_revision);
+ printf("Ethernet MAC0 address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pbuf.eeprom.atom4.data.mac0_addr[0], pbuf.eeprom.atom4.data.mac0_addr[1],
+ pbuf.eeprom.atom4.data.mac0_addr[2], pbuf.eeprom.atom4.data.mac0_addr[3],
+ pbuf.eeprom.atom4.data.mac0_addr[4], pbuf.eeprom.atom4.data.mac0_addr[5]);
+ printf("Ethernet MAC1 address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pbuf.eeprom.atom4.data.mac1_addr[0], pbuf.eeprom.atom4.data.mac1_addr[1],
+ pbuf.eeprom.atom4.data.mac1_addr[2], pbuf.eeprom.atom4.data.mac1_addr[3],
+ pbuf.eeprom.atom4.data.mac1_addr[4], pbuf.eeprom.atom4.data.mac1_addr[5]);
+ } else {
+ printf("Custom data v%d is not Supported\n", pbuf.eeprom.atom4.data.version);
+ }
+ printf("--------EEPROM INFO--------\n\n");
+}
+
+/**
+ * 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)
+{
+ u8 i;
+ u8 *mac;
+
+ 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;
+ }
+ mac = (index == 0) ? pbuf.eeprom.atom4.data.mac0_addr :
+ pbuf.eeprom.atom4.data.mac1_addr;
+
+ for (i = 0; *string && (i < MAC_ADDR_BYTES); i++) {
+ mac[i] = hextoul(string, &string);
+
+ if (*string == ':')
+ string++;
+ }
+
+ update_crc();
+}
+
+/**
+ * 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(void)
+{
+ memset((void *)pbuf.buf, 0, sizeof(struct starfive_eeprom));
+ memcpy(pbuf.eeprom.header.signature, STARFIVE_EEPROM_HATS_SIG,
+ strlen(STARFIVE_EEPROM_HATS_SIG));
+ pbuf.eeprom.header.version = FORMAT_VERSION;
+ pbuf.eeprom.header.numatoms = 2;
+ pbuf.eeprom.header.eeplen = sizeof(struct starfive_eeprom);
+
+ pbuf.eeprom.atom1.header.type = HATS_ATOM_VENDOR;
+ pbuf.eeprom.atom1.header.count = 1;
+ pbuf.eeprom.atom1.header.dlen = sizeof(struct eeprom_atom1_data) + sizeof(u16);
+ pbuf.eeprom.atom1.data.vslen = STARFIVE_EEPROM_ATOM1_VSTR_SIZE;
+ pbuf.eeprom.atom1.data.pslen = STARFIVE_EEPROM_ATOM1_PSTR_SIZE;
+ memcpy(pbuf.eeprom.atom1.data.vstr, STARFIVE_EEPROM_ATOM1_VSTR,
+ strlen(STARFIVE_EEPROM_ATOM1_VSTR));
+ memcpy(pbuf.eeprom.atom1.data.pstr, STARFIVE_EEPROM_ATOM1_PSTR,
+ strlen(STARFIVE_EEPROM_ATOM1_PSTR));
+
+ pbuf.eeprom.atom4.header.type = HATS_ATOM_CUSTOM;
+ pbuf.eeprom.atom4.header.count = 2;
+ pbuf.eeprom.atom4.header.dlen = sizeof(struct eeprom_atom4_data) + sizeof(u16);
+ pbuf.eeprom.atom4.data.version = FORMAT_VERSION;
+ pbuf.eeprom.atom4.data.pcb_revision = PCB_VERSION;
+ pbuf.eeprom.atom4.data.bom_revision = BOM_VERSION;
+ set_mac_address(STARFIVE_DEFAULT_MAC0, 0);
+ set_mac_address(STARFIVE_DEFAULT_MAC1, 1);
+}
+
+/**
+ * prog_eeprom() - write the EEPROM from memory
+ */
+static int prog_eeprom(unsigned int size)
+{
+ unsigned int i;
+ void *p;
+ uchar tmp_buff[STARFIVE_EEPROM_HATS_SIZE_MAX];
+ struct udevice *dev;
+ int ret;
+
+ if (is_match_magic()) {
+ printf("MAGIC ERROR, Please check the data@%p.\n", pbuf.buf);
+ return -1;
+ }
+
+ 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) {
+ printf("Get i2c bus:%d addr:%d fail.\n", CONFIG_SYS_EEPROM_BUS_NUM,
+ CONFIG_SYS_I2C_EEPROM_ADDR);
+ return ret;
+ }
+
+ for (i = 0, p = (u8 *)pbuf.buf; i < size; ) {
+ if (!ret)
+ ret = dm_i2c_write(dev, i, p, min((int)(size - i),
+ BYTES_PER_EEPROM_PAGE));
+ if (ret)
+ break;
+
+ udelay(EEPROM_WRITE_DELAY_MS);
+ i += BYTES_PER_EEPROM_PAGE;
+ p += BYTES_PER_EEPROM_PAGE;
+ }
+
+ 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 *)pbuf.buf, (void *)tmp_buff,
+ STARFIVE_EEPROM_HATS_SIZE_MAX))
+ ret = -1;
+ }
+
+ if (ret) {
+ has_been_read = -1;
+ printf("Programming failed.\n");
+ return -1;
+ }
+
+ printf("Programming passed.\n");
+ return 0;
+}
+
+/**
+ * read_eeprom() - read the EEPROM into memory, if it hasn't been read already
+ */
+static int read_eeprom(void)
+{
+ 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, 1, &dev);
+ if (!ret)
+ ret = dm_i2c_read(dev, 0, (u8 *)pbuf.buf,
+ STARFIVE_EEPROM_HATS_SIZE_MAX);
+
+ has_been_read = (ret == 0) ? 1 : 0;
+
+ return ret;
+}
+
+/**
+ * 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)
+{
+ u32 p;
+
+ p = simple_strtoul(string, &string, 16);
+ if (p > U8_MAX) {
+ printf("%s must not be greater than %d\n", "PCB revision",
+ U8_MAX);
+ return;
+ }
+
+ pbuf.eeprom.atom4.data.pcb_revision = p;
+
+ update_crc();
+}
+
+/**
+ * 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)
+{
+ if (string[0] < 'A' || string[0] > 'Z') {
+ printf("BOM revision must be an uppercase letter between A and Z\n");
+ return;
+ }
+
+ pbuf.eeprom.atom4.data.bom_revision = string[0];
+
+ update_crc();
+}
+
+/**
+ * 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)
+{
+ u32 len;
+
+ len = (strlen(string) > STARFIVE_EEPROM_ATOM1_PSTR_SIZE) ?
+ STARFIVE_EEPROM_ATOM1_PSTR_SIZE : strlen(string);
+
+ memcpy((void *)pbuf.eeprom.atom1.data.pstr, (void *)string, len);
+
+ update_crc();
+}
+
+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();
+ 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();
+ } else if (!strcmp(cmd, "initialize")) {
+ init_local_copy();
+ return 0;
+ } else if (!strcmp(cmd, "write_eeprom")) {
+ return prog_eeprom(STARFIVE_EEPROM_HATS_SIZE_MAX);
+ }
+
+ if (argc != 3)
+ return print_usage();
+
+ if (is_match_magic()) {
+ 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()) {
+ dump_raw_eeprom();
+ return 0;
+ }
+
+ // 1, setup ethaddr env
+ eth_env_set_enetaddr("eth0addr", pbuf.eeprom.atom4.data.mac0_addr);
+ eth_env_set_enetaddr("eth1addr", pbuf.eeprom.atom4.data.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#", pbuf.eeprom.atom1.data.pstr);
+
+ printf("StarFive EEPROM format v%u\n", pbuf.eeprom.header.version);
+ show_eeprom();
+ return 0;
+}
+
+/**
+ * get_pcb_revision_from_eeprom - get the PCB revision
+ *
+ * 1.2A return 'A'/'a', 1.3B return 'B'/'b',other values are illegal
+ */
+u8 get_pcb_revision_from_eeprom(void)
+{
+ u8 pv = 0xFF;
+
+ if (read_eeprom())
+ return pv;
+
+ return pbuf.eeprom.atom1.data.pstr[6];
+}
+
+/**
+ * get_ddr_size_from_eeprom - get the DDR size
+ * pstr: VF7110A1-2228-D008E000-00000001
+ * VF7110A1/VF7110B1 : VisionFive JH7110A /VisionFive JH7110B
+ * D008:怀8GB LPDDR4
+ * E000: No emmc device, ECxx: include emmc device, xx: Capacity size[GB]
+ * return: the field of 'D008E000'
+ */
+
+u32 get_ddr_size_from_eeprom(void)
+{
+ u32 pv = 0xFFFFFFFF;
+
+ if (read_eeprom())
+ return pv;
+
+ return hextoul(&pbuf.eeprom.atom1.data.pstr[14], NULL);
+}
diff --git a/board/technexion/pico-imx8mq/pico-imx8mq.c b/board/technexion/pico-imx8mq/pico-imx8mq.c
index 951e3e1985b..2be3206f78a 100644
--- a/board/technexion/pico-imx8mq/pico-imx8mq.c
+++ b/board/technexion/pico-imx8mq/pico-imx8mq.c
@@ -54,7 +54,7 @@ int board_early_init_f(void)
int board_phys_sdram_size(phys_size_t *size)
{
- int ddr_size = readl(M4_BOOTROM_BASE_ADDR);
+ int ddr_size = readl(MCU_BOOTROM_BASE_ADDR);
if (ddr_size == 0x4) {
*size = 0x100000000;
diff --git a/board/technexion/pico-imx8mq/spl.c b/board/technexion/pico-imx8mq/spl.c
index 8b853a914e8..2afb4d37608 100644
--- a/board/technexion/pico-imx8mq/spl.c
+++ b/board/technexion/pico-imx8mq/spl.c
@@ -89,7 +89,7 @@ static void spl_dram_init(void)
printf("%s: LPDDR4 %d GiB\n", __func__, size);
ddr_init(dram_timing);
- writel(size, M4_BOOTROM_BASE_ADDR);
+ writel(size, MCU_BOOTROM_BASE_ADDR);
}
#define USDHC2_CD_GPIO IMX_GPIO_NR(2, 12)
diff --git a/board/thead/th1520_lpi4a/Kconfig b/board/thead/th1520_lpi4a/Kconfig
new file mode 100644
index 00000000000..622246127c1
--- /dev/null
+++ b/board/thead/th1520_lpi4a/Kconfig
@@ -0,0 +1,42 @@
+if TARGET_TH1520_LPI4A
+
+config ARCH_THEAD
+ bool
+ default y
+
+config SYS_BOARD
+ default "th1520_lpi4a"
+
+config SYS_VENDOR
+ default "thead"
+
+config SYS_CPU
+ default "generic"
+
+config SYS_CONFIG_NAME
+ default "th1520_lpi4a"
+
+config TEXT_BASE
+ default 0x01b00000 if SPL
+ default 0x01c00000 if !RISCV_SMODE
+ default 0x01c00000 if RISCV_SMODE
+
+config SPL_TEXT_BASE
+ default 0x08000000
+
+config SPL_OPENSBI_LOAD_ADDR
+ default 0x80000000
+
+config BOARD_SPECIFIC_OPTIONS
+ def_bool y
+ select ARCH_EARLY_INIT_R
+ imply CPU
+ imply CPU_RISCV
+ imply RISCV_TIMER if RISCV_SMODE
+ imply CMD_CPU
+ imply SMP
+ imply SUPPORT_OF_CONTROL
+ imply OF_CONTROL
+ imply OF_REAL
+
+endif
diff --git a/board/thead/th1520_lpi4a/MAINTAINERS b/board/thead/th1520_lpi4a/MAINTAINERS
new file mode 100644
index 00000000000..36c7ab7cc30
--- /dev/null
+++ b/board/thead/th1520_lpi4a/MAINTAINERS
@@ -0,0 +1,7 @@
+Lichee PI 4A
+M: Wei Fu <wefu@redhat.com>
+M: Yixun Lan <dlan@gentoo.org>
+S: Maintained
+F: board/thead/th1520_lpi4a/
+F: configs/th1520_lpi4a_defconfig
+F: doc/board/thead/lpi4a.rst
diff --git a/board/thead/th1520_lpi4a/Makefile b/board/thead/th1520_lpi4a/Makefile
new file mode 100644
index 00000000000..9671b3bbb0b
--- /dev/null
+++ b/board/thead/th1520_lpi4a/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2023, Yixun Lan <dlan@gentoo.org>
+
+obj-y += board.o
diff --git a/board/thead/th1520_lpi4a/board.c b/board/thead/th1520_lpi4a/board.c
new file mode 100644
index 00000000000..16c3e456b3e
--- /dev/null
+++ b/board/thead/th1520_lpi4a/board.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023, Yixun Lan <dlan@gentoo.org>
+ *
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+
+int board_init(void)
+{
+ enable_caches();
+
+ return 0;
+}
diff --git a/board/thecus/n2350/n2350.c b/board/thecus/n2350/n2350.c
index fd8f95f9446..05b125fd7f8 100644
--- a/board/thecus/n2350/n2350.c
+++ b/board/thecus/n2350/n2350.c
@@ -25,7 +25,7 @@ DECLARE_GLOBAL_DATA_PTR;
#define N2350_GPP_OUT_ENA_LOW (~(BIT(20) | BIT(21) | BIT(24)))
#define N2350_GPP_OUT_ENA_MID (~(BIT(12) | BIT(13) | BIT(16) | BIT(19) | BIT(22)))
#define N2350_GPP_OUT_VAL_LOW (BIT(21) | BIT(24))
-#define N2350_GPP_OUT_VAL_MID (BIT(0) | BIT(12) | BIT(13))
+#define N2350_GPP_OUT_VAL_MID (BIT(0) | BIT(12) | BIT(13) | BIT(16))
#define N2350_GPP_POL_LOW 0x0
#define N2350_GPP_POL_MID 0x0
diff --git a/board/toradex/apalis-imx8/apalis-imx8.c b/board/toradex/apalis-imx8/apalis-imx8.c
index aa76c486eec..e2bbaba8b8c 100644
--- a/board/toradex/apalis-imx8/apalis-imx8.c
+++ b/board/toradex/apalis-imx8/apalis-imx8.c
@@ -85,18 +85,18 @@ static void setup_iomux_uart(void)
static uint32_t do_get_tdx_user_fuse(int a, int b)
{
- sc_err_t sciErr;
+ int sciErr;
u32 val_a = 0;
u32 val_b = 0;
sciErr = sc_misc_otp_fuse_read(-1, a, &val_a);
- if (sciErr != SC_ERR_NONE) {
+ if (sciErr) {
printf("Error reading out user fuse %d\n", a);
return 0;
}
sciErr = sc_misc_otp_fuse_read(-1, b, &val_b);
- if (sciErr != SC_ERR_NONE) {
+ if (sciErr) {
printf("Error reading out user fuse %d\n", b);
return 0;
}
@@ -131,9 +131,9 @@ void board_mem_get_layout(u64 *phys_sdram_1_start,
{
u32 is_quadplus = 0, val = 0;
struct tdx_user_fuses tdxramfuses;
- sc_err_t scierr = sc_misc_otp_fuse_read(-1, 6, &val);
+ int scierr = sc_misc_otp_fuse_read(-1, 6, &val);
- if (scierr == SC_ERR_NONE) {
+ if (scierr) {
/* QP has one A72 core disabled */
is_quadplus = ((val >> 4) & 0x3) != 0x0;
}
diff --git a/board/toradex/colibri-imx8x/colibri-imx8x.c b/board/toradex/colibri-imx8x/colibri-imx8x.c
index 52fc7a391bb..6c0b09787c8 100644
--- a/board/toradex/colibri-imx8x/colibri-imx8x.c
+++ b/board/toradex/colibri-imx8x/colibri-imx8x.c
@@ -12,6 +12,7 @@
#include <asm/arch/imx8-pins.h>
#include <asm/arch/iomux.h>
#include <firmware/imx/sci/sci.h>
+#include <asm/arch/snvs_security_sc.h>
#include <asm/arch/sys_proto.h>
#include <asm/gpio.h>
#include <asm/io.h>
@@ -43,9 +44,9 @@ static void setup_iomux_uart(void)
static int is_imx8dx(void)
{
u32 val = 0;
- sc_err_t sc_err = sc_misc_otp_fuse_read(-1, 6, &val);
+ int sc_err = sc_misc_otp_fuse_read(-1, 6, &val);
- if (sc_err == SC_ERR_NONE) {
+ if (sc_err) {
/* DX has two A35 cores disabled */
return (val & 0xf) != 0x0;
}
@@ -70,7 +71,7 @@ void board_mem_get_layout(u64 *phys_sdram_1_start,
int board_early_init_f(void)
{
sc_pm_clock_rate_t rate;
- sc_err_t err = 0;
+ int err;
/*
* This works around that having only UART3 up the baudrate is 1.2M
@@ -78,13 +79,13 @@ int board_early_init_f(void)
*/
rate = 80000000;
err = sc_pm_set_clock_rate(-1, SC_R_UART_0, SC_PM_CLK_PER, &rate);
- if (err != SC_ERR_NONE)
+ if (err)
return 0;
/* Set UART3 clock root to 80 MHz and enable it */
rate = SC_80MHZ;
err = sc_pm_setup_uart(SC_R_UART_3, rate);
- if (err != SC_ERR_NONE)
+ if (err)
return 0;
setup_iomux_uart();
@@ -139,6 +140,13 @@ int board_init(void)
{
board_gpio_init();
+ if (IS_ENABLED(CONFIG_IMX_SNVS_SEC_SC_AUTO)) {
+ int ret = snvs_security_sc_init();
+
+ if (ret)
+ return ret;
+ }
+
return 0;
}
@@ -170,6 +178,8 @@ int board_late_init(void)
env_set("board_rev", "v1.0");
#endif
+ build_info();
+
select_dt_from_module_version();
return 0;
diff --git a/board/toradex/colibri_imx6/colibri_imx6.c b/board/toradex/colibri_imx6/colibri_imx6.c
index 65e0e9a156a..677caa4a4eb 100644
--- a/board/toradex/colibri_imx6/colibri_imx6.c
+++ b/board/toradex/colibri_imx6/colibri_imx6.c
@@ -767,8 +767,7 @@ MX6_MMDC_P1_MPRDDQBY3DL, 0x33333333,
/*
* MDMISC mirroring interleaved (row/bank/col)
*/
-/* TODO: check what the RALAT field does */
-MX6_MMDC_P0_MDMISC, 0x00081740,
+MX6_MMDC_P0_MDMISC, 0x000b17c0,
/*
* MDSCR con_req
@@ -900,8 +899,7 @@ MX6_MMDC_P1_MPRDDQBY3DL, 0x33333333,
/*
* MDMISC mirroring interleaved (row/bank/col)
*/
-/* TODO: check what the RALAT field does */
-MX6_MMDC_P0_MDMISC, 0x00081740,
+MX6_MMDC_P0_MDMISC, 0x000b17c0,
/*
* MDSCR con_req
diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c
index 11f4d5e14a8..e513f4a2919 100644
--- a/board/toradex/common/tdx-cfg-block.c
+++ b/board/toradex/common/tdx-cfg-block.c
@@ -139,6 +139,7 @@ const struct toradex_som toradex_modules[] = {
[66] = { "Verdin iMX8M Plus Quad 8GB WB", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
[67] = { "Apalis iMX8QM 8GB WB IT", TARGET_IS_ENABLED(APALIS_IMX8) },
[68] = { "Verdin iMX8M Mini Quad 2GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
+ [70] = { "Verdin iMX8M Plus Quad 8GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
};
const char * const toradex_carrier_boards[] = {
diff --git a/board/toradex/common/tdx-cfg-block.h b/board/toradex/common/tdx-cfg-block.h
index 32e4c6f6879..45fa04ca38a 100644
--- a/board/toradex/common/tdx-cfg-block.h
+++ b/board/toradex/common/tdx-cfg-block.h
@@ -94,6 +94,8 @@ enum {
VERDIN_IMX8MPQ_8GB_WIFI_BT,
APALIS_IMX8QM_8GB_WIFI_BT_IT,
VERDIN_IMX8MMQ_WIFI_BT_IT_NO_CAN,
+ /* 69 */
+ VERDIN_IMX8MPQ_8GB_WIFI_BT_IT = 70, /* 70 */
};
enum {
diff --git a/board/toradex/verdin-imx8mm/MAINTAINERS b/board/toradex/verdin-imx8mm/MAINTAINERS
index 974b3a10329..b0f4329253a 100644
--- a/board/toradex/verdin-imx8mm/MAINTAINERS
+++ b/board/toradex/verdin-imx8mm/MAINTAINERS
@@ -3,7 +3,6 @@ M: Marcel Ziswiler <marcel.ziswiler@toradex.com>
W: https://www.toradex.com/computer-on-modules/verdin-arm-family/nxp-imx-8m-mini
S: Maintained
F: arch/arm/dts/imx8mm-verdin.dtsi
-F: arch/arm/dts/imx8mm-verdin-dahlia.dtsi
F: arch/arm/dts/imx8mm-verdin-dev.dtsi
F: arch/arm/dts/imx8mm-verdin-wifi.dtsi
F: arch/arm/dts/imx8mm-verdin-wifi-dev.dts
diff --git a/board/toradex/verdin-imx8mp/MAINTAINERS b/board/toradex/verdin-imx8mp/MAINTAINERS
index cff3c503838..ea04a83926a 100644
--- a/board/toradex/verdin-imx8mp/MAINTAINERS
+++ b/board/toradex/verdin-imx8mp/MAINTAINERS
@@ -1,6 +1,5 @@
Verdin iMX8M Plus
F: arch/arm/dts/imx8mp-verdin.dtsi
-F: arch/arm/dts/imx8mp-verdin-dahlia.dtsi
F: arch/arm/dts/imx8mp-verdin-dev.dtsi
F: arch/arm/dts/imx8mp-verdin-wifi.dtsi
F: arch/arm/dts/imx8mp-verdin-wifi-dev.dts
diff --git a/board/toradex/verdin-imx8mp/verdin-imx8mp.c b/board/toradex/verdin-imx8mp/verdin-imx8mp.c
index 5490d3ed44a..e16a771e3ec 100644
--- a/board/toradex/verdin-imx8mp/verdin-imx8mp.c
+++ b/board/toradex/verdin-imx8mp/verdin-imx8mp.c
@@ -81,7 +81,8 @@ static void select_dt_from_module_version(void)
*/
is_wifi = (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_WIFI_BT_IT) ||
(tdx_hw_tag.prodid == VERDIN_IMX8MPQ_2GB_WIFI_BT_IT) ||
- (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_8GB_WIFI_BT);
+ (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_8GB_WIFI_BT) ||
+ (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_8GB_WIFI_BT_IT);
}
if (is_wifi)
diff --git a/board/variscite/imx8mn_var_som/imx8mn_var_som.c b/board/variscite/imx8mn_var_som/imx8mn_var_som.c
index d40f4d01761..61b9455a8f4 100644
--- a/board/variscite/imx8mn_var_som/imx8mn_var_som.c
+++ b/board/variscite/imx8mn_var_som/imx8mn_var_som.c
@@ -1,11 +1,50 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2021 Collabora Ltd.
+ * Copyright 2018-2020 Variscite Ltd.
+ * Copyright 2023 DimOnOff Inc.
*/
#include <common.h>
+#include <dm.h>
#include <env.h>
+#include <fdtdec.h>
+#include <fdt_support.h>
+#include <i2c_eeprom.h>
+#include <malloc.h>
#include <asm/io.h>
+#include <asm/global_data.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <linux/libfdt.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Optional SOM features flags. */
+#define VAR_EEPROM_F_WIFI BIT(0)
+#define VAR_EEPROM_F_ETH BIT(1) /* Ethernet PHY on SOM. */
+#define VAR_EEPROM_F_AUDIO BIT(2)
+#define VAR_EEPROM_F_MX8M_LVDS BIT(3) /* i.MX8MM, i.MX8MN, i.MX8MQ only */
+#define VAR_EEPROM_F_MX8Q_SOC_ID BIT(3) /* 0 = i.MX8QM, 1 = i.MX8QP */
+#define VAR_EEPROM_F_NAND BIT(4)
+
+#define VAR_IMX8_EEPROM_MAGIC 0x384D /* "8M" */
+
+/* Number of DRAM adjustment tables. */
+#define DRAM_TABLES_NUM 7
+
+struct var_imx8_eeprom_info {
+ u16 magic;
+ u8 partnumber[3]; /* Part number */
+ u8 assembly[10]; /* Assembly number */
+ u8 date[9]; /* Build date */
+ u8 mac[6]; /* MAC address */
+ u8 somrev;
+ u8 eeprom_version;
+ u8 features; /* SOM features */
+ u8 dramsize; /* DRAM size */
+ u8 off[DRAM_TABLES_NUM + 1]; /* DRAM table offsets */
+ u8 partnumber2[5]; /* Part number 2 */
+} __packed;
static void setup_fec(void)
{
@@ -28,3 +67,178 @@ int board_mmc_get_env_dev(int devno)
{
return devno;
}
+
+#if !defined(CONFIG_SPL_BUILD)
+
+#if defined(CONFIG_DISPLAY_BOARDINFO)
+
+static void display_som_infos(struct var_imx8_eeprom_info *info)
+{
+ char partnumber[sizeof(info->partnumber) +
+ sizeof(info->partnumber2) + 1];
+ char assembly[sizeof(info->assembly) + 1];
+ char date[sizeof(info->date) + 1];
+
+ /* Read first part of P/N. */
+ memcpy(partnumber, info->partnumber, sizeof(info->partnumber));
+
+ /* Read second part of P/N. */
+ if (info->eeprom_version >= 3)
+ memcpy(partnumber + sizeof(info->partnumber), info->partnumber2,
+ sizeof(info->partnumber2));
+
+ memcpy(assembly, info->assembly, sizeof(info->assembly));
+ memcpy(date, info->date, sizeof(info->date));
+
+ /* Make sure strings are null terminated. */
+ partnumber[sizeof(partnumber) - 1] = '\0';
+ assembly[sizeof(assembly) - 1] = '\0';
+ date[sizeof(date) - 1] = '\0';
+
+ printf("SOM board: P/N: %s, Assy: %s, Date: %s\n"
+ " Wifi: %s, EthPhy: %s, Rev: %d\n",
+ partnumber, assembly, date,
+ info->features & VAR_EEPROM_F_WIFI ? "yes" : "no",
+ info->features & VAR_EEPROM_F_ETH ? "yes" : "no",
+ info->somrev);
+}
+
+static int var_read_som_eeprom(struct var_imx8_eeprom_info *info)
+{
+ const char *path = "eeprom-som";
+ struct udevice *dev;
+ int ret, off;
+
+ off = fdt_path_offset(gd->fdt_blob, path);
+ if (off < 0) {
+ pr_err("%s: fdt_path_offset() failed: %d\n", __func__, off);
+ return off;
+ }
+
+ ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, off, &dev);
+ if (ret) {
+ pr_err("%s: uclass_get_device_by_of_offset() failed: %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = i2c_eeprom_read(dev, 0, (uint8_t *)info,
+ sizeof(struct var_imx8_eeprom_info));
+ if (ret) {
+ pr_err("%s: i2c_eeprom_read() failed: %d\n", __func__, ret);
+ return ret;
+ }
+
+ if (htons(info->magic) != VAR_IMX8_EEPROM_MAGIC) {
+ /* Do not fail if the content is invalid */
+ pr_err("Board: Invalid board info magic: 0x%08x, expected 0x%08x\n",
+ htons(info->magic), VAR_IMX8_EEPROM_MAGIC);
+ }
+
+ return 0;
+}
+
+int checkboard(void)
+{
+ int rc;
+ struct var_imx8_eeprom_info *info;
+
+ info = malloc(sizeof(struct var_imx8_eeprom_info));
+ if (!info)
+ return -ENOMEM;
+
+ rc = var_read_som_eeprom(info);
+ if (rc)
+ return rc;
+
+ display_som_infos(info);
+
+#if defined(CONFIG_BOARD_TYPES)
+ gd->board_type = info->features;
+#endif /* CONFIG_BOARD_TYPES */
+
+ return 0;
+}
+
+#endif /* CONFIG_DISPLAY_BOARDINFO */
+
+static int insert_gpios_prop(void *blob, int node, const char *prop,
+ unsigned int phandle, u32 gpio, u32 flags)
+{
+ fdt32_t val[3] = { cpu_to_fdt32(phandle), cpu_to_fdt32(gpio),
+ cpu_to_fdt32(flags) };
+ return fdt_setprop(blob, node, prop, &val, sizeof(val));
+}
+
+static int configure_phy_reset_gpios(void *blob)
+{
+ int node;
+ int phynode;
+ int ret;
+ u32 handle;
+ u32 gpio;
+ u32 flags;
+ char path[1024];
+ const char *eth_alias = "ethernet0";
+
+ snprintf(path, sizeof(path), "%s/mdio/ethernet-phy@4",
+ fdt_get_alias(blob, eth_alias));
+
+ phynode = fdt_path_offset(blob, path);
+ if (phynode < 0) {
+ pr_err("%s(): unable to locate PHY node: %s\n", __func__, path);
+ return 0;
+ }
+
+ if (gd_board_type() & VAR_EEPROM_F_ETH) {
+ snprintf(path, sizeof(path), "%s",
+ fdt_get_alias(blob, "gpio0")); /* Alias to gpio1 */
+ gpio = 9;
+ flags = GPIO_ACTIVE_LOW;
+ } else {
+ snprintf(path, sizeof(path), "%s/gpio@20",
+ fdt_get_alias(blob, "i2c1")); /* Alias to i2c2 */
+ gpio = 5;
+ flags = GPIO_ACTIVE_HIGH;
+ }
+
+ node = fdt_path_offset(blob, path);
+ if (node < 0) {
+ pr_err("%s(): unable to locate GPIO node: %s\n", __func__,
+ path);
+ return 0;
+ }
+
+ handle = fdt_get_phandle(blob, node);
+ if (handle < 0) {
+ pr_err("%s(): unable to locate GPIO controller handle: %s\n",
+ __func__, path);
+ }
+
+ ret = insert_gpios_prop(blob, phynode, "reset-gpios",
+ handle, gpio, flags);
+ if (ret < 0) {
+ pr_err("%s(): failed to set reset-gpios property\n", __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
+#if defined(CONFIG_OF_BOARD_FIXUP)
+int board_fix_fdt(void *blob)
+{
+ /* Fix U-Boot device tree: */
+ return configure_phy_reset_gpios(blob);
+}
+#endif /* CONFIG_OF_BOARD_FIXUP */
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+ /* Fix kernel device tree: */
+ return configure_phy_reset_gpios(blob);
+}
+#endif /* CONFIG_OF_BOARD_SETUP */
+
+#endif /* CONFIG_SPL_BUILD */
diff --git a/boot/Kconfig b/boot/Kconfig
index a643a3d1286..c8b8f36d835 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -1630,4 +1630,18 @@ config SAVE_PREV_BL_INITRAMFS_START_ADDR
If no initramfs was provided by previous bootloader, no env variables
will be created.
+menu "Configuration editor"
+
+config CEDIT
+ bool "Configuration editor"
+ depends on BOOTSTD
+ help
+ Provides a way to deal with board configuration and present it to
+ the user for adjustment.
+
+ This is intended to provide both graphical and text-based user
+ interfaces, but only graphical is support at present.
+
+endmenu # Configuration editor
+
endmenu # Booting
diff --git a/boot/Makefile b/boot/Makefile
index f94c31d922d..f828f870a37 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -33,6 +33,7 @@ ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL
obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o
obj-$(CONFIG_$(SPL_TPL_)EXPO) += bootflow_menu.o
obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow_menu.o
+obj-$(CONFIG_$(SPL_TPL_)CEDIT) += cedit.o
endif
obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o
@@ -50,7 +51,7 @@ ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o
endif
-obj-$(CONFIG_$(SPL_TPL_)EXPO) += expo.o scene.o scene_menu.o
+obj-$(CONFIG_$(SPL_TPL_)EXPO) += expo.o scene.o scene_menu.o expo_build.o
obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE) += vbe.o
obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE_REQUEST) += vbe_request.o
diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c
index 7f06dac0af7..7c1abe5772c 100644
--- a/boot/bootflow_menu.c
+++ b/boot/bootflow_menu.c
@@ -124,6 +124,10 @@ int bootflow_menu_new(struct expo **expp)
priv->num_bootflows++;
}
+ ret = scene_arrange(scn);
+ if (ret)
+ return log_msg_ret("arr", ret);
+
*expp = exp;
return 0;
@@ -205,7 +209,7 @@ int bootflow_menu_run(struct bootstd_priv *std, bool text_mode,
return log_msg_ret("scn", ret);
if (text_mode)
- exp_set_text_mode(exp, text_mode);
+ expo_set_text_mode(exp, text_mode);
done = false;
do {
diff --git a/boot/bootmeth-uclass.c b/boot/bootmeth-uclass.c
index 3b3e0614daf..701ee8ad1c8 100644
--- a/boot/bootmeth-uclass.c
+++ b/boot/bootmeth-uclass.c
@@ -301,32 +301,6 @@ int bootmeth_try_file(struct bootflow *bflow, struct blk_desc *desc,
return 0;
}
-static int alloc_file(const char *fname, uint size, void **bufp)
-{
- loff_t bytes_read;
- ulong addr;
- char *buf;
- int ret;
-
- buf = malloc(size + 1);
- if (!buf)
- return log_msg_ret("buf", -ENOMEM);
- addr = map_to_sysmem(buf);
-
- ret = fs_read(fname, addr, 0, size, &bytes_read);
- if (ret) {
- free(buf);
- return log_msg_ret("read", ret);
- }
- if (size != bytes_read)
- return log_msg_ret("bread", -EIO);
- buf[size] = '\0';
-
- *bufp = buf;
-
- return 0;
-}
-
int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align)
{
void *buf;
@@ -338,7 +312,7 @@ int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align)
if (size > size_limit)
return log_msg_ret("chk", -E2BIG);
- ret = alloc_file(bflow->fname, bflow->size, &buf);
+ ret = fs_read_alloc(bflow->fname, bflow->size, align, &buf);
if (ret)
return log_msg_ret("all", ret);
@@ -374,7 +348,7 @@ int bootmeth_alloc_other(struct bootflow *bflow, const char *fname,
if (ret)
return log_msg_ret("fs", ret);
- ret = alloc_file(path, size, &buf);
+ ret = fs_read_alloc(path, size, 0, &buf);
if (ret)
return log_msg_ret("all", ret);
diff --git a/boot/cedit.c b/boot/cedit.c
new file mode 100644
index 00000000000..ee24658917b
--- /dev/null
+++ b/boot/cedit.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Implementation of configuration editor
+ *
+ * Copyright 2023 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <cli.h>
+#include <dm.h>
+#include <expo.h>
+#include <menu.h>
+#include <video.h>
+#include <linux/delay.h>
+#include "scene_internal.h"
+
+int cedit_arange(struct expo *exp, struct video_priv *vpriv, uint scene_id)
+{
+ struct scene_obj_txt *txt;
+ struct scene_obj *obj;
+ struct scene *scn;
+ int y;
+
+ scn = expo_lookup_scene_id(exp, scene_id);
+ if (!scn)
+ return log_msg_ret("scn", -ENOENT);
+
+ txt = scene_obj_find_by_name(scn, "prompt");
+ if (txt)
+ scene_obj_set_pos(scn, txt->obj.id, 0, vpriv->ysize - 50);
+
+ txt = scene_obj_find_by_name(scn, "title");
+ if (txt)
+ scene_obj_set_pos(scn, txt->obj.id, 200, 10);
+
+ y = 100;
+ list_for_each_entry(obj, &scn->obj_head, sibling) {
+ if (obj->type == SCENEOBJT_MENU) {
+ scene_obj_set_pos(scn, obj->id, 50, y);
+ scene_menu_arrange(scn, (struct scene_obj_menu *)obj);
+ y += 50;
+ }
+ }
+
+ return 0;
+}
+
+int cedit_run(struct expo *exp)
+{
+ struct cli_ch_state s_cch, *cch = &s_cch;
+ struct video_priv *vid_priv;
+ uint scene_id;
+ struct udevice *dev;
+ struct scene *scn;
+ bool done;
+ int ret;
+
+ cli_ch_init(cch);
+
+ /* For now we only support a video console */
+ ret = uclass_first_device_err(UCLASS_VIDEO, &dev);
+ if (ret)
+ return log_msg_ret("vid", ret);
+ ret = expo_set_display(exp, dev);
+ if (ret)
+ return log_msg_ret("dis", ret);
+
+ ret = expo_first_scene_id(exp);
+ if (ret < 0)
+ return log_msg_ret("scn", ret);
+ scene_id = ret;
+
+ ret = expo_set_scene_id(exp, scene_id);
+ if (ret)
+ return log_msg_ret("sid", ret);
+
+ exp->popup = true;
+
+ /* This is not supported for now */
+ if (0)
+ expo_set_text_mode(exp, true);
+
+ vid_priv = dev_get_uclass_priv(dev);
+
+ scn = expo_lookup_scene_id(exp, scene_id);
+ scene_highlight_first(scn);
+
+ cedit_arange(exp, vid_priv, scene_id);
+
+ ret = expo_calc_dims(exp);
+ if (ret)
+ return log_msg_ret("dim", ret);
+
+ done = false;
+ do {
+ struct expo_action act;
+ int ichar, key;
+
+ ret = expo_render(exp);
+ if (ret)
+ break;
+
+ ichar = cli_ch_process(cch, 0);
+ if (!ichar) {
+ while (!ichar && !tstc()) {
+ schedule();
+ mdelay(2);
+ ichar = cli_ch_process(cch, -ETIMEDOUT);
+ }
+ if (!ichar) {
+ ichar = getchar();
+ ichar = cli_ch_process(cch, ichar);
+ }
+ }
+
+ key = 0;
+ if (ichar) {
+ key = bootmenu_conv_key(ichar);
+ if (key == BKEY_NONE)
+ key = ichar;
+ }
+ if (!key)
+ continue;
+
+ ret = expo_send_key(exp, key);
+ if (ret)
+ break;
+
+ ret = expo_action_get(exp, &act);
+ if (!ret) {
+ switch (act.type) {
+ case EXPOACT_POINT_OBJ:
+ scene_set_highlight_id(scn, act.select.id);
+ cedit_arange(exp, vid_priv, scene_id);
+ break;
+ case EXPOACT_OPEN:
+ scene_set_open(scn, act.select.id, true);
+ cedit_arange(exp, vid_priv, scene_id);
+ break;
+ case EXPOACT_CLOSE:
+ scene_set_open(scn, act.select.id, false);
+ cedit_arange(exp, vid_priv, scene_id);
+ break;
+ case EXPOACT_SELECT:
+ scene_set_open(scn, scn->highlight_id, false);
+ cedit_arange(exp, vid_priv, scene_id);
+ break;
+ case EXPOACT_QUIT:
+ log_debug("quitting\n");
+ done = true;
+ break;
+ default:
+ break;
+ }
+ }
+ } while (!done);
+
+ if (ret)
+ return log_msg_ret("end", ret);
+
+ return 0;
+}
diff --git a/boot/expo.c b/boot/expo.c
index 05950a17603..db837f7b492 100644
--- a/boot/expo.c
+++ b/boot/expo.c
@@ -6,6 +6,8 @@
* Written by Simon Glass <sjg@chromium.org>
*/
+#define LOG_CATEGORY LOGC_EXPO
+
#include <common.h>
#include <dm.h>
#include <expo.h>
@@ -54,6 +56,22 @@ void expo_destroy(struct expo *exp)
free(exp);
}
+uint resolve_id(struct expo *exp, uint id)
+{
+ log_debug("resolve id %d\n", id);
+ if (!id)
+ id = exp->next_id++;
+ else if (id >= exp->next_id)
+ exp->next_id = id + 1;
+
+ return id;
+}
+
+void expo_set_dynamic_start(struct expo *exp, uint dyn_start)
+{
+ exp->next_id = dyn_start;
+}
+
int expo_str(struct expo *exp, const char *name, uint id, const char *str)
{
struct expo_string *estr;
@@ -83,12 +101,45 @@ const char *expo_get_str(struct expo *exp, uint id)
int expo_set_display(struct expo *exp, struct udevice *dev)
{
+ struct udevice *cons;
+ int ret;
+
+ ret = device_find_first_child_by_uclass(dev, UCLASS_VIDEO_CONSOLE,
+ &cons);
+ if (ret)
+ return log_msg_ret("con", ret);
+
exp->display = dev;
+ exp->cons = cons;
+
+ return 0;
+}
+
+int expo_calc_dims(struct expo *exp)
+{
+ struct scene *scn;
+ int ret;
+
+ if (!exp->cons)
+ return log_msg_ret("dim", -ENOTSUPP);
+
+ list_for_each_entry(scn, &exp->scene_head, sibling) {
+ /*
+ * Do the menus last so that all the menus' text objects
+ * are dimensioned
+ */
+ ret = scene_calc_dims(scn, false);
+ if (ret)
+ return log_msg_ret("scn", ret);
+ ret = scene_calc_dims(scn, true);
+ if (ret)
+ return log_msg_ret("scn", ret);
+ }
return 0;
}
-void exp_set_text_mode(struct expo *exp, bool text_mode)
+void expo_set_text_mode(struct expo *exp, bool text_mode)
{
exp->text_mode = text_mode;
}
@@ -107,13 +158,33 @@ struct scene *expo_lookup_scene_id(struct expo *exp, uint scene_id)
int expo_set_scene_id(struct expo *exp, uint scene_id)
{
- if (!expo_lookup_scene_id(exp, scene_id))
+ struct scene *scn;
+ int ret;
+
+ scn = expo_lookup_scene_id(exp, scene_id);
+ if (!scn)
return log_msg_ret("id", -ENOENT);
+ ret = scene_arrange(scn);
+ if (ret)
+ return log_msg_ret("arr", ret);
+
exp->scene_id = scene_id;
return 0;
}
+int expo_first_scene_id(struct expo *exp)
+{
+ struct scene *scn;
+
+ if (list_empty(&exp->scene_head))
+ return -ENOENT;
+
+ scn = list_first_entry(&exp->scene_head, struct scene, sibling);
+
+ return scn->id;
+}
+
int expo_render(struct expo *exp)
{
struct udevice *dev = exp->display;
@@ -156,6 +227,11 @@ int expo_send_key(struct expo *exp, int key)
ret = scene_send_key(scn, key, &exp->action);
if (ret)
return log_msg_ret("key", ret);
+
+ /* arrange it to get any changes */
+ ret = scene_arrange(scn);
+ if (ret)
+ return log_msg_ret("arr", ret);
}
return scn ? 0 : -ECHILD;
@@ -168,3 +244,25 @@ int expo_action_get(struct expo *exp, struct expo_action *act)
return act->type == EXPOACT_NONE ? -EAGAIN : 0;
}
+
+int expo_apply_theme(struct expo *exp, ofnode node)
+{
+ struct scene *scn;
+ struct expo_theme *theme = &exp->theme;
+ int ret;
+
+ log_debug("Applying theme %s\n", ofnode_get_name(node));
+
+ memset(theme, '\0', sizeof(struct expo_theme));
+ ofnode_read_u32(node, "font-size", &theme->font_size);
+ ofnode_read_u32(node, "menu-inset", &theme->menu_inset);
+ ofnode_read_u32(node, "menuitem-gap-y", &theme->menuitem_gap_y);
+
+ list_for_each_entry(scn, &exp->scene_head, sibling) {
+ ret = scene_apply_theme(scn, theme);
+ if (ret)
+ return log_msg_ret("app", ret);
+ }
+
+ return 0;
+}
diff --git a/boot/expo_build.c b/boot/expo_build.c
new file mode 100644
index 00000000000..22f62eb54bc
--- /dev/null
+++ b/boot/expo_build.c
@@ -0,0 +1,401 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Building an expo from an FDT description
+ *
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#define LOG_CATEGORY LOGC_EXPO
+
+#include <common.h>
+#include <expo.h>
+#include <fdtdec.h>
+#include <log.h>
+#include <malloc.h>
+#include <dm/ofnode.h>
+#include <linux/libfdt.h>
+
+/**
+ * struct build_info - Information to use when building
+ *
+ * @str_for_id: String for each ID in use, NULL if empty. The string is NULL
+ * if there is nothing for this ID. Since ID 0 is never used, the first
+ * element of this array is always NULL
+ * @str_count: Number of entries in @str_for_id
+ */
+struct build_info {
+ const char **str_for_id;
+ int str_count;
+};
+
+/**
+ * add_txt_str - Add a string or lookup its ID, then add to expo
+ *
+ * @info: Build information
+ * @node: Node describing scene
+ * @scn: Scene to add to
+ * @find_name: Name to look for (e.g. "title"). This will find a property called
+ * "title" if it exists, else will look up the string for "title-id"
+ * Return: ID of added string, or -ve on error
+ */
+int add_txt_str(struct build_info *info, ofnode node, struct scene *scn,
+ const char *find_name, uint obj_id)
+{
+ const char *text;
+ uint str_id;
+ int ret;
+
+ text = ofnode_read_string(node, find_name);
+ if (!text) {
+ char name[40];
+ u32 id;
+
+ snprintf(name, sizeof(name), "%s-id", find_name);
+ ret = ofnode_read_u32(node, name, &id);
+ if (ret)
+ return log_msg_ret("id", -EINVAL);
+
+ if (id >= info->str_count)
+ return log_msg_ret("id", -E2BIG);
+ text = info->str_for_id[id];
+ if (!text)
+ return log_msg_ret("id", -EINVAL);
+ }
+
+ ret = expo_str(scn->expo, find_name, 0, text);
+ if (ret < 0)
+ return log_msg_ret("add", ret);
+ str_id = ret;
+
+ ret = scene_txt_str(scn, find_name, obj_id, str_id, text, NULL);
+ if (ret < 0)
+ return log_msg_ret("add", ret);
+
+ return ret;
+}
+
+/**
+ * add_txt_str_list - Add a list string or lookup its ID, then add to expo
+ *
+ * @info: Build information
+ * @node: Node describing scene
+ * @scn: Scene to add to
+ * @find_name: Name to look for (e.g. "title"). This will find a string-list
+ * property called "title" if it exists, else will look up the string in the
+ * "title-id" string list.
+ * Return: ID of added string, or -ve on error
+ */
+int add_txt_str_list(struct build_info *info, ofnode node, struct scene *scn,
+ const char *find_name, int index, uint obj_id)
+{
+ const char *text;
+ uint str_id;
+ int ret;
+
+ ret = ofnode_read_string_index(node, find_name, index, &text);
+ if (ret) {
+ char name[40];
+ u32 id;
+
+ snprintf(name, sizeof(name), "%s-id", find_name);
+ ret = ofnode_read_u32_index(node, name, index, &id);
+ if (ret)
+ return log_msg_ret("id", -ENOENT);
+
+ if (id >= info->str_count)
+ return log_msg_ret("id", -E2BIG);
+ text = info->str_for_id[id];
+ if (!text)
+ return log_msg_ret("id", -EINVAL);
+ }
+
+ ret = expo_str(scn->expo, find_name, 0, text);
+ if (ret < 0)
+ return log_msg_ret("add", ret);
+ str_id = ret;
+
+ ret = scene_txt_str(scn, find_name, obj_id, str_id, text, NULL);
+ if (ret < 0)
+ return log_msg_ret("add", ret);
+
+ return ret;
+}
+
+/*
+ * build_element() - Handle creating a text object from a label
+ *
+ * Look up a property called @label or @label-id and create a string for it
+ */
+int build_element(void *ldtb, int node, const char *label)
+{
+ return 0;
+}
+
+/**
+ * read_strings() - Read in the list of strings
+ *
+ * Read the strings into an ID-indexed list, so they can be used for building
+ * an expo. The strings are in a /strings node and each has its own subnode
+ * containing the ID and the string itself:
+ *
+ * example {
+ * id = <123>;
+ * value = "This is a test";
+ * };
+ *
+ * Future work may add support for unicode and multiple languages
+ *
+ * @info: Build information
+ * @root: Root node to read from
+ * Returns: 0 if OK, -ENOMEM if out of memory, -EINVAL if there is a format
+ * error
+ */
+static int read_strings(struct build_info *info, ofnode root)
+{
+ ofnode strings, node;
+
+ strings = ofnode_find_subnode(root, "strings");
+ if (!ofnode_valid(strings))
+ return log_msg_ret("str", -EINVAL);
+
+ ofnode_for_each_subnode(node, strings) {
+ const char *val;
+ int ret;
+ u32 id;
+
+ ret = ofnode_read_u32(node, "id", &id);
+ if (ret)
+ return log_msg_ret("id", -EINVAL);
+ val = ofnode_read_string(node, "value");
+ if (!val)
+ return log_msg_ret("val", -EINVAL);
+
+ if (id >= info->str_count) {
+ int new_count = info->str_count + 20;
+ void *new_arr;
+
+ new_arr = realloc(info->str_for_id,
+ new_count * sizeof(char *));
+ if (!new_arr)
+ return log_msg_ret("id", -ENOMEM);
+ memset(new_arr + info->str_count, '\0',
+ (new_count - info->str_count) * sizeof(char *));
+ info->str_for_id = new_arr;
+ info->str_count = new_count;
+ }
+
+ info->str_for_id[id] = val;
+ }
+
+ return 0;
+}
+
+/**
+ * list_strings() - List the available strings with their IDs
+ *
+ * @info: Build information
+ */
+static void list_strings(struct build_info *info)
+{
+ int i;
+
+ for (i = 0; i < info->str_count; i++) {
+ if (info->str_for_id[i])
+ printf("%3d %s\n", i, info->str_for_id[i]);
+ }
+}
+
+/**
+ * menu_build() - Build a menu and add it to a scene
+ *
+ * See doc/developer/expo.rst for a description of the format
+ *
+ * @info: Build information
+ * @node: Node containing the menu description
+ * @scn: Scene to add the menu to
+ * Returns: 0 if OK, -ENOMEM if out of memory, -EINVAL if there is a format
+ * error, -ENOENT if there is a references to a non-existent string
+ */
+static int menu_build(struct build_info *info, ofnode node, struct scene *scn)
+{
+ struct scene_obj_menu *menu;
+ uint title_id, menu_id;
+ const u32 *item_ids;
+ int ret, size, i;
+ const char *name;
+ u32 id;
+
+ name = ofnode_get_name(node);
+ ret = ofnode_read_u32(node, "id", &id);
+ if (ret)
+ return log_msg_ret("id", -EINVAL);
+
+ ret = scene_menu(scn, name, id, &menu);
+ if (ret < 0)
+ return log_msg_ret("men", ret);
+ menu_id = ret;
+
+ /* Set the title */
+ ret = add_txt_str(info, node, scn, "title", 0);
+ if (ret < 0)
+ return log_msg_ret("tit", ret);
+ title_id = ret;
+ ret = scene_menu_set_title(scn, menu_id, title_id);
+
+ item_ids = ofnode_read_prop(node, "item-id", &size);
+ if (!item_ids)
+ return log_msg_ret("itm", -EINVAL);
+ if (!size || size % sizeof(u32))
+ return log_msg_ret("isz", -EINVAL);
+ size /= sizeof(u32);
+
+ for (i = 0; i < size; i++) {
+ struct scene_menitem *item;
+ uint label, key, desc;
+
+ ret = add_txt_str_list(info, node, scn, "item-label", i, 0);
+ if (ret < 0 && ret != -ENOENT)
+ return log_msg_ret("lab", ret);
+ label = max(0, ret);
+
+ ret = add_txt_str_list(info, node, scn, "key-label", i, 0);
+ if (ret < 0 && ret != -ENOENT)
+ return log_msg_ret("key", ret);
+ key = max(0, ret);
+
+ ret = add_txt_str_list(info, node, scn, "desc-label", i, 0);
+ if (ret < 0 && ret != -ENOENT)
+ return log_msg_ret("lab", ret);
+ desc = max(0, ret);
+
+ ret = scene_menuitem(scn, menu_id, simple_xtoa(i),
+ fdt32_to_cpu(item_ids[i]), key, label,
+ desc, 0, 0, &item);
+ if (ret < 0)
+ return log_msg_ret("mi", ret);
+ }
+
+ return 0;
+}
+
+/**
+ * menu_build() - Build an expo object and add it to a scene
+ *
+ * See doc/developer/expo.rst for a description of the format
+ *
+ * @info: Build information
+ * @node: Node containing the object description
+ * @scn: Scene to add the object to
+ * Returns: 0 if OK, -ENOMEM if out of memory, -EINVAL if there is a format
+ * error, -ENOENT if there is a references to a non-existent string
+ */
+static int obj_build(struct build_info *info, ofnode node, struct scene *scn)
+{
+ const char *type;
+ u32 id;
+ int ret;
+
+ log_debug("- object %s\n", ofnode_get_name(node));
+ ret = ofnode_read_u32(node, "id", &id);
+ if (ret)
+ return log_msg_ret("id", -EINVAL);
+
+ type = ofnode_read_string(node, "type");
+ if (!type)
+ return log_msg_ret("typ", -EINVAL);
+
+ if (!strcmp("menu", type))
+ ret = menu_build(info, node, scn);
+ else
+ ret = -EINVAL;
+ if (ret)
+ return log_msg_ret("bld", ret);
+
+ return 0;
+}
+
+/**
+ * scene_build() - Build a scene and all its objects
+ *
+ * See doc/developer/expo.rst for a description of the format
+ *
+ * @info: Build information
+ * @node: Node containing the scene description
+ * @scn: Scene to add the object to
+ * Returns: 0 if OK, -ENOMEM if out of memory, -EINVAL if there is a format
+ * error, -ENOENT if there is a references to a non-existent string
+ */
+static int scene_build(struct build_info *info, ofnode scn_node,
+ struct expo *exp)
+{
+ const char *name;
+ struct scene *scn;
+ uint id, title_id;
+ ofnode node;
+ int ret;
+
+ name = ofnode_get_name(scn_node);
+ log_debug("Building scene %s\n", name);
+ ret = ofnode_read_u32(scn_node, "id", &id);
+ if (ret)
+ return log_msg_ret("id", -EINVAL);
+
+ ret = scene_new(exp, name, id, &scn);
+ if (ret < 0)
+ return log_msg_ret("scn", ret);
+
+ ret = add_txt_str(info, scn_node, scn, "title", 0);
+ if (ret < 0)
+ return log_msg_ret("tit", ret);
+ title_id = ret;
+ scene_title_set(scn, title_id);
+
+ ret = add_txt_str(info, scn_node, scn, "prompt", 0);
+ if (ret < 0)
+ return log_msg_ret("pr", ret);
+
+ ofnode_for_each_subnode(node, scn_node) {
+ ret = obj_build(info, node, scn);
+ if (ret < 0)
+ return log_msg_ret("mit", ret);
+ }
+
+ return 0;
+}
+
+int expo_build(ofnode root, struct expo **expp)
+{
+ struct build_info info;
+ ofnode scenes, node;
+ struct expo *exp;
+ u32 dyn_start;
+ int ret;
+
+ memset(&info, '\0', sizeof(info));
+ ret = read_strings(&info, root);
+ if (ret)
+ return log_msg_ret("str", ret);
+ if (_DEBUG)
+ list_strings(&info);
+
+ ret = expo_new("name", NULL, &exp);
+ if (ret)
+ return log_msg_ret("exp", ret);
+
+ if (!ofnode_read_u32(root, "dynamic-start", &dyn_start))
+ expo_set_dynamic_start(exp, dyn_start);
+
+ scenes = ofnode_find_subnode(root, "scenes");
+ if (!ofnode_valid(scenes))
+ return log_msg_ret("sno", -EINVAL);
+
+ ofnode_for_each_subnode(node, scenes) {
+ ret = scene_build(&info, node, exp);
+ if (ret < 0)
+ return log_msg_ret("scn", ret);
+ }
+ *expp = exp;
+
+ return 0;
+}
diff --git a/boot/scene.c b/boot/scene.c
index 030f6aa2a0a..e52333371f9 100644
--- a/boot/scene.c
+++ b/boot/scene.c
@@ -6,26 +6,19 @@
* Written by Simon Glass <sjg@chromium.org>
*/
+#define LOG_CATEGORY LOGC_EXPO
+
#include <common.h>
#include <dm.h>
#include <expo.h>
#include <malloc.h>
#include <mapmem.h>
+#include <menu.h>
#include <video.h>
#include <video_console.h>
#include <linux/input.h>
#include "scene_internal.h"
-uint resolve_id(struct expo *exp, uint id)
-{
- if (!id)
- id = exp->next_id++;
- else if (id >= exp->next_id)
- exp->next_id = id + 1;
-
- return id;
-}
-
int scene_new(struct expo *exp, const char *name, uint id, struct scene **scnp)
{
struct scene *scn;
@@ -65,16 +58,12 @@ void scene_destroy(struct scene *scn)
scene_obj_destroy(obj);
free(scn->name);
- free(scn->title);
free(scn);
}
-int scene_title_set(struct scene *scn, const char *title)
+int scene_title_set(struct scene *scn, uint id)
{
- free(scn->title);
- scn->title = strdup(title);
- if (!scn->title)
- return log_msg_ret("tit", -ENOMEM);
+ scn->title_id = id;
return 0;
}
@@ -103,6 +92,18 @@ void *scene_obj_find(struct scene *scn, uint id, enum scene_obj_t type)
return NULL;
}
+void *scene_obj_find_by_name(struct scene *scn, const char *name)
+{
+ struct scene_obj *obj;
+
+ list_for_each_entry(obj, &scn->obj_head, sibling) {
+ if (!strcmp(name, obj->name))
+ return obj;
+ }
+
+ return NULL;
+}
+
int scene_obj_add(struct scene *scn, const char *name, uint id,
enum scene_obj_t type, uint size, struct scene_obj **objp)
{
@@ -213,22 +214,46 @@ int scene_obj_set_pos(struct scene *scn, uint id, int x, int y)
obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
if (!obj)
return log_msg_ret("find", -ENOENT);
- obj->x = x;
- obj->y = y;
- if (obj->type == SCENEOBJT_MENU)
- scene_menu_arrange(scn, (struct scene_obj_menu *)obj);
+ obj->dim.x = x;
+ obj->dim.y = y;
+
+ return 0;
+}
+
+int scene_obj_set_size(struct scene *scn, uint id, int w, int h)
+{
+ struct scene_obj *obj;
+
+ obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
+ if (!obj)
+ return log_msg_ret("find", -ENOENT);
+ obj->dim.w = w;
+ obj->dim.h = h;
return 0;
}
int scene_obj_set_hide(struct scene *scn, uint id, bool hide)
{
+ int ret;
+
+ ret = scene_obj_flag_clrset(scn, id, SCENEOF_HIDE,
+ hide ? SCENEOF_HIDE : 0);
+ if (ret)
+ return log_msg_ret("flg", ret);
+
+ return 0;
+}
+
+int scene_obj_flag_clrset(struct scene *scn, uint id, uint clr, uint set)
+{
struct scene_obj *obj;
obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
if (!obj)
return log_msg_ret("find", -ENOENT);
- obj->hide = hide;
+ obj->flags &= ~clr;
+ obj->flags |= set;
return 0;
}
@@ -258,16 +283,30 @@ int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
case SCENEOBJT_TEXT: {
struct scene_obj_txt *txt = (struct scene_obj_txt *)obj;
struct expo *exp = scn->expo;
+ struct vidconsole_bbox bbox;
+ const char *str;
+ int len, ret;
+ str = expo_get_str(exp, txt->str_id);
+ if (!str)
+ return log_msg_ret("str", -ENOENT);
+ len = strlen(str);
+
+ /* if there is no console, make it up */
+ if (!exp->cons) {
+ if (widthp)
+ *widthp = 8 * len;
+ return 16;
+ }
+
+ ret = vidconsole_measure(scn->expo->cons, txt->font_name,
+ txt->font_size, str, &bbox);
+ if (ret)
+ return log_msg_ret("mea", ret);
if (widthp)
- *widthp = 16; /* fake value for now */
- if (txt->font_size)
- return txt->font_size;
- if (exp->display)
- return video_default_font_height(exp->display);
-
- /* use a sensible default */
- return 16;
+ *widthp = bbox.x1;
+
+ return bbox.y1;
}
}
@@ -282,18 +321,13 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode)
{
struct scene *scn = obj->scene;
struct expo *exp = scn->expo;
- struct udevice *cons, *dev = exp->display;
+ const struct expo_theme *theme = &exp->theme;
+ struct udevice *dev = exp->display;
+ struct udevice *cons = text_mode ? NULL : exp->cons;
int x, y, ret;
- cons = NULL;
- if (!text_mode) {
- ret = device_find_first_child_by_uclass(dev,
- UCLASS_VIDEO_CONSOLE,
- &cons);
- }
-
- x = obj->x;
- y = obj->y;
+ x = obj->dim.x;
+ y = obj->dim.y;
switch (obj->type) {
case SCENEOBJT_NONE:
@@ -325,14 +359,45 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode)
}
if (ret && ret != -ENOSYS)
return log_msg_ret("font", ret);
- vidconsole_set_cursor_pos(cons, x, y);
str = expo_get_str(exp, txt->str_id);
- if (str)
+ if (str) {
+ struct video_priv *vid_priv;
+ struct vidconsole_colour old;
+ enum colour_idx fore, back;
+
+ if (CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK)) {
+ fore = VID_BLACK;
+ back = VID_WHITE;
+ } else {
+ fore = VID_LIGHT_GRAY;
+ back = VID_BLACK;
+ }
+
+ vid_priv = dev_get_uclass_priv(dev);
+ if (obj->flags & SCENEOF_POINT) {
+ vidconsole_push_colour(cons, fore, back, &old);
+ video_fill_part(dev, x - theme->menu_inset, y,
+ x + obj->dim.w,
+ y + obj->dim.h,
+ vid_priv->colour_bg);
+ }
+ vidconsole_set_cursor_pos(cons, x, y);
vidconsole_put_string(cons, str);
+ if (obj->flags & SCENEOF_POINT)
+ vidconsole_pop_colour(cons, &old);
+ }
break;
}
case SCENEOBJT_MENU: {
struct scene_obj_menu *menu = (struct scene_obj_menu *)obj;
+
+ if (exp->popup && (obj->flags & SCENEOF_OPEN)) {
+ if (!cons)
+ return -ENOTSUPP;
+
+ /* draw a background behind the menu items */
+ scene_menu_render(menu);
+ }
/*
* With a vidconsole, the text and item pointer are rendered as
* normal objects so we don't need to do anything here. The menu
@@ -371,6 +436,30 @@ int scene_arrange(struct scene *scn)
return 0;
}
+int scene_render_deps(struct scene *scn, uint id)
+{
+ struct scene_obj *obj;
+ int ret;
+
+ if (!id)
+ return 0;
+ obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
+ if (!obj)
+ return log_msg_ret("obj", -ENOENT);
+
+ if (!(obj->flags & SCENEOF_HIDE)) {
+ ret = scene_obj_render(obj, false);
+ if (ret && ret != -ENOTSUPP)
+ return log_msg_ret("ren", ret);
+
+ if (obj->type == SCENEOBJT_MENU)
+ scene_menu_render_deps(scn,
+ (struct scene_obj_menu *)obj);
+ }
+
+ return 0;
+}
+
int scene_render(struct scene *scn)
{
struct expo *exp = scn->expo;
@@ -378,21 +467,107 @@ int scene_render(struct scene *scn)
int ret;
list_for_each_entry(obj, &scn->obj_head, sibling) {
- if (!obj->hide) {
+ if (!(obj->flags & SCENEOF_HIDE)) {
ret = scene_obj_render(obj, exp->text_mode);
if (ret && ret != -ENOTSUPP)
return log_msg_ret("ren", ret);
}
}
+ /* render any highlighted object on top of the others */
+ if (scn->highlight_id && !exp->text_mode) {
+ ret = scene_render_deps(scn, scn->highlight_id);
+ if (ret && ret != -ENOTSUPP)
+ return log_msg_ret("dep", ret);
+ }
+
return 0;
}
+/**
+ * send_key_obj() - Handle a keypress for moving between objects
+ *
+ * @scn: Scene to receive the key
+ * @key: Key to send (KEYCODE_UP)
+ * @event: Returns resulting event from this keypress
+ * Returns: 0 if OK, -ve on error
+ */
+static void send_key_obj(struct scene *scn, struct scene_obj *obj, int key,
+ struct expo_action *event)
+{
+ switch (key) {
+ case BKEY_UP:
+ while (obj != list_first_entry(&scn->obj_head, struct scene_obj,
+ sibling)) {
+ obj = list_entry(obj->sibling.prev,
+ struct scene_obj, sibling);
+ if (obj->type == SCENEOBJT_MENU) {
+ event->type = EXPOACT_POINT_OBJ;
+ event->select.id = obj->id;
+ log_debug("up to obj %d\n", event->select.id);
+ break;
+ }
+ }
+ break;
+ case BKEY_DOWN:
+ while (!list_is_last(&obj->sibling, &scn->obj_head)) {
+ obj = list_entry(obj->sibling.next, struct scene_obj,
+ sibling);
+ if (obj->type == SCENEOBJT_MENU) {
+ event->type = EXPOACT_POINT_OBJ;
+ event->select.id = obj->id;
+ log_debug("down to obj %d\n", event->select.id);
+ break;
+ }
+ }
+ break;
+ case BKEY_SELECT:
+ if (obj->type == SCENEOBJT_MENU) {
+ event->type = EXPOACT_OPEN;
+ event->select.id = obj->id;
+ log_debug("open obj %d\n", event->select.id);
+ }
+ break;
+ case BKEY_QUIT:
+ event->type = EXPOACT_QUIT;
+ log_debug("obj quit\n");
+ break;
+ }
+}
+
int scene_send_key(struct scene *scn, int key, struct expo_action *event)
{
+ struct scene_obj_menu *menu;
struct scene_obj *obj;
int ret;
+ event->type = EXPOACT_NONE;
+
+ /*
+ * In 'popup' mode, arrow keys move betwen objects, unless a menu is
+ * opened
+ */
+ if (scn->expo->popup) {
+ obj = NULL;
+ if (scn->highlight_id) {
+ obj = scene_obj_find(scn, scn->highlight_id,
+ SCENEOBJT_NONE);
+ }
+ if (!obj)
+ return 0;
+
+ if (!(obj->flags & SCENEOF_OPEN)) {
+ send_key_obj(scn, obj, key, event);
+ return 0;
+ }
+
+ menu = (struct scene_obj_menu *)obj,
+ ret = scene_menu_send_key(scn, menu, key, event);
+ if (ret)
+ return log_msg_ret("key", ret);
+ return 0;
+ }
+
list_for_each_entry(obj, &scn->obj_head, sibling) {
if (obj->type == SCENEOBJT_MENU) {
struct scene_obj_menu *menu;
@@ -401,14 +576,108 @@ int scene_send_key(struct scene *scn, int key, struct expo_action *event)
ret = scene_menu_send_key(scn, menu, key, event);
if (ret)
return log_msg_ret("key", ret);
+ break;
+ }
+ }
- /* only allow one menu */
- ret = scene_menu_arrange(scn, menu);
- if (ret)
- return log_msg_ret("arr", ret);
+ return 0;
+}
+
+int scene_calc_dims(struct scene *scn, bool do_menus)
+{
+ struct scene_obj *obj;
+ int ret;
+
+ list_for_each_entry(obj, &scn->obj_head, sibling) {
+ switch (obj->type) {
+ case SCENEOBJT_NONE:
+ case SCENEOBJT_TEXT:
+ case SCENEOBJT_IMAGE: {
+ int width;
+
+ if (!do_menus) {
+ ret = scene_obj_get_hw(scn, obj->id, &width);
+ if (ret < 0)
+ return log_msg_ret("get", ret);
+ obj->dim.w = width;
+ obj->dim.h = ret;
+ }
+ break;
+ }
+ case SCENEOBJT_MENU: {
+ struct scene_obj_menu *menu;
+
+ if (do_menus) {
+ menu = (struct scene_obj_menu *)obj;
+
+ ret = scene_menu_calc_dims(menu);
+ if (ret)
+ return log_msg_ret("men", ret);
+ }
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int scene_apply_theme(struct scene *scn, struct expo_theme *theme)
+{
+ struct scene_obj *obj;
+ int ret;
+
+ /* Avoid error-checking optional items */
+ scene_txt_set_font(scn, scn->title_id, NULL, theme->font_size);
+
+ list_for_each_entry(obj, &scn->obj_head, sibling) {
+ switch (obj->type) {
+ case SCENEOBJT_NONE:
+ case SCENEOBJT_IMAGE:
+ case SCENEOBJT_MENU:
+ break;
+ case SCENEOBJT_TEXT:
+ scene_txt_set_font(scn, obj->id, NULL,
+ theme->font_size);
+ break;
+ }
+ }
+
+ ret = scene_arrange(scn);
+ if (ret)
+ return log_msg_ret("arr", ret);
+
+ return 0;
+}
+
+void scene_set_highlight_id(struct scene *scn, uint id)
+{
+ scn->highlight_id = id;
+}
+
+void scene_highlight_first(struct scene *scn)
+{
+ struct scene_obj *obj;
+
+ list_for_each_entry(obj, &scn->obj_head, sibling) {
+ switch (obj->type) {
+ case SCENEOBJT_MENU:
+ scene_set_highlight_id(scn, obj->id);
+ return;
+ default:
break;
}
}
+}
+
+int scene_set_open(struct scene *scn, uint id, bool open)
+{
+ int ret;
+
+ ret = scene_obj_flag_clrset(scn, id, SCENEOF_OPEN,
+ open ? SCENEOF_OPEN : 0);
+ if (ret)
+ return log_msg_ret("flg", ret);
return 0;
}
diff --git a/boot/scene_internal.h b/boot/scene_internal.h
index e8fd765811e..fb1ea5533b9 100644
--- a/boot/scene_internal.h
+++ b/boot/scene_internal.h
@@ -23,7 +23,7 @@ struct scene *expo_lookup_scene_id(struct expo *exp, uint scene_id);
*
* @exp: Expo to use
* @id: ID to use, or 0 to auto-allocate one
- * @return: Either @id, or the auto-allocated ID
+ * Returns: Either @id, or the auto-allocated ID
*/
uint resolve_id(struct expo *exp, uint id);
@@ -36,10 +36,19 @@ uint resolve_id(struct expo *exp, uint id);
* @scn: Scene to search
* @id: ID of object to find
* @type: Type of the object, or SCENEOBJT_NONE to match any type
+ * Returns: Object found, or NULL if not found
*/
void *scene_obj_find(struct scene *scn, uint id, enum scene_obj_t type);
/**
+ * scene_obj_find_by_name() - Find an object in a scene by name
+ *
+ * @scn: Scene to search
+ * @name: Name to search for
+ */
+void *scene_obj_find_by_name(struct scene *scn, const char *name);
+
+/**
* scene_obj_add() - Add a new object to a scene
*
* @scn: Scene to update
@@ -54,6 +63,28 @@ int scene_obj_add(struct scene *scn, const char *name, uint id,
enum scene_obj_t type, uint size, struct scene_obj **objp);
/**
+ * scene_obj_flag_clrset() - Adjust object flags
+ *
+ * @scn: Scene to update
+ * @id: ID of object to update
+ * @clr: Bits to clear in the object's flags
+ * @set: Bits to set in the object's flags
+ * Returns 0 if OK, -ENOENT if the object was not found
+ */
+int scene_obj_flag_clrset(struct scene *scn, uint id, uint clr, uint set);
+
+/**
+ * scene_calc_dims() - Calculate the dimensions of the scene objects
+ *
+ * Updates the width and height of all objects based on their contents
+ *
+ * @scn: Scene to update
+ * @do_menus: true to calculate only menus, false to calculate everything else
+ * Returns 0 if OK, -ENOTSUPP if there is no graphical console
+ */
+int scene_calc_dims(struct scene *scn, bool do_menus);
+
+/**
* scene_menu_arrange() - Set the position of things in the menu
*
* This updates any items associated with a menu to make sure they are
@@ -62,17 +93,27 @@ int scene_obj_add(struct scene *scn, const char *name, uint id,
*
* @scn: Scene to update
* @menu: Menu to process
+ * Returns: 0 if OK, -ve on error
*/
int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu);
/**
+ * scene_apply_theme() - Apply a theme to a scene
+ *
+ * @scn: Scene to update
+ * @theme: Theme to apply
+ * Returns: 0 if OK, -ve on error
+ */
+int scene_apply_theme(struct scene *scn, struct expo_theme *theme);
+
+/**
* scene_menu_send_key() - Send a key to a menu for processing
*
* @scn: Scene to use
* @menu: Menu to use
* @key: Key code to send (KEY_...)
* @event: Place to put any event which is generated by the key
- * @return 0 if OK, -ENOTTY if there is no current menu item, other -ve on other
+ * Returns: 0 if OK, -ENOTTY if there is no current menu item, other -ve on other
* error
*/
int scene_menu_send_key(struct scene *scn, struct scene_obj_menu *menu, int key,
@@ -89,7 +130,7 @@ void scene_menu_destroy(struct scene_obj_menu *menu);
* scene_menu_display() - Display a menu as text
*
* @menu: Menu to display
- * @return 0 if OK, -ENOENT if @id is invalid
+ * Returns: 0 if OK, -ENOENT if @id is invalid
*/
int scene_menu_display(struct scene_obj_menu *menu);
@@ -120,4 +161,41 @@ int scene_render(struct scene *scn);
*/
int scene_send_key(struct scene *scn, int key, struct expo_action *event);
+/**
+ * scene_menu_render() - Render the background behind a menu
+ *
+ * @menu: Menu to render
+ */
+void scene_menu_render(struct scene_obj_menu *menu);
+
+/**
+ * scene_render_deps() - Render an object and its dependencies
+ *
+ * @scn: Scene to render
+ * @id: Object ID to render (or 0 for none)
+ * Returns: 0 if OK, -ve on error
+ */
+int scene_render_deps(struct scene *scn, uint id);
+
+/**
+ * scene_menu_render_deps() - Render a menu and its dependencies
+ *
+ * Renders the menu and all of its attached objects
+ *
+ * @scn: Scene to render
+ * @menu: Menu render
+ * Returns: 0 if OK, -ve on error
+ */
+int scene_menu_render_deps(struct scene *scn, struct scene_obj_menu *menu);
+
+/**
+ * scene_menu_calc_dims() - Calculate the dimensions of a menu
+ *
+ * Updates the width and height of the menu based on its contents
+ *
+ * @menu: Menu to update
+ * Returns 0 if OK, -ENOTSUPP if there is no graphical console
+ */
+int scene_menu_calc_dims(struct scene_obj_menu *menu);
+
#endif /* __SCENE_INTERNAL_H */
diff --git a/boot/scene_menu.c b/boot/scene_menu.c
index 18998e862ab..8a355f838cc 100644
--- a/boot/scene_menu.c
+++ b/boot/scene_menu.c
@@ -6,7 +6,7 @@
* Written by Simon Glass <sjg@chromium.org>
*/
-#define LOG_CATEGORY LOGC_BOOT
+#define LOG_CATEGORY LOGC_EXPO
#include <common.h>
#include <dm.h>
@@ -33,6 +33,58 @@ void scene_menu_destroy(struct scene_obj_menu *menu)
scene_menuitem_destroy(item);
}
+static struct scene_menitem *scene_menuitem_find(struct scene_obj_menu *menu,
+ int id)
+{
+ struct scene_menitem *item;
+
+ list_for_each_entry(item, &menu->item_head, sibling) {
+ if (item->id == id)
+ return item;
+ }
+
+ return NULL;
+}
+
+/**
+ * update_pointers() - Update the pointer object and handle highlights
+ *
+ * @menu: Menu to update
+ * @id: ID of menu item to select/deselect
+ * @point: true if @id is being selected, false if it is being deselected
+ */
+static int update_pointers(struct scene_obj_menu *menu, uint id, bool point)
+{
+ struct scene *scn = menu->obj.scene;
+ const bool stack = scn->expo->popup;
+ const struct scene_menitem *item;
+ int ret;
+
+ item = scene_menuitem_find(menu, id);
+ if (!item)
+ return log_msg_ret("itm", -ENOENT);
+
+ /* adjust the pointer object to point to the selected item */
+ if (menu->pointer_id && item && point) {
+ struct scene_obj *label;
+
+ label = scene_obj_find(scn, item->label_id, SCENEOBJT_NONE);
+
+ ret = scene_obj_set_pos(scn, menu->pointer_id,
+ menu->obj.dim.x + 200, label->dim.y);
+ if (ret < 0)
+ return log_msg_ret("ptr", ret);
+ }
+
+ if (stack) {
+ point &= scn->highlight_id == menu->obj.id;
+ scene_obj_flag_clrset(scn, item->label_id, SCENEOF_POINT,
+ point ? SCENEOF_POINT : 0);
+ }
+
+ return 0;
+}
+
/**
* menu_point_to_item() - Point to a particular menu item
*
@@ -40,18 +92,115 @@ void scene_menu_destroy(struct scene_obj_menu *menu)
*/
static void menu_point_to_item(struct scene_obj_menu *menu, uint item_id)
{
+ if (menu->cur_item_id)
+ update_pointers(menu, menu->cur_item_id, false);
menu->cur_item_id = item_id;
+ update_pointers(menu, item_id, true);
+}
+
+static int scene_bbox_union(struct scene *scn, uint id, int inset,
+ struct vidconsole_bbox *bbox)
+{
+ struct scene_obj *obj;
+
+ if (!id)
+ return 0;
+ obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
+ if (!obj)
+ return log_msg_ret("obj", -ENOENT);
+ if (bbox->valid) {
+ bbox->x0 = min(bbox->x0, obj->dim.x - inset);
+ bbox->y0 = min(bbox->y0, obj->dim.y);
+ bbox->x1 = max(bbox->x1, obj->dim.x + obj->dim.w + inset);
+ bbox->y1 = max(bbox->y1, obj->dim.y + obj->dim.h);
+ } else {
+ bbox->x0 = obj->dim.x - inset;
+ bbox->y0 = obj->dim.y;
+ bbox->x1 = obj->dim.x + obj->dim.w + inset;
+ bbox->y1 = obj->dim.y + obj->dim.h;
+ bbox->valid = true;
+ }
+
+ return 0;
+}
+
+/**
+ * scene_menu_calc_bbox() - Calculate bounding boxes for the menu
+ *
+ * @menu: Menu to process
+ * @bbox: Returns bounding box of menu including prompts
+ * @label_bbox: Returns bounding box of labels
+ */
+static void scene_menu_calc_bbox(struct scene_obj_menu *menu,
+ struct vidconsole_bbox *bbox,
+ struct vidconsole_bbox *label_bbox)
+{
+ const struct expo_theme *theme = &menu->obj.scene->expo->theme;
+ const struct scene_menitem *item;
+
+ bbox->valid = false;
+ scene_bbox_union(menu->obj.scene, menu->title_id, 0, bbox);
+
+ label_bbox->valid = false;
+
+ list_for_each_entry(item, &menu->item_head, sibling) {
+ scene_bbox_union(menu->obj.scene, item->label_id,
+ theme->menu_inset, bbox);
+ scene_bbox_union(menu->obj.scene, item->key_id, 0, bbox);
+ scene_bbox_union(menu->obj.scene, item->desc_id, 0, bbox);
+ scene_bbox_union(menu->obj.scene, item->preview_id, 0, bbox);
+
+ /* Get the bounding box of all labels */
+ scene_bbox_union(menu->obj.scene, item->label_id,
+ theme->menu_inset, label_bbox);
+ }
+
+ /*
+ * subtract the final menuitem's gap to keep the insert the same top
+ * and bottom
+ */
+ label_bbox->y1 -= theme->menuitem_gap_y;
+}
+
+int scene_menu_calc_dims(struct scene_obj_menu *menu)
+{
+ struct vidconsole_bbox bbox, label_bbox;
+ const struct scene_menitem *item;
+
+ scene_menu_calc_bbox(menu, &bbox, &label_bbox);
+
+ /* Make all labels the same size */
+ if (label_bbox.valid) {
+ list_for_each_entry(item, &menu->item_head, sibling) {
+ scene_obj_set_size(menu->obj.scene, item->label_id,
+ label_bbox.x1 - label_bbox.x0,
+ label_bbox.y1 - label_bbox.y0);
+ }
+ }
+
+ if (bbox.valid) {
+ menu->obj.dim.w = bbox.x1 - bbox.x0;
+ menu->obj.dim.h = bbox.y1 - bbox.y0;
+ }
+
+ return 0;
}
int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu)
{
+ const bool open = menu->obj.flags & SCENEOF_OPEN;
+ struct expo *exp = scn->expo;
+ const bool stack = exp->popup;
+ const struct expo_theme *theme = &exp->theme;
struct scene_menitem *item;
- int y, cur_y;
+ uint sel_id;
+ int x, y;
int ret;
- y = menu->obj.y;
+ x = menu->obj.dim.x;
+ y = menu->obj.dim.y;
if (menu->title_id) {
- ret = scene_obj_set_pos(scn, menu->title_id, menu->obj.x, y);
+ ret = scene_obj_set_pos(scn, menu->title_id, menu->obj.dim.x, y);
if (ret < 0)
return log_msg_ret("tit", ret);
@@ -59,7 +208,10 @@ int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu)
if (ret < 0)
return log_msg_ret("hei", ret);
- y += ret * 2;
+ if (stack)
+ x += 200;
+ else
+ y += ret * 2;
}
/*
@@ -68,11 +220,12 @@ int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu)
* small. This can be updated once text measuring is supported in
* vidconsole
*/
- cur_y = -1;
+ sel_id = menu->cur_item_id;
list_for_each_entry(item, &menu->item_head, sibling) {
+ bool selected;
int height;
- ret = scene_obj_get_hw(scn, item->desc_id, NULL);
+ ret = scene_obj_get_hw(scn, item->label_id, NULL);
if (ret < 0)
return log_msg_ret("get", ret);
height = ret;
@@ -81,32 +234,33 @@ int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu)
y += height;
/* select an item if not done already */
- if (!menu->cur_item_id)
- menu_point_to_item(menu, item->id);
+ if (!sel_id)
+ sel_id = item->id;
+
+ selected = sel_id == item->id;
/*
* Put the label on the left, then leave a space for the
* pointer, then the key and the description
*/
- if (item->label_id) {
- ret = scene_obj_set_pos(scn, item->label_id, menu->obj.x,
- y);
- if (ret < 0)
- return log_msg_ret("nam", ret);
- }
-
- ret = scene_obj_set_pos(scn, item->key_id, menu->obj.x + 230,
- y);
+ ret = scene_obj_set_pos(scn, item->label_id,
+ x + theme->menu_inset, y);
if (ret < 0)
- return log_msg_ret("key", ret);
+ return log_msg_ret("nam", ret);
+ scene_obj_set_hide(scn, item->label_id,
+ stack && !open && !selected);
- ret = scene_obj_set_pos(scn, item->desc_id, menu->obj.x + 280,
- y);
- if (ret < 0)
- return log_msg_ret("des", ret);
+ if (item->key_id) {
+ ret = scene_obj_set_pos(scn, item->key_id, x + 230, y);
+ if (ret < 0)
+ return log_msg_ret("key", ret);
+ }
- if (menu->cur_item_id == item->id)
- cur_y = y;
+ if (item->desc_id) {
+ ret = scene_obj_set_pos(scn, item->desc_id, x + 280, y);
+ if (ret < 0)
+ return log_msg_ret("des", ret);
+ }
if (item->preview_id) {
bool hide;
@@ -125,19 +279,12 @@ int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu)
return log_msg_ret("hid", ret);
}
- y += height;
+ if (!stack || open)
+ y += height + theme->menuitem_gap_y;
}
- if (menu->pointer_id && cur_y != -1) {
- /*
- * put the pointer to the right of and level with the item it
- * points to
- */
- ret = scene_obj_set_pos(scn, menu->pointer_id,
- menu->obj.x + 200, cur_y);
- if (ret < 0)
- return log_msg_ret("ptr", ret);
- }
+ if (sel_id)
+ menu_point_to_item(menu, sel_id);
return 0;
}
@@ -158,10 +305,6 @@ int scene_menu(struct scene *scn, const char *name, uint id,
*menup = menu;
INIT_LIST_HEAD(&menu->item_head);
- ret = scene_menu_arrange(scn, menu);
- if (ret)
- return log_msg_ret("pos", ret);
-
return menu->obj.id;
}
@@ -191,6 +334,7 @@ static struct scene_menitem *scene_menu_find_key(struct scene *scn,
int scene_menu_send_key(struct scene *scn, struct scene_obj_menu *menu, int key,
struct expo_action *event)
{
+ const bool open = menu->obj.flags & SCENEOF_OPEN;
struct scene_menitem *item, *cur, *key_item;
cur = NULL;
@@ -215,7 +359,7 @@ int scene_menu_send_key(struct scene *scn, struct scene_obj_menu *menu, int key,
struct scene_menitem, sibling)) {
item = list_entry(item->sibling.prev,
struct scene_menitem, sibling);
- event->type = EXPOACT_POINT;
+ event->type = EXPOACT_POINT_ITEM;
event->select.id = item->id;
log_debug("up to item %d\n", event->select.id);
}
@@ -224,7 +368,7 @@ int scene_menu_send_key(struct scene *scn, struct scene_obj_menu *menu, int key,
if (!list_is_last(&item->sibling, &menu->item_head)) {
item = list_entry(item->sibling.next,
struct scene_menitem, sibling);
- event->type = EXPOACT_POINT;
+ event->type = EXPOACT_POINT_ITEM;
event->select.id = item->id;
log_debug("down to item %d\n", event->select.id);
}
@@ -235,8 +379,13 @@ int scene_menu_send_key(struct scene *scn, struct scene_obj_menu *menu, int key,
log_debug("select item %d\n", event->select.id);
break;
case BKEY_QUIT:
- event->type = EXPOACT_QUIT;
- log_debug("quit\n");
+ if (scn->expo->popup && open) {
+ event->type = EXPOACT_CLOSE;
+ event->select.id = menu->obj.id;
+ } else {
+ event->type = EXPOACT_QUIT;
+ log_debug("menu quit\n");
+ }
break;
case '0'...'9':
key_item = scene_menu_find_key(scn, menu, key);
@@ -258,14 +407,13 @@ int scene_menuitem(struct scene *scn, uint menu_id, const char *name, uint id,
{
struct scene_obj_menu *menu;
struct scene_menitem *item;
- int ret;
menu = scene_obj_find(scn, menu_id, SCENEOBJT_MENU);
if (!menu)
return log_msg_ret("find", -ENOENT);
/* Check that the text ID is valid */
- if (!scene_obj_find(scn, desc_id, SCENEOBJT_TEXT))
+ if (!scene_obj_find(scn, label_id, SCENEOBJT_TEXT))
return log_msg_ret("txt", -EINVAL);
item = calloc(1, sizeof(struct scene_obj_menu));
@@ -285,10 +433,6 @@ int scene_menuitem(struct scene *scn, uint menu_id, const char *name, uint id,
item->flags = flags;
list_add_tail(&item->sibling, &menu->item_head);
- ret = scene_menu_arrange(scn, menu);
- if (ret)
- return log_msg_ret("pos", ret);
-
if (itemp)
*itemp = item;
@@ -388,3 +532,49 @@ int scene_menu_display(struct scene_obj_menu *menu)
return -ENOTSUPP;
}
+
+void scene_menu_render(struct scene_obj_menu *menu)
+{
+ struct expo *exp = menu->obj.scene->expo;
+ const struct expo_theme *theme = &exp->theme;
+ struct vidconsole_bbox bbox, label_bbox;
+ struct udevice *dev = exp->display;
+ struct video_priv *vid_priv;
+ struct udevice *cons = exp->cons;
+ struct vidconsole_colour old;
+ enum colour_idx fore, back;
+
+ if (CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK)) {
+ fore = VID_BLACK;
+ back = VID_WHITE;
+ } else {
+ fore = VID_LIGHT_GRAY;
+ back = VID_BLACK;
+ }
+
+ scene_menu_calc_bbox(menu, &bbox, &label_bbox);
+ vidconsole_push_colour(cons, fore, back, &old);
+ vid_priv = dev_get_uclass_priv(dev);
+ video_fill_part(dev, label_bbox.x0 - theme->menu_inset,
+ label_bbox.y0 - theme->menu_inset,
+ label_bbox.x1, label_bbox.y1 + theme->menu_inset,
+ vid_priv->colour_fg);
+ vidconsole_pop_colour(cons, &old);
+}
+
+int scene_menu_render_deps(struct scene *scn, struct scene_obj_menu *menu)
+{
+ struct scene_menitem *item;
+
+ scene_render_deps(scn, menu->title_id);
+ scene_render_deps(scn, menu->cur_item_id);
+ scene_render_deps(scn, menu->pointer_id);
+
+ list_for_each_entry(item, &menu->item_head, sibling) {
+ scene_render_deps(scn, item->key_id);
+ scene_render_deps(scn, item->label_id);
+ scene_render_deps(scn, item->desc_id);
+ }
+
+ return 0;
+}
diff --git a/cmd/Kconfig b/cmd/Kconfig
index c1941849f98..fd76972eaa3 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -428,6 +428,15 @@ config CMD_ABOOTIMG
See doc/android/boot-image.rst for details.
+config CMD_CEDIT
+ bool "cedit - Configuration editor"
+ depends on CEDIT
+ default y
+ help
+ Provides a command to allow editing of board configuration and
+ providing a UI for the user to adjust settings. Subcommands allow
+ loading and saving of configuration as well as showing an editor.
+
config CMD_ELF
bool "bootelf, bootvx"
default y
@@ -1850,7 +1859,6 @@ config CMD_RARP
config CMD_NFS
bool "nfs"
- default y
help
Boot image via network using NFS protocol.
diff --git a/cmd/Makefile b/cmd/Makefile
index 6c37521b4e2..9f8c0b058be 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_CMD_BUTTON) += button.o
obj-$(CONFIG_CMD_CAT) += cat.o
obj-$(CONFIG_CMD_CACHE) += cache.o
obj-$(CONFIG_CMD_CBFS) += cbfs.o
+obj-$(CONFIG_CMD_CEDIT) += cedit.o
obj-$(CONFIG_CMD_CLK) += clk.o
obj-$(CONFIG_CMD_CLS) += cls.o
obj-$(CONFIG_CMD_CONFIG) += config.o
diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
index 6baeedc69f9..987b16889f8 100644
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -351,8 +351,8 @@ static struct bootmenu_data *bootmenu_create(int delay)
* UEFI specification requires booting from removal media using
* a architecture-specific default image name such as BOOTAA64.EFI.
*/
- efi_ret = eficonfig_generate_media_device_boot_option();
- if (efi_ret != EFI_SUCCESS && efi_ret != EFI_NOT_FOUND)
+ efi_ret = efi_bootmgr_update_media_device_boot_option();
+ if (efi_ret != EFI_SUCCESS)
goto cleanup;
ret = prepare_uefi_bootorder_entry(menu, &iter, &i);
diff --git a/cmd/cat.c b/cmd/cat.c
index 1273a26b145..b059080193d 100644
--- a/cmd/cat.c
+++ b/cmd/cat.c
@@ -17,8 +17,8 @@ static int do_cat(struct cmd_tbl *cmdtp, int flag, int argc,
char *dev;
char *file;
char *buffer;
- phys_addr_t addr;
- loff_t file_size;
+ ulong file_size;
+ int ret;
if (argc < 4)
return CMD_RET_USAGE;
@@ -27,40 +27,27 @@ static int do_cat(struct cmd_tbl *cmdtp, int flag, int argc,
dev = argv[2];
file = argv[3];
+ ret = fs_load_alloc(ifname, dev, file, 0, 0, (void **)&buffer,
+ &file_size);
+
// check file exists
- if (fs_set_blk_dev(ifname, dev, FS_TYPE_ANY))
+ switch (ret) {
+ case 0:
+ break;
+ case -ENOMEDIUM:
return CMD_RET_FAILURE;
-
- if (!fs_exists(file)) {
+ case -ENOENT:
log_err("File does not exist: ifname=%s dev=%s file=%s\n", ifname, dev, file);
return CMD_RET_FAILURE;
- }
-
- // get file size
- if (fs_set_blk_dev(ifname, dev, FS_TYPE_ANY))
+ case -E2BIG:
+ log_err("File is too large: ifname=%s dev=%s file=%s\n", ifname, dev, file);
return CMD_RET_FAILURE;
-
- if (fs_size(file, &file_size)) {
- log_err("Cannot read file size: ifname=%s dev=%s file=%s\n", ifname, dev, file);
+ case -ENOMEM:
+ log_err("Not enough memory: ifname=%s dev=%s file=%s\n", ifname, dev, file);
return CMD_RET_FAILURE;
- }
-
- // allocate memory for file content
- buffer = calloc(sizeof(char), file_size + 1);
- if (!buffer) {
- log_err("Out of memory\n");
- return CMD_RET_FAILURE;
- }
-
- // map pointer to system memory
- addr = map_to_sysmem(buffer);
-
- // read file to memory
- if (fs_set_blk_dev(ifname, dev, FS_TYPE_ANY))
- return CMD_RET_FAILURE;
-
- if (fs_read(file, addr, 0, 0, &file_size)) {
- log_err("Cannot read file: ifname=%s dev=%s file=%s\n", ifname, dev, file);
+ default:
+ case -EIO:
+ log_err("File-read failed: ifname=%s dev=%s file=%s\n", ifname, dev, file);
return CMD_RET_FAILURE;
}
diff --git a/cmd/cedit.c b/cmd/cedit.c
new file mode 100644
index 00000000000..0cae304c4ad
--- /dev/null
+++ b/cmd/cedit.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * 'cedit' command
+ *
+ * Copyright 2023 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <expo.h>
+#include <fs.h>
+#include <dm/ofnode.h>
+#include <linux/sizes.h>
+
+struct expo *cur_exp;
+
+static int do_cedit_load(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ const char *fname;
+ struct expo *exp;
+ oftree tree;
+ ulong size;
+ void *buf;
+ int ret;
+
+ if (argc < 4)
+ return CMD_RET_USAGE;
+ fname = argv[3];
+
+ ret = fs_load_alloc(argv[1], argv[2], argv[3], SZ_1M, 0, &buf, &size);
+ if (ret) {
+ printf("File not found\n");
+ return CMD_RET_FAILURE;
+ }
+
+ tree = oftree_from_fdt(buf);
+ if (!oftree_valid(tree)) {
+ printf("Cannot create oftree\n");
+ return CMD_RET_FAILURE;
+ }
+
+ ret = expo_build(oftree_root(tree), &exp);
+ oftree_dispose(tree);
+ if (ret) {
+ printf("Failed to build expo: %dE\n", ret);
+ return CMD_RET_FAILURE;
+ }
+
+ cur_exp = exp;
+
+ return 0;
+}
+
+static int do_cedit_run(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ ofnode node;
+ int ret;
+
+ if (!cur_exp) {
+ printf("No expo loaded\n");
+ return CMD_RET_FAILURE;
+ }
+
+ node = ofnode_path("/cedit-theme");
+ if (ofnode_valid(node)) {
+ ret = expo_apply_theme(cur_exp, node);
+ if (ret)
+ return CMD_RET_FAILURE;
+ } else {
+ log_warning("No theme found\n");
+ }
+ ret = cedit_run(cur_exp);
+ if (ret) {
+ log_err("Failed (err=%dE)\n", ret);
+ return CMD_RET_FAILURE;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_SYS_LONGHELP
+static char cedit_help_text[] =
+ "load <interface> <dev[:part]> <filename> - load config editor\n"
+ "cedit run - run config editor";
+#endif /* CONFIG_SYS_LONGHELP */
+
+U_BOOT_CMD_WITH_SUBCMDS(cedit, "Configuration editor", cedit_help_text,
+ U_BOOT_SUBCMD_MKENT(load, 5, 1, do_cedit_load),
+ U_BOOT_SUBCMD_MKENT(run, 1, 1, do_cedit_run),
+);
diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
index 720f52b48b8..e6e8a0a488e 100644
--- a/cmd/eficonfig.c
+++ b/cmd/eficonfig.c
@@ -1135,43 +1135,6 @@ out:
}
/**
- * eficonfig_get_unused_bootoption() - get unused "Boot####" index
- *
- * @buf: pointer to the buffer to store boot option variable name
- * @buf_size: buffer size
- * @index: pointer to store the index in the BootOrder variable
- * Return: status code
- */
-efi_status_t eficonfig_get_unused_bootoption(u16 *buf, efi_uintn_t buf_size,
- unsigned int *index)
-{
- u32 i;
- efi_status_t ret;
- efi_uintn_t size;
-
- if (buf_size < u16_strsize(u"Boot####"))
- return EFI_BUFFER_TOO_SMALL;
-
- for (i = 0; i <= 0xFFFF; i++) {
- size = 0;
- efi_create_indexed_name(buf, buf_size, "Boot", i);
- ret = efi_get_variable_int(buf, &efi_global_variable_guid,
- NULL, &size, NULL, NULL);
- if (ret == EFI_BUFFER_TOO_SMALL)
- continue;
- else
- break;
- }
-
- if (i > 0xFFFF)
- return EFI_OUT_OF_RESOURCES;
-
- *index = i;
-
- return EFI_SUCCESS;
-}
-
-/**
* eficonfig_set_boot_option() - set boot option
*
* @varname: pointer to variable name
@@ -1209,46 +1172,6 @@ static efi_status_t eficonfig_set_boot_option(u16 *varname, struct efi_device_pa
}
/**
- * eficonfig_append_bootorder() - append new boot option in BootOrder variable
- *
- * @index: "Boot####" index to append to BootOrder variable
- * Return: status code
- */
-efi_status_t eficonfig_append_bootorder(u16 index)
-{
- u16 *bootorder;
- efi_status_t ret;
- u16 *new_bootorder = NULL;
- efi_uintn_t last, size, new_size;
-
- /* append new boot option */
- bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
- last = size / sizeof(u16);
- new_size = size + sizeof(u16);
- new_bootorder = calloc(1, new_size);
- if (!new_bootorder) {
- ret = EFI_OUT_OF_RESOURCES;
- goto out;
- }
- memcpy(new_bootorder, bootorder, size);
- new_bootorder[last] = index;
-
- ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid,
- EFI_VARIABLE_NON_VOLATILE |
- EFI_VARIABLE_BOOTSERVICE_ACCESS |
- EFI_VARIABLE_RUNTIME_ACCESS,
- new_size, new_bootorder, false);
- if (ret != EFI_SUCCESS)
- goto out;
-
-out:
- free(bootorder);
- free(new_bootorder);
-
- return ret;
-}
-
-/**
* create_boot_option_entry() - create boot option entry
*
* @efi_menu: pointer to the efimenu structure
@@ -1619,7 +1542,7 @@ static efi_status_t eficonfig_process_add_boot_option(void *data)
if (!bo)
return EFI_OUT_OF_RESOURCES;
- ret = eficonfig_get_unused_bootoption(varname, sizeof(varname), &bo->boot_index);
+ ret = efi_bootmgr_get_unused_bootoption(varname, sizeof(varname), &bo->boot_index);
if (ret != EFI_SUCCESS)
return ret;
@@ -1627,7 +1550,7 @@ static efi_status_t eficonfig_process_add_boot_option(void *data)
if (ret != EFI_SUCCESS)
goto out;
- ret = eficonfig_append_bootorder((u16)bo->boot_index);
+ ret = efi_bootmgr_append_bootorder((u16)bo->boot_index);
if (ret != EFI_SUCCESS)
goto out;
@@ -1657,31 +1580,6 @@ static efi_status_t eficonfig_process_boot_selected(void *data)
}
/**
- * search_bootorder() - search the boot option index in BootOrder
- *
- * @bootorder: pointer to the BootOrder variable
- * @num: number of BootOrder entry
- * @target: target boot option index to search
- * @index: pointer to store the index of BootOrder variable
- * Return: true if exists, false otherwise
- */
-static bool search_bootorder(u16 *bootorder, efi_uintn_t num, u32 target, u32 *index)
-{
- u32 i;
-
- for (i = 0; i < num; i++) {
- if (target == bootorder[i]) {
- if (index)
- *index = i;
-
- return true;
- }
- }
-
- return false;
-}
-
-/**
* eficonfig_add_boot_selection_entry() - add boot option menu entry
*
* @efi_menu: pointer to store the efimenu structure
@@ -1805,7 +1703,7 @@ static efi_status_t eficonfig_show_boot_selection(unsigned int *selected)
if (efi_varname_is_load_option(var_name16, &index)) {
/* If the index is included in the BootOrder, skip it */
- if (search_bootorder(bootorder, num, index, NULL))
+ if (efi_search_bootorder(bootorder, num, index, NULL))
continue;
ret = eficonfig_add_boot_selection_entry(efi_menu, index, selected);
@@ -2202,7 +2100,7 @@ static efi_status_t eficonfig_create_change_boot_order_entry(struct efimenu *efi
if (efi_varname_is_load_option(var_name16, &index)) {
/* If the index is included in the BootOrder, skip it */
- if (search_bootorder(bootorder, num, index, NULL))
+ if (efi_search_bootorder(bootorder, num, index, NULL))
continue;
ret = eficonfig_add_change_boot_order_entry(efi_menu, index, false);
@@ -2305,50 +2203,6 @@ out:
}
/**
- * delete_boot_option() - delete selected boot option
- *
- * @boot_index: boot option index to delete
- * Return: status code
- */
-static efi_status_t delete_boot_option(u16 boot_index)
-{
- u16 *bootorder;
- u16 varname[9];
- efi_status_t ret;
- unsigned int index;
- efi_uintn_t num, size;
-
- efi_create_indexed_name(varname, sizeof(varname),
- "Boot", boot_index);
- ret = efi_set_variable_int(varname, &efi_global_variable_guid,
- 0, 0, NULL, false);
- if (ret != EFI_SUCCESS) {
- log_err("delete boot option(%ls) failed\n", varname);
- return ret;
- }
-
- /* update BootOrder if necessary */
- bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
- if (!bootorder)
- return EFI_SUCCESS;
-
- num = size / sizeof(u16);
- if (!search_bootorder(bootorder, num, boot_index, &index))
- return EFI_SUCCESS;
-
- memmove(&bootorder[index], &bootorder[index + 1],
- (num - index - 1) * sizeof(u16));
- size -= sizeof(u16);
- ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid,
- EFI_VARIABLE_NON_VOLATILE |
- EFI_VARIABLE_BOOTSERVICE_ACCESS |
- EFI_VARIABLE_RUNTIME_ACCESS,
- size, bootorder, false);
-
- return ret;
-}
-
-/**
* eficonfig_process_delete_boot_option() - handler to delete boot option
*
* @data: pointer to the data for each entry
@@ -2362,7 +2216,7 @@ static efi_status_t eficonfig_process_delete_boot_option(void *data)
while (1) {
ret = eficonfig_show_boot_selection(&selected);
if (ret == EFI_SUCCESS)
- ret = delete_boot_option(selected);
+ ret = efi_bootmgr_delete_boot_option(selected);
if (ret != EFI_SUCCESS)
break;
@@ -2375,256 +2229,6 @@ static efi_status_t eficonfig_process_delete_boot_option(void *data)
}
/**
- * eficonfig_enumerate_boot_option() - enumerate the possible bootable media
- *
- * @opt: pointer to the media boot option structure
- * @volume_handles: pointer to the efi handles
- * @count: number of efi handle
- * Return: status code
- */
-efi_status_t eficonfig_enumerate_boot_option(struct eficonfig_media_boot_option *opt,
- efi_handle_t *volume_handles, efi_status_t count)
-{
- u32 i;
- struct efi_handler *handler;
- efi_status_t ret = EFI_SUCCESS;
-
- for (i = 0; i < count; i++) {
- u16 *p;
- u16 dev_name[BOOTMENU_DEVICE_NAME_MAX];
- char *optional_data;
- struct efi_load_option lo;
- char buf[BOOTMENU_DEVICE_NAME_MAX];
- struct efi_device_path *device_path;
-
- ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler);
- if (ret != EFI_SUCCESS)
- continue;
- ret = efi_protocol_open(handler, (void **)&device_path,
- efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
- if (ret != EFI_SUCCESS)
- continue;
-
- ret = efi_disk_get_device_name(volume_handles[i], buf, BOOTMENU_DEVICE_NAME_MAX);
- if (ret != EFI_SUCCESS)
- continue;
-
- p = dev_name;
- utf8_utf16_strncpy(&p, buf, strlen(buf));
-
- lo.label = dev_name;
- lo.attributes = LOAD_OPTION_ACTIVE;
- lo.file_path = device_path;
- lo.file_path_length = efi_dp_size(device_path) + sizeof(END);
- /*
- * Set the dedicated guid to optional_data, it is used to identify
- * the boot option that automatically generated by the bootmenu.
- * efi_serialize_load_option() expects optional_data is null-terminated
- * utf8 string, so set the "1234567" string to allocate enough space
- * to store guid, instead of realloc the load_option.
- */
- lo.optional_data = "1234567";
- opt[i].size = efi_serialize_load_option(&lo, (u8 **)&opt[i].lo);
- if (!opt[i].size) {
- ret = EFI_OUT_OF_RESOURCES;
- goto out;
- }
- /* set the guid */
- optional_data = (char *)opt[i].lo + (opt[i].size - u16_strsize(u"1234567"));
- memcpy(optional_data, &efi_guid_bootmenu_auto_generated, sizeof(efi_guid_t));
- }
-
-out:
- return ret;
-}
-
-/**
- * eficonfig_delete_invalid_boot_option() - delete non-existing boot option
- *
- * @opt: pointer to the media boot option structure
- * @count: number of media boot option structure
- * Return: status code
- */
-efi_status_t eficonfig_delete_invalid_boot_option(struct eficonfig_media_boot_option *opt,
- efi_status_t count)
-{
- efi_uintn_t size;
- void *load_option;
- u32 i, list_size = 0;
- struct efi_load_option lo;
- u16 *var_name16 = NULL;
- u16 varname[] = u"Boot####";
- efi_status_t ret = EFI_SUCCESS;
- u16 *delete_index_list = NULL, *p;
- efi_uintn_t buf_size;
-
- buf_size = 128;
- var_name16 = malloc(buf_size);
- if (!var_name16)
- return EFI_OUT_OF_RESOURCES;
-
- var_name16[0] = 0;
- for (;;) {
- int index;
- efi_guid_t guid;
- efi_uintn_t tmp;
-
- ret = efi_next_variable_name(&buf_size, &var_name16, &guid);
- if (ret == EFI_NOT_FOUND) {
- /*
- * EFI_NOT_FOUND indicates we retrieved all EFI variables.
- * This should be treated as success.
- */
- ret = EFI_SUCCESS;
- break;
- }
- if (ret != EFI_SUCCESS)
- goto out;
-
- if (!efi_varname_is_load_option(var_name16, &index))
- continue;
-
- efi_create_indexed_name(varname, sizeof(varname), "Boot", index);
- load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
- if (!load_option)
- continue;
-
- tmp = size;
- ret = efi_deserialize_load_option(&lo, load_option, &size);
- if (ret != EFI_SUCCESS)
- goto next;
-
- if (size >= sizeof(efi_guid_bootmenu_auto_generated) &&
- !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) {
- for (i = 0; i < count; i++) {
- if (opt[i].size == tmp &&
- memcmp(opt[i].lo, load_option, tmp) == 0) {
- opt[i].exist = true;
- break;
- }
- }
-
- /*
- * The entire list of variables must be retrieved by
- * efi_get_next_variable_name_int() before deleting the invalid
- * boot option, just save the index here.
- */
- if (i == count) {
- p = realloc(delete_index_list, sizeof(u32) *
- (list_size + 1));
- if (!p) {
- ret = EFI_OUT_OF_RESOURCES;
- goto out;
- }
- delete_index_list = p;
- delete_index_list[list_size++] = index;
- }
- }
-next:
- free(load_option);
- }
-
- /* delete all invalid boot options */
- for (i = 0; i < list_size; i++) {
- ret = delete_boot_option(delete_index_list[i]);
- if (ret != EFI_SUCCESS)
- goto out;
- }
-
-out:
- free(var_name16);
- free(delete_index_list);
-
- return ret;
-}
-
-/**
- * eficonfig_generate_media_device_boot_option() - generate the media device boot option
- *
- * This function enumerates all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
- * and generate the bootmenu entries.
- * This function also provide the BOOT#### variable maintenance for
- * the media device entries.
- * - Automatically create the BOOT#### variable for the newly detected device,
- * this BOOT#### variable is distinguished by the special GUID
- * stored in the EFI_LOAD_OPTION.optional_data
- * - If the device is not attached to the system, the associated BOOT#### variable
- * is automatically deleted.
- *
- * Return: status code
- */
-efi_status_t eficonfig_generate_media_device_boot_option(void)
-{
- u32 i;
- efi_status_t ret;
- efi_uintn_t count;
- efi_handle_t *volume_handles = NULL;
- struct eficonfig_media_boot_option *opt = NULL;
-
- ret = efi_locate_handle_buffer_int(BY_PROTOCOL, &efi_simple_file_system_protocol_guid,
- NULL, &count, (efi_handle_t **)&volume_handles);
- if (ret != EFI_SUCCESS)
- return ret;
-
- opt = calloc(count, sizeof(struct eficonfig_media_boot_option));
- if (!opt)
- goto out;
-
- /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */
- ret = eficonfig_enumerate_boot_option(opt, volume_handles, count);
- if (ret != EFI_SUCCESS)
- goto out;
-
- /*
- * System hardware configuration may vary depending on the user setup.
- * The boot option is automatically added by the bootmenu.
- * If the device is not attached to the system, the boot option needs
- * to be deleted.
- */
- ret = eficonfig_delete_invalid_boot_option(opt, count);
- if (ret != EFI_SUCCESS)
- goto out;
-
- /* add non-existent boot option */
- for (i = 0; i < count; i++) {
- u32 boot_index;
- u16 var_name[9];
-
- if (!opt[i].exist) {
- ret = eficonfig_get_unused_bootoption(var_name, sizeof(var_name),
- &boot_index);
- if (ret != EFI_SUCCESS)
- goto out;
-
- ret = efi_set_variable_int(var_name, &efi_global_variable_guid,
- EFI_VARIABLE_NON_VOLATILE |
- EFI_VARIABLE_BOOTSERVICE_ACCESS |
- EFI_VARIABLE_RUNTIME_ACCESS,
- opt[i].size, opt[i].lo, false);
- if (ret != EFI_SUCCESS)
- goto out;
-
- ret = eficonfig_append_bootorder(boot_index);
- if (ret != EFI_SUCCESS) {
- efi_set_variable_int(var_name, &efi_global_variable_guid,
- 0, 0, NULL, false);
- goto out;
- }
- }
- }
-
-out:
- if (opt) {
- for (i = 0; i < count; i++)
- free(opt[i].lo);
- }
- free(opt);
- efi_free_pool(volume_handles);
-
- return ret;
-}
-
-/**
* eficonfig_init() - do required initialization for eficonfig command
*
* Return: status code
@@ -2709,8 +2313,8 @@ static int do_eficonfig(struct cmd_tbl *cmdtp, int flag, int argc, char *const a
if (ret != EFI_SUCCESS)
return CMD_RET_FAILURE;
- ret = eficonfig_generate_media_device_boot_option();
- if (ret != EFI_SUCCESS && ret != EFI_NOT_FOUND)
+ ret = efi_bootmgr_update_media_device_boot_option();
+ if (ret != EFI_SUCCESS)
return ret;
while (1) {
diff --git a/common/board_f.c b/common/board_f.c
index 1688e27071f..334d04af197 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -633,8 +633,6 @@ static int init_post(void)
static int reloc_fdt(void)
{
if (!IS_ENABLED(CONFIG_OF_EMBED)) {
- if (gd->flags & GD_FLG_SKIP_RELOC)
- return 0;
if (gd->new_fdt) {
memcpy(gd->new_fdt, gd->fdt_blob,
fdt_totalsize(gd->fdt_blob));
diff --git a/common/hash.c b/common/hash.c
index 9a52d6073ce..cbffdfd6db3 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -586,6 +586,8 @@ int hash_command(const char *algo_name, int flags, struct cmd_tbl *cmdtp,
output = memalign(ARCH_DMA_MINALIGN,
sizeof(uint32_t) * HASH_MAX_DIGEST_SIZE);
+ if (!output)
+ return CMD_RET_FAILURE;
buf = map_sysmem(addr, len);
algo->hash_func_ws(buf, len, output, algo->chunk_size);
@@ -602,6 +604,7 @@ int hash_command(const char *algo_name, int flags, struct cmd_tbl *cmdtp,
flags & HASH_FLAG_ENV)) {
printf("ERROR: %s does not contain a valid "
"%s sum\n", *argv, algo->name);
+ free(output);
return 1;
}
if (memcmp(output, vsum, algo->digest_size) != 0) {
@@ -612,6 +615,7 @@ int hash_command(const char *algo_name, int flags, struct cmd_tbl *cmdtp,
for (i = 0; i < algo->digest_size; i++)
printf("%02x", vsum[i]);
puts(" ** ERROR **\n");
+ free(output);
return 1;
}
} else {
@@ -622,10 +626,10 @@ int hash_command(const char *algo_name, int flags, struct cmd_tbl *cmdtp,
store_result(algo, output, *argv,
flags & HASH_FLAG_ENV);
}
- unmap_sysmem(output);
-
}
+ free(output);
+
/* Horrible code size hack for boards that just want crc32 */
} else {
ulong crc;
diff --git a/common/log.c b/common/log.c
index 7cfc49bc28a..6f02a25c593 100644
--- a/common/log.c
+++ b/common/log.c
@@ -31,6 +31,7 @@ static const char *const log_cat_name[] = {
"boot",
"event",
"fs",
+ "expo",
};
_Static_assert(ARRAY_SIZE(log_cat_name) == LOGC_COUNT - LOGC_NONE,
diff --git a/configs/10m50_defconfig b/configs/10m50_defconfig
index 54a67c5aa98..b76f31b009f 100644
--- a/configs/10m50_defconfig
+++ b/configs/10m50_defconfig
@@ -26,7 +26,6 @@ CONFIG_CMD_GPIO=y
# CONFIG_CMD_ITEST is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_ENV_OVERWRITE=y
diff --git a/configs/3c120_defconfig b/configs/3c120_defconfig
index fc73c0613d0..13da353d7eb 100644
--- a/configs/3c120_defconfig
+++ b/configs/3c120_defconfig
@@ -26,7 +26,6 @@ CONFIG_CMD_GPIO=y
# CONFIG_CMD_ITEST is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_ENV_OVERWRITE=y
diff --git a/configs/CMPC885_defconfig b/configs/CMPC885_defconfig
index f5bc6d6c004..54873daa156 100644
--- a/configs/CMPC885_defconfig
+++ b/configs/CMPC885_defconfig
@@ -51,7 +51,6 @@ CONFIG_CMD_ASKENV=y
CONFIG_CMD_MTD=y
CONFIG_CMD_NAND=y
CONFIG_CMD_DHCP=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_MII=y
CONFIG_MII_INIT=y
CONFIG_CMD_PING=y
diff --git a/configs/CMPCPRO_defconfig b/configs/CMPCPRO_defconfig
index 80913e653be..d817274a936 100644
--- a/configs/CMPCPRO_defconfig
+++ b/configs/CMPCPRO_defconfig
@@ -136,7 +136,6 @@ CONFIG_CMD_MTD=y
CONFIG_CMD_NAND=y
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
# CONFIG_CMD_SLEEP is not set
diff --git a/configs/apalis-tk1_defconfig b/configs/apalis-tk1_defconfig
index 36d28a249cd..fda85c2d6ae 100644
--- a/configs/apalis-tk1_defconfig
+++ b/configs/apalis-tk1_defconfig
@@ -43,7 +43,6 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_PCI=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_TIME=y
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
diff --git a/configs/apalis_imx6_defconfig b/configs/apalis_imx6_defconfig
index dcee5173c1b..5f0f78191c4 100644
--- a/configs/apalis_imx6_defconfig
+++ b/configs/apalis_imx6_defconfig
@@ -62,7 +62,6 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_SDP=y
CONFIG_CMD_USB_MASS_STORAGE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_BOOTCOUNT=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
diff --git a/configs/apalis_t30_defconfig b/configs/apalis_t30_defconfig
index 516552584c7..83aab2450be 100644
--- a/configs/apalis_t30_defconfig
+++ b/configs/apalis_t30_defconfig
@@ -38,7 +38,6 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_PCI=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
diff --git a/configs/arbel_evb_defconfig b/configs/arbel_evb_defconfig
index 29c4c187b58..c27a7cdd3a2 100644
--- a/configs/arbel_evb_defconfig
+++ b/configs/arbel_evb_defconfig
@@ -2,7 +2,8 @@ CONFIG_ARM=y
CONFIG_ARCH_NPCM=y
CONFIG_SYS_MALLOC_LEN=0x240000
CONFIG_SYS_MALLOC_F_LEN=0x1000
-CONFIG_NR_DRAM_BANKS=1
+CONFIG_TEXT_BASE=0x06208000
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x40000
CONFIG_ENV_OFFSET=0x3C0000
CONFIG_ENV_SECT_SIZE=0x1000
@@ -22,6 +23,8 @@ CONFIG_BOOTCOMMAND="run common_bootargs; run romboot"
CONFIG_HUSH_PARSER=y
CONFIG_SYS_MAXARGS=32
CONFIG_SYS_BOOTM_LEN=0x1400000
+CONFIG_SYS_LOAD_ADDR=0x06208000
+CONFIG_SYS_INIT_SP_ADDR=0x06208000
CONFIG_CMD_FUSE=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
@@ -86,3 +89,13 @@ CONFIG_USB_STORAGE=y
CONFIG_LIB_HW_RAND=y
CONFIG_SHA_HW_ACCEL=y
# CONFIG_EFI_LOADER is not set
+CONFIG_TEE=y
+CONFIG_OPTEE=y
+CONFIG_TPM=y
+CONFIG_TPM_V2=y
+CONFIG_TPM2_FTPM_TEE=y
+CONFIG_CMD_TPM=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_PART=y
diff --git a/configs/bayleybay_defconfig b/configs/bayleybay_defconfig
index 4e59d513cdc..a44c9b714be 100644
--- a/configs/bayleybay_defconfig
+++ b/configs/bayleybay_defconfig
@@ -37,7 +37,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_BOOTSTAGE=y
diff --git a/configs/beaver_defconfig b/configs/beaver_defconfig
index 3820a333ecb..0d8a74be7aa 100644
--- a/configs/beaver_defconfig
+++ b/configs/beaver_defconfig
@@ -38,7 +38,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
diff --git a/configs/bitmain_antminer_s9_defconfig b/configs/bitmain_antminer_s9_defconfig
index c38ba15cd03..3995d41ce1b 100644
--- a/configs/bitmain_antminer_s9_defconfig
+++ b/configs/bitmain_antminer_s9_defconfig
@@ -55,7 +55,6 @@ CONFIG_CMD_PART=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_MAY_FAIL=y
-# CONFIG_CMD_NFS is not set
CONFIG_SYS_DISABLE_AUTOLOAD=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
diff --git a/configs/brppt1_mmc_defconfig b/configs/brppt1_mmc_defconfig
index 2c9b0662159..653620263cd 100644
--- a/configs/brppt1_mmc_defconfig
+++ b/configs/brppt1_mmc_defconfig
@@ -64,7 +64,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_ITEST is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_MAY_FAIL=y
-# CONFIG_CMD_NFS is not set
CONFIG_SYS_DISABLE_AUTOLOAD=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
diff --git a/configs/brppt2_defconfig b/configs/brppt2_defconfig
index 00ef3d9908e..05ee4c5797e 100644
--- a/configs/brppt2_defconfig
+++ b/configs/brppt2_defconfig
@@ -56,7 +56,6 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_MAY_FAIL=y
-# CONFIG_CMD_NFS is not set
CONFIG_SYS_DISABLE_AUTOLOAD=y
CONFIG_CMD_MII=y
CONFIG_CMD_CACHE=y
diff --git a/configs/brsmarc1_defconfig b/configs/brsmarc1_defconfig
index 1e55ed7c60d..94943fccf1a 100644
--- a/configs/brsmarc1_defconfig
+++ b/configs/brsmarc1_defconfig
@@ -73,7 +73,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_ITEST is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_MAY_FAIL=y
-# CONFIG_CMD_NFS is not set
CONFIG_SYS_DISABLE_AUTOLOAD=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
diff --git a/configs/brxre1_defconfig b/configs/brxre1_defconfig
index 1c437e9743c..b50aef0aad9 100644
--- a/configs/brxre1_defconfig
+++ b/configs/brxre1_defconfig
@@ -63,7 +63,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_ITEST is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_MAY_FAIL=y
-# CONFIG_CMD_NFS is not set
CONFIG_SYS_DISABLE_AUTOLOAD=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
diff --git a/configs/cardhu_defconfig b/configs/cardhu_defconfig
index 00fea793f92..4fe4621f037 100644
--- a/configs/cardhu_defconfig
+++ b/configs/cardhu_defconfig
@@ -35,7 +35,6 @@ CONFIG_CMD_PCI=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
diff --git a/configs/cei-tk1-som_defconfig b/configs/cei-tk1-som_defconfig
index c00e6bec5a3..b920ac2ae40 100644
--- a/configs/cei-tk1-som_defconfig
+++ b/configs/cei-tk1-som_defconfig
@@ -41,7 +41,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
diff --git a/configs/cherryhill_defconfig b/configs/cherryhill_defconfig
index 4137b1c77e9..00799715e8f 100644
--- a/configs/cherryhill_defconfig
+++ b/configs/cherryhill_defconfig
@@ -28,7 +28,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_EXT2=y
diff --git a/configs/chromebook_link64_defconfig b/configs/chromebook_link64_defconfig
index 8c75d654290..558609e13d6 100644
--- a/configs/chromebook_link64_defconfig
+++ b/configs/chromebook_link64_defconfig
@@ -50,7 +50,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_BOOTSTAGE=y
diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig
index 3098857d6e1..96c26f1c377 100644
--- a/configs/chromebook_link_defconfig
+++ b/configs/chromebook_link_defconfig
@@ -37,7 +37,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_SOUND=y
diff --git a/configs/chromebook_samus_defconfig b/configs/chromebook_samus_defconfig
index 0d20891d2bc..4019c169a4c 100644
--- a/configs/chromebook_samus_defconfig
+++ b/configs/chromebook_samus_defconfig
@@ -39,7 +39,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_SOUND=y
diff --git a/configs/chromebox_panther_defconfig b/configs/chromebox_panther_defconfig
index 96c739cbfbc..f050d066be4 100644
--- a/configs/chromebox_panther_defconfig
+++ b/configs/chromebox_panther_defconfig
@@ -32,7 +32,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_BOOTSTAGE=y
diff --git a/configs/cm_t43_defconfig b/configs/cm_t43_defconfig
index a307e83d1d4..12d010ab64b 100644
--- a/configs/cm_t43_defconfig
+++ b/configs/cm_t43_defconfig
@@ -62,7 +62,6 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_NAND=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
-# CONFIG_CMD_NFS is not set
CONFIG_SYS_DISABLE_AUTOLOAD=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_MTDPARTS=y
diff --git a/configs/colibri_imx6_defconfig b/configs/colibri_imx6_defconfig
index 9d2a2018c99..be1037b6cbb 100644
--- a/configs/colibri_imx6_defconfig
+++ b/configs/colibri_imx6_defconfig
@@ -61,7 +61,6 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_SDP=y
CONFIG_CMD_USB_MASS_STORAGE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_BOOTCOUNT=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
diff --git a/configs/colibri_t20_defconfig b/configs/colibri_t20_defconfig
index cdf9e8b1d01..eb2e202f6f2 100644
--- a/configs/colibri_t20_defconfig
+++ b/configs/colibri_t20_defconfig
@@ -36,7 +36,6 @@ CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_CACHE=y
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
diff --git a/configs/colibri_t30_defconfig b/configs/colibri_t30_defconfig
index fed867a8eb2..8098ff7abc1 100644
--- a/configs/colibri_t30_defconfig
+++ b/configs/colibri_t30_defconfig
@@ -36,7 +36,6 @@ CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
diff --git a/configs/colibri_vf_defconfig b/configs/colibri_vf_defconfig
index c47bfc801a2..4d4d0e4aaf4 100644
--- a/configs/colibri_vf_defconfig
+++ b/configs/colibri_vf_defconfig
@@ -51,7 +51,6 @@ CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_EXT4=y
diff --git a/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig b/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig
index 14f00b6212e..656d575998c 100644
--- a/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig
+++ b/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig
@@ -44,7 +44,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_BOOTSTAGE=y
diff --git a/configs/conga-qeval20-qa3-e3845_defconfig b/configs/conga-qeval20-qa3-e3845_defconfig
index 613dcd3ca59..54dc59e8a13 100644
--- a/configs/conga-qeval20-qa3-e3845_defconfig
+++ b/configs/conga-qeval20-qa3-e3845_defconfig
@@ -40,7 +40,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_BOOTSTAGE=y
diff --git a/configs/coreboot64_defconfig b/configs/coreboot64_defconfig
index 60a1924e9e5..8aadaa68c27 100644
--- a/configs/coreboot64_defconfig
+++ b/configs/coreboot64_defconfig
@@ -30,7 +30,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_SOUND=y
diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig
index 058caf008f9..0f3512d23c6 100644
--- a/configs/coreboot_defconfig
+++ b/configs/coreboot_defconfig
@@ -32,7 +32,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_SOUND=y
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index a8a79fd1056..d3513b94d88 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -36,7 +36,6 @@ CONFIG_CMD_LOADM=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_CACHE=y
CONFIG_CMD_RTC=y
CONFIG_CMD_TIME=y
diff --git a/configs/cougarcanyon2_defconfig b/configs/cougarcanyon2_defconfig
index 47834bb6fef..da5ff5573d0 100644
--- a/configs/cougarcanyon2_defconfig
+++ b/configs/cougarcanyon2_defconfig
@@ -31,7 +31,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_EXT2=y
diff --git a/configs/crownbay_defconfig b/configs/crownbay_defconfig
index 69ad017f987..70e1a50a244 100644
--- a/configs/crownbay_defconfig
+++ b/configs/crownbay_defconfig
@@ -33,7 +33,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_SOUND=y
diff --git a/configs/dalmore_defconfig b/configs/dalmore_defconfig
index 936787bb39c..92f4436eebd 100644
--- a/configs/dalmore_defconfig
+++ b/configs/dalmore_defconfig
@@ -36,7 +36,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
diff --git a/configs/dfi-bt700-q7x-151_defconfig b/configs/dfi-bt700-q7x-151_defconfig
index 14e6e6c2d84..9313e7fbd12 100644
--- a/configs/dfi-bt700-q7x-151_defconfig
+++ b/configs/dfi-bt700-q7x-151_defconfig
@@ -38,7 +38,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_BOOTSTAGE=y
diff --git a/configs/edison_defconfig b/configs/edison_defconfig
index 00342aace9a..8692a8a9995 100644
--- a/configs/edison_defconfig
+++ b/configs/edison_defconfig
@@ -28,7 +28,6 @@ CONFIG_CMD_DFU=y
CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_PART=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_TIMER=y
CONFIG_CMD_HASH=y
CONFIG_CMD_EXT4=y
diff --git a/configs/efi-x86_payload32_defconfig b/configs/efi-x86_payload32_defconfig
index a5c629b46f3..4149eea6cf6 100644
--- a/configs/efi-x86_payload32_defconfig
+++ b/configs/efi-x86_payload32_defconfig
@@ -25,7 +25,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_EXT2=y
diff --git a/configs/efi-x86_payload64_defconfig b/configs/efi-x86_payload64_defconfig
index 5cde04a5ac9..d41f73cccfc 100644
--- a/configs/efi-x86_payload64_defconfig
+++ b/configs/efi-x86_payload64_defconfig
@@ -25,7 +25,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_EXT2=y
diff --git a/configs/galileo_defconfig b/configs/galileo_defconfig
index 0d2ebdab926..c6d989ea6ef 100644
--- a/configs/galileo_defconfig
+++ b/configs/galileo_defconfig
@@ -29,7 +29,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_EXT2=y
diff --git a/configs/gazerbeam_defconfig b/configs/gazerbeam_defconfig
index c8c8469d8a6..7901a195aa7 100644
--- a/configs/gazerbeam_defconfig
+++ b/configs/gazerbeam_defconfig
@@ -123,7 +123,6 @@ CONFIG_SYS_LOADS_BAUD_CHANGE=y
CONFIG_CMD_MMC=y
CONFIG_CMD_AXI=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_CACHE=y
diff --git a/configs/ge_bx50v3_defconfig b/configs/ge_bx50v3_defconfig
index f005e91e0bc..2ef560ccaa4 100644
--- a/configs/ge_bx50v3_defconfig
+++ b/configs/ge_bx50v3_defconfig
@@ -34,7 +34,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_PCI=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_BMP=y
CONFIG_CMD_BOOTCOUNT=y
CONFIG_CMD_CACHE=y
diff --git a/configs/harmony_defconfig b/configs/harmony_defconfig
index b1d9399b860..8b49505a650 100644
--- a/configs/harmony_defconfig
+++ b/configs/harmony_defconfig
@@ -31,7 +31,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_EXT4_WRITE=y
diff --git a/configs/imx28_xea_defconfig b/configs/imx28_xea_defconfig
index 06dd6b1f0ed..96d15e89af8 100644
--- a/configs/imx28_xea_defconfig
+++ b/configs/imx28_xea_defconfig
@@ -14,6 +14,9 @@ CONFIG_SPL_DM_SPI=y
CONFIG_DEFAULT_DEVICE_TREE="imx28-xea"
CONFIG_SPL_TEXT_BASE=0x1000
CONFIG_TARGET_XEA=y
+CONFIG_SPL_MXS_PMU_MINIMAL_VDD5V_CURRENT=y
+CONFIG_SPL_MXS_PMU_DISABLE_BATT_CHARGE=y
+# CONFIG_SPL_MXS_PMU_ENABLE_4P2_LINEAR_REGULATOR is not set
CONFIG_SPL_MMC=y
CONFIG_SPL_SERIAL=y
CONFIG_SPL_STACK=0x20000
@@ -26,6 +29,8 @@ CONFIG_SYS_LOAD_ADDR=0x42000000
CONFIG_SPL_PAYLOAD="u-boot.img"
CONFIG_FIT=y
CONFIG_TIMESTAMP=y
+# CONFIG_BOOTMETH_EXTLINUX is not set
+# CONFIG_BOOTMETH_VBE is not set
CONFIG_OF_BOARD_SETUP=y
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0,115200n8"
@@ -95,7 +100,7 @@ CONFIG_MMC_MXS=y
CONFIG_MTD=y
CONFIG_DM_MTD=y
CONFIG_DM_SPI_FLASH=y
-CONFIG_SF_DEFAULT_BUS=3
+CONFIG_SF_DEFAULT_BUS=2
CONFIG_SPI_FLASH_SFDP_SUPPORT=y
CONFIG_SPI_FLASH_ISSI=y
CONFIG_SPI_FLASH_SPANSION=y
@@ -113,9 +118,9 @@ CONFIG_PINCTRL_MXS=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
-CONFIG_CONS_INDEX=0
+CONFIG_SPECIFY_CONSOLE_INDEX=y
+CONFIG_DM_SERIAL=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_MXS_SPI=y
-CONFIG_FS_FAT=y
# CONFIG_SPL_OF_LIBFDT is not set
diff --git a/configs/imx28_xea_sb_defconfig b/configs/imx28_xea_sb_defconfig
index bb7bf5d9dab..a43183444d7 100644
--- a/configs/imx28_xea_sb_defconfig
+++ b/configs/imx28_xea_sb_defconfig
@@ -94,7 +94,9 @@ CONFIG_PINCTRL_MXS=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_SPECIFY_CONSOLE_INDEX=y
CONFIG_CONS_INDEX=0
+CONFIG_DM_SERIAL=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_MXS_SPI=y
diff --git a/configs/imx8mm_beacon_defconfig b/configs/imx8mm_beacon_defconfig
index bb02b9bfcc9..52edb2ed19d 100644
--- a/configs/imx8mm_beacon_defconfig
+++ b/configs/imx8mm_beacon_defconfig
@@ -5,6 +5,7 @@ CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_ENV_SOURCE_FILE="imx8mm_beacon"
CONFIG_SF_DEFAULT_SPEED=10000000
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xFFFFDE00
diff --git a/configs/imx8mm_beacon_fspi_defconfig b/configs/imx8mm_beacon_fspi_defconfig
new file mode 100644
index 00000000000..805fd3f6715
--- /dev/null
+++ b/configs/imx8mm_beacon_fspi_defconfig
@@ -0,0 +1,155 @@
+CONFIG_ARM=y
+CONFIG_ARCH_IMX8M=y
+CONFIG_TEXT_BASE=0x40200000
+CONFIG_SYS_MALLOC_LEN=0x2000000
+CONFIG_SPL_GPIO=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_ENV_SIZE=0x2000
+CONFIG_ENV_OFFSET=0xFFFFDE00
+CONFIG_IMX_CONFIG="board/freescale/imx8mm_evk/imximage-8mm-lpddr4-fspi.cfg"
+CONFIG_DM_GPIO=y
+CONFIG_DEFAULT_DEVICE_TREE="imx8mm-beacon-kit"
+CONFIG_SPL_TEXT_BASE=0x7E2000
+CONFIG_TARGET_IMX8MM_BEACON=y
+CONFIG_SYS_PROMPT="u-boot=> "
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_SPL=y
+CONFIG_SYS_LOAD_ADDR=0x40480000
+CONFIG_LTO=y
+CONFIG_SYS_MONITOR_LEN=524288
+CONFIG_FIT=y
+CONFIG_FIT_EXTERNAL_OFFSET=0x3000
+CONFIG_SPL_LOAD_FIT=y
+# CONFIG_USE_SPL_FIT_GENERATOR is not set
+CONFIG_OF_SYSTEM_SETUP=y
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; fi;"
+CONFIG_DEFAULT_FDT_FILE="imx8mm-beacon-kit.dtb"
+CONFIG_SPL_MAX_SIZE=0x25000
+CONFIG_SPL_PAD_TO=0x0
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x910000
+CONFIG_SPL_BSS_MAX_SIZE=0x2000
+CONFIG_SPL_BOARD_INIT=y
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK=0x920000
+CONFIG_SYS_SPL_MALLOC=y
+CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y
+CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x42200000
+CONFIG_SYS_SPL_MALLOC_SIZE=0x80000
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x300
+CONFIG_SPL_CRC32=y
+CONFIG_SPL_I2C=y
+CONFIG_SPL_NOR_SUPPORT=y
+CONFIG_SPL_POWER=y
+CONFIG_SPL_USB_HOST=y
+CONFIG_SPL_USB_GADGET=y
+CONFIG_SPL_USB_SDP_SUPPORT=y
+CONFIG_SPL_WATCHDOG=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_MAXARGS=64
+CONFIG_SYS_CBSIZE=2048
+CONFIG_SYS_PBSIZE=2074
+CONFIG_SYS_BOOTM_LEN=0x800000
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_CLK=y
+CONFIG_CMD_FUSE=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_SDP=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_SYS_MMC_ENV_DEV=2
+CONFIG_SYS_MMC_ENV_PART=2
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_USE_ETHPRIME=y
+CONFIG_ETHPRIME="FEC"
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_CLK_COMPOSITE_CCF=y
+CONFIG_CLK_COMPOSITE_CCF=y
+CONFIG_SPL_CLK_IMX8MM=y
+CONFIG_CLK_IMX8MM=y
+CONFIG_MXC_GPIO=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_I2C=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS400_ES_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SF_DEFAULT_MODE=0
+CONFIG_SF_DEFAULT_SPEED=40000000
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHYLIB=y
+CONFIG_PHY_ATHEROS=y
+CONFIG_PHY_GIGE=y
+CONFIG_FEC_MXC=y
+CONFIG_MII=y
+CONFIG_SPL_PHY=y
+CONFIG_SPL_NOP_PHY=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_PINCTRL_IMX8M=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_IMX8M_POWER_DOMAIN=y
+CONFIG_DM_PMIC=y
+# CONFIG_SPL_PMIC_CHILDREN is not set
+CONFIG_DM_PMIC_BD71837=y
+CONFIG_SPL_DM_PMIC_BD71837=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_BD71837=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_SERIAL=y
+CONFIG_MXC_UART=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_NXP_FSPI=y
+CONFIG_SYSRESET=y
+CONFIG_SPL_SYSRESET=y
+CONFIG_SYSRESET_PSCI=y
+CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_DM_THERMAL=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_MXC_USB_OTG_HACTIVE=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_VENDOR_NUM=0x0525
+CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
+CONFIG_CI_UDC=y
+CONFIG_SDP_LOADADDR=0x40400000
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_FSPI_CONF_HEADER=y
+CONFIG_FSPI_CONF_FILE="fspi_header.bin"
diff --git a/configs/imx8mm_venice_defconfig b/configs/imx8mm_venice_defconfig
index 9d0d0ee315e..a485910a529 100644
--- a/configs/imx8mm_venice_defconfig
+++ b/configs/imx8mm_venice_defconfig
@@ -6,7 +6,7 @@ CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_ENV_SIZE=0x8000
-CONFIG_ENV_OFFSET=0xff0000
+CONFIG_ENV_OFFSET=0x3f0000
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="imx8mm-venice"
CONFIG_SPL_TEXT_BASE=0x7E1000
@@ -19,7 +19,7 @@ CONFIG_SPL_SERIAL=y
CONFIG_SPL_DRIVERS_MISC=y
CONFIG_SPL_STACK=0x920000
CONFIG_SPL=y
-CONFIG_ENV_OFFSET_REDUND=0xff8000
+CONFIG_ENV_OFFSET_REDUND=0x3f8000
CONFIG_SYS_LOAD_ADDR=0x48200000
CONFIG_SYS_MEMTEST_START=0x40000000
CONFIG_SYS_MEMTEST_END=0x80000000
@@ -36,6 +36,7 @@ CONFIG_BOARD_LATE_INIT=y
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x910000
CONFIG_SPL_BSS_MAX_SIZE=0x2000
+CONFIG_SPL_BOARD_INIT=y
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
CONFIG_SYS_SPL_MALLOC=y
CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y
@@ -51,6 +52,7 @@ CONFIG_SYS_PBSIZE=2074
CONFIG_SYS_BOOTM_LEN=0x10000000
# CONFIG_CMD_EXPORTENV is not set
# CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_ERASEENV=y
CONFIG_CRC32_VERIFY=y
CONFIG_CMD_MD5SUM=y
CONFIG_MD5SUM_VERIFY=y
@@ -89,6 +91,7 @@ CONFIG_CLK_COMPOSITE_CCF=y
CONFIG_SPL_CLK_IMX8MM=y
CONFIG_CLK_IMX8MM=y
CONFIG_GPIO_HOG=y
+CONFIG_DM_GPIO_LOOKUP_LABEL=y
CONFIG_MXC_GPIO=y
CONFIG_DM_I2C=y
CONFIG_LED=y
diff --git a/configs/imx8mn_beacon_2g_defconfig b/configs/imx8mn_beacon_2g_defconfig
index 494085b373c..00e7cd01c27 100644
--- a/configs/imx8mn_beacon_2g_defconfig
+++ b/configs/imx8mn_beacon_2g_defconfig
@@ -5,6 +5,7 @@ CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_ENV_SOURCE_FILE="imx8mn_beacon"
CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=40000000
CONFIG_ENV_SIZE=0x2000
diff --git a/configs/imx8mn_beacon_defconfig b/configs/imx8mn_beacon_defconfig
index 629025a7eb4..d9a413f96d9 100644
--- a/configs/imx8mn_beacon_defconfig
+++ b/configs/imx8mn_beacon_defconfig
@@ -5,6 +5,7 @@ CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_ENV_SOURCE_FILE="imx8mn_beacon"
CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=40000000
CONFIG_ENV_SIZE=0x2000
diff --git a/configs/imx8mn_beacon_fspi_defconfig b/configs/imx8mn_beacon_fspi_defconfig
index dade877a14e..6c626aee6a9 100644
--- a/configs/imx8mn_beacon_fspi_defconfig
+++ b/configs/imx8mn_beacon_fspi_defconfig
@@ -5,6 +5,7 @@ CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_ENV_SOURCE_FILE="imx8mn_beacon"
CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=40000000
CONFIG_ENV_SIZE=0x2000
diff --git a/configs/imx8mn_var_som_defconfig b/configs/imx8mn_var_som_defconfig
index 350c0225a69..b346b14ebdd 100644
--- a/configs/imx8mn_var_som_defconfig
+++ b/configs/imx8mn_var_som_defconfig
@@ -23,12 +23,15 @@ CONFIG_SPL_SYS_MALLOC_F_LEN=0x2000
CONFIG_SPL=y
CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000
CONFIG_SYS_LOAD_ADDR=0x40480000
+CONFIG_OF_BOARD_FIXUP=y
CONFIG_FIT=y
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
CONFIG_SPL_LOAD_FIT=y
+CONFIG_OF_BOARD_SETUP=y
CONFIG_OF_SYSTEM_SETUP=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_DEFAULT_FDT_FILE="freescale/imx8mn-var-som-symphony.dtb"
+CONFIG_BOARD_TYPES=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL_MAX_SIZE=0x25000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
@@ -76,6 +79,7 @@ CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_UUU_SUPPORT=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=2
CONFIG_MXC_GPIO=y
+CONFIG_DM_PCA953X=y
CONFIG_DM_I2C=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_IO_VOLTAGE=y
diff --git a/configs/imx8mn_venice_defconfig b/configs/imx8mn_venice_defconfig
index 3974a384d1e..39f930ae2ca 100644
--- a/configs/imx8mn_venice_defconfig
+++ b/configs/imx8mn_venice_defconfig
@@ -6,7 +6,7 @@ CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_ENV_SIZE=0x8000
-CONFIG_ENV_OFFSET=0xff0000
+CONFIG_ENV_OFFSET=0x3f0000
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="imx8mn-venice"
CONFIG_SPL_TEXT_BASE=0x912000
@@ -19,7 +19,7 @@ CONFIG_SPL_SERIAL=y
CONFIG_SPL_DRIVERS_MISC=y
CONFIG_SPL_STACK=0x980000
CONFIG_SPL=y
-CONFIG_ENV_OFFSET_REDUND=0xff8000
+CONFIG_ENV_OFFSET_REDUND=0x3f8000
CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000
CONFIG_SYS_LOAD_ADDR=0x48200000
CONFIG_SYS_MEMTEST_START=0x40000000
@@ -38,6 +38,7 @@ CONFIG_SPL_MAX_SIZE=0x25000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x950000
CONFIG_SPL_BSS_MAX_SIZE=0x2000
+CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_BOOTROM_SUPPORT=y
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
CONFIG_SYS_SPL_MALLOC=y
@@ -54,6 +55,7 @@ CONFIG_SYS_PBSIZE=2074
CONFIG_SYS_BOOTM_LEN=0x10000000
# CONFIG_CMD_EXPORTENV is not set
# CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_ERASEENV=y
CONFIG_CRC32_VERIFY=y
CONFIG_CMD_MD5SUM=y
CONFIG_MD5SUM_VERIFY=y
@@ -90,6 +92,7 @@ CONFIG_SPL_DM=y
CONFIG_SPL_CLK_IMX8MN=y
CONFIG_CLK_IMX8MN=y
CONFIG_GPIO_HOG=y
+CONFIG_DM_GPIO_LOOKUP_LABEL=y
CONFIG_MXC_GPIO=y
CONFIG_DM_I2C=y
CONFIG_LED=y
diff --git a/configs/imx8mp_beacon_defconfig b/configs/imx8mp_beacon_defconfig
index 99c4043ace8..77a10b901de 100644
--- a/configs/imx8mp_beacon_defconfig
+++ b/configs/imx8mp_beacon_defconfig
@@ -18,6 +18,7 @@ CONFIG_SYS_HAS_ARMV8_SECURE_BASE=y
CONFIG_TARGET_IMX8MP_BEACON=y
CONFIG_SYS_PROMPT="u-boot=> "
CONFIG_SYS_MONITOR_LEN=524288
+CONFIG_LTO=y
CONFIG_SPL_MMC=y
CONFIG_SPL_SERIAL=y
CONFIG_SPL_DRIVERS_MISC=y
diff --git a/configs/imx8mp_venice_defconfig b/configs/imx8mp_venice_defconfig
index a6f6ec67c52..294206ba8b2 100644
--- a/configs/imx8mp_venice_defconfig
+++ b/configs/imx8mp_venice_defconfig
@@ -6,7 +6,7 @@ CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_ENV_SIZE=0x8000
-CONFIG_ENV_OFFSET=0xff0000
+CONFIG_ENV_OFFSET=0x3f0000
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="imx8mp-venice"
CONFIG_SPL_TEXT_BASE=0x920000
@@ -19,7 +19,7 @@ CONFIG_SPL_SERIAL=y
CONFIG_SPL_DRIVERS_MISC=y
CONFIG_SPL_STACK=0x960000
CONFIG_SPL=y
-CONFIG_ENV_OFFSET_REDUND=0xff8000
+CONFIG_ENV_OFFSET_REDUND=0x3f8000
CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000
CONFIG_SYS_LOAD_ADDR=0x40480000
CONFIG_SYS_MEMTEST_START=0x40000000
@@ -38,6 +38,7 @@ CONFIG_SPL_MAX_SIZE=0x26000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x98fc00
CONFIG_SPL_BSS_MAX_SIZE=0x400
+CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_BOOTROM_SUPPORT=y
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
CONFIG_SYS_SPL_MALLOC=y
@@ -54,6 +55,7 @@ CONFIG_SYS_PBSIZE=2074
CONFIG_SYS_BOOTM_LEN=0x10000000
# CONFIG_CMD_EXPORTENV is not set
# CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_ERASEENV=y
CONFIG_CRC32_VERIFY=y
CONFIG_CMD_MD5SUM=y
CONFIG_MD5SUM_VERIFY=y
@@ -75,7 +77,7 @@ CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
-CONFIG_OF_LIST="imx8mp-venice imx8mp-venice-gw74xx"
+CONFIG_OF_LIST="imx8mp-venice imx8mp-venice-gw74xx imx8mp-venice-gw7905-2x"
CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
CONFIG_SYS_MMC_ENV_DEV=2
@@ -87,6 +89,7 @@ CONFIG_SPL_DM=y
CONFIG_CLK_COMPOSITE_CCF=y
CONFIG_CLK_IMX8MP=y
CONFIG_GPIO_HOG=y
+CONFIG_DM_GPIO_LOOKUP_LABEL=y
CONFIG_MXC_GPIO=y
CONFIG_DM_I2C=y
CONFIG_LED=y
diff --git a/configs/imx93_11x11_evk_defconfig b/configs/imx93_11x11_evk_defconfig
index 0de563f790b..65f473885c6 100644
--- a/configs/imx93_11x11_evk_defconfig
+++ b/configs/imx93_11x11_evk_defconfig
@@ -81,6 +81,7 @@ CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
+CONFIG_ADC_IMX93=y
CONFIG_CPU=y
CONFIG_CPU_IMX=y
CONFIG_IMX_RGPIO2P=y
diff --git a/configs/jetson-tk1_defconfig b/configs/jetson-tk1_defconfig
index b2a39e0c844..d8086281582 100644
--- a/configs/jetson-tk1_defconfig
+++ b/configs/jetson-tk1_defconfig
@@ -40,7 +40,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
diff --git a/configs/malta64_defconfig b/configs/malta64_defconfig
index 03de1616840..a69e1934fe8 100644
--- a/configs/malta64_defconfig
+++ b/configs/malta64_defconfig
@@ -26,7 +26,6 @@ CONFIG_CMD_IDE=y
CONFIG_CMD_PCI=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_DATE=y
# CONFIG_ISO_PARTITION is not set
diff --git a/configs/malta64el_defconfig b/configs/malta64el_defconfig
index 3ea9fa9857e..21a291d341c 100644
--- a/configs/malta64el_defconfig
+++ b/configs/malta64el_defconfig
@@ -28,7 +28,6 @@ CONFIG_CMD_IDE=y
CONFIG_CMD_PCI=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_DATE=y
# CONFIG_ISO_PARTITION is not set
diff --git a/configs/malta_defconfig b/configs/malta_defconfig
index 317b422a6b6..8c76ebbb155 100644
--- a/configs/malta_defconfig
+++ b/configs/malta_defconfig
@@ -25,7 +25,6 @@ CONFIG_CMD_IDE=y
CONFIG_CMD_PCI=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_DATE=y
# CONFIG_ISO_PARTITION is not set
diff --git a/configs/maltael_defconfig b/configs/maltael_defconfig
index 3e4d2beda2f..4abd3b15580 100644
--- a/configs/maltael_defconfig
+++ b/configs/maltael_defconfig
@@ -27,7 +27,6 @@ CONFIG_CMD_IDE=y
CONFIG_CMD_PCI=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_DATE=y
# CONFIG_ISO_PARTITION is not set
diff --git a/configs/medcom-wide_defconfig b/configs/medcom-wide_defconfig
index 47fcf1574e4..e99bb8f5b52 100644
--- a/configs/medcom-wide_defconfig
+++ b/configs/medcom-wide_defconfig
@@ -31,7 +31,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_EXT4_WRITE=y
diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig
index 6082b8d70d6..8347a9dcecf 100644
--- a/configs/minnowmax_defconfig
+++ b/configs/minnowmax_defconfig
@@ -43,7 +43,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_BOOTSTAGE=y
diff --git a/configs/mscc_jr2_defconfig b/configs/mscc_jr2_defconfig
index b30b804dbf2..e3ff906098a 100644
--- a/configs/mscc_jr2_defconfig
+++ b/configs/mscc_jr2_defconfig
@@ -44,7 +44,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_SPI=y
CONFIG_CMD_DHCP=y
# CONFIG_NET_TFTP_VARS is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_MTDPARTS=y
CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
diff --git a/configs/mscc_luton_defconfig b/configs/mscc_luton_defconfig
index 9a1e0c3e064..e811bc97e1f 100644
--- a/configs/mscc_luton_defconfig
+++ b/configs/mscc_luton_defconfig
@@ -46,7 +46,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_SPI=y
CONFIG_CMD_DHCP=y
# CONFIG_NET_TFTP_VARS is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_MTDPARTS=y
diff --git a/configs/mscc_ocelot_defconfig b/configs/mscc_ocelot_defconfig
index a372b21f66b..f3246f22196 100644
--- a/configs/mscc_ocelot_defconfig
+++ b/configs/mscc_ocelot_defconfig
@@ -44,7 +44,6 @@ CONFIG_CMD_MTD=y
CONFIG_CMD_SPI=y
CONFIG_CMD_DHCP=y
# CONFIG_NET_TFTP_VARS is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_MTDPARTS=y
CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
diff --git a/configs/mscc_serval_defconfig b/configs/mscc_serval_defconfig
index 055ed68305a..4ff7933717b 100644
--- a/configs/mscc_serval_defconfig
+++ b/configs/mscc_serval_defconfig
@@ -41,7 +41,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_SPI=y
CONFIG_CMD_DHCP=y
# CONFIG_NET_TFTP_VARS is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_MTDPARTS=y
CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
diff --git a/configs/mscc_servalt_defconfig b/configs/mscc_servalt_defconfig
index 6e225a69389..5f6ed73c2ed 100644
--- a/configs/mscc_servalt_defconfig
+++ b/configs/mscc_servalt_defconfig
@@ -40,7 +40,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_SPI=y
CONFIG_CMD_DHCP=y
# CONFIG_NET_TFTP_VARS is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_MTDPARTS=y
CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
diff --git a/configs/mt7620_mt7530_rfb_defconfig b/configs/mt7620_mt7530_rfb_defconfig
index 96f10926b13..af9df547d57 100644
--- a/configs/mt7620_mt7530_rfb_defconfig
+++ b/configs/mt7620_mt7530_rfb_defconfig
@@ -38,7 +38,6 @@ CONFIG_SYS_BOOTM_LEN=0x1000000
CONFIG_CMD_GPIO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_SPI=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_MII=y
# CONFIG_CMD_MDIO is not set
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clocks clock-names interrupt-parent interrupts resets reset-names"
diff --git a/configs/mt7620_rfb_defconfig b/configs/mt7620_rfb_defconfig
index d96da91df36..fe57fd1892d 100644
--- a/configs/mt7620_rfb_defconfig
+++ b/configs/mt7620_rfb_defconfig
@@ -39,7 +39,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_MII=y
# CONFIG_CMD_MDIO is not set
CONFIG_CMD_FAT=y
diff --git a/configs/mt7621_nand_rfb_defconfig b/configs/mt7621_nand_rfb_defconfig
index 5291bb300e4..368bf800968 100644
--- a/configs/mt7621_nand_rfb_defconfig
+++ b/configs/mt7621_nand_rfb_defconfig
@@ -49,7 +49,6 @@ CONFIG_CMD_MTD=y
CONFIG_CMD_PART=y
# CONFIG_CMD_PINMUX is not set
CONFIG_CMD_USB=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
# CONFIG_SPL_DOS_PARTITION is not set
diff --git a/configs/mt7621_rfb_defconfig b/configs/mt7621_rfb_defconfig
index b50fbec92dd..49c9e7411d8 100644
--- a/configs/mt7621_rfb_defconfig
+++ b/configs/mt7621_rfb_defconfig
@@ -47,7 +47,6 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_PART=y
# CONFIG_CMD_PINMUX is not set
CONFIG_CMD_SPI=y
-# CONFIG_CMD_NFS is not set
CONFIG_DOS_PARTITION=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_ISO_PARTITION is not set
diff --git a/configs/mt7623a_unielec_u7623_02_defconfig b/configs/mt7623a_unielec_u7623_02_defconfig
index a7687b54f0c..20c84d65df7 100644
--- a/configs/mt7623a_unielec_u7623_02_defconfig
+++ b/configs/mt7623a_unielec_u7623_02_defconfig
@@ -31,7 +31,6 @@ CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_READ=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NET_RANDOM_ETHADDR=y
diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig
index 62a17f2cbc7..5e7c1fefadb 100644
--- a/configs/mt7623n_bpir2_defconfig
+++ b/configs/mt7623n_bpir2_defconfig
@@ -31,7 +31,6 @@ CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_READ=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/mt7628_rfb_defconfig b/configs/mt7628_rfb_defconfig
index 0e100fca498..7e5b76c590a 100644
--- a/configs/mt7628_rfb_defconfig
+++ b/configs/mt7628_rfb_defconfig
@@ -37,7 +37,6 @@ CONFIG_SYS_BOOTM_LEN=0x1000000
CONFIG_CMD_GPIO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_SPI=y
-# CONFIG_CMD_NFS is not set
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NET_RANDOM_ETHADDR=y
diff --git a/configs/mt7629_rfb_defconfig b/configs/mt7629_rfb_defconfig
index ea8d77c0a26..0e3bd4ffa7b 100644
--- a/configs/mt7629_rfb_defconfig
+++ b/configs/mt7629_rfb_defconfig
@@ -48,7 +48,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_SF_TEST=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
diff --git a/configs/mx23_olinuxino_defconfig b/configs/mx23_olinuxino_defconfig
index 89b69fb3236..24968e18710 100644
--- a/configs/mx23_olinuxino_defconfig
+++ b/configs/mx23_olinuxino_defconfig
@@ -50,6 +50,7 @@ CONFIG_LED_STATUS_BOOT=0
CONFIG_LED_STATUS_CMD=y
CONFIG_MMC_MXS=y
CONFIG_CONS_INDEX=0
+CONFIG_DM_SERIAL=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_HOST_ETHER=y
diff --git a/configs/mx23evk_defconfig b/configs/mx23evk_defconfig
index 3602ead8635..7d0e7cc1e00 100644
--- a/configs/mx23evk_defconfig
+++ b/configs/mx23evk_defconfig
@@ -49,6 +49,7 @@ CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_CONS_INDEX=0
+CONFIG_DM_SERIAL=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_STORAGE=y
diff --git a/configs/mx28evk_defconfig b/configs/mx28evk_defconfig
index dad8839a6c1..df0cceaea71 100644
--- a/configs/mx28evk_defconfig
+++ b/configs/mx28evk_defconfig
@@ -62,6 +62,6 @@ CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_RTC_MXS=y
-CONFIG_CONS_INDEX=0
+CONFIG_DM_SERIAL=y
CONFIG_SPI=y
CONFIG_USB=y
diff --git a/configs/nyan-big_defconfig b/configs/nyan-big_defconfig
index a9c10cdbb0b..cc64facd5f2 100644
--- a/configs/nyan-big_defconfig
+++ b/configs/nyan-big_defconfig
@@ -45,7 +45,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_BMP=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
diff --git a/configs/odroid_defconfig b/configs/odroid_defconfig
index ce0c47e505d..b1943cfd39b 100644
--- a/configs/odroid_defconfig
+++ b/configs/odroid_defconfig
@@ -41,7 +41,6 @@ CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_CACHE=y
# CONFIG_CMD_SLEEP is not set
CONFIG_CMD_PMIC=y
diff --git a/configs/omap4_panda_defconfig b/configs/omap4_panda_defconfig
index e27e27d0143..5571722ea6d 100644
--- a/configs/omap4_panda_defconfig
+++ b/configs/omap4_panda_defconfig
@@ -33,7 +33,6 @@ CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
CONFIG_OF_CONTROL=y
CONFIG_ENV_OVERWRITE=y
diff --git a/configs/omap4_sdp4430_defconfig b/configs/omap4_sdp4430_defconfig
index 909f10ee790..0a8a1c77ea4 100644
--- a/configs/omap4_sdp4430_defconfig
+++ b/configs/omap4_sdp4430_defconfig
@@ -29,7 +29,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_EFI_PARTITION is not set
CONFIG_SPL_PARTITION_UUIDS=y
diff --git a/configs/p2371-0000_defconfig b/configs/p2371-0000_defconfig
index 7e75f44c743..dcfd3eb99a5 100644
--- a/configs/p2371-0000_defconfig
+++ b/configs/p2371-0000_defconfig
@@ -28,7 +28,6 @@ CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
CONFIG_ENV_OVERWRITE=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/p2371-2180_defconfig b/configs/p2371-2180_defconfig
index 2543a2d11f8..5b91631367b 100644
--- a/configs/p2371-2180_defconfig
+++ b/configs/p2371-2180_defconfig
@@ -34,7 +34,6 @@ CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
CONFIG_OF_LIVE=y
CONFIG_ENV_OVERWRITE=y
diff --git a/configs/p2571_defconfig b/configs/p2571_defconfig
index 47a0a62d252..7e2829e3a0d 100644
--- a/configs/p2571_defconfig
+++ b/configs/p2571_defconfig
@@ -29,7 +29,6 @@ CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
CONFIG_ENV_OVERWRITE=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/p2771-0000-000_defconfig b/configs/p2771-0000-000_defconfig
index e3b978eb1ed..ae235058afd 100644
--- a/configs/p2771-0000-000_defconfig
+++ b/configs/p2771-0000-000_defconfig
@@ -27,7 +27,6 @@ CONFIG_CMD_PCI=y
CONFIG_CMD_SPI=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
CONFIG_ENV_OVERWRITE=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/p2771-0000-500_defconfig b/configs/p2771-0000-500_defconfig
index c99a24eef40..0ea47192dda 100644
--- a/configs/p2771-0000-500_defconfig
+++ b/configs/p2771-0000-500_defconfig
@@ -27,7 +27,6 @@ CONFIG_CMD_PCI=y
CONFIG_CMD_SPI=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
CONFIG_ENV_OVERWRITE=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/configs/p3450-0000_defconfig b/configs/p3450-0000_defconfig
index e280be8f2ec..b0d538f0f83 100644
--- a/configs/p3450-0000_defconfig
+++ b/configs/p3450-0000_defconfig
@@ -35,7 +35,6 @@ CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
CONFIG_OF_LIVE=y
CONFIG_ENV_OVERWRITE=y
diff --git a/configs/paz00_defconfig b/configs/paz00_defconfig
index fadf7fdeb07..8c125c39b2f 100644
--- a/configs/paz00_defconfig
+++ b/configs/paz00_defconfig
@@ -28,7 +28,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_EXT4_WRITE=y
diff --git a/configs/phycore-imx8mm_defconfig b/configs/phycore-imx8mm_defconfig
index ffdb5cce8eb..4a27d15cb11 100644
--- a/configs/phycore-imx8mm_defconfig
+++ b/configs/phycore-imx8mm_defconfig
@@ -21,6 +21,7 @@ CONFIG_SPL_STACK=0x920000
CONFIG_SPL=y
CONFIG_ENV_OFFSET_REDUND=0x3E0000
CONFIG_SYS_LOAD_ADDR=0x40480000
+CONFIG_LTO=y
CONFIG_FIT=y
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
CONFIG_SPL_LOAD_FIT=y
diff --git a/configs/phycore-imx8mp_defconfig b/configs/phycore-imx8mp_defconfig
index 3d076204ad0..7bf404be860 100644
--- a/configs/phycore-imx8mp_defconfig
+++ b/configs/phycore-imx8mp_defconfig
@@ -21,6 +21,7 @@ CONFIG_SPL_STACK=0x960000
CONFIG_SPL=y
CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000
CONFIG_SYS_LOAD_ADDR=0x40480000
+CONFIG_LTO=y
CONFIG_FIT=y
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
CONFIG_SPL_LOAD_FIT=y
diff --git a/configs/plutux_defconfig b/configs/plutux_defconfig
index 4fee9df94f8..ab9aef5e478 100644
--- a/configs/plutux_defconfig
+++ b/configs/plutux_defconfig
@@ -32,7 +32,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
diff --git a/configs/poleg_evb_defconfig b/configs/poleg_evb_defconfig
index b00fb48a5a7..cab589d7aa0 100644
--- a/configs/poleg_evb_defconfig
+++ b/configs/poleg_evb_defconfig
@@ -102,3 +102,6 @@ CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_WDT_NPCM=y
CONFIG_LIB_HW_RAND=y
CONFIG_SHA_HW_ACCEL=y
+CONFIG_FIT=y
+CONFIG_SHA256=y
+CONFIG_SHA512=y
diff --git a/configs/qemu-x86_64_defconfig b/configs/qemu-x86_64_defconfig
index f29a5aa0f81..6a539a859e0 100644
--- a/configs/qemu-x86_64_defconfig
+++ b/configs/qemu-x86_64_defconfig
@@ -47,7 +47,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_TIME=y
CONFIG_CMD_QFW=y
CONFIG_CMD_BOOTSTAGE=y
diff --git a/configs/qemu-x86_defconfig b/configs/qemu-x86_defconfig
index 9bf29647fe5..a7c37b8b0e1 100644
--- a/configs/qemu-x86_defconfig
+++ b/configs/qemu-x86_defconfig
@@ -28,7 +28,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_TIME=y
CONFIG_CMD_QFW=y
CONFIG_CMD_BOOTSTAGE=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 1ec44d5b33b..4cef6c51539 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -30,6 +30,7 @@ CONFIG_AUTOBOOT_STOP_STR_ENABLE=y
CONFIG_AUTOBOOT_STOP_STR_CRYPT="$5$rounds=640000$HrpE65IkB8CM5nCL$BKT3QdF98Bo8fJpTr9tjZLZQyzqPASBY20xuK5Rent9"
CONFIG_IMAGE_PRE_LOAD=y
CONFIG_IMAGE_PRE_LOAD_SIG=y
+CONFIG_CEDIT=y
CONFIG_CONSOLE_RECORD=y
CONFIG_CONSOLE_RECORD_OUT_SIZE=0x6000
CONFIG_PRE_CONSOLE_BUFFER=y
diff --git a/configs/seaboard_defconfig b/configs/seaboard_defconfig
index 00cca911710..f8759f25546 100644
--- a/configs/seaboard_defconfig
+++ b/configs/seaboard_defconfig
@@ -31,7 +31,6 @@ CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_EXT4_WRITE=y
diff --git a/configs/smdkv310_defconfig b/configs/smdkv310_defconfig
index cc0ecad11b3..2f466d23a54 100644
--- a/configs/smdkv310_defconfig
+++ b/configs/smdkv310_defconfig
@@ -27,7 +27,6 @@ CONFIG_SYS_PBSIZE=1024
# CONFIG_CMD_XIMG is not set
CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_CACHE=y
# CONFIG_CMD_SLEEP is not set
CONFIG_CMD_EXT4_WRITE=y
diff --git a/configs/sniper_defconfig b/configs/sniper_defconfig
index f6b59a6e9b8..c762d75aec1 100644
--- a/configs/sniper_defconfig
+++ b/configs/sniper_defconfig
@@ -32,7 +32,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_ENV_OVERWRITE=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_SYS_I2C_LEGACY=y
diff --git a/configs/socrates_defconfig b/configs/socrates_defconfig
index ba5990bfe25..33092c74613 100644
--- a/configs/socrates_defconfig
+++ b/configs/socrates_defconfig
@@ -57,7 +57,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_SNTP=y
diff --git a/configs/som-db5800-som-6867_defconfig b/configs/som-db5800-som-6867_defconfig
index ad95274879a..4a149133db6 100644
--- a/configs/som-db5800-som-6867_defconfig
+++ b/configs/som-db5800-som-6867_defconfig
@@ -38,7 +38,6 @@ CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_BOOTSTAGE=y
diff --git a/configs/starfive_visionfive2_defconfig b/configs/starfive_visionfive2_defconfig
index ffbc4b94767..570a1f53a19 100644
--- a/configs/starfive_visionfive2_defconfig
+++ b/configs/starfive_visionfive2_defconfig
@@ -7,12 +7,13 @@ CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80000000
CONFIG_SF_DEFAULT_SPEED=100000000
CONFIG_SPL_DM_SPI=y
-CONFIG_DEFAULT_DEVICE_TREE="jh7110-starfive-visionfive-2-v1.3b"
+CONFIG_DEFAULT_DEVICE_TREE="jh7110-starfive-visionfive-2"
CONFIG_SPL_TEXT_BASE=0x8000000
CONFIG_SYS_PROMPT="StarFive #"
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_DM_RESET=y
CONFIG_SPL_MMC=y
+CONFIG_SPL_DRIVERS_MISC=y
CONFIG_SPL_STACK=0x8180000
CONFIG_SPL=y
CONFIG_SPL_SPI_FLASH_SUPPORT=y
@@ -23,6 +24,7 @@ CONFIG_SPL_OPENSBI_LOAD_ADDR=0x40000000
CONFIG_ARCH_RV64I=y
CONFIG_CMODEL_MEDANY=y
CONFIG_RISCV_SMODE=y
+# CONFIG_OF_BOARD_FIXUP is not set
CONFIG_FIT=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_QSPI_BOOT=y
@@ -31,9 +33,11 @@ CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyS0,115200 debug rootwait earlycon=sbi"
CONFIG_USE_PREBOOT=y
CONFIG_PREBOOT="setenv fdt_addr ${fdtcontroladdr};fdt addr ${fdtcontroladdr};"
-CONFIG_DEFAULT_FDT_FILE="starfive/jh7110-starfive-visionfive-2-v1.3b.dtb"
+CONFIG_DEFAULT_FDT_FILE="starfive/jh7110-starfive-visionfive-2.dtb"
CONFIG_DISPLAY_CPUINFO=y
CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_ID_EEPROM=y
+CONFIG_SYS_EEPROM_BUS_NUM=5
CONFIG_SPL_MAX_SIZE=0x40000
CONFIG_SPL_PAD_TO=0x0
CONFIG_SPL_BSS_START_ADDR=0x8040000
@@ -45,19 +49,34 @@ CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x80000000
CONFIG_SYS_SPL_MALLOC_SIZE=0x400000
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_SYS_CBSIZE=256
CONFIG_SYS_PBSIZE=276
CONFIG_SYS_BOOTM_LEN=0x4000000
+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_MEMINFO=y
+CONFIG_CMD_I2C=y
CONFIG_CMD_TFTPPUT=y
+CONFIG_OF_BOARD=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
CONFIG_SPL_CLK_COMPOSITE_CCF=y
CONFIG_CLK_COMPOSITE_CCF=y
CONFIG_SPL_CLK_JH7110=y
-# CONFIG_I2C is not set
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_DW=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
+CONFIG_SPL_I2C_EEPROM=y
+CONFIG_SYS_I2C_EEPROM_ADDR=0X50
CONFIG_MMC_HS400_SUPPORT=y
CONFIG_SPL_MMC_HS400_SUPPORT=y
CONFIG_MMC_DW=y
@@ -66,6 +85,13 @@ CONFIG_SPI_FLASH_EON=y
CONFIG_SPI_FLASH_GIGADEVICE=y
CONFIG_SPI_FLASH_ISSI=y
CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_PHY_MOTORCOMM=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_ETH_PHY=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_STARFIVE=y
+CONFIG_RGMII=y
+CONFIG_RMII=y
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
CONFIG_SPL_PINCTRL=y
diff --git a/configs/tec-ng_defconfig b/configs/tec-ng_defconfig
index 442cee33a9f..4776e92683d 100644
--- a/configs/tec-ng_defconfig
+++ b/configs/tec-ng_defconfig
@@ -34,7 +34,6 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
diff --git a/configs/tec_defconfig b/configs/tec_defconfig
index 461c46c725d..8a5d959a5c0 100644
--- a/configs/tec_defconfig
+++ b/configs/tec_defconfig
@@ -31,7 +31,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_EXT4_WRITE=y
diff --git a/configs/th1520_lpi4a_defconfig b/configs/th1520_lpi4a_defconfig
new file mode 100644
index 00000000000..710ec6abf52
--- /dev/null
+++ b/configs/th1520_lpi4a_defconfig
@@ -0,0 +1,82 @@
+CONFIG_RISCV=y
+CONFIG_SYS_MALLOC_LEN=0x800000
+CONFIG_SYS_MALLOC_F_LEN=0x3000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80200000
+CONFIG_DEFAULT_DEVICE_TREE="th1520-lichee-pi-4a"
+CONFIG_SYS_PROMPT="LPI4A=> "
+CONFIG_SYS_LOAD_ADDR=0x80200000
+# CONFIG_SMP is not set
+CONFIG_TARGET_TH1520_LPI4A=y
+CONFIG_ARCH_RV64I=y
+CONFIG_OF_BOARD_FIXUP=y
+CONFIG_SYS_BOOT_GET_CMDLINE=y
+CONFIG_SYS_BOOT_GET_KBD=y
+CONFIG_FIT=y
+# CONFIG_FIT_FULL_CHECK is not set
+# CONFIG_FIT_PRINT is not set
+# CONFIG_BOOTSTD is not set
+# CONFIG_LEGACY_IMAGE_FORMAT is not set
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTARGS_SUBST=y
+CONFIG_BOOTCOMMAND=""
+CONFIG_DEFAULT_FDT_FILE="thead/th1520-lichee-pi-4a.dtb"
+CONFIG_LOG=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SYS_CBSIZE=256
+CONFIG_SYS_PBSIZE=276
+CONFIG_CMD_CONFIG=y
+CONFIG_CMD_LICENSE=y
+CONFIG_CMD_BOOTZ=y
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+CONFIG_SYS_BOOTM_LEN=0x4000000
+CONFIG_CMD_BOOTMENU=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_MEMORY is not set
+# CONFIG_CMD_LZMADEC is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SOURCE is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_SLEEP is not set
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_VERSION_VARIABLE=y
+# CONFIG_NET is not set
+# CONFIG_BLOCK_CACHE is not set
+# CONFIG_GPIO is not set
+# CONFIG_I2C is not set
+# CONFIG_INPUT is not set
+# CONFIG_DM_MMC is not set
+# CONFIG_MTD is not set
+# CONFIG_POWER is not set
+CONFIG_SYS_NS16550=y
+CONFIG_RISCV_TIMER=y
+CONFIG_AES=y
+CONFIG_BLAKE2=y
+CONFIG_SHA512=y
+CONFIG_LZ4=y
+CONFIG_LZMA=y
+CONFIG_LZO=y
+CONFIG_ZLIB_UNCOMPRESS=y
+CONFIG_BZIP2=y
+CONFIG_ZSTD=y
+CONFIG_LIB_RATIONAL=y
+# CONFIG_EFI_LOADER is not set
+# CONFIG_LMB_USE_MAX_REGIONS is not set
diff --git a/configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig b/configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig
index 43dab09316e..69499e17f4c 100644
--- a/configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig
+++ b/configs/theadorable-x86-conga-qa3-e3845-pcie-x4_defconfig
@@ -38,7 +38,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_BMP=y
CONFIG_CMD_TIME=y
diff --git a/configs/theadorable-x86-conga-qa3-e3845_defconfig b/configs/theadorable-x86-conga-qa3-e3845_defconfig
index 5aec52733e6..e2e64b74349 100644
--- a/configs/theadorable-x86-conga-qa3-e3845_defconfig
+++ b/configs/theadorable-x86-conga-qa3-e3845_defconfig
@@ -37,7 +37,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_BMP=y
CONFIG_CMD_TIME=y
diff --git a/configs/theadorable-x86-dfi-bt700_defconfig b/configs/theadorable-x86-dfi-bt700_defconfig
index d5a28a2df4b..751ae3497ec 100644
--- a/configs/theadorable-x86-dfi-bt700_defconfig
+++ b/configs/theadorable-x86-dfi-bt700_defconfig
@@ -35,7 +35,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_BMP=y
CONFIG_CMD_TIME=y
diff --git a/configs/trimslice_defconfig b/configs/trimslice_defconfig
index d94a0b408b5..9ec08bda883 100644
--- a/configs/trimslice_defconfig
+++ b/configs/trimslice_defconfig
@@ -35,7 +35,6 @@ CONFIG_CMD_PCI=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
diff --git a/configs/venice2_defconfig b/configs/venice2_defconfig
index fd538da3ac5..ebd1754fc8b 100644
--- a/configs/venice2_defconfig
+++ b/configs/venice2_defconfig
@@ -36,7 +36,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
diff --git a/configs/ventana_defconfig b/configs/ventana_defconfig
index 5e2ff877ca8..2da8ba94d62 100644
--- a/configs/ventana_defconfig
+++ b/configs/ventana_defconfig
@@ -29,7 +29,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NFS is not set
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_EXT4_WRITE=y
diff --git a/configs/verdin-imx8mm_defconfig b/configs/verdin-imx8mm_defconfig
index 0eb18915154..09e14c6f8c4 100644
--- a/configs/verdin-imx8mm_defconfig
+++ b/configs/verdin-imx8mm_defconfig
@@ -98,6 +98,7 @@ CONFIG_CLK_COMPOSITE_CCF=y
CONFIG_SPL_CLK_IMX8MM=y
CONFIG_CLK_IMX8MM=y
CONFIG_GPIO_HOG=y
+CONFIG_SPL_GPIO_HOG=y
CONFIG_MXC_GPIO=y
CONFIG_DM_I2C=y
CONFIG_MISC=y
diff --git a/configs/verdin-imx8mp_defconfig b/configs/verdin-imx8mp_defconfig
index f1fa2b8f496..2df0f4f3443 100644
--- a/configs/verdin-imx8mp_defconfig
+++ b/configs/verdin-imx8mp_defconfig
@@ -42,6 +42,7 @@ CONFIG_PREBOOT="test -n ${fdtfile} || setenv fdtfile imx8mp-verdin-${variant}-${
CONFIG_LOG=y
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_ARCH_MISC_INIT=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_BOARD_LATE_INIT=y
CONFIG_SPL_MAX_SIZE=0x26000
@@ -108,6 +109,7 @@ CONFIG_CLK_COMPOSITE_CCF=y
CONFIG_CLK_IMX8MP=y
CONFIG_FSL_CAAM=y
CONFIG_GPIO_HOG=y
+CONFIG_SPL_GPIO_HOG=y
CONFIG_MXC_GPIO=y
CONFIG_DM_PCA953X=y
CONFIG_DM_I2C=y
diff --git a/configs/vexpress_ca9x4_defconfig b/configs/vexpress_ca9x4_defconfig
index 4ee64c332b3..5cacecc7cbc 100644
--- a/configs/vexpress_ca9x4_defconfig
+++ b/configs/vexpress_ca9x4_defconfig
@@ -30,7 +30,6 @@ CONFIG_CMD_MMC=y
# CONFIG_CMD_ITEST is not set
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_BOOTFILESIZE=y
-# CONFIG_CMD_NFS is not set
# CONFIG_CMD_SLEEP is not set
CONFIG_CMD_UBI=y
CONFIG_OF_CONTROL=y
diff --git a/configs/x240_defconfig b/configs/x240_defconfig
new file mode 100644
index 00000000000..6d25c5ae3fc
--- /dev/null
+++ b/configs/x240_defconfig
@@ -0,0 +1,86 @@
+CONFIG_ARM=y
+CONFIG_ARCH_CPU_INIT=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_TEXT_BASE=0x200000000
+CONFIG_SYS_MALLOC_LEN=0x900000
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x200FF0000
+CONFIG_TARGET_X240=y
+CONFIG_ENV_SIZE=0x10000
+CONFIG_ENV_OFFSET=0x00f80000
+CONFIG_ENV_SECT_SIZE=0x40000
+CONFIG_DM_GPIO=y
+CONFIG_DEFAULT_DEVICE_TREE="ac5-98dx35xx-atl-x240"
+CONFIG_SYS_LOAD_ADDR=0x220000000
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_FIT=y
+CONFIG_BOOTDELAY=3
+CONFIG_SYS_CONSOLE_ENV_OVERWRITE=y
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_UBI=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_CLK=y
+CONFIG_CLK_MVEBU=y
+CONFIG_GPIO_HOG=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MVTWSI=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_MISC=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_NAND_PXA3XX=y
+CONFIG_SYS_NAND_ONFI_DETECTION=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_PHY=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_ARMADA_8K=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_RTC=y
+CONFIG_RTC_MAX313XX=y
+CONFIG_DM_SCSI=y
+CONFIG_SYS_NS16550=y
+CONFIG_MVEBU_A3700_SPI=y
+CONFIG_DM_THERMAL=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_ASIX88179=y
+CONFIG_USB_ETHER_MCS7830=y
+CONFIG_USB_ETHER_RTL8152=y
+CONFIG_USB_ETHER_SMSC95XX=y
+# CONFIG_FAT_WRITE is not set
diff --git a/doc/board/beacon/beacon-imx8mm.rst b/doc/board/beacon/beacon-imx8mm.rst
new file mode 100644
index 00000000000..8bf983bff77
--- /dev/null
+++ b/doc/board/beacon/beacon-imx8mm.rst
@@ -0,0 +1,55 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+U-Boot for the Beacon EmbeddedWorks i.MX8M Mini Devkit
+======================================================
+
+Quick Start
+-----------
+
+- Build the ARM Trusted firmware binary
+- Get DDR firmware
+- Build U-Boot
+- Burn U-Boot to microSD Card
+- Boot
+
+Get and Build the ARM Trusted firmware
+--------------------------------------
+
+.. code-block:: bash
+
+ $ git clone https://github.com/nxp-imx/imx-atf.git -b v2.6
+ $ make PLAT=imx8mm bl31 CROSS_COMPILE=aarch64-linux-gnu-
+ $ cp build/imx8mm/release/bl31.bin ../
+
+Get the DDR firmware
+--------------------
+
+.. code-block:: bash
+
+ $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.15.bin
+ $ chmod +x firmware-imx-8.15.bin
+ $ ./firmware-imx-8.15
+ $ cp firmware-imx-8.15/firmware/ddr/synopsys/lpddr4*.bin .
+
+Build U-Boot
+------------
+
+.. code-block:: bash
+
+ $ make imx8mm_beacon_defconfig
+ $ make CROSS_COMPILE=aarch64-linux-gnu-
+
+Burn U-Boot to microSD Card
+---------------------------
+
+.. code-block:: bash
+
+ $ sudo dd if=flash.bin of=/dev/sd[x] bs=1024 seek=33
+
+Boot
+----
+
+Set baseboard DIP switches for micoSD Card:
+- S11 (1:8) 01101000
+- S10 (1:8) 11001000
+- S17 (1:8) 0110xxxx
diff --git a/doc/board/beacon/beacon-imx8mn.rst b/doc/board/beacon/beacon-imx8mn.rst
new file mode 100644
index 00000000000..bb4a86369bb
--- /dev/null
+++ b/doc/board/beacon/beacon-imx8mn.rst
@@ -0,0 +1,53 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+U-Boot for the Beacon EmbeddedWorks i.MX8M Nano Devkit
+======================================================
+
+Quick Start
+-----------
+
+- Build the ARM Trusted firmware binary
+- Get DDR firmware
+- Build U-Boot
+- Burn U-Boot to microSD Card
+- Boot
+
+Get and Build the ARM Trusted firmware
+--------------------------------------
+
+.. code-block:: bash
+
+ $ git clone https://github.com/nxp-imx/imx-atf.git -b v2.6
+ $ make PLAT=imx8mn bl31 CROSS_COMPILE=aarch64-linux-gnu-
+ $ cp build/imx8mn/release/bl31.bin ../
+
+Get the DDR firmware
+--------------------
+
+.. code-block:: bash
+
+ $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.15.bin
+ $ chmod +x firmware-imx-8.15.bin
+ $ ./firmware-imx-8.15
+ $ cp firmware-imx-8.15/firmware/ddr/synopsys/lpddr4*.bin .
+
+Build U-Boot
+------------
+
+.. code-block:: bash
+
+ $ make imx8mn_beacon_defconfig
+ $ make CROSS_COMPILE=aarch64-linux-gnu-
+
+Burn U-Boot to microSD Card
+---------------------------
+
+.. code-block:: bash
+
+ $ sudo dd if=flash.bin of=/dev/sd[x] bs=1024 seek=32
+
+Boot
+----
+
+Set baseboard DIP switches for micoSD Card:
+S17 (1:8): 1100xxxx
diff --git a/doc/board/beacon/index.rst b/doc/board/beacon/index.rst
index 1fe1046a4ce..bf62b09fbad 100644
--- a/doc/board/beacon/index.rst
+++ b/doc/board/beacon/index.rst
@@ -7,3 +7,5 @@ Beacon
:maxdepth: 2
beacon-imx8mp
+ beacon-imx8mm
+ beacon-imx8mn
diff --git a/doc/board/gateworks/imx8mm_venice.rst b/doc/board/gateworks/imx8mm_venice.rst
index f1e7e499445..ea78dfd7ae6 100644
--- a/doc/board/gateworks/imx8mm_venice.rst
+++ b/doc/board/gateworks/imx8mm_venice.rst
@@ -47,4 +47,6 @@ Update eMMC
=> tftpboot $loadaddr flash.bin
=> setexpr blkcnt $filesize + 0x1ff && setexpr blkcnt $blkcnt / 0x200
- => mmc dev 2 && mmc write $loadaddr 0x42 $blkcnt
+ => mmc dev 2 0 && mmc write $loadaddr 0x42 $blkcnt # emmc user hw part
+ => mmc dev 2 1 && mmc write $loadaddr 0x42 $blkcnt # or emmc boot0 hw part
+ => mmc dev 2 2 && mmc write $loadaddr 0x42 $blkcnt # or emmc boot1 hw part
diff --git a/doc/board/gateworks/imx8mn_venice.rst b/doc/board/gateworks/imx8mn_venice.rst
index 7ba953a4a85..7015f4ef31c 100644
--- a/doc/board/gateworks/imx8mn_venice.rst
+++ b/doc/board/gateworks/imx8mn_venice.rst
@@ -47,4 +47,6 @@ Update eMMC
=> tftpboot $loadaddr flash.bin
=> setexpr blkcnt $filesize + 0x1ff && setexpr blkcnt $blkcnt / 0x200
- => mmc dev 2 && mmc write $loadaddr 0x40 $blkcnt
+ => mmc dev 2 0 && mmc write $loadaddr 0x40 $blkcnt # emmc user hw part
+ => mmc dev 2 1 && mmc write $loadaddr 0 $blkcnt # or emmc boot0 hw part
+ => mmc dev 2 2 && mmc write $loadaddr 0 $blkcnt # or emmc boot1 hw part
diff --git a/doc/board/gateworks/imx8mp_venice.rst b/doc/board/gateworks/imx8mp_venice.rst
index 632cd742d1f..a219caadff2 100644
--- a/doc/board/gateworks/imx8mp_venice.rst
+++ b/doc/board/gateworks/imx8mp_venice.rst
@@ -47,4 +47,6 @@ Update eMMC
=> tftpboot $loadaddr flash.bin
=> setexpr blkcnt $filesize + 0x1ff && setexpr blkcnt $blkcnt / 0x200
- => mmc dev 2 && mmc write $loadaddr 0x40 $blkcnt
+ => mmc dev 2 0 && mmc write $loadaddr 0x40 $blkcnt # emmc user hw part
+ => mmc dev 2 1 && mmc write $loadaddr 0 $blkcnt # or emmc boot0 hw part
+ => mmc dev 2 2 && mmc write $loadaddr 0 $blkcnt # or emmc boot1 hw part
diff --git a/doc/board/index.rst b/doc/board/index.rst
index 9ef25b10915..84aa8c158ab 100644
--- a/doc/board/index.rst
+++ b/doc/board/index.rst
@@ -32,6 +32,7 @@ Board-specific doc
nokia/index
nxp/index
openpiton/index
+ phytec/index
purism/index
qualcomm/index
renesas/index
@@ -45,6 +46,7 @@ Board-specific doc
starfive/index
ste/index
tbs/index
+ thead/index
ti/index
toradex/index
variscite/index
diff --git a/doc/board/phytec/index.rst b/doc/board/phytec/index.rst
new file mode 100644
index 00000000000..a5b442045ed
--- /dev/null
+++ b/doc/board/phytec/index.rst
@@ -0,0 +1,10 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+PHYTEC
+======
+
+.. toctree::
+ :maxdepth: 2
+
+ phycore-imx8mm
+ phycore-imx8mp
diff --git a/doc/board/phytec/phycore-imx8mm.rst b/doc/board/phytec/phycore-imx8mm.rst
new file mode 100644
index 00000000000..e9dc2259907
--- /dev/null
+++ b/doc/board/phytec/phycore-imx8mm.rst
@@ -0,0 +1,60 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+phyCORE-i.MX 8M Mini
+====================
+
+The phyCORE-i.MX 8M Mini with 2GB of main memory is supported.
+
+Quick Start
+-----------
+
+- Build the ARM Trusted firmware binary
+- Get ddr firmware
+- Build U-Boot
+- Boot
+
+Build the ARM Trusted firmware binary
+-------------------------------------
+
+.. code-block:: bash
+
+ $ git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
+ $ cd trusted-firmware-a
+ $ export CROSS_COMPILE=aarch64-linux-gnu
+ $ export IMX_BOOT_UART_BASE=0x30880000
+ $ make PLAT=imx8mm bl31
+
+Get the ddr firmware
+--------------------
+
+.. code-block:: bash
+
+ $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.19.bin
+ $ chmod +x firmware-imx-8.19.bin
+ $ ./firmware-imx-8.19.bin
+
+Build U-Boot for SD card
+------------------------
+
+Copy binaries
+^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ $ cp <TF-A dir>/build/imx8mm/release/bl31.bin .
+ $ cp firmware-imx-8.19/firmware/ddr/synopsys/lpddr4*.bin .
+
+Build U-Boot
+^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ $ make phycore-imx8mm_defconfig
+ $ make flash.bin
+
+Flash SD card
+^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ $ sudo dd if=flash.bin of=/dev/sd[x] bs=1024 seek=33 conv=sync
diff --git a/doc/board/phytec/phycore-imx8mp.rst b/doc/board/phytec/phycore-imx8mp.rst
new file mode 100644
index 00000000000..fda751aeffb
--- /dev/null
+++ b/doc/board/phytec/phycore-imx8mp.rst
@@ -0,0 +1,60 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+phyCORE-i.MX 8M Plus
+====================
+
+The phyCORE-i.MX 8M Plus with 2GB of main memory is supported.
+
+Quick Start
+-----------
+
+- Build the ARM Trusted firmware binary
+- Get ddr firmware
+- Build U-Boot
+- Boot
+
+Build the ARM Trusted firmware binary
+-------------------------------------
+
+.. code-block:: bash
+
+ $ git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
+ $ cd trusted-firmware-a
+ $ export CROSS_COMPILE=aarch64-linux-gnu
+ $ export IMX_BOOT_UART_BASE=0x30860000
+ $ make PLAT=imx8mp bl31
+
+Get the ddr firmware
+--------------------
+
+.. code-block:: bash
+
+ $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.19.bin
+ $ chmod +x firmware-imx-8.19.bin
+ $ ./firmware-imx-8.19.bin
+
+Build U-Boot for SD card
+------------------------
+
+Copy binaries
+^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ $ cp <TF-A dir>/build/imx8mp/release/bl31.bin .
+ $ cp firmware-imx-8.19/firmware/ddr/synopsys/lpddr4*.bin .
+
+Build U-Boot
+^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ $ make phycore-imx8mp_defconfig
+ $ make flash.bin
+
+Flash SD card
+^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ $ sudo dd if=flash.bin of=/dev/sd[x] bs=1024 seek=32 conv=sync
diff --git a/doc/board/starfive/visionfive2.rst b/doc/board/starfive/visionfive2.rst
index 4d43ac9729c..951e0d80fb9 100644
--- a/doc/board/starfive/visionfive2.rst
+++ b/doc/board/starfive/visionfive2.rst
@@ -62,7 +62,7 @@ Now build the U-Boot SPL and U-Boot proper
.. code-block:: console
cd <U-Boot-dir>
- make starfive_visionfive2_13b_defconfig
+ make starfive_visionfive2_defconfig
make OPENSBI=$(opensbi_dir)/opensbi/build/platform/generic/firmware/fw_dynamic.bin
This will generate spl/u-boot-spl.bin and FIT image (u-boot.itb)
@@ -118,7 +118,7 @@ Program the SD card
sudo cp u-boot.itb /mnt/
sudo cp Image.gz /mnt/
sudo cp initramfs.cpio.gz /mnt/
- sudo cp jh7110-starfive-visionfive-2-v1.3b.dtb /mnt/
+ sudo cp jh7110-starfive-visionfive-2.dtb /mnt/
sudo umount /mnt
Booting
@@ -264,7 +264,7 @@ Sample boot log from StarFive VisionFive2 board
StarFive #fatload mmc 1:3 ${kernel_addr_r} Image.gz
6429424 bytes read in 394 ms (15.6 MiB/s)
- StarFive #fatload mmc 1:3 ${fdt_addr_r} jh7110-starfive-visionfive-2-v1.3b.dtb
+ StarFive #fatload mmc 1:3 ${fdt_addr_r} jh7110-starfive-visionfive-2.dtb
11285 bytes read in 5 ms (2.2 MiB/s)
StarFive #fatload mmc 1:3 ${ramdisk_addr_r} initramfs.cpio.gz
152848495 bytes read in 9271 ms (15.7 MiB/s)
diff --git a/doc/board/thead/index.rst b/doc/board/thead/index.rst
new file mode 100644
index 00000000000..41566d3a368
--- /dev/null
+++ b/doc/board/thead/index.rst
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+T-HEAD
+========
+
+.. toctree::
+ :maxdepth: 1
+
+ lpi4a
diff --git a/doc/board/thead/lpi4a.rst b/doc/board/thead/lpi4a.rst
new file mode 100644
index 00000000000..e395c6ae12c
--- /dev/null
+++ b/doc/board/thead/lpi4a.rst
@@ -0,0 +1,129 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Sipeed's Lichee PI 4A based on T-HEAD TH1520 SoC
+================================================
+
+The LicheePi4A is a high-performance RISC-V SBC based on TH1520(4xC910@1.85GHz),
+comes with 4/8/16 GB RAM, and up to 128GB eMMC, and rich peripherals.
+
+ - SoC T-HEAD TH1520 SoC
+ - System Memory 4GB, 8GB, or 16GB LPDDR4X
+ - Storage eMMC flash with 8/32/128 GB
+ - external microSD slot
+ - Networking 2x Gigabit Ethernet
+ - WiFi+BT
+ - Display HDMI2.0, 4-lane MIPI DSI
+ - Camera 4-lane MIPI CSI + 2x2-lane MIPI CSI
+ - Audio Onboard Speaker, 2xMEMS MIC, 3.5mm headphone jack
+ - USB 4xUSB3.0 Type-A, 1xUSB2.0 Type-C
+ - GPIO 2x10Pin breakout, UART/IIC/SPI
+ - Power DC 12V/2A, POE 5V/2.4A, USB Type-C 5V/2A
+
+TH1520 RISC-V SoC
+-----------------
+
+The TH1520 SoC consist of quad-core RISC-V Xuantie C910 (RV64GCV) processor,
+Xuantie C906 audio DSP, low power Xuantie E902 core, it also integrate
+Imagination GPU for graphics, and 4 TOPS NPU for AI acceleration.
+
+Mainline support
+----------------
+
+The support for following drivers are already enabled:
+
+1. ns16550 UART Driver.
+
+Building
+~~~~~~~~
+
+1. Add the RISC-V toolchain to your PATH.
+2. Setup ARCH & cross compilation environment variable:
+
+.. code-block:: none
+
+ export CROSS_COMPILE=<riscv64 toolchain prefix>
+
+The U-Boot is capable of running in M-Mode, so we can directly build it.
+
+.. code-block:: console
+
+ cd <U-Boot-dir>
+ make th1520_lpi4a_defconfig
+ make
+
+This will generate u-boot-dtb.bin
+
+Booting
+~~~~~~~
+
+Currently, we rely on vendor u-boot to initialize the clock, pinctrl subsystem,
+and chain load the mainline u-boot image either via tftp or emmc storage,
+then bootup from it.
+
+Sample boot log from Lichee PI 4A board via tftp
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: none
+
+ brom_ver 8
+ [APP][E] protocol_connect failed, exit.
+
+ U-Boot SPL 2020.01-00016-g8c870a6be8 (May 20 2023 - 01:04:49 +0000)
+ FM[1] lpddr4x dualrank freq=3733 64bit dbi_off=n sdram init
+ ddr initialized, jump to uboot
+ image has no header
+
+
+ U-Boot 2020.01-00016-g8c870a6be8 (May 20 2023 - 01:04:49 +0000)
+
+ CPU: rv64imafdcvsu
+ Model: T-HEAD c910 light
+ DRAM: 8 GiB
+ C910 CPU FREQ: 750MHz
+ AHB2_CPUSYS_HCLK FREQ: 250MHz
+ AHB3_CPUSYS_PCLK FREQ: 125MHz
+ PERISYS_AHB_HCLK FREQ: 250MHz
+ PERISYS_APB_PCLK FREQ: 62MHz
+ GMAC PLL POSTDIV FREQ: 1000MHZ
+ DPU0 PLL POSTDIV FREQ: 1188MHZ
+ DPU1 PLL POSTDIV FREQ: 1188MHZ
+ MMC: sdhci@ffe7080000: 0, sd@ffe7090000: 1
+ Loading Environment from MMC... OK
+ Error reading output register
+ Warning: cannot get lcd-en GPIO
+ LCD panel cannot be found : -121
+ splash screen startup cost 16 ms
+ In: serial
+ Out: serial
+ Err: serial
+ Net:
+ Warning: ethernet@ffe7070000 using MAC address from ROM
+ eth0: ethernet@ffe7070000ethernet@ffe7070000:0 is connected to ethernet@ffe7070000. Reconnecting to ethernet@ffe7060000
+
+ Warning: ethernet@ffe7060000 (eth1) using random MAC address - 42:25:d4:16:5f:fc
+ , eth1: ethernet@ffe7060000
+ Hit any key to stop autoboot: 2
+ ethernet@ffe7060000 Waiting for PHY auto negotiation to complete.. done
+ Speed: 1000, full duplex
+ Using ethernet@ffe7070000 device
+ TFTP from server 192.168.8.50; our IP address is 192.168.8.45
+ Filename 'u-boot-dtb.bin'.
+ Load address: 0x1c00000
+ Loading: * #########################
+ 8 MiB/s
+ done
+ Bytes transferred = 376686 (5bf6e hex)
+ ## Starting application at 0x01C00000 ...
+
+ U-Boot 2023.07-rc2-00004-g1befbe31c1 (May 23 2023 - 18:40:01 +0800)
+
+ CPU: rv64imafdc
+ Model: Sipeed Lichee Pi 4A
+ DRAM: 8 GiB
+ Core: 13 devices, 6 uclasses, devicetree: separate
+ Loading Environment from <NULL>... OK
+ In: serial@ffe7014000
+ Out: serial@ffe7014000
+ Err: serial@ffe7014000
+ Model: Sipeed Lichee Pi 4A
+ LPI4A=>
diff --git a/doc/develop/expo.rst b/doc/develop/expo.rst
index 32dd7f09030..2ac4af232da 100644
--- a/doc/develop/expo.rst
+++ b/doc/develop/expo.rst
@@ -85,6 +85,9 @@ or even the IDs of objects. Programmatic creation of many items in a loop can be
handled by allocating space in the enum for a maximum number of items, then
adding the loop count to the enum values to obtain unique IDs.
+Where dynamic IDs are need, use expo_set_dynamic_start() to set the start value,
+so that they are allocated above the starting (enum) IDs.
+
All text strings are stored in a structure attached to the expo, referenced by
a text ID. This makes it easier at some point to implement multiple languages or
to support Unicode strings.
@@ -97,10 +100,13 @@ objects first, then create the menu item, passing in the relevant IDs.
Creating an expo
----------------
-To create an expo, use `expo_new()` followed by `scene_new()` to create a scene.
-Then add objects to the scene, using functions like `scene_txt_str()` and
-`scene_menu()`. For every menu item, add text and image objects, then create
-the menu item with `scene_menuitem()`, referring to those objects.
+To create an expo programmatically, use `expo_new()` followed by `scene_new()`
+to create a scene. Then add objects to the scene, using functions like
+`scene_txt_str()` and `scene_menu()`. For every menu item, add text and image
+objects, then create the menu item with `scene_menuitem()`, referring to those
+objects.
+
+To create an expo using a description file, see :ref:`expo_format` below.
Layout
------
@@ -152,8 +158,287 @@ such as scanning devices for more bootflows.
Themes
------
-Expo does not itself support themes. The bootflow_menu implement supposed a
-basic theme, applying font sizes to the various text objects in the expo.
+Expo supports simple themes, for setting the font size, for example. Use the
+expo_apply_theme() function to load a theme, passing a node with the required
+properties:
+
+font-size
+ Font size to use for all text (type: u32)
+
+menu-inset
+ Number of pixels to inset the menu on the sides and top (type: u32)
+
+menuitem-gap-y
+ Number of pixels between menu items
+
+Pop-up mode
+-----------
+
+Expos support two modes. The simple mode is used for selecting from a single
+menu, e.g. when choosing with OS to boot. In this mode the menu items are shown
+in a list (label, > pointer, key and description) and can be chosen using arrow
+keys and enter::
+
+ U-Boot Boot Menu
+
+ UP and DOWN to choose, ENTER to select
+
+ mmc1 > 0 Fedora-Workstation-armhfp-31-1.9
+ mmc3 1 Armbian
+
+The popup mode allows multiple menus to be present in a scene. Each is shown
+just as its title and label, as with the `CPU Speed` and `AC Power` menus here::
+
+ Test Configuration
+
+
+ CPU Speed <2 GHz> (highlighted)
+
+ AC Power Always Off
+
+
+ UP and DOWN to choose, ENTER to select
+
+
+.. _expo_format:
+
+Expo Format
+-----------
+
+It can be tedious to create a complex expo using code. Expo supports a
+data-driven approach, where the expo description is in a devicetree file. This
+makes it easier and faster to create and edit the description. An expo builder
+is provided to convert this format into an expo structure.
+
+Layout of the expo scenes is handled automatically, based on a set of simple
+rules. The :doc:`../usage/cmd/cedit` can be used to load a configuration
+and create an expo from it.
+
+Top-level node
+~~~~~~~~~~~~~~
+
+The top-level node has the following properties:
+
+dynamic-start
+ type: u32, optional
+
+ Specifies the start of the dynamically allocated objects. This results in
+ a call to expo_set_dynamic_start().
+
+The top-level node has the following subnodes:
+
+scenes
+ Specifies the scenes in the expo, each one being a subnode
+
+strings
+ Specifies the strings in the expo, each one being a subnode
+
+`scenes` node
+~~~~~~~~~~~~~
+
+Contains a list of scene subnodes. The name of each subnode is passed as the
+name to `scene_new()`.
+
+`strings` node
+~~~~~~~~~~~~~~
+
+Contains a list of string subnodes. The name of each subnode is ignored.
+
+`strings` subnodes
+~~~~~~~~~~~~~~~~~~
+
+Each subnode defines a string which can be used by scenes and objects. Each
+string has an ID number which is used to refer to it.
+
+The `strings` subnodes have the following properties:
+
+id
+ type: u32, required
+
+ Specifies the ID number for the string.
+
+value:
+ type: string, required
+
+ Specifies the string text. For now only a single value is supported. Future
+ work may add support for multiple languages by using a value for each
+ language.
+
+Scene nodes (`scenes` subnodes)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each subnode of the `scenes` node contains a scene description.
+
+Most properties can use either a string or a string ID. For example, a `title`
+property can be used to provide the title for a menu; alternatively a `title-id`
+property can provide the string ID of the title. If both are present, the
+ID takes preference, except that if a string with that ID does not exist, it
+falls back to using the string from the property (`title` in this example). The
+description below shows these are alternative properties with the same
+description.
+
+The scene nodes have the following properties:
+
+id
+ type: u32, required
+
+ Specifies the ID number for the string.
+
+title / title-id
+ type: string / u32, required
+
+ Specifies the title of the scene. This is shown at the top of the scene.
+
+prompt / prompt-id
+ type: string / u32, required
+
+ Specifies a prompt for the scene. This is shown at the bottom of the scene.
+
+The scene nodes have a subnode for each object in the scene.
+
+Object nodes
+~~~~~~~~~~~~
+
+The object-node name is used as the name of the object, e.g. when calling
+`scene_menu()` to create a menu.
+
+Object nodes have the following common properties:
+
+type
+ type: string, required
+
+ Specifies the type of the object. Valid types are:
+
+ "menu"
+ Menu containing items which can be selected by the user
+
+id
+ type: u32, required
+
+ Specifies the ID of the object. This is used when referring to the object.
+
+
+Menu nodes have the following additional properties:
+
+title / title-id
+ type: string / u32, required
+
+ Specifies the title of the menu. This is shown to the left of the area for
+ this menu.
+
+item-id
+ type: u32 list, required
+
+ Specifies the ID for each menu item. These are used for checking which item
+ has been selected.
+
+item-label / item-label-id
+ type: string list / u32 list, required
+
+ Specifies the label for each item in the menu. These are shown to the user.
+ In 'popup' mode these form the items in the menu.
+
+key-label / key-label-id
+ type: string list / u32 list, optional
+
+ Specifies the key for each item in the menu. These are currently only
+ intended for use in simple mode.
+
+desc-label / desc-label-id
+ type: string list / u32 list, optional
+
+ Specifies the description for each item in the menu. These are currently
+ only intended for use in simple mode.
+
+
+Expo layout
+~~~~~~~~~~~
+
+The `expo_arrange()` function can be called to arrange the expo objects in a
+suitable manner. For each scene it puts the title at the top, the prompt at the
+bottom and the objects in order from top to bottom.
+
+Expo format example
+~~~~~~~~~~~~~~~~~~~
+
+This example shows an expo with a single scene consisting of two menus. The
+scene title is specified using a string from the strings table, but all other
+strings are provided inline in the nodes where they are used.
+
+::
+
+ #define ID_PROMPT 1
+ #define ID_SCENE1 2
+ #define ID_SCENE1_TITLE 3
+
+ #define ID_CPU_SPEED 4
+ #define ID_CPU_SPEED_TITLE 5
+ #define ID_CPU_SPEED_1 6
+ #define ID_CPU_SPEED_2 7
+ #define ID_CPU_SPEED_3 8
+
+ #define ID_POWER_LOSS 9
+ #define ID_AC_OFF 10
+ #define ID_AC_ON 11
+ #define ID_AC_MEMORY 12
+
+ #define ID_DYNAMIC_START 13
+
+ &cedit {
+ dynamic-start = <ID_DYNAMIC_START>;
+
+ scenes {
+ main {
+ id = <ID_SCENE1>;
+
+ /* value refers to the matching id in /strings */
+ title-id = <ID_SCENE1_TITLE>;
+
+ /* simple string is used as it is */
+ prompt = "UP and DOWN to choose, ENTER to select";
+
+ /* defines a menu within the scene */
+ cpu-speed {
+ type = "menu";
+ id = <ID_CPU_SPEED>;
+
+ /*
+ * has both string and ID. The string is ignored
+ * if the ID is present and points to a string
+ */
+ title = "CPU speed";
+ title-id = <ID_CPU_SPEED_TITLE>;
+
+ /* menu items as simple strings */
+ item-label = "2 GHz", "2.5 GHz", "3 GHz";
+
+ /* IDs for the menu items */
+ item-id = <ID_CPU_SPEED_1 ID_CPU_SPEED_2
+ ID_CPU_SPEED_3>;
+ };
+
+ power-loss {
+ type = "menu";
+ id = <ID_POWER_LOSS>;
+
+ title = "AC Power";
+ item-label = "Always Off", "Always On",
+ "Memory";
+
+ item-id = <ID_AC_OFF ID_AC_ON ID_AC_MEMORY>;
+ };
+ };
+ };
+
+ strings {
+ title {
+ id = <ID_SCENE1_TITLE>;
+ value = "Test Configuration";
+ value-es = "configuración de prueba";
+ };
+ };
+ };
+
API documentation
-----------------
@@ -166,12 +451,10 @@ Future ideas
Some ideas for future work:
- Default menu item and a timeout
-- Higher-level / automatic / more flexible layout of objects
- Image formats other than BMP
- Use of ANSI sequences to control a serial terminal
- Colour selection
-- Better support for handling lots of settings, e.g. with multiple menus and
- radio/option widgets
+- Support for more widgets, e.g. text, numeric, radio/option
- Mouse support
- Integrate Nuklear, NxWidgets or some other library for a richer UI
- Optimise rendering by only updating the display with changes since last render
@@ -179,10 +462,10 @@ Some ideas for future work:
- Add a Kconfig option to drop the names to save code / data space
- Add a Kconfig option to disable vidconsole support to save code / data space
- Support both graphical and text menus at the same time on different devices
-- Implement proper measurement of object bounding boxes, to permit more exact
- layout. This would tidy up the layout when Truetype is not used
- Support unicode
- Support curses for proper serial-terminal menus
+- Add support for large menus which need to scroll
+- Add support for reading and writing configuration settings with cedit
.. Simon Glass <sjg@chromium.org>
.. 7-Oct-22
diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
index 6626ceec52b..a7a41f2facf 100644
--- a/doc/develop/uefi/uefi.rst
+++ b/doc/develop/uefi/uefi.rst
@@ -552,6 +552,13 @@ update using a capsule file with --fw-version of 5, the update will fail.
When the --fw-version in the capsule file is updated, lowest-supported-version
in the dtb might be updated accordingly.
+If user needs to enforce anti-rollback to any older version,
+the lowest-supported-version property in dtb must be always updated manually.
+
+Note that the lowest-supported-version property specified in U-Boot's control
+device tree can be changed by U-Boot fdt command.
+Secure systems should not enable this command.
+
To insert the lowest supported version into a dtb
.. code-block:: console
diff --git a/doc/device-tree-bindings/config.txt b/doc/device-tree-bindings/config.txt
index 3151778b2c9..f50c68bbdc3 100644
--- a/doc/device-tree-bindings/config.txt
+++ b/doc/device-tree-bindings/config.txt
@@ -76,6 +76,8 @@ u-boot,mmc-env-partition (int)
precedence. In that case, only if the partition is not found,
mmc-env-offset* will be tried.
+ Note that CONFIG_ENV_MMC_PARTITION overrides this device-tree setting.
+
u-boot,no-apm-finalize (bool)
For x86 devices running on coreboot, this tells U-Boot not to lock
down the Intel Management Engine (ME) registers. This allows U-Boot to
diff --git a/doc/device-tree-bindings/spi/brcm,bcm63xx-hsspi.yaml b/doc/device-tree-bindings/spi/brcm,bcm63xx-hsspi.yaml
new file mode 100644
index 00000000000..6554978583f
--- /dev/null
+++ b/doc/device-tree-bindings/spi/brcm,bcm63xx-hsspi.yaml
@@ -0,0 +1,134 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/brcm,bcm63xx-hsspi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom Broadband SoC High Speed SPI controller
+
+maintainers:
+ - William Zhang <william.zhang@broadcom.com>
+ - Kursad Oney <kursad.oney@broadcom.com>
+ - Jonas Gorski <jonas.gorski@gmail.com>
+
+description: |
+ Broadcom Broadband SoC supports High Speed SPI master controller since the
+ early MIPS based chips such as BCM6328 and BCM63268. This initial rev 1.0
+ controller was carried over to recent ARM based chips, such as BCM63138,
+ BCM4908 and BCM6858. The old MIPS based chip should continue to use the
+ brcm,bcm6328-hsspi compatible string. The recent ARM based chip is required to
+ use the brcm,bcmbca-hsspi-v1.0 as part of its compatible string list as
+ defined below to match the specific chip along with ip revision info.
+
+ This rev 1.0 controller has a limitation that can not keep the chip select line
+ active between the SPI transfers within the same SPI message. This can
+ terminate the transaction to some SPI devices prematurely. The issue can be
+ worked around by either the controller's prepend mode or using the dummy chip
+ select workaround. Driver automatically picks the suitable mode based on
+ transfer type so it is transparent to the user.
+
+ The newer SoCs such as BCM6756, BCM4912 and BCM6855 include an updated SPI
+ controller rev 1.1 that add the capability to allow the driver to control chip
+ select explicitly. This solves the issue in the old controller.
+
+properties:
+ compatible:
+ oneOf:
+ - const: brcm,bcm6328-hsspi
+ - items:
+ - enum:
+ - brcm,bcm47622-hsspi
+ - brcm,bcm4908-hsspi
+ - brcm,bcm63138-hsspi
+ - brcm,bcm63146-hsspi
+ - brcm,bcm63148-hsspi
+ - brcm,bcm63158-hsspi
+ - brcm,bcm63178-hsspi
+ - brcm,bcm6846-hsspi
+ - brcm,bcm6856-hsspi
+ - brcm,bcm6858-hsspi
+ - brcm,bcm6878-hsspi
+ - const: brcm,bcmbca-hsspi-v1.0
+ - items:
+ - enum:
+ - brcm,bcm4912-hsspi
+ - brcm,bcm6756-hsspi
+ - brcm,bcm6813-hsspi
+ - brcm,bcm6855-hsspi
+ - const: brcm,bcmbca-hsspi-v1.1
+
+ reg:
+ items:
+ - description: main registers
+ - description: miscellaneous control registers
+ minItems: 1
+
+ reg-names:
+ items:
+ - const: hsspi
+ - const: spim-ctrl
+ minItems: 1
+
+ clocks:
+ items:
+ - description: SPI master reference clock
+ - description: SPI master pll clock
+
+ clock-names:
+ items:
+ - const: hsspi
+ - const: pll
+
+ interrupts:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - interrupts
+
+allOf:
+ - $ref: spi-controller.yaml#
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - brcm,bcm6328-hsspi
+ - brcm,bcmbca-hsspi-v1.0
+ then:
+ properties:
+ reg:
+ maxItems: 1
+ reg-names:
+ maxItems: 1
+ else:
+ properties:
+ reg:
+ minItems: 2
+ maxItems: 2
+ reg-names:
+ minItems: 2
+ maxItems: 2
+ required:
+ - reg-names
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ spi@ff801000 {
+ compatible = "brcm,bcm6756-hsspi", "brcm,bcmbca-hsspi-v1.1";
+ reg = <0xff801000 0x1000>,
+ <0xff802610 0x4>;
+ reg-names = "hsspi", "spim-ctrl";
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&hsspi>, <&hsspi_pll>;
+ clock-names = "hsspi", "pll";
+ num-cs = <8>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
diff --git a/doc/device-tree-bindings/spi/soft-spi.txt b/doc/device-tree-bindings/spi/soft-spi.txt
index dfb50664732..bdf7e86befb 100644
--- a/doc/device-tree-bindings/spi/soft-spi.txt
+++ b/doc/device-tree-bindings/spi/soft-spi.txt
@@ -9,10 +9,10 @@ The soft SPI node requires the following properties:
Mandatory properties:
compatible: "spi-gpio"
cs-gpios: GPIOs to use for SPI chip select (output)
-gpio-sck: GPIO to use for SPI clock (output)
+sck-gpios: GPIO to use for SPI clock (output)
And at least one of:
-gpio-mosi: GPIO to use for SPI MOSI line (output)
-gpio-miso: GPIO to use for SPI MISO line (input)
+mosi-gpios: GPIO to use for SPI MOSI line (output)
+miso-gpios: GPIO to use for SPI MISO line (input)
Optional propertie:
spi-delay-us: Number of microseconds of delay between each CS transition
@@ -27,9 +27,9 @@ Example:
soft-spi {
compatible = "spi-gpio";
cs-gpios = <&gpio 235 0>; /* Y43 */
- gpio-sck = <&gpio 225 0>; /* Y31 */
- gpio-mosi = <&gpio 227 0>; /* Y33 */
- gpio-miso = <&gpio 224 0>; /* Y30 */
+ sck-gpios = <&gpio 225 0>; /* Y31 */
+ mosi-gpios = <&gpio 227 0>; /* Y33 */
+ miso-gpios = <&gpio 224 0>; /* Y30 */
spi-delay-us = <1>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/doc/imx/habv4/csf_examples/mx8m/csf.sh b/doc/imx/habv4/csf_examples/mx8m/csf.sh
index 5b383fa982f..d87015f6c4e 100644
--- a/doc/imx/habv4/csf_examples/mx8m/csf.sh
+++ b/doc/imx/habv4/csf_examples/mx8m/csf.sh
@@ -22,6 +22,27 @@
cp doc/imx/habv4/csf_examples/mx8m/csf_spl.txt csf_spl.tmp
cp doc/imx/habv4/csf_examples/mx8m/csf_fit.txt csf_fit.tmp
+# update File Paths from env vars
+if ! [ -r $CSF_KEY ]; then
+ echo "Error: \$CSF_KEY not found"
+ exit 1
+fi
+if ! [ -r $IMG_KEY ]; then
+ echo "Error: \$IMG_KEY not found"
+ exit 1
+fi
+if ! [ -r $SRK_TABLE ]; then
+ echo "Error: \$SRK_TABLE not found"
+ exit 1
+fi
+sed -i "s:\$CSF_KEY:$CSF_KEY:" csf_spl.tmp
+sed -i "s:\$IMG_KEY:$IMG_KEY:" csf_spl.tmp
+sed -i "s:\$SRK_TABLE:$SRK_TABLE:" csf_spl.tmp
+sed -i "s:\$CSF_KEY:$CSF_KEY:" csf_fit.tmp
+sed -i "s:\$IMG_KEY:$IMG_KEY:" csf_fit.tmp
+sed -i "s:\$SRK_TABLE:$SRK_TABLE:" csf_fit.tmp
+
+# update SPL Blocks
spl_block_base=$(printf "0x%x" $(( $(sed -n "/CONFIG_SPL_TEXT_BASE=/ s@.*=@@p" .config) - 0x40)) )
spl_block_size=$(printf "0x%x" $(stat -tc %s u-boot-spl-ddr.bin))
sed -i "/Blocks = / s@.*@ Blocks = $spl_block_base 0x0 $spl_block_size \"flash.bin\"@" csf_spl.tmp
diff --git a/doc/imx/habv4/csf_examples/mx8m/csf_fit.txt b/doc/imx/habv4/csf_examples/mx8m/csf_fit.txt
index bbb82f69448..3d79edf2813 100644
--- a/doc/imx/habv4/csf_examples/mx8m/csf_fit.txt
+++ b/doc/imx/habv4/csf_examples/mx8m/csf_fit.txt
@@ -7,21 +7,21 @@
Signature Format = CMS
[Install SRK]
- # FIXME: Adjust path here
- File = "/path/to/cst-3.3.1/crts/SRK_1_2_3_4_table.bin"
+ # SRK_TABLE is full path to SRK_1_2_3_4_table.bin
+ File = "$SRK_TABLE"
Source index = 0
[Install CSFK]
- # FIXME: Adjust path here
- File = "/path/to/cst-3.3.1/crts/CSF1_1_sha256_4096_65537_v3_usr_crt.pem"
+ # CSF_KEY is full path to CSF1_1_sha256_4096_65537_v3_usr_crt.pem
+ File = "$CSF_KEY"
[Authenticate CSF]
[Install Key]
Verification index = 0
Target Index = 2
- # FIXME: Adjust path here
- File = "/path/to/cst-3.3.1/crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem"
+ # IMG_KEY is full path to IMG1_1_sha256_4096_65537_v3_usr_crt.pem
+ File = "$IMG_KEY"
[Authenticate Data]
Verification index = 2
diff --git a/doc/imx/habv4/csf_examples/mx8m/csf_spl.txt b/doc/imx/habv4/csf_examples/mx8m/csf_spl.txt
index 00e34f6b1b9..88fa420a5fa 100644
--- a/doc/imx/habv4/csf_examples/mx8m/csf_spl.txt
+++ b/doc/imx/habv4/csf_examples/mx8m/csf_spl.txt
@@ -7,13 +7,13 @@
Signature Format = CMS
[Install SRK]
- # FIXME: Adjust path here
- File = "/path/to/cst-3.3.1/crts/SRK_1_2_3_4_table.bin"
+ # SRK_TABLE is full path to SRK_1_2_3_4_table.bin
+ File = "$SRK_TABLE"
Source index = 0
[Install CSFK]
- # FIXME: Adjust path here
- File = "/path/to/cst-3.3.1/crts/CSF1_1_sha256_4096_65537_v3_usr_crt.pem"
+ # CSF_KEY is full path to CSF1_1_sha256_4096_65537_v3_usr_crt.pem
+ File = "$CSF_KEY"
[Authenticate CSF]
@@ -24,8 +24,8 @@
[Install Key]
Verification index = 0
Target Index = 2
- # FIXME: Adjust path here
- File = "/path/to/cst-3.3.1/crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem"
+ # IMG_KEY is full path to IMG1_1_sha256_4096_65537_v3_usr_crt.pem
+ File = "$IMG_KEY"
[Authenticate Data]
Verification index = 2
diff --git a/doc/imx/habv4/guides/mx8m_spl_secure_boot.txt b/doc/imx/habv4/guides/mx8m_spl_secure_boot.txt
index e79726bf2c5..e16e5410bd9 100644
--- a/doc/imx/habv4/guides/mx8m_spl_secure_boot.txt
+++ b/doc/imx/habv4/guides/mx8m_spl_secure_boot.txt
@@ -207,6 +207,16 @@ dd if=csf_fit.bin of=flash.bin bs=1 seek=${csf_block_offset} conv=notrunc
```
The entire script is available in doc/imx/habv4/csf_examples/mx8m/csf.sh
+and can be used as follows to modify flash.bin to be signed
+(adjust paths as needed):
+```
+export CST_DIR=/usr/src/cst-3.3.1/
+export CSF_KEY=$CST_DIR/crts/CSF1_1_sha256_4096_65537_v3_usr_crt.pem
+export IMG_KEY=$CST_DIR/crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem
+export SRK_TABLE=$CST_DIR/crts/SRK_1_2_3_4_table.bin
+export PATH=$CST_DIR/linux64/bin:$PATH
+/bin/sh doc/imx/habv4/csf_examples/mx8m/csf.sh
+```
1.4 Closing the device
-----------------------
diff --git a/doc/usage/cmd/cedit.rst b/doc/usage/cmd/cedit.rst
new file mode 100644
index 00000000000..8e1110c7c77
--- /dev/null
+++ b/doc/usage/cmd/cedit.rst
@@ -0,0 +1,31 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+cedit command
+=============
+
+Synopis
+-------
+
+::
+
+ cedit load <interface> <dev[:part]> <filename>
+ cedit run
+
+Description
+-----------
+
+The *cedit* command is used to load a configuration-editor description and allow
+the user to interact with it.
+
+It makes use of the expo subsystem.
+
+The description is in the form of a devicetree file, as documented at
+:ref:`expo_format`.
+
+Example
+-------
+
+::
+
+ => cedit load hostfs - fred.dtb
+ => cedit run
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 388e59f1733..f2ffd2787aa 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -39,6 +39,7 @@ Shell commands
cmd/bootz
cmd/cat
cmd/cbsysinfo
+ cmd/cedit
cmd/cls
cmd/cmp
cmd/coninfo
diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig
index e719c38bb31..4336732dee5 100644
--- a/drivers/adc/Kconfig
+++ b/drivers/adc/Kconfig
@@ -63,3 +63,11 @@ config STM32_ADC
- core driver to deal with common resources
- child driver to deal with individual ADC resources (declare ADC
device and associated channels, start/stop conversions)
+
+config ADC_IMX93
+ bool "Enable NXP IMX93 ADC driver"
+ help
+ This enables basic driver for NXP IMX93 ADC.
+ It provides:
+ - 4 analog input channels
+ - 12-bit resolution
diff --git a/drivers/adc/Makefile b/drivers/adc/Makefile
index c1387f3a346..5336c820973 100644
--- a/drivers/adc/Makefile
+++ b/drivers/adc/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_ADC_SANDBOX) += sandbox.o
obj-$(CONFIG_SARADC_ROCKCHIP) += rockchip-saradc.o
obj-$(CONFIG_SARADC_MESON) += meson-saradc.o
obj-$(CONFIG_STM32_ADC) += stm32-adc.o stm32-adc-core.o
+obj-$(CONFIG_ADC_IMX93) += imx93-adc.o
diff --git a/drivers/adc/imx93-adc.c b/drivers/adc/imx93-adc.c
new file mode 100644
index 00000000000..41d04e0426c
--- /dev/null
+++ b/drivers/adc/imx93-adc.c
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 ASEM Srl
+ * Author: Luca Ellero <l.ellero@asem.it>
+ *
+ * Originally based on NXP linux-imx kernel v5.15 drivers/iio/adc/imx93_adc.c
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <linux/bitfield.h>
+#include <linux/iopoll.h>
+#include <clk.h>
+#include <adc.h>
+
+#define IMX93_ADC_MCR 0x00
+#define IMX93_ADC_MSR 0x04
+#define IMX93_ADC_ISR 0x10
+#define IMX93_ADC_IMR 0x20
+#define IMX93_ADC_CIMR0 0x24
+#define IMX93_ADC_CTR0 0x94
+#define IMX93_ADC_NCMR0 0xA4
+#define IMX93_ADC_PCDR0 0x100
+#define IMX93_ADC_PCDR1 0x104
+#define IMX93_ADC_PCDR2 0x108
+#define IMX93_ADC_PCDR3 0x10c
+#define IMX93_ADC_PCDR4 0x110
+#define IMX93_ADC_PCDR5 0x114
+#define IMX93_ADC_PCDR6 0x118
+#define IMX93_ADC_PCDR7 0x11c
+#define IMX93_ADC_CALSTAT 0x39C
+
+#define IMX93_ADC_MCR_MODE_MASK BIT(29)
+#define IMX93_ADC_MCR_NSTART_MASK BIT(24)
+#define IMX93_ADC_MCR_CALSTART_MASK BIT(14)
+#define IMX93_ADC_MCR_ADCLKSE_MASK BIT(8)
+#define IMX93_ADC_MCR_PWDN_MASK BIT(0)
+
+#define IMX93_ADC_MSR_CALFAIL_MASK BIT(30)
+#define IMX93_ADC_MSR_CALBUSY_MASK BIT(29)
+#define IMX93_ADC_MSR_ADCSTATUS_MASK GENMASK(2, 0)
+
+#define IMX93_ADC_ISR_EOC_MASK BIT(1)
+
+#define IMX93_ADC_IMR_EOC_MASK BIT(1)
+#define IMX93_ADC_IMR_ECH_MASK BIT(0)
+
+#define IMX93_ADC_PCDR_CDATA_MASK GENMASK(11, 0)
+
+#define IDLE 0
+#define POWER_DOWN 1
+#define WAIT_STATE 2
+#define BUSY_IN_CALIBRATION 3
+#define SAMPLE 4
+#define CONVERSION 6
+
+#define IMX93_ADC_MAX_CHANNEL 3
+#define IMX93_ADC_DAT_MASK 0xfff
+#define IMX93_ADC_TIMEOUT 100000
+
+struct imx93_adc_priv {
+ int active_channel;
+ void __iomem *regs;
+ struct clk ipg_clk;
+};
+
+static void imx93_adc_power_down(struct imx93_adc_priv *adc)
+{
+ u32 mcr, msr;
+ int ret;
+
+ mcr = readl(adc->regs + IMX93_ADC_MCR);
+ mcr |= FIELD_PREP(IMX93_ADC_MCR_PWDN_MASK, 1);
+ writel(mcr, adc->regs + IMX93_ADC_MCR);
+
+ ret = readl_poll_timeout(adc->regs + IMX93_ADC_MSR, msr,
+ ((msr & IMX93_ADC_MSR_ADCSTATUS_MASK) == POWER_DOWN), 50);
+ if (ret == -ETIMEDOUT)
+ pr_warn("ADC not in power down mode, current MSR: %x\n", msr);
+}
+
+static void imx93_adc_power_up(struct imx93_adc_priv *adc)
+{
+ u32 mcr;
+
+ /* bring ADC out of power down state, in idle state */
+ mcr = readl(adc->regs + IMX93_ADC_MCR);
+ mcr &= ~FIELD_PREP(IMX93_ADC_MCR_PWDN_MASK, 1);
+ writel(mcr, adc->regs + IMX93_ADC_MCR);
+}
+
+static void imx93_adc_config_ad_clk(struct imx93_adc_priv *adc)
+{
+ u32 mcr;
+
+ /* put adc in power down mode */
+ imx93_adc_power_down(adc);
+
+ /* config the AD_CLK equal to bus clock */
+ mcr = readl(adc->regs + IMX93_ADC_MCR);
+ mcr |= FIELD_PREP(IMX93_ADC_MCR_ADCLKSE_MASK, 1);
+ writel(mcr, adc->regs + IMX93_ADC_MCR);
+
+ /* bring ADC out of power down state, in idle state */
+ imx93_adc_power_up(adc);
+}
+
+static int imx93_adc_calibration(struct imx93_adc_priv *adc)
+{
+ u32 mcr, msr;
+ int ret;
+
+ /* make sure ADC is in power down mode */
+ imx93_adc_power_down(adc);
+
+ /* config SAR controller operating clock */
+ mcr = readl(adc->regs + IMX93_ADC_MCR);
+ mcr &= ~FIELD_PREP(IMX93_ADC_MCR_ADCLKSE_MASK, 1);
+ writel(mcr, adc->regs + IMX93_ADC_MCR);
+
+ /* bring ADC out of power down state */
+ imx93_adc_power_up(adc);
+
+ /*
+ * we use the default TSAMP/NRSMPL/AVGEN in MCR,
+ * can add the setting of these bit if need
+ */
+
+ /* run calibration */
+ mcr = readl(adc->regs + IMX93_ADC_MCR);
+ mcr |= FIELD_PREP(IMX93_ADC_MCR_CALSTART_MASK, 1);
+ writel(mcr, adc->regs + IMX93_ADC_MCR);
+
+ /* wait calibration to be finished */
+ ret = readl_poll_timeout(adc->regs + IMX93_ADC_MSR, msr,
+ !(msr & IMX93_ADC_MSR_CALBUSY_MASK), 2000000);
+ if (ret == -ETIMEDOUT) {
+ pr_warn("ADC calibration timeout\n");
+ return ret;
+ }
+
+ /* check whether calbration is successful or not */
+ msr = readl(adc->regs + IMX93_ADC_MSR);
+ if (msr & IMX93_ADC_MSR_CALFAIL_MASK) {
+ pr_warn("ADC calibration failed!\n");
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+static int imx93_adc_channel_data(struct udevice *dev, int channel,
+ unsigned int *data)
+{
+ struct imx93_adc_priv *adc = dev_get_priv(dev);
+ u32 isr, pcda;
+ int ret;
+
+ if (channel != adc->active_channel) {
+ pr_err("Requested channel is not active!\n");
+ return -EINVAL;
+ }
+
+ ret = readl_poll_timeout(adc->regs + IMX93_ADC_ISR, isr,
+ (isr & IMX93_ADC_ISR_EOC_MASK), IMX93_ADC_TIMEOUT);
+
+ /* clear interrupts */
+ writel(isr, adc->regs + IMX93_ADC_ISR);
+
+ if (ret == -ETIMEDOUT) {
+ pr_warn("ADC conversion timeout!\n");
+ return ret;
+ }
+
+ pcda = readl(adc->regs + IMX93_ADC_PCDR0 + channel * 4);
+
+ *data = FIELD_GET(IMX93_ADC_PCDR_CDATA_MASK, pcda);
+
+ return 0;
+}
+
+static int imx93_adc_start_channel(struct udevice *dev, int channel)
+{
+ struct imx93_adc_priv *adc = dev_get_priv(dev);
+ u32 imr, mcr;
+
+ /* config channel mask register */
+ writel(1 << channel, adc->regs + IMX93_ADC_NCMR0);
+
+ /* config interrupt mask */
+ imr = FIELD_PREP(IMX93_ADC_IMR_EOC_MASK, 1);
+ writel(imr, adc->regs + IMX93_ADC_IMR);
+ writel(1 << channel, adc->regs + IMX93_ADC_CIMR0);
+
+ /* config one-shot mode */
+ mcr = readl(adc->regs + IMX93_ADC_MCR);
+ mcr &= ~FIELD_PREP(IMX93_ADC_MCR_MODE_MASK, 1);
+ writel(mcr, adc->regs + IMX93_ADC_MCR);
+
+ /* start normal conversion */
+ mcr = readl(adc->regs + IMX93_ADC_MCR);
+ mcr |= FIELD_PREP(IMX93_ADC_MCR_NSTART_MASK, 1);
+ writel(mcr, adc->regs + IMX93_ADC_MCR);
+
+ adc->active_channel = channel;
+
+ return 0;
+}
+
+static int imx93_adc_stop(struct udevice *dev)
+{
+ struct imx93_adc_priv *adc = dev_get_priv(dev);
+
+ imx93_adc_power_down(adc);
+
+ adc->active_channel = -1;
+
+ return 0;
+}
+
+static int imx93_adc_probe(struct udevice *dev)
+{
+ struct imx93_adc_priv *adc = dev_get_priv(dev);
+ unsigned int ret;
+
+ ret = imx93_adc_calibration(adc);
+ if (ret < 0)
+ return ret;
+
+ imx93_adc_config_ad_clk(adc);
+
+ adc->active_channel = -1;
+
+ return 0;
+}
+
+static int imx93_adc_of_to_plat(struct udevice *dev)
+{
+ struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
+ struct imx93_adc_priv *adc = dev_get_priv(dev);
+ unsigned int ret;
+
+ adc->regs = dev_read_addr_ptr(dev);
+ if (adc->regs == (struct imx93_adc *)FDT_ADDR_T_NONE) {
+ pr_err("Dev: %s - can't get address!", dev->name);
+ return -ENODATA;
+ }
+
+ ret = clk_get_by_name(dev, "ipg", &adc->ipg_clk);
+ if (ret < 0) {
+ pr_err("Can't get ADC ipg clk: %d\n", ret);
+ return ret;
+ }
+ ret = clk_enable(&adc->ipg_clk);
+ if(ret) {
+ pr_err("Can't enable ADC ipg clk: %d\n", ret);
+ return ret;
+ }
+
+ uc_pdata->data_mask = IMX93_ADC_DAT_MASK;
+ uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
+ uc_pdata->data_timeout_us = IMX93_ADC_TIMEOUT;
+
+ /* Mask available channel bits: [0:3] */
+ uc_pdata->channel_mask = (2 << IMX93_ADC_MAX_CHANNEL) - 1;
+
+ return 0;
+}
+
+static const struct adc_ops imx93_adc_ops = {
+ .start_channel = imx93_adc_start_channel,
+ .channel_data = imx93_adc_channel_data,
+ .stop = imx93_adc_stop,
+};
+
+static const struct udevice_id imx93_adc_ids[] = {
+ { .compatible = "nxp,imx93-adc" },
+ { }
+};
+
+U_BOOT_DRIVER(imx93_adc) = {
+ .name = "imx93-adc",
+ .id = UCLASS_ADC,
+ .of_match = imx93_adc_ids,
+ .ops = &imx93_adc_ops,
+ .probe = imx93_adc_probe,
+ .of_to_plat = imx93_adc_of_to_plat,
+ .priv_auto = sizeof(struct imx93_adc_priv),
+};
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 3ad5af964f3..29859cdfa15 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -160,6 +160,7 @@ config SANDBOX_CLK_CCF
config CLK_SCMI
bool "Enable SCMI clock driver"
+ depends on CLK
depends on SCMI_FIRMWARE
help
Enable this option if you want to support clock devices exposed
diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index 09bef596f22..a21a3ce34bb 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -337,7 +337,8 @@ static int imx8mp_clk_probe(struct udevice *dev)
clk_dm(IMX8MP_CLK_UART2_ROOT, imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0));
clk_dm(IMX8MP_CLK_UART3_ROOT, imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0));
clk_dm(IMX8MP_CLK_UART4_ROOT, imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0));
- clk_dm(IMX8MP_CLK_USB_ROOT, imx_clk_gate4("usb_root_clk", "usb_core_ref", base + 0x44d0, 0));
+ clk_dm(IMX8MP_CLK_USB_ROOT, imx_clk_gate2("usb_root_clk", "hsio_axi", base + 0x44d0, 0));
+ clk_dm(IMX8MP_CLK_USB_SUSP, imx_clk_gate2("usb_suspend_clk", "clock-osc-24m", base + 0x44d0, 0));
clk_dm(IMX8MP_CLK_USB_PHY_ROOT, imx_clk_gate4("usb_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0));
clk_dm(IMX8MP_CLK_USDHC1_ROOT, imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0));
clk_dm(IMX8MP_CLK_USDHC2_ROOT, imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0));
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index ec574c44607..8df16e56af5 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -12,6 +12,7 @@
#include <fdt_support.h>
#include <log.h>
#include <malloc.h>
+#include <of_live.h>
#include <linux/libfdt.h>
#include <dm/of_access.h>
#include <dm/of_addr.h>
@@ -51,6 +52,20 @@ static oftree oftree_ensure(void *fdt)
oftree tree;
int i;
+ if (of_live_active()) {
+ struct device_node *root;
+ int ret;
+
+ ret = unflatten_device_tree(fdt, &root);
+ if (ret) {
+ log_err("Failed to create live tree: err=%d\n", ret);
+ return oftree_null();
+ }
+ tree = oftree_from_np(root);
+
+ return tree;
+ }
+
if (gd->flags & GD_FLG_RELOC) {
i = oftree_find(fdt);
if (i == -1) {
@@ -67,7 +82,7 @@ static oftree oftree_ensure(void *fdt)
}
} else {
if (fdt != gd->fdt_blob) {
- log_debug("Cannot only access control FDT before relocation\n");
+ log_debug("Only the control FDT can be accessed before relocation\n");
return oftree_null();
}
}
@@ -77,6 +92,12 @@ static oftree oftree_ensure(void *fdt)
return tree;
}
+void oftree_dispose(oftree tree)
+{
+ if (of_live_active())
+ of_live_free(tree.np);
+}
+
void *ofnode_lookup_fdt(ofnode node)
{
if (gd->flags & GD_FLG_RELOC) {
@@ -133,6 +154,10 @@ oftree oftree_from_fdt(void *fdt)
if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE))
return oftree_ensure(fdt);
+#ifdef OF_CHECKS
+ if (of_live_active())
+ return oftree_null();
+#endif
tree.fdt = fdt;
return tree;
diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c
index 54d563d929b..02de692d66f 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -46,7 +46,7 @@ int scmi_to_linux_errno(s32 scmi_code)
for (n = 0; n < ARRAY_SIZE(scmi_linux_errmap); n++)
if (scmi_code == scmi_linux_errmap[n].scmi)
- return scmi_linux_errmap[1].errno;
+ return scmi_linux_errmap[n].errno;
return -EPROTO;
}
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 712119c3415..31027f3d990 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -1474,7 +1474,7 @@ static int gpio_post_bind(struct udevice *dev)
}
#endif
- if (CONFIG_IS_ENABLED(GPIO_HOG)) {
+ if (CONFIG_IS_ENABLED(GPIO_HOG) && dev_has_ofnode(dev)) {
struct udevice *child;
ofnode node;
diff --git a/drivers/led/led_bcm6753.c b/drivers/led/led_bcm6753.c
index 88b650cbfca..2466d930116 100644
--- a/drivers/led/led_bcm6753.c
+++ b/drivers/led/led_bcm6753.c
@@ -174,57 +174,65 @@ static const struct led_ops bcm6753_led_ops = {
static int bcm6753_led_probe(struct udevice *dev)
{
- struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
-
- /* Top-level LED node */
- if (!uc_plat->label) {
- void __iomem *regs;
- u32 set_bits = 0;
-
- regs = dev_remap_addr(dev);
- if (!regs)
- return -EINVAL;
-
- if (dev_read_bool(dev, "brcm,serial-led-msb-first"))
- set_bits |= CLED_CTRL_SERIAL_LED_MSB_FIRST;
- if (dev_read_bool(dev, "brcm,serial-led-en-pol"))
- set_bits |= CLED_CTRL_SERIAL_LED_EN_POL;
- if (dev_read_bool(dev, "brcm,serial-led-clk-pol"))
- set_bits |= CLED_CTRL_SERIAL_LED_CLK_POL;
- if (dev_read_bool(dev, "brcm,serial-led-data-ppol"))
- set_bits |= CLED_CTRL_SERIAL_LED_DATA_PPOL;
-
- clrsetbits_32(regs + CLED_CTRL_REG, CLED_CTRL_MASK, set_bits);
- } else {
- struct bcm6753_led_priv *priv = dev_get_priv(dev);
- void __iomem *regs;
- unsigned int pin;
-
- regs = dev_remap_addr(dev_get_parent(dev));
- if (!regs)
- return -EINVAL;
-
- pin = dev_read_u32_default(dev, "reg", LEDS_MAX);
- if (pin >= LEDS_MAX)
- return -EINVAL;
-
- priv->regs = regs;
- priv->pin = pin;
-
- /* this led is managed by software */
- clrbits_32(regs + CLED_HW_LED_EN_REG, 1 << pin);
-
- /* configure the polarity */
- if (dev_read_bool(dev, "active-low"))
- clrbits_32(regs + CLED_PLED_OP_PPOL_REG, 1 << pin);
- else
- setbits_32(regs + CLED_PLED_OP_PPOL_REG, 1 << pin);
- }
+ struct bcm6753_led_priv *priv = dev_get_priv(dev);
+ void __iomem *regs;
+ unsigned int pin;
+
+ regs = dev_remap_addr(dev_get_parent(dev));
+ if (!regs)
+ return -EINVAL;
+
+ pin = dev_read_u32_default(dev, "reg", LEDS_MAX);
+ if (pin >= LEDS_MAX)
+ return -EINVAL;
+
+ priv->regs = regs;
+ priv->pin = pin;
+
+ /* this led is managed by software */
+ clrbits_32(regs + CLED_HW_LED_EN_REG, 1 << pin);
+
+ /* configure the polarity */
+ if (dev_read_bool(dev, "active-low"))
+ clrbits_32(regs + CLED_PLED_OP_PPOL_REG, 1 << pin);
+ else
+ setbits_32(regs + CLED_PLED_OP_PPOL_REG, 1 << pin);
return 0;
}
-static int bcm6753_led_bind(struct udevice *parent)
+U_BOOT_DRIVER(bcm6753_led) = {
+ .name = "bcm6753-led",
+ .id = UCLASS_LED,
+ .probe = bcm6753_led_probe,
+ .priv_auto = sizeof(struct bcm6753_led_priv),
+ .ops = &bcm6753_led_ops,
+};
+
+static int bcm6753_led_wrap_probe(struct udevice *dev)
+{
+ void __iomem *regs;
+ u32 set_bits = 0;
+
+ regs = dev_remap_addr(dev);
+ if (!regs)
+ return -EINVAL;
+
+ if (dev_read_bool(dev, "brcm,serial-led-msb-first"))
+ set_bits |= CLED_CTRL_SERIAL_LED_MSB_FIRST;
+ if (dev_read_bool(dev, "brcm,serial-led-en-pol"))
+ set_bits |= CLED_CTRL_SERIAL_LED_EN_POL;
+ if (dev_read_bool(dev, "brcm,serial-led-clk-pol"))
+ set_bits |= CLED_CTRL_SERIAL_LED_CLK_POL;
+ if (dev_read_bool(dev, "brcm,serial-led-data-ppol"))
+ set_bits |= CLED_CTRL_SERIAL_LED_DATA_PPOL;
+
+ clrsetbits_32(regs + CLED_CTRL_REG, CLED_CTRL_MASK, set_bits);
+
+ return 0;
+}
+
+static int bcm6753_led_wrap_bind(struct udevice *parent)
{
ofnode node;
@@ -247,12 +255,10 @@ static const struct udevice_id bcm6753_led_ids[] = {
{ /* sentinel */ }
};
-U_BOOT_DRIVER(bcm6753_led) = {
- .name = "bcm6753-led",
- .id = UCLASS_LED,
+U_BOOT_DRIVER(bcm6753_led_wrap) = {
+ .name = "bcm6753_led_wrap",
+ .id = UCLASS_NOP,
.of_match = bcm6753_led_ids,
- .bind = bcm6753_led_bind,
- .probe = bcm6753_led_probe,
- .priv_auto = sizeof(struct bcm6753_led_priv),
- .ops = &bcm6753_led_ops,
+ .probe = bcm6753_led_wrap_probe,
+ .bind = bcm6753_led_wrap_bind,
};
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 04460f1acb2..b9f5c7a37ae 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -364,8 +364,8 @@ config NPCM_OTP
To compile this driver as a module, choose M here: the module
will be called npcm_otp.
-config IMX_SENTINEL
- bool "Enable i.MX Sentinel MU driver and API"
+config IMX_ELE
+ bool "Enable i.MX EdgeLock Enclave MU driver and API"
depends on MISC && (ARCH_IMX9 || ARCH_IMX8ULP)
help
If you say Y here to enable Message Unit driver to work with
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 52aed096021..fd8805f34bd 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -47,7 +47,7 @@ obj-$(CONFIG_SANDBOX) += irq_sandbox.o irq_sandbox_test.o
obj-$(CONFIG_$(SPL_)I2C_EEPROM) += i2c_eeprom.o
obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o
obj-$(CONFIG_IMX8) += imx8/
-obj-$(CONFIG_IMX_SENTINEL) += sentinel/
+obj-$(CONFIG_IMX_ELE) += imx_ele/
obj-$(CONFIG_LED_STATUS) += status_led.o
obj-$(CONFIG_LED_STATUS_GPIO) += gpio_led.o
obj-$(CONFIG_MPC83XX_SERDES) += mpc83xx_serdes.o
diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c
index dfede7f1d5f..3e3002ba6df 100644
--- a/drivers/misc/imx8/scu_api.c
+++ b/drivers/misc/imx8/scu_api.c
@@ -481,6 +481,22 @@ int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp,
return 0;
}
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status)
+{
+ struct sc_rpc_msg_s msg;
+ struct udevice *dev = gd->arch.scu_dev;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SIZE(&msg) = 1U;
+ RPC_SVC(&msg) = (u8)(SC_RPC_SVC_MISC);
+ RPC_FUNC(&msg) = (u8)(MISC_FUNC_GET_BUTTON_STATUS);
+
+ misc_call(dev, SC_FALSE, &msg, 1U, &msg, 1U);
+
+ if (status)
+ *status = (sc_bool_t)(!!(RPC_U8(&msg, 0U)));
+}
+
/* RM */
sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr)
{
@@ -851,6 +867,21 @@ int sc_pm_cpu_start(sc_ipc_t ipc, sc_rsrc_t resource, sc_bool_t enable,
return ret;
}
+void sc_pm_reboot(sc_ipc_t ipc, sc_pm_reset_type_t type)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = (u8)(PM_FUNC_REBOOT);
+ RPC_U8(&msg, 0U) = (u8)(type);
+ RPC_SIZE(&msg) = 2U;
+
+ misc_call(dev, SC_TRUE, &msg, size, &msg, size);
+}
+
int sc_pm_get_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_power_mode_t *mode)
{
@@ -877,6 +908,28 @@ int sc_pm_get_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
return ret;
}
+int sc_timer_set_wdog_window(sc_ipc_t ipc, sc_timer_wdog_time_t window)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SIZE(&msg) = 2U;
+ RPC_SVC(&msg) = (u8)(SC_RPC_SVC_TIMER);
+ RPC_FUNC(&msg) = (u8)(TIMER_FUNC_SET_WDOG_WINDOW);
+
+ RPC_U32(&msg, 0U) = (u32)(window);
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret)
+ printf("%s: window:%u: res:%d\n",
+ __func__, window, RPC_R8(&msg));
+
+ return ret;
+}
+
int sc_seco_authenticate(sc_ipc_t ipc, sc_seco_auth_cmd_t cmd,
sc_faddr_t addr)
{
@@ -974,6 +1027,31 @@ void sc_seco_build_info(sc_ipc_t ipc, u32 *version, u32 *commit)
*commit = RPC_U32(&msg, 4U);
}
+int sc_seco_v2x_build_info(sc_ipc_t ipc, u32 *version, u32 *commit)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SIZE(&msg) = 1U;
+ RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = (u8)(SECO_FUNC_V2X_BUILD_INFO);
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret)
+ printf("%s: res:%d\n", __func__, RPC_R8(&msg));
+
+ if (version)
+ *version = RPC_U32(&msg, 0U);
+
+ if (commit)
+ *commit = RPC_U32(&msg, 4U);
+
+ return ret;
+}
+
int sc_seco_get_event(sc_ipc_t ipc, u8 idx, u32 *event)
{
struct udevice *dev = gd->arch.scu_dev;
diff --git a/drivers/misc/sentinel/Makefile b/drivers/misc/imx_ele/Makefile
index 446154cb201..f8d8c55f983 100644
--- a/drivers/misc/sentinel/Makefile
+++ b/drivers/misc/imx_ele/Makefile
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0+
-obj-y += s400_api.o s4mu.o
+obj-y += ele_api.o ele_mu.o
obj-$(CONFIG_CMD_FUSE) += fuse.o
diff --git a/drivers/misc/sentinel/s400_api.c b/drivers/misc/imx_ele/ele_api.c
index 6c0d0b3f18a..0c017734a49 100644
--- a/drivers/misc/sentinel/s400_api.c
+++ b/drivers/misc/imx_ele/ele_api.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright 2020 NXP
+ * Copyright 2020, 2023 NXP
*
*/
@@ -9,25 +9,37 @@
#include <malloc.h>
#include <asm/io.h>
#include <dm.h>
-#include <asm/mach-imx/s400_api.h>
+#include <asm/mach-imx/ele_api.h>
#include <misc.h>
DECLARE_GLOBAL_DATA_PTR;
-int ahab_release_rdc(u8 core_id, u8 xrdc, u32 *response)
+static u32 compute_crc(const struct ele_msg *msg)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ u32 crc = 0;
+ size_t i = 0;
+ u32 *data = (u32 *)msg;
+
+ for (i = 0; i < (msg->size - 1); i++)
+ crc ^= data[i];
+
+ return crc;
+}
+
+int ele_release_rdc(u8 core_id, u8 xrdc, u32 *response)
+{
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 2;
msg.command = ELE_RELEASE_RDC_REQ;
switch (xrdc) {
@@ -59,20 +71,20 @@ int ahab_release_rdc(u8 core_id, u8 xrdc, u32 *response)
return ret;
}
-int ahab_auth_oem_ctnr(ulong ctnr_addr, u32 *response)
+int ele_auth_oem_ctnr(ulong ctnr_addr, u32 *response)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 3;
msg.command = ELE_OEM_CNTN_AUTH_REQ;
msg.data[0] = upper_32_bits(ctnr_addr);
@@ -89,20 +101,20 @@ int ahab_auth_oem_ctnr(ulong ctnr_addr, u32 *response)
return ret;
}
-int ahab_release_container(u32 *response)
+int ele_release_container(u32 *response)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 1;
msg.command = ELE_RELEASE_CONTAINER_REQ;
@@ -117,20 +129,20 @@ int ahab_release_container(u32 *response)
return ret;
}
-int ahab_verify_image(u32 img_id, u32 *response)
+int ele_verify_image(u32 img_id, u32 *response)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 2;
msg.command = ELE_VERIFY_IMAGE_REQ;
msg.data[0] = 1 << img_id;
@@ -146,20 +158,20 @@ int ahab_verify_image(u32 img_id, u32 *response)
return ret;
}
-int ahab_forward_lifecycle(u16 life_cycle, u32 *response)
+int ele_forward_lifecycle(u16 life_cycle, u32 *response)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 2;
msg.command = ELE_FWD_LIFECYCLE_UP_REQ;
msg.data[0] = life_cycle;
@@ -175,15 +187,15 @@ int ahab_forward_lifecycle(u16 life_cycle, u32 *response)
return ret;
}
-int ahab_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response)
+int ele_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
@@ -198,8 +210,8 @@ int ahab_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *respo
return -EINVAL;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 2;
msg.command = ELE_READ_FUSE_REQ;
msg.data[0] = fuse_id;
@@ -223,20 +235,20 @@ int ahab_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *respo
return ret;
}
-int ahab_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response)
+int ele_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 3;
msg.command = ELE_WRITE_FUSE_REQ;
msg.data[0] = (32 << 16) | (fuse_id << 5);
@@ -256,20 +268,20 @@ int ahab_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response)
return ret;
}
-int ahab_release_caam(u32 core_did, u32 *response)
+int ele_release_caam(u32 core_did, u32 *response)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 2;
msg.command = ELE_RELEASE_CAAM_REQ;
msg.data[0] = core_did;
@@ -285,15 +297,15 @@ int ahab_release_caam(u32 core_did, u32 *response)
return ret;
}
-int ahab_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response)
+int ele_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
@@ -307,8 +319,8 @@ int ahab_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response)
return -EINVAL;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 1;
msg.command = ELE_GET_FW_VERSION_REQ;
@@ -326,20 +338,20 @@ int ahab_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response)
return ret;
}
-int ahab_dump_buffer(u32 *buffer, u32 buffer_length)
+int ele_dump_buffer(u32 *buffer, u32 buffer_length)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret, i = 0;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 1;
msg.command = ELE_DUMP_DEBUG_BUFFER_REQ;
@@ -360,25 +372,25 @@ int ahab_dump_buffer(u32 *buffer, u32 buffer_length)
return i;
}
-int ahab_get_info(struct sentinel_get_info_data *info, u32 *response)
+int ele_get_info(struct ele_get_info_data *info, u32 *response)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 4;
msg.command = ELE_GET_INFO_REQ;
msg.data[0] = upper_32_bits((ulong)info);
msg.data[1] = lower_32_bits((ulong)info);
- msg.data[2] = sizeof(struct sentinel_get_info_data);
+ msg.data[2] = sizeof(struct ele_get_info_data);
ret = misc_call(dev, false, &msg, size, &msg, size);
if (ret)
@@ -391,20 +403,20 @@ int ahab_get_info(struct sentinel_get_info_data *info, u32 *response)
return ret;
}
-int ahab_get_fw_status(u32 *status, u32 *response)
+int ele_get_fw_status(u32 *status, u32 *response)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 1;
msg.command = ELE_GET_FW_STATUS_REQ;
@@ -421,20 +433,20 @@ int ahab_get_fw_status(u32 *status, u32 *response)
return ret;
}
-int ahab_release_m33_trout(void)
+int ele_release_m33_trout(void)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 1;
msg.command = ELE_ENABLE_RTC_REQ;
@@ -446,16 +458,16 @@ int ahab_release_m33_trout(void)
return ret;
}
-int ahab_get_events(u32 *events, u32 *events_cnt, u32 *response)
+int ele_get_events(u32 *events, u32 *events_cnt, u32 *response)
{
- struct udevice *dev = gd->arch.s400_dev;
- int size = sizeof(struct sentinel_msg);
- struct sentinel_msg msg;
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
int ret, i = 0;
u32 actual_events;
if (!dev) {
- printf("s400 dev is not initialized\n");
+ printf("ele dev is not initialized\n");
return -ENODEV;
}
@@ -464,8 +476,8 @@ int ahab_get_events(u32 *events, u32 *events_cnt, u32 *response)
return -EINVAL;
}
- msg.version = AHAB_VERSION;
- msg.tag = AHAB_CMD_TAG;
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
msg.size = 1;
msg.command = ELE_GET_EVENTS_REQ;
@@ -490,3 +502,122 @@ int ahab_get_events(u32 *events, u32 *events_cnt, u32 *response)
return ret;
}
+
+int ele_start_rng(void)
+{
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
+ int ret;
+
+ if (!dev) {
+ printf("ele dev is not initialized\n");
+ return -ENODEV;
+ }
+
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
+ msg.size = 1;
+ msg.command = ELE_START_RNG;
+
+ ret = misc_call(dev, false, &msg, size, &msg, size);
+ if (ret)
+ printf("Error: %s: ret %d, response 0x%x\n",
+ __func__, ret, msg.data[0]);
+
+ return ret;
+}
+
+int ele_write_secure_fuse(ulong signed_msg_blk, u32 *response)
+{
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
+ int ret;
+
+ if (!dev) {
+ printf("ele dev is not initialized\n");
+ return -ENODEV;
+ }
+
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
+ msg.size = 3;
+ msg.command = ELE_WRITE_SECURE_FUSE_REQ;
+
+ msg.data[0] = upper_32_bits(signed_msg_blk);
+ msg.data[1] = lower_32_bits(signed_msg_blk);
+
+ ret = misc_call(dev, false, &msg, size, &msg, size);
+ if (ret)
+ printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
+ __func__, ret, msg.data[0], msg.data[1]);
+
+ if (response)
+ *response = msg.data[0];
+
+ return ret;
+}
+
+int ele_return_lifecycle_update(ulong signed_msg_blk, u32 *response)
+{
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
+ int ret;
+
+ if (!dev) {
+ printf("ele dev is not initialized\n");
+ return -ENODEV;
+ }
+
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
+ msg.size = 3;
+ msg.command = ELE_RET_LIFECYCLE_UP_REQ;
+
+ msg.data[0] = upper_32_bits(signed_msg_blk);
+ msg.data[1] = lower_32_bits(signed_msg_blk);
+
+ ret = misc_call(dev, false, &msg, size, &msg, size);
+ if (ret)
+ printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
+ __func__, ret, msg.data[0], msg.data[1]);
+
+ if (response)
+ *response = msg.data[0];
+
+ return ret;
+}
+
+int ele_generate_dek_blob(u32 key_id, u32 src_paddr, u32 dst_paddr, u32 max_output_size)
+{
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg;
+ int ret;
+
+ if (!dev) {
+ printf("ele dev is not initialized\n");
+ return -ENODEV;
+ }
+
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
+ msg.size = 8;
+ msg.command = ELE_GENERATE_DEK_BLOB;
+ msg.data[0] = key_id;
+ msg.data[1] = 0x0;
+ msg.data[2] = src_paddr;
+ msg.data[3] = 0x0;
+ msg.data[4] = dst_paddr;
+ msg.data[5] = max_output_size;
+ msg.data[6] = compute_crc(&msg);
+
+ ret = misc_call(dev, false, &msg, size, &msg, size);
+ if (ret)
+ printf("Error: %s: ret 0x%x, response 0x%x\n",
+ __func__, ret, msg.data[0]);
+
+ return ret;
+}
diff --git a/drivers/misc/sentinel/s4mu.c b/drivers/misc/imx_ele/ele_mu.c
index 794fc40c620..053cdcf0fe0 100644
--- a/drivers/misc/sentinel/s4mu.c
+++ b/drivers/misc/imx_ele/ele_mu.c
@@ -9,7 +9,7 @@
#include <dm/lists.h>
#include <dm/root.h>
#include <dm/device-internal.h>
-#include <asm/mach-imx/s400_api.h>
+#include <asm/mach-imx/ele_api.h>
#include <asm/arch/imx-regs.h>
#include <linux/iopoll.h>
#include <misc.h>
@@ -22,7 +22,7 @@ struct imx8ulp_mu {
#define MU_SR_TE0_MASK BIT(0)
#define MU_SR_RF0_MASK BIT(0)
-#define MU_TR_COUNT 4
+#define MU_TR_COUNT 8
#define MU_RR_COUNT 4
void mu_hal_init(ulong base)
@@ -42,7 +42,7 @@ int mu_hal_sendmsg(ulong base, u32 reg_index, u32 msg)
assert(reg_index < MU_TR_COUNT);
- debug("sendmsg sr 0x%x\n", readl(&mu_base->sr));
+ debug("sendmsg tsr 0x%x\n", readl(&mu_base->tsr));
/* Wait TX register to be empty. */
ret = readl_poll_timeout(&mu_base->tsr, val, val & mask, 10000);
@@ -64,14 +64,24 @@ int mu_hal_receivemsg(ulong base, u32 reg_index, u32 *msg)
u32 mask = MU_SR_RF0_MASK << reg_index;
u32 val;
int ret;
+ u32 count = 10;
- assert(reg_index < MU_TR_COUNT);
+ assert(reg_index < MU_RR_COUNT);
- debug("receivemsg sr 0x%x\n", readl(&mu_base->sr));
+ debug("receivemsg rsr 0x%x\n", readl(&mu_base->rsr));
- /* Wait RX register to be full. */
- ret = readl_poll_timeout(&mu_base->rsr, val, val & mask, 10000);
- if (ret < 0) {
+ do {
+ /* Wait RX register to be full. */
+ ret = readl_poll_timeout(&mu_base->rsr, val, val & mask, 1000000);
+ if (ret < 0) {
+ count--;
+ printf("mu receive msg wait %us\n", 10 - count);
+ } else {
+ break;
+ }
+ } while (count > 0);
+
+ if (count == 0) {
debug("%s timeout\n", __func__);
return -ETIMEDOUT;
}
@@ -85,7 +95,7 @@ int mu_hal_receivemsg(ulong base, u32 reg_index, u32 *msg)
static int imx8ulp_mu_read(struct mu_type *base, void *data)
{
- struct sentinel_msg *msg = (struct sentinel_msg *)data;
+ struct ele_msg *msg = (struct ele_msg *)data;
int ret;
u8 count = 0;
@@ -99,7 +109,7 @@ static int imx8ulp_mu_read(struct mu_type *base, void *data)
count++;
/* Check size */
- if (msg->size > S400_MAX_MSG) {
+ if (msg->size > ELE_MAX_MSG) {
*((u32 *)msg) = 0;
return -EINVAL;
}
@@ -118,7 +128,7 @@ static int imx8ulp_mu_read(struct mu_type *base, void *data)
static int imx8ulp_mu_write(struct mu_type *base, void *data)
{
- struct sentinel_msg *msg = (struct sentinel_msg *)data;
+ struct ele_msg *msg = (struct ele_msg *)data;
int ret;
u8 count = 0;
@@ -126,7 +136,7 @@ static int imx8ulp_mu_write(struct mu_type *base, void *data)
return -EINVAL;
/* Check size */
- if (msg->size > S400_MAX_MSG)
+ if (msg->size > ELE_MAX_MSG)
return -EINVAL;
/* Write first word */
@@ -171,7 +181,7 @@ static int imx8ulp_mu_call(struct udevice *dev, int no_resp, void *tx_msg,
return ret;
}
- result = ((struct sentinel_msg *)rx_msg)->data[0];
+ result = ((struct ele_msg *)rx_msg)->data[0];
if ((result & 0xff) == 0xd6)
return 0;
@@ -196,7 +206,7 @@ static int imx8ulp_mu_probe(struct udevice *dev)
/* U-Boot not enable interrupts, so need to enable RX interrupts */
mu_hal_init((ulong)priv->base);
- gd->arch.s400_dev = dev;
+ gd->arch.ele_dev = dev;
return 0;
}
diff --git a/drivers/misc/sentinel/fuse.c b/drivers/misc/imx_ele/fuse.c
index 99342d33c06..4e4dcb42cdd 100644
--- a/drivers/misc/sentinel/fuse.c
+++ b/drivers/misc/imx_ele/fuse.c
@@ -10,7 +10,7 @@
#include <asm/arch/sys_proto.h>
#include <asm/arch/imx-regs.h>
#include <env.h>
-#include <asm/mach-imx/s400_api.h>
+#include <asm/mach-imx/ele_api.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -24,11 +24,11 @@ struct fsb_map_entry {
bool redundancy;
};
-struct s400_map_entry {
+struct ele_map_entry {
s32 fuse_bank;
u32 fuse_words;
u32 fuse_offset;
- u32 s400_index;
+ u32 ele_index;
};
#if defined(CONFIG_IMX8ULP)
@@ -65,7 +65,7 @@ u32 nonecc_fuse_banks[] = {
0, 1, 8, 12, 16, 22, 24, 25, 26, 27, 36, 41, 51, 56
};
-struct s400_map_entry s400_api_mapping_table[] = {
+struct ele_map_entry ele_api_mapping_table[] = {
{ 1, 8 }, /* LOCK */
{ 2, 8 }, /* ECID */
{ 7, 4, 0, 1 }, /* OTP_UNIQ_ID */
@@ -122,7 +122,7 @@ struct fsb_map_entry fsb_mapping_table[] = {
{ 63, 8 },
};
-struct s400_map_entry s400_api_mapping_table[] = {
+struct ele_map_entry ele_api_mapping_table[] = {
{ 7, 1, 7, 63 },
{ 16, 8, },
{ 17, 8, },
@@ -159,18 +159,18 @@ static s32 map_fsb_fuse_index(u32 bank, u32 word, bool *redundancy)
return word + word_pos;
}
-static s32 map_s400_fuse_index(u32 bank, u32 word)
+static s32 map_ele_fuse_index(u32 bank, u32 word)
{
- s32 size = ARRAY_SIZE(s400_api_mapping_table);
+ s32 size = ARRAY_SIZE(ele_api_mapping_table);
s32 i;
/* map the fuse from ocotp fuse map to FSB*/
for (i = 0; i < size; i++) {
- if (s400_api_mapping_table[i].fuse_bank != -1 &&
- s400_api_mapping_table[i].fuse_bank == bank) {
- if (word >= s400_api_mapping_table[i].fuse_offset &&
- word < (s400_api_mapping_table[i].fuse_offset +
- s400_api_mapping_table[i].fuse_words))
+ if (ele_api_mapping_table[i].fuse_bank != -1 &&
+ ele_api_mapping_table[i].fuse_bank == bank) {
+ if (word >= ele_api_mapping_table[i].fuse_offset &&
+ word < (ele_api_mapping_table[i].fuse_offset +
+ ele_api_mapping_table[i].fuse_words))
break;
}
}
@@ -178,10 +178,10 @@ static s32 map_s400_fuse_index(u32 bank, u32 word)
if (i == size)
return -1; /* Failed to find */
- if (s400_api_mapping_table[i].s400_index != 0)
- return s400_api_mapping_table[i].s400_index;
+ if (ele_api_mapping_table[i].ele_index != 0)
+ return ele_api_mapping_table[i].ele_index;
- return s400_api_mapping_table[i].fuse_bank * 8 + word;
+ return ele_api_mapping_table[i].fuse_bank * 8 + word;
}
#if defined(CONFIG_IMX8ULP)
@@ -202,7 +202,7 @@ int fuse_sense(u32 bank, u32 word, u32 *val)
return 0;
}
- word_index = map_s400_fuse_index(bank, word);
+ word_index = map_ele_fuse_index(bank, word);
if (word_index >= 0) {
u32 data[4];
u32 res, size = 4;
@@ -212,7 +212,7 @@ int fuse_sense(u32 bank, u32 word, u32 *val)
if (word_index != 1)
size = 1;
- ret = ahab_read_common_fuse(word_index, data, size, &res);
+ ret = ele_read_common_fuse(word_index, data, size, &res);
if (ret) {
printf("ahab read fuse failed %d, 0x%x\n", ret, res);
return ret;
@@ -255,13 +255,13 @@ int fuse_sense(u32 bank, u32 word, u32 *val)
return 0;
}
- word_index = map_s400_fuse_index(bank, word);
+ word_index = map_ele_fuse_index(bank, word);
if (word_index >= 0) {
u32 data;
u32 res, size = 1;
int ret;
- ret = ahab_read_common_fuse(word_index, &data, size, &res);
+ ret = ele_read_common_fuse(word_index, &data, size, &res);
if (ret) {
printf("ahab read fuse failed %d, 0x%x\n", ret, res);
return ret;
@@ -304,7 +304,7 @@ int fuse_prog(u32 bank, u32 word, u32 val)
lock = true;
#endif
- ret = ahab_write_fuse((bank * 8 + word), val, lock, &res);
+ ret = ele_write_fuse((bank * 8 + word), val, lock, &res);
if (ret) {
printf("ahab write fuse failed %d, 0x%x\n", ret, res);
return ret;
diff --git a/drivers/misc/npcm_host_intf.c b/drivers/misc/npcm_host_intf.c
index 0244e404570..79f57f57d89 100644
--- a/drivers/misc/npcm_host_intf.c
+++ b/drivers/misc/npcm_host_intf.c
@@ -50,9 +50,6 @@ static int npcm_host_intf_bind(struct udevice *dev)
const char *type;
int ret;
- /* Release host wait */
- setbits_8(SMC_CTL_REG_ADDR, SMC_CTL_HOSTWAIT);
-
syscon = syscon_regmap_lookup_by_phandle(dev, "syscon");
if (IS_ERR(syscon)) {
dev_err(dev, "%s: unable to get syscon, dev %s\n", __func__, dev->name);
@@ -93,6 +90,9 @@ static int npcm_host_intf_bind(struct udevice *dev)
regmap_update_bits(syscon, MFSEL1, MFSEL1_LPCSEL, MFSEL1_LPCSEL);
}
+ /* Release host wait */
+ setbits_8(SMC_CTL_REG_ADDR, SMC_CTL_HOSTWAIT);
+
return 0;
}
diff --git a/drivers/misc/npcm_otp.c b/drivers/misc/npcm_otp.c
index 304910888bb..08029724c04 100644
--- a/drivers/misc/npcm_otp.c
+++ b/drivers/misc/npcm_otp.c
@@ -33,7 +33,7 @@ static int npcm_otp_check_inputs(u32 arr, u32 word)
if (arr >= NPCM_NUM_OF_SA) {
if (IS_ENABLED(CONFIG_ARCH_NPCM8XX))
printf("\nError: npcm8XX otp includs only one bank: 0\n");
- if (IS_ENABLED(CONFIG_ARCH_NPCM7XX))
+ if (IS_ENABLED(CONFIG_ARCH_NPCM7xx))
printf("\nError: npcm7XX otp includs only two banks: 0 and 1\n");
return -1;
}
diff --git a/drivers/mtd/nand/raw/pxa3xx_nand.c b/drivers/mtd/nand/raw/pxa3xx_nand.c
index fcd1b9c6361..d502e967f92 100644
--- a/drivers/mtd/nand/raw/pxa3xx_nand.c
+++ b/drivers/mtd/nand/raw/pxa3xx_nand.c
@@ -125,6 +125,7 @@ DECLARE_GLOBAL_DATA_PTR;
/* System control register and bit to enable NAND on some SoCs */
#define GENCONF_SOC_DEVICE_MUX 0x208
#define GENCONF_SOC_DEVICE_MUX_NFC_EN BIT(0)
+#define GENCONF_SOC_DEVICE_MUX_NFC_DEVBUS_ARB_EN BIT(27)
/*
* This should be large enough to read 'ONFI' and 'JEDEC'.
@@ -167,6 +168,7 @@ enum pxa3xx_nand_variant {
PXA3XX_NAND_VARIANT_PXA,
PXA3XX_NAND_VARIANT_ARMADA370,
PXA3XX_NAND_VARIANT_ARMADA_8K,
+ PXA3XX_NAND_VARIANT_AC5,
};
struct pxa3xx_nand_host {
@@ -391,6 +393,10 @@ static const struct udevice_id pxa3xx_nand_dt_ids[] = {
.compatible = "marvell,armada-8k-nand-controller",
.data = PXA3XX_NAND_VARIANT_ARMADA_8K,
},
+ {
+ .compatible = "marvell,mvebu-ac5-pxa3xx-nand",
+ .data = PXA3XX_NAND_VARIANT_AC5,
+ },
{}
};
@@ -505,6 +511,9 @@ static int pxa3xx_nand_init_timings(struct pxa3xx_nand_host *host)
if (mode < 0)
mode = 0;
+ if (info->variant == PXA3XX_NAND_VARIANT_AC5)
+ mode = min(mode, 3);
+
timings = onfi_async_timing_mode_to_sdr_timings(mode);
if (IS_ERR(timings))
return PTR_ERR(timings);
@@ -730,7 +739,8 @@ static irqreturn_t pxa3xx_nand_irq(struct pxa3xx_nand_info *info)
/* NDCB3 register is available in NFCv2 (Armada 370/XP SoC) */
if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
- info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K)
+ info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K ||
+ info->variant == PXA3XX_NAND_VARIANT_AC5)
nand_writel(info, NDCB0, info->ndcb3);
}
@@ -1579,7 +1589,8 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
/* Device detection must be done with ECC disabled */
if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
- info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K)
+ info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K ||
+ info->variant == PXA3XX_NAND_VARIANT_AC5)
nand_writel(info, NDECCCTRL, 0x0);
if (nand_scan_ident(mtd, 1, NULL))
@@ -1630,7 +1641,8 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
*/
if (mtd->writesize > info->chunk_size) {
if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
- info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) {
+ info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K ||
+ info->variant == PXA3XX_NAND_VARIANT_AC5) {
chip->cmdfunc = nand_cmdfunc_extended;
} else {
dev_err(mtd->dev,
@@ -1728,7 +1740,7 @@ static int alloc_nand_resource(struct udevice *dev, struct pxa3xx_nand_info *inf
return PTR_ERR(sysctrl_base);
regmap_read(sysctrl_base, GENCONF_SOC_DEVICE_MUX, &reg);
- reg |= GENCONF_SOC_DEVICE_MUX_NFC_EN;
+ reg |= GENCONF_SOC_DEVICE_MUX_NFC_EN | GENCONF_SOC_DEVICE_MUX_NFC_DEVBUS_ARB_EN;
regmap_write(sysctrl_base, GENCONF_SOC_DEVICE_MUX, reg);
}
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 3f8b7967893..45872159842 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -446,6 +446,11 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
+ {
+ INFO("w25q256jwm", 0xef8019, 0, 64 * 1024, 512,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
{ INFO("w25x64", 0xef3017, 0, 64 * 1024, 128, SECT_4K) },
{
INFO("w25q64dw", 0xef6017, 0, 64 * 1024, 128,
@@ -528,8 +533,42 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("XM25QH128A", 0x207018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
#endif
#ifdef CONFIG_SPI_FLASH_XTX
- /* XTX Technology (Shenzhen) Limited */
- { INFO("xt25f128b", 0x0b4018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ /* XTX Technology Limited */
+ /* adding these 3V QSPI flash parts */
+ { INFO("xt25f08", 0x0b4014, 0, 64 * 1024, 16,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("xt25f16", 0x0b4015, 0, 64 * 1024, 32,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("xt25f32", 0x0b4016, 0, 64 * 1024, 64,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("xt25f64", 0x0b4017, 0, 64 * 1024, 128,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("xt25f128", 0x0b4018, 0, 64 * 1024, 256,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("xt25f256", 0x0b4019, 0, 64 * 1024, 512,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ /* adding these 1.8V QSPI flash parts */
+ { INFO("xt25q08", 0x0b6014, 0, 64 * 1024, 16,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("xt25q16", 0x0b6015, 0, 64 * 1024, 32,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("xt25q32", 0x0b6016, 0, 64 * 1024, 64,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("xt25q64", 0x0b6017, 0, 64 * 1024, 128,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("xt25q128", 0x0b6018, 0, 64 * 1024, 256,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("xt25q256", 0x0b6019, 0, 64 * 1024, 512,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("xt25q512", 0x0b601A, 0, 64 * 1024, 1024,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("xt25q01g", 0x0b601B, 0, 64 * 1024, 2048,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ /* adding these wide voltage QSPI flash parts */
+ { INFO("xt25w512", 0x0b651A, 0, 64 * 1024, 1024,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("xt25w01g", 0x0b651B, 0, 64 * 1024, 2048,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
#endif
{ },
};
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index d662dd34989..0ed39a61e4d 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -249,6 +249,13 @@ config DWC_ETH_QOS_QCOM
The Synopsys Designware Ethernet QOS IP block with specific
configuration used in Qcom QCS404 SoC.
+config DWC_ETH_QOS_STARFIVE
+ bool "Synopsys DWC Ethernet QOS device support for STARFIVE"
+ depends on DWC_ETH_QOS
+ help
+ The Synopsys Designware Ethernet QOS IP block with specific
+ configuration used in STARFIVE JH7110 soc.
+
config E1000
bool "Intel PRO/1000 Gigabit Ethernet support"
depends on PCI
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 46a40e2ed9f..d4af253b6f2 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_DSA_SANDBOX) += dsa_sandbox.o
obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o
obj-$(CONFIG_DWC_ETH_QOS_IMX) += dwc_eth_qos_imx.o
obj-$(CONFIG_DWC_ETH_QOS_QCOM) += dwc_eth_qos_qcom.o
+obj-$(CONFIG_DWC_ETH_QOS_STARFIVE) += dwc_eth_qos_starfive.o
obj-$(CONFIG_E1000) += e1000.o
obj-$(CONFIG_E1000_SPI) += e1000_spi.o
obj-$(CONFIG_EEPRO100) += eepro100.o
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 9bbba6eed07..1e92bd9ca9c 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1725,6 +1725,12 @@ static const struct udevice_id eqos_ids[] = {
.data = (ulong)&eqos_qcom_config
},
#endif
+#if IS_ENABLED(CONFIG_DWC_ETH_QOS_STARFIVE)
+ {
+ .compatible = "starfive,jh7110-dwmac",
+ .data = (ulong)&eqos_jh7110_config
+ },
+#endif
{ }
};
diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h
index fddbe9336c9..a6b719af809 100644
--- a/drivers/net/dwc_eth_qos.h
+++ b/drivers/net/dwc_eth_qos.h
@@ -289,3 +289,4 @@ int eqos_null_ops(struct udevice *dev);
extern struct eqos_config eqos_imx_config;
extern struct eqos_config eqos_qcom_config;
+extern struct eqos_config eqos_jh7110_config;
diff --git a/drivers/net/dwc_eth_qos_starfive.c b/drivers/net/dwc_eth_qos_starfive.c
new file mode 100644
index 00000000000..5be8ac0f1a5
--- /dev/null
+++ b/drivers/net/dwc_eth_qos_starfive.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
+ * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
+ */
+
+#include <common.h>
+#include <asm/cache.h>
+#include <asm/gpio.h>
+#include <clk.h>
+#include <dm.h>
+#include <eth_phy.h>
+#include <net.h>
+#include <regmap.h>
+#include <reset.h>
+#include <syscon.h>
+
+#include "dwc_eth_qos.h"
+
+#define STARFIVE_DWMAC_PHY_INFT_RGMII 0x1
+#define STARFIVE_DWMAC_PHY_INFT_RMII 0x4
+#define STARFIVE_DWMAC_PHY_INFT_FIELD 0x7U
+
+struct starfive_platform_data {
+ struct regmap *regmap;
+ struct reset_ctl_bulk resets;
+ struct clk_bulk clks;
+ phy_interface_t interface;
+ u32 offset;
+ u32 shift;
+ bool tx_use_rgmii_clk;
+};
+
+static int eqos_interface_init_jh7110(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct starfive_platform_data *data = pdata->priv_pdata;
+ struct ofnode_phandle_args args;
+ unsigned int mode;
+ int ret;
+
+ switch (data->interface) {
+ case PHY_INTERFACE_MODE_RMII:
+ mode = STARFIVE_DWMAC_PHY_INFT_RMII;
+ break;
+
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ mode = STARFIVE_DWMAC_PHY_INFT_RGMII;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ ret = dev_read_phandle_with_args(dev, "starfive,syscon", NULL,
+ 2, 0, &args);
+ if (ret)
+ return ret;
+
+ if (args.args_count != 2)
+ return -EINVAL;
+
+ data->offset = args.args[0];
+ data->shift = args.args[1];
+ data->regmap = syscon_regmap_lookup_by_phandle(dev, "starfive,syscon");
+ if (IS_ERR(data->regmap)) {
+ ret = PTR_ERR(data->regmap);
+ pr_err("Failed to get regmap: %d\n", ret);
+ return ret;
+ }
+
+ return regmap_update_bits(data->regmap, data->offset,
+ STARFIVE_DWMAC_PHY_INFT_FIELD << data->shift,
+ mode << data->shift);
+}
+
+static int eqos_set_tx_clk_speed_jh7110(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct starfive_platform_data *data = pdata->priv_pdata;
+ struct clk *pclk, *c;
+ ulong rate;
+ int ret;
+
+ /* Generally, the rgmii_tx clock is provided by the internal clock,
+ * which needs to match the corresponding clock frequency according
+ * to different speeds. If the rgmii_tx clock is provided by the
+ * external rgmii_rxin, there is no need to configure the clock
+ * internally, because rgmii_rxin will be adaptively adjusted.
+ */
+ if (data->tx_use_rgmii_clk)
+ return 0;
+
+ switch (eqos->phy->speed) {
+ case SPEED_1000:
+ rate = 125 * 1000 * 1000;
+ break;
+ case SPEED_100:
+ rate = 25 * 1000 * 1000;
+ break;
+ case SPEED_10:
+ rate = 2.5 * 1000 * 1000;
+ break;
+ default:
+ pr_err("invalid speed %d", eqos->phy->speed);
+ return -EINVAL;
+ }
+
+ /* eqos->clk_tx clock has no set rate operation, so just set the parent
+ * clock rate directly
+ */
+ ret = clk_get_by_id(eqos->clk_tx.id, &c);
+ if (ret)
+ return ret;
+
+ pclk = clk_get_parent(c);
+ if (pclk) {
+ ret = clk_set_rate(pclk, rate);
+ if (ret < 0) {
+ pr_err("jh7110 (clk_tx, %lu) failed: %d", rate, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static ulong eqos_get_tick_clk_rate_jh7110(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+
+ return clk_get_rate(&eqos->clk_tx);
+}
+
+static int eqos_start_clks_jh7110(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct starfive_platform_data *data = pdata->priv_pdata;
+
+ return clk_enable_bulk(&data->clks);
+}
+
+static int eqos_stop_clks_jh7110(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct starfive_platform_data *data = pdata->priv_pdata;
+
+ return clk_disable_bulk(&data->clks);
+}
+
+static int eqos_start_resets_jh7110(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct starfive_platform_data *data = pdata->priv_pdata;
+
+ return reset_deassert_bulk(&data->resets);
+}
+
+static int eqos_stop_resets_jh7110(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct starfive_platform_data *data = pdata->priv_pdata;
+
+ return reset_assert_bulk(&data->resets);
+}
+
+static int eqos_remove_resources_jh7110(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct starfive_platform_data *data = pdata->priv_pdata;
+
+ reset_assert_bulk(&data->resets);
+ clk_disable_bulk(&data->clks);
+
+ return 0;
+}
+
+static int eqos_probe_resources_jh7110(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct starfive_platform_data *data;
+ int ret;
+
+ data = calloc(1, sizeof(struct starfive_platform_data));
+ if (!data)
+ return -ENOMEM;
+
+ pdata->priv_pdata = data;
+ data->interface = eqos->config->interface(dev);
+ if (data->interface == PHY_INTERFACE_MODE_NA) {
+ pr_err("Invalid PHY interface\n");
+ return -EINVAL;
+ }
+
+ ret = reset_get_bulk(dev, &data->resets);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_get_bulk(dev, &data->clks);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_get_by_name(dev, "gtx", &eqos->clk_tx);
+ if (ret)
+ return ret;
+
+ data->tx_use_rgmii_clk = dev_read_bool(dev, "starfive,tx-use-rgmii-clk");
+
+ return eqos_interface_init_jh7110(dev);
+}
+
+static struct eqos_ops eqos_jh7110_ops = {
+ .eqos_inval_desc = eqos_inval_desc_generic,
+ .eqos_flush_desc = eqos_flush_desc_generic,
+ .eqos_inval_buffer = eqos_inval_buffer_generic,
+ .eqos_flush_buffer = eqos_flush_buffer_generic,
+ .eqos_probe_resources = eqos_probe_resources_jh7110,
+ .eqos_remove_resources = eqos_remove_resources_jh7110,
+ .eqos_stop_resets = eqos_stop_resets_jh7110,
+ .eqos_start_resets = eqos_start_resets_jh7110,
+ .eqos_stop_clks = eqos_stop_clks_jh7110,
+ .eqos_start_clks = eqos_start_clks_jh7110,
+ .eqos_calibrate_pads = eqos_null_ops,
+ .eqos_disable_calibration = eqos_null_ops,
+ .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_jh7110,
+ .eqos_get_enetaddr = eqos_null_ops,
+ .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_jh7110
+};
+
+/* mdio_wait: There is no need to wait after setting the MAC_MDIO_Address register
+ * swr_wait: Software reset bit must be read at least 4 CSR clock cycles
+ * after it is written to 1.
+ * config_mac: Enable rx queue to DCB mode.
+ * config_mac_mdio: CSR clock range is 250-300 Mhz.
+ * axi_bus_width: The width of the data bus is 64 bit.
+ */
+struct eqos_config __maybe_unused eqos_jh7110_config = {
+ .reg_access_always_ok = false,
+ .mdio_wait = 0,
+ .swr_wait = 4,
+ .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
+ .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300,
+ .axi_bus_width = EQOS_AXI_WIDTH_64,
+ .interface = dev_read_phy_mode,
+ .ops = &eqos_jh7110_ops
+};
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 24158776f52..0c3c39a5504 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -220,6 +220,12 @@ config PHY_MICREL_KSZ8XXX
endif # PHY_MICREL
+config PHY_MOTORCOMM
+ tristate "Motorcomm PHYs"
+ help
+ Enables support for Motorcomm network PHYs.
+ Currently supports the YT8531 Gigabit Ethernet PHYs.
+
config PHY_MSCC
bool "Microsemi Corp Ethernet PHYs support"
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 85d17f109cd..2487f366e1c 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_PHY_MARVELL_10G) += marvell10g.o
obj-$(CONFIG_PHY_MICREL_KSZ8XXX) += micrel_ksz8xxx.o
obj-$(CONFIG_PHY_MICREL_KSZ90X1) += micrel_ksz90x1.o
obj-$(CONFIG_PHY_MESON_GXL) += meson-gxl.o
+obj-$(CONFIG_PHY_MOTORCOMM) += motorcomm.o
obj-$(CONFIG_PHY_NATSEMI) += natsemi.o
obj-$(CONFIG_PHY_NXP_C45_TJA11XX) += nxp-c45-tja11xx.o
obj-$(CONFIG_PHY_NXP_TJA11XX) += nxp-tja11xx.o
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
new file mode 100644
index 00000000000..e822fd76f27
--- /dev/null
+++ b/drivers/net/phy/motorcomm.c
@@ -0,0 +1,437 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Motorcomm 8531 PHY driver.
+ *
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <phy.h>
+#include <linux/bitfield.h>
+
+#define PHY_ID_YT8531 0x4f51e91b
+#define PHY_ID_MASK GENMASK(31, 0)
+
+/* Extended Register's Address Offset Register */
+#define YTPHY_PAGE_SELECT 0x1E
+
+/* Extended Register's Data Register */
+#define YTPHY_PAGE_DATA 0x1F
+
+#define YTPHY_SYNCE_CFG_REG 0xA012
+
+#define YTPHY_DTS_OUTPUT_CLK_DIS 0
+#define YTPHY_DTS_OUTPUT_CLK_25M 25000000
+#define YTPHY_DTS_OUTPUT_CLK_125M 125000000
+
+#define YT8531_SCR_SYNCE_ENABLE BIT(6)
+/* 1b0 output 25m clock *default*
+ * 1b1 output 125m clock
+ */
+#define YT8531_SCR_CLK_FRE_SEL_125M BIT(4)
+#define YT8531_SCR_CLK_SRC_MASK GENMASK(3, 1)
+#define YT8531_SCR_CLK_SRC_PLL_125M 0
+#define YT8531_SCR_CLK_SRC_UTP_RX 1
+#define YT8531_SCR_CLK_SRC_SDS_RX 2
+#define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3
+#define YT8531_SCR_CLK_SRC_REF_25M 4
+#define YT8531_SCR_CLK_SRC_SSC_25M 5
+
+/* 1b0 use original tx_clk_rgmii *default*
+ * 1b1 use inverted tx_clk_rgmii.
+ */
+#define YT8531_RC1R_TX_CLK_SEL_INVERTED BIT(14)
+#define YT8531_RC1R_RX_DELAY_MASK GENMASK(13, 10)
+#define YT8531_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4)
+#define YT8531_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0)
+#define YT8531_RC1R_RGMII_0_000_NS 0
+#define YT8531_RC1R_RGMII_0_150_NS 1
+#define YT8531_RC1R_RGMII_0_300_NS 2
+#define YT8531_RC1R_RGMII_0_450_NS 3
+#define YT8531_RC1R_RGMII_0_600_NS 4
+#define YT8531_RC1R_RGMII_0_750_NS 5
+#define YT8531_RC1R_RGMII_0_900_NS 6
+#define YT8531_RC1R_RGMII_1_050_NS 7
+#define YT8531_RC1R_RGMII_1_200_NS 8
+#define YT8531_RC1R_RGMII_1_350_NS 9
+#define YT8531_RC1R_RGMII_1_500_NS 10
+#define YT8531_RC1R_RGMII_1_650_NS 11
+#define YT8531_RC1R_RGMII_1_800_NS 12
+#define YT8531_RC1R_RGMII_1_950_NS 13
+#define YT8531_RC1R_RGMII_2_100_NS 14
+#define YT8531_RC1R_RGMII_2_250_NS 15
+
+/* Phy gmii clock gating Register */
+#define YT8531_CLOCK_GATING_REG 0xC
+#define YT8531_CGR_RX_CLK_EN BIT(12)
+
+/* Specific Status Register */
+#define YTPHY_SPECIFIC_STATUS_REG 0x11
+#define YTPHY_DUPLEX_MASK BIT(13)
+#define YTPHY_DUPLEX_SHIFT 13
+#define YTPHY_SPEED_MODE_MASK GENMASK(15, 14)
+#define YTPHY_SPEED_MODE_SHIFT 14
+
+#define YT8531_EXTREG_SLEEP_CONTROL1_REG 0x27
+#define YT8531_ESC1R_SLEEP_SW BIT(15)
+#define YT8531_ESC1R_PLLON_SLP BIT(14)
+
+#define YT8531_RGMII_CONFIG1_REG 0xA003
+
+#define YT8531_CHIP_CONFIG_REG 0xA001
+#define YT8531_CCR_SW_RST BIT(15)
+/* 1b0 disable 1.9ns rxc clock delay *default*
+ * 1b1 enable 1.9ns rxc clock delay
+ */
+#define YT8531_CCR_RXC_DLY_EN BIT(8)
+#define YT8531_CCR_RXC_DLY_1_900_NS 1900
+
+/* bits in struct ytphy_plat_priv->flag */
+#define TX_CLK_ADJ_ENABLED BIT(0)
+#define AUTO_SLEEP_DISABLED BIT(1)
+#define KEEP_PLL_ENABLED BIT(2)
+#define TX_CLK_10_INVERTED BIT(3)
+#define TX_CLK_100_INVERTED BIT(4)
+#define TX_CLK_1000_INVERTED BIT(5)
+
+struct ytphy_plat_priv {
+ u32 rx_delay_ps;
+ u32 tx_delay_ps;
+ u32 clk_out_frequency;
+ u32 flag;
+};
+
+/**
+ * struct ytphy_cfg_reg_map - map a config value to a register value
+ * @cfg: value in device configuration
+ * @reg: value in the register
+ */
+struct ytphy_cfg_reg_map {
+ u32 cfg;
+ u32 reg;
+};
+
+static const struct ytphy_cfg_reg_map ytphy_rgmii_delays[] = {
+ /* for tx delay / rx delay with YT8531_CCR_RXC_DLY_EN is not set. */
+ { 0, YT8531_RC1R_RGMII_0_000_NS },
+ { 150, YT8531_RC1R_RGMII_0_150_NS },
+ { 300, YT8531_RC1R_RGMII_0_300_NS },
+ { 450, YT8531_RC1R_RGMII_0_450_NS },
+ { 600, YT8531_RC1R_RGMII_0_600_NS },
+ { 750, YT8531_RC1R_RGMII_0_750_NS },
+ { 900, YT8531_RC1R_RGMII_0_900_NS },
+ { 1050, YT8531_RC1R_RGMII_1_050_NS },
+ { 1200, YT8531_RC1R_RGMII_1_200_NS },
+ { 1350, YT8531_RC1R_RGMII_1_350_NS },
+ { 1500, YT8531_RC1R_RGMII_1_500_NS },
+ { 1650, YT8531_RC1R_RGMII_1_650_NS },
+ { 1800, YT8531_RC1R_RGMII_1_800_NS },
+ { 1950, YT8531_RC1R_RGMII_1_950_NS }, /* default tx/rx delay */
+ { 2100, YT8531_RC1R_RGMII_2_100_NS },
+ { 2250, YT8531_RC1R_RGMII_2_250_NS },
+
+ /* only for rx delay with YT8531_CCR_RXC_DLY_EN is set. */
+ { 0 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_000_NS },
+ { 150 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_150_NS },
+ { 300 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_300_NS },
+ { 450 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_450_NS },
+ { 600 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_600_NS },
+ { 750 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_750_NS },
+ { 900 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_0_900_NS },
+ { 1050 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_050_NS },
+ { 1200 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_200_NS },
+ { 1350 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_350_NS },
+ { 1500 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_500_NS },
+ { 1650 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_650_NS },
+ { 1800 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_800_NS },
+ { 1950 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_1_950_NS },
+ { 2100 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_2_100_NS },
+ { 2250 + YT8531_CCR_RXC_DLY_1_900_NS, YT8531_RC1R_RGMII_2_250_NS }
+};
+
+static u32 ytphy_get_delay_reg_value(struct phy_device *phydev,
+ u32 val,
+ u16 *rxc_dly_en)
+{
+ int tb_size = ARRAY_SIZE(ytphy_rgmii_delays);
+ int tb_size_half = tb_size / 2;
+ int i;
+
+ /* when rxc_dly_en is NULL, it is get the delay for tx, only half of
+ * tb_size is valid.
+ */
+ if (!rxc_dly_en)
+ tb_size = tb_size_half;
+
+ for (i = 0; i < tb_size; i++) {
+ if (ytphy_rgmii_delays[i].cfg == val) {
+ if (rxc_dly_en && i < tb_size_half)
+ *rxc_dly_en = 0;
+ return ytphy_rgmii_delays[i].reg;
+ }
+ }
+
+ pr_warn("Unsupported value %d, using default (%u)\n",
+ val, YT8531_RC1R_RGMII_1_950_NS);
+
+ /* when rxc_dly_en is not NULL, it is get the delay for rx.
+ * The rx default in dts and ytphy_rgmii_clk_delay_config is 1950 ps,
+ * so YT8531_CCR_RXC_DLY_EN should not be set.
+ */
+ if (rxc_dly_en)
+ *rxc_dly_en = 0;
+
+ return YT8531_RC1R_RGMII_1_950_NS;
+}
+
+static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask,
+ u16 set)
+{
+ int ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_SELECT, regnum);
+ if (ret < 0)
+ return ret;
+
+ return phy_modify(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA, mask, set);
+}
+
+static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
+{
+ struct ytphy_plat_priv *priv = phydev->priv;
+ u16 rxc_dly_en = YT8531_CCR_RXC_DLY_EN;
+ u32 rx_reg, tx_reg;
+ u16 mask, val = 0;
+ int ret;
+
+ rx_reg = ytphy_get_delay_reg_value(phydev, priv->rx_delay_ps,
+ &rxc_dly_en);
+ tx_reg = ytphy_get_delay_reg_value(phydev, priv->tx_delay_ps,
+ NULL);
+
+ switch (phydev->interface) {
+ case PHY_INTERFACE_MODE_RGMII:
+ rxc_dly_en = 0;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ val |= FIELD_PREP(YT8531_RC1R_RX_DELAY_MASK, rx_reg);
+ break;
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ rxc_dly_en = 0;
+ val |= FIELD_PREP(YT8531_RC1R_GE_TX_DELAY_MASK, tx_reg);
+ break;
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ val |= FIELD_PREP(YT8531_RC1R_RX_DELAY_MASK, rx_reg) |
+ FIELD_PREP(YT8531_RC1R_GE_TX_DELAY_MASK, tx_reg);
+ break;
+ default: /* do not support other modes */
+ return -EOPNOTSUPP;
+ }
+
+ ret = ytphy_modify_ext(phydev, YT8531_CHIP_CONFIG_REG,
+ YT8531_CCR_RXC_DLY_EN, rxc_dly_en);
+ if (ret < 0)
+ return ret;
+
+ /* Generally, it is not necessary to adjust YT8531_RC1R_FE_TX_DELAY */
+ mask = YT8531_RC1R_RX_DELAY_MASK | YT8531_RC1R_GE_TX_DELAY_MASK;
+ return ytphy_modify_ext(phydev, YT8531_RGMII_CONFIG1_REG, mask, val);
+}
+
+static int yt8531_parse_status(struct phy_device *phydev)
+{
+ int val;
+ int speed, speed_mode;
+
+ val = phy_read(phydev, MDIO_DEVAD_NONE, YTPHY_SPECIFIC_STATUS_REG);
+ if (val < 0)
+ return val;
+
+ speed_mode = (val & YTPHY_SPEED_MODE_MASK) >> YTPHY_SPEED_MODE_SHIFT;
+ switch (speed_mode) {
+ case 2:
+ speed = SPEED_1000;
+ break;
+ case 1:
+ speed = SPEED_100;
+ break;
+ default:
+ speed = SPEED_10;
+ break;
+ }
+
+ phydev->speed = speed;
+ phydev->duplex = (val & YTPHY_DUPLEX_MASK) >> YTPHY_DUPLEX_SHIFT;
+
+ return 0;
+}
+
+static int yt8531_startup(struct phy_device *phydev)
+{
+ struct ytphy_plat_priv *priv = phydev->priv;
+ u16 val = 0;
+ int ret;
+
+ ret = genphy_update_link(phydev);
+ if (ret)
+ return ret;
+
+ ret = yt8531_parse_status(phydev);
+ if (ret)
+ return ret;
+
+ if (phydev->speed < 0)
+ return -EINVAL;
+
+ if (!(priv->flag & TX_CLK_ADJ_ENABLED))
+ return 0;
+
+ switch (phydev->speed) {
+ case SPEED_1000:
+ if (priv->flag & TX_CLK_1000_INVERTED)
+ val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
+ break;
+ case SPEED_100:
+ if (priv->flag & TX_CLK_100_INVERTED)
+ val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
+ break;
+ case SPEED_10:
+ if (priv->flag & TX_CLK_10_INVERTED)
+ val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
+ break;
+ default:
+ printf("UNKNOWN SPEED\n");
+ return -EINVAL;
+ }
+
+ ret = ytphy_modify_ext(phydev, YT8531_RGMII_CONFIG1_REG,
+ YT8531_RC1R_TX_CLK_SEL_INVERTED, val);
+ if (ret < 0)
+ pr_warn("Modify TX_CLK_SEL err:%d\n", ret);
+
+ return 0;
+}
+
+static void ytphy_dt_parse(struct phy_device *phydev)
+{
+ struct ytphy_plat_priv *priv = phydev->priv;
+
+ priv->clk_out_frequency = ofnode_read_u32_default(phydev->node,
+ "motorcomm,clk-out-frequency-hz",
+ YTPHY_DTS_OUTPUT_CLK_DIS);
+ priv->rx_delay_ps = ofnode_read_u32_default(phydev->node,
+ "rx-internal-delay-ps",
+ YT8531_RC1R_RGMII_1_950_NS);
+ priv->tx_delay_ps = ofnode_read_u32_default(phydev->node,
+ "tx-internal-delay-ps",
+ YT8531_RC1R_RGMII_1_950_NS);
+
+ if (ofnode_read_bool(phydev->node, "motorcomm,auto-sleep-disabled"))
+ priv->flag |= AUTO_SLEEP_DISABLED;
+
+ if (ofnode_read_bool(phydev->node, "motorcomm,keep-pll-enabled"))
+ priv->flag |= KEEP_PLL_ENABLED;
+
+ if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-adj-enabled"))
+ priv->flag |= TX_CLK_ADJ_ENABLED;
+
+ if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-10-inverted"))
+ priv->flag |= TX_CLK_10_INVERTED;
+
+ if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-100-inverted"))
+ priv->flag |= TX_CLK_100_INVERTED;
+
+ if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-1000-inverted"))
+ priv->flag |= TX_CLK_1000_INVERTED;
+}
+
+static int yt8531_config(struct phy_device *phydev)
+{
+ struct ytphy_plat_priv *priv = phydev->priv;
+ u16 mask, val;
+ int ret;
+
+ ret = genphy_config_aneg(phydev);
+ if (ret < 0)
+ return ret;
+
+ ytphy_dt_parse(phydev);
+ switch (priv->clk_out_frequency) {
+ case YTPHY_DTS_OUTPUT_CLK_DIS:
+ mask = YT8531_SCR_SYNCE_ENABLE;
+ val = 0;
+ break;
+ case YTPHY_DTS_OUTPUT_CLK_25M:
+ mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
+ YT8531_SCR_CLK_FRE_SEL_125M;
+ val = YT8531_SCR_SYNCE_ENABLE |
+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
+ YT8531_SCR_CLK_SRC_REF_25M);
+ break;
+ case YTPHY_DTS_OUTPUT_CLK_125M:
+ mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
+ YT8531_SCR_CLK_FRE_SEL_125M;
+ val = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_FRE_SEL_125M |
+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
+ YT8531_SCR_CLK_SRC_PLL_125M);
+ break;
+ default:
+ pr_warn("Freq err:%u\n", priv->clk_out_frequency);
+ return -EINVAL;
+ }
+
+ ret = ytphy_modify_ext(phydev, YTPHY_SYNCE_CFG_REG, mask,
+ val);
+ if (ret < 0)
+ return ret;
+
+ ret = ytphy_rgmii_clk_delay_config(phydev);
+ if (ret < 0)
+ return ret;
+
+ if (priv->flag & AUTO_SLEEP_DISABLED) {
+ /* disable auto sleep */
+ ret = ytphy_modify_ext(phydev,
+ YT8531_EXTREG_SLEEP_CONTROL1_REG,
+ YT8531_ESC1R_SLEEP_SW, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (priv->flag & KEEP_PLL_ENABLED) {
+ /* enable RXC clock when no wire plug */
+ ret = ytphy_modify_ext(phydev,
+ YT8531_CLOCK_GATING_REG,
+ YT8531_CGR_RX_CLK_EN, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int yt8531_probe(struct phy_device *phydev)
+{
+ struct ytphy_plat_priv *priv;
+
+ priv = calloc(1, sizeof(struct ytphy_plat_priv));
+ if (!priv)
+ return -ENOMEM;
+
+ phydev->priv = priv;
+
+ return 0;
+}
+
+U_BOOT_PHY_DRIVER(motorcomm8531) = {
+ .name = "YT8531 Gigabit Ethernet",
+ .uid = PHY_ID_YT8531,
+ .mask = PHY_ID_MASK,
+ .features = PHY_GBIT_FEATURES,
+ .probe = &yt8531_probe,
+ .config = &yt8531_config,
+ .startup = &yt8531_startup,
+ .shutdown = &genphy_shutdown,
+};
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index f674b0baa35..523a4c9f919 100644
--- a/drivers/net/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ti/am65-cpsw-nuss.c
@@ -223,6 +223,8 @@ out:
return phy->link;
}
+#define AM65_GMII_SEL_PORT_OFFS(x) (0x4 * ((x) - 1))
+
#define AM65_GMII_SEL_MODE_MII 0
#define AM65_GMII_SEL_MODE_RMII 1
#define AM65_GMII_SEL_MODE_RGMII 2
@@ -233,11 +235,12 @@ static void am65_cpsw_gmii_sel_k3(struct am65_cpsw_priv *priv,
phy_interface_t phy_mode, int slave)
{
struct am65_cpsw_common *common = priv->cpsw_common;
+ fdt_addr_t gmii_sel = common->gmii_sel + AM65_GMII_SEL_PORT_OFFS(slave);
u32 reg;
u32 mode = 0;
bool rgmii_id = false;
- reg = readl(common->gmii_sel);
+ reg = readl(gmii_sel);
dev_dbg(common->dev, "old gmii_sel: %08x\n", reg);
@@ -273,9 +276,9 @@ static void am65_cpsw_gmii_sel_k3(struct am65_cpsw_priv *priv,
reg = mode;
dev_dbg(common->dev, "gmii_sel PHY mode: %u, new gmii_sel: %08x\n",
phy_mode, reg);
- writel(reg, common->gmii_sel);
+ writel(reg, gmii_sel);
- reg = readl(common->gmii_sel);
+ reg = readl(gmii_sel);
if (reg != mode)
dev_err(common->dev,
"gmii_sel PHY mode NOT SET!: requested: %08x, gmii_sel: %08x\n",
diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c
index f18be08518e..7976e3b3ed5 100644
--- a/drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c
+++ b/drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c
@@ -808,6 +808,9 @@ static bool is_gpio_persist(struct udevice *dev, uint bank)
status = npcm_get_reset_status();
dev_dbg(dev, "reset status: 0x%x\n", status);
+ if (status & PORST)
+ return false;
+
if (status & CORST)
regmap_read(priv->rst_regmap, CORSTC, &val);
else if (status & WD0RST)
diff --git a/drivers/power/domain/imx8-power-domain-legacy.c b/drivers/power/domain/imx8-power-domain-legacy.c
index 37b0f95abac..c8ca2665752 100644
--- a/drivers/power/domain/imx8-power-domain-legacy.c
+++ b/drivers/power/domain/imx8-power-domain-legacy.c
@@ -89,7 +89,6 @@ static int imx8_power_domain_on(struct power_domain *power_domain)
struct udevice *dev = power_domain->dev;
struct imx8_power_domain_plat *pdata;
struct imx8_power_domain_priv *ppriv;
- sc_err_t ret;
int err;
struct power_domain parent_domain;
@@ -117,11 +116,11 @@ static int imx8_power_domain_on(struct power_domain *power_domain)
if (!sc_rm_is_resource_owned(-1, pdata->resource_id))
printf("%s [%d] not owned by curr partition\n", dev->name, pdata->resource_id);
- ret = sc_pm_set_resource_power_mode(-1, pdata->resource_id,
+ err = sc_pm_set_resource_power_mode(-1, pdata->resource_id,
SC_PM_PW_MODE_ON);
- if (ret) {
+ if (err) {
printf("Error: %s Power up failed! (error = %d)\n",
- dev->name, ret);
+ dev->name, err);
return -EIO;
}
}
@@ -139,7 +138,7 @@ static int imx8_power_domain_off_node(struct power_domain *power_domain)
struct imx8_power_domain_priv *ppriv;
struct imx8_power_domain_priv *child_ppriv;
struct imx8_power_domain_plat *pdata;
- sc_err_t ret;
+ int ret;
ppriv = dev_get_priv(dev);
pdata = dev_get_plat(dev);
diff --git a/drivers/power/domain/imx8m-power-domain.c b/drivers/power/domain/imx8m-power-domain.c
index 145f6ec0cd3..df5d7d69562 100644
--- a/drivers/power/domain/imx8m-power-domain.c
+++ b/drivers/power/domain/imx8m-power-domain.c
@@ -338,6 +338,9 @@ static int imx8m_power_domain_on(struct power_domain *power_domain)
}
}
+ /* delay for reset to propagate */
+ udelay(5);
+
if (domain->bits.pxx) {
/* request the domain to power up */
setbits_le32(base + regs->pup, domain->bits.pxx);
diff --git a/drivers/ram/starfive/starfive_ddr.c b/drivers/ram/starfive/starfive_ddr.c
index 553f2ce6f44..a0a3d6b33dc 100644
--- a/drivers/ram/starfive/starfive_ddr.c
+++ b/drivers/ram/starfive/starfive_ddr.c
@@ -72,8 +72,6 @@ static int starfive_ddr_probe(struct udevice *dev)
u64 rate;
int ret;
- /* Read memory base and size from DT */
- fdtdec_setup_mem_size_base();
priv->info.base = gd->ram_base;
priv->info.size = gd->ram_size;
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index f5468353e10..428a4d210de 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -291,8 +291,16 @@ int pl01x_serial_probe(struct udevice *dev)
struct pl01x_serial_plat *plat = dev_get_plat(dev);
struct pl01x_priv *priv = dev_get_priv(dev);
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_serial_pl01x *dtplat = &plat->dtplat;
+
+ priv->regs = (struct pl01x_regs *)dtplat->reg[0];
+ plat->type = dtplat->type;
+#else
priv->regs = (struct pl01x_regs *)plat->base;
+#endif
priv->type = plat->type;
+
if (!plat->skip_init)
return pl01x_generic_serial_init(priv->regs, priv->type);
else
@@ -321,7 +329,7 @@ int pl01x_serial_pending(struct udevice *dev, bool input)
if (input)
return pl01x_tstc(priv->regs);
else
- return fr & UART_PL01x_FR_TXFF ? 0 : 1;
+ return fr & UART_PL01x_FR_TXFE ? 0 : 1;
}
static const struct dm_serial_ops pl01x_serial_ops = {
@@ -331,7 +339,7 @@ static const struct dm_serial_ops pl01x_serial_ops = {
.setbrg = pl01x_serial_setbrg,
};
-#if CONFIG_IS_ENABLED(OF_CONTROL)
+#if CONFIG_IS_ENABLED(OF_REAL)
static const struct udevice_id pl01x_serial_id[] ={
{.compatible = "arm,pl011", .data = TYPE_PL011},
{.compatible = "arm,pl010", .data = TYPE_PL010},
@@ -380,8 +388,10 @@ int pl01x_serial_of_to_plat(struct udevice *dev)
U_BOOT_DRIVER(serial_pl01x) = {
.name = "serial_pl01x",
.id = UCLASS_SERIAL,
+#if CONFIG_IS_ENABLED(OF_REAL)
.of_match = of_match_ptr(pl01x_serial_id),
.of_to_plat = of_match_ptr(pl01x_serial_of_to_plat),
+#endif
.plat_auto = sizeof(struct pl01x_serial_plat),
.probe = pl01x_serial_probe,
.ops = &pl01x_serial_ops,
@@ -389,6 +399,8 @@ U_BOOT_DRIVER(serial_pl01x) = {
.priv_auto = sizeof(struct pl01x_priv),
};
+DM_DRIVER_ALIAS(serial_pl01x, arm_pl011)
+DM_DRIVER_ALIAS(serial_pl01x, arm_pl010)
#endif
#if defined(CONFIG_DEBUG_UART_PL010) || defined(CONFIG_DEBUG_UART_PL011)
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 453a5983b2a..854b8b88daf 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -101,12 +101,21 @@ config ATMEL_SPI
config BCM63XX_HSSPI
bool "BCM63XX HSSPI driver"
- depends on (ARCH_BMIPS || BCM6856 || BCM6858 || BCM63158)
+ depends on (ARCH_BMIPS || ARCH_BCMBCA)
help
- Enable the BCM6328 HSSPI driver. This driver can be used to
+ Enable the BCM63XX HSSPI driver. This driver can be used to
access the SPI NOR flash on platforms embedding this Broadcom
SPI core.
+config BCMBCA_HSSPI
+ bool "BCMBCA HSSPI driver"
+ depends on ARCH_BCMBCA && HAVE_SPI_CS_CTRL
+ help
+ This enables support for the High Speed SPI controller present on
+ newer Broadcom BCMBCA SoCs. These SoCs include an updated SPI controller
+ that adds the capability to allow the driver to control chip select
+ explicitly.
+
config BCM63XX_SPI
bool "BCM6348 SPI driver"
depends on ARCH_BMIPS
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 95dba9ac455..c27b3327c33 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_ATH79_SPI) += ath79_spi.o
obj-$(CONFIG_ATMEL_QSPI) += atmel-quadspi.o
obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o
obj-$(CONFIG_BCM63XX_HSSPI) += bcm63xx_hsspi.o
+obj-$(CONFIG_BCMBCA_HSSPI) += bcmbca_hsspi.o
obj-$(CONFIG_BCM63XX_SPI) += bcm63xx_spi.o
obj-$(CONFIG_BCMSTB_SPI) += bcmstb_spi.o
obj-$(CONFIG_CF_SPI) += cf_spi.o
diff --git a/drivers/spi/bcm63xx_hsspi.c b/drivers/spi/bcm63xx_hsspi.c
index 4d714adc4af..a24bb430cbb 100644
--- a/drivers/spi/bcm63xx_hsspi.c
+++ b/drivers/spi/bcm63xx_hsspi.c
@@ -20,7 +20,13 @@
#define HSSPI_PP 0
-#define SPI_MAX_SYNC_CLOCK 30000000
+/*
+ * The maximum frequency for SPI synchronous mode is 30MHz for some chips and
+ * 25MHz for some others. This depends on the chip layout and SPI signals
+ * distance to the pad. We use the lower of these values to cover all relevant
+ * chips.
+ */
+#define SPI_MAX_SYNC_CLOCK 25000000
/* SPI Control register */
#define SPI_CTL_REG 0x000
@@ -72,12 +78,16 @@
#define SPI_PFL_MODE_REG(x) (0x100 + (0x20 * (x)) + 0x08)
#define SPI_PFL_MODE_FILL_SHIFT 0
#define SPI_PFL_MODE_FILL_MASK (0xff << SPI_PFL_MODE_FILL_SHIFT)
+#define SPI_PFL_MODE_MDRDST_SHIFT 8
+#define SPI_PFL_MODE_MDWRST_SHIFT 12
#define SPI_PFL_MODE_MDRDSZ_SHIFT 16
#define SPI_PFL_MODE_MDRDSZ_MASK (1 << SPI_PFL_MODE_MDRDSZ_SHIFT)
#define SPI_PFL_MODE_MDWRSZ_SHIFT 18
#define SPI_PFL_MODE_MDWRSZ_MASK (1 << SPI_PFL_MODE_MDWRSZ_SHIFT)
#define SPI_PFL_MODE_3WIRE_SHIFT 20
#define SPI_PFL_MODE_3WIRE_MASK (1 << SPI_PFL_MODE_3WIRE_SHIFT)
+#define SPI_PFL_MODE_PREPCNT_SHIFT 24
+#define SPI_PFL_MODE_PREPCNT_MASK (4 << SPI_PFL_MODE_PREPCNT_SHIFT)
/* SPI Ping-Pong FIFO registers */
#define HSSPI_FIFO_SIZE 0x200
@@ -96,12 +106,21 @@
#define HSSPI_FIFO_OP_CODE_W (2 << HSSPI_FIFO_OP_CODE_SHIFT)
#define HSSPI_FIFO_OP_CODE_R (3 << HSSPI_FIFO_OP_CODE_SHIFT)
+#define HSSPI_MAX_DATA_SIZE (HSSPI_FIFO_SIZE - HSSPI_FIFO_OP_SIZE)
+#define HSSPI_MAX_PREPEND_SIZE 15
+
+#define HSSPI_XFER_MODE_PREPEND 0
+#define HSSPI_XFER_MODE_DUMMYCS 1
+
struct bcm63xx_hsspi_priv {
void __iomem *regs;
ulong clk_rate;
uint8_t num_cs;
uint8_t cs_pols;
uint speed;
+ uint xfer_mode;
+ uint32_t prepend_cnt;
+ uint8_t prepend_buf[HSSPI_MAX_PREPEND_SIZE];
};
static int bcm63xx_hsspi_cs_info(struct udevice *bus, uint cs,
@@ -143,9 +162,16 @@ static void bcm63xx_hsspi_activate_cs(struct bcm63xx_hsspi_priv *priv,
struct dm_spi_slave_plat *plat)
{
uint32_t clr, set;
+ uint speed = priv->speed;
+
+ if (priv->xfer_mode == HSSPI_XFER_MODE_DUMMYCS &&
+ speed > SPI_MAX_SYNC_CLOCK) {
+ speed = SPI_MAX_SYNC_CLOCK;
+ debug("Force to dummy cs mode. Reduce the speed to %dHz\n", speed);
+ }
/* profile clock */
- set = DIV_ROUND_UP(priv->clk_rate, priv->speed);
+ set = DIV_ROUND_UP(priv->clk_rate, speed);
set = DIV_ROUND_UP(2048, set);
set &= SPI_PFL_CLK_FREQ_MASK;
set |= SPI_PFL_CLK_RSTLOOP_MASK;
@@ -164,7 +190,7 @@ static void bcm63xx_hsspi_activate_cs(struct bcm63xx_hsspi_priv *priv,
set |= SPI_PFL_SIG_LATCHRIS_MASK;
/* async clk */
- if (priv->speed > SPI_MAX_SYNC_CLOCK)
+ if (speed > SPI_MAX_SYNC_CLOCK)
set |= SPI_PFL_SIG_ASYNCIN_MASK;
clrsetbits_32(priv->regs + SPI_PFL_SIG_REG(plat->cs), clr, set);
@@ -173,17 +199,24 @@ static void bcm63xx_hsspi_activate_cs(struct bcm63xx_hsspi_priv *priv,
set = 0;
clr = 0;
- /* invert cs polarity */
- if (priv->cs_pols & BIT(plat->cs))
- clr |= BIT(plat->cs);
- else
- set |= BIT(plat->cs);
-
- /* invert dummy cs polarity */
- if (priv->cs_pols & BIT(!plat->cs))
- clr |= BIT(!plat->cs);
- else
- set |= BIT(!plat->cs);
+ if (priv->xfer_mode == HSSPI_XFER_MODE_PREPEND) {
+ if (priv->cs_pols & BIT(plat->cs))
+ set |= BIT(plat->cs);
+ else
+ clr |= BIT(plat->cs);
+ } else {
+ /* invert cs polarity */
+ if (priv->cs_pols & BIT(plat->cs))
+ clr |= BIT(plat->cs);
+ else
+ set |= BIT(plat->cs);
+
+ /* invert dummy cs polarity */
+ if (priv->cs_pols & BIT(!plat->cs))
+ clr |= BIT(!plat->cs);
+ else
+ set |= BIT(!plat->cs);
+ }
clrsetbits_32(priv->regs + SPI_CTL_REG, clr, set);
}
@@ -212,16 +245,21 @@ static void bcm63xx_hsspi_deactivate_cs(struct bcm63xx_hsspi_priv *priv)
* all the time. This hack is also used in the upstream linux driver and
* allows keeping CS active between transfers even if the HW doesn't give
* this possibility.
+ *
+ * This workaround only works when the dummy CS (usually CS1 when the actual
+ * CS is 0) pinmuxed to SPI chip select function if SPI clock is faster than
+ * SPI_MAX_SYNC_CLOCK. In old broadcom chip, CS1 pin is default to chip select
+ * function. But this is not the case for new chips. To make this function
+ * always work, it should be called with maximum clock of SPI_MAX_SYNC_CLOCK.
*/
-static int bcm63xx_hsspi_xfer(struct udevice *dev, unsigned int bitlen,
- const void *dout, void *din, unsigned long flags)
+static int bcm63xx_hsspi_xfer_dummy_cs(struct udevice *dev, unsigned int data_bytes,
+ const void *dout, void *din, unsigned long flags)
{
struct bcm63xx_hsspi_priv *priv = dev_get_priv(dev->parent);
struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev);
- size_t data_bytes = bitlen / 8;
size_t step_size = HSSPI_FIFO_SIZE;
uint16_t opcode = 0;
- uint32_t val;
+ uint32_t val = SPI_PFL_MODE_FILL_MASK;
const uint8_t *tx = dout;
uint8_t *rx = din;
@@ -240,14 +278,17 @@ static int bcm63xx_hsspi_xfer(struct udevice *dev, unsigned int bitlen,
step_size -= HSSPI_FIFO_OP_SIZE;
/* dual mode */
- if ((opcode == HSSPI_FIFO_OP_CODE_R && plat->mode == SPI_RX_DUAL) ||
- (opcode == HSSPI_FIFO_OP_CODE_W && plat->mode == SPI_TX_DUAL))
+ if ((opcode == HSSPI_FIFO_OP_CODE_R && (plat->mode & SPI_RX_DUAL)) ||
+ (opcode == HSSPI_FIFO_OP_CODE_W && (plat->mode & SPI_TX_DUAL))) {
opcode |= HSSPI_FIFO_OP_MBIT_MASK;
- /* profile mode */
- val = SPI_PFL_MODE_FILL_MASK |
- SPI_PFL_MODE_MDRDSZ_MASK |
- SPI_PFL_MODE_MDWRSZ_MASK;
+ /* profile mode */
+ if (plat->mode & SPI_RX_DUAL)
+ val |= SPI_PFL_MODE_MDRDSZ_MASK;
+ if (plat->mode & SPI_TX_DUAL)
+ val |= SPI_PFL_MODE_MDWRSZ_MASK;
+ }
+
if (plat->mode & SPI_3WIRE)
val |= SPI_PFL_MODE_3WIRE_MASK;
writel(val, priv->regs + SPI_PFL_MODE_REG(plat->cs));
@@ -301,6 +342,182 @@ static int bcm63xx_hsspi_xfer(struct udevice *dev, unsigned int bitlen,
return 0;
}
+static int bcm63xx_prepare_prepend_transfer(struct bcm63xx_hsspi_priv *priv,
+ unsigned int data_bytes, const void *dout, void *din,
+ unsigned long flags)
+{
+ /*
+ * only support multiple half duplex write transfer + optional
+ * full duplex read/write at the end.
+ */
+ if (flags & SPI_XFER_BEGIN) {
+ /* clear prepends */
+ priv->prepend_cnt = 0;
+ }
+
+ if (din) {
+ /* buffering reads not possible for prepend mode */
+ if (!(flags & SPI_XFER_END)) {
+ debug("unable to buffer reads\n");
+ return HSSPI_XFER_MODE_DUMMYCS;
+ }
+
+ /* check rx size */
+ if (data_bytes > HSSPI_MAX_DATA_SIZE) {
+ debug("max rx bytes exceeded\n");
+ return HSSPI_XFER_MODE_DUMMYCS;
+ }
+ }
+
+ if (dout) {
+ /* check tx size */
+ if (flags & SPI_XFER_END) {
+ if (priv->prepend_cnt + data_bytes > HSSPI_MAX_DATA_SIZE) {
+ debug("max tx bytes exceeded\n");
+ return HSSPI_XFER_MODE_DUMMYCS;
+ }
+ } else {
+ if (priv->prepend_cnt + data_bytes > HSSPI_MAX_PREPEND_SIZE) {
+ debug("max prepend bytes exceeded\n");
+ return HSSPI_XFER_MODE_DUMMYCS;
+ }
+
+ /*
+ * buffer transfer data in the prepend buf in case we have to fall
+ * back to dummy cs mode.
+ */
+ memcpy(&priv->prepend_buf[priv->prepend_cnt], dout, data_bytes);
+ priv->prepend_cnt += data_bytes;
+ }
+ }
+
+ return HSSPI_XFER_MODE_PREPEND;
+}
+
+static int bcm63xx_hsspi_xfer_prepend(struct udevice *dev, unsigned int data_bytes,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct bcm63xx_hsspi_priv *priv = dev_get_priv(dev->parent);
+ struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev);
+ uint16_t opcode = 0;
+ uint32_t val, offset;
+ int ret;
+
+ if (flags & SPI_XFER_END) {
+ offset = HSSPI_FIFO_BASE + HSSPI_FIFO_OP_SIZE;
+ if (priv->prepend_cnt) {
+ /* copy prepend data */
+ memcpy_toio(priv->regs + offset,
+ priv->prepend_buf, priv->prepend_cnt);
+ }
+
+ if (dout && data_bytes) {
+ /* copy tx data */
+ offset += priv->prepend_cnt;
+ memcpy_toio(priv->regs + offset, dout, data_bytes);
+ }
+
+ bcm63xx_hsspi_activate_cs(priv, plat);
+ if (dout && !din) {
+ /* all half-duplex write. merge to single write */
+ data_bytes += priv->prepend_cnt;
+ opcode = HSSPI_FIFO_OP_CODE_W;
+ priv->prepend_cnt = 0;
+ } else if (!dout && din) {
+ /* half-duplex read with prepend write */
+ opcode = HSSPI_FIFO_OP_CODE_R;
+ } else {
+ /* full duplex read/write */
+ opcode = HSSPI_FIFO_OP_READ_WRITE;
+ }
+
+ /* profile mode */
+ val = SPI_PFL_MODE_FILL_MASK;
+ if (plat->mode & SPI_3WIRE)
+ val |= SPI_PFL_MODE_3WIRE_MASK;
+
+ /* dual mode */
+ if ((opcode == HSSPI_FIFO_OP_CODE_R && (plat->mode & SPI_RX_DUAL)) ||
+ (opcode == HSSPI_FIFO_OP_CODE_W && (plat->mode & SPI_TX_DUAL))) {
+ opcode |= HSSPI_FIFO_OP_MBIT_MASK;
+
+ if (plat->mode & SPI_RX_DUAL) {
+ val |= SPI_PFL_MODE_MDRDSZ_MASK;
+ val |= priv->prepend_cnt << SPI_PFL_MODE_MDRDST_SHIFT;
+ }
+ if (plat->mode & SPI_TX_DUAL) {
+ val |= SPI_PFL_MODE_MDWRSZ_MASK;
+ val |= priv->prepend_cnt << SPI_PFL_MODE_MDWRST_SHIFT;
+ }
+ }
+ val |= (priv->prepend_cnt << SPI_PFL_MODE_PREPCNT_SHIFT);
+ writel(val, priv->regs + SPI_PFL_MODE_REG(plat->cs));
+
+ /* set fifo operation */
+ val = opcode | (data_bytes & HSSPI_FIFO_OP_BYTES_MASK);
+ writew(cpu_to_be16(val),
+ priv->regs + HSSPI_FIFO_OP_REG);
+
+ /* issue the transfer */
+ val = SPI_CMD_OP_START;
+ val |= (plat->cs << SPI_CMD_PFL_SHIFT) &
+ SPI_CMD_PFL_MASK;
+ val |= (plat->cs << SPI_CMD_SLAVE_SHIFT) &
+ SPI_CMD_SLAVE_MASK;
+ writel(val, priv->regs + SPI_CMD_REG);
+
+ /* wait for completion */
+ ret = wait_for_bit_32(priv->regs + SPI_STAT_REG,
+ SPI_STAT_SRCBUSY_MASK, false,
+ 1000, false);
+ if (ret) {
+ bcm63xx_hsspi_deactivate_cs(priv);
+ printf("spi polling timeout\n");
+ return ret;
+ }
+
+ /* copy rx data */
+ if (din)
+ memcpy_fromio(din, priv->regs + HSSPI_FIFO_BASE,
+ data_bytes);
+ bcm63xx_hsspi_deactivate_cs(priv);
+ }
+
+ return 0;
+}
+
+static int bcm63xx_hsspi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct bcm63xx_hsspi_priv *priv = dev_get_priv(dev->parent);
+ int ret;
+ u32 data_bytes = bitlen >> 3;
+
+ if (priv->xfer_mode == HSSPI_XFER_MODE_PREPEND) {
+ priv->xfer_mode =
+ bcm63xx_prepare_prepend_transfer(priv, data_bytes, dout, din, flags);
+ }
+
+ /* if not prependable, fall back to dummy cs mode with safe clock */
+ if (priv->xfer_mode == HSSPI_XFER_MODE_DUMMYCS) {
+ /* For pending prepend data from previous transfers, send it first */
+ if (priv->prepend_cnt) {
+ bcm63xx_hsspi_xfer_dummy_cs(dev, priv->prepend_cnt,
+ priv->prepend_buf, NULL,
+ (flags & ~SPI_XFER_END) | SPI_XFER_BEGIN);
+ priv->prepend_cnt = 0;
+ }
+ ret = bcm63xx_hsspi_xfer_dummy_cs(dev, data_bytes, dout, din, flags);
+ } else {
+ ret = bcm63xx_hsspi_xfer_prepend(dev, data_bytes, dout, din, flags);
+ }
+
+ if (flags & SPI_XFER_END)
+ priv->xfer_mode = HSSPI_XFER_MODE_PREPEND;
+
+ return ret;
+}
+
static const struct dm_spi_ops bcm63xx_hsspi_ops = {
.cs_info = bcm63xx_hsspi_cs_info,
.set_mode = bcm63xx_hsspi_set_mode,
@@ -310,6 +527,7 @@ static const struct dm_spi_ops bcm63xx_hsspi_ops = {
static const struct udevice_id bcm63xx_hsspi_ids[] = {
{ .compatible = "brcm,bcm6328-hsspi", },
+ { .compatible = "brcm,bcmbca-hsspi-v1.0", },
{ /* sentinel */ }
};
@@ -317,6 +535,7 @@ static int bcm63xx_hsspi_child_pre_probe(struct udevice *dev)
{
struct bcm63xx_hsspi_priv *priv = dev_get_priv(dev->parent);
struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev);
+ struct spi_slave *slave = dev_get_parent_priv(dev);
/* check cs */
if (plat->cs >= priv->num_cs) {
@@ -330,6 +549,13 @@ static int bcm63xx_hsspi_child_pre_probe(struct udevice *dev)
else
priv->cs_pols &= ~BIT(plat->cs);
+ /*
+ * set the max read/write size to make sure each xfer are within the
+ * prepend limit
+ */
+ slave->max_read_size = HSSPI_MAX_DATA_SIZE;
+ slave->max_write_size = HSSPI_MAX_DATA_SIZE;
+
return 0;
}
@@ -391,6 +617,9 @@ static int bcm63xx_hsspi_probe(struct udevice *dev)
priv->cs_pols = readl(priv->regs + SPI_CTL_REG) &
SPI_CTL_CS_POL_MASK;
+ /* default in prepend mode */
+ priv->xfer_mode = HSSPI_XFER_MODE_PREPEND;
+
return 0;
}
diff --git a/drivers/spi/bcmbca_hsspi.c b/drivers/spi/bcmbca_hsspi.c
new file mode 100644
index 00000000000..fbe315a7d45
--- /dev/null
+++ b/drivers/spi/bcmbca_hsspi.c
@@ -0,0 +1,414 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017 Ɓlvaro FernƔndez Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/spi/spi-bcm63xx-hsspi.c:
+ * Copyright (C) 2000-2010 Broadcom Corporation
+ * Copyright (C) 2012-2013 Jonas Gorski <jogo@openwrt.org>
+ * Copyright (C) 2021 Broadcom Ltd
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <clk.h>
+#include <spi.h>
+#include <reset.h>
+#include <wait_bit.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+
+#define HSSPI_PP 0
+
+#define SPI_MAX_SYNC_CLOCK 30000000
+
+/* SPI Control register */
+#define SPI_CTL_REG 0x000
+#define SPI_CTL_CS_POL_SHIFT 0
+#define SPI_CTL_CS_POL_MASK (0xff << SPI_CTL_CS_POL_SHIFT)
+#define SPI_CTL_CLK_GATE_SHIFT 16
+#define SPI_CTL_CLK_GATE_MASK BIT(SPI_CTL_CLK_GATE_SHIFT)
+#define SPI_CTL_CLK_POL_SHIFT 17
+#define SPI_CTL_CLK_POL_MASK BIT(SPI_CTL_CLK_POL_SHIFT)
+
+/* SPI Interrupts registers */
+#define SPI_IR_STAT_REG 0x008
+#define SPI_IR_ST_MASK_REG 0x00c
+#define SPI_IR_MASK_REG 0x010
+
+#define SPI_IR_CLEAR_ALL 0xff001f1f
+
+/* SPI Ping-Pong Command registers */
+#define SPI_CMD_REG (0x080 + (0x40 * (HSSPI_PP)) + 0x00)
+#define SPI_CMD_OP_SHIFT 0
+#define SPI_CMD_OP_START BIT(SPI_CMD_OP_SHIFT)
+#define SPI_CMD_PFL_SHIFT 8
+#define SPI_CMD_PFL_MASK (0x7 << SPI_CMD_PFL_SHIFT)
+#define SPI_CMD_SLAVE_SHIFT 12
+#define SPI_CMD_SLAVE_MASK (0x7 << SPI_CMD_SLAVE_SHIFT)
+
+/* SPI Ping-Pong Status registers */
+#define SPI_STAT_REG (0x080 + (0x40 * (HSSPI_PP)) + 0x04)
+#define SPI_STAT_SRCBUSY_SHIFT 1
+#define SPI_STAT_SRCBUSY_MASK BIT(SPI_STAT_SRCBUSY_SHIFT)
+
+/* SPI Profile Clock registers */
+#define SPI_PFL_CLK_REG(x) (0x100 + (0x20 * (x)) + 0x00)
+#define SPI_PFL_CLK_FREQ_SHIFT 0
+#define SPI_PFL_CLK_FREQ_MASK (0x3fff << SPI_PFL_CLK_FREQ_SHIFT)
+#define SPI_PFL_CLK_RSTLOOP_SHIFT 15
+#define SPI_PFL_CLK_RSTLOOP_MASK BIT(SPI_PFL_CLK_RSTLOOP_SHIFT)
+
+/* SPI Profile Signal registers */
+#define SPI_PFL_SIG_REG(x) (0x100 + (0x20 * (x)) + 0x04)
+#define SPI_PFL_SIG_LATCHRIS_SHIFT 12
+#define SPI_PFL_SIG_LATCHRIS_MASK BIT(SPI_PFL_SIG_LATCHRIS_SHIFT)
+#define SPI_PFL_SIG_LAUNCHRIS_SHIFT 13
+#define SPI_PFL_SIG_LAUNCHRIS_MASK BIT(SPI_PFL_SIG_LAUNCHRIS_SHIFT)
+#define SPI_PFL_SIG_ASYNCIN_SHIFT 16
+#define SPI_PFL_SIG_ASYNCIN_MASK BIT(SPI_PFL_SIG_ASYNCIN_SHIFT)
+
+/* SPI Profile Mode registers */
+#define SPI_PFL_MODE_REG(x) (0x100 + (0x20 * (x)) + 0x08)
+#define SPI_PFL_MODE_FILL_SHIFT 0
+#define SPI_PFL_MODE_FILL_MASK (0xff << SPI_PFL_MODE_FILL_SHIFT)
+#define SPI_PFL_MODE_MDRDSZ_SHIFT 16
+#define SPI_PFL_MODE_MDRDSZ_MASK BIT(SPI_PFL_MODE_MDRDSZ_SHIFT)
+#define SPI_PFL_MODE_MDWRSZ_SHIFT 18
+#define SPI_PFL_MODE_MDWRSZ_MASK BIT(SPI_PFL_MODE_MDWRSZ_SHIFT)
+#define SPI_PFL_MODE_3WIRE_SHIFT 20
+#define SPI_PFL_MODE_3WIRE_MASK BIT(SPI_PFL_MODE_3WIRE_SHIFT)
+
+/* SPI Ping-Pong FIFO registers */
+#define HSSPI_FIFO_SIZE 0x200
+#define HSSPI_FIFO_BASE (0x200 + \
+ (HSSPI_FIFO_SIZE * HSSPI_PP))
+
+/* SPI Ping-Pong FIFO OP register */
+#define HSSPI_FIFO_OP_SIZE 0x2
+#define HSSPI_FIFO_OP_REG (HSSPI_FIFO_BASE + 0x00)
+#define HSSPI_FIFO_OP_BYTES_SHIFT 0
+#define HSSPI_FIFO_OP_BYTES_MASK (0x3ff << HSSPI_FIFO_OP_BYTES_SHIFT)
+#define HSSPI_FIFO_OP_MBIT_SHIFT 11
+#define HSSPI_FIFO_OP_MBIT_MASK BIT(HSSPI_FIFO_OP_MBIT_SHIFT)
+#define HSSPI_FIFO_OP_CODE_SHIFT 13
+#define HSSPI_FIFO_OP_READ_WRITE (1 << HSSPI_FIFO_OP_CODE_SHIFT)
+#define HSSPI_FIFO_OP_CODE_W (2 << HSSPI_FIFO_OP_CODE_SHIFT)
+#define HSSPI_FIFO_OP_CODE_R (3 << HSSPI_FIFO_OP_CODE_SHIFT)
+
+#define HSSPI_MAX_DATA_SIZE (HSSPI_FIFO_SIZE - HSSPI_FIFO_OP_SIZE)
+
+#define SPIM_CTRL_CS_OVERRIDE_SEL_SHIFT 0
+#define SPIM_CTRL_CS_OVERRIDE_SEL_MASK 0xff
+#define SPIM_CTRL_CS_OVERRIDE_VAL_SHIFT 8
+#define SPIM_CTRL_CS_OVERRIDE_VAL_MASK 0xff
+
+struct bcmbca_hsspi_priv {
+ void __iomem *regs;
+ void __iomem *spim_ctrl;
+ u32 clk_rate;
+ u8 num_cs;
+ u8 cs_pols;
+ u32 speed;
+};
+
+static int bcmbca_hsspi_cs_info(struct udevice *bus, uint cs,
+ struct spi_cs_info *info)
+{
+ struct bcmbca_hsspi_priv *priv = dev_get_priv(bus);
+
+ if (cs >= priv->num_cs) {
+ dev_err(bus, "no cs %u\n", cs);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int bcmbca_hsspi_set_mode(struct udevice *bus, uint mode)
+{
+ struct bcmbca_hsspi_priv *priv = dev_get_priv(bus);
+
+ /* clock polarity */
+ if (mode & SPI_CPOL)
+ setbits_32(priv->regs + SPI_CTL_REG, SPI_CTL_CLK_POL_MASK);
+ else
+ clrbits_32(priv->regs + SPI_CTL_REG, SPI_CTL_CLK_POL_MASK);
+
+ return 0;
+}
+
+static int bcmbca_hsspi_set_speed(struct udevice *bus, uint speed)
+{
+ struct bcmbca_hsspi_priv *priv = dev_get_priv(bus);
+
+ priv->speed = speed;
+
+ return 0;
+}
+
+static void bcmbca_hsspi_setup_clock(struct bcmbca_hsspi_priv *priv,
+ struct dm_spi_slave_plat *plat)
+{
+ u32 clr, set;
+
+ /* profile clock */
+ set = DIV_ROUND_UP(priv->clk_rate, priv->speed);
+ set = DIV_ROUND_UP(2048, set);
+ set &= SPI_PFL_CLK_FREQ_MASK;
+ set |= SPI_PFL_CLK_RSTLOOP_MASK;
+ writel(set, priv->regs + SPI_PFL_CLK_REG(plat->cs));
+
+ /* profile signal */
+ set = 0;
+ clr = SPI_PFL_SIG_LAUNCHRIS_MASK |
+ SPI_PFL_SIG_LATCHRIS_MASK |
+ SPI_PFL_SIG_ASYNCIN_MASK;
+
+ /* latch/launch config */
+ if (plat->mode & SPI_CPHA)
+ set |= SPI_PFL_SIG_LAUNCHRIS_MASK;
+ else
+ set |= SPI_PFL_SIG_LATCHRIS_MASK;
+
+ /* async clk */
+ if (priv->speed > SPI_MAX_SYNC_CLOCK)
+ set |= SPI_PFL_SIG_ASYNCIN_MASK;
+
+ clrsetbits_32(priv->regs + SPI_PFL_SIG_REG(plat->cs), clr, set);
+
+ /* global control */
+ set = 0;
+ clr = 0;
+
+ if (priv->cs_pols & BIT(plat->cs))
+ set |= BIT(plat->cs);
+ else
+ clr |= BIT(plat->cs);
+
+ clrsetbits_32(priv->regs + SPI_CTL_REG, clr, set);
+}
+
+static void bcmbca_hsspi_activate_cs(struct bcmbca_hsspi_priv *priv,
+ struct dm_spi_slave_plat *plat)
+{
+ u32 val;
+
+ /* set the override bit */
+ val = readl(priv->spim_ctrl);
+ val |= BIT(plat->cs + SPIM_CTRL_CS_OVERRIDE_SEL_SHIFT);
+ writel(val, priv->spim_ctrl);
+}
+
+static void bcmbca_hsspi_deactivate_cs(struct bcmbca_hsspi_priv *priv,
+ struct dm_spi_slave_plat *plat)
+{
+ u32 val;
+
+ /* clear the cs override bit */
+ val = readl(priv->spim_ctrl);
+ val &= ~BIT(plat->cs + SPIM_CTRL_CS_OVERRIDE_SEL_SHIFT);
+ writel(val, priv->spim_ctrl);
+}
+
+static int bcmbca_hsspi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct bcmbca_hsspi_priv *priv = dev_get_priv(dev->parent);
+ struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev);
+ size_t data_bytes = bitlen / 8;
+ size_t step_size = HSSPI_FIFO_SIZE;
+ u16 opcode = 0;
+ u32 val = SPI_PFL_MODE_FILL_MASK;
+ const u8 *tx = dout;
+ u8 *rx = din;
+ u32 cs_act = 0;
+
+ if (flags & SPI_XFER_BEGIN)
+ bcmbca_hsspi_setup_clock(priv, plat);
+
+ /* fifo operation */
+ if (tx && rx)
+ opcode = HSSPI_FIFO_OP_READ_WRITE;
+ else if (rx)
+ opcode = HSSPI_FIFO_OP_CODE_R;
+ else if (tx)
+ opcode = HSSPI_FIFO_OP_CODE_W;
+
+ if (opcode != HSSPI_FIFO_OP_CODE_R)
+ step_size -= HSSPI_FIFO_OP_SIZE;
+
+ /* dual mode */
+ if ((opcode == HSSPI_FIFO_OP_CODE_R && (plat->mode & SPI_RX_DUAL)) ||
+ (opcode == HSSPI_FIFO_OP_CODE_W && (plat->mode & SPI_TX_DUAL))) {
+ opcode |= HSSPI_FIFO_OP_MBIT_MASK;
+
+ /* profile mode */
+ if (plat->mode & SPI_RX_DUAL)
+ val |= SPI_PFL_MODE_MDRDSZ_MASK;
+ if (plat->mode & SPI_TX_DUAL)
+ val |= SPI_PFL_MODE_MDWRSZ_MASK;
+ }
+
+ if (plat->mode & SPI_3WIRE)
+ val |= SPI_PFL_MODE_3WIRE_MASK;
+ writel(val, priv->regs + SPI_PFL_MODE_REG(plat->cs));
+
+ /* transfer loop */
+ while (data_bytes > 0) {
+ size_t curr_step = min(step_size, data_bytes);
+ int ret;
+
+ /* copy tx data */
+ if (tx) {
+ memcpy_toio(priv->regs + HSSPI_FIFO_BASE +
+ HSSPI_FIFO_OP_SIZE, tx, curr_step);
+ tx += curr_step;
+ }
+
+ /* set fifo operation */
+ writew(cpu_to_be16(opcode | (curr_step & HSSPI_FIFO_OP_BYTES_MASK)),
+ priv->regs + HSSPI_FIFO_OP_REG);
+
+ /* make sure we keep cs active until spi transfer is done */
+ if (!cs_act) {
+ bcmbca_hsspi_activate_cs(priv, plat);
+ cs_act = 1;
+ }
+
+ /* issue the transfer */
+ val = SPI_CMD_OP_START;
+ val |= (plat->cs << SPI_CMD_PFL_SHIFT) &
+ SPI_CMD_PFL_MASK;
+ val |= (plat->cs << SPI_CMD_SLAVE_SHIFT) &
+ SPI_CMD_SLAVE_MASK;
+ writel(val, priv->regs + SPI_CMD_REG);
+
+ /* wait for completion */
+ ret = wait_for_bit_32(priv->regs + SPI_STAT_REG,
+ SPI_STAT_SRCBUSY_MASK, false,
+ 1000, false);
+ if (ret) {
+ bcmbca_hsspi_deactivate_cs(priv, plat);
+ dev_err(dev, "interrupt timeout\n");
+ return ret;
+ }
+
+ data_bytes -= curr_step;
+ if ((flags & SPI_XFER_END) && !data_bytes)
+ bcmbca_hsspi_deactivate_cs(priv, plat);
+
+ /* copy rx data */
+ if (rx) {
+ memcpy_fromio(rx, priv->regs + HSSPI_FIFO_BASE,
+ curr_step);
+ rx += curr_step;
+ }
+ }
+
+ return 0;
+}
+
+static const struct dm_spi_ops bcmbca_hsspi_ops = {
+ .cs_info = bcmbca_hsspi_cs_info,
+ .set_mode = bcmbca_hsspi_set_mode,
+ .set_speed = bcmbca_hsspi_set_speed,
+ .xfer = bcmbca_hsspi_xfer,
+};
+
+static const struct udevice_id bcmbca_hsspi_ids[] = {
+ { .compatible = "brcm,bcmbca-hsspi-v1.1", },
+ { /* sentinel */ }
+};
+
+static int bcmbca_hsspi_child_pre_probe(struct udevice *dev)
+{
+ struct bcmbca_hsspi_priv *priv = dev_get_priv(dev->parent);
+ struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev);
+ u32 val;
+
+ /* check cs */
+ if (plat->cs >= priv->num_cs) {
+ dev_err(dev, "no cs %u\n", plat->cs);
+ return -EINVAL;
+ }
+
+ /* cs polarity */
+ if (plat->mode & SPI_CS_HIGH)
+ priv->cs_pols |= BIT(plat->cs);
+ else
+ priv->cs_pols &= ~BIT(plat->cs);
+
+ /* set the polarity to spim cs register */
+ val = readl(priv->spim_ctrl);
+ val &= ~BIT(plat->cs + SPIM_CTRL_CS_OVERRIDE_VAL_SHIFT);
+ if (priv->cs_pols & BIT(plat->cs))
+ val |= BIT(plat->cs + SPIM_CTRL_CS_OVERRIDE_VAL_SHIFT);
+ writel(val, priv->spim_ctrl);
+
+ return 0;
+}
+
+static int bcmbca_hsspi_probe(struct udevice *dev)
+{
+ struct bcmbca_hsspi_priv *priv = dev_get_priv(dev);
+ struct clk clk;
+ int ret;
+
+ priv->regs = dev_remap_addr_name(dev, "hsspi");
+ if (!priv->regs)
+ return -EINVAL;
+
+ priv->spim_ctrl = dev_remap_addr_name(dev, "spim-ctrl");
+ if (!priv->spim_ctrl) {
+ dev_err(dev, "misc spim ctrl register not defined in dts!\n");
+ return -EINVAL;
+ }
+
+ priv->num_cs = dev_read_u32_default(dev, "num-cs", 8);
+
+ /* enable clock */
+ ret = clk_get_by_name(dev, "hsspi", &clk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_enable(&clk);
+ if (ret < 0 && ret != -ENOSYS)
+ return ret;
+
+ clk_free(&clk);
+
+ /* get clock rate */
+ ret = clk_get_by_name(dev, "pll", &clk);
+ if (ret < 0 && ret != -ENOSYS)
+ return ret;
+
+ priv->clk_rate = clk_get_rate(&clk);
+
+ clk_free(&clk);
+
+ /* initialize hardware */
+ writel(0, priv->regs + SPI_IR_MASK_REG);
+
+ /* clear pending interrupts */
+ writel(SPI_IR_CLEAR_ALL, priv->regs + SPI_IR_STAT_REG);
+
+ /* enable clk gate */
+ setbits_32(priv->regs + SPI_CTL_REG, SPI_CTL_CLK_GATE_MASK);
+
+ /* read default cs polarities */
+ priv->cs_pols = readl(priv->regs + SPI_CTL_REG) &
+ SPI_CTL_CS_POL_MASK;
+
+ dev_info(dev, "Broadcom BCMBCA HS SPI bus driver\n");
+ return 0;
+}
+
+U_BOOT_DRIVER(bcmbca_hsspi) = {
+ .name = "bcmbca_hsspi",
+ .id = UCLASS_SPI,
+ .of_match = bcmbca_hsspi_ids,
+ .ops = &bcmbca_hsspi_ops,
+ .priv_auto = sizeof(struct bcmbca_hsspi_priv),
+ .child_pre_probe = bcmbca_hsspi_child_pre_probe,
+ .probe = bcmbca_hsspi_probe,
+};
diff --git a/drivers/spi/npcm_pspi.c b/drivers/spi/npcm_pspi.c
index bd9ac654113..37bab709672 100644
--- a/drivers/spi/npcm_pspi.c
+++ b/drivers/spi/npcm_pspi.c
@@ -40,7 +40,7 @@ static inline void spi_cs_activate(struct udevice *dev)
struct udevice *bus = dev->parent;
struct npcm_pspi_priv *priv = dev_get_priv(bus);
- dm_gpio_set_value(&priv->cs_gpio, 0);
+ dm_gpio_set_value(&priv->cs_gpio, 1);
}
static inline void spi_cs_deactivate(struct udevice *dev)
@@ -48,7 +48,7 @@ static inline void spi_cs_deactivate(struct udevice *dev)
struct udevice *bus = dev->parent;
struct npcm_pspi_priv *priv = dev_get_priv(bus);
- dm_gpio_set_value(&priv->cs_gpio, 1);
+ dm_gpio_set_value(&priv->cs_gpio, 0);
}
static inline void npcm_pspi_enable(struct npcm_pspi_priv *priv)
@@ -122,6 +122,9 @@ static int npcm_pspi_xfer(struct udevice *dev, unsigned int bitlen,
if (flags & SPI_XFER_END)
spi_cs_deactivate(dev);
+ debug("npcm_pspi_xfer: slave %s:%s dout %08X din %08X bitlen %u\n",
+ dev->parent->name, dev->name, *(uint *)tx, *(uint *)rx, bitlen);
+
npcm_pspi_disable(priv);
return ret;
@@ -183,6 +186,7 @@ static int npcm_pspi_set_mode(struct udevice *bus, uint mode)
val |= pspi_mode;
writew(val, priv->base + PSPI_CTL1);
+ debug("%s: mode=%u\n", __func__, mode);
return 0;
}
@@ -197,9 +201,9 @@ static int npcm_pspi_probe(struct udevice *bus)
return ret;
priv->base = dev_read_addr_ptr(bus);
- priv->max_hz = dev_read_u32_default(bus, "spi-max-frequency", 0);
+ priv->max_hz = dev_read_u32_default(bus, "spi-max-frequency", 1000000);
gpio_request_by_name_nodev(offset_to_ofnode(node), "cs-gpios", 0,
- &priv->cs_gpio, GPIOD_IS_OUT);
+ &priv->cs_gpio, GPIOD_IS_OUT| GPIOD_ACTIVE_LOW);
return 0;
}
diff --git a/drivers/spi/pl022_spi.c b/drivers/spi/pl022_spi.c
index 828eab3d342..fc7388b379d 100644
--- a/drivers/spi/pl022_spi.c
+++ b/drivers/spi/pl022_spi.c
@@ -12,9 +12,11 @@
#include <clk.h>
#include <common.h>
#include <dm.h>
-#include <dm/platform_data/spi_pl022.h>
+#include <dm/device_compat.h>
+#include <fdtdec.h>
#include <linux/io.h>
#include <asm/global_data.h>
+#include <asm/gpio.h>
#include <spi.h>
#define SSP_CR0 0x000
@@ -66,6 +68,15 @@
#define SSP_SR_MASK_RFF (0x1 << 3) /* Receive FIFO full */
#define SSP_SR_MASK_BSY (0x1 << 4) /* Busy Flag */
+struct pl022_spi_pdata {
+ fdt_addr_t addr;
+ fdt_size_t size;
+ unsigned int freq;
+#if CONFIG_IS_ENABLED(DM_GPIO)
+ struct gpio_desc cs_gpio;
+#endif
+};
+
struct pl022_spi_slave {
void *base;
unsigned int freq;
@@ -107,7 +118,7 @@ static int pl022_spi_probe(struct udevice *bus)
return 0;
}
-static void flush(struct pl022_spi_slave *ps)
+static void pl022_spi_flush(struct pl022_spi_slave *ps)
{
do {
while (readw(ps->base + SSP_SR) & SSP_SR_MASK_RNE)
@@ -126,7 +137,7 @@ static int pl022_spi_claim_bus(struct udevice *dev)
reg |= SSP_CR1_MASK_SSE;
writew(reg, ps->base + SSP_CR1);
- flush(ps);
+ pl022_spi_flush(ps);
return 0;
}
@@ -137,7 +148,7 @@ static int pl022_spi_release_bus(struct udevice *dev)
struct pl022_spi_slave *ps = dev_get_priv(bus);
u16 reg;
- flush(ps);
+ pl022_spi_flush(ps);
/* Disable the SPI hardware */
reg = readw(ps->base + SSP_CR1);
@@ -147,6 +158,17 @@ static int pl022_spi_release_bus(struct udevice *dev)
return 0;
}
+static void pl022_spi_set_cs(struct udevice *dev, bool on)
+{
+#if CONFIG_IS_ENABLED(DM_GPIO)
+ struct udevice *bus = dev->parent;
+ struct pl022_spi_pdata *plat = dev_get_plat(bus);
+
+ if (dm_gpio_is_valid(&plat->cs_gpio))
+ dm_gpio_set_value(&plat->cs_gpio, on ? 1 : 0);
+#endif
+}
+
static int pl022_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
@@ -159,7 +181,7 @@ static int pl022_spi_xfer(struct udevice *dev, unsigned int bitlen,
if (bitlen == 0)
/* Finish any previously submitted transfers */
- return 0;
+ goto done;
/*
* TODO: The controller can do non-multiple-of-8 bit
@@ -172,9 +194,13 @@ static int pl022_spi_xfer(struct udevice *dev, unsigned int bitlen,
if (bitlen % 8) {
/* Errors always terminate an ongoing transfer */
flags |= SPI_XFER_END;
- return -1;
+ ret = -1;
+ goto done;
}
+ if (flags & SPI_XFER_BEGIN)
+ pl022_spi_set_cs(dev, true);
+
len = bitlen / 8;
while (len_tx < len) {
@@ -201,6 +227,10 @@ static int pl022_spi_xfer(struct udevice *dev, unsigned int bitlen,
}
}
+done:
+ if (flags & SPI_XFER_END)
+ pl022_spi_set_cs(dev, false);
+
return ret;
}
@@ -303,11 +333,18 @@ static int pl022_spi_of_to_plat(struct udevice *bus)
plat->freq = clk_get_rate(&clkdev);
+#if CONFIG_IS_ENABLED(DM_GPIO)
+ ret = gpio_request_by_name(bus, "cs-gpios", 0, &plat->cs_gpio,
+ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+ if (ret < 0 && ret != -ENOENT)
+ return ret;
+#endif
+
return 0;
}
static const struct udevice_id pl022_spi_ids[] = {
- { .compatible = "arm,pl022-spi" },
+ { .compatible = "arm,pl022" },
{ }
};
#endif
diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c
index f3602a25ba3..0fa14339bdc 100644
--- a/drivers/spi/soft_spi.c
+++ b/drivers/spi/soft_spi.c
@@ -248,20 +248,33 @@ static int soft_spi_probe(struct udevice *dev)
cs_flags = (slave && slave->mode & SPI_CS_HIGH) ? 0 : GPIOD_ACTIVE_LOW;
clk_flags = (slave && slave->mode & SPI_CPOL) ? GPIOD_ACTIVE_LOW : 0;
- if (gpio_request_by_name(dev, "cs-gpios", 0, &plat->cs,
- GPIOD_IS_OUT | cs_flags) ||
- gpio_request_by_name(dev, "gpio-sck", 0, &plat->sclk,
- GPIOD_IS_OUT | clk_flags))
+ ret = gpio_request_by_name(dev, "cs-gpios", 0, &plat->cs,
+ GPIOD_IS_OUT | cs_flags);
+ if (ret)
+ return -EINVAL;
+
+ ret = gpio_request_by_name(dev, "gpio-sck", 0, &plat->sclk,
+ GPIOD_IS_OUT | clk_flags);
+ if (ret)
+ ret = gpio_request_by_name(dev, "sck-gpios", 0, &plat->sclk,
+ GPIOD_IS_OUT | clk_flags);
+ if (ret)
return -EINVAL;
ret = gpio_request_by_name(dev, "gpio-mosi", 0, &plat->mosi,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
if (ret)
+ ret = gpio_request_by_name(dev, "mosi-gpios", 0, &plat->mosi,
+ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+ if (ret)
plat->flags |= SPI_MASTER_NO_TX;
ret = gpio_request_by_name(dev, "gpio-miso", 0, &plat->miso,
GPIOD_IS_IN);
if (ret)
+ ret = gpio_request_by_name(dev, "gpio-miso", 0, &plat->miso,
+ GPIOD_IS_IN);
+ if (ret)
plat->flags |= SPI_MASTER_NO_RX;
if ((plat->flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_TX)) ==
diff --git a/drivers/spi/spi-synquacer.c b/drivers/spi/spi-synquacer.c
index 0f5d0a30c39..553f9687e3b 100644
--- a/drivers/spi/spi-synquacer.c
+++ b/drivers/spi/spi-synquacer.c
@@ -186,7 +186,7 @@ static void synquacer_spi_config(struct udevice *dev, void *rx, const void *tx)
struct udevice *bus = dev->parent;
struct synquacer_spi_priv *priv = dev_get_priv(bus);
struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
- u32 val, div, bus_width = 1;
+ u32 val, div, bus_width;
int rwflag;
rwflag = (rx ? 1 : 0) | (tx ? 2 : 0);
@@ -203,16 +203,14 @@ static void synquacer_spi_config(struct udevice *dev, void *rx, const void *tx)
priv->mode = slave_plat->mode;
priv->speed = slave_plat->max_hz;
- if (priv->mode & SPI_TX_BYTE)
- bus_width = 1;
- else if (priv->mode & SPI_TX_DUAL)
+ if (priv->mode & SPI_TX_DUAL)
bus_width = 2;
else if (priv->mode & SPI_TX_QUAD)
bus_width = 4;
else if (priv->mode & SPI_TX_OCTAL)
bus_width = 8;
else
- log_warning("SPI mode not configured, setting to byte mode\n");
+ bus_width = 1; /* default is single bit mode */
div = DIV_ROUND_UP(125000000, priv->speed);
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index cdc20f5e946..1ca74805fd9 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -25,7 +25,7 @@ obj-$(CONFIG_RISCV_TIMER) += riscv_timer.o
obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
obj-$(CONFIG_SANDBOX_TIMER) += sandbox_timer.o
obj-$(CONFIG_SP804_TIMER) += sp804_timer.o
-obj-$(CONFIG_$(SPL_)SIFIVE_CLINT) += sifive_clint_timer.o
+obj-$(CONFIG_$(SPL_)RISCV_ACLINT) += riscv_aclint_timer.o
obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
obj-$(CONFIG_STM32_TIMER) += stm32_timer.o
obj-$(CONFIG_TEGRA_TIMER) += tegra-timer.o
diff --git a/drivers/timer/riscv_aclint_timer.c b/drivers/timer/riscv_aclint_timer.c
new file mode 100644
index 00000000000..e29d527c8d7
--- /dev/null
+++ b/drivers/timer/riscv_aclint_timer.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020, Sean Anderson <seanga2@gmail.com>
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <timer.h>
+#include <asm/io.h>
+#include <dm/device-internal.h>
+#include <linux/err.h>
+
+#define CLINT_MTIME_OFFSET 0xbff8
+#define ACLINT_MTIME_OFFSET 0
+
+/* mtime register */
+#define MTIME_REG(base, offset) ((ulong)(base) + (offset))
+
+static u64 notrace riscv_aclint_timer_get_count(struct udevice *dev)
+{
+ return readq((void __iomem *)MTIME_REG(dev_get_priv(dev),
+ dev_get_driver_data(dev)));
+}
+
+#if CONFIG_IS_ENABLED(RISCV_MMODE) && IS_ENABLED(CONFIG_TIMER_EARLY)
+/**
+ * timer_early_get_rate() - Get the timer rate before driver model
+ */
+unsigned long notrace timer_early_get_rate(void)
+{
+ return RISCV_MMODE_TIMER_FREQ;
+}
+
+/**
+ * timer_early_get_count() - Get the timer count before driver model
+ *
+ */
+u64 notrace timer_early_get_count(void)
+{
+ return readq((void __iomem *)MTIME_REG(RISCV_MMODE_TIMERBASE,
+ RISCV_MMODE_TIMEROFF));
+}
+#endif
+
+static const struct timer_ops riscv_aclint_timer_ops = {
+ .get_count = riscv_aclint_timer_get_count,
+};
+
+static int riscv_aclint_timer_probe(struct udevice *dev)
+{
+ dev_set_priv(dev, dev_read_addr_ptr(dev));
+ if (!dev_get_priv(dev))
+ return -EINVAL;
+
+ return timer_timebase_fallback(dev);
+}
+
+static const struct udevice_id riscv_aclint_timer_ids[] = {
+ { .compatible = "riscv,clint0", .data = CLINT_MTIME_OFFSET },
+ { .compatible = "sifive,clint0", .data = CLINT_MTIME_OFFSET },
+ { .compatible = "riscv,aclint-mtimer", .data = ACLINT_MTIME_OFFSET },
+ { }
+};
+
+U_BOOT_DRIVER(riscv_aclint_timer) = {
+ .name = "riscv_aclint_timer",
+ .id = UCLASS_TIMER,
+ .of_match = riscv_aclint_timer_ids,
+ .probe = riscv_aclint_timer_probe,
+ .ops = &riscv_aclint_timer_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/timer/sifive_clint_timer.c b/drivers/timer/sifive_clint_timer.c
deleted file mode 100644
index 939b99d937d..00000000000
--- a/drivers/timer/sifive_clint_timer.c
+++ /dev/null
@@ -1,68 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2020, Sean Anderson <seanga2@gmail.com>
- * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
- */
-
-#include <common.h>
-#include <clk.h>
-#include <dm.h>
-#include <timer.h>
-#include <asm/io.h>
-#include <dm/device-internal.h>
-#include <linux/err.h>
-
-/* mtime register */
-#define MTIME_REG(base) ((ulong)(base) + 0xbff8)
-
-static u64 notrace sifive_clint_get_count(struct udevice *dev)
-{
- return readq((void __iomem *)MTIME_REG(dev_get_priv(dev)));
-}
-
-#if CONFIG_IS_ENABLED(RISCV_MMODE) && IS_ENABLED(CONFIG_TIMER_EARLY)
-/**
- * timer_early_get_rate() - Get the timer rate before driver model
- */
-unsigned long notrace timer_early_get_rate(void)
-{
- return RISCV_MMODE_TIMER_FREQ;
-}
-
-/**
- * timer_early_get_count() - Get the timer count before driver model
- *
- */
-u64 notrace timer_early_get_count(void)
-{
- return readq((void __iomem *)MTIME_REG(RISCV_MMODE_TIMERBASE));
-}
-#endif
-
-static const struct timer_ops sifive_clint_ops = {
- .get_count = sifive_clint_get_count,
-};
-
-static int sifive_clint_probe(struct udevice *dev)
-{
- dev_set_priv(dev, dev_read_addr_ptr(dev));
- if (!dev_get_priv(dev))
- return -EINVAL;
-
- return timer_timebase_fallback(dev);
-}
-
-static const struct udevice_id sifive_clint_ids[] = {
- { .compatible = "riscv,clint0" },
- { .compatible = "sifive,clint0" },
- { }
-};
-
-U_BOOT_DRIVER(sifive_clint) = {
- .name = "sifive_clint",
- .id = UCLASS_TIMER,
- .of_match = sifive_clint_ids,
- .probe = sifive_clint_probe,
- .ops = &sifive_clint_ops,
- .flags = DM_FLAG_PRE_RELOC,
-};
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index 8dd29edd3de..3bf1a95e7f2 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -775,7 +775,7 @@ static inline void ufshcd_prepare_utp_nop_upiu(struct ufs_hba *hba)
/* command descriptor fields */
ucd_req_ptr->header.dword_0 =
- UPIU_HEADER_DWORD(UPIU_TRANSACTION_NOP_OUT, 0, 0, 0x1f);
+ UPIU_HEADER_DWORD(UPIU_TRANSACTION_NOP_OUT, 0, 0, TASK_TAG);
/* clear rest of the fields of basic header */
ucd_req_ptr->header.dword_1 = 0;
ucd_req_ptr->header.dword_2 = 0;
diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index 6b5390136a7..0f9bb49e44f 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -62,10 +62,43 @@ static double tt_sqrt(double value)
return lo;
}
+static double tt_fmod(double x, double y)
+{
+ double rem;
+
+ if (y == 0.0)
+ return 0.0;
+ rem = x - (x / y) * y;
+
+ return rem;
+}
+
+/* dummy implementation */
+static double tt_pow(double x, double y)
+{
+ return 0;
+}
+
+/* dummy implementation */
+static double tt_cos(double val)
+{
+ return 0;
+}
+
+/* dummy implementation */
+static double tt_acos(double val)
+{
+ return 0;
+}
+
#define STBTT_ifloor tt_floor
#define STBTT_iceil tt_ceil
#define STBTT_fabs tt_fabs
#define STBTT_sqrt tt_sqrt
+#define STBTT_pow tt_pow
+#define STBTT_fmod tt_fmod
+#define STBTT_cos tt_cos
+#define STBTT_acos tt_acos
#define STBTT_malloc(size, u) ((void)(u), malloc(size))
#define STBTT_free(size, u) ((void)(u), free(size))
#define STBTT_assert(x)
@@ -154,33 +187,33 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
end = line + met->font_size * vid_priv->line_length;
switch (vid_priv->bpix) {
-#ifdef CONFIG_VIDEO_BPP8
case VIDEO_BPP8: {
u8 *dst;
- for (dst = line; dst < (u8 *)end; ++dst)
- *dst = clr;
+ if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
+ for (dst = line; dst < (u8 *)end; ++dst)
+ *dst = clr;
+ }
break;
}
-#endif
-#ifdef CONFIG_VIDEO_BPP16
case VIDEO_BPP16: {
u16 *dst = line;
- for (dst = line; dst < (u16 *)end; ++dst)
- *dst = clr;
+ if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
+ for (dst = line; dst < (u16 *)end; ++dst)
+ *dst = clr;
+ }
break;
}
-#endif
-#ifdef CONFIG_VIDEO_BPP32
case VIDEO_BPP32: {
u32 *dst = line;
- for (dst = line; dst < (u32 *)end; ++dst)
- *dst = clr;
+ if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
+ for (dst = line; dst < (u32 *)end; ++dst)
+ *dst = clr;
+ }
break;
}
-#endif
default:
return -ENOSYS;
}
@@ -256,7 +289,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
*/
x_shift = xpos - (double)tt_floor(xpos);
xpos += advance * met->scale;
- width_frac = (int)VID_TO_POS(xpos);
+ width_frac = (int)VID_TO_POS(advance * met->scale);
if (x + width_frac >= vc_priv->xsize_frac)
return -EAGAIN;
@@ -317,52 +350,52 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
end = dst;
}
break;
-#ifdef CONFIG_VIDEO_BPP16
case VIDEO_BPP16: {
uint16_t *dst = (uint16_t *)line + xoff;
int i;
- for (i = 0; i < width; i++) {
- int val = *bits;
- int out;
-
- if (vid_priv->colour_bg)
- val = 255 - val;
- out = val >> 3 |
- (val >> 2) << 5 |
- (val >> 3) << 11;
- if (vid_priv->colour_fg)
- *dst++ |= out;
- else
- *dst++ &= out;
- bits++;
+ if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
+ for (i = 0; i < width; i++) {
+ int val = *bits;
+ int out;
+
+ if (vid_priv->colour_bg)
+ val = 255 - val;
+ out = val >> 3 |
+ (val >> 2) << 5 |
+ (val >> 3) << 11;
+ if (vid_priv->colour_fg)
+ *dst++ |= out;
+ else
+ *dst++ &= out;
+ bits++;
+ }
+ end = dst;
}
- end = dst;
break;
}
-#endif
-#ifdef CONFIG_VIDEO_BPP32
case VIDEO_BPP32: {
u32 *dst = (u32 *)line + xoff;
int i;
- for (i = 0; i < width; i++) {
- int val = *bits;
- int out;
-
- if (vid_priv->colour_bg)
- val = 255 - val;
- out = val | val << 8 | val << 16;
- if (vid_priv->colour_fg)
- *dst++ |= out;
- else
- *dst++ &= out;
- bits++;
+ if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
+ for (i = 0; i < width; i++) {
+ int val = *bits;
+ int out;
+
+ if (vid_priv->colour_bg)
+ val = 255 - val;
+ out = val | val << 8 | val << 16;
+ if (vid_priv->colour_fg)
+ *dst++ |= out;
+ else
+ *dst++ &= out;
+ bits++;
+ }
+ end = dst;
}
- end = dst;
break;
}
-#endif
default:
free(data);
return -ENOSYS;
@@ -379,72 +412,6 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
}
/**
- * console_truetype_erase() - Erase a character
- *
- * This is used for backspace. We erase a square of the display within the
- * given bounds.
- *
- * @dev: Device to update
- * @xstart: X start position in pixels from the left
- * @ystart: Y start position in pixels from the top
- * @xend: X end position in pixels from the left
- * @yend: Y end position in pixels from the top
- * @clr: Value to write
- * Return: 0 if OK, -ENOSYS if the display depth is not supported
- */
-static int console_truetype_erase(struct udevice *dev, int xstart, int ystart,
- int xend, int yend, int clr)
-{
- struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
- void *start, *line;
- int pixels = xend - xstart;
- int row, i, ret;
-
- start = vid_priv->fb + ystart * vid_priv->line_length;
- start += xstart * VNBYTES(vid_priv->bpix);
- line = start;
- for (row = ystart; row < yend; row++) {
- switch (vid_priv->bpix) {
-#ifdef CONFIG_VIDEO_BPP8
- case VIDEO_BPP8: {
- uint8_t *dst = line;
-
- for (i = 0; i < pixels; i++)
- *dst++ = clr;
- break;
- }
-#endif
-#ifdef CONFIG_VIDEO_BPP16
- case VIDEO_BPP16: {
- uint16_t *dst = line;
-
- for (i = 0; i < pixels; i++)
- *dst++ = clr;
- break;
- }
-#endif
-#ifdef CONFIG_VIDEO_BPP32
- case VIDEO_BPP32: {
- uint32_t *dst = line;
-
- for (i = 0; i < pixels; i++)
- *dst++ = clr;
- break;
- }
-#endif
- default:
- return -ENOSYS;
- }
- line += vid_priv->line_length;
- }
- ret = vidconsole_sync_copy(dev, start, line);
- if (ret)
- return ret;
-
- return 0;
-}
-
-/**
* console_truetype_backspace() - Handle a backspace operation
*
* This clears the previous character so that the console looks as if it had
@@ -482,9 +449,9 @@ static int console_truetype_backspace(struct udevice *dev)
else
xend = vid_priv->xsize;
- console_truetype_erase(dev, VID_TO_PIXEL(pos->xpos_frac), pos->ypos,
- xend, pos->ypos + vc_priv->y_charsize,
- vid_priv->colour_bg);
+ video_fill_part(vid_dev, VID_TO_PIXEL(pos->xpos_frac), pos->ypos,
+ xend, pos->ypos + vc_priv->y_charsize,
+ vid_priv->colour_bg);
/* Move the cursor back to where it was when we pushed this record */
vc_priv->xcur_frac = pos->xpos_frac;
@@ -680,8 +647,8 @@ static void select_metrics(struct udevice *dev, struct console_tt_metrics *met)
vc_priv->tab_width_frac = VID_TO_POS(met->font_size) * 8 / 2;
}
-static int truetype_select_font(struct udevice *dev, const char *name,
- uint size)
+static int get_metrics(struct udevice *dev, const char *name, uint size,
+ struct console_tt_metrics **metp)
{
struct console_tt_priv *priv = dev_get_priv(dev);
struct console_tt_metrics *met;
@@ -719,11 +686,70 @@ static int truetype_select_font(struct udevice *dev, const char *name,
met = priv->metrics;
}
+ *metp = met;
+
+ return 0;
+}
+
+static int truetype_select_font(struct udevice *dev, const char *name,
+ uint size)
+{
+ struct console_tt_metrics *met;
+ int ret;
+
+ ret = get_metrics(dev, name, size, &met);
+ if (ret)
+ return log_msg_ret("sel", ret);
+
select_metrics(dev, met);
return 0;
}
+int truetype_measure(struct udevice *dev, const char *name, uint size,
+ const char *text, struct vidconsole_bbox *bbox)
+{
+ struct console_tt_metrics *met;
+ stbtt_fontinfo *font;
+ int lsb, advance;
+ const char *s;
+ int width;
+ int last;
+ int ret;
+
+ ret = get_metrics(dev, name, size, &met);
+ if (ret)
+ return log_msg_ret("sel", ret);
+
+ bbox->valid = false;
+ if (!*text)
+ return 0;
+
+ font = &met->font;
+ width = 0;
+ for (last = 0, s = text; *s; s++) {
+ int ch = *s;
+
+ /* Used kerning to fine-tune the position of this character */
+ if (last)
+ width += stbtt_GetCodepointKernAdvance(font, last, ch);
+
+ /* First get some basic metrics about this character */
+ stbtt_GetCodepointHMetrics(font, ch, &advance, &lsb);
+
+ width += advance;
+ last = ch;
+ }
+
+ bbox->valid = true;
+ bbox->x0 = 0;
+ bbox->y0 = 0;
+ bbox->x1 = tt_ceil((double)width * met->scale);
+ bbox->y1 = met->font_size;
+
+ return 0;
+}
+
const char *console_truetype_get_font_size(struct udevice *dev, uint *sizep)
{
struct console_tt_priv *priv = dev_get_priv(dev);
@@ -775,6 +801,7 @@ struct vidconsole_ops console_truetype_ops = {
.get_font = console_truetype_get_font,
.get_font_size = console_truetype_get_font_size,
.select_font = truetype_select_font,
+ .measure = truetype_measure,
};
U_BOOT_DRIVER(vidconsole_truetype) = {
diff --git a/drivers/video/stb_truetype.h b/drivers/video/stb_truetype.h
index 438bfce468c..c6973bb353c 100644
--- a/drivers/video/stb_truetype.h
+++ b/drivers/video/stb_truetype.h
@@ -1,11 +1,21 @@
-// stb_truetype.h - v1.08 - public domain
-// authored from 2009-2015 by Sean Barrett / RAD Game Tools
+// stb_truetype.h - v1.26 - public domain
+// authored from 2009-2021 by Sean Barrett / RAD Game Tools
+//
+// =======================================================================
+//
+// NO SECURITY GUARANTEE -- DO NOT USE THIS ON UNTRUSTED FONT FILES
+//
+// This library does no range checking of the offsets found in the file,
+// meaning an attacker can use it to read arbitrary memory.
+//
+// =======================================================================
//
// This library processes TrueType files:
// parse files
// extract glyph metrics
// extract glyph shapes
// render glyphs to one-channel bitmaps with antialiasing (box filter)
+// render glyphs to one-channel SDF bitmaps (signed-distance field/function)
//
// Todo:
// non-MS cmaps
@@ -20,58 +30,68 @@
//
// Mikko Mononen: compound shape support, more cmap formats
// Tor Andersson: kerning, subpixel rendering
-//
-// Bug/warning reports/fixes:
-// "Zer" on mollyrocket (with fix)
-// Cass Everitt
-// stoiko (Haemimont Games)
-// Brian Hook
-// Walter van Niftrik
-// David Gow
-// David Given
-// Ivan-Assen Ivanov
-// Anthony Pesch
-// Johan Duparc
-// Hou Qiming
-// Fabian "ryg" Giesen
-// Martins Mozeiko
-// Cap Petschulat
-// Omar Cornut
-// github:aloucks
-// Peter LaValle
-// Sergey Popov
-// Giumo X. Clanjor
-// Higor Euripedes
+// Dougall Johnson: OpenType / Type 2 font handling
+// Daniel Ribeiro Maciel: basic GPOS-based kerning
//
// Misc other:
// Ryan Gordon
+// Simon Glass
+// github:IntellectualKitty
+// Imanol Celaya
+// Daniel Ribeiro Maciel
+//
+// Bug/warning reports/fixes:
+// "Zer" on mollyrocket Fabian "ryg" Giesen github:NiLuJe
+// Cass Everitt Martins Mozeiko github:aloucks
+// stoiko (Haemimont Games) Cap Petschulat github:oyvindjam
+// Brian Hook Omar Cornut github:vassvik
+// Walter van Niftrik Ryan Griege
+// David Gow Peter LaValle
+// David Given Sergey Popov
+// Ivan-Assen Ivanov Giumo X. Clanjor
+// Anthony Pesch Higor Euripedes
+// Johan Duparc Thomas Fields
+// Hou Qiming Derek Vinyard
+// Rob Loach Cort Stratton
+// Kenney Phillis Jr. Brian Costabile
+// Ken Voskuil (kaesve)
//
// VERSION HISTORY
//
+// 1.26 (2021-08-28) fix broken rasterizer
+// 1.25 (2021-07-11) many fixes
+// 1.24 (2020-02-05) fix warning
+// 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS)
+// 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined
+// 1.21 (2019-02-25) fix warning
+// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
+// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod
+// 1.18 (2018-01-29) add missing function
+// 1.17 (2017-07-23) make more arguments const; doc fix
+// 1.16 (2017-07-12) SDF support
+// 1.15 (2017-03-03) make more arguments const
+// 1.14 (2017-01-16) num-fonts-in-TTC function
+// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts
+// 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual
+// 1.11 (2016-04-02) fix unused-variable warning
+// 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef
+// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly
// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
// variant PackFontRanges to pack and render in separate phases;
// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
// fixed an assert() bug in the new rasterizer
// replace assert() with STBTT_assert() in new rasterizer
-// 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine)
-// also more precise AA rasterizer, except if shapes overlap
-// remove need for STBTT_sort
-// 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC
-// 1.04 (2015-04-15) typo in example
-// 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes
//
// Full history can be found at the end of this file.
//
// LICENSE
//
-// This software is in the public domain. Where that dedication is not
-// recognized, you are granted a perpetual, irrevocable license to copy,
-// distribute, and modify this file as you see fit.
+// See end of file for license information.
//
// USAGE
//
-// Include this file in whatever places neeed to refer to it. In ONE C/C++
+// Include this file in whatever places need to refer to it. In ONE C/C++
// file, write:
// #define STB_TRUETYPE_IMPLEMENTATION
// before the #include of this file. This expands out the actual
@@ -87,14 +107,15 @@
// Improved 3D API (more shippable):
// #include "stb_rect_pack.h" -- optional, but you really want it
// stbtt_PackBegin()
-// stbtt_PackSetOversample() -- for improved quality on small fonts
+// stbtt_PackSetOversampling() -- for improved quality on small fonts
// stbtt_PackFontRanges() -- pack and renders
// stbtt_PackEnd()
// stbtt_GetPackedQuad()
//
// "Load" a font file from a memory buffer (you have to keep the buffer loaded)
// stbtt_InitFont()
-// stbtt_GetFontOffsetForIndex() -- use for TTC font collections
+// stbtt_GetFontOffsetForIndex() -- indexing for TTC font collections
+// stbtt_GetNumberOfFonts() -- number of fonts for TTC font collections
//
// Render a unicode codepoint to a bitmap
// stbtt_GetCodepointBitmap() -- allocates and returns a bitmap
@@ -104,6 +125,7 @@
// Character advance/positioning
// stbtt_GetCodepointHMetrics()
// stbtt_GetFontVMetrics()
+// stbtt_GetFontVMetricsOS2()
// stbtt_GetCodepointKernAdvance()
//
// Starting with version 1.06, the rasterizer was replaced with a new,
@@ -159,7 +181,7 @@
// measurement for describing font size, defined as 72 points per inch.
// stb_truetype provides a point API for compatibility. However, true
// "per inch" conventions don't make much sense on computer displays
-// since they different monitors have different number of pixels per
+// since different monitors have different number of pixels per
// inch. For example, Windows traditionally uses a convention that
// there are 96 pixels per inch, thus making 'inch' measurements have
// nothing to do with inches, and thus effectively defining a point to
@@ -169,6 +191,39 @@
// for non-commercial fonts, thus making fonts scaled in points
// according to the TrueType spec incoherently sized in practice.
//
+// DETAILED USAGE:
+//
+// Scale:
+// Select how high you want the font to be, in points or pixels.
+// Call ScaleForPixelHeight or ScaleForMappingEmToPixels to compute
+// a scale factor SF that will be used by all other functions.
+//
+// Baseline:
+// You need to select a y-coordinate that is the baseline of where
+// your text will appear. Call GetFontBoundingBox to get the baseline-relative
+// bounding box for all characters. SF*-y0 will be the distance in pixels
+// that the worst-case character could extend above the baseline, so if
+// you want the top edge of characters to appear at the top of the
+// screen where y=0, then you would set the baseline to SF*-y0.
+//
+// Current point:
+// Set the current point where the first character will appear. The
+// first character could extend left of the current point; this is font
+// dependent. You can either choose a current point that is the leftmost
+// point and hope, or add some padding, or check the bounding box or
+// left-side-bearing of the first character to be displayed and set
+// the current point based on that.
+//
+// Displaying a character:
+// Compute the bounding box of the character. It will contain signed values
+// relative to <current_point, baseline>. I.e. if it returns x0,y0,x1,y1,
+// then the character should be displayed in the rectangle from
+// <current_point+SF*x0, baseline+SF*y0> to <current_point+SF*x1,baseline+SF*y1).
+//
+// Advancing for the next character:
+// Call GlyphHMetrics, and compute 'current_point += SF * advance'.
+//
+//
// ADVANCED USAGE
//
// Quality:
@@ -203,19 +258,6 @@
// recommend it.
//
//
-// SOURCE STATISTICS (based on v0.6c, 2050 LOC)
-//
-// Documentation & header file 520 LOC \___ 660 LOC documentation
-// Sample code 140 LOC /
-// Truetype parsing 620 LOC ---- 620 LOC TrueType
-// Software rasterization 240 LOC \ .
-// Curve tesselation 120 LOC \__ 550 LOC Bitmap creation
-// Bitmap management 100 LOC /
-// Baked bitmap interface 70 LOC /
-// Font name matching & access 150 LOC ---- 150
-// C runtime library abstraction 60 LOC ---- 60
-//
-//
// PERFORMANCE MEASUREMENTS FOR 1.06:
//
// 32-bit 64-bit
@@ -230,8 +272,8 @@
//// SAMPLE PROGRAMS
////
//
-// Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless
-//
+// Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless.
+// See "tests/truetype_demo_win32.c" for a complete version.
#if 0
#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
#include "stb_truetype.h"
@@ -257,6 +299,8 @@ void my_stbtt_initfont(void)
void my_stbtt_print(float x, float y, char *text)
{
// assume orthographic projection with units = screen pixels, origin at top left
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, ftex);
glBegin(GL_QUADS);
@@ -264,10 +308,10 @@ void my_stbtt_print(float x, float y, char *text)
if (*text >= 32 && *text < 128) {
stbtt_aligned_quad q;
stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9
- glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0);
- glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0);
- glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1);
- glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1);
+ glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y0);
+ glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y0);
+ glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y1);
+ glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y1);
}
++text;
}
@@ -305,7 +349,7 @@ int main(int argc, char **argv)
}
return 0;
}
-#endif
+#endif
//
// Output:
//
@@ -319,9 +363,9 @@ int main(int argc, char **argv)
// :@@. M@M
// @@@o@@@@
// :M@@V:@@.
-//
+//
//////////////////////////////////////////////////////////////////////////////
-//
+//
// Complete program: print "Hello World!" banner, with bugs
//
#if 0
@@ -375,7 +419,8 @@ int main(int arg, char **argv)
//// INTEGRATION WITH YOUR CODEBASE
////
//// The following sections allow you to supply alternate definitions
-//// of C library functions used by stb_truetype.
+//// of C library functions used by stb_truetype, e.g. if you don't
+//// link with the C runtime library.
#ifdef STB_TRUETYPE_IMPLEMENTATION
// #define your own (u)stbtt_int8/16/32 before including to override this
@@ -391,7 +436,7 @@ int main(int arg, char **argv)
typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1];
typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1];
- // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
+ // e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
#ifndef STBTT_ifloor
#include <math.h>
#define STBTT_ifloor(x) ((int) floor(x))
@@ -401,6 +446,18 @@ int main(int arg, char **argv)
#ifndef STBTT_sqrt
#include <math.h>
#define STBTT_sqrt(x) sqrt(x)
+ #define STBTT_pow(x,y) pow(x,y)
+ #endif
+
+ #ifndef STBTT_fmod
+ #include <math.h>
+ #define STBTT_fmod(x,y) fmod(x,y)
+ #endif
+
+ #ifndef STBTT_cos
+ #include <math.h>
+ #define STBTT_cos(x) cos(x)
+ #define STBTT_acos(x) acos(x)
#endif
#ifndef STBTT_fabs
@@ -452,6 +509,14 @@ int main(int arg, char **argv)
extern "C" {
#endif
+// private structure
+typedef struct
+{
+ unsigned char *data;
+ int cursor;
+ int size;
+} stbtt__buf;
+
//////////////////////////////////////////////////////////////////////////////
//
// TEXTURE BAKING API
@@ -481,7 +546,7 @@ typedef struct
float x1,y1,s1,t1; // bottom-right
} stbtt_aligned_quad;
-STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above
+STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, // same data as above
int char_index, // character to display
float *xpos, float *ypos, // pointers to current position in screen pixel space
stbtt_aligned_quad *q, // output: quad to draw
@@ -496,6 +561,9 @@ STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, //
//
// It's inefficient; you might want to c&p it and optimize it.
+STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap);
+// Query the font vertical metrics without having to create a font first.
+
//////////////////////////////////////////////////////////////////////////////
//
@@ -520,7 +588,7 @@ typedef struct stbrp_rect stbrp_rect;
STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context);
// Initializes a packing context stored in the passed-in stbtt_pack_context.
// Future calls using this context will pack characters into the bitmap passed
-// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is
+// in here: a 1-channel bitmap that is width * height. stride_in_bytes is
// the distance from one row to the next (or 0 to mean they are packed tightly
// together). "padding" is the amount of padding to leave between each
// character (normally you want '1' for bitmaps you'll use as textures with
@@ -533,7 +601,7 @@ STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc);
#define STBTT_POINT_SIZE(x) (-(x))
-STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size,
+STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size,
int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range);
// Creates character bitmaps from the font_index'th font found in fontdata (use
// font_index=0 if you don't know what that is). It creates num_chars_in_range
@@ -558,7 +626,7 @@ typedef struct
unsigned char h_oversample, v_oversample; // don't set these, they're used internally
} stbtt_pack_range;
-STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges);
+STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges);
// Creates character bitmaps from multiple ranges of characters stored in
// ranges. This will usually create a better-packed bitmap than multiple
// calls to stbtt_PackFontRange. Note that you can call this multiple
@@ -580,19 +648,25 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
// To use with PackFontRangesGather etc., you must set it before calls
// call to PackFontRangesGatherRects.
-STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above
+STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip);
+// If skip != 0, this tells stb_truetype to skip any codepoints for which
+// there is no corresponding glyph. If skip=0, which is the default, then
+// codepoints without a glyph recived the font's "missing character" glyph,
+// typically an empty box by convention.
+
+STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above
int char_index, // character to display
float *xpos, float *ypos, // pointers to current position in screen pixel space
stbtt_aligned_quad *q, // output: quad to draw
int align_to_integer);
-STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
+STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects);
-STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
+STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
// Calling these functions in sequence is roughly equivalent to calling
// stbtt_PackFontRanges(). If you more control over the packing of multiple
// fonts, or if you want to pack custom data into a font texture, take a look
-// at the source to of stbtt_PackFontRanges() and create a custom version
+// at the source to of stbtt_PackFontRanges() and create a custom version
// using these functions, e.g. call GatherRects multiple times,
// building up a single array of rects, then call PackRects once,
// then call RenderIntoRects repeatedly. This may result in a
@@ -608,6 +682,7 @@ struct stbtt_pack_context {
int height;
int stride_in_bytes;
int padding;
+ int skip_missing;
unsigned int h_oversample, v_oversample;
unsigned char *pixels;
void *nodes;
@@ -619,18 +694,23 @@ struct stbtt_pack_context {
//
//
+STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data);
+// This function will determine the number of fonts in a font file. TrueType
+// collection (.ttc) files may contain multiple fonts, while TrueType font
+// (.ttf) files only contain one font. The number of fonts can be used for
+// indexing with the previous function where the index is between zero and one
+// less than the total fonts. If an error occurs, -1 is returned.
+
STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
// Each .ttf/.ttc file may have more than one font. Each font has a sequential
// index number starting from 0. Call this function to get the font offset for
// a given index; it returns -1 if the index is out of range. A regular .ttf
// file will only define one font and it always be at offset 0, so it will
-// return '0' for index 0, and -1 for all other indices. You can just skip
-// this step if you know it's that kind of font.
+// return '0' for index 0, and -1 for all other indices.
-
-// The following structure is defined publically so you can declare one on
+// The following structure is defined publicly so you can declare one on
// the stack or as a global or etc, but you should treat it as opaque.
-typedef struct stbtt_fontinfo
+struct stbtt_fontinfo
{
void * userdata;
unsigned char * data; // pointer to .ttf file
@@ -638,10 +718,17 @@ typedef struct stbtt_fontinfo
int numGlyphs; // number of glyphs, needed for range checking
- int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf
+ int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf
int index_map; // a cmap mapping for our chosen character encoding
int indexToLocFormat; // format needed to map from glyph index to glyph
-} stbtt_fontinfo;
+
+ stbtt__buf cff; // cff font data
+ stbtt__buf charstrings; // the charstring index
+ stbtt__buf gsubrs; // global charstring subroutines index
+ stbtt__buf subrs; // private charstring subroutines index
+ stbtt__buf fontdicts; // array of font dicts
+ stbtt__buf fdselect; // map from glyph to fontdict
+};
STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset);
// Given an offset into the file that defines a font, this function builds
@@ -660,6 +747,7 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
// and you want a speed-up, call this function with the character you're
// going to process, then use glyph-based functions instead of the
// codepoint-based functions.
+// Returns 0 if the character codepoint is not defined in the font.
//////////////////////////////////////////////////////////////////////////////
@@ -688,6 +776,12 @@ STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, in
// these are expressed in unscaled coordinates, so you must multiply by
// the scale factor for a given size
+STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap);
+// analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2
+// table (specific to MS/Windows TTF files).
+//
+// Returns 1 on success (table present), 0 on failure.
+
STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1);
// the bounding box around all possible characters
@@ -707,6 +801,18 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1,
STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
// as above, but takes one or more glyph indices for greater efficiency
+typedef struct stbtt_kerningentry
+{
+ int glyph1; // use stbtt_FindGlyphIndex
+ int glyph2;
+ int advance;
+} stbtt_kerningentry;
+
+STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info);
+STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length);
+// Retrieves a complete list of all of the kerning pairs provided by the font
+// stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write.
+// The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1)
//////////////////////////////////////////////////////////////////////////////
//
@@ -718,7 +824,8 @@ STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, in
enum {
STBTT_vmove=1,
STBTT_vline,
- STBTT_vcurve
+ STBTT_vcurve,
+ STBTT_vcubic
};
#endif
@@ -727,7 +834,7 @@ STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, in
#define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file
typedef struct
{
- stbtt_vertex_type x,y,cx,cy;
+ stbtt_vertex_type x,y,cx,cy,cx1,cy1;
unsigned char type,padding;
} stbtt_vertex;
#endif
@@ -740,7 +847,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
// returns # of vertices and fills *vertices with the pointer to them
// these are expressed in "unscaled" coordinates
//
-// The shape is a series of countours. Each one starts with
+// The shape is a series of contours. Each one starts with
// a STBTT_moveto, then consists of a series of mixed
// STBTT_lineto and STBTT_curveto segments. A lineto
// draws a line from previous endpoint to its x,y; a curveto
@@ -750,6 +857,12 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
// frees the data allocated above
+STBTT_DEF unsigned char *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl);
+STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg);
+STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg);
+// fills svg with the character's SVG data.
+// returns data size or 0 if SVG not found.
+
//////////////////////////////////////////////////////////////////////////////
//
// BITMAP RENDERING
@@ -781,6 +894,10 @@ STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, uns
// same as stbtt_MakeCodepointBitmap, but you can specify a subpixel
// shift for the character
+STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint);
+// same as stbtt_MakeCodepointBitmapSubpixel, but prefiltering
+// is performed (see stbtt_PackSetOversampling)
+
STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
// get the bbox of the bitmap centered around the glyph origin; so the
// bitmap width is ix1-ix0, height is iy1-iy0, and location to place
@@ -798,6 +915,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float
STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff);
STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph);
STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph);
+STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int glyph);
STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
@@ -822,6 +940,64 @@ STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, // 1-channel bitmap
//////////////////////////////////////////////////////////////////////////////
//
+// Signed Distance Function (or Field) rendering
+
+STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata);
+// frees the SDF bitmap allocated below
+
+STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
+STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
+// These functions compute a discretized SDF field for a single character, suitable for storing
+// in a single-channel texture, sampling with bilinear filtering, and testing against
+// larger than some threshold to produce scalable fonts.
+// info -- the font
+// scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap
+// glyph/codepoint -- the character to generate the SDF for
+// padding -- extra "pixels" around the character which are filled with the distance to the character (not 0),
+// which allows effects like bit outlines
+// onedge_value -- value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character)
+// pixel_dist_scale -- what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale)
+// if positive, > onedge_value is inside; if negative, < onedge_value is inside
+// width,height -- output height & width of the SDF bitmap (including padding)
+// xoff,yoff -- output origin of the character
+// return value -- a 2D array of bytes 0..255, width*height in size
+//
+// pixel_dist_scale & onedge_value are a scale & bias that allows you to make
+// optimal use of the limited 0..255 for your application, trading off precision
+// and special effects. SDF values outside the range 0..255 are clamped to 0..255.
+//
+// Example:
+// scale = stbtt_ScaleForPixelHeight(22)
+// padding = 5
+// onedge_value = 180
+// pixel_dist_scale = 180/5.0 = 36.0
+//
+// This will create an SDF bitmap in which the character is about 22 pixels
+// high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled
+// shape, sample the SDF at each pixel and fill the pixel if the SDF value
+// is greater than or equal to 180/255. (You'll actually want to antialias,
+// which is beyond the scope of this example.) Additionally, you can compute
+// offset outlines (e.g. to stroke the character border inside & outside,
+// or only outside). For example, to fill outside the character up to 3 SDF
+// pixels, you would compare against (180-36.0*3)/255 = 72/255. The above
+// choice of variables maps a range from 5 pixels outside the shape to
+// 2 pixels inside the shape to 0..255; this is intended primarily for apply
+// outside effects only (the interior range is needed to allow proper
+// antialiasing of the font at *smaller* sizes)
+//
+// The function computes the SDF analytically at each SDF pixel, not by e.g.
+// building a higher-res bitmap and approximating it. In theory the quality
+// should be as high as possible for an SDF of this size & representation, but
+// unclear if this is true in practice (perhaps building a higher-res bitmap
+// and computing from that can allow drop-out prevention).
+//
+// The algorithm has not been optimized at all, so expect it to be slow
+// if computing lots of characters or very large sizes.
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
// Finding the right font...
//
// You should really just solve this offline, keep your own tables
@@ -943,6 +1119,158 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS
#define STBTT_RASTERIZER_VERSION 2
#endif
+#ifdef _MSC_VER
+#define STBTT__NOTUSED(v) (void)(v)
+#else
+#define STBTT__NOTUSED(v) (void)sizeof(v)
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+//
+// stbtt__buf helpers to parse data from file
+//
+
+static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b)
+{
+ if (b->cursor >= b->size)
+ return 0;
+ return b->data[b->cursor++];
+}
+
+static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b)
+{
+ if (b->cursor >= b->size)
+ return 0;
+ return b->data[b->cursor];
+}
+
+static void stbtt__buf_seek(stbtt__buf *b, int o)
+{
+ STBTT_assert(!(o > b->size || o < 0));
+ b->cursor = (o > b->size || o < 0) ? b->size : o;
+}
+
+static void stbtt__buf_skip(stbtt__buf *b, int o)
+{
+ stbtt__buf_seek(b, b->cursor + o);
+}
+
+static stbtt_uint32 stbtt__buf_get(stbtt__buf *b, int n)
+{
+ stbtt_uint32 v = 0;
+ int i;
+ STBTT_assert(n >= 1 && n <= 4);
+ for (i = 0; i < n; i++)
+ v = (v << 8) | stbtt__buf_get8(b);
+ return v;
+}
+
+static stbtt__buf stbtt__new_buf(const void *p, size_t size)
+{
+ stbtt__buf r;
+ STBTT_assert(size < 0x40000000);
+ r.data = (stbtt_uint8*) p;
+ r.size = (int) size;
+ r.cursor = 0;
+ return r;
+}
+
+#define stbtt__buf_get16(b) stbtt__buf_get((b), 2)
+#define stbtt__buf_get32(b) stbtt__buf_get((b), 4)
+
+static stbtt__buf stbtt__buf_range(const stbtt__buf *b, int o, int s)
+{
+ stbtt__buf r = stbtt__new_buf(NULL, 0);
+ if (o < 0 || s < 0 || o > b->size || s > b->size - o) return r;
+ r.data = b->data + o;
+ r.size = s;
+ return r;
+}
+
+static stbtt__buf stbtt__cff_get_index(stbtt__buf *b)
+{
+ int count, start, offsize;
+ start = b->cursor;
+ count = stbtt__buf_get16(b);
+ if (count) {
+ offsize = stbtt__buf_get8(b);
+ STBTT_assert(offsize >= 1 && offsize <= 4);
+ stbtt__buf_skip(b, offsize * count);
+ stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1);
+ }
+ return stbtt__buf_range(b, start, b->cursor - start);
+}
+
+static stbtt_uint32 stbtt__cff_int(stbtt__buf *b)
+{
+ int b0 = stbtt__buf_get8(b);
+ if (b0 >= 32 && b0 <= 246) return b0 - 139;
+ else if (b0 >= 247 && b0 <= 250) return (b0 - 247)*256 + stbtt__buf_get8(b) + 108;
+ else if (b0 >= 251 && b0 <= 254) return -(b0 - 251)*256 - stbtt__buf_get8(b) - 108;
+ else if (b0 == 28) return stbtt__buf_get16(b);
+ else if (b0 == 29) return stbtt__buf_get32(b);
+ STBTT_assert(0);
+ return 0;
+}
+
+static void stbtt__cff_skip_operand(stbtt__buf *b) {
+ int v, b0 = stbtt__buf_peek8(b);
+ STBTT_assert(b0 >= 28);
+ if (b0 == 30) {
+ stbtt__buf_skip(b, 1);
+ while (b->cursor < b->size) {
+ v = stbtt__buf_get8(b);
+ if ((v & 0xF) == 0xF || (v >> 4) == 0xF)
+ break;
+ }
+ } else {
+ stbtt__cff_int(b);
+ }
+}
+
+static stbtt__buf stbtt__dict_get(stbtt__buf *b, int key)
+{
+ stbtt__buf_seek(b, 0);
+ while (b->cursor < b->size) {
+ int start = b->cursor, end, op;
+ while (stbtt__buf_peek8(b) >= 28)
+ stbtt__cff_skip_operand(b);
+ end = b->cursor;
+ op = stbtt__buf_get8(b);
+ if (op == 12) op = stbtt__buf_get8(b) | 0x100;
+ if (op == key) return stbtt__buf_range(b, start, end-start);
+ }
+ return stbtt__buf_range(b, 0, 0);
+}
+
+static void stbtt__dict_get_ints(stbtt__buf *b, int key, int outcount, stbtt_uint32 *out)
+{
+ int i;
+ stbtt__buf operands = stbtt__dict_get(b, key);
+ for (i = 0; i < outcount && operands.cursor < operands.size; i++)
+ out[i] = stbtt__cff_int(&operands);
+}
+
+static int stbtt__cff_index_count(stbtt__buf *b)
+{
+ stbtt__buf_seek(b, 0);
+ return stbtt__buf_get16(b);
+}
+
+static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i)
+{
+ int count, offsize, start, end;
+ stbtt__buf_seek(&b, 0);
+ count = stbtt__buf_get16(&b);
+ offsize = stbtt__buf_get8(&b);
+ STBTT_assert(i >= 0 && i < count);
+ STBTT_assert(offsize >= 1 && offsize <= 4);
+ stbtt__buf_skip(&b, i*offsize);
+ start = stbtt__buf_get(&b, offsize);
+ end = stbtt__buf_get(&b, offsize);
+ return stbtt__buf_range(&b, 2+(count+1)*offsize+start, end - start);
+}
+
//////////////////////////////////////////////////////////////////////////
//
// accessors to parse data from file
@@ -955,32 +1283,22 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS
#define ttCHAR(p) (* (stbtt_int8 *) (p))
#define ttFixed(p) ttLONG(p)
-#if defined(STB_TRUETYPE_BIGENDIAN) && !defined(ALLOW_UNALIGNED_TRUETYPE)
-
- #define ttUSHORT(p) (* (stbtt_uint16 *) (p))
- #define ttSHORT(p) (* (stbtt_int16 *) (p))
- #define ttULONG(p) (* (stbtt_uint32 *) (p))
- #define ttLONG(p) (* (stbtt_int32 *) (p))
-
-#else
-
- static stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; }
- static stbtt_int16 ttSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; }
- static stbtt_uint32 ttULONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
- static stbtt_int32 ttLONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
-
-#endif
+static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; }
+static stbtt_int16 ttSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; }
+static stbtt_uint32 ttULONG(stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
+static stbtt_int32 ttLONG(stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
#define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
#define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3])
-static int stbtt__isfont(const stbtt_uint8 *font)
+static int stbtt__isfont(stbtt_uint8 *font)
{
// check the version number
if (stbtt_tag4(font, '1',0,0,0)) return 1; // TrueType 1
if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this!
if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF
if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0
+ if (stbtt_tag(font, "true")) return 1; // Apple specification for TrueType fonts
return 0;
}
@@ -998,7 +1316,7 @@ static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart,
return 0;
}
-STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index)
+static int stbtt_GetFontOffsetForIndex_internal(unsigned char *font_collection, int index)
{
// if it's just a font, there's only one valid index
if (stbtt__isfont(font_collection))
@@ -1017,14 +1335,59 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection,
return -1;
}
-STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, int fontstart)
+static int stbtt_GetNumberOfFonts_internal(unsigned char *font_collection)
+{
+ // if it's just a font, there's only one valid font
+ if (stbtt__isfont(font_collection))
+ return 1;
+
+ // check if it's a TTC
+ if (stbtt_tag(font_collection, "ttcf")) {
+ // version 1?
+ if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
+ return ttLONG(font_collection+8);
+ }
+ }
+ return 0;
+}
+
+static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict)
+{
+ stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 };
+ stbtt__buf pdict;
+ stbtt__dict_get_ints(&fontdict, 18, 2, private_loc);
+ if (!private_loc[1] || !private_loc[0]) return stbtt__new_buf(NULL, 0);
+ pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]);
+ stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff);
+ if (!subrsoff) return stbtt__new_buf(NULL, 0);
+ stbtt__buf_seek(&cff, private_loc[1]+subrsoff);
+ return stbtt__cff_get_index(&cff);
+}
+
+// since most people won't use this, find this table the first time it's needed
+static int stbtt__get_svg(stbtt_fontinfo *info)
+{
+ stbtt_uint32 t;
+ if (info->svg < 0) {
+ t = stbtt__find_table(info->data, info->fontstart, "SVG ");
+ if (t) {
+ stbtt_uint32 offset = ttULONG(info->data + t + 2);
+ info->svg = t + offset;
+ } else {
+ info->svg = 0;
+ }
+ }
+ return info->svg;
+}
+
+static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart)
{
- stbtt_uint8 *data = (stbtt_uint8 *) data2;
stbtt_uint32 cmap, t;
stbtt_int32 i,numTables;
info->data = data;
info->fontstart = fontstart;
+ info->cff = stbtt__new_buf(NULL, 0);
cmap = stbtt__find_table(data, fontstart, "cmap"); // required
info->loca = stbtt__find_table(data, fontstart, "loca"); // required
@@ -1033,8 +1396,62 @@ STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, i
info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required
info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required
info->kern = stbtt__find_table(data, fontstart, "kern"); // not required
- if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx)
+ info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required
+
+ if (!cmap || !info->head || !info->hhea || !info->hmtx)
return 0;
+ if (info->glyf) {
+ // required for truetype
+ if (!info->loca) return 0;
+ } else {
+ // initialization for CFF / Type2 fonts (OTF)
+ stbtt__buf b, topdict, topdictidx;
+ stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0;
+ stbtt_uint32 cff;
+
+ cff = stbtt__find_table(data, fontstart, "CFF ");
+ if (!cff) return 0;
+
+ info->fontdicts = stbtt__new_buf(NULL, 0);
+ info->fdselect = stbtt__new_buf(NULL, 0);
+
+ // @TODO this should use size from table (not 512MB)
+ info->cff = stbtt__new_buf(data+cff, 512*1024*1024);
+ b = info->cff;
+
+ // read the header
+ stbtt__buf_skip(&b, 2);
+ stbtt__buf_seek(&b, stbtt__buf_get8(&b)); // hdrsize
+
+ // @TODO the name INDEX could list multiple fonts,
+ // but we just use the first one.
+ stbtt__cff_get_index(&b); // name INDEX
+ topdictidx = stbtt__cff_get_index(&b);
+ topdict = stbtt__cff_index_get(topdictidx, 0);
+ stbtt__cff_get_index(&b); // string INDEX
+ info->gsubrs = stbtt__cff_get_index(&b);
+
+ stbtt__dict_get_ints(&topdict, 17, 1, &charstrings);
+ stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype);
+ stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff);
+ stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff);
+ info->subrs = stbtt__get_subrs(b, topdict);
+
+ // we only support Type 2 charstrings
+ if (cstype != 2) return 0;
+ if (charstrings == 0) return 0;
+
+ if (fdarrayoff) {
+ // looks like a CID font
+ if (!fdselectoff) return 0;
+ stbtt__buf_seek(&b, fdarrayoff);
+ info->fontdicts = stbtt__cff_get_index(&b);
+ info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size-fdselectoff);
+ }
+
+ stbtt__buf_seek(&b, charstrings);
+ info->charstrings = stbtt__cff_get_index(&b);
+ }
t = stbtt__find_table(data, fontstart, "maxp");
if (t)
@@ -1042,6 +1459,8 @@ STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, i
else
info->numGlyphs = 0xffff;
+ info->svg = -1;
+
// find a cmap encoding table we understand *now* to avoid searching
// later. (todo: could make this installable)
// the same regardless of glyph.
@@ -1125,12 +1544,12 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
search += 2;
{
- stbtt_uint16 offset, start;
+ stbtt_uint16 offset, start, last;
stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1);
- STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item));
start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
- if (unicode_codepoint < start)
+ last = ttUSHORT(data + endCount + 2*item);
+ if (unicode_codepoint < start || unicode_codepoint > last)
return 0;
offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
@@ -1185,6 +1604,8 @@ static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index)
{
int g1,g2;
+ STBTT_assert(!info->cff.size);
+
if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range
if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format
@@ -1199,15 +1620,21 @@ static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index)
return g1==g2 ? -1 : g1; // if length is 0, return -1
}
+static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
+
STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1)
{
- int g = stbtt__GetGlyfOffset(info, glyph_index);
- if (g < 0) return 0;
+ if (info->cff.size) {
+ stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1);
+ } else {
+ int g = stbtt__GetGlyfOffset(info, glyph_index);
+ if (g < 0) return 0;
- if (x0) *x0 = ttSHORT(info->data + g + 2);
- if (y0) *y0 = ttSHORT(info->data + g + 4);
- if (x1) *x1 = ttSHORT(info->data + g + 6);
- if (y1) *y1 = ttSHORT(info->data + g + 8);
+ if (x0) *x0 = ttSHORT(info->data + g + 2);
+ if (y0) *y0 = ttSHORT(info->data + g + 4);
+ if (x1) *x1 = ttSHORT(info->data + g + 6);
+ if (y1) *y1 = ttSHORT(info->data + g + 8);
+ }
return 1;
}
@@ -1219,7 +1646,10 @@ STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, i
STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index)
{
stbtt_int16 numberOfContours;
- int g = stbtt__GetGlyfOffset(info, glyph_index);
+ int g;
+ if (info->cff.size)
+ return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0;
+ g = stbtt__GetGlyfOffset(info, glyph_index);
if (g < 0) return 1;
numberOfContours = ttSHORT(info->data + g);
return numberOfContours == 0;
@@ -1241,7 +1671,7 @@ static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_
return num_vertices;
}
-STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
+static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
{
stbtt_int16 numberOfContours;
stbtt_uint8 *endPtsOfContours;
@@ -1337,7 +1767,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
if (i != 0)
num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
- // now start the new one
+ // now start the new one
start_off = !(flags & 1);
if (start_off) {
// if we start off with an off-curve point, then when we need to find a point on the curve
@@ -1379,7 +1809,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
}
}
num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
- } else if (numberOfContours == -1) {
+ } else if (numberOfContours < 0) {
// Compound shapes.
int more = 1;
stbtt_uint8 *comp = data + g + 10;
@@ -1390,7 +1820,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
int comp_num_verts = 0, i;
stbtt_vertex *comp_verts = 0, *tmp = 0;
float mtx[6] = {1,0,0,1,0,0}, m, n;
-
+
flags = ttSHORT(comp); comp+=2;
gidx = ttSHORT(comp); comp+=2;
@@ -1420,7 +1850,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
}
-
+
// Find transformation scales.
m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
@@ -1446,7 +1876,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
if (comp_verts) STBTT_free(comp_verts, info->userdata);
return 0;
}
- if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
+ if (num_vertices > 0 && vertices) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
if (vertices) STBTT_free(vertices, info->userdata);
vertices = tmp;
@@ -1456,9 +1886,6 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
// More components ?
more = flags & (1<<5);
}
- } else if (numberOfContours < 0) {
- // @TODO other compound variations?
- STBTT_assert(0);
} else {
// numberOfCounters == 0, do nothing
}
@@ -1467,6 +1894,414 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
return num_vertices;
}
+typedef struct
+{
+ int bounds;
+ int started;
+ float first_x, first_y;
+ float x, y;
+ stbtt_int32 min_x, max_x, min_y, max_y;
+
+ stbtt_vertex *pvertices;
+ int num_vertices;
+} stbtt__csctx;
+
+#define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0}
+
+static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y)
+{
+ if (x > c->max_x || !c->started) c->max_x = x;
+ if (y > c->max_y || !c->started) c->max_y = y;
+ if (x < c->min_x || !c->started) c->min_x = x;
+ if (y < c->min_y || !c->started) c->min_y = y;
+ c->started = 1;
+}
+
+static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1)
+{
+ if (c->bounds) {
+ stbtt__track_vertex(c, x, y);
+ if (type == STBTT_vcubic) {
+ stbtt__track_vertex(c, cx, cy);
+ stbtt__track_vertex(c, cx1, cy1);
+ }
+ } else {
+ stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy);
+ c->pvertices[c->num_vertices].cx1 = (stbtt_int16) cx1;
+ c->pvertices[c->num_vertices].cy1 = (stbtt_int16) cy1;
+ }
+ c->num_vertices++;
+}
+
+static void stbtt__csctx_close_shape(stbtt__csctx *ctx)
+{
+ if (ctx->first_x != ctx->x || ctx->first_y != ctx->y)
+ stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0);
+}
+
+static void stbtt__csctx_rmove_to(stbtt__csctx *ctx, float dx, float dy)
+{
+ stbtt__csctx_close_shape(ctx);
+ ctx->first_x = ctx->x = ctx->x + dx;
+ ctx->first_y = ctx->y = ctx->y + dy;
+ stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0);
+}
+
+static void stbtt__csctx_rline_to(stbtt__csctx *ctx, float dx, float dy)
+{
+ ctx->x += dx;
+ ctx->y += dy;
+ stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0);
+}
+
+static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx, float dx1, float dy1, float dx2, float dy2, float dx3, float dy3)
+{
+ float cx1 = ctx->x + dx1;
+ float cy1 = ctx->y + dy1;
+ float cx2 = cx1 + dx2;
+ float cy2 = cy1 + dy2;
+ ctx->x = cx2 + dx3;
+ ctx->y = cy2 + dy3;
+ stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2);
+}
+
+static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n)
+{
+ int count = stbtt__cff_index_count(&idx);
+ int bias = 107;
+ if (count >= 33900)
+ bias = 32768;
+ else if (count >= 1240)
+ bias = 1131;
+ n += bias;
+ if (n < 0 || n >= count)
+ return stbtt__new_buf(NULL, 0);
+ return stbtt__cff_index_get(idx, n);
+}
+
+static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int glyph_index)
+{
+ stbtt__buf fdselect = info->fdselect;
+ int nranges, start, end, v, fmt, fdselector = -1, i;
+
+ stbtt__buf_seek(&fdselect, 0);
+ fmt = stbtt__buf_get8(&fdselect);
+ if (fmt == 0) {
+ // untested
+ stbtt__buf_skip(&fdselect, glyph_index);
+ fdselector = stbtt__buf_get8(&fdselect);
+ } else if (fmt == 3) {
+ nranges = stbtt__buf_get16(&fdselect);
+ start = stbtt__buf_get16(&fdselect);
+ for (i = 0; i < nranges; i++) {
+ v = stbtt__buf_get8(&fdselect);
+ end = stbtt__buf_get16(&fdselect);
+ if (glyph_index >= start && glyph_index < end) {
+ fdselector = v;
+ break;
+ }
+ start = end;
+ }
+ }
+ if (fdselector == -1) stbtt__new_buf(NULL, 0);
+ return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector));
+}
+
+static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, stbtt__csctx *c)
+{
+ int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0;
+ int has_subrs = 0, clear_stack;
+ float s[48];
+ stbtt__buf subr_stack[10], subrs = info->subrs, b;
+ float f;
+
+#define STBTT__CSERR(s) (0)
+
+ // this currently ignores the initial width value, which isn't needed if we have hmtx
+ b = stbtt__cff_index_get(info->charstrings, glyph_index);
+ while (b.cursor < b.size) {
+ i = 0;
+ clear_stack = 1;
+ b0 = stbtt__buf_get8(&b);
+ switch (b0) {
+ // @TODO implement hinting
+ case 0x13: // hintmask
+ case 0x14: // cntrmask
+ if (in_header)
+ maskbits += (sp / 2); // implicit "vstem"
+ in_header = 0;
+ stbtt__buf_skip(&b, (maskbits + 7) / 8);
+ break;
+
+ case 0x01: // hstem
+ case 0x03: // vstem
+ case 0x12: // hstemhm
+ case 0x17: // vstemhm
+ maskbits += (sp / 2);
+ break;
+
+ case 0x15: // rmoveto
+ in_header = 0;
+ if (sp < 2) return STBTT__CSERR("rmoveto stack");
+ stbtt__csctx_rmove_to(c, s[sp-2], s[sp-1]);
+ break;
+ case 0x04: // vmoveto
+ in_header = 0;
+ if (sp < 1) return STBTT__CSERR("vmoveto stack");
+ stbtt__csctx_rmove_to(c, 0, s[sp-1]);
+ break;
+ case 0x16: // hmoveto
+ in_header = 0;
+ if (sp < 1) return STBTT__CSERR("hmoveto stack");
+ stbtt__csctx_rmove_to(c, s[sp-1], 0);
+ break;
+
+ case 0x05: // rlineto
+ if (sp < 2) return STBTT__CSERR("rlineto stack");
+ for (; i + 1 < sp; i += 2)
+ stbtt__csctx_rline_to(c, s[i], s[i+1]);
+ break;
+
+ // hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical
+ // starting from a different place.
+
+ case 0x07: // vlineto
+ if (sp < 1) return STBTT__CSERR("vlineto stack");
+ goto vlineto;
+ case 0x06: // hlineto
+ if (sp < 1) return STBTT__CSERR("hlineto stack");
+ for (;;) {
+ if (i >= sp) break;
+ stbtt__csctx_rline_to(c, s[i], 0);
+ i++;
+ vlineto:
+ if (i >= sp) break;
+ stbtt__csctx_rline_to(c, 0, s[i]);
+ i++;
+ }
+ break;
+
+ case 0x1F: // hvcurveto
+ if (sp < 4) return STBTT__CSERR("hvcurveto stack");
+ goto hvcurveto;
+ case 0x1E: // vhcurveto
+ if (sp < 4) return STBTT__CSERR("vhcurveto stack");
+ for (;;) {
+ if (i + 3 >= sp) break;
+ stbtt__csctx_rccurve_to(c, 0, s[i], s[i+1], s[i+2], s[i+3], (sp - i == 5) ? s[i + 4] : 0.0f);
+ i += 4;
+ hvcurveto:
+ if (i + 3 >= sp) break;
+ stbtt__csctx_rccurve_to(c, s[i], 0, s[i+1], s[i+2], (sp - i == 5) ? s[i+4] : 0.0f, s[i+3]);
+ i += 4;
+ }
+ break;
+
+ case 0x08: // rrcurveto
+ if (sp < 6) return STBTT__CSERR("rcurveline stack");
+ for (; i + 5 < sp; i += 6)
+ stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
+ break;
+
+ case 0x18: // rcurveline
+ if (sp < 8) return STBTT__CSERR("rcurveline stack");
+ for (; i + 5 < sp - 2; i += 6)
+ stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
+ if (i + 1 >= sp) return STBTT__CSERR("rcurveline stack");
+ stbtt__csctx_rline_to(c, s[i], s[i+1]);
+ break;
+
+ case 0x19: // rlinecurve
+ if (sp < 8) return STBTT__CSERR("rlinecurve stack");
+ for (; i + 1 < sp - 6; i += 2)
+ stbtt__csctx_rline_to(c, s[i], s[i+1]);
+ if (i + 5 >= sp) return STBTT__CSERR("rlinecurve stack");
+ stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
+ break;
+
+ case 0x1A: // vvcurveto
+ case 0x1B: // hhcurveto
+ if (sp < 4) return STBTT__CSERR("(vv|hh)curveto stack");
+ f = 0.0;
+ if (sp & 1) { f = s[i]; i++; }
+ for (; i + 3 < sp; i += 4) {
+ if (b0 == 0x1B)
+ stbtt__csctx_rccurve_to(c, s[i], f, s[i+1], s[i+2], s[i+3], 0.0);
+ else
+ stbtt__csctx_rccurve_to(c, f, s[i], s[i+1], s[i+2], 0.0, s[i+3]);
+ f = 0.0;
+ }
+ break;
+
+ case 0x0A: // callsubr
+ if (!has_subrs) {
+ if (info->fdselect.size)
+ subrs = stbtt__cid_get_glyph_subrs(info, glyph_index);
+ has_subrs = 1;
+ }
+ // FALLTHROUGH
+ case 0x1D: // callgsubr
+ if (sp < 1) return STBTT__CSERR("call(g|)subr stack");
+ v = (int) s[--sp];
+ if (subr_stack_height >= 10) return STBTT__CSERR("recursion limit");
+ subr_stack[subr_stack_height++] = b;
+ b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v);
+ if (b.size == 0) return STBTT__CSERR("subr not found");
+ b.cursor = 0;
+ clear_stack = 0;
+ break;
+
+ case 0x0B: // return
+ if (subr_stack_height <= 0) return STBTT__CSERR("return outside subr");
+ b = subr_stack[--subr_stack_height];
+ clear_stack = 0;
+ break;
+
+ case 0x0E: // endchar
+ stbtt__csctx_close_shape(c);
+ return 1;
+
+ case 0x0C: { // two-byte escape
+ float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6;
+ float dx, dy;
+ int b1 = stbtt__buf_get8(&b);
+ switch (b1) {
+ // @TODO These "flex" implementations ignore the flex-depth and resolution,
+ // and always draw beziers.
+ case 0x22: // hflex
+ if (sp < 7) return STBTT__CSERR("hflex stack");
+ dx1 = s[0];
+ dx2 = s[1];
+ dy2 = s[2];
+ dx3 = s[3];
+ dx4 = s[4];
+ dx5 = s[5];
+ dx6 = s[6];
+ stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0);
+ stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0);
+ break;
+
+ case 0x23: // flex
+ if (sp < 13) return STBTT__CSERR("flex stack");
+ dx1 = s[0];
+ dy1 = s[1];
+ dx2 = s[2];
+ dy2 = s[3];
+ dx3 = s[4];
+ dy3 = s[5];
+ dx4 = s[6];
+ dy4 = s[7];
+ dx5 = s[8];
+ dy5 = s[9];
+ dx6 = s[10];
+ dy6 = s[11];
+ //fd is s[12]
+ stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
+ stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
+ break;
+
+ case 0x24: // hflex1
+ if (sp < 9) return STBTT__CSERR("hflex1 stack");
+ dx1 = s[0];
+ dy1 = s[1];
+ dx2 = s[2];
+ dy2 = s[3];
+ dx3 = s[4];
+ dx4 = s[5];
+ dx5 = s[6];
+ dy5 = s[7];
+ dx6 = s[8];
+ stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0);
+ stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1+dy2+dy5));
+ break;
+
+ case 0x25: // flex1
+ if (sp < 11) return STBTT__CSERR("flex1 stack");
+ dx1 = s[0];
+ dy1 = s[1];
+ dx2 = s[2];
+ dy2 = s[3];
+ dx3 = s[4];
+ dy3 = s[5];
+ dx4 = s[6];
+ dy4 = s[7];
+ dx5 = s[8];
+ dy5 = s[9];
+ dx6 = dy6 = s[10];
+ dx = dx1+dx2+dx3+dx4+dx5;
+ dy = dy1+dy2+dy3+dy4+dy5;
+ if (STBTT_fabs(dx) > STBTT_fabs(dy))
+ dy6 = -dy;
+ else
+ dx6 = -dx;
+ stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
+ stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
+ break;
+
+ default:
+ return STBTT__CSERR("unimplemented");
+ }
+ } break;
+
+ default:
+ if (b0 != 255 && b0 != 28 && b0 < 32)
+ return STBTT__CSERR("reserved operator");
+
+ // push immediate
+ if (b0 == 255) {
+ f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000;
+ } else {
+ stbtt__buf_skip(&b, -1);
+ f = (float)(stbtt_int16)stbtt__cff_int(&b);
+ }
+ if (sp >= 48) return STBTT__CSERR("push stack overflow");
+ s[sp++] = f;
+ clear_stack = 0;
+ break;
+ }
+ if (clear_stack) sp = 0;
+ }
+ return STBTT__CSERR("no endchar");
+
+#undef STBTT__CSERR
+}
+
+static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
+{
+ // runs the charstring twice, once to count and once to output (to avoid realloc)
+ stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1);
+ stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0);
+ if (stbtt__run_charstring(info, glyph_index, &count_ctx)) {
+ *pvertices = (stbtt_vertex*)STBTT_malloc(count_ctx.num_vertices*sizeof(stbtt_vertex), info->userdata);
+ output_ctx.pvertices = *pvertices;
+ if (stbtt__run_charstring(info, glyph_index, &output_ctx)) {
+ STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices);
+ return output_ctx.num_vertices;
+ }
+ }
+ *pvertices = NULL;
+ return 0;
+}
+
+static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1)
+{
+ stbtt__csctx c = STBTT__CSCTX_INIT(1);
+ int r = stbtt__run_charstring(info, glyph_index, &c);
+ if (x0) *x0 = r ? c.min_x : 0;
+ if (y0) *y0 = r ? c.min_y : 0;
+ if (x1) *x1 = r ? c.max_x : 0;
+ if (y1) *y1 = r ? c.max_y : 0;
+ return r ? c.num_vertices : 0;
+}
+
+STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
+{
+ if (!info->cff.size)
+ return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices);
+ else
+ return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices);
+}
+
STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing)
{
stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34);
@@ -1479,7 +2314,49 @@ STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_inde
}
}
-STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
+STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info)
+{
+ stbtt_uint8 *data = info->data + info->kern;
+
+ // we only look at the first table. it must be 'horizontal' and format 0.
+ if (!info->kern)
+ return 0;
+ if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
+ return 0;
+ if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
+ return 0;
+
+ return ttUSHORT(data+10);
+}
+
+STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length)
+{
+ stbtt_uint8 *data = info->data + info->kern;
+ int k, length;
+
+ // we only look at the first table. it must be 'horizontal' and format 0.
+ if (!info->kern)
+ return 0;
+ if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
+ return 0;
+ if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
+ return 0;
+
+ length = ttUSHORT(data+10);
+ if (table_length < length)
+ length = table_length;
+
+ for (k = 0; k < length; k++)
+ {
+ table[k].glyph1 = ttUSHORT(data+18+(k*6));
+ table[k].glyph2 = ttUSHORT(data+20+(k*6));
+ table[k].advance = ttSHORT(data+22+(k*6));
+ }
+
+ return length;
+}
+
+static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
{
stbtt_uint8 *data = info->data + info->kern;
stbtt_uint32 needle, straw;
@@ -1509,9 +2386,242 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1,
return 0;
}
+static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph)
+{
+ stbtt_uint16 coverageFormat = ttUSHORT(coverageTable);
+ switch (coverageFormat) {
+ case 1: {
+ stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2);
+
+ // Binary search.
+ stbtt_int32 l=0, r=glyphCount-1, m;
+ int straw, needle=glyph;
+ while (l <= r) {
+ stbtt_uint8 *glyphArray = coverageTable + 4;
+ stbtt_uint16 glyphID;
+ m = (l + r) >> 1;
+ glyphID = ttUSHORT(glyphArray + 2 * m);
+ straw = glyphID;
+ if (needle < straw)
+ r = m - 1;
+ else if (needle > straw)
+ l = m + 1;
+ else {
+ return m;
+ }
+ }
+ break;
+ }
+
+ case 2: {
+ stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
+ stbtt_uint8 *rangeArray = coverageTable + 4;
+
+ // Binary search.
+ stbtt_int32 l=0, r=rangeCount-1, m;
+ int strawStart, strawEnd, needle=glyph;
+ while (l <= r) {
+ stbtt_uint8 *rangeRecord;
+ m = (l + r) >> 1;
+ rangeRecord = rangeArray + 6 * m;
+ strawStart = ttUSHORT(rangeRecord);
+ strawEnd = ttUSHORT(rangeRecord + 2);
+ if (needle < strawStart)
+ r = m - 1;
+ else if (needle > strawEnd)
+ l = m + 1;
+ else {
+ stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4);
+ return startCoverageIndex + glyph - strawStart;
+ }
+ }
+ break;
+ }
+
+ default: return -1; // unsupported
+ }
+
+ return -1;
+}
+
+static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
+{
+ stbtt_uint16 classDefFormat = ttUSHORT(classDefTable);
+ switch (classDefFormat)
+ {
+ case 1: {
+ stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2);
+ stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4);
+ stbtt_uint8 *classDef1ValueArray = classDefTable + 6;
+
+ if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
+ return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
+ break;
+ }
+
+ case 2: {
+ stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2);
+ stbtt_uint8 *classRangeRecords = classDefTable + 4;
+
+ // Binary search.
+ stbtt_int32 l=0, r=classRangeCount-1, m;
+ int strawStart, strawEnd, needle=glyph;
+ while (l <= r) {
+ stbtt_uint8 *classRangeRecord;
+ m = (l + r) >> 1;
+ classRangeRecord = classRangeRecords + 6 * m;
+ strawStart = ttUSHORT(classRangeRecord);
+ strawEnd = ttUSHORT(classRangeRecord + 2);
+ if (needle < strawStart)
+ r = m - 1;
+ else if (needle > strawEnd)
+ l = m + 1;
+ else
+ return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
+ }
+ break;
+ }
+
+ default:
+ return -1; // Unsupported definition type, return an error.
+ }
+
+ // "All glyphs not assigned to a class fall into class 0". (OpenType spec)
+ return 0;
+}
+
+// Define to STBTT_assert(x) if you want to break on unimplemented formats.
+#define STBTT_GPOS_TODO_assert(x)
+
+static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
+{
+ stbtt_uint16 lookupListOffset;
+ stbtt_uint8 *lookupList;
+ stbtt_uint16 lookupCount;
+ stbtt_uint8 *data;
+ stbtt_int32 i, sti;
+
+ if (!info->gpos) return 0;
+
+ data = info->data + info->gpos;
+
+ if (ttUSHORT(data+0) != 1) return 0; // Major version 1
+ if (ttUSHORT(data+2) != 0) return 0; // Minor version 0
+
+ lookupListOffset = ttUSHORT(data+8);
+ lookupList = data + lookupListOffset;
+ lookupCount = ttUSHORT(lookupList);
+
+ for (i=0; i<lookupCount; ++i) {
+ stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i);
+ stbtt_uint8 *lookupTable = lookupList + lookupOffset;
+
+ stbtt_uint16 lookupType = ttUSHORT(lookupTable);
+ stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4);
+ stbtt_uint8 *subTableOffsets = lookupTable + 6;
+ if (lookupType != 2) // Pair Adjustment Positioning Subtable
+ continue;
+
+ for (sti=0; sti<subTableCount; sti++) {
+ stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
+ stbtt_uint8 *table = lookupTable + subtableOffset;
+ stbtt_uint16 posFormat = ttUSHORT(table);
+ stbtt_uint16 coverageOffset = ttUSHORT(table + 2);
+ stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1);
+ if (coverageIndex == -1) continue;
+
+ switch (posFormat) {
+ case 1: {
+ stbtt_int32 l, r, m;
+ int straw, needle;
+ stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
+ stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
+ if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
+ stbtt_int32 valueRecordPairSizeInBytes = 2;
+ stbtt_uint16 pairSetCount = ttUSHORT(table + 8);
+ stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex);
+ stbtt_uint8 *pairValueTable = table + pairPosOffset;
+ stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable);
+ stbtt_uint8 *pairValueArray = pairValueTable + 2;
+
+ if (coverageIndex >= pairSetCount) return 0;
+
+ needle=glyph2;
+ r=pairValueCount-1;
+ l=0;
+
+ // Binary search.
+ while (l <= r) {
+ stbtt_uint16 secondGlyph;
+ stbtt_uint8 *pairValue;
+ m = (l + r) >> 1;
+ pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
+ secondGlyph = ttUSHORT(pairValue);
+ straw = secondGlyph;
+ if (needle < straw)
+ r = m - 1;
+ else if (needle > straw)
+ l = m + 1;
+ else {
+ stbtt_int16 xAdvance = ttSHORT(pairValue + 2);
+ return xAdvance;
+ }
+ }
+ } else
+ return 0;
+ break;
+ }
+
+ case 2: {
+ stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
+ stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
+ if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
+ stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
+ stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
+ int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
+ int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2);
+
+ stbtt_uint16 class1Count = ttUSHORT(table + 12);
+ stbtt_uint16 class2Count = ttUSHORT(table + 14);
+ stbtt_uint8 *class1Records, *class2Records;
+ stbtt_int16 xAdvance;
+
+ if (glyph1class < 0 || glyph1class >= class1Count) return 0; // malformed
+ if (glyph2class < 0 || glyph2class >= class2Count) return 0; // malformed
+
+ class1Records = table + 16;
+ class2Records = class1Records + 2 * (glyph1class * class2Count);
+ xAdvance = ttSHORT(class2Records + 2 * glyph2class);
+ return xAdvance;
+ } else
+ return 0;
+ break;
+ }
+
+ default:
+ return 0; // Unsupported position format
+ }
+ }
+ }
+
+ return 0;
+}
+
+STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2)
+{
+ int xAdvance = 0;
+
+ if (info->gpos)
+ xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
+ else if (info->kern)
+ xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
+
+ return xAdvance;
+}
+
STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2)
{
- if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs
+ if (!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs
return 0;
return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2));
}
@@ -1528,6 +2638,17 @@ STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, in
if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8);
}
+STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap)
+{
+ int tab = stbtt__find_table(info->data, info->fontstart, "OS/2");
+ if (!tab)
+ return 0;
+ if (typoAscent ) *typoAscent = ttSHORT(info->data+tab + 68);
+ if (typoDescent) *typoDescent = ttSHORT(info->data+tab + 70);
+ if (typoLineGap) *typoLineGap = ttSHORT(info->data+tab + 72);
+ return 1;
+}
+
STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1)
{
*x0 = ttSHORT(info->data + info->head + 36);
@@ -1553,6 +2674,45 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
STBTT_free(v, info->userdata);
}
+STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl)
+{
+ int i;
+ stbtt_uint8 *data = info->data;
+ stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *) info);
+
+ int numEntries = ttUSHORT(svg_doc_list);
+ stbtt_uint8 *svg_docs = svg_doc_list + 2;
+
+ for(i=0; i<numEntries; i++) {
+ stbtt_uint8 *svg_doc = svg_docs + (12 * i);
+ if ((gl >= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2)))
+ return svg_doc;
+ }
+ return 0;
+}
+
+STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg)
+{
+ stbtt_uint8 *data = info->data;
+ stbtt_uint8 *svg_doc;
+
+ if (info->svg == 0)
+ return 0;
+
+ svg_doc = stbtt_FindSVGDoc(info, gl);
+ if (svg_doc != NULL) {
+ *svg = (char *) data + info->svg + ttULONG(svg_doc + 4);
+ return ttULONG(svg_doc + 8);
+ } else {
+ return 0;
+ }
+}
+
+STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg)
+{
+ return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg);
+}
+
//////////////////////////////////////////////////////////////////////////////
//
// antialiasing software rasterizer
@@ -1560,7 +2720,7 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
{
- int x0,y0,x1,y1;
+ int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning
if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
// e.g. space character
if (ix0) *ix0 = 0;
@@ -1624,7 +2784,7 @@ static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata)
hh->num_remaining_in_head_chunk = count;
}
--hh->num_remaining_in_head_chunk;
- return (char *) (hh->head) + size * hh->num_remaining_in_head_chunk;
+ return (char *) (hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk;
}
}
@@ -1676,8 +2836,9 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
{
stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
+ STBTT_assert(z != NULL);
if (!z) return z;
-
+
// round dx down to avoid overshooting
if (dxdy < 0)
z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy);
@@ -1697,6 +2858,7 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
{
stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
+ STBTT_assert(z != NULL);
//STBTT_assert(e->y0 <= start_point);
if (!z) return z;
z->fdx = dxdy;
@@ -1754,7 +2916,7 @@ static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__ac
}
}
}
-
+
e = e->next;
}
}
@@ -1768,13 +2930,10 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
int s; // vertical subsample index
unsigned char scanline_data[512], *scanline;
- if (result->w > 512) {
+ if (result->w > 512)
scanline = (unsigned char *) STBTT_malloc(result->w, userdata);
- if (!scanline)
- return;
- } else {
+ else
scanline = scanline_data;
- }
y = off_y * vsubsample;
e[n].y0 = (off_y + result->h) * (float) vsubsample + 1;
@@ -1824,23 +2983,23 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
while (e->y0 <= scan_y) {
if (e->y1 > scan_y) {
stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
- if (!z)
- return;
- // find insertion point
- if (active == NULL)
- active = z;
- else if (z->x < active->x) {
- // insert at front
- z->next = active;
- active = z;
- } else {
- // find thing to insert AFTER
- stbtt__active_edge *p = active;
- while (p->next && p->next->x < z->x)
- p = p->next;
- // at this point, p->next->x is NOT < z->x
- z->next = p->next;
- p->next = z;
+ if (z != NULL) {
+ // find insertion point
+ if (active == NULL)
+ active = z;
+ else if (z->x < active->x) {
+ // insert at front
+ z->next = active;
+ active = z;
+ } else {
+ // find thing to insert AFTER
+ stbtt__active_edge *p = active;
+ while (p->next && p->next->x < z->x)
+ p = p->next;
+ // at this point, p->next->x is NOT < z->x
+ z->next = p->next;
+ p->next = z;
+ }
}
}
++e;
@@ -1903,6 +3062,23 @@ static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edg
}
}
+static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width)
+{
+ STBTT_assert(top_width >= 0);
+ STBTT_assert(bottom_width >= 0);
+ return (top_width + bottom_width) / 2.0f * height;
+}
+
+static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1)
+{
+ return stbtt__sized_trapezoid_area(height, tx1 - tx0, bx1 - bx0);
+}
+
+static float stbtt__sized_triangle_area(float height, float width)
+{
+ return height * width / 2;
+}
+
static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top)
{
float y_bottom = y_top+1;
@@ -1957,13 +3133,13 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
float height;
// simple case, only spans one pixel
int x = (int) x_top;
- height = sy1 - sy0;
+ height = (sy1 - sy0) * e->direction;
STBTT_assert(x >= 0 && x < len);
- scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height;
- scanline_fill[x] += e->direction * height; // everything right of this pixel is filled
+ scanline[x] += stbtt__position_trapezoid_area(height, x_top, x+1.0f, x_bottom, x+1.0f);
+ scanline_fill[x] += height; // everything right of this pixel is filled
} else {
int x,x1,x2;
- float y_crossing, step, sign, area;
+ float y_crossing, y_final, step, sign, area;
// covers 2+ pixels
if (x_top > x_bottom) {
// flip scanline vertically; signed area is the same
@@ -1976,29 +3152,79 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
dy = -dy;
t = x0, x0 = xb, xb = t;
}
+ STBTT_assert(dy >= 0);
+ STBTT_assert(dx >= 0);
x1 = (int) x_top;
x2 = (int) x_bottom;
// compute intersection with y axis at x1+1
- y_crossing = (x1+1 - x0) * dy + y_top;
+ y_crossing = y_top + dy * (x1+1 - x0);
+
+ // compute intersection with y axis at x2
+ y_final = y_top + dy * (x2 - x0);
+
+ // x1 x_top x2 x_bottom
+ // y_top +------|-----+------------+------------+--------|---+------------+
+ // | | | | | |
+ // | | | | | |
+ // sy0 | Txxxxx|............|............|............|............|
+ // y_crossing | *xxxxx.......|............|............|............|
+ // | | xxxxx..|............|............|............|
+ // | | /- xx*xxxx........|............|............|
+ // | | dy < | xxxxxx..|............|............|
+ // y_final | | \- | xx*xxx.........|............|
+ // sy1 | | | | xxxxxB...|............|
+ // | | | | | |
+ // | | | | | |
+ // y_bottom +------------+------------+------------+------------+------------+
+ //
+ // goal is to measure the area covered by '.' in each pixel
+
+ // if x2 is right at the right edge of x1, y_crossing can blow up, github #1057
+ // @TODO: maybe test against sy1 rather than y_bottom?
+ if (y_crossing > y_bottom)
+ y_crossing = y_bottom;
sign = e->direction;
- // area of the rectangle covered from y0..y_crossing
+
+ // area of the rectangle covered from sy0..y_crossing
area = sign * (y_crossing-sy0);
- // area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing)
- scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2);
- step = sign * dy;
+ // area of the triangle (x_top,sy0), (x1+1,sy0), (x1+1,y_crossing)
+ scanline[x1] += stbtt__sized_triangle_area(area, x1+1 - x_top);
+
+ // check if final y_crossing is blown up; no test case for this
+ if (y_final > y_bottom) {
+ y_final = y_bottom;
+ dy = (y_final - y_crossing ) / (x2 - (x1+1)); // if denom=0, y_final = y_crossing, so y_final <= y_bottom
+ }
+
+ // in second pixel, area covered by line segment found in first pixel
+ // is always a rectangle 1 wide * the height of that line segment; this
+ // is exactly what the variable 'area' stores. it also gets a contribution
+ // from the line segment within it. the THIRD pixel will get the first
+ // pixel's rectangle contribution, the second pixel's rectangle contribution,
+ // and its own contribution. the 'own contribution' is the same in every pixel except
+ // the leftmost and rightmost, a trapezoid that slides down in each pixel.
+ // the second pixel's contribution to the third pixel will be the
+ // rectangle 1 wide times the height change in the second pixel, which is dy.
+
+ step = sign * dy * 1; // dy is dy/dx, change in y for every 1 change in x,
+ // which multiplied by 1-pixel-width is how much pixel area changes for each step in x
+ // so the area advances by 'step' every time
+
for (x = x1+1; x < x2; ++x) {
- scanline[x] += area + step/2;
+ scanline[x] += area + step/2; // area of trapezoid is 1*step/2
area += step;
}
- y_crossing += dy * (x2 - (x1+1));
+ STBTT_assert(STBTT_fabs(area) <= 1.01f); // accumulated error from area += step unless we round step down
+ STBTT_assert(sy1 > y_final-0.01f);
- STBTT_assert(fabs(area) <= 1.01f);
-
- scanline[x2] += area + sign * (1-(x_bottom-x2)/2) * (sy1-y_crossing);
+ // area covered in the last pixel is the rectangle from all the pixels to the left,
+ // plus the trapezoid filled by the line segment in this pixel all the way to the right edge
+ scanline[x2] += area + sign * stbtt__position_trapezoid_area(sy1-y_final, (float) x2, x2+1.0f, x_bottom, x2+1.0f);
+ // the rest of the line is filled based on the total height of the line segment in this pixel
scanline_fill[x2] += sign * (sy1-sy0);
}
} else {
@@ -2006,6 +3232,9 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
// clipping logic. since this does not match the intended use
// of this library, we use a different, very slow brute
// force implementation
+ // note though that this does happen some of the time because
+ // x_top and x_bottom can be extrapolated at the top & bottom of
+ // the shape and actually lie outside the bounding box
int x;
for (x=0; x < len; ++x) {
// cases:
@@ -2021,19 +3250,18 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
// from the other y segment, and it might ignored as an empty segment. to avoid
// that, we need to explicitly produce segments based on x positions.
- // rename variables to clear pairs
+ // rename variables to clearly-defined pairs
float y0 = y_top;
float x1 = (float) (x);
float x2 = (float) (x+1);
float x3 = xb;
float y3 = y_bottom;
- float y1,y2;
// x = e->x + e->dx * (y-y_top)
// (y-y_top) = (x - e->x) / e->dx
// y = (x - e->x) / e->dx + y_top
- y1 = (x - x0) / dx + y_top;
- y2 = (x+1 - x0) / dx + y_top;
+ float y1 = (x - x0) / dx + y_top;
+ float y2 = (x+1 - x0) / dx + y_top;
if (x0 < x1 && x3 > x2) { // three segments descending down-right
stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
@@ -2073,13 +3301,12 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
int y,j=0, i;
float scanline_data[129], *scanline, *scanline2;
- if (result->w > 64) {
+ STBTT__NOTUSED(vsubsample);
+
+ if (result->w > 64)
scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata);
- if (!scanline)
- return;
- } else {
+ else
scanline = scanline_data;
- }
scanline2 = scanline + result->w;
@@ -2113,12 +3340,18 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
while (e->y0 <= scan_y_bottom) {
if (e->y0 != e->y1) {
stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
- if (!z)
- return;
- STBTT_assert(z->ey >= scan_y_top);
- // insert at front
- z->next = active;
- active = z;
+ if (z != NULL) {
+ if (j == 0 && off_y != 0) {
+ if (z->ey < scan_y_top) {
+ // this can happen due to subpixel positioning and some kind of fp rounding error i think
+ z->ey = scan_y_top;
+ }
+ }
+ STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds
+ // insert at front
+ z->next = active;
+ active = z;
+ }
}
++e;
}
@@ -2183,7 +3416,7 @@ static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)
static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n)
{
- /* threshhold for transitioning to insertion sort */
+ /* threshold for transitioning to insertion sort */
while (n > 12) {
stbtt__edge t;
int c01,c12,c,m,i,j;
@@ -2318,7 +3551,7 @@ static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
points[n].y = y;
}
-// tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching
+// tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching
static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n)
{
// midpoint
@@ -2339,6 +3572,48 @@ static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x
return 1;
}
+static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n)
+{
+ // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough
+ float dx0 = x1-x0;
+ float dy0 = y1-y0;
+ float dx1 = x2-x1;
+ float dy1 = y2-y1;
+ float dx2 = x3-x2;
+ float dy2 = y3-y2;
+ float dx = x3-x0;
+ float dy = y3-y0;
+ float longlen = (float) (STBTT_sqrt(dx0*dx0+dy0*dy0)+STBTT_sqrt(dx1*dx1+dy1*dy1)+STBTT_sqrt(dx2*dx2+dy2*dy2));
+ float shortlen = (float) STBTT_sqrt(dx*dx+dy*dy);
+ float flatness_squared = longlen*longlen-shortlen*shortlen;
+
+ if (n > 16) // 65536 segments on one curve better be enough!
+ return;
+
+ if (flatness_squared > objspace_flatness_squared) {
+ float x01 = (x0+x1)/2;
+ float y01 = (y0+y1)/2;
+ float x12 = (x1+x2)/2;
+ float y12 = (y1+y2)/2;
+ float x23 = (x2+x3)/2;
+ float y23 = (y2+y3)/2;
+
+ float xa = (x01+x12)/2;
+ float ya = (y01+y12)/2;
+ float xb = (x12+x23)/2;
+ float yb = (y12+y23)/2;
+
+ float mx = (xa+xb)/2;
+ float my = (ya+yb)/2;
+
+ stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1);
+ stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1);
+ } else {
+ stbtt__add_point(points, *num_points,x3,y3);
+ *num_points = *num_points+1;
+ }
+}
+
// returns number of contours
static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata)
{
@@ -2395,6 +3670,14 @@ static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts,
objspace_flatness_squared, 0);
x = vertices[i].x, y = vertices[i].y;
break;
+ case STBTT_vcubic:
+ stbtt__tesselate_cubic(points, &num_points, x,y,
+ vertices[i].cx, vertices[i].cy,
+ vertices[i].cx1, vertices[i].cy1,
+ vertices[i].x, vertices[i].y,
+ objspace_flatness_squared, 0);
+ x = vertices[i].x, y = vertices[i].y;
+ break;
}
}
(*contour_lengths)[n] = num_points - start;
@@ -2411,8 +3694,9 @@ error:
STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata)
{
- float scale = scale_x > scale_y ? scale_y : scale_x;
- int winding_count, *winding_lengths;
+ float scale = scale_x > scale_y ? scale_y : scale_x;
+ int winding_count = 0;
+ int *winding_lengths = NULL;
stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata);
if (windings) {
stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata);
@@ -2430,7 +3714,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info
{
int ix0,iy0,ix1,iy1;
stbtt__bitmap gbm;
- stbtt_vertex *vertices;
+ stbtt_vertex *vertices;
int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
if (scale_x == 0) scale_x = scale_y;
@@ -2453,7 +3737,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info
if (height) *height = gbm.h;
if (xoff ) *xoff = ix0;
if (yoff ) *yoff = iy0;
-
+
if (gbm.w && gbm.h) {
gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata);
if (gbm.pixels) {
@@ -2464,7 +3748,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info
}
STBTT_free(vertices, info->userdata);
return gbm.pixels;
-}
+}
STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff)
{
@@ -2476,7 +3760,7 @@ STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigne
int ix0,iy0;
stbtt_vertex *vertices;
int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
- stbtt__bitmap gbm;
+ stbtt__bitmap gbm;
stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0);
gbm.pixels = output;
@@ -2498,7 +3782,12 @@ STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *
STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
{
return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff);
-}
+}
+
+STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint)
+{
+ stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info,codepoint));
+}
STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint)
{
@@ -2508,7 +3797,7 @@ STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, uns
STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
{
return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff);
-}
+}
STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint)
{
@@ -2521,7 +3810,7 @@ STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned ch
//
// This is SUPER-CRAPPY packing to keep source code small
-STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf)
+static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // font location (use offset=0 for plain .ttf)
float pixel_height, // height of font in pixels
unsigned char *pixels, int pw, int ph, // bitmap to be filled in
int first_char, int num_chars, // characters to bake
@@ -2530,6 +3819,7 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // fo
float scale;
int x,y,bottom_y, i;
stbtt_fontinfo f;
+ f.userdata = NULL;
if (!stbtt_InitFont(&f, data, offset))
return -1;
STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
@@ -2566,11 +3856,11 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // fo
return bottom_y;
}
-STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
+STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
{
float d3d_bias = opengl_fillrule ? 0 : -0.5f;
float ipw = 1.0f / pw, iph = 1.0f / ph;
- stbtt_bakedchar *b = chardata + char_index;
+ const stbtt_bakedchar *b = chardata + char_index;
int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f);
int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f);
@@ -2593,11 +3883,6 @@ STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int
//
#ifndef STB_RECT_PACK_VERSION
-#ifdef _MSC_VER
-#define STBTT__NOTUSED(v) (void)(v)
-#else
-#define STBTT__NOTUSED(v) (void)sizeof(v)
-#endif
typedef int stbrp_coord;
@@ -2637,7 +3922,7 @@ static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *no
con->y = 0;
con->bottom_y = 0;
STBTT__NOTUSED(nodes);
- STBTT__NOTUSED(num_nodes);
+ STBTT__NOTUSED(num_nodes);
}
static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects)
@@ -2691,6 +3976,7 @@ STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, in
spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
spc->h_oversample = 1;
spc->v_oversample = 1;
+ spc->skip_missing = 0;
stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
@@ -2716,6 +4002,11 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
spc->v_oversample = v_oversample;
}
+STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip)
+{
+ spc->skip_missing = skip;
+}
+
#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
@@ -2723,6 +4014,7 @@ static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_i
unsigned char buffer[STBTT_MAX_OVERSAMPLE];
int safe_w = w - kernel_width;
int j;
+ STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
for (j=0; j < h; ++j) {
int i;
unsigned int total;
@@ -2784,6 +4076,7 @@ static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_i
unsigned char buffer[STBTT_MAX_OVERSAMPLE];
int safe_h = h - kernel_width;
int j;
+ STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
for (j=0; j < w; ++j) {
int i;
unsigned int total;
@@ -2853,9 +4146,10 @@ static float stbtt__oversample_shift(int oversample)
}
// rects array must be big enough to accommodate all characters in the given ranges
-STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
+STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
{
int i,j,k;
+ int missing_glyph_added = 0;
k=0;
for (i=0; i < num_ranges; ++i) {
@@ -2867,13 +4161,19 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fon
int x0,y0,x1,y1;
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
int glyph = stbtt_FindGlyphIndex(info, codepoint);
- stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
- scale * spc->h_oversample,
- scale * spc->v_oversample,
- 0,0,
- &x0,&y0,&x1,&y1);
- rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
- rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
+ if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) {
+ rects[k].w = rects[k].h = 0;
+ } else {
+ stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
+ scale * spc->h_oversample,
+ scale * spc->v_oversample,
+ 0,0,
+ &x0,&y0,&x1,&y1);
+ rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
+ rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
+ if (glyph == 0)
+ missing_glyph_added = 1;
+ }
++k;
}
}
@@ -2881,10 +4181,33 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fon
return k;
}
+STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int prefilter_x, int prefilter_y, float *sub_x, float *sub_y, int glyph)
+{
+ stbtt_MakeGlyphBitmapSubpixel(info,
+ output,
+ out_w - (prefilter_x - 1),
+ out_h - (prefilter_y - 1),
+ out_stride,
+ scale_x,
+ scale_y,
+ shift_x,
+ shift_y,
+ glyph);
+
+ if (prefilter_x > 1)
+ stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x);
+
+ if (prefilter_y > 1)
+ stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y);
+
+ *sub_x = stbtt__oversample_shift(prefilter_x);
+ *sub_y = stbtt__oversample_shift(prefilter_y);
+}
+
// rects array must be big enough to accommodate all characters in the given ranges
-STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
+STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
{
- int i,j,k, return_value = 1;
+ int i,j,k, missing_glyph = -1, return_value = 1;
// save current values
int old_h_over = spc->h_oversample;
@@ -2903,7 +4226,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt
sub_y = stbtt__oversample_shift(spc->v_oversample);
for (j=0; j < ranges[i].num_chars; ++j) {
stbrp_rect *r = &rects[k];
- if (r->was_packed) {
+ if (r->was_packed && r->w != 0 && r->h != 0) {
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
int advance, lsb, x0,y0,x1,y1;
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
@@ -2949,6 +4272,13 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt
bc->yoff = (float) y0 * recip_v + sub_y;
bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
+
+ if (glyph == 0)
+ missing_glyph = j;
+ } else if (spc->skip_missing) {
+ return_value = 0;
+ } else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) {
+ ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph];
} else {
return_value = 0; // if any fail, report failure
}
@@ -2969,7 +4299,7 @@ STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect
stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects);
}
-STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
+STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
{
stbtt_fontinfo info;
int i,j,n, return_value = 1;
@@ -2987,24 +4317,25 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd
n = 0;
for (i=0; i < num_ranges; ++i)
n += ranges[i].num_chars;
-
+
rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
if (rects == NULL)
return 0;
+ info.userdata = spc->user_allocator_context;
stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
stbtt_PackFontRangesPackRects(spc, rects, n);
-
+
return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects);
STBTT_free(rects, spc->user_allocator_context);
return return_value;
}
-STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size,
+STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size,
int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range)
{
stbtt_pack_range range;
@@ -3016,10 +4347,23 @@ STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontda
return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
}
-STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
+STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap)
+{
+ int i_ascent, i_descent, i_lineGap;
+ float scale;
+ stbtt_fontinfo info;
+ stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index));
+ scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size);
+ stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap);
+ *ascent = (float) i_ascent * scale;
+ *descent = (float) i_descent * scale;
+ *lineGap = (float) i_lineGap * scale;
+}
+
+STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
{
float ipw = 1.0f / pw, iph = 1.0f / ph;
- stbtt_packedchar *b = chardata + char_index;
+ const stbtt_packedchar *b = chardata + char_index;
if (align_to_integer) {
float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f);
@@ -3043,6 +4387,385 @@ STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, i
*xpos += b->xadvance;
}
+//////////////////////////////////////////////////////////////////////////////
+//
+// sdf computation
+//
+
+#define STBTT_min(a,b) ((a) < (b) ? (a) : (b))
+#define STBTT_max(a,b) ((a) < (b) ? (b) : (a))
+
+static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q1[2], float q2[2], float hits[2][2])
+{
+ float q0perp = q0[1]*ray[0] - q0[0]*ray[1];
+ float q1perp = q1[1]*ray[0] - q1[0]*ray[1];
+ float q2perp = q2[1]*ray[0] - q2[0]*ray[1];
+ float roperp = orig[1]*ray[0] - orig[0]*ray[1];
+
+ float a = q0perp - 2*q1perp + q2perp;
+ float b = q1perp - q0perp;
+ float c = q0perp - roperp;
+
+ float s0 = 0., s1 = 0.;
+ int num_s = 0;
+
+ if (a != 0.0) {
+ float discr = b*b - a*c;
+ if (discr > 0.0) {
+ float rcpna = -1 / a;
+ float d = (float) STBTT_sqrt(discr);
+ s0 = (b+d) * rcpna;
+ s1 = (b-d) * rcpna;
+ if (s0 >= 0.0 && s0 <= 1.0)
+ num_s = 1;
+ if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) {
+ if (num_s == 0) s0 = s1;
+ ++num_s;
+ }
+ }
+ } else {
+ // 2*b*s + c = 0
+ // s = -c / (2*b)
+ s0 = c / (-2 * b);
+ if (s0 >= 0.0 && s0 <= 1.0)
+ num_s = 1;
+ }
+
+ if (num_s == 0)
+ return 0;
+ else {
+ float rcp_len2 = 1 / (ray[0]*ray[0] + ray[1]*ray[1]);
+ float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2;
+
+ float q0d = q0[0]*rayn_x + q0[1]*rayn_y;
+ float q1d = q1[0]*rayn_x + q1[1]*rayn_y;
+ float q2d = q2[0]*rayn_x + q2[1]*rayn_y;
+ float rod = orig[0]*rayn_x + orig[1]*rayn_y;
+
+ float q10d = q1d - q0d;
+ float q20d = q2d - q0d;
+ float q0rd = q0d - rod;
+
+ hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d;
+ hits[0][1] = a*s0+b;
+
+ if (num_s > 1) {
+ hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d;
+ hits[1][1] = a*s1+b;
+ return 2;
+ } else {
+ return 1;
+ }
+ }
+}
+
+static int equal(float *a, float *b)
+{
+ return (a[0] == b[0] && a[1] == b[1]);
+}
+
+static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts)
+{
+ int i;
+ float orig[2], ray[2] = { 1, 0 };
+ float y_frac;
+ int winding = 0;
+
+ // make sure y never passes through a vertex of the shape
+ y_frac = (float) STBTT_fmod(y, 1.0f);
+ if (y_frac < 0.01f)
+ y += 0.01f;
+ else if (y_frac > 0.99f)
+ y -= 0.01f;
+
+ orig[0] = x;
+ orig[1] = y;
+
+ // test a ray from (-infinity,y) to (x,y)
+ for (i=0; i < nverts; ++i) {
+ if (verts[i].type == STBTT_vline) {
+ int x0 = (int) verts[i-1].x, y0 = (int) verts[i-1].y;
+ int x1 = (int) verts[i ].x, y1 = (int) verts[i ].y;
+ if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
+ float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
+ if (x_inter < x)
+ winding += (y0 < y1) ? 1 : -1;
+ }
+ }
+ if (verts[i].type == STBTT_vcurve) {
+ int x0 = (int) verts[i-1].x , y0 = (int) verts[i-1].y ;
+ int x1 = (int) verts[i ].cx, y1 = (int) verts[i ].cy;
+ int x2 = (int) verts[i ].x , y2 = (int) verts[i ].y ;
+ int ax = STBTT_min(x0,STBTT_min(x1,x2)), ay = STBTT_min(y0,STBTT_min(y1,y2));
+ int by = STBTT_max(y0,STBTT_max(y1,y2));
+ if (y > ay && y < by && x > ax) {
+ float q0[2],q1[2],q2[2];
+ float hits[2][2];
+ q0[0] = (float)x0;
+ q0[1] = (float)y0;
+ q1[0] = (float)x1;
+ q1[1] = (float)y1;
+ q2[0] = (float)x2;
+ q2[1] = (float)y2;
+ if (equal(q0,q1) || equal(q1,q2)) {
+ x0 = (int)verts[i-1].x;
+ y0 = (int)verts[i-1].y;
+ x1 = (int)verts[i ].x;
+ y1 = (int)verts[i ].y;
+ if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
+ float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
+ if (x_inter < x)
+ winding += (y0 < y1) ? 1 : -1;
+ }
+ } else {
+ int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits);
+ if (num_hits >= 1)
+ if (hits[0][0] < 0)
+ winding += (hits[0][1] < 0 ? -1 : 1);
+ if (num_hits >= 2)
+ if (hits[1][0] < 0)
+ winding += (hits[1][1] < 0 ? -1 : 1);
+ }
+ }
+ }
+ }
+ return winding;
+}
+
+static float stbtt__cuberoot( float x )
+{
+ if (x<0)
+ return -(float) STBTT_pow(-x,1.0f/3.0f);
+ else
+ return (float) STBTT_pow( x,1.0f/3.0f);
+}
+
+// x^3 + a*x^2 + b*x + c = 0
+static int stbtt__solve_cubic(float a, float b, float c, float* r)
+{
+ float s = -a / 3;
+ float p = b - a*a / 3;
+ float q = a * (2*a*a - 9*b) / 27 + c;
+ float p3 = p*p*p;
+ float d = q*q + 4*p3 / 27;
+ if (d >= 0) {
+ float z = (float) STBTT_sqrt(d);
+ float u = (-q + z) / 2;
+ float v = (-q - z) / 2;
+ u = stbtt__cuberoot(u);
+ v = stbtt__cuberoot(v);
+ r[0] = s + u + v;
+ return 1;
+ } else {
+ float u = (float) STBTT_sqrt(-p/3);
+ float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3; // p3 must be negative, since d is negative
+ float m = (float) STBTT_cos(v);
+ float n = (float) STBTT_cos(v-3.141592/2)*1.732050808f;
+ r[0] = s + u * 2 * m;
+ r[1] = s - u * (m + n);
+ r[2] = s - u * (m - n);
+
+ //STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f); // these asserts may not be safe at all scales, though they're in bezier t parameter units so maybe?
+ //STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f);
+ //STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f);
+ return 3;
+ }
+}
+
+STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff)
+{
+ float scale_x = scale, scale_y = scale;
+ int ix0,iy0,ix1,iy1;
+ int w,h;
+ unsigned char *data;
+
+ if (scale == 0) return NULL;
+
+ stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1);
+
+ // if empty, return NULL
+ if (ix0 == ix1 || iy0 == iy1)
+ return NULL;
+
+ ix0 -= padding;
+ iy0 -= padding;
+ ix1 += padding;
+ iy1 += padding;
+
+ w = (ix1 - ix0);
+ h = (iy1 - iy0);
+
+ if (width ) *width = w;
+ if (height) *height = h;
+ if (xoff ) *xoff = ix0;
+ if (yoff ) *yoff = iy0;
+
+ // invert for y-downwards bitmaps
+ scale_y = -scale_y;
+
+ {
+ int x,y,i,j;
+ float *precompute;
+ stbtt_vertex *verts;
+ int num_verts = stbtt_GetGlyphShape(info, glyph, &verts);
+ data = (unsigned char *) STBTT_malloc(w * h, info->userdata);
+ precompute = (float *) STBTT_malloc(num_verts * sizeof(float), info->userdata);
+
+ for (i=0,j=num_verts-1; i < num_verts; j=i++) {
+ if (verts[i].type == STBTT_vline) {
+ float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
+ float x1 = verts[j].x*scale_x, y1 = verts[j].y*scale_y;
+ float dist = (float) STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
+ precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist;
+ } else if (verts[i].type == STBTT_vcurve) {
+ float x2 = verts[j].x *scale_x, y2 = verts[j].y *scale_y;
+ float x1 = verts[i].cx*scale_x, y1 = verts[i].cy*scale_y;
+ float x0 = verts[i].x *scale_x, y0 = verts[i].y *scale_y;
+ float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
+ float len2 = bx*bx + by*by;
+ if (len2 != 0.0f)
+ precompute[i] = 1.0f / (bx*bx + by*by);
+ else
+ precompute[i] = 0.0f;
+ } else
+ precompute[i] = 0.0f;
+ }
+
+ for (y=iy0; y < iy1; ++y) {
+ for (x=ix0; x < ix1; ++x) {
+ float val;
+ float min_dist = 999999.0f;
+ float sx = (float) x + 0.5f;
+ float sy = (float) y + 0.5f;
+ float x_gspace = (sx / scale_x);
+ float y_gspace = (sy / scale_y);
+
+ int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts, verts); // @OPTIMIZE: this could just be a rasterization, but needs to be line vs. non-tesselated curves so a new path
+
+ for (i=0; i < num_verts; ++i) {
+ float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
+
+ if (verts[i].type == STBTT_vline && precompute[i] != 0.0f) {
+ float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y;
+
+ float dist,dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
+ if (dist2 < min_dist*min_dist)
+ min_dist = (float) STBTT_sqrt(dist2);
+
+ // coarse culling against bbox
+ //if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist &&
+ // sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist)
+ dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i];
+ STBTT_assert(i != 0);
+ if (dist < min_dist) {
+ // check position along line
+ // x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0)
+ // minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy)
+ float dx = x1-x0, dy = y1-y0;
+ float px = x0-sx, py = y0-sy;
+ // minimize (px+t*dx)^2 + (py+t*dy)^2 = px*px + 2*px*dx*t + t^2*dx*dx + py*py + 2*py*dy*t + t^2*dy*dy
+ // derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve
+ float t = -(px*dx + py*dy) / (dx*dx + dy*dy);
+ if (t >= 0.0f && t <= 1.0f)
+ min_dist = dist;
+ }
+ } else if (verts[i].type == STBTT_vcurve) {
+ float x2 = verts[i-1].x *scale_x, y2 = verts[i-1].y *scale_y;
+ float x1 = verts[i ].cx*scale_x, y1 = verts[i ].cy*scale_y;
+ float box_x0 = STBTT_min(STBTT_min(x0,x1),x2);
+ float box_y0 = STBTT_min(STBTT_min(y0,y1),y2);
+ float box_x1 = STBTT_max(STBTT_max(x0,x1),x2);
+ float box_y1 = STBTT_max(STBTT_max(y0,y1),y2);
+ // coarse culling against bbox to avoid computing cubic unnecessarily
+ if (sx > box_x0-min_dist && sx < box_x1+min_dist && sy > box_y0-min_dist && sy < box_y1+min_dist) {
+ int num=0;
+ float ax = x1-x0, ay = y1-y0;
+ float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
+ float mx = x0 - sx, my = y0 - sy;
+ float res[3] = {0.f,0.f,0.f};
+ float px,py,t,it,dist2;
+ float a_inv = precompute[i];
+ if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula
+ float a = 3*(ax*bx + ay*by);
+ float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by);
+ float c = mx*ax+my*ay;
+ if (a == 0.0) { // if a is 0, it's linear
+ if (b != 0.0) {
+ res[num++] = -c/b;
+ }
+ } else {
+ float discriminant = b*b - 4*a*c;
+ if (discriminant < 0)
+ num = 0;
+ else {
+ float root = (float) STBTT_sqrt(discriminant);
+ res[0] = (-b - root)/(2*a);
+ res[1] = (-b + root)/(2*a);
+ num = 2; // don't bother distinguishing 1-solution case, as code below will still work
+ }
+ }
+ } else {
+ float b = 3*(ax*bx + ay*by) * a_inv; // could precompute this as it doesn't depend on sample point
+ float c = (2*(ax*ax + ay*ay) + (mx*bx+my*by)) * a_inv;
+ float d = (mx*ax+my*ay) * a_inv;
+ num = stbtt__solve_cubic(b, c, d, res);
+ }
+ dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
+ if (dist2 < min_dist*min_dist)
+ min_dist = (float) STBTT_sqrt(dist2);
+
+ if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) {
+ t = res[0], it = 1.0f - t;
+ px = it*it*x0 + 2*t*it*x1 + t*t*x2;
+ py = it*it*y0 + 2*t*it*y1 + t*t*y2;
+ dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
+ if (dist2 < min_dist * min_dist)
+ min_dist = (float) STBTT_sqrt(dist2);
+ }
+ if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) {
+ t = res[1], it = 1.0f - t;
+ px = it*it*x0 + 2*t*it*x1 + t*t*x2;
+ py = it*it*y0 + 2*t*it*y1 + t*t*y2;
+ dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
+ if (dist2 < min_dist * min_dist)
+ min_dist = (float) STBTT_sqrt(dist2);
+ }
+ if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) {
+ t = res[2], it = 1.0f - t;
+ px = it*it*x0 + 2*t*it*x1 + t*t*x2;
+ py = it*it*y0 + 2*t*it*y1 + t*t*y2;
+ dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
+ if (dist2 < min_dist * min_dist)
+ min_dist = (float) STBTT_sqrt(dist2);
+ }
+ }
+ }
+ }
+ if (winding == 0)
+ min_dist = -min_dist; // if outside the shape, value is negative
+ val = onedge_value + pixel_dist_scale * min_dist;
+ if (val < 0)
+ val = 0;
+ else if (val > 255)
+ val = 255;
+ data[(y-iy0)*w+(x-ix0)] = (unsigned char) val;
+ }
+ }
+ STBTT_free(precompute, info->userdata);
+ STBTT_free(verts, info->userdata);
+ }
+ return data;
+}
+
+STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff)
+{
+ return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff);
+}
+
+STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata)
+{
+ STBTT_free(bitmap, userdata);
+}
//////////////////////////////////////////////////////////////////////////////
//
@@ -3050,7 +4773,7 @@ STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, i
//
// check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string
-static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2)
+static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2)
{
stbtt_int32 i=0;
@@ -3089,9 +4812,9 @@ static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8
return i;
}
-STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2)
+static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2)
{
- return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2);
+ return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2);
}
// returns results in whatever encoding you request... but note that 2-byte encodings
@@ -3147,7 +4870,7 @@ static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name,
return 1;
} else if (matchlen < nlen && name[matchlen] == ' ') {
++matchlen;
- if (stbtt_CompareUTF8toUTF16_bigendian((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen))
+ if (stbtt_CompareUTF8toUTF16_bigendian_internal((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen))
return 1;
}
} else {
@@ -3193,7 +4916,7 @@ static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *nam
return 0;
}
-STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags)
+static int stbtt_FindMatchingFont_internal(unsigned char *font_collection, char *name_utf8, stbtt_int32 flags)
{
stbtt_int32 i;
for (i=0;;++i) {
@@ -3204,11 +4927,71 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const
}
}
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+
+STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset,
+ float pixel_height, unsigned char *pixels, int pw, int ph,
+ int first_char, int num_chars, stbtt_bakedchar *chardata)
+{
+ return stbtt_BakeFontBitmap_internal((unsigned char *) data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata);
+}
+
+STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index)
+{
+ return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index);
+}
+
+STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data)
+{
+ return stbtt_GetNumberOfFonts_internal((unsigned char *) data);
+}
+
+STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset)
+{
+ return stbtt_InitFont_internal(info, (unsigned char *) data, offset);
+}
+
+STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags)
+{
+ return stbtt_FindMatchingFont_internal((unsigned char *) fontdata, (char *) name, flags);
+}
+
+STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2)
+{
+ return stbtt_CompareUTF8toUTF16_bigendian_internal((char *) s1, len1, (char *) s2, len2);
+}
+
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
#endif // STB_TRUETYPE_IMPLEMENTATION
// FULL VERSION HISTORY
//
+// 1.25 (2021-07-11) many fixes
+// 1.24 (2020-02-05) fix warning
+// 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS)
+// 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined
+// 1.21 (2019-02-25) fix warning
+// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
+// 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod
+// 1.18 (2018-01-29) add missing function
+// 1.17 (2017-07-23) make more arguments const; doc fix
+// 1.16 (2017-07-12) SDF support
+// 1.15 (2017-03-03) make more arguments const
+// 1.14 (2017-01-16) num-fonts-in-TTC function
+// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts
+// 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual
+// 1.11 (2016-04-02) fix unused-variable warning
+// 1.10 (2016-04-02) allow user-defined fabs() replacement
+// fix memory leak if fontsize=0.0
+// fix warning from duplicate typedef
+// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges
// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
// allow PackFontRanges to pack and render in separate phases;
@@ -3250,3 +5033,45 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const
// 0.2 (2009-03-11) Fix unsigned/signed char warnings
// 0.1 (2009-03-09) First public release
//
+
+/*
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2017 Sean Barrett
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+software, either in source code form or as a compiled binary, for any purpose,
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this
+software dedicate any and all copyright interest in the software to the public
+domain. We make this dedication for the benefit of the public at large and to
+the detriment of our heirs and successors. We intend this dedication to be an
+overt act of relinquishment in perpetuity of all present and future rights to
+this software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------------------
+*/
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index a21fde0e1d4..05f93047809 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -596,6 +596,48 @@ int vidconsole_select_font(struct udevice *dev, const char *name, uint size)
return ops->select_font(dev, name, size);
}
+int vidconsole_measure(struct udevice *dev, const char *name, uint size,
+ const char *text, struct vidconsole_bbox *bbox)
+{
+ struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
+ struct vidconsole_ops *ops = vidconsole_get_ops(dev);
+ int ret;
+
+ if (ops->select_font) {
+ ret = ops->measure(dev, name, size, text, bbox);
+ if (ret != -ENOSYS)
+ return ret;
+ }
+
+ bbox->valid = true;
+ bbox->x0 = 0;
+ bbox->y0 = 0;
+ bbox->x1 = priv->x_charsize * strlen(text);
+ bbox->y1 = priv->y_charsize;
+
+ return 0;
+}
+
+void vidconsole_push_colour(struct udevice *dev, enum colour_idx fg,
+ enum colour_idx bg, struct vidconsole_colour *old)
+{
+ struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+
+ old->colour_fg = vid_priv->colour_fg;
+ old->colour_bg = vid_priv->colour_bg;
+
+ vid_priv->colour_fg = video_index_to_colour(vid_priv, fg);
+ vid_priv->colour_bg = video_index_to_colour(vid_priv, bg);
+}
+
+void vidconsole_pop_colour(struct udevice *dev, struct vidconsole_colour *old)
+{
+ struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+
+ vid_priv->colour_fg = old->colour_fg;
+ vid_priv->colour_bg = old->colour_bg;
+}
+
/* Set up the number of rows and colours (rotated drivers override this) */
static int vidconsole_pre_probe(struct udevice *dev)
{
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index 1b66a8061a7..95e874b770b 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -142,6 +142,58 @@ int video_reserve(ulong *addrp)
return 0;
}
+int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
+ int yend, u32 colour)
+{
+ struct video_priv *priv = dev_get_uclass_priv(dev);
+ void *start, *line;
+ int pixels = xend - xstart;
+ int row, i, ret;
+
+ start = priv->fb + ystart * priv->line_length;
+ start += xstart * VNBYTES(priv->bpix);
+ line = start;
+ for (row = ystart; row < yend; row++) {
+ switch (priv->bpix) {
+ case VIDEO_BPP8: {
+ u8 *dst = line;
+
+ if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
+ for (i = 0; i < pixels; i++)
+ *dst++ = colour;
+ }
+ break;
+ }
+ case VIDEO_BPP16: {
+ u16 *dst = line;
+
+ if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
+ for (i = 0; i < pixels; i++)
+ *dst++ = colour;
+ }
+ break;
+ }
+ case VIDEO_BPP32: {
+ u32 *dst = line;
+
+ if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
+ for (i = 0; i < pixels; i++)
+ *dst++ = colour;
+ }
+ break;
+ }
+ default:
+ return -ENOSYS;
+ }
+ line += priv->line_length;
+ }
+ ret = video_sync_copy(dev, start, line);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
int video_fill(struct udevice *dev, u32 colour)
{
struct video_priv *priv = dev_get_uclass_priv(dev);
@@ -208,7 +260,7 @@ static const struct vid_rgb colours[VID_COLOUR_COUNT] = {
{ 0xff, 0xff, 0xff }, /* white */
};
-u32 video_index_to_colour(struct video_priv *priv, unsigned int idx)
+u32 video_index_to_colour(struct video_priv *priv, enum colour_idx idx)
{
switch (priv->bpix) {
case VIDEO_BPP16:
diff --git a/env/Kconfig b/env/Kconfig
index 7342397e169..13e32104b4c 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -662,6 +662,18 @@ config SYS_MMC_ENV_PART
partition 0 or the first boot partition, which is 1 or some other defined
partition.
+config USE_ENV_MMC_PARTITION
+ bool "use the mmc environment partition name"
+ depends on ENV_IS_IN_MMC
+
+config ENV_MMC_PARTITION
+ string "mmc environment partition name"
+ depends on USE_ENV_MMC_PARTITION
+ help
+ MMC partition name used to save environment variables.
+ If this variable is unset, u-boot will try to get the env partition name
+ from the device-tree's /config node.
+
config ENV_MMC_USE_DT
bool "Read partition name and offset in DT"
depends on ENV_IS_IN_MMC && OF_CONTROL
diff --git a/env/mmc.c b/env/mmc.c
index 7a5836ad66c..cb14bbb58f1 100644
--- a/env/mmc.c
+++ b/env/mmc.c
@@ -114,8 +114,13 @@ static inline s64 mmc_offset(struct mmc *mmc, int copy)
if (IS_ENABLED(CONFIG_SYS_MMC_ENV_PART))
hwpart = mmc_get_env_part(mmc);
+#if defined(CONFIG_ENV_MMC_PARTITION)
+ str = CONFIG_ENV_MMC_PARTITION;
+#else
/* look for the partition in mmc CONFIG_SYS_MMC_ENV_DEV */
str = ofnode_conf_read_str(dt_prop.partition);
+#endif
+
if (str) {
/* try to place the environment at end of the partition */
err = mmc_offset_try_partition(str, copy, &val);
diff --git a/fs/fs.c b/fs/fs.c
index 8324b4a22f2..2b815b1db0f 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -13,6 +13,7 @@
#include <env.h>
#include <lmb.h>
#include <log.h>
+#include <malloc.h>
#include <mapmem.h>
#include <part.h>
#include <ext4fs.h>
@@ -26,6 +27,7 @@
#include <asm/io.h>
#include <div64.h>
#include <linux/math64.h>
+#include <linux/sizes.h>
#include <efi_loader.h>
#include <squashfs.h>
#include <erofs.h>
@@ -1008,3 +1010,59 @@ int do_fs_types(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
puts("\n");
return CMD_RET_SUCCESS;
}
+
+int fs_read_alloc(const char *fname, ulong size, uint align, void **bufp)
+{
+ loff_t bytes_read;
+ ulong addr;
+ char *buf;
+ int ret;
+
+ buf = memalign(align, size + 1);
+ if (!buf)
+ return log_msg_ret("buf", -ENOMEM);
+ addr = map_to_sysmem(buf);
+
+ ret = fs_read(fname, addr, 0, size, &bytes_read);
+ if (ret) {
+ free(buf);
+ return log_msg_ret("read", ret);
+ }
+ if (size != bytes_read)
+ return log_msg_ret("bread", -EIO);
+ buf[size] = '\0';
+
+ *bufp = buf;
+
+ return 0;
+}
+
+int fs_load_alloc(const char *ifname, const char *dev_part_str,
+ const char *fname, ulong max_size, ulong align, void **bufp,
+ ulong *sizep)
+{
+ loff_t size;
+ void *buf;
+ int ret;
+
+ if (fs_set_blk_dev(ifname, dev_part_str, FS_TYPE_ANY))
+ return log_msg_ret("set", -ENOMEDIUM);
+
+ ret = fs_size(fname, &size);
+ if (ret)
+ return log_msg_ret("sz", -ENOENT);
+
+ if (size >= (max_size ?: SZ_1G))
+ return log_msg_ret("sz", -E2BIG);
+
+ if (fs_set_blk_dev(ifname, dev_part_str, FS_TYPE_ANY))
+ return log_msg_ret("set", -ENOMEDIUM);
+
+ ret = fs_read_alloc(fname, size, align, &buf);
+ if (ret)
+ return log_msg_ret("al", ret);
+ *sizep = size;
+ *bufp = buf;
+
+ return 0;
+}
diff --git a/include/configs/arbel.h b/include/configs/arbel.h
index 8e27fb52a1c..891257bc93a 100644
--- a/include/configs/arbel.h
+++ b/include/configs/arbel.h
@@ -7,12 +7,13 @@
#define __CONFIG_ARBEL_H
#define CFG_SYS_SDRAM_BASE 0x0
-#define CFG_SYS_BOOTMAPSZ (20 << 20)
+#define CFG_SYS_BOOTMAPSZ (30 << 20)
+#define CFG_SYS_BOOTM_LEN (20 << 20)
#define CFG_SYS_INIT_RAM_ADDR CFG_SYS_SDRAM_BASE
#define CFG_SYS_INIT_RAM_SIZE 0x8000
/* Default environemnt variables */
-#define CFG_EXTRA_ENV_SETTINGS "uimage_flash_addr=80200000\0" \
+#define CFG_EXTRA_ENV_SETTINGS "uimage_flash_addr=80400000\0" \
"stdin=serial\0" \
"stdout=serial\0" \
"stderr=serial\0" \
diff --git a/include/configs/imx8mm_beacon.h b/include/configs/imx8mm_beacon.h
index d85ae21e231..fa20651d2df 100644
--- a/include/configs/imx8mm_beacon.h
+++ b/include/configs/imx8mm_beacon.h
@@ -9,8 +9,17 @@
#include <linux/sizes.h>
#include <asm/arch/imx-regs.h>
+#define UBOOT_ITB_OFFSET 0x57C00
+#define FSPI_CONF_BLOCK_SIZE 0x1000
+#define UBOOT_ITB_OFFSET_FSPI \
+ (UBOOT_ITB_OFFSET + FSPI_CONF_BLOCK_SIZE)
+#ifdef CONFIG_FSPI_CONF_HEADER
+#define CFG_SYS_UBOOT_BASE \
+ (QSPI0_AMBA_BASE + UBOOT_ITB_OFFSET_FSPI)
+#else
#define CFG_SYS_UBOOT_BASE \
(QSPI0_AMBA_BASE + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512)
+#endif
#ifdef CONFIG_SPL_BUILD
/* malloc f used before GD_FLG_FULL_MALLOC_INIT set */
@@ -19,56 +28,6 @@
#endif
-/* Initial environment variables */
-#define CFG_EXTRA_ENV_SETTINGS \
- "script=boot.scr\0" \
- "image=Image\0" \
- "console=ttymxc1,115200\0" \
- "fdt_addr=0x43000000\0" \
- "boot_fit=try\0" \
- "fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \
- "initrd_addr=0x43800000\0" \
- "mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV) "\0" \
- "mmcpart=1\0" \
- "finduuid=part uuid mmc ${mmcdev}:2 uuid\0" \
- "mmcautodetect=yes\0" \
- "mmcargs=setenv bootargs console=${console},${baudrate}" \
- " root=PARTUUID=${uuid} rootwait rw ${mtdparts} ${optargs}\0" \
- "loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr}" \
- " ${script};\0" \
- "bootscript=echo Running bootscript from mmc ...; " \
- "source\0" \
- "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
- "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
- "mmcboot=echo Booting from mmc ...; " \
- "run finduuid; " \
- "run mmcargs; " \
- "if run loadfdt; then " \
- "booti ${loadaddr} - ${fdt_addr}; " \
- "else " \
- "echo WARN: Cannot load the DT; " \
- "fi; " \
- "netargs=setenv bootargs console=${console} " \
- "root=/dev/nfs " \
- "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
- "netboot=echo Booting from net ...; " \
- "run netargs; " \
- "if test ${ip_dyn} = yes; then " \
- "setenv get_cmd dhcp; " \
- "else " \
- "setenv get_cmd tftp; " \
- "fi; " \
- "${get_cmd} ${loadaddr} ${image}; " \
- "if test ${boot_fit} = yes || test ${boot_fit} = try; then " \
- "bootm ${loadaddr}; " \
- "else " \
- "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \
- "booti ${loadaddr} - ${fdt_addr}; " \
- "else " \
- "echo WARN: Cannot load the DT; " \
- "fi; " \
- "fi;\0"
-
/* Link Definitions */
#define CFG_SYS_INIT_RAM_ADDR 0x40000000
diff --git a/include/configs/imx8mm_venice.h b/include/configs/imx8mm_venice.h
index 5579a05d165..046d5685d04 100644
--- a/include/configs/imx8mm_venice.h
+++ b/include/configs/imx8mm_venice.h
@@ -26,16 +26,16 @@
func(DHCP, dhcp, na)
#include <config_distro_bootcmd.h>
#define CFG_EXTRA_ENV_SETTINGS \
- "splblk=0x42\0" \
BOOTENV
#define CFG_SYS_INIT_RAM_ADDR 0x40000000
#define CFG_SYS_INIT_RAM_SIZE SZ_2M
+/* SDRAM configuration: 4GiB */
#define CFG_SYS_SDRAM_BASE 0x40000000
-
-/* SDRAM configuration */
-#define PHYS_SDRAM 0x40000000
-#define PHYS_SDRAM_SIZE SZ_4G
+#define PHYS_SDRAM 0x40000000
+#define PHYS_SDRAM_SIZE 0x80000000 /* 2 GB */
+#define PHYS_SDRAM_2 0xC0000000
+#define PHYS_SDRAM_2_SIZE 0x80000000 /* 2 GB */
#endif
diff --git a/include/configs/imx8mn_beacon.h b/include/configs/imx8mn_beacon.h
index 1880d0311e4..699e2090449 100644
--- a/include/configs/imx8mn_beacon.h
+++ b/include/configs/imx8mn_beacon.h
@@ -12,67 +12,6 @@
#define CFG_SYS_UBOOT_BASE \
(QSPI0_AMBA_BASE + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512)
-/* Initial environment variables */
-#define CFG_EXTRA_ENV_SETTINGS \
- "script=boot.scr\0" \
- "image=Image\0" \
- "ramdiskimage=rootfs.cpio.uboot\0" \
- "console=ttymxc1,115200\0" \
- "fdt_addr=0x43000000\0" \
- "ramdisk_addr=0x44000000\0" \
- "boot_fdt=try\0" \
- "fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \
- "initrd_addr=0x43800000\0" \
- "mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV) "\0" \
- "mmcpart=1\0" \
- "finduuid=part uuid mmc ${mmcdev}:2 uuid\0" \
- "mmcautodetect=yes\0" \
- "mmcargs=setenv bootargs console=${console} " \
- " root=PARTUUID=${uuid} rootwait rw ${mtdparts} ${optargs}\0" \
- "ramargs=setenv bootargs console=${console} root=/dev/ram rw " \
- " ${optargs}\0" \
- "loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
- "bootscript=echo Running bootscript from mmc ...; " \
- "source\0" \
- "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
- "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
- "loadramdisk=load mmc ${mmcdev} ${ramdisk_addr} ${ramdiskimage}\0"\
- "mmcboot=echo Booting from mmc ...; " \
- "run finduuid; run mmcargs; " \
- "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
- "if run loadfdt; then " \
- "booti ${loadaddr} - ${fdt_addr}; " \
- "else " \
- "echo WARN: Cannot load the DT; " \
- "fi; " \
- "else " \
- "echo wait for boot; " \
- "fi;\0" \
- "netargs=setenv bootargs console=${console} " \
- "root=/dev/nfs " \
- "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
- "netboot=echo Booting from net ...; " \
- "run netargs; " \
- "if test ${ip_dyn} = yes; then " \
- "setenv get_cmd dhcp; " \
- "else " \
- "setenv get_cmd tftp; " \
- "fi; " \
- "${get_cmd} ${loadaddr} ${image}; " \
- "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
- "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \
- "booti ${loadaddr} - ${fdt_addr}; " \
- "else " \
- "echo WARN: Cannot load the DT; " \
- "fi; " \
- "else " \
- "booti; " \
- "fi;\0" \
- "ramboot=echo Booting from RAMdisk...; "\
- "run loadimage; run loadfdt; fdt addr $fdt_addr; "\
- "run loadramdisk; run ramargs; " \
- "booti ${loadaddr} ${ramdisk_addr} ${fdt_addr} ${optargs}\0"
-
/* Link Definitions */
#define CFG_SYS_INIT_RAM_ADDR 0x40000000
diff --git a/include/configs/imx8mn_venice.h b/include/configs/imx8mn_venice.h
index 80c2df9f30f..1cc054a82ba 100644
--- a/include/configs/imx8mn_venice.h
+++ b/include/configs/imx8mn_venice.h
@@ -20,16 +20,16 @@
func(DHCP, dhcp, na)
#include <config_distro_bootcmd.h>
#define CFG_EXTRA_ENV_SETTINGS \
- "splblk=0x40\0" \
BOOTENV
#define CFG_SYS_INIT_RAM_ADDR 0x40000000
#define CFG_SYS_INIT_RAM_SIZE SZ_2M
+/* SDRAM configuration: 4GiB */
#define CFG_SYS_SDRAM_BASE 0x40000000
-
-/* SDRAM configuration */
-#define PHYS_SDRAM 0x40000000
-#define PHYS_SDRAM_SIZE SZ_4G
+#define PHYS_SDRAM 0x40000000
+#define PHYS_SDRAM_SIZE 0x80000000 /* 2 GB */
+#define PHYS_SDRAM_2 0xC0000000
+#define PHYS_SDRAM_2_SIZE 0x80000000 /* 2 GB */
#endif
diff --git a/include/configs/imx8mp_venice.h b/include/configs/imx8mp_venice.h
index 4b32d5a77ef..47413ecd7fb 100644
--- a/include/configs/imx8mp_venice.h
+++ b/include/configs/imx8mp_venice.h
@@ -20,16 +20,16 @@
func(DHCP, dhcp, na)
#include <config_distro_bootcmd.h>
#define CFG_EXTRA_ENV_SETTINGS \
- "splblk=0x40\0" \
BOOTENV
#define CFG_SYS_INIT_RAM_ADDR 0x40000000
#define CFG_SYS_INIT_RAM_SIZE SZ_2M
+/* SDRAM configuration: 4GiB */
#define CFG_SYS_SDRAM_BASE 0x40000000
-
-/* SDRAM configuration */
-#define PHYS_SDRAM 0x40000000
-#define PHYS_SDRAM_SIZE SZ_4G
+#define PHYS_SDRAM 0x40000000
+#define PHYS_SDRAM_SIZE 0x80000000 /* 2 GB */
+#define PHYS_SDRAM_2 0xC0000000
+#define PHYS_SDRAM_2_SIZE 0x80000000 /* 2 GB */
#endif
diff --git a/include/configs/poleg.h b/include/configs/poleg.h
index c3f1d3393cb..1e96e838be4 100644
--- a/include/configs/poleg.h
+++ b/include/configs/poleg.h
@@ -27,6 +27,8 @@
"eth1addr=00:00:F7:A0:00:FD\0" \
"eth2addr=00:00:F7:A0:00:FE\0" \
"eth3addr=00:00:F7:A0:00:FF\0" \
+ "console=ttyS0,115200n8\0" \
+ "earlycon=uart8250,mmio32,0xf0000000\0" \
"common_bootargs=setenv bootargs earlycon=${earlycon} root=/dev/ram " \
"console=${console} mem=${mem} ramdisk_size=48000 basemac=${ethaddr}\0" \
"sd_prog=fatload mmc 0 10000000 image-bmc; cp.b 10000000 80000000 ${filesize}\0" \
diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h
index 20135f569eb..f6d326bda0d 100644
--- a/include/configs/qemu-riscv.h
+++ b/include/configs/qemu-riscv.h
@@ -11,8 +11,8 @@
#define CFG_SYS_SDRAM_BASE 0x80000000
#define RISCV_MMODE_TIMERBASE 0x2000000
+#define RISCV_MMODE_TIMEROFF 0xbff8
#define RISCV_MMODE_TIMER_FREQ 1000000
-
#define RISCV_SMODE_TIMER_FREQ 1000000
/* Environment options */
diff --git a/include/configs/sifive-unleashed.h b/include/configs/sifive-unleashed.h
index de3a0dcdd59..f208f5e20db 100644
--- a/include/configs/sifive-unleashed.h
+++ b/include/configs/sifive-unleashed.h
@@ -14,8 +14,8 @@
#define CFG_SYS_SDRAM_BASE 0x80000000
#define RISCV_MMODE_TIMERBASE 0x2000000
+#define RISCV_MMODE_TIMEROFF 0xbff8
#define RISCV_MMODE_TIMER_FREQ 1000000
-
#define RISCV_SMODE_TIMER_FREQ 1000000
/* Environment options */
diff --git a/include/configs/starfive-visionfive2.h b/include/configs/starfive-visionfive2.h
index 93dcc22d366..4ee02b8420f 100644
--- a/include/configs/starfive-visionfive2.h
+++ b/include/configs/starfive-visionfive2.h
@@ -9,6 +9,7 @@
#define _STARFIVE_VISIONFIVE2_H
#define RISCV_MMODE_TIMERBASE 0x2000000
+#define RISCV_MMODE_TIMEROFF 0xbff8
#define RISCV_MMODE_TIMER_FREQ 4000000
#define RISCV_SMODE_TIMER_FREQ 4000000
diff --git a/include/configs/th1520_lpi4a.h b/include/configs/th1520_lpi4a.h
new file mode 100644
index 00000000000..87496a52c4c
--- /dev/null
+++ b/include/configs/th1520_lpi4a.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2023 Yixun Lan <dlan@gentoo.org>
+ *
+ */
+
+#ifndef __TH1520_LPI4A_H
+#define __TH1520_LPI4A_H
+
+#include <linux/sizes.h>
+
+#define CFG_SYS_SDRAM_BASE 0x00000000
+
+#define UART_BASE 0xffe7014000
+#define UART_REG_WIDTH 32
+
+/* Environment options */
+
+#define CFG_EXTRA_ENV_SETTINGS \
+ "PS1=[LPi4A]# \0"
+
+#endif /* __TH1520_LPI4A_H */
diff --git a/include/configs/x240.h b/include/configs/x240.h
new file mode 100644
index 00000000000..3601df588d5
--- /dev/null
+++ b/include/configs/x240.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2022 Allied Telesis
+ */
+
+#ifndef __X240_H_
+#define __X240_H_
+
+#include <asm/arch/soc.h>
+
+/* additions for new ARM relocation support */
+#define CFG_SYS_SDRAM_BASE 0x200000000
+
+#define CFG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, \
+ 115200, 230400, 460800, 921600 }
+
+/* Default Env vars */
+
+#define BOOT_TARGET_DEVICES(func) \
+ func(USB, usb, 0) \
+ func(DHCP, dhcp, na)
+
+#include <config_distro_bootcmd.h>
+
+#define CFG_EXTRA_ENV_SETTINGS \
+ BOOTENV \
+ "kernel_addr_r=0x202000000\0" \
+ "fdt_addr_r=0x201000000\0" \
+ "ramdisk_addr_r=0x206000000\0" \
+ "fdtfile=marvell/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0"
+
+/*
+ * High Level Configuration Options (easy to change)
+ */
+#define CFG_SYS_TCLK 325000000
+
+#endif /* __X240_H_ */
diff --git a/include/dm/of.h b/include/dm/of.h
index fce7cef0ff6..b1c934f610d 100644
--- a/include/dm/of.h
+++ b/include/dm/of.h
@@ -63,6 +63,8 @@ struct device_node {
struct device_node *sibling;
};
+#define BAD_OF_ROOT 0xdead11e3
+
#define OF_MAX_PHANDLE_ARGS 16
/**
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 443db6252dd..0f38b3e736d 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -353,6 +353,16 @@ static inline oftree oftree_from_np(struct device_node *root)
}
/**
+ * oftree_dispose() - Dispose of an oftree
+ *
+ * This can be used to dispose of a tree that has been created (other than
+ * the control FDT which must not be disposed)
+ *
+ * @tree: Tree to dispose
+ */
+void oftree_dispose(oftree tree);
+
+/**
* ofnode_name_eq() - Check if the node name is equivalent to a given name
* ignoring the unit address
*
diff --git a/include/dm/platform_data/serial_pl01x.h b/include/dm/platform_data/serial_pl01x.h
index e3d4e308a14..811697ce5c6 100644
--- a/include/dm/platform_data/serial_pl01x.h
+++ b/include/dm/platform_data/serial_pl01x.h
@@ -20,7 +20,11 @@ enum pl01x_type {
* @skip_init: Don't attempt to change port configuration (also means @clock
* is ignored)
*/
+#include <dt-structs.h>
struct pl01x_serial_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_serial_pl01x dtplat;
+#endif
unsigned long base;
enum pl01x_type type;
unsigned int clock;
diff --git a/include/dm/platform_data/spi_pl022.h b/include/dm/platform_data/spi_pl022.h
deleted file mode 100644
index 7f74b3cbc5c..00000000000
--- a/include/dm/platform_data/spi_pl022.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * (C) Copyright 2018
- * Quentin Schulz, Bootlin, quentin.schulz@bootlin.com
- *
- * Structure for use with U_BOOT_DRVINFO for pl022 SPI devices or to use
- * in of_to_plat.
- */
-
-#ifndef __spi_pl022_h
-#define __spi_pl022_h
-
-#include <fdtdec.h>
-
-struct pl022_spi_pdata {
- fdt_addr_t addr;
- fdt_size_t size;
- unsigned int freq;
-};
-
-#endif /* __spi_pl022_h */
diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h
index 9d5cc2ddde8..3f28ce685f4 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -324,8 +324,18 @@
#define IMX8MP_CLK_CLKOUT2_SEL 317
#define IMX8MP_CLK_CLKOUT2_DIV 318
#define IMX8MP_CLK_CLKOUT2 319
-
-#define IMX8MP_CLK_END 320
+#define IMX8MP_CLK_USB_SUSP 320
+#define IMX8MP_CLK_AUDIO_AHB_ROOT IMX8MP_CLK_AUDIO_ROOT
+#define IMX8MP_CLK_AUDIO_AXI_ROOT 321
+#define IMX8MP_CLK_SAI1_ROOT 322
+#define IMX8MP_CLK_SAI2_ROOT 323
+#define IMX8MP_CLK_SAI3_ROOT 324
+#define IMX8MP_CLK_SAI5_ROOT 325
+#define IMX8MP_CLK_SAI6_ROOT 326
+#define IMX8MP_CLK_SAI7_ROOT 327
+#define IMX8MP_CLK_PDM_ROOT 328
+#define IMX8MP_CLK_MEDIA_LDB_ROOT 329
+#define IMX8MP_CLK_END 330
#define IMX8MP_CLK_AUDIOMIX_SAI1_IPG 0
#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1 1
diff --git a/include/efi_config.h b/include/efi_config.h
index 01ce9b2b06d..d7c1601137e 100644
--- a/include/efi_config.h
+++ b/include/efi_config.h
@@ -105,11 +105,6 @@ efi_status_t eficonfig_process_common(struct efimenu *efi_menu,
void (*item_data_print)(void *),
char *(*item_choice)(void *));
efi_status_t eficonfig_process_select_file(void *data);
-efi_status_t eficonfig_get_unused_bootoption(u16 *buf,
- efi_uintn_t buf_size, u32 *index);
-efi_status_t eficonfig_append_bootorder(u16 index);
-efi_status_t eficonfig_generate_media_device_boot_option(void);
-
efi_status_t eficonfig_append_menu_entry(struct efimenu *efi_menu,
char *title, eficonfig_entry_func func,
void *data);
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 11e08a804f7..604fd765f75 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -517,6 +517,17 @@ struct efi_register_notify_event {
int efi_init_early(void);
/* Initialize efi execution environment */
efi_status_t efi_init_obj_list(void);
+/* Append new boot option in BootOrder variable */
+efi_status_t efi_bootmgr_append_bootorder(u16 index);
+/* Get unused "Boot####" index */
+efi_status_t efi_bootmgr_get_unused_bootoption(u16 *buf,
+ efi_uintn_t buf_size, u32 *index);
+/* Generate the media device boot option */
+efi_status_t efi_bootmgr_update_media_device_boot_option(void);
+/* Delete selected boot option */
+efi_status_t efi_bootmgr_delete_boot_option(u16 boot_index);
+/* search the boot option index in BootOrder */
+bool efi_search_bootorder(u16 *bootorder, efi_uintn_t num, u32 target, u32 *index);
/* Set up console modes */
void efi_setup_console_size(void);
/* Install device tree */
diff --git a/include/expo.h b/include/expo.h
index d242f48e30c..0b1d944a169 100644
--- a/include/expo.h
+++ b/include/expo.h
@@ -7,22 +7,31 @@
#ifndef __SCENE_H
#define __SCENE_H
+#include <dm/ofnode_decl.h>
#include <linux/list.h>
struct udevice;
+struct video_priv;
/**
* enum expoact_type - types of actions reported by the expo
*
* @EXPOACT_NONE: no action
- * @EXPOACT_POINT: menu item was highlighted (@id indicates which)
+ * @EXPOACT_POINT_OBJ: object was highlighted (@id indicates which)
+ * @EXPOACT_POINT_ITEM: menu item was highlighted (@id indicates which)
* @EXPOACT_SELECT: menu item was selected (@id indicates which)
+ * @EXPOACT_OPEN: menu was opened, so an item can be selected (@id indicates
+ * which menu object)
+ * @EXPOACT_CLOSE: menu was closed (@id indicates which menu object)
* @EXPOACT_QUIT: request to exit the menu
*/
enum expoact_type {
EXPOACT_NONE,
- EXPOACT_POINT,
+ EXPOACT_POINT_OBJ,
+ EXPOACT_POINT_ITEM,
EXPOACT_SELECT,
+ EXPOACT_OPEN,
+ EXPOACT_CLOSE,
EXPOACT_QUIT,
};
@@ -30,7 +39,7 @@ enum expoact_type {
* struct expo_action - an action report by the expo
*
* @type: Action type (EXPOACT_NONE if there is no action)
- * @select: Used for EXPOACT_POINT and EXPOACT_SELECT
+ * @select: Used for EXPOACT_POINT_ITEM and EXPOACT_SELECT
* @id: ID number of the object affected.
*/
struct expo_action {
@@ -43,6 +52,19 @@ struct expo_action {
};
/**
+ * struct expo_theme - theme for the expo
+ *
+ * @font_size: Default font size for all text
+ * @menu_inset: Inset width (on each side and top/bottom) for menu items
+ * @menuitem_gap_y: Gap between menu items in pixels
+ */
+struct expo_theme {
+ u32 font_size;
+ u32 menu_inset;
+ u32 menuitem_gap_y;
+};
+
+/**
* struct expo - information about an expo
*
* A group of scenes which can be presented to the user, typically to obtain
@@ -50,23 +72,29 @@ struct expo_action {
*
* @name: Name of the expo (allocated)
* @display: Display to use (`UCLASS_VIDEO`), or NULL to use text mode
+ * @cons: Console to use (`UCLASS_VIDEO_CONSOLE`), or NULL to use text mode
* @scene_id: Current scene ID (0 if none)
* @next_id: Next ID number to use, for automatic allocation
* @action: Action selected by user. At present only one is supported, with the
* type set to EXPOACT_NONE if there is no action
* @text_mode: true to use text mode for the menu (no vidconsole)
+ * @popup: true to use popup menus, instead of showing all items
* @priv: Private data for the controller
+ * @theme: Information about fonts styles, etc.
* @scene_head: List of scenes
* @str_head: list of strings
*/
struct expo {
char *name;
struct udevice *display;
+ struct udevice *cons;
uint scene_id;
uint next_id;
struct expo_action action;
bool text_mode;
+ bool popup;
void *priv;
+ struct expo_theme theme;
struct list_head scene_head;
struct list_head str_head;
};
@@ -92,7 +120,8 @@ struct expo_string {
* @expo: Expo this scene is part of
* @name: Name of the scene (allocated)
* @id: ID number of the scene
- * @title: Title of the scene (allocated)
+ * @title_id: String ID of title of the scene (allocated)
+ * @highlight_id: ID of highlighted object, if any
* @sibling: Node to link this scene to its siblings
* @obj_head: List of objects in the scene
*/
@@ -100,7 +129,8 @@ struct scene {
struct expo *expo;
char *name;
uint id;
- char *title;
+ uint title_id;
+ uint highlight_id;
struct list_head sibling;
struct list_head obj_head;
};
@@ -121,15 +151,43 @@ enum scene_obj_t {
};
/**
+ * struct scene_dim - Dimensions of an object
+ *
+ * @x: x position, in pixels from left side
+ * @y: y position, in pixels from top
+ * @w: width, in pixels
+ * @h: height, in pixels
+ */
+struct scene_dim {
+ int x;
+ int y;
+ int w;
+ int h;
+};
+
+/**
+ * enum scene_obj_flags_t - flags for objects
+ *
+ * @SCENEOF_HIDE: object should be hidden
+ * @SCENEOF_POINT: object should be highlighted
+ * @SCENEOF_OPEN: object should be opened (e.g. menu is opened so that an option
+ * can be selected)
+ */
+enum scene_obj_flags_t {
+ SCENEOF_HIDE = 1 << 0,
+ SCENEOF_POINT = 1 << 1,
+ SCENEOF_OPEN = 1 << 2,
+};
+
+/**
* struct scene_obj - information about an object in a scene
*
* @scene: Scene that this object relates to
* @name: Name of the object (allocated)
* @id: ID number of the object
* @type: Type of this object
- * @x: x position, in pixels from left side
- * @y: y position, in pixels from top
- * @hide: true if the object should be hidden
+ * @dim: Dimensions for this object
+ * @flags: Flags for this object
* @sibling: Node to link this object to its siblings
*/
struct scene_obj {
@@ -137,9 +195,8 @@ struct scene_obj {
char *name;
uint id;
enum scene_obj_t type;
- int x;
- int y;
- bool hide;
+ struct scene_dim dim;
+ int flags;
struct list_head sibling;
};
@@ -256,6 +313,25 @@ int expo_new(const char *name, void *priv, struct expo **expp);
void expo_destroy(struct expo *exp);
/**
+ * expo_set_dynamic_start() - Set the start of the 'dynamic' IDs
+ *
+ * It is common for a set of 'static' IDs to be used to refer to objects in the
+ * expo. These typically use an enum so that they are defined in sequential
+ * order.
+ *
+ * Dynamic IDs (for objects not in the enum) are intended to be used for
+ * objects to which the code does not need to refer. These are ideally located
+ * above the static IDs.
+ *
+ * Use this function to set the start of the dynamic range, making sure that the
+ * value is higher than all the statically allocated IDs.
+ *
+ * @exp: Expo to update
+ * @dyn_start: Start ID that expo should use for dynamic allocation
+ */
+void expo_set_dynamic_start(struct expo *exp, uint dyn_start);
+
+/**
* expo_str() - add a new string to an expo
*
* @exp: Expo to update
@@ -285,6 +361,16 @@ const char *expo_get_str(struct expo *exp, uint id);
int expo_set_display(struct expo *exp, struct udevice *dev);
/**
+ * expo_calc_dims() - Calculate the dimensions of the objects
+ *
+ * Updates the width and height of all objects based on their contents
+ *
+ * @exp: Expo to update
+ * Returns 0 if OK, -ENOTSUPP if there is no graphical console
+ */
+int expo_calc_dims(struct expo *exp);
+
+/**
* expo_set_scene_id() - Set the current scene ID
*
* @exp: Expo to update
@@ -294,6 +380,14 @@ int expo_set_display(struct expo *exp, struct udevice *dev);
int expo_set_scene_id(struct expo *exp, uint scene_id);
/**
+ * expo_first_scene_id() - Get the ID of the first scene
+ *
+ * @exp: Expo to check
+ * Returns: Scene ID of first scene, or -ENOENT if there are no scenes
+ */
+int expo_first_scene_id(struct expo *exp);
+
+/**
* expo_render() - render the expo on the display / console
*
* @exp: Expo to render
@@ -304,12 +398,12 @@ int expo_set_scene_id(struct expo *exp, uint scene_id);
int expo_render(struct expo *exp);
/**
- * exp_set_text_mode() - Controls whether the expo renders in text mode
+ * expo_set_text_mode() - Controls whether the expo renders in text mode
*
* @exp: Expo to update
* @text_mode: true to use text mode, false to use the console
*/
-void exp_set_text_mode(struct expo *exp, bool text_mode);
+void expo_set_text_mode(struct expo *exp, bool text_mode);
/**
* scene_new() - create a new scene in a expo
@@ -335,13 +429,43 @@ int scene_new(struct expo *exp, const char *name, uint id, struct scene **scnp);
struct scene *expo_lookup_scene_id(struct expo *exp, uint scene_id);
/**
+ * scene_highlight_first() - Highlight the first item in a scene
+ *
+ * This highlights the first item, so that the user can see that it is pointed
+ * to
+ *
+ * @scn: Scene to update
+ */
+void scene_highlight_first(struct scene *scn);
+
+/**
+ * scene_set_highlight_id() - Set the object which is highlighted
+ *
+ * Sets a new object to highlight in the scene
+ *
+ * @scn: Scene to update
+ * @id: ID of object to highlight
+ */
+void scene_set_highlight_id(struct scene *scn, uint id);
+
+/**
+ * scene_set_open() - Set whether an item is open or not
+ *
+ * @scn: Scene to update
+ * @id: ID of object to update
+ * @open: true to open the object, false to close it
+ * Returns: 0 if OK, -ENOENT if @id is invalid
+ */
+int scene_set_open(struct scene *scn, uint id, bool open);
+
+/**
* scene_title_set() - set the scene title
*
* @scn: Scene to update
- * @title: Title to set, NULL if none (this is allocated by this call)
- * Returns: 0 if OK, -ENOMEM if out of memory
+ * @title_id: Title ID to set
+ * Returns: 0 if OK
*/
-int scene_title_set(struct scene *scn, const char *title);
+int scene_title_set(struct scene *scn, uint title_id);
/**
* scene_obj_count() - Count the number of objects in a scene
@@ -426,6 +550,17 @@ int scene_txt_set_font(struct scene *scn, uint id, const char *font_name,
int scene_obj_set_pos(struct scene *scn, uint id, int x, int y);
/**
+ * scene_obj_set_size() - Set the size of an object
+ *
+ * @scn: Scene to update
+ * @id: ID of object to update
+ * @w: width in pixels
+ * @h: height in pixels
+ * Returns: 0 if OK, -ENOENT if @id is invalid
+ */
+int scene_obj_set_size(struct scene *scn, uint id, int w, int h);
+
+/**
* scene_obj_set_hide() - Set whether an object is hidden
*
* The update happens when the expo is next rendered.
@@ -519,4 +654,46 @@ int expo_send_key(struct expo *exp, int key);
*/
int expo_action_get(struct expo *exp, struct expo_action *act);
+/**
+ * expo_apply_theme() - Apply a theme to an expo
+ *
+ * @exp: Expo to update
+ * @node: Node containing the theme
+ */
+int expo_apply_theme(struct expo *exp, ofnode node);
+
+/**
+ * expo_build() - Build an expo from an FDT description
+ *
+ * Build a complete expo from a description in the provided devicetree.
+ *
+ * See doc/developer/expo.rst for a description of the format
+ *
+ * @root: Root node for expo description
+ * @expp: Returns the new expo
+ * Returns: 0 if OK, -ENOMEM if out of memory, -EINVAL if there is a format
+ * error, -ENOENT if there is a references to a non-existent string
+ */
+int expo_build(ofnode root, struct expo **expp);
+
+/**
+ * cedit_arange() - Arrange objects in a configuration-editor scene
+ *
+ * @exp: Expo to update
+ * @vid_priv: Private info of the video device
+ * @scene_id: scene ID to arrange
+ * Returns: 0 if OK, -ve on error
+ */
+int cedit_arange(struct expo *exp, struct video_priv *vid_priv, uint scene_id);
+
+/**
+ * cedit_run() - Run a configuration editor
+ *
+ * This accepts input until the user quits with Escape
+ *
+ * @exp: Expo to use
+ * Returns: 0 if OK, -ve on error
+ */
+int cedit_run(struct expo *exp);
+
#endif /*__SCENE_H */
diff --git a/include/firmware/imx/sci/rpc.h b/include/firmware/imx/sci/rpc.h
index 39de7f0e3e0..85af6f3996e 100644
--- a/include/firmware/imx/sci/rpc.h
+++ b/include/firmware/imx/sci/rpc.h
@@ -23,12 +23,12 @@
#define RPC_FUNC(MSG) ((MSG)->func)
#define RPC_R8(MSG) ((MSG)->func)
#define RPC_I64(MSG, IDX) ((s64)(RPC_U32((MSG), (IDX))) << 32ULL) | \
- (s64)(RPC_U32((MSG), (IDX) + 4U))
+ (s64)(RPC_U32((MSG), (IDX) + 4U))
#define RPC_I32(MSG, IDX) ((MSG)->DATA.i32[(IDX) / 4U])
#define RPC_I16(MSG, IDX) ((MSG)->DATA.i16[(IDX) / 2U])
#define RPC_I8(MSG, IDX) ((MSG)->DATA.i8[(IDX)])
#define RPC_U64(MSG, IDX) ((u64)(RPC_U32((MSG), (IDX))) << 32ULL) | \
- (u64)(RPC_U32((MSG), (IDX) + 4U))
+ (u64)(RPC_U32((MSG), (IDX) + 4U))
#define RPC_U32(MSG, IDX) ((MSG)->DATA.u32[(IDX) / 4U])
#define RPC_U16(MSG, IDX) ((MSG)->DATA.u16[(IDX) / 2U])
#define RPC_U8(MSG, IDX) ((MSG)->DATA.u8[(IDX)])
@@ -67,7 +67,9 @@ struct sc_rpc_msg_s {
#define PM_FUNC_SET_SYS_POWER_MODE 19U
#define PM_FUNC_SET_PARTITION_POWER_MODE 1U
#define PM_FUNC_GET_SYS_POWER_MODE 2U
+#define PM_FUNC_PARTITION_WAKE 28U
#define PM_FUNC_SET_RESOURCE_POWER_MODE 3U
+#define PM_FUNC_SET_RESOURCE_POWER_MODE_ALL 22U
#define PM_FUNC_GET_RESOURCE_POWER_MODE 4U
#define PM_FUNC_REQ_LOW_POWER_MODE 16U
#define PM_FUNC_REQ_CPU_LOW_POWER_MODE 20U
@@ -81,13 +83,16 @@ struct sc_rpc_msg_s {
#define PM_FUNC_GET_CLOCK_PARENT 15U
#define PM_FUNC_RESET 13U
#define PM_FUNC_RESET_REASON 10U
+#define PM_FUNC_GET_RESET_PART 26U
#define PM_FUNC_BOOT 8U
+#define PM_FUNC_SET_BOOT_PARM 27U
#define PM_FUNC_REBOOT 9U
#define PM_FUNC_REBOOT_PARTITION 12U
+#define PM_FUNC_REBOOT_CONTINUE 25U
#define PM_FUNC_CPU_START 11U
#define PM_FUNC_CPU_RESET 23U
#define PM_FUNC_RESOURCE_RESET 29U
-#define PM_FUNC_IS_PARTITION_STARTED 24U
+#define PM_FUNC_IS_PARTITION_STARTED 24U
/* MISC RPC */
#define MISC_FUNC_UNKNOWN 0
@@ -95,16 +100,10 @@ struct sc_rpc_msg_s {
#define MISC_FUNC_GET_CONTROL 2U
#define MISC_FUNC_SET_MAX_DMA_GROUP 4U
#define MISC_FUNC_SET_DMA_GROUP 5U
-#define MISC_FUNC_SECO_IMAGE_LOAD 8U
-#define MISC_FUNC_SECO_AUTHENTICATE 9U
-#define MISC_FUNC_SECO_FUSE_WRITE 20U
-#define MISC_FUNC_SECO_ENABLE_DEBUG 21U
-#define MISC_FUNC_SECO_FORWARD_LIFECYCLE 22U
-#define MISC_FUNC_SECO_RETURN_LIFECYCLE 23U
-#define MISC_FUNC_SECO_BUILD_INFO 24U
#define MISC_FUNC_DEBUG_OUT 10U
#define MISC_FUNC_WAVEFORM_CAPTURE 6U
#define MISC_FUNC_BUILD_INFO 15U
+#define MISC_FUNC_API_VER 35U
#define MISC_FUNC_UNIQUE_ID 19U
#define MISC_FUNC_SET_ARI 3U
#define MISC_FUNC_BOOT_STATUS 7U
@@ -114,8 +113,11 @@ struct sc_rpc_msg_s {
#define MISC_FUNC_SET_TEMP 12U
#define MISC_FUNC_GET_TEMP 13U
#define MISC_FUNC_GET_BOOT_DEV 16U
+#define MISC_FUNC_GET_BOOT_TYPE 33U
+#define MISC_FUNC_GET_BOOT_CONTAINER 36U
#define MISC_FUNC_GET_BUTTON_STATUS 18U
-#define MISC_FUNC_GET_BOOT_CONTAINER 36U
+#define MISC_FUNC_ROMPATCH_CHECKSUM 26U
+#define MISC_FUNC_BOARD_IOCTL 34U
/* PAD RPC */
#define PAD_FUNC_UNKNOWN 0
@@ -160,6 +162,7 @@ struct sc_rpc_msg_s {
#define RM_FUNC_GET_RESOURCE_INFO 16U
#define RM_FUNC_MEMREG_ALLOC 17U
#define RM_FUNC_MEMREG_SPLIT 29U
+#define RM_FUNC_MEMREG_FRAG 32U
#define RM_FUNC_MEMREG_FREE 18U
#define RM_FUNC_FIND_MEMREG 30U
#define RM_FUNC_ASSIGN_MEMREG 19U
@@ -190,6 +193,7 @@ struct sc_rpc_msg_s {
#define SECO_FUNC_UPDATE_MPMR 14U /* Index for seco_update_mpmr() RPC call */
#define SECO_FUNC_GET_MP_SIGN 15U /* Index for seco_get_mp_sign() RPC call */
#define SECO_FUNC_BUILD_INFO 16U /* Index for seco_build_info() RPC call */
+#define SECO_FUNC_V2X_BUILD_INFO 30U /* Index for sc_seco_v2x_build_info() RPC call */
#define SECO_FUNC_CHIP_INFO 17U /* Index for seco_chip_info() RPC call */
#define SECO_FUNC_ENABLE_DEBUG 18U /* Index for seco_enable_debug() RPC call */
#define SECO_FUNC_GET_EVENT 19U /* Index for seco_get_event() RPC call */
@@ -210,6 +214,7 @@ struct sc_rpc_msg_s {
#define TIMER_FUNC_UNKNOWN 0 /* Unknown function */
#define TIMER_FUNC_SET_WDOG_TIMEOUT 1U /* Index for sc_timer_set_wdog_timeout() RPC call */
#define TIMER_FUNC_SET_WDOG_PRE_TIMEOUT 12U /* Index for sc_timer_set_wdog_pre_timeout() RPC call */
+#define TIMER_FUNC_SET_WDOG_WINDOW 19U /* Index for sc_timer_set_wdog_window() RPC call */
#define TIMER_FUNC_START_WDOG 2U /* Index for sc_timer_start_wdog() RPC call */
#define TIMER_FUNC_STOP_WDOG 3U /* Index for sc_timer_stop_wdog() RPC call */
#define TIMER_FUNC_PING_WDOG 4U /* Index for sc_timer_ping_wdog() RPC call */
diff --git a/include/firmware/imx/sci/sci.h b/include/firmware/imx/sci/sci.h
index 61c8211b443..f832982b3de 100644
--- a/include/firmware/imx/sci/sci.h
+++ b/include/firmware/imx/sci/sci.h
@@ -13,6 +13,7 @@
#include <firmware/imx/sci/svc/pm/api.h>
#include <firmware/imx/sci/svc/rm/api.h>
#include <firmware/imx/sci/svc/seco/api.h>
+#include <firmware/imx/sci/svc/timer/api.h>
#include <firmware/imx/sci/rpc.h>
#include <dt-bindings/soc/imx_rsrc.h>
#include <linux/errno.h>
@@ -73,6 +74,7 @@ int sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
sc_pm_clk_parent_t parent);
int sc_pm_cpu_start(sc_ipc_t ipc, sc_rsrc_t resource, sc_bool_t enable,
sc_faddr_t address);
+void sc_pm_reboot(sc_ipc_t ipc, sc_pm_reset_type_t type);
sc_bool_t sc_pm_is_partition_started(sc_ipc_t ipc, sc_rm_pt_t pt);
int sc_pm_resource_reset(sc_ipc_t ipc, sc_rsrc_t resource);
@@ -88,6 +90,7 @@ void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit);
int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val);
int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp,
s16 *celsius, s8 *tenths);
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status);
/* RM API */
sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr);
@@ -117,6 +120,9 @@ int sc_pad_get(sc_ipc_t ipc, sc_pad_t pad, uint32_t *val);
/* SMMU API */
int sc_rm_set_master_sid(sc_ipc_t ipc, sc_rsrc_t resource, sc_rm_sid_t sid);
+/* Timer API */
+int sc_timer_set_wdog_window(sc_ipc_t ipc, sc_timer_wdog_time_t window);
+
/* SECO API */
int sc_seco_authenticate(sc_ipc_t ipc, sc_seco_auth_cmd_t cmd,
sc_faddr_t addr);
@@ -124,6 +130,7 @@ int sc_seco_forward_lifecycle(sc_ipc_t ipc, u32 change);
int sc_seco_chip_info(sc_ipc_t ipc, u16 *lc, u16 *monotonic, u32 *uid_l,
u32 *uid_h);
void sc_seco_build_info(sc_ipc_t ipc, u32 *version, u32 *commit);
+int sc_seco_v2x_build_info(sc_ipc_t ipc, u32 *version, u32 *commit);
int sc_seco_get_event(sc_ipc_t ipc, u8 idx, u32 *event);
int sc_seco_gen_key_blob(sc_ipc_t ipc, u32 id, sc_faddr_t load_addr,
sc_faddr_t export_addr, u16 max_size);
@@ -374,6 +381,23 @@ static inline int sc_seco_secvio_config(sc_ipc_t ipc, u8 id, u8 access, u32 *dat
return -EOPNOTSUPP;
}
+static inline void sc_pm_reboot(sc_ipc_t ipc, sc_pm_reset_type_t type)
+{
+}
+
+static inline int sc_seco_v2x_build_info(sc_ipc_t ipc, u32 *version, u32 *commit)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status)
+{
+}
+
+static inline int sc_timer_set_wdog_window(sc_ipc_t ipc, sc_timer_wdog_time_t window)
+{
+ return -EOPNOTSUPP;
+}
#endif
#endif
diff --git a/include/firmware/imx/sci/svc/misc/api.h b/include/firmware/imx/sci/svc/misc/api.h
index 3629eb68d7a..a4b92b86cc6 100644
--- a/include/firmware/imx/sci/svc/misc/api.h
+++ b/include/firmware/imx/sci/svc/misc/api.h
@@ -5,27 +5,45 @@
#ifndef SC_MISC_API_H
#define SC_MISC_API_H
+/* Defines for type widths */
+#define SC_MISC_DMA_GRP_W 5U /* Width of sc_misc_dma_group_t */
+/* Max DMA channel priority group */
+#define SC_MISC_DMA_GRP_MAX 31U
/* Defines for sc_misc_boot_status_t */
#define SC_MISC_BOOT_STATUS_SUCCESS 0U /* Success */
#define SC_MISC_BOOT_STATUS_SECURITY 1U /* Security violation */
-/* Defines for sc_misc_seco_auth_cmd_t */
-#define SC_MISC_SECO_AUTH_SECO_FW 0U /* SECO Firmware */
-#define SC_MISC_SECO_AUTH_HDMI_TX_FW 1U /* HDMI TX Firmware */
-#define SC_MISC_SECO_AUTH_HDMI_RX_FW 2U /* HDMI RX Firmware */
-
/* Defines for sc_misc_temp_t */
-#define SC_MISC_TEMP 0U /* Temp sensor */
-#define SC_MISC_TEMP_HIGH 1U /* Temp high alarm */
-#define SC_MISC_TEMP_LOW 2U /* Temp low alarm */
+#define SC_MISC_TEMP 0U /* Temp sensor */
+#define SC_MISC_TEMP_HIGH 1U /* Temp high alarm */
+#define SC_MISC_TEMP_LOW 2U /* Temp low alarm */
+
+/* Defines for sc_misc_bt_t */
+#define SC_MISC_BT_PRIMARY 0U /* Primary boot */
+#define SC_MISC_BT_SECONDARY 1U /* Secondary boot */
+#define SC_MISC_BT_RECOVERY 2U /* Recovery boot */
+#define SC_MISC_BT_MANUFACTURE 3U /* Manufacture boot */
+#define SC_MISC_BT_SERIAL 4U /* Serial boot */
+/* Types */
-/* Defines for sc_misc_seco_auth_cmd_t */
-#define SC_MISC_AUTH_CONTAINER 0U /* Authenticate container */
-#define SC_MISC_VERIFY_IMAGE 1U /* Verify image */
-#define SC_MISC_REL_CONTAINER 2U /* Release container */
+/*
+ * This type is used to store a DMA channel priority group.
+ */
+typedef u8 sc_misc_dma_group_t;
+/*
+ * This type is used report boot status.
+ */
typedef u8 sc_misc_boot_status_t;
+
+/*
+ * This type is used report boot status.
+ */
typedef u8 sc_misc_temp_t;
+/*
+ * This type is used report the boot type.
+ */
+typedef u8 sc_misc_bt_t;
#endif /* SC_MISC_API_H */
diff --git a/include/firmware/imx/sci/svc/pm/api.h b/include/firmware/imx/sci/svc/pm/api.h
index 9008b85c6f6..d1b085d7f87 100644
--- a/include/firmware/imx/sci/svc/pm/api.h
+++ b/include/firmware/imx/sci/svc/pm/api.h
@@ -6,6 +6,14 @@
#ifndef SC_PM_API_H
#define SC_PM_API_H
+#include <firmware/imx/sci/types.h>
+/* Defines for type widths */
+#define SC_PM_POWER_MODE_W 2U /* Width of sc_pm_power_mode_t */
+#define SC_PM_CLOCK_MODE_W 3U /* Width of sc_pm_clock_mode_t */
+#define SC_PM_RESET_TYPE_W 2U /* Width of sc_pm_reset_type_t */
+#define SC_PM_RESET_REASON_W 4U /* Width of sc_pm_reset_reason_t */
+/* Defines for ALL parameters */
+#define SC_PM_CLK_ALL ((sc_pm_clk_t)UINT8_MAX) /* All clocks */
/* Defines for sc_pm_power_mode_t */
#define SC_PM_PW_MODE_OFF 0U /* Power off */
#define SC_PM_PW_MODE_STBY 1U /* Power in standby */
@@ -35,10 +43,96 @@
#define SC_PM_CLK_MODE_AUTOGATE_HW 4U /* Clock is in HW autogate mode */
#define SC_PM_CLK_MODE_AUTOGATE_SW_HW 5U /* Clock is in SW-HW autogate mode */
+/* Defines for sc_pm_clk_parent_t */
+#define SC_PM_PARENT_XTAL 0U /*!< Parent is XTAL. */
+#define SC_PM_PARENT_PLL0 1U /*!< Parent is PLL0 */
+#define SC_PM_PARENT_PLL1 2U /*!< Parent is PLL1 or PLL0/2 */
+#define SC_PM_PARENT_PLL2 3U /*!< Parent in PLL2 or PLL0/4 */
+#define SC_PM_PARENT_BYPS 4U /*!< Parent is a bypass clock. */
+
+/* Defines for sc_pm_reset_type_t */
+#define SC_PM_RESET_TYPE_COLD 0U /* Cold reset */
+#define SC_PM_RESET_TYPE_WARM 1U /* Warm reset */
+#define SC_PM_RESET_TYPE_BOARD 2U /* Board reset */
+
+/* Defines for sc_pm_reset_reason_t */
+#define SC_PM_RESET_REASON_POR 0U /* Power on reset */
+#define SC_PM_RESET_REASON_JTAG 1U /* JTAG reset */
+#define SC_PM_RESET_REASON_SW 2U /* Software reset */
+#define SC_PM_RESET_REASON_WDOG 3U /* Partition watchdog reset */
+#define SC_PM_RESET_REASON_LOCKUP 4U /* SCU lockup reset */
+#define SC_PM_RESET_REASON_SNVS 5U /* SNVS reset */
+#define SC_PM_RESET_REASON_TEMP 6U /* Temp panic reset */
+#define SC_PM_RESET_REASON_MSI 7U /* MSI reset */
+#define SC_PM_RESET_REASON_UECC 8U /* ECC reset */
+#define SC_PM_RESET_REASON_SCFW_WDOG 9U /* SCFW watchdog reset */
+#define SC_PM_RESET_REASON_ROM_WDOG 10U /* SCU ROM watchdog reset */
+#define SC_PM_RESET_REASON_SECO 11U /* SECO reset */
+#define SC_PM_RESET_REASON_SCFW_FAULT 12U /* SCFW fault reset */
+
+/* Defines for sc_pm_sys_if_t */
+#define SC_PM_SYS_IF_INTERCONNECT 0U /* System interconnect */
+#define SC_PM_SYS_IF_MU 1U /* AP -> SCU message units */
+#define SC_PM_SYS_IF_OCMEM 2U /* On-chip memory (ROM/OCRAM) */
+#define SC_PM_SYS_IF_DDR 3U /* DDR memory */
+
+/* Defines for sc_pm_wake_src_t */
+/* No wake source, used for self-kill */
+#define SC_PM_WAKE_SRC_NONE 0U
+/* Wakeup from SCU to resume CPU (IRQSTEER & GIC powered down) */
+#define SC_PM_WAKE_SRC_SCU 1U
+/* Wakeup from IRQSTEER to resume CPU (GIC powered down) */
+#define SC_PM_WAKE_SRC_IRQSTEER 2U
+/* Wakeup from IRQSTEER+GIC to wake CPU (GIC clock gated) */
+#define SC_PM_WAKE_SRC_IRQSTEER_GIC 3U
+/* Wakeup from GIC to wake CPU */
+#define SC_PM_WAKE_SRC_GIC 4U
+/* Types */
+
+/*
+ * This type is used to declare a power mode. Note resources only use
+ * SC_PM_PW_MODE_OFF and SC_PM_PW_MODE_ON. The other modes are used only
+ * as system power modes.
+ */
typedef u8 sc_pm_power_mode_t;
+
+/*
+ * This type is used to declare a clock.
+ */
typedef u8 sc_pm_clk_t;
+
+/*
+ * This type is used to declare a clock mode.
+ */
typedef u8 sc_pm_clk_mode_t;
+
+/*
+ * This type is used to declare the clock parent.
+ */
typedef u8 sc_pm_clk_parent_t;
+
+/*
+ * This type is used to declare clock rates.
+ */
typedef u32 sc_pm_clock_rate_t;
+/*
+ * This type is used to declare a desired reset type.
+ */
+typedef u8 sc_pm_reset_type_t;
+
+/*
+ * This type is used to declare a reason for a reset.
+ */
+typedef u8 sc_pm_reset_reason_t;
+
+/*
+ * This type is used to specify a system-level interface to be power managed.
+ */
+typedef u8 sc_pm_sys_if_t;
+
+/*
+ * This type is used to specify a wake source for CPU resources.
+ */
+typedef u8 sc_pm_wake_src_t;
#endif /* SC_PM_API_H */
diff --git a/include/firmware/imx/sci/svc/rm/api.h b/include/firmware/imx/sci/svc/rm/api.h
index 163d81403c5..f4e9abcd9b3 100644
--- a/include/firmware/imx/sci/svc/rm/api.h
+++ b/include/firmware/imx/sci/svc/rm/api.h
@@ -38,32 +38,36 @@
/* Types */
-/*!
+/*
* This type is used to declare a resource partition.
*/
typedef u8 sc_rm_pt_t;
-/*!
+/*
* This type is used to declare a memory region.
*/
typedef u8 sc_rm_mr_t;
-/*!
+/*
* This type is used to declare a resource domain ID used by the
* isolation HW.
*/
typedef u8 sc_rm_did_t;
-/*!
+/*
* This type is used to declare an SMMU StreamID.
*/
typedef u16 sc_rm_sid_t;
-/*!
+/*
* This type is a used to declare master transaction attributes.
*/
typedef u8 sc_rm_spa_t;
+/*
+ * This type is used to declare a resource/memory region access permission.
+ * Refer to the XRDC2 Block Guide for more information.
+ */
typedef u8 sc_rm_perm_t;
#endif /* SC_RM_API_H */
diff --git a/include/firmware/imx/sci/svc/seco/api.h b/include/firmware/imx/sci/svc/seco/api.h
index 6e9c302315b..7d4b6b92e17 100644
--- a/include/firmware/imx/sci/svc/seco/api.h
+++ b/include/firmware/imx/sci/svc/seco/api.h
@@ -17,6 +17,7 @@
#define SC_SECO_AUTH_SECO_FW 3U /* SECO Firmware */
#define SC_SECO_AUTH_HDMI_TX_FW 4U /* HDMI TX Firmware */
#define SC_SECO_AUTH_HDMI_RX_FW 5U /* HDMI RX Firmware */
+#define SC_SECO_EVERIFY_IMAGE 6U /* Enhanced verify image */
#define SC_SECO_RNG_STAT_UNAVAILABLE 0U /* Unable to initialize the RNG */
#define SC_SECO_RNG_STAT_INPROGRESS 1U /* Initialization is on-going */
@@ -24,12 +25,12 @@
/* Types */
-/*!
+/*
* This type is used to issue SECO authenticate commands.
*/
typedef u8 sc_seco_auth_cmd_t;
-/*!
+/*
* This type is used to return the RNG initialization status.
*/
typedef u32 sc_seco_rng_stat_t;
diff --git a/include/firmware/imx/sci/svc/timer/api.h b/include/firmware/imx/sci/svc/timer/api.h
new file mode 100644
index 00000000000..c2fe34aa751
--- /dev/null
+++ b/include/firmware/imx/sci/svc/timer/api.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018-2019 NXP
+ */
+
+#ifndef SC_TIMER_API_H
+#define SC_TIMER_API_H
+
+/* Defines */
+
+/* Defines for type widths */
+#define SC_TIMER_ACTION_W 3U /* Width of sc_timer_wdog_action_t */
+
+/* Defines for sc_timer_wdog_action_t */
+#define SC_TIMER_WDOG_ACTION_PARTITION 0U /* Reset partition */
+#define SC_TIMER_WDOG_ACTION_WARM 1U /* Warm reset system */
+#define SC_TIMER_WDOG_ACTION_COLD 2U /* Cold reset system */
+#define SC_TIMER_WDOG_ACTION_BOARD 3U /* Reset board */
+#define SC_TIMER_WDOG_ACTION_IRQ 4U /* Only generate IRQs */
+
+/* Types */
+
+/*
+ * This type is used to configure the watchdog action.
+ */
+typedef u8 sc_timer_wdog_action_t;
+
+/*
+ * This type is used to declare a watchdog time value in milliseconds.
+ */
+typedef u32 sc_timer_wdog_time_t;
+
+#endif /* SC_TIMER_API_H */
diff --git a/include/fs.h b/include/fs.h
index 8370d88cb20..e341a0ed01b 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -300,4 +300,42 @@ int do_fs_type(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
*/
int do_fs_types(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
+/**
+ * fs_read_alloc() - Allocate space for a file and read it
+ *
+ * You must call fs_set_blk_dev() or a similar function before calling this,
+ * since that sets up the block device to use.
+ *
+ * The file is terminated with a nul character
+ *
+ * @fname: Filename to read
+ * @size: Size of file to read (must be correct!)
+ * @align: Alignment to use for memory allocation (0 for default)
+ * @bufp: On success, returns the allocated buffer with the nul-terminated file
+ * in it
+ * Return: 0 if OK, -ENOMEM if out of memory, -EIO if read failed
+ */
+int fs_read_alloc(const char *fname, ulong size, uint align, void **bufp);
+
+/**
+ * fs_load_alloc() - Load a file into allocated space
+ *
+ * The file is terminated with a nul character
+ *
+ * @ifname: Interface name to read from (e.g. "mmc")
+ * @dev_part_str: Device and partition string (e.g. "1:2")
+ * @fname: Filename to read
+ * @max_size: Maximum allowed size for the file (use 0 for 1GB)
+ * @align: Alignment to use for memory allocation (0 for default)
+ * @bufp: On success, returns the allocated buffer with the nul-terminated file
+ * in it
+ * @sizep: On success, returns the size of the file
+ * Return: 0 if OK, -ENOMEM if out of memory, -ENOENT if the file does not
+ * exist, -ENOMEDIUM if the device does not exist, -E2BIG if the file is too
+ * large (greater than @max_size), -EIO if read failed
+ */
+int fs_load_alloc(const char *ifname, const char *dev_part_str,
+ const char *fname, ulong max_size, ulong align, void **bufp,
+ ulong *sizep);
+
#endif /* _FS_H */
diff --git a/include/fsl_sec.h b/include/fsl_sec.h
index d8861d1d0b7..9dad1d1ec47 100644
--- a/include/fsl_sec.h
+++ b/include/fsl_sec.h
@@ -13,8 +13,8 @@
#include <asm/io.h>
#ifdef CONFIG_SYS_FSL_SEC_LE
-#define sec_in32(a) in_le32((ulong *)(ulong)a)
-#define sec_out32(a, v) out_le32((ulong *)(ulong)a, v)
+#define sec_in32(a) in_le32((ulong *)(ulong)(a))
+#define sec_out32(a, v) out_le32((ulong *)(ulong)(a), v)
#define sec_in16(a) in_le16(a)
#define sec_clrbits32 clrbits_le32
#define sec_setbits32 setbits_le32
diff --git a/include/imx_sip.h b/include/imx_sip.h
index ebbb3a16d7e..8a5ca34f393 100644
--- a/include/imx_sip.h
+++ b/include/imx_sip.h
@@ -13,8 +13,8 @@
#define IMX_SIP_BUILDINFO_GET_COMMITHASH 0x00
#define IMX_SIP_SRC 0xC2000005
-#define IMX_SIP_SRC_M4_START 0x00
-#define IMX_SIP_SRC_M4_STARTED 0x01
-#define IMX_SIP_SRC_M4_STOP 0x02
+#define IMX_SIP_SRC_MCU_START 0x00
+#define IMX_SIP_SRC_MCU_STARTED 0x01
+#define IMX_SIP_SRC_MCU_STOP 0x02
#endif
diff --git a/include/log.h b/include/log.h
index 3bab40b6171..6e84f080ef3 100644
--- a/include/log.h
+++ b/include/log.h
@@ -102,6 +102,8 @@ enum log_category_t {
LOGC_EVENT,
/** @LOGC_FS: Related to filesystems */
LOGC_FS,
+ /** @LOGC_EXPO: Related to expo handling */
+ LOGC_EXPO,
/** @LOGC_COUNT: Number of log categories */
LOGC_COUNT,
/** @LOGC_END: Sentinel value for lists of log categories */
diff --git a/include/of_live.h b/include/of_live.h
index f59d6af3350..05e86ac06b1 100644
--- a/include/of_live.h
+++ b/include/of_live.h
@@ -36,4 +36,14 @@ int of_live_build(const void *fdt_blob, struct device_node **rootp);
*/
int unflatten_device_tree(const void *blob, struct device_node **mynodes);
+/**
+ * of_live_free() - Dispose of a livetree
+ *
+ * This frees memory used by the tree, after which @root becomes invalid and
+ * cannot be used
+ *
+ * @root: Tree to dispose
+ */
+void of_live_free(struct device_node *root);
+
#endif
diff --git a/include/test/cedit-test.h b/include/test/cedit-test.h
new file mode 100644
index 00000000000..349df75b16d
--- /dev/null
+++ b/include/test/cedit-test.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Binding shared between cedit.dtsi and test/boot/expo.c
+ *
+ * Copyright 2023 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#ifndef __cedit_test_h
+#define __cedit_test_h
+
+#define ID_PROMPT 1
+#define ID_SCENE1 2
+#define ID_SCENE1_TITLE 3
+
+#define ID_CPU_SPEED 4
+#define ID_CPU_SPEED_TITLE 5
+#define ID_CPU_SPEED_1 6
+#define ID_CPU_SPEED_2 7
+#define ID_CPU_SPEED_3 8
+
+#define ID_POWER_LOSS 9
+#define ID_AC_OFF 10
+#define ID_AC_ON 11
+#define ID_AC_MEMORY 12
+
+#define ID_DYNAMIC_START 13
+
+#endif
diff --git a/include/test/ut.h b/include/test/ut.h
index dddf9ad241f..ea6ee95d734 100644
--- a/include/test/ut.h
+++ b/include/test/ut.h
@@ -130,7 +130,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
\
if (!(cond)) { \
ut_fail(uts, __FILE__, __LINE__, __func__, #cond); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -142,7 +142,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
if (!(cond)) { \
ut_failf(uts, __FILE__, __LINE__, __func__, #cond, \
fmt, ##args); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -157,7 +157,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
#expr1 " == " #expr2, \
"Expected %#x (%d), got %#x (%d)", \
_val1, _val1, _val2, _val2); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -175,7 +175,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
(unsigned long long)_val1, \
(unsigned long long)_val2, \
(unsigned long long)_val2); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -189,7 +189,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
ut_failf(uts, __FILE__, __LINE__, __func__, \
#expr1 " = " #expr2, \
"Expected \"%s\", got \"%s\"", _val1, _val2); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -208,7 +208,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
#expr1 " = " #expr2, \
"Expected \"%.*s\", got \"%.*s\"", \
_len, _val1, _len, _val2); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -228,7 +228,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
#expr1 " = " #expr2, \
"Expected \"%s\", got \"%s\"", \
__buf1, __buf2); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -242,7 +242,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
ut_failf(uts, __FILE__, __LINE__, __func__, \
#expr1 " = " #expr2, \
"Expected %p, got %p", _val1, _val2); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -257,7 +257,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
ut_failf(uts, __FILE__, __LINE__, __func__, \
#expr1 " = " #expr2, \
"Expected %lx, got %lx", _val1, _val2); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -271,7 +271,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
ut_failf(uts, __FILE__, __LINE__, __func__, \
#expr " != NULL", \
"Expected NULL, got %p", _val); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -285,7 +285,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
ut_failf(uts, __FILE__, __LINE__, __func__, \
#expr " = NULL", \
"Expected non-null, got NULL"); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -300,7 +300,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
#expr " = NULL", \
"Expected pointer, got error %ld", \
PTR_ERR(_val)); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -316,7 +316,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
ut_failf(uts, __FILE__, __LINE__, __func__, \
"console", "\nExpected '%s',\n got '%s'", \
uts->expect_str, uts->actual_str); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -329,7 +329,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
ut_failf(uts, __FILE__, __LINE__, __func__, \
"console", "\nExpected '%s',\n got '%s'", \
uts->expect_str, uts->actual_str); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -341,7 +341,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
if (ut_check_skipline(uts)) { \
ut_failf(uts, __FILE__, __LINE__, __func__, \
"console", "\nExpected a line, got end"); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -354,7 +354,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
ut_failf(uts, __FILE__, __LINE__, __func__, \
"console", "\nExpected '%s',\n got to '%s'", \
uts->expect_str, uts->actual_str); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -367,7 +367,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
ut_failf(uts, __FILE__, __LINE__, __func__, \
"console", "Expected no more output, got '%s'",\
uts->actual_str); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
@@ -381,7 +381,7 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
"console", \
"Expected dump of length %x bytes, got '%s'", \
total_bytes, uts->actual_str); \
- __ret = CMD_RET_FAILURE; \
+ return CMD_RET_FAILURE; \
} \
__ret; \
})
diff --git a/include/video.h b/include/video.h
index 03434a81234..e98d0f9c895 100644
--- a/include/video.h
+++ b/include/video.h
@@ -163,11 +163,11 @@ enum colour_idx {
* The caller has to guarantee that the color index is less than
* VID_COLOR_COUNT.
*
- * @priv private data of the console device
- * @idx color index
+ * @priv private data of the video device (UCLASS_VIDEO)
+ * @idx color index (e.g. VID_YELLOW)
* Return: color value
*/
-u32 video_index_to_colour(struct video_priv *priv, unsigned int idx);
+u32 video_index_to_colour(struct video_priv *priv, enum colour_idx idx);
/**
* video_reserve() - Reserve frame-buffer memory for video devices
@@ -205,6 +205,22 @@ int video_clear(struct udevice *dev);
int video_fill(struct udevice *dev, u32 colour);
/**
+ * video_fill_part() - Erase a region
+ *
+ * Erase a rectangle of the display within the given bounds.
+ *
+ * @dev: Device to update
+ * @xstart: X start position in pixels from the left
+ * @ystart: Y start position in pixels from the top
+ * @xend: X end position in pixels from the left
+ * @yend: Y end position in pixels from the top
+ * @colour: Value to write
+ * Return: 0 if OK, -ENOSYS if the display depth is not supported
+ */
+int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
+ int yend, u32 colour);
+
+/**
* video_sync() - Sync a device's frame buffer with its hardware
*
* @vid: Device to sync
diff --git a/include/video_console.h b/include/video_console.h
index 3db9a7e1fb9..2694e44f6ec 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -72,6 +72,38 @@ struct vidfont_info {
};
/**
+ * struct vidconsole_colour - Holds colour information
+ *
+ * @colour_fg: Foreground colour (pixel value)
+ * @colour_bg: Background colour (pixel value)
+ */
+struct vidconsole_colour {
+ u32 colour_fg;
+ u32 colour_bg;
+};
+
+/**
+ * struct vidconsole_bbox - Bounding box of text
+ *
+ * This describes the bounding box of something, measured in pixels. The x0/y0
+ * pair is inclusive; the x1/y2 pair is exclusive, meaning that it is one pixel
+ * beyond the extent of the object
+ *
+ * @valid: Values are valid (bounding box is known)
+ * @x0: left x position, in pixels from left side
+ * @y0: top y position, in pixels from top
+ * @x1: right x position + 1
+ * @y1: botton y position + 1
+ */
+struct vidconsole_bbox {
+ bool valid;
+ int x0;
+ int y0;
+ int x1;
+ int y1;
+};
+
+/**
* struct vidconsole_ops - Video console operations
*
* These operations work on either an absolute console position (measured
@@ -178,6 +210,20 @@ struct vidconsole_ops {
* Returns: 0 on success, -ENOENT if no such font
*/
int (*select_font)(struct udevice *dev, const char *name, uint size);
+
+ /**
+ * measure() - Measure the bounds of some text
+ *
+ * @dev: Device to adjust
+ * @name: Font name to use (NULL to use default)
+ * @size: Font size to use (0 to use default)
+ * @text: Text to measure
+ * @bbox: Returns bounding box of text, assuming it is positioned
+ * at 0,0
+ * Returns: 0 on success, -ENOENT if no such font
+ */
+ int (*measure)(struct udevice *dev, const char *name, uint size,
+ const char *text, struct vidconsole_bbox *bbox);
};
/* Get a pointer to the driver operations for a video console device */
@@ -204,6 +250,38 @@ int vidconsole_get_font(struct udevice *dev, int seq,
*/
int vidconsole_select_font(struct udevice *dev, const char *name, uint size);
+/*
+ * vidconsole_measure() - Measuring the bounding box of some text
+ *
+ * @dev: Console device to use
+ * @name: Font name, NULL for default
+ * @size: Font size, ignored if @name is NULL
+ * @text: Text to measure
+ * @bbox: Returns nounding box of text
+ * Returns: 0 if OK, -ve on error
+ */
+int vidconsole_measure(struct udevice *dev, const char *name, uint size,
+ const char *text, struct vidconsole_bbox *bbox);
+
+/**
+ * vidconsole_push_colour() - Temporarily change the font colour
+ *
+ * @dev: Device to adjust
+ * @fg: Foreground colour to select
+ * @bg: Background colour to select
+ * @old: Place to store the current colour, so it can be restored
+ */
+void vidconsole_push_colour(struct udevice *dev, enum colour_idx fg,
+ enum colour_idx bg, struct vidconsole_colour *old);
+
+/**
+ * vidconsole_pop_colour() - Restore the original colour
+ *
+ * @dev: Device to adjust
+ * @old: Old colour to be restored
+ */
+void vidconsole_pop_colour(struct udevice *dev, struct vidconsole_colour *old);
+
/**
* vidconsole_putc_xy() - write a single character to a position
*
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index 7ac5f89f76d..a40762c74c8 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -344,3 +344,388 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle, void **load_options)
error:
return ret;
}
+
+/**
+ * efi_bootmgr_enumerate_boot_option() - enumerate the possible bootable media
+ *
+ * @opt: pointer to the media boot option structure
+ * @volume_handles: pointer to the efi handles
+ * @count: number of efi handle
+ * Return: status code
+ */
+static efi_status_t efi_bootmgr_enumerate_boot_option(struct eficonfig_media_boot_option *opt,
+ efi_handle_t *volume_handles,
+ efi_status_t count)
+{
+ u32 i;
+ struct efi_handler *handler;
+ efi_status_t ret = EFI_SUCCESS;
+
+ for (i = 0; i < count; i++) {
+ u16 *p;
+ u16 dev_name[BOOTMENU_DEVICE_NAME_MAX];
+ char *optional_data;
+ struct efi_load_option lo;
+ char buf[BOOTMENU_DEVICE_NAME_MAX];
+ struct efi_device_path *device_path;
+ struct efi_device_path *short_dp;
+
+ ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler);
+ if (ret != EFI_SUCCESS)
+ continue;
+ ret = efi_protocol_open(handler, (void **)&device_path,
+ efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (ret != EFI_SUCCESS)
+ continue;
+
+ ret = efi_disk_get_device_name(volume_handles[i], buf, BOOTMENU_DEVICE_NAME_MAX);
+ if (ret != EFI_SUCCESS)
+ continue;
+
+ p = dev_name;
+ utf8_utf16_strncpy(&p, buf, strlen(buf));
+
+ /* prefer to short form device path */
+ short_dp = efi_dp_shorten(device_path);
+ if (short_dp)
+ device_path = short_dp;
+
+ lo.label = dev_name;
+ lo.attributes = LOAD_OPTION_ACTIVE;
+ lo.file_path = device_path;
+ lo.file_path_length = efi_dp_size(device_path) + sizeof(END);
+ /*
+ * Set the dedicated guid to optional_data, it is used to identify
+ * the boot option that automatically generated by the bootmenu.
+ * efi_serialize_load_option() expects optional_data is null-terminated
+ * utf8 string, so set the "1234567" string to allocate enough space
+ * to store guid, instead of realloc the load_option.
+ */
+ lo.optional_data = "1234567";
+ opt[i].size = efi_serialize_load_option(&lo, (u8 **)&opt[i].lo);
+ if (!opt[i].size) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+ /* set the guid */
+ optional_data = (char *)opt[i].lo + (opt[i].size - u16_strsize(u"1234567"));
+ memcpy(optional_data, &efi_guid_bootmenu_auto_generated, sizeof(efi_guid_t));
+ }
+
+out:
+ return ret;
+}
+
+/**
+ * efi_bootmgr_delete_invalid_boot_option() - delete non-existing boot option
+ *
+ * @opt: pointer to the media boot option structure
+ * @count: number of media boot option structure
+ * Return: status code
+ */
+static efi_status_t efi_bootmgr_delete_invalid_boot_option(struct eficonfig_media_boot_option *opt,
+ efi_status_t count)
+{
+ efi_uintn_t size;
+ void *load_option;
+ u32 i, list_size = 0;
+ struct efi_load_option lo;
+ u16 *var_name16 = NULL;
+ u16 varname[] = u"Boot####";
+ efi_status_t ret = EFI_SUCCESS;
+ u16 *delete_index_list = NULL, *p;
+ efi_uintn_t buf_size;
+
+ buf_size = 128;
+ var_name16 = malloc(buf_size);
+ if (!var_name16)
+ return EFI_OUT_OF_RESOURCES;
+
+ var_name16[0] = 0;
+ for (;;) {
+ int index;
+ efi_guid_t guid;
+ efi_uintn_t tmp;
+
+ ret = efi_next_variable_name(&buf_size, &var_name16, &guid);
+ if (ret == EFI_NOT_FOUND) {
+ /*
+ * EFI_NOT_FOUND indicates we retrieved all EFI variables.
+ * This should be treated as success.
+ */
+ ret = EFI_SUCCESS;
+ break;
+ }
+
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+ if (!efi_varname_is_load_option(var_name16, &index))
+ continue;
+
+ efi_create_indexed_name(varname, sizeof(varname), "Boot", index);
+ load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
+ if (!load_option)
+ continue;
+
+ tmp = size;
+ ret = efi_deserialize_load_option(&lo, load_option, &size);
+ if (ret != EFI_SUCCESS)
+ goto next;
+
+ if (size >= sizeof(efi_guid_bootmenu_auto_generated) &&
+ !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) {
+ for (i = 0; i < count; i++) {
+ if (opt[i].size == tmp &&
+ memcmp(opt[i].lo, load_option, tmp) == 0) {
+ opt[i].exist = true;
+ break;
+ }
+ }
+
+ /*
+ * The entire list of variables must be retrieved by
+ * efi_get_next_variable_name_int() before deleting the invalid
+ * boot option, just save the index here.
+ */
+ if (i == count) {
+ p = realloc(delete_index_list, sizeof(u32) *
+ (list_size + 1));
+ if (!p) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+ delete_index_list = p;
+ delete_index_list[list_size++] = index;
+ }
+ }
+next:
+ free(load_option);
+ }
+
+ /* delete all invalid boot options */
+ for (i = 0; i < list_size; i++) {
+ ret = efi_bootmgr_delete_boot_option(delete_index_list[i]);
+ if (ret != EFI_SUCCESS)
+ goto out;
+ }
+
+out:
+ free(var_name16);
+ free(delete_index_list);
+
+ return ret;
+}
+
+/**
+ * efi_bootmgr_get_unused_bootoption() - get unused "Boot####" index
+ *
+ * @buf: pointer to the buffer to store boot option variable name
+ * @buf_size: buffer size
+ * @index: pointer to store the index in the BootOrder variable
+ * Return: status code
+ */
+efi_status_t efi_bootmgr_get_unused_bootoption(u16 *buf, efi_uintn_t buf_size,
+ unsigned int *index)
+{
+ u32 i;
+ efi_status_t ret;
+ efi_uintn_t size;
+
+ if (buf_size < u16_strsize(u"Boot####"))
+ return EFI_BUFFER_TOO_SMALL;
+
+ for (i = 0; i <= 0xFFFF; i++) {
+ size = 0;
+ efi_create_indexed_name(buf, buf_size, "Boot", i);
+ ret = efi_get_variable_int(buf, &efi_global_variable_guid,
+ NULL, &size, NULL, NULL);
+ if (ret == EFI_BUFFER_TOO_SMALL)
+ continue;
+ else
+ break;
+ }
+
+ if (i > 0xFFFF)
+ return EFI_OUT_OF_RESOURCES;
+
+ *index = i;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ * efi_bootmgr_append_bootorder() - append new boot option in BootOrder variable
+ *
+ * @index: "Boot####" index to append to BootOrder variable
+ * Return: status code
+ */
+efi_status_t efi_bootmgr_append_bootorder(u16 index)
+{
+ u16 *bootorder;
+ efi_status_t ret;
+ u16 *new_bootorder = NULL;
+ efi_uintn_t last, size, new_size;
+
+ /* append new boot option */
+ bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
+ last = size / sizeof(u16);
+ new_size = size + sizeof(u16);
+ new_bootorder = calloc(1, new_size);
+ if (!new_bootorder) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+ memcpy(new_bootorder, bootorder, size);
+ new_bootorder[last] = index;
+
+ ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ new_size, new_bootorder, false);
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+out:
+ free(bootorder);
+ free(new_bootorder);
+
+ return ret;
+}
+
+/**
+ * efi_bootmgr_delete_boot_option() - delete selected boot option
+ *
+ * @boot_index: boot option index to delete
+ * Return: status code
+ */
+efi_status_t efi_bootmgr_delete_boot_option(u16 boot_index)
+{
+ u16 *bootorder;
+ u16 varname[9];
+ efi_status_t ret;
+ unsigned int index;
+ efi_uintn_t num, size;
+
+ efi_create_indexed_name(varname, sizeof(varname),
+ "Boot", boot_index);
+ ret = efi_set_variable_int(varname, &efi_global_variable_guid,
+ 0, 0, NULL, false);
+ if (ret != EFI_SUCCESS) {
+ log_err("delete boot option(%ls) failed\n", varname);
+ return ret;
+ }
+
+ /* update BootOrder if necessary */
+ bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
+ if (!bootorder)
+ return EFI_SUCCESS;
+
+ num = size / sizeof(u16);
+ if (!efi_search_bootorder(bootorder, num, boot_index, &index))
+ return EFI_SUCCESS;
+
+ memmove(&bootorder[index], &bootorder[index + 1],
+ (num - index - 1) * sizeof(u16));
+ size -= sizeof(u16);
+ ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ size, bootorder, false);
+
+ return ret;
+}
+
+/**
+ * efi_bootmgr_update_media_device_boot_option() - generate the media device boot option
+ *
+ * This function enumerates all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
+ * and generate the bootmenu entries.
+ * This function also provide the BOOT#### variable maintenance for
+ * the media device entries.
+ * - Automatically create the BOOT#### variable for the newly detected device,
+ * this BOOT#### variable is distinguished by the special GUID
+ * stored in the EFI_LOAD_OPTION.optional_data
+ * - If the device is not attached to the system, the associated BOOT#### variable
+ * is automatically deleted.
+ *
+ * Return: status code
+ */
+efi_status_t efi_bootmgr_update_media_device_boot_option(void)
+{
+ u32 i;
+ efi_status_t ret;
+ efi_uintn_t count;
+ efi_handle_t *volume_handles = NULL;
+ struct eficonfig_media_boot_option *opt = NULL;
+
+ ret = efi_locate_handle_buffer_int(BY_PROTOCOL,
+ &efi_simple_file_system_protocol_guid,
+ NULL, &count,
+ (efi_handle_t **)&volume_handles);
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+ opt = calloc(count, sizeof(struct eficonfig_media_boot_option));
+ if (!opt) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+
+ /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */
+ ret = efi_bootmgr_enumerate_boot_option(opt, volume_handles, count);
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+ /*
+ * System hardware configuration may vary depending on the user setup.
+ * The boot option is automatically added by the bootmenu.
+ * If the device is not attached to the system, the boot option needs
+ * to be deleted.
+ */
+ ret = efi_bootmgr_delete_invalid_boot_option(opt, count);
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+ /* add non-existent boot option */
+ for (i = 0; i < count; i++) {
+ u32 boot_index;
+ u16 var_name[9];
+
+ if (!opt[i].exist) {
+ ret = efi_bootmgr_get_unused_bootoption(var_name, sizeof(var_name),
+ &boot_index);
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+ ret = efi_set_variable_int(var_name, &efi_global_variable_guid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ opt[i].size, opt[i].lo, false);
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+ ret = efi_bootmgr_append_bootorder(boot_index);
+ if (ret != EFI_SUCCESS) {
+ efi_set_variable_int(var_name, &efi_global_variable_guid,
+ 0, 0, NULL, false);
+ goto out;
+ }
+ }
+ }
+
+out:
+ if (opt) {
+ for (i = 0; i < count; i++)
+ free(opt[i].lo);
+ }
+ free(opt);
+ efi_free_pool(volume_handles);
+
+ if (ret == EFI_NOT_FOUND)
+ return EFI_SUCCESS;
+ return ret;
+}
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index d5065f296ae..2ca7359f3e1 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -97,6 +97,12 @@ static efi_status_t EFIAPI efi_disconnect_controller(
efi_handle_t driver_image_handle,
efi_handle_t child_handle);
+static
+efi_status_t EFIAPI efi_connect_controller(efi_handle_t controller_handle,
+ efi_handle_t *driver_image_handle,
+ struct efi_device_path *remain_device_path,
+ bool recursive);
+
/* Called on every callback entry */
int __efi_entry_check(void)
{
@@ -1298,7 +1304,7 @@ static efi_status_t efi_disconnect_all_drivers
const efi_guid_t *protocol,
efi_handle_t child_handle)
{
- efi_uintn_t number_of_drivers;
+ efi_uintn_t number_of_drivers, tmp;
efi_handle_t *driver_handle_buffer;
efi_status_t r, ret;
@@ -1308,15 +1314,30 @@ static efi_status_t efi_disconnect_all_drivers
return ret;
if (!number_of_drivers)
return EFI_SUCCESS;
- ret = EFI_NOT_FOUND;
+
+ tmp = number_of_drivers;
while (number_of_drivers) {
- r = EFI_CALL(efi_disconnect_controller(
+ ret = EFI_CALL(efi_disconnect_controller(
handle,
driver_handle_buffer[--number_of_drivers],
child_handle));
- if (r == EFI_SUCCESS)
- ret = r;
+ if (ret != EFI_SUCCESS)
+ goto reconnect;
}
+
+ free(driver_handle_buffer);
+ return ret;
+
+reconnect:
+ /* Reconnect all disconnected drivers */
+ for (; number_of_drivers < tmp; number_of_drivers++) {
+ r = EFI_CALL(efi_connect_controller(handle,
+ &driver_handle_buffer[number_of_drivers],
+ NULL, true));
+ if (r != EFI_SUCCESS)
+ EFI_PRINT("Failed to reconnect controller\n");
+ }
+
free(driver_handle_buffer);
return ret;
}
@@ -1352,18 +1373,26 @@ static efi_status_t efi_uninstall_protocol
r = efi_search_protocol(handle, protocol, &handler);
if (r != EFI_SUCCESS)
goto out;
+ if (handler->protocol_interface != protocol_interface)
+ return EFI_NOT_FOUND;
/* Disconnect controllers */
- efi_disconnect_all_drivers(efiobj, protocol, NULL);
+ r = efi_disconnect_all_drivers(efiobj, protocol, NULL);
+ if (r != EFI_SUCCESS) {
+ r = EFI_ACCESS_DENIED;
+ goto out;
+ }
/* Close protocol */
list_for_each_entry_safe(item, pos, &handler->open_infos, link) {
if (item->info.attributes ==
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL ||
item->info.attributes == EFI_OPEN_PROTOCOL_GET_PROTOCOL ||
item->info.attributes == EFI_OPEN_PROTOCOL_TEST_PROTOCOL)
- list_del(&item->link);
+ efi_delete_open_info(item);
}
+ /* if agents didn't close the protocols properly */
if (!list_empty(&handler->open_infos)) {
r = EFI_ACCESS_DENIED;
+ EFI_CALL(efi_connect_controller(handle, NULL, NULL, true));
goto out;
}
r = efi_remove_protocol(handle, protocol, protocol_interface);
diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c
index 1f4ab2b419a..cdfd16ea774 100644
--- a/lib/efi_loader/efi_helper.c
+++ b/lib/efi_loader/efi_helper.c
@@ -257,3 +257,28 @@ efi_status_t efi_next_variable_name(efi_uintn_t *size, u16 **buf, efi_guid_t *gu
return ret;
}
+
+/**
+ * efi_search_bootorder() - search the boot option index in BootOrder
+ *
+ * @bootorder: pointer to the BootOrder variable
+ * @num: number of BootOrder entry
+ * @target: target boot option index to search
+ * @index: pointer to store the index of BootOrder variable
+ * Return: true if exists, false otherwise
+ */
+bool efi_search_bootorder(u16 *bootorder, efi_uintn_t num, u32 target, u32 *index)
+{
+ u32 i;
+
+ for (i = 0; i < num; i++) {
+ if (target == bootorder[i]) {
+ if (index)
+ *index = i;
+
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/lib/efi_selftest/efi_selftest_controllers.c b/lib/efi_selftest/efi_selftest_controllers.c
index 63e674bedc0..02f19574f83 100644
--- a/lib/efi_selftest/efi_selftest_controllers.c
+++ b/lib/efi_selftest/efi_selftest_controllers.c
@@ -28,6 +28,7 @@ static efi_guid_t guid_child_controller =
static efi_handle_t handle_controller;
static efi_handle_t handle_child_controller[NUMBER_OF_CHILD_CONTROLLERS];
static efi_handle_t handle_driver;
+static bool allow_removal;
/*
* Count child controllers
@@ -85,8 +86,8 @@ static efi_status_t EFIAPI supported(
controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER);
switch (ret) {
case EFI_ACCESS_DENIED:
- case EFI_ALREADY_STARTED:
return ret;
+ case EFI_ALREADY_STARTED:
case EFI_SUCCESS:
break;
default:
@@ -124,8 +125,8 @@ static efi_status_t EFIAPI start(
controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER);
switch (ret) {
case EFI_ACCESS_DENIED:
- case EFI_ALREADY_STARTED:
return ret;
+ case EFI_ALREADY_STARTED:
case EFI_SUCCESS:
break;
default:
@@ -238,6 +239,9 @@ static efi_status_t EFIAPI stop(
if (ret != EFI_SUCCESS)
efi_st_error("Cannot free buffer\n");
+ if (!allow_removal)
+ return EFI_DEVICE_ERROR;
+
/* Detach driver from controller */
ret = boottime->close_protocol(
controller_handle, &guid_controller,
@@ -342,6 +346,7 @@ static int execute(void)
return EFI_ST_FAILURE;
}
/* Destroy remaining child controllers and disconnect controller */
+ allow_removal = true;
ret = boottime->disconnect_controller(handle_controller, NULL, NULL);
if (ret != EFI_SUCCESS) {
efi_st_error("Failed to disconnect controller\n");
@@ -393,7 +398,40 @@ static int execute(void)
efi_st_error("Number of children %u != %u\n",
(unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS);
}
- /* Uninstall controller protocol */
+
+ allow_removal = false;
+ /* Try to uninstall controller protocol using the wrong interface */
+ ret = boottime->uninstall_protocol_interface(handle_controller,
+ &guid_controller,
+ &interface1);
+ if (ret != EFI_NOT_FOUND) {
+ efi_st_error("Interface not checked when uninstalling protocol\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /*
+ * Uninstall a protocol while Disconnect controller won't
+ * allow it.
+ */
+ ret = boottime->uninstall_protocol_interface(handle_controller,
+ &guid_controller,
+ &interface2);
+ if (ret != EFI_ACCESS_DENIED) {
+ efi_st_error("Uninstall protocol interface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ /*
+ * Check number of child controllers and make sure children have
+ * been reconnected
+ */
+ ret = count_child_controllers(handle_controller, &guid_controller,
+ &count);
+ if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS) {
+ efi_st_error("Number of children %u != %u\n",
+ (unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS);
+ }
+
+ allow_removal = true;
ret = boottime->uninstall_protocol_interface(handle_controller,
&guid_controller,
&interface2);
diff --git a/lib/lzma/LzmaDec.c b/lib/lzma/LzmaDec.c
index 341149f766b..a90b35c6a99 100644
--- a/lib/lzma/LzmaDec.c
+++ b/lib/lzma/LzmaDec.c
@@ -152,8 +152,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
const Byte *buf = p->buf;
UInt32 range = p->range;
UInt32 code = p->code;
-
- schedule();
+ unsigned int loop = 0;
do
{
@@ -162,6 +161,9 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
unsigned ttt;
unsigned posState = processedPos & pbMask;
+ if (!(loop++ & 1023))
+ schedule();
+
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
IF_BIT_0(prob)
{
@@ -177,8 +179,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
state -= (state < 4) ? state : 3;
symbol = 1;
- schedule();
-
do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
}
else
@@ -188,8 +188,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
state -= (state < 10) ? 3 : 6;
symbol = 1;
- schedule();
-
do
{
unsigned bit;
@@ -321,8 +319,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
UInt32 mask = 1;
unsigned i = 1;
- schedule();
-
do
{
GET_BIT2(prob + i, i, ; , distance |= mask);
@@ -335,8 +331,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
{
numDirectBits -= kNumAlignBits;
- schedule();
-
do
{
NORMALIZE
@@ -409,8 +403,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
const Byte *lim = dest + curLen;
dicPos += curLen;
- schedule();
-
do
*(dest) = (Byte)*(dest + src);
while (++dest != lim);
@@ -418,8 +410,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
else
{
- schedule();
-
do
{
dic[dicPos++] = dic[pos];
diff --git a/lib/of_live.c b/lib/of_live.c
index 1b5964d09a9..25f7af61061 100644
--- a/lib/of_live.c
+++ b/lib/of_live.c
@@ -287,9 +287,12 @@ int unflatten_device_tree(const void *blob, struct device_node **mynodes)
debug(" size is %lx, allocating...\n", size);
/* Allocate memory for the expanded device tree */
- mem = malloc(size + 4);
+ mem = memalign(__alignof__(struct device_node), size + 4);
memset(mem, '\0', size);
+ /* Set up value for dm_test_livetree_align() */
+ *(u32 *)mem = BAD_OF_ROOT;
+
*(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef);
debug(" unflattening %p...\n", mem);
@@ -327,3 +330,9 @@ int of_live_build(const void *fdt_blob, struct device_node **rootp)
return ret;
}
+
+void of_live_free(struct device_node *root)
+{
+ /* the tree is stored as a contiguous block of memory */
+ free(root);
+}
diff --git a/lib/zlib/inflate.c b/lib/zlib/inflate.c
index 30dfe155995..8f767b7b9d2 100644
--- a/lib/zlib/inflate.c
+++ b/lib/zlib/inflate.c
@@ -455,8 +455,9 @@ int ZEXPORT inflate(z_streamp strm, int flush)
if (copy > have) copy = have;
if (copy) {
if (state->head != Z_NULL &&
- state->head->extra != Z_NULL) {
- len = state->head->extra_len - state->length;
+ state->head->extra != Z_NULL &&
+ (len = state->head->extra_len - state->length) <
+ state->head->extra_max) {
zmemcpy(state->head->extra + len, next,
len + copy > state->head->extra_max ?
state->head->extra_max - len : copy);
diff --git a/test/boot/expo.c b/test/boot/expo.c
index 7104dff05e8..3898f853a75 100644
--- a/test/boot/expo.c
+++ b/test/boot/expo.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <command.h>
#include <dm.h>
#include <expo.h>
#include <menu.h>
@@ -13,6 +14,7 @@
#include <test/suites.h>
#include <test/ut.h>
#include "bootstd_common.h"
+#include <test/cedit-test.h>
#include "../../boot/scene_internal.h"
enum {
@@ -28,6 +30,8 @@ enum {
OBJ_MENU_TITLE,
/* strings */
+ STR_SCENE_TITLE,
+
STR_TEXT,
STR_TEXT2,
STR_MENU_TITLE,
@@ -120,7 +124,7 @@ static int expo_scene(struct unit_test_state *uts)
struct expo *exp;
ulong start_mem;
char name[100];
- int id;
+ int id, title_id;
start_mem = ut_check_free();
@@ -141,21 +145,20 @@ static int expo_scene(struct unit_test_state *uts)
ut_asserteq_str(SCENE_NAME1, scn->name);
/* Set the title */
- strcpy(name, SCENE_TITLE);
- ut_assertok(scene_title_set(scn, name));
- *name = '\0';
- ut_assertnonnull(scn->title);
- ut_asserteq_str(SCENE_TITLE, scn->title);
+ title_id = expo_str(exp, "title", STR_SCENE_TITLE, SCENE_TITLE);
+ ut_assert(title_id >= 0);
- /* Use an allocated ID */
+ /* Use an allocated ID - this will be allocated after the title str */
scn = NULL;
id = scene_new(exp, SCENE_NAME2, 0, &scn);
ut_assertnonnull(scn);
- ut_asserteq(SCENE2, id);
- ut_asserteq(SCENE2 + 1, exp->next_id);
+ ut_assertok(scene_title_set(scn, title_id));
+ ut_asserteq(STR_SCENE_TITLE + 1, id);
+ ut_asserteq(STR_SCENE_TITLE + 2, exp->next_id);
ut_asserteq_ptr(exp, scn->expo);
ut_asserteq_str(SCENE_NAME2, scn->name);
+ ut_asserteq(title_id, scn->title_id);
expo_destroy(exp);
@@ -225,7 +228,7 @@ static int expo_object(struct unit_test_state *uts)
}
BOOTSTD_TEST(expo_object, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
-/* Check setting object attributes */
+/* Check setting object attributes and using themes */
static int expo_object_attr(struct unit_test_state *uts)
{
struct scene_obj_menu *menu;
@@ -235,6 +238,7 @@ static int expo_object_attr(struct unit_test_state *uts)
struct expo *exp;
ulong start_mem;
char name[100];
+ ofnode node;
char *data;
int id;
@@ -249,8 +253,8 @@ static int expo_object_attr(struct unit_test_state *uts)
ut_assert(id > 0);
ut_assertok(scene_obj_set_pos(scn, OBJ_LOGO, 123, 456));
- ut_asserteq(123, img->obj.x);
- ut_asserteq(456, img->obj.y);
+ ut_asserteq(123, img->obj.dim.x);
+ ut_asserteq(456, img->obj.dim.y);
ut_asserteq(-ENOENT, scene_obj_set_pos(scn, OBJ_TEXT2, 0, 0));
@@ -272,6 +276,11 @@ static int expo_object_attr(struct unit_test_state *uts)
ut_asserteq(-ENOENT, scene_menu_set_title(scn, OBJ_TEXT2, OBJ_TEXT));
ut_asserteq(-EINVAL, scene_menu_set_title(scn, OBJ_MENU, OBJ_TEXT2));
+ node = ofnode_path("/bootstd/theme");
+ ut_assert(ofnode_valid(node));
+ ut_assertok(expo_apply_theme(exp, node));
+ ut_asserteq(30, txt->font_size);
+
expo_destroy(exp);
ut_assertok(ut_check_delta(start_mem));
@@ -306,8 +315,8 @@ static int expo_object_menu(struct unit_test_state *uts)
ut_asserteq(0, menu->pointer_id);
ut_assertok(scene_obj_set_pos(scn, OBJ_MENU, 50, 400));
- ut_asserteq(50, menu->obj.x);
- ut_asserteq(400, menu->obj.y);
+ ut_asserteq(50, menu->obj.dim.x);
+ ut_asserteq(400, menu->obj.dim.y);
id = scene_txt_str(scn, "title", OBJ_MENU_TITLE, STR_MENU_TITLE,
"Main Menu", &tit);
@@ -347,29 +356,31 @@ static int expo_object_menu(struct unit_test_state *uts)
ut_asserteq(desc_id, item->desc_id);
ut_asserteq(preview_id, item->preview_id);
- /* adding an item should cause the first item to become current */
+ ut_assertok(scene_arrange(scn));
+
+ /* arranging the scene should cause the first item to become current */
ut_asserteq(id, menu->cur_item_id);
/* the title should be at the top */
- ut_asserteq(menu->obj.x, tit->obj.x);
- ut_asserteq(menu->obj.y, tit->obj.y);
+ ut_asserteq(menu->obj.dim.x, tit->obj.dim.x);
+ ut_asserteq(menu->obj.dim.y, tit->obj.dim.y);
/* the first item should be next */
- ut_asserteq(menu->obj.x, name1->obj.x);
- ut_asserteq(menu->obj.y + 32, name1->obj.y);
+ ut_asserteq(menu->obj.dim.x, name1->obj.dim.x);
+ ut_asserteq(menu->obj.dim.y + 32, name1->obj.dim.y);
- ut_asserteq(menu->obj.x + 230, key1->obj.x);
- ut_asserteq(menu->obj.y + 32, key1->obj.y);
+ ut_asserteq(menu->obj.dim.x + 230, key1->obj.dim.x);
+ ut_asserteq(menu->obj.dim.y + 32, key1->obj.dim.y);
- ut_asserteq(menu->obj.x + 200, ptr->obj.x);
- ut_asserteq(menu->obj.y + 32, ptr->obj.y);
+ ut_asserteq(menu->obj.dim.x + 200, ptr->obj.dim.x);
+ ut_asserteq(menu->obj.dim.y + 32, ptr->obj.dim.y);
- ut_asserteq(menu->obj.x + 280, desc1->obj.x);
- ut_asserteq(menu->obj.y + 32, desc1->obj.y);
+ ut_asserteq(menu->obj.dim.x + 280, desc1->obj.dim.x);
+ ut_asserteq(menu->obj.dim.y + 32, desc1->obj.dim.y);
- ut_asserteq(-4, prev1->obj.x);
- ut_asserteq(menu->obj.y + 32, prev1->obj.y);
- ut_asserteq(false, prev1->obj.hide);
+ ut_asserteq(-4, prev1->obj.dim.x);
+ ut_asserteq(menu->obj.dim.y + 32, prev1->obj.dim.y);
+ ut_asserteq(true, prev1->obj.flags & SCENEOF_HIDE);
expo_destroy(exp);
@@ -470,6 +481,48 @@ static int expo_render_image(struct unit_test_state *uts)
/* render without a scene */
ut_asserteq(-ECHILD, expo_render(exp));
+ ut_assertok(expo_calc_dims(exp));
+ ut_assertok(scene_arrange(scn));
+
+ /* check dimensions of text */
+ obj = scene_obj_find(scn, OBJ_TEXT, SCENEOBJT_NONE);
+ ut_assertnonnull(obj);
+ ut_asserteq(400, obj->dim.x);
+ ut_asserteq(100, obj->dim.y);
+ ut_asserteq(126, obj->dim.w);
+ ut_asserteq(40, obj->dim.h);
+
+ /* check dimensions of image */
+ obj = scene_obj_find(scn, OBJ_LOGO, SCENEOBJT_NONE);
+ ut_assertnonnull(obj);
+ ut_asserteq(50, obj->dim.x);
+ ut_asserteq(20, obj->dim.y);
+ ut_asserteq(160, obj->dim.w);
+ ut_asserteq(160, obj->dim.h);
+
+ /* check dimensions of menu labels - both should be the same width */
+ obj = scene_obj_find(scn, ITEM1_LABEL, SCENEOBJT_NONE);
+ ut_assertnonnull(obj);
+ ut_asserteq(50, obj->dim.x);
+ ut_asserteq(436, obj->dim.y);
+ ut_asserteq(29, obj->dim.w);
+ ut_asserteq(18, obj->dim.h);
+
+ obj = scene_obj_find(scn, ITEM2_LABEL, SCENEOBJT_NONE);
+ ut_assertnonnull(obj);
+ ut_asserteq(50, obj->dim.x);
+ ut_asserteq(454, obj->dim.y);
+ ut_asserteq(29, obj->dim.w);
+ ut_asserteq(18, obj->dim.h);
+
+ /* check dimensions of menu */
+ obj = scene_obj_find(scn, OBJ_MENU, SCENEOBJT_NONE);
+ ut_assertnonnull(obj);
+ ut_asserteq(50, obj->dim.x);
+ ut_asserteq(400, obj->dim.y);
+ ut_asserteq(160, obj->dim.w);
+ ut_asserteq(160, obj->dim.h);
+
/* render it */
expo_set_scene_id(exp, SCENE1);
ut_assertok(expo_render(exp));
@@ -479,16 +532,16 @@ static int expo_render_image(struct unit_test_state *uts)
ut_assertok(expo_action_get(exp, &act));
- ut_asserteq(EXPOACT_POINT, act.type);
+ ut_asserteq(EXPOACT_POINT_ITEM, act.type);
ut_asserteq(ITEM2, act.select.id);
ut_assertok(expo_render(exp));
/* make sure only the preview for the second item is shown */
obj = scene_obj_find(scn, ITEM1_PREVIEW, SCENEOBJT_NONE);
- ut_asserteq(true, obj->hide);
+ ut_asserteq(true, obj->flags & SCENEOF_HIDE);
obj = scene_obj_find(scn, ITEM2_PREVIEW, SCENEOBJT_NONE);
- ut_asserteq(false, obj->hide);
+ ut_asserteq(false, obj->flags & SCENEOF_HIDE);
/* select it */
ut_assertok(expo_send_key(exp, BKEY_SELECT));
@@ -504,7 +557,7 @@ static int expo_render_image(struct unit_test_state *uts)
ut_assert_console_end();
/* now try in text mode */
- exp_set_text_mode(exp, true);
+ expo_set_text_mode(exp, true);
ut_assertok(expo_render(exp));
ut_assert_nextline("U-Boot : Boot Menu");
@@ -519,7 +572,7 @@ static int expo_render_image(struct unit_test_state *uts)
ut_assertok(expo_action_get(exp, &act));
- ut_asserteq(EXPOACT_POINT, act.type);
+ ut_asserteq(EXPOACT_POINT_ITEM, act.type);
ut_asserteq(ITEM1, act.select.id);
ut_assertok(expo_render(exp));
@@ -537,3 +590,125 @@ static int expo_render_image(struct unit_test_state *uts)
return 0;
}
BOOTSTD_TEST(expo_render_image, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/* Check building an expo from a devicetree description */
+static int expo_test_build(struct unit_test_state *uts)
+{
+ struct scene_obj_menu *menu;
+ struct scene_menitem *item;
+ struct scene_obj_txt *txt;
+ struct scene_obj *obj;
+ struct scene *scn;
+ struct expo *exp;
+ int count;
+ ofnode node;
+
+ node = ofnode_path("/cedit");
+ ut_assert(ofnode_valid(node));
+ ut_assertok(expo_build(node, &exp));
+
+ ut_asserteq_str("name", exp->name);
+ ut_asserteq(0, exp->scene_id);
+ ut_asserteq(ID_DYNAMIC_START + 20, exp->next_id);
+ ut_asserteq(false, exp->popup);
+
+ /* check the scene */
+ scn = expo_lookup_scene_id(exp, ID_SCENE1);
+ ut_assertnonnull(scn);
+ ut_asserteq_str("main", scn->name);
+ ut_asserteq(ID_SCENE1, scn->id);
+ ut_asserteq(ID_DYNAMIC_START + 1, scn->title_id);
+ ut_asserteq(0, scn->highlight_id);
+
+ /* check the title */
+ txt = scene_obj_find(scn, scn->title_id, SCENEOBJT_NONE);
+ ut_assertnonnull(txt);
+ obj = &txt->obj;
+ ut_asserteq_ptr(scn, obj->scene);
+ ut_asserteq_str("title", obj->name);
+ ut_asserteq(scn->title_id, obj->id);
+ ut_asserteq(SCENEOBJT_TEXT, obj->type);
+ ut_asserteq(0, obj->flags);
+ ut_asserteq_str("Test Configuration", expo_get_str(exp, txt->str_id));
+
+ /* check the menu */
+ menu = scene_obj_find(scn, ID_CPU_SPEED, SCENEOBJT_NONE);
+ obj = &menu->obj;
+ ut_asserteq_ptr(scn, obj->scene);
+ ut_asserteq_str("cpu-speed", obj->name);
+ ut_asserteq(ID_CPU_SPEED, obj->id);
+ ut_asserteq(SCENEOBJT_MENU, obj->type);
+ ut_asserteq(0, obj->flags);
+
+ txt = scene_obj_find(scn, menu->title_id, SCENEOBJT_NONE);
+ ut_asserteq_str("CPU speed", expo_get_str(exp, txt->str_id));
+
+ ut_asserteq(0, menu->cur_item_id);
+ ut_asserteq(0, menu->pointer_id);
+
+ /* check the items */
+ item = list_first_entry(&menu->item_head, struct scene_menitem,
+ sibling);
+ ut_asserteq_str("00", item->name);
+ ut_asserteq(ID_CPU_SPEED_1, item->id);
+ ut_asserteq(0, item->key_id);
+ ut_asserteq(0, item->desc_id);
+ ut_asserteq(0, item->preview_id);
+ ut_asserteq(0, item->flags);
+
+ txt = scene_obj_find(scn, item->label_id, SCENEOBJT_NONE);
+ ut_asserteq_str("2 GHz", expo_get_str(exp, txt->str_id));
+
+ count = 0;
+ list_for_each_entry(item, &menu->item_head, sibling)
+ count++;
+ ut_asserteq(3, count);
+
+ expo_destroy(exp);
+
+ return 0;
+}
+BOOTSTD_TEST(expo_test_build, UT_TESTF_DM);
+
+/* Check the cedit command */
+static int expo_cedit(struct unit_test_state *uts)
+{
+ extern struct expo *cur_exp;
+ struct scene_obj_menu *menu;
+ struct scene_obj_txt *txt;
+ struct expo *exp;
+ struct scene *scn;
+
+ if (!IS_ENABLED(CONFIG_CMD_CEDIT))
+ return -EAGAIN;
+
+ ut_assertok(run_command("cedit load hostfs - cedit.dtb", 0));
+
+ console_record_reset_enable();
+
+ /*
+ * ^N Move down to second menu
+ * ^M Open menu
+ * ^N Move down to second item
+ * ^M Select item
+ * \e Quit
+ */
+ console_in_puts("\x0e\x0d\x0e\x0d\e");
+ ut_assertok(run_command("cedit run", 0));
+
+ exp = cur_exp;
+ scn = expo_lookup_scene_id(exp, exp->scene_id);
+ ut_assertnonnull(scn);
+
+ menu = scene_obj_find(scn, scn->highlight_id, SCENEOBJT_NONE);
+ ut_assertnonnull(menu);
+
+ txt = scene_obj_find(scn, menu->title_id, SCENEOBJT_NONE);
+ ut_assertnonnull(txt);
+ ut_asserteq_str("AC Power", expo_get_str(exp, txt->str_id));
+
+ ut_asserteq(ID_AC_ON, menu->cur_item_id);
+
+ return 0;
+}
+BOOTSTD_TEST(expo_cedit, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
diff --git a/test/boot/files/expo_layout.dts b/test/boot/files/expo_layout.dts
new file mode 100644
index 00000000000..55d5c910dd5
--- /dev/null
+++ b/test/boot/files/expo_layout.dts
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Sample expo screen layout
+ */
+
+/dts-v1/;
+
+/*
+enum {
+ ZERO,
+ ID_PROMPT,
+
+ ID_SCENE1,
+ ID_SCENE1_TITLE,
+
+ ID_CPU_SPEED,
+ ID_CPU_SPEED_TITLE,
+ ID_CPU_SPEED_1,
+ ID_CPU_SPEED_2,
+ ID_CPU_SPEED_3,
+
+ ID_POWER_LOSS,
+ ID_AC_OFF,
+ ID_AC_ON,
+ ID_AC_MEMORY,
+
+ ID_DYNAMIC_START,
+};
+*/
+
+/ {
+ dynamic-start = <ID_DYNAMIC_START>;
+
+ scenes {
+ main {
+ id = <ID_SCENE1>;
+
+ /* value refers to the matching id in /strings */
+ title-id = <ID_SCENE1_TITLE>;
+
+ /* simple string is used as it is */
+ prompt = "UP and DOWN to choose, ENTER to select";
+
+ /* defines a menu within the scene */
+ cpu-speed {
+ type = "menu";
+ id = <ID_CPU_SPEED>;
+
+ /*
+ * has both string and ID. The string is ignored
+ * if the ID is present and points to a string
+ */
+ title = "CPU speed";
+ title-id = <ID_CPU_SPEED_TITLE>;
+
+ /* menu items as simple strings */
+ item-label = "2 GHz", "2.5 GHz", "3 GHz";
+
+ /* IDs for the menu items */
+ item-id = <ID_CPU_SPEED_1 ID_CPU_SPEED_2
+ ID_CPU_SPEED_3>;
+ };
+
+ power-loss {
+ type = "menu";
+ id = <ID_POWER_LOSS>;
+
+ title = "AC Power";
+ item-label = "Always Off", "Always On",
+ "Memory";
+
+ item-id = <ID_AC_OFF ID_AC_ON ID_AC_MEMORY>;
+ };
+ };
+ };
+
+ strings {
+ title {
+ id = <ID_SCENE1_TITLE>;
+ value = "Test Configuration";
+ value-es = "configuración de prueba";
+ };
+ };
+};
diff --git a/test/cmd/bdinfo.c b/test/cmd/bdinfo.c
index 9068df79c4f..cddf1a46d49 100644
--- a/test/cmd/bdinfo.c
+++ b/test/cmd/bdinfo.c
@@ -27,19 +27,25 @@ DECLARE_GLOBAL_DATA_PTR;
/* Declare a new bdinfo test */
#define BDINFO_TEST(_name, _flags) UNIT_TEST(_name, _flags, bdinfo_test)
-static void bdinfo_test_num_l(struct unit_test_state *uts,
- const char *name, ulong value)
+static int test_num_l(struct unit_test_state *uts, const char *name,
+ ulong value)
{
- ut_assert_nextline("%-12s= 0x%0*lx", name, 2 * (int)sizeof(value), value);
+ ut_assert_nextline("%-12s= 0x%0*lx", name, 2 * (int)sizeof(value),
+ value);
+
+ return 0;
}
-static void bdinfo_test_num_ll(struct unit_test_state *uts,
- const char *name, unsigned long long value)
+static int test_num_ll(struct unit_test_state *uts, const char *name,
+ unsigned long long value)
{
- ut_assert_nextline("%-12s= 0x%.*llx", name, 2 * (int)sizeof(ulong), value);
+ ut_assert_nextline("%-12s= 0x%.*llx", name, 2 * (int)sizeof(ulong),
+ value);
+
+ return 0;
}
-static void test_eth(struct unit_test_state *uts)
+static int test_eth(struct unit_test_state *uts)
{
const int idx = eth_get_dev_index();
uchar enetaddr[6];
@@ -59,9 +65,11 @@ static void test_eth(struct unit_test_state *uts)
else
ut_assert_nextline("%-12s= %pM", name, enetaddr);
ut_assert_nextline("IP addr = %s", env_get("ipaddr"));
+
+ return 0;
}
-static void test_video_info(struct unit_test_state *uts)
+static int test_video_info(struct unit_test_state *uts)
{
const struct udevice *dev;
struct uclass *uc;
@@ -73,22 +81,25 @@ static void test_video_info(struct unit_test_state *uts)
struct video_priv *upriv = dev_get_uclass_priv(dev);
struct video_uc_plat *plat = dev_get_uclass_plat(dev);
- bdinfo_test_num_ll(uts, "FB base", (ulong)upriv->fb);
+ ut_assertok(test_num_ll(uts, "FB base",
+ (ulong)upriv->fb));
if (upriv->copy_fb) {
- bdinfo_test_num_ll(uts, "FB copy",
- (ulong)upriv->copy_fb);
- bdinfo_test_num_l(uts, " copy size",
- plat->copy_size);
+ ut_assertok(test_num_ll(uts, "FB copy",
+ (ulong)upriv->copy_fb));
+ ut_assertok(test_num_l(uts, " copy size",
+ plat->copy_size));
}
ut_assert_nextline("%-12s= %dx%dx%d", "FB size",
upriv->xsize, upriv->ysize,
1 << upriv->bpix);
}
}
+
+ return 0;
}
-static void lmb_test_dump_region(struct unit_test_state *uts,
- struct lmb_region *rgn, char *name)
+static int lmb_test_dump_region(struct unit_test_state *uts,
+ struct lmb_region *rgn, char *name)
{
unsigned long long base, size, end;
enum lmb_flags flags;
@@ -105,13 +116,17 @@ static void lmb_test_dump_region(struct unit_test_state *uts,
ut_assert_nextline(" %s[%d]\t[0x%llx-0x%llx], 0x%08llx bytes flags: %x",
name, i, base, end, size, flags);
}
+
+ return 0;
}
-static void lmb_test_dump_all(struct unit_test_state *uts, struct lmb *lmb)
+static int lmb_test_dump_all(struct unit_test_state *uts, struct lmb *lmb)
{
ut_assert_nextline("lmb_dump_all:");
lmb_test_dump_region(uts, &lmb->memory, "memory");
lmb_test_dump_region(uts, &lmb->reserved, "reserved");
+
+ return 0;
}
static int bdinfo_test_move(struct unit_test_state *uts)
@@ -123,44 +138,48 @@ static int bdinfo_test_move(struct unit_test_state *uts)
ut_assertok(console_record_reset_enable());
ut_assertok(run_commandf("bdinfo"));
- bdinfo_test_num_l(uts, "boot_params", 0);
+ ut_assertok(test_num_l(uts, "boot_params", 0));
for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) {
if (bd->bi_dram[i].size) {
- bdinfo_test_num_l(uts, "DRAM bank", i);
- bdinfo_test_num_ll(uts, "-> start", bd->bi_dram[i].start);
- bdinfo_test_num_ll(uts, "-> size", bd->bi_dram[i].size);
+ ut_assertok(test_num_l(uts, "DRAM bank", i));
+ ut_assertok(test_num_ll(uts, "-> start",
+ bd->bi_dram[i].start));
+ ut_assertok(test_num_ll(uts, "-> size",
+ bd->bi_dram[i].size));
}
}
/* CONFIG_SYS_HAS_SRAM testing not supported */
- bdinfo_test_num_l(uts, "flashstart", 0);
- bdinfo_test_num_l(uts, "flashsize", 0);
- bdinfo_test_num_l(uts, "flashoffset", 0);
+ ut_assertok(test_num_l(uts, "flashstart", 0));
+ ut_assertok(test_num_l(uts, "flashsize", 0));
+ ut_assertok(test_num_l(uts, "flashoffset", 0));
ut_assert_nextline("baudrate = %lu bps",
env_get_ulong("baudrate", 10, 1234));
- bdinfo_test_num_l(uts, "relocaddr", gd->relocaddr);
- bdinfo_test_num_l(uts, "reloc off", gd->reloc_off);
+ ut_assertok(test_num_l(uts, "relocaddr", gd->relocaddr));
+ ut_assertok(test_num_l(uts, "reloc off", gd->reloc_off));
ut_assert_nextline("%-12s= %u-bit", "Build", (uint)sizeof(void *) * 8);
if (IS_ENABLED(CONFIG_CMD_NET))
- test_eth(uts);
+ ut_assertok(test_eth(uts));
/*
* Make sure environment variable "fdtcontroladdr" address
* matches mapped control DT address.
*/
ut_assert(map_to_sysmem(gd->fdt_blob) == env_get_hex("fdtcontroladdr", 0x1234));
- bdinfo_test_num_l(uts, "fdt_blob", (ulong)map_to_sysmem(gd->fdt_blob));
- bdinfo_test_num_l(uts, "new_fdt", (ulong)map_to_sysmem(gd->new_fdt));
- bdinfo_test_num_l(uts, "fdt_size", (ulong)gd->fdt_size);
+ ut_assertok(test_num_l(uts, "fdt_blob",
+ (ulong)map_to_sysmem(gd->fdt_blob)));
+ ut_assertok(test_num_l(uts, "new_fdt",
+ (ulong)map_to_sysmem(gd->new_fdt)));
+ ut_assertok(test_num_l(uts, "fdt_size", (ulong)gd->fdt_size));
if (IS_ENABLED(CONFIG_VIDEO))
test_video_info(uts);
/* The gd->multi_dtb_fit may not be available, hence, #if below. */
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
- bdinfo_test_num_l(uts, "multi_dtb_fit", (ulong)gd->multi_dtb_fit);
+ ut_assertok(test_num_l(uts, "multi_dtb_fit", (ulong)gd->multi_dtb_fit));
#endif
if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) {
diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c
index 473a8cef578..6fbebc7da08 100644
--- a/test/dm/ofnode.c
+++ b/test/dm/ofnode.c
@@ -1240,3 +1240,48 @@ static int dm_test_ofnode_copy_props_ot(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_ofnode_copy_props_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
+
+/* check that the livetree is aligned to a structure boundary */
+static int dm_test_livetree_align(struct unit_test_state *uts)
+{
+ const int align = __alignof__(struct unit_test_state);
+ struct device_node *node;
+ u32 *sentinel;
+ ulong start;
+
+ start = (ulong)gd_of_root();
+ ut_asserteq(start, ALIGN(start, align));
+
+ node = gd_of_root();
+ sentinel = (void *)node - sizeof(u32);
+
+ /*
+ * The sentinel should be overwritten with the root node. If it isn't,
+ * then the root node is not at the very start of the livetree memory
+ * area, and free(root) will fail to free the memory used by the
+ * livetree.
+ */
+ ut_assert(*sentinel != BAD_OF_ROOT);
+
+ return 0;
+}
+DM_TEST(dm_test_livetree_align, UT_TESTF_LIVE_TREE);
+
+/* check that it is possible to load an arbitrary livetree */
+static int dm_test_livetree_ensure(struct unit_test_state *uts)
+{
+ oftree tree;
+ ofnode node;
+
+ /* read from other.dtb */
+ ut_assertok(test_load_other_fdt(uts));
+ tree = oftree_from_fdt(uts->other_fdt);
+ ut_assert(oftree_valid(tree));
+ node = oftree_path(tree, "/node/subnode");
+ ut_assert(ofnode_valid(node));
+ ut_asserteq_str("sandbox-other2",
+ ofnode_read_string(node, "compatible"));
+
+ return 0;
+}
+DM_TEST(dm_test_livetree_ensure, 0);
diff --git a/test/dm/video.c b/test/dm/video.c
index 30778157d94..0534ee93a3d 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -556,7 +556,7 @@ static int dm_test_video_truetype(struct unit_test_state *uts)
ut_assertok(video_get_nologo(uts, &dev));
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
vidconsole_put_string(con, test_string);
- ut_asserteq(12237, compress_frame_buffer(uts, dev));
+ ut_asserteq(12174, compress_frame_buffer(uts, dev));
return 0;
}
@@ -577,7 +577,7 @@ static int dm_test_video_truetype_scroll(struct unit_test_state *uts)
ut_assertok(video_get_nologo(uts, &dev));
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
vidconsole_put_string(con, test_string);
- ut_asserteq(35030, compress_frame_buffer(uts, dev));
+ ut_asserteq(34287, compress_frame_buffer(uts, dev));
return 0;
}
@@ -598,7 +598,7 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts)
ut_assertok(video_get_nologo(uts, &dev));
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
vidconsole_put_string(con, test_string);
- ut_asserteq(29018, compress_frame_buffer(uts, dev));
+ ut_asserteq(29471, compress_frame_buffer(uts, dev));
return 0;
}
diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py
index 0b45863b438..aa1d477cd56 100644
--- a/test/py/tests/test_ut.py
+++ b/test/py/tests/test_ut.py
@@ -282,6 +282,15 @@ label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
copy_prepared_image(cons, mmc_dev, fname)
+def setup_cedit_file(cons):
+ infname = os.path.join(cons.config.source_dir,
+ 'test/boot/files/expo_layout.dts')
+ expo_tool = os.path.join(cons.config.source_dir, 'tools/expo.py')
+ outfname = 'cedit.dtb'
+ u_boot_utils.run_and_log(
+ cons, f'{expo_tool} -e {infname} -l {infname} -o {outfname}')
+
+
@pytest.mark.buildconfigspec('ut_dm')
def test_ut_dm_init(u_boot_console):
"""Initialize data for ut dm tests."""
@@ -319,6 +328,7 @@ def test_ut_dm_init_bootstd(u_boot_console):
setup_bootflow_image(u_boot_console)
setup_bootmenu_image(u_boot_console)
+ setup_cedit_file(u_boot_console)
# Restart so that the new mmc1.img is picked up
u_boot_console.restart_uboot()
diff --git a/tools/binman/control.py b/tools/binman/control.py
index 68597c4e779..7e2dd3541b9 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -9,7 +9,7 @@ from collections import OrderedDict
import glob
try:
import importlib.resources
-except ImportError:
+except ImportError: # pragma: no cover
# for Python 3.6
import importlib_resources
import os
diff --git a/tools/expo.py b/tools/expo.py
new file mode 100755
index 00000000000..c6eb87aec73
--- /dev/null
+++ b/tools/expo.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0+
+
+"""
+Expo utility - used for testing of expo features
+
+Copyright 2023 Google LLC
+Written by Simon Glass <sjg@chromium.org>
+"""
+
+import argparse
+import collections
+import io
+import re
+import subprocess
+import sys
+
+#from u_boot_pylib import cros_subprocess
+from u_boot_pylib import tools
+
+# Parse:
+# SCENE1 = 7,
+# or SCENE2,
+RE_ENUM = re.compile(r'(\S*)(\s*= (\d))?,')
+
+# Parse #define <name> "string"
+RE_DEF = re.compile(r'#define (\S*)\s*"(.*)"')
+
+def calc_ids(fname):
+ """Figure out the value of the enums in a C file
+
+ Args:
+ fname (str): Filename to parse
+
+ Returns:
+ OrderedDict():
+ key (str): enum name
+ value (int or str):
+ Value of enum, if int
+ Value of #define, if string
+ """
+ vals = collections.OrderedDict()
+ with open(fname, 'r', encoding='utf-8') as inf:
+ in_enum = False
+ cur_id = 0
+ for line in inf.readlines():
+ line = line.strip()
+ if line == 'enum {':
+ in_enum = True
+ continue
+ if in_enum and line == '};':
+ in_enum = False
+
+ if in_enum:
+ if not line or line.startswith('/*'):
+ continue
+ m_enum = RE_ENUM.match(line)
+ if m_enum.group(3):
+ cur_id = int(m_enum.group(3))
+ vals[m_enum.group(1)] = cur_id
+ cur_id += 1
+ else:
+ m_def = RE_DEF.match(line)
+ if m_def:
+ vals[m_def.group(1)] = tools.to_bytes(m_def.group(2))
+
+ return vals
+
+
+def run_expo(args):
+ """Run the expo program"""
+ ids = calc_ids(args.enum_fname)
+
+ indata = tools.read_file(args.layout)
+
+ outf = io.BytesIO()
+
+ for name, val in ids.items():
+ if isinstance(val, int):
+ outval = b'%d' % val
+ else:
+ outval = b'"%s"' % val
+ find_str = r'\b%s\b' % name
+ indata = re.sub(tools.to_bytes(find_str), outval, indata)
+
+ outf.write(indata)
+ data = outf.getvalue()
+
+ with open('/tmp/asc', 'wb') as outf:
+ outf.write(data)
+ proc = subprocess.run('dtc', input=data, capture_output=True, check=True)
+ edtb = proc.stdout
+ if proc.stderr:
+ print(proc.stderr)
+ return 1
+ tools.write_file(args.outfile, edtb)
+ return 0
+
+
+def parse_args(argv):
+ """Parse the command-line arguments
+
+ Args:
+ argv (list of str): List of string arguments
+
+ Returns:
+ tuple: (options, args) with the command-line options and arugments.
+ options provides access to the options (e.g. option.debug)
+ args is a list of string arguments
+ """
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-e', '--enum-fname', type=str,
+ help='C file containing enum declaration for expo items')
+ parser.add_argument('-l', '--layout', type=str,
+ help='Devicetree file source .dts for expo layout')
+ parser.add_argument('-o', '--outfile', type=str,
+ help='Filename to write expo layout dtb')
+
+ return parser.parse_args(argv)
+
+def start_expo():
+ """Start the expo program"""
+ args = parse_args(sys.argv[1:])
+
+ ret_code = run_expo(args)
+ sys.exit(ret_code)
+
+
+if __name__ == "__main__":
+ start_expo()