aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/arch/arm/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/arch/arm/cpu')
-rw-r--r--roms/u-boot/arch/arm/cpu/Makefile3
-rw-r--r--roms/u-boot/arch/arm/cpu/arm11/Makefile10
-rw-r--r--roms/u-boot/arch/arm/cpu/arm11/cpu.c113
-rw-r--r--roms/u-boot/arch/arm/cpu/arm11/sctlr.S25
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/Makefile10
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/mx31/Makefile9
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/mx31/devices.c50
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/mx31/generic.c219
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/mx31/relocate.S22
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/mx31/timer.c45
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/mx35/Makefile11
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/mx35/generic.c530
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/mx35/mx35_sdram.c120
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/mx35/relocate.S22
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/mx35/timer.c46
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/start.S94
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1136/u-boot-spl.lds50
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1176/Makefile12
-rw-r--r--roms/u-boot/arch/arm/cpu/arm1176/start.S121
-rw-r--r--roms/u-boot/arch/arm/cpu/arm720t/Makefile7
-rw-r--r--roms/u-boot/arch/arm/cpu/arm720t/cpu.c21
-rw-r--r--roms/u-boot/arch/arm/cpu/arm720t/interrupts.c26
-rw-r--r--roms/u-boot/arch/arm/cpu/arm720t/start.S79
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/Makefile17
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/cpu.c49
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/ep93xx/Makefile19
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/ep93xx/cpu.c37
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/ep93xx/led.c85
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S457
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/ep93xx/speed.c95
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/ep93xx/timer.c117
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/imx/Makefile8
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/imx/generic.c76
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/imx/speed.c85
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/imx/timer.c100
-rw-r--r--roms/u-boot/arch/arm/cpu/arm920t/start.S112
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/Makefile32
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/armada100/Makefile7
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/armada100/cpu.c93
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/armada100/dram.c117
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/armada100/timer.c198
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/cache.c92
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/cpu.c55
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mx25/Makefile7
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mx25/generic.c274
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mx25/relocate.S22
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mx25/reset.c40
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mx25/timer.c50
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mx27/Makefile7
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mx27/generic.c378
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mx27/relocate.S50
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mx27/reset.c41
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mx27/timer.c166
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/Makefile81
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/clock.c436
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/iomux.c96
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxs.c295
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxs_init.h28
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage-signed.cfg11
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage-spl.mx23.cfg5
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage-spl.mx28.cfg6
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg7
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg9
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_boot.c162
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c79
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c361
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c1291
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/start.S95
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/timer.c159
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/u-boot-imx23.bd18
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd14
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds68
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/Makefile21
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/cpu.c116
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/reset.c39
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/spear600.c223
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/spl.c302
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c113
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c118
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c113
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c127
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr_lowlevel_init.S173
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr_misc.c253
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/start.S65
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/timer.c124
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds54
-rw-r--r--roms/u-boot/arch/arm/cpu/arm926ejs/start.S112
-rw-r--r--roms/u-boot/arch/arm/cpu/arm946es/Makefile8
-rw-r--r--roms/u-boot/arch/arm/cpu/arm946es/cpu.c67
-rw-r--r--roms/u-boot/arch/arm/cpu/arm946es/start.S101
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/Kconfig79
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/Makefile46
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/arch_timer.c64
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm235xx/Makefile10
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-bcm235xx.c568
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-bsc.c51
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-core.c514
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-core.h491
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-eth.c143
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-sdio.c72
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-usb-otg.c26
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm281xx/Makefile11
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-bcm281xx.c572
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-bsc.c51
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-core.c514
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-core.h491
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-eth.c143
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-sdio.c72
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-usb-otg.c26
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcm281xx/reset.c27
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcmcygnus/Makefile5
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcmcygnus/reset.c20
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcmnsp/Makefile5
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/bcmnsp/reset.c19
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/cache_v7.c212
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/cache_v7_asm.S152
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/config.mk11
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/cp15.c28
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/cpu.c85
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/exception_level.c58
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/iproc-common/Makefile7
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/iproc-common/armpll.c169
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/iproc-common/hwinit-common.c16
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/iproc-common/timer.c132
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/kona-common/Makefile8
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/kona-common/clk-stubs.c25
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/kona-common/hwinit-common.c17
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/kona-common/reset.S25
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/kona-common/s_init.c11
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/lowlevel_init.S70
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/Kconfig104
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/Makefile19
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/clock.c122
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/cpu.c399
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/fdt.c196
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.c213
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.h75
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c130
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h11
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c246
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c40
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/psci.S257
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/soc.c242
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/spl.c15
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/ls102xa/timer.c126
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/mpu_v7r.c121
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/nonsec_virt.S225
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/psci-common.c46
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/psci.S347
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/s5p-common/Makefile16
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/s5p-common/cpu_info.c51
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/s5p-common/pwm.c225
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/s5p-common/sromc.c32
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/s5p-common/timer.c139
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/s5p4418/Makefile6
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/s5p4418/cpu.c122
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/sctlr.S22
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/smccc-call.S59
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/start.S342
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/stv0991/Makefile7
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/stv0991/clock.c42
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/stv0991/lowlevel.S11
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/stv0991/pinmux.c66
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/stv0991/reset.c27
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/stv0991/timer.c114
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/sunxi/Makefile19
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/sunxi/fel_utils.S41
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/sunxi/psci.c313
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/sunxi/start.c1
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/sunxi/timer.c116
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/sunxi/tzpc.c26
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds57
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/syslib.c42
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/vf610/Kconfig37
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/vf610/Makefile11
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/vf610/generic.c407
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/vf610/timer.c88
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/virt-dt.c70
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7/virt-v7.c145
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7m/Makefile9
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7m/cache.c373
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7m/config.mk6
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7m/cpu.c58
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7m/mpu.c44
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7m/start.S16
-rw-r--r--roms/u-boot/arch/arm/cpu/armv7m/systick-timer.c119
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/Kconfig177
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/Makefile47
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/bcmns3/Makefile5
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/bcmns3/lowlevel.S98
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/cache.S267
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/cache_v8.c757
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/config.mk12
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/cpu-dt.c33
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/cpu.c86
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/exception_level.c58
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/exceptions.S160
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fel_utils.S81
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/Kconfig658
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/Makefile63
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/cpu.c1656
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/cpu.h9
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.core_prefetch20
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.falcon150
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch220
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3400
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3_227
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.pci_iommu_extra67
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.qspi42
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc437
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fdt.c700
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c421
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c261
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c665
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c256
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/icid.c195
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S430
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1012a_serdes.c73
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c130
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1028a_serdes.c90
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1043_ids.c90
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_psci.S19
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_serdes.c85
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1046_ids.c89
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1046a_serdes.c100
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1088_ids.c32
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1088a_serdes.c144
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls2080a_serdes.c123
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls2088_ids.c35
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/lx2160_ids.c48
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/lx2160a_serdes.c149
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/mp.c343
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ppa.c284
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/soc.c975
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/spintable.S118
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/spl.c150
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/fwcall.c131
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/generic_timer.c117
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/hisilicon/Makefile6
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/hisilicon/pinmux.c185
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/linux-kernel-image-header-vars.h85
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/lowlevel_init.S43
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/psci.S331
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/sec_firmware.c504
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/sec_firmware_asm.S75
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/smccc-call.S47
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/spin_table.c62
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/spin_table_v8.S22
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/spl_data.c29
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/start.S402
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/tlb.S34
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/transition.S51
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/u-boot-spl.lds87
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/u-boot.lds175
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/xen/Makefile6
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/xen/hypercall.S79
-rw-r--r--roms/u-boot/arch/arm/cpu/armv8/xen/lowlevel_init.S33
-rw-r--r--roms/u-boot/arch/arm/cpu/pxa/Makefile15
-rw-r--r--roms/u-boot/arch/arm/cpu/pxa/cache.c58
-rw-r--r--roms/u-boot/arch/arm/cpu/pxa/config.mk18
-rw-r--r--roms/u-boot/arch/arm/cpu/pxa/cpuinfo.c145
-rw-r--r--roms/u-boot/arch/arm/cpu/pxa/pxa2xx.c295
-rw-r--r--roms/u-boot/arch/arm/cpu/pxa/relocate.S22
-rw-r--r--roms/u-boot/arch/arm/cpu/pxa/start.S205
-rw-r--r--roms/u-boot/arch/arm/cpu/pxa/timer.c16
-rw-r--r--roms/u-boot/arch/arm/cpu/pxa/usb.c89
-rw-r--r--roms/u-boot/arch/arm/cpu/sa1100/Makefile9
-rw-r--r--roms/u-boot/arch/arm/cpu/sa1100/cpu.c65
-rw-r--r--roms/u-boot/arch/arm/cpu/sa1100/start.S126
-rw-r--r--roms/u-boot/arch/arm/cpu/sa1100/timer.c66
-rw-r--r--roms/u-boot/arch/arm/cpu/u-boot-spl.lds94
-rw-r--r--roms/u-boot/arch/arm/cpu/u-boot.lds240
272 files changed, 36442 insertions, 0 deletions
diff --git a/roms/u-boot/arch/arm/cpu/Makefile b/roms/u-boot/arch/arm/cpu/Makefile
new file mode 100644
index 000000000..a0e1c2a65
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj- += dummy.o
diff --git a/roms/u-boot/arch/arm/cpu/arm11/Makefile b/roms/u-boot/arch/arm/cpu/arm11/Makefile
new file mode 100644
index 000000000..5dfa01ae8
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm11/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+obj-y = cpu.o
+
+ifneq ($(CONFIG_SPL_BUILD),y)
+obj-$(CONFIG_EFI_LOADER) += sctlr.o
+endif
diff --git a/roms/u-boot/arch/arm/cpu/arm11/cpu.c b/roms/u-boot/arch/arm/cpu/arm11/cpu.c
new file mode 100644
index 000000000..ffe35111d
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm11/cpu.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2004 Texas Insturments
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ */
+
+/*
+ * CPU specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <irq_func.h>
+#include <asm/cache.h>
+#include <asm/system.h>
+
+static void cache_flush(void);
+
+int cleanup_before_linux (void)
+{
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * we turn off caches etc ...
+ */
+
+ disable_interrupts();
+
+ /* turn off I/D-cache */
+ icache_disable();
+ dcache_disable();
+ /* flush I/D-cache */
+ cache_flush();
+
+ return 0;
+}
+
+static void cache_flush(void)
+{
+ unsigned long i = 0;
+ /* clean entire data cache */
+ asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (i));
+ /* invalidate both caches and flush btb */
+ asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (i));
+ /* mem barrier to sync things */
+ asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (i));
+}
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+void invalidate_dcache_all(void)
+{
+ asm volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0));
+}
+
+void flush_dcache_all(void)
+{
+ asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (0));
+ asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+ if (!check_cache_range(start, stop))
+ return;
+
+ while (start < stop) {
+ asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (start));
+ start += CONFIG_SYS_CACHELINE_SIZE;
+ }
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+ if (!check_cache_range(start, stop))
+ return;
+
+ while (start < stop) {
+ asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r" (start));
+ start += CONFIG_SYS_CACHELINE_SIZE;
+ }
+
+ asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
+}
+
+#else /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
+void invalidate_dcache_all(void)
+{
+}
+
+void flush_dcache_all(void)
+{
+}
+#endif /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
+
+#if !(CONFIG_IS_ENABLED(SYS_ICACHE_OFF) && CONFIG_IS_ENABLED(SYS_DCACHE_OFF))
+void enable_caches(void)
+{
+#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
+ icache_enable();
+#endif
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+ dcache_enable();
+#endif
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/arm11/sctlr.S b/roms/u-boot/arch/arm/cpu/arm11/sctlr.S
new file mode 100644
index 000000000..74a7fc4a2
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm11/sctlr.S
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Routines to access the system control register
+ *
+ * Copyright (c) 2019 Heinrich Schuchardt
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * void allow_unaligned(void) - allow unaligned access
+ *
+ * This routine sets the enable unaligned data support flag and clears the
+ * aligned flag in the system control register.
+ * After calling this routine unaligned access does no longer leads to a
+ * data abort or undefined behavior but is handled by the CPU.
+ * For details see the "ARM Architecture Reference Manual" for ARMv6.
+ */
+ENTRY(allow_unaligned)
+ mrc p15, 0, r0, c1, c0, 0 @ load system control register
+ orr r0, r0, #1 << 22 @ set unaligned data support flag
+ bic r0, r0, #2 @ clear aligned flag
+ mcr p15, 0, r0, c1, c0, 0 @ write system control register
+ bx lr @ return
+ENDPROC(allow_unaligned)
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/Makefile b/roms/u-boot/arch/arm/cpu/arm1136/Makefile
new file mode 100644
index 000000000..24c33861c
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+extra-y = start.o
+
+obj-y += ../arm11/
+obj-$(CONFIG_MX31) += mx31/
+obj-$(CONFIG_MX35) += mx35/
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/mx31/Makefile b/roms/u-boot/arch/arm/cpu/arm1136/mx31/Makefile
new file mode 100644
index 000000000..67799eeb8
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/mx31/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+obj-y += generic.o
+obj-y += timer.o
+obj-y += devices.o
+obj-y += relocate.o
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/mx31/devices.c b/roms/u-boot/arch/arm/cpu/arm1136/mx31/devices.c
new file mode 100644
index 000000000..9997e8fc3
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/mx31/devices.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *
+ * (C) Copyright 2009 Magnus Lilja <lilja.magnus@gmail.com>
+ *
+ * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ */
+
+#include <common.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/clock.h>
+
+void mx31_uart1_hw_init(void)
+{
+ /* setup pins for UART1 */
+ mx31_gpio_mux(MUX_RXD1__UART1_RXD_MUX);
+ mx31_gpio_mux(MUX_TXD1__UART1_TXD_MUX);
+ mx31_gpio_mux(MUX_RTS1__UART1_RTS_B);
+ mx31_gpio_mux(MUX_CTS1__UART1_CTS_B);
+}
+
+void mx31_uart2_hw_init(void)
+{
+ /* setup pins for UART2 */
+ mx31_gpio_mux(MUX_RXD2__UART2_RXD_MUX);
+ mx31_gpio_mux(MUX_TXD2__UART2_TXD_MUX);
+ mx31_gpio_mux(MUX_RTS2__UART2_RTS_B);
+ mx31_gpio_mux(MUX_CTS2__UART2_CTS_B);
+}
+
+#ifdef CONFIG_MXC_SPI
+/*
+ * Note: putting several spi setups here makes no sense as they may differ
+ * at board level (physical pin SS0 of CSPI2 may aswell be used as SS0 of CSPI3)
+ */
+void mx31_spi2_hw_init(void)
+{
+ /* SPI2 */
+ mx31_gpio_mux(MUX_CSPI2_SS2__CSPI2_SS2_B);
+ mx31_gpio_mux(MUX_CSPI2_SCLK__CSPI2_CLK);
+ mx31_gpio_mux(MUX_CSPI2_SPI_RDY__CSPI2_DATAREADY_B);
+ mx31_gpio_mux(MUX_CSPI2_MOSI__CSPI2_MOSI);
+ mx31_gpio_mux(MUX_CSPI2_MISO__CSPI2_MISO);
+ mx31_gpio_mux(MUX_CSPI2_SS0__CSPI2_SS0_B);
+ mx31_gpio_mux(MUX_CSPI2_SS1__CSPI2_SS1_B);
+
+ /* start SPI2 clock */
+ __REG(CCM_CGR2) = __REG(CCM_CGR2) | (3 << 4);
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/mx31/generic.c b/roms/u-boot/arch/arm/cpu/arm1136/mx31/generic.c
new file mode 100644
index 000000000..a3d4f1479
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/mx31/generic.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2007
+ * Sascha Hauer, Pengutronix
+ */
+
+#include <common.h>
+#include <div64.h>
+#include <init.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/clock.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+
+static u32 mx31_decode_pll(u32 reg, u32 infreq)
+{
+ u32 mfi = GET_PLL_MFI(reg);
+ s32 mfn = GET_PLL_MFN(reg);
+ u32 mfd = GET_PLL_MFD(reg);
+ u32 pd = GET_PLL_PD(reg);
+
+ mfi = mfi <= 5 ? 5 : mfi;
+ mfn = mfn >= 512 ? mfn - 1024 : mfn;
+ mfd += 1;
+ pd += 1;
+
+ return lldiv(2 * (u64)infreq * (mfi * mfd + mfn),
+ mfd * pd);
+}
+
+static u32 mx31_get_mpl_dpdgck_clk(void)
+{
+ u32 infreq;
+
+ if ((readl(CCM_CCMR) & CCMR_PRCS_MASK) == CCMR_FPM)
+ infreq = MXC_CLK32 * 1024;
+ else
+ infreq = MXC_HCLK;
+
+ return mx31_decode_pll(readl(CCM_MPCTL), infreq);
+}
+
+static u32 mx31_get_mcu_main_clk(void)
+{
+ /* For now we assume mpl_dpdgck_clk == mcu_main_clk
+ * which should be correct for most boards
+ */
+ return mx31_get_mpl_dpdgck_clk();
+}
+
+static u32 mx31_get_ipg_clk(void)
+{
+ u32 freq = mx31_get_mcu_main_clk();
+ u32 pdr0 = readl(CCM_PDR0);
+
+ freq /= GET_PDR0_MAX_PODF(pdr0) + 1;
+ freq /= GET_PDR0_IPG_PODF(pdr0) + 1;
+
+ return freq;
+}
+
+/* hsp is the clock for the ipu */
+static u32 mx31_get_hsp_clk(void)
+{
+ u32 freq = mx31_get_mcu_main_clk();
+ u32 pdr0 = readl(CCM_PDR0);
+
+ freq /= GET_PDR0_HSP_PODF(pdr0) + 1;
+
+ return freq;
+}
+
+void mx31_dump_clocks(void)
+{
+ u32 cpufreq = mx31_get_mcu_main_clk();
+ printf("mx31 cpu clock: %dMHz\n", cpufreq / 1000000);
+ printf("ipg clock : %dHz\n", mx31_get_ipg_clk());
+ printf("hsp clock : %dHz\n", mx31_get_hsp_clk());
+}
+
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+ switch (clk) {
+ case MXC_ARM_CLK:
+ return mx31_get_mcu_main_clk();
+ case MXC_IPG_CLK:
+ case MXC_IPG_PERCLK:
+ case MXC_CSPI_CLK:
+ case MXC_UART_CLK:
+ case MXC_ESDHC_CLK:
+ case MXC_I2C_CLK:
+ return mx31_get_ipg_clk();
+ case MXC_IPU_CLK:
+ return mx31_get_hsp_clk();
+ }
+ return -1;
+}
+
+u32 imx_get_uartclk(void)
+{
+ return mxc_get_clock(MXC_UART_CLK);
+}
+
+void mx31_gpio_mux(unsigned long mode)
+{
+ unsigned long reg, shift, tmp;
+
+ reg = IOMUXC_BASE + (mode & 0x1fc);
+ shift = (~mode & 0x3) * 8;
+
+ tmp = readl(reg);
+ tmp &= ~(0xff << shift);
+ tmp |= ((mode >> IOMUX_MODE_POS) & 0xff) << shift;
+ writel(tmp, reg);
+}
+
+void mx31_set_pad(enum iomux_pins pin, u32 config)
+{
+ u32 field, l, reg;
+
+ pin &= IOMUX_PADNUM_MASK;
+ reg = (IOMUXC_BASE + 0x154) + (pin + 2) / 3 * 4;
+ field = (pin + 2) % 3;
+
+ l = readl(reg);
+ l &= ~(0x1ff << (field * 10));
+ l |= config << (field * 10);
+ writel(l, reg);
+
+}
+
+void mx31_set_gpr(enum iomux_gp_func gp, char en)
+{
+ u32 l;
+ struct iomuxc_regs *iomuxc = (struct iomuxc_regs *)IOMUXC_BASE;
+
+ l = readl(&iomuxc->gpr);
+ if (en)
+ l |= gp;
+ else
+ l &= ~gp;
+
+ writel(l, &iomuxc->gpr);
+}
+
+void mxc_setup_weimcs(int cs, const struct mxc_weimcs *weimcs)
+{
+ struct mx31_weim *weim = (struct mx31_weim *) WEIM_BASE;
+ struct mx31_weim_cscr *cscr = &weim->cscr[cs];
+
+ writel(weimcs->upper, &cscr->upper);
+ writel(weimcs->lower, &cscr->lower);
+ writel(weimcs->additional, &cscr->additional);
+}
+
+struct mx3_cpu_type mx31_cpu_type[] = {
+ { .srev = 0x00, .v = 0x10 },
+ { .srev = 0x10, .v = 0x11 },
+ { .srev = 0x11, .v = 0x11 },
+ { .srev = 0x12, .v = 0x1F },
+ { .srev = 0x13, .v = 0x1F },
+ { .srev = 0x14, .v = 0x12 },
+ { .srev = 0x15, .v = 0x12 },
+ { .srev = 0x28, .v = 0x20 },
+ { .srev = 0x29, .v = 0x20 },
+};
+
+u32 get_cpu_rev(void)
+{
+ u32 i, srev;
+
+ /* read SREV register from IIM module */
+ struct iim_regs *iim = (struct iim_regs *)MX31_IIM_BASE_ADDR;
+ srev = readl(&iim->iim_srev);
+
+ for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++)
+ if (srev == mx31_cpu_type[i].srev)
+ return mx31_cpu_type[i].v | (MXC_CPU_MX31 << 12);
+
+ return srev | 0x8000;
+}
+
+static char *get_reset_cause(void)
+{
+ /* read RCSR register from CCM module */
+ struct clock_control_regs *ccm =
+ (struct clock_control_regs *)CCM_BASE;
+
+ u32 cause = readl(&ccm->rcsr) & 0x07;
+
+ switch (cause) {
+ case 0x0000:
+ return "POR";
+ case 0x0001:
+ return "RST";
+ case 0x0002:
+ return "WDOG";
+ case 0x0006:
+ return "JTAG";
+ case 0x0007:
+ return "ARM11P power gating";
+ default:
+ return "unknown reset";
+ }
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+ u32 srev = get_cpu_rev();
+
+ printf("CPU: Freescale i.MX31 rev %d.%d%s at %d MHz.\n",
+ (srev & 0xF0) >> 4, (srev & 0x0F),
+ ((srev & 0x8000) ? " unknown" : ""),
+ mx31_get_mcu_main_clk() / 1000000);
+ printf("Reset cause: %s\n", get_reset_cause());
+ return 0;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/mx31/relocate.S b/roms/u-boot/arch/arm/cpu/arm1136/mx31/relocate.S
new file mode 100644
index 000000000..225e5281b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/mx31/relocate.S
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * relocate - i.MX31-specific vector relocation
+ *
+ * Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net>
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * The i.MX31 SoC is very specific with respect to exceptions: it
+ * does not provide RAM at the high vectors address (0xFFFF0000),
+ * thus only the low address (0x00000000) is useable; but that is
+ * in ROM, so let's avoid relocating the vectors.
+ */
+ .section .text.relocate_vectors,"ax",%progbits
+
+ENTRY(relocate_vectors)
+
+ bx lr
+
+ENDPROC(relocate_vectors)
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/mx31/timer.c b/roms/u-boot/arch/arm/cpu/arm1136/mx31/timer.c
new file mode 100644
index 000000000..a91386049
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/mx31/timer.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2007
+ * Sascha Hauer, Pengutronix
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/io.h>
+
+#define TIMER_BASE 0x53f90000 /* General purpose timer 1 */
+
+/* General purpose timers registers */
+#define GPTCR __REG(TIMER_BASE) /* Control register */
+#define GPTPR __REG(TIMER_BASE + 0x4) /* Prescaler register */
+#define GPTSR __REG(TIMER_BASE + 0x8) /* Status register */
+#define GPTCNT __REG(TIMER_BASE + 0x24) /* Counter register */
+
+/* General purpose timers bitfields */
+#define GPTCR_SWR (1 << 15) /* Software reset */
+#define GPTCR_FRR (1 << 9) /* Freerun / restart */
+#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */
+#define GPTCR_TEN 1 /* Timer enable */
+
+/* The 32768Hz 32-bit timer overruns in 131072 seconds */
+int timer_init(void)
+{
+ int i;
+
+ /* setup GP Timer 1 */
+ GPTCR = GPTCR_SWR;
+ for (i = 0; i < 100; i++)
+ GPTCR = 0; /* We have no udelay by now */
+ GPTPR = 0; /* 32Khz */
+ /* Freerun Mode, PERCLK1 input */
+ GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN;
+
+ return 0;
+}
+
+unsigned long timer_read_counter(void)
+{
+ return GPTCNT;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/mx35/Makefile b/roms/u-boot/arch/arm/cpu/arm1136/mx35/Makefile
new file mode 100644
index 000000000..36568f99e
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/mx35/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
+
+obj-y += generic.o
+obj-y += timer.o
+obj-y += mx35_sdram.o
+obj-y += relocate.o
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/mx35/generic.c b/roms/u-boot/arch/arm/cpu/arm1136/mx35/generic.c
new file mode 100644
index 000000000..cbf76ab4f
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/mx35/generic.c
@@ -0,0 +1,530 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2007
+ * Sascha Hauer, Pengutronix
+ *
+ * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <clock_legacy.h>
+#include <command.h>
+#include <div64.h>
+#include <init.h>
+#include <net.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
+#ifdef CONFIG_FSL_ESDHC_IMX
+#include <fsl_esdhc_imx.h>
+#endif
+#include <netdev.h>
+#include <spl.h>
+
+#define CLK_CODE(arm, ahb, sel) (((arm) << 16) + ((ahb) << 8) + (sel))
+#define CLK_CODE_ARM(c) (((c) >> 16) & 0xFF)
+#define CLK_CODE_AHB(c) (((c) >> 8) & 0xFF)
+#define CLK_CODE_PATH(c) ((c) & 0xFF)
+
+#define CCM_GET_DIVIDER(x, m, o) (((x) & (m)) >> (o))
+
+#ifdef CONFIG_FSL_ESDHC_IMX
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
+static int g_clk_mux_auto[8] = {
+ CLK_CODE(1, 3, 0), CLK_CODE(1, 2, 1), CLK_CODE(2, 1, 1), -1,
+ CLK_CODE(1, 6, 0), CLK_CODE(1, 4, 1), CLK_CODE(2, 2, 1), -1,
+};
+
+static int g_clk_mux_consumer[16] = {
+ CLK_CODE(1, 4, 0), CLK_CODE(1, 3, 1), CLK_CODE(1, 3, 1), -1,
+ -1, -1, CLK_CODE(4, 1, 0), CLK_CODE(1, 5, 0),
+ CLK_CODE(1, 8, 1), CLK_CODE(1, 6, 1), CLK_CODE(2, 4, 0), -1,
+ -1, -1, CLK_CODE(4, 2, 0), -1,
+};
+
+static int hsp_div_table[3][16] = {
+ {4, 3, 2, -1, -1, -1, 1, 5, 4, 3, 2, -1, -1, -1, 1, -1},
+ {-1, -1, -1, -1, -1, -1, -1, -1, 8, 6, 4, -1, -1, -1, 2, -1},
+ {3, -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1},
+};
+
+u32 get_cpu_rev(void)
+{
+ int reg;
+ struct iim_regs *iim =
+ (struct iim_regs *)IIM_BASE_ADDR;
+ reg = readl(&iim->iim_srev);
+ if (!reg) {
+ reg = readw(ROMPATCH_REV);
+ reg <<= 4;
+ } else {
+ reg += CHIP_REV_1_0;
+ }
+
+ return 0x35000 + (reg & 0xFF);
+}
+
+static u32 get_arm_div(u32 pdr0, u32 *fi, u32 *fd)
+{
+ int *pclk_mux;
+ if (pdr0 & MXC_CCM_PDR0_AUTO_CON) {
+ pclk_mux = g_clk_mux_consumer +
+ ((pdr0 & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >>
+ MXC_CCM_PDR0_CON_MUX_DIV_OFFSET);
+ } else {
+ pclk_mux = g_clk_mux_auto +
+ ((pdr0 & MXC_CCM_PDR0_AUTO_MUX_DIV_MASK) >>
+ MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET);
+ }
+
+ if ((*pclk_mux) == -1)
+ return -1;
+
+ if (fi && fd) {
+ if (!CLK_CODE_PATH(*pclk_mux)) {
+ *fi = *fd = 1;
+ return CLK_CODE_ARM(*pclk_mux);
+ }
+ if (pdr0 & MXC_CCM_PDR0_AUTO_CON) {
+ *fi = 3;
+ *fd = 4;
+ } else {
+ *fi = 2;
+ *fd = 3;
+ }
+ }
+ return CLK_CODE_ARM(*pclk_mux);
+}
+
+static int get_ahb_div(u32 pdr0)
+{
+ int *pclk_mux;
+
+ pclk_mux = g_clk_mux_consumer +
+ ((pdr0 & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >>
+ MXC_CCM_PDR0_CON_MUX_DIV_OFFSET);
+
+ if ((*pclk_mux) == -1)
+ return -1;
+
+ return CLK_CODE_AHB(*pclk_mux);
+}
+
+static u32 decode_pll(u32 reg, u32 infreq)
+{
+ u32 mfi = (reg >> 10) & 0xf;
+ s32 mfn = reg & 0x3ff;
+ u32 mfd = (reg >> 16) & 0x3ff;
+ u32 pd = (reg >> 26) & 0xf;
+
+ mfi = mfi <= 5 ? 5 : mfi;
+ mfn = mfn >= 512 ? mfn - 1024 : mfn;
+ mfd += 1;
+ pd += 1;
+
+ return lldiv(2 * (u64)infreq * (mfi * mfd + mfn),
+ mfd * pd);
+}
+
+static u32 get_mcu_main_clk(void)
+{
+ u32 arm_div = 0, fi = 0, fd = 0;
+ struct ccm_regs *ccm =
+ (struct ccm_regs *)IMX_CCM_BASE;
+ arm_div = get_arm_div(readl(&ccm->pdr0), &fi, &fd);
+ fi *= decode_pll(readl(&ccm->mpctl), MXC_HCLK);
+ return fi / (arm_div * fd);
+}
+
+static u32 get_ipg_clk(void)
+{
+ u32 freq = get_mcu_main_clk();
+ struct ccm_regs *ccm =
+ (struct ccm_regs *)IMX_CCM_BASE;
+ u32 pdr0 = readl(&ccm->pdr0);
+
+ return freq / (get_ahb_div(pdr0) * 2);
+}
+
+static u32 get_ipg_per_clk(void)
+{
+ u32 freq = get_mcu_main_clk();
+ struct ccm_regs *ccm =
+ (struct ccm_regs *)IMX_CCM_BASE;
+ u32 pdr0 = readl(&ccm->pdr0);
+ u32 pdr4 = readl(&ccm->pdr4);
+ u32 div;
+ if (pdr0 & MXC_CCM_PDR0_PER_SEL) {
+ div = CCM_GET_DIVIDER(pdr4,
+ MXC_CCM_PDR4_PER0_PODF_MASK,
+ MXC_CCM_PDR4_PER0_PODF_OFFSET) + 1;
+ } else {
+ div = CCM_GET_DIVIDER(pdr0,
+ MXC_CCM_PDR0_PER_PODF_MASK,
+ MXC_CCM_PDR0_PER_PODF_OFFSET) + 1;
+ div *= get_ahb_div(pdr0);
+ }
+ return freq / div;
+}
+
+u32 imx_get_uartclk(void)
+{
+ u32 freq;
+ struct ccm_regs *ccm =
+ (struct ccm_regs *)IMX_CCM_BASE;
+ u32 pdr4 = readl(&ccm->pdr4);
+
+ if (readl(&ccm->pdr3) & MXC_CCM_PDR3_UART_M_U)
+ freq = get_mcu_main_clk();
+ else
+ freq = decode_pll(readl(&ccm->ppctl), MXC_HCLK);
+ freq /= CCM_GET_DIVIDER(pdr4,
+ MXC_CCM_PDR4_UART_PODF_MASK,
+ MXC_CCM_PDR4_UART_PODF_OFFSET) + 1;
+ return freq;
+}
+
+unsigned int mxc_get_main_clock(enum mxc_main_clock clk)
+{
+ u32 nfc_pdf, hsp_podf;
+ u32 pll, ret_val = 0, usb_podf;
+ struct ccm_regs *ccm =
+ (struct ccm_regs *)IMX_CCM_BASE;
+
+ u32 reg = readl(&ccm->pdr0);
+ u32 reg4 = readl(&ccm->pdr4);
+
+ reg |= 0x1;
+
+ switch (clk) {
+ case CPU_CLK:
+ ret_val = get_mcu_main_clk();
+ break;
+ case AHB_CLK:
+ ret_val = get_mcu_main_clk();
+ break;
+ case HSP_CLK:
+ if (reg & CLKMODE_CONSUMER) {
+ hsp_podf = (reg >> 20) & 0x3;
+ pll = get_mcu_main_clk();
+ hsp_podf = hsp_div_table[hsp_podf][(reg>>16)&0xF];
+ if (hsp_podf > 0) {
+ ret_val = pll / hsp_podf;
+ } else {
+ puts("mismatch HSP with ARM clock setting\n");
+ ret_val = 0;
+ }
+ } else {
+ ret_val = get_mcu_main_clk();
+ }
+ break;
+ case IPG_CLK:
+ ret_val = get_ipg_clk();
+ break;
+ case IPG_PER_CLK:
+ ret_val = get_ipg_per_clk();
+ break;
+ case NFC_CLK:
+ nfc_pdf = (reg4 >> 28) & 0xF;
+ pll = get_mcu_main_clk();
+ /* AHB/nfc_pdf */
+ ret_val = pll / (nfc_pdf + 1);
+ break;
+ case USB_CLK:
+ usb_podf = (reg4 >> 22) & 0x3F;
+ if (reg4 & 0x200)
+ pll = get_mcu_main_clk();
+ else
+ pll = decode_pll(readl(&ccm->ppctl), MXC_HCLK);
+
+ ret_val = pll / (usb_podf + 1);
+ break;
+ default:
+ printf("Unknown clock: %d\n", clk);
+ break;
+ }
+
+ return ret_val;
+}
+unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk)
+{
+ u32 ret_val = 0, pdf, pre_pdf, clk_sel;
+ struct ccm_regs *ccm =
+ (struct ccm_regs *)IMX_CCM_BASE;
+ u32 mpdr2 = readl(&ccm->pdr2);
+ u32 mpdr3 = readl(&ccm->pdr3);
+ u32 mpdr4 = readl(&ccm->pdr4);
+
+ switch (clk) {
+ case UART1_BAUD:
+ case UART2_BAUD:
+ case UART3_BAUD:
+ clk_sel = mpdr3 & (1 << 14);
+ pdf = (mpdr4 >> 10) & 0x3F;
+ ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
+ decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
+ break;
+ case SSI1_BAUD:
+ pre_pdf = (mpdr2 >> 24) & 0x7;
+ pdf = mpdr2 & 0x3F;
+ clk_sel = mpdr2 & (1 << 6);
+ ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
+ decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
+ ((pre_pdf + 1) * (pdf + 1));
+ break;
+ case SSI2_BAUD:
+ pre_pdf = (mpdr2 >> 27) & 0x7;
+ pdf = (mpdr2 >> 8) & 0x3F;
+ clk_sel = mpdr2 & (1 << 6);
+ ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
+ decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
+ ((pre_pdf + 1) * (pdf + 1));
+ break;
+ case CSI_BAUD:
+ clk_sel = mpdr2 & (1 << 7);
+ pdf = (mpdr2 >> 16) & 0x3F;
+ ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
+ decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
+ break;
+ case MSHC_CLK:
+ pre_pdf = readl(&ccm->pdr1);
+ clk_sel = (pre_pdf & 0x80);
+ pdf = (pre_pdf >> 22) & 0x3F;
+ pre_pdf = (pre_pdf >> 28) & 0x7;
+ ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
+ decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
+ ((pre_pdf + 1) * (pdf + 1));
+ break;
+ case ESDHC1_CLK:
+ clk_sel = mpdr3 & 0x40;
+ pdf = mpdr3 & 0x3F;
+ ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
+ decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
+ break;
+ case ESDHC2_CLK:
+ clk_sel = mpdr3 & 0x40;
+ pdf = (mpdr3 >> 8) & 0x3F;
+ ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
+ decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
+ break;
+ case ESDHC3_CLK:
+ clk_sel = mpdr3 & 0x40;
+ pdf = (mpdr3 >> 16) & 0x3F;
+ ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
+ decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
+ break;
+ case SPDIF_CLK:
+ clk_sel = mpdr3 & 0x400000;
+ pre_pdf = (mpdr3 >> 29) & 0x7;
+ pdf = (mpdr3 >> 23) & 0x3F;
+ ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
+ decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
+ ((pre_pdf + 1) * (pdf + 1));
+ break;
+ default:
+ printf("%s(): This clock: %d not supported yet\n",
+ __func__, clk);
+ break;
+ }
+
+ return ret_val;
+}
+
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+ switch (clk) {
+ case MXC_ARM_CLK:
+ return get_mcu_main_clk();
+ case MXC_AHB_CLK:
+ break;
+ case MXC_IPG_CLK:
+ return get_ipg_clk();
+ case MXC_IPG_PERCLK:
+ case MXC_I2C_CLK:
+ return get_ipg_per_clk();
+ case MXC_UART_CLK:
+ return imx_get_uartclk();
+ case MXC_ESDHC1_CLK:
+ return mxc_get_peri_clock(ESDHC1_CLK);
+ case MXC_ESDHC2_CLK:
+ return mxc_get_peri_clock(ESDHC2_CLK);
+ case MXC_ESDHC3_CLK:
+ return mxc_get_peri_clock(ESDHC3_CLK);
+ case MXC_USB_CLK:
+ return mxc_get_main_clock(USB_CLK);
+ case MXC_FEC_CLK:
+ return get_ipg_clk();
+ case MXC_CSPI_CLK:
+ return get_ipg_clk();
+ }
+ return -1;
+}
+
+#ifdef CONFIG_FEC_MXC
+/*
+ * The MX35 has no fuse for MAC, return a NULL MAC
+ */
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+ memset(mac, 0, 6);
+}
+
+u32 imx_get_fecclk(void)
+{
+ return mxc_get_clock(MXC_IPG_CLK);
+}
+#endif
+
+int do_mx35_showclocks(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ u32 cpufreq = get_mcu_main_clk();
+ printf("mx35 cpu clock: %dMHz\n", cpufreq / 1000000);
+ printf("ipg clock : %dHz\n", get_ipg_clk());
+ printf("ipg per clock : %dHz\n", get_ipg_per_clk());
+ printf("uart clock : %dHz\n", mxc_get_clock(MXC_UART_CLK));
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ clocks, CONFIG_SYS_MAXARGS, 1, do_mx35_showclocks,
+ "display clocks",
+ ""
+);
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+static char *get_reset_cause(void)
+{
+ /* read RCSR register from CCM module */
+ struct ccm_regs *ccm =
+ (struct ccm_regs *)IMX_CCM_BASE;
+
+ u32 cause = readl(&ccm->rcsr) & 0x0F;
+
+ switch (cause) {
+ case 0x0000:
+ return "POR";
+ case 0x0002:
+ return "JTAG";
+ case 0x0004:
+ return "RST";
+ case 0x0008:
+ return "WDOG";
+ default:
+ return "unknown reset";
+ }
+}
+
+int print_cpuinfo(void)
+{
+ u32 srev = get_cpu_rev();
+
+ printf("CPU: Freescale i.MX35 rev %d.%d at %d MHz.\n",
+ (srev & 0xF0) >> 4, (srev & 0x0F),
+ get_mcu_main_clk() / 1000000);
+
+ printf("Reset cause: %s\n", get_reset_cause());
+
+ return 0;
+}
+#endif
+
+/*
+ * Initializes on-chip ethernet controllers.
+ * to override, implement board_eth_init()
+ */
+int cpu_eth_init(struct bd_info *bis)
+{
+ int rc = -ENODEV;
+
+#if defined(CONFIG_FEC_MXC)
+ rc = fecmxc_initialize(bis);
+#endif
+
+ return rc;
+}
+
+#ifdef CONFIG_FSL_ESDHC_IMX
+/*
+ * Initializes on-chip MMC controllers.
+ * to override, implement board_mmc_init()
+ */
+int cpu_mmc_init(struct bd_info *bis)
+{
+ return fsl_esdhc_mmc_init(bis);
+}
+#endif
+
+int get_clocks(void)
+{
+#ifdef CONFIG_FSL_ESDHC_IMX
+#if CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC2_BASE_ADDR
+ gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+#elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC3_BASE_ADDR
+ gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+#else
+ gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
+#endif
+#endif
+ return 0;
+}
+
+#define RCSR_MEM_CTL_WEIM 0
+#define RCSR_MEM_CTL_NAND 1
+#define RCSR_MEM_CTL_ATA 2
+#define RCSR_MEM_CTL_EXPANSION 3
+#define RCSR_MEM_TYPE_NOR 0
+#define RCSR_MEM_TYPE_ONENAND 2
+#define RCSR_MEM_TYPE_SD 0
+#define RCSR_MEM_TYPE_I2C 2
+#define RCSR_MEM_TYPE_SPI 3
+
+u32 spl_boot_device(void)
+{
+ struct ccm_regs *ccm =
+ (struct ccm_regs *)IMX_CCM_BASE;
+
+ u32 rcsr = readl(&ccm->rcsr);
+ u32 mem_type, mem_ctl;
+
+ /* In external mode, no boot device is returned */
+ if ((rcsr >> 10) & 0x03)
+ return BOOT_DEVICE_NONE;
+
+ mem_ctl = (rcsr >> 25) & 0x03;
+ mem_type = (rcsr >> 23) & 0x03;
+
+ switch (mem_ctl) {
+ case RCSR_MEM_CTL_WEIM:
+ switch (mem_type) {
+ case RCSR_MEM_TYPE_NOR:
+ return BOOT_DEVICE_NOR;
+ case RCSR_MEM_TYPE_ONENAND:
+ return BOOT_DEVICE_ONENAND;
+ default:
+ return BOOT_DEVICE_NONE;
+ }
+ case RCSR_MEM_CTL_NAND:
+ return BOOT_DEVICE_NAND;
+ case RCSR_MEM_CTL_EXPANSION:
+ switch (mem_type) {
+ case RCSR_MEM_TYPE_SD:
+ return BOOT_DEVICE_MMC1;
+ case RCSR_MEM_TYPE_I2C:
+ return BOOT_DEVICE_I2C;
+ case RCSR_MEM_TYPE_SPI:
+ return BOOT_DEVICE_SPI;
+ default:
+ return BOOT_DEVICE_NONE;
+ }
+ }
+
+ return BOOT_DEVICE_NONE;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/mx35/mx35_sdram.c b/roms/u-boot/arch/arm/cpu/arm1136/mx35/mx35_sdram.c
new file mode 100644
index 000000000..f120e84dc
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/mx35/mx35_sdram.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2012, Stefano Babic <sbabic@denx.de>
+ */
+
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <asm/arch/imx-regs.h>
+#include <linux/types.h>
+#include <asm/arch/sys_proto.h>
+
+#define ESDCTL_DDR2_EMR2 0x04000000
+#define ESDCTL_DDR2_EMR3 0x06000000
+#define ESDCTL_PRECHARGE 0x00000400
+#define ESDCTL_DDR2_EN_DLL 0x02000400
+#define ESDCTL_DDR2_RESET_DLL 0x00000333
+#define ESDCTL_DDR2_MR 0x00000233
+#define ESDCTL_DDR2_OCD_DEFAULT 0x02000780
+
+enum {
+ SMODE_NORMAL = 0,
+ SMODE_PRECHARGE,
+ SMODE_AUTO_REFRESH,
+ SMODE_LOAD_REG,
+ SMODE_MANUAL_REFRESH
+};
+
+#define set_mode(x, en, m) (x | (en << 31) | (m << 28))
+
+static inline void dram_wait(unsigned int count)
+{
+ volatile unsigned int wait = count;
+
+ while (wait--)
+ ;
+
+}
+
+void mx3_setup_sdram_bank(u32 start_address, u32 ddr2_config,
+ u32 row, u32 col, u32 dsize, u32 refresh)
+{
+ struct esdc_regs *esdc = (struct esdc_regs *)ESDCTL_BASE_ADDR;
+ u32 *cfg_reg, *ctl_reg;
+ u32 val;
+ u32 ctlval;
+
+ switch (start_address) {
+ case CSD0_BASE_ADDR:
+ cfg_reg = &esdc->esdcfg0;
+ ctl_reg = &esdc->esdctl0;
+ break;
+ case CSD1_BASE_ADDR:
+ cfg_reg = &esdc->esdcfg1;
+ ctl_reg = &esdc->esdctl1;
+ break;
+ default:
+ return;
+ }
+
+ /* The MX35 supports 11 up to 14 rows */
+ if (row < 11 || row > 14 || col < 8 || col > 10)
+ return;
+ ctlval = (row - 11) << 24 | (col - 8) << 20 | (dsize << 16);
+
+ /* Initialize MISC register for DDR2 */
+ val = ESDC_MISC_RST | ESDC_MISC_MDDR_EN | ESDC_MISC_MDDR_DL_RST |
+ ESDC_MISC_DDR_EN | ESDC_MISC_DDR2_EN;
+ writel(val, &esdc->esdmisc);
+ val &= ~(ESDC_MISC_RST | ESDC_MISC_MDDR_DL_RST);
+ writel(val, &esdc->esdmisc);
+
+ /*
+ * according to DDR2 specs, wait a while before
+ * the PRECHARGE_ALL command
+ */
+ dram_wait(0x20000);
+
+ /* Load DDR2 config and timing */
+ writel(ddr2_config, cfg_reg);
+
+ /* Precharge ALL */
+ writel(set_mode(ctlval, 1, SMODE_PRECHARGE),
+ ctl_reg);
+ writel(0xda, start_address + ESDCTL_PRECHARGE);
+
+ /* Load mode */
+ writel(set_mode(ctlval, 1, SMODE_LOAD_REG),
+ ctl_reg);
+ writeb(0xda, start_address + ESDCTL_DDR2_EMR2); /* EMRS2 */
+ writeb(0xda, start_address + ESDCTL_DDR2_EMR3); /* EMRS3 */
+ writeb(0xda, start_address + ESDCTL_DDR2_EN_DLL); /* Enable DLL */
+ writeb(0xda, start_address + ESDCTL_DDR2_RESET_DLL); /* Reset DLL */
+
+ /* Precharge ALL */
+ writel(set_mode(ctlval, 1, SMODE_PRECHARGE),
+ ctl_reg);
+ writel(0xda, start_address + ESDCTL_PRECHARGE);
+
+ /* Set mode auto refresh : at least two refresh are required */
+ writel(set_mode(ctlval, 1, SMODE_AUTO_REFRESH),
+ ctl_reg);
+ writel(0xda, start_address);
+ writel(0xda, start_address);
+
+ writel(set_mode(ctlval, 1, SMODE_LOAD_REG),
+ ctl_reg);
+ writeb(0xda, start_address + ESDCTL_DDR2_MR);
+ writeb(0xda, start_address + ESDCTL_DDR2_OCD_DEFAULT);
+
+ /* OCD mode exit */
+ writeb(0xda, start_address + ESDCTL_DDR2_EN_DLL); /* Enable DLL */
+
+ /* Set normal mode */
+ writel(set_mode(ctlval, 1, SMODE_NORMAL) | refresh,
+ ctl_reg);
+
+ dram_wait(0x20000);
+
+ /* Do not set delay lines, only for MDDR */
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/mx35/relocate.S b/roms/u-boot/arch/arm/cpu/arm1136/mx35/relocate.S
new file mode 100644
index 000000000..e41e5a572
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/mx35/relocate.S
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * relocate - i.MX35-specific vector relocation
+ *
+ * Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net>
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * The i.MX35 SoC is very specific with respect to exceptions: it
+ * does not provide RAM at the high vectors address (0xFFFF0000),
+ * thus only the low address (0x00000000) is useable; but that is
+ * in ROM, so let's avoid relocating the vectors.
+ */
+ .section .text.relocate_vectors,"ax",%progbits
+
+ENTRY(relocate_vectors)
+
+ bx lr
+
+ENDPROC(relocate_vectors)
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/mx35/timer.c b/roms/u-boot/arch/arm/cpu/arm1136/mx35/timer.c
new file mode 100644
index 000000000..f2541c398
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/mx35/timer.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2007
+ * Sascha Hauer, Pengutronix
+ *
+ * (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/ptrace.h>
+
+/* General purpose timers bitfields */
+#define GPTCR_SWR (1<<15) /* Software reset */
+#define GPTCR_FRR (1<<9) /* Freerun / restart */
+#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */
+#define GPTCR_TEN (1) /* Timer enable */
+
+/*
+ * nothing really to do with interrupts, just starts up a counter.
+ * The 32KHz 32-bit timer overruns in 134217 seconds
+ */
+int timer_init(void)
+{
+ int i;
+ struct gpt_regs *gpt = (struct gpt_regs *)GPT1_BASE_ADDR;
+ struct ccm_regs *ccm = (struct ccm_regs *)CCM_BASE_ADDR;
+
+ /* setup GP Timer 1 */
+ writel(GPTCR_SWR, &gpt->ctrl);
+
+ writel(readl(&ccm->cgr1) | 3 << MXC_CCM_CGR1_GPT_OFFSET, &ccm->cgr1);
+
+ for (i = 0; i < 100; i++)
+ writel(0, &gpt->ctrl); /* We have no udelay by now */
+ writel(0, &gpt->pre); /* prescaler = 1 */
+ /* Freerun Mode, 32KHz input */
+ writel(readl(&gpt->ctrl) | GPTCR_CLKSOURCE_32 | GPTCR_FRR,
+ &gpt->ctrl);
+ writel(readl(&gpt->ctrl) | GPTCR_TEN, &gpt->ctrl);
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/start.S b/roms/u-boot/arch/arm/cpu/arm1136/start.S
new file mode 100644
index 000000000..da7278e59
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/start.S
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * armboot - Startup Code for OMP2420/ARM1136 CPU-core
+ *
+ * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
+ *
+ * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
+ * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
+ * Copyright (c) 2003 Kshitij <kshitij@ti.com>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * setup Memory and board specific bits prior to relocation.
+ * relocate armboot to ram
+ * setup stack
+ *
+ *************************************************************************
+ */
+
+ .globl reset
+
+reset:
+ /*
+ * set the cpu to SVC32 mode
+ */
+ mrs r0,cpsr
+ bic r0,r0,#0x1f
+ orr r0,r0,#0xd3
+ msr cpsr,r0
+
+ /* the mask ROM code should have PLL and others stable */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ bl cpu_init_crit
+#endif
+
+ bl _main
+
+/*------------------------------------------------------------------------------*/
+
+ .globl c_runtime_cpu_setup
+c_runtime_cpu_setup:
+
+ bx lr
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+cpu_init_crit:
+ /*
+ * flush v4 I/D caches
+ */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 /* Invalidate I+D+BTB caches */
+ mcr p15, 0, r0, c8, c7, 0 /* Invalidate Unified TLB */
+
+ /*
+ * disable MMU stuff and caches
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
+ bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
+ orr r0, r0, #0x00000002 @ set bit 1 (A) Align
+ orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
+ mcr p15, 0, r0, c1, c0, 0
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
+ /*
+ * Jump to board specific initialization... The Mask ROM will have already initialized
+ * basic memory. Go here to bump up clock rate and handle wake up conditions.
+ */
+ mov ip, lr /* persevere link reg across call */
+ bl lowlevel_init /* go setup pll,mux,memory */
+ mov lr, ip /* restore link */
+#endif
+ mov pc, lr /* back to my caller */
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/roms/u-boot/arch/arm/cpu/arm1136/u-boot-spl.lds b/roms/u-boot/arch/arm/cpu/arm1136/u-boot-spl.lds
new file mode 100644
index 000000000..f83988fd7
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1136/u-boot-spl.lds
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ * Aneesh V <aneesh@ti.com>
+ */
+
+MEMORY { .sram : ORIGIN = IMAGE_TEXT_BASE,\
+ LENGTH = IMAGE_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+ LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ .text :
+ {
+ __start = .;
+ *(.vectors)
+ arch/arm/cpu/arm1136/start.o (.text*)
+ *(.text*)
+ } >.sram
+
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
+
+ . = ALIGN(4);
+ .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
+ . = ALIGN(4);
+ __image_copy_end = .;
+
+ .end :
+ {
+ *(.__end)
+ }
+
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_end = .;
+ } >.sdram
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm1176/Makefile b/roms/u-boot/arch/arm/cpu/arm1176/Makefile
new file mode 100644
index 000000000..32332474f
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1176/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+
+obj- += dummy.o
+extra-y = start.o
+
+obj-y += ../arm11/
diff --git a/roms/u-boot/arch/arm/cpu/arm1176/start.S b/roms/u-boot/arch/arm/cpu/arm1176/start.S
new file mode 100644
index 000000000..140292468
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm1176/start.S
@@ -0,0 +1,121 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * armboot - Startup Code for ARM1176 CPU-core
+ *
+ * Copyright (c) 2007 Samsung Electronics
+ *
+ * Copyright (C) 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+ *
+ * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com)
+ * 2007-09-21 - Added MoviNAND and OneNAND boot codes by
+ * jsgood (jsgood.yang@samsung.com)
+ * Base codes by scsuh (sc.suh)
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+
+#ifndef CONFIG_SYS_PHY_UBOOT_BASE
+#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_UBOOT_BASE
+#endif
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * setup Memory and board specific bits prior to relocation.
+ * relocate armboot to ram
+ * setup stack
+ *
+ *************************************************************************
+ */
+
+ .globl reset
+
+reset:
+ /* Allow the board to save important registers */
+ b save_boot_params
+.globl save_boot_params_ret
+save_boot_params_ret:
+
+ /*
+ * set the cpu to SVC32 mode
+ */
+ mrs r0, cpsr
+ bic r0, r0, #0x3f
+ orr r0, r0, #0xd3
+ msr cpsr, r0
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+ /*
+ * we do sys-critical inits only at reboot,
+ * not when booting from ram!
+ */
+cpu_init_crit:
+ /*
+ * When booting from NAND - it has definitely been a reset, so, no need
+ * to flush caches and disable the MMU
+ */
+#ifndef CONFIG_SPL_BUILD
+ /*
+ * flush v4 I/D caches
+ */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
+ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
+
+ /*
+ * disable MMU stuff and caches
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
+ bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
+ orr r0, r0, #0x00000002 @ set bit 1 (A) Align
+ orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
+
+ /* Prepare to disable the MMU */
+ adr r2, mmu_disable_phys
+ sub r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
+ b mmu_disable
+
+ .align 5
+ /* Run in a single cache-line */
+mmu_disable:
+ mcr p15, 0, r0, c1, c0, 0
+ nop
+ nop
+ mov pc, r2
+mmu_disable_phys:
+
+#endif
+
+ /*
+ * Go setup Memory and board specific bits prior to relocation.
+ */
+ bl lowlevel_init /* go setup pll,mux,memory */
+
+ bl _main
+
+/*------------------------------------------------------------------------------*/
+
+ .globl c_runtime_cpu_setup
+c_runtime_cpu_setup:
+
+ mov pc, lr
+
+WEAK(save_boot_params)
+ b save_boot_params_ret /* back to my caller */
+ENDPROC(save_boot_params)
diff --git a/roms/u-boot/arch/arm/cpu/arm720t/Makefile b/roms/u-boot/arch/arm/cpu/arm720t/Makefile
new file mode 100644
index 000000000..e70b59061
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm720t/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+extra-y = start.o
+obj-y = interrupts.o cpu.o
diff --git a/roms/u-boot/arch/arm/cpu/arm720t/cpu.c b/roms/u-boot/arch/arm/cpu/arm720t/cpu.c
new file mode 100644
index 000000000..ece09c83a
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm720t/cpu.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ */
+
+/*
+ * cleanup_before_linux() - Prepare the CPU to jump to Linux
+ *
+ * This function is called just before we call Linux, it
+ * prepares the processor for linux
+ */
+int cleanup_before_linux(void)
+{
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm720t/interrupts.c b/roms/u-boot/arch/arm/cpu/arm720t/interrupts.c
new file mode 100644
index 000000000..f0fc58dea
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm720t/interrupts.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_ARCH_TEGRA)
+static ulong timestamp;
+static ulong lastdec;
+
+int timer_init (void)
+{
+ /* No timer routines for tegra as yet */
+ lastdec = 0;
+ timestamp = 0;
+
+ return 0;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/arm720t/start.S b/roms/u-boot/arch/arm/cpu/arm720t/start.S
new file mode 100644
index 000000000..ecb4e44fd
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm720t/start.S
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * armboot - Startup Code for ARM720 CPU-core
+ *
+ * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from RAM!
+ * relocate armboot to ram
+ * setup stack
+ * jump to second stage
+ *
+ *************************************************************************
+ */
+
+ .globl reset
+
+reset:
+ /*
+ * set the cpu to SVC32 mode
+ */
+ mrs r0,cpsr
+ bic r0,r0,#0x1f
+ orr r0,r0,#0xd3
+ msr cpsr,r0
+
+ /*
+ * we do sys-critical inits only at reboot,
+ * not when booting from ram!
+ */
+#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && \
+ !defined(CONFIG_SKIP_LOWLEVEL_INIT_ONLY)
+ bl cpu_init_crit
+#endif
+
+ bl _main
+
+/*------------------------------------------------------------------------------*/
+
+ .globl c_runtime_cpu_setup
+c_runtime_cpu_setup:
+
+ mov pc, lr
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+
+#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && \
+ !defined(CONFIG_SKIP_LOWLEVEL_INIT_ONLY)
+cpu_init_crit:
+
+ mov ip, lr
+ /*
+ * before relocating, we have to setup RAM timing
+ * because memory timing is board-dependent, you will
+ * find a lowlevel_init.S in your board directory.
+ */
+ bl lowlevel_init
+ mov lr, ip
+
+ mov pc, lr
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/Makefile b/roms/u-boot/arch/arm/cpu/arm920t/Makefile
new file mode 100644
index 000000000..c63f578f1
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/Makefile
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+extra-y = start.o
+
+obj-y += cpu.o
+
+obj-$(CONFIG_EP93XX) += ep93xx/
+obj-$(CONFIG_IMX) += imx/
+
+# some files can only build in ARM mode
+
+ifdef CONFIG_$(SPL_)SYS_THUMB_BUILD
+CFLAGS_cpu.o := -marm
+endif
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/cpu.c b/roms/u-boot/arch/arm/cpu/arm920t/cpu.c
new file mode 100644
index 000000000..305713e78
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/cpu.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ */
+
+/*
+ * CPU specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <irq_func.h>
+#include <asm/system.h>
+
+static void cache_flush(void);
+
+int cleanup_before_linux (void)
+{
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * we turn off caches etc ...
+ */
+
+ disable_interrupts();
+
+ /* turn off I/D-cache */
+ icache_disable();
+ dcache_disable();
+ /* flush I/D-cache */
+ cache_flush();
+
+ return 0;
+}
+
+/* flush I/D-cache */
+static void cache_flush (void)
+{
+ unsigned long i = 0;
+
+ asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/Makefile b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/Makefile
new file mode 100644
index 000000000..152b5e7c5
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/Makefile
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Cirrus Logic EP93xx CPU-specific Makefile
+#
+# Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
+#
+# Copyright (C) 2004, 2005
+# Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
+#
+# Copyright (C) 2006
+# Dominic Rath <Dominic.Rath@gmx.de>
+#
+# Based on an original Makefile, which is
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+obj-y = cpu.o led.o speed.o timer.o
+obj-y += lowlevel_init.o
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/cpu.c b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/cpu.c
new file mode 100644
index 000000000..3435bdc74
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/cpu.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Cirrus Logic EP93xx CPU-specific support.
+ *
+ * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
+ *
+ * Copyright (C) 2004, 2005
+ * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/arch/ep93xx.h>
+#include <asm/io.h>
+
+/* We reset the CPU by generating a 1-->0 transition on DeviceCfg bit 31. */
+extern void reset_cpu(void)
+{
+ struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
+ uint32_t value;
+
+ /* Unlock DeviceCfg and set SWRST */
+ writel(0xAA, &syscon->sysswlock);
+ value = readl(&syscon->devicecfg);
+ value |= SYSCON_DEVICECFG_SWRST;
+ writel(value, &syscon->devicecfg);
+
+ /* Unlock DeviceCfg and clear SWRST */
+ writel(0xAA, &syscon->sysswlock);
+ value = readl(&syscon->devicecfg);
+ value &= ~SYSCON_DEVICECFG_SWRST;
+ writel(value, &syscon->devicecfg);
+
+ /* Dying... */
+ while (1)
+ ; /* noop */
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/led.c b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/led.c
new file mode 100644
index 000000000..862663acb
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/led.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2010, 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
+ */
+
+#include <asm/io.h>
+#include <asm/arch/ep93xx.h>
+#include <config.h>
+#include <status_led.h>
+
+static uint8_t saved_state[2] = {CONFIG_LED_STATUS_OFF, CONFIG_LED_STATUS_OFF};
+static uint32_t gpio_pin[2] = {1 << CONFIG_LED_STATUS_GREEN,
+ 1 << CONFIG_LED_STATUS_RED};
+
+static inline void switch_LED_on(uint8_t led)
+{
+ register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE;
+
+ writel(readl(&gpio->pedr) | gpio_pin[led], &gpio->pedr);
+ saved_state[led] = CONFIG_LED_STATUS_ON;
+}
+
+static inline void switch_LED_off(uint8_t led)
+{
+ register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE;
+
+ writel(readl(&gpio->pedr) & ~gpio_pin[led], &gpio->pedr);
+ saved_state[led] = CONFIG_LED_STATUS_OFF;
+}
+
+void red_led_on(void)
+{
+ switch_LED_on(CONFIG_LED_STATUS_RED);
+}
+
+void red_led_off(void)
+{
+ switch_LED_off(CONFIG_LED_STATUS_RED);
+}
+
+void green_led_on(void)
+{
+ switch_LED_on(CONFIG_LED_STATUS_GREEN);
+}
+
+void green_led_off(void)
+{
+ switch_LED_off(CONFIG_LED_STATUS_GREEN);
+}
+
+void __led_init(led_id_t mask, int state)
+{
+ __led_set(mask, state);
+}
+
+void __led_toggle(led_id_t mask)
+{
+ if (CONFIG_LED_STATUS_RED == mask) {
+ if (CONFIG_LED_STATUS_ON == saved_state[CONFIG_LED_STATUS_RED])
+ red_led_off();
+ else
+ red_led_on();
+ } else if (CONFIG_LED_STATUS_GREEN == mask) {
+ if (CONFIG_LED_STATUS_ON ==
+ saved_state[CONFIG_LED_STATUS_GREEN])
+ green_led_off();
+ else
+ green_led_on();
+ }
+}
+
+void __led_set(led_id_t mask, int state)
+{
+ if (CONFIG_LED_STATUS_RED == mask) {
+ if (CONFIG_LED_STATUS_ON == state)
+ red_led_on();
+ else
+ red_led_off();
+ } else if (CONFIG_LED_STATUS_GREEN == mask) {
+ if (CONFIG_LED_STATUS_ON == state)
+ green_led_on();
+ else
+ green_led_off();
+ }
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S
new file mode 100644
index 000000000..5239b1053
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S
@@ -0,0 +1,457 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Low-level initialization for EP93xx
+ *
+ * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
+ * Copyright (C) 2013
+ * Sergey Kostanabev <sergey.kostanbaev <at> fairwaves.ru>
+ *
+ * Copyright (C) 2006 Dominic Rath <Dominic.Rath@gmx.de>
+ * Copyright (C) 2006 Cirrus Logic Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ */
+
+#include <config.h>
+#include <asm/arch-ep93xx/ep93xx.h>
+
+/*
+/* Configure the SDRAM based on the supplied settings.
+ *
+ * Input: r0 - SDRAM DEVCFG register
+ * r2 - configuration for SDRAM chips
+ * Output: none
+ * Modifies: r3, r4
+ */
+ep93xx_sdram_config:
+ /* Program the SDRAM device configuration register. */
+ ldr r3, =SDRAM_BASE
+#ifdef CONFIG_EDB93XX_SDCS0
+ str r0, [r3, #SDRAM_OFF_DEVCFG0]
+#endif
+#ifdef CONFIG_EDB93XX_SDCS1
+ str r0, [r3, #SDRAM_OFF_DEVCFG1]
+#endif
+#ifdef CONFIG_EDB93XX_SDCS2
+ str r0, [r3, #SDRAM_OFF_DEVCFG2]
+#endif
+#ifdef CONFIG_EDB93XX_SDCS3
+ str r0, [r3, #SDRAM_OFF_DEVCFG3]
+#endif
+
+ /* Set the Initialize and MRS bits (issue continuous NOP commands
+ * (INIT & MRS set))
+ */
+ ldr r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_INIT | \
+ EP93XX_SDRAMCTRL_GLOBALCFG_MRS | \
+ EP93XX_SDRAMCTRL_GLOBALCFG_CKE)
+ str r4, [r3, #SDRAM_OFF_GLCONFIG]
+
+ /* Delay for 200us. */
+ mov r4, #0x3000
+delay1:
+ subs r4, r4, #1
+ bne delay1
+
+ /* Clear the MRS bit to issue a precharge all. */
+ ldr r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_INIT | \
+ EP93XX_SDRAMCTRL_GLOBALCFG_CKE)
+ str r4, [r3, #SDRAM_OFF_GLCONFIG]
+
+ /* Temporarily set the refresh timer to 0x10. Make it really low so
+ * that refresh cycles are generated.
+ */
+ ldr r4, =0x10
+ str r4, [r3, #SDRAM_OFF_REFRSHTIMR]
+
+ /* Delay for at least 80 SDRAM clock cycles. */
+ mov r4, #80
+delay2:
+ subs r4, r4, #1
+ bne delay2
+
+ /* Set the refresh timer to the fastest required for any device
+ * that might be used. Set 9.6 ms refresh time.
+ */
+ ldr r4, =0x01e0
+ str r4, [r3, #SDRAM_OFF_REFRSHTIMR]
+
+ /* Select mode register update mode. */
+ ldr r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_CKE | \
+ EP93XX_SDRAMCTRL_GLOBALCFG_MRS)
+ str r4, [r3, #SDRAM_OFF_GLCONFIG]
+
+ /* Program the mode register on the SDRAM by performing fake read */
+ ldr r4, [r2]
+
+ /* Select normal operating mode. */
+ ldr r4, =EP93XX_SDRAMCTRL_GLOBALCFG_CKE
+ str r4, [r3, #SDRAM_OFF_GLCONFIG]
+
+ /* Return to the caller. */
+ mov pc, lr
+
+/*
+ * Test to see if the SDRAM has been configured in a usable mode.
+ *
+ * Input: r0 - Test address of SDRAM
+ * Output: r0 - 0 -- Test OK, -1 -- Failed
+ * Modifies: r0-r5
+ */
+ep93xx_sdram_test:
+ /* Load the test patterns to be written to SDRAM. */
+ ldr r1, =0xf00dface
+ ldr r2, =0xdeadbeef
+ ldr r3, =0x08675309
+ ldr r4, =0xdeafc0ed
+
+ /* Store the test patterns to SDRAM. */
+ stmia r0, {r1-r4}
+
+ /* Load the test patterns from SDRAM one at a time and compare them
+ * to the actual pattern.
+ */
+ ldr r5, [r0]
+ cmp r5, r1
+ ldreq r5, [r0, #0x0004]
+ cmpeq r5, r2
+ ldreq r5, [r0, #0x0008]
+ cmpeq r5, r3
+ ldreq r5, [r0, #0x000c]
+ cmpeq r5, r4
+
+ /* Return -1 if a mismatch was encountered, 0 otherwise. */
+ mvnne r0, #0xffffffff
+ moveq r0, #0x00000000
+
+ /* Return to the caller. */
+ mov pc, lr
+
+/*
+ * Determine the size of the SDRAM. Use data=address for the scan.
+ *
+ * Input: r0 - Start SDRAM address
+ * Return: r0 - Single block size
+ * r1 - Valid block mask
+ * r2 - Total block count
+ * Modifies: r0-r5
+ */
+ep93xx_sdram_size:
+ /* Store zero at offset zero. */
+ str r0, [r0]
+
+ /* Start checking for an alias at 1MB into SDRAM. */
+ ldr r1, =0x00100000
+
+ /* Store the offset at the current offset. */
+check_block_size:
+ str r1, [r0, r1]
+
+ /* Read back from zero. */
+ ldr r2, [r0]
+
+ /* Stop searching of an alias was found. */
+ cmp r1, r2
+ beq found_block_size
+
+ /* Advance to the next power of two boundary. */
+ mov r1, r1, lsl #1
+
+ /* Loop back if the size has not reached 256MB. */
+ cmp r1, #0x10000000
+ bne check_block_size
+
+ /* A full 256MB of memory was found, so return it now. */
+ ldr r0, =0x10000000
+ ldr r1, =0x00000000
+ ldr r2, =0x00000001
+ mov pc, lr
+
+ /* An alias was found. See if the first block is 128MB in size. */
+found_block_size:
+ cmp r1, #0x08000000
+
+ /* The first block is 128MB, so there is no further memory. Return it
+ * now.
+ */
+ ldreq r0, =0x08000000
+ ldreq r1, =0x00000000
+ ldreq r2, =0x00000001
+ moveq pc, lr
+
+ /* Save the block size, set the block address bits to zero, and
+ * initialize the block count to one.
+ */
+ mov r3, r1
+ ldr r4, =0x00000000
+ ldr r5, =0x00000001
+
+ /* Look for additional blocks of memory by searching for non-aliases. */
+find_blocks:
+ /* Store zero back to address zero. It may be overwritten. */
+ str r0, [r0]
+
+ /* Advance to the next power of two boundary. */
+ mov r1, r1, lsl #1
+
+ /* Store the offset at the current offset. */
+ str r1, [r0, r1]
+
+ /* Read back from zero. */
+ ldr r2, [r0]
+
+ /* See if a non-alias was found. */
+ cmp r1, r2
+
+ /* If a non-alias was found, then or in the block address bit and
+ * multiply the block count by two (since there are two unique
+ * blocks, one with this bit zero and one with it one).
+ */
+ orrne r4, r4, r1
+ movne r5, r5, lsl #1
+
+ /* Continue searching if there are more address bits to check. */
+ cmp r1, #0x08000000
+ bne find_blocks
+
+ /* Return the block size, address mask, and count. */
+ mov r0, r3
+ mov r1, r4
+ mov r2, r5
+
+ /* Return to the caller. */
+ mov pc, lr
+
+
+.globl lowlevel_init
+lowlevel_init:
+
+ mov r6, lr
+
+ /* Make sure caches are off and invalidated. */
+ ldr r0, =0x00000000
+ mcr p15, 0, r0, c1, c0, 0
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ /* Turn off the green LED and turn on the red LED. If the red LED
+ * is left on for too long, the external reset circuit described
+ * by application note AN258 will cause the system to reset.
+ */
+ ldr r1, =EP93XX_LED_DATA
+ ldr r0, [r1]
+ bic r0, r0, #EP93XX_LED_GREEN_ON
+ orr r0, r0, #EP93XX_LED_RED_ON
+ str r0, [r1]
+
+ /* Undo the silly static memory controller programming performed
+ * by the boot rom.
+ */
+ ldr r0, =SMC_BASE
+
+ /* Set WST1 and WST2 to 31 HCLK cycles (slowest access) */
+ ldr r1, =0x0000fbe0
+
+ /* Reset EP93XX_OFF_SMCBCR0 */
+ ldr r2, [r0]
+ orr r2, r2, r1
+ str r2, [r0]
+
+ ldr r2, [r0, #EP93XX_OFF_SMCBCR1]
+ orr r2, r2, r1
+ str r2, [r0, #EP93XX_OFF_SMCBCR1]
+
+ ldr r2, [r0, #EP93XX_OFF_SMCBCR2]
+ orr r2, r2, r1
+ str r2, [r0, #EP93XX_OFF_SMCBCR2]
+
+ ldr r2, [r0, #EP93XX_OFF_SMCBCR3]
+ orr r2, r2, r1
+ str r2, [r0, #EP93XX_OFF_SMCBCR3]
+
+ ldr r2, [r0, #EP93XX_OFF_SMCBCR6]
+ orr r2, r2, r1
+ str r2, [r0, #EP93XX_OFF_SMCBCR6]
+
+ ldr r2, [r0, #EP93XX_OFF_SMCBCR7]
+ orr r2, r2, r1
+ str r2, [r0, #EP93XX_OFF_SMCBCR7]
+
+ /* Set the PLL1 and processor clock. */
+ ldr r0, =SYSCON_BASE
+#ifdef CONFIG_EDB9301
+ /* 332MHz, giving a 166MHz processor clock. */
+ ldr r1, = 0x02b49907
+#else
+
+#ifdef CONFIG_EDB93XX_INDUSTRIAL
+ /* 384MHz, giving a 196MHz processor clock. */
+ ldr r1, =0x02a4bb38
+#else
+ /* 400MHz, giving a 200MHz processor clock. */
+ ldr r1, =0x02a4e39e
+#endif
+#endif
+ str r1, [r0, #SYSCON_OFF_CLKSET1]
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ /* Need to make sure that SDRAM is configured correctly before
+ * coping the code into it.
+ */
+
+#ifdef CONFIG_EDB93XX_SDCS0
+ mov r11, #SDRAM_DEVCFG0_BASE
+#endif
+#ifdef CONFIG_EDB93XX_SDCS1
+ mov r11, #SDRAM_DEVCFG1_BASE
+#endif
+#ifdef CONFIG_EDB93XX_SDCS2
+ mov r11, #SDRAM_DEVCFG2_BASE
+#endif
+#ifdef CONFIG_EDB93XX_SDCS3
+ ldr r0, =SYSCON_BASE
+ ldr r0, [r0, #SYSCON_OFF_SYSCFG]
+ ands r0, r0, #SYSCON_SYSCFG_LASDO
+ moveq r11, #SDRAM_DEVCFG3_ASD0_BASE
+ movne r11, #SDRAM_DEVCFG3_ASD1_BASE
+#endif
+ /* See Table 13-5 in EP93xx datasheet for more info about DRAM
+ * register mapping */
+
+ /* Try a 32-bit wide configuration of SDRAM. */
+ ldr r0, =(EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT | \
+ EP93XX_SDRAMCTRL_DEVCFG_SROMLL | \
+ EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2 | \
+ EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2)
+
+ /* Set burst count: 4 and CAS: 2
+ * Burst mode [A11:A10]; CAS [A16:A14]
+ */
+ orr r2, r11, #0x00008800
+ bl ep93xx_sdram_config
+
+ /* Test the SDRAM. */
+ mov r0, r11
+ bl ep93xx_sdram_test
+ cmp r0, #0x00000000
+ beq ep93xx_sdram_done
+
+ /* Try a 16-bit wide configuration of SDRAM. */
+ ldr r0, =(EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT | \
+ EP93XX_SDRAMCTRL_DEVCFG_SROMLL | \
+ EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2 | \
+ EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2 | \
+ EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH)
+
+ /* Set burst count: 8, CAS: 2, sequential burst
+ * Accoring to Table 13-3 for 16bit operations mapping must be shifted.
+ * Burst mode [A10:A9]; CAS [A15:A13]
+ */
+ orr r2, r11, #0x00004600
+ bl ep93xx_sdram_config
+
+ /* Test the SDRAM. */
+ mov r0, r11
+ bl ep93xx_sdram_test
+ cmp r0, #0x00000000
+ beq ep93xx_sdram_done
+
+ /* Turn off the red LED. */
+ ldr r0, =EP93XX_LED_DATA
+ ldr r1, [r0]
+ bic r1, r1, #EP93XX_LED_RED_ON
+ str r1, [r0]
+
+ /* There is no SDRAM so flash the green LED. */
+flash_green:
+ orr r1, r1, #EP93XX_LED_GREEN_ON
+ str r1, [r0]
+ ldr r2, =0x00010000
+flash_green_delay_1:
+ subs r2, r2, #1
+ bne flash_green_delay_1
+ bic r1, r1, #EP93XX_LED_GREEN_ON
+ str r1, [r0]
+ ldr r2, =0x00010000
+flash_green_delay_2:
+ subs r2, r2, #1
+ bne flash_green_delay_2
+ orr r1, r1, #EP93XX_LED_GREEN_ON
+ str r1, [r0]
+ ldr r2, =0x00010000
+flash_green_delay_3:
+ subs r2, r2, #1
+ bne flash_green_delay_3
+ bic r1, r1, #EP93XX_LED_GREEN_ON
+ str r1, [r0]
+ ldr r2, =0x00050000
+flash_green_delay_4:
+ subs r2, r2, #1
+ bne flash_green_delay_4
+ b flash_green
+
+
+ep93xx_sdram_done:
+ ldr r1, =EP93XX_LED_DATA
+ ldr r0, [r1]
+ bic r0, r0, #EP93XX_LED_RED_ON
+ str r0, [r1]
+
+ /* Determine the size of the SDRAM. */
+ mov r0, r11
+ bl ep93xx_sdram_size
+
+ /* Save the SDRAM characteristics. */
+ mov r8, r0
+ mov r9, r1
+ mov r10, r2
+
+ /* Compute total memory size into r1 */
+ mul r1, r8, r10
+#ifdef CONFIG_EDB93XX_SDCS0
+ ldr r2, [r0, #SDRAM_OFF_DEVCFG0]
+#endif
+#ifdef CONFIG_EDB93XX_SDCS1
+ ldr r2, [r0, #SDRAM_OFF_DEVCFG1]
+#endif
+#ifdef CONFIG_EDB93XX_SDCS2
+ ldr r2, [r0, #SDRAM_OFF_DEVCFG2]
+#endif
+#ifdef CONFIG_EDB93XX_SDCS3
+ ldr r2, [r0, #SDRAM_OFF_DEVCFG3]
+#endif
+
+ /* Consider small DRAM size as:
+ * < 32Mb for 32bit bus
+ * < 64Mb for 16bit bus
+ */
+ tst r2, #EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH
+ moveq r1, r1, lsr #1
+ cmp r1, #0x02000000
+
+#if defined(CONFIG_EDB9301)
+ /* Set refresh counter to 20ms for small DRAM size, otherwise 9.6ms */
+ movlt r1, #0x03f0
+ movge r1, #0x01e0
+#else
+ /* Set refresh counter to 30.7ms for small DRAM size, otherwise 15ms */
+ movlt r1, #0x0600
+ movge r1, #0x2f0
+#endif
+ str r1, [r0, #SDRAM_OFF_REFRSHTIMR]
+
+ /* Save the memory configuration information. */
+ orr r0, r11, #UBOOT_MEMORYCNF_BANK_SIZE
+ stmia r0, {r8-r11}
+
+ mov lr, r6
+ mov pc, lr
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/speed.c b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/speed.c
new file mode 100644
index 000000000..51e9dda05
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/speed.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Cirrus Logic EP93xx PLL support.
+ *
+ * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
+ */
+
+#include <common.h>
+#include <asm/arch/ep93xx.h>
+#include <asm/io.h>
+#include <div64.h>
+
+/*
+ * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL.
+ *
+ * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
+ * the specified bus in HZ.
+ */
+
+/*
+ * return the PLL output frequency
+ *
+ * PLL rate = CONFIG_SYS_CLK_FREQ * (X1FBD + 1) * (X2FBD + 1)
+ * / (X2IPD + 1) / 2^PS
+ */
+static ulong get_PLLCLK(uint32_t *pllreg)
+{
+ uint8_t i;
+ const uint32_t clkset = readl(pllreg);
+ uint64_t rate = CONFIG_SYS_CLK_FREQ;
+ rate *= ((clkset >> SYSCON_CLKSET_PLL_X1FBD1_SHIFT) & 0x1f) + 1;
+ rate *= ((clkset >> SYSCON_CLKSET_PLL_X2FBD2_SHIFT) & 0x3f) + 1;
+ do_div(rate, (clkset & 0x1f) + 1); /* X2IPD */
+ for (i = 0; i < ((clkset >> SYSCON_CLKSET_PLL_PS_SHIFT) & 3); i++)
+ rate >>= 1;
+
+ return (ulong)rate;
+}
+
+/* return FCLK frequency */
+ulong get_FCLK(void)
+{
+ const uint8_t fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
+ struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
+
+ const uint32_t clkset1 = readl(&syscon->clkset1);
+ const uint8_t fclk_div =
+ fclk_divisors[(clkset1 >> SYSCON_CLKSET1_FCLK_DIV_SHIFT) & 7];
+ const ulong fclk_rate = get_PLLCLK(&syscon->clkset1) / fclk_div;
+
+ return fclk_rate;
+}
+
+/* return HCLK frequency */
+ulong get_HCLK(void)
+{
+ const uint8_t hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
+ struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
+
+ const uint32_t clkset1 = readl(&syscon->clkset1);
+ const uint8_t hclk_div =
+ hclk_divisors[(clkset1 >> SYSCON_CLKSET1_HCLK_DIV_SHIFT) & 7];
+ const ulong hclk_rate = get_PLLCLK(&syscon->clkset1) / hclk_div;
+
+ return hclk_rate;
+}
+
+/* return PCLK frequency */
+ulong get_PCLK(void)
+{
+ const uint8_t pclk_divisors[] = { 1, 2, 4, 8 };
+ struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
+
+ const uint32_t clkset1 = readl(&syscon->clkset1);
+ const uint8_t pclk_div =
+ pclk_divisors[(clkset1 >> SYSCON_CLKSET1_PCLK_DIV_SHIFT) & 3];
+ const ulong pclk_rate = get_HCLK() / pclk_div;
+
+ return pclk_rate;
+}
+
+/* return UCLK frequency */
+ulong get_UCLK(void)
+{
+ struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
+ ulong uclk_rate;
+
+ const uint32_t value = readl(&syscon->pwrcnt);
+ if (value & SYSCON_PWRCNT_UART_BAUD)
+ uclk_rate = CONFIG_SYS_CLK_FREQ;
+ else
+ uclk_rate = CONFIG_SYS_CLK_FREQ / 2;
+
+ return uclk_rate;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/timer.c b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/timer.c
new file mode 100644
index 000000000..892bb06db
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/timer.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Cirrus Logic EP93xx timer support.
+ *
+ * Copyright (C) 2009, 2010 Matthias Kaehlcke <matthias@kaehlcke.net>
+ *
+ * Copyright (C) 2004, 2005
+ * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
+ *
+ * Based on the original intr.c Cirrus Logic EP93xx Rev D. interrupt support,
+ * author unknown.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <time.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <asm/arch/ep93xx.h>
+#include <asm/io.h>
+#include <div64.h>
+
+#define TIMER_CLKSEL (1 << 3)
+#define TIMER_ENABLE (1 << 7)
+
+#define TIMER_FREQ 508469 /* ticks / second */
+#define TIMER_MAX_VAL 0xFFFFFFFF
+
+static struct ep93xx_timer
+{
+ unsigned long long ticks;
+ unsigned long last_read;
+} timer;
+
+static inline unsigned long long usecs_to_ticks(unsigned long usecs)
+{
+ unsigned long long ticks = (unsigned long long)usecs * TIMER_FREQ;
+ do_div(ticks, 1000 * 1000);
+
+ return ticks;
+}
+
+static inline void read_timer(void)
+{
+ struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE;
+ const unsigned long now = TIMER_MAX_VAL - readl(&timer_regs->timer3.value);
+
+ if (now >= timer.last_read)
+ timer.ticks += now - timer.last_read;
+ else
+ /* an overflow occurred */
+ timer.ticks += TIMER_MAX_VAL - timer.last_read + now;
+
+ timer.last_read = now;
+}
+
+/*
+ * Get the number of ticks (in CONFIG_SYS_HZ resolution)
+ */
+unsigned long long get_ticks(void)
+{
+ unsigned long long sys_ticks;
+
+ read_timer();
+
+ sys_ticks = timer.ticks * CONFIG_SYS_HZ;
+ do_div(sys_ticks, TIMER_FREQ);
+
+ return sys_ticks;
+}
+
+unsigned long get_timer(unsigned long base)
+{
+ return get_ticks() - base;
+}
+
+void __udelay(unsigned long usec)
+{
+ unsigned long long target;
+
+ read_timer();
+
+ target = timer.ticks + usecs_to_ticks(usec);
+
+ while (timer.ticks < target)
+ read_timer();
+}
+
+int timer_init(void)
+{
+ struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE;
+
+ /* use timer 3 with 508KHz and free running, not enabled now */
+ writel(TIMER_CLKSEL, &timer_regs->timer3.control);
+
+ /* set initial timer value */
+ writel(TIMER_MAX_VAL, &timer_regs->timer3.load);
+
+ /* Enable the timer */
+ writel(TIMER_ENABLE | TIMER_CLKSEL,
+ &timer_regs->timer3.control);
+
+ /* Reset the timer */
+ read_timer();
+ timer.ticks = 0;
+
+ return 0;
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+unsigned long get_tbclk(void)
+{
+ return CONFIG_SYS_HZ;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/imx/Makefile b/roms/u-boot/arch/arm/cpu/arm920t/imx/Makefile
new file mode 100644
index 000000000..04bc12959
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/imx/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+obj-y += generic.o
+obj-y += speed.o
+obj-y += timer.o
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/imx/generic.c b/roms/u-boot/arch/arm/cpu/arm920t/imx/generic.c
new file mode 100644
index 000000000..dbb908ecd
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/imx/generic.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * arch/arm/mach-imx/generic.c
+ *
+ * author: Sascha Hauer
+ * Created: april 20th, 2004
+ * Copyright: Synertronixx GmbH
+ *
+ * Common code for i.MX machines
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_IMX
+
+#include <asm/arch/imx-regs.h>
+
+void imx_gpio_mode(int gpio_mode)
+{
+ unsigned int pin = gpio_mode & GPIO_PIN_MASK;
+ unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5;
+ unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10;
+ unsigned int tmp;
+
+ /* Pullup enable */
+ if(gpio_mode & GPIO_PUEN)
+ PUEN(port) |= (1<<pin);
+ else
+ PUEN(port) &= ~(1<<pin);
+
+ /* Data direction */
+ if(gpio_mode & GPIO_OUT)
+ DDIR(port) |= 1<<pin;
+ else
+ DDIR(port) &= ~(1<<pin);
+
+ /* Primary / alternate function */
+ if(gpio_mode & GPIO_AF)
+ GPR(port) |= (1<<pin);
+ else
+ GPR(port) &= ~(1<<pin);
+
+ /* use as gpio? */
+ if( ocr == 3 )
+ GIUS(port) |= (1<<pin);
+ else
+ GIUS(port) &= ~(1<<pin);
+
+ /* Output / input configuration */
+ /* FIXME: I'm not very sure about OCR and ICONF, someone
+ * should have a look over it
+ */
+ if(pin<16) {
+ tmp = OCR1(port);
+ tmp &= ~( 3<<(pin*2));
+ tmp |= (ocr << (pin*2));
+ OCR1(port) = tmp;
+
+ if( gpio_mode & GPIO_AOUT )
+ ICONFA1(port) &= ~( 3<<(pin*2));
+ if( gpio_mode & GPIO_BOUT )
+ ICONFB1(port) &= ~( 3<<(pin*2));
+ } else {
+ tmp = OCR2(port);
+ tmp &= ~( 3<<((pin-16)*2));
+ tmp |= (ocr << ((pin-16)*2));
+ OCR2(port) = tmp;
+
+ if( gpio_mode & GPIO_AOUT )
+ ICONFA2(port) &= ~( 3<<((pin-16)*2));
+ if( gpio_mode & GPIO_BOUT )
+ ICONFB2(port) &= ~( 3<<((pin-16)*2));
+ }
+}
+
+#endif /* CONFIG_IMX */
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/imx/speed.c b/roms/u-boot/arch/arm/cpu/arm920t/imx/speed.c
new file mode 100644
index 000000000..eff611319
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/imx/speed.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *
+ * (c) 2004 Sascha Hauer <sascha@saschahauer.de>
+ */
+
+
+#include <common.h>
+#if defined (CONFIG_IMX)
+
+#include <asm/arch/imx-regs.h>
+
+/* ------------------------------------------------------------------------- */
+/* NOTE: This describes the proper use of this file.
+ *
+ * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL.
+ * SH FIXME: 16780000 in our case
+ * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
+ * the specified bus in HZ.
+ */
+/* ------------------------------------------------------------------------- */
+
+ulong get_systemPLLCLK(void)
+{
+ /* FIXME: We assume System_SEL = 0 here */
+ u32 spctl0 = SPCTL0;
+ u32 mfi = (spctl0 >> 10) & 0xf;
+ u32 mfn = spctl0 & 0x3f;
+ u32 mfd = (spctl0 >> 16) & 0x3f;
+ u32 pd = (spctl0 >> 26) & 0xf;
+
+ mfi = mfi<=5 ? 5 : mfi;
+
+ return (2*(CONFIG_SYSPLL_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1);
+}
+
+ulong get_mcuPLLCLK(void)
+{
+ /* FIXME: We assume System_SEL = 0 here */
+ u32 mpctl0 = MPCTL0;
+ u32 mfi = (mpctl0 >> 10) & 0xf;
+ u32 mfn = mpctl0 & 0x3f;
+ u32 mfd = (mpctl0 >> 16) & 0x3f;
+ u32 pd = (mpctl0 >> 26) & 0xf;
+
+ mfi = mfi<=5 ? 5 : mfi;
+
+ return (2*(CONFIG_SYS_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1);
+}
+
+ulong get_FCLK(void)
+{
+ return (( CSCR>>15)&1) ? get_mcuPLLCLK()>>1 : get_mcuPLLCLK();
+}
+
+/* return HCLK frequency */
+ulong get_HCLK(void)
+{
+ u32 bclkdiv = (( CSCR >> 10 ) & 0xf) + 1;
+ printf("bclkdiv: %d\n", bclkdiv);
+ return get_systemPLLCLK() / bclkdiv;
+}
+
+/* return BCLK frequency */
+ulong get_BCLK(void)
+{
+ return get_HCLK();
+}
+
+ulong get_PERCLK1(void)
+{
+ return get_systemPLLCLK() / (((PCDR) & 0xf)+1);
+}
+
+ulong get_PERCLK2(void)
+{
+ return get_systemPLLCLK() / (((PCDR>>4) & 0xf)+1);
+}
+
+ulong get_PERCLK3(void)
+{
+ return get_systemPLLCLK() / (((PCDR>>16) & 0x7f)+1);
+}
+
+#endif /* defined (CONFIG_IMX) */
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/imx/timer.c b/roms/u-boot/arch/arm/cpu/arm920t/imx/timer.c
new file mode 100644
index 000000000..0cd3a0398
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/imx/timer.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <time.h>
+#if defined (CONFIG_IMX)
+
+#include <asm/arch/imx-regs.h>
+#include <linux/delay.h>
+
+int timer_init (void)
+{
+ int i;
+ /* setup GP Timer 1 */
+ TCTL1 = TCTL_SWR;
+ for ( i=0; i<100; i++) TCTL1 = 0; /* We have no udelay by now */
+ TPRER1 = get_PERCLK1() / 1000000; /* 1 MHz */
+ TCTL1 |= TCTL_FRR | (1<<1); /* Freerun Mode, PERCLK1 input */
+
+ /* Reset the timer */
+ TCTL1 &= ~TCTL_TEN;
+ TCTL1 |= TCTL_TEN; /* Enable timer */
+
+ return (0);
+}
+
+/*
+ * timer without interrupts
+ */
+static ulong get_timer_masked (void)
+{
+ return TCN1;
+}
+
+ulong get_timer (ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+void __udelay(unsigned long usec)
+{
+ ulong endtime = get_timer_masked() + usec;
+ signed long diff;
+
+ do {
+ ulong now = get_timer_masked ();
+ diff = endtime - now;
+ } while (diff >= 0);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return CONFIG_SYS_HZ;
+}
+
+/*
+ * Reset the cpu by setting up the watchdog timer and let him time out
+ */
+void reset_cpu(void)
+{
+ /* Disable watchdog and set Time-Out field to 0 */
+ WCR = 0x00000000;
+
+ /* Write Service Sequence */
+ WSR = 0x00005555;
+ WSR = 0x0000AAAA;
+
+ /* Enable watchdog */
+ WCR = 0x00000001;
+
+ while (1);
+ /*NOTREACHED*/
+}
+
+#endif /* defined (CONFIG_IMX) */
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/start.S b/roms/u-boot/arch/arm/cpu/arm920t/start.S
new file mode 100644
index 000000000..e9326f4b5
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm920t/start.S
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * armboot - Startup Code for ARM920 CPU-core
+ *
+ * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
+ */
+
+#include <asm-offsets.h>
+#include <common.h>
+#include <config.h>
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (called from the ARM reset exception vector)
+ *
+ * do important init only if we don't start from memory!
+ * relocate armboot to ram
+ * setup stack
+ * jump to second stage
+ *
+ *************************************************************************
+ */
+
+ .globl reset
+
+reset:
+ /*
+ * set the cpu to SVC32 mode
+ */
+ mrs r0, cpsr
+ bic r0, r0, #0x1f
+ orr r0, r0, #0xd3
+ msr cpsr, r0
+
+#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
+ /*
+ * relocate exception table
+ */
+ ldr r0, =_start
+ ldr r1, =0x0
+ mov r2, #16
+copyex:
+ subs r2, r2, #1
+ ldr r3, [r0], #4
+ str r3, [r1], #4
+ bne copyex
+#endif
+
+ /*
+ * we do sys-critical inits only at reboot,
+ * not when booting from ram!
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ bl cpu_init_crit
+#endif
+
+ bl _main
+
+/*------------------------------------------------------------------------------*/
+
+ .globl c_runtime_cpu_setup
+c_runtime_cpu_setup:
+
+ mov pc, lr
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+cpu_init_crit:
+ /*
+ * flush v4 I/D caches
+ */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
+ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
+
+ /*
+ * disable MMU stuff and caches
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
+ bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
+ orr r0, r0, #0x00000002 @ set bit 1 (A) Align
+ orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
+ mcr p15, 0, r0, c1, c0, 0
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
+ /*
+ * before relocating, we have to setup RAM timing
+ * because memory timing is board-dependend, you will
+ * find a lowlevel_init.S in your board directory.
+ */
+ mov ip, lr
+
+ bl lowlevel_init
+ mov lr, ip
+#endif
+ mov pc, lr
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/Makefile b/roms/u-boot/arch/arm/cpu/arm926ejs/Makefile
new file mode 100644
index 000000000..98aafe805
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/Makefile
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+extra-y = start.o
+obj-y = cpu.o cache.o
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_NO_CPU_SUPPORT
+extra-y :=
+endif
+endif
+
+obj-$(CONFIG_ARMADA100) += armada100/
+obj-$(CONFIG_MX25) += mx25/
+obj-$(CONFIG_MX27) += mx27/
+obj-$(if $(filter mxs,$(SOC)),y) += mxs/
+obj-$(if $(filter spear,$(SOC)),y) += spear/
+
+# some files can only build in ARM or THUMB2, not THUMB1
+
+ifdef CONFIG_$(SPL_)SYS_THUMB_BUILD
+ifndef CONFIG_HAS_THUMB2
+
+CFLAGS_cpu.o := -marm
+CFLAGS_cache.o := -marm
+CFLAGS_REMOVE_cpu.o := $(LTO_CFLAGS)
+CFLAGS_REMOVE_cache.o := $(LTO_CFLAGS)
+
+endif
+endif
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/armada100/Makefile b/roms/u-boot/arch/arm/cpu/arm926ejs/armada100/Makefile
new file mode 100644
index 000000000..77ac0e262
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/armada100/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2010
+# Marvell Semiconductor <www.marvell.com>
+# Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+
+obj-y = cpu.o timer.o dram.o
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/armada100/cpu.c b/roms/u-boot/arch/arm/cpu/arm926ejs/armada100/cpu.c
new file mode 100644
index 000000000..96726b314
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/armada100/cpu.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ * Contributor: Mahavir Jain <mjain@marvell.com>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <init.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/armada100.h>
+
+#define UARTCLK14745KHZ (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1))
+#define SET_MRVL_ID (1<<8)
+#define L2C_RAM_SEL (1<<4)
+
+int arch_cpu_init(void)
+{
+ u32 val;
+ struct armd1cpu_registers *cpuregs =
+ (struct armd1cpu_registers *) ARMD1_CPU_BASE;
+
+ struct armd1apb1_registers *apb1clkres =
+ (struct armd1apb1_registers *) ARMD1_APBC1_BASE;
+
+ struct armd1mpmu_registers *mpmu =
+ (struct armd1mpmu_registers *) ARMD1_MPMU_BASE;
+
+ /* set SEL_MRVL_ID bit in ARMADA100_CPU_CONF register */
+ val = readl(&cpuregs->cpu_conf);
+ val = val | SET_MRVL_ID;
+ writel(val, &cpuregs->cpu_conf);
+
+ /* Enable Clocks for all hardware units */
+ writel(0xFFFFFFFF, &mpmu->acgr);
+
+ /* Turn on AIB and AIB-APB Functional clock */
+ writel(APBC_APBCLK | APBC_FNCLK, &apb1clkres->aib);
+
+ /* ensure L2 cache is not mapped as SRAM */
+ val = readl(&cpuregs->cpu_conf);
+ val = val & ~(L2C_RAM_SEL);
+ writel(val, &cpuregs->cpu_conf);
+
+ /* Enable GPIO clock */
+ writel(APBC_APBCLK, &apb1clkres->gpio);
+
+#ifdef CONFIG_I2C_MV
+ /* Enable general I2C clock */
+ writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+ writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+
+ /* Enable power I2C clock */
+ writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+ writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+#endif
+
+ /*
+ * Enable Functional and APB clock at 14.7456MHz
+ * for configured UART console
+ */
+#if (CONFIG_SYS_NS16550_COM1 == ARMD1_UART3_BASE)
+ writel(UARTCLK14745KHZ, &apb1clkres->uart3);
+#elif (CONFIG_SYS_NS16550_COM1 == ARMD1_UART2_BASE)
+ writel(UARTCLK14745KHZ, &apb1clkres->uart2);
+#else
+ writel(UARTCLK14745KHZ, &apb1clkres->uart1);
+#endif
+ icache_enable();
+
+ return 0;
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+ u32 id;
+ struct armd1cpu_registers *cpuregs =
+ (struct armd1cpu_registers *) ARMD1_CPU_BASE;
+
+ id = readl(&cpuregs->chip_id);
+ printf("SoC: Armada 88AP%X-%X\n", (id & 0xFFF), (id >> 0x10));
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/armada100/dram.c b/roms/u-boot/arch/arm/cpu/arm926ejs/armada100/dram.c
new file mode 100644
index 000000000..c97b5b194
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/armada100/dram.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>,
+ * Contributor: Mahavir Jain <mjain@marvell.com>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/armada100.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * ARMADA100 DRAM controller supports upto 8 banks
+ * for chip select 0 and 1
+ */
+
+/*
+ * DDR Memory Control Registers
+ * Refer Datasheet Appendix A.17
+ */
+struct armd1ddr_map_registers {
+ u32 cs; /* Memory Address Map Register -CS */
+ u32 pad[3];
+};
+
+struct armd1ddr_registers {
+ u8 pad[0x100 - 0x000];
+ struct armd1ddr_map_registers mmap[2];
+};
+
+/*
+ * armd1_sdram_base - reads SDRAM Base Address Register
+ */
+u32 armd1_sdram_base(int chip_sel)
+{
+ struct armd1ddr_registers *ddr_regs =
+ (struct armd1ddr_registers *)ARMD1_DRAM_BASE;
+ u32 result = 0;
+ u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs);
+
+ if (!CS_valid)
+ return 0;
+
+ result = readl(&ddr_regs->mmap[chip_sel].cs) & 0xFF800000;
+ return result;
+}
+
+/*
+ * armd1_sdram_size - reads SDRAM size
+ */
+u32 armd1_sdram_size(int chip_sel)
+{
+ struct armd1ddr_registers *ddr_regs =
+ (struct armd1ddr_registers *)ARMD1_DRAM_BASE;
+ u32 result = 0;
+ u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs);
+
+ if (!CS_valid)
+ return 0;
+
+ result = readl(&ddr_regs->mmap[chip_sel].cs);
+ result = (result >> 16) & 0xF;
+ if (result < 0x7) {
+ printf("Unknown DRAM Size\n");
+ return -1;
+ } else {
+ return ((0x8 << (result - 0x7)) * 1024 * 1024);
+ }
+}
+
+int dram_init(void)
+{
+ int i;
+
+ gd->ram_size = 0;
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ gd->bd->bi_dram[i].start = armd1_sdram_base(i);
+ gd->bd->bi_dram[i].size = armd1_sdram_size(i);
+ /*
+ * It is assumed that all memory banks are consecutive
+ * and without gaps.
+ * If the gap is found, ram_size will be reported for
+ * consecutive memory only
+ */
+ if (gd->bd->bi_dram[i].start != gd->ram_size)
+ break;
+
+ gd->ram_size += gd->bd->bi_dram[i].size;
+
+ }
+
+ for (; i < CONFIG_NR_DRAM_BANKS; i++) {
+ /* If above loop terminated prematurely, we need to set
+ * remaining banks' start address & size as 0. Otherwise other
+ * u-boot functions and Linux kernel gets wrong values which
+ * could result in crash */
+ gd->bd->bi_dram[i].start = 0;
+ gd->bd->bi_dram[i].size = 0;
+ }
+ return 0;
+}
+
+/*
+ * If this function is not defined here,
+ * board.c alters dram bank zero configuration defined above.
+ */
+int dram_init_banksize(void)
+{
+ dram_init();
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/armada100/timer.c b/roms/u-boot/arch/arm/cpu/arm926ejs/armada100/timer.c
new file mode 100644
index 000000000..6d77ad3b6
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/armada100/timer.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ * Contributor: Mahavir Jain <mjain@marvell.com>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <init.h>
+#include <time.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/armada100.h>
+#include <asm/global_data.h>
+#include <linux/delay.h>
+
+/*
+ * Timer registers
+ * Refer Section A.6 in Datasheet
+ */
+struct armd1tmr_registers {
+ u32 clk_ctrl; /* Timer clk control reg */
+ u32 match[9]; /* Timer match registers */
+ u32 count[3]; /* Timer count registers */
+ u32 status[3];
+ u32 ie[3];
+ u32 preload[3]; /* Timer preload value */
+ u32 preload_ctrl[3];
+ u32 wdt_match_en;
+ u32 wdt_match_r;
+ u32 wdt_val;
+ u32 wdt_sts;
+ u32 icr[3];
+ u32 wdt_icr;
+ u32 cer; /* Timer count enable reg */
+ u32 cmr;
+ u32 ilr[3];
+ u32 wcr;
+ u32 wfar;
+ u32 wsar;
+ u32 cvwr;
+};
+
+#define TIMER 0 /* Use TIMER 0 */
+/* Each timer has 3 match registers */
+#define MATCH_CMP(x) ((3 * TIMER) + x)
+#define TIMER_LOAD_VAL 0xffffffff
+#define COUNT_RD_REQ 0x1
+
+DECLARE_GLOBAL_DATA_PTR;
+/* Using gd->arch.tbu from timestamp and gd->arch.tbl for lastdec */
+
+/* For preventing risk of instability in reading counter value,
+ * first set read request to register cvwr and then read same
+ * register after it captures counter value.
+ */
+ulong read_timer(void)
+{
+ struct armd1tmr_registers *armd1timers =
+ (struct armd1tmr_registers *) ARMD1_TIMER_BASE;
+ volatile int loop=100;
+
+ writel(COUNT_RD_REQ, &armd1timers->cvwr);
+ while (loop--);
+ return(readl(&armd1timers->cvwr));
+}
+
+static ulong get_timer_masked(void)
+{
+ ulong now = read_timer();
+
+ if (now >= gd->arch.tbl) {
+ /* normal mode */
+ gd->arch.tbu += now - gd->arch.tbl;
+ } else {
+ /* we have an overflow ... */
+ gd->arch.tbu += now + TIMER_LOAD_VAL - gd->arch.tbl;
+ }
+ gd->arch.tbl = now;
+
+ return gd->arch.tbu;
+}
+
+ulong get_timer(ulong base)
+{
+ return ((get_timer_masked() / (CONFIG_SYS_HZ_CLOCK / 1000)) -
+ base);
+}
+
+void __udelay(unsigned long usec)
+{
+ ulong delayticks;
+ ulong endtime;
+
+ delayticks = (usec * (CONFIG_SYS_HZ_CLOCK / 1000000));
+ endtime = get_timer_masked() + delayticks;
+
+ while (get_timer_masked() < endtime);
+}
+
+/*
+ * init the Timer
+ */
+int timer_init(void)
+{
+ struct armd1apb1_registers *apb1clkres =
+ (struct armd1apb1_registers *) ARMD1_APBC1_BASE;
+ struct armd1tmr_registers *armd1timers =
+ (struct armd1tmr_registers *) ARMD1_TIMER_BASE;
+
+ /* Enable Timer clock at 3.25 MHZ */
+ writel(APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3), &apb1clkres->timers);
+
+ /* load value into timer */
+ writel(0x0, &armd1timers->clk_ctrl);
+ /* Use Timer 0 Match Resiger 0 */
+ writel(TIMER_LOAD_VAL, &armd1timers->match[MATCH_CMP(0)]);
+ /* Preload value is 0 */
+ writel(0x0, &armd1timers->preload[TIMER]);
+ /* Enable match comparator 0 for Timer 0 */
+ writel(0x1, &armd1timers->preload_ctrl[TIMER]);
+
+ /* Enable timer 0 */
+ writel(0x1, &armd1timers->cer);
+ /* init the gd->arch.tbu and gd->arch.tbl value */
+ gd->arch.tbl = read_timer();
+ gd->arch.tbu = 0;
+
+ return 0;
+}
+
+#define MPMU_APRR_WDTR (1<<4)
+#define TMR_WFAR 0xbaba /* WDT Register First key */
+#define TMP_WSAR 0xeb10 /* WDT Register Second key */
+
+/*
+ * This function uses internal Watchdog Timer
+ * based reset mechanism.
+ * Steps to write watchdog registers (protected access)
+ * 1. Write key value to TMR_WFAR reg.
+ * 2. Write key value to TMP_WSAR reg.
+ * 3. Perform write operation.
+ */
+void reset_cpu(void)
+{
+ struct armd1mpmu_registers *mpmu =
+ (struct armd1mpmu_registers *) ARMD1_MPMU_BASE;
+ struct armd1tmr_registers *armd1timers =
+ (struct armd1tmr_registers *) ARMD1_TIMER_BASE;
+ u32 val;
+
+ /* negate hardware reset to the WDT after system reset */
+ val = readl(&mpmu->aprr);
+ val = val | MPMU_APRR_WDTR;
+ writel(val, &mpmu->aprr);
+
+ /* reset/enable WDT clock */
+ writel(APBC_APBCLK | APBC_FNCLK | APBC_RST, &mpmu->wdtpcr);
+ readl(&mpmu->wdtpcr);
+ writel(APBC_APBCLK | APBC_FNCLK, &mpmu->wdtpcr);
+ readl(&mpmu->wdtpcr);
+
+ /* clear previous WDT status */
+ writel(TMR_WFAR, &armd1timers->wfar);
+ writel(TMP_WSAR, &armd1timers->wsar);
+ writel(0, &armd1timers->wdt_sts);
+
+ /* set match counter */
+ writel(TMR_WFAR, &armd1timers->wfar);
+ writel(TMP_WSAR, &armd1timers->wsar);
+ writel(0xf, &armd1timers->wdt_match_r);
+
+ /* enable WDT reset */
+ writel(TMR_WFAR, &armd1timers->wfar);
+ writel(TMP_WSAR, &armd1timers->wsar);
+ writel(0x3, &armd1timers->wdt_match_en);
+
+ while(1);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return (ulong)CONFIG_SYS_HZ;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/cache.c b/roms/u-boot/arch/arm/cpu/arm926ejs/cache.c
new file mode 100644
index 000000000..acab9bccc
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/cache.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2011
+ * Ilya Yanok, EmCraft Systems
+ */
+#include <cpu_func.h>
+#include <asm/cache.h>
+#include <linux/types.h>
+#include <common.h>
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+void invalidate_dcache_all(void)
+{
+ asm volatile("mcr p15, 0, %0, c7, c6, 0\n" : : "r"(0));
+}
+
+void flush_dcache_all(void)
+{
+ asm volatile(
+ "0:"
+ "mrc p15, 0, r15, c7, c14, 3\n"
+ "bne 0b\n"
+ "mcr p15, 0, %0, c7, c10, 4\n"
+ : : "r"(0) : "memory"
+ );
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+ if (!check_cache_range(start, stop))
+ return;
+
+ while (start < stop) {
+ asm volatile("mcr p15, 0, %0, c7, c6, 1\n" : : "r"(start));
+ start += CONFIG_SYS_CACHELINE_SIZE;
+ }
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+ if (!check_cache_range(start, stop))
+ return;
+
+ while (start < stop) {
+ asm volatile("mcr p15, 0, %0, c7, c14, 1\n" : : "r"(start));
+ start += CONFIG_SYS_CACHELINE_SIZE;
+ }
+
+ asm volatile("mcr p15, 0, %0, c7, c10, 4\n" : : "r"(0));
+}
+#else /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
+void invalidate_dcache_all(void)
+{
+}
+
+void flush_dcache_all(void)
+{
+}
+#endif /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
+
+/*
+ * Stub implementations for l2 cache operations
+ */
+
+__weak void l2_cache_disable(void) {}
+
+#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)
+__weak void invalidate_l2_cache(void) {}
+#endif
+
+#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
+/* Invalidate entire I-cache and branch predictor array */
+void invalidate_icache_all(void)
+{
+ unsigned long i = 0;
+
+ asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (i));
+}
+#else
+void invalidate_icache_all(void) {}
+#endif
+
+void enable_caches(void)
+{
+#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
+ icache_enable();
+#endif
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+ dcache_enable();
+#endif
+}
+
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/cpu.c b/roms/u-boot/arch/arm/cpu/arm926ejs/cpu.c
new file mode 100644
index 000000000..93d7a02ed
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/cpu.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ */
+
+/*
+ * CPU specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <irq_func.h>
+#include <asm/cache.h>
+#include <asm/system.h>
+
+static void cache_flush(void);
+
+int cleanup_before_linux (void)
+{
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * we turn off caches etc ...
+ */
+
+ disable_interrupts();
+
+
+ /* turn off I/D-cache */
+ icache_disable();
+ dcache_disable();
+ l2_cache_disable();
+
+ /* flush I/D-cache */
+ cache_flush();
+
+ return 0;
+}
+
+/* flush I/D-cache */
+static void cache_flush (void)
+{
+#if !(CONFIG_IS_ENABLED(SYS_ICACHE_OFF) && CONFIG_IS_ENABLED(SYS_DCACHE_OFF))
+ unsigned long i = 0;
+
+ asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
+#endif
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/Makefile b/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/Makefile
new file mode 100644
index 000000000..ac5ebaf5e
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+
+obj-y += generic.o timer.o reset.o relocate.o
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/generic.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/generic.c
new file mode 100644
index 000000000..9cd60abcc
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/generic.c
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2009 DENX Software Engineering
+ * Author: John Rigby <jrigby@gmail.com>
+ *
+ * Based on mx27/generic.c:
+ * Copyright (c) 2008 Eric Jarrige <eric.jarrige@armadeus.org>
+ * Copyright (c) 2009 Ilya Yanok <yanok@emcraft.com>
+ */
+
+#include <common.h>
+#include <clock_legacy.h>
+#include <div64.h>
+#include <init.h>
+#include <net.h>
+#include <netdev.h>
+#include <vsprintf.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch-imx/cpu.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/clock.h>
+
+#ifdef CONFIG_FSL_ESDHC_IMX
+#include <fsl_esdhc_imx.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
+/*
+ * get the system pll clock in Hz
+ *
+ * mfi + mfn / (mfd +1)
+ * f = 2 * f_ref * --------------------
+ * pd + 1
+ */
+static unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref)
+{
+ unsigned int mfi = (pll >> CCM_PLL_MFI_SHIFT)
+ & CCM_PLL_MFI_MASK;
+ int mfn = (pll >> CCM_PLL_MFN_SHIFT)
+ & CCM_PLL_MFN_MASK;
+ unsigned int mfd = (pll >> CCM_PLL_MFD_SHIFT)
+ & CCM_PLL_MFD_MASK;
+ unsigned int pd = (pll >> CCM_PLL_PD_SHIFT)
+ & CCM_PLL_PD_MASK;
+
+ mfi = mfi <= 5 ? 5 : mfi;
+ mfn = mfn >= 512 ? mfn - 1024 : mfn;
+ mfd += 1;
+ pd += 1;
+
+ return lldiv(2 * (u64) f_ref * (mfi * mfd + mfn),
+ mfd * pd);
+}
+
+static ulong imx_get_mpllclk(void)
+{
+ struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
+ ulong fref = MXC_HCLK;
+
+ return imx_decode_pll(readl(&ccm->mpctl), fref);
+}
+
+static ulong imx_get_upllclk(void)
+{
+ struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
+ ulong fref = MXC_HCLK;
+
+ return imx_decode_pll(readl(&ccm->upctl), fref);
+}
+
+static ulong imx_get_armclk(void)
+{
+ struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
+ ulong cctl = readl(&ccm->cctl);
+ ulong fref = imx_get_mpllclk();
+ ulong div;
+
+ if (cctl & CCM_CCTL_ARM_SRC)
+ fref = lldiv((u64) fref * 3, 4);
+
+ div = ((cctl >> CCM_CCTL_ARM_DIV_SHIFT)
+ & CCM_CCTL_ARM_DIV_MASK) + 1;
+
+ return fref / div;
+}
+
+static ulong imx_get_ahbclk(void)
+{
+ struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
+ ulong cctl = readl(&ccm->cctl);
+ ulong fref = imx_get_armclk();
+ ulong div;
+
+ div = ((cctl >> CCM_CCTL_AHB_DIV_SHIFT)
+ & CCM_CCTL_AHB_DIV_MASK) + 1;
+
+ return fref / div;
+}
+
+static ulong imx_get_ipgclk(void)
+{
+ return imx_get_ahbclk() / 2;
+}
+
+static ulong imx_get_perclk(int clk)
+{
+ struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
+ ulong fref = readl(&ccm->mcr) & (1 << clk) ? imx_get_upllclk() :
+ imx_get_ahbclk();
+ ulong div;
+
+ div = readl(&ccm->pcdr[CCM_PERCLK_REG(clk)]);
+ div = ((div >> CCM_PERCLK_SHIFT(clk)) & CCM_PERCLK_MASK) + 1;
+
+ return fref / div;
+}
+
+int imx_set_perclk(enum mxc_clock clk, bool from_upll, unsigned int freq)
+{
+ struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
+ ulong fref = from_upll ? imx_get_upllclk() : imx_get_ahbclk();
+ ulong div = (fref + freq - 1) / freq;
+
+ if (clk > MXC_UART_CLK || !div || --div > CCM_PERCLK_MASK)
+ return -EINVAL;
+
+ clrsetbits_le32(&ccm->pcdr[CCM_PERCLK_REG(clk)],
+ CCM_PERCLK_MASK << CCM_PERCLK_SHIFT(clk),
+ div << CCM_PERCLK_SHIFT(clk));
+ if (from_upll)
+ setbits_le32(&ccm->mcr, 1 << clk);
+ else
+ clrbits_le32(&ccm->mcr, 1 << clk);
+ return 0;
+}
+
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+ if (clk >= MXC_CLK_NUM)
+ return -1;
+ switch (clk) {
+ case MXC_ARM_CLK:
+ return imx_get_armclk();
+ case MXC_AHB_CLK:
+ return imx_get_ahbclk();
+ case MXC_IPG_CLK:
+ case MXC_CSPI_CLK:
+ case MXC_FEC_CLK:
+ return imx_get_ipgclk();
+ default:
+ return imx_get_perclk(clk);
+ }
+}
+
+u32 get_cpu_rev(void)
+{
+ u32 srev;
+ u32 system_rev = 0x25000;
+
+ /* read SREV register from IIM module */
+ struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
+ srev = readl(&iim->iim_srev);
+
+ switch (srev) {
+ case 0x00:
+ system_rev |= CHIP_REV_1_0;
+ break;
+ case 0x01:
+ system_rev |= CHIP_REV_1_1;
+ break;
+ case 0x02:
+ system_rev |= CHIP_REV_1_2;
+ break;
+ default:
+ system_rev |= 0x8000;
+ break;
+ }
+
+ return system_rev;
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+static char *get_reset_cause(void)
+{
+ /* read RCSR register from CCM module */
+ struct ccm_regs *ccm =
+ (struct ccm_regs *)IMX_CCM_BASE;
+
+ u32 cause = readl(&ccm->rcsr) & 0x0f;
+
+ if (cause == 0)
+ return "POR";
+ else if (cause == 1)
+ return "RST";
+ else if ((cause & 2) == 2)
+ return "WDOG";
+ else if ((cause & 4) == 4)
+ return "SW RESET";
+ else if ((cause & 8) == 8)
+ return "JTAG";
+ else
+ return "unknown reset";
+
+}
+
+int print_cpuinfo(void)
+{
+ char buf[32];
+ u32 cpurev = get_cpu_rev();
+
+ printf("CPU: Freescale i.MX25 rev%d.%d%s at %s MHz\n",
+ (cpurev & 0xF0) >> 4, (cpurev & 0x0F),
+ ((cpurev & 0x8000) ? " unknown" : ""),
+ strmhz(buf, imx_get_armclk()));
+ printf("Reset cause: %s\n", get_reset_cause());
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_FEC_MXC)
+/*
+ * Initializes on-chip ethernet controllers.
+ * to override, implement board_eth_init()
+ */
+int cpu_eth_init(struct bd_info *bis)
+{
+ struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
+ ulong val;
+
+ val = readl(&ccm->cgr0);
+ val |= (1 << 23);
+ writel(val, &ccm->cgr0);
+ return fecmxc_initialize(bis);
+}
+#endif
+
+int get_clocks(void)
+{
+#ifdef CONFIG_FSL_ESDHC_IMX
+#if CONFIG_SYS_FSL_ESDHC_ADDR == IMX_MMC_SDHC2_BASE
+ gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+#else
+ gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
+#endif
+#endif
+ return 0;
+}
+
+#ifdef CONFIG_FSL_ESDHC_IMX
+/*
+ * Initializes on-chip MMC controllers.
+ * to override, implement board_mmc_init()
+ */
+int cpu_mmc_init(struct bd_info *bis)
+{
+ return fsl_esdhc_mmc_init(bis);
+}
+#endif
+
+#ifdef CONFIG_FEC_MXC
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+ int i;
+ struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
+ struct fuse_bank *bank = &iim->bank[0];
+ struct fuse_bank0_regs *fuse =
+ (struct fuse_bank0_regs *)bank->fuse_regs;
+
+ for (i = 0; i < 6; i++)
+ mac[i] = readl(&fuse->mac_addr[i]) & 0xff;
+}
+#endif /* CONFIG_FEC_MXC */
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/relocate.S b/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/relocate.S
new file mode 100644
index 000000000..709e35c81
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/relocate.S
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * relocate - i.MX25-specific vector relocation
+ *
+ * Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net>
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * The i.MX25 SoC is very specific with respect to exceptions: it
+ * does not provide RAM at the high vectors address (0xFFFF0000),
+ * thus only the low address (0x00000000) is useable; but that is
+ * in ROM, so let's avoid relocating the vectors.
+ */
+ .section .text.relocate_vectors,"ax",%progbits
+
+ENTRY(relocate_vectors)
+
+ bx lr
+
+ENDPROC(relocate_vectors)
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/reset.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/reset.c
new file mode 100644
index 000000000..7844a99c1
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/reset.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2009
+ * Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+
+/*
+ * Reset the cpu by setting up the watchdog timer and let it time out
+ */
+void reset_cpu(void)
+{
+ struct wdog_regs *regs = (struct wdog_regs *)IMX_WDT_BASE;
+ /* Disable watchdog and set Time-Out field to 0 */
+ writew(0, &regs->wcr);
+
+ /* Write Service Sequence */
+ writew(WSR_UNLOCK1, &regs->wsr);
+ writew(WSR_UNLOCK2, &regs->wsr);
+
+ /* Enable watchdog */
+ writew(WCR_WDE, &regs->wcr);
+
+ while (1) ;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/timer.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/timer.c
new file mode 100644
index 000000000..4b726d5c7
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mx25/timer.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2009
+ * Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com>
+ *
+ * (C) Copyright 2009 DENX Software Engineering
+ * Author: John Rigby <jrigby@gmail.com>
+ * Add support for MX25
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/ptrace.h>
+
+/* nothing really to do with interrupts, just starts up a counter. */
+/* The 32KHz 32-bit timer overruns in 134217 seconds */
+int timer_init(void)
+{
+ int i;
+ struct gpt_regs *gpt = (struct gpt_regs *)IMX_GPT1_BASE;
+ struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
+
+ /* setup GP Timer 1 */
+ writel(GPT_CTRL_SWR, &gpt->ctrl);
+
+ writel(readl(&ccm->cgr1) | CCM_CGR1_GPT1, &ccm->cgr1);
+
+ for (i = 0; i < 100; i++)
+ writel(0, &gpt->ctrl); /* We have no udelay by now */
+ writel(0, &gpt->pre); /* prescaler = 1 */
+ /* Freerun Mode, 32KHz input */
+ writel(readl(&gpt->ctrl) | GPT_CTRL_CLKSOURCE_32 | GPT_CTRL_FRR,
+ &gpt->ctrl);
+ writel(readl(&gpt->ctrl) | GPT_CTRL_TEN, &gpt->ctrl);
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/Makefile b/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/Makefile
new file mode 100644
index 000000000..ac5ebaf5e
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+
+obj-y += generic.o timer.o reset.o relocate.o
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/generic.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/generic.c
new file mode 100644
index 000000000..8b9d3a272
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/generic.c
@@ -0,0 +1,378 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2008 Eric Jarrige <eric.jarrige@armadeus.org>
+ * Copyright (c) 2009 Ilya Yanok <yanok@emcraft.com>
+ */
+
+#include <common.h>
+#include <div64.h>
+#include <net.h>
+#include <netdev.h>
+#include <vsprintf.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/mach-imx/sys_proto.h>
+#ifdef CONFIG_MMC_MXC
+#include <asm/arch/mxcmmc.h>
+#endif
+
+/*
+ * get the system pll clock in Hz
+ *
+ * mfi + mfn / (mfd +1)
+ * f = 2 * f_ref * --------------------
+ * pd + 1
+ */
+static unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref)
+{
+ unsigned int mfi = (pll >> 10) & 0xf;
+ unsigned int mfn = pll & 0x3ff;
+ unsigned int mfd = (pll >> 16) & 0x3ff;
+ unsigned int pd = (pll >> 26) & 0xf;
+
+ mfi = mfi <= 5 ? 5 : mfi;
+
+ return lldiv(2 * (u64)f_ref * (mfi * (mfd + 1) + mfn),
+ (mfd + 1) * (pd + 1));
+}
+
+static ulong clk_in_32k(void)
+{
+ return 1024 * CONFIG_MX27_CLK32;
+}
+
+static ulong clk_in_26m(void)
+{
+ struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
+
+ if (readl(&pll->cscr) & CSCR_OSC26M_DIV1P5) {
+ /* divide by 1.5 */
+ return 26000000 * 2 / 3;
+ } else {
+ return 26000000;
+ }
+}
+
+static ulong imx_get_mpllclk(void)
+{
+ struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
+ ulong cscr = readl(&pll->cscr);
+ ulong fref;
+
+ if (cscr & CSCR_MCU_SEL)
+ fref = clk_in_26m();
+ else
+ fref = clk_in_32k();
+
+ return imx_decode_pll(readl(&pll->mpctl0), fref);
+}
+
+static ulong imx_get_armclk(void)
+{
+ struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
+ ulong cscr = readl(&pll->cscr);
+ ulong fref = imx_get_mpllclk();
+ ulong div;
+
+ if (!(cscr & CSCR_ARM_SRC_MPLL))
+ fref = lldiv((fref * 2), 3);
+
+ div = ((cscr >> 12) & 0x3) + 1;
+
+ return lldiv(fref, div);
+}
+
+static ulong imx_get_ahbclk(void)
+{
+ struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
+ ulong cscr = readl(&pll->cscr);
+ ulong fref = imx_get_mpllclk();
+ ulong div;
+
+ div = ((cscr >> 8) & 0x3) + 1;
+
+ return lldiv(fref * 2, 3 * div);
+}
+
+static __attribute__((unused)) ulong imx_get_spllclk(void)
+{
+ struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
+ ulong cscr = readl(&pll->cscr);
+ ulong fref;
+
+ if (cscr & CSCR_SP_SEL)
+ fref = clk_in_26m();
+ else
+ fref = clk_in_32k();
+
+ return imx_decode_pll(readl(&pll->spctl0), fref);
+}
+
+static ulong imx_decode_perclk(ulong div)
+{
+ return lldiv((imx_get_mpllclk() * 2), (div * 3));
+}
+
+static ulong imx_get_perclk1(void)
+{
+ struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
+
+ return imx_decode_perclk((readl(&pll->pcdr1) & 0x3f) + 1);
+}
+
+static ulong imx_get_perclk2(void)
+{
+ struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
+
+ return imx_decode_perclk(((readl(&pll->pcdr1) >> 8) & 0x3f) + 1);
+}
+
+static __attribute__((unused)) ulong imx_get_perclk3(void)
+{
+ struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
+
+ return imx_decode_perclk(((readl(&pll->pcdr1) >> 16) & 0x3f) + 1);
+}
+
+static __attribute__((unused)) ulong imx_get_perclk4(void)
+{
+ struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
+
+ return imx_decode_perclk(((readl(&pll->pcdr1) >> 24) & 0x3f) + 1);
+}
+
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+ switch (clk) {
+ case MXC_ARM_CLK:
+ return imx_get_armclk();
+ case MXC_I2C_CLK:
+ return imx_get_ahbclk()/2;
+ case MXC_UART_CLK:
+ return imx_get_perclk1();
+ case MXC_FEC_CLK:
+ return imx_get_ahbclk();
+ case MXC_ESDHC_CLK:
+ return imx_get_perclk2();
+ }
+ return -1;
+}
+
+
+u32 get_cpu_rev(void)
+{
+ return MXC_CPU_MX27 << 12;
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo (void)
+{
+ char buf[32];
+
+ printf("CPU: Freescale i.MX27 at %s MHz\n\n",
+ strmhz(buf, imx_get_mpllclk()));
+ return 0;
+}
+#endif
+
+int cpu_eth_init(struct bd_info *bis)
+{
+#if defined(CONFIG_FEC_MXC)
+ struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
+
+ /* enable FEC clock */
+ writel(readl(&pll->pccr1) | PCCR1_HCLK_FEC, &pll->pccr1);
+ writel(readl(&pll->pccr0) | PCCR0_FEC_EN, &pll->pccr0);
+ return fecmxc_initialize(bis);
+#else
+ return 0;
+#endif
+}
+
+/*
+ * Initializes on-chip MMC controllers.
+ * to override, implement board_mmc_init()
+ */
+int cpu_mmc_init(struct bd_info *bis)
+{
+#ifdef CONFIG_MMC_MXC
+ return mxc_mmc_init(bis);
+#else
+ return 0;
+#endif
+}
+
+void imx_gpio_mode(int gpio_mode)
+{
+ struct gpio_port_regs *regs = (struct gpio_port_regs *)IMX_GPIO_BASE;
+ unsigned int pin = gpio_mode & GPIO_PIN_MASK;
+ unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT;
+ unsigned int aout = (gpio_mode & GPIO_AOUT_MASK) >> GPIO_AOUT_SHIFT;
+ unsigned int bout = (gpio_mode & GPIO_BOUT_MASK) >> GPIO_BOUT_SHIFT;
+ unsigned int tmp;
+
+ /* Pullup enable */
+ if (gpio_mode & GPIO_PUEN) {
+ writel(readl(&regs->port[port].puen) | (1 << pin),
+ &regs->port[port].puen);
+ } else {
+ writel(readl(&regs->port[port].puen) & ~(1 << pin),
+ &regs->port[port].puen);
+ }
+
+ /* Data direction */
+ if (gpio_mode & GPIO_OUT) {
+ writel(readl(&regs->port[port].gpio_dir) | 1 << pin,
+ &regs->port[port].gpio_dir);
+ } else {
+ writel(readl(&regs->port[port].gpio_dir) & ~(1 << pin),
+ &regs->port[port].gpio_dir);
+ }
+
+ /* Primary / alternate function */
+ if (gpio_mode & GPIO_AF) {
+ writel(readl(&regs->port[port].gpr) | (1 << pin),
+ &regs->port[port].gpr);
+ } else {
+ writel(readl(&regs->port[port].gpr) & ~(1 << pin),
+ &regs->port[port].gpr);
+ }
+
+ /* use as gpio? */
+ if (!(gpio_mode & (GPIO_PF | GPIO_AF))) {
+ writel(readl(&regs->port[port].gius) | (1 << pin),
+ &regs->port[port].gius);
+ } else {
+ writel(readl(&regs->port[port].gius) & ~(1 << pin),
+ &regs->port[port].gius);
+ }
+
+ /* Output / input configuration */
+ if (pin < 16) {
+ tmp = readl(&regs->port[port].ocr1);
+ tmp &= ~(3 << (pin * 2));
+ tmp |= (ocr << (pin * 2));
+ writel(tmp, &regs->port[port].ocr1);
+
+ writel(readl(&regs->port[port].iconfa1) & ~(3 << (pin * 2)),
+ &regs->port[port].iconfa1);
+ writel(readl(&regs->port[port].iconfa1) | aout << (pin * 2),
+ &regs->port[port].iconfa1);
+ writel(readl(&regs->port[port].iconfb1) & ~(3 << (pin * 2)),
+ &regs->port[port].iconfb1);
+ writel(readl(&regs->port[port].iconfb1) | bout << (pin * 2),
+ &regs->port[port].iconfb1);
+ } else {
+ pin -= 16;
+
+ tmp = readl(&regs->port[port].ocr2);
+ tmp &= ~(3 << (pin * 2));
+ tmp |= (ocr << (pin * 2));
+ writel(tmp, &regs->port[port].ocr2);
+
+ writel(readl(&regs->port[port].iconfa2) & ~(3 << (pin * 2)),
+ &regs->port[port].iconfa2);
+ writel(readl(&regs->port[port].iconfa2) | aout << (pin * 2),
+ &regs->port[port].iconfa2);
+ writel(readl(&regs->port[port].iconfb2) & ~(3 << (pin * 2)),
+ &regs->port[port].iconfb2);
+ writel(readl(&regs->port[port].iconfb2) | bout << (pin * 2),
+ &regs->port[port].iconfb2);
+ }
+}
+
+#ifdef CONFIG_MXC_UART
+void mx27_uart1_init_pins(void)
+{
+ int i;
+ unsigned int mode[] = {
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(mode); i++)
+ imx_gpio_mode(mode[i]);
+
+}
+#endif /* CONFIG_MXC_UART */
+
+#ifdef CONFIG_FEC_MXC
+void mx27_fec_init_pins(void)
+{
+ int i;
+ unsigned int mode[] = {
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC | GPIO_PUEN,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_CLR,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(mode); i++)
+ imx_gpio_mode(mode[i]);
+}
+
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+ int i;
+ struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
+ struct fuse_bank *bank = &iim->bank[0];
+ struct fuse_bank0_regs *fuse =
+ (struct fuse_bank0_regs *)bank->fuse_regs;
+
+ for (i = 0; i < 6; i++)
+ mac[6 - 1 - i] = readl(&fuse->mac_addr[i]) & 0xff;
+}
+#endif /* CONFIG_FEC_MXC */
+
+#ifdef CONFIG_MMC_MXC
+void mx27_sd1_init_pins(void)
+{
+ int i;
+ unsigned int mode[] = {
+ PE18_PF_SD1_D0,
+ PE19_PF_SD1_D1,
+ PE20_PF_SD1_D2,
+ PE21_PF_SD1_D3,
+ PE22_PF_SD1_CMD,
+ PE23_PF_SD1_CLK,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(mode); i++)
+ imx_gpio_mode(mode[i]);
+
+}
+
+void mx27_sd2_init_pins(void)
+{
+ int i;
+ unsigned int mode[] = {
+ PB4_PF_SD2_D0,
+ PB5_PF_SD2_D1,
+ PB6_PF_SD2_D2,
+ PB7_PF_SD2_D3,
+ PB8_PF_SD2_CMD,
+ PB9_PF_SD2_CLK,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(mode); i++)
+ imx_gpio_mode(mode[i]);
+
+}
+#endif /* CONFIG_MMC_MXC */
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/relocate.S b/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/relocate.S
new file mode 100644
index 000000000..5dfa272be
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/relocate.S
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * relocate - i.MX27-specific vector relocation
+ *
+ * Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+
+/*
+ * The i.MX27 SoC is very specific with respect to exceptions: it
+ * does not provide RAM at the high vectors address (0xFFFF0000),
+ * thus only the low address (0x00000000) is useable; but that is
+ * in ROM. Therefore, vectors cannot be changed at all.
+ *
+ * However, these ROM-based vectors actually just perform indirect
+ * calls through pointers located in RAM at SoC-specific addresses,
+ * as follows:
+ *
+ * Offset Exception Use by ROM code
+ * 0x00000000 reset indirect branch to [0x00000014]
+ * 0x00000004 undefined instruction indirect branch to [0xfffffef0]
+ * 0x00000008 software interrupt indirect branch to [0xfffffef4]
+ * 0x0000000c prefetch abort indirect branch to [0xfffffef8]
+ * 0x00000010 data abort indirect branch to [0xfffffefc]
+ * 0x00000014 (reserved in ARMv5) vector to ROM reset: 0xc0000000
+ * 0x00000018 IRQ indirect branch to [0xffffff00]
+ * 0x0000001c FIQ indirect branch to [0xffffff04]
+ *
+ * In order to initialize exceptions on i.MX27, we must copy U-Boot's
+ * indirect (not exception!) vector table into 0xfffffef0..0xffffff04
+ * taking care not to copy vectors number 5 (reserved exception).
+ */
+
+ .section .text.relocate_vectors,"ax",%progbits
+
+ENTRY(relocate_vectors)
+
+ ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
+ ldr r1, =32 /* size of vector table */
+ add r0, r0, r1 /* skip to indirect table */
+ ldr r1, =0xFFFFFEF0 /* i.MX27 indirect table */
+ ldmia r0!, {r2-r8} /* load indirect vectors 1..7 */
+ stmia r1!, {r2-r5, r7,r8} /* write all but vector 5 */
+
+ bx lr
+
+ENDPROC(relocate_vectors)
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/reset.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/reset.c
new file mode 100644
index 000000000..496fb3081
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/reset.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2009
+ * Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+
+/*
+ * Reset the cpu by setting up the watchdog timer and let it time out
+ */
+void reset_cpu(void)
+{
+ struct wdog_regs *regs = (struct wdog_regs *)IMX_WDT_BASE;
+ /* Disable watchdog and set Time-Out field to 0 */
+ writew(0x0000, &regs->wcr);
+
+ /* Write Service Sequence */
+ writew(0x5555, &regs->wsr);
+ writew(0xAAAA, &regs->wsr);
+
+ /* Enable watchdog */
+ writew(WCR_WDE, &regs->wcr);
+
+ while (1);
+ /*NOTREACHED*/
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/timer.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/timer.c
new file mode 100644
index 000000000..4fd6a8059
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mx27/timer.c
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2009
+ * Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com>
+ */
+
+#include <common.h>
+#include <div64.h>
+#include <init.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/ptrace.h>
+#include <linux/delay.h>
+
+/* General purpose timers bitfields */
+#define GPTCR_SWR (1 << 15) /* Software reset */
+#define GPTCR_FRR (1 << 8) /* Freerun / restart */
+#define GPTCR_CLKSOURCE_32 (4 << 1) /* Clock source */
+#define GPTCR_TEN 1 /* Timer enable */
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define timestamp (gd->arch.tbl)
+#define lastinc (gd->arch.lastinc)
+
+/*
+ * "time" is measured in 1 / CONFIG_SYS_HZ seconds,
+ * "tick" is internal timer period
+ */
+#ifdef CONFIG_MX27_TIMER_HIGH_PRECISION
+/* ~0.4% error - measured with stop-watch on 100s boot-delay */
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, CONFIG_MX27_CLK32);
+ return tick;
+}
+
+static inline unsigned long long time_to_tick(unsigned long long time)
+{
+ time *= CONFIG_MX27_CLK32;
+ do_div(time, CONFIG_SYS_HZ);
+ return time;
+}
+
+static inline unsigned long long us_to_tick(unsigned long long us)
+{
+ us = us * CONFIG_MX27_CLK32 + 999999;
+ do_div(us, 1000000);
+ return us;
+}
+#else
+/* ~2% error */
+#define TICK_PER_TIME ((CONFIG_MX27_CLK32 + CONFIG_SYS_HZ / 2) / \
+ CONFIG_SYS_HZ)
+#define US_PER_TICK (1000000 / CONFIG_MX27_CLK32)
+
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ do_div(tick, TICK_PER_TIME);
+ return tick;
+}
+
+static inline unsigned long long time_to_tick(unsigned long long time)
+{
+ return time * TICK_PER_TIME;
+}
+
+static inline unsigned long long us_to_tick(unsigned long long us)
+{
+ us += US_PER_TICK - 1;
+ do_div(us, US_PER_TICK);
+ return us;
+}
+#endif
+
+/* nothing really to do with interrupts, just starts up a counter. */
+/* The 32768Hz 32-bit timer overruns in 131072 seconds */
+int timer_init(void)
+{
+ int i;
+ struct gpt_regs *regs = (struct gpt_regs *)IMX_TIM1_BASE;
+ struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
+
+ /* setup GP Timer 1 */
+ writel(GPTCR_SWR, &regs->gpt_tctl);
+
+ writel(readl(&pll->pccr0) | PCCR0_GPT1_EN, &pll->pccr0);
+ writel(readl(&pll->pccr1) | PCCR1_PERCLK1_EN, &pll->pccr1);
+
+ for (i = 0; i < 100; i++)
+ writel(0, &regs->gpt_tctl); /* We have no udelay by now */
+ writel(0, &regs->gpt_tprer); /* 32Khz */
+ /* Freerun Mode, PERCLK1 input */
+ writel(readl(&regs->gpt_tctl) | GPTCR_CLKSOURCE_32 | GPTCR_FRR,
+ &regs->gpt_tctl);
+ writel(readl(&regs->gpt_tctl) | GPTCR_TEN, &regs->gpt_tctl);
+
+ return 0;
+}
+
+unsigned long long get_ticks(void)
+{
+ struct gpt_regs *regs = (struct gpt_regs *)IMX_TIM1_BASE;
+ ulong now = readl(&regs->gpt_tcn); /* current tick value */
+
+ if (now >= lastinc) {
+ /*
+ * normal mode (non roll)
+ * move stamp forward with absolut diff ticks
+ */
+ timestamp += (now - lastinc);
+ } else {
+ /* we have rollover of incrementer */
+ timestamp += (0xFFFFFFFF - lastinc) + now;
+ }
+ lastinc = now;
+ return timestamp;
+}
+
+static ulong get_timer_masked(void)
+{
+ /*
+ * get_ticks() returns a long long (64 bit), it wraps in
+ * 2^64 / CONFIG_MX27_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
+ * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
+ * 5 * 10^6 days - long enough.
+ */
+ return tick_to_time(get_ticks());
+}
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+/* delay x useconds AND preserve advance timstamp value */
+void __udelay(unsigned long usec)
+{
+ unsigned long long tmp;
+ ulong tmo;
+
+ tmo = us_to_tick(usec);
+ tmp = get_ticks() + tmo; /* get current timestamp */
+
+ while (get_ticks() < tmp) /* loop till event */
+ /*NOP*/;
+}
+
+ulong get_tbclk(void)
+{
+ return CONFIG_MX27_CLK32;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/Makefile b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/Makefile
new file mode 100644
index 000000000..f60e61e43
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/Makefile
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+extra-$(CONFIG_SPL_BUILD) := start.o
+
+obj-y = clock.o mxs.o iomux.o timer.o
+
+ifdef CONFIG_SPL_BUILD
+obj-y += spl_boot.o spl_lradc_init.o spl_mem_init.o spl_power_init.o
+endif
+
+# Specify the target for use in elftosb call
+MKIMAGE_TARGET-$(CONFIG_MX23) = mxsimage$(CONFIG_SPL_FRAMEWORK:%=-spl).mx23.cfg
+MKIMAGE_TARGET-$(CONFIG_MX28) = mxsimage$(CONFIG_SPL_FRAMEWORK:%=-spl).mx28.cfg
+
+# Generate HAB-capable IVT
+#
+# Note on computing the post-IVT size field value for the U-Boot binary.
+# The value is the result of adding the following:
+# -> The size of U-Boot binary aligned to 64B (u-boot.bin)
+# -> The size of IVT block aligned to 64B (u-boot.ivt)
+# -> The size of U-Boot signature (u-boot.sig), 3904 B
+# -> The 64B hole in front of U-Boot binary for 'struct mxs_spl_data' passing
+#
+quiet_cmd_mkivt_mxs = MXSIVT $@
+cmd_mkivt_mxs = \
+ sz=`expr \`stat -c "%s" $^\` + 64 + 3904 + 128` ; \
+ echo -n "0x402000d1 $2 0 0 0 $3 $4 0 $$sz 0 0 0 0 0 0 0" | \
+ tr -s " " | xargs -d " " -i printf "%08x\n" "{}" | rev | \
+ sed "s/\(.\)\(.\)/\\\\\\\\x\2\1\n/g" | xargs -i printf "{}" >$@
+
+# Align binary to 64B
+quiet_cmd_mkalign_mxs = MXSALGN $@
+cmd_mkalign_mxs = \
+ dd if=$^ of=$@ ibs=64 conv=sync 2>/dev/null && \
+ mv $@ $^
+
+# Assemble the CSF file
+quiet_cmd_mkcsfreq_mxs = MXSCSFR $@
+cmd_mkcsfreq_mxs = \
+ ivt=$(word 1,$^) ; \
+ bin=$(word 2,$^) ; \
+ csf=$(word 3,$^) ; \
+ sed "s@VENDOR@$(VENDOR)@g;s@BOARD@$(BOARD)@g" "$$csf" | \
+ sed '/^\#\#Blocks/ d' > $@ ; \
+ echo " Blocks = $2 0x0 `stat -c '%s' $$bin` \"$$bin\" , \\" >> $@ ; \
+ echo " $3 0x0 0x40 \"$$ivt\"" >> $@
+
+# Sign files
+quiet_cmd_mkcst_mxs = MXSCST $@
+cmd_mkcst_mxs = cst -o $@ < $^ \
+ $(if $(KBUILD_VERBOSE:1=), >/dev/null)
+
+spl/u-boot-spl.ivt: spl/u-boot-spl.bin
+ $(call if_changed,mkalign_mxs)
+ $(call if_changed,mkivt_mxs,$(CONFIG_SPL_TEXT_BASE),\
+ 0x00008000,0x00008040)
+
+u-boot.ivt: u-boot.bin
+ $(call if_changed,mkalign_mxs)
+ $(call if_changed,mkivt_mxs,$(CONFIG_SYS_TEXT_BASE),\
+ 0x40001000,0x40001040)
+
+spl/u-boot-spl.csf: spl/u-boot-spl.ivt spl/u-boot-spl.bin board/$(VENDOR)/$(BOARD)/sign/u-boot-spl.csf
+ $(call if_changed,mkcsfreq_mxs,$(CONFIG_SPL_TEXT_BASE),0x8000)
+
+u-boot.csf: u-boot.ivt u-boot.bin board/$(VENDOR)/$(BOARD)/sign/u-boot.csf
+ $(call if_changed,mkcsfreq_mxs,$(CONFIG_SYS_TEXT_BASE),0x40001000)
+
+%.sig: %.csf
+ $(call if_changed,mkcst_mxs)
+
+MKIMAGEFLAGS_u-boot.sb = -n $< -T mxsimage
+u-boot.sb: $(src)/$(MKIMAGE_TARGET-y) u-boot.bin spl/u-boot-spl.bin FORCE
+ $(call if_changed,mkimage)
+
+MKIMAGEFLAGS_u-boot-signed.sb = -n $< -T mxsimage
+u-boot-signed.sb: $(src)/mxsimage-signed.cfg u-boot.ivt u-boot.sig spl/u-boot-spl.ivt spl/u-boot-spl.sig FORCE
+ $(call if_changed,mkimage)
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/clock.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/clock.c
new file mode 100644
index 000000000..4e1cf3a1e
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/clock.c
@@ -0,0 +1,436 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Freescale i.MX23/i.MX28 clock setup code
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * Based on code from LTIB:
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <log.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+
+/*
+ * The PLL frequency is 480MHz and XTAL frequency is 24MHz
+ * iMX23: datasheet section 4.2
+ * iMX28: datasheet section 10.2
+ */
+#define PLL_FREQ_KHZ 480000
+#define PLL_FREQ_COEF 18
+#define XTAL_FREQ_KHZ 24000
+
+#define PLL_FREQ_MHZ (PLL_FREQ_KHZ / 1000)
+#define XTAL_FREQ_MHZ (XTAL_FREQ_KHZ / 1000)
+
+#if defined(CONFIG_MX23)
+#define MXC_SSPCLK_MAX MXC_SSPCLK0
+#elif defined(CONFIG_MX28)
+#define MXC_SSPCLK_MAX MXC_SSPCLK3
+#endif
+
+static uint32_t mxs_get_pclk(void)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ uint32_t clkctrl, clkseq, div;
+ uint8_t clkfrac, frac;
+
+ clkctrl = readl(&clkctrl_regs->hw_clkctrl_cpu);
+
+ /* No support of fractional divider calculation */
+ if (clkctrl &
+ (CLKCTRL_CPU_DIV_XTAL_FRAC_EN | CLKCTRL_CPU_DIV_CPU_FRAC_EN)) {
+ return 0;
+ }
+
+ clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq);
+
+ /* XTAL Path */
+ if (clkseq & CLKCTRL_CLKSEQ_BYPASS_CPU) {
+ div = (clkctrl & CLKCTRL_CPU_DIV_XTAL_MASK) >>
+ CLKCTRL_CPU_DIV_XTAL_OFFSET;
+ return XTAL_FREQ_MHZ / div;
+ }
+
+ /* REF Path */
+ clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]);
+ frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK;
+ div = clkctrl & CLKCTRL_CPU_DIV_CPU_MASK;
+ return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
+}
+
+static uint32_t mxs_get_hclk(void)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ uint32_t div;
+ uint32_t clkctrl;
+
+ clkctrl = readl(&clkctrl_regs->hw_clkctrl_hbus);
+
+ /* No support of fractional divider calculation */
+ if (clkctrl & CLKCTRL_HBUS_DIV_FRAC_EN)
+ return 0;
+
+ div = clkctrl & CLKCTRL_HBUS_DIV_MASK;
+ return mxs_get_pclk() / div;
+}
+
+static uint32_t mxs_get_emiclk(void)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ uint32_t clkctrl, clkseq, div;
+ uint8_t clkfrac, frac;
+
+ clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq);
+ clkctrl = readl(&clkctrl_regs->hw_clkctrl_emi);
+
+ /* XTAL Path */
+ if (clkseq & CLKCTRL_CLKSEQ_BYPASS_EMI) {
+ div = (clkctrl & CLKCTRL_EMI_DIV_XTAL_MASK) >>
+ CLKCTRL_EMI_DIV_XTAL_OFFSET;
+ return XTAL_FREQ_MHZ / div;
+ }
+
+ /* REF Path */
+ clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_EMI]);
+ frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK;
+ div = clkctrl & CLKCTRL_EMI_DIV_EMI_MASK;
+ return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
+}
+
+static uint32_t mxs_get_gpmiclk(void)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+#if defined(CONFIG_MX23)
+ uint8_t *reg =
+ &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU];
+#elif defined(CONFIG_MX28)
+ uint8_t *reg =
+ &clkctrl_regs->hw_clkctrl_frac1[CLKCTRL_FRAC1_GPMI];
+#endif
+ uint32_t clkctrl, clkseq, div;
+ uint8_t clkfrac, frac;
+
+ clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq);
+ clkctrl = readl(&clkctrl_regs->hw_clkctrl_gpmi);
+
+ /* XTAL Path */
+ if (clkseq & CLKCTRL_CLKSEQ_BYPASS_GPMI) {
+ div = clkctrl & CLKCTRL_GPMI_DIV_MASK;
+ return XTAL_FREQ_MHZ / div;
+ }
+
+ /* REF Path */
+ clkfrac = readb(reg);
+ frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK;
+ div = clkctrl & CLKCTRL_GPMI_DIV_MASK;
+ return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
+}
+
+/*
+ * Set IO clock frequency, in kHz
+ */
+void mxs_set_ioclk(enum mxs_ioclock io, uint32_t freq)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ uint32_t div;
+ int io_reg;
+
+ if (freq == 0)
+ return;
+
+ if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1))
+ return;
+
+ div = (PLL_FREQ_KHZ * PLL_FREQ_COEF) / freq;
+
+ if (div < 18)
+ div = 18;
+
+ if (div > 35)
+ div = 35;
+
+ io_reg = CLKCTRL_FRAC0_IO0 - io; /* Register order is reversed */
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac0_set[io_reg]);
+ writeb(CLKCTRL_FRAC_CLKGATE | (div & CLKCTRL_FRAC_FRAC_MASK),
+ &clkctrl_regs->hw_clkctrl_frac0[io_reg]);
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac0_clr[io_reg]);
+}
+
+/*
+ * Get IO clock, returns IO clock in kHz
+ */
+static uint32_t mxs_get_ioclk(enum mxs_ioclock io)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ uint8_t ret;
+ int io_reg;
+
+ if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1))
+ return 0;
+
+ io_reg = CLKCTRL_FRAC0_IO0 - io; /* Register order is reversed */
+
+ ret = readb(&clkctrl_regs->hw_clkctrl_frac0[io_reg]) &
+ CLKCTRL_FRAC_FRAC_MASK;
+
+ return (PLL_FREQ_KHZ * PLL_FREQ_COEF) / ret;
+}
+
+/*
+ * Configure SSP clock frequency, in kHz
+ */
+void mxs_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ uint32_t clk, clkreg;
+
+ if (ssp > MXC_SSPCLK_MAX)
+ return;
+
+ clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) +
+ (ssp * sizeof(struct mxs_register_32));
+
+ clrbits_le32(clkreg, CLKCTRL_SSP_CLKGATE);
+ while (readl(clkreg) & CLKCTRL_SSP_CLKGATE)
+ ;
+
+ if (xtal)
+ clk = XTAL_FREQ_KHZ;
+ else
+ clk = mxs_get_ioclk(ssp >> 1);
+
+ if (freq > clk)
+ return;
+
+ /* Calculate the divider and cap it if necessary */
+ clk /= freq;
+ if (clk > CLKCTRL_SSP_DIV_MASK)
+ clk = CLKCTRL_SSP_DIV_MASK;
+
+ clrsetbits_le32(clkreg, CLKCTRL_SSP_DIV_MASK, clk);
+ while (readl(clkreg) & CLKCTRL_SSP_BUSY)
+ ;
+
+ if (xtal)
+ writel(CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp,
+ &clkctrl_regs->hw_clkctrl_clkseq_set);
+ else
+ writel(CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp,
+ &clkctrl_regs->hw_clkctrl_clkseq_clr);
+}
+
+/*
+ * Return SSP frequency, in kHz
+ */
+static uint32_t mxs_get_sspclk(enum mxs_sspclock ssp)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ uint32_t clkreg;
+ uint32_t clk, tmp;
+
+ if (ssp > MXC_SSPCLK_MAX)
+ return 0;
+
+ tmp = readl(&clkctrl_regs->hw_clkctrl_clkseq);
+ if (tmp & (CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp))
+ return XTAL_FREQ_KHZ;
+
+ clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) +
+ (ssp * sizeof(struct mxs_register_32));
+
+ tmp = readl(clkreg) & CLKCTRL_SSP_DIV_MASK;
+
+ if (tmp == 0)
+ return 0;
+
+ clk = mxs_get_ioclk(ssp >> 1);
+
+ return clk / tmp;
+}
+
+/*
+ * Set SSP/MMC bus frequency, in kHz)
+ */
+void mxs_set_ssp_busclock(unsigned int bus, uint32_t freq)
+{
+ struct mxs_ssp_regs *ssp_regs;
+ const enum mxs_sspclock clk = mxs_ssp_clock_by_bus(bus);
+ const uint32_t sspclk = mxs_get_sspclk(clk);
+ uint32_t reg;
+ uint32_t divide, rate, tgtclk;
+
+ ssp_regs = mxs_ssp_regs_by_bus(bus);
+
+ /*
+ * SSP bit rate = SSPCLK / (CLOCK_DIVIDE * (1 + CLOCK_RATE)),
+ * CLOCK_DIVIDE has to be an even value from 2 to 254, and
+ * CLOCK_RATE could be any integer from 0 to 255.
+ */
+ for (divide = 2; divide < 254; divide += 2) {
+ rate = sspclk / freq / divide;
+ if (rate <= 256)
+ break;
+ }
+
+ tgtclk = sspclk / divide / rate;
+ while (tgtclk > freq) {
+ rate++;
+ tgtclk = sspclk / divide / rate;
+ }
+ if (rate > 256)
+ rate = 256;
+
+ /* Always set timeout the maximum */
+ reg = SSP_TIMING_TIMEOUT_MASK |
+ (divide << SSP_TIMING_CLOCK_DIVIDE_OFFSET) |
+ ((rate - 1) << SSP_TIMING_CLOCK_RATE_OFFSET);
+ writel(reg, &ssp_regs->hw_ssp_timing);
+
+ debug("SPI%d: Set freq rate to %d KHz (requested %d KHz)\n",
+ bus, tgtclk, freq);
+}
+
+void mxs_set_lcdclk(uint32_t __maybe_unused lcd_base, uint32_t freq)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ uint32_t fp, x, k_rest, k_best, x_best, tk;
+ int32_t k_best_l = 999, k_best_t = 0, x_best_l = 0xff, x_best_t = 0xff;
+
+ if (freq == 0)
+ return;
+
+#if defined(CONFIG_MX23)
+ writel(CLKCTRL_CLKSEQ_BYPASS_PIX, &clkctrl_regs->hw_clkctrl_clkseq_clr);
+#elif defined(CONFIG_MX28)
+ writel(CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF, &clkctrl_regs->hw_clkctrl_clkseq_clr);
+#endif
+
+ /*
+ * / 18 \ 1 1
+ * freq kHz = | 480000000 Hz * -- | * --- * ------
+ * \ x / k 1000
+ *
+ * 480000000 Hz 18
+ * ------------ * --
+ * freq kHz x
+ * k = -------------------
+ * 1000
+ */
+
+ fp = ((PLL_FREQ_KHZ * 1000) / freq) * 18;
+
+ for (x = 18; x <= 35; x++) {
+ tk = fp / x;
+ if ((tk / 1000 == 0) || (tk / 1000 > 255))
+ continue;
+
+ k_rest = tk % 1000;
+
+ if (k_rest < (k_best_l % 1000)) {
+ k_best_l = tk;
+ x_best_l = x;
+ }
+
+ if (k_rest > (k_best_t % 1000)) {
+ k_best_t = tk;
+ x_best_t = x;
+ }
+ }
+
+ if (1000 - (k_best_t % 1000) > (k_best_l % 1000)) {
+ k_best = k_best_l;
+ x_best = x_best_l;
+ } else {
+ k_best = k_best_t;
+ x_best = x_best_t;
+ }
+
+ k_best /= 1000;
+
+#if defined(CONFIG_MX23)
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_PIX]);
+ writeb(CLKCTRL_FRAC_CLKGATE | (x_best & CLKCTRL_FRAC_FRAC_MASK),
+ &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_PIX]);
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_PIX]);
+
+ writel(CLKCTRL_PIX_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_pix_set);
+ clrsetbits_le32(&clkctrl_regs->hw_clkctrl_pix,
+ CLKCTRL_PIX_DIV_MASK | CLKCTRL_PIX_CLKGATE,
+ k_best << CLKCTRL_PIX_DIV_OFFSET);
+
+ while (readl(&clkctrl_regs->hw_clkctrl_pix) & CLKCTRL_PIX_BUSY)
+ ;
+#elif defined(CONFIG_MX28)
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac1_set[CLKCTRL_FRAC1_PIX]);
+ writeb(CLKCTRL_FRAC_CLKGATE | (x_best & CLKCTRL_FRAC_FRAC_MASK),
+ &clkctrl_regs->hw_clkctrl_frac1[CLKCTRL_FRAC1_PIX]);
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac1_clr[CLKCTRL_FRAC1_PIX]);
+
+ writel(CLKCTRL_DIS_LCDIF_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_lcdif_set);
+ clrsetbits_le32(&clkctrl_regs->hw_clkctrl_lcdif,
+ CLKCTRL_DIS_LCDIF_DIV_MASK | CLKCTRL_DIS_LCDIF_CLKGATE,
+ k_best << CLKCTRL_DIS_LCDIF_DIV_OFFSET);
+
+ while (readl(&clkctrl_regs->hw_clkctrl_lcdif) & CLKCTRL_DIS_LCDIF_BUSY)
+ ;
+#endif
+}
+
+uint32_t mxc_get_clock(enum mxc_clock clk)
+{
+ switch (clk) {
+ case MXC_ARM_CLK:
+ return mxs_get_pclk() * 1000000;
+ case MXC_GPMI_CLK:
+ return mxs_get_gpmiclk() * 1000000;
+ case MXC_AHB_CLK:
+ case MXC_IPG_CLK:
+ return mxs_get_hclk() * 1000000;
+ case MXC_EMI_CLK:
+ return mxs_get_emiclk();
+ case MXC_IO0_CLK:
+ return mxs_get_ioclk(MXC_IOCLK0);
+ case MXC_IO1_CLK:
+ return mxs_get_ioclk(MXC_IOCLK1);
+ case MXC_XTAL_CLK:
+ return XTAL_FREQ_KHZ * 1000;
+ case MXC_SSP0_CLK:
+ return mxs_get_sspclk(MXC_SSPCLK0);
+#ifdef CONFIG_MX28
+ case MXC_SSP1_CLK:
+ return mxs_get_sspclk(MXC_SSPCLK1);
+ case MXC_SSP2_CLK:
+ return mxs_get_sspclk(MXC_SSPCLK2);
+ case MXC_SSP3_CLK:
+ return mxs_get_sspclk(MXC_SSPCLK3);
+#endif
+ }
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/iomux.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/iomux.c
new file mode 100644
index 000000000..381264b8a
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/iomux.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ * <armlinux@phytec.de>
+ */
+
+#include <common.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/imx-regs.h>
+
+#if defined(CONFIG_MX23)
+#define DRIVE_OFFSET 0x200
+#define PULL_OFFSET 0x400
+#elif defined(CONFIG_MX28)
+#define DRIVE_OFFSET 0x300
+#define PULL_OFFSET 0x600
+#else
+#error "Please select CONFIG_MX23 or CONFIG_MX28"
+#endif
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t pad)
+{
+ u32 reg, ofs, bp, bm;
+ void *iomux_base = (void *)MXS_PINCTRL_BASE;
+ struct mxs_register_32 *mxs_reg;
+
+ /* muxsel */
+ ofs = 0x100;
+ ofs += PAD_BANK(pad) * 0x20 + PAD_PIN(pad) / 16 * 0x10;
+ bp = PAD_PIN(pad) % 16 * 2;
+ bm = 0x3 << bp;
+ reg = readl(iomux_base + ofs);
+ reg &= ~bm;
+ reg |= PAD_MUXSEL(pad) << bp;
+ writel(reg, iomux_base + ofs);
+
+ /* drive */
+ ofs = DRIVE_OFFSET;
+ ofs += PAD_BANK(pad) * 0x40 + PAD_PIN(pad) / 8 * 0x10;
+ /* mA */
+ if (PAD_MA_VALID(pad)) {
+ bp = PAD_PIN(pad) % 8 * 4;
+ bm = 0x3 << bp;
+ reg = readl(iomux_base + ofs);
+ reg &= ~bm;
+ reg |= PAD_MA(pad) << bp;
+ writel(reg, iomux_base + ofs);
+ }
+ /* vol */
+ if (PAD_VOL_VALID(pad)) {
+ bp = PAD_PIN(pad) % 8 * 4 + 2;
+ mxs_reg = (struct mxs_register_32 *)(iomux_base + ofs);
+ if (PAD_VOL(pad))
+ writel(1 << bp, &mxs_reg->reg_set);
+ else
+ writel(1 << bp, &mxs_reg->reg_clr);
+ }
+
+ /* pull */
+ if (PAD_PULL_VALID(pad)) {
+ ofs = PULL_OFFSET;
+ ofs += PAD_BANK(pad) * 0x10;
+ bp = PAD_PIN(pad);
+ mxs_reg = (struct mxs_register_32 *)(iomux_base + ofs);
+ if (PAD_PULL(pad))
+ writel(1 << bp, &mxs_reg->reg_set);
+ else
+ writel(1 << bp, &mxs_reg->reg_clr);
+ }
+
+ return 0;
+}
+
+int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
+{
+ const iomux_cfg_t *p = pad_list;
+ int i;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ ret = mxs_iomux_setup_pad(*p);
+ if (ret)
+ return ret;
+ p++;
+ }
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxs.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxs.c
new file mode 100644
index 000000000..4d21e3df7
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxs.c
@@ -0,0 +1,295 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Freescale i.MX23/i.MX28 common code
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * Based on code from LTIB:
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <hang.h>
+#include <init.h>
+#include <net.h>
+#include <asm/global_data.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/mach-imx/dma.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/sections.h>
+#include <linux/compiler.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Lowlevel init isn't used on i.MX28, so just have a dummy here */
+__weak void lowlevel_init(void) {}
+
+void reset_cpu(void) __attribute__((noreturn));
+
+void reset_cpu(void)
+{
+ struct mxs_rtc_regs *rtc_regs =
+ (struct mxs_rtc_regs *)MXS_RTC_BASE;
+ struct mxs_lcdif_regs *lcdif_regs =
+ (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
+
+ /*
+ * Shut down the LCD controller as it interferes with BootROM boot mode
+ * pads sampling.
+ */
+ writel(LCDIF_CTRL_RUN, &lcdif_regs->hw_lcdif_ctrl_clr);
+
+ /* Wait 1 uS before doing the actual watchdog reset */
+ writel(1, &rtc_regs->hw_rtc_watchdog);
+ writel(RTC_CTRL_WATCHDOGEN, &rtc_regs->hw_rtc_ctrl_set);
+
+ /* Endless loop, reset will exit from here */
+ for (;;)
+ ;
+}
+
+/*
+ * This function will craft a jumptable at 0x0 which will redirect interrupt
+ * vectoring to proper location of U-Boot in RAM.
+ *
+ * The structure of the jumptable will be as follows:
+ * ldr pc, [pc, #0x18] ..... for each vector, thus repeated 8 times
+ * <destination address> ... for each previous ldr, thus also repeated 8 times
+ *
+ * The "ldr pc, [pc, #0x18]" instruction above loads address from memory at
+ * offset 0x18 from current value of PC register. Note that PC is already
+ * incremented by 4 when computing the offset, so the effective offset is
+ * actually 0x20, this the associated <destination address>. Loading the PC
+ * register with an address performs a jump to that address.
+ */
+void mx28_fixup_vt(uint32_t start_addr)
+{
+ /* ldr pc, [pc, #0x18] */
+ const uint32_t ldr_pc = 0xe59ff018;
+ /* Jumptable location is 0x0 */
+ uint32_t *vt = (uint32_t *)0x0;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ /* cppcheck-suppress nullPointer */
+ vt[i] = ldr_pc;
+ /* cppcheck-suppress nullPointer */
+ vt[i + 8] = start_addr + (4 * i);
+ }
+}
+
+#ifdef CONFIG_ARCH_MISC_INIT
+int arch_misc_init(void)
+{
+ mx28_fixup_vt(gd->relocaddr);
+ return 0;
+}
+#endif
+
+int arch_cpu_init(void)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ mx28_fixup_vt((uint32_t)&_start);
+
+ /*
+ * Enable NAND clock
+ */
+ /* Set bypass bit */
+ writel(CLKCTRL_CLKSEQ_BYPASS_GPMI,
+ &clkctrl_regs->hw_clkctrl_clkseq_set);
+
+ /* Set GPMI clock to ref_xtal / 1 */
+ clrbits_le32(&clkctrl_regs->hw_clkctrl_gpmi, CLKCTRL_GPMI_CLKGATE);
+ while (readl(&clkctrl_regs->hw_clkctrl_gpmi) & CLKCTRL_GPMI_CLKGATE)
+ ;
+ clrsetbits_le32(&clkctrl_regs->hw_clkctrl_gpmi,
+ CLKCTRL_GPMI_DIV_MASK, 1);
+
+ udelay(1000);
+
+ /*
+ * Configure GPIO unit
+ */
+ mxs_gpio_init();
+
+#ifdef CONFIG_APBH_DMA
+ /* Start APBH DMA */
+ mxs_dma_init();
+#endif
+
+ return 0;
+}
+
+u32 get_cpu_rev(void)
+{
+ struct mxs_digctl_regs *digctl_regs =
+ (struct mxs_digctl_regs *)MXS_DIGCTL_BASE;
+ uint8_t rev = readl(&digctl_regs->hw_digctl_chipid) & 0x000000FF;
+
+ switch (readl(&digctl_regs->hw_digctl_chipid) & HW_DIGCTL_CHIPID_MASK) {
+ case HW_DIGCTL_CHIPID_MX23:
+ switch (rev) {
+ case 0x0:
+ case 0x1:
+ case 0x2:
+ case 0x3:
+ case 0x4:
+ return (MXC_CPU_MX23 << 12) | (rev + 0x10);
+ default:
+ return 0;
+ }
+ case HW_DIGCTL_CHIPID_MX28:
+ switch (rev) {
+ case 0x1:
+ return (MXC_CPU_MX28 << 12) | 0x12;
+ default:
+ return 0;
+ }
+ default:
+ return 0;
+ }
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+const char *get_imx_type(u32 imxtype)
+{
+ switch (imxtype) {
+ case MXC_CPU_MX23:
+ return "23";
+ case MXC_CPU_MX28:
+ return "28";
+ default:
+ return "??";
+ }
+}
+
+int print_cpuinfo(void)
+{
+ u32 cpurev;
+ struct mxs_spl_data *data = MXS_SPL_DATA;
+
+ cpurev = get_cpu_rev();
+ printf("CPU: Freescale i.MX%s rev%d.%d at %d MHz\n",
+ get_imx_type((cpurev & 0xFF000) >> 12),
+ (cpurev & 0x000F0) >> 4,
+ (cpurev & 0x0000F) >> 0,
+ mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ printf("BOOT: %s\n", mxs_boot_modes[data->boot_mode_idx].mode);
+ return 0;
+}
+#endif
+
+int do_mx28_showclocks(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ printf("CPU: %3d MHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ printf("BUS: %3d MHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000000);
+ printf("EMI: %3d MHz\n", mxc_get_clock(MXC_EMI_CLK));
+ printf("GPMI: %3d MHz\n", mxc_get_clock(MXC_GPMI_CLK) / 1000000);
+ return 0;
+}
+
+/*
+ * Initializes on-chip ethernet controllers.
+ */
+#if defined(CONFIG_MX28) && defined(CONFIG_CMD_NET)
+int cpu_eth_init(struct bd_info *bis)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ /* Turn on ENET clocks */
+ clrbits_le32(&clkctrl_regs->hw_clkctrl_enet,
+ CLKCTRL_ENET_SLEEP | CLKCTRL_ENET_DISABLE);
+
+ /* Set up ENET PLL for 50 MHz */
+ /* Power on ENET PLL */
+ writel(CLKCTRL_PLL2CTRL0_POWER,
+ &clkctrl_regs->hw_clkctrl_pll2ctrl0_set);
+
+ udelay(10);
+
+ /* Gate on ENET PLL */
+ writel(CLKCTRL_PLL2CTRL0_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_pll2ctrl0_clr);
+
+ /* Enable pad output */
+ setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
+
+ return 0;
+}
+#endif
+
+__weak void mx28_adjust_mac(int dev_id, unsigned char *mac)
+{
+ mac[0] = 0x00;
+ mac[1] = 0x04; /* Use FSL vendor MAC address by default */
+
+ if (dev_id == 1) /* Let MAC1 be MAC0 + 1 by default */
+ mac[5] += 1;
+}
+
+#ifdef CONFIG_MX28_FEC_MAC_IN_OCOTP
+
+#define MXS_OCOTP_MAX_TIMEOUT 1000000
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+ struct mxs_ocotp_regs *ocotp_regs =
+ (struct mxs_ocotp_regs *)MXS_OCOTP_BASE;
+ uint32_t data;
+
+ memset(mac, 0, 6);
+
+ writel(OCOTP_CTRL_RD_BANK_OPEN, &ocotp_regs->hw_ocotp_ctrl_set);
+
+ if (mxs_wait_mask_clr(&ocotp_regs->hw_ocotp_ctrl_reg, OCOTP_CTRL_BUSY,
+ MXS_OCOTP_MAX_TIMEOUT)) {
+ printf("MXS FEC: Can't get MAC from OCOTP\n");
+ return;
+ }
+
+ data = readl(&ocotp_regs->hw_ocotp_cust0);
+
+ mac[2] = (data >> 24) & 0xff;
+ mac[3] = (data >> 16) & 0xff;
+ mac[4] = (data >> 8) & 0xff;
+ mac[5] = data & 0xff;
+ mx28_adjust_mac(dev_id, mac);
+}
+#else
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+ memset(mac, 0, 6);
+}
+#endif
+
+int mxs_dram_init(void)
+{
+ struct mxs_spl_data *data = MXS_SPL_DATA;
+
+ if (data->mem_dram_size == 0) {
+ printf("MXS:\n"
+ "Error, the RAM size passed up from SPL is 0!\n");
+ hang();
+ }
+
+ gd->ram_size = data->mem_dram_size;
+ return 0;
+}
+
+U_BOOT_CMD(
+ clocks, CONFIG_SYS_MAXARGS, 1, do_mx28_showclocks,
+ "display clocks",
+ ""
+);
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxs_init.h b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxs_init.h
new file mode 100644
index 000000000..062deb779
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxs_init.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Freescale i.MX28 SPL functions
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ */
+
+#ifndef __M28_INIT_H__
+#define __M28_INIT_H__
+
+void early_delay(int delay);
+
+void mxs_power_init(void);
+
+#ifdef CONFIG_SPL_MXS_PSWITCH_WAIT
+void mxs_power_wait_pswitch(void);
+#else
+static inline void mxs_power_wait_pswitch(void) { }
+#endif
+
+void mxs_mem_init(void);
+uint32_t mxs_mem_get_size(void);
+
+void mxs_lradc_init(void);
+void mxs_lradc_enable_batt_measurement(void);
+
+#endif /* __M28_INIT_H__ */
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage-signed.cfg b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage-signed.cfg
new file mode 100644
index 000000000..83953daf2
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage-signed.cfg
@@ -0,0 +1,11 @@
+DISPLAYPROGRESS
+SECTION 0x0 BOOTABLE
+ TAG LAST
+ LOAD 0x1000 spl/u-boot-spl.bin
+ LOAD 0x8000 spl/u-boot-spl.ivt
+ LOAD 0x8040 spl/u-boot-spl.sig
+ CALL HAB 0x8000 0x0
+ LOAD 0x40002000 u-boot.bin
+ LOAD 0x40001000 u-boot.ivt
+ LOAD 0x40001040 u-boot.sig
+ CALL HAB 0x40001000 0x0
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage-spl.mx23.cfg b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage-spl.mx23.cfg
new file mode 100644
index 000000000..ab2183ed3
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage-spl.mx23.cfg
@@ -0,0 +1,5 @@
+DISPLAYPROGRESS
+SECTION 0x0 BOOTABLE
+ TAG LAST
+ LOAD 0x1000 spl/u-boot-spl.bin
+ CALL 0x1000 0x0
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage-spl.mx28.cfg b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage-spl.mx28.cfg
new file mode 100644
index 000000000..0d95064ff
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage-spl.mx28.cfg
@@ -0,0 +1,6 @@
+DISPLAYPROGRESS
+SECTION 0x0 BOOTABLE
+ TAG LAST
+ LOAD 0x1000 spl/u-boot-spl.bin
+ LOAD IVT 0x8000 0x1000
+ CALL HAB 0x8000 0x0
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg
new file mode 100644
index 000000000..e7028092a
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg
@@ -0,0 +1,7 @@
+DISPLAYPROGRESS
+SECTION 0x0 BOOTABLE
+ TAG LAST
+ LOAD 0x1000 spl/u-boot-spl.bin
+ CALL 0x1000 0x0
+ LOAD 0x40002000 u-boot.bin
+ CALL 0x40002000 0x0
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
new file mode 100644
index 000000000..3f7bf5992
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
@@ -0,0 +1,9 @@
+DISPLAYPROGRESS
+SECTION 0x0 BOOTABLE
+ TAG LAST
+ LOAD 0x1000 spl/u-boot-spl.bin
+ LOAD IVT 0x8000 0x1000
+ CALL HAB 0x8000 0x0
+ LOAD 0x40002000 u-boot.bin
+ LOAD IVT 0x8000 0x40002000
+ CALL HAB 0x8000 0x0
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
new file mode 100644
index 000000000..0a8985b90
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Freescale i.MX28 Boot setup
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ */
+
+#include <common.h>
+#include <config.h>
+#include <init.h>
+#include <log.h>
+#include <serial.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>
+#include <asm/sections.h>
+#include <linux/compiler.h>
+
+#include "mxs_init.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+static gd_t gdata __section(".data");
+#ifdef CONFIG_SPL_SERIAL_SUPPORT
+static struct bd_info bdata __section(".data");
+#endif
+
+/*
+ * This delay function is intended to be used only in early stage of boot, where
+ * clock are not set up yet.
+ */
+void early_delay(int delay)
+{
+ struct mxs_digctl_regs *digctl_regs =
+ (struct mxs_digctl_regs *)MXS_DIGCTL_BASE;
+
+ uint32_t st = readl(&digctl_regs->hw_digctl_microseconds);
+ while (readl(&digctl_regs->hw_digctl_microseconds) - st <= delay)
+ ;
+}
+
+#if defined(CONFIG_MX23)
+#define MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
+static const iomux_cfg_t iomux_boot[] = {
+ MX23_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD,
+ MX23_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD,
+ MX23_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD,
+ MX23_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD,
+ MX23_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD,
+ MX23_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD,
+};
+#endif
+
+static uint8_t mxs_get_bootmode_index(void)
+{
+ uint8_t bootmode = 0;
+ int i;
+ uint8_t masked;
+
+#if defined(CONFIG_MX23)
+ /* Setup IOMUX of bootmode pads to GPIO */
+ mxs_iomux_setup_multiple_pads(iomux_boot, ARRAY_SIZE(iomux_boot));
+
+ /* Setup bootmode pins as GPIO input */
+ gpio_direction_input(MX23_PAD_LCD_D00__GPIO_1_0);
+ gpio_direction_input(MX23_PAD_LCD_D01__GPIO_1_1);
+ gpio_direction_input(MX23_PAD_LCD_D02__GPIO_1_2);
+ gpio_direction_input(MX23_PAD_LCD_D03__GPIO_1_3);
+ gpio_direction_input(MX23_PAD_LCD_D05__GPIO_1_5);
+
+ /* Read bootmode pads */
+ bootmode |= (gpio_get_value(MX23_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0;
+ bootmode |= (gpio_get_value(MX23_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1;
+ bootmode |= (gpio_get_value(MX23_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2;
+ bootmode |= (gpio_get_value(MX23_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3;
+ bootmode |= (gpio_get_value(MX23_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5;
+#elif defined(CONFIG_MX28)
+ /* The global boot mode will be detected by ROM code and its value
+ * is stored at the fixed address 0x00019BF0 in OCRAM.
+ */
+#define GLOBAL_BOOT_MODE_ADDR 0x00019BF0
+ bootmode = __raw_readl(GLOBAL_BOOT_MODE_ADDR);
+#endif
+
+ for (i = 0; i < ARRAY_SIZE(mxs_boot_modes); i++) {
+ masked = bootmode & mxs_boot_modes[i].boot_mask;
+ if (masked == mxs_boot_modes[i].boot_pads)
+ break;
+ }
+
+ return i;
+}
+
+static void mxs_spl_fixup_vectors(void)
+{
+ /*
+ * Copy our vector table to 0x0, since due to HAB, we cannot
+ * be loaded to 0x0. We want to have working vectoring though,
+ * thus this fixup. Our vectoring table is PIC, so copying is
+ * fine.
+ */
+
+ /* cppcheck-suppress nullPointer */
+ memcpy(0x0, &_start, 0x60);
+}
+
+static void mxs_spl_console_init(void)
+{
+#ifdef CONFIG_SPL_SERIAL_SUPPORT
+ gd->bd = &bdata;
+ gd->baudrate = CONFIG_BAUDRATE;
+ serial_init();
+ gd->have_console = 1;
+#endif
+}
+
+void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr,
+ const iomux_cfg_t *iomux_setup,
+ const unsigned int iomux_size)
+{
+ struct mxs_spl_data *data = MXS_SPL_DATA;
+ uint8_t bootmode = mxs_get_bootmode_index();
+ set_gd(&gdata);
+
+ mxs_spl_fixup_vectors();
+
+ mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size);
+
+ mxs_spl_console_init();
+ debug("SPL: Serial Console Initialised\n");
+
+ mxs_power_init();
+
+ mxs_mem_init();
+ data->mem_dram_size = mxs_mem_get_size();
+
+ data->boot_mode_idx = bootmode;
+
+ mxs_power_wait_pswitch();
+
+ if (mxs_boot_modes[data->boot_mode_idx].boot_pads == MXS_BM_JTAG) {
+ debug("SPL: Waiting for JTAG user\n");
+ asm volatile ("x: b x");
+ }
+}
+
+#ifndef CONFIG_SPL_FRAMEWORK
+/* Support aparatus */
+inline void board_init_f(unsigned long bootflag)
+{
+ for (;;)
+ ;
+}
+
+inline void board_init_r(gd_t *id, ulong dest_addr)
+{
+ for (;;)
+ ;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c
new file mode 100644
index 000000000..2cfbd7809
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Freescale i.MX28 Battery measurement init
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ */
+
+#include <common.h>
+#include <config.h>
+#include <log.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+
+#include "mxs_init.h"
+
+void mxs_lradc_init(void)
+{
+ struct mxs_lradc_regs *regs = (struct mxs_lradc_regs *)MXS_LRADC_BASE;
+
+ debug("SPL: Initialisating LRADC\n");
+
+ writel(LRADC_CTRL0_SFTRST, &regs->hw_lradc_ctrl0_clr);
+ writel(LRADC_CTRL0_CLKGATE, &regs->hw_lradc_ctrl0_clr);
+ writel(LRADC_CTRL0_ONCHIP_GROUNDREF, &regs->hw_lradc_ctrl0_clr);
+
+ clrsetbits_le32(&regs->hw_lradc_ctrl3,
+ LRADC_CTRL3_CYCLE_TIME_MASK,
+ LRADC_CTRL3_CYCLE_TIME_6MHZ);
+
+ clrsetbits_le32(&regs->hw_lradc_ctrl4,
+ LRADC_CTRL4_LRADC7SELECT_MASK |
+ LRADC_CTRL4_LRADC6SELECT_MASK,
+ LRADC_CTRL4_LRADC7SELECT_CHANNEL7 |
+ LRADC_CTRL4_LRADC6SELECT_CHANNEL10);
+}
+
+void mxs_lradc_enable_batt_measurement(void)
+{
+ struct mxs_lradc_regs *regs = (struct mxs_lradc_regs *)MXS_LRADC_BASE;
+
+ debug("SPL: Enabling LRADC battery measurement\n");
+
+ /* Check if the channel is present at all. */
+ if (!(readl(&regs->hw_lradc_status) & LRADC_STATUS_CHANNEL7_PRESENT)) {
+ debug("SPL: LRADC channel 7 is not present - aborting\n");
+ return;
+ }
+
+ debug("SPL: LRADC channel 7 is present - configuring\n");
+
+ writel(LRADC_CTRL1_LRADC7_IRQ_EN, &regs->hw_lradc_ctrl1_clr);
+ writel(LRADC_CTRL1_LRADC7_IRQ, &regs->hw_lradc_ctrl1_clr);
+
+ clrsetbits_le32(&regs->hw_lradc_conversion,
+ LRADC_CONVERSION_SCALE_FACTOR_MASK,
+ LRADC_CONVERSION_SCALE_FACTOR_LI_ION);
+ writel(LRADC_CONVERSION_AUTOMATIC, &regs->hw_lradc_conversion_set);
+
+ /* Configure the channel. */
+ writel((1 << 7) << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
+ &regs->hw_lradc_ctrl2_clr);
+ writel(0xffffffff, &regs->hw_lradc_ch7_clr);
+ clrbits_le32(&regs->hw_lradc_ch7, LRADC_CH_NUM_SAMPLES_MASK);
+ writel(LRADC_CH_ACCUMULATE, &regs->hw_lradc_ch7_clr);
+
+ /* Schedule the channel. */
+ writel(1 << 7, &regs->hw_lradc_ctrl0_set);
+
+ /* Start the channel sampling. */
+ writel(((1 << 7) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) |
+ ((1 << 3) << LRADC_DELAY_TRIGGER_DELAYS_OFFSET) |
+ 100, &regs->hw_lradc_delay3);
+
+ writel(0xffffffff, &regs->hw_lradc_ch7_clr);
+ writel(LRADC_DELAY_KICK, &regs->hw_lradc_delay3_set);
+
+ debug("SPL: LRADC channel 7 configuration complete\n");
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
new file mode 100644
index 000000000..a94803ee9
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
@@ -0,0 +1,361 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Freescale i.MX28 RAM init
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ */
+
+#include <common.h>
+#include <config.h>
+#include <init.h>
+#include <log.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+#include <linux/compiler.h>
+
+#include "mxs_init.h"
+
+__weak uint32_t mxs_dram_vals[] = {
+/*
+ * i.MX28 DDR2 at 200MHz
+ */
+#if defined(CONFIG_MX28)
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000100, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00010101, 0x01010101,
+ 0x000f0f01, 0x0f02020a, 0x00000000, 0x00010101,
+ 0x00000100, 0x00000100, 0x00000000, 0x00000002,
+ 0x01010000, 0x07080403, 0x06005003, 0x0a0000c8,
+ 0x02009c40, 0x0002030c, 0x0036a609, 0x031a0612,
+ 0x02030202, 0x00c8001c, 0x00000000, 0x00000000,
+ 0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
+ 0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
+ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000612, 0x01000F02,
+ 0x06120612, 0x00000200, 0x00020007, 0xf4004a27,
+ 0xf4004a27, 0xf4004a27, 0xf4004a27, 0x07000300,
+ 0x07000300, 0x07400300, 0x07400300, 0x00000005,
+ 0x00000000, 0x00000000, 0x01000000, 0x01020408,
+ 0x08040201, 0x000f1133, 0x00000000, 0x00001f04,
+ 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04,
+ 0x00001f04, 0x00001f04, 0x00001f04, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00010000, 0x00030404,
+ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x01010000,
+ 0x01000000, 0x03030000, 0x00010303, 0x01020202,
+ 0x00000000, 0x02040303, 0x21002103, 0x00061200,
+ 0x06120612, 0x04420442, 0x04420442, 0x00040004,
+ 0x00040004, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xffffffff
+
+/*
+ * i.MX23 DDR at 133MHz
+ */
+#elif defined(CONFIG_MX23)
+ 0x01010001, 0x00010100, 0x01000101, 0x00000001,
+ 0x00000101, 0x00000000, 0x00010000, 0x01000001,
+ 0x00000000, 0x00000001, 0x07000200, 0x00070202,
+ 0x02020000, 0x04040a01, 0x00000201, 0x02040000,
+ 0x02000000, 0x19000f08, 0x0d0d0000, 0x02021313,
+ 0x02061521, 0x0000000a, 0x00080008, 0x00200020,
+ 0x00200020, 0x00200020, 0x000003f7, 0x00000000,
+ 0x00000000, 0x00000020, 0x00000020, 0x00c80000,
+ 0x000a23cd, 0x000000c8, 0x00006665, 0x00000000,
+ 0x00000101, 0x00040001, 0x00000000, 0x00000000,
+ 0x00010000
+#else
+#error Unsupported memory initialization
+#endif
+};
+
+__weak void mxs_adjust_memory_params(uint32_t *dram_vals)
+{
+ debug("SPL: Using default SDRAM parameters\n");
+}
+
+#ifdef CONFIG_MX28
+static void initialize_dram_values(void)
+{
+ int i;
+
+ debug("SPL: Setting mx28 board specific SDRAM parameters\n");
+ mxs_adjust_memory_params(mxs_dram_vals);
+
+ debug("SPL: Applying SDRAM parameters\n");
+ for (i = 0; i < ARRAY_SIZE(mxs_dram_vals); i++)
+ writel(mxs_dram_vals[i], MXS_DRAM_BASE + (4 * i));
+}
+#else
+static void initialize_dram_values(void)
+{
+ int i;
+
+ debug("SPL: Setting mx23 board specific SDRAM parameters\n");
+ mxs_adjust_memory_params(mxs_dram_vals);
+
+ /*
+ * HW_DRAM_CTL27, HW_DRAM_CTL28 and HW_DRAM_CTL35 are not initialized as
+ * per FSL bootlets code.
+ *
+ * mx23 Reference Manual marks HW_DRAM_CTL27 and HW_DRAM_CTL28 as
+ * "reserved".
+ * HW_DRAM_CTL8 is setup as the last element.
+ * So skip the initialization of these HW_DRAM_CTL registers.
+ */
+ debug("SPL: Applying SDRAM parameters\n");
+ for (i = 0; i < ARRAY_SIZE(mxs_dram_vals); i++) {
+ if (i == 8 || i == 27 || i == 28 || i == 35)
+ continue;
+ writel(mxs_dram_vals[i], MXS_DRAM_BASE + (4 * i));
+ }
+
+ /*
+ * Enable tRAS lockout in HW_DRAM_CTL08 ; it must be the last
+ * element to be set
+ */
+ writel((1 << 24), MXS_DRAM_BASE + (4 * 8));
+}
+#endif
+
+static void mxs_mem_init_clock(void)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+#if defined(CONFIG_MX23)
+ /* Fractional divider for ref_emi is 33 ; 480 * 18 / 33 = 266MHz */
+ const unsigned char divider = 33;
+#elif defined(CONFIG_MX28)
+ /* Fractional divider for ref_emi is 21 ; 480 * 18 / 21 = 411MHz */
+ const unsigned char divider = 21;
+#endif
+
+ debug("SPL: Initialising FRAC0\n");
+
+ /* Gate EMI clock */
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_EMI]);
+
+ /* Set fractional divider for ref_emi */
+ writeb(CLKCTRL_FRAC_CLKGATE | (divider & CLKCTRL_FRAC_FRAC_MASK),
+ &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_EMI]);
+
+ /* Ungate EMI clock */
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_EMI]);
+
+ early_delay(11000);
+
+ /* Set EMI clock divider for EMI clock to 411 / 2 = 205MHz */
+ writel((2 << CLKCTRL_EMI_DIV_EMI_OFFSET) |
+ (1 << CLKCTRL_EMI_DIV_XTAL_OFFSET),
+ &clkctrl_regs->hw_clkctrl_emi);
+
+ /* Unbypass EMI */
+ writel(CLKCTRL_CLKSEQ_BYPASS_EMI,
+ &clkctrl_regs->hw_clkctrl_clkseq_clr);
+
+ early_delay(10000);
+ debug("SPL: FRAC0 Initialised\n");
+}
+
+static void mxs_mem_setup_cpu_and_hbus(void)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ debug("SPL: Setting CPU and HBUS clock frequencies\n");
+
+ /* Set fractional divider for ref_cpu to 480 * 18 / 19 = 454MHz
+ * and ungate CPU clock */
+ writeb(19 & CLKCTRL_FRAC_FRAC_MASK,
+ (uint8_t *)&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]);
+
+ /* Set CPU bypass */
+ writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
+ &clkctrl_regs->hw_clkctrl_clkseq_set);
+
+ /* HBUS = 151MHz */
+ writel(CLKCTRL_HBUS_DIV_MASK, &clkctrl_regs->hw_clkctrl_hbus_set);
+ writel(((~3) << CLKCTRL_HBUS_DIV_OFFSET) & CLKCTRL_HBUS_DIV_MASK,
+ &clkctrl_regs->hw_clkctrl_hbus_clr);
+
+ early_delay(10000);
+
+ /* CPU clock divider = 1 */
+ clrsetbits_le32(&clkctrl_regs->hw_clkctrl_cpu,
+ CLKCTRL_CPU_DIV_CPU_MASK, 1);
+
+ /* Disable CPU bypass */
+ writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
+ &clkctrl_regs->hw_clkctrl_clkseq_clr);
+
+ early_delay(15000);
+}
+
+static void mxs_mem_setup_vdda(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Configuring VDDA\n");
+
+ writel((0xc << POWER_VDDACTRL_TRG_OFFSET) |
+ (0x7 << POWER_VDDACTRL_BO_OFFSET_OFFSET) |
+ POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW,
+ &power_regs->hw_power_vddactrl);
+}
+
+uint32_t mxs_mem_get_size(void)
+{
+ uint32_t sz, da;
+ uint32_t *vt = (uint32_t *)0x20;
+ /* The following is "subs pc, r14, #4", used as return from DABT. */
+ const uint32_t data_abort_memdetect_handler = 0xe25ef004;
+
+ /* Replace the DABT handler. */
+ da = vt[4];
+ vt[4] = data_abort_memdetect_handler;
+
+ sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
+
+ /* Restore the old DABT handler. */
+ vt[4] = da;
+
+ return sz;
+}
+
+#ifdef CONFIG_MX23
+static void mx23_mem_setup_vddmem(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Setting mx23 VDDMEM\n");
+
+ /* We must wait before and after disabling the current limiter! */
+ early_delay(10000);
+
+ clrbits_le32(&power_regs->hw_power_vddmemctrl,
+ POWER_VDDMEMCTRL_ENABLE_ILIMIT);
+
+ early_delay(10000);
+
+}
+
+static void mx23_mem_init(void)
+{
+ debug("SPL: Initialising mx23 SDRAM Controller\n");
+
+ /*
+ * Reset/ungate the EMI block. This is essential, otherwise the system
+ * suffers from memory instability. This thing is mx23 specific and is
+ * no longer present on mx28.
+ */
+ mxs_reset_block((struct mxs_register_32 *)MXS_EMI_BASE);
+
+ mx23_mem_setup_vddmem();
+
+ /*
+ * Configure the DRAM registers
+ */
+
+ /* Clear START and SREFRESH bit from DRAM_CTL8 */
+ clrbits_le32(MXS_DRAM_BASE + 0x20, (1 << 16) | (1 << 8));
+
+ initialize_dram_values();
+
+ /* Set START bit in DRAM_CTL8 */
+ setbits_le32(MXS_DRAM_BASE + 0x20, 1 << 16);
+
+ clrbits_le32(MXS_DRAM_BASE + 0x40, 1 << 17);
+
+ /* Wait for EMI_STAT bit DRAM_HALTED */
+ for (;;) {
+ if (!(readl(MXS_EMI_BASE + 0x10) & (1 << 1)))
+ break;
+ early_delay(1000);
+ }
+
+ /* Adjust EMI port priority. */
+ clrsetbits_le32(0x80020000, 0x1f << 16, 0x2);
+ early_delay(20000);
+
+ setbits_le32(MXS_DRAM_BASE + 0x40, 1 << 19);
+ setbits_le32(MXS_DRAM_BASE + 0x40, 1 << 11);
+}
+#endif
+
+#ifdef CONFIG_MX28
+static void mx28_mem_init(void)
+{
+ struct mxs_pinctrl_regs *pinctrl_regs =
+ (struct mxs_pinctrl_regs *)MXS_PINCTRL_BASE;
+
+ debug("SPL: Initialising mx28 SDRAM Controller\n");
+
+ /* Set DDR2 mode */
+ writel(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2,
+ &pinctrl_regs->hw_pinctrl_emi_ds_ctrl_set);
+
+ /*
+ * Configure the DRAM registers
+ */
+
+ /* Clear START bit from DRAM_CTL16 */
+ clrbits_le32(MXS_DRAM_BASE + 0x40, 1);
+
+ initialize_dram_values();
+
+ /* Clear SREFRESH bit from DRAM_CTL17 */
+ clrbits_le32(MXS_DRAM_BASE + 0x44, 1);
+
+ /* Set START bit in DRAM_CTL16 */
+ setbits_le32(MXS_DRAM_BASE + 0x40, 1);
+
+ /* Wait for bit 20 (DRAM init complete) in DRAM_CTL58 */
+ while (!(readl(MXS_DRAM_BASE + 0xe8) & (1 << 20)))
+ ;
+}
+#endif
+
+void mxs_mem_init(void)
+{
+ early_delay(11000);
+
+ mxs_mem_init_clock();
+
+ mxs_mem_setup_vdda();
+
+#if defined(CONFIG_MX23)
+ mx23_mem_init();
+#elif defined(CONFIG_MX28)
+ mx28_mem_init();
+#endif
+
+ early_delay(10000);
+
+ mxs_mem_setup_cpu_and_hbus();
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
new file mode 100644
index 000000000..35ea71a5b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
@@ -0,0 +1,1291 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Freescale i.MX28 Boot PMIC init
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ */
+
+#include <common.h>
+#include <config.h>
+#include <hang.h>
+#include <log.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+
+#include "mxs_init.h"
+
+#ifdef CONFIG_SYS_MXS_VDD5V_ONLY
+#define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \
+ POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2
+#else
+#define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \
+ POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL
+#endif
+/**
+ * mxs_power_clock2xtal() - Switch CPU core clock source to 24MHz XTAL
+ *
+ * This function switches the CPU core clock from PLL to 24MHz XTAL
+ * oscilator. This is necessary if the PLL is being reconfigured to
+ * prevent crash of the CPU core.
+ */
+static void mxs_power_clock2xtal(void)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ debug("SPL: Switching CPU clock to 24MHz XTAL\n");
+
+ /* Set XTAL as CPU reference clock */
+ writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
+ &clkctrl_regs->hw_clkctrl_clkseq_set);
+}
+
+/**
+ * mxs_power_clock2pll() - Switch CPU core clock source to PLL
+ *
+ * This function switches the CPU core clock from 24MHz XTAL oscilator
+ * to PLL. This can only be called once the PLL has re-locked and once
+ * the PLL is stable after reconfiguration.
+ */
+static void mxs_power_clock2pll(void)
+{
+ struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ debug("SPL: Switching CPU core clock source to PLL\n");
+
+ /*
+ * TODO: Are we really? It looks like we turn on PLL0, but we then
+ * set the CLKCTRL_CLKSEQ_BYPASS_CPU bit of the (which was already
+ * set by mxs_power_clock2xtal()). Clearing this bit here seems to
+ * introduce some instability (causing the CPU core to hang). Maybe
+ * we aren't giving PLL0 enough time to stabilise?
+ */
+ setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
+ CLKCTRL_PLL0CTRL0_POWER);
+ early_delay(100);
+
+ /*
+ * TODO: Should the PLL0 FORCE_LOCK bit be set here followed be a
+ * wait on the PLL0 LOCK bit?
+ */
+ setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
+ CLKCTRL_CLKSEQ_BYPASS_CPU);
+}
+
+/**
+ * mxs_power_set_auto_restart() - Set the auto-restart bit
+ *
+ * This function ungates the RTC block and sets the AUTO_RESTART
+ * bit to work around a design bug on MX28EVK Rev. A .
+ */
+
+static void mxs_power_set_auto_restart(void)
+{
+ struct mxs_rtc_regs *rtc_regs =
+ (struct mxs_rtc_regs *)MXS_RTC_BASE;
+
+ debug("SPL: Setting auto-restart bit\n");
+
+ writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
+ while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
+ ;
+
+ writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
+ while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
+ ;
+
+ /* Do nothing if flag already set */
+ if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
+ return;
+
+ while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
+ ;
+
+ setbits_le32(&rtc_regs->hw_rtc_persistent0,
+ RTC_PERSISTENT0_AUTO_RESTART);
+ writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set);
+ writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr);
+ while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
+ ;
+ while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
+ ;
+}
+
+/**
+ * mxs_power_set_linreg() - Set linear regulators 25mV below DC-DC converter
+ *
+ * This function configures the VDDIO, VDDA and VDDD linear regulators output
+ * to be 25mV below the VDDIO, VDDA and VDDD output from the DC-DC switching
+ * converter. This is the recommended setting for the case where we use both
+ * linear regulators and DC-DC converter to power the VDDIO rail.
+ */
+static void mxs_power_set_linreg(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ /* Set linear regulator 25mV below switching converter */
+ debug("SPL: Setting VDDD 25mV below DC-DC converters\n");
+ clrsetbits_le32(&power_regs->hw_power_vdddctrl,
+ POWER_VDDDCTRL_LINREG_OFFSET_MASK,
+ POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
+
+ debug("SPL: Setting VDDA 25mV below DC-DC converters\n");
+ clrsetbits_le32(&power_regs->hw_power_vddactrl,
+ POWER_VDDACTRL_LINREG_OFFSET_MASK,
+ POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW);
+
+ debug("SPL: Setting VDDIO 25mV below DC-DC converters\n");
+ clrsetbits_le32(&power_regs->hw_power_vddioctrl,
+ POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
+ POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
+}
+
+/**
+ * mxs_get_batt_volt() - Measure battery input voltage
+ *
+ * This function retrieves the battery input voltage and returns it.
+ */
+static int mxs_get_batt_volt(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+ uint32_t volt = readl(&power_regs->hw_power_battmonitor);
+ volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
+ volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
+ volt *= 8;
+
+ debug("SPL: Battery Voltage = %dmV\n", volt);
+ return volt;
+}
+
+/**
+ * mxs_is_batt_ready() - Test if the battery provides enough voltage to boot
+ *
+ * This function checks if the battery input voltage is higher than 3.6V and
+ * therefore allows the system to successfully boot using this power source.
+ */
+static int mxs_is_batt_ready(void)
+{
+ return (mxs_get_batt_volt() >= 3600);
+}
+
+/**
+ * mxs_is_batt_good() - Test if battery is operational at all
+ *
+ * This function starts recharging the battery and tests if the input current
+ * provided by the 5V input recharging the battery is also sufficient to power
+ * the DC-DC converter.
+ */
+static int mxs_is_batt_good(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+ uint32_t volt = mxs_get_batt_volt();
+
+ if ((volt >= 2400) && (volt <= 4300)) {
+ debug("SPL: Battery is good\n");
+ return 1;
+ }
+
+ clrsetbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+ 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+ writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+ &power_regs->hw_power_5vctrl_clr);
+
+ clrsetbits_le32(&power_regs->hw_power_charge,
+ POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
+ POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
+
+ writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
+ writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+ &power_regs->hw_power_5vctrl_clr);
+
+ early_delay(500000);
+
+ volt = mxs_get_batt_volt();
+
+ if (volt >= 3500) {
+ debug("SPL: Battery Voltage too high\n");
+ return 0;
+ }
+
+ if (volt >= 2400) {
+ debug("SPL: Battery is good\n");
+ return 1;
+ }
+
+ writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
+ &power_regs->hw_power_charge_clr);
+ writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
+
+ debug("SPL: Battery Voltage too low\n");
+ return 0;
+}
+
+/**
+ * mxs_power_setup_5v_detect() - Start the 5V input detection comparator
+ *
+ * This function enables the 5V detection comparator and sets the 5V valid
+ * threshold to 4.4V . We use 4.4V threshold here to make sure that even
+ * under high load, the voltage drop on the 5V input won't be so critical
+ * to cause undervolt on the 4P2 linear regulator supplying the DC-DC
+ * converter and thus making the system crash.
+ */
+static void mxs_power_setup_5v_detect(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ /* Start 5V detection */
+ debug("SPL: Starting 5V input detection comparator\n");
+ clrsetbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_VBUSVALID_TRSH_MASK,
+ POWER_5VCTRL_VBUSVALID_TRSH_4V4 |
+ POWER_5VCTRL_PWRUP_VBUS_CMPS);
+}
+
+/**
+ * mxs_power_switch_dcdc_clocksource() - Switch PLL clock for DC-DC converters
+ * @freqsel: One of the POWER_MISC_FREQSEL_xxx defines to select the clock
+ *
+ * This function configures and then enables an alternative PLL clock source
+ * for the DC-DC converters.
+ */
+void mxs_power_switch_dcdc_clocksource(uint32_t freqsel)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ /* Select clocksource for DC-DC converters */
+ clrsetbits_le32(&power_regs->hw_power_misc,
+ POWER_MISC_FREQSEL_MASK,
+ freqsel);
+ setbits_le32(&power_regs->hw_power_misc,
+ POWER_MISC_SEL_PLLCLK);
+}
+
+/**
+ * mxs_power_setup_dcdc_clocksource() - Setup PLL clock source for DC-DC converters
+ *
+ * Normally, there is no need to switch DC-DC clocksource. This is the reason,
+ * why this function is a stub and does nothing. However, boards can implement
+ * this function when required and call mxs_power_switch_dcdc_clocksource() to
+ * switch to an alternative clock source.
+ */
+__weak void mxs_power_setup_dcdc_clocksource(void)
+{
+ debug("SPL: Using default DC-DC clocksource\n");
+}
+
+/**
+ * mxs_src_power_init() - Preconfigure the power block
+ *
+ * This function configures reasonable values for the DC-DC control loop
+ * and battery monitor.
+ */
+static void mxs_src_power_init(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Pre-Configuring power block\n");
+
+ /* Improve efficieny and reduce transient ripple */
+ writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
+ POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
+
+ clrsetbits_le32(&power_regs->hw_power_dclimits,
+ POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
+ 0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
+
+ setbits_le32(&power_regs->hw_power_battmonitor,
+ POWER_BATTMONITOR_EN_BATADJ);
+
+ /* Increase the RCSCALE level for quick DCDC response to dynamic load */
+ clrsetbits_le32(&power_regs->hw_power_loopctrl,
+ POWER_LOOPCTRL_EN_RCSCALE_MASK,
+ POWER_LOOPCTRL_RCSCALE_THRESH |
+ POWER_LOOPCTRL_EN_RCSCALE_8X);
+
+ clrsetbits_le32(&power_regs->hw_power_minpwr,
+ POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
+
+ /* 5V to battery handoff ... FIXME */
+ setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+ early_delay(30);
+ clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+}
+
+/**
+ * mxs_power_init_4p2_params() - Configure the parameters of the 4P2 regulator
+ *
+ * This function configures the necessary parameters for the 4P2 linear
+ * regulator to supply the DC-DC converter from 5V input.
+ */
+static void mxs_power_init_4p2_params(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Configuring common 4P2 regulator params\n");
+
+ /* Setup 4P2 parameters */
+ clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
+ POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
+ POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET));
+
+ clrsetbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_HEADROOM_ADJ_MASK,
+ 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET);
+
+ clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
+ POWER_DCDC4P2_DROPOUT_CTRL_MASK,
+ DCDC4P2_DROPOUT_CONFIG);
+
+ clrsetbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+ 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+}
+
+/**
+ * mxs_enable_4p2_dcdc_input() - Enable or disable the DCDC input from 4P2
+ * @xfer: Select if the input shall be enabled or disabled
+ *
+ * This function enables or disables the 4P2 input into the DC-DC converter.
+ */
+static void mxs_enable_4p2_dcdc_input(int xfer)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+ uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
+ uint32_t prev_5v_brnout, prev_5v_droop;
+
+ debug("SPL: %s 4P2 DC-DC Input\n", xfer ? "Enabling" : "Disabling");
+
+ if (xfer && (readl(&power_regs->hw_power_5vctrl) &
+ POWER_5VCTRL_ENABLE_DCDC)) {
+ return;
+ }
+
+ prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
+ POWER_5VCTRL_PWDN_5VBRNOUT;
+ prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
+ POWER_CTRL_ENIRQ_VDD5V_DROOP;
+
+ clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
+ writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
+ &power_regs->hw_power_reset);
+
+ clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP);
+
+ /*
+ * Recording orignal values that will be modified temporarlily
+ * to handle a chip bug. See chip errata for CQ ENGR00115837
+ */
+ tmp = readl(&power_regs->hw_power_5vctrl);
+ vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK;
+ vbus_5vdetect = tmp & POWER_5VCTRL_VBUSVALID_5VDETECT;
+
+ pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO;
+
+ /*
+ * Disable mechanisms that get erroneously tripped by when setting
+ * the DCDC4P2 EN_DCDC
+ */
+ clrbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_VBUSVALID_5VDETECT |
+ POWER_5VCTRL_VBUSVALID_TRSH_MASK);
+
+ writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set);
+
+ if (xfer) {
+ setbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_DCDC_XFER);
+ early_delay(20);
+ clrbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_DCDC_XFER);
+
+ setbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_ENABLE_DCDC);
+ } else {
+ setbits_le32(&power_regs->hw_power_dcdc4p2,
+ POWER_DCDC4P2_ENABLE_DCDC);
+ }
+
+ early_delay(25);
+
+ clrsetbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh);
+
+ if (vbus_5vdetect)
+ writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set);
+
+ if (!pwd_bo)
+ clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO);
+
+ while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ)
+ writel(POWER_CTRL_VBUS_VALID_IRQ,
+ &power_regs->hw_power_ctrl_clr);
+
+ if (prev_5v_brnout) {
+ writel(POWER_5VCTRL_PWDN_5VBRNOUT,
+ &power_regs->hw_power_5vctrl_set);
+ writel(POWER_RESET_UNLOCK_KEY,
+ &power_regs->hw_power_reset);
+ } else {
+ writel(POWER_5VCTRL_PWDN_5VBRNOUT,
+ &power_regs->hw_power_5vctrl_clr);
+ writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
+ &power_regs->hw_power_reset);
+ }
+
+ while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ)
+ writel(POWER_CTRL_VDD5V_DROOP_IRQ,
+ &power_regs->hw_power_ctrl_clr);
+
+ if (prev_5v_droop)
+ clrbits_le32(&power_regs->hw_power_ctrl,
+ POWER_CTRL_ENIRQ_VDD5V_DROOP);
+ else
+ setbits_le32(&power_regs->hw_power_ctrl,
+ POWER_CTRL_ENIRQ_VDD5V_DROOP);
+}
+
+/**
+ * mxs_power_init_4p2_regulator() - Start the 4P2 regulator
+ *
+ * This function enables the 4P2 regulator and switches the DC-DC converter
+ * to use the 4P2 input.
+ */
+static void mxs_power_init_4p2_regulator(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+ uint32_t tmp, tmp2;
+
+ debug("SPL: Enabling 4P2 regulator\n");
+
+ setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
+
+ writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
+
+ writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+ &power_regs->hw_power_5vctrl_clr);
+ clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK);
+
+ /* Power up the 4p2 rail and logic/control */
+ writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+ &power_regs->hw_power_5vctrl_clr);
+
+ /*
+ * Start charging up the 4p2 capacitor. We ramp of this charge
+ * gradually to avoid large inrush current from the 5V cable which can
+ * cause transients/problems
+ */
+ debug("SPL: Charging 4P2 capacitor\n");
+ mxs_enable_4p2_dcdc_input(0);
+
+ if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
+ /*
+ * If we arrived here, we were unable to recover from mx23 chip
+ * errata 5837. 4P2 is disabled and sufficient battery power is
+ * not present. Exiting to not enable DCDC power during 5V
+ * connected state.
+ */
+ clrbits_le32(&power_regs->hw_power_dcdc4p2,
+ POWER_DCDC4P2_ENABLE_DCDC);
+ writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+ &power_regs->hw_power_5vctrl_set);
+
+ debug("SPL: Unable to recover from mx23 errata 5837\n");
+ hang();
+ }
+
+ /*
+ * Here we set the 4p2 brownout level to something very close to 4.2V.
+ * We then check the brownout status. If the brownout status is false,
+ * the voltage is already close to the target voltage of 4.2V so we
+ * can go ahead and set the 4P2 current limit to our max target limit.
+ * If the brownout status is true, we need to ramp us the current limit
+ * so that we don't cause large inrush current issues. We step up the
+ * current limit until the brownout status is false or until we've
+ * reached our maximum defined 4p2 current limit.
+ */
+ debug("SPL: Setting 4P2 brownout level\n");
+ clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
+ POWER_DCDC4P2_BO_MASK,
+ 22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */
+
+ if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) {
+ setbits_le32(&power_regs->hw_power_5vctrl,
+ 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+ } else {
+ tmp = (readl(&power_regs->hw_power_5vctrl) &
+ POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >>
+ POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
+ while (tmp < 0x3f) {
+ if (!(readl(&power_regs->hw_power_sts) &
+ POWER_STS_DCDC_4P2_BO)) {
+ tmp = readl(&power_regs->hw_power_5vctrl);
+ tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
+ early_delay(100);
+ writel(tmp, &power_regs->hw_power_5vctrl);
+ break;
+ } else {
+ tmp++;
+ tmp2 = readl(&power_regs->hw_power_5vctrl);
+ tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
+ tmp2 |= tmp <<
+ POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
+ writel(tmp2, &power_regs->hw_power_5vctrl);
+ early_delay(100);
+ }
+ }
+ }
+
+ clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
+ writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
+}
+
+/**
+ * mxs_power_init_dcdc_4p2_source() - Switch DC-DC converter to 4P2 source
+ *
+ * This function configures the DC-DC converter to be supplied from the 4P2
+ * linear regulator.
+ */
+static void mxs_power_init_dcdc_4p2_source(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Switching DC-DC converters to 4P2\n");
+
+ if (!(readl(&power_regs->hw_power_dcdc4p2) &
+ POWER_DCDC4P2_ENABLE_DCDC)) {
+ debug("SPL: Already switched - aborting\n");
+ hang();
+ }
+
+ mxs_enable_4p2_dcdc_input(1);
+
+ if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
+ clrbits_le32(&power_regs->hw_power_dcdc4p2,
+ POWER_DCDC4P2_ENABLE_DCDC);
+ writel(POWER_5VCTRL_ENABLE_DCDC,
+ &power_regs->hw_power_5vctrl_clr);
+ writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+ &power_regs->hw_power_5vctrl_set);
+ }
+}
+
+/**
+ * mxs_power_enable_4p2() - Power up the 4P2 regulator
+ *
+ * This function drives the process of powering up the 4P2 linear regulator
+ * and switching the DC-DC converter input over to the 4P2 linear regulator.
+ */
+static void mxs_power_enable_4p2(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+ uint32_t vdddctrl, vddactrl, vddioctrl;
+ uint32_t tmp;
+
+ debug("SPL: Powering up 4P2 regulator\n");
+
+ vdddctrl = readl(&power_regs->hw_power_vdddctrl);
+ vddactrl = readl(&power_regs->hw_power_vddactrl);
+ vddioctrl = readl(&power_regs->hw_power_vddioctrl);
+
+ setbits_le32(&power_regs->hw_power_vdddctrl,
+ POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
+ POWER_VDDDCTRL_PWDN_BRNOUT);
+
+ setbits_le32(&power_regs->hw_power_vddactrl,
+ POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
+ POWER_VDDACTRL_PWDN_BRNOUT);
+
+ setbits_le32(&power_regs->hw_power_vddioctrl,
+ POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT);
+
+ mxs_power_init_4p2_params();
+ mxs_power_init_4p2_regulator();
+
+ /* Shutdown battery (none present) */
+ if (!mxs_is_batt_ready()) {
+ clrbits_le32(&power_regs->hw_power_dcdc4p2,
+ POWER_DCDC4P2_BO_MASK);
+ writel(POWER_CTRL_DCDC4P2_BO_IRQ,
+ &power_regs->hw_power_ctrl_clr);
+ writel(POWER_CTRL_ENIRQ_DCDC4P2_BO,
+ &power_regs->hw_power_ctrl_clr);
+ }
+
+ mxs_power_init_dcdc_4p2_source();
+
+ writel(vdddctrl, &power_regs->hw_power_vdddctrl);
+ early_delay(20);
+ writel(vddactrl, &power_regs->hw_power_vddactrl);
+ early_delay(20);
+ writel(vddioctrl, &power_regs->hw_power_vddioctrl);
+
+ /*
+ * Check if FET is enabled on either powerout and if so,
+ * disable load.
+ */
+ tmp = 0;
+ tmp |= !(readl(&power_regs->hw_power_vdddctrl) &
+ POWER_VDDDCTRL_DISABLE_FET);
+ tmp |= !(readl(&power_regs->hw_power_vddactrl) &
+ POWER_VDDACTRL_DISABLE_FET);
+ tmp |= !(readl(&power_regs->hw_power_vddioctrl) &
+ POWER_VDDIOCTRL_DISABLE_FET);
+ if (tmp)
+ writel(POWER_CHARGE_ENABLE_LOAD,
+ &power_regs->hw_power_charge_clr);
+
+ debug("SPL: 4P2 regulator powered-up\n");
+}
+
+/**
+ * mxs_boot_valid_5v() - Boot from 5V supply
+ *
+ * This function configures the power block to boot from valid 5V input.
+ * This is called only if the 5V is reliable and can properly supply the
+ * CPU. This function proceeds to configure the 4P2 converter to be supplied
+ * from the 5V input.
+ */
+static void mxs_boot_valid_5v(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Booting from 5V supply\n");
+
+ /*
+ * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
+ * disconnect event. FIXME
+ */
+ writel(POWER_5VCTRL_VBUSVALID_5VDETECT,
+ &power_regs->hw_power_5vctrl_set);
+
+ /* Configure polarity to check for 5V disconnection. */
+ writel(POWER_CTRL_POLARITY_VBUSVALID |
+ POWER_CTRL_POLARITY_VDD5V_GT_VDDIO,
+ &power_regs->hw_power_ctrl_clr);
+
+ writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ,
+ &power_regs->hw_power_ctrl_clr);
+
+ mxs_power_enable_4p2();
+}
+
+/**
+ * mxs_powerdown() - Shut down the system
+ *
+ * This function powers down the CPU completely.
+ */
+static void mxs_powerdown(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("Powering Down\n");
+
+ writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
+ writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
+ &power_regs->hw_power_reset);
+}
+
+/**
+ * mxs_batt_boot() - Configure the power block to boot from battery input
+ *
+ * This function configures the power block to boot from the battery voltage
+ * supply.
+ */
+static void mxs_batt_boot(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Configuring power block to boot from battery\n");
+
+ clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
+ clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
+
+ clrbits_le32(&power_regs->hw_power_dcdc4p2,
+ POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2);
+ writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr);
+
+ /* 5V to battery handoff. */
+ setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+ early_delay(30);
+ clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+
+ writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
+
+ clrsetbits_le32(&power_regs->hw_power_minpwr,
+ POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
+
+ mxs_power_set_linreg();
+
+ clrbits_le32(&power_regs->hw_power_vdddctrl,
+ POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG);
+
+ clrbits_le32(&power_regs->hw_power_vddactrl,
+ POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG);
+
+ clrbits_le32(&power_regs->hw_power_vddioctrl,
+ POWER_VDDIOCTRL_DISABLE_FET);
+
+ setbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
+
+ setbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_ENABLE_DCDC);
+
+ clrsetbits_le32(&power_regs->hw_power_5vctrl,
+ POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+ 0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+
+ mxs_power_enable_4p2();
+}
+
+/**
+ * mxs_handle_5v_conflict() - Test if the 5V input is reliable
+ *
+ * This function tests if the 5V input can reliably supply the system. If it
+ * can, then proceed to configuring the system to boot from 5V source, otherwise
+ * try booting from battery supply. If we can not boot from battery supply
+ * either, shut down the system.
+ */
+static void mxs_handle_5v_conflict(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+ uint32_t tmp;
+
+ debug("SPL: Resolving 5V conflict\n");
+
+ setbits_le32(&power_regs->hw_power_vddioctrl,
+ POWER_VDDIOCTRL_BO_OFFSET_MASK);
+
+ for (;;) {
+ tmp = readl(&power_regs->hw_power_sts);
+
+ if (tmp & POWER_STS_VDDIO_BO) {
+ /*
+ * VDDIO has a brownout, then the VDD5V_GT_VDDIO becomes
+ * unreliable
+ */
+ debug("SPL: VDDIO has a brownout\n");
+ mxs_powerdown();
+ break;
+ }
+
+ if (tmp & POWER_STS_VDD5V_GT_VDDIO) {
+ debug("SPL: POWER_STS_VDD5V_GT_VDDIO is set\n");
+ mxs_boot_valid_5v();
+ break;
+ } else {
+ debug("SPL: POWER_STS_VDD5V_GT_VDDIO is not set\n");
+ mxs_powerdown();
+ break;
+ }
+
+ /*
+ * TODO: I can't see this being reached. We'll either
+ * powerdown or boot from a stable 5V supply.
+ */
+ if (tmp & POWER_STS_PSWITCH_MASK) {
+ debug("SPL: POWER_STS_PSWITCH_MASK is set\n");
+ mxs_batt_boot();
+ break;
+ }
+ }
+}
+
+/**
+ * mxs_5v_boot() - Configure the power block to boot from 5V input
+ *
+ * This function handles configuration of the power block when supplied by
+ * a 5V input.
+ */
+static void mxs_5v_boot(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Configuring power block to boot from 5V input\n");
+
+ /*
+ * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
+ * but their implementation always returns 1 so we omit it here.
+ */
+ if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+ debug("SPL: 5V VDD good\n");
+ mxs_boot_valid_5v();
+ return;
+ }
+
+ early_delay(1000);
+ if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+ debug("SPL: 5V VDD good (after delay)\n");
+ mxs_boot_valid_5v();
+ return;
+ }
+
+ debug("SPL: 5V VDD not good\n");
+ mxs_handle_5v_conflict();
+}
+
+/**
+ * mxs_init_batt_bo() - Configure battery brownout threshold
+ *
+ * This function configures the battery input brownout threshold. The value
+ * at which the battery brownout happens is configured to 3.0V in the code.
+ */
+static void mxs_init_batt_bo(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Initialising battery brown-out level to 3.0V\n");
+
+ /* Brownout at 3V */
+ clrsetbits_le32(&power_regs->hw_power_battmonitor,
+ POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
+ 15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
+
+ writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
+ writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
+}
+
+/**
+ * mxs_switch_vddd_to_dcdc_source() - Switch VDDD rail to DC-DC converter
+ *
+ * This function turns off the VDDD linear regulator and therefore makes
+ * the VDDD rail be supplied only by the DC-DC converter.
+ */
+static void mxs_switch_vddd_to_dcdc_source(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Switching VDDD to DC-DC converters\n");
+
+ clrsetbits_le32(&power_regs->hw_power_vdddctrl,
+ POWER_VDDDCTRL_LINREG_OFFSET_MASK,
+ POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
+
+ clrbits_le32(&power_regs->hw_power_vdddctrl,
+ POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
+ POWER_VDDDCTRL_DISABLE_STEPPING);
+}
+
+/**
+ * mxs_power_configure_power_source() - Configure power block source
+ *
+ * This function is the core of the power configuration logic. The function
+ * selects the power block input source and configures the whole power block
+ * accordingly. After the configuration is complete and the system is stable
+ * again, the function switches the CPU clock source back to PLL. Finally,
+ * the function switches the voltage rails to DC-DC converter.
+ */
+static void mxs_power_configure_power_source(void)
+{
+ int batt_ready, batt_good;
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+ struct mxs_lradc_regs *lradc_regs =
+ (struct mxs_lradc_regs *)MXS_LRADC_BASE;
+
+ debug("SPL: Configuring power source\n");
+
+ mxs_power_setup_dcdc_clocksource();
+ mxs_src_power_init();
+
+ if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+ batt_ready = mxs_is_batt_ready();
+ if (batt_ready) {
+ /* 5V source detected, good battery detected. */
+ mxs_batt_boot();
+ } else {
+ batt_good = mxs_is_batt_good();
+ if (!batt_good) {
+ /* 5V source detected, bad battery detected. */
+ writel(LRADC_CONVERSION_AUTOMATIC,
+ &lradc_regs->hw_lradc_conversion_clr);
+ clrbits_le32(&power_regs->hw_power_battmonitor,
+ POWER_BATTMONITOR_BATT_VAL_MASK);
+ }
+ mxs_5v_boot();
+ }
+ } else {
+ /* 5V not detected, booting from battery. */
+ mxs_batt_boot();
+ }
+
+ /*
+ * TODO: Do not switch CPU clock to PLL if we are VDD5V is sourced
+ * from USB VBUS
+ */
+ mxs_power_clock2pll();
+
+ mxs_init_batt_bo();
+
+ mxs_switch_vddd_to_dcdc_source();
+
+#ifdef CONFIG_MX23
+ /* Fire up the VDDMEM LinReg now that we're all set. */
+ debug("SPL: Enabling mx23 VDDMEM linear regulator\n");
+ writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT,
+ &power_regs->hw_power_vddmemctrl);
+#endif
+}
+
+/**
+ * mxs_enable_output_rail_protection() - Enable power rail protection
+ *
+ * This function enables overload protection on the power rails. This is
+ * triggered if the power rails' voltage drops rapidly due to overload and
+ * in such case, the supply to the powerrail is cut-off, protecting the
+ * CPU from damage. Note that under such condition, the system will likely
+ * crash or misbehave.
+ */
+static void mxs_enable_output_rail_protection(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Enabling output rail protection\n");
+
+ writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
+ POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
+
+ setbits_le32(&power_regs->hw_power_vdddctrl,
+ POWER_VDDDCTRL_PWDN_BRNOUT);
+
+ setbits_le32(&power_regs->hw_power_vddactrl,
+ POWER_VDDACTRL_PWDN_BRNOUT);
+
+ setbits_le32(&power_regs->hw_power_vddioctrl,
+ POWER_VDDIOCTRL_PWDN_BRNOUT);
+}
+
+/**
+ * mxs_get_vddio_power_source_off() - Get VDDIO rail power source
+ *
+ * This function tests if the VDDIO rail is supplied by linear regulator
+ * or by the DC-DC converter. Returns 1 if powered by linear regulator,
+ * returns 0 if powered by the DC-DC converter.
+ */
+static int mxs_get_vddio_power_source_off(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+ uint32_t tmp;
+
+ if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+ tmp = readl(&power_regs->hw_power_vddioctrl);
+ if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
+ if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
+ POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
+ return 1;
+ }
+ }
+
+ if (!(readl(&power_regs->hw_power_5vctrl) &
+ POWER_5VCTRL_ENABLE_DCDC)) {
+ if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
+ POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+
+}
+
+/**
+ * mxs_get_vddd_power_source_off() - Get VDDD rail power source
+ *
+ * This function tests if the VDDD rail is supplied by linear regulator
+ * or by the DC-DC converter. Returns 1 if powered by linear regulator,
+ * returns 0 if powered by the DC-DC converter.
+ */
+static int mxs_get_vddd_power_source_off(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+ uint32_t tmp;
+
+ tmp = readl(&power_regs->hw_power_vdddctrl);
+ if (tmp & POWER_VDDDCTRL_DISABLE_FET) {
+ if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
+ POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
+ return 1;
+ }
+ }
+
+ if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+ if (!(readl(&power_regs->hw_power_5vctrl) &
+ POWER_5VCTRL_ENABLE_DCDC)) {
+ return 1;
+ }
+ }
+
+ if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) {
+ if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
+ POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+struct mxs_vddx_cfg {
+ uint32_t *reg;
+ uint8_t step_mV;
+ uint16_t lowest_mV;
+ int (*powered_by_linreg)(void);
+ uint32_t trg_mask;
+ uint32_t bo_irq;
+ uint32_t bo_enirq;
+ uint32_t bo_offset_mask;
+ uint32_t bo_offset_offset;
+};
+
+static const struct mxs_vddx_cfg mxs_vddio_cfg = {
+ .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
+ hw_power_vddioctrl),
+#if defined(CONFIG_MX23)
+ .step_mV = 25,
+#else
+ .step_mV = 50,
+#endif
+ .lowest_mV = 2800,
+ .powered_by_linreg = mxs_get_vddio_power_source_off,
+ .trg_mask = POWER_VDDIOCTRL_TRG_MASK,
+ .bo_irq = POWER_CTRL_VDDIO_BO_IRQ,
+ .bo_enirq = POWER_CTRL_ENIRQ_VDDIO_BO,
+ .bo_offset_mask = POWER_VDDIOCTRL_BO_OFFSET_MASK,
+ .bo_offset_offset = POWER_VDDIOCTRL_BO_OFFSET_OFFSET,
+};
+
+static const struct mxs_vddx_cfg mxs_vddd_cfg = {
+ .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
+ hw_power_vdddctrl),
+ .step_mV = 25,
+ .lowest_mV = 800,
+ .powered_by_linreg = mxs_get_vddd_power_source_off,
+ .trg_mask = POWER_VDDDCTRL_TRG_MASK,
+ .bo_irq = POWER_CTRL_VDDD_BO_IRQ,
+ .bo_enirq = POWER_CTRL_ENIRQ_VDDD_BO,
+ .bo_offset_mask = POWER_VDDDCTRL_BO_OFFSET_MASK,
+ .bo_offset_offset = POWER_VDDDCTRL_BO_OFFSET_OFFSET,
+};
+
+#ifdef CONFIG_MX23
+static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
+ .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
+ hw_power_vddmemctrl),
+ .step_mV = 50,
+ .lowest_mV = 1700,
+ .powered_by_linreg = NULL,
+ .trg_mask = POWER_VDDMEMCTRL_TRG_MASK,
+ .bo_irq = 0,
+ .bo_enirq = 0,
+ .bo_offset_mask = 0,
+ .bo_offset_offset = 0,
+};
+#endif
+
+/**
+ * mxs_power_set_vddx() - Configure voltage on DC-DC converter rail
+ * @cfg: Configuration data of the DC-DC converter rail
+ * @new_target: New target voltage of the DC-DC converter rail
+ * @new_brownout: New brownout trigger voltage
+ *
+ * This function configures the output voltage on the DC-DC converter rail.
+ * The rail is selected by the @cfg argument. The new voltage target is
+ * selected by the @new_target and the voltage is specified in mV. The
+ * new brownout value is selected by the @new_brownout argument and the
+ * value is also in mV.
+ */
+static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
+ uint32_t new_target, uint32_t new_brownout)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+ uint32_t cur_target, diff, bo_int = 0;
+ uint32_t powered_by_linreg = 0;
+ int adjust_up, tmp;
+
+ new_brownout = DIV_ROUND_CLOSEST(new_target - new_brownout,
+ cfg->step_mV);
+
+ cur_target = readl(cfg->reg);
+ cur_target &= cfg->trg_mask;
+ cur_target *= cfg->step_mV;
+ cur_target += cfg->lowest_mV;
+
+ adjust_up = new_target > cur_target;
+ if (cfg->powered_by_linreg)
+ powered_by_linreg = cfg->powered_by_linreg();
+
+ if (adjust_up && cfg->bo_irq) {
+ if (powered_by_linreg) {
+ bo_int = readl(cfg->reg);
+ clrbits_le32(cfg->reg, cfg->bo_enirq);
+ }
+ setbits_le32(cfg->reg, cfg->bo_offset_mask);
+ }
+
+ do {
+ if (abs(new_target - cur_target) > 100) {
+ if (adjust_up)
+ diff = cur_target + 100;
+ else
+ diff = cur_target - 100;
+ } else {
+ diff = new_target;
+ }
+
+ diff -= cfg->lowest_mV;
+ diff /= cfg->step_mV;
+
+ clrsetbits_le32(cfg->reg, cfg->trg_mask, diff);
+
+ if (powered_by_linreg ||
+ (readl(&power_regs->hw_power_sts) &
+ POWER_STS_VDD5V_GT_VDDIO))
+ early_delay(500);
+ else {
+ for (;;) {
+ tmp = readl(&power_regs->hw_power_sts);
+ if (tmp & POWER_STS_DC_OK)
+ break;
+ }
+ }
+
+ cur_target = readl(cfg->reg);
+ cur_target &= cfg->trg_mask;
+ cur_target *= cfg->step_mV;
+ cur_target += cfg->lowest_mV;
+ } while (new_target > cur_target);
+
+ if (cfg->bo_irq) {
+ if (adjust_up && powered_by_linreg) {
+ writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr);
+ if (bo_int & cfg->bo_enirq)
+ setbits_le32(cfg->reg, cfg->bo_enirq);
+ }
+
+ clrsetbits_le32(cfg->reg, cfg->bo_offset_mask,
+ new_brownout << cfg->bo_offset_offset);
+ }
+}
+
+/**
+ * mxs_setup_batt_detect() - Start the battery voltage measurement logic
+ *
+ * This function starts and configures the LRADC block. This allows the
+ * power initialization code to measure battery voltage and based on this
+ * knowledge, decide whether to boot at all, boot from battery or boot
+ * from 5V input.
+ */
+static void mxs_setup_batt_detect(void)
+{
+ debug("SPL: Starting battery voltage measurement logic\n");
+
+ mxs_lradc_init();
+ mxs_lradc_enable_batt_measurement();
+ early_delay(10);
+}
+
+/**
+ * mxs_ungate_power() - Ungate the POWER block
+ *
+ * This function ungates clock to the power block. In case the power block
+ * was still gated at this point, it will not be possible to configure the
+ * block and therefore the power initialization would fail. This function
+ * is only needed on i.MX233, on i.MX28 the power block is always ungated.
+ */
+static void mxs_ungate_power(void)
+{
+#ifdef CONFIG_MX23
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ writel(POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr);
+#endif
+}
+
+/**
+ * mxs_power_init() - The power block init main function
+ *
+ * This function calls all the power block initialization functions in
+ * proper sequence to start the power block.
+ */
+void mxs_power_init(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Initialising Power Block\n");
+
+ mxs_ungate_power();
+
+ mxs_power_clock2xtal();
+ mxs_power_set_auto_restart();
+ mxs_power_set_linreg();
+ mxs_power_setup_5v_detect();
+
+ mxs_setup_batt_detect();
+
+ mxs_power_configure_power_source();
+ mxs_enable_output_rail_protection();
+
+ debug("SPL: Setting VDDIO to 3V3 (brownout @ 3v15)\n");
+ mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
+
+ debug("SPL: Setting VDDD to 1V55 (brownout @ 1v400)\n");
+ mxs_power_set_vddx(&mxs_vddd_cfg, 1550, 1400);
+#ifdef CONFIG_MX23
+ debug("SPL: Setting mx23 VDDMEM to 2V5 (brownout @ 1v7)\n");
+ mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700);
+#endif
+ writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
+ POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
+ POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
+ POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
+
+ writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
+
+ early_delay(1000);
+}
+
+#ifdef CONFIG_SPL_MXS_PSWITCH_WAIT
+/**
+ * mxs_power_wait_pswitch() - Wait for power switch to be pressed
+ *
+ * This function waits until the power-switch was pressed to start booting
+ * the board.
+ */
+void mxs_power_wait_pswitch(void)
+{
+ struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+
+ debug("SPL: Waiting for power switch input\n");
+ while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
+ ;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/start.S b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/start.S
new file mode 100644
index 000000000..adec2c8ad
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/start.S
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * armboot - Startup Code for ARM926EJS CPU-core
+ *
+ * Copyright (c) 2003 Texas Instruments
+ *
+ * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
+ *
+ * Copyright (c) 2001 Marius Groger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Zupke <azu@sysgo.de>
+ * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
+ * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
+ * Copyright (c) 2003 Kshitij <kshitij@ti.com>
+ * Copyright (c) 2010 Albert Aribaud <albert.u.boot@aribaud.net>
+ *
+ * Change to support call back into iMX28 bootrom
+ * Copyright (c) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <common.h>
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * setup Memory and board specific bits prior to relocation.
+ * relocate armboot to ram
+ * setup stack
+ *
+ *************************************************************************
+ */
+
+ .globl reset
+reset:
+ /*
+ * If the CPU is configured in "Wait JTAG connection mode", the stack
+ * pointer is not configured and is zero. This will cause crash when
+ * trying to push data onto stack right below here. Load the SP and make
+ * it point to the end of OCRAM if the SP is zero.
+ */
+ cmp sp, #0x00000000
+ ldreq sp, =CONFIG_SYS_INIT_SP_ADDR
+
+ /*
+ * Store all registers on old stack pointer, this will allow us later to
+ * return to the BootROM and let the BootROM load U-Boot into RAM.
+ *
+ * WARNING: Register r0 and r1 are used by the BootROM to pass data
+ * to the called code. Register r0 will contain arbitrary
+ * data that are set in the BootStream. In case this code
+ * was started with CALL instruction, register r1 will contain
+ * pointer to the return value this function can then set.
+ * The code below MUST NOT CHANGE register r0 and r1 !
+ */
+ push {r0-r12,r14}
+
+ /* Save control register c1 */
+ mrc p15, 0, r2, c1, c0, 0
+ push {r2}
+
+ /* Set the cpu to SVC32 mode and store old CPSR register content. */
+ mrs r2, cpsr
+ push {r2}
+ bic r2, r2, #0x1f
+ orr r2, r2, #0xd3
+ msr cpsr, r2
+
+ bl board_init_ll
+
+ /* Restore BootROM's CPU mode (especially FIQ). */
+ pop {r2}
+ msr cpsr,r2
+
+ /*
+ * Restore c1 register. Especially set exception vector location
+ * back to BootROM space which is required by bootrom for USB boot.
+ */
+ pop {r2}
+ mcr p15, 0, r2, c1, c0, 0
+
+ pop {r0-r12,r14}
+
+ /*
+ * In case this code was started by the CALL instruction, the register
+ * r0 is examined by the BootROM after this code returns. The value in
+ * r0 must be set to 0 to indicate successful return.
+ */
+ mov r0, #0
+
+ bx lr
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/timer.c b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/timer.c
new file mode 100644
index 000000000..3dff3d768
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/timer.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Freescale i.MX28 timer driver
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * Based on code from LTIB:
+ * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+#include <linux/delay.h>
+
+/* Maximum fixed count */
+#if defined(CONFIG_MX23)
+#define TIMER_LOAD_VAL 0xffff
+#elif defined(CONFIG_MX28)
+#define TIMER_LOAD_VAL 0xffffffff
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define timestamp (gd->arch.tbl)
+#define lastdec (gd->arch.lastinc)
+
+/*
+ * This driver uses 1kHz clock source.
+ */
+#define MXS_INCREMENTER_HZ 1000
+
+static inline unsigned long tick_to_time(unsigned long tick)
+{
+ return tick / (MXS_INCREMENTER_HZ / CONFIG_SYS_HZ);
+}
+
+static inline unsigned long time_to_tick(unsigned long time)
+{
+ return time * (MXS_INCREMENTER_HZ / CONFIG_SYS_HZ);
+}
+
+/* Calculate how many ticks happen in "us" microseconds */
+static inline unsigned long us_to_tick(unsigned long us)
+{
+ return (us * MXS_INCREMENTER_HZ) / 1000000;
+}
+
+int timer_init(void)
+{
+ struct mxs_timrot_regs *timrot_regs =
+ (struct mxs_timrot_regs *)MXS_TIMROT_BASE;
+
+ /* Reset Timers and Rotary Encoder module */
+ mxs_reset_block(&timrot_regs->hw_timrot_rotctrl_reg);
+
+ /* Set fixed_count to 0 */
+#if defined(CONFIG_MX23)
+ writel(0, &timrot_regs->hw_timrot_timcount0);
+#elif defined(CONFIG_MX28)
+ writel(0, &timrot_regs->hw_timrot_fixed_count0);
+#endif
+
+ /* Set UPDATE bit and 1Khz frequency */
+ writel(TIMROT_TIMCTRLn_UPDATE | TIMROT_TIMCTRLn_RELOAD |
+ TIMROT_TIMCTRLn_SELECT_1KHZ_XTAL,
+ &timrot_regs->hw_timrot_timctrl0);
+
+ /* Set fixed_count to maximal value */
+#if defined(CONFIG_MX23)
+ writel(TIMER_LOAD_VAL - 1, &timrot_regs->hw_timrot_timcount0);
+#elif defined(CONFIG_MX28)
+ writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
+#endif
+
+ return 0;
+}
+
+unsigned long long get_ticks(void)
+{
+ struct mxs_timrot_regs *timrot_regs =
+ (struct mxs_timrot_regs *)MXS_TIMROT_BASE;
+ uint32_t now;
+
+ /* Current tick value */
+#if defined(CONFIG_MX23)
+ /* Upper bits are the valid ones. */
+ now = readl(&timrot_regs->hw_timrot_timcount0) >>
+ TIMROT_RUNNING_COUNTn_RUNNING_COUNT_OFFSET;
+#elif defined(CONFIG_MX28)
+ now = readl(&timrot_regs->hw_timrot_running_count0);
+#else
+#error "Don't know how to read timrot_regs"
+#endif
+
+ if (lastdec >= now) {
+ /*
+ * normal mode (non roll)
+ * move stamp forward with absolut diff ticks
+ */
+ timestamp += (lastdec - now);
+ } else {
+ /* we have rollover of decrementer */
+ timestamp += (TIMER_LOAD_VAL - now) + lastdec;
+
+ }
+ lastdec = now;
+
+ return timestamp;
+}
+
+ulong get_timer(ulong base)
+{
+ return tick_to_time(get_ticks()) - base;
+}
+
+/* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */
+#define MXS_HW_DIGCTL_MICROSECONDS 0x8001c0c0
+
+void __udelay(unsigned long usec)
+{
+ uint32_t old, new, incr;
+ uint32_t counter = 0;
+
+ old = readl(MXS_HW_DIGCTL_MICROSECONDS);
+
+ while (counter < usec) {
+ new = readl(MXS_HW_DIGCTL_MICROSECONDS);
+
+ /* Check if the timer wrapped. */
+ if (new < old) {
+ incr = 0xffffffff - old;
+ incr += new;
+ } else {
+ incr = new - old;
+ }
+
+ /*
+ * Check if we are close to the maximum time and the counter
+ * would wrap if incremented. If that's the case, break out
+ * from the loop as the requested delay time passed.
+ */
+ if (counter + incr < counter)
+ break;
+
+ counter += incr;
+ old = new;
+ }
+}
+
+ulong get_tbclk(void)
+{
+ return MXS_INCREMENTER_HZ;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/u-boot-imx23.bd b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/u-boot-imx23.bd
new file mode 100644
index 000000000..3a51879d5
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/u-boot-imx23.bd
@@ -0,0 +1,18 @@
+options {
+ driveTag = 0x00;
+ flags = 0x01;
+}
+
+sources {
+ u_boot_spl="spl/u-boot-spl.bin";
+ u_boot="u-boot.bin";
+}
+
+section (0) {
+ load u_boot_spl > 0x0000;
+ load ivt (entry = 0x0014) > 0x8000;
+ call 0x8000;
+
+ load u_boot > 0x40000100;
+ call 0x40000100;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd
new file mode 100644
index 000000000..c60615a45
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd
@@ -0,0 +1,14 @@
+sources {
+ u_boot_spl="spl/u-boot-spl.bin";
+ u_boot="u-boot.bin";
+}
+
+section (0) {
+ load u_boot_spl > 0x0000;
+ load ivt (entry = 0x0014) > 0x8000;
+ hab call 0x8000;
+
+ load u_boot > 0x40000100;
+ load ivt (entry = 0x40000100) > 0x8000;
+ hab call 0x8000;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds
new file mode 100644
index 000000000..7e20448f8
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * January 2004 - Changed to support H4 device
+ * Copyright (c) 2004-2008 Texas Instruments
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = IMAGE_TEXT_BASE;
+
+ . = ALIGN(4);
+ .text :
+ {
+ *(.vectors)
+ arch/arm/cpu/arm926ejs/mxs/start.o (.text*)
+ *(.text*)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+ . = ALIGN(4);
+ .data : {
+ *(.data*)
+ }
+
+ . = ALIGN(4);
+
+ .rel.dyn : {
+ __rel_dyn_start = .;
+ *(.rel*)
+ __rel_dyn_end = .;
+ }
+
+ .bss : {
+ . = ALIGN(4);
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_end = .;
+ }
+
+ .end :
+ {
+ *(.__end)
+ }
+
+ _image_binary_end = .;
+
+ .dynsym _image_binary_end : { *(.dynsym) }
+ .dynbss : { *(.dynbss) }
+ .dynstr : { *(.dynstr*) }
+ .dynamic : { *(.dynamic*) }
+ .hash : { *(.hash*) }
+ .plt : { *(.plt*) }
+ .interp : { *(.interp*) }
+ .gnu : { *(.gnu*) }
+ .ARM.exidx : { *(.ARM.exidx*) }
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/Makefile b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/Makefile
new file mode 100644
index 000000000..b1b6b4028
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/Makefile
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+obj-y := cpu.o \
+ reset.o \
+ timer.o
+
+ifdef CONFIG_SPL_BUILD
+obj-y += spl.o
+obj-$(CONFIG_SPEAR600) += spear600.o
+obj-$(CONFIG_DDR_MT47H64M16) += spr600_mt47h64m16_3_333_cl5_psync.o
+obj-$(CONFIG_DDR_MT47H32M16) += spr600_mt47h32m16_333_cl5_psync.o
+obj-$(CONFIG_DDR_MT47H32M16) += spr600_mt47h32m16_37e_166_cl4_sync.o
+obj-$(CONFIG_DDR_MT47H128M8) += spr600_mt47h128m8_3_266_cl5_async.o
+else
+obj-y += spr_misc.o spr_lowlevel_init.o
+endif
+
+extra-$(CONFIG_SPL_BUILD) := start.o
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/cpu.c b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/cpu.c
new file mode 100644
index 000000000..210654107
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/cpu.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2010
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spr_misc.h>
+
+int arch_cpu_init(void)
+{
+ struct misc_regs *const misc_p =
+ (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+ u32 periph1_clken, periph_clk_cfg;
+
+ periph1_clken = readl(&misc_p->periph1_clken);
+
+#if defined(CONFIG_SPEAR3XX)
+ periph1_clken |= MISC_GPT2ENB;
+#elif defined(CONFIG_SPEAR600)
+ periph1_clken |= MISC_GPT3ENB;
+#endif
+
+#if defined(CONFIG_PL011_SERIAL)
+ periph1_clken |= MISC_UART0ENB;
+
+ periph_clk_cfg = readl(&misc_p->periph_clk_cfg);
+ periph_clk_cfg &= ~CONFIG_SPEAR_UARTCLKMSK;
+ periph_clk_cfg |= CONFIG_SPEAR_UART48M;
+ writel(periph_clk_cfg, &misc_p->periph_clk_cfg);
+#endif
+#if defined(CONFIG_ETH_DESIGNWARE)
+ periph1_clken |= MISC_ETHENB;
+#endif
+#if defined(CONFIG_DW_UDC)
+ periph1_clken |= MISC_USBDENB;
+#endif
+#if defined(CONFIG_SYS_I2C_DW)
+ periph1_clken |= MISC_I2CENB;
+#endif
+#if defined(CONFIG_ST_SMI)
+ periph1_clken |= MISC_SMIENB;
+#endif
+#if defined(CONFIG_NAND_FSMC)
+ periph1_clken |= MISC_FSMCENB;
+#endif
+#if defined(CONFIG_USB_EHCI_SPEAR)
+ periph1_clken |= PERIPH_USBH1 | PERIPH_USBH2;
+#endif
+#if defined(CONFIG_SPEAR_GPIO)
+ periph1_clken |= MISC_GPIO3ENB | MISC_GPIO4ENB;
+#endif
+#if defined(CONFIG_PL022_SPI)
+ periph1_clken |= MISC_SSP1ENB | MISC_SSP2ENB | MISC_SSP3ENB;
+#endif
+
+ writel(periph1_clken, &misc_p->periph1_clken);
+
+ return 0;
+}
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+#ifdef CONFIG_SPEAR300
+ printf("CPU: SPEAr300\n");
+#elif defined(CONFIG_SPEAR310)
+ printf("CPU: SPEAr310\n");
+#elif defined(CONFIG_SPEAR320)
+ printf("CPU: SPEAr320\n");
+#elif defined(CONFIG_SPEAR600)
+ printf("CPU: SPEAr600\n");
+#else
+#error CPU not supported in spear platform
+#endif
+ return 0;
+}
+#endif
+
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_NAND_ECC_BCH) && defined(CONFIG_NAND_FSMC)
+static int do_switch_ecc(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ if (argc != 2)
+ goto usage;
+
+ if (strncmp(argv[1], "hw", 2) == 0) {
+ /* 1-bit HW ECC */
+ printf("Switching to 1-bit HW ECC\n");
+ fsmc_nand_switch_ecc(1);
+ } else if (strncmp(argv[1], "bch4", 2) == 0) {
+ /* 4-bit SW ECC BCH4 */
+ printf("Switching to 4-bit SW ECC (BCH4)\n");
+ fsmc_nand_switch_ecc(4);
+ } else {
+ goto usage;
+ }
+
+ return 0;
+
+usage:
+ printf("Usage: nandecc %s\n", cmdtp->usage);
+ return 1;
+}
+
+U_BOOT_CMD(
+ nandecc, 2, 0, do_switch_ecc,
+ "switch NAND ECC calculation algorithm",
+ "hw|bch4 - Switch between NAND hardware 1-bit HW and"
+ " 4-bit SW BCH\n"
+);
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/reset.c b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/reset.c
new file mode 100644
index 000000000..97a624e16
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/reset.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spr_syscntl.h>
+#include <linux/delay.h>
+
+void reset_cpu(void)
+{
+ struct syscntl_regs *syscntl_regs_p =
+ (struct syscntl_regs *)CONFIG_SPEAR_SYSCNTLBASE;
+
+ printf("System is going to reboot ...\n");
+
+ /*
+ * This 1 second delay will allow the above message
+ * to be printed before reset
+ */
+ udelay((1000 * 1000));
+
+ /* Going into slow mode before resetting SOC */
+ writel(0x02, &syscntl_regs_p->scctrl);
+
+ /*
+ * Writing any value to the system status register will
+ * reset the SoC
+ */
+ writel(0x00, &syscntl_regs_p->scsysstat);
+
+ /* system will restart */
+ while (1)
+ ;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spear600.c b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spear600.c
new file mode 100644
index 000000000..b31ede5eb
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spear600.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000-2009
+ * Viresh Kumar, ST Microelectronics, viresh.kumar@st.com
+ * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com
+ */
+
+#include <common.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/spr_misc.h>
+#include <asm/arch/spr_defs.h>
+
+void spear_late_init(void)
+{
+ struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+
+ writel(0x80000007, &misc_p->arb_icm_ml1);
+ writel(0x80000007, &misc_p->arb_icm_ml2);
+ writel(0x80000007, &misc_p->arb_icm_ml3);
+ writel(0x80000007, &misc_p->arb_icm_ml4);
+ writel(0x80000007, &misc_p->arb_icm_ml5);
+ writel(0x80000007, &misc_p->arb_icm_ml6);
+ writel(0x80000007, &misc_p->arb_icm_ml7);
+ writel(0x80000007, &misc_p->arb_icm_ml8);
+ writel(0x80000007, &misc_p->arb_icm_ml9);
+}
+
+static void sel_1v8(void)
+{
+ struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+ u32 ddr1v8, ddr2v5;
+
+ ddr2v5 = readl(&misc_p->ddr_2v5_compensation);
+ ddr2v5 &= 0x8080ffc0;
+ ddr2v5 |= 0x78000003;
+ writel(ddr2v5, &misc_p->ddr_2v5_compensation);
+
+ ddr1v8 = readl(&misc_p->ddr_1v8_compensation);
+ ddr1v8 &= 0x8080ffc0;
+ ddr1v8 |= 0x78000010;
+ writel(ddr1v8, &misc_p->ddr_1v8_compensation);
+
+ while (!(readl(&misc_p->ddr_1v8_compensation) & DDR_COMP_ACCURATE))
+ ;
+}
+
+static void sel_2v5(void)
+{
+ struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+ u32 ddr1v8, ddr2v5;
+
+ ddr1v8 = readl(&misc_p->ddr_1v8_compensation);
+ ddr1v8 &= 0x8080ffc0;
+ ddr1v8 |= 0x78000003;
+ writel(ddr1v8, &misc_p->ddr_1v8_compensation);
+
+ ddr2v5 = readl(&misc_p->ddr_2v5_compensation);
+ ddr2v5 &= 0x8080ffc0;
+ ddr2v5 |= 0x78000010;
+ writel(ddr2v5, &misc_p->ddr_2v5_compensation);
+
+ while (!(readl(&misc_p->ddr_2v5_compensation) & DDR_COMP_ACCURATE))
+ ;
+}
+
+/*
+ * plat_ddr_init:
+ */
+void plat_ddr_init(void)
+{
+ struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+ u32 ddrpad;
+ u32 core3v3, ddr1v8, ddr2v5;
+
+ /* DDR pad register configurations */
+ ddrpad = readl(&misc_p->ddr_pad);
+ ddrpad &= ~DDR_PAD_CNF_MSK;
+
+#if (CONFIG_DDR_HCLK)
+ ddrpad |= 0xEAAB;
+#elif (CONFIG_DDR_2HCLK)
+ ddrpad |= 0xEAAD;
+#elif (CONFIG_DDR_PLL2)
+ ddrpad |= 0xEAAD;
+#endif
+ writel(ddrpad, &misc_p->ddr_pad);
+
+ /* Compensation register configurations */
+ core3v3 = readl(&misc_p->core_3v3_compensation);
+ core3v3 &= 0x8080ffe0;
+ core3v3 |= 0x78000002;
+ writel(core3v3, &misc_p->core_3v3_compensation);
+
+ ddr1v8 = readl(&misc_p->ddr_1v8_compensation);
+ ddr1v8 &= 0x8080ffc0;
+ ddr1v8 |= 0x78000004;
+ writel(ddr1v8, &misc_p->ddr_1v8_compensation);
+
+ ddr2v5 = readl(&misc_p->ddr_2v5_compensation);
+ ddr2v5 &= 0x8080ffc0;
+ ddr2v5 |= 0x78000004;
+ writel(ddr2v5, &misc_p->ddr_2v5_compensation);
+
+ if ((readl(&misc_p->ddr_pad) & DDR_PAD_SW_CONF) == DDR_PAD_SW_CONF) {
+ /* Software memory configuration */
+ if (readl(&misc_p->ddr_pad) & DDR_PAD_SSTL_SEL)
+ sel_1v8();
+ else
+ sel_2v5();
+ } else {
+ /* Hardware memory configuration */
+ if (readl(&misc_p->ddr_pad) & DDR_PAD_DRAM_TYPE)
+ sel_1v8();
+ else
+ sel_2v5();
+ }
+}
+
+/*
+ * xxx_boot_selected:
+ *
+ * return true if the particular booting option is selected
+ * return false otherwise
+ */
+static u32 read_bootstrap(void)
+{
+ return (readl(CONFIG_SPEAR_BOOTSTRAPCFG) >> CONFIG_SPEAR_BOOTSTRAPSHFT)
+ & CONFIG_SPEAR_BOOTSTRAPMASK;
+}
+
+int snor_boot_selected(void)
+{
+ u32 bootstrap = read_bootstrap();
+
+ if (SNOR_BOOT_SUPPORTED) {
+ /* Check whether SNOR boot is selected */
+ if ((bootstrap & CONFIG_SPEAR_ONLYSNORBOOT) ==
+ CONFIG_SPEAR_ONLYSNORBOOT)
+ return true;
+
+ if ((bootstrap & CONFIG_SPEAR_NORNANDBOOT) ==
+ CONFIG_SPEAR_NORNAND8BOOT)
+ return true;
+
+ if ((bootstrap & CONFIG_SPEAR_NORNANDBOOT) ==
+ CONFIG_SPEAR_NORNAND16BOOT)
+ return true;
+ }
+
+ return false;
+}
+
+int nand_boot_selected(void)
+{
+ u32 bootstrap = read_bootstrap();
+
+ if (NAND_BOOT_SUPPORTED) {
+ /* Check whether NAND boot is selected */
+ if ((bootstrap & CONFIG_SPEAR_NORNANDBOOT) ==
+ CONFIG_SPEAR_NORNAND8BOOT)
+ return true;
+
+ if ((bootstrap & CONFIG_SPEAR_NORNANDBOOT) ==
+ CONFIG_SPEAR_NORNAND16BOOT)
+ return true;
+ }
+
+ return false;
+}
+
+int pnor_boot_selected(void)
+{
+ /* Parallel NOR boot is not selected in any SPEAr600 revision */
+ return false;
+}
+
+int usb_boot_selected(void)
+{
+ u32 bootstrap = read_bootstrap();
+
+ if (USB_BOOT_SUPPORTED) {
+ /* Check whether USB boot is selected */
+ if (!(bootstrap & CONFIG_SPEAR_USBBOOT))
+ return true;
+ }
+
+ return false;
+}
+
+int tftp_boot_selected(void)
+{
+ /* TFTP boot is not selected in any SPEAr600 revision */
+ return false;
+}
+
+int uart_boot_selected(void)
+{
+ /* UART boot is not selected in any SPEAr600 revision */
+ return false;
+}
+
+int spi_boot_selected(void)
+{
+ /* SPI boot is not selected in any SPEAr600 revision */
+ return false;
+}
+
+int i2c_boot_selected(void)
+{
+ /* I2C boot is not selected in any SPEAr600 revision */
+ return false;
+}
+
+int mmc_boot_selected(void)
+{
+ return false;
+}
+
+void plat_late_init(void)
+{
+ spear_late_init();
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spl.c b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spl.c
new file mode 100644
index 000000000..b5b9945a8
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spl.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2011
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Copyright (C) 2012 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <spl.h>
+#include <version.h>
+#include <asm/io.h>
+#include <asm/ptrace.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spr_defs.h>
+#include <asm/arch/spr_misc.h>
+#include <asm/arch/spr_syscntl.h>
+#include <linux/mtd/st_smi.h>
+
+/* Reserve some space to store the BootROM's stack pointer during SPL operation.
+ * The BSS cannot be used for this purpose because it will be zeroed after
+ * having stored the pointer, so force the location to the data section.
+ */
+u32 bootrom_stash_sp __section(".data");
+
+static void ddr_clock_init(void)
+{
+ struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+ u32 clkenb, ddrpll;
+
+ clkenb = readl(&misc_p->periph1_clken);
+ clkenb &= ~PERIPH_MPMCMSK;
+ clkenb |= PERIPH_MPMC_WE;
+
+ /* Intentionally done twice */
+ writel(clkenb, &misc_p->periph1_clken);
+ writel(clkenb, &misc_p->periph1_clken);
+
+ ddrpll = readl(&misc_p->pll_ctr_reg);
+ ddrpll &= ~MEM_CLK_SEL_MSK;
+#if (CONFIG_DDR_HCLK)
+ ddrpll |= MEM_CLK_HCLK;
+#elif (CONFIG_DDR_2HCLK)
+ ddrpll |= MEM_CLK_2HCLK;
+#elif (CONFIG_DDR_PLL2)
+ ddrpll |= MEM_CLK_PLL2;
+#else
+#error "please define one of CONFIG_DDR_(HCLK|2HCLK|PLL2)"
+#endif
+ writel(ddrpll, &misc_p->pll_ctr_reg);
+
+ writel(readl(&misc_p->periph1_clken) | PERIPH_MPMC_EN,
+ &misc_p->periph1_clken);
+}
+
+static void mpmc_init_values(void)
+{
+ u32 i;
+ u32 *mpmc_reg_p = (u32 *)CONFIG_SPEAR_MPMCBASE;
+ u32 *mpmc_val_p = &mpmc_conf_vals[0];
+
+ for (i = 0; i < CONFIG_SPEAR_MPMCREGS; i++, mpmc_reg_p++, mpmc_val_p++)
+ writel(*mpmc_val_p, mpmc_reg_p);
+
+ mpmc_reg_p = (u32 *)CONFIG_SPEAR_MPMCBASE;
+
+ /*
+ * MPMC controller start
+ * MPMC waiting for DLLLOCKREG high
+ */
+ writel(0x01000100, &mpmc_reg_p[7]);
+
+ while (!(readl(&mpmc_reg_p[3]) & 0x10000))
+ ;
+}
+
+static void mpmc_init(void)
+{
+ /* Clock related settings for DDR */
+ ddr_clock_init();
+
+ /*
+ * DDR pad register bits are different for different SoCs
+ * Compensation values are also handled separately
+ */
+ plat_ddr_init();
+
+ /* Initialize mpmc register values */
+ mpmc_init_values();
+}
+
+static void pll_init(void)
+{
+ struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+
+ /* Initialize PLLs */
+ writel(FREQ_332, &misc_p->pll1_frq);
+ writel(0x1C0A, &misc_p->pll1_cntl);
+ writel(0x1C0E, &misc_p->pll1_cntl);
+ writel(0x1C06, &misc_p->pll1_cntl);
+ writel(0x1C0E, &misc_p->pll1_cntl);
+
+ writel(FREQ_332, &misc_p->pll2_frq);
+ writel(0x1C0A, &misc_p->pll2_cntl);
+ writel(0x1C0E, &misc_p->pll2_cntl);
+ writel(0x1C06, &misc_p->pll2_cntl);
+ writel(0x1C0E, &misc_p->pll2_cntl);
+
+ /* wait for pll locks */
+ while (!(readl(&misc_p->pll1_cntl) & 0x1))
+ ;
+ while (!(readl(&misc_p->pll2_cntl) & 0x1))
+ ;
+}
+
+static void mac_init(void)
+{
+ struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+
+ writel(readl(&misc_p->periph1_clken) & (~PERIPH_GMAC),
+ &misc_p->periph1_clken);
+
+ writel(SYNTH23, &misc_p->gmac_synth_clk);
+
+ switch (get_socrev()) {
+ case SOC_SPEAR600_AA:
+ case SOC_SPEAR600_AB:
+ case SOC_SPEAR600_BA:
+ case SOC_SPEAR600_BB:
+ case SOC_SPEAR600_BC:
+ case SOC_SPEAR600_BD:
+ writel(0x0, &misc_p->gmac_ctr_reg);
+ break;
+
+ case SOC_SPEAR300:
+ case SOC_SPEAR310:
+ case SOC_SPEAR320:
+ writel(0x4, &misc_p->gmac_ctr_reg);
+ break;
+ }
+
+ writel(readl(&misc_p->periph1_clken) | PERIPH_GMAC,
+ &misc_p->periph1_clken);
+
+ writel(readl(&misc_p->periph1_rst) | PERIPH_GMAC,
+ &misc_p->periph1_rst);
+ writel(readl(&misc_p->periph1_rst) & (~PERIPH_GMAC),
+ &misc_p->periph1_rst);
+}
+
+static void sys_init(void)
+{
+ struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+ struct syscntl_regs *syscntl_p =
+ (struct syscntl_regs *)CONFIG_SPEAR_SYSCNTLBASE;
+
+ /* Set system state to SLOW */
+ writel(SLOW, &syscntl_p->scctrl);
+ writel(PLL_TIM << 3, &syscntl_p->scpllctrl);
+
+ /* Initialize PLLs */
+ pll_init();
+
+ /*
+ * Ethernet configuration
+ * To be done only if the tftp boot is not selected already
+ * Boot code ensures the correct configuration in tftp booting
+ */
+ if (!tftp_boot_selected())
+ mac_init();
+
+ writel(RTC_DISABLE | PLLTIMEEN, &misc_p->periph_clk_cfg);
+ writel(0x555, &misc_p->amba_clk_cfg);
+
+ writel(NORMAL, &syscntl_p->scctrl);
+
+ /* Wait for system to switch to normal mode */
+ while (((readl(&syscntl_p->scctrl) >> MODE_SHIFT) & MODE_MASK)
+ != NORMAL)
+ ;
+}
+
+/*
+ * get_socrev
+ *
+ * Get SoC Revision.
+ * @return SOC_SPEARXXX
+ */
+int get_socrev(void)
+{
+#if defined(CONFIG_SPEAR600)
+ struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+ u32 soc_id = readl(&misc_p->soc_core_id);
+ u32 pri_socid = (soc_id >> SOC_PRI_SHFT) & 0xFF;
+ u32 sec_socid = (soc_id >> SOC_SEC_SHFT) & 0xFF;
+
+ if ((pri_socid == 'B') && (sec_socid == 'B'))
+ return SOC_SPEAR600_BB;
+ else if ((pri_socid == 'B') && (sec_socid == 'C'))
+ return SOC_SPEAR600_BC;
+ else if ((pri_socid == 'B') && (sec_socid == 'D'))
+ return SOC_SPEAR600_BD;
+ else if (soc_id == 0)
+ return SOC_SPEAR600_BA;
+ else
+ return SOC_SPEAR_NA;
+#elif defined(CONFIG_SPEAR300)
+ return SOC_SPEAR300;
+#elif defined(CONFIG_SPEAR310)
+ return SOC_SPEAR310;
+#elif defined(CONFIG_SPEAR320)
+ return SOC_SPEAR320;
+#endif
+}
+
+/*
+ * SNOR (Serial NOR flash) related functions
+ */
+static void snor_init(void)
+{
+ struct smi_regs *const smicntl =
+ (struct smi_regs * const)CONFIG_SYS_SMI_BASE;
+
+ /* Setting the fast mode values. SMI working at 166/4 = 41.5 MHz */
+ writel(HOLD1 | FAST_MODE | BANK_EN | DSEL_TIME | PRESCAL4,
+ &smicntl->smi_cr1);
+}
+
+u32 spl_boot_device(void)
+{
+ u32 mode = 0;
+
+ if (usb_boot_selected()) {
+ mode = BOOT_DEVICE_BOOTROM;
+ } else if (snor_boot_selected()) {
+ /* SNOR-SMI initialization */
+ snor_init();
+
+ mode = BOOT_DEVICE_NOR;
+ }
+
+ return mode;
+}
+
+void board_boot_order(u32 *spl_boot_list)
+{
+ spl_boot_list[0] = spl_boot_device();
+
+ /*
+ * If the main boot device (eg. NOR) is empty, try to jump back into the
+ * BootROM for USB boot process.
+ */
+ if (USB_BOOT_SUPPORTED)
+ spl_boot_list[1] = BOOT_DEVICE_BOOTROM;
+}
+
+void board_init_f(ulong dummy)
+{
+ struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+
+ /* Initialize PLLs */
+ sys_init();
+
+ preloader_console_init();
+ arch_cpu_init();
+
+ /* Enable IPs (release reset) */
+ writel(PERIPH_RST_ALL, &misc_p->periph1_rst);
+
+ /* Initialize MPMC */
+ puts("Configure DDR\n");
+ mpmc_init();
+ spear_late_init();
+}
+
+/*
+ * In a few cases (Ethernet, UART or USB boot, we might want to go back into the
+ * BootROM code right after having initialized a few components like the DRAM).
+ * The following function is called from SPL common code (board_init_r).
+ */
+int board_return_to_bootrom(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ /*
+ * Retrieve the BootROM's stack pointer and jump back to the start of
+ * the SPL, where we can easily branch back into the BootROM. Don't do
+ * it right here because SPL might be compiled in Thumb mode while the
+ * BootROM expects ARM mode.
+ */
+ asm volatile ("ldr r0, =bootrom_stash_sp;"
+ "ldr r0, [r0];"
+ "mov sp, r0;"
+#if defined(CONFIG_SPL_SYS_THUMB_BUILD)
+ "blx back_to_bootrom;"
+#else
+ "bl back_to_bootrom;"
+#endif
+ );
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c
new file mode 100644
index 000000000..79ab2a70d
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000-2009
+ * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com
+ */
+
+#include <common.h>
+
+#if (CONFIG_DDR_PLL2)
+
+const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = {
+ 0x00000001,
+ 0x00000000,
+ 0x01000000,
+ 0x00000101,
+ 0x00000001,
+ 0x01000000,
+ 0x00010001,
+ 0x00000100,
+ 0x00010001,
+ 0x00000003,
+ 0x01000201,
+ 0x06000202,
+ 0x06060106,
+ 0x03050502,
+ 0x03040404,
+ 0x02020503,
+ 0x02010106,
+ 0x03000404,
+ 0x02030202,
+ 0x03000204,
+ 0x0707073f,
+ 0x07070707,
+ 0x06060607,
+ 0x06060606,
+ 0x05050506,
+ 0x05050505,
+ 0x04040405,
+ 0x04040404,
+ 0x03030304,
+ 0x03030303,
+ 0x02020203,
+ 0x02020202,
+ 0x01010102,
+ 0x01010101,
+ 0x08080a01,
+ 0x0000023f,
+ 0x00040800,
+ 0x00000000,
+ 0x00000f02,
+ 0x00001b1b,
+ 0x7f000000,
+ 0x005f0000,
+ 0x1c040b6a,
+ 0x00640064,
+ 0x00640064,
+ 0x00640064,
+ 0x00000064,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x000007ff,
+ 0x00000000,
+ 0x47ec00c8,
+ 0x00c8001f,
+ 0x00000000,
+ 0x0000cd98,
+ 0x00000000,
+ 0x03030100,
+ 0x03030303,
+ 0x03030303,
+ 0x03030303,
+ 0x00270000,
+ 0x00250027,
+ 0x00300000,
+ 0x008900b7,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c
new file mode 100644
index 000000000..121b63607
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000-2009
+ * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com
+ */
+
+#include <common.h>
+
+#if (CONFIG_DDR_PLL2 || CONFIG_DDR_2HCLK)
+
+const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = {
+#if (CONFIG_DDR_PLL2)
+ 0x00000001,
+ 0x00000000,
+#elif (CONFIG_DDR_2HCLK)
+ 0x02020201,
+ 0x02020202,
+#endif
+ 0x01000000,
+ 0x00000101,
+ 0x00000101,
+ 0x01000000,
+ 0x00010001,
+ 0x00000100,
+ 0x01010001,
+ 0x00000201,
+ 0x01000101,
+ 0x06000002,
+ 0x06060106,
+ 0x03050502,
+ 0x03040404,
+ 0x02020503,
+ 0x02010106,
+ 0x03000405,
+ 0x03040202,
+ 0x04000305,
+ 0x0707073f,
+ 0x07070707,
+ 0x06060607,
+ 0x06060606,
+ 0x05050506,
+ 0x05050505,
+ 0x04040405,
+ 0x04040404,
+ 0x03030304,
+ 0x03030303,
+ 0x02020203,
+ 0x02020202,
+ 0x01010102,
+ 0x01010101,
+ 0x0a0a0a01,
+ 0x0000023f,
+ 0x00050a00,
+ 0x11000000,
+ 0x00001302,
+ 0x00000A0A,
+ 0x72000000,
+ 0x00550000,
+ 0x2b050e86,
+ 0x00640064,
+ 0x00640064,
+ 0x00640064,
+ 0x00000064,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00000a24,
+ 0x43C20000,
+ 0x5b1c00c8,
+ 0x00c8002e,
+ 0x00000000,
+ 0x0001046b,
+ 0x00000000,
+ 0x03030100,
+ 0x03030303,
+ 0x03030303,
+ 0x03030303,
+ 0x00210000,
+ 0x00010021,
+ 0x00200000,
+ 0x006c0090,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c
new file mode 100644
index 000000000..64c8bab9b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000-2009
+ * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com
+ */
+
+#include <common.h>
+
+#if (CONFIG_DDR_HCLK)
+
+const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = {
+ 0x03030301,
+ 0x03030303,
+ 0x01000000,
+ 0x00000101,
+ 0x00000001,
+ 0x01000000,
+ 0x00010001,
+ 0x00000100,
+ 0x00010001,
+ 0x00000003,
+ 0x01000201,
+ 0x06000202,
+ 0x06060106,
+ 0x03050502,
+ 0x03040404,
+ 0x02020503,
+ 0x02010106,
+ 0x03000404,
+ 0x02020202,
+ 0x03000203,
+ 0x0707073f,
+ 0x07070707,
+ 0x06060607,
+ 0x06060606,
+ 0x05050506,
+ 0x05050505,
+ 0x04040405,
+ 0x04040404,
+ 0x03030304,
+ 0x03030303,
+ 0x02020203,
+ 0x02020202,
+ 0x01010102,
+ 0x01010101,
+ 0x08080a01,
+ 0x0000023f,
+ 0x00030600,
+ 0x00000000,
+ 0x00000a02,
+ 0x00001c1c,
+ 0x7f000000,
+ 0x005f0000,
+ 0x12030743,
+ 0x00640064,
+ 0x00640064,
+ 0x00640064,
+ 0x00000064,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x0000050e,
+ 0x00000000,
+ 0x2d8900c8,
+ 0x00c80014,
+ 0x00000000,
+ 0x00008236,
+ 0x00000000,
+ 0x03030100,
+ 0x03030303,
+ 0x03030303,
+ 0x03030303,
+ 0x00400000,
+ 0x003a0040,
+ 0x00680000,
+ 0x00d80120,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c
new file mode 100644
index 000000000..87654663f
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000-2009
+ * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com
+ */
+
+#include <common.h>
+
+#if (CONFIG_DDR_PLL2 || CONFIG_DDR_2HCLK)
+
+const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = {
+#if (CONFIG_DDR_PLL2)
+ 0x00000001,
+ 0x00000000,
+#elif (CONFIG_DDR_2HCLK)
+ 0x02020201,
+ 0x02020202,
+#endif
+ 0x01000000,
+ 0x00000101,
+ 0x00000101,
+ 0x01000000,
+ 0x00010001,
+ 0x00000100,
+ 0x01010001,
+ 0x00000201,
+ 0x01000101,
+ 0x06000002,
+ 0x06060106,
+ 0x03050502,
+ 0x03040404,
+ 0x02020503,
+#ifdef CONFIG_X600
+ 0x02030206,
+#else
+ 0x02010106,
+#endif
+ 0x03000405,
+ 0x03040202,
+ 0x04000305,
+ 0x0707073f,
+ 0x07070707,
+ 0x06060607,
+ 0x06060606,
+ 0x05050506,
+ 0x05050505,
+ 0x04040405,
+ 0x04040404,
+ 0x03030304,
+ 0x03030303,
+ 0x02020203,
+ 0x02020202,
+ 0x01010102,
+ 0x01010101,
+ 0x0a0a0a01,
+ 0x0000023f,
+ 0x00050a00,
+ 0x11000000,
+ 0x00001302,
+ 0x00000A0A,
+#ifdef CONFIG_X600
+ 0x7f000000,
+ 0x005c0000,
+#else
+ 0x72000000,
+ 0x00550000,
+#endif
+ 0x2b050e86,
+ 0x00640064,
+ 0x00640064,
+ 0x00640064,
+ 0x00000064,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00200020,
+ 0x00000a24,
+ 0x43C20000,
+ 0x5b1c00c8,
+ 0x00c8002e,
+ 0x00000000,
+ 0x0001046b,
+ 0x00000000,
+ 0x03030100,
+ 0x03030303,
+ 0x03030303,
+ 0x03030303,
+ 0x00210000,
+ 0x00010021,
+ 0x00200000,
+ 0x006c0090,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x003fffff,
+ 0x003fffff,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr_lowlevel_init.S b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr_lowlevel_init.S
new file mode 100644
index 000000000..417e87a7b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr_lowlevel_init.S
@@ -0,0 +1,173 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2006
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ */
+
+#include <config.h>
+
+/*
+ * platform specific initializations are already done in Xloader
+ * Initializations already done include
+ * DDR, PLLs, IP's clock enable and reset release etc
+ */
+.globl lowlevel_init
+lowlevel_init:
+ mov pc, lr
+
+/* void setfreq(unsigned int device, unsigned int frequency) */
+.global setfreq
+setfreq:
+ stmfd sp!,{r14}
+ stmfd sp!,{r0-r12}
+
+ mov r8,sp
+ ldr sp,SRAM_STACK_V
+
+ /* Saving the function arguements for later use */
+ mov r4,r0
+ mov r5,r1
+
+ /* Putting DDR into self refresh */
+ ldr r0,DDR_07_V
+ ldr r1,[r0]
+ ldr r2,DDR_ACTIVE_V
+ bic r1, r1, r2
+ str r1,[r0]
+ ldr r0,DDR_57_V
+ ldr r1,[r0]
+ ldr r2,CYCLES_MASK_V
+ bic r1, r1, r2
+ ldr r2,REFRESH_CYCLES_V
+ orr r1, r1, r2, lsl #16
+ str r1,[r0]
+ ldr r0,DDR_07_V
+ ldr r1,[r0]
+ ldr r2,SREFRESH_MASK_V
+ orr r1, r1, r2
+ str r1,[r0]
+
+ /* flush pipeline */
+ b flush
+ .align 5
+flush:
+ /* Delay to ensure self refresh mode */
+ ldr r0,SREFRESH_DELAY_V
+delay:
+ sub r0,r0,#1
+ cmp r0,#0
+ bne delay
+
+ /* Putting system in slow mode */
+ ldr r0,SCCTRL_V
+ mov r1,#2
+ str r1,[r0]
+
+ /* Changing PLL(1/2) frequency */
+ mov r0,r4
+ mov r1,r5
+
+ cmp r4,#0
+ beq pll1_freq
+
+ /* Change PLL2 (DDR frequency) */
+ ldr r6,PLL2_FREQ_V
+ ldr r7,PLL2_CNTL_V
+ b pll2_freq
+
+pll1_freq:
+ /* Change PLL1 (CPU frequency) */
+ ldr r6,PLL1_FREQ_V
+ ldr r7,PLL1_CNTL_V
+
+pll2_freq:
+ mov r0,r6
+ ldr r1,[r0]
+ ldr r2,PLLFREQ_MASK_V
+ bic r1,r1,r2
+ mov r2,r5,lsr#1
+ orr r1,r1,r2,lsl#24
+ str r1,[r0]
+
+ mov r0,r7
+ ldr r1,P1C0A_V
+ str r1,[r0]
+ ldr r1,P1C0E_V
+ str r1,[r0]
+ ldr r1,P1C06_V
+ str r1,[r0]
+ ldr r1,P1C0E_V
+ str r1,[r0]
+
+lock:
+ ldr r1,[r0]
+ and r1,r1,#1
+ cmp r1,#0
+ beq lock
+
+ /* Putting system back to normal mode */
+ ldr r0,SCCTRL_V
+ mov r1,#4
+ str r1,[r0]
+
+ /* Putting DDR back to normal */
+ ldr r0,DDR_07_V
+ ldr r1,[R0]
+ ldr r2,SREFRESH_MASK_V
+ bic r1, r1, r2
+ str r1,[r0]
+ ldr r2,DDR_ACTIVE_V
+ orr r1, r1, r2
+ str r1,[r0]
+
+ /* Delay to ensure self refresh mode */
+ ldr r0,SREFRESH_DELAY_V
+1:
+ sub r0,r0,#1
+ cmp r0,#0
+ bne 1b
+
+ mov sp,r8
+ /* Resuming back to code */
+ ldmia sp!,{r0-r12}
+ ldmia sp!,{pc}
+
+SCCTRL_V:
+ .word 0xfca00000
+PLL1_FREQ_V:
+ .word 0xfca8000C
+PLL1_CNTL_V:
+ .word 0xfca80008
+PLL2_FREQ_V:
+ .word 0xfca80018
+PLL2_CNTL_V:
+ .word 0xfca80014
+PLLFREQ_MASK_V:
+ .word 0xff000000
+P1C0A_V:
+ .word 0x1C0A
+P1C0E_V:
+ .word 0x1C0E
+P1C06_V:
+ .word 0x1C06
+
+SREFRESH_DELAY_V:
+ .word 0x9999
+SRAM_STACK_V:
+ .word 0xD2800600
+DDR_07_V:
+ .word 0xfc60001c
+DDR_ACTIVE_V:
+ .word 0x01000000
+DDR_57_V:
+ .word 0xfc6000e4
+CYCLES_MASK_V:
+ .word 0xffff0000
+REFRESH_CYCLES_V:
+ .word 0xf0f0
+SREFRESH_MASK_V:
+ .word 0x00010000
+
+.global setfreq_sz
+setfreq_sz:
+ .word setfreq_sz - setfreq
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr_misc.c b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr_misc.c
new file mode 100644
index 000000000..044052b32
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/spr_misc.c
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <env.h>
+#include <i2c.h>
+#include <init.h>
+#include <net.h>
+#include <asm/global_data.h>
+#include <linux/mtd/st_smi.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spr_emi.h>
+#include <asm/arch/spr_defs.h>
+
+#define CPU 0
+#define DDR 1
+#define SRAM_REL 0xD2801000
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_CMD_NET)
+static int i2c_read_mac(uchar *buffer);
+#endif
+
+int dram_init(void)
+{
+ /* Store complete RAM size and return */
+ gd->ram_size = get_ram_size(PHYS_SDRAM_1, PHYS_SDRAM_1_MAXSIZE);
+
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = gd->ram_size;
+
+ return 0;
+}
+
+int board_early_init_f()
+{
+#if defined(CONFIG_ST_SMI)
+ smi_init();
+#endif
+ return 0;
+}
+int misc_init_r(void)
+{
+#if defined(CONFIG_CMD_NET)
+ uchar mac_id[6];
+
+ if (!eth_env_get_enetaddr("ethaddr", mac_id) && !i2c_read_mac(mac_id))
+ eth_env_set_enetaddr("ethaddr", mac_id);
+#endif
+ env_set("verify", "n");
+
+#if defined(CONFIG_SPEAR_USBTTY)
+ env_set("stdin", "usbtty");
+ env_set("stdout", "usbtty");
+ env_set("stderr", "usbtty");
+
+#ifndef CONFIG_SYS_NO_DCACHE
+ dcache_enable();
+#endif
+#endif
+ return 0;
+}
+
+#ifdef CONFIG_SPEAR_EMI
+struct cust_emi_para {
+ unsigned int tap;
+ unsigned int tsdp;
+ unsigned int tdpw;
+ unsigned int tdpr;
+ unsigned int tdcs;
+};
+
+/* EMI timing setting of m28w640hc of linux kernel */
+const struct cust_emi_para emi_timing_m28w640hc = {
+ .tap = 0x10,
+ .tsdp = 0x05,
+ .tdpw = 0x0a,
+ .tdpr = 0x0a,
+ .tdcs = 0x05,
+};
+
+/* EMI timing setting of bootrom */
+const struct cust_emi_para emi_timing_bootrom = {
+ .tap = 0xf,
+ .tsdp = 0x0,
+ .tdpw = 0xff,
+ .tdpr = 0x111,
+ .tdcs = 0x02,
+};
+
+void spear_emi_init(void)
+{
+ const struct cust_emi_para *p = &emi_timing_m28w640hc;
+ struct emi_regs *emi_regs_p = (struct emi_regs *)CONFIG_SPEAR_EMIBASE;
+ unsigned int cs;
+ unsigned int val, tmp;
+
+ val = readl(CONFIG_SPEAR_RASBASE);
+
+ if (val & EMI_ACKMSK)
+ tmp = 0x3f;
+ else
+ tmp = 0x0;
+
+ writel(tmp, &emi_regs_p->ack);
+
+ for (cs = 0; cs < CONFIG_SYS_MAX_FLASH_BANKS; cs++) {
+ writel(p->tap, &emi_regs_p->bank_regs[cs].tap);
+ writel(p->tsdp, &emi_regs_p->bank_regs[cs].tsdp);
+ writel(p->tdpw, &emi_regs_p->bank_regs[cs].tdpw);
+ writel(p->tdpr, &emi_regs_p->bank_regs[cs].tdpr);
+ writel(p->tdcs, &emi_regs_p->bank_regs[cs].tdcs);
+ writel(EMI_CNTL_ENBBYTERW | ((val & 0x18) >> 3),
+ &emi_regs_p->bank_regs[cs].control);
+ }
+}
+#endif
+
+int spear_board_init(ulong mach_type)
+{
+ gd->bd->bi_arch_number = mach_type;
+
+ /* adress of boot parameters */
+ gd->bd->bi_boot_params = CONFIG_BOOT_PARAMS_ADDR;
+
+#ifdef CONFIG_SPEAR_EMI
+ spear_emi_init();
+#endif
+ return 0;
+}
+
+#if defined(CONFIG_CMD_NET)
+static int i2c_read_mac(uchar *buffer)
+{
+ u8 buf[2];
+
+ i2c_read(CONFIG_I2C_CHIPADDRESS, MAGIC_OFF, 1, buf, MAGIC_LEN);
+
+ /* Check if mac in i2c memory is valid */
+ if ((buf[0] == MAGIC_BYTE0) && (buf[1] == MAGIC_BYTE1)) {
+ /* Valid mac address is saved in i2c eeprom */
+ i2c_read(CONFIG_I2C_CHIPADDRESS, MAC_OFF, 1, buffer, MAC_LEN);
+ return 0;
+ }
+
+ return -1;
+}
+
+static int write_mac(uchar *mac)
+{
+ u8 buf[2];
+
+ buf[0] = (u8)MAGIC_BYTE0;
+ buf[1] = (u8)MAGIC_BYTE1;
+ i2c_write(CONFIG_I2C_CHIPADDRESS, MAGIC_OFF, 1, buf, MAGIC_LEN);
+
+ buf[0] = (u8)~MAGIC_BYTE0;
+ buf[1] = (u8)~MAGIC_BYTE1;
+
+ i2c_read(CONFIG_I2C_CHIPADDRESS, MAGIC_OFF, 1, buf, MAGIC_LEN);
+
+ /* check if valid MAC address is saved in I2C EEPROM or not? */
+ if ((buf[0] == MAGIC_BYTE0) && (buf[1] == MAGIC_BYTE1)) {
+ i2c_write(CONFIG_I2C_CHIPADDRESS, MAC_OFF, 1, mac, MAC_LEN);
+ puts("I2C EEPROM written with mac address \n");
+ return 0;
+ }
+
+ puts("I2C EEPROM writing failed\n");
+ return -1;
+}
+#endif
+
+int do_chip_config(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ void (*sram_setfreq) (unsigned int, unsigned int);
+ unsigned int frequency;
+#if defined(CONFIG_CMD_NET)
+ unsigned char mac[6];
+#endif
+
+ if ((argc > 3) || (argc < 2))
+ return cmd_usage(cmdtp);
+
+ if ((!strcmp(argv[1], "cpufreq")) || (!strcmp(argv[1], "ddrfreq"))) {
+
+ frequency = simple_strtoul(argv[2], NULL, 0);
+
+ if (frequency > 333) {
+ printf("Frequency is limited to 333MHz\n");
+ return 1;
+ }
+
+ sram_setfreq = memcpy((void *)SRAM_REL, setfreq, setfreq_sz);
+
+ if (!strcmp(argv[1], "cpufreq")) {
+ sram_setfreq(CPU, frequency);
+ printf("CPU frequency changed to %u\n", frequency);
+ } else {
+ sram_setfreq(DDR, frequency);
+ printf("DDR frequency changed to %u\n", frequency);
+ }
+
+ return 0;
+
+#if defined(CONFIG_CMD_NET)
+ } else if (!strcmp(argv[1], "ethaddr")) {
+
+ u32 reg;
+ char *e, *s = argv[2];
+ for (reg = 0; reg < 6; ++reg) {
+ mac[reg] = s ? simple_strtoul(s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+ write_mac(mac);
+
+ return 0;
+#endif
+ } else if (!strcmp(argv[1], "print")) {
+#if defined(CONFIG_CMD_NET)
+ if (!i2c_read_mac(mac)) {
+ printf("Ethaddr (from i2c mem) = %pM\n", mac);
+ } else {
+ printf("Ethaddr (from i2c mem) = Not set\n");
+ }
+#endif
+ return 0;
+ }
+
+ return cmd_usage(cmdtp);
+}
+
+U_BOOT_CMD(chip_config, 3, 1, do_chip_config,
+ "configure chip",
+ "chip_config cpufreq/ddrfreq frequency\n"
+#if defined(CONFIG_CMD_NET)
+ "chip_config ethaddr XX:XX:XX:XX:XX:XX\n"
+#endif
+ "chip_config print");
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/start.S b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/start.S
new file mode 100644
index 000000000..9ac96291b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/start.S
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * armboot - Startup Code for ARM926EJS CPU-core
+ *
+ * Copyright (c) 2003 Texas Instruments
+ *
+ * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
+ *
+ * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
+ * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
+ * Copyright (c) 2003 Kshitij <kshitij@ti.com>
+ */
+
+
+#include <config.h>
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * The BootROM already initialized its own stack in the [0-0xb00] reserved
+ * range of the SRAM. The SPL (in _main) will update the stack pointer to
+ * its own SRAM area (right before the gd section).
+ *
+ *************************************************************************
+ */
+
+ .globl reset
+ .globl back_to_bootrom
+
+reset:
+ /*
+ * SPL has to return back to BootROM in a few cases (eg. Ethernet boot,
+ * UART boot, USB boot): save registers in BootROM's stack and then the
+ * BootROM's stack pointer in the SPL's data section.
+ */
+ push {r0-r12,lr}
+ ldr r0, =bootrom_stash_sp
+ str sp, [r0]
+
+ /*
+ * Flush v4 I/D caches
+ */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 /* Flush v3/v4 cache */
+ mcr p15, 0, r0, c8, c7, 0 /* Flush v4 TLB */
+
+ /*
+ * Enable instruction cache
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
+ mcr p15, 0, r0, c1, c0, 0
+
+ /*
+ * Go setup Memory and board specific bits prior to relocation.
+ * This call is not supposed to return.
+ */
+ b _main /* _main will call board_init_f */
+
+back_to_bootrom:
+ pop {r0-r12,pc}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/timer.c b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/timer.c
new file mode 100644
index 000000000..b42baa715
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/timer.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spr_gpt.h>
+#include <asm/arch/spr_misc.h>
+#include <asm/ptrace.h>
+#include <linux/delay.h>
+
+#define GPT_RESOLUTION (CONFIG_SPEAR_HZ_CLOCK / CONFIG_SPEAR_HZ)
+#define READ_TIMER() (readl(&gpt_regs_p->count) & GPT_FREE_RUNNING)
+
+static struct gpt_regs *const gpt_regs_p =
+ (struct gpt_regs *)CONFIG_SPEAR_TIMERBASE;
+
+static struct misc_regs *const misc_regs_p =
+ (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static ulong get_timer_masked(void);
+
+#define timestamp gd->arch.tbl
+#define lastdec gd->arch.lastinc
+
+int timer_init(void)
+{
+ u32 synth;
+
+ /* Prescaler setting */
+#if defined(CONFIG_SPEAR3XX)
+ writel(MISC_PRSC_CFG, &misc_regs_p->prsc2_clk_cfg);
+ synth = MISC_GPT4SYNTH;
+#elif defined(CONFIG_SPEAR600)
+ writel(MISC_PRSC_CFG, &misc_regs_p->prsc1_clk_cfg);
+ synth = MISC_GPT3SYNTH;
+#else
+# error Incorrect config. Can only be SPEAR{600|300|310|320}
+#endif
+
+ writel(readl(&misc_regs_p->periph_clk_cfg) | synth,
+ &misc_regs_p->periph_clk_cfg);
+
+ /* disable timers */
+ writel(GPT_PRESCALER_1 | GPT_MODE_AUTO_RELOAD, &gpt_regs_p->control);
+
+ /* load value for free running */
+ writel(GPT_FREE_RUNNING, &gpt_regs_p->compare);
+
+ /* auto reload, start timer */
+ writel(readl(&gpt_regs_p->control) | GPT_ENABLE, &gpt_regs_p->control);
+
+ /* Reset the timer */
+ lastdec = READ_TIMER();
+ timestamp = 0;
+
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+ulong get_timer(ulong base)
+{
+ return (get_timer_masked() / GPT_RESOLUTION) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+ ulong tmo;
+ ulong start = get_timer_masked();
+ ulong tenudelcnt = CONFIG_SPEAR_HZ_CLOCK / (1000 * 100);
+ ulong rndoff;
+
+ rndoff = (usec % 10) ? 1 : 0;
+
+ /* tenudelcnt timer tick gives 10 microsecconds delay */
+ tmo = ((usec / 10) + rndoff) * tenudelcnt;
+
+ while ((ulong) (get_timer_masked() - start) < tmo)
+ ;
+}
+
+static ulong get_timer_masked(void)
+{
+ ulong now = READ_TIMER();
+
+ if (now >= lastdec) {
+ /* normal mode */
+ timestamp += now - lastdec;
+ } else {
+ /* we have an overflow ... */
+ timestamp += now + GPT_FREE_RUNNING - lastdec;
+ }
+ lastdec = now;
+
+ return timestamp;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return CONFIG_SPEAR_HZ;
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds
new file mode 100644
index 000000000..0964a9742
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2015 Stefan Roese <sr@denx.de>
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * January 2004 - Changed to support H4 device
+ * Copyright (c) 2004-2008 Texas Instruments
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ */
+
+MEMORY { .sram : ORIGIN = IMAGE_TEXT_BASE,\
+ LENGTH = IMAGE_MAX_SIZE }
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ .text :
+ {
+ __start = .;
+ *(.vectors)
+ CPUDIR/spear/start.o (.text*)
+ *(.text*)
+ } > .sram
+
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
+
+ . = ALIGN(4);
+ .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
+
+ . = ALIGN(4);
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+ } > .sram
+
+ . = ALIGN(4);
+ __image_copy_end = .;
+ _end = .;
+
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_end = .;
+ } > .sram
+}
diff --git a/roms/u-boot/arch/arm/cpu/arm926ejs/start.S b/roms/u-boot/arch/arm/cpu/arm926ejs/start.S
new file mode 100644
index 000000000..ff592ba81
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm926ejs/start.S
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * armboot - Startup Code for ARM926EJS CPU-core
+ *
+ * Copyright (c) 2003 Texas Instruments
+ *
+ * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
+ *
+ * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
+ * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
+ * Copyright (c) 2003 Kshitij <kshitij@ti.com>
+ * Copyright (c) 2010 Albert Aribaud <albert.u.boot@aribaud.net>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <common.h>
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * setup Memory and board specific bits prior to relocation.
+ * relocate armboot to ram
+ * setup stack
+ *
+ *************************************************************************
+ */
+
+ .globl reset
+
+reset:
+ /*
+ * set the cpu to SVC32 mode
+ */
+ mrs r0,cpsr
+ bic r0,r0,#0x1f
+ orr r0,r0,#0xd3
+ msr cpsr,r0
+
+ /*
+ * we do sys-critical inits only at reboot,
+ * not when booting from ram!
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ bl cpu_init_crit
+#endif
+
+ bl _main
+
+/*------------------------------------------------------------------------------*/
+
+ .globl c_runtime_cpu_setup
+c_runtime_cpu_setup:
+
+ bx lr
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+cpu_init_crit:
+ /*
+ * flush D cache before disabling it
+ */
+ mov r0, #0
+flush_dcache:
+ mrc p15, 0, r15, c7, c10, 3
+ bne flush_dcache
+
+ mcr p15, 0, r0, c8, c7, 0 /* invalidate TLB */
+ mcr p15, 0, r0, c7, c5, 0 /* invalidate I Cache */
+
+ /*
+ * disable MMU and D cache
+ * enable I cache if SYS_ICACHE_OFF is not defined
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00000300 /* clear bits 9:8 (---- --RS) */
+ bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
+#ifdef CONFIG_SYS_EXCEPTION_VECTORS_HIGH
+ orr r0, r0, #0x00002000 /* set bit 13 (--V- ----) */
+#else
+ bic r0, r0, #0x00002000 /* clear bit 13 (--V- ----) */
+#endif
+ orr r0, r0, #0x00000002 /* set bit 1 (A) Align */
+#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
+ orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
+#endif
+ mcr p15, 0, r0, c1, c0, 0
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
+ /*
+ * Go setup Memory and board specific bits prior to relocation.
+ */
+ mov r4, lr /* perserve link reg across call */
+ bl lowlevel_init /* go setup pll,mux,memory */
+ mov lr, r4 /* restore link */
+#endif
+ mov pc, lr /* back to my caller */
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/roms/u-boot/arch/arm/cpu/arm946es/Makefile b/roms/u-boot/arch/arm/cpu/arm946es/Makefile
new file mode 100644
index 000000000..24cebe3f5
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm946es/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+extra-y = start.o
+
+obj-y = cpu.o
diff --git a/roms/u-boot/arch/arm/cpu/arm946es/cpu.c b/roms/u-boot/arch/arm/cpu/arm946es/cpu.c
new file mode 100644
index 000000000..334bb5427
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm946es/cpu.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ */
+
+/*
+ * CPU specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <irq_func.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+static void cache_flush(void);
+
+int cleanup_before_linux (void)
+{
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * we turn off caches etc ...
+ */
+
+ disable_interrupts();
+
+ /* ARM926E-S needs the protection unit enabled for the icache to have
+ * been enabled - left for possible later use
+ * should turn off the protection unit as well....
+ */
+ /* turn off I/D-cache */
+ icache_disable();
+ dcache_disable();
+ /* flush I/D-cache */
+ cache_flush();
+
+ return 0;
+}
+
+/* flush I/D-cache */
+static void cache_flush (void)
+{
+ unsigned long i = 0;
+
+ asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i));
+ asm ("mcr p15, 0, %0, c7, c6, 0": :"r" (i));
+}
+
+#ifndef CONFIG_ARCH_INTEGRATOR
+
+__attribute__((noreturn)) void reset_cpu(void)
+{
+ writew(0x0, 0xfffece10);
+ writew(0x8, 0xfffece10);
+ for (;;)
+ ;
+}
+
+#endif /* #ifdef CONFIG_ARCH_INTEGRATOR */
diff --git a/roms/u-boot/arch/arm/cpu/arm946es/start.S b/roms/u-boot/arch/arm/cpu/arm946es/start.S
new file mode 100644
index 000000000..0ec340b1a
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/arm946es/start.S
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * armboot - Startup Code for ARM926EJS CPU-core
+ *
+ * Copyright (c) 2003 Texas Instruments
+ *
+ * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
+ *
+ * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
+ * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
+ * Copyright (c) 2003 Kshitij <kshitij@ti.com>
+ * Copyright (c) 2010 Albert Aribaud <albert.u.boot@aribaud.net>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * setup Memory and board specific bits prior to relocation.
+ * relocate armboot to ram
+ * setup stack
+ *
+ *************************************************************************
+ */
+
+ .globl reset
+
+reset:
+ /*
+ * set the cpu to SVC32 mode
+ */
+ mrs r0,cpsr
+ bic r0,r0,#0x1f
+ orr r0,r0,#0xd3
+ msr cpsr,r0
+
+ /*
+ * we do sys-critical inits only at reboot,
+ * not when booting from ram!
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ bl cpu_init_crit
+#endif
+
+ bl _main
+
+/*------------------------------------------------------------------------------*/
+
+ .globl c_runtime_cpu_setup
+c_runtime_cpu_setup:
+
+ mov pc, lr
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+cpu_init_crit:
+ /*
+ * flush v4 I/D caches
+ */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 /* flush v4 I-cache */
+ mcr p15, 0, r0, c7, c6, 0 /* flush v4 D-cache */
+
+ /*
+ * disable MMU stuff and caches
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
+ bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
+ orr r0, r0, #0x00000002 /* set bit 1 (A) Align */
+ orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
+ mcr p15, 0, r0, c1, c0, 0
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
+ /*
+ * Go setup Memory and board specific bits prior to relocation.
+ */
+ mov ip, lr /* perserve link reg across call */
+ bl lowlevel_init /* go setup memory */
+ mov lr, ip /* restore link */
+#endif
+ mov pc, lr /* back to my caller */
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv7/Kconfig b/roms/u-boot/arch/arm/cpu/armv7/Kconfig
new file mode 100644
index 000000000..60bb0a9e1
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/Kconfig
@@ -0,0 +1,79 @@
+if CPU_V7A
+
+config CPU_V7_HAS_NONSEC
+ bool
+
+config CPU_V7_HAS_VIRT
+ bool
+
+config ARCH_SUPPORT_PSCI
+ bool
+
+config ARMV7_NONSEC
+ bool "Enable support for booting in non-secure mode" if EXPERT
+ depends on CPU_V7_HAS_NONSEC
+ default y
+ ---help---
+ Say Y here to enable support for booting in non-secure / SVC mode.
+
+config ARMV7_BOOT_SEC_DEFAULT
+ bool "Boot in secure mode by default" if EXPERT
+ depends on ARMV7_NONSEC
+ default y if ARCH_TEGRA
+ ---help---
+ Say Y here to boot in secure mode by default even if non-secure mode
+ is supported. This option is useful to boot kernels which do not
+ suppport booting in non-secure mode. Only set this if you need it.
+ This can be overridden at run-time by setting the bootm_boot_mode env.
+ variable to "sec" or "nonsec".
+
+config ARMV7_VIRT
+ bool "Enable support for hardware virtualization" if EXPERT
+ depends on CPU_V7_HAS_VIRT && ARMV7_NONSEC
+ default y
+ ---help---
+ Say Y here to boot in hypervisor (HYP) mode when booting non-secure.
+
+config ARMV7_PSCI
+ bool "Enable PSCI support" if EXPERT
+ depends on ARMV7_NONSEC && ARCH_SUPPORT_PSCI
+ default y
+ help
+ Say Y here to enable PSCI support.
+
+choice
+ prompt "Supported PSCI version"
+ depends on ARMV7_PSCI
+ default ARMV7_PSCI_0_1 if ARCH_SUNXI
+ default ARMV7_PSCI_1_0
+ help
+ Select the supported PSCI version.
+
+config ARMV7_PSCI_1_0
+ bool "PSCI V1.0"
+
+config ARMV7_PSCI_0_2
+ bool "PSCI V0.2"
+
+config ARMV7_PSCI_0_1
+ bool "PSCI V0.1"
+endchoice
+
+config ARMV7_PSCI_NR_CPUS
+ int "Maximum supported CPUs for PSCI"
+ depends on ARMV7_NONSEC
+ default 4
+ help
+ The maximum number of CPUs supported in the PSCI firmware.
+ It is no problem to set a larger value than the number of
+ CPUs in the actual hardware implementation.
+
+config ARMV7_LPAE
+ bool "Use LPAE page table format" if EXPERT
+ depends on CPU_V7A
+ default y if ARMV7_VIRT
+ ---help---
+ Say Y here to use the long descriptor page table format. This is
+ required if U-Boot runs in HYP mode.
+
+endif
diff --git a/roms/u-boot/arch/arm/cpu/armv7/Makefile b/roms/u-boot/arch/arm/cpu/armv7/Makefile
new file mode 100644
index 000000000..0e83e394d
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/Makefile
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+extra-y := start.o
+
+obj-y += cache_v7.o cache_v7_asm.o
+
+obj-y += cpu.o cp15.o
+obj-y += syslib.o
+
+obj-$(CONFIG_SYS_ARM_MPU) += mpu_v7r.o
+
+ifneq ($(CONFIG_SPL_BUILD),y)
+obj-$(CONFIG_EFI_LOADER) += sctlr.o
+obj-$(CONFIG_ARMV7_NONSEC) += exception_level.o
+endif
+
+ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y)
+obj-y += lowlevel_init.o
+endif
+
+obj-$(CONFIG_ARM_SMCCC) += smccc-call.o
+obj-$(CONFIG_ARMV7_NONSEC) += nonsec_virt.o virt-v7.o virt-dt.o
+obj-$(CONFIG_ARMV7_PSCI) += psci.o psci-common.o
+
+obj-$(CONFIG_IPROC) += iproc-common/
+obj-$(CONFIG_KONA) += kona-common/
+obj-$(CONFIG_SYS_ARCH_TIMER) += arch_timer.o
+
+ifneq (,$(filter s5pc1xx exynos,$(SOC)))
+obj-y += s5p-common/
+endif
+
+obj-$(if $(filter bcm235xx,$(SOC)),y) += bcm235xx/
+obj-$(if $(filter bcm281xx,$(SOC)),y) += bcm281xx/
+obj-$(if $(filter bcmcygnus,$(SOC)),y) += bcmcygnus/
+obj-$(if $(filter bcmnsp,$(SOC)),y) += bcmnsp/
+obj-$(if $(filter ls102xa,$(SOC)),y) += ls102xa/
+obj-$(CONFIG_RMOBILE) += rmobile/
+obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/
+obj-$(CONFIG_ARCH_SUNXI) += sunxi/
+obj-$(CONFIG_VF610) += vf610/
+obj-$(CONFIG_ARCH_S5P4418) += s5p4418/
+obj-$(CONFIG_ARCH_NEXELL) += s5p-common/
diff --git a/roms/u-boot/arch/arm/cpu/armv7/arch_timer.c b/roms/u-boot/arch/arm/cpu/armv7/arch_timer.c
new file mode 100644
index 000000000..d96406f76
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/arch_timer.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2012-2014
+ * Texas Instruments Incorporated, <www.ti.com>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <div64.h>
+#include <bootstage.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_SYS_HZ_CLOCK
+static inline u32 read_cntfrq(void)
+{
+ u32 frq;
+
+ asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (frq));
+ return frq;
+}
+#endif
+
+int timer_init(void)
+{
+ gd->arch.tbl = 0;
+ gd->arch.tbu = 0;
+
+#ifdef CONFIG_SYS_HZ_CLOCK
+ gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK;
+#else
+ gd->arch.timer_rate_hz = read_cntfrq();
+#endif
+ return 0;
+}
+
+unsigned long long get_ticks(void)
+{
+ ulong nowl, nowu;
+
+ asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (nowl), "=r" (nowu));
+
+ gd->arch.tbl = nowl;
+ gd->arch.tbu = nowu;
+
+ return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
+}
+
+
+ulong timer_get_boot_us(void)
+{
+ if (!gd->arch.timer_rate_hz)
+ timer_init();
+
+ return lldiv(get_ticks(), gd->arch.timer_rate_hz / 1000000);
+}
+
+ulong get_tbclk(void)
+{
+ return gd->arch.timer_rate_hz;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/Makefile b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/Makefile
new file mode 100644
index 000000000..3d09126ca
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2013 Broadcom Corporation.
+
+obj-y += clk-core.o
+obj-y += clk-bcm235xx.o
+obj-y += clk-sdio.o
+obj-y += clk-bsc.o
+obj-$(CONFIG_BCM_SF2_ETH) += clk-eth.o
+obj-y += clk-usb-otg.o
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-bcm235xx.c b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-bcm235xx.c
new file mode 100644
index 000000000..39217c5b2
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-bcm235xx.c
@@ -0,0 +1,568 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+/*
+ *
+ * bcm235xx-specific clock tables
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <asm/arch/sysmap.h>
+#include <asm/kona-common/clk.h>
+#include "clk-core.h"
+
+#define CLOCK_1K 1000
+#define CLOCK_1M (CLOCK_1K * 1000)
+
+/* declare a reference clock */
+#define DECLARE_REF_CLK(clk_name, clk_parent, clk_rate, clk_div) \
+static struct refclk clk_name = { \
+ .clk = { \
+ .name = #clk_name, \
+ .parent = clk_parent, \
+ .rate = clk_rate, \
+ .div = clk_div, \
+ .ops = &ref_clk_ops, \
+ }, \
+}
+
+/*
+ * Reference clocks
+ */
+
+/* Declare a list of reference clocks */
+DECLARE_REF_CLK(ref_crystal, 0, 26 * CLOCK_1M, 1);
+DECLARE_REF_CLK(var_96m, 0, 96 * CLOCK_1M, 1);
+DECLARE_REF_CLK(ref_96m, 0, 96 * CLOCK_1M, 1);
+DECLARE_REF_CLK(ref_312m, 0, 312 * CLOCK_1M, 0);
+DECLARE_REF_CLK(ref_104m, &ref_312m.clk, 104 * CLOCK_1M, 3);
+DECLARE_REF_CLK(ref_52m, &ref_104m.clk, 52 * CLOCK_1M, 2);
+DECLARE_REF_CLK(ref_13m, &ref_52m.clk, 13 * CLOCK_1M, 4);
+DECLARE_REF_CLK(var_312m, 0, 312 * CLOCK_1M, 0);
+DECLARE_REF_CLK(var_104m, &var_312m.clk, 104 * CLOCK_1M, 3);
+DECLARE_REF_CLK(var_52m, &var_104m.clk, 52 * CLOCK_1M, 2);
+DECLARE_REF_CLK(var_13m, &var_52m.clk, 13 * CLOCK_1M, 4);
+
+struct refclk_lkup {
+ struct refclk *procclk;
+ const char *name;
+};
+
+/* Lookup table for string to clk tranlation */
+#define MKSTR(x) {&x, #x}
+static struct refclk_lkup refclk_str_tbl[] = {
+ MKSTR(ref_crystal), MKSTR(var_96m), MKSTR(ref_96m),
+ MKSTR(ref_312m), MKSTR(ref_104m), MKSTR(ref_52m),
+ MKSTR(ref_13m), MKSTR(var_312m), MKSTR(var_104m),
+ MKSTR(var_52m), MKSTR(var_13m),
+};
+
+int refclk_entries = sizeof(refclk_str_tbl)/sizeof(refclk_str_tbl[0]);
+
+/* convert ref clock string to clock structure pointer */
+struct refclk *refclk_str_to_clk(const char *name)
+{
+ int i;
+ struct refclk_lkup *tblp = refclk_str_tbl;
+ for (i = 0; i < refclk_entries; i++, tblp++) {
+ if (!(strcmp(name, tblp->name)))
+ return tblp->procclk;
+ }
+ return NULL;
+}
+
+/* frequency tables indexed by freq_id */
+unsigned long master_axi_freq_tbl[8] = {
+ 26 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 104 * CLOCK_1M,
+ 156 * CLOCK_1M,
+ 156 * CLOCK_1M,
+ 208 * CLOCK_1M,
+ 312 * CLOCK_1M,
+ 312 * CLOCK_1M
+};
+
+unsigned long master_ahb_freq_tbl[8] = {
+ 26 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 78 * CLOCK_1M,
+ 104 * CLOCK_1M,
+ 104 * CLOCK_1M,
+ 156 * CLOCK_1M
+};
+
+unsigned long slave_axi_freq_tbl[8] = {
+ 26 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 78 * CLOCK_1M,
+ 104 * CLOCK_1M,
+ 156 * CLOCK_1M,
+ 156 * CLOCK_1M
+};
+
+unsigned long slave_apb_freq_tbl[8] = {
+ 26 * CLOCK_1M,
+ 26 * CLOCK_1M,
+ 39 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 78 * CLOCK_1M
+};
+
+unsigned long esub_freq_tbl[8] = {
+ 78 * CLOCK_1M,
+ 156 * CLOCK_1M,
+ 156 * CLOCK_1M,
+ 156 * CLOCK_1M,
+ 208 * CLOCK_1M,
+ 208 * CLOCK_1M,
+ 208 * CLOCK_1M
+};
+
+static struct bus_clk_data bsc1_apb_data = {
+ .gate = HW_SW_GATE_AUTO(0x0458, 16, 0, 1),
+};
+
+static struct bus_clk_data bsc2_apb_data = {
+ .gate = HW_SW_GATE_AUTO(0x045c, 16, 0, 1),
+};
+
+static struct bus_clk_data bsc3_apb_data = {
+ .gate = HW_SW_GATE_AUTO(0x0484, 16, 0, 1),
+};
+
+/* * Master CCU clocks */
+static struct peri_clk_data sdio1_data = {
+ .gate = HW_SW_GATE(0x0358, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_52m",
+ "ref_52m",
+ "var_96m",
+ "ref_96m"),
+ .sel = SELECTOR(0x0a28, 0, 3),
+ .div = DIVIDER(0x0a28, 4, 14),
+ .trig = TRIGGER(0x0afc, 9),
+};
+
+static struct peri_clk_data sdio2_data = {
+ .gate = HW_SW_GATE(0x035c, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_52m",
+ "ref_52m",
+ "var_96m",
+ "ref_96m"),
+ .sel = SELECTOR(0x0a2c, 0, 3),
+ .div = DIVIDER(0x0a2c, 4, 14),
+ .trig = TRIGGER(0x0afc, 10),
+};
+
+static struct peri_clk_data sdio3_data = {
+ .gate = HW_SW_GATE(0x0364, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_52m",
+ "ref_52m",
+ "var_96m",
+ "ref_96m"),
+ .sel = SELECTOR(0x0a34, 0, 3),
+ .div = DIVIDER(0x0a34, 4, 14),
+ .trig = TRIGGER(0x0afc, 12),
+};
+
+static struct peri_clk_data sdio4_data = {
+ .gate = HW_SW_GATE(0x0360, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_52m",
+ "ref_52m",
+ "var_96m",
+ "ref_96m"),
+ .sel = SELECTOR(0x0a30, 0, 3),
+ .div = DIVIDER(0x0a30, 4, 14),
+ .trig = TRIGGER(0x0afc, 11),
+};
+
+static struct peri_clk_data sdio1_sleep_data = {
+ .clocks = CLOCKS("ref_32k"),
+ .gate = SW_ONLY_GATE(0x0358, 20, 4),
+};
+
+static struct peri_clk_data sdio2_sleep_data = {
+ .clocks = CLOCKS("ref_32k"),
+ .gate = SW_ONLY_GATE(0x035c, 20, 4),
+};
+
+static struct peri_clk_data sdio3_sleep_data = {
+ .clocks = CLOCKS("ref_32k"),
+ .gate = SW_ONLY_GATE(0x0364, 20, 4),
+};
+
+static struct peri_clk_data sdio4_sleep_data = {
+ .clocks = CLOCKS("ref_32k"),
+ .gate = SW_ONLY_GATE(0x0360, 20, 4),
+};
+
+static struct bus_clk_data usb_otg_ahb_data = {
+ .gate = HW_SW_GATE_AUTO(0x0348, 16, 0, 1),
+};
+
+static struct bus_clk_data sdio1_ahb_data = {
+ .gate = HW_SW_GATE_AUTO(0x0358, 16, 0, 1),
+};
+
+static struct bus_clk_data sdio2_ahb_data = {
+ .gate = HW_SW_GATE_AUTO(0x035c, 16, 0, 1),
+};
+
+static struct bus_clk_data sdio3_ahb_data = {
+ .gate = HW_SW_GATE_AUTO(0x0364, 16, 0, 1),
+};
+
+static struct bus_clk_data sdio4_ahb_data = {
+ .gate = HW_SW_GATE_AUTO(0x0360, 16, 0, 1),
+};
+
+/* * Slave CCU clocks */
+static struct peri_clk_data bsc1_data = {
+ .gate = HW_SW_GATE(0x0458, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_104m",
+ "ref_104m",
+ "var_13m",
+ "ref_13m"),
+ .sel = SELECTOR(0x0a64, 0, 3),
+ .trig = TRIGGER(0x0afc, 23),
+};
+
+static struct peri_clk_data bsc2_data = {
+ .gate = HW_SW_GATE(0x045c, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_104m",
+ "ref_104m",
+ "var_13m",
+ "ref_13m"),
+ .sel = SELECTOR(0x0a68, 0, 3),
+ .trig = TRIGGER(0x0afc, 24),
+};
+
+static struct peri_clk_data bsc3_data = {
+ .gate = HW_SW_GATE(0x0484, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_104m",
+ "ref_104m",
+ "var_13m",
+ "ref_13m"),
+ .sel = SELECTOR(0x0a84, 0, 3),
+ .trig = TRIGGER(0x0b00, 2),
+};
+
+/*
+ * CCU clocks
+ */
+
+static struct ccu_clock kpm_ccu_clk = {
+ .clk = {
+ .name = "kpm_ccu_clk",
+ .ops = &ccu_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .num_policy_masks = 1,
+ .policy_freq_offset = 0x00000008,
+ .freq_bit_shift = 8,
+ .policy_ctl_offset = 0x0000000c,
+ .policy0_mask_offset = 0x00000010,
+ .policy1_mask_offset = 0x00000014,
+ .policy2_mask_offset = 0x00000018,
+ .policy3_mask_offset = 0x0000001c,
+ .lvm_en_offset = 0x00000034,
+ .freq_id = 2,
+ .freq_tbl = master_axi_freq_tbl,
+};
+
+static struct ccu_clock kps_ccu_clk = {
+ .clk = {
+ .name = "kps_ccu_clk",
+ .ops = &ccu_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .num_policy_masks = 1,
+ .policy_freq_offset = 0x00000008,
+ .freq_bit_shift = 8,
+ .policy_ctl_offset = 0x0000000c,
+ .policy0_mask_offset = 0x00000010,
+ .policy1_mask_offset = 0x00000014,
+ .policy2_mask_offset = 0x00000018,
+ .policy3_mask_offset = 0x0000001c,
+ .lvm_en_offset = 0x00000034,
+ .freq_id = 2,
+ .freq_tbl = slave_axi_freq_tbl,
+};
+
+#ifdef CONFIG_BCM_SF2_ETH
+static struct ccu_clock esub_ccu_clk = {
+ .clk = {
+ .name = "esub_ccu_clk",
+ .ops = &ccu_clk_ops,
+ .ccu_clk_mgr_base = ESUB_CLK_BASE_ADDR,
+ },
+ .num_policy_masks = 1,
+ .policy_freq_offset = 0x00000008,
+ .freq_bit_shift = 8,
+ .policy_ctl_offset = 0x0000000c,
+ .policy0_mask_offset = 0x00000010,
+ .policy1_mask_offset = 0x00000014,
+ .policy2_mask_offset = 0x00000018,
+ .policy3_mask_offset = 0x0000001c,
+ .lvm_en_offset = 0x00000034,
+ .freq_id = 2,
+ .freq_tbl = esub_freq_tbl,
+};
+#endif
+
+/*
+ * Bus clocks
+ */
+
+/* KPM bus clocks */
+static struct bus_clock usb_otg_ahb_clk = {
+ .clk = {
+ .name = "usb_otg_ahb_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .freq_tbl = master_ahb_freq_tbl,
+ .data = &usb_otg_ahb_data,
+};
+
+static struct bus_clock sdio1_ahb_clk = {
+ .clk = {
+ .name = "sdio1_ahb_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .freq_tbl = master_ahb_freq_tbl,
+ .data = &sdio1_ahb_data,
+};
+
+static struct bus_clock sdio2_ahb_clk = {
+ .clk = {
+ .name = "sdio2_ahb_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .freq_tbl = master_ahb_freq_tbl,
+ .data = &sdio2_ahb_data,
+};
+
+static struct bus_clock sdio3_ahb_clk = {
+ .clk = {
+ .name = "sdio3_ahb_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .freq_tbl = master_ahb_freq_tbl,
+ .data = &sdio3_ahb_data,
+};
+
+static struct bus_clock sdio4_ahb_clk = {
+ .clk = {
+ .name = "sdio4_ahb_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .freq_tbl = master_ahb_freq_tbl,
+ .data = &sdio4_ahb_data,
+};
+
+static struct bus_clock bsc1_apb_clk = {
+ .clk = {
+ .name = "bsc1_apb_clk",
+ .parent = &kps_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .freq_tbl = slave_apb_freq_tbl,
+ .data = &bsc1_apb_data,
+};
+
+static struct bus_clock bsc2_apb_clk = {
+ .clk = {
+ .name = "bsc2_apb_clk",
+ .parent = &kps_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .freq_tbl = slave_apb_freq_tbl,
+ .data = &bsc2_apb_data,
+};
+
+static struct bus_clock bsc3_apb_clk = {
+ .clk = {
+ .name = "bsc3_apb_clk",
+ .parent = &kps_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .freq_tbl = slave_apb_freq_tbl,
+ .data = &bsc3_apb_data,
+};
+
+/* KPM peripheral */
+static struct peri_clock sdio1_clk = {
+ .clk = {
+ .name = "sdio1_clk",
+ .parent = &ref_52m.clk,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio1_data,
+};
+
+static struct peri_clock sdio2_clk = {
+ .clk = {
+ .name = "sdio2_clk",
+ .parent = &ref_52m.clk,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio2_data,
+};
+
+static struct peri_clock sdio3_clk = {
+ .clk = {
+ .name = "sdio3_clk",
+ .parent = &ref_52m.clk,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio3_data,
+};
+
+static struct peri_clock sdio4_clk = {
+ .clk = {
+ .name = "sdio4_clk",
+ .parent = &ref_52m.clk,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio4_data,
+};
+
+static struct peri_clock sdio1_sleep_clk = {
+ .clk = {
+ .name = "sdio1_sleep_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio1_sleep_data,
+};
+
+static struct peri_clock sdio2_sleep_clk = {
+ .clk = {
+ .name = "sdio2_sleep_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio2_sleep_data,
+};
+
+static struct peri_clock sdio3_sleep_clk = {
+ .clk = {
+ .name = "sdio3_sleep_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio3_sleep_data,
+};
+
+static struct peri_clock sdio4_sleep_clk = {
+ .clk = {
+ .name = "sdio4_sleep_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio4_sleep_data,
+};
+
+/* KPS peripheral clock */
+static struct peri_clock bsc1_clk = {
+ .clk = {
+ .name = "bsc1_clk",
+ .parent = &ref_13m.clk,
+ .rate = 13 * CLOCK_1M,
+ .div = 1,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .data = &bsc1_data,
+};
+
+static struct peri_clock bsc2_clk = {
+ .clk = {
+ .name = "bsc2_clk",
+ .parent = &ref_13m.clk,
+ .rate = 13 * CLOCK_1M,
+ .div = 1,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .data = &bsc2_data,
+};
+
+static struct peri_clock bsc3_clk = {
+ .clk = {
+ .name = "bsc3_clk",
+ .parent = &ref_13m.clk,
+ .rate = 13 * CLOCK_1M,
+ .div = 1,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .data = &bsc3_data,
+};
+
+/* public table for registering clocks */
+struct clk_lookup arch_clk_tbl[] = {
+ /* Peripheral clocks */
+ CLK_LK(sdio1),
+ CLK_LK(sdio2),
+ CLK_LK(sdio3),
+ CLK_LK(sdio4),
+ CLK_LK(sdio1_sleep),
+ CLK_LK(sdio2_sleep),
+ CLK_LK(sdio3_sleep),
+ CLK_LK(sdio4_sleep),
+ CLK_LK(bsc1),
+ CLK_LK(bsc2),
+ CLK_LK(bsc3),
+ /* Bus clocks */
+ CLK_LK(usb_otg_ahb),
+ CLK_LK(sdio1_ahb),
+ CLK_LK(sdio2_ahb),
+ CLK_LK(sdio3_ahb),
+ CLK_LK(sdio4_ahb),
+ CLK_LK(bsc1_apb),
+ CLK_LK(bsc2_apb),
+ CLK_LK(bsc3_apb),
+#ifdef CONFIG_BCM_SF2_ETH
+ CLK_LK(esub_ccu),
+#endif
+};
+
+/* public array size */
+unsigned int arch_clk_tbl_array_size = ARRAY_SIZE(arch_clk_tbl);
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-bsc.c b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-bsc.c
new file mode 100644
index 000000000..1b3f36aeb
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-bsc.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <asm/arch/sysmap.h>
+#include <asm/kona-common/clk.h>
+#include "clk-core.h"
+
+/* Enable appropriate clocks for a BSC/I2C port */
+int clk_bsc_enable(void *base)
+{
+ int ret;
+ char *bscstr, *apbstr;
+
+ switch ((u32) base) {
+ case PMU_BSC_BASE_ADDR:
+ /* PMU clock is always enabled */
+ return 0;
+ case BSC1_BASE_ADDR:
+ bscstr = "bsc1_clk";
+ apbstr = "bsc1_apb_clk";
+ break;
+ case BSC2_BASE_ADDR:
+ bscstr = "bsc2_clk";
+ apbstr = "bsc2_apb_clk";
+ break;
+ case BSC3_BASE_ADDR:
+ bscstr = "bsc3_clk";
+ apbstr = "bsc3_apb_clk";
+ break;
+ default:
+ printf("%s: base 0x%p not found\n", __func__, base);
+ return -EINVAL;
+ }
+
+ /* Note that the bus clock must be enabled first */
+
+ ret = clk_get_and_enable(apbstr);
+ if (ret)
+ return ret;
+
+ ret = clk_get_and_enable(bscstr);
+ if (ret)
+ return ret;
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-core.c b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-core.c
new file mode 100644
index 000000000..d7edefee2
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-core.c
@@ -0,0 +1,514 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+/*
+ *
+ * bcm235xx architecture clock framework
+ *
+ */
+
+#include <common.h>
+#include <log.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <bitfield.h>
+#include <asm/arch/sysmap.h>
+#include <asm/kona-common/clk.h>
+#include "clk-core.h"
+
+#define CLK_WR_ACCESS_PASSWORD 0x00a5a501
+#define WR_ACCESS_OFFSET 0 /* common to all clock blocks */
+#define POLICY_CTL_GO 1 /* Load and refresh policy masks */
+#define POLICY_CTL_GO_ATL 4 /* Active Load */
+
+/* Helper function */
+int clk_get_and_enable(char *clkstr)
+{
+ int ret = 0;
+ struct clk *c;
+
+ debug("%s: %s\n", __func__, clkstr);
+
+ c = clk_get(clkstr);
+ if (c) {
+ ret = clk_enable(c);
+ if (ret)
+ return ret;
+ } else {
+ printf("%s: Couldn't find %s\n", __func__, clkstr);
+ return -EINVAL;
+ }
+ return ret;
+}
+
+/*
+ * Poll a register in a CCU's address space, returning when the
+ * specified bit in that register's value is set (or clear). Delay
+ * a microsecond after each read of the register. Returns true if
+ * successful, or false if we gave up trying.
+ *
+ * Caller must ensure the CCU lock is held.
+ */
+#define CLK_GATE_DELAY_USEC 2000
+static inline int wait_bit(void *base, u32 offset, u32 bit, bool want)
+{
+ unsigned int tries;
+ u32 bit_mask = 1 << bit;
+
+ for (tries = 0; tries < CLK_GATE_DELAY_USEC; tries++) {
+ u32 val;
+ bool bit_val;
+
+ val = readl(base + offset);
+ bit_val = (val & bit_mask) ? 1 : 0;
+ if (bit_val == want)
+ return 0; /* success */
+ udelay(1);
+ }
+
+ debug("%s: timeout on addr 0x%p, waiting for bit %d to go to %d\n",
+ __func__, base + offset, bit, want);
+
+ return -ETIMEDOUT;
+}
+
+/* Enable a peripheral clock */
+static int peri_clk_enable(struct clk *c, int enable)
+{
+ int ret = 0;
+ u32 reg;
+ struct peri_clock *peri_clk = to_peri_clk(c);
+ struct peri_clk_data *cd = peri_clk->data;
+ struct bcm_clk_gate *gate = &cd->gate;
+ void *base = (void *)c->ccu_clk_mgr_base;
+
+
+ debug("%s: %s\n", __func__, c->name);
+
+ clk_get_rate(c); /* Make sure rate and sel are filled in */
+
+ /* enable access */
+ writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);
+
+ if (enable) {
+ debug("%s %s set rate %lu div %lu sel %d parent %lu\n",
+ __func__, c->name, c->rate, c->div, c->sel,
+ c->parent->rate);
+
+ /*
+ * clkgate - only software controllable gates are
+ * supported by u-boot which includes all clocks
+ * that matter. This avoids bringing in a lot of extra
+ * complexity as done in the kernel framework.
+ */
+ if (gate_exists(gate)) {
+ reg = readl(base + cd->gate.offset);
+ reg |= (1 << cd->gate.en_bit);
+ writel(reg, base + cd->gate.offset);
+ }
+
+ /* div and pll select */
+ if (divider_exists(&cd->div)) {
+ reg = readl(base + cd->div.offset);
+ bitfield_replace(reg, cd->div.shift, cd->div.width,
+ c->div - 1);
+ writel(reg, base + cd->div.offset);
+ }
+
+ /* frequency selector */
+ if (selector_exists(&cd->sel)) {
+ reg = readl(base + cd->sel.offset);
+ bitfield_replace(reg, cd->sel.shift, cd->sel.width,
+ c->sel);
+ writel(reg, base + cd->sel.offset);
+ }
+
+ /* trigger */
+ if (trigger_exists(&cd->trig)) {
+ writel((1 << cd->trig.bit), base + cd->trig.offset);
+
+ /* wait for trigger status bit to go to 0 */
+ ret = wait_bit(base, cd->trig.offset, cd->trig.bit, 0);
+ if (ret)
+ return ret;
+ }
+
+ /* wait for running (status_bit = 1) */
+ ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, 1);
+ if (ret)
+ return ret;
+ } else {
+ debug("%s disable clock %s\n", __func__, c->name);
+
+ /* clkgate */
+ reg = readl(base + cd->gate.offset);
+ reg &= ~(1 << cd->gate.en_bit);
+ writel(reg, base + cd->gate.offset);
+
+ /* wait for stop (status_bit = 0) */
+ ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, 0);
+ }
+
+ /* disable access */
+ writel(0, base + WR_ACCESS_OFFSET);
+
+ return ret;
+}
+
+/* Set the rate of a peripheral clock */
+static int peri_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret = 0;
+ int i;
+ unsigned long diff;
+ unsigned long new_rate = 0, div = 1;
+ struct peri_clock *peri_clk = to_peri_clk(c);
+ struct peri_clk_data *cd = peri_clk->data;
+ const char **clock;
+
+ debug("%s: %s\n", __func__, c->name);
+ diff = rate;
+
+ i = 0;
+ for (clock = cd->clocks; *clock; clock++, i++) {
+ struct refclk *ref = refclk_str_to_clk(*clock);
+ if (!ref) {
+ printf("%s: Lookup of %s failed\n", __func__, *clock);
+ return -EINVAL;
+ }
+
+ /* round to the new rate */
+ div = ref->clk.rate / rate;
+ if (div == 0)
+ div = 1;
+
+ new_rate = ref->clk.rate / div;
+
+ /* get the min diff */
+ if (abs(new_rate - rate) < diff) {
+ diff = abs(new_rate - rate);
+ c->sel = i;
+ c->parent = &ref->clk;
+ c->rate = new_rate;
+ c->div = div;
+ }
+ }
+
+ debug("%s %s set rate %lu div %lu sel %d parent %lu\n", __func__,
+ c->name, c->rate, c->div, c->sel, c->parent->rate);
+ return ret;
+}
+
+/* Get the rate of a peripheral clock */
+static unsigned long peri_clk_get_rate(struct clk *c)
+{
+ struct peri_clock *peri_clk = to_peri_clk(c);
+ struct peri_clk_data *cd = peri_clk->data;
+ void *base = (void *)c->ccu_clk_mgr_base;
+ int div = 1;
+ const char **clock;
+ struct refclk *ref;
+ u32 reg;
+
+ debug("%s: %s\n", __func__, c->name);
+ if (selector_exists(&cd->sel)) {
+ reg = readl(base + cd->sel.offset);
+ c->sel = bitfield_extract(reg, cd->sel.shift, cd->sel.width);
+ } else {
+ /*
+ * For peri clocks that don't have a selector, the single
+ * reference clock will always exist at index 0.
+ */
+ c->sel = 0;
+ }
+
+ if (divider_exists(&cd->div)) {
+ reg = readl(base + cd->div.offset);
+ div = bitfield_extract(reg, cd->div.shift, cd->div.width);
+ div += 1;
+ }
+
+ clock = cd->clocks;
+ ref = refclk_str_to_clk(clock[c->sel]);
+ if (!ref) {
+ printf("%s: Can't lookup %s\n", __func__, clock[c->sel]);
+ return 0;
+ }
+
+ c->parent = &ref->clk;
+ c->div = div;
+ c->rate = c->parent->rate / c->div;
+ debug("%s parent rate %lu div %d sel %d rate %lu\n", __func__,
+ c->parent->rate, div, c->sel, c->rate);
+
+ return c->rate;
+}
+
+/* Peripheral clock operations */
+struct clk_ops peri_clk_ops = {
+ .enable = peri_clk_enable,
+ .set_rate = peri_clk_set_rate,
+ .get_rate = peri_clk_get_rate,
+};
+
+/* Enable a CCU clock */
+static int ccu_clk_enable(struct clk *c, int enable)
+{
+ struct ccu_clock *ccu_clk = to_ccu_clk(c);
+ void *base = (void *)c->ccu_clk_mgr_base;
+ int ret = 0;
+ u32 reg;
+
+ debug("%s: %s\n", __func__, c->name);
+ if (!enable)
+ return -EINVAL; /* CCU clock cannot shutdown */
+
+ /* enable access */
+ writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);
+
+ /* config enable for policy engine */
+ writel(1, base + ccu_clk->lvm_en_offset);
+
+ /* wait for bit to go to 0 */
+ ret = wait_bit(base, ccu_clk->lvm_en_offset, 0, 0);
+ if (ret)
+ return ret;
+
+ /* freq ID */
+ if (!ccu_clk->freq_bit_shift)
+ ccu_clk->freq_bit_shift = 8;
+
+ /* Set frequency id for each of the 4 policies */
+ reg = ccu_clk->freq_id |
+ (ccu_clk->freq_id << (ccu_clk->freq_bit_shift)) |
+ (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 2)) |
+ (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 3));
+ writel(reg, base + ccu_clk->policy_freq_offset);
+
+ /* enable all clock mask */
+ writel(0x7fffffff, base + ccu_clk->policy0_mask_offset);
+ writel(0x7fffffff, base + ccu_clk->policy1_mask_offset);
+ writel(0x7fffffff, base + ccu_clk->policy2_mask_offset);
+ writel(0x7fffffff, base + ccu_clk->policy3_mask_offset);
+
+ if (ccu_clk->num_policy_masks == 2) {
+ writel(0x7fffffff, base + ccu_clk->policy0_mask2_offset);
+ writel(0x7fffffff, base + ccu_clk->policy1_mask2_offset);
+ writel(0x7fffffff, base + ccu_clk->policy2_mask2_offset);
+ writel(0x7fffffff, base + ccu_clk->policy3_mask2_offset);
+ }
+
+ /* start policy engine */
+ reg = readl(base + ccu_clk->policy_ctl_offset);
+ reg |= (POLICY_CTL_GO + POLICY_CTL_GO_ATL);
+ writel(reg, base + ccu_clk->policy_ctl_offset);
+
+ /* wait till started */
+ ret = wait_bit(base, ccu_clk->policy_ctl_offset, 0, 0);
+ if (ret)
+ return ret;
+
+ /* disable access */
+ writel(0, base + WR_ACCESS_OFFSET);
+
+ return ret;
+}
+
+/* Get the CCU clock rate */
+static unsigned long ccu_clk_get_rate(struct clk *c)
+{
+ struct ccu_clock *ccu_clk = to_ccu_clk(c);
+ debug("%s: %s\n", __func__, c->name);
+ c->rate = ccu_clk->freq_tbl[ccu_clk->freq_id];
+ return c->rate;
+}
+
+/* CCU clock operations */
+struct clk_ops ccu_clk_ops = {
+ .enable = ccu_clk_enable,
+ .get_rate = ccu_clk_get_rate,
+};
+
+/* Enable a bus clock */
+static int bus_clk_enable(struct clk *c, int enable)
+{
+ struct bus_clock *bus_clk = to_bus_clk(c);
+ struct bus_clk_data *cd = bus_clk->data;
+ void *base = (void *)c->ccu_clk_mgr_base;
+ int ret = 0;
+ u32 reg;
+
+ debug("%s: %s\n", __func__, c->name);
+ /* enable access */
+ writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);
+
+ /* enable gating */
+ reg = readl(base + cd->gate.offset);
+ if (!!(reg & (1 << cd->gate.status_bit)) == !!enable)
+ debug("%s already %s\n", c->name,
+ enable ? "enabled" : "disabled");
+ else {
+ int want = (enable) ? 1 : 0;
+ reg |= (1 << cd->gate.hw_sw_sel_bit);
+
+ if (enable)
+ reg |= (1 << cd->gate.en_bit);
+ else
+ reg &= ~(1 << cd->gate.en_bit);
+
+ writel(reg, base + cd->gate.offset);
+ ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit,
+ want);
+ if (ret)
+ return ret;
+ }
+
+ /* disable access */
+ writel(0, base + WR_ACCESS_OFFSET);
+
+ return ret;
+}
+
+/* Get the rate of a bus clock */
+static unsigned long bus_clk_get_rate(struct clk *c)
+{
+ struct bus_clock *bus_clk = to_bus_clk(c);
+ struct ccu_clock *ccu_clk;
+
+ debug("%s: %s\n", __func__, c->name);
+ ccu_clk = to_ccu_clk(c->parent);
+
+ c->rate = bus_clk->freq_tbl[ccu_clk->freq_id];
+ c->div = ccu_clk->freq_tbl[ccu_clk->freq_id] / c->rate;
+ return c->rate;
+}
+
+/* Bus clock operations */
+struct clk_ops bus_clk_ops = {
+ .enable = bus_clk_enable,
+ .get_rate = bus_clk_get_rate,
+};
+
+/* Enable a reference clock */
+static int ref_clk_enable(struct clk *c, int enable)
+{
+ debug("%s: %s\n", __func__, c->name);
+ return 0;
+}
+
+/* Reference clock operations */
+struct clk_ops ref_clk_ops = {
+ .enable = ref_clk_enable,
+};
+
+/*
+ * clk.h implementation follows
+ */
+
+/* Initialize the clock framework */
+int clk_init(void)
+{
+ debug("%s:\n", __func__);
+ return 0;
+}
+
+/* Get a clock handle, give a name string */
+struct clk *clk_get(const char *con_id)
+{
+ int i;
+ struct clk_lookup *clk_tblp;
+
+ debug("%s: %s\n", __func__, con_id);
+
+ clk_tblp = arch_clk_tbl;
+ for (i = 0; i < arch_clk_tbl_array_size; i++, clk_tblp++) {
+ if (clk_tblp->con_id) {
+ if (!con_id || strcmp(clk_tblp->con_id, con_id))
+ continue;
+ return clk_tblp->clk;
+ }
+ }
+ return NULL;
+}
+
+/* Enable a clock */
+int clk_enable(struct clk *c)
+{
+ int ret = 0;
+
+ debug("%s: %s\n", __func__, c->name);
+ if (!c->ops || !c->ops->enable)
+ return -1;
+
+ /* enable parent clock first */
+ if (c->parent)
+ ret = clk_enable(c->parent);
+
+ if (ret)
+ return ret;
+
+ if (!c->use_cnt)
+ ret = c->ops->enable(c, 1);
+ c->use_cnt++;
+
+ return ret;
+}
+
+/* Disable a clock */
+void clk_disable(struct clk *c)
+{
+ debug("%s: %s\n", __func__, c->name);
+ if (!c->ops || !c->ops->enable)
+ return;
+
+ if (c->use_cnt > 0) {
+ c->use_cnt--;
+ if (c->use_cnt == 0)
+ c->ops->enable(c, 0);
+ }
+
+ /* disable parent */
+ if (c->parent)
+ clk_disable(c->parent);
+}
+
+/* Get the clock rate */
+unsigned long clk_get_rate(struct clk *c)
+{
+ unsigned long rate;
+
+ if (!c || !c->ops || !c->ops->get_rate)
+ return 0;
+ debug("%s: %s\n", __func__, c->name);
+
+ rate = c->ops->get_rate(c);
+ debug("%s: rate = %ld\n", __func__, rate);
+ return rate;
+}
+
+/* Set the clock rate */
+int clk_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret;
+
+ if (!c || !c->ops || !c->ops->set_rate)
+ return -EINVAL;
+ debug("%s: %s rate=%ld\n", __func__, c->name, rate);
+
+ if (c->use_cnt)
+ return -EINVAL;
+
+ ret = c->ops->set_rate(c, rate);
+
+ return ret;
+}
+
+/* Not required for this arch */
+/*
+long clk_round_rate(struct clk *clk, unsigned long rate);
+int clk_set_parent(struct clk *clk, struct clk *parent);
+struct clk *clk_get_parent(struct clk *clk);
+*/
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-core.h b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-core.h
new file mode 100644
index 000000000..ace384dea
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-core.h
@@ -0,0 +1,491 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+#include <linux/stddef.h>
+#include <linux/stringify.h>
+
+#ifdef CONFIG_CLK_DEBUG
+#undef writel
+#undef readl
+static inline void writel(u32 val, void *addr)
+{
+ printf("Write [0x%p] = 0x%08x\n", addr, val);
+ *(u32 *)addr = val;
+}
+
+static inline u32 readl(void *addr)
+{
+ u32 val = *(u32 *)addr;
+ printf("Read [0x%p] = 0x%08x\n", addr, val);
+ return val;
+}
+#endif
+
+struct clk;
+
+struct clk_lookup {
+ const char *dev_id;
+ const char *con_id;
+ struct clk *clk;
+};
+
+extern struct clk_lookup arch_clk_tbl[];
+extern unsigned int arch_clk_tbl_array_size;
+
+/**
+ * struct clk_ops - standard clock operations
+ * @enable: enable/disable clock, see clk_enable() and clk_disable()
+ * @set_rate: set the clock rate, see clk_set_rate().
+ * @get_rate: get the clock rate, see clk_get_rate().
+ * @round_rate: round a given clock rate, see clk_round_rate().
+ * @set_parent: set the clock's parent, see clk_set_parent().
+ *
+ * Group the common clock implementations together so that we
+ * don't have to keep setting the same fiels again. We leave
+ * enable in struct clk.
+ *
+ */
+struct clk_ops {
+ int (*enable)(struct clk *c, int enable);
+ int (*set_rate)(struct clk *c, unsigned long rate);
+ unsigned long (*get_rate)(struct clk *c);
+ unsigned long (*round_rate)(struct clk *c, unsigned long rate);
+ int (*set_parent)(struct clk *c, struct clk *parent);
+};
+
+struct clk {
+ struct clk *parent;
+ const char *name;
+ int use_cnt;
+ unsigned long rate; /* in HZ */
+
+ /* programmable divider. 0 means fixed ratio to parent clock */
+ unsigned long div;
+
+ struct clk_src *src;
+ struct clk_ops *ops;
+
+ unsigned long ccu_clk_mgr_base;
+ int sel;
+};
+
+struct refclk *refclk_str_to_clk(const char *name);
+
+/* The common clock framework uses u8 to represent a parent index */
+#define PARENT_COUNT_MAX ((u32)U8_MAX)
+
+#define BAD_CLK_INDEX U8_MAX /* Can't ever be valid */
+#define BAD_CLK_NAME ((const char *)-1)
+
+#define BAD_SCALED_DIV_VALUE U64_MAX
+
+/*
+ * Utility macros for object flag management. If possible, flags
+ * should be defined such that 0 is the desired default value.
+ */
+#define FLAG(type, flag) BCM_CLK_ ## type ## _FLAGS_ ## flag
+#define FLAG_SET(obj, type, flag) ((obj)->flags |= FLAG(type, flag))
+#define FLAG_CLEAR(obj, type, flag) ((obj)->flags &= ~(FLAG(type, flag)))
+#define FLAG_FLIP(obj, type, flag) ((obj)->flags ^= FLAG(type, flag))
+#define FLAG_TEST(obj, type, flag) (!!((obj)->flags & FLAG(type, flag)))
+
+/* Clock field state tests */
+
+#define gate_exists(gate) FLAG_TEST(gate, GATE, EXISTS)
+#define gate_is_enabled(gate) FLAG_TEST(gate, GATE, ENABLED)
+#define gate_is_hw_controllable(gate) FLAG_TEST(gate, GATE, HW)
+#define gate_is_sw_controllable(gate) FLAG_TEST(gate, GATE, SW)
+#define gate_is_sw_managed(gate) FLAG_TEST(gate, GATE, SW_MANAGED)
+#define gate_is_no_disable(gate) FLAG_TEST(gate, GATE, NO_DISABLE)
+
+#define gate_flip_enabled(gate) FLAG_FLIP(gate, GATE, ENABLED)
+
+#define divider_exists(div) FLAG_TEST(div, DIV, EXISTS)
+#define divider_is_fixed(div) FLAG_TEST(div, DIV, FIXED)
+#define divider_has_fraction(div) (!divider_is_fixed(div) && \
+ (div)->frac_width > 0)
+
+#define selector_exists(sel) ((sel)->width != 0)
+#define trigger_exists(trig) FLAG_TEST(trig, TRIG, EXISTS)
+
+/* Clock type, used to tell common block what it's part of */
+enum bcm_clk_type {
+ bcm_clk_none, /* undefined clock type */
+ bcm_clk_bus,
+ bcm_clk_core,
+ bcm_clk_peri
+};
+
+/*
+ * Gating control and status is managed by a 32-bit gate register.
+ *
+ * There are several types of gating available:
+ * - (no gate)
+ * A clock with no gate is assumed to be always enabled.
+ * - hardware-only gating (auto-gating)
+ * Enabling or disabling clocks with this type of gate is
+ * managed automatically by the hardware. Such clocks can be
+ * considered by the software to be enabled. The current status
+ * of auto-gated clocks can be read from the gate status bit.
+ * - software-only gating
+ * Auto-gating is not available for this type of clock.
+ * Instead, software manages whether it's enabled by setting or
+ * clearing the enable bit. The current gate status of a gate
+ * under software control can be read from the gate status bit.
+ * To ensure a change to the gating status is complete, the
+ * status bit can be polled to verify that the gate has entered
+ * the desired state.
+ * - selectable hardware or software gating
+ * Gating for this type of clock can be configured to be either
+ * under software or hardware control. Which type is in use is
+ * determined by the hw_sw_sel bit of the gate register.
+ */
+struct bcm_clk_gate {
+ u32 offset; /* gate register offset */
+ u32 status_bit; /* 0: gate is disabled; 0: gatge is enabled */
+ u32 en_bit; /* 0: disable; 1: enable */
+ u32 hw_sw_sel_bit; /* 0: hardware gating; 1: software gating */
+ u32 flags; /* BCM_CLK_GATE_FLAGS_* below */
+};
+
+/*
+ * Gate flags:
+ * HW means this gate can be auto-gated
+ * SW means the state of this gate can be software controlled
+ * NO_DISABLE means this gate is (only) enabled if under software control
+ * SW_MANAGED means the status of this gate is under software control
+ * ENABLED means this software-managed gate is *supposed* to be enabled
+ */
+#define BCM_CLK_GATE_FLAGS_EXISTS ((u32)1 << 0) /* Gate is valid */
+#define BCM_CLK_GATE_FLAGS_HW ((u32)1 << 1) /* Can auto-gate */
+#define BCM_CLK_GATE_FLAGS_SW ((u32)1 << 2) /* Software control */
+#define BCM_CLK_GATE_FLAGS_NO_DISABLE ((u32)1 << 3) /* HW or enabled */
+#define BCM_CLK_GATE_FLAGS_SW_MANAGED ((u32)1 << 4) /* SW now in control */
+#define BCM_CLK_GATE_FLAGS_ENABLED ((u32)1 << 5) /* If SW_MANAGED */
+
+/*
+ * Gate initialization macros.
+ *
+ * Any gate initially under software control will be enabled.
+ */
+
+/* A hardware/software gate initially under software control */
+#define HW_SW_GATE(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \
+ { \
+ .offset = (_offset), \
+ .status_bit = (_status_bit), \
+ .en_bit = (_en_bit), \
+ .hw_sw_sel_bit = (_hw_sw_sel_bit), \
+ .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \
+ FLAG(GATE, SW_MANAGED)|FLAG(GATE, ENABLED)| \
+ FLAG(GATE, EXISTS), \
+ }
+
+/* A hardware/software gate initially under hardware control */
+#define HW_SW_GATE_AUTO(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \
+ { \
+ .offset = (_offset), \
+ .status_bit = (_status_bit), \
+ .en_bit = (_en_bit), \
+ .hw_sw_sel_bit = (_hw_sw_sel_bit), \
+ .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \
+ FLAG(GATE, EXISTS), \
+ }
+
+/* A hardware-or-enabled gate (enabled if not under hardware control) */
+#define HW_ENABLE_GATE(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \
+ { \
+ .offset = (_offset), \
+ .status_bit = (_status_bit), \
+ .en_bit = (_en_bit), \
+ .hw_sw_sel_bit = (_hw_sw_sel_bit), \
+ .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \
+ FLAG(GATE, NO_DISABLE)|FLAG(GATE, EXISTS), \
+ }
+
+/* A software-only gate */
+#define SW_ONLY_GATE(_offset, _status_bit, _en_bit) \
+ { \
+ .offset = (_offset), \
+ .status_bit = (_status_bit), \
+ .en_bit = (_en_bit), \
+ .flags = FLAG(GATE, SW)|FLAG(GATE, SW_MANAGED)| \
+ FLAG(GATE, ENABLED)|FLAG(GATE, EXISTS), \
+ }
+
+/* A hardware-only gate */
+#define HW_ONLY_GATE(_offset, _status_bit) \
+ { \
+ .offset = (_offset), \
+ .status_bit = (_status_bit), \
+ .flags = FLAG(GATE, HW)|FLAG(GATE, EXISTS), \
+ }
+
+/*
+ * Each clock can have zero, one, or two dividers which change the
+ * output rate of the clock. Each divider can be either fixed or
+ * variable. If there are two dividers, they are the "pre-divider"
+ * and the "regular" or "downstream" divider. If there is only one,
+ * there is no pre-divider.
+ *
+ * A fixed divider is any non-zero (positive) value, and it
+ * indicates how the input rate is affected by the divider.
+ *
+ * The value of a variable divider is maintained in a sub-field of a
+ * 32-bit divider register. The position of the field in the
+ * register is defined by its offset and width. The value recorded
+ * in this field is always 1 less than the value it represents.
+ *
+ * In addition, a variable divider can indicate that some subset
+ * of its bits represent a "fractional" part of the divider. Such
+ * bits comprise the low-order portion of the divider field, and can
+ * be viewed as representing the portion of the divider that lies to
+ * the right of the decimal point. Most variable dividers have zero
+ * fractional bits. Variable dividers with non-zero fraction width
+ * still record a value 1 less than the value they represent; the
+ * added 1 does *not* affect the low-order bit in this case, it
+ * affects the bits above the fractional part only. (Often in this
+ * code a divider field value is distinguished from the value it
+ * represents by referring to the latter as a "divisor".)
+ *
+ * In order to avoid dealing with fractions, divider arithmetic is
+ * performed using "scaled" values. A scaled value is one that's
+ * been left-shifted by the fractional width of a divider. Dividing
+ * a scaled value by a scaled divisor produces the desired quotient
+ * without loss of precision and without any other special handling
+ * for fractions.
+ *
+ * The recorded value of a variable divider can be modified. To
+ * modify either divider (or both), a clock must be enabled (i.e.,
+ * using its gate). In addition, a trigger register (described
+ * below) must be used to commit the change, and polled to verify
+ * the change is complete.
+ */
+struct bcm_clk_div {
+ union {
+ struct { /* variable divider */
+ u32 offset; /* divider register offset */
+ u32 shift; /* field shift */
+ u32 width; /* field width */
+ u32 frac_width; /* field fraction width */
+
+ u64 scaled_div; /* scaled divider value */
+ };
+ u32 fixed; /* non-zero fixed divider value */
+ };
+ u32 flags; /* BCM_CLK_DIV_FLAGS_* below */
+};
+
+/*
+ * Divider flags:
+ * EXISTS means this divider exists
+ * FIXED means it is a fixed-rate divider
+ */
+#define BCM_CLK_DIV_FLAGS_EXISTS ((u32)1 << 0) /* Divider is valid */
+#define BCM_CLK_DIV_FLAGS_FIXED ((u32)1 << 1) /* Fixed-value */
+
+/* Divider initialization macros */
+
+/* A fixed (non-zero) divider */
+#define FIXED_DIVIDER(_value) \
+ { \
+ .fixed = (_value), \
+ .flags = FLAG(DIV, EXISTS)|FLAG(DIV, FIXED), \
+ }
+
+/* A divider with an integral divisor */
+#define DIVIDER(_offset, _shift, _width) \
+ { \
+ .offset = (_offset), \
+ .shift = (_shift), \
+ .width = (_width), \
+ .scaled_div = BAD_SCALED_DIV_VALUE, \
+ .flags = FLAG(DIV, EXISTS), \
+ }
+
+/* A divider whose divisor has an integer and fractional part */
+#define FRAC_DIVIDER(_offset, _shift, _width, _frac_width) \
+ { \
+ .offset = (_offset), \
+ .shift = (_shift), \
+ .width = (_width), \
+ .frac_width = (_frac_width), \
+ .scaled_div = BAD_SCALED_DIV_VALUE, \
+ .flags = FLAG(DIV, EXISTS), \
+ }
+
+/*
+ * Clocks may have multiple "parent" clocks. If there is more than
+ * one, a selector must be specified to define which of the parent
+ * clocks is currently in use. The selected clock is indicated in a
+ * sub-field of a 32-bit selector register. The range of
+ * representable selector values typically exceeds the number of
+ * available parent clocks. Occasionally the reset value of a
+ * selector field is explicitly set to a (specific) value that does
+ * not correspond to a defined input clock.
+ *
+ * We register all known parent clocks with the common clock code
+ * using a packed array (i.e., no empty slots) of (parent) clock
+ * names, and refer to them later using indexes into that array.
+ * We maintain an array of selector values indexed by common clock
+ * index values in order to map between these common clock indexes
+ * and the selector values used by the hardware.
+ *
+ * Like dividers, a selector can be modified, but to do so a clock
+ * must be enabled, and a trigger must be used to commit the change.
+ */
+struct bcm_clk_sel {
+ u32 offset; /* selector register offset */
+ u32 shift; /* field shift */
+ u32 width; /* field width */
+
+ u32 parent_count; /* number of entries in parent_sel[] */
+ u32 *parent_sel; /* array of parent selector values */
+ u8 clk_index; /* current selected index in parent_sel[] */
+};
+
+/* Selector initialization macro */
+#define SELECTOR(_offset, _shift, _width) \
+ { \
+ .offset = (_offset), \
+ .shift = (_shift), \
+ .width = (_width), \
+ .clk_index = BAD_CLK_INDEX, \
+ }
+
+/*
+ * Making changes to a variable divider or a selector for a clock
+ * requires the use of a trigger. A trigger is defined by a single
+ * bit within a register. To signal a change, a 1 is written into
+ * that bit. To determine when the change has been completed, that
+ * trigger bit is polled; the read value will be 1 while the change
+ * is in progress, and 0 when it is complete.
+ *
+ * Occasionally a clock will have more than one trigger. In this
+ * case, the "pre-trigger" will be used when changing a clock's
+ * selector and/or its pre-divider.
+ */
+struct bcm_clk_trig {
+ u32 offset; /* trigger register offset */
+ u32 bit; /* trigger bit */
+ u32 flags; /* BCM_CLK_TRIG_FLAGS_* below */
+};
+
+/*
+ * Trigger flags:
+ * EXISTS means this trigger exists
+ */
+#define BCM_CLK_TRIG_FLAGS_EXISTS ((u32)1 << 0) /* Trigger is valid */
+
+/* Trigger initialization macro */
+#define TRIGGER(_offset, _bit) \
+ { \
+ .offset = (_offset), \
+ .bit = (_bit), \
+ .flags = FLAG(TRIG, EXISTS), \
+ }
+
+struct bus_clk_data {
+ struct bcm_clk_gate gate;
+};
+
+struct core_clk_data {
+ struct bcm_clk_gate gate;
+};
+
+struct peri_clk_data {
+ struct bcm_clk_gate gate;
+ struct bcm_clk_trig pre_trig;
+ struct bcm_clk_div pre_div;
+ struct bcm_clk_trig trig;
+ struct bcm_clk_div div;
+ struct bcm_clk_sel sel;
+ const char *clocks[]; /* must be last; use CLOCKS() to declare */
+};
+#define CLOCKS(...) { __VA_ARGS__, NULL, }
+#define NO_CLOCKS { NULL, } /* Must use of no parent clocks */
+
+struct refclk {
+ struct clk clk;
+};
+
+struct peri_clock {
+ struct clk clk;
+ struct peri_clk_data *data;
+};
+
+struct ccu_clock {
+ struct clk clk;
+
+ int num_policy_masks;
+ unsigned long policy_freq_offset;
+ int freq_bit_shift; /* 8 for most CCUs */
+ unsigned long policy_ctl_offset;
+ unsigned long policy0_mask_offset;
+ unsigned long policy1_mask_offset;
+ unsigned long policy2_mask_offset;
+ unsigned long policy3_mask_offset;
+ unsigned long policy0_mask2_offset;
+ unsigned long policy1_mask2_offset;
+ unsigned long policy2_mask2_offset;
+ unsigned long policy3_mask2_offset;
+ unsigned long lvm_en_offset;
+
+ int freq_id;
+ unsigned long *freq_tbl;
+};
+
+struct bus_clock {
+ struct clk clk;
+ struct bus_clk_data *data;
+ unsigned long *freq_tbl;
+};
+
+struct ref_clock {
+ struct clk clk;
+};
+
+static inline int is_same_clock(struct clk *a, struct clk *b)
+{
+ return a == b;
+}
+
+#define to_clk(p) (&((p)->clk))
+#define name_to_clk(name) (&((name##_clk).clk))
+/* declare a struct clk_lookup */
+#define CLK_LK(name) \
+{.con_id = __stringify(name##_clk), .clk = name_to_clk(name),}
+
+static inline struct refclk *to_refclk(struct clk *clock)
+{
+ return container_of(clock, struct refclk, clk);
+}
+
+static inline struct peri_clock *to_peri_clk(struct clk *clock)
+{
+ return container_of(clock, struct peri_clock, clk);
+}
+
+static inline struct ccu_clock *to_ccu_clk(struct clk *clock)
+{
+ return container_of(clock, struct ccu_clock, clk);
+}
+
+static inline struct bus_clock *to_bus_clk(struct clk *clock)
+{
+ return container_of(clock, struct bus_clock, clk);
+}
+
+static inline struct ref_clock *to_ref_clk(struct clk *clock)
+{
+ return container_of(clock, struct ref_clock, clk);
+}
+
+extern struct clk_ops peri_clk_ops;
+extern struct clk_ops ccu_clk_ops;
+extern struct clk_ops bus_clk_ops;
+extern struct clk_ops ref_clk_ops;
+
+int clk_get_and_enable(char *clkstr);
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-eth.c b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-eth.c
new file mode 100644
index 000000000..209ceca9a
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-eth.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <asm/arch/sysmap.h>
+#include <asm/kona-common/clk.h>
+#include "clk-core.h"
+
+#define WR_ACCESS_ADDR ESUB_CLK_BASE_ADDR
+#define WR_ACCESS_PASSWORD 0xA5A500
+
+#define PLLE_POST_RESETB_ADDR (ESUB_CLK_BASE_ADDR + 0x00000C00)
+
+#define PLLE_RESETB_ADDR (ESUB_CLK_BASE_ADDR + 0x00000C58)
+#define PLLE_RESETB_I_PLL_RESETB_PLLE_MASK 0x00010000
+#define PLLE_POST_RESETB_I_POST_RESETB_PLLE_MASK 0x00000001
+
+#define PLL_LOCK_ADDR (ESUB_CLK_BASE_ADDR + 0x00000C38)
+#define PLL_LOCK_PLL_LOCK_PLLE_MASK 0x00000001
+
+#define ESW_SYS_DIV_ADDR (ESUB_CLK_BASE_ADDR + 0x00000A04)
+#define ESW_SYS_DIV_PLL_SELECT_MASK 0x00000300
+#define ESW_SYS_DIV_DIV_MASK 0x0000001C
+#define ESW_SYS_DIV_PLL_VAR_208M_CLK_SELECT 0x00000100
+#define ESW_SYS_DIV_DIV_SELECT 0x4
+#define ESW_SYS_DIV_TRIGGER_MASK 0x00000001
+
+#define ESUB_AXI_DIV_DEBUG_ADDR (ESUB_CLK_BASE_ADDR + 0x00000E04)
+#define ESUB_AXI_DIV_DEBUG_PLL_SELECT_MASK 0x0000001C
+#define ESUB_AXI_DIV_DEBUG_PLL_SELECT_OVERRIDE_MASK 0x00000040
+#define ESUB_AXI_DIV_DEBUG_PLL_VAR_208M_CLK_SELECT 0x0
+#define ESUB_AXI_DIV_DEBUG_TRIGGER_MASK 0x00000001
+
+#define PLL_MAX_RETRY 100
+
+/* Enable appropriate clocks for Ethernet */
+int clk_eth_enable(void)
+{
+ int rc = -1;
+ int retry_count = 0;
+ rc = clk_get_and_enable("esub_ccu_clk");
+
+ /* Enable Access to CCU registers */
+ writel((1 | WR_ACCESS_PASSWORD), WR_ACCESS_ADDR);
+
+ writel(readl(PLLE_POST_RESETB_ADDR) &
+ ~PLLE_POST_RESETB_I_POST_RESETB_PLLE_MASK,
+ PLLE_POST_RESETB_ADDR);
+
+ /* Take PLL out of reset and put into normal mode */
+ writel(readl(PLLE_RESETB_ADDR) | PLLE_RESETB_I_PLL_RESETB_PLLE_MASK,
+ PLLE_RESETB_ADDR);
+
+ /* Wait for PLL lock */
+ rc = -1;
+ while (retry_count < PLL_MAX_RETRY) {
+ udelay(100);
+ if (readl(PLL_LOCK_ADDR) & PLL_LOCK_PLL_LOCK_PLLE_MASK) {
+ rc = 0;
+ break;
+ }
+ retry_count++;
+ }
+
+ if (rc == -1) {
+ printf("%s: ETH-PLL lock timeout, Ethernet is not enabled!\n",
+ __func__);
+ return -1;
+ }
+
+ writel(readl(PLLE_POST_RESETB_ADDR) |
+ PLLE_POST_RESETB_I_POST_RESETB_PLLE_MASK,
+ PLLE_POST_RESETB_ADDR);
+
+ /* Switch esw_sys_clk to use 104MHz(208MHz/2) clock */
+ writel((readl(ESW_SYS_DIV_ADDR) &
+ ~(ESW_SYS_DIV_PLL_SELECT_MASK | ESW_SYS_DIV_DIV_MASK)) |
+ ESW_SYS_DIV_PLL_VAR_208M_CLK_SELECT | ESW_SYS_DIV_DIV_SELECT,
+ ESW_SYS_DIV_ADDR);
+
+ writel(readl(ESW_SYS_DIV_ADDR) | ESW_SYS_DIV_TRIGGER_MASK,
+ ESW_SYS_DIV_ADDR);
+
+ /* Wait for trigger complete */
+ rc = -1;
+ retry_count = 0;
+ while (retry_count < PLL_MAX_RETRY) {
+ udelay(100);
+ if (!(readl(ESW_SYS_DIV_ADDR) & ESW_SYS_DIV_TRIGGER_MASK)) {
+ rc = 0;
+ break;
+ }
+ retry_count++;
+ }
+
+ if (rc == -1) {
+ printf("%s: SYS CLK Trigger timeout, Ethernet is not enabled!\n",
+ __func__);
+ return -1;
+ }
+
+ /* switch Esub AXI clock to 208MHz */
+ writel((readl(ESUB_AXI_DIV_DEBUG_ADDR) &
+ ~(ESUB_AXI_DIV_DEBUG_PLL_SELECT_MASK |
+ ESUB_AXI_DIV_DEBUG_PLL_SELECT_OVERRIDE_MASK |
+ ESUB_AXI_DIV_DEBUG_TRIGGER_MASK)) |
+ ESUB_AXI_DIV_DEBUG_PLL_VAR_208M_CLK_SELECT |
+ ESUB_AXI_DIV_DEBUG_PLL_SELECT_OVERRIDE_MASK,
+ ESUB_AXI_DIV_DEBUG_ADDR);
+
+ writel(readl(ESUB_AXI_DIV_DEBUG_ADDR) |
+ ESUB_AXI_DIV_DEBUG_TRIGGER_MASK,
+ ESUB_AXI_DIV_DEBUG_ADDR);
+
+ /* Wait for trigger complete */
+ rc = -1;
+ retry_count = 0;
+ while (retry_count < PLL_MAX_RETRY) {
+ udelay(100);
+ if (!(readl(ESUB_AXI_DIV_DEBUG_ADDR) &
+ ESUB_AXI_DIV_DEBUG_TRIGGER_MASK)) {
+ rc = 0;
+ break;
+ }
+ retry_count++;
+ }
+
+ if (rc == -1) {
+ printf("%s: AXI CLK Trigger timeout, Ethernet is not enabled!\n",
+ __func__);
+ return -1;
+ }
+
+ /* Disable Access to CCU registers */
+ writel(WR_ACCESS_PASSWORD, WR_ACCESS_ADDR);
+
+ return rc;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-sdio.c b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-sdio.c
new file mode 100644
index 000000000..f2ba354c2
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-sdio.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <asm/arch/sysmap.h>
+#include <asm/kona-common/clk.h>
+#include "clk-core.h"
+
+/* Enable appropriate clocks for an SDIO port */
+int clk_sdio_enable(void *base, u32 rate, u32 *actual_ratep)
+{
+ int ret;
+ struct clk *c;
+
+ char *clkstr;
+ char *slpstr;
+ char *ahbstr;
+
+ switch ((u32) base) {
+ case CONFIG_SYS_SDIO_BASE0:
+ clkstr = CONFIG_SYS_SDIO0 "_clk";
+ ahbstr = CONFIG_SYS_SDIO0 "_ahb_clk";
+ slpstr = CONFIG_SYS_SDIO0 "_sleep_clk";
+ break;
+ case CONFIG_SYS_SDIO_BASE1:
+ clkstr = CONFIG_SYS_SDIO1 "_clk";
+ ahbstr = CONFIG_SYS_SDIO1 "_ahb_clk";
+ slpstr = CONFIG_SYS_SDIO1 "_sleep_clk";
+ break;
+ case CONFIG_SYS_SDIO_BASE2:
+ clkstr = CONFIG_SYS_SDIO2 "_clk";
+ ahbstr = CONFIG_SYS_SDIO2 "_ahb_clk";
+ slpstr = CONFIG_SYS_SDIO2 "_sleep_clk";
+ break;
+ case CONFIG_SYS_SDIO_BASE3:
+ clkstr = CONFIG_SYS_SDIO3 "_clk";
+ ahbstr = CONFIG_SYS_SDIO3 "_ahb_clk";
+ slpstr = CONFIG_SYS_SDIO3 "_sleep_clk";
+ break;
+ default:
+ printf("%s: base 0x%p not found\n", __func__, base);
+ return -EINVAL;
+ }
+
+ ret = clk_get_and_enable(ahbstr);
+ if (ret)
+ return ret;
+
+ ret = clk_get_and_enable(slpstr);
+ if (ret)
+ return ret;
+
+ c = clk_get(clkstr);
+ if (c) {
+ ret = clk_set_rate(c, rate);
+ if (ret)
+ return ret;
+
+ ret = clk_enable(c);
+ if (ret)
+ return ret;
+ } else {
+ printf("%s: Couldn't find %s\n", __func__, clkstr);
+ return -EINVAL;
+ }
+ *actual_ratep = rate;
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-usb-otg.c b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-usb-otg.c
new file mode 100644
index 000000000..f604aec62
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm235xx/clk-usb-otg.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <linux/errno.h>
+#include <asm/arch/sysmap.h>
+#include "clk-core.h"
+
+/* Enable appropriate clocks for the USB OTG port */
+int clk_usb_otg_enable(void *base)
+{
+ char *ahbstr;
+
+ switch ((u32) base) {
+ case HSOTG_BASE_ADDR:
+ ahbstr = "usb_otg_ahb_clk";
+ break;
+ default:
+ printf("%s: base 0x%p not found\n", __func__, base);
+ return -EINVAL;
+ }
+
+ return clk_get_and_enable(ahbstr);
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/Makefile b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/Makefile
new file mode 100644
index 000000000..e5099975c
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2013 Broadcom Corporation.
+
+obj-y += reset.o
+obj-y += clk-core.o
+obj-y += clk-bcm281xx.o
+obj-y += clk-sdio.o
+obj-y += clk-bsc.o
+obj-$(CONFIG_BCM_SF2_ETH) += clk-eth.o
+obj-y += clk-usb-otg.o
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-bcm281xx.c b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-bcm281xx.c
new file mode 100644
index 000000000..8f6260e78
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-bcm281xx.c
@@ -0,0 +1,572 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+/*
+ *
+ * bcm281xx-specific clock tables
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <asm/arch/sysmap.h>
+#include <asm/kona-common/clk.h>
+#include "clk-core.h"
+
+#define CLOCK_1K 1000
+#define CLOCK_1M (CLOCK_1K * 1000)
+
+/* declare a reference clock */
+#define DECLARE_REF_CLK(clk_name, clk_parent, clk_rate, clk_div) \
+static struct refclk clk_name = { \
+ .clk = { \
+ .name = #clk_name, \
+ .parent = clk_parent, \
+ .rate = clk_rate, \
+ .div = clk_div, \
+ .ops = &ref_clk_ops, \
+ }, \
+}
+
+/*
+ * Reference clocks
+ */
+
+/* Declare a list of reference clocks */
+DECLARE_REF_CLK(ref_crystal, 0, 26 * CLOCK_1M, 1);
+DECLARE_REF_CLK(var_96m, 0, 96 * CLOCK_1M, 1);
+DECLARE_REF_CLK(ref_96m, 0, 96 * CLOCK_1M, 1);
+DECLARE_REF_CLK(ref_312m, 0, 312 * CLOCK_1M, 0);
+DECLARE_REF_CLK(ref_104m, &ref_312m.clk, 104 * CLOCK_1M, 3);
+DECLARE_REF_CLK(ref_52m, &ref_104m.clk, 52 * CLOCK_1M, 2);
+DECLARE_REF_CLK(ref_13m, &ref_52m.clk, 13 * CLOCK_1M, 4);
+DECLARE_REF_CLK(var_312m, 0, 312 * CLOCK_1M, 0);
+DECLARE_REF_CLK(var_104m, &var_312m.clk, 104 * CLOCK_1M, 3);
+DECLARE_REF_CLK(var_52m, &var_104m.clk, 52 * CLOCK_1M, 2);
+DECLARE_REF_CLK(var_13m, &var_52m.clk, 13 * CLOCK_1M, 4);
+
+struct refclk_lkup {
+ struct refclk *procclk;
+ const char *name;
+};
+
+/* Lookup table for string to clk tranlation */
+#define MKSTR(x) {&x, #x}
+static struct refclk_lkup refclk_str_tbl[] = {
+ MKSTR(ref_crystal), MKSTR(var_96m), MKSTR(ref_96m),
+ MKSTR(ref_312m), MKSTR(ref_104m), MKSTR(ref_52m),
+ MKSTR(ref_13m), MKSTR(var_312m), MKSTR(var_104m),
+ MKSTR(var_52m), MKSTR(var_13m),
+};
+
+int refclk_entries = sizeof(refclk_str_tbl)/sizeof(refclk_str_tbl[0]);
+
+/* convert ref clock string to clock structure pointer */
+struct refclk *refclk_str_to_clk(const char *name)
+{
+ int i;
+ struct refclk_lkup *tblp = refclk_str_tbl;
+ for (i = 0; i < refclk_entries; i++, tblp++) {
+ if (!(strcmp(name, tblp->name)))
+ return tblp->procclk;
+ }
+ return NULL;
+}
+
+/* frequency tables indexed by freq_id */
+unsigned long master_axi_freq_tbl[8] = {
+ 26 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 104 * CLOCK_1M,
+ 156 * CLOCK_1M,
+ 156 * CLOCK_1M,
+ 208 * CLOCK_1M,
+ 312 * CLOCK_1M,
+ 312 * CLOCK_1M
+};
+
+unsigned long master_ahb_freq_tbl[8] = {
+ 26 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 78 * CLOCK_1M,
+ 104 * CLOCK_1M,
+ 104 * CLOCK_1M,
+ 156 * CLOCK_1M
+};
+
+unsigned long slave_axi_freq_tbl[8] = {
+ 26 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 78 * CLOCK_1M,
+ 104 * CLOCK_1M,
+ 156 * CLOCK_1M,
+ 156 * CLOCK_1M
+};
+
+unsigned long slave_apb_freq_tbl[8] = {
+ 26 * CLOCK_1M,
+ 26 * CLOCK_1M,
+ 39 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 52 * CLOCK_1M,
+ 78 * CLOCK_1M
+};
+
+unsigned long esub_freq_tbl[8] = {
+ 78 * CLOCK_1M,
+ 156 * CLOCK_1M,
+ 156 * CLOCK_1M,
+ 156 * CLOCK_1M,
+ 208 * CLOCK_1M,
+ 208 * CLOCK_1M,
+ 208 * CLOCK_1M
+};
+
+static struct bus_clk_data bsc1_apb_data = {
+ .gate = HW_SW_GATE_AUTO(0x0458, 16, 0, 1),
+};
+
+static struct bus_clk_data bsc2_apb_data = {
+ .gate = HW_SW_GATE_AUTO(0x045c, 16, 0, 1),
+};
+
+static struct bus_clk_data bsc3_apb_data = {
+ .gate = HW_SW_GATE_AUTO(0x0484, 16, 0, 1),
+};
+
+/* * Master CCU clocks */
+static struct peri_clk_data sdio1_data = {
+ .gate = HW_SW_GATE(0x0358, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_52m",
+ "ref_52m",
+ "var_96m",
+ "ref_96m"),
+ .sel = SELECTOR(0x0a28, 0, 3),
+ .div = DIVIDER(0x0a28, 4, 14),
+ .trig = TRIGGER(0x0afc, 9),
+};
+
+static struct peri_clk_data sdio2_data = {
+ .gate = HW_SW_GATE(0x035c, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_52m",
+ "ref_52m",
+ "var_96m",
+ "ref_96m"),
+ .sel = SELECTOR(0x0a2c, 0, 3),
+ .div = DIVIDER(0x0a2c, 4, 14),
+ .trig = TRIGGER(0x0afc, 10),
+};
+
+static struct peri_clk_data sdio3_data = {
+ .gate = HW_SW_GATE(0x0364, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_52m",
+ "ref_52m",
+ "var_96m",
+ "ref_96m"),
+ .sel = SELECTOR(0x0a34, 0, 3),
+ .div = DIVIDER(0x0a34, 4, 14),
+ .trig = TRIGGER(0x0afc, 12),
+};
+
+static struct peri_clk_data sdio4_data = {
+ .gate = HW_SW_GATE(0x0360, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_52m",
+ "ref_52m",
+ "var_96m",
+ "ref_96m"),
+ .sel = SELECTOR(0x0a30, 0, 3),
+ .div = DIVIDER(0x0a30, 4, 14),
+ .trig = TRIGGER(0x0afc, 11),
+};
+
+static struct peri_clk_data sdio1_sleep_data = {
+ .clocks = CLOCKS("ref_32k"),
+ .gate = SW_ONLY_GATE(0x0358, 20, 4),
+};
+
+static struct peri_clk_data sdio2_sleep_data = {
+ .clocks = CLOCKS("ref_32k"),
+ .gate = SW_ONLY_GATE(0x035c, 20, 4),
+};
+
+static struct peri_clk_data sdio3_sleep_data = {
+ .clocks = CLOCKS("ref_32k"),
+ .gate = SW_ONLY_GATE(0x0364, 20, 4),
+};
+
+static struct peri_clk_data sdio4_sleep_data = {
+ .clocks = CLOCKS("ref_32k"),
+ .gate = SW_ONLY_GATE(0x0360, 20, 4),
+};
+
+static struct bus_clk_data usb_otg_ahb_data = {
+ .gate = HW_SW_GATE_AUTO(0x0348, 16, 0, 1),
+};
+
+static struct bus_clk_data sdio1_ahb_data = {
+ .gate = HW_SW_GATE_AUTO(0x0358, 16, 0, 1),
+};
+
+static struct bus_clk_data sdio2_ahb_data = {
+ .gate = HW_SW_GATE_AUTO(0x035c, 16, 0, 1),
+};
+
+static struct bus_clk_data sdio3_ahb_data = {
+ .gate = HW_SW_GATE_AUTO(0x0364, 16, 0, 1),
+};
+
+static struct bus_clk_data sdio4_ahb_data = {
+ .gate = HW_SW_GATE_AUTO(0x0360, 16, 0, 1),
+};
+
+/* * Slave CCU clocks */
+static struct peri_clk_data bsc1_data = {
+ .gate = HW_SW_GATE(0x0458, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_104m",
+ "ref_104m",
+ "var_13m",
+ "ref_13m"),
+ .sel = SELECTOR(0x0a64, 0, 3),
+ .trig = TRIGGER(0x0afc, 23),
+};
+
+static struct peri_clk_data bsc2_data = {
+ .gate = HW_SW_GATE(0x045c, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_104m",
+ "ref_104m",
+ "var_13m",
+ "ref_13m"),
+ .sel = SELECTOR(0x0a68, 0, 3),
+ .trig = TRIGGER(0x0afc, 24),
+};
+
+static struct peri_clk_data bsc3_data = {
+ .gate = HW_SW_GATE(0x0484, 18, 2, 3),
+ .clocks = CLOCKS("ref_crystal",
+ "var_104m",
+ "ref_104m",
+ "var_13m",
+ "ref_13m"),
+ .sel = SELECTOR(0x0a84, 0, 3),
+ .trig = TRIGGER(0x0b00, 2),
+};
+
+/*
+ * CCU clocks
+ */
+
+static struct ccu_clock kpm_ccu_clk = {
+ .clk = {
+ .name = "kpm_ccu_clk",
+ .ops = &ccu_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .num_policy_masks = 1,
+ .policy_freq_offset = 0x00000008,
+ .freq_bit_shift = 8,
+ .policy_ctl_offset = 0x0000000c,
+ .policy0_mask_offset = 0x00000010,
+ .policy1_mask_offset = 0x00000014,
+ .policy2_mask_offset = 0x00000018,
+ .policy3_mask_offset = 0x0000001c,
+ .lvm_en_offset = 0x00000034,
+ .freq_id = 2,
+ .freq_tbl = master_axi_freq_tbl,
+};
+
+static struct ccu_clock kps_ccu_clk = {
+ .clk = {
+ .name = "kps_ccu_clk",
+ .ops = &ccu_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .num_policy_masks = 2,
+ .policy_freq_offset = 0x00000008,
+ .freq_bit_shift = 8,
+ .policy_ctl_offset = 0x0000000c,
+ .policy0_mask_offset = 0x00000010,
+ .policy1_mask_offset = 0x00000014,
+ .policy2_mask_offset = 0x00000018,
+ .policy3_mask_offset = 0x0000001c,
+ .policy0_mask2_offset = 0x00000048,
+ .policy1_mask2_offset = 0x0000004c,
+ .policy2_mask2_offset = 0x00000050,
+ .policy3_mask2_offset = 0x00000054,
+ .lvm_en_offset = 0x00000034,
+ .freq_id = 2,
+ .freq_tbl = slave_axi_freq_tbl,
+};
+
+#ifdef CONFIG_BCM_SF2_ETH
+static struct ccu_clock esub_ccu_clk = {
+ .clk = {
+ .name = "esub_ccu_clk",
+ .ops = &ccu_clk_ops,
+ .ccu_clk_mgr_base = ESUB_CLK_BASE_ADDR,
+ },
+ .num_policy_masks = 1,
+ .policy_freq_offset = 0x00000008,
+ .freq_bit_shift = 8,
+ .policy_ctl_offset = 0x0000000c,
+ .policy0_mask_offset = 0x00000010,
+ .policy1_mask_offset = 0x00000014,
+ .policy2_mask_offset = 0x00000018,
+ .policy3_mask_offset = 0x0000001c,
+ .lvm_en_offset = 0x00000034,
+ .freq_id = 2,
+ .freq_tbl = esub_freq_tbl,
+};
+#endif
+
+/*
+ * Bus clocks
+ */
+
+/* KPM bus clocks */
+static struct bus_clock usb_otg_ahb_clk = {
+ .clk = {
+ .name = "usb_otg_ahb_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .freq_tbl = master_ahb_freq_tbl,
+ .data = &usb_otg_ahb_data,
+};
+
+static struct bus_clock sdio1_ahb_clk = {
+ .clk = {
+ .name = "sdio1_ahb_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .freq_tbl = master_ahb_freq_tbl,
+ .data = &sdio1_ahb_data,
+};
+
+static struct bus_clock sdio2_ahb_clk = {
+ .clk = {
+ .name = "sdio2_ahb_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .freq_tbl = master_ahb_freq_tbl,
+ .data = &sdio2_ahb_data,
+};
+
+static struct bus_clock sdio3_ahb_clk = {
+ .clk = {
+ .name = "sdio3_ahb_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .freq_tbl = master_ahb_freq_tbl,
+ .data = &sdio3_ahb_data,
+};
+
+static struct bus_clock sdio4_ahb_clk = {
+ .clk = {
+ .name = "sdio4_ahb_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .freq_tbl = master_ahb_freq_tbl,
+ .data = &sdio4_ahb_data,
+};
+
+static struct bus_clock bsc1_apb_clk = {
+ .clk = {
+ .name = "bsc1_apb_clk",
+ .parent = &kps_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .freq_tbl = slave_apb_freq_tbl,
+ .data = &bsc1_apb_data,
+};
+
+static struct bus_clock bsc2_apb_clk = {
+ .clk = {
+ .name = "bsc2_apb_clk",
+ .parent = &kps_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .freq_tbl = slave_apb_freq_tbl,
+ .data = &bsc2_apb_data,
+};
+
+static struct bus_clock bsc3_apb_clk = {
+ .clk = {
+ .name = "bsc3_apb_clk",
+ .parent = &kps_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .freq_tbl = slave_apb_freq_tbl,
+ .data = &bsc3_apb_data,
+};
+
+/* KPM peripheral */
+static struct peri_clock sdio1_clk = {
+ .clk = {
+ .name = "sdio1_clk",
+ .parent = &ref_52m.clk,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio1_data,
+};
+
+static struct peri_clock sdio2_clk = {
+ .clk = {
+ .name = "sdio2_clk",
+ .parent = &ref_52m.clk,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio2_data,
+};
+
+static struct peri_clock sdio3_clk = {
+ .clk = {
+ .name = "sdio3_clk",
+ .parent = &ref_52m.clk,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio3_data,
+};
+
+static struct peri_clock sdio4_clk = {
+ .clk = {
+ .name = "sdio4_clk",
+ .parent = &ref_52m.clk,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio4_data,
+};
+
+static struct peri_clock sdio1_sleep_clk = {
+ .clk = {
+ .name = "sdio1_sleep_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio1_sleep_data,
+};
+
+static struct peri_clock sdio2_sleep_clk = {
+ .clk = {
+ .name = "sdio2_sleep_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio2_sleep_data,
+};
+
+static struct peri_clock sdio3_sleep_clk = {
+ .clk = {
+ .name = "sdio3_sleep_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio3_sleep_data,
+};
+
+static struct peri_clock sdio4_sleep_clk = {
+ .clk = {
+ .name = "sdio4_sleep_clk",
+ .parent = &kpm_ccu_clk.clk,
+ .ops = &bus_clk_ops,
+ .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR,
+ },
+ .data = &sdio4_sleep_data,
+};
+
+/* KPS peripheral clock */
+static struct peri_clock bsc1_clk = {
+ .clk = {
+ .name = "bsc1_clk",
+ .parent = &ref_13m.clk,
+ .rate = 13 * CLOCK_1M,
+ .div = 1,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .data = &bsc1_data,
+};
+
+static struct peri_clock bsc2_clk = {
+ .clk = {
+ .name = "bsc2_clk",
+ .parent = &ref_13m.clk,
+ .rate = 13 * CLOCK_1M,
+ .div = 1,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .data = &bsc2_data,
+};
+
+static struct peri_clock bsc3_clk = {
+ .clk = {
+ .name = "bsc3_clk",
+ .parent = &ref_13m.clk,
+ .rate = 13 * CLOCK_1M,
+ .div = 1,
+ .ops = &peri_clk_ops,
+ .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR,
+ },
+ .data = &bsc3_data,
+};
+
+/* public table for registering clocks */
+struct clk_lookup arch_clk_tbl[] = {
+ /* Peripheral clocks */
+ CLK_LK(sdio1),
+ CLK_LK(sdio2),
+ CLK_LK(sdio3),
+ CLK_LK(sdio4),
+ CLK_LK(sdio1_sleep),
+ CLK_LK(sdio2_sleep),
+ CLK_LK(sdio3_sleep),
+ CLK_LK(sdio4_sleep),
+ CLK_LK(bsc1),
+ CLK_LK(bsc2),
+ CLK_LK(bsc3),
+ /* Bus clocks */
+ CLK_LK(usb_otg_ahb),
+ CLK_LK(sdio1_ahb),
+ CLK_LK(sdio2_ahb),
+ CLK_LK(sdio3_ahb),
+ CLK_LK(sdio4_ahb),
+ CLK_LK(bsc1_apb),
+ CLK_LK(bsc2_apb),
+ CLK_LK(bsc3_apb),
+#ifdef CONFIG_BCM_SF2_ETH
+ CLK_LK(esub_ccu),
+#endif
+};
+
+/* public array size */
+unsigned int arch_clk_tbl_array_size = ARRAY_SIZE(arch_clk_tbl);
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-bsc.c b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-bsc.c
new file mode 100644
index 000000000..1b3f36aeb
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-bsc.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <asm/arch/sysmap.h>
+#include <asm/kona-common/clk.h>
+#include "clk-core.h"
+
+/* Enable appropriate clocks for a BSC/I2C port */
+int clk_bsc_enable(void *base)
+{
+ int ret;
+ char *bscstr, *apbstr;
+
+ switch ((u32) base) {
+ case PMU_BSC_BASE_ADDR:
+ /* PMU clock is always enabled */
+ return 0;
+ case BSC1_BASE_ADDR:
+ bscstr = "bsc1_clk";
+ apbstr = "bsc1_apb_clk";
+ break;
+ case BSC2_BASE_ADDR:
+ bscstr = "bsc2_clk";
+ apbstr = "bsc2_apb_clk";
+ break;
+ case BSC3_BASE_ADDR:
+ bscstr = "bsc3_clk";
+ apbstr = "bsc3_apb_clk";
+ break;
+ default:
+ printf("%s: base 0x%p not found\n", __func__, base);
+ return -EINVAL;
+ }
+
+ /* Note that the bus clock must be enabled first */
+
+ ret = clk_get_and_enable(apbstr);
+ if (ret)
+ return ret;
+
+ ret = clk_get_and_enable(bscstr);
+ if (ret)
+ return ret;
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-core.c b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-core.c
new file mode 100644
index 000000000..26b673a54
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-core.c
@@ -0,0 +1,514 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+/*
+ *
+ * bcm281xx architecture clock framework
+ *
+ */
+
+#include <common.h>
+#include <log.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <bitfield.h>
+#include <asm/arch/sysmap.h>
+#include <asm/kona-common/clk.h>
+#include "clk-core.h"
+
+#define CLK_WR_ACCESS_PASSWORD 0x00a5a501
+#define WR_ACCESS_OFFSET 0 /* common to all clock blocks */
+#define POLICY_CTL_GO 1 /* Load and refresh policy masks */
+#define POLICY_CTL_GO_ATL 4 /* Active Load */
+
+/* Helper function */
+int clk_get_and_enable(char *clkstr)
+{
+ int ret = 0;
+ struct clk *c;
+
+ debug("%s: %s\n", __func__, clkstr);
+
+ c = clk_get(clkstr);
+ if (c) {
+ ret = clk_enable(c);
+ if (ret)
+ return ret;
+ } else {
+ printf("%s: Couldn't find %s\n", __func__, clkstr);
+ return -EINVAL;
+ }
+ return ret;
+}
+
+/*
+ * Poll a register in a CCU's address space, returning when the
+ * specified bit in that register's value is set (or clear). Delay
+ * a microsecond after each read of the register. Returns true if
+ * successful, or false if we gave up trying.
+ *
+ * Caller must ensure the CCU lock is held.
+ */
+#define CLK_GATE_DELAY_USEC 2000
+static inline int wait_bit(void *base, u32 offset, u32 bit, bool want)
+{
+ unsigned int tries;
+ u32 bit_mask = 1 << bit;
+
+ for (tries = 0; tries < CLK_GATE_DELAY_USEC; tries++) {
+ u32 val;
+ bool bit_val;
+
+ val = readl(base + offset);
+ bit_val = (val & bit_mask) ? 1 : 0;
+ if (bit_val == want)
+ return 0; /* success */
+ udelay(1);
+ }
+
+ debug("%s: timeout on addr 0x%p, waiting for bit %d to go to %d\n",
+ __func__, base + offset, bit, want);
+
+ return -ETIMEDOUT;
+}
+
+/* Enable a peripheral clock */
+static int peri_clk_enable(struct clk *c, int enable)
+{
+ int ret = 0;
+ u32 reg;
+ struct peri_clock *peri_clk = to_peri_clk(c);
+ struct peri_clk_data *cd = peri_clk->data;
+ struct bcm_clk_gate *gate = &cd->gate;
+ void *base = (void *)c->ccu_clk_mgr_base;
+
+
+ debug("%s: %s\n", __func__, c->name);
+
+ clk_get_rate(c); /* Make sure rate and sel are filled in */
+
+ /* enable access */
+ writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);
+
+ if (enable) {
+ debug("%s %s set rate %lu div %lu sel %d parent %lu\n",
+ __func__, c->name, c->rate, c->div, c->sel,
+ c->parent->rate);
+
+ /*
+ * clkgate - only software controllable gates are
+ * supported by u-boot which includes all clocks
+ * that matter. This avoids bringing in a lot of extra
+ * complexity as done in the kernel framework.
+ */
+ if (gate_exists(gate)) {
+ reg = readl(base + cd->gate.offset);
+ reg |= (1 << cd->gate.en_bit);
+ writel(reg, base + cd->gate.offset);
+ }
+
+ /* div and pll select */
+ if (divider_exists(&cd->div)) {
+ reg = readl(base + cd->div.offset);
+ bitfield_replace(reg, cd->div.shift, cd->div.width,
+ c->div - 1);
+ writel(reg, base + cd->div.offset);
+ }
+
+ /* frequency selector */
+ if (selector_exists(&cd->sel)) {
+ reg = readl(base + cd->sel.offset);
+ bitfield_replace(reg, cd->sel.shift, cd->sel.width,
+ c->sel);
+ writel(reg, base + cd->sel.offset);
+ }
+
+ /* trigger */
+ if (trigger_exists(&cd->trig)) {
+ writel((1 << cd->trig.bit), base + cd->trig.offset);
+
+ /* wait for trigger status bit to go to 0 */
+ ret = wait_bit(base, cd->trig.offset, cd->trig.bit, 0);
+ if (ret)
+ return ret;
+ }
+
+ /* wait for running (status_bit = 1) */
+ ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, 1);
+ if (ret)
+ return ret;
+ } else {
+ debug("%s disable clock %s\n", __func__, c->name);
+
+ /* clkgate */
+ reg = readl(base + cd->gate.offset);
+ reg &= ~(1 << cd->gate.en_bit);
+ writel(reg, base + cd->gate.offset);
+
+ /* wait for stop (status_bit = 0) */
+ ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, 0);
+ }
+
+ /* disable access */
+ writel(0, base + WR_ACCESS_OFFSET);
+
+ return ret;
+}
+
+/* Set the rate of a peripheral clock */
+static int peri_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret = 0;
+ int i;
+ unsigned long diff;
+ unsigned long new_rate = 0, div = 1;
+ struct peri_clock *peri_clk = to_peri_clk(c);
+ struct peri_clk_data *cd = peri_clk->data;
+ const char **clock;
+
+ debug("%s: %s\n", __func__, c->name);
+ diff = rate;
+
+ i = 0;
+ for (clock = cd->clocks; *clock; clock++, i++) {
+ struct refclk *ref = refclk_str_to_clk(*clock);
+ if (!ref) {
+ printf("%s: Lookup of %s failed\n", __func__, *clock);
+ return -EINVAL;
+ }
+
+ /* round to the new rate */
+ div = ref->clk.rate / rate;
+ if (div == 0)
+ div = 1;
+
+ new_rate = ref->clk.rate / div;
+
+ /* get the min diff */
+ if (abs(new_rate - rate) < diff) {
+ diff = abs(new_rate - rate);
+ c->sel = i;
+ c->parent = &ref->clk;
+ c->rate = new_rate;
+ c->div = div;
+ }
+ }
+
+ debug("%s %s set rate %lu div %lu sel %d parent %lu\n", __func__,
+ c->name, c->rate, c->div, c->sel, c->parent->rate);
+ return ret;
+}
+
+/* Get the rate of a peripheral clock */
+static unsigned long peri_clk_get_rate(struct clk *c)
+{
+ struct peri_clock *peri_clk = to_peri_clk(c);
+ struct peri_clk_data *cd = peri_clk->data;
+ void *base = (void *)c->ccu_clk_mgr_base;
+ int div = 1;
+ const char **clock;
+ struct refclk *ref;
+ u32 reg;
+
+ debug("%s: %s\n", __func__, c->name);
+ if (selector_exists(&cd->sel)) {
+ reg = readl(base + cd->sel.offset);
+ c->sel = bitfield_extract(reg, cd->sel.shift, cd->sel.width);
+ } else {
+ /*
+ * For peri clocks that don't have a selector, the single
+ * reference clock will always exist at index 0.
+ */
+ c->sel = 0;
+ }
+
+ if (divider_exists(&cd->div)) {
+ reg = readl(base + cd->div.offset);
+ div = bitfield_extract(reg, cd->div.shift, cd->div.width);
+ div += 1;
+ }
+
+ clock = cd->clocks;
+ ref = refclk_str_to_clk(clock[c->sel]);
+ if (!ref) {
+ printf("%s: Can't lookup %s\n", __func__, clock[c->sel]);
+ return 0;
+ }
+
+ c->parent = &ref->clk;
+ c->div = div;
+ c->rate = c->parent->rate / c->div;
+ debug("%s parent rate %lu div %d sel %d rate %lu\n", __func__,
+ c->parent->rate, div, c->sel, c->rate);
+
+ return c->rate;
+}
+
+/* Peripheral clock operations */
+struct clk_ops peri_clk_ops = {
+ .enable = peri_clk_enable,
+ .set_rate = peri_clk_set_rate,
+ .get_rate = peri_clk_get_rate,
+};
+
+/* Enable a CCU clock */
+static int ccu_clk_enable(struct clk *c, int enable)
+{
+ struct ccu_clock *ccu_clk = to_ccu_clk(c);
+ void *base = (void *)c->ccu_clk_mgr_base;
+ int ret = 0;
+ u32 reg;
+
+ debug("%s: %s\n", __func__, c->name);
+ if (!enable)
+ return -EINVAL; /* CCU clock cannot shutdown */
+
+ /* enable access */
+ writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);
+
+ /* config enable for policy engine */
+ writel(1, base + ccu_clk->lvm_en_offset);
+
+ /* wait for bit to go to 0 */
+ ret = wait_bit(base, ccu_clk->lvm_en_offset, 0, 0);
+ if (ret)
+ return ret;
+
+ /* freq ID */
+ if (!ccu_clk->freq_bit_shift)
+ ccu_clk->freq_bit_shift = 8;
+
+ /* Set frequency id for each of the 4 policies */
+ reg = ccu_clk->freq_id |
+ (ccu_clk->freq_id << (ccu_clk->freq_bit_shift)) |
+ (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 2)) |
+ (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 3));
+ writel(reg, base + ccu_clk->policy_freq_offset);
+
+ /* enable all clock mask */
+ writel(0x7fffffff, base + ccu_clk->policy0_mask_offset);
+ writel(0x7fffffff, base + ccu_clk->policy1_mask_offset);
+ writel(0x7fffffff, base + ccu_clk->policy2_mask_offset);
+ writel(0x7fffffff, base + ccu_clk->policy3_mask_offset);
+
+ if (ccu_clk->num_policy_masks == 2) {
+ writel(0x7fffffff, base + ccu_clk->policy0_mask2_offset);
+ writel(0x7fffffff, base + ccu_clk->policy1_mask2_offset);
+ writel(0x7fffffff, base + ccu_clk->policy2_mask2_offset);
+ writel(0x7fffffff, base + ccu_clk->policy3_mask2_offset);
+ }
+
+ /* start policy engine */
+ reg = readl(base + ccu_clk->policy_ctl_offset);
+ reg |= (POLICY_CTL_GO + POLICY_CTL_GO_ATL);
+ writel(reg, base + ccu_clk->policy_ctl_offset);
+
+ /* wait till started */
+ ret = wait_bit(base, ccu_clk->policy_ctl_offset, 0, 0);
+ if (ret)
+ return ret;
+
+ /* disable access */
+ writel(0, base + WR_ACCESS_OFFSET);
+
+ return ret;
+}
+
+/* Get the CCU clock rate */
+static unsigned long ccu_clk_get_rate(struct clk *c)
+{
+ struct ccu_clock *ccu_clk = to_ccu_clk(c);
+ debug("%s: %s\n", __func__, c->name);
+ c->rate = ccu_clk->freq_tbl[ccu_clk->freq_id];
+ return c->rate;
+}
+
+/* CCU clock operations */
+struct clk_ops ccu_clk_ops = {
+ .enable = ccu_clk_enable,
+ .get_rate = ccu_clk_get_rate,
+};
+
+/* Enable a bus clock */
+static int bus_clk_enable(struct clk *c, int enable)
+{
+ struct bus_clock *bus_clk = to_bus_clk(c);
+ struct bus_clk_data *cd = bus_clk->data;
+ void *base = (void *)c->ccu_clk_mgr_base;
+ int ret = 0;
+ u32 reg;
+
+ debug("%s: %s\n", __func__, c->name);
+ /* enable access */
+ writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);
+
+ /* enable gating */
+ reg = readl(base + cd->gate.offset);
+ if (!!(reg & (1 << cd->gate.status_bit)) == !!enable)
+ debug("%s already %s\n", c->name,
+ enable ? "enabled" : "disabled");
+ else {
+ int want = (enable) ? 1 : 0;
+ reg |= (1 << cd->gate.hw_sw_sel_bit);
+
+ if (enable)
+ reg |= (1 << cd->gate.en_bit);
+ else
+ reg &= ~(1 << cd->gate.en_bit);
+
+ writel(reg, base + cd->gate.offset);
+ ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit,
+ want);
+ if (ret)
+ return ret;
+ }
+
+ /* disable access */
+ writel(0, base + WR_ACCESS_OFFSET);
+
+ return ret;
+}
+
+/* Get the rate of a bus clock */
+static unsigned long bus_clk_get_rate(struct clk *c)
+{
+ struct bus_clock *bus_clk = to_bus_clk(c);
+ struct ccu_clock *ccu_clk;
+
+ debug("%s: %s\n", __func__, c->name);
+ ccu_clk = to_ccu_clk(c->parent);
+
+ c->rate = bus_clk->freq_tbl[ccu_clk->freq_id];
+ c->div = ccu_clk->freq_tbl[ccu_clk->freq_id] / c->rate;
+ return c->rate;
+}
+
+/* Bus clock operations */
+struct clk_ops bus_clk_ops = {
+ .enable = bus_clk_enable,
+ .get_rate = bus_clk_get_rate,
+};
+
+/* Enable a reference clock */
+static int ref_clk_enable(struct clk *c, int enable)
+{
+ debug("%s: %s\n", __func__, c->name);
+ return 0;
+}
+
+/* Reference clock operations */
+struct clk_ops ref_clk_ops = {
+ .enable = ref_clk_enable,
+};
+
+/*
+ * clk.h implementation follows
+ */
+
+/* Initialize the clock framework */
+int clk_init(void)
+{
+ debug("%s:\n", __func__);
+ return 0;
+}
+
+/* Get a clock handle, give a name string */
+struct clk *clk_get(const char *con_id)
+{
+ int i;
+ struct clk_lookup *clk_tblp;
+
+ debug("%s: %s\n", __func__, con_id);
+
+ clk_tblp = arch_clk_tbl;
+ for (i = 0; i < arch_clk_tbl_array_size; i++, clk_tblp++) {
+ if (clk_tblp->con_id) {
+ if (!con_id || strcmp(clk_tblp->con_id, con_id))
+ continue;
+ return clk_tblp->clk;
+ }
+ }
+ return NULL;
+}
+
+/* Enable a clock */
+int clk_enable(struct clk *c)
+{
+ int ret = 0;
+
+ debug("%s: %s\n", __func__, c->name);
+ if (!c->ops || !c->ops->enable)
+ return -1;
+
+ /* enable parent clock first */
+ if (c->parent)
+ ret = clk_enable(c->parent);
+
+ if (ret)
+ return ret;
+
+ if (!c->use_cnt) {
+ c->use_cnt++;
+ ret = c->ops->enable(c, 1);
+ }
+
+ return ret;
+}
+
+/* Disable a clock */
+void clk_disable(struct clk *c)
+{
+ debug("%s: %s\n", __func__, c->name);
+ if (!c->ops || !c->ops->enable)
+ return;
+
+ if (c->use_cnt) {
+ c->use_cnt--;
+ c->ops->enable(c, 0);
+ }
+
+ /* disable parent */
+ if (c->parent)
+ clk_disable(c->parent);
+}
+
+/* Get the clock rate */
+unsigned long clk_get_rate(struct clk *c)
+{
+ unsigned long rate;
+
+ if (!c || !c->ops || !c->ops->get_rate)
+ return 0;
+ debug("%s: %s\n", __func__, c->name);
+
+ rate = c->ops->get_rate(c);
+ debug("%s: rate = %ld\n", __func__, rate);
+ return rate;
+}
+
+/* Set the clock rate */
+int clk_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret;
+
+ if (!c || !c->ops || !c->ops->set_rate)
+ return -EINVAL;
+ debug("%s: %s rate=%ld\n", __func__, c->name, rate);
+
+ if (c->use_cnt)
+ return -EINVAL;
+
+ ret = c->ops->set_rate(c, rate);
+
+ return ret;
+}
+
+/* Not required for this arch */
+/*
+long clk_round_rate(struct clk *clk, unsigned long rate);
+int clk_set_parent(struct clk *clk, struct clk *parent);
+struct clk *clk_get_parent(struct clk *clk);
+*/
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-core.h b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-core.h
new file mode 100644
index 000000000..f0fbff081
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-core.h
@@ -0,0 +1,491 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+#include <linux/stddef.h>
+#include <linux/stringify.h>
+
+#ifdef CONFIG_CLK_DEBUG
+#undef writel
+#undef readl
+static inline void writel(u32 val, void *addr)
+{
+ printf("Write [0x%p] = 0x%08x\n", addr, val);
+ *(u32 *)addr = val;
+}
+
+static inline u32 readl(void *addr)
+{
+ u32 val = *(u32 *)addr;
+ printf("Read [0x%p] = 0x%08x\n", addr, val);
+ return val;
+}
+#endif
+
+struct clk;
+
+struct clk_lookup {
+ const char *dev_id;
+ const char *con_id;
+ struct clk *clk;
+};
+
+extern struct clk_lookup arch_clk_tbl[];
+extern unsigned int arch_clk_tbl_array_size;
+
+/**
+ * struct clk_ops - standard clock operations
+ * @enable: enable/disable clock, see clk_enable() and clk_disable()
+ * @set_rate: set the clock rate, see clk_set_rate().
+ * @get_rate: get the clock rate, see clk_get_rate().
+ * @round_rate: round a given clock rate, see clk_round_rate().
+ * @set_parent: set the clock's parent, see clk_set_parent().
+ *
+ * Group the common clock implementations together so that we
+ * don't have to keep setting the same fiels again. We leave
+ * enable in struct clk.
+ *
+ */
+struct clk_ops {
+ int (*enable) (struct clk *c, int enable);
+ int (*set_rate) (struct clk *c, unsigned long rate);
+ unsigned long (*get_rate) (struct clk *c);
+ unsigned long (*round_rate) (struct clk *c, unsigned long rate);
+ int (*set_parent) (struct clk *c, struct clk *parent);
+};
+
+struct clk {
+ struct clk *parent;
+ const char *name;
+ int use_cnt;
+ unsigned long rate; /* in HZ */
+
+ /* programmable divider. 0 means fixed ratio to parent clock */
+ unsigned long div;
+
+ struct clk_src *src;
+ struct clk_ops *ops;
+
+ unsigned long ccu_clk_mgr_base;
+ int sel;
+};
+
+struct refclk *refclk_str_to_clk(const char *name);
+
+/* The common clock framework uses u8 to represent a parent index */
+#define PARENT_COUNT_MAX ((u32)U8_MAX)
+
+#define BAD_CLK_INDEX U8_MAX /* Can't ever be valid */
+#define BAD_CLK_NAME ((const char *)-1)
+
+#define BAD_SCALED_DIV_VALUE U64_MAX
+
+/*
+ * Utility macros for object flag management. If possible, flags
+ * should be defined such that 0 is the desired default value.
+ */
+#define FLAG(type, flag) BCM_CLK_ ## type ## _FLAGS_ ## flag
+#define FLAG_SET(obj, type, flag) ((obj)->flags |= FLAG(type, flag))
+#define FLAG_CLEAR(obj, type, flag) ((obj)->flags &= ~(FLAG(type, flag)))
+#define FLAG_FLIP(obj, type, flag) ((obj)->flags ^= FLAG(type, flag))
+#define FLAG_TEST(obj, type, flag) (!!((obj)->flags & FLAG(type, flag)))
+
+/* Clock field state tests */
+
+#define gate_exists(gate) FLAG_TEST(gate, GATE, EXISTS)
+#define gate_is_enabled(gate) FLAG_TEST(gate, GATE, ENABLED)
+#define gate_is_hw_controllable(gate) FLAG_TEST(gate, GATE, HW)
+#define gate_is_sw_controllable(gate) FLAG_TEST(gate, GATE, SW)
+#define gate_is_sw_managed(gate) FLAG_TEST(gate, GATE, SW_MANAGED)
+#define gate_is_no_disable(gate) FLAG_TEST(gate, GATE, NO_DISABLE)
+
+#define gate_flip_enabled(gate) FLAG_FLIP(gate, GATE, ENABLED)
+
+#define divider_exists(div) FLAG_TEST(div, DIV, EXISTS)
+#define divider_is_fixed(div) FLAG_TEST(div, DIV, FIXED)
+#define divider_has_fraction(div) (!divider_is_fixed(div) && \
+ (div)->frac_width > 0)
+
+#define selector_exists(sel) ((sel)->width != 0)
+#define trigger_exists(trig) FLAG_TEST(trig, TRIG, EXISTS)
+
+/* Clock type, used to tell common block what it's part of */
+enum bcm_clk_type {
+ bcm_clk_none, /* undefined clock type */
+ bcm_clk_bus,
+ bcm_clk_core,
+ bcm_clk_peri
+};
+
+/*
+ * Gating control and status is managed by a 32-bit gate register.
+ *
+ * There are several types of gating available:
+ * - (no gate)
+ * A clock with no gate is assumed to be always enabled.
+ * - hardware-only gating (auto-gating)
+ * Enabling or disabling clocks with this type of gate is
+ * managed automatically by the hardware. Such clocks can be
+ * considered by the software to be enabled. The current status
+ * of auto-gated clocks can be read from the gate status bit.
+ * - software-only gating
+ * Auto-gating is not available for this type of clock.
+ * Instead, software manages whether it's enabled by setting or
+ * clearing the enable bit. The current gate status of a gate
+ * under software control can be read from the gate status bit.
+ * To ensure a change to the gating status is complete, the
+ * status bit can be polled to verify that the gate has entered
+ * the desired state.
+ * - selectable hardware or software gating
+ * Gating for this type of clock can be configured to be either
+ * under software or hardware control. Which type is in use is
+ * determined by the hw_sw_sel bit of the gate register.
+ */
+struct bcm_clk_gate {
+ u32 offset; /* gate register offset */
+ u32 status_bit; /* 0: gate is disabled; 0: gatge is enabled */
+ u32 en_bit; /* 0: disable; 1: enable */
+ u32 hw_sw_sel_bit; /* 0: hardware gating; 1: software gating */
+ u32 flags; /* BCM_CLK_GATE_FLAGS_* below */
+};
+
+/*
+ * Gate flags:
+ * HW means this gate can be auto-gated
+ * SW means the state of this gate can be software controlled
+ * NO_DISABLE means this gate is (only) enabled if under software control
+ * SW_MANAGED means the status of this gate is under software control
+ * ENABLED means this software-managed gate is *supposed* to be enabled
+ */
+#define BCM_CLK_GATE_FLAGS_EXISTS ((u32)1 << 0) /* Gate is valid */
+#define BCM_CLK_GATE_FLAGS_HW ((u32)1 << 1) /* Can auto-gate */
+#define BCM_CLK_GATE_FLAGS_SW ((u32)1 << 2) /* Software control */
+#define BCM_CLK_GATE_FLAGS_NO_DISABLE ((u32)1 << 3) /* HW or enabled */
+#define BCM_CLK_GATE_FLAGS_SW_MANAGED ((u32)1 << 4) /* SW now in control */
+#define BCM_CLK_GATE_FLAGS_ENABLED ((u32)1 << 5) /* If SW_MANAGED */
+
+/*
+ * Gate initialization macros.
+ *
+ * Any gate initially under software control will be enabled.
+ */
+
+/* A hardware/software gate initially under software control */
+#define HW_SW_GATE(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \
+ { \
+ .offset = (_offset), \
+ .status_bit = (_status_bit), \
+ .en_bit = (_en_bit), \
+ .hw_sw_sel_bit = (_hw_sw_sel_bit), \
+ .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \
+ FLAG(GATE, SW_MANAGED)|FLAG(GATE, ENABLED)| \
+ FLAG(GATE, EXISTS), \
+ }
+
+/* A hardware/software gate initially under hardware control */
+#define HW_SW_GATE_AUTO(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \
+ { \
+ .offset = (_offset), \
+ .status_bit = (_status_bit), \
+ .en_bit = (_en_bit), \
+ .hw_sw_sel_bit = (_hw_sw_sel_bit), \
+ .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \
+ FLAG(GATE, EXISTS), \
+ }
+
+/* A hardware-or-enabled gate (enabled if not under hardware control) */
+#define HW_ENABLE_GATE(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \
+ { \
+ .offset = (_offset), \
+ .status_bit = (_status_bit), \
+ .en_bit = (_en_bit), \
+ .hw_sw_sel_bit = (_hw_sw_sel_bit), \
+ .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \
+ FLAG(GATE, NO_DISABLE)|FLAG(GATE, EXISTS), \
+ }
+
+/* A software-only gate */
+#define SW_ONLY_GATE(_offset, _status_bit, _en_bit) \
+ { \
+ .offset = (_offset), \
+ .status_bit = (_status_bit), \
+ .en_bit = (_en_bit), \
+ .flags = FLAG(GATE, SW)|FLAG(GATE, SW_MANAGED)| \
+ FLAG(GATE, ENABLED)|FLAG(GATE, EXISTS), \
+ }
+
+/* A hardware-only gate */
+#define HW_ONLY_GATE(_offset, _status_bit) \
+ { \
+ .offset = (_offset), \
+ .status_bit = (_status_bit), \
+ .flags = FLAG(GATE, HW)|FLAG(GATE, EXISTS), \
+ }
+
+/*
+ * Each clock can have zero, one, or two dividers which change the
+ * output rate of the clock. Each divider can be either fixed or
+ * variable. If there are two dividers, they are the "pre-divider"
+ * and the "regular" or "downstream" divider. If there is only one,
+ * there is no pre-divider.
+ *
+ * A fixed divider is any non-zero (positive) value, and it
+ * indicates how the input rate is affected by the divider.
+ *
+ * The value of a variable divider is maintained in a sub-field of a
+ * 32-bit divider register. The position of the field in the
+ * register is defined by its offset and width. The value recorded
+ * in this field is always 1 less than the value it represents.
+ *
+ * In addition, a variable divider can indicate that some subset
+ * of its bits represent a "fractional" part of the divider. Such
+ * bits comprise the low-order portion of the divider field, and can
+ * be viewed as representing the portion of the divider that lies to
+ * the right of the decimal point. Most variable dividers have zero
+ * fractional bits. Variable dividers with non-zero fraction width
+ * still record a value 1 less than the value they represent; the
+ * added 1 does *not* affect the low-order bit in this case, it
+ * affects the bits above the fractional part only. (Often in this
+ * code a divider field value is distinguished from the value it
+ * represents by referring to the latter as a "divisor".)
+ *
+ * In order to avoid dealing with fractions, divider arithmetic is
+ * performed using "scaled" values. A scaled value is one that's
+ * been left-shifted by the fractional width of a divider. Dividing
+ * a scaled value by a scaled divisor produces the desired quotient
+ * without loss of precision and without any other special handling
+ * for fractions.
+ *
+ * The recorded value of a variable divider can be modified. To
+ * modify either divider (or both), a clock must be enabled (i.e.,
+ * using its gate). In addition, a trigger register (described
+ * below) must be used to commit the change, and polled to verify
+ * the change is complete.
+ */
+struct bcm_clk_div {
+ union {
+ struct { /* variable divider */
+ u32 offset; /* divider register offset */
+ u32 shift; /* field shift */
+ u32 width; /* field width */
+ u32 frac_width; /* field fraction width */
+
+ u64 scaled_div; /* scaled divider value */
+ };
+ u32 fixed; /* non-zero fixed divider value */
+ };
+ u32 flags; /* BCM_CLK_DIV_FLAGS_* below */
+};
+
+/*
+ * Divider flags:
+ * EXISTS means this divider exists
+ * FIXED means it is a fixed-rate divider
+ */
+#define BCM_CLK_DIV_FLAGS_EXISTS ((u32)1 << 0) /* Divider is valid */
+#define BCM_CLK_DIV_FLAGS_FIXED ((u32)1 << 1) /* Fixed-value */
+
+/* Divider initialization macros */
+
+/* A fixed (non-zero) divider */
+#define FIXED_DIVIDER(_value) \
+ { \
+ .fixed = (_value), \
+ .flags = FLAG(DIV, EXISTS)|FLAG(DIV, FIXED), \
+ }
+
+/* A divider with an integral divisor */
+#define DIVIDER(_offset, _shift, _width) \
+ { \
+ .offset = (_offset), \
+ .shift = (_shift), \
+ .width = (_width), \
+ .scaled_div = BAD_SCALED_DIV_VALUE, \
+ .flags = FLAG(DIV, EXISTS), \
+ }
+
+/* A divider whose divisor has an integer and fractional part */
+#define FRAC_DIVIDER(_offset, _shift, _width, _frac_width) \
+ { \
+ .offset = (_offset), \
+ .shift = (_shift), \
+ .width = (_width), \
+ .frac_width = (_frac_width), \
+ .scaled_div = BAD_SCALED_DIV_VALUE, \
+ .flags = FLAG(DIV, EXISTS), \
+ }
+
+/*
+ * Clocks may have multiple "parent" clocks. If there is more than
+ * one, a selector must be specified to define which of the parent
+ * clocks is currently in use. The selected clock is indicated in a
+ * sub-field of a 32-bit selector register. The range of
+ * representable selector values typically exceeds the number of
+ * available parent clocks. Occasionally the reset value of a
+ * selector field is explicitly set to a (specific) value that does
+ * not correspond to a defined input clock.
+ *
+ * We register all known parent clocks with the common clock code
+ * using a packed array (i.e., no empty slots) of (parent) clock
+ * names, and refer to them later using indexes into that array.
+ * We maintain an array of selector values indexed by common clock
+ * index values in order to map between these common clock indexes
+ * and the selector values used by the hardware.
+ *
+ * Like dividers, a selector can be modified, but to do so a clock
+ * must be enabled, and a trigger must be used to commit the change.
+ */
+struct bcm_clk_sel {
+ u32 offset; /* selector register offset */
+ u32 shift; /* field shift */
+ u32 width; /* field width */
+
+ u32 parent_count; /* number of entries in parent_sel[] */
+ u32 *parent_sel; /* array of parent selector values */
+ u8 clk_index; /* current selected index in parent_sel[] */
+};
+
+/* Selector initialization macro */
+#define SELECTOR(_offset, _shift, _width) \
+ { \
+ .offset = (_offset), \
+ .shift = (_shift), \
+ .width = (_width), \
+ .clk_index = BAD_CLK_INDEX, \
+ }
+
+/*
+ * Making changes to a variable divider or a selector for a clock
+ * requires the use of a trigger. A trigger is defined by a single
+ * bit within a register. To signal a change, a 1 is written into
+ * that bit. To determine when the change has been completed, that
+ * trigger bit is polled; the read value will be 1 while the change
+ * is in progress, and 0 when it is complete.
+ *
+ * Occasionally a clock will have more than one trigger. In this
+ * case, the "pre-trigger" will be used when changing a clock's
+ * selector and/or its pre-divider.
+ */
+struct bcm_clk_trig {
+ u32 offset; /* trigger register offset */
+ u32 bit; /* trigger bit */
+ u32 flags; /* BCM_CLK_TRIG_FLAGS_* below */
+};
+
+/*
+ * Trigger flags:
+ * EXISTS means this trigger exists
+ */
+#define BCM_CLK_TRIG_FLAGS_EXISTS ((u32)1 << 0) /* Trigger is valid */
+
+/* Trigger initialization macro */
+#define TRIGGER(_offset, _bit) \
+ { \
+ .offset = (_offset), \
+ .bit = (_bit), \
+ .flags = FLAG(TRIG, EXISTS), \
+ }
+
+struct bus_clk_data {
+ struct bcm_clk_gate gate;
+};
+
+struct core_clk_data {
+ struct bcm_clk_gate gate;
+};
+
+struct peri_clk_data {
+ struct bcm_clk_gate gate;
+ struct bcm_clk_trig pre_trig;
+ struct bcm_clk_div pre_div;
+ struct bcm_clk_trig trig;
+ struct bcm_clk_div div;
+ struct bcm_clk_sel sel;
+ const char *clocks[]; /* must be last; use CLOCKS() to declare */
+};
+#define CLOCKS(...) { __VA_ARGS__, NULL, }
+#define NO_CLOCKS { NULL, } /* Must use of no parent clocks */
+
+struct refclk {
+ struct clk clk;
+};
+
+struct peri_clock {
+ struct clk clk;
+ struct peri_clk_data *data;
+};
+
+struct ccu_clock {
+ struct clk clk;
+
+ int num_policy_masks;
+ unsigned long policy_freq_offset;
+ int freq_bit_shift; /* 8 for most CCUs */
+ unsigned long policy_ctl_offset;
+ unsigned long policy0_mask_offset;
+ unsigned long policy1_mask_offset;
+ unsigned long policy2_mask_offset;
+ unsigned long policy3_mask_offset;
+ unsigned long policy0_mask2_offset;
+ unsigned long policy1_mask2_offset;
+ unsigned long policy2_mask2_offset;
+ unsigned long policy3_mask2_offset;
+ unsigned long lvm_en_offset;
+
+ int freq_id;
+ unsigned long *freq_tbl;
+};
+
+struct bus_clock {
+ struct clk clk;
+ struct bus_clk_data *data;
+ unsigned long *freq_tbl;
+};
+
+struct ref_clock {
+ struct clk clk;
+};
+
+static inline int is_same_clock(struct clk *a, struct clk *b)
+{
+ return (a == b);
+}
+
+#define to_clk(p) (&((p)->clk))
+#define name_to_clk(name) (&((name##_clk).clk))
+/* declare a struct clk_lookup */
+#define CLK_LK(name) \
+{.con_id = __stringify(name##_clk), .clk = name_to_clk(name),}
+
+static inline struct refclk *to_refclk(struct clk *clock)
+{
+ return container_of(clock, struct refclk, clk);
+}
+
+static inline struct peri_clock *to_peri_clk(struct clk *clock)
+{
+ return container_of(clock, struct peri_clock, clk);
+}
+
+static inline struct ccu_clock *to_ccu_clk(struct clk *clock)
+{
+ return container_of(clock, struct ccu_clock, clk);
+}
+
+static inline struct bus_clock *to_bus_clk(struct clk *clock)
+{
+ return container_of(clock, struct bus_clock, clk);
+}
+
+static inline struct ref_clock *to_ref_clk(struct clk *clock)
+{
+ return container_of(clock, struct ref_clock, clk);
+}
+
+extern struct clk_ops peri_clk_ops;
+extern struct clk_ops ccu_clk_ops;
+extern struct clk_ops bus_clk_ops;
+extern struct clk_ops ref_clk_ops;
+
+extern int clk_get_and_enable(char *clkstr);
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-eth.c b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-eth.c
new file mode 100644
index 000000000..209ceca9a
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-eth.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <asm/arch/sysmap.h>
+#include <asm/kona-common/clk.h>
+#include "clk-core.h"
+
+#define WR_ACCESS_ADDR ESUB_CLK_BASE_ADDR
+#define WR_ACCESS_PASSWORD 0xA5A500
+
+#define PLLE_POST_RESETB_ADDR (ESUB_CLK_BASE_ADDR + 0x00000C00)
+
+#define PLLE_RESETB_ADDR (ESUB_CLK_BASE_ADDR + 0x00000C58)
+#define PLLE_RESETB_I_PLL_RESETB_PLLE_MASK 0x00010000
+#define PLLE_POST_RESETB_I_POST_RESETB_PLLE_MASK 0x00000001
+
+#define PLL_LOCK_ADDR (ESUB_CLK_BASE_ADDR + 0x00000C38)
+#define PLL_LOCK_PLL_LOCK_PLLE_MASK 0x00000001
+
+#define ESW_SYS_DIV_ADDR (ESUB_CLK_BASE_ADDR + 0x00000A04)
+#define ESW_SYS_DIV_PLL_SELECT_MASK 0x00000300
+#define ESW_SYS_DIV_DIV_MASK 0x0000001C
+#define ESW_SYS_DIV_PLL_VAR_208M_CLK_SELECT 0x00000100
+#define ESW_SYS_DIV_DIV_SELECT 0x4
+#define ESW_SYS_DIV_TRIGGER_MASK 0x00000001
+
+#define ESUB_AXI_DIV_DEBUG_ADDR (ESUB_CLK_BASE_ADDR + 0x00000E04)
+#define ESUB_AXI_DIV_DEBUG_PLL_SELECT_MASK 0x0000001C
+#define ESUB_AXI_DIV_DEBUG_PLL_SELECT_OVERRIDE_MASK 0x00000040
+#define ESUB_AXI_DIV_DEBUG_PLL_VAR_208M_CLK_SELECT 0x0
+#define ESUB_AXI_DIV_DEBUG_TRIGGER_MASK 0x00000001
+
+#define PLL_MAX_RETRY 100
+
+/* Enable appropriate clocks for Ethernet */
+int clk_eth_enable(void)
+{
+ int rc = -1;
+ int retry_count = 0;
+ rc = clk_get_and_enable("esub_ccu_clk");
+
+ /* Enable Access to CCU registers */
+ writel((1 | WR_ACCESS_PASSWORD), WR_ACCESS_ADDR);
+
+ writel(readl(PLLE_POST_RESETB_ADDR) &
+ ~PLLE_POST_RESETB_I_POST_RESETB_PLLE_MASK,
+ PLLE_POST_RESETB_ADDR);
+
+ /* Take PLL out of reset and put into normal mode */
+ writel(readl(PLLE_RESETB_ADDR) | PLLE_RESETB_I_PLL_RESETB_PLLE_MASK,
+ PLLE_RESETB_ADDR);
+
+ /* Wait for PLL lock */
+ rc = -1;
+ while (retry_count < PLL_MAX_RETRY) {
+ udelay(100);
+ if (readl(PLL_LOCK_ADDR) & PLL_LOCK_PLL_LOCK_PLLE_MASK) {
+ rc = 0;
+ break;
+ }
+ retry_count++;
+ }
+
+ if (rc == -1) {
+ printf("%s: ETH-PLL lock timeout, Ethernet is not enabled!\n",
+ __func__);
+ return -1;
+ }
+
+ writel(readl(PLLE_POST_RESETB_ADDR) |
+ PLLE_POST_RESETB_I_POST_RESETB_PLLE_MASK,
+ PLLE_POST_RESETB_ADDR);
+
+ /* Switch esw_sys_clk to use 104MHz(208MHz/2) clock */
+ writel((readl(ESW_SYS_DIV_ADDR) &
+ ~(ESW_SYS_DIV_PLL_SELECT_MASK | ESW_SYS_DIV_DIV_MASK)) |
+ ESW_SYS_DIV_PLL_VAR_208M_CLK_SELECT | ESW_SYS_DIV_DIV_SELECT,
+ ESW_SYS_DIV_ADDR);
+
+ writel(readl(ESW_SYS_DIV_ADDR) | ESW_SYS_DIV_TRIGGER_MASK,
+ ESW_SYS_DIV_ADDR);
+
+ /* Wait for trigger complete */
+ rc = -1;
+ retry_count = 0;
+ while (retry_count < PLL_MAX_RETRY) {
+ udelay(100);
+ if (!(readl(ESW_SYS_DIV_ADDR) & ESW_SYS_DIV_TRIGGER_MASK)) {
+ rc = 0;
+ break;
+ }
+ retry_count++;
+ }
+
+ if (rc == -1) {
+ printf("%s: SYS CLK Trigger timeout, Ethernet is not enabled!\n",
+ __func__);
+ return -1;
+ }
+
+ /* switch Esub AXI clock to 208MHz */
+ writel((readl(ESUB_AXI_DIV_DEBUG_ADDR) &
+ ~(ESUB_AXI_DIV_DEBUG_PLL_SELECT_MASK |
+ ESUB_AXI_DIV_DEBUG_PLL_SELECT_OVERRIDE_MASK |
+ ESUB_AXI_DIV_DEBUG_TRIGGER_MASK)) |
+ ESUB_AXI_DIV_DEBUG_PLL_VAR_208M_CLK_SELECT |
+ ESUB_AXI_DIV_DEBUG_PLL_SELECT_OVERRIDE_MASK,
+ ESUB_AXI_DIV_DEBUG_ADDR);
+
+ writel(readl(ESUB_AXI_DIV_DEBUG_ADDR) |
+ ESUB_AXI_DIV_DEBUG_TRIGGER_MASK,
+ ESUB_AXI_DIV_DEBUG_ADDR);
+
+ /* Wait for trigger complete */
+ rc = -1;
+ retry_count = 0;
+ while (retry_count < PLL_MAX_RETRY) {
+ udelay(100);
+ if (!(readl(ESUB_AXI_DIV_DEBUG_ADDR) &
+ ESUB_AXI_DIV_DEBUG_TRIGGER_MASK)) {
+ rc = 0;
+ break;
+ }
+ retry_count++;
+ }
+
+ if (rc == -1) {
+ printf("%s: AXI CLK Trigger timeout, Ethernet is not enabled!\n",
+ __func__);
+ return -1;
+ }
+
+ /* Disable Access to CCU registers */
+ writel(WR_ACCESS_PASSWORD, WR_ACCESS_ADDR);
+
+ return rc;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-sdio.c b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-sdio.c
new file mode 100644
index 000000000..f2ba354c2
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-sdio.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <asm/arch/sysmap.h>
+#include <asm/kona-common/clk.h>
+#include "clk-core.h"
+
+/* Enable appropriate clocks for an SDIO port */
+int clk_sdio_enable(void *base, u32 rate, u32 *actual_ratep)
+{
+ int ret;
+ struct clk *c;
+
+ char *clkstr;
+ char *slpstr;
+ char *ahbstr;
+
+ switch ((u32) base) {
+ case CONFIG_SYS_SDIO_BASE0:
+ clkstr = CONFIG_SYS_SDIO0 "_clk";
+ ahbstr = CONFIG_SYS_SDIO0 "_ahb_clk";
+ slpstr = CONFIG_SYS_SDIO0 "_sleep_clk";
+ break;
+ case CONFIG_SYS_SDIO_BASE1:
+ clkstr = CONFIG_SYS_SDIO1 "_clk";
+ ahbstr = CONFIG_SYS_SDIO1 "_ahb_clk";
+ slpstr = CONFIG_SYS_SDIO1 "_sleep_clk";
+ break;
+ case CONFIG_SYS_SDIO_BASE2:
+ clkstr = CONFIG_SYS_SDIO2 "_clk";
+ ahbstr = CONFIG_SYS_SDIO2 "_ahb_clk";
+ slpstr = CONFIG_SYS_SDIO2 "_sleep_clk";
+ break;
+ case CONFIG_SYS_SDIO_BASE3:
+ clkstr = CONFIG_SYS_SDIO3 "_clk";
+ ahbstr = CONFIG_SYS_SDIO3 "_ahb_clk";
+ slpstr = CONFIG_SYS_SDIO3 "_sleep_clk";
+ break;
+ default:
+ printf("%s: base 0x%p not found\n", __func__, base);
+ return -EINVAL;
+ }
+
+ ret = clk_get_and_enable(ahbstr);
+ if (ret)
+ return ret;
+
+ ret = clk_get_and_enable(slpstr);
+ if (ret)
+ return ret;
+
+ c = clk_get(clkstr);
+ if (c) {
+ ret = clk_set_rate(c, rate);
+ if (ret)
+ return ret;
+
+ ret = clk_enable(c);
+ if (ret)
+ return ret;
+ } else {
+ printf("%s: Couldn't find %s\n", __func__, clkstr);
+ return -EINVAL;
+ }
+ *actual_ratep = rate;
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-usb-otg.c b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-usb-otg.c
new file mode 100644
index 000000000..f604aec62
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/clk-usb-otg.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <linux/errno.h>
+#include <asm/arch/sysmap.h>
+#include "clk-core.h"
+
+/* Enable appropriate clocks for the USB OTG port */
+int clk_usb_otg_enable(void *base)
+{
+ char *ahbstr;
+
+ switch ((u32) base) {
+ case HSOTG_BASE_ADDR:
+ ahbstr = "usb_otg_ahb_clk";
+ break;
+ default:
+ printf("%s: base 0x%p not found\n", __func__, base);
+ return -EINVAL;
+ }
+
+ return clk_get_and_enable(ahbstr);
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/reset.c b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/reset.c
new file mode 100644
index 000000000..1491e5c88
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcm281xx/reset.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/io.h>
+#include <asm/arch/sysmap.h>
+
+#define EN_MASK 0x08000000 /* Enable timer */
+#define SRSTEN_MASK 0x04000000 /* Enable soft reset */
+#define CLKS_SHIFT 20 /* Clock period shift */
+#define LD_SHIFT 0 /* Reload value shift */
+
+void reset_cpu(void)
+{
+ /*
+ * Set WD enable, RST enable,
+ * 3.9 msec clock period (8), reload value (8*3.9ms)
+ */
+ u32 reg = EN_MASK + SRSTEN_MASK + (8 << CLKS_SHIFT) + (8 << LD_SHIFT);
+ writel(reg, SECWD2_BASE_ADDR);
+
+ while (1)
+ ; /* loop forever till reset */
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcmcygnus/Makefile b/roms/u-boot/arch/arm/cpu/armv7/bcmcygnus/Makefile
new file mode 100644
index 000000000..3496bcd2e
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcmcygnus/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2014 Broadcom Corporation.
+
+obj-y += reset.o
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcmcygnus/reset.c b/roms/u-boot/arch/arm/cpu/armv7/bcmcygnus/reset.c
new file mode 100644
index 000000000..63992fd87
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcmcygnus/reset.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/io.h>
+
+#define CRMU_MAIL_BOX1 0x03024028
+#define CRMU_SOFT_RESET_CMD 0xFFFFFFFF
+
+void reset_cpu(void)
+{
+ /* Send soft reset command via Mailbox. */
+ writel(CRMU_SOFT_RESET_CMD, CRMU_MAIL_BOX1);
+
+ while (1)
+ ; /* loop forever till reset */
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcmnsp/Makefile b/roms/u-boot/arch/arm/cpu/armv7/bcmnsp/Makefile
new file mode 100644
index 000000000..3496bcd2e
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcmnsp/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2014 Broadcom Corporation.
+
+obj-y += reset.o
diff --git a/roms/u-boot/arch/arm/cpu/armv7/bcmnsp/reset.c b/roms/u-boot/arch/arm/cpu/armv7/bcmnsp/reset.c
new file mode 100644
index 000000000..a3137752e
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/bcmnsp/reset.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/io.h>
+
+#define CRU_RESET_OFFSET 0x1803F184
+
+void reset_cpu(void)
+{
+ /* Reset the cpu by setting software reset request bit */
+ writel(0x1, CRU_RESET_OFFSET);
+
+ while (1)
+ ; /* loop forever till reset */
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/cache_v7.c b/roms/u-boot/arch/arm/cpu/armv7/cache_v7.c
new file mode 100644
index 000000000..19ff43235
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/cache_v7.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ * Aneesh V <aneesh@ti.com>
+ */
+#include <cpu_func.h>
+#include <asm/cache.h>
+#include <linux/types.h>
+#include <common.h>
+#include <asm/armv7.h>
+#include <asm/utils.h>
+
+#define ARMV7_DCACHE_INVAL_RANGE 1
+#define ARMV7_DCACHE_CLEAN_INVAL_RANGE 2
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+
+/* Asm functions from cache_v7_asm.S */
+void v7_flush_dcache_all(void);
+void v7_invalidate_dcache_all(void);
+
+static u32 get_ccsidr(void)
+{
+ u32 ccsidr;
+
+ /* Read current CP15 Cache Size ID Register */
+ asm volatile ("mrc p15, 1, %0, c0, c0, 0" : "=r" (ccsidr));
+ return ccsidr;
+}
+
+static void v7_dcache_clean_inval_range(u32 start, u32 stop, u32 line_len)
+{
+ u32 mva;
+
+ /* Align start to cache line boundary */
+ start &= ~(line_len - 1);
+ for (mva = start; mva < stop; mva = mva + line_len) {
+ /* DCCIMVAC - Clean & Invalidate data cache by MVA to PoC */
+ asm volatile ("mcr p15, 0, %0, c7, c14, 1" : : "r" (mva));
+ }
+}
+
+static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len)
+{
+ u32 mva;
+
+ if (!check_cache_range(start, stop))
+ return;
+
+ for (mva = start; mva < stop; mva = mva + line_len) {
+ /* DCIMVAC - Invalidate data cache by MVA to PoC */
+ asm volatile ("mcr p15, 0, %0, c7, c6, 1" : : "r" (mva));
+ }
+}
+
+static void v7_dcache_maint_range(u32 start, u32 stop, u32 range_op)
+{
+ u32 line_len, ccsidr;
+
+ ccsidr = get_ccsidr();
+ line_len = ((ccsidr & CCSIDR_LINE_SIZE_MASK) >>
+ CCSIDR_LINE_SIZE_OFFSET) + 2;
+ /* Converting from words to bytes */
+ line_len += 2;
+ /* converting from log2(linelen) to linelen */
+ line_len = 1 << line_len;
+
+ switch (range_op) {
+ case ARMV7_DCACHE_CLEAN_INVAL_RANGE:
+ v7_dcache_clean_inval_range(start, stop, line_len);
+ break;
+ case ARMV7_DCACHE_INVAL_RANGE:
+ v7_dcache_inval_range(start, stop, line_len);
+ break;
+ }
+
+ /* DSB to make sure the operation is complete */
+ dsb();
+}
+
+/* Invalidate TLB */
+static void v7_inval_tlb(void)
+{
+ /* Invalidate entire unified TLB */
+ asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0));
+ /* Invalidate entire data TLB */
+ asm volatile ("mcr p15, 0, %0, c8, c6, 0" : : "r" (0));
+ /* Invalidate entire instruction TLB */
+ asm volatile ("mcr p15, 0, %0, c8, c5, 0" : : "r" (0));
+ /* Full system DSB - make sure that the invalidation is complete */
+ dsb();
+ /* Full system ISB - make sure the instruction stream sees it */
+ isb();
+}
+
+void invalidate_dcache_all(void)
+{
+ v7_invalidate_dcache_all();
+
+ v7_outer_cache_inval_all();
+}
+
+/*
+ * Performs a clean & invalidation of the entire data cache
+ * at all levels
+ */
+void flush_dcache_all(void)
+{
+ v7_flush_dcache_all();
+
+ v7_outer_cache_flush_all();
+}
+
+/*
+ * Invalidates range in all levels of D-cache/unified cache used:
+ * Affects the range [start, stop - 1]
+ */
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+ check_cache_range(start, stop);
+
+ v7_dcache_maint_range(start, stop, ARMV7_DCACHE_INVAL_RANGE);
+
+ v7_outer_cache_inval_range(start, stop);
+}
+
+/*
+ * Flush range(clean & invalidate) from all levels of D-cache/unified
+ * cache used:
+ * Affects the range [start, stop - 1]
+ */
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+ check_cache_range(start, stop);
+
+ v7_dcache_maint_range(start, stop, ARMV7_DCACHE_CLEAN_INVAL_RANGE);
+
+ v7_outer_cache_flush_range(start, stop);
+}
+
+void arm_init_before_mmu(void)
+{
+ v7_outer_cache_enable();
+ invalidate_dcache_all();
+ v7_inval_tlb();
+}
+
+void mmu_page_table_flush(unsigned long start, unsigned long stop)
+{
+ flush_dcache_range(start, stop);
+ v7_inval_tlb();
+}
+#else /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
+void invalidate_dcache_all(void)
+{
+}
+
+void flush_dcache_all(void)
+{
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void arm_init_before_mmu(void)
+{
+}
+
+void mmu_page_table_flush(unsigned long start, unsigned long stop)
+{
+}
+
+#endif /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
+
+#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
+/* Invalidate entire I-cache and branch predictor array */
+void invalidate_icache_all(void)
+{
+ /*
+ * Invalidate all instruction caches to PoU.
+ * Also flushes branch target cache.
+ */
+ asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
+
+ /* Invalidate entire branch predictor array */
+ asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
+
+ /* Full system DSB - make sure that the invalidation is complete */
+ dsb();
+
+ /* ISB - make sure the instruction stream sees it */
+ isb();
+}
+#else
+void invalidate_icache_all(void)
+{
+}
+#endif
+
+/* Stub implementations for outer cache operations */
+__weak void v7_outer_cache_enable(void) {}
+__weak void v7_outer_cache_disable(void) {}
+__weak void v7_outer_cache_flush_all(void) {}
+__weak void v7_outer_cache_inval_all(void) {}
+__weak void v7_outer_cache_flush_range(u32 start, u32 end) {}
+__weak void v7_outer_cache_inval_range(u32 start, u32 end) {}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/cache_v7_asm.S b/roms/u-boot/arch/arm/cpu/armv7/cache_v7_asm.S
new file mode 100644
index 000000000..e38d72f87
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/cache_v7_asm.S
@@ -0,0 +1,152 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+#include <linux/sizes.h>
+#include <asm/system.h>
+
+#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)
+#define ARM(x...)
+#define THUMB(x...) x
+#else
+#define ARM(x...) x
+#define THUMB(x...)
+#endif
+
+/*
+ * v7_flush_dcache_all()
+ *
+ * Flush the whole D-cache.
+ *
+ * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ *
+ * Note: copied from arch/arm/mm/cache-v7.S of Linux 4.4
+ */
+ENTRY(__v7_flush_dcache_all)
+ dmb @ ensure ordering with previous memory accesses
+ mrc p15, 1, r0, c0, c0, 1 @ read clidr
+ mov r3, r0, lsr #23 @ move LoC into position
+ ands r3, r3, #7 << 1 @ extract LoC*2 from clidr
+ beq finished @ if loc is 0, then no need to clean
+start_flush_levels:
+ mov r10, #0 @ start clean at cache level 0
+flush_levels:
+ add r2, r10, r10, lsr #1 @ work out 3x current cache level
+ mov r1, r0, lsr r2 @ extract cache type bits from clidr
+ and r1, r1, #7 @ mask of the bits for current cache only
+ cmp r1, #2 @ see what cache we have at this level
+ blt skip @ skip if no cache, or just i-cache
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+ isb @ isb to sych the new cssr&csidr
+ mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
+ and r2, r1, #7 @ extract the length of the cache lines
+ add r2, r2, #4 @ add 4 (line length offset)
+ movw r4, #0x3ff
+ ands r4, r4, r1, lsr #3 @ find maximum number on the way size
+ clz r5, r4 @ find bit position of way size increment
+ movw r7, #0x7fff
+ ands r7, r7, r1, lsr #13 @ extract max number of the index size
+loop1:
+ mov r9, r7 @ create working copy of max index
+loop2:
+ ARM( orr r11, r10, r4, lsl r5 ) @ factor way and cache number into r11
+ THUMB( lsl r6, r4, r5 )
+ THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
+ ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11
+ THUMB( lsl r6, r9, r2 )
+ THUMB( orr r11, r11, r6 ) @ factor index number into r11
+ mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
+ subs r9, r9, #1 @ decrement the index
+ bge loop2
+ subs r4, r4, #1 @ decrement the way
+ bge loop1
+skip:
+ add r10, r10, #2 @ increment cache number
+ cmp r3, r10
+ bgt flush_levels
+finished:
+ mov r10, #0 @ swith back to cache level 0
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+ dsb st
+ isb
+ bx lr
+ENDPROC(__v7_flush_dcache_all)
+
+ENTRY(v7_flush_dcache_all)
+ ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
+ bl __v7_flush_dcache_all
+ ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
+ bx lr
+ENDPROC(v7_flush_dcache_all)
+
+/*
+ * v7_invalidate_dcache_all()
+ *
+ * Invalidate the whole D-cache.
+ *
+ * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ *
+ * Note: copied from __v7_flush_dcache_all above with
+ * mcr p15, 0, r11, c7, c14, 2
+ * Replaced with:
+ * mcr p15, 0, r11, c7, c6, 2
+ */
+ENTRY(__v7_invalidate_dcache_all)
+ dmb @ ensure ordering with previous memory accesses
+ mrc p15, 1, r0, c0, c0, 1 @ read clidr
+ mov r3, r0, lsr #23 @ move LoC into position
+ ands r3, r3, #7 << 1 @ extract LoC*2 from clidr
+ beq inval_finished @ if loc is 0, then no need to clean
+ mov r10, #0 @ start clean at cache level 0
+inval_levels:
+ add r2, r10, r10, lsr #1 @ work out 3x current cache level
+ mov r1, r0, lsr r2 @ extract cache type bits from clidr
+ and r1, r1, #7 @ mask of the bits for current cache only
+ cmp r1, #2 @ see what cache we have at this level
+ blt inval_skip @ skip if no cache, or just i-cache
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+ isb @ isb to sych the new cssr&csidr
+ mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
+ and r2, r1, #7 @ extract the length of the cache lines
+ add r2, r2, #4 @ add 4 (line length offset)
+ movw r4, #0x3ff
+ ands r4, r4, r1, lsr #3 @ find maximum number on the way size
+ clz r5, r4 @ find bit position of way size increment
+ movw r7, #0x7fff
+ ands r7, r7, r1, lsr #13 @ extract max number of the index size
+inval_loop1:
+ mov r9, r7 @ create working copy of max index
+inval_loop2:
+ ARM( orr r11, r10, r4, lsl r5 ) @ factor way and cache number into r11
+ THUMB( lsl r6, r4, r5 )
+ THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
+ ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11
+ THUMB( lsl r6, r9, r2 )
+ THUMB( orr r11, r11, r6 ) @ factor index number into r11
+ mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
+ subs r9, r9, #1 @ decrement the index
+ bge inval_loop2
+ subs r4, r4, #1 @ decrement the way
+ bge inval_loop1
+inval_skip:
+ add r10, r10, #2 @ increment cache number
+ cmp r3, r10
+ bgt inval_levels
+inval_finished:
+ mov r10, #0 @ swith back to cache level 0
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+ dsb st
+ isb
+ bx lr
+ENDPROC(__v7_invalidate_dcache_all)
+
+ENTRY(v7_invalidate_dcache_all)
+ ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
+ bl __v7_invalidate_dcache_all
+ ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
+ bx lr
+ENDPROC(v7_invalidate_dcache_all)
diff --git a/roms/u-boot/arch/arm/cpu/armv7/config.mk b/roms/u-boot/arch/arm/cpu/armv7/config.mk
new file mode 100644
index 000000000..68036d6fb
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/config.mk
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+
+# On supported platforms we set the bit which causes us to trap on unaligned
+# memory access. This is the opposite of what the compiler expects to be
+# the default so we must pass in -mno-unaligned-access so that it is aware
+# of our decision.
+PF_NO_UNALIGNED := $(call cc-option, -mno-unaligned-access,)
+PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED)
diff --git a/roms/u-boot/arch/arm/cpu/armv7/cp15.c b/roms/u-boot/arch/arm/cpu/armv7/cp15.c
new file mode 100644
index 000000000..0ac4e7ba8
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/cp15.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2015 Texas Insturments
+ */
+
+/*
+ * CP15 specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/system.h>
+#include <asm/cache.h>
+#include <asm/armv7.h>
+#include <linux/compiler.h>
+
+void __weak v7_arch_cp15_set_l2aux_ctrl(u32 l2actlr, u32 cpu_midr,
+ u32 cpu_rev_comb, u32 cpu_variant,
+ u32 cpu_rev)
+{
+ asm volatile ("mcr p15, 1, %0, c15, c0, 0\n\t" : : "r"(l2actlr));
+}
+
+void __weak v7_arch_cp15_set_acr(u32 acr, u32 cpu_midr, u32 cpu_rev_comb,
+ u32 cpu_variant, u32 cpu_rev)
+{
+ asm volatile ("mcr p15, 0, %0, c1, c0, 1\n\t" : : "r"(acr));
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/cpu.c b/roms/u-boot/arch/arm/cpu/armv7/cpu.c
new file mode 100644
index 000000000..68807d209
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/cpu.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2008 Texas Insturments
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ */
+
+/*
+ * CPU specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <irq_func.h>
+#include <asm/system.h>
+#include <asm/cache.h>
+#include <asm/armv7.h>
+#include <linux/compiler.h>
+
+void __weak cpu_cache_initialization(void){}
+
+int cleanup_before_linux_select(int flags)
+{
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * we turn off caches etc ...
+ */
+#ifndef CONFIG_SPL_BUILD
+ disable_interrupts();
+#endif
+
+ if (flags & CBL_DISABLE_CACHES) {
+ /*
+ * turn off D-cache
+ * dcache_disable() in turn flushes the d-cache and disables MMU
+ */
+ dcache_disable();
+ v7_outer_cache_disable();
+
+ /*
+ * After D-cache is flushed and before it is disabled there may
+ * be some new valid entries brought into the cache. We are
+ * sure that these lines are not dirty and will not affect our
+ * execution. (because unwinding the call-stack and setting a
+ * bit in CP15 SCTRL is all we did during this. We have not
+ * pushed anything on to the stack. Neither have we affected
+ * any static data) So just invalidate the entire d-cache again
+ * to avoid coherency problems for kernel
+ */
+ invalidate_dcache_all();
+
+ icache_disable();
+ invalidate_icache_all();
+ } else {
+ /*
+ * Turn off I-cache and invalidate it
+ */
+ icache_disable();
+ invalidate_icache_all();
+
+ flush_dcache_all();
+ invalidate_icache_all();
+ icache_enable();
+ }
+
+ /*
+ * Some CPU need more cache attention before starting the kernel.
+ */
+ cpu_cache_initialization();
+
+ return 0;
+}
+
+int cleanup_before_linux(void)
+{
+ return cleanup_before_linux_select(CBL_ALL);
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/exception_level.c b/roms/u-boot/arch/arm/cpu/armv7/exception_level.c
new file mode 100644
index 000000000..f6d25bb68
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/exception_level.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Switch to non-secure mode
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt
+ *
+ * This module contains the ARMv7 specific code required for leaving the
+ * secure mode before booting an operating system.
+ */
+
+#include <common.h>
+#include <bootm.h>
+#include <cpu_func.h>
+#include <log.h>
+#include <asm/armv7.h>
+#include <asm/secure.h>
+#include <asm/setjmp.h>
+
+/**
+ * entry_non_secure() - entry point when switching to non-secure mode
+ *
+ * When switching to non-secure mode switch_to_non_secure_mode() calls this
+ * function passing a jump buffer. We use this jump buffer to restore the
+ * original stack and register state.
+ *
+ * @non_secure_jmp: jump buffer for restoring stack and registers
+ */
+static void entry_non_secure(struct jmp_buf_data *non_secure_jmp)
+{
+ dcache_enable();
+ debug("Reached non-secure mode\n");
+
+ /* Restore stack and registers saved in switch_to_non_secure_mode() */
+ longjmp(non_secure_jmp, 1);
+}
+
+/**
+ * switch_to_non_secure_mode() - switch to non-secure mode
+ *
+ * Operating systems may expect to run in non-secure mode. Here we check if
+ * we are running in secure mode and switch to non-secure mode if necessary.
+ */
+void switch_to_non_secure_mode(void)
+{
+ static bool is_nonsec;
+ struct jmp_buf_data non_secure_jmp;
+
+ if (armv7_boot_nonsec() && !is_nonsec) {
+ if (setjmp(&non_secure_jmp))
+ return;
+ dcache_disable(); /* flush cache before switch to HYP */
+ armv7_init_nonsec();
+ is_nonsec = true;
+ secure_ram_addr(_do_nonsec_entry)(entry_non_secure,
+ (uintptr_t)&non_secure_jmp,
+ 0, 0);
+ }
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/iproc-common/Makefile b/roms/u-boot/arch/arm/cpu/armv7/iproc-common/Makefile
new file mode 100644
index 000000000..6f5c837a9
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/iproc-common/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2014 Broadcom Corporation.
+
+obj-y += armpll.o
+obj-y += hwinit-common.o
+obj-y += timer.o
diff --git a/roms/u-boot/arch/arm/cpu/armv7/iproc-common/armpll.c b/roms/u-boot/arch/arm/cpu/armv7/iproc-common/armpll.c
new file mode 100644
index 000000000..efa3d9e5a
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/iproc-common/armpll.c
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/iproc-common/armpll.h>
+#include <asm/iproc-common/sysmap.h>
+
+#define NELEMS(x) (sizeof(x) / sizeof(x[0]))
+
+struct armpll_parameters {
+ unsigned int mode;
+ unsigned int ndiv_int;
+ unsigned int ndiv_frac;
+ unsigned int pdiv;
+ unsigned int freqid;
+};
+
+struct armpll_parameters armpll_clk_tab[] = {
+ { 25, 64, 1, 1, 0},
+ { 100, 64, 1, 1, 2},
+ { 400, 64, 1, 1, 6},
+ { 448, 71, 713050, 1, 6},
+ { 500, 80, 1, 1, 6},
+ { 560, 89, 629145, 1, 6},
+ { 600, 96, 1, 1, 6},
+ { 800, 64, 1, 1, 7},
+ { 896, 71, 713050, 1, 7},
+ { 1000, 80, 1, 1, 7},
+ { 1100, 88, 1, 1, 7},
+ { 1120, 89, 629145, 1, 7},
+ { 1200, 96, 1, 1, 7},
+};
+
+uint32_t armpll_config(uint32_t clkmhz)
+{
+ uint32_t freqid;
+ uint32_t ndiv_frac;
+ uint32_t pll;
+ uint32_t status = 1;
+ uint32_t timeout_countdown;
+ int i;
+
+ for (i = 0; i < NELEMS(armpll_clk_tab); i++) {
+ if (armpll_clk_tab[i].mode == clkmhz) {
+ status = 0;
+ break;
+ }
+ }
+
+ if (status) {
+ printf("Error: Clock configuration not supported\n");
+ goto armpll_config_done;
+ }
+
+ /* Enable write access */
+ writel(IPROC_REG_WRITE_ACCESS, IHOST_PROC_CLK_WR_ACCESS);
+
+ if (clkmhz == 25)
+ freqid = 0;
+ else
+ freqid = 2;
+
+ /* Bypass ARM clock and run on sysclk */
+ writel(1 << IHOST_PROC_CLK_POLICY_FREQ__PRIV_ACCESS_MODE |
+ freqid << IHOST_PROC_CLK_POLICY_FREQ__POLICY3_FREQ_R |
+ freqid << IHOST_PROC_CLK_POLICY_FREQ__POLICY2_FREQ_R |
+ freqid << IHOST_PROC_CLK_POLICY_FREQ__POLICY1_FREQ_R |
+ freqid << IHOST_PROC_CLK_POLICY_FREQ__POLICY0_FREQ_R,
+ IHOST_PROC_CLK_POLICY_FREQ);
+
+ writel(1 << IHOST_PROC_CLK_POLICY_CTL__GO |
+ 1 << IHOST_PROC_CLK_POLICY_CTL__GO_AC,
+ IHOST_PROC_CLK_POLICY_CTL);
+
+ /* Poll CCU until operation complete */
+ timeout_countdown = 0x100000;
+ while (readl(IHOST_PROC_CLK_POLICY_CTL) &
+ (1 << IHOST_PROC_CLK_POLICY_CTL__GO)) {
+ timeout_countdown--;
+ if (timeout_countdown == 0) {
+ printf("CCU polling timedout\n");
+ status = 1;
+ goto armpll_config_done;
+ }
+ }
+
+ if (clkmhz == 25 || clkmhz == 100) {
+ status = 0;
+ goto armpll_config_done;
+ }
+
+ /* Now it is safe to program the PLL */
+ pll = readl(IHOST_PROC_CLK_PLLARMB);
+ pll &= ~((1 << IHOST_PROC_CLK_PLLARMB__PLLARM_NDIV_FRAC_WIDTH) - 1);
+ ndiv_frac =
+ ((1 << IHOST_PROC_CLK_PLLARMB__PLLARM_NDIV_FRAC_WIDTH) - 1) &
+ (armpll_clk_tab[i].ndiv_frac <<
+ IHOST_PROC_CLK_PLLARMB__PLLARM_NDIV_FRAC_R);
+ pll |= ndiv_frac;
+ writel(pll, IHOST_PROC_CLK_PLLARMB);
+
+ writel(1 << IHOST_PROC_CLK_PLLARMA__PLLARM_LOCK |
+ armpll_clk_tab[i].ndiv_int <<
+ IHOST_PROC_CLK_PLLARMA__PLLARM_NDIV_INT_R |
+ armpll_clk_tab[i].pdiv <<
+ IHOST_PROC_CLK_PLLARMA__PLLARM_PDIV_R |
+ 1 << IHOST_PROC_CLK_PLLARMA__PLLARM_SOFT_RESETB,
+ IHOST_PROC_CLK_PLLARMA);
+
+ /* Poll ARM PLL Lock until operation complete */
+ timeout_countdown = 0x100000;
+ while (readl(IHOST_PROC_CLK_PLLARMA) &
+ (1 << IHOST_PROC_CLK_PLLARMA__PLLARM_LOCK)) {
+ timeout_countdown--;
+ if (timeout_countdown == 0) {
+ printf("ARM PLL lock failed\n");
+ status = 1;
+ goto armpll_config_done;
+ }
+ }
+
+ pll = readl(IHOST_PROC_CLK_PLLARMA);
+ pll |= (1 << IHOST_PROC_CLK_PLLARMA__PLLARM_SOFT_POST_RESETB);
+ writel(pll, IHOST_PROC_CLK_PLLARMA);
+
+ /* Set the policy */
+ writel(1 << IHOST_PROC_CLK_POLICY_FREQ__PRIV_ACCESS_MODE |
+ armpll_clk_tab[i].freqid <<
+ IHOST_PROC_CLK_POLICY_FREQ__POLICY3_FREQ_R |
+ armpll_clk_tab[i].freqid <<
+ IHOST_PROC_CLK_POLICY_FREQ__POLICY2_FREQ_R |
+ armpll_clk_tab[i].freqid <<
+ IHOST_PROC_CLK_POLICY_FREQ__POLICY1_FREQ_R |
+ armpll_clk_tab[i+4].freqid <<
+ IHOST_PROC_CLK_POLICY_FREQ__POLICY0_FREQ_R,
+ IHOST_PROC_CLK_POLICY_FREQ);
+
+ writel(IPROC_CLKCT_HDELAY_SW_EN, IHOST_PROC_CLK_CORE0_CLKGATE);
+ writel(IPROC_CLKCT_HDELAY_SW_EN, IHOST_PROC_CLK_CORE1_CLKGATE);
+ writel(IPROC_CLKCT_HDELAY_SW_EN, IHOST_PROC_CLK_ARM_SWITCH_CLKGATE);
+ writel(IPROC_CLKCT_HDELAY_SW_EN, IHOST_PROC_CLK_ARM_PERIPH_CLKGATE);
+ writel(IPROC_CLKCT_HDELAY_SW_EN, IHOST_PROC_CLK_APB0_CLKGATE);
+
+ writel(1 << IHOST_PROC_CLK_POLICY_CTL__GO |
+ 1 << IHOST_PROC_CLK_POLICY_CTL__GO_AC,
+ IHOST_PROC_CLK_POLICY_CTL);
+
+ /* Poll CCU until operation complete */
+ timeout_countdown = 0x100000;
+ while (readl(IHOST_PROC_CLK_POLICY_CTL) &
+ (1 << IHOST_PROC_CLK_POLICY_CTL__GO)) {
+ timeout_countdown--;
+ if (timeout_countdown == 0) {
+ printf("CCU polling failed\n");
+ status = 1;
+ goto armpll_config_done;
+ }
+ }
+
+ status = 0;
+armpll_config_done:
+ /* Disable access to PLL registers */
+ writel(0, IHOST_PROC_CLK_WR_ACCESS);
+
+ return status;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/iproc-common/hwinit-common.c b/roms/u-boot/arch/arm/cpu/armv7/iproc-common/hwinit-common.c
new file mode 100644
index 000000000..896d2f956
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/iproc-common/hwinit-common.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/cache.h>
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+void enable_caches(void)
+{
+ /* Enable D-cache. I-cache is already enabled in start.S */
+ dcache_enable();
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv7/iproc-common/timer.c b/roms/u-boot/arch/arm/cpu/armv7/iproc-common/timer.c
new file mode 100644
index 000000000..a4255a44c
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/iproc-common/timer.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <div64.h>
+#include <init.h>
+#include <time.h>
+#include <asm/io.h>
+#include <asm/iproc-common/timer.h>
+#include <asm/iproc-common/sysmap.h>
+#include <linux/delay.h>
+
+static inline uint64_t timer_global_read(void)
+{
+ uint64_t cur_tick;
+ uint32_t count_h;
+ uint32_t count_l;
+
+ do {
+ count_h = readl(IPROC_PERIPH_GLB_TIM_REG_BASE +
+ TIMER_GLB_HI_OFFSET);
+ count_l = readl(IPROC_PERIPH_GLB_TIM_REG_BASE +
+ TIMER_GLB_LOW_OFFSET);
+ cur_tick = readl(IPROC_PERIPH_GLB_TIM_REG_BASE +
+ TIMER_GLB_HI_OFFSET);
+ } while (cur_tick != count_h);
+
+ return (cur_tick << 32) + count_l;
+}
+
+void timer_global_init(void)
+{
+ writel(0, IPROC_PERIPH_GLB_TIM_REG_BASE + TIMER_GLB_CTRL_OFFSET);
+ writel(0, IPROC_PERIPH_GLB_TIM_REG_BASE + TIMER_GLB_LOW_OFFSET);
+ writel(0, IPROC_PERIPH_GLB_TIM_REG_BASE + TIMER_GLB_HI_OFFSET);
+ writel(TIMER_GLB_TIM_CTRL_TIM_EN,
+ IPROC_PERIPH_GLB_TIM_REG_BASE + TIMER_GLB_CTRL_OFFSET);
+}
+
+int timer_init(void)
+{
+ timer_global_init();
+ return 0;
+}
+
+unsigned long get_timer(unsigned long base)
+{
+ uint64_t count;
+ uint64_t ret;
+ uint64_t tim_clk;
+ uint64_t periph_clk;
+
+ count = timer_global_read();
+
+ /* default arm clk is 1GHz, periph_clk=arm_clk/2, tick per msec */
+ periph_clk = 500000;
+ tim_clk = lldiv(periph_clk,
+ (((readl(IPROC_PERIPH_GLB_TIM_REG_BASE +
+ TIMER_GLB_CTRL_OFFSET) &
+ TIMER_GLB_TIM_CTRL_PRESC_MASK) >> 8) + 1));
+
+ ret = lldiv(count, (uint32_t)tim_clk);
+
+ /* returns msec */
+ return ret - base;
+}
+
+void __udelay(unsigned long usec)
+{
+ uint64_t cur_tick, end_tick;
+ uint64_t tim_clk;
+ uint64_t periph_clk;
+
+ /* default arm clk is 1GHz, periph_clk=arm_clk/2, tick per usec */
+ periph_clk = 500;
+
+ tim_clk = lldiv(periph_clk,
+ (((readl(IPROC_PERIPH_GLB_TIM_REG_BASE +
+ TIMER_GLB_CTRL_OFFSET) &
+ TIMER_GLB_TIM_CTRL_PRESC_MASK) >> 8) + 1));
+
+ cur_tick = timer_global_read();
+
+ end_tick = tim_clk;
+ end_tick *= usec;
+ end_tick += cur_tick;
+
+ do {
+ cur_tick = timer_global_read();
+
+ } while (cur_tick < end_tick);
+}
+
+void timer_systick_init(uint32_t tick_ms)
+{
+ /* Disable timer and clear interrupt status*/
+ writel(0, IPROC_PERIPH_PVT_TIM_REG_BASE + TIMER_PVT_CTRL_OFFSET);
+ writel(TIMER_PVT_TIM_INT_STATUS_SET,
+ IPROC_PERIPH_PVT_TIM_REG_BASE + TIMER_PVT_STATUS_OFFSET);
+ writel((PLL_AXI_CLK/1000) * tick_ms,
+ IPROC_PERIPH_PVT_TIM_REG_BASE + TIMER_PVT_LOAD_OFFSET);
+ writel(TIMER_PVT_TIM_CTRL_INT_EN |
+ TIMER_PVT_TIM_CTRL_AUTO_RELD |
+ TIMER_PVT_TIM_CTRL_TIM_EN,
+ IPROC_PERIPH_PVT_TIM_REG_BASE + TIMER_PVT_CTRL_OFFSET);
+}
+
+void timer_systick_isr(void *data)
+{
+ writel(TIMER_PVT_TIM_INT_STATUS_SET,
+ IPROC_PERIPH_PVT_TIM_REG_BASE + TIMER_PVT_STATUS_OFFSET);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value in msec.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This is used in conjuction with get_ticks, which returns msec as ticks.
+ * Here we just return ticks/sec = msec/sec = 1000
+ */
+ulong get_tbclk(void)
+{
+ return 1000;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/kona-common/Makefile b/roms/u-boot/arch/arm/cpu/armv7/kona-common/Makefile
new file mode 100644
index 000000000..56de3d18e
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/kona-common/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2013 Broadcom Corporation.
+
+obj-y += s_init.o
+obj-y += hwinit-common.o
+obj-y += clk-stubs.o
+obj-${CONFIG_KONA_RESET_S} += reset.o
diff --git a/roms/u-boot/arch/arm/cpu/armv7/kona-common/clk-stubs.c b/roms/u-boot/arch/arm/cpu/armv7/kona-common/clk-stubs.c
new file mode 100644
index 000000000..4eddaca88
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/kona-common/clk-stubs.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+#include <common.h>
+
+/*
+ * These weak functions are available to kona architectures that don't
+ * require clock enables from the driver code.
+ */
+int __weak clk_sdio_enable(void *base, u32 rate, u32 *actual_ratep)
+{
+ return 0;
+}
+
+int __weak clk_bsc_enable(void *base)
+{
+ return 0;
+}
+
+int __weak clk_usb_otg_enable(void *base)
+{
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/kona-common/hwinit-common.c b/roms/u-boot/arch/arm/cpu/armv7/kona-common/hwinit-common.c
new file mode 100644
index 000000000..cfc7c9fbc
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/kona-common/hwinit-common.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/cache.h>
+#include <linux/sizes.h>
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+void enable_caches(void)
+{
+ /* Enable D-cache. I-cache is already enabled in start.S */
+ dcache_enable();
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv7/kona-common/reset.S b/roms/u-boot/arch/arm/cpu/armv7/kona-common/reset.S
new file mode 100644
index 000000000..eea835b34
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/kona-common/reset.S
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2013 Broadcom Corporation.
+ */
+
+.globl reset_cpu
+reset_cpu:
+ ldr r1, =0x35001f00
+ ldr r2, [r1]
+ ldr r4, =0x80000000
+ and r4, r2, r4
+ ldr r3, =0xA5A500
+ orr r4, r4, r3
+ orr r4, r4, #0x1
+
+ str r4, [r1]
+
+ ldr r1, =0x35001f04
+ ldr r2, [r1]
+ ldr r4, =0x80000000
+ and r4, r2, r4
+ str r4, [r1]
+
+_loop_forever:
+ b _loop_forever
diff --git a/roms/u-boot/arch/arm/cpu/armv7/kona-common/s_init.c b/roms/u-boot/arch/arm/cpu/armv7/kona-common/s_init.c
new file mode 100644
index 000000000..778b9176f
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/kona-common/s_init.c
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Broadcom Corporation.
+ */
+
+/*
+ * Early system init. Currently empty.
+ */
+void s_init(void)
+{
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/lowlevel_init.S b/roms/u-boot/arch/arm/cpu/armv7/lowlevel_init.S
new file mode 100644
index 000000000..ba4b374a8
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/lowlevel_init.S
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * A lowlevel_init function that sets up the stack to call a C function to
+ * perform further init.
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ * Aneesh V <aneesh@ti.com>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+
+.pushsection .text.s_init, "ax"
+WEAK(s_init)
+ bx lr
+ENDPROC(s_init)
+.popsection
+
+.pushsection .text.lowlevel_init, "ax"
+WEAK(lowlevel_init)
+ /*
+ * Setup a temporary stack. Global data is not available yet.
+ */
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
+ ldr sp, =CONFIG_SPL_STACK
+#else
+ ldr sp, =CONFIG_SYS_INIT_SP_ADDR
+#endif
+ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
+#ifdef CONFIG_SPL_DM
+ mov r9, #0
+#else
+ /*
+ * Set up global data for boards that still need it. This will be
+ * removed soon.
+ */
+#ifdef CONFIG_SPL_BUILD
+ ldr r9, =gdata
+#else
+ sub sp, sp, #GD_SIZE
+ bic sp, sp, #7
+ mov r9, sp
+#endif
+#endif
+ /*
+ * Save the old lr(passed in ip) and the current lr to stack
+ */
+ push {ip, lr}
+
+ /*
+ * Call the very early init function. This should do only the
+ * absolute bare minimum to get started. It should not:
+ *
+ * - set up DRAM
+ * - use global_data
+ * - clear BSS
+ * - try to start a console
+ *
+ * For boards with SPL this should be empty since SPL can do all of
+ * this init in the SPL board_init_f() function which is called
+ * immediately after this.
+ */
+ bl s_init
+ pop {ip, pc}
+ENDPROC(lowlevel_init)
+.popsection
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/Kconfig b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/Kconfig
new file mode 100644
index 000000000..747059b56
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/Kconfig
@@ -0,0 +1,104 @@
+config ARCH_LS1021A
+ bool
+ select SYS_FSL_DDR_BE if SYS_FSL_DDR
+ select SYS_FSL_DDR_VER_50 if SYS_FSL_DDR
+ select SYS_FSL_ERRATUM_A008378
+ select SYS_FSL_ERRATUM_A008407
+ select SYS_FSL_ERRATUM_A008850
+ select SYS_FSL_ERRATUM_A008997 if USB
+ select SYS_FSL_ERRATUM_A009007 if USB
+ select SYS_FSL_ERRATUM_A009008 if USB
+ select SYS_FSL_ERRATUM_A009663
+ select SYS_FSL_ERRATUM_A009798 if USB
+ select SYS_FSL_ERRATUM_A009942
+ select SYS_FSL_ERRATUM_A010315
+ select SYS_FSL_HAS_CCI400
+ select SYS_FSL_HAS_DDR3 if SYS_FSL_DDR
+ select SYS_FSL_HAS_DDR4 if SYS_FSL_DDR
+ select SYS_FSL_HAS_SEC
+ select SYS_FSL_SEC_COMPAT_5
+ select SYS_FSL_SEC_LE
+ select SYS_FSL_SRDS_1
+ select SYS_HAS_SERDES
+ imply CMD_PCI
+ imply SCSI
+ imply SCSI_AHCI
+
+menu "LS102xA architecture"
+ depends on ARCH_LS1021A
+
+config LS1_DEEP_SLEEP
+ bool "Deep sleep"
+
+config MAX_CPUS
+ int "Maximum number of CPUs permitted for LS102xA"
+ default 2
+ help
+ Set this number to the maximum number of possible CPUs in the SoC.
+ SoCs may have multiple clusters with each cluster may have multiple
+ ports. If some ports are reserved but higher ports are used for
+ cores, count the reserved ports. This will allocate enough memory
+ in spin table to properly handle all cores.
+
+config NXP_ESBC
+ bool "NXP_ESBC"
+ help
+ Enable Freescale Secure Boot feature. Normally selected
+ by defconfig. If unsure, do not change.
+
+config SYS_CCI400_OFFSET
+ hex "Offset for CCI400 base"
+ depends on SYS_FSL_HAS_CCI400
+ default 0x180000
+ help
+ Offset for CCI400 base.
+ CCI400 base addr = CCSRBAR + CCI400_OFFSET
+
+config SYS_FSL_ERRATUM_A008850
+ bool
+ help
+ Workaround for DDR erratum A008850
+
+config SYS_FSL_ERRATUM_A008997
+ bool
+ help
+ Workaround for USB PHY erratum A008997
+
+config SYS_FSL_ERRATUM_A009007
+ bool
+ help
+ Workaround for USB PHY erratum A009007
+
+config SYS_FSL_ERRATUM_A009008
+ bool
+ help
+ Workaround for USB PHY erratum A009008
+
+config SYS_FSL_ERRATUM_A009798
+ bool
+ help
+ Workaround for USB PHY erratum A009798
+
+config SYS_FSL_ERRATUM_A010315
+ bool "Workaround for PCIe erratum A010315"
+
+config SYS_FSL_HAS_CCI400
+ bool
+
+config SYS_FSL_SRDS_1
+ bool
+
+config SYS_FSL_SRDS_2
+ bool
+
+config SYS_HAS_SERDES
+ bool
+
+config SYS_FSL_IFC_BANK_COUNT
+ int "Maximum banks of Integrated flash controller"
+ default 8
+
+config SYS_FSL_ERRATUM_A008407
+ bool
+
+endmenu
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/Makefile b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/Makefile
new file mode 100644
index 000000000..0c1596f33
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/Makefile
@@ -0,0 +1,19 @@
+#
+# Copyright 2014 Freescale Semiconductor, Inc.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += cpu.o
+obj-y += clock.o
+obj-y += timer.o
+obj-y += fsl_epu.o
+obj-y += soc.o
+
+obj-$(CONFIG_OF_LIBFDT) += fdt.o
+obj-$(CONFIG_SYS_HAS_SERDES) += fsl_ls1_serdes.o ls102xa_serdes.o
+obj-$(CONFIG_SPL) += spl.o
+
+ifdef CONFIG_ARMV7_PSCI
+obj-y += psci.o ls102xa_psci.o
+endif
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/clock.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/clock.c
new file mode 100644
index 000000000..940995ef5
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/clock.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <clock_legacy.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/immap_ls102xa.h>
+#include <asm/arch/clock.h>
+#include <fsl_ifc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
+#define CONFIG_SYS_FSL_NUM_CC_PLLS 2
+#endif
+
+void get_sys_info(struct sys_info *sys_info)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_LS1_CLK_ADDR);
+ unsigned int cpu;
+ const u8 core_cplx_pll[6] = {
+ [0] = 0, /* CC1 PPL / 1 */
+ [1] = 0, /* CC1 PPL / 2 */
+ [4] = 1, /* CC2 PPL / 1 */
+ [5] = 1, /* CC2 PPL / 2 */
+ };
+
+ const u8 core_cplx_pll_div[6] = {
+ [0] = 1, /* CC1 PPL / 1 */
+ [1] = 2, /* CC1 PPL / 2 */
+ [4] = 1, /* CC2 PPL / 1 */
+ [5] = 2, /* CC2 PPL / 2 */
+ };
+
+ uint i;
+ uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
+ uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
+ unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
+
+ sys_info->freq_systembus = sysclk;
+#ifdef CONFIG_DDR_CLK_FREQ
+ sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
+#else
+ sys_info->freq_ddrbus = sysclk;
+#endif
+
+ sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >>
+ RCWSR0_SYS_PLL_RAT_SHIFT) & RCWSR0_SYS_PLL_RAT_MASK;
+ sys_info->freq_ddrbus *= (in_be32(&gur->rcwsr[0]) >>
+ RCWSR0_MEM_PLL_RAT_SHIFT) & RCWSR0_MEM_PLL_RAT_MASK;
+
+ for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
+ ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0x3f;
+ if (ratio[i] > 4)
+ freq_c_pll[i] = sysclk * ratio[i];
+ else
+ freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
+ }
+
+ for (cpu = 0; cpu < CONFIG_MAX_CPUS; cpu++) {
+ u32 c_pll_sel = (in_be32(&clk->clkcsr[cpu].clkcncsr) >> 27)
+ & 0xf;
+ u32 cplx_pll = core_cplx_pll[c_pll_sel];
+
+ sys_info->freq_processor[cpu] =
+ freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
+ }
+
+#if defined(CONFIG_FSL_IFC)
+ sys_info->freq_localbus = sys_info->freq_systembus;
+#endif
+}
+
+int get_clocks(void)
+{
+ struct sys_info sys_info;
+
+ get_sys_info(&sys_info);
+ gd->cpu_clk = sys_info.freq_processor[0];
+ gd->bus_clk = sys_info.freq_systembus;
+ gd->mem_clk = sys_info.freq_ddrbus * 2;
+
+#if defined(CONFIG_FSL_ESDHC)
+ gd->arch.sdhc_clk = gd->bus_clk;
+#endif
+
+ return 0;
+}
+
+ulong get_bus_freq(ulong dummy)
+{
+ return gd->bus_clk;
+}
+
+ulong get_ddr_freq(ulong dummy)
+{
+ return gd->mem_clk;
+}
+
+int get_serial_clock(void)
+{
+ return gd->bus_clk / 2;
+}
+
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+ switch (clk) {
+ case MXC_I2C_CLK:
+ return get_bus_freq(0) / 2;
+ case MXC_DSPI_CLK:
+ return get_bus_freq(0) / 2;
+ case MXC_UART_CLK:
+ return get_bus_freq(0) / 2;
+ default:
+ printf("Unsupported clock\n");
+ }
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/cpu.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/cpu.c
new file mode 100644
index 000000000..d863c9625
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/cpu.c
@@ -0,0 +1,399 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <init.h>
+#include <net.h>
+#include <vsprintf.h>
+#include <asm/arch/clock.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/immap_ls102xa.h>
+#include <asm/cache.h>
+#include <asm/system.h>
+#include <tsec.h>
+#include <netdev.h>
+#include <fsl_esdhc.h>
+#include <config.h>
+#include <fsl_wdog.h>
+#include <linux/delay.h>
+
+#include "fsl_epu.h"
+
+#define DCSR_RCPM2_BLOCK_OFFSET 0x223000
+#define DCSR_RCPM2_CPMFSMCR0 0x400
+#define DCSR_RCPM2_CPMFSMSR0 0x404
+#define DCSR_RCPM2_CPMFSMCR1 0x414
+#define DCSR_RCPM2_CPMFSMSR1 0x418
+#define CPMFSMSR_FSM_STATE_MASK 0x7f
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+
+/*
+ * Bit[1] of the descriptor indicates the descriptor type,
+ * and bit[0] indicates whether the descriptor is valid.
+ */
+#define PMD_TYPE_TABLE 0x3
+#define PMD_TYPE_SECT 0x1
+
+/* AttrIndx[2:0] */
+#define PMD_ATTRINDX(t) ((t) << 2)
+
+/* Section */
+#define PMD_SECT_AF (1 << 10)
+
+#define BLOCK_SIZE_L1 (1UL << 30)
+#define BLOCK_SIZE_L2 (1UL << 21)
+
+/* TTBCR flags */
+#define TTBCR_EAE (1 << 31)
+#define TTBCR_T0SZ(x) ((x) << 0)
+#define TTBCR_T1SZ(x) ((x) << 16)
+#define TTBCR_USING_TTBR0 (TTBCR_T0SZ(0) | TTBCR_T1SZ(0))
+#define TTBCR_IRGN0_NC (0 << 8)
+#define TTBCR_IRGN0_WBWA (1 << 8)
+#define TTBCR_IRGN0_WT (2 << 8)
+#define TTBCR_IRGN0_WBNWA (3 << 8)
+#define TTBCR_IRGN0_MASK (3 << 8)
+#define TTBCR_ORGN0_NC (0 << 10)
+#define TTBCR_ORGN0_WBWA (1 << 10)
+#define TTBCR_ORGN0_WT (2 << 10)
+#define TTBCR_ORGN0_WBNWA (3 << 10)
+#define TTBCR_ORGN0_MASK (3 << 10)
+#define TTBCR_SHARED_NON (0 << 12)
+#define TTBCR_SHARED_OUTER (2 << 12)
+#define TTBCR_SHARED_INNER (3 << 12)
+#define TTBCR_EPD0 (0 << 7)
+#define TTBCR (TTBCR_SHARED_NON | \
+ TTBCR_ORGN0_NC | \
+ TTBCR_IRGN0_NC | \
+ TTBCR_USING_TTBR0 | \
+ TTBCR_EAE)
+
+/*
+ * Memory region attributes for LPAE (defined in pgtable):
+ *
+ * n = AttrIndx[2:0]
+ *
+ * n MAIR
+ * UNCACHED 000 00000000
+ * BUFFERABLE 001 01000100
+ * DEV_WC 001 01000100
+ * WRITETHROUGH 010 10101010
+ * WRITEBACK 011 11101110
+ * DEV_CACHED 011 11101110
+ * DEV_SHARED 100 00000100
+ * DEV_NONSHARED 100 00000100
+ * unused 101
+ * unused 110
+ * WRITEALLOC 111 11111111
+ */
+#define MT_MAIR0 0xeeaa4400
+#define MT_MAIR1 0xff000004
+#define MT_STRONLY_ORDER 0
+#define MT_NORMAL_NC 1
+#define MT_DEVICE_MEM 4
+#define MT_NORMAL 7
+
+/* The phy_addr must be aligned to 4KB */
+static inline void set_pgtable(u32 *page_table, u32 index, u32 phy_addr)
+{
+ u32 value = phy_addr | PMD_TYPE_TABLE;
+
+ page_table[2 * index] = value;
+ page_table[2 * index + 1] = 0;
+}
+
+/* The phy_addr must be aligned to 4KB */
+static inline void set_pgsection(u32 *page_table, u32 index, u64 phy_addr,
+ u32 memory_type)
+{
+ u64 value;
+
+ value = phy_addr | PMD_TYPE_SECT | PMD_SECT_AF;
+ value |= PMD_ATTRINDX(memory_type);
+ page_table[2 * index] = value & 0xFFFFFFFF;
+ page_table[2 * index + 1] = (value >> 32) & 0xFFFFFFFF;
+}
+
+/*
+ * Start MMU after DDR is available, we create MMU table in DRAM.
+ * The base address of TTLB is gd->arch.tlb_addr. We use two
+ * levels of translation tables here to cover 40-bit address space.
+ *
+ * The TTLBs are located at PHY 2G~4G.
+ *
+ * VA mapping:
+ *
+ * ------- <---- 0GB
+ * | |
+ * | |
+ * |-------| <---- 0x24000000
+ * |///////| ===> 192MB VA map for PCIe1 with offset 0x40_0000_0000
+ * |-------| <---- 0x300000000
+ * | |
+ * |-------| <---- 0x34000000
+ * |///////| ===> 192MB VA map for PCIe2 with offset 0x48_0000_0000
+ * |-------| <---- 0x40000000
+ * | |
+ * |-------| <---- 0x80000000 DDR0 space start
+ * |\\\\\\\|
+ *.|\\\\\\\| ===> 2GB VA map for 2GB DDR0 Memory space
+ * |\\\\\\\|
+ * ------- <---- 4GB DDR0 space end
+ */
+static void mmu_setup(void)
+{
+ u32 *level0_table = (u32 *)gd->arch.tlb_addr;
+ u32 *level1_table = (u32 *)(gd->arch.tlb_addr + 0x1000);
+ u64 va_start = 0;
+ u32 reg;
+ int i;
+
+ /* Level 0 Table 2-3 are used to map DDR */
+ set_pgsection(level0_table, 3, 3 * BLOCK_SIZE_L1, MT_NORMAL);
+ set_pgsection(level0_table, 2, 2 * BLOCK_SIZE_L1, MT_NORMAL);
+ /* Level 0 Table 1 is used to map device */
+ set_pgsection(level0_table, 1, 1 * BLOCK_SIZE_L1, MT_DEVICE_MEM);
+ /* Level 0 Table 0 is used to map device including PCIe MEM */
+ set_pgtable(level0_table, 0, (u32)level1_table);
+
+ /* Level 1 has 512 entries */
+ for (i = 0; i < 512; i++) {
+ /* Mapping for PCIe 1 */
+ if (va_start >= CONFIG_SYS_PCIE1_VIRT_ADDR &&
+ va_start < (CONFIG_SYS_PCIE1_VIRT_ADDR +
+ CONFIG_SYS_PCIE_MMAP_SIZE))
+ set_pgsection(level1_table, i,
+ CONFIG_SYS_PCIE1_PHYS_BASE + va_start,
+ MT_DEVICE_MEM);
+ /* Mapping for PCIe 2 */
+ else if (va_start >= CONFIG_SYS_PCIE2_VIRT_ADDR &&
+ va_start < (CONFIG_SYS_PCIE2_VIRT_ADDR +
+ CONFIG_SYS_PCIE_MMAP_SIZE))
+ set_pgsection(level1_table, i,
+ CONFIG_SYS_PCIE2_PHYS_BASE + va_start,
+ MT_DEVICE_MEM);
+ else
+ set_pgsection(level1_table, i,
+ va_start,
+ MT_DEVICE_MEM);
+ va_start += BLOCK_SIZE_L2;
+ }
+
+ asm volatile("dsb sy;isb");
+ asm volatile("mcr p15, 0, %0, c2, c0, 2" /* Write RT to TTBCR */
+ : : "r" (TTBCR) : "memory");
+ asm volatile("mcrr p15, 0, %0, %1, c2" /* TTBR 0 */
+ : : "r" ((u32)level0_table), "r" (0) : "memory");
+ asm volatile("mcr p15, 0, %0, c10, c2, 0" /* write MAIR 0 */
+ : : "r" (MT_MAIR0) : "memory");
+ asm volatile("mcr p15, 0, %0, c10, c2, 1" /* write MAIR 1 */
+ : : "r" (MT_MAIR1) : "memory");
+
+ /* Set the access control to all-supervisor */
+ asm volatile("mcr p15, 0, %0, c3, c0, 0"
+ : : "r" (~0));
+
+ /* Enable the mmu */
+ reg = get_cr();
+ set_cr(reg | CR_M);
+}
+
+/*
+ * This function is called from lib/board.c. It recreates MMU
+ * table in main memory. MMU and i/d-cache are enabled here.
+ */
+void enable_caches(void)
+{
+ /* Invalidate all TLB */
+ mmu_page_table_flush(gd->arch.tlb_addr,
+ gd->arch.tlb_addr + gd->arch.tlb_size);
+ /* Set up and enable mmu */
+ mmu_setup();
+
+ /* Invalidate & Enable d-cache */
+ invalidate_dcache_all();
+ set_cr(get_cr() | CR_C);
+}
+#endif /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
+
+
+uint get_svr(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+
+ return in_be32(&gur->svr);
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+ char buf1[32], buf2[32];
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ unsigned int svr, major, minor, ver, i;
+
+ svr = in_be32(&gur->svr);
+ major = SVR_MAJ(svr);
+ minor = SVR_MIN(svr);
+
+ puts("CPU: Freescale LayerScape ");
+
+ ver = SVR_SOC_VER(svr);
+ switch (ver) {
+ case SOC_VER_SLS1020:
+ puts("SLS1020");
+ break;
+ case SOC_VER_LS1020:
+ puts("LS1020");
+ break;
+ case SOC_VER_LS1021:
+ puts("LS1021");
+ break;
+ case SOC_VER_LS1022:
+ puts("LS1022");
+ break;
+ default:
+ puts("Unknown");
+ break;
+ }
+
+ if (IS_E_PROCESSOR(svr) && (ver != SOC_VER_SLS1020))
+ puts("E");
+
+ printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
+
+ puts("Clock Configuration:");
+
+ printf("\n CPU0(ARMV7):%-4s MHz, ", strmhz(buf1, gd->cpu_clk));
+ printf("\n Bus:%-4s MHz, ", strmhz(buf1, gd->bus_clk));
+ printf("DDR:%-4s MHz (%s MT/s data rate), ",
+ strmhz(buf1, gd->mem_clk/2), strmhz(buf2, gd->mem_clk));
+ puts("\n");
+
+ /* Display the RCW, so that no one gets confused as to what RCW
+ * we're actually using for this boot.
+ */
+ puts("Reset Configuration Word (RCW):");
+ for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) {
+ u32 rcw = in_be32(&gur->rcwsr[i]);
+
+ if ((i % 4) == 0)
+ printf("\n %08x:", i * 4);
+ printf(" %08x", rcw);
+ }
+ puts("\n");
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_FSL_ESDHC
+int cpu_mmc_init(struct bd_info *bis)
+{
+ return fsl_esdhc_mmc_init(bis);
+}
+#endif
+
+int cpu_eth_init(struct bd_info *bis)
+{
+#if defined(CONFIG_TSEC_ENET) && !defined(CONFIG_DM_ETH)
+ tsec_standard_init(bis);
+#endif
+
+ return 0;
+}
+
+int arch_cpu_init(void)
+{
+ void *epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET);
+ void *rcpm2_base =
+ (void *)(CONFIG_SYS_DCSRBAR + DCSR_RCPM2_BLOCK_OFFSET);
+ struct ccsr_scfg *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
+ u32 state;
+
+ icache_enable();
+
+ /*
+ * The RCPM FSM state may not be reset after power-on.
+ * So, reset them.
+ */
+ state = in_be32(rcpm2_base + DCSR_RCPM2_CPMFSMSR0) &
+ CPMFSMSR_FSM_STATE_MASK;
+ if (state != 0) {
+ out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR0, 0x80);
+ out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR0, 0x0);
+ }
+
+ state = in_be32(rcpm2_base + DCSR_RCPM2_CPMFSMSR1) &
+ CPMFSMSR_FSM_STATE_MASK;
+ if (state != 0) {
+ out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR1, 0x80);
+ out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR1, 0x0);
+ }
+
+ /*
+ * After wakeup from deep sleep, Clear EPU registers
+ * as early as possible to prevent from possible issue.
+ * It's also safe to clear at normal boot.
+ */
+ fsl_epu_clean(epu_base);
+
+ setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SEC_RD_WR);
+
+ return 0;
+}
+
+#ifdef CONFIG_ARMV7_NONSEC
+/* Set the address at which the secondary core starts from.*/
+void smp_set_core_boot_addr(unsigned long addr, int corenr)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+
+ out_be32(&gur->scratchrw[0], addr);
+}
+
+/* Release the secondary core from holdoff state and kick it */
+void smp_kick_all_cpus(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+
+ out_be32(&gur->brrl, 0x2);
+
+ /*
+ * LS1 STANDBYWFE is not captured outside the ARM module in the soc.
+ * So add a delay to wait bootrom execute WFE.
+ */
+ udelay(1);
+
+ asm volatile("sev");
+}
+#endif
+
+void reset_cpu(void)
+{
+ struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
+
+ clrbits_be16(&wdog->wcr, WCR_SRS);
+
+ while (1) {
+ /*
+ * Let the watchdog trigger
+ */
+ }
+}
+
+void arch_preboot_os(void)
+{
+ unsigned long ctrl;
+
+ /* Disable PL1 Physical Timer */
+ asm("mrc p15, 0, %0, c14, c2, 1" : "=r" (ctrl));
+ ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
+ asm("mcr p15, 0, %0, c14, c2, 1" : : "r" (ctrl));
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fdt.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fdt.c
new file mode 100644
index 000000000..0daf8234f
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fdt.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <clock_legacy.h>
+#include <net.h>
+#include <asm/global_data.h>
+#include <linux/libfdt.h>
+#include <fdt_support.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/arch/clock.h>
+#include <linux/ctype.h>
+#ifdef CONFIG_FSL_ESDHC
+#include <fsl_esdhc.h>
+#endif
+#include <tsec.h>
+#include <asm/arch/immap_ls102xa.h>
+#include <fsl_sec.h>
+#include <dm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void ft_fixup_enet_phy_connect_type(void *fdt)
+{
+#ifdef CONFIG_DM_ETH
+ struct udevice *dev;
+#else
+ struct eth_device *dev;
+#endif
+ struct tsec_private *priv;
+ const char *enet_path, *phy_path;
+ char enet[16];
+ char phy[16];
+ int phy_node;
+ int i = 0;
+ uint32_t ph;
+#ifdef CONFIG_DM_ETH
+ char *name[3] = { "ethernet@2d10000", "ethernet@2d50000",
+ "ethernet@2d90000" };
+#else
+ char *name[3] = { "eTSEC1", "eTSEC2", "eTSEC3" };
+#endif
+
+ for (; i < ARRAY_SIZE(name); i++) {
+ dev = eth_get_dev_by_name(name[i]);
+ if (dev) {
+ sprintf(enet, "ethernet%d", i);
+ sprintf(phy, "enet%d_rgmii_phy", i);
+ } else {
+ continue;
+ }
+
+#ifdef CONFIG_DM_ETH
+ priv = dev_get_priv(dev);
+#else
+ priv = dev->priv;
+#endif
+ if (priv->flags & TSEC_SGMII)
+ continue;
+
+ enet_path = fdt_get_alias(fdt, enet);
+ if (!enet_path)
+ continue;
+
+ phy_path = fdt_get_alias(fdt, phy);
+ if (!phy_path)
+ continue;
+
+ phy_node = fdt_path_offset(fdt, phy_path);
+ if (phy_node < 0)
+ continue;
+
+ ph = fdt_create_phandle(fdt, phy_node);
+ if (ph)
+ do_fixup_by_path_u32(fdt, enet_path,
+ "phy-handle", ph, 1);
+
+ do_fixup_by_path(fdt, enet_path, "phy-connection-type",
+ phy_string_for_interface(
+ PHY_INTERFACE_MODE_RGMII_ID),
+ strlen(phy_string_for_interface(
+ PHY_INTERFACE_MODE_RGMII_ID)) + 1,
+ 1);
+ }
+}
+
+void ft_cpu_setup(void *blob, struct bd_info *bd)
+{
+ int off;
+ int val;
+ const char *sysclk_path;
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ unsigned int svr;
+ svr = in_be32(&gur->svr);
+
+ unsigned long busclk = get_bus_freq(0);
+
+ /* delete crypto node if not on an E-processor */
+ if (!IS_E_PROCESSOR(svr))
+ fdt_fixup_crypto_node(blob, 0);
+#if CONFIG_SYS_FSL_SEC_COMPAT >= 4
+ else {
+ ccsr_sec_t __iomem *sec;
+
+ sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR;
+ fdt_fixup_crypto_node(blob, sec_in32(&sec->secvid_ms));
+ }
+#endif
+
+ off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
+ while (off != -FDT_ERR_NOTFOUND) {
+ val = gd->cpu_clk;
+ fdt_setprop(blob, off, "clock-frequency", &val, 4);
+ off = fdt_node_offset_by_prop_value(blob, off,
+ "device_type", "cpu", 4);
+ }
+
+ do_fixup_by_prop_u32(blob, "device_type", "soc",
+ 4, "bus-frequency", busclk, 1);
+
+ ft_fixup_enet_phy_connect_type(blob);
+
+#ifdef CONFIG_SYS_NS16550
+ do_fixup_by_compat_u32(blob, "fsl,16550-FIFO64",
+ "clock-frequency", CONFIG_SYS_NS16550_CLK, 1);
+#endif
+
+ sysclk_path = fdt_get_alias(blob, "sysclk");
+ if (sysclk_path)
+ do_fixup_by_path_u32(blob, sysclk_path, "clock-frequency",
+ CONFIG_SYS_CLK_FREQ, 1);
+ do_fixup_by_compat_u32(blob, "fsl,qoriq-sysclk-2.0",
+ "clock-frequency", CONFIG_SYS_CLK_FREQ, 1);
+
+#if defined(CONFIG_DEEP_SLEEP) && defined(CONFIG_SD_BOOT)
+#define UBOOT_HEAD_LEN 0x1000
+ /*
+ * Reserved memory in SD boot deep sleep case.
+ * Second stage uboot binary and malloc space should be reserved.
+ * If the memory they occupied has not been reserved, then this
+ * space would be used by kernel and overwritten in uboot when
+ * deep sleep resume, which cause deep sleep failed.
+ * Since second uboot binary has a head, that space need to be
+ * reserved either(assuming its size is less than 0x1000).
+ */
+ off = fdt_add_mem_rsv(blob, CONFIG_SYS_TEXT_BASE - UBOOT_HEAD_LEN,
+ CONFIG_SYS_MONITOR_LEN + CONFIG_SYS_SPL_MALLOC_SIZE +
+ UBOOT_HEAD_LEN);
+ if (off < 0)
+ printf("Failed to reserve memory for SD boot deep sleep: %s\n",
+ fdt_strerror(off));
+#endif
+
+#if defined(CONFIG_FSL_ESDHC)
+ fdt_fixup_esdhc(blob, bd);
+#endif
+
+ /*
+ * platform bus clock = system bus clock/2
+ * Here busclk = system bus clock
+ * We are using the platform bus clock as 1588 Timer reference
+ * clock source select
+ */
+ do_fixup_by_compat_u32(blob, "fsl, gianfar-ptp-timer",
+ "timer-frequency", busclk / 2, 1);
+
+ /*
+ * clock-freq should change to clock-frequency and
+ * flexcan-v1.0 should change to p1010-flexcan respectively
+ * in the future.
+ */
+ do_fixup_by_compat_u32(blob, "fsl, flexcan-v1.0",
+ "clock_freq", busclk / 2, 1);
+
+ do_fixup_by_compat_u32(blob, "fsl, flexcan-v1.0",
+ "clock-frequency", busclk / 2, 1);
+
+ do_fixup_by_compat_u32(blob, "fsl, ls1021a-flexcan",
+ "clock-frequency", busclk / 2, 1);
+
+#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI)
+ off = fdt_node_offset_by_compat_reg(blob, FSL_IFC_COMPAT,
+ CONFIG_SYS_IFC_ADDR);
+ fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
+#else
+ off = fdt_node_offset_by_compat_reg(blob, FSL_QSPI_COMPAT,
+ QSPI0_BASE_ADDR);
+ fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
+ off = fdt_node_offset_by_compat_reg(blob, FSL_DSPI_COMPAT,
+ DSPI1_BASE_ADDR);
+ fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
+#endif
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.c
new file mode 100644
index 000000000..e31a4fb6c
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#include "fsl_epu.h"
+
+struct fsm_reg_vals epu_default_val[] = {
+ /* EPGCR (Event Processor Global Control Register) */
+ {EPGCR, 0},
+ /* EPECR (Event Processor Event Control Registers) */
+ {EPECR0 + EPECR_STRIDE * 0, 0},
+ {EPECR0 + EPECR_STRIDE * 1, 0},
+ {EPECR0 + EPECR_STRIDE * 2, 0xF0004004},
+ {EPECR0 + EPECR_STRIDE * 3, 0x80000084},
+ {EPECR0 + EPECR_STRIDE * 4, 0x20000084},
+ {EPECR0 + EPECR_STRIDE * 5, 0x08000004},
+ {EPECR0 + EPECR_STRIDE * 6, 0x80000084},
+ {EPECR0 + EPECR_STRIDE * 7, 0x80000084},
+ {EPECR0 + EPECR_STRIDE * 8, 0x60000084},
+ {EPECR0 + EPECR_STRIDE * 9, 0x08000084},
+ {EPECR0 + EPECR_STRIDE * 10, 0x42000084},
+ {EPECR0 + EPECR_STRIDE * 11, 0x90000084},
+ {EPECR0 + EPECR_STRIDE * 12, 0x80000084},
+ {EPECR0 + EPECR_STRIDE * 13, 0x08000084},
+ {EPECR0 + EPECR_STRIDE * 14, 0x02000084},
+ {EPECR0 + EPECR_STRIDE * 15, 0x00000004},
+ /*
+ * EPEVTCR (Event Processor EVT Pin Control Registers)
+ * SCU8 triger EVT2, and SCU11 triger EVT9
+ */
+ {EPEVTCR0 + EPEVTCR_STRIDE * 0, 0},
+ {EPEVTCR0 + EPEVTCR_STRIDE * 1, 0},
+ {EPEVTCR0 + EPEVTCR_STRIDE * 2, 0x80000001},
+ {EPEVTCR0 + EPEVTCR_STRIDE * 3, 0},
+ {EPEVTCR0 + EPEVTCR_STRIDE * 4, 0},
+ {EPEVTCR0 + EPEVTCR_STRIDE * 5, 0},
+ {EPEVTCR0 + EPEVTCR_STRIDE * 6, 0},
+ {EPEVTCR0 + EPEVTCR_STRIDE * 7, 0},
+ {EPEVTCR0 + EPEVTCR_STRIDE * 8, 0},
+ {EPEVTCR0 + EPEVTCR_STRIDE * 9, 0xB0000001},
+ /* EPCMPR (Event Processor Counter Compare Registers) */
+ {EPCMPR0 + EPCMPR_STRIDE * 0, 0},
+ {EPCMPR0 + EPCMPR_STRIDE * 1, 0},
+ {EPCMPR0 + EPCMPR_STRIDE * 2, 0x000000FF},
+ {EPCMPR0 + EPCMPR_STRIDE * 3, 0},
+ {EPCMPR0 + EPCMPR_STRIDE * 4, 0x000000FF},
+ {EPCMPR0 + EPCMPR_STRIDE * 5, 0x00000020},
+ {EPCMPR0 + EPCMPR_STRIDE * 6, 0},
+ {EPCMPR0 + EPCMPR_STRIDE * 7, 0},
+ {EPCMPR0 + EPCMPR_STRIDE * 8, 0x000000FF},
+ {EPCMPR0 + EPCMPR_STRIDE * 9, 0x000000FF},
+ {EPCMPR0 + EPCMPR_STRIDE * 10, 0x000000FF},
+ {EPCMPR0 + EPCMPR_STRIDE * 11, 0x000000FF},
+ {EPCMPR0 + EPCMPR_STRIDE * 12, 0x000000FF},
+ {EPCMPR0 + EPCMPR_STRIDE * 13, 0},
+ {EPCMPR0 + EPCMPR_STRIDE * 14, 0x000000FF},
+ {EPCMPR0 + EPCMPR_STRIDE * 15, 0x000000FF},
+ /* EPCCR (Event Processor Counter Control Registers) */
+ {EPCCR0 + EPCCR_STRIDE * 0, 0},
+ {EPCCR0 + EPCCR_STRIDE * 1, 0},
+ {EPCCR0 + EPCCR_STRIDE * 2, 0x92840000},
+ {EPCCR0 + EPCCR_STRIDE * 3, 0},
+ {EPCCR0 + EPCCR_STRIDE * 4, 0x92840000},
+ {EPCCR0 + EPCCR_STRIDE * 5, 0x92840000},
+ {EPCCR0 + EPCCR_STRIDE * 6, 0},
+ {EPCCR0 + EPCCR_STRIDE * 7, 0},
+ {EPCCR0 + EPCCR_STRIDE * 8, 0x92840000},
+ {EPCCR0 + EPCCR_STRIDE * 9, 0x92840000},
+ {EPCCR0 + EPCCR_STRIDE * 10, 0x92840000},
+ {EPCCR0 + EPCCR_STRIDE * 11, 0x92840000},
+ {EPCCR0 + EPCCR_STRIDE * 12, 0x92840000},
+ {EPCCR0 + EPCCR_STRIDE * 13, 0},
+ {EPCCR0 + EPCCR_STRIDE * 14, 0x92840000},
+ {EPCCR0 + EPCCR_STRIDE * 15, 0x92840000},
+ /* EPSMCR (Event Processor SCU Mux Control Registers) */
+ {EPSMCR0 + EPSMCR_STRIDE * 0, 0},
+ {EPSMCR0 + EPSMCR_STRIDE * 1, 0},
+ {EPSMCR0 + EPSMCR_STRIDE * 2, 0x6C700000},
+ {EPSMCR0 + EPSMCR_STRIDE * 3, 0x2F000000},
+ {EPSMCR0 + EPSMCR_STRIDE * 4, 0x002F0000},
+ {EPSMCR0 + EPSMCR_STRIDE * 5, 0x00002E00},
+ {EPSMCR0 + EPSMCR_STRIDE * 6, 0x7C000000},
+ {EPSMCR0 + EPSMCR_STRIDE * 7, 0x30000000},
+ {EPSMCR0 + EPSMCR_STRIDE * 8, 0x64300000},
+ {EPSMCR0 + EPSMCR_STRIDE * 9, 0x00003000},
+ {EPSMCR0 + EPSMCR_STRIDE * 10, 0x65000030},
+ {EPSMCR0 + EPSMCR_STRIDE * 11, 0x31740000},
+ {EPSMCR0 + EPSMCR_STRIDE * 12, 0x7F000000},
+ {EPSMCR0 + EPSMCR_STRIDE * 13, 0x00003100},
+ {EPSMCR0 + EPSMCR_STRIDE * 14, 0x00000031},
+ {EPSMCR0 + EPSMCR_STRIDE * 15, 0x76000000},
+ /* EPACR (Event Processor Action Control Registers) */
+ {EPACR0 + EPACR_STRIDE * 0, 0},
+ {EPACR0 + EPACR_STRIDE * 1, 0},
+ {EPACR0 + EPACR_STRIDE * 2, 0},
+ {EPACR0 + EPACR_STRIDE * 3, 0x00000080},
+ {EPACR0 + EPACR_STRIDE * 4, 0},
+ {EPACR0 + EPACR_STRIDE * 5, 0x00000040},
+ {EPACR0 + EPACR_STRIDE * 6, 0},
+ {EPACR0 + EPACR_STRIDE * 7, 0},
+ {EPACR0 + EPACR_STRIDE * 8, 0},
+ {EPACR0 + EPACR_STRIDE * 9, 0x0000001C},
+ {EPACR0 + EPACR_STRIDE * 10, 0x00000020},
+ {EPACR0 + EPACR_STRIDE * 11, 0},
+ {EPACR0 + EPACR_STRIDE * 12, 0x00000003},
+ {EPACR0 + EPACR_STRIDE * 13, 0x06000000},
+ {EPACR0 + EPACR_STRIDE * 14, 0x04000000},
+ {EPACR0 + EPACR_STRIDE * 15, 0x02000000},
+ /* EPIMCR (Event Processor Input Mux Control Registers) */
+ {EPIMCR0 + EPIMCR_STRIDE * 0, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 1, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 2, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 3, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 4, 0x44000000},
+ {EPIMCR0 + EPIMCR_STRIDE * 5, 0x40000000},
+ {EPIMCR0 + EPIMCR_STRIDE * 6, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 7, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 8, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 9, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 10, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 11, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 12, 0x44000000},
+ {EPIMCR0 + EPIMCR_STRIDE * 13, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 14, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 15, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 16, 0x6A000000},
+ {EPIMCR0 + EPIMCR_STRIDE * 17, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 18, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 19, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 20, 0x48000000},
+ {EPIMCR0 + EPIMCR_STRIDE * 21, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 22, 0x6C000000},
+ {EPIMCR0 + EPIMCR_STRIDE * 23, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 24, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 25, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 26, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 27, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 28, 0x76000000},
+ {EPIMCR0 + EPIMCR_STRIDE * 29, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 30, 0},
+ {EPIMCR0 + EPIMCR_STRIDE * 31, 0x76000000},
+ /* EPXTRIGCR (Event Processor Crosstrigger Control Register) */
+ {EPXTRIGCR, 0x0000FFDF},
+ /* end */
+ {FSM_END_FLAG, 0},
+};
+
+/**
+ * fsl_epu_setup - Setup EPU registers to default values
+ */
+void fsl_epu_setup(void *epu_base)
+{
+ struct fsm_reg_vals *data = epu_default_val;
+
+ if (!epu_base || !data)
+ return;
+
+ while (data->offset != FSM_END_FLAG) {
+ out_be32(epu_base + data->offset, data->value);
+ data++;
+ }
+}
+
+/**
+ * fsl_epu_clean - Clear EPU registers
+ */
+void fsl_epu_clean(void *epu_base)
+{
+ u32 offset;
+
+ /* follow the exact sequence to clear the registers */
+ /* Clear EPACRn */
+ for (offset = EPACR0; offset <= EPACR15; offset += EPACR_STRIDE)
+ out_be32(epu_base + offset, 0);
+
+ /* Clear EPEVTCRn */
+ for (offset = EPEVTCR0; offset <= EPEVTCR9; offset += EPEVTCR_STRIDE)
+ out_be32(epu_base + offset, 0);
+
+ /* Clear EPGCR */
+ out_be32(epu_base + EPGCR, 0);
+
+ /* Clear EPSMCRn */
+ for (offset = EPSMCR0; offset <= EPSMCR15; offset += EPSMCR_STRIDE)
+ out_be32(epu_base + offset, 0);
+
+ /* Clear EPCCRn */
+ for (offset = EPCCR0; offset <= EPCCR31; offset += EPCCR_STRIDE)
+ out_be32(epu_base + offset, 0);
+
+ /* Clear EPCMPRn */
+ for (offset = EPCMPR0; offset <= EPCMPR31; offset += EPCMPR_STRIDE)
+ out_be32(epu_base + offset, 0);
+
+ /* Clear EPCTRn */
+ for (offset = EPCTR0; offset <= EPCTR31; offset += EPCTR_STRIDE)
+ out_be32(epu_base + offset, 0);
+
+ /* Clear EPIMCRn */
+ for (offset = EPIMCR0; offset <= EPIMCR31; offset += EPIMCR_STRIDE)
+ out_be32(epu_base + offset, 0);
+
+ /* Clear EPXTRIGCRn */
+ out_be32(epu_base + EPXTRIGCR, 0);
+
+ /* Clear EPECRn */
+ for (offset = EPECR0; offset <= EPECR15; offset += EPECR_STRIDE)
+ out_be32(epu_base + offset, 0);
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.h b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.h
new file mode 100644
index 000000000..711eea565
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ */
+
+#ifndef __FSL_EPU_H
+#define __FSL_EPU_H
+
+#include <asm/types.h>
+
+#define FSL_STRIDE_4B 4
+#define FSL_STRIDE_8B 8
+
+/* Block offsets */
+#define EPU_BLOCK_OFFSET 0x00000000
+
+/* EPGCR (Event Processor Global Control Register) */
+#define EPGCR 0x000
+
+/* EPEVTCR0-9 (Event Processor EVT Pin Control Registers) */
+#define EPEVTCR0 0x050
+#define EPEVTCR9 0x074
+#define EPEVTCR_STRIDE FSL_STRIDE_4B
+
+/* EPXTRIGCR (Event Processor Crosstrigger Control Register) */
+#define EPXTRIGCR 0x090
+
+/* EPIMCR0-31 (Event Processor Input Mux Control Registers) */
+#define EPIMCR0 0x100
+#define EPIMCR31 0x17C
+#define EPIMCR_STRIDE FSL_STRIDE_4B
+
+/* EPSMCR0-15 (Event Processor SCU Mux Control Registers) */
+#define EPSMCR0 0x200
+#define EPSMCR15 0x278
+#define EPSMCR_STRIDE FSL_STRIDE_8B
+
+/* EPECR0-15 (Event Processor Event Control Registers) */
+#define EPECR0 0x300
+#define EPECR15 0x33C
+#define EPECR_STRIDE FSL_STRIDE_4B
+
+/* EPACR0-15 (Event Processor Action Control Registers) */
+#define EPACR0 0x400
+#define EPACR15 0x43C
+#define EPACR_STRIDE FSL_STRIDE_4B
+
+/* EPCCRi0-15 (Event Processor Counter Control Registers) */
+#define EPCCR0 0x800
+#define EPCCR15 0x83C
+#define EPCCR31 0x87C
+#define EPCCR_STRIDE FSL_STRIDE_4B
+
+/* EPCMPR0-15 (Event Processor Counter Compare Registers) */
+#define EPCMPR0 0x900
+#define EPCMPR15 0x93C
+#define EPCMPR31 0x97C
+#define EPCMPR_STRIDE FSL_STRIDE_4B
+
+/* EPCTR0-31 (Event Processor Counter Register) */
+#define EPCTR0 0xA00
+#define EPCTR31 0xA7C
+#define EPCTR_STRIDE FSL_STRIDE_4B
+
+#define FSM_END_FLAG 0xFFFFFFFFUL
+
+struct fsm_reg_vals {
+ u32 offset;
+ u32 value;
+};
+
+void fsl_epu_setup(void *epu_base);
+void fsl_epu_clean(void *epu_base);
+
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c
new file mode 100644
index 000000000..caf51e17b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/immap_ls102xa.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+#include "fsl_ls1_serdes.h"
+
+#ifdef CONFIG_SYS_FSL_SRDS_1
+static u64 serdes1_prtcl_map;
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+static u64 serdes2_prtcl_map;
+#endif
+
+int is_serdes_configured(enum srds_prtcl device)
+{
+ u64 ret = 0;
+
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ if (!(serdes1_prtcl_map & (1ULL << NONE)))
+ fsl_serdes_init();
+
+ ret |= (1ULL << device) & serdes1_prtcl_map;
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ if (!(serdes2_prtcl_map & (1ULL << NONE)))
+ fsl_serdes_init();
+
+ ret |= (1ULL << device) & serdes2_prtcl_map;
+#endif
+
+ return !!ret;
+}
+
+int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 cfg = in_be32(&gur->rcwsr[4]);
+ int i;
+
+ switch (sd) {
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ case FSL_SRDS_1:
+ cfg &= RCWSR4_SRDS1_PRTCL_MASK;
+ cfg >>= RCWSR4_SRDS1_PRTCL_SHIFT;
+ break;
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ case FSL_SRDS_2:
+ cfg &= RCWSR4_SRDS2_PRTCL_MASK;
+ cfg >>= RCWSR4_SRDS2_PRTCL_SHIFT;
+ break;
+#endif
+ default:
+ printf("invalid SerDes%d\n", sd);
+ break;
+ }
+ /* Is serdes enabled at all? */
+ if (unlikely(cfg == 0))
+ return -ENODEV;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (serdes_get_prtcl(sd, cfg, i) == device)
+ return i;
+ }
+
+ return -ENODEV;
+}
+
+u64 serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u64 serdes_prtcl_map = 0;
+ u32 cfg;
+ int lane;
+
+ cfg = in_be32(&gur->rcwsr[4]) & sd_prctl_mask;
+ cfg >>= sd_prctl_shift;
+ printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
+
+ if (!is_serdes_prtcl_valid(sd, cfg))
+ printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
+
+ for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
+ enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
+
+ serdes_prtcl_map |= (1ULL << lane_prtcl);
+ }
+
+ /* Set the first bit to indicate serdes has been initialized */
+ serdes_prtcl_map |= (1ULL << NONE);
+
+ return serdes_prtcl_map;
+}
+
+void fsl_serdes_init(void)
+{
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ if (!(serdes1_prtcl_map & (1ULL << NONE)))
+ serdes1_prtcl_map = serdes_init(FSL_SRDS_1,
+ CONFIG_SYS_FSL_SERDES_ADDR,
+ RCWSR4_SRDS1_PRTCL_MASK,
+ RCWSR4_SRDS1_PRTCL_SHIFT);
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ if (!(serdes2_prtcl_map & (1ULL << NONE)))
+ serdes2_prtcl_map = serdes_init(FSL_SRDS_2,
+ CONFIG_SYS_FSL_SERDES_ADDR +
+ FSL_SRDS_2 * 0x1000,
+ RCWSR4_SRDS2_PRTCL_MASK,
+ RCWSR4_SRDS2_PRTCL_SHIFT);
+#endif
+}
+
+const char *serdes_clock_to_string(u32 clock)
+{
+ switch (clock) {
+ case SRDS_PLLCR0_RFCK_SEL_100:
+ return "100";
+ case SRDS_PLLCR0_RFCK_SEL_125:
+ return "125";
+ default:
+ return "100";
+ }
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h
new file mode 100644
index 000000000..7382aef8e
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ */
+
+#ifndef __FSL_LS1_SERDES_H
+#define __FSL_LS1_SERDES_H
+
+int is_serdes_prtcl_valid(int serdes, u32 prtcl);
+int serdes_lane_enabled(int lane);
+#endif /* __FSL_LS1_SERDES_H */
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c
new file mode 100644
index 000000000..28a794520
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Author: Hongbo Zhang <hongbo.zhang@nxp.com>
+ * This file implements LS102X platform PSCI SYSTEM-SUSPEND function
+ */
+
+#include <config.h>
+#include <cpu_func.h>
+#include <asm/io.h>
+#include <asm/psci.h>
+#include <asm/arch/immap_ls102xa.h>
+#include <fsl_immap.h>
+#include "fsl_epu.h"
+
+#define __secure __section("._secure.text")
+
+#define CCSR_GICD_CTLR 0x1000
+#define CCSR_GICC_CTLR 0x2000
+#define DCSR_RCPM_CG1CR0 0x31c
+#define DCSR_RCPM_CSTTACR0 0xb00
+#define DCFG_CRSTSR_WDRFR 0x8
+#define DDR_RESV_LEN 128
+
+#ifdef CONFIG_LS1_DEEP_SLEEP
+/*
+ * DDR controller initialization training breaks the first 128 bytes of DDR,
+ * save them so that the bootloader can restore them while resuming.
+ */
+static void __secure ls1_save_ddr_head(void)
+{
+ const char *src = (const char *)CONFIG_SYS_SDRAM_BASE;
+ char *dest = (char *)(OCRAM_BASE_S_ADDR + OCRAM_S_SIZE - DDR_RESV_LEN);
+ struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
+ int i;
+
+ out_le32(&scfg->sparecr[2], dest);
+
+ for (i = 0; i < DDR_RESV_LEN; i++)
+ *dest++ = *src++;
+}
+
+static void __secure ls1_fsm_setup(void)
+{
+ void *dcsr_epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET);
+ void *dcsr_rcpm_base = (void *)SYS_FSL_DCSR_RCPM_ADDR;
+
+ out_be32(dcsr_rcpm_base + DCSR_RCPM_CSTTACR0, 0x00001001);
+ out_be32(dcsr_rcpm_base + DCSR_RCPM_CG1CR0, 0x00000001);
+
+ fsl_epu_setup((void *)dcsr_epu_base);
+
+ /* Pull MCKE signal low before enabling deep sleep signal in FPGA */
+ out_be32(dcsr_epu_base + EPECR0, 0x5);
+ out_be32(dcsr_epu_base + EPSMCR15, 0x76300000);
+}
+
+static void __secure ls1_deepsleep_irq_cfg(void)
+{
+ struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
+ struct ccsr_rcpm __iomem *rcpm = (void *)CONFIG_SYS_FSL_RCPM_ADDR;
+ u32 ippdexpcr0, ippdexpcr1, pmcintecr = 0;
+
+ /* Mask interrupts from GIC */
+ out_be32(&rcpm->nfiqoutr, 0x0ffffffff);
+ out_be32(&rcpm->nirqoutr, 0x0ffffffff);
+ /* Mask deep sleep wake-up interrupts while entering deep sleep */
+ out_be32(&rcpm->dsimskr, 0x0ffffffff);
+
+ ippdexpcr0 = in_be32(&rcpm->ippdexpcr0);
+ /*
+ * Workaround of errata A-008646
+ * Errata states that read to register ippdexpcr1 always returns
+ * zero irrespective of what value is written into it. So its value
+ * is first saved to a spare register and then read from it
+ */
+ ippdexpcr1 = in_be32(&scfg->sparecr[7]);
+
+ /*
+ * To allow OCRAM to be used as wakeup source in deep sleep,
+ * do not power it down.
+ */
+ out_be32(&rcpm->ippdexpcr1, ippdexpcr1 | RCPM_IPPDEXPCR1_OCRAM1);
+
+ if (ippdexpcr0 & RCPM_IPPDEXPCR0_ETSEC)
+ pmcintecr |= SCFG_PMCINTECR_ETSECRXG0 |
+ SCFG_PMCINTECR_ETSECRXG1 |
+ SCFG_PMCINTECR_ETSECERRG0 |
+ SCFG_PMCINTECR_ETSECERRG1;
+
+ if (ippdexpcr0 & RCPM_IPPDEXPCR0_GPIO)
+ pmcintecr |= SCFG_PMCINTECR_GPIO;
+
+ if (ippdexpcr1 & RCPM_IPPDEXPCR1_LPUART)
+ pmcintecr |= SCFG_PMCINTECR_LPUART;
+
+ if (ippdexpcr1 & RCPM_IPPDEXPCR1_FLEXTIMER)
+ pmcintecr |= SCFG_PMCINTECR_FTM;
+
+ /* Always set external IRQ pins as wakeup source */
+ pmcintecr |= SCFG_PMCINTECR_IRQ0 | SCFG_PMCINTECR_IRQ1;
+
+ out_be32(&scfg->pmcintlecr, 0);
+ /* Clear PMC interrupt status */
+ out_be32(&scfg->pmcintsr, 0xffffffff);
+ /* Enable wakeup interrupt during deep sleep */
+ out_be32(&scfg->pmcintecr, pmcintecr);
+}
+
+static void __secure ls1_delay(unsigned int loop)
+{
+ while (loop--) {
+ int i = 1000;
+ while (i--)
+ ;
+ }
+}
+
+static void __secure ls1_start_fsm(void)
+{
+ void *dcsr_epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET);
+ void *ccsr_gic_base = (void *)SYS_FSL_GIC_ADDR;
+ struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
+ struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+
+ /* Set HRSTCR */
+ setbits_be32(&scfg->hrstcr, 0x80000000);
+
+ /* Place DDR controller in self refresh mode */
+ setbits_be32(&ddr->sdram_cfg_2, 0x80000000);
+
+ ls1_delay(2000);
+
+ /* Set EVT4_B to lock the signal MCKE down */
+ out_be32(dcsr_epu_base + EPECR0, 0x0);
+
+ ls1_delay(2000);
+
+ out_be32(ccsr_gic_base + CCSR_GICD_CTLR, 0x0);
+ out_be32(ccsr_gic_base + CCSR_GICC_CTLR, 0x0);
+
+ /* Enable all EPU Counters */
+ setbits_be32(dcsr_epu_base + EPGCR, 0x80000000);
+
+ /* Enable SCU15 */
+ setbits_be32(dcsr_epu_base + EPECR15, 0x90000004);
+
+ /* Enter WFI mode, and EPU FSM will start */
+ __asm__ __volatile__ ("wfi" : : : "memory");
+
+ /* NEVER ENTER HERE */
+ while (1)
+ ;
+}
+
+static void __secure ls1_deep_sleep(u32 entry_point)
+{
+ struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+ struct ccsr_rcpm __iomem *rcpm = (void *)CONFIG_SYS_FSL_RCPM_ADDR;
+#ifdef QIXIS_BASE
+ u32 tmp;
+ void *qixis_base = (void *)QIXIS_BASE;
+#endif
+
+ /* Enable cluster to enter the PCL10 state */
+ out_be32(&scfg->clusterpmcr, SCFG_CLUSTERPMCR_WFIL2EN);
+
+ /* Save the first 128 bytes of DDR data */
+ ls1_save_ddr_head();
+
+ /* Save the kernel resume entry */
+ out_le32(&scfg->sparecr[3], entry_point);
+
+ /* Request to put cluster 0 in PCL10 state */
+ setbits_be32(&rcpm->clpcl10setr, RCPM_CLPCL10SETR_C0);
+
+ /* Setup the registers of the EPU FSM for deep sleep */
+ ls1_fsm_setup();
+
+#ifdef QIXIS_BASE
+ /* Connect the EVENT button to IRQ in FPGA */
+ tmp = in_8(qixis_base + QIXIS_CTL_SYS);
+ tmp &= ~QIXIS_CTL_SYS_EVTSW_MASK;
+ tmp |= QIXIS_CTL_SYS_EVTSW_IRQ;
+ out_8(qixis_base + QIXIS_CTL_SYS, tmp);
+
+ /* Enable deep sleep signals in FPGA */
+ tmp = in_8(qixis_base + QIXIS_PWR_CTL2);
+ tmp |= QIXIS_PWR_CTL2_PCTL;
+ out_8(qixis_base + QIXIS_PWR_CTL2, tmp);
+
+ /* Pull down PCIe RST# */
+ tmp = in_8(qixis_base + QIXIS_RST_FORCE_3);
+ tmp |= QIXIS_RST_FORCE_3_PCIESLOT1;
+ out_8(qixis_base + QIXIS_RST_FORCE_3, tmp);
+#endif
+
+ /* Enable Warm Device Reset */
+ setbits_be32(&scfg->dpslpcr, SCFG_DPSLPCR_WDRR_EN);
+ setbits_be32(&gur->crstsr, DCFG_CRSTSR_WDRFR);
+
+ /* Disable QE */
+ setbits_be32(&gur->devdisr, CCSR_DEVDISR1_QE);
+
+ ls1_deepsleep_irq_cfg();
+
+ psci_v7_flush_dcache_all();
+
+ ls1_start_fsm();
+}
+
+#else
+static void __secure ls1_sleep(void)
+{
+ struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
+ struct ccsr_rcpm __iomem *rcpm = (void *)CONFIG_SYS_FSL_RCPM_ADDR;
+
+#ifdef QIXIS_BASE
+ u32 tmp;
+ void *qixis_base = (void *)QIXIS_BASE;
+
+ /* Connect the EVENT button to IRQ in FPGA */
+ tmp = in_8(qixis_base + QIXIS_CTL_SYS);
+ tmp &= ~QIXIS_CTL_SYS_EVTSW_MASK;
+ tmp |= QIXIS_CTL_SYS_EVTSW_IRQ;
+ out_8(qixis_base + QIXIS_CTL_SYS, tmp);
+#endif
+
+ /* Enable cluster to enter the PCL10 state */
+ out_be32(&scfg->clusterpmcr, SCFG_CLUSTERPMCR_WFIL2EN);
+
+ setbits_be32(&rcpm->powmgtcsr, RCPM_POWMGTCSR_LPM20_REQ);
+
+ __asm__ __volatile__ ("wfi" : : : "memory");
+}
+#endif
+
+void __secure ls1_system_suspend(u32 fn, u32 entry_point, u32 context_id)
+{
+#ifdef CONFIG_LS1_DEEP_SLEEP
+ ls1_deep_sleep(entry_point);
+#else
+ ls1_sleep();
+#endif
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c
new file mode 100644
index 000000000..8c030be8b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/immap_ls102xa.h>
+
+static u8 serdes_cfg_tbl[][SRDS_MAX_LANES] = {
+ [0x00] = {PCIE1, PCIE1, PCIE1, PCIE1},
+ [0x10] = {PCIE1, SATA1, PCIE2, PCIE2},
+ [0x20] = {PCIE1, SGMII_TSEC1, PCIE2, SGMII_TSEC2},
+ [0x30] = {PCIE1, SATA1, SGMII_TSEC1, SGMII_TSEC2},
+ [0x40] = {PCIE1, PCIE1, SATA1, SGMII_TSEC2},
+ [0x50] = {PCIE1, PCIE1, PCIE2, SGMII_TSEC2},
+ [0x60] = {PCIE1, PCIE1, SGMII_TSEC1, SGMII_TSEC2},
+ [0x70] = {PCIE1, SATA1, PCIE2, SGMII_TSEC2},
+ [0x80] = {PCIE2, PCIE2, PCIE2, PCIE2},
+};
+
+enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
+{
+ return serdes_cfg_tbl[cfg][lane];
+}
+
+int is_serdes_prtcl_valid(int serdes, u32 prtcl)
+{
+ int i;
+
+ if (prtcl >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (serdes_cfg_tbl[prtcl][i] != NONE)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/psci.S b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/psci.S
new file mode 100644
index 000000000..531cfb033
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/psci.S
@@ -0,0 +1,257 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ * Author: Wang Dongsheng <dongsheng.wang@freescale.com>
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+
+#include <asm/armv7.h>
+#include <asm/arch-armv7/generictimer.h>
+#include <asm/psci.h>
+
+#define RCPM_TWAITSR 0x04C
+
+#define SCFG_CORE0_SFT_RST 0x130
+#define SCFG_CORESRENCR 0x204
+
+#define DCFG_CCSR_RSTCR 0x0B0
+#define DCFG_CCSR_RSTCR_RESET_REQ 0x2
+#define DCFG_CCSR_BRR 0x0E4
+#define DCFG_CCSR_SCRATCHRW1 0x200
+
+#define PSCI_FN_PSCI_VERSION_FEATURE_MASK 0x0
+#define PSCI_FN_CPU_SUSPEND_FEATURE_MASK 0x0
+#define PSCI_FN_CPU_OFF_FEATURE_MASK 0x0
+#define PSCI_FN_CPU_ON_FEATURE_MASK 0x0
+#define PSCI_FN_AFFINITY_INFO_FEATURE_MASK 0x0
+#define PSCI_FN_SYSTEM_OFF_FEATURE_MASK 0x0
+#define PSCI_FN_SYSTEM_RESET_FEATURE_MASK 0x0
+#define PSCI_FN_SYSTEM_SUSPEND_FEATURE_MASK 0x0
+
+ .pushsection ._secure.text, "ax"
+
+ .arch_extension sec
+
+ .align 5
+
+#define ONE_MS (COUNTER_FREQUENCY / 1000)
+#define RESET_WAIT (30 * ONE_MS)
+
+.globl psci_version
+psci_version:
+ movw r0, #0
+ movt r0, #1
+
+ bx lr
+
+_ls102x_psci_supported_table:
+ .word ARM_PSCI_0_2_FN_PSCI_VERSION
+ .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_CPU_SUSPEND
+ .word PSCI_FN_CPU_SUSPEND_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_CPU_OFF
+ .word PSCI_FN_CPU_OFF_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_CPU_ON
+ .word PSCI_FN_CPU_ON_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_AFFINITY_INFO
+ .word PSCI_FN_AFFINITY_INFO_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_SYSTEM_OFF
+ .word PSCI_FN_SYSTEM_OFF_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_SYSTEM_RESET
+ .word PSCI_FN_SYSTEM_RESET_FEATURE_MASK
+ .word ARM_PSCI_1_0_FN_SYSTEM_SUSPEND
+ .word PSCI_FN_SYSTEM_SUSPEND_FEATURE_MASK
+ .word 0
+ .word ARM_PSCI_RET_NI
+
+.globl psci_features
+psci_features:
+ adr r2, _ls102x_psci_supported_table
+1: ldr r3, [r2]
+ cmp r3, #0
+ beq out_psci_features
+ cmp r1, r3
+ addne r2, r2, #8
+ bne 1b
+
+out_psci_features:
+ ldr r0, [r2, #4]
+ bx lr
+
+@ r0: return value ARM_PSCI_RET_SUCCESS or ARM_PSCI_RET_INVAL
+@ r1: input target CPU ID in MPIDR format, original value in r1 may be dropped
+@ r4: output validated CPU ID if ARM_PSCI_RET_SUCCESS returns, meaningless for
+@ ARM_PSCI_RET_INVAL,suppose caller saves r4 before calling
+LENTRY(psci_check_target_cpu_id)
+ @ Get the real CPU number
+ and r4, r1, #0xff
+ mov r0, #ARM_PSCI_RET_INVAL
+
+ @ Bit[31:24], bits must be zero.
+ tst r1, #0xff000000
+ bxne lr
+
+ @ Affinity level 2 - Cluster: only one cluster in LS1021xa.
+ tst r1, #0xff0000
+ bxne lr
+
+ @ Affinity level 1 - Processors: should be in 0xf00 format.
+ lsr r1, r1, #8
+ teq r1, #0xf
+ bxne lr
+
+ @ Affinity level 0 - CPU: only 0, 1 are valid in LS1021xa.
+ cmp r4, #2
+ bxge lr
+
+ mov r0, #ARM_PSCI_RET_SUCCESS
+ bx lr
+ENDPROC(psci_check_target_cpu_id)
+
+ @ r1 = target CPU
+ @ r2 = target PC
+.globl psci_cpu_on
+psci_cpu_on:
+ push {r4, r5, r6, lr}
+
+ @ Clear and Get the correct CPU number
+ @ r1 = 0xf01
+ bl psci_check_target_cpu_id
+ cmp r0, #ARM_PSCI_RET_INVAL
+ beq out_psci_cpu_on
+
+ mov r0, r4
+ mov r1, r2
+ mov r2, r3
+ bl psci_save
+ mov r1, r4
+
+ @ Get DCFG base address
+ movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
+ movt r4, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16)
+
+ @ Detect target CPU state
+ ldr r2, [r4, #DCFG_CCSR_BRR]
+ rev r2, r2
+ lsr r2, r2, r1
+ ands r2, r2, #1
+ beq holdoff_release
+
+ @ Reset target CPU
+ @ Get SCFG base address
+ movw r0, #(CONFIG_SYS_FSL_SCFG_ADDR & 0xffff)
+ movt r0, #(CONFIG_SYS_FSL_SCFG_ADDR >> 16)
+
+ @ Enable CORE Soft Reset
+ movw r5, #0
+ movt r5, #(1 << 15)
+ rev r5, r5
+ str r5, [r0, #SCFG_CORESRENCR]
+
+ @ Get CPUx offset register
+ mov r6, #0x4
+ mul r6, r6, r1
+ add r2, r0, r6
+
+ @ Do reset on target CPU
+ movw r5, #0
+ movt r5, #(1 << 15)
+ rev r5, r5
+ str r5, [r2, #SCFG_CORE0_SFT_RST]
+
+ @ Wait target CPU up
+ timer_wait r2, RESET_WAIT
+
+ @ Disable CORE soft reset
+ mov r5, #0
+ str r5, [r0, #SCFG_CORESRENCR]
+
+holdoff_release:
+ @ Release on target CPU
+ ldr r2, [r4, #DCFG_CCSR_BRR]
+ mov r6, #1
+ lsl r6, r6, r1 @ 32 bytes per CPU
+
+ rev r6, r6
+ orr r2, r2, r6
+ str r2, [r4, #DCFG_CCSR_BRR]
+
+ @ Set secondary boot entry
+ ldr r6, =psci_cpu_entry
+ rev r6, r6
+ str r6, [r4, #DCFG_CCSR_SCRATCHRW1]
+
+ isb
+ dsb
+
+ @ Return
+ mov r0, #ARM_PSCI_RET_SUCCESS
+
+out_psci_cpu_on:
+ pop {r4, r5, r6, lr}
+ bx lr
+
+.globl psci_cpu_off
+psci_cpu_off:
+ bl psci_cpu_off_common
+
+1: wfi
+ b 1b
+
+.globl psci_affinity_info
+psci_affinity_info:
+ push {lr}
+
+ mov r0, #ARM_PSCI_RET_INVAL
+
+ @ Verify Affinity level
+ cmp r2, #0
+ bne out_affinity_info
+
+ bl psci_check_target_cpu_id
+ cmp r0, #ARM_PSCI_RET_INVAL
+ beq out_affinity_info
+ mov r1, r4
+
+ @ Get RCPM base address
+ movw r4, #(CONFIG_SYS_FSL_RCPM_ADDR & 0xffff)
+ movt r4, #(CONFIG_SYS_FSL_RCPM_ADDR >> 16)
+
+ mov r0, #PSCI_AFFINITY_LEVEL_ON
+
+ @ Detect target CPU state
+ ldr r2, [r4, #RCPM_TWAITSR]
+ rev r2, r2
+ lsr r2, r2, r1
+ ands r2, r2, #1
+ beq out_affinity_info
+
+ mov r0, #PSCI_AFFINITY_LEVEL_OFF
+
+out_affinity_info:
+ pop {pc}
+
+.globl psci_system_reset
+psci_system_reset:
+ @ Get DCFG base address
+ movw r1, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
+ movt r1, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16)
+
+ mov r2, #DCFG_CCSR_RSTCR_RESET_REQ
+ rev r2, r2
+ str r2, [r1, #DCFG_CCSR_RSTCR]
+
+1: wfi
+ b 1b
+
+.globl psci_system_suspend
+psci_system_suspend:
+ push {lr}
+
+ bl ls1_system_suspend
+
+ pop {pc}
+
+ .popsection
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/soc.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/soc.c
new file mode 100644
index 000000000..8a95ee86a
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/soc.c
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <log.h>
+#include <asm/arch/clock.h>
+#include <asm/io.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/immap_ls102xa.h>
+#include <asm/arch/ls102xa_soc.h>
+#include <asm/arch/ls102xa_stream_id.h>
+#include <fsl_csu.h>
+#include <fsl_ddr_sdram.h>
+
+struct liodn_id_table sec_liodn_tbl[] = {
+ SET_SEC_JR_LIODN_ENTRY(0, 0x10, 0x10),
+ SET_SEC_JR_LIODN_ENTRY(1, 0x10, 0x10),
+ SET_SEC_JR_LIODN_ENTRY(2, 0x10, 0x10),
+ SET_SEC_JR_LIODN_ENTRY(3, 0x10, 0x10),
+ SET_SEC_RTIC_LIODN_ENTRY(a, 0x10),
+ SET_SEC_RTIC_LIODN_ENTRY(b, 0x10),
+ SET_SEC_RTIC_LIODN_ENTRY(c, 0x10),
+ SET_SEC_RTIC_LIODN_ENTRY(d, 0x10),
+ SET_SEC_DECO_LIODN_ENTRY(0, 0x10, 0x10),
+ SET_SEC_DECO_LIODN_ENTRY(1, 0x10, 0x10),
+ SET_SEC_DECO_LIODN_ENTRY(2, 0x10, 0x10),
+ SET_SEC_DECO_LIODN_ENTRY(3, 0x10, 0x10),
+ SET_SEC_DECO_LIODN_ENTRY(4, 0x10, 0x10),
+ SET_SEC_DECO_LIODN_ENTRY(5, 0x10, 0x10),
+ SET_SEC_DECO_LIODN_ENTRY(6, 0x10, 0x10),
+ SET_SEC_DECO_LIODN_ENTRY(7, 0x10, 0x10),
+};
+
+struct smmu_stream_id dev_stream_id[] = {
+ { 0x100, 0x01, "ETSEC MAC1" },
+ { 0x104, 0x02, "ETSEC MAC2" },
+ { 0x108, 0x03, "ETSEC MAC3" },
+ { 0x10c, 0x04, "PEX1" },
+ { 0x110, 0x05, "PEX2" },
+ { 0x114, 0x06, "qDMA" },
+ { 0x118, 0x07, "SATA" },
+ { 0x11c, 0x08, "USB3" },
+ { 0x120, 0x09, "QE" },
+ { 0x124, 0x0a, "eSDHC" },
+ { 0x128, 0x0b, "eMA" },
+ { 0x14c, 0x0c, "2D-ACE" },
+ { 0x150, 0x0d, "USB2" },
+ { 0x18c, 0x0e, "DEBUG" },
+};
+
+unsigned int get_soc_major_rev(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ unsigned int svr, major;
+
+ svr = in_be32(&gur->svr);
+ major = SVR_MAJ(svr);
+
+ return major;
+}
+
+static void erratum_a009008(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009008
+ u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
+
+ clrsetbits_be32(scfg + SCFG_USB3PRM1CR / 4,
+ 0xF << 6,
+ SCFG_USB_TXVREFTUNE << 6);
+#endif /* CONFIG_SYS_FSL_ERRATUM_A009008 */
+}
+
+static void erratum_a009798(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009798
+ u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
+
+ clrbits_be32(scfg + SCFG_USB3PRM1CR / 4,
+ SCFG_USB_SQRXTUNE_MASK << 23);
+#endif /* CONFIG_SYS_FSL_ERRATUM_A009798 */
+}
+
+static void erratum_a008997(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008997
+ u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
+
+ clrsetbits_be32(scfg + SCFG_USB3PRM2CR / 4,
+ SCFG_USB_PCSTXSWINGFULL_MASK,
+ SCFG_USB_PCSTXSWINGFULL_VAL);
+#endif /* CONFIG_SYS_FSL_ERRATUM_A008997 */
+}
+
+static void erratum_a009007(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009007
+ void __iomem *usb_phy = (void __iomem *)USB_PHY_BASE;
+
+ out_le16(usb_phy + USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_1);
+ out_le16(usb_phy + USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_2);
+ out_le16(usb_phy + USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_3);
+ out_le16(usb_phy + USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_4);
+#endif /* CONFIG_SYS_FSL_ERRATUM_A009007 */
+}
+
+static void erratum_a008850_early(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008850
+ /* part 1 of 2 */
+ struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR +
+ CONFIG_SYS_CCI400_OFFSET);
+ struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+
+ /* disables propagation of barrier transactions to DDRC from CCI400 */
+ out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
+
+ /* disable the re-ordering in DDRC */
+ out_be32(&ddr->eor, DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS);
+#endif
+}
+
+void erratum_a008850_post(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008850
+ /* part 2 of 2 */
+ struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR +
+ CONFIG_SYS_CCI400_OFFSET);
+ struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+ u32 tmp;
+
+ /* enable propagation of barrier transactions to DDRC from CCI400 */
+ out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
+
+ /* enable the re-ordering in DDRC */
+ tmp = in_be32(&ddr->eor);
+ tmp &= ~(DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS);
+ out_be32(&ddr->eor, tmp);
+#endif
+}
+
+void s_init(void)
+{
+}
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_A010315
+void erratum_a010315(void)
+{
+ int i;
+
+ for (i = PCIE1; i <= PCIE2; i++)
+ if (!is_serdes_configured(i)) {
+ debug("PCIe%d: disabled all R/W permission!\n", i);
+ set_pcie_ns_access(i, 0);
+ }
+}
+#endif
+
+int arch_soc_init(void)
+{
+ struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
+ struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR +
+ CONFIG_SYS_CCI400_OFFSET);
+ unsigned int major;
+
+#ifdef CONFIG_LAYERSCAPE_NS_ACCESS
+ enable_layerscape_ns_access();
+#endif
+
+#ifdef CONFIG_FSL_QSPI
+ out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
+#endif
+
+#ifdef CONFIG_VIDEO_FSL_DCU_FB
+ out_be32(&scfg->pixclkcr, SCFG_PIXCLKCR_PXCKEN);
+#endif
+
+ /* Configure Little endian for SAI, ASRC and SPDIF */
+ out_be32(&scfg->endiancr, SCFG_ENDIANCR_LE);
+
+ /*
+ * Enable snoop requests and DVM message requests for
+ * All the slave insterfaces.
+ */
+ out_le32(&cci->slave[0].snoop_ctrl,
+ CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
+ out_le32(&cci->slave[1].snoop_ctrl,
+ CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
+ out_le32(&cci->slave[2].snoop_ctrl,
+ CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
+ out_le32(&cci->slave[4].snoop_ctrl,
+ CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
+
+ major = get_soc_major_rev();
+ if (major == SOC_MAJOR_VER_1_0) {
+ /*
+ * Set CCI-400 Slave interface S1, S2 Shareable Override
+ * Register All transactions are treated as non-shareable
+ */
+ out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
+ out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
+ }
+
+ /* Enable all the snoop signal for various masters */
+ out_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SEC_RD_WR |
+ SCFG_SNPCNFGCR_DCU_RD_WR |
+ SCFG_SNPCNFGCR_SATA_RD_WR |
+ SCFG_SNPCNFGCR_USB3_RD_WR |
+ SCFG_SNPCNFGCR_DBG_RD_WR |
+ SCFG_SNPCNFGCR_EDMA_SNP);
+
+ /*
+ * Memory controller require a register write before being enabled.
+ * Affects: DDR
+ * Register: EDDRTQCFG
+ * Description: Memory controller performance is not optimal with
+ * default internal target queue register values.
+ * Workaround: Write a value of 63b2_0042h to address: 157_020Ch.
+ */
+ out_be32(&scfg->eddrtqcfg, 0x63b20042);
+
+ /* Erratum */
+ erratum_a008850_early();
+ erratum_a009008();
+ erratum_a009798();
+ erratum_a008997();
+ erratum_a009007();
+
+ return 0;
+}
+
+int ls102xa_smmu_stream_id_init(void)
+{
+ ls1021x_config_caam_stream_id(sec_liodn_tbl,
+ ARRAY_SIZE(sec_liodn_tbl));
+
+ ls102xa_config_smmu_stream_id(dev_stream_id,
+ ARRAY_SIZE(dev_stream_id));
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/spl.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/spl.c
new file mode 100644
index 000000000..308536c33
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/spl.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <spl.h>
+
+u32 spl_boot_device(void)
+{
+#ifdef CONFIG_SPL_MMC_SUPPORT
+ return BOOT_DEVICE_MMC1;
+#endif
+ return BOOT_DEVICE_NAND;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/timer.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/timer.c
new file mode 100644
index 000000000..d79bf105f
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/timer.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <div64.h>
+#include <asm/arch/immap_ls102xa.h>
+#include <asm/arch/clock.h>
+#include <linux/delay.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * This function is intended for SHORT delays only.
+ * It will overflow at around 10 seconds @ 400MHz,
+ * or 20 seconds @ 200MHz.
+ */
+unsigned long usec2ticks(unsigned long usec)
+{
+ ulong ticks;
+
+ if (usec < 1000)
+ ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000;
+ else
+ ticks = ((usec / 10) * (get_tbclk() / 100000));
+
+ return ticks;
+}
+
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ unsigned long freq;
+
+ asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq));
+
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, freq);
+
+ return tick;
+}
+
+static inline unsigned long long us_to_tick(unsigned long long usec)
+{
+ unsigned long freq;
+
+ asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq));
+
+ usec = usec * freq + 999999;
+ do_div(usec, 1000000);
+
+ return usec;
+}
+
+int timer_init(void)
+{
+ struct sctr_regs *sctr = (struct sctr_regs *)SCTR_BASE_ADDR;
+ unsigned long ctrl, freq;
+ unsigned long long val;
+
+ /* Enable System Counter */
+ writel(SYS_COUNTER_CTRL_ENABLE, &sctr->cntcr);
+
+ freq = COUNTER_FREQUENCY;
+ asm("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
+
+ /* Set PL1 Physical Timer Ctrl */
+ ctrl = ARCH_TIMER_CTRL_ENABLE;
+ asm("mcr p15, 0, %0, c14, c2, 1" : : "r" (ctrl));
+
+ /* Set PL1 Physical Comp Value */
+ val = TIMER_COMP_VAL;
+ asm("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val));
+
+ gd->arch.tbl = 0;
+ gd->arch.tbu = 0;
+
+ return 0;
+}
+
+unsigned long long get_ticks(void)
+{
+ unsigned long long now;
+
+ asm("mrrc p15, 0, %Q0, %R0, c14" : "=r" (now));
+
+ gd->arch.tbl = (unsigned long)(now & 0xffffffff);
+ gd->arch.tbu = (unsigned long)(now >> 32);
+
+ return now;
+}
+
+unsigned long get_timer(ulong base)
+{
+ return tick_to_time(get_ticks()) - base;
+}
+
+/* delay x useconds and preserve advance timstamp value */
+void __udelay(unsigned long usec)
+{
+ unsigned long long start;
+ unsigned long tmo;
+
+ start = get_ticks(); /* get current timestamp */
+ tmo = us_to_tick(usec); /* convert usecs to ticks */
+
+ while ((get_ticks() - start) < tmo)
+ ; /* loop till time has passed */
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+unsigned long get_tbclk(void)
+{
+ unsigned long freq;
+
+ asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq));
+
+ return freq;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/mpu_v7r.c b/roms/u-boot/arch/arm/cpu/armv7/mpu_v7r.c
new file mode 100644
index 000000000..57ab640e2
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/mpu_v7r.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Cortex-R Memory Protection Unit specific code
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Lokesh Vutla <lokeshvutla@ti.com>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <asm/armv7.h>
+#include <asm/system.h>
+#include <asm/barriers.h>
+#include <linux/bitops.h>
+#include <linux/compiler.h>
+
+#include <asm/armv7_mpu.h>
+
+/* MPU Type register definitions */
+#define MPUIR_S_SHIFT 0
+#define MPUIR_S_MASK BIT(MPUIR_S_SHIFT)
+#define MPUIR_DREGION_SHIFT 8
+#define MPUIR_DREGION_MASK (0xff << 8)
+
+/**
+ * Note:
+ * The Memory Protection Unit(MPU) allows to partition memory into regions
+ * and set individual protection attributes for each region. In absence
+ * of MPU a default map[1] will take effect. make sure to run this code
+ * from a region which has execution permissions by default.
+ * [1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0460d/I1002400.html
+ */
+
+void disable_mpu(void)
+{
+ u32 reg;
+
+ reg = get_cr();
+ reg &= ~CR_M;
+ dsb();
+ set_cr(reg);
+ isb();
+}
+
+void enable_mpu(void)
+{
+ u32 reg;
+
+ reg = get_cr();
+ reg |= CR_M;
+ dsb();
+ set_cr(reg);
+ isb();
+}
+
+int mpu_enabled(void)
+{
+ return get_cr() & CR_M;
+}
+
+void mpu_config(struct mpu_region_config *rgn)
+{
+ u32 attr, val;
+
+ attr = get_attr_encoding(rgn->mr_attr);
+
+ /* MPU Region Number Register */
+ asm volatile ("mcr p15, 0, %0, c6, c2, 0" : : "r" (rgn->region_no));
+
+ /* MPU Region Base Address Register */
+ asm volatile ("mcr p15, 0, %0, c6, c1, 0" : : "r" (rgn->start_addr));
+
+ /* MPU Region Size and Enable Register */
+ if (rgn->reg_size)
+ val = (rgn->reg_size << REGION_SIZE_SHIFT) | ENABLE_REGION;
+ else
+ val = DISABLE_REGION;
+ asm volatile ("mcr p15, 0, %0, c6, c1, 2" : : "r" (val));
+
+ /* MPU Region Access Control Register */
+ val = rgn->xn << XN_SHIFT | rgn->ap << AP_SHIFT | attr;
+ asm volatile ("mcr p15, 0, %0, c6, c1, 4" : : "r" (val));
+}
+
+void setup_mpu_regions(struct mpu_region_config *rgns, u32 num_rgns)
+{
+ u32 num, i;
+
+ asm volatile ("mrc p15, 0, %0, c0, c0, 4" : "=r" (num));
+ num = (num & MPUIR_DREGION_MASK) >> MPUIR_DREGION_SHIFT;
+ /* Regions to be configured cannot be greater than available regions */
+ if (num < num_rgns)
+ num_rgns = num;
+ /**
+ * Assuming dcache might not be enabled at this point, disabling
+ * and invalidating only icache.
+ */
+ icache_disable();
+ invalidate_icache_all();
+
+ disable_mpu();
+
+ for (i = 0; i < num_rgns; i++)
+ mpu_config(&rgns[i]);
+
+ enable_mpu();
+
+ icache_enable();
+}
+
+void enable_caches(void)
+{
+ /*
+ * setup_mpu_regions() might have enabled Icache. So add a check
+ * before enabling Icache
+ */
+ if (!icache_status())
+ icache_enable();
+ dcache_enable();
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/nonsec_virt.S b/roms/u-boot/arch/arm/cpu/armv7/nonsec_virt.S
new file mode 100644
index 000000000..1773fae20
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/nonsec_virt.S
@@ -0,0 +1,225 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * code for switching cores into non-secure state and into HYP mode
+ *
+ * Copyright (c) 2013 Andre Przywara <andre.przywara@linaro.org>
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/gic.h>
+#include <asm/armv7.h>
+#include <asm/proc-armv/ptrace.h>
+
+.arch_extension sec
+.arch_extension virt
+
+ .pushsection ._secure.text, "ax"
+
+ .align 5
+/* the vector table for secure state and HYP mode */
+_monitor_vectors:
+ .word 0 /* reset */
+ .word 0 /* undef */
+ adr pc, _secure_monitor
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+
+.macro is_cpu_virt_capable tmp
+ mrc p15, 0, \tmp, c0, c1, 1 @ read ID_PFR1
+ and \tmp, \tmp, #CPUID_ARM_VIRT_MASK @ mask virtualization bits
+ cmp \tmp, #(1 << CPUID_ARM_VIRT_SHIFT)
+.endm
+
+/*
+ * secure monitor handler
+ * U-Boot calls this "software interrupt" in start.S
+ * This is executed on a "smc" instruction, we use a "smc #0" to switch
+ * to non-secure state.
+ * r0, r1, r2: passed to the callee
+ * ip: target PC
+ */
+_secure_monitor:
+#ifdef CONFIG_ARMV7_PSCI
+ ldr r5, =_psci_vectors @ Switch to the next monitor
+ mcr p15, 0, r5, c12, c0, 1
+ isb
+
+ @ Obtain a secure stack
+ bl psci_stack_setup
+
+ @ Configure the PSCI backend
+ push {r0, r1, r2, ip}
+ bl psci_arch_init
+ pop {r0, r1, r2, ip}
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_773022
+ mrc p15, 0, r5, c1, c0, 1
+ orr r5, r5, #(1 << 1)
+ mcr p15, 0, r5, c1, c0, 1
+ isb
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_774769
+ mrc p15, 0, r5, c1, c0, 1
+ orr r5, r5, #(1 << 25)
+ mcr p15, 0, r5, c1, c0, 1
+ isb
+#endif
+
+ mrc p15, 0, r5, c1, c1, 0 @ read SCR
+ bic r5, r5, #0x4a @ clear IRQ, EA, nET bits
+ orr r5, r5, #0x31 @ enable NS, AW, FW bits
+ @ FIQ preserved for secure mode
+ mov r6, #SVC_MODE @ default mode is SVC
+ is_cpu_virt_capable r4
+#ifdef CONFIG_ARMV7_VIRT
+ orreq r5, r5, #0x100 @ allow HVC instruction
+ moveq r6, #HYP_MODE @ Enter the kernel as HYP
+ mrseq r3, sp_svc
+ msreq sp_hyp, r3 @ migrate SP
+#endif
+
+ mcr p15, 0, r5, c1, c1, 0 @ write SCR (with NS bit set)
+ isb
+
+ bne 1f
+
+ @ Reset CNTVOFF to 0 before leaving monitor mode
+ mrc p15, 0, r4, c0, c1, 1 @ read ID_PFR1
+ ands r4, r4, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits
+ movne r4, #0
+ mcrrne p15, 4, r4, r4, c14 @ Reset CNTVOFF to zero
+1:
+ mov lr, ip
+ mov ip, #(F_BIT | I_BIT | A_BIT) @ Set A, I and F
+ tst lr, #1 @ Check for Thumb PC
+ orrne ip, ip, #T_BIT @ Set T if Thumb
+ orr ip, ip, r6 @ Slot target mode in
+ msr spsr_cxfs, ip @ Set full SPSR
+ movs pc, lr @ ERET to non-secure
+
+ENTRY(_do_nonsec_entry)
+ mov ip, r0
+ mov r0, r1
+ mov r1, r2
+ mov r2, r3
+ smc #0
+ENDPROC(_do_nonsec_entry)
+
+.macro get_cbar_addr addr
+#ifdef CONFIG_ARM_GIC_BASE_ADDRESS
+ ldr \addr, =CONFIG_ARM_GIC_BASE_ADDRESS
+#else
+ mrc p15, 4, \addr, c15, c0, 0 @ read CBAR
+ bfc \addr, #0, #15 @ clear reserved bits
+#endif
+.endm
+
+.macro get_gicd_addr addr
+ get_cbar_addr \addr
+ add \addr, \addr, #GIC_DIST_OFFSET @ GIC dist i/f offset
+.endm
+
+.macro get_gicc_addr addr, tmp
+ get_cbar_addr \addr
+ is_cpu_virt_capable \tmp
+ movne \tmp, #GIC_CPU_OFFSET_A9 @ GIC CPU offset for A9
+ moveq \tmp, #GIC_CPU_OFFSET_A15 @ GIC CPU offset for A15/A7
+ add \addr, \addr, \tmp
+.endm
+
+#ifndef CONFIG_ARMV7_PSCI
+/*
+ * Secondary CPUs start here and call the code for the core specific parts
+ * of the non-secure and HYP mode transition. The GIC distributor specific
+ * code has already been executed by a C function before.
+ * Then they go back to wfi and wait to be woken up by the kernel again.
+ */
+ENTRY(_smp_pen)
+ cpsid i
+ cpsid f
+
+ bl _nonsec_init
+
+ adr r0, _smp_pen @ do not use this address again
+ b smp_waitloop @ wait for IPIs, board specific
+ENDPROC(_smp_pen)
+#endif
+
+/*
+ * Switch a core to non-secure state.
+ *
+ * 1. initialize the GIC per-core interface
+ * 2. allow coprocessor access in non-secure modes
+ *
+ * Called from smp_pen by secondary cores and directly by the BSP.
+ * Do not assume that the stack is available and only use registers
+ * r0-r3 and r12.
+ *
+ * PERIPHBASE is used to get the GIC address. This could be 40 bits long,
+ * though, but we check this in C before calling this function.
+ */
+ENTRY(_nonsec_init)
+ get_gicd_addr r3
+
+ mvn r1, #0 @ all bits to 1
+ str r1, [r3, #GICD_IGROUPRn] @ allow private interrupts
+
+ get_gicc_addr r3, r1
+
+ mov r1, #3 @ Enable both groups
+ str r1, [r3, #GICC_CTLR] @ and clear all other bits
+ mov r1, #0xff
+ str r1, [r3, #GICC_PMR] @ set priority mask register
+
+ mrc p15, 0, r0, c1, c1, 2
+ movw r1, #0x3fff
+ movt r1, #0x0004
+ orr r0, r0, r1
+ mcr p15, 0, r0, c1, c1, 2 @ NSACR = all copros to non-sec
+
+/* The CNTFRQ register of the generic timer needs to be
+ * programmed in secure state. Some primary bootloaders / firmware
+ * omit this, so if the frequency is provided in the configuration,
+ * we do this here instead.
+ * But first check if we have the generic timer.
+ */
+#ifdef COUNTER_FREQUENCY
+ mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1
+ and r0, r0, #CPUID_ARM_GENTIMER_MASK @ mask arch timer bits
+ cmp r0, #(1 << CPUID_ARM_GENTIMER_SHIFT)
+ ldreq r1, =COUNTER_FREQUENCY
+ mcreq p15, 0, r1, c14, c0, 0 @ write CNTFRQ
+#endif
+
+ adr r1, _monitor_vectors
+ mcr p15, 0, r1, c12, c0, 1 @ set MVBAR to secure vectors
+ isb
+
+ mov r0, r3 @ return GICC address
+ bx lr
+ENDPROC(_nonsec_init)
+
+#ifdef CONFIG_SMP_PEN_ADDR
+/* void __weak smp_waitloop(unsigned previous_address); */
+ENTRY(smp_waitloop)
+ wfi
+ ldr r1, =CONFIG_SMP_PEN_ADDR @ load start address
+ ldr r1, [r1]
+#ifdef CONFIG_PEN_ADDR_BIG_ENDIAN
+ rev r1, r1
+#endif
+ cmp r0, r1 @ make sure we dont execute this code
+ beq smp_waitloop @ again (due to a spurious wakeup)
+ mov r0, r1
+ b _do_nonsec_entry
+ENDPROC(smp_waitloop)
+.weak smp_waitloop
+#endif
+
+ .popsection
diff --git a/roms/u-boot/arch/arm/cpu/armv7/psci-common.c b/roms/u-boot/arch/arm/cpu/armv7/psci-common.c
new file mode 100644
index 000000000..a328b2bc0
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/psci-common.c
@@ -0,0 +1,46 @@
+/*
+ * Common PSCI functions
+ *
+ * Copyright (C) 2016 Chen-Yu Tsai
+ * Author: Chen-Yu Tsai <wens@csie.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <asm/armv7.h>
+#include <asm/macro.h>
+#include <asm/psci.h>
+#include <asm/secure.h>
+#include <linux/linkage.h>
+
+static u32 psci_target_pc[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 };
+static u32 psci_context_id[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 };
+
+void __secure psci_save(int cpu, u32 pc, u32 context_id)
+{
+ psci_target_pc[cpu] = pc;
+ psci_context_id[cpu] = context_id;
+ dsb();
+}
+
+u32 __secure psci_get_target_pc(int cpu)
+{
+ return psci_target_pc[cpu];
+}
+
+u32 __secure psci_get_context_id(int cpu)
+{
+ return psci_context_id[cpu];
+}
+
diff --git a/roms/u-boot/arch/arm/cpu/armv7/psci.S b/roms/u-boot/arch/arm/cpu/armv7/psci.S
new file mode 100644
index 000000000..983cd9044
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/psci.S
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2013,2014 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+#include <asm/psci.h>
+
+ .pushsection ._secure.text, "ax"
+
+ .arch_extension sec
+
+ .align 5
+ .globl _psci_vectors
+_psci_vectors:
+ b default_psci_vector @ reset
+ b default_psci_vector @ undef
+ b _smc_psci @ smc
+ b default_psci_vector @ pabort
+ b default_psci_vector @ dabort
+ b default_psci_vector @ hyp
+ b default_psci_vector @ irq
+ b psci_fiq_enter @ fiq
+
+ENTRY(psci_fiq_enter)
+ movs pc, lr
+ENDPROC(psci_fiq_enter)
+.weak psci_fiq_enter
+
+ENTRY(default_psci_vector)
+ movs pc, lr
+ENDPROC(default_psci_vector)
+.weak default_psci_vector
+
+ENTRY(psci_version)
+ENTRY(psci_cpu_suspend)
+ENTRY(psci_cpu_off)
+ENTRY(psci_cpu_on)
+ENTRY(psci_affinity_info)
+ENTRY(psci_migrate)
+ENTRY(psci_migrate_info_type)
+ENTRY(psci_migrate_info_up_cpu)
+ENTRY(psci_system_off)
+ENTRY(psci_system_reset)
+ENTRY(psci_features)
+ENTRY(psci_cpu_freeze)
+ENTRY(psci_cpu_default_suspend)
+ENTRY(psci_node_hw_state)
+ENTRY(psci_system_suspend)
+ENTRY(psci_set_suspend_mode)
+ENTRY(psi_stat_residency)
+ENTRY(psci_stat_count)
+ mov r0, #ARM_PSCI_RET_NI @ Return -1 (Not Implemented)
+ mov pc, lr
+ENDPROC(psci_stat_count)
+ENDPROC(psi_stat_residency)
+ENDPROC(psci_set_suspend_mode)
+ENDPROC(psci_system_suspend)
+ENDPROC(psci_node_hw_state)
+ENDPROC(psci_cpu_default_suspend)
+ENDPROC(psci_cpu_freeze)
+ENDPROC(psci_features)
+ENDPROC(psci_system_reset)
+ENDPROC(psci_system_off)
+ENDPROC(psci_migrate_info_up_cpu)
+ENDPROC(psci_migrate_info_type)
+ENDPROC(psci_migrate)
+ENDPROC(psci_affinity_info)
+ENDPROC(psci_cpu_on)
+ENDPROC(psci_cpu_off)
+ENDPROC(psci_cpu_suspend)
+ENDPROC(psci_version)
+.weak psci_version
+.weak psci_cpu_suspend
+.weak psci_cpu_off
+.weak psci_cpu_on
+.weak psci_affinity_info
+.weak psci_migrate
+.weak psci_migrate_info_type
+.weak psci_migrate_info_up_cpu
+.weak psci_system_off
+.weak psci_system_reset
+.weak psci_features
+.weak psci_cpu_freeze
+.weak psci_cpu_default_suspend
+.weak psci_node_hw_state
+.weak psci_system_suspend
+.weak psci_set_suspend_mode
+.weak psi_stat_residency
+.weak psci_stat_count
+
+_psci_table:
+ .word ARM_PSCI_FN_CPU_SUSPEND
+ .word psci_cpu_suspend
+ .word ARM_PSCI_FN_CPU_OFF
+ .word psci_cpu_off
+ .word ARM_PSCI_FN_CPU_ON
+ .word psci_cpu_on
+ .word ARM_PSCI_FN_MIGRATE
+ .word psci_migrate
+ .word ARM_PSCI_0_2_FN_PSCI_VERSION
+ .word psci_version
+ .word ARM_PSCI_0_2_FN_CPU_SUSPEND
+ .word psci_cpu_suspend
+ .word ARM_PSCI_0_2_FN_CPU_OFF
+ .word psci_cpu_off
+ .word ARM_PSCI_0_2_FN_CPU_ON
+ .word psci_cpu_on
+ .word ARM_PSCI_0_2_FN_AFFINITY_INFO
+ .word psci_affinity_info
+ .word ARM_PSCI_0_2_FN_MIGRATE
+ .word psci_migrate
+ .word ARM_PSCI_0_2_FN_MIGRATE_INFO_TYPE
+ .word psci_migrate_info_type
+ .word ARM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU
+ .word psci_migrate_info_up_cpu
+ .word ARM_PSCI_0_2_FN_SYSTEM_OFF
+ .word psci_system_off
+ .word ARM_PSCI_0_2_FN_SYSTEM_RESET
+ .word psci_system_reset
+ .word ARM_PSCI_1_0_FN_PSCI_FEATURES
+ .word psci_features
+ .word ARM_PSCI_1_0_FN_CPU_FREEZE
+ .word psci_cpu_freeze
+ .word ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND
+ .word psci_cpu_default_suspend
+ .word ARM_PSCI_1_0_FN_NODE_HW_STATE
+ .word psci_node_hw_state
+ .word ARM_PSCI_1_0_FN_SYSTEM_SUSPEND
+ .word psci_system_suspend
+ .word ARM_PSCI_1_0_FN_SET_SUSPEND_MODE
+ .word psci_set_suspend_mode
+ .word ARM_PSCI_1_0_FN_STAT_RESIDENCY
+ .word psi_stat_residency
+ .word ARM_PSCI_1_0_FN_STAT_COUNT
+ .word psci_stat_count
+ .word 0
+ .word 0
+
+_smc_psci:
+ push {r4-r7,lr}
+
+ @ Switch to secure
+ mrc p15, 0, r7, c1, c1, 0
+ bic r4, r7, #1
+ mcr p15, 0, r4, c1, c1, 0
+ isb
+
+ adr r4, _psci_table
+1: ldr r5, [r4] @ Load PSCI function ID
+ ldr r6, [r4, #4] @ Load target PC
+ cmp r5, #0 @ If reach the end, bail out
+ moveq r0, #ARM_PSCI_RET_INVAL @ Return -2 (Invalid)
+ beq 2f
+ cmp r0, r5 @ If not matching, try next entry
+ addne r4, r4, #8
+ bne 1b
+
+ blx r6 @ Execute PSCI function
+
+ @ Switch back to non-secure
+2: mcr p15, 0, r7, c1, c1, 0
+
+ pop {r4-r7, lr}
+ movs pc, lr @ Return to the kernel
+
+@ Requires dense and single-cluster CPU ID space
+ENTRY(psci_get_cpu_id)
+ mrc p15, 0, r0, c0, c0, 5 /* read MPIDR */
+ and r0, r0, #0xff /* return CPU ID in cluster */
+ bx lr
+ENDPROC(psci_get_cpu_id)
+.weak psci_get_cpu_id
+
+/* Imported from Linux kernel */
+ENTRY(psci_v7_flush_dcache_all)
+ stmfd sp!, {r4-r5, r7, r9-r11, lr}
+ dmb @ ensure ordering with previous memory accesses
+ mrc p15, 1, r0, c0, c0, 1 @ read clidr
+ ands r3, r0, #0x7000000 @ extract loc from clidr
+ mov r3, r3, lsr #23 @ left align loc bit field
+ beq finished @ if loc is 0, then no need to clean
+ mov r10, #0 @ start clean at cache level 0
+flush_levels:
+ add r2, r10, r10, lsr #1 @ work out 3x current cache level
+ mov r1, r0, lsr r2 @ extract cache type bits from clidr
+ and r1, r1, #7 @ mask of the bits for current cache only
+ cmp r1, #2 @ see what cache we have at this level
+ blt skip @ skip if no cache, or just i-cache
+ mrs r9, cpsr @ make cssr&csidr read atomic
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+ isb @ isb to sych the new cssr&csidr
+ mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
+ msr cpsr_c, r9
+ and r2, r1, #7 @ extract the length of the cache lines
+ add r2, r2, #4 @ add 4 (line length offset)
+ ldr r4, =0x3ff
+ ands r4, r4, r1, lsr #3 @ find maximum number on the way size
+ clz r5, r4 @ find bit position of way size increment
+ ldr r7, =0x7fff
+ ands r7, r7, r1, lsr #13 @ extract max number of the index size
+loop1:
+ mov r9, r7 @ create working copy of max index
+loop2:
+ orr r11, r10, r4, lsl r5 @ factor way and cache number into r11
+ orr r11, r11, r9, lsl r2 @ factor index number into r11
+ mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
+ subs r9, r9, #1 @ decrement the index
+ bge loop2
+ subs r4, r4, #1 @ decrement the way
+ bge loop1
+skip:
+ add r10, r10, #2 @ increment cache number
+ cmp r3, r10
+ bgt flush_levels
+finished:
+ mov r10, #0 @ swith back to cache level 0
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+ dsb st
+ isb
+ ldmfd sp!, {r4-r5, r7, r9-r11, lr}
+ bx lr
+ENDPROC(psci_v7_flush_dcache_all)
+
+ENTRY(psci_disable_smp)
+ mrc p15, 0, r0, c1, c0, 1 @ ACTLR
+ bic r0, r0, #(1 << 6) @ Clear SMP bit
+ mcr p15, 0, r0, c1, c0, 1 @ ACTLR
+ isb
+ dsb
+ bx lr
+ENDPROC(psci_disable_smp)
+.weak psci_disable_smp
+
+ENTRY(psci_enable_smp)
+ mrc p15, 0, r0, c1, c0, 1 @ ACTLR
+ orr r0, r0, #(1 << 6) @ Set SMP bit
+ mcr p15, 0, r0, c1, c0, 1 @ ACTLR
+ isb
+ bx lr
+ENDPROC(psci_enable_smp)
+.weak psci_enable_smp
+
+ENTRY(psci_cpu_off_common)
+ push {lr}
+
+ bl psci_v7_flush_dcache_all
+
+ clrex @ Why???
+
+ mrc p15, 0, r0, c1, c0, 0 @ SCTLR
+ bic r0, r0, #(1 << 2) @ Clear C bit
+ mcr p15, 0, r0, c1, c0, 0 @ SCTLR
+ isb
+ dsb
+
+ bl psci_v7_flush_dcache_all
+
+ clrex @ Why???
+
+ bl psci_disable_smp
+
+ pop {lr}
+ bx lr
+ENDPROC(psci_cpu_off_common)
+
+@ The stacks are allocated in reverse order, i.e.
+@ the stack for CPU0 has the highest memory address.
+@
+@ -------------------- __secure_stack_end
+@ | CPU0 target PC |
+@ |------------------|
+@ | |
+@ | CPU0 stack |
+@ | |
+@ |------------------| __secure_stack_end - 1KB
+@ | . |
+@ | . |
+@ | . |
+@ | . |
+@ -------------------- __secure_stack_start
+@
+@ This expects CPU ID in r0 and returns stack top in r0
+LENTRY(psci_get_cpu_stack_top)
+ @ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT)
+ ldr r3, =__secure_stack_end
+ sub r0, r3, r0, LSL #ARM_PSCI_STACK_SHIFT
+ sub r0, r0, #4 @ Save space for target PC
+ bx lr
+ENDPROC(psci_get_cpu_stack_top)
+
+@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in
+@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across
+@ this function.
+ENTRY(psci_stack_setup)
+ mov r6, lr
+ mov r7, r0
+ bl psci_get_cpu_id @ CPU ID => r0
+ bl psci_get_cpu_stack_top @ stack top => r0
+ mov sp, r0
+ mov r0, r7
+ bx r6
+ENDPROC(psci_stack_setup)
+
+ENTRY(psci_arch_init)
+ mov pc, lr
+ENDPROC(psci_arch_init)
+.weak psci_arch_init
+
+ENTRY(psci_arch_cpu_entry)
+ mov pc, lr
+ENDPROC(psci_arch_cpu_entry)
+.weak psci_arch_cpu_entry
+
+ENTRY(psci_cpu_entry)
+ bl psci_enable_smp
+
+ bl _nonsec_init
+
+ bl psci_stack_setup
+
+ bl psci_arch_cpu_entry
+
+ bl psci_get_cpu_id @ CPU ID => r0
+ mov r2, r0 @ CPU ID => r2
+ bl psci_get_context_id @ context id => r0
+ mov r1, r0 @ context id => r1
+ mov r0, r2 @ CPU ID => r0
+ bl psci_get_target_pc @ target PC => r0
+ b _do_nonsec_entry
+ENDPROC(psci_cpu_entry)
+
+ .popsection
diff --git a/roms/u-boot/arch/arm/cpu/armv7/s5p-common/Makefile b/roms/u-boot/arch/arm/cpu/armv7/s5p-common/Makefile
new file mode 100644
index 000000000..bfe02389c
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/s5p-common/Makefile
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2009 Samsung Electronics
+# Minkyu Kang <mk7.kang@samsung.com>
+
+ifdef CONFIG_ARCH_NEXELL
+obj-$(CONFIG_PWM_NX) += pwm.o
+obj-$(CONFIG_S5P4418_ONEWIRE) += pwm.o
+else
+obj-y += cpu_info.o
+ifndef CONFIG_SPL_BUILD
+obj-y += timer.o
+obj-y += sromc.o
+obj-$(CONFIG_PWM) += pwm.o
+endif
+endif
diff --git a/roms/u-boot/arch/arm/cpu/armv7/s5p-common/cpu_info.c b/roms/u-boot/arch/arm/cpu/armv7/s5p-common/cpu_info.c
new file mode 100644
index 000000000..d910282e2
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/s5p-common/cpu_info.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ */
+#include <common.h>
+#include <fdtdec.h>
+#include <init.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/clk.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Default is s5pc100 */
+unsigned int s5p_cpu_id = 0xC100;
+/* Default is EVT1 */
+unsigned int s5p_cpu_rev = 1;
+
+#ifdef CONFIG_ARCH_CPU_INIT
+int arch_cpu_init(void)
+{
+ s5p_set_cpu_id();
+
+ return 0;
+}
+#endif
+
+u32 get_device_type(void)
+{
+ return s5p_cpu_id;
+}
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+ const char *cpu_model;
+ int len;
+
+ /* For SoC with no real CPU ID in naming convention. */
+ cpu_model = fdt_getprop(gd->fdt_blob, 0, "cpu-model", &len);
+ if (cpu_model)
+ printf("CPU: %.*s @ ", len, cpu_model);
+ else
+ printf("CPU: %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+
+ print_freq(get_arm_clk(), "\n");
+
+ return 0;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv7/s5p-common/pwm.c b/roms/u-boot/arch/arm/cpu/armv7/s5p-common/pwm.c
new file mode 100644
index 000000000..aef2e5574
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/s5p-common/pwm.c
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2011 Samsung Electronics
+ *
+ * Donghwa Lee <dh09.lee@samsung.com>
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <pwm.h>
+#include <asm/io.h>
+#include <asm/arch/pwm.h>
+#include <asm/arch/clk.h>
+
+int pwm_enable(int pwm_id)
+{
+ const struct s5p_timer *pwm =
+#if defined(CONFIG_ARCH_NEXELL)
+ (struct s5p_timer *)PHY_BASEADDR_PWM;
+#else
+ (struct s5p_timer *)samsung_get_base_timer();
+#endif
+ unsigned long tcon;
+
+ tcon = readl(&pwm->tcon);
+ tcon |= TCON_START(pwm_id);
+
+ writel(tcon, &pwm->tcon);
+
+ return 0;
+}
+
+void pwm_disable(int pwm_id)
+{
+ const struct s5p_timer *pwm =
+#if defined(CONFIG_ARCH_NEXELL)
+ (struct s5p_timer *)PHY_BASEADDR_PWM;
+#else
+ (struct s5p_timer *)samsung_get_base_timer();
+#endif
+ unsigned long tcon;
+
+ tcon = readl(&pwm->tcon);
+ tcon &= ~TCON_START(pwm_id);
+
+ writel(tcon, &pwm->tcon);
+}
+
+static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq)
+{
+ unsigned long tin_parent_rate;
+ unsigned int div;
+
+#if defined(CONFIG_ARCH_NEXELL)
+ unsigned int pre_div;
+ const struct s5p_timer *pwm =
+ (struct s5p_timer *)PHY_BASEADDR_PWM;
+ unsigned int val;
+ struct clk *clk = clk_get(CORECLK_NAME_PCLK);
+
+ tin_parent_rate = clk_get_rate(clk);
+#else
+ tin_parent_rate = get_pwm_clk();
+#endif
+
+#if defined(CONFIG_ARCH_NEXELL)
+ writel(0, &pwm->tcfg0);
+ val = readl(&pwm->tcfg0);
+
+ if (pwm_id < 2)
+ div = ((val >> 0) & 0xff) + 1;
+ else
+ div = ((val >> 8) & 0xff) + 1;
+
+ writel(0, &pwm->tcfg1);
+ val = readl(&pwm->tcfg1);
+ val = (val >> MUX_DIV_SHIFT(pwm_id)) & 0xF;
+ pre_div = (1UL << val);
+
+ freq = tin_parent_rate / div / pre_div;
+
+ return freq;
+#else
+ for (div = 2; div <= 16; div *= 2) {
+ if ((tin_parent_rate / (div << 16)) < freq)
+ return tin_parent_rate / div;
+ }
+
+ return tin_parent_rate / 16;
+#endif
+}
+
+#define NS_IN_SEC 1000000000UL
+
+int pwm_config(int pwm_id, int duty_ns, int period_ns)
+{
+ const struct s5p_timer *pwm =
+#if defined(CONFIG_ARCH_NEXELL)
+ (struct s5p_timer *)PHY_BASEADDR_PWM;
+#else
+ (struct s5p_timer *)samsung_get_base_timer();
+#endif
+ unsigned int offset;
+ unsigned long tin_rate;
+ unsigned long tin_ns;
+ unsigned long frequency;
+ unsigned long tcon;
+ unsigned long tcnt;
+ unsigned long tcmp;
+
+ /*
+ * We currently avoid using 64bit arithmetic by using the
+ * fact that anything faster than 1GHz is easily representable
+ * by 32bits.
+ */
+ if (period_ns > NS_IN_SEC || duty_ns > NS_IN_SEC || period_ns == 0)
+ return -ERANGE;
+
+ if (duty_ns > period_ns)
+ return -EINVAL;
+
+ frequency = NS_IN_SEC / period_ns;
+
+ /* Check to see if we are changing the clock rate of the PWM */
+ tin_rate = pwm_calc_tin(pwm_id, frequency);
+
+ tin_ns = NS_IN_SEC / tin_rate;
+
+ if (IS_ENABLED(CONFIG_ARCH_NEXELL))
+ /* The counter starts at zero. */
+ tcnt = (period_ns / tin_ns) - 1;
+ else
+ tcnt = period_ns / tin_ns;
+
+ /* Note, counters count down */
+ tcmp = duty_ns / tin_ns;
+ tcmp = tcnt - tcmp;
+
+ /* Update the PWM register block. */
+ offset = pwm_id * 3;
+ if (pwm_id < 4) {
+ writel(tcnt, &pwm->tcntb0 + offset);
+ writel(tcmp, &pwm->tcmpb0 + offset);
+ }
+
+ tcon = readl(&pwm->tcon);
+ tcon |= TCON_UPDATE(pwm_id);
+ if (pwm_id < 4)
+ tcon |= TCON_AUTO_RELOAD(pwm_id);
+ else
+ tcon |= TCON4_AUTO_RELOAD;
+ writel(tcon, &pwm->tcon);
+
+ tcon &= ~TCON_UPDATE(pwm_id);
+ writel(tcon, &pwm->tcon);
+
+ return 0;
+}
+
+int pwm_init(int pwm_id, int div, int invert)
+{
+ u32 val;
+ const struct s5p_timer *pwm =
+#if defined(CONFIG_ARCH_NEXELL)
+ (struct s5p_timer *)PHY_BASEADDR_PWM;
+#else
+ (struct s5p_timer *)samsung_get_base_timer();
+#endif
+ unsigned long ticks_per_period;
+ unsigned int offset, prescaler;
+
+ /*
+ * Timer Freq(HZ) =
+ * PWM_CLK / { (prescaler_value + 1) * (divider_value) }
+ */
+
+ val = readl(&pwm->tcfg0);
+ if (pwm_id < 2) {
+ prescaler = PRESCALER_0;
+ val &= ~0xff;
+ val |= (prescaler & 0xff);
+ } else {
+ prescaler = PRESCALER_1;
+ val &= ~(0xff << 8);
+ val |= (prescaler & 0xff) << 8;
+ }
+ writel(val, &pwm->tcfg0);
+ val = readl(&pwm->tcfg1);
+ val &= ~(0xf << MUX_DIV_SHIFT(pwm_id));
+ val |= (div & 0xf) << MUX_DIV_SHIFT(pwm_id);
+ writel(val, &pwm->tcfg1);
+
+ if (pwm_id == 4) {
+ /*
+ * TODO(sjg): Use this as a countdown timer for now. We count
+ * down from the maximum value to 0, then reset.
+ */
+ ticks_per_period = -1UL;
+ } else {
+ const unsigned long pwm_hz = 1000;
+#if defined(CONFIG_ARCH_NEXELL)
+ struct clk *clk = clk_get(CORECLK_NAME_PCLK);
+ unsigned long timer_rate_hz = clk_get_rate(clk) /
+#else
+ unsigned long timer_rate_hz = get_pwm_clk() /
+#endif
+ ((prescaler + 1) * (1 << div));
+
+ ticks_per_period = timer_rate_hz / pwm_hz;
+ }
+
+ /* set count value */
+ offset = pwm_id * 3;
+
+ writel(ticks_per_period, &pwm->tcntb0 + offset);
+
+ val = readl(&pwm->tcon) & ~(0xf << TCON_OFFSET(pwm_id));
+ if (invert && (pwm_id < 4))
+ val |= TCON_INVERTER(pwm_id);
+ writel(val, &pwm->tcon);
+
+ pwm_enable(pwm_id);
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/s5p-common/sromc.c b/roms/u-boot/arch/arm/cpu/armv7/s5p-common/sromc.c
new file mode 100644
index 000000000..0fc170936
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/s5p-common/sromc.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2010 Samsung Electronics
+ * Naveen Krishna Ch <ch.naveen@samsung.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/sromc.h>
+
+/*
+ * s5p_config_sromc() - select the proper SROMC Bank and configure the
+ * band width control and bank control registers
+ * srom_bank - SROM
+ * srom_bw_conf - SMC Band witdh reg configuration value
+ * srom_bc_conf - SMC Bank Control reg configuration value
+ */
+void s5p_config_sromc(u32 srom_bank, u32 srom_bw_conf, u32 srom_bc_conf)
+{
+ u32 tmp;
+ struct s5p_sromc *srom =
+ (struct s5p_sromc *)samsung_get_base_sromc();
+
+ /* Configure SMC_BW register to handle proper SROMC bank */
+ tmp = srom->bw;
+ tmp &= ~(0xF << (srom_bank * 4));
+ tmp |= srom_bw_conf;
+ srom->bw = tmp;
+
+ /* Configure SMC_BC register */
+ srom->bc[srom_bank] = srom_bc_conf;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/s5p-common/timer.c b/roms/u-boot/arch/arm/cpu/armv7/s5p-common/timer.c
new file mode 100644
index 000000000..8141f40d5
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/s5p-common/timer.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Heungjun Kim <riverful.kim@samsung.com>
+ * Inki Dae <inki.dae@samsung.com>
+ * Minkyu Kang <mk7.kang@samsung.com>
+ */
+
+#include <common.h>
+#include <div64.h>
+#include <init.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/pwm.h>
+#include <asm/arch/clk.h>
+#include <linux/delay.h>
+
+/* Use the old PWM interface for now */
+#undef CONFIG_DM_PWM
+#include <pwm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+unsigned long get_current_tick(void);
+static void reset_timer_masked(void);
+
+/* macro to read the 16 bit timer */
+static inline struct s5p_timer *s5p_get_base_timer(void)
+{
+ return (struct s5p_timer *)samsung_get_base_timer();
+}
+
+/**
+ * Read the countdown timer.
+ *
+ * This operates at 1MHz and counts downwards. It will wrap about every
+ * hour (2^32 microseconds).
+ *
+ * @return current value of timer
+ */
+static unsigned long timer_get_us_down(void)
+{
+ struct s5p_timer *const timer = s5p_get_base_timer();
+
+ return readl(&timer->tcnto4);
+}
+
+int timer_init(void)
+{
+ /* PWM Timer 4 */
+ pwm_init(4, MUX_DIV_4, 0);
+ pwm_config(4, 100000, 100000);
+ pwm_enable(4);
+
+ /* Use this as the current monotonic time in us */
+ gd->arch.timer_reset_value = 0;
+
+ /* Use this as the last timer value we saw */
+ gd->arch.lastinc = timer_get_us_down();
+ reset_timer_masked();
+
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+unsigned long get_timer(unsigned long base)
+{
+ unsigned long long time_ms;
+
+ ulong now = timer_get_us_down();
+
+ /*
+ * Increment the time by the amount elapsed since the last read.
+ * The timer may have wrapped around, but it makes no difference to
+ * our arithmetic here.
+ */
+ gd->arch.timer_reset_value += gd->arch.lastinc - now;
+ gd->arch.lastinc = now;
+
+ /* Divide by 1000 to convert from us to ms */
+ time_ms = gd->arch.timer_reset_value;
+ do_div(time_ms, 1000);
+ return time_ms - base;
+}
+
+unsigned long __attribute__((no_instrument_function)) timer_get_us(void)
+{
+ static unsigned long base_time_us;
+
+ struct s5p_timer *const timer =
+ (struct s5p_timer *)samsung_get_base_timer();
+ unsigned long now_downward_us = readl(&timer->tcnto4);
+
+ if (!base_time_us)
+ base_time_us = now_downward_us;
+
+ /* Note that this timer counts downward. */
+ return base_time_us - now_downward_us;
+}
+
+/* delay x useconds */
+void __udelay(unsigned long usec)
+{
+ unsigned long count_value;
+
+ count_value = timer_get_us_down();
+ while ((int)(count_value - timer_get_us_down()) < (int)usec)
+ ;
+}
+
+static void reset_timer_masked(void)
+{
+ struct s5p_timer *const timer = s5p_get_base_timer();
+
+ /* reset time */
+ gd->arch.lastinc = readl(&timer->tcnto4);
+ gd->arch.tbl = 0;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+unsigned long get_tbclk(void)
+{
+ return CONFIG_SYS_HZ;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/s5p4418/Makefile b/roms/u-boot/arch/arm/cpu/armv7/s5p4418/Makefile
new file mode 100644
index 000000000..321b257b6
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/s5p4418/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2016 Nexell
+# Hyunseok, Jung <hsjung@nexell.co.kr>
+
+obj-y += cpu.o
diff --git a/roms/u-boot/arch/arm/cpu/armv7/s5p4418/cpu.c b/roms/u-boot/arch/arm/cpu/armv7/s5p4418/cpu.c
new file mode 100644
index 000000000..3baa761ec
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/s5p4418/cpu.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Nexell
+ * Hyunseok, Jung <hsjung@nexell.co.kr>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/system.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/arch/nexell.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/reset.h>
+#include <asm/arch/tieoff.h>
+#include <cpu_func.h>
+#include <linux/delay.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_ARCH_CPU_INIT
+#error must be define the macro "CONFIG_ARCH_CPU_INIT"
+#endif
+
+void s_init(void)
+{
+}
+
+static void cpu_soc_init(void)
+{
+ /*
+ * NOTE> ALIVE Power Gate must enable for Alive register access.
+ * must be clear wfi jump address
+ */
+ writel(1, ALIVEPWRGATEREG);
+ writel(0xFFFFFFFF, SCR_ARM_SECOND_BOOT);
+
+ /* write 0xf0 on alive scratchpad reg for boot success check */
+ writel(readl(SCR_SIGNAGURE_READ) | 0xF0, (SCR_SIGNAGURE_SET));
+
+ /* set l2 cache tieoff */
+ nx_tieoff_set(NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2RET1N_0, 1);
+ nx_tieoff_set(NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2RET1N_1, 1);
+}
+
+#ifdef CONFIG_PL011_SERIAL
+static void serial_device_init(void)
+{
+ char dev[10];
+ int id;
+
+ sprintf(dev, "nx-uart.%d", CONFIG_CONS_INDEX);
+ id = RESET_ID_UART0 + CONFIG_CONS_INDEX;
+
+ struct clk *clk = clk_get((const char *)dev);
+
+ /* reset control: Low active ___|--- */
+ nx_rstcon_setrst(id, RSTCON_ASSERT);
+ udelay(10);
+ nx_rstcon_setrst(id, RSTCON_NEGATE);
+ udelay(10);
+
+ /* set clock */
+ clk_disable(clk);
+ clk_set_rate(clk, CONFIG_PL011_CLOCK);
+ clk_enable(clk);
+}
+#endif
+
+int arch_cpu_init(void)
+{
+ flush_dcache_all();
+ cpu_soc_init();
+ clk_init();
+
+ if (IS_ENABLED(CONFIG_PL011_SERIAL))
+ serial_device_init();
+
+ return 0;
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+ return 0;
+}
+#endif
+
+void reset_cpu(void)
+{
+ void *clkpwr_reg = (void *)PHY_BASEADDR_CLKPWR;
+ const u32 sw_rst_enb_bitpos = 3;
+ const u32 sw_rst_enb_mask = 1 << sw_rst_enb_bitpos;
+ const u32 sw_rst_bitpos = 12;
+ const u32 sw_rst_mask = 1 << sw_rst_bitpos;
+ int pwrcont = 0x224;
+ int pwrmode = 0x228;
+ u32 read_value;
+
+ read_value = readl((void *)(clkpwr_reg + pwrcont));
+
+ read_value &= ~sw_rst_enb_mask;
+ read_value |= 1 << sw_rst_enb_bitpos;
+
+ writel(read_value, (void *)(clkpwr_reg + pwrcont));
+ writel(sw_rst_mask, (void *)(clkpwr_reg + pwrmode));
+}
+
+void enable_caches(void)
+{
+ /* Enable D-cache. I-cache is already enabled in start.S */
+ dcache_enable();
+}
+
+#if defined(CONFIG_ARCH_MISC_INIT)
+int arch_misc_init(void)
+{
+ return 0;
+}
+#endif /* CONFIG_ARCH_MISC_INIT */
diff --git a/roms/u-boot/arch/arm/cpu/armv7/sctlr.S b/roms/u-boot/arch/arm/cpu/armv7/sctlr.S
new file mode 100644
index 000000000..bd56e41af
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/sctlr.S
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Routines to access the system control register
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * void allow_unaligned(void) - allow unaligned access
+ *
+ * This routine clears the aligned flag in the system control register.
+ * After calling this routine unaligned access does no longer lead to a
+ * data abort but is handled by the CPU.
+ */
+ENTRY(allow_unaligned)
+ mrc p15, 0, r0, c1, c0, 0 @ load system control register
+ bic r0, r0, #2 @ clear aligned flag
+ mcr p15, 0, r0, c1, c0, 0 @ write system control register
+ bx lr @ return
+ENDPROC(allow_unaligned)
diff --git a/roms/u-boot/arch/arm/cpu/armv7/smccc-call.S b/roms/u-boot/arch/arm/cpu/armv7/smccc-call.S
new file mode 100644
index 000000000..f70728f2c
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/smccc-call.S
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2015, Linaro Limited
+ */
+#include <linux/linkage.h>
+
+#include <asm/opcodes-sec.h>
+#include <asm/opcodes-virt.h>
+
+#ifdef CONFIG_EFI_LOADER
+ .section .text.efi_runtime
+#endif
+
+#define UNWIND(x...)
+ /*
+ * Wrap c macros in asm macros to delay expansion until after the
+ * SMCCC asm macro is expanded.
+ */
+ .macro SMCCC_SMC
+ __SMC(0)
+ .endm
+
+ .macro SMCCC_HVC
+ __HVC(0)
+ .endm
+
+ .macro SMCCC instr
+UNWIND( .fnstart)
+ mov r12, sp
+ push {r4-r7}
+UNWIND( .save {r4-r7})
+ ldm r12, {r4-r7}
+ \instr
+ pop {r4-r7}
+ ldr r12, [sp, #(4 * 4)]
+ stm r12, {r0-r3}
+ bx lr
+UNWIND( .fnend)
+ .endm
+
+/*
+ * void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
+ * unsigned long a3, unsigned long a4, unsigned long a5,
+ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ * struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_smc)
+ SMCCC SMCCC_SMC
+ENDPROC(__arm_smccc_smc)
+
+/*
+ * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
+ * unsigned long a3, unsigned long a4, unsigned long a5,
+ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ * struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_hvc)
+ SMCCC SMCCC_HVC
+ENDPROC(__arm_smccc_hvc)
diff --git a/roms/u-boot/arch/arm/cpu/armv7/start.S b/roms/u-boot/arch/arm/cpu/armv7/start.S
new file mode 100644
index 000000000..dcb4195d7
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/start.S
@@ -0,0 +1,342 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core
+ *
+ * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
+ *
+ * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
+ * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
+ * Copyright (c) 2003 Kshitij <kshitij@ti.com>
+ * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/system.h>
+#include <linux/linkage.h>
+#include <asm/armv7.h>
+
+/*************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * Do important init only if we don't start from memory!
+ * Setup memory and board specific bits prior to relocation.
+ * Relocate armboot to ram. Setup stack.
+ *
+ *************************************************************************/
+
+ .globl reset
+ .globl save_boot_params_ret
+ .type save_boot_params_ret,%function
+#ifdef CONFIG_ARMV7_LPAE
+ .global switch_to_hypervisor_ret
+#endif
+
+reset:
+ /* Allow the board to save important registers */
+ b save_boot_params
+save_boot_params_ret:
+#ifdef CONFIG_ARMV7_LPAE
+/*
+ * check for Hypervisor support
+ */
+ mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1
+ and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits
+ cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT)
+ beq switch_to_hypervisor
+switch_to_hypervisor_ret:
+#endif
+ /*
+ * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
+ * except if in HYP mode already
+ */
+ mrs r0, cpsr
+ and r1, r0, #0x1f @ mask mode bits
+ teq r1, #0x1a @ test for HYP mode
+ bicne r0, r0, #0x1f @ clear all mode bits
+ orrne r0, r0, #0x13 @ set SVC mode
+ orr r0, r0, #0xc0 @ disable FIQ and IRQ
+ msr cpsr,r0
+
+/*
+ * Setup vector:
+ * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
+ * Continue to use ROM code vector only in OMAP4 spl)
+ */
+#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
+ /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
+ mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
+ bic r0, #CR_V @ V = 0
+ mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register
+
+#ifdef CONFIG_HAS_VBAR
+ /* Set vector address in CP15 VBAR register */
+ ldr r0, =_start
+ mcr p15, 0, r0, c12, c0, 0 @Set VBAR
+#endif
+#endif
+
+ /* the mask ROM code should have PLL and others stable */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+#ifdef CONFIG_CPU_V7A
+ bl cpu_init_cp15
+#endif
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
+ bl cpu_init_crit
+#endif
+#endif
+
+ bl _main
+
+/*------------------------------------------------------------------------------*/
+
+ENTRY(c_runtime_cpu_setup)
+/*
+ * If I-cache is enabled invalidate it
+ */
+#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
+ mcr p15, 0, r0, c7, c10, 4 @ DSB
+ mcr p15, 0, r0, c7, c5, 4 @ ISB
+#endif
+
+ bx lr
+
+ENDPROC(c_runtime_cpu_setup)
+
+/*************************************************************************
+ *
+ * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
+ * __attribute__((weak));
+ *
+ * Stack pointer is not yet initialized at this moment
+ * Don't save anything to stack even if compiled with -O0
+ *
+ *************************************************************************/
+ENTRY(save_boot_params)
+ b save_boot_params_ret @ back to my caller
+ENDPROC(save_boot_params)
+ .weak save_boot_params
+
+#ifdef CONFIG_ARMV7_LPAE
+ENTRY(switch_to_hypervisor)
+ b switch_to_hypervisor_ret
+ENDPROC(switch_to_hypervisor)
+ .weak switch_to_hypervisor
+#endif
+
+/*************************************************************************
+ *
+ * cpu_init_cp15
+ *
+ * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
+ * CONFIG_SYS_ICACHE_OFF is defined.
+ *
+ *************************************************************************/
+ENTRY(cpu_init_cp15)
+ /*
+ * Invalidate L1 I/D
+ */
+ mov r0, #0 @ set up for MCR
+ mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
+ mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
+ mcr p15, 0, r0, c7, c10, 4 @ DSB
+ mcr p15, 0, r0, c7, c5, 4 @ ISB
+
+ /*
+ * disable MMU stuff and caches
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
+ bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
+ orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
+ orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
+#if CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
+ bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
+#else
+ orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
+#endif
+ mcr p15, 0, r0, c1, c0, 0
+
+#ifdef CONFIG_ARM_ERRATA_716044
+ mrc p15, 0, r0, c1, c0, 0 @ read system control register
+ orr r0, r0, #1 << 11 @ set bit #11
+ mcr p15, 0, r0, c1, c0, 0 @ write system control register
+#endif
+
+#if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072))
+ mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
+ orr r0, r0, #1 << 4 @ set bit #4
+ mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_743622
+ mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
+ orr r0, r0, #1 << 6 @ set bit #6
+ mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_751472
+ mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
+ orr r0, r0, #1 << 11 @ set bit #11
+ mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
+#endif
+#ifdef CONFIG_ARM_ERRATA_761320
+ mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
+ orr r0, r0, #1 << 21 @ set bit #21
+ mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_845369
+ mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
+ orr r0, r0, #1 << 22 @ set bit #22
+ mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
+#endif
+
+ mov r5, lr @ Store my Caller
+ mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR)
+ mov r3, r1, lsr #20 @ get variant field
+ and r3, r3, #0xf @ r3 has CPU variant
+ and r4, r1, #0xf @ r4 has CPU revision
+ mov r2, r3, lsl #4 @ shift variant field for combined value
+ orr r2, r4, r2 @ r2 has combined CPU variant + revision
+
+/* Early stack for ERRATA that needs into call C code */
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
+ ldr r0, =(CONFIG_SPL_STACK)
+#else
+ ldr r0, =(CONFIG_SYS_INIT_SP_ADDR)
+#endif
+ bic r0, r0, #7 /* 8-byte alignment for ABI compliance */
+ mov sp, r0
+
+#ifdef CONFIG_ARM_ERRATA_798870
+ cmp r2, #0x30 @ Applies to lower than R3p0
+ bge skip_errata_798870 @ skip if not affected rev
+ cmp r2, #0x20 @ Applies to including and above R2p0
+ blt skip_errata_798870 @ skip if not affected rev
+
+ mrc p15, 1, r0, c15, c0, 0 @ read l2 aux ctrl reg
+ orr r0, r0, #1 << 7 @ Enable hazard-detect timeout
+ push {r1-r5} @ Save the cpu info registers
+ bl v7_arch_cp15_set_l2aux_ctrl
+ isb @ Recommended ISB after l2actlr update
+ pop {r1-r5} @ Restore the cpu info - fall through
+skip_errata_798870:
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_801819
+ cmp r2, #0x24 @ Applies to lt including R2p4
+ bgt skip_errata_801819 @ skip if not affected rev
+ cmp r2, #0x20 @ Applies to including and above R2p0
+ blt skip_errata_801819 @ skip if not affected rev
+ mrc p15, 0, r0, c0, c0, 6 @ pick up REVIDR reg
+ and r0, r0, #1 << 3 @ check REVIDR[3]
+ cmp r0, #1 << 3
+ beq skip_errata_801819 @ skip erratum if REVIDR[3] is set
+
+ mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register
+ orr r0, r0, #3 << 27 @ Disables streaming. All write-allocate
+ @ lines allocate in the L1 or L2 cache.
+ orr r0, r0, #3 << 25 @ Disables streaming. All write-allocate
+ @ lines allocate in the L1 cache.
+ push {r1-r5} @ Save the cpu info registers
+ bl v7_arch_cp15_set_acr
+ pop {r1-r5} @ Restore the cpu info - fall through
+skip_errata_801819:
+#endif
+
+#ifdef CONFIG_ARM_CORTEX_A15_CVE_2017_5715
+ mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register
+ orr r0, r0, #1 << 0 @ Enable invalidates of BTB
+ push {r1-r5} @ Save the cpu info registers
+ bl v7_arch_cp15_set_acr
+ pop {r1-r5} @ Restore the cpu info - fall through
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_454179
+ mrc p15, 0, r0, c1, c0, 1 @ Read ACR
+
+ cmp r2, #0x21 @ Only on < r2p1
+ orrlt r0, r0, #(0x3 << 6) @ Set DBSM(BIT7) and IBE(BIT6) bits
+
+ push {r1-r5} @ Save the cpu info registers
+ bl v7_arch_cp15_set_acr
+ pop {r1-r5} @ Restore the cpu info - fall through
+#endif
+
+#if defined(CONFIG_ARM_ERRATA_430973) || defined (CONFIG_ARM_CORTEX_A8_CVE_2017_5715)
+ mrc p15, 0, r0, c1, c0, 1 @ Read ACR
+
+#ifdef CONFIG_ARM_CORTEX_A8_CVE_2017_5715
+ orr r0, r0, #(0x1 << 6) @ Set IBE bit always to enable OS WA
+#else
+ cmp r2, #0x21 @ Only on < r2p1
+ orrlt r0, r0, #(0x1 << 6) @ Set IBE bit
+#endif
+ push {r1-r5} @ Save the cpu info registers
+ bl v7_arch_cp15_set_acr
+ pop {r1-r5} @ Restore the cpu info - fall through
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_621766
+ mrc p15, 0, r0, c1, c0, 1 @ Read ACR
+
+ cmp r2, #0x21 @ Only on < r2p1
+ orrlt r0, r0, #(0x1 << 5) @ Set L1NEON bit
+
+ push {r1-r5} @ Save the cpu info registers
+ bl v7_arch_cp15_set_acr
+ pop {r1-r5} @ Restore the cpu info - fall through
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_725233
+ mrc p15, 1, r0, c9, c0, 2 @ Read L2ACR
+
+ cmp r2, #0x21 @ Only on < r2p1 (Cortex A8)
+ orrlt r0, r0, #(0x1 << 27) @ L2 PLD data forwarding disable
+
+ push {r1-r5} @ Save the cpu info registers
+ bl v7_arch_cp15_set_l2aux_ctrl
+ pop {r1-r5} @ Restore the cpu info - fall through
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_852421
+ mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
+ orr r0, r0, #1 << 24 @ set bit #24
+ mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_852423
+ mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
+ orr r0, r0, #1 << 12 @ set bit #12
+ mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
+#endif
+
+ mov pc, r5 @ back to my caller
+ENDPROC(cpu_init_cp15)
+
+#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && \
+ !defined(CONFIG_SKIP_LOWLEVEL_INIT_ONLY)
+/*************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************/
+ENTRY(cpu_init_crit)
+ /*
+ * Jump to board specific initialization...
+ * The Mask ROM will have already initialized
+ * basic memory. Go here to bump up clock rate and handle
+ * wake up conditions.
+ */
+ b lowlevel_init @ go setup pll,mux,memory
+ENDPROC(cpu_init_crit)
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv7/stv0991/Makefile b/roms/u-boot/arch/arm/cpu/armv7/stv0991/Makefile
new file mode 100644
index 000000000..3be5eba4b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/stv0991/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2014, STMicroelectronics - All Rights Reserved
+# Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
+
+obj-y := timer.o clock.o pinmux.o reset.o
+obj-y += lowlevel.o
diff --git a/roms/u-boot/arch/arm/cpu/armv7/stv0991/clock.c b/roms/u-boot/arch/arm/cpu/armv7/stv0991/clock.c
new file mode 100644
index 000000000..1e35deed3
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/stv0991/clock.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2014, STMicroelectronics - All Rights Reserved
+ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
+ */
+
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/stv0991_cgu.h>
+#include<asm/arch/stv0991_periph.h>
+
+static struct stv0991_cgu_regs *const stv0991_cgu_regs = \
+ (struct stv0991_cgu_regs *) (CGU_BASE_ADDR);
+
+void enable_pll1(void)
+{
+ /* pll1 already configured for 1000Mhz, just need to enable it */
+ writel(readl(&stv0991_cgu_regs->pll1_ctrl) & ~(0x01),
+ &stv0991_cgu_regs->pll1_ctrl);
+}
+
+void clock_setup(int peripheral)
+{
+ switch (peripheral) {
+ case UART_CLOCK_CFG:
+ writel(UART_CLK_CFG, &stv0991_cgu_regs->uart_freq);
+ break;
+ case ETH_CLOCK_CFG:
+ enable_pll1();
+ writel(ETH_CLK_CFG, &stv0991_cgu_regs->eth_freq);
+
+ /* Clock selection for ethernet tx_clk & rx_clk*/
+ writel((readl(&stv0991_cgu_regs->eth_ctrl) & ETH_CLK_MASK)
+ | ETH_CLK_CTRL, &stv0991_cgu_regs->eth_ctrl);
+ break;
+ case QSPI_CLOCK_CFG:
+ writel(QSPI_CLK_CTRL, &stv0991_cgu_regs->qspi_freq);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/stv0991/lowlevel.S b/roms/u-boot/arch/arm/cpu/armv7/stv0991/lowlevel.S
new file mode 100644
index 000000000..218ac70f3
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/stv0991/lowlevel.S
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2014 stmicroelectronics
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+ mov pc, lr
+ENDPROC(lowlevel_init)
diff --git a/roms/u-boot/arch/arm/cpu/armv7/stv0991/pinmux.c b/roms/u-boot/arch/arm/cpu/armv7/stv0991/pinmux.c
new file mode 100644
index 000000000..6c44ffe50
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/stv0991/pinmux.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2014, STMicroelectronics - All Rights Reserved
+ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
+ */
+
+#include <asm/io.h>
+#include <asm/arch/stv0991_creg.h>
+#include <asm/arch/stv0991_periph.h>
+#include <asm/arch/hardware.h>
+
+static struct stv0991_creg *const stv0991_creg = \
+ (struct stv0991_creg *)CREG_BASE_ADDR;
+
+int stv0991_pinmux_config(int peripheral)
+{
+ switch (peripheral) {
+ case UART_GPIOC_30_31:
+ /* SSDA/SSCL pad muxing to UART Rx/Dx */
+ writel((readl(&stv0991_creg->mux12) & GPIOC_31_MUX_MASK) |
+ CFG_GPIOC_31_UART_RX,
+ &stv0991_creg->mux12);
+ writel((readl(&stv0991_creg->mux12) & GPIOC_30_MUX_MASK) |
+ CFG_GPIOC_30_UART_TX,
+ &stv0991_creg->mux12);
+ /* SSDA/SSCL pad config to push pull*/
+ writel((readl(&stv0991_creg->cfg_pad6) & GPIOC_31_MODE_MASK) |
+ CFG_GPIOC_31_MODE_PP,
+ &stv0991_creg->cfg_pad6);
+ writel((readl(&stv0991_creg->cfg_pad6) & GPIOC_30_MODE_MASK) |
+ CFG_GPIOC_30_MODE_HIGH,
+ &stv0991_creg->cfg_pad6);
+ break;
+ case UART_GPIOB_16_17:
+ /* ethernet rx_6/7 to UART Rx/Dx */
+ writel((readl(&stv0991_creg->mux7) & GPIOB_17_MUX_MASK) |
+ CFG_GPIOB_17_UART_RX,
+ &stv0991_creg->mux7);
+ writel((readl(&stv0991_creg->mux7) & GPIOB_16_MUX_MASK) |
+ CFG_GPIOB_16_UART_TX,
+ &stv0991_creg->mux7);
+ break;
+ case ETH_GPIOB_10_31_C_0_4:
+ writel(readl(&stv0991_creg->mux6) & 0x000000FF,
+ &stv0991_creg->mux6);
+ writel(0x00000000, &stv0991_creg->mux7);
+ writel(0x00000000, &stv0991_creg->mux8);
+ writel(readl(&stv0991_creg->mux9) & 0xFFF00000,
+ &stv0991_creg->mux9);
+ /* Ethernet Voltage configuration to 1.8V*/
+ writel((readl(&stv0991_creg->vdd_pad1) & VDD_ETH_PS_MASK) |
+ ETH_VDD_CFG, &stv0991_creg->vdd_pad1);
+ writel((readl(&stv0991_creg->vdd_pad1) & VDD_ETH_PS_MASK) |
+ ETH_M_VDD_CFG, &stv0991_creg->vdd_pad1);
+
+ break;
+ case QSPI_CS_CLK_PAD:
+ writel((readl(&stv0991_creg->mux13) & FLASH_CS_NC_MASK) |
+ CFG_FLASH_CS_NC, &stv0991_creg->mux13);
+ writel((readl(&stv0991_creg->mux13) & FLASH_CLK_MASK) |
+ CFG_FLASH_CLK, &stv0991_creg->mux13);
+ default:
+ break;
+ }
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/stv0991/reset.c b/roms/u-boot/arch/arm/cpu/armv7/stv0991/reset.c
new file mode 100644
index 000000000..77d4477c8
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/stv0991/reset.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2014, STMicroelectronics - All Rights Reserved
+ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/io.h>
+#include <asm/arch/stv0991_wdru.h>
+#include <linux/delay.h>
+void reset_cpu(void)
+{
+ puts("System is going to reboot ...\n");
+ /*
+ * This 1 second delay will allow the above message
+ * to be printed before reset
+ */
+ udelay((1000 * 1000));
+
+ /* Setting bit 1 of the WDRU unit will reset the SoC */
+ writel(WDRU_RST_SYS, &stv0991_wd_ru_ptr->wdru_ctrl1);
+
+ /* system will restart */
+ while (1)
+ ;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/stv0991/timer.c b/roms/u-boot/arch/arm/cpu/armv7/stv0991/timer.c
new file mode 100644
index 000000000..07033acb5
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/stv0991/timer.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2014, STMicroelectronics - All Rights Reserved
+ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch-stv0991/hardware.h>
+#include <asm/arch-stv0991/stv0991_cgu.h>
+#include <asm/arch-stv0991/stv0991_gpt.h>
+#include <linux/delay.h>
+
+static struct stv0991_cgu_regs *const stv0991_cgu_regs = \
+ (struct stv0991_cgu_regs *) (CGU_BASE_ADDR);
+
+#define READ_TIMER() (readl(&gpt1_regs_ptr->cnt) & GPT_FREE_RUNNING)
+#define GPT_RESOLUTION (CONFIG_STV0991_HZ_CLOCK / CONFIG_STV0991_HZ)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define timestamp gd->arch.tbl
+#define lastdec gd->arch.lastinc
+
+static ulong get_timer_masked(void);
+
+int timer_init(void)
+{
+ /* Timer1 clock configuration */
+ writel(TIMER1_CLK_CFG, &stv0991_cgu_regs->tim_freq);
+ writel(readl(&stv0991_cgu_regs->cgu_enable_2) |
+ TIMER1_CLK_EN, &stv0991_cgu_regs->cgu_enable_2);
+
+ /* Stop the timer */
+ writel(readl(&gpt1_regs_ptr->cr1) & ~GPT_CR1_CEN, &gpt1_regs_ptr->cr1);
+ writel(GPT_PRESCALER_128, &gpt1_regs_ptr->psc);
+ /* Configure timer for auto-reload */
+ writel(readl(&gpt1_regs_ptr->cr1) | GPT_MODE_AUTO_RELOAD,
+ &gpt1_regs_ptr->cr1);
+
+ /* load value for free running */
+ writel(GPT_FREE_RUNNING, &gpt1_regs_ptr->arr);
+
+ /* start timer */
+ writel(readl(&gpt1_regs_ptr->cr1) | GPT_CR1_CEN,
+ &gpt1_regs_ptr->cr1);
+
+ /* Reset the timer */
+ lastdec = READ_TIMER();
+ timestamp = 0;
+
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+ulong get_timer(ulong base)
+{
+ return (get_timer_masked() / GPT_RESOLUTION) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+ ulong tmo;
+ ulong start = get_timer_masked();
+ ulong tenudelcnt = CONFIG_STV0991_HZ_CLOCK / (1000 * 100);
+ ulong rndoff;
+
+ rndoff = (usec % 10) ? 1 : 0;
+
+ /* tenudelcnt timer tick gives 10 microsecconds delay */
+ tmo = ((usec / 10) + rndoff) * tenudelcnt;
+
+ while ((ulong) (get_timer_masked() - start) < tmo)
+ ;
+}
+
+static ulong get_timer_masked(void)
+{
+ ulong now = READ_TIMER();
+
+ if (now >= lastdec) {
+ /* normal mode */
+ timestamp += now - lastdec;
+ } else {
+ /* we have an overflow ... */
+ timestamp += now + GPT_FREE_RUNNING - lastdec;
+ }
+ lastdec = now;
+
+ return timestamp;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return CONFIG_STV0991_HZ;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/sunxi/Makefile b/roms/u-boot/arch/arm/cpu/armv7/sunxi/Makefile
new file mode 100644
index 000000000..1d40d6a18
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/sunxi/Makefile
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
+#
+# Based on some other Makefile
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+obj-y += timer.o
+
+obj-$(CONFIG_MACH_SUN6I) += tzpc.o
+obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o
+
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_ARMV7_PSCI) += psci.o
+endif
+
+ifdef CONFIG_SPL_BUILD
+obj-y += fel_utils.o
+endif
diff --git a/roms/u-boot/arch/arm/cpu/armv7/sunxi/fel_utils.S b/roms/u-boot/arch/arm/cpu/armv7/sunxi/fel_utils.S
new file mode 100644
index 000000000..b2310751d
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/sunxi/fel_utils.S
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Utility functions for FEL mode.
+ *
+ * Copyright (c) 2015 Google, Inc
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/system.h>
+#include <linux/linkage.h>
+
+ENTRY(save_boot_params)
+ ldr r0, =fel_stash
+ str sp, [r0, #0]
+ str lr, [r0, #4]
+ mrs lr, cpsr @ Read CPSR
+ str lr, [r0, #8]
+ mrc p15, 0, lr, c1, c0, 0 @ Read CP15 SCTLR Register
+ str lr, [r0, #12]
+ mrc p15, 0, lr, c12, c0, 0 @ Read VBAR
+ str lr, [r0, #16]
+ mrc p15, 0, lr, c1, c0, 0 @ Read CP15 Control Register
+ str lr, [r0, #20]
+ b save_boot_params_ret
+ENDPROC(save_boot_params)
+
+ENTRY(return_to_fel)
+ mov sp, r0
+ mov lr, r1
+ ldr r0, =fel_stash
+ ldr r1, [r0, #20]
+ mcr p15, 0, r1, c1, c0, 0 @ Write CP15 Control Register
+ ldr r1, [r0, #16]
+ mcr p15, 0, r1, c12, c0, 0 @ Write VBAR
+ ldr r1, [r0, #12]
+ mcr p15, 0, r1, c1, c0, 0 @ Write CP15 SCTLR Register
+ ldr r1, [r0, #8]
+ msr cpsr, r1 @ Write CPSR
+ bx lr
+ENDPROC(return_to_fel)
diff --git a/roms/u-boot/arch/arm/cpu/armv7/sunxi/psci.c b/roms/u-boot/arch/arm/cpu/armv7/sunxi/psci.c
new file mode 100644
index 000000000..1ac50f558
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/sunxi/psci.c
@@ -0,0 +1,313 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016
+ * Author: Chen-Yu Tsai <wens@csie.org>
+ *
+ * Based on assembly code by Marc Zyngier <marc.zyngier@arm.com>,
+ * which was based on code by Carl van Schaik <carl@ok-labs.com>.
+ */
+#include <config.h>
+#include <common.h>
+#include <asm/cache.h>
+
+#include <asm/arch/cpu.h>
+#include <asm/arch/cpucfg.h>
+#include <asm/arch/prcm.h>
+#include <asm/armv7.h>
+#include <asm/gic.h>
+#include <asm/io.h>
+#include <asm/psci.h>
+#include <asm/secure.h>
+#include <asm/system.h>
+
+#include <linux/bitops.h>
+
+#define __irq __attribute__ ((interrupt ("IRQ")))
+
+#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
+#define GICC_BASE (SUNXI_GIC400_BASE + GIC_CPU_OFFSET_A15)
+
+/*
+ * R40 is different from other single cluster SoCs.
+ *
+ * The power clamps are located in the unused space after the per-core
+ * reset controls for core 3. The secondary core entry address register
+ * is in the SRAM controller address range.
+ */
+#define SUN8I_R40_PWROFF (0x110)
+#define SUN8I_R40_PWR_CLAMP(cpu) (0x120 + (cpu) * 0x4)
+#define SUN8I_R40_SRAMC_SOFT_ENTRY_REG0 (0xbc)
+
+static void __secure cp15_write_cntp_tval(u32 tval)
+{
+ asm volatile ("mcr p15, 0, %0, c14, c2, 0" : : "r" (tval));
+}
+
+static void __secure cp15_write_cntp_ctl(u32 val)
+{
+ asm volatile ("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
+}
+
+static u32 __secure cp15_read_cntp_ctl(void)
+{
+ u32 val;
+
+ asm volatile ("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
+
+ return val;
+}
+
+#define ONE_MS (COUNTER_FREQUENCY / 1000)
+
+static void __secure __mdelay(u32 ms)
+{
+ u32 reg = ONE_MS * ms;
+
+ cp15_write_cntp_tval(reg);
+ isb();
+ cp15_write_cntp_ctl(3);
+
+ do {
+ isb();
+ reg = cp15_read_cntp_ctl();
+ } while (!(reg & BIT(2)));
+
+ cp15_write_cntp_ctl(0);
+ isb();
+}
+
+static void __secure clamp_release(u32 __maybe_unused *clamp)
+{
+#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
+ defined(CONFIG_MACH_SUN8I_H3) || \
+ defined(CONFIG_MACH_SUN8I_R40)
+ u32 tmp = 0x1ff;
+ do {
+ tmp >>= 1;
+ writel(tmp, clamp);
+ } while (tmp);
+
+ __mdelay(10);
+#endif
+}
+
+static void __secure clamp_set(u32 __maybe_unused *clamp)
+{
+#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
+ defined(CONFIG_MACH_SUN8I_H3) || \
+ defined(CONFIG_MACH_SUN8I_R40)
+ writel(0xff, clamp);
+#endif
+}
+
+static void __secure sunxi_power_switch(u32 *clamp, u32 *pwroff, bool on,
+ int cpu)
+{
+ if (on) {
+ /* Release power clamp */
+ clamp_release(clamp);
+
+ /* Clear power gating */
+ clrbits_le32(pwroff, BIT(cpu));
+ } else {
+ /* Set power gating */
+ setbits_le32(pwroff, BIT(cpu));
+
+ /* Activate power clamp */
+ clamp_set(clamp);
+ }
+}
+
+#ifdef CONFIG_MACH_SUN8I_R40
+/* secondary core entry address is programmed differently on R40 */
+static void __secure sunxi_set_entry_address(void *entry)
+{
+ writel((u32)entry,
+ SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
+}
+#else
+static void __secure sunxi_set_entry_address(void *entry)
+{
+ struct sunxi_cpucfg_reg *cpucfg =
+ (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+
+ writel((u32)entry, &cpucfg->priv0);
+}
+#endif
+
+#ifdef CONFIG_MACH_SUN7I
+/* sun7i (A20) is different from other single cluster SoCs */
+static void __secure sunxi_cpu_set_power(int __always_unused cpu, bool on)
+{
+ struct sunxi_cpucfg_reg *cpucfg =
+ (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+
+ sunxi_power_switch(&cpucfg->cpu1_pwr_clamp, &cpucfg->cpu1_pwroff,
+ on, 0);
+}
+#elif defined CONFIG_MACH_SUN8I_R40
+static void __secure sunxi_cpu_set_power(int cpu, bool on)
+{
+ struct sunxi_cpucfg_reg *cpucfg =
+ (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+
+ sunxi_power_switch((void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu),
+ (void *)cpucfg + SUN8I_R40_PWROFF,
+ on, 0);
+}
+#else /* ! CONFIG_MACH_SUN7I && ! CONFIG_MACH_SUN8I_R40 */
+static void __secure sunxi_cpu_set_power(int cpu, bool on)
+{
+ struct sunxi_prcm_reg *prcm =
+ (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
+
+ sunxi_power_switch(&prcm->cpu_pwr_clamp[cpu], &prcm->cpu_pwroff,
+ on, cpu);
+}
+#endif /* CONFIG_MACH_SUN7I */
+
+void __secure sunxi_cpu_power_off(u32 cpuid)
+{
+ struct sunxi_cpucfg_reg *cpucfg =
+ (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+ u32 cpu = cpuid & 0x3;
+
+ /* Wait for the core to enter WFI */
+ while (1) {
+ if (readl(&cpucfg->cpu[cpu].status) & BIT(2))
+ break;
+ __mdelay(1);
+ }
+
+ /* Assert reset on target CPU */
+ writel(0, &cpucfg->cpu[cpu].rst);
+
+ /* Lock CPU (Disable external debug access) */
+ clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
+
+ /* Power down CPU */
+ sunxi_cpu_set_power(cpuid, false);
+
+ /* Unlock CPU (Disable external debug access) */
+ setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
+}
+
+static u32 __secure cp15_read_scr(void)
+{
+ u32 scr;
+
+ asm volatile ("mrc p15, 0, %0, c1, c1, 0" : "=r" (scr));
+
+ return scr;
+}
+
+static void __secure cp15_write_scr(u32 scr)
+{
+ asm volatile ("mcr p15, 0, %0, c1, c1, 0" : : "r" (scr));
+ isb();
+}
+
+/*
+ * Although this is an FIQ handler, the FIQ is processed in monitor mode,
+ * which means there's no FIQ banked registers. This is the same as IRQ
+ * mode, so use the IRQ attribute to ask the compiler to handler entry
+ * and return.
+ */
+void __secure __irq psci_fiq_enter(void)
+{
+ u32 scr, reg, cpu;
+
+ /* Switch to secure mode */
+ scr = cp15_read_scr();
+ cp15_write_scr(scr & ~BIT(0));
+
+ /* Validate reason based on IAR and acknowledge */
+ reg = readl(GICC_BASE + GICC_IAR);
+
+ /* Skip spurious interrupts 1022 and 1023 */
+ if (reg == 1023 || reg == 1022)
+ goto out;
+
+ /* End of interrupt */
+ writel(reg, GICC_BASE + GICC_EOIR);
+ dsb();
+
+ /* Get CPU number */
+ cpu = (reg >> 10) & 0x7;
+
+ /* Power off the CPU */
+ sunxi_cpu_power_off(cpu);
+
+out:
+ /* Restore security level */
+ cp15_write_scr(scr);
+}
+
+int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc,
+ u32 context_id)
+{
+ struct sunxi_cpucfg_reg *cpucfg =
+ (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+ u32 cpu = (mpidr & 0x3);
+
+ /* store target PC and context id */
+ psci_save(cpu, pc, context_id);
+
+ /* Set secondary core power on PC */
+ sunxi_set_entry_address(&psci_cpu_entry);
+
+ /* Assert reset on target CPU */
+ writel(0, &cpucfg->cpu[cpu].rst);
+
+ /* Invalidate L1 cache */
+ clrbits_le32(&cpucfg->gen_ctrl, BIT(cpu));
+
+ /* Lock CPU (Disable external debug access) */
+ clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
+
+ /* Power up target CPU */
+ sunxi_cpu_set_power(cpu, true);
+
+ /* De-assert reset on target CPU */
+ writel(BIT(1) | BIT(0), &cpucfg->cpu[cpu].rst);
+
+ /* Unlock CPU (Disable external debug access) */
+ setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
+
+ return ARM_PSCI_RET_SUCCESS;
+}
+
+s32 __secure psci_cpu_off(void)
+{
+ psci_cpu_off_common();
+
+ /* Ask CPU0 via SGI15 to pull the rug... */
+ writel(BIT(16) | 15, GICD_BASE + GICD_SGIR);
+ dsb();
+
+ /* Wait to be turned off */
+ while (1)
+ wfi();
+}
+
+void __secure psci_arch_init(void)
+{
+ u32 reg;
+
+ /* SGI15 as Group-0 */
+ clrbits_le32(GICD_BASE + GICD_IGROUPRn, BIT(15));
+
+ /* Set SGI15 priority to 0 */
+ writeb(0, GICD_BASE + GICD_IPRIORITYRn + 15);
+
+ /* Be cool with non-secure */
+ writel(0xff, GICC_BASE + GICC_PMR);
+
+ /* Switch FIQEn on */
+ setbits_le32(GICC_BASE + GICC_CTLR, BIT(3));
+
+ reg = cp15_read_scr();
+ reg |= BIT(2); /* Enable FIQ in monitor mode */
+ reg &= ~BIT(0); /* Secure mode */
+ cp15_write_scr(reg);
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/sunxi/start.c b/roms/u-boot/arch/arm/cpu/armv7/sunxi/start.c
new file mode 100644
index 000000000..6b392fa83
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/sunxi/start.c
@@ -0,0 +1 @@
+/* Intentionally empty. Only needed to get FEL SPL link line right */
diff --git a/roms/u-boot/arch/arm/cpu/armv7/sunxi/timer.c b/roms/u-boot/arch/arm/cpu/armv7/sunxi/timer.c
new file mode 100644
index 000000000..b75859963
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/sunxi/timer.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/timer.h>
+#include <linux/delay.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TIMER_MODE (0x0 << 7) /* continuous mode */
+#define TIMER_DIV (0x0 << 4) /* pre scale 1 */
+#define TIMER_SRC (0x1 << 2) /* osc24m */
+#define TIMER_RELOAD (0x1 << 1) /* reload internal value */
+#define TIMER_EN (0x1 << 0) /* enable timer */
+
+#define TIMER_CLOCK (24 * 1000 * 1000)
+#define COUNT_TO_USEC(x) ((x) / 24)
+#define USEC_TO_COUNT(x) ((x) * 24)
+#define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ)
+#define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ)
+
+#define TIMER_LOAD_VAL 0xffffffff
+
+#define TIMER_NUM 0 /* we use timer 0 */
+
+/* read the 32-bit timer */
+static ulong read_timer(void)
+{
+ struct sunxi_timer_reg *timers =
+ (struct sunxi_timer_reg *)SUNXI_TIMER_BASE;
+ struct sunxi_timer *timer = &timers->timer[TIMER_NUM];
+
+ /*
+ * The hardware timer counts down, therefore we invert to
+ * produce an incrementing timer.
+ */
+ return ~readl(&timer->val);
+}
+
+/* init timer register */
+int timer_init(void)
+{
+ struct sunxi_timer_reg *timers =
+ (struct sunxi_timer_reg *)SUNXI_TIMER_BASE;
+ struct sunxi_timer *timer = &timers->timer[TIMER_NUM];
+ writel(TIMER_LOAD_VAL, &timer->inter);
+ writel(TIMER_MODE | TIMER_DIV | TIMER_SRC | TIMER_RELOAD | TIMER_EN,
+ &timer->ctl);
+
+ return 0;
+}
+
+/* timer without interrupts */
+static ulong get_timer_masked(void)
+{
+ /* current tick value */
+ ulong now = TICKS_TO_HZ(read_timer());
+
+ if (now >= gd->arch.lastinc) /* normal (non rollover) */
+ gd->arch.tbl += (now - gd->arch.lastinc);
+ else {
+ /* rollover */
+ gd->arch.tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL)
+ - gd->arch.lastinc) + now;
+ }
+ gd->arch.lastinc = now;
+
+ return gd->arch.tbl;
+}
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+/* delay x useconds */
+void __udelay(unsigned long usec)
+{
+ long tmo = USEC_TO_COUNT(usec);
+ ulong now, last = read_timer();
+
+ while (tmo > 0) {
+ now = read_timer();
+ if (now > last) /* normal (non rollover) */
+ tmo -= now - last;
+ else /* rollover */
+ tmo -= TIMER_LOAD_VAL - last + now;
+ last = now;
+ }
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return CONFIG_SYS_HZ;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/sunxi/tzpc.c b/roms/u-boot/arch/arm/cpu/armv7/sunxi/tzpc.c
new file mode 100644
index 000000000..0c86a21a3
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/sunxi/tzpc.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2015 Chen-Yu Tsai <wens@csie.org>
+ */
+
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/tzpc.h>
+
+/* Configure Trust Zone Protection Controller */
+void tzpc_init(void)
+{
+ struct sunxi_tzpc *tzpc = (struct sunxi_tzpc *)SUNXI_TZPC_BASE;
+
+#ifdef CONFIG_MACH_SUN6I
+ /* Enable non-secure access to the RTC */
+ writel(SUN6I_TZPC_DECPORT0_RTC, &tzpc->decport0_set);
+#endif
+
+#ifdef CONFIG_MACH_SUN8I_H3
+ /* Enable non-secure access to all peripherals */
+ writel(SUN8I_H3_TZPC_DECPORT0_ALL, &tzpc->decport0_set);
+ writel(SUN8I_H3_TZPC_DECPORT1_ALL, &tzpc->decport1_set);
+ writel(SUN8I_H3_TZPC_DECPORT2_ALL, &tzpc->decport2_set);
+#endif
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds b/roms/u-boot/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds
new file mode 100644
index 000000000..942c29fc9
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * Based on omap-common/u-boot-spl.lds:
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ * Aneesh V <aneesh@ti.com>
+ */
+MEMORY { .sram : ORIGIN = IMAGE_TEXT_BASE,\
+ LENGTH = IMAGE_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+ LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ .text :
+ {
+ __start = .;
+ *(.vectors)
+ arch/arm/cpu/armv7/start.o (.text)
+ *(.text*)
+ } > .sram
+
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
+
+ . = ALIGN(4);
+ .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
+
+ . = ALIGN(4);
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+ } > .sram
+
+ . = ALIGN(4);
+ __image_copy_end = .;
+ _end = .;
+
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_end = .;
+ } > .sdram
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/syslib.c b/roms/u-boot/arch/arm/cpu/armv7/syslib.c
new file mode 100644
index 000000000..7e2963697
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/syslib.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2008
+ * Texas Instruments, <www.ti.com>
+ *
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Syed Mohammed Khasim <khasim@ti.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+/************************************************************
+ * sdelay() - simple spin loop. Will be constant time as
+ * its generally used in bypass conditions only. This
+ * is necessary until timers are accessible.
+ *
+ * not inline to increase chances its in cache when called
+ *************************************************************/
+void sdelay(unsigned long loops)
+{
+ __asm__ volatile ("1:\n" "subs %0, %1, #1\n"
+ "bne 1b":"=r" (loops):"0"(loops));
+}
+
+/*********************************************************************
+ * wait_on_value() - common routine to allow waiting for changes in
+ * volatile regs.
+ *********************************************************************/
+u32 wait_on_value(u32 read_bit_mask, u32 match_value, void *read_addr,
+ u32 bound)
+{
+ u32 i = 0, val;
+ do {
+ ++i;
+ val = readl((u32)read_addr) & read_bit_mask;
+ if (val == match_value)
+ return 1;
+ if (i == bound)
+ return 0;
+ } while (1);
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/vf610/Kconfig b/roms/u-boot/arch/arm/cpu/armv7/vf610/Kconfig
new file mode 100644
index 000000000..5d485a3ce
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/vf610/Kconfig
@@ -0,0 +1,37 @@
+if ARCH_VF610
+
+config VF610
+ bool
+ default y
+
+choice
+ prompt "Vybrid board select"
+
+config TARGET_VF610TWR
+ bool "TWR-VF65GS10-DS5"
+
+config TARGET_COLIBRI_VF
+ bool "Colibri VF50/61"
+ select BOARD_LATE_INIT
+
+config TARGET_PCM052
+ bool "PCM-052"
+ select SYS_FSL_ERRATUM_ESDHC135
+ select SYS_FSL_ERRATUM_ESDHC_A001
+
+config TARGET_BK4R1
+ bool "BK4r1"
+ select SYS_FSL_ERRATUM_ESDHC135
+ select SYS_FSL_ERRATUM_ESDHC_A001
+ select BOARD_LATE_INIT
+
+endchoice
+
+config SYS_SOC
+ default "vf610"
+
+source "board/freescale/vf610twr/Kconfig"
+source "board/phytec/pcm052/Kconfig"
+source "board/toradex/colibri_vf/Kconfig"
+
+endif
diff --git a/roms/u-boot/arch/arm/cpu/armv7/vf610/Makefile b/roms/u-boot/arch/arm/cpu/armv7/vf610/Makefile
new file mode 100644
index 000000000..b5b479b49
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/vf610/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2013 Freescale Semiconductor, Inc.
+
+obj-y += generic.o
+obj-y += timer.o
+
+MKIMAGEFLAGS_u-boot.vyb = -T vybridimage
+
+u-boot.vyb: u-boot.imx
+ $(call if_changed,mkimage)
diff --git a/roms/u-boot/arch/arm/cpu/armv7/vf610/generic.c b/roms/u-boot/arch/arm/cpu/armv7/vf610/generic.c
new file mode 100644
index 000000000..c23ddc12b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/vf610/generic.c
@@ -0,0 +1,407 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <clock_legacy.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <init.h>
+#include <net.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/mach-imx/sys_proto.h>
+#include <env.h>
+#include <netdev.h>
+#ifdef CONFIG_FSL_ESDHC_IMX
+#include <fsl_esdhc_imx.h>
+#endif
+
+#ifdef CONFIG_FSL_ESDHC_IMX
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
+static char soc_type[] = "xx0";
+
+#ifdef CONFIG_MXC_OCOTP
+void enable_ocotp_clk(unsigned char enable)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+ u32 reg;
+
+ reg = readl(&ccm->ccgr6);
+ if (enable)
+ reg |= CCM_CCGR6_OCOTP_CTRL_MASK;
+ else
+ reg &= ~CCM_CCGR6_OCOTP_CTRL_MASK;
+ writel(reg, &ccm->ccgr6);
+}
+#endif
+
+static u32 get_mcu_main_clk(void)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+ u32 ccm_ccsr, ccm_cacrr, armclk_div;
+ u32 sysclk_sel, pll_pfd_sel = 0;
+ u32 freq = 0;
+
+ ccm_ccsr = readl(&ccm->ccsr);
+ sysclk_sel = ccm_ccsr & CCM_CCSR_SYS_CLK_SEL_MASK;
+ sysclk_sel >>= CCM_CCSR_SYS_CLK_SEL_OFFSET;
+
+ ccm_cacrr = readl(&ccm->cacrr);
+ armclk_div = ccm_cacrr & CCM_CACRR_ARM_CLK_DIV_MASK;
+ armclk_div >>= CCM_CACRR_ARM_CLK_DIV_OFFSET;
+ armclk_div += 1;
+
+ switch (sysclk_sel) {
+ case 0:
+ freq = FASE_CLK_FREQ;
+ break;
+ case 1:
+ freq = SLOW_CLK_FREQ;
+ break;
+ case 2:
+ pll_pfd_sel = ccm_ccsr & CCM_CCSR_PLL2_PFD_CLK_SEL_MASK;
+ pll_pfd_sel >>= CCM_CCSR_PLL2_PFD_CLK_SEL_OFFSET;
+ if (pll_pfd_sel == 0)
+ freq = PLL2_MAIN_FREQ;
+ else if (pll_pfd_sel == 1)
+ freq = PLL2_PFD1_FREQ;
+ else if (pll_pfd_sel == 2)
+ freq = PLL2_PFD2_FREQ;
+ else if (pll_pfd_sel == 3)
+ freq = PLL2_PFD3_FREQ;
+ else if (pll_pfd_sel == 4)
+ freq = PLL2_PFD4_FREQ;
+ break;
+ case 3:
+ freq = PLL2_MAIN_FREQ;
+ break;
+ case 4:
+ pll_pfd_sel = ccm_ccsr & CCM_CCSR_PLL1_PFD_CLK_SEL_MASK;
+ pll_pfd_sel >>= CCM_CCSR_PLL1_PFD_CLK_SEL_OFFSET;
+ if (pll_pfd_sel == 0)
+ freq = PLL1_MAIN_FREQ;
+ else if (pll_pfd_sel == 1)
+ freq = PLL1_PFD1_FREQ;
+ else if (pll_pfd_sel == 2)
+ freq = PLL1_PFD2_FREQ;
+ else if (pll_pfd_sel == 3)
+ freq = PLL1_PFD3_FREQ;
+ else if (pll_pfd_sel == 4)
+ freq = PLL1_PFD4_FREQ;
+ break;
+ case 5:
+ freq = PLL3_MAIN_FREQ;
+ break;
+ default:
+ printf("unsupported system clock select\n");
+ }
+
+ return freq / armclk_div;
+}
+
+static u32 get_bus_clk(void)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+ u32 ccm_cacrr, busclk_div;
+
+ ccm_cacrr = readl(&ccm->cacrr);
+
+ busclk_div = ccm_cacrr & CCM_CACRR_BUS_CLK_DIV_MASK;
+ busclk_div >>= CCM_CACRR_BUS_CLK_DIV_OFFSET;
+ busclk_div += 1;
+
+ return get_mcu_main_clk() / busclk_div;
+}
+
+static u32 get_ipg_clk(void)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+ u32 ccm_cacrr, ipgclk_div;
+
+ ccm_cacrr = readl(&ccm->cacrr);
+
+ ipgclk_div = ccm_cacrr & CCM_CACRR_IPG_CLK_DIV_MASK;
+ ipgclk_div >>= CCM_CACRR_IPG_CLK_DIV_OFFSET;
+ ipgclk_div += 1;
+
+ return get_bus_clk() / ipgclk_div;
+}
+
+static u32 get_uart_clk(void)
+{
+ return get_ipg_clk();
+}
+
+static u32 get_sdhc_clk(void)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+ u32 ccm_cscmr1, ccm_cscdr2, sdhc_clk_sel, sdhc_clk_div;
+ u32 freq = 0;
+
+ ccm_cscmr1 = readl(&ccm->cscmr1);
+ sdhc_clk_sel = ccm_cscmr1 & CCM_CSCMR1_ESDHC1_CLK_SEL_MASK;
+ sdhc_clk_sel >>= CCM_CSCMR1_ESDHC1_CLK_SEL_OFFSET;
+
+ ccm_cscdr2 = readl(&ccm->cscdr2);
+ sdhc_clk_div = ccm_cscdr2 & CCM_CSCDR2_ESDHC1_CLK_DIV_MASK;
+ sdhc_clk_div >>= CCM_CSCDR2_ESDHC1_CLK_DIV_OFFSET;
+ sdhc_clk_div += 1;
+
+ switch (sdhc_clk_sel) {
+ case 0:
+ freq = PLL3_MAIN_FREQ;
+ break;
+ case 1:
+ freq = PLL3_PFD3_FREQ;
+ break;
+ case 2:
+ freq = PLL1_PFD3_FREQ;
+ break;
+ case 3:
+ freq = get_bus_clk();
+ break;
+ }
+
+ return freq / sdhc_clk_div;
+}
+
+u32 get_fec_clk(void)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+ u32 ccm_cscmr2, rmii_clk_sel;
+ u32 freq = 0;
+
+ ccm_cscmr2 = readl(&ccm->cscmr2);
+ rmii_clk_sel = ccm_cscmr2 & CCM_CSCMR2_RMII_CLK_SEL_MASK;
+ rmii_clk_sel >>= CCM_CSCMR2_RMII_CLK_SEL_OFFSET;
+
+ switch (rmii_clk_sel) {
+ case 0:
+ freq = ENET_EXTERNAL_CLK;
+ break;
+ case 1:
+ freq = AUDIO_EXTERNAL_CLK;
+ break;
+ case 2:
+ freq = PLL5_MAIN_FREQ;
+ break;
+ case 3:
+ freq = PLL5_MAIN_FREQ / 2;
+ break;
+ }
+
+ return freq;
+}
+
+static u32 get_i2c_clk(void)
+{
+ return get_ipg_clk();
+}
+
+static u32 get_dspi_clk(void)
+{
+ return get_ipg_clk();
+}
+
+u32 get_lpuart_clk(void)
+{
+ return get_uart_clk();
+}
+
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+ switch (clk) {
+ case MXC_ARM_CLK:
+ return get_mcu_main_clk();
+ case MXC_BUS_CLK:
+ return get_bus_clk();
+ case MXC_IPG_CLK:
+ return get_ipg_clk();
+ case MXC_UART_CLK:
+ return get_uart_clk();
+ case MXC_ESDHC_CLK:
+ return get_sdhc_clk();
+ case MXC_FEC_CLK:
+ return get_fec_clk();
+ case MXC_I2C_CLK:
+ return get_i2c_clk();
+ case MXC_DSPI_CLK:
+ return get_dspi_clk();
+ default:
+ break;
+ }
+ return -1;
+}
+
+/* Dump some core clocks */
+int do_vf610_showclocks(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ printf("\n");
+ printf("cpu clock : %8d MHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ printf("bus clock : %8d MHz\n", mxc_get_clock(MXC_BUS_CLK) / 1000000);
+ printf("ipg clock : %8d MHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000000);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ clocks, CONFIG_SYS_MAXARGS, 1, do_vf610_showclocks,
+ "display clocks",
+ ""
+);
+
+#ifdef CONFIG_FEC_MXC
+__weak void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+ struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+ struct fuse_bank *bank = &ocotp->bank[4];
+ struct fuse_bank4_regs *fuse =
+ (struct fuse_bank4_regs *)bank->fuse_regs;
+
+ u32 value = readl(&fuse->mac_addr0);
+ mac[0] = (value >> 8);
+ mac[1] = value;
+
+ value = readl(&fuse->mac_addr1);
+ mac[2] = value >> 24;
+ mac[3] = value >> 16;
+ mac[4] = value >> 8;
+ mac[5] = value;
+}
+#endif
+
+u32 get_cpu_rev(void)
+{
+ return MXC_CPU_VF610 << 12;
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+static char *get_reset_cause(void)
+{
+ u32 cause;
+ struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+
+ cause = readl(&src_regs->srsr);
+ writel(cause, &src_regs->srsr);
+
+ if (cause & SRC_SRSR_POR_RST)
+ return "POWER ON RESET";
+ else if (cause & SRC_SRSR_WDOG_A5)
+ return "WDOG A5";
+ else if (cause & SRC_SRSR_WDOG_M4)
+ return "WDOG M4";
+ else if (cause & SRC_SRSR_JTAG_RST)
+ return "JTAG HIGH-Z";
+ else if (cause & SRC_SRSR_SW_RST)
+ return "SW RESET";
+ else if (cause & SRC_SRSR_RESETB)
+ return "EXTERNAL RESET";
+ else
+ return "unknown reset";
+}
+
+int print_cpuinfo(void)
+{
+ printf("CPU: Freescale Vybrid VF%s at %d MHz\n",
+ soc_type, mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ printf("Reset cause: %s\n", get_reset_cause());
+
+ return 0;
+}
+#endif
+
+int arch_cpu_init(void)
+{
+ struct mscm *mscm = (struct mscm *)MSCM_BASE_ADDR;
+
+ soc_type[0] = mscm->cpxcount ? '6' : '5'; /*Dual Core => VF6x0 */
+ soc_type[1] = mscm->cpxcfg1 ? '1' : '0'; /* L2 Cache => VFx10 */
+
+ return 0;
+}
+
+#ifdef CONFIG_ARCH_MISC_INIT
+int arch_misc_init(void)
+{
+ char soc[6];
+
+ strcpy(soc, "vf");
+ strcat(soc, soc_type);
+ env_set("soc", soc);
+
+ return 0;
+}
+#endif
+
+int cpu_eth_init(struct bd_info *bis)
+{
+ int rc = -ENODEV;
+
+#if defined(CONFIG_FEC_MXC)
+ rc = fecmxc_initialize(bis);
+#endif
+
+ return rc;
+}
+
+#ifdef CONFIG_FSL_ESDHC_IMX
+int cpu_mmc_init(struct bd_info *bis)
+{
+ return fsl_esdhc_mmc_init(bis);
+}
+#endif
+
+int get_clocks(void)
+{
+#ifdef CONFIG_FSL_ESDHC_IMX
+ gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+#endif
+ return 0;
+}
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+void enable_caches(void)
+{
+#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+ enum dcache_option option = DCACHE_WRITETHROUGH;
+#else
+ enum dcache_option option = DCACHE_WRITEBACK;
+#endif
+ dcache_enable();
+ icache_enable();
+
+ /* Enable caching on OCRAM */
+ mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR, IRAM_SIZE, option);
+}
+#endif
+
+#ifdef CONFIG_SYS_I2C_MXC
+/* i2c_num can be from 0 - 3 */
+int enable_i2c_clk(unsigned char enable, unsigned int i2c_num)
+{
+ struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
+
+ switch (i2c_num) {
+ case 0:
+ clrsetbits_le32(&ccm->ccgr4, CCM_CCGR4_I2C0_CTRL_MASK,
+ CCM_CCGR4_I2C0_CTRL_MASK);
+ case 2:
+ clrsetbits_le32(&ccm->ccgr10, CCM_CCGR10_I2C2_CTRL_MASK,
+ CCM_CCGR10_I2C2_CTRL_MASK);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv7/vf610/timer.c b/roms/u-boot/arch/arm/cpu/armv7/vf610/timer.c
new file mode 100644
index 000000000..a9c1a8fce
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/vf610/timer.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <div64.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/clock.h>
+#include <linux/delay.h>
+
+static struct pit_reg *cur_pit = (struct pit_reg *)PIT_BASE_ADDR;
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TIMER_LOAD_VAL 0xffffffff
+
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, mxc_get_clock(MXC_IPG_CLK));
+
+ return tick;
+}
+
+static inline unsigned long long us_to_tick(unsigned long long usec)
+{
+ usec = usec * mxc_get_clock(MXC_IPG_CLK) + 999999;
+ do_div(usec, 1000000);
+
+ return usec;
+}
+
+int timer_init(void)
+{
+ __raw_writel(0, &cur_pit->mcr);
+
+ __raw_writel(TIMER_LOAD_VAL, &cur_pit->ldval1);
+ __raw_writel(0, &cur_pit->tctrl1);
+ __raw_writel(1, &cur_pit->tctrl1);
+
+ gd->arch.tbl = 0;
+ gd->arch.tbu = 0;
+
+ return 0;
+}
+
+unsigned long long get_ticks(void)
+{
+ ulong now = TIMER_LOAD_VAL - __raw_readl(&cur_pit->cval1);
+
+ /* increment tbu if tbl has rolled over */
+ if (now < gd->arch.tbl)
+ gd->arch.tbu++;
+ gd->arch.tbl = now;
+
+ return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
+}
+
+ulong get_timer(ulong base)
+{
+ return tick_to_time(get_ticks()) - base;
+}
+
+/* delay x useconds AND preserve advance timstamp value */
+void __udelay(unsigned long usec)
+{
+ unsigned long long start;
+ ulong tmo;
+
+ start = get_ticks(); /* get current timestamp */
+ tmo = us_to_tick(usec); /* convert usecs to ticks */
+ while ((get_ticks() - start) < tmo)
+ ; /* loop till time has passed */
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return mxc_get_clock(MXC_IPG_CLK);
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/virt-dt.c b/roms/u-boot/arch/arm/cpu/armv7/virt-dt.c
new file mode 100644
index 000000000..c0422485b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/virt-dt.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <log.h>
+#include <stdio_dev.h>
+#include <linux/ctype.h>
+#include <linux/types.h>
+#include <linux/libfdt.h>
+#include <fdt_support.h>
+#include <asm/armv7.h>
+#include <asm/psci.h>
+
+int armv7_apply_memory_carveout(u64 *start, u64 *size)
+{
+#ifdef CONFIG_ARMV7_SECURE_RESERVE_SIZE
+ if (*start + *size < CONFIG_ARMV7_SECURE_BASE ||
+ *start >= (u64)CONFIG_ARMV7_SECURE_BASE +
+ CONFIG_ARMV7_SECURE_RESERVE_SIZE)
+ return 0;
+
+ /* carveout must be at the beginning or the end of the bank */
+ if (*start == CONFIG_ARMV7_SECURE_BASE ||
+ *start + *size == (u64)CONFIG_ARMV7_SECURE_BASE +
+ CONFIG_ARMV7_SECURE_RESERVE_SIZE) {
+ if (*size < CONFIG_ARMV7_SECURE_RESERVE_SIZE) {
+ debug("Secure monitor larger than RAM bank!?\n");
+ return -EINVAL;
+ }
+ *size -= CONFIG_ARMV7_SECURE_RESERVE_SIZE;
+ if (*start == CONFIG_ARMV7_SECURE_BASE)
+ *start += CONFIG_ARMV7_SECURE_RESERVE_SIZE;
+ return 0;
+ }
+ debug("Secure monitor not located at beginning or end of RAM bank\n");
+ return -EINVAL;
+#else /* !CONFIG_ARMV7_SECURE_RESERVE_SIZE */
+ return 0;
+#endif
+}
+
+int psci_update_dt(void *fdt)
+{
+#ifdef CONFIG_ARMV7_NONSEC
+ if (!armv7_boot_nonsec())
+ return 0;
+#endif
+#ifndef CONFIG_ARMV7_SECURE_BASE
+ /* secure code lives in RAM, keep it alive */
+ fdt_add_mem_rsv(fdt, (unsigned long)__secure_start,
+ __secure_end - __secure_start);
+#endif
+
+ return fdt_psci(fdt);
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7/virt-v7.c b/roms/u-boot/arch/arm/cpu/armv7/virt-v7.c
new file mode 100644
index 000000000..5ffeca13d
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7/virt-v7.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2013
+ * Andre Przywara, Linaro <andre.przywara@linaro.org>
+ *
+ * Routines to transition ARMv7 processors from secure into non-secure state
+ * and from non-secure SVC into HYP mode
+ * needed to enable ARMv7 virtualization for current hypervisors
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/armv7.h>
+#include <asm/cache.h>
+#include <asm/gic.h>
+#include <asm/io.h>
+#include <asm/secure.h>
+
+static unsigned int read_id_pfr1(void)
+{
+ unsigned int reg;
+
+ asm("mrc p15, 0, %0, c0, c1, 1\n" : "=r"(reg));
+ return reg;
+}
+
+static unsigned long get_gicd_base_address(void)
+{
+#ifdef CONFIG_ARM_GIC_BASE_ADDRESS
+ return CONFIG_ARM_GIC_BASE_ADDRESS + GIC_DIST_OFFSET;
+#else
+ unsigned periphbase;
+
+ /* get the GIC base address from the CBAR register */
+ asm("mrc p15, 4, %0, c15, c0, 0\n" : "=r" (periphbase));
+
+ /* the PERIPHBASE can be mapped above 4 GB (lower 8 bits used to
+ * encode this). Bail out here since we cannot access this without
+ * enabling paging.
+ */
+ if ((periphbase & 0xff) != 0) {
+ printf("nonsec: PERIPHBASE is above 4 GB, no access.\n");
+ return -1;
+ }
+
+ return (periphbase & CBAR_MASK) + GIC_DIST_OFFSET;
+#endif
+}
+
+/* Define a specific version of this function to enable any available
+ * hardware protections for the reserved region */
+void __weak protect_secure_section(void) {}
+
+static void relocate_secure_section(void)
+{
+#ifdef CONFIG_ARMV7_SECURE_BASE
+ size_t sz = __secure_end - __secure_start;
+ unsigned long szflush = ALIGN(sz + 1, CONFIG_SYS_CACHELINE_SIZE);
+
+ memcpy((void *)CONFIG_ARMV7_SECURE_BASE, __secure_start, sz);
+
+ flush_dcache_range(CONFIG_ARMV7_SECURE_BASE,
+ CONFIG_ARMV7_SECURE_BASE + szflush);
+ protect_secure_section();
+ invalidate_icache_all();
+#endif
+}
+
+static void kick_secondary_cpus_gic(unsigned long gicdaddr)
+{
+ /* kick all CPUs (except this one) by writing to GICD_SGIR */
+ writel(1U << 24, gicdaddr + GICD_SGIR);
+}
+
+void __weak smp_kick_all_cpus(void)
+{
+ unsigned long gic_dist_addr;
+
+ gic_dist_addr = get_gicd_base_address();
+ if (gic_dist_addr == -1)
+ return;
+
+ kick_secondary_cpus_gic(gic_dist_addr);
+}
+
+__weak void psci_board_init(void)
+{
+}
+
+int armv7_init_nonsec(void)
+{
+ unsigned int reg;
+ unsigned itlinesnr, i;
+ unsigned long gic_dist_addr;
+
+ /* check whether the CPU supports the security extensions */
+ reg = read_id_pfr1();
+ if ((reg & 0xF0) == 0) {
+ printf("nonsec: Security extensions not implemented.\n");
+ return -1;
+ }
+
+ /* the SCR register will be set directly in the monitor mode handler,
+ * according to the spec one should not tinker with it in secure state
+ * in SVC mode. Do not try to read it once in non-secure state,
+ * any access to it will trap.
+ */
+
+ gic_dist_addr = get_gicd_base_address();
+ if (gic_dist_addr == -1)
+ return -1;
+
+ /* enable the GIC distributor */
+ writel(readl(gic_dist_addr + GICD_CTLR) | 0x03,
+ gic_dist_addr + GICD_CTLR);
+
+ /* TYPER[4:0] contains an encoded number of available interrupts */
+ itlinesnr = readl(gic_dist_addr + GICD_TYPER) & 0x1f;
+
+ /* set all bits in the GIC group registers to one to allow access
+ * from non-secure state. The first 32 interrupts are private per
+ * CPU and will be set later when enabling the GIC for each core
+ */
+ for (i = 1; i <= itlinesnr; i++)
+ writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i);
+
+ psci_board_init();
+
+ /*
+ * Relocate secure section before any cpu runs in secure ram.
+ * smp_kick_all_cpus may enable other cores and runs into secure
+ * ram, so need to relocate secure section before enabling other
+ * cores.
+ */
+ relocate_secure_section();
+
+#ifndef CONFIG_ARMV7_PSCI
+ smp_set_core_boot_addr((unsigned long)secure_ram_addr(_smp_pen), -1);
+ smp_kick_all_cpus();
+#endif
+
+ /* call the non-sec switching code on this CPU also */
+ secure_ram_addr(_nonsec_init)();
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7m/Makefile b/roms/u-boot/arch/arm/cpu/armv7m/Makefile
new file mode 100644
index 000000000..baeac9343
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7m/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+extra-y := start.o
+obj-y += cpu.o cache.o
+obj-$(CONFIG_SYS_ARM_MPU) += mpu.o
+obj-$(CONFIG_SYS_ARCH_TIMER) += systick-timer.o
diff --git a/roms/u-boot/arch/arm/cpu/armv7m/cache.c b/roms/u-boot/arch/arm/cpu/armv7m/cache.c
new file mode 100644
index 000000000..d1aecf6a8
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7m/cache.c
@@ -0,0 +1,373 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
+ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <errno.h>
+#include <log.h>
+#include <asm/armv7m.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+
+/* Cache maintenance operation registers */
+
+#define V7M_CACHE_REG_ICIALLU ((u32 *)(V7M_CACHE_MAINT_BASE + 0x00))
+#define INVAL_ICACHE_POU 0
+#define V7M_CACHE_REG_ICIMVALU ((u32 *)(V7M_CACHE_MAINT_BASE + 0x08))
+#define V7M_CACHE_REG_DCIMVAC ((u32 *)(V7M_CACHE_MAINT_BASE + 0x0C))
+#define V7M_CACHE_REG_DCISW ((u32 *)(V7M_CACHE_MAINT_BASE + 0x10))
+#define V7M_CACHE_REG_DCCMVAU ((u32 *)(V7M_CACHE_MAINT_BASE + 0x14))
+#define V7M_CACHE_REG_DCCMVAC ((u32 *)(V7M_CACHE_MAINT_BASE + 0x18))
+#define V7M_CACHE_REG_DCCSW ((u32 *)(V7M_CACHE_MAINT_BASE + 0x1C))
+#define V7M_CACHE_REG_DCCIMVAC ((u32 *)(V7M_CACHE_MAINT_BASE + 0x20))
+#define V7M_CACHE_REG_DCCISW ((u32 *)(V7M_CACHE_MAINT_BASE + 0x24))
+#define WAYS_SHIFT 30
+#define SETS_SHIFT 5
+
+/* armv7m processor feature registers */
+
+#define V7M_PROC_REG_CLIDR ((u32 *)(V7M_PROC_FTR_BASE + 0x00))
+#define V7M_PROC_REG_CTR ((u32 *)(V7M_PROC_FTR_BASE + 0x04))
+#define V7M_PROC_REG_CCSIDR ((u32 *)(V7M_PROC_FTR_BASE + 0x08))
+#define MASK_NUM_WAYS GENMASK(12, 3)
+#define MASK_NUM_SETS GENMASK(27, 13)
+#define CLINE_SIZE_MASK GENMASK(2, 0)
+#define NUM_WAYS_SHIFT 3
+#define NUM_SETS_SHIFT 13
+#define V7M_PROC_REG_CSSELR ((u32 *)(V7M_PROC_FTR_BASE + 0x0C))
+#define SEL_I_OR_D BIT(0)
+
+enum cache_type {
+ DCACHE,
+ ICACHE,
+};
+
+/* PoU : Point of Unification, Poc: Point of Coherency */
+enum cache_action {
+ INVALIDATE_POU, /* i-cache invalidate by address */
+ INVALIDATE_POC, /* d-cache invalidate by address */
+ INVALIDATE_SET_WAY, /* d-cache invalidate by sets/ways */
+ FLUSH_POU, /* d-cache clean by address to the PoU */
+ FLUSH_POC, /* d-cache clean by address to the PoC */
+ FLUSH_SET_WAY, /* d-cache clean by sets/ways */
+ FLUSH_INVAL_POC, /* d-cache clean & invalidate by addr to PoC */
+ FLUSH_INVAL_SET_WAY, /* d-cache clean & invalidate by set/ways */
+};
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+struct dcache_config {
+ u32 ways;
+ u32 sets;
+};
+
+static void get_cache_ways_sets(struct dcache_config *cache)
+{
+ u32 cache_size_id = readl(V7M_PROC_REG_CCSIDR);
+
+ cache->ways = (cache_size_id & MASK_NUM_WAYS) >> NUM_WAYS_SHIFT;
+ cache->sets = (cache_size_id & MASK_NUM_SETS) >> NUM_SETS_SHIFT;
+}
+
+/*
+ * Return the io register to perform required cache action like clean or clean
+ * & invalidate by sets/ways.
+ */
+static u32 *get_action_reg_set_ways(enum cache_action action)
+{
+ switch (action) {
+ case INVALIDATE_SET_WAY:
+ return V7M_CACHE_REG_DCISW;
+ case FLUSH_SET_WAY:
+ return V7M_CACHE_REG_DCCSW;
+ case FLUSH_INVAL_SET_WAY:
+ return V7M_CACHE_REG_DCCISW;
+ default:
+ break;
+ };
+
+ return NULL;
+}
+
+/*
+ * Return the io register to perform required cache action like clean or clean
+ * & invalidate by adddress or range.
+ */
+static u32 *get_action_reg_range(enum cache_action action)
+{
+ switch (action) {
+ case INVALIDATE_POU:
+ return V7M_CACHE_REG_ICIMVALU;
+ case INVALIDATE_POC:
+ return V7M_CACHE_REG_DCIMVAC;
+ case FLUSH_POU:
+ return V7M_CACHE_REG_DCCMVAU;
+ case FLUSH_POC:
+ return V7M_CACHE_REG_DCCMVAC;
+ case FLUSH_INVAL_POC:
+ return V7M_CACHE_REG_DCCIMVAC;
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+static u32 get_cline_size(enum cache_type type)
+{
+ u32 size;
+
+ if (type == DCACHE)
+ clrbits_le32(V7M_PROC_REG_CSSELR, BIT(SEL_I_OR_D));
+ else if (type == ICACHE)
+ setbits_le32(V7M_PROC_REG_CSSELR, BIT(SEL_I_OR_D));
+ /* Make sure cache selection is effective for next memory access */
+ dsb();
+
+ size = readl(V7M_PROC_REG_CCSIDR) & CLINE_SIZE_MASK;
+ /* Size enocoded as 2 less than log(no_of_words_in_cache_line) base 2 */
+ size = 1 << (size + 2);
+ debug("cache line size is %d\n", size);
+
+ return size;
+}
+
+/* Perform the action like invalidate/clean on a range of cache addresses */
+static int action_cache_range(enum cache_action action, u32 start_addr,
+ int64_t size)
+{
+ u32 cline_size;
+ u32 *action_reg;
+ enum cache_type type;
+
+ action_reg = get_action_reg_range(action);
+ if (!action_reg)
+ return -EINVAL;
+ if (action == INVALIDATE_POU)
+ type = ICACHE;
+ else
+ type = DCACHE;
+
+ /* Cache line size is minium size for the cache action */
+ cline_size = get_cline_size(type);
+ /* Align start address to cache line boundary */
+ start_addr &= ~(cline_size - 1);
+ debug("total size for cache action = %llx\n", size);
+ do {
+ writel(start_addr, action_reg);
+ size -= cline_size;
+ start_addr += cline_size;
+ } while (size > cline_size);
+
+ /* Make sure cache action is effective for next memory access */
+ dsb();
+ isb(); /* Make sure instruction stream sees it */
+ debug("cache action on range done\n");
+
+ return 0;
+}
+
+/* Perform the action like invalidate/clean on all cached addresses */
+static int action_dcache_all(enum cache_action action)
+{
+ struct dcache_config cache;
+ u32 *action_reg;
+ int i, j;
+
+ action_reg = get_action_reg_set_ways(action);
+ if (!action_reg)
+ return -EINVAL;
+
+ clrbits_le32(V7M_PROC_REG_CSSELR, BIT(SEL_I_OR_D));
+ /* Make sure cache selection is effective for next memory access */
+ dsb();
+
+ get_cache_ways_sets(&cache); /* Get number of ways & sets */
+ debug("cache: ways= %d, sets= %d\n", cache.ways + 1, cache.sets + 1);
+ for (i = cache.sets; i >= 0; i--) {
+ for (j = cache.ways; j >= 0; j--) {
+ writel((j << WAYS_SHIFT) | (i << SETS_SHIFT),
+ action_reg);
+ }
+ }
+
+ /* Make sure cache action is effective for next memory access */
+ dsb();
+ isb(); /* Make sure instruction stream sees it */
+
+ return 0;
+}
+
+void dcache_enable(void)
+{
+ if (dcache_status()) /* return if cache already enabled */
+ return;
+
+ if (action_dcache_all(INVALIDATE_SET_WAY)) {
+ printf("ERR: D-cache not enabled\n");
+ return;
+ }
+
+ setbits_le32(&V7M_SCB->ccr, BIT(V7M_CCR_DCACHE));
+
+ /* Make sure cache action is effective for next memory access */
+ dsb();
+ isb(); /* Make sure instruction stream sees it */
+}
+
+void dcache_disable(void)
+{
+ if (!dcache_status())
+ return;
+
+ /* if dcache is enabled-> dcache disable & then flush */
+ if (action_dcache_all(FLUSH_SET_WAY)) {
+ printf("ERR: D-cache not flushed\n");
+ return;
+ }
+
+ clrbits_le32(&V7M_SCB->ccr, BIT(V7M_CCR_DCACHE));
+
+ /* Make sure cache action is effective for next memory access */
+ dsb();
+ isb(); /* Make sure instruction stream sees it */
+}
+
+int dcache_status(void)
+{
+ return (readl(&V7M_SCB->ccr) & BIT(V7M_CCR_DCACHE)) != 0;
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+ if (action_cache_range(INVALIDATE_POC, start, stop - start)) {
+ printf("ERR: D-cache not invalidated\n");
+ return;
+ }
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+ if (action_cache_range(FLUSH_POC, start, stop - start)) {
+ printf("ERR: D-cache not flushed\n");
+ return;
+ }
+}
+void flush_dcache_all(void)
+{
+ if (action_dcache_all(FLUSH_SET_WAY)) {
+ printf("ERR: D-cache not flushed\n");
+ return;
+ }
+}
+
+void invalidate_dcache_all(void)
+{
+ if (action_dcache_all(INVALIDATE_SET_WAY)) {
+ printf("ERR: D-cache not invalidated\n");
+ return;
+ }
+}
+#else
+void dcache_enable(void)
+{
+ return;
+}
+
+void dcache_disable(void)
+{
+ return;
+}
+
+int dcache_status(void)
+{
+ return 0;
+}
+
+void flush_dcache_all(void)
+{
+}
+
+void invalidate_dcache_all(void)
+{
+}
+
+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
+ enum dcache_option option)
+{
+}
+
+#endif
+
+#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
+
+void invalidate_icache_all(void)
+{
+ writel(INVAL_ICACHE_POU, V7M_CACHE_REG_ICIALLU);
+
+ /* Make sure cache action is effective for next memory access */
+ dsb();
+ isb(); /* Make sure instruction stream sees it */
+}
+
+void icache_enable(void)
+{
+ if (icache_status())
+ return;
+
+ invalidate_icache_all();
+ setbits_le32(&V7M_SCB->ccr, BIT(V7M_CCR_ICACHE));
+
+ /* Make sure cache action is effective for next memory access */
+ dsb();
+ isb(); /* Make sure instruction stream sees it */
+}
+
+int icache_status(void)
+{
+ return (readl(&V7M_SCB->ccr) & BIT(V7M_CCR_ICACHE)) != 0;
+}
+
+void icache_disable(void)
+{
+ if (!icache_status())
+ return;
+
+ isb(); /* flush pipeline */
+ clrbits_le32(&V7M_SCB->ccr, BIT(V7M_CCR_ICACHE));
+ isb(); /* subsequent instructions fetch see cache disable effect */
+}
+#else
+void invalidate_icache_all(void)
+{
+ return;
+}
+
+void icache_enable(void)
+{
+ return;
+}
+
+void icache_disable(void)
+{
+ return;
+}
+
+int icache_status(void)
+{
+ return 0;
+}
+#endif
+
+void enable_caches(void)
+{
+#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
+ icache_enable();
+#endif
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+ dcache_enable();
+#endif
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7m/config.mk b/roms/u-boot/arch/arm/cpu/armv7m/config.mk
new file mode 100644
index 000000000..f50964cfb
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7m/config.mk
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2015
+# Kamil Lulko, <kamil.lulko@gmail.com>
+
+PLATFORM_CPPFLAGS += -mno-unaligned-access
diff --git a/roms/u-boot/arch/arm/cpu/armv7m/cpu.c b/roms/u-boot/arch/arm/cpu/armv7m/cpu.c
new file mode 100644
index 000000000..63721018c
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7m/cpu.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2010,2011
+ * Vladimir Khusainov, Emcraft Systems, vlad@emcraft.com
+ *
+ * (C) Copyright 2015
+ * Kamil Lulko, <kamil.lulko@gmail.com>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <irq_func.h>
+#include <asm/io.h>
+#include <asm/armv7m.h>
+
+/*
+ * This is called right before passing control to
+ * the Linux kernel point.
+ */
+int cleanup_before_linux(void)
+{
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * disable interrupt and turn off caches etc ...
+ */
+ disable_interrupts();
+ /*
+ * turn off D-cache
+ * dcache_disable() in turn flushes the d-cache
+ * MPU is still enabled & can't be disabled as the u-boot
+ * code might be running in sdram which by default is not
+ * executable area.
+ */
+ dcache_disable();
+ /* invalidate to make sure no cache line gets dirty between
+ * dcache flushing and disabling dcache */
+ invalidate_dcache_all();
+
+ icache_disable();
+ invalidate_icache_all();
+
+ return 0;
+}
+
+/*
+ * Perform the low-level reset.
+ */
+void reset_cpu(void)
+{
+ /*
+ * Perform reset but keep priority group unchanged.
+ */
+ writel((V7M_AIRCR_VECTKEY << V7M_AIRCR_VECTKEY_SHIFT)
+ | (V7M_SCB->aircr & V7M_AIRCR_PRIGROUP_MSK)
+ | V7M_AIRCR_SYSRESET, &V7M_SCB->aircr);
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7m/mpu.c b/roms/u-boot/arch/arm/cpu/armv7m/mpu.c
new file mode 100644
index 000000000..81e7492f1
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7m/mpu.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
+ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
+ */
+
+#include <linux/bitops.h>
+#include <asm/armv7m.h>
+#include <asm/armv7_mpu.h>
+#include <asm/io.h>
+
+#define V7M_MPU_CTRL_ENABLE BIT(0)
+#define V7M_MPU_CTRL_DISABLE (0 << 0)
+#define V7M_MPU_CTRL_HFNMIENA BIT(1)
+#define V7M_MPU_CTRL_PRIVDEFENA BIT(2)
+#define VALID_REGION BIT(4)
+
+void disable_mpu(void)
+{
+ writel(0, &V7M_MPU->ctrl);
+}
+
+void enable_mpu(void)
+{
+ writel(V7M_MPU_CTRL_ENABLE | V7M_MPU_CTRL_PRIVDEFENA, &V7M_MPU->ctrl);
+
+ /* Make sure new mpu config is effective for next memory access */
+ dsb();
+ isb(); /* Make sure instruction stream sees it */
+}
+
+void mpu_config(struct mpu_region_config *reg_config)
+{
+ uint32_t attr;
+
+ attr = get_attr_encoding(reg_config->mr_attr);
+
+ writel(reg_config->start_addr | VALID_REGION | reg_config->region_no,
+ &V7M_MPU->rbar);
+
+ writel(reg_config->xn << XN_SHIFT | reg_config->ap << AP_SHIFT | attr
+ | reg_config->reg_size << REGION_SIZE_SHIFT | ENABLE_REGION
+ , &V7M_MPU->rasr);
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv7m/start.S b/roms/u-boot/arch/arm/cpu/armv7m/start.S
new file mode 100644
index 000000000..0c07f2140
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7m/start.S
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2015
+ * Kamil Lulko, <kamil.lulko@gmail.com>
+ */
+
+#include <asm/assembler.h>
+
+.globl reset
+.type reset, %function
+reset:
+ W(b) _main
+
+.globl c_runtime_cpu_setup
+c_runtime_cpu_setup:
+ mov pc, lr
diff --git a/roms/u-boot/arch/arm/cpu/armv7m/systick-timer.c b/roms/u-boot/arch/arm/cpu/armv7m/systick-timer.c
new file mode 100644
index 000000000..556eaf8c7
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv7m/systick-timer.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * ARM Cortex M3/M4/M7 SysTick timer driver
+ * (C) Copyright 2017 Renesas Electronics Europe Ltd
+ *
+ * Based on arch/arm/mach-stm32/stm32f1/timer.c
+ * (C) Copyright 2015
+ * Kamil Lulko, <kamil.lulko@gmail.com>
+ *
+ * Copyright 2015 ATS Advanced Telematics Systems GmbH
+ * Copyright 2015 Konsulko Group, Matt Porter <mporter@konsulko.com>
+ *
+ * The SysTick timer is a 24-bit count down timer. The clock can be either the
+ * CPU clock or a reference clock. Since the timer will wrap around very quickly
+ * when using the CPU clock, and we do not handle the timer interrupts, it is
+ * expected that this driver is only ever used with a slow reference clock.
+ *
+ * The number of reference clock ticks that correspond to 10ms is normally
+ * defined in the SysTick Calibration register's TENMS field. However, on some
+ * devices this is wrong, so this driver allows the clock rate to be defined
+ * using CONFIG_SYS_HZ_CLOCK.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* SysTick Base Address - fixed for all Cortex M3, M4 and M7 devices */
+#define SYSTICK_BASE 0xE000E010
+
+struct cm3_systick {
+ uint32_t ctrl;
+ uint32_t reload_val;
+ uint32_t current_val;
+ uint32_t calibration;
+};
+
+#define TIMER_MAX_VAL 0x00FFFFFF
+#define SYSTICK_CTRL_EN BIT(0)
+/* Clock source: 0 = Ref clock, 1 = CPU clock */
+#define SYSTICK_CTRL_CPU_CLK BIT(2)
+#define SYSTICK_CAL_NOREF BIT(31)
+#define SYSTICK_CAL_SKEW BIT(30)
+#define SYSTICK_CAL_TENMS_MASK 0x00FFFFFF
+
+/* read the 24-bit timer */
+static ulong read_timer(void)
+{
+ struct cm3_systick *systick = (struct cm3_systick *)SYSTICK_BASE;
+
+ /* The timer counts down, therefore convert to an incrementing timer */
+ return TIMER_MAX_VAL - readl(&systick->current_val);
+}
+
+int timer_init(void)
+{
+ struct cm3_systick *systick = (struct cm3_systick *)SYSTICK_BASE;
+ u32 cal;
+
+ writel(TIMER_MAX_VAL, &systick->reload_val);
+ /* Any write to current_val reg clears it to 0 */
+ writel(0, &systick->current_val);
+
+ cal = readl(&systick->calibration);
+ if (cal & SYSTICK_CAL_NOREF)
+ /* Use CPU clock, no interrupts */
+ writel(SYSTICK_CTRL_EN | SYSTICK_CTRL_CPU_CLK, &systick->ctrl);
+ else
+ /* Use external clock, no interrupts */
+ writel(SYSTICK_CTRL_EN, &systick->ctrl);
+
+ /*
+ * If the TENMS field is inexact or wrong, specify the clock rate using
+ * CONFIG_SYS_HZ_CLOCK.
+ */
+#if defined(CONFIG_SYS_HZ_CLOCK)
+ gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK;
+#else
+ gd->arch.timer_rate_hz = (cal & SYSTICK_CAL_TENMS_MASK) * 100;
+#endif
+
+ gd->arch.tbl = 0;
+ gd->arch.tbu = 0;
+ gd->arch.lastinc = read_timer();
+
+ return 0;
+}
+
+/* return milli-seconds timer value */
+ulong get_timer(ulong base)
+{
+ unsigned long long t = get_ticks() * 1000;
+
+ return (ulong)((t / gd->arch.timer_rate_hz)) - base;
+}
+
+unsigned long long get_ticks(void)
+{
+ u32 now = read_timer();
+
+ if (now >= gd->arch.lastinc)
+ gd->arch.tbl += (now - gd->arch.lastinc);
+ else
+ gd->arch.tbl += (TIMER_MAX_VAL - gd->arch.lastinc) + now;
+
+ gd->arch.lastinc = now;
+
+ return gd->arch.tbl;
+}
+
+ulong get_tbclk(void)
+{
+ return gd->arch.timer_rate_hz;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/Kconfig b/roms/u-boot/arch/arm/cpu/armv8/Kconfig
new file mode 100644
index 000000000..b7a10a8e3
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/Kconfig
@@ -0,0 +1,177 @@
+if ARM64
+
+config ARMV8_SPL_EXCEPTION_VECTORS
+ bool "Install crash dump exception vectors"
+ depends on SPL
+ default n
+ help
+ The default exception vector table is only used for the crash
+ dump, but still takes quite a lot of space in the image size.
+
+ Say N here if you are running out of code space in the image
+ and want to save some space at the cost of less debugging info.
+
+config ARMV8_MULTIENTRY
+ bool "Enable multiple CPUs to enter into U-Boot"
+
+config ARMV8_SET_SMPEN
+ bool "Enable data coherency with other cores in cluster"
+ help
+ Say Y here if there is not any trust firmware to set
+ CPUECTLR_EL1.SMPEN bit before U-Boot.
+
+ For A53, it enables data coherency with other cores in the
+ cluster, and for A57/A72, it enables receiving of instruction
+ cache and TLB maintenance operations.
+ Cortex A53/57/72 cores require CPUECTLR_EL1.SMPEN set even
+ for single core systems. Unfortunately write access to this
+ register may be controlled by EL3/EL2 firmware. To be more
+ precise, by default (if there is EL2/EL3 firmware running)
+ this register is RO for NS EL1.
+ This switch can be used to avoid writing to CPUECTLR_EL1,
+ it can be safely enabled when EL2/EL3 initialized SMPEN bit
+ or when CPU implementation doesn't include that register.
+
+config ARMV8_SPIN_TABLE
+ bool "Support spin-table enable method"
+ depends on ARMV8_MULTIENTRY && OF_LIBFDT
+ help
+ Say Y here to support "spin-table" enable method for booting Linux.
+
+ To use this feature, you must do:
+ - Specify enable-method = "spin-table" in each CPU node in the
+ Device Tree you are using to boot the kernel
+ - Bring secondary CPUs into U-Boot proper in a board specific
+ manner. This must be done *after* relocation. Otherwise, the
+ secondary CPUs will spin in unprotected memory area because the
+ master CPU protects the relocated spin code.
+
+ U-Boot automatically does:
+ - Set "cpu-release-addr" property of each CPU node
+ (overwrites it if already exists).
+ - Reserve the code for the spin-table and the release address
+ via a /memreserve/ region in the Device Tree.
+
+menu "ARMv8 secure monitor firmware"
+config ARMV8_SEC_FIRMWARE_SUPPORT
+ bool "Enable ARMv8 secure monitor firmware framework support"
+ select FIT
+ select OF_LIBFDT
+ help
+ This framework is aimed at making secure monitor firmware load
+ process brief.
+ Note: Only FIT format image is supported.
+ You should prepare and provide the below information:
+ - Address of secure firmware.
+ - Address to hold the return address from secure firmware.
+ - Secure firmware FIT image related information.
+ Such as: SEC_FIRMWARE_FIT_IMAGE and SEC_FIRMWARE_FIT_CNF_NAME
+ - The target exception level that secure monitor firmware will
+ return to.
+
+config SPL_ARMV8_SEC_FIRMWARE_SUPPORT
+ bool "Enable ARMv8 secure monitor firmware framework support for SPL"
+ select SPL_FIT
+ select SPL_OF_LIBFDT
+ help
+ Say Y here to support this framework in SPL phase.
+
+config SPL_RECOVER_DATA_SECTION
+ bool "save/restore SPL data section"
+ help
+ Say Y here to save SPL data section for cold boot, and restore
+ at warm boot in SPL phase.
+
+config SEC_FIRMWARE_ARMV8_PSCI
+ bool "PSCI implementation in secure monitor firmware"
+ depends on ARMV8_SEC_FIRMWARE_SUPPORT || SPL_ARMV8_SEC_FIRMWARE_SUPPORT
+ help
+ This config enables the ARMv8 PSCI implementation in secure monitor
+ firmware. This is a private PSCI implementation and different from
+ those implemented under the common ARMv8 PSCI framework.
+
+config ARMV8_SEC_FIRMWARE_ERET_ADDR_REVERT
+ bool "ARMv8 secure monitor firmware ERET address byteorder swap"
+ depends on ARMV8_SEC_FIRMWARE_SUPPORT || SPL_ARMV8_SEC_FIRMWARE_SUPPORT
+ help
+ Say Y here when the endianness of the register or memory holding the
+ Secure firmware exception return address is different with core's.
+
+endmenu
+
+config PSCI_RESET
+ bool "Use PSCI for reset and shutdown"
+ default y
+ select ARM_SMCCC if OF_CONTROL
+ depends on !ARCH_EXYNOS7 && !ARCH_BCM283X && \
+ !TARGET_LS2080AQDS && \
+ !TARGET_LS2080ARDB && !TARGET_LS2080A_EMU && \
+ !TARGET_LS1088ARDB && !TARGET_LS1088AQDS && \
+ !TARGET_LS1012ARDB && !TARGET_LS1012AFRDM && \
+ !TARGET_LS1012A2G5RDB && !TARGET_LS1012AQDS && \
+ !TARGET_LS1012AFRWY && \
+ !TARGET_LS1028ARDB && !TARGET_LS1028AQDS && \
+ !TARGET_LS1043ARDB && !TARGET_LS1043AQDS && \
+ !TARGET_LS1046ARDB && !TARGET_LS1046AQDS && \
+ !TARGET_LS1046AFRWY && \
+ !TARGET_LS2081ARDB && !TARGET_LX2160ARDB && \
+ !TARGET_LX2160AQDS && !TARGET_LX2162AQDS && \
+ !ARCH_UNIPHIER
+ help
+ Most armv8 systems have PSCI support enabled in EL3, either through
+ ARM Trusted Firmware or other firmware.
+
+ On these systems, we do not need to implement system reset manually,
+ but can instead rely on higher level firmware to deal with it.
+
+ Select Y here to make use of PSCI calls for system reset
+
+config ARMV8_PSCI
+ bool "Enable PSCI support" if EXPERT
+ default n
+ help
+ PSCI is Power State Coordination Interface defined by ARM.
+ The PSCI in U-boot provides a general framework and each platform
+ can implement their own specific PSCI functions.
+ Say Y here to enable PSCI support on ARMv8 platform.
+
+config ARMV8_PSCI_NR_CPUS
+ int "Maximum supported CPUs for PSCI"
+ depends on ARMV8_PSCI
+ default 4
+ help
+ The maximum number of CPUs supported in the PSCI firmware.
+ It is no problem to set a larger value than the number of CPUs in
+ the actual hardware implementation.
+
+config ARMV8_PSCI_CPUS_PER_CLUSTER
+ int "Number of CPUs per cluster"
+ depends on ARMV8_PSCI
+ default 0
+ help
+ The number of CPUs per cluster, suppose each cluster has same number
+ of CPU cores, platforms with asymmetric clusters don't apply here.
+ A value 0 or no definition of it works for single cluster system.
+ System with multi-cluster should difine their own exact value.
+
+config ARMV8_EA_EL3_FIRST
+ bool "External aborts and SError interrupt exception are taken in EL3"
+ default n
+ help
+ Exception handling at all exception levels for External Abort and
+ SError interrupt exception are taken in EL3.
+
+if SYS_HAS_ARMV8_SECURE_BASE
+
+config ARMV8_SECURE_BASE
+ hex "Secure address for PSCI image"
+ depends on ARMV8_PSCI
+ help
+ Address for placing the PSCI text, data and stack sections.
+ If not defined, the PSCI sections are placed together with the u-boot
+ but platform can choose to place PSCI code image separately in other
+ places such as some secure RAM built-in SOC etc.
+
+endif
+
+endif
diff --git a/roms/u-boot/arch/arm/cpu/armv8/Makefile b/roms/u-boot/arch/arm/cpu/armv8/Makefile
new file mode 100644
index 000000000..d85ddde43
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/Makefile
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+extra-y := start.o
+
+obj-y += cpu.o
+ifndef CONFIG_$(SPL_TPL_)TIMER
+obj-$(CONFIG_SYS_ARCH_TIMER) += generic_timer.o
+endif
+ifndef CONFIG_$(SPL_)SYS_DCACHE_OFF
+obj-y += cache_v8.o
+obj-y += cache.o
+endif
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) += exceptions.o
+else
+obj-y += exceptions.o
+obj-y += exception_level.o
+endif
+obj-y += tlb.o
+obj-y += transition.o
+ifndef CONFIG_ARMV8_PSCI
+obj-y += fwcall.o
+endif
+obj-y += cpu-dt.o
+obj-$(CONFIG_ARM_SMCCC) += smccc-call.o
+
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o
+else
+obj-$(CONFIG_ARCH_SUNXI) += fel_utils.o
+endif
+obj-$(CONFIG_$(SPL_)ARMV8_SEC_FIRMWARE_SUPPORT) += sec_firmware.o sec_firmware_asm.o
+
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_SPL_RECOVER_DATA_SECTION) += spl_data.o
+endif
+
+obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/
+obj-$(CONFIG_S32V234) += s32v234/
+obj-$(CONFIG_TARGET_HIKEY) += hisilicon/
+obj-$(CONFIG_ARMV8_PSCI) += psci.o
+obj-$(CONFIG_ARCH_SUNXI) += lowlevel_init.o
+obj-$(CONFIG_TARGET_BCMNS3) += bcmns3/
+obj-$(CONFIG_XEN) += xen/
diff --git a/roms/u-boot/arch/arm/cpu/armv8/bcmns3/Makefile b/roms/u-boot/arch/arm/cpu/armv8/bcmns3/Makefile
new file mode 100644
index 000000000..a35e29d11
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/bcmns3/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2020 Broadcom.
+
+obj-y += lowlevel.o
diff --git a/roms/u-boot/arch/arm/cpu/armv8/bcmns3/lowlevel.S b/roms/u-boot/arch/arm/cpu/armv8/bcmns3/lowlevel.S
new file mode 100644
index 000000000..bf1a17ab0
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/bcmns3/lowlevel.S
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2020 Broadcom.
+ *
+ */
+
+#include <asm/macro.h>
+#include <linux/linkage.h>
+
+hnf_pstate_poll:
+ /* x0 has the desired status, return 0 for success, 1 for timeout
+ * clobber x1, x2, x3, x4, x6, x7
+ */
+ mov x1, x0
+ mov x7, #0 /* flag for timeout */
+ mrs x3, cntpct_el0 /* read timer */
+ mov w0, #600
+ mov w6, #1000
+ mul w0, w0, w6
+ add x3, x3, x0 /* timeout after 100 microseconds */
+ mov x0, #0x18
+ movk x0, #0x6120, lsl #16 /* HNF0_PSTATE_STATUS */
+ mov w6, #4 /* HN-F node count */
+1:
+ ldr x2, [x0]
+ cmp x2, x1 /* check status */
+ b.eq 2f
+ mrs x4, cntpct_el0
+ cmp x4, x3
+ b.ls 1b
+ mov x7, #1 /* timeout */
+ b 3f
+2:
+ add x0, x0, #0x10000 /* move to next node */
+ subs w6, w6, #1
+ cbnz w6, 1b
+3:
+ mov x0, x7
+ ret
+
+hnf_set_pstate:
+ /* x0 has the desired state, clobber x1, x2, x6 */
+ mov x1, x0
+ /* power state to SFONLY */
+ mov w6, #4 /* HN-F node count */
+ mov x0, #0x10
+ movk x0, #0x6120, lsl #16 /* HNF0_PSTATE_REQ */
+1: /* set pstate to sfonly */
+ ldr x2, [x0]
+ and x2, x2, #0xfffffffffffffffc /* & HNFPSTAT_MASK */
+ orr x2, x2, x1
+ str x2, [x0]
+ add x0, x0, #0x10000 /* move to next node */
+ subs w6, w6, #1
+ cbnz w6, 1b
+
+ ret
+
+ENTRY(__asm_flush_l3_dcache)
+ /*
+ * Return status in x0
+ * success 0
+ * timeout 1 for setting SFONLY, 2 for FAM, 3 for both
+ */
+ mov x29, lr
+ mov x8, #0
+
+ dsb sy
+ mov x0, #0x1 /* HNFPSTAT_SFONLY */
+ bl hnf_set_pstate
+
+ mov x0, #0x4 /* SFONLY status */
+ bl hnf_pstate_poll
+ cbz x0, 1f
+ mov x8, #1 /* timeout */
+1:
+ dsb sy
+ mov x0, #0x3 /* HNFPSTAT_FAM */
+ bl hnf_set_pstate
+
+ mov x0, #0xc /* FAM status */
+ bl hnf_pstate_poll
+ cbz x0, 1f
+ add x8, x8, #0x2
+1:
+ mov x0, x8
+ mov lr, x29
+ ret
+ENDPROC(__asm_flush_l3_dcache)
+
+ENTRY(save_boot_params)
+/*
+ * void set_boot_params(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
+ */
+ adr x4, bl33_info
+ str x0, [x4]
+ b save_boot_params_ret
+ENDPROC(save_boot_params)
diff --git a/roms/u-boot/arch/arm/cpu/armv8/cache.S b/roms/u-boot/arch/arm/cpu/armv8/cache.S
new file mode 100644
index 000000000..443d94c26
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/cache.S
@@ -0,0 +1,267 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * This file is based on sample code from ARMv8 ARM.
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/macro.h>
+#include <asm/system.h>
+#include <linux/linkage.h>
+
+/*
+ * void __asm_dcache_level(level)
+ *
+ * flush or invalidate one level cache.
+ *
+ * x0: cache level
+ * x1: 0 clean & invalidate, 1 invalidate only
+ * x2~x9: clobbered
+ */
+.pushsection .text.__asm_dcache_level, "ax"
+ENTRY(__asm_dcache_level)
+ lsl x12, x0, #1
+ msr csselr_el1, x12 /* select cache level */
+ isb /* sync change of cssidr_el1 */
+ mrs x6, ccsidr_el1 /* read the new cssidr_el1 */
+ and x2, x6, #7 /* x2 <- log2(cache line size)-4 */
+ add x2, x2, #4 /* x2 <- log2(cache line size) */
+ mov x3, #0x3ff
+ and x3, x3, x6, lsr #3 /* x3 <- max number of #ways */
+ clz w5, w3 /* bit position of #ways */
+ mov x4, #0x7fff
+ and x4, x4, x6, lsr #13 /* x4 <- max number of #sets */
+ /* x12 <- cache level << 1 */
+ /* x2 <- line length offset */
+ /* x3 <- number of cache ways - 1 */
+ /* x4 <- number of cache sets - 1 */
+ /* x5 <- bit position of #ways */
+
+loop_set:
+ mov x6, x3 /* x6 <- working copy of #ways */
+loop_way:
+ lsl x7, x6, x5
+ orr x9, x12, x7 /* map way and level to cisw value */
+ lsl x7, x4, x2
+ orr x9, x9, x7 /* map set number to cisw value */
+ tbz w1, #0, 1f
+ dc isw, x9
+ b 2f
+1: dc cisw, x9 /* clean & invalidate by set/way */
+2: subs x6, x6, #1 /* decrement the way */
+ b.ge loop_way
+ subs x4, x4, #1 /* decrement the set */
+ b.ge loop_set
+
+ ret
+ENDPROC(__asm_dcache_level)
+.popsection
+
+/*
+ * void __asm_flush_dcache_all(int invalidate_only)
+ *
+ * x0: 0 clean & invalidate, 1 invalidate only
+ *
+ * flush or invalidate all data cache by SET/WAY.
+ */
+.pushsection .text.__asm_dcache_all, "ax"
+ENTRY(__asm_dcache_all)
+ mov x1, x0
+ dsb sy
+ mrs x10, clidr_el1 /* read clidr_el1 */
+ lsr x11, x10, #24
+ and x11, x11, #0x7 /* x11 <- loc */
+ cbz x11, finished /* if loc is 0, exit */
+ mov x15, lr
+ mov x0, #0 /* start flush at cache level 0 */
+ /* x0 <- cache level */
+ /* x10 <- clidr_el1 */
+ /* x11 <- loc */
+ /* x15 <- return address */
+
+loop_level:
+ lsl x12, x0, #1
+ add x12, x12, x0 /* x0 <- tripled cache level */
+ lsr x12, x10, x12
+ and x12, x12, #7 /* x12 <- cache type */
+ cmp x12, #2
+ b.lt skip /* skip if no cache or icache */
+ bl __asm_dcache_level /* x1 = 0 flush, 1 invalidate */
+skip:
+ add x0, x0, #1 /* increment cache level */
+ cmp x11, x0
+ b.gt loop_level
+
+ mov x0, #0
+ msr csselr_el1, x0 /* restore csselr_el1 */
+ dsb sy
+ isb
+ mov lr, x15
+
+finished:
+ ret
+ENDPROC(__asm_dcache_all)
+.popsection
+
+.pushsection .text.__asm_flush_dcache_all, "ax"
+ENTRY(__asm_flush_dcache_all)
+ mov x0, #0
+ b __asm_dcache_all
+ENDPROC(__asm_flush_dcache_all)
+.popsection
+
+.pushsection .text.__asm_invalidate_dcache_all, "ax"
+ENTRY(__asm_invalidate_dcache_all)
+ mov x0, #0x1
+ b __asm_dcache_all
+ENDPROC(__asm_invalidate_dcache_all)
+.popsection
+
+/*
+ * void __asm_flush_dcache_range(start, end)
+ *
+ * clean & invalidate data cache in the range
+ *
+ * x0: start address
+ * x1: end address
+ */
+.pushsection .text.__asm_flush_dcache_range, "ax"
+ENTRY(__asm_flush_dcache_range)
+ mrs x3, ctr_el0
+ lsr x3, x3, #16
+ and x3, x3, #0xf
+ mov x2, #4
+ lsl x2, x2, x3 /* cache line size */
+
+ /* x2 <- minimal cache line size in cache system */
+ sub x3, x2, #1
+ bic x0, x0, x3
+1: dc civac, x0 /* clean & invalidate data or unified cache */
+ add x0, x0, x2
+ cmp x0, x1
+ b.lo 1b
+ dsb sy
+ ret
+ENDPROC(__asm_flush_dcache_range)
+.popsection
+/*
+ * void __asm_invalidate_dcache_range(start, end)
+ *
+ * invalidate data cache in the range
+ *
+ * x0: start address
+ * x1: end address
+ */
+.pushsection .text.__asm_invalidate_dcache_range, "ax"
+ENTRY(__asm_invalidate_dcache_range)
+ mrs x3, ctr_el0
+ ubfm x3, x3, #16, #19
+ mov x2, #4
+ lsl x2, x2, x3 /* cache line size */
+
+ /* x2 <- minimal cache line size in cache system */
+ sub x3, x2, #1
+ bic x0, x0, x3
+1: dc ivac, x0 /* invalidate data or unified cache */
+ add x0, x0, x2
+ cmp x0, x1
+ b.lo 1b
+ dsb sy
+ ret
+ENDPROC(__asm_invalidate_dcache_range)
+.popsection
+
+/*
+ * void __asm_invalidate_icache_all(void)
+ *
+ * invalidate all tlb entries.
+ */
+.pushsection .text.__asm_invalidate_icache_all, "ax"
+ENTRY(__asm_invalidate_icache_all)
+ ic ialluis
+ isb sy
+ ret
+ENDPROC(__asm_invalidate_icache_all)
+.popsection
+
+.pushsection .text.__asm_invalidate_l3_dcache, "ax"
+ENTRY(__asm_invalidate_l3_dcache)
+ mov x0, #0 /* return status as success */
+ ret
+ENDPROC(__asm_invalidate_l3_dcache)
+ .weak __asm_invalidate_l3_dcache
+.popsection
+
+.pushsection .text.__asm_flush_l3_dcache, "ax"
+ENTRY(__asm_flush_l3_dcache)
+ mov x0, #0 /* return status as success */
+ ret
+ENDPROC(__asm_flush_l3_dcache)
+ .weak __asm_flush_l3_dcache
+.popsection
+
+.pushsection .text.__asm_invalidate_l3_icache, "ax"
+ENTRY(__asm_invalidate_l3_icache)
+ mov x0, #0 /* return status as success */
+ ret
+ENDPROC(__asm_invalidate_l3_icache)
+ .weak __asm_invalidate_l3_icache
+.popsection
+
+/*
+ * void __asm_switch_ttbr(ulong new_ttbr)
+ *
+ * Safely switches to a new page table.
+ */
+.pushsection .text.__asm_switch_ttbr, "ax"
+ENTRY(__asm_switch_ttbr)
+ /* x2 = SCTLR (alive throghout the function) */
+ switch_el x4, 3f, 2f, 1f
+3: mrs x2, sctlr_el3
+ b 0f
+2: mrs x2, sctlr_el2
+ b 0f
+1: mrs x2, sctlr_el1
+0:
+
+ /* Unset CR_M | CR_C | CR_I from SCTLR to disable all caches */
+ movn x1, #(CR_M | CR_C | CR_I)
+ and x1, x2, x1
+ switch_el x4, 3f, 2f, 1f
+3: msr sctlr_el3, x1
+ b 0f
+2: msr sctlr_el2, x1
+ b 0f
+1: msr sctlr_el1, x1
+0: isb
+
+ /* This call only clobbers x30 (lr) and x9 (unused) */
+ mov x3, x30
+ bl __asm_invalidate_tlb_all
+
+ /* From here on we're running safely with caches disabled */
+
+ /* Set TTBR to our first argument */
+ switch_el x4, 3f, 2f, 1f
+3: msr ttbr0_el3, x0
+ b 0f
+2: msr ttbr0_el2, x0
+ b 0f
+1: msr ttbr0_el1, x0
+0: isb
+
+ /* Restore original SCTLR and thus enable caches again */
+ switch_el x4, 3f, 2f, 1f
+3: msr sctlr_el3, x2
+ b 0f
+2: msr sctlr_el2, x2
+ b 0f
+1: msr sctlr_el1, x2
+0: isb
+
+ ret x3
+ENDPROC(__asm_switch_ttbr)
+.popsection
diff --git a/roms/u-boot/arch/arm/cpu/armv8/cache_v8.c b/roms/u-boot/arch/arm/cpu/armv8/cache_v8.c
new file mode 100644
index 000000000..15cecb5e0
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/cache_v8.c
@@ -0,0 +1,757 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * (C) Copyright 2016
+ * Alexander Graf <agraf@suse.de>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <hang.h>
+#include <log.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/system.h>
+#include <asm/armv8/mmu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+
+/*
+ * With 4k page granule, a virtual address is split into 4 lookup parts
+ * spanning 9 bits each:
+ *
+ * _______________________________________________
+ * | | | | | | |
+ * | 0 | Lv0 | Lv1 | Lv2 | Lv3 | off |
+ * |_______|_______|_______|_______|_______|_______|
+ * 63-48 47-39 38-30 29-21 20-12 11-00
+ *
+ * mask page size
+ *
+ * Lv0: FF8000000000 --
+ * Lv1: 7FC0000000 1G
+ * Lv2: 3FE00000 2M
+ * Lv3: 1FF000 4K
+ * off: FFF
+ */
+
+u64 get_tcr(int el, u64 *pips, u64 *pva_bits)
+{
+ u64 max_addr = 0;
+ u64 ips, va_bits;
+ u64 tcr;
+ int i;
+
+ /* Find the largest address we need to support */
+ for (i = 0; mem_map[i].size || mem_map[i].attrs; i++)
+ max_addr = max(max_addr, mem_map[i].virt + mem_map[i].size);
+
+ /* Calculate the maximum physical (and thus virtual) address */
+ if (max_addr > (1ULL << 44)) {
+ ips = 5;
+ va_bits = 48;
+ } else if (max_addr > (1ULL << 42)) {
+ ips = 4;
+ va_bits = 44;
+ } else if (max_addr > (1ULL << 40)) {
+ ips = 3;
+ va_bits = 42;
+ } else if (max_addr > (1ULL << 36)) {
+ ips = 2;
+ va_bits = 40;
+ } else if (max_addr > (1ULL << 32)) {
+ ips = 1;
+ va_bits = 36;
+ } else {
+ ips = 0;
+ va_bits = 32;
+ }
+
+ if (el == 1) {
+ tcr = TCR_EL1_RSVD | (ips << 32) | TCR_EPD1_DISABLE;
+ } else if (el == 2) {
+ tcr = TCR_EL2_RSVD | (ips << 16);
+ } else {
+ tcr = TCR_EL3_RSVD | (ips << 16);
+ }
+
+ /* PTWs cacheable, inner/outer WBWA and inner shareable */
+ tcr |= TCR_TG0_4K | TCR_SHARED_INNER | TCR_ORGN_WBWA | TCR_IRGN_WBWA;
+ tcr |= TCR_T0SZ(va_bits);
+
+ if (pips)
+ *pips = ips;
+ if (pva_bits)
+ *pva_bits = va_bits;
+
+ return tcr;
+}
+
+#define MAX_PTE_ENTRIES 512
+
+static int pte_type(u64 *pte)
+{
+ return *pte & PTE_TYPE_MASK;
+}
+
+/* Returns the LSB number for a PTE on level <level> */
+static int level2shift(int level)
+{
+ /* Page is 12 bits wide, every level translates 9 bits */
+ return (12 + 9 * (3 - level));
+}
+
+static u64 *find_pte(u64 addr, int level)
+{
+ int start_level = 0;
+ u64 *pte;
+ u64 idx;
+ u64 va_bits;
+ int i;
+
+ debug("addr=%llx level=%d\n", addr, level);
+
+ get_tcr(0, NULL, &va_bits);
+ if (va_bits < 39)
+ start_level = 1;
+
+ if (level < start_level)
+ return NULL;
+
+ /* Walk through all page table levels to find our PTE */
+ pte = (u64*)gd->arch.tlb_addr;
+ for (i = start_level; i < 4; i++) {
+ idx = (addr >> level2shift(i)) & 0x1FF;
+ pte += idx;
+ debug("idx=%llx PTE %p at level %d: %llx\n", idx, pte, i, *pte);
+
+ /* Found it */
+ if (i == level)
+ return pte;
+ /* PTE is no table (either invalid or block), can't traverse */
+ if (pte_type(pte) != PTE_TYPE_TABLE)
+ return NULL;
+ /* Off to the next level */
+ pte = (u64*)(*pte & 0x0000fffffffff000ULL);
+ }
+
+ /* Should never reach here */
+ return NULL;
+}
+
+/* Returns and creates a new full table (512 entries) */
+static u64 *create_table(void)
+{
+ u64 *new_table = (u64*)gd->arch.tlb_fillptr;
+ u64 pt_len = MAX_PTE_ENTRIES * sizeof(u64);
+
+ /* Allocate MAX_PTE_ENTRIES pte entries */
+ gd->arch.tlb_fillptr += pt_len;
+
+ if (gd->arch.tlb_fillptr - gd->arch.tlb_addr > gd->arch.tlb_size)
+ panic("Insufficient RAM for page table: 0x%lx > 0x%lx. "
+ "Please increase the size in get_page_table_size()",
+ gd->arch.tlb_fillptr - gd->arch.tlb_addr,
+ gd->arch.tlb_size);
+
+ /* Mark all entries as invalid */
+ memset(new_table, 0, pt_len);
+
+ return new_table;
+}
+
+static void set_pte_table(u64 *pte, u64 *table)
+{
+ /* Point *pte to the new table */
+ debug("Setting %p to addr=%p\n", pte, table);
+ *pte = PTE_TYPE_TABLE | (ulong)table;
+}
+
+/* Splits a block PTE into table with subpages spanning the old block */
+static void split_block(u64 *pte, int level)
+{
+ u64 old_pte = *pte;
+ u64 *new_table;
+ u64 i = 0;
+ /* level describes the parent level, we need the child ones */
+ int levelshift = level2shift(level + 1);
+
+ if (pte_type(pte) != PTE_TYPE_BLOCK)
+ panic("PTE %p (%llx) is not a block. Some driver code wants to "
+ "modify dcache settings for an range not covered in "
+ "mem_map.", pte, old_pte);
+
+ new_table = create_table();
+ debug("Splitting pte %p (%llx) into %p\n", pte, old_pte, new_table);
+
+ for (i = 0; i < MAX_PTE_ENTRIES; i++) {
+ new_table[i] = old_pte | (i << levelshift);
+
+ /* Level 3 block PTEs have the table type */
+ if ((level + 1) == 3)
+ new_table[i] |= PTE_TYPE_TABLE;
+
+ debug("Setting new_table[%lld] = %llx\n", i, new_table[i]);
+ }
+
+ /* Set the new table into effect */
+ set_pte_table(pte, new_table);
+}
+
+/* Add one mm_region map entry to the page tables */
+static void add_map(struct mm_region *map)
+{
+ u64 *pte;
+ u64 virt = map->virt;
+ u64 phys = map->phys;
+ u64 size = map->size;
+ u64 attrs = map->attrs | PTE_TYPE_BLOCK | PTE_BLOCK_AF;
+ u64 blocksize;
+ int level;
+ u64 *new_table;
+
+ while (size) {
+ pte = find_pte(virt, 0);
+ if (pte && (pte_type(pte) == PTE_TYPE_FAULT)) {
+ debug("Creating table for virt 0x%llx\n", virt);
+ new_table = create_table();
+ set_pte_table(pte, new_table);
+ }
+
+ for (level = 1; level < 4; level++) {
+ pte = find_pte(virt, level);
+ if (!pte)
+ panic("pte not found\n");
+
+ blocksize = 1ULL << level2shift(level);
+ debug("Checking if pte fits for virt=%llx size=%llx blocksize=%llx\n",
+ virt, size, blocksize);
+ if (size >= blocksize && !(virt & (blocksize - 1))) {
+ /* Page fits, create block PTE */
+ debug("Setting PTE %p to block virt=%llx\n",
+ pte, virt);
+ if (level == 3)
+ *pte = phys | attrs | PTE_TYPE_PAGE;
+ else
+ *pte = phys | attrs;
+ virt += blocksize;
+ phys += blocksize;
+ size -= blocksize;
+ break;
+ } else if (pte_type(pte) == PTE_TYPE_FAULT) {
+ /* Page doesn't fit, create subpages */
+ debug("Creating subtable for virt 0x%llx blksize=%llx\n",
+ virt, blocksize);
+ new_table = create_table();
+ set_pte_table(pte, new_table);
+ } else if (pte_type(pte) == PTE_TYPE_BLOCK) {
+ debug("Split block into subtable for virt 0x%llx blksize=0x%llx\n",
+ virt, blocksize);
+ split_block(pte, level);
+ }
+ }
+ }
+}
+
+enum pte_type {
+ PTE_INVAL,
+ PTE_BLOCK,
+ PTE_LEVEL,
+};
+
+/*
+ * This is a recursively called function to count the number of
+ * page tables we need to cover a particular PTE range. If you
+ * call this with level = -1 you basically get the full 48 bit
+ * coverage.
+ */
+static int count_required_pts(u64 addr, int level, u64 maxaddr)
+{
+ int levelshift = level2shift(level);
+ u64 levelsize = 1ULL << levelshift;
+ u64 levelmask = levelsize - 1;
+ u64 levelend = addr + levelsize;
+ int r = 0;
+ int i;
+ enum pte_type pte_type = PTE_INVAL;
+
+ for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) {
+ struct mm_region *map = &mem_map[i];
+ u64 start = map->virt;
+ u64 end = start + map->size;
+
+ /* Check if the PTE would overlap with the map */
+ if (max(addr, start) <= min(levelend, end)) {
+ start = max(addr, start);
+ end = min(levelend, end);
+
+ /* We need a sub-pt for this level */
+ if ((start & levelmask) || (end & levelmask)) {
+ pte_type = PTE_LEVEL;
+ break;
+ }
+
+ /* Lv0 can not do block PTEs, so do levels here too */
+ if (level <= 0) {
+ pte_type = PTE_LEVEL;
+ break;
+ }
+
+ /* PTE is active, but fits into a block */
+ pte_type = PTE_BLOCK;
+ }
+ }
+
+ /*
+ * Block PTEs at this level are already covered by the parent page
+ * table, so we only need to count sub page tables.
+ */
+ if (pte_type == PTE_LEVEL) {
+ int sublevel = level + 1;
+ u64 sublevelsize = 1ULL << level2shift(sublevel);
+
+ /* Account for the new sub page table ... */
+ r = 1;
+
+ /* ... and for all child page tables that one might have */
+ for (i = 0; i < MAX_PTE_ENTRIES; i++) {
+ r += count_required_pts(addr, sublevel, maxaddr);
+ addr += sublevelsize;
+
+ if (addr >= maxaddr) {
+ /*
+ * We reached the end of address space, no need
+ * to look any further.
+ */
+ break;
+ }
+ }
+ }
+
+ return r;
+}
+
+/* Returns the estimated required size of all page tables */
+__weak u64 get_page_table_size(void)
+{
+ u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64);
+ u64 size = 0;
+ u64 va_bits;
+ int start_level = 0;
+
+ get_tcr(0, NULL, &va_bits);
+ if (va_bits < 39)
+ start_level = 1;
+
+ /* Account for all page tables we would need to cover our memory map */
+ size = one_pt * count_required_pts(0, start_level - 1, 1ULL << va_bits);
+
+ /*
+ * We need to duplicate our page table once to have an emergency pt to
+ * resort to when splitting page tables later on
+ */
+ size *= 2;
+
+ /*
+ * We may need to split page tables later on if dcache settings change,
+ * so reserve up to 4 (random pick) page tables for that.
+ */
+ size += one_pt * 4;
+
+ return size;
+}
+
+void setup_pgtables(void)
+{
+ int i;
+
+ if (!gd->arch.tlb_fillptr || !gd->arch.tlb_addr)
+ panic("Page table pointer not setup.");
+
+ /*
+ * Allocate the first level we're on with invalidate entries.
+ * If the starting level is 0 (va_bits >= 39), then this is our
+ * Lv0 page table, otherwise it's the entry Lv1 page table.
+ */
+ create_table();
+
+ /* Now add all MMU table entries one after another to the table */
+ for (i = 0; mem_map[i].size || mem_map[i].attrs; i++)
+ add_map(&mem_map[i]);
+}
+
+static void setup_all_pgtables(void)
+{
+ u64 tlb_addr = gd->arch.tlb_addr;
+ u64 tlb_size = gd->arch.tlb_size;
+
+ /* Reset the fill ptr */
+ gd->arch.tlb_fillptr = tlb_addr;
+
+ /* Create normal system page tables */
+ setup_pgtables();
+
+ /* Create emergency page tables */
+ gd->arch.tlb_size -= (uintptr_t)gd->arch.tlb_fillptr -
+ (uintptr_t)gd->arch.tlb_addr;
+ gd->arch.tlb_addr = gd->arch.tlb_fillptr;
+ setup_pgtables();
+ gd->arch.tlb_emerg = gd->arch.tlb_addr;
+ gd->arch.tlb_addr = tlb_addr;
+ gd->arch.tlb_size = tlb_size;
+}
+
+/* to activate the MMU we need to set up virtual memory */
+__weak void mmu_setup(void)
+{
+ int el;
+
+ /* Set up page tables only once */
+ if (!gd->arch.tlb_fillptr)
+ setup_all_pgtables();
+
+ el = current_el();
+ set_ttbr_tcr_mair(el, gd->arch.tlb_addr, get_tcr(el, NULL, NULL),
+ MEMORY_ATTRIBUTES);
+
+ /* enable the mmu */
+ set_sctlr(get_sctlr() | CR_M);
+}
+
+/*
+ * Performs a invalidation of the entire data cache at all levels
+ */
+void invalidate_dcache_all(void)
+{
+ __asm_invalidate_dcache_all();
+ __asm_invalidate_l3_dcache();
+}
+
+/*
+ * Performs a clean & invalidation of the entire data cache at all levels.
+ * This function needs to be inline to avoid using stack.
+ * __asm_flush_l3_dcache return status of timeout
+ */
+inline void flush_dcache_all(void)
+{
+ int ret;
+
+ __asm_flush_dcache_all();
+ ret = __asm_flush_l3_dcache();
+ if (ret)
+ debug("flushing dcache returns 0x%x\n", ret);
+ else
+ debug("flushing dcache successfully.\n");
+}
+
+#ifndef CONFIG_SYS_DISABLE_DCACHE_OPS
+/*
+ * Invalidates range in all levels of D-cache/unified cache
+ */
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+ __asm_invalidate_dcache_range(start, stop);
+}
+
+/*
+ * Flush range(clean & invalidate) from all levels of D-cache/unified cache
+ */
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+ __asm_flush_dcache_range(start, stop);
+}
+#else
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+#endif /* CONFIG_SYS_DISABLE_DCACHE_OPS */
+
+void dcache_enable(void)
+{
+ /* The data cache is not active unless the mmu is enabled */
+ if (!(get_sctlr() & CR_M)) {
+ invalidate_dcache_all();
+ __asm_invalidate_tlb_all();
+ mmu_setup();
+ }
+
+ set_sctlr(get_sctlr() | CR_C);
+}
+
+void dcache_disable(void)
+{
+ uint32_t sctlr;
+
+ sctlr = get_sctlr();
+
+ /* if cache isn't enabled no need to disable */
+ if (!(sctlr & CR_C))
+ return;
+
+ set_sctlr(sctlr & ~(CR_C|CR_M));
+
+ flush_dcache_all();
+ __asm_invalidate_tlb_all();
+}
+
+int dcache_status(void)
+{
+ return (get_sctlr() & CR_C) != 0;
+}
+
+u64 *__weak arch_get_page_table(void) {
+ puts("No page table offset defined\n");
+
+ return NULL;
+}
+
+static bool is_aligned(u64 addr, u64 size, u64 align)
+{
+ return !(addr & (align - 1)) && !(size & (align - 1));
+}
+
+/* Use flag to indicate if attrs has more than d-cache attributes */
+static u64 set_one_region(u64 start, u64 size, u64 attrs, bool flag, int level)
+{
+ int levelshift = level2shift(level);
+ u64 levelsize = 1ULL << levelshift;
+ u64 *pte = find_pte(start, level);
+
+ /* Can we can just modify the current level block PTE? */
+ if (is_aligned(start, size, levelsize)) {
+ if (flag) {
+ *pte &= ~PMD_ATTRMASK;
+ *pte |= attrs & PMD_ATTRMASK;
+ } else {
+ *pte &= ~PMD_ATTRINDX_MASK;
+ *pte |= attrs & PMD_ATTRINDX_MASK;
+ }
+ debug("Set attrs=%llx pte=%p level=%d\n", attrs, pte, level);
+
+ return levelsize;
+ }
+
+ /* Unaligned or doesn't fit, maybe split block into table */
+ debug("addr=%llx level=%d pte=%p (%llx)\n", start, level, pte, *pte);
+
+ /* Maybe we need to split the block into a table */
+ if (pte_type(pte) == PTE_TYPE_BLOCK)
+ split_block(pte, level);
+
+ /* And then double-check it became a table or already is one */
+ if (pte_type(pte) != PTE_TYPE_TABLE)
+ panic("PTE %p (%llx) for addr=%llx should be a table",
+ pte, *pte, start);
+
+ /* Roll on to the next page table level */
+ return 0;
+}
+
+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
+ enum dcache_option option)
+{
+ u64 attrs = PMD_ATTRINDX(option >> 2);
+ u64 real_start = start;
+ u64 real_size = size;
+
+ debug("start=%lx size=%lx\n", (ulong)start, (ulong)size);
+
+ if (!gd->arch.tlb_emerg)
+ panic("Emergency page table not setup.");
+
+ /*
+ * We can not modify page tables that we're currently running on,
+ * so we first need to switch to the "emergency" page tables where
+ * we can safely modify our primary page tables and then switch back
+ */
+ __asm_switch_ttbr(gd->arch.tlb_emerg);
+
+ /*
+ * Loop through the address range until we find a page granule that fits
+ * our alignment constraints, then set it to the new cache attributes
+ */
+ while (size > 0) {
+ int level;
+ u64 r;
+
+ for (level = 1; level < 4; level++) {
+ /* Set d-cache attributes only */
+ r = set_one_region(start, size, attrs, false, level);
+ if (r) {
+ /* PTE successfully replaced */
+ size -= r;
+ start += r;
+ break;
+ }
+ }
+
+ }
+
+ /* We're done modifying page tables, switch back to our primary ones */
+ __asm_switch_ttbr(gd->arch.tlb_addr);
+
+ /*
+ * Make sure there's nothing stale in dcache for a region that might
+ * have caches off now
+ */
+ flush_dcache_range(real_start, real_start + real_size);
+}
+
+/*
+ * Modify MMU table for a region with updated PXN/UXN/Memory type/valid bits.
+ * The procecess is break-before-make. The target region will be marked as
+ * invalid during the process of changing.
+ */
+void mmu_change_region_attr(phys_addr_t addr, size_t siz, u64 attrs)
+{
+ int level;
+ u64 r, size, start;
+
+ start = addr;
+ size = siz;
+ /*
+ * Loop through the address range until we find a page granule that fits
+ * our alignment constraints, then set it to "invalid".
+ */
+ while (size > 0) {
+ for (level = 1; level < 4; level++) {
+ /* Set PTE to fault */
+ r = set_one_region(start, size, PTE_TYPE_FAULT, true,
+ level);
+ if (r) {
+ /* PTE successfully invalidated */
+ size -= r;
+ start += r;
+ break;
+ }
+ }
+ }
+
+ flush_dcache_range(gd->arch.tlb_addr,
+ gd->arch.tlb_addr + gd->arch.tlb_size);
+ __asm_invalidate_tlb_all();
+
+ /*
+ * Loop through the address range until we find a page granule that fits
+ * our alignment constraints, then set it to the new cache attributes
+ */
+ start = addr;
+ size = siz;
+ while (size > 0) {
+ for (level = 1; level < 4; level++) {
+ /* Set PTE to new attributes */
+ r = set_one_region(start, size, attrs, true, level);
+ if (r) {
+ /* PTE successfully updated */
+ size -= r;
+ start += r;
+ break;
+ }
+ }
+ }
+ flush_dcache_range(gd->arch.tlb_addr,
+ gd->arch.tlb_addr + gd->arch.tlb_size);
+ __asm_invalidate_tlb_all();
+}
+
+#else /* !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
+
+/*
+ * For SPL builds, we may want to not have dcache enabled. Any real U-Boot
+ * running however really wants to have dcache and the MMU active. Check that
+ * everything is sane and give the developer a hint if it isn't.
+ */
+#ifndef CONFIG_SPL_BUILD
+#error Please describe your MMU layout in CONFIG_SYS_MEM_MAP and enable dcache.
+#endif
+
+void invalidate_dcache_all(void)
+{
+}
+
+void flush_dcache_all(void)
+{
+}
+
+void dcache_enable(void)
+{
+}
+
+void dcache_disable(void)
+{
+}
+
+int dcache_status(void)
+{
+ return 0;
+}
+
+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
+ enum dcache_option option)
+{
+}
+
+#endif /* !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
+
+#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
+
+void icache_enable(void)
+{
+ invalidate_icache_all();
+ set_sctlr(get_sctlr() | CR_I);
+}
+
+void icache_disable(void)
+{
+ set_sctlr(get_sctlr() & ~CR_I);
+}
+
+int icache_status(void)
+{
+ return (get_sctlr() & CR_I) != 0;
+}
+
+void invalidate_icache_all(void)
+{
+ __asm_invalidate_icache_all();
+ __asm_invalidate_l3_icache();
+}
+
+#else /* !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) */
+
+void icache_enable(void)
+{
+}
+
+void icache_disable(void)
+{
+}
+
+int icache_status(void)
+{
+ return 0;
+}
+
+void invalidate_icache_all(void)
+{
+}
+
+#endif /* !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) */
+
+/*
+ * Enable dCache & iCache, whether cache is actually enabled
+ * depend on CONFIG_SYS_DCACHE_OFF and CONFIG_SYS_ICACHE_OFF
+ */
+void __weak enable_caches(void)
+{
+ icache_enable();
+ dcache_enable();
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/config.mk b/roms/u-boot/arch/arm/cpu/armv8/config.mk
new file mode 100644
index 000000000..6f9093109
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/config.mk
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+PLATFORM_RELFLAGS += -fno-common -ffixed-x18
+
+PF_NO_UNALIGNED := $(call cc-option, -mstrict-align)
+PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED)
+
+EFI_LDS := elf_aarch64_efi.lds
+EFI_CRT0 := crt0_aarch64_efi.o
+EFI_RELOC := reloc_aarch64_efi.o
diff --git a/roms/u-boot/arch/arm/cpu/armv8/cpu-dt.c b/roms/u-boot/arch/arm/cpu/armv8/cpu-dt.c
new file mode 100644
index 000000000..61c38b17c
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/cpu-dt.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <asm/cache.h>
+#include <asm/psci.h>
+#include <asm/system.h>
+#include <asm/armv8/sec_firmware.h>
+
+#if CONFIG_IS_ENABLED(ARMV8_SEC_FIRMWARE_SUPPORT)
+int psci_update_dt(void *fdt)
+{
+ /*
+ * If the PSCI in SEC Firmware didn't work, avoid to update the
+ * device node of PSCI. But still return 0 instead of an error
+ * number to support detecting PSCI dynamically and then switching
+ * the SMP boot method between PSCI and spin-table.
+ */
+ if (sec_firmware_support_psci_version() == PSCI_INVALID_VER)
+ return 0;
+ fdt_psci(fdt);
+
+#if defined(CONFIG_ARMV8_PSCI) && !defined(CONFIG_ARMV8_SECURE_BASE)
+ /* secure code lives in RAM, keep it alive */
+ fdt_add_mem_rsv(fdt, (unsigned long)__secure_start,
+ __secure_end - __secure_start);
+#endif
+
+ return 0;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv8/cpu.c b/roms/u-boot/arch/arm/cpu/armv8/cpu.c
new file mode 100644
index 000000000..ea40c55dd
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/cpu.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2008 Texas Insturments
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <irq_func.h>
+#include <asm/cache.h>
+#include <asm/system.h>
+#include <asm/secure.h>
+#include <linux/compiler.h>
+
+/*
+ * sdelay() - simple spin loop.
+ *
+ * Will delay execution by roughly (@loops * 2) cycles.
+ * This is necessary to be used before timers are accessible.
+ *
+ * A value of "0" will results in 2^64 loops.
+ */
+void sdelay(unsigned long loops)
+{
+ __asm__ volatile ("1:\n" "subs %0, %0, #1\n"
+ "b.ne 1b" : "=r" (loops) : "0"(loops) : "cc");
+}
+
+void __weak board_cleanup_before_linux(void){}
+
+int cleanup_before_linux(void)
+{
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * disable interrupt and turn off caches etc ...
+ */
+
+ board_cleanup_before_linux();
+
+ disable_interrupts();
+
+ /*
+ * Turn off I-cache and invalidate it
+ */
+ icache_disable();
+ invalidate_icache_all();
+
+ /*
+ * turn off D-cache
+ * dcache_disable() in turn flushes the d-cache and disables MMU
+ */
+ dcache_disable();
+ invalidate_dcache_all();
+
+ return 0;
+}
+
+#ifdef CONFIG_ARMV8_PSCI
+static void relocate_secure_section(void)
+{
+#ifdef CONFIG_ARMV8_SECURE_BASE
+ size_t sz = __secure_end - __secure_start;
+
+ memcpy((void *)CONFIG_ARMV8_SECURE_BASE, __secure_start, sz);
+ flush_dcache_range(CONFIG_ARMV8_SECURE_BASE,
+ CONFIG_ARMV8_SECURE_BASE + sz + 1);
+ invalidate_icache_all();
+#endif
+}
+
+void armv8_setup_psci(void)
+{
+ relocate_secure_section();
+ secure_ram_addr(psci_setup_vectors)();
+ secure_ram_addr(psci_arch_init)();
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv8/exception_level.c b/roms/u-boot/arch/arm/cpu/armv8/exception_level.c
new file mode 100644
index 000000000..b11936548
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/exception_level.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Switch to non-secure mode
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt
+ *
+ * This module contains the ARMv8 specific code required to adjust the exception
+ * level before booting an operating system.
+ */
+
+#include <common.h>
+#include <bootm.h>
+#include <cpu_func.h>
+#include <log.h>
+#include <asm/cache.h>
+#include <asm/setjmp.h>
+
+/**
+ * entry_non_secure() - entry point when switching to non-secure mode
+ *
+ * When switching to non-secure mode switch_to_non_secure_mode() calls this
+ * function passing a jump buffer. We use this jump buffer to restore the
+ * original stack and register state.
+ *
+ * @non_secure_jmp: jump buffer for restoring stack and registers
+ */
+static void entry_non_secure(struct jmp_buf_data *non_secure_jmp)
+{
+ dcache_enable();
+ debug("Reached non-secure mode\n");
+
+ /* Restore stack and registers saved in switch_to_non_secure_mode() */
+ longjmp(non_secure_jmp, 1);
+}
+
+/**
+ * switch_to_non_secure_mode() - switch to non-secure mode
+ *
+ * Exception level EL3 is meant to be used by the secure monitor only (ARM
+ * trusted firmware being one embodiment). The operating system shall be
+ * started at exception level EL2. So here we check the exception level
+ * and switch it if necessary.
+ */
+void switch_to_non_secure_mode(void)
+{
+ struct jmp_buf_data non_secure_jmp;
+
+ /* On AArch64 we need to make sure we call our payload in < EL3 */
+ if (current_el() == 3) {
+ if (setjmp(&non_secure_jmp))
+ return;
+ dcache_disable(); /* flush cache before switch to EL2 */
+
+ /* Move into EL2 and keep running there */
+ armv8_switch_to_el2((uintptr_t)&non_secure_jmp, 0, 0, 0,
+ (uintptr_t)entry_non_secure, ES_TO_AARCH64);
+ }
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/exceptions.S b/roms/u-boot/arch/arm/cpu/armv8/exceptions.S
new file mode 100644
index 000000000..a15af72e0
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/exceptions.S
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/ptrace.h>
+#include <asm/macro.h>
+#include <linux/linkage.h>
+
+/*
+ * AArch64 exception vectors:
+ * We have four types of exceptions:
+ * - synchronous: traps, data aborts, undefined instructions, ...
+ * - IRQ: group 1 (normal) interrupts
+ * - FIQ: group 0 or secure interrupts
+ * - SError: fatal system errors
+ * There are entries for all four of those for different contexts:
+ * - from same exception level, when using the SP_EL0 stack pointer
+ * - from same exception level, when using the SP_ELx stack pointer
+ * - from lower exception level, when this is AArch64
+ * - from lower exception level, when this is AArch32
+ * Each of those 16 entries have space for 32 instructions, each entry must
+ * be 128 byte aligned, the whole table must be 2K aligned.
+ * The 32 instructions are not enough to save and restore all registers and
+ * to branch to the actual handler, so we split this up:
+ * Each entry saves the LR, branches to the save routine, then to the actual
+ * handler, then to the restore routine. The save and restore routines are
+ * each split in half and stuffed in the unused gap between the entries.
+ * Also as we do not run anything in a lower exception level, we just provide
+ * the first 8 entries for exceptions from the same EL.
+ */
+ .align 11
+ .globl vectors
+vectors:
+ .align 7 /* Current EL Synchronous Thread */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_bad_sync
+ b exception_exit
+
+/*
+ * Save (most of) the GP registers to the stack frame.
+ * This is the first part of the shared routine called into from all entries.
+ */
+_exception_entry:
+ stp x27, x28, [sp, #-16]!
+ stp x25, x26, [sp, #-16]!
+ stp x23, x24, [sp, #-16]!
+ stp x21, x22, [sp, #-16]!
+ stp x19, x20, [sp, #-16]!
+ stp x17, x18, [sp, #-16]!
+ stp x15, x16, [sp, #-16]!
+ stp x13, x14, [sp, #-16]!
+ stp x11, x12, [sp, #-16]!
+ stp x9, x10, [sp, #-16]!
+ stp x7, x8, [sp, #-16]!
+ stp x5, x6, [sp, #-16]!
+ stp x3, x4, [sp, #-16]!
+ stp x1, x2, [sp, #-16]!
+ b _save_el_regs /* jump to the second part */
+
+ .align 7 /* Current EL IRQ Thread */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_bad_irq
+ b exception_exit
+
+/*
+ * Save exception specific context: ESR and ELR, for all exception levels.
+ * This is the second part of the shared routine called into from all entries.
+ */
+_save_el_regs:
+ /* Could be running at EL3/EL2/EL1 */
+ switch_el x11, 3f, 2f, 1f
+3: mrs x1, esr_el3
+ mrs x2, elr_el3
+ b 0f
+2: mrs x1, esr_el2
+ mrs x2, elr_el2
+ b 0f
+1: mrs x1, esr_el1
+ mrs x2, elr_el1
+0:
+ stp x2, x0, [sp, #-16]!
+ mov x0, sp
+ ret
+
+ .align 7 /* Current EL FIQ Thread */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_bad_fiq
+ /* falling through to _exception_exit */
+/*
+ * Restore the exception return address, for all exception levels.
+ * This is the first part of the shared routine called into from all entries.
+ */
+exception_exit:
+ ldp x2, x0, [sp],#16
+ switch_el x11, 3f, 2f, 1f
+3: msr elr_el3, x2
+ b _restore_regs
+2: msr elr_el2, x2
+ b _restore_regs
+1: msr elr_el1, x2
+ b _restore_regs /* jump to the second part */
+
+ .align 7 /* Current EL Error Thread */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_bad_error
+ b exception_exit
+
+/*
+ * Restore the general purpose registers from the exception stack, then return.
+ * This is the second part of the shared routine called into from all entries.
+ */
+_restore_regs:
+ ldp x1, x2, [sp],#16
+ ldp x3, x4, [sp],#16
+ ldp x5, x6, [sp],#16
+ ldp x7, x8, [sp],#16
+ ldp x9, x10, [sp],#16
+ ldp x11, x12, [sp],#16
+ ldp x13, x14, [sp],#16
+ ldp x15, x16, [sp],#16
+ ldp x17, x18, [sp],#16
+ ldp x19, x20, [sp],#16
+ ldp x21, x22, [sp],#16
+ ldp x23, x24, [sp],#16
+ ldp x25, x26, [sp],#16
+ ldp x27, x28, [sp],#16
+ ldp x29, x30, [sp],#16
+ eret
+
+ .align 7 /* Current EL (SP_ELx) Synchronous Handler */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_sync
+ b exception_exit
+
+ .align 7 /* Current EL (SP_ELx) IRQ Handler */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_irq
+ b exception_exit
+
+ .align 7 /* Current EL (SP_ELx) FIQ Handler */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_fiq
+ b exception_exit
+
+ .align 7 /* Current EL (SP_ELx) Error Handler */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_error
+ b exception_exit
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fel_utils.S b/roms/u-boot/arch/arm/cpu/armv8/fel_utils.S
new file mode 100644
index 000000000..7def44ad1
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fel_utils.S
@@ -0,0 +1,81 @@
+/*
+ * Utility functions for FEL mode, when running SPL in AArch64.
+ *
+ * Copyright (c) 2017 Arm Ltd.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/system.h>
+#include <linux/linkage.h>
+
+/*
+ * We don't overwrite save_boot_params() here, to save the FEL state upon
+ * entry, since this would run *after* the RMR reset, which clobbers that
+ * state.
+ * Instead we store the state _very_ early in the boot0 hook, *before*
+ * resetting to AArch64.
+ */
+
+/*
+ * The FEL routines in BROM run in AArch32.
+ * Reset back into 32-bit mode here and restore the saved FEL state
+ * afterwards.
+ * Resetting back into AArch32/EL3 using the RMR always enters the BROM,
+ * but we can use the CPU hotplug mechanism to branch back to our code
+ * immediately.
+ */
+ENTRY(return_to_fel)
+ /*
+ * the RMR reset will clear all registers, so save the arguments
+ * (LR and SP) in the fel_stash structure, which we read anyways later
+ */
+ adr x2, fel_stash
+ str w0, [x2]
+ str w1, [x2, #4]
+
+ adr x1, fel_stash_addr // to find the fel_stash address in AA32
+ str w2, [x1]
+
+ ldr x0, =0xfa50392f // CPU hotplug magic
+#ifdef CONFIG_MACH_SUN50I_H616
+ ldr x2, =(SUNXI_R_CPUCFG_BASE + 0x1c0)
+ str w0, [x2], #0x4
+#elif CONFIG_MACH_SUN50I_H6
+ ldr x2, =(SUNXI_RTC_BASE + 0x1b8) // BOOT_CPU_HP_FLAG_REG
+ str w0, [x2], #0x4
+#else
+ ldr x2, =(SUNXI_CPUCFG_BASE + 0x1a4) // offset for CPU hotplug base
+ str w0, [x2, #0x8]
+#endif
+ adr x0, back_in_32
+ str w0, [x2]
+
+ dsb sy
+ isb sy
+ mov x0, #2 // RMR reset into AArch32
+ dsb sy
+ msr RMR_EL3, x0
+ isb sy
+1: wfi
+ b 1b
+
+/* AArch32 code to restore the state from fel_stash and return back to FEL. */
+back_in_32:
+ .word 0xe59f0028 // ldr r0, [pc, #40] ; load fel_stash address
+ .word 0xe5901008 // ldr r1, [r0, #8]
+ .word 0xe129f001 // msr CPSR_fc, r1
+ .word 0xf57ff06f // isb
+ .word 0xe590d000 // ldr sp, [r0]
+ .word 0xe590e004 // ldr lr, [r0, #4]
+ .word 0xe5901010 // ldr r1, [r0, #16]
+ .word 0xee0c1f10 // mcr 15, 0, r1, cr12, cr0, {0} ; VBAR
+ .word 0xe590100c // ldr r1, [r0, #12]
+ .word 0xee011f10 // mcr 15, 0, r1, cr1, cr0, {0} ; SCTLR
+ .word 0xf57ff06f // isb
+ .word 0xe12fff1e // bx lr ; return to FEL
+fel_stash_addr:
+ .word 0x00000000 // receives fel_stash addr, by AA64 code above
+ENDPROC(return_to_fel)
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
new file mode 100644
index 000000000..9c58f69db
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -0,0 +1,658 @@
+config ARCH_LS1012A
+ bool
+ select ARMV8_SET_SMPEN
+ select ARM_ERRATA_855873 if !TFABOOT
+ select FSL_LAYERSCAPE
+ select FSL_LSCH2
+ select SYS_FSL_SRDS_1
+ select SYS_HAS_SERDES
+ select SYS_FSL_DDR_BE
+ select SYS_FSL_MMDC
+ select SYS_FSL_ERRATUM_A010315
+ select SYS_FSL_ERRATUM_A009798
+ select SYS_FSL_ERRATUM_A008997
+ select SYS_FSL_ERRATUM_A009007
+ select SYS_FSL_ERRATUM_A009008
+ select ARCH_EARLY_INIT_R
+ select BOARD_EARLY_INIT_F
+ select SYS_I2C_MXC
+ select SYS_I2C_MXC_I2C1 if !DM_I2C
+ select SYS_I2C_MXC_I2C2 if !DM_I2C
+ imply PANIC_HANG
+
+config ARCH_LS1028A
+ bool
+ select ARMV8_SET_SMPEN
+ select FSL_LAYERSCAPE
+ select FSL_LSCH3
+ select NXP_LSCH3_2
+ select SYS_FSL_HAS_CCI400
+ select SYS_FSL_SRDS_1
+ select SYS_HAS_SERDES
+ select SYS_FSL_DDR
+ select SYS_FSL_DDR_LE
+ select SYS_FSL_DDR_VER_50
+ select SYS_FSL_HAS_DDR3
+ select SYS_FSL_HAS_DDR4
+ select SYS_FSL_HAS_SEC
+ select SYS_FSL_SEC_COMPAT_5
+ select SYS_FSL_SEC_LE
+ select FSL_TZASC_1
+ select ARCH_EARLY_INIT_R
+ select BOARD_EARLY_INIT_F
+ select SYS_I2C_MXC
+ select SYS_FSL_ERRATUM_A008997
+ select SYS_FSL_ERRATUM_A009007
+ select SYS_FSL_ERRATUM_A008514 if !TFABOOT
+ select SYS_FSL_ERRATUM_A009663 if !TFABOOT
+ select SYS_FSL_ERRATUM_A009942 if !TFABOOT
+ select SYS_FSL_ERRATUM_A050382
+ select SYS_FSL_ERRATUM_A011334
+ select SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND
+ select RESV_RAM if GIC_V3_ITS
+ imply PANIC_HANG
+
+config ARCH_LS1043A
+ bool
+ select ARMV8_SET_SMPEN
+ select ARM_ERRATA_855873 if !TFABOOT
+ select FSL_LAYERSCAPE
+ select FSL_LSCH2
+ select SYS_FSL_SRDS_1
+ select SYS_HAS_SERDES
+ select SYS_FSL_DDR
+ select SYS_FSL_DDR_BE
+ select SYS_FSL_DDR_VER_50
+ select SYS_FSL_ERRATUM_A008850 if !TFABOOT
+ select SYS_FSL_ERRATUM_A008997
+ select SYS_FSL_ERRATUM_A009007
+ select SYS_FSL_ERRATUM_A009008
+ select SYS_FSL_ERRATUM_A009660 if !TFABOOT
+ select SYS_FSL_ERRATUM_A009663 if !TFABOOT
+ select SYS_FSL_ERRATUM_A009798
+ select SYS_FSL_ERRATUM_A009942 if !TFABOOT
+ select SYS_FSL_ERRATUM_A010315
+ select SYS_FSL_ERRATUM_A010539
+ select SYS_FSL_HAS_DDR3
+ select SYS_FSL_HAS_DDR4
+ select ARCH_EARLY_INIT_R
+ select BOARD_EARLY_INIT_F
+ select SYS_I2C_MXC
+ select SYS_I2C_MXC_I2C1 if !DM_I2C
+ select SYS_I2C_MXC_I2C2 if !DM_I2C
+ select SYS_I2C_MXC_I2C3 if !DM_I2C
+ select SYS_I2C_MXC_I2C4 if !DM_I2C
+ imply CMD_PCI
+
+config ARCH_LS1046A
+ bool
+ select ARMV8_SET_SMPEN
+ select FSL_LAYERSCAPE
+ select FSL_LSCH2
+ select SYS_FSL_SRDS_1
+ select SYS_HAS_SERDES
+ select SYS_FSL_DDR
+ select SYS_FSL_DDR_BE
+ select SYS_FSL_DDR_VER_50
+ select SYS_FSL_ERRATUM_A008336 if !TFABOOT
+ select SYS_FSL_ERRATUM_A008511 if !TFABOOT
+ select SYS_FSL_ERRATUM_A008850 if !TFABOOT
+ select SYS_FSL_ERRATUM_A008997
+ select SYS_FSL_ERRATUM_A009007
+ select SYS_FSL_ERRATUM_A009008
+ select SYS_FSL_ERRATUM_A009798
+ select SYS_FSL_ERRATUM_A009801
+ select SYS_FSL_ERRATUM_A009803 if !TFABOOT
+ select SYS_FSL_ERRATUM_A009942 if !TFABOOT
+ select SYS_FSL_ERRATUM_A010165 if !TFABOOT
+ select SYS_FSL_ERRATUM_A010539
+ select SYS_FSL_HAS_DDR4
+ select SYS_FSL_SRDS_2
+ select ARCH_EARLY_INIT_R
+ select BOARD_EARLY_INIT_F
+ select SYS_I2C_MXC
+ select SYS_I2C_MXC_I2C1 if !DM_I2C
+ select SYS_I2C_MXC_I2C2 if !DM_I2C
+ select SYS_I2C_MXC_I2C3 if !DM_I2C
+ select SYS_I2C_MXC_I2C4 if !DM_I2C
+ imply SCSI
+ imply SCSI_AHCI
+
+config ARCH_LS1088A
+ bool
+ select ARMV8_SET_SMPEN
+ select ARM_ERRATA_855873 if !TFABOOT
+ select FSL_LAYERSCAPE
+ select FSL_LSCH3
+ select SYS_FSL_SRDS_1
+ select SYS_HAS_SERDES
+ select SYS_FSL_DDR
+ select SYS_FSL_DDR_LE
+ select SYS_FSL_DDR_VER_50
+ select SYS_FSL_EC1
+ select SYS_FSL_EC2
+ select SYS_FSL_ERRATUM_A009803 if !TFABOOT
+ select SYS_FSL_ERRATUM_A009942 if !TFABOOT
+ select SYS_FSL_ERRATUM_A010165 if !TFABOOT
+ select SYS_FSL_ERRATUM_A008511 if !TFABOOT
+ select SYS_FSL_ERRATUM_A008850 if !TFABOOT
+ select SYS_FSL_ERRATUM_A009007
+ select SYS_FSL_HAS_CCI400
+ select SYS_FSL_HAS_DDR4
+ select SYS_FSL_HAS_RGMII
+ select SYS_FSL_HAS_SEC
+ select SYS_FSL_SEC_COMPAT_5
+ select SYS_FSL_SEC_LE
+ select SYS_FSL_SRDS_1
+ select SYS_FSL_SRDS_2
+ select FSL_TZASC_1
+ select FSL_TZASC_400
+ select FSL_TZPC_BP147
+ select ARCH_EARLY_INIT_R
+ select BOARD_EARLY_INIT_F
+ select SYS_I2C_MXC
+ select SYS_I2C_MXC_I2C1 if !TFABOOT
+ select SYS_I2C_MXC_I2C2 if !TFABOOT
+ select SYS_I2C_MXC_I2C3 if !TFABOOT
+ select SYS_I2C_MXC_I2C4 if !TFABOOT
+ select RESV_RAM if GIC_V3_ITS
+ imply SCSI
+ imply PANIC_HANG
+
+config ARCH_LS2080A
+ bool
+ select ARMV8_SET_SMPEN
+ select ARM_ERRATA_826974
+ select ARM_ERRATA_828024
+ select ARM_ERRATA_829520
+ select ARM_ERRATA_833471
+ select FSL_LAYERSCAPE
+ select FSL_LSCH3
+ select SYS_FSL_SRDS_1
+ select SYS_HAS_SERDES
+ select SYS_FSL_DDR
+ select SYS_FSL_DDR_LE
+ select SYS_FSL_DDR_VER_50
+ select SYS_FSL_HAS_CCN504
+ select SYS_FSL_HAS_DP_DDR
+ select SYS_FSL_HAS_SEC
+ select SYS_FSL_HAS_DDR4
+ select SYS_FSL_SEC_COMPAT_5
+ select SYS_FSL_SEC_LE
+ select SYS_FSL_SRDS_2
+ select FSL_TZASC_1
+ select FSL_TZASC_2
+ select FSL_TZASC_400
+ select FSL_TZPC_BP147
+ select SYS_FSL_ERRATUM_A008336 if !TFABOOT
+ select SYS_FSL_ERRATUM_A008511 if !TFABOOT
+ select SYS_FSL_ERRATUM_A008514 if !TFABOOT
+ select SYS_FSL_ERRATUM_A008585
+ select SYS_FSL_ERRATUM_A008997
+ select SYS_FSL_ERRATUM_A009007
+ select SYS_FSL_ERRATUM_A009008
+ select SYS_FSL_ERRATUM_A009635
+ select SYS_FSL_ERRATUM_A009663 if !TFABOOT
+ select SYS_FSL_ERRATUM_A009798
+ select SYS_FSL_ERRATUM_A009801
+ select SYS_FSL_ERRATUM_A009803 if !TFABOOT
+ select SYS_FSL_ERRATUM_A009942 if !TFABOOT
+ select SYS_FSL_ERRATUM_A010165 if !TFABOOT
+ select SYS_FSL_ERRATUM_A009203
+ select ARCH_EARLY_INIT_R
+ select BOARD_EARLY_INIT_F
+ select SYS_I2C_MXC
+ select SYS_I2C_MXC_I2C1 if !TFABOOT
+ select SYS_I2C_MXC_I2C2 if !TFABOOT
+ select SYS_I2C_MXC_I2C3 if !TFABOOT
+ select SYS_I2C_MXC_I2C4 if !TFABOOT
+ select RESV_RAM if GIC_V3_ITS
+ imply DISTRO_DEFAULTS
+ imply PANIC_HANG
+
+config ARCH_LX2162A
+ bool
+ select ARMV8_SET_SMPEN
+ select FSL_LSCH3
+ select NXP_LSCH3_2
+ select SYS_HAS_SERDES
+ select SYS_FSL_SRDS_1
+ select SYS_FSL_SRDS_2
+ select SYS_FSL_DDR
+ select SYS_FSL_DDR_LE
+ select SYS_FSL_DDR_VER_50
+ select SYS_FSL_EC1
+ select SYS_FSL_EC2
+ select SYS_FSL_ERRATUM_A050204
+ select SYS_FSL_ERRATUM_A011334
+ select SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND
+ select SYS_FSL_HAS_RGMII
+ select SYS_FSL_HAS_SEC
+ select SYS_FSL_HAS_CCN508
+ select SYS_FSL_HAS_DDR4
+ select SYS_FSL_SEC_COMPAT_5
+ select SYS_FSL_SEC_LE
+ select ARCH_EARLY_INIT_R
+ select BOARD_EARLY_INIT_F
+ select SYS_I2C_MXC
+ select RESV_RAM if GIC_V3_ITS
+ imply DISTRO_DEFAULTS
+ imply PANIC_HANG
+ imply SCSI
+ imply SCSI_AHCI
+
+config ARCH_LX2160A
+ bool
+ select ARMV8_SET_SMPEN
+ select FSL_LSCH3
+ select NXP_LSCH3_2
+ select SYS_HAS_SERDES
+ select SYS_FSL_SRDS_1
+ select SYS_FSL_SRDS_2
+ select SYS_NXP_SRDS_3
+ select SYS_FSL_DDR
+ select SYS_FSL_DDR_LE
+ select SYS_FSL_DDR_VER_50
+ select SYS_FSL_EC1
+ select SYS_FSL_EC2
+ select SYS_FSL_ERRATUM_A050204
+ select SYS_FSL_ERRATUM_A011334
+ select SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND
+ select SYS_FSL_HAS_RGMII
+ select SYS_FSL_HAS_SEC
+ select SYS_FSL_HAS_CCN508
+ select SYS_FSL_HAS_DDR4
+ select SYS_FSL_SEC_COMPAT_5
+ select SYS_FSL_SEC_LE
+ select ARCH_EARLY_INIT_R
+ select BOARD_EARLY_INIT_F
+ select SYS_I2C_MXC
+ select RESV_RAM if GIC_V3_ITS
+ imply DISTRO_DEFAULTS
+ imply PANIC_HANG
+ imply SCSI
+ imply SCSI_AHCI
+
+config FSL_LSCH2
+ bool
+ select SYS_FSL_HAS_CCI400
+ select SYS_FSL_HAS_SEC
+ select SYS_FSL_SEC_COMPAT_5
+ select SYS_FSL_SEC_BE
+
+config FSL_LSCH3
+ select ARCH_MISC_INIT
+ bool
+
+config NXP_LSCH3_2
+ bool
+
+menu "Layerscape architecture"
+ depends on FSL_LSCH2 || FSL_LSCH3
+
+config FSL_LAYERSCAPE
+ bool
+
+config HAS_FEATURE_GIC64K_ALIGN
+ bool
+ default y if ARCH_LS1043A
+
+config HAS_FEATURE_ENHANCED_MSI
+ bool
+ default y if ARCH_LS1043A
+
+menu "Layerscape PPA"
+config FSL_LS_PPA
+ bool "FSL Layerscape PPA firmware support"
+ depends on !ARMV8_PSCI
+ select ARMV8_SEC_FIRMWARE_SUPPORT
+ select SEC_FIRMWARE_ARMV8_PSCI
+ select ARMV8_SEC_FIRMWARE_ERET_ADDR_REVERT if FSL_LSCH2
+ help
+ The FSL Primary Protected Application (PPA) is a software component
+ which is loaded during boot stage, and then remains resident in RAM
+ and runs in the TrustZone after boot.
+ Say y to enable it.
+
+config SPL_FSL_LS_PPA
+ bool "FSL Layerscape PPA firmware support for SPL build"
+ depends on !ARMV8_PSCI
+ select SPL_ARMV8_SEC_FIRMWARE_SUPPORT
+ select SEC_FIRMWARE_ARMV8_PSCI
+ select ARMV8_SEC_FIRMWARE_ERET_ADDR_REVERT if FSL_LSCH2
+ help
+ The FSL Primary Protected Application (PPA) is a software component
+ which is loaded during boot stage, and then remains resident in RAM
+ and runs in the TrustZone after boot. This is to load PPA during SPL
+ stage instead of the RAM version of U-Boot. Once PPA is initialized,
+ the rest of U-Boot (including RAM version) runs at EL2.
+choice
+ prompt "FSL Layerscape PPA firmware loading-media select"
+ depends on FSL_LS_PPA
+ default SYS_LS_PPA_FW_IN_MMC if SD_BOOT
+ default SYS_LS_PPA_FW_IN_NAND if NAND_BOOT
+ default SYS_LS_PPA_FW_IN_XIP
+
+config SYS_LS_PPA_FW_IN_XIP
+ bool "XIP"
+ help
+ Say Y here if the PPA firmware locate at XIP flash, such
+ as NOR or QSPI flash.
+
+config SYS_LS_PPA_FW_IN_MMC
+ bool "eMMC or SD Card"
+ help
+ Say Y here if the PPA firmware locate at eMMC/SD card.
+
+config SYS_LS_PPA_FW_IN_NAND
+ bool "NAND"
+ help
+ Say Y here if the PPA firmware locate at NAND flash.
+
+endchoice
+
+config LS_PPA_ESBC_HDR_SIZE
+ hex "Length of PPA ESBC header"
+ depends on FSL_LS_PPA && CHAIN_OF_TRUST && !SYS_LS_PPA_FW_IN_XIP
+ default 0x2000
+ help
+ Length (in bytes) of PPA ESBC header to be copied from MMC/SD or
+ NAND to memory to validate PPA image.
+
+endmenu
+
+config SYS_FSL_ERRATUM_A008997
+ bool "Workaround for USB PHY erratum A008997"
+
+config SYS_FSL_ERRATUM_A009007
+ bool
+ help
+ Workaround for USB PHY erratum A009007
+
+config SYS_FSL_ERRATUM_A009008
+ bool "Workaround for USB PHY erratum A009008"
+
+config SYS_FSL_ERRATUM_A009798
+ bool "Workaround for USB PHY erratum A009798"
+
+config SYS_FSL_ERRATUM_A050204
+ bool "Workaround for USB PHY erratum A050204"
+ help
+ USB3.0 Receiver needs to enable fixed equalization
+ for each of PHY instances in an SOC. This is similar
+ to erratum A-009007, but this one is for LX2160A and LX2162A,
+ and the register value is different.
+
+config SYS_FSL_ERRATUM_A010315
+ bool "Workaround for PCIe erratum A010315"
+
+config SYS_FSL_ERRATUM_A010539
+ bool "Workaround for PIN MUX erratum A010539"
+
+config MAX_CPUS
+ int "Maximum number of CPUs permitted for Layerscape"
+ default 2 if ARCH_LS1028A
+ default 4 if ARCH_LS1043A
+ default 4 if ARCH_LS1046A
+ default 16 if ARCH_LS2080A
+ default 8 if ARCH_LS1088A
+ default 16 if ARCH_LX2160A
+ default 16 if ARCH_LX2162A
+ default 1
+ help
+ Set this number to the maximum number of possible CPUs in the SoC.
+ SoCs may have multiple clusters with each cluster may have multiple
+ ports. If some ports are reserved but higher ports are used for
+ cores, count the reserved ports. This will allocate enough memory
+ in spin table to properly handle all cores.
+
+config EMC2305
+ bool "Fan controller"
+ help
+ Enable the EMC2305 fan controller for configuration of fan
+ speed.
+
+config NXP_ESBC
+ bool "NXP_ESBC"
+ help
+ Enable Freescale Secure Boot feature
+
+config QSPI_AHB_INIT
+ bool "Init the QSPI AHB bus"
+ help
+ The default setting for QSPI AHB bus just support 3bytes addressing.
+ But some QSPI flash size up to 64MBytes, so initialize the QSPI AHB
+ bus for those flashes to support the full QSPI flash size.
+
+config FSPI_AHB_EN_4BYTE
+ bool "Enable 4-byte Fast Read command for AHB mode"
+ default n
+ help
+ The default setting for FlexSPI AHB bus just supports 3-byte addressing.
+ But some FlexSPI flash sizes are up to 64MBytes.
+ This flag enables fast read command for AHB mode and modifies required
+ LUT to support full FlexSPI flash.
+
+config SYS_CCI400_OFFSET
+ hex "Offset for CCI400 base"
+ depends on SYS_FSL_HAS_CCI400
+ default 0x3090000 if ARCH_LS1088A || ARCH_LS1028A
+ default 0x180000 if FSL_LSCH2
+ help
+ Offset for CCI400 base
+ CCI400 base addr = CCSRBAR + CCI400_OFFSET
+
+config SYS_FSL_IFC_BANK_COUNT
+ int "Maximum banks of Integrated flash controller"
+ depends on ARCH_LS1043A || ARCH_LS1046A || ARCH_LS2080A || ARCH_LS1088A
+ default 4 if ARCH_LS1043A
+ default 4 if ARCH_LS1046A
+ default 8 if ARCH_LS2080A || ARCH_LS1088A
+
+config SYS_FSL_HAS_CCI400
+ bool
+
+config SYS_FSL_HAS_CCN504
+ bool
+
+config SYS_FSL_HAS_CCN508
+ bool
+
+config SYS_FSL_HAS_DP_DDR
+ bool
+
+config SYS_FSL_SRDS_1
+ bool
+
+config SYS_FSL_SRDS_2
+ bool
+
+config SYS_NXP_SRDS_3
+ bool
+
+config SYS_HAS_SERDES
+ bool
+
+config FSL_TZASC_1
+ bool
+
+config FSL_TZASC_2
+ bool
+
+config FSL_TZASC_400
+ bool
+
+config FSL_TZPC_BP147
+ bool
+endmenu
+
+menu "Layerscape clock tree configuration"
+ depends on FSL_LSCH2 || FSL_LSCH3
+
+config SYS_FSL_CLK
+ bool "Enable clock tree initialization"
+ default y
+
+config CLUSTER_CLK_FREQ
+ int "Reference clock of core cluster"
+ depends on ARCH_LS1012A
+ default 100000000
+ help
+ This number is the reference clock frequency of core PLL.
+ For most platforms, the core PLL and Platform PLL have the same
+ reference clock, but for some platforms, LS1012A for instance,
+ they are provided sepatately.
+
+config SYS_FSL_PCLK_DIV
+ int "Platform clock divider"
+ default 1 if ARCH_LS1028A
+ default 1 if ARCH_LS1043A
+ default 1 if ARCH_LS1046A
+ default 1 if ARCH_LS1088A
+ default 2
+ help
+ This is the divider that is used to derive Platform clock from
+ Platform PLL, in another word:
+ Platform_clk = Platform_PLL_freq / this_divider
+
+config SYS_FSL_DSPI_CLK_DIV
+ int "DSPI clock divider"
+ default 1 if ARCH_LS1043A
+ default 2
+ help
+ This is the divider that is used to derive DSPI clock from Platform
+ clock, in another word DSPI_clk = Platform_clk / this_divider.
+
+config SYS_FSL_DUART_CLK_DIV
+ int "DUART clock divider"
+ default 1 if ARCH_LS1043A
+ default 4 if ARCH_LX2160A
+ default 4 if ARCH_LX2162A
+ default 2
+ help
+ This is the divider that is used to derive DUART clock from Platform
+ clock, in another word DUART_clk = Platform_clk / this_divider.
+
+config SYS_FSL_I2C_CLK_DIV
+ int "I2C clock divider"
+ default 1 if ARCH_LS1043A
+ default 4 if ARCH_LS1012A
+ default 4 if ARCH_LS1028A
+ default 8 if ARCH_LX2160A
+ default 8 if ARCH_LX2162A
+ default 8 if ARCH_LS1088A
+ default 2
+ help
+ This is the divider that is used to derive I2C clock from Platform
+ clock, in another word I2C_clk = Platform_clk / this_divider.
+
+config SYS_FSL_IFC_CLK_DIV
+ int "IFC clock divider"
+ default 1 if ARCH_LS1043A
+ default 4 if ARCH_LS1012A
+ default 4 if ARCH_LS1028A
+ default 8 if ARCH_LX2160A
+ default 8 if ARCH_LX2162A
+ default 8 if ARCH_LS1088A
+ default 2
+ help
+ This is the divider that is used to derive IFC clock from Platform
+ clock, in another word IFC_clk = Platform_clk / this_divider.
+
+config SYS_FSL_LPUART_CLK_DIV
+ int "LPUART clock divider"
+ default 1 if ARCH_LS1043A
+ default 2
+ help
+ This is the divider that is used to derive LPUART clock from Platform
+ clock, in another word LPUART_clk = Platform_clk / this_divider.
+
+config SYS_FSL_SDHC_CLK_DIV
+ int "SDHC clock divider"
+ default 1 if ARCH_LS1043A
+ default 1 if ARCH_LS1012A
+ default 2
+ help
+ This is the divider that is used to derive SDHC clock from Platform
+ clock, in another word SDHC_clk = Platform_clk / this_divider.
+
+config SYS_FSL_QMAN_CLK_DIV
+ int "QMAN clock divider"
+ default 1 if ARCH_LS1043A
+ default 2
+ help
+ This is the divider that is used to derive QMAN clock from Platform
+ clock, in another word QMAN_clk = Platform_clk / this_divider.
+endmenu
+
+config RESV_RAM
+ bool
+ help
+ Reserve memory from the top, tracked by gd->arch.resv_ram. This
+ reserved RAM can be used by special driver that resides in memory
+ after U-Boot exits. It's up to implementation to allocate and allow
+ access to this reserved memory. For example, the reserved RAM can
+ be at the high end of physical memory. The reserve RAM may be
+ excluded from memory bank(s) passed to OS, or marked as reserved.
+
+config SYS_FSL_EC1
+ bool
+ help
+ Ethernet controller 1, this is connected to
+ MAC17 for LX2160A and LX2162A or to MAC3 for other SoCs
+ Provides DPAA2 capabilities
+
+config SYS_FSL_EC2
+ bool
+ help
+ Ethernet controller 2, this is connected to
+ MAC18 for LX2160A and LX2162A or to MAC4 for other SoCs
+ Provides DPAA2 capabilities
+
+config SYS_FSL_ERRATUM_A008336
+ bool
+
+config SYS_FSL_ERRATUM_A008514
+ bool
+
+config SYS_FSL_ERRATUM_A008585
+ bool
+
+config SYS_FSL_ERRATUM_A008850
+ bool
+
+config SYS_FSL_ERRATUM_A009203
+ bool
+
+config SYS_FSL_ERRATUM_A009635
+ bool
+
+config SYS_FSL_ERRATUM_A009660
+ bool
+
+config SYS_FSL_ERRATUM_A050382
+ bool
+
+config SYS_FSL_HAS_RGMII
+ bool
+ depends on SYS_FSL_EC1 || SYS_FSL_EC2
+
+config SPL_LDSCRIPT
+ default "arch/arm/cpu/armv8/u-boot-spl.lds" if ARCH_LS1043A || ARCH_LS1046A || ARCH_LS2080A
+
+config HAS_FSL_XHCI_USB
+ bool
+ default y if ARCH_LS1043A || ARCH_LS1046A
+ help
+ For some SoC(such as LS1043A and LS1046A), USB and QE-HDLC multiplex use
+ pins, select it when the pins are assigned to USB.
+
+config SYS_FSL_BOOTROM_BASE
+ hex
+ depends on FSL_LSCH2
+ default 0
+
+config SYS_FSL_BOOTROM_SIZE
+ hex
+ depends on FSL_LSCH2
+ default 0x1000000
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/Makefile b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/Makefile
new file mode 100644
index 000000000..598c36ee6
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/Makefile
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2016-2018 NXP
+# Copyright 2014-2015, Freescale Semiconductor
+
+obj-y += cpu.o
+obj-y += lowlevel.o
+obj-y += soc.o
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_MP) += mp.o spintable.o
+obj-$(CONFIG_OF_LIBFDT) += fdt.o
+endif
+obj-$(CONFIG_SPL) += spl.o
+obj-$(CONFIG_$(SPL_)FSL_LS_PPA) += ppa.o
+
+ifneq ($(CONFIG_FSL_LSCH3),)
+obj-y += fsl_lsch3_speed.o
+obj-$(CONFIG_SYS_HAS_SERDES) += fsl_lsch3_serdes.o
+else
+ifneq ($(CONFIG_FSL_LSCH2),)
+obj-y += fsl_lsch2_speed.o
+obj-$(CONFIG_SYS_HAS_SERDES) += fsl_lsch2_serdes.o
+endif
+endif
+
+ifneq ($(CONFIG_ARCH_LX2160A),)
+obj-$(CONFIG_SYS_HAS_SERDES) += lx2160a_serdes.o
+obj-y += icid.o lx2160_ids.o
+endif
+
+ifneq ($(CONFIG_ARCH_LX2162A),)
+obj-$(CONFIG_SYS_HAS_SERDES) += lx2160a_serdes.o
+obj-y += icid.o lx2160_ids.o
+endif
+
+ifneq ($(CONFIG_ARCH_LS2080A),)
+obj-$(CONFIG_SYS_HAS_SERDES) += ls2080a_serdes.o
+obj-y += icid.o ls2088_ids.o
+endif
+
+ifneq ($(CONFIG_ARCH_LS1043A),)
+obj-$(CONFIG_SYS_HAS_SERDES) += ls1043a_serdes.o
+obj-$(CONFIG_ARMV8_PSCI) += ls1043a_psci.o
+obj-y += icid.o ls1043_ids.o
+endif
+
+ifneq ($(CONFIG_ARCH_LS1012A),)
+obj-$(CONFIG_SYS_HAS_SERDES) += ls1012a_serdes.o
+endif
+
+ifneq ($(CONFIG_ARCH_LS1046A),)
+obj-$(CONFIG_SYS_HAS_SERDES) += ls1046a_serdes.o
+obj-y += icid.o ls1046_ids.o
+endif
+
+ifneq ($(CONFIG_ARCH_LS1088A),)
+obj-$(CONFIG_SYS_HAS_SERDES) += ls1088a_serdes.o
+obj-y += icid.o ls1088_ids.o
+endif
+
+ifneq ($(CONFIG_ARCH_LS1028A),)
+obj-$(CONFIG_SYS_HAS_SERDES) += ls1028a_serdes.o
+obj-y += icid.o ls1028_ids.o
+endif
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
new file mode 100644
index 000000000..d0103fc88
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -0,0 +1,1656 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017-2020 NXP
+ * Copyright 2014-2015 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <env.h>
+#include <fsl_ddr_sdram.h>
+#include <init.h>
+#include <hang.h>
+#include <log.h>
+#include <net.h>
+#include <vsprintf.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/ptrace.h>
+#include <linux/errno.h>
+#include <asm/system.h>
+#include <fm_eth.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/soc.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/speed.h>
+#include <fsl_immap.h>
+#include <asm/arch/mp.h>
+#include <efi_loader.h>
+#include <fsl-mc/fsl_mc.h>
+#ifdef CONFIG_FSL_ESDHC
+#include <fsl_esdhc.h>
+#endif
+#include <asm/armv8/sec_firmware.h>
+#ifdef CONFIG_SYS_FSL_DDR
+#include <fsl_ddr.h>
+#endif
+#include <asm/arch/clock.h>
+#include <hwconfig.h>
+#include <fsl_qbman.h>
+
+#ifdef CONFIG_TFABOOT
+#include <env_internal.h>
+#ifdef CONFIG_CHAIN_OF_TRUST
+#include <fsl_validate.h>
+#endif
+#endif
+#include <linux/mii.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct cpu_type cpu_type_list[] = {
+ CPU_TYPE_ENTRY(LS2080A, LS2080A, 8),
+ CPU_TYPE_ENTRY(LS2085A, LS2085A, 8),
+ CPU_TYPE_ENTRY(LS2045A, LS2045A, 4),
+ CPU_TYPE_ENTRY(LS2088A, LS2088A, 8),
+ CPU_TYPE_ENTRY(LS2084A, LS2084A, 8),
+ CPU_TYPE_ENTRY(LS2048A, LS2048A, 4),
+ CPU_TYPE_ENTRY(LS2044A, LS2044A, 4),
+ CPU_TYPE_ENTRY(LS2081A, LS2081A, 8),
+ CPU_TYPE_ENTRY(LS2041A, LS2041A, 4),
+ CPU_TYPE_ENTRY(LS1043A, LS1043A, 4),
+ CPU_TYPE_ENTRY(LS1043A, LS1043A_P23, 4),
+ CPU_TYPE_ENTRY(LS1023A, LS1023A, 2),
+ CPU_TYPE_ENTRY(LS1023A, LS1023A_P23, 2),
+ CPU_TYPE_ENTRY(LS1046A, LS1046A, 4),
+ CPU_TYPE_ENTRY(LS1026A, LS1026A, 2),
+ CPU_TYPE_ENTRY(LS2040A, LS2040A, 4),
+ CPU_TYPE_ENTRY(LS1012A, LS1012A, 1),
+ CPU_TYPE_ENTRY(LS1017A, LS1017A, 1),
+ CPU_TYPE_ENTRY(LS1018A, LS1018A, 1),
+ CPU_TYPE_ENTRY(LS1027A, LS1027A, 2),
+ CPU_TYPE_ENTRY(LS1028A, LS1028A, 2),
+ CPU_TYPE_ENTRY(LS1088A, LS1088A, 8),
+ CPU_TYPE_ENTRY(LS1084A, LS1084A, 8),
+ CPU_TYPE_ENTRY(LS1048A, LS1048A, 4),
+ CPU_TYPE_ENTRY(LS1044A, LS1044A, 4),
+ CPU_TYPE_ENTRY(LX2160A, LX2160A, 16),
+ CPU_TYPE_ENTRY(LX2120A, LX2120A, 12),
+ CPU_TYPE_ENTRY(LX2080A, LX2080A, 8),
+ CPU_TYPE_ENTRY(LX2162A, LX2162A, 16),
+ CPU_TYPE_ENTRY(LX2122A, LX2122A, 12),
+ CPU_TYPE_ENTRY(LX2082A, LX2082A, 8),
+};
+
+#define EARLY_PGTABLE_SIZE 0x5000
+static struct mm_region early_map[] = {
+#ifdef CONFIG_FSL_LSCH3
+ { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
+ CONFIG_SYS_FSL_CCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
+ SYS_FSL_OCRAM_SPACE_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
+ { CONFIG_SYS_FSL_QSPI_BASE1, CONFIG_SYS_FSL_QSPI_BASE1,
+ CONFIG_SYS_FSL_QSPI_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE},
+#ifdef CONFIG_FSL_IFC
+ /* For IFC Region #1, only the first 4MB is cache-enabled */
+ { CONFIG_SYS_FSL_IFC_BASE1, CONFIG_SYS_FSL_IFC_BASE1,
+ CONFIG_SYS_FSL_IFC_SIZE1_1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
+ { CONFIG_SYS_FSL_IFC_BASE1 + CONFIG_SYS_FSL_IFC_SIZE1_1,
+ CONFIG_SYS_FSL_IFC_BASE1 + CONFIG_SYS_FSL_IFC_SIZE1_1,
+ CONFIG_SYS_FSL_IFC_SIZE1 - CONFIG_SYS_FSL_IFC_SIZE1_1,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
+ { CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FSL_IFC_BASE1,
+ CONFIG_SYS_FSL_IFC_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
+#endif
+ { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
+ CONFIG_SYS_FSL_DRAM_SIZE1,
+#if defined(CONFIG_TFABOOT) || \
+ (defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD))
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+#else /* Start with nGnRnE and PXN and UXN to prevent speculative access */
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
+#endif
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
+#ifdef CONFIG_FSL_IFC
+ /* Map IFC region #2 up to CONFIG_SYS_FLASH_BASE for NAND boot */
+ { CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FSL_IFC_BASE2,
+ CONFIG_SYS_FLASH_BASE - CONFIG_SYS_FSL_IFC_BASE2,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
+#endif
+ { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
+ CONFIG_SYS_FSL_DCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
+ CONFIG_SYS_FSL_DRAM_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
+#ifdef CONFIG_SYS_FSL_DRAM_BASE3
+ { CONFIG_SYS_FSL_DRAM_BASE3, CONFIG_SYS_FSL_DRAM_BASE3,
+ CONFIG_SYS_FSL_DRAM_SIZE3,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
+#endif
+#elif defined(CONFIG_FSL_LSCH2)
+ { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
+ CONFIG_SYS_FSL_CCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
+ SYS_FSL_OCRAM_SPACE_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
+ { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
+ CONFIG_SYS_FSL_DCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_QSPI_BASE, CONFIG_SYS_FSL_QSPI_BASE,
+ CONFIG_SYS_FSL_QSPI_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
+#ifdef CONFIG_FSL_IFC
+ { CONFIG_SYS_FSL_IFC_BASE, CONFIG_SYS_FSL_IFC_BASE,
+ CONFIG_SYS_FSL_IFC_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
+#endif
+ { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
+ CONFIG_SYS_FSL_DRAM_SIZE1,
+#if defined(CONFIG_TFABOOT) || \
+ (defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD))
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+#else /* Start with nGnRnE and PXN and UXN to prevent speculative access */
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
+#endif
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
+ { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
+ CONFIG_SYS_FSL_DRAM_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
+#endif
+ {}, /* list terminator */
+};
+
+static struct mm_region final_map[] = {
+#ifdef CONFIG_FSL_LSCH3
+ { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
+ CONFIG_SYS_FSL_CCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
+ SYS_FSL_OCRAM_SPACE_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
+ { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
+ CONFIG_SYS_FSL_DRAM_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
+ { CONFIG_SYS_FSL_QSPI_BASE1, CONFIG_SYS_FSL_QSPI_BASE1,
+ CONFIG_SYS_FSL_QSPI_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_QSPI_BASE2, CONFIG_SYS_FSL_QSPI_BASE2,
+ CONFIG_SYS_FSL_QSPI_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+#ifdef CONFIG_FSL_IFC
+ { CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FSL_IFC_BASE2,
+ CONFIG_SYS_FSL_IFC_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+#endif
+ { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
+ CONFIG_SYS_FSL_DCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_MC_BASE, CONFIG_SYS_FSL_MC_BASE,
+ CONFIG_SYS_FSL_MC_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_NI_BASE, CONFIG_SYS_FSL_NI_BASE,
+ CONFIG_SYS_FSL_NI_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ /* For QBMAN portal, only the first 64MB is cache-enabled */
+ { CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_BASE,
+ CONFIG_SYS_FSL_QBMAN_SIZE_1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_NS
+ },
+ { CONFIG_SYS_FSL_QBMAN_BASE + CONFIG_SYS_FSL_QBMAN_SIZE_1,
+ CONFIG_SYS_FSL_QBMAN_BASE + CONFIG_SYS_FSL_QBMAN_SIZE_1,
+ CONFIG_SYS_FSL_QBMAN_SIZE - CONFIG_SYS_FSL_QBMAN_SIZE_1,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_PCIE1_PHYS_ADDR, CONFIG_SYS_PCIE1_PHYS_ADDR,
+ CONFIG_SYS_PCIE1_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_PCIE2_PHYS_ADDR, CONFIG_SYS_PCIE2_PHYS_ADDR,
+ CONFIG_SYS_PCIE2_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+#ifdef CONFIG_SYS_PCIE3_PHYS_ADDR
+ { CONFIG_SYS_PCIE3_PHYS_ADDR, CONFIG_SYS_PCIE3_PHYS_ADDR,
+ CONFIG_SYS_PCIE3_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+#endif
+#ifdef CONFIG_SYS_PCIE4_PHYS_ADDR
+ { CONFIG_SYS_PCIE4_PHYS_ADDR, CONFIG_SYS_PCIE4_PHYS_ADDR,
+ CONFIG_SYS_PCIE4_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+#endif
+#ifdef SYS_PCIE5_PHYS_ADDR
+ { SYS_PCIE5_PHYS_ADDR, SYS_PCIE5_PHYS_ADDR,
+ SYS_PCIE5_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+#endif
+#ifdef SYS_PCIE6_PHYS_ADDR
+ { SYS_PCIE6_PHYS_ADDR, SYS_PCIE6_PHYS_ADDR,
+ SYS_PCIE6_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+#endif
+ { CONFIG_SYS_FSL_WRIOP1_BASE, CONFIG_SYS_FSL_WRIOP1_BASE,
+ CONFIG_SYS_FSL_WRIOP1_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_AIOP1_BASE, CONFIG_SYS_FSL_AIOP1_BASE,
+ CONFIG_SYS_FSL_AIOP1_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_PEBUF_BASE, CONFIG_SYS_FSL_PEBUF_BASE,
+ CONFIG_SYS_FSL_PEBUF_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
+ CONFIG_SYS_FSL_DRAM_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
+#ifdef CONFIG_SYS_FSL_DRAM_BASE3
+ { CONFIG_SYS_FSL_DRAM_BASE3, CONFIG_SYS_FSL_DRAM_BASE3,
+ CONFIG_SYS_FSL_DRAM_SIZE3,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
+#endif
+#elif defined(CONFIG_FSL_LSCH2)
+ { CONFIG_SYS_FSL_BOOTROM_BASE, CONFIG_SYS_FSL_BOOTROM_BASE,
+ CONFIG_SYS_FSL_BOOTROM_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
+ CONFIG_SYS_FSL_CCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
+ SYS_FSL_OCRAM_SPACE_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
+ { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
+ CONFIG_SYS_FSL_DCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_QSPI_BASE, CONFIG_SYS_FSL_QSPI_BASE,
+ CONFIG_SYS_FSL_QSPI_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+#ifdef CONFIG_FSL_IFC
+ { CONFIG_SYS_FSL_IFC_BASE, CONFIG_SYS_FSL_IFC_BASE,
+ CONFIG_SYS_FSL_IFC_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
+#endif
+ { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
+ CONFIG_SYS_FSL_DRAM_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
+ { CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_BASE,
+ CONFIG_SYS_FSL_QBMAN_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
+ CONFIG_SYS_FSL_DRAM_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
+ { CONFIG_SYS_PCIE1_PHYS_ADDR, CONFIG_SYS_PCIE1_PHYS_ADDR,
+ CONFIG_SYS_PCIE1_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+ { CONFIG_SYS_PCIE2_PHYS_ADDR, CONFIG_SYS_PCIE2_PHYS_ADDR,
+ CONFIG_SYS_PCIE2_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+#ifdef CONFIG_SYS_PCIE3_PHYS_ADDR
+ { CONFIG_SYS_PCIE3_PHYS_ADDR, CONFIG_SYS_PCIE3_PHYS_ADDR,
+ CONFIG_SYS_PCIE3_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
+#endif
+ { CONFIG_SYS_FSL_DRAM_BASE3, CONFIG_SYS_FSL_DRAM_BASE3,
+ CONFIG_SYS_FSL_DRAM_SIZE3,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
+#endif
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+ {}, /* space holder for secure mem */
+#endif
+ {},
+};
+
+struct mm_region *mem_map = early_map;
+
+void cpu_name(char *name)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ unsigned int i, svr, ver;
+
+ svr = gur_in32(&gur->svr);
+ ver = SVR_SOC_VER(svr);
+
+ for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++)
+ if ((cpu_type_list[i].soc_ver & SVR_WO_E) == ver) {
+ strcpy(name, cpu_type_list[i].name);
+#if defined(CONFIG_ARCH_LX2160A) || defined(CONFIG_ARCH_LX2162A)
+ if (IS_C_PROCESSOR(svr))
+ strcat(name, "C");
+#endif
+
+ if (IS_E_PROCESSOR(svr))
+ strcat(name, "E");
+
+ sprintf(name + strlen(name), " Rev%d.%d",
+ SVR_MAJ(svr), SVR_MIN(svr));
+ break;
+ }
+
+ if (i == ARRAY_SIZE(cpu_type_list))
+ strcpy(name, "unknown");
+}
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+/*
+ * To start MMU before DDR is available, we create MMU table in SRAM.
+ * The base address of SRAM is CONFIG_SYS_FSL_OCRAM_BASE. We use three
+ * levels of translation tables here to cover 40-bit address space.
+ * We use 4KB granule size, with 40 bits physical address, T0SZ=24
+ * Address above EARLY_PGTABLE_SIZE (0x5000) is free for other purpose.
+ * Note, the debug print in cache_v8.c is not usable for debugging
+ * these early MMU tables because UART is not yet available.
+ */
+static inline void early_mmu_setup(void)
+{
+ unsigned int el = current_el();
+
+ /* global data is already setup, no allocation yet */
+ if (el == 3)
+ gd->arch.tlb_addr = CONFIG_SYS_FSL_OCRAM_BASE;
+ else
+ gd->arch.tlb_addr = CONFIG_SYS_DDR_SDRAM_BASE;
+ gd->arch.tlb_fillptr = gd->arch.tlb_addr;
+ gd->arch.tlb_size = EARLY_PGTABLE_SIZE;
+
+ /* Create early page tables */
+ setup_pgtables();
+
+ /* point TTBR to the new table */
+ set_ttbr_tcr_mair(el, gd->arch.tlb_addr,
+ get_tcr(el, NULL, NULL) &
+ ~(TCR_ORGN_MASK | TCR_IRGN_MASK),
+ MEMORY_ATTRIBUTES);
+
+ set_sctlr(get_sctlr() | CR_M);
+}
+
+static void fix_pcie_mmu_map(void)
+{
+#ifdef CONFIG_ARCH_LS2080A
+ unsigned int i;
+ u32 svr, ver;
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+
+ svr = gur_in32(&gur->svr);
+ ver = SVR_SOC_VER(svr);
+
+ /* Fix PCIE base and size for LS2088A */
+ if ((ver == SVR_LS2088A) || (ver == SVR_LS2084A) ||
+ (ver == SVR_LS2048A) || (ver == SVR_LS2044A) ||
+ (ver == SVR_LS2081A) || (ver == SVR_LS2041A)) {
+ for (i = 0; i < ARRAY_SIZE(final_map); i++) {
+ switch (final_map[i].phys) {
+ case CONFIG_SYS_PCIE1_PHYS_ADDR:
+ final_map[i].phys = 0x2000000000ULL;
+ final_map[i].virt = 0x2000000000ULL;
+ final_map[i].size = 0x800000000ULL;
+ break;
+ case CONFIG_SYS_PCIE2_PHYS_ADDR:
+ final_map[i].phys = 0x2800000000ULL;
+ final_map[i].virt = 0x2800000000ULL;
+ final_map[i].size = 0x800000000ULL;
+ break;
+#ifdef CONFIG_SYS_PCIE3_PHYS_ADDR
+ case CONFIG_SYS_PCIE3_PHYS_ADDR:
+ final_map[i].phys = 0x3000000000ULL;
+ final_map[i].virt = 0x3000000000ULL;
+ final_map[i].size = 0x800000000ULL;
+ break;
+#endif
+#ifdef CONFIG_SYS_PCIE4_PHYS_ADDR
+ case CONFIG_SYS_PCIE4_PHYS_ADDR:
+ final_map[i].phys = 0x3800000000ULL;
+ final_map[i].virt = 0x3800000000ULL;
+ final_map[i].size = 0x800000000ULL;
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+ }
+#endif
+}
+
+/*
+ * The final tables look similar to early tables, but different in detail.
+ * These tables are in DRAM. Sub tables are added to enable cache for
+ * QBMan and OCRAM.
+ *
+ * Put the MMU table in secure memory if gd->arch.secure_ram is valid.
+ * OCRAM will be not used for this purpose so gd->arch.secure_ram can't be 0.
+ */
+static inline void final_mmu_setup(void)
+{
+ u64 tlb_addr_save = gd->arch.tlb_addr;
+ unsigned int el = current_el();
+ int index;
+
+ /* fix the final_map before filling in the block entries */
+ fix_pcie_mmu_map();
+
+ mem_map = final_map;
+
+ /* Update mapping for DDR to actual size */
+ for (index = 0; index < ARRAY_SIZE(final_map) - 2; index++) {
+ /*
+ * Find the entry for DDR mapping and update the address and
+ * size. Zero-sized mapping will be skipped when creating MMU
+ * table.
+ */
+ switch (final_map[index].virt) {
+ case CONFIG_SYS_FSL_DRAM_BASE1:
+ final_map[index].virt = gd->bd->bi_dram[0].start;
+ final_map[index].phys = gd->bd->bi_dram[0].start;
+ final_map[index].size = gd->bd->bi_dram[0].size;
+ break;
+#ifdef CONFIG_SYS_FSL_DRAM_BASE2
+ case CONFIG_SYS_FSL_DRAM_BASE2:
+#if (CONFIG_NR_DRAM_BANKS >= 2)
+ final_map[index].virt = gd->bd->bi_dram[1].start;
+ final_map[index].phys = gd->bd->bi_dram[1].start;
+ final_map[index].size = gd->bd->bi_dram[1].size;
+#else
+ final_map[index].size = 0;
+#endif
+ break;
+#endif
+#ifdef CONFIG_SYS_FSL_DRAM_BASE3
+ case CONFIG_SYS_FSL_DRAM_BASE3:
+#if (CONFIG_NR_DRAM_BANKS >= 3)
+ final_map[index].virt = gd->bd->bi_dram[2].start;
+ final_map[index].phys = gd->bd->bi_dram[2].start;
+ final_map[index].size = gd->bd->bi_dram[2].size;
+#else
+ final_map[index].size = 0;
+#endif
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+ if (gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED) {
+ if (el == 3) {
+ /*
+ * Only use gd->arch.secure_ram if the address is
+ * recalculated. Align to 4KB for MMU table.
+ */
+ /* put page tables in secure ram */
+ index = ARRAY_SIZE(final_map) - 2;
+ gd->arch.tlb_addr = gd->arch.secure_ram & ~0xfff;
+ final_map[index].virt = gd->arch.secure_ram & ~0x3;
+ final_map[index].phys = final_map[index].virt;
+ final_map[index].size = CONFIG_SYS_MEM_RESERVE_SECURE;
+ final_map[index].attrs = PTE_BLOCK_OUTER_SHARE;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_SECURED;
+ tlb_addr_save = gd->arch.tlb_addr;
+ } else {
+ /* Use allocated (board_f.c) memory for TLB */
+ tlb_addr_save = gd->arch.tlb_allocated;
+ gd->arch.tlb_addr = tlb_addr_save;
+ }
+ }
+#endif
+
+ /* Reset the fill ptr */
+ gd->arch.tlb_fillptr = tlb_addr_save;
+
+ /* Create normal system page tables */
+ setup_pgtables();
+
+ /* Create emergency page tables */
+ gd->arch.tlb_addr = gd->arch.tlb_fillptr;
+ gd->arch.tlb_emerg = gd->arch.tlb_addr;
+ setup_pgtables();
+ gd->arch.tlb_addr = tlb_addr_save;
+
+ /* Disable cache and MMU */
+ dcache_disable(); /* TLBs are invalidated */
+ invalidate_icache_all();
+
+ /* point TTBR to the new table */
+ set_ttbr_tcr_mair(el, gd->arch.tlb_addr, get_tcr(el, NULL, NULL),
+ MEMORY_ATTRIBUTES);
+
+ set_sctlr(get_sctlr() | CR_M);
+}
+
+u64 get_page_table_size(void)
+{
+ return 0x10000;
+}
+
+int arch_cpu_init(void)
+{
+ /*
+ * This function is called before U-Boot relocates itself to speed up
+ * on system running. It is not necessary to run if performance is not
+ * critical. Skip if MMU is already enabled by SPL or other means.
+ */
+ if (get_sctlr() & CR_M)
+ return 0;
+
+ icache_enable();
+ __asm_invalidate_dcache_all();
+ __asm_invalidate_tlb_all();
+ early_mmu_setup();
+ set_sctlr(get_sctlr() | CR_C);
+ return 0;
+}
+
+void mmu_setup(void)
+{
+ final_mmu_setup();
+}
+
+/*
+ * This function is called from common/board_r.c.
+ * It recreates MMU table in main memory.
+ */
+void enable_caches(void)
+{
+ mmu_setup();
+ __asm_invalidate_tlb_all();
+ icache_enable();
+ dcache_enable();
+}
+#endif /* !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
+
+#ifdef CONFIG_TFABOOT
+enum boot_src __get_boot_src(u32 porsr1)
+{
+ enum boot_src src = BOOT_SOURCE_RESERVED;
+ u32 rcw_src = (porsr1 & RCW_SRC_MASK) >> RCW_SRC_BIT;
+#if !defined(CONFIG_NXP_LSCH3_2)
+ u32 val;
+#endif
+ debug("%s: rcw_src 0x%x\n", __func__, rcw_src);
+
+#if defined(CONFIG_FSL_LSCH3)
+#if defined(CONFIG_NXP_LSCH3_2)
+ switch (rcw_src) {
+ case RCW_SRC_SDHC1_VAL:
+ src = BOOT_SOURCE_SD_MMC;
+ break;
+ case RCW_SRC_SDHC2_VAL:
+ src = BOOT_SOURCE_SD_MMC2;
+ break;
+ case RCW_SRC_I2C1_VAL:
+ src = BOOT_SOURCE_I2C1_EXTENDED;
+ break;
+ case RCW_SRC_FLEXSPI_NAND2K_VAL:
+ src = BOOT_SOURCE_XSPI_NAND;
+ break;
+ case RCW_SRC_FLEXSPI_NAND4K_VAL:
+ src = BOOT_SOURCE_XSPI_NAND;
+ break;
+ case RCW_SRC_RESERVED_1_VAL:
+ src = BOOT_SOURCE_RESERVED;
+ break;
+ case RCW_SRC_FLEXSPI_NOR_24B:
+ src = BOOT_SOURCE_XSPI_NOR;
+ break;
+ default:
+ src = BOOT_SOURCE_RESERVED;
+ }
+#else
+ val = rcw_src & RCW_SRC_TYPE_MASK;
+ if (val == RCW_SRC_NOR_VAL) {
+ val = rcw_src & NOR_TYPE_MASK;
+
+ switch (val) {
+ case NOR_16B_VAL:
+ case NOR_32B_VAL:
+ src = BOOT_SOURCE_IFC_NOR;
+ break;
+ default:
+ src = BOOT_SOURCE_RESERVED;
+ }
+ } else {
+ /* RCW SRC Serial Flash */
+ val = rcw_src & RCW_SRC_SERIAL_MASK;
+ switch (val) {
+ case RCW_SRC_QSPI_VAL:
+ /* RCW SRC Serial NOR (QSPI) */
+ src = BOOT_SOURCE_QSPI_NOR;
+ break;
+ case RCW_SRC_SD_CARD_VAL:
+ /* RCW SRC SD Card */
+ src = BOOT_SOURCE_SD_MMC;
+ break;
+ case RCW_SRC_EMMC_VAL:
+ /* RCW SRC EMMC */
+ src = BOOT_SOURCE_SD_MMC;
+ break;
+ case RCW_SRC_I2C1_VAL:
+ /* RCW SRC I2C1 Extended */
+ src = BOOT_SOURCE_I2C1_EXTENDED;
+ break;
+ default:
+ src = BOOT_SOURCE_RESERVED;
+ }
+ }
+#endif
+#elif defined(CONFIG_FSL_LSCH2)
+ /* RCW SRC NAND */
+ val = rcw_src & RCW_SRC_NAND_MASK;
+ if (val == RCW_SRC_NAND_VAL) {
+ val = rcw_src & NAND_RESERVED_MASK;
+ if (val != NAND_RESERVED_1 && val != NAND_RESERVED_2)
+ src = BOOT_SOURCE_IFC_NAND;
+
+ } else {
+ /* RCW SRC NOR */
+ val = rcw_src & RCW_SRC_NOR_MASK;
+ if (val == NOR_8B_VAL || val == NOR_16B_VAL) {
+ src = BOOT_SOURCE_IFC_NOR;
+ } else {
+ switch (rcw_src) {
+ case QSPI_VAL1:
+ case QSPI_VAL2:
+ src = BOOT_SOURCE_QSPI_NOR;
+ break;
+ case SD_VAL:
+ src = BOOT_SOURCE_SD_MMC;
+ break;
+ default:
+ src = BOOT_SOURCE_RESERVED;
+ }
+ }
+ }
+#endif
+
+ if (CONFIG_IS_ENABLED(SYS_FSL_ERRATUM_A010539) && !rcw_src)
+ src = BOOT_SOURCE_QSPI_NOR;
+
+ debug("%s: src 0x%x\n", __func__, src);
+ return src;
+}
+
+enum boot_src get_boot_src(void)
+{
+ struct pt_regs regs;
+ u32 porsr1 = 0;
+
+#if defined(CONFIG_FSL_LSCH3)
+ u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
+#elif defined(CONFIG_FSL_LSCH2)
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+#endif
+
+ if (current_el() == 2) {
+ regs.regs[0] = SIP_SVC_RCW;
+
+ smc_call(&regs);
+ if (!regs.regs[0])
+ porsr1 = regs.regs[1];
+ }
+
+ if (current_el() == 3 || !porsr1) {
+#ifdef CONFIG_FSL_LSCH3
+ porsr1 = in_le32(dcfg_ccsr + DCFG_PORSR1 / 4);
+#elif defined(CONFIG_FSL_LSCH2)
+ porsr1 = in_be32(&gur->porsr1);
+#endif
+ }
+
+ debug("%s: porsr1 0x%x\n", __func__, porsr1);
+
+ return __get_boot_src(porsr1);
+}
+
+#ifdef CONFIG_ENV_IS_IN_MMC
+int mmc_get_env_dev(void)
+{
+ enum boot_src src = get_boot_src();
+ int dev = CONFIG_SYS_MMC_ENV_DEV;
+
+ switch (src) {
+ case BOOT_SOURCE_SD_MMC:
+ dev = 0;
+ break;
+ case BOOT_SOURCE_SD_MMC2:
+ dev = 1;
+ break;
+ default:
+ break;
+ }
+
+ return dev;
+}
+#endif
+
+enum env_location env_get_location(enum env_operation op, int prio)
+{
+ enum boot_src src = get_boot_src();
+ enum env_location env_loc = ENVL_NOWHERE;
+
+ if (prio)
+ return ENVL_UNKNOWN;
+
+#ifdef CONFIG_ENV_IS_NOWHERE
+ return env_loc;
+#endif
+
+ switch (src) {
+ case BOOT_SOURCE_IFC_NOR:
+ env_loc = ENVL_FLASH;
+ break;
+ case BOOT_SOURCE_QSPI_NOR:
+ /* FALLTHROUGH */
+ case BOOT_SOURCE_XSPI_NOR:
+ env_loc = ENVL_SPI_FLASH;
+ break;
+ case BOOT_SOURCE_IFC_NAND:
+ /* FALLTHROUGH */
+ case BOOT_SOURCE_QSPI_NAND:
+ /* FALLTHROUGH */
+ case BOOT_SOURCE_XSPI_NAND:
+ env_loc = ENVL_NAND;
+ break;
+ case BOOT_SOURCE_SD_MMC:
+ /* FALLTHROUGH */
+ case BOOT_SOURCE_SD_MMC2:
+ env_loc = ENVL_MMC;
+ break;
+ case BOOT_SOURCE_I2C1_EXTENDED:
+ /* FALLTHROUGH */
+ default:
+ break;
+ }
+
+ return env_loc;
+}
+#endif /* CONFIG_TFABOOT */
+
+u32 initiator_type(u32 cluster, int init_id)
+{
+ struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 idx = (cluster >> (init_id * 8)) & TP_CLUSTER_INIT_MASK;
+ u32 type = 0;
+
+ type = gur_in32(&gur->tp_ityp[idx]);
+ if (type & TP_ITYP_AV)
+ return type;
+
+ return 0;
+}
+
+u32 cpu_pos_mask(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ int i = 0;
+ u32 cluster, type, mask = 0;
+
+ do {
+ int j;
+
+ cluster = gur_in32(&gur->tp_cluster[i].lower);
+ for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
+ type = initiator_type(cluster, j);
+ if (type && (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_ARM))
+ mask |= 1 << (i * TP_INIT_PER_CLUSTER + j);
+ }
+ i++;
+ } while ((cluster & TP_CLUSTER_EOC) == 0x0);
+
+ return mask;
+}
+
+u32 cpu_mask(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ int i = 0, count = 0;
+ u32 cluster, type, mask = 0;
+
+ do {
+ int j;
+
+ cluster = gur_in32(&gur->tp_cluster[i].lower);
+ for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
+ type = initiator_type(cluster, j);
+ if (type) {
+ if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_ARM)
+ mask |= 1 << count;
+ count++;
+ }
+ }
+ i++;
+ } while ((cluster & TP_CLUSTER_EOC) == 0x0);
+
+ return mask;
+}
+
+/*
+ * Return the number of cores on this SOC.
+ */
+int cpu_numcores(void)
+{
+ return hweight32(cpu_mask());
+}
+
+int fsl_qoriq_core_to_cluster(unsigned int core)
+{
+ struct ccsr_gur __iomem *gur =
+ (void __iomem *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ int i = 0, count = 0;
+ u32 cluster;
+
+ do {
+ int j;
+
+ cluster = gur_in32(&gur->tp_cluster[i].lower);
+ for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
+ if (initiator_type(cluster, j)) {
+ if (count == core)
+ return i;
+ count++;
+ }
+ }
+ i++;
+ } while ((cluster & TP_CLUSTER_EOC) == 0x0);
+
+ return -1; /* cannot identify the cluster */
+}
+
+u32 fsl_qoriq_core_to_type(unsigned int core)
+{
+ struct ccsr_gur __iomem *gur =
+ (void __iomem *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ int i = 0, count = 0;
+ u32 cluster, type;
+
+ do {
+ int j;
+
+ cluster = gur_in32(&gur->tp_cluster[i].lower);
+ for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
+ type = initiator_type(cluster, j);
+ if (type) {
+ if (count == core)
+ return type;
+ count++;
+ }
+ }
+ i++;
+ } while ((cluster & TP_CLUSTER_EOC) == 0x0);
+
+ return -1; /* cannot identify the cluster */
+}
+
+#ifndef CONFIG_FSL_LSCH3
+uint get_svr(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+
+ return gur_in32(&gur->svr);
+}
+#endif
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ struct sys_info sysinfo;
+ char buf[32];
+ unsigned int i, core;
+ u32 type, rcw, svr = gur_in32(&gur->svr);
+
+ puts("SoC: ");
+
+ cpu_name(buf);
+ printf(" %s (0x%x)\n", buf, svr);
+ memset((u8 *)buf, 0x00, ARRAY_SIZE(buf));
+ get_sys_info(&sysinfo);
+ puts("Clock Configuration:");
+ for_each_cpu(i, core, cpu_numcores(), cpu_mask()) {
+ if (!(i % 3))
+ puts("\n ");
+ type = TP_ITYP_VER(fsl_qoriq_core_to_type(core));
+ printf("CPU%d(%s):%-4s MHz ", core,
+ type == TY_ITYP_VER_A7 ? "A7 " :
+ (type == TY_ITYP_VER_A53 ? "A53" :
+ (type == TY_ITYP_VER_A57 ? "A57" :
+ (type == TY_ITYP_VER_A72 ? "A72" : " "))),
+ strmhz(buf, sysinfo.freq_processor[core]));
+ }
+ /* Display platform clock as Bus frequency. */
+ printf("\n Bus: %-4s MHz ",
+ strmhz(buf, sysinfo.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV));
+ printf("DDR: %-4s MT/s", strmhz(buf, sysinfo.freq_ddrbus));
+#ifdef CONFIG_SYS_DPAA_FMAN
+ printf(" FMAN: %-4s MHz", strmhz(buf, sysinfo.freq_fman[0]));
+#endif
+#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
+ if (soc_has_dp_ddr()) {
+ printf(" DP-DDR: %-4s MT/s",
+ strmhz(buf, sysinfo.freq_ddrbus2));
+ }
+#endif
+ puts("\n");
+
+ /*
+ * Display the RCW, so that no one gets confused as to what RCW
+ * we're actually using for this boot.
+ */
+ puts("Reset Configuration Word (RCW):");
+ for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) {
+ rcw = gur_in32(&gur->rcwsr[i]);
+ if ((i % 4) == 0)
+ printf("\n %08x:", i * 4);
+ printf(" %08x", rcw);
+ }
+ puts("\n");
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_FSL_ESDHC
+int cpu_mmc_init(struct bd_info *bis)
+{
+ return fsl_esdhc_mmc_init(bis);
+}
+#endif
+
+int cpu_eth_init(struct bd_info *bis)
+{
+ int error = 0;
+
+#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
+ error = fsl_mc_ldpaa_init(bis);
+#endif
+#ifdef CONFIG_FMAN_ENET
+ fm_standard_init(bis);
+#endif
+ return error;
+}
+
+int check_psci(void)
+{
+ unsigned int psci_ver;
+
+ psci_ver = sec_firmware_support_psci_version();
+ if (psci_ver == PSCI_INVALID_VER)
+ return 1;
+
+ return 0;
+}
+
+static void config_core_prefetch(void)
+{
+ char *buf = NULL;
+ char buffer[HWCONFIG_BUFFER_SIZE];
+ const char *prefetch_arg = NULL;
+ size_t arglen;
+ unsigned int mask;
+ struct pt_regs regs;
+
+ if (env_get_f("hwconfig", buffer, sizeof(buffer)) > 0)
+ buf = buffer;
+ else
+ return;
+
+ prefetch_arg = hwconfig_subarg_f("core_prefetch", "disable",
+ &arglen, buf);
+
+ if (prefetch_arg) {
+ mask = simple_strtoul(prefetch_arg, NULL, 0) & 0xff;
+ if (mask & 0x1) {
+ printf("Core0 prefetch can't be disabled\n");
+ return;
+ }
+
+#define SIP_PREFETCH_DISABLE_64 0xC200FF13
+ regs.regs[0] = SIP_PREFETCH_DISABLE_64;
+ regs.regs[1] = mask;
+ smc_call(&regs);
+
+ if (regs.regs[0])
+ printf("Prefetch disable config failed for mask ");
+ else
+ printf("Prefetch disable config passed for mask ");
+ printf("0x%x\n", mask);
+ }
+}
+
+#ifdef CONFIG_PCIE_ECAM_GENERIC
+__weak void set_ecam_icids(void)
+{
+}
+#endif
+
+int arch_early_init_r(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009635
+ u32 svr_dev_id;
+ /*
+ * erratum A009635 is valid only for LS2080A SoC and
+ * its personalitiesi
+ */
+ svr_dev_id = get_svr();
+ if (IS_SVR_DEV(svr_dev_id, SVR_DEV(SVR_LS2080A)))
+ erratum_a009635();
+#endif
+#if defined(CONFIG_SYS_FSL_ERRATUM_A009942) && defined(CONFIG_SYS_FSL_DDR)
+ erratum_a009942_check_cpo();
+#endif
+ if (check_psci()) {
+ debug("PSCI: PSCI does not exist.\n");
+
+ /* if PSCI does not exist, boot secondary cores here */
+ if (fsl_layerscape_wake_seconday_cores())
+ printf("Did not wake secondary cores\n");
+ }
+
+ config_core_prefetch();
+
+#ifdef CONFIG_SYS_HAS_SERDES
+ fsl_serdes_init();
+#endif
+#ifdef CONFIG_SYS_FSL_HAS_RGMII
+ /* some dpmacs in armv8a based freescale layerscape SOCs can be
+ * configured via both serdes(sgmii, xfi, xlaui etc) bits and via
+ * EC*_PMUX(rgmii) bits in RCW.
+ * e.g. dpmac 17 and 18 in LX2160A can be configured as SGMII from
+ * serdes bits and as RGMII via EC1_PMUX/EC2_PMUX bits
+ * Now if a dpmac is enabled as RGMII through ECx_PMUX then it takes
+ * precedence over SerDes protocol. i.e. in LX2160A if we select serdes
+ * protocol that configures dpmac17 as SGMII and set the EC1_PMUX as
+ * RGMII, then the dpmac is RGMII and not SGMII.
+ *
+ * Therefore, even thought fsl_rgmii_init is after fsl_serdes_init
+ * function of SOC, the dpmac will be enabled as RGMII even if it was
+ * also enabled before as SGMII. If ECx_PMUX is not configured for
+ * RGMII, DPMAC will remain configured as SGMII from fsl_serdes_init().
+ */
+ fsl_rgmii_init();
+#endif
+#ifdef CONFIG_FMAN_ENET
+#ifndef CONFIG_DM_ETH
+ fman_enet_init();
+#endif
+#endif
+#ifdef CONFIG_SYS_DPAA_QBMAN
+ setup_qbman_portals();
+#endif
+#ifdef CONFIG_PCIE_ECAM_GENERIC
+ set_ecam_icids();
+#endif
+ return 0;
+}
+
+int timer_init(void)
+{
+ u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR;
+#ifdef CONFIG_FSL_LSCH3
+ u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
+#endif
+#if defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A) || \
+ defined(CONFIG_ARCH_LS1028A)
+ u32 __iomem *pctbenr = (u32 *)FSL_PMU_PCTBENR_OFFSET;
+ u32 svr_dev_id;
+#endif
+#ifdef COUNTER_FREQUENCY_REAL
+ unsigned long cntfrq = COUNTER_FREQUENCY_REAL;
+
+ /* Update with accurate clock frequency */
+ if (current_el() == 3)
+ asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory");
+#endif
+
+#ifdef CONFIG_FSL_LSCH3
+ /* Enable timebase for all clusters.
+ * It is safe to do so even some clusters are not enabled.
+ */
+ out_le32(cltbenr, 0xf);
+#endif
+
+#if defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A) || \
+ defined(CONFIG_ARCH_LS1028A)
+ /*
+ * In certain Layerscape SoCs, the clock for each core's
+ * has an enable bit in the PMU Physical Core Time Base Enable
+ * Register (PCTBENR), which allows the watchdog to operate.
+ */
+ setbits_le32(pctbenr, 0xff);
+ /*
+ * For LS2080A SoC and its personalities, timer controller
+ * offset is different
+ */
+ svr_dev_id = get_svr();
+ if (IS_SVR_DEV(svr_dev_id, SVR_DEV(SVR_LS2080A)))
+ cntcr = (u32 *)SYS_FSL_LS2080A_LS2085A_TIMER_ADDR;
+
+#endif
+
+ /* Enable clock for timer
+ * This is a global setting.
+ */
+ out_le32(cntcr, 0x1);
+
+ return 0;
+}
+
+__efi_runtime_data u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR;
+
+void __efi_runtime reset_cpu(void)
+{
+#if defined(CONFIG_ARCH_LX2160A) || defined(CONFIG_ARCH_LX2162A)
+ /* clear the RST_REQ_MSK and SW_RST_REQ */
+ out_le32(rstcr, 0x0);
+
+ /* initiate the sw reset request */
+ out_le32(rstcr, 0x1);
+#else
+ u32 val;
+
+ /* Raise RESET_REQ_B */
+ val = scfg_in32(rstcr);
+ val |= 0x02;
+ scfg_out32(rstcr, val);
+#endif
+}
+
+#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_PSCI_RESET)
+
+void __efi_runtime EFIAPI efi_reset_system(
+ enum efi_reset_type reset_type,
+ efi_status_t reset_status,
+ unsigned long data_size, void *reset_data)
+{
+ switch (reset_type) {
+ case EFI_RESET_COLD:
+ case EFI_RESET_WARM:
+ case EFI_RESET_PLATFORM_SPECIFIC:
+ reset_cpu();
+ break;
+ case EFI_RESET_SHUTDOWN:
+ /* Nothing we can do */
+ break;
+ }
+
+ while (1) { }
+}
+
+efi_status_t efi_reset_system_init(void)
+{
+ return efi_add_runtime_mmio(&rstcr, sizeof(*rstcr));
+}
+
+#endif
+
+/*
+ * Calculate reserved memory with given memory bank
+ * Return aligned memory size on success
+ * Return (ram_size + needed size) for failure
+ */
+phys_size_t board_reserve_ram_top(phys_size_t ram_size)
+{
+ phys_size_t ram_top = ram_size;
+
+#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
+ ram_top = mc_get_dram_block_size();
+ if (ram_top > ram_size)
+ return ram_size + ram_top;
+
+ ram_top = ram_size - ram_top;
+ /* The start address of MC reserved memory needs to be aligned. */
+ ram_top &= ~(CONFIG_SYS_MC_RSV_MEM_ALIGN - 1);
+#endif
+
+ return ram_size - ram_top;
+}
+
+phys_size_t get_effective_memsize(void)
+{
+ phys_size_t ea_size, rem = 0;
+
+ /*
+ * For ARMv8 SoCs, DDR memory is split into two or three regions. The
+ * first region is 2GB space at 0x8000_0000. Secure memory needs to
+ * allocated from first region. If the memory extends to the second
+ * region (or the third region if applicable), Management Complex (MC)
+ * memory should be put into the highest region, i.e. the end of DDR
+ * memory. CONFIG_MAX_MEM_MAPPED is set to the size of first region so
+ * U-Boot doesn't relocate itself into higher address. Should DDR be
+ * configured to skip the first region, this function needs to be
+ * adjusted.
+ */
+ if (gd->ram_size > CONFIG_MAX_MEM_MAPPED) {
+ ea_size = CONFIG_MAX_MEM_MAPPED;
+ rem = gd->ram_size - ea_size;
+ } else {
+ ea_size = gd->ram_size;
+ }
+
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+ /* Check if we have enough space for secure memory */
+ if (ea_size > CONFIG_SYS_MEM_RESERVE_SECURE)
+ ea_size -= CONFIG_SYS_MEM_RESERVE_SECURE;
+ else
+ printf("Error: No enough space for secure memory.\n");
+#endif
+ /* Check if we have enough memory for MC */
+ if (rem < board_reserve_ram_top(rem)) {
+ /* Not enough memory in high region to reserve */
+ if (ea_size > board_reserve_ram_top(ea_size))
+ ea_size -= board_reserve_ram_top(ea_size);
+ else
+ printf("Error: No enough space for reserved memory.\n");
+ }
+
+ return ea_size;
+}
+
+#ifdef CONFIG_TFABOOT
+phys_size_t tfa_get_dram_size(void)
+{
+ struct pt_regs regs;
+ phys_size_t dram_size = 0;
+
+ regs.regs[0] = SMC_DRAM_BANK_INFO;
+ regs.regs[1] = -1;
+
+ smc_call(&regs);
+ if (regs.regs[0])
+ return 0;
+
+ dram_size = regs.regs[1];
+ return dram_size;
+}
+
+static int tfa_dram_init_banksize(void)
+{
+ int i = 0, ret = 0;
+ struct pt_regs regs;
+ phys_size_t dram_size = tfa_get_dram_size();
+
+ debug("dram_size %llx\n", dram_size);
+
+ if (!dram_size)
+ return -EINVAL;
+
+ do {
+ regs.regs[0] = SMC_DRAM_BANK_INFO;
+ regs.regs[1] = i;
+
+ smc_call(&regs);
+ if (regs.regs[0]) {
+ ret = -EINVAL;
+ break;
+ }
+
+ debug("bank[%d]: start %lx, size %lx\n", i, regs.regs[1],
+ regs.regs[2]);
+ gd->bd->bi_dram[i].start = regs.regs[1];
+ gd->bd->bi_dram[i].size = regs.regs[2];
+
+ dram_size -= gd->bd->bi_dram[i].size;
+
+ i++;
+ } while (dram_size);
+
+ if (i > 0)
+ ret = 0;
+
+#if defined(CONFIG_RESV_RAM) && !defined(CONFIG_SPL_BUILD)
+ /* Assign memory for MC */
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+ if (gd->bd->bi_dram[2].size >=
+ board_reserve_ram_top(gd->bd->bi_dram[2].size)) {
+ gd->arch.resv_ram = gd->bd->bi_dram[2].start +
+ gd->bd->bi_dram[2].size -
+ board_reserve_ram_top(gd->bd->bi_dram[2].size);
+ } else
+#endif
+ {
+ if (gd->bd->bi_dram[1].size >=
+ board_reserve_ram_top(gd->bd->bi_dram[1].size)) {
+ gd->arch.resv_ram = gd->bd->bi_dram[1].start +
+ gd->bd->bi_dram[1].size -
+ board_reserve_ram_top(gd->bd->bi_dram[1].size);
+ } else if (gd->bd->bi_dram[0].size >
+ board_reserve_ram_top(gd->bd->bi_dram[0].size)) {
+ gd->arch.resv_ram = gd->bd->bi_dram[0].start +
+ gd->bd->bi_dram[0].size -
+ board_reserve_ram_top(gd->bd->bi_dram[0].size);
+ }
+ }
+#endif /* CONFIG_RESV_RAM */
+
+ return ret;
+}
+#endif
+
+int dram_init_banksize(void)
+{
+#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
+ phys_size_t dp_ddr_size;
+#endif
+
+#ifdef CONFIG_TFABOOT
+ if (!tfa_dram_init_banksize())
+ return 0;
+#endif
+ /*
+ * gd->ram_size has the total size of DDR memory, less reserved secure
+ * memory. The DDR extends from low region to high region(s) presuming
+ * no hole is created with DDR configuration. gd->arch.secure_ram tracks
+ * the location of secure memory. gd->arch.resv_ram tracks the location
+ * of reserved memory for Management Complex (MC). Because gd->ram_size
+ * is reduced by this function if secure memory is reserved, checking
+ * gd->arch.secure_ram should be done to avoid running it repeatedly.
+ */
+
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+ if (gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED) {
+ debug("No need to run again, skip %s\n", __func__);
+
+ return 0;
+ }
+#endif
+
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ if (gd->ram_size > CONFIG_SYS_DDR_BLOCK1_SIZE) {
+ gd->bd->bi_dram[0].size = CONFIG_SYS_DDR_BLOCK1_SIZE;
+ gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
+ gd->bd->bi_dram[1].size = gd->ram_size -
+ CONFIG_SYS_DDR_BLOCK1_SIZE;
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+ if (gd->bi_dram[1].size > CONFIG_SYS_DDR_BLOCK2_SIZE) {
+ gd->bd->bi_dram[2].start = CONFIG_SYS_DDR_BLOCK3_BASE;
+ gd->bd->bi_dram[2].size = gd->bd->bi_dram[1].size -
+ CONFIG_SYS_DDR_BLOCK2_SIZE;
+ gd->bd->bi_dram[1].size = CONFIG_SYS_DDR_BLOCK2_SIZE;
+ }
+#endif
+ } else {
+ gd->bd->bi_dram[0].size = gd->ram_size;
+ }
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+ if (gd->bd->bi_dram[0].size >
+ CONFIG_SYS_MEM_RESERVE_SECURE) {
+ gd->bd->bi_dram[0].size -=
+ CONFIG_SYS_MEM_RESERVE_SECURE;
+ gd->arch.secure_ram = gd->bd->bi_dram[0].start +
+ gd->bd->bi_dram[0].size;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+ gd->ram_size -= CONFIG_SYS_MEM_RESERVE_SECURE;
+ }
+#endif /* CONFIG_SYS_MEM_RESERVE_SECURE */
+
+#if defined(CONFIG_RESV_RAM) && !defined(CONFIG_SPL_BUILD)
+ /* Assign memory for MC */
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+ if (gd->bd->bi_dram[2].size >=
+ board_reserve_ram_top(gd->bd->bi_dram[2].size)) {
+ gd->arch.resv_ram = gd->bd->bi_dram[2].start +
+ gd->bd->bi_dram[2].size -
+ board_reserve_ram_top(gd->bd->bi_dram[2].size);
+ } else
+#endif
+ {
+ if (gd->bd->bi_dram[1].size >=
+ board_reserve_ram_top(gd->bd->bi_dram[1].size)) {
+ gd->arch.resv_ram = gd->bd->bi_dram[1].start +
+ gd->bd->bi_dram[1].size -
+ board_reserve_ram_top(gd->bd->bi_dram[1].size);
+ } else if (gd->bd->bi_dram[0].size >
+ board_reserve_ram_top(gd->bd->bi_dram[0].size)) {
+ gd->arch.resv_ram = gd->bd->bi_dram[0].start +
+ gd->bd->bi_dram[0].size -
+ board_reserve_ram_top(gd->bd->bi_dram[0].size);
+ }
+ }
+#endif /* CONFIG_RESV_RAM */
+
+#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+#error "This SoC shouldn't have DP DDR"
+#endif
+ if (soc_has_dp_ddr()) {
+ /* initialize DP-DDR here */
+ puts("DP-DDR: ");
+ /*
+ * DDR controller use 0 as the base address for binding.
+ * It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access.
+ */
+ dp_ddr_size = fsl_other_ddr_sdram(CONFIG_SYS_DP_DDR_BASE_PHY,
+ CONFIG_DP_DDR_CTRL,
+ CONFIG_DP_DDR_NUM_CTRLS,
+ CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR,
+ NULL, NULL, NULL);
+ if (dp_ddr_size) {
+ gd->bd->bi_dram[2].start = CONFIG_SYS_DP_DDR_BASE;
+ gd->bd->bi_dram[2].size = dp_ddr_size;
+ } else {
+ puts("Not detected");
+ }
+ }
+#endif
+
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+ debug("%s is called. gd->ram_size is reduced to %lu\n",
+ __func__, (ulong)gd->ram_size);
+#endif
+
+ return 0;
+}
+
+#if CONFIG_IS_ENABLED(EFI_LOADER)
+void efi_add_known_memory(void)
+{
+ int i;
+ phys_addr_t ram_start;
+ phys_size_t ram_size;
+
+ /* Add RAM */
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+#error "This SoC shouldn't have DP DDR"
+#endif
+ if (i == 2)
+ continue; /* skip DP-DDR */
+#endif
+ ram_start = gd->bd->bi_dram[i].start;
+ ram_size = gd->bd->bi_dram[i].size;
+#ifdef CONFIG_RESV_RAM
+ if (gd->arch.resv_ram >= ram_start &&
+ gd->arch.resv_ram < ram_start + ram_size)
+ ram_size = gd->arch.resv_ram - ram_start;
+#endif
+ efi_add_memory_map(ram_start, ram_size,
+ EFI_CONVENTIONAL_MEMORY);
+ }
+}
+#endif
+
+/*
+ * Before DDR size is known, early MMU table have DDR mapped as device memory
+ * to avoid speculative access. To relocate U-Boot to DDR, "normal memory"
+ * needs to be set for these mappings.
+ * If a special case configures DDR with holes in the mapping, the holes need
+ * to be marked as invalid. This is not implemented in this function.
+ */
+void update_early_mmu_table(void)
+{
+ if (!gd->arch.tlb_addr)
+ return;
+
+ if (gd->ram_size <= CONFIG_SYS_FSL_DRAM_SIZE1) {
+ mmu_change_region_attr(
+ CONFIG_SYS_SDRAM_BASE,
+ gd->ram_size,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE |
+ PTE_BLOCK_NS |
+ PTE_TYPE_VALID);
+ } else {
+ mmu_change_region_attr(
+ CONFIG_SYS_SDRAM_BASE,
+ CONFIG_SYS_DDR_BLOCK1_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE |
+ PTE_BLOCK_NS |
+ PTE_TYPE_VALID);
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+#ifndef CONFIG_SYS_DDR_BLOCK2_SIZE
+#error "Missing CONFIG_SYS_DDR_BLOCK2_SIZE"
+#endif
+ if (gd->ram_size - CONFIG_SYS_DDR_BLOCK1_SIZE >
+ CONFIG_SYS_DDR_BLOCK2_SIZE) {
+ mmu_change_region_attr(
+ CONFIG_SYS_DDR_BLOCK2_BASE,
+ CONFIG_SYS_DDR_BLOCK2_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE |
+ PTE_BLOCK_NS |
+ PTE_TYPE_VALID);
+ mmu_change_region_attr(
+ CONFIG_SYS_DDR_BLOCK3_BASE,
+ gd->ram_size -
+ CONFIG_SYS_DDR_BLOCK1_SIZE -
+ CONFIG_SYS_DDR_BLOCK2_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE |
+ PTE_BLOCK_NS |
+ PTE_TYPE_VALID);
+ } else
+#endif
+ {
+ mmu_change_region_attr(
+ CONFIG_SYS_DDR_BLOCK2_BASE,
+ gd->ram_size -
+ CONFIG_SYS_DDR_BLOCK1_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE |
+ PTE_BLOCK_NS |
+ PTE_TYPE_VALID);
+ }
+ }
+}
+
+__weak int dram_init(void)
+{
+ fsl_initdram();
+#if (!defined(CONFIG_SPL) && !defined(CONFIG_TFABOOT)) || \
+ defined(CONFIG_SPL_BUILD)
+ /* This will break-before-make MMU for DDR */
+ update_early_mmu_table();
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_ARCH_MISC_INIT
+__weak int serdes_misc_init(void)
+{
+ return 0;
+}
+
+int arch_misc_init(void)
+{
+ serdes_misc_init();
+
+ return 0;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/cpu.h b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/cpu.h
new file mode 100644
index 000000000..45da95831
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/cpu.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2014-2015, Freescale Semiconductor
+ */
+
+int fsl_qoriq_core_to_cluster(unsigned int core);
+u32 initiator_type(u32 cluster, int init_id);
+u32 cpu_mask(void);
+int check_psci(void);
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.core_prefetch b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.core_prefetch
new file mode 100644
index 000000000..85cf6abd6
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.core_prefetch
@@ -0,0 +1,20 @@
+Core instruction prefetch disable
+---------------------------------
+To disable instruction prefetch of core; hwconfig needs to be updated.
+for e.g.
+setenv hwconfig 'fsl_ddr:bank_intlv=auto;core_prefetch:disable=0x02'
+
+Here 0x02 can be replaced with any valid value except Mask[0] bit. It
+represents 64 bit mask. The 64-bit Mask has one bit for each core.
+Mask[0] = core0
+Mask[1] = core1
+Mask[2] = core2
+etc
+If the bit is set ('b1) in the mask, then prefetch is disabled for
+that core when it is released from reset.
+
+core0 prefetch should not be disabled i.e. Mask[0] should never be set.
+Setting Mask[0] may lead to undefined behavior.
+
+Once disabled, prefetch remains disabled until the next reset.
+There is no function to re-enable prefetch.
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.falcon b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.falcon
new file mode 100644
index 000000000..b3c6693a4
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.falcon
@@ -0,0 +1,150 @@
+Falcon boot option
+------------------
+Falcon boot is a short cut boot method for SD/eMMC targets. It skips loading the
+RAM version U-Boot. Instead, it loads FIT image and boot directly to Linux.
+CONFIG_SPL_OS_BOOT enables falcon boot. CONFIG_SPL_LOAD_FIT enables the FIT
+image support (also need CONFIG_SPL_OF_LIBFDT, CONFIG_SPL_FIT and optionally
+CONFIG_SPL_GZIP).
+
+To enable falcon boot, a hook function spl_start_uboot() returns 0 to indicate
+booting U-Boot is not the first choice. The kernel FIT image needs to be put
+at CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR. SPL mmc driver reads the header to
+determine if this is a FIT image. If true, FIT image components are parsed and
+copied or decompressed (if applicable) to their destinations. If FIT image is
+not found, normal U-Boot flow will follow.
+
+An important part of falcon boot is to prepare the device tree. A normal U-Boot
+does FDT fixups when booting Linux. For falcon boot, Linux boots directly from
+SPL, skipping the normal U-Boot. The device tree has to be prepared in advance.
+A command "spl export" should be called under the normal RAM version U-Boot.
+It is equivalent to go through "bootm" step-by-step until device tree fixup is
+done. The device tree in memory is the one needed for falcon boot. Falcon boot
+flow suggests to save this image to SD/eMMC at the location pointed by macro
+CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, with maximum size specified by macro
+CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS. However, when FIT image is used for
+Linux, the device tree stored in FIT image overwrites the memory loaded by spl
+driver from these sectors. We could change this loading order to favor the
+stored sectors. But when secure boot is enabled, these sectors are used for
+signature header and needs to be loaded before the FIT image. So it is important
+to understand the device tree in FIT image should be the one actually used, or
+leave it absent to favor the stored sectors. It is easier to deploy the FIT
+image with embedded static device tree to multiple boards.
+
+Macro CONFIG_SYS_SPL_ARGS_ADDR serves two purposes. One is the pointer to load
+the stored sectors to. Normally this is the static device tree. The second
+purpose is the memory location of signature header for secure boot. After the
+FIT image is loaded into memory, it is validated against the signature header
+before individual components are extracted (and optionally decompressed) into
+their final memory locations, respectively. After the validation, the header
+is no longer used. The static device tree is copied into this location. So
+this macro is passed as the location of device tree when booting Linux.
+
+Steps to prepare static device tree
+-----------------------------------
+To prepare the static device tree for Layerscape boards, it is important to
+understand the fixups in U-Boot. Memory size and location, as well as reserved
+memory blocks are added/updated. Ethernet MAC addressed are updated. FMan
+microcode (if used) is embedded in the device tree. Kernel command line and
+initrd information are embedded. Others including CPU status, boot method,
+Ethernet port status, etc. are also updated.
+
+Following normal booting process, all variables are set, all images are loaded
+before "bootm" command would be issued to boot, run command
+
+spl export fdt <address>
+
+where the address is the location of FIT image. U-Boot goes through the booting
+process as if "bootm start", "bootm loados", "bootm ramdisk"... commands but
+stops before "bootm go". There we have the fixed-up device tree in memory.
+We can check the device tree header by these commands
+
+fdt addr <fdt address>
+fdt header
+
+Where the fdt address is the device tree in memory. It is printed by U-Boot.
+It is useful to know the exact size. One way to extract this static device
+tree is to save it to eMMC/SD using command in U-Boot, and extract under Linux
+with these commands, repectively
+
+mmc write <address> <sector> <sectors>
+dd if=/dev/mmcblk0 of=<filename> bs=512 skip=<sector> count=<sectors>
+
+Note, U-Boot takes values as hexadecimals while Linux takes them as decimals by
+default. If using NAND or other storage, the commands are slightly different.
+When we have the static device tree image, we can re-make the FIT image with
+it. It is important to specify the load addresses in FIT image for every
+components. Otherwise U-Boot cannot load them correctly.
+
+Generate FIT image with static device tree
+------------------------------------------
+Example:
+
+/dts-v1/;
+
+/ {
+ description = "Image file for the LS1043A Linux Kernel";
+ #address-cells = <1>;
+
+ images {
+ kernel {
+ description = "ARM64 Linux kernel";
+ data = /incbin/("./arch/arm64/boot/Image.gz");
+ type = "kernel";
+ arch = "arm64";
+ os = "linux";
+ compression = "gzip";
+ load = <0x80080000>;
+ entry = <0x80080000>;
+ };
+ fdt-1 {
+ description = "Flattened Device Tree blob";
+ data = /incbin/("./fsl-ls1043ardb-static.dtb");
+ type = "flat_dt";
+ arch = "arm64";
+ compression = "none";
+ load = <0x90000000>;
+ };
+ ramdisk {
+ description = "LS1043 Ramdisk";
+ data = /incbin/("./rootfs.cpio.gz");
+ type = "ramdisk";
+ arch = "arm64";
+ os = "linux";
+ compression = "none";
+ load = <0xa0000000>;
+ };
+ };
+
+ configurations {
+ default = "config-1";
+ config-1 {
+ description = "Boot Linux kernel";
+ kernel = "kernel";
+ fdt = "fdt-1";
+ ramdisk = "ramdisk";
+ loadables = "fdt", "ramdisk";
+ };
+ };
+};
+
+The "loadables" is not optional. It tells SPL which images to load into memory.
+
+Falcon mode with QSPI boot
+--------------------------
+To use falcon mode with QSPI boot, SPL needs to be enabled. Similar to SD or
+NAND boot, a RAM version full feature U-Boot is needed. Unlike SD or NAND boot,
+SPL with QSPI doesn't need to combine SPL image with RAM version image. Two
+separated images are used, u-boot-spl.pbl and u-boot.img. The former is SPL
+image with RCW and PBI commands to load the SPL payload into On-Chip RAM. The
+latter is RAM version U-Boot in FIT format (or legacy format if FIT is not
+used).
+
+Other things to consider
+-----------------------
+Falcon boot skips a lot of initialization in U-Boot. If Linux expects the
+hardware to be initialized by U-Boot, the related code should be ported to SPL
+build. For example, if Linux expect Ethernet PHY to be initialized in U-Boot
+(which is not a common case), the PHY initialization has to be included in
+falcon boot. This increases the SPL image size and should be handled carefully.
+If Linux has PHY driver enabled, it still depends on the correct MDIO bus setup
+in U-Boot. Normal U-Boot sets the MDC ratio to generate a proper clock signal.
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch2 b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch2
new file mode 100644
index 000000000..d7f7b9f11
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch2
@@ -0,0 +1,20 @@
+#
+# Copyright 2015 Freescale Semiconductor
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+Freescale LayerScape with Chassis Generation 2
+
+This architecture supports Freescale ARMv8 SoCs with Chassis generation 2,
+for example LS1043A.
+
+Watchdog support Overview
+-------------------
+Support watchdog driver for LSCH2. The driver is disabled in default.
+You can enable it by setting CONFIG_IMX_WATCHDOG.
+Use following config to set watchdog timeout, if this config is not defined,
+the default timeout value is 128s which is the maximum. Set 10 seconds for
+example:
+Set CONFIG_WATCHDOG_RESET_DISABLE to disable reset watchdog, so that the
+watchdog will not be fed in u-boot.
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3 b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3
new file mode 100644
index 000000000..6c98d99d0
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3
@@ -0,0 +1,400 @@
+#
+# Copyright 2014-2015 Freescale Semiconductor
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+Freescale LayerScape with Chassis Generation 3
+
+This architecture supports Freescale ARMv8 SoCs with Chassis generation 3,
+for example LS2080A.
+
+DDR Layout
+============
+Entire DDR region splits into two regions.
+ - Region 1 is at address 0x8000_0000 to 0xffff_ffff.
+ - Region 2 is at 0x80_8000_0000 to the top of total memory,
+ for example 16GB, 0x83_ffff_ffff.
+
+All DDR memory is marked as cache-enabled.
+
+When MC and Debug server is enabled, they carve 512MB away from the high
+end of DDR. For example, if the total DDR is 16GB, it shrinks to 15.5GB
+with MC and Debug server enabled. Linux only sees 15.5GB.
+
+The reserved 512MB layout looks like
+
+ +---------------+ <-- top/end of memory
+ | 256MB | debug server
+ +---------------+
+ | 256MB | MC
+ +---------------+
+ | ... |
+
+MC requires the memory to be aligned with 512MB, so even debug server is
+not enabled, 512MB is reserved, not 256MB.
+
+Flash Layout
+============
+
+(1) A typical layout of various images (including Linux and other firmware images)
+ is shown below considering a 32MB NOR flash device present on most
+ pre-silicon platforms (simulator and emulator):
+
+ -------------------------
+ | FIT Image |
+ | (linux + DTB + RFS) |
+ ------------------------- ----> 0x0120_0000
+ | Debug Server FW |
+ ------------------------- ----> 0x00C0_0000
+ | AIOP FW |
+ ------------------------- ----> 0x0070_0000
+ | MC FW |
+ ------------------------- ----> 0x006C_0000
+ | MC DPL Blob |
+ ------------------------- ----> 0x0020_0000
+ | BootLoader + Env|
+ ------------------------- ----> 0x0000_1000
+ | PBI |
+ ------------------------- ----> 0x0000_0080
+ | RCW |
+ ------------------------- ----> 0x0000_0000
+
+ 32-MB NOR flash layout for pre-silicon platforms (simulator and emulator)
+
+(2) A typical layout of various images (including Linux and other firmware images)
+ is shown below considering a 128MB NOR flash device present on QDS and RDB
+ boards:
+ ----------------------------------------- ----> 0x5_8800_0000 ---
+ | .. Unused .. (7M) | |
+ ----------------------------------------- ----> 0x5_8790_0000 |
+ | FIT Image (linux + DTB + RFS) (40M) | |
+ ----------------------------------------- ----> 0x5_8510_0000 |
+ | PHY firmware (2M) | |
+ ----------------------------------------- ----> 0x5_84F0_0000 | 64K
+ | Debug Server FW (2M) | | Alt
+ ----------------------------------------- ----> 0x5_84D0_0000 | Bank
+ | AIOP FW (4M) | |
+ ----------------------------------------- ----> 0x5_8490_0000 (vbank4)
+ | MC DPC Blob (1M) | |
+ ----------------------------------------- ----> 0x5_8480_0000 |
+ | MC DPL Blob (1M) | |
+ ----------------------------------------- ----> 0x5_8470_0000 |
+ | MC FW (4M) | |
+ ----------------------------------------- ----> 0x5_8430_0000 |
+ | BootLoader Environment (1M) | |
+ ----------------------------------------- ----> 0x5_8420_0000 |
+ | BootLoader (1M) | |
+ ----------------------------------------- ----> 0x5_8410_0000 |
+ | RCW and PBI (1M) | |
+ ----------------------------------------- ----> 0x5_8400_0000 ---
+ | .. Unused .. (7M) | |
+ ----------------------------------------- ----> 0x5_8390_0000 |
+ | FIT Image (linux + DTB + RFS) (40M) | |
+ ----------------------------------------- ----> 0x5_8110_0000 |
+ | PHY firmware (2M) | |
+ ----------------------------------------- ----> 0x5_80F0_0000 | 64K
+ | Debug Server FW (2M) | | Bank
+ ----------------------------------------- ----> 0x5_80D0_0000 |
+ | AIOP FW (4M) | |
+ ----------------------------------------- ----> 0x5_8090_0000 (vbank0)
+ | MC DPC Blob (1M) | |
+ ----------------------------------------- ----> 0x5_8080_0000 |
+ | MC DPL Blob (1M) | |
+ ----------------------------------------- ----> 0x5_8070_0000 |
+ | MC FW (4M) | |
+ ----------------------------------------- ----> 0x5_8030_0000 |
+ | BootLoader Environment (1M) | |
+ ----------------------------------------- ----> 0x5_8020_0000 |
+ | BootLoader (1M) | |
+ ----------------------------------------- ----> 0x5_8010_0000 |
+ | RCW and PBI (1M) | |
+ ----------------------------------------- ----> 0x5_8000_0000 ---
+
+ 128-MB NOR flash layout for QDS and RDB boards
+
+Environment Variables
+=====================
+mcboottimeout: MC boot timeout in milliseconds. If this variable is not defined
+ the value CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS will be assumed.
+
+mcmemsize: MC DRAM block size in hex. If this variable is not defined, the value
+ CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE will be assumed.
+
+mcinitcmd: This environment variable is defined to initiate MC and DPL deployment
+ from the location where it is stored(NOR, NAND, SD, SATA, USB)during
+ u-boot booting.If this variable is not defined then MC_BOOT_ENV_VAR
+ will be null and MC will not be booted and DPL will not be applied
+ during U-boot booting.However the MC, DPC and DPL can be applied from
+ console independently.
+ The variable needs to be set from the console once and then on
+ rebooting the parameters set in the variable will automatically be
+ executed. The commmand is demostrated taking an example of mc boot
+ using NOR Flash i.e. MC, DPL, and DPC is stored in the NOR flash:
+
+ cp.b 0xa0000000 0x580300000 $filesize
+ cp.b 0x80000000 0x580800000 $filesize
+ cp.b 0x90000000 0x580700000 $filesize
+
+ setenv mcinitcmd 'fsl_mc start mc 0x580300000 0x580800000'
+
+ If only linux is to be booted then the mcinitcmd environment should be set as
+
+ setenv mcinitcmd 'fsl_mc start mc 0x580300000 0x580800000;fsl_mc apply DPL 0x580700000'
+
+ Here the addresses 0xa0000000, 0x80000000, 0x80000000 are of DDR to where
+ MC binary, DPC binary and DPL binary are stored and 0x580300000, 0x580800000
+ and 0x580700000 are addresses in NOR where these are copied. It is to be
+ noted that these addresses in 'fsl_mc start mc 0x580300000 0x580800000;fsl_mc apply DPL 0x580700000'
+ can be replaced with the addresses of DDR to
+ which these will be copied in case of these binaries being stored in other
+ devices like SATA, USB, NAND, SD etc.
+
+Booting from NAND
+-------------------
+Booting from NAND requires two images, RCW and u-boot-with-spl.bin.
+The difference between NAND boot RCW image and NOR boot image is the PBI
+command sequence. Below is one example for PBI commands for LS2085AQDS which
+uses NAND device with 2KB/page, block size 128KB.
+
+1) CCSR 4-byte write to 0x00e00404, data=0x00000000
+2) CCSR 4-byte write to 0x00e00400, data=0x1800a000
+The above two commands set bootloc register to 0x00000000_1800a000 where
+the u-boot code will be running in OCRAM.
+
+3) Block Copy: SRC=0x0107, SRC_ADDR=0x00020000, DEST_ADDR=0x1800a000,
+BLOCK_SIZE=0x00014000
+This command copies u-boot image from NAND device into OCRAM. The values need
+to adjust accordingly.
+
+SRC should match the cfg_rcw_src, the reset config pins. It depends
+ on the NAND device. See reference manual for cfg_rcw_src.
+SRC_ADDR is the offset of u-boot-with-spl.bin image in NAND device. In
+ the example above, 128KB. For easy maintenance, we put it at
+ the beginning of next block from RCW.
+DEST_ADDR is fixed at 0x1800a000, matching bootloc set above.
+BLOCK_SIZE is the size to be copied by PBI.
+
+RCW image should be written to the beginning of NAND device. Example of using
+u-boot command
+
+nand write <rcw image in memory> 0 <size of rcw image>
+
+To form the NAND image, build u-boot with NAND config, for example,
+ls2080aqds_nand_defconfig. The image needed is u-boot-with-spl.bin.
+The u-boot image should be written to match SRC_ADDR, in above example 0x20000.
+
+nand write <u-boot image in memory> 200000 <size of u-boot image>
+
+With these two images in NAND device, the board can boot from NAND.
+
+Another example for LS2085ARDB boards,
+
+1) CCSR 4-byte write to 0x00e00404, data=0x00000000
+2) CCSR 4-byte write to 0x00e00400, data=0x1800a000
+3) Block Copy: SRC=0x0119, SRC_ADDR=0x00080000, DEST_ADDR=0x1800a000,
+BLOCK_SIZE=0x00014000
+
+nand write <rcw image in memory> 0 <size of rcw image>
+nand write <u-boot image in memory> 80000 <size of u-boot image>
+
+Notice the difference from QDS is SRC, SRC_ADDR and the offset of u-boot image
+to match board NAND device with 4KB/page, block size 512KB.
+
+Note, LS2088A and LS1088A don't support booting from NAND.
+
+Booting from SD/eMMC
+-------------------
+Booting from SD/eMMC requires two images, RCW and u-boot-with-spl.bin.
+The difference between SD boot RCW image and QSPI-NOR boot image is the
+PBI command sequence. Below is one example for PBI commands for RDB
+and QDS which uses SD device with block size 512. Block location can be
+calculated by dividing offset with block size.
+
+1) Block Copy: SRC=0x0040, SRC_ADDR=0x00100000, DEST_ADDR=0x1800a000,
+BLOCK_SIZE=0x00016000
+
+This command copies u-boot image from SD device into OCRAM. The values
+need to adjust accordingly for SD/eMMC
+
+SRC should match the cfg_rcw_src, the reset config pins.
+ The value for source(SRC) can be 0x0040 or 0x0041
+ depending upon SD or eMMC.
+SRC_ADDR is the offset of u-boot-with-spl.bin image in SD device.
+ In the example above, 1MB. This is same as QSPI-NOR.
+DEST_ADDR is configured at 0x1800a000, matching bootloc set above.
+BLOCK_SIZE is the size to be copied by PBI.
+
+2) CCSR 4-byte write to 0x01e00404, data=0x00000000
+3) CCSR 4-byte write to 0x01e00400, data=0x1800a000
+The above two commands set bootloc register to 0x00000000_1800a000 where
+the u-boot code will be running in OCRAM.
+
+
+RCW image should be written at 8th block of device(SD/eMMC). Example of
+using u-boot command
+
+mmc erase 0x8 0x10
+mmc write <rcw image in memory> 0x8 <size of rcw in block count typical value=10>
+
+To form the SD-Boot image, build u-boot with SD config, for example,
+ls1088ardb_sdcard_qspi_defconfig. The image needed is u-boot-with-spl.bin.
+The u-boot image should be written to match SRC_ADDR, in above example
+offset 0x100000 in other work it means block location 0x800
+
+mmc erase 0x800 0x1800
+mmc write <u-boot image in memory> 0x800 <size of u-boot image in block count>
+
+With these two images in SD/eMMC device, the board can boot from SD/eMMC.
+
+MMU Translation Tables
+======================
+
+(1) Early MMU Tables:
+
+ Level 0 Level 1 Level 2
+------------------ ------------------ ------------------
+| 0x00_0000_0000 | -----> | 0x00_0000_0000 | -----> | 0x00_0000_0000 |
+------------------ ------------------ ------------------
+| 0x80_0000_0000 | --| | 0x00_4000_0000 | | 0x00_0020_0000 |
+------------------ | ------------------ ------------------
+| invalid | | | 0x00_8000_0000 | | 0x00_0040_0000 |
+------------------ | ------------------ ------------------
+ | | 0x00_c000_0000 | | 0x00_0060_0000 |
+ | ------------------ ------------------
+ | | 0x01_0000_0000 | | 0x00_0080_0000 |
+ | ------------------ ------------------
+ | ... ...
+ | ------------------
+ | | 0x05_8000_0000 | --|
+ | ------------------ |
+ | | 0x05_c000_0000 | |
+ | ------------------ |
+ | ... |
+ | ------------------ | ------------------
+ |--> | 0x80_0000_0000 | |-> | 0x00_3000_0000 |
+ ------------------ ------------------
+ | 0x80_4000_0000 | | 0x00_3020_0000 |
+ ------------------ ------------------
+ | 0x80_8000_0000 | | 0x00_3040_0000 |
+ ------------------ ------------------
+ | 0x80_c000_0000 | | 0x00_3060_0000 |
+ ------------------ ------------------
+ | 0x81_0000_0000 | | 0x00_3080_0000 |
+ ------------------ ------------------
+ ... ...
+
+(2) Final MMU Tables:
+
+ Level 0 Level 1 Level 2
+------------------ ------------------ ------------------
+| 0x00_0000_0000 | -----> | 0x00_0000_0000 | -----> | 0x00_0000_0000 |
+------------------ ------------------ ------------------
+| 0x80_0000_0000 | --| | 0x00_4000_0000 | | 0x00_0020_0000 |
+------------------ | ------------------ ------------------
+| invalid | | | 0x00_8000_0000 | | 0x00_0040_0000 |
+------------------ | ------------------ ------------------
+ | | 0x00_c000_0000 | | 0x00_0060_0000 |
+ | ------------------ ------------------
+ | | 0x01_0000_0000 | | 0x00_0080_0000 |
+ | ------------------ ------------------
+ | ... ...
+ | ------------------
+ | | 0x08_0000_0000 | --|
+ | ------------------ |
+ | | 0x08_4000_0000 | |
+ | ------------------ |
+ | ... |
+ | ------------------ | ------------------
+ |--> | 0x80_0000_0000 | |--> | 0x08_0000_0000 |
+ ------------------ ------------------
+ | 0x80_4000_0000 | | 0x08_0020_0000 |
+ ------------------ ------------------
+ | 0x80_8000_0000 | | 0x08_0040_0000 |
+ ------------------ ------------------
+ | 0x80_c000_0000 | | 0x08_0060_0000 |
+ ------------------ ------------------
+ | 0x81_0000_0000 | | 0x08_0080_0000 |
+ ------------------ ------------------
+ ... ...
+
+
+DPAA2 commands to manage Management Complex (MC)
+------------------------------------------------
+DPAA2 commands has been introduced to manage Management Complex
+(MC). These commands are used to start mc, aiop and apply DPL
+from u-boot command prompt.
+
+Please note Management complex Firmware(MC), DPL and DPC are no
+more deployed during u-boot boot-sequence.
+
+Commands:
+a) fsl_mc start mc <FW_addr> <DPC_addr> - Start Management Complex
+b) fsl_mc apply DPL <DPL_addr> - Apply DPL file
+c) fsl_mc start aiop <FW_addr> - Start AIOP
+
+How to use commands :-
+1. Command sequence for u-boot ethernet:
+ a) fsl_mc start mc <FW_addr> <DPC_addr> - Start Management Complex
+ b) DPMAC net-devices are now available for use
+
+ Example-
+ Assumption: MC firmware, DPL and DPC dtb is already programmed
+ on NOR flash.
+
+ => fsl_mc start mc 580300000 580800000
+ => setenv ethact DPMAC1@xgmii
+ => ping $serverip
+
+2. Command sequence for Linux boot:
+ a) fsl_mc start mc <FW_addr> <DPC_addr> - Start Management Complex
+ b) fsl_mc apply DPL <DPL_addr> - Apply DPL file
+ c) No DPMAC net-devices are available for use in u-boot
+ d) boot Linux
+
+ Example-
+ Assumption: MC firmware, DPL and DPC dtb is already programmed
+ on NOR flash.
+
+ => fsl_mc start mc 580300000 580800000
+ => setenv ethact DPMAC1@xgmii
+ => tftp a0000000 kernel.itb
+ => fsl_mc apply dpl 580700000
+ => bootm a0000000
+
+3. Command sequence for AIOP boot:
+ a) fsl_mc start mc <FW_addr> <DPC_addr> - Start Management Complex
+ b) fsl_mc start aiop <FW_addr> - Start AIOP
+ c) fsl_mc apply DPL <DPL_addr> - Apply DPL file
+ d) No DPMAC net-devices are availabe for use in u-boot
+ Please note actual AIOP start will happen during DPL parsing of
+ Management complex
+
+ Example-
+ Assumption: MC firmware, DPL, DPC dtb and AIOP firmware is already
+ programmed on NOR flash.
+
+ => fsl_mc start mc 580300000 580800000
+ => fsl_mc start aiop 0x580900000
+ => setenv ethact DPMAC1@xgmii
+ => fsl_mc apply dpl 580700000
+
+Errata A009635
+---------------
+If the core runs at higher than x3 speed of the platform, there is
+possiblity about sev instruction to getting missed by other cores.
+This is because of SoC Run Control block may not able to sample
+the EVENTI(Sev) signals.
+
+Workaround: Configure Run Control and EPU to periodically send out EVENTI signals to
+wake up A57 cores
+
+Errata workaround uses Env variable "a009635_interval_val". It uses decimal
+value.
+- Default value of env variable is platform clock (MHz)
+
+- User can modify default value by updating the env variable
+ setenv a009635_interval_val 600; saveenv;
+ It configure platform clock as 600 MHz
+
+- Env variable as 0 signifies no workaround
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3_2 b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3_2
new file mode 100644
index 000000000..6d4bd0b80
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3_2
@@ -0,0 +1,27 @@
+#
+# Copyright 2018 NXP
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+NXP LayerScape with Chassis Generation 3.2
+
+This architecture supports NXP ARMv8 SoCs with Chassis generation 3.2
+for example LX2160A.
+
+This architecture is enhancement over Chassis Generation 3 with
+few differences mentioned below
+
+1)DDR Layout
+============
+Entire DDR region splits into three regions.
+ - Region 1 is at address 0x8000_0000 to 0xffff_ffff.
+ - Region 2 is at address 0x20_8000_0000 to 0x3f_ffff_ffff,
+ - Region 3 is at address 0x60_0000_0000 to the top of memory,
+ for example 140GB, 0x63_7fff_ffff.
+
+All DDR memory is marked as cache-enabled.
+
+2)IFC is removed
+
+3)Number of I2C controllers increased to 8
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.pci_iommu_extra b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.pci_iommu_extra
new file mode 100644
index 000000000..43db4d8e9
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.pci_iommu_extra
@@ -0,0 +1,67 @@
+#
+# Copyright 2020 NXP
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+Specifying extra IOMMU mappings for PCI controllers
+
+This feature can be enabled through the PCI_IOMMU_EXTRA_MAPPINGS Kconfig option.
+
+The "pci_iommu_extra" env var or "pci-iommu-extra" device tree property (to be
+used for example in more static scenarios such as hardwired PCI endpoints that
+get initialized later in the system setup) allows two things:
+ - for a SRIOV capable PCI EP identified by its B.D.F specify the maximum number
+ of VFs that will ever be created for it
+ - for hot-plug case, specify the B.D.F with which the device will show up on
+ the PCI bus
+
+The env var consists of a list of <bdf>,<action> pairs for a certain pci bus
+identified by its controller's base register address, as defined in the "reg"
+property in the device tree.
+
+pci_iommu_extra = pci@<addr1>,<bdf>,<action>,<bdf>,<action>,
+ pci@<addr2>,<bdf>,<action>,<bdf>,<action>,...
+
+where:
+ <addr> is the base register address of the pci controller for which the
+ subsequent <bdf>,<action> pairs apply
+ <bdf> identifies to which B.D.F the action applies to
+ <action> can be:
+ - "vfs=<number>" to specify that for the PCI EP identified previously by
+ the <bdf> to include mappings for <number> of VFs.
+ The variant "noari_vfs=<number>" is available to disable taking ARI into
+ account.
+ - "hp" to specify that on this <bdf> there will be a hot-plugged device so
+ it needs a mapping
+The device tree property must be placed under the correct pci controller node
+and only the bdf and action pairs need to be specified, like this:
+
+pci-iommu-extra = "<bdf>,<action>,<bdf>,<action>,...";
+
+Note: the env var has priority over the device tree property.
+
+For example, given this configuration on bus 6:
+
+=> pci 6
+Scanning PCI devices on bus 6
+BusDevFun VendorId DeviceId Device Class Sub-Class
+_____________________________________________________________
+06.00.00 0x8086 0x1572 Network controller 0x00
+06.00.01 0x8086 0x1572 Network controller 0x00
+
+The following u-boot env var will create iommu mappings for 3 VFs for each PF:
+
+=> setenv pci_iommu_extra pci@0x3800000,6.0.0,vfs=3,6.0.1,vfs=3
+
+For the device tree case, this would be specified like this:
+
+pci-iommu-extra = "6.0.0,vfs=3,6.0.1,vfs=3";
+
+To add an iommu mapping for a hot-plugged device, please see following example:
+
+=> setenv pci_iommu_extra pci@0x3800000,2.16.0,hp
+
+For the device tree case, this would be specified like this:
+
+pci-iommu-extra = "2.16.0,hp";
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.qspi b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.qspi
new file mode 100644
index 000000000..de86f4b30
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.qspi
@@ -0,0 +1,42 @@
+QSPI Boot source support Overview
+-------------------
+ 1. LS1043A
+ LS1043AQDS
+ 2. LS2080A
+ LS2080AQDS
+ 3. LS1012A
+ LS1012AQDS
+ LS1012ARDB
+ 4. LS1046A
+ LS1046AQDS
+ LS1046ARDB
+
+Booting from QSPI
+-------------------
+Booting from QSPI requires two images, RCW and u-boot-dtb.bin.
+The difference between QSPI boot RCW image and NOR boot image is the PBI
+command sequence for setting the boot location pointer. It's should point
+to the address for u-boot in QSPI flash.
+
+RCW image should be written to the beginning of QSPI flash device.
+Example of using u-boot command
+
+=> sf probe 0:0
+SF: Detected S25FL256S_64K with page size 256 Bytes, erase size 64 KiB, total 32 MiB
+=> sf erase 0 +<size of rcw image>
+SF: 65536 bytes @ 0x0 Erased: OK
+=> sf write <rcw image in memory> 0 <size of rcw image>
+SF: 164 bytes @ 0x0 Written: OK
+
+To get the QSPI image, build u-boot with QSPI config, for example,
+<board_name>_qspi_defconfig. The image needed is u-boot-dtb.bin.
+The u-boot image should be written to 0x10000(but 0x1000 for LS1043A, LS2080A).
+
+=> sf probe 0:0
+SF: Detected S25FL256S_64K with page size 256 Bytes, erase size 64 KiB, total 32 MiB
+=> sf erase 10000 +<size of u-boot image>
+SF: 589824 bytes @ 0x10000 Erased: OK
+=> sf write <u-boot image in memory> 10000 <size of u-boot image>
+SF: 580966 bytes @ 0x10000 Written: OK
+
+With these two images in QSPI flash device, the board can boot from QSPI.
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc
new file mode 100644
index 000000000..f33d05d05
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc
@@ -0,0 +1,437 @@
+SoC overview
+
+ 1. LS1043A
+ 2. LS1088A
+ 3. LS2080A
+ 4. LS1012A
+ 5. LS1046A
+ 6. LS2088A
+ 7. LS2081A
+ 8. LX2160A
+ 9. LS1028A
+ 10. LX2162A
+
+LS1043A
+---------
+The LS1043A integrated multicore processor combines four ARM Cortex-A53
+processor cores with datapath acceleration optimized for L2/3 packet
+processing, single pass security offload and robust traffic management
+and quality of service.
+
+The LS1043A SoC includes the following function and features:
+ - Four 64-bit ARM Cortex-A53 CPUs
+ - 1 MB unified L2 Cache
+ - One 32-bit DDR3L/DDR4 SDRAM memory controllers with ECC and interleaving
+ support
+ - Data Path Acceleration Architecture (DPAA) incorporating acceleration the
+ the following functions:
+ - Packet parsing, classification, and distribution (FMan)
+ - Queue management for scheduling, packet sequencing, and congestion
+ management (QMan)
+ - Hardware buffer management for buffer allocation and de-allocation (BMan)
+ - Cryptography acceleration (SEC)
+ - Ethernet interfaces by FMan
+ - Up to 1 x XFI supporting 10G interface
+ - Up to 1 x QSGMII
+ - Up to 4 x SGMII supporting 1000Mbps
+ - Up to 2 x SGMII supporting 2500Mbps
+ - Up to 2 x RGMII supporting 1000Mbps
+ - High-speed peripheral interfaces
+ - Three PCIe 2.0 controllers, one supporting x4 operation
+ - One serial ATA (SATA 3.0) controllers
+ - Additional peripheral interfaces
+ - Three high-speed USB 3.0 controllers with integrated PHY
+ - Enhanced secure digital host controller (eSDXC/eMMC)
+ - Quad Serial Peripheral Interface (QSPI) Controller
+ - Serial peripheral interface (SPI) controller
+ - Four I2C controllers
+ - Two DUARTs
+ - Integrated flash controller supporting NAND and NOR flash
+ - QorIQ platform's trust architecture 2.1
+
+LS1088A
+--------
+The QorIQ LS1088A processor is built on the Layerscape
+architecture combining eight ARM A53 processor cores
+with advanced, high-performance datapath acceleration
+and networks, peripheral interfaces required for
+networking, wireless infrastructure, and general-purpose
+embedded applications.
+
+LS1088A is compliant with the Layerscape Chassis Generation 3.
+
+Features summary:
+ - 8 32-bit / 64-bit ARM v8 Cortex-A53 CPUs
+ - Cores are in 2 cluster of 4-cores each
+ - 1MB L2 - Cache per cluster
+ - Cache coherent interconnect (CCI-400)
+ - 1 64-bit DDR4 SDRAM memory controller with ECC
+ - Data path acceleration architecture 2.0 (DPAA2)
+ - 4-Lane 10GHz SerDes comprising of WRIOP
+ - 4-Lane 10GHz SerDes comprising of PCI, SATA, uQE(TDM/HLDC/UART)
+ - Ethernet interfaces: SGMIIs, RGMIIs, QSGMIIs, XFIs
+ - QSPI, SPI, IFC2.0 supporting NAND, NOR flash
+ - 3 PCIe3.0 , 1 SATA3.0, 2 USB3.0, 1 SDXC, 2 DUARTs etc
+ - 2 DUARTs
+ - 4 I2C, GPIO
+ - Thermal monitor unit(TMU)
+ - 4 Flextimers and 1 generic timer
+ - Support for hardware virtualization and partitioning enforcement
+ - QorIQ platform's trust architecture 3.0
+ - Service processor (SP) provides pre-boot initialization and secure-boot
+ capabilities
+
+LS2080A
+--------
+The LS2080A integrated multicore processor combines eight ARM Cortex-A57
+processor cores with high-performance data path acceleration logic and network
+and peripheral bus interfaces required for networking, telecom/datacom,
+wireless infrastructure, and mil/aerospace applications.
+
+The LS2080A SoC includes the following function and features:
+
+ - Eight 64-bit ARM Cortex-A57 CPUs
+ - 1 MB platform cache with ECC
+ - Two 64-bit DDR4 SDRAM memory controllers with ECC and interleaving support
+ - One secondary 32-bit DDR4 SDRAM memory controller, intended for use by
+ the AIOP
+ - Data path acceleration architecture (DPAA2) incorporating acceleration for
+ the following functions:
+ - Packet parsing, classification, and distribution (WRIOP)
+ - Queue and Hardware buffer management for scheduling, packet sequencing, and
+ congestion management, buffer allocation and de-allocation (QBMan)
+ - Cryptography acceleration (SEC) at up to 10 Gbps
+ - RegEx pattern matching acceleration (PME) at up to 10 Gbps
+ - Decompression/compression acceleration (DCE) at up to 20 Gbps
+ - Accelerated I/O processing (AIOP) at up to 20 Gbps
+ - QDMA engine
+ - 16 SerDes lanes at up to 10.3125 GHz
+ - Ethernet interfaces
+ - Up to eight 10 Gbps Ethernet MACs
+ - Up to eight 1 / 2.5 Gbps Ethernet MACs
+ - High-speed peripheral interfaces
+ - Four PCIe 3.0 controllers, one supporting SR-IOV
+ - Additional peripheral interfaces
+ - Two serial ATA (SATA 3.0) controllers
+ - Two high-speed USB 3.0 controllers with integrated PHY
+ - Enhanced secure digital host controller (eSDXC/eMMC)
+ - Serial peripheral interface (SPI) controller
+ - Quad Serial Peripheral Interface (QSPI) Controller
+ - Four I2C controllers
+ - Two DUARTs
+ - Integrated flash controller (IFC 2.0) supporting NAND and NOR flash
+ - Support for hardware virtualization and partitioning enforcement
+ - QorIQ platform's trust architecture 3.0
+ - Service processor (SP) provides pre-boot initialization and secure-boot
+ capabilities
+
+LS1012A
+--------
+The LS1012A features an advanced 64-bit ARM v8 Cortex-
+A53 processor, with 32 KB of parity protected L1-I cache,
+32 KB of ECC protected L1-D cache, as well as 256 KB of
+ECC protected L2 cache.
+
+The LS1012A SoC includes the following function and features:
+ - One 64-bit ARM v8 Cortex-A53 core with the following capabilities:
+ - ARM v8 cryptography extensions
+ - One 16-bit DDR3L SDRAM memory controller, Up to 1.0 GT/s, Supports
+ 16-/8-bit operation (no ECC support)
+ - ARM core-link CCI-400 cache coherent interconnect
+ - Packet Forwarding Engine (PFE)
+ - Cryptography acceleration (SEC)
+ - Ethernet interfaces supported by PFE:
+ - One Configurable x3 SerDes:
+ Two Serdes PLLs supported for usage by any SerDes data lane
+ Support for up to 6 GBaud operation
+ - High-speed peripheral interfaces:
+ - One PCI Express Gen2 controller, supporting x1 operation
+ - One serial ATA (SATA Gen 3.0) controller
+ - One USB 3.0/2.0 controller with integrated PHY
+ - One USB 2.0 controller with ULPI interface. .
+ - Additional peripheral interfaces:
+ - One quad serial peripheral interface (QuadSPI) controller
+ - One serial peripheral interface (SPI) controller
+ - Two enhanced secure digital host controllers
+ - Two I2C controllers
+ - One 16550 compliant DUART (two UART interfaces)
+ - Two general purpose IOs (GPIO)
+ - Two FlexTimers
+ - Five synchronous audio interfaces (SAI)
+ - Pre-boot loader (PBL) provides pre-boot initialization and RCW loading
+ - Single-source clocking solution enabling generation of core, platform,
+ DDR, SerDes, and USB clocks from a single external crystal and internal
+ crystaloscillator
+ - Thermal monitor unit (TMU) with +/- 3C accuracy
+ - Two WatchDog timers
+ - ARM generic timer
+ - QorIQ platform's trust architecture 2.1
+
+LS1046A
+--------
+The LS1046A integrated multicore processor combines four ARM Cortex-A72
+processor cores with datapath acceleration optimized for L2/3 packet
+processing, single pass security offload and robust traffic management
+and quality of service.
+
+The LS1046A SoC includes the following function and features:
+ - Four 64-bit ARM Cortex-A72 CPUs
+ - 2 MB unified L2 Cache
+ - One 64-bit DDR4 SDRAM memory controllers with ECC and interleaving
+ support
+ - Data Path Acceleration Architecture (DPAA) incorporating acceleration the
+ the following functions:
+ - Packet parsing, classification, and distribution (FMan)
+ - Queue management for scheduling, packet sequencing, and congestion
+ management (QMan)
+ - Hardware buffer management for buffer allocation and de-allocation (BMan)
+ - Cryptography acceleration (SEC)
+ - Two Configurable x4 SerDes
+ - Two PLLs per four-lane SerDes
+ - Support for 10G operation
+ - Ethernet interfaces by FMan
+ - Up to 2 x XFI supporting 10G interface (MAC 9, 10)
+ - Up to 1 x QSGMII (MAC 5, 6, 10, 1)
+ - Up to 4 x SGMII supporting 1000Mbps (MAC 5, 6, 9, 10)
+ - Up to 3 x SGMII supporting 2500Mbps (MAC 5, 9, 10)
+ - Up to 2 x RGMII supporting 1000Mbps (MAC 3, 4)
+ - High-speed peripheral interfaces
+ - Three PCIe 3.0 controllers, one supporting x4 operation
+ - One serial ATA (SATA 3.0) controllers
+ - Additional peripheral interfaces
+ - Three high-speed USB 3.0 controllers with integrated PHY
+ - Enhanced secure digital host controller (eSDXC/eMMC)
+ - Quad Serial Peripheral Interface (QSPI) Controller
+ - Serial peripheral interface (SPI) controller
+ - Four I2C controllers
+ - Two DUARTs
+ - Integrated flash controller (IFC) supporting NAND and NOR flash
+ - QorIQ platform's trust architecture 2.1
+
+LS2088A
+--------
+The LS2088A integrated multicore processor combines eight ARM Cortex-A72
+processor cores with high-performance data path acceleration logic and network
+and peripheral bus interfaces required for networking, telecom/datacom,
+wireless infrastructure, and mil/aerospace applications.
+
+The LS2088A SoC includes the following function and features:
+
+ - Eight 64-bit ARM Cortex-A72 CPUs
+ - 1 MB platform cache with ECC
+ - Two 64-bit DDR4 SDRAM memory controllers with ECC and interleaving support
+ - One secondary 32-bit DDR4 SDRAM memory controller, intended for use by
+ the AIOP
+ - Data path acceleration architecture (DPAA2) incorporating acceleration for
+ the following functions:
+ - Packet parsing, classification, and distribution (WRIOP)
+ - Queue and Hardware buffer management for scheduling, packet sequencing, and
+ congestion management, buffer allocation and de-allocation (QBMan)
+ - Cryptography acceleration (SEC) at up to 10 Gbps
+ - RegEx pattern matching acceleration (PME) at up to 10 Gbps
+ - Decompression/compression acceleration (DCE) at up to 20 Gbps
+ - Accelerated I/O processing (AIOP) at up to 20 Gbps
+ - QDMA engine
+ - 16 SerDes lanes at up to 10.3125 GHz
+ - Ethernet interfaces
+ - Up to eight 10 Gbps Ethernet MACs
+ - Up to eight 1 / 2.5 Gbps Ethernet MACs
+ - High-speed peripheral interfaces
+ - Four PCIe 3.0 controllers, one supporting SR-IOV
+ - Additional peripheral interfaces
+ - Two serial ATA (SATA 3.0) controllers
+ - Two high-speed USB 3.0 controllers with integrated PHY
+ - Enhanced secure digital host controller (eSDXC/eMMC)
+ - Serial peripheral interface (SPI) controller
+ - Quad Serial Peripheral Interface (QSPI) Controller
+ - Four I2C controllers
+ - Two DUARTs
+ - Integrated flash controller (IFC 2.0) supporting NAND and NOR flash
+ - Support for hardware virtualization and partitioning enforcement
+ - QorIQ platform's trust architecture 3.0
+ - Service processor (SP) provides pre-boot initialization and secure-boot
+ capabilities
+
+LS2088A SoC has 3 more similar SoC personalities
+1)LS2048A, few difference w.r.t. LS2088A:
+ a) Four 64-bit ARM v8 Cortex-A72 CPUs
+
+2)LS2084A, few difference w.r.t. LS2088A:
+ a) No AIOP
+ b) No 32-bit DDR3 SDRAM memory
+ c) 5 * 1/10G + 5 *1G WRIOP
+ d) No L2 switch
+
+3)LS2044A, few difference w.r.t. LS2084A:
+ a) Four 64-bit ARM v8 Cortex-A72 CPUs
+
+LS2081A
+--------
+LS2081A is 40-pin derivative of LS2084A.
+So feature-wise it is same as LS2084A.
+Refer to LS2084A(LS2088A) section above for details.
+
+It has one more similar SoC personality
+1)LS2041A, few difference w.r.t. LS2081A:
+ a) Four 64-bit ARM v8 Cortex-A72 CPUs
+
+LX2160A
+--------
+The QorIQ LX2160A processor is built in the 16FFC process on
+the Layerscape architecture combining sixteen ARM A72 processor
+cores with advanced, high-performance datapath acceleration and
+network, peripheral interfaces required for networking, wireless
+infrastructure, storage, and general-purpose embedded applications.
+
+LX2160A is compliant with the Layerscape Chassis Generation 3.2.
+
+The LX2160A SoC includes the following function and features:
+ Sixteen 32-bit / 64-bit ARM v8 A72 CPUs
+ Cache Coherent Interconnect Fabric (CCN508 aka “Eliot”)
+ Two 64-bit 3.2GT/s DDR4 SDRAM memory controllers with ECC.
+ Data path acceleration architecture (DPAA2)
+ 24 Serdes lanes at up to 25 GHz
+ Ethernet interfaces
+ Single WRIOP tile supporting 130Gbps using 18 MACs
+ Support for 10G-SXGMII (aka USXGMII).
+ Support for SGMII (and 1000Base-KX)
+ Support for XFI (and 10GBase-KR)
+ Support for CAUI4 (100G); CAUI2 (50G) and 25G-AUI(25G).
+ Support for XLAUI (and 40GBase-KR4) for 40G.
+ Support for two RGMII parallel interfaces.
+ Energy efficient Ethernet support (802.3az)
+ IEEE 1588 support.
+ High-speed peripheral interfaces
+ Two PCIe Gen 4.0 8-lane controllers supporting SR-IOV,
+ Four PCIe Gen 4.0 4-lane controllers.
+ Four serial ATA (SATA 3.0) controllers.
+ Two USB 3.0 controllers with integrated PHY
+ Two Enhanced secure digital host controllers
+ Two Controller Area Network (CAN) modules
+ Flexible Serial peripheral interface (FlexSPI) controller.
+ Three Serial peripheral interface (SPI) controllers.
+ Eight I2C Controllers.
+ Four PL011 UARTs supporting two 4-pin UART ports or four 2-pin UART ports.
+ General Purpose IO (GPIO)
+ Support for hardware virtualization and partitioning (ARM MMU-500)
+ Support for GIC (ARM GIC-500)
+ QorIQ platform Trust Architecture 3.0
+ One Secure WatchDog timer and one Non-Secure Watchdog timer.
+ ARM Generic Timer
+ Two Flextimers
+ Debug supporting run control, data acquisition, high-speed trace,
+ performance/event monitoring
+ Thermal Monitor Unit (TMU) with +/- 2C accuracy
+ Support for Voltage ID (VID) for yield improvement
+
+LX2160A SoC has 2 more similar SoC personalities
+1)LX2120A, few difference w.r.t. LX2160A:
+ a) Twelve 64-bit ARM v8 Cortex-A72 CPUs
+
+2)LX2080A, few difference w.r.t. LX2160A:
+ a) Eight 64-bit ARM v8 Cortex-A72 CPUs
+
+
+LS1028A
+--------
+The QorIQ LS1028A processor integrates two 64-bit Arm Cortex-A72 cores with
+a GPU and LCD controller, as well as two TSN-enabled Ethernet controllers and
+a TSNenabled 4-port switch.
+
+The high performance Cortex-A72 cores, performing above 16,000 CoreMarks,
+combined with 2.5 Gbit Ethernet, PCI express Gen 3.0, SATA 3.0, USB 3.0 and
+Octal/Quad SPI interfaces provide capabilities for a number of industrial and
+embedded applications. The device provides excellent integration with the
+new Time-Sensitive Networking standard, and enables a number of
+TSN applications.
+
+The LS1028A SoC includes the following function and features:
+ - Two 64-bit ARM v8 A72 CPUs
+ - Cache Coherent interconnect (CCI-400)
+ - One 32-bit DDR3L/DDR4 SDRAM memory controller with ECC
+ - eDP/Displayport interface
+ - Graphics processing unit
+ - One Configurable x4 SerDes
+ - Ethernet interfaces
+ - Non-switched: One Ethernet MAC supporting 2.5G, 1G, 100M, 10M, one
+ ethernet MAC supporting 1G, 100M, 10M.
+ - Switched: TSN IP to support four 2.5/1G interfaces.
+ - None of the MACs support MACSEC
+ - Support for RGMII, SGMII (and 1000Base-KX), SGMII 2.5x, QSGMII
+ - Support for 10G-SXGMII and 10G-QXGMII.
+ - Energy efficient Ethernet support (802.3az)
+ - IEEE 1588 support
+ - High-speed peripheral interfaces
+ - Two PCIe 3.0 controllers, one supporting x4 operation
+ - One serial ATA (SATA 3.0) controller
+ - Additional peripheral interfaces
+ - Two high-speed USB 2.0/3.0 controllers with integrated PHY each
+ supporting host or device modes
+ - Two Enhanced secure digital host controllers (SD/SDIO/eMMC)
+ - Two Serial peripheral interface (SPI) controllers
+ - Eight I2C controllers
+ - Two UART controllers
+ - Additional six Industrual UARTs (LPUART).
+ - One FlexSPI controller
+ - General Purpose IO (GPIO)
+ - Two CAN-FD interfaces
+ - Eight Flextimers with PWM I/O
+ - Support for hardware virtualization and partitioning enforcement
+ - Layerscape Trust Architecture
+ - Service Processor (SP) provides pre-boot initialization and secure-boot
+ capabilities
+
+LX2162A
+--------
+The QorIQ LX2162A processor is built on the Layerscape architecture
+combining sixteen ARM A72 processor cores with advanced, high-performance
+datapath acceleration and network, peripheral interfaces required for
+networking, wireless infrastructure, storage, and general-purpose embedded
+applications.
+
+LX2162A is compliant with the Layerscape Chassis Generation 3.2.
+
+The LX2162A SoC includes the following function and features:
+ Sixteen 32-bit / 64-bit ARM v8 A72 CPUs
+ Cache Coherent Interconnect Fabric (CCN508)
+ One 64-bit 2.9GT/s DDR4 SDRAM memory controllers with ECC.
+ Data path acceleration architecture (DPAA2)
+ 12 Serdes lanes at up to 25 GHz
+ Ethernet interfaces
+ Support for 10G-SXGMII (aka USXGMII).
+ Support for SGMII (and 1000Base-KX)
+ Support for XFI (and 10GBase-KR)
+ Support for CAUI2 (50G) and 25G-AUI(25G).
+ Support for XLAUI (and 40GBase-KR4) for 40G.
+ Support for two RGMII parallel interfaces.
+ Energy efficient Ethernet support (802.3az)
+ IEEE 1588 support.
+ High-speed peripheral interfaces
+ One PCIe Gen 3.0 8-lane controllers supporting SR-IOV,
+ Two PCIe Gen 3.0 4-lane controllers.
+ Four serial ATA (SATA 3.0) controllers.
+ One USB 3.0 controllers with integrated PHY
+ Two Enhanced secure digital host controllers
+ Two Controller Area Network (CAN) modules
+ Flexible Serial peripheral interface (FlexSPI) controller.
+ Three Serial peripheral interface (SPI) controllers.
+ Eight I2C Controllers.
+ Four PL011 UARTs supporting two 4-pin UART ports or four 2-pin UART ports.
+ General Purpose IO (GPIO)
+ Support for hardware virtualization and partitioning (ARM MMU-500)
+ Support for GIC (ARM GIC-500)
+ QorIQ platform Trust Architecture 3.0
+ One Secure WatchDog timer and one Non-Secure Watchdog timer.
+ ARM Generic Timer
+ Two Flextimers
+ Debug supporting run control, data acquisition, high-speed trace,
+ performance/event monitoring
+ Thermal Monitor Unit (TMU) with +/- 2C accuracy
+ Support for Voltage ID (VID) for yield improvement
+
+LX2162A SoC has 2 more similar SoC personalities
+1)LX2122A, few difference w.r.t. LX2162A:
+ a) Twelve 64-bit ARM v8 Cortex-A72 CPUs
+
+2)LX2082A, few difference w.r.t. LX2162A:
+ a) Eight 64-bit ARM v8 Cortex-A72 CPUs
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
new file mode 100644
index 000000000..f1624ff30
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
@@ -0,0 +1,700 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014-2015 Freescale Semiconductor, Inc.
+ * Copyright 2020-2021 NXP
+ */
+
+#include <common.h>
+#include <clock_legacy.h>
+#include <efi_loader.h>
+#include <log.h>
+#include <asm/cache.h>
+#include <linux/libfdt.h>
+#include <fdt_support.h>
+#include <phy.h>
+#ifdef CONFIG_FSL_LSCH3
+#include <asm/arch/fdt.h>
+#endif
+#ifdef CONFIG_FSL_ESDHC
+#include <fsl_esdhc.h>
+#endif
+#ifdef CONFIG_SYS_DPAA_FMAN
+#include <fsl_fman.h>
+#endif
+#ifdef CONFIG_MP
+#include <asm/arch/mp.h>
+#endif
+#include <fsl_sec.h>
+#include <asm/arch-fsl-layerscape/soc.h>
+#if CONFIG_IS_ENABLED(ARMV8_SEC_FIRMWARE_SUPPORT)
+#include <asm/armv8/sec_firmware.h>
+#endif
+#include <asm/arch/speed.h>
+#include <fsl_qbman.h>
+
+int fdt_fixup_phy_connection(void *blob, int offset, phy_interface_t phyc)
+{
+ const char *conn;
+
+ /* Do NOT apply fixup for backplane modes specified in DT */
+ if (phyc == PHY_INTERFACE_MODE_XGMII) {
+ conn = fdt_getprop(blob, offset, "phy-connection-type", NULL);
+ if (is_backplane_mode(conn))
+ return 0;
+ }
+ return fdt_setprop_string(blob, offset, "phy-connection-type",
+ phy_string_for_interface(phyc));
+}
+
+#ifdef CONFIG_MP
+void ft_fixup_cpu(void *blob)
+{
+ int off;
+ __maybe_unused u64 spin_tbl_addr = (u64)get_spin_tbl_addr();
+ fdt32_t *reg;
+ int addr_cells;
+ u64 val, core_id;
+ u32 mask = cpu_pos_mask();
+ int off_prev = -1;
+
+ off = fdt_path_offset(blob, "/cpus");
+ if (off < 0) {
+ puts("couldn't find /cpus node\n");
+ return;
+ }
+
+ fdt_support_default_count_cells(blob, off, &addr_cells, NULL);
+
+ off = fdt_node_offset_by_prop_value(blob, off_prev, "device_type",
+ "cpu", 4);
+ while (off != -FDT_ERR_NOTFOUND) {
+ reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0);
+ if (reg) {
+ core_id = fdt_read_number(reg, addr_cells);
+ if (!test_bit(id_to_core(core_id), &mask)) {
+ fdt_del_node(blob, off);
+ off = off_prev;
+ }
+ }
+ off_prev = off;
+ off = fdt_node_offset_by_prop_value(blob, off_prev,
+ "device_type", "cpu", 4);
+ }
+
+#if CONFIG_IS_ENABLED(ARMV8_SEC_FIRMWARE_SUPPORT) && \
+ defined(CONFIG_SEC_FIRMWARE_ARMV8_PSCI)
+ int node;
+ u32 psci_ver;
+
+ /* Check the psci version to determine if the psci is supported */
+ psci_ver = sec_firmware_support_psci_version();
+ if (psci_ver == 0xffffffff) {
+ /* remove psci DT node */
+ node = fdt_path_offset(blob, "/psci");
+ if (node >= 0)
+ goto remove_psci_node;
+
+ node = fdt_node_offset_by_compatible(blob, -1, "arm,psci");
+ if (node >= 0)
+ goto remove_psci_node;
+
+ node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-0.2");
+ if (node >= 0)
+ goto remove_psci_node;
+
+ node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-1.0");
+ if (node >= 0)
+ goto remove_psci_node;
+
+remove_psci_node:
+ if (node >= 0)
+ fdt_del_node(blob, node);
+ } else {
+ return;
+ }
+#endif
+ off = fdt_path_offset(blob, "/cpus");
+ if (off < 0) {
+ puts("couldn't find /cpus node\n");
+ return;
+ }
+ fdt_support_default_count_cells(blob, off, &addr_cells, NULL);
+
+ off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
+ while (off != -FDT_ERR_NOTFOUND) {
+ reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0);
+ if (reg) {
+ core_id = fdt_read_number(reg, addr_cells);
+ if (core_id == 0 || (is_core_online(core_id))) {
+ val = spin_tbl_addr;
+ val += id_to_core(core_id) *
+ SPIN_TABLE_ELEM_SIZE;
+ val = cpu_to_fdt64(val);
+ fdt_setprop_string(blob, off, "enable-method",
+ "spin-table");
+ fdt_setprop(blob, off, "cpu-release-addr",
+ &val, sizeof(val));
+ } else {
+ debug("skipping offline core\n");
+ }
+ } else {
+ puts("Warning: found cpu node without reg property\n");
+ }
+ off = fdt_node_offset_by_prop_value(blob, off, "device_type",
+ "cpu", 4);
+ }
+
+ fdt_add_mem_rsv(blob, (uintptr_t)secondary_boot_code_start,
+ secondary_boot_code_size);
+#if CONFIG_IS_ENABLED(EFI_LOADER)
+ efi_add_memory_map((uintptr_t)secondary_boot_code_start,
+ secondary_boot_code_size, EFI_RESERVED_MEMORY_TYPE);
+#endif
+}
+#endif
+
+void fsl_fdt_disable_usb(void *blob)
+{
+ int off;
+ /*
+ * SYSCLK is used as a reference clock for USB. When the USB
+ * controller is used, SYSCLK must meet the additional requirement
+ * of 100 MHz.
+ */
+ if (CONFIG_SYS_CLK_FREQ != 100000000) {
+ off = fdt_node_offset_by_compatible(blob, -1, "snps,dwc3");
+ while (off != -FDT_ERR_NOTFOUND) {
+ fdt_status_disabled(blob, off);
+ off = fdt_node_offset_by_compatible(blob, off,
+ "snps,dwc3");
+ }
+ }
+}
+
+#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
+static void fdt_fixup_gic(void *blob)
+{
+ int offset, err;
+ u64 reg[8];
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ unsigned int val;
+ struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
+ int align_64k = 0;
+
+ val = gur_in32(&gur->svr);
+
+ if (!IS_SVR_DEV(val, SVR_DEV(SVR_LS1043A))) {
+ align_64k = 1;
+ } else if (SVR_REV(val) != REV1_0) {
+ val = scfg_in32(&scfg->gic_align) & (0x01 << GIC_ADDR_BIT);
+ if (!val)
+ align_64k = 1;
+ }
+
+ offset = fdt_subnode_offset(blob, 0, "interrupt-controller@1400000");
+ if (offset < 0) {
+ printf("WARNING: fdt_subnode_offset can't find node %s: %s\n",
+ "interrupt-controller@1400000", fdt_strerror(offset));
+ return;
+ }
+
+ /* Fixup gic node align with 64K */
+ if (align_64k) {
+ reg[0] = cpu_to_fdt64(GICD_BASE_64K);
+ reg[1] = cpu_to_fdt64(GICD_SIZE_64K);
+ reg[2] = cpu_to_fdt64(GICC_BASE_64K);
+ reg[3] = cpu_to_fdt64(GICC_SIZE_64K);
+ reg[4] = cpu_to_fdt64(GICH_BASE_64K);
+ reg[5] = cpu_to_fdt64(GICH_SIZE_64K);
+ reg[6] = cpu_to_fdt64(GICV_BASE_64K);
+ reg[7] = cpu_to_fdt64(GICV_SIZE_64K);
+ } else {
+ /* Fixup gic node align with default */
+ reg[0] = cpu_to_fdt64(GICD_BASE);
+ reg[1] = cpu_to_fdt64(GICD_SIZE);
+ reg[2] = cpu_to_fdt64(GICC_BASE);
+ reg[3] = cpu_to_fdt64(GICC_SIZE);
+ reg[4] = cpu_to_fdt64(GICH_BASE);
+ reg[5] = cpu_to_fdt64(GICH_SIZE);
+ reg[6] = cpu_to_fdt64(GICV_BASE);
+ reg[7] = cpu_to_fdt64(GICV_SIZE);
+ }
+
+ err = fdt_setprop(blob, offset, "reg", reg, sizeof(reg));
+ if (err < 0) {
+ printf("WARNING: fdt_setprop can't set %s from node %s: %s\n",
+ "reg", "interrupt-controller@1400000",
+ fdt_strerror(err));
+ return;
+ }
+
+ return;
+}
+#endif
+
+#ifdef CONFIG_HAS_FEATURE_ENHANCED_MSI
+static int _fdt_fixup_msi_node(void *blob, const char *name,
+ int irq_0, int irq_1, int rev)
+{
+ int err, offset, len;
+ u32 tmp[4][3];
+ void *p;
+
+ offset = fdt_path_offset(blob, name);
+ if (offset < 0) {
+ printf("WARNING: fdt_path_offset can't find path %s: %s\n",
+ name, fdt_strerror(offset));
+ return 0;
+ }
+
+ /*fixup the property of interrupts*/
+
+ tmp[0][0] = cpu_to_fdt32(0x0);
+ tmp[0][1] = cpu_to_fdt32(irq_0);
+ tmp[0][2] = cpu_to_fdt32(0x4);
+
+ if (rev > REV1_0) {
+ tmp[1][0] = cpu_to_fdt32(0x0);
+ tmp[1][1] = cpu_to_fdt32(irq_1);
+ tmp[1][2] = cpu_to_fdt32(0x4);
+ tmp[2][0] = cpu_to_fdt32(0x0);
+ tmp[2][1] = cpu_to_fdt32(irq_1 + 1);
+ tmp[2][2] = cpu_to_fdt32(0x4);
+ tmp[3][0] = cpu_to_fdt32(0x0);
+ tmp[3][1] = cpu_to_fdt32(irq_1 + 2);
+ tmp[3][2] = cpu_to_fdt32(0x4);
+ len = sizeof(tmp);
+ } else {
+ len = sizeof(tmp[0]);
+ }
+
+ err = fdt_setprop(blob, offset, "interrupts", tmp, len);
+ if (err < 0) {
+ printf("WARNING: fdt_setprop can't set %s from node %s: %s\n",
+ "interrupts", name, fdt_strerror(err));
+ return 0;
+ }
+
+ /*fixup the property of reg*/
+ p = (char *)fdt_getprop(blob, offset, "reg", &len);
+ if (!p) {
+ printf("WARNING: fdt_getprop can't get %s from node %s\n",
+ "reg", name);
+ return 0;
+ }
+
+ memcpy((char *)tmp, p, len);
+
+ if (rev > REV1_0)
+ *((u32 *)tmp + 3) = cpu_to_fdt32(0x1000);
+ else
+ *((u32 *)tmp + 3) = cpu_to_fdt32(0x8);
+
+ err = fdt_setprop(blob, offset, "reg", tmp, len);
+ if (err < 0) {
+ printf("WARNING: fdt_setprop can't set %s from node %s: %s\n",
+ "reg", name, fdt_strerror(err));
+ return 0;
+ }
+
+ /*fixup the property of compatible*/
+ if (rev > REV1_0)
+ err = fdt_setprop_string(blob, offset, "compatible",
+ "fsl,ls1043a-v1.1-msi");
+ else
+ err = fdt_setprop_string(blob, offset, "compatible",
+ "fsl,ls1043a-msi");
+ if (err < 0) {
+ printf("WARNING: fdt_setprop can't set %s from node %s: %s\n",
+ "compatible", name, fdt_strerror(err));
+ return 0;
+ }
+
+ return 1;
+}
+
+static int _fdt_fixup_pci_msi(void *blob, const char *name, int rev)
+{
+ int offset, len, err;
+ void *p;
+ int val;
+ u32 tmp[4][8];
+
+ offset = fdt_path_offset(blob, name);
+ if (offset < 0) {
+ printf("WARNING: fdt_path_offset can't find path %s: %s\n",
+ name, fdt_strerror(offset));
+ return 0;
+ }
+
+ p = (char *)fdt_getprop(blob, offset, "interrupt-map", &len);
+ if (!p || len != sizeof(tmp)) {
+ printf("WARNING: fdt_getprop can't get %s from node %s\n",
+ "interrupt-map", name);
+ return 0;
+ }
+
+ memcpy((char *)tmp, p, len);
+
+ val = fdt32_to_cpu(tmp[0][6]);
+ if (rev == REV1_0) {
+ tmp[1][6] = cpu_to_fdt32(val + 1);
+ tmp[2][6] = cpu_to_fdt32(val + 2);
+ tmp[3][6] = cpu_to_fdt32(val + 3);
+ } else {
+ tmp[1][6] = cpu_to_fdt32(val);
+ tmp[2][6] = cpu_to_fdt32(val);
+ tmp[3][6] = cpu_to_fdt32(val);
+ }
+
+ err = fdt_setprop(blob, offset, "interrupt-map", tmp, sizeof(tmp));
+ if (err < 0) {
+ printf("WARNING: fdt_setprop can't set %s from node %s: %s.\n",
+ "interrupt-map", name, fdt_strerror(err));
+ return 0;
+ }
+ return 1;
+}
+
+/* Fixup msi node for ls1043a rev1.1*/
+
+static void fdt_fixup_msi(void *blob)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ unsigned int rev;
+
+ rev = gur_in32(&gur->svr);
+
+ if (!IS_SVR_DEV(rev, SVR_DEV(SVR_LS1043A)))
+ return;
+
+ rev = SVR_REV(rev);
+
+ _fdt_fixup_msi_node(blob, "/soc/msi-controller1@1571000",
+ 116, 111, rev);
+ _fdt_fixup_msi_node(blob, "/soc/msi-controller2@1572000",
+ 126, 121, rev);
+ _fdt_fixup_msi_node(blob, "/soc/msi-controller3@1573000",
+ 160, 155, rev);
+
+ _fdt_fixup_pci_msi(blob, "/soc/pcie@3400000", rev);
+ _fdt_fixup_pci_msi(blob, "/soc/pcie@3500000", rev);
+ _fdt_fixup_pci_msi(blob, "/soc/pcie@3600000", rev);
+}
+#endif
+
+#if CONFIG_IS_ENABLED(ARMV8_SEC_FIRMWARE_SUPPORT)
+/* Remove JR node used by SEC firmware */
+void fdt_fixup_remove_jr(void *blob)
+{
+ int jr_node, addr_cells, len;
+ int crypto_node = fdt_path_offset(blob, "crypto");
+ u64 jr_offset, used_jr;
+ fdt32_t *reg;
+
+ used_jr = sec_firmware_used_jobring_offset();
+ fdt_support_default_count_cells(blob, crypto_node, &addr_cells, NULL);
+
+ jr_node = fdt_node_offset_by_compatible(blob, crypto_node,
+ "fsl,sec-v4.0-job-ring");
+
+ while (jr_node != -FDT_ERR_NOTFOUND) {
+ reg = (fdt32_t *)fdt_getprop(blob, jr_node, "reg", &len);
+ if (reg) {
+ jr_offset = fdt_read_number(reg, addr_cells);
+ if (jr_offset == used_jr) {
+ fdt_del_node(blob, jr_node);
+ break;
+ }
+ }
+ jr_node = fdt_node_offset_by_compatible(blob, jr_node,
+ "fsl,sec-v4.0-job-ring");
+ }
+}
+#endif
+
+#ifdef CONFIG_ARCH_LS1028A
+static void fdt_disable_multimedia(void *blob, unsigned int svr)
+{
+ int off;
+
+ if (IS_MULTIMEDIA_EN(svr))
+ return;
+
+ /* Disable eDP/LCD node */
+ off = fdt_node_offset_by_compatible(blob, -1, "arm,mali-dp500");
+ if (off != -FDT_ERR_NOTFOUND)
+ fdt_status_disabled(blob, off);
+
+ /* Disable GPU node */
+ off = fdt_node_offset_by_compatible(blob, -1, "fsl,ls1028a-gpu");
+ if (off != -FDT_ERR_NOTFOUND)
+ fdt_status_disabled(blob, off);
+}
+#endif
+
+#ifdef CONFIG_PCIE_ECAM_GENERIC
+__weak void fdt_fixup_ecam(void *blob)
+{
+}
+#endif
+
+/*
+ * If it is a non-E part the crypto is disabled on the following SoCs:
+ * - LS1043A
+ * - LS1088A
+ * - LS2080A
+ * - LS2088A
+ * and their personalities.
+ *
+ * On all other SoCs just the export-controlled ciphers are disabled, that
+ * means that the following is still working:
+ * - hashing (using MDHA - message digest hash accelerator)
+ * - random number generation (using RNG4)
+ * - cyclic redundancy checking (using CRCA)
+ * - runtime integrity checker (RTIC)
+ *
+ * The linux driver will figure out what is available and what is not.
+ * Therefore, we just remove the crypto node on the SoCs which have no crypto
+ * support at all.
+ */
+static bool crypto_is_disabled(unsigned int svr)
+{
+ if (IS_E_PROCESSOR(svr))
+ return false;
+
+ if (IS_SVR_DEV(svr, SVR_DEV(SVR_LS1043A)))
+ return true;
+
+ if (IS_SVR_DEV(svr, SVR_DEV(SVR_LS1088A)))
+ return true;
+
+ if (IS_SVR_DEV(svr, SVR_DEV(SVR_LS2080A)))
+ return true;
+
+ if (IS_SVR_DEV(svr, SVR_DEV(SVR_LS2088A)))
+ return true;
+
+ return false;
+}
+
+#ifdef CONFIG_FSL_PFE
+void pfe_set_firmware_in_fdt(void *blob, int pfenode, void *pfw, char *pename,
+ unsigned int len)
+{
+ int rc, fwnode;
+ unsigned int phandle;
+ char subnode_str[32], prop_str[32], phandle_str[32], s[64];
+
+ sprintf(subnode_str, "pfe-%s-firmware", pename);
+ sprintf(prop_str, "fsl,pfe-%s-firmware", pename);
+ sprintf(phandle_str, "fsl,%s-firmware", pename);
+
+ /*Add PE FW to fdt.*/
+ /* Increase the size of the fdt to make room for the node. */
+ rc = fdt_increase_size(blob, len);
+ if (rc < 0) {
+ printf("Unable to make room for %s firmware: %s\n", pename,
+ fdt_strerror(rc));
+ return;
+ }
+
+ /* Create the firmware node. */
+ fwnode = fdt_add_subnode(blob, pfenode, subnode_str);
+ if (fwnode < 0) {
+ fdt_get_path(blob, pfenode, s, sizeof(s));
+ printf("Could not add firmware node to %s: %s\n", s,
+ fdt_strerror(fwnode));
+ return;
+ }
+
+ rc = fdt_setprop_string(blob, fwnode, "compatible", prop_str);
+ if (rc < 0) {
+ fdt_get_path(blob, fwnode, s, sizeof(s));
+ printf("Could not add compatible property to node %s: %s\n", s,
+ fdt_strerror(rc));
+ return;
+ }
+
+ rc = fdt_setprop_u32(blob, fwnode, "length", len);
+ if (rc < 0) {
+ fdt_get_path(blob, fwnode, s, sizeof(s));
+ printf("Could not add compatible property to node %s: %s\n", s,
+ fdt_strerror(rc));
+ return;
+ }
+
+ /*create phandle and set the property*/
+ phandle = fdt_create_phandle(blob, fwnode);
+ if (!phandle) {
+ fdt_get_path(blob, fwnode, s, sizeof(s));
+ printf("Could not add phandle property to node %s: %s\n", s,
+ fdt_strerror(rc));
+ return;
+ }
+
+ rc = fdt_setprop(blob, fwnode, phandle_str, pfw, len);
+ if (rc < 0) {
+ fdt_get_path(blob, fwnode, s, sizeof(s));
+ printf("Could not add firmware property to node %s: %s\n", s,
+ fdt_strerror(rc));
+ return;
+ }
+}
+
+void fdt_fixup_pfe_firmware(void *blob)
+{
+ int pfenode;
+ unsigned int len_class = 0, len_tmu = 0, len_util = 0;
+ const char *p;
+ void *pclassfw, *ptmufw, *putilfw;
+
+ /* The first PFE we find, will contain the actual firmware. */
+ pfenode = fdt_node_offset_by_compatible(blob, -1, "fsl,pfe");
+ if (pfenode < 0)
+ /* Exit silently if there are no PFE devices */
+ return;
+
+ /* If we already have a firmware node, then also exit silently. */
+ if (fdt_node_offset_by_compatible(blob, -1,
+ "fsl,pfe-class-firmware") > 0)
+ return;
+
+ /* If the environment variable is not set, then exit silently */
+ p = env_get("class_elf_firmware");
+ if (!p)
+ return;
+
+ pclassfw = (void *)simple_strtoul(p, NULL, 16);
+ if (!pclassfw)
+ return;
+
+ p = env_get("class_elf_size");
+ if (!p)
+ return;
+ len_class = simple_strtoul(p, NULL, 16);
+
+ /* If the environment variable is not set, then exit silently */
+ p = env_get("tmu_elf_firmware");
+ if (!p)
+ return;
+
+ ptmufw = (void *)simple_strtoul(p, NULL, 16);
+ if (!ptmufw)
+ return;
+
+ p = env_get("tmu_elf_size");
+ if (!p)
+ return;
+ len_tmu = simple_strtoul(p, NULL, 16);
+
+ if (len_class == 0 || len_tmu == 0) {
+ printf("PFE FW corrupted. CLASS FW size %d, TMU FW size %d\n",
+ len_class, len_tmu);
+ return;
+ }
+
+ /*Add CLASS FW to fdt.*/
+ pfe_set_firmware_in_fdt(blob, pfenode, pclassfw, "class", len_class);
+
+ /*Add TMU FW to fdt.*/
+ pfe_set_firmware_in_fdt(blob, pfenode, ptmufw, "tmu", len_tmu);
+
+ /* Util PE firmware is handled separately as it is not a usual case*/
+ p = env_get("util_elf_firmware");
+ if (!p)
+ return;
+
+ putilfw = (void *)simple_strtoul(p, NULL, 16);
+ if (!putilfw)
+ return;
+
+ p = env_get("util_elf_size");
+ if (!p)
+ return;
+ len_util = simple_strtoul(p, NULL, 16);
+
+ if (len_util) {
+ printf("PFE Util PE firmware is not added to FDT.\n");
+ return;
+ }
+
+ pfe_set_firmware_in_fdt(blob, pfenode, putilfw, "util", len_util);
+}
+#endif
+
+void ft_cpu_setup(void *blob, struct bd_info *bd)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ unsigned int svr = gur_in32(&gur->svr);
+
+ /* delete crypto node if not on an E-processor */
+ if (crypto_is_disabled(svr))
+ fdt_fixup_crypto_node(blob, 0);
+#if CONFIG_SYS_FSL_SEC_COMPAT >= 4
+ else {
+ ccsr_sec_t __iomem *sec;
+
+#if CONFIG_IS_ENABLED(ARMV8_SEC_FIRMWARE_SUPPORT)
+ fdt_fixup_remove_jr(blob);
+ fdt_fixup_kaslr(blob);
+#endif
+
+ sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR;
+ fdt_fixup_crypto_node(blob, sec_in32(&sec->secvid_ms));
+ }
+#endif
+
+#ifdef CONFIG_MP
+ ft_fixup_cpu(blob);
+#endif
+
+#ifdef CONFIG_SYS_NS16550
+ do_fixup_by_compat_u32(blob, "fsl,ns16550",
+ "clock-frequency", CONFIG_SYS_NS16550_CLK, 1);
+#endif
+
+ do_fixup_by_path_u32(blob, "/sysclk", "clock-frequency",
+ CONFIG_SYS_CLK_FREQ, 1);
+
+#ifdef CONFIG_GIC_V3_ITS
+ ls_gic_rd_tables_init(blob);
+#endif
+
+#if defined(CONFIG_PCIE_LAYERSCAPE) || defined(CONFIG_PCIE_LAYERSCAPE_GEN4)
+ ft_pci_setup(blob, bd);
+#endif
+
+#ifdef CONFIG_FSL_ESDHC
+ fdt_fixup_esdhc(blob, bd);
+#endif
+
+#ifdef CONFIG_SYS_DPAA_QBMAN
+ fdt_fixup_bportals(blob);
+ fdt_fixup_qportals(blob);
+ do_fixup_by_compat_u32(blob, "fsl,qman",
+ "clock-frequency", get_qman_freq(), 1);
+#endif
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+ fdt_fixup_fman_firmware(blob);
+#endif
+#ifdef CONFIG_FSL_PFE
+ fdt_fixup_pfe_firmware(blob);
+#endif
+#ifndef CONFIG_ARCH_LS1012A
+ fsl_fdt_disable_usb(blob);
+#endif
+#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
+ fdt_fixup_gic(blob);
+#endif
+#ifdef CONFIG_HAS_FEATURE_ENHANCED_MSI
+ fdt_fixup_msi(blob);
+#endif
+#ifdef CONFIG_ARCH_LS1028A
+ fdt_disable_multimedia(blob, svr);
+#endif
+#ifdef CONFIG_PCIE_ECAM_GENERIC
+ fdt_fixup_ecam(blob);
+#endif
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c
new file mode 100644
index 000000000..41c89b890
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c
@@ -0,0 +1,421 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <log.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/soc.h>
+
+#ifdef CONFIG_SYS_FSL_SRDS_1
+static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
+#endif
+
+int is_serdes_configured(enum srds_prtcl device)
+{
+ int ret = 0;
+
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ if (!serdes1_prtcl_map[NONE])
+ fsl_serdes_init();
+
+ ret |= serdes1_prtcl_map[device];
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ if (!serdes2_prtcl_map[NONE])
+ fsl_serdes_init();
+
+ ret |= serdes2_prtcl_map[device];
+#endif
+
+ return !!ret;
+}
+
+int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 cfg = gur_in32(&gur->rcwsr[4]);
+ int i;
+
+ switch (sd) {
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ case FSL_SRDS_1:
+ cfg &= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
+ break;
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ case FSL_SRDS_2:
+ cfg &= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
+ break;
+#endif
+ default:
+ printf("invalid SerDes%d\n", sd);
+ break;
+ }
+
+ /* Is serdes enabled at all? */
+ if (unlikely(cfg == 0))
+ return -ENODEV;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (serdes_get_prtcl(sd, cfg, i) == device)
+ return i;
+ }
+
+ return -ENODEV;
+}
+
+int get_serdes_protocol(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 cfg = gur_in32(&gur->rcwsr[4]) &
+ FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
+
+ return cfg;
+}
+
+const char *serdes_clock_to_string(u32 clock)
+{
+ switch (clock) {
+ case SRDS_PLLCR0_RFCK_SEL_100:
+ return "100";
+ case SRDS_PLLCR0_RFCK_SEL_125:
+ return "125";
+ case SRDS_PLLCR0_RFCK_SEL_156_25:
+ return "156.25";
+ default:
+ return "100";
+ }
+}
+
+void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
+ u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 cfg;
+ int lane;
+
+ if (serdes_prtcl_map[NONE])
+ return;
+
+ memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
+
+ cfg = gur_in32(&gur->rcwsr[4]) & sd_prctl_mask;
+ cfg >>= sd_prctl_shift;
+ printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
+
+ if (!is_serdes_prtcl_valid(sd, cfg))
+ printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
+
+ for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
+ enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
+
+ if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
+ debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
+ else
+ serdes_prtcl_map[lane_prtcl] = 1;
+ }
+
+ /* Set the first element to indicate serdes has been initialized */
+ serdes_prtcl_map[NONE] = 1;
+}
+
+__weak int get_serdes_volt(void)
+{
+ return -1;
+}
+
+__weak int set_serdes_volt(int svdd)
+{
+ return -1;
+}
+
+int setup_serdes_volt(u32 svdd)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ struct ccsr_serdes *serdes1_base;
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ struct ccsr_serdes *serdes2_base;
+#endif
+ u32 cfg_rcw4 = gur_in32(&gur->rcwsr[4]);
+ u32 cfg_rcw5 = gur_in32(&gur->rcwsr[5]);
+ u32 cfg_tmp, reg = 0;
+ int svdd_cur, svdd_tar;
+ int ret;
+ int i;
+
+ /* Only support switch SVDD to 900mV/1000mV */
+ if (svdd != 900 && svdd != 1000)
+ return -EINVAL;
+
+ svdd_tar = svdd;
+ svdd_cur = get_serdes_volt();
+ if (svdd_cur < 0)
+ return -EINVAL;
+
+ debug("%s: current SVDD: %dmV; target SVDD: %dmV\n",
+ __func__, svdd_cur, svdd_tar);
+ if (svdd_cur == svdd_tar)
+ return 0;
+
+ serdes1_base = (void *)CONFIG_SYS_FSL_SERDES_ADDR;
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ serdes2_base = (void *)serdes1_base + 0x10000;
+#endif
+
+ /* Put the all enabled lanes in reset */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
+ cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
+
+ for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
+ reg = in_be32(&serdes1_base->lane[i].gcr0);
+ reg &= 0xFF9FFFFF;
+ out_be32(&serdes1_base->lane[i].gcr0, reg);
+ }
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
+ cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
+
+ for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
+ reg = in_be32(&serdes2_base->lane[i].gcr0);
+ reg &= 0xFF9FFFFF;
+ out_be32(&serdes2_base->lane[i].gcr0, reg);
+ }
+#endif
+
+ /* Put the all enabled PLL in reset */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
+ for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
+ reg = in_be32(&serdes1_base->bank[i].rstctl);
+ reg &= 0xFFFFFFBF;
+ reg |= 0x10000000;
+ out_be32(&serdes1_base->bank[i].rstctl, reg);
+ udelay(1);
+
+ reg = in_be32(&serdes1_base->bank[i].rstctl);
+ reg &= 0xFFFFFF1F;
+ out_be32(&serdes1_base->bank[i].rstctl, reg);
+ }
+ udelay(1);
+#endif
+
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
+ for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
+ reg = in_be32(&serdes2_base->bank[i].rstctl);
+ reg &= 0xFFFFFFBF;
+ reg |= 0x10000000;
+ out_be32(&serdes2_base->bank[i].rstctl, reg);
+ udelay(1);
+
+ reg = in_be32(&serdes2_base->bank[i].rstctl);
+ reg &= 0xFFFFFF1F;
+ out_be32(&serdes2_base->bank[i].rstctl, reg);
+ }
+ udelay(1);
+#endif
+
+ /* Put the Rx/Tx calibration into reset */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ reg = in_be32(&serdes1_base->srdstcalcr);
+ reg &= 0xF7FFFFFF;
+ out_be32(&serdes1_base->srdstcalcr, reg);
+ reg = in_be32(&serdes1_base->srdsrcalcr);
+ reg &= 0xF7FFFFFF;
+ out_be32(&serdes1_base->srdsrcalcr, reg);
+
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ reg = in_be32(&serdes2_base->srdstcalcr);
+ reg &= 0xF7FFFFFF;
+ out_be32(&serdes2_base->srdstcalcr, reg);
+ reg = in_be32(&serdes2_base->srdsrcalcr);
+ reg &= 0xF7FFFFFF;
+ out_be32(&serdes2_base->srdsrcalcr, reg);
+#endif
+
+ /*
+ * If SVDD set failed, will not return directly, so that the
+ * serdes lanes can complete reseting.
+ */
+ ret = set_serdes_volt(svdd_tar);
+ if (ret)
+ printf("%s: Failed to set SVDD\n", __func__);
+
+ /* Wait for SVDD to stabilize */
+ udelay(100);
+
+ /* For each PLL that’s not disabled via RCW */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
+ for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
+ reg = in_be32(&serdes1_base->bank[i].rstctl);
+ reg |= 0x00000020;
+ out_be32(&serdes1_base->bank[i].rstctl, reg);
+ udelay(1);
+
+ reg = in_be32(&serdes1_base->bank[i].rstctl);
+ reg |= 0x00000080;
+ out_be32(&serdes1_base->bank[i].rstctl, reg);
+
+ /* Take the Rx/Tx calibration out of reset */
+ if (!(cfg_tmp == 0x3 && i == 1)) {
+ udelay(1);
+ reg = in_be32(&serdes1_base->srdstcalcr);
+ reg |= 0x08000000;
+ out_be32(&serdes1_base->srdstcalcr, reg);
+ reg = in_be32(&serdes1_base->srdsrcalcr);
+ reg |= 0x08000000;
+ out_be32(&serdes1_base->srdsrcalcr, reg);
+ }
+ }
+ udelay(1);
+#endif
+
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
+ for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
+ reg = in_be32(&serdes2_base->bank[i].rstctl);
+ reg |= 0x00000020;
+ out_be32(&serdes2_base->bank[i].rstctl, reg);
+ udelay(1);
+
+ reg = in_be32(&serdes2_base->bank[i].rstctl);
+ reg |= 0x00000080;
+ out_be32(&serdes2_base->bank[i].rstctl, reg);
+
+ /* Take the Rx/Tx calibration out of reset */
+ if (!(cfg_tmp == 0x3 && i == 1)) {
+ udelay(1);
+ reg = in_be32(&serdes2_base->srdstcalcr);
+ reg |= 0x08000000;
+ out_be32(&serdes2_base->srdstcalcr, reg);
+ reg = in_be32(&serdes2_base->srdsrcalcr);
+ reg |= 0x08000000;
+ out_be32(&serdes2_base->srdsrcalcr, reg);
+ }
+ }
+ udelay(1);
+
+#endif
+
+ /* Wait for at lesat 625us to ensure the PLLs being reset are locked */
+ udelay(800);
+
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
+ for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
+ /* if the PLL is not locked, set RST_ERR */
+ reg = in_be32(&serdes1_base->bank[i].pllcr0);
+ if (!((reg >> 23) & 0x1)) {
+ reg = in_be32(&serdes1_base->bank[i].rstctl);
+ reg |= 0x20000000;
+ out_be32(&serdes1_base->bank[i].rstctl, reg);
+ } else {
+ udelay(1);
+ reg = in_be32(&serdes1_base->bank[i].rstctl);
+ reg &= 0xFFFFFFEF;
+ reg |= 0x00000040;
+ out_be32(&serdes1_base->bank[i].rstctl, reg);
+ udelay(1);
+ }
+ }
+#endif
+
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
+ for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
+ reg = in_be32(&serdes2_base->bank[i].pllcr0);
+ if (!((reg >> 23) & 0x1)) {
+ reg = in_be32(&serdes2_base->bank[i].rstctl);
+ reg |= 0x20000000;
+ out_be32(&serdes2_base->bank[i].rstctl, reg);
+ } else {
+ udelay(1);
+ reg = in_be32(&serdes2_base->bank[i].rstctl);
+ reg &= 0xFFFFFFEF;
+ reg |= 0x00000040;
+ out_be32(&serdes2_base->bank[i].rstctl, reg);
+ udelay(1);
+ }
+ }
+#endif
+
+ /* Take the all enabled lanes out of reset */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
+ cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
+
+ for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
+ reg = in_be32(&serdes1_base->lane[i].gcr0);
+ reg |= 0x00600000;
+ out_be32(&serdes1_base->lane[i].gcr0, reg);
+ }
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
+ cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
+
+ for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
+ reg = in_be32(&serdes2_base->lane[i].gcr0);
+ reg |= 0x00600000;
+ out_be32(&serdes2_base->lane[i].gcr0, reg);
+ }
+#endif
+ /* For each PLL being reset, and achieved PLL lock set RST_DONE */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
+ for (i = 0; i < 2; i++) {
+ reg = in_be32(&serdes1_base->bank[i].pllcr0);
+ if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
+ reg = in_be32(&serdes1_base->bank[i].rstctl);
+ reg |= 0x40000000;
+ out_be32(&serdes1_base->bank[i].rstctl, reg);
+ }
+ }
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
+ for (i = 0; i < 2; i++) {
+ reg = in_be32(&serdes2_base->bank[i].pllcr0);
+ if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
+ reg = in_be32(&serdes2_base->bank[i].rstctl);
+ reg |= 0x40000000;
+ out_be32(&serdes2_base->bank[i].rstctl, reg);
+ }
+ }
+#endif
+
+ return ret;
+}
+
+void fsl_serdes_init(void)
+{
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ serdes_init(FSL_SRDS_1,
+ CONFIG_SYS_FSL_SERDES_ADDR,
+ FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK,
+ FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT,
+ serdes1_prtcl_map);
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ serdes_init(FSL_SRDS_2,
+ CONFIG_SYS_FSL_SERDES_ADDR,
+ FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK,
+ FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT,
+ serdes2_prtcl_map);
+#endif
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c
new file mode 100644
index 000000000..63d34e1ec
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c
@@ -0,0 +1,261 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ * Copyright 2019 NXP.
+ */
+
+#include <common.h>
+#include <clock_legacy.h>
+#include <cpu_func.h>
+#include <asm/global_data.h>
+#include <linux/compiler.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/soc.h>
+#include <fsl_ifc.h>
+#include "cpu.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
+#define CONFIG_SYS_FSL_NUM_CC_PLLS 2
+#endif
+
+void get_sys_info(struct sys_info *sys_info)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+/* rcw_tmp is needed to get FMAN clock, or to get cluster group A
+ * mux 2 clock for LS1043A/LS1046A.
+ */
+#if defined(CONFIG_SYS_DPAA_FMAN) || \
+ defined(CONFIG_TARGET_LS1046ARDB) || \
+ defined(CONFIG_TARGET_LS1043ARDB)
+ u32 rcw_tmp;
+#endif
+ struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_CLK_ADDR);
+ unsigned int cpu;
+ const u8 core_cplx_pll[8] = {
+ [0] = 0, /* CC1 PPL / 1 */
+ [1] = 0, /* CC1 PPL / 2 */
+ [4] = 1, /* CC2 PPL / 1 */
+ [5] = 1, /* CC2 PPL / 2 */
+ };
+
+ const u8 core_cplx_pll_div[8] = {
+ [0] = 1, /* CC1 PPL / 1 */
+ [1] = 2, /* CC1 PPL / 2 */
+ [4] = 1, /* CC2 PPL / 1 */
+ [5] = 2, /* CC2 PPL / 2 */
+ };
+
+ uint i, cluster;
+ uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
+ uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
+ unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
+ unsigned long cluster_clk;
+
+ sys_info->freq_systembus = sysclk;
+#ifndef CONFIG_CLUSTER_CLK_FREQ
+#define CONFIG_CLUSTER_CLK_FREQ CONFIG_SYS_CLK_FREQ
+#endif
+ cluster_clk = CONFIG_CLUSTER_CLK_FREQ;
+
+#ifdef CONFIG_DDR_CLK_FREQ
+ sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
+#else
+ sys_info->freq_ddrbus = sysclk;
+#endif
+
+ /* The freq_systembus is used to record frequency of platform PLL */
+ sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >>
+ FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_SHIFT) &
+ FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK;
+
+#ifdef CONFIG_ARCH_LS1012A
+ sys_info->freq_ddrbus = 2 * sys_info->freq_systembus;
+#else
+ sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >>
+ FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_SHIFT) &
+ FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK;
+#endif
+
+ for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
+ ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0xff;
+ if (ratio[i] > 4)
+ freq_c_pll[i] = cluster_clk * ratio[i];
+ else
+ freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
+ }
+
+ for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
+ cluster = fsl_qoriq_core_to_cluster(cpu);
+ u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27)
+ & 0xf;
+ u32 cplx_pll = core_cplx_pll[c_pll_sel];
+
+ sys_info->freq_processor[cpu] =
+ freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
+ }
+
+#define HWA_CGA_M1_CLK_SEL 0xe0000000
+#define HWA_CGA_M1_CLK_SHIFT 29
+#ifdef CONFIG_SYS_DPAA_FMAN
+ rcw_tmp = in_be32(&gur->rcwsr[7]);
+ switch ((rcw_tmp & HWA_CGA_M1_CLK_SEL) >> HWA_CGA_M1_CLK_SHIFT) {
+ case 2:
+ sys_info->freq_fman[0] = freq_c_pll[0] / 2;
+ break;
+ case 3:
+ sys_info->freq_fman[0] = freq_c_pll[0] / 3;
+ break;
+ case 4:
+ sys_info->freq_fman[0] = freq_c_pll[0] / 4;
+ break;
+ case 5:
+ sys_info->freq_fman[0] = sys_info->freq_systembus;
+ break;
+ case 6:
+ sys_info->freq_fman[0] = freq_c_pll[1] / 2;
+ break;
+ case 7:
+ sys_info->freq_fman[0] = freq_c_pll[1] / 3;
+ break;
+ default:
+ printf("Error: Unknown FMan1 clock select!\n");
+ break;
+ }
+#endif
+
+#define HWA_CGA_M2_CLK_SEL 0x00000007
+#define HWA_CGA_M2_CLK_SHIFT 0
+#if defined(CONFIG_TARGET_LS1046ARDB) || defined(CONFIG_TARGET_LS1043ARDB)
+ rcw_tmp = in_be32(&gur->rcwsr[15]);
+ switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) {
+ case 1:
+ sys_info->freq_cga_m2 = freq_c_pll[1];
+ break;
+#if defined(CONFIG_TARGET_LS1046ARDB)
+ case 2:
+ sys_info->freq_cga_m2 = freq_c_pll[1] / 2;
+ break;
+#endif
+ case 3:
+ sys_info->freq_cga_m2 = freq_c_pll[1] / 3;
+ break;
+#if defined(CONFIG_TARGET_LS1046ARDB)
+ case 6:
+ sys_info->freq_cga_m2 = freq_c_pll[0] / 2;
+ break;
+#endif
+ default:
+ printf("Error: Unknown cluster group A mux 2 clock select!\n");
+ break;
+ }
+#endif
+
+#if defined(CONFIG_FSL_IFC)
+ sys_info->freq_localbus = sys_info->freq_systembus /
+ CONFIG_SYS_FSL_IFC_CLK_DIV;
+#endif
+#ifdef CONFIG_SYS_DPAA_QBMAN
+ sys_info->freq_qman = (sys_info->freq_systembus /
+ CONFIG_SYS_FSL_PCLK_DIV) /
+ CONFIG_SYS_FSL_QMAN_CLK_DIV;
+#endif
+}
+
+#ifdef CONFIG_SYS_DPAA_QBMAN
+unsigned long get_qman_freq(void)
+{
+ struct sys_info sys_info;
+
+ get_sys_info(&sys_info);
+
+ return sys_info.freq_qman;
+}
+#endif
+
+int get_clocks(void)
+{
+ struct sys_info sys_info;
+#ifdef CONFIG_FSL_ESDHC
+ u32 clock = 0;
+#endif
+ get_sys_info(&sys_info);
+ gd->cpu_clk = sys_info.freq_processor[0];
+ gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV;
+ gd->mem_clk = sys_info.freq_ddrbus;
+#ifdef CONFIG_FSL_ESDHC
+#if defined(CONFIG_ARCH_LS1012A)
+ clock = sys_info.freq_systembus;
+#elif defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
+ clock = sys_info.freq_cga_m2;
+#endif
+ gd->arch.sdhc_per_clk = clock / CONFIG_SYS_FSL_SDHC_CLK_DIV;
+ gd->arch.sdhc_clk = gd->bus_clk / CONFIG_SYS_FSL_SDHC_CLK_DIV;
+#endif
+ if (gd->cpu_clk != 0)
+ return 0;
+ else
+ return 1;
+}
+
+/********************************************
+ * get_bus_freq
+ * return platform clock in Hz
+ *********************************************/
+ulong get_bus_freq(ulong dummy)
+{
+ if (!gd->bus_clk)
+ get_clocks();
+
+ return gd->bus_clk;
+}
+
+ulong get_ddr_freq(ulong dummy)
+{
+ if (!gd->mem_clk)
+ get_clocks();
+
+ return gd->mem_clk;
+}
+
+int get_serial_clock(void)
+{
+ return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV;
+}
+
+int get_i2c_freq(ulong dummy)
+{
+ return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV;
+}
+
+int get_dspi_freq(ulong dummy)
+{
+ return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV;
+}
+
+#ifdef CONFIG_FSL_LPUART
+int get_uart_freq(ulong dummy)
+{
+ return get_bus_freq(0) / CONFIG_SYS_FSL_LPUART_CLK_DIV;
+}
+#endif
+
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+ switch (clk) {
+ case MXC_I2C_CLK:
+ return get_i2c_freq(0);
+ case MXC_DSPI_CLK:
+ return get_dspi_freq(0);
+#ifdef CONFIG_FSL_LPUART
+ case MXC_UART_CLK:
+ return get_uart_freq(0);
+#endif
+ default:
+ printf("Unsupported clock\n");
+ }
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
new file mode 100644
index 000000000..fad7a9356
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
@@ -0,0 +1,665 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2016-2018, 2020 NXP
+ * Copyright 2014-2015 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <env.h>
+#include <log.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/soc.h>
+#include <fsl-mc/ldpaa_wriop.h>
+
+#ifdef CONFIG_SYS_FSL_SRDS_1
+static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
+#endif
+#ifdef CONFIG_SYS_NXP_SRDS_3
+static u8 serdes3_prtcl_map[SERDES_PRCTL_COUNT];
+#endif
+
+#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
+#if defined(CONFIG_ARCH_LX2160A) || defined(CONFIG_ARCH_LX2162A)
+int xfi_dpmac[XFI14 + 1];
+int sgmii_dpmac[SGMII18 + 1];
+int a25gaui_dpmac[_25GE10 + 1];
+int xlaui_dpmac[_40GE2 + 1];
+int caui2_dpmac[_50GE2 + 1];
+int caui4_dpmac[_100GE2 + 1];
+#else
+int xfi_dpmac[XFI8 + 1];
+int sgmii_dpmac[SGMII16 + 1];
+#endif
+#endif
+
+__weak void wriop_init_dpmac_qsgmii(int sd, int lane_prtcl)
+{
+ return;
+}
+
+/*
+ *The return value of this func is the serdes protocol used.
+ *Typically this function is called number of times depending
+ *upon the number of serdes blocks in the Silicon.
+ *Zero is used to denote that no serdes was enabled,
+ *this is the case when golden RCW was used where DPAA2 bring was
+ *intentionally removed to achieve boot to prompt
+*/
+
+__weak int serdes_get_number(int serdes, int cfg)
+{
+ return cfg;
+}
+
+int is_serdes_configured(enum srds_prtcl device)
+{
+ int ret = 0;
+
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ if (!serdes1_prtcl_map[NONE])
+ fsl_serdes_init();
+
+ ret |= serdes1_prtcl_map[device];
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ if (!serdes2_prtcl_map[NONE])
+ fsl_serdes_init();
+
+ ret |= serdes2_prtcl_map[device];
+#endif
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ if (!serdes3_prtcl_map[NONE])
+ fsl_serdes_init();
+
+ ret |= serdes3_prtcl_map[device];
+#endif
+
+ return !!ret;
+}
+
+int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 cfg = 0;
+ int i;
+
+ switch (sd) {
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ case FSL_SRDS_1:
+ cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]);
+ cfg &= FSL_CHASSIS3_SRDS1_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
+ break;
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ case FSL_SRDS_2:
+ cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS2_REGSR - 1]);
+ cfg &= FSL_CHASSIS3_SRDS2_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_SRDS2_PRTCL_SHIFT;
+ break;
+#endif
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ case NXP_SRDS_3:
+ cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS3_REGSR - 1]);
+ cfg &= FSL_CHASSIS3_SRDS3_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_SRDS3_PRTCL_SHIFT;
+ break;
+#endif
+ default:
+ printf("invalid SerDes%d\n", sd);
+ break;
+ }
+
+ cfg = serdes_get_number(sd, cfg);
+
+ /* Is serdes enabled at all? */
+ if (cfg == 0)
+ return -ENODEV;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (serdes_get_prtcl(sd, cfg, i) == device)
+ return i;
+ }
+
+ return -ENODEV;
+}
+
+void serdes_init(u32 sd, u32 sd_addr, u32 rcwsr, u32 sd_prctl_mask,
+ u32 sd_prctl_shift, u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 cfg;
+ int lane;
+
+ if (serdes_prtcl_map[NONE])
+ return;
+
+ memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
+
+ cfg = gur_in32(&gur->rcwsr[rcwsr - 1]) & sd_prctl_mask;
+ cfg >>= sd_prctl_shift;
+
+ cfg = serdes_get_number(sd, cfg);
+ printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
+
+ if (!is_serdes_prtcl_valid(sd, cfg))
+ printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
+
+ for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
+ enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
+ if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
+ debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
+ else {
+ serdes_prtcl_map[lane_prtcl] = 1;
+#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
+#if defined(CONFIG_ARCH_LX2160A) || defined(CONFIG_ARCH_LX2162A)
+ if (lane_prtcl >= XFI1 && lane_prtcl <= XFI14)
+ wriop_init_dpmac(sd, xfi_dpmac[lane_prtcl],
+ (int)lane_prtcl);
+
+ if (lane_prtcl >= SGMII1 && lane_prtcl <= SGMII18)
+ wriop_init_dpmac(sd, sgmii_dpmac[lane_prtcl],
+ (int)lane_prtcl);
+
+ if (lane_prtcl >= _25GE1 && lane_prtcl <= _25GE10)
+ wriop_init_dpmac(sd, a25gaui_dpmac[lane_prtcl],
+ (int)lane_prtcl);
+
+ if (lane_prtcl >= _40GE1 && lane_prtcl <= _40GE2)
+ wriop_init_dpmac(sd, xlaui_dpmac[lane_prtcl],
+ (int)lane_prtcl);
+
+ if (lane_prtcl >= _50GE1 && lane_prtcl <= _50GE2)
+ wriop_init_dpmac(sd, caui2_dpmac[lane_prtcl],
+ (int)lane_prtcl);
+
+ if (lane_prtcl >= _100GE1 && lane_prtcl <= _100GE2)
+ wriop_init_dpmac(sd, caui4_dpmac[lane_prtcl],
+ (int)lane_prtcl);
+
+#else
+ switch (lane_prtcl) {
+ case QSGMII_A:
+ case QSGMII_B:
+ case QSGMII_C:
+ case QSGMII_D:
+ wriop_init_dpmac_qsgmii(sd, (int)lane_prtcl);
+ break;
+ default:
+ if (lane_prtcl >= XFI1 && lane_prtcl <= XFI8)
+ wriop_init_dpmac(sd,
+ xfi_dpmac[lane_prtcl],
+ (int)lane_prtcl);
+
+ if (lane_prtcl >= SGMII1 &&
+ lane_prtcl <= SGMII16)
+ wriop_init_dpmac(sd, sgmii_dpmac[
+ lane_prtcl],
+ (int)lane_prtcl);
+ break;
+ }
+#endif
+#endif
+ }
+ }
+
+ /* Set the first element to indicate serdes has been initialized */
+ serdes_prtcl_map[NONE] = 1;
+}
+
+__weak int get_serdes_volt(void)
+{
+ return -1;
+}
+
+__weak int set_serdes_volt(int svdd)
+{
+ return -1;
+}
+
+#define LNAGCR0_RT_RSTB 0x00600000
+
+#define RSTCTL_RESET_MASK 0x000000E0
+
+#define RSTCTL_RSTREQ 0x80000000
+#define RSTCTL_RST_DONE 0x40000000
+#define RSTCTL_RSTERR 0x20000000
+
+#define RSTCTL_SDEN 0x00000020
+#define RSTCTL_SDRST_B 0x00000040
+#define RSTCTL_PLLRST_B 0x00000080
+
+#define TCALCR_CALRST_B 0x08000000
+
+struct serdes_prctl_info {
+ u32 id;
+ u32 mask;
+ u32 shift;
+};
+
+struct serdes_prctl_info srds_prctl_info[] = {
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ {.id = 1,
+ .mask = FSL_CHASSIS3_SRDS1_PRTCL_MASK,
+ .shift = FSL_CHASSIS3_SRDS1_PRTCL_SHIFT
+ },
+
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ {.id = 2,
+ .mask = FSL_CHASSIS3_SRDS2_PRTCL_MASK,
+ .shift = FSL_CHASSIS3_SRDS2_PRTCL_SHIFT
+ },
+#endif
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ {.id = 3,
+ .mask = FSL_CHASSIS3_SRDS3_PRTCL_MASK,
+ .shift = FSL_CHASSIS3_SRDS3_PRTCL_SHIFT
+ },
+#endif
+ {} /* NULL ENTRY */
+};
+
+static int get_serdes_prctl_info_idx(u32 serdes_id)
+{
+ int pos = 0;
+ struct serdes_prctl_info *srds_info;
+
+ /* loop until NULL ENTRY defined by .id=0 */
+ for (srds_info = srds_prctl_info; srds_info->id != 0;
+ srds_info++, pos++) {
+ if (srds_info->id == serdes_id)
+ return pos;
+ }
+
+ return -1;
+}
+
+static void do_enabled_lanes_reset(u32 serdes_id, u32 cfg,
+ struct ccsr_serdes __iomem *serdes_base,
+ bool cmplt)
+{
+ int i, pos;
+ u32 cfg_tmp;
+
+ pos = get_serdes_prctl_info_idx(serdes_id);
+ if (pos == -1) {
+ printf("invalid serdes_id %d\n", serdes_id);
+ return;
+ }
+
+ cfg_tmp = cfg & srds_prctl_info[pos].mask;
+ cfg_tmp >>= srds_prctl_info[pos].shift;
+
+ for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
+ if (cmplt)
+ setbits_le32(&serdes_base->lane[i].gcr0,
+ LNAGCR0_RT_RSTB);
+ else
+ clrbits_le32(&serdes_base->lane[i].gcr0,
+ LNAGCR0_RT_RSTB);
+ }
+}
+
+static void do_pll_reset(u32 cfg,
+ struct ccsr_serdes __iomem *serdes_base)
+{
+ int i;
+
+ for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
+ clrbits_le32(&serdes_base->bank[i].rstctl,
+ RSTCTL_RESET_MASK);
+ udelay(1);
+
+ setbits_le32(&serdes_base->bank[i].rstctl,
+ RSTCTL_RSTREQ);
+ }
+ udelay(1);
+}
+
+static void do_rx_tx_cal_reset(struct ccsr_serdes __iomem *serdes_base)
+{
+ clrbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
+ clrbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
+}
+
+static void do_rx_tx_cal_reset_comp(u32 cfg, int i,
+ struct ccsr_serdes __iomem *serdes_base)
+{
+ if (!(cfg == 0x3 && i == 1)) {
+ udelay(1);
+ setbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
+ setbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
+ }
+ udelay(1);
+}
+
+static void do_pll_reset_done(u32 cfg,
+ struct ccsr_serdes __iomem *serdes_base)
+{
+ int i;
+ u32 reg = 0;
+
+ for (i = 0; i < 2; i++) {
+ reg = in_le32(&serdes_base->bank[i].pllcr0);
+ if (!(cfg & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
+ setbits_le32(&serdes_base->bank[i].rstctl,
+ RSTCTL_RST_DONE);
+ }
+ }
+}
+
+static void do_serdes_enable(u32 cfg,
+ struct ccsr_serdes __iomem *serdes_base)
+{
+ int i;
+
+ for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
+ setbits_le32(&serdes_base->bank[i].rstctl, RSTCTL_SDEN);
+ udelay(1);
+
+ setbits_le32(&serdes_base->bank[i].rstctl, RSTCTL_PLLRST_B);
+ udelay(1);
+ /* Take the Rx/Tx calibration out of reset */
+ do_rx_tx_cal_reset_comp(cfg, i, serdes_base);
+ }
+}
+
+static void do_pll_lock(u32 cfg,
+ struct ccsr_serdes __iomem *serdes_base)
+{
+ int i;
+ u32 reg = 0;
+
+ for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
+ /* if the PLL is not locked, set RST_ERR */
+ reg = in_le32(&serdes_base->bank[i].pllcr0);
+ if (!((reg >> 23) & 0x1)) {
+ setbits_le32(&serdes_base->bank[i].rstctl,
+ RSTCTL_RSTERR);
+ } else {
+ udelay(1);
+ setbits_le32(&serdes_base->bank[i].rstctl,
+ RSTCTL_SDRST_B);
+ udelay(1);
+ }
+ }
+}
+
+int setup_serdes_volt(u32 svdd)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ struct ccsr_serdes __iomem *serdes1_base =
+ (void *)CONFIG_SYS_FSL_LSCH3_SERDES_ADDR;
+ u32 cfg_rcwsrds1 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]);
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ struct ccsr_serdes __iomem *serdes2_base =
+ (void *)(CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + 0x10000);
+ u32 cfg_rcwsrds2 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS2_REGSR - 1]);
+#endif
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ struct ccsr_serdes __iomem *serdes3_base =
+ (void *)(CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + 0x20000);
+ u32 cfg_rcwsrds3 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS3_REGSR - 1]);
+#endif
+ u32 cfg_tmp;
+ int svdd_cur, svdd_tar;
+ int ret = 1;
+
+ /* Only support switch SVDD to 900mV */
+ if (svdd != 900)
+ return -EINVAL;
+
+ /* Scale up to the LTC resolution is 1/4096V */
+ svdd = (svdd * 4096) / 1000;
+
+ svdd_tar = svdd;
+ svdd_cur = get_serdes_volt();
+ if (svdd_cur < 0)
+ return -EINVAL;
+
+ debug("%s: current SVDD: %x; target SVDD: %x\n",
+ __func__, svdd_cur, svdd_tar);
+ if (svdd_cur == svdd_tar)
+ return 0;
+
+ /* Put the all enabled lanes in reset */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ do_enabled_lanes_reset(1, cfg_rcwsrds1, serdes1_base, false);
+#endif
+
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ do_enabled_lanes_reset(2, cfg_rcwsrds2, serdes2_base, false);
+#endif
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ do_enabled_lanes_reset(3, cfg_rcwsrds3, serdes3_base, false);
+#endif
+
+ /* Put the all enabled PLL in reset */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ cfg_tmp = cfg_rcwsrds1 & 0x3;
+ do_pll_reset(cfg_tmp, serdes1_base);
+#endif
+
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ cfg_tmp = cfg_rcwsrds1 & 0xC;
+ cfg_tmp >>= 2;
+ do_pll_reset(cfg_tmp, serdes2_base);
+#endif
+
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ cfg_tmp = cfg_rcwsrds3 & 0x30;
+ cfg_tmp >>= 4;
+ do_pll_reset(cfg_tmp, serdes3_base);
+#endif
+
+ /* Put the Rx/Tx calibration into reset */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ do_rx_tx_cal_reset(serdes1_base);
+#endif
+
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ do_rx_tx_cal_reset(serdes2_base);
+#endif
+
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ do_rx_tx_cal_reset(serdes3_base);
+#endif
+
+ ret = set_serdes_volt(svdd);
+ if (ret < 0) {
+ printf("could not change SVDD\n");
+ ret = -1;
+ }
+
+ /* For each PLL that’s not disabled via RCW enable the SERDES */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ cfg_tmp = cfg_rcwsrds1 & 0x3;
+ do_serdes_enable(cfg_tmp, serdes1_base);
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ cfg_tmp = cfg_rcwsrds1 & 0xC;
+ cfg_tmp >>= 2;
+ do_serdes_enable(cfg_tmp, serdes2_base);
+#endif
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ cfg_tmp = cfg_rcwsrds3 & 0x30;
+ cfg_tmp >>= 4;
+ do_serdes_enable(cfg_tmp, serdes3_base);
+#endif
+
+ /* Wait for at at least 625us, ensure the PLLs being reset are locked */
+ udelay(800);
+
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ cfg_tmp = cfg_rcwsrds1 & 0x3;
+ do_pll_lock(cfg_tmp, serdes1_base);
+#endif
+
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ cfg_tmp = cfg_rcwsrds1 & 0xC;
+ cfg_tmp >>= 2;
+ do_pll_lock(cfg_tmp, serdes2_base);
+#endif
+
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ cfg_tmp = cfg_rcwsrds3 & 0x30;
+ cfg_tmp >>= 4;
+ do_pll_lock(cfg_tmp, serdes3_base);
+#endif
+
+ /* Take the all enabled lanes out of reset */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ do_enabled_lanes_reset(1, cfg_rcwsrds1, serdes1_base, true);
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ do_enabled_lanes_reset(2, cfg_rcwsrds2, serdes2_base, true);
+#endif
+
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ do_enabled_lanes_reset(3, cfg_rcwsrds3, serdes3_base, true);
+#endif
+
+ /* For each PLL being reset, and achieved PLL lock set RST_DONE */
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ cfg_tmp = cfg_rcwsrds1 & 0x3;
+ do_pll_reset_done(cfg_tmp, serdes1_base);
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ cfg_tmp = cfg_rcwsrds1 & 0xC;
+ cfg_tmp >>= 2;
+ do_pll_reset_done(cfg_tmp, serdes2_base);
+#endif
+
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ cfg_tmp = cfg_rcwsrds3 & 0x30;
+ cfg_tmp >>= 4;
+ do_pll_reset_done(cfg_tmp, serdes3_base);
+#endif
+
+ return ret;
+}
+
+void fsl_serdes_init(void)
+{
+#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
+ int i , j;
+
+#if defined(CONFIG_ARCH_LX2160A) || defined(CONFIG_ARCH_LX2162A)
+ for (i = XFI1, j = 1; i <= XFI14; i++, j++)
+ xfi_dpmac[i] = j;
+
+ for (i = SGMII1, j = 1; i <= SGMII18; i++, j++)
+ sgmii_dpmac[i] = j;
+
+ for (i = _25GE1, j = 1; i <= _25GE10; i++, j++)
+ a25gaui_dpmac[i] = j;
+
+ for (i = _40GE1, j = 1; i <= _40GE2; i++, j++)
+ xlaui_dpmac[i] = j;
+
+ for (i = _50GE1, j = 1; i <= _50GE2; i++, j++)
+ caui2_dpmac[i] = j;
+
+ for (i = _100GE1, j = 1; i <= _100GE2; i++, j++)
+ caui4_dpmac[i] = j;
+#else
+ for (i = XFI1, j = 1; i <= XFI8; i++, j++)
+ xfi_dpmac[i] = j;
+
+ for (i = SGMII1, j = 1; i <= SGMII16; i++, j++)
+ sgmii_dpmac[i] = j;
+#endif
+#endif
+
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ serdes_init(FSL_SRDS_1,
+ CONFIG_SYS_FSL_LSCH3_SERDES_ADDR,
+ FSL_CHASSIS3_SRDS1_REGSR,
+ FSL_CHASSIS3_SRDS1_PRTCL_MASK,
+ FSL_CHASSIS3_SRDS1_PRTCL_SHIFT,
+ serdes1_prtcl_map);
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ serdes_init(FSL_SRDS_2,
+ CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + FSL_SRDS_2 * 0x10000,
+ FSL_CHASSIS3_SRDS2_REGSR,
+ FSL_CHASSIS3_SRDS2_PRTCL_MASK,
+ FSL_CHASSIS3_SRDS2_PRTCL_SHIFT,
+ serdes2_prtcl_map);
+#endif
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ serdes_init(NXP_SRDS_3,
+ CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + NXP_SRDS_3 * 0x10000,
+ FSL_CHASSIS3_SRDS3_REGSR,
+ FSL_CHASSIS3_SRDS3_PRTCL_MASK,
+ FSL_CHASSIS3_SRDS3_PRTCL_SHIFT,
+ serdes3_prtcl_map);
+#endif
+}
+
+int serdes_set_env(int sd, int rcwsr, int sd_prctl_mask, int sd_prctl_shift)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ char scfg[16], snum[16];
+ int cfgr = 0;
+ u32 cfg;
+
+ cfg = gur_in32(&gur->rcwsr[rcwsr - 1]) & sd_prctl_mask;
+ cfg >>= sd_prctl_shift;
+ cfg = serdes_get_number(sd, cfg);
+
+#if defined(SRDS_BITS_PER_LANE)
+ /*
+ * reverse lanes, lane 0 should be printed first so it must be moved to
+ * high order bits.
+ * For example bb58 should read 85bb, lane 0 being protocol 8.
+ * This only applies to SoCs that define SRDS_BITS_PER_LANE and have
+ * independent per-lane protocol configuration, at this time LS1028A and
+ * LS1088A. LS2 and LX2 SoCs encode the full protocol mix across all
+ * lanes as a single value.
+ */
+ for (int i = 0; i < SRDS_MAX_LANES; i++) {
+ int tmp;
+
+ tmp = cfg >> (i * SRDS_BITS_PER_LANE);
+ tmp &= GENMASK(SRDS_BITS_PER_LANE - 1, 0);
+ tmp <<= (SRDS_MAX_LANES - i - 1) * SRDS_BITS_PER_LANE;
+ cfgr |= tmp;
+ }
+#endif /* SRDS_BITS_PER_LANE */
+
+ snprintf(snum, 16, "serdes%d", sd);
+ snprintf(scfg, 16, "%x", cfgr);
+ env_set(snum, scfg);
+
+ return 0;
+}
+
+int serdes_misc_init(void)
+{
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ serdes_set_env(FSL_SRDS_1, FSL_CHASSIS3_SRDS1_REGSR,
+ FSL_CHASSIS3_SRDS1_PRTCL_MASK,
+ FSL_CHASSIS3_SRDS1_PRTCL_SHIFT);
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ serdes_set_env(FSL_SRDS_2, FSL_CHASSIS3_SRDS2_REGSR,
+ FSL_CHASSIS3_SRDS2_PRTCL_MASK,
+ FSL_CHASSIS3_SRDS2_PRTCL_SHIFT);
+#endif
+#ifdef CONFIG_SYS_NXP_SRDS_3
+ serdes_set_env(NXP_SRDS_3, FSL_CHASSIS3_SRDS3_REGSR,
+ FSL_CHASSIS3_SRDS3_PRTCL_MASK,
+ FSL_CHASSIS3_SRDS3_PRTCL_SHIFT);
+#endif
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c
new file mode 100644
index 000000000..25a1c36d2
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014-2015, Freescale Semiconductor, Inc.
+ * Copyright 2019-2020 NXP
+ *
+ * Derived from arch/power/cpu/mpc85xx/speed.c
+ */
+
+#include <common.h>
+#include <clock_legacy.h>
+#include <cpu_func.h>
+#include <asm/global_data.h>
+#include <linux/compiler.h>
+#include <fsl_ifc.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/arch-fsl-layerscape/immap_lsch3.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/soc.h>
+#include "cpu.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
+#define CONFIG_SYS_FSL_NUM_CC_PLLS 6
+#endif
+
+
+void get_sys_info(struct sys_info *sys_info)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ struct ccsr_clk_cluster_group __iomem *clk_grp[2] = {
+ (void *)(CONFIG_SYS_FSL_CH3_CLK_GRPA_ADDR),
+ (void *)(CONFIG_SYS_FSL_CH3_CLK_GRPB_ADDR)
+ };
+ struct ccsr_clk_ctrl __iomem *clk_ctrl =
+ (void *)(CONFIG_SYS_FSL_CH3_CLK_CTRL_ADDR);
+ unsigned int cpu;
+ const u8 core_cplx_pll[16] = {
+ [0] = 0, /* CC1 PPL / 1 */
+ [1] = 0, /* CC1 PPL / 2 */
+ [2] = 0, /* CC1 PPL / 4 */
+ [4] = 1, /* CC2 PPL / 1 */
+ [5] = 1, /* CC2 PPL / 2 */
+ [6] = 1, /* CC2 PPL / 4 */
+ [8] = 2, /* CC3 PPL / 1 */
+ [9] = 2, /* CC3 PPL / 2 */
+ [10] = 2, /* CC3 PPL / 4 */
+ [12] = 3, /* CC4 PPL / 1 */
+ [13] = 3, /* CC4 PPL / 2 */
+ [14] = 3, /* CC4 PPL / 4 */
+ };
+
+ const u8 core_cplx_pll_div[16] = {
+ [0] = 1, /* CC1 PPL / 1 */
+ [1] = 2, /* CC1 PPL / 2 */
+ [2] = 4, /* CC1 PPL / 4 */
+ [4] = 1, /* CC2 PPL / 1 */
+ [5] = 2, /* CC2 PPL / 2 */
+ [6] = 4, /* CC2 PPL / 4 */
+ [8] = 1, /* CC3 PPL / 1 */
+ [9] = 2, /* CC3 PPL / 2 */
+ [10] = 4, /* CC3 PPL / 4 */
+ [12] = 1, /* CC4 PPL / 1 */
+ [13] = 2, /* CC4 PPL / 2 */
+ [14] = 4, /* CC4 PPL / 4 */
+ };
+
+ uint i, cluster;
+#if defined(CONFIG_ARCH_LS1028A) || defined(CONFIG_ARCH_LS1088A)
+ uint rcw_tmp;
+#endif
+ uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
+ uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
+ unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
+ int cc_group[12] = CONFIG_SYS_FSL_CLUSTER_CLOCKS;
+ u32 c_pll_sel, cplx_pll;
+ void *offset;
+
+ sys_info->freq_systembus = sysclk;
+#ifdef CONFIG_DDR_CLK_FREQ
+ sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
+#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
+ sys_info->freq_ddrbus2 = CONFIG_DDR_CLK_FREQ;
+#endif
+#else
+ sys_info->freq_ddrbus = sysclk;
+#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
+ sys_info->freq_ddrbus2 = sysclk;
+#endif
+#endif
+
+ /* The freq_systembus is used to record frequency of platform PLL */
+ sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >>
+ FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_SHIFT) &
+ FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_MASK;
+ sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >>
+ FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_SHIFT) &
+ FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK;
+#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
+ if (soc_has_dp_ddr()) {
+ sys_info->freq_ddrbus2 *= (gur_in32(&gur->rcwsr[0]) >>
+ FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_SHIFT) &
+ FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_MASK;
+ } else {
+ sys_info->freq_ddrbus2 = 0;
+ }
+#endif
+
+ for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
+ /*
+ * fixme: prefer to combine the following into one line, but
+ * cannot pass compiling without warning about in_le32.
+ */
+ offset = (void *)((size_t)clk_grp[i/3] +
+ offsetof(struct ccsr_clk_cluster_group,
+ pllngsr[i%3].gsr));
+ ratio[i] = (in_le32(offset) >> 1) & 0x3f;
+ freq_c_pll[i] = sysclk * ratio[i];
+ }
+
+ for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
+ cluster = fsl_qoriq_core_to_cluster(cpu);
+ c_pll_sel = (in_le32(&clk_ctrl->clkcncsr[cluster].csr) >> 27)
+ & 0xf;
+ cplx_pll = core_cplx_pll[c_pll_sel];
+ cplx_pll += cc_group[cluster] - 1;
+ sys_info->freq_processor[cpu] =
+ freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
+ }
+
+#if defined(CONFIG_FSL_IFC)
+ sys_info->freq_localbus = sys_info->freq_systembus /
+ CONFIG_SYS_FSL_IFC_CLK_DIV;
+#endif
+
+#if defined(CONFIG_ARCH_LS1028A) || defined(CONFIG_ARCH_LS1088A)
+#define HWA_CGA_M2_CLK_SEL 0x00380000
+#define HWA_CGA_M2_CLK_SHIFT 19
+ rcw_tmp = in_le32(&gur->rcwsr[5]);
+ switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) {
+ case 1:
+ sys_info->freq_cga_m2 = freq_c_pll[1];
+ break;
+ case 2:
+ sys_info->freq_cga_m2 = freq_c_pll[1] / 2;
+ break;
+ case 3:
+ sys_info->freq_cga_m2 = freq_c_pll[1] / 3;
+ break;
+ case 4:
+ sys_info->freq_cga_m2 = freq_c_pll[1] / 4;
+ break;
+ case 6:
+ sys_info->freq_cga_m2 = freq_c_pll[0] / 2;
+ break;
+ case 7:
+ sys_info->freq_cga_m2 = freq_c_pll[0] / 3;
+ break;
+ default:
+ printf("Error: Unknown peripheral clock select!\n");
+ break;
+ }
+#endif
+}
+
+int get_clocks(void)
+{
+ struct sys_info sys_info;
+#ifdef CONFIG_FSL_ESDHC
+ u32 clock = 0;
+#endif
+ get_sys_info(&sys_info);
+ gd->cpu_clk = sys_info.freq_processor[0];
+ gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV;
+ gd->mem_clk = sys_info.freq_ddrbus;
+#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
+ gd->arch.mem2_clk = sys_info.freq_ddrbus2;
+#endif
+
+#ifdef CONFIG_FSL_ESDHC
+#if defined(CONFIG_ARCH_LS1028A) || defined(CONFIG_ARCH_LS1088A)
+ clock = sys_info.freq_cga_m2;
+#elif defined(CONFIG_ARCH_LX2160A) || defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LX2162A)
+ clock = sys_info.freq_systembus;
+#endif
+ gd->arch.sdhc_per_clk = clock / CONFIG_SYS_FSL_SDHC_CLK_DIV;
+ gd->arch.sdhc_clk = gd->bus_clk / CONFIG_SYS_FSL_SDHC_CLK_DIV;
+#endif
+
+ if (gd->cpu_clk != 0)
+ return 0;
+ else
+ return 1;
+}
+
+/********************************************
+ * get_bus_freq
+ * return platform clock in Hz
+ *********************************************/
+ulong get_bus_freq(ulong dummy)
+{
+ if (!gd->bus_clk)
+ get_clocks();
+
+ return gd->bus_clk;
+}
+
+/********************************************
+ * get_ddr_freq
+ * return ddr bus freq in Hz
+ *********************************************/
+ulong get_ddr_freq(ulong ctrl_num)
+{
+ if (!gd->mem_clk)
+ get_clocks();
+
+ /*
+ * DDR controller 0 & 1 are on memory complex 0
+ * DDR controller 2 is on memory complext 1
+ */
+#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
+ if (ctrl_num >= 2)
+ return gd->arch.mem2_clk;
+#endif
+
+ return gd->mem_clk;
+}
+
+int get_i2c_freq(ulong dummy)
+{
+ return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV;
+}
+
+int get_dspi_freq(ulong dummy)
+{
+ return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV;
+}
+
+int get_serial_clock(void)
+{
+ return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV;
+}
+
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+ switch (clk) {
+ case MXC_I2C_CLK:
+ return get_i2c_freq(0);
+ case MXC_DSPI_CLK:
+ return get_dspi_freq(0);
+ default:
+ printf("Unsupported clock\n");
+ }
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/icid.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/icid.c
new file mode 100644
index 000000000..82c5a8b12
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/icid.c
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <common.h>
+#include <linux/libfdt.h>
+#include <fdt_support.h>
+
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/arch-fsl-layerscape/fsl_icid.h>
+#include <fsl_fman.h>
+
+static void set_icid(struct icid_id_table *tbl, int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ if (tbl[i].le)
+ out_le32((u32 *)(tbl[i].reg_addr), tbl[i].reg);
+ else
+ out_be32((u32 *)(tbl[i].reg_addr), tbl[i].reg);
+}
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+void set_fman_icids(struct fman_icid_id_table *tbl, int size)
+{
+ int i;
+ ccsr_fman_t *fm = (void *)CONFIG_SYS_FSL_FM1_ADDR;
+
+ for (i = 0; i < size; i++) {
+ out_be32(&fm->fm_bmi_common.fmbm_ppid[tbl[i].port_id - 1],
+ tbl[i].icid);
+ }
+}
+#endif
+
+void set_icids(void)
+{
+ /* setup general icid offsets */
+ set_icid(icid_tbl, icid_tbl_sz);
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+ set_fman_icids(fman_icid_tbl, fman_icid_tbl_sz);
+#endif
+}
+
+int fdt_set_iommu_prop(void *blob, int off, int smmu_ph, u32 *ids, int num_ids)
+{
+ int i, ret;
+ u32 prop[8];
+
+ /*
+ * Note: The "iommus" property definition mentions Stream IDs while
+ * this code handles ICIDs. The current implementation assumes that
+ * ICIDs and Stream IDs are equal.
+ */
+ for (i = 0; i < num_ids; i++) {
+ prop[i * 2] = cpu_to_fdt32(smmu_ph);
+ prop[i * 2 + 1] = cpu_to_fdt32(ids[i]);
+ }
+ ret = fdt_setprop(blob, off, "iommus",
+ prop, sizeof(u32) * num_ids * 2);
+ if (ret) {
+ printf("WARNING unable to set iommus: %s\n", fdt_strerror(ret));
+ return ret;
+ }
+
+ return 0;
+}
+
+int fdt_fixup_icid_tbl(void *blob, int smmu_ph,
+ struct icid_id_table *tbl, int size)
+{
+ int i, err, off;
+
+ for (i = 0; i < size; i++) {
+ if (!tbl[i].compat)
+ continue;
+
+ off = fdt_node_offset_by_compat_reg(blob,
+ tbl[i].compat,
+ tbl[i].compat_addr);
+ if (off > 0) {
+ err = fdt_set_iommu_prop(blob, off, smmu_ph,
+ &tbl[i].id, 1);
+ if (err)
+ return err;
+ } else {
+ printf("WARNING could not find node %s: %s.\n",
+ tbl[i].compat, fdt_strerror(off));
+ }
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+int get_fman_port_icid(int port_id, struct fman_icid_id_table *tbl,
+ const int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (tbl[i].port_id == port_id)
+ return tbl[i].icid;
+ }
+
+ return -1;
+}
+
+void fdt_fixup_fman_port_icid_by_compat(void *blob, int smmu_ph,
+ const char *compat)
+{
+ int noff, len, icid;
+ const u32 *prop;
+
+ noff = fdt_node_offset_by_compatible(blob, -1, compat);
+ while (noff > 0) {
+ prop = fdt_getprop(blob, noff, "cell-index", &len);
+ if (!prop) {
+ printf("WARNING missing cell-index for fman port\n");
+ continue;
+ }
+ if (len != 4) {
+ printf("WARNING bad cell-index size for fman port\n");
+ continue;
+ }
+
+ icid = get_fman_port_icid(fdt32_to_cpu(*prop),
+ fman_icid_tbl, fman_icid_tbl_sz);
+ if (icid < 0) {
+ printf("WARNING unknown ICID for fman port %d\n",
+ *prop);
+ continue;
+ }
+
+ fdt_set_iommu_prop(blob, noff, smmu_ph, (u32 *)&icid, 1);
+
+ noff = fdt_node_offset_by_compatible(blob, noff, compat);
+ }
+}
+
+void fdt_fixup_fman_icids(void *blob, int smmu_ph)
+{
+ static const char * const compats[] = {
+ "fsl,fman-v3-port-oh",
+ "fsl,fman-v3-port-rx",
+ "fsl,fman-v3-port-tx",
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(compats); i++)
+ fdt_fixup_fman_port_icid_by_compat(blob, smmu_ph, compats[i]);
+}
+#endif
+
+int fdt_get_smmu_phandle(void *blob)
+{
+ int noff, smmu_ph;
+
+ noff = fdt_node_offset_by_compatible(blob, -1, "arm,mmu-500");
+ if (noff < 0) {
+ printf("WARNING failed to get smmu node: %s\n",
+ fdt_strerror(noff));
+ return noff;
+ }
+
+ smmu_ph = fdt_get_phandle(blob, noff);
+ if (!smmu_ph) {
+ smmu_ph = fdt_create_phandle(blob, noff);
+ if (!smmu_ph) {
+ printf("WARNING failed to get smmu phandle\n");
+ return -1;
+ }
+ }
+
+ return smmu_ph;
+}
+
+void fdt_fixup_icid(void *blob)
+{
+ int smmu_ph;
+
+ smmu_ph = fdt_get_smmu_phandle(blob);
+ if (smmu_ph < 0)
+ return;
+
+ fdt_fixup_icid_tbl(blob, smmu_ph, icid_tbl, icid_tbl_sz);
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+ fdt_fixup_fman_icids(blob, smmu_ph);
+#endif
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S
new file mode 100644
index 000000000..d8803738f
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S
@@ -0,0 +1,430 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2014-2015 Freescale Semiconductor
+ * Copyright 2019 NXP
+ *
+ * Extracted from armv8/start.S
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/gic.h>
+#include <asm/macro.h>
+#include <asm/arch-fsl-layerscape/soc.h>
+#ifdef CONFIG_FSL_LSCH3
+#include <asm/arch-fsl-layerscape/immap_lsch3.h>
+#endif
+#include <asm/u-boot.h>
+
+ .align 3
+ .weak secondary_boot_addr
+secondary_boot_addr:
+ .quad 0
+
+/* Get GIC offset
+* For LS1043a rev1.0, GIC base address align with 4k.
+* For LS1043a rev1.1, if DCFG_GIC400_ALIGN[GIC_ADDR_BIT]
+* is set, GIC base address align with 4K, or else align
+* with 64k.
+* output:
+* x0: the base address of GICD
+* x1: the base address of GICC
+*/
+ENTRY(get_gic_offset)
+ ldr x0, =GICD_BASE
+#ifdef CONFIG_GICV2
+ ldr x1, =GICC_BASE
+#endif
+#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
+ ldr x2, =DCFG_CCSR_SVR
+ ldr w2, [x2]
+ rev w2, w2
+ lsr w3, w2, #16
+ ldr w4, =SVR_DEV(SVR_LS1043A)
+ cmp w3, w4
+ b.ne 1f
+ ands w2, w2, #0xff
+ cmp w2, #REV1_0
+ b.eq 1f
+ ldr x2, =SCFG_GIC400_ALIGN
+ ldr w2, [x2]
+ rev w2, w2
+ tbnz w2, #GIC_ADDR_BIT, 1f
+ ldr x0, =GICD_BASE_64K
+#ifdef CONFIG_GICV2
+ ldr x1, =GICC_BASE_64K
+#endif
+1:
+#endif
+ ret
+ENDPROC(get_gic_offset)
+
+ENTRY(smp_kick_all_cpus)
+ /* Kick secondary cpus up by SGI 0 interrupt */
+#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
+ mov x29, lr /* Save LR */
+ bl get_gic_offset
+ bl gic_kick_secondary_cpus
+ mov lr, x29 /* Restore LR */
+#endif
+ ret
+ENDPROC(smp_kick_all_cpus)
+
+
+ENTRY(lowlevel_init)
+ mov x29, lr /* Save LR */
+
+ /* unmask SError and abort */
+ msr daifclr, #4
+
+ /* Set HCR_EL2[AMO] so SError @EL2 is taken */
+ mrs x0, hcr_el2
+ orr x0, x0, #0x20 /* AMO */
+ msr hcr_el2, x0
+ isb
+
+ switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */
+1:
+
+#if defined (CONFIG_SYS_FSL_HAS_CCN504)
+
+ /* Set Wuo bit for RN-I 20 */
+#ifdef CONFIG_ARCH_LS2080A
+ ldr x0, =CCI_AUX_CONTROL_BASE(20)
+ ldr x1, =0x00000010
+ bl ccn504_set_aux
+
+ /*
+ * Set forced-order mode in RNI-6, RNI-20
+ * This is required for performance optimization on LS2088A
+ * LS2080A family does not support setting forced-order mode,
+ * so skip this operation for LS2080A family
+ */
+ bl get_svr
+ lsr w0, w0, #16
+ ldr w1, =SVR_DEV(SVR_LS2080A)
+ cmp w0, w1
+ b.eq 1f
+
+ ldr x0, =CCI_AUX_CONTROL_BASE(6)
+ ldr x1, =0x00000020
+ bl ccn504_set_aux
+ ldr x0, =CCI_AUX_CONTROL_BASE(20)
+ ldr x1, =0x00000020
+ bl ccn504_set_aux
+1:
+#endif
+
+ /* Add fully-coherent masters to DVM domain */
+ ldr x0, =CCI_MN_BASE
+ ldr x1, =CCI_MN_RNF_NODEID_LIST
+ ldr x2, =CCI_MN_DVM_DOMAIN_CTL_SET
+ bl ccn504_add_masters_to_dvm
+
+ /* Set all RN-I ports to QoS of 15 */
+ ldr x0, =CCI_S0_QOS_CONTROL_BASE(0)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+ ldr x0, =CCI_S1_QOS_CONTROL_BASE(0)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+ ldr x0, =CCI_S2_QOS_CONTROL_BASE(0)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+
+ ldr x0, =CCI_S0_QOS_CONTROL_BASE(2)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+ ldr x0, =CCI_S1_QOS_CONTROL_BASE(2)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+ ldr x0, =CCI_S2_QOS_CONTROL_BASE(2)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+
+ ldr x0, =CCI_S0_QOS_CONTROL_BASE(6)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+ ldr x0, =CCI_S1_QOS_CONTROL_BASE(6)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+ ldr x0, =CCI_S2_QOS_CONTROL_BASE(6)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+
+ ldr x0, =CCI_S0_QOS_CONTROL_BASE(12)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+ ldr x0, =CCI_S1_QOS_CONTROL_BASE(12)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+ ldr x0, =CCI_S2_QOS_CONTROL_BASE(12)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+
+ ldr x0, =CCI_S0_QOS_CONTROL_BASE(16)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+ ldr x0, =CCI_S1_QOS_CONTROL_BASE(16)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+ ldr x0, =CCI_S2_QOS_CONTROL_BASE(16)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+
+ ldr x0, =CCI_S0_QOS_CONTROL_BASE(20)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+ ldr x0, =CCI_S1_QOS_CONTROL_BASE(20)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+ ldr x0, =CCI_S2_QOS_CONTROL_BASE(20)
+ ldr x1, =0x00FF000C
+ bl ccn504_set_qos
+#endif /* CONFIG_SYS_FSL_HAS_CCN504 */
+
+#ifdef SMMU_BASE
+ /* Set the SMMU page size in the sACR register */
+ ldr x1, =SMMU_BASE
+ ldr w0, [x1, #0x10]
+ orr w0, w0, #1 << 16 /* set sACR.pagesize to indicate 64K page */
+ str w0, [x1, #0x10]
+#endif
+
+ /* Initialize GIC Secure Bank Status */
+#if !defined(CONFIG_SPL_BUILD)
+#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
+ branch_if_slave x0, 1f
+ bl get_gic_offset
+ bl gic_init_secure
+1:
+#ifdef CONFIG_GICV3
+ ldr x0, =GICR_BASE
+ bl gic_init_secure_percpu
+#elif defined(CONFIG_GICV2)
+ bl get_gic_offset
+ bl gic_init_secure_percpu
+#endif
+#endif
+#endif
+
+100:
+ branch_if_master x0, x1, 2f
+
+#if defined(CONFIG_MP) && defined(CONFIG_ARMV8_MULTIENTRY)
+ /*
+ * Formerly, here was a jump to secondary_boot_func, but we just
+ * return early here and let the generic code in start.S handle
+ * the jump to secondary_boot_func.
+ */
+ mov lr, x29 /* Restore LR */
+ ret
+#endif
+
+2:
+ switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */
+1:
+#ifdef CONFIG_FSL_TZPC_BP147
+ /* Set Non Secure access for all devices protected via TZPC */
+ ldr x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */
+ orr w0, w0, #1 << 3 /* DCFG_RESET is accessible from NS world */
+ str w0, [x1]
+
+ isb
+ dsb sy
+#endif
+
+#ifdef CONFIG_FSL_TZASC_400
+ /*
+ * LS2080 and its personalities does not support TZASC
+ * So skip TZASC related operations
+ */
+ bl get_svr
+ lsr w0, w0, #16
+ ldr w1, =SVR_DEV(SVR_LS2080A)
+ cmp w0, w1
+ b.eq 1f
+
+ /* Set TZASC so that:
+ * a. We use only Region0 whose global secure write/read is EN
+ * b. We use only Region0 whose NSAID write/read is EN
+ *
+ * NOTE: As per the CCSR map doc, TZASC 3 and TZASC 4 are just
+ * placeholders.
+ */
+
+.macro tzasc_prog, xreg
+
+ mov x12, TZASC1_BASE
+ mov x16, #0x10000
+ mul x14, \xreg, x16
+ add x14, x14,x12
+ mov x1, #0x8
+ add x1, x1, x14
+
+ ldr w0, [x1] /* Filter 0 Gate Keeper Register */
+ orr w0, w0, #1 << 0 /* Set open_request for Filter 0 */
+ str w0, [x1]
+
+ mov x1, #0x110
+ add x1, x1, x14
+
+ ldr w0, [x1] /* Region-0 Attributes Register */
+ orr w0, w0, #1 << 31 /* Set Sec global write en, Bit[31] */
+ orr w0, w0, #1 << 30 /* Set Sec global read en, Bit[30] */
+ str w0, [x1]
+
+ mov x1, #0x114
+ add x1, x1, x14
+
+ ldr w0, [x1] /* Region-0 Access Register */
+ mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */
+ str w0, [x1]
+.endm
+
+#ifdef CONFIG_FSL_TZASC_1
+ mov x13, #0
+ tzasc_prog x13
+
+#endif
+#ifdef CONFIG_FSL_TZASC_2
+ mov x13, #1
+ tzasc_prog x13
+
+#endif
+ isb
+ dsb sy
+#endif
+100:
+1:
+#ifdef CONFIG_ARCH_LS1046A
+ switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */
+1:
+ /* Initialize the L2 RAM latency */
+ mrs x1, S3_1_c11_c0_2
+ mov x0, #0x1C7
+ /* Clear L2 Tag RAM latency and L2 Data RAM latency */
+ bic x1, x1, x0
+ /* Set L2 data ram latency bits [2:0] */
+ orr x1, x1, #0x2
+ /* set L2 tag ram latency bits [8:6] */
+ orr x1, x1, #0x80
+ msr S3_1_c11_c0_2, x1
+ isb
+100:
+#endif
+
+#if !defined(CONFIG_TFABOOT) && \
+ (defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD))
+ bl fsl_ocram_init
+#endif
+
+ mov lr, x29 /* Restore LR */
+ ret
+ENDPROC(lowlevel_init)
+
+#if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD)
+ENTRY(fsl_ocram_init)
+ mov x28, lr /* Save LR */
+ bl fsl_clear_ocram
+ bl fsl_ocram_clear_ecc_err
+ mov lr, x28 /* Restore LR */
+ ret
+ENDPROC(fsl_ocram_init)
+
+ENTRY(fsl_clear_ocram)
+/* Clear OCRAM */
+ ldr x0, =CONFIG_SYS_FSL_OCRAM_BASE
+ ldr x1, =(CONFIG_SYS_FSL_OCRAM_BASE + CONFIG_SYS_FSL_OCRAM_SIZE)
+ mov x2, #0
+clear_loop:
+ str x2, [x0]
+ add x0, x0, #8
+ cmp x0, x1
+ b.lo clear_loop
+ ret
+ENDPROC(fsl_clear_ocram)
+
+ENTRY(fsl_ocram_clear_ecc_err)
+ /* OCRAM1/2 ECC status bit */
+ mov w1, #0x60
+ ldr x0, =DCSR_DCFG_SBEESR2
+ str w1, [x0]
+ ldr x0, =DCSR_DCFG_MBEESR2
+ str w1, [x0]
+ ret
+ENDPROC(fsl_ocram_init)
+#endif
+
+#ifdef CONFIG_FSL_LSCH3
+ .globl get_svr
+get_svr:
+ ldr x1, =FSL_LSCH3_SVR
+ ldr w0, [x1]
+ ret
+#endif
+
+#if defined(CONFIG_SYS_FSL_HAS_CCN504) || defined(CONFIG_SYS_FSL_HAS_CCN508)
+hnf_pstate_poll:
+ /* x0 has the desired status, return only if operation succeed
+ * clobber x1, x2, x6
+ */
+ mov x1, x0
+ mov w6, #8 /* HN-F node count */
+ mov x0, #0x18
+ movk x0, #0x420, lsl #16 /* HNF0_PSTATE_STATUS */
+1:
+ ldr x2, [x0]
+ cmp x2, x1 /* check status */
+ b.eq 2f
+ b 1b
+2:
+ add x0, x0, #0x10000 /* move to next node */
+ subs w6, w6, #1
+ cbnz w6, 1b
+ ret
+
+hnf_set_pstate:
+ /* x0 has the desired state, clobber x1, x2, x6 */
+ mov x1, x0
+ /* power state to SFONLY */
+ mov w6, #8 /* HN-F node count */
+ mov x0, #0x10
+ movk x0, #0x420, lsl #16 /* HNF0_PSTATE_REQ */
+1: /* set pstate to sfonly */
+ ldr x2, [x0]
+ and x2, x2, #0xfffffffffffffffc /* & HNFPSTAT_MASK */
+ orr x2, x2, x1
+ str x2, [x0]
+ add x0, x0, #0x10000 /* move to next node */
+ subs w6, w6, #1
+ cbnz w6, 1b
+
+ ret
+
+ENTRY(__asm_flush_l3_dcache)
+ /*
+ * Return status in x0
+ * success 0
+ */
+ mov x29, lr
+
+ dsb sy
+ mov x0, #0x1 /* HNFPSTAT_SFONLY */
+ bl hnf_set_pstate
+
+ mov x0, #0x4 /* SFONLY status */
+ bl hnf_pstate_poll
+
+ dsb sy
+ mov x0, #0x3 /* HNFPSTAT_FAM */
+ bl hnf_set_pstate
+
+ mov x0, #0xc /* FAM status */
+ bl hnf_pstate_poll
+
+ mov x0, #0
+ mov lr, x29
+ ret
+ENDPROC(__asm_flush_l3_dcache)
+#endif /* CONFIG_SYS_FSL_HAS_CCN504 */
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1012a_serdes.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1012a_serdes.c
new file mode 100644
index 000000000..8d7beca7d
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1012a_serdes.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/immap_lsch2.h>
+
+struct serdes_config {
+ u32 protocol;
+ u8 lanes[SRDS_MAX_LANES];
+};
+
+static struct serdes_config serdes1_cfg_tbl[] = {
+ {0x2208, {SGMII_2500_FM1_DTSEC1, SGMII_2500_FM1_DTSEC2, NONE, SATA1} },
+ {0x0008, {NONE, NONE, NONE, SATA1} },
+ {0x3508, {SGMII_FM1_DTSEC1, PCIE1, NONE, SATA1} },
+ {0x3305, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2, NONE, PCIE1} },
+ {0x2205, {SGMII_2500_FM1_DTSEC1, SGMII_2500_FM1_DTSEC2, NONE, PCIE1} },
+ {0x2305, {SGMII_2500_FM1_DTSEC1, SGMII_FM1_DTSEC2, NONE, PCIE1} },
+ {0x9508, {TX_CLK, PCIE1, NONE, SATA1} },
+ {0x3905, {SGMII_FM1_DTSEC1, TX_CLK, NONE, PCIE1} },
+ {0x9305, {TX_CLK, SGMII_FM1_DTSEC2, NONE, PCIE1} },
+ {}
+};
+
+static struct serdes_config *serdes_cfg_tbl[] = {
+ serdes1_cfg_tbl,
+};
+
+enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
+{
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == cfg)
+ return ptr->lanes[lane];
+ ptr++;
+ }
+
+ return 0;
+}
+
+int is_serdes_prtcl_valid(int serdes, u32 prtcl)
+{
+ int i;
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == prtcl)
+ break;
+ ptr++;
+ }
+
+ if (!ptr->protocol)
+ return 0;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (ptr->lanes[i] != NONE)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c
new file mode 100644
index 000000000..49df8b379
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ */
+
+#include <common.h>
+#include <fdt_support.h>
+#include <log.h>
+#include <asm/arch-fsl-layerscape/immap_lsch3.h>
+#include <asm/arch-fsl-layerscape/fsl_icid.h>
+#include <asm/arch-fsl-layerscape/fsl_portals.h>
+
+struct icid_id_table icid_tbl[] = {
+ SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
+ SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
+ SET_SDHC_ICID(1, FSL_SDMMC_STREAM_ID),
+ SET_SDHC_ICID(2, FSL_SDMMC2_STREAM_ID),
+ SET_SATA_ICID(1, "fsl,ls1028a-ahci", FSL_SATA1_STREAM_ID),
+ SET_EDMA_ICID(FSL_EDMA_STREAM_ID),
+ SET_QDMA_ICID("fsl,ls1028a-qdma", FSL_DMA_STREAM_ID),
+ SET_GPU_ICID("fsl,ls1028a-gpu", FSL_GPU_STREAM_ID),
+ SET_DISPLAY_ICID(FSL_DISPLAY_STREAM_ID),
+#ifdef CONFIG_FSL_CAAM
+ SET_SEC_JR_ICID_ENTRY(0, FSL_SEC_JR1_STREAM_ID),
+ SET_SEC_JR_ICID_ENTRY(1, FSL_SEC_JR2_STREAM_ID),
+ SET_SEC_JR_ICID_ENTRY(2, FSL_SEC_JR3_STREAM_ID),
+ SET_SEC_JR_ICID_ENTRY(3, FSL_SEC_JR4_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
+#endif
+};
+
+int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
+
+/* integrated PCI is handled separately as it's not part of CCSR/SCFG */
+#ifdef CONFIG_PCIE_ECAM_GENERIC
+
+#define ECAM_IERB_BASE 0x1f0800000ULL
+#define ECAM_IERB_OFFSET_NA -1
+#define ECAM_IERB_FUNC_CNT ARRAY_SIZE(ierb_offset)
+/* cache related transaction attributes for PCIe functions */
+#define ECAM_IERB_MSICAR (ECAM_IERB_BASE + 0xa400)
+#define ECAM_IERB_MSICAR_VALUE 0x30
+
+/* offset of IERB config register per PCI function */
+static int ierb_offset[] = {
+ 0x0800,
+ 0x1800,
+ 0x2800,
+ 0x3800,
+ 0x4800,
+ 0x5800,
+ 0x6800,
+ ECAM_IERB_OFFSET_NA,
+ 0x0804,
+ 0x0808,
+ 0x1804,
+ 0x1808,
+};
+
+/*
+ * Use a custom function for LS1028A, for now this is the only SoC with IERB
+ * and we're currently considering reorganizing IERB for future SoCs.
+ */
+void set_ecam_icids(void)
+{
+ int i;
+
+ out_le32(ECAM_IERB_MSICAR, ECAM_IERB_MSICAR_VALUE);
+
+ for (i = 0; i < ECAM_IERB_FUNC_CNT; i++) {
+ if (ierb_offset[i] == ECAM_IERB_OFFSET_NA)
+ continue;
+
+ out_le32(ECAM_IERB_BASE + ierb_offset[i],
+ FSL_ECAM_STREAM_ID_START + i);
+ }
+}
+
+static int fdt_setprop_inplace_idx_u32(void *fdt, int nodeoffset,
+ const char *name, uint32_t idx, u32 val)
+{
+ val = cpu_to_be32(val);
+ return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
+ strlen(name),
+ idx * sizeof(val), &val,
+ sizeof(val));
+}
+
+static int fdt_getprop_len(void *fdt, int nodeoffset, const char *name)
+{
+ int len;
+
+ if (fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), &len))
+ return len;
+
+ return 0;
+}
+
+void fdt_fixup_ecam(void *blob)
+{
+ int off;
+
+ off = fdt_node_offset_by_compatible(blob, 0, "pci-host-ecam-generic");
+ if (off < 0) {
+ debug("ECAM node not found\n");
+ return;
+ }
+
+ if (fdt_getprop_len(blob, off, "msi-map") != 16 ||
+ fdt_getprop_len(blob, off, "iommu-map") != 16) {
+ log_err("invalid msi/iommu-map propertly size in ECAM node\n");
+ return;
+ }
+
+ fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 2,
+ FSL_ECAM_STREAM_ID_START);
+ fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 3,
+ ECAM_IERB_FUNC_CNT);
+
+ fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 2,
+ FSL_ECAM_STREAM_ID_START);
+ fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 3,
+ ECAM_IERB_FUNC_CNT);
+}
+#endif /* CONFIG_PCIE_ECAM_GENERIC */
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1028a_serdes.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1028a_serdes.c
new file mode 100644
index 000000000..80d2910f6
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1028a_serdes.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+
+struct serdes_config {
+ u32 protocol;
+ u8 lanes[SRDS_MAX_LANES];
+ u8 rcw_lanes[SRDS_MAX_LANES];
+};
+
+static struct serdes_config serdes1_cfg_tbl[] = {
+ /* SerDes 1 */
+ {0xCC5B, {PCIE1, QSGMII_B, PCIE2, PCIE2} },
+ {0xEB99, {SGMII1, SGMII1, PCIE2, SATA1} },
+ {0xCC99, {SGMII1, SGMII1, PCIE2, PCIE2} },
+ {0xBB99, {SGMII1, SGMII1, PCIE2, PCIE1} },
+ {0x9999, {SGMII1, SGMII2, SGMII3, SGMII4} },
+ {0xEBCC, {PCIE1, PCIE1, PCIE2, SATA1} },
+ {0xCCCC, {PCIE1, PCIE1, PCIE2, PCIE2} },
+ {0xDDDD, {PCIE1, PCIE1, PCIE1, PCIE1} },
+ {0xE031, {SXGMII1, QXGMII2, NONE, SATA1} },
+ {0xB991, {SXGMII1, SGMII1, SGMII2, PCIE1} },
+ {0xBB31, {SXGMII1, QXGMII2, PCIE2, PCIE1} },
+ {0xCC31, {SXGMII1, QXGMII2, PCIE2, PCIE2} },
+ {0xBB51, {SXGMII1, QSGMII_B, PCIE2, PCIE1} },
+ {0xBB38, {SGMII_T1, QXGMII2, PCIE2, PCIE1} },
+ {0xCC38, {SGMII_T1, QXGMII2, PCIE2, PCIE2} },
+ {0xBB58, {SGMII_T1, QSGMII_B, PCIE2, PCIE1} },
+ {0xCC58, {SGMII_T1, QSGMII_B, PCIE2, PCIE2} },
+ {0xCC8B, {PCIE1, SGMII_T1, PCIE2, PCIE2} },
+ {0xEB58, {SGMII_T1, QSGMII_B, PCIE2, SATA1} },
+ {0xEB8B, {PCIE1, SGMII_T1, PCIE2, SATA1} },
+ {0xE8CC, {PCIE1, PCIE1, SGMII_T1, SATA1} },
+ {0x7777, {SGMII1, SGMII2, SGMII3, SGMII4} },
+ {0x9999, {SGMII1, SGMII2, SGMII3, SGMII4} },
+ {0xb998, {SGMII_T1, SGMII2, SGMII3, PCIE1} },
+ {0xbb56, {SGMII_T1, QSGMII_B, PCIE2, PCIE1} },
+ {}
+};
+
+static struct serdes_config *serdes_cfg_tbl[] = {
+ serdes1_cfg_tbl,
+};
+
+enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
+{
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == cfg)
+ return ptr->lanes[lane];
+ ptr++;
+ }
+
+ return 0;
+}
+
+int is_serdes_prtcl_valid(int serdes, u32 prtcl)
+{
+ int i;
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == prtcl)
+ break;
+ ptr++;
+ }
+
+ if (!ptr->protocol)
+ return 0;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (ptr->lanes[i] != NONE)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1043_ids.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1043_ids.c
new file mode 100644
index 000000000..3bd993beb
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1043_ids.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <common.h>
+#include <asm/arch-fsl-layerscape/immap_lsch2.h>
+#include <asm/arch-fsl-layerscape/fsl_icid.h>
+#include <asm/arch-fsl-layerscape/fsl_portals.h>
+#include <fsl_sec.h>
+
+#ifdef CONFIG_SYS_DPAA_QBMAN
+struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+};
+#endif
+
+struct icid_id_table icid_tbl[] = {
+#ifdef CONFIG_SYS_DPAA_QBMAN
+ SET_QMAN_ICID(FSL_DPAA1_STREAM_ID_START),
+ SET_BMAN_ICID(FSL_DPAA1_STREAM_ID_START + 1),
+#endif
+
+ SET_SDHC_ICID(FSL_SDHC_STREAM_ID),
+
+ SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
+ SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
+ SET_USB_ICID(3, "snps,dwc3", FSL_USB3_STREAM_ID),
+
+ SET_SATA_ICID("fsl,ls1043a-ahci", FSL_SATA_STREAM_ID),
+ SET_QDMA_ICID("fsl,ls1043a-qdma", FSL_QDMA_STREAM_ID),
+ SET_EDMA_ICID(FSL_EDMA_STREAM_ID),
+ SET_ETR_ICID(FSL_ETR_STREAM_ID),
+ SET_DEBUG_ICID(FSL_DEBUG_STREAM_ID),
+ SET_QE_ICID(FSL_QE_STREAM_ID),
+#ifdef CONFIG_FSL_CAAM
+ SET_SEC_QI_ICID(FSL_DPAA1_STREAM_ID_END),
+ SET_SEC_JR_ICID_ENTRY(0, FSL_DPAA1_STREAM_ID_START + 3),
+ SET_SEC_JR_ICID_ENTRY(1, FSL_DPAA1_STREAM_ID_START + 4),
+ SET_SEC_JR_ICID_ENTRY(2, FSL_DPAA1_STREAM_ID_START + 5),
+ SET_SEC_JR_ICID_ENTRY(3, FSL_DPAA1_STREAM_ID_START + 6),
+ SET_SEC_RTIC_ICID_ENTRY(0, FSL_DPAA1_STREAM_ID_START + 7),
+ SET_SEC_RTIC_ICID_ENTRY(1, FSL_DPAA1_STREAM_ID_START + 8),
+ SET_SEC_RTIC_ICID_ENTRY(2, FSL_DPAA1_STREAM_ID_START + 9),
+ SET_SEC_RTIC_ICID_ENTRY(3, FSL_DPAA1_STREAM_ID_START + 10),
+ SET_SEC_DECO_ICID_ENTRY(0, FSL_DPAA1_STREAM_ID_START + 11),
+ SET_SEC_DECO_ICID_ENTRY(1, FSL_DPAA1_STREAM_ID_START + 12),
+#endif
+};
+
+int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+struct fman_icid_id_table fman_icid_tbl[] = {
+ /* port id, icid */
+ SET_FMAN_ICID_ENTRY(0x02, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x03, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x04, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x05, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x06, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x07, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x08, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x09, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x0a, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x0b, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x0c, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x0d, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x28, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x29, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x2a, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x2b, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x2c, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x2d, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x10, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x11, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x30, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x31, FSL_DPAA1_STREAM_ID_END),
+};
+
+int fman_icid_tbl_sz = ARRAY_SIZE(fman_icid_tbl);
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_psci.S b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_psci.S
new file mode 100644
index 000000000..b4c7d6f85
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_psci.S
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Author: Hongbo Zhang <hongbo.zhang@nxp.com>
+ * This file implements LS102X platform PSCI SYSTEM-SUSPEND function
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/psci.h>
+
+ .pushsection ._secure.text, "ax"
+
+.globl psci_version
+psci_version:
+ ldr w0, =0x00010000 /* PSCI v1.0 */
+ ret
+
+ .popsection
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_serdes.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_serdes.c
new file mode 100644
index 000000000..6c5e52eba
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_serdes.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/immap_lsch2.h>
+
+struct serdes_config {
+ u32 protocol;
+ u8 lanes[SRDS_MAX_LANES];
+};
+
+static struct serdes_config serdes1_cfg_tbl[] = {
+ /* SerDes 1 */
+ {0x1555, {XFI_FM1_MAC9, PCIE1, PCIE2, PCIE3} },
+ {0x2555, {SGMII_2500_FM1_DTSEC9, PCIE1, PCIE2, PCIE3} },
+ {0x4555, {QSGMII_FM1_A, PCIE1, PCIE2, PCIE3} },
+ {0x4558, {QSGMII_FM1_A, PCIE1, PCIE2, SATA1} },
+ {0x1355, {XFI_FM1_MAC9, SGMII_FM1_DTSEC2, PCIE2, PCIE3} },
+ {0x2355, {SGMII_2500_FM1_DTSEC9, SGMII_FM1_DTSEC2, PCIE2, PCIE3} },
+ {0x3335, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC2, SGMII_FM1_DTSEC5,
+ PCIE3} },
+ {0x3355, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC2, PCIE2, PCIE3} },
+ {0x3358, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC2, PCIE2, SATA1} },
+ {0x3555, {SGMII_FM1_DTSEC9, PCIE1, PCIE2, PCIE3} },
+ {0x3558, {SGMII_FM1_DTSEC9, PCIE1, PCIE2, SATA1} },
+ {0x7000, {PCIE1, PCIE1, PCIE1, PCIE1} },
+ {0x9998, {PCIE1, PCIE2, PCIE3, SATA1} },
+ {0x6058, {PCIE1, PCIE1, PCIE2, SATA1} },
+ {0x1455, {XFI_FM1_MAC9, QSGMII_FM1_A, PCIE2, PCIE3} },
+ {0x2455, {SGMII_2500_FM1_DTSEC9, QSGMII_FM1_A, PCIE2, PCIE3} },
+ {0x2255, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC2, PCIE2, PCIE3} },
+ {0x3333, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC2, SGMII_FM1_DTSEC5,
+ SGMII_FM1_DTSEC6} },
+ {}
+};
+
+static struct serdes_config *serdes_cfg_tbl[] = {
+ serdes1_cfg_tbl,
+};
+
+enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
+{
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == cfg)
+ return ptr->lanes[lane];
+ ptr++;
+ }
+
+ return 0;
+}
+
+int is_serdes_prtcl_valid(int serdes, u32 prtcl)
+{
+ int i;
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == prtcl)
+ break;
+ ptr++;
+ }
+
+ if (!ptr->protocol)
+ return 0;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (ptr->lanes[i] != NONE)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1046_ids.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1046_ids.c
new file mode 100644
index 000000000..abd847b5b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1046_ids.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <common.h>
+#include <asm/arch-fsl-layerscape/immap_lsch2.h>
+#include <asm/arch-fsl-layerscape/fsl_icid.h>
+#include <asm/arch-fsl-layerscape/fsl_portals.h>
+
+#ifdef CONFIG_SYS_DPAA_QBMAN
+struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+ SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
+};
+#endif
+
+struct icid_id_table icid_tbl[] = {
+#ifdef CONFIG_SYS_DPAA_QBMAN
+ SET_QMAN_ICID(FSL_DPAA1_STREAM_ID_START),
+ SET_BMAN_ICID(FSL_DPAA1_STREAM_ID_START + 1),
+#endif
+
+ SET_SDHC_ICID(FSL_SDHC_STREAM_ID),
+
+ SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
+ SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
+ SET_USB_ICID(3, "snps,dwc3", FSL_USB3_STREAM_ID),
+
+ SET_SATA_ICID("fsl,ls1046a-ahci", FSL_SATA_STREAM_ID),
+ SET_QDMA_ICID("fsl,ls1046a-qdma", FSL_QDMA_STREAM_ID),
+ SET_EDMA_ICID(FSL_EDMA_STREAM_ID),
+ SET_ETR_ICID(FSL_ETR_STREAM_ID),
+ SET_DEBUG_ICID(FSL_DEBUG_STREAM_ID),
+#ifdef CONFIG_FSL_CAAM
+ SET_SEC_QI_ICID(FSL_DPAA1_STREAM_ID_END),
+ SET_SEC_JR_ICID_ENTRY(0, FSL_DPAA1_STREAM_ID_START + 3),
+ SET_SEC_JR_ICID_ENTRY(1, FSL_DPAA1_STREAM_ID_START + 4),
+ SET_SEC_JR_ICID_ENTRY(2, FSL_DPAA1_STREAM_ID_START + 5),
+ SET_SEC_JR_ICID_ENTRY(3, FSL_DPAA1_STREAM_ID_START + 6),
+ SET_SEC_RTIC_ICID_ENTRY(0, FSL_DPAA1_STREAM_ID_START + 7),
+ SET_SEC_RTIC_ICID_ENTRY(1, FSL_DPAA1_STREAM_ID_START + 8),
+ SET_SEC_RTIC_ICID_ENTRY(2, FSL_DPAA1_STREAM_ID_START + 9),
+ SET_SEC_RTIC_ICID_ENTRY(3, FSL_DPAA1_STREAM_ID_START + 10),
+ SET_SEC_DECO_ICID_ENTRY(0, FSL_DPAA1_STREAM_ID_START + 11),
+ SET_SEC_DECO_ICID_ENTRY(1, FSL_DPAA1_STREAM_ID_START + 12),
+ SET_SEC_DECO_ICID_ENTRY(2, FSL_DPAA1_STREAM_ID_START + 13),
+#endif
+};
+
+int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+struct fman_icid_id_table fman_icid_tbl[] = {
+ /* port id, icid */
+ SET_FMAN_ICID_ENTRY(0x02, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x03, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x04, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x05, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x06, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x07, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x08, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x09, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x0a, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x0b, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x0c, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x0d, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x28, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x29, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x2a, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x2b, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x2c, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x2d, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x10, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x11, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x30, FSL_DPAA1_STREAM_ID_END),
+ SET_FMAN_ICID_ENTRY(0x31, FSL_DPAA1_STREAM_ID_END),
+};
+
+int fman_icid_tbl_sz = ARRAY_SIZE(fman_icid_tbl);
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1046a_serdes.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1046a_serdes.c
new file mode 100644
index 000000000..9347e516b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1046a_serdes.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2019 NXP
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/immap_lsch2.h>
+
+struct serdes_config {
+ u32 protocol;
+ u8 lanes[SRDS_MAX_LANES];
+};
+
+static struct serdes_config serdes1_cfg_tbl[] = {
+ /* SerDes 1 */
+ {0x3333, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC5,
+ SGMII_FM1_DTSEC6} },
+ {0x1133, {XFI_FM1_MAC9, XFI_FM1_MAC10, SGMII_FM1_DTSEC5,
+ SGMII_FM1_DTSEC6} },
+ {0x1333, {XFI_FM1_MAC9, SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC5,
+ SGMII_FM1_DTSEC6} },
+ {0x2333, {SGMII_2500_FM1_DTSEC9, SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC5,
+ SGMII_FM1_DTSEC6} },
+ {0x2233, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC10,
+ SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6} },
+ {0x1040, {XFI_FM1_MAC9, NONE, QSGMII_FM1_A, NONE} },
+ {0x2040, {SGMII_2500_FM1_DTSEC9, NONE, QSGMII_FM1_A, NONE} },
+ {0x1163, {XFI_FM1_MAC9, XFI_FM1_MAC10, PCIE1, SGMII_FM1_DTSEC6} },
+ {0x2263, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC10, PCIE1,
+ SGMII_FM1_DTSEC6} },
+ {0x3363, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC10, PCIE1,
+ SGMII_FM1_DTSEC6} },
+ {0x2223, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC10,
+ SGMII_2500_FM1_DTSEC5, SGMII_FM1_DTSEC6} },
+ {0x3040, {SGMII_FM1_DTSEC9, NONE, QSGMII_FM1_A, NONE} },
+ {}
+};
+
+static struct serdes_config serdes2_cfg_tbl[] = {
+ /* SerDes 2 */
+ {0x8888, {PCIE1, PCIE1, PCIE1, PCIE1} },
+ {0x5559, {PCIE1, PCIE2, PCIE3, SATA1} },
+ {0x5577, {PCIE1, PCIE2, PCIE3, PCIE3} },
+ {0x5506, {PCIE1, PCIE2, NONE, PCIE3} },
+ {0x0506, {NONE, PCIE2, NONE, PCIE3} },
+ {0x0559, {NONE, PCIE2, PCIE3, SATA1} },
+ {0x5A59, {PCIE1, SGMII_FM1_DTSEC2, PCIE3, SATA1} },
+ {0x5A06, {PCIE1, SGMII_FM1_DTSEC2, NONE, PCIE3} },
+ {}
+};
+
+static struct serdes_config *serdes_cfg_tbl[] = {
+ serdes1_cfg_tbl,
+ serdes2_cfg_tbl,
+};
+
+enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
+{
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == cfg)
+ return ptr->lanes[lane];
+ ptr++;
+ }
+
+ return 0;
+}
+
+int is_serdes_prtcl_valid(int serdes, u32 prtcl)
+{
+ int i;
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == prtcl)
+ break;
+ ptr++;
+ }
+
+ if (!ptr->protocol)
+ return 0;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (ptr->lanes[i] != NONE)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1088_ids.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1088_ids.c
new file mode 100644
index 000000000..23743ae10
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1088_ids.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ */
+
+#include <common.h>
+#include <asm/arch-fsl-layerscape/immap_lsch3.h>
+#include <asm/arch-fsl-layerscape/fsl_icid.h>
+#include <asm/arch-fsl-layerscape/fsl_portals.h>
+
+struct icid_id_table icid_tbl[] = {
+ SET_SDHC_ICID(1, FSL_SDMMC_STREAM_ID),
+ SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
+ SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
+ SET_SATA_ICID(1, "fsl,ls1088a-ahci", FSL_SATA1_STREAM_ID),
+#ifdef CONFIG_FSL_CAAM
+ SET_SEC_JR_ICID_ENTRY(0, FSL_SEC_JR1_STREAM_ID),
+ SET_SEC_JR_ICID_ENTRY(1, FSL_SEC_JR2_STREAM_ID),
+ SET_SEC_JR_ICID_ENTRY(2, FSL_SEC_JR3_STREAM_ID),
+ SET_SEC_JR_ICID_ENTRY(3, FSL_SEC_JR4_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
+#endif
+};
+
+int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1088a_serdes.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1088a_serdes.c
new file mode 100644
index 000000000..280afbbf9
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls1088a_serdes.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017-2019 NXP
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/soc.h>
+#include <asm/io.h>
+
+struct serdes_config {
+ u8 ip_protocol;
+ u8 lanes[SRDS_MAX_LANES];
+ u8 rcw_lanes[SRDS_MAX_LANES];
+};
+
+static struct serdes_config serdes1_cfg_tbl[] = {
+ /* SerDes 1 */
+ {0x12, {SGMII3, SGMII7, SGMII1, SGMII2 }, {3, 3, 3, 3 } },
+ {0x15, {SGMII3, SGMII7, XFI1, XFI2 }, {3, 3, 1, 1 } },
+ {0x16, {SGMII3, SGMII7, SGMII1, XFI2 }, {3, 3, 3, 1 } },
+ {0x17, {SGMII3, SGMII7, SGMII1, SGMII2 }, {3, 3, 3, 2 } },
+ {0x18, {SGMII3, SGMII7, SGMII1, SGMII2 }, {3, 3, 2, 2 } },
+ {0x19, {SGMII3, QSGMII_B, XFI1, XFI2}, {3, 4, 1, 1 } },
+ {0x1A, {SGMII3, QSGMII_B, SGMII1, XFI2 }, {3, 4, 3, 1 } },
+ {0x1B, {SGMII3, QSGMII_B, SGMII1, SGMII2 }, {3, 4, 3, 2 } },
+ {0x1C, {SGMII3, QSGMII_B, SGMII1, SGMII2 }, {3, 4, 2, 2 } },
+ {0x1D, {QSGMII_A, QSGMII_B, XFI1, XFI2 }, {4, 4, 1, 1 } },
+ {0x1E, {QSGMII_A, QSGMII_B, SGMII1, XFI2 }, {4, 4, 3, 1 } },
+ {0x1F, {QSGMII_A, QSGMII_B, SGMII1, SGMII2 }, {4, 4, 3, 2 } },
+ {0x20, {QSGMII_A, QSGMII_B, SGMII1, SGMII2 }, {4, 4, 2, 2 } },
+ {0x35, {SGMII3, QSGMII_B, SGMII1, SGMII2 }, {3, 4, 3, 3 } },
+ {0x36, {QSGMII_A, QSGMII_B, SGMII1, SGMII2 }, {4, 4, 3, 3 } },
+ {0x3A, {SGMII3, PCIE1, SGMII1, SGMII2 }, {3, 5, 3, 3 } },
+ {}
+};
+
+static struct serdes_config serdes2_cfg_tbl[] = {
+ /* SerDes 2 */
+ {0x0C, {PCIE1, PCIE1, PCIE1, PCIE1 }, {8, 8, 8, 8 } },
+ {0x0D, {PCIE1, PCIE2, PCIE3, SATA1 }, {5, 5, 5, 9 } },
+ {0x0E, {PCIE1, PCIE1, PCIE2, SATA1 }, {7, 7, 6, 9 } },
+ {0x13, {PCIE1, PCIE1, PCIE3, PCIE3 }, {7, 7, 7, 7 } },
+ {0x14, {PCIE1, PCIE2, PCIE3, PCIE3 }, {5, 5, 7, 7 } },
+ {0x3C, {NONE, PCIE2, NONE, PCIE3 }, {0, 5, 0, 6 } },
+ {}
+};
+
+static struct serdes_config *serdes_cfg_tbl[] = {
+ serdes1_cfg_tbl,
+ serdes2_cfg_tbl,
+};
+
+bool soc_has_mac1(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ unsigned int svr = gur_in32(&gur->svr);
+ unsigned int version = SVR_SOC_VER(svr);
+
+ return (version == SVR_LS1088A || version == SVR_LS1084A);
+}
+
+int serdes_get_number(int serdes, int cfg)
+{
+ struct serdes_config *ptr;
+ int i, j, index, lnk;
+ int is_found, max_lane = SRDS_MAX_LANES;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+
+ while (ptr->ip_protocol) {
+ is_found = 1;
+ for (i = 0, j = max_lane - 1; i < max_lane; i++, j--) {
+ lnk = cfg & (0xf << 4 * i);
+ lnk = lnk >> (4 * i);
+
+ index = (serdes == FSL_SRDS_1) ? j : i;
+
+ if (ptr->rcw_lanes[index] == lnk && is_found)
+ is_found = 1;
+ else
+ is_found = 0;
+ }
+
+ if (is_found)
+ return ptr->ip_protocol;
+ ptr++;
+ }
+
+ return 0;
+}
+
+enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
+{
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+ /*
+ * LS1044A/1048A support only one XFI port
+ * Disable MAC1 for LS1044A/1048A
+ */
+ if (serdes == FSL_SRDS_1 && lane == 2) {
+ if (!soc_has_mac1())
+ return 0;
+ }
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->ip_protocol) {
+ if (ptr->ip_protocol == cfg)
+ return ptr->lanes[lane];
+ ptr++;
+ }
+
+ return 0;
+}
+
+int is_serdes_prtcl_valid(int serdes, u32 prtcl)
+{
+ int i;
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->ip_protocol) {
+ if (ptr->ip_protocol == prtcl)
+ break;
+ ptr++;
+ }
+
+ if (!ptr->ip_protocol)
+ return 0;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (ptr->lanes[i] != NONE)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls2080a_serdes.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls2080a_serdes.c
new file mode 100644
index 000000000..799742284
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls2080a_serdes.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014-2015 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+
+struct serdes_config {
+ u8 protocol;
+ u8 lanes[SRDS_MAX_LANES];
+};
+
+static struct serdes_config serdes1_cfg_tbl[] = {
+ /* SerDes 1 */
+ {0x03, {PCIE2, PCIE2, PCIE2, PCIE2, PCIE1, PCIE1, PCIE1, PCIE1 } },
+ {0x05, {PCIE2, PCIE2, PCIE2, PCIE2, SGMII4, SGMII3, SGMII2, SGMII1 } },
+ {0x07, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
+ SGMII1 } },
+ {0x09, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
+ SGMII1 } },
+ {0x0A, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
+ SGMII1 } },
+ {0x0C, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
+ SGMII1 } },
+ {0x0E, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
+ SGMII1 } },
+ {0x26, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, XFI2, XFI1 } },
+ {0x28, {SGMII8, SGMII7, SGMII6, SGMII5, XFI4, XFI3, XFI2, XFI1 } },
+ {0x2A, {XFI8, XFI7, XFI6, XFI5, XFI4, XFI3, XFI2, XFI1 } },
+ {0x2B, {SGMII8, SGMII7, SGMII6, SGMII5, XAUI1, XAUI1, XAUI1, XAUI1 } },
+ {0x32, {XAUI2, XAUI2, XAUI2, XAUI2, XAUI1, XAUI1, XAUI1, XAUI1 } },
+ {0x33, {PCIE2, PCIE2, PCIE2, PCIE2, QSGMII_D, QSGMII_C, QSGMII_B,
+ QSGMII_A} },
+ {0x35, {QSGMII_D, QSGMII_C, QSGMII_B, PCIE2, XFI4, XFI3, XFI2, XFI1 } },
+ {0x39, {SGMII8, SGMII7, SGMII6, PCIE2, SGMII4, SGMII3, SGMII2,
+ PCIE1 } },
+ {0x3B, {XFI8, XFI7, XFI6, PCIE2, XFI4, XFI3, XFI2, PCIE1 } },
+ {0x4B, {PCIE2, PCIE2, PCIE2, PCIE2, XFI4, XFI3, XFI2, XFI1 } },
+ {0x4C, {XFI8, XFI7, XFI6, XFI5, PCIE1, PCIE1, PCIE1, PCIE1 } },
+ {0x4D, {SGMII8, SGMII7, PCIE2, PCIE2, SGMII4, SGMII3, PCIE1, PCIE1 } },
+ {}
+};
+static struct serdes_config serdes2_cfg_tbl[] = {
+ /* SerDes 2 */
+ {0x07, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
+ SGMII16 } },
+ {0x09, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
+ SGMII16 } },
+ {0x0A, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
+ SGMII16 } },
+ {0x0C, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
+ SGMII16 } },
+ {0x0E, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
+ SGMII16 } },
+ {0x3D, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3 } },
+ {0x3E, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3 } },
+ {0x3F, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } },
+ {0x40, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } },
+ {0x41, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SATA1, SATA2 } },
+ {0x42, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SATA1, SATA2 } },
+ {0x43, {PCIE3, PCIE3, PCIE3, PCIE3, NONE, NONE, SATA1, SATA2 } },
+ {0x44, {PCIE3, PCIE3, PCIE3, PCIE3, NONE, NONE, SATA1, SATA2 } },
+ {0x45, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, PCIE4,
+ PCIE4 } },
+ {0x47, {PCIE3, SGMII10, SGMII11, SGMII12, PCIE4, SGMII14, SGMII15,
+ SGMII16 } },
+ {0x49, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, SATA1,
+ SATA2 } },
+ {0x4A, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, SATA1,
+ SATA2 } },
+ {0x51, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } },
+ {0x57, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SGMII15, SGMII16 } },
+ {}
+};
+
+static struct serdes_config *serdes_cfg_tbl[] = {
+ serdes1_cfg_tbl,
+ serdes2_cfg_tbl,
+};
+
+enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
+{
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == cfg)
+ return ptr->lanes[lane];
+ ptr++;
+ }
+
+ return 0;
+}
+
+int is_serdes_prtcl_valid(int serdes, u32 prtcl)
+{
+ int i;
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == prtcl)
+ break;
+ ptr++;
+ }
+
+ if (!ptr->protocol)
+ return 0;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (ptr->lanes[i] != NONE)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls2088_ids.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls2088_ids.c
new file mode 100644
index 000000000..e6403b795
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ls2088_ids.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ */
+
+#include <common.h>
+#include <asm/arch-fsl-layerscape/immap_lsch3.h>
+#include <asm/arch-fsl-layerscape/fsl_icid.h>
+#include <asm/arch-fsl-layerscape/fsl_portals.h>
+
+struct icid_id_table icid_tbl[] = {
+ SET_SDHC_ICID(1, FSL_SDMMC_STREAM_ID),
+ SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
+ SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
+ SET_SATA_ICID(1, "fsl,ls2080a-ahci", FSL_SATA1_STREAM_ID),
+ SET_SATA_ICID(2, "fsl,ls2080a-ahci", FSL_SATA2_STREAM_ID),
+#ifdef CONFIG_FSL_CAAM
+ SET_SEC_JR_ICID_ENTRY(0, FSL_SEC_JR1_STREAM_ID),
+ SET_SEC_JR_ICID_ENTRY(1, FSL_SEC_JR2_STREAM_ID),
+ SET_SEC_JR_ICID_ENTRY(2, FSL_SEC_JR3_STREAM_ID),
+ SET_SEC_JR_ICID_ENTRY(3, FSL_SEC_JR4_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(4, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(5, FSL_SEC_STREAM_ID),
+#endif
+};
+
+int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/lx2160_ids.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/lx2160_ids.c
new file mode 100644
index 000000000..3a0ed1fa5
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/lx2160_ids.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ */
+
+#include <common.h>
+#include <asm/arch-fsl-layerscape/immap_lsch3.h>
+#include <asm/arch-fsl-layerscape/fsl_icid.h>
+#include <asm/arch-fsl-layerscape/fsl_portals.h>
+
+struct icid_id_table icid_tbl[] = {
+ SET_SDHC_ICID(1, FSL_SDMMC_STREAM_ID),
+ SET_SDHC_ICID(2, FSL_SDMMC2_STREAM_ID),
+ SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
+ SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
+ SET_SATA_ICID(1, "fsl,lx2160a-ahci", FSL_SATA1_STREAM_ID),
+ SET_SATA_ICID(2, "fsl,lx2160a-ahci", FSL_SATA2_STREAM_ID),
+ SET_SATA_ICID(3, "fsl,lx2160a-ahci", FSL_SATA3_STREAM_ID),
+ SET_SATA_ICID(4, "fsl,lx2160a-ahci", FSL_SATA4_STREAM_ID),
+#ifdef CONFIG_FSL_CAAM
+ SET_SEC_JR_ICID_ENTRY(0, FSL_SEC_JR1_STREAM_ID),
+ SET_SEC_JR_ICID_ENTRY(1, FSL_SEC_JR2_STREAM_ID),
+ SET_SEC_JR_ICID_ENTRY(2, FSL_SEC_JR3_STREAM_ID),
+ SET_SEC_JR_ICID_ENTRY(3, FSL_SEC_JR4_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
+ SET_SEC_RTIC_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(4, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(5, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(6, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(7, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(8, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(9, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(10, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(11, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(12, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(13, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(14, FSL_SEC_STREAM_ID),
+ SET_SEC_DECO_ICID_ENTRY(15, FSL_SEC_STREAM_ID),
+#endif
+};
+
+int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/lx2160a_serdes.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/lx2160a_serdes.c
new file mode 100644
index 000000000..5941d90e0
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/lx2160a_serdes.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018, 2020 NXP
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+
+struct serdes_config {
+ u8 protocol;
+ u8 lanes[SRDS_MAX_LANES];
+};
+
+#if defined(CONFIG_ARCH_LX2162A)
+static struct serdes_config serdes1_cfg_tbl[] = {
+ /* SerDes 1 */
+ {0x01, {PCIE1, PCIE1, PCIE1, PCIE1 } },
+ {0x02, {SGMII6, SGMII5, SGMII4, SGMII3 } },
+ {0x03, {XFI6, XFI5, XFI4, XFI3 } },
+ {0x09, {SGMII6, SGMII5, SGMII4, PCIE1 } },
+ {0x0B, {SGMII6, SGMII5, PCIE1, PCIE1 } },
+ {0x0F, {_50GE2, _50GE2, _50GE1, _50GE1 } },
+ {0x10, {_25GE6, _25GE5, _50GE1, _50GE1 } },
+ {0x11, {_25GE6, _25GE5, _25GE4, _25GE3 } },
+ {0x12, {_25GE6, _25GE5, XFI4, XFI3 } },
+ {0x14, {_40GE1, _40GE1, _40GE1, _40GE1 } },
+ {}
+};
+#else
+static struct serdes_config serdes1_cfg_tbl[] = {
+ /* SerDes 1 */
+ {0x01, {PCIE2, PCIE2, PCIE2, PCIE2, PCIE1, PCIE1, PCIE1, PCIE1 } },
+ {0x02, {PCIE2, PCIE2, PCIE2, PCIE2, SGMII6, SGMII5, SGMII4, SGMII3 } },
+ {0x03, {PCIE2, PCIE2, PCIE2, PCIE2, XFI6, XFI5, XFI4,
+ XFI3 } },
+ {0x04, {SGMII10, SGMII9, SGMII8, SGMII7, SGMII6, SGMII5, SGMII4,
+ SGMII3 } },
+ {0x05, {XFI10, XFI9, XFI8, XFI7, PCIE1, PCIE1, PCIE1,
+ PCIE1 } },
+ {0x06, {SGMII10, SGMII9, SGMII8, SGMII7, SGMII6, SGMII5, XFI4,
+ XFI3 } },
+ {0x07, {SGMII10, SGMII9, SGMII8, SGMII7, XFI6, XFI5, XFI4,
+ XFI3 } },
+ {0x08, {XFI10, XFI9, XFI8, XFI7, XFI6, XFI5, XFI4, XFI3 } },
+ {0x09, {SGMII10, SGMII9, SGMII8, PCIE2, SGMII6, SGMII5, SGMII4,
+ PCIE1 } },
+ {0x0A, {XFI10, XFI9, XFI8, PCIE2, XFI6, XFI5, XFI4, PCIE1 } },
+ {0x0B, {SGMII10, SGMII9, PCIE2, PCIE2, SGMII6, SGMII5, PCIE1, PCIE1 } },
+ {0x0C, {SGMII10, SGMII9, PCIE2, PCIE2, PCIE1, PCIE1, PCIE1, PCIE1 } },
+ {0x0D, {_100GE2, _100GE2, _100GE2, _100GE2, _100GE1, _100GE1, _100GE1,
+ _100GE1 } },
+ {0x0E, {PCIE2, PCIE2, PCIE2, PCIE2, _100GE1, _100GE1, _100GE1,
+ _100GE1 } },
+ {0x0F, {PCIE2, PCIE2, PCIE2, PCIE2, _50GE2, _50GE2, _50GE1, _50GE1 } },
+ {0x10, {PCIE2, PCIE2, PCIE2, PCIE2, _25GE6, _25GE5, _50GE1, _50GE1 } },
+ {0x11, {PCIE2, PCIE2, PCIE2, PCIE2, _25GE6, _25GE5, _25GE4, _25GE3 } },
+ {0x12, {XFI10, XFI9, XFI8, XFI7, _25GE6, _25GE5, XFI4,
+ XFI3 } },
+ {0x13, {_40GE2, _40GE2, _40GE2, _40GE2, _25GE6, _25GE5, XFI4, XFI3 } },
+ {0x14, {_40GE2, _40GE2, _40GE2, _40GE2, _40GE1, _40GE1, _40GE1,
+ _40GE1 } },
+ {0x15, {_25GE10, _25GE9, PCIE2, PCIE2, _25GE6, _25GE5, _25GE4,
+ _25GE3 } },
+ {0x16, {XFI10, XFI9, PCIE2, PCIE2, XFI6, XFI5, XFI4, XFI3 } },
+ {}
+};
+#endif
+
+static struct serdes_config serdes2_cfg_tbl[] = {
+ /* SerDes 2 */
+ {0x01, {PCIE3, PCIE3, SATA1, SATA2, PCIE4, PCIE4, PCIE4, PCIE4 } },
+ {0x02, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3 } },
+ {0x03, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } },
+ {0x04, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SATA1, SATA2 } },
+ {0x05, {PCIE3, PCIE3, PCIE3, PCIE3, SATA3, SATA4, SATA1, SATA2 } },
+ {0x06, {PCIE3, PCIE3, PCIE3, PCIE3, SGMII15, SGMII16, XFI13,
+ XFI14 } },
+ {0x07, {PCIE3, SGMII12, SGMII17, SGMII18, PCIE4, SGMII16, XFI13,
+ XFI14 } },
+ {0x08, {NONE, NONE, SATA1, SATA2, SATA3, SATA4, XFI13, XFI14 } },
+ {0x09, {SGMII11, SGMII12, SGMII17, SGMII18, SGMII15, SGMII16, SGMII13,
+ SGMII14} },
+ {0x0A, {SGMII11, SGMII12, SGMII17, SGMII18, PCIE4, PCIE4, PCIE4,
+ PCIE4 } },
+ {0x0B, {PCIE3, SGMII12, SGMII17, SGMII18, PCIE4, SGMII16, SGMII13,
+ SGMII14 } },
+ {0x0C, {SGMII11, SGMII12, SGMII17, SGMII18, PCIE4, PCIE4, SATA1,
+ SATA2 } },
+ {0x0D, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SGMII13, SGMII14 } },
+ {0x0E, {PCIE3, PCIE3, SGMII17, SGMII18, PCIE4, PCIE4, SGMII13,
+ SGMII14 } },
+ {}
+};
+
+static struct serdes_config serdes3_cfg_tbl[] = {
+ /* SerDes 3 */
+ {0x02, {PCIE5, PCIE5, PCIE5, PCIE5, PCIE5, PCIE5, PCIE5, PCIE5 } },
+ {0x03, {PCIE5, PCIE5, PCIE5, PCIE5, PCIE6, PCIE6, PCIE6, PCIE6 } },
+ {}
+};
+
+static struct serdes_config *serdes_cfg_tbl[] = {
+ serdes1_cfg_tbl,
+ serdes2_cfg_tbl,
+ serdes3_cfg_tbl,
+};
+
+enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
+{
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == cfg)
+ return ptr->lanes[lane];
+ ptr++;
+ }
+
+ return 0;
+}
+
+int is_serdes_prtcl_valid(int serdes, u32 prtcl)
+{
+ int i;
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == prtcl)
+ break;
+ ptr++;
+ }
+
+ if (!ptr->protocol)
+ return 0;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (ptr->lanes[i] != NONE)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/mp.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/mp.c
new file mode 100644
index 000000000..730d7663d
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/mp.c
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014-2015 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <image.h>
+#include <log.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/arch/mp.h>
+#include <asm/arch/soc.h>
+#include <linux/delay.h>
+#include <linux/psci.h>
+#include "cpu.h"
+#include <asm/arch-fsl-layerscape/soc.h>
+#include <efi_loader.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void *get_spin_tbl_addr(void)
+{
+ /* the spin table is at the beginning */
+ return secondary_boot_code_start;
+}
+
+void update_os_arch_secondary_cores(uint8_t os_arch)
+{
+ u64 *table = get_spin_tbl_addr();
+ int i;
+
+ for (i = 1; i < CONFIG_MAX_CPUS; i++) {
+ if (os_arch == IH_ARCH_DEFAULT)
+ table[i * WORDS_PER_SPIN_TABLE_ENTRY +
+ SPIN_TABLE_ELEM_ARCH_COMP_IDX] = OS_ARCH_SAME;
+ else
+ table[i * WORDS_PER_SPIN_TABLE_ENTRY +
+ SPIN_TABLE_ELEM_ARCH_COMP_IDX] = OS_ARCH_DIFF;
+ }
+}
+
+#ifdef CONFIG_FSL_LSCH3
+static void wake_secondary_core_n(int cluster, int core, int cluster_cores)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ struct ccsr_reset __iomem *rst = (void *)(CONFIG_SYS_FSL_RST_ADDR);
+ u32 mpidr = 0;
+
+ mpidr = ((cluster << 8) | core);
+ /*
+ * mpidr_el1 register value of core which needs to be released
+ * is written to scratchrw[6] register
+ */
+ gur_out32(&gur->scratchrw[6], mpidr);
+ asm volatile("dsb st" : : : "memory");
+ rst->brrl |= 1 << ((cluster * cluster_cores) + core);
+ asm volatile("dsb st" : : : "memory");
+ /*
+ * scratchrw[6] register value is polled
+ * when the value becomes zero, this means that this core is up
+ * and running, next core can be released now
+ */
+ while (gur_in32(&gur->scratchrw[6]) != 0)
+ ;
+}
+#endif
+
+int fsl_layerscape_wake_seconday_cores(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+#ifdef CONFIG_FSL_LSCH3
+ struct ccsr_reset __iomem *rst = (void *)(CONFIG_SYS_FSL_RST_ADDR);
+ u32 svr, ver, cluster, type;
+ int j = 0, cluster_cores = 0;
+#elif defined(CONFIG_FSL_LSCH2)
+ struct ccsr_scfg __iomem *scfg = (void *)(CONFIG_SYS_FSL_SCFG_ADDR);
+#endif
+ u32 cores, cpu_up_mask = 1;
+ int i, timeout = 10;
+ u64 *table;
+#ifdef CONFIG_EFI_LOADER
+ u64 reloc_addr = U32_MAX;
+ efi_status_t ret;
+#endif
+
+#ifdef COUNTER_FREQUENCY_REAL
+ /* update for secondary cores */
+ __real_cntfrq = COUNTER_FREQUENCY_REAL;
+ flush_dcache_range((unsigned long)&__real_cntfrq,
+ (unsigned long)&__real_cntfrq + 8);
+#endif
+
+#ifdef CONFIG_EFI_LOADER
+ /*
+ * EFI will reserve 64kb for its runtime services. This will probably
+ * overlap with our spin table code, which is why we have to relocate
+ * it.
+ * Keep this after the __real_cntfrq update, so we have it when we
+ * copy the complete section here.
+ */
+ ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+ EFI_RESERVED_MEMORY_TYPE,
+ efi_size_in_pages(secondary_boot_code_size),
+ &reloc_addr);
+ if (ret == EFI_SUCCESS) {
+ debug("Relocating spin table from %llx to %llx (size %lx)\n",
+ (u64)secondary_boot_code_start, reloc_addr,
+ secondary_boot_code_size);
+ memcpy((void *)reloc_addr, secondary_boot_code_start,
+ secondary_boot_code_size);
+ flush_dcache_range(reloc_addr,
+ reloc_addr + secondary_boot_code_size);
+
+ /* set new entry point for secondary cores */
+ secondary_boot_addr += (void *)reloc_addr -
+ secondary_boot_code_start;
+ flush_dcache_range((unsigned long)&secondary_boot_addr,
+ (unsigned long)&secondary_boot_addr + 8);
+
+ /* this will be used to reserve the memory */
+ secondary_boot_code_start = (void *)reloc_addr;
+ }
+#endif
+
+ cores = cpu_mask();
+ /* Clear spin table so that secondary processors
+ * observe the correct value after waking up from wfe.
+ */
+ table = get_spin_tbl_addr();
+ memset(table, 0, CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE);
+ flush_dcache_range((unsigned long)table,
+ (unsigned long)table +
+ (CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE));
+
+ debug("Waking secondary cores to start from %lx\n", gd->relocaddr);
+
+#ifdef CONFIG_FSL_LSCH3
+ gur_out32(&gur->bootlocptrh, (u32)(gd->relocaddr >> 32));
+ gur_out32(&gur->bootlocptrl, (u32)gd->relocaddr);
+
+ svr = gur_in32(&gur->svr);
+ ver = SVR_SOC_VER(svr);
+ if (ver == SVR_LS2080A || ver == SVR_LS2085A) {
+ gur_out32(&gur->scratchrw[6], 1);
+ asm volatile("dsb st" : : : "memory");
+ rst->brrl = cores;
+ asm volatile("dsb st" : : : "memory");
+ } else {
+ /*
+ * Release the cores out of reset one-at-a-time to avoid
+ * power spikes
+ */
+ i = 0;
+ cluster = in_le32(&gur->tp_cluster[i].lower);
+ for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
+ type = initiator_type(cluster, j);
+ if (type &&
+ TP_ITYP_TYPE(type) == TP_ITYP_TYPE_ARM)
+ cluster_cores++;
+ }
+
+ do {
+ cluster = in_le32(&gur->tp_cluster[i].lower);
+ for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
+ type = initiator_type(cluster, j);
+ if (type &&
+ TP_ITYP_TYPE(type) == TP_ITYP_TYPE_ARM)
+ wake_secondary_core_n(i, j,
+ cluster_cores);
+ }
+ i++;
+ } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC);
+ }
+#elif defined(CONFIG_FSL_LSCH2)
+ scfg_out32(&scfg->scratchrw[0], (u32)(gd->relocaddr >> 32));
+ scfg_out32(&scfg->scratchrw[1], (u32)gd->relocaddr);
+ asm volatile("dsb st" : : : "memory");
+ gur_out32(&gur->brrl, cores);
+ asm volatile("dsb st" : : : "memory");
+
+ /* Bootup online cores */
+ scfg_out32(&scfg->corebcr, cores);
+#endif
+ /* This is needed as a precautionary measure.
+ * If some code before this has accidentally released the secondary
+ * cores then the pre-bootloader code will trap them in a "wfe" unless
+ * the scratchrw[6] is set. In this case we need a sev here to get these
+ * cores moving again.
+ */
+ asm volatile("sev");
+
+ while (timeout--) {
+ flush_dcache_range((unsigned long)table, (unsigned long)table +
+ CONFIG_MAX_CPUS * 64);
+ for (i = 1; i < CONFIG_MAX_CPUS; i++) {
+ if (table[i * WORDS_PER_SPIN_TABLE_ENTRY +
+ SPIN_TABLE_ELEM_STATUS_IDX])
+ cpu_up_mask |= 1 << i;
+ }
+ if (hweight32(cpu_up_mask) == hweight32(cores))
+ break;
+ udelay(10);
+ }
+ if (timeout <= 0) {
+ printf("CPU: Failed to bring up some cores (mask 0x%x)\n",
+ cores ^ cpu_up_mask);
+ return 1;
+ }
+ printf("CPU: %d cores online\n", hweight32(cores));
+
+ return 0;
+}
+
+int is_core_valid(unsigned int core)
+{
+ return !!((1 << core) & cpu_mask());
+}
+
+static int is_pos_valid(unsigned int pos)
+{
+ return !!((1 << pos) & cpu_pos_mask());
+}
+
+int is_core_online(u64 cpu_id)
+{
+ u64 *table = get_spin_tbl_addr();
+ int pos = id_to_core(cpu_id);
+ table += pos * WORDS_PER_SPIN_TABLE_ENTRY;
+ return table[SPIN_TABLE_ELEM_STATUS_IDX] == 1;
+}
+
+int cpu_reset(u32 nr)
+{
+ puts("Feature is not implemented.\n");
+
+ return 0;
+}
+
+int cpu_disable(u32 nr)
+{
+ puts("Feature is not implemented.\n");
+
+ return 0;
+}
+
+static int core_to_pos(int nr)
+{
+ u32 cores = cpu_pos_mask();
+ int i, count = 0;
+
+ if (nr == 0) {
+ return 0;
+ } else if (nr >= hweight32(cores)) {
+ puts("Not a valid core number.\n");
+ return -1;
+ }
+
+ for (i = 1; i < 32; i++) {
+ if (is_pos_valid(i)) {
+ count++;
+ if (count == nr)
+ break;
+ }
+ }
+
+ if (count != nr)
+ return -1;
+
+ return i;
+}
+
+int cpu_status(u32 nr)
+{
+ u64 *table = get_spin_tbl_addr();
+ int pos;
+
+ if (nr == 0) {
+ printf("table base @ 0x%p\n", table);
+ } else {
+ pos = core_to_pos(nr);
+ if (pos < 0)
+ return -1;
+ table += pos * WORDS_PER_SPIN_TABLE_ENTRY;
+ printf("table @ 0x%p\n", table);
+ printf(" addr - 0x%016llx\n",
+ table[SPIN_TABLE_ELEM_ENTRY_ADDR_IDX]);
+ printf(" status - 0x%016llx\n",
+ table[SPIN_TABLE_ELEM_STATUS_IDX]);
+ printf(" lpid - 0x%016llx\n",
+ table[SPIN_TABLE_ELEM_LPID_IDX]);
+ }
+
+ return 0;
+}
+
+int cpu_release(u32 nr, int argc, char *const argv[])
+{
+ u64 boot_addr;
+ u64 *table = get_spin_tbl_addr();
+ int pos;
+
+ boot_addr = simple_strtoull(argv[0], NULL, 16);
+
+ if (check_psci()) {
+ /* SPIN Table is used */
+ pos = core_to_pos(nr);
+ if (pos <= 0)
+ return -1;
+
+ table += pos * WORDS_PER_SPIN_TABLE_ENTRY;
+ table[SPIN_TABLE_ELEM_ENTRY_ADDR_IDX] = boot_addr;
+ flush_dcache_range((unsigned long)table,
+ (unsigned long)table + SPIN_TABLE_ELEM_SIZE);
+ asm volatile("dsb st");
+
+ /*
+ * The secondary CPUs polling the spin-table above for a non-zero
+ * value. To save power "wfe" is called. Thus call "sev" here to
+ * wake the CPUs and let them check the spin-table again (see
+ * slave_cpu loop in lowlevel.S)
+ */
+ asm volatile("sev");
+ } else {
+ /* Use PSCI to kick the core */
+ struct pt_regs regs;
+
+ printf("begin to kick cpu core #%d to address %llx\n",
+ nr, boot_addr);
+ regs.regs[0] = PSCI_0_2_FN64_CPU_ON;
+ regs.regs[1] = nr;
+ regs.regs[2] = boot_addr;
+ regs.regs[3] = 0;
+ smc_call(&regs);
+ if (regs.regs[0])
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ppa.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ppa.c
new file mode 100644
index 000000000..b9894d41b
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/ppa.c
@@ -0,0 +1,284 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ */
+#include <common.h>
+#include <log.h>
+#include <malloc.h>
+#include <config.h>
+#include <errno.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/system.h>
+#include <asm/types.h>
+#include <asm/arch/soc.h>
+#ifdef CONFIG_FSL_LSCH3
+#include <asm/arch/immap_lsch3.h>
+#elif defined(CONFIG_FSL_LSCH2)
+#include <asm/arch/immap_lsch2.h>
+#endif
+#if CONFIG_IS_ENABLED(ARMV8_SEC_FIRMWARE_SUPPORT)
+#include <asm/armv8/sec_firmware.h>
+#endif
+#ifdef CONFIG_CHAIN_OF_TRUST
+#include <fsl_validate.h>
+#endif
+
+#ifdef CONFIG_SYS_LS_PPA_FW_IN_NAND
+#include <nand.h>
+#elif defined(CONFIG_SYS_LS_PPA_FW_IN_MMC)
+#include <mmc.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int ppa_init(void)
+{
+ unsigned int el = current_el();
+ void *ppa_fit_addr;
+ u32 *boot_loc_ptr_l, *boot_loc_ptr_h;
+ u32 *loadable_l, *loadable_h;
+ int ret;
+
+#ifdef CONFIG_CHAIN_OF_TRUST
+ uintptr_t ppa_esbc_hdr = 0;
+ uintptr_t ppa_img_addr = 0;
+#if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \
+ defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
+ void *ppa_hdr_ddr;
+#endif
+#endif
+
+ /* Skip if running at lower exception level */
+ if (el < 3) {
+ debug("Skipping PPA init, running at EL%d\n", el);
+ return 0;
+ }
+
+#ifdef CONFIG_SYS_LS_PPA_FW_IN_XIP
+ ppa_fit_addr = (void *)CONFIG_SYS_LS_PPA_FW_ADDR;
+ debug("%s: PPA image load from XIP\n", __func__);
+#ifdef CONFIG_CHAIN_OF_TRUST
+ ppa_esbc_hdr = CONFIG_SYS_LS_PPA_ESBC_ADDR;
+#endif
+#else /* !CONFIG_SYS_LS_PPA_FW_IN_XIP */
+ size_t fw_length, fdt_header_len = sizeof(struct fdt_header);
+
+ /* Copy PPA image from MMC/SD/NAND to allocated memory */
+#ifdef CONFIG_SYS_LS_PPA_FW_IN_MMC
+ struct mmc *mmc;
+ int dev = CONFIG_SYS_MMC_ENV_DEV;
+ struct fdt_header *fitp;
+ u32 cnt;
+ u32 blk;
+
+ debug("%s: PPA image load from eMMC/SD\n", __func__);
+
+ ret = mmc_initialize(gd->bd);
+ if (ret) {
+ printf("%s: mmc_initialize() failed\n", __func__);
+ return ret;
+ }
+ mmc = find_mmc_device(dev);
+ if (!mmc) {
+ printf("PPA: MMC cannot find device for PPA firmware\n");
+ return -ENODEV;
+ }
+
+ ret = mmc_init(mmc);
+ if (ret) {
+ printf("%s: mmc_init() failed\n", __func__);
+ return ret;
+ }
+
+ fitp = malloc(roundup(fdt_header_len, 512));
+ if (!fitp) {
+ printf("PPA: malloc failed for FIT header(size 0x%zx)\n",
+ roundup(fdt_header_len, 512));
+ return -ENOMEM;
+ }
+
+ blk = CONFIG_SYS_LS_PPA_FW_ADDR / 512;
+ cnt = DIV_ROUND_UP(fdt_header_len, 512);
+ debug("%s: MMC read PPA FIT header: dev # %u, block # %u, count %u\n",
+ __func__, dev, blk, cnt);
+ ret = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, fitp);
+ if (ret != cnt) {
+ free(fitp);
+ printf("MMC/SD read of PPA FIT header at offset 0x%x failed\n",
+ CONFIG_SYS_LS_PPA_FW_ADDR);
+ return -EIO;
+ }
+
+ ret = fdt_check_header(fitp);
+ if (ret) {
+ free(fitp);
+ printf("%s: fdt_check_header() failed\n", __func__);
+ return ret;
+ }
+
+#ifdef CONFIG_CHAIN_OF_TRUST
+ ppa_hdr_ddr = malloc(CONFIG_LS_PPA_ESBC_HDR_SIZE);
+ if (!ppa_hdr_ddr) {
+ printf("PPA: malloc failed for PPA header\n");
+ return -ENOMEM;
+ }
+
+ blk = CONFIG_SYS_LS_PPA_ESBC_ADDR >> 9;
+ cnt = DIV_ROUND_UP(CONFIG_LS_PPA_ESBC_HDR_SIZE, 512);
+ ret = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, ppa_hdr_ddr);
+ if (ret != cnt) {
+ free(ppa_hdr_ddr);
+ printf("MMC/SD read of PPA header failed\n");
+ return -EIO;
+ }
+ debug("Read PPA header to 0x%p\n", ppa_hdr_ddr);
+
+ ppa_esbc_hdr = (uintptr_t)ppa_hdr_ddr;
+#endif
+
+ fw_length = fdt_totalsize(fitp);
+ free(fitp);
+
+ fw_length = roundup(fw_length, 512);
+ ppa_fit_addr = malloc(fw_length);
+ if (!ppa_fit_addr) {
+ printf("PPA: malloc failed for PPA image(size 0x%zx)\n",
+ fw_length);
+ return -ENOMEM;
+ }
+
+ blk = CONFIG_SYS_LS_PPA_FW_ADDR / 512;
+ cnt = DIV_ROUND_UP(fw_length, 512);
+ debug("%s: MMC read PPA FIT image: dev # %u, block # %u, count %u\n",
+ __func__, dev, blk, cnt);
+ ret = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, ppa_fit_addr);
+ if (ret != cnt) {
+ free(ppa_fit_addr);
+ printf("MMC/SD read of PPA FIT header at offset 0x%x failed\n",
+ CONFIG_SYS_LS_PPA_FW_ADDR);
+ return -EIO;
+ }
+
+#elif defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
+ struct fdt_header fit;
+
+ debug("%s: PPA image load from NAND\n", __func__);
+
+ nand_init();
+ ret = nand_read(get_nand_dev_by_index(0),
+ (loff_t)CONFIG_SYS_LS_PPA_FW_ADDR,
+ &fdt_header_len, (u_char *)&fit);
+ if (ret == -EUCLEAN) {
+ printf("NAND read of PPA FIT header at offset 0x%x failed\n",
+ CONFIG_SYS_LS_PPA_FW_ADDR);
+ return -EIO;
+ }
+
+ ret = fdt_check_header(&fit);
+ if (ret) {
+ printf("%s: fdt_check_header() failed\n", __func__);
+ return ret;
+ }
+
+#ifdef CONFIG_CHAIN_OF_TRUST
+ ppa_hdr_ddr = malloc(CONFIG_LS_PPA_ESBC_HDR_SIZE);
+ if (!ppa_hdr_ddr) {
+ printf("PPA: malloc failed for PPA header\n");
+ return -ENOMEM;
+ }
+
+ fw_length = CONFIG_LS_PPA_ESBC_HDR_SIZE;
+
+ ret = nand_read(get_nand_dev_by_index(0),
+ (loff_t)CONFIG_SYS_LS_PPA_ESBC_ADDR,
+ &fw_length, (u_char *)ppa_hdr_ddr);
+ if (ret == -EUCLEAN) {
+ free(ppa_hdr_ddr);
+ printf("NAND read of PPA firmware at offset 0x%x failed\n",
+ CONFIG_SYS_LS_PPA_FW_ADDR);
+ return -EIO;
+ }
+ debug("Read PPA header to 0x%p\n", ppa_hdr_ddr);
+
+ ppa_esbc_hdr = (uintptr_t)ppa_hdr_ddr;
+#endif
+
+ fw_length = fdt_totalsize(&fit);
+
+ ppa_fit_addr = malloc(fw_length);
+ if (!ppa_fit_addr) {
+ printf("PPA: malloc failed for PPA image(size 0x%zx)\n",
+ fw_length);
+ return -ENOMEM;
+ }
+
+ ret = nand_read(get_nand_dev_by_index(0),
+ (loff_t)CONFIG_SYS_LS_PPA_FW_ADDR,
+ &fw_length, (u_char *)ppa_fit_addr);
+ if (ret == -EUCLEAN) {
+ free(ppa_fit_addr);
+ printf("NAND read of PPA firmware at offset 0x%x failed\n",
+ CONFIG_SYS_LS_PPA_FW_ADDR);
+ return -EIO;
+ }
+#else
+#error "No CONFIG_SYS_LS_PPA_FW_IN_xxx defined"
+#endif
+
+#endif
+
+#ifdef CONFIG_CHAIN_OF_TRUST
+ ppa_img_addr = (uintptr_t)ppa_fit_addr;
+ if (fsl_check_boot_mode_secure() != 0) {
+ /*
+ * In case of failure in validation, fsl_secboot_validate
+ * would not return back in case of Production environment
+ * with ITS=1. In Development environment (ITS=0 and
+ * SB_EN=1), the function may return back in case of
+ * non-fatal failures.
+ */
+ ret = fsl_secboot_validate(ppa_esbc_hdr,
+ PPA_KEY_HASH,
+ &ppa_img_addr);
+ if (ret != 0)
+ printf("SEC firmware(s) validation failed\n");
+ else
+ printf("SEC firmware(s) validation Successful\n");
+ }
+#if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \
+ defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
+ free(ppa_hdr_ddr);
+#endif
+#endif
+
+#ifdef CONFIG_FSL_LSCH3
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ boot_loc_ptr_l = &gur->bootlocptrl;
+ boot_loc_ptr_h = &gur->bootlocptrh;
+
+ /* Assign addresses to loadable ptrs */
+ loadable_l = &gur->scratchrw[4];
+ loadable_h = &gur->scratchrw[5];
+#elif defined(CONFIG_FSL_LSCH2)
+ struct ccsr_scfg __iomem *scfg = (void *)(CONFIG_SYS_FSL_SCFG_ADDR);
+ boot_loc_ptr_l = &scfg->scratchrw[1];
+ boot_loc_ptr_h = &scfg->scratchrw[0];
+
+ /* Assign addresses to loadable ptrs */
+ loadable_l = &scfg->scratchrw[2];
+ loadable_h = &scfg->scratchrw[3];
+#endif
+
+ debug("fsl-ppa: boot_loc_ptr_l = 0x%p, boot_loc_ptr_h =0x%p\n",
+ boot_loc_ptr_l, boot_loc_ptr_h);
+ ret = sec_firmware_init(ppa_fit_addr, boot_loc_ptr_l, boot_loc_ptr_h,
+ loadable_l, loadable_h);
+
+#if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \
+ defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
+ free(ppa_fit_addr);
+#endif
+
+ return ret;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/soc.c
new file mode 100644
index 000000000..c3cd6c7ac
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/soc.c
@@ -0,0 +1,975 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014-2015 Freescale Semiconductor
+ * Copyright 2019-2021 NXP
+ */
+
+#include <common.h>
+#include <clock_legacy.h>
+#include <cpu_func.h>
+#include <env.h>
+#include <fsl_immap.h>
+#include <fsl_ifc.h>
+#include <init.h>
+#include <linux/sizes.h>
+#include <log.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/soc.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/global_data.h>
+#include <asm/arch-fsl-layerscape/config.h>
+#include <asm/arch-fsl-layerscape/ns_access.h>
+#include <asm/arch-fsl-layerscape/fsl_icid.h>
+#include <asm/gic-v3.h>
+#ifdef CONFIG_LAYERSCAPE_NS_ACCESS
+#include <fsl_csu.h>
+#endif
+#ifdef CONFIG_SYS_FSL_DDR
+#include <fsl_ddr_sdram.h>
+#include <fsl_ddr.h>
+#endif
+#ifdef CONFIG_CHAIN_OF_TRUST
+#include <fsl_validate.h>
+#endif
+#include <fsl_immap.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <linux/err.h>
+#ifdef CONFIG_GIC_V3_ITS
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
+#ifdef CONFIG_GIC_V3_ITS
+int ls_gic_rd_tables_init(void *blob)
+{
+ struct fdt_memory lpi_base;
+ fdt_addr_t addr;
+ fdt_size_t size;
+ int offset, ret;
+
+ offset = fdt_path_offset(gd->fdt_blob, "/syscon@0x80000000");
+ addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, offset, "reg",
+ 0, &size, false);
+
+ lpi_base.start = addr;
+ lpi_base.end = addr + size - 1;
+ ret = fdtdec_add_reserved_memory(blob, "lpi_rd_table", &lpi_base, NULL, false);
+ if (ret) {
+ debug("%s: failed to add reserved memory\n", __func__);
+ return ret;
+ }
+
+ ret = gic_lpi_tables_init();
+ if (ret)
+ debug("%s: failed to init gic-lpi-tables\n", __func__);
+
+ return ret;
+}
+#endif
+
+bool soc_has_dp_ddr(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 svr = gur_in32(&gur->svr);
+
+ /* LS2085A, LS2088A, LS2048A has DP_DDR */
+ if ((SVR_SOC_VER(svr) == SVR_LS2085A) ||
+ (SVR_SOC_VER(svr) == SVR_LS2088A) ||
+ (SVR_SOC_VER(svr) == SVR_LS2048A))
+ return true;
+
+ return false;
+}
+
+bool soc_has_aiop(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 svr = gur_in32(&gur->svr);
+
+ /* LS2085A has AIOP */
+ if (SVR_SOC_VER(svr) == SVR_LS2085A)
+ return true;
+
+ return false;
+}
+
+static inline void set_usb_txvreftune(u32 __iomem *scfg, u32 offset)
+{
+ scfg_clrsetbits32(scfg + offset / 4,
+ 0xF << 6,
+ SCFG_USB_TXVREFTUNE << 6);
+}
+
+static void erratum_a009008(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009008
+ u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
+
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
+ defined(CONFIG_ARCH_LS1012A)
+ set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB1);
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
+ set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB2);
+ set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB3);
+#endif
+#elif defined(CONFIG_ARCH_LS2080A)
+ set_usb_txvreftune(scfg, SCFG_USB3PRM1CR);
+#endif
+#endif /* CONFIG_SYS_FSL_ERRATUM_A009008 */
+}
+
+static inline void set_usb_sqrxtune(u32 __iomem *scfg, u32 offset)
+{
+ scfg_clrbits32(scfg + offset / 4,
+ SCFG_USB_SQRXTUNE_MASK << 23);
+}
+
+static void erratum_a009798(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009798
+ u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
+
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
+ defined(CONFIG_ARCH_LS1012A)
+ set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB1);
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
+ set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB2);
+ set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB3);
+#endif
+#elif defined(CONFIG_ARCH_LS2080A)
+ set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR);
+#endif
+#endif /* CONFIG_SYS_FSL_ERRATUM_A009798 */
+}
+
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
+ defined(CONFIG_ARCH_LS1012A)
+static inline void set_usb_pcstxswingfull(u32 __iomem *scfg, u32 offset)
+{
+ scfg_clrsetbits32(scfg + offset / 4,
+ 0x7F << 9,
+ SCFG_USB_PCSTXSWINGFULL << 9);
+}
+#endif
+
+static void erratum_a008997(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008997
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
+ defined(CONFIG_ARCH_LS1012A)
+ u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
+
+ set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB1);
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
+ set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB2);
+ set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB3);
+#endif
+#elif defined(CONFIG_ARCH_LS1028A)
+ clrsetbits_le32(DCSR_BASE + DCSR_USB_IOCR1,
+ 0x7F << 11,
+ DCSR_USB_PCSTXSWINGFULL << 11);
+#endif
+#endif /* CONFIG_SYS_FSL_ERRATUM_A008997 */
+}
+
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
+ defined(CONFIG_ARCH_LS1012A)
+
+#define PROGRAM_USB_PHY_RX_OVRD_IN_HI(phy) \
+ out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_1); \
+ out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_2); \
+ out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_3); \
+ out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_4)
+
+#elif defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A) || \
+ defined(CONFIG_ARCH_LS1028A) || defined(CONFIG_ARCH_LX2160A) || \
+ defined(CONFIG_ARCH_LX2162A)
+
+#define PROGRAM_USB_PHY_RX_OVRD_IN_HI(phy) \
+ out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_1); \
+ out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_2); \
+ out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_3); \
+ out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_4)
+
+#endif
+
+static void erratum_a009007(void)
+{
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
+ defined(CONFIG_ARCH_LS1012A)
+ void __iomem *usb_phy = (void __iomem *)SCFG_USB_PHY1;
+
+ PROGRAM_USB_PHY_RX_OVRD_IN_HI(usb_phy);
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
+ usb_phy = (void __iomem *)SCFG_USB_PHY2;
+ PROGRAM_USB_PHY_RX_OVRD_IN_HI(usb_phy);
+
+ usb_phy = (void __iomem *)SCFG_USB_PHY3;
+ PROGRAM_USB_PHY_RX_OVRD_IN_HI(usb_phy);
+#endif
+#elif defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A) || \
+ defined(CONFIG_ARCH_LS1028A)
+ void __iomem *dcsr = (void __iomem *)DCSR_BASE;
+
+ PROGRAM_USB_PHY_RX_OVRD_IN_HI(dcsr + DCSR_USB_PHY1);
+ PROGRAM_USB_PHY_RX_OVRD_IN_HI(dcsr + DCSR_USB_PHY2);
+#endif /* CONFIG_SYS_FSL_ERRATUM_A009007 */
+}
+
+#if defined(CONFIG_FSL_LSCH3)
+static void erratum_a050204(void)
+{
+#if defined(CONFIG_ARCH_LX2160A) || defined(CONFIG_ARCH_LX2162A)
+ void __iomem *dcsr = (void __iomem *)DCSR_BASE;
+
+ PROGRAM_USB_PHY_RX_OVRD_IN_HI(dcsr + DCSR_USB_PHY1);
+ PROGRAM_USB_PHY_RX_OVRD_IN_HI(dcsr + DCSR_USB_PHY2);
+#endif
+}
+/*
+ * This erratum requires setting a value to eddrtqcr1 to
+ * optimal the DDR performance.
+ */
+static void erratum_a008336(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008336
+ u32 *eddrtqcr1;
+
+#ifdef CONFIG_SYS_FSL_DCSR_DDR_ADDR
+ eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800;
+ if (fsl_ddr_get_version(0) == 0x50200)
+ out_le32(eddrtqcr1, 0x63b30002);
+#endif
+#ifdef CONFIG_SYS_FSL_DCSR_DDR2_ADDR
+ eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800;
+ if (fsl_ddr_get_version(0) == 0x50200)
+ out_le32(eddrtqcr1, 0x63b30002);
+#endif
+#endif
+}
+
+/*
+ * This erratum requires a register write before being Memory
+ * controller 3 being enabled.
+ */
+static void erratum_a008514(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008514
+ u32 *eddrtqcr1;
+
+#ifdef CONFIG_SYS_FSL_DCSR_DDR3_ADDR
+ eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800;
+ out_le32(eddrtqcr1, 0x63b20002);
+#endif
+#endif
+}
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009635
+#define PLATFORM_CYCLE_ENV_VAR "a009635_interval_val"
+
+static unsigned long get_internval_val_mhz(void)
+{
+ char *interval = env_get(PLATFORM_CYCLE_ENV_VAR);
+ /*
+ * interval is the number of platform cycles(MHz) between
+ * wake up events generated by EPU.
+ */
+ ulong interval_mhz = get_bus_freq(0) / (1000 * 1000);
+
+ if (interval)
+ interval_mhz = simple_strtoul(interval, NULL, 10);
+
+ return interval_mhz;
+}
+
+void erratum_a009635(void)
+{
+ u32 val;
+ unsigned long interval_mhz = get_internval_val_mhz();
+
+ if (!interval_mhz)
+ return;
+
+ val = in_le32(DCSR_CGACRE5);
+ writel(val | 0x00000200, DCSR_CGACRE5);
+
+ val = in_le32(EPU_EPCMPR5);
+ writel(interval_mhz, EPU_EPCMPR5);
+ val = in_le32(EPU_EPCCR5);
+ writel(val | 0x82820000, EPU_EPCCR5);
+ val = in_le32(EPU_EPSMCR5);
+ writel(val | 0x002f0000, EPU_EPSMCR5);
+ val = in_le32(EPU_EPECR5);
+ writel(val | 0x20000000, EPU_EPECR5);
+ val = in_le32(EPU_EPGCR);
+ writel(val | 0x80000000, EPU_EPGCR);
+}
+#endif /* CONFIG_SYS_FSL_ERRATUM_A009635 */
+
+static void erratum_rcw_src(void)
+{
+#if defined(CONFIG_SPL) && defined(CONFIG_NAND_BOOT)
+ u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
+ u32 __iomem *dcfg_dcsr = (u32 __iomem *)DCFG_DCSR_BASE;
+ u32 val;
+
+ val = in_le32(dcfg_ccsr + DCFG_PORSR1 / 4);
+ val &= ~DCFG_PORSR1_RCW_SRC;
+ val |= DCFG_PORSR1_RCW_SRC_NOR;
+ out_le32(dcfg_dcsr + DCFG_DCSR_PORCR1 / 4, val);
+#endif
+}
+
+#define I2C_DEBUG_REG 0x6
+#define I2C_GLITCH_EN 0x8
+/*
+ * This erratum requires setting glitch_en bit to enable
+ * digital glitch filter to improve clock stability.
+ */
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009203
+static void erratum_a009203(void)
+{
+#ifdef CONFIG_SYS_I2C
+ u8 __iomem *ptr;
+#ifdef I2C1_BASE_ADDR
+ ptr = (u8 __iomem *)(I2C1_BASE_ADDR + I2C_DEBUG_REG);
+
+ writeb(I2C_GLITCH_EN, ptr);
+#endif
+#ifdef I2C2_BASE_ADDR
+ ptr = (u8 __iomem *)(I2C2_BASE_ADDR + I2C_DEBUG_REG);
+
+ writeb(I2C_GLITCH_EN, ptr);
+#endif
+#ifdef I2C3_BASE_ADDR
+ ptr = (u8 __iomem *)(I2C3_BASE_ADDR + I2C_DEBUG_REG);
+
+ writeb(I2C_GLITCH_EN, ptr);
+#endif
+#ifdef I2C4_BASE_ADDR
+ ptr = (u8 __iomem *)(I2C4_BASE_ADDR + I2C_DEBUG_REG);
+
+ writeb(I2C_GLITCH_EN, ptr);
+#endif
+#endif
+}
+#endif
+
+void bypass_smmu(void)
+{
+ u32 val;
+ val = (in_le32(SMMU_SCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK);
+ out_le32(SMMU_SCR0, val);
+ val = (in_le32(SMMU_NSCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK);
+ out_le32(SMMU_NSCR0, val);
+}
+void fsl_lsch3_early_init_f(void)
+{
+ erratum_rcw_src();
+#ifdef CONFIG_FSL_IFC
+ init_early_memctl_regs(); /* tighten IFC timing */
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009203
+ erratum_a009203();
+#endif
+ erratum_a008514();
+ erratum_a008336();
+ erratum_a009008();
+ erratum_a009798();
+ erratum_a008997();
+ erratum_a009007();
+ erratum_a050204();
+#ifdef CONFIG_CHAIN_OF_TRUST
+ /* In case of Secure Boot, the IBR configures the SMMU
+ * to allow only Secure transactions.
+ * SMMU must be reset in bypass mode.
+ * Set the ClientPD bit and Clear the USFCFG Bit
+ */
+ if (fsl_check_boot_mode_secure() == 1)
+ bypass_smmu();
+#endif
+
+#if defined(CONFIG_ARCH_LS1088A) || defined(CONFIG_ARCH_LS1028A) || \
+ defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LX2160A) || \
+ defined(CONFIG_ARCH_LX2162A)
+ set_icids();
+#endif
+}
+
+/* Get VDD in the unit mV from voltage ID */
+int get_core_volt_from_fuse(void)
+{
+ struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ int vdd;
+ u32 fusesr;
+ u8 vid;
+
+ /* get the voltage ID from fuse status register */
+ fusesr = in_le32(&gur->dcfg_fusesr);
+ debug("%s: fusesr = 0x%x\n", __func__, fusesr);
+ vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT) &
+ FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK;
+ if ((vid == 0) || (vid == FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK)) {
+ vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT) &
+ FSL_CHASSIS3_DCFG_FUSESR_VID_MASK;
+ }
+ debug("%s: VID = 0x%x\n", __func__, vid);
+ switch (vid) {
+ case 0x00: /* VID isn't supported */
+ vdd = -EINVAL;
+ debug("%s: The VID feature is not supported\n", __func__);
+ break;
+ case 0x08: /* 0.9V silicon */
+ vdd = 900;
+ break;
+ case 0x10: /* 1.0V silicon */
+ vdd = 1000;
+ break;
+ default: /* Other core voltage */
+ vdd = -EINVAL;
+ debug("%s: The VID(%x) isn't supported\n", __func__, vid);
+ break;
+ }
+ debug("%s: The required minimum volt of CORE is %dmV\n", __func__, vdd);
+
+ return vdd;
+}
+
+#elif defined(CONFIG_FSL_LSCH2)
+/*
+ * This erratum requires setting a value to eddrtqcr1 to optimal
+ * the DDR performance. The eddrtqcr1 register is in SCFG space
+ * of LS1043A and the offset is 0x157_020c.
+ */
+#if defined(CONFIG_SYS_FSL_ERRATUM_A009660) \
+ && defined(CONFIG_SYS_FSL_ERRATUM_A008514)
+#error A009660 and A008514 can not be both enabled.
+#endif
+
+static void erratum_a009660(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009660
+ u32 *eddrtqcr1 = (void *)CONFIG_SYS_FSL_SCFG_ADDR + 0x20c;
+ out_be32(eddrtqcr1, 0x63b20042);
+#endif
+}
+
+static void erratum_a008850_early(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008850
+ /* part 1 of 2 */
+ struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR +
+ CONFIG_SYS_CCI400_OFFSET);
+ struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+
+ /* Skip if running at lower exception level */
+ if (current_el() < 3)
+ return;
+
+ /* disables propagation of barrier transactions to DDRC from CCI400 */
+ out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
+
+ /* disable the re-ordering in DDRC */
+ ddr_out32(&ddr->eor, DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS);
+#endif
+}
+
+void erratum_a008850_post(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008850
+ /* part 2 of 2 */
+ struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR +
+ CONFIG_SYS_CCI400_OFFSET);
+ struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+ u32 tmp;
+
+ /* Skip if running at lower exception level */
+ if (current_el() < 3)
+ return;
+
+ /* enable propagation of barrier transactions to DDRC from CCI400 */
+ out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
+
+ /* enable the re-ordering in DDRC */
+ tmp = ddr_in32(&ddr->eor);
+ tmp &= ~(DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS);
+ ddr_out32(&ddr->eor, tmp);
+#endif
+}
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_A010315
+void erratum_a010315(void)
+{
+ int i;
+
+ for (i = PCIE1; i <= PCIE4; i++)
+ if (!is_serdes_configured(i)) {
+ debug("PCIe%d: disabled all R/W permission!\n", i);
+ set_pcie_ns_access(i, 0);
+ }
+}
+#endif
+
+static void erratum_a010539(void)
+{
+#if defined(CONFIG_SYS_FSL_ERRATUM_A010539) && defined(CONFIG_QSPI_BOOT)
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 porsr1;
+
+ porsr1 = in_be32(&gur->porsr1);
+ porsr1 &= ~FSL_CHASSIS2_CCSR_PORSR1_RCW_MASK;
+ out_be32((void *)(CONFIG_SYS_DCSR_DCFG_ADDR + DCFG_DCSR_PORCR1),
+ porsr1);
+ out_be32((void *)(CONFIG_SYS_FSL_SCFG_ADDR + 0x1a8), 0xffffffff);
+#endif
+}
+
+/* Get VDD in the unit mV from voltage ID */
+int get_core_volt_from_fuse(void)
+{
+ struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ int vdd;
+ u32 fusesr;
+ u8 vid;
+
+ fusesr = in_be32(&gur->dcfg_fusesr);
+ debug("%s: fusesr = 0x%x\n", __func__, fusesr);
+ vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_ALTVID_SHIFT) &
+ FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK;
+ if ((vid == 0) || (vid == FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK)) {
+ vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_VID_SHIFT) &
+ FSL_CHASSIS2_DCFG_FUSESR_VID_MASK;
+ }
+ debug("%s: VID = 0x%x\n", __func__, vid);
+ switch (vid) {
+ case 0x00: /* VID isn't supported */
+ vdd = -EINVAL;
+ debug("%s: The VID feature is not supported\n", __func__);
+ break;
+ case 0x08: /* 0.9V silicon */
+ vdd = 900;
+ break;
+ case 0x10: /* 1.0V silicon */
+ vdd = 1000;
+ break;
+ default: /* Other core voltage */
+ vdd = -EINVAL;
+ printf("%s: The VID(%x) isn't supported\n", __func__, vid);
+ break;
+ }
+ debug("%s: The required minimum volt of CORE is %dmV\n", __func__, vdd);
+
+ return vdd;
+}
+
+__weak int board_switch_core_volt(u32 vdd)
+{
+ return 0;
+}
+
+static int setup_core_volt(u32 vdd)
+{
+ return board_setup_core_volt(vdd);
+}
+
+#ifdef CONFIG_SYS_FSL_DDR
+static void ddr_enable_0v9_volt(bool en)
+{
+ struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+ u32 tmp;
+
+ tmp = ddr_in32(&ddr->ddr_cdr1);
+
+ if (en)
+ tmp |= DDR_CDR1_V0PT9_EN;
+ else
+ tmp &= ~DDR_CDR1_V0PT9_EN;
+
+ ddr_out32(&ddr->ddr_cdr1, tmp);
+}
+#endif
+
+int setup_chip_volt(void)
+{
+ int vdd;
+
+ vdd = get_core_volt_from_fuse();
+ /* Nothing to do for silicons doesn't support VID */
+ if (vdd < 0)
+ return vdd;
+
+ if (setup_core_volt(vdd))
+ printf("%s: Switch core VDD to %dmV failed\n", __func__, vdd);
+#ifdef CONFIG_SYS_HAS_SERDES
+ if (setup_serdes_volt(vdd))
+ printf("%s: Switch SVDD to %dmV failed\n", __func__, vdd);
+#endif
+
+#ifdef CONFIG_SYS_FSL_DDR
+ if (vdd == 900)
+ ddr_enable_0v9_volt(true);
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_FSL_PFE
+void init_pfe_scfg_dcfg_regs(void)
+{
+ struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
+ u32 ecccr2;
+
+ out_be32(&scfg->pfeasbcr,
+ in_be32(&scfg->pfeasbcr) | SCFG_PFEASBCR_AWCACHE0);
+ out_be32(&scfg->pfebsbcr,
+ in_be32(&scfg->pfebsbcr) | SCFG_PFEASBCR_AWCACHE0);
+
+ /* CCI-400 QoS settings for PFE */
+ out_be32(&scfg->wr_qos1, (unsigned int)(SCFG_WR_QOS1_PFE1_QOS
+ | SCFG_WR_QOS1_PFE2_QOS));
+ out_be32(&scfg->rd_qos1, (unsigned int)(SCFG_RD_QOS1_PFE1_QOS
+ | SCFG_RD_QOS1_PFE2_QOS));
+
+ ecccr2 = in_be32(CONFIG_SYS_DCSR_DCFG_ADDR + DCFG_DCSR_ECCCR2);
+ out_be32((void *)CONFIG_SYS_DCSR_DCFG_ADDR + DCFG_DCSR_ECCCR2,
+ ecccr2 | (unsigned int)DISABLE_PFE_ECC);
+}
+#endif
+
+void fsl_lsch2_early_init_f(void)
+{
+ struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR +
+ CONFIG_SYS_CCI400_OFFSET);
+ struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
+#if defined(CONFIG_FSL_QSPI) && defined(CONFIG_TFABOOT)
+ enum boot_src src;
+#endif
+
+#ifdef CONFIG_LAYERSCAPE_NS_ACCESS
+ enable_layerscape_ns_access();
+#endif
+
+#ifdef CONFIG_FSL_IFC
+ init_early_memctl_regs(); /* tighten IFC timing */
+#endif
+
+#if defined(CONFIG_FSL_QSPI) && defined(CONFIG_TFABOOT)
+ src = get_boot_src();
+ if (src != BOOT_SOURCE_QSPI_NOR)
+ out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
+#else
+#if defined(CONFIG_FSL_QSPI) && !defined(CONFIG_QSPI_BOOT)
+ out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
+#endif
+#endif
+ /* Make SEC reads and writes snoopable */
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
+ setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP |
+ SCFG_SNPCNFGCR_SECWRSNP | SCFG_SNPCNFGCR_USB1RDSNP |
+ SCFG_SNPCNFGCR_USB1WRSNP | SCFG_SNPCNFGCR_USB2RDSNP |
+ SCFG_SNPCNFGCR_USB2WRSNP | SCFG_SNPCNFGCR_USB3RDSNP |
+ SCFG_SNPCNFGCR_USB3WRSNP | SCFG_SNPCNFGCR_SATARDSNP |
+ SCFG_SNPCNFGCR_SATAWRSNP);
+#elif defined(CONFIG_ARCH_LS1012A)
+ setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP |
+ SCFG_SNPCNFGCR_SECWRSNP | SCFG_SNPCNFGCR_USB1RDSNP |
+ SCFG_SNPCNFGCR_USB1WRSNP | SCFG_SNPCNFGCR_SATARDSNP |
+ SCFG_SNPCNFGCR_SATAWRSNP);
+#else
+ setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP |
+ SCFG_SNPCNFGCR_SECWRSNP |
+ SCFG_SNPCNFGCR_SATARDSNP |
+ SCFG_SNPCNFGCR_SATAWRSNP);
+#endif
+
+ /*
+ * Enable snoop requests and DVM message requests for
+ * Slave insterface S4 (A53 core cluster)
+ */
+ if (current_el() == 3) {
+ out_le32(&cci->slave[4].snoop_ctrl,
+ CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
+ }
+
+ /*
+ * Program Central Security Unit (CSU) to grant access
+ * permission for USB 2.0 controller
+ */
+#if defined(CONFIG_ARCH_LS1012A) && defined(CONFIG_USB_EHCI_FSL)
+ if (current_el() == 3)
+ set_devices_ns_access(CSU_CSLX_USB_2, CSU_ALL_RW);
+#endif
+ /* Erratum */
+ erratum_a008850_early(); /* part 1 of 2 */
+ erratum_a009660();
+ erratum_a010539();
+ erratum_a009008();
+ erratum_a009798();
+ erratum_a008997();
+ erratum_a009007();
+
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
+ set_icids();
+#endif
+}
+#endif
+
+#ifdef CONFIG_FSPI_AHB_EN_4BYTE
+int fspi_ahb_init(void)
+{
+ /* Enable 4bytes address support and fast read */
+ u32 *fspi_lut, lut_key, *fspi_key;
+
+ fspi_key = (void *)SYS_NXP_FSPI_ADDR + SYS_NXP_FSPI_LUTKEY_BASE_ADDR;
+ fspi_lut = (void *)SYS_NXP_FSPI_ADDR + SYS_NXP_FSPI_LUT_BASE_ADDR;
+
+ lut_key = in_be32(fspi_key);
+
+ if (lut_key == SYS_NXP_FSPI_LUTKEY) {
+ /* That means the register is BE */
+ out_be32(fspi_key, SYS_NXP_FSPI_LUTKEY);
+ /* Unlock the lut table */
+ out_be32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_UNLOCK);
+ /* Create READ LUT */
+ out_be32(fspi_lut, 0x0820040c);
+ out_be32(fspi_lut + 1, 0x24003008);
+ out_be32(fspi_lut + 2, 0x00000000);
+ /* Lock the lut table */
+ out_be32(fspi_key, SYS_NXP_FSPI_LUTKEY);
+ out_be32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_LOCK);
+ } else {
+ /* That means the register is LE */
+ out_le32(fspi_key, SYS_NXP_FSPI_LUTKEY);
+ /* Unlock the lut table */
+ out_le32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_UNLOCK);
+ /* Create READ LUT */
+ out_le32(fspi_lut, 0x0820040c);
+ out_le32(fspi_lut + 1, 0x24003008);
+ out_le32(fspi_lut + 2, 0x00000000);
+ /* Lock the lut table */
+ out_le32(fspi_key, SYS_NXP_FSPI_LUTKEY);
+ out_le32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_LOCK);
+ }
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_QSPI_AHB_INIT
+/* Enable 4bytes address support and fast read */
+int qspi_ahb_init(void)
+{
+ u32 *qspi_lut, lut_key, *qspi_key;
+
+ qspi_key = (void *)SYS_FSL_QSPI_ADDR + 0x300;
+ qspi_lut = (void *)SYS_FSL_QSPI_ADDR + 0x310;
+
+ lut_key = in_be32(qspi_key);
+
+ if (lut_key == 0x5af05af0) {
+ /* That means the register is BE */
+ out_be32(qspi_key, 0x5af05af0);
+ /* Unlock the lut table */
+ out_be32(qspi_key + 1, 0x00000002);
+ out_be32(qspi_lut, 0x0820040c);
+ out_be32(qspi_lut + 1, 0x1c080c08);
+ out_be32(qspi_lut + 2, 0x00002400);
+ /* Lock the lut table */
+ out_be32(qspi_key, 0x5af05af0);
+ out_be32(qspi_key + 1, 0x00000001);
+ } else {
+ /* That means the register is LE */
+ out_le32(qspi_key, 0x5af05af0);
+ /* Unlock the lut table */
+ out_le32(qspi_key + 1, 0x00000002);
+ out_le32(qspi_lut, 0x0820040c);
+ out_le32(qspi_lut + 1, 0x1c080c08);
+ out_le32(qspi_lut + 2, 0x00002400);
+ /* Lock the lut table */
+ out_le32(qspi_key, 0x5af05af0);
+ out_le32(qspi_key + 1, 0x00000001);
+ }
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_TFABOOT
+#define MAX_BOOTCMD_SIZE 512
+
+int fsl_setenv_bootcmd(void)
+{
+ int ret;
+ enum boot_src src = get_boot_src();
+ char bootcmd_str[MAX_BOOTCMD_SIZE];
+
+ switch (src) {
+#ifdef IFC_NOR_BOOTCOMMAND
+ case BOOT_SOURCE_IFC_NOR:
+ sprintf(bootcmd_str, IFC_NOR_BOOTCOMMAND);
+ break;
+#endif
+#ifdef QSPI_NOR_BOOTCOMMAND
+ case BOOT_SOURCE_QSPI_NOR:
+ sprintf(bootcmd_str, QSPI_NOR_BOOTCOMMAND);
+ break;
+#endif
+#ifdef XSPI_NOR_BOOTCOMMAND
+ case BOOT_SOURCE_XSPI_NOR:
+ sprintf(bootcmd_str, XSPI_NOR_BOOTCOMMAND);
+ break;
+#endif
+#ifdef IFC_NAND_BOOTCOMMAND
+ case BOOT_SOURCE_IFC_NAND:
+ sprintf(bootcmd_str, IFC_NAND_BOOTCOMMAND);
+ break;
+#endif
+#ifdef QSPI_NAND_BOOTCOMMAND
+ case BOOT_SOURCE_QSPI_NAND:
+ sprintf(bootcmd_str, QSPI_NAND_BOOTCOMMAND);
+ break;
+#endif
+#ifdef XSPI_NAND_BOOTCOMMAND
+ case BOOT_SOURCE_XSPI_NAND:
+ sprintf(bootcmd_str, XSPI_NAND_BOOTCOMMAND);
+ break;
+#endif
+#ifdef SD_BOOTCOMMAND
+ case BOOT_SOURCE_SD_MMC:
+ sprintf(bootcmd_str, SD_BOOTCOMMAND);
+ break;
+#endif
+#ifdef SD2_BOOTCOMMAND
+ case BOOT_SOURCE_SD_MMC2:
+ sprintf(bootcmd_str, SD2_BOOTCOMMAND);
+ break;
+#endif
+ default:
+#ifdef QSPI_NOR_BOOTCOMMAND
+ sprintf(bootcmd_str, QSPI_NOR_BOOTCOMMAND);
+#endif
+ break;
+ }
+
+ ret = env_set("bootcmd", bootcmd_str);
+ if (ret) {
+ printf("Failed to set bootcmd: ret = %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+int fsl_setenv_mcinitcmd(void)
+{
+ int ret = 0;
+ enum boot_src src = get_boot_src();
+
+ switch (src) {
+#ifdef IFC_MC_INIT_CMD
+ case BOOT_SOURCE_IFC_NAND:
+ case BOOT_SOURCE_IFC_NOR:
+ ret = env_set("mcinitcmd", IFC_MC_INIT_CMD);
+ break;
+#endif
+#ifdef QSPI_MC_INIT_CMD
+ case BOOT_SOURCE_QSPI_NAND:
+ case BOOT_SOURCE_QSPI_NOR:
+ ret = env_set("mcinitcmd", QSPI_MC_INIT_CMD);
+ break;
+#endif
+#ifdef XSPI_MC_INIT_CMD
+ case BOOT_SOURCE_XSPI_NAND:
+ case BOOT_SOURCE_XSPI_NOR:
+ ret = env_set("mcinitcmd", XSPI_MC_INIT_CMD);
+ break;
+#endif
+#ifdef SD_MC_INIT_CMD
+ case BOOT_SOURCE_SD_MMC:
+ ret = env_set("mcinitcmd", SD_MC_INIT_CMD);
+ break;
+#endif
+#ifdef SD2_MC_INIT_CMD
+ case BOOT_SOURCE_SD_MMC2:
+ ret = env_set("mcinitcmd", SD2_MC_INIT_CMD);
+ break;
+#endif
+ default:
+#ifdef QSPI_MC_INIT_CMD
+ ret = env_set("mcinitcmd", QSPI_MC_INIT_CMD);
+#endif
+ break;
+ }
+
+ if (ret) {
+ printf("Failed to set mcinitcmd: ret = %d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_BOARD_LATE_INIT
+__weak int fsl_board_late_init(void)
+{
+ return 0;
+}
+
+#define DWC3_GSBUSCFG0 0xc100
+#define DWC3_GSBUSCFG0_CACHETYPE_SHIFT 16
+#define DWC3_GSBUSCFG0_CACHETYPE(n) (((n) & 0xffff) \
+ << DWC3_GSBUSCFG0_CACHETYPE_SHIFT)
+
+void enable_dwc3_snooping(void)
+{
+ int ret;
+ u32 val;
+ struct udevice *bus;
+ struct uclass *uc;
+ fdt_addr_t dwc3_base;
+
+ ret = uclass_get(UCLASS_USB, &uc);
+ if (ret)
+ return;
+
+ uclass_foreach_dev(bus, uc) {
+ if (!strcmp(bus->driver->of_match->compatible, "fsl,layerscape-dwc3")) {
+ dwc3_base = devfdt_get_addr(bus);
+ if (dwc3_base == FDT_ADDR_T_NONE) {
+ dev_err(bus, "dwc3 regs missing\n");
+ continue;
+ }
+ val = in_le32(dwc3_base + DWC3_GSBUSCFG0);
+ val &= ~DWC3_GSBUSCFG0_CACHETYPE(~0);
+ val |= DWC3_GSBUSCFG0_CACHETYPE(0x2222);
+ writel(val, dwc3_base + DWC3_GSBUSCFG0);
+ }
+ }
+}
+
+int board_late_init(void)
+{
+#ifdef CONFIG_CHAIN_OF_TRUST
+ fsl_setenv_chain_of_trust();
+#endif
+#ifdef CONFIG_TFABOOT
+ /*
+ * Set bootcmd and mcinitcmd if they don't exist in the environment.
+ */
+ if (!env_get("bootcmd"))
+ fsl_setenv_bootcmd();
+ if (!env_get("mcinitcmd"))
+ fsl_setenv_mcinitcmd();
+#endif
+#ifdef CONFIG_QSPI_AHB_INIT
+ qspi_ahb_init();
+#endif
+#ifdef CONFIG_FSPI_AHB_EN_4BYTE
+ fspi_ahb_init();
+#endif
+
+ if (IS_ENABLED(CONFIG_DM))
+ enable_dwc3_snooping();
+
+ return fsl_board_late_init();
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/spintable.S b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/spintable.S
new file mode 100644
index 000000000..363ded03e
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/spintable.S
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2014-2015 Freescale Semiconductor
+ * Copyright 2019 NXP
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+#include <asm/system.h>
+#include <asm/arch/mp.h>
+
+.align 3
+.global secondary_boot_addr
+secondary_boot_addr:
+ .quad __secondary_boot_func
+
+.global secondary_boot_code_start
+secondary_boot_code_start:
+ .quad __secondary_boot_code_start
+
+.global secondary_boot_code_size
+secondary_boot_code_size:
+ .quad __secondary_boot_code_end - __secondary_boot_code_start
+
+ /* Using 64 bit alignment since the spin table is accessed as data */
+ .align 3
+ /* Secondary Boot Code starts here */
+__secondary_boot_code_start:
+__spin_table:
+ .space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE
+
+ .align 2
+__secondary_boot_func:
+ /*
+ * MPIDR_EL1 Fields:
+ * MPIDR[1:0] = AFF0_CPUID <- Core ID (0,1)
+ * MPIDR[7:2] = AFF0_RES
+ * MPIDR[15:8] = AFF1_CLUSTERID <- Cluster ID (0,1,2,3)
+ * MPIDR[23:16] = AFF2_CLUSTERID
+ * MPIDR[24] = MT
+ * MPIDR[29:25] = RES0
+ * MPIDR[30] = U
+ * MPIDR[31] = ME
+ * MPIDR[39:32] = AFF3
+ *
+ * Linear Processor ID (LPID) calculation from MPIDR_EL1:
+ * (We only use AFF0_CPUID and AFF1_CLUSTERID for now
+ * until AFF2_CLUSTERID and AFF3 have non-zero values)
+ *
+ * LPID = MPIDR[15:8] | MPIDR[1:0]
+ */
+ mrs x0, mpidr_el1
+ ubfm x1, x0, #8, #15
+ ubfm x2, x0, #0, #1
+ orr x10, x2, x1, lsl #2 /* x10 has LPID */
+ ubfm x9, x0, #0, #15 /* x9 contains MPIDR[15:0] */
+ /*
+ * offset of the spin table element for this core from start of spin
+ * table (each elem is padded to 64 bytes)
+ */
+ lsl x1, x10, #6
+ adr x0, __spin_table
+ /* physical address of this cpus spin table element */
+ add x11, x1, x0
+
+ adr x0, __real_cntfrq
+ ldr x0, [x0]
+ msr cntfrq_el0, x0 /* set with real frequency */
+ str x9, [x11, #16] /* LPID */
+ mov x4, #1
+ str x4, [x11, #8] /* STATUS */
+ dsb sy
+
+1:
+ wfe
+ ldr x4, [x11]
+ cbz x4, 1b
+ mrs x1, sctlr_el2
+ tbz x1, #25, 2f
+ rev x4, x4 /* BE to LE conversion */
+2:
+ ldr x6, =ES_TO_AARCH64
+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+ adr x5, 3f
+ switch_el x7, 0f, _dead_loop, _dead_loop
+0: armv8_switch_to_el2_m x5, x6, x7
+#endif
+3:
+ ldr x7, [x11, #24] /* ARCH_COMP */
+ cbz x7, 4f
+ ldr x6, =ES_TO_AARCH32
+4:
+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+ switch_el x7, _dead_loop, 0f, _dead_loop
+0: armv8_switch_to_el1_m x4, x6, x7
+#else
+ switch_el x7, 0f, _dead_loop, _dead_loop
+0: armv8_switch_to_el2_m x4, x6, x7
+#endif
+
+_dead_loop:
+ wfe
+ b _dead_loop
+
+ /* Ensure that the literals used by the secondary boot code are
+ * assembled within it (this is required so that we can protect
+ * this area with a single memreserve region
+ */
+ .ltorg
+
+ /* 64 bit alignment for elements accessed as data */
+ .align 3
+ .global __real_cntfrq
+__real_cntfrq:
+ .quad COUNTER_FREQUENCY
+ /* Secondary Boot Code ends here */
+__secondary_boot_code_end:
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/spl.c b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/spl.c
new file mode 100644
index 000000000..b3f1148f9
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fsl-layerscape/spl.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014-2015 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <clock_legacy.h>
+#include <cpu_func.h>
+#include <debug_uart.h>
+#include <env.h>
+#include <hang.h>
+#include <image.h>
+#include <init.h>
+#include <log.h>
+#include <spl.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <fsl_ifc.h>
+#include <i2c.h>
+#include <fsl_csu.h>
+#include <asm/arch/fdt.h>
+#include <asm/arch/ppa.h>
+#include <asm/arch/soc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 spl_boot_device(void)
+{
+#ifdef CONFIG_SPL_MMC_SUPPORT
+ return BOOT_DEVICE_MMC1;
+#endif
+#ifdef CONFIG_SPL_NAND_SUPPORT
+ return BOOT_DEVICE_NAND;
+#endif
+#ifdef CONFIG_QSPI_BOOT
+ return BOOT_DEVICE_NOR;
+#endif
+ return 0;
+}
+
+#ifdef CONFIG_SPL_BUILD
+
+void spl_board_init(void)
+{
+#if defined(CONFIG_NXP_ESBC) && defined(CONFIG_FSL_LSCH2)
+ /*
+ * In case of Secure Boot, the IBR configures the SMMU
+ * to allow only Secure transactions.
+ * SMMU must be reset in bypass mode.
+ * Set the ClientPD bit and Clear the USFCFG Bit
+ */
+ u32 val;
+ val = (in_le32(SMMU_SCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK);
+ out_le32(SMMU_SCR0, val);
+ val = (in_le32(SMMU_NSCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK);
+ out_le32(SMMU_NSCR0, val);
+#endif
+#ifdef CONFIG_LAYERSCAPE_NS_ACCESS
+ enable_layerscape_ns_access();
+#endif
+#ifdef CONFIG_SPL_FSL_LS_PPA
+ ppa_init();
+#endif
+}
+
+void board_init_f(ulong dummy)
+{
+ int ret;
+
+ icache_enable();
+ /* Clear global data */
+ memset((void *)gd, 0, sizeof(gd_t));
+ if (IS_ENABLED(CONFIG_DEBUG_UART))
+ debug_uart_init();
+ board_early_init_f();
+ ret = spl_early_init();
+ if (ret) {
+ debug("spl_early_init() failed: %d\n", ret);
+ hang();
+ }
+ timer_init();
+#ifdef CONFIG_ARCH_LS2080A
+ env_init();
+#endif
+ get_clocks();
+
+ preloader_console_init();
+ spl_set_bd();
+
+#ifdef CONFIG_SYS_I2C
+#ifdef CONFIG_SPL_I2C_SUPPORT
+ i2c_init_all();
+#endif
+#endif
+#ifdef CONFIG_VID
+ init_func_vid();
+#endif
+ dram_init();
+#ifdef CONFIG_SPL_FSL_LS_PPA
+#ifndef CONFIG_SYS_MEM_RESERVE_SECURE
+#error Need secure RAM for PPA
+#endif
+ /*
+ * Secure memory location is determined in dram_init_banksize().
+ * gd->ram_size is deducted by the size of secure ram.
+ */
+ dram_init_banksize();
+
+ /*
+ * After dram_init_bank_size(), we know U-Boot only uses the first
+ * memory bank regardless how big the memory is.
+ */
+ gd->ram_top = gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
+
+ /*
+ * If PPA is loaded, U-Boot will resume running at EL2.
+ * Cache and MMU will be enabled. Need a place for TLB.
+ * U-Boot will be relocated to the end of available memory
+ * in first bank. At this point, we cannot know how much
+ * memory U-Boot uses. Put TLB table lower by SPL_TLB_SETBACK
+ * to avoid overlapping. As soon as the RAM version U-Boot sets
+ * up new MMU, this space is no longer needed.
+ */
+ gd->ram_top -= SPL_TLB_SETBACK;
+ gd->arch.tlb_size = PGTABLE_SIZE;
+ gd->arch.tlb_addr = (gd->ram_top - gd->arch.tlb_size) & ~(0x10000 - 1);
+ gd->arch.tlb_allocated = gd->arch.tlb_addr;
+#endif /* CONFIG_SPL_FSL_LS_PPA */
+#if defined(CONFIG_QSPI_AHB_INIT) && defined(CONFIG_QSPI_BOOT)
+ qspi_ahb_init();
+#endif
+}
+
+#ifdef CONFIG_SPL_OS_BOOT
+/*
+ * Return
+ * 0 if booting into OS is selected
+ * 1 if booting into U-Boot is selected
+ */
+int spl_start_uboot(void)
+{
+ env_init();
+ if (env_get_yesno("boot_os") != 0)
+ return 0;
+
+ return 1;
+}
+#endif /* CONFIG_SPL_OS_BOOT */
+#endif /* CONFIG_SPL_BUILD */
diff --git a/roms/u-boot/arch/arm/cpu/armv8/fwcall.c b/roms/u-boot/arch/arm/cpu/armv8/fwcall.c
new file mode 100644
index 000000000..16914dc1e
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/fwcall.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0+
+/**
+ * (C) Copyright 2014, Cavium Inc.
+ * (C) Copyright 2017, Xilinx Inc.
+ *
+**/
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/cache.h>
+#include <asm/macro.h>
+#include <asm/psci.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+
+/*
+ * Issue the hypervisor call
+ *
+ * x0~x7: input arguments
+ * x0~x3: output arguments
+ */
+static void hvc_call(struct pt_regs *args)
+{
+ asm volatile(
+ "ldr x0, %0\n"
+ "ldr x1, %1\n"
+ "ldr x2, %2\n"
+ "ldr x3, %3\n"
+ "ldr x4, %4\n"
+ "ldr x5, %5\n"
+ "ldr x6, %6\n"
+ "hvc #0\n"
+ "str x0, %0\n"
+ "str x1, %1\n"
+ "str x2, %2\n"
+ "str x3, %3\n"
+ : "+m" (args->regs[0]), "+m" (args->regs[1]),
+ "+m" (args->regs[2]), "+m" (args->regs[3])
+ : "m" (args->regs[4]), "m" (args->regs[5]),
+ "m" (args->regs[6])
+ : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
+ "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
+ "x16", "x17");
+}
+
+/*
+ * void smc_call(arg0, arg1...arg7)
+ *
+ * issue the secure monitor call
+ *
+ * x0~x7: input arguments
+ * x0~x3: output arguments
+ */
+
+void smc_call(struct pt_regs *args)
+{
+ asm volatile(
+ "ldr x0, %0\n"
+ "ldr x1, %1\n"
+ "ldr x2, %2\n"
+ "ldr x3, %3\n"
+ "ldr x4, %4\n"
+ "ldr x5, %5\n"
+ "ldr x6, %6\n"
+ "smc #0\n"
+ "str x0, %0\n"
+ "str x1, %1\n"
+ "str x2, %2\n"
+ "str x3, %3\n"
+ : "+m" (args->regs[0]), "+m" (args->regs[1]),
+ "+m" (args->regs[2]), "+m" (args->regs[3])
+ : "m" (args->regs[4]), "m" (args->regs[5]),
+ "m" (args->regs[6])
+ : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
+ "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
+ "x16", "x17");
+}
+
+/*
+ * For now, all systems we support run at least in EL2 and thus
+ * trigger PSCI calls to EL3 using SMC. If anyone ever wants to
+ * use PSCI on U-Boot running below a hypervisor, please detect
+ * this and set the flag accordingly.
+ */
+static const bool use_smc_for_psci = true;
+
+void __noreturn psci_system_reset(void)
+{
+ struct pt_regs regs;
+
+ regs.regs[0] = ARM_PSCI_0_2_FN_SYSTEM_RESET;
+
+ if (use_smc_for_psci)
+ smc_call(&regs);
+ else
+ hvc_call(&regs);
+
+ while (1)
+ ;
+}
+
+void __noreturn psci_system_reset2(u32 reset_level, u32 cookie)
+{
+ struct pt_regs regs;
+
+ regs.regs[0] = ARM_PSCI_0_2_FN64_SYSTEM_RESET2;
+ regs.regs[1] = PSCI_RESET2_TYPE_VENDOR | reset_level;
+ regs.regs[2] = cookie;
+ if (use_smc_for_psci)
+ smc_call(&regs);
+ else
+ hvc_call(&regs);
+
+ while (1)
+ ;
+}
+
+void __noreturn psci_system_off(void)
+{
+ struct pt_regs regs;
+
+ regs.regs[0] = ARM_PSCI_0_2_FN_SYSTEM_OFF;
+
+ if (use_smc_for_psci)
+ smc_call(&regs);
+ else
+ hvc_call(&regs);
+
+ while (1)
+ ;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/generic_timer.c b/roms/u-boot/arch/arm/cpu/armv8/generic_timer.c
new file mode 100644
index 000000000..f27a74b9d
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/generic_timer.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <bootstage.h>
+#include <command.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <asm/system.h>
+#include <linux/bitops.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Generic timer implementation of get_tbclk()
+ */
+unsigned long get_tbclk(void)
+{
+ unsigned long cntfrq;
+ asm volatile("mrs %0, cntfrq_el0" : "=r" (cntfrq));
+ return cntfrq;
+}
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008585
+/*
+ * FSL erratum A-008585 says that the ARM generic timer counter "has the
+ * potential to contain an erroneous value for a small number of core
+ * clock cycles every time the timer value changes".
+ * This sometimes leads to a consecutive counter read returning a lower
+ * value than the previous one, thus reporting the time to go backwards.
+ * The workaround is to read the counter twice and only return when the value
+ * was the same in both reads.
+ * Assumes that the CPU runs in much higher frequency than the timer.
+ */
+unsigned long timer_read_counter(void)
+{
+ unsigned long cntpct;
+ unsigned long temp;
+
+ isb();
+ asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
+ asm volatile("mrs %0, cntpct_el0" : "=r" (temp));
+ while (temp != cntpct) {
+ asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
+ asm volatile("mrs %0, cntpct_el0" : "=r" (temp));
+ }
+
+ return cntpct;
+}
+#elif CONFIG_SUNXI_A64_TIMER_ERRATUM
+/*
+ * This erratum sometimes flips the lower 11 bits of the counter value
+ * to all 0's or all 1's, leading to jumps forwards or backwards.
+ * Backwards jumps might be interpreted all roll-overs and be treated as
+ * huge jumps forward.
+ * The workaround is to check whether the lower 11 bits of the counter are
+ * all 0 or all 1, then discard this value and read again.
+ * This occasionally discards valid values, but will catch all erroneous
+ * reads and fixes the problem reliably. Also this mostly requires only a
+ * single read, so does not have any significant overhead.
+ * The algorithm was conceived by Samuel Holland.
+ */
+unsigned long timer_read_counter(void)
+{
+ unsigned long cntpct;
+
+ isb();
+ do {
+ asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
+ } while (((cntpct + 1) & GENMASK(10, 0)) <= 1);
+
+ return cntpct;
+}
+#else
+/*
+ * timer_read_counter() using the Arm Generic Timer (aka arch timer).
+ */
+unsigned long timer_read_counter(void)
+{
+ unsigned long cntpct;
+
+ isb();
+ asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
+
+ return cntpct;
+}
+#endif
+
+uint64_t get_ticks(void)
+{
+ unsigned long ticks = timer_read_counter();
+
+ gd->arch.tbl = ticks;
+
+ return ticks;
+}
+
+unsigned long usec2ticks(unsigned long usec)
+{
+ ulong ticks;
+ if (usec < 1000)
+ ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000;
+ else
+ ticks = ((usec / 10) * (get_tbclk() / 100000));
+
+ return ticks;
+}
+
+ulong timer_get_boot_us(void)
+{
+ u64 val = get_ticks() * 1000000;
+
+ return val / get_tbclk();
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/hisilicon/Makefile b/roms/u-boot/arch/arm/cpu/armv8/hisilicon/Makefile
new file mode 100644
index 000000000..cf2fe05f4
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/hisilicon/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2015 Linaro
+# Peter Griffin <peter.griffin@linaro.org>
+
+obj-y += pinmux.o
diff --git a/roms/u-boot/arch/arm/cpu/armv8/hisilicon/pinmux.c b/roms/u-boot/arch/arm/cpu/armv8/hisilicon/pinmux.c
new file mode 100644
index 000000000..5183e00a4
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/hisilicon/pinmux.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Linaro.
+ * Peter Griffin <peter.griffin@linaro.org>
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <log.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/pinmux.h>
+#include <linux/bitops.h>
+
+struct hi6220_pinmux0_regs *pmx0 =
+ (struct hi6220_pinmux0_regs *)HI6220_PINMUX0_BASE;
+
+struct hi6220_pinmux1_regs *pmx1 =
+ (struct hi6220_pinmux1_regs *)HI6220_PINMUX1_BASE;
+
+static void hi6220_uart_config(int peripheral)
+{
+ switch (peripheral) {
+ case PERIPH_ID_UART0:
+ writel(MUX_M0, &pmx0->iomg[48]); /* UART0_RXD */
+ writel(MUX_M0, &pmx0->iomg[49]); /* UART0_TXD */
+
+ writel(DRIVE1_02MA | PULL_UP, &pmx1->iocfg[49]); /* UART0_RXD */
+ writel(DRIVE1_02MA | PULL_UP, &pmx1->iocfg[50]); /* UART0_TXD */
+ break;
+
+ case PERIPH_ID_UART1:
+ writel(MUX_M0, &pmx0->iomg[50]); /* UART1_CTS_N */
+ writel(MUX_M0, &pmx0->iomg[51]); /* UART1_RTS_N */
+ writel(MUX_M0, &pmx0->iomg[52]); /* UART1_RXD */
+ writel(MUX_M0, &pmx0->iomg[53]); /* UART1_TXD */
+
+ writel(DRIVE1_02MA | PULL_UP, &pmx1->iocfg[51]); /*UART1_CTS_N*/
+ writel(DRIVE1_02MA | PULL_UP, &pmx1->iocfg[53]); /* UART1_RXD */
+ writel(DRIVE1_02MA, &pmx1->iocfg[52]); /* UART1_RTS_N */
+ writel(DRIVE1_02MA, &pmx1->iocfg[54]); /* UART1_TXD */
+ break;
+
+ case PERIPH_ID_UART2:
+ writel(MUX_M0, &pmx0->iomg[54]); /* UART2_CTS_N */
+ writel(MUX_M0, &pmx0->iomg[55]); /* UART2_RTS_N */
+ writel(MUX_M0, &pmx0->iomg[56]); /* UART2_RXD */
+ writel(MUX_M0, &pmx0->iomg[57]); /* UART2_TXD */
+
+ writel(DRIVE1_02MA, &pmx1->iocfg[55]); /* UART2_CTS_N */
+ writel(DRIVE1_02MA, &pmx1->iocfg[56]); /* UART2_RTS_N */
+ writel(DRIVE1_02MA, &pmx1->iocfg[57]); /* UART2_RXD */
+ writel(DRIVE1_02MA, &pmx1->iocfg[58]); /* UART2_TXD */
+ break;
+
+ case PERIPH_ID_UART3:
+ writel(MUX_M1, &pmx0->iomg[96]); /* UART3_CTS_N */
+ writel(MUX_M1, &pmx0->iomg[97]); /* UART3_RTS_N */
+ writel(MUX_M1, &pmx0->iomg[98]); /* UART3_RXD */
+ writel(MUX_M1, &pmx0->iomg[99]); /* UART3_TXD */
+
+ /* UART3_TXD */
+ writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[100]);
+ /* UART3_RTS_N */
+ writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[101]);
+ /* UART3_RXD */
+ writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[102]);
+ /* UART3_TXD */
+ writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[103]);
+ break;
+
+ case PERIPH_ID_UART4:
+ writel(MUX_M1, &pmx0->iomg[116]); /* UART4_CTS_N */
+ writel(MUX_M1, &pmx0->iomg[117]); /* UART4_RTS_N */
+ writel(MUX_M1, &pmx0->iomg[118]); /* UART4_RXD */
+ writel(MUX_M1, &pmx0->iomg[119]); /* UART4_TXD */
+
+ /* UART4_CTS_N */
+ writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[120]);
+ /* UART4_RTS_N */
+ writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[121]);
+ /* UART4_RXD */
+ writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[122]);
+ /* UART4_TXD */
+ writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[123]);
+ break;
+ case PERIPH_ID_UART5:
+ writel(MUX_M1, &pmx0->iomg[114]); /* UART5_RXD */
+ writel(MUX_M1, &pmx0->iomg[115]); /* UART5_TXD */
+
+ /* UART5_RXD */
+ writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[118]);
+ /* UART5_TXD */
+ writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[119]);
+
+ break;
+
+ default:
+ debug("%s: invalid peripheral %d", __func__, peripheral);
+ return;
+ }
+}
+
+static int hi6220_mmc_config(int peripheral)
+{
+ u32 tmp;
+
+ switch (peripheral) {
+ case PERIPH_ID_SDMMC0:
+
+ /* eMMC pinmux config */
+ writel(MUX_M0, &pmx0->iomg[64]); /* EMMC_CLK */
+ writel(MUX_M0, &pmx0->iomg[65]); /* EMMC_CMD */
+ writel(MUX_M0, &pmx0->iomg[66]); /* EMMC_DATA0 */
+ writel(MUX_M0, &pmx0->iomg[67]); /* EMMC_DATA1 */
+ writel(MUX_M0, &pmx0->iomg[68]); /* EMMC_DATA2 */
+ writel(MUX_M0, &pmx0->iomg[69]); /* EMMC_DATA3 */
+ writel(MUX_M0, &pmx0->iomg[70]); /* EMMC_DATA4 */
+ writel(MUX_M0, &pmx0->iomg[71]); /* EMMC_DATA5 */
+ writel(MUX_M0, &pmx0->iomg[72]); /* EMMC_DATA6 */
+ writel(MUX_M0, &pmx0->iomg[73]); /* EMMC_DATA7 */
+
+ /*eMMC configure up/down/drive */
+ writel(DRIVE1_08MA, &pmx1->iocfg[65]); /* EMMC_CLK */
+
+ tmp = DRIVE1_04MA | PULL_UP;
+ writel(tmp, &pmx1->iocfg[65]); /* EMMC_CMD */
+ writel(tmp, &pmx1->iocfg[66]); /* EMMC_DATA0 */
+ writel(tmp, &pmx1->iocfg[67]); /* EMMC_DATA1 */
+ writel(tmp, &pmx1->iocfg[68]); /* EMMC_DATA2 */
+ writel(tmp, &pmx1->iocfg[69]); /* EMMC_DATA3 */
+ writel(tmp, &pmx1->iocfg[70]); /* EMMC_DATA4 */
+ writel(tmp, &pmx1->iocfg[71]); /* EMMC_DATA5 */
+ writel(tmp, &pmx1->iocfg[72]); /* EMMC_DATA6 */
+ writel(tmp, &pmx1->iocfg[73]); /* EMMC_DATA7 */
+
+ writel(DRIVE1_04MA, &pmx1->iocfg[73]); /* EMMC_RST_N */
+ break;
+
+ case PERIPH_ID_SDMMC1:
+
+ writel(MUX_M0, &pmx0->iomg[3]); /* SD_CLK */
+ writel(MUX_M0, &pmx0->iomg[4]); /* SD_CMD */
+ writel(MUX_M0, &pmx0->iomg[5]); /* SD_DATA0 */
+ writel(MUX_M0, &pmx0->iomg[6]); /* SD_DATA1 */
+ writel(MUX_M0, &pmx0->iomg[7]); /* SD_DATA2 */
+ writel(MUX_M0, &pmx0->iomg[8]); /* SD_DATA3 */
+
+ writel(DRIVE1_10MA | BIT(2), &pmx1->iocfg[3]); /*SD_CLK*/
+ writel(DRIVE1_08MA | BIT(2), &pmx1->iocfg[4]); /*SD_CMD*/
+ writel(DRIVE1_08MA | BIT(2), &pmx1->iocfg[5]); /*SD_DATA0*/
+ writel(DRIVE1_08MA | BIT(2), &pmx1->iocfg[6]); /*SD_DATA1*/
+ writel(DRIVE1_08MA | BIT(2), &pmx1->iocfg[7]); /*SD_DATA2*/
+ writel(DRIVE1_08MA | BIT(2), &pmx1->iocfg[8]); /*SD_DATA3*/
+ break;
+
+ default:
+ debug("%s: invalid peripheral %d", __func__, peripheral);
+ return -1;
+ }
+
+ return 0;
+}
+
+int hi6220_pinmux_config(int peripheral)
+{
+ switch (peripheral) {
+ case PERIPH_ID_UART0:
+ case PERIPH_ID_UART1:
+ case PERIPH_ID_UART2:
+ case PERIPH_ID_UART3:
+ hi6220_uart_config(peripheral);
+ break;
+ case PERIPH_ID_SDMMC0:
+ case PERIPH_ID_SDMMC1:
+ return hi6220_mmc_config(peripheral);
+ default:
+ debug("%s: invalid peripheral %d", __func__, peripheral);
+ return -1;
+ }
+
+ return 0;
+}
+
+
diff --git a/roms/u-boot/arch/arm/cpu/armv8/linux-kernel-image-header-vars.h b/roms/u-boot/arch/arm/cpu/armv8/linux-kernel-image-header-vars.h
new file mode 100644
index 000000000..b4220e493
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/linux-kernel-image-header-vars.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * (C) Copyright 2017 NVIDIA Corporation <www.nvidia.com>
+ *
+ * Derived from Linux kernel v4.14 files:
+ *
+ * arch/arm64/include/asm/assembler.h:
+ * Based on arch/arm/include/asm/assembler.h, arch/arm/mm/proc-macros.S
+ * Copyright (C) 1996-2000 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * arch/arm64/kernel/head.S:
+ * Based on arch/arm/kernel/head.S
+ * Copyright (C) 1994-2002 Russell King
+ * Copyright (C) 2003-2012 ARM Ltd.
+ * Authors: Catalin Marinas <catalin.marinas@arm.com>
+ * Will Deacon <will.deacon@arm.com>
+ *
+ * arch/arm64/kernel/image.h:
+ * Copyright (C) 2014 ARM Ltd.
+ */
+
+/*
+ * There aren't any ELF relocations we can use to endian-swap values known only
+ * at link time (e.g. the subtraction of two symbol addresses), so we must get
+ * the linker to endian-swap certain values before emitting them.
+ *
+ * Note that, in order for this to work when building the ELF64 PIE executable
+ * (for KASLR), these values should not be referenced via R_AARCH64_ABS64
+ * relocations, since these are fixed up at runtime rather than at build time
+ * when PIE is in effect. So we need to split them up in 32-bit high and low
+ * words.
+ */
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define DATA_LE32(data) \
+ ((((data) & 0x000000ff) << 24) | \
+ (((data) & 0x0000ff00) << 8) | \
+ (((data) & 0x00ff0000) >> 8) | \
+ (((data) & 0xff000000) >> 24))
+#else
+#define DATA_LE32(data) ((data) & 0xffffffff)
+#endif
+
+#define DEFINE_IMAGE_LE64(sym, data) \
+ sym##_lo32 = DATA_LE32((data) & 0xffffffff); \
+ sym##_hi32 = DATA_LE32((data) >> 32)
+
+#define __MAX(a, b) (((a) > (b)) ? (a) : (b))
+#define __CODE_DATA_SIZE (__bss_start - _start)
+#define __BSS_SIZE (__bss_end - __bss_start)
+#ifdef CONFIG_INIT_SP_RELATIVE
+#define __MAX_EXTRA_RAM_USAGE __MAX(__BSS_SIZE, CONFIG_SYS_INIT_SP_BSS_OFFSET)
+#else
+#define __MAX_EXTRA_RAM_USAGE __BSS_SIZE
+#endif
+#define __MEM_USAGE (__CODE_DATA_SIZE + __MAX_EXTRA_RAM_USAGE)
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define __HEAD_FLAG_BE 1
+#else
+#define __HEAD_FLAG_BE 0
+#endif
+
+#define __HEAD_FLAG_PAGE_SIZE 1 /* 4K hard-coded */
+
+#define __HEAD_FLAG_PHYS_BASE 1
+
+#define __HEAD_FLAGS ((__HEAD_FLAG_BE << 0) | \
+ (__HEAD_FLAG_PAGE_SIZE << 1) | \
+ (__HEAD_FLAG_PHYS_BASE << 3))
+
+#define TEXT_OFFSET (CONFIG_SYS_TEXT_BASE - \
+ CONFIG_LNX_KRNL_IMG_TEXT_OFFSET_BASE)
+
+/*
+ * These will output as part of the Image header, which should be little-endian
+ * regardless of the endianness of the kernel. While constant values could be
+ * endian swapped in head.S, all are done here for consistency.
+ */
+#define HEAD_SYMBOLS \
+ DEFINE_IMAGE_LE64(_kernel_size_le, __MEM_USAGE); \
+ DEFINE_IMAGE_LE64(_kernel_offset_le, TEXT_OFFSET); \
+ DEFINE_IMAGE_LE64(_kernel_flags_le, __HEAD_FLAGS);
+
+ HEAD_SYMBOLS
diff --git a/roms/u-boot/arch/arm/cpu/armv8/lowlevel_init.S b/roms/u-boot/arch/arm/cpu/armv8/lowlevel_init.S
new file mode 100644
index 000000000..f4f0cdce9
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/lowlevel_init.S
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * A lowlevel_init function that sets up the stack to call a C function to
+ * perform further init.
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+ /*
+ * Setup a temporary stack. Global data is not available yet.
+ */
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
+ ldr w0, =CONFIG_SPL_STACK
+#else
+ ldr w0, =CONFIG_SYS_INIT_SP_ADDR
+#endif
+ bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */
+
+ /*
+ * Save the old LR(passed in x29) and the current LR to stack
+ */
+ stp x29, x30, [sp, #-16]!
+
+ /*
+ * Call the very early init function. This should do only the
+ * absolute bare minimum to get started. It should not:
+ *
+ * - set up DRAM
+ * - use global_data
+ * - clear BSS
+ * - try to start a console
+ *
+ * For boards with SPL this should be empty since SPL can do all of
+ * this init in the SPL board_init_f() function which is called
+ * immediately after this.
+ */
+ bl s_init
+ ldp x29, x30, [sp]
+ ret
+ENDPROC(lowlevel_init)
diff --git a/roms/u-boot/arch/arm/cpu/armv8/psci.S b/roms/u-boot/arch/arm/cpu/armv8/psci.S
new file mode 100644
index 000000000..7ffc8dbad
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/psci.S
@@ -0,0 +1,331 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Author: Hongbo Zhang <hongbo.zhang@nxp.com>
+ * This file implements LS102X platform PSCI SYSTEM-SUSPEND function
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/psci.h>
+#include <asm/secure.h>
+
+/* Default PSCI function, return -1, Not Implemented */
+#define PSCI_DEFAULT(__fn) \
+ ENTRY(__fn); \
+ mov w0, #ARM_PSCI_RET_NI; \
+ ret; \
+ ENDPROC(__fn); \
+ .weak __fn
+
+/* PSCI function and ID table definition*/
+#define PSCI_TABLE(__id, __fn) \
+ .quad __id; \
+ .quad __fn
+
+.pushsection ._secure.text, "ax"
+
+/* 32 bits PSCI default functions */
+PSCI_DEFAULT(psci_version)
+PSCI_DEFAULT(psci_cpu_suspend)
+PSCI_DEFAULT(psci_cpu_off)
+PSCI_DEFAULT(psci_cpu_on)
+PSCI_DEFAULT(psci_affinity_info)
+PSCI_DEFAULT(psci_migrate)
+PSCI_DEFAULT(psci_migrate_info_type)
+PSCI_DEFAULT(psci_migrate_info_up_cpu)
+PSCI_DEFAULT(psci_system_off)
+PSCI_DEFAULT(psci_system_reset)
+PSCI_DEFAULT(psci_features)
+PSCI_DEFAULT(psci_cpu_freeze)
+PSCI_DEFAULT(psci_cpu_default_suspend)
+PSCI_DEFAULT(psci_node_hw_state)
+PSCI_DEFAULT(psci_system_suspend)
+PSCI_DEFAULT(psci_set_suspend_mode)
+PSCI_DEFAULT(psi_stat_residency)
+PSCI_DEFAULT(psci_stat_count)
+
+.align 3
+_psci_32_table:
+PSCI_TABLE(ARM_PSCI_FN_CPU_SUSPEND, psci_cpu_suspend)
+PSCI_TABLE(ARM_PSCI_FN_CPU_OFF, psci_cpu_off)
+PSCI_TABLE(ARM_PSCI_FN_CPU_ON, psci_cpu_on)
+PSCI_TABLE(ARM_PSCI_FN_MIGRATE, psci_migrate)
+PSCI_TABLE(ARM_PSCI_0_2_FN_PSCI_VERSION, psci_version)
+PSCI_TABLE(ARM_PSCI_0_2_FN_CPU_SUSPEND, psci_cpu_suspend)
+PSCI_TABLE(ARM_PSCI_0_2_FN_CPU_OFF, psci_cpu_off)
+PSCI_TABLE(ARM_PSCI_0_2_FN_CPU_ON, psci_cpu_on)
+PSCI_TABLE(ARM_PSCI_0_2_FN_AFFINITY_INFO, psci_affinity_info)
+PSCI_TABLE(ARM_PSCI_0_2_FN_MIGRATE, psci_migrate)
+PSCI_TABLE(ARM_PSCI_0_2_FN_MIGRATE_INFO_TYPE, psci_migrate_info_type)
+PSCI_TABLE(ARM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU, psci_migrate_info_up_cpu)
+PSCI_TABLE(ARM_PSCI_0_2_FN_SYSTEM_OFF, psci_system_off)
+PSCI_TABLE(ARM_PSCI_0_2_FN_SYSTEM_RESET, psci_system_reset)
+PSCI_TABLE(ARM_PSCI_1_0_FN_PSCI_FEATURES, psci_features)
+PSCI_TABLE(ARM_PSCI_1_0_FN_CPU_FREEZE, psci_cpu_freeze)
+PSCI_TABLE(ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND, psci_cpu_default_suspend)
+PSCI_TABLE(ARM_PSCI_1_0_FN_NODE_HW_STATE, psci_node_hw_state)
+PSCI_TABLE(ARM_PSCI_1_0_FN_SYSTEM_SUSPEND, psci_system_suspend)
+PSCI_TABLE(ARM_PSCI_1_0_FN_SET_SUSPEND_MODE, psci_set_suspend_mode)
+PSCI_TABLE(ARM_PSCI_1_0_FN_STAT_RESIDENCY, psi_stat_residency)
+PSCI_TABLE(ARM_PSCI_1_0_FN_STAT_COUNT, psci_stat_count)
+PSCI_TABLE(0, 0)
+
+/* 64 bits PSCI default functions */
+PSCI_DEFAULT(psci_cpu_suspend_64)
+PSCI_DEFAULT(psci_cpu_on_64)
+PSCI_DEFAULT(psci_affinity_info_64)
+PSCI_DEFAULT(psci_migrate_64)
+PSCI_DEFAULT(psci_migrate_info_up_cpu_64)
+PSCI_DEFAULT(psci_cpu_default_suspend_64)
+PSCI_DEFAULT(psci_node_hw_state_64)
+PSCI_DEFAULT(psci_system_suspend_64)
+PSCI_DEFAULT(psci_stat_residency_64)
+PSCI_DEFAULT(psci_stat_count_64)
+
+.align 3
+_psci_64_table:
+PSCI_TABLE(ARM_PSCI_0_2_FN64_CPU_SUSPEND, psci_cpu_suspend_64)
+PSCI_TABLE(ARM_PSCI_0_2_FN64_CPU_ON, psci_cpu_on_64)
+PSCI_TABLE(ARM_PSCI_0_2_FN64_AFFINITY_INFO, psci_affinity_info_64)
+PSCI_TABLE(ARM_PSCI_0_2_FN64_MIGRATE, psci_migrate_64)
+PSCI_TABLE(ARM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU, psci_migrate_info_up_cpu_64)
+PSCI_TABLE(ARM_PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND, psci_cpu_default_suspend_64)
+PSCI_TABLE(ARM_PSCI_1_0_FN64_NODE_HW_STATE, psci_node_hw_state_64)
+PSCI_TABLE(ARM_PSCI_1_0_FN64_SYSTEM_SUSPEND, psci_system_suspend_64)
+PSCI_TABLE(ARM_PSCI_1_0_FN64_STAT_RESIDENCY, psci_stat_residency_64)
+PSCI_TABLE(ARM_PSCI_1_0_FN64_STAT_COUNT, psci_stat_count_64)
+PSCI_TABLE(0, 0)
+
+.macro psci_enter
+ /* PSCI call is Fast Call(atomic), so mask DAIF */
+ mrs x15, DAIF
+ stp x15, xzr, [sp, #-16]!
+ ldr x15, =0x3C0
+ msr DAIF, x15
+ /* SMC convention, x18 ~ x30 should be saved by callee */
+ stp x29, x30, [sp, #-16]!
+ stp x27, x28, [sp, #-16]!
+ stp x25, x26, [sp, #-16]!
+ stp x23, x24, [sp, #-16]!
+ stp x21, x22, [sp, #-16]!
+ stp x19, x20, [sp, #-16]!
+ mrs x15, elr_el3
+ stp x18, x15, [sp, #-16]!
+.endm
+
+.macro psci_return
+ /* restore registers */
+ ldp x18, x15, [sp], #16
+ msr elr_el3, x15
+ ldp x19, x20, [sp], #16
+ ldp x21, x22, [sp], #16
+ ldp x23, x24, [sp], #16
+ ldp x25, x26, [sp], #16
+ ldp x27, x28, [sp], #16
+ ldp x29, x30, [sp], #16
+ /* restore DAIF */
+ ldp x15, xzr, [sp], #16
+ msr DAIF, x15
+ eret
+.endm
+
+/* Caller must put PSCI function-ID table base in x9 */
+handle_psci:
+ psci_enter
+1: ldr x10, [x9] /* Load PSCI function table */
+ cbz x10, 3f /* If reach the end, bail out */
+ cmp x10, x0
+ b.eq 2f /* PSCI function found */
+ add x9, x9, #16 /* If not match, try next entry */
+ b 1b
+
+2: ldr x11, [x9, #8] /* Load PSCI function */
+ blr x11 /* Call PSCI function */
+ psci_return
+
+3: mov x0, #ARM_PSCI_RET_NI
+ psci_return
+
+/*
+ * Handle SiP service functions defined in SiP service function table.
+ * Use DECLARE_SECURE_SVC(_name, _id, _fn) to add platform specific SiP
+ * service function into the SiP service function table.
+ * SiP service function table is located in '._secure_svc_tbl_entries' section,
+ * which is next to '._secure.text' section.
+ */
+handle_svc:
+ adr x9, __secure_svc_tbl_start
+ adr x10, __secure_svc_tbl_end
+ subs x12, x10, x9 /* Get number of entries in table */
+ b.eq 2f /* Make sure SiP function table is not empty */
+ psci_enter
+1: ldr x10, [x9] /* Load SiP function table */
+ ldr x11, [x9, #8]
+ cmp w10, w0
+ b.eq 2b /* SiP service function found */
+ add x9, x9, #SECURE_SVC_TBL_OFFSET /* Move to next entry */
+ subs x12, x12, #SECURE_SVC_TBL_OFFSET
+ b.eq 3b /* If reach the end, bail out */
+ b 1b
+2: ldr x0, =0xFFFFFFFF
+ eret
+
+handle_smc32:
+ /* SMC function ID 0x84000000-0x8400001F: 32 bits PSCI */
+ ldr w9, =0x8400001F
+ cmp w0, w9
+ b.gt handle_svc
+ ldr w9, =0x84000000
+ cmp w0, w9
+ b.lt handle_svc
+
+ adr x9, _psci_32_table
+ b handle_psci
+
+handle_smc64:
+ /* check SMC32 or SMC64 calls */
+ ubfx x9, x0, #30, #1
+ cbz x9, handle_smc32
+
+ /* SMC function ID 0xC4000000-0xC400001F: 64 bits PSCI */
+ ldr x9, =0xC400001F
+ cmp x0, x9
+ b.gt handle_svc
+ ldr x9, =0xC4000000
+ cmp x0, x9
+ b.lt handle_svc
+
+ adr x9, _psci_64_table
+ b handle_psci
+
+/*
+ * Get CPU ID from MPIDR, suppose every cluster has same number of CPU cores,
+ * Platform with asymmetric clusters should implement their own interface.
+ * In case this function being called by other platform's C code, the ARM
+ * Architecture Procedure Call Standard is considered, e.g. register X0 is
+ * used for the return value, while in this PSCI environment, X0 usually holds
+ * the SMC function identifier, so X0 should be saved by caller function.
+ */
+ENTRY(psci_get_cpu_id)
+#ifdef CONFIG_ARMV8_PSCI_CPUS_PER_CLUSTER
+ mrs x9, MPIDR_EL1
+ ubfx x9, x9, #8, #8
+ ldr x10, =CONFIG_ARMV8_PSCI_CPUS_PER_CLUSTER
+ mul x9, x10, x9
+#else
+ mov x9, xzr
+#endif
+ mrs x10, MPIDR_EL1
+ ubfx x10, x10, #0, #8
+ add x0, x10, x9
+ ret
+ENDPROC(psci_get_cpu_id)
+.weak psci_get_cpu_id
+
+/* CPU ID input in x0, stack top output in x0*/
+LENTRY(psci_get_cpu_stack_top)
+ adr x9, __secure_stack_end
+ lsl x0, x0, #ARM_PSCI_STACK_SHIFT
+ sub x0, x9, x0
+ ret
+ENDPROC(psci_get_cpu_stack_top)
+
+unhandled_exception:
+ b unhandled_exception /* simply dead loop */
+
+handle_sync:
+ mov x15, x30
+ mov x14, x0
+
+ bl psci_get_cpu_id
+ bl psci_get_cpu_stack_top
+ mov x9, #1
+ msr spsel, x9
+ mov sp, x0
+
+ mov x0, x14
+ mov x30, x15
+
+ mrs x9, esr_el3
+ ubfx x9, x9, #26, #6
+ cmp x9, #0x13
+ b.eq handle_smc32
+ cmp x9, #0x17
+ b.eq handle_smc64
+
+ b unhandled_exception
+
+#ifdef CONFIG_ARMV8_EA_EL3_FIRST
+/*
+ * Override this function if custom error handling is
+ * needed for asynchronous aborts
+ */
+ENTRY(plat_error_handler)
+ ret
+ENDPROC(plat_error_handler)
+.weak plat_error_handler
+
+handle_error:
+ bl psci_get_cpu_id
+ bl psci_get_cpu_stack_top
+ mov x9, #1
+ msr spsel, x9
+ mov sp, x0
+
+ bl plat_error_handler /* Platform specific error handling */
+deadloop:
+ b deadloop /* Never return */
+#endif
+
+ .align 11
+ .globl el3_exception_vectors
+el3_exception_vectors:
+ b unhandled_exception /* Sync, Current EL using SP0 */
+ .align 7
+ b unhandled_exception /* IRQ, Current EL using SP0 */
+ .align 7
+ b unhandled_exception /* FIQ, Current EL using SP0 */
+ .align 7
+ b unhandled_exception /* SError, Current EL using SP0 */
+ .align 7
+ b unhandled_exception /* Sync, Current EL using SPx */
+ .align 7
+ b unhandled_exception /* IRQ, Current EL using SPx */
+ .align 7
+ b unhandled_exception /* FIQ, Current EL using SPx */
+ .align 7
+ b unhandled_exception /* SError, Current EL using SPx */
+ .align 7
+ b handle_sync /* Sync, Lower EL using AArch64 */
+ .align 7
+ b unhandled_exception /* IRQ, Lower EL using AArch64 */
+ .align 7
+ b unhandled_exception /* FIQ, Lower EL using AArch64 */
+ .align 7
+#ifdef CONFIG_ARMV8_EA_EL3_FIRST
+ b handle_error /* SError, Lower EL using AArch64 */
+#else
+ b unhandled_exception /* SError, Lower EL using AArch64 */
+#endif
+ .align 7
+ b unhandled_exception /* Sync, Lower EL using AArch32 */
+ .align 7
+ b unhandled_exception /* IRQ, Lower EL using AArch32 */
+ .align 7
+ b unhandled_exception /* FIQ, Lower EL using AArch32 */
+ .align 7
+ b unhandled_exception /* SError, Lower EL using AArch32 */
+
+ENTRY(psci_setup_vectors)
+ adr x0, el3_exception_vectors
+ msr vbar_el3, x0
+ ret
+ENDPROC(psci_setup_vectors)
+
+ENTRY(psci_arch_init)
+ ret
+ENDPROC(psci_arch_init)
+.weak psci_arch_init
+
+.popsection
diff --git a/roms/u-boot/arch/arm/cpu/armv8/sec_firmware.c b/roms/u-boot/arch/arm/cpu/armv8/sec_firmware.c
new file mode 100644
index 000000000..267894fbc
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/sec_firmware.c
@@ -0,0 +1,504 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <errno.h>
+#include <fdt_support.h>
+#include <image.h>
+#include <log.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/ptrace.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/types.h>
+#include <asm/macro.h>
+#include <asm/armv8/sec_firmware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+extern void c_runtime_cpu_setup(void);
+
+#define SEC_FIRMWARE_LOADED 0x1
+#define SEC_FIRMWARE_RUNNING 0x2
+#define SEC_FIRMWARE_ADDR_MASK (~0x3)
+/*
+ * Secure firmware load addr
+ * Flags used: 0x1 secure firmware has been loaded to secure memory
+ * 0x2 secure firmware is running
+ */
+phys_addr_t sec_firmware_addr;
+
+#ifndef SEC_FIRMWARE_FIT_IMAGE
+#define SEC_FIRMWARE_FIT_IMAGE "firmware"
+#endif
+#ifndef SEC_FIRMWARE_FIT_CNF_NAME
+#define SEC_FIRMWARE_FIT_CNF_NAME "config-1"
+#endif
+#ifndef SEC_FIRMWARE_TARGET_EL
+#define SEC_FIRMWARE_TARGET_EL 2
+#endif
+
+static int sec_firmware_get_data(const void *sec_firmware_img,
+ const void **data, size_t *size)
+{
+ int conf_node_off, fw_node_off;
+ char *conf_node_name = NULL;
+ char *desc;
+ int ret;
+
+ conf_node_name = SEC_FIRMWARE_FIT_CNF_NAME;
+
+ conf_node_off = fit_conf_get_node(sec_firmware_img, conf_node_name);
+ if (conf_node_off < 0) {
+ printf("SEC Firmware: %s: no such config\n", conf_node_name);
+ return -ENOENT;
+ }
+
+ fw_node_off = fit_conf_get_prop_node(sec_firmware_img, conf_node_off,
+ SEC_FIRMWARE_FIT_IMAGE);
+ if (fw_node_off < 0) {
+ printf("SEC Firmware: No '%s' in config\n",
+ SEC_FIRMWARE_FIT_IMAGE);
+ return -ENOLINK;
+ }
+
+ /* Verify secure firmware image */
+ if (!(fit_image_verify(sec_firmware_img, fw_node_off))) {
+ printf("SEC Firmware: Bad firmware image (bad CRC)\n");
+ return -EINVAL;
+ }
+
+ if (fit_image_get_data(sec_firmware_img, fw_node_off, data, size)) {
+ printf("SEC Firmware: Can't get %s subimage data/size",
+ SEC_FIRMWARE_FIT_IMAGE);
+ return -ENOENT;
+ }
+
+ ret = fit_get_desc(sec_firmware_img, fw_node_off, &desc);
+ if (ret)
+ printf("SEC Firmware: Can't get description\n");
+ else
+ printf("%s\n", desc);
+
+ return ret;
+}
+
+/*
+ * SEC Firmware FIT image parser checks if the image is in FIT
+ * format, verifies integrity of the image and calculates raw
+ * image address and size values.
+ *
+ * Returns 0 on success and a negative errno on error task fail.
+ */
+static int sec_firmware_parse_image(const void *sec_firmware_img,
+ const void **raw_image_addr,
+ size_t *raw_image_size)
+{
+ int ret;
+
+ ret = sec_firmware_get_data(sec_firmware_img, raw_image_addr,
+ raw_image_size);
+ if (ret)
+ return ret;
+
+ debug("SEC Firmware: raw_image_addr = 0x%p, raw_image_size = 0x%lx\n",
+ *raw_image_addr, *raw_image_size);
+
+ return 0;
+}
+
+/*
+ * SEC Firmware FIT image parser to check if any loadable is
+ * present. If present, verify integrity of the loadable and
+ * copy loadable to address provided in (loadable_h, loadable_l).
+ *
+ * Returns 0 on success and a negative errno on error task fail.
+ */
+static int sec_firmware_check_copy_loadable(const void *sec_firmware_img,
+ u32 *loadable_l, u32 *loadable_h)
+{
+ phys_addr_t sec_firmware_loadable_addr = 0;
+ int conf_node_off, ld_node_off, images;
+ char *conf_node_name = NULL;
+ const void *data;
+ size_t size;
+ ulong load;
+ const char *name, *str, *type;
+ int len;
+
+ conf_node_name = SEC_FIRMWARE_FIT_CNF_NAME;
+
+ conf_node_off = fit_conf_get_node(sec_firmware_img, conf_node_name);
+ if (conf_node_off < 0) {
+ printf("SEC Firmware: %s: no such config\n", conf_node_name);
+ return -ENOENT;
+ }
+
+ /* find the node holding the images information */
+ images = fdt_path_offset(sec_firmware_img, FIT_IMAGES_PATH);
+ if (images < 0) {
+ printf("%s: Cannot find /images node: %d\n", __func__, images);
+ return -1;
+ }
+
+ type = FIT_LOADABLE_PROP;
+
+ name = fdt_getprop(sec_firmware_img, conf_node_off, type, &len);
+ if (!name) {
+ /* Loadables not present */
+ return 0;
+ }
+
+ printf("SEC Firmware: '%s' present in config\n", type);
+
+ for (str = name; str && ((str - name) < len);
+ str = strchr(str, '\0') + 1) {
+ printf("%s: '%s'\n", type, str);
+ ld_node_off = fdt_subnode_offset(sec_firmware_img, images, str);
+ if (ld_node_off < 0) {
+ printf("cannot find image node '%s': %d\n", str,
+ ld_node_off);
+ return -EINVAL;
+ }
+
+ /* Verify secure firmware image */
+ if (!(fit_image_verify(sec_firmware_img, ld_node_off))) {
+ printf("SEC Loadable: Bad loadable image (bad CRC)\n");
+ return -EINVAL;
+ }
+
+ if (fit_image_get_data(sec_firmware_img, ld_node_off,
+ &data, &size)) {
+ printf("SEC Loadable: Can't get subimage data/size");
+ return -ENOENT;
+ }
+
+ /* Get load address, treated as load offset to secure memory */
+ if (fit_image_get_load(sec_firmware_img, ld_node_off, &load)) {
+ printf("SEC Loadable: Can't get subimage load");
+ return -ENOENT;
+ }
+
+ /* Compute load address for loadable in secure memory */
+ sec_firmware_loadable_addr = (sec_firmware_addr -
+ gd->arch.tlb_size) + load;
+
+ /* Copy loadable to secure memory and flush dcache */
+ debug("%s copied to address 0x%p\n",
+ FIT_LOADABLE_PROP, (void *)sec_firmware_loadable_addr);
+ memcpy((void *)sec_firmware_loadable_addr, data, size);
+ flush_dcache_range(sec_firmware_loadable_addr,
+ sec_firmware_loadable_addr + size);
+
+ /* Populate loadable address only for Trusted OS */
+ if (!strcmp(str, "trustedOS@1")) {
+ /*
+ * Populate address ptrs for loadable image with
+ * loadbale addr
+ */
+ out_le32(loadable_l, (sec_firmware_loadable_addr &
+ WORD_MASK));
+ out_le32(loadable_h, (sec_firmware_loadable_addr >>
+ WORD_SHIFT));
+ }
+ }
+
+ return 0;
+}
+
+static int sec_firmware_copy_image(const char *title,
+ u64 image_addr, u32 image_size, u64 sec_firmware)
+{
+ debug("%s copied to address 0x%p\n", title, (void *)sec_firmware);
+ memcpy((void *)sec_firmware, (void *)image_addr, image_size);
+ flush_dcache_range(sec_firmware, sec_firmware + image_size);
+
+ return 0;
+}
+
+/*
+ * This function will parse the SEC Firmware image, and then load it
+ * to secure memory. Also load any loadable if present along with SEC
+ * Firmware image.
+ */
+static int sec_firmware_load_image(const void *sec_firmware_img,
+ u32 *loadable_l, u32 *loadable_h)
+{
+ const void *raw_image_addr;
+ size_t raw_image_size = 0;
+ int ret;
+
+ /*
+ * The Excetpion Level must be EL3 to load and initialize
+ * the SEC Firmware.
+ */
+ if (current_el() != 3) {
+ ret = -EACCES;
+ goto out;
+ }
+
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+ /*
+ * The SEC Firmware must be stored in secure memory.
+ * Append SEC Firmware to secure mmu table.
+ */
+ if (!(gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED)) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ sec_firmware_addr = (gd->arch.secure_ram & MEM_RESERVE_SECURE_ADDR_MASK) +
+ gd->arch.tlb_size;
+#else
+#error "The CONFIG_SYS_MEM_RESERVE_SECURE must be defined when enabled SEC Firmware support"
+#endif
+
+ /* Align SEC Firmware base address to 4K */
+ sec_firmware_addr = (sec_firmware_addr + 0xfff) & ~0xfff;
+ debug("SEC Firmware: Load address: 0x%llx\n",
+ sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);
+
+ ret = sec_firmware_parse_image(sec_firmware_img, &raw_image_addr,
+ &raw_image_size);
+ if (ret)
+ goto out;
+
+ /* TODO:
+ * Check if the end addr of SEC Firmware has been extend the secure
+ * memory.
+ */
+
+ /* Copy the secure firmware to secure memory */
+ ret = sec_firmware_copy_image("SEC Firmware", (u64)raw_image_addr,
+ raw_image_size, sec_firmware_addr &
+ SEC_FIRMWARE_ADDR_MASK);
+ if (ret)
+ goto out;
+
+ /*
+ * Check if any loadable are present along with firmware image, if
+ * present load them.
+ */
+ ret = sec_firmware_check_copy_loadable(sec_firmware_img, loadable_l,
+ loadable_h);
+ if (ret)
+ goto out;
+
+ sec_firmware_addr |= SEC_FIRMWARE_LOADED;
+ debug("SEC Firmware: Entry point: 0x%llx\n",
+ sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);
+
+ return 0;
+
+out:
+ printf("SEC Firmware: error (%d)\n", ret);
+ sec_firmware_addr = 0;
+
+ return ret;
+}
+
+static int sec_firmware_entry(u32 *eret_hold_l, u32 *eret_hold_h)
+{
+ const void *entry = (void *)(sec_firmware_addr &
+ SEC_FIRMWARE_ADDR_MASK);
+
+ return _sec_firmware_entry(entry, eret_hold_l, eret_hold_h);
+}
+
+/* Check the secure firmware FIT image */
+__weak bool sec_firmware_is_valid(const void *sec_firmware_img)
+{
+ if (fdt_check_header(sec_firmware_img)) {
+ printf("SEC Firmware: Bad firmware image (not a FIT image)\n");
+ return false;
+ }
+
+ if (fit_check_format(sec_firmware_img, IMAGE_SIZE_INVAL)) {
+ printf("SEC Firmware: Bad firmware image (bad FIT header)\n");
+ return false;
+ }
+
+ return true;
+}
+
+#ifdef CONFIG_SEC_FIRMWARE_ARMV8_PSCI
+/*
+ * The PSCI_VERSION function is added from PSCI v0.2. When the PSCI
+ * v0.1 received this function, the NOT_SUPPORTED (0xffff_ffff) error
+ * number will be returned according to SMC Calling Conventions. But
+ * when getting the NOT_SUPPORTED error number, we cannot ensure if
+ * the PSCI version is v0.1 or other error occurred. So, PSCI v0.1
+ * won't be supported by this framework.
+ * And if the secure firmware isn't running, return NOT_SUPPORTED.
+ *
+ * The return value on success is PSCI version in format
+ * major[31:16]:minor[15:0].
+ */
+unsigned int sec_firmware_support_psci_version(void)
+{
+ if (current_el() == SEC_FIRMWARE_TARGET_EL)
+ return _sec_firmware_support_psci_version();
+
+ return PSCI_INVALID_VER;
+}
+#endif
+
+/*
+ * Check with sec_firmware if it supports random number generation
+ * via HW RNG
+ *
+ * The return value will be true if it is supported
+ */
+bool sec_firmware_support_hwrng(void)
+{
+#ifdef CONFIG_TFABOOT
+ /* return true as TFA has one job ring reserved */
+ return true;
+#endif
+ if (sec_firmware_addr & SEC_FIRMWARE_RUNNING) {
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * sec_firmware_get_random - Get a random number from SEC Firmware
+ * @rand: random number buffer to be filled
+ * @bytes: Number of bytes of random number to be supported
+ * @eret: -1 in case of error, 0 for success
+ */
+int sec_firmware_get_random(uint8_t *rand, int bytes)
+{
+ unsigned long long num;
+ struct pt_regs regs;
+ int param1;
+
+ if (!bytes || bytes > 8) {
+ printf("Max Random bytes genration supported is 8\n");
+ return -1;
+ }
+#define SIP_RNG_64 0xC200FF11
+ regs.regs[0] = SIP_RNG_64;
+
+ if (bytes <= 4)
+ param1 = 0;
+ else
+ param1 = 1;
+ regs.regs[1] = param1;
+
+ smc_call(&regs);
+
+ if (regs.regs[0])
+ return -1;
+
+ num = regs.regs[1];
+ memcpy(rand, &num, bytes);
+
+ return 0;
+}
+
+/*
+ * sec_firmware_init - Initialize the SEC Firmware
+ * @sec_firmware_img: the SEC Firmware image address
+ * @eret_hold_l: the address to hold exception return address low
+ * @eret_hold_h: the address to hold exception return address high
+ * @loadable_l: the address to hold loadable address low
+ * @loadable_h: the address to hold loadable address high
+ */
+int sec_firmware_init(const void *sec_firmware_img,
+ u32 *eret_hold_l,
+ u32 *eret_hold_h,
+ u32 *loadable_l,
+ u32 *loadable_h)
+{
+ int ret;
+
+ if (!sec_firmware_is_valid(sec_firmware_img))
+ return -EINVAL;
+
+ ret = sec_firmware_load_image(sec_firmware_img, loadable_l,
+ loadable_h);
+ if (ret) {
+ printf("SEC Firmware: Failed to load image\n");
+ return ret;
+ } else if (sec_firmware_addr & SEC_FIRMWARE_LOADED) {
+ ret = sec_firmware_entry(eret_hold_l, eret_hold_h);
+ if (ret) {
+ printf("SEC Firmware: Failed to initialize\n");
+ return ret;
+ }
+ }
+
+ debug("SEC Firmware: Return from SEC Firmware: current_el = %d\n",
+ current_el());
+
+ /*
+ * The PE will be turned into target EL when returned from
+ * SEC Firmware.
+ */
+ if (current_el() != SEC_FIRMWARE_TARGET_EL)
+ return -EACCES;
+
+ sec_firmware_addr |= SEC_FIRMWARE_RUNNING;
+
+ /* Set exception table and enable caches if it isn't EL3 */
+ if (current_el() != 3) {
+ c_runtime_cpu_setup();
+ enable_caches();
+ }
+
+ return 0;
+}
+
+/*
+ * fdt_fix_kaslr - Add kalsr-seed node in Device tree
+ * @fdt: Device tree
+ * @eret: 0 in case of error, 1 for success
+ */
+int fdt_fixup_kaslr(void *fdt)
+{
+ int nodeoffset;
+ int err, ret = 0;
+ u8 rand[8];
+
+#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT)
+ /* Check if random seed generation is supported */
+ if (sec_firmware_support_hwrng() == false) {
+ printf("WARNING: SEC firmware not running, no kaslr-seed\n");
+ return 0;
+ }
+
+ ret = sec_firmware_get_random(rand, 8);
+ if (ret < 0) {
+ printf("WARNING: No random number to set kaslr-seed\n");
+ return 0;
+ }
+
+ err = fdt_check_header(fdt);
+ if (err < 0) {
+ printf("fdt_chosen: %s\n", fdt_strerror(err));
+ return 0;
+ }
+
+ /* find or create "/chosen" node. */
+ nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen");
+ if (nodeoffset < 0)
+ return 0;
+
+ err = fdt_setprop(fdt, nodeoffset, "kaslr-seed", rand,
+ sizeof(rand));
+ if (err < 0) {
+ printf("WARNING: can't set kaslr-seed %s.\n",
+ fdt_strerror(err));
+ return 0;
+ }
+ ret = 1;
+#endif
+
+ return ret;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/sec_firmware_asm.S b/roms/u-boot/arch/arm/cpu/armv8/sec_firmware_asm.S
new file mode 100644
index 000000000..af1b2da07
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/sec_firmware_asm.S
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/system.h>
+#include <asm/macro.h>
+
+WEAK(_sec_firmware_entry)
+ /*
+ * x0: Secure Firmware entry point
+ * x1: Exception return address Low
+ * x2: Exception return address High
+ */
+
+ /* Save stack pointer for EL2 */
+ mov x3, sp
+ msr sp_el2, x3
+
+ /* Set exception return address hold pointer */
+ adr x4, 1f
+ mov x3, x4
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_ERET_ADDR_REVERT
+ rev w3, w3
+#endif
+ str w3, [x1]
+ lsr x3, x4, #32
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_ERET_ADDR_REVERT
+ rev w3, w3
+#endif
+ str w3, [x2]
+
+ /* Call SEC monitor */
+ br x0
+
+1:
+ mov x0, #0
+ ret
+ENDPROC(_sec_firmware_entry)
+
+#ifdef CONFIG_SEC_FIRMWARE_ARMV8_PSCI
+ENTRY(_sec_firmware_support_psci_version)
+ mov x0, 0x84000000
+ mov x1, 0x0
+ mov x2, 0x0
+ mov x3, 0x0
+ smc #0
+ ret
+ENDPROC(_sec_firmware_support_psci_version)
+
+/*
+ * Switch from AArch64 EL2 to AArch32 EL2
+ * @param inputs:
+ * x0: argument, zero
+ * x1: machine nr
+ * x2: fdt address
+ * x3: input argument
+ * x4: kernel entry point
+ * @param outputs for secure firmware:
+ * x0: function id
+ * x1: kernel entry point
+ * x2: machine nr
+ * x3: fdt address
+*/
+ENTRY(armv8_el2_to_aarch32)
+ mov x3, x2
+ mov x2, x1
+ mov x1, x4
+ ldr x0, =0xc200ff17
+ smc #0
+ ret
+ENDPROC(armv8_el2_to_aarch32)
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/armv8/smccc-call.S b/roms/u-boot/arch/arm/cpu/armv8/smccc-call.S
new file mode 100644
index 000000000..dc92b2877
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/smccc-call.S
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2015, Linaro Limited
+ */
+#include <linux/linkage.h>
+#include <linux/arm-smccc.h>
+#include <generated/asm-offsets.h>
+
+#ifdef CONFIG_EFI_LOADER
+ .section .text.efi_runtime
+#endif
+
+ .macro SMCCC instr
+ .cfi_startproc
+ \instr #0
+ ldr x4, [sp]
+ stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
+ stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
+ ldr x4, [sp, #8]
+ cbz x4, 1f /* no quirk structure */
+ ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS]
+ cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6
+ b.ne 1f
+ str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS]
+1: ret
+ .cfi_endproc
+ .endm
+
+/*
+ * void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
+ * unsigned long a3, unsigned long a4, unsigned long a5,
+ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ * struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_smc)
+ SMCCC smc
+ENDPROC(__arm_smccc_smc)
+
+/*
+ * void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
+ * unsigned long a3, unsigned long a4, unsigned long a5,
+ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
+ * struct arm_smccc_quirk *quirk)
+ */
+ENTRY(__arm_smccc_hvc)
+ SMCCC hvc
+ENDPROC(__arm_smccc_hvc)
diff --git a/roms/u-boot/arch/arm/cpu/armv8/spin_table.c b/roms/u-boot/arch/arm/cpu/armv8/spin_table.c
new file mode 100644
index 000000000..42a0962fd
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/spin_table.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ */
+
+#include <common.h>
+#include <linux/libfdt.h>
+#include <asm/spin_table.h>
+
+int spin_table_update_dt(void *fdt)
+{
+ int cpus_offset, offset;
+ const char *prop;
+ int ret;
+ unsigned long rsv_addr = (unsigned long)&spin_table_reserve_begin;
+ unsigned long rsv_size = &spin_table_reserve_end -
+ &spin_table_reserve_begin;
+
+ cpus_offset = fdt_path_offset(fdt, "/cpus");
+ if (cpus_offset < 0)
+ return -ENODEV;
+
+ for (offset = fdt_first_subnode(fdt, cpus_offset);
+ offset >= 0;
+ offset = fdt_next_subnode(fdt, offset)) {
+ prop = fdt_getprop(fdt, offset, "device_type", NULL);
+ if (!prop || strcmp(prop, "cpu"))
+ continue;
+
+ /*
+ * In the first loop, we check if every CPU node specifies
+ * spin-table. Otherwise, just return successfully to not
+ * disturb other methods, like psci.
+ */
+ prop = fdt_getprop(fdt, offset, "enable-method", NULL);
+ if (!prop || strcmp(prop, "spin-table"))
+ return 0;
+ }
+
+ for (offset = fdt_first_subnode(fdt, cpus_offset);
+ offset >= 0;
+ offset = fdt_next_subnode(fdt, offset)) {
+ prop = fdt_getprop(fdt, offset, "device_type", NULL);
+ if (!prop || strcmp(prop, "cpu"))
+ continue;
+
+ ret = fdt_setprop_u64(fdt, offset, "cpu-release-addr",
+ (unsigned long)&spin_table_cpu_release_addr);
+ if (ret)
+ return -ENOSPC;
+ }
+
+ ret = fdt_add_mem_rsv(fdt, rsv_addr, rsv_size);
+ if (ret)
+ return -ENOSPC;
+
+ printf(" Reserved memory region for spin-table: addr=%lx size=%lx\n",
+ rsv_addr, rsv_size);
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/spin_table_v8.S b/roms/u-boot/arch/arm/cpu/armv8/spin_table_v8.S
new file mode 100644
index 000000000..6d2684327
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/spin_table_v8.S
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(spin_table_secondary_jump)
+.globl spin_table_reserve_begin
+spin_table_reserve_begin:
+0: wfe
+ ldr x0, spin_table_cpu_release_addr
+ cbz x0, 0b
+ br x0
+.globl spin_table_cpu_release_addr
+ .align 3
+spin_table_cpu_release_addr:
+ .quad 0
+.globl spin_table_reserve_end
+spin_table_reserve_end:
+ENDPROC(spin_table_secondary_jump)
diff --git a/roms/u-boot/arch/arm/cpu/armv8/spl_data.c b/roms/u-boot/arch/arm/cpu/armv8/spl_data.c
new file mode 100644
index 000000000..8f1231c86
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/spl_data.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020 NXP
+ */
+
+#include <common.h>
+#include <spl.h>
+
+char __data_save_start[0] __section(".__data_save_start");
+char __data_save_end[0] __section(".__data_save_end");
+
+u32 cold_reboot_flag = 1;
+
+void spl_save_restore_data(void)
+{
+ u32 data_size = __data_save_end - __data_save_start;
+
+ if (cold_reboot_flag == 1) {
+ /* Save data section to data_save section */
+ memcpy(__data_save_start, __data_save_start - data_size,
+ data_size);
+ } else {
+ /* Restore the data_save section to data section */
+ memcpy(__data_save_start - data_size, __data_save_start,
+ data_size);
+ }
+
+ cold_reboot_flag++;
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/start.S b/roms/u-boot/arch/arm/cpu/armv8/start.S
new file mode 100644
index 000000000..662449156
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/start.S
@@ -0,0 +1,402 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+#include <asm/armv8/mmu.h>
+
+/*************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ *************************************************************************/
+
+.globl _start
+_start:
+#if defined(CONFIG_LINUX_KERNEL_IMAGE_HEADER)
+#include <asm/boot0-linux-kernel-header.h>
+#elif defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK)
+/*
+ * Various SoCs need something special and SoC-specific up front in
+ * order to boot, allow them to set that in their boot0.h file and then
+ * use it here.
+ */
+#include <asm/arch/boot0.h>
+#else
+ b reset
+#endif
+
+ .align 3
+
+.globl _TEXT_BASE
+_TEXT_BASE:
+ .quad CONFIG_SYS_TEXT_BASE
+
+/*
+ * These are defined in the linker script.
+ */
+.globl _end_ofs
+_end_ofs:
+ .quad _end - _start
+
+.globl _bss_start_ofs
+_bss_start_ofs:
+ .quad __bss_start - _start
+
+.globl _bss_end_ofs
+_bss_end_ofs:
+ .quad __bss_end - _start
+
+reset:
+ /* Allow the board to save important registers */
+ b save_boot_params
+.globl save_boot_params_ret
+save_boot_params_ret:
+
+#if CONFIG_POSITION_INDEPENDENT
+ /* Verify that we're 4K aligned. */
+ adr x0, _start
+ ands x0, x0, #0xfff
+ b.eq 1f
+0:
+ /*
+ * FATAL, can't continue.
+ * U-Boot needs to be loaded at a 4K aligned address.
+ *
+ * We use ADRP and ADD to load some symbol addresses during startup.
+ * The ADD uses an absolute (non pc-relative) lo12 relocation
+ * thus requiring 4K alignment.
+ */
+ wfi
+ b 0b
+1:
+
+ /*
+ * Fix .rela.dyn relocations. This allows U-Boot to be loaded to and
+ * executed at a different address than it was linked at.
+ */
+pie_fixup:
+ adr x0, _start /* x0 <- Runtime value of _start */
+ ldr x1, _TEXT_BASE /* x1 <- Linked value of _start */
+ subs x9, x0, x1 /* x9 <- Run-vs-link offset */
+ beq pie_fixup_done
+ adrp x2, __rel_dyn_start /* x2 <- Runtime &__rel_dyn_start */
+ add x2, x2, #:lo12:__rel_dyn_start
+ adrp x3, __rel_dyn_end /* x3 <- Runtime &__rel_dyn_end */
+ add x3, x3, #:lo12:__rel_dyn_end
+pie_fix_loop:
+ ldp x0, x1, [x2], #16 /* (x0, x1) <- (Link location, fixup) */
+ ldr x4, [x2], #8 /* x4 <- addend */
+ cmp w1, #1027 /* relative fixup? */
+ bne pie_skip_reloc
+ /* relative fix: store addend plus offset at dest location */
+ add x0, x0, x9
+ add x4, x4, x9
+ str x4, [x0]
+pie_skip_reloc:
+ cmp x2, x3
+ b.lo pie_fix_loop
+pie_fixup_done:
+#endif
+
+#ifdef CONFIG_SYS_RESET_SCTRL
+ bl reset_sctrl
+#endif
+
+#if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD)
+.macro set_vbar, regname, reg
+ msr \regname, \reg
+.endm
+ adr x0, vectors
+#else
+.macro set_vbar, regname, reg
+.endm
+#endif
+ /*
+ * Could be EL3/EL2/EL1, Initial State:
+ * Little Endian, MMU Disabled, i/dCache Disabled
+ */
+ switch_el x1, 3f, 2f, 1f
+3: set_vbar vbar_el3, x0
+ mrs x0, scr_el3
+ orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */
+ msr scr_el3, x0
+ msr cptr_el3, xzr /* Enable FP/SIMD */
+#ifdef COUNTER_FREQUENCY
+ ldr x0, =COUNTER_FREQUENCY
+ msr cntfrq_el0, x0 /* Initialize CNTFRQ */
+#endif
+ b 0f
+2: set_vbar vbar_el2, x0
+ mov x0, #0x33ff
+ msr cptr_el2, x0 /* Enable FP/SIMD */
+ b 0f
+1: set_vbar vbar_el1, x0
+ mov x0, #3 << 20
+ msr cpacr_el1, x0 /* Enable FP/SIMD */
+0:
+ isb
+
+ /*
+ * Enable SMPEN bit for coherency.
+ * This register is not architectural but at the moment
+ * this bit should be set for A53/A57/A72.
+ */
+#ifdef CONFIG_ARMV8_SET_SMPEN
+ switch_el x1, 3f, 1f, 1f
+3:
+ mrs x0, S3_1_c15_c2_1 /* cpuectlr_el1 */
+ orr x0, x0, #0x40
+ msr S3_1_c15_c2_1, x0
+ isb
+1:
+#endif
+
+ /* Apply ARM core specific erratas */
+ bl apply_core_errata
+
+ /*
+ * Cache/BPB/TLB Invalidate
+ * i-cache is invalidated before enabled in icache_enable()
+ * tlb is invalidated before mmu is enabled in dcache_enable()
+ * d-cache is invalidated before enabled in dcache_enable()
+ */
+
+ /* Processor specific initialization */
+ bl lowlevel_init
+
+#if defined(CONFIG_ARMV8_SPIN_TABLE) && !defined(CONFIG_SPL_BUILD)
+ branch_if_master x0, x1, master_cpu
+ b spin_table_secondary_jump
+ /* never return */
+#elif defined(CONFIG_ARMV8_MULTIENTRY)
+ branch_if_master x0, x1, master_cpu
+
+ /*
+ * Slave CPUs
+ */
+slave_cpu:
+ wfe
+ ldr x1, =CPU_RELEASE_ADDR
+ ldr x0, [x1]
+ cbz x0, slave_cpu
+ br x0 /* branch to the given address */
+#endif /* CONFIG_ARMV8_MULTIENTRY */
+master_cpu:
+ bl _main
+
+#ifdef CONFIG_SYS_RESET_SCTRL
+reset_sctrl:
+ switch_el x1, 3f, 2f, 1f
+3:
+ mrs x0, sctlr_el3
+ b 0f
+2:
+ mrs x0, sctlr_el2
+ b 0f
+1:
+ mrs x0, sctlr_el1
+
+0:
+ ldr x1, =0xfdfffffa
+ and x0, x0, x1
+
+ switch_el x1, 6f, 5f, 4f
+6:
+ msr sctlr_el3, x0
+ b 7f
+5:
+ msr sctlr_el2, x0
+ b 7f
+4:
+ msr sctlr_el1, x0
+
+7:
+ dsb sy
+ isb
+ b __asm_invalidate_tlb_all
+ ret
+#endif
+
+/*-----------------------------------------------------------------------*/
+
+WEAK(apply_core_errata)
+
+ mov x29, lr /* Save LR */
+ /* For now, we support Cortex-A53, Cortex-A57 specific errata */
+
+ /* Check if we are running on a Cortex-A53 core */
+ branch_if_a53_core x0, apply_a53_core_errata
+
+ /* Check if we are running on a Cortex-A57 core */
+ branch_if_a57_core x0, apply_a57_core_errata
+0:
+ mov lr, x29 /* Restore LR */
+ ret
+
+apply_a53_core_errata:
+
+#ifdef CONFIG_ARM_ERRATA_855873
+ mrs x0, midr_el1
+ tst x0, #(0xf << 20)
+ b.ne 0b
+
+ mrs x0, midr_el1
+ and x0, x0, #0xf
+ cmp x0, #3
+ b.lt 0b
+
+ mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
+ /* Enable data cache clean as data cache clean/invalidate */
+ orr x0, x0, #1 << 44
+ msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
+ isb
+#endif
+ b 0b
+
+apply_a57_core_errata:
+
+#ifdef CONFIG_ARM_ERRATA_828024
+ mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
+ /* Disable non-allocate hint of w-b-n-a memory type */
+ orr x0, x0, #1 << 49
+ /* Disable write streaming no L1-allocate threshold */
+ orr x0, x0, #3 << 25
+ /* Disable write streaming no-allocate threshold */
+ orr x0, x0, #3 << 27
+ msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
+ isb
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_826974
+ mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
+ /* Disable speculative load execution ahead of a DMB */
+ orr x0, x0, #1 << 59
+ msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
+ isb
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_833471
+ mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
+ /* FPSCR write flush.
+ * Note that in some cases where a flush is unnecessary this
+ could impact performance. */
+ orr x0, x0, #1 << 38
+ msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
+ isb
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_829520
+ mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
+ /* Disable Indirect Predictor bit will prevent this erratum
+ from occurring
+ * Note that in some cases where a flush is unnecessary this
+ could impact performance. */
+ orr x0, x0, #1 << 4
+ msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
+ isb
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_833069
+ mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
+ /* Disable Enable Invalidates of BTB bit */
+ and x0, x0, #0xE
+ msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
+ isb
+#endif
+ b 0b
+ENDPROC(apply_core_errata)
+
+/*-----------------------------------------------------------------------*/
+
+WEAK(lowlevel_init)
+ mov x29, lr /* Save LR */
+
+#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
+ branch_if_slave x0, 1f
+ ldr x0, =GICD_BASE
+ bl gic_init_secure
+1:
+#if defined(CONFIG_GICV3)
+ ldr x0, =GICR_BASE
+ bl gic_init_secure_percpu
+#elif defined(CONFIG_GICV2)
+ ldr x0, =GICD_BASE
+ ldr x1, =GICC_BASE
+ bl gic_init_secure_percpu
+#endif
+#endif
+
+#ifdef CONFIG_ARMV8_MULTIENTRY
+ branch_if_master x0, x1, 2f
+
+ /*
+ * Slave should wait for master clearing spin table.
+ * This sync prevent salves observing incorrect
+ * value of spin table and jumping to wrong place.
+ */
+#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
+#ifdef CONFIG_GICV2
+ ldr x0, =GICC_BASE
+#endif
+ bl gic_wait_for_interrupt
+#endif
+
+ /*
+ * All slaves will enter EL2 and optionally EL1.
+ */
+ adr x4, lowlevel_in_el2
+ ldr x5, =ES_TO_AARCH64
+ bl armv8_switch_to_el2
+
+lowlevel_in_el2:
+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+ adr x4, lowlevel_in_el1
+ ldr x5, =ES_TO_AARCH64
+ bl armv8_switch_to_el1
+
+lowlevel_in_el1:
+#endif
+
+#endif /* CONFIG_ARMV8_MULTIENTRY */
+
+2:
+ mov lr, x29 /* Restore LR */
+ ret
+ENDPROC(lowlevel_init)
+
+WEAK(smp_kick_all_cpus)
+ /* Kick secondary cpus up by SGI 0 interrupt */
+#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
+ ldr x0, =GICD_BASE
+ b gic_kick_secondary_cpus
+#endif
+ ret
+ENDPROC(smp_kick_all_cpus)
+
+/*-----------------------------------------------------------------------*/
+
+ENTRY(c_runtime_cpu_setup)
+#if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD)
+ /* Relocate vBAR */
+ adr x0, vectors
+ switch_el x1, 3f, 2f, 1f
+3: msr vbar_el3, x0
+ b 0f
+2: msr vbar_el2, x0
+ b 0f
+1: msr vbar_el1, x0
+0:
+#endif
+
+ ret
+ENDPROC(c_runtime_cpu_setup)
+
+WEAK(save_boot_params)
+ b save_boot_params_ret /* back to my caller */
+ENDPROC(save_boot_params)
diff --git a/roms/u-boot/arch/arm/cpu/armv8/tlb.S b/roms/u-boot/arch/arm/cpu/armv8/tlb.S
new file mode 100644
index 000000000..46a0d7d8f
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/tlb.S
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+
+/*
+ * void __asm_invalidate_tlb_all(void)
+ *
+ * invalidate all tlb entries.
+*/
+.pushsection .text.__asm_invalidate_tlb_all, "ax"
+ENTRY(__asm_invalidate_tlb_all)
+ switch_el x9, 3f, 2f, 1f
+3: tlbi alle3
+ dsb sy
+ isb
+ b 0f
+2: tlbi alle2
+ dsb sy
+ isb
+ b 0f
+1: tlbi vmalle1
+ dsb sy
+ isb
+0:
+ ret
+ENDPROC(__asm_invalidate_tlb_all)
+.popsection
diff --git a/roms/u-boot/arch/arm/cpu/armv8/transition.S b/roms/u-boot/arch/arm/cpu/armv8/transition.S
new file mode 100644
index 000000000..a31af4ffc
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/transition.S
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+
+.pushsection .text.armv8_switch_to_el2, "ax"
+ENTRY(armv8_switch_to_el2)
+ switch_el x6, 1f, 0f, 0f
+0:
+ cmp x5, #ES_TO_AARCH64
+ b.eq 2f
+ /*
+ * When loading 32-bit kernel, it will jump
+ * to secure firmware again, and never return.
+ */
+ bl armv8_el2_to_aarch32
+2:
+ /*
+ * x4 is kernel entry point or switch_to_el1
+ * if CONFIG_ARMV8_SWITCH_TO_EL1 is defined.
+ * When running in EL2 now, jump to the
+ * address saved in x4.
+ */
+ br x4
+1: armv8_switch_to_el2_m x4, x5, x6
+ENDPROC(armv8_switch_to_el2)
+.popsection
+
+.pushsection .text.armv8_switch_to_el1, "ax"
+ENTRY(armv8_switch_to_el1)
+ switch_el x6, 0f, 1f, 0f
+0:
+ /* x4 is kernel entry point. When running in EL1
+ * now, jump to the address saved in x4.
+ */
+ br x4
+1: armv8_switch_to_el1_m x4, x5, x6
+ENDPROC(armv8_switch_to_el1)
+.popsection
+
+.pushsection .text.armv8_el2_to_aarch32, "ax"
+WEAK(armv8_el2_to_aarch32)
+ ret
+ENDPROC(armv8_el2_to_aarch32)
+.popsection
diff --git a/roms/u-boot/arch/arm/cpu/armv8/u-boot-spl.lds b/roms/u-boot/arch/arm/cpu/armv8/u-boot-spl.lds
new file mode 100644
index 000000000..9edb662b0
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/u-boot-spl.lds
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ * Aneesh V <aneesh@ti.com>
+ */
+
+MEMORY { .sram : ORIGIN = IMAGE_TEXT_BASE,
+ LENGTH = IMAGE_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR,
+ LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+ .text : {
+ . = ALIGN(8);
+ *(.__image_copy_start)
+ CPUDIR/start.o (.text*)
+ *(.text*)
+ } >.sram
+
+ .rodata : {
+ . = ALIGN(8);
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+ } >.sram
+
+ .data : {
+ . = ALIGN(8);
+ *(.data*)
+ } >.sram
+
+#ifdef CONFIG_SPL_RECOVER_DATA_SECTION
+ .data_save : {
+ *(.__data_save_start)
+ . = SIZEOF(.data);
+ *(.__data_save_end)
+ } >.sram
+#endif
+
+ .u_boot_list : {
+ . = ALIGN(8);
+ KEEP(*(SORT(.u_boot_list*)));
+ } >.sram
+
+ .image_copy_end : {
+ . = ALIGN(8);
+ *(.__image_copy_end)
+ } >.sram
+
+ .end : {
+ . = ALIGN(8);
+ *(.__end)
+ } >.sram
+
+ _image_binary_end = .;
+
+ .bss_start (NOLOAD) : {
+ . = ALIGN(8);
+ KEEP(*(.__bss_start));
+ } >.sdram
+
+ .bss (NOLOAD) : {
+ *(.bss*)
+ . = ALIGN(8);
+ } >.sdram
+
+ .bss_end (NOLOAD) : {
+ KEEP(*(.__bss_end));
+ } >.sdram
+
+ /DISCARD/ : { *(.rela*) }
+ /DISCARD/ : { *(.dynsym) }
+ /DISCARD/ : { *(.dynstr*) }
+ /DISCARD/ : { *(.dynamic*) }
+ /DISCARD/ : { *(.plt*) }
+ /DISCARD/ : { *(.interp*) }
+ /DISCARD/ : { *(.gnu*) }
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/u-boot.lds b/roms/u-boot/arch/arm/cpu/armv8/u-boot.lds
new file mode 100644
index 000000000..255498059
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/u-boot.lds
@@ -0,0 +1,175 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ */
+
+#include <config.h>
+#include <asm/psci.h>
+
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+#ifdef CONFIG_ARMV8_SECURE_BASE
+ /DISCARD/ : { *(.rela._secure*) }
+#endif
+ . = 0x00000000;
+
+ . = ALIGN(8);
+ .text :
+ {
+ *(.__image_copy_start)
+ CPUDIR/start.o (.text*)
+ }
+
+ /* This needs to come before *(.text*) */
+ .efi_runtime : {
+ __efi_runtime_start = .;
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
+ __efi_runtime_stop = .;
+ }
+
+ .text_rest :
+ {
+ *(.text*)
+ }
+
+#ifdef CONFIG_ARMV8_PSCI
+ .__secure_start :
+#ifndef CONFIG_ARMV8_SECURE_BASE
+ ALIGN(CONSTANT(COMMONPAGESIZE))
+#endif
+ {
+ KEEP(*(.__secure_start))
+ }
+
+#ifndef CONFIG_ARMV8_SECURE_BASE
+#define CONFIG_ARMV8_SECURE_BASE
+#define __ARMV8_PSCI_STACK_IN_RAM
+#endif
+ .secure_text CONFIG_ARMV8_SECURE_BASE :
+ AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
+ {
+ *(._secure.text)
+ . = ALIGN(8);
+ __secure_svc_tbl_start = .;
+ KEEP(*(._secure_svc_tbl_entries))
+ __secure_svc_tbl_end = .;
+ }
+
+ .secure_data : AT(LOADADDR(.secure_text) + SIZEOF(.secure_text))
+ {
+ *(._secure.data)
+ }
+
+ .secure_stack ALIGN(ADDR(.secure_data) + SIZEOF(.secure_data),
+ CONSTANT(COMMONPAGESIZE)) (NOLOAD) :
+#ifdef __ARMV8_PSCI_STACK_IN_RAM
+ AT(ADDR(.secure_stack))
+#else
+ AT(LOADADDR(.secure_data) + SIZEOF(.secure_data))
+#endif
+ {
+ KEEP(*(.__secure_stack_start))
+
+ . = . + CONFIG_ARMV8_PSCI_NR_CPUS * ARM_PSCI_STACK_SIZE;
+
+ . = ALIGN(CONSTANT(COMMONPAGESIZE));
+
+ KEEP(*(.__secure_stack_end))
+ }
+
+#ifndef __ARMV8_PSCI_STACK_IN_RAM
+ . = LOADADDR(.secure_stack);
+#endif
+
+ .__secure_end : AT(ADDR(.__secure_end)) {
+ KEEP(*(.__secure_end))
+ LONG(0x1d1071c); /* Must output something to reset LMA */
+ }
+#endif
+
+ . = ALIGN(8);
+ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+ . = ALIGN(8);
+ .data : {
+ *(.data*)
+ }
+
+ . = ALIGN(8);
+
+ . = .;
+
+ . = ALIGN(8);
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+ }
+
+ . = ALIGN(8);
+
+ .efi_runtime_rel : {
+ __efi_runtime_rel_start = .;
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
+ __efi_runtime_rel_stop = .;
+ }
+
+ . = ALIGN(8);
+
+ .image_copy_end :
+ {
+ *(.__image_copy_end)
+ }
+
+ . = ALIGN(8);
+
+ .rel_dyn_start :
+ {
+ *(.__rel_dyn_start)
+ }
+
+ .rela.dyn : {
+ *(.rela*)
+ }
+
+ .rel_dyn_end :
+ {
+ *(.__rel_dyn_end)
+ }
+
+ _end = .;
+
+ . = ALIGN(8);
+
+ .bss_start : {
+ KEEP(*(.__bss_start));
+ }
+
+ .bss : {
+ *(.bss*)
+ . = ALIGN(8);
+ }
+
+ .bss_end : {
+ KEEP(*(.__bss_end));
+ }
+
+ /DISCARD/ : { *(.dynsym) }
+ /DISCARD/ : { *(.dynstr*) }
+ /DISCARD/ : { *(.dynamic*) }
+ /DISCARD/ : { *(.plt*) }
+ /DISCARD/ : { *(.interp*) }
+ /DISCARD/ : { *(.gnu*) }
+
+#ifdef CONFIG_LINUX_KERNEL_IMAGE_HEADER
+#include "linux-kernel-image-header-vars.h"
+#endif
+}
diff --git a/roms/u-boot/arch/arm/cpu/armv8/xen/Makefile b/roms/u-boot/arch/arm/cpu/armv8/xen/Makefile
new file mode 100644
index 000000000..e3b4ae2bd
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/xen/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) 2018 NXP
+# (C) 2020 EPAM Systems Inc.
+
+obj-y += lowlevel_init.o hypercall.o
diff --git a/roms/u-boot/arch/arm/cpu/armv8/xen/hypercall.S b/roms/u-boot/arch/arm/cpu/armv8/xen/hypercall.S
new file mode 100644
index 000000000..731256b34
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/xen/hypercall.S
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * hypercall.S
+ *
+ * Xen hypercall wrappers
+ *
+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (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.
+ */
+
+/*
+ * The Xen hypercall calling convention is very similar to the procedure
+ * call standard for the ARM 64-bit architecture: the first parameter is
+ * passed in x0, the second in x1, the third in x2, the fourth in x3 and
+ * the fifth in x4.
+ *
+ * The hypercall number is passed in x16.
+ *
+ * The return value is in x0.
+ *
+ * The hvc ISS is required to be 0xEA1, that is the Xen specific ARM
+ * hypercall tag.
+ *
+ * Parameter structs passed to hypercalls are laid out according to
+ * the ARM 64-bit EABI standard.
+ */
+
+#include <xen/interface/xen.h>
+
+#define XEN_HYPERCALL_TAG 0xEA1
+
+#define HYPERCALL_SIMPLE(hypercall) \
+.globl HYPERVISOR_##hypercall; \
+.align 4,0x90; \
+HYPERVISOR_##hypercall: \
+ mov x16, #__HYPERVISOR_##hypercall; \
+ hvc XEN_HYPERCALL_TAG; \
+ ret; \
+
+#define HYPERCALL0 HYPERCALL_SIMPLE
+#define HYPERCALL1 HYPERCALL_SIMPLE
+#define HYPERCALL2 HYPERCALL_SIMPLE
+#define HYPERCALL3 HYPERCALL_SIMPLE
+#define HYPERCALL4 HYPERCALL_SIMPLE
+#define HYPERCALL5 HYPERCALL_SIMPLE
+
+ .text
+
+HYPERCALL2(xen_version);
+HYPERCALL3(console_io);
+HYPERCALL3(grant_table_op);
+HYPERCALL2(sched_op);
+HYPERCALL2(event_channel_op);
+HYPERCALL2(hvm_op);
+HYPERCALL2(memory_op);
+
diff --git a/roms/u-boot/arch/arm/cpu/armv8/xen/lowlevel_init.S b/roms/u-boot/arch/arm/cpu/armv8/xen/lowlevel_init.S
new file mode 100644
index 000000000..760e32ed7
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/armv8/xen/lowlevel_init.S
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0+
+ *
+ * (C) 2017 NXP
+ * (C) 2020 EPAM Systems Inc.
+ */
+
+#include <config.h>
+
+.align 8
+.global rom_pointer
+rom_pointer:
+ .space 32
+
+/*
+ * Routine: save_boot_params (called after reset from start.S)
+ */
+
+.global save_boot_params
+save_boot_params:
+ /* The firmware provided ATAG/FDT address can be found in r2/x0 */
+ adr x1, rom_pointer
+ stp x0, x2, [x1], #16
+ stp x3, x4, [x1], #16
+
+ /* Returns */
+ b save_boot_params_ret
+
+.global restore_boot_params
+restore_boot_params:
+ adr x1, rom_pointer
+ ldp x0, x2, [x1], #16
+ ldp x3, x4, [x1], #16
+ ret
diff --git a/roms/u-boot/arch/arm/cpu/pxa/Makefile b/roms/u-boot/arch/arm/cpu/pxa/Makefile
new file mode 100644
index 000000000..263d9ddb4
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/pxa/Makefile
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+extra-y = start.o
+
+obj-$(CONFIG_CPU_PXA25X) += pxa2xx.o
+obj-$(CONFIG_CPU_PXA27X) += pxa2xx.o
+
+obj-y += cpuinfo.o
+obj-y += timer.o
+obj-y += usb.o
+obj-y += relocate.o
+obj-y += cache.o
diff --git a/roms/u-boot/arch/arm/cpu/pxa/cache.c b/roms/u-boot/arch/arm/cpu/pxa/cache.c
new file mode 100644
index 000000000..a2ec5e28c
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/pxa/cache.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Vasily Khoruzhick <anarsoul@gmail.com>
+ */
+
+#include <cpu_func.h>
+#include <asm/cache.h>
+#include <linux/types.h>
+#include <common.h>
+
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+void invalidate_dcache_all(void)
+{
+ /* Flush/Invalidate I cache */
+ asm volatile("mcr p15, 0, %0, c7, c5, 0\n" : : "r"(0));
+ /* Flush/Invalidate D cache */
+ asm volatile("mcr p15, 0, %0, c7, c6, 0\n" : : "r"(0));
+}
+
+void flush_dcache_all(void)
+{
+ return invalidate_dcache_all();
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+ start &= ~(CONFIG_SYS_CACHELINE_SIZE - 1);
+ stop &= ~(CONFIG_SYS_CACHELINE_SIZE - 1);
+
+ while (start <= stop) {
+ asm volatile("mcr p15, 0, %0, c7, c6, 1\n" : : "r"(start));
+ start += CONFIG_SYS_CACHELINE_SIZE;
+ }
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+ return invalidate_dcache_range(start, stop);
+}
+#else /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
+void invalidate_dcache_all(void)
+{
+}
+
+void flush_dcache_all(void)
+{
+}
+#endif /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
+
+/*
+ * Stub implementations for l2 cache operations
+ */
+
+__weak void l2_cache_disable(void) {}
+
+#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)
+__weak void invalidate_l2_cache(void) {}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/pxa/config.mk b/roms/u-boot/arch/arm/cpu/pxa/config.mk
new file mode 100644
index 000000000..e7b183674
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/pxa/config.mk
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2002
+# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+# Marius Groeger <mgroeger@sysgo.de>
+
+#
+# !WARNING!
+# The PXA's OneNAND SPL uses .text.0 and .text.1 segments to allow booting from
+# really small OneNAND memories where the mmap'd window is only 1KiB big. The
+# .text.0 contains only the bare minimum needed to load the real SPL into SRAM.
+# Add .text.0 and .text.1 into OBJFLAGS, so when the SPL is being objcopy'd,
+# they are not discarded.
+#
+
+#ifdef CONFIG_SPL_BUILD
+OBJCOPYFLAGS += -j .text.0 -j .text.1
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/pxa/cpuinfo.c b/roms/u-boot/arch/arm/cpu/pxa/cpuinfo.c
new file mode 100644
index 000000000..0d9542f99
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/pxa/cpuinfo.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * PXA CPU information display
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <errno.h>
+#include <linux/compiler.h>
+
+#ifdef CONFIG_CPU_PXA25X
+#if ((CONFIG_SYS_INIT_SP_ADDR) != 0xfffff800)
+#error "Init SP address must be set to 0xfffff800 for PXA250"
+#endif
+#endif
+
+#define CPU_MASK_PXA_PRODID 0x000003f0
+#define CPU_MASK_PXA_REVID 0x0000000f
+
+#define CPU_MASK_PRODREV (CPU_MASK_PXA_PRODID | CPU_MASK_PXA_REVID)
+
+#define CPU_VALUE_PXA25X 0x100
+#define CPU_VALUE_PXA27X 0x110
+
+static uint32_t pxa_get_cpuid(void)
+{
+ uint32_t cpuid;
+ asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r"(cpuid));
+ return cpuid;
+}
+
+int cpu_is_pxa25x(void)
+{
+ uint32_t id = pxa_get_cpuid();
+ id &= CPU_MASK_PXA_PRODID;
+ return id == CPU_VALUE_PXA25X;
+}
+
+int cpu_is_pxa27x(void)
+{
+ uint32_t id = pxa_get_cpuid();
+ id &= CPU_MASK_PXA_PRODID;
+ return id == CPU_VALUE_PXA27X;
+}
+
+int cpu_is_pxa27xm(void)
+{
+ uint32_t id = pxa_get_cpuid();
+ return ((id & CPU_MASK_PXA_PRODID) == CPU_VALUE_PXA27X) &&
+ ((id & CPU_MASK_PXA_REVID) == 8);
+}
+
+uint32_t pxa_get_cpu_revision(void)
+{
+ return pxa_get_cpuid() & CPU_MASK_PRODREV;
+}
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+static const char *pxa25x_get_revision(void)
+{
+ static __maybe_unused const char * const revs_25x[] = { "A0" };
+ static __maybe_unused const char * const revs_26x[] = {
+ "A0", "B0", "B1"
+ };
+ static const char *unknown = "Unknown";
+ uint32_t id;
+
+ if (!cpu_is_pxa25x())
+ return unknown;
+
+ id = pxa_get_cpuid() & CPU_MASK_PXA_REVID;
+
+/* PXA26x is a sick special case as it can't be told apart from PXA25x :-( */
+#ifdef CONFIG_CPU_PXA26X
+ switch (id) {
+ case 3: return revs_26x[0];
+ case 5: return revs_26x[1];
+ case 6: return revs_26x[2];
+ }
+#else
+ if (id == 6)
+ return revs_25x[0];
+#endif
+ return unknown;
+}
+
+static const char *pxa27x_get_revision(void)
+{
+ static const char *const rev[] = { "A0", "A1", "B0", "B1", "C0", "C5" };
+ static const char *unknown = "Unknown";
+ uint32_t id;
+
+ if (!cpu_is_pxa27x())
+ return unknown;
+
+ id = pxa_get_cpuid() & CPU_MASK_PXA_REVID;
+
+ if ((id == 5) || (id == 6) || (id > 8))
+ return unknown;
+
+ /* Cap the special PXA270 C5 case. */
+ if (id == 7)
+ id = 5;
+
+ /* Cap the special PXA270M A1 case. */
+ if (id == 8)
+ id = 1;
+
+ return rev[id];
+}
+
+static int print_cpuinfo_pxa2xx(void)
+{
+ if (cpu_is_pxa25x()) {
+ puts("Marvell PXA25x rev. ");
+ puts(pxa25x_get_revision());
+ } else if (cpu_is_pxa27x()) {
+ puts("Marvell PXA27x");
+ if (cpu_is_pxa27xm()) puts("M");
+ puts(" rev. ");
+ puts(pxa27x_get_revision());
+ } else
+ return -EINVAL;
+
+ puts("\n");
+
+ return 0;
+}
+
+int print_cpuinfo(void)
+{
+ int ret;
+
+ puts("CPU: ");
+
+ ret = print_cpuinfo_pxa2xx();
+ if (!ret)
+ return ret;
+
+ return ret;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/pxa/pxa2xx.c b/roms/u-boot/arch/arm/cpu/pxa/pxa2xx.c
new file mode 100644
index 000000000..c7efb6775
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/pxa/pxa2xx.c
@@ -0,0 +1,295 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <init.h>
+#include <irq_func.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <command.h>
+
+/* Flush I/D-cache */
+static void cache_flush(void)
+{
+ unsigned long i = 0;
+
+ asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (i));
+}
+
+int cleanup_before_linux(void)
+{
+ /*
+ * This function is called just before we call Linux. It prepares
+ * the processor for Linux by just disabling everything that can
+ * disturb booting Linux.
+ */
+
+ disable_interrupts();
+ icache_disable();
+ dcache_disable();
+ cache_flush();
+
+ return 0;
+}
+
+inline void writelrb(uint32_t val, uint32_t addr)
+{
+ writel(val, addr);
+ asm volatile("" : : : "memory");
+ readl(addr);
+ asm volatile("" : : : "memory");
+}
+
+void pxa2xx_dram_init(void)
+{
+ uint32_t tmp;
+ int i;
+ /*
+ * 1) Initialize Asynchronous static memory controller
+ */
+
+ writelrb(CONFIG_SYS_MSC0_VAL, MSC0);
+ writelrb(CONFIG_SYS_MSC1_VAL, MSC1);
+ writelrb(CONFIG_SYS_MSC2_VAL, MSC2);
+ /*
+ * 2) Initialize Card Interface
+ */
+
+ /* MECR: Memory Expansion Card Register */
+ writelrb(CONFIG_SYS_MECR_VAL, MECR);
+ /* MCMEM0: Card Interface slot 0 timing */
+ writelrb(CONFIG_SYS_MCMEM0_VAL, MCMEM0);
+ /* MCMEM1: Card Interface slot 1 timing */
+ writelrb(CONFIG_SYS_MCMEM1_VAL, MCMEM1);
+ /* MCATT0: Card Interface Attribute Space Timing, slot 0 */
+ writelrb(CONFIG_SYS_MCATT0_VAL, MCATT0);
+ /* MCATT1: Card Interface Attribute Space Timing, slot 1 */
+ writelrb(CONFIG_SYS_MCATT1_VAL, MCATT1);
+ /* MCIO0: Card Interface I/O Space Timing, slot 0 */
+ writelrb(CONFIG_SYS_MCIO0_VAL, MCIO0);
+ /* MCIO1: Card Interface I/O Space Timing, slot 1 */
+ writelrb(CONFIG_SYS_MCIO1_VAL, MCIO1);
+
+ /*
+ * 3) Configure Fly-By DMA register
+ */
+
+ writelrb(CONFIG_SYS_FLYCNFG_VAL, FLYCNFG);
+
+ /*
+ * 4) Initialize Timing for Sync Memory (SDCLK0)
+ */
+
+ /*
+ * Before accessing MDREFR we need a valid DRI field, so we set
+ * this to power on defaults + DRI field.
+ */
+
+ /* Read current MDREFR config and zero out DRI */
+ tmp = readl(MDREFR) & ~0xfff;
+ /* Add user-specified DRI */
+ tmp |= CONFIG_SYS_MDREFR_VAL & 0xfff;
+ /* Configure important bits */
+ tmp |= MDREFR_K0RUN | MDREFR_SLFRSH;
+ tmp &= ~(MDREFR_APD | MDREFR_E1PIN);
+
+ /* Write MDREFR back */
+ writelrb(tmp, MDREFR);
+
+ /*
+ * 5) Initialize Synchronous Static Memory (Flash/Peripherals)
+ */
+
+ /* Initialize SXCNFG register. Assert the enable bits.
+ *
+ * Write SXMRS to cause an MRS command to all enabled banks of
+ * synchronous static memory. Note that SXLCR need not be written
+ * at this time.
+ */
+ writelrb(CONFIG_SYS_SXCNFG_VAL, SXCNFG);
+
+ /*
+ * 6) Initialize SDRAM
+ */
+
+ writelrb(CONFIG_SYS_MDREFR_VAL & ~MDREFR_SLFRSH, MDREFR);
+ writelrb(CONFIG_SYS_MDREFR_VAL | MDREFR_E1PIN, MDREFR);
+
+ /*
+ * 7) Write MDCNFG with MDCNFG:DEx deasserted (set to 0), to configure
+ * but not enable each SDRAM partition pair.
+ */
+
+ writelrb(CONFIG_SYS_MDCNFG_VAL &
+ ~(MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3), MDCNFG);
+
+ /* Wait for the clock to the SDRAMs to stabilize, 100..200 usec. */
+ writel(0, OSCR);
+ while (readl(OSCR) < 0x300)
+ asm volatile("" : : : "memory");
+
+ /*
+ * 8) Trigger a number (usually 8) refresh cycles by attempting
+ * non-burst read or write accesses to disabled SDRAM, as commonly
+ * specified in the power up sequence documented in SDRAM data
+ * sheets. The address(es) used for this purpose must not be
+ * cacheable.
+ */
+ for (i = 9; i >= 0; i--) {
+ writel(i, 0xa0000000);
+ asm volatile("" : : : "memory");
+ }
+ /*
+ * 9) Write MDCNFG with enable bits asserted (MDCNFG:DEx set to 1).
+ */
+
+ tmp = CONFIG_SYS_MDCNFG_VAL &
+ (MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3);
+ tmp |= readl(MDCNFG);
+ writelrb(tmp, MDCNFG);
+
+ /*
+ * 10) Write MDMRS.
+ */
+
+ writelrb(CONFIG_SYS_MDMRS_VAL, MDMRS);
+
+ /*
+ * 11) Enable APD
+ */
+
+ if (CONFIG_SYS_MDREFR_VAL & MDREFR_APD) {
+ tmp = readl(MDREFR);
+ tmp |= MDREFR_APD;
+ writelrb(tmp, MDREFR);
+ }
+}
+
+void pxa_gpio_setup(void)
+{
+ writel(CONFIG_SYS_GPSR0_VAL, GPSR0);
+ writel(CONFIG_SYS_GPSR1_VAL, GPSR1);
+ writel(CONFIG_SYS_GPSR2_VAL, GPSR2);
+#if defined(CONFIG_CPU_PXA27X)
+ writel(CONFIG_SYS_GPSR3_VAL, GPSR3);
+#endif
+
+ writel(CONFIG_SYS_GPCR0_VAL, GPCR0);
+ writel(CONFIG_SYS_GPCR1_VAL, GPCR1);
+ writel(CONFIG_SYS_GPCR2_VAL, GPCR2);
+#if defined(CONFIG_CPU_PXA27X)
+ writel(CONFIG_SYS_GPCR3_VAL, GPCR3);
+#endif
+
+ writel(CONFIG_SYS_GPDR0_VAL, GPDR0);
+ writel(CONFIG_SYS_GPDR1_VAL, GPDR1);
+ writel(CONFIG_SYS_GPDR2_VAL, GPDR2);
+#if defined(CONFIG_CPU_PXA27X)
+ writel(CONFIG_SYS_GPDR3_VAL, GPDR3);
+#endif
+
+ writel(CONFIG_SYS_GAFR0_L_VAL, GAFR0_L);
+ writel(CONFIG_SYS_GAFR0_U_VAL, GAFR0_U);
+ writel(CONFIG_SYS_GAFR1_L_VAL, GAFR1_L);
+ writel(CONFIG_SYS_GAFR1_U_VAL, GAFR1_U);
+ writel(CONFIG_SYS_GAFR2_L_VAL, GAFR2_L);
+ writel(CONFIG_SYS_GAFR2_U_VAL, GAFR2_U);
+#if defined(CONFIG_CPU_PXA27X)
+ writel(CONFIG_SYS_GAFR3_L_VAL, GAFR3_L);
+ writel(CONFIG_SYS_GAFR3_U_VAL, GAFR3_U);
+#endif
+
+ writel(CONFIG_SYS_PSSR_VAL, PSSR);
+}
+
+void pxa_interrupt_setup(void)
+{
+ writel(0, ICLR);
+ writel(0, ICMR);
+#if defined(CONFIG_CPU_PXA27X)
+ writel(0, ICLR2);
+ writel(0, ICMR2);
+#endif
+}
+
+void pxa_clock_setup(void)
+{
+ writel(CONFIG_SYS_CKEN, CKEN);
+ writel(CONFIG_SYS_CCCR, CCCR);
+ asm volatile("mcr p14, 0, %0, c6, c0, 0" : : "r"(0x0b));
+
+ /* enable the 32Khz oscillator for RTC and PowerManager */
+ writel(OSCC_OON, OSCC);
+ while (!(readl(OSCC) & OSCC_OOK))
+ asm volatile("" : : : "memory");
+}
+
+void pxa_wakeup(void)
+{
+ uint32_t rcsr;
+
+ rcsr = readl(RCSR);
+ writel(rcsr & (RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR), RCSR);
+
+ /* Wakeup */
+ if (rcsr & RCSR_SMR) {
+ writel(PSSR_PH, PSSR);
+ pxa2xx_dram_init();
+ icache_disable();
+ dcache_disable();
+ asm volatile("mov pc, %0" : : "r"(readl(PSPR)));
+ }
+}
+
+int arch_cpu_init(void)
+{
+ pxa_gpio_setup();
+ pxa_wakeup();
+ pxa_interrupt_setup();
+ pxa_clock_setup();
+ return 0;
+}
+
+void i2c_clk_enable(void)
+{
+ /* Set the global I2C clock on */
+ writel(readl(CKEN) | CKEN14_I2C, CKEN);
+}
+
+void __attribute__((weak)) reset_cpu(void) __attribute__((noreturn));
+
+void reset_cpu(void)
+{
+ uint32_t tmp;
+
+ setbits_le32(OWER, OWER_WME);
+
+ tmp = readl(OSCR);
+ tmp += 0x1000;
+ writel(tmp, OSMR3);
+ writel(MDREFR_SLFRSH, MDREFR);
+
+ for (;;)
+ ;
+}
+
+void enable_caches(void)
+{
+#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
+ icache_enable();
+#endif
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+ dcache_enable();
+#endif
+}
diff --git a/roms/u-boot/arch/arm/cpu/pxa/relocate.S b/roms/u-boot/arch/arm/cpu/pxa/relocate.S
new file mode 100644
index 000000000..778cd45e9
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/pxa/relocate.S
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * relocate - PXA270 vector relocation
+ *
+ * Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net>
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * The PXA SoC is very specific with respect to exceptions: it
+ * does not provide RAM at the high vectors address (0xFFFF0000),
+ * thus only the low address (0x00000000) is useable; but that is
+ * in ROM, so let's avoid relocating the vectors.
+ */
+ .section .text.relocate_vectors,"ax",%progbits
+
+ENTRY(relocate_vectors)
+
+ bx lr
+
+ENDPROC(relocate_vectors)
diff --git a/roms/u-boot/arch/arm/cpu/pxa/start.S b/roms/u-boot/arch/arm/cpu/pxa/start.S
new file mode 100644
index 000000000..575abac09
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/pxa/start.S
@@ -0,0 +1,205 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * armboot - Startup Code for XScale CPU-core
+ *
+ * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
+ * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ * Copyright (C) 2000 Wolfgang Denk <wd@denx.de>
+ * Copyright (C) 2001 Alex Zuepke <azu@sysgo.de>
+ * Copyright (C) 2001 Marius Groger <mag@sysgo.de>
+ * Copyright (C) 2002 Alex Zupke <azu@sysgo.de>
+ * Copyright (C) 2002 Gary Jennejohn <garyj@denx.de>
+ * Copyright (C) 2002 Kyle Harris <kharris@nexus-tech.net>
+ * Copyright (C) 2003 Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>
+ * Copyright (C) 2003 Kshitij <kshitij@ti.com>
+ * Copyright (C) 2003 Richard Woodruff <r-woodruff2@ti.com>
+ * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ * Copyright (C) 2004 Texas Instruments <r-woodruff2@ti.com>
+ * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * setup Memory and board specific bits prior to relocation.
+ * relocate armboot to ram
+ * setup stack
+ *
+ *************************************************************************
+ */
+
+ .globl reset
+
+reset:
+ /*
+ * set the cpu to SVC32 mode
+ */
+ mrs r0,cpsr
+ bic r0,r0,#0x1f
+ orr r0,r0,#0xd3
+ msr cpsr,r0
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ bl cpu_init_crit
+#endif
+
+#ifdef CONFIG_CPU_PXA25X
+ bl lock_cache_for_stack
+#endif
+#ifdef CONFIG_CPU_PXA27X
+ /*
+ * enable clock for SRAM
+ */
+ ldr r0,=CKEN
+ ldr r1,[r0]
+ orr r1,r1,#(1 << 20)
+ str r1,[r0]
+#endif
+ bl _main
+
+/*------------------------------------------------------------------------------*/
+
+ .globl c_runtime_cpu_setup
+c_runtime_cpu_setup:
+
+#ifdef CONFIG_CPU_PXA25X
+ /*
+ * Unlock (actually, disable) the cache now that board_init_f
+ * is done. We could do this earlier but we would need to add
+ * a new C runtime hook, whereas c_runtime_cpu_setup already
+ * exists.
+ * As this routine is just a call to cpu_init_crit, let us
+ * tail-optimize and do a simple branch here.
+ */
+ b cpu_init_crit
+#else
+ bx lr
+#endif
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_CPU_PXA25X)
+cpu_init_crit:
+ /*
+ * flush v4 I/D caches
+ */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 /* Invalidate I+D+BTB caches */
+ mcr p15, 0, r0, c8, c7, 0 /* Invalidate Unified TLB */
+
+ /*
+ * disable MMU stuff and caches
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00003300 @ clear bits 13:12, 9:8 (--VI --RS)
+ bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
+ orr r0, r0, #0x00000002 @ set bit 1 (A) Align
+ mcr p15, 0, r0, c1, c0, 0
+
+ mov pc, lr /* back to my caller */
+#endif /* !CONFIG_SKIP_LOWLEVEL_INIT || CONFIG_CPU_PXA25X */
+
+/*
+ * Enable MMU to use DCache as DRAM.
+ *
+ * This is useful on PXA25x and PXA26x in early bootstages, where there is no
+ * other possible memory available to hold stack.
+ */
+#ifdef CONFIG_CPU_PXA25X
+.macro CPWAIT reg
+ mrc p15, 0, \reg, c2, c0, 0
+ mov \reg, \reg
+ sub pc, pc, #4
+.endm
+lock_cache_for_stack:
+ /* Domain access -- enable for all CPs */
+ ldr r0, =0x0000ffff
+ mcr p15, 0, r0, c3, c0, 0
+
+ /* Point TTBR to MMU table */
+ ldr r0, =mmutable
+ mcr p15, 0, r0, c2, c0, 0
+
+ /* Kick in MMU, ICache, DCache, BTB */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, #0x1b00
+ bic r0, #0x0087
+ orr r0, #0x1800
+ orr r0, #0x0005
+ mcr p15, 0, r0, c1, c0, 0
+ CPWAIT r0
+
+ /* Unlock Icache, Dcache */
+ mcr p15, 0, r0, c9, c1, 1
+ mcr p15, 0, r0, c9, c2, 1
+
+ /* Flush Icache, Dcache, BTB */
+ mcr p15, 0, r0, c7, c7, 0
+
+ /* Unlock I-TLB, D-TLB */
+ mcr p15, 0, r0, c10, c4, 1
+ mcr p15, 0, r0, c10, c8, 1
+
+ /* Flush TLB */
+ mcr p15, 0, r0, c8, c7, 0
+
+ /* Allocate 4096 bytes of Dcache as RAM */
+
+ /* Drain pending loads and stores */
+ mcr p15, 0, r0, c7, c10, 4
+
+ mov r4, #0x00
+ mov r5, #0x00
+ mov r2, #0x01
+ mcr p15, 0, r0, c9, c2, 0
+ CPWAIT r0
+
+ /* 128 lines reserved (128 x 32bytes = 4096 bytes total) */
+ mov r0, #128
+ ldr r1, =0xfffff000
+
+alloc:
+ mcr p15, 0, r1, c7, c2, 5
+ /* Drain pending loads and stores */
+ mcr p15, 0, r0, c7, c10, 4
+ strd r4, [r1], #8
+ strd r4, [r1], #8
+ strd r4, [r1], #8
+ strd r4, [r1], #8
+ subs r0, #0x01
+ bne alloc
+ /* Drain pending loads and stores */
+ mcr p15, 0, r0, c7, c10, 4
+ mov r2, #0x00
+ mcr p15, 0, r2, c9, c2, 0
+ CPWAIT r0
+
+ mov pc, lr
+
+.section .mmutable, "a"
+mmutable:
+ .align 14
+ /* 0x00000000 - 0xffe00000 : 1:1, uncached mapping */
+ .set __base, 0
+ .rept 0xfff
+ .word (__base << 20) | 0xc12
+ .set __base, __base + 1
+ .endr
+
+ /* 0xfff00000 : 1:1, cached mapping */
+ .word (0xfff << 20) | 0x1c1e
+#endif /* CONFIG_CPU_PXA25X */
diff --git a/roms/u-boot/arch/arm/cpu/pxa/timer.c b/roms/u-boot/arch/arm/cpu/pxa/timer.c
new file mode 100644
index 000000000..8e9d61044
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/pxa/timer.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Marvell PXA2xx/3xx timer driver
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+
+int timer_init(void)
+{
+ writel(0, CONFIG_SYS_TIMER_COUNTER);
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/cpu/pxa/usb.c b/roms/u-boot/arch/arm/cpu/pxa/usb.c
new file mode 100644
index 000000000..13e010d91
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/pxa/usb.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2006
+ * Markus Klotzbuecher, DENX Software Engineering <mk@denx.de>
+ */
+
+#include <common.h>
+#include <linux/delay.h>
+
+#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT)
+# if defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_CPU_PXA27X)
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/io.h>
+#include <usb.h>
+
+int usb_cpu_init(void)
+{
+#if defined(CONFIG_CPU_MONAHANS)
+ /* Enable USB host clock. */
+ writel(readl(CKENA) | CKENA_2_USBHOST | CKENA_20_UDC, CKENA);
+ udelay(100);
+#endif
+#if defined(CONFIG_CPU_PXA27X)
+ /* Enable USB host clock. */
+ writel(readl(CKEN) | CKEN10_USBHOST, CKEN);
+#endif
+
+#if defined(CONFIG_CPU_MONAHANS)
+ /* Configure Port 2 for Host (USB Client Registers) */
+ writel(0x3000c, UP2OCR);
+#endif
+
+ writel(readl(UHCHR) | UHCHR_FHR, UHCHR);
+ mdelay(11);
+ writel(readl(UHCHR) & ~UHCHR_FHR, UHCHR);
+
+ writel(readl(UHCHR) | UHCHR_FSBIR, UHCHR);
+ while (readl(UHCHR) & UHCHR_FSBIR)
+ udelay(1);
+
+#if defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_PXA27X)
+ writel(readl(UHCHR) & ~UHCHR_SSEP0, UHCHR);
+#endif
+#if defined(CONFIG_CPU_PXA27X)
+ writel(readl(UHCHR) & ~UHCHR_SSEP2, UHCHR);
+#endif
+ writel(readl(UHCHR) & ~(UHCHR_SSEP1 | UHCHR_SSE), UHCHR);
+
+ return 0;
+}
+
+int usb_cpu_stop(void)
+{
+ writel(readl(UHCHR) | UHCHR_FHR, UHCHR);
+ udelay(11);
+ writel(readl(UHCHR) & ~UHCHR_FHR, UHCHR);
+
+ writel(readl(UHCCOMS) | UHCCOMS_HCR, UHCCOMS);
+ udelay(10);
+
+#if defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_PXA27X)
+ writel(readl(UHCHR) | UHCHR_SSEP0, UHCHR);
+#endif
+#if defined(CONFIG_CPU_PXA27X)
+ writel(readl(UHCHR) | UHCHR_SSEP2, UHCHR);
+#endif
+ writel(readl(UHCHR) | UHCHR_SSEP1 | UHCHR_SSE, UHCHR);
+
+#if defined(CONFIG_CPU_MONAHANS)
+ /* Disable USB host clock. */
+ writel(readl(CKENA) & ~(CKENA_2_USBHOST | CKENA_20_UDC), CKENA);
+ udelay(100);
+#endif
+#if defined(CONFIG_CPU_PXA27X)
+ /* Disable USB host clock. */
+ writel(readl(CKEN) & ~CKEN10_USBHOST, CKEN);
+#endif
+
+ return 0;
+}
+
+int usb_cpu_init_fail(void)
+{
+ return usb_cpu_stop();
+}
+
+# endif /* defined(CONFIG_CPU_MONAHANS) || defined(CONFIG_CPU_PXA27X) */
+#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */
diff --git a/roms/u-boot/arch/arm/cpu/sa1100/Makefile b/roms/u-boot/arch/arm/cpu/sa1100/Makefile
new file mode 100644
index 000000000..38193092c
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/sa1100/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+extra-y = start.o
+
+obj-y += cpu.o
+obj-y += timer.o
diff --git a/roms/u-boot/arch/arm/cpu/sa1100/cpu.c b/roms/u-boot/arch/arm/cpu/sa1100/cpu.c
new file mode 100644
index 000000000..6f67f7fc2
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/sa1100/cpu.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ */
+
+/*
+ * CPU specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <irq_func.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+static void cache_flush(void);
+
+int cleanup_before_linux (void)
+{
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * just disable everything that can disturb booting linux
+ */
+
+ disable_interrupts();
+
+ /* turn off I-cache */
+ icache_disable();
+ dcache_disable();
+
+ /* flush I-cache */
+ cache_flush();
+
+ return (0);
+}
+
+/* flush I/D-cache */
+static void cache_flush (void)
+{
+ unsigned long i = 0;
+
+ asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i));
+}
+
+#define RST_BASE 0x90030000
+#define RSRR 0x00
+#define RCSR 0x04
+
+__attribute__((noreturn)) void reset_cpu(void)
+{
+ /* repeat endlessly */
+ while (1) {
+ writel(0, RST_BASE + RCSR);
+ writel(1, RST_BASE + RSRR);
+ }
+}
diff --git a/roms/u-boot/arch/arm/cpu/sa1100/start.S b/roms/u-boot/arch/arm/cpu/sa1100/start.S
new file mode 100644
index 000000000..8eb005309
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/sa1100/start.S
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * armboot - Startup Code for SA1100 CPU
+ *
+ * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
+ * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ * Copyright (C) 2000 Wolfgang Denk <wd@denx.de>
+ * Copyright (c) 2001 Alex Züpke <azu@sysgo.de>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * relocate armboot to ram
+ * setup stack
+ * jump to second stage
+ *
+ *************************************************************************
+ */
+
+ .globl reset
+
+reset:
+ /*
+ * set the cpu to SVC32 mode
+ */
+ mrs r0,cpsr
+ bic r0,r0,#0x1f
+ orr r0,r0,#0xd3
+ msr cpsr,r0
+
+ /*
+ * we do sys-critical inits only at reboot,
+ * not when booting from ram!
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ bl cpu_init_crit
+#endif
+
+ bl _main
+
+/*------------------------------------------------------------------------------*/
+
+ .globl c_runtime_cpu_setup
+c_runtime_cpu_setup:
+
+ mov pc, lr
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+
+
+/* Interrupt-Controller base address */
+IC_BASE: .word 0x90050000
+#define ICMR 0x04
+
+
+/* Reset-Controller */
+RST_BASE: .word 0x90030000
+#define RSRR 0x00
+#define RCSR 0x04
+
+
+/* PWR */
+PWR_BASE: .word 0x90020000
+#define PSPR 0x08
+#define PPCR 0x14
+cpuspeed: .word CONFIG_SYS_CPUSPEED
+
+
+cpu_init_crit:
+ /*
+ * mask all IRQs
+ */
+ ldr r0, IC_BASE
+ mov r1, #0x00
+ str r1, [r0, #ICMR]
+
+ /* set clock speed */
+ ldr r0, PWR_BASE
+ ldr r1, cpuspeed
+ str r1, [r0, #PPCR]
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
+ /*
+ * before relocating, we have to setup RAM timing
+ * because memory timing is board-dependend, you will
+ * find a lowlevel_init.S in your board directory.
+ */
+ mov ip, lr
+ bl lowlevel_init
+ mov lr, ip
+#endif
+
+ /*
+ * disable MMU stuff and enable I-cache
+ */
+ mrc p15,0,r0,c1,c0
+ bic r0, r0, #0x00002000 @ clear bit 13 (X)
+ bic r0, r0, #0x0000000f @ clear bits 3-0 (WCAM)
+ orr r0, r0, #0x00001000 @ set bit 12 (I) Icache
+ orr r0, r0, #0x00000002 @ set bit 1 (A) Align
+ mcr p15,0,r0,c1,c0
+
+ /*
+ * flush v4 I/D caches
+ */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
+ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
+
+ mov pc, lr
diff --git a/roms/u-boot/arch/arm/cpu/sa1100/timer.c b/roms/u-boot/arch/arm/cpu/sa1100/timer.c
new file mode 100644
index 000000000..a5cdaf5a6
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/sa1100/timer.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ */
+
+#include <common.h>
+#include <SA-1100.h>
+#include <time.h>
+#include <linux/delay.h>
+
+static ulong get_timer_masked (void)
+{
+ return OSCR;
+}
+
+ulong get_timer (ulong base)
+{
+ return get_timer_masked ();
+}
+
+void __udelay(unsigned long usec)
+{
+ ulong tmo;
+ ulong endtime;
+ signed long diff;
+
+ if (usec >= 1000) {
+ tmo = usec / 1000;
+ tmo *= CONFIG_SYS_HZ;
+ tmo /= 1000;
+ } else {
+ tmo = usec * CONFIG_SYS_HZ;
+ tmo /= (1000*1000);
+ }
+
+ endtime = get_timer_masked () + tmo;
+
+ do {
+ ulong now = get_timer_masked ();
+ diff = endtime - now;
+ } while (diff >= 0);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return CONFIG_SYS_HZ;
+}
diff --git a/roms/u-boot/arch/arm/cpu/u-boot-spl.lds b/roms/u-boot/arch/arm/cpu/u-boot-spl.lds
new file mode 100644
index 000000000..97899a567
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/u-boot-spl.lds
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2004-2008 Texas Instruments
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ __image_copy_start = .;
+ *(.vectors)
+ CPUDIR/start.o (.text*)
+ *(.text*)
+ *(.glue*)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+ . = ALIGN(4);
+ .data : {
+ *(.data*)
+ }
+
+ . = ALIGN(4);
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+ }
+
+ . = ALIGN(4);
+ .binman_sym_table : {
+ __binman_sym_start = .;
+ KEEP(*(SORT(.binman_sym*)));
+ __binman_sym_end = .;
+ }
+
+ . = ALIGN(4);
+
+ __image_copy_end = .;
+
+ .rel.dyn : {
+ __rel_dyn_start = .;
+ *(.rel*)
+ __rel_dyn_end = .;
+ }
+
+ .end :
+ {
+ *(.__end)
+ }
+
+ _image_binary_end = .;
+
+ .bss __rel_dyn_start (OVERLAY) : {
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_end = .;
+ }
+ __bss_size = __bss_end - __bss_start;
+ .dynsym _image_binary_end : { *(.dynsym) }
+ .dynbss : { *(.dynbss) }
+ .dynstr : { *(.dynstr*) }
+ .dynamic : { *(.dynamic*) }
+ .hash : { *(.hash*) }
+ .plt : { *(.plt*) }
+ .interp : { *(.interp*) }
+ .gnu : { *(.gnu*) }
+ .ARM.exidx : { *(.ARM.exidx*) }
+}
+
+#if defined(IMAGE_MAX_SIZE)
+ASSERT(__image_copy_end - __image_copy_start <= (IMAGE_MAX_SIZE), \
+ "SPL image too big");
+#endif
+
+#if defined(CONFIG_SPL_BSS_MAX_SIZE)
+ASSERT(__bss_end - __bss_start <= (CONFIG_SPL_BSS_MAX_SIZE), \
+ "SPL image BSS too big");
+#endif
+
+#if defined(CONFIG_SPL_MAX_FOOTPRINT)
+ASSERT(__bss_end - _start <= (CONFIG_SPL_MAX_FOOTPRINT), \
+ "SPL image plus BSS too big");
+#endif
diff --git a/roms/u-boot/arch/arm/cpu/u-boot.lds b/roms/u-boot/arch/arm/cpu/u-boot.lds
new file mode 100644
index 000000000..0eb164d2e
--- /dev/null
+++ b/roms/u-boot/arch/arm/cpu/u-boot.lds
@@ -0,0 +1,240 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2004-2008 Texas Instruments
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ */
+
+#include <config.h>
+#include <asm/psci.h>
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+#ifndef CONFIG_CMDLINE
+ /DISCARD/ : { *(.u_boot_list_2_cmd_*) }
+#endif
+#if defined(CONFIG_ARMV7_SECURE_BASE) && defined(CONFIG_ARMV7_NONSEC)
+ /*
+ * If CONFIG_ARMV7_SECURE_BASE is true, secure code will not
+ * bundle with u-boot, and code offsets are fixed. Secure zone
+ * only needs to be copied from the loading address to
+ * CONFIG_ARMV7_SECURE_BASE, which is the linking and running
+ * address for secure code.
+ *
+ * If CONFIG_ARMV7_SECURE_BASE is undefined, the secure zone will
+ * be included in u-boot address space, and some absolute address
+ * were used in secure code. The absolute addresses of the secure
+ * code also needs to be relocated along with the accompanying u-boot
+ * code.
+ *
+ * So DISCARD is only for CONFIG_ARMV7_SECURE_BASE.
+ */
+ /DISCARD/ : { *(.rel._secure*) }
+#endif
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ *(.__image_copy_start)
+ *(.vectors)
+ CPUDIR/start.o (.text*)
+ }
+
+ /* This needs to come before *(.text*) */
+ .__efi_runtime_start : {
+ *(.__efi_runtime_start)
+ }
+
+ .efi_runtime : {
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
+ }
+
+ .__efi_runtime_stop : {
+ *(.__efi_runtime_stop)
+ }
+
+ .text_rest :
+ {
+ *(.text*)
+ }
+
+#ifdef CONFIG_ARMV7_NONSEC
+
+ /* Align the secure section only if we're going to use it in situ */
+ .__secure_start
+#ifndef CONFIG_ARMV7_SECURE_BASE
+ ALIGN(CONSTANT(COMMONPAGESIZE))
+#endif
+ : {
+ KEEP(*(.__secure_start))
+ }
+
+#ifndef CONFIG_ARMV7_SECURE_BASE
+#define CONFIG_ARMV7_SECURE_BASE
+#define __ARMV7_PSCI_STACK_IN_RAM
+#endif
+
+ .secure_text CONFIG_ARMV7_SECURE_BASE :
+ AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
+ {
+ *(._secure.text)
+ }
+
+ .secure_data : AT(LOADADDR(.secure_text) + SIZEOF(.secure_text))
+ {
+ *(._secure.data)
+ }
+
+#ifdef CONFIG_ARMV7_PSCI
+ .secure_stack ALIGN(ADDR(.secure_data) + SIZEOF(.secure_data),
+ CONSTANT(COMMONPAGESIZE)) (NOLOAD) :
+#ifdef __ARMV7_PSCI_STACK_IN_RAM
+ AT(ADDR(.secure_stack))
+#else
+ AT(LOADADDR(.secure_data) + SIZEOF(.secure_data))
+#endif
+ {
+ KEEP(*(.__secure_stack_start))
+
+ /* Skip addreses for stack */
+ . = . + CONFIG_ARMV7_PSCI_NR_CPUS * ARM_PSCI_STACK_SIZE;
+
+ /* Align end of stack section to page boundary */
+ . = ALIGN(CONSTANT(COMMONPAGESIZE));
+
+ KEEP(*(.__secure_stack_end))
+
+#ifdef CONFIG_ARMV7_SECURE_MAX_SIZE
+ /*
+ * We are not checking (__secure_end - __secure_start) here,
+ * as these are the load addresses, and do not include the
+ * stack section. Instead, use the end of the stack section
+ * and the start of the text section.
+ */
+ ASSERT((. - ADDR(.secure_text)) <= CONFIG_ARMV7_SECURE_MAX_SIZE,
+ "Error: secure section exceeds secure memory size");
+#endif
+ }
+
+#ifndef __ARMV7_PSCI_STACK_IN_RAM
+ /* Reset VMA but don't allocate space if we have secure SRAM */
+ . = LOADADDR(.secure_stack);
+#endif
+
+#endif
+
+ .__secure_end : AT(ADDR(.__secure_end)) {
+ *(.__secure_end)
+ LONG(0x1d1071c); /* Must output something to reset LMA */
+ }
+#endif
+
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+ . = ALIGN(4);
+ .data : {
+ *(.data*)
+ }
+
+ . = ALIGN(4);
+
+ . = .;
+
+ . = ALIGN(4);
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+ }
+
+ . = ALIGN(4);
+
+ .efi_runtime_rel_start :
+ {
+ *(.__efi_runtime_rel_start)
+ }
+
+ .efi_runtime_rel : {
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
+ }
+
+ .efi_runtime_rel_stop :
+ {
+ *(.__efi_runtime_rel_stop)
+ }
+
+ . = ALIGN(4);
+
+ .image_copy_end :
+ {
+ *(.__image_copy_end)
+ }
+
+ .rel_dyn_start :
+ {
+ *(.__rel_dyn_start)
+ }
+
+ .rel.dyn : {
+ *(.rel*)
+ }
+
+ .rel_dyn_end :
+ {
+ *(.__rel_dyn_end)
+ }
+
+ .end :
+ {
+ *(.__end)
+ }
+
+ _image_binary_end = .;
+
+ /*
+ * Deprecated: this MMU section is used by pxa at present but
+ * should not be used by new boards/CPUs.
+ */
+ . = ALIGN(4096);
+ .mmutable : {
+ *(.mmutable)
+ }
+
+/*
+ * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
+ * __bss_base and __bss_limit are for linker only (overlay ordering)
+ */
+
+ .bss_start __rel_dyn_start (OVERLAY) : {
+ KEEP(*(.__bss_start));
+ __bss_base = .;
+ }
+
+ .bss __bss_base (OVERLAY) : {
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_limit = .;
+ }
+
+ .bss_end __bss_limit (OVERLAY) : {
+ KEEP(*(.__bss_end));
+ }
+
+ .dynsym _image_binary_end : { *(.dynsym) }
+ .dynbss : { *(.dynbss) }
+ .dynstr : { *(.dynstr*) }
+ .dynamic : { *(.dynamic*) }
+ .plt : { *(.plt*) }
+ .interp : { *(.interp*) }
+ .gnu.hash : { *(.gnu.hash) }
+ .gnu : { *(.gnu*) }
+ .ARM.exidx : { *(.ARM.exidx*) }
+ .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
+}