aboutsummaryrefslogtreecommitdiffstats
path: root/plat
diff options
context:
space:
mode:
authorAlistair Delva <adelva@google.com>2021-02-15 12:43:29 -0800
committerAlistair Delva <adelva@google.com>2021-02-15 12:44:34 -0800
commitfaa476c0caaa598afa5a6109d17102db5fe35ec6 (patch)
tree37a21c69306801ee7cdda5167a30896c8740155b /plat
parentb00a71fc312c9781fa6f404dccfb55b062b2ccac (diff)
parent66306814586b1bf6bcb859aaad218ec3bb090e94 (diff)
downloadplatform_external_arm-trusted-firmware-faa476c0caaa598afa5a6109d17102db5fe35ec6.tar.gz
platform_external_arm-trusted-firmware-faa476c0caaa598afa5a6109d17102db5fe35ec6.tar.bz2
platform_external_arm-trusted-firmware-faa476c0caaa598afa5a6109d17102db5fe35ec6.zip
Merge branch 'aosp/upstream-master' into HEADandroid-s-preview-1
This keeps the bl31 interface change reverted which still has not been fixed in upstream U-Boot for rockchip devices. Test: CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rk3399 \ DEBUG=0 ERROR_DEPRECATED=1 bl31 Signed-off-by: Alistair Delva <adelva@google.com> Change-Id: I7c3972a7b767715efb05593096d5d92dba14c609
Diffstat (limited to 'plat')
-rw-r--r--plat/allwinner/common/allwinner-common.mk14
-rw-r--r--plat/allwinner/common/include/platform_def.h17
-rw-r--r--plat/allwinner/common/sunxi_bl31_setup.c9
-rw-r--r--plat/allwinner/common/sunxi_common.c23
-rw-r--r--plat/allwinner/common/sunxi_pm.c194
-rw-r--r--plat/allwinner/common/sunxi_security.c21
-rw-r--r--plat/allwinner/sun50i_a64/include/sunxi_ccu.h14
-rw-r--r--plat/allwinner/sun50i_a64/include/sunxi_mmap.h7
-rw-r--r--plat/allwinner/sun50i_a64/include/sunxi_spc.h16
-rw-r--r--plat/allwinner/sun50i_a64/sunxi_power.c21
-rw-r--r--plat/allwinner/sun50i_h6/include/sunxi_ccu.h14
-rw-r--r--plat/allwinner/sun50i_h6/include/sunxi_mmap.h13
-rw-r--r--plat/allwinner/sun50i_h6/include/sunxi_spc.h16
-rw-r--r--plat/allwinner/sun50i_h6/platform.mk2
-rw-r--r--plat/allwinner/sun50i_h6/sunxi_power.c74
-rw-r--r--plat/amlogic/axg/axg_bl31_setup.c170
-rw-r--r--plat/amlogic/axg/axg_common.c115
-rw-r--r--plat/amlogic/axg/axg_def.h129
-rw-r--r--plat/amlogic/axg/axg_pm.c166
-rw-r--r--plat/amlogic/axg/include/platform_def.h66
-rw-r--r--plat/amlogic/axg/platform.mk95
-rw-r--r--plat/amlogic/common/aarch64/aml_helpers.S6
-rw-r--r--plat/amlogic/common/aml_console.c4
-rw-r--r--plat/arm/board/a5ds/a5ds_err.c4
-rw-r--r--plat/arm/board/a5ds/fdts/a5ds_fw_config.dts27
-rw-r--r--plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts8
-rw-r--r--plat/arm/board/a5ds/include/platform_def.h27
-rw-r--r--plat/arm/board/a5ds/platform.mk26
-rw-r--r--plat/arm/board/arm_fpga/aarch64/fpga_helpers.S167
-rw-r--r--plat/arm/board/arm_fpga/build_axf.ld.S47
-rw-r--r--plat/arm/board/arm_fpga/fpga_bl31_setup.c254
-rw-r--r--plat/arm/board/arm_fpga/fpga_console.c38
-rw-r--r--plat/arm/board/arm_fpga/fpga_def.h39
-rw-r--r--plat/arm/board/arm_fpga/fpga_gicv3.c84
-rw-r--r--plat/arm/board/arm_fpga/fpga_pm.c103
-rw-r--r--plat/arm/board/arm_fpga/fpga_private.h31
-rw-r--r--plat/arm/board/arm_fpga/fpga_topology.c77
-rw-r--r--plat/arm/board/arm_fpga/include/plat_macros.S13
-rw-r--r--plat/arm/board/arm_fpga/include/platform_def.h88
-rw-r--r--plat/arm/board/arm_fpga/platform.mk120
-rw-r--r--plat/arm/board/arm_fpga/rom_trampoline.S24
-rw-r--r--plat/arm/board/common/board_arm_trusted_boot.c260
-rw-r--r--plat/arm/board/common/board_common.mk105
-rw-r--r--plat/arm/board/common/protpk/README14
-rw-r--r--plat/arm/board/common/protpk/arm_dev_protpk.S18
-rw-r--r--plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin1
-rw-r--r--plat/arm/board/common/protpk/arm_protprivk_rsa.pem27
-rw-r--r--plat/arm/board/common/rotpk/arm_dev_rotpk.S26
-rw-r--r--plat/arm/board/corstone700/common/corstone700_helpers.S (renamed from plat/arm/board/corstone700/corstone700_helpers.S)0
-rw-r--r--plat/arm/board/corstone700/common/corstone700_plat.c (renamed from plat/arm/board/corstone700/corstone700_plat.c)9
-rw-r--r--plat/arm/board/corstone700/common/corstone700_pm.c (renamed from plat/arm/board/corstone700/corstone700_pm.c)0
-rw-r--r--plat/arm/board/corstone700/common/corstone700_security.c (renamed from plat/arm/board/corstone700/corstone700_security.c)0
-rw-r--r--plat/arm/board/corstone700/common/corstone700_stack_protector.c35
-rw-r--r--plat/arm/board/corstone700/common/corstone700_topology.c (renamed from plat/arm/board/corstone700/corstone700_topology.c)6
-rw-r--r--plat/arm/board/corstone700/common/drivers/mhu/mhu.c117
-rw-r--r--plat/arm/board/corstone700/common/drivers/mhu/mhu.h37
-rw-r--r--plat/arm/board/corstone700/common/include/platform_def.h (renamed from plat/arm/board/corstone700/include/platform_def.h)152
-rw-r--r--plat/arm/board/corstone700/platform.mk34
-rw-r--r--plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk18
-rw-r--r--plat/arm/board/fvp/fconf/fconf_hw_config_getter.c296
-rw-r--r--plat/arm/board/fvp/fconf/fconf_nt_config_getter.c64
-rw-r--r--plat/arm/board/fvp/fdts/event_log.dtsi12
-rw-r--r--plat/arm/board/fvp/fdts/fvp_fw_config.dts51
-rw-r--r--plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts10
-rw-r--r--plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts78
-rw-r--r--plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts65
-rw-r--r--plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts112
-rw-r--r--plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts6
-rw-r--r--plat/arm/board/fvp/fdts/optee_sp_manifest.dts49
-rw-r--r--plat/arm/board/fvp/fvp_bl1_setup.c64
-rw-r--r--plat/arm/board/fvp/fvp_bl2_setup.c93
-rw-r--r--plat/arm/board/fvp/fvp_bl31_setup.c64
-rw-r--r--plat/arm/board/fvp/fvp_common.c80
-rw-r--r--plat/arm/board/fvp/fvp_console.c54
-rw-r--r--plat/arm/board/fvp/fvp_def.h33
-rw-r--r--plat/arm/board/fvp/fvp_err.c5
-rw-r--r--plat/arm/board/fvp/fvp_gicv3.c173
-rw-r--r--plat/arm/board/fvp/fvp_io_storage.c18
-rw-r--r--plat/arm/board/fvp/fvp_measured_boot.c40
-rw-r--r--plat/arm/board/fvp/fvp_pm.c23
-rw-r--r--plat/arm/board/fvp/fvp_security.c4
-rw-r--r--plat/arm/board/fvp/fvp_topology.c46
-rw-r--r--plat/arm/board/fvp/fvp_trusted_boot.c31
-rw-r--r--plat/arm/board/fvp/include/fconf_hw_config_getter.h48
-rw-r--r--plat/arm/board/fvp/include/fconf_nt_config_getter.h27
-rw-r--r--plat/arm/board/fvp/include/platform_def.h57
-rw-r--r--plat/arm/board/fvp/jmptbl.i15
-rw-r--r--plat/arm/board/fvp/platform.mk149
-rw-r--r--plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c29
-rw-r--r--plat/arm/board/fvp/sp_min/sp_min-fvp.mk16
-rw-r--r--plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts27
-rw-r--r--plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts8
-rw-r--r--plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c4
-rw-r--r--plat/arm/board/fvp_ve/fvp_ve_err.c4
-rw-r--r--plat/arm/board/fvp_ve/include/platform_def.h29
-rw-r--r--plat/arm/board/fvp_ve/platform.mk29
-rw-r--r--plat/arm/board/juno/fdts/juno_fw_config.dts21
-rw-r--r--plat/arm/board/juno/fdts/juno_tb_fw_config.dts33
-rw-r--r--plat/arm/board/juno/include/platform_def.h32
-rw-r--r--plat/arm/board/juno/jmptbl.i14
-rw-r--r--plat/arm/board/juno/juno_bl1_setup.c14
-rw-r--r--plat/arm/board/juno/juno_common.c42
-rw-r--r--plat/arm/board/juno/juno_decl.h2
-rw-r--r--plat/arm/board/juno/juno_def.h7
-rw-r--r--plat/arm/board/juno/juno_err.c3
-rw-r--r--plat/arm/board/juno/juno_security.c6
-rw-r--r--plat/arm/board/juno/juno_stack_protector.c18
-rw-r--r--plat/arm/board/juno/juno_topology.c4
-rw-r--r--plat/arm/board/juno/juno_trng.c82
-rw-r--r--plat/arm/board/juno/juno_trusted_boot.c126
-rw-r--r--plat/arm/board/juno/platform.mk37
-rw-r--r--plat/arm/board/morello/aarch64/morello_helper.S55
-rw-r--r--plat/arm/board/morello/include/plat_macros.S25
-rw-r--r--plat/arm/board/morello/include/platform_def.h99
-rw-r--r--plat/arm/board/morello/morello_bl31_setup.c137
-rw-r--r--plat/arm/board/morello/morello_def.h33
-rw-r--r--plat/arm/board/morello/morello_interconnect.c33
-rw-r--r--plat/arm/board/morello/morello_plat.c22
-rw-r--r--plat/arm/board/morello/morello_security.c12
-rw-r--r--plat/arm/board/morello/morello_topology.c60
-rw-r--r--plat/arm/board/morello/platform.mk67
-rw-r--r--plat/arm/board/n1sdp/include/platform_def.h6
-rw-r--r--plat/arm/board/n1sdp/n1sdp_bl31_setup.c8
-rw-r--r--plat/arm/board/n1sdp/platform.mk19
-rw-r--r--plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts27
-rw-r--r--plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts3
-rw-r--r--plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts35
-rw-r--r--plat/arm/board/rde1edge/include/platform_def.h10
-rw-r--r--plat/arm/board/rde1edge/platform.mk22
-rw-r--r--plat/arm/board/rde1edge/rde1edge_err.c4
-rw-r--r--plat/arm/board/rde1edge/rde1edge_plat.c13
-rw-r--r--plat/arm/board/rde1edge/rde1edge_topology.c9
-rw-r--r--plat/arm/board/rde1edge/rde1edge_trusted_boot.c26
-rw-r--r--plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts27
-rw-r--r--plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts3
-rw-r--r--plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts36
-rw-r--r--plat/arm/board/rdn1edge/include/platform_def.h17
-rw-r--r--plat/arm/board/rdn1edge/platform.mk29
-rw-r--r--plat/arm/board/rdn1edge/rdn1edge_err.c4
-rw-r--r--plat/arm/board/rdn1edge/rdn1edge_plat.c81
-rw-r--r--plat/arm/board/rdn1edge/rdn1edge_topology.c26
-rw-r--r--plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c26
-rw-r--r--plat/arm/board/rdn2/fdts/rdn2_fw_config.dts27
-rw-r--r--plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts22
-rw-r--r--plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts28
-rw-r--r--plat/arm/board/rdn2/include/platform_def.h65
-rw-r--r--plat/arm/board/rdn2/platform.mk60
-rw-r--r--plat/arm/board/rdn2/rdn2_err.c17
-rw-r--r--plat/arm/board/rdn2/rdn2_plat.c31
-rw-r--r--plat/arm/board/rdn2/rdn2_security.c25
-rw-r--r--plat/arm/board/rdn2/rdn2_topology.c62
-rw-r--r--plat/arm/board/rdn2/rdn2_trusted_boot.c26
-rw-r--r--plat/arm/board/rdv1/fdts/rdv1_fw_config.dts27
-rw-r--r--plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts22
-rw-r--r--plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts28
-rw-r--r--plat/arm/board/rdv1/include/platform_def.h65
-rw-r--r--plat/arm/board/rdv1/platform.mk60
-rw-r--r--plat/arm/board/rdv1/rdv1_err.c17
-rw-r--r--plat/arm/board/rdv1/rdv1_plat.c30
-rw-r--r--plat/arm/board/rdv1/rdv1_security.c22
-rw-r--r--plat/arm/board/rdv1/rdv1_topology.c62
-rw-r--r--plat/arm/board/rdv1/rdv1_trusted_boot.c26
-rw-r--r--plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts27
-rw-r--r--plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts22
-rw-r--r--plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts28
-rw-r--r--plat/arm/board/rdv1mc/include/platform_def.h37
-rw-r--r--plat/arm/board/rdv1mc/platform.mk68
-rw-r--r--plat/arm/board/rdv1mc/rdv1mc_err.c17
-rw-r--r--plat/arm/board/rdv1mc/rdv1mc_plat.c131
-rw-r--r--plat/arm/board/rdv1mc/rdv1mc_security.c10
-rw-r--r--plat/arm/board/rdv1mc/rdv1mc_topology.c78
-rw-r--r--plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c26
-rw-r--r--plat/arm/board/sgi575/fdts/sgi575_fw_config.dts27
-rw-r--r--plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts3
-rw-r--r--plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts35
-rw-r--r--plat/arm/board/sgi575/include/platform_def.h10
-rw-r--r--plat/arm/board/sgi575/platform.mk23
-rw-r--r--plat/arm/board/sgi575/sgi575_err.c4
-rw-r--r--plat/arm/board/sgi575/sgi575_plat.c14
-rw-r--r--plat/arm/board/sgi575/sgi575_trusted_boot.c26
-rw-r--r--plat/arm/board/sgm775/fdts/sgm775_fw_config.dts21
-rw-r--r--plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts22
-rw-r--r--plat/arm/board/sgm775/include/platform_def.h5
-rw-r--r--plat/arm/board/sgm775/platform.mk18
-rw-r--r--plat/arm/board/sgm775/sgm775_err.c4
-rw-r--r--plat/arm/board/sgm775/sgm775_trusted_boot.c26
-rw-r--r--plat/arm/board/tc0/fdts/tc0_fw_config.dts33
-rw-r--r--plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts118
-rw-r--r--plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts104
-rw-r--r--plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts54
-rw-r--r--plat/arm/board/tc0/include/plat_macros.S24
-rw-r--r--plat/arm/board/tc0/include/platform_def.h266
-rw-r--r--plat/arm/board/tc0/include/tc0_helpers.S61
-rw-r--r--plat/arm/board/tc0/include/tc0_plat.h12
-rw-r--r--plat/arm/board/tc0/platform.mk119
-rw-r--r--plat/arm/board/tc0/tc0_bl31_setup.c55
-rw-r--r--plat/arm/board/tc0/tc0_err.c17
-rw-r--r--plat/arm/board/tc0/tc0_interconnect.c35
-rw-r--r--plat/arm/board/tc0/tc0_plat.c155
-rw-r--r--plat/arm/board/tc0/tc0_security.c23
-rw-r--r--plat/arm/board/tc0/tc0_topology.c58
-rw-r--r--plat/arm/board/tc0/tc0_trusted_boot.c26
-rw-r--r--plat/arm/common/aarch32/arm_bl2_mem_params_desc.c3
-rw-r--r--plat/arm/common/aarch32/arm_helpers.S6
-rw-r--r--plat/arm/common/aarch64/arm_bl2_mem_params_desc.c3
-rw-r--r--plat/arm/common/aarch64/arm_ehf.c33
-rw-r--r--plat/arm/common/aarch64/arm_helpers.S6
-rw-r--r--plat/arm/common/aarch64/arm_sdei.c47
-rw-r--r--plat/arm/common/aarch64/execution_state_switch.c3
-rw-r--r--plat/arm/common/arm_bl1_setup.c68
-rw-r--r--plat/arm/common/arm_bl2_setup.c50
-rw-r--r--plat/arm/common/arm_bl31_setup.c82
-rw-r--r--plat/arm/common/arm_common.c31
-rw-r--r--plat/arm/common/arm_common.mk69
-rw-r--r--plat/arm/common/arm_console.c19
-rw-r--r--plat/arm/common/arm_dyn_cfg.c221
-rw-r--r--plat/arm/common/arm_dyn_cfg_helpers.c391
-rw-r--r--plat/arm/common/arm_image_load.c55
-rw-r--r--plat/arm/common/arm_io_storage.c288
-rw-r--r--plat/arm/common/arm_nor_psci_mem_protect.c3
-rw-r--r--plat/arm/common/arm_pm.c3
-rw-r--r--plat/arm/common/arm_tzc400.c9
-rw-r--r--plat/arm/common/fconf/arm_fconf_io.c304
-rw-r--r--plat/arm/common/fconf/arm_fconf_sp.c155
-rw-r--r--plat/arm/common/fconf/fconf_nv_cntr_getter.c62
-rw-r--r--plat/arm/common/fconf/fconf_sdei_getter.c103
-rw-r--r--plat/arm/common/fconf/fconf_sec_intr_config.c131
-rw-r--r--plat/arm/common/sp_min/arm_sp_min_setup.c20
-rw-r--r--plat/arm/common/tsp/arm_tsp_setup.c10
-rw-r--r--plat/arm/css/common/css_pm.c29
-rw-r--r--plat/arm/css/sgi/aarch64/sgi_helper.S24
-rw-r--r--plat/arm/css/sgi/include/sgi_base_platform_def.h56
-rw-r--r--plat/arm/css/sgi/include/sgi_plat.h13
-rw-r--r--plat/arm/css/sgi/include/sgi_soc_css_def_v2.h194
-rw-r--r--plat/arm/css/sgi/include/sgi_soc_platform_def.h15
-rw-r--r--plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h13
-rw-r--r--plat/arm/css/sgi/include/sgi_variant.h15
-rw-r--r--plat/arm/css/sgi/sgi-common.mk23
-rw-r--r--plat/arm/css/sgi/sgi_bl31_setup.c62
-rw-r--r--plat/arm/css/sgi/sgi_image_load.c9
-rw-r--r--plat/arm/css/sgi/sgi_plat.c11
-rw-r--r--plat/arm/css/sgi/sgi_plat_v2.c85
-rw-r--r--plat/arm/css/sgi/sgi_ras.c18
-rw-r--r--plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts4
-rw-r--r--plat/arm/css/sgm/include/sgm_base_platform_def.h22
-rw-r--r--plat/arm/css/sgm/sgm-common.mk16
-rw-r--r--plat/arm/css/sgm/sgm_bl31_setup.c4
-rw-r--r--plat/brcm/board/common/bcm_console.c65
-rw-r--r--plat/brcm/board/common/bcm_elog.c268
-rw-r--r--plat/brcm/board/common/bcm_elog_ddr.c133
-rw-r--r--plat/brcm/board/common/bcm_elog_ddr.h107
-rw-r--r--plat/brcm/board/common/board_arm_trusted_boot.c624
-rw-r--r--plat/brcm/board/common/board_common.c74
-rw-r--r--plat/brcm/board/common/board_common.mk285
-rw-r--r--plat/brcm/board/common/brcm_mbedtls.c12
-rw-r--r--plat/brcm/board/common/chip_id.h37
-rw-r--r--plat/brcm/board/common/cmn_plat_def.h84
-rw-r--r--plat/brcm/board/common/cmn_plat_util.h43
-rw-r--r--plat/brcm/board/common/cmn_sec.c49
-rw-r--r--plat/brcm/board/common/cmn_sec.h19
-rw-r--r--plat/brcm/board/common/err.c37
-rw-r--r--plat/brcm/board/common/plat_setup.c27
-rw-r--r--plat/brcm/board/common/platform_common.c94
-rw-r--r--plat/brcm/board/common/sbl_util.c40
-rw-r--r--plat/brcm/board/common/sbl_util.h19
-rw-r--r--plat/brcm/board/common/timer_sync.c71
-rw-r--r--plat/brcm/board/stingray/aarch64/plat_helpers.S263
-rw-r--r--plat/brcm/board/stingray/bcm958742t-ns3.mk22
-rw-r--r--plat/brcm/board/stingray/bcm958742t.mk19
-rw-r--r--plat/brcm/board/stingray/driver/ddr/soc/include/board_family.h33
-rw-r--r--plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.c302
-rw-r--r--plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.h11
-rw-r--r--plat/brcm/board/stingray/driver/ihost_pll_config.c287
-rw-r--r--plat/brcm/board/stingray/driver/plat_emmc.c109
-rw-r--r--plat/brcm/board/stingray/driver/swreg.c375
-rw-r--r--plat/brcm/board/stingray/include/bl33_info.h38
-rw-r--r--plat/brcm/board/stingray/include/board_info.h38
-rw-r--r--plat/brcm/board/stingray/include/crmu_def.h227
-rw-r--r--plat/brcm/board/stingray/include/ddr_init.h39
-rw-r--r--plat/brcm/board/stingray/include/fsx.h37
-rw-r--r--plat/brcm/board/stingray/include/ihost_pm.h19
-rw-r--r--plat/brcm/board/stingray/include/iommu.h19
-rw-r--r--plat/brcm/board/stingray/include/ncsi.h32
-rw-r--r--plat/brcm/board/stingray/include/paxb.h74
-rw-r--r--plat/brcm/board/stingray/include/paxc.h23
-rw-r--r--plat/brcm/board/stingray/include/plat_macros.S52
-rw-r--r--plat/brcm/board/stingray/include/platform_def.h268
-rw-r--r--plat/brcm/board/stingray/include/platform_sotp.h36
-rw-r--r--plat/brcm/board/stingray/include/scp_cmd.h25
-rw-r--r--plat/brcm/board/stingray/include/scp_utils.h34
-rw-r--r--plat/brcm/board/stingray/include/sdio.h247
-rw-r--r--plat/brcm/board/stingray/include/sr_def.h619
-rw-r--r--plat/brcm/board/stingray/include/sr_utils.h42
-rw-r--r--plat/brcm/board/stingray/include/swreg.h36
-rw-r--r--plat/brcm/board/stingray/include/timer_sync.h12
-rw-r--r--plat/brcm/board/stingray/platform.mk293
-rw-r--r--plat/brcm/board/stingray/src/bl2_setup.c743
-rw-r--r--plat/brcm/board/stingray/src/bl31_setup.c1068
-rw-r--r--plat/brcm/board/stingray/src/brcm_pm_ops.c407
-rw-r--r--plat/brcm/board/stingray/src/fsx.c477
-rw-r--r--plat/brcm/board/stingray/src/ihost_pm.c355
-rw-r--r--plat/brcm/board/stingray/src/iommu.c536
-rw-r--r--plat/brcm/board/stingray/src/ncsi.c54
-rw-r--r--plat/brcm/board/stingray/src/paxb.c911
-rw-r--r--plat/brcm/board/stingray/src/paxc.c267
-rw-r--r--plat/brcm/board/stingray/src/pm.c131
-rw-r--r--plat/brcm/board/stingray/src/scp_cmd.c60
-rw-r--r--plat/brcm/board/stingray/src/scp_utils.c227
-rw-r--r--plat/brcm/board/stingray/src/sdio.c144
-rw-r--r--plat/brcm/board/stingray/src/sr_paxb_phy.c806
-rw-r--r--plat/brcm/board/stingray/src/topology.c52
-rw-r--r--plat/brcm/board/stingray/src/tz_sec.c153
-rw-r--r--plat/brcm/common/brcm_bl2_mem_params_desc.c106
-rw-r--r--plat/brcm/common/brcm_bl2_setup.c202
-rw-r--r--plat/brcm/common/brcm_bl31_setup.c291
-rw-r--r--plat/brcm/common/brcm_ccn.c36
-rw-r--r--plat/brcm/common/brcm_common.c59
-rw-r--r--plat/brcm/common/brcm_gicv3.c91
-rw-r--r--plat/brcm/common/brcm_image_load.c41
-rw-r--r--plat/brcm/common/brcm_io_storage.c408
-rw-r--r--plat/brcm/common/brcm_mhu.c131
-rw-r--r--plat/brcm/common/brcm_mhu.h19
-rw-r--r--plat/brcm/common/brcm_scpi.c252
-rw-r--r--plat/brcm/common/brcm_scpi.h107
-rw-r--r--plat/common/aarch64/plat_common.c43
-rw-r--r--plat/common/aarch64/plat_ehf.c37
-rw-r--r--plat/common/aarch64/platform_mp_stack.S10
-rw-r--r--plat/common/plat_bl1_common.c31
-rw-r--r--plat/common/plat_bl_common.c50
-rw-r--r--plat/common/plat_psci_common.c13
-rw-r--r--plat/common/plat_spmd_manifest.c192
-rw-r--r--plat/hisilicon/hikey/aarch64/hikey_helpers.S6
-rw-r--r--plat/hisilicon/hikey/hikey_bl1_setup.c2
-rw-r--r--plat/hisilicon/hikey/hikey_bl2_setup.c2
-rw-r--r--plat/hisilicon/hikey/hikey_bl31_setup.c2
-rw-r--r--plat/hisilicon/hikey/platform.mk10
-rw-r--r--plat/hisilicon/hikey960/aarch64/hikey960_helpers.S6
-rw-r--r--plat/hisilicon/hikey960/hikey960_bl1_setup.c2
-rw-r--r--plat/hisilicon/hikey960/hikey960_bl2_setup.c2
-rw-r--r--plat/hisilicon/hikey960/hikey960_bl31_setup.c3
-rw-r--r--plat/hisilicon/hikey960/hikey960_bl_common.c7
-rw-r--r--plat/hisilicon/hikey960/hikey960_pm.c12
-rw-r--r--plat/hisilicon/hikey960/include/hi3660.h7
-rw-r--r--plat/hisilicon/hikey960/platform.mk15
-rw-r--r--plat/hisilicon/poplar/aarch64/poplar_helpers.S6
-rw-r--r--plat/hisilicon/poplar/bl1_plat_setup.c2
-rw-r--r--plat/hisilicon/poplar/bl2_plat_setup.c2
-rw-r--r--plat/hisilicon/poplar/bl31_plat_setup.c2
-rw-r--r--plat/imx/common/aarch32/imx_uart_console.S8
-rw-r--r--plat/imx/common/imx_ehf.c22
-rw-r--r--plat/imx/common/imx_sdei.c32
-rw-r--r--plat/imx/common/imx_sip_handler.c36
-rw-r--r--plat/imx/common/imx_sip_svc.c3
-rw-r--r--plat/imx/common/imx_uart_console.S9
-rw-r--r--plat/imx/common/include/imx8_iomux.h28
-rw-r--r--plat/imx/common/include/imx8_lpuart.h7
-rw-r--r--plat/imx/common/include/imx_sip_svc.h5
-rw-r--r--plat/imx/common/include/imx_uart.h7
-rw-r--r--plat/imx/common/lpuart_console.S9
-rw-r--r--plat/imx/common/plat_imx8_gic.c4
-rw-r--r--plat/imx/imx7/common/imx7.mk7
-rw-r--r--plat/imx/imx7/common/imx7_bl2_el3_common.c4
-rw-r--r--plat/imx/imx8m/gpc_common.c27
-rw-r--r--plat/imx/imx8m/imx8m_psci_common.c2
-rw-r--r--plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c4
-rw-r--r--plat/imx/imx8m/imx8mm/include/gpc_reg.h129
-rw-r--r--plat/imx/imx8m/imx8mm/include/platform_def.h6
-rw-r--r--plat/imx/imx8m/imx8mm/platform.mk19
-rw-r--r--plat/imx/imx8m/imx8mn/gpc.c94
-rw-r--r--plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c186
-rw-r--r--plat/imx/imx8m/imx8mn/imx8mn_psci.c44
-rw-r--r--plat/imx/imx8m/imx8mn/include/gpc_reg.h111
-rw-r--r--plat/imx/imx8m/imx8mn/include/platform_def.h135
-rw-r--r--plat/imx/imx8m/imx8mn/platform.mk56
-rw-r--r--plat/imx/imx8m/imx8mp/gpc.c379
-rw-r--r--plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c187
-rw-r--r--plat/imx/imx8m/imx8mp/imx8mp_psci.c44
-rw-r--r--plat/imx/imx8m/imx8mp/include/gpc_reg.h151
-rw-r--r--plat/imx/imx8m/imx8mp/include/platform_def.h154
-rw-r--r--plat/imx/imx8m/imx8mp/platform.mk56
-rw-r--r--plat/imx/imx8m/imx8mq/gpc.c9
-rw-r--r--plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c2
-rw-r--r--plat/imx/imx8m/imx8mq/include/gpc_reg.h89
-rw-r--r--plat/imx/imx8m/imx8mq/platform.mk11
-rw-r--r--plat/imx/imx8m/include/gpc.h96
-rw-r--r--plat/imx/imx8m/include/imx_rdc.h6
-rw-r--r--plat/imx/imx8qm/imx8qm_bl31_setup.c35
-rw-r--r--plat/imx/imx8qm/include/platform_def.h13
-rw-r--r--plat/imx/imx8qm/platform.mk17
-rw-r--r--plat/imx/imx8qx/imx8qx_bl31_setup.c47
-rw-r--r--plat/imx/imx8qx/include/platform_def.h12
-rw-r--r--plat/imx/imx8qx/platform.mk17
-rw-r--r--plat/intel/soc/agilex/bl2_plat_setup.c13
-rw-r--r--plat/intel/soc/agilex/bl31_plat_setup.c45
-rw-r--r--plat/intel/soc/agilex/include/agilex_clock_manager.h1
-rw-r--r--plat/intel/soc/agilex/include/agilex_mmc.h7
-rw-r--r--plat/intel/soc/agilex/include/socfpga_plat_def.h1
-rw-r--r--plat/intel/soc/agilex/platform.mk22
-rw-r--r--plat/intel/soc/agilex/soc/agilex_clock_manager.c76
-rw-r--r--plat/intel/soc/agilex/soc/agilex_mmc.c19
-rw-r--r--plat/intel/soc/agilex/soc/agilex_pinmux.c8
-rw-r--r--plat/intel/soc/common/drivers/ccu/ncore_ccu.c15
-rw-r--r--plat/intel/soc/common/include/platform_def.h14
-rw-r--r--plat/intel/soc/common/include/socfpga_emac.h24
-rw-r--r--plat/intel/soc/common/include/socfpga_handoff.h1
-rw-r--r--plat/intel/soc/common/include/socfpga_mailbox.h161
-rw-r--r--plat/intel/soc/common/include/socfpga_sip_svc.h36
-rw-r--r--plat/intel/soc/common/include/socfpga_system_manager.h8
-rw-r--r--plat/intel/soc/common/soc/socfpga_emac.c38
-rw-r--r--plat/intel/soc/common/soc/socfpga_mailbox.c488
-rw-r--r--plat/intel/soc/common/socfpga_delay_timer.c4
-rw-r--r--plat/intel/soc/common/socfpga_psci.c12
-rw-r--r--plat/intel/soc/common/socfpga_sip_svc.c181
-rw-r--r--plat/intel/soc/stratix10/bl2_plat_setup.c11
-rw-r--r--plat/intel/soc/stratix10/bl31_plat_setup.c13
-rw-r--r--plat/intel/soc/stratix10/include/socfpga_plat_def.h3
-rw-r--r--plat/intel/soc/stratix10/platform.mk21
-rw-r--r--plat/layerscape/common/aarch64/ls_console.S27
-rw-r--r--plat/layerscape/common/include/ls_16550.h9
-rw-r--r--plat/layerscape/common/ls_bl1_setup.c2
-rw-r--r--plat/layerscape/common/ls_bl2_setup.c2
-rw-r--r--plat/layerscape/common/ls_bl31_setup.c4
-rw-r--r--plat/layerscape/common/tsp/ls_tsp_setup.c2
-rw-r--r--plat/marvell/a3700/common/a3700_common.mk171
-rw-r--r--plat/marvell/a8k/common/aarch64/plat_arch_config.c45
-rw-r--r--plat/marvell/armada/a3k/a3700/board/pm_src.c (renamed from plat/marvell/a3700/a3700/board/pm_src.c)0
-rw-r--r--plat/marvell/armada/a3k/a3700/mvebu_def.h (renamed from plat/marvell/a3700/a3700/mvebu_def.h)0
-rw-r--r--plat/marvell/armada/a3k/a3700/plat_bl31_setup.c (renamed from plat/marvell/a3700/a3700/plat_bl31_setup.c)0
-rw-r--r--plat/marvell/armada/a3k/a3700/platform.mk (renamed from plat/marvell/a3700/a3700/platform.mk)4
-rw-r--r--plat/marvell/armada/a3k/common/a3700_common.mk233
-rw-r--r--plat/marvell/armada/a3k/common/a3700_ea.c (renamed from plat/marvell/a3700/common/a3700_ea.c)0
-rw-r--r--plat/marvell/armada/a3k/common/a3700_sip_svc.c (renamed from plat/marvell/a3700/common/a3700_sip_svc.c)0
-rw-r--r--plat/marvell/armada/a3k/common/aarch64/a3700_common.c (renamed from plat/marvell/a3700/common/aarch64/a3700_common.c)0
-rw-r--r--plat/marvell/armada/a3k/common/aarch64/plat_helpers.S (renamed from plat/marvell/a3700/common/aarch64/plat_helpers.S)0
-rw-r--r--plat/marvell/armada/a3k/common/cm3_system_reset.c62
-rw-r--r--plat/marvell/armada/a3k/common/dram_win.c (renamed from plat/marvell/a3700/common/dram_win.c)56
-rw-r--r--plat/marvell/armada/a3k/common/include/a3700_plat_def.h (renamed from plat/marvell/a3700/common/include/a3700_plat_def.h)18
-rw-r--r--plat/marvell/armada/a3k/common/include/a3700_pm.h (renamed from plat/marvell/a3700/common/include/a3700_pm.h)4
-rw-r--r--plat/marvell/armada/a3k/common/include/ddr_info.h (renamed from plat/marvell/a3700/common/include/ddr_info.h)0
-rw-r--r--plat/marvell/armada/a3k/common/include/dram_win.h (renamed from plat/marvell/a3700/common/include/dram_win.h)0
-rw-r--r--plat/marvell/armada/a3k/common/include/io_addr_dec.h (renamed from plat/marvell/a3700/common/include/io_addr_dec.h)0
-rw-r--r--plat/marvell/armada/a3k/common/include/plat_macros.S (renamed from plat/marvell/a3700/common/include/plat_macros.S)0
-rw-r--r--plat/marvell/armada/a3k/common/include/platform_def.h (renamed from plat/marvell/a3700/common/include/platform_def.h)37
-rw-r--r--plat/marvell/armada/a3k/common/io_addr_dec.c (renamed from plat/marvell/a3700/common/io_addr_dec.c)0
-rw-r--r--plat/marvell/armada/a3k/common/marvell_plat_config.c (renamed from plat/marvell/a3700/common/marvell_plat_config.c)0
-rw-r--r--plat/marvell/armada/a3k/common/plat_cci.c35
-rw-r--r--plat/marvell/armada/a3k/common/plat_pm.c (renamed from plat/marvell/a3700/common/plat_pm.c)10
-rw-r--r--plat/marvell/armada/a8k/a70x0/board/dram_port.c (renamed from plat/marvell/a8k/a70x0/board/dram_port.c)1
-rw-r--r--plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c (renamed from plat/marvell/a8k/a70x0/board/marvell_plat_config.c)6
-rw-r--r--plat/marvell/armada/a8k/a70x0/mvebu_def.h (renamed from plat/marvell/a8k/a70x0/mvebu_def.h)0
-rw-r--r--plat/marvell/armada/a8k/a70x0/platform.mk (renamed from plat/marvell/a8k/a70x0_amc/platform.mk)5
-rw-r--r--plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c (renamed from plat/marvell/a8k/a70x0_amc/board/dram_port.c)1
-rw-r--r--plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c (renamed from plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c)6
-rw-r--r--plat/marvell/armada/a8k/a70x0_amc/mvebu_def.h (renamed from plat/marvell/a8k/a70x0_amc/mvebu_def.h)0
-rw-r--r--plat/marvell/armada/a8k/a70x0_amc/platform.mk (renamed from plat/marvell/a8k/a70x0/platform.mk)5
-rw-r--r--plat/marvell/armada/a8k/a80x0/board/dram_port.c (renamed from plat/marvell/a8k/a80x0/board/dram_port.c)5
-rw-r--r--plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c (renamed from plat/marvell/a8k/a80x0/board/marvell_plat_config.c)6
-rw-r--r--plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h (renamed from plat/marvell/a8k/a80x0/board/phy-porting-layer.h)11
-rw-r--r--plat/marvell/armada/a8k/a80x0/mvebu_def.h (renamed from plat/marvell/a8k/a80x0/mvebu_def.h)0
-rw-r--r--plat/marvell/armada/a8k/a80x0/platform.mk (renamed from plat/marvell/a8k/a80x0/platform.mk)6
-rw-r--r--plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c (renamed from plat/marvell/a8k/a80x0_mcbin/board/dram_port.c)1
-rw-r--r--plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c200
-rw-r--r--plat/marvell/armada/a8k/a80x0_mcbin/mvebu_def.h (renamed from plat/marvell/a8k/a80x0_mcbin/mvebu_def.h)0
-rw-r--r--plat/marvell/armada/a8k/a80x0_mcbin/platform.mk (renamed from plat/marvell/a8k/a80x0_mcbin/platform.mk)5
-rw-r--r--plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c140
-rw-r--r--plat/marvell/armada/a8k/a80x0_puzzle/board/marvell_plat_config.c (renamed from plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c)3
-rw-r--r--plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c59
-rw-r--r--plat/marvell/armada/a8k/a80x0_puzzle/mvebu_def.h17
-rw-r--r--plat/marvell/armada/a8k/a80x0_puzzle/platform.mk20
-rw-r--r--plat/marvell/armada/a8k/common/a8k_common.mk (renamed from plat/marvell/a8k/common/a8k_common.mk)80
-rw-r--r--plat/marvell/armada/a8k/common/aarch64/a8k_common.c (renamed from plat/marvell/a8k/common/aarch64/a8k_common.c)12
-rw-r--r--plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c95
-rw-r--r--plat/marvell/armada/a8k/common/aarch64/plat_helpers.S (renamed from plat/marvell/a8k/common/aarch64/plat_helpers.S)0
-rw-r--r--plat/marvell/armada/a8k/common/ble/ble.ld.S (renamed from plat/marvell/a8k/common/ble/ble.ld.S)0
-rw-r--r--plat/marvell/armada/a8k/common/ble/ble.mk (renamed from plat/marvell/a8k/common/ble/ble.mk)12
-rw-r--r--plat/marvell/armada/a8k/common/ble/ble_main.c (renamed from plat/marvell/a8k/common/ble/ble_main.c)0
-rw-r--r--plat/marvell/armada/a8k/common/ble/ble_mem.S (renamed from plat/marvell/a8k/common/ble/ble_mem.S)0
-rw-r--r--plat/marvell/armada/a8k/common/include/a8k_plat_def.h (renamed from plat/marvell/a8k/common/include/a8k_plat_def.h)0
-rw-r--r--plat/marvell/armada/a8k/common/include/ddr_info.h (renamed from plat/marvell/a8k/common/include/ddr_info.h)0
-rw-r--r--plat/marvell/armada/a8k/common/include/mentor_i2c_plat.h (renamed from plat/marvell/a8k/common/include/mentor_i2c_plat.h)0
-rw-r--r--plat/marvell/armada/a8k/common/include/plat_macros.S (renamed from plat/marvell/a8k/common/include/plat_macros.S)0
-rw-r--r--plat/marvell/armada/a8k/common/include/platform_def.h (renamed from plat/marvell/a8k/common/include/platform_def.h)31
-rw-r--r--plat/marvell/armada/a8k/common/mss/mss_a8k.mk (renamed from plat/marvell/a8k/common/mss/mss_a8k.mk)5
-rw-r--r--plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c (renamed from plat/marvell/a8k/common/mss/mss_bl2_setup.c)29
-rw-r--r--plat/marvell/armada/a8k/common/mss/mss_pm_ipc.c (renamed from plat/marvell/a8k/common/mss/mss_pm_ipc.c)0
-rw-r--r--plat/marvell/armada/a8k/common/mss/mss_pm_ipc.h (renamed from plat/marvell/a8k/common/mss/mss_pm_ipc.h)0
-rw-r--r--plat/marvell/armada/a8k/common/plat_bl1_setup.c (renamed from plat/marvell/a8k/common/plat_bl1_setup.c)0
-rw-r--r--plat/marvell/armada/a8k/common/plat_bl31_setup.c (renamed from plat/marvell/a8k/common/plat_bl31_setup.c)9
-rw-r--r--plat/marvell/armada/a8k/common/plat_ble_setup.c (renamed from plat/marvell/a8k/common/plat_ble_setup.c)100
-rw-r--r--plat/marvell/armada/a8k/common/plat_pm.c (renamed from plat/marvell/a8k/common/plat_pm.c)0
-rw-r--r--plat/marvell/armada/a8k/common/plat_pm_trace.c (renamed from plat/marvell/a8k/common/plat_pm_trace.c)0
-rw-r--r--plat/marvell/armada/a8k/common/plat_thermal.c (renamed from plat/marvell/a8k/common/plat_thermal.c)0
-rw-r--r--plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c (renamed from plat/marvell/common/aarch64/marvell_bl2_mem_params_desc.c)39
-rw-r--r--plat/marvell/armada/common/aarch64/marvell_common.c (renamed from plat/marvell/common/aarch64/marvell_common.c)0
-rw-r--r--plat/marvell/armada/common/aarch64/marvell_helpers.S (renamed from plat/marvell/common/aarch64/marvell_helpers.S)7
-rw-r--r--plat/marvell/armada/common/marvell_bl1_setup.c (renamed from plat/marvell/common/marvell_bl1_setup.c)0
-rw-r--r--plat/marvell/armada/common/marvell_bl2_setup.c (renamed from plat/marvell/common/marvell_bl2_setup.c)23
-rw-r--r--plat/marvell/armada/common/marvell_bl31_setup.c (renamed from plat/marvell/common/marvell_bl31_setup.c)0
-rw-r--r--plat/marvell/armada/common/marvell_cci.c (renamed from plat/marvell/common/marvell_cci.c)0
-rw-r--r--plat/marvell/armada/common/marvell_common.mk (renamed from plat/marvell/common/marvell_common.mk)41
-rw-r--r--plat/marvell/armada/common/marvell_console.c (renamed from plat/marvell/common/marvell_console.c)53
-rw-r--r--plat/marvell/armada/common/marvell_ddr_info.c (renamed from plat/marvell/common/marvell_ddr_info.c)0
-rw-r--r--plat/marvell/armada/common/marvell_gicv2.c (renamed from plat/marvell/common/marvell_gicv2.c)0
-rw-r--r--plat/marvell/armada/common/marvell_gicv3.c (renamed from plat/marvell/common/marvell_gicv3.c)0
-rw-r--r--plat/marvell/armada/common/marvell_image_load.c (renamed from plat/marvell/common/marvell_image_load.c)0
-rw-r--r--plat/marvell/armada/common/marvell_io_storage.c (renamed from plat/marvell/common/marvell_io_storage.c)19
-rw-r--r--plat/marvell/armada/common/marvell_pm.c (renamed from plat/marvell/common/marvell_pm.c)0
-rw-r--r--plat/marvell/armada/common/marvell_topology.c (renamed from plat/marvell/common/marvell_topology.c)0
-rw-r--r--plat/marvell/armada/common/mrvl_sip_svc.c (renamed from plat/marvell/common/mrvl_sip_svc.c)0
-rw-r--r--plat/marvell/armada/common/mss/mss_common.mk (renamed from plat/marvell/common/mss/mss_common.mk)4
-rw-r--r--plat/marvell/armada/common/mss/mss_ipc_drv.c (renamed from plat/marvell/common/mss/mss_ipc_drv.c)0
-rw-r--r--plat/marvell/armada/common/mss/mss_ipc_drv.h (renamed from plat/marvell/common/mss/mss_ipc_drv.h)0
-rw-r--r--plat/marvell/armada/common/mss/mss_mem.h (renamed from plat/marvell/common/mss/mss_mem.h)0
-rw-r--r--plat/marvell/armada/common/mss/mss_scp_bl2_format.h (renamed from plat/marvell/common/mss/mss_scp_bl2_format.h)4
-rw-r--r--plat/marvell/armada/common/mss/mss_scp_bootloader.c (renamed from plat/marvell/common/mss/mss_scp_bootloader.c)21
-rw-r--r--plat/marvell/armada/common/mss/mss_scp_bootloader.h (renamed from plat/marvell/common/mss/mss_scp_bootloader.h)0
-rw-r--r--plat/marvell/armada/common/plat_delay_timer.c (renamed from plat/marvell/common/plat_delay_timer.c)0
-rw-r--r--plat/marvell/marvell.mk39
-rw-r--r--plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c158
-rw-r--r--plat/marvell/octeontx/otx2/t91/t9130/board/marvell_plat_config.c188
-rw-r--r--plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h145
-rw-r--r--plat/marvell/octeontx/otx2/t91/t9130/mvebu_def.h25
-rw-r--r--plat/marvell/octeontx/otx2/t91/t9130/platform.mk20
-rw-r--r--plat/marvell/version.mk2
-rw-r--r--plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c125
-rw-r--r--plat/mediatek/common/drivers/uart/8250_console.S7
-rw-r--r--plat/mediatek/common/drivers/uart/uart.c (renamed from plat/mediatek/mt8183/drivers/uart/uart.c)11
-rw-r--r--plat/mediatek/common/mtk_plat_common.c32
-rw-r--r--plat/mediatek/common/mtk_plat_common.h3
-rw-r--r--plat/mediatek/mt6795/aarch64/plat_helpers.S6
-rw-r--r--plat/mediatek/mt6795/bl31.ld.S84
-rw-r--r--plat/mediatek/mt8173/bl31_plat_setup.c2
-rw-r--r--plat/mediatek/mt8173/drivers/wdt/wdt.c115
-rw-r--r--plat/mediatek/mt8173/drivers/wdt/wdt.h20
-rw-r--r--plat/mediatek/mt8173/include/mt8173_def.h12
-rw-r--r--plat/mediatek/mt8173/include/plat_sip_calls.h3
-rw-r--r--plat/mediatek/mt8173/include/platform_def.h2
-rw-r--r--plat/mediatek/mt8173/plat_pm.c9
-rw-r--r--plat/mediatek/mt8173/plat_sip_calls.c4
-rw-r--r--plat/mediatek/mt8173/platform.mk2
-rw-r--r--plat/mediatek/mt8183/bl31_plat_setup.c5
-rw-r--r--plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c10
-rw-r--r--plat/mediatek/mt8183/drivers/timer/mt_timer.c29
-rw-r--r--plat/mediatek/mt8183/drivers/timer/mt_timer.h20
-rw-r--r--plat/mediatek/mt8183/drivers/uart/uart.h2
-rw-r--r--plat/mediatek/mt8183/include/platform_def.h2
-rw-r--r--plat/mediatek/mt8183/platform.mk13
-rw-r--r--plat/mediatek/mt8192/aarch64/plat_helpers.S49
-rw-r--r--plat/mediatek/mt8192/aarch64/platform_common.c46
-rw-r--r--plat/mediatek/mt8192/bl31_plat_setup.c115
-rw-r--r--plat/mediatek/mt8192/drivers/dcm/mtk_dcm.c63
-rw-r--r--plat/mediatek/mt8192/drivers/dcm/mtk_dcm.h14
-rw-r--r--plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.c562
-rw-r--r--plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.h68
-rw-r--r--plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c122
-rw-r--r--plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.h102
-rw-r--r--plat/mediatek/mt8192/drivers/gpio/mtgpio.c340
-rw-r--r--plat/mediatek/mt8192/drivers/gpio/mtgpio.h384
-rw-r--r--plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c123
-rw-r--r--plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.c269
-rw-r--r--plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.h106
-rw-r--r--plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c148
-rw-r--r--plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.h12
-rw-r--r--plat/mediatek/mt8192/drivers/pmic/pmic.c13
-rw-r--r--plat/mediatek/mt8192/drivers/pmic/pmic.h15
-rw-r--r--plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h76
-rw-r--r--plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_common.h48
-rw-r--r--plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c84
-rw-r--r--plat/mediatek/mt8192/drivers/rtc/rtc.c148
-rw-r--r--plat/mediatek/mt8192/drivers/rtc/rtc.h197
-rw-r--r--plat/mediatek/mt8192/drivers/spmc/mtspmc.c177
-rw-r--r--plat/mediatek/mt8192/drivers/spmc/mtspmc.h31
-rw-r--r--plat/mediatek/mt8192/drivers/spmc/mtspmc_private.h184
-rw-r--r--plat/mediatek/mt8192/drivers/timer/mt_timer.c38
-rw-r--r--plat/mediatek/mt8192/drivers/timer/mt_timer.h35
-rw-r--r--plat/mediatek/mt8192/drivers/uart/uart.h100
-rw-r--r--plat/mediatek/mt8192/include/mcucfg.h257
-rw-r--r--plat/mediatek/mt8192/include/mt_gic_v3.h27
-rw-r--r--plat/mediatek/mt8192/include/plat_helpers.h12
-rw-r--r--plat/mediatek/mt8192/include/plat_macros.S38
-rw-r--r--plat/mediatek/mt8192/include/plat_mt_cirq.h128
-rw-r--r--plat/mediatek/mt8192/include/plat_mtk_lpm.h48
-rw-r--r--plat/mediatek/mt8192/include/plat_pm.h38
-rw-r--r--plat/mediatek/mt8192/include/plat_private.h18
-rw-r--r--plat/mediatek/mt8192/include/plat_sip_calls.h15
-rw-r--r--plat/mediatek/mt8192/include/platform_def.h126
-rw-r--r--plat/mediatek/mt8192/plat_mt_cirq.c552
-rw-r--r--plat/mediatek/mt8192/plat_mt_gic.c196
-rw-r--r--plat/mediatek/mt8192/plat_pm.c397
-rw-r--r--plat/mediatek/mt8192/plat_sip_calls.c27
-rw-r--r--plat/mediatek/mt8192/plat_topology.c75
-rw-r--r--plat/mediatek/mt8192/platform.mk83
-rw-r--r--plat/nvidia/tegra/common/aarch64/tegra_helpers.S107
-rw-r--r--plat/nvidia/tegra/common/drivers/smmu/smmu.c177
-rw-r--r--plat/nvidia/tegra/common/tegra_bl31_setup.c172
-rw-r--r--plat/nvidia/tegra/common/tegra_common.mk62
-rw-r--r--plat/nvidia/tegra/common/tegra_delay_timer.c44
-rw-r--r--plat/nvidia/tegra/common/tegra_fiq_glue.c45
-rw-r--r--plat/nvidia/tegra/common/tegra_gicv2.c9
-rw-r--r--plat/nvidia/tegra/common/tegra_gicv3.c79
-rw-r--r--plat/nvidia/tegra/common/tegra_platform.c56
-rw-r--r--plat/nvidia/tegra/common/tegra_pm.c172
-rw-r--r--plat/nvidia/tegra/common/tegra_sdei.c56
-rw-r--r--plat/nvidia/tegra/common/tegra_sip_calls.c33
-rw-r--r--plat/nvidia/tegra/common/tegra_stack_protector.c28
-rw-r--r--plat/nvidia/tegra/common/tegra_topology.c48
-rw-r--r--plat/nvidia/tegra/drivers/bpmp/bpmp.c (renamed from plat/nvidia/tegra/common/drivers/bpmp/bpmp.c)0
-rw-r--r--plat/nvidia/tegra/drivers/bpmp_ipc/intf.c (renamed from plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c)59
-rw-r--r--plat/nvidia/tegra/drivers/bpmp_ipc/intf.h (renamed from plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h)30
-rw-r--r--plat/nvidia/tegra/drivers/bpmp_ipc/ivc.c (renamed from plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c)1
-rw-r--r--plat/nvidia/tegra/drivers/bpmp_ipc/ivc.h (renamed from plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h)17
-rw-r--r--plat/nvidia/tegra/drivers/flowctrl/flowctrl.c (renamed from plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c)0
-rw-r--r--plat/nvidia/tegra/drivers/gpcdma/gpcdma.c (renamed from plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c)0
-rw-r--r--plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c (renamed from plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c)20
-rw-r--r--plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c (renamed from plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c)282
-rw-r--r--plat/nvidia/tegra/drivers/pmc/pmc.c (renamed from plat/nvidia/tegra/common/drivers/pmc/pmc.c)0
-rw-r--r--plat/nvidia/tegra/drivers/smmu/smmu.c121
-rw-r--r--plat/nvidia/tegra/drivers/spe/shared_console.S (renamed from plat/nvidia/tegra/common/drivers/spe/shared_console.S)78
-rw-r--r--plat/nvidia/tegra/include/drivers/bpmp_ipc.h5
-rw-r--r--plat/nvidia/tegra/include/drivers/flowctrl.h3
-rw-r--r--plat/nvidia/tegra/include/drivers/mce.h3
-rw-r--r--plat/nvidia/tegra/include/drivers/memctrl.h2
-rw-r--r--plat/nvidia/tegra/include/drivers/memctrl_v2.h155
-rw-r--r--plat/nvidia/tegra/include/drivers/pmc.h33
-rw-r--r--plat/nvidia/tegra/include/drivers/security_engine.h3
-rw-r--r--plat/nvidia/tegra/include/drivers/smmu.h843
-rw-r--r--plat/nvidia/tegra/include/drivers/spe.h7
-rw-r--r--plat/nvidia/tegra/include/plat_macros.S4
-rw-r--r--plat/nvidia/tegra/include/platform_def.h61
-rw-r--r--plat/nvidia/tegra/include/t132/tegra_def.h14
-rw-r--r--plat/nvidia/tegra/include/t186/tegra186_private.h8
-rw-r--r--plat/nvidia/tegra/include/t186/tegra_def.h49
-rw-r--r--plat/nvidia/tegra/include/t186/tegra_mc_def.h115
-rw-r--r--plat/nvidia/tegra/include/t194/tegra194_private.h2
-rw-r--r--plat/nvidia/tegra/include/t194/tegra194_ras_private.h263
-rw-r--r--plat/nvidia/tegra/include/t194/tegra_def.h61
-rw-r--r--plat/nvidia/tegra/include/t194/tegra_mc_def.h685
-rw-r--r--plat/nvidia/tegra/include/t210/tegra_def.h22
-rw-r--r--plat/nvidia/tegra/include/tegra_platform.h9
-rw-r--r--plat/nvidia/tegra/include/tegra_private.h39
-rw-r--r--plat/nvidia/tegra/lib/debug/profiler.c (renamed from plat/nvidia/tegra/common/lib/debug/profiler.c)0
-rw-r--r--plat/nvidia/tegra/platform.mk36
-rw-r--r--plat/nvidia/tegra/soc/t132/plat_psci_handlers.c52
-rw-r--r--plat/nvidia/tegra/soc/t132/plat_setup.c82
-rw-r--r--plat/nvidia/tegra/soc/t132/platform_t132.mk12
-rw-r--r--plat/nvidia/tegra/soc/t186/drivers/mce/mce.c9
-rw-r--r--plat/nvidia/tegra/soc/t186/drivers/se/se.c277
-rw-r--r--plat/nvidia/tegra/soc/t186/drivers/se/se_private.h100
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_memctrl.c390
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_psci_handlers.c76
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_secondary.c31
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_setup.c126
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_smmu.c166
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_trampoline.S132
-rw-r--r--plat/nvidia/tegra/soc/t186/platform_t186.mk27
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h4
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/include/se.h2
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h495
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/mce/mce.c36
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c38
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/se/se.c296
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/se/se_private.h86
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_memctrl.c694
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_psci_handlers.c202
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_ras.c501
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_secondary.c25
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_setup.c151
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_sip_calls.c72
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_smmu.c271
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_trampoline.S28
-rw-r--r--plat/nvidia/tegra/soc/t194/platform_t194.mk48
-rw-r--r--plat/nvidia/tegra/soc/t210/drivers/se/se_private.h6
-rw-r--r--plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c119
-rw-r--r--plat/nvidia/tegra/soc/t210/plat_psci_handlers.c60
-rw-r--r--plat/nvidia/tegra/soc/t210/plat_setup.c93
-rw-r--r--plat/nvidia/tegra/soc/t210/plat_sip_calls.c40
-rw-r--r--plat/nvidia/tegra/soc/t210/platform_t210.mk23
-rw-r--r--plat/nxp/common/plat_make_helper/plat_build_macros.mk11
-rw-r--r--plat/qemu/common/aarch32/plat_helpers.S6
-rw-r--r--plat/qemu/common/aarch64/plat_helpers.S9
-rw-r--r--plat/qemu/common/qemu_common.c20
-rw-r--r--plat/qemu/common/qemu_console.c4
-rw-r--r--plat/qemu/common/qemu_io_storage.c71
-rw-r--r--plat/qemu/common/qemu_spm.c138
-rw-r--r--plat/qemu/common/qemu_stack_protector.c16
-rw-r--r--plat/qemu/qemu/include/platform_def.h14
-rw-r--r--plat/qemu/qemu/platform.mk33
-rw-r--r--plat/qemu/qemu_sbsa/include/platform_def.h183
-rw-r--r--plat/qemu/qemu_sbsa/platform.mk34
-rw-r--r--plat/qemu/qemu_sbsa/sbsa_pm.c237
-rw-r--r--plat/qemu/qemu_sbsa/sbsa_private.h17
-rw-r--r--plat/qemu/qemu_sbsa/sbsa_topology.c63
-rw-r--r--plat/qti/common/inc/aarch64/plat_macros.S106
-rw-r--r--plat/qti/common/inc/qti_board_def.h37
-rw-r--r--plat/qti/common/inc/qti_cpu.h16
-rw-r--r--plat/qti/common/inc/qti_interrupt_svc.h12
-rw-r--r--plat/qti/common/inc/qti_plat.h56
-rw-r--r--plat/qti/common/inc/qti_rng.h14
-rw-r--r--plat/qti/common/inc/qti_uart_console.h19
-rw-r--r--plat/qti/common/inc/spmi_arb.h23
-rw-r--r--plat/qti/common/src/aarch64/qti_helpers.S88
-rw-r--r--plat/qti/common/src/aarch64/qti_kryo4_gold.S83
-rw-r--r--plat/qti/common/src/aarch64/qti_kryo4_silver.S79
-rw-r--r--plat/qti/common/src/aarch64/qti_uart_console.S102
-rw-r--r--plat/qti/common/src/pm8998.c43
-rw-r--r--plat/qti/common/src/qti_bl31_setup.c155
-rw-r--r--plat/qti/common/src/qti_common.c194
-rw-r--r--plat/qti/common/src/qti_gic_v3.c159
-rw-r--r--plat/qti/common/src/qti_interrupt_svc.c65
-rw-r--r--plat/qti/common/src/qti_pm.c287
-rw-r--r--plat/qti/common/src/qti_rng.c53
-rw-r--r--plat/qti/common/src/qti_stack_protector.c26
-rw-r--r--plat/qti/common/src/qti_syscall.c357
-rw-r--r--plat/qti/common/src/qti_topology.c48
-rw-r--r--plat/qti/common/src/spmi_arb.c113
-rw-r--r--plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h59
-rw-r--r--plat/qti/qtiseclib/inc/qtiseclib_defs.h104
-rw-r--r--plat/qti/qtiseclib/inc/qtiseclib_interface.h83
-rw-r--r--plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h35
-rw-r--r--plat/qti/qtiseclib/src/qtiseclib_cb_interface.c207
-rw-r--r--plat/qti/qtiseclib/src/qtiseclib_interface_stub.c114
-rw-r--r--plat/qti/sc7180/inc/platform_def.h194
-rw-r--r--plat/qti/sc7180/inc/qti_rng_io.h15
-rw-r--r--plat/qti/sc7180/inc/qti_secure_io_cfg.h30
-rw-r--r--plat/qti/sc7180/platform.mk119
-rw-r--r--plat/renesas/common/aarch64/plat_helpers.S (renamed from plat/renesas/rcar/aarch64/plat_helpers.S)2
-rw-r--r--plat/renesas/common/aarch64/platform_common.c (renamed from plat/renesas/rcar/aarch64/platform_common.c)0
-rw-r--r--plat/renesas/common/bl2_cpg_init.c (renamed from plat/renesas/rcar/bl2_cpg_init.c)22
-rw-r--r--plat/renesas/common/bl2_interrupt_error.c (renamed from plat/renesas/rcar/bl2_interrupt_error.c)0
-rw-r--r--plat/renesas/common/bl2_plat_mem_params_desc.c (renamed from plat/renesas/rcar/bl2_plat_mem_params_desc.c)0
-rw-r--r--plat/renesas/common/bl2_secure_setting.c362
-rw-r--r--plat/renesas/common/bl31_plat_setup.c (renamed from plat/renesas/rcar/bl31_plat_setup.c)27
-rw-r--r--plat/renesas/common/common.mk132
-rw-r--r--plat/renesas/common/include/plat.ld.S (renamed from plat/renesas/rcar/include/plat.ld.S)0
-rw-r--r--plat/renesas/common/include/plat_macros.S (renamed from plat/renesas/rcar/include/plat_macros.S)0
-rw-r--r--plat/renesas/common/include/platform_def.h (renamed from plat/renesas/rcar/include/platform_def.h)42
-rw-r--r--plat/renesas/common/include/rcar_def.h (renamed from plat/renesas/rcar/include/rcar_def.h)208
-rw-r--r--plat/renesas/common/include/rcar_private.h (renamed from plat/renesas/rcar/include/rcar_private.h)19
-rw-r--r--plat/renesas/common/include/rcar_version.h (renamed from plat/renesas/rcar/include/rcar_version.h)6
-rw-r--r--plat/renesas/common/include/registers/axi_registers.h (renamed from plat/renesas/rcar/include/registers/axi_registers.h)0
-rw-r--r--plat/renesas/common/include/registers/cpg_registers.h (renamed from plat/renesas/rcar/include/registers/cpg_registers.h)0
-rw-r--r--plat/renesas/common/include/registers/lifec_registers.h144
-rw-r--r--plat/renesas/common/plat_image_load.c (renamed from plat/renesas/rcar/plat_image_load.c)0
-rw-r--r--plat/renesas/common/plat_pm.c (renamed from plat/renesas/rcar/plat_pm.c)25
-rw-r--r--plat/renesas/common/plat_storage.c (renamed from plat/renesas/rcar/plat_storage.c)24
-rw-r--r--plat/renesas/common/plat_topology.c (renamed from plat/renesas/rcar/plat_topology.c)0
-rw-r--r--plat/renesas/common/rcar_common.c (renamed from plat/renesas/rcar/rcar_common.c)8
-rw-r--r--plat/renesas/rcar/bl2_plat_setup.c31
-rw-r--r--plat/renesas/rcar/bl2_secure_setting.c352
-rw-r--r--plat/renesas/rcar/include/registers/lifec_registers.h144
-rw-r--r--plat/renesas/rcar/platform.mk149
-rw-r--r--plat/renesas/rzg/bl2_plat_setup.c909
-rw-r--r--plat/renesas/rzg/platform.mk222
-rw-r--r--plat/rockchip/common/bl31_plat_setup.c2
-rw-r--r--plat/rockchip/common/drivers/parameter/ddr_parameter.h4
-rw-r--r--plat/rockchip/common/params_setup.c22
-rw-r--r--plat/rockchip/common/rockchip_stack_protector.c24
-rw-r--r--plat/rockchip/common/sp_min_plat_setup.c4
-rw-r--r--plat/rockchip/px30/platform.mk5
-rw-r--r--plat/rockchip/rk3328/platform.mk4
-rw-r--r--plat/rockchip/rk3368/include/platform_def.h4
-rw-r--r--plat/rockchip/rk3368/platform.mk4
-rw-r--r--plat/rockchip/rk3399/platform.mk17
-rw-r--r--plat/rpi/common/aarch64/plat_helpers.S (renamed from plat/rpi/rpi4/aarch64/plat_helpers.S)95
-rw-r--r--plat/rpi/common/include/rpi_shared.h4
-rw-r--r--plat/rpi/common/rpi3_common.c39
-rw-r--r--plat/rpi/common/rpi3_pm.c34
-rw-r--r--plat/rpi/rpi3/aarch64/plat_helpers.S165
-rw-r--r--plat/rpi/rpi3/include/platform_def.h10
-rw-r--r--plat/rpi/rpi3/include/rpi_hw.h8
-rw-r--r--plat/rpi/rpi3/platform.mk23
-rw-r--r--plat/rpi/rpi3/rpi3_bl1_setup.c2
-rw-r--r--plat/rpi/rpi3/rpi3_bl2_setup.c15
-rw-r--r--plat/rpi/rpi3/rpi3_bl31_setup.c2
-rw-r--r--plat/rpi/rpi4/include/platform_def.h9
-rw-r--r--plat/rpi/rpi4/include/rpi_hw.h11
-rw-r--r--plat/rpi/rpi4/platform.mk6
-rw-r--r--plat/rpi/rpi4/rpi4_bl31_setup.c20
-rw-r--r--plat/socionext/synquacer/include/plat.ld.S1
-rw-r--r--plat/socionext/synquacer/include/platform_def.h4
-rw-r--r--plat/socionext/synquacer/platform.mk9
-rw-r--r--plat/socionext/synquacer/sq_bl31_setup.c5
-rw-r--r--plat/socionext/synquacer/sq_helpers.S6
-rw-r--r--plat/socionext/uniphier/include/platform_def.h1
-rw-r--r--plat/socionext/uniphier/platform.mk20
-rw-r--r--plat/socionext/uniphier/tsp/uniphier_tsp_setup.c15
-rw-r--r--plat/socionext/uniphier/uniphier.h15
-rw-r--r--plat/socionext/uniphier/uniphier_bl2_setup.c25
-rw-r--r--plat/socionext/uniphier/uniphier_bl31_setup.c37
-rw-r--r--plat/socionext/uniphier/uniphier_boot_device.c48
-rw-r--r--plat/socionext/uniphier/uniphier_console.S9
-rw-r--r--plat/socionext/uniphier/uniphier_console_setup.c54
-rw-r--r--plat/socionext/uniphier/uniphier_emmc.c48
-rw-r--r--plat/socionext/uniphier/uniphier_image_desc.c4
-rw-r--r--plat/socionext/uniphier/uniphier_io_storage.c47
-rw-r--r--plat/socionext/uniphier/uniphier_nand.c18
-rw-r--r--plat/socionext/uniphier/uniphier_psci.c68
-rw-r--r--plat/socionext/uniphier/uniphier_soc_info.c13
-rw-r--r--plat/socionext/uniphier/uniphier_xlat_setup.c48
-rw-r--r--plat/ti/k3/board/generic/board.mk7
-rw-r--r--plat/ti/k3/board/lite/board.mk24
-rw-r--r--plat/ti/k3/board/lite/include/board_def.h34
-rw-r--r--plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c14
-rw-r--r--plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h15
-rw-r--r--plat/ti/k3/common/drivers/ti_sci/ti_sci.c1
-rw-r--r--plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h3
-rw-r--r--plat/ti/k3/common/k3_bl31_setup.c34
-rw-r--r--plat/ti/k3/common/k3_console.c2
-rw-r--r--plat/ti/k3/common/k3_helpers.S6
-rw-r--r--plat/ti/k3/common/k3_psci.c8
-rw-r--r--plat/ti/k3/common/plat_common.mk17
-rw-r--r--plat/ti/k3/include/platform_def.h20
-rw-r--r--plat/ti/k3/platform.mk2
-rw-r--r--plat/xilinx/common/pm_service/pm_ipi.c4
-rw-r--r--plat/xilinx/versal/bl31_versal_setup.c12
-rw-r--r--plat/xilinx/versal/include/versal_def.h1
-rw-r--r--plat/xilinx/versal/plat_psci.c12
-rw-r--r--plat/xilinx/versal/plat_versal.c6
-rw-r--r--plat/xilinx/versal/platform.mk9
-rw-r--r--plat/xilinx/versal/pm_service/pm_api_sys.c112
-rw-r--r--plat/xilinx/versal/pm_service/pm_api_sys.h7
-rw-r--r--plat/xilinx/versal/pm_service/pm_client.c9
-rw-r--r--plat/xilinx/versal/pm_service/pm_defs.h27
-rw-r--r--plat/xilinx/versal/pm_service/pm_svc_main.c37
-rw-r--r--plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S6
-rw-r--r--plat/xilinx/zynqmp/bl31_zynqmp_setup.c33
-rw-r--r--plat/xilinx/zynqmp/include/zynqmp_def.h17
-rw-r--r--plat/xilinx/zynqmp/plat_zynqmp.c6
-rw-r--r--plat/xilinx/zynqmp/platform.mk9
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_clock.c45
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_clock.h4
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c46
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c367
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h15
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_sys.c232
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_sys.h22
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_defs.h50
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_svc_main.c121
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_svc_main.h5
-rw-r--r--plat/xilinx/zynqmp/sip_svc_setup.c15
-rw-r--r--plat/xilinx/zynqmp/tsp/tsp_plat_setup.c4
841 files changed, 47405 insertions, 9093 deletions
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 98bcf3e22..901d88895 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -5,6 +5,8 @@
#
include lib/xlat_tables_v2/xlat_tables.mk
+include lib/libfdt/libfdt.mk
+include drivers/arm/gic/v2/gicv2.mk
AW_PLAT := plat/allwinner
@@ -12,17 +14,15 @@ PLAT_INCLUDES := -Iinclude/plat/arm/common/aarch64 \
-I${AW_PLAT}/common/include \
-I${AW_PLAT}/${PLAT}/include
-include lib/libfdt/libfdt.mk
-
PLAT_BL_COMMON_SOURCES := drivers/ti/uart/${ARCH}/16550_console.S \
${XLAT_TABLES_LIB_SRCS} \
${AW_PLAT}/common/plat_helpers.S \
${AW_PLAT}/common/sunxi_common.c
BL31_SOURCES += drivers/allwinner/axp/common.c \
- drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
- drivers/arm/gic/v2/gicv2_main.c \
+ drivers/allwinner/sunxi_msgbox.c \
+ drivers/arm/css/scpi/css_scpi.c \
+ ${GICV2_SOURCES} \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
lib/cpus/${ARCH}/cortex_a53.S \
@@ -48,6 +48,10 @@ ENABLE_SVE_FOR_NS := 0
ERRATA_A53_835769 := 1
ERRATA_A53_843419 := 1
ERRATA_A53_855873 := 1
+ERRATA_A53_1530924 := 1
+
+# The traditional U-Boot load address is 160MB into DRAM.
+PRELOADED_BL33_BASE ?= 0x4a000000
# The reset vector can be changed for each CPU.
PROGRAMMABLE_RESET_ADDRESS := 1
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index 32a7c0408..93720fff2 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -13,16 +13,18 @@
#include <sunxi_mmap.h>
-#define BL31_BASE SUNXI_SRAM_A2_BASE
-#define BL31_LIMIT (SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE)
+#define BL31_BASE (SUNXI_SRAM_A2_BASE + 0x4000)
+#define BL31_LIMIT (SUNXI_SRAM_A2_BASE + \
+ SUNXI_SRAM_A2_SIZE - SUNXI_SCP_SIZE)
+
+/* The SCP firmware is allocated the last 16KiB of SRAM A2. */
+#define SUNXI_SCP_BASE BL31_LIMIT
+#define SUNXI_SCP_SIZE 0x4000
/* Overwrite U-Boot SPL, but reserve the first page for the SPL header. */
#define BL31_NOBITS_BASE (SUNXI_SRAM_A1_BASE + 0x1000)
#define BL31_NOBITS_LIMIT (SUNXI_SRAM_A1_BASE + SUNXI_SRAM_A1_SIZE)
-/* The traditional U-Boot load address is 160MB into DRAM, so at 0x4a000000 */
-#define PLAT_SUNXI_NS_IMAGE_OFFSET (SUNXI_DRAM_BASE + (160U << 20))
-
/* How much memory to reserve as secure for BL32, if configured */
#define SUNXI_DRAM_SEC_SIZE (32U << 20)
@@ -35,6 +37,9 @@
#define MAX_MMAP_REGIONS (3 + PLATFORM_MMAP_REGIONS)
#define MAX_XLAT_TABLES 1
+#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE \
+ (SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE - 0x200)
+
#define PLAT_MAX_PWR_LVL_STATES U(2)
#define PLAT_MAX_RET_STATE U(1)
#define PLAT_MAX_OFF_STATE U(2)
@@ -51,7 +56,7 @@
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \
PLATFORM_MAX_CPUS_PER_CLUSTER)
#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4)
-#define PLATFORM_MMAP_REGIONS 4
+#define PLATFORM_MMAP_REGIONS 5
#define PLATFORM_STACK_SIZE (0x1000 / PLATFORM_CORE_COUNT)
#ifndef SPD_none
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index a24527c5d..b619b18ed 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -28,7 +28,7 @@
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
-static console_16550_t console;
+static console_t console;
static const gicv2_driver_data_t sunxi_gic_data = {
.gicd_base = SUNXI_GICD_BASE,
@@ -57,7 +57,7 @@ static void *sunxi_find_dtb(void)
for (i = 0; i < 2048 / sizeof(uint64_t); i++) {
uint32_t *dtb_base;
- if (u_boot_base[i] != PLAT_SUNXI_NS_IMAGE_OFFSET)
+ if (u_boot_base[i] != PRELOADED_BL33_BASE)
continue;
/* Does the suspected U-Boot size look anyhow reasonable? */
@@ -96,13 +96,10 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
* Tell BL31 where the non-trusted software image
* is located and the entry state information
*/
- bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+ bl33_image_ep_info.pc = PRELOADED_BL33_BASE;
bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
-
- /* Turn off all secondary CPUs */
- sunxi_disable_secondary_cpus(read_mpidr());
}
void bl31_plat_arch_setup(void)
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 3759c285e..5b536a043 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -21,11 +21,13 @@
static const mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = {
MAP_REGION_FLAT(SUNXI_SRAM_BASE, SUNXI_SRAM_SIZE,
MT_RW_DATA | MT_SECURE),
+ MAP_REGION_FLAT(SUNXI_SCP_BASE, SUNXI_SCP_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
MAP_REGION_FLAT(SUNXI_DEV_BASE, SUNXI_DEV_SIZE,
MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
MAP_REGION(SUNXI_DRAM_BASE, SUNXI_DRAM_VIRT_BASE, SUNXI_DRAM_SEC_SIZE,
MT_RW_DATA | MT_SECURE),
- MAP_REGION(PLAT_SUNXI_NS_IMAGE_OFFSET,
+ MAP_REGION(PRELOADED_BL33_BASE,
SUNXI_DRAM_VIRT_BASE + SUNXI_DRAM_SEC_SIZE,
SUNXI_DRAM_MAP_SIZE,
MT_RO_DATA | MT_NS),
@@ -37,15 +39,6 @@ unsigned int plat_get_syscnt_freq2(void)
return SUNXI_OSC24M_CLK_IN_HZ;
}
-uintptr_t plat_get_ns_image_entrypoint(void)
-{
-#ifdef PRELOADED_BL33_BASE
- return PRELOADED_BL33_BASE;
-#else
- return PLAT_SUNXI_NS_IMAGE_OFFSET;
-#endif
-}
-
void sunxi_configure_mmu_el3(int flags)
{
mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
@@ -123,11 +116,9 @@ int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb)
device_bit = BIT(6);
break;
case SUNXI_SOC_H6:
- if (use_rsb)
- return -ENODEV;
- pin_func = 0x33;
+ pin_func = use_rsb ? 0x22 : 0x33;
device_bit = BIT(16);
- reset_offset = 0x19c;
+ reset_offset = use_rsb ? 0x1bc : 0x19c;
break;
case SUNXI_SOC_A64:
pin_func = use_rsb ? 0x22 : 0x33;
@@ -155,7 +146,7 @@ int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb)
if (socid != SUNXI_SOC_H6)
mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit);
else
- mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x19c, device_bit | BIT(0));
+ mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, BIT(0));
/* assert, then de-assert reset of I2C/RSB controller */
mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
@@ -175,7 +166,7 @@ DEFINE_BAKERY_LOCK(arisc_lock);
*/
void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param)
{
- uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE - 0x4000 + 0x100;
+ uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE + 0x100;
do {
bakery_lock_get(&arisc_lock);
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index 9b074d2ac..aa80c528b 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,7 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/css/css_scpi.h>
#include <drivers/arm/gicv2.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
@@ -17,6 +18,7 @@
#include <plat/common/platform.h>
#include <sunxi_cpucfg.h>
+#include <sunxi_def.h>
#include <sunxi_mmap.h>
#include <sunxi_private.h>
@@ -24,25 +26,83 @@
#define SUNXI_WDOG0_CFG_REG (SUNXI_R_WDOG_BASE + 0x0014)
#define SUNXI_WDOG0_MODE_REG (SUNXI_R_WDOG_BASE + 0x0018)
-#define mpidr_is_valid(mpidr) ( \
- MPIDR_AFFLVL3_VAL(mpidr) == 0 && \
- MPIDR_AFFLVL2_VAL(mpidr) == 0 && \
- MPIDR_AFFLVL1_VAL(mpidr) < PLATFORM_CLUSTER_COUNT && \
- MPIDR_AFFLVL0_VAL(mpidr) < PLATFORM_MAX_CPUS_PER_CLUSTER)
+#define CPU_PWR_LVL MPIDR_AFFLVL0
+#define CLUSTER_PWR_LVL MPIDR_AFFLVL1
+#define SYSTEM_PWR_LVL MPIDR_AFFLVL2
-static int sunxi_pwr_domain_on(u_register_t mpidr)
+#define CPU_PWR_STATE(state) \
+ ((state)->pwr_domain_state[CPU_PWR_LVL])
+#define CLUSTER_PWR_STATE(state) \
+ ((state)->pwr_domain_state[CLUSTER_PWR_LVL])
+#define SYSTEM_PWR_STATE(state) \
+ ((state)->pwr_domain_state[SYSTEM_PWR_LVL])
+
+/*
+ * The addresses for the SCP exception vectors are defined in the or1k
+ * architecture specification.
+ */
+#define OR1K_VEC_FIRST 0x01
+#define OR1K_VEC_LAST 0x0e
+#define OR1K_VEC_ADDR(n) (0x100 * (n))
+
+/*
+ * This magic value is the little-endian representation of the or1k
+ * instruction "l.mfspr r2, r0, 0x12", which is guaranteed to be the
+ * first instruction in the SCP firmware.
+ */
+#define SCP_FIRMWARE_MAGIC 0xb4400012
+
+static bool scpi_available;
+
+static inline scpi_power_state_t scpi_map_state(plat_local_state_t psci_state)
{
- if (mpidr_is_valid(mpidr) == 0)
- return PSCI_E_INTERN_FAIL;
+ if (is_local_state_run(psci_state))
+ return scpi_power_on;
+ if (is_local_state_retn(psci_state))
+ return scpi_power_retention;
+ return scpi_power_off;
+}
- sunxi_cpu_on(mpidr);
+static void sunxi_cpu_standby(plat_local_state_t cpu_state)
+{
+ u_register_t scr = read_scr_el3();
+
+ assert(is_local_state_retn(cpu_state));
+
+ write_scr_el3(scr | SCR_IRQ_BIT);
+ wfi();
+ write_scr_el3(scr);
+}
+
+static int sunxi_pwr_domain_on(u_register_t mpidr)
+{
+ if (scpi_available) {
+ scpi_set_css_power_state(mpidr,
+ scpi_power_on,
+ scpi_power_on,
+ scpi_power_on);
+ } else {
+ sunxi_cpu_on(mpidr);
+ }
return PSCI_E_SUCCESS;
}
static void sunxi_pwr_domain_off(const psci_power_state_t *target_state)
{
- gicv2_cpuif_disable();
+ plat_local_state_t cpu_pwr_state = CPU_PWR_STATE(target_state);
+ plat_local_state_t cluster_pwr_state = CLUSTER_PWR_STATE(target_state);
+ plat_local_state_t system_pwr_state = SYSTEM_PWR_STATE(target_state);
+
+ if (is_local_state_off(cpu_pwr_state))
+ gicv2_cpuif_disable();
+
+ if (scpi_available) {
+ scpi_set_css_power_state(read_mpidr(),
+ scpi_map_state(cpu_pwr_state),
+ scpi_map_state(cluster_pwr_state),
+ scpi_map_state(system_pwr_state));
+ }
}
static void __dead2 sunxi_pwr_down_wfi(const psci_power_state_t *target_state)
@@ -55,12 +115,26 @@ static void __dead2 sunxi_pwr_down_wfi(const psci_power_state_t *target_state)
static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
- gicv2_pcpu_distif_init();
- gicv2_cpuif_enable();
+ if (is_local_state_off(SYSTEM_PWR_STATE(target_state)))
+ gicv2_distif_init();
+ if (is_local_state_off(CPU_PWR_STATE(target_state))) {
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+ }
}
static void __dead2 sunxi_system_off(void)
{
+ gicv2_cpuif_disable();
+
+ if (scpi_available) {
+ /* Send the power down request to the SCP */
+ uint32_t ret = scpi_sys_power_state(scpi_system_shutdown);
+
+ if (ret != SCP_OK)
+ ERROR("PSCI: SCPI %s failed: %d\n", "shutdown", ret);
+ }
+
/* Turn off all secondary CPUs */
sunxi_disable_secondary_cpus(read_mpidr());
@@ -74,6 +148,16 @@ static void __dead2 sunxi_system_off(void)
static void __dead2 sunxi_system_reset(void)
{
+ gicv2_cpuif_disable();
+
+ if (scpi_available) {
+ /* Send the system reset request to the SCP */
+ uint32_t ret = scpi_sys_power_state(scpi_system_reboot);
+
+ if (ret != SCP_OK)
+ ERROR("PSCI: SCPI %s failed: %d\n", "reboot", ret);
+ }
+
/* Reset the whole system when the watchdog times out */
mmio_write_32(SUNXI_WDOG0_CFG_REG, 1);
/* Enable the watchdog with the shortest timeout (0.5 seconds) */
@@ -86,22 +170,66 @@ static void __dead2 sunxi_system_reset(void)
panic();
}
+static int sunxi_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state)
+{
+ unsigned int power_level = psci_get_pstate_pwrlvl(power_state);
+ unsigned int type = psci_get_pstate_type(power_state);
+
+ assert(req_state != NULL);
+
+ if (power_level > PLAT_MAX_PWR_LVL)
+ return PSCI_E_INVALID_PARAMS;
+
+ if (type == PSTATE_TYPE_STANDBY) {
+ /* Only one retention power state is supported. */
+ if (psci_get_pstate_id(power_state) > 0)
+ return PSCI_E_INVALID_PARAMS;
+ /* The SoC cannot be suspended without losing state */
+ if (power_level == SYSTEM_PWR_LVL)
+ return PSCI_E_INVALID_PARAMS;
+ for (unsigned int i = 0; i <= power_level; ++i)
+ req_state->pwr_domain_state[i] = PLAT_MAX_RET_STATE;
+ } else {
+ /* Only one off power state is supported. */
+ if (psci_get_pstate_id(power_state) > 0)
+ return PSCI_E_INVALID_PARAMS;
+ for (unsigned int i = 0; i <= power_level; ++i)
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+ }
+ /* Higher power domain levels should all remain running */
+ for (unsigned int i = power_level + 1; i <= PLAT_MAX_PWR_LVL; ++i)
+ req_state->pwr_domain_state[i] = PSCI_LOCAL_STATE_RUN;
+
+ return PSCI_E_SUCCESS;
+}
+
static int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
{
/* The non-secure entry point must be in DRAM */
- if (ns_entrypoint >= SUNXI_DRAM_BASE)
- return PSCI_E_SUCCESS;
+ if (ns_entrypoint < SUNXI_DRAM_BASE) {
+ return PSCI_E_INVALID_ADDRESS;
+ }
- return PSCI_E_INVALID_ADDRESS;
+ return PSCI_E_SUCCESS;
+}
+
+static void sunxi_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+ assert(req_state);
+
+ for (unsigned int i = 0; i <= PLAT_MAX_PWR_LVL; ++i)
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
}
static plat_psci_ops_t sunxi_psci_ops = {
+ .cpu_standby = sunxi_cpu_standby,
.pwr_domain_on = sunxi_pwr_domain_on,
.pwr_domain_off = sunxi_pwr_domain_off,
- .pwr_domain_pwr_down_wfi = sunxi_pwr_down_wfi,
.pwr_domain_on_finish = sunxi_pwr_domain_on_finish,
.system_off = sunxi_system_off,
.system_reset = sunxi_system_reset,
+ .validate_power_state = sunxi_validate_power_state,
.validate_ns_entrypoint = sunxi_validate_ns_entrypoint,
};
@@ -110,13 +238,43 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
{
assert(psci_ops);
- for (int cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu += 1) {
+ /* Program all CPU entry points. */
+ for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; ++cpu) {
mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu),
sec_entrypoint & 0xffffffff);
mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu),
sec_entrypoint >> 32);
}
+ /* Check for a valid SCP firmware, and boot the SCP if found. */
+ if (mmio_read_32(SUNXI_SCP_BASE) == SCP_FIRMWARE_MAGIC) {
+ /* Program SCP exception vectors to the firmware entrypoint. */
+ for (unsigned int i = OR1K_VEC_FIRST; i <= OR1K_VEC_LAST; ++i) {
+ uint32_t vector = SUNXI_SRAM_A2_BASE + OR1K_VEC_ADDR(i);
+ uint32_t offset = SUNXI_SCP_BASE - vector;
+
+ mmio_write_32(vector, offset >> 2);
+ clean_dcache_range(vector, sizeof(uint32_t));
+ }
+ /* Take the SCP out of reset. */
+ mmio_setbits_32(SUNXI_R_CPUCFG_BASE, BIT(0));
+ /* Wait for the SCP firmware to boot. */
+ if (scpi_wait_ready() == 0)
+ scpi_available = true;
+ }
+
+ NOTICE("PSCI: System suspend is %s\n",
+ scpi_available ? "available via SCPI" : "unavailable");
+ if (scpi_available) {
+ /* Suspend is only available via SCPI. */
+ sunxi_psci_ops.pwr_domain_suspend = sunxi_pwr_domain_off;
+ sunxi_psci_ops.pwr_domain_suspend_finish = sunxi_pwr_domain_on_finish;
+ sunxi_psci_ops.get_sys_suspend_power_state = sunxi_get_sys_suspend_power_state;
+ } else {
+ /* This is only needed when SCPI is unavailable. */
+ sunxi_psci_ops.pwr_domain_pwr_down_wfi = sunxi_pwr_down_wfi;
+ }
+
*psci_ops = &sunxi_psci_ops;
return 0;
diff --git a/plat/allwinner/common/sunxi_security.c b/plat/allwinner/common/sunxi_security.c
index 1f16a0b72..98b91c39f 100644
--- a/plat/allwinner/common/sunxi_security.c
+++ b/plat/allwinner/common/sunxi_security.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,16 +7,11 @@
#include <common/debug.h>
#include <lib/mmio.h>
+#include <sunxi_ccu.h>
#include <sunxi_mmap.h>
#include <sunxi_private.h>
+#include <sunxi_spc.h>
-#ifdef SUNXI_SPC_BASE
-#define SPC_DECPORT_STA_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0x4)
-#define SPC_DECPORT_SET_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0x8)
-#define SPC_DECPORT_CLR_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0xc)
-#endif
-
-#define R_PRCM_SEC_SWITCH_REG 0x1d0
#define DMA_SEC_REG 0x20
/*
@@ -27,20 +22,18 @@
*/
void sunxi_security_setup(void)
{
-#ifdef SUNXI_SPC_BASE
int i;
INFO("Configuring SPC Controller\n");
/* SPC setup: set all devices to non-secure */
- for (i = 0; i < 6; i++)
- mmio_write_32(SPC_DECPORT_SET_REG(i), 0xff);
-#endif
+ for (i = 0; i < SUNXI_SPC_NUM_PORTS; i++)
+ mmio_write_32(SUNXI_SPC_DECPORT_SET_REG(i), 0xffffffff);
/* set MBUS clocks, bus clocks (AXI/AHB/APB) and PLLs to non-secure */
mmio_write_32(SUNXI_CCU_SEC_SWITCH_REG, 0x7);
- /* set R_PRCM clocks to non-secure */
- mmio_write_32(SUNXI_R_PRCM_BASE + R_PRCM_SEC_SWITCH_REG, 0x7);
+ /* Set R_PRCM bus clocks to non-secure */
+ mmio_write_32(SUNXI_R_PRCM_SEC_SWITCH_REG, 0x1);
/* Set all DMA channels (16 max.) to non-secure */
mmio_write_32(SUNXI_DMA_BASE + DMA_SEC_REG, 0xffff);
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_ccu.h b/plat/allwinner/sun50i_a64/include/sunxi_ccu.h
new file mode 100644
index 000000000..2a2488621
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/include/sunxi_ccu.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CCU_H
+#define SUNXI_CCU_H
+
+#define SUNXI_CCU_SEC_SWITCH_REG (SUNXI_CCU_BASE + 0x02f0)
+
+#define SUNXI_R_PRCM_SEC_SWITCH_REG (SUNXI_R_PRCM_BASE + 0x01d0)
+
+#endif /* SUNXI_CCU_H */
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
index db4409118..6c847d39b 100644
--- a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,8 +14,8 @@
#define SUNXI_SRAM_SIZE 0x00044000
#define SUNXI_SRAM_A1_BASE 0x00010000
#define SUNXI_SRAM_A1_SIZE 0x00008000
-#define SUNXI_SRAM_A2_BASE 0x00044000
-#define SUNXI_SRAM_A2_SIZE 0x00010000
+#define SUNXI_SRAM_A2_BASE 0x00040000
+#define SUNXI_SRAM_A2_SIZE 0x00014000
#define SUNXI_SRAM_C_BASE 0x00018000
#define SUNXI_SRAM_C_SIZE 0x0001c000
#define SUNXI_DEV_BASE 0x01000000
@@ -36,7 +36,6 @@
#define SUNXI_MSGBOX_BASE 0x01c17000
#define SUNXI_SPINLOCK_BASE 0x01c18000
#define SUNXI_CCU_BASE 0x01c20000
-#define SUNXI_CCU_SEC_SWITCH_REG (SUNXI_CCU_BASE + 0x2f0)
#define SUNXI_PIO_BASE 0x01c20800
#define SUNXI_TIMER_BASE 0x01c20c00
#define SUNXI_WDOG_BASE 0x01c20ca0
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_spc.h b/plat/allwinner/sun50i_a64/include/sunxi_spc.h
new file mode 100644
index 000000000..5ba7e18fe
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/include/sunxi_spc.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_SPC_H
+#define SUNXI_SPC_H
+
+#define SUNXI_SPC_NUM_PORTS 6
+
+#define SUNXI_SPC_DECPORT_STA_REG(p) (SUNXI_SPC_BASE + 0x0004 + 0x0c * (p))
+#define SUNXI_SPC_DECPORT_SET_REG(p) (SUNXI_SPC_BASE + 0x0008 + 0x0c * (p))
+#define SUNXI_SPC_DECPORT_CLR_REG(p) (SUNXI_SPC_BASE + 0x000c + 0x0c * (p))
+
+#endif /* SUNXI_SPC_H */
diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c
index 5b7d76ae9..80a69c340 100644
--- a/plat/allwinner/sun50i_a64/sunxi_power.c
+++ b/plat/allwinner/sun50i_a64/sunxi_power.c
@@ -92,21 +92,13 @@ static int rsb_init(void)
if (ret)
return ret;
- /* Start with 400 KHz to issue the I2C->RSB switch command. */
- ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 400000);
- if (ret)
- return ret;
-
- /*
- * Initiate an I2C transaction to write 0x7c into register 0x3e,
- * switching the PMIC to RSB mode.
- */
- ret = rsb_set_device_mode(0x7c3e00);
+ /* Switch to the recommended 3 MHz bus clock. */
+ ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000);
if (ret)
return ret;
- /* Now in RSB mode, switch to the recommended 3 MHz. */
- ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000);
+ /* Initiate an I2C transaction to switch the PMIC to RSB mode. */
+ ret = rsb_set_device_mode(AXP20X_MODE_RSB << 16 | AXP20X_MODE_REG << 8);
if (ret)
return ret;
@@ -156,6 +148,11 @@ int sunxi_pmic_setup(uint16_t socid, const void *fdt)
pmic = AXP803_RSB;
axp_setup_regulators(fdt);
+ /* Switch the PMIC back to I2C mode. */
+ ret = axp_write(AXP20X_MODE_REG, AXP20X_MODE_I2C);
+ if (ret)
+ return ret;
+
break;
default:
return -ENODEV;
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_ccu.h b/plat/allwinner/sun50i_h6/include/sunxi_ccu.h
new file mode 100644
index 000000000..85fbb9080
--- /dev/null
+++ b/plat/allwinner/sun50i_h6/include/sunxi_ccu.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CCU_H
+#define SUNXI_CCU_H
+
+#define SUNXI_CCU_SEC_SWITCH_REG (SUNXI_CCU_BASE + 0x0f00)
+
+#define SUNXI_R_PRCM_SEC_SWITCH_REG (SUNXI_R_PRCM_BASE + 0x0290)
+
+#endif /* SUNXI_CCU_H */
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
index f36491a8a..2d7b09837 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,8 +14,8 @@
#define SUNXI_SRAM_SIZE 0x000f8000
#define SUNXI_SRAM_A1_BASE 0x00020000
#define SUNXI_SRAM_A1_SIZE 0x00008000
-#define SUNXI_SRAM_A2_BASE 0x00104000
-#define SUNXI_SRAM_A2_SIZE 0x00014000
+#define SUNXI_SRAM_A2_BASE 0x00100000
+#define SUNXI_SRAM_A2_SIZE 0x00018000
#define SUNXI_SRAM_C_BASE 0x00028000
#define SUNXI_SRAM_C_SIZE 0x0001e000
#define SUNXI_DEV_BASE 0x01000000
@@ -29,9 +29,9 @@
#define SUNXI_SID_BASE 0x03006000
#define SUNXI_DMA_BASE 0x03002000
#define SUNXI_MSGBOX_BASE 0x03003000
-#define SUNXI_CCU_BASE 0x03010000
-#define SUNXI_CCU_SEC_SWITCH_REG (SUNXI_CCU_BASE + 0xf00)
-#define SUNXI_PIO_BASE 0x030b0000
+#define SUNXI_CCU_BASE 0x03001000
+#define SUNXI_PIO_BASE 0x0300b000
+#define SUNXI_SPC_BASE 0x03008000
#define SUNXI_TIMER_BASE 0x03009000
#define SUNXI_WDOG_BASE 0x030090a0
#define SUNXI_THS_BASE 0x05070400
@@ -55,6 +55,7 @@
#define SUNXI_R_TWD_BASE 0x07020800
#define SUNXI_R_CPUCFG_BASE 0x07000400
#define SUNXI_R_I2C_BASE 0x07081400
+#define SUNXI_R_RSB_BASE 0x07083000
#define SUNXI_R_UART_BASE 0x07080000
#define SUNXI_R_PIO_BASE 0x07022000
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_spc.h b/plat/allwinner/sun50i_h6/include/sunxi_spc.h
new file mode 100644
index 000000000..0f5965bee
--- /dev/null
+++ b/plat/allwinner/sun50i_h6/include/sunxi_spc.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_SPC_H
+#define SUNXI_SPC_H
+
+#define SUNXI_SPC_NUM_PORTS 14
+
+#define SUNXI_SPC_DECPORT_STA_REG(p) (SUNXI_SPC_BASE + 0x0000 + 0x10 * (p))
+#define SUNXI_SPC_DECPORT_SET_REG(p) (SUNXI_SPC_BASE + 0x0004 + 0x10 * (p))
+#define SUNXI_SPC_DECPORT_CLR_REG(p) (SUNXI_SPC_BASE + 0x0008 + 0x10 * (p))
+
+#endif /* SUNXI_SPC_H */
diff --git a/plat/allwinner/sun50i_h6/platform.mk b/plat/allwinner/sun50i_h6/platform.mk
index 4ecc57cf0..1c98919b1 100644
--- a/plat/allwinner/sun50i_h6/platform.mk
+++ b/plat/allwinner/sun50i_h6/platform.mk
@@ -8,4 +8,4 @@
include plat/allwinner/common/allwinner-common.mk
BL31_SOURCES += drivers/allwinner/axp/axp805.c \
- drivers/mentor/i2c/mi2cv.c
+ drivers/allwinner/sunxi_rsb.c
diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index 443015bac..a7865a5d4 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -6,20 +6,17 @@
*/
#include <errno.h>
-#include <string.h>
-#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/allwinner/axp.h>
-#include <drivers/delay_timer.h>
-#include <drivers/mentor/mi2cv.h>
-#include <lib/mmio.h>
+#include <drivers/allwinner/sunxi_rsb.h>
#include <sunxi_def.h>
#include <sunxi_mmap.h>
#include <sunxi_private.h>
-#define AXP805_ADDR 0x36
+#define AXP805_HW_ADDR 0x745
+#define AXP805_RT_ADDR 0x3a
static enum pmic_type {
UNKNOWN,
@@ -28,67 +25,67 @@ static enum pmic_type {
int axp_read(uint8_t reg)
{
- uint8_t val;
- int ret;
-
- ret = i2c_write(AXP805_ADDR, 0, 0, &reg, 1);
- if (ret == 0)
- ret = i2c_read(AXP805_ADDR, 0, 0, &val, 1);
- if (ret) {
- ERROR("PMIC: Cannot read AXP805 register %02x\n", reg);
- return ret;
- }
-
- return val;
+ return rsb_read(AXP805_RT_ADDR, reg);
}
int axp_write(uint8_t reg, uint8_t val)
{
- int ret;
-
- ret = i2c_write(AXP805_ADDR, reg, 1, &val, 1);
- if (ret)
- ERROR("PMIC: Cannot write AXP805 register %02x\n", reg);
-
- return ret;
+ return rsb_write(AXP805_RT_ADDR, reg, val);
}
-static int axp805_probe(void)
+static int rsb_init(void)
{
int ret;
- /* Switch the AXP805 to master/single-PMIC mode. */
- ret = axp_write(0xff, 0x0);
+ ret = rsb_init_controller();
if (ret)
return ret;
- ret = axp_check_id();
+ /* Switch to the recommended 3 MHz bus clock. */
+ ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000);
if (ret)
return ret;
- return 0;
+ /* Initiate an I2C transaction to switch the PMIC to RSB mode. */
+ ret = rsb_set_device_mode(AXP20X_MODE_RSB << 16 | AXP20X_MODE_REG << 8);
+ if (ret)
+ return ret;
+
+ /* Associate the 8-bit runtime address with the 12-bit bus address. */
+ ret = rsb_assign_runtime_address(AXP805_HW_ADDR, AXP805_RT_ADDR);
+ if (ret)
+ return ret;
+
+ return axp_check_id();
}
int sunxi_pmic_setup(uint16_t socid, const void *fdt)
{
int ret;
- INFO("PMIC: Probing AXP805 on I2C\n");
+ INFO("PMIC: Probing AXP805 on RSB\n");
- ret = sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
+ ret = sunxi_init_platform_r_twi(socid, true);
if (ret)
return ret;
- /* initialise mi2cv driver */
- i2c_init((void *)SUNXI_R_I2C_BASE);
+ ret = rsb_init();
+ if (ret)
+ return ret;
- ret = axp805_probe();
+ /* Switch the AXP805 to master/single-PMIC mode. */
+ ret = axp_write(0xff, 0x0);
if (ret)
return ret;
pmic = AXP805;
axp_setup_regulators(fdt);
+ /* Switch the PMIC back to I2C mode. */
+ ret = axp_write(AXP20X_MODE_REG, AXP20X_MODE_I2C);
+ if (ret)
+ return ret;
+
return 0;
}
@@ -96,10 +93,9 @@ void sunxi_power_down(void)
{
switch (pmic) {
case AXP805:
- /* Re-initialise after rich OS might have used it. */
- sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
- /* initialise mi2cv driver */
- i2c_init((void *)SUNXI_R_I2C_BASE);
+ /* (Re-)init RSB in case the rich OS has disabled it. */
+ sunxi_init_platform_r_twi(SUNXI_SOC_H6, true);
+ rsb_init();
axp_power_off();
break;
default:
diff --git a/plat/amlogic/axg/axg_bl31_setup.c b/plat/amlogic/axg/axg_bl31_setup.c
new file mode 100644
index 000000000..8cc9d69f4
--- /dev/null
+++ b/plat/amlogic/axg/axg_bl31_setup.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/bl_common.h>
+#include <common/interrupt_props.h>
+#include <drivers/arm/gicv2.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include "aml_private.h"
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+static image_info_t bl30_image_info;
+static image_info_t bl301_image_info;
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+ entry_point_info_t *next_image_info;
+
+ next_image_info = (type == NON_SECURE) ?
+ &bl33_image_ep_info : &bl32_image_ep_info;
+
+ /* None of the images can have 0x0 as the entrypoint. */
+ if (next_image_info->pc != 0U)
+ return next_image_info;
+
+ return NULL;
+}
+
+/*******************************************************************************
+ * Perform any BL31 early platform setup. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before
+ * they are lost (potentially). This needs to be done before the MMU is
+ * initialized so that the memory layout can be used while creating page
+ * tables. BL2 has flushed this information to memory, so we are guaranteed
+ * to pick up good data.
+ ******************************************************************************/
+struct axg_bl31_param {
+ param_header_t h;
+ image_info_t *bl31_image_info;
+ entry_point_info_t *bl32_ep_info;
+ image_info_t *bl32_image_info;
+ entry_point_info_t *bl33_ep_info;
+ image_info_t *bl33_image_info;
+ image_info_t *scp_image_info[];
+};
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ struct axg_bl31_param *from_bl2;
+
+ /* Initialize the console to provide early debug support */
+ aml_console_init();
+
+ from_bl2 = (struct axg_bl31_param *)arg0;
+
+ /* Check params passed from BL2 are not NULL. */
+ assert(from_bl2 != NULL);
+ assert(from_bl2->h.type == PARAM_BL31);
+ assert(from_bl2->h.version >= VERSION_1);
+
+ /*
+ * Copy BL32 and BL33 entry point information. It is stored in Secure
+ * RAM, in BL2's address space.
+ */
+ bl32_image_ep_info = *from_bl2->bl32_ep_info;
+ bl33_image_ep_info = *from_bl2->bl33_ep_info;
+
+#if AML_USE_ATOS
+ /*
+ * BL2 is unconditionally setting 0 (OPTEE_AARCH64) in arg0 even when
+ * the BL32 image is 32bit (OPTEE_AARCH32). This is causing the boot to
+ * hang when ATOS (32bit Amlogic BL32 binary-only TEE OS) is used.
+ *
+ * Hardcode to OPTEE_AARCH32 / MODE_RW_32.
+ */
+ bl32_image_ep_info.args.arg0 = MODE_RW_32;
+#endif
+
+ if (bl33_image_ep_info.pc == 0U) {
+ ERROR("BL31: BL33 entrypoint not obtained from BL2\n");
+ panic();
+ }
+
+ bl30_image_info = *from_bl2->scp_image_info[0];
+ bl301_image_info = *from_bl2->scp_image_info[1];
+}
+
+void bl31_plat_arch_setup(void)
+{
+ aml_setup_page_tables();
+
+ enable_mmu_el3(0);
+}
+
+static inline bool axg_scp_ready(void)
+{
+ return AML_AO_RTI_SCP_IS_READY(mmio_read_32(AML_AO_RTI_SCP_STAT));
+}
+
+static inline void axg_scp_boot(void)
+{
+ aml_scpi_upload_scp_fw(bl30_image_info.image_base,
+ bl30_image_info.image_size, 0);
+ aml_scpi_upload_scp_fw(bl301_image_info.image_base,
+ bl301_image_info.image_size, 1);
+ while (!axg_scp_ready())
+ ;
+}
+
+/*******************************************************************************
+ * GICv2 driver setup information
+ ******************************************************************************/
+static const interrupt_prop_t axg_interrupt_props[] = {
+ INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+};
+
+static const gicv2_driver_data_t axg_gic_data = {
+ .gicd_base = AML_GICD_BASE,
+ .gicc_base = AML_GICC_BASE,
+ .interrupt_props = axg_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(axg_interrupt_props)
+};
+
+void bl31_platform_setup(void)
+{
+ aml_mhu_secure_init();
+
+ gicv2_driver_init(&axg_gic_data);
+ gicv2_distif_init();
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+
+ axg_scp_boot();
+}
diff --git a/plat/amlogic/axg/axg_common.c b/plat/amlogic/axg/axg_common.c
new file mode 100644
index 000000000..870daf459
--- /dev/null
+++ b/plat/amlogic/axg/axg_common.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bl31/interrupt_mgmt.h>
+#include <common/bl_common.h>
+#include <common/ep_info.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <platform_def.h>
+#include <stdint.h>
+
+/*******************************************************************************
+ * Platform memory map regions
+ ******************************************************************************/
+#define MAP_NSDRAM0 MAP_REGION_FLAT(AML_NSDRAM0_BASE, \
+ AML_NSDRAM0_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_NS_SHARE_MEM MAP_REGION_FLAT(AML_NS_SHARE_MEM_BASE, \
+ AML_NS_SHARE_MEM_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_SEC_SHARE_MEM MAP_REGION_FLAT(AML_SEC_SHARE_MEM_BASE, \
+ AML_SEC_SHARE_MEM_SIZE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE0 MAP_REGION_FLAT(AML_SEC_DEVICE0_BASE, \
+ AML_SEC_DEVICE0_SIZE, \
+ MT_DEVICE | MT_RW)
+
+#define MAP_GIC_DEVICE MAP_REGION_FLAT(AML_GIC_DEVICE_BASE, \
+ AML_GIC_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE1 MAP_REGION_FLAT(AML_SEC_DEVICE1_BASE, \
+ AML_SEC_DEVICE1_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE2 MAP_REGION_FLAT(AML_SEC_DEVICE2_BASE, \
+ AML_SEC_DEVICE2_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_TZRAM MAP_REGION_FLAT(AML_TZRAM_BASE, \
+ AML_TZRAM_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+static const mmap_region_t axg_mmap[] = {
+ MAP_NSDRAM0,
+ MAP_NS_SHARE_MEM,
+ MAP_SEC_SHARE_MEM,
+ MAP_SEC_DEVICE0,
+ MAP_GIC_DEVICE,
+ MAP_SEC_DEVICE1,
+ MAP_SEC_DEVICE2,
+ MAP_TZRAM,
+ {0}
+};
+
+/*******************************************************************************
+ * Per-image regions
+ ******************************************************************************/
+#define MAP_BL31 MAP_REGION_FLAT(BL31_BASE, \
+ BL31_END - BL31_BASE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+#define MAP_BL_CODE MAP_REGION_FLAT(BL_CODE_BASE, \
+ BL_CODE_END - BL_CODE_BASE, \
+ MT_CODE | MT_SECURE)
+
+#define MAP_BL_RO_DATA MAP_REGION_FLAT(BL_RO_DATA_BASE, \
+ BL_RO_DATA_END - BL_RO_DATA_BASE, \
+ MT_RO_DATA | MT_SECURE)
+
+#define MAP_BL_COHERENT MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, \
+ BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+/*******************************************************************************
+ * Function that sets up the translation tables.
+ ******************************************************************************/
+void aml_setup_page_tables(void)
+{
+#if IMAGE_BL31
+ const mmap_region_t axg_bl_mmap[] = {
+ MAP_BL31,
+ MAP_BL_CODE,
+ MAP_BL_RO_DATA,
+#if USE_COHERENT_MEM
+ MAP_BL_COHERENT,
+#endif
+ {0}
+ };
+#endif
+
+ mmap_add(axg_bl_mmap);
+
+ mmap_add(axg_mmap);
+
+ init_xlat_tables();
+}
+
+/*******************************************************************************
+ * Function that returns the system counter frequency
+ ******************************************************************************/
+unsigned int plat_get_syscnt_freq2(void)
+{
+ mmio_clrbits_32(AML_SYS_CPU_CFG7, PLAT_SYS_CPU_CFG7);
+ mmio_clrbits_32(AML_AO_TIMESTAMP_CNTL, PLAT_AO_TIMESTAMP_CNTL);
+
+ return AML_OSC24M_CLK_IN_HZ;
+}
diff --git a/plat/amlogic/axg/axg_def.h b/plat/amlogic/axg/axg_def.h
new file mode 100644
index 000000000..d90681afd
--- /dev/null
+++ b/plat/amlogic/axg/axg_def.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AXG_DEF_H
+#define AXG_DEF_H
+
+#include <lib/utils_def.h>
+
+/*******************************************************************************
+ * System oscillator
+ ******************************************************************************/
+#define AML_OSC24M_CLK_IN_HZ ULL(24000000) /* 24 MHz */
+
+/*******************************************************************************
+ * Memory regions
+ ******************************************************************************/
+#define AML_NS_SHARE_MEM_BASE UL(0x05000000)
+#define AML_NS_SHARE_MEM_SIZE UL(0x00100000)
+
+#define AML_SEC_SHARE_MEM_BASE UL(0x05200000)
+#define AML_SEC_SHARE_MEM_SIZE UL(0x00100000)
+
+#define AML_GIC_DEVICE_BASE UL(0xFFC00000)
+#define AML_GIC_DEVICE_SIZE UL(0x00008000)
+
+#define AML_NSDRAM0_BASE UL(0x01000000)
+#define AML_NSDRAM0_SIZE UL(0x0F000000)
+
+#define BL31_BASE UL(0x05100000)
+#define BL31_SIZE UL(0x00100000)
+#define BL31_LIMIT (BL31_BASE + BL31_SIZE)
+
+/* Shared memory used for SMC services */
+#define AML_SHARE_MEM_INPUT_BASE UL(0x050FE000)
+#define AML_SHARE_MEM_OUTPUT_BASE UL(0x050FF000)
+
+#define AML_SEC_DEVICE0_BASE UL(0xFFD00000)
+#define AML_SEC_DEVICE0_SIZE UL(0x00026000)
+
+#define AML_SEC_DEVICE1_BASE UL(0xFF800000)
+#define AML_SEC_DEVICE1_SIZE UL(0x0000A000)
+
+#define AML_SEC_DEVICE2_BASE UL(0xFF620000)
+#define AML_SEC_DEVICE2_SIZE UL(0x00028000)
+
+#define AML_TZRAM_BASE UL(0xFFFC0000)
+#define AML_TZRAM_SIZE UL(0x00020000)
+
+/* Mailboxes */
+#define AML_MHU_SECURE_SCP_TO_AP_PAYLOAD UL(0xFFFD3800)
+#define AML_MHU_SECURE_AP_TO_SCP_PAYLOAD UL(0xFFFD3A00)
+#define AML_PSCI_MAILBOX_BASE UL(0xFFFD3F00)
+
+/*******************************************************************************
+ * GIC-400 and interrupt handling related constants
+ ******************************************************************************/
+#define AML_GICD_BASE UL(0xFFC01000)
+#define AML_GICC_BASE UL(0xFFC02000)
+
+#define IRQ_SEC_PHY_TIMER 29
+
+#define IRQ_SEC_SGI_0 8
+#define IRQ_SEC_SGI_1 9
+#define IRQ_SEC_SGI_2 10
+#define IRQ_SEC_SGI_3 11
+#define IRQ_SEC_SGI_4 12
+#define IRQ_SEC_SGI_5 13
+#define IRQ_SEC_SGI_6 14
+#define IRQ_SEC_SGI_7 15
+#define IRQ_SEC_SGI_8 16
+
+/*******************************************************************************
+ * UART definitions
+ ******************************************************************************/
+#define AML_UART0_AO_BASE UL(0xFF803000)
+#define AML_UART0_AO_CLK_IN_HZ AML_OSC24M_CLK_IN_HZ
+#define AML_UART_BAUDRATE U(115200)
+
+/*******************************************************************************
+ * Memory-mapped I/O Registers
+ ******************************************************************************/
+#define AML_AO_TIMESTAMP_CNTL UL(0xFF8000B4)
+
+#define AML_SYS_CPU_CFG7 UL(0xFF634664)
+
+#define AML_AO_RTI_STATUS_REG3 UL(0xFF80001C)
+#define AML_AO_RTI_SCP_STAT UL(0xFF80023C)
+#define AML_AO_RTI_SCP_READY_OFF U(0x14)
+#define AML_A0_RTI_SCP_READY_MASK U(3)
+#define AML_AO_RTI_SCP_IS_READY(v) \
+ ((((v) >> AML_AO_RTI_SCP_READY_OFF) & \
+ AML_A0_RTI_SCP_READY_MASK) == AML_A0_RTI_SCP_READY_MASK)
+
+#define AML_HIU_MAILBOX_SET_0 UL(0xFF63C404)
+#define AML_HIU_MAILBOX_STAT_0 UL(0xFF63C408)
+#define AML_HIU_MAILBOX_CLR_0 UL(0xFF63C40C)
+#define AML_HIU_MAILBOX_SET_3 UL(0xFF63C428)
+#define AML_HIU_MAILBOX_STAT_3 UL(0xFF63C42C)
+#define AML_HIU_MAILBOX_CLR_3 UL(0xFF63C430)
+
+#define AML_SHA_DMA_BASE UL(0xFF63E000)
+#define AML_SHA_DMA_DESC (AML_SHA_DMA_BASE + 0x08)
+#define AML_SHA_DMA_STATUS (AML_SHA_DMA_BASE + 0x28)
+
+/*******************************************************************************
+ * System Monitor Call IDs and arguments
+ ******************************************************************************/
+#define AML_SM_GET_SHARE_MEM_INPUT_BASE U(0x82000020)
+#define AML_SM_GET_SHARE_MEM_OUTPUT_BASE U(0x82000021)
+
+#define AML_SM_EFUSE_READ U(0x82000030)
+#define AML_SM_EFUSE_USER_MAX U(0x82000033)
+
+#define AML_SM_JTAG_ON U(0x82000040)
+#define AML_SM_JTAG_OFF U(0x82000041)
+#define AML_SM_GET_CHIP_ID U(0x82000044)
+
+#define AML_JTAG_STATE_ON U(0)
+#define AML_JTAG_STATE_OFF U(1)
+
+#define AML_JTAG_M3_AO U(0)
+#define AML_JTAG_M3_EE U(1)
+#define AML_JTAG_A53_AO U(2)
+#define AML_JTAG_A53_EE U(3)
+
+#endif /* AXG_DEF_H */
diff --git a/plat/amlogic/axg/axg_pm.c b/plat/amlogic/axg/axg_pm.c
new file mode 100644
index 000000000..e67f263a4
--- /dev/null
+++ b/plat/amlogic/axg/axg_pm.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <common/debug.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/console.h>
+#include <errno.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include "aml_private.h"
+
+#define SCPI_POWER_ON 0
+#define SCPI_POWER_RETENTION 1
+#define SCPI_POWER_OFF 3
+
+#define SCPI_SYSTEM_SHUTDOWN 0
+#define SCPI_SYSTEM_REBOOT 1
+
+static uintptr_t axg_sec_entrypoint;
+
+static void axg_pm_set_reset_addr(u_register_t mpidr, uint64_t value)
+{
+ unsigned int core = plat_calc_core_pos(mpidr);
+ uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4);
+
+ mmio_write_64(cpu_mailbox_addr, value);
+}
+
+static void axg_pm_reset(u_register_t mpidr, uint32_t value)
+{
+ unsigned int core = plat_calc_core_pos(mpidr);
+ uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4) + 8;
+
+ mmio_write_32(cpu_mailbox_addr, value);
+}
+
+static void __dead2 axg_system_reset(void)
+{
+ u_register_t mpidr = read_mpidr_el1();
+ int ret;
+
+ INFO("BL31: PSCI_SYSTEM_RESET\n");
+
+ ret = aml_scpi_sys_power_state(SCPI_SYSTEM_REBOOT);
+ if (ret != 0) {
+ ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %i\n", ret);
+ panic();
+ }
+
+ axg_pm_reset(mpidr, 0);
+
+ wfi();
+
+ ERROR("BL31: PSCI_SYSTEM_RESET: Operation not handled\n");
+ panic();
+}
+
+static void __dead2 axg_system_off(void)
+{
+ u_register_t mpidr = read_mpidr_el1();
+ int ret;
+
+ INFO("BL31: PSCI_SYSTEM_OFF\n");
+
+ ret = aml_scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN);
+ if (ret != 0) {
+ ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %i\n", ret);
+ panic();
+ }
+
+ axg_pm_set_reset_addr(mpidr, 0);
+ axg_pm_reset(mpidr, 0);
+
+ dmbsy();
+ wfi();
+
+ ERROR("BL31: PSCI_SYSTEM_OFF: Operation not handled\n");
+ panic();
+}
+
+static int32_t axg_pwr_domain_on(u_register_t mpidr)
+{
+ axg_pm_set_reset_addr(mpidr, axg_sec_entrypoint);
+ aml_scpi_set_css_power_state(mpidr,
+ SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON);
+ dmbsy();
+ sev();
+
+ return PSCI_E_SUCCESS;
+}
+
+static void axg_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+ PLAT_LOCAL_STATE_OFF);
+
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+
+ axg_pm_set_reset_addr(read_mpidr_el1(), 0);
+}
+
+static void axg_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ u_register_t mpidr = read_mpidr_el1();
+ uint32_t system_state = SCPI_POWER_ON;
+ uint32_t cluster_state = SCPI_POWER_ON;
+
+ assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+ PLAT_LOCAL_STATE_OFF);
+
+ axg_pm_reset(mpidr, -1);
+
+ gicv2_cpuif_disable();
+
+ if (target_state->pwr_domain_state[MPIDR_AFFLVL2] ==
+ PLAT_LOCAL_STATE_OFF)
+ system_state = SCPI_POWER_OFF;
+
+ if (target_state->pwr_domain_state[MPIDR_AFFLVL1] ==
+ PLAT_LOCAL_STATE_OFF)
+ cluster_state = SCPI_POWER_OFF;
+
+
+ aml_scpi_set_css_power_state(mpidr,
+ SCPI_POWER_OFF, cluster_state,
+ system_state);
+}
+
+static void __dead2 axg_pwr_domain_pwr_down_wfi(const psci_power_state_t
+ *target_state)
+{
+ dsbsy();
+ axg_pm_reset(read_mpidr_el1(), 0);
+
+ for (;;)
+ wfi();
+}
+
+/*******************************************************************************
+ * Platform handlers and setup function.
+ ******************************************************************************/
+static const plat_psci_ops_t axg_ops = {
+ .pwr_domain_on = axg_pwr_domain_on,
+ .pwr_domain_on_finish = axg_pwr_domain_on_finish,
+ .pwr_domain_off = axg_pwr_domain_off,
+ .pwr_domain_pwr_down_wfi = axg_pwr_domain_pwr_down_wfi,
+ .system_off = axg_system_off,
+ .system_reset = axg_system_reset
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ axg_sec_entrypoint = sec_entrypoint;
+ *psci_ops = &axg_ops;
+ return 0;
+}
diff --git a/plat/amlogic/axg/include/platform_def.h b/plat/amlogic/axg/include/platform_def.h
new file mode 100644
index 000000000..c97687e36
--- /dev/null
+++ b/plat/amlogic/axg/include/platform_def.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <lib/utils_def.h>
+
+#include "../axg_def.h"
+
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+#define PLATFORM_STACK_SIZE UL(0x1000)
+
+#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4)
+#define PLATFORM_CLUSTER_COUNT U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER
+#define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT
+
+#define AML_PRIMARY_CPU U(0)
+
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(2)
+
+#define PLAT_SYS_CPU_CFG7 (U(1) << 25)
+#define PLAT_AO_TIMESTAMP_CNTL U(0x1ff)
+
+/* Local power state for power domains in Run state. */
+#define PLAT_LOCAL_STATE_RUN U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define PLAT_LOCAL_STATE_RET U(1)
+/* Local power state for power-down. Valid for CPU and cluster power domains. */
+#define PLAT_LOCAL_STATE_OFF U(2)
+
+/*
+ * Macros used to parse state information from State-ID if it is using the
+ * recommended encoding for State-ID.
+ */
+#define PLAT_LOCAL_PSTATE_WIDTH U(4)
+#define PLAT_LOCAL_PSTATE_MASK ((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_SHIFT U(6)
+#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT)
+
+/* Memory-related defines */
+#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32)
+
+#define MAX_MMAP_REGIONS 16
+#define MAX_XLAT_TABLES 8
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/amlogic/axg/platform.mk b/plat/amlogic/axg/platform.mk
new file mode 100644
index 000000000..3560b0cd1
--- /dev/null
+++ b/plat/amlogic/axg/platform.mk
@@ -0,0 +1,95 @@
+#
+# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include lib/xlat_tables_v2/xlat_tables.mk
+
+AML_PLAT := plat/amlogic
+AML_PLAT_SOC := ${AML_PLAT}/${PLAT}
+AML_PLAT_COMMON := ${AML_PLAT}/common
+
+DOIMAGEPATH ?= tools/amlogic
+DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage
+
+PLAT_INCLUDES := -Iinclude/drivers/amlogic/ \
+ -I${AML_PLAT_SOC}/include \
+ -I${AML_PLAT_COMMON}/include
+
+GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
+ drivers/arm/gic/v2/gicv2_main.c \
+ drivers/arm/gic/v2/gicv2_helpers.c \
+ plat/common/plat_gicv2.c
+
+BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
+ plat/common/plat_psci_common.c \
+ drivers/amlogic/console/aarch64/meson_console.S \
+ ${AML_PLAT_SOC}/${PLAT}_bl31_setup.c \
+ ${AML_PLAT_SOC}/${PLAT}_pm.c \
+ ${AML_PLAT_SOC}/${PLAT}_common.c \
+ ${AML_PLAT_COMMON}/aarch64/aml_helpers.S \
+ ${AML_PLAT_COMMON}/aml_efuse.c \
+ ${AML_PLAT_COMMON}/aml_mhu.c \
+ ${AML_PLAT_COMMON}/aml_scpi.c \
+ ${AML_PLAT_COMMON}/aml_sip_svc.c \
+ ${AML_PLAT_COMMON}/aml_thermal.c \
+ ${AML_PLAT_COMMON}/aml_topology.c \
+ ${AML_PLAT_COMMON}/aml_console.c \
+ drivers/amlogic/crypto/sha_dma.c \
+ ${XLAT_TABLES_LIB_SRCS} \
+ ${GIC_SOURCES}
+
+# Tune compiler for Cortex-A53
+ifeq ($(notdir $(CC)),armclang)
+ TF_CFLAGS_aarch64 += -mcpu=cortex-a53
+else ifneq ($(findstring clang,$(notdir $(CC))),)
+ TF_CFLAGS_aarch64 += -mcpu=cortex-a53
+else
+ TF_CFLAGS_aarch64 += -mtune=cortex-a53
+endif
+
+# Build config flags
+# ------------------
+
+# Enable all errata workarounds for Cortex-A53
+ERRATA_A53_855873 := 1
+ERRATA_A53_819472 := 1
+ERRATA_A53_824069 := 1
+ERRATA_A53_827319 := 1
+
+WORKAROUND_CVE_2017_5715 := 0
+
+# Have different sections for code and rodata
+SEPARATE_CODE_AND_RODATA := 1
+
+# Use Coherent memory
+USE_COHERENT_MEM := 1
+
+AML_USE_ATOS := 0
+$(eval $(call assert_boolean,AML_USE_ATOS))
+$(eval $(call add_define,AML_USE_ATOS))
+
+# Verify build config
+# -------------------
+
+ifneq (${RESET_TO_BL31}, 0)
+ $(error Error: ${PLAT} needs RESET_TO_BL31=0)
+endif
+
+ifeq (${ARCH},aarch32)
+ $(error Error: AArch32 not supported on ${PLAT})
+endif
+
+all: ${BUILD_PLAT}/bl31.img
+distclean realclean clean: cleanimage
+
+cleanimage:
+ ${Q}${MAKE} -C ${DOIMAGEPATH} clean
+
+${DOIMAGETOOL}:
+ ${Q}${MAKE} -C ${DOIMAGEPATH}
+
+${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL}
+ ${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img
+
diff --git a/plat/amlogic/common/aarch64/aml_helpers.S b/plat/amlogic/common/aarch64/aml_helpers.S
index 39bff0833..159c7d17f 100644
--- a/plat/amlogic/common/aarch64/aml_helpers.S
+++ b/plat/amlogic/common/aarch64/aml_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -78,8 +78,8 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush()
- * Out : return -1 on error else return 0.
+ * void plat_crash_console_flush()
+ * Out : void.
* Clobber list : x0, x1
* ---------------------------------------------
*/
diff --git a/plat/amlogic/common/aml_console.c b/plat/amlogic/common/aml_console.c
index 352279b6c..e21d707a0 100644
--- a/plat/amlogic/common/aml_console.c
+++ b/plat/amlogic/common/aml_console.c
@@ -11,7 +11,7 @@
/*******************************************************************************
* Function that sets up the console
******************************************************************************/
-static console_meson_t aml_console;
+static console_t aml_console;
void aml_console_init(void)
{
@@ -28,6 +28,6 @@ void aml_console_init(void)
panic();
}
- console_set_scope(&aml_console.console,
+ console_set_scope(&aml_console,
CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
}
diff --git a/plat/arm/board/a5ds/a5ds_err.c b/plat/arm/board/a5ds/a5ds_err.c
index 65b41dd4c..feb9fdfaa 100644
--- a/plat/arm/board/a5ds/a5ds_err.c
+++ b/plat/arm/board/a5ds/a5ds_err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,7 @@
*/
void __dead2 plat_arm_error_handler(int err)
{
- while (1) {
+ while (true) {
wfi();
}
}
diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
new file mode 100644
index 000000000..b9ff8bff1
--- /dev/null
+++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x2001300>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x83000000>;
+ max-size = <0x01000000>;
+ id = <HW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
index 7b3aa1144..c66186f64 100644
--- a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
+++ b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,11 +7,9 @@
/dts-v1/;
/ {
- /* Platform Config */
- plat_arm_bl2 {
+ tb_fw-config {
compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x83000000>;
- hw_config_max_size = <0x01000000>;
+
/* Disable authentication for development */
disable_auth = <0x0>;
};
diff --git a/plat/arm/board/a5ds/include/platform_def.h b/plat/arm/board/a5ds/include/platform_def.h
index 31dfb1cf1..792a754fa 100644
--- a/plat/arm/board/a5ds/include/platform_def.h
+++ b/plat/arm/board/a5ds/include/platform_def.h
@@ -11,6 +11,7 @@
#include <lib/utils_def.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/smccc_def.h>
#include <plat/common/common_def.h>
/* Memory location options for TSP */
@@ -151,10 +152,18 @@
#endif
/*
+ * Map the region for device tree configuration with read and write permissions
+ */
+#define ARM_MAP_BL_CONFIG_REGION MAP_REGION_FLAT(ARM_BL_RAM_BASE, \
+ (ARM_FW_CONFIGS_LIMIT \
+ - ARM_BL_RAM_BASE), \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+/*
* The max number of regions like RO(code), coherent and data required by
* different BL stages which need to be mapped in the MMU.
*/
-#define ARM_BL_REGIONS 5
+#define ARM_BL_REGIONS 6
#define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \
ARM_BL_REGIONS)
@@ -187,11 +196,17 @@
#define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT)
/*
- * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base
+ * To enable FW_CONFIG to be loaded by BL1, define the corresponding base
* and limit. Leave enough space of BL2 meminfo.
*/
-#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t))
-#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE)
+#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t))
+#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE)
+
+/*
+ * Define limit of firmware configuration memory:
+ * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory
+ */
+#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2))
/*******************************************************************************
* BL1 specific defines.
@@ -219,7 +234,9 @@
#define BL2_LIMIT BL1_RW_BASE
/* Put BL32 below BL2 in NS DRAM.*/
-#define ARM_BL2_MEM_DESC_BASE ARM_TB_FW_CONFIG_LIMIT
+#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT
+#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE \
+ + (PAGE_SIZE / 2U))
#define BL32_BASE ((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)\
- PLAT_ARM_MAX_BL32_SIZE)
diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk
index d42b2bfa8..8b0dc5cf3 100644
--- a/plat/arm/board/a5ds/platform.mk
+++ b/plat/arm/board/a5ds/platform.mk
@@ -1,9 +1,12 @@
#
-# Copyright (c) 2019, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
+# Firmware Configuration Framework sources
+include lib/fconf/fconf.mk
+
# Add `libfdt` and Arm common helpers required for Dynamic Config
include lib/libfdt/libfdt.mk
@@ -11,9 +14,10 @@ DYN_CFG_SOURCES += plat/arm/common/arm_dyn_cfg.c \
plat/arm/common/arm_dyn_cfg_helpers.c \
common/fdt_wrappers.c
-A5DS_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
+# Include GICv2 driver files
+include drivers/arm/gic/v2/gicv2.mk
+
+A5DS_GIC_SOURCES := ${GICV2_SOURCES} \
plat/common/plat_gicv2.c \
plat/arm/common/arm_gicv2.c
@@ -38,6 +42,7 @@ BL1_SOURCES += drivers/io/io_fip.c \
plat/arm/common/arm_err.c \
plat/arm/board/a5ds/a5ds_err.c \
plat/arm/common/arm_io_storage.c \
+ plat/arm/common/fconf/arm_fconf_io.c \
plat/arm/board/a5ds/${ARCH}/a5ds_helpers.S \
plat/arm/board/a5ds/a5ds_bl1_setup.c \
lib/aarch32/arm32_aeabi_divmod.c \
@@ -58,6 +63,7 @@ BL2_SOURCES += lib/aarch32/arm32_aeabi_divmod.c \
plat/arm/common/arm_err.c \
plat/arm/board/a5ds/a5ds_err.c \
plat/arm/common/arm_io_storage.c \
+ plat/arm/common/fconf/arm_fconf_io.c \
plat/arm/common/${ARCH}/arm_bl2_mem_params_desc.c \
plat/arm/common/arm_image_load.c \
common/desc_image_load.c \
@@ -67,17 +73,21 @@ BL2_SOURCES += lib/aarch32/arm32_aeabi_divmod.c \
# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
ifdef UNIX_MK
-FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb
+FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
$(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \
fdts/$(notdir ${FVP_HW_CONFIG_DTS})))
# Add the HW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG}))
-FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \
+FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \
+ plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \
${FVP_HW_CONFIG_DTS}
endif
diff --git a/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S
new file mode 100644
index 000000000..20120c9c3
--- /dev/null
+++ b/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include "../fpga_private.h"
+
+#include <platform_def.h>
+
+ .globl plat_get_my_entrypoint
+ .globl plat_secondary_cold_boot_setup
+ .globl plat_is_my_cpu_primary
+ .globl platform_mem_init
+ .globl plat_my_core_pos
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_crash_console_flush
+ .globl plat_fpga_calc_core_pos
+
+/* -----------------------------------------------------------------------
+ * Indicate a cold boot for every CPU - warm boot is unsupported for the
+ * holding pen PSCI implementation.
+ * -----------------------------------------------------------------------
+ */
+func plat_get_my_entrypoint
+ mov x0, #0
+ ret
+endfunc plat_get_my_entrypoint
+
+/* -----------------------------------------------------------------------
+ * void plat_secondary_cold_boot_setup (void);
+ * -----------------------------------------------------------------------
+ */
+func plat_secondary_cold_boot_setup
+
+ /*
+ * Wait for the primary processor to initialise the .BSS segment
+ * to avoid a race condition that would erase fpga_valid_mpids
+ * if it is populated before the C runtime is ready.
+ *
+ * We cannot use the current spin-lock implementation until the
+ * runtime is up and we should not rely on sevl/wfe instructions as
+ * it is optional whether they are implemented or not, so we use
+ * a global variable as lock and wait for the primary processor to
+ * finish the C runtime bring-up.
+ */
+
+ ldr w0, =C_RUNTIME_READY_KEY
+ adrp x1, secondary_core_spinlock
+ add x1, x1, :lo12:secondary_core_spinlock
+1:
+ wfe
+ ldr w2, [x1]
+ cmp w2, w0
+ b.ne 1b
+ /* Prevent reordering of the store into fpga_valid_mpids below */
+ dmb ish
+
+ mov x10, x30
+ bl plat_my_core_pos
+ mov x30, x10
+
+ adrp x4, fpga_valid_mpids
+ add x4, x4, :lo12:fpga_valid_mpids
+ mov x5, #VALID_MPID
+ strb w5, [x4, x0]
+
+ /*
+ * Poll the CPU's hold entry until it indicates to jump
+ * to the entrypoint address.
+ */
+
+ adrp x1, hold_base
+ add x1, x1, :lo12:hold_base
+poll_hold_entry:
+ ldr x3, [x1, x0, LSL #PLAT_FPGA_HOLD_ENTRY_SHIFT]
+ cmp x3, #PLAT_FPGA_HOLD_STATE_GO
+ b.ne 1f
+
+ adrp x2, fpga_sec_entrypoint
+ add x2, x2, :lo12:fpga_sec_entrypoint
+ ldr x3, [x2]
+ br x3
+1:
+ wfe
+ b poll_hold_entry
+
+endfunc plat_secondary_cold_boot_setup
+
+/* -----------------------------------------------------------------------
+ * unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary cpu
+ * -----------------------------------------------------------------------
+ */
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ mov_imm x1, MPIDR_AFFINITY_MASK
+ and x0, x0, x1
+ cmp x0, #FPGA_PRIMARY_CPU
+ cset w0, eq
+ ret
+endfunc plat_is_my_cpu_primary
+
+func platform_mem_init
+ ret
+endfunc platform_mem_init
+
+func plat_my_core_pos
+ ldr x1, =(MPID_MASK & ~(MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT))
+ mrs x0, mpidr_el1
+ and x0, x0, x1
+ b plat_fpga_calc_core_pos
+
+endfunc plat_my_core_pos
+
+/* -----------------------------------------------------------------------
+ * unsigned int plat_fpga_calc_core_pos (uint32_t mpid)
+ * Clobber registers: x0 to x5
+ * -----------------------------------------------------------------------
+ */
+func plat_fpga_calc_core_pos
+ /*
+ * Check for MT bit in MPIDR, which may be either value for images
+ * running on the FPGA.
+ *
+ * If not set, shift MPIDR to left to make it look as if in a
+ * multi-threaded implementation.
+ *
+ */
+ tst x0, #MPIDR_MT_MASK
+ lsl x3, x0, #MPIDR_AFFINITY_BITS
+ csel x3, x3, x0, eq
+
+ /* Extract individual affinity fields from MPIDR */
+ ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+
+ mov x4, #FPGA_MAX_CPUS_PER_CLUSTER
+ mov x5, #FPGA_MAX_PE_PER_CPU
+
+ /* Compute linear position */
+ madd x1, x2, x4, x1
+ madd x0, x1, x5, x0
+
+ ret
+endfunc plat_fpga_calc_core_pos
+
+func plat_crash_console_init
+ mov_imm x0, PLAT_FPGA_CRASH_UART_BASE
+ b console_pl011_core_init
+endfunc plat_crash_console_init
+
+func plat_crash_console_putc
+ mov_imm x1, PLAT_FPGA_CRASH_UART_BASE
+ b console_pl011_core_putc
+endfunc plat_crash_console_putc
+
+func plat_crash_console_flush
+ mov_imm x0, PLAT_FPGA_CRASH_UART_BASE
+ b console_pl011_core_flush
+endfunc plat_crash_console_flush
diff --git a/plat/arm/board/arm_fpga/build_axf.ld.S b/plat/arm/board/arm_fpga/build_axf.ld.S
new file mode 100644
index 000000000..d7cd00882
--- /dev/null
+++ b/plat/arm/board/arm_fpga/build_axf.ld.S
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Linker script for the Arm Ltd. FPGA boards to generate an ELF file that
+ * contains the ROM trampoline, BL31 and the DTB.
+ *
+ * This allows to pass just one file to the uploader tool, and automatically
+ * provides the correct load addresses.
+ */
+
+#include <platform_def.h>
+
+OUTPUT_FORMAT("elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+
+INPUT(./bl31/bl31.elf)
+INPUT(./rom_trampoline.o)
+
+TARGET(binary)
+INPUT(./fdts/arm_fpga.dtb)
+
+ENTRY(_start)
+
+SECTIONS
+{
+ .rom (0x0): {
+ *rom_trampoline.o(.text*)
+ KEEP(*(.rom))
+ }
+
+ .bl31 (BL31_BASE): {
+ ASSERT(. == ALIGN(PAGE_SIZE), "BL31_BASE is not page aligned");
+ *bl31.elf(.text* .data* .rodata* ro* .bss*)
+ *bl31.elf(.stack)
+ }
+
+ .dtb (FPGA_PRELOADED_DTB_BASE): {
+ ASSERT(. == ALIGN(8), "DTB address is not 8-byte aligned");
+ *arm_fpga.dtb
+ }
+
+ /DISCARD/ : { *(.debug_*) }
+ /DISCARD/ : { *(.note*) }
+ /DISCARD/ : { *(.comment*) }
+}
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
new file mode 100644
index 000000000..a5f5ea0f3
--- /dev/null
+++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/delay_timer.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/extensions/spe.h>
+#include <libfdt.h>
+
+#include "fpga_private.h"
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+static entry_point_info_t bl33_image_ep_info;
+volatile uint32_t secondary_core_spinlock;
+
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+ return PRELOADED_BL33_BASE;
+#else
+ return 0ULL;
+#endif
+}
+
+uint32_t fpga_get_spsr_for_bl33_entry(void)
+{
+ return SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ /* Add this core to the VALID mpids list */
+ fpga_valid_mpids[plat_my_core_pos()] = VALID_MPID;
+
+ /*
+ * Notify the secondary CPUs that the C runtime is ready
+ * so they can announce themselves.
+ */
+ secondary_core_spinlock = C_RUNTIME_READY_KEY;
+ dsbish();
+ sev();
+
+ fpga_console_init();
+
+ bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+ bl33_image_ep_info.spsr = fpga_get_spsr_for_bl33_entry();
+ SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+ /* Set x0-x3 for the primary CPU as expected by the kernel */
+ bl33_image_ep_info.args.arg0 = (u_register_t)FPGA_PRELOADED_DTB_BASE;
+ bl33_image_ep_info.args.arg1 = 0U;
+ bl33_image_ep_info.args.arg2 = 0U;
+ bl33_image_ep_info.args.arg3 = 0U;
+}
+
+void bl31_plat_arch_setup(void)
+{
+}
+
+void bl31_platform_setup(void)
+{
+ /* Write frequency to CNTCRL and initialize timer */
+ generic_delay_timer_init();
+
+ /*
+ * Before doing anything else, wait for some time to ensure that
+ * the secondary CPUs have populated the fpga_valid_mpids array.
+ * As the number of secondary cores is unknown and can even be 0,
+ * it is not possible to rely on any signal from them, so use a
+ * delay instead.
+ */
+ mdelay(5);
+
+ /*
+ * On the event of a cold reset issued by, for instance, a reset pin
+ * assertion, we cannot guarantee memory to be initialized to zero.
+ * In such scenario, if the secondary cores reached
+ * plat_secondary_cold_boot_setup before the primary one initialized
+ * .BSS, we could end up having a race condition if the spinlock
+ * was not cleared before.
+ *
+ * Similarly, if there were a reset before the spinlock had been
+ * cleared, the secondary cores would find the lock opened before
+ * .BSS is cleared, causing another race condition.
+ *
+ * So clean the spinlock as soon as we think it is safe to reduce the
+ * chances of any race condition on a reset.
+ */
+ secondary_core_spinlock = 0UL;
+
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ plat_fpga_gic_init();
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+ entry_point_info_t *next_image_info;
+ next_image_info = &bl33_image_ep_info;
+
+ /* Only expecting BL33: the kernel will run in EL2NS */
+ assert(type == NON_SECURE);
+
+ /* None of the images can have 0x0 as the entrypoint */
+ if (next_image_info->pc) {
+ return next_image_info;
+ } else {
+ return NULL;
+ }
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
+ int node;
+
+ node = fdt_node_offset_by_compatible(fdt, 0, "arm,armv8-timer");
+ if (node < 0) {
+ return FPGA_DEFAULT_TIMER_FREQUENCY;
+ }
+
+ return fdt_read_uint32_default(fdt, node, "clock-frequency",
+ FPGA_DEFAULT_TIMER_FREQUENCY);
+}
+
+static void fpga_prepare_dtb(void)
+{
+ void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
+ const char *cmdline = (void *)(uintptr_t)FPGA_PRELOADED_CMD_LINE;
+ int err;
+
+ err = fdt_open_into(fdt, fdt, FPGA_MAX_DTB_SIZE);
+ if (err < 0) {
+ ERROR("cannot open devicetree at %p: %d\n", fdt, err);
+ panic();
+ }
+
+ /* Check for the command line signature. */
+ if (!strncmp(cmdline, "CMD:", 4)) {
+ int chosen;
+
+ INFO("using command line at 0x%x\n", FPGA_PRELOADED_CMD_LINE);
+
+ chosen = fdt_add_subnode(fdt, 0, "chosen");
+ if (chosen == -FDT_ERR_EXISTS) {
+ chosen = fdt_path_offset(fdt, "/chosen");
+ }
+ if (chosen < 0) {
+ ERROR("cannot find /chosen node: %d\n", chosen);
+ } else {
+ const char *eol;
+ char nul = 0;
+ int slen;
+
+ /*
+ * There is most likely an EOL at the end of the
+ * command line, make sure we terminate the line there.
+ * We can't replace the EOL with a NUL byte in the
+ * source, as this is in read-only memory. So we first
+ * create the property without any termination, then
+ * append a single NUL byte.
+ */
+ eol = strchr(cmdline, '\n');
+ if (!eol) {
+ eol = strchr(cmdline, 0);
+ }
+ /* Skip the signature and omit the EOL/NUL byte. */
+ slen = eol - (cmdline + 4);
+
+ /*
+ * Let's limit the size of the property, just in case
+ * we find the signature by accident. The Linux kernel
+ * limits to 4096 characters at most (in fact 2048 for
+ * arm64), so that sounds like a reasonable number.
+ */
+ if (slen > 4095) {
+ slen = 4095;
+ }
+ err = fdt_setprop(fdt, chosen, "bootargs",
+ cmdline + 4, slen);
+ if (!err) {
+ err = fdt_appendprop(fdt, chosen, "bootargs",
+ &nul, 1);
+ }
+ if (err) {
+ ERROR("Could not set command line: %d\n", err);
+ }
+ }
+ }
+
+ if (err < 0) {
+ ERROR("Error %d extending Device Tree\n", err);
+ panic();
+ }
+
+ err = fdt_add_cpus_node(fdt, FPGA_MAX_PE_PER_CPU,
+ FPGA_MAX_CPUS_PER_CLUSTER,
+ FPGA_MAX_CLUSTER_COUNT);
+
+ if (err == -EEXIST) {
+ WARN("Not overwriting already existing /cpus node in DTB\n");
+ } else {
+ if (err < 0) {
+ ERROR("Error %d creating the /cpus DT node\n", err);
+ panic();
+ } else {
+ unsigned int nr_cores = fpga_get_nr_gic_cores();
+
+ INFO("Adjusting GICR DT region to cover %u cores\n",
+ nr_cores);
+ err = fdt_adjust_gic_redist(fdt, nr_cores,
+ 1U << GICR_PCPUBASE_SHIFT);
+ if (err < 0) {
+ ERROR("Error %d fixing up GIC DT node\n", err);
+ }
+ }
+ }
+
+ /* Check whether we support the SPE PMU. Remove the DT node if not. */
+ if (!spe_supported()) {
+ int node = fdt_node_offset_by_compatible(fdt, 0,
+ "arm,statistical-profiling-extension-v1");
+
+ if (node >= 0) {
+ fdt_del_node(fdt, node);
+ }
+ }
+
+ err = fdt_pack(fdt);
+ if (err < 0) {
+ ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, err);
+ }
+
+ clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt));
+}
+
+void bl31_plat_runtime_setup(void)
+{
+ fpga_prepare_dtb();
+}
+
+void bl31_plat_enable_mmu(uint32_t flags)
+{
+ /* TODO: determine if MMU needs to be enabled */
+}
diff --git a/plat/arm/board/arm_fpga/fpga_console.c b/plat/arm/board/arm_fpga/fpga_console.c
new file mode 100644
index 000000000..8c1da62e2
--- /dev/null
+++ b/plat/arm/board/arm_fpga/fpga_console.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <common/fdt_wrappers.h>
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+
+#include <platform_def.h>
+
+static console_t console;
+
+void fpga_console_init(void)
+{
+ const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
+ uintptr_t base_addr = PLAT_FPGA_CRASH_UART_BASE;
+ int node;
+
+ /*
+ * Try to read the UART base address from the DT, by chasing the
+ * stdout-path property of the chosen node.
+ * If this does not work, use the crash console address as a fallback.
+ */
+ node = fdt_get_stdout_node_offset(fdt);
+ if (node >= 0) {
+ fdt_get_reg_props_by_index(fdt, node, 0, &base_addr, NULL);
+ }
+
+ (void)console_pl011_register(base_addr, 0, 0, &console);
+
+ console_set_scope(&console, CONSOLE_FLAG_BOOT |
+ CONSOLE_FLAG_RUNTIME);
+}
diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h
new file mode 100644
index 000000000..2884ea6d4
--- /dev/null
+++ b/plat/arm/board/arm_fpga/fpga_def.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/utils_def.h>
+
+#ifndef FPGA_DEF_H
+#define FPGA_DEF_H
+
+/*
+ * These are set to large values to account for images describing systems with
+ * larger cluster configurations.
+ *
+ * For cases where the number of clusters, cores or threads is smaller than a
+ * maximum value below, this does not affect the PSCI functionality as any PEs
+ * that are present will still be indexed appropriately regardless of any empty
+ * entries in the array used to represent the topology.
+ */
+
+#define FPGA_MAX_CLUSTER_COUNT 4
+#define FPGA_MAX_CPUS_PER_CLUSTER 8
+#define FPGA_MAX_PE_PER_CPU 4
+
+#define FPGA_PRIMARY_CPU 0x0
+/*******************************************************************************
+ * FPGA image memory map related constants
+ ******************************************************************************/
+
+/*
+ * UART base address, just for the crash console, as a fallback.
+ * The actual console UART address is taken from the DT.
+ */
+#define PLAT_FPGA_CRASH_UART_BASE 0x7ff80000
+
+#define FPGA_DEFAULT_TIMER_FREQUENCY 10000000
+
+#endif
diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c
new file mode 100644
index 000000000..bfc116bef
--- /dev/null
+++ b/plat/arm/board/arm_fpga/fpga_gicv3.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/arm/gic_common.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+static const interrupt_prop_t fpga_interrupt_props[] = {
+ PLATFORM_G1S_PROPS(INTR_GROUP1S),
+ PLATFORM_G0_PROPS(INTR_GROUP0)
+};
+
+static uintptr_t fpga_rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+static unsigned int fpga_mpidr_to_core_pos(unsigned long mpidr)
+{
+ return (unsigned int)plat_core_pos_by_mpidr(mpidr);
+}
+
+static gicv3_driver_data_t fpga_gicv3_driver_data = {
+ .interrupt_props = fpga_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(fpga_interrupt_props),
+ .rdistif_num = PLATFORM_CORE_COUNT,
+ .rdistif_base_addrs = fpga_rdistif_base_addrs,
+ .mpidr_to_core_pos = fpga_mpidr_to_core_pos
+};
+
+void plat_fpga_gic_init(void)
+{
+ const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
+ int node, ret;
+
+ node = fdt_node_offset_by_compatible(fdt, 0, "arm,gic-v3");
+ if (node < 0) {
+ WARN("No \"arm,gic-v3\" compatible node found in DT, no GIC support.\n");
+ return;
+ }
+
+ /* TODO: Assuming only empty "ranges;" properties up the bus path. */
+ ret = fdt_get_reg_props_by_index(fdt, node, 0,
+ &fpga_gicv3_driver_data.gicd_base, NULL);
+ if (ret < 0) {
+ WARN("Could not read GIC distributor address from DT.\n");
+ return;
+ }
+
+ ret = fdt_get_reg_props_by_index(fdt, node, 1,
+ &fpga_gicv3_driver_data.gicr_base, NULL);
+ if (ret < 0) {
+ WARN("Could not read GIC redistributor address from DT.\n");
+ return;
+ }
+
+ gicv3_driver_init(&fpga_gicv3_driver_data);
+ gicv3_distif_init();
+ gicv3_rdistif_init(plat_my_core_pos());
+ gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+void fpga_pwr_gic_on_finish(void)
+{
+ gicv3_rdistif_init(plat_my_core_pos());
+ gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+void fpga_pwr_gic_off(void)
+{
+ gicv3_cpuif_disable(plat_my_core_pos());
+ gicv3_rdistif_off(plat_my_core_pos());
+}
+
+unsigned int fpga_get_nr_gic_cores(void)
+{
+ return gicv3_rdistif_get_number_frames(fpga_gicv3_driver_data.gicr_base);
+}
diff --git a/plat/arm/board/arm_fpga/fpga_pm.c b/plat/arm/board/arm_fpga/fpga_pm.c
new file mode 100644
index 000000000..a306a23d4
--- /dev/null
+++ b/plat/arm/board/arm_fpga/fpga_pm.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+#include "fpga_private.h"
+#include <platform_def.h>
+
+/*
+ * This is a basic PSCI implementation that allows secondary CPUs to be
+ * released from their initial state and continue to the warm boot entrypoint.
+ *
+ * The secondary CPUs are placed in a holding pen and released by calls
+ * to fpga_pwr_domain_on(mpidr), which updates the hold entry for the CPU
+ * specified by the mpidr argument - the (polling) target CPU will then branch
+ * to the BL31 warm boot sequence at the entrypoint address.
+ *
+ * Additionally, the secondary CPUs are kept in a low-power wfe() state
+ * (placed there at the end of each poll) and woken when necessary through
+ * calls to sev() in fpga_pwr_domain_on(mpidr), once the hold state for the
+ * relevant CPU has been updated.
+ *
+ * Hotplug is currently implemented using a wfi-loop, which removes the
+ * dependencies on any power controllers or other mechanism that is specific
+ * to the running system as specified by the FPGA image.
+ */
+
+uint64_t hold_base[PLATFORM_CORE_COUNT];
+uintptr_t fpga_sec_entrypoint;
+
+/*
+ * Calls to the CPU specified by the mpidr will set its hold entry to a value
+ * indicating that it should stop polling and branch off to the warm entrypoint.
+ */
+static int fpga_pwr_domain_on(u_register_t mpidr)
+{
+ int pos = plat_core_pos_by_mpidr(mpidr);
+ unsigned long current_mpidr = read_mpidr_el1();
+
+ if (pos < 0) {
+ panic();
+ }
+
+ if (mpidr == current_mpidr) {
+ return PSCI_E_ALREADY_ON;
+ }
+ hold_base[pos] = PLAT_FPGA_HOLD_STATE_GO;
+ flush_dcache_range((uintptr_t)&hold_base[pos], sizeof(uint64_t));
+ sev(); /* Wake any CPUs from wfe */
+
+ return PSCI_E_SUCCESS;
+}
+
+void fpga_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ fpga_pwr_gic_on_finish();
+}
+
+static void fpga_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ fpga_pwr_gic_off();
+
+ while (1) {
+ wfi();
+ }
+}
+
+static void fpga_cpu_standby(plat_local_state_t cpu_state)
+{
+ /*
+ * Enter standby state
+ * dsb is good practice before using wfi to enter low power states
+ */
+ u_register_t scr = read_scr_el3();
+ write_scr_el3(scr|SCR_IRQ_BIT);
+ dsb();
+ wfi();
+ write_scr_el3(scr);
+}
+
+plat_psci_ops_t plat_fpga_psci_pm_ops = {
+ .pwr_domain_on = fpga_pwr_domain_on,
+ .pwr_domain_on_finish = fpga_pwr_domain_on_finish,
+ .pwr_domain_off = fpga_pwr_domain_off,
+ .cpu_standby = fpga_cpu_standby
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ fpga_sec_entrypoint = sec_entrypoint;
+ flush_dcache_range((uint64_t)&fpga_sec_entrypoint,
+ sizeof(fpga_sec_entrypoint));
+ *psci_ops = &plat_fpga_psci_pm_ops;
+ return 0;
+}
diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h
new file mode 100644
index 000000000..1ca241f26
--- /dev/null
+++ b/plat/arm/board/arm_fpga/fpga_private.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FPGA_PRIVATE_H
+#define FPGA_PRIVATE_H
+
+#include "../fpga_def.h"
+#include <platform_def.h>
+
+#define C_RUNTIME_READY_KEY (0xaa55aa55)
+#define VALID_MPID (1U)
+#define FPGA_MAX_DTB_SIZE 0x10000
+
+#ifndef __ASSEMBLER__
+
+extern unsigned char fpga_valid_mpids[PLATFORM_CORE_COUNT];
+
+void fpga_console_init(void);
+
+void plat_fpga_gic_init(void);
+void fpga_pwr_gic_on_finish(void);
+void fpga_pwr_gic_off(void);
+unsigned int plat_fpga_calc_core_pos(uint32_t mpid);
+unsigned int fpga_get_nr_gic_cores(void);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* FPGA_PRIVATE_H */
diff --git a/plat/arm/board/arm_fpga/fpga_topology.c b/plat/arm/board/arm_fpga/fpga_topology.c
new file mode 100644
index 000000000..7fead869b
--- /dev/null
+++ b/plat/arm/board/arm_fpga/fpga_topology.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/spinlock.h>
+
+#include "fpga_private.h"
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+unsigned char fpga_power_domain_tree_desc[FPGA_MAX_CLUSTER_COUNT + 2];
+unsigned char fpga_valid_mpids[PLATFORM_CORE_COUNT];
+
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ unsigned int i;
+
+ /*
+ * The highest level is the system level. The next level is constituted
+ * by clusters and then cores in clusters.
+ *
+ * This description of the power domain topology is aligned with the CPU
+ * indices returned by the plat_core_pos_by_mpidr() and plat_my_core_pos()
+ * APIs.
+ *
+ * A description of the topology tree can be found at
+ * https://trustedfirmware-a.readthedocs.io/en/latest/design/psci-pd-tree.html#design
+ */
+
+ if (fpga_power_domain_tree_desc[0] == 0U) {
+ /*
+ * As fpga_power_domain_tree_desc[0] == 0, assume that the
+ * Power Domain Topology Tree has not been initialized, so
+ * perform the initialization here.
+ */
+
+ fpga_power_domain_tree_desc[0] = 1U;
+ fpga_power_domain_tree_desc[1] = FPGA_MAX_CLUSTER_COUNT;
+
+ for (i = 0U; i < FPGA_MAX_CLUSTER_COUNT; i++) {
+ fpga_power_domain_tree_desc[2 + i] =
+ (FPGA_MAX_CPUS_PER_CLUSTER *
+ FPGA_MAX_PE_PER_CPU);
+ }
+ }
+
+ return fpga_power_domain_tree_desc;
+}
+
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+ unsigned int core_pos;
+
+ mpidr &= (MPID_MASK & ~(MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT));
+ mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
+
+ if ((MPIDR_AFFLVL2_VAL(mpidr) >= FPGA_MAX_CLUSTER_COUNT) ||
+ (MPIDR_AFFLVL1_VAL(mpidr) >= FPGA_MAX_CPUS_PER_CLUSTER) ||
+ (MPIDR_AFFLVL0_VAL(mpidr) >= FPGA_MAX_PE_PER_CPU)) {
+ ERROR ("Invalid mpidr: 0x%08x\n", (uint32_t)mpidr);
+ panic();
+ }
+
+ /* Calculate the core position, based on the maximum topology. */
+ core_pos = plat_fpga_calc_core_pos(mpidr);
+
+ /* Check whether this core is actually present. */
+ if (fpga_valid_mpids[core_pos] != VALID_MPID) {
+ return -1;
+ }
+
+ return core_pos;
+}
diff --git a/plat/arm/board/arm_fpga/include/plat_macros.S b/plat/arm/board/arm_fpga/include/plat_macros.S
new file mode 100644
index 000000000..44cddeb36
--- /dev/null
+++ b/plat/arm/board/arm_fpga/include/plat_macros.S
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+.macro plat_crash_print_regs
+.endm
+
+#endif
diff --git a/plat/arm/board/arm_fpga/include/platform_def.h b/plat/arm/board/arm_fpga/include/platform_def.h
new file mode 100644
index 000000000..411b936da
--- /dev/null
+++ b/plat/arm/board/arm_fpga/include/platform_def.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <plat/common/common_def.h>
+#include <platform_def.h>
+#include "../fpga_def.h"
+
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+
+#define PLATFORM_LINKER_ARCH aarch64
+
+#define PLATFORM_STACK_SIZE UL(0x800)
+
+#define CACHE_WRITEBACK_SHIFT U(6)
+#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT)
+
+#define PLATFORM_CORE_COUNT \
+ (FPGA_MAX_CLUSTER_COUNT * \
+ FPGA_MAX_CPUS_PER_CLUSTER * \
+ FPGA_MAX_PE_PER_CPU)
+
+#define PLAT_NUM_PWR_DOMAINS (FPGA_MAX_CLUSTER_COUNT + PLATFORM_CORE_COUNT + 1)
+
+#if !ENABLE_PIE
+#define BL31_BASE UL(0x80000000)
+#define BL31_LIMIT UL(0x80100000)
+#else
+#define BL31_BASE UL(0x0)
+#define BL31_LIMIT UL(0x01000000)
+#endif
+
+#define PLAT_SDEI_NORMAL_PRI 0x70
+
+#define ARM_IRQ_SEC_PHY_TIMER 29
+
+#define ARM_IRQ_SEC_SGI_0 8
+#define ARM_IRQ_SEC_SGI_1 9
+#define ARM_IRQ_SEC_SGI_2 10
+#define ARM_IRQ_SEC_SGI_3 11
+#define ARM_IRQ_SEC_SGI_4 12
+#define ARM_IRQ_SEC_SGI_5 13
+#define ARM_IRQ_SEC_SGI_6 14
+#define ARM_IRQ_SEC_SGI_7 15
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLATFORM_G1S_PROPS(grp) \
+ INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE)
+
+#define PLATFORM_G0_PROPS(grp) \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE)
+
+#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_OFF_STATE 2
+
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
+
+#define PLAT_FPGA_HOLD_ENTRY_SHIFT 3
+#define PLAT_FPGA_HOLD_STATE_WAIT 0
+#define PLAT_FPGA_HOLD_STATE_GO 1
+
+#endif
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
new file mode 100644
index 000000000..3ac1c01ab
--- /dev/null
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -0,0 +1,120 @@
+#
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include lib/libfdt/libfdt.mk
+
+RESET_TO_BL31 := 1
+ifeq (${RESET_TO_BL31}, 0)
+$(error "This is a BL31-only port; RESET_TO_BL31 must be enabled")
+endif
+
+ifeq (${ENABLE_PIE}, 1)
+override SEPARATE_CODE_AND_RODATA := 1
+endif
+
+CTX_INCLUDE_AARCH32_REGS := 0
+ifeq (${CTX_INCLUDE_AARCH32_REGS}, 1)
+$(error "This is an AArch64-only port; CTX_INCLUDE_AARCH32_REGS must be disabled")
+endif
+
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+$(error "TRUSTED_BOARD_BOOT must be disabled")
+endif
+
+PRELOADED_BL33_BASE := 0x80080000
+
+FPGA_PRELOADED_DTB_BASE := 0x80070000
+$(eval $(call add_define,FPGA_PRELOADED_DTB_BASE))
+
+FPGA_PRELOADED_CMD_LINE := 0x1000
+$(eval $(call add_define,FPGA_PRELOADED_CMD_LINE))
+
+# Treating this as a memory-constrained port for now
+USE_COHERENT_MEM := 0
+
+# This can be overridden depending on CPU(s) used in the FPGA image
+HW_ASSISTED_COHERENCY := 1
+
+PL011_GENERIC_UART := 1
+
+SUPPORT_UNKNOWN_MPID ?= 1
+
+FPGA_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S
+
+# select a different set of CPU files, depending on whether we compile for
+# hardware assisted coherency cores or not
+ifeq (${HW_ASSISTED_COHERENCY}, 0)
+# Cores used without DSU
+ FPGA_CPU_LIBS += lib/cpus/aarch64/cortex_a35.S \
+ lib/cpus/aarch64/cortex_a53.S \
+ lib/cpus/aarch64/cortex_a57.S \
+ lib/cpus/aarch64/cortex_a72.S \
+ lib/cpus/aarch64/cortex_a73.S
+else
+# AArch64-only cores
+ FPGA_CPU_LIBS += lib/cpus/aarch64/cortex_a76.S \
+ lib/cpus/aarch64/cortex_a76ae.S \
+ lib/cpus/aarch64/cortex_a77.S \
+ lib/cpus/aarch64/cortex_a78.S \
+ lib/cpus/aarch64/neoverse_n_common.S \
+ lib/cpus/aarch64/neoverse_n1.S \
+ lib/cpus/aarch64/neoverse_n2.S \
+ lib/cpus/aarch64/neoverse_e1.S \
+ lib/cpus/aarch64/neoverse_v1.S \
+ lib/cpus/aarch64/cortex_a78_ae.S \
+ lib/cpus/aarch64/cortex_a65.S \
+ lib/cpus/aarch64/cortex_a65ae.S \
+ lib/cpus/aarch64/cortex_klein.S \
+ lib/cpus/aarch64/cortex_matterhorn.S
+
+# AArch64/AArch32 cores
+ FPGA_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \
+ lib/cpus/aarch64/cortex_a75.S
+endif
+
+ifeq (${SUPPORT_UNKNOWN_MPID}, 1)
+# Add support for unknown/invalid MPIDs (aarch64 only)
+$(eval $(call add_define,SUPPORT_UNKNOWN_MPID))
+ FPGA_CPU_LIBS += lib/cpus/aarch64/generic.S
+endif
+
+# Allow detection of GIC-600
+GICV3_SUPPORT_GIC600 := 1
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+FPGA_GIC_SOURCES := ${GICV3_SOURCES} \
+ plat/common/plat_gicv3.c \
+ plat/arm/board/arm_fpga/fpga_gicv3.c
+
+FDT_SOURCES := fdts/arm_fpga.dts
+
+PLAT_INCLUDES := -Iplat/arm/board/arm_fpga/include
+
+PLAT_BL_COMMON_SOURCES := plat/arm/board/arm_fpga/${ARCH}/fpga_helpers.S
+
+BL31_SOURCES += common/fdt_wrappers.c \
+ common/fdt_fixup.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ drivers/arm/pl011/${ARCH}/pl011_console.S \
+ plat/common/plat_psci_common.c \
+ plat/arm/board/arm_fpga/fpga_pm.c \
+ plat/arm/board/arm_fpga/fpga_topology.c \
+ plat/arm/board/arm_fpga/fpga_console.c \
+ plat/arm/board/arm_fpga/fpga_bl31_setup.c \
+ ${FPGA_CPU_LIBS} \
+ ${FPGA_GIC_SOURCES}
+
+$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,31))
+$(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,31))
+
+bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/build_axf.ld
+ $(ECHO) " LD $@"
+ $(Q)$(LD) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} --strip-debug -o ${BUILD_PLAT}/bl31.axf
+
+all: bl31.axf
diff --git a/plat/arm/board/arm_fpga/rom_trampoline.S b/plat/arm/board/arm_fpga/rom_trampoline.S
new file mode 100644
index 000000000..cd66c7927
--- /dev/null
+++ b/plat/arm/board/arm_fpga/rom_trampoline.S
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * The Arm Ltd. FPGA images start execution at address 0x0, which is
+ * mapped at an (emulated) ROM image. The payload uploader can write to
+ * this memory, but write access by the CPU cores is prohibited.
+ *
+ * Provide a simple trampoline to start BL31 execution at the actual
+ * load address. We put the DTB address in x0, so any code in DRAM could
+ * make use of that information (not yet used in BL31 right now).
+ */
+
+#include <asm_macros.S>
+#include <common/bl_common.ld.h>
+
+.text
+.global _start
+
+_start:
+ mov_imm x1, BL31_BASE /* beginning of DRAM */
+ mov_imm x0, FPGA_PRELOADED_DTB_BASE
+ br x1
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index c71e932a0..66cc3e949 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,136 +8,180 @@
#include <stdint.h>
#include <string.h>
+#include <common/debug.h>
+#include <drivers/arm/cryptocell/cc_rotpk.h>
+#include <drivers/delay_timer.h>
#include <lib/cassert.h>
+#include <lib/fconf/fconf.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/common/fconf_nv_cntr_getter.h>
+#include <plat/common/common_def.h>
#include <plat/common/platform.h>
-#include <tools_share/tbbr_oid.h>
#include <platform_def.h>
-/* SHA256 algorithm */
-#define SHA256_BYTES 32
-
-/* ROTPK locations */
-#define ARM_ROTPK_REGS_ID 1
-#define ARM_ROTPK_DEVEL_RSA_ID 2
-#define ARM_ROTPK_DEVEL_ECDSA_ID 3
-
-static const unsigned char rotpk_hash_hdr[] = \
- "\x30\x31\x30\x0D\x06\x09\x60\x86\x48" \
- "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
-static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1;
-static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES];
+#if defined(ARM_COT_tbbr)
+#include <tools_share/tbbr_oid.h>
+#elif defined(ARM_COT_dualroot)
+#include <tools_share/dualroot_oid.h>
+#endif
-/* Use the cryptocell variants if Cryptocell is present */
#if !ARM_CRYPTOCELL_INTEG
#if !ARM_ROTPK_LOCATION_ID
#error "ARM_ROTPK_LOCATION_ID not defined"
#endif
+#endif
+
+#if COT_DESC_IN_DTB && defined(IMAGE_BL2)
+uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS];
+#else
+uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS] = {
+ TFW_NVCTR_BASE,
+ NTFW_CTR_BASE
+};
+#endif
+
/* Weak definition may be overridden in specific platform */
#pragma weak plat_get_nv_ctr
#pragma weak plat_set_nv_ctr
-#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
-static const unsigned char arm_devel_rotpk_hash[] = \
- "\xB0\xF3\x82\x09\x12\x97\xD8\x3A" \
- "\x37\x7A\x72\x47\x1B\xEC\x32\x73" \
- "\xE9\x92\x32\xE2\x49\x59\xF6\x5E" \
- "\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA";
-#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
-static const unsigned char arm_devel_rotpk_hash[] = \
- "\x2E\x40\xBF\x6E\xF9\x12\xBB\x98" \
- "\x31\x71\x09\x0E\x1E\x15\x3D\x0B" \
- "\xFD\xD1\xCC\x69\x4A\x98\xEB\x8B" \
- "\xA0\xB0\x20\x86\x4E\x6C\x07\x17";
+extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[];
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) || ARM_CRYPTOCELL_INTEG
+static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
#endif
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
/*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- * digestAlgorithm AlgorithmIdentifier,
- * digest OCTET STRING
- * }
+ * Return the ROTPK hash stored in dedicated registers.
*/
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
unsigned int *flags)
{
uint8_t *dst;
+ uint32_t *src, tmp;
+ unsigned int words, i;
assert(key_ptr != NULL);
assert(key_len != NULL);
assert(flags != NULL);
/* Copy the DER header */
- memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
- dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len];
-#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
- || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
- memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES);
-#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
- uint32_t *src, tmp;
- unsigned int words, i;
+ memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
+ dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
- /*
- * Append the hash from Trusted Root-Key Storage registers. The hash has
- * not been written linearly into the registers, so we have to do a bit
- * of byte swapping:
- *
- * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C
- * +---------------------------------------------------------------+
- * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 |
- * +---------------------------------------------------------------+
- * | ... ... | | ... ... |
- * | +--------------------+ | +-------+
- * | | | |
- * +----------------------------+ +----------------------------+
- * | | | |
- * +-------+ | +--------------------+ |
- * | | | |
- * v v v v
- * +---------------------------------------------------------------+
- * | | |
- * +---------------------------------------------------------------+
- * 0 15 16 31
- *
- * Additionally, we have to access the registers in 32-bit words
- */
- words = SHA256_BYTES >> 3;
+ words = ARM_ROTPK_HASH_LEN >> 2;
- /* Swap bytes 0-15 (first four registers) */
src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
for (i = 0 ; i < words ; i++) {
tmp = src[words - 1 - i];
/* Words are read in little endian */
- *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
- *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
- *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
*dst++ = (uint8_t)(tmp & 0xFF);
- }
-
- /* Swap bytes 16-31 (last four registers) */
- src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2);
- for (i = 0 ; i < words ; i++) {
- tmp = src[words - 1 - i];
- *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
- *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
- *dst++ = (uint8_t)(tmp & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
}
-#endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
- || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) */
*key_ptr = (void *)rotpk_hash_der;
*key_len = (unsigned int)sizeof(rotpk_hash_der);
*flags = ROTPK_IS_HASH;
return 0;
}
+#endif
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
+ (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+/*
+ * Return development ROTPK hash generated from ROT_KEY.
+ */
+int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ *key_ptr = arm_rotpk_header;
+ *key_len = arm_rotpk_hash_end - arm_rotpk_header;
+ *flags = ROTPK_IS_HASH;
+ return 0;
+}
+#endif
+
+#if ARM_CRYPTOCELL_INTEG
+/*
+ * Return ROTPK hash from CryptoCell.
+ */
+int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ unsigned char *dst;
+
+ assert(key_ptr != NULL);
+ assert(key_len != NULL);
+ assert(flags != NULL);
+
+ /* Copy the DER header */
+ memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
+ dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+ *key_ptr = rotpk_hash_der;
+ *key_len = sizeof(rotpk_hash_der);
+ return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags);
+}
+#endif
+
+/*
+ * Wrapper function for most Arm platforms to get ROTPK hash.
+ */
+static int get_rotpk_info(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+#if ARM_CRYPTOCELL_INTEG
+ return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
+#else
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
+ (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+ return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
+#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+ return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
+#else
+ return 1;
+#endif
+#endif /* ARM_CRYPTOCELL_INTEG */
+}
+
+#if defined(ARM_COT_tbbr)
+
+int arm_get_rotpk_info(void *cookie __unused, void **key_ptr,
+ unsigned int *key_len, unsigned int *flags)
+{
+ return get_rotpk_info(key_ptr, key_len, flags);
+}
+
+#elif defined(ARM_COT_dualroot)
+
+int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ /*
+ * Return the right root of trust key hash based on the cookie value:
+ * - NULL means the primary ROTPK.
+ * - Otherwise, interpret cookie as the OID of the certificate
+ * extension containing the key.
+ */
+ if (cookie == NULL) {
+ return get_rotpk_info(key_ptr, key_len, flags);
+ } else if (strcmp(cookie, PROT_PK_OID) == 0) {
+ extern unsigned char arm_protpk_hash[];
+ extern unsigned char arm_protpk_hash_end[];
+ *key_ptr = arm_protpk_hash;
+ *key_len = arm_protpk_hash_end - arm_protpk_hash;
+ *flags = ROTPK_IS_HASH;
+ return 0;
+ } else {
+ /* Invalid key ID. */
+ return 1;
+ }
+}
+#endif
/*
* Return the non-volatile counter value stored in the platform. The cookie
@@ -155,9 +199,11 @@ int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
oid = (const char *)cookie;
if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
- nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
+ nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+ TRUSTED_NV_CTR_ID);
} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
- nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
+ nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+ NON_TRUSTED_NV_CTR_ID);
} else {
return 1;
}
@@ -179,37 +225,3 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
{
return 1;
}
-#else /* ARM_CRYPTOCELL_INTEG */
-
-#include <drivers/arm/cryptocell/cc_rotpk.h>
-
-/*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- * digestAlgorithm AlgorithmIdentifier,
- * digest OCTET STRING
- * }
- */
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
- unsigned int *flags)
-{
- unsigned char *dst;
-
- assert(key_ptr != NULL);
- assert(key_len != NULL);
- assert(flags != NULL);
-
- /* Copy the DER header */
- memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
- dst = &rotpk_hash_der[rotpk_hash_hdr_len];
- *key_ptr = rotpk_hash_der;
- *key_len = sizeof(rotpk_hash_der);
- return cc_get_rotpk_hash(dst, SHA256_BYTES, flags);
-}
-#endif /* ARM_CRYPTOCELL_INTEG */
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index b98dfd48b..6db0c0031 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -12,31 +12,80 @@ BL1_SOURCES += drivers/cfi/v2m/v2m_flash.c
BL2_SOURCES += drivers/cfi/v2m/v2m_flash.c
ifneq (${TRUSTED_BOARD_BOOT},0)
- ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
- # ROTPK hash location
- ifeq (${ARM_ROTPK_LOCATION}, regs)
- ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID
- else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
- KEY_ALG := rsa
- ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID
- else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa)
- KEY_ALG := ecdsa
- ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID
- else
- $(error "Unsupported ARM_ROTPK_LOCATION value")
- endif
- $(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
-
- # Certificate NV-Counters. Use values corresponding to tied off values in
- # ARM development platforms
- TFW_NVCTR_VAL ?= 31
- NTFW_NVCTR_VAL ?= 223
- else
- # Certificate NV-Counters when CryptoCell is integrated. For development
- # platforms we set the counter to first valid value.
- TFW_NVCTR_VAL ?= 0
- NTFW_NVCTR_VAL ?= 0
- endif
- BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c
- BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c
+ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
+# ROTPK hash location
+ifeq (${ARM_ROTPK_LOCATION}, regs)
+ ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID
+else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
+ CRYPTO_ALG=rsa
+ ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID
+ ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin
+$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
+$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
+$(warning Development keys support for FVP is deprecated. Use `regs` \
+option instead)
+else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa)
+ CRYPTO_ALG=ec
+ ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID
+ ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin
+$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
+$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
+$(warning Development keys support for FVP is deprecated. Use `regs` \
+option instead)
+else
+ $(error "Unsupported ARM_ROTPK_LOCATION value")
+endif
+
+$(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
+
+# Force generation of the new hash if ROT_KEY is specified
+ifdef ROT_KEY
+ HASH_PREREQUISITES = $(ROT_KEY) FORCE
+else
+ HASH_PREREQUISITES = $(ROT_KEY)
+endif
+
+$(ARM_ROTPK_HASH) : $(HASH_PREREQUISITES)
+ifndef ROT_KEY
+ $(error Cannot generate hash: no ROT_KEY defined)
+endif
+ openssl ${CRYPTO_ALG} -in $< -pubout -outform DER | openssl dgst \
+ -sha256 -binary > $@
+
+# Certificate NV-Counters. Use values corresponding to tied off values in
+# ARM development platforms
+TFW_NVCTR_VAL ?= 31
+NTFW_NVCTR_VAL ?= 223
+else
+# Certificate NV-Counters when CryptoCell is integrated. For development
+# platforms we set the counter to first valid value.
+TFW_NVCTR_VAL ?= 0
+NTFW_NVCTR_VAL ?= 0
+endif
+BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \
+ plat/arm/board/common/rotpk/arm_dev_rotpk.S
+BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \
+ plat/arm/board/common/rotpk/arm_dev_rotpk.S
+
+# Allows platform code to provide implementation variants depending on the
+# selected chain of trust.
+$(eval $(call add_define,ARM_COT_${COT}))
+
+ifeq (${COT},dualroot)
+# Platform Root of Trust key files.
+ARM_PROT_KEY := plat/arm/board/common/protpk/arm_protprivk_rsa.pem
+ARM_PROTPK_HASH := plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
+
+# Provide the private key to cert_create tool. It needs it to sign the images.
+PROT_KEY := ${ARM_PROT_KEY}
+
+$(eval $(call add_define_val,ARM_PROTPK_HASH,'"$(ARM_PROTPK_HASH)"'))
+
+BL1_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S
+BL2_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S
+
+$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+endif
+
endif
diff --git a/plat/arm/board/common/protpk/README b/plat/arm/board/common/protpk/README
new file mode 100644
index 000000000..3aca180d2
--- /dev/null
+++ b/plat/arm/board/common/protpk/README
@@ -0,0 +1,14 @@
+This directory contains some development keys to be used as the platform
+root-of-trust key.
+
+* arm_protprivk_rsa.pem is a 2K RSA private key in PEM format. It has been
+ generated using the openssl command line tool:
+
+ openssl genrsa 2048 > arm_protprivk_rsa.pem
+
+* arm_protpk_rsa_sha256.bin is the SHA-256 hash of the DER-encoded public key
+ associated with the above private key. It has been generated using the openssl
+ command line tool:
+
+ openssl rsa -in arm_protprivk_rsa.pem -pubout -outform DER | \
+ openssl dgst -sha256 -binary > arm_protpk_rsa_sha256.bin
diff --git a/plat/arm/board/common/protpk/arm_dev_protpk.S b/plat/arm/board/common/protpk/arm_dev_protpk.S
new file mode 100644
index 000000000..2688cbbb1
--- /dev/null
+++ b/plat/arm/board/common/protpk/arm_dev_protpk.S
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ .global arm_protpk_hash
+ .global arm_protpk_hash_end
+
+ .section .rodata.arm_protpk_hash, "a"
+
+arm_protpk_hash:
+ /* DER header. */
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+ /* Key hash. */
+ .incbin ARM_PROTPK_HASH
+arm_protpk_hash_end:
diff --git a/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin b/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
new file mode 100644
index 000000000..587da6605
--- /dev/null
+++ b/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
@@ -0,0 +1 @@
+œó6{W*…`Ÿtíve×·§è£ €¾PžÆK{9 \ No newline at end of file
diff --git a/plat/arm/board/common/protpk/arm_protprivk_rsa.pem b/plat/arm/board/common/protpk/arm_protprivk_rsa.pem
new file mode 100644
index 000000000..eeaad9e28
--- /dev/null
+++ b/plat/arm/board/common/protpk/arm_protprivk_rsa.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAzR0h/Z4Up17wfuRlYrUWseGDmlGKpl1PflGiYbyVmI7PwTTp
+y/T77EiljGp52suLWntHsc0lee50pW16DU2c5bVfmyofau3GjJ1Yqw5XFAahr6eM
+/0mkN8utrevvcRT9CP07D+zdhb/WlRUAnedqr/AUHU8BXS+Bxe8P0Z0Z7+DKjYZp
+thzXxsjKM02BFFzNwyVrlyBFDkW/53A4M+dpmuWDjAGCJH88W/u0LdmLcii11IzD
+/Ofz8Jxc/ZhqL+9FFK4qU+AJp8yXAnACSB46DlNltJrode0y5tmPhtS37ZF7EFb8
+UZWwZVgtuQyuyz9RYUS6jtiGuq6s8GlRwjTe7wIDAQABAoIBAFoWIYeyln+sQxR4
+W88umfkmgxaUGcFX2kIwuJEUst9+WeERzF24C62LeqphWYOvQlVLMAH3iC41fSXr
+H2AYZoC9WHBd386nAD1iHj+C3Nv+zaTIgjTdszKOUonAxjl0bm40SmyELAdCaoyv
+3MV9jm4Xk74LpR24b9bvWJNH3MxttH9hiYS+n0IzeTXDfO8GrNvHh92zx+jo8yMm
+Khhu+TDC9jA2pHpJcF/0EXxYMhwYiQT16nnHb+xMgS4JpalQhvVK01s4VYGHRoFk
+K6xh4TIS336LDLyalrGsPlfNfEdx+DimShDIfBUx9Jp3Pp11TUQUz4rhIHB9WdfG
+b6bV4wECgYEA+cgPS2TQ7XQ1RJq1S7OGePtBXvnoH226KwGS6Fey8838tLxbblim
+MU+EOYs3O66V6U2YpzmIakXo8030k8thY+jKbZl3l0m/hMuPOG66hfE5i7dYsiP4
+atok5wFiNeNYYjHMEayzk53MhG8EOh36msAO7ohKmenONUBA7pk6yTkCgYEA0jhk
+HPshwi+wKkx+JLTnuoEgx40tkRgSF2xBqKssMTasaQmX8qG+w9CEs0R8nZCI70Vc
+tXSFcidjdkHUVE2WsygIFuS1tbsAnpaxtn3E6rjie30X/Z280+TV0HjR0EMETmwl
+ShC5lZ0oP3LpEZfjbR5qs2kFW4MOxA7tjQVaMWcCgYEA5ZbVMBifzdMl70RA5i9C
+qEtSQAl3KgRCvar5rKSHsX+iC0Kiy9+iCusq/3WONEZ6NvMDIJpKYFyYDaOW7o5f
+m2TrRChu+1lnN5mfsGBfBCTBH0JMvZlAin6ussLb0eqBX+ijyY8zlLjTttsQSJcr
+tThZwTj3UVfOGbZQuL+RgEkCgYBXO3U3nXI9vUIx2zoBC1yZRNoQVGITMlTXiWGZ
+lyYoadKTZ5q44Sti4BUguounaoGYIEU/OtHhM70PJnPwY53kS/lHXrKUbbvtEwU9
+f+UFraC1s4wP/rOLjgq3jlsqO5T+4dt7Z4NLNUKtSYazeT6zWgrW1f6WIcUv0C38
+9bqegwKBgFCK3Oa5ibL5sPaPQ/1UfdeW4JVuu6A4JhHS7r+cVLsmcrvE1Qv7Wcvw
+B5aqXeqLu2dtIN8/f++3tzccs9LXKY/fh72D4TVjfrqOSSZoGTH9l4U5NXbqWM3I
+skkAYb2bMST/d1qSyYesgXVNAlaQHRh3vEz8x853nJ3v9OFj8/rW
+-----END RSA PRIVATE KEY-----
diff --git a/plat/arm/board/common/rotpk/arm_dev_rotpk.S b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
new file mode 100644
index 000000000..80f2192e4
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "plat/arm/common/arm_def.h"
+
+ .global arm_rotpk_header
+ .global arm_rotpk_header_end
+ .section .rodata.arm_rotpk_hash, "a"
+
+arm_rotpk_header:
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+arm_rotpk_header_len:
+
+#ifdef ARM_ROTPK_HASH
+ .global arm_rotpk_hash_end
+ .incbin ARM_ROTPK_HASH
+arm_rotpk_hash_end:
+#endif
+
+.if ARM_ROTPK_HEADER_LEN != arm_rotpk_header_len - arm_rotpk_header
+.error "Invalid ROTPK header length."
+.endif
diff --git a/plat/arm/board/corstone700/corstone700_helpers.S b/plat/arm/board/corstone700/common/corstone700_helpers.S
index c713f4f1a..c713f4f1a 100644
--- a/plat/arm/board/corstone700/corstone700_helpers.S
+++ b/plat/arm/board/corstone700/common/corstone700_helpers.S
diff --git a/plat/arm/board/corstone700/corstone700_plat.c b/plat/arm/board/corstone700/common/corstone700_plat.c
index cee6fd618..629f076ba 100644
--- a/plat/arm/board/corstone700/corstone700_plat.c
+++ b/plat/arm/board/corstone700/common/corstone700_plat.c
@@ -1,10 +1,12 @@
/*
- * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/bl_common.h>
+
+#include <mhu.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
@@ -16,6 +18,7 @@
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
+ ARM_MAP_NS_SHARED_RAM,
ARM_MAP_NS_DRAM1,
CORSTONE700_MAP_DEVICE,
{0}
@@ -26,9 +29,11 @@ const mmap_region_t plat_arm_mmap[] = {
*/
void __init plat_arm_pwrc_setup(void)
{
+ mhu_secure_init();
}
unsigned int plat_get_syscnt_freq2(void)
{
- return CORSTONE700_TIMER_BASE_FREQUENCY;
+ /* Returning the Generic Timer Frequency */
+ return SYS_COUNTER_FREQ_IN_TICKS;
}
diff --git a/plat/arm/board/corstone700/corstone700_pm.c b/plat/arm/board/corstone700/common/corstone700_pm.c
index 4884ea519..4884ea519 100644
--- a/plat/arm/board/corstone700/corstone700_pm.c
+++ b/plat/arm/board/corstone700/common/corstone700_pm.c
diff --git a/plat/arm/board/corstone700/corstone700_security.c b/plat/arm/board/corstone700/common/corstone700_security.c
index 39b2fc902..39b2fc902 100644
--- a/plat/arm/board/corstone700/corstone700_security.c
+++ b/plat/arm/board/corstone700/common/corstone700_security.c
diff --git a/plat/arm/board/corstone700/common/corstone700_stack_protector.c b/plat/arm/board/corstone700/common/corstone700_stack_protector.c
new file mode 100644
index 000000000..6fd09da5b
--- /dev/null
+++ b/plat/arm/board/corstone700/common/corstone700_stack_protector.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <plat/common/platform.h>
+
+static uint32_t plat_generate_random_number(void)
+{
+ uintptr_t return_addr = (uintptr_t)__builtin_return_address(0U);
+ uintptr_t frame_addr = (uintptr_t)__builtin_frame_address(0U);
+ uint64_t cntpct = read_cntpct_el0();
+
+ /* Generate 32-bit pattern: saving the 2 least significant bytes
+ * in random_lo and random_hi
+ */
+ uint16_t random_lo = (uint16_t)(
+ (((uint64_t)return_addr) << 13) ^ frame_addr ^ cntpct
+ );
+
+ uint16_t random_hi = (uint16_t)(
+ (((uint64_t)frame_addr) << 15) ^ return_addr ^ cntpct
+ );
+
+ return (((uint32_t)random_hi) << 16) | random_lo;
+}
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ return plat_generate_random_number(); /* a 32-bit pattern is returned */
+}
diff --git a/plat/arm/board/corstone700/corstone700_topology.c b/plat/arm/board/corstone700/common/corstone700_topology.c
index d9445e0c5..904f5ab3a 100644
--- a/plat/arm/board/corstone700/corstone700_topology.c
+++ b/plat/arm/board/corstone700/common/corstone700_topology.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,8 +8,8 @@
#include <plat/common/platform.h>
/* The Corstone700 power domain tree descriptor */
-static unsigned char corstone700_power_domain_tree_desc
- [PLAT_ARM_CLUSTER_COUNT + 2];
+static unsigned char corstone700_power_domain_tree_desc[PLAT_ARM_CLUSTER_COUNT
+ + 2];
/*******************************************************************************
* This function dynamically constructs the topology according to
* CLUSTER_COUNT and returns it.
diff --git a/plat/arm/board/corstone700/common/drivers/mhu/mhu.c b/plat/arm/board/corstone700/common/drivers/mhu/mhu.c
new file mode 100644
index 000000000..2231d1173
--- /dev/null
+++ b/plat/arm/board/corstone700/common/drivers/mhu/mhu.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+
+#include "mhu.h"
+#include <plat_arm.h>
+#include <platform_def.h>
+
+ARM_INSTANTIATE_LOCK;
+
+#pragma weak plat_arm_pwrc_setup
+
+/*
+ * Slot 31 is reserved because the MHU hardware uses this register bit to
+ * indicate a non-secure access attempt. The total number of available slots is
+ * therefore 31 [30:0].
+ */
+#define MHU_MAX_SLOT_ID 30
+
+void mhu_secure_message_start(uintptr_t address, unsigned int slot_id)
+{
+ unsigned int intr_stat_check;
+ uint64_t timeout_cnt;
+ volatile uint8_t expiration;
+
+ assert(slot_id <= MHU_MAX_SLOT_ID);
+ arm_lock_get();
+
+ /*
+ * Make sure any previous command has finished
+ * and polling timeout not expired
+ */
+
+ timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT);
+
+ do {
+ intr_stat_check = (mmio_read_32(address + CPU_INTR_S_STAT) &
+ (1 << slot_id));
+
+ expiration = timeout_elapsed(timeout_cnt);
+
+ } while ((intr_stat_check != 0U) && (expiration == 0U));
+
+ /*
+ * Note: No risk of timer overflows while waiting
+ * for the timeout expiration.
+ * According to Armv8 TRM: System counter roll-over
+ * time of not less than 40 years
+ */
+}
+
+void mhu_secure_message_send(uintptr_t address,
+ unsigned int slot_id,
+ unsigned int message)
+{
+ unsigned char access_ready;
+ uint64_t timeout_cnt;
+ volatile uint8_t expiration;
+
+ assert(slot_id <= MHU_MAX_SLOT_ID);
+ assert((mmio_read_32(address + CPU_INTR_S_STAT) &
+ (1 << slot_id)) == 0U);
+
+ MHU_V2_ACCESS_REQUEST(address);
+
+ timeout_cnt = timeout_init_us(MHU_POLL_INTR_STAT_TIMEOUT);
+
+ do {
+ access_ready = MHU_V2_IS_ACCESS_READY(address);
+ expiration = timeout_elapsed(timeout_cnt);
+
+ } while ((access_ready == 0U) && (expiration == 0U));
+
+ /*
+ * Note: No risk of timer overflows while waiting
+ * for the timeout expiration.
+ * According to Armv8 TRM: System counter roll-over
+ * time of not less than 40 years
+ */
+
+ mmio_write_32(address + CPU_INTR_S_SET, message);
+}
+
+void mhu_secure_message_end(uintptr_t address, unsigned int slot_id)
+{
+ assert(slot_id <= MHU_MAX_SLOT_ID);
+ /*
+ * Clear any response we got by writing one in the relevant slot bit to
+ * the CLEAR register
+ */
+ MHU_V2_CLEAR_REQUEST(address);
+
+ arm_lock_release();
+}
+
+void __init mhu_secure_init(void)
+{
+ arm_lock_init();
+
+ /*
+ * The STAT register resets to zero. Ensure it is in the expected state,
+ * as a stale or garbage value would make us think it's a message we've
+ * already sent.
+ */
+
+ assert(mmio_read_32(PLAT_SDK700_MHU0_SEND + CPU_INTR_S_STAT) == 0);
+}
diff --git a/plat/arm/board/corstone700/common/drivers/mhu/mhu.h b/plat/arm/board/corstone700/common/drivers/mhu/mhu.h
new file mode 100644
index 000000000..3808746e9
--- /dev/null
+++ b/plat/arm/board/corstone700/common/drivers/mhu/mhu.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MHU_H
+#define MHU_H
+
+#define MHU_POLL_INTR_STAT_TIMEOUT 50000 /*timeout value in us*/
+
+/* CPU MHU secure channel registers */
+#define CPU_INTR_S_STAT 0x00
+#define CPU_INTR_S_SET 0x0C
+
+/* MHUv2 Control Registers Offsets */
+#define MHU_V2_MSG_CFG_OFFSET 0xF80
+#define MHU_V2_ACCESS_REQ_OFFSET 0xF88
+#define MHU_V2_ACCESS_READY_OFFSET 0xF8C
+
+#define MHU_V2_ACCESS_REQUEST(addr) \
+ mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1)
+
+#define MHU_V2_CLEAR_REQUEST(addr) \
+ mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0)
+
+#define MHU_V2_IS_ACCESS_READY(addr) \
+ (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1)
+
+void mhu_secure_message_start(uintptr_t address, unsigned int slot_id);
+void mhu_secure_message_send(uintptr_t address,
+ unsigned int slot_id,
+ unsigned int message);
+void mhu_secure_message_end(uintptr_t address, unsigned int slot_id);
+void mhu_secure_init(void);
+
+#endif /* MHU_H */
diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/common/include/platform_def.h
index 8dff3ec3f..57b0551b3 100644
--- a/plat/arm/board/corstone700/include/platform_def.h
+++ b/plat/arm/board/corstone700/common/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,18 +11,33 @@
#include <lib/xlat_tables/xlat_tables_defs.h>
#include <plat/arm/board/common/v2m_def.h>
#include <plat/arm/common/arm_spm_def.h>
+#include <plat/arm/common/smccc_def.h>
#include <plat/common/common_def.h>
+/* PL011 UART related constants */
+#ifdef V2M_IOFPGA_UART0_CLK_IN_HZ
+#undef V2M_IOFPGA_UART0_CLK_IN_HZ
+#endif
+
+#ifdef V2M_IOFPGA_UART1_CLK_IN_HZ
+#undef V2M_IOFPGA_UART1_CLK_IN_HZ
+#endif
+
+#define V2M_IOFPGA_UART0_CLK_IN_HZ 32000000
+#define V2M_IOFPGA_UART1_CLK_IN_HZ 32000000
+
/* Core/Cluster/Thread counts for Corstone700 */
#define CORSTONE700_CLUSTER_COUNT U(1)
#define CORSTONE700_MAX_CPUS_PER_CLUSTER U(4)
#define CORSTONE700_MAX_PE_PER_CPU U(1)
-#define CORSTONE700_CORE_COUNT (CORSTONE700_CLUSTER_COUNT * \
- CORSTONE700_MAX_CPUS_PER_CLUSTER * \
- CORSTONE700_MAX_PE_PER_CPU)
-#define PLATFORM_CORE_COUNT CORSTONE700_CORE_COUNT
+
#define PLAT_ARM_CLUSTER_COUNT CORSTONE700_CLUSTER_COUNT
+#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \
+ CORSTONE700_MAX_CPUS_PER_CLUSTER * \
+ CORSTONE700_MAX_PE_PER_CPU)
+
+
/* UART related constants */
#define PLAT_ARM_BOOT_UART_BASE 0x1a510000
#define PLAT_ARM_BOOT_UART_CLK_IN_HZ V2M_IOFPGA_UART0_CLK_IN_HZ
@@ -52,6 +67,9 @@
#define ARM_BL_RAM_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \
ARM_SHARED_RAM_SIZE)
+#define ARM_NS_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE + UL(0x00100000)
+#define ARM_NS_SHARED_RAM_SIZE 0x00300000
+
/*
* SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM (excluding
* the page reserved for fw_configs) to BL32
@@ -68,31 +86,54 @@
#define ARM_CACHE_WRITEBACK_SHIFT 6
/*
- * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base
+ * To enable FW_CONFIG to be loaded by BL1, define the corresponding base
* and limit. Leave enough space for BL2 meminfo.
*/
-#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t))
-#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U))
+#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t))
+#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U))
+
+/*
+ * Boot parameters passed from BL2 to BL31/BL32 are stored here
+ */
+#define ARM_BL2_MEM_DESC_BASE (ARM_FW_CONFIG_LIMIT)
+#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE \
+ + (PAGE_SIZE / 2U))
+
+/*
+ * Define limit of firmware configuration memory:
+ * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory
+ */
+#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2))
/*
* The max number of regions like RO(code), coherent and data required by
* different BL stages which need to be mapped in the MMU.
*/
-#define ARM_BL_REGIONS 2
+#define ARM_BL_REGIONS 3
#define PLAT_ARM_MMAP_ENTRIES 8
#define MAX_XLAT_TABLES 5
#define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \
ARM_BL_REGIONS)
/* GIC related constants */
-#define PLAT_ARM_GICD_BASE 0x1C010000
-#define PLAT_ARM_GICC_BASE 0x1C02F000
+#define PLAT_ARM_GICD_BASE 0x1C010000
+#define PLAT_ARM_GICC_BASE 0x1C02F000
+
+/* MHUv2 Secure Channel receiver and sender */
+#define PLAT_SDK700_MHU0_SEND 0x1B800000
+#define PLAT_SDK700_MHU0_RECV 0x1B810000
/* Timer/watchdog related constants */
#define ARM_SYS_CNTCTL_BASE UL(0x1a200000)
#define ARM_SYS_CNTREAD_BASE UL(0x1a210000)
#define ARM_SYS_TIMCTL_BASE UL(0x1a220000)
-#define CORSTONE700_TIMER_BASE_FREQUENCY UL(24000000)
+
+#ifdef TARGET_PLATFORM_FVP
+#define SYS_COUNTER_FREQ_IN_TICKS UL(50000000) /* 50MHz */
+#else
+#define SYS_COUNTER_FREQ_IN_TICKS UL(32000000) /* 32MHz */
+#endif
+
#define CORSTONE700_IRQ_TZ_WDOG 32
#define CORSTONE700_IRQ_SEC_SYS_TIMER 34
@@ -101,49 +142,54 @@
* Macros mapping the MPIDR Affinity levels to ARM Platform Power levels. The
* power levels have a 1:1 mapping with the MPIDR affinity levels.
*/
-#define ARM_PWR_LVL0 MPIDR_AFFLVL0
-#define ARM_PWR_LVL1 MPIDR_AFFLVL1
-#define ARM_PWR_LVL2 MPIDR_AFFLVL2
+#define ARM_PWR_LVL0 MPIDR_AFFLVL0
+#define ARM_PWR_LVL1 MPIDR_AFFLVL1
+#define ARM_PWR_LVL2 MPIDR_AFFLVL2
/*
* Macros for local power states in ARM platforms encoded by State-ID field
* within the power-state parameter.
*/
/* Local power state for power domains in Run state. */
-#define ARM_LOCAL_STATE_RUN U(0)
+#define ARM_LOCAL_STATE_RUN U(0)
/* Local power state for retention. Valid only for CPU power domains */
-#define ARM_LOCAL_STATE_RET U(1)
+#define ARM_LOCAL_STATE_RET U(1)
/* Local power state for OFF/power-down. Valid for CPU and cluster
* power domains
*/
-#define ARM_LOCAL_STATE_OFF U(2)
+#define ARM_LOCAL_STATE_OFF U(2)
-#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
-#define PLAT_ARM_NSTIMER_FRAME_ID U(1)
+#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
+#define PLAT_ARM_NSTIMER_FRAME_ID U(1)
-#define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + UL(0x8000000))
+#define PLAT_ARM_NS_IMAGE_BASE (ARM_NS_SHARED_RAM_BASE)
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
/*
* This macro defines the deepest retention state possible. A higher state
* ID will represent an invalid or a power down state.
*/
-#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_RET_STATE 1
/*
* This macro defines the deepest power down states possible. Any state ID
* higher than this is invalid.
*/
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_OFF_STATE 2
-#define PLATFORM_STACK_SIZE UL(0x440)
+#define PLATFORM_STACK_SIZE UL(0x440)
-#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \
+#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \
ARM_SHARED_RAM_BASE, \
ARM_SHARED_RAM_SIZE, \
- MT_DEVICE | MT_RW | MT_SECURE)
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+#define ARM_MAP_NS_SHARED_RAM MAP_REGION_FLAT( \
+ ARM_NS_SHARED_RAM_BASE, \
+ ARM_NS_SHARED_RAM_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
#define ARM_MAP_NS_DRAM1 MAP_REGION_FLAT( \
ARM_NS_DRAM1_BASE, \
@@ -168,23 +214,31 @@
MT_DEVICE | MT_RW | MT_SECURE)
#endif
+/*
+ * Map the region for device tree configuration with read and write permissions
+ */
+#define ARM_MAP_BL_CONFIG_REGION MAP_REGION_FLAT(ARM_BL_RAM_BASE, \
+ (ARM_FW_CONFIGS_LIMIT \
+ - ARM_BL_RAM_BASE), \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
#define CORSTONE700_DEVICE_BASE (0x1A000000)
#define CORSTONE700_DEVICE_SIZE (0x26000000)
-#define CORSTONE700_MAP_DEVICE MAP_REGION_FLAT( \
- CORSTONE700_DEVICE_BASE, \
- CORSTONE700_DEVICE_SIZE, \
- MT_DEVICE | MT_RW | MT_SECURE)
-
-#define ARM_IRQ_SEC_PHY_TIMER 29
-
-#define ARM_IRQ_SEC_SGI_0 8
-#define ARM_IRQ_SEC_SGI_1 9
-#define ARM_IRQ_SEC_SGI_2 10
-#define ARM_IRQ_SEC_SGI_3 11
-#define ARM_IRQ_SEC_SGI_4 12
-#define ARM_IRQ_SEC_SGI_5 13
-#define ARM_IRQ_SEC_SGI_6 14
-#define ARM_IRQ_SEC_SGI_7 15
+#define CORSTONE700_MAP_DEVICE MAP_REGION_FLAT( \
+ CORSTONE700_DEVICE_BASE,\
+ CORSTONE700_DEVICE_SIZE,\
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define ARM_IRQ_SEC_PHY_TIMER 29
+
+#define ARM_IRQ_SEC_SGI_0 8
+#define ARM_IRQ_SEC_SGI_1 9
+#define ARM_IRQ_SEC_SGI_2 10
+#define ARM_IRQ_SEC_SGI_3 11
+#define ARM_IRQ_SEC_SGI_4 12
+#define ARM_IRQ_SEC_SGI_5 13
+#define ARM_IRQ_SEC_SGI_6 14
+#define ARM_IRQ_SEC_SGI_7 15
/*
* Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3
@@ -192,7 +246,7 @@
* as Group 0 interrupts.
*/
#define ARM_G1S_IRQ_PROPS(grp) \
- INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
+ INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
(grp), GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \
(grp), GIC_INTR_CFG_EDGE), \
@@ -217,11 +271,11 @@
* as Group 0 interrupts.
*/
#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
- ARM_G1S_IRQ_PROPS(grp), \
- INTR_PROP_DESC(CORSTONE700_IRQ_TZ_WDOG, \
- GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL), \
- INTR_PROP_DESC(CORSTONE700_IRQ_SEC_SYS_TIMER, \
- GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL) \
+ ARM_G1S_IRQ_PROPS(grp), \
+ INTR_PROP_DESC(CORSTONE700_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, \
+ (grp), GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(CORSTONE700_IRQ_SEC_SYS_TIMER, \
+ GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL)
#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk
index bff3589eb..9a8d38c11 100644
--- a/plat/arm/board/corstone700/platform.mk
+++ b/plat/arm/board/corstone700/platform.mk
@@ -1,9 +1,14 @@
#
-# Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
+# Making sure the corstone700 platform type is specified
+ifeq ($(filter ${TARGET_PLATFORM}, fpga fvp),)
+ $(error TARGET_PLATFORM must be fpga or fvp)
+endif
+
CORSTONE700_CPU_LIBS += lib/cpus/aarch32/cortex_a32.S
BL32_SOURCES += plat/arm/common/aarch32/arm_helpers.S \
@@ -11,34 +16,39 @@ BL32_SOURCES += plat/arm/common/aarch32/arm_helpers.S \
plat/arm/common/arm_common.c \
lib/xlat_tables/aarch32/xlat_tables.c \
lib/xlat_tables/xlat_tables_common.c \
- ${CORSTONE700_CPU_LIBS}
+ ${CORSTONE700_CPU_LIBS} \
+ plat/arm/board/corstone700/common/drivers/mhu/mhu.c
-PLAT_INCLUDES := -Iplat/arm/board/corstone700/include
+PLAT_INCLUDES := -Iplat/arm/board/corstone700/common/include \
+ -Iinclude/plat/arm/common \
+ -Iplat/arm/board/corstone700/common/drivers/mhu
NEED_BL32 := yes
-CORSTONE700_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
- plat/common/plat_gicv2.c \
+# Include GICv2 driver files
+include drivers/arm/gic/v2/gicv2.mk
+
+CORSTONE700_GIC_SOURCES := ${GICV2_SOURCES} \
+ plat/common/plat_gicv2.c \
plat/arm/common/arm_gicv2.c
# BL1/BL2 Image not a part of the capsule Image for Corstone700
override NEED_BL1 := no
override NEED_BL2 := no
override NEED_BL2U := no
+override NEED_BL33 := yes
#TFA for Corstone700 starts from BL32
override RESET_TO_SP_MIN := 1
#Device tree
-CORSTONE700_HW_CONFIG_DTS := fdts/corstone700.dts
-CORSTONE700_HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb
+CORSTONE700_HW_CONFIG_DTS := fdts/corstone700_${TARGET_PLATFORM}.dts
+CORSTONE700_HW_CONFIG := ${BUILD_PLAT}/fdts/corstone700_${TARGET_PLATFORM}.dtb
FDT_SOURCES += ${CORSTONE700_HW_CONFIG_DTS}
$(eval CORSTONE700_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(CORSTONE700_HW_CONFIG_DTS)))
# Add the HW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${CORSTONE700_HW_CONFIG},--hw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${CORSTONE700_HW_CONFIG},--hw-config,${CORSTONE700_HW_CONFIG}))
# Check for Linux kernel as a BL33 image by default
$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
@@ -46,4 +56,8 @@ $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
$(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.")
endif
$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
+# Adding TARGET_PLATFORM as a GCC define (-D option)
+$(eval $(call add_define,TARGET_PLATFORM_$(call uppercase,${TARGET_PLATFORM})))
+
include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk
index 57e1ec3e4..75dc0f10c 100644
--- a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk
+++ b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -7,12 +7,18 @@
# SP_MIN source files specific to FVP platform
BL32_SOURCES += drivers/cfi/v2m/v2m_flash.c \
lib/utils/mem_region.c \
- plat/arm/board/corstone700/corstone700_helpers.S \
- plat/arm/board/corstone700/corstone700_topology.c \
- plat/arm/board/corstone700/corstone700_security.c \
- plat/arm/board/corstone700/corstone700_plat.c \
- plat/arm/board/corstone700/corstone700_pm.c \
+ plat/arm/board/corstone700/common/corstone700_helpers.S \
+ plat/arm/board/corstone700/common/corstone700_topology.c \
+ plat/arm/board/corstone700/common/corstone700_security.c \
+ plat/arm/board/corstone700/common/corstone700_plat.c \
+ plat/arm/board/corstone700/common/corstone700_pm.c \
plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c \
${CORSTONE700_GIC_SOURCES}
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+ ifneq (${ENABLE_STACK_PROTECTOR},none)
+ BL32_SOURCES += plat/arm/board/corstone700/common/corstone700_stack_protector.c
+ endif
+endif
+
include plat/arm/common/sp_min/arm_sp_min.mk
diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
new file mode 100644
index 000000000..35a777b6f
--- /dev/null
+++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <fconf_hw_config_getter.h>
+#include <libfdt.h>
+#include <plat/common/platform.h>
+
+struct gicv3_config_t gicv3_config;
+struct hw_topology_t soc_topology;
+struct uart_serial_config_t uart_serial_config;
+struct cpu_timer_t cpu_timer;
+
+#define ILLEGAL_ADDR ULL(~0)
+
+int fconf_populate_gicv3_config(uintptr_t config)
+{
+ int err;
+ int node;
+ uintptr_t addr;
+
+ /* Necessary to work with libfdt APIs */
+ const void *hw_config_dtb = (const void *)config;
+
+ /*
+ * Find the offset of the node containing "arm,gic-v3" compatible property.
+ * Populating fconf strucutures dynamically is not supported for legacy
+ * systems which use GICv2 IP. Simply skip extracting GIC properties.
+ */
+ node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,gic-v3");
+ if (node < 0) {
+ WARN("FCONF: Unable to locate node with arm,gic-v3 compatible property\n");
+ return 0;
+ }
+ /* The GICv3 DT binding holds at least two address/size pairs,
+ * the first describing the distributor, the second the redistributors.
+ * See: bindings/interrupt-controller/arm,gic-v3.yaml
+ */
+ err = fdt_get_reg_props_by_index(hw_config_dtb, node, 0, &addr, NULL);
+ if (err < 0) {
+ ERROR("FCONF: Failed to read GICD reg property of GIC node\n");
+ return err;
+ }
+ gicv3_config.gicd_base = addr;
+
+ err = fdt_get_reg_props_by_index(hw_config_dtb, node, 1, &addr, NULL);
+ if (err < 0) {
+ ERROR("FCONF: Failed to read GICR reg property of GIC node\n");
+ } else {
+ gicv3_config.gicr_base = addr;
+ }
+
+ return err;
+}
+
+int fconf_populate_topology(uintptr_t config)
+{
+ int err, node, cluster_node, core_node, thread_node;
+ uint32_t cluster_count = 0, max_cpu_per_cluster = 0, total_cpu_count = 0;
+ uint32_t max_pwr_lvl = 0;
+
+ /* Necessary to work with libfdt APIs */
+ const void *hw_config_dtb = (const void *)config;
+
+ /* Find the offset of the node containing "arm,psci-1.0" compatible property */
+ node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,psci-1.0");
+ if (node < 0) {
+ ERROR("FCONF: Unable to locate node with arm,psci-1.0 compatible property\n");
+ return node;
+ }
+
+ err = fdt_read_uint32(hw_config_dtb, node, "max-pwr-lvl", &max_pwr_lvl);
+ if (err < 0) {
+ /*
+ * Some legacy FVP dts may not have this property. Assign the default
+ * value.
+ */
+ WARN("FCONF: Could not locate max-pwr-lvl property\n");
+ max_pwr_lvl = 2;
+ }
+
+ assert(max_pwr_lvl <= MPIDR_AFFLVL2);
+
+ /* Find the offset of the "cpus" node */
+ node = fdt_path_offset(hw_config_dtb, "/cpus");
+ if (node < 0) {
+ ERROR("FCONF: Node '%s' not found in hardware configuration dtb\n", "cpus");
+ return node;
+ }
+
+ /* A typical cpu-map node in a device tree is shown here for reference
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&CPU0>;
+ };
+ core1 {
+ cpu = <&CPU1>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&CPU2>;
+ };
+ core1 {
+ cpu = <&CPU3>;
+ };
+ };
+ };
+ */
+
+ /* Locate the cpu-map child node */
+ node = fdt_subnode_offset(hw_config_dtb, node, "cpu-map");
+ if (node < 0) {
+ ERROR("FCONF: Node '%s' not found in hardware configuration dtb\n", "cpu-map");
+ return node;
+ }
+
+ uint32_t cpus_per_cluster[PLAT_ARM_CLUSTER_COUNT] = {0};
+
+ /* Iterate through cluster nodes */
+ fdt_for_each_subnode(cluster_node, hw_config_dtb, node) {
+ assert(cluster_count < PLAT_ARM_CLUSTER_COUNT);
+
+ /* Iterate through core nodes */
+ fdt_for_each_subnode(core_node, hw_config_dtb, cluster_node) {
+ /* core nodes may have child nodes i.e., "thread" nodes */
+ if (fdt_first_subnode(hw_config_dtb, core_node) < 0) {
+ cpus_per_cluster[cluster_count]++;
+ } else {
+ /* Multi-threaded CPU description is found in dtb */
+ fdt_for_each_subnode(thread_node, hw_config_dtb, core_node) {
+ cpus_per_cluster[cluster_count]++;
+ }
+
+ /* Since in some dtbs, core nodes may not have thread node,
+ * no need to error if even one child node is not found.
+ */
+ }
+ }
+
+ /* Ensure every cluster node has at least 1 child node */
+ if (cpus_per_cluster[cluster_count] < 1U) {
+ ERROR("FCONF: Unable to locate the core node in cluster %d\n", cluster_count);
+ return -1;
+ }
+
+ VERBOSE("CLUSTER ID: %d cpu-count: %d\n", cluster_count,
+ cpus_per_cluster[cluster_count]);
+
+ /* Find the maximum number of cpus in any cluster */
+ max_cpu_per_cluster = MAX(max_cpu_per_cluster, cpus_per_cluster[cluster_count]);
+ total_cpu_count += cpus_per_cluster[cluster_count];
+ cluster_count++;
+ }
+
+
+ /* At least one cluster node is expected in hardware configuration dtb */
+ if (cluster_count < 1U) {
+ ERROR("FCONF: Unable to locate the cluster node in cpu-map node\n");
+ return -1;
+ }
+
+ soc_topology.plat_max_pwr_level = max_pwr_lvl;
+ soc_topology.plat_cluster_count = cluster_count;
+ soc_topology.cluster_cpu_count = max_cpu_per_cluster;
+ soc_topology.plat_cpu_count = total_cpu_count;
+
+ return 0;
+}
+
+int fconf_populate_uart_config(uintptr_t config)
+{
+ int uart_node, node, err;
+ uintptr_t addr;
+ const char *path;
+ uint32_t phandle;
+ uint64_t translated_addr;
+
+ /* Necessary to work with libfdt APIs */
+ const void *hw_config_dtb = (const void *)config;
+
+ /*
+ * uart child node is indirectly referenced through its path which is
+ * specified in the `serial1` property of the "aliases" node.
+ * Note that TF-A boot console is mapped to serial0 while runtime
+ * console is mapped to serial1.
+ */
+
+ path = fdt_get_alias(hw_config_dtb, "serial1");
+ if (path == NULL) {
+ ERROR("FCONF: Could not read serial1 property in aliases node\n");
+ return -1;
+ }
+
+ /* Find the offset of the uart serial node */
+ uart_node = fdt_path_offset(hw_config_dtb, path);
+ if (uart_node < 0) {
+ ERROR("FCONF: Failed to locate uart serial node using its path\n");
+ return -1;
+ }
+
+ /* uart serial node has its offset and size of address in reg property */
+ err = fdt_get_reg_props_by_index(hw_config_dtb, uart_node, 0, &addr,
+ NULL);
+ if (err < 0) {
+ ERROR("FCONF: Failed to read reg property of '%s' node\n",
+ "uart serial");
+ return err;
+ }
+ VERBOSE("FCONF: UART node address: %lx\n", addr);
+
+ /*
+ * Perform address translation of local device address to CPU address
+ * domain.
+ */
+ translated_addr = fdtw_translate_address(hw_config_dtb,
+ uart_node, (uint64_t)addr);
+ if (translated_addr == ILLEGAL_ADDR) {
+ ERROR("FCONF: failed to translate UART node base address");
+ return -1;
+ }
+
+ uart_serial_config.uart_base = translated_addr;
+
+ VERBOSE("FCONF: UART serial device base address: %llx\n",
+ uart_serial_config.uart_base);
+
+ /*
+ * The phandle of the DT node which captures the clock info of uart
+ * serial node is specified in the "clocks" property.
+ */
+ err = fdt_read_uint32(hw_config_dtb, uart_node, "clocks", &phandle);
+ if (err < 0) {
+ ERROR("FCONF: Could not read clocks property in uart serial node\n");
+ return err;
+ }
+
+ node = fdt_node_offset_by_phandle(hw_config_dtb, phandle);
+ if (node < 0) {
+ ERROR("FCONF: Failed to locate clk node using its path\n");
+ return node;
+ }
+
+ /*
+ * Retrieve clock frequency. We assume clock provider generates a fixed
+ * clock.
+ */
+ err = fdt_read_uint32(hw_config_dtb, node, "clock-frequency",
+ &uart_serial_config.uart_clk);
+ if (err < 0) {
+ ERROR("FCONF: Could not read clock-frequency property in clk node\n");
+ return err;
+ }
+
+ VERBOSE("FCONF: UART serial device clk frequency: %x\n",
+ uart_serial_config.uart_clk);
+
+ return 0;
+}
+
+int fconf_populate_cpu_timer(uintptr_t config)
+{
+ int err, node;
+
+ /* Necessary to work with libfdt APIs */
+ const void *hw_config_dtb = (const void *)config;
+
+ /* Find the node offset point to "arm,armv8-timer" compatible property,
+ * a per-core architected timer attached to a GIC to deliver its per-processor
+ * interrupts via PPIs */
+ node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,armv8-timer");
+ if (node < 0) {
+ ERROR("FCONF: Unrecognized hardware configuration dtb (%d)\n", node);
+ return node;
+ }
+
+ /* Locate the cell holding the clock-frequency, an optional field */
+ err = fdt_read_uint32(hw_config_dtb, node, "clock-frequency", &cpu_timer.clock_freq);
+ if (err < 0) {
+ WARN("FCONF failed to read clock-frequency property\n");
+ }
+
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config);
+FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
+FCONF_REGISTER_POPULATOR(HW_CONFIG, uart_config, fconf_populate_uart_config);
+FCONF_REGISTER_POPULATOR(HW_CONFIG, cpu_timer, fconf_populate_cpu_timer);
diff --git a/plat/arm/board/fvp/fconf/fconf_nt_config_getter.c b/plat/arm/board/fvp/fconf/fconf_nt_config_getter.c
new file mode 100644
index 000000000..e25801520
--- /dev/null
+++ b/plat/arm/board/fvp/fconf/fconf_nt_config_getter.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+
+#include <libfdt.h>
+#include <fconf_nt_config_getter.h>
+
+#include <plat/common/platform.h>
+
+struct event_log_config_t event_log_config;
+
+int fconf_populate_event_log_config(uintptr_t config)
+{
+ int err;
+ int node;
+
+ /* Necessary to work with libfdt APIs */
+ const void *dtb = (const void *)config;
+
+ /*
+ * Find the offset of the node containing "arm,tpm_event_log"
+ * compatible property
+ */
+ const char *compatible_str = "arm,tpm_event_log";
+
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find '%s' compatible in dtb\n",
+ compatible_str);
+ return node;
+ }
+
+ /* Retrieve Event Log details from the DTB */
+#ifdef SPD_opteed
+ err = fdtw_read_cells(dtb, node, "tpm_event_log_sm_addr", 2,
+ &event_log_config.tpm_event_log_sm_addr);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for 'tpm_event_log_sm_addr'\n");
+ return err;
+ }
+#endif
+ err = fdtw_read_cells(dtb, node,
+ "tpm_event_log_addr", 2, &event_log_config.tpm_event_log_addr);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for 'tpm_event_log_addr'\n");
+ return err;
+ }
+
+ err = fdtw_read_cells(dtb, node,
+ "tpm_event_log_size", 1, &event_log_config.tpm_event_log_size);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for 'tpm_event_log_size'\n");
+ }
+
+ return err;
+}
+
+FCONF_REGISTER_POPULATOR(NT_CONFIG, event_log_config,
+ fconf_populate_event_log_config);
diff --git a/plat/arm/board/fvp/fdts/event_log.dtsi b/plat/arm/board/fvp/fdts/event_log.dtsi
new file mode 100644
index 000000000..47af672df
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/event_log.dtsi
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* TPM Event Log Config */
+event_log: tpm_event_log {
+ compatible = "arm,tpm_event_log";
+ tpm_event_log_addr = <0x0 0x0>;
+ tpm_event_log_size = <0x0>;
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
new file mode 100644
index 000000000..9fb566b1e
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x1800>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x82000000>;
+ max-size = <0x01000000>;
+ id = <HW_CONFIG_ID>;
+ };
+
+ /*
+ * Load SoC and TOS firmware configs at the base of
+ * non shared SRAM. The runtime checks ensure we don't
+ * overlap BL2, BL31 or BL32. The NT firmware config
+ * is loaded at base of DRAM.
+ */
+ soc_fw-config {
+ load-address = <0x0 0x04001300>;
+ max-size = <0x200>;
+ id = <SOC_FW_CONFIG_ID>;
+ };
+
+ tos_fw-config {
+ load-address = <0x0 0x04001500>;
+ max-size = <0xB00>;
+ id = <TOS_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0x80000000>;
+ max-size = <0x200>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts
index 7ab980b1b..8f32b9880 100644
--- a/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,5 +7,13 @@
/dts-v1/;
/ {
+#if MEASURED_BOOT
+#include "event_log.dtsi"
+#endif
+};
+#if MEASURED_BOOT && defined(SPD_opteed)
+&event_log {
+ tpm_event_log_sm_addr = <0x0 0x0>;
};
+#endif
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
new file mode 100644
index 000000000..f4805db69
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+#define AFF 00
+
+#include "fvp-defs.dtsi"
+#undef POST
+#define POST \
+ };
+
+/ {
+ compatible = "arm,ffa-core-manifest-1.0";
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ attribute {
+ spmc_id = <0x8000>;
+ maj_ver = <0x1>;
+ min_ver = <0x0>;
+ exec_state = <0x0>;
+ load_address = <0x0 0x6000000>;
+ entrypoint = <0x0 0x6000000>;
+ binary_size = <0x80000>;
+ };
+
+ hypervisor {
+ compatible = "hafnium,hafnium";
+ vm1 {
+ is_ffa_partition;
+ debug_name = "cactus-primary";
+ load_address = <0x7000000>;
+ vcpu_count = <8>;
+ mem_size = <1048576>;
+ };
+ vm2 {
+ is_ffa_partition;
+ debug_name = "cactus-secondary";
+ load_address = <0x7100000>;
+ vcpu_count = <8>;
+ mem_size = <1048576>;
+ };
+ vm3 {
+ is_ffa_partition;
+ debug_name = "cactus-tertiary";
+ load_address = <0x7200000>;
+ vcpu_count = <8>;
+ mem_size = <1048576>;
+ };
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ CPU_0
+
+ /*
+ * SPMC (Hafnium) requires secondary core nodes are declared
+ * in descending order.
+ */
+ CPU_7
+ CPU_6
+ CPU_5
+ CPU_4
+ CPU_3
+ CPU_2
+ CPU_1
+ };
+
+ memory@6000000 {
+ device_type = "memory";
+ reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */
+ };
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
new file mode 100644
index 000000000..57d6792e1
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+#define AFF 00
+
+#include "fvp-defs.dtsi"
+#undef POST
+#define POST \
+ };
+
+/ {
+ compatible = "arm,ffa-core-manifest-1.0";
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ attribute {
+ spmc_id = <0x8000>;
+ maj_ver = <0x1>;
+ min_ver = <0x0>;
+ exec_state = <0x0>;
+ load_address = <0x0 0x6000000>;
+ entrypoint = <0x0 0x6000000>;
+ binary_size = <0x80000>;
+ };
+
+ hypervisor {
+ compatible = "hafnium,hafnium";
+ vm1 {
+ is_ffa_partition;
+ debug_name = "op-tee";
+ load_address = <0x6280000>;
+ smc_whitelist = <0xbe000000>;
+ vcpu_count = <8>;
+ mem_size = <1048576>;
+ };
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ CPU_0
+
+ /*
+ * SPMC (Hafnium) requires secondary core nodes are declared
+ * in descending order.
+ */
+ CPU_7
+ CPU_6
+ CPU_5
+ CPU_4
+ CPU_3
+ CPU_2
+ CPU_1
+ };
+
+ memory@6000000 {
+ device_type = "memory";
+ reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */
+ };
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index ce589385c..fe154e970 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,25 +7,12 @@
/dts-v1/;
/ {
- /* Platform Config */
- plat_arm_bl2 {
+ tb_fw-config {
compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x82000000>;
- hw_config_max_size = <0x01000000>;
+
/* Disable authentication for development */
disable_auth = <0x0>;
- /*
- * Load SoC and TOS firmware configs at the base of
- * non shared SRAM. The runtime checks ensure we don't
- * overlap BL2, BL31 or BL32. The NT firmware config
- * is loaded at base of DRAM.
- */
- soc_fw_config_addr = <0x0 0x04001000>;
- soc_fw_config_max_size = <0x200>;
- tos_fw_config_addr = <0x0 0x04001200>;
- tos_fw_config_max_size = <0x200>;
- nt_fw_config_addr = <0x0 0x80000000>;
- nt_fw_config_max_size = <0x200>;
+
/*
* The following two entries are placeholders for Mbed TLS
* heap information. The default values don't matter since
@@ -37,5 +24,96 @@
*/
mbedtls_heap_addr = <0x0 0x0>;
mbedtls_heap_size = <0x0>;
+
+#if MEASURED_BOOT
+ /* BL2 image hash calculated by BL1 */
+ bl2_hash_data = [
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+#if BL2_HASH_SIZE > 32
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+#if BL2_HASH_SIZE > 48
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+#endif /* > 48 */
+#endif /* > 32 */
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00];
+#endif /* MEASURED_BOOT */
+ };
+
+ /*
+ * UUID's here are UUID RFC 4122 compliant meaning fieds are stored in
+ * network order (big endian)
+ */
+
+#if ARM_IO_IN_DTB
+ arm-io_policies {
+ fip-handles {
+ compatible = "arm,io-fip-handle";
+ scp_bl2_uuid = <0x9766fd3d 0x89bee849 0xae5d78a1 0x40608213>;
+ bl31_uuid = <0x47d4086d 0x4cfe9846 0x9b952950 0xcbbd5a00>;
+ bl32_uuid = <0x05d0e189 0x53dc1347 0x8d2b500a 0x4b7a3e38>;
+ bl32_extra1_uuid = <0x0b70c28b 0x2a5a7840 0x9f650a56 0x82738288>;
+ bl32_extra2_uuid = <0x8ea87bb1 0xcfa23f4d 0x85fde7bb 0xa50220d9>;
+ bl33_uuid = <0xd6d0eea7 0xfcead54b 0x97829934 0xf234b6e4>;
+ hw_cfg_uuid = <0x08b8f1d9 0xc9cf9349 0xa9626fbc 0x6b7265cc>;
+ soc_fw_cfg_uuid = <0x9979814b 0x0376fb46 0x8c8e8d26 0x7f7859e0>;
+ tos_fw_cfg_uuid = <0x26257c1a 0xdbc67f47 0x8d96c4c4 0xb0248021>;
+ nt_fw_cfg_uuid = <0x28da9815 0x93e87e44 0xac661aaf 0x801550f9>;
+ t_key_cert_uuid = <0x827ee890 0xf860e411 0xa1b477a7 0x21b4f94c>;
+ scp_fw_key_uuid = <0x024221a1 0xf860e411 0x8d9bf33c 0x0e15a014>;
+ soc_fw_key_uuid = <0x8ab8becc 0xf960e411 0x9ad0eb48 0x22d8dcf8>;
+ tos_fw_key_cert_uuid = <0x9477d603 0xfb60e411 0x85ddb710 0x5b8cee04>;
+ nt_fw_key_cert_uuid = <0x8ad5832a 0xfb60e411 0x8aafdf30 0xbbc49859>;
+ scp_fw_content_cert_uuid = <0x44be6f04 0x5e63e411 0xb28b73d8 0xeaae9656>;
+ soc_fw_content_cert_uuid = <0xe2b20c20 0x5e63e411 0x9ce8abcc 0xf92bb666>;
+ tos_fw_content_cert_uuid = <0xa49f4411 0x5e63e411 0x87283f05 0x722af33d>;
+ nt_fw_content_cert_uuid = <0x8ec4c1f3 0x5d63e411 0xa7a987ee 0x40b23fa7>;
+ sp_content_cert_uuid = <0x776dfd44 0x86974c3b 0x91ebc13e 0x025a2a6f>;
+ };
+ };
+#endif /* ARM_IO_IN_DTB */
+
+ secure-partitions {
+ compatible = "arm,sp";
+#ifdef OPTEE_SP_FW_CONFIG
+ op-tee {
+ uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>;
+ load-address = <0x6280000>;
+ };
+#else
+ cactus-primary {
+ uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>;
+ load-address = <0x7000000>;
+ owner = "SiP";
+ };
+
+ cactus-secondary {
+ uuid = <0xd1582309 0xf02347b9 0x827c4464 0xf5578fc8>;
+ load-address = <0x7100000>;
+ owner = "Plat";
+ };
+
+ cactus-tertiary {
+ uuid = <0x79b55c73 0x1d8c44b9 0x859361e1 0x770ad8d2>;
+ load-address = <0x7200000>;
+ };
+#endif
};
+
+#if COT_DESC_IN_DTB
+ #include "cot_descriptors.dtsi"
+#endif
+
+};
+
+#if COT_DESC_IN_DTB
+
+#include "../fvp_def.h"
+
+&trusted_nv_counter {
+ reg = <TFW_NVCTR_BASE>;
+};
+
+&non_trusted_nv_counter {
+ reg = <NTFW_CTR_BASE>;
};
+#endif
diff --git a/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts
index 7ab980b1b..7bed6cb3b 100644
--- a/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,5 +7,7 @@
/dts-v1/;
/ {
-
+#if MEASURED_BOOT
+#include "event_log.dtsi"
+#endif
};
diff --git a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
new file mode 100644
index 000000000..928d0d3bf
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
+ * that has additional optional properties defined.
+ *
+ */
+
+/dts-v1/;
+
+/ {
+ compatible = "arm,ffa-manifest-1.0";
+
+ /* Properties */
+ description = "op-tee";
+ ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+ uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>;
+ id = <1>;
+ execution-ctx-count = <8>;
+ exception-level = <2>; /* S-EL1 */
+ execution-state = <0>; /* AARCH64 */
+ load-address = <0x6280000>;
+ entrypoint-offset = <0x1000>;
+ xlat-granule = <0>; /* 4KiB */
+ boot-order = <0>;
+ messaging-method = <0>; /* Direct messaging only */
+ run-time-model = <1>; /* Run to completion */
+
+ /* Boot protocol */
+ gp-register-num = <0x0>;
+
+ device-regions {
+ compatible = "arm,ffa-manifest-device-regions";
+
+ uart1 {
+ base-address = <0x00000000 0x1c0a0000>;
+ pages-count = <1>;
+ attributes = <0x3>; /* read-write */
+ };
+
+ gicd {
+ base-address = <0x00000000 0x2f000000>;
+ pages-count = <16>;
+ attributes = <0x3>; /* read-write */
+ };
+ };
+};
diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c
index 8f6170daa..e713bbc44 100644
--- a/plat/arm/board/fvp/fvp_bl1_setup.c
+++ b/plat/arm/board/fvp/fvp_bl1_setup.c
@@ -1,9 +1,12 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+
+#include <bl1/bl1.h>
#include <common/tbbr/tbbr_img_def.h>
#include <drivers/arm/smmu_v3.h>
#include <drivers/arm/sp805.h>
@@ -61,6 +64,63 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved)
/* Setup the watchdog to reset the system as soon as possible */
sp805_refresh(ARM_SP805_TWDG_BASE, 1U);
- while (1)
+ while (true)
wfi();
}
+
+#if MEASURED_BOOT
+/*
+ * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB.
+ */
+void bl1_plat_set_bl2_hash(const image_desc_t *image_desc)
+{
+ arm_bl1_set_bl2_hash(image_desc);
+}
+
+/*
+ * Implementation for bl1_plat_handle_post_image_load(). This function
+ * populates the default arguments to BL2. The BL2 memory layout structure
+ * is allocated and the calculated layout is populated in arg1 to BL2.
+ */
+int bl1_plat_handle_post_image_load(unsigned int image_id)
+{
+ meminfo_t *bl2_tzram_layout;
+ meminfo_t *bl1_tzram_layout;
+ image_desc_t *image_desc;
+ entry_point_info_t *ep_info;
+
+ if (image_id != BL2_IMAGE_ID) {
+ return 0;
+ }
+
+ /* Get the image descriptor */
+ image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
+ assert(image_desc != NULL);
+
+ /* Calculate BL2 hash and set it in TB_FW_CONFIG */
+ bl1_plat_set_bl2_hash(image_desc);
+
+ /* Get the entry point info */
+ ep_info = &image_desc->ep_info;
+
+ /* Find out how much free trusted ram remains after BL1 load */
+ bl1_tzram_layout = bl1_plat_sec_mem_layout();
+
+ /*
+ * Create a new layout of memory for BL2 as seen by BL1 i.e.
+ * tell it the amount of total and free memory available.
+ * This layout is created at the first free address visible
+ * to BL2. BL2 will read the memory layout before using its
+ * memory for other purposes.
+ */
+ bl2_tzram_layout = (meminfo_t *)bl1_tzram_layout->total_base;
+
+ bl1_calc_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout);
+
+ ep_info->args.arg1 = (uintptr_t)bl2_tzram_layout;
+
+ VERBOSE("BL1: BL2 memory layout address = %p\n",
+ (void *)bl2_tzram_layout);
+ return 0;
+}
+#endif /* MEASURED_BOOT */
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 89636d18a..f2f21432d 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -1,12 +1,20 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/desc_image_load.h>
#include <drivers/arm/sp804_delay_timer.h>
-#include <drivers/generic_delay_timer.h>
-#include <lib/mmio.h>
+#if MEASURED_BOOT
+#include <drivers/measured_boot/measured_boot.h>
+#endif
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
@@ -28,3 +36,82 @@ void bl2_platform_setup(void)
/* Initialize System level generic or SP804 timer */
fvp_timer_init();
}
+
+/*******************************************************************************
+ * This function returns the list of executable images
+ ******************************************************************************/
+struct bl_params *plat_get_next_bl_params(void)
+{
+ struct bl_params *arm_bl_params;
+
+ arm_bl_params = arm_get_next_bl_params();
+
+#if __aarch64__ && !BL2_AT_EL3
+ const struct dyn_cfg_dtb_info_t *fw_config_info;
+ bl_mem_params_node_t *param_node;
+ uintptr_t fw_config_base = 0U;
+ entry_point_info_t *ep_info;
+
+ /* Get BL31 image node */
+ param_node = get_bl_mem_params_node(BL31_IMAGE_ID);
+ assert(param_node != NULL);
+
+ /* get fw_config load address */
+ fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
+ assert(fw_config_info != NULL);
+
+ fw_config_base = fw_config_info->config_addr;
+ assert(fw_config_base != 0U);
+
+ /*
+ * Get the entry point info of BL31 image and override
+ * arg1 of entry point info with fw_config base address
+ */
+ ep_info = &param_node->ep_info;
+ ep_info->args.arg1 = (uint32_t)fw_config_base;
+#endif /* __aarch64__ && !BL2_AT_EL3 */
+
+ return arm_bl_params;
+}
+#if MEASURED_BOOT
+static int fvp_bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ const bl_mem_params_node_t *bl_mem_params =
+ get_bl_mem_params_node(image_id);
+
+ assert(bl_mem_params != NULL);
+
+ image_info_t info = bl_mem_params->image_info;
+ int err;
+
+ if ((info.h.attr & IMAGE_ATTRIB_SKIP_LOADING) == 0U) {
+ /* Calculate image hash and record data in Event Log */
+ err = tpm_record_measurement(info.image_base,
+ info.image_size, image_id);
+ if (err != 0) {
+ ERROR("%s%s image id %u (%i)\n",
+ "BL2: Failed to ", "record", image_id, err);
+ return err;
+ }
+ }
+
+ err = arm_bl2_handle_post_image_load(image_id);
+ if (err != 0) {
+ ERROR("%s%s image id %u (%i)\n",
+ "BL2: Failed to ", "handle", image_id, err);
+ }
+
+ return err;
+}
+
+int arm_bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ int err = fvp_bl2_plat_handle_post_image_load(image_id);
+
+ if (err != 0) {
+ ERROR("%s() returns %i\n", __func__, err);
+ }
+
+ return err;
+}
+#endif /* MEASURED_BOOT */
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index 8627c5ef0..f9ee4492f 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -1,10 +1,16 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+#include <common/debug.h>
#include <drivers/arm/smmu_v3.h>
+#include <fconf_hw_config_getter.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <lib/mmio.h>
#include <plat/arm/common/arm_config.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
@@ -14,6 +20,19 @@
void __init bl31_early_platform_setup2(u_register_t arg0,
u_register_t arg1, u_register_t arg2, u_register_t arg3)
{
+#if !RESET_TO_BL31 && !BL2_AT_EL3
+ const struct dyn_cfg_dtb_info_t *soc_fw_config_info;
+
+ INFO("BL31 FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1);
+ /* Fill the properties struct with the info from the config dtb */
+ fconf_populate("FW_CONFIG", arg1);
+
+ soc_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, SOC_FW_CONFIG_ID);
+ if (soc_fw_config_info != NULL) {
+ arg1 = soc_fw_config_info->config_addr;
+ }
+#endif /* !RESET_TO_BL31 && !BL2_AT_EL3 */
+
arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
/* Initialize the platform config for future decision making */
@@ -41,3 +60,46 @@ void __init bl31_early_platform_setup2(u_register_t arg0,
if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U)
smmuv3_init(PLAT_FVP_SMMUV3_BASE);
}
+
+void __init bl31_plat_arch_setup(void)
+{
+ arm_bl31_plat_arch_setup();
+
+ /*
+ * For RESET_TO_BL31 systems, BL31 is the first bootloader to run.
+ * So there is no BL2 to load the HW_CONFIG dtb into memory before
+ * control is passed to BL31.
+ */
+#if !RESET_TO_BL31 && !BL2_AT_EL3
+ /* HW_CONFIG was also loaded by BL2 */
+ const struct dyn_cfg_dtb_info_t *hw_config_info;
+
+ hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+ assert(hw_config_info != NULL);
+
+ fconf_populate("HW_CONFIG", hw_config_info->config_addr);
+#endif
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ unsigned int counter_base_frequency;
+
+#if !RESET_TO_BL31 && !BL2_AT_EL3
+ /* Get the frequency through FCONF API for HW_CONFIG */
+ counter_base_frequency = FCONF_GET_PROPERTY(hw_config, cpu_timer, clock_freq);
+ if (counter_base_frequency > 0U) {
+ return counter_base_frequency;
+ }
+#endif
+
+ /* Read the frequency from Frequency modes table */
+ counter_base_frequency = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF);
+
+ /* The first entry of the frequency modes table must not be 0 */
+ if (counter_base_frequency == 0U) {
+ panic();
+ }
+
+ return counter_base_frequency;
+}
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index ffaa93de4..52686faca 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,12 +13,17 @@
#include <drivers/arm/sp804_delay_timer.h>
#include <drivers/generic_delay_timer.h>
#include <lib/mmio.h>
+#include <lib/smccc.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <platform_def.h>
+#include <services/arm_arch_svc.h>
+#if SPM_MM
+#include <services/spm_mm_partition.h>
+#endif
+
#include <plat/arm/common/arm_config.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <platform_def.h>
-#include <services/spm_mm_partition.h>
#include "fvp_private.h"
@@ -43,6 +48,18 @@ arm_config_t arm_config;
DEVICE1_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
+#if FVP_GICR_REGION_PROTECTION
+#define MAP_GICD_MEM MAP_REGION_FLAT(BASE_GICD_BASE, \
+ BASE_GICD_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+/* Map all core's redistributor memory as read-only. After boots up,
+ * per-core map its redistributor memory as read-write */
+#define MAP_GICR_MEM MAP_REGION_FLAT(BASE_GICR_BASE, \
+ (BASE_GICR_SIZE * PLATFORM_CORE_COUNT),\
+ MT_DEVICE | MT_RO | MT_SECURE)
+#endif /* FVP_GICR_REGION_PROTECTION */
+
/*
* Need to be mapped with write permissions in order to set a new non-volatile
* counter value.
@@ -65,7 +82,9 @@ const mmap_region_t plat_arm_mmap[] = {
V2M_MAP_FLASH0_RW,
V2M_MAP_IOFPGA,
MAP_DEVICE0,
+#if FVP_INTERCONNECT_DRIVER == FVP_CCN
MAP_DEVICE1,
+#endif
#if TRUSTED_BOARD_BOOT
/* To access the Root of Trust Public Key registers. */
MAP_DEVICE2,
@@ -81,11 +100,16 @@ const mmap_region_t plat_arm_mmap[] = {
V2M_MAP_FLASH0_RW,
V2M_MAP_IOFPGA,
MAP_DEVICE0,
+#if FVP_INTERCONNECT_DRIVER == FVP_CCN
MAP_DEVICE1,
+#endif
ARM_MAP_NS_DRAM1,
#ifdef __aarch64__
ARM_MAP_DRAM2,
#endif
+#if defined(SPD_spmd)
+ ARM_MAP_TRUSTED_DRAM,
+#endif
#ifdef SPD_tspd
ARM_MAP_TSP_SEC_MEM,
#endif
@@ -126,11 +150,18 @@ const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_EL3_TZC_DRAM,
V2M_MAP_IOFPGA,
MAP_DEVICE0,
+#if FVP_GICR_REGION_PROTECTION
+ MAP_GICD_MEM,
+ MAP_GICR_MEM,
+#else
MAP_DEVICE1,
+#endif /* FVP_GICR_REGION_PROTECTION */
ARM_V2M_MAP_MEM_PROTECT,
#if SPM_MM
ARM_SPM_BUF_EL3_MMAP,
#endif
+ /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
+ ARM_DTB_DRAM_NS,
{0}
};
@@ -157,6 +188,8 @@ const mmap_region_t plat_arm_mmap[] = {
V2M_MAP_IOFPGA,
MAP_DEVICE0,
MAP_DEVICE1,
+ /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
+ ARM_DTB_DRAM_NS,
{0}
};
#endif
@@ -410,7 +443,7 @@ int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
void fvp_timer_init(void)
{
-#if FVP_USE_SP804_TIMER
+#if USE_SP804_TIMER
/* Enable the clock override for SP804 timer 0, which means that no
* clock dividers are applied and the raw (35MHz) clock will be used.
*/
@@ -425,5 +458,42 @@ void fvp_timer_init(void)
/* Enable System level generic timer */
mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
CNTCR_FCREQ(0U) | CNTCR_EN);
-#endif /* FVP_USE_SP804_TIMER */
+#endif /* USE_SP804_TIMER */
+}
+
+/*****************************************************************************
+ * plat_is_smccc_feature_available() - This function checks whether SMCCC
+ * feature is availabile for platform.
+ * @fid: SMCCC function id
+ *
+ * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
+ * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
+ *****************************************************************************/
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+ switch (fid) {
+ case SMCCC_ARCH_SOC_ID:
+ return SMC_ARCH_CALL_SUCCESS;
+ default:
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+ }
+}
+
+/* Get SOC version */
+int32_t plat_get_soc_version(void)
+{
+ return (int32_t)
+ ((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT)
+ | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT)
+ | FVP_SOC_ID);
+}
+
+/* Get SOC revision */
+int32_t plat_get_soc_revision(void)
+{
+ unsigned int sys_id;
+
+ sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
+ return (int32_t)((sys_id >> V2M_SYS_ID_REV_SHIFT) &
+ V2M_SYS_ID_REV_MASK);
}
diff --git a/plat/arm/board/fvp/fvp_console.c b/plat/arm/board/fvp/fvp_console.c
new file mode 100644
index 000000000..1a6cd4202
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_console.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+#include <fconf_hw_config_getter.h>
+#include <plat/arm/common/plat_arm.h>
+
+static console_t fvp_runtime_console;
+
+/* Initialize the runtime console */
+void arm_console_runtime_init(void)
+{
+ uintptr_t uart_base;
+ uint32_t uart_clk;
+
+ /*
+ * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and
+ * BL2_AT_EL3 systems.
+ */
+#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3
+ uart_base = PLAT_ARM_RUN_UART_BASE;
+ uart_clk = PLAT_ARM_RUN_UART_CLK_IN_HZ;
+#else
+ uart_base = FCONF_GET_PROPERTY(hw_config, uart_serial_config,
+ uart_base);
+ uart_clk = FCONF_GET_PROPERTY(hw_config, uart_serial_config,
+ uart_clk);
+#endif
+
+ int rc = console_pl011_register(uart_base, uart_clk,
+ ARM_CONSOLE_BAUDRATE,
+ &fvp_runtime_console);
+
+ if (rc == 0) {
+ panic();
+ }
+
+ console_set_scope(&fvp_runtime_console, CONSOLE_FLAG_RUNTIME);
+}
+
+void arm_console_runtime_end(void)
+{
+ console_flush();
+ (void)console_unregister(&fvp_runtime_console);
+}
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
index 347ba2e1e..831eb35b7 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,6 +27,11 @@
#define FVP_CCI 1
#define FVP_CCN 2
+/******************************************************************************
+ * Definition of platform soc id
+ *****************************************************************************/
+#define FVP_SOC_ID 0
+
/*******************************************************************************
* FVP memory map related constants
******************************************************************************/
@@ -52,8 +57,18 @@
#define DEVICE1_BASE UL(0x2e000000)
#define DEVICE1_SIZE UL(0x1A00000)
#else
-#define DEVICE1_BASE UL(0x2f000000)
-#define DEVICE1_SIZE UL(0x200000)
+#define DEVICE1_BASE BASE_GICD_BASE
+
+#if GIC_ENABLE_V4_EXTN
+/* GICv4 mapping: GICD + CORE_COUNT * 256KB */
+#define DEVICE1_SIZE ((BASE_GICR_BASE - BASE_GICD_BASE) + \
+ (PLATFORM_CORE_COUNT * 0x40000))
+#else
+/* GICv2 and GICv3 mapping: GICD + CORE_COUNT * 128KB */
+#define DEVICE1_SIZE ((BASE_GICR_BASE - BASE_GICD_BASE) + \
+ (PLATFORM_CORE_COUNT * 0x20000))
+#endif /* GIC_ENABLE_V4_EXTN */
+
#define NSRAM_BASE UL(0x2e000000)
#define NSRAM_SIZE UL(0x10000)
#endif
@@ -110,7 +125,7 @@
#define FVP_SP810_CTRL_TIM3_OV BIT_32(22)
/*******************************************************************************
- * GIC-400 & interrupt handling related constants
+ * GIC & interrupt handling related constants
******************************************************************************/
/* VE compatible GIC memory map */
#define VE_GICD_BASE UL(0x2c001000)
@@ -120,7 +135,16 @@
/* Base FVP compatible GIC memory map */
#define BASE_GICD_BASE UL(0x2f000000)
+#define BASE_GICD_SIZE UL(0x10000)
#define BASE_GICR_BASE UL(0x2f100000)
+
+#if GIC_ENABLE_V4_EXTN
+/* GICv4 redistributor size: 256KB */
+#define BASE_GICR_SIZE UL(0x40000)
+#else
+#define BASE_GICR_SIZE UL(0x20000)
+#endif /* GIC_ENABLE_V4_EXTN */
+
#define BASE_GICC_BASE UL(0x2c000000)
#define BASE_GICH_BASE UL(0x2c010000)
#define BASE_GICV_BASE UL(0x2c02f000)
@@ -128,7 +152,6 @@
#define FVP_IRQ_TZ_WDOG 56
#define FVP_IRQ_SEC_SYS_TIMER 57
-
/*******************************************************************************
* TrustZone address space controller related constants
******************************************************************************/
diff --git a/plat/arm/board/fvp/fvp_err.c b/plat/arm/board/fvp/fvp_err.c
index 2437cd474..c9b20905f 100644
--- a/plat/arm/board/fvp/fvp_err.c
+++ b/plat/arm/board/fvp/fvp_err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,7 +10,6 @@
#include <drivers/arm/sp805.h>
#include <drivers/cfi/v2m_flash.h>
#include <plat/arm/common/plat_arm.h>
-#include <plat/common/platform.h>
#include <platform_def.h>
/*
@@ -38,7 +37,7 @@ __dead2 void plat_arm_error_handler(int err)
break;
}
- (void)console_flush();
+ console_flush();
/* Setup the watchdog to reset the system as soon as possible */
sp805_refresh(ARM_SP805_TWDG_BASE, 1U);
diff --git a/plat/arm/board/fvp/fvp_gicv3.c b/plat/arm/board/fvp/fvp_gicv3.c
new file mode 100644
index 000000000..8f3e7b702
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_gicv3.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <platform_def.h>
+
+#include <common/interrupt_props.h>
+#include <drivers/arm/gicv3.h>
+#include <fconf_hw_config_getter.h>
+#include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/common/fconf_sec_intr_config.h>
+#include <plat/common/platform.h>
+
+#if FVP_GICR_REGION_PROTECTION
+/* To indicate GICR region of the core initialized as Read-Write */
+static bool fvp_gicr_rw_region_init[PLATFORM_CORE_COUNT] = {false};
+#endif /* FVP_GICR_REGION_PROTECTION */
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t fvp_rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+/* Default GICR base address to be used for GICR probe. */
+static uint64_t fvp_gicr_base_addrs[2] = { 0U };
+
+/* List of zero terminated GICR frame addresses which CPUs will probe */
+static uint64_t *fvp_gicr_frames = fvp_gicr_base_addrs;
+
+#if !(SEC_INT_DESC_IN_FCONF && ((!defined(__aarch64__) && defined(IMAGE_BL32)) || \
+ (defined(__aarch64__) && defined(IMAGE_BL31))))
+static const interrupt_prop_t fvp_interrupt_props[] = {
+ PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
+ PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
+};
+#endif
+
+/*
+ * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
+ * to core position.
+ *
+ * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
+ * values read from GICR_TYPER don't have an MT field. To reuse the same
+ * translation used for CPUs, we insert MT bit read from the PE's MPIDR into
+ * that read from GICR_TYPER.
+ *
+ * Assumptions:
+ *
+ * - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
+ * - No CPUs implemented in the system use affinity level 3.
+ */
+static unsigned int fvp_gicv3_mpidr_hash(u_register_t mpidr)
+{
+ u_register_t temp_mpidr = mpidr;
+
+ temp_mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
+ return plat_arm_calc_core_pos(temp_mpidr);
+}
+
+
+static gicv3_driver_data_t fvp_gic_data = {
+ .rdistif_num = PLATFORM_CORE_COUNT,
+ .rdistif_base_addrs = fvp_rdistif_base_addrs,
+ .mpidr_to_core_pos = fvp_gicv3_mpidr_hash
+};
+
+/******************************************************************************
+ * This function gets called per core to make its redistributor frame rw
+ *****************************************************************************/
+static void fvp_gicv3_make_rdistrif_rw(void)
+{
+#if FVP_GICR_REGION_PROTECTION
+ unsigned int core_pos = plat_my_core_pos();
+
+ /* Make the redistributor frame RW if it is not done previously */
+ if (fvp_gicr_rw_region_init[core_pos] != true) {
+ int ret = xlat_change_mem_attributes(BASE_GICR_BASE +
+ (core_pos * BASE_GICR_SIZE),
+ BASE_GICR_SIZE,
+ MT_EXECUTE_NEVER |
+ MT_DEVICE | MT_RW |
+ MT_SECURE);
+
+ if (ret != 0) {
+ ERROR("Failed to make redistributor frame \
+ read write = %d\n", ret);
+ panic();
+ } else {
+ fvp_gicr_rw_region_init[core_pos] = true;
+ }
+ }
+#else
+ return;
+#endif /* FVP_GICR_REGION_PROTECTION */
+}
+
+void plat_arm_gic_driver_init(void)
+{
+ fvp_gicv3_make_rdistrif_rw();
+ /*
+ * Get GICD and GICR base addressed through FCONF APIs.
+ * FCONF is not supported in BL32 for FVP.
+ */
+#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \
+ (defined(__aarch64__) && defined(IMAGE_BL31))
+ fvp_gic_data.gicd_base = (uintptr_t)FCONF_GET_PROPERTY(hw_config,
+ gicv3_config,
+ gicd_base);
+ fvp_gicr_base_addrs[0] = FCONF_GET_PROPERTY(hw_config, gicv3_config,
+ gicr_base);
+#if SEC_INT_DESC_IN_FCONF
+ fvp_gic_data.interrupt_props = FCONF_GET_PROPERTY(hw_config,
+ sec_intr_prop, descriptor);
+ fvp_gic_data.interrupt_props_num = FCONF_GET_PROPERTY(hw_config,
+ sec_intr_prop, count);
+#else
+ fvp_gic_data.interrupt_props = fvp_interrupt_props;
+ fvp_gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props);
+#endif
+#else
+ fvp_gic_data.gicd_base = PLAT_ARM_GICD_BASE;
+ fvp_gicr_base_addrs[0] = PLAT_ARM_GICR_BASE;
+ fvp_gic_data.interrupt_props = fvp_interrupt_props;
+ fvp_gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props);
+#endif
+
+ /*
+ * The GICv3 driver is initialized in EL3 and does not need
+ * to be initialized again in SEL1. This is because the S-EL1
+ * can use GIC system registers to manage interrupts and does
+ * not need GIC interface base addresses to be configured.
+ */
+
+#if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \
+ (defined(__aarch64__) && defined(IMAGE_BL31))
+ gicv3_driver_init(&fvp_gic_data);
+ if (gicv3_rdistif_probe((uintptr_t)fvp_gicr_base_addrs[0]) == -1) {
+ ERROR("No GICR base frame found for Primary CPU\n");
+ panic();
+ }
+#endif
+}
+
+/******************************************************************************
+ * Function to iterate over all GICR frames and discover the corresponding
+ * per-cpu redistributor frame as well as initialize the corresponding
+ * interface in GICv3.
+ *****************************************************************************/
+void plat_arm_gic_pcpu_init(void)
+{
+ int result;
+ const uint64_t *plat_gicr_frames = fvp_gicr_frames;
+
+ fvp_gicv3_make_rdistrif_rw();
+
+ do {
+ result = gicv3_rdistif_probe(*plat_gicr_frames);
+
+ /* If the probe is successful, no need to proceed further */
+ if (result == 0)
+ break;
+
+ plat_gicr_frames++;
+ } while (*plat_gicr_frames != 0U);
+
+ if (result == -1) {
+ ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr());
+ panic();
+ }
+ gicv3_rdistif_init(plat_my_core_pos());
+}
diff --git a/plat/arm/board/fvp/fvp_io_storage.c b/plat/arm/board/fvp/fvp_io_storage.c
index 9c4c1d574..109d32150 100644
--- a/plat/arm/board/fvp/fvp_io_storage.c
+++ b/plat/arm/board/fvp/fvp_io_storage.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -120,18 +120,22 @@ void plat_arm_io_setup(void)
{
int io_result;
- arm_io_setup();
+ io_result = arm_io_setup();
+ if (io_result < 0) {
+ panic();
+ }
/* Register the additional IO devices on this platform */
io_result = register_io_dev_sh(&sh_dev_con);
- assert(io_result == 0);
+ if (io_result < 0) {
+ panic();
+ }
/* Open connections to devices and cache the handles */
io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle);
- assert(io_result == 0);
-
- /* Ignore improbable errors in release builds */
- (void)io_result;
+ if (io_result < 0) {
+ panic();
+ }
}
/*
diff --git a/plat/arm/board/fvp/fvp_measured_boot.c b/plat/arm/board/fvp/fvp_measured_boot.c
new file mode 100644
index 000000000..b145aae58
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_measured_boot.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/measured_boot/event_log.h>
+#include <plat/arm/common/plat_arm.h>
+
+/* FVP table with platform specific image IDs, names and PCRs */
+static const image_data_t fvp_images_data[] = {
+ { BL2_IMAGE_ID, BL2_STRING, PCR_0 }, /* Reserved for BL2 */
+ { BL31_IMAGE_ID, BL31_STRING, PCR_0 },
+ { BL32_IMAGE_ID, BL32_STRING, PCR_0 },
+ { BL32_EXTRA1_IMAGE_ID, BL32_EXTRA1_IMAGE_STRING, PCR_0 },
+ { BL32_EXTRA2_IMAGE_ID, BL32_EXTRA2_IMAGE_STRING, PCR_0 },
+ { BL33_IMAGE_ID, BL33_STRING, PCR_0 },
+ { GPT_IMAGE_ID, GPT_IMAGE_STRING, PCR_0 },
+ { HW_CONFIG_ID, HW_CONFIG_STRING, PCR_0 },
+ { NT_FW_CONFIG_ID, NT_FW_CONFIG_STRING, PCR_0 },
+ { SCP_BL2_IMAGE_ID, SCP_BL2_IMAGE_STRING, PCR_0 },
+ { SOC_FW_CONFIG_ID, SOC_FW_CONFIG_STRING, PCR_0 },
+ { STM32_IMAGE_ID, STM32_IMAGE_STRING, PCR_0 },
+ { TOS_FW_CONFIG_ID, TOS_FW_CONFIG_STRING, PCR_0 },
+ { INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
+};
+
+static const measured_boot_data_t fvp_measured_boot_data = {
+ fvp_images_data,
+ arm_set_nt_fw_info,
+ arm_set_tos_fw_info
+};
+
+/*
+ * Function retuns pointer to FVP plat_measured_boot_data_t structure
+ */
+const measured_boot_data_t *plat_get_measured_boot_data(void)
+{
+ return &fvp_measured_boot_data;
+}
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 0a62543fa..333d89288 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -1,11 +1,10 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <errno.h>
#include <arch_helpers.h>
#include <common/debug.h>
@@ -16,7 +15,6 @@
#include <lib/psci/psci.h>
#include <plat/arm/common/arm_config.h>
#include <plat/arm/common/plat_arm.h>
-#include <plat/common/platform.h>
#include <platform_def.h>
#include "fvp_private.h"
@@ -66,6 +64,25 @@ static void fvp_cluster_pwrdwn_common(void)
/* Disable coherency if this cluster is to be turned off */
fvp_interconnect_disable();
+#if HW_ASSISTED_COHERENCY
+ uint32_t reg;
+
+ /*
+ * If we have determined this core to be the last man standing and we
+ * intend to power down the cluster proactively, we provide a hint to
+ * the power controller that cluster power is not required when all
+ * cores are powered down.
+ * Note that this is only an advisory to power controller and is supported
+ * by SoCs with DynamIQ Shared Units only.
+ */
+ reg = read_clusterpwrdn();
+
+ /* Clear and set bit 0 : Cluster power not required */
+ reg &= ~DSU_CLUSTER_PWR_MASK;
+ reg |= DSU_CLUSTER_PWR_OFF;
+ write_clusterpwrdn(reg);
+#endif
+
/* Program the power controller to turn the cluster off */
fvp_pwrc_write_pcoffr(mpidr);
}
diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c
index 80ec2171b..937f09f6e 100644
--- a/plat/arm/board/fvp/fvp_security.c
+++ b/plat/arm/board/fvp/fvp_security.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,5 +22,5 @@ void plat_arm_security_setup(void)
*/
if ((get_arm_config()->flags & ARM_CONFIG_HAS_TZC) != 0U)
- arm_tzc400_setup(NULL);
+ arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL);
}
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
index 24e79b4d4..80cfbd5ce 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -1,18 +1,21 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <platform_def.h>
+#include <assert.h>
#include <arch.h>
#include <drivers/arm/fvp/fvp_pwrc.h>
+#include <fconf_hw_config_getter.h>
#include <lib/cassert.h>
#include <plat/arm/common/arm_config.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
+#include <platform_def.h>
+
/* The FVP power domain tree descriptor */
static unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 2];
@@ -21,24 +24,47 @@ CASSERT(((FVP_CLUSTER_COUNT > 0) && (FVP_CLUSTER_COUNT <= 256)),
assert_invalid_fvp_cluster_count);
/*******************************************************************************
- * This function dynamically constructs the topology according to
- * FVP_CLUSTER_COUNT and returns it.
+ * This function dynamically constructs the topology according to cpu-map node
+ * in HW_CONFIG dtb and returns it.
******************************************************************************/
const unsigned char *plat_get_power_domain_tree_desc(void)
{
- int i;
+ unsigned int i;
+ uint32_t cluster_count, cpus_per_cluster;
+
+ /*
+ * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and
+ * BL2_AT_EL3 systems.
+ */
+#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3
+ cluster_count = FVP_CLUSTER_COUNT;
+ cpus_per_cluster = FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU;
+#else
+ cluster_count = FCONF_GET_PROPERTY(hw_config, topology, plat_cluster_count);
+ cpus_per_cluster = FCONF_GET_PROPERTY(hw_config, topology, cluster_cpu_count);
+ /* Several FVP Models use the same blanket dts. Ex: FVP_Base_Cortex-A65x4
+ * and FVP_Base_Cortex-A65AEx8 both use same dts but have different number of
+ * CPUs in the cluster, as reflected by build flags FVP_MAX_CPUS_PER_CLUSTER.
+ * Take the minimum of two to ensure PSCI functions do not exceed the size of
+ * the PSCI data structures allocated at build time.
+ */
+ cpus_per_cluster = MIN(cpus_per_cluster,
+ (uint32_t)(FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU));
+
+#endif
+
+ assert(cluster_count > 0U);
+ assert(cpus_per_cluster > 0U);
/*
* The highest level is the system level. The next level is constituted
* by clusters and then cores in clusters.
*/
fvp_power_domain_tree_desc[0] = 1;
- fvp_power_domain_tree_desc[1] = FVP_CLUSTER_COUNT;
-
- for (i = 0; i < FVP_CLUSTER_COUNT; i++)
- fvp_power_domain_tree_desc[i + 2] =
- FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU;
+ fvp_power_domain_tree_desc[1] = (unsigned char)cluster_count;
+ for (i = 0; i < cluster_count; i++)
+ fvp_power_domain_tree_desc[i + 2] = (unsigned char)cpus_per_cluster;
return fvp_power_domain_tree_desc;
}
diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c
index dc5076435..1ea37f7a3 100644
--- a/plat/arm/board/fvp/fvp_trusted_boot.c
+++ b/plat/arm/board/fvp/fvp_trusted_boot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,12 +9,33 @@
#include <string.h>
#include <lib/mmio.h>
-
+#include <lib/fconf/fconf.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/common/fconf_nv_cntr_getter.h>
#include <plat/common/platform.h>
#include <platform_def.h>
#include <tools_share/tbbr_oid.h>
/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
+
+/*
* Store a new non-volatile counter value.
*
* On some FVP versions, the non-volatile counters are read-only so this
@@ -31,9 +52,11 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
oid = (const char *)cookie;
if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
- nv_ctr_addr = TFW_NVCTR_BASE;
+ nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+ TRUSTED_NV_CTR_ID);
} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
- nv_ctr_addr = NTFW_CTR_BASE;
+ nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+ NON_TRUSTED_NV_CTR_ID);
} else {
return 1;
}
diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
new file mode 100644
index 000000000..ca85f7a70
--- /dev/null
+++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_HW_CONFIG_GETTER_H
+#define FCONF_HW_CONFIG_GETTER_H
+
+#include <lib/fconf/fconf.h>
+
+/* Hardware Config related getter */
+#define hw_config__gicv3_config_getter(prop) gicv3_config.prop
+#define hw_config__topology_getter(prop) soc_topology.prop
+#define hw_config__uart_serial_config_getter(prop) uart_serial_config.prop
+#define hw_config__cpu_timer_getter(prop) cpu_timer.prop
+
+struct gicv3_config_t {
+ uint64_t gicd_base;
+ uint64_t gicr_base;
+};
+
+struct hw_topology_t {
+ uint32_t plat_cluster_count;
+ uint32_t cluster_cpu_count;
+ uint32_t plat_cpu_count;
+ uint32_t plat_max_pwr_level;
+};
+
+struct uart_serial_config_t {
+ uint64_t uart_base;
+ uint32_t uart_clk;
+};
+
+struct cpu_timer_t {
+ uint32_t clock_freq;
+};
+
+int fconf_populate_gicv3_config(uintptr_t config);
+int fconf_populate_topology(uintptr_t config);
+int fconf_populate_uart_config(uintptr_t config);
+int fconf_populate_cpu_timer(uintptr_t config);
+
+extern struct gicv3_config_t gicv3_config;
+extern struct hw_topology_t soc_topology;
+extern struct uart_serial_config_t uart_serial_config;
+extern struct cpu_timer_t cpu_timer;
+#endif /* FCONF_HW_CONFIG_GETTER_H */
diff --git a/plat/arm/board/fvp/include/fconf_nt_config_getter.h b/plat/arm/board/fvp/include/fconf_nt_config_getter.h
new file mode 100644
index 000000000..0824c3509
--- /dev/null
+++ b/plat/arm/board/fvp/include/fconf_nt_config_getter.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_NT_CONFIG_GETTER_H
+#define FCONF_NT_CONFIG_GETTER_H
+
+#include <lib/fconf/fconf.h>
+
+/* NT Firmware Config related getter */
+#define nt_config__event_log_config_getter(prop) event_log.prop
+
+struct event_log_config_t {
+#ifdef SPD_opteed
+ void *tpm_event_log_sm_addr;
+#endif
+ void *tpm_event_log_addr;
+ size_t tpm_event_log_size;
+};
+
+int fconf_populate_event_log_config(uintptr_t config);
+
+extern struct event_log_config_t event_log_config;
+
+#endif /* FCONF_NT_CONFIG_GETTER_H */
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index c2b7b98d4..8defcf837 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -43,6 +43,15 @@
#define PLAT_ARM_TRUSTED_DRAM_BASE UL(0x06000000)
#define PLAT_ARM_TRUSTED_DRAM_SIZE UL(0x02000000) /* 32 MB */
+/*
+ * Max size of SPMC is 2MB for fvp. With SPMD enabled this value corresponds to
+ * max size of BL32 image.
+ */
+#if defined(SPD_spmd)
+#define PLAT_ARM_SPMC_BASE PLAT_ARM_TRUSTED_DRAM_BASE
+#define PLAT_ARM_SPMC_SIZE UL(0x200000) /* 2 MB */
+#endif
+
/* virtual address used by dynamic mem_protect for chunk_base */
#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
@@ -52,6 +61,13 @@
#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
#define PLAT_ARM_DRAM2_SIZE UL(0x80000000)
+#define PLAT_HW_CONFIG_DTB_BASE ULL(0x82000000)
+#define PLAT_HW_CONFIG_DTB_SIZE ULL(0x8000)
+
+#define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \
+ PLAT_HW_CONFIG_DTB_BASE, \
+ PLAT_HW_CONFIG_DTB_SIZE, \
+ MT_MEMORY | MT_RO | MT_NS)
/*
* Load address of BL33 for this platform port
*/
@@ -63,21 +79,21 @@
*/
#if defined(IMAGE_BL31)
# if SPM_MM
-# define PLAT_ARM_MMAP_ENTRIES 9
+# define PLAT_ARM_MMAP_ENTRIES 10
# define MAX_XLAT_TABLES 9
# define PLAT_SP_IMAGE_MMAP_REGIONS 30
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
# else
-# define PLAT_ARM_MMAP_ENTRIES 8
+# define PLAT_ARM_MMAP_ENTRIES 9
# if USE_DEBUGFS
-# define MAX_XLAT_TABLES 6
+# define MAX_XLAT_TABLES 8
# else
-# define MAX_XLAT_TABLES 5
+# define MAX_XLAT_TABLES 7
# endif
# endif
#elif defined(IMAGE_BL32)
-# define PLAT_ARM_MMAP_ENTRIES 8
-# define MAX_XLAT_TABLES 5
+# define PLAT_ARM_MMAP_ENTRIES 9
+# define MAX_XLAT_TABLES 6
#elif !USE_ROMLIB
# define PLAT_ARM_MMAP_ENTRIES 11
# define MAX_XLAT_TABLES 5
@@ -111,17 +127,27 @@
* little space for growth.
*/
#if TRUSTED_BOARD_BOOT
+#if COT_DESC_IN_DTB
+# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1E000) - FVP_BL2_ROMLIB_OPTIMIZATION)
+#else
# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - FVP_BL2_ROMLIB_OPTIMIZATION)
+#endif
#else
-# define PLAT_ARM_MAX_BL2_SIZE (UL(0x11000) - FVP_BL2_ROMLIB_OPTIMIZATION)
+# define PLAT_ARM_MAX_BL2_SIZE (UL(0x13000) - FVP_BL2_ROMLIB_OPTIMIZATION)
#endif
+#if RESET_TO_BL31
+/* Size of Trusted SRAM - the first 4KB of shared memory */
+#define PLAT_ARM_MAX_BL31_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \
+ ARM_SHARED_RAM_SIZE)
+#else
/*
* Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
* calculated using the current BL31 PROGBITS debug size plus the sizes of
* BL2 and BL1-RW
*/
-#define PLAT_ARM_MAX_BL31_SIZE UL(0x3B000)
+#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000)
+#endif /* RESET_TO_BL31 */
#ifndef __aarch64__
/*
@@ -139,13 +165,13 @@
# if TRUSTED_BOARD_BOOT
# define PLATFORM_STACK_SIZE UL(0x1000)
# else
-# define PLATFORM_STACK_SIZE UL(0x440)
+# define PLATFORM_STACK_SIZE UL(0x500)
# endif
#elif defined(IMAGE_BL2)
# if TRUSTED_BOARD_BOOT
# define PLATFORM_STACK_SIZE UL(0x1000)
# else
-# define PLATFORM_STACK_SIZE UL(0x400)
+# define PLATFORM_STACK_SIZE UL(0x440)
# endif
#elif defined(IMAGE_BL2U)
# define PLATFORM_STACK_SIZE UL(0x400)
@@ -230,8 +256,8 @@
/*
* GIC related constants to cater for both GICv2 and GICv3 instances of an
- * FVP. They could be overriden at runtime in case the FVP implements the legacy
- * VE memory map.
+ * FVP. They could be overridden at runtime in case the FVP implements the
+ * legacy VE memory map.
*/
#define PLAT_ARM_GICD_BASE BASE_GICD_BASE
#define PLAT_ARM_GICR_BASE BASE_GICR_BASE
@@ -251,8 +277,13 @@
#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
+#if SDEI_IN_FCONF
+#define PLAT_SDEI_DP_EVENT_MAX_CNT ARM_SDEI_DP_EVENT_MAX_CNT
+#define PLAT_SDEI_DS_EVENT_MAX_CNT ARM_SDEI_DS_EVENT_MAX_CNT
+#else
#define PLAT_ARM_PRIVATE_SDEI_EVENTS ARM_SDEI_PRIVATE_EVENTS
#define PLAT_ARM_SHARED_SDEI_EVENTS ARM_SDEI_SHARED_EVENTS
+#endif
#define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \
PLAT_SP_IMAGE_NS_BUF_SIZE)
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index 6ccdd283f..b72bdab4a 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -15,11 +15,26 @@
# fdt fdt_getprop_namelen patch
rom rom_lib_init
+fdt fdt_getprop
+fdt fdt_get_property
fdt fdt_getprop_namelen
fdt fdt_setprop_inplace
fdt fdt_check_header
fdt fdt_node_offset_by_compatible
fdt fdt_setprop_inplace_namelen_partial
+fdt fdt_first_subnode
+fdt fdt_next_subnode
+fdt fdt_path_offset
+fdt fdt_path_offset_namelen
+fdt fdt_subnode_offset
+fdt fdt_address_cells
+fdt fdt_size_cells
+fdt fdt_parent_offset
+fdt fdt_stringlist_search
+fdt fdt_get_alias_namelen
+fdt fdt_get_name
+fdt fdt_get_alias
+fdt fdt_node_offset_by_phandle
mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 97a326c09..6c09d7268 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -7,9 +7,6 @@
# Use the GICv3 driver on the FVP by default
FVP_USE_GIC_DRIVER := FVP_GICV3
-# Use the SP804 timer instead of the generic one
-FVP_USE_SP804_TIMER := 0
-
# Default cluster count for FVP
FVP_CLUSTER_COUNT := 2
@@ -19,10 +16,11 @@ FVP_MAX_CPUS_PER_CLUSTER := 4
# Default number of threads per CPU on FVP
FVP_MAX_PE_PER_CPU := 1
-FVP_DT_PREFIX := fvp-base-gicv3-psci
+# Disable redistributor frame of inactive/fused CPU cores by marking it as read
+# only; enable redistributor frames of all CPU cores by default.
+FVP_GICR_REGION_PROTECTION := 0
-$(eval $(call assert_boolean,FVP_USE_SP804_TIMER))
-$(eval $(call add_define,FVP_USE_SP804_TIMER))
+FVP_DT_PREFIX := fvp-base-gicv3-psci
# The FVP platform depends on this macro to build with correct GIC driver.
$(eval $(call add_define,FVP_USE_GIC_DRIVER))
@@ -36,6 +34,9 @@ $(eval $(call add_define,FVP_MAX_CPUS_PER_CLUSTER))
# Pass FVP_MAX_PE_PER_CPU to the build system.
$(eval $(call add_define,FVP_MAX_PE_PER_CPU))
+# Pass FVP_GICR_REGION_PROTECTION to the build system.
+$(eval $(call add_define,FVP_GICR_REGION_PROTECTION))
+
# Sanity check the cluster count and if FVP_CLUSTER_COUNT <= 2,
# choose the CCI driver , else the CCN driver
ifeq ($(FVP_CLUSTER_COUNT), 0)
@@ -48,23 +49,34 @@ endif
$(eval $(call add_define,FVP_INTERCONNECT_DRIVER))
-FVP_GICV3_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/v3/gicv3_helpers.c \
+# Choose the GIC sources depending upon the how the FVP will be invoked
+ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3)
+
+# The GIC model (GIC-600 or GIC-500) will be detected at runtime
+GICV3_SUPPORT_GIC600 := 1
+GICV3_OVERRIDE_DISTIF_PWR_OPS := 1
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+FVP_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
plat/arm/common/arm_gicv3.c
-# Choose the GIC sources depending upon the how the FVP will be invoked
-ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3)
-FVP_GIC_SOURCES := ${FVP_GICV3_SOURCES} \
- drivers/arm/gic/v3/gic500.c
-else ifeq (${FVP_USE_GIC_DRIVER},FVP_GIC600)
-FVP_GIC_SOURCES := ${FVP_GICV3_SOURCES} \
- drivers/arm/gic/v3/gic600.c
+ ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31} ${RESET_TO_SP_MIN}),)
+ FVP_GIC_SOURCES += plat/arm/board/fvp/fvp_gicv3.c
+ endif
+
else ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV2)
-FVP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
+
+# No GICv4 extension
+GIC_ENABLE_V4_EXTN := 0
+$(eval $(call add_define,GIC_ENABLE_V4_EXTN))
+
+# Include GICv2 driver files
+include drivers/arm/gic/v2/gicv2.mk
+
+FVP_GIC_SOURCES := ${GICV2_SOURCES} \
plat/common/plat_gicv2.c \
plat/arm/common/arm_gicv2.c
@@ -112,11 +124,15 @@ else
FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a76.S \
lib/cpus/aarch64/cortex_a76ae.S \
lib/cpus/aarch64/cortex_a77.S \
+ lib/cpus/aarch64/cortex_a78.S \
+ lib/cpus/aarch64/neoverse_n_common.S \
lib/cpus/aarch64/neoverse_n1.S \
+ lib/cpus/aarch64/neoverse_n2.S \
lib/cpus/aarch64/neoverse_e1.S \
- lib/cpus/aarch64/neoverse_zeus.S \
- lib/cpus/aarch64/cortex_hercules.S \
- lib/cpus/aarch64/cortex_hercules_ae.S \
+ lib/cpus/aarch64/neoverse_v1.S \
+ lib/cpus/aarch64/cortex_a78_ae.S \
+ lib/cpus/aarch64/cortex_klein.S \
+ lib/cpus/aarch64/cortex_matterhorn.S \
lib/cpus/aarch64/cortex_a65.S \
lib/cpus/aarch64/cortex_a65ae.S
endif
@@ -139,11 +155,10 @@ BL1_SOURCES += drivers/arm/smmu/smmu_v3.c \
plat/arm/board/fvp/fvp_bl1_setup.c \
plat/arm/board/fvp/fvp_err.c \
plat/arm/board/fvp/fvp_io_storage.c \
- plat/arm/board/fvp/fvp_trusted_boot.c \
${FVP_CPU_LIBS} \
${FVP_INTERCONNECT_SOURCES}
-ifeq (${FVP_USE_SP804_TIMER},1)
+ifeq (${USE_SP804_TIMER},1)
BL1_SOURCES += drivers/arm/sp804/sp804_delay_timer.c
else
BL1_SOURCES += drivers/delay_timer/generic_delay_timer.c
@@ -158,11 +173,13 @@ BL2_SOURCES += drivers/arm/sp805/sp805.c \
plat/arm/board/fvp/fvp_bl2_setup.c \
plat/arm/board/fvp/fvp_err.c \
plat/arm/board/fvp/fvp_io_storage.c \
- plat/arm/board/fvp/fvp_trusted_boot.c \
plat/arm/common/arm_nor_psci_mem_protect.c \
${FVP_SECURITY_SOURCES}
+ifeq (${COT_DESC_IN_DTB},1)
+BL2_SOURCES += plat/arm/common/fconf/fconf_nv_cntr_getter.c
+endif
ifeq (${BL2_AT_EL3},1)
BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \
@@ -171,14 +188,14 @@ BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \
${FVP_INTERCONNECT_SOURCES}
endif
-ifeq (${FVP_USE_SP804_TIMER},1)
+ifeq (${USE_SP804_TIMER},1)
BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c
endif
BL2U_SOURCES += plat/arm/board/fvp/fvp_bl2u_setup.c \
${FVP_SECURITY_SOURCES}
-ifeq (${FVP_USE_SP804_TIMER},1)
+ifeq (${USE_SP804_TIMER},1)
BL2U_SOURCES += drivers/arm/sp804/sp804_delay_timer.c
endif
@@ -188,6 +205,7 @@ BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \
drivers/cfi/v2m/v2m_flash.c \
lib/utils/mem_region.c \
plat/arm/board/fvp/fvp_bl31_setup.c \
+ plat/arm/board/fvp/fvp_console.c \
plat/arm/board/fvp/fvp_pm.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/aarch64/fvp_helpers.S \
@@ -197,7 +215,21 @@ BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \
${FVP_INTERCONNECT_SOURCES} \
${FVP_SECURITY_SOURCES}
-ifeq (${FVP_USE_SP804_TIMER},1)
+# Support for fconf in BL31
+# Added separately from the above list for better readability
+ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31}),)
+BL31_SOURCES += common/fdt_wrappers.c \
+ lib/fconf/fconf.c \
+ lib/fconf/fconf_dyn_cfg_getter.c \
+ plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+
+ifeq (${SEC_INT_DESC_IN_FCONF},1)
+BL31_SOURCES += plat/arm/common/fconf/fconf_sec_intr_config.c
+endif
+
+endif
+
+ifeq (${USE_SP804_TIMER},1)
BL31_SOURCES += drivers/arm/sp804/sp804_delay_timer.c
else
BL31_SOURCES += drivers/delay_timer/generic_delay_timer.c
@@ -207,11 +239,13 @@ endif
ifdef UNIX_MK
FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts
FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \
+ ${PLAT}_fw_config.dts \
${PLAT}_tb_fw_config.dts \
${PLAT}_soc_fw_config.dts \
${PLAT}_nt_fw_config.dts \
)
+FVP_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
FVP_SOC_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb
FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
@@ -221,21 +255,36 @@ FDT_SOURCES += plat/arm/board/fvp/fdts/${PLAT}_tsp_fw_config.dts
FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tsp_fw_config.dtb
# Add the TOS_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG}))
+endif
+
+ifeq (${SPD},spmd)
+
+ifeq ($(ARM_SPMC_MANIFEST_DTS),)
+ARM_SPMC_MANIFEST_DTS := plat/arm/board/fvp/fdts/${PLAT}_spmc_manifest.dts
+endif
+
+FDT_SOURCES += ${ARM_SPMC_MANIFEST_DTS}
+FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/$(notdir $(basename ${ARM_SPMC_MANIFEST_DTS})).dtb
+
+# Add the TOS_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG}))
endif
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config,${FVP_FW_CONFIG}))
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG}))
# Add the SOC_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config,${FVP_SOC_FW_CONFIG}))
# Add the NT_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG}))
FDT_SOURCES += ${FVP_HW_CONFIG_DTS}
$(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS)))
# Add the HW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG}))
endif
# Enable Activity Monitor Unit extensions by default
@@ -277,19 +326,30 @@ endif
# Enable the dynamic translation tables library.
ifeq (${ARCH},aarch32)
ifeq (${RESET_TO_SP_MIN},1)
- BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+ BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
endif
-else # if AArch64
+else # AArch64
ifeq (${RESET_TO_BL31},1)
- BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+ BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
endif
ifeq (${SPD},trusty)
- BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+ BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
+ endif
+endif
+
+ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
+ ifeq (${ARCH},aarch32)
+ BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES
+ else # AArch64
+ BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES
+ ifeq (${SPD},tspd)
+ BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES
+ endif
endif
endif
ifeq (${USE_DEBUGFS},1)
- BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+ BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
endif
# Add support for platform supplied linker script for BL31 build
@@ -302,8 +362,15 @@ endif
include plat/arm/board/common/board_common.mk
include plat/arm/common/arm_common.mk
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c
+BL2_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c
+
+ifeq (${MEASURED_BOOT},1)
+BL2_SOURCES += plat/arm/board/fvp/fvp_measured_boot.c
+endif
+
# FVP being a development platform, enable capability to disable Authentication
# dynamically if TRUSTED_BOARD_BOOT is set.
-ifeq (${TRUSTED_BOARD_BOOT}, 1)
- DYN_DISABLE_AUTH := 1
+DYN_DISABLE_AUTH := 1
endif
diff --git a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
index 88c91e6fe..763b42afb 100644
--- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
+++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
@@ -1,13 +1,20 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+
+#include <bl32/sp_min/platform_sp_min.h>
+#include <common/debug.h>
+#include <lib/fconf/fconf.h>
#include <plat/arm/common/plat_arm.h>
#include "../fvp_private.h"
+uintptr_t hw_config_dtb;
+
void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
@@ -30,4 +37,24 @@ void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
* FVP PSCI code will enable coherency for other clusters.
*/
fvp_interconnect_enable();
+
+ hw_config_dtb = arg2;
+}
+
+void sp_min_plat_arch_setup(void)
+{
+ arm_sp_min_plat_arch_setup();
+
+ /*
+ * For RESET_TO_SP_MIN systems, SP_MIN(BL32) is the first bootloader
+ * to run. So there is no BL2 to load the HW_CONFIG dtb into memory
+ * before control is passed to SP_MIN.
+ * Also, BL2 skips loading HW_CONFIG dtb for BL2_AT_EL3 builds.
+ */
+#if !RESET_TO_SP_MIN && !BL2_AT_EL3
+ assert(hw_config_dtb != 0U);
+
+ INFO("SP_MIN FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb);
+ fconf_populate("HW_CONFIG", hw_config_dtb);
+#endif
}
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index 0250a5f1a..64cb7add5 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -10,6 +10,7 @@ BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \
lib/utils/mem_region.c \
plat/arm/board/fvp/aarch32/fvp_helpers.S \
plat/arm/board/fvp/fvp_pm.c \
+ plat/arm/board/fvp/fvp_console.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c \
plat/arm/common/arm_nor_psci_mem_protect.c \
@@ -18,4 +19,17 @@ BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \
${FVP_INTERCONNECT_SOURCES} \
${FVP_SECURITY_SOURCES}
+# Support for fconf in SP_MIN(BL32)
+# Added separately from the above list for better readability
+ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_SP_MIN}),)
+BL32_SOURCES += common/fdt_wrappers.c \
+ lib/fconf/fconf.c \
+ plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+
+ifeq (${SEC_INT_DESC_IN_FCONF},1)
+BL32_SOURCES += plat/arm/common/fconf/fconf_sec_intr_config.c
+endif
+
+endif
+
include plat/arm/common/sp_min/arm_sp_min.mk
diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
new file mode 100644
index 000000000..6e5691bd9
--- /dev/null
+++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x80001300>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x82000000>;
+ max-size = <0x01000000>;
+ id = <HW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts
index 9ab2d9656..c66186f64 100644
--- a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts
+++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,11 +7,9 @@
/dts-v1/;
/ {
- /* Platform Config */
- plat_arm_bl2 {
+ tb_fw-config {
compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x82000000>;
- hw_config_max_size = <0x01000000>;
+
/* Disable authentication for development */
disable_auth = <0x0>;
};
diff --git a/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c b/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c
index 25e096417..4ccae27a2 100644
--- a/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c
+++ b/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c
@@ -25,7 +25,7 @@ void bl2_platform_setup(void)
{
arm_bl2_platform_setup();
-#ifdef FVP_VE_USE_SP804_TIMER
+#if USE_SP804_TIMER
/*
* Enable the clock override for SP804 timer 0, which means that no
* clock dividers are applied and the raw (35 MHz) clock will be used
@@ -37,5 +37,5 @@ void bl2_platform_setup(void)
SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV);
#else
generic_delay_timer_init();
-#endif /* FVP_VE_USE_SP804_TIMER */
+#endif /* USE_SP804_TIMER */
}
diff --git a/plat/arm/board/fvp_ve/fvp_ve_err.c b/plat/arm/board/fvp_ve/fvp_ve_err.c
index 7f9d2f7ed..8d3568850 100644
--- a/plat/arm/board/fvp_ve/fvp_ve_err.c
+++ b/plat/arm/board/fvp_ve/fvp_ve_err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,7 @@
*/
void __dead2 plat_arm_error_handler(int err)
{
- while (1) {
+ while (true) {
wfi();
}
}
diff --git a/plat/arm/board/fvp_ve/include/platform_def.h b/plat/arm/board/fvp_ve/include/platform_def.h
index 1b07a9b42..3f2fcee58 100644
--- a/plat/arm/board/fvp_ve/include/platform_def.h
+++ b/plat/arm/board/fvp_ve/include/platform_def.h
@@ -11,6 +11,7 @@
#include <lib/utils_def.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/smccc_def.h>
#include <plat/common/common_def.h>
#include "../fvp_ve_def.h"
@@ -120,10 +121,19 @@
#endif
/*
+ * Map the region for device tree configuration with read and write permissions
+ */
+#define ARM_MAP_BL_CONFIG_REGION MAP_REGION_FLAT(ARM_BL_RAM_BASE, \
+ (ARM_FW_CONFIGS_LIMIT \
+ - ARM_BL_RAM_BASE), \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+
+/*
* The max number of regions like RO(code), coherent and data required by
* different BL stages which need to be mapped in the MMU.
*/
-#define ARM_BL_REGIONS 5
+#define ARM_BL_REGIONS 6
#define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \
ARM_BL_REGIONS)
@@ -168,11 +178,18 @@
#define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT)
/*
- * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base
+ * To enable FW_CONFIG to be loaded by BL1, define the corresponding base
* and limit. Leave enough space of BL2 meminfo.
*/
-#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t))
-#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE)
+#define ARM_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t))
+#define ARM_FW_CONFIG_LIMIT ((ARM_BL_RAM_BASE + PAGE_SIZE) \
+ + (PAGE_SIZE / 2U))
+
+/*
+ * Define limit of firmware configuration memory:
+ * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory
+ */
+#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2))
/*******************************************************************************
* BL1 specific defines.
@@ -203,7 +220,9 @@
/* Put BL32 below BL2 in NS DRAM.*/
-#define ARM_BL2_MEM_DESC_BASE ARM_TB_FW_CONFIG_LIMIT
+#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT
+#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE \
+ + (PAGE_SIZE / 2U))
#define BL32_BASE ((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)\
- PLAT_ARM_MAX_BL32_SIZE)
diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk
index 4d21f4ba0..ac45d57ee 100644
--- a/plat/arm/board/fvp_ve/platform.mk
+++ b/plat/arm/board/fvp_ve/platform.mk
@@ -1,20 +1,20 @@
#
-# Copyright (c) 2019, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
ifdef ARM_CORTEX_A5
# Use the SP804 timer instead of the generic one
-FVP_VE_USE_SP804_TIMER := 1
-$(eval $(call add_define,FVP_VE_USE_SP804_TIMER))
+USE_SP804_TIMER := 1
BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c
endif
-FVP_VE_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
- plat/common/plat_gicv2.c \
+# Include GICv2 driver files
+include drivers/arm/gic/v2/gicv2.mk
+
+FVP_VE_GIC_SOURCES := ${GICV2_SOURCES} \
+ plat/common/plat_gicv2.c \
plat/arm/common/arm_gicv2.c
FVP_VE_SECURITY_SOURCES := plat/arm/board/fvp_ve/fvp_ve_security.c
@@ -42,6 +42,7 @@ BL1_SOURCES += drivers/arm/sp805/sp805.c \
plat/arm/common/arm_err.c \
plat/arm/board/fvp_ve/fvp_ve_err.c \
plat/arm/common/arm_io_storage.c \
+ plat/arm/common/fconf/arm_fconf_io.c \
drivers/cfi/v2m/v2m_flash.c \
plat/arm/board/fvp_ve/${ARCH}/fvp_ve_helpers.S \
plat/arm/board/fvp_ve/fvp_ve_bl1_setup.c \
@@ -63,6 +64,7 @@ BL2_SOURCES += plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c \
plat/arm/common/arm_err.c \
plat/arm/board/fvp_ve/fvp_ve_err.c \
plat/arm/common/arm_io_storage.c \
+ plat/arm/common/fconf/arm_fconf_io.c \
plat/arm/common/${ARCH}/arm_bl2_mem_params_desc.c \
plat/arm/common/arm_image_load.c \
common/desc_image_load.c \
@@ -72,18 +74,22 @@ BL2_SOURCES += plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c \
# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
ifdef UNIX_MK
-FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts
+FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts \
+ plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts
+FVP_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_fw_config.dtb
FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_tb_fw_config.dtb
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config,${FVP_FW_CONFIG}))
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG}))
FDT_SOURCES += ${FVP_HW_CONFIG_DTS}
$(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \
fdts/$(notdir ${FVP_HW_CONFIG_DTS})))
# Add the HW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG}))
endif
NEED_BL32 := yes
@@ -116,6 +122,9 @@ else
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
endif
+# Firmware Configuration Framework sources
+include lib/fconf/fconf.mk
+
# Add `libfdt` and Arm common helpers required for Dynamic Config
include lib/libfdt/libfdt.mk
diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts
new file mode 100644
index 000000000..c0538f863
--- /dev/null
+++ b/plat/arm/board/juno/fdts/juno_fw_config.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
index a8ab6c5f9..80cfa3ea1 100644
--- a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
+++ b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,19 +7,20 @@
/dts-v1/;
/ {
- /* Platform Config */
- compatible = "arm,tb_fw";
- /* Disable authentication for development */
- disable_auth = <0x0>;
- /*
- * The following two entries are placeholders for Mbed TLS
- * heap information. The default values don't matter since
- * they will be overwritten by BL1.
- * In case of having shared Mbed TLS heap between BL1 and BL2,
- * BL1 will populate these two properties with the respective
- * info about the shared heap. This info will be available for
- * BL2 in order to locate and re-use the heap.
- */
- mbedtls_heap_addr = <0x0 0x0>;
- mbedtls_heap_size = <0x0>;
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
};
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 16bb33d7e..91c3ae7e0 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -50,6 +50,9 @@
#define NSRAM_BASE UL(0x2e000000)
#define NSRAM_SIZE UL(0x00008000) /* 32KB */
+#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
+
/* virtual address used by dynamic mem_protect for chunk_base */
#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
@@ -136,7 +139,7 @@
# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - JUNO_BL2_ROMLIB_OPTIMIZATION)
#endif
#else
-# define PLAT_ARM_MAX_BL2_SIZE (UL(0xF000) - JUNO_BL2_ROMLIB_OPTIMIZATION)
+# define PLAT_ARM_MAX_BL2_SIZE (UL(0x13000) - JUNO_BL2_ROMLIB_OPTIMIZATION)
#endif
/*
@@ -145,7 +148,7 @@
* BL2 and BL1-RW. SCP_BL2 image is loaded into the space BL31 -> BL2_BASE.
* Hence the BL31 PROGBITS size should be >= PLAT_CSS_MAX_SCP_BL2_SIZE.
*/
-#define PLAT_ARM_MAX_BL31_SIZE UL(0x3E000)
+#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000)
#if JUNO_AARCH32_EL3_RUNTIME
/*
@@ -154,7 +157,7 @@
* BL2 and BL1-RW. SCP_BL2 image is loaded into the space BL32 -> BL2_BASE.
* Hence the BL32 PROGBITS size should be >= PLAT_CSS_MAX_SCP_BL2_SIZE.
*/
-#define PLAT_ARM_MAX_BL32_SIZE UL(0x3E000)
+#define PLAT_ARM_MAX_BL32_SIZE UL(0x3D000)
#endif
/*
@@ -212,6 +215,9 @@
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_GPU) | \
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CORESIGHT))
+/* TZC related constants */
+#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL
+
/*
* Required ARM CSS based platform porting definitions
*/
@@ -224,7 +230,6 @@
/* MHU related constants */
#define PLAT_CSS_MHU_BASE UL(0x2b1f0000)
-#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
/*
* Base address of the first memory region used for communication between AP
@@ -244,16 +249,14 @@
#endif
/*
- * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
- * SCP_BL2 size plus a little space for growth.
+ * SCP_BL2 uses up whatever remaining space is available as it is loaded before
+ * anything else in this memory region and is handed over to the SCP before
+ * BL31 is loaded over the top.
*/
-#define PLAT_CSS_MAX_SCP_BL2_SIZE UL(0x14000)
+#define PLAT_CSS_MAX_SCP_BL2_SIZE \
+ ((SCP_BL2_LIMIT - ARM_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK)
-/*
- * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
- * SCP_BL2U size plus a little space for growth.
- */
-#define PLAT_CSS_MAX_SCP_BL2U_SIZE UL(0x14000)
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE
#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
CSS_G1S_IRQ_PROPS(grp), \
@@ -301,4 +304,7 @@
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#endif
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i
index 6ccdd283f..393a64816 100644
--- a/plat/arm/board/juno/jmptbl.i
+++ b/plat/arm/board/juno/jmptbl.i
@@ -15,11 +15,25 @@
# fdt fdt_getprop_namelen patch
rom rom_lib_init
+fdt fdt_getprop
+fdt fdt_get_property
fdt fdt_getprop_namelen
fdt fdt_setprop_inplace
fdt fdt_check_header
fdt fdt_node_offset_by_compatible
fdt fdt_setprop_inplace_namelen_partial
+fdt fdt_first_subnode
+fdt fdt_next_subnode
+fdt fdt_parent_offset
+fdt fdt_stringlist_search
+fdt fdt_get_alias_namelen
+fdt fdt_path_offset
+fdt fdt_path_offset_namelen
+fdt fdt_address_cells
+fdt fdt_size_cells
+fdt fdt_get_name
+fdt fdt_get_alias
+fdt fdt_node_offset_by_phandle
mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
index 89398d686..2234055d4 100644
--- a/plat/arm/board/juno/juno_bl1_setup.c
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -60,17 +60,13 @@ static int is_watchdog_reset(void)
* The following function checks if Firmware update is needed,
* by checking if TOC in FIP image is valid or watchdog reset happened.
******************************************************************************/
-int plat_arm_bl1_fwu_needed(void)
+bool plat_arm_bl1_fwu_needed(void)
{
const int32_t *nv_flags_ptr = (const int32_t *)V2M_SYS_NVFLAGS_ADDR;
/* Check if TOC is invalid or watchdog reset happened. */
- if ((arm_io_is_toc_valid() != 1) ||
- (((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT))
- && is_watchdog_reset()))
- return 1;
-
- return 0;
+ return (!arm_io_is_toc_valid() || (((*nv_flags_ptr == -EAUTH) ||
+ (*nv_flags_ptr == -ENOENT)) && is_watchdog_reset()));
}
/*******************************************************************************
@@ -101,7 +97,7 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved)
/* Setup the watchdog to reset the system as soon as possible */
sp805_refresh(ARM_SP805_TWDG_BASE, 1U);
- while (1)
+ while (true)
wfi();
}
diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c
index 9570d2d4c..da4918cf2 100644
--- a/plat/arm/board/juno/juno_common.c
+++ b/plat/arm/board/juno/juno_common.c
@@ -1,10 +1,13 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <lib/smccc.h>
#include <platform_def.h>
+#include <services/arm_arch_svc.h>
+
#include <plat/arm/common/plat_arm.h>
/*
@@ -91,3 +94,40 @@ const mmap_region_t plat_arm_mmap[] = {
#endif
ARM_CASSERT_MMAP
+
+/*****************************************************************************
+ * plat_is_smccc_feature_available() - This function checks whether SMCCC
+ * feature is availabile for platform.
+ * @fid: SMCCC function id
+ *
+ * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
+ * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
+ *****************************************************************************/
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+ switch (fid) {
+ case SMCCC_ARCH_SOC_ID:
+ return SMC_ARCH_CALL_SUCCESS;
+ default:
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+ }
+}
+
+/* Get SOC version */
+int32_t plat_get_soc_version(void)
+{
+ return (int32_t)
+ ((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT)
+ | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT)
+ | JUNO_SOC_ID);
+}
+
+/* Get SOC revision */
+int32_t plat_get_soc_revision(void)
+{
+ unsigned int sys_id;
+
+ sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
+ return (int32_t)((sys_id >> V2M_SYS_ID_REV_SHIFT) &
+ V2M_SYS_ID_REV_MASK);
+}
diff --git a/plat/arm/board/juno/juno_decl.h b/plat/arm/board/juno/juno_decl.h
index cd87c3b77..21e56c051 100644
--- a/plat/arm/board/juno/juno_decl.h
+++ b/plat/arm/board/juno/juno_decl.h
@@ -7,6 +7,6 @@
#ifndef JUNO_DECL_H
#define JUNO_DECL_H
-int juno_getentropy(void *buf, size_t len);
+bool juno_getentropy(uint64_t *buf);
#endif /* JUNO_DECL_H */
diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h
index 3b34a9f6a..ddf99dcdb 100644
--- a/plat/arm/board/juno/juno_def.h
+++ b/plat/arm/board/juno/juno_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,11 @@
#include <lib/utils_def.h>
+/******************************************************************************
+ * Definition of platform soc id
+ *****************************************************************************/
+#define JUNO_SOC_ID 1
+
/*******************************************************************************
* Juno memory map related constants
******************************************************************************/
diff --git a/plat/arm/board/juno/juno_err.c b/plat/arm/board/juno/juno_err.c
index 961bfda17..60699cc73 100644
--- a/plat/arm/board/juno/juno_err.c
+++ b/plat/arm/board/juno/juno_err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,7 +9,6 @@
#include <arch_helpers.h>
#include <drivers/arm/sp805.h>
#include <plat/arm/common/plat_arm.h>
-#include <plat/common/platform.h>
#include <platform_def.h>
/*
diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c
index 32823e01c..1e64c029d 100644
--- a/plat/arm/board/juno/juno_security.c
+++ b/plat/arm/board/juno/juno_security.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -127,13 +127,13 @@ void plat_arm_security_setup(void)
init_debug_cfg();
/* Initialize the TrustZone Controller */
#ifdef JUNO_TZMP1
- arm_tzc400_setup(juno_tzmp1_tzc_regions);
+ arm_tzc400_setup(PLAT_ARM_TZC_BASE, juno_tzmp1_tzc_regions);
INFO("TZC protected shared memory base address for TZMP usecase: %p\n",
(void *)JUNO_AP_TZC_SHARE_DRAM1_BASE);
INFO("TZC protected shared memory end address for TZMP usecase: %p\n",
(void *)JUNO_AP_TZC_SHARE_DRAM1_END);
#else
- arm_tzc400_setup(NULL);
+ arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL);
#endif
/* Do ARM CSS internal NIC setup */
css_init_nic400();
diff --git a/plat/arm/board/juno/juno_stack_protector.c b/plat/arm/board/juno/juno_stack_protector.c
index 236eb5ba3..8c51f574c 100644
--- a/plat/arm/board/juno/juno_stack_protector.c
+++ b/plat/arm/board/juno/juno_stack_protector.c
@@ -13,20 +13,16 @@
u_register_t plat_get_stack_protector_canary(void)
{
- u_register_t c[TRNG_NBYTES / sizeof(u_register_t)];
- u_register_t ret = 0;
- size_t i;
+ uint64_t entropy;
- if (juno_getentropy(c, sizeof(c)) != 0) {
+ if (!juno_getentropy(&entropy)) {
ERROR("Not enough entropy to initialize canary value\n");
panic();
}
- /*
- * On Juno we get 128-bits of entropy in one round.
- * Fuse the values together to form the canary.
- */
- for (i = 0; i < ARRAY_SIZE(c); i++)
- ret ^= c[i];
- return ret;
+ if (sizeof(entropy) == sizeof(u_register_t)) {
+ return entropy;
+ }
+
+ return (entropy & 0xffffffffULL) ^ (entropy >> 32);
}
diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c
index 052ab9f8a..075f512c3 100644
--- a/plat/arm/board/juno/juno_topology.c
+++ b/plat/arm/board/juno/juno_topology.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,7 +20,7 @@ static scmi_channel_plat_info_t juno_scmi_plat_info = {
.ring_doorbell = &mhu_ring_doorbell,
};
-scmi_channel_plat_info_t *plat_css_get_scmi_info(void)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
{
return &juno_scmi_plat_info;
}
diff --git a/plat/arm/board/juno/juno_trng.c b/plat/arm/board/juno/juno_trng.c
index 7869d3e33..b38e49f45 100644
--- a/plat/arm/board/juno/juno_trng.c
+++ b/plat/arm/board/juno/juno_trng.c
@@ -5,6 +5,8 @@
*/
#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
#include <lib/mmio.h>
@@ -16,7 +18,10 @@
#define NSAMPLE_CLOCKS 1 /* min 1 cycle, max 231 cycles */
#define NRETRIES 5
-static inline int output_valid(void)
+/* initialised to false */
+static bool juno_trng_initialized;
+
+static bool output_valid(void)
{
int i;
@@ -25,59 +30,58 @@ static inline int output_valid(void)
val = mmio_read_32(TRNG_BASE + TRNG_STATUS);
if (val & 1U)
- break;
+ return true;
}
- if (i >= NRETRIES)
- return 0; /* No output data available. */
- return 1;
+ return false; /* No output data available. */
}
/*
- * This function fills `buf` with `len` bytes of entropy.
+ * This function fills `buf` with 8 bytes of entropy.
* It uses the Trusted Entropy Source peripheral on Juno.
- * Returns 0 when the buffer has been filled with entropy
- * successfully and -1 otherwise.
+ * Returns 'true' when the buffer has been filled with entropy
+ * successfully, or 'false' otherwise.
*/
-int juno_getentropy(void *buf, size_t len)
+bool juno_getentropy(uint64_t *buf)
{
- uint8_t *bp = buf;
+ uint64_t ret;
assert(buf);
- assert(len);
- assert(!check_uptr_overflow((uintptr_t)bp, len));
-
- /* Disable interrupt mode. */
- mmio_write_32(TRNG_BASE + TRNG_INTMASK, 0);
- /* Program TRNG to sample for `NSAMPLE_CLOCKS`. */
- mmio_write_32(TRNG_BASE + TRNG_CONFIG, NSAMPLE_CLOCKS);
+ assert(!check_uptr_overflow((uintptr_t)buf, sizeof(*buf)));
+
+ if (!juno_trng_initialized) {
+ /* Disable interrupt mode. */
+ mmio_write_32(TRNG_BASE + TRNG_INTMASK, 0);
+ /* Program TRNG to sample for `NSAMPLE_CLOCKS`. */
+ mmio_write_32(TRNG_BASE + TRNG_CONFIG, NSAMPLE_CLOCKS);
+ /* Abort any potentially pending sampling. */
+ mmio_write_32(TRNG_BASE + TRNG_CONTROL, 2);
+ /* Reset TRNG outputs. */
+ mmio_write_32(TRNG_BASE + TRNG_STATUS, 1);
- while (len > 0) {
- int i;
+ juno_trng_initialized = true;
+ }
+ if (!output_valid()) {
/* Start TRNG. */
mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1);
- /* Check if output is valid. */
if (!output_valid())
- return -1;
-
- /* Fill entropy buffer. */
- for (i = 0; i < TRNG_NOUTPUTS; i++) {
- size_t n;
- uint32_t val;
-
- val = mmio_read_32(TRNG_BASE + i * sizeof(uint32_t));
- n = MIN(len, sizeof(uint32_t));
- memcpy(bp, &val, n);
- bp += n;
- len -= n;
- if (len == 0)
- break;
- }
-
- /* Reset TRNG outputs. */
- mmio_write_32(TRNG_BASE + TRNG_STATUS, 1);
+ return false;
}
- return 0;
+ /* XOR each two 32-bit registers together, combine the pairs */
+ ret = mmio_read_32(TRNG_BASE + 0);
+ ret ^= mmio_read_32(TRNG_BASE + 4);
+ ret <<= 32;
+
+ ret |= mmio_read_32(TRNG_BASE + 8);
+ ret ^= mmio_read_32(TRNG_BASE + 12);
+ *buf = ret;
+
+ /* Acknowledge current cycle, clear output registers. */
+ mmio_write_32(TRNG_BASE + TRNG_STATUS, 1);
+ /* Trigger next TRNG cycle. */
+ mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1);
+
+ return true;
}
diff --git a/plat/arm/board/juno/juno_trusted_boot.c b/plat/arm/board/juno/juno_trusted_boot.c
new file mode 100644
index 000000000..25a74705d
--- /dev/null
+++ b/plat/arm/board/juno/juno_trusted_boot.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <drivers/arm/cryptocell/cc_rotpk.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/common_def.h>
+#include <plat/common/platform.h>
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+
+static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
+
+extern unsigned char arm_rotpk_header[];
+
+/*
+ * Return the ROTPK hash stored in the registers of Juno board.
+ */
+static int juno_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ uint8_t *dst;
+ uint32_t *src, tmp;
+ unsigned int words, i;
+
+ assert(key_ptr != NULL);
+ assert(key_len != NULL);
+ assert(flags != NULL);
+
+ /* Copy the DER header */
+ memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
+ dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+
+
+ /*
+ * Append the hash from Trusted Root-Key Storage registers. The hash has
+ * not been written linearly into the registers, so we have to do a bit
+ * of byte swapping:
+ *
+ * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C
+ * +---------------------------------------------------------------+
+ * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 |
+ * +---------------------------------------------------------------+
+ * | ... ... | | ... ... |
+ * | +--------------------+ | +-------+
+ * | | | |
+ * +----------------------------+ +----------------------------+
+ * | | | |
+ * +-------+ | +--------------------+ |
+ * | | | |
+ * v v v v
+ * +---------------------------------------------------------------+
+ * | | |
+ * +---------------------------------------------------------------+
+ * 0 15 16 31
+ *
+ * Additionally, we have to access the registers in 32-bit words
+ */
+ words = ARM_ROTPK_HASH_LEN >> 3;
+
+ /* Swap bytes 0-15 (first four registers) */
+ src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
+ for (i = 0 ; i < words ; i++) {
+ tmp = src[words - 1 - i];
+ /* Words are read in little endian */
+ *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
+ *dst++ = (uint8_t)(tmp & 0xFF);
+ }
+
+ /* Swap bytes 16-31 (last four registers) */
+ src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + ARM_ROTPK_HASH_LEN / 2);
+ for (i = 0 ; i < words ; i++) {
+ tmp = src[words - 1 - i];
+ *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
+ *dst++ = (uint8_t)(tmp & 0xFF);
+ }
+
+ *key_ptr = (void *)rotpk_hash_der;
+ *key_len = (unsigned int)sizeof(rotpk_hash_der);
+ *flags = ROTPK_IS_HASH;
+ return 0;
+}
+
+#endif
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+#if ARM_CRYPTOCELL_INTEG
+ return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
+#else
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
+ (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+ return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
+#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+ return juno_get_rotpk_info_regs(key_ptr, key_len, flags);
+#else
+ return 1;
+#endif
+
+#endif /* ARM_CRYPTOCELL_INTEG */
+}
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index bd6bae536..61cfb610c 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -1,12 +1,13 @@
#
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
-JUNO_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
+# Include GICv2 driver files
+include drivers/arm/gic/v2/gicv2.mk
+
+JUNO_GIC_SOURCES := ${GICV2_SOURCES} \
plat/common/plat_gicv2.c \
plat/arm/common/arm_gicv2.c
@@ -91,6 +92,11 @@ ifeq (${CSS_USE_SCMI_SDS_DRIVER},1)
BL1_SOURCES += drivers/arm/css/sds/sds.c
endif
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += plat/arm/board/juno/juno_trusted_boot.c
+BL2_SOURCES += plat/arm/board/juno/juno_trusted_boot.c
+endif
+
endif
ifneq (${RESET_TO_BL31},0)
@@ -102,7 +108,7 @@ ifeq ($(USE_ROMLIB),1)
all : bl1_romlib.bin
endif
-bl1_romlib.bin : $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/romlib/romlib.bin
+bl1_romlib.bin : $(BUILD_PLAT)/bl1.bin romlib.bin
@echo "Building combined BL1 and ROMLIB binary for Juno $@"
./lib/romlib/gen_combined_bl1_romlib.sh -o bl1_romlib.bin $(BUILD_PLAT)
@@ -142,20 +148,33 @@ ENABLE_SVE_FOR_NS := 0
# Enable the dynamic translation tables library.
ifeq (${ARCH},aarch32)
ifeq (${RESET_TO_SP_MIN},1)
- BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+ BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
endif
else
ifeq (${RESET_TO_BL31},1)
- BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+ BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
+ endif
+endif
+
+ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
+ ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1)
+ BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES
+ else
+ BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES
endif
endif
# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts
+FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts \
+ plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts
+
+FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
include plat/arm/board/common/board_common.mk
include plat/arm/common/arm_common.mk
diff --git a/plat/arm/board/morello/aarch64/morello_helper.S b/plat/arm/board/morello/aarch64/morello_helper.S
new file mode 100644
index 000000000..60470a843
--- /dev/null
+++ b/plat/arm/board/morello/aarch64/morello_helper.S
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+#include <rainier.h>
+
+#include <platform_def.h>
+
+ .globl plat_arm_calc_core_pos
+ .globl plat_reset_handler
+
+ /* -----------------------------------------------------
+ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+ *
+ * Helper function to calculate the core position.
+ * ((ChipId * MORELLO_MAX_CLUSTERS_PER_CHIP + ClusterId) *
+ * MORELLO_MAX_CPUS_PER_CLUSTER * MORELLO_MAX_PE_PER_CPU) +
+ * (CPUId * MORELLO_MAX_PE_PER_CPU) + ThreadId
+ *
+ * which can be simplified as:
+ *
+ * (((ChipId * MORELLO_MAX_CLUSTERS_PER_CHIP + ClusterId) *
+ * MORELLO_MAX_CPUS_PER_CLUSTER + CPUId) * MORELLO_MAX_PE_PER_CPU) +
+ * ThreadId
+ * ------------------------------------------------------
+ */
+
+func plat_arm_calc_core_pos
+ mov x4, x0
+
+ /*
+ * The MT bit in MPIDR is always set for morello and the
+ * affinity level 0 corresponds to thread affinity level.
+ */
+
+ /* Extract individual affinity fields from MPIDR */
+ ubfx x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS
+
+ /* Compute linear position */
+ mov x4, #MORELLO_MAX_CLUSTERS_PER_CHIP
+ madd x2, x3, x4, x2
+ mov x4, #MORELLO_MAX_CPUS_PER_CLUSTER
+ madd x1, x2, x4, x1
+ mov x4, #MORELLO_MAX_PE_PER_CPU
+ madd x0, x1, x4, x0
+ ret
+endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/board/morello/include/plat_macros.S b/plat/arm/board/morello/include/plat_macros.S
new file mode 100644
index 000000000..195be8435
--- /dev/null
+++ b/plat/arm/board/morello/include/plat_macros.S
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <css_macros.S>
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ *
+ * There are currently no platform specific regs
+ * to print.
+ * ---------------------------------------------
+ */
+ .macro plat_crash_print_regs
+ .endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/arm/board/morello/include/platform_def.h b/plat/arm/board/morello/include/platform_def.h
new file mode 100644
index 000000000..9ca75ffe7
--- /dev/null
+++ b/plat/arm/board/morello/include/platform_def.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/css/common/css_def.h>
+
+/* UART related constants */
+#define PLAT_ARM_BOOT_UART_BASE ULL(0x2A400000)
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ U(50000000)
+
+#define PLAT_ARM_RUN_UART_BASE ULL(0x2A410000)
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ U(50000000)
+
+#define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ
+
+#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0xF80000000)
+
+/*
+ * To access the complete DDR memory along with remote chip's DDR memory,
+ * which is at 4 TB offset, physical and virtual address space limits are
+ * extended to 43-bits.
+ */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43)
+
+#if CSS_USE_SCMI_SDS_DRIVER
+#define MORELLO_SCMI_PAYLOAD_BASE ULL(0x45400000)
+#else
+#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE ULL(0x45400000)
+#endif
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE UL(0x00080000)
+#define PLAT_ARM_MAX_BL31_SIZE UL(0x20000)
+
+/*******************************************************************************
+ * MORELLO topology related constants
+ ******************************************************************************/
+#define MORELLO_MAX_CPUS_PER_CLUSTER U(2)
+#define PLAT_ARM_CLUSTER_COUNT U(2)
+#define PLAT_MORELLO_CHIP_COUNT U(1)
+#define MORELLO_MAX_CLUSTERS_PER_CHIP U(2)
+#define MORELLO_MAX_PE_PER_CPU U(1)
+
+#define PLATFORM_CORE_COUNT (PLAT_MORELLO_CHIP_COUNT * \
+ PLAT_ARM_CLUSTER_COUNT * \
+ MORELLO_MAX_CPUS_PER_CLUSTER * \
+ MORELLO_MAX_PE_PER_CPU)
+
+/* System power domain level */
+#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL3
+
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage.
+ */
+#define PLAT_ARM_MMAP_ENTRIES U(9)
+#define MAX_XLAT_TABLES U(10)
+
+#define PLATFORM_STACK_SIZE U(0x400)
+
+#define PLAT_ARM_NSTIMER_FRAME_ID U(0)
+#define PLAT_CSS_MHU_BASE UL(0x45000000)
+#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
+#define PLAT_MAX_PWR_LVL U(2)
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
+
+#define MORELLO_DEVICE_BASE ULL(0x08000000)
+#define MORELLO_DEVICE_SIZE ULL(0x48000000)
+
+#define MORELLO_MAP_DEVICE MAP_REGION_FLAT( \
+ MORELLO_DEVICE_BASE, \
+ MORELLO_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define ARM_MAP_DRAM1 MAP_REGION_FLAT( \
+ ARM_DRAM1_BASE, \
+ ARM_DRAM1_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x300C0000)
+
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c
new file mode 100644
index 000000000..59dd37b17
--- /dev/null
+++ b/plat/arm/board/morello/morello_bl31_setup.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <drivers/arm/css/sds.h>
+#include <lib/cassert.h>
+#include <plat/arm/common/plat_arm.h>
+
+#include "morello_def.h"
+#include <platform_def.h>
+
+/*
+ * Platform information structure stored in SDS.
+ * This structure holds information about platform's DDR
+ * size which is an information about multichip setup
+ * - Local DDR size in bytes, DDR memory in master board
+ * - Remote DDR size in bytes, DDR memory in slave board
+ * - slave_count
+ * - multichip mode
+ */
+struct morello_plat_info {
+ uint64_t local_ddr_size;
+ uint64_t remote_ddr_size;
+ uint8_t slave_count;
+ bool multichip_mode;
+} __packed;
+
+/* Compile time assertion to ensure the size of structure is 18 bytes */
+CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
+ assert_invalid_plat_info_size);
+/*
+ * BL33 image information structure stored in SDS.
+ * This structure holds the source & destination addresses and
+ * the size of the BL33 image which will be loaded by BL31.
+ */
+struct morello_bl33_info {
+ uint32_t bl33_src_addr;
+ uint32_t bl33_dst_addr;
+ uint32_t bl33_size;
+};
+
+static scmi_channel_plat_info_t morello_scmi_plat_info = {
+ .scmi_mbx_mem = MORELLO_SCMI_PAYLOAD_BASE,
+ .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhu_ring_doorbell
+};
+
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
+{
+ return &morello_scmi_plat_info;
+}
+
+const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
+{
+ return css_scmi_override_pm_ops(ops);
+}
+
+static void copy_bl33(uint32_t src, uint32_t dst, uint32_t size)
+{
+ unsigned int i;
+
+ INFO("Copying BL33 to DDR memory...\n");
+ for (i = 0U; i < size; (i = i + 8U))
+ mmio_write_64((dst + i), mmio_read_64(src + i));
+
+ for (i = 0U; i < size; (i = i + 8U)) {
+ if (mmio_read_64(src + i) != mmio_read_64(dst + i)) {
+ ERROR("Copy failed!\n");
+ panic();
+ }
+ }
+ INFO("done\n");
+}
+
+void bl31_platform_setup(void)
+{
+ int ret;
+ struct morello_plat_info plat_info;
+ struct morello_bl33_info bl33_info;
+ struct morello_plat_info *copy_dest;
+
+ ret = sds_init();
+ if (ret != SDS_OK) {
+ ERROR("SDS initialization failed. ret:%d\n", ret);
+ panic();
+ }
+
+ ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
+ MORELLO_SDS_PLATFORM_INFO_OFFSET,
+ &plat_info,
+ MORELLO_SDS_PLATFORM_INFO_SIZE,
+ SDS_ACCESS_MODE_NON_CACHED);
+ if (ret != SDS_OK) {
+ ERROR("Error getting platform info from SDS. ret:%d\n", ret);
+ panic();
+ }
+
+ /* Validate plat_info SDS */
+ if ((plat_info.local_ddr_size == 0U)
+ || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
+ || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
+ || (plat_info.slave_count > MORELLO_MAX_SLAVE_COUNT)) {
+ ERROR("platform info SDS is corrupted\n");
+ panic();
+ }
+
+ arm_bl31_platform_setup();
+
+ ret = sds_struct_read(MORELLO_SDS_BL33_INFO_STRUCT_ID,
+ MORELLO_SDS_BL33_INFO_OFFSET,
+ &bl33_info,
+ MORELLO_SDS_BL33_INFO_SIZE,
+ SDS_ACCESS_MODE_NON_CACHED);
+ if (ret != SDS_OK) {
+ ERROR("Error getting BL33 info from SDS. ret:%d\n", ret);
+ panic();
+ }
+ copy_bl33(bl33_info.bl33_src_addr,
+ bl33_info.bl33_dst_addr,
+ bl33_info.bl33_size);
+ /*
+ * Pass platform information to BL33. This method is followed as
+ * currently there is no BL1/BL2 involved in boot flow of MORELLO.
+ * When TBBR is implemented for MORELLO, this method should be removed
+ * and platform information should be passed to BL33 using NT_FW_CONFIG
+ * passing mechanism.
+ */
+ copy_dest = (struct morello_plat_info *)MORELLO_PLATFORM_INFO_BASE;
+ *copy_dest = plat_info;
+}
diff --git a/plat/arm/board/morello/morello_def.h b/plat/arm/board/morello/morello_def.h
new file mode 100644
index 000000000..793729b99
--- /dev/null
+++ b/plat/arm/board/morello/morello_def.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MORELLO_DEF_H
+#define MORELLO_DEF_H
+
+/* Non-secure SRAM MMU mapping */
+#define MORELLO_NS_SRAM_BASE UL(0x06000000)
+#define MORELLO_NS_SRAM_SIZE UL(0x00010000)
+#define MORELLO_MAP_NS_SRAM MAP_REGION_FLAT( \
+ MORELLO_NS_SRAM_BASE, \
+ MORELLO_NS_SRAM_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+/* SDS Platform information defines */
+#define MORELLO_SDS_PLATFORM_INFO_STRUCT_ID U(8)
+#define MORELLO_SDS_PLATFORM_INFO_OFFSET U(0)
+#define MORELLO_SDS_PLATFORM_INFO_SIZE U(18)
+#define MORELLO_MAX_DDR_CAPACITY U(0x1000000000)
+#define MORELLO_MAX_SLAVE_COUNT U(16)
+
+/* SDS BL33 image information defines */
+#define MORELLO_SDS_BL33_INFO_STRUCT_ID U(9)
+#define MORELLO_SDS_BL33_INFO_OFFSET U(0)
+#define MORELLO_SDS_BL33_INFO_SIZE U(12)
+
+/* Base address of non-secure SRAM where Platform information will be filled */
+#define MORELLO_PLATFORM_INFO_BASE UL(0x06000000)
+
+#endif /* MORELLO_DEF_H */
diff --git a/plat/arm/board/morello/morello_interconnect.c b/plat/arm/board/morello/morello_interconnect.c
new file mode 100644
index 000000000..d941bfe0f
--- /dev/null
+++ b/plat/arm/board/morello/morello_interconnect.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/*
+ * For MORELLO which supports FCM (with automatic interconnect enter/exit),
+ * we should not do anything in these interface functions.
+ * They are used to override the weak functions in cci drivers.
+ */
+
+/******************************************************************************
+ * Helper function to initialize ARM interconnect driver.
+ *****************************************************************************/
+void plat_arm_interconnect_init(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to place current master into coherency
+ *****************************************************************************/
+void plat_arm_interconnect_enter_coherency(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to remove current master from coherency
+ *****************************************************************************/
+void plat_arm_interconnect_exit_coherency(void)
+{
+}
diff --git a/plat/arm/board/morello/morello_plat.c b/plat/arm/board/morello/morello_plat.c
new file mode 100644
index 000000000..3830687a3
--- /dev/null
+++ b/plat/arm/board/morello/morello_plat.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+#include "morello_def.h"
+
+/*
+ * Table of regions to map using the MMU.
+ * Replace or extend the below regions as required
+ */
+
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ MORELLO_MAP_DEVICE,
+ MORELLO_MAP_NS_SRAM,
+ ARM_MAP_DRAM1,
+ {0}
+};
diff --git a/plat/arm/board/morello/morello_security.c b/plat/arm/board/morello/morello_security.c
new file mode 100644
index 000000000..a388a8099
--- /dev/null
+++ b/plat/arm/board/morello/morello_security.c
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * TZC programming is currently not done.
+ */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/morello/morello_topology.c b/plat/arm/board/morello/morello_topology.c
new file mode 100644
index 000000000..ef2f7534f
--- /dev/null
+++ b/plat/arm/board/morello/morello_topology.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/cassert.h>
+#include <plat/arm/common/plat_arm.h>
+
+/* Compile time assertion to ensure the core count is 4 */
+CASSERT(PLATFORM_CORE_COUNT == 4U, assert_invalid_platform_core_count);
+
+/* Topology */
+typedef struct morello_topology {
+ const unsigned char *power_tree;
+ unsigned int plat_cluster_core_count;
+} morello_topology_t;
+
+/*
+ * The power domain tree descriptor. The cluster power domains are
+ * arranged so that when the PSCI generic code creates the power domain tree,
+ * the indices of the CPU power domain nodes it allocates match the linear
+ * indices returned by plat_core_pos_by_mpidr().
+ */
+const unsigned char morello_pd_tree_desc[] = {
+ PLAT_MORELLO_CHIP_COUNT,
+ PLAT_ARM_CLUSTER_COUNT,
+ MORELLO_MAX_CPUS_PER_CLUSTER,
+ MORELLO_MAX_CPUS_PER_CLUSTER,
+};
+
+/* Topology configuration for morello */
+const morello_topology_t morello_topology = {
+ .power_tree = morello_pd_tree_desc,
+ .plat_cluster_core_count = MORELLO_MAX_CPUS_PER_CLUSTER
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return morello_topology.power_tree;
+}
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+ return morello_topology.plat_cluster_core_count;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = {
+ 0, 1, 2, 3};
diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk
new file mode 100644
index 000000000..fc7d4d363
--- /dev/null
+++ b/plat/arm/board/morello/platform.mk
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+MORELLO_BASE := plat/arm/board/morello
+
+INTERCONNECT_SOURCES := ${MORELLO_BASE}/morello_interconnect.c
+
+PLAT_INCLUDES := -I${MORELLO_BASE}/include
+
+MORELLO_CPU_SOURCES := lib/cpus/aarch64/rainier.S
+
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600 := 1
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+MORELLO_GIC_SOURCES := ${GICV3_SOURCES} \
+ plat/common/plat_gicv3.c \
+ plat/arm/common/arm_gicv3.c \
+
+PLAT_BL_COMMON_SOURCES := ${MORELLO_BASE}/morello_plat.c \
+ ${MORELLO_BASE}/aarch64/morello_helper.S
+
+BL31_SOURCES := ${MORELLO_CPU_SOURCES} \
+ ${INTERCONNECT_SOURCES} \
+ ${MORELLO_GIC_SOURCES} \
+ ${MORELLO_BASE}/morello_bl31_setup.c \
+ ${MORELLO_BASE}/morello_topology.c \
+ ${MORELLO_BASE}/morello_security.c \
+ drivers/arm/css/sds/sds.c
+
+FDT_SOURCES += fdts/morello-fvp.dts
+
+# TF-A not required to load the SCP Images
+override CSS_LOAD_SCP_IMAGES := 0
+
+# BL1/BL2 Image not a part of the capsule Image for morello
+override NEED_BL1 := no
+override NEED_BL2 := no
+override NEED_BL2U := no
+
+#TF-A for morello starts from BL31
+override RESET_TO_BL31 := 1
+
+# 32 bit mode not supported
+override CTX_INCLUDE_AARCH32_REGS := 0
+
+override ARM_PLAT_MT := 1
+
+# Select SCMI/SDS drivers instead of SCPI/BOM driver for communicating with the
+# SCP during power management operations and for SCP RAM Firmware transfer.
+CSS_USE_SCMI_SDS_DRIVER := 1
+
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY := 1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM := 0
+
+include plat/arm/common/arm_common.mk
+include plat/arm/css/common/css_common.mk
+include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index 6a309e8e1..cc07852c2 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -90,7 +90,6 @@
#define PLAT_ARM_NSTIMER_FRAME_ID 0
#define PLAT_CSS_MHU_BASE 0x45000000
-#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
#define PLAT_MAX_PWR_LVL 2
#define PLAT_ARM_G1S_IRQS ARM_G1S_IRQS, \
@@ -144,4 +143,7 @@
#define SBSA_SECURE_WDOG_BASE UL(0x2A480000)
#define SBSA_SECURE_WDOG_TIMEOUT UL(100)
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index b150b8959..d7003e951 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -63,8 +63,8 @@ static struct gic600_multichip_data n1sdp_multichip_data __init = {
PLAT_ARM_GICD_BASE >> 16
},
.spi_ids = {
- {32, 255},
- {0, 0}
+ {32, 479},
+ {512, 959}
}
};
@@ -74,7 +74,7 @@ static uintptr_t n1sdp_multichip_gicr_frames[3] = {
0
};
-scmi_channel_plat_info_t *plat_css_get_scmi_info()
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
{
return &n1sdp_scmi_plat_info;
}
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index 8816670dc..f20397acd 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -14,14 +14,16 @@ PLAT_INCLUDES := -I${N1SDP_BASE}/include
N1SDP_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600 := 1
+GICV3_IMPL_GIC600_MULTICHIP := 1
-N1SDP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/v3/gicv3_helpers.c \
- drivers/arm/gic/v3/gic600_multichip.c \
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+N1SDP_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
plat/arm/common/arm_gicv3.c \
- drivers/arm/gic/v3/gic600.c
PLAT_BL_COMMON_SOURCES := ${N1SDP_BASE}/n1sdp_plat.c \
${N1SDP_BASE}/aarch64/n1sdp_helper.S
@@ -36,6 +38,8 @@ BL31_SOURCES := ${N1SDP_CPU_SOURCES} \
${N1SDP_BASE}/n1sdp_security.c \
drivers/arm/css/sds/sds.c
+FDT_SOURCES += fdts/${PLAT}-single-chip.dts \
+ fdts/${PLAT}-multi-chip.dts
# TF-A not required to load the SCP Images
override CSS_LOAD_SCP_IMAGES := 0
@@ -63,6 +67,9 @@ HW_ASSISTED_COHERENCY := 1
# When building for systems with hardware-assisted coherency, there's no need to
# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
USE_COHERENT_MEM := 0
+
+# Enable the flag since N1SDP has a system level cache
+NEOVERSE_Nx_EXTERNAL_LLC := 1
include plat/arm/common/arm_common.mk
include plat/arm/css/common/css_common.mk
include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts
new file mode 100644
index 000000000..69fb0d498
--- /dev/null
+++ b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0xFEF00000>;
+ max-size = <0x0100000>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
index 41769217a..0af821e15 100644
--- a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
+++ b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,6 +17,7 @@
system-id {
platform-id = <0x0>;
config-id = <0x0>;
+ multi-chip-mode = <0x0>;
};
};
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts
index 766dc00f5..dba91e535 100644
--- a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts
+++ b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,19 +7,22 @@
/dts-v1/;
/ {
- /* Platform Config */
- compatible = "arm,tb_fw";
- nt_fw_config_addr = <0x0 0xFEF00000>;
- nt_fw_config_max_size = <0x0100000>;
- /*
- * The following two entries are placeholders for Mbed TLS
- * heap information. The default values don't matter since
- * they will be overwritten by BL1.
- * In case of having shared Mbed TLS heap between BL1 and BL2,
- * BL1 will populate these two properties with the respective
- * info about the shared heap. This info will be available for
- * BL2 in order to locate and re-use the heap.
- */
- mbedtls_heap_addr = <0x0 0x0>;
- mbedtls_heap_size = <0x0>;
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
};
diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h
index 2be3f8852..c39fe2b69 100644
--- a/plat/arm/board/rde1edge/include/platform_def.h
+++ b/plat/arm/board/rde1edge/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,14 +9,13 @@
#include <lib/utils_def.h>
-#include <sgi_base_platform_def.h>
+#include <sgi_soc_platform_def.h>
#define PLAT_ARM_CLUSTER_COUNT U(2)
#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(8)
#define CSS_SGI_MAX_PE_PER_CPU U(2)
#define PLAT_CSS_MHU_BASE UL(0x45400000)
-#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
/* Base address of DMC-620 instances */
#define RDE1EDGE_DMC620_BASE0 UL(0x4e000000)
@@ -37,4 +36,9 @@
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#endif
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x300C0000)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk
index 43c37ffc1..53074f495 100644
--- a/plat/arm/board/rde1edge/platform.mk
+++ b/plat/arm/board/rde1edge/platform.mk
@@ -12,6 +12,8 @@ PLAT_INCLUDES += -I${RDE1EDGE_BASE}/include/
SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_e1.S
+PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c
+
BL1_SOURCES += ${SGI_CPU_SOURCES} \
${RDE1EDGE_BASE}/rde1edge_err.c
@@ -29,17 +31,31 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \
lib/utils/mem_region.c \
plat/arm/common/arm_nor_psci_mem_protect.c
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c
+BL2_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c
+endif
+
# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
+FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_fw_config.dts \
+ ${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
+FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_nt_fw_config.dts
NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
# Add the NT_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
+
+ifneq ($(CSS_SGI_CHIP_COUNT),1)
+ $(error "Chip count for RDE1Edge should be 1, currently set to \
+ ${CSS_SGI_CHIP_COUNT}.")
+endif
override CTX_INCLUDE_AARCH32_REGS := 0
diff --git a/plat/arm/board/rde1edge/rde1edge_err.c b/plat/arm/board/rde1edge/rde1edge_err.c
index e344d8268..c72c18ced 100644
--- a/plat/arm/board/rde1edge/rde1edge_err.c
+++ b/plat/arm/board/rde1edge/rde1edge_err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,7 @@
*/
void __dead2 plat_arm_error_handler(int err)
{
- while (1) {
+ while (true) {
wfi();
}
}
diff --git a/plat/arm/board/rde1edge/rde1edge_plat.c b/plat/arm/board/rde1edge/rde1edge_plat.c
index a1b8d621d..44d818aec 100644
--- a/plat/arm/board/rde1edge/rde1edge_plat.c
+++ b/plat/arm/board/rde1edge/rde1edge_plat.c
@@ -1,10 +1,11 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <plat/common/platform.h>
+#include <sgi_plat.h>
unsigned int plat_arm_sgi_get_platform_id(void)
{
@@ -16,3 +17,13 @@ unsigned int plat_arm_sgi_get_config_id(void)
{
return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
}
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+ return 0;
+}
+
+void bl31_platform_setup(void)
+{
+ sgi_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/rde1edge/rde1edge_topology.c b/plat/arm/board/rde1edge/rde1edge_topology.c
index 0b56f208a..a16283e45 100644
--- a/plat/arm/board/rde1edge/rde1edge_topology.c
+++ b/plat/arm/board/rde1edge/rde1edge_topology.c
@@ -7,12 +7,15 @@
#include <plat/arm/common/plat_arm.h>
/******************************************************************************
- * The power domain tree descriptor.
+ * The power domain tree descriptor. RD-E1-Edge platform consists of two
+ * clusters with eight CPUs in each cluster. The CPUs are multi-threaded with
+ * two threads per CPU.
******************************************************************************/
static const unsigned char rde1edge_pd_tree_desc[] = {
+ CSS_SGI_CHIP_COUNT,
PLAT_ARM_CLUSTER_COUNT,
- CSS_SGI_MAX_CPUS_PER_CLUSTER,
- CSS_SGI_MAX_CPUS_PER_CLUSTER
+ CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU
};
/******************************************************************************
diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
new file mode 100644
index 000000000..4592b8fba
--- /dev/null
+++ b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
new file mode 100644
index 000000000..d3b7fba49
--- /dev/null
+++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0xFEF00000>;
+ max-size = <0x0100000>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+};
+
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
index fff587476..68366c5ca 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
+++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,5 +17,6 @@
system-id {
platform-id = <0x0>;
config-id = <0x0>;
+ multi-chip-mode = <0x0>;
};
};
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
index b14d7adca..257ef4a3f 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
+++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
@@ -1,25 +1,27 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/dts-v1/;
-
/ {
- /* Platform Config */
- compatible = "arm,tb_fw";
- nt_fw_config_addr = <0x0 0xFEF00000>;
- nt_fw_config_max_size = <0x0100000>;
- /*
- * The following two entries are placeholders for Mbed TLS
- * heap information. The default values don't matter since
- * they will be overwritten by BL1.
- * In case of having shared Mbed TLS heap between BL1 and BL2,
- * BL1 will populate these two properties with the respective
- * info about the shared heap. This info will be available for
- * BL2 in order to locate and re-use the heap.
- */
- mbedtls_heap_addr = <0x0 0x0>;
- mbedtls_heap_size = <0x0>;
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
};
diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h
index c635faa44..b167c46e0 100644
--- a/plat/arm/board/rdn1edge/include/platform_def.h
+++ b/plat/arm/board/rdn1edge/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,14 +9,13 @@
#include <lib/utils_def.h>
-#include <sgi_base_platform_def.h>
+#include <sgi_soc_platform_def.h>
#define PLAT_ARM_CLUSTER_COUNT U(2)
#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(4)
#define CSS_SGI_MAX_PE_PER_CPU U(1)
#define PLAT_CSS_MHU_BASE UL(0x45400000)
-#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
/* Base address of DMC-620 instances */
#define RDN1EDGE_DMC620_BASE0 UL(0x4e000000)
@@ -27,15 +26,23 @@
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+/* Virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
+
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43)
#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#endif
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x300C0000)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk
index ca1e95eaf..d65854f8d 100644
--- a/plat/arm/board/rdn1edge/platform.mk
+++ b/plat/arm/board/rdn1edge/platform.mk
@@ -4,6 +4,9 @@
# SPDX-License-Identifier: BSD-3-Clause
#
+# GIC-600 configuration
+GICV3_IMPL_GIC600_MULTICHIP := 1
+
include plat/arm/css/sgi/sgi-common.mk
RDN1EDGE_BASE = plat/arm/board/rdn1edge
@@ -12,6 +15,8 @@ PLAT_INCLUDES += -I${RDN1EDGE_BASE}/include/
SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S
+PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c
+
BL1_SOURCES += ${SGI_CPU_SOURCES} \
${RDN1EDGE_BASE}/rdn1edge_err.c
@@ -29,17 +34,35 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \
lib/utils/mem_region.c \
plat/arm/common/arm_nor_psci_mem_protect.c
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c
+BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c
+endif
+
+# Enable dynamic addition of MMAP regions in BL31
+BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
+
# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
+FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_fw_config.dts \
+ ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
+FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_nt_fw_config.dts
NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
# Add the NT_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
+
+$(eval $(call CREATE_SEQ,SEQ,2))
+ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ)))
+ $(error "Chip count for RDN1Edge platform should be one of $(SEQ), currently \
+ set to ${CSS_SGI_CHIP_COUNT}.")
+endif
override CTX_INCLUDE_AARCH32_REGS := 0
diff --git a/plat/arm/board/rdn1edge/rdn1edge_err.c b/plat/arm/board/rdn1edge/rdn1edge_err.c
index cdcbf256a..46d318c7b 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_err.c
+++ b/plat/arm/board/rdn1edge/rdn1edge_err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,7 @@
*/
void __dead2 plat_arm_error_handler(int err)
{
- while (1) {
+ while (true) {
wfi();
}
}
diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c
index 3b7e5ee4e..1dbbf26da 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_plat.c
+++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c
@@ -1,10 +1,44 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
+#include <sgi_soc_platform_def.h>
+#include <sgi_plat.h>
+
+#if defined(IMAGE_BL31)
+static const mmap_region_t rdn1edge_dynamic_mmap[] = {
+ ARM_MAP_SHARED_RAM_REMOTE_CHIP(1),
+ CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
+ SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1)
+};
+
+static struct gic600_multichip_data rdn1e1_multichip_data __init = {
+ .rt_owner_base = PLAT_ARM_GICD_BASE,
+ .rt_owner = 0,
+ .chip_count = CSS_SGI_CHIP_COUNT,
+ .chip_addrs = {
+ PLAT_ARM_GICD_BASE >> 16,
+ (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16
+ },
+ .spi_ids = {
+ {32, 255},
+ {0, 0}
+ }
+};
+
+static uintptr_t rdn1e1_multichip_gicr_frames[] = {
+ PLAT_ARM_GICR_BASE, /* Chip 0's GICR Base */
+ PLAT_ARM_GICR_BASE +
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), /* Chip 1's GICR BASE */
+ UL(0) /* Zero Termination */
+};
+#endif /* IMAGE_BL31 */
unsigned int plat_arm_sgi_get_platform_id(void)
{
@@ -16,3 +50,48 @@ unsigned int plat_arm_sgi_get_config_id(void)
{
return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
}
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+ return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+ SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+/*
+ * IMAGE_BL31 macro is added to build bl31_platform_setup function only for BL31
+ * because PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not
+ * for other stages.
+ */
+#if defined(IMAGE_BL31)
+void bl31_platform_setup(void)
+{
+ int i, ret;
+
+ if (plat_arm_sgi_get_multi_chip_mode() == 0 && CSS_SGI_CHIP_COUNT > 1) {
+ ERROR("Chip Count is set to %d but multi-chip mode not enabled\n",
+ CSS_SGI_CHIP_COUNT);
+ panic();
+ } else if (plat_arm_sgi_get_multi_chip_mode() == 1 &&
+ CSS_SGI_CHIP_COUNT > 1) {
+ INFO("Enabling support for multi-chip in RD-N1-Edge\n");
+
+ for (i = 0; i < ARRAY_SIZE(rdn1edge_dynamic_mmap); i++) {
+ ret = mmap_add_dynamic_region(
+ rdn1edge_dynamic_mmap[i].base_pa,
+ rdn1edge_dynamic_mmap[i].base_va,
+ rdn1edge_dynamic_mmap[i].size,
+ rdn1edge_dynamic_mmap[i].attr
+ );
+ if (ret != 0) {
+ ERROR("Failed to add dynamic mmap entry\n");
+ panic();
+ }
+ }
+
+ plat_arm_override_gicr_frames(rdn1e1_multichip_gicr_frames);
+ gic600_multichip_init(&rdn1e1_multichip_data);
+ }
+
+ sgi_bl31_common_platform_setup();
+}
+#endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdn1edge/rdn1edge_topology.c b/plat/arm/board/rdn1edge/rdn1edge_topology.c
index 687ae3595..5bbea6998 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_topology.c
+++ b/plat/arm/board/rdn1edge/rdn1edge_topology.c
@@ -5,14 +5,19 @@
*/
#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
/******************************************************************************
* The power domain tree descriptor.
******************************************************************************/
static const unsigned char rdn1edge_pd_tree_desc[] = {
- PLAT_ARM_CLUSTER_COUNT,
+ (PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT),
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+#if (CSS_SGI_CHIP_COUNT > 1)
CSS_SGI_MAX_CPUS_PER_CLUSTER,
CSS_SGI_MAX_CPUS_PER_CLUSTER
+#endif
};
/*******************************************************************************
@@ -28,5 +33,22 @@ const unsigned char *plat_get_power_domain_tree_desc(void)
* to the SCMI power domain ID implemented by SCP.
******************************************************************************/
const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
- 0, 1, 2, 3, 4, 5, 6, 7
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+#if (CSS_SGI_CHIP_COUNT > 1)
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x4)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x5)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x6)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x7)),
+#endif
};
diff --git a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c
new file mode 100644
index 000000000..4592b8fba
--- /dev/null
+++ b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts
new file mode 100644
index 000000000..9c9cefe87
--- /dev/null
+++ b/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0xFEF00000>;
+ max-size = <0x0100000>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts
new file mode 100644
index 000000000..bbc36fc14
--- /dev/null
+++ b/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+/ {
+ /* compatible string */
+ compatible = "arm,rd-n2";
+
+ /*
+ * Place holder for system-id node with default values. The
+ * value of platform-id and config-id will be set to the
+ * correct values during the BL2 stage of boot.
+ */
+ system-id {
+ platform-id = <0x0>;
+ config-id = <0x0>;
+ multi-chip-mode = <0x0>;
+ };
+};
diff --git a/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts
new file mode 100644
index 000000000..49eda2735
--- /dev/null
+++ b/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
+};
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
new file mode 100644
index 000000000..3f753f73f
--- /dev/null
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+
+#include <sgi_soc_platform_def_v2.h>
+
+#define PLAT_ARM_CLUSTER_COUNT U(16)
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1)
+#define CSS_SGI_MAX_PE_PER_CPU U(1)
+
+#define PLAT_CSS_MHU_BASE UL(0x2A920000)
+#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
+
+#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+
+/* TZC Related Constants */
+#define PLAT_ARM_TZC_BASE UL(0x10720000)
+#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0)
+
+#define TZC400_OFFSET UL(0x1000000)
+#define TZC400_COUNT U(8)
+
+#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \
+ (n * TZC400_OFFSET))
+
+#define TZC_NSAID_ALL_AP U(0)
+#define TZC_NSAID_PCI U(1)
+#define TZC_NSAID_HDLCD0 U(2)
+#define TZC_NSAID_CLCD U(7)
+#define TZC_NSAID_AP U(9)
+#define TZC_NSAID_VIRTIO U(15)
+
+#define PLAT_ARM_TZC_NS_DEV_ACCESS \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI)) | \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP)) | \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD)) | \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
+
+/*
+ * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
+ */
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#endif
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x301C0000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
new file mode 100644
index 000000000..03771dc3d
--- /dev/null
+++ b/plat/arm/board/rdn2/platform.mk
@@ -0,0 +1,60 @@
+# Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# RD-N2 platform uses GIC-Clayton which is based on GICv4.1
+GIC_ENABLE_V4_EXTN := 1
+
+include plat/arm/css/sgi/sgi-common.mk
+
+RDN2_BASE = plat/arm/board/rdn2
+
+PLAT_INCLUDES += -I${RDN2_BASE}/include/
+
+SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_n2.S
+
+PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat_v2.c
+
+BL1_SOURCES += ${SGI_CPU_SOURCES} \
+ ${RDN2_BASE}/rdn2_err.c
+
+BL2_SOURCES += ${RDN2_BASE}/rdn2_plat.c \
+ ${RDN2_BASE}/rdn2_security.c \
+ ${RDN2_BASE}/rdn2_err.c \
+ lib/utils/mem_region.c \
+ drivers/arm/tzc/tzc400.c \
+ plat/arm/common/arm_tzc400.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+BL31_SOURCES += ${SGI_CPU_SOURCES} \
+ ${RDN2_BASE}/rdn2_plat.c \
+ ${RDN2_BASE}/rdn2_topology.c \
+ drivers/cfi/v2m/v2m_flash.c \
+ lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += ${RDN2_BASE}/rdn2_trusted_boot.c
+BL2_SOURCES += ${RDN2_BASE}/rdn2_trusted_boot.c
+endif
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES += ${RDN2_BASE}/fdts/${PLAT}_fw_config.dts \
+ ${RDN2_BASE}/fdts/${PLAT}_tb_fw_config.dts
+FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+
+FDT_SOURCES += ${RDN2_BASE}/fdts/${PLAT}_nt_fw_config.dts
+NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
+
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+
+override CTX_INCLUDE_AARCH32_REGS := 0
+override ENABLE_AMU := 1
diff --git a/plat/arm/board/rdn2/rdn2_err.c b/plat/arm/board/rdn2/rdn2_err.c
new file mode 100644
index 000000000..802ac21f6
--- /dev/null
+++ b/plat/arm/board/rdn2/rdn2_err.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * rdn2 error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+ while (1) {
+ wfi();
+ }
+}
diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/rdn2/rdn2_plat.c
new file mode 100644
index 000000000..5bf14e3a1
--- /dev/null
+++ b/plat/arm/board/rdn2/rdn2_plat.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+#include <sgi_plat.h>
+
+unsigned int plat_arm_sgi_get_platform_id(void)
+{
+ return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
+ & SID_SYSTEM_ID_PART_NUM_MASK;
+}
+
+unsigned int plat_arm_sgi_get_config_id(void)
+{
+ return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
+}
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+ return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+ SID_MULTI_CHIP_MODE_MASK) >>
+ SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+void bl31_platform_setup(void)
+{
+ sgi_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/rdn2/rdn2_security.c b/plat/arm/board/rdn2/rdn2_security.c
new file mode 100644
index 000000000..9568b60cd
--- /dev/null
+++ b/plat/arm/board/rdn2/rdn2_security.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+
+static const arm_tzc_regions_info_t tzc_regions[] = {
+ ARM_TZC_REGIONS_DEF,
+ {}
+};
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+
+ int i;
+
+ for (i = 0; i < TZC400_COUNT; i++)
+ arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
+
+}
diff --git a/plat/arm/board/rdn2/rdn2_topology.c b/plat/arm/board/rdn2/rdn2_topology.c
new file mode 100644
index 000000000..5c2e287cb
--- /dev/null
+++ b/plat/arm/board/rdn2/rdn2_topology.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+/******************************************************************************
+ * The power domain tree descriptor.
+ ******************************************************************************/
+const unsigned char rd_n2_pd_tree_desc[] = {
+ PLAT_ARM_CLUSTER_COUNT,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return rd_n2_pd_tree_desc;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF)),
+};
diff --git a/plat/arm/board/rdn2/rdn2_trusted_boot.c b/plat/arm/board/rdn2/rdn2_trusted_boot.c
new file mode 100644
index 000000000..4592b8fba
--- /dev/null
+++ b/plat/arm/board/rdn2/rdn2_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts b/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts
new file mode 100644
index 000000000..9c9cefe87
--- /dev/null
+++ b/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0xFEF00000>;
+ max-size = <0x0100000>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts b/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts
new file mode 100644
index 000000000..62ba2c3f2
--- /dev/null
+++ b/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+/ {
+ /* compatible string */
+ compatible = "arm,rd-v1";
+
+ /*
+ * Place holder for system-id node with default values. The
+ * value of platform-id and config-id will be set to the
+ * correct values during the BL2 stage of boot.
+ */
+ system-id {
+ platform-id = <0x0>;
+ config-id = <0x0>;
+ multi-chip-mode = <0x0>;
+ };
+};
diff --git a/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts b/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts
new file mode 100644
index 000000000..49eda2735
--- /dev/null
+++ b/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
+};
diff --git a/plat/arm/board/rdv1/include/platform_def.h b/plat/arm/board/rdv1/include/platform_def.h
new file mode 100644
index 000000000..5b98b4e8c
--- /dev/null
+++ b/plat/arm/board/rdv1/include/platform_def.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+
+#include <sgi_soc_platform_def.h>
+
+#define PLAT_ARM_CLUSTER_COUNT U(16)
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1)
+#define CSS_SGI_MAX_PE_PER_CPU U(1)
+
+#define PLAT_CSS_MHU_BASE UL(0x45400000)
+#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
+
+#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+
+/* TZC Related Constants */
+#define PLAT_ARM_TZC_BASE UL(0x21830000)
+#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0)
+
+#define TZC400_OFFSET UL(0x1000000)
+#define TZC400_COUNT 4
+
+#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \
+ (n * TZC400_OFFSET))
+
+#define TZC_NSAID_ALL_AP U(0)
+#define TZC_NSAID_PCI U(1)
+#define TZC_NSAID_HDLCD0 U(2)
+#define TZC_NSAID_CLCD U(7)
+#define TZC_NSAID_AP U(9)
+#define TZC_NSAID_VIRTIO U(15)
+
+#define PLAT_ARM_TZC_NS_DEV_ACCESS \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI)) | \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP)) | \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD)) | \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
+
+/*
+ * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
+ */
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#endif
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x30140000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdv1/platform.mk b/plat/arm/board/rdv1/platform.mk
new file mode 100644
index 000000000..2ffd139c9
--- /dev/null
+++ b/plat/arm/board/rdv1/platform.mk
@@ -0,0 +1,60 @@
+# Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# RD-V1 platform uses GIC-Clayton which is based on GICv4.1
+GIC_ENABLE_V4_EXTN := 1
+
+include plat/arm/css/sgi/sgi-common.mk
+
+RDV1_BASE = plat/arm/board/rdv1
+
+PLAT_INCLUDES += -I${RDV1_BASE}/include/
+
+SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_v1.S
+
+PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c
+
+BL1_SOURCES += ${SGI_CPU_SOURCES} \
+ ${RDV1_BASE}/rdv1_err.c
+
+BL2_SOURCES += ${RDV1_BASE}/rdv1_plat.c \
+ ${RDV1_BASE}/rdv1_security.c \
+ ${RDV1_BASE}/rdv1_err.c \
+ lib/utils/mem_region.c \
+ drivers/arm/tzc/tzc400.c \
+ plat/arm/common/arm_tzc400.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+BL31_SOURCES += ${SGI_CPU_SOURCES} \
+ ${RDV1_BASE}/rdv1_plat.c \
+ ${RDV1_BASE}/rdv1_topology.c \
+ drivers/cfi/v2m/v2m_flash.c \
+ lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += ${RDV1_BASE}/rdv1_trusted_boot.c
+BL2_SOURCES += ${RDV1_BASE}/rdv1_trusted_boot.c
+endif
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES += ${RDV1_BASE}/fdts/${PLAT}_fw_config.dts \
+ ${RDV1_BASE}/fdts/${PLAT}_tb_fw_config.dts
+FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+
+FDT_SOURCES += ${RDV1_BASE}/fdts/${PLAT}_nt_fw_config.dts
+NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
+
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
+
+override CTX_INCLUDE_AARCH32_REGS := 0
+override ENABLE_AMU := 1
diff --git a/plat/arm/board/rdv1/rdv1_err.c b/plat/arm/board/rdv1/rdv1_err.c
new file mode 100644
index 000000000..68f9a3ef6
--- /dev/null
+++ b/plat/arm/board/rdv1/rdv1_err.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * rdv1 error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+ while (1) {
+ wfi();
+ }
+}
diff --git a/plat/arm/board/rdv1/rdv1_plat.c b/plat/arm/board/rdv1/rdv1_plat.c
new file mode 100644
index 000000000..ab5251e51
--- /dev/null
+++ b/plat/arm/board/rdv1/rdv1_plat.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+#include <sgi_plat.h>
+
+unsigned int plat_arm_sgi_get_platform_id(void)
+{
+ return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
+ & SID_SYSTEM_ID_PART_NUM_MASK;
+}
+
+unsigned int plat_arm_sgi_get_config_id(void)
+{
+ return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
+}
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+ return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+ SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+void bl31_platform_setup(void)
+{
+ sgi_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/rdv1/rdv1_security.c b/plat/arm/board/rdv1/rdv1_security.c
new file mode 100644
index 000000000..1247db860
--- /dev/null
+++ b/plat/arm/board/rdv1/rdv1_security.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+static const arm_tzc_regions_info_t tzc_regions[] = {
+ ARM_TZC_REGIONS_DEF,
+ {}
+};
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+ int i;
+
+ for (i = 0; i < TZC400_COUNT; i++)
+ arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
+}
diff --git a/plat/arm/board/rdv1/rdv1_topology.c b/plat/arm/board/rdv1/rdv1_topology.c
new file mode 100644
index 000000000..ab64fd8d0
--- /dev/null
+++ b/plat/arm/board/rdv1/rdv1_topology.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+/******************************************************************************
+ * The power domain tree descriptor.
+ ******************************************************************************/
+const unsigned char rd_v1_pd_tree_desc[] = {
+ PLAT_ARM_CLUSTER_COUNT,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return rd_v1_pd_tree_desc;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF))
+};
diff --git a/plat/arm/board/rdv1/rdv1_trusted_boot.c b/plat/arm/board/rdv1/rdv1_trusted_boot.c
new file mode 100644
index 000000000..4592b8fba
--- /dev/null
+++ b/plat/arm/board/rdv1/rdv1_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts b/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts
new file mode 100644
index 000000000..9c9cefe87
--- /dev/null
+++ b/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0xFEF00000>;
+ max-size = <0x0100000>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts b/plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts
new file mode 100644
index 000000000..71c7db3cb
--- /dev/null
+++ b/plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+/ {
+ /* compatible string */
+ compatible = "arm,rd-v1-mc";
+
+ /*
+ * Place holder for system-id node with default values. The
+ * value of platform-id and config-id will be set to the
+ * correct values during the BL2 stage of boot.
+ */
+ system-id {
+ platform-id = <0x0>;
+ config-id = <0x0>;
+ multi-chip-mode = <0x0>;
+ };
+};
diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts b/plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts
new file mode 100644
index 000000000..49eda2735
--- /dev/null
+++ b/plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
+};
diff --git a/plat/arm/board/rdv1mc/include/platform_def.h b/plat/arm/board/rdv1mc/include/platform_def.h
new file mode 100644
index 000000000..112b2102b
--- /dev/null
+++ b/plat/arm/board/rdv1mc/include/platform_def.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <sgi_soc_platform_def.h>
+
+#define PLAT_ARM_CLUSTER_COUNT U(4)
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(1)
+#define CSS_SGI_MAX_PE_PER_CPU U(1)
+
+#define PLAT_CSS_MHU_BASE UL(0x45400000)
+#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
+
+#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+
+/* Virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xC0000000)
+
+/* Physical and virtual address space limits for MMU in AARCH64 mode */
+#define PLAT_PHY_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
+ CSS_SGI_CHIP_COUNT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
+ CSS_SGI_CHIP_COUNT)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x30140000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdv1mc/platform.mk b/plat/arm/board/rdv1mc/platform.mk
new file mode 100644
index 000000000..50728416a
--- /dev/null
+++ b/plat/arm/board/rdv1mc/platform.mk
@@ -0,0 +1,68 @@
+# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Enable GICv4 extension with multichip driver
+GIC_ENABLE_V4_EXTN := 1
+GICV3_IMPL_GIC600_MULTICHIP := 1
+
+include plat/arm/css/sgi/sgi-common.mk
+
+RDV1MC_BASE = plat/arm/board/rdv1mc
+
+PLAT_INCLUDES += -I${RDV1MC_BASE}/include/
+
+SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_v1.S
+
+PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c
+
+BL1_SOURCES += ${SGI_CPU_SOURCES} \
+ ${RDV1MC_BASE}/rdv1mc_err.c
+
+BL2_SOURCES += ${RDV1MC_BASE}/rdv1mc_plat.c \
+ ${RDV1MC_BASE}/rdv1mc_security.c \
+ ${RDV1MC_BASE}/rdv1mc_err.c \
+ lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+BL31_SOURCES += ${SGI_CPU_SOURCES} \
+ ${RDV1MC_BASE}/rdv1mc_plat.c \
+ ${RDV1MC_BASE}/rdv1mc_topology.c \
+ drivers/cfi/v2m/v2m_flash.c \
+ drivers/arm/gic/v3/gic600_multichip.c \
+ lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += ${RDV1MC_BASE}/rdv1mc_trusted_boot.c
+BL2_SOURCES += ${RDV1MC_BASE}/rdv1mc_trusted_boot.c
+endif
+
+# Enable dynamic addition of MMAP regions in BL31
+BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES += ${RDV1MC_BASE}/fdts/${PLAT}_fw_config.dts \
+ ${RDV1MC_BASE}/fdts/${PLAT}_tb_fw_config.dts
+FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+
+$(eval $(call CREATE_SEQ,SEQ,4))
+ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ)))
+ $(error "Chip count for RD-V1-MC should be either $(SEQ) \
+ currently it is set to ${CSS_SGI_CHIP_COUNT}.")
+endif
+
+FDT_SOURCES += ${RDV1MC_BASE}/fdts/${PLAT}_nt_fw_config.dts
+NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
+
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
+
+override CTX_INCLUDE_AARCH32_REGS := 0
diff --git a/plat/arm/board/rdv1mc/rdv1mc_err.c b/plat/arm/board/rdv1mc/rdv1mc_err.c
new file mode 100644
index 000000000..755a5034e
--- /dev/null
+++ b/plat/arm/board/rdv1mc/rdv1mc_err.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * rdv1mc error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+ while (true) {
+ wfi();
+ }
+}
diff --git a/plat/arm/board/rdv1mc/rdv1mc_plat.c b/plat/arm/board/rdv1mc/rdv1mc_plat.c
new file mode 100644
index 000000000..d85940066
--- /dev/null
+++ b/plat/arm/board/rdv1mc/rdv1mc_plat.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <sgi_soc_platform_def.h>
+#include <sgi_plat.h>
+
+#if defined(IMAGE_BL31)
+static const mmap_region_t rdv1mc_dynamic_mmap[] = {
+ ARM_MAP_SHARED_RAM_REMOTE_CHIP(1),
+ CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
+ SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1),
+#if (CSS_SGI_CHIP_COUNT > 2)
+ ARM_MAP_SHARED_RAM_REMOTE_CHIP(2),
+ CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2),
+ SOC_CSS_MAP_DEVICE_REMOTE_CHIP(2),
+#endif
+#if (CSS_SGI_CHIP_COUNT > 3)
+ ARM_MAP_SHARED_RAM_REMOTE_CHIP(3),
+ CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3),
+ SOC_CSS_MAP_DEVICE_REMOTE_CHIP(3)
+#endif
+};
+
+static struct gic600_multichip_data rdv1mc_multichip_data __init = {
+ .rt_owner_base = PLAT_ARM_GICD_BASE,
+ .rt_owner = 0,
+ .chip_count = CSS_SGI_CHIP_COUNT,
+ .chip_addrs = {
+ PLAT_ARM_GICD_BASE >> 16,
+ (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
+#if (CSS_SGI_CHIP_COUNT > 2)
+ (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
+#endif
+#if (CSS_SGI_CHIP_COUNT > 3)
+ (PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
+#endif
+ },
+ .spi_ids = {
+ {32, 255},
+ {0, 0},
+#if (CSS_SGI_CHIP_COUNT > 2)
+ {0, 0},
+#endif
+#if (CSS_SGI_CHIP_COUNT > 3)
+ {0, 0},
+#endif
+ }
+};
+
+static uintptr_t rdv1mc_multichip_gicr_frames[] = {
+ /* Chip 0's GICR Base */
+ PLAT_ARM_GICR_BASE,
+ /* Chip 1's GICR BASE */
+ PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),
+#if (CSS_SGI_CHIP_COUNT > 2)
+ /* Chip 2's GICR BASE */
+ PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2),
+#endif
+#if (CSS_SGI_CHIP_COUNT > 3)
+ /* Chip 3's GICR BASE */
+ PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3),
+#endif
+ UL(0) /* Zero Termination */
+};
+#endif /* IMAGE_BL31 */
+
+unsigned int plat_arm_sgi_get_platform_id(void)
+{
+ return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
+ & SID_SYSTEM_ID_PART_NUM_MASK;
+}
+
+unsigned int plat_arm_sgi_get_config_id(void)
+{
+ return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
+}
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+ return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+ SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+/*
+ * bl31_platform_setup_function is guarded by IMAGE_BL31 macro because
+ * PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not
+ * for other stages.
+ */
+#if defined(IMAGE_BL31)
+void bl31_platform_setup(void)
+{
+ int ret;
+ unsigned int i;
+
+ if ((plat_arm_sgi_get_multi_chip_mode() == 0) &&
+ (CSS_SGI_CHIP_COUNT > 1)) {
+ ERROR("Chip Count is set to %u but multi-chip mode is not "
+ "enabled\n", CSS_SGI_CHIP_COUNT);
+ panic();
+ } else if ((plat_arm_sgi_get_multi_chip_mode() == 1) &&
+ (CSS_SGI_CHIP_COUNT > 1)) {
+ INFO("Enabling support for multi-chip in RD-V1-MC\n");
+
+ for (i = 0; i < ARRAY_SIZE(rdv1mc_dynamic_mmap); i++) {
+ ret = mmap_add_dynamic_region(
+ rdv1mc_dynamic_mmap[i].base_pa,
+ rdv1mc_dynamic_mmap[i].base_va,
+ rdv1mc_dynamic_mmap[i].size,
+ rdv1mc_dynamic_mmap[i].attr);
+ if (ret != 0) {
+ ERROR("Failed to add dynamic mmap entry "
+ "(ret=%d)\n", ret);
+ panic();
+ }
+ }
+
+ plat_arm_override_gicr_frames(
+ rdv1mc_multichip_gicr_frames);
+ gic600_multichip_init(&rdv1mc_multichip_data);
+ }
+
+ sgi_bl31_common_platform_setup();
+}
+#endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdv1mc/rdv1mc_security.c b/plat/arm/board/rdv1mc/rdv1mc_security.c
new file mode 100644
index 000000000..541f800a8
--- /dev/null
+++ b/plat/arm/board/rdv1mc/rdv1mc_security.c
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/rdv1mc/rdv1mc_topology.c b/plat/arm/board/rdv1mc/rdv1mc_topology.c
new file mode 100644
index 000000000..4486e5cfa
--- /dev/null
+++ b/plat/arm/board/rdv1mc/rdv1mc_topology.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+#include <sgi_variant.h>
+
+/******************************************************************************
+ * The power domain tree descriptor.
+ ******************************************************************************/
+const unsigned char rd_v1_mc_pd_tree_desc_multi_chip[] = {
+ ((PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT)),
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+#if (CSS_SGI_CHIP_COUNT > 1)
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+#endif
+#if (CSS_SGI_CHIP_COUNT > 2)
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+#endif
+#if (CSS_SGI_CHIP_COUNT > 3)
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER,
+ CSS_SGI_MAX_CPUS_PER_CLUSTER
+#endif
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ if (plat_arm_sgi_get_multi_chip_mode() == 1)
+ return rd_v1_mc_pd_tree_desc_multi_chip;
+ panic();
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+#if (CSS_SGI_CHIP_COUNT > 1)
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)),
+#endif
+#if (CSS_SGI_CHIP_COUNT > 2)
+ (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x3)),
+#endif
+#if (CSS_SGI_CHIP_COUNT > 3)
+ (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x3))
+#endif
+};
diff --git a/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c b/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c
new file mode 100644
index 000000000..4592b8fba
--- /dev/null
+++ b/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts
new file mode 100644
index 000000000..84fc1ad5f
--- /dev/null
+++ b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ nt_fw-config {
+ load-address = <0x0 0xFEF00000>;
+ max-size = <0x0100000>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
index 1e1ea14b0..260247a0d 100644
--- a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
+++ b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,5 +17,6 @@
system-id {
platform-id = <0x0>;
config-id = <0x0>;
+ multi-chip-mode = <0x0>;
};
};
diff --git a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
index b14d7adca..49eda2735 100644
--- a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
+++ b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,19 +7,22 @@
/dts-v1/;
/ {
- /* Platform Config */
- compatible = "arm,tb_fw";
- nt_fw_config_addr = <0x0 0xFEF00000>;
- nt_fw_config_max_size = <0x0100000>;
- /*
- * The following two entries are placeholders for Mbed TLS
- * heap information. The default values don't matter since
- * they will be overwritten by BL1.
- * In case of having shared Mbed TLS heap between BL1 and BL2,
- * BL1 will populate these two properties with the respective
- * info about the shared heap. This info will be available for
- * BL2 in order to locate and re-use the heap.
- */
- mbedtls_heap_addr = <0x0 0x0>;
- mbedtls_heap_size = <0x0>;
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
};
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
index fd59e5277..c929334cd 100644
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ b/plat/arm/board/sgi575/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,14 +9,13 @@
#include <lib/utils_def.h>
-#include <sgi_base_platform_def.h>
+#include <sgi_soc_platform_def.h>
#define PLAT_ARM_CLUSTER_COUNT U(2)
#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(4)
#define CSS_SGI_MAX_PE_PER_CPU U(1)
#define PLAT_CSS_MHU_BASE UL(0x45000000)
-#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
/* Base address of DMC-620 instances */
#define SGI575_DMC620_BASE0 UL(0x4e000000)
@@ -38,4 +37,9 @@
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#endif
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x300C0000)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk
index ce2717fe0..89abcfe8e 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/sgi575/platform.mk
@@ -12,6 +12,8 @@ PLAT_INCLUDES += -I${SGI575_BASE}/include/
SGI_CPU_SOURCES := lib/cpus/aarch64/cortex_a75.S
+PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c
+
BL1_SOURCES += ${SGI_CPU_SOURCES} \
${SGI575_BASE}/sgi575_err.c
@@ -29,15 +31,30 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \
lib/utils/mem_region.c \
plat/arm/common/arm_nor_psci_mem_protect.c
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c
+BL2_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c
+endif
+
# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts
+FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_fw_config.dts \
+ ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts
+
+FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_nt_fw_config.dts
NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
# Add the NT_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
+
+ifneq ($(CSS_SGI_CHIP_COUNT),1)
+ $(error "Chip count for SGI575 should be 1, currently set to \
+ ${CSS_SGI_CHIP_COUNT}.")
+endif
diff --git a/plat/arm/board/sgi575/sgi575_err.c b/plat/arm/board/sgi575/sgi575_err.c
index c1cc1a7fd..21bfcb73a 100644
--- a/plat/arm/board/sgi575/sgi575_err.c
+++ b/plat/arm/board/sgi575/sgi575_err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,7 @@
*/
void __dead2 plat_arm_error_handler(int err)
{
- while (1) {
+ while (true) {
wfi();
}
}
diff --git a/plat/arm/board/sgi575/sgi575_plat.c b/plat/arm/board/sgi575/sgi575_plat.c
index 0d3fd16ab..dc294e6a8 100644
--- a/plat/arm/board/sgi575/sgi575_plat.c
+++ b/plat/arm/board/sgi575/sgi575_plat.c
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <plat/common/platform.h>
-
+#include <sgi_plat.h>
#include <sgi_variant.h>
unsigned int plat_arm_sgi_get_platform_id(void)
@@ -18,3 +18,13 @@ unsigned int plat_arm_sgi_get_config_id(void)
return (mmio_read_32(SSC_VERSION) >> SSC_VERSION_CONFIG_SHIFT)
& SSC_VERSION_CONFIG_MASK;
}
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+ return 0;
+}
+
+void bl31_platform_setup(void)
+{
+ sgi_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/sgi575/sgi575_trusted_boot.c b/plat/arm/board/sgi575/sgi575_trusted_boot.c
new file mode 100644
index 000000000..4592b8fba
--- /dev/null
+++ b/plat/arm/board/sgi575/sgi575_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
new file mode 100644
index 000000000..5d478e9a5
--- /dev/null
+++ b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
index 95025493b..49eda2735 100644
--- a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
+++ b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,10 +7,22 @@
/dts-v1/;
/ {
- /* Platform Config */
- plat_arm_bl2 {
+ tb_fw-config {
compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x83000000>;
- hw_config_max_size = <0x01000000>;
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
};
};
diff --git a/plat/arm/board/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h
index d165ff9ed..e83cd5764 100644
--- a/plat/arm/board/sgm775/include/platform_def.h
+++ b/plat/arm/board/sgm775/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,6 +12,9 @@
#define PLAT_MAX_CPUS_PER_CLUSTER U(8)
#define PLAT_MAX_PE_PER_CPU U(1)
+#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
+
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk
index 7a843c369..a649939de 100644
--- a/plat/arm/board/sgm775/platform.mk
+++ b/plat/arm/board/sgm775/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,7 +8,16 @@ include plat/arm/css/sgm/sgm-common.mk
SGM775_BASE= plat/arm/board/sgm775
-FDT_SOURCES += ${SGM775_BASE}/fdts/sgm775_tb_fw_config.dts
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES += ${SGM775_BASE}/fdts/${PLAT}_fw_config.dts \
+ ${SGM775_BASE}/fdts/${PLAT}_tb_fw_config.dts
+FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
PLAT_INCLUDES +=-I${SGM775_BASE}/include/
@@ -21,3 +30,8 @@ BL2_SOURCES += lib/utils/mem_region.c \
BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \
lib/utils/mem_region.c \
plat/arm/common/arm_nor_psci_mem_protect.c
+
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c
+BL2_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c
+endif
diff --git a/plat/arm/board/sgm775/sgm775_err.c b/plat/arm/board/sgm775/sgm775_err.c
index e1e05860d..dc114f07f 100644
--- a/plat/arm/board/sgm775/sgm775_err.c
+++ b/plat/arm/board/sgm775/sgm775_err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,7 @@
*/
void __dead2 plat_arm_error_handler(int err)
{
- while (1) {
+ while (true) {
wfi();
}
}
diff --git a/plat/arm/board/sgm775/sgm775_trusted_boot.c b/plat/arm/board/sgm775/sgm775_trusted_boot.c
new file mode 100644
index 000000000..4592b8fba
--- /dev/null
+++ b/plat/arm/board/sgm775/sgm775_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/tc0/fdts/tc0_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_fw_config.dts
new file mode 100644
index 000000000..4b6abd4d1
--- /dev/null
+++ b/plat/arm/board/tc0/fdts/tc0_fw_config.dts
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x400>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+
+ tos_fw-config {
+ load-address = <0x0 0x04001700>;
+ max-size = <0x1000>;
+ id = <TOS_FW_CONFIG_ID>;
+ };
+
+ hw-config {
+ load-address = <0x0 0x83000000>;
+ max-size = <0x01000000>;
+ id = <HW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts b/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts
new file mode 100644
index 000000000..2f459b013
--- /dev/null
+++ b/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+/ {
+ compatible = "arm,ffa-core-manifest-1.0";
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ attribute {
+ spmc_id = <0x8000>;
+ maj_ver = <0x1>;
+ min_ver = <0x0>;
+ exec_state = <0x0>;
+ load_address = <0x0 0xfd000000>;
+ entrypoint = <0x0 0xfd000000>;
+ binary_size = <0x80000>;
+ };
+
+ hypervisor {
+ compatible = "hafnium,hafnium";
+ vm1 {
+ is_ffa_partition;
+ debug_name = "cactus-primary";
+ load_address = <0xfe000000>;
+ vcpu_count = <8>;
+ mem_size = <1048576>;
+ };
+ vm2 {
+ is_ffa_partition;
+ debug_name = "cactus-secondary";
+ load_address = <0xfe100000>;
+ vcpu_count = <8>;
+ mem_size = <1048576>;
+ };
+ vm3 {
+ is_ffa_partition;
+ debug_name = "cactus-tertiary";
+ load_address = <0xfe200000>;
+ vcpu_count = <8>;
+ mem_size = <1048576>;
+ };
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ CPU0:cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ };
+
+ /*
+ * SPMC (Hafnium) requires secondary cpu nodes are declared in
+ * descending order
+ */
+ CPU7:cpu@700 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x700>;
+ enable-method = "psci";
+ };
+
+ CPU6:cpu@600 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x600>;
+ enable-method = "psci";
+ };
+
+ CPU5:cpu@500 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x500>;
+ enable-method = "psci";
+ };
+
+ CPU4:cpu@400 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x400>;
+ enable-method = "psci";
+ };
+
+ CPU3:cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x300>;
+ enable-method = "psci";
+ };
+
+ CPU2:cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x200>;
+ enable-method = "psci";
+ };
+
+ CPU1:cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ };
+ };
+
+ /* 32MB of TC0_TZC_DRAM1_BASE */
+ memory@fd000000 {
+ device_type = "memory";
+ reg = <0x0 0xfd000000 0x2000000>;
+ };
+};
diff --git a/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts b/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts
new file mode 100644
index 000000000..221039c43
--- /dev/null
+++ b/plat/arm/board/tc0/fdts/tc0_spmc_optee_sp_manifest.dts
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+/ {
+ compatible = "arm,ffa-core-manifest-1.0";
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ attribute {
+ spmc_id = <0x8000>;
+ maj_ver = <0x1>;
+ min_ver = <0x0>;
+ exec_state = <0x0>;
+ load_address = <0x0 0xfd000000>;
+ entrypoint = <0x0 0xfd000000>;
+ binary_size = <0x80000>;
+ };
+
+ hypervisor {
+ compatible = "hafnium,hafnium";
+ vm1 {
+ is_ffa_partition;
+ debug_name = "op-tee";
+ load_address = <0xfd280000>;
+ vcpu_count = <8>;
+ mem_size = <30928896>; /* 32MB TZC DRAM - SPMC region */
+ };
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ CPU0:cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ };
+
+ /*
+ * SPMC (Hafnium) requires secondary cpu nodes are declared in
+ * descending order
+ */
+ CPU7:cpu@700 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x700>;
+ enable-method = "psci";
+ };
+
+ CPU6:cpu@600 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x600>;
+ enable-method = "psci";
+ };
+
+ CPU5:cpu@500 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x500>;
+ enable-method = "psci";
+ };
+
+ CPU4:cpu@400 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x400>;
+ enable-method = "psci";
+ };
+
+ CPU3:cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x300>;
+ enable-method = "psci";
+ };
+
+ CPU2:cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x200>;
+ enable-method = "psci";
+ };
+
+ CPU1:cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ };
+ };
+
+ /* 32MB of TC0_TZC_DRAM1_BASE */
+ memory@fd000000 {
+ device_type = "memory";
+ reg = <0x0 0xfd000000 0x2000000>;
+ };
+};
diff --git a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts
new file mode 100644
index 000000000..de5f95d5e
--- /dev/null
+++ b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+ tb_fw-config {
+ compatible = "arm,tb_fw";
+
+ /* Disable authentication for development */
+ disable_auth = <0x0>;
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+ };
+
+ secure-partitions {
+ compatible = "arm,sp";
+#if OPTEE_SP_FW_CONFIG
+ op-tee {
+ uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>;
+ load-address = <0xfd280000>;
+ };
+#else
+ cactus-primary {
+ uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>;
+ load-address = <0xfe000000>;
+ owner = "SiP";
+ };
+
+ cactus-secondary {
+ uuid = <0xd1582309 0xf02347b9 0x827c4464 0xf5578fc8>;
+ load-address = <0xfe100000>;
+ owner = "Plat";
+ };
+
+ cactus-tertiary {
+ uuid = <0x79b55c73 0x1d8c44b9 0x859361e1 0x770ad8d2>;
+ load-address = <0xfe200000>;
+ };
+#endif
+ };
+};
diff --git a/plat/arm/board/tc0/include/plat_macros.S b/plat/arm/board/tc0/include/plat_macros.S
new file mode 100644
index 000000000..6006fa5b8
--- /dev/null
+++ b/plat/arm/board/tc0/include/plat_macros.S
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <arm_macros.S>
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ *
+ * There are currently no platform specific regs
+ * to print.
+ * ---------------------------------------------
+ */
+ .macro plat_crash_print_regs
+ .endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h
new file mode 100644
index 000000000..30b5ab716
--- /dev/null
+++ b/plat/arm/board/tc0/include/platform_def.h
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <plat/arm/board/common/board_css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/arm_spm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
+#include <plat/common/common_def.h>
+
+#define PLATFORM_CORE_COUNT 8
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00080000 /* 512 KB */
+
+/*
+ * The top 16MB of ARM_DRAM1 is configured as secure access only using the TZC,
+ * its base is ARM_AP_TZC_DRAM1_BASE.
+ *
+ * Reserve 32MB below ARM_AP_TZC_DRAM1_BASE for:
+ * - BL32_BASE when SPD_spmd is enabled
+ * - Region to load Trusted OS
+ */
+#define TC0_TZC_DRAM1_BASE (ARM_AP_TZC_DRAM1_BASE - \
+ TC0_TZC_DRAM1_SIZE)
+#define TC0_TZC_DRAM1_SIZE UL(0x02000000) /* 32 MB */
+#define TC0_TZC_DRAM1_END (TC0_TZC_DRAM1_BASE + \
+ TC0_TZC_DRAM1_SIZE - 1)
+
+#define TC0_NS_DRAM1_BASE ARM_DRAM1_BASE
+#define TC0_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \
+ ARM_TZC_DRAM1_SIZE - \
+ TC0_TZC_DRAM1_SIZE)
+#define TC0_NS_DRAM1_END (TC0_NS_DRAM1_BASE + \
+ TC0_NS_DRAM1_SIZE - 1)
+
+/*
+ * Mappings for TC0 DRAM1 (non-secure) and TC0 TZC DRAM1 (secure)
+ */
+#define TC0_MAP_NS_DRAM1 MAP_REGION_FLAT( \
+ TC0_NS_DRAM1_BASE, \
+ TC0_NS_DRAM1_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
+
+
+#define TC0_MAP_TZC_DRAM1 MAP_REGION_FLAT( \
+ TC0_TZC_DRAM1_BASE, \
+ TC0_TZC_DRAM1_SIZE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+/*
+ * Max size of SPMC is 2MB for tc0. With SPMD enabled this value corresponds to
+ * max size of BL32 image.
+ */
+#if defined(SPD_spmd)
+#define PLAT_ARM_SPMC_BASE TC0_TZC_DRAM1_BASE
+#define PLAT_ARM_SPMC_SIZE UL(0x200000) /* 2 MB */
+#endif
+
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage.
+ */
+#if defined(IMAGE_BL31)
+# if SPM_MM
+# define PLAT_ARM_MMAP_ENTRIES 9
+# define MAX_XLAT_TABLES 7
+# define PLAT_SP_IMAGE_MMAP_REGIONS 7
+# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
+# else
+# define PLAT_ARM_MMAP_ENTRIES 8
+# define MAX_XLAT_TABLES 8
+# endif
+#elif defined(IMAGE_BL32)
+# define PLAT_ARM_MMAP_ENTRIES 8
+# define MAX_XLAT_TABLES 5
+#elif !USE_ROMLIB
+# define PLAT_ARM_MMAP_ENTRIES 11
+# define MAX_XLAT_TABLES 7
+#else
+# define PLAT_ARM_MMAP_ENTRIES 12
+# define MAX_XLAT_TABLES 6
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
+ * plus a little space for growth.
+ */
+#define PLAT_ARM_MAX_BL1_RW_SIZE 0xC000
+
+/*
+ * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
+ */
+
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0x1000
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0xe000
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+# define PLAT_ARM_MAX_BL2_SIZE 0x20000
+#else
+# define PLAT_ARM_MAX_BL2_SIZE 0x14000
+#endif
+
+/*
+ * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of
+ * BL2 and BL1-RW
+ */
+#define PLAT_ARM_MAX_BL31_SIZE 0x3B000
+
+/*
+ * Size of cacheable stacks
+ */
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+# define PLATFORM_STACK_SIZE 0x1000
+# else
+# define PLATFORM_STACK_SIZE 0x440
+# endif
+#elif defined(IMAGE_BL2)
+# if TRUSTED_BOARD_BOOT
+# define PLATFORM_STACK_SIZE 0x1000
+# else
+# define PLATFORM_STACK_SIZE 0x400
+# endif
+#elif defined(IMAGE_BL2U)
+# define PLATFORM_STACK_SIZE 0x400
+#elif defined(IMAGE_BL31)
+# if SPM_MM
+# define PLATFORM_STACK_SIZE 0x500
+# else
+# define PLATFORM_STACK_SIZE 0x400
+# endif
+#elif defined(IMAGE_BL32)
+# define PLATFORM_STACK_SIZE 0x440
+#endif
+
+
+#define TC0_DEVICE_BASE 0x21000000
+#define TC0_DEVICE_SIZE 0x5f000000
+
+// TC0_MAP_DEVICE covers different peripherals
+// available to the platform
+#define TC0_MAP_DEVICE MAP_REGION_FLAT( \
+ TC0_DEVICE_BASE, \
+ TC0_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+
+#define TC0_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\
+ V2M_FLASH0_SIZE, \
+ MT_DEVICE | MT_RO | MT_SECURE)
+
+#define PLAT_ARM_NSTIMER_FRAME_ID 0
+
+#define PLAT_ARM_TRUSTED_ROM_BASE 0x0
+#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000 /* 512KB */
+
+#define PLAT_ARM_NSRAM_BASE 0x06000000
+#define PLAT_ARM_NSRAM_SIZE 0x00080000 /* 512KB */
+
+#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
+
+#define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \
+ PLAT_SP_IMAGE_NS_BUF_SIZE)
+
+/*******************************************************************************
+ * Memprotect definitions
+ ******************************************************************************/
+/* PSCI memory protect definitions:
+ * This variable is stored in a non-secure flash because some ARM reference
+ * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
+ * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
+ */
+#define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \
+ V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+/*Secure Watchdog Constants */
+#define SBSA_SECURE_WDOG_BASE UL(0x2A480000)
+#define SBSA_SECURE_WDOG_TIMEOUT UL(100)
+
+#define PLAT_ARM_SCMI_CHANNEL_COUNT 1
+
+#define PLAT_ARM_CLUSTER_COUNT U(1)
+#define PLAT_MAX_CPUS_PER_CLUSTER U(8)
+#define PLAT_MAX_PE_PER_CPU U(1)
+
+#define PLAT_CSS_MHU_BASE UL(0x45400000)
+#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
+
+#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+
+/*
+ * Physical and virtual address space limits for MMU in AARCH64
+ */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x30140000)
+
+/*
+ * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
+ * SCP_BL2 size plus a little space for growth.
+ */
+#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x20000
+
+/*
+ * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
+ * SCP_BL2U size plus a little space for growth.
+ */
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x20000
+
+/* TZC Related Constants */
+#define PLAT_ARM_TZC_BASE UL(0x25000000)
+#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0)
+
+#define TZC400_OFFSET UL(0x1000000)
+#define TZC400_COUNT 4
+
+#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \
+ (n * TZC400_OFFSET))
+
+#define TZC_NSAID_DEFAULT U(0)
+
+#define PLAT_ARM_TZC_NS_DEV_ACCESS \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_DEFAULT))
+
+/*
+ * The first region below, TC0_TZC_DRAM1_BASE (0xfd000000) to
+ * ARM_SCP_TZC_DRAM1_END (0xffffffff) will mark the last 48 MB of DRAM as
+ * secure. The second region gives non secure access to rest of DRAM.
+ */
+#define TC0_TZC_REGIONS_DEF \
+ {TC0_TZC_DRAM1_BASE, ARM_SCP_TZC_DRAM1_END, \
+ TZC_REGION_S_RDWR, PLAT_ARM_TZC_NS_DEV_ACCESS}, \
+ {TC0_NS_DRAM1_BASE, TC0_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
+ PLAT_ARM_TZC_NS_DEV_ACCESS}
+
+/* virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/tc0/include/tc0_helpers.S b/plat/arm/board/tc0/include/tc0_helpers.S
new file mode 100644
index 000000000..90623a273
--- /dev/null
+++ b/plat/arm/board/tc0/include/tc0_helpers.S
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+#include <cpu_macros.S>
+
+ .globl plat_arm_calc_core_pos
+ .globl plat_reset_handler
+
+ /* ---------------------------------------------------------------------
+ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+ *
+ * Function to calculate the core position on TC0.
+ *
+ * (ClusterId * PLAT_MAX_CPUS_PER_CLUSTER * PLAT_MAX_PE_PER_CPU) +
+ * (CPUId * PLAT_MAX_PE_PER_CPU) +
+ * ThreadId
+ *
+ * which can be simplified as:
+ *
+ * ((ClusterId * PLAT_MAX_CPUS_PER_CLUSTER + CPUId) * PLAT_MAX_PE_PER_CPU)
+ * + ThreadId
+ * ---------------------------------------------------------------------
+ */
+func plat_arm_calc_core_pos
+ /*
+ * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
+ * look as if in a multi-threaded implementation.
+ */
+ tst x0, #MPIDR_MT_MASK
+ lsl x3, x0, #MPIDR_AFFINITY_BITS
+ csel x3, x3, x0, eq
+
+ /* Extract individual affinity fields from MPIDR */
+ ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+
+ /* Compute linear position */
+ mov x4, #PLAT_MAX_CPUS_PER_CLUSTER
+ madd x1, x2, x4, x1
+ mov x5, #PLAT_MAX_PE_PER_CPU
+ madd x0, x1, x5, x0
+ ret
+endfunc plat_arm_calc_core_pos
+
+ /* -----------------------------------------------------
+ * void plat_reset_handler(void);
+ *
+ * Determine the CPU MIDR and disable power down bit for
+ * that CPU.
+ * -----------------------------------------------------
+ */
+func plat_reset_handler
+ ret
+endfunc plat_reset_handler
diff --git a/plat/arm/board/tc0/include/tc0_plat.h b/plat/arm/board/tc0/include/tc0_plat.h
new file mode 100644
index 000000000..f0cb43132
--- /dev/null
+++ b/plat/arm/board/tc0/include/tc0_plat.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef tc0_bl31_common_platform_setup_PLAT_H
+#define tc0_bl31_common_platform_setup_PLAT_H
+
+void tc0_bl31_common_platform_setup(void);
+
+#endif /* tc0_bl31_common_platform_setup_PLAT_H */
diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk
new file mode 100644
index 000000000..393d09cff
--- /dev/null
+++ b/plat/arm/board/tc0/platform.mk
@@ -0,0 +1,119 @@
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+CSS_LOAD_SCP_IMAGES := 1
+
+CSS_USE_SCMI_SDS_DRIVER := 1
+
+RAS_EXTENSION := 0
+
+SDEI_SUPPORT := 0
+
+EL3_EXCEPTION_HANDLING := 0
+
+HANDLE_EA_EL3_FIRST := 0
+
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY := 1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM := 0
+
+GIC_ENABLE_V4_EXTN := 1
+
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600 := 1
+
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+ENT_GIC_SOURCES := ${GICV3_SOURCES} \
+ plat/common/plat_gicv3.c \
+ plat/arm/common/arm_gicv3.c
+
+override NEED_BL2U := no
+
+override ARM_PLAT_MT := 1
+
+TC0_BASE = plat/arm/board/tc0
+
+PLAT_INCLUDES += -I${TC0_BASE}/include/
+
+TC0_CPU_SOURCES := lib/cpus/aarch64/cortex_klein.S \
+ lib/cpus/aarch64/cortex_matterhorn.S
+
+INTERCONNECT_SOURCES := ${TC0_BASE}/tc0_interconnect.c
+
+PLAT_BL_COMMON_SOURCES += ${TC0_BASE}/tc0_plat.c \
+ ${TC0_BASE}/include/tc0_helpers.S
+
+BL1_SOURCES += ${INTERCONNECT_SOURCES} \
+ ${TC0_CPU_SOURCES} \
+ ${TC0_BASE}/tc0_trusted_boot.c \
+ ${TC0_BASE}/tc0_err.c \
+ drivers/arm/sbsa/sbsa.c
+
+
+BL2_SOURCES += ${TC0_BASE}/tc0_security.c \
+ ${TC0_BASE}/tc0_err.c \
+ ${TC0_BASE}/tc0_trusted_boot.c \
+ lib/utils/mem_region.c \
+ drivers/arm/tzc/tzc400.c \
+ plat/arm/common/arm_tzc400.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+BL31_SOURCES += ${INTERCONNECT_SOURCES} \
+ ${TC0_CPU_SOURCES} \
+ ${ENT_GIC_SOURCES} \
+ ${TC0_BASE}/tc0_bl31_setup.c \
+ ${TC0_BASE}/tc0_topology.c \
+ drivers/cfi/v2m/v2m_flash.c \
+ lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES += ${TC0_BASE}/fdts/${PLAT}_fw_config.dts \
+ ${TC0_BASE}/fdts/${PLAT}_tb_fw_config.dts
+FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+
+ifeq (${SPD},spmd)
+ifeq ($(ARM_SPMC_MANIFEST_DTS),)
+ARM_SPMC_MANIFEST_DTS := ${TC0_BASE}/fdts/${PLAT}_spmc_manifest.dts
+endif
+
+FDT_SOURCES += ${ARM_SPMC_MANIFEST_DTS}
+TC0_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/$(notdir $(basename ${ARM_SPMC_MANIFEST_DTS})).dtb
+
+# Add the TOS_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TC0_TOS_FW_CONFIG},--tos-fw-config,${TC0_TOS_FW_CONFIG}))
+endif
+
+#Device tree
+TC0_HW_CONFIG_DTS := fdts/tc0.dts
+TC0_HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb
+FDT_SOURCES += ${TC0_HW_CONFIG_DTS}
+$(eval TC0_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(TC0_HW_CONFIG_DTS)))
+
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TC0_HW_CONFIG},--hw-config,${TC0_HW_CONFIG}))
+
+override CTX_INCLUDE_AARCH32_REGS := 0
+
+override CTX_INCLUDE_PAUTH_REGS := 1
+
+override ENABLE_SPE_FOR_LOWER_ELS := 0
+
+include plat/arm/common/arm_common.mk
+include plat/arm/css/common/css_common.mk
+include plat/arm/soc/common/soc_css.mk
+include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/tc0/tc0_bl31_setup.c b/plat/arm/board/tc0/tc0_bl31_setup.c
new file mode 100644
index 000000000..b91b11c9d
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_bl31_setup.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <libfdt.h>
+#include <tc0_plat.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+static scmi_channel_plat_info_t tc0_scmi_plat_info[] = {
+ {
+ .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+ .db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhuv2_ring_doorbell,
+ }
+};
+
+void bl31_platform_setup(void)
+{
+ tc0_bl31_common_platform_setup();
+}
+
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
+{
+
+ return &tc0_scmi_plat_info[channel_id];
+
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+}
+
+void tc0_bl31_common_platform_setup(void)
+{
+ arm_bl31_platform_setup();
+}
+
+const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
+{
+ return css_scmi_override_pm_ops(ops);
+}
diff --git a/plat/arm/board/tc0/tc0_err.c b/plat/arm/board/tc0/tc0_err.c
new file mode 100644
index 000000000..83f2e9f6a
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_err.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * tc0 error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+ while (true) {
+ wfi();
+ }
+}
diff --git a/plat/arm/board/tc0/tc0_interconnect.c b/plat/arm/board/tc0/tc0_interconnect.c
new file mode 100644
index 000000000..e2fc4e1e1
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_interconnect.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * For Total Compute we should not do anything in these interface functions.
+ * They are used to override the weak functions in cci drivers.
+ */
+
+/******************************************************************************
+ * Helper function to initialize ARM interconnect driver.
+ *****************************************************************************/
+void __init plat_arm_interconnect_init(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to place current master into coherency
+ *****************************************************************************/
+void plat_arm_interconnect_enter_coherency(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to remove current master from coherency
+ *****************************************************************************/
+void plat_arm_interconnect_exit_coherency(void)
+{
+}
diff --git a/plat/arm/board/tc0/tc0_plat.c b/plat/arm/board/tc0/tc0_plat.c
new file mode 100644
index 000000000..b5698c098
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_plat.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <plat/common/platform.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/ccn.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <drivers/arm/sbsa.h>
+
+#if SPM_MM
+#include <services/spm_mm_partition.h>
+#endif
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
+ * arm_configure_mmu_elx() will give the available subset of that.
+ */
+#if IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ TC0_FLASH0_RO,
+ TC0_MAP_DEVICE,
+ {0}
+};
+#endif
+#if IMAGE_BL2
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ TC0_FLASH0_RO,
+ TC0_MAP_DEVICE,
+ TC0_MAP_NS_DRAM1,
+#if defined(SPD_spmd)
+ TC0_MAP_TZC_DRAM1,
+#endif
+#if ARM_BL31_IN_DRAM
+ ARM_MAP_BL31_SEC_DRAM,
+#endif
+#if SPM_MM
+ ARM_SP_IMAGE_MMAP,
+#endif
+#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
+ ARM_MAP_BL1_RW,
+#endif
+#ifdef SPD_opteed
+ ARM_MAP_OPTEE_CORE_MEM,
+ ARM_OPTEE_PAGEABLE_LOAD_MEM,
+#endif
+ {0}
+};
+#endif
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ V2M_MAP_IOFPGA,
+ TC0_MAP_DEVICE,
+#if SPM_MM
+ ARM_SPM_BUF_EL3_MMAP,
+#endif
+ {0}
+};
+
+#if SPM_MM && defined(IMAGE_BL31)
+const mmap_region_t plat_arm_secure_partition_mmap[] = {
+ PLAT_ARM_SECURE_MAP_DEVICE,
+ ARM_SP_IMAGE_MMAP,
+ ARM_SP_IMAGE_NS_BUF_MMAP,
+ ARM_SP_CPER_BUF_MMAP,
+ ARM_SP_IMAGE_RW_MMAP,
+ ARM_SPM_BUF_EL0_MMAP,
+ {0}
+};
+#endif /* SPM_MM && defined(IMAGE_BL31) */
+#endif
+
+ARM_CASSERT_MMAP
+
+#if SPM_MM && defined(IMAGE_BL31)
+/*
+ * Boot information passed to a secure partition during initialisation. Linear
+ * indices in MP information will be filled at runtime.
+ */
+static spm_mm_mp_info_t sp_mp_info[] = {
+ [0] = {0x81000000, 0},
+ [1] = {0x81000100, 0},
+ [2] = {0x81000200, 0},
+ [3] = {0x81000300, 0},
+ [4] = {0x81010000, 0},
+ [5] = {0x81010100, 0},
+ [6] = {0x81010200, 0},
+ [7] = {0x81010300, 0},
+};
+
+const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = {
+ .h.type = PARAM_SP_IMAGE_BOOT_INFO,
+ .h.version = VERSION_1,
+ .h.size = sizeof(spm_mm_boot_info_t),
+ .h.attr = 0,
+ .sp_mem_base = ARM_SP_IMAGE_BASE,
+ .sp_mem_limit = ARM_SP_IMAGE_LIMIT,
+ .sp_image_base = ARM_SP_IMAGE_BASE,
+ .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE,
+ .sp_heap_base = ARM_SP_IMAGE_HEAP_BASE,
+ .sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE,
+ .sp_shared_buf_base = PLAT_SPM_BUF_BASE,
+ .sp_image_size = ARM_SP_IMAGE_SIZE,
+ .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
+ .sp_heap_size = ARM_SP_IMAGE_HEAP_SIZE,
+ .sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE,
+ .sp_shared_buf_size = PLAT_SPM_BUF_SIZE,
+ .num_sp_mem_regions = ARM_SP_IMAGE_NUM_MEM_REGIONS,
+ .num_cpus = PLATFORM_CORE_COUNT,
+ .mp_info = &sp_mp_info[0],
+};
+
+const struct mmap_region *plat_get_secure_partition_mmap(void *cookie)
+{
+ return plat_arm_secure_partition_mmap;
+}
+
+const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
+ void *cookie)
+{
+ return &plat_arm_secure_partition_boot_info;
+}
+#endif /* SPM_MM && defined(IMAGE_BL31) */
+
+#if TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ assert(heap_addr != NULL);
+ assert(heap_size != NULL);
+
+ return arm_get_mbedtls_heap(heap_addr, heap_size);
+}
+#endif
+
+void plat_arm_secure_wdt_start(void)
+{
+ sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+ sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+}
diff --git a/plat/arm/board/tc0/tc0_security.c b/plat/arm/board/tc0/tc0_security.c
new file mode 100644
index 000000000..f54376203
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_security.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+static const arm_tzc_regions_info_t tzc_regions[] = {
+ TC0_TZC_REGIONS_DEF,
+ {}
+};
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+ unsigned int i;
+
+ for (i = 0U; i < TZC400_COUNT; i++) {
+ arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
+ }
+}
diff --git a/plat/arm/board/tc0/tc0_topology.c b/plat/arm/board/tc0/tc0_topology.c
new file mode 100644
index 000000000..8cfc3b50e
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_topology.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+/******************************************************************************
+ * The power domain tree descriptor.
+ ******************************************************************************/
+const unsigned char tc0_pd_tree_desc[] = {
+ PLAT_ARM_CLUSTER_COUNT,
+ PLAT_MAX_CPUS_PER_CLUSTER,
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return tc0_pd_tree_desc;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+ (SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+};
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+ return PLAT_MAX_CPUS_PER_CLUSTER;
+}
+
+#if ARM_PLAT_MT
+/******************************************************************************
+ * Return the number of PE's supported by the CPU.
+ *****************************************************************************/
+unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr)
+{
+ return PLAT_MAX_PE_PER_CPU;
+}
+#endif
diff --git a/plat/arm/board/tc0/tc0_trusted_boot.c b/plat/arm/board/tc0/tc0_trusted_boot.c
new file mode 100644
index 000000000..614f7e2ad
--- /dev/null
+++ b/plat/arm/board/tc0/tc0_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
diff --git a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
index 7aeeb2aed..78360b06c 100644
--- a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
+++ b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,7 +8,6 @@
#include <common/bl_common.h>
#include <common/desc_image_load.h>
-#include <plat/common/platform.h>
/*******************************************************************************
* Following descriptor provides BL image/ep information that gets used
diff --git a/plat/arm/common/aarch32/arm_helpers.S b/plat/arm/common/aarch32/arm_helpers.S
index badddd3a9..1da2d4cad 100644
--- a/plat/arm/common/aarch32/arm_helpers.S
+++ b/plat/arm/common/aarch32/arm_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -64,10 +64,10 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush()
+ * void plat_crash_console_flush()
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : r0
* ---------------------------------------------
*/
diff --git a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
index 0514b3994..6a8943d5d 100644
--- a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
+++ b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,7 +8,6 @@
#include <common/bl_common.h>
#include <common/desc_image_load.h>
-#include <plat/common/platform.h>
/*******************************************************************************
* Following descriptor provides BL image/ep information that gets used
diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c
deleted file mode 100644
index 69ebd798f..000000000
--- a/plat/arm/common/aarch64/arm_ehf.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <bl31/ehf.h>
-
-/*
- * Enumeration of priority levels on ARM platforms.
- */
-ehf_pri_desc_t arm_exceptions[] = {
-#if RAS_EXTENSION
- /* RAS Priority */
- EHF_PRI_DESC(ARM_PRI_BITS, PLAT_RAS_PRI),
-#endif
-
-#if SDEI_SUPPORT
- /* Critical priority SDEI */
- EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_CRITICAL_PRI),
-
- /* Normal priority SDEI */
- EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
-#endif
-#if SPM_MM
- EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SP_PRI),
-#endif
-};
-
-/* Plug in ARM exceptions to Exception Handling Framework. */
-EHF_REGISTER_PRIORITIES(arm_exceptions, ARRAY_SIZE(arm_exceptions), ARM_PRI_BITS);
diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S
index 06720589a..b47078173 100644
--- a/plat/arm/common/aarch64/arm_helpers.S
+++ b/plat/arm/common/aarch64/arm_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -66,10 +66,10 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush()
+ * void plat_crash_console_flush()
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : r0
* ---------------------------------------------
*/
diff --git a/plat/arm/common/aarch64/arm_sdei.c b/plat/arm/common/aarch64/arm_sdei.c
index 493134b6a..3c74a465c 100644
--- a/plat/arm/common/aarch64/arm_sdei.c
+++ b/plat/arm/common/aarch64/arm_sdei.c
@@ -1,16 +1,51 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* SDEI configuration for ARM platforms */
-#include <platform_def.h>
-
#include <bl31/ehf.h>
+#include <common/debug.h>
#include <services/sdei.h>
+#if SDEI_IN_FCONF
+#include <plat/arm/common/fconf_sdei_getter.h>
+#endif
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+
+#if SDEI_IN_FCONF
+/* Private event mappings */
+static sdei_ev_map_t arm_sdei_private[PLAT_SDEI_DP_EVENT_MAX_CNT + 1] = { 0 };
+
+/* Shared event mappings */
+static sdei_ev_map_t arm_sdei_shared[PLAT_SDEI_DS_EVENT_MAX_CNT] = { 0 };
+
+void plat_sdei_setup(void)
+{
+ uint32_t i;
+
+ arm_sdei_private[0] = (sdei_ev_map_t)SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI);
+
+ for (i = 0; i < FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_cnt); i++) {
+ arm_sdei_private[i + 1] = (sdei_ev_map_t)SDEI_PRIVATE_EVENT(
+ FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_nums[i]),
+ FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_intrs[i]),
+ FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_flags[i]));
+ }
+
+ for (i = 0; i < FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_cnt); i++) {
+ arm_sdei_shared[i] = (sdei_ev_map_t)SDEI_SHARED_EVENT( \
+ FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_nums[i]),
+ FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_intrs[i]),
+ FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_flags[i]));
+ }
+ INFO("FCONF: SDEI platform setup\n");
+}
+#else
/* Private event mappings */
static sdei_ev_map_t arm_sdei_private[] = {
PLAT_ARM_PRIVATE_SDEI_EVENTS
@@ -21,5 +56,11 @@ static sdei_ev_map_t arm_sdei_shared[] = {
PLAT_ARM_SHARED_SDEI_EVENTS
};
+void plat_sdei_setup(void)
+{
+ INFO("SDEI platform setup\n");
+}
+#endif /* SDEI_IN_FCONF */
+
/* Export ARM SDEI events */
REGISTER_SDEI_MAP(arm_sdei_private, arm_sdei_shared);
diff --git a/plat/arm/common/aarch64/execution_state_switch.c b/plat/arm/common/aarch64/execution_state_switch.c
index 8835fa135..bed929a9c 100644
--- a/plat/arm/common/aarch64/execution_state_switch.c
+++ b/plat/arm/common/aarch64/execution_state_switch.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,7 +12,6 @@
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/psci/psci.h>
#include <lib/utils.h>
-#include <plat/arm/common/arm_sip_svc.h>
#include <plat/arm/common/plat_arm.h>
#include <smccc_helpers.h>
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index b19a7c39c..4b2a062f9 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,8 @@
#include <arch.h>
#include <bl1/bl1.h>
#include <common/bl_common.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/arm/common/plat_arm.h>
@@ -52,6 +54,9 @@
/* Data structure which holds the extents of the trusted SRAM for BL1*/
static meminfo_t bl1_tzram_layout;
+/* Boolean variable to hold condition whether firmware update needed or not */
+static bool is_fwu_needed;
+
struct meminfo *bl1_plat_sec_mem_layout(void)
{
return &bl1_tzram_layout;
@@ -141,9 +146,59 @@ void bl1_plat_arch_setup(void)
*/
void arm_bl1_platform_setup(void)
{
+ const struct dyn_cfg_dtb_info_t *fw_config_info;
+ image_desc_t *desc;
+ uint32_t fw_config_max_size;
+ int err = -1;
+
/* Initialise the IO layer and register platform IO devices */
plat_arm_io_setup();
- arm_load_tb_fw_config();
+
+ /* Check if we need FWU before further processing */
+ is_fwu_needed = plat_arm_bl1_fwu_needed();
+ if (is_fwu_needed) {
+ ERROR("Skip platform setup as FWU detected\n");
+ return;
+ }
+
+ /* Set global DTB info for fixed fw_config information */
+ fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
+ set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID);
+
+ /* Fill the device tree information struct with the info from the config dtb */
+ err = fconf_load_config(FW_CONFIG_ID);
+ if (err < 0) {
+ ERROR("Loading of FW_CONFIG failed %d\n", err);
+ plat_error_handler(err);
+ }
+
+ /*
+ * FW_CONFIG loaded successfully. If FW_CONFIG device tree parsing
+ * is successful then load TB_FW_CONFIG device tree.
+ */
+ fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
+ if (fw_config_info != NULL) {
+ err = fconf_populate_dtb_registry(fw_config_info->config_addr);
+ if (err < 0) {
+ ERROR("Parsing of FW_CONFIG failed %d\n", err);
+ plat_error_handler(err);
+ }
+ /* load TB_FW_CONFIG */
+ err = fconf_load_config(TB_FW_CONFIG_ID);
+ if (err < 0) {
+ ERROR("Loading of TB_FW_CONFIG failed %d\n", err);
+ plat_error_handler(err);
+ }
+ } else {
+ ERROR("Invalid FW_CONFIG address\n");
+ plat_error_handler(err);
+ }
+
+ /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */
+ desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
+ assert(desc != NULL);
+ desc->ep_info.args.arg0 = fw_config_info->config_addr;
+
#if TRUSTED_BOARD_BOOT
/* Share the Mbed TLS heap info with other images */
arm_bl1_set_mbedtls_heap();
@@ -184,9 +239,9 @@ void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
* On Arm platforms, the FWU process is triggered when the FIP image has
* been tampered with.
*/
-int plat_arm_bl1_fwu_needed(void)
+bool plat_arm_bl1_fwu_needed(void)
{
- return (arm_io_is_toc_valid() != 1);
+ return !arm_io_is_toc_valid();
}
/*******************************************************************************
@@ -195,8 +250,5 @@ int plat_arm_bl1_fwu_needed(void)
******************************************************************************/
unsigned int bl1_plat_get_next_image_id(void)
{
- if (plat_arm_bl1_fwu_needed() != 0)
- return NS_BL1U_IMAGE_ID;
-
- return BL2_IMAGE_ID;
+ return is_fwu_needed ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID;
}
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index cdf87ca55..c90e93cd8 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,6 +14,8 @@
#include <common/debug.h>
#include <common/desc_image_load.h>
#include <drivers/generic_delay_timer.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
#ifdef SPD_opteed
#include <lib/optee_utils.h>
#endif
@@ -24,17 +26,23 @@
/* Data structure which holds the extents of the trusted SRAM for BL2 */
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
+/* Base address of fw_config received from BL1 */
+static uintptr_t config_base;
+
/*
- * Check that BL2_BASE is above ARM_TB_FW_CONFIG_LIMIT. This reserved page is
+ * Check that BL2_BASE is above ARM_FW_CONFIG_LIMIT. This reserved page is
* for `meminfo_t` data structure and fw_configs passed from BL1.
*/
-CASSERT(BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl2_base_overflows);
+CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows);
/* Weak definitions may be overridden in specific ARM standard platform */
#pragma weak bl2_early_platform_setup2
#pragma weak bl2_platform_setup
#pragma weak bl2_plat_arch_setup
#pragma weak bl2_plat_sec_mem_layout
+#if MEASURED_BOOT
+#pragma weak bl2_plat_get_hash
+#endif
#define MAP_BL2_TOTAL MAP_REGION_FLAT( \
bl2_tzram_layout.total_base, \
@@ -49,7 +57,7 @@ CASSERT(BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl2_base_overflows);
* in x0. This memory layout is sitting at the base of the free trusted SRAM.
* Copy it to a safe location before its reclaimed by later BL2 functionality.
******************************************************************************/
-void arm_bl2_early_platform_setup(uintptr_t tb_fw_config,
+void arm_bl2_early_platform_setup(uintptr_t fw_config,
struct meminfo *mem_layout)
{
/* Initialize the console to provide early debug support */
@@ -58,11 +66,10 @@ void arm_bl2_early_platform_setup(uintptr_t tb_fw_config,
/* Setup the BL2 memory layout */
bl2_tzram_layout = *mem_layout;
+ config_base = fw_config;
+
/* Initialise the IO layer and register platform IO devices */
plat_arm_io_setup();
-
- if (tb_fw_config != 0U)
- arm_bl2_set_tb_cfg_addr((void *)tb_fw_config);
}
void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
@@ -123,6 +130,7 @@ void arm_bl2_plat_arch_setup(void)
#if ARM_CRYPTOCELL_INTEG
ARM_MAP_BL_COHERENT_RAM,
#endif
+ ARM_MAP_BL_CONFIG_REGION,
{0}
};
@@ -139,7 +147,18 @@ void arm_bl2_plat_arch_setup(void)
void bl2_plat_arch_setup(void)
{
+ const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
+
arm_bl2_plat_arch_setup();
+
+ /* Fill the properties struct with the info from the config dtb */
+ fconf_populate("FW_CONFIG", config_base);
+
+ /* TB_FW_CONFIG was also loaded by BL1 */
+ tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
+ assert(tb_fw_config_info != NULL);
+
+ fconf_populate("TB_FW", tb_fw_config_info->config_addr);
}
int arm_bl2_handle_post_image_load(unsigned int image_id)
@@ -150,7 +169,7 @@ int arm_bl2_handle_post_image_load(unsigned int image_id)
bl_mem_params_node_t *pager_mem_params = NULL;
bl_mem_params_node_t *paged_mem_params = NULL;
#endif
- assert(bl_mem_params);
+ assert(bl_mem_params != NULL);
switch (image_id) {
#ifdef __aarch64__
@@ -202,6 +221,13 @@ int arm_bl2_handle_post_image_load(unsigned int image_id)
******************************************************************************/
int arm_bl2_plat_handle_post_image_load(unsigned int image_id)
{
+#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+ /* For Secure Partitions we don't need post processing */
+ if ((image_id >= (MAX_NUMBER_IDS - MAX_SP_IDS)) &&
+ (image_id < MAX_NUMBER_IDS)) {
+ return 0;
+ }
+#endif
return arm_bl2_handle_post_image_load(image_id);
}
@@ -209,3 +235,11 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
{
return arm_bl2_plat_handle_post_image_load(image_id);
}
+
+#if MEASURED_BOOT
+/* Read TCG_DIGEST_SIZE bytes of BL2 hash data */
+void bl2_plat_get_hash(void *data)
+{
+ arm_bl2_get_hash(data);
+}
+#endif
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 939885f98..81ef6e7b2 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,7 +14,6 @@
#include <lib/debugfs.h>
#include <lib/extensions/ras.h>
#include <lib/mmio.h>
-#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
@@ -29,10 +28,10 @@ static entry_point_info_t bl33_image_ep_info;
#if !RESET_TO_BL31
/*
- * Check that BL31_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page
+ * Check that BL31_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page
* is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2.
*/
-CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
+CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
#endif
/* Weak definitions may be overridden in specific ARM standard platform */
@@ -47,7 +46,13 @@ CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
MT_MEMORY | MT_RW | MT_SECURE)
#if RECLAIM_INIT_CODE
IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
-IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END);
+IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED);
+IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED);
+
+#define BL_INIT_CODE_END ((BL_CODE_END_UNALIGNED + PAGE_SIZE - 1) & \
+ ~(PAGE_SIZE - 1))
+#define BL_STACKS_END ((BL_STACKS_END_UNALIGNED + PAGE_SIZE - 1) & \
+ ~(PAGE_SIZE - 1))
#define MAP_BL_INIT_CODE MAP_REGION_FLAT( \
BL_INIT_CODE_BASE, \
@@ -56,6 +61,14 @@ IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END);
MT_CODE | MT_SECURE)
#endif
+#if SEPARATE_NOBITS_REGION
+#define MAP_BL31_NOBITS MAP_REGION_FLAT( \
+ BL31_NOBITS_BASE, \
+ BL31_NOBITS_LIMIT \
+ - BL31_NOBITS_BASE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+#endif
/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for the
* security state specified. BL33 corresponds to the non-secure image type
@@ -107,6 +120,18 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi
SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
bl32_image_ep_info.pc = BL32_BASE;
bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
+
+#if defined(SPD_spmd)
+ /* SPM (hafnium in secure world) expects SPM Core manifest base address
+ * in x0, which in !RESET_TO_BL31 case loaded after base of non shared
+ * SRAM(after 4KB offset of SRAM). But in RESET_TO_BL31 case all non
+ * shared SRAM is allocated to BL31, so to avoid overwriting of manifest
+ * keep it in the last page.
+ */
+ bl32_image_ep_info.args.arg0 = ARM_TRUSTED_SRAM_BASE +
+ PLAT_ARM_TRUSTED_SRAM_SIZE - PAGE_SIZE;
+#endif
+
# endif /* BL32_BASE */
/* Populate entry point information for BL33 */
@@ -123,6 +148,14 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi
bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+#if defined(SPD_spmd) && !(ARM_LINUX_KERNEL_AS_BL33)
+ /*
+ * Hafnium in normal world expects its manifest address in x0, which
+ * is loaded at base of DRAM.
+ */
+ bl33_image_ep_info.args.arg0 = (u_register_t)ARM_DRAM1_BASE;
+#endif
+
# if ARM_LINUX_KERNEL_AS_BL33
/*
* According to the file ``Documentation/arm64/booting.txt`` of the
@@ -249,21 +282,51 @@ void arm_bl31_plat_runtime_setup(void)
/* Initialize the runtime console */
arm_console_runtime_init();
+
#if RECLAIM_INIT_CODE
arm_free_init_memory();
#endif
+
+#if PLAT_RO_XLAT_TABLES
+ arm_xlat_make_tables_readonly();
+#endif
}
#if RECLAIM_INIT_CODE
/*
- * Zero out and make RW memory used to store image boot time code so it can
- * be reclaimed during runtime
+ * Make memory for image boot time code RW to reclaim it as stack for the
+ * secondary cores, or RO where it cannot be reclaimed:
+ *
+ * |-------- INIT SECTION --------|
+ * -----------------------------------------
+ * | CORE 0 | CORE 1 | CORE 2 | EXTRA |
+ * | STACK | STACK | STACK | SPACE |
+ * -----------------------------------------
+ * <-------------------> <------>
+ * MAKE RW AND XN MAKE
+ * FOR STACKS RO AND XN
*/
void arm_free_init_memory(void)
{
- int ret = xlat_change_mem_attributes(BL_INIT_CODE_BASE,
+ int ret = 0;
+
+ if (BL_STACKS_END < BL_INIT_CODE_END) {
+ /* Reclaim some of the init section as stack if possible. */
+ if (BL_INIT_CODE_BASE < BL_STACKS_END) {
+ ret |= xlat_change_mem_attributes(BL_INIT_CODE_BASE,
+ BL_STACKS_END - BL_INIT_CODE_BASE,
+ MT_RW_DATA);
+ }
+ /* Make the rest of the init section read-only. */
+ ret |= xlat_change_mem_attributes(BL_STACKS_END,
+ BL_INIT_CODE_END - BL_STACKS_END,
+ MT_RO_DATA);
+ } else {
+ /* The stacks cover the init section, so reclaim it all. */
+ ret |= xlat_change_mem_attributes(BL_INIT_CODE_BASE,
BL_INIT_CODE_END - BL_INIT_CODE_BASE,
MT_RW_DATA);
+ }
if (ret != 0) {
ERROR("Could not reclaim initialization code");
@@ -295,6 +358,9 @@ void __init arm_bl31_plat_arch_setup(void)
#if RECLAIM_INIT_CODE
MAP_BL_INIT_CODE,
#endif
+#if SEPARATE_NOBITS_REGION
+ MAP_BL31_NOBITS,
+#endif
ARM_MAP_BL_RO,
#if USE_ROMLIB
ARM_MAP_ROMLIB_CODE,
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 255e6b421..7d9fd6c72 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -13,10 +13,11 @@
#include <common/debug.h>
#include <common/romlib.h>
#include <lib/mmio.h>
+#include <lib/smccc.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <services/arm_arch_svc.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <services/spm_mm_partition.h>
/* Weak definitions may be overridden in specific ARM standard platform */
#pragma weak plat_get_ns_image_entrypoint
@@ -26,6 +27,29 @@
* conflicts with the definition in plat/common. */
#pragma weak plat_get_syscnt_freq2
+/* Get ARM SOC-ID */
+#pragma weak plat_arm_get_soc_id
+
+/*******************************************************************************
+ * Changes the memory attributes for the region of mapped memory where the BL
+ * image's translation tables are located such that the tables will have
+ * read-only permissions.
+ ******************************************************************************/
+#if PLAT_RO_XLAT_TABLES
+void arm_xlat_make_tables_readonly(void)
+{
+ int rc = xlat_make_tables_readonly();
+
+ if (rc != 0) {
+ ERROR("Failed to make translation tables read-only at EL%u.\n",
+ get_current_el());
+ panic();
+ }
+
+ INFO("Translation tables are now read-only at EL%u.\n",
+ get_current_el());
+}
+#endif
void arm_setup_romlib(void)
{
@@ -73,7 +97,7 @@ uint32_t arm_get_spsr_for_bl33_entry(void)
* the FIP ToC and allowing the platform to have a say as
* well.
*/
- spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
return spsr;
}
#else
@@ -192,7 +216,7 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
* Translate entry point to Physical Address using the EL1&0
* translation regime, including stage 2.
*/
- ats12e1r(ep);
+ AT(ats12e1r, ep);
}
isb();
par = read_par_el1();
@@ -212,3 +236,4 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
return arm_validate_ns_entrypoint(pa);
}
#endif
+
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index c8b7ab448..74afc53eb 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -121,10 +121,33 @@ endif
ENABLE_PSCI_STAT := 1
ENABLE_PMF := 1
+# Override the standard libc with optimised libc_asm
+OVERRIDE_LIBC := 1
+ifeq (${OVERRIDE_LIBC},1)
+ include lib/libc/libc_asm.mk
+endif
+
# On ARM platforms, separate the code and read-only data sections to allow
# mapping the former as executable and the latter as execute-never.
SEPARATE_CODE_AND_RODATA := 1
+# On ARM platforms, disable SEPARATE_NOBITS_REGION by default. Both PROGBITS
+# and NOBITS sections of BL31 image are adjacent to each other and loaded
+# into Trusted SRAM.
+SEPARATE_NOBITS_REGION := 0
+
+# In order to support SEPARATE_NOBITS_REGION for Arm platforms, we need to load
+# BL31 PROGBITS into secure DRAM space and BL31 NOBITS into SRAM. Hence mandate
+# the build to require that ARM_BL31_IN_DRAM is enabled as well.
+ifeq ($(SEPARATE_NOBITS_REGION),1)
+ ifneq ($(ARM_BL31_IN_DRAM),1)
+ $(error For SEPARATE_NOBITS_REGION, ARM_BL31_IN_DRAM must be enabled)
+ endif
+ ifneq ($(RECLAIM_INIT_CODE),0)
+ $(error For SEPARATE_NOBITS_REGION, RECLAIM_INIT_CODE cannot be supported)
+ endif
+endif
+
# Disable ARM Cryptocell by default
ARM_CRYPTOCELL_INTEG := 0
$(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG))
@@ -160,12 +183,21 @@ include lib/xlat_tables_v2/xlat_tables.mk
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
endif
+ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c \
+ plat/arm/common/fconf/arm_fconf_io.c
+ifeq (${SPD},spmd)
+ ifeq (${SPMD_SPM_AT_SEL2},1)
+ ARM_IO_SOURCES += plat/arm/common/fconf/arm_fconf_sp.c
+ endif
+endif
+
BL1_SOURCES += drivers/io/io_fip.c \
drivers/io/io_memmap.c \
drivers/io/io_storage.c \
plat/arm/common/arm_bl1_setup.c \
plat/arm/common/arm_err.c \
- plat/arm/common/arm_io_storage.c
+ ${ARM_IO_SOURCES}
+
ifdef EL3_PAYLOAD_BASE
# Need the plat_arm_program_trusted_mailbox() function to release secondary CPUs from
# their holding pen
@@ -179,7 +211,10 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \
drivers/io/io_storage.c \
plat/arm/common/arm_bl2_setup.c \
plat/arm/common/arm_err.c \
- plat/arm/common/arm_io_storage.c
+ ${ARM_IO_SOURCES}
+
+# Firmware Configuration Framework sources
+include lib/fconf/fconf.mk
# Add `libfdt` and Arm common helpers required for Dynamic Config
include lib/libfdt/libfdt.mk
@@ -229,11 +264,14 @@ endif
endif
ifeq (${EL3_EXCEPTION_HANDLING},1)
-BL31_SOURCES += plat/arm/common/aarch64/arm_ehf.c
+BL31_SOURCES += plat/common/aarch64/plat_ehf.c
endif
ifeq (${SDEI_SUPPORT},1)
BL31_SOURCES += plat/arm/common/aarch64/arm_sdei.c
+ifeq (${SDEI_IN_FCONF},1)
+BL31_SOURCES += plat/arm/common/fconf/fconf_sdei_getter.c
+endif
endif
# RAS sources
@@ -248,16 +286,33 @@ PLAT_BL_COMMON_SOURCES += plat/arm/common/aarch64/arm_pauth.c \
lib/extensions/pauth/pauth_helpers.S
endif
+ifeq (${SPD},spmd)
+BL31_SOURCES += plat/common/plat_spmd_manifest.c \
+ common/fdt_wrappers.c \
+ ${LIBFDT_SRCS}
+
+endif
+
ifneq (${TRUSTED_BOARD_BOOT},0)
# Include common TBB sources
AUTH_SOURCES := drivers/auth/auth_mod.c \
drivers/auth/crypto_mod.c \
drivers/auth/img_parser_mod.c \
+ lib/fconf/fconf_tbbr_getter.c
# Include the selected chain of trust sources.
ifeq (${COT},tbbr)
- AUTH_SOURCES += drivers/auth/tbbr/tbbr_cot.c
+ BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \
+ drivers/auth/tbbr/tbbr_cot_bl1.c
+ ifneq (${COT_DESC_IN_DTB},0)
+ BL2_SOURCES += lib/fconf/fconf_cot_getter.c
+ else
+ BL2_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \
+ drivers/auth/tbbr/tbbr_cot_bl2.c
+ endif
+ else ifeq (${COT},dualroot)
+ AUTH_SOURCES += drivers/auth/dualroot/cot.c
else
$(error Unknown chain of trust ${COT})
endif
@@ -293,3 +348,9 @@ ifeq (${RECLAIM_INIT_CODE}, 1)
$(error "To reclaim init code xlat tables v2 must be used")
endif
endif
+
+ifeq (${MEASURED_BOOT},1)
+ MEASURED_BOOT_MK := drivers/measured_boot/measured_boot.mk
+ $(info Including ${MEASURED_BOOT_MK})
+ include ${MEASURED_BOOT_MK}
+endif
diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c
index 123811d71..af5f11e46 100644
--- a/plat/arm/common/arm_console.c
+++ b/plat/arm/common/arm_console.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,11 +13,14 @@
#include <drivers/console.h>
#include <plat/arm/common/plat_arm.h>
+#pragma weak arm_console_runtime_init
+#pragma weak arm_console_runtime_end
+
/*******************************************************************************
* Functions that set up the console
******************************************************************************/
-static console_pl011_t arm_boot_console;
-static console_pl011_t arm_runtime_console;
+static console_t arm_boot_console;
+static console_t arm_runtime_console;
/* Initialize the console to provide early debug support */
void __init arm_console_boot_init(void)
@@ -35,13 +38,13 @@ void __init arm_console_boot_init(void)
panic();
}
- console_set_scope(&arm_boot_console.console, CONSOLE_FLAG_BOOT);
+ console_set_scope(&arm_boot_console, CONSOLE_FLAG_BOOT);
}
void arm_console_boot_end(void)
{
- (void)console_flush();
- (void)console_unregister(&arm_boot_console.console);
+ console_flush();
+ (void)console_unregister(&arm_boot_console);
}
/* Initialize the runtime console */
@@ -54,10 +57,10 @@ void arm_console_runtime_init(void)
if (rc == 0)
panic();
- console_set_scope(&arm_runtime_console.console, CONSOLE_FLAG_RUNTIME);
+ console_set_scope(&arm_runtime_console, CONSOLE_FLAG_RUNTIME);
}
void arm_console_runtime_end(void)
{
- (void)console_flush();
+ console_flush();
}
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index e6c5a7361..6b3a61180 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,13 +15,17 @@
#include <common/tbbr/tbbr_img_def.h>
#if TRUSTED_BOARD_BOOT
#include <drivers/auth/mbedtls/mbedtls_config.h>
+#if MEASURED_BOOT
+#include <drivers/auth/crypto_mod.h>
+#include <mbedtls/md.h>
#endif
+#endif
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <lib/fconf/fconf_tbbr_getter.h>
+
#include <plat/arm/common/arm_dyn_cfg_helpers.h>
#include <plat/arm/common/plat_arm.h>
-#include <plat/common/platform.h>
-
-/* Variable to store the address to TB_FW_CONFIG passed from BL1 */
-static void *tb_fw_cfg_dtb;
#if TRUSTED_BOARD_BOOT
@@ -57,20 +61,10 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
#elif defined(IMAGE_BL2)
- int err;
-
/* If in BL2, retrieve the already allocated heap's info from DTB */
- if (tb_fw_cfg_dtb != NULL) {
- err = arm_get_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, heap_addr,
- heap_size);
- if (err < 0) {
- ERROR("BL2: unable to retrieve shared Mbed TLS heap information from DTB\n");
- panic();
- }
- } else {
- ERROR("BL2: DTB missing, cannot get Mbed TLS heap\n");
- panic();
- }
+ *heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr);
+ *heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size);
+
#endif
return 0;
@@ -83,6 +77,8 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
void arm_bl1_set_mbedtls_heap(void)
{
int err;
+ uintptr_t tb_fw_cfg_dtb;
+ const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
/*
* If tb_fw_cfg_dtb==NULL then DTB is not present for the current
@@ -96,141 +92,150 @@ void arm_bl1_set_mbedtls_heap(void)
* information, we would need to call plat_get_mbedtls_heap to retrieve
* the default heap's address and size.
*/
- if ((tb_fw_cfg_dtb != NULL) && (mbedtls_heap_addr != NULL)) {
- err = arm_set_dtb_mbedtls_heap_info(tb_fw_cfg_dtb,
+
+ tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
+ assert(tb_fw_config_info != NULL);
+
+ tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
+
+ if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) {
+ /* As libfdt uses void *, we can't avoid this cast */
+ void *dtb = (void *)tb_fw_cfg_dtb;
+
+ err = arm_set_dtb_mbedtls_heap_info(dtb,
mbedtls_heap_addr, mbedtls_heap_size);
if (err < 0) {
- ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n");
+ ERROR("%swrite shared Mbed TLS heap information%s",
+ "BL1: unable to ", " to DTB\n");
panic();
}
+#if !MEASURED_BOOT
/*
* Ensure that the info written to the DTB is visible to other
* images. It's critical because BL2 won't be able to proceed
* without the heap info.
+ *
+ * In MEASURED_BOOT case flushing is done in
+ * arm_bl1_set_bl2_hash() function which is called after heap
+ * information is written in the DTB.
*/
- flush_dcache_range((uintptr_t)tb_fw_cfg_dtb,
- fdt_totalsize(tb_fw_cfg_dtb));
+ flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb));
+#endif /* !MEASURED_BOOT */
}
}
-#endif /* TRUSTED_BOARD_BOOT */
-
+#if MEASURED_BOOT
/*
- * Helper function to load TB_FW_CONFIG and populate the load information to
- * arg0 of BL2 entrypoint info.
+ * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB.
+ * Executed only from BL1.
*/
-void arm_load_tb_fw_config(void)
+void arm_bl1_set_bl2_hash(const image_desc_t *image_desc)
{
+ unsigned char hash_data[MBEDTLS_MD_MAX_SIZE];
+ const image_info_t image_info = image_desc->image_info;
+ uintptr_t tb_fw_cfg_dtb;
int err;
- uintptr_t config_base = 0UL;
- image_desc_t *desc;
-
- image_desc_t arm_tb_fw_info = {
- .image_id = TB_FW_CONFIG_ID,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = ARM_TB_FW_CONFIG_BASE,
- .image_info.image_max_size =
- ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE
- };
+ const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
- VERBOSE("BL1: Loading TB_FW_CONFIG\n");
- err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info.image_info);
- if (err != 0) {
- /* Return if TB_FW_CONFIG is not loaded */
- VERBOSE("Failed to load TB_FW_CONFIG\n");
- return;
- }
-
- /* At this point we know that a DTB is indeed available */
- config_base = arm_tb_fw_info.image_info.image_base;
- tb_fw_cfg_dtb = (void *)config_base;
+ tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
+ assert(tb_fw_config_info != NULL);
- /* The BL2 ep_info arg0 is modified to point to TB_FW_CONFIG */
- desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
- assert(desc != NULL);
- desc->ep_info.args.arg0 = config_base;
+ tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
- INFO("BL1: TB_FW_CONFIG loaded at address = 0x%lx\n", config_base);
+ /*
+ * If tb_fw_cfg_dtb==NULL then DTB is not present for the current
+ * platform. As such, we cannot write to the DTB at all and pass
+ * measured data.
+ */
+ if (tb_fw_cfg_dtb == 0UL) {
+ panic();
+ }
-#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH)
- int tb_fw_node;
- uint32_t disable_auth = 0;
+ /* Calculate hash */
+ err = crypto_mod_calc_hash(MBEDTLS_MD_ID,
+ (void *)image_info.image_base,
+ image_info.image_size, hash_data);
+ if (err != 0) {
+ ERROR("%scalculate%s\n", "BL1: unable to ",
+ " BL2 hash");
+ panic();
+ }
- err = arm_dyn_tb_fw_cfg_init((void *)config_base, &tb_fw_node);
+ err = arm_set_bl2_hash_info((void *)tb_fw_cfg_dtb, hash_data);
if (err < 0) {
- ERROR("Invalid TB_FW_CONFIG loaded\n");
+ ERROR("%swrite%sdata%s\n", "BL1: unable to ",
+ " BL2 hash ", "to DTB\n");
panic();
}
- err = arm_dyn_get_disable_auth((void *)config_base, tb_fw_node, &disable_auth);
- if (err < 0)
- return;
-
- if (disable_auth == 1)
- dyn_disable_auth();
-#endif
+ /*
+ * Ensure that the info written to the DTB is visible to other
+ * images. It's critical because BL2 won't be able to proceed
+ * without the heap info and its hash data.
+ */
+ flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize((void *)tb_fw_cfg_dtb));
}
/*
- * BL2 utility function to set the address of TB_FW_CONFIG passed from BL1.
+ * Reads TCG_DIGEST_SIZE bytes of BL2 hash data from the DTB.
+ * Executed only from BL2.
*/
-void arm_bl2_set_tb_cfg_addr(void *dtb)
+void arm_bl2_get_hash(void *data)
{
- assert(dtb != NULL);
- tb_fw_cfg_dtb = dtb;
+ const void *bl2_hash;
+
+ assert(data != NULL);
+
+ /* Retrieve TCG_DIGEST_SIZE bytes of BL2 hash data from the DTB */
+ bl2_hash = FCONF_GET_PROPERTY(tbbr, dyn_config, bl2_hash_data);
+ (void)memcpy(data, bl2_hash, TCG_DIGEST_SIZE);
}
+#endif /* MEASURED_BOOT */
+#endif /* TRUSTED_BOARD_BOOT */
/*
* BL2 utility function to initialize dynamic configuration specified by
- * TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if
- * specified in TB_FW_CONFIG.
+ * FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if
+ * specified in FW_CONFIG.
*/
void arm_bl2_dyn_cfg_init(void)
{
- int err = 0, tb_fw_node;
unsigned int i;
bl_mem_params_node_t *cfg_mem_params = NULL;
- uint64_t image_base;
+ uintptr_t image_base;
uint32_t image_size;
const unsigned int config_ids[] = {
HW_CONFIG_ID,
SOC_FW_CONFIG_ID,
NT_FW_CONFIG_ID,
-#ifdef SPD_tspd
- /* Currently tos_fw_config is only present for TSP */
+#if defined(SPD_tspd) || defined(SPD_spmd)
+ /* tos_fw_config is only present for TSPD/SPMD */
TOS_FW_CONFIG_ID
#endif
};
- if (tb_fw_cfg_dtb == NULL) {
- VERBOSE("No TB_FW_CONFIG specified\n");
- return;
- }
-
- err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node);
- if (err < 0) {
- ERROR("Invalid TB_FW_CONFIG passed from BL1\n");
- panic();
- }
+ const struct dyn_cfg_dtb_info_t *dtb_info;
/* Iterate through all the fw config IDs */
for (i = 0; i < ARRAY_SIZE(config_ids); i++) {
/* Get the config load address and size from TB_FW_CONFIG */
cfg_mem_params = get_bl_mem_params_node(config_ids[i]);
if (cfg_mem_params == NULL) {
- VERBOSE("Couldn't find HW_CONFIG in bl_mem_params_node\n");
+ VERBOSE("%sHW_CONFIG in bl_mem_params_node\n",
+ "Couldn't find ");
continue;
}
- err = arm_dyn_get_config_load_info(tb_fw_cfg_dtb, tb_fw_node,
- config_ids[i], &image_base, &image_size);
- if (err < 0) {
- VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n",
- config_ids[i]);
+ dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]);
+ if (dtb_info == NULL) {
+ VERBOSE("%sconfig_id %d load info in TB_FW_CONFIG\n",
+ "Couldn't find ", config_ids[i]);
continue;
}
+ image_base = dtb_info->config_addr;
+ image_size = dtb_info->config_max_size;
+
/*
* Do some runtime checks on the load addresses of soc_fw_config,
* tos_fw_config, nt_fw_config. This is not a comprehensive check
@@ -238,32 +243,34 @@ void arm_bl2_dyn_cfg_init(void)
*/
if (config_ids[i] != HW_CONFIG_ID) {
- if (check_uptr_overflow(image_base, image_size))
+ if (check_uptr_overflow(image_base, image_size)) {
continue;
-
+ }
#ifdef BL31_BASE
/* Ensure the configs don't overlap with BL31 */
if ((image_base >= BL31_BASE) &&
- (image_base <= BL31_LIMIT))
+ (image_base <= BL31_LIMIT)) {
continue;
+ }
#endif
/* Ensure the configs are loaded in a valid address */
- if (image_base < ARM_BL_RAM_BASE)
+ if (image_base < ARM_BL_RAM_BASE) {
continue;
+ }
#ifdef BL32_BASE
/*
* If BL32 is present, ensure that the configs don't
* overlap with it.
*/
if ((image_base >= BL32_BASE) &&
- (image_base <= BL32_LIMIT))
+ (image_base <= BL32_LIMIT)) {
continue;
+ }
#endif
}
-
- cfg_mem_params->image_info.image_base = (uintptr_t)image_base;
- cfg_mem_params->image_info.image_max_size = image_size;
+ cfg_mem_params->image_info.image_base = image_base;
+ cfg_mem_params->image_info.image_max_size = (uint32_t)image_size;
/*
* Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from
@@ -271,16 +278,4 @@ void arm_bl2_dyn_cfg_init(void)
*/
cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
}
-
-#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH)
- uint32_t disable_auth = 0;
-
- err = arm_dyn_get_disable_auth(tb_fw_cfg_dtb, tb_fw_node,
- &disable_auth);
- if (err < 0)
- return;
-
- if (disable_auth == 1)
- dyn_disable_auth();
-#endif
}
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index 36d37f8f6..5f20c8d48 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -1,142 +1,38 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <libfdt.h>
-
+#if MEASURED_BOOT
#include <common/desc_image_load.h>
+#endif
#include <common/fdt_wrappers.h>
+
+#include <libfdt.h>
+
#include <plat/arm/common/arm_dyn_cfg_helpers.h>
#include <plat/arm/common/plat_arm.h>
#define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
#define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
-typedef struct config_load_info_prop {
- unsigned int config_id;
- const char *config_addr;
- const char *config_max_size;
-} config_load_info_prop_t;
-
-static const config_load_info_prop_t prop_names[] = {
- {HW_CONFIG_ID, "hw_config_addr", "hw_config_max_size"},
- {SOC_FW_CONFIG_ID, "soc_fw_config_addr", "soc_fw_config_max_size"},
- {TOS_FW_CONFIG_ID, "tos_fw_config_addr", "tos_fw_config_max_size"},
- {NT_FW_CONFIG_ID, "nt_fw_config_addr", "nt_fw_config_max_size"}
-};
-
-/*******************************************************************************
- * Helper to read the load information corresponding to the `config_id` in
- * TB_FW_CONFIG. This function expects the following properties to be defined :
- * <config>_addr size : 2 cells
- * <config>_max_size size : 1 cell
- *
- * Arguments:
- * void *dtb - pointer to the TB_FW_CONFIG in memory
- * int node - The node offset to appropriate node in the
- * DTB.
- * unsigned int config_id - The configuration id
- * uint64_t *config_addr - Returns the `config` load address if read
- * is successful.
- * uint32_t *config_size - Returns the `config` size if read is
- * successful.
- *
- * Returns 0 on success and -1 on error.
- ******************************************************************************/
-int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id,
- uint64_t *config_addr, uint32_t *config_size)
-{
- int err;
- unsigned int i;
-
- assert(dtb != NULL);
- assert(config_addr != NULL);
- assert(config_size != NULL);
-
- for (i = 0; i < ARRAY_SIZE(prop_names); i++) {
- if (prop_names[i].config_id == config_id)
- break;
- }
-
- if (i == ARRAY_SIZE(prop_names)) {
- WARN("Invalid config id %d\n", config_id);
- return -1;
- }
-
- /* Check if the pointer to DT is correct */
- assert(fdt_check_header(dtb) == 0);
-
- /* Assert the node offset point to "arm,tb_fw" compatible property */
- assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"));
-
- err = fdtw_read_cells(dtb, node, prop_names[i].config_addr, 2,
- (void *) config_addr);
- if (err < 0) {
- WARN("Read cell failed for %s\n", prop_names[i].config_addr);
- return -1;
- }
-
- err = fdtw_read_cells(dtb, node, prop_names[i].config_max_size, 1,
- (void *) config_size);
- if (err < 0) {
- WARN("Read cell failed for %s\n", prop_names[i].config_max_size);
- return -1;
- }
-
- VERBOSE("Dyn cfg: Read config_id %d load info from TB_FW_CONFIG 0x%llx 0x%x\n",
- config_id, (unsigned long long)*config_addr, *config_size);
-
- return 0;
-}
-
-/*******************************************************************************
- * Helper to read the `disable_auth` property in config DTB. This function
- * expects the following properties to be present in the config DTB.
- * name : disable_auth size : 1 cell
- *
- * Arguments:
- * void *dtb - pointer to the TB_FW_CONFIG in memory
- * int node - The node offset to appropriate node in the
- * DTB.
- * uint64_t *disable_auth - The value of `disable_auth` property on
- * successful read. Must be 0 or 1.
- *
- * Returns 0 on success and -1 on error.
- ******************************************************************************/
-int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth)
-{
- int err;
-
- assert(dtb != NULL);
- assert(disable_auth != NULL);
-
- /* Check if the pointer to DT is correct */
- assert(fdt_check_header(dtb) == 0);
-
- /* Assert the node offset point to "arm,tb_fw" compatible property */
- assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"));
-
- /* Locate the disable_auth cell and read the value */
- err = fdtw_read_cells(dtb, node, "disable_auth", 1, disable_auth);
- if (err < 0) {
- WARN("Read cell failed for `disable_auth`\n");
- return -1;
- }
+#if MEASURED_BOOT
+#define DTB_PROP_BL2_HASH_DATA "bl2_hash_data"
+#ifdef SPD_opteed
+/*
+ * Currently OP-TEE does not support reading DTBs from Secure memory
+ * and this property should be removed when this feature is supported.
+ */
+#define DTB_PROP_HW_SM_LOG_ADDR "tpm_event_log_sm_addr"
+#endif
+#define DTB_PROP_HW_LOG_ADDR "tpm_event_log_addr"
+#define DTB_PROP_HW_LOG_SIZE "tpm_event_log_size"
- /* Check if the value is boolean */
- if ((*disable_auth != 0U) && (*disable_auth != 1U)) {
- WARN("Invalid value for `disable_auth` cell %d\n", *disable_auth);
- return -1;
- }
-
- VERBOSE("Dyn cfg: `disable_auth` cell found with value = %d\n",
- *disable_auth);
- return 0;
-}
+static int dtb_root = -1;
+#endif /* MEASURED_BOOT */
/*******************************************************************************
* Validate the tb_fw_config is a valid DTB file and returns the node offset
@@ -154,62 +50,22 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
/* Check if the pointer to DT is correct */
if (fdt_check_header(dtb) != 0) {
- WARN("Invalid DTB file passed as TB_FW_CONFIG\n");
+ WARN("Invalid DTB file passed as%s\n", " TB_FW_CONFIG");
return -1;
}
/* Assert the node offset point to "arm,tb_fw" compatible property */
*node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw");
if (*node < 0) {
- WARN("The compatible property `arm,tb_fw` not found in the config\n");
- return -1;
- }
-
- VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n");
- return 0;
-}
-
-/*
- * Reads and returns the Mbed TLS shared heap information from the DTB.
- * This function is supposed to be called *only* when a DTB is present.
- * This function is supposed to be called only by BL2.
- *
- * Returns:
- * 0 = success
- * -1 = error. In this case the values of heap_addr, heap_size should be
- * considered as garbage by the caller.
- */
-int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr,
- size_t *heap_size)
-{
- int err, dtb_root;
-
- /* Verify the DTB is valid and get the root node */
- err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
- if (err < 0) {
- ERROR("Invalid TB_FW_CONFIG. Cannot retrieve Mbed TLS heap information from DTB\n");
+ WARN("The compatible property '%s' not%s", "arm,tb_fw",
+ " found in the config\n");
return -1;
}
- /* Retrieve the Mbed TLS heap details from the DTB */
- err = fdtw_read_cells(dtb, dtb_root,
- DTB_PROP_MBEDTLS_HEAP_ADDR, 2, heap_addr);
- if (err < 0) {
- ERROR("Error while reading %s from DTB\n",
- DTB_PROP_MBEDTLS_HEAP_ADDR);
- return -1;
- }
- err = fdtw_read_cells(dtb, dtb_root,
- DTB_PROP_MBEDTLS_HEAP_SIZE, 1, heap_size);
- if (err < 0) {
- ERROR("Error while reading %s from DTB\n",
- DTB_PROP_MBEDTLS_HEAP_SIZE);
- return -1;
- }
+ VERBOSE("Dyn cfg: '%s'%s", "arm,tb_fw", " found in the config\n");
return 0;
}
-
/*
* This function writes the Mbed TLS heap address and size in the DTB. When it
* is called, it is guaranteed that a DTB is available. However it is not
@@ -221,19 +77,21 @@ int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr,
*
* Returns:
* 0 = success
- * 1 = error
+ * -1 = error
*/
int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
{
- int err, dtb_root;
-
+#if !MEASURED_BOOT
+ int dtb_root;
+#endif
/*
* Verify that the DTB is valid, before attempting to write to it,
* and get the DTB root node.
*/
- err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
+ int err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
if (err < 0) {
- ERROR("Invalid TB_FW_CONFIG loaded. Unable to get root node\n");
+ ERROR("Invalid%s loaded. Unable to get root node\n",
+ " TB_FW_CONFIG");
return -1;
}
@@ -247,18 +105,199 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
err = fdtw_write_inplace_cells(dtb, dtb_root,
DTB_PROP_MBEDTLS_HEAP_ADDR, 2, &heap_addr);
if (err < 0) {
- ERROR("Unable to write DTB property %s\n",
- DTB_PROP_MBEDTLS_HEAP_ADDR);
+ ERROR("%sDTB property '%s'\n",
+ "Unable to write ", DTB_PROP_MBEDTLS_HEAP_ADDR);
return -1;
}
err = fdtw_write_inplace_cells(dtb, dtb_root,
DTB_PROP_MBEDTLS_HEAP_SIZE, 1, &heap_size);
if (err < 0) {
- ERROR("Unable to write DTB property %s\n",
- DTB_PROP_MBEDTLS_HEAP_SIZE);
+ ERROR("%sDTB property '%s'\n",
+ "Unable to write ", DTB_PROP_MBEDTLS_HEAP_SIZE);
return -1;
}
return 0;
}
+
+#if MEASURED_BOOT
+/*
+ * This function writes the BL2 hash data in HW_FW_CONFIG DTB.
+ * When it is called, it is guaranteed that a DTB is available.
+ *
+ * This function is supposed to be called only by BL1.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ */
+int arm_set_bl2_hash_info(void *dtb, void *data)
+{
+ assert(dtb_root >= 0);
+
+ /*
+ * Write the BL2 hash data in the DTB.
+ */
+ return fdtw_write_inplace_bytes(dtb, dtb_root,
+ DTB_PROP_BL2_HASH_DATA,
+ TCG_DIGEST_SIZE, data);
+}
+
+/*
+ * Write the Event Log address and its size in the DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ */
+static int arm_set_event_log_info(uintptr_t config_base,
+#ifdef SPD_opteed
+ uintptr_t sm_log_addr,
+#endif
+ uintptr_t log_addr, size_t log_size)
+{
+ /* As libfdt uses void *, we can't avoid this cast */
+ void *dtb = (void *)config_base;
+ const char *compatible = "arm,tpm_event_log";
+ int err, node;
+
+ /*
+ * Verify that the DTB is valid, before attempting to write to it,
+ * and get the DTB root node.
+ */
+
+ /* Check if the pointer to DT is correct */
+ err = fdt_check_header(dtb);
+ if (err < 0) {
+ WARN("Invalid DTB file passed\n");
+ return err;
+ }
+
+ /* Assert the node offset point to compatible property */
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible);
+ if (node < 0) {
+ WARN("The compatible property '%s' not%s", compatible,
+ " found in the config\n");
+ return node;
+ }
+
+ VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
+
+#ifdef SPD_opteed
+ if (sm_log_addr != 0UL) {
+ err = fdtw_write_inplace_cells(dtb, node,
+ DTB_PROP_HW_SM_LOG_ADDR, 2, &sm_log_addr);
+ if (err < 0) {
+ ERROR("%sDTB property '%s'\n",
+ "Unable to write ", DTB_PROP_HW_SM_LOG_ADDR);
+ return err;
+ }
+ }
+#endif
+ err = fdtw_write_inplace_cells(dtb, node,
+ DTB_PROP_HW_LOG_ADDR, 2, &log_addr);
+ if (err < 0) {
+ ERROR("%sDTB property '%s'\n",
+ "Unable to write ", DTB_PROP_HW_LOG_ADDR);
+ return err;
+ }
+
+ err = fdtw_write_inplace_cells(dtb, node,
+ DTB_PROP_HW_LOG_SIZE, 1, &log_size);
+ if (err < 0) {
+ ERROR("%sDTB property '%s'\n",
+ "Unable to write ", DTB_PROP_HW_LOG_SIZE);
+ } else {
+ /*
+ * Ensure that the info written to the DTB is visible
+ * to other images.
+ */
+ flush_dcache_range(config_base, fdt_totalsize(dtb));
+ }
+
+ return err;
+}
+
+/*
+ * This function writes the Event Log address and its size
+ * in the TOS_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ */
+int arm_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr,
+ size_t log_size)
+{
+ int err;
+
+ assert(config_base != 0UL);
+ assert(log_addr != 0UL);
+
+ /* Write the Event Log address and its size in the DTB */
+ err = arm_set_event_log_info(config_base,
+#ifdef SPD_opteed
+ 0UL,
+#endif
+ log_addr, log_size);
+ if (err < 0) {
+ ERROR("%sEvent Log data to TOS_FW_CONFIG\n",
+ "Unable to write ");
+ }
+
+ return err;
+}
+
+/*
+ * This function writes the Event Log address and its size
+ * in the NT_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ */
+int arm_set_nt_fw_info(uintptr_t config_base,
+#ifdef SPD_opteed
+ uintptr_t log_addr,
+#endif
+ size_t log_size, uintptr_t *ns_log_addr)
+{
+ uintptr_t ns_addr;
+ const bl_mem_params_node_t *cfg_mem_params;
+ int err;
+
+ assert(config_base != 0UL);
+ assert(ns_log_addr != NULL);
+
+ /* Get the config load address and size from NT_FW_CONFIG */
+ cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
+ assert(cfg_mem_params != NULL);
+
+ /* Calculate Event Log address in Non-secure memory */
+ ns_addr = cfg_mem_params->image_info.image_base +
+ cfg_mem_params->image_info.image_max_size;
+
+ /* Check for memory space */
+ if ((uint64_t)(ns_addr + log_size) > ARM_NS_DRAM1_END) {
+ return -1;
+ }
+
+ /* Write the Event Log address and its size in the DTB */
+ err = arm_set_event_log_info(config_base,
+#ifdef SPD_opteed
+ log_addr,
+#endif
+ ns_addr, log_size);
+
+ /* Return Event Log address in Non-secure memory */
+ *ns_log_addr = (err < 0) ? 0UL : ns_addr;
+ return err;
+}
+#endif /* MEASURED_BOOT */
diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c
index 2faaa76c4..ed7f1f5a5 100644
--- a/plat/arm/common/arm_image_load.c
+++ b/plat/arm/common/arm_image_load.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,9 @@
#include <assert.h>
#include <common/bl_common.h>
#include <common/desc_image_load.h>
+#if defined(SPD_spmd)
+#include <plat/arm/common/fconf_arm_sp_getter.h>
+#endif
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
@@ -29,12 +32,62 @@ void plat_flush_next_bl_params(void)
next_bl_params_cpy_ptr);
}
+#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+/*******************************************************************************
+ * This function appends Secure Partitions to list of loadable images.
+ ******************************************************************************/
+static void plat_add_sp_images_load_info(struct bl_load_info *load_info)
+{
+ bl_load_info_node_t *node_info = load_info->head;
+ unsigned int index = 0;
+
+ if (sp_mem_params_descs[index].image_id == 0) {
+ ERROR("No Secure Partition Image available\n");
+ return;
+ }
+
+ /* Traverse through the bl images list */
+ do {
+ node_info = node_info->next_load_info;
+ } while (node_info->next_load_info != NULL);
+
+ for (; index < MAX_SP_IDS; index++) {
+ /* Populate the image information */
+ node_info->image_id = sp_mem_params_descs[index].image_id;
+ node_info->image_info = &sp_mem_params_descs[index].image_info;
+
+ if ((index + 1U) == MAX_SP_IDS) {
+ INFO("Reached Max number of SPs\n");
+ return;
+ }
+
+ if (sp_mem_params_descs[index + 1U].image_id == 0) {
+ return;
+ }
+
+ node_info->next_load_info =
+ &sp_mem_params_descs[index + 1U].load_node_mem;
+ node_info = node_info->next_load_info;
+
+ }
+}
+#endif
+
/*******************************************************************************
* This function returns the list of loadable images.
******************************************************************************/
struct bl_load_info *plat_get_bl_image_load_info(void)
{
+#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+ bl_load_info_t *bl_load_info;
+
+ bl_load_info = get_bl_load_info_from_mem_params_desc();
+ plat_add_sp_images_load_info(bl_load_info);
+
+ return bl_load_info;
+#else
return get_bl_load_info_from_mem_params_desc();
+#endif
}
/*******************************************************************************
diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c
index fc1eb490e..34b4101e1 100644
--- a/plat/arm/common/arm_io_storage.c
+++ b/plat/arm/common/arm_io_storage.c
@@ -1,263 +1,33 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <assert.h>
-#include <string.h>
-
-#include <platform_def.h>
-
#include <common/debug.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_fip.h>
#include <drivers/io/io_memmap.h>
#include <drivers/io/io_storage.h>
#include <lib/utils.h>
+
+#include <plat/arm/common/arm_fconf_getter.h>
+#include <plat/arm/common/arm_fconf_io_storage.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <tools_share/firmware_image_package.h>
+#include <platform_def.h>
/* IO devices */
static const io_dev_connector_t *fip_dev_con;
-static uintptr_t fip_dev_handle;
+uintptr_t fip_dev_handle;
static const io_dev_connector_t *memmap_dev_con;
-static uintptr_t memmap_dev_handle;
-
-static const io_block_spec_t fip_block_spec = {
- .offset = PLAT_ARM_FIP_BASE,
- .length = PLAT_ARM_FIP_MAX_SIZE
-};
-
-static const io_uuid_spec_t bl2_uuid_spec = {
- .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
-};
-
-static const io_uuid_spec_t scp_bl2_uuid_spec = {
- .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
-};
-
-static const io_uuid_spec_t bl31_uuid_spec = {
- .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
-};
-
-static const io_uuid_spec_t bl32_uuid_spec = {
- .uuid = UUID_SECURE_PAYLOAD_BL32,
-};
-
-static const io_uuid_spec_t bl32_extra1_uuid_spec = {
- .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
-};
-
-static const io_uuid_spec_t bl32_extra2_uuid_spec = {
- .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
-};
-
-static const io_uuid_spec_t bl33_uuid_spec = {
- .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
-};
-
-static const io_uuid_spec_t tb_fw_config_uuid_spec = {
- .uuid = UUID_TB_FW_CONFIG,
-};
-
-static const io_uuid_spec_t hw_config_uuid_spec = {
- .uuid = UUID_HW_CONFIG,
-};
-
-static const io_uuid_spec_t soc_fw_config_uuid_spec = {
- .uuid = UUID_SOC_FW_CONFIG,
-};
-
-static const io_uuid_spec_t tos_fw_config_uuid_spec = {
- .uuid = UUID_TOS_FW_CONFIG,
-};
-
-static const io_uuid_spec_t nt_fw_config_uuid_spec = {
- .uuid = UUID_NT_FW_CONFIG,
-};
-
-#if TRUSTED_BOARD_BOOT
-static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
- .uuid = UUID_TRUSTED_BOOT_FW_CERT,
-};
-
-static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
- .uuid = UUID_TRUSTED_KEY_CERT,
-};
-
-static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
- .uuid = UUID_SCP_FW_KEY_CERT,
-};
-
-static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
- .uuid = UUID_SOC_FW_KEY_CERT,
-};
-
-static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
- .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
-};
-
-static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
- .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
-};
-
-static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
- .uuid = UUID_SCP_FW_CONTENT_CERT,
-};
-
-static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
- .uuid = UUID_SOC_FW_CONTENT_CERT,
-};
-
-static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
- .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
-};
-
-static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
- .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
-};
-#endif /* TRUSTED_BOARD_BOOT */
-
-
-static int open_fip(const uintptr_t spec);
-static int open_memmap(const uintptr_t spec);
-
-struct plat_io_policy {
- uintptr_t *dev_handle;
- uintptr_t image_spec;
- int (*check)(const uintptr_t spec);
-};
-
-/* By default, ARM platforms load images from the FIP */
-static const struct plat_io_policy policies[] = {
- [FIP_IMAGE_ID] = {
- &memmap_dev_handle,
- (uintptr_t)&fip_block_spec,
- open_memmap
- },
- [BL2_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl2_uuid_spec,
- open_fip
- },
- [SCP_BL2_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&scp_bl2_uuid_spec,
- open_fip
- },
- [BL31_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl31_uuid_spec,
- open_fip
- },
- [BL32_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl32_uuid_spec,
- open_fip
- },
- [BL32_EXTRA1_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl32_extra1_uuid_spec,
- open_fip
- },
- [BL32_EXTRA2_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl32_extra2_uuid_spec,
- open_fip
- },
- [BL33_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl33_uuid_spec,
- open_fip
- },
- [TB_FW_CONFIG_ID] = {
- &fip_dev_handle,
- (uintptr_t)&tb_fw_config_uuid_spec,
- open_fip
- },
- [HW_CONFIG_ID] = {
- &fip_dev_handle,
- (uintptr_t)&hw_config_uuid_spec,
- open_fip
- },
- [SOC_FW_CONFIG_ID] = {
- &fip_dev_handle,
- (uintptr_t)&soc_fw_config_uuid_spec,
- open_fip
- },
- [TOS_FW_CONFIG_ID] = {
- &fip_dev_handle,
- (uintptr_t)&tos_fw_config_uuid_spec,
- open_fip
- },
- [NT_FW_CONFIG_ID] = {
- &fip_dev_handle,
- (uintptr_t)&nt_fw_config_uuid_spec,
- open_fip
- },
-#if TRUSTED_BOARD_BOOT
- [TRUSTED_BOOT_FW_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&tb_fw_cert_uuid_spec,
- open_fip
- },
- [TRUSTED_KEY_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&trusted_key_cert_uuid_spec,
- open_fip
- },
- [SCP_FW_KEY_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&scp_fw_key_cert_uuid_spec,
- open_fip
- },
- [SOC_FW_KEY_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&soc_fw_key_cert_uuid_spec,
- open_fip
- },
- [TRUSTED_OS_FW_KEY_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&tos_fw_key_cert_uuid_spec,
- open_fip
- },
- [NON_TRUSTED_FW_KEY_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&nt_fw_key_cert_uuid_spec,
- open_fip
- },
- [SCP_FW_CONTENT_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&scp_fw_cert_uuid_spec,
- open_fip
- },
- [SOC_FW_CONTENT_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&soc_fw_cert_uuid_spec,
- open_fip
- },
- [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&tos_fw_cert_uuid_spec,
- open_fip
- },
- [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
- &fip_dev_handle,
- (uintptr_t)&nt_fw_cert_uuid_spec,
- open_fip
- },
-#endif /* TRUSTED_BOARD_BOOT */
-};
-
+uintptr_t memmap_dev_handle;
/* Weak definitions may be overridden in specific ARM standard platform */
#pragma weak plat_arm_io_setup
#pragma weak plat_arm_get_alt_image_source
-
-static int open_fip(const uintptr_t spec)
+int open_fip(const uintptr_t spec)
{
int result;
uintptr_t local_image_handle;
@@ -274,8 +44,7 @@ static int open_fip(const uintptr_t spec)
return result;
}
-
-static int open_memmap(const uintptr_t spec)
+int open_memmap(const uintptr_t spec)
{
int result;
uintptr_t local_image_handle;
@@ -291,33 +60,41 @@ static int open_memmap(const uintptr_t spec)
return result;
}
-
-void arm_io_setup(void)
+int arm_io_setup(void)
{
int io_result;
io_result = register_io_dev_fip(&fip_dev_con);
- assert(io_result == 0);
+ if (io_result < 0) {
+ return io_result;
+ }
io_result = register_io_dev_memmap(&memmap_dev_con);
- assert(io_result == 0);
+ if (io_result < 0) {
+ return io_result;
+ }
/* Open connections to devices and cache the handles */
io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
&fip_dev_handle);
- assert(io_result == 0);
+ if (io_result < 0) {
+ return io_result;
+ }
io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
&memmap_dev_handle);
- assert(io_result == 0);
- /* Ignore improbable errors in release builds */
- (void)io_result;
+ return io_result;
}
void plat_arm_io_setup(void)
{
- arm_io_setup();
+ int err;
+
+ err = arm_io_setup();
+ if (err < 0) {
+ panic();
+ }
}
int plat_arm_get_alt_image_source(
@@ -337,9 +114,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
int result;
const struct plat_io_policy *policy;
- assert(image_id < ARRAY_SIZE(policies));
-
- policy = &policies[image_id];
+ policy = FCONF_GET_PROPERTY(arm, io_policies, image_id);
result = policy->check(policy->image_spec);
if (result == 0) {
*image_spec = policy->image_spec;
@@ -357,12 +132,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
* See if a Firmware Image Package is available,
* by checking if TOC is valid or not.
*/
-int arm_io_is_toc_valid(void)
+bool arm_io_is_toc_valid(void)
{
- int result;
-
- result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
-
- return (result == 0);
+ return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0);
}
-
diff --git a/plat/arm/common/arm_nor_psci_mem_protect.c b/plat/arm/common/arm_nor_psci_mem_protect.c
index b9181eb4c..1fa234d79 100644
--- a/plat/arm/common/arm_nor_psci_mem_protect.c
+++ b/plat/arm/common/arm_nor_psci_mem_protect.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,7 +9,6 @@
#include <common/debug.h>
#include <drivers/cfi/v2m_flash.h>
#include <lib/psci/psci.h>
-#include <lib/mmio.h>
#include <lib/utils.h>
#include <plat/arm/common/plat_arm.h>
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index c95f4523c..5434c9457 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -1,11 +1,10 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <errno.h>
#include <platform_def.h>
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index 34e650f19..370ef0a86 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,7 +19,8 @@
* When booting an EL3 payload, this is simplified: we configure region 0 with
* secure access only and do not enable any other region.
******************************************************************************/
-void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions)
+void arm_tzc400_setup(uintptr_t tzc_base,
+ const arm_tzc_regions_info_t *tzc_regions)
{
#ifndef EL3_PAYLOAD_BASE
unsigned int region_index = 1U;
@@ -32,7 +33,7 @@ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions)
INFO("Configuring TrustZone Controller\n");
- tzc400_init(PLAT_ARM_TZC_BASE);
+ tzc400_init(tzc_base);
/* Disable filters. */
tzc400_disable_filters();
@@ -74,5 +75,5 @@ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions)
void plat_arm_security_setup(void)
{
- arm_tzc400_setup(NULL);
+ arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL);
}
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
new file mode 100644
index 000000000..48286c2f2
--- /dev/null
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/io/io_storage.h>
+#include <lib/object_pool.h>
+#include <libfdt.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <plat/arm/common/arm_fconf_getter.h>
+#include <plat/arm/common/arm_fconf_io_storage.h>
+#include <platform_def.h>
+
+const io_block_spec_t fip_block_spec = {
+ .offset = PLAT_ARM_FIP_BASE,
+ .length = PLAT_ARM_FIP_MAX_SIZE
+};
+
+const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = {
+ [BL2_IMAGE_ID] = {UUID_TRUSTED_BOOT_FIRMWARE_BL2},
+ [TB_FW_CONFIG_ID] = {UUID_TB_FW_CONFIG},
+ [FW_CONFIG_ID] = {UUID_FW_CONFIG},
+#if !ARM_IO_IN_DTB
+ [SCP_BL2_IMAGE_ID] = {UUID_SCP_FIRMWARE_SCP_BL2},
+ [BL31_IMAGE_ID] = {UUID_EL3_RUNTIME_FIRMWARE_BL31},
+ [BL32_IMAGE_ID] = {UUID_SECURE_PAYLOAD_BL32},
+ [BL32_EXTRA1_IMAGE_ID] = {UUID_SECURE_PAYLOAD_BL32_EXTRA1},
+ [BL32_EXTRA2_IMAGE_ID] = {UUID_SECURE_PAYLOAD_BL32_EXTRA2},
+ [BL33_IMAGE_ID] = {UUID_NON_TRUSTED_FIRMWARE_BL33},
+ [HW_CONFIG_ID] = {UUID_HW_CONFIG},
+ [SOC_FW_CONFIG_ID] = {UUID_SOC_FW_CONFIG},
+ [TOS_FW_CONFIG_ID] = {UUID_TOS_FW_CONFIG},
+ [NT_FW_CONFIG_ID] = {UUID_NT_FW_CONFIG},
+#endif /* ARM_IO_IN_DTB */
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT},
+#if !ARM_IO_IN_DTB
+ [TRUSTED_KEY_CERT_ID] = {UUID_TRUSTED_KEY_CERT},
+ [SCP_FW_KEY_CERT_ID] = {UUID_SCP_FW_KEY_CERT},
+ [SOC_FW_KEY_CERT_ID] = {UUID_SOC_FW_KEY_CERT},
+ [TRUSTED_OS_FW_KEY_CERT_ID] = {UUID_TRUSTED_OS_FW_KEY_CERT},
+ [NON_TRUSTED_FW_KEY_CERT_ID] = {UUID_NON_TRUSTED_FW_KEY_CERT},
+ [SCP_FW_CONTENT_CERT_ID] = {UUID_SCP_FW_CONTENT_CERT},
+ [SOC_FW_CONTENT_CERT_ID] = {UUID_SOC_FW_CONTENT_CERT},
+ [TRUSTED_OS_FW_CONTENT_CERT_ID] = {UUID_TRUSTED_OS_FW_CONTENT_CERT},
+ [NON_TRUSTED_FW_CONTENT_CERT_ID] = {UUID_NON_TRUSTED_FW_CONTENT_CERT},
+#if defined(SPD_spmd)
+ [SIP_SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT},
+ [PLAT_SP_CONTENT_CERT_ID] = {UUID_PLAT_SECURE_PARTITION_CONTENT_CERT},
+#endif
+#endif /* ARM_IO_IN_DTB */
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+/* By default, ARM platforms load images from the FIP */
+struct plat_io_policy policies[MAX_NUMBER_IDS] = {
+ [FIP_IMAGE_ID] = {
+ &memmap_dev_handle,
+ (uintptr_t)&fip_block_spec,
+ open_memmap
+ },
+ [BL2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[BL2_IMAGE_ID],
+ open_fip
+ },
+ [TB_FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[TB_FW_CONFIG_ID],
+ open_fip
+ },
+ [FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[FW_CONFIG_ID],
+ open_fip
+ },
+#if !ARM_IO_IN_DTB
+ [SCP_BL2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[SCP_BL2_IMAGE_ID],
+ open_fip
+ },
+ [BL31_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[BL31_IMAGE_ID],
+ open_fip
+ },
+ [BL32_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[BL32_IMAGE_ID],
+ open_fip
+ },
+ [BL32_EXTRA1_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[BL32_EXTRA1_IMAGE_ID],
+ open_fip
+ },
+ [BL32_EXTRA2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[BL32_EXTRA2_IMAGE_ID],
+ open_fip
+ },
+ [BL33_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[BL33_IMAGE_ID],
+ open_fip
+ },
+ [HW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[HW_CONFIG_ID],
+ open_fip
+ },
+ [SOC_FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[SOC_FW_CONFIG_ID],
+ open_fip
+ },
+ [TOS_FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[TOS_FW_CONFIG_ID],
+ open_fip
+ },
+ [NT_FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[NT_FW_CONFIG_ID],
+ open_fip
+ },
+#endif /* ARM_IO_IN_DTB */
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_BOOT_FW_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[TRUSTED_BOOT_FW_CERT_ID],
+ open_fip
+ },
+#if !ARM_IO_IN_DTB
+ [TRUSTED_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[TRUSTED_KEY_CERT_ID],
+ open_fip
+ },
+ [SCP_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[SCP_FW_KEY_CERT_ID],
+ open_fip
+ },
+ [SOC_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[SOC_FW_KEY_CERT_ID],
+ open_fip
+ },
+ [TRUSTED_OS_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[TRUSTED_OS_FW_KEY_CERT_ID],
+ open_fip
+ },
+ [NON_TRUSTED_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[NON_TRUSTED_FW_KEY_CERT_ID],
+ open_fip
+ },
+ [SCP_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[SCP_FW_CONTENT_CERT_ID],
+ open_fip
+ },
+ [SOC_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[SOC_FW_CONTENT_CERT_ID],
+ open_fip
+ },
+ [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[TRUSTED_OS_FW_CONTENT_CERT_ID],
+ open_fip
+ },
+ [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[NON_TRUSTED_FW_CONTENT_CERT_ID],
+ open_fip
+ },
+#if defined(SPD_spmd)
+ [SIP_SP_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[SIP_SP_CONTENT_CERT_ID],
+ open_fip
+ },
+ [PLAT_SP_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[PLAT_SP_CONTENT_CERT_ID],
+ open_fip
+ },
+#endif
+#endif /* ARM_IO_IN_DTB */
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+#ifdef IMAGE_BL2
+
+#if TRUSTED_BOARD_BOOT
+#define FCONF_ARM_IO_UUID_NUMBER U(21)
+#else
+#define FCONF_ARM_IO_UUID_NUMBER U(10)
+#endif
+
+static io_uuid_spec_t fconf_arm_uuids[FCONF_ARM_IO_UUID_NUMBER];
+static OBJECT_POOL_ARRAY(fconf_arm_uuids_pool, fconf_arm_uuids);
+
+struct policies_load_info {
+ unsigned int image_id;
+ const char *name;
+};
+
+/* image id to property name table */
+static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = {
+ {SCP_BL2_IMAGE_ID, "scp_bl2_uuid"},
+ {BL31_IMAGE_ID, "bl31_uuid"},
+ {BL32_IMAGE_ID, "bl32_uuid"},
+ {BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"},
+ {BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"},
+ {BL33_IMAGE_ID, "bl33_uuid"},
+ {HW_CONFIG_ID, "hw_cfg_uuid"},
+ {SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"},
+ {TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"},
+ {NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"},
+#if TRUSTED_BOARD_BOOT
+ {TRUSTED_KEY_CERT_ID, "t_key_cert_uuid"},
+ {SCP_FW_KEY_CERT_ID, "scp_fw_key_uuid"},
+ {SOC_FW_KEY_CERT_ID, "soc_fw_key_uuid"},
+ {TRUSTED_OS_FW_KEY_CERT_ID, "tos_fw_key_cert_uuid"},
+ {NON_TRUSTED_FW_KEY_CERT_ID, "nt_fw_key_cert_uuid"},
+ {SCP_FW_CONTENT_CERT_ID, "scp_fw_content_cert_uuid"},
+ {SOC_FW_CONTENT_CERT_ID, "soc_fw_content_cert_uuid"},
+ {TRUSTED_OS_FW_CONTENT_CERT_ID, "tos_fw_content_cert_uuid"},
+ {NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"},
+#if defined(SPD_spmd)
+ {SIP_SP_CONTENT_CERT_ID, "sip_sp_content_cert_uuid"},
+ {PLAT_SP_CONTENT_CERT_ID, "plat_sp_content_cert_uuid"},
+#endif
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+int fconf_populate_arm_io_policies(uintptr_t config)
+{
+ int err, node;
+ unsigned int i;
+ unsigned int j;
+
+ union uuid_helper_t uuid_helper;
+ io_uuid_spec_t *uuid_ptr;
+
+ /* As libfdt uses void *, we can't avoid this cast */
+ const void *dtb = (void *)config;
+
+ /* Assert the node offset point to "arm,io-fip-handle" compatible property */
+ const char *compatible_str = "arm,io-fip-handle";
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
+ return node;
+ }
+
+ /* Locate the uuid cells and read the value for all the load info uuid */
+ for (i = 0; i < FCONF_ARM_IO_UUID_NUMBER; i++) {
+ uuid_ptr = pool_alloc(&fconf_arm_uuids_pool);
+ err = fdt_read_uint32_array(dtb, node, load_info[i].name,
+ 4, uuid_helper.word);
+ if (err < 0) {
+ WARN("FCONF: Read cell failed for %s\n", load_info[i].name);
+ return err;
+ }
+
+ /* Convert uuid from big endian to little endian */
+ for (j = 0U; j < 4U; j++) {
+ uuid_helper.word[j] =
+ ((uuid_helper.word[j] >> 24U) & 0xff) |
+ ((uuid_helper.word[j] << 8U) & 0xff0000) |
+ ((uuid_helper.word[j] >> 8U) & 0xff00) |
+ ((uuid_helper.word[j] << 24U) & 0xff000000);
+ }
+
+ VERBOSE("FCONF: arm-io_policies.%s cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
+ load_info[i].name,
+ uuid_helper.word[0], uuid_helper.word[1],
+ uuid_helper.word[2], uuid_helper.word[3]);
+
+ uuid_ptr->uuid = uuid_helper.uuid_struct;
+ policies[load_info[i].image_id].image_spec = (uintptr_t)uuid_ptr;
+ policies[load_info[i].image_id].dev_handle = &fip_dev_handle;
+ policies[load_info[i].image_id].check = open_fip;
+ }
+ return 0;
+}
+
+#if ARM_IO_IN_DTB
+FCONF_REGISTER_POPULATOR(TB_FW, arm_io, fconf_populate_arm_io_policies);
+#endif /* ARM_IO_IN_DTB */
+
+#endif /* IMAGE_BL2 */
diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c
new file mode 100644
index 000000000..7950e7f6d
--- /dev/null
+++ b/plat/arm/common/fconf/arm_fconf_sp.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/io/io_storage.h>
+#include <lib/object_pool.h>
+#include <libfdt.h>
+#include <plat/arm/common/arm_fconf_getter.h>
+#include <plat/arm/common/arm_fconf_io_storage.h>
+#include <plat/arm/common/fconf_arm_sp_getter.h>
+#include <platform_def.h>
+#include <tools_share/firmware_image_package.h>
+
+#ifdef IMAGE_BL2
+
+bl_mem_params_node_t sp_mem_params_descs[MAX_SP_IDS];
+
+struct arm_sp_t arm_sp;
+
+int fconf_populate_arm_sp(uintptr_t config)
+{
+ int sp_node, node, err;
+ union uuid_helper_t uuid_helper;
+ unsigned int index = 0;
+ uint32_t val32;
+ bool is_plat_owned = false;
+ const unsigned int sip_start = SP_PKG1_ID;
+ unsigned int sip_index = sip_start;
+ const unsigned int sip_end = sip_start + MAX_SP_IDS / 2;
+ const unsigned int plat_start = SP_PKG5_ID;
+ unsigned int plat_index = plat_start;
+ const unsigned int plat_end = plat_start + MAX_SP_IDS / 2;
+ unsigned int j;
+
+ /* As libfdt use void *, we can't avoid this cast */
+ const void *dtb = (void *)config;
+
+ /* Assert the node offset point to "arm,sp" compatible property */
+ const char *compatible_str = "arm,sp";
+
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s in dtb\n", compatible_str);
+ return node;
+ }
+
+ fdt_for_each_subnode(sp_node, dtb, node) {
+ if ((index == MAX_SP_IDS) || (sip_index == sip_end)
+ || (plat_index == plat_end)) {
+ ERROR("FCONF: Reached max number of SPs\n");
+ return -1;
+ }
+
+ /* Read UUID */
+ err = fdt_read_uint32_array(dtb, sp_node, "uuid", 4,
+ uuid_helper.word);
+ if (err < 0) {
+ ERROR("FCONF: cannot read SP uuid\n");
+ return -1;
+ }
+
+ /* Convert uuid from big endian to little endian */
+ for (j = 0U; j < 4U; j++) {
+ uuid_helper.word[j] =
+ ((uuid_helper.word[j] >> 24U) & 0xff) |
+ ((uuid_helper.word[j] << 8U) & 0xff0000) |
+ ((uuid_helper.word[j] >> 8U) & 0xff00) |
+ ((uuid_helper.word[j] << 24U) & 0xff000000);
+ }
+
+ arm_sp.uuids[index] = uuid_helper;
+ VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n",
+ __func__,
+ uuid_helper.word[0],
+ uuid_helper.word[1],
+ uuid_helper.word[2],
+ uuid_helper.word[3],
+ arm_sp.load_addr[index]);
+
+ /* Read Load address */
+ err = fdt_read_uint32(dtb, sp_node, "load-address", &val32);
+ if (err < 0) {
+ ERROR("FCONF: cannot read SP load address\n");
+ return -1;
+ }
+ arm_sp.load_addr[index] = val32;
+
+ /* Read owner field only for dualroot CoT */
+#if defined(ARM_COT_dualroot)
+ /* Owner is an optional field, no need to catch error */
+ fdtw_read_string(dtb, sp_node, "owner",
+ arm_sp.owner[index], ARM_SP_OWNER_NAME_LEN);
+#endif
+ /* If owner is empty mark it as SiP owned */
+ if ((strncmp(arm_sp.owner[index], "SiP",
+ ARM_SP_OWNER_NAME_LEN) == 0) ||
+ (strncmp(arm_sp.owner[index], "",
+ ARM_SP_OWNER_NAME_LEN) == 0)) {
+ is_plat_owned = false;
+ } else if (strcmp(arm_sp.owner[index], "Plat") == 0) {
+ is_plat_owned = true;
+ } else {
+ ERROR("FCONF: %s is not a valid SP owner\n",
+ arm_sp.owner[index]);
+ return -1;
+ }
+ /*
+ * Add SP information in mem param descriptor and IO policies
+ * structure.
+ */
+ if (is_plat_owned) {
+ sp_mem_params_descs[index].image_id = plat_index;
+ policies[plat_index].image_spec =
+ (uintptr_t)&arm_sp.uuids[index];
+ policies[plat_index].dev_handle = &fip_dev_handle;
+ policies[plat_index].check = open_fip;
+ plat_index++;
+ } else {
+ sp_mem_params_descs[index].image_id = sip_index;
+ policies[sip_index].image_spec =
+ (uintptr_t)&arm_sp.uuids[index];
+ policies[sip_index].dev_handle = &fip_dev_handle;
+ policies[sip_index].check = open_fip;
+ sip_index++;
+ }
+ SET_PARAM_HEAD(&sp_mem_params_descs[index].image_info,
+ PARAM_IMAGE_BINARY, VERSION_2, 0);
+ sp_mem_params_descs[index].image_info.image_max_size =
+ ARM_SP_MAX_SIZE;
+ sp_mem_params_descs[index].next_handoff_image_id =
+ INVALID_IMAGE_ID;
+ sp_mem_params_descs[index].image_info.image_base =
+ arm_sp.load_addr[index];
+ index++;
+ }
+
+ if ((sp_node < 0) && (sp_node != -FDT_ERR_NOTFOUND)) {
+ ERROR("%u: fdt_for_each_subnode(): %d\n", __LINE__, node);
+ return sp_node;
+ }
+
+ arm_sp.number_of_sp = index;
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(TB_FW, arm_sp, fconf_populate_arm_sp);
+
+#endif /* IMAGE_BL2 */
diff --git a/plat/arm/common/fconf/fconf_nv_cntr_getter.c b/plat/arm/common/fconf/fconf_nv_cntr_getter.c
new file mode 100644
index 000000000..8d645ef3d
--- /dev/null
+++ b/plat/arm/common/fconf/fconf_nv_cntr_getter.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+
+#include <libfdt.h>
+
+#include <plat/arm/common/fconf_nv_cntr_getter.h>
+
+/*******************************************************************************
+ * fconf_populate_cot_descs() - Populate available nv-counters and update global
+ * structure.
+ * @config[in]: Pointer to the device tree blob in memory
+ *
+ * Return 0 on success or an error value otherwise.
+ ******************************************************************************/
+static int fconf_populate_nv_cntrs(uintptr_t config)
+{
+ int rc, node, child;
+ uint32_t id;
+ uintptr_t reg;
+
+ /* As libfdt uses void *, we can't avoid this cast */
+ const void *dtb = (void *)config;
+ const char *compatible_str = "arm, non-volatile-counter";
+
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s compatible in node\n",
+ compatible_str);
+ return node;
+ }
+
+ fdt_for_each_subnode(child, dtb, node) {
+
+ rc = fdt_read_uint32(dtb, child, "id", &id);
+ if (rc < 0) {
+ ERROR("FCONF: Can't find %s property in node\n", "id");
+ return rc;
+ }
+
+ assert(id < MAX_NV_CTR_IDS);
+
+ rc = fdt_get_reg_props_by_index(dtb, child, 0, &reg, NULL);
+ if (rc < 0) {
+ ERROR("FCONF: Can't find %s property in node\n", "reg");
+ return rc;
+ }
+
+ nv_cntr_base_addr[id] = reg;
+ }
+
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(TB_FW, nv_cntrs, fconf_populate_nv_cntrs);
diff --git a/plat/arm/common/fconf/fconf_sdei_getter.c b/plat/arm/common/fconf/fconf_sdei_getter.c
new file mode 100644
index 000000000..c26e316a5
--- /dev/null
+++ b/plat/arm/common/fconf/fconf_sdei_getter.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <libfdt.h>
+#include <plat/arm/common/fconf_sdei_getter.h>
+
+#define PRIVATE_EVENT_NUM(i) private_events[3 * (i)]
+#define PRIVATE_EVENT_INTR(i) private_events[3 * (i) + 1]
+#define PRIVATE_EVENT_FLAGS(i) private_events[3 * (i) + 2]
+
+#define SHARED_EVENT_NUM(i) shared_events[3 * (i)]
+#define SHARED_EVENT_INTR(i) shared_events[3 * (i) + 1]
+#define SHARED_EVENT_FLAGS(i) shared_events[3 * (i) + 2]
+
+struct sdei_dyn_config_t sdei_dyn_config;
+
+int fconf_populate_sdei_dyn_config(uintptr_t config)
+{
+ uint32_t i;
+ int node, err;
+ uint32_t private_events[PLAT_SDEI_DP_EVENT_MAX_CNT * 3];
+ uint32_t shared_events[PLAT_SDEI_DS_EVENT_MAX_CNT * 3];
+
+ const void *dtb = (void *)config;
+
+ /* Check that the node offset points to compatible property */
+ node = fdt_node_offset_by_compatible(dtb, -1, "arm,sdei-1.0");
+ if (node < 0) {
+ ERROR("FCONF: Can't find 'arm,sdei-1.0' compatible node in dtb\n");
+ return node;
+ }
+
+ /* Read number of private mappings */
+ err = fdt_read_uint32(dtb, node, "private_event_count",
+ &sdei_dyn_config.private_ev_cnt);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for 'private_event_count': %u\n",
+ sdei_dyn_config.private_ev_cnt);
+ return err;
+ }
+
+ /* Check if the value is in range */
+ if (sdei_dyn_config.private_ev_cnt > PLAT_SDEI_DP_EVENT_MAX_CNT) {
+ ERROR("FCONF: Invalid value for 'private_event_count': %u\n",
+ sdei_dyn_config.private_ev_cnt);
+ return -1;
+ }
+
+ /* Read private mappings */
+ err = fdt_read_uint32_array(dtb, node, "private_events",
+ sdei_dyn_config.private_ev_cnt * 3, private_events);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for 'private_events': %d\n", err);
+ return err;
+ }
+
+ /* Move data to fconf struct */
+ for (i = 0; i < sdei_dyn_config.private_ev_cnt; i++) {
+ sdei_dyn_config.private_ev_nums[i] = PRIVATE_EVENT_NUM(i);
+ sdei_dyn_config.private_ev_intrs[i] = PRIVATE_EVENT_INTR(i);
+ sdei_dyn_config.private_ev_flags[i] = PRIVATE_EVENT_FLAGS(i);
+ }
+
+ /* Read number of shared mappings */
+ err = fdt_read_uint32(dtb, node, "shared_event_count",
+ &sdei_dyn_config.shared_ev_cnt);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for 'shared_event_count'\n");
+ return err;
+ }
+
+ /* Check if the value is in range */
+ if (sdei_dyn_config.shared_ev_cnt > PLAT_SDEI_DS_EVENT_MAX_CNT) {
+ ERROR("FCONF: Invalid value for 'shared_event_count': %u\n",
+ sdei_dyn_config.shared_ev_cnt);
+ return -1;
+ }
+
+ /* Read shared mappings */
+ err = fdt_read_uint32_array(dtb, node, "shared_events",
+ sdei_dyn_config.shared_ev_cnt * 3, shared_events);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for 'shared_events': %d\n", err);
+ return err;
+ }
+
+ /* Move data to fconf struct */
+ for (i = 0; i < sdei_dyn_config.shared_ev_cnt; i++) {
+ sdei_dyn_config.shared_ev_nums[i] = SHARED_EVENT_NUM(i);
+ sdei_dyn_config.shared_ev_intrs[i] = SHARED_EVENT_INTR(i);
+ sdei_dyn_config.shared_ev_flags[i] = SHARED_EVENT_FLAGS(i);
+ }
+
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(HW_CONFIG, sdei, fconf_populate_sdei_dyn_config);
diff --git a/plat/arm/common/fconf/fconf_sec_intr_config.c b/plat/arm/common/fconf/fconf_sec_intr_config.c
new file mode 100644
index 000000000..f28be240e
--- /dev/null
+++ b/plat/arm/common/fconf/fconf_sec_intr_config.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <libfdt.h>
+#include <plat/arm/common/fconf_sec_intr_config.h>
+
+#define G0_INTR_NUM(i) g0_intr_prop[3U * (i)]
+#define G0_INTR_PRIORITY(i) g0_intr_prop[3U * (i) + 1]
+#define G0_INTR_CONFIG(i) g0_intr_prop[3U * (i) + 2]
+
+#define G1S_INTR_NUM(i) g1s_intr_prop[3U * (i)]
+#define G1S_INTR_PRIORITY(i) g1s_intr_prop[3U * (i) + 1]
+#define G1S_INTR_CONFIG(i) g1s_intr_prop[3U * (i) + 2]
+
+struct sec_intr_prop_t sec_intr_prop;
+
+static void print_intr_prop(interrupt_prop_t prop)
+{
+ VERBOSE("FCONF: Secure Interrupt NUM: %d, PRI: %d, TYPE: %d\n",
+ prop.intr_num, prop.intr_pri, prop.intr_cfg);
+}
+
+int fconf_populate_sec_intr_config(uintptr_t config)
+{
+ int node, err;
+ uint32_t g0_intr_count, g1s_intr_count;
+ uint32_t g0_intr_prop[SEC_INT_COUNT_MAX * 3];
+ uint32_t g1s_intr_prop[SEC_INT_COUNT_MAX * 3];
+
+ /* Necessary to work with libfdt APIs */
+ const void *hw_config_dtb = (const void *)config;
+
+ node = fdt_node_offset_by_compatible(hw_config_dtb, -1,
+ "arm,secure_interrupt_desc");
+ if (node < 0) {
+ ERROR("FCONF: Unable to locate node with %s compatible property\n",
+ "arm,secure_interrupt_desc");
+ return node;
+ }
+
+ /* Read number of Group 0 interrupts specified by platform */
+ err = fdt_read_uint32(hw_config_dtb, node, "g0_intr_cnt", &g0_intr_count);
+ if (err < 0) {
+ ERROR("FCONF: Could not locate g0s_intr_cnt property\n");
+ return err;
+ }
+
+ /* At least 1 Group 0 interrupt description has to be provided*/
+ if (g0_intr_count < 1U) {
+ ERROR("FCONF: Invalid number of Group 0 interrupts count specified\n");
+ return -1;
+ }
+
+ /* Read number of Group 1 secure interrupts specified by platform */
+ err = fdt_read_uint32(hw_config_dtb, node, "g1s_intr_cnt",
+ &g1s_intr_count);
+ if (err < 0) {
+ ERROR("FCONF: Could not locate g1s_intr_cnt property\n");
+ return err;
+ }
+
+ /* At least one Group 1 interrupt description has to be provided*/
+ if (g1s_intr_count < 1U) {
+ ERROR("FCONF: Invalid number of Group 1 secure interrupts count specified\n");
+ return -1;
+ }
+
+ /*
+ * Check if the total number of secure interrupts described are within
+ * the limit defined statically by the platform.
+ */
+ if ((g0_intr_count + g1s_intr_count) > SEC_INT_COUNT_MAX) {
+ ERROR("FCONF: Total number of secure interrupts exceed limit the of %d\n",
+ SEC_INT_COUNT_MAX);
+ return -1;
+ }
+
+ sec_intr_prop.count = g0_intr_count + g1s_intr_count;
+
+ /* Read the Group 0 interrupt descriptors */
+ err = fdt_read_uint32_array(hw_config_dtb, node, "g0_intr_desc",
+ g0_intr_count * 3, g0_intr_prop);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for 'g0s_intr_desc': %d\n", err);
+ return err;
+ }
+
+ /* Read the Group 1 secure interrupt descriptors */
+ err = fdt_read_uint32_array(hw_config_dtb, node, "g1s_intr_desc",
+ g1s_intr_count * 3, g1s_intr_prop);
+ if (err < 0) {
+ ERROR("FCONF: Read cell failed for 'g1s_intr_desc': %d\n", err);
+ return err;
+ }
+
+ /* Populate Group 0 interrupt descriptors into fconf based C struct */
+ for (uint32_t i = 0; i < g0_intr_count; i++) {
+ interrupt_prop_t sec_intr_property;
+
+ /* Secure Interrupt Group: INTR_GROUP0 i.e., 0x1 */
+ sec_intr_property.intr_grp = 1;
+ sec_intr_property.intr_num = G0_INTR_NUM(i);
+ sec_intr_property.intr_pri = G0_INTR_PRIORITY(i);
+ sec_intr_property.intr_cfg = G0_INTR_CONFIG(i);
+ sec_intr_prop.descriptor[i] = sec_intr_property;
+ print_intr_prop(sec_intr_property);
+ }
+
+ /* Populate G1 secure interrupt descriptors into fconf based C struct */
+ for (uint32_t i = 0; i < g1s_intr_count; i++) {
+ interrupt_prop_t sec_intr_property;
+
+ /* Secure Interrupt Group: INTR_GROUP1S i.e., 0x0 */
+ sec_intr_property.intr_grp = 0;
+ sec_intr_property.intr_num = G1S_INTR_NUM(i);
+ sec_intr_property.intr_pri = G1S_INTR_PRIORITY(i);
+ sec_intr_property.intr_cfg = G1S_INTR_CONFIG(i);
+ sec_intr_prop.descriptor[i + g0_intr_count] = sec_intr_property;
+ print_intr_prop(sec_intr_property);
+ }
+
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(HW_CONFIG, sec_intr_prop, fconf_populate_sec_intr_config);
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index bb69914ae..270093c4e 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,6 @@
#include <bl32/sp_min/platform_sp_min.h>
#include <common/bl_common.h>
#include <common/debug.h>
-#include <drivers/arm/pl011.h>
#include <drivers/console.h>
#include <lib/mmio.h>
#include <plat/arm/common/plat_arm.h>
@@ -30,10 +29,10 @@ static entry_point_info_t bl33_image_ep_info;
MT_MEMORY | MT_RW | MT_SECURE)
/*
- * Check that BL32_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page
+ * Check that BL32_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page
* is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2.
*/
-CASSERT(BL32_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl32_base_overflows);
+CASSERT(BL32_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl32_base_overflows);
/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for the
@@ -168,6 +167,10 @@ void arm_sp_min_plat_runtime_setup(void)
{
/* Initialize the runtime console */
arm_console_runtime_init();
+
+#if PLAT_RO_XLAT_TABLES
+ arm_xlat_make_tables_readonly();
+#endif
}
/*******************************************************************************
@@ -183,7 +186,7 @@ void sp_min_platform_setup(void)
* Do initial security configuration to allow DRAM/device access
* (if earlier BL has not already done so).
*/
-#if RESET_TO_SP_MIN
+#if RESET_TO_SP_MIN && !JUNO_AARCH32_EL3_RUNTIME
plat_arm_security_setup();
#if defined(PLAT_ARM_MEM_PROT_ADDR)
@@ -214,7 +217,7 @@ void sp_min_plat_runtime_setup(void)
* Perform the very early platform specific architectural setup here. At the
* moment this only initializes the MMU
******************************************************************************/
-void sp_min_plat_arch_setup(void)
+void arm_sp_min_plat_arch_setup(void)
{
const mmap_region_t bl_regions[] = {
MAP_BL_SP_MIN_TOTAL,
@@ -229,3 +232,8 @@ void sp_min_plat_arch_setup(void)
enable_mmu_svc_mon(0);
}
+
+void sp_min_plat_arch_setup(void)
+{
+ arm_sp_min_plat_arch_setup();
+}
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index aefdf89c7..a4da8c35e 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -28,7 +28,7 @@
/*******************************************************************************
* Initialize the UART
******************************************************************************/
-static console_pl011_t arm_tsp_runtime_console;
+static console_t arm_tsp_runtime_console;
void arm_tsp_early_platform_setup(void)
{
@@ -43,7 +43,7 @@ void arm_tsp_early_platform_setup(void)
if (rc == 0)
panic();
- console_set_scope(&arm_tsp_runtime_console.console,
+ console_set_scope(&arm_tsp_runtime_console,
CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
}
@@ -79,4 +79,8 @@ void tsp_plat_arch_setup(void)
setup_page_tables(bl_regions, plat_arm_get_mmap());
enable_mmu_el1(0);
+
+#if PLAT_RO_XLAT_TABLES
+ arm_xlat_make_tables_readonly();
+#endif
}
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index 01c674f82..926b8ec7c 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -1,11 +1,10 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <errno.h>
#include <platform_def.h>
@@ -15,7 +14,6 @@
#include <lib/cassert.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/arm/css/common/css_pm.h>
-#include <plat/common/platform.h>
/* Allow CSS platforms to override `plat_arm_psci_pm_ops` */
#pragma weak plat_arm_psci_pm_ops
@@ -125,9 +123,32 @@ static void css_power_down_common(const psci_power_state_t *target_state)
/* Prevent interrupts from spuriously waking up this cpu */
plat_arm_gic_cpuif_disable();
+ /* Turn redistributor off */
+ plat_arm_gic_redistif_off();
+
/* Cluster is to be turned off, so disable coherency */
- if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
+ if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
plat_arm_interconnect_exit_coherency();
+
+#if HW_ASSISTED_COHERENCY
+ uint32_t reg;
+
+ /*
+ * If we have determined this core to be the last man standing and we
+ * intend to power down the cluster proactively, we provide a hint to
+ * the power controller that cluster power is not required when all
+ * cores are powered down.
+ * Note that this is only an advisory to power controller and is supported
+ * by SoCs with DynamIQ Shared Units only.
+ */
+ reg = read_clusterpwrdn();
+
+ /* Clear and set bit 0 : Cluster power not required */
+ reg &= ~DSU_CLUSTER_PWR_MASK;
+ reg |= DSU_CLUSTER_PWR_OFF;
+ write_clusterpwrdn(reg);
+#endif
+ }
}
/*******************************************************************************
diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S
index b80903d06..04bfb7771 100644
--- a/plat/arm/css/sgi/aarch64/sgi_helper.S
+++ b/plat/arm/css/sgi/aarch64/sgi_helper.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,19 +18,22 @@
* unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
*
* Helper function to calculate the core position.
+ * (ChipId * PLAT_ARM_CLUSTER_COUNT *
+ * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) +
* (ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) +
* (CPUId * CSS_SGI_MAX_PE_PER_CPU) +
* ThreadId
*
* which can be simplified as:
*
- * ((ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER + CPUId) *
- * CSS_SGI_MAX_PE_PER_CPU) + ThreadId
+ * ((((ChipId * PLAT_ARM_CLUSTER_COUNT) + ClusterId) *
+ * CSS_SGI_MAX_CPUS_PER_CLUSTER) + CPUId) * CSS_SGI_MAX_PE_PER_CPU +
+ * ThreadId
* ------------------------------------------------------
*/
func plat_arm_calc_core_pos
- mov x3, x0
+ mov x4, x0
/*
* The MT bit in MPIDR is always set for SGI platforms
@@ -38,15 +41,18 @@ func plat_arm_calc_core_pos
*/
/* Extract individual affinity fields from MPIDR */
- ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
- ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
- ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS
/* Compute linear position */
+ mov x4, #PLAT_ARM_CLUSTER_COUNT
+ madd x2, x3, x4, x2
mov x4, #CSS_SGI_MAX_CPUS_PER_CLUSTER
madd x1, x2, x4, x1
- mov x5, #CSS_SGI_MAX_PE_PER_CPU
- madd x0, x1, x5, x0
+ mov x4, #CSS_SGI_MAX_PE_PER_CPU
+ madd x0, x1, x4, x0
ret
endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index e21457304..b805746de 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,20 +9,21 @@
#include <lib/utils_def.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
-#include <plat/arm/board/common/board_css_def.h>
-#include <plat/arm/board/common/v2m_def.h>
#include <plat/arm/common/arm_def.h>
#include <plat/arm/common/arm_spm_def.h>
#include <plat/arm/css/common/css_def.h>
-#include <plat/arm/soc/common/soc_css_def.h>
#include <plat/common/common_def.h>
-#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \
- CSS_SGI_MAX_CPUS_PER_CLUSTER * \
+#define PLATFORM_CORE_COUNT (CSS_SGI_CHIP_COUNT * \
+ PLAT_ARM_CLUSTER_COUNT * \
+ CSS_SGI_MAX_CPUS_PER_CLUSTER * \
CSS_SGI_MAX_PE_PER_CPU)
#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */
+/* Remote chip address offset (4TB per chip) */
+#define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) ((ULL(1) << 42) * (n))
+
/*
* PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
* plat_arm_mmap array defined for each BL stage.
@@ -34,15 +35,15 @@
# define PLAT_SP_IMAGE_MMAP_REGIONS 7
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
# else
-# define PLAT_ARM_MMAP_ENTRIES 8
-# define MAX_XLAT_TABLES 5
+# define PLAT_ARM_MMAP_ENTRIES (5 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
+# define MAX_XLAT_TABLES (6 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
# endif
#elif defined(IMAGE_BL32)
# define PLAT_ARM_MMAP_ENTRIES 8
# define MAX_XLAT_TABLES 5
#elif !USE_ROMLIB
# define PLAT_ARM_MMAP_ENTRIES 11
-# define MAX_XLAT_TABLES 5
+# define MAX_XLAT_TABLES 7
#else
# define PLAT_ARM_MMAP_ENTRIES 12
# define MAX_XLAT_TABLES 6
@@ -52,7 +53,7 @@
* PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
* plus a little space for growth.
*/
-#define PLAT_ARM_MAX_BL1_RW_SIZE 0xB000
+#define PLAT_ARM_MAX_BL1_RW_SIZE 0xC000
/*
* PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
@@ -73,7 +74,7 @@
#if TRUSTED_BOARD_BOOT
# define PLAT_ARM_MAX_BL2_SIZE 0x1D000
#else
-# define PLAT_ARM_MAX_BL2_SIZE 0x11000
+# define PLAT_ARM_MAX_BL2_SIZE 0x14000
#endif
/*
@@ -119,6 +120,9 @@
#define PLAT_ARM_NSRAM_BASE 0x06000000
#define PLAT_ARM_NSRAM_SIZE 0x00080000 /* 512KB */
+#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
+
#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp)
#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
@@ -129,10 +133,29 @@
CSS_SGI_DEVICE_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE 0x30000000
-#define PLAT_ARM_GICC_BASE 0x2C000000
-#define PLAT_ARM_GICR_BASE 0x300C0000
+#define ARM_MAP_SHARED_RAM_REMOTE_CHIP(n) \
+ MAP_REGION_FLAT( \
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \
+ ARM_SHARED_RAM_BASE, \
+ ARM_SHARED_RAM_SIZE, \
+ MT_NON_CACHEABLE | MT_RW | MT_SECURE \
+ )
+
+#define CSS_SGI_MAP_DEVICE_REMOTE_CHIP(n) \
+ MAP_REGION_FLAT( \
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \
+ CSS_SGI_DEVICE_BASE, \
+ CSS_SGI_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE \
+ )
+
+#define SOC_CSS_MAP_DEVICE_REMOTE_CHIP(n) \
+ MAP_REGION_FLAT( \
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + \
+ SOC_CSS_DEVICE_BASE, \
+ SOC_CSS_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE \
+ )
/* Map the secure region for access from S-EL0 */
#define PLAT_ARM_SECURE_MAP_DEVICE MAP_REGION_FLAT( \
@@ -212,4 +235,7 @@
#define SBSA_SECURE_WDOG_BASE UL(0x2A480000)
#define SBSA_SECURE_WDOG_TIMEOUT UL(100)
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT CSS_SGI_CHIP_COUNT
+
#endif /* SGI_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_plat.h b/plat/arm/css/sgi/include/sgi_plat.h
new file mode 100644
index 000000000..a5fbded3c
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_plat.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGI_PLAT_H
+#define SGI_PLAT_H
+
+/* BL31 platform setup common to all SGI based platforms */
+void sgi_bl31_common_platform_setup(void);
+
+#endif /* SGI_PLAT_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
new file mode 100644
index 000000000..03f107367
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGI_SOC_CSS_DEF_V2_H
+#define SGI_SOC_CSS_DEF_V2_H
+
+#include <lib/utils_def.h>
+#include <plat/common/common_def.h>
+
+/*
+ * Definitions common to all ARM CSS SoCs
+ */
+
+/* Following covers ARM CSS SoC Peripherals */
+
+#define SOC_SYSTEM_PERIPH_BASE UL(0x0C000000)
+#define SOC_SYSTEM_PERIPH_SIZE UL(0x02000000)
+
+#define SOC_PLATFORM_PERIPH_BASE UL(0x0E000000)
+#define SOC_PLATFORM_PERIPH_SIZE UL(0x02000000)
+
+#define SOC_CSS_PCIE_CONTROL_BASE UL(0x0ef20000)
+
+/* PL011 UART related constants */
+#define SOC_CSS_UART1_BASE UL(0x0ef80000)
+#define SOC_CSS_UART0_BASE UL(0x0ef70000)
+
+/* Memory controller */
+#define SOC_MEMCNTRL_BASE UL(0x10000000)
+#define SOC_MEMCNTRL_SIZE UL(0x10000000)
+
+#define SOC_CSS_UART0_CLK_IN_HZ UL(7372800)
+#define SOC_CSS_UART1_CLK_IN_HZ UL(7372800)
+
+/* SoC NIC-400 Global Programmers View (GPV) */
+#define SOC_CSS_NIC400_BASE UL(0x0ED00000)
+
+#define SOC_CSS_NIC400_USB_EHCI U(0)
+#define SOC_CSS_NIC400_TLX_MASTER U(1)
+#define SOC_CSS_NIC400_USB_OHCI U(2)
+#define SOC_CSS_NIC400_PL354_SMC U(3)
+/*
+ * The apb4_bridge controls access to:
+ * - the PCIe configuration registers
+ * - the MMU units for USB, HDLCD and DMA
+ */
+#define SOC_CSS_NIC400_APB4_BRIDGE U(4)
+
+/* Non-volatile counters */
+#define SOC_TRUSTED_NVCTR_BASE UL(0x0EE70000)
+#define TFW_NVCTR_BASE (SOC_TRUSTED_NVCTR_BASE + 0x0000)
+#define TFW_NVCTR_SIZE U(4)
+#define NTFW_CTR_BASE (SOC_TRUSTED_NVCTR_BASE + 0x0004)
+#define NTFW_CTR_SIZE U(4)
+
+/* Keys */
+#define SOC_KEYS_BASE UL(0x0EE80000)
+#define TZ_PUB_KEY_HASH_BASE (SOC_KEYS_BASE + 0x0000)
+#define TZ_PUB_KEY_HASH_SIZE U(32)
+#define HU_KEY_BASE (SOC_KEYS_BASE + 0x0020)
+#define HU_KEY_SIZE U(16)
+#define END_KEY_BASE (SOC_KEYS_BASE + 0x0044)
+#define END_KEY_SIZE U(32)
+
+#define SOC_PLATFORM_PERIPH_MAP_DEVICE MAP_REGION_FLAT( \
+ SOC_PLATFORM_PERIPH_BASE, \
+ SOC_PLATFORM_PERIPH_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define SOC_SYSTEM_PERIPH_MAP_DEVICE MAP_REGION_FLAT( \
+ SOC_SYSTEM_PERIPH_BASE, \
+ SOC_SYSTEM_PERIPH_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define SOC_MEMCNTRL_MAP_DEVICE MAP_REGION_FLAT( \
+ SOC_MEMCNTRL_BASE, \
+ SOC_MEMCNTRL_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+/*
+ * The bootsec_bridge controls access to a bunch of peripherals, e.g. the UARTs.
+ */
+#define SOC_CSS_NIC400_BOOTSEC_BRIDGE U(5)
+#define SOC_CSS_NIC400_BOOTSEC_BRIDGE_UART1 UL(1 << 12)
+
+/*
+ * Required platform porting definitions common to all ARM CSS SoCs
+ */
+/* 2MB used for SCP DDR retraining */
+#define PLAT_ARM_SCP_TZC_DRAM1_SIZE UL(0x00200000)
+
+/* V2M motherboard system registers & offsets */
+#define V2M_SYSREGS_BASE UL(0x0C010000)
+#define V2M_SYS_LED U(0x8)
+
+/*
+ * V2M sysled bit definitions. The values written to this
+ * register are defined in arch.h & runtime_svc.h. Only
+ * used by the primary cpu to diagnose any cold boot issues.
+ *
+ * SYS_LED[0] - Security state (S=0/NS=1)
+ * SYS_LED[2:1] - Exception Level (EL3-EL0)
+ * SYS_LED[7:3] - Exception Class (Sync/Async & origin)
+ *
+ */
+#define V2M_SYS_LED_SS_SHIFT U(0)
+#define V2M_SYS_LED_EL_SHIFT U(1)
+#define V2M_SYS_LED_EC_SHIFT U(3)
+
+#define V2M_SYS_LED_SS_MASK U(0x01)
+#define V2M_SYS_LED_EL_MASK U(0x03)
+#define V2M_SYS_LED_EC_MASK U(0x1f)
+
+/* NOR Flash */
+#define V2M_FLASH0_BASE UL(0x08000000)
+#define V2M_FLASH0_SIZE UL(0x04000000)
+#define V2M_FLASH_BLOCK_SIZE UL(0x00040000) /* 256 KB */
+
+/*
+ * The flash can be mapped either as read-only or read-write.
+ *
+ * If it is read-write then it should also be mapped as device memory because
+ * NOR flash programming involves sending a fixed, ordered sequence of commands.
+ *
+ * If it is read-only then it should also be mapped as:
+ * - Normal memory, because reading from NOR flash is transparent, it is like
+ * reading from RAM.
+ * - Non-executable by default. If some parts of the flash need to be executable
+ * then platform code is responsible for re-mapping the appropriate portion
+ * of it as executable.
+ */
+#define V2M_MAP_FLASH0_RW MAP_REGION_FLAT(V2M_FLASH0_BASE,\
+ V2M_FLASH0_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define V2M_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\
+ V2M_FLASH0_SIZE, \
+ MT_RO_DATA | MT_SECURE)
+
+#define SGI_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\
+ V2M_FLASH0_SIZE, \
+ MT_DEVICE | MT_RO | MT_SECURE)
+
+/* Platform ID address */
+#define BOARD_CSS_PLAT_ID_REG_ADDR UL(0x0EFE00E0)
+
+/* Platform ID related accessors */
+#define BOARD_CSS_PLAT_ID_REG_ID_MASK U(0x0F)
+#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT U(0x00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_MASK U(0xF00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_SHIFT U(0x08)
+#define BOARD_CSS_PLAT_TYPE_RTL U(0x00)
+#define BOARD_CSS_PLAT_TYPE_FPGA U(0x01)
+#define BOARD_CSS_PLAT_TYPE_EMULATOR U(0x02)
+#define BOARD_CSS_PLAT_TYPE_FVP U(0x03)
+
+#ifndef __ASSEMBLER__
+
+#include <lib/mmio.h>
+
+#define BOARD_CSS_GET_PLAT_TYPE(addr) \
+ ((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK) \
+ >> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
+
+#endif /* __ASSEMBLER__ */
+
+
+#define MAX_IO_DEVICES U(3)
+#define MAX_IO_HANDLES U(4)
+
+/* Reserve the last block of flash for PSCI MEM PROTECT flag */
+#define PLAT_ARM_FIP_BASE V2M_FLASH0_BASE
+#define PLAT_ARM_FIP_MAX_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE
+#define PLAT_ARM_NVM_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+/* UART related constants */
+#define PLAT_ARM_BOOT_UART_BASE SOC_CSS_UART0_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ SOC_CSS_UART0_CLK_IN_HZ
+
+#define PLAT_ARM_RUN_UART_BASE SOC_CSS_UART1_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ SOC_CSS_UART1_CLK_IN_HZ
+
+#define PLAT_ARM_SP_MIN_RUN_UART_BASE SOC_CSS_UART1_BASE
+#define PLAT_ARM_SP_MIN_RUN_UART_CLK_IN_HZ SOC_CSS_UART1_CLK_IN_HZ
+
+#define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ
+
+#endif /* SGI_SOC_CSS_DEF_V2_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def.h b/plat/arm/css/sgi/include/sgi_soc_platform_def.h
new file mode 100644
index 000000000..d7a839a52
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_soc_platform_def.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGI_SOC_PLATFORM_DEF_H
+#define SGI_SOC_PLATFORM_DEF_H
+
+#include <sgi_base_platform_def.h>
+#include <plat/arm/board/common/board_css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
+
+#endif /* SGI_SOC_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h
new file mode 100644
index 000000000..cb747c34a
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGI_SOC_PLATFORM_DEF_V2_H
+#define SGI_SOC_PLATFORM_DEF_V2_H
+
+#include <sgi_base_platform_def.h>
+#include <sgi_soc_css_def_v2.h>
+
+#endif /* SGI_SOC_PLATFORM_DEF_V2_H */
diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h
index c75f2132b..ecf6d93d6 100644
--- a/plat/arm/css/sgi/include/sgi_variant.h
+++ b/plat/arm/css/sgi/include/sgi_variant.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,16 +8,24 @@
#define SGI_VARIANT_H
/* SSC_VERSION values for SGI575 */
-#define SGI575_SSC_VER_PART_NUM 0x0783
+#define SGI575_SSC_VER_PART_NUM 0x0783
/* SID Version values for RD-N1E1-Edge */
#define RD_N1E1_EDGE_SID_VER_PART_NUM 0x0786
#define RD_E1_EDGE_CONFIG_ID 0x2
+/* SID Version values for RD-V1 */
+#define RD_V1_SID_VER_PART_NUM 0x078a
+
+/* SID Version values for RD-N2 */
+#define RD_N2_SID_VER_PART_NUM 0x07B7
+
/* Structure containing SGI platform variant information */
typedef struct sgi_platform_info {
unsigned int platform_id; /* Part Number of the platform */
unsigned int config_id; /* Config Id of the platform */
+ unsigned int chip_id; /* Chip Id or Node number */
+ unsigned int multi_chip_mode; /* Multi-chip mode availability */
} sgi_platform_info_t;
extern sgi_platform_info_t sgi_plat_info;
@@ -28,4 +36,7 @@ unsigned int plat_arm_sgi_get_platform_id(void);
/* returns the configuration id of the platform */
unsigned int plat_arm_sgi_get_config_id(void);
+/* returns true if operating in multi-chip configuration */
+unsigned int plat_arm_sgi_get_multi_chip_mode(void);
+
#endif /* SGI_VARIANT_H */
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 71601118f..615f53dc9 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -16,20 +16,23 @@ EL3_EXCEPTION_HANDLING := 0
HANDLE_EA_EL3_FIRST := 0
+CSS_SGI_CHIP_COUNT := 1
+
INTERCONNECT_SOURCES := ${CSS_ENT_BASE}/sgi_interconnect.c
PLAT_INCLUDES += -I${CSS_ENT_BASE}/include
-ENT_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/v3/gicv3_helpers.c \
- plat/common/plat_gicv3.c \
- plat/arm/common/arm_gicv3.c \
- drivers/arm/gic/v3/gic600.c
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600 := 1
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+ENT_GIC_SOURCES := ${GICV3_SOURCES} \
+ plat/common/plat_gicv3.c \
+ plat/arm/common/arm_gicv3.c
-PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c \
- ${CSS_ENT_BASE}/aarch64/sgi_helper.S
+PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/aarch64/sgi_helper.S
BL1_SOURCES += ${INTERCONNECT_SOURCES} \
drivers/arm/sbsa/sbsa.c
@@ -52,6 +55,8 @@ endif
$(eval $(call add_define,SGI_PLAT))
+$(eval $(call add_define,CSS_SGI_CHIP_COUNT))
+
override CSS_LOAD_SCP_IMAGES := 0
override NEED_BL2U := no
override ARM_BL31_IN_DRAM := 1
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index ba050d5f1..36c3fbb6c 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -28,18 +28,58 @@ static scmi_channel_plat_info_t sgi575_scmi_plat_info = {
.ring_doorbell = &mhu_ring_doorbell,
};
-static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info = {
+static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info[] = {
+ {
.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
.db_preserve_mask = 0xfffffffe,
.db_modify_mask = 0x1,
.ring_doorbell = &mhuv2_ring_doorbell,
+ },
+ #if (CSS_SGI_CHIP_COUNT > 1)
+ {
+ .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),
+ .db_reg_addr = PLAT_CSS_MHU_BASE
+ + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1) + SENDER_REG_SET(0),
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhuv2_ring_doorbell,
+ },
+ #endif
+ #if (CSS_SGI_CHIP_COUNT > 2)
+ {
+ .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2),
+ .db_reg_addr = PLAT_CSS_MHU_BASE +
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2) + SENDER_REG_SET(0),
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhuv2_ring_doorbell,
+ },
+ #endif
+ #if (CSS_SGI_CHIP_COUNT > 3)
+ {
+ .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3),
+ .db_reg_addr = PLAT_CSS_MHU_BASE +
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3) + SENDER_REG_SET(0),
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhuv2_ring_doorbell,
+ },
+ #endif
};
-scmi_channel_plat_info_t *plat_css_get_scmi_info(void)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
{
- if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM)
- return &rd_n1e1_edge_scmi_plat_info;
+ if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
+ sgi_plat_info.platform_id == RD_V1_SID_VER_PART_NUM ||
+ sgi_plat_info.platform_id == RD_N2_SID_VER_PART_NUM) {
+ if (channel_id >= ARRAY_SIZE(rd_n1e1_edge_scmi_plat_info))
+ panic();
+ return &rd_n1e1_edge_scmi_plat_info[channel_id];
+ }
else if (sgi_plat_info.platform_id == SGI575_SSC_VER_PART_NUM)
return &sgi575_scmi_plat_info;
else
@@ -51,11 +91,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
{
sgi_plat_info.platform_id = plat_arm_sgi_get_platform_id();
sgi_plat_info.config_id = plat_arm_sgi_get_config_id();
+ sgi_plat_info.multi_chip_mode = plat_arm_sgi_get_multi_chip_mode();
arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
}
-void bl31_platform_setup(void)
+void sgi_bl31_common_platform_setup(void)
{
arm_bl31_platform_setup();
@@ -66,9 +107,12 @@ void bl31_platform_setup(void)
const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
{
- /* For RD-E1-Edge platform only CPU ON/OFF is supported */
- if ((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) &&
- (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) {
+ /*
+ * For RD-E1-Edge, only CPU power ON/OFF, PSCI platform callbacks are
+ * supported.
+ */
+ if (((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) &&
+ (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID))) {
ops->cpu_standby = NULL;
ops->system_off = NULL;
ops->system_reset = NULL;
diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c
index a2f10dcc7..09f3b728d 100644
--- a/plat/arm/css/sgi/sgi_image_load.c
+++ b/plat/arm/css/sgi/sgi_image_load.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -62,6 +62,13 @@ static int plat_sgi_append_config_node(void)
return -1;
}
+ platcfg = plat_arm_sgi_get_multi_chip_mode();
+ err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg);
+ if (err < 0) {
+ ERROR("Failed to set multi-chip-mode\n");
+ return -1;
+ }
+
flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size);
return 0;
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index b611eaff5..39eb89eb8 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,7 +15,10 @@
#include <plat/common/platform.h>
#include <drivers/arm/sbsa.h>
#include <sgi_base_platform_def.h>
+
+#if SPM_MM
#include <services/spm_mm_partition.h>
+#endif
#define SGI_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\
V2M_FLASH0_SIZE, \
@@ -40,6 +43,9 @@ const mmap_region_t plat_arm_mmap[] = {
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
SGI_MAP_FLASH0_RO,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+ ARM_V2M_MAP_MEM_PROTECT,
+#endif
CSS_SGI_MAP_DEVICE,
SOC_CSS_MAP_DEVICE,
ARM_MAP_NS_DRAM1,
@@ -60,6 +66,9 @@ const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
V2M_MAP_IOFPGA,
CSS_SGI_MAP_DEVICE,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+ ARM_V2M_MAP_MEM_PROTECT,
+#endif
SOC_CSS_MAP_DEVICE,
#if SPM_MM
ARM_SPM_BUF_EL3_MMAP,
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c
new file mode 100644
index 000000000..a770255fc
--- /dev/null
+++ b/plat/arm/css/sgi/sgi_plat_v2.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <drivers/arm/sbsa.h>
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ */
+#if IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ SGI_MAP_FLASH0_RO,
+ CSS_SGI_MAP_DEVICE,
+ SOC_PLATFORM_PERIPH_MAP_DEVICE,
+ SOC_SYSTEM_PERIPH_MAP_DEVICE,
+ {0}
+};
+#endif
+
+#if IMAGE_BL2
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ SGI_MAP_FLASH0_RO,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+ ARM_V2M_MAP_MEM_PROTECT,
+#endif
+ CSS_SGI_MAP_DEVICE,
+ SOC_MEMCNTRL_MAP_DEVICE,
+ SOC_PLATFORM_PERIPH_MAP_DEVICE,
+ SOC_SYSTEM_PERIPH_MAP_DEVICE,
+ ARM_MAP_NS_DRAM1,
+#if ARM_BL31_IN_DRAM
+ ARM_MAP_BL31_SEC_DRAM,
+#endif
+#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
+ ARM_MAP_BL1_RW,
+#endif
+ {0}
+};
+#endif
+
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+ ARM_V2M_MAP_MEM_PROTECT,
+#endif
+ CSS_SGI_MAP_DEVICE,
+ SOC_PLATFORM_PERIPH_MAP_DEVICE,
+ SOC_SYSTEM_PERIPH_MAP_DEVICE,
+ {0}
+};
+
+#endif
+
+ARM_CASSERT_MMAP
+
+#if TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ assert(heap_addr != NULL);
+ assert(heap_size != NULL);
+
+ return arm_get_mbedtls_heap(heap_addr, heap_size);
+}
+#endif
+
+void plat_arm_secure_wdt_start(void)
+{
+ sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+ sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+}
diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c
index f56544e72..a04972d70 100644
--- a/plat/arm/css/sgi/sgi_ras.c
+++ b/plat/arm/css/sgi/sgi_ras.c
@@ -111,6 +111,7 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
struct sgi_ras_ev_map *ras_map;
mm_communicate_header_t *header;
uint32_t intr;
+ int ret;
cm_el1_sysregs_context_save(NON_SECURE);
intr = data->interrupt;
@@ -120,7 +121,7 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
* this interrupt
*/
ras_map = find_ras_event_map_by_intr(intr);
- assert(ras_map);
+ assert(ras_map != NULL);
/*
* Populate the MM_COMMUNICATE payload to share the
@@ -152,9 +153,20 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
plat_ic_end_of_interrupt(intr);
/* Dispatch the event to the SDEI client */
- sdei_dispatch_event(ras_map->sdei_ev_num);
+ ret = sdei_dispatch_event(ras_map->sdei_ev_num);
+ if (ret != 0) {
+ /*
+ * sdei_dispatch_event() may return failing result in some cases,
+ * for example kernel may not have registered a handler or RAS event
+ * may happen early during boot. We restore the NS context when
+ * sdei_dispatch_event() returns failing result.
+ */
+ ERROR("SDEI dispatch failed: %d", ret);
+ cm_el1_sysregs_context_restore(NON_SECURE);
+ cm_set_next_eret_context(NON_SECURE);
+ }
- return 0;
+ return ret;
}
int sgi_ras_intr_handler_setup(void)
diff --git a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
index d48101842..54b2423c1 100644
--- a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
+++ b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,7 +8,7 @@
/ {
/* Platform Config */
- plat_arm_bl2 {
+ tb_fw-config {
compatible = "arm,tb_fw";
hw_config_addr = <0x0 0x83000000>;
hw_config_max_size = <0x01000000>;
diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h
index 24bbed513..2d8e6778f 100644
--- a/plat/arm/css/sgm/include/sgm_base_platform_def.h
+++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -86,7 +86,6 @@
/* MHU related constants */
#define PLAT_CSS_MHU_BASE 0x2b1f0000
-#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
#define PLAT_ARM_TRUSTED_ROM_BASE 0x00000000
#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000
@@ -134,16 +133,14 @@
#endif
/*
- * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
- * SCP_BL2 size plus a little space for growth.
+ * SCP_BL2 uses up whatever remaining space is available as it is loaded before
+ * anything else in this memory region and is handed over to the SCP before
+ * BL31 is loaded over the top.
*/
-#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x15000
+#define PLAT_CSS_MAX_SCP_BL2_SIZE \
+ ((SCP_BL2_LIMIT - ARM_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK)
-/*
- * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
- * SCP_BL2U size plus a little space for growth.
- */
-#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x15000
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE
/*
* Most platform porting definitions provided by included headers
@@ -192,7 +189,7 @@
#if TRUSTED_BOARD_BOOT
# define PLAT_ARM_MAX_BL2_SIZE 0x1D000
#else
-# define PLAT_ARM_MAX_BL2_SIZE 0x11000
+# define PLAT_ARM_MAX_BL2_SIZE 0x12000
#endif
/*
@@ -239,4 +236,7 @@
/* System power domain level */
#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1)
+
#endif /* SGM_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk
index ac34450a7..5b954f842 100644
--- a/plat/arm/css/sgm/sgm-common.mk
+++ b/plat/arm/css/sgm/sgm-common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -22,13 +22,15 @@ SGM_CPU_SOURCES := lib/cpus/aarch64/cortex_a55.S \
INTERCONNECT_SOURCES := ${CSS_SGM_BASE}/sgm_interconnect.c
-SGM_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/v3/gicv3_helpers.c \
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600 := 1
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+SGM_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
- plat/arm/common/arm_gicv3.c \
- drivers/arm/gic/v3/gic600.c \
- drivers/arm/gic/v3/arm_gicv3_common.c
+ plat/arm/common/arm_gicv3.c
BL1_SOURCES += $(SGM_CPU_SOURCES) \
${INTERCONNECT_SOURCES} \
diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c
index 7e92ac835..907e9fdac 100644
--- a/plat/arm/css/sgm/sgm_bl31_setup.c
+++ b/plat/arm/css/sgm/sgm_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,7 +20,7 @@ static scmi_channel_plat_info_t sgm775_scmi_plat_info = {
.ring_doorbell = &mhu_ring_doorbell,
};
-scmi_channel_plat_info_t *plat_css_get_scmi_info()
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
{
return &sgm775_scmi_plat_info;
}
diff --git a/plat/brcm/board/common/bcm_console.c b/plat/brcm/board/common/bcm_console.c
new file mode 100644
index 000000000..5f2009403
--- /dev/null
+++ b/plat/brcm/board/common/bcm_console.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/ti/uart/uart_16550.h>
+
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Functions that set up the console
+ ******************************************************************************/
+static console_t bcm_boot_console;
+static console_t bcm_runtime_console;
+
+/* Initialize the console to provide early debug support */
+void bcm_console_boot_init(void)
+{
+ int rc = console_16550_register(PLAT_BRCM_BOOT_UART_BASE,
+ PLAT_BRCM_BOOT_UART_CLK_IN_HZ,
+ BRCM_CONSOLE_BAUDRATE,
+ &bcm_boot_console);
+ if (rc == 0) {
+ /*
+ * The crash console doesn't use the multi console API, it uses
+ * the core console functions directly. It is safe to call panic
+ * and let it print debug information.
+ */
+ panic();
+ }
+
+ console_set_scope(&bcm_boot_console, CONSOLE_FLAG_BOOT);
+}
+
+void bcm_console_boot_end(void)
+{
+ console_flush();
+
+ (void)console_unregister(&bcm_boot_console);
+}
+
+/* Initialize the runtime console */
+void bcm_console_runtime_init(void)
+{
+ int rc = console_16550_register(PLAT_BRCM_BL31_RUN_UART_BASE,
+ PLAT_BRCM_BL31_RUN_UART_CLK_IN_HZ,
+ BRCM_CONSOLE_BAUDRATE,
+ &bcm_runtime_console);
+ if (rc == 0)
+ panic();
+
+ console_set_scope(&bcm_runtime_console, CONSOLE_FLAG_RUNTIME);
+}
+
+void bcm_console_runtime_end(void)
+{
+ console_flush();
+
+ (void)console_unregister(&bcm_runtime_console);
+}
diff --git a/plat/brcm/board/common/bcm_elog.c b/plat/brcm/board/common/bcm_elog.c
new file mode 100644
index 000000000..093157ef0
--- /dev/null
+++ b/plat/brcm/board/common/bcm_elog.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2018 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <plat/common/platform.h>
+
+#include <bcm_elog.h>
+
+/* error logging signature */
+#define BCM_ELOG_SIG_OFFSET 0x0000
+#define BCM_ELOG_SIG_VAL 0x75767971
+
+/* current logging offset that points to where new logs should be added */
+#define BCM_ELOG_OFF_OFFSET 0x0004
+
+/* current logging length (excluding header) */
+#define BCM_ELOG_LEN_OFFSET 0x0008
+
+#define BCM_ELOG_HEADER_LEN 12
+
+/*
+ * @base: base address of memory where log is saved
+ * @max_size: max size of memory reserved for logging
+ * @is_active: indicates logging is currently active
+ * @level: current logging level
+ */
+struct bcm_elog {
+ uintptr_t base;
+ uint32_t max_size;
+ unsigned int is_active;
+ unsigned int level;
+};
+
+static struct bcm_elog global_elog;
+
+extern void memcpy16(void *dst, const void *src, unsigned int len);
+
+/*
+ * Log one character
+ */
+static void elog_putchar(struct bcm_elog *elog, unsigned char c)
+{
+ uint32_t offset, len;
+
+ offset = mmio_read_32(elog->base + BCM_ELOG_OFF_OFFSET);
+ len = mmio_read_32(elog->base + BCM_ELOG_LEN_OFFSET);
+ mmio_write_8(elog->base + offset, c);
+ offset++;
+
+ /* log buffer is now full and need to wrap around */
+ if (offset >= elog->max_size)
+ offset = BCM_ELOG_HEADER_LEN;
+
+ /* only increment length when log buffer is not full */
+ if (len < elog->max_size - BCM_ELOG_HEADER_LEN)
+ len++;
+
+ mmio_write_32(elog->base + BCM_ELOG_OFF_OFFSET, offset);
+ mmio_write_32(elog->base + BCM_ELOG_LEN_OFFSET, len);
+}
+
+static void elog_unsigned_num(struct bcm_elog *elog, unsigned long unum,
+ unsigned int radix)
+{
+ /* Just need enough space to store 64 bit decimal integer */
+ unsigned char num_buf[20];
+ int i = 0, rem;
+
+ do {
+ rem = unum % radix;
+ if (rem < 0xa)
+ num_buf[i++] = '0' + rem;
+ else
+ num_buf[i++] = 'a' + (rem - 0xa);
+ } while (unum /= radix);
+
+ while (--i >= 0)
+ elog_putchar(elog, num_buf[i]);
+}
+
+static void elog_string(struct bcm_elog *elog, const char *str)
+{
+ while (*str)
+ elog_putchar(elog, *str++);
+}
+
+/*
+ * Routine to initialize error logging
+ */
+int bcm_elog_init(void *base, uint32_t size, unsigned int level)
+{
+ struct bcm_elog *elog = &global_elog;
+ uint32_t val;
+
+ elog->base = (uintptr_t)base;
+ elog->max_size = size;
+ elog->is_active = 1;
+ elog->level = level / 10;
+
+ /*
+ * If a valid signature can be found, it means logs have been copied
+ * into designated memory by another software. In this case, we should
+ * not re-initialize the entry header in the designated memory
+ */
+ val = mmio_read_32(elog->base + BCM_ELOG_SIG_OFFSET);
+ if (val != BCM_ELOG_SIG_VAL) {
+ mmio_write_32(elog->base + BCM_ELOG_SIG_OFFSET,
+ BCM_ELOG_SIG_VAL);
+ mmio_write_32(elog->base + BCM_ELOG_OFF_OFFSET,
+ BCM_ELOG_HEADER_LEN);
+ mmio_write_32(elog->base + BCM_ELOG_LEN_OFFSET, 0);
+ }
+
+ return 0;
+}
+
+/*
+ * Routine to disable error logging
+ */
+void bcm_elog_exit(void)
+{
+ struct bcm_elog *elog = &global_elog;
+
+ if (!elog->is_active)
+ return;
+
+ elog->is_active = 0;
+
+ flush_dcache_range(elog->base, elog->max_size);
+}
+
+/*
+ * Routine to copy error logs from current memory to 'dst' memory and continue
+ * logging from the new 'dst' memory.
+ * dst and base addresses must be 16-bytes aligned.
+ */
+int bcm_elog_copy_log(void *dst, uint32_t max_size)
+{
+ struct bcm_elog *elog = &global_elog;
+ uint32_t offset, len;
+
+ if (!elog->is_active || ((uintptr_t)dst == elog->base))
+ return -1;
+
+ /* flush cache before copying logs */
+ flush_dcache_range(elog->base, max_size);
+
+ /*
+ * If current offset exceeds the new max size, then that is considered
+ * as a buffer overflow situation. In this case, we reset the offset
+ * back to the beginning
+ */
+ offset = mmio_read_32(elog->base + BCM_ELOG_OFF_OFFSET);
+ if (offset >= max_size) {
+ offset = BCM_ELOG_HEADER_LEN;
+ mmio_write_32(elog->base + BCM_ELOG_OFF_OFFSET, offset);
+ }
+
+ /* note payload length does not include header */
+ len = mmio_read_32(elog->base + BCM_ELOG_LEN_OFFSET);
+ if (len > max_size - BCM_ELOG_HEADER_LEN) {
+ len = max_size - BCM_ELOG_HEADER_LEN;
+ mmio_write_32(elog->base + BCM_ELOG_LEN_OFFSET, len);
+ }
+
+ /* Need to copy everything including the header. */
+ memcpy16(dst, (const void *)elog->base, len + BCM_ELOG_HEADER_LEN);
+ elog->base = (uintptr_t)dst;
+ elog->max_size = max_size;
+
+ return 0;
+}
+
+/*
+ * Main routine to save logs into memory
+ */
+void bcm_elog(const char *fmt, ...)
+{
+ va_list args;
+ const char *prefix_str;
+ int bit64;
+ int64_t num;
+ uint64_t unum;
+ char *str;
+ struct bcm_elog *elog = &global_elog;
+
+ /* We expect the LOG_MARKER_* macro as the first character */
+ unsigned int level = fmt[0];
+
+ if (!elog->is_active || level > elog->level)
+ return;
+
+ prefix_str = plat_log_get_prefix(level);
+
+ while (*prefix_str != '\0') {
+ elog_putchar(elog, *prefix_str);
+ prefix_str++;
+ }
+
+ va_start(args, fmt);
+ fmt++;
+ while (*fmt) {
+ bit64 = 0;
+
+ if (*fmt == '%') {
+ fmt++;
+ /* Check the format specifier */
+loop:
+ switch (*fmt) {
+ case 'i': /* Fall through to next one */
+ case 'd':
+ if (bit64)
+ num = va_arg(args, int64_t);
+ else
+ num = va_arg(args, int32_t);
+
+ if (num < 0) {
+ elog_putchar(elog, '-');
+ unum = (unsigned long)-num;
+ } else
+ unum = (unsigned long)num;
+
+ elog_unsigned_num(elog, unum, 10);
+ break;
+ case 's':
+ str = va_arg(args, char *);
+ elog_string(elog, str);
+ break;
+ case 'x':
+ if (bit64)
+ unum = va_arg(args, uint64_t);
+ else
+ unum = va_arg(args, uint32_t);
+
+ elog_unsigned_num(elog, unum, 16);
+ break;
+ case 'l':
+ bit64 = 1;
+ fmt++;
+ goto loop;
+ case 'u':
+ if (bit64)
+ unum = va_arg(args, uint64_t);
+ else
+ unum = va_arg(args, uint32_t);
+
+ elog_unsigned_num(elog, unum, 10);
+ break;
+ default:
+ /* Exit on any other format specifier */
+ goto exit;
+ }
+ fmt++;
+ continue;
+ }
+ elog_putchar(elog, *fmt++);
+ }
+exit:
+ va_end(args);
+}
diff --git a/plat/brcm/board/common/bcm_elog_ddr.c b/plat/brcm/board/common/bcm_elog_ddr.c
new file mode 100644
index 000000000..89e7bff8f
--- /dev/null
+++ b/plat/brcm/board/common/bcm_elog_ddr.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2019-2020 Broadcom.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+
+#include <ddr_init.h>
+#include <scp_cmd.h>
+#include <scp_utils.h>
+#include <platform_def.h>
+
+#include "bcm_elog_ddr.h"
+#include "m0_cfg.h"
+#include "m0_ipc.h"
+
+void elog_init_ddr_log(void)
+{
+ struct elog_setup setup = {0};
+ struct elog_global_header global;
+ struct elog_meta_record rec;
+ unsigned int rec_idx = 0;
+ uint32_t log_offset;
+ uintptr_t metadata;
+ char *rec_desc[ELOG_SUPPORTED_REC_CNT] = {"SYSRESET", "THERMAL",
+ "DDR_ECC", "APBOOTLG",
+ "IDM"};
+
+ /*
+ * If this is warm boot, return immediately.
+ * We expect metadata to be initialized already
+ */
+ if (is_warmboot()) {
+ WARN("Warmboot detected, skip ELOG metadata initialization\n");
+ return;
+ }
+
+ memset(&global, 0, sizeof(global));
+
+ global.sector_size = ELOG_SECTOR_SIZE;
+ global.signature = ELOG_GLOBAL_META_HDR_SIG;
+ global.rec_count = ELOG_SUPPORTED_REC_CNT;
+
+ /* Start of logging area in DDR memory */
+ log_offset = ELOG_STORE_OFFSET;
+
+ /* Shift to the first RECORD header */
+ log_offset += 2 * global.sector_size;
+
+ /* Temporary place to hold metadata */
+ metadata = TMP_ELOG_METADATA_BASE;
+
+ memcpy((void *)metadata, &global, sizeof(global));
+ metadata += sizeof(global);
+
+ while (rec_idx < global.rec_count) {
+ memset(&rec, 0, sizeof(rec));
+
+ rec.type = rec_idx;
+ if (rec_idx == ELOG_REC_UART_LOG) {
+ rec.format = ELOG_REC_FMT_ASCII;
+ rec.src_mem_type = ELOG_SRC_MEM_TYPE_DDR;
+ rec.alt_src_mem_type = ELOG_SRC_MEM_TYPE_FS4_SCRATCH;
+ rec.src_mem_addr = BCM_ELOG_BL31_BASE;
+ rec.alt_src_mem_addr = BCM_ELOG_BL2_BASE;
+ rec.rec_size = ELOG_APBOOTLG_REC_SIZE;
+ } else if (rec_idx == ELOG_REC_IDM_LOG) {
+ rec.type = IDM_ELOG_REC_TYPE;
+ rec.format = ELOG_REC_FMT_CUSTOM;
+ rec.src_mem_type = ELOG_SRC_MEM_TYPE_DDR;
+ rec.alt_src_mem_type = ELOG_SRC_MEM_TYPE_CRMU_SCRATCH;
+ rec.src_mem_addr = ELOG_IDM_SRC_MEM_ADDR;
+ rec.alt_src_mem_addr = 0x0;
+ rec.rec_size = ELOG_DEFAULT_REC_SIZE;
+ } else {
+ rec.format = ELOG_REC_FMT_CUSTOM;
+ rec.src_mem_type = ELOG_SRC_MEM_TYPE_CRMU_SCRATCH;
+ rec.alt_src_mem_type = ELOG_SRC_MEM_TYPE_CRMU_SCRATCH;
+ rec.src_mem_addr = ELOG_USE_DEFAULT_MEM_ADDR;
+ rec.alt_src_mem_addr = ELOG_USE_DEFAULT_MEM_ADDR;
+ rec.rec_size = ELOG_DEFAULT_REC_SIZE;
+ }
+
+ rec.nvm_type = LOG_MEDIA_DDR;
+ rec.sector_size = ELOG_SECTOR_SIZE;
+
+ rec.rec_addr = (uint64_t)log_offset;
+ log_offset += rec.rec_size;
+
+ /* Sanity checks */
+ if (rec.type > ELOG_MAX_REC_COUNT ||
+ rec.format > ELOG_MAX_REC_FORMAT ||
+ (rec.nvm_type > ELOG_MAX_NVM_TYPE &&
+ rec.nvm_type != ELOG_NVM_DEFAULT) ||
+ !rec.rec_size ||
+ !rec.sector_size ||
+ rec_idx >= ELOG_SUPPORTED_REC_CNT) {
+ ERROR("Invalid ELOG record(%u) detected\n", rec_idx);
+ return;
+ }
+
+ memset(rec.rec_desc, ' ', sizeof(rec.rec_desc));
+
+ memcpy(rec.rec_desc, rec_desc[rec_idx],
+ strlen(rec_desc[rec_idx]));
+
+ memcpy((void *)metadata, &rec, sizeof(rec));
+ metadata += sizeof(rec);
+
+ rec_idx++;
+ }
+
+ setup.params[0] = TMP_ELOG_METADATA_BASE;
+ setup.params[1] = (sizeof(global) + global.rec_count * sizeof(rec));
+ setup.cmd = ELOG_SETUP_CMD_WRITE_META;
+
+ flush_dcache_range((uintptr_t)&setup, sizeof(struct elog_setup));
+ flush_dcache_range((uintptr_t)setup.params[0], setup.params[1]);
+
+ /* initialize DDR Logging METADATA if this is NOT warmboot */
+ if (!is_warmboot()) {
+ if (scp_send_cmd(MCU_IPC_MCU_CMD_ELOG_SETUP,
+ (uint32_t)(uintptr_t)(&setup),
+ SCP_CMD_DEFAULT_TIMEOUT_US)) {
+ ERROR("scp_send_cmd: timeout/error for elog setup\n");
+ return;
+ }
+ }
+
+ NOTICE("MCU Error logging initialized\n");
+}
diff --git a/plat/brcm/board/common/bcm_elog_ddr.h b/plat/brcm/board/common/bcm_elog_ddr.h
new file mode 100644
index 000000000..6f21a680d
--- /dev/null
+++ b/plat/brcm/board/common/bcm_elog_ddr.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2019-2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BCM_ELOG_DDR_H
+#define BCM_ELOG_DDR_H
+
+#define ELOG_GLOBAL_META_HDR_SIG 0x45524c47
+#define ELOG_MAX_REC_COUNT 13
+#define ELOG_MAX_REC_FORMAT 1
+#define ELOG_MAX_NVM_TYPE 4
+/* Use a default NVM, set by m0 configuration */
+#define ELOG_NVM_DEFAULT 0xff
+
+/* Max. number of cmd parameters per elog spec */
+#define ELOG_PARAM_COUNT 3
+/*
+ * Number of supported RECORD Types-
+ * SYSRESET, THERMAL, DDR_ECC, APBOOTLG, IDM
+ */
+#define ELOG_SUPPORTED_REC_CNT 5
+
+#define ELOG_REC_DESC_LENGTH 8
+
+#define ELOG_SECTOR_SIZE 0x1000
+
+/* Default Record size for all record types except APBOOTLOG */
+#define ELOG_DEFAULT_REC_SIZE 0x10000
+
+/* Default record size for APBOOTLOG record */
+#define ELOG_APBOOTLG_REC_SIZE 0x60000
+
+/* Use default CRMU provided mem address */
+#define ELOG_USE_DEFAULT_MEM_ADDR 0x0
+
+/* Temporary place to hold metadata */
+#define TMP_ELOG_METADATA_BASE (ELOG_AP_UART_LOG_BASE + \
+ BCM_ELOG_BL2_SIZE)
+/* IDM ELOG source memory address */
+#define ELOG_IDM_SRC_MEM_ADDR 0x8f213000
+
+#define IDM_ELOG_REC_TYPE 5
+
+enum elog_record_type {
+ ELOG_REC_SYS_RESET_EVT = 0,
+ ELOG_REC_THERMAL_EVT,
+ ELOG_REC_DDR_ECC,
+ ELOG_REC_UART_LOG,
+ ELOG_REC_IDM_LOG,
+ ELOG_REC_MAX
+};
+
+enum elog_record_format {
+ ELOG_REC_FMT_ASCII = 0,
+ ELOG_REC_FMT_CUSTOM
+};
+
+enum elog_src_memory_type {
+ ELOG_SRC_MEM_TYPE_CRMU_SCRATCH = 0,
+ ELOG_SRC_MEM_TYPE_FS4_SCRATCH,
+ ELOG_SRC_MEM_TYPE_DDR,
+ ELOG_SRC_MEM_TYPE_CHIMP_SCRATCH
+};
+
+enum elog_setup_cmd {
+ ELOG_SETUP_CMD_VALIDATE_META,
+ ELOG_SETUP_CMD_WRITE_META,
+ ELOG_SETUP_CMD_ERASE,
+ ELOG_SETUP_CMD_READ,
+ ELOG_SETUP_CMD_CHECK
+};
+
+struct elog_setup {
+ uint32_t cmd;
+ uint32_t params[ELOG_PARAM_COUNT];
+ uint32_t result;
+ uint32_t ret_code;
+};
+
+struct elog_meta_record {
+ uint8_t type;
+ uint8_t format;
+ uint8_t src_mem_type;
+ uint8_t alt_src_mem_type;
+ uint8_t nvm_type;
+ char rec_desc[ELOG_REC_DESC_LENGTH];
+ uint64_t src_mem_addr;
+ uint64_t alt_src_mem_addr;
+ uint64_t rec_addr;
+ uint32_t rec_size;
+ uint32_t sector_size;
+ uint8_t padding[3];
+} __packed;
+
+struct elog_global_header {
+ uint32_t signature;
+ uint32_t sector_size;
+ uint8_t revision;
+ uint8_t rec_count;
+ uint16_t padding;
+} __packed;
+
+void elog_init_ddr_log(void);
+
+#endif /* BCM_ELOG_DDR_H */
diff --git a/plat/brcm/board/common/board_arm_trusted_boot.c b/plat/brcm/board/common/board_arm_trusted_boot.c
new file mode 100644
index 000000000..7a4dad013
--- /dev/null
+++ b/plat/brcm/board/common/board_arm_trusted_boot.c
@@ -0,0 +1,624 @@
+/*
+ * Copyright 2015 - 2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <tools_share/tbbr_oid.h>
+
+#include <sbl_util.h>
+#include <sotp.h>
+
+/* Weak definition may be overridden in specific platform */
+#pragma weak plat_match_rotpk
+#pragma weak plat_get_nv_ctr
+#pragma weak plat_set_nv_ctr
+
+/* SHA256 algorithm */
+#define SHA256_BYTES 32
+
+/* ROTPK locations */
+#define ARM_ROTPK_REGS_ID 1
+#define ARM_ROTPK_DEVEL_RSA_ID 2
+#define BRCM_ROTPK_SOTP_RSA_ID 3
+
+#if !ARM_ROTPK_LOCATION_ID
+ #error "ARM_ROTPK_LOCATION_ID not defined"
+#endif
+
+static const unsigned char rotpk_hash_hdr[] =
+ "\x30\x31\x30\x0D\x06\x09\x60\x86\x48"
+ "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
+static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1;
+static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES];
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
+static const unsigned char arm_devel_rotpk_hash[] =
+ "\xB0\xF3\x82\x09\x12\x97\xD8\x3A"
+ "\x37\x7A\x72\x47\x1B\xEC\x32\x73"
+ "\xE9\x92\x32\xE2\x49\x59\xF6\x5E"
+ "\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA";
+#endif
+
+#pragma weak plat_rotpk_hash
+const unsigned char plat_rotpk_hash[] =
+ "\xdb\x06\x67\x95\x4f\x88\x2b\x88"
+ "\x49\xbf\x70\x3f\xde\x50\x4a\x96"
+ "\xd8\x17\x69\xd4\xa0\x6c\xba\xee"
+ "\x66\x3e\x71\x82\x2d\x95\x69\xe4";
+
+#pragma weak rom_slice
+const unsigned char rom_slice[] =
+ "\x77\x06\xbc\x98\x40\xbe\xfd\xab"
+ "\x60\x4b\x74\x3c\x9a\xb3\x80\x75"
+ "\x39\xb6\xda\x27\x07\x2e\x5b\xbf"
+ "\x5c\x47\x91\xc9\x95\x26\x26\x0c";
+
+#if (ARM_ROTPK_LOCATION_ID == BRCM_ROTPK_SOTP_RSA_ID)
+static int plat_is_trusted_boot(void)
+{
+ uint64_t section3_row0_data;
+
+ section3_row0_data = sotp_mem_read(SOTP_DEVICE_SECURE_CFG0_ROW, 0);
+
+ if ((section3_row0_data & SOTP_DEVICE_SECURE_CFG0_AB_MASK) == 0) {
+ INFO("NOT AB\n");
+ return 0;
+ }
+
+ INFO("AB\n");
+ return TRUSTED_BOARD_BOOT;
+}
+
+/*
+ * FAST AUTH is enabled if all following conditions are met:
+ * - AB part
+ * - SOTP.DEV != 0
+ * - SOTP.CID != 0
+ * - SOTP.ENC_DEV_TYPE = ENC_AB_DEV
+ * - Manuf_debug strap set high
+ */
+static int plat_fast_auth_enabled(void)
+{
+ uint32_t chip_state;
+ uint64_t section3_row0_data;
+ uint64_t section3_row1_data;
+
+ section3_row0_data =
+ sotp_mem_read(SOTP_DEVICE_SECURE_CFG0_ROW, 0);
+ section3_row1_data =
+ sotp_mem_read(SOTP_DEVICE_SECURE_CFG1_ROW, 0);
+
+ chip_state = mmio_read_32(SOTP_REGS_SOTP_CHIP_STATES);
+
+ if (plat_is_trusted_boot() &&
+ (section3_row0_data & SOTP_DEVICE_SECURE_CFG0_DEV_MASK) &&
+ (section3_row0_data & SOTP_DEVICE_SECURE_CFG0_CID_MASK) &&
+ ((section3_row1_data & SOTP_ENC_DEV_TYPE_MASK) ==
+ SOTP_ENC_DEV_TYPE_AB_DEV) &&
+ (chip_state & SOTP_CHIP_STATES_MANU_DEBUG_MASK))
+ return 1;
+
+ return 0;
+}
+#endif
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ uint8_t *dst;
+
+ assert(key_ptr != NULL);
+ assert(key_len != NULL);
+ assert(flags != NULL);
+
+ *flags = 0;
+
+ /* Copy the DER header */
+ memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
+ dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len];
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
+ memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES);
+#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+ uint32_t *src, tmp;
+ unsigned int words, i;
+
+ /*
+ * Append the hash from Trusted Root-Key Storage registers. The hash has
+ * not been written linearly into the registers, so we have to do a bit
+ * of byte swapping:
+ *
+ * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C
+ * +---------------------------------------------------------------+
+ * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 |
+ * +---------------------------------------------------------------+
+ * | ... ... | | ... ... |
+ * | +--------------------+ | +-------+
+ * | | | |
+ * +----------------------------+ +----------------------------+
+ * | | | |
+ * +-------+ | +--------------------+ |
+ * | | | |
+ * v v v v
+ * +---------------------------------------------------------------+
+ * | | |
+ * +---------------------------------------------------------------+
+ * 0 15 16 31
+ *
+ * Additionally, we have to access the registers in 32-bit words
+ */
+ words = SHA256_BYTES >> 3;
+
+ /* Swap bytes 0-15 (first four registers) */
+ src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
+ for (i = 0 ; i < words ; i++) {
+ tmp = src[words - 1 - i];
+ /* Words are read in little endian */
+ *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
+ *dst++ = (uint8_t)(tmp & 0xFF);
+ }
+
+ /* Swap bytes 16-31 (last four registers) */
+ src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2);
+ for (i = 0 ; i < words ; i++) {
+ tmp = src[words - 1 - i];
+ *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
+ *dst++ = (uint8_t)(tmp & 0xFF);
+ }
+#elif (ARM_ROTPK_LOCATION_ID == BRCM_ROTPK_SOTP_RSA_ID)
+{
+ int i;
+ int ret = -1;
+
+ /*
+ * In non-AB mode, we do not read the key.
+ * In AB mode:
+ * - The Dauth is in BL11 if SBL is enabled
+ * - The Dauth is in SOTP if SBL is disabled.
+ */
+ if (plat_is_trusted_boot() == 0) {
+
+ INFO("NON-AB: Do not read DAUTH!\n");
+ *flags = ROTPK_NOT_DEPLOYED;
+ ret = 0;
+
+ } else if ((sbl_status() == SBL_ENABLED) &&
+ (mmio_read_32(BL11_DAUTH_BASE) == BL11_DAUTH_ID)) {
+
+ /* Read hash from BL11 */
+ INFO("readKeys (DAUTH) from BL11\n");
+
+ memcpy(dst,
+ (void *)(BL11_DAUTH_BASE + sizeof(uint32_t)),
+ SHA256_BYTES);
+
+ for (i = 0; i < SHA256_BYTES; i++)
+ if (dst[i] != 0)
+ break;
+
+ if (i >= SHA256_BYTES)
+ ERROR("Hash not valid from BL11\n");
+ else
+ ret = 0;
+
+ } else if (sotp_key_erased()) {
+
+ memcpy(dst, plat_rotpk_hash, SHA256_BYTES);
+
+ INFO("SOTP erased, Use internal key hash.\n");
+ ret = 0;
+
+ } else if (plat_fast_auth_enabled()) {
+
+ INFO("AB DEV: FAST AUTH!\n");
+ *flags = ROTPK_NOT_DEPLOYED;
+ ret = 0;
+
+ } else if (!(mmio_read_32(SOTP_STATUS_1) & SOTP_DAUTH_ECC_ERROR_MASK)) {
+
+ /* Read hash from SOTP */
+ ret = sotp_read_key(dst,
+ SHA256_BYTES,
+ SOTP_DAUTH_ROW,
+ SOTP_K_HMAC_ROW-1);
+
+ INFO("sotp_read_key (DAUTH): %i\n", ret);
+
+ } else {
+
+ uint64_t row_data;
+ uint32_t k;
+
+ for (k = 0; k < (SOTP_K_HMAC_ROW - SOTP_DAUTH_ROW); k++) {
+ row_data = sotp_mem_read(SOTP_DAUTH_ROW + k,
+ SOTP_ROW_NO_ECC);
+
+ if (row_data != 0)
+ break;
+ }
+
+ if (k == (SOTP_K_HMAC_ROW - SOTP_DAUTH_ROW)) {
+ INFO("SOTP NOT PROGRAMMED: Do not use DAUTH!\n");
+
+ if (sotp_mem_read(SOTP_ATF2_CFG_ROW_ID,
+ SOTP_ROW_NO_ECC) & SOTP_ROMKEY_MASK) {
+ memcpy(dst, plat_rotpk_hash, SHA256_BYTES);
+
+ INFO("Use internal key hash.\n");
+ ret = 0;
+ } else {
+ *flags = ROTPK_NOT_DEPLOYED;
+ ret = 0;
+ }
+ } else {
+ INFO("No hash found in SOTP\n");
+ }
+ }
+ if (ret)
+ return ret;
+}
+#endif
+
+ *key_ptr = (void *)rotpk_hash_der;
+ *key_len = (unsigned int)sizeof(rotpk_hash_der);
+ *flags |= ROTPK_IS_HASH;
+
+ return 0;
+}
+
+#define SOTP_NUM_BITS_PER_ROW 41
+#define SOTP_NVCTR_ROW_ALL_ONES 0x1ffffffffff
+#define SOTP_NVCTR_TRUSTED_IN_USE \
+ ((uint64_t)0x3 << (SOTP_NUM_BITS_PER_ROW-2))
+#define SOTP_NVCTR_NON_TRUSTED_IN_USE ((uint64_t)0x3)
+#define SOTP_NVCTR_TRUSTED_NEAR_END SOTP_NVCTR_NON_TRUSTED_IN_USE
+#define SOTP_NVCTR_NON_TRUSTED_NEAR_END SOTP_NVCTR_TRUSTED_IN_USE
+
+#define SOTP_NVCTR_ROW_START 64
+#define SOTP_NVCTR_ROW_END 75
+
+/*
+ * SOTP NVCTR are stored in section 10 of SOTP (rows 64-75).
+ * Each row of SOTP is 41 bits.
+ * NVCTR's are stored in a bitstream format.
+ * We are tolerant to consecutive bit errors.
+ * Trusted NVCTR starts at the top of row 64 in bitstream format.
+ * Non Trusted NVCTR starts at the bottom of row 75 in reverse bitstream.
+ * Each row can only be used by 1 of the 2 counters. This is determined
+ * by 2 zeros remaining at the beginning or end of the last available row.
+ * If one counter has already starting using a row, the other will be
+ * prevent from writing to that row.
+ *
+ * Example counter values for SOTP programmed below:
+ * Trusted Counter (rows64-69) = 5 * 41 + 40 = 245
+ * NonTrusted Counter (row75-71) = 3 * 41 + 4 = 127
+ * 40 39 38 37 36 ..... 5 4 3 2 1 0
+ * row 64 1 1 1 1 1 1 1 1 1 1 1
+ * row 65 1 1 1 1 1 1 1 1 1 1 1
+ * row 66 1 1 1 1 1 1 1 1 1 1 1
+ * row 67 1 1 1 1 1 1 1 1 1 1 1
+ * row 68 1 1 1 1 1 1 1 1 1 1 1
+ * row 69 1 1 1 1 1 1 1 1 1 1 0
+ * row 71 0 0 0 0 0 0 0 0 0 0 0
+ * row 71 0 0 0 0 0 0 0 0 0 0 0
+ * row 71 0 0 0 0 0 0 0 1 1 1 1
+ * row 73 1 1 1 1 1 1 1 1 1 1 1
+ * row 74 1 1 1 1 1 1 1 1 1 1 1
+ * row 75 1 1 1 1 1 1 1 1 1 1 1
+ *
+ */
+
+#if (DEBUG == 1)
+/*
+ * Dump sotp rows
+ */
+void sotp_dump_rows(uint32_t start_row, uint32_t end_row)
+{
+ int32_t rownum;
+ uint64_t rowdata;
+
+ for (rownum = start_row; rownum <= end_row; rownum++) {
+ rowdata = sotp_mem_read(rownum, SOTP_ROW_NO_ECC);
+ INFO("%d 0x%llx\n", rownum, rowdata);
+ }
+}
+#endif
+
+/*
+ * Get SOTP Trusted nvctr
+ */
+unsigned int sotp_get_trusted_nvctr(void)
+{
+ uint64_t rowdata;
+ uint64_t nextrowdata;
+ uint32_t rownum;
+ unsigned int nvctr;
+
+ rownum = SOTP_NVCTR_ROW_START;
+ nvctr = SOTP_NUM_BITS_PER_ROW;
+
+ /*
+ * Determine what row has last valid data for trusted ctr
+ */
+ rowdata = sotp_mem_read(rownum, SOTP_ROW_NO_ECC);
+ while ((rowdata & SOTP_NVCTR_TRUSTED_IN_USE) &&
+ (rowdata & SOTP_NVCTR_TRUSTED_NEAR_END) &&
+ (rownum < SOTP_NVCTR_ROW_END)) {
+ /*
+ * Current row in use and has data in last 2 bits as well.
+ * Check if next row also has data for this counter
+ */
+ nextrowdata = sotp_mem_read(rownum+1, SOTP_ROW_NO_ECC);
+ if (nextrowdata & SOTP_NVCTR_TRUSTED_IN_USE) {
+ /* Next row also has data so increment rownum */
+ rownum++;
+ nvctr += SOTP_NUM_BITS_PER_ROW;
+ rowdata = nextrowdata;
+ } else {
+ /* Next row does not have data */
+ break;
+ }
+ }
+
+ if (rowdata & SOTP_NVCTR_TRUSTED_IN_USE) {
+ while ((rowdata & 0x1) == 0) {
+ nvctr--;
+ rowdata >>= 1;
+ }
+ } else
+ nvctr -= SOTP_NUM_BITS_PER_ROW;
+
+ INFO("CTR %i\n", nvctr);
+ return nvctr;
+}
+
+/*
+ * Get SOTP NonTrusted nvctr
+ */
+unsigned int sotp_get_nontrusted_nvctr(void)
+{
+ uint64_t rowdata;
+ uint64_t nextrowdata;
+ uint32_t rownum;
+ unsigned int nvctr;
+
+ nvctr = SOTP_NUM_BITS_PER_ROW;
+ rownum = SOTP_NVCTR_ROW_END;
+
+ /*
+ * Determine what row has last valid data for nontrusted ctr
+ */
+ rowdata = sotp_mem_read(rownum, SOTP_ROW_NO_ECC);
+ while ((rowdata & SOTP_NVCTR_NON_TRUSTED_NEAR_END) &&
+ (rowdata & SOTP_NVCTR_NON_TRUSTED_IN_USE) &&
+ (rownum > SOTP_NVCTR_ROW_START)) {
+ /*
+ * Current row in use and has data in last 2 bits as well.
+ * Check if next row also has data for this counter
+ */
+ nextrowdata = sotp_mem_read(rownum-1, SOTP_ROW_NO_ECC);
+ if (nextrowdata & SOTP_NVCTR_NON_TRUSTED_IN_USE) {
+ /* Next row also has data so decrement rownum */
+ rownum--;
+ nvctr += SOTP_NUM_BITS_PER_ROW;
+ rowdata = nextrowdata;
+ } else {
+ /* Next row does not have data */
+ break;
+ }
+ }
+
+ if (rowdata & SOTP_NVCTR_NON_TRUSTED_IN_USE) {
+ while ((rowdata & ((uint64_t)0x1 << (SOTP_NUM_BITS_PER_ROW-1)))
+ ==
+ 0) {
+ nvctr--;
+ rowdata <<= 1;
+ }
+ } else
+ nvctr -= SOTP_NUM_BITS_PER_ROW;
+
+ INFO("NCTR %i\n", nvctr);
+ return nvctr;
+}
+
+/*
+ * Set SOTP Trusted nvctr
+ */
+int sotp_set_trusted_nvctr(unsigned int nvctr)
+{
+ int numrows_available;
+ uint32_t nontrusted_rownum;
+ uint32_t trusted_rownum;
+ uint64_t rowdata;
+ unsigned int maxnvctr;
+
+ /*
+ * Read SOTP to find out how many rows are used by the
+ * NON Trusted nvctr
+ */
+ nontrusted_rownum = SOTP_NVCTR_ROW_END;
+ do {
+ rowdata = sotp_mem_read(nontrusted_rownum, SOTP_ROW_NO_ECC);
+ if (rowdata & SOTP_NVCTR_NON_TRUSTED_IN_USE)
+ nontrusted_rownum--;
+ else
+ break;
+ } while (nontrusted_rownum >= SOTP_NVCTR_ROW_START);
+
+ /*
+ * Calculate maximum value we can have for nvctr based on
+ * number of available rows.
+ */
+ numrows_available = nontrusted_rownum - SOTP_NVCTR_ROW_START + 1;
+ maxnvctr = numrows_available * SOTP_NUM_BITS_PER_ROW;
+ if (maxnvctr) {
+ /*
+ * Last 2 bits of counter can't be written or it will
+ * overflow with nontrusted counter
+ */
+ maxnvctr -= 2;
+ }
+
+ if (nvctr > maxnvctr) {
+ /* Error - not enough room */
+ WARN("tctr not set\n");
+ return 1;
+ }
+
+ /*
+ * It is safe to write the nvctr, fill all 1's up to the
+ * last row and then fill the last row with partial bitstream
+ */
+ trusted_rownum = SOTP_NVCTR_ROW_START;
+ rowdata = SOTP_NVCTR_ROW_ALL_ONES;
+
+ while (nvctr >= SOTP_NUM_BITS_PER_ROW) {
+ sotp_mem_write(trusted_rownum, SOTP_ROW_NO_ECC, rowdata);
+ nvctr -= SOTP_NUM_BITS_PER_ROW;
+ trusted_rownum++;
+ }
+ rowdata <<= (SOTP_NUM_BITS_PER_ROW - nvctr);
+ sotp_mem_write(trusted_rownum, SOTP_ROW_NO_ECC, rowdata);
+ return 0;
+}
+
+/*
+ * Set SOTP NonTrusted nvctr
+ */
+int sotp_set_nontrusted_nvctr(unsigned int nvctr)
+{
+ int numrows_available;
+ uint32_t nontrusted_rownum;
+ uint32_t trusted_rownum;
+ uint64_t rowdata;
+ unsigned int maxnvctr;
+
+ /*
+ * Read SOTP to find out how many rows are used by the
+ * Trusted nvctr
+ */
+ trusted_rownum = SOTP_NVCTR_ROW_START;
+ do {
+ rowdata = sotp_mem_read(trusted_rownum, SOTP_ROW_NO_ECC);
+ if (rowdata & SOTP_NVCTR_TRUSTED_IN_USE)
+ trusted_rownum++;
+ else
+ break;
+ } while (trusted_rownum <= SOTP_NVCTR_ROW_END);
+
+ /*
+ * Calculate maximum value we can have for nvctr based on
+ * number of available rows.
+ */
+ numrows_available = SOTP_NVCTR_ROW_END - trusted_rownum + 1;
+ maxnvctr = numrows_available * SOTP_NUM_BITS_PER_ROW;
+ if (maxnvctr) {
+ /*
+ * Last 2 bits of counter can't be written or it will
+ * overflow with nontrusted counter
+ */
+ maxnvctr -= 2;
+ }
+
+ if (nvctr > maxnvctr) {
+ /* Error - not enough room */
+ WARN("nctr not set\n");
+ return 1;
+ }
+
+ /*
+ * It is safe to write the nvctr, fill all 1's up to the
+ * last row and then fill the last row with partial bitstream
+ */
+ nontrusted_rownum = SOTP_NVCTR_ROW_END;
+ rowdata = SOTP_NVCTR_ROW_ALL_ONES;
+
+ while (nvctr >= SOTP_NUM_BITS_PER_ROW) {
+ sotp_mem_write(nontrusted_rownum, SOTP_ROW_NO_ECC, rowdata);
+ nvctr -= SOTP_NUM_BITS_PER_ROW;
+ nontrusted_rownum--;
+ }
+ rowdata >>= (SOTP_NUM_BITS_PER_ROW - nvctr);
+ sotp_mem_write(nontrusted_rownum, SOTP_ROW_NO_ECC, rowdata);
+ return 0;
+}
+
+/*
+ * Return the non-volatile counter value stored in the platform. The cookie
+ * will contain the OID of the counter in the certificate.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+ const char *oid;
+
+ assert(cookie != NULL);
+ assert(nv_ctr != NULL);
+
+ *nv_ctr = 0;
+ if ((sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC) &
+ SOTP_ATF_NVCOUNTER_ENABLE_MASK)) {
+ oid = (const char *)cookie;
+ if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0)
+ *nv_ctr = sotp_get_trusted_nvctr();
+ else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0)
+ *nv_ctr = sotp_get_nontrusted_nvctr();
+ else
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Store a new non-volatile counter value.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ const char *oid;
+
+ if (sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC) &
+ SOTP_ATF_NVCOUNTER_ENABLE_MASK) {
+ INFO("set CTR %i\n", nv_ctr);
+ oid = (const char *)cookie;
+ if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0)
+ return sotp_set_trusted_nvctr(nv_ctr);
+ else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0)
+ return sotp_set_nontrusted_nvctr(nv_ctr);
+ return 1;
+ }
+ return 0;
+}
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
diff --git a/plat/brcm/board/common/board_common.c b/plat/brcm/board/common/board_common.c
new file mode 100644
index 000000000..2f764ab25
--- /dev/null
+++ b/plat/brcm/board/common/board_common.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <brcm_def.h>
+#include <plat_brcm.h>
+
+#if IMAGE_BL2
+const mmap_region_t plat_brcm_mmap[] = {
+ HSLS_REGION,
+ BRCM_MAP_SHARED_RAM,
+ BRCM_MAP_NAND_RO,
+ BRCM_MAP_QSPI_RO,
+#ifdef PERIPH0_REGION
+ PERIPH0_REGION,
+#endif
+#ifdef PERIPH1_REGION
+ PERIPH1_REGION,
+#endif
+#ifdef USE_DDR
+ BRCM_MAP_NS_DRAM1,
+#if BRCM_BL31_IN_DRAM
+ BRCM_MAP_BL31_SEC_DRAM,
+#endif
+#else
+#ifdef BRCM_MAP_EXT_SRAM
+ BRCM_MAP_EXT_SRAM,
+#endif
+#endif
+#if defined(USE_CRMU_SRAM) && defined(CRMU_SRAM_BASE)
+ CRMU_SRAM_REGION,
+#endif
+ {0}
+};
+#endif
+
+#if IMAGE_BL31
+const mmap_region_t plat_brcm_mmap[] = {
+ HSLS_REGION,
+#ifdef PERIPH0_REGION
+ PERIPH0_REGION,
+#endif
+#ifdef PERIPH1_REGION
+ PERIPH1_REGION,
+#endif
+#ifdef PERIPH2_REGION
+ PERIPH2_REGION,
+#endif
+#ifdef USB_REGION
+ USB_REGION,
+#endif
+#ifdef USE_DDR
+ BRCM_MAP_NS_DRAM1,
+#ifdef BRCM_MAP_NS_SHARED_DRAM
+ BRCM_MAP_NS_SHARED_DRAM,
+#endif
+#else
+#ifdef BRCM_MAP_EXT_SRAM
+ BRCM_MAP_EXT_SRAM,
+#endif
+#endif
+#if defined(USE_CRMU_SRAM) && defined(CRMU_SRAM_BASE)
+ CRMU_SRAM_REGION,
+#endif
+ {0}
+};
+#endif
+
+CASSERT((ARRAY_SIZE(plat_brcm_mmap) - 1) <= PLAT_BRCM_MMAP_ENTRIES,
+ assert_plat_brcm_mmap_mismatch);
+CASSERT((PLAT_BRCM_MMAP_ENTRIES + BRCM_BL_REGIONS) <= MAX_MMAP_REGIONS,
+ assert_max_mmap_regions);
diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk
new file mode 100644
index 000000000..3069f914b
--- /dev/null
+++ b/plat/brcm/board/common/board_common.mk
@@ -0,0 +1,285 @@
+#
+# Copyright (c) 2015 - 2020, Broadcom
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_BL_COMMON_SOURCES += plat/brcm/board/common/board_common.c
+
+# If no board config makefile, do not include it
+ifneq (${BOARD_CFG},)
+BOARD_CFG_MAKE := $(shell find plat/brcm/board/${PLAT} -name '${BOARD_CFG}.mk')
+$(eval $(call add_define,BOARD_CFG))
+ifneq (${BOARD_CFG_MAKE},)
+$(info Including ${BOARD_CFG_MAKE})
+include ${BOARD_CFG_MAKE}
+else
+$(error Error: File ${BOARD_CFG}.mk not found in plat/brcm/board/${PLAT})
+endif
+endif
+
+# To compile with highest log level (VERBOSE) set value to 50
+LOG_LEVEL := 40
+
+# Use custom generic timer clock
+ifneq (${GENTIMER_ACTUAL_CLOCK},)
+$(info Using GENTIMER_ACTUAL_CLOCK=$(GENTIMER_ACTUAL_CLOCK))
+SYSCNT_FREQ := $(GENTIMER_ACTUAL_CLOCK)
+$(eval $(call add_define,SYSCNT_FREQ))
+endif
+
+ifeq (${DRIVER_EMMC_ENABLE},)
+DRIVER_EMMC_ENABLE :=1
+endif
+
+ifeq (${DRIVER_SPI_ENABLE},)
+DRIVER_SPI_ENABLE := 0
+endif
+
+# By default, Trusted Watchdog is always enabled unless SPIN_ON_BL1_EXIT is set
+ifeq (${BRCM_DISABLE_TRUSTED_WDOG},)
+BRCM_DISABLE_TRUSTED_WDOG := 0
+endif
+ifeq (${SPIN_ON_BL1_EXIT}, 1)
+BRCM_DISABLE_TRUSTED_WDOG := 1
+endif
+
+$(eval $(call assert_boolean,BRCM_DISABLE_TRUSTED_WDOG))
+$(eval $(call add_define,BRCM_DISABLE_TRUSTED_WDOG))
+
+# Process ARM_BL31_IN_DRAM flag
+ifeq (${ARM_BL31_IN_DRAM},)
+ARM_BL31_IN_DRAM := 0
+endif
+$(eval $(call assert_boolean,ARM_BL31_IN_DRAM))
+$(eval $(call add_define,ARM_BL31_IN_DRAM))
+
+ifeq (${STANDALONE_BL2},yes)
+BL2_LOG_LEVEL := 40
+$(eval $(call add_define,MMU_DISABLED))
+endif
+
+# BL2 XIP from QSPI
+RUN_BL2_FROM_QSPI := 0
+ifeq (${RUN_BL2_FROM_QSPI},1)
+$(eval $(call add_define,RUN_BL2_FROM_QSPI))
+endif
+
+# BL2 XIP from NAND
+RUN_BL2_FROM_NAND := 0
+ifeq (${RUN_BL2_FROM_NAND},1)
+$(eval $(call add_define,RUN_BL2_FROM_NAND))
+endif
+
+ifneq (${ELOG_AP_UART_LOG_BASE},)
+$(eval $(call add_define,ELOG_AP_UART_LOG_BASE))
+endif
+
+ifeq (${ELOG_SUPPORT},1)
+ifeq (${ELOG_STORE_MEDIA},DDR)
+$(eval $(call add_define,ELOG_STORE_MEDIA_DDR))
+ifneq (${ELOG_STORE_OFFSET},)
+$(eval $(call add_define,ELOG_STORE_OFFSET))
+endif
+endif
+endif
+
+ifneq (${BL2_LOG_LEVEL},)
+$(eval $(call add_define,BL2_LOG_LEVEL))
+endif
+
+ifneq (${BL31_LOG_LEVEL},)
+$(eval $(call add_define,BL31_LOG_LEVEL))
+endif
+
+# Use CRMU SRAM from iHOST
+ifneq (${USE_CRMU_SRAM},)
+$(eval $(call add_define,USE_CRMU_SRAM))
+endif
+
+# Use PIO mode if DDR is not used
+ifeq (${USE_DDR},yes)
+EMMC_USE_DMA := 1
+else
+EMMC_USE_DMA := 0
+endif
+$(eval $(call add_define,EMMC_USE_DMA))
+
+# On BRCM platforms, separate the code and read-only data sections to allow
+# mapping the former as executable and the latter as execute-never.
+SEPARATE_CODE_AND_RODATA := 1
+
+# Use generic OID definition (tbbr_oid.h)
+USE_TBBR_DEFS := 1
+
+PLAT_INCLUDES += -Iplat/brcm/board/common \
+ -Iinclude/drivers/brcm \
+ -Iinclude/drivers/brcm/emmc
+
+PLAT_BL_COMMON_SOURCES += plat/brcm/common/brcm_common.c \
+ plat/brcm/board/common/cmn_sec.c \
+ plat/brcm/board/common/bcm_console.c \
+ plat/brcm/board/common/brcm_mbedtls.c \
+ plat/brcm/board/common/plat_setup.c \
+ plat/brcm/board/common/platform_common.c \
+ drivers/arm/sp804/sp804_delay_timer.c \
+ drivers/brcm/sotp.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/io/io_fip.c \
+ drivers/io/io_memmap.c \
+ drivers/io/io_storage.c \
+ plat/brcm/common/brcm_io_storage.c \
+ plat/brcm/board/common/err.c \
+ plat/brcm/board/common/sbl_util.c \
+ drivers/arm/sp805/sp805.c
+
+# Add RNG driver
+DRIVER_RNG_ENABLE := 1
+ifeq (${DRIVER_RNG_ENABLE},1)
+PLAT_BL_COMMON_SOURCES += drivers/brcm/rng.c
+endif
+
+# Add eMMC driver
+ifeq (${DRIVER_EMMC_ENABLE},1)
+$(eval $(call add_define,DRIVER_EMMC_ENABLE))
+
+EMMC_SOURCES += drivers/brcm/emmc/emmc_chal_sd.c \
+ drivers/brcm/emmc/emmc_csl_sdcard.c \
+ drivers/brcm/emmc/emmc_csl_sdcmd.c \
+ drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c
+
+PLAT_BL_COMMON_SOURCES += ${EMMC_SOURCES}
+
+ifeq (${DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT},)
+$(eval $(call add_define,DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT))
+endif
+endif
+
+BL2_SOURCES += plat/brcm/common/brcm_bl2_mem_params_desc.c \
+ plat/brcm/common/brcm_image_load.c \
+ common/desc_image_load.c
+
+BL2_SOURCES += plat/brcm/common/brcm_bl2_setup.c
+
+BL31_SOURCES += plat/brcm/common/brcm_bl31_setup.c
+
+ifeq (${BCM_ELOG},yes)
+ELOG_SOURCES += plat/brcm/board/common/bcm_elog.c
+BL2_SOURCES += ${ELOG_SOURCES}
+BL31_SOURCES += ${ELOG_SOURCES}
+endif
+
+# Add spi driver
+ifeq (${DRIVER_SPI_ENABLE},1)
+PLAT_BL_COMMON_SOURCES += drivers/brcm/spi/iproc_spi.c \
+ drivers/brcm/spi/iproc_qspi.c
+endif
+
+# Add spi nor/flash driver
+ifeq (${DRIVER_SPI_NOR_ENABLE},1)
+PLAT_BL_COMMON_SOURCES += drivers/brcm/spi_sf.c \
+ drivers/brcm/spi_flash.c
+endif
+
+ifeq (${DRIVER_OCOTP_ENABLE},1)
+$(eval $(call add_define,DRIVER_OCOTP_ENABLE))
+BL2_SOURCES += drivers/brcm/ocotp.c
+endif
+
+# Enable FRU table support
+ifeq (${USE_FRU},yes)
+$(eval $(call add_define,USE_FRU))
+BL2_SOURCES += drivers/brcm/fru.c
+endif
+
+# Enable GPIO support
+ifeq (${USE_GPIO},yes)
+$(eval $(call add_define,USE_GPIO))
+BL2_SOURCES += drivers/gpio/gpio.c
+BL2_SOURCES += drivers/brcm/iproc_gpio.c
+ifeq (${GPIO_SUPPORT_FLOAT_DETECTION},yes)
+$(eval $(call add_define,GPIO_SUPPORT_FLOAT_DETECTION))
+endif
+endif
+
+# Include mbedtls if it can be located
+MBEDTLS_DIR := mbedtls
+MBEDTLS_CHECK := $(shell find ${MBEDTLS_DIR}/include -name '${MBEDTLS_DIR}')
+
+ifneq (${MBEDTLS_CHECK},)
+$(info Found mbedTLS at ${MBEDTLS_DIR})
+PLAT_INCLUDES += -I${MBEDTLS_DIR}/include/mbedtls
+# Specify mbedTLS configuration file
+MBEDTLS_CONFIG_FILE := "<brcm_mbedtls_config.h>"
+
+# By default, use RSA keys
+KEY_ALG := rsa_1_5
+
+# Include common TBB sources
+AUTH_SOURCES += drivers/auth/auth_mod.c \
+ drivers/auth/crypto_mod.c \
+ drivers/auth/img_parser_mod.c \
+ drivers/auth/tbbr/tbbr_cot_common.c \
+ drivers/auth/tbbr/tbbr_cot_bl2.c
+
+BL2_SOURCES += ${AUTH_SOURCES}
+
+# Use ATF framework for MBEDTLS
+TRUSTED_BOARD_BOOT := 1
+CRYPTO_LIB_MK := drivers/auth/mbedtls/mbedtls_crypto.mk
+IMG_PARSER_LIB_MK := drivers/auth/mbedtls/mbedtls_x509.mk
+$(info Including ${CRYPTO_LIB_MK})
+include ${CRYPTO_LIB_MK}
+$(info Including ${IMG_PARSER_LIB_MK})
+include ${IMG_PARSER_LIB_MK}
+
+# Use ATF secure boot functions
+# Use Hardcoded hash for devel
+
+ARM_ROTPK_LOCATION=arm_rsa
+ifeq (${ARM_ROTPK_LOCATION}, arm_rsa)
+ARM_ROTPK_LOCATION_ID=ARM_ROTPK_DEVEL_RSA_ID
+ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem
+else ifeq (${ARM_ROTPK_LOCATION}, brcm_rsa)
+ARM_ROTPK_LOCATION_ID=BRCM_ROTPK_SOTP_RSA_ID
+ifeq (${ROT_KEY},)
+ROT_KEY=plat/brcm/board/common/rotpk/rsa_dauth2048_key.pem
+endif
+KEY_FIND := $(shell m="${ROT_KEY}"; [ -f "$$m" ] && echo "$$m")
+ifeq (${KEY_FIND},)
+$(error Error: No ${ROT_KEY} located)
+else
+$(info Using ROT_KEY: ${ROT_KEY})
+endif
+else
+$(error "Unsupported ARM_ROTPK_LOCATION value")
+endif
+
+$(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
+PLAT_BL_COMMON_SOURCES+=plat/brcm/board/common/board_arm_trusted_boot.c
+endif
+
+#M0 runtime firmware
+ifdef SCP_BL2
+$(eval $(call add_define,NEED_SCP_BL2))
+SCP_CFG_DIR=$(dir ${SCP_BL2})
+PLAT_INCLUDES += -I${SCP_CFG_DIR}
+endif
+
+ifneq (${NEED_BL33},yes)
+# If there is no BL33, BL31 will jump to this address.
+ifeq (${USE_DDR},yes)
+PRELOADED_BL33_BASE := 0x80000000
+else
+PRELOADED_BL33_BASE := 0x74000000
+endif
+endif
+
+# Use translation tables library v1 by default
+ARM_XLAT_TABLES_LIB_V1 := 1
+ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
+$(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1))
+$(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1))
+PLAT_BL_COMMON_SOURCES += lib/xlat_tables/aarch64/xlat_tables.c \
+ lib/xlat_tables/xlat_tables_common.c
+endif
diff --git a/plat/brcm/board/common/brcm_mbedtls.c b/plat/brcm/board/common/brcm_mbedtls.c
new file mode 100644
index 000000000..af42b861b
--- /dev/null
+++ b/plat/brcm/board/common/brcm_mbedtls.c
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2015 - 2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+
+void tls_exit(int code)
+{
+ INFO("%s: 0x%x\n", __func__, code);
+}
diff --git a/plat/brcm/board/common/chip_id.h b/plat/brcm/board/common/chip_id.h
new file mode 100644
index 000000000..842ac1f88
--- /dev/null
+++ b/plat/brcm/board/common/chip_id.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CHIP_ID_H
+#define CHIP_ID_H
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#define CHIP_REV_MAJOR_MASK 0xF0
+#define CHIP_REV_MAJOR_AX 0x00
+#define CHIP_REV_MAJOR_BX 0x10
+#define CHIP_REV_MAJOR_CX 0x20
+#define CHIP_REV_MAJOR_DX 0x30
+
+/* Get Chip ID (product number) of the chip */
+static inline unsigned int chip_get_product_id(void)
+{
+ return PLAT_CHIP_ID_GET;
+}
+
+/* Get Revision ID (major and minor) number of the chip */
+static inline unsigned int chip_get_rev_id(void)
+{
+ return PLAT_CHIP_REV_GET;
+}
+
+static inline unsigned int chip_get_rev_id_major(void)
+{
+ return (chip_get_rev_id() & CHIP_REV_MAJOR_MASK);
+}
+
+#endif
diff --git a/plat/brcm/board/common/cmn_plat_def.h b/plat/brcm/board/common/cmn_plat_def.h
new file mode 100644
index 000000000..8aa7fd453
--- /dev/null
+++ b/plat/brcm/board/common/cmn_plat_def.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CMN_PLAT_DEF_H
+#define CMN_PLAT_DEF_H
+
+#include <bcm_elog.h>
+
+#ifndef GET_LOG_LEVEL
+#define GET_LOG_LEVEL() LOG_LEVEL
+#endif
+
+#ifndef SET_LOG_LEVEL
+#define SET_LOG_LEVEL(x) ((void)(x))
+#endif
+
+#define PLAT_LOG_NOTICE(...) \
+ do { \
+ if (GET_LOG_LEVEL() >= LOG_LEVEL_NOTICE) { \
+ bcm_elog(LOG_MARKER_NOTICE __VA_ARGS__); \
+ tf_log(LOG_MARKER_NOTICE __VA_ARGS__); \
+ } \
+ } while (0)
+
+#define PLAT_LOG_ERROR(...) \
+ do { \
+ if (GET_LOG_LEVEL() >= LOG_LEVEL_ERROR) { \
+ bcm_elog(LOG_MARKER_ERROR, __VA_ARGS__); \
+ tf_log(LOG_MARKER_ERROR __VA_ARGS__); \
+ } \
+ } while (0)
+
+#define PLAT_LOG_WARN(...) \
+ do { \
+ if (GET_LOG_LEVEL() >= LOG_LEVEL_WARNING) { \
+ bcm_elog(LOG_MARKER_WARNING, __VA_ARGS__);\
+ tf_log(LOG_MARKER_WARNING __VA_ARGS__); \
+ } \
+ } while (0)
+
+#define PLAT_LOG_INFO(...) \
+ do { \
+ if (GET_LOG_LEVEL() >= LOG_LEVEL_INFO) { \
+ bcm_elog(LOG_MARKER_INFO __VA_ARGS__); \
+ tf_log(LOG_MARKER_INFO __VA_ARGS__); \
+ } \
+ } while (0)
+
+#define PLAT_LOG_VERBOSE(...) \
+ do { \
+ if (GET_LOG_LEVEL() >= LOG_LEVEL_VERBOSE) { \
+ bcm_elog(LOG_MARKER_VERBOSE __VA_ARGS__);\
+ tf_log(LOG_MARKER_VERBOSE __VA_ARGS__); \
+ } \
+ } while (0)
+
+/* Print file and line number on assert */
+#define PLAT_LOG_LEVEL_ASSERT LOG_LEVEL_INFO
+
+/*
+ * The number of regions like RO(code), coherent and data required by
+ * different BL stages which need to be mapped in the MMU.
+ */
+#if USE_COHERENT_MEM
+#define CMN_BL_REGIONS 3
+#else
+#define CMN_BL_REGIONS 2
+#endif
+
+/*
+ * FIP definitions
+ */
+#define PLAT_FIP_ATTEMPT_OFFSET 0x20000
+#define PLAT_FIP_NUM_ATTEMPTS 128
+
+#define PLAT_BRCM_FIP_QSPI_BASE QSPI_BASE_ADDR
+#define PLAT_BRCM_FIP_NAND_BASE NAND_BASE_ADDR
+#define PLAT_BRCM_FIP_MAX_SIZE 0x01000000
+
+#define PLAT_BRCM_FIP_BASE PLAT_BRCM_FIP_QSPI_BASE
+#endif
diff --git a/plat/brcm/board/common/cmn_plat_util.h b/plat/brcm/board/common/cmn_plat_util.h
new file mode 100644
index 000000000..178c84357
--- /dev/null
+++ b/plat/brcm/board/common/cmn_plat_util.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CMN_PLAT_UTIL_H
+#define CMN_PLAT_UTIL_H
+
+#include <lib/mmio.h>
+
+/* BOOT source */
+#define BOOT_SOURCE_MASK 7
+#define BOOT_SOURCE_QSPI 0
+#define BOOT_SOURCE_NAND 1
+#define BOOT_SOURCE_SPI_NAND 2
+#define BOOT_SOURCE_UART 3
+#define BOOT_SOURCE_RES4 4
+#define BOOT_SOURCE_EMMC 5
+#define BOOT_SOURCE_ATE 6
+#define BOOT_SOURCE_USB 7
+#define BOOT_SOURCE_MAX 8
+#define BOOT_SOURCE_UNKNOWN (-1)
+
+#define KHMAC_SHA256_KEY_SIZE 32
+
+#define SOFT_PWR_UP_RESET_L0 0
+#define SOFT_SYS_RESET_L1 1
+#define SOFT_RESET_L3 0x3
+
+#define BOOT_SOURCE_SOFT_DATA_OFFSET 8
+#define BOOT_SOURCE_SOFT_ENABLE_OFFSET 14
+#define BOOT_SOURCE_SOFT_ENABLE_MASK BIT(BOOT_SOURCE_SOFT_ENABLE_OFFSET)
+
+typedef struct _key {
+ uint8_t hmac_sha256[KHMAC_SHA256_KEY_SIZE];
+} cmn_key_t;
+
+uint32_t boot_source_get(void);
+void bl1_platform_wait_events(void);
+void plat_soft_reset(uint32_t reset);
+
+#endif
diff --git a/plat/brcm/board/common/cmn_sec.c b/plat/brcm/board/common/cmn_sec.c
new file mode 100644
index 000000000..c80d5dd6f
--- /dev/null
+++ b/plat/brcm/board/common/cmn_sec.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include <cmn_sec.h>
+
+#pragma weak plat_tz_master_default_cfg
+#pragma weak plat_tz_sdio_ns_master_set
+#pragma weak plat_tz_usb_ns_master_set
+
+void plat_tz_master_default_cfg(void)
+{
+ /* This function should be implemented in the platform side. */
+ ERROR("%s: TZ CONFIGURATION NOT SET!!!\n", __func__);
+}
+
+void plat_tz_sdio_ns_master_set(uint32_t ns)
+{
+ /* This function should be implemented in the platform side. */
+ ERROR("%s: TZ CONFIGURATION NOT SET!!!\n", __func__);
+}
+
+void plat_tz_usb_ns_master_set(uint32_t ns)
+{
+ /* This function should be implemented in the platform side. */
+ ERROR("%s: TZ CONFIGURATION NOT SET!!!\n", __func__);
+}
+
+void tz_master_default_cfg(void)
+{
+ plat_tz_master_default_cfg();
+}
+
+void tz_sdio_ns_master_set(uint32_t ns)
+{
+ plat_tz_sdio_ns_master_set(ns);
+}
+
+void tz_usb_ns_master_set(uint32_t ns)
+{
+ plat_tz_usb_ns_master_set(ns);
+}
diff --git a/plat/brcm/board/common/cmn_sec.h b/plat/brcm/board/common/cmn_sec.h
new file mode 100644
index 000000000..f74863d88
--- /dev/null
+++ b/plat/brcm/board/common/cmn_sec.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CMN_SEC_H
+#define CMN_SEC_H
+
+#include <stdint.h>
+
+#define SECURE_MASTER 0
+#define NS_MASTER 1
+
+void tz_master_default_cfg(void);
+void tz_usb_ns_master_set(uint32_t ns);
+void tz_sdio_ns_master_set(uint32_t ns);
+
+#endif
diff --git a/plat/brcm/board/common/err.c b/plat/brcm/board/common/err.c
new file mode 100644
index 000000000..1fc73c481
--- /dev/null
+++ b/plat/brcm/board/common/err.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#define L0_RESET 0x2
+
+/*
+ * Brcm error handler
+ */
+void plat_error_handler(int err)
+{
+ INFO("L0 reset...\n");
+
+ /* Ensure the characters are flushed out */
+ console_flush();
+
+ mmio_write_32(CRMU_SOFT_RESET_CTRL, L0_RESET);
+
+ /*
+ * In case we get here:
+ * Loop until the watchdog resets the system
+ */
+ while (1) {
+ wfi();
+ }
+}
diff --git a/plat/brcm/board/common/plat_setup.c b/plat/brcm/board/common/plat_setup.c
new file mode 100644
index 000000000..95e12ed1e
--- /dev/null
+++ b/plat/brcm/board/common/plat_setup.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/*
+ * This function returns the fixed clock frequency at which private
+ * timers run. This value will be programmed into CNTFRQ_EL0.
+ */
+unsigned int plat_get_syscnt_freq2(void)
+{
+ return SYSCNT_FREQ;
+}
+
+static const char * const plat_prefix_str[] = {
+ "E: ", "N: ", "W: ", "I: ", "V: "
+};
+
+const char *plat_log_get_prefix(unsigned int log_level)
+{
+ return plat_prefix_str[log_level - 1U];
+}
diff --git a/plat/brcm/board/common/platform_common.c b/plat/brcm/board/common/platform_common.c
new file mode 100644
index 000000000..f4c9a738f
--- /dev/null
+++ b/plat/brcm/board/common/platform_common.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/brcm/sotp.h>
+
+#include <cmn_plat_util.h>
+#include <platform_def.h>
+
+uint32_t boot_source_get(void)
+{
+ uint32_t data;
+
+#ifdef FORCE_BOOTSOURCE
+ data = FORCE_BOOTSOURCE;
+#else
+ /* Read primary boot strap from CRMU persistent registers */
+ data = mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG1);
+ if (data & BOOT_SOURCE_SOFT_ENABLE_MASK) {
+ data >>= BOOT_SOURCE_SOFT_DATA_OFFSET;
+ } else {
+ uint64_t sotp_atf_row;
+
+ sotp_atf_row =
+ sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC);
+
+ if (sotp_atf_row & SOTP_BOOT_SOURCE_ENABLE_MASK) {
+ /* Construct the boot source based on SOTP bits */
+ data = 0;
+ if (sotp_atf_row & SOTP_BOOT_SOURCE_BITS0)
+ data |= 0x1;
+ if (sotp_atf_row & SOTP_BOOT_SOURCE_BITS1)
+ data |= 0x2;
+ if (sotp_atf_row & SOTP_BOOT_SOURCE_BITS2)
+ data |= 0x4;
+ } else {
+
+ /*
+ * This path is for L0 reset with
+ * Primary Boot source disabled in SOTP.
+ * BOOT_SOURCE_FROM_PR_ON_L1 compile flag will allow
+ * to never come back here so that the
+ * external straps will not be read on L1 reset.
+ */
+
+ /* Use the external straps */
+ data = mmio_read_32(ROM_S0_IDM_IO_STATUS);
+
+#ifdef BOOT_SOURCE_FROM_PR_ON_L1
+ /* Enable boot source read from PR#1 */
+ mmio_setbits_32(CRMU_IHOST_SW_PERSISTENT_REG1,
+ BOOT_SOURCE_SOFT_ENABLE_MASK);
+
+ /* set boot source */
+ data &= BOOT_SOURCE_MASK;
+ mmio_clrsetbits_32(CRMU_IHOST_SW_PERSISTENT_REG1,
+ BOOT_SOURCE_MASK << BOOT_SOURCE_SOFT_DATA_OFFSET,
+ data << BOOT_SOURCE_SOFT_DATA_OFFSET);
+#endif
+ }
+ }
+#endif
+ return (data & BOOT_SOURCE_MASK);
+}
+
+void __dead2 plat_soft_reset(uint32_t reset)
+{
+ if (reset == SOFT_RESET_L3) {
+ mmio_setbits_32(CRMU_IHOST_SW_PERSISTENT_REG1, reset);
+ mmio_write_32(CRMU_MAIL_BOX0, 0x0);
+ mmio_write_32(CRMU_MAIL_BOX1, 0xFFFFFFFF);
+ }
+
+ if (reset != SOFT_SYS_RESET_L1)
+ reset = SOFT_PWR_UP_RESET_L0;
+
+ if (reset == SOFT_PWR_UP_RESET_L0)
+ INFO("L0 RESET...\n");
+
+ if (reset == SOFT_SYS_RESET_L1)
+ INFO("L1 RESET...\n");
+
+ console_flush();
+
+ mmio_clrbits_32(CRMU_SOFT_RESET_CTRL, 1 << reset);
+
+ while (1) {
+ ;
+ }
+}
diff --git a/plat/brcm/board/common/sbl_util.c b/plat/brcm/board/common/sbl_util.c
new file mode 100644
index 000000000..06e5b33b7
--- /dev/null
+++ b/plat/brcm/board/common/sbl_util.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include <platform_def.h>
+#include <sbl_util.h>
+#include <sotp.h>
+
+#pragma weak plat_sbl_status
+
+int plat_sbl_status(uint64_t sbl_status)
+{
+ return sbl_status ? 1:0;
+}
+
+int sbl_status(void)
+{
+ uint64_t sbl_sotp = 0;
+ int ret = SBL_DISABLED;
+
+ sbl_sotp = sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC);
+
+ if (sbl_sotp != SOTP_ECC_ERR_DETECT) {
+
+ sbl_sotp &= SOTP_SBL_MASK;
+
+ if (plat_sbl_status(sbl_sotp))
+ ret = SBL_ENABLED;
+ }
+
+ VERBOSE("SBL status: %d\n", ret);
+
+ return ret;
+}
diff --git a/plat/brcm/board/common/sbl_util.h b/plat/brcm/board/common/sbl_util.h
new file mode 100644
index 000000000..07473895e
--- /dev/null
+++ b/plat/brcm/board/common/sbl_util.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SBL_UTIL_H
+#define SBL_UTIL_H
+
+#include <stdint.h>
+
+#include <sotp.h>
+
+#define SBL_DISABLED 0
+#define SBL_ENABLED 1
+
+int sbl_status(void);
+
+#endif /* #ifdef SBL_UTIL_H */
diff --git a/plat/brcm/board/common/timer_sync.c b/plat/brcm/board/common/timer_sync.c
new file mode 100644
index 000000000..7e33a9407
--- /dev/null
+++ b/plat/brcm/board/common/timer_sync.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+#include <timer_sync.h>
+
+/*******************************************************************************
+ * Defines related to time sync and satelite timers
+ ******************************************************************************/
+#define TIME_SYNC_WR_ENA ((uint32_t)0xACCE55 << 8)
+#define IHOST_STA_TMR_CTRL 0x1800
+#define IHOST_SAT_TMR_INC_L 0x1814
+#define IHOST_SAT_TMR_INC_H 0x1818
+
+#define SAT_TMR_CYCLE_DELAY 2
+#define SAT_TMR_32BIT_WRAP_VAL (BIT_64(32) - SAT_TMR_CYCLE_DELAY)
+
+void ihost_enable_satellite_timer(unsigned int cluster_id)
+{
+ uintptr_t ihost_base;
+ uint32_t time_lx, time_h;
+ uintptr_t ihost_enable;
+
+ VERBOSE("Program iHost%u satellite timer\n", cluster_id);
+ ihost_base = IHOST0_BASE + cluster_id * IHOST_ADDR_SPACE;
+
+ /* this read starts the satellite timer counting from 0 */
+ ihost_enable = CENTRAL_TIMER_GET_IHOST_ENA_BASE + cluster_id * 4;
+ time_lx = mmio_read_32(ihost_enable);
+
+ /*
+ * Increment the satellite timer by the central timer plus 2
+ * to accommodate for a 1 cycle delay through NOC
+ * plus counter starting from 0.
+ */
+ mmio_write_32(ihost_base + IHOST_SAT_TMR_INC_L,
+ time_lx + SAT_TMR_CYCLE_DELAY);
+
+ /*
+ * Read the latched upper data, if lx will wrap by adding 2 to it
+ * we need to handle the wrap
+ */
+ time_h = mmio_read_32(CENTRAL_TIMER_GET_H);
+ if (time_lx >= SAT_TMR_32BIT_WRAP_VAL)
+ mmio_write_32(ihost_base + IHOST_SAT_TMR_INC_H, time_h + 1);
+ else
+ mmio_write_32(ihost_base + IHOST_SAT_TMR_INC_H, time_h);
+}
+
+void brcm_timer_sync_init(void)
+{
+ unsigned int cluster_id;
+
+ /* Get the Time Sync module out of reset */
+ mmio_setbits_32(CDRU_MISC_RESET_CONTROL,
+ BIT(CDRU_MISC_RESET_CONTROL_TS_RESET_N));
+
+ /* Deassert the Central Timer TIMER_EN signal for all module */
+ mmio_write_32(CENTRAL_TIMER_SAT_TMR_ENA, TIME_SYNC_WR_ENA);
+
+ /* enables/programs iHost0 satellite timer*/
+ cluster_id = MPIDR_AFFLVL1_VAL(read_mpidr());
+ ihost_enable_satellite_timer(cluster_id);
+}
diff --git a/plat/brcm/board/stingray/aarch64/plat_helpers.S b/plat/brcm/board/stingray/aarch64/plat_helpers.S
new file mode 100644
index 000000000..9a2039daf
--- /dev/null
+++ b/plat/brcm/board/stingray/aarch64/plat_helpers.S
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2015-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cpu_macros.S>
+#include <cortex_a72.h>
+#include <drivers/ti/uart/uart_16550.h>
+
+#include <platform_def.h>
+
+ .globl plat_reset_handler
+ .globl platform_get_entrypoint
+ .globl plat_secondary_cold_boot_setup
+ .globl platform_mem_init
+ .globl platform_check_mpidr
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_crash_console_flush
+ .globl plat_disable_acp
+ .globl plat_is_my_cpu_primary
+ .globl plat_my_core_pos
+ .globl platform_is_primary_cpu
+ .globl plat_brcm_calc_core_pos
+ .globl plat_get_my_entrypoint
+
+
+ /* ------------------------------------------------------------
+ * void plat_l2_init(void);
+ *
+ * BL1 and BL2 run with one core, one cluster
+ * This is safe to disable cluster coherency
+ * to make use of the data cache MMU WB attribute
+ * for the SRAM.
+ *
+ * Set L2 Auxiliary Control Register
+ * --------------------------------------------------------------------
+ */
+func plat_l2_init
+ mrs x0, CORTEX_A72_L2ACTLR_EL1
+#if (IMAGE_BL1 || IMAGE_BL2) || defined(USE_SINGLE_CLUSTER)
+ orr x0, x0, #CORTEX_A72_L2ACTLR_DISABLE_ACE_SH_OR_CHI
+#else
+ bic x0, x0, #CORTEX_A72_L2ACTLR_DISABLE_ACE_SH_OR_CHI
+#endif
+ msr CORTEX_A72_L2ACTLR_EL1, x0
+
+ /* Set L2 Control Register */
+ mrs x0, CORTEX_A72_L2CTLR_EL1
+ mov x1, #((CORTEX_A72_L2_DATA_RAM_LATENCY_MASK << \
+ CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
+ (CORTEX_A72_L2_TAG_RAM_LATENCY_MASK << \
+ CORTEX_A72_L2CTLR_TAG_RAM_LATENCY_SHIFT) | \
+ (U(0x1) << CORTEX_A72_L2CTLR_TAG_RAM_SETUP_SHIFT) | \
+ (U(0x1) << CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT))
+ bic x0, x0, x1
+ mov x1, #((CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES << \
+ CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
+ (U(0x1) << CORTEX_A72_L2CTLR_TAG_RAM_SETUP_SHIFT) | \
+ (U(0x1) << CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT))
+ orr x0, x0, x1
+ msr CORTEX_A72_L2CTLR_EL1, x0
+
+ isb
+ ret
+endfunc plat_l2_init
+
+ /* --------------------------------------------------------------------
+ * void plat_reset_handler(void);
+ *
+ * Before adding code in this function, refer to the guidelines in
+ * docs/firmware-design.md.
+ *
+ * --------------------------------------------------------------------
+ */
+func plat_reset_handler
+ mov x9, x30
+ bl plat_l2_init
+ mov x30, x9
+ ret
+endfunc plat_reset_handler
+
+ /* -----------------------------------------------------
+ * void platform_get_entrypoint (unsigned int mpid);
+ *
+ * Main job of this routine is to distinguish between
+ * a cold and warm boot.
+ * On a cold boot the secondaries first wait for the
+ * platform to be initialized after which they are
+ * hotplugged in. The primary proceeds to perform the
+ * platform initialization.
+ * -----------------------------------------------------
+ */
+func platform_get_entrypoint
+ /*TBD-STINGRAY*/
+ mov x0, #0
+ ret
+endfunc platform_get_entrypoint
+
+ /* -----------------------------------------------------
+ * void plat_secondary_cold_boot_setup (void);
+ *
+ * This function performs any platform specific actions
+ * needed for a secondary cpu after a cold reset e.g
+ * mark the cpu's presence, mechanism to place it in a
+ * holding pen etc.
+ * -----------------------------------------------------
+ */
+func plat_secondary_cold_boot_setup
+ bl plat_my_core_pos
+ mov_imm x1, SECONDARY_CPU_SPIN_BASE_ADDR
+ add x0, x1, x0, LSL #3
+ mov x1, #0
+ str x1, [x0]
+
+ /* Wait until the entrypoint gets populated */
+poll_mailbox:
+ ldr x1, [x0]
+ cbz x1, 1f
+ br x1
+1:
+ wfe
+ b poll_mailbox
+endfunc plat_secondary_cold_boot_setup
+
+
+ /* -----------------------------------------------------
+ * void platform_mem_init(void);
+ *
+ * We don't need to carry out any memory initialization
+ * on CSS platforms. The Secure RAM is accessible straight away.
+ * -----------------------------------------------------
+ */
+func platform_mem_init
+ /*TBD-STINGRAY*/
+ ret
+endfunc platform_mem_init
+
+ /* -----------------------------------------------------
+ * Placeholder function which should be redefined by
+ * each platform.
+ * -----------------------------------------------------
+ */
+func platform_check_mpidr
+ /*TBD-STINGRAY*/
+ mov x0, xzr
+ ret
+endfunc platform_check_mpidr
+
+ /* ---------------------------------------------
+ * int plat_crash_console_init(void)
+ * Function to initialize the crash console
+ * without a C Runtime to print crash report.
+ * Clobber list : x0, x1, x2
+ * ---------------------------------------------
+ */
+
+func plat_crash_console_init
+ mov_imm x0, BRCM_CRASH_CONSOLE_BASE
+ mov_imm x1, BRCM_CRASH_CONSOLE_REFCLK
+ mov_imm x2, BRCM_CRASH_CONSOLE_BAUDRATE
+ b console_16550_core_init
+ ret
+endfunc plat_crash_console_init
+
+ /* ---------------------------------------------
+ * int plat_crash_console_putc(void)
+ * Function to print a character on the crash
+ * console without a C Runtime.
+ * Clobber list : x1, x2, x3
+ * ---------------------------------------------
+ */
+
+func plat_crash_console_putc
+ mov_imm x1, BRCM_CRASH_CONSOLE_BASE
+ b console_16550_core_putc
+ ret
+endfunc plat_crash_console_putc
+
+ /* ---------------------------------------------
+ * void plat_crash_console_flush(void)
+ * Function to flush crash console
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ mov_imm x0, BRCM_CRASH_CONSOLE_BASE
+ b console_16550_core_flush
+ ret
+endfunc plat_crash_console_flush
+
+ /* -----------------------------------------------------
+ * Placeholder function which should be redefined by
+ * each platform. This function is allowed to use
+ * registers x0 - x17.
+ * -----------------------------------------------------
+ */
+
+func plat_disable_acp
+ /*TBD-STINGRAY*/
+ ret
+endfunc plat_disable_acp
+
+ /* -----------------------------------------------------
+ * unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary
+ * cpu (applicable only after a cold boot)
+ * -----------------------------------------------------
+ */
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ b platform_is_primary_cpu
+endfunc plat_is_my_cpu_primary
+
+ /* -----------------------------------------------------
+ * unsigned int plat_my_core_pos(void)
+ * This function uses the plat_brcm_calc_core_pos()
+ * definition to get the index of the calling CPU.
+ * -----------------------------------------------------
+ */
+func plat_my_core_pos
+ mrs x0, mpidr_el1
+ b plat_brcm_calc_core_pos
+endfunc plat_my_core_pos
+
+ /* -----------------------------------------------------
+ * unsigned int platform_is_primary_cpu (void);
+ *
+ * Find out whether the current cpu is the primary
+ * cpu (applicable only after a cold boot)
+ * -----------------------------------------------------
+ */
+func platform_is_primary_cpu
+ mov x9, x30
+ bl plat_my_core_pos
+ cmp x0, #PRIMARY_CPU
+ cset x0, eq
+ ret x9
+endfunc platform_is_primary_cpu
+
+ /* -----------------------------------------------------
+ * unsigned int plat_brcm_calc_core_pos(uint64_t mpidr)
+ * Helper function to calculate the core position.
+ * With this function: CorePos = (ClusterId * 4) +
+ * CoreId
+ * -----------------------------------------------------
+ */
+func plat_brcm_calc_core_pos
+ and x1, x0, #MPIDR_CPU_MASK
+ and x0, x0, #MPIDR_CLUSTER_MASK
+ add x0, x1, x0, LSR #7
+ ret
+endfunc plat_brcm_calc_core_pos
+
+func plat_get_my_entrypoint
+ mrs x0, mpidr_el1
+ b platform_get_entrypoint
+endfunc plat_get_my_entrypoint
diff --git a/plat/brcm/board/stingray/bcm958742t-ns3.mk b/plat/brcm/board/stingray/bcm958742t-ns3.mk
new file mode 100644
index 000000000..5164eeb5c
--- /dev/null
+++ b/plat/brcm/board/stingray/bcm958742t-ns3.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2015 - 2020, Broadcom
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+#######################################################
+# Board config file for bcm958742t-ns3 Stingray SST100-NS3
+#######################################################
+
+include plat/brcm/board/stingray/bcm958742t.mk
+
+# Load BL33 at 0xFF00_0000 address
+ifneq (${BL33_OVERRIDE_LOAD_ADDR},)
+$(eval $(call add_define_val,BL33_OVERRIDE_LOAD_ADDR,0xFF000000))
+endif
+
+# Nitro DDR secure memory
+# Nitro FW and config 0x8AE00000 - 0x8B000000
+# Nitro Crash dump 0x8B000000 - 0x8D000000
+DDR_NITRO_SECURE_REGION_START := 0x8AE00000
+DDR_NITRO_SECURE_REGION_END := 0x8D000000
diff --git a/plat/brcm/board/stingray/bcm958742t.mk b/plat/brcm/board/stingray/bcm958742t.mk
new file mode 100644
index 000000000..5e164b856
--- /dev/null
+++ b/plat/brcm/board/stingray/bcm958742t.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2015 - 2020, Broadcom
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+#######################################################
+# Board config file for bcm958742t Stingray SST100
+#######################################################
+BOARD_FAMILY := "<bcm958742t.h>"
+$(eval $(call add_define,BOARD_FAMILY))
+
+# Board has internal programmable regulator
+IHOST_REG_TYPE := IHOST_REG_INTEGRATED
+$(eval $(call add_define,IHOST_REG_TYPE))
+
+# Board has internal programmable regulator
+VDDC_REG_TYPE := VDDC_REG_INTEGRATED
+$(eval $(call add_define,VDDC_REG_TYPE))
diff --git a/plat/brcm/board/stingray/driver/ddr/soc/include/board_family.h b/plat/brcm/board/stingray/driver/ddr/soc/include/board_family.h
new file mode 100644
index 000000000..b2427cf1d
--- /dev/null
+++ b/plat/brcm/board/stingray/driver/ddr/soc/include/board_family.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BOARD_FAMILY_H
+#define BOARD_FAMILY_H
+
+#if defined(DRIVER_SPD_ENABLE) && !defined(DRIVER_SPD_SPOOF)
+#include <spd.h>
+#endif
+
+#ifdef USE_GPIO
+/* max number of supported GPIOs to construct the bitmap for board detection */
+#define MAX_NR_GPIOS 4
+
+/* max GPIO bitmap value */
+#define MAX_GPIO_BITMAP_VAL (BIT(MAX_NR_GPIOS) - 1)
+#endif
+
+struct mcb_ref_group {
+ uint32_t mcb_ref;
+ unsigned int *mcb_cfg;
+};
+
+#define MCB_REF_GROUP(ref) \
+{ \
+ .mcb_ref = 0x ## ref, \
+ .mcb_cfg = mcb_ ## ref, \
+}
+
+#endif
diff --git a/plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.c b/plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.c
new file mode 100644
index 000000000..74d207735
--- /dev/null
+++ b/plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2016-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+static void brcm_stingray_pnor_pinmux_init(void)
+{
+ unsigned int i;
+
+ INFO(" - pnor pinmux init start.\n");
+
+ /* Set PNOR_ADV_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2dc),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set PNOR_BAA_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2e0),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set PNOR_BLS_0_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2e4),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set PNOR_BLS_1_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2e8),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set PNOR_CRE_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2ec),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set PNOR_CS_2_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2f0),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set PNOR_CS_1_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2f4),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set PNOR_CS_0_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2f8),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set PNOR_WE_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x2fc),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set PNOR_OE_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x300),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set PNOR_INTR_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x304),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set PNOR_DAT_x_MODE_SEL_CONTROL.fsel = 0x2 */
+ for (i = 0; i < 0x40; i += 0x4) {
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x308 + i),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+ }
+
+ /* Set NAND_CE1_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x348),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set NAND_CE0_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x34c),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set NAND_WE_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x350),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set NAND_WP_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x354),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set NAND_RE_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x358),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set NAND_RDY_BSY_N_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x35c),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set NAND_IOx_0_MODE_SEL_CONTROL.fsel = 0x2 */
+ for (i = 0; i < 0x40; i += 0x4) {
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x360 + i),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+ }
+
+ /* Set NAND_ALE_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x3a0),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ /* Set NAND_CLE_MODE_SEL_CONTROL.fsel = 0x2 */
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x3a4),
+ MODE_SEL_CONTROL_FSEL_MASK,
+ MODE_SEL_CONTROL_FSEL_MODE2);
+
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x40), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x44), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x48), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x4c), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x50), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x54), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x58), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x5c), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x60), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x64), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x68), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x6c), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x70), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x74), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x78), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x7c), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x80), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x84), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x88), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x8c), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x90), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x94), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x98), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0x9c), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0xa0), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0xa4), (7 << 1), 0x8);
+ mmio_clrsetbits_32((uintptr_t)(HSLS_IOPAD_BASE + 0xa8), (7 << 1), 0x8);
+
+ INFO(" - pnor pinmux init done.\n");
+}
+
+#if BL2_TEST_EXT_SRAM
+#define SRAM_CHECKS_GRANUL 0x100000
+#define SRAM_CHECKS_CNT 8
+static unsigned int sram_checks[SRAM_CHECKS_CNT] = {
+ /* offset, magic */
+ 0xd00dfeed,
+ 0xfadebabe,
+ 0xc001d00d,
+ 0xa5a5b5b5,
+ 0x5a5a5b5b,
+ 0xc5c5d5d5,
+ 0x5c5c5d5d,
+ 0xe5e5f5f5,
+};
+#endif
+
+static void brcm_stingray_pnor_sram_init(void)
+{
+ unsigned int val, tmp;
+#if BL2_TEST_EXT_SRAM
+ unsigned int off, i;
+#endif
+ INFO(" - pnor sram init start.\n");
+
+ /* Enable PNOR Clock */
+ INFO(" -- enable pnor clock\n");
+ mmio_write_32((uintptr_t)(PNOR_IDM_IO_CONTROL_DIRECT), 0x1);
+ udelay(500);
+
+ /* Reset PNOR */
+ INFO(" -- reset pnor\n");
+ mmio_setbits_32((uintptr_t)(PNOR_IDM_IO_RESET_CONTROL), 0x1);
+ udelay(500);
+ mmio_clrbits_32((uintptr_t)(PNOR_IDM_IO_RESET_CONTROL), 0x1);
+ udelay(500);
+
+ /* Configure slave address to chip-select mapping */
+ INFO(" -- configure pnor slave address to chip-select mapping\n");
+ /* 0x74000000-0x75ffffff => CS0 (32MB) */
+ val = (0xfe << PNOR_ICFG_CS_x_MASK0_SHIFT);
+ val |= (0x74);
+ mmio_write_32((uintptr_t)(PNOR_ICFG_CS_0), val);
+ /* 0x76000000-0x77ffffff => CS1 (32MB) */
+ val = (0xfe << PNOR_ICFG_CS_x_MASK0_SHIFT);
+ val |= (0x76);
+ mmio_write_32((uintptr_t)(PNOR_ICFG_CS_1), val);
+ /* 0xffffffff-0xffffffff => CS2 (0MB) */
+ val = (0x00 << PNOR_ICFG_CS_x_MASK0_SHIFT);
+ val |= (0xff);
+ mmio_write_32((uintptr_t)(PNOR_ICFG_CS_2), val);
+
+ /* Print PNOR ID */
+ tmp = 0x0;
+ val = mmio_read_32((uintptr_t)(PNOR_REG_PERIPH_ID0));
+ tmp |= (val & PNOR_REG_PERIPH_IDx_MASK);
+ val = mmio_read_32((uintptr_t)(PNOR_REG_PERIPH_ID1));
+ tmp |= ((val & PNOR_REG_PERIPH_IDx_MASK) << 8);
+ val = mmio_read_32((uintptr_t)(PNOR_REG_PERIPH_ID2));
+ tmp |= ((val & PNOR_REG_PERIPH_IDx_MASK) << 16);
+ val = mmio_read_32((uintptr_t)(PNOR_REG_PERIPH_ID3));
+ tmp |= ((val & PNOR_REG_PERIPH_IDx_MASK) << 24);
+ INFO(" -- pnor primecell_id = 0x%x\n", tmp);
+
+ /* PNOR set_cycles */
+#ifdef EMULATION_SETUP
+ val = 0x00129A44;
+#else
+ val = 0x00125954; /* 0x00002DEF; */
+#endif
+ mmio_write_32((uintptr_t)(PNOR_REG_SET_CYCLES), val);
+ INFO(" -- pnor set_cycles = 0x%x\n", val);
+
+ /* PNOR set_opmode */
+ val = 0x0;
+#ifdef EMULATION_SETUP
+ /* TODO: Final values to be provided by DV folks */
+ val &= ~(0x7 << 7); /* set_wr_bl */
+ val &= ~(0x7 << 3); /* set_rd_bl */
+ val &= ~(0x3);
+ val |= (0x1); /* set_mw */
+#else
+ /* TODO: Final values to be provided by DV folks */
+ val &= ~(0x7 << 7); /* set_wr_bl */
+ val &= ~(0x7 << 3); /* set_rd_bl */
+ val &= ~(0x3);
+ val |= (0x1); /* set_mw */
+#endif
+ mmio_write_32((uintptr_t)(PNOR_REG_SET_OPMODE), val);
+ INFO(" -- pnor set_opmode = 0x%x\n", val);
+
+#ifndef EMULATION_SETUP
+ /* Actual SRAM chip will require self-refresh */
+ val = 0x1;
+ mmio_write_32((uintptr_t)(PNOR_REG_REFRESH_0), val);
+ INFO(" -- pnor refresh_0 = 0x%x\n", val);
+#endif
+
+#if BL2_TEST_EXT_SRAM
+ /* Check PNOR SRAM access */
+ for (off = 0; off < NOR_SIZE; off += SRAM_CHECKS_GRANUL) {
+ i = (off / SRAM_CHECKS_GRANUL) % SRAM_CHECKS_CNT;
+ val = sram_checks[i];
+ INFO(" -- pnor sram write addr=0x%lx value=0x%lx\n",
+ (unsigned long)(NOR_BASE_ADDR + off),
+ (unsigned long)val);
+ mmio_write_32((uintptr_t)(NOR_BASE_ADDR + off), val);
+ }
+ tmp = 0;
+ for (off = 0; off < NOR_SIZE; off += SRAM_CHECKS_GRANUL) {
+ i = (off / SRAM_CHECKS_GRANUL) % SRAM_CHECKS_CNT;
+ val = mmio_read_32((uintptr_t)(NOR_BASE_ADDR + off));
+ INFO(" -- pnor sram read addr=0x%lx value=0x%lx\n",
+ (unsigned long)(NOR_BASE_ADDR + off),
+ (unsigned long)val);
+ if (val == sram_checks[i])
+ tmp++;
+ }
+ INFO(" -- pnor sram checks pass=%d total=%d\n",
+ tmp, (NOR_SIZE / SRAM_CHECKS_GRANUL));
+
+ if (tmp != (NOR_SIZE / SRAM_CHECKS_GRANUL)) {
+ INFO(" - pnor sram init failed.\n");
+ while (1)
+ ;
+ } else {
+ INFO(" - pnor sram init done.\n");
+ }
+#endif
+}
+
+void ext_sram_init(void)
+{
+ INFO("%s start.\n", __func__);
+
+ brcm_stingray_pnor_pinmux_init();
+
+ brcm_stingray_pnor_sram_init();
+
+ INFO("%s done.\n", __func__);
+}
diff --git a/plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.h b/plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.h
new file mode 100644
index 000000000..85086538f
--- /dev/null
+++ b/plat/brcm/board/stingray/driver/ext_sram_init/ext_sram_init.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2016-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EXT_SRAM_INIT_H
+#define EXT_SRAM_INIT_H
+
+void ext_sram_init(void);
+#endif
diff --git a/plat/brcm/board/stingray/driver/ihost_pll_config.c b/plat/brcm/board/stingray/driver/ihost_pll_config.c
new file mode 100644
index 000000000..118492872
--- /dev/null
+++ b/plat/brcm/board/stingray/driver/ihost_pll_config.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2016-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include <dmu.h>
+
+#define IHOST0_CONFIG_ROOT 0x66000000
+#define IHOST1_CONFIG_ROOT 0x66002000
+#define IHOST2_CONFIG_ROOT 0x66004000
+#define IHOST3_CONFIG_ROOT 0x66006000
+#define A72_CRM_PLL_PWR_ON 0x00000070
+#define A72_CRM_PLL_PWR_ON__PLL0_RESETB_R 4
+#define A72_CRM_PLL_PWR_ON__PLL0_POST_RESETB_R 5
+#define A72_CRM_PLL_CHNL_BYPS_EN 0x000000ac
+#define A72_CRM_PLL_CHNL_BYPS_EN__PLL_0_CHNL_0_BYPS_EN_R 0
+#define A72_CRM_PLL_CHNL_BYPS_EN_DATAMASK 0x0000ec1f
+#define A72_CRM_PLL_CMD 0x00000080
+#define A72_CRM_PLL_CMD__UPDATE_PLL0_FREQUENCY_VCO_R 0
+#define A72_CRM_PLL_CMD__UPDATE_PLL0_FREQUENCY_POST_R 1
+#define A72_CRM_PLL_STATUS 0x00000084
+#define A72_CRM_PLL_STATUS__PLL0_LOCK_R 9
+#define A72_CRM_PLL0_CTRL1 0x00000100
+#define A72_CRM_PLL0_CTRL2 0x00000104
+#define A72_CRM_PLL0_CTRL3 0x00000108
+#define A72_CRM_PLL0_CTRL3__PLL0_PDIV_R 12
+#define A72_CRM_PLL0_CTRL4 0x0000010c
+#define A72_CRM_PLL0_CTRL4__PLL0_KP_R 0
+#define A72_CRM_PLL0_CTRL4__PLL0_KI_R 4
+#define A72_CRM_PLL0_CTRL4__PLL0_KA_R 7
+#define A72_CRM_PLL0_CTRL4__PLL0_FREFEFF_INFO_R 10
+
+#define PLL_MODE_VCO 0x0
+#define PLL_MODE_BYPASS 0x1
+#define PLL_RESET_TYPE_PLL 0x1
+#define PLL_RESET_TYPE_POST 0x2
+#define PLL_VCO 0x1
+#define PLL_POSTDIV 0x2
+#define ARM_FREQ_3G PLL_FREQ_FULL
+#define ARM_FREQ_1P5G PLL_FREQ_HALF
+#define ARM_FREQ_750M PLL_FREQ_QRTR
+
+static unsigned int ARMCOE_crm_getBaseAddress(unsigned int cluster_num)
+{
+ unsigned int ihostx_config_root;
+
+ switch (cluster_num) {
+ case 0:
+ default:
+ ihostx_config_root = IHOST0_CONFIG_ROOT;
+ break;
+ case 1:
+ ihostx_config_root = IHOST1_CONFIG_ROOT;
+ break;
+ case 2:
+ ihostx_config_root = IHOST2_CONFIG_ROOT;
+ break;
+ case 3:
+ ihostx_config_root = IHOST3_CONFIG_ROOT;
+ break;
+ }
+
+ return ihostx_config_root;
+}
+
+static void ARMCOE_crm_pllAssertReset(unsigned int cluster_num,
+ unsigned int reset_type)
+{
+ unsigned long ihostx_config_root;
+ unsigned int pll_rst_ctrl;
+
+ ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
+ pll_rst_ctrl = mmio_read_32(ihostx_config_root + A72_CRM_PLL_PWR_ON);
+
+ // PLL reset
+ if (reset_type & PLL_RESET_TYPE_PLL) {
+ pll_rst_ctrl &= ~(0x1<<A72_CRM_PLL_PWR_ON__PLL0_RESETB_R);
+ }
+ // post-div channel reset
+ if (reset_type & PLL_RESET_TYPE_POST) {
+ pll_rst_ctrl &= ~(0x1<<A72_CRM_PLL_PWR_ON__PLL0_POST_RESETB_R);
+ }
+
+ mmio_write_32(ihostx_config_root + A72_CRM_PLL_PWR_ON, pll_rst_ctrl);
+}
+
+static void ARMCOE_crm_pllSetMode(unsigned int cluster_num, unsigned int mode)
+{
+ unsigned long ihostx_config_root;
+ unsigned int pll_byp_ctrl;
+
+ ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
+ pll_byp_ctrl = mmio_read_32(ihostx_config_root +
+ A72_CRM_PLL_CHNL_BYPS_EN);
+
+ if (mode == PLL_MODE_VCO) {
+ // use PLL DCO output
+ pll_byp_ctrl &=
+ ~BIT(A72_CRM_PLL_CHNL_BYPS_EN__PLL_0_CHNL_0_BYPS_EN_R);
+ } else {
+ // use PLL bypass sources
+ pll_byp_ctrl |=
+ BIT(A72_CRM_PLL_CHNL_BYPS_EN__PLL_0_CHNL_0_BYPS_EN_R);
+ }
+
+ mmio_write_32(ihostx_config_root + A72_CRM_PLL_CHNL_BYPS_EN,
+ pll_byp_ctrl);
+}
+
+static void ARMCOE_crm_pllFreqSet(unsigned int cluster_num,
+ unsigned int ihost_pll_freq_sel,
+ unsigned int pdiv)
+{
+ unsigned int ndiv_int;
+ unsigned int ndiv_frac_low, ndiv_frac_high;
+ unsigned long ihostx_config_root;
+
+ ndiv_frac_low = 0x0;
+ ndiv_frac_high = 0x0;
+
+ if (ihost_pll_freq_sel == ARM_FREQ_3G) {
+ ndiv_int = 0x78;
+ } else if (ihost_pll_freq_sel == ARM_FREQ_1P5G) {
+ ndiv_int = 0x3c;
+ } else if (ihost_pll_freq_sel == ARM_FREQ_750M) {
+ ndiv_int = 0x1e;
+ } else {
+ return;
+ }
+
+ ndiv_int &= 0x3FF; // low 10 bits
+ ndiv_frac_low &= 0x3FF;
+ ndiv_frac_high &= 0x3FF;
+
+ ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
+
+ mmio_write_32(ihostx_config_root+A72_CRM_PLL0_CTRL1, ndiv_frac_low);
+ mmio_write_32(ihostx_config_root+A72_CRM_PLL0_CTRL2, ndiv_frac_high);
+ mmio_write_32(ihostx_config_root+A72_CRM_PLL0_CTRL3,
+ ndiv_int |
+ ((pdiv << A72_CRM_PLL0_CTRL3__PLL0_PDIV_R & 0xF000)));
+
+ mmio_write_32(ihostx_config_root + A72_CRM_PLL0_CTRL4,
+ /* From Section 10 of PLL spec */
+ (3 << A72_CRM_PLL0_CTRL4__PLL0_KP_R) |
+ /* From Section 10 of PLL spec */
+ (2 << A72_CRM_PLL0_CTRL4__PLL0_KI_R) |
+ /* Normal mode (i.e. not fast-locking) */
+ (0 << A72_CRM_PLL0_CTRL4__PLL0_KA_R) |
+ /* 50 MHz */
+ (50 << A72_CRM_PLL0_CTRL4__PLL0_FREFEFF_INFO_R));
+}
+
+static void ARMCOE_crm_pllDeassertReset(unsigned int cluster_num,
+ unsigned int reset_type)
+{
+ unsigned long ihostx_config_root;
+ unsigned int pll_rst_ctrl;
+
+ ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
+ pll_rst_ctrl = mmio_read_32(ihostx_config_root + A72_CRM_PLL_PWR_ON);
+
+ // PLL reset
+ if (reset_type & PLL_RESET_TYPE_PLL) {
+ pll_rst_ctrl |= (0x1 << A72_CRM_PLL_PWR_ON__PLL0_RESETB_R);
+ }
+
+ // post-div channel reset
+ if (reset_type & PLL_RESET_TYPE_POST) {
+ pll_rst_ctrl |= (0x1 << A72_CRM_PLL_PWR_ON__PLL0_POST_RESETB_R);
+ }
+
+ mmio_write_32(ihostx_config_root + A72_CRM_PLL_PWR_ON, pll_rst_ctrl);
+}
+
+static void ARMCOE_crm_pllUpdate(unsigned int cluster_num, unsigned int type)
+{
+ unsigned long ihostx_config_root;
+ unsigned int pll_cmd;
+
+ ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
+ pll_cmd = mmio_read_32(ihostx_config_root + A72_CRM_PLL_CMD);
+
+ // VCO update
+ if (type & PLL_VCO) {
+ pll_cmd |= BIT(A72_CRM_PLL_CMD__UPDATE_PLL0_FREQUENCY_VCO_R);
+ }
+ // post-div channel update
+ if (type & PLL_POSTDIV) {
+ pll_cmd |= BIT(A72_CRM_PLL_CMD__UPDATE_PLL0_FREQUENCY_POST_R);
+ }
+
+ mmio_write_32(ihostx_config_root+A72_CRM_PLL_CMD, pll_cmd);
+}
+
+static void insert_delay(unsigned int delay)
+{
+ volatile unsigned int index;
+
+ for (index = 0; index < delay; index++)
+ ;
+}
+
+
+/*
+ * Returns 1 if PLL locked within certain interval
+ */
+static unsigned int ARMCOE_crm_pllIsLocked(unsigned int cluster_num)
+{
+ unsigned long ihostx_config_root;
+ unsigned int lock_status;
+ unsigned int i;
+
+ ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
+
+ /* wait a while for pll to lock before returning from this function */
+ for (i = 0; i < 1500; i++) {
+ insert_delay(256);
+ lock_status = mmio_read_32(ihostx_config_root +
+ A72_CRM_PLL_STATUS);
+ if (lock_status & BIT(A72_CRM_PLL_STATUS__PLL0_LOCK_R))
+ return 1;
+ }
+
+ ERROR("PLL of Cluster #%u failed to lock\n", cluster_num);
+ return 0;
+}
+
+/*
+ * ihost PLL Variable Frequency Configuration
+ *
+ * Frequency Limit {VCO,ARM} (GHz):
+ * 0 - no limit,
+ * 1 - {3.0,1.5},
+ * 2 - {4.0,2.0},
+ * 3 - {5.0,2.5}
+ */
+uint32_t bcm_set_ihost_pll_freq(uint32_t cluster_num, int ihost_pll_freq_sel)
+{
+ NOTICE("cluster: %u, freq_sel:0x%x\n", cluster_num, ihost_pll_freq_sel);
+
+ //bypass PLL
+ ARMCOE_crm_pllSetMode(cluster_num, PLL_MODE_BYPASS);
+ //assert reset
+ ARMCOE_crm_pllAssertReset(cluster_num,
+ PLL_RESET_TYPE_PLL | PLL_RESET_TYPE_POST);
+ //set ndiv_int for different freq
+ ARMCOE_crm_pllFreqSet(cluster_num, ihost_pll_freq_sel, 0x1);
+ //de-assert reset
+ ARMCOE_crm_pllDeassertReset(cluster_num, PLL_RESET_TYPE_PLL);
+ ARMCOE_crm_pllUpdate(cluster_num, PLL_VCO);
+ //waiting for PLL lock
+ ARMCOE_crm_pllIsLocked(cluster_num);
+ ARMCOE_crm_pllDeassertReset(cluster_num, PLL_RESET_TYPE_POST);
+ //disable bypass PLL
+ ARMCOE_crm_pllSetMode(cluster_num, PLL_MODE_VCO);
+
+ return 0;
+}
+
+uint32_t bcm_get_ihost_pll_freq(uint32_t cluster_num)
+{
+ unsigned long ihostx_config_root;
+ uint32_t ndiv_int;
+ uint32_t ihost_pll_freq_sel;
+
+ ihostx_config_root = ARMCOE_crm_getBaseAddress(cluster_num);
+ ndiv_int = mmio_read_32(ihostx_config_root+A72_CRM_PLL0_CTRL3) & 0x3FF;
+
+ if (ndiv_int == 0x78) {
+ ihost_pll_freq_sel = ARM_FREQ_3G;
+ } else if (ndiv_int == 0x3c) {
+ ihost_pll_freq_sel = ARM_FREQ_1P5G;
+ } else if (ndiv_int == 0x1e) {
+ ihost_pll_freq_sel = ARM_FREQ_750M;
+ } else {
+ /* return unlimit otherwise*/
+ ihost_pll_freq_sel = 0;
+ }
+ return ihost_pll_freq_sel;
+}
diff --git a/plat/brcm/board/stingray/driver/plat_emmc.c b/plat/brcm/board/stingray/driver/plat_emmc.c
new file mode 100644
index 000000000..82085e1af
--- /dev/null
+++ b/plat/brcm/board/stingray/driver/plat_emmc.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2016 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#define ICFG_IPROC_IOPAD_CTRL_4 (IPROC_ROOT + 0x9c0)
+#define ICFG_IPROC_IOPAD_CTRL_5 (IPROC_ROOT + 0x9c4)
+#define ICFG_IPROC_IOPAD_CTRL_6 (IPROC_ROOT + 0x9c8)
+#define ICFG_IPROC_IOPAD_CTRL_7 (IPROC_ROOT + 0x9cc)
+
+#define IOPAD_CTRL4_SDIO0_CD_IND_R 30
+#define IOPAD_CTRL4_SDIO0_CD_SRC_R 31
+#define IOPAD_CTRL4_SDIO0_CD_HYS_R 29
+#define IOPAD_CTRL4_SDIO0_CD_PULL_R 28
+#define IOPAD_CTRL4_SDIO0_CD_DRIVE_R 24
+#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_SRC_R 23
+#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_HYS_R 21
+#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_DRIVE_R 17
+
+#define IOPAD_CTRL4_SDIO0_DATA0_SRC_R 15
+#define IOPAD_CTRL4_SDIO0_DATA0_HYS_R 13
+#define IOPAD_CTRL4_SDIO0_DATA0_DRIVE_R 9
+#define IOPAD_CTRL4_SDIO0_DATA1_SRC_R 7
+#define IOPAD_CTRL4_SDIO0_DATA1_HYS_R 5
+#define IOPAD_CTRL4_SDIO0_DATA1_DRIVE_R 1
+
+#define IOPAD_CTRL5_SDIO0_DATA2_SRC_R 31
+#define IOPAD_CTRL5_SDIO0_DATA2_HYS_R 29
+#define IOPAD_CTRL5_SDIO0_DATA2_DRIVE_R 25
+#define IOPAD_CTRL5_SDIO0_DATA3_SRC_R 23
+#define IOPAD_CTRL5_SDIO0_DATA3_IND_R 22
+#define IOPAD_CTRL5_SDIO0_DATA3_HYS_R 21
+#define IOPAD_CTRL5_SDIO0_DATA3_DRIVE_R 17
+#define IOPAD_CTRL5_SDIO0_DATA4_SRC_R 15
+#define IOPAD_CTRL5_SDIO0_DATA4_HYS_R 13
+#define IOPAD_CTRL5_SDIO0_DATA4_DRIVE_R 9
+#define IOPAD_CTRL5_SDIO0_DATA5_SRC_R 7
+#define IOPAD_CTRL5_SDIO0_DATA5_HYS_R 5
+#define IOPAD_CTRL5_SDIO0_DATA5_DRIVE_R 1
+
+#define IOPAD_CTRL6_SDIO0_DATA6_SRC_R 31
+#define IOPAD_CTRL6_SDIO0_DATA6_HYS_R 29
+#define IOPAD_CTRL6_SDIO0_DATA6_DRIVE_R 25
+#define IOPAD_CTRL6_SDIO0_DATA7_SRC_R 23
+#define IOPAD_CTRL6_SDIO0_DATA7_HYS_R 21
+#define IOPAD_CTRL6_SDIO0_DATA7_DRIVE_R 17
+
+void emmc_soft_reset(void)
+{
+ uint32_t val = 0;
+
+ val = (BIT(IOPAD_CTRL6_SDIO0_DATA7_SRC_R) |
+ BIT(IOPAD_CTRL6_SDIO0_DATA7_HYS_R) |
+ BIT(IOPAD_CTRL6_SDIO0_DATA7_DRIVE_R) |
+ BIT(IOPAD_CTRL6_SDIO0_DATA6_SRC_R) |
+ BIT(IOPAD_CTRL6_SDIO0_DATA6_HYS_R) |
+ BIT(IOPAD_CTRL6_SDIO0_DATA6_DRIVE_R));
+
+ mmio_write_32(ICFG_IPROC_IOPAD_CTRL_6, val);
+
+ val = (BIT(IOPAD_CTRL5_SDIO0_DATA3_SRC_R) |
+ BIT(IOPAD_CTRL5_SDIO0_DATA3_HYS_R) |
+ BIT(IOPAD_CTRL5_SDIO0_DATA3_DRIVE_R) |
+ BIT(IOPAD_CTRL5_SDIO0_DATA4_SRC_R) |
+ BIT(IOPAD_CTRL5_SDIO0_DATA4_HYS_R) |
+ BIT(IOPAD_CTRL5_SDIO0_DATA4_DRIVE_R) |
+ BIT(IOPAD_CTRL5_SDIO0_DATA5_SRC_R) |
+ BIT(IOPAD_CTRL5_SDIO0_DATA5_HYS_R) |
+ BIT(IOPAD_CTRL5_SDIO0_DATA5_DRIVE_R));
+
+ mmio_write_32(ICFG_IPROC_IOPAD_CTRL_5, val);
+
+ val = (BIT(IOPAD_CTRL4_SDIO0_DATA0_SRC_R) |
+ BIT(IOPAD_CTRL4_SDIO0_DATA0_HYS_R) |
+ BIT(IOPAD_CTRL4_SDIO0_DATA0_DRIVE_R) |
+ BIT(IOPAD_CTRL4_SDIO0_DATA1_SRC_R) |
+ BIT(IOPAD_CTRL4_SDIO0_DATA1_HYS_R) |
+ BIT(IOPAD_CTRL4_SDIO0_DATA1_DRIVE_R) |
+ BIT(IOPAD_CTRL5_SDIO0_DATA2_SRC_R) |
+ BIT(IOPAD_CTRL5_SDIO0_DATA2_HYS_R) |
+ BIT(IOPAD_CTRL5_SDIO0_DATA2_DRIVE_R));
+
+ mmio_write_32(ICFG_IPROC_IOPAD_CTRL_6, val);
+
+ val = (BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_SRC_R) |
+ BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_HYS_R) |
+ BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_DRIVE_R) |
+ BIT(IOPAD_CTRL4_SDIO0_CD_SRC_R) |
+ BIT(IOPAD_CTRL4_SDIO0_CD_HYS_R));
+
+ /*
+ * set pull-down, clear pull-up=0
+ * bit 12: pull-down bit 11: pull-up
+ * Note: In emulation, this pull-down setting was not
+ * sufficient. Board design likely requires pull down on
+ * this pin for eMMC.
+ */
+
+ val |= BIT(IOPAD_CTRL4_SDIO0_CD_PULL_R);
+
+ mmio_write_32(ICFG_IPROC_IOPAD_CTRL_4, val);
+}
diff --git a/plat/brcm/board/stingray/driver/swreg.c b/plat/brcm/board/stingray/driver/swreg.c
new file mode 100644
index 000000000..2b7c53b53
--- /dev/null
+++ b/plat/brcm/board/stingray/driver/swreg.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2017 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <sr_utils.h>
+#include <swreg.h>
+
+#define MIN_VOLT 760000
+#define MAX_VOLT 1060000
+
+#define BSTI_WRITE 0x1
+#define BSTI_READ 0x2
+#define BSTI_COMMAND_TA 0x2
+#define BSTI_COMMAND_DATA 0xFF
+#define BSTI_CONTROL_VAL 0x81
+#define BSTI_CONTROL_BUSY 0x100
+#define BSTI_TOGGLE_BIT 0x2
+#define BSTI_CONFI_DONE_MASK 0xFFFFFFFD
+#define BSTI_REG_DATA_MASK 0xFFFF
+#define BSTI_CMD(sb, op, pa, ra, ta, data) \
+ ((((sb) & 0x3) << 30) | (((op) & 0x3) << 28) | \
+ (((pa) & 0x1F) << 23) | (((ra) & 0x1F) << 18) | \
+ (((ta) & 0x3) << 16) | (data))
+
+#define PHY_REG0 0x0
+#define PHY_REG1 0x1
+#define PHY_REG4 0x4
+#define PHY_REG5 0x5
+#define PHY_REG6 0x6
+#define PHY_REG7 0x7
+#define PHY_REGC 0xc
+
+#define IHOST_VDDC_DATA 0x560
+#define DDR_CORE_DATA 0x2560
+#define UPDATE_POS_EDGE(data, set) ((data) | ((set) << 1))
+
+/*
+ * Formula for SR A2 reworked board:
+ * step = ((vol/(1.4117 * 0.98)) - 500000)/3125
+ * where,
+ * vol - input voltage
+ * 500000 - Reference voltage
+ * 3125 - one step value
+ */
+#define A2_VOL_REF 500000
+#define ONE_STEP_VALUE 3125
+#define VOL_DIV(vol) (((vol*10000ull)/(14117*98ull)) * 100ull)
+#define STEP_VALUE(vol) \
+ ((((((VOL_DIV(vol)) - A2_VOL_REF) / ONE_STEP_VALUE) & 0xFF) << 8) | 4)
+
+#define B0_VOL_REF ((500000/100)*98)
+#define B0_ONE_STEP_VALUE 3125
+/*
+ * Formula for SR B0 chip for IHOST12/03 and VDDC_CORE
+ * step = ((vol/1.56) - (500000 * 0.98))/3125
+ * where,
+ * vol - input voltage
+ * 500000 - Reference voltage
+ * 3125 - one step value
+ */
+#define B0_VOL_DIV(vol) (((vol)*100ull)/156)
+#define B0_STEP_VALUE(vol) \
+ ((((((B0_VOL_DIV(vol)) - B0_VOL_REF) / B0_ONE_STEP_VALUE) \
+ & 0xFF) << 8) | 4)
+
+/*
+ * Formula for SR B0 chip for DDR-CORE
+ * step = ((vol/1) - (500000 * 0.98))/3125
+ * where,
+ * vol - input voltage
+ * 500000 - Reference voltage
+ * 3125 - one step value
+ */
+#define B0_DDR_VDDC_VOL_DIV(vol) ((vol)/1)
+#define B0_DDR_VDDC_STEP_VALUE(vol) \
+ ((((((B0_DDR_VDDC_VOL_DIV(vol)) - B0_VOL_REF) / B0_ONE_STEP_VALUE) \
+ & 0xFF) << 8) | 4)
+
+#define MAX_SWREG_CNT 8
+#define MAX_ADDR_PER_SWREG 16
+#define MAX_REG_ADDR 0xF
+#define MIN_REG_ADDR 0x0
+
+static const char *sw_reg_name[MAX_SWREG_CNT] = {
+ "DDR_VDDC",
+ "IHOST03",
+ "IHOST12",
+ "IHOST_ARRAY",
+ "DDRIO_SLAVE",
+ "VDDC_CORE",
+ "VDDC1",
+ "DDRIO_MASTER"
+};
+
+/* firmware values for all SWREG for 3.3V input operation */
+static const uint16_t swreg_fm_data_bx[MAX_SWREG_CNT][MAX_ADDR_PER_SWREG] = {
+ /* DDR logic: Power Domains independent of 12v or 3p3v */
+ {0x25E0, 0x2D54, 0x0EC6, 0x01EC, 0x28BB, 0x1144, 0x0200, 0x69C0,
+ 0x0010, 0x0EDF, 0x90D7, 0x8000, 0x820C, 0x0003, 0x0001, 0x0000},
+
+ /* ihost03, 3p3V */
+ {0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80,
+ 0x003F, 0x0FFF, 0x90D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000},
+
+ /* ihost12 3p3v */
+ {0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80,
+ 0x003F, 0x0FFF, 0x90D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000},
+
+ /* ihost array */
+ {0x25E0, 0x2D94, 0x0EC6, 0x01EC, 0x2ABB, 0x1144, 0x0340, 0x69C0,
+ 0x0010, 0x0EDF, 0x90D7, 0x8000, 0x860C, 0x0003, 0x0001, 0x0000},
+
+ /* ddr io slave : 3p3v */
+ {0x0560, 0x4438, 0x0000, 0x001F, 0x8028, 0x4444, 0x0300, 0x4380,
+ 0x003F, 0x0FFF, 0x10D7, 0x8000, 0xA70C, 0x0003, 0x0001, 0x0000},
+
+ /* core master 3p3v */
+ {0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80,
+ 0x003F, 0x0FFF, 0x90D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000},
+
+ /* core slave 3p3v */
+ {0x0560, 0x4438, 0x0000, 0x001F, 0x8028, 0x4444, 0x0300, 0x4380,
+ 0x003F, 0x0FFF, 0x10D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000},
+
+ /* ddr io master : 3p3v */
+ {0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80,
+ 0x003F, 0x0FFF, 0x90D7, 0x8000, 0xA70C, 0x0003, 0x0001, 0x0000},
+};
+
+#define FM_DATA swreg_fm_data_bx
+
+static int swreg_poll(void)
+{
+ uint32_t data;
+ int retry = 100;
+
+ do {
+ data = mmio_read_32(BSTI_CONTROL_OFFSET);
+ if ((data & BSTI_CONTROL_BUSY) != BSTI_CONTROL_BUSY)
+ return 0;
+ retry--;
+ udelay(1);
+ } while (retry > 0);
+
+ return -ETIMEDOUT;
+}
+
+static int write_swreg_config(enum sw_reg reg_id, uint32_t addr, uint32_t data)
+{
+ uint32_t cmd;
+ int ret;
+
+ cmd = BSTI_CMD(0x1, BSTI_WRITE, reg_id, addr, BSTI_COMMAND_TA, data);
+ mmio_write_32(BSTI_CONTROL_OFFSET, BSTI_CONTROL_VAL);
+ mmio_write_32(BSTI_COMMAND_OFFSET, cmd);
+ ret = swreg_poll();
+ if (ret) {
+ ERROR("Failed to write swreg %s addr 0x%x\n",
+ sw_reg_name[reg_id-1], addr);
+ return ret;
+ }
+ return ret;
+}
+
+static int read_swreg_config(enum sw_reg reg_id, uint32_t addr, uint32_t *data)
+{
+ uint32_t cmd;
+ int ret;
+
+ cmd = BSTI_CMD(0x1, BSTI_READ, reg_id, addr, BSTI_COMMAND_TA, PHY_REG0);
+ mmio_write_32(BSTI_CONTROL_OFFSET, BSTI_CONTROL_VAL);
+ mmio_write_32(BSTI_COMMAND_OFFSET, cmd);
+ ret = swreg_poll();
+ if (ret) {
+ ERROR("Failed to read swreg %s addr 0x%x\n",
+ sw_reg_name[reg_id-1], addr);
+ return ret;
+ }
+
+ *data = mmio_read_32(BSTI_COMMAND_OFFSET);
+ *data &= BSTI_REG_DATA_MASK;
+ return ret;
+}
+
+static int swreg_config_done(enum sw_reg reg_id)
+{
+ uint32_t read_data;
+ int ret;
+
+ ret = read_swreg_config(reg_id, PHY_REG0, &read_data);
+ if (ret)
+ return ret;
+
+ read_data &= BSTI_CONFI_DONE_MASK;
+ read_data |= BSTI_TOGGLE_BIT;
+ ret = write_swreg_config(reg_id, PHY_REG0, read_data);
+ if (ret)
+ return ret;
+
+ ret = read_swreg_config(reg_id, PHY_REG0, &read_data);
+ if (ret)
+ return ret;
+
+ read_data &= BSTI_CONFI_DONE_MASK;
+ ret = write_swreg_config(reg_id, PHY_REG0, read_data);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+#ifdef DUMP_SWREG
+static void dump_swreg_firmware(void)
+{
+ enum sw_reg reg_id;
+ uint32_t data;
+ int addr;
+ int ret;
+
+ for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) {
+ INFO("SWREG: %s\n", sw_reg_name[reg_id - 1]);
+ for (addr = MIN_REG_ADDR; addr <= MAX_REG_ADDR; addr++) {
+ ret = read_swreg_config(reg_id, addr, &data);
+ if (ret)
+ ERROR("Failed to read offset %d\n", addr);
+ INFO("\t0x%x: 0x%04x\n", addr, data);
+ }
+ }
+}
+#endif
+
+int set_swreg(enum sw_reg reg_id, uint32_t micro_volts)
+{
+ uint32_t step, programmed_step;
+ uint32_t data = IHOST_VDDC_DATA;
+ int ret;
+
+ if ((micro_volts > MAX_VOLT) || (micro_volts < MIN_VOLT)) {
+ ERROR("input voltage out-of-range\n");
+ ret = -EINVAL;
+ goto failed;
+ }
+
+ ret = read_swreg_config(reg_id, PHY_REGC, &programmed_step);
+ if (ret)
+ goto failed;
+
+ if (reg_id == DDR_VDDC)
+ step = B0_DDR_VDDC_STEP_VALUE(micro_volts);
+ else
+ step = B0_STEP_VALUE(micro_volts);
+
+ if ((step >> 8) != (programmed_step >> 8)) {
+ ret = write_swreg_config(reg_id, PHY_REGC, step);
+ if (ret)
+ goto failed;
+
+ if (reg_id == DDR_VDDC)
+ data = DDR_CORE_DATA;
+
+ ret = write_swreg_config(reg_id, PHY_REG0,
+ UPDATE_POS_EDGE(data, 1));
+ if (ret)
+ goto failed;
+
+ ret = write_swreg_config(reg_id, PHY_REG0,
+ UPDATE_POS_EDGE(data, 0));
+ if (ret)
+ goto failed;
+ }
+
+ INFO("%s voltage updated to %duV\n", sw_reg_name[reg_id-1],
+ micro_volts);
+ return ret;
+
+failed:
+ /*
+ * Stop booting if voltages are not set
+ * correctly. Booting will fail at random point
+ * if we continue with wrong voltage settings.
+ */
+ ERROR("Failed to set %s voltage to %duV\n", sw_reg_name[reg_id-1],
+ micro_volts);
+ assert(0);
+
+ return ret;
+}
+
+/* Update SWREG firmware for all power doman for A2 chip */
+int swreg_firmware_update(void)
+{
+ enum sw_reg reg_id;
+ uint32_t data;
+ int addr;
+ int ret;
+
+ /* write firmware values */
+ for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) {
+ /* write higher location first */
+ for (addr = MAX_REG_ADDR; addr >= MIN_REG_ADDR; addr--) {
+ ret = write_swreg_config(reg_id, addr,
+ FM_DATA[reg_id - 1][addr]);
+ if (ret)
+ goto exit;
+ }
+ }
+
+ /* trigger SWREG firmware update */
+ for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) {
+ /*
+ * Slave regulator doesn't have to be updated,
+ * Updating Master is enough
+ */
+ if ((reg_id == DDRIO_SLAVE) || (reg_id == VDDC1))
+ continue;
+
+ ret = swreg_config_done(reg_id);
+ if (ret) {
+ ERROR("Failed to trigger SWREG firmware update for %s\n"
+ , sw_reg_name[reg_id-1]);
+ return ret;
+ }
+ }
+
+ for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) {
+ /*
+ * IHOST_ARRAY will be used on some boards like STRATUS and
+ * there will not be any issue even if it is updated on other
+ * boards where it is not used.
+ */
+ if (reg_id == IHOST_ARRAY)
+ continue;
+
+ for (addr = MIN_REG_ADDR; addr <= MAX_REG_ADDR; addr++) {
+ ret = read_swreg_config(reg_id, addr, &data);
+ if (ret || (!ret &&
+ (data != FM_DATA[reg_id - 1][addr]))) {
+ ERROR("swreg fm update failed: %s at off %d\n",
+ sw_reg_name[reg_id - 1], addr);
+ ERROR("Read val: 0x%x, expected val: 0x%x\n",
+ data, FM_DATA[reg_id - 1][addr]);
+ return -1;
+ }
+ }
+ }
+
+ INFO("Updated SWREG firmware\n");
+
+#ifdef DUMP_SWREG
+ dump_swreg_firmware();
+#endif
+ return ret;
+
+exit:
+ /*
+ * Stop booting if swreg firmware update fails.
+ * Booting will fail at random point if we
+ * continue with wrong voltage settings.
+ */
+ ERROR("Failed to update firmware for %s SWREG\n",
+ sw_reg_name[reg_id-1]);
+ assert(0);
+
+ return ret;
+}
diff --git a/plat/brcm/board/stingray/include/bl33_info.h b/plat/brcm/board/stingray/include/bl33_info.h
new file mode 100644
index 000000000..1dac48c17
--- /dev/null
+++ b/plat/brcm/board/stingray/include/bl33_info.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BL33_INFO_H
+#define BL33_INFO_H
+
+/* Increase version number each time this file is modified */
+#define BL33_INFO_VERSION 4
+
+struct chip_info {
+ unsigned int chip_id;
+ unsigned int rev_id;
+};
+
+struct boot_time_info {
+ unsigned int bl1_start;
+ unsigned int bl1_end;
+ unsigned int bl2_start;
+ unsigned int bl2_end;
+ unsigned int bl31_start;
+ unsigned int bl31_end;
+ unsigned int bl32_start;
+ unsigned int bl32_end;
+ unsigned int bl33_start;
+ unsigned int bl33_prompt;
+ unsigned int bl33_end;
+};
+
+struct bl33_info {
+ unsigned int version;
+ struct chip_info chip;
+ struct boot_time_info boot_time_info;
+};
+
+#endif
diff --git a/plat/brcm/board/stingray/include/board_info.h b/plat/brcm/board/stingray/include/board_info.h
new file mode 100644
index 000000000..89012591e
--- /dev/null
+++ b/plat/brcm/board/stingray/include/board_info.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BOARD_INFO_H
+#define BOARD_INFO_H
+
+#define IHOST_REG_INTEGRATED 0
+#define IHOST_REG_EXT_PROGRAMMABLE 1
+#define IHOST_REG_EXT_FIXED 2
+
+#if defined(IHOST_REG_TYPE)
+ #if ((IHOST_REG_TYPE != IHOST_REG_INTEGRATED) && \
+ (IHOST_REG_TYPE != IHOST_REG_EXT_PROGRAMMABLE) && \
+ (IHOST_REG_TYPE != IHOST_REG_EXT_FIXED))
+ #error "IHOST_REG_TYPE not valid"
+ #endif
+#else
+ #define IHOST_REG_TYPE IHOST_REG_INTEGRATED
+#endif
+
+#define VDDC_REG_INTEGRATED 0
+#define VDDC_REG_EXT_PROGRAMMABLE 1
+#define VDDC_REG_EXT_FIXED 2
+
+#if defined(VDDC_REG_TYPE)
+ #if ((VDDC_REG_TYPE != VDDC_REG_INTEGRATED) && \
+ (VDDC_REG_TYPE != VDDC_REG_EXT_PROGRAMMABLE) && \
+ (VDDC_REG_TYPE != VDDC_REG_EXT_FIXED))
+ #error "VDDC_REG_TYPE not valid"
+ #endif
+#else
+ #define VDDC_REG_TYPE VDDC_REG_INTEGRATED
+#endif
+
+#endif
diff --git a/plat/brcm/board/stingray/include/crmu_def.h b/plat/brcm/board/stingray/include/crmu_def.h
new file mode 100644
index 000000000..ebc2bb65b
--- /dev/null
+++ b/plat/brcm/board/stingray/include/crmu_def.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2019-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CRMU_DEF_H
+#define CRMU_DEF_H
+
+#define CRMU_REGS_BASE 0x66410000
+/* 32 kB IDRAM */
+#define CRMU_IDRAM_BASE_ADDR CRMU_REGS_BASE
+#define CRMU_IDRAM_SIZE 0x8000
+/* 4 kB Scratch RAM */
+#define CRMU_SRAM_BASE (CRMU_IDRAM_BASE_ADDR + CRMU_IDRAM_SIZE)
+#define CRMU_SRAM_SIZE 0x1000
+
+#define CRMU_RESERVED_SPACE 0x3000
+#define CRMU_CORE_BASE (CRMU_SRAM_BASE + CRMU_SRAM_SIZE + \
+ CRMU_RESERVED_SPACE)
+
+#define CRMU_SHARED_SRAM_BASE CRMU_SRAM_BASE
+#define CRMU_SHARED_SRAM_SIZE 0x200
+#define CRMU_CFG_BASE (CRMU_SHARED_SRAM_BASE + \
+ CRMU_SHARED_SRAM_SIZE)
+
+#define CRMU_PWR_GOOD_STATUS CRMU_CORE_BASE
+#define CRMU_PWR_GOOD_STATUS__BBL_POWER_GOOD 0
+#define CRMU_ISO_CELL_CONTROL (CRMU_CORE_BASE + 0x4)
+#define CRMU_ISO_CELL_CONTROL__CRMU_ISO_PDBBL 16
+#define CRMU_ISO_CELL_CONTROL__CRMU_ISO_PDBBL_TAMPER 24
+#define CRMU_SPRU_SOURCE_SEL_STAT (CRMU_CORE_BASE + 0xc)
+#define CRMU_SPRU_SOURCE_SEL_STAT__SPRU_SOURCE_SELECT 0
+#define BSTI_BASE (CRMU_CORE_BASE + 0x28)
+#define BSTI_CONTROL_OFFSET BSTI_BASE
+#define BSTI_COMMAND_OFFSET (BSTI_BASE + 0x4)
+
+#define OCOTP_REGS_BASE (CRMU_CORE_BASE + 0x400)
+
+#define CRMU_TCI_BASE (CRMU_CORE_BASE + 0x800)
+#define CRMU_SWREG_STATUS_ADDR (CRMU_TCI_BASE + 0x0c)
+#define CRMU_CHIP_OTPC_STATUS (CRMU_TCI_BASE + 0x10)
+#define CRMU_CHIP_OTPC_STATUS__OTP_BISR_LOAD_DONE 19
+#define CRMU_BISR_PDG_MASK (CRMU_TCI_BASE + 0x4c)
+#define CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST0 2
+#define CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST1 3
+#define CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST2 4
+#define CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST3 0
+#define CRMU_POWER_POLL (CRMU_TCI_BASE + 0x60)
+#define CRMU_OTP_STATUS CRMU_POWER_POLL
+#define CRMU_OTP_STATUS_BIT 1
+#define CRMU_DDR_PHY_AON_CTRL (CRMU_TCI_BASE + 0x64)
+#define CRMU_DDRPHY2_HW_RESETN_R BIT(21)
+#define CRMU_DDRPHY2_PWROKIN_PHY_R BIT(20)
+#define CRMU_DDRPHY2_PWRONIN_PHY_R BIT(19)
+#define CRMU_DDRPHY2_ISO_PHY_DFI_R BIT(18)
+#define CRMU_DDRPHY2_ISO_PHY_REGS_R BIT(17)
+#define CRMU_DDRPHY2_ISO_PHY_PLL_R BIT(16)
+#define CRMU_DDRPHY1_HW_RESETN_R BIT(13)
+#define CRMU_DDRPHY1_PWROKIN_PHY_R BIT(12)
+#define CRMU_DDRPHY1_PWRONIN_PHY_R BIT(11)
+#define CRMU_DDRPHY1_ISO_PHY_DFI_R BIT(10)
+#define CRMU_DDRPHY1_ISO_PHY_REGS_R BIT(9)
+#define CRMU_DDRPHY1_ISO_PHY_PLL_R BIT(8)
+#define CRMU_DDRPHY0_HW_RESETN_R BIT(5)
+#define CRMU_DDRPHY0_PWROKIN_PHY_R BIT(4)
+#define CRMU_DDRPHY0_PWRONIN_PHY_R BIT(3)
+#define CRMU_DDRPHY0_ISO_PHY_DFI_R BIT(2)
+#define CRMU_DDRPHY0_ISO_PHY_REGS_R BIT(1)
+#define CRMU_DDRPHY0_ISO_PHY_PLL_R BIT(0)
+#define CRMU_EMEM_RESET_N_R BIT(16)
+#define CRMU_EMEM_PRESET_N_R BIT(0)
+#define CRMU_SWREG_CTRL_ADDR (CRMU_TCI_BASE + 0x6c)
+#define CRMU_AON_CTRL1 (CRMU_TCI_BASE + 0x70)
+#define CRMU_AON_CTRL1__LCPLL1_ISO_IN 18
+#define CRMU_AON_CTRL1__LCPLL1_PWRON_LDO 19
+#define CRMU_AON_CTRL1__LCPLL1_PWR_ON 20
+#define CRMU_AON_CTRL1__LCPLL0_ISO_IN 21
+#define CRMU_AON_CTRL1__LCPLL0_PWRON_LDO 22
+#define CRMU_AON_CTRL1__LCPLL0_PWR_ON 23
+#define CRMU_PCIE_LCPLL_PWR_ON_SHIFT 29
+#define CRMU_PCIE_LCPLL_PWR_ON_MASK BIT(CRMU_PCIE_LCPLL_PWR_ON_SHIFT)
+#define CRMU_PCIE_LCPLL_PWRON_LDO_SHIFT 28
+#define CRMU_PCIE_LCPLL_PWRON_LDO_MASK BIT(CRMU_PCIE_LCPLL_PWRON_LDO_SHIFT)
+#define CRMU_PCIE_LCPLL_ISO_IN_SHIFT 27
+#define CRMU_PCIE_LCPLL_ISO_IN_MASK BIT(CRMU_PCIE_LCPLL_ISO_IN_SHIFT)
+#define CRMU_MASTER_AXI_ARUSER_CONFIG (CRMU_TCI_BASE + 0x74)
+#define CRMU_MASTER_AXI_AWUSER_CONFIG (CRMU_TCI_BASE + 0x78)
+#define CRMU_DDR_PHY_AON_CTRL_1 (CRMU_TCI_BASE + 0x8c)
+
+#define CDRU_BASE_ADDR (CRMU_CORE_BASE + 0x1000)
+#define CDRU_MISC_RESET_CONTROL CDRU_BASE_ADDR
+#define CDRU_MISC_RESET_CONTROL_TS_RESET_N 16
+#define CDRU_MISC_RESET_CONTROL__CDRU_USBSS_RESET_N 14
+#define CDRU_MISC_RESET_CONTROL__CDRU_SATA_RESET_N_R 15
+#define CDRU_MISC_RESET_CONTROL__CDRU_MHB_RESET_N_R 13
+#define CDRU_MISC_RESET_CONTROL__CDRU_PCIE_RESET_N_R 3
+#define CDRU_MISC_RESET_CONTROL__CDRU_PM_RESET_N_R 2
+#define CDRU_MISC_RESET_CONTROL__CDRU_NITRO_RESET_N_R 1
+
+#define CDRU_PROC_EVENT_CLEAR (CDRU_BASE_ADDR + 0x48)
+#define CDRU_PROC_EVENT_CLEAR__IH0_CDRU_STANDBYWFIL2 0
+#define CDRU_PROC_EVENT_CLEAR__IH0_CDRU_STANDBYWFI 3
+#define CDRU_PROC_EVENT_CLEAR__IH1_CDRU_STANDBYWFIL2 5
+#define CDRU_PROC_EVENT_CLEAR__IH1_CDRU_STANDBYWFI 8
+#define CDRU_PROC_EVENT_CLEAR__IH2_CDRU_STANDBYWFIL2 10
+#define CDRU_PROC_EVENT_CLEAR__IH2_CDRU_STANDBYWFI 13
+#define CDRU_PROC_EVENT_CLEAR__IH3_CDRU_STANDBYWFIL2 15
+#define CDRU_PROC_EVENT_CLEAR__IH3_CDRU_STANDBYWFI 18
+
+#define CDRU_CHIP_STRAP_CTRL (CDRU_BASE_ADDR + 0x50)
+#define CDRU_CHIP_STRAP_CTRL__SOFTWARE_OVERRIDE 31
+
+#define CDRU_CHIP_IO_PAD_CONTROL (CDRU_BASE_ADDR + 0x58)
+#define CDRU_CHIP_IO_PAD_CONTROL__CDRU_IOMUX_FORCE_PDN_R 8
+#define CDRU_CHIP_IO_PAD_CONTROL__CDRU_IOMUX_FORCE_PAD_IN_R 0
+
+#define CDRU_CHIP_STRAP_DATA_LSW (CDRU_BASE_ADDR + 0x5c)
+#define CDRU_CHIP_STRAP_DATA_LSW__BISR_BYPASS_MODE 18
+#define CDRU_CHIP_STRAP_DATA_LSW__NIC_MODE_MASK BIT(8)
+#define CDRU_CHIP_STRAP_DATA_LSW_PAD_USB_MODE BIT(26)
+
+#define CDRU_CHIP_STRAP_DATA (CDRU_BASE_ADDR + 0x5c)
+#define CDRU_DDR0_CONTROL_OFFSET (CDRU_BASE_ADDR + 0xb8)
+#define CDRU_DDR1_CONTROL_OFFSET (CDRU_BASE_ADDR + 0xbc)
+#define CDRU_DDR2_CONTROL_OFFSET (CDRU_BASE_ADDR + 0xc0)
+#define CRMU_SW_POR_RESET_CTRL (CDRU_BASE_ADDR + 0x100)
+
+#define CDRU_GENPLL2_CONTROL1 (CDRU_BASE_ADDR + 0x1b0)
+#define CDRU_GENPLL2_CONTROL1__CHNL6_FS4_CLK BIT(11)
+#define CDRU_GENPLL5_CONTROL1 (CDRU_BASE_ADDR + 0x24c)
+#define CDRU_GENPLL5_CONTROL1__CHNL0_DME_CLK BIT(6)
+#define CDRU_GENPLL5_CONTROL1__CHNL1_CRYPTO_AE_CLK BIT(7)
+#define CDRU_GENPLL5_CONTROL1__CHNL2_RAID_AE_CLK BIT(8)
+
+#define CDRU_NITRO_CONTROL (CDRU_BASE_ADDR + 0x2c4)
+#define CDRU_NITRO_CONTROL__CDRU_NITRO_SEC_MODE_R 20
+#define CDRU_NITRO_CONTROL__CDRU_NITRO_SEC_OVERRIDE_R 16
+
+#define CDRU_MISC_CLK_ENABLE_CONTROL (CDRU_BASE_ADDR + 0x2c8)
+#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_EMEM2_CLK_EN_R 11
+#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_EMEM1_CLK_EN_R 10
+#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_EMEM0_CLK_EN_R 9
+#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_SATA_CLK_EN_R 8
+#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_USBSS_CLK_EN_R 7
+#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_MHB_CLK_EN_R 6
+#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_HSLS_CLK_EN_R 5
+#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_SCR_CLK_EN_R 4
+#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_FS4_CLK_EN_R 3
+#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_PCIE_CLK_EN_R 2
+#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_PM_CLK_EN_R 1
+#define CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_NITRO_CLK_EN_R 0
+
+#define CDRU_CCN_REGISTER_CONTROL_1 (CDRU_BASE_ADDR + 0x324)
+#define CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_EMEM0_BIT 6
+#define CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_EMEM1_BIT 5
+#define CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_EMEM2_BIT 4
+
+#define CDRU_CHIP_TOP_SPARE_REG0 (CDRU_BASE_ADDR + 0x378)
+#define CDRU_CHIP_TOP_SPARE_REG1 (CDRU_BASE_ADDR + 0x37c)
+
+#define CENTRAL_TIMER_BASE (CRMU_CORE_BASE + 0x5000)
+#define CENTRAL_TIMER_CTRL (CENTRAL_TIMER_BASE + 0x0)
+#define CENTRAL_TIMER_GET_L (CENTRAL_TIMER_BASE + 0x4)
+#define CENTRAL_TIMER_GET_L0 (CENTRAL_TIMER_BASE + 0x8) /* SCR STM */
+#define CENTRAL_TIMER_GET_L1 (CENTRAL_TIMER_BASE + 0xC) /* FS STM */
+#define CENTRAL_TIMER_GET_L2 (CENTRAL_TIMER_BASE + 0x10) /* iHost0 */
+#define CENTRAL_TIMER_GET_L3 (CENTRAL_TIMER_BASE + 0x14) /* iHost1 */
+#define CENTRAL_TIMER_GET_L4 (CENTRAL_TIMER_BASE + 0x18) /* iHost2 */
+#define CENTRAL_TIMER_GET_L5 (CENTRAL_TIMER_BASE + 0x1C) /* iHost3 */
+#define CENTRAL_TIMER_GET_H (CENTRAL_TIMER_BASE + 0x28)
+#define CENTRAL_TIMER_SAT_TMR_ENA (CENTRAL_TIMER_BASE + 0x34)
+#define CENTRAL_TIMER_GET_IHOST_ENA_BASE (CENTRAL_TIMER_GET_L2)
+
+#define CRMU_WDT_REGS_BASE (CRMU_CORE_BASE + 0x6000)
+
+#define CRMU_MAIL_BOX0 (CRMU_CORE_BASE + 0x8024)
+#define CRMU_MAIL_BOX1 (CRMU_CORE_BASE + 0x8028)
+#define CRMU_READ_MAIL_BOX0 (CRMU_CORE_BASE + 0x802c)
+#define CRMU_READ_MAIL_BOX1 (CRMU_CORE_BASE + 0x8030)
+#define AP_TO_SCP_MAILBOX1 CRMU_MAIL_BOX1
+#define SCP_TO_AP_MAILBOX1 CRMU_READ_MAIL_BOX1
+#define CRMU_IHOST_POWER_CONFIG (CRMU_CORE_BASE + 0x8038)
+#define CRMU_RESET_EVENT_LOG (CRMU_CORE_BASE + 0x8064)
+#define CRMU_SOFT_RESET_CTRL (CRMU_CORE_BASE + 0x8090)
+#define CRMU_SOFT_RESET_CTRL__SOFT_PWR_UP_RST 0
+#define CRMU_SOFT_RESET_CTRL__SOFT_SYS_RST 1
+#define CRMU_SPARE_REG_0 (CRMU_CORE_BASE + 0x80b8)
+#define CRMU_SPARE_REG_1 (CRMU_CORE_BASE + 0x80bc)
+#define CRMU_SPARE_REG_2 (CRMU_CORE_BASE + 0x80c0)
+#define CRMU_SPARE_REG_3 (CRMU_CORE_BASE + 0x80c4)
+#define CRMU_SPARE_REG_4 (CRMU_CORE_BASE + 0x80c8)
+#define CRMU_SPARE_REG_5 (CRMU_CORE_BASE + 0x80cc)
+#define CRMU_CORE_ADDR_RANGE0_LOW (CRMU_CORE_BASE + 0x8c30)
+#define CRMU_CORE_ADDR_RANGE1_LOW (CRMU_CORE_BASE + 0x8c38)
+#define CRMU_CORE_ADDR_RANGE2_LOW (CRMU_CORE_BASE + 0x8c40)
+#define CRMU_IHOST_SW_PERSISTENT_REG0 (CRMU_CORE_BASE + 0x8c54)
+#define CRMU_IHOST_SW_PERSISTENT_REG1 (CRMU_CORE_BASE + 0x8c58)
+#define CRMU_IHOST_SW_PERSISTENT_REG2 (CRMU_CORE_BASE + 0x8c5c)
+#define CRMU_IHOST_SW_PERSISTENT_REG3 (CRMU_CORE_BASE + 0x8c60)
+#define CRMU_IHOST_SW_PERSISTENT_REG4 (CRMU_CORE_BASE + 0x8c64)
+#define CRMU_IHOST_SW_PERSISTENT_REG5 (CRMU_CORE_BASE + 0x8c68)
+#define CRMU_IHOST_SW_PERSISTENT_REG6 (CRMU_CORE_BASE + 0x8c6c)
+#define CRMU_IHOST_SW_PERSISTENT_REG7 (CRMU_CORE_BASE + 0x8c70)
+#define CRMU_BBL_AUTH_CHECK (CRMU_CORE_BASE + 0x8c78)
+#define CRMU_SOTP_NEUTRALIZE_ENABLE (CRMU_CORE_BASE + 0x8c84)
+#define CRMU_IHOST_SW_PERSISTENT_REG8 (CRMU_CORE_BASE + 0x8c88)
+#define CRMU_IHOST_SW_PERSISTENT_REG9 (CRMU_CORE_BASE + 0x8c8c)
+#define CRMU_IHOST_SW_PERSISTENT_REG10 (CRMU_CORE_BASE + 0x8c90)
+#define CRMU_IHOST_SW_PERSISTENT_REG11 (CRMU_CORE_BASE + 0x8c94)
+
+#define CNT_CONTROL_BASE (CRMU_CORE_BASE + 0x9000)
+#define CNTCR (CNT_CONTROL_BASE)
+#define CNTCR__EN BIT(0)
+
+#define SPRU_BBL_WDATA (CRMU_CORE_BASE + 0xa000)
+#define SPRU_BBL_CMD (CRMU_CORE_BASE + 0xa004)
+#define SPRU_BBL_CMD__IND_SOFT_RST_N 10
+#define SPRU_BBL_CMD__IND_WR 11
+#define SPRU_BBL_CMD__BBL_ADDR_R 0
+#define SPRU_BBL_CMD__IND_RD 12
+#define SPRU_BBL_CMD__BBL_ADDR_R 0
+#define SPRU_BBL_STATUS (CRMU_CORE_BASE + 0xa008)
+#define SPRU_BBL_STATUS__ACC_DONE 0
+#define SPRU_BBL_RDATA (CRMU_CORE_BASE + 0xa00c)
+
+#endif /* CRMU_DEF_H */
diff --git a/plat/brcm/board/stingray/include/ddr_init.h b/plat/brcm/board/stingray/include/ddr_init.h
new file mode 100644
index 000000000..0c135b1d5
--- /dev/null
+++ b/plat/brcm/board/stingray/include/ddr_init.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDR_INIT_H
+#define DDR_INIT_H
+
+#include <fru.h>
+
+#pragma weak ddr_initialize
+#pragma weak ddr_secure_region_config
+#pragma weak ddr_info_save
+#pragma weak get_active_ddr_channel
+#pragma weak is_warmboot
+
+void ddr_initialize(struct ddr_info *ddr)
+{
+}
+
+void ddr_secure_region_config(uint64_t start, uint64_t end)
+{
+}
+
+void ddr_info_save(void)
+{
+}
+
+unsigned char get_active_ddr_channel(void)
+{
+ return 0;
+}
+
+static inline unsigned int is_warmboot(void)
+{
+ return 0;
+}
+#endif
diff --git a/plat/brcm/board/stingray/include/fsx.h b/plat/brcm/board/stingray/include/fsx.h
new file mode 100644
index 000000000..c52ff0a0d
--- /dev/null
+++ b/plat/brcm/board/stingray/include/fsx.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FSX_H
+#define FSX_H
+
+#include <stdbool.h>
+
+typedef enum FSX_TYPE {
+ eFS4_RAID,
+ eFS4_CRYPTO,
+ eFS6_PKI,
+} eFSX_TYPE;
+
+void fsx_init(eFSX_TYPE fsx_type,
+ unsigned int ring_count,
+ unsigned int dme_count,
+ unsigned int ae_count,
+ unsigned int start_stream_id,
+ unsigned int msi_dev_id,
+ uintptr_t idm_io_control_direct,
+ uintptr_t idm_reset_control,
+ uintptr_t base,
+ uintptr_t dme_base);
+
+void fsx_meminit(const char *name,
+ uintptr_t idm_io_control_direct,
+ uintptr_t idm_io_status);
+
+void fs4_disable_clocks(bool disable_sram,
+ bool disable_crypto,
+ bool disable_raid);
+
+#endif /* FSX_H */
diff --git a/plat/brcm/board/stingray/include/ihost_pm.h b/plat/brcm/board/stingray/include/ihost_pm.h
new file mode 100644
index 000000000..83493ab18
--- /dev/null
+++ b/plat/brcm/board/stingray/include/ihost_pm.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IHOST_PM
+#define IHOST_PM
+
+#include <stdint.h>
+
+#define CLUSTER_POWER_ON 0x1
+#define CLUSTER_POWER_OFF 0x0
+
+void ihost_power_on_cluster(u_register_t mpidr);
+void ihost_power_on_secondary_core(u_register_t mpidr, uint64_t rvbar);
+void ihost_enable_satellite_timer(unsigned int cluster_id);
+
+#endif
diff --git a/plat/brcm/board/stingray/include/iommu.h b/plat/brcm/board/stingray/include/iommu.h
new file mode 100644
index 000000000..e7b29854e
--- /dev/null
+++ b/plat/brcm/board/stingray/include/iommu.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IOMMU_H
+#define IOMMU_H
+
+enum iommu_domain {
+ PCIE_PAXC,
+ DOMAIN_CRMU,
+};
+
+void arm_smmu_create_identity_map(enum iommu_domain dom);
+void arm_smmu_reserve_secure_cntxt(void);
+void arm_smmu_enable_secure_client_port(void);
+
+#endif /* IOMMU_H */
diff --git a/plat/brcm/board/stingray/include/ncsi.h b/plat/brcm/board/stingray/include/ncsi.h
new file mode 100644
index 000000000..04dd64001
--- /dev/null
+++ b/plat/brcm/board/stingray/include/ncsi.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NCSI_H
+#define NCSI_H
+
+/*
+ * There are 10 registers for NCSI IO drivers.
+ */
+#define NITRO_NCSI_IOPAD_CONTROL_NUM 10
+#define NITRO_NCSI_IOPAD_CONTROL_BASE 0x60e05080
+
+/*
+ * NCSI IO Drive strength
+ * 000 - Drives 2mA
+ * 001 - Drives 4mA
+ * 010 - Drives 6mA
+ * 011 - Drives 8mA
+ * 100 - Drives 10mA
+ * 101 - Drives 12mA
+ * 110 - Drives 14mA
+ * 111 - Drives 16mA
+ */
+#define PAD_SELX_VALUE(selx) ((selx) << 1)
+#define PAD_SELX_MASK (0x7 << 1)
+
+void brcm_stingray_ncsi_init(void);
+
+#endif
diff --git a/plat/brcm/board/stingray/include/paxb.h b/plat/brcm/board/stingray/include/paxb.h
new file mode 100644
index 000000000..c64c8a6c6
--- /dev/null
+++ b/plat/brcm/board/stingray/include/paxb.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PAXB_H
+#define PAXB_H
+
+/* total number of PCIe cores */
+#define NUM_OF_SR_PCIE_CORES 8
+#define NUM_OF_NS3Z_PCIE_CORES 1
+
+/*
+ * List of PCIe core and PAXB wrapper memory power registers
+ */
+#define PCIE_CORE_BASE 0x40000800
+#define PCIE_CORE_SOFT_RST_CFG_BASE (PCIE_CORE_BASE + 0x40)
+#define PCIE_CORE_SOFT_RST 0x1
+#define PCIE_CORE_ISO_CFG_BASE (PCIE_CORE_BASE + 0x54)
+#define PCIE_CORE_MEM_ISO 0x2
+#define PCIE_CORE_ISO 0x1
+
+#define PCIE_CORE_MEM_PWR_BASE (PCIE_CORE_BASE + 0x58)
+#define PCIE_PAXB_MEM_PWR_BASE (PCIE_CORE_BASE + 0x5c)
+#define PCIE_CORE_PMI_CFG_BASE (PCIE_CORE_BASE + 0x64)
+#define PCIE_CORE_RESERVED_CFG (PCIE_CORE_BASE + 0x6c)
+#define PCIE_CORE_MEM_PWR_STATUS_BASE (PCIE_CORE_BASE + 0x74)
+#define PCIE_PAXB_MEM_PWR_STATUS_BASE (PCIE_CORE_BASE + 0x78)
+#define PCIE_CORE_PWR_OFFSET 0x100
+
+#define SR_A0_DEVICE_ID 0xd713
+#define SR_B0_DEVICE_ID 0xd714
+/* TODO: Modify device ID once available */
+#define NS3Z_DEVICE_ID 0xd715
+
+/* FIXME: change link speed to GEN3 when it's ready */
+#define GEN1_LINK_SPEED 1
+#define GEN2_LINK_SPEED 2
+#define GEN3_LINK_SPEED 3
+
+typedef struct {
+ uint32_t type;
+ uint32_t device_id;
+ uint32_t pipemux_idx;
+ uint32_t num_cores;
+ int (*pipemux_init)(void);
+ int (*phy_init)(void);
+ int (*core_needs_enable)(unsigned int core_idx);
+ unsigned int (*get_link_width)(unsigned int core_idx);
+ unsigned int (*get_link_speed)(void);
+} paxb_cfg;
+
+enum paxb_type {
+ PAXB_SR,
+ PAXB_NS3Z,
+};
+
+extern const paxb_cfg *paxb;
+
+#ifdef USE_PAXB
+void paxb_init(void);
+void paxb_rc_cfg_write(unsigned int core_idx, unsigned int where,
+ uint32_t val);
+unsigned int paxb_rc_cfg_read(unsigned int core_idx, unsigned int where);
+int pcie_core_needs_enable(unsigned int core_idx);
+const paxb_cfg *paxb_get_sr_config(void);
+#else
+static inline void paxb_init(void)
+{
+}
+#endif
+
+#endif /* PAXB_H */
diff --git a/plat/brcm/board/stingray/include/paxc.h b/plat/brcm/board/stingray/include/paxc.h
new file mode 100644
index 000000000..ae1af2ed3
--- /dev/null
+++ b/plat/brcm/board/stingray/include/paxc.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2017 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PAXC_H
+#define PAXC_H
+
+#ifdef USE_PAXC
+void paxc_init(void);
+void paxc_mhb_ns_init(void);
+#else
+static inline void paxc_init(void)
+{
+}
+
+static inline void paxc_mhb_ns_init(void)
+{
+}
+#endif
+
+#endif /* PAXC_H */
diff --git a/plat/brcm/board/stingray/include/plat_macros.S b/plat/brcm/board/stingray/include/plat_macros.S
new file mode 100644
index 000000000..dccd54a32
--- /dev/null
+++ b/plat/brcm/board/stingray/include/plat_macros.S
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+.section .rodata.gic_reg_name, "aS"
+gicc_regs:
+ .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+gicd_pend_reg:
+ .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
+newline:
+ .asciz "\n"
+spacer:
+ .asciz ":\t\t0x"
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant registers whenever an
+ * unhandled exception is taken in BL31.
+ * ---------------------------------------------
+ */
+.macro plat_crash_print_regs
+ nop
+.endm
+
+/* ---------------------------------------------
+ * The below macro prints out relevant GIC
+ * registers whenever an unhandled exception is
+ * taken in BL31.
+ * ---------------------------------------------
+ */
+.macro plat_print_gic_regs
+ nop
+ /*TBD-STINGRAY*/
+.endm
+
+/* ------------------------------------------------
+ * The below required platform porting macro prints
+ * out relevant interconnect registers whenever an
+ * unhandled exception is taken in BL3-1.
+ * ------------------------------------------------
+ */
+.macro plat_print_interconnect_regs
+ nop
+ /*TBD-STINGRAY*/
+.endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/brcm/board/stingray/include/platform_def.h b/plat/brcm/board/stingray/include/platform_def.h
new file mode 100644
index 000000000..474212429
--- /dev/null
+++ b/plat/brcm/board/stingray/include/platform_def.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2015-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <plat/common/common_def.h>
+
+#include <brcm_def.h>
+#include "sr_def.h"
+#include <cmn_plat_def.h>
+
+/*
+ * Most platform porting definitions provided by included headers
+ */
+#define PLAT_BRCM_SCP_TZC_DRAM1_SIZE ULL(0x0)
+
+/*
+ * Required by standard platform porting definitions
+ */
+#define PLATFORM_CLUSTER0_CORE_COUNT 2
+#define PLATFORM_CLUSTER1_CORE_COUNT 2
+#define PLATFORM_CLUSTER2_CORE_COUNT 2
+#define PLATFORM_CLUSTER3_CORE_COUNT 2
+
+#define BRCM_SYSTEM_COUNT 1
+#define BRCM_CLUSTER_COUNT 4
+
+#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \
+ PLATFORM_CLUSTER1_CORE_COUNT+ \
+ PLATFORM_CLUSTER2_CORE_COUNT+ \
+ PLATFORM_CLUSTER3_CORE_COUNT)
+
+#define PLAT_NUM_PWR_DOMAINS (BRCM_SYSTEM_COUNT + \
+ BRCM_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
+
+/* TBD-STINGRAY */
+#define CACHE_WRITEBACK_SHIFT 6
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+/* TBD-STINGRAY */
+#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL1
+
+#define BL1_PLATFORM_STACK_SIZE 0x3300
+#define BL2_PLATFORM_STACK_SIZE 0xc000
+#define BL11_PLATFORM_STACK_SIZE 0x2b00
+#define DEFAULT_PLATFORM_STACK_SIZE 0x400
+#if IMAGE_BL1
+# define PLATFORM_STACK_SIZE BL1_PLATFORM_STACK_SIZE
+#else
+#if IMAGE_BL2
+#ifdef USE_BL1_RW
+# define PLATFORM_STACK_SIZE BL2_PLATFORM_STACK_SIZE
+#else
+# define PLATFORM_STACK_SIZE BL1_PLATFORM_STACK_SIZE
+#endif
+#else
+#if IMAGE_BL11
+# define PLATFORM_STACK_SIZE BL11_PLATFORM_STACK_SIZE
+#else
+# define PLATFORM_STACK_SIZE DEFAULT_PLATFORM_STACK_SIZE
+#endif
+#endif
+#endif
+
+#define PLAT_BRCM_TRUSTED_SRAM_BASE 0x66D00000
+#define PLAT_BRCM_TRUSTED_SRAM_SIZE 0x00040000
+
+#ifdef RUN_BL1_FROM_QSPI /* BL1 XIP from QSPI */
+# define PLAT_BRCM_TRUSTED_ROM_BASE QSPI_BASE_ADDR
+#elif RUN_BL1_FROM_NAND /* BL1 XIP from NAND */
+# define PLAT_BRCM_TRUSTED_ROM_BASE NAND_BASE_ADDR
+#else /* BL1 executed in ROM */
+# define PLAT_BRCM_TRUSTED_ROM_BASE ROM_BASE_ADDR
+#endif
+#define PLAT_BRCM_TRUSTED_ROM_SIZE 0x00040000
+
+/*******************************************************************************
+ * BL1 specific defines.
+ ******************************************************************************/
+#define BL1_RO_BASE PLAT_BRCM_TRUSTED_ROM_BASE
+#define BL1_RO_LIMIT (PLAT_BRCM_TRUSTED_ROM_BASE \
+ + PLAT_BRCM_TRUSTED_ROM_SIZE)
+
+/*
+ * Put BL1 RW at the beginning of the Trusted SRAM.
+ */
+#define BL1_RW_BASE (BRCM_BL_RAM_BASE)
+#define BL1_RW_LIMIT (BL1_RW_BASE + 0x12000)
+
+#define BL11_RW_BASE BL1_RW_LIMIT
+#define BL11_RW_LIMIT (PLAT_BRCM_TRUSTED_SRAM_BASE + \
+ PLAT_BRCM_TRUSTED_SRAM_SIZE)
+
+/*******************************************************************************
+ * BL2 specific defines.
+ ******************************************************************************/
+#if RUN_BL2_FROM_QSPI /* BL2 XIP from QSPI */
+#define BL2_BASE QSPI_BASE_ADDR
+#define BL2_LIMIT (BL2_BASE + 0x40000)
+#define BL2_RW_BASE BL1_RW_LIMIT
+#define BL2_RW_LIMIT (PLAT_BRCM_TRUSTED_SRAM_BASE + \
+ PLAT_BRCM_TRUSTED_SRAM_SIZE)
+#elif RUN_BL2_FROM_NAND /* BL2 XIP from NAND */
+#define BL2_BASE NAND_BASE_ADDR
+#define BL2_LIMIT (BL2_BASE + 0x40000)
+#define BL2_RW_BASE BL1_RW_LIMIT
+#define BL2_RW_LIMIT (PLAT_BRCM_TRUSTED_SRAM_BASE + \
+ PLAT_BRCM_TRUSTED_SRAM_SIZE)
+#else
+#define BL2_BASE (BL1_RW_LIMIT + PAGE_SIZE)
+#define BL2_LIMIT (BRCM_BL_RAM_BASE + BRCM_BL_RAM_SIZE)
+#endif
+
+/*
+ * BL1 persistent area in internal SRAM
+ * This area will increase as more features gets into BL1
+ */
+#define BL1_PERSISTENT_DATA_SIZE 0x2000
+
+/* To reduce BL2 runtime footprint, we can re-use some BL1_RW area */
+#define BL1_RW_RECLAIM_BASE (PLAT_BRCM_TRUSTED_SRAM_BASE + \
+ BL1_PERSISTENT_DATA_SIZE)
+
+/*******************************************************************************
+ * BL3-1 specific defines.
+ ******************************************************************************/
+/* Max Size of BL31 (in DRAM) */
+#define PLAT_BRCM_MAX_BL31_SIZE 0x30000
+
+#ifdef USE_DDR
+#define BL31_BASE BRCM_AP_TZC_DRAM1_BASE
+
+#define BL31_LIMIT (BRCM_AP_TZC_DRAM1_BASE + \
+ PLAT_BRCM_MAX_BL31_SIZE)
+#else
+/* Put BL3-1 at the end of external on-board SRAM connected as NOR flash */
+#define BL31_BASE (NOR_BASE_ADDR + NOR_SIZE - \
+ PLAT_BRCM_MAX_BL31_SIZE)
+
+#define BL31_LIMIT (NOR_BASE_ADDR + NOR_SIZE)
+#endif
+
+#define SECURE_DDR_END_ADDRESS BL31_LIMIT
+
+#ifdef NEED_SCP_BL2
+#define SCP_BL2_BASE BL31_BASE
+#define PLAT_MAX_SCP_BL2_SIZE 0x9000
+#define PLAT_SCP_COM_SHARED_MEM_BASE (CRMU_SHARED_SRAM_BASE)
+/* dummy defined */
+#define PLAT_BRCM_MHU_BASE 0x0
+#endif
+
+#define SECONDARY_CPU_SPIN_BASE_ADDR BRCM_SHARED_RAM_BASE
+
+/* Generic system timer counter frequency */
+#ifndef SYSCNT_FREQ
+#define SYSCNT_FREQ (125 * 1000 * 1000)
+#endif
+
+/*
+ * Enable the BL32 definitions, only when optee os is selected as secure
+ * payload (BL32).
+ */
+#ifdef SPD_opteed
+/*
+ * Reserved Memory Map : SHMEM & TZDRAM.
+ *
+ * +--------+----------+ 0x8D000000
+ * | SHMEM (NS) | 16MB
+ * +-------------------+ 0x8E000000
+ * | | TEE_RAM(S)| 4MB
+ * + TZDRAM +----------+ 0x8E400000
+ * | | TA_RAM(S) | 12MB
+ * +-------------------+ 0x8F000000
+ * | BL31 Binary (S) | 192KB
+ * +-------------------+ 0x8F030000
+ */
+
+#define BL32_VA_SIZE (4 * 1024 * 1024)
+#define BL32_BASE (0x8E000000)
+#define BL32_LIMIT (BL32_BASE + BL32_VA_SIZE)
+#define TSP_SEC_MEM_BASE BL32_BASE
+#define TSP_SEC_MEM_SIZE BL32_VA_SIZE
+#endif
+
+#ifdef SPD_opteed
+ #define SECURE_DDR_BASE_ADDRESS BL32_BASE
+#else
+ #define SECURE_DDR_BASE_ADDRESS BL31_BASE
+#endif
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+
+#define MAX_XLAT_TABLES 7
+
+#define PLAT_BRCM_MMAP_ENTRIES 10
+
+#define MAX_MMAP_REGIONS (PLAT_BRCM_MMAP_ENTRIES + \
+ BRCM_BL_REGIONS)
+
+#ifdef USE_DDR
+#ifdef BL33_OVERRIDE_LOAD_ADDR
+#define PLAT_BRCM_NS_IMAGE_OFFSET BL33_OVERRIDE_LOAD_ADDR
+#else
+/*
+ * BL3-3 image starting offset.
+ * Putting start of DRAM as of now.
+ */
+#define PLAT_BRCM_NS_IMAGE_OFFSET 0x80000000
+#endif /* BL33_OVERRIDE_LOAD_ADDR */
+#else
+/*
+ * BL3-3 image starting offset.
+ * Putting start of external on-board SRAM as of now.
+ */
+#define PLAT_BRCM_NS_IMAGE_OFFSET NOR_BASE_ADDR
+#endif /* USE_DDR */
+/******************************************************************************
+ * Required platform porting definitions common to all BRCM platforms
+ *****************************************************************************/
+
+#define MAX_IO_DEVICES 5
+#define MAX_IO_HANDLES 6
+
+#define PRIMARY_CPU 0
+
+/* GIC Parameter */
+#define PLAT_BRCM_GICD_BASE GIC500_BASE
+#define PLAT_BRCM_GICR_BASE (GIC500_BASE + 0x200000)
+
+/* Define secure interrupt as per Group here */
+#define PLAT_BRCM_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BRCM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(BRCM_IRQ_SEC_SPI_0, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE)
+
+#define PLAT_BRCM_G0_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BRCM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, (grp), \
+ GIC_INTR_CFG_EDGE), \
+
+/*
+ *CCN 502 related constants.
+ */
+#define PLAT_BRCM_CLUSTER_COUNT 4 /* Number of RN-F Masters */
+#define PLAT_BRCM_CLUSTER_TO_CCN_ID_MAP CLUSTER0_NODE_ID, CLUSTER1_NODE_ID, CLUSTER2_NODE_ID, CLUSTER3_NODE_ID
+#define CCN_SIZE 0x1000000
+#define CLUSTER0_NODE_ID 1
+#define CLUSTER1_NODE_ID 7
+#define CLUSTER2_NODE_ID 9
+#define CLUSTER3_NODE_ID 15
+
+#endif
diff --git a/plat/brcm/board/stingray/include/platform_sotp.h b/plat/brcm/board/stingray/include/platform_sotp.h
new file mode 100644
index 000000000..0389f3871
--- /dev/null
+++ b/plat/brcm/board/stingray/include/platform_sotp.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_SOTP_H
+#define PLATFORM_SOTP_H
+
+#define SOTP_DEVICE_SECURE_CFG0_ROW 17
+#define SOTP_DEVICE_SECURE_CFG1_ROW 18
+#define SOTP_DEVICE_SECURE_CFG2_ROW 19
+#define SOTP_DEVICE_SECURE_CFG3_ROW 20
+#define SOTP_BRCM_SOFTWARE_CFG0_ROW 21
+#define SOTP_BRCM_SOFTWARE_CFG1_ROW 22
+#define SOTP_BRCM_SOFTWARE_CFG2_ROW 23
+#define SOTP_BRCM_SOFTWARE_CFG3_ROW 24
+#define SOTP_CUSTOMER_ID_CFG0_ROW 25
+#define SOTP_CUSTOMER_ID_CFG1_ROW 26
+#define SOTP_CUSTOMER_ID_CFG2_ROW 27
+#define SOTP_CUSTOMER_ID_CFG3_ROW 28
+#define SOTP_CUSTOMER_DEV_CFG0_ROW 29
+#define SOTP_CUSTOMER_DEV_CFG1_ROW 30
+#define SOTP_CUSTOMER_DEV_CFG2_ROW 31
+#define SOTP_CUSTOMER_DEV_CFG3_ROW 32
+#define SOTP_DAUTH_ROW 33
+#define SOTP_K_HMAC_ROW 45
+#define SOTP_K_AES_ROW 57
+#define SOTP_NVCOUNTER_ROW 69
+
+#define SOTP_BRCM_CFG_ECC_ERROR_MASK 0x100000
+#define SOTP_DAUTH_ECC_ERROR_MASK 0x800000
+#define SOTP_K_HMAC_ECC_ERROR_MASK 0x1000000
+#define SOTP_K_AES_ECC_ERROR_MASK 0x2000000
+
+#endif
diff --git a/plat/brcm/board/stingray/include/scp_cmd.h b/plat/brcm/board/stingray/include/scp_cmd.h
new file mode 100644
index 000000000..806ef56a5
--- /dev/null
+++ b/plat/brcm/board/stingray/include/scp_cmd.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SCP_CMD_H
+#define SCP_SMD_H
+
+#include <stdint.h>
+
+typedef struct {
+ int cmd;
+ int completed;
+ int ret;
+} crmu_response_t;
+
+
+#define SCP_CMD_MASK 0xffff
+#define SCP_CMD_DEFAULT_TIMEOUT_US 1000
+#define SCP_CMD_SCP_BOOT_TIMEOUT_US 5000
+
+int scp_send_cmd(uint32_t cmd, uint32_t param, uint32_t timeout);
+
+#endif
diff --git a/plat/brcm/board/stingray/include/scp_utils.h b/plat/brcm/board/stingray/include/scp_utils.h
new file mode 100644
index 000000000..c39b18cb2
--- /dev/null
+++ b/plat/brcm/board/stingray/include/scp_utils.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SCP_UTILS_H
+#define SCP_UTILS_H
+
+#include <common/bl_common.h>
+#include <lib/mmio.h>
+
+#include <m0_cfg.h>
+
+int plat_bcm_bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info);
+
+bool is_crmu_alive(void);
+bool bcm_scp_issue_sys_reset(void);
+
+#define SCP_READ_CFG(cfg) mmio_read_32(CRMU_CFG_BASE + \
+ offsetof(M0CFG, cfg))
+#define SCP_WRITE_CFG(cfg, value) mmio_write_32(CRMU_CFG_BASE + \
+ offsetof(M0CFG, cfg), value)
+
+#define SCP_READ_CFG16(cfg) mmio_read_16(CRMU_CFG_BASE + \
+ offsetof(M0CFG, cfg))
+#define SCP_WRITE_CFG16(cfg, value) mmio_write_16(CRMU_CFG_BASE + \
+ offsetof(M0CFG, cfg), value)
+
+#define SCP_READ_CFG8(cfg) mmio_read_8(CRMU_CFG_BASE + \
+ offsetof(M0CFG, cfg))
+#define SCP_WRITE_CFG8(cfg, value) mmio_write_8(CRMU_CFG_BASE + \
+ offsetof(M0CFG, cfg), value)
+#endif
diff --git a/plat/brcm/board/stingray/include/sdio.h b/plat/brcm/board/stingray/include/sdio.h
new file mode 100644
index 000000000..e08904eaa
--- /dev/null
+++ b/plat/brcm/board/stingray/include/sdio.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2019-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SDIO_H
+#define SDIO_H
+
+#include <stdbool.h>
+
+#define SR_IPROC_SDIO0_CFG_BASE 0x689006e4
+#define SR_IPROC_SDIO0_SID_BASE 0x68900b00
+#define SR_IPROC_SDIO0_PAD_BASE 0x68a4017c
+#define SR_IPROC_SDIO0_IOCTRL_BASE 0x68e02408
+
+#define SR_IPROC_SDIO1_CFG_BASE 0x68900734
+#define SR_IPROC_SDIO1_SID_BASE 0x68900b08
+#define SR_IPROC_SDIO1_PAD_BASE 0x68a401b4
+#define SR_IPROC_SDIO1_IOCTRL_BASE 0x68e03408
+
+#define NS3Z_IPROC_SDIO0_CFG_BASE 0x68a20540
+#define NS3Z_IPROC_SDIO0_SID_BASE 0x68900b00
+#define NS3Z_IPROC_SDIO0_TP_OUT_SEL 0x68a20308
+#define NS3Z_IPROC_SDIO0_PAD_BASE 0x68a20500
+#define NS3Z_IPROC_SDIO0_IOCTRL_BASE 0x68e02408
+
+#define PHY_BYPASS BIT(14)
+#define LEGACY_EN BIT(31)
+#define PHY_DISABLE (LEGACY_EN | PHY_BYPASS)
+
+#define NS3Z_IPROC_SDIO1_CFG_BASE 0x68a30540
+#define NS3Z_IPROC_SDIO1_SID_BASE 0x68900b08
+#define NS3Z_IPROC_SDIO1_PAD_BASE 0x68a30500
+#define NS3Z_IPROC_SDIO1_IOCTRL_BASE 0x68e03408
+
+#define ICFG_SDIO_CAP0 0x10
+#define ICFG_SDIO_CAP1 0x14
+#define ICFG_SDIO_STRAPSTATUS_0 0x0
+#define ICFG_SDIO_STRAPSTATUS_1 0x4
+#define ICFG_SDIO_STRAPSTATUS_2 0x8
+#define ICFG_SDIO_STRAPSTATUS_3 0xc
+#define ICFG_SDIO_STRAPSTATUS_4 0x18
+
+#define ICFG_SDIO_SID_ARADDR 0x0
+#define ICFG_SDIO_SID_AWADDR 0x4
+
+#define ICFG_SDIOx_CAP0__SLOT_TYPE_MASK 0x3
+#define ICFG_SDIOx_CAP0__SLOT_TYPE_SHIFT 27
+#define ICFG_SDIOx_CAP0__INT_MODE_SHIFT 26
+#define ICFG_SDIOx_CAP0__SYS_BUS_64BIT_SHIFT 25
+#define ICFG_SDIOx_CAP0__VOLTAGE_1P8V_SHIFT 24
+#define ICFG_SDIOx_CAP0__VOLTAGE_3P0V_SHIFT 23
+#define ICFG_SDIOx_CAP0__VOLTAGE_3P3V_SHIFT 22
+#define ICFG_SDIOx_CAP0__SUSPEND_RESUME_SHIFT 21
+#define ICFG_SDIOx_CAP0__SDMA_SHIFT 20
+#define ICFG_SDIOx_CAP0__HIGH_SPEED_SHIFT 19
+#define ICFG_SDIOx_CAP0__ADMA2_SHIFT 18
+#define ICFG_SDIOx_CAP0__EXTENDED_MEDIA_SHIFT 17
+#define ICFG_SDIOx_CAP0__MAX_BLOCK_LEN_MASK 0x3
+#define ICFG_SDIOx_CAP0__MAX_BLOCK_LEN_SHIFT 15
+#define ICFG_SDIOx_CAP0__BASE_CLK_FREQ_MASK 0xff
+#define ICFG_SDIOx_CAP0__BASE_CLK_FREQ_SHIFT 7
+#define ICFG_SDIOx_CAP0__TIMEOUT_UNIT_SHIFT 6
+#define ICFG_SDIOx_CAP0__TIMEOUT_CLK_FREQ_MASK 0x3f
+#define ICFG_SDIOx_CAP0__TIMEOUT_CLK_FREQ_SHIFT 0
+
+#define ICFG_SDIOx_CAP1__SPI_BLOCK_MODE_SHIFT 22
+#define ICFG_SDIOx_CAP1__SPI_MODE_SHIFT 21
+#define ICFG_SDIOx_CAP1__CLK_MULT_MASK 0xff
+#define ICFG_SDIOx_CAP1__CLK_MULT_SHIFT 13
+#define ICFG_SDIOx_CAP1__RETUNING_MODE_MASK 0x3
+#define ICFG_SDIOx_CAP1__RETUNING_MODE_SHIFT 11
+#define ICFG_SDIOx_CAP1__TUNE_SDR50_SHIFT 10
+#define ICFG_SDIOx_CAP1__TIME_RETUNE_MASK 0xf
+#define ICFG_SDIOx_CAP1__TIME_RETUNE_SHIFT 6
+#define ICFG_SDIOx_CAP1__DRIVER_D_SHIFT 5
+#define ICFG_SDIOx_CAP1__DRIVER_C_SHIFT 4
+#define ICFG_SDIOx_CAP1__DRIVER_A_SHIFT 3
+#define ICFG_SDIOx_CAP1__DDR50_SHIFT 2
+#define ICFG_SDIOx_CAP1__SDR104_SHIFT 1
+#define ICFG_SDIOx_CAP1__SDR50_SHIFT 0
+
+#ifdef USE_DDR
+#define SDIO_DMA 1
+#else
+#define SDIO_DMA 0
+#endif
+
+#define SDIO0_CAP0_CFG \
+ (0x1 << ICFG_SDIOx_CAP0__SLOT_TYPE_SHIFT) \
+ | (0x0 << ICFG_SDIOx_CAP0__INT_MODE_SHIFT) \
+ | (0x0 << ICFG_SDIOx_CAP0__SYS_BUS_64BIT_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_1P8V_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_3P0V_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_3P3V_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__SUSPEND_RESUME_SHIFT) \
+ | (SDIO_DMA << ICFG_SDIOx_CAP0__SDMA_SHIFT) \
+ | (SDIO_DMA << ICFG_SDIOx_CAP0__ADMA2_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__HIGH_SPEED_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__EXTENDED_MEDIA_SHIFT) \
+ | (0x2 << ICFG_SDIOx_CAP0__MAX_BLOCK_LEN_SHIFT) \
+ | (0xc8 << ICFG_SDIOx_CAP0__BASE_CLK_FREQ_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__TIMEOUT_UNIT_SHIFT) \
+ | (0x30 << ICFG_SDIOx_CAP0__TIMEOUT_CLK_FREQ_SHIFT)
+
+#define SDIO0_CAP1_CFG \
+ (0x1 << ICFG_SDIOx_CAP1__SPI_BLOCK_MODE_SHIFT)\
+ | (0x1 << ICFG_SDIOx_CAP1__SPI_MODE_SHIFT)\
+ | (0x0 << ICFG_SDIOx_CAP1__CLK_MULT_SHIFT)\
+ | (0x2 << ICFG_SDIOx_CAP1__RETUNING_MODE_SHIFT)\
+ | (0x1 << ICFG_SDIOx_CAP1__TUNE_SDR50_SHIFT)\
+ | (0x0 << ICFG_SDIOx_CAP1__DRIVER_D_SHIFT)\
+ | (0x0 << ICFG_SDIOx_CAP1__DRIVER_C_SHIFT)\
+ | (0x1 << ICFG_SDIOx_CAP1__DRIVER_A_SHIFT)\
+ | (0x1 << ICFG_SDIOx_CAP1__DDR50_SHIFT)\
+ | (0x1 << ICFG_SDIOx_CAP1__SDR104_SHIFT)\
+ | (0x1 << ICFG_SDIOx_CAP1__SDR50_SHIFT)
+
+#define SDIO1_CAP0_CFG \
+ (0x0 << ICFG_SDIOx_CAP0__SLOT_TYPE_SHIFT) \
+ | (0x0 << ICFG_SDIOx_CAP0__INT_MODE_SHIFT) \
+ | (0x0 << ICFG_SDIOx_CAP0__SYS_BUS_64BIT_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_1P8V_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_3P0V_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__VOLTAGE_3P3V_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__SUSPEND_RESUME_SHIFT) \
+ | (SDIO_DMA << ICFG_SDIOx_CAP0__SDMA_SHIFT) \
+ | (SDIO_DMA << ICFG_SDIOx_CAP0__ADMA2_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__HIGH_SPEED_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__EXTENDED_MEDIA_SHIFT) \
+ | (0x2 << ICFG_SDIOx_CAP0__MAX_BLOCK_LEN_SHIFT) \
+ | (0xc8 << ICFG_SDIOx_CAP0__BASE_CLK_FREQ_SHIFT) \
+ | (0x1 << ICFG_SDIOx_CAP0__TIMEOUT_UNIT_SHIFT) \
+ | (0x30 << ICFG_SDIOx_CAP0__TIMEOUT_CLK_FREQ_SHIFT)
+
+#define SDIO1_CAP1_CFG \
+ (0x1 << ICFG_SDIOx_CAP1__SPI_BLOCK_MODE_SHIFT)\
+ | (0x1 << ICFG_SDIOx_CAP1__SPI_MODE_SHIFT)\
+ | (0x0 << ICFG_SDIOx_CAP1__CLK_MULT_SHIFT)\
+ | (0x2 << ICFG_SDIOx_CAP1__RETUNING_MODE_SHIFT)\
+ | (0x1 << ICFG_SDIOx_CAP1__TUNE_SDR50_SHIFT)\
+ | (0x0 << ICFG_SDIOx_CAP1__DRIVER_D_SHIFT)\
+ | (0x0 << ICFG_SDIOx_CAP1__DRIVER_C_SHIFT)\
+ | (0x1 << ICFG_SDIOx_CAP1__DRIVER_A_SHIFT)\
+ | (0x1 << ICFG_SDIOx_CAP1__DDR50_SHIFT)\
+ | (0x1 << ICFG_SDIOx_CAP1__SDR104_SHIFT)\
+ | (0x1 << ICFG_SDIOx_CAP1__SDR50_SHIFT)
+
+#define PAD_SDIO_CLK 0x4
+#define PAD_SDIO_DATA0 0x8
+#define PAD_SDIO_DATA1 0xc
+#define PAD_SDIO_DATA2 0x10
+#define PAD_SDIO_DATA3 0x14
+#define PAD_SDIO_DATA4 0x18
+#define PAD_SDIO_DATA5 0x1c
+#define PAD_SDIO_DATA6 0x20
+#define PAD_SDIO_DATA7 0x24
+#define PAD_SDIO_CMD 0x28
+
+/* 12mA Drive strength*/
+#define PAD_SDIO_SELX (0x5 << 1)
+#define PAD_SDIO_SRC (1 << 0)
+#define PAD_SDIO_MASK (0xF << 0)
+#define PAD_SDIO_VALUE (PAD_SDIO_SELX | PAD_SDIO_SRC)
+
+/*
+ * SDIO_PRESETVAL0
+ *
+ * Each 13 Bit filed consists:
+ * drivestrength - 12:11
+ * clkgensel - b10
+ * sdkclkfreqsel - 9:0
+ * Field Bit(s) Description
+ * ============================================================
+ * SDR25_PRESET 25:13 Preset Value for SDR25
+ * SDR50_PRESET 12:0 Preset Value for SDR50
+ */
+#define SDIO_PRESETVAL0 0x01005001
+
+/*
+ * SDIO_PRESETVAL1
+ *
+ * Each 13 Bit filed consists:
+ * drivestrength - 12:11
+ * clkgensel - b10
+ * sdkclkfreqsel - 9:0
+ * Field Bit(s) Description
+ * ============================================================
+ * SDR104_PRESET 25:13 Preset Value for SDR104
+ * SDR12_PRESET 12:0 Preset Value for SDR12
+ */
+#define SDIO_PRESETVAL1 0x03000004
+
+/*
+ * SDIO_PRESETVAL2
+ *
+ * Each 13 Bit filed consists:
+ * drivestrength - 12:11
+ * clkgensel - b10
+ * sdkclkfreqsel - 9:0
+ * Field Bit(s) Description
+ * ============================================================
+ * HIGH_SPEED_PRESET 25:13 Preset Value for High Speed
+ * INIT_PRESET 12:0 Preset Value for Initialization
+ */
+#define SDIO_PRESETVAL2 0x010040FA
+
+/*
+ * SDIO_PRESETVAL3
+ *
+ * Each 13 Bit filed consists:
+ * drivestrength - 12:11
+ * clkgensel - b10
+ * sdkclkfreqsel - 9:0
+ * Field Bit(s) Description
+ * ============================================================
+ * DDR50_PRESET 25:13 Preset Value for DDR50
+ * DEFAULT_PRESET 12:0 Preset Value for Default Speed
+ */
+#define SDIO_PRESETVAL3 0x01004004
+
+/*
+ * SDIO_PRESETVAL4
+ *
+ * Field Bit(s) Description
+ * ============================================================
+ * FORCE_USE_IP_TUNE_CLK 30 Force use IP clock
+ * TUNING_COUNT 29:24 Tuning count
+ * OVERRIDE_1P8V 23:16
+ * OVERRIDE_3P3V 15:8
+ * OVERRIDE_3P0V 7:0
+ */
+#define SDIO_PRESETVAL4 0x20010101
+
+#define SDIO_SID_SHIFT 5
+
+typedef struct {
+ uintptr_t cfg_base;
+ uintptr_t sid_base;
+ uintptr_t io_ctrl_base;
+ uintptr_t pad_base;
+} SDIO_CFG;
+
+void brcm_stingray_sdio_init(void);
+
+#endif /* SDIO_H */
diff --git a/plat/brcm/board/stingray/include/sr_def.h b/plat/brcm/board/stingray/include/sr_def.h
new file mode 100644
index 000000000..be0dee127
--- /dev/null
+++ b/plat/brcm/board/stingray/include/sr_def.h
@@ -0,0 +1,619 @@
+/*
+ * Copyright (c) 2016-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SR_DEF_H
+#define SR_DEF_H
+
+#ifndef __ASSEMBLER__
+#include <lib/mmio.h>
+#endif
+
+#include <common/interrupt_props.h>
+#include <drivers/arm/gic_common.h>
+
+#include <crmu_def.h>
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define BRCM_BL31_PLAT_PARAM_VAL ULL(0x0f1e2d3c4b5a6978)
+
+#define MHB_BASE_ADDR 0x60000000
+#define PLAT_BRCM_CCN_BASE 0x61000000
+#define CORESIGHT_BASE_ADDR 0x62000000
+#define SMMU_BASE 0x64000000
+
+/* memory map entries*/
+/* Grouping block device for bigger MMU region */
+/* covers MHB, CNN, coresight, GIC, MMU, APB, CRMU */
+#define PERIPH0_BASE MHB_BASE_ADDR
+#define PERIPH0_SIZE 0x06d00000
+
+#define PERIPH1_BASE 0x66d80000
+#define PERIPH1_SIZE 0x00f80000
+
+#define HSLS_BASE_ADDR 0x68900000
+#define HSLS_SIZE 0x04500000
+
+#define GIC500_BASE 0x63c00000
+#define GIC500_SIZE 0x400000
+
+/*******************************************************************************
+ * CCN related constants
+ ******************************************************************************/
+#define OLY_MN_REGISTERS_NODE0_SECURE_ACCESS (PLAT_BRCM_CCN_BASE + 0x0)
+
+#define OLY_RNI3PDVM_REGISTERS_NODE8_AUX_CTL (PLAT_BRCM_CCN_BASE + 0x880500)
+
+/* Used for acceleration of coherent ordered writes */
+#define OLY_RNI3PDVM_REGISTERS_NODE8_AUX_CTL_WUO BIT(4)
+/* Wait for completion of requests at RN-I */
+#define OLY_RNI3PDVM_REGISTERS_NODE8_AUX_CTL_WFC BIT(3)
+
+/*
+ * Forces all reads from the RN-I to be sent with the request order bit set
+ * and this ensures ordered allocation of read data buffers in the RN-I
+ */
+#define OLY_RNI3PDVM_REGISTERS_NODE8_AUX_CTL_RQO BIT(5)
+
+#define OLY_RNI3PDVM_REGISTERS_NODE14_AUX_CTL (PLAT_BRCM_CCN_BASE + 0x8e0500)
+
+/* Wait for completion of requests at RN-I */
+#define OLY_RNI3PDVM_REGISTERS_NODE14_AUX_CTL_WFC BIT(3)
+
+#define OLY_HNI_REGISTERS_NODE0_POS_CONTROL (PLAT_BRCM_CCN_BASE + 0x80000)
+#define POS_CONTROL_HNI_POS_EN BIT(0)
+
+#define OLY_HNI_REGISTERS_NODE0_PCIERC_RNI_NODEID_LIST \
+ (PLAT_BRCM_CCN_BASE + 0x80008)
+/* PAXB and PAXC connected to 8th Node */
+#define SR_RNI_PCIE_CONNECTED BIT(8)
+/* PAXB connected to 6th Node */
+#define SRP_RNI_PCIE_CONNECTED BIT(6)
+
+#define OLY_HNI_REGISTERS_NODE0_SA_AUX_CTL (PLAT_BRCM_CCN_BASE + 0x80500)
+#define SA_AUX_CTL_POS_EARLY_WR_COMP_EN BIT(5)
+#define SA_AUX_CTL_SER_DEVNE_WR BIT(9)
+
+/*******************************************************************************
+ * Coresight related constants
+ ******************************************************************************/
+#define CORESIGHT_BASE_ADDR 0x62000000
+
+#define IHOST0_BASE 0x66000000
+#define IHOST_ADDR_SPACE 0x2000
+
+/*******************************************************************************
+ * SCR related constants
+ ******************************************************************************/
+#define SCR_BASE 0x6600a000
+#define SCR_ARCACHE_OFFSET 4
+#define SCR_ARCACHE_MASK (0x3 << SCR_ARCACHE_OFFSET)
+#define SCR_AWCACHE_OFFSET 6
+#define SCR_AWCACHE_MASK (0x3 << SCR_AWCACHE_OFFSET)
+#define SCR_AXCACHE_CONFIG_MASK (SCR_ARCACHE_MASK | SCR_AWCACHE_MASK)
+#define SCR_TBUX_AXCACHE_CONFIG ((0x1 << SCR_AWCACHE_OFFSET) | \
+ (0x1 << SCR_ARCACHE_OFFSET))
+
+#define SCR_REGS_SCR_SOFT_RESET (SCR_BASE + 0x1c)
+#define SCR_REGS_GIC_SOFT_RESET BIT(0)
+
+#define SCR_GPV_BASE 0x66100000
+#define SCR_NOC_SECURITY0 (SCR_GPV_BASE + 0x08)
+#define SCR_NOC_DDR_REGISTER_ACCESS (SCR_GPV_BASE + 0x30)
+
+/*******************************************************************************
+ * MEMC and DDR related constants
+ ******************************************************************************/
+#define DDR0_CONTROL_ROOT 0x66200000
+#define EMEM_SS_CFG_0_ROOT 0x66202000
+#define EMEM_SYS_IF_0_ROOT 0x66204000
+#define DDR_PHY0_ROOT 0x66240000
+
+#define DDR1_CONTROL_ROOT 0x66280000
+#define EMEM_SS_CFG_1_ROOT 0x66282000
+#define EMEM_SYS_IF_1_ROOT 0x66284000
+#define DDR_PHY1_ROOT 0x662c0000
+
+#define DDR2_CONTROL_ROOT 0x66300000
+#define EMEM_SS_CFG_2_ROOT 0x66302000
+#define EMEM_SYS_IF_2_ROOT 0x66304000
+#define DDR_PHY2_ROOT 0x66340000
+
+/*******************************************************************************
+ * TZC400 related constants
+ ******************************************************************************/
+#define TZC_400_BASE 0x66d84000
+
+/*******************************************************************************
+ * FS4 related constants
+ ******************************************************************************/
+#define FS4_SRAM_IDM_IO_CONTROL_DIRECT 0x66d8a408
+
+#define FS4_CRYPTO_IDM_IO_CONTROL_DIRECT 0x66d8e408
+#define FS4_CRYPTO_IDM_RESET_CONTROL 0x66d8e800
+#define FS4_CRYPTO_BASE 0x67000000
+#define FS4_CRYPTO_DME_BASE (FS4_CRYPTO_BASE + 0x280000)
+
+#define FS4_RAID_IDM_IO_CONTROL_DIRECT 0x66d8f408
+#define FS4_RAID_IDM_IO_STATUS 0x66d8f500
+#define FS4_RAID_IDM_RESET_CONTROL 0x66d8f800
+#define FS4_RAID_BASE 0x67400000
+#define FS4_RAID_DME_BASE (FS4_RAID_BASE + 0x280000)
+
+#define FS4_CRYPTO_GPV_BASE 0x67300000
+#define FS4_RAID_GPV_BASE 0x67700000
+
+#define FS6_PKI_BASE 0x67400000
+#define FS6_PKI_DME_BASE 0x66D90000
+
+#define TZC400_FS_SRAM_ROOT 0x66d84000
+#define GATE_KEEPER_OFFSET 0x8
+#define REGION_ATTRIBUTES_0_OFFSET 0x110
+#define REGION_ID_ACCESS_0_OFFSET 0x114
+
+#define NIC400_FS_NOC_ROOT 0x66e00000
+#define NIC400_FS_NOC_SECURITY2_OFFSET 0x10
+#define NIC400_FS_NOC_SECURITY4_OFFSET 0x18
+#define NIC400_FS_NOC_SECURITY7_OFFSET 0x24
+
+/*******************************************************************************
+ * SATA PHY related constants
+ ******************************************************************************/
+#define SATA_BASE 0x67d00000
+
+/*******************************************************************************
+ * USB related constants
+ ******************************************************************************/
+#define USB_BASE 0x68500000
+#define USB_SIZE 0x00400000
+#define XHC_BASE (USB_BASE + 0x11000)
+#define MAX_USB_PORTS 3
+
+/*******************************************************************************
+ * HSLS related constants
+ ******************************************************************************/
+#define IPROC_ROOT 0x68900000
+#define HSLS_ICFG_REGS_BASE IPROC_ROOT
+#define HSLS_IDM_REGS_BASE 0x68e00000
+#define HSLS_MODE_SEL_CONTROL 0x68a40000
+#define HSLS_TZPC_BASE 0x68b40000
+#define HSLS_GPV_BASE 0x6cd00000
+
+/*******************************************************************************
+ * Chip ID related constants
+ ******************************************************************************/
+#define ICFG_CHIP_ID HSLS_ICFG_REGS_BASE
+#define CHIP_ID_SR 0xd730
+#define CHIP_ID_NS3Z 0xe56d
+#define CHIP_ID_MASK 0xf000
+#define ICFG_CHIP_REVISION_ID (HSLS_ICFG_REGS_BASE + 0x4)
+#define PLAT_CHIP_ID_GET (mmio_read_32(ICFG_CHIP_ID))
+#define PLAT_CHIP_REV_GET (mmio_read_32(ICFG_CHIP_REVISION_ID))
+
+/*******************************************************************************
+ * Timers related constants
+ ******************************************************************************/
+/* ChipcommonG_tim0_TIM_TIMER1Load 0x68930000 */
+#define SP804_TIMER0_BASE 0x68930000
+#define SP804_TIMER1_BASE 0x68940000
+#define SP804_TIMER0_TIMER_VAL_REG_OFFSET 0x4
+#define SP804_TIMER0_CLKMULT 2
+#define SP804_TIMER0_CLKDIV 25
+
+/*******************************************************************************
+ * GPIO related constants
+ ******************************************************************************/
+#define IPROC_GPIO_NS_BASE 0x689d0000
+#define IPROC_GPIO_S_BASE 0x68b00000
+#define IPROC_GPIO_NR 151
+#define GPIO_S_CNTRL_REG 0x68b60000
+
+/*******************************************************************************
+ * I2C SMBUS related constants
+ ******************************************************************************/
+#define SMBUS0_REGS_BASE 0x689b0000
+#define SMBUS1_REGS_BASE 0x689e0000
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define ChipcommonG_UART0_UART_RBR_THR_DLL 0x68a00000
+#define ChipcommonG_UART1_UART_RBR_THR_DLL 0x68a10000
+#define ChipcommonG_UART2_UART_RBR_THR_DLL 0x68a20000
+#define ChipcommonG_UART3_UART_RBR_THR_DLL 0x68a30000
+
+#define UART0_BASE_ADDR ChipcommonG_UART0_UART_RBR_THR_DLL
+#define UART1_BASE_ADDR ChipcommonG_UART1_UART_RBR_THR_DLL
+#define UART2_BASE_ADDR ChipcommonG_UART2_UART_RBR_THR_DLL
+#define UART3_BASE_ADDR ChipcommonG_UART3_UART_RBR_THR_DLL
+
+#define UART_SPR_OFFSET 0x1c /* Scratch Pad Register */
+
+#define LOG_LEVEL_REGISTER CRMU_SPARE_REG_3
+#define GET_LOG_LEVEL() (mmio_read_32(LOG_LEVEL_REGISTER))
+#define SET_LOG_LEVEL(x) (mmio_write_32(LOG_LEVEL_REGISTER, x))
+
+#define IO_RETRY_REGISTER CRMU_SPARE_REG_4
+
+#define DWC_UART_REFCLK (25 * 1000 * 1000)
+#define DWC_UART_REFCLK_DIV 16
+/* Baud rate in emulation will vary based on setting of 25MHz SCLK */
+#define DWC_UART_BAUDRATE 115200
+
+#define BRCM_CRASH_CONSOLE_BASE UART1_BASE_ADDR
+#define BRCM_CRASH_CONSOLE_REFCLK DWC_UART_REFCLK
+#define BRCM_CRASH_CONSOLE_BAUDRATE DWC_UART_BAUDRATE
+
+#ifdef BOARD_CONSOLE_UART
+#define PLAT_BRCM_BOOT_UART_BASE BOARD_CONSOLE_UART
+#else
+#define PLAT_BRCM_BOOT_UART_BASE UART1_BASE_ADDR
+#endif
+#define CONSOLE_UART_ID ((PLAT_BRCM_BOOT_UART_BASE >> 16) & 0x3)
+
+#define PLAT_BRCM_BOOT_UART_CLK_IN_HZ DWC_UART_REFCLK
+#define BRCM_CONSOLE_BAUDRATE DWC_UART_BAUDRATE
+
+#define PLAT_BRCM_BL31_RUN_UART_BASE PLAT_BRCM_BOOT_UART_BASE
+#define PLAT_BRCM_BL31_RUN_UART_CLK_IN_HZ PLAT_BRCM_BOOT_UART_CLK_IN_HZ
+
+/*******************************************************************************
+ * IOMUX related constants
+ ******************************************************************************/
+#define HSLS_IOPAD_BASE HSLS_MODE_SEL_CONTROL
+#define MODE_SEL_CONTROL_FSEL_MASK 0x7
+#define MODE_SEL_CONTROL_FSEL_MODE0 0x0
+#define MODE_SEL_CONTROL_FSEL_MODE1 0x1
+#define MODE_SEL_CONTROL_FSEL_MODE2 0x2
+#define MODE_SEL_CONTROL_FSEL_MODE3 0x3
+#define MODE_SEL_CONTROL_FSEL_DEBUG 0x4
+#define IPROC_IOPAD_MODE_BASE (HSLS_MODE_SEL_CONTROL + 0x29c)
+#define UART0_SIN_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x4a8)
+#define UART0_SOUT_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x4ac)
+#define UART1_SIN_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3b8)
+#define UART1_SOUT_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3bc)
+#define UARTx_SIN_MODE_SEL_CONTROL_FSEL 0
+#define UARTx_SOUT_MODE_SEL_CONTROL_FSEL 0
+
+/*******************************************************************************
+ * PKA constants
+ ******************************************************************************/
+#define ICFG_PKA_MEM_PWR_CTRL (HSLS_ICFG_REGS_BASE + 0xac0)
+#define ICFG_PKA_MEM_PWR_CTRL__POWERONIN BIT(0)
+#define ICFG_PKA_MEM_PWR_CTRL__POWEROKIN BIT(1)
+#define ICFG_PKA_MEM_PWR_CTRL__ARRPOWERONIN BIT(2)
+#define ICFG_PKA_MEM_PWR_CTRL__ARRPOWEROKIN BIT(3)
+#define ICFG_PKA_MEM_PWR_CTRL__POWERONOUT BIT(4)
+#define ICFG_PKA_MEM_PWR_CTRL__POWEROKOUT BIT(5)
+#define ICFG_PKA_MEM_PWR_CTRL__ARRPOWERONOUT BIT(6)
+#define ICFG_PKA_MEM_PWR_CTRL__ARRPOWEROKOUT BIT(7)
+#define ICFG_PKA_MEM_PWR_CTRL__ISO BIT(8)
+
+/*******************************************************************************
+ * RNG constants
+ ******************************************************************************/
+#define RNG_BASE_ADDR 0x68b20000
+
+/*******************************************************************************
+ * Trusted Watchdog constants
+ ******************************************************************************/
+#define ARM_SP805_TWDG_BASE 0x68b30000
+#define ARM_SP805_TWDG_CLK_HZ ((25 * 1000 * 1000) / 2)
+/*
+ * The TBBR document specifies a watchdog timeout of 256 seconds. SP805
+ * asserts reset after two consecutive countdowns (2 x 128 = 256 sec)
+ */
+#define ARM_TWDG_TIMEOUT_SEC 128
+#define ARM_TWDG_LOAD_VAL (ARM_SP805_TWDG_CLK_HZ * \
+ ARM_TWDG_TIMEOUT_SEC)
+
+/*******************************************************************************
+ * SOTP related constants
+ ******************************************************************************/
+#define SOTP_REGS_OTP_BASE 0x68b50000
+#define SOTP_CHIP_CTRL (SOTP_REGS_OTP_BASE + 0x4c)
+#define SOTP_CLEAR_SYSCTRL_ALL_MASTER_NS 0
+
+/*******************************************************************************
+ * DMAC/PL330 related constants
+ ******************************************************************************/
+#define DMAC_M0_IDM_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x408)
+#define BOOT_MANAGER_NS BIT(25)
+#define DMAC_M0_IDM_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0x800)
+#define ICFG_DMAC_CONFIG_0 (HSLS_ICFG_REGS_BASE + 0x190)
+#define ICFG_DMAC_CONFIG_1 (HSLS_ICFG_REGS_BASE + 0x194)
+#define ICFG_DMAC_CONFIG_2 (HSLS_ICFG_REGS_BASE + 0x198)
+#define BOOT_PERIPHERAL_NS 0xffffffff
+#define ICFG_DMAC_CONFIG_3 (HSLS_ICFG_REGS_BASE + 0x19c)
+#define BOOT_IRQ_NS 0x0000ffff
+#define ICFG_DMAC_SID_ARADDR_CONTROL (HSLS_ICFG_REGS_BASE + 0xaf0)
+#define ICFG_DMAC_SID_AWADDR_CONTROL (HSLS_ICFG_REGS_BASE + 0xaf4)
+#define ICFG_DMAC_MEM_PWR_CTRL__POWERONIN BIT(0)
+#define ICFG_DMAC_MEM_PWR_CTRL__POWEROKIN BIT(1)
+#define ICFG_DMAC_MEM_PWR_CTRL__ARRPOWERONIN BIT(2)
+#define ICFG_DMAC_MEM_PWR_CTRL__ARRPOWEROKIN BIT(3)
+#define ICFG_DMAC_MEM_PWR_CTRL__POWERONOUT BIT(4)
+#define ICFG_DMAC_MEM_PWR_CTRL__POWEROKOUT BIT(5)
+#define ICFG_DMAC_MEM_PWR_CTRL__ARRPOWERONOUT BIT(6)
+#define ICFG_DMAC_MEM_PWR_CTRL__ARRPOWEROKOUT BIT(7)
+#define ICFG_DMAC_MEM_PWR_CTRL__ISO BIT(8)
+#define ICFG_DMAC_MEM_PWR_CTRL (HSLS_ICFG_REGS_BASE + 0xadc)
+
+/*******************************************************************************
+ * PNOR related constants
+ ******************************************************************************/
+#define PNOR_ICFG_BASE (HSLS_ICFG_REGS_BASE + 0x780)
+#define PNOR_ICFG_CS_0 PNOR_ICFG_BASE
+#define PNOR_ICFG_CS_1 (PNOR_ICFG_BASE + 0x4)
+#define PNOR_ICFG_CS_2 (PNOR_ICFG_BASE + 0x8)
+#define PNOR_ICFG_CS_x_MASK0_MASK 0xff
+#define PNOR_ICFG_CS_x_MASK0_SHIFT 8
+#define PNOR_ICFG_CS_x_MATCH0_MASK 0xff
+#define PNOR_ICFG_CS_x_MATCH0_SHIFT 0
+
+#define PNOR_IDM_BASE (HSLS_IDM_REGS_BASE + 0xb000)
+#define PNOR_IDM_IO_CONTROL_DIRECT (PNOR_IDM_BASE + 0x408)
+#define PNOR_IDM_IO_RESET_CONTROL (PNOR_IDM_BASE + 0x800)
+
+#define PNOR_REG_BASE 0x68c50000
+#define PNOR_REG_DIRECT_CMD (PNOR_REG_BASE + 0x010)
+#define PNOR_REG_SET_CYCLES (PNOR_REG_BASE + 0x014)
+#define PNOR_REG_SET_OPMODE (PNOR_REG_BASE + 0x018)
+#define PNOR_REG_REFRESH_0 (PNOR_REG_BASE + 0x020)
+#define PNOR_REG_PERIPH_ID0 (PNOR_REG_BASE + 0xfe0)
+#define PNOR_REG_PERIPH_ID1 (PNOR_REG_BASE + 0xfe4)
+#define PNOR_REG_PERIPH_ID2 (PNOR_REG_BASE + 0xfe8)
+#define PNOR_REG_PERIPH_ID3 (PNOR_REG_BASE + 0xfec)
+#define PNOR_REG_PERIPH_IDx_MASK 0xff
+
+/*******************************************************************************
+ * NAND related constants
+ ******************************************************************************/
+#define NAND_FLASH_REVISION 0x68c60000
+#define NAND_IDM_IDM_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0xa408)
+#define NAND_IDM_IDM_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0xa800)
+
+/*******************************************************************************
+ * eMMC related constants
+ ******************************************************************************/
+#define PLAT_SD_MAX_READ_LENGTH 0x400
+
+#define SDIO0_EMMCSDXC_SYSADDR 0x68cf1000
+#define SDIO_IDM0_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x2408)
+#define SDIO_IDM1_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x3408)
+#define SDIO_IDM0_IDM_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0x2800)
+#define ICFG_SDIO0_BASE (HSLS_ICFG_REGS_BASE + 0x6e4)
+#define ICFG_SDIO1_BASE (HSLS_ICFG_REGS_BASE + 0x734)
+#define ICFG_SDIO0_CAP0 (ICFG_SDIO0_BASE + 0x10)
+#define ICFG_SDIO0_CAP1 (ICFG_SDIO0_BASE + 0x14)
+#define ICFG_SDIO0_SID (HSLS_ICFG_REGS_BASE + 0xb00)
+#define ICFG_SDIO1_SID (HSLS_ICFG_REGS_BASE + 0xb08)
+
+/*******************************************************************************
+ * Bootstrap related constants
+ ******************************************************************************/
+#define ROM_S0_IDM_IO_STATUS (HSLS_IDM_REGS_BASE + 0x9500)
+
+/*******************************************************************************
+ * ROM related constants
+ ******************************************************************************/
+#define ROM_BASE_ADDR 0x6ce00000
+#define ROM_VERSION_STRING_ADDR (ROM_BASE_ADDR + 0x28000)
+#define ROM_BUILD_MESSAGE_ADDR (ROM_BASE_ADDR + 0x28018)
+
+/*******************************************************************************
+ * Boot source peripheral related constants
+ ******************************************************************************/
+#define QSPI_CTRL_BASE_ADDR 0x68c70000
+#define QSPI_BASE_ADDR 0x70000000
+#define QSPI_SIZE 0x08000000
+#define NOR_BASE_ADDR 0x74000000
+#define NOR_SIZE 0x04000000
+#define NAND_BASE_ADDR 0x78000000
+#define NAND_SIZE 0x08000000
+
+#define QSPI_IDM_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0xc800)
+
+#define APBR_IDM_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0xe800)
+#define APBS_IDM_IDM_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0xf800)
+
+#define APBX_IDM_IDM_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x10408)
+#define APBX_IDM_IDM_IO_CONTROL_DIRECT_CLK_ENABLE 0
+#define APBX_IDM_IDM_IO_CONTROL_DIRECT_WDOG_SCLK_SEL 2
+#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM0_SCLK_SEL 4
+#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM1_SCLK_SEL 6
+#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM2_SCLK_SEL 8
+#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM3_SCLK_SEL 10
+#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM4_SCLK_SEL 12
+#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM5_SCLK_SEL 13
+#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM6_SCLK_SEL 14
+#define APBX_IDM_IDM_IO_CONTROL_DIRECT_TIM7_SCLK_SEL 15
+
+#define APBY_IDM_IDM_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x11408)
+#define APBY_IDM_IDM_IO_CONTROL_DIRECT_CLK_ENABLE 0
+#define APBY_IDM_IDM_IO_CONTROL_DIRECT_UART0_SCLK_SEL 2
+#define APBY_IDM_IDM_IO_CONTROL_DIRECT_UART1_SCLK_SEL 4
+#define APBY_IDM_IDM_IO_CONTROL_DIRECT_UART2_SCLK_SEL 6
+#define APBY_IDM_IDM_IO_CONTROL_DIRECT_UART3_SCLK_SEL 8
+
+#define APBZ_IDM_IDM_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x12408)
+#define APBZ_IDM_IDM_IO_CONTROL_DIRECT_CLK_ENABLE 0
+#define APBZ_IDM_IDM_IO_CONTROL_DIRECT_WDOG_SCLK_SEL 2
+
+/*******************************************************************************
+ * Stingray memory map related constants
+ ******************************************************************************/
+
+/* The last 4KB of Trusted SRAM are used as shared memory */
+#define BRCM_SHARED_RAM_SIZE 0x0
+#define BRCM_SHARED_RAM_BASE (PLAT_BRCM_TRUSTED_SRAM_BASE + \
+ PLAT_BRCM_TRUSTED_SRAM_SIZE - \
+ BRCM_SHARED_RAM_SIZE)
+
+/* Reserve 4 KB to store error logs in BL2 */
+#define BCM_ELOG_BL2_SIZE 0x00001000
+#define BCM_ELOG_BL2_BASE BL1_RW_LIMIT
+
+/* The remaining Trusted SRAM is used to load the BL images */
+#define BRCM_BL_RAM_BASE (PLAT_BRCM_TRUSTED_SRAM_BASE)
+#define BRCM_BL_RAM_SIZE (PLAT_BRCM_TRUSTED_SRAM_SIZE - \
+ BRCM_SHARED_RAM_SIZE)
+
+/* DDR Address where TMON temperature values are written */
+#define TMON_SHARED_DDR_ADDRESS 0x8f100000
+
+/* Reserve 4 kB to pass data to BL33 */
+#define BL33_SHARED_DDR_BASE 0x8f102000
+#define BL33_SHARED_DDR_SIZE 0x1000
+
+/* Default AP error logging base addr */
+#ifndef ELOG_AP_UART_LOG_BASE
+#define ELOG_AP_UART_LOG_BASE 0x8f110000
+#endif
+
+/* Reserve 16 to store error logs in BL31 */
+#define BCM_ELOG_BL31_BASE ELOG_AP_UART_LOG_BASE
+#define BCM_ELOG_BL31_SIZE 0x4000
+
+/*******************************************************************************
+ * Non-secure DDR Map
+ ******************************************************************************/
+#define BRCM_DRAM1_BASE ULL(0x80000000)
+#define BRCM_DRAM1_SIZE ULL(0x10000000)
+#define BRCM_DRAM2_BASE ULL(0x880000000)
+#define BRCM_DRAM2_SIZE ULL(0x780000000)
+#define BRCM_DRAM3_BASE ULL(0x8800000000)
+#define BRCM_DRAM3_SIZE ULL(0x7800000000)
+#define BRCM_SHARED_DRAM_BASE BL33_SHARED_DDR_BASE
+#define BRCM_SHARED_DRAM_SIZE BL33_SHARED_DDR_SIZE
+#define BRCM_EXT_SRAM_BASE ULL(0x74000000)
+#define BRCM_EXT_SRAM_SIZE ULL(0x4000000)
+
+/* Priority levels for platforms */
+#define PLAT_RAS_PRI 0x10
+#define PLAT_SDEI_CRITICAL_PRI 0x60
+#define PLAT_SDEI_NORMAL_PRI 0x70
+
+/* Define a list of Group 1 Secure and Group 0 interrupts as per GICv3 */
+#define BRCM_IRQ_SEC_SGI_0 14
+#define BRCM_IRQ_SEC_SGI_1 15
+
+/* RTC periodic interrupt */
+#define BRCM_IRQ_SEC_SPI_0 49
+
+/*
+ * Macros for local power states in SR platforms encoded by State-ID field
+ * within the power-state parameter.
+ */
+
+/* Local power state for power domains in Run state. */
+#define PLAT_LOCAL_STATE_RUN 0
+
+/* Local power state for retention. Valid only for CPU power domains */
+#define PLAT_LOCAL_STATE_RET 1
+
+/*
+ * Local power state for OFF/power-down. Valid for CPU and cluster power
+ * domains.
+ */
+#define PLAT_LOCAL_STATE_OFF 2
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE PLAT_LOCAL_STATE_RET
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE PLAT_LOCAL_STATE_OFF
+
+/* ChiMP-related constants */
+
+#define NITRO_TZPC_TZPCDECPROT0clr 0x60c01808
+#define NITRO_TZPC_TZPCDECPROT0clr__DECPROT0_chimp_m_clr_R 1
+
+#define NIC400_NITRO_CHIMP_S_IDM_IO_CONTROL_DIRECT 0x60e00408
+
+#define CHIMP_INDIRECT_ADDR_MASK 0x3fffff
+#define CHIMP_INDIRECT_BASE 0x60800000
+
+#define CHIMP_REG_ECO_RESERVED 0x3042400
+
+#define CHIMP_FLASH_ACCESS_DONE_BIT 2
+
+/* indicate FRU table programming is done successfully */
+#define CHIMP_FRU_PROG_DONE_BIT 9
+
+#define CHIMP_REG_CTRL_BPE_MODE_REG 0x0
+#define CHIMP_REG_CTRL_BPE_STAT_REG 0x4
+#define CHIMP_REG_CTRL_FSTBOOT_PTR_REG 0x8
+#define CHIMP_REG_CHIMP_REG_CTRL_BPE_MODE_REG__cm3_rst_L 1
+#define CHIMP_REG_CHIMP_REG_CTRL_BPE_MODE_REG__cm3_rst_R 1
+#define CHIMP_REG_CTRL_BASE 0x3040000
+#define CHIMP_FAST_BOOT_MODE_BIT 2
+#define CHIMP_REG_CHIMP_APE_SCPAD 0x3300000
+#define CHIMP_REG_CHIMP_SCPAD 0x3100000
+
+/* Chimp health status offset in scratch pad ram */
+#define CHIMP_HEALTH_STATUS_OFFSET 0x8
+/*
+ * If not in NIC mode then FASTBOOT can be enabled.
+ * "Not in NIC mode" means that FORCE_FASTBOOT is set
+ * and a valid (1 or 2) fastboot type is specified.
+ *
+ * Three types of fastboot are supported:
+ * 0 = No fastboot. Boots Nitro/ChiMP and lets ROM loader
+ * initialize ChiMP from NVRAM (QSPI).
+ *
+ * 1 = Jump in place (need a flat image)
+ * This is intended to speedup Nitro FW boot on Palladium,
+ * can be used with a real chip as well.
+ * 2 = Jump normally with decompression
+ * Modus operandi for a real chip. Works also on Palladium
+ * Note: image decompressing takes time on Palladium.
+ * 3 = No fastboot support. No ChiMP bringup
+ * (use only for AP debug or for ChiMP's deferred setup).
+ */
+#define CHIMP_FASTBOOT_JUMP_DECOMPRESS 2
+#define CHIMP_FASTBOOT_JUMP_IN_PLACE 1
+#define CHIMP_FASTBOOT_NITRO_RESET 0
+/*
+ * Definitions for a non-Nitro access
+ * to QSPI PAD after the handshake
+ */
+#define QSPI_HOLD_N_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3e8)
+#define QSPI_WP_N_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3ec)
+#define QSPI_SCK_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3f0)
+#define QSPI_CS_N_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3f4)
+#define QSPI_MOSI_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3f8)
+#define QSPI_MISO_MODE_SEL_CONTROL (HSLS_MODE_SEL_CONTROL + 0x3fc)
+
+/*******************************************************************************
+ * Stream IDs for different blocks of SR
+ * block_id for different blocks is as follows:
+ * PCIE : 0x0
+ * PAXC : 0x1
+ * FS4 : 0x2
+ * Rest of the masters(includes MHB via RNI): 0x3
+ ******************************************************************************/
+#define SR_SID_VAL(block_id, subblock_id, device_num) ((block_id << 13) | \
+ (subblock_id << 11) | \
+ (device_num))
+
+#define CRMU_STREAM_ID SR_SID_VAL(0x3, 0x0, 0x7)
+#define CRMU_SID_SHIFT 5
+
+#define DMAC_STREAM_ID SR_SID_VAL(0x3, 0x0, 0x0)
+#define DMAC_SID_SHIFT 5
+
+/* DDR SHMOO Values defines */
+#define IDRAM_SHMOO_VALUES_ADDR CRMU_IDRAM_BASE_ADDR
+#define DDR_SHMOO_VALUES_ADDR 0x8f103000
+#define SHMOO_SIZE_PER_CHANNEL 0x1000
+
+#endif /* SR_DEF_H */
diff --git a/plat/brcm/board/stingray/include/sr_utils.h b/plat/brcm/board/stingray/include/sr_utils.h
new file mode 100644
index 000000000..b3fc735f7
--- /dev/null
+++ b/plat/brcm/board/stingray/include/sr_utils.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SR_UTILS_H
+#define SR_UTILS_H
+
+#include <lib/mmio.h>
+
+#include <chip_id.h>
+#include <cmn_plat_util.h>
+#include <sr_def.h>
+
+static inline void brcm_stingray_set_qspi_mux(int enable_ap)
+{
+ mmio_write_32(QSPI_HOLD_N_MODE_SEL_CONTROL, enable_ap);
+ mmio_write_32(QSPI_WP_N_MODE_SEL_CONTROL, enable_ap);
+ mmio_write_32(QSPI_SCK_MODE_SEL_CONTROL, enable_ap);
+ mmio_write_32(QSPI_CS_N_MODE_SEL_CONTROL, enable_ap);
+ mmio_write_32(QSPI_MOSI_MODE_SEL_CONTROL, enable_ap);
+ mmio_write_32(QSPI_MISO_MODE_SEL_CONTROL, enable_ap);
+}
+
+static inline void brcm_stingray_set_straps(uint32_t boot_source)
+{
+ /* Enable software strap override */
+ mmio_setbits_32(CDRU_CHIP_STRAP_CTRL,
+ BIT(CDRU_CHIP_STRAP_CTRL__SOFTWARE_OVERRIDE));
+
+ /* set straps to the next boot source */
+ mmio_clrsetbits_32(CDRU_CHIP_STRAP_DATA,
+ BOOT_SOURCE_MASK,
+ boot_source);
+
+ /* Disable software strap override */
+ mmio_clrbits_32(CDRU_CHIP_STRAP_CTRL,
+ BIT(CDRU_CHIP_STRAP_CTRL__SOFTWARE_OVERRIDE));
+}
+
+#endif
diff --git a/plat/brcm/board/stingray/include/swreg.h b/plat/brcm/board/stingray/include/swreg.h
new file mode 100644
index 000000000..6e971ce34
--- /dev/null
+++ b/plat/brcm/board/stingray/include/swreg.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SWREG_H
+#define SWREG_H
+
+/* default voltage if no valid OTP */
+#define VDDC_CORE_DEF_VOLT 910000 /* 0.91v */
+#define IHOST_DEF_VOLT 940000 /* 0.94v */
+
+#define B0_VDDC_CORE_DEF_VOLT 950000 /* 0.95v */
+#define B0_IHOST_DEF_VOLT 950000 /* 0.95v */
+#define B0_DDR_VDDC_DEF_VOLT 1000000 /* 1v */
+
+#define SWREG_IHOST1_DIS 4
+#define SWREG_IHOST1_REG_RESETB 5
+#define SWREG_IHOST1_PMU_STABLE 2
+
+enum sw_reg {
+ DDR_VDDC = 1,
+ IHOST03,
+ IHOST12,
+ IHOST_ARRAY,
+ DDRIO_SLAVE,
+ VDDC_CORE,
+ VDDC1,
+ DDRIO_MASTER
+};
+
+int set_swreg(enum sw_reg reg_id, uint32_t micro_volts);
+int swreg_firmware_update(void);
+
+#endif
diff --git a/plat/brcm/board/stingray/include/timer_sync.h b/plat/brcm/board/stingray/include/timer_sync.h
new file mode 100644
index 000000000..1f15bb0f8
--- /dev/null
+++ b/plat/brcm/board/stingray/include/timer_sync.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2016 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TIMER_SYNC_H
+#define TIMER_SYNC_H
+
+void brcm_timer_sync_init(void);
+
+#endif
diff --git a/plat/brcm/board/stingray/platform.mk b/plat/brcm/board/stingray/platform.mk
new file mode 100644
index 000000000..c5509bb6b
--- /dev/null
+++ b/plat/brcm/board/stingray/platform.mk
@@ -0,0 +1,293 @@
+#
+# Copyright (c) 2019-2020, Broadcom
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Set the toc_flags to 1 for 100% speed operation
+# Set the toc_flags to 2 for 50% speed operation
+# Set the toc_flags to 3 for 25% speed operation
+# Set the toc_flags bit 3 to indicate ignore the fip in UEFI copy mode
+PLAT_TOC_FLAGS := 0x0
+
+# Set the IHOST_PLL_FREQ to,
+# 1 for full speed
+# 2 for 50% speed
+# 3 for 25% speed
+# 0 for bypass
+$(eval $(call add_define_val,IHOST_PLL_FREQ,1))
+
+# Enable workaround for ERRATA_A72_859971
+ERRATA_A72_859971 := 1
+
+# Cache Coherency Interconnect Driver needed
+DRIVER_CC_ENABLE := 1
+$(eval $(call add_define,DRIVER_CC_ENABLE))
+
+# Enable to erase eMMC
+INCLUDE_EMMC_DRIVER_ERASE_CODE := 0
+
+ifeq (${INCLUDE_EMMC_DRIVER_ERASE_CODE},1)
+$(eval $(call add_define,INCLUDE_EMMC_DRIVER_ERASE_CODE))
+endif
+
+# BL31 is in DRAM
+ARM_BL31_IN_DRAM := 1
+
+ifneq (${USE_EMULATOR},yes)
+STINGRAY_EMULATION_SETUP := 0
+ifeq (${FASTBOOT_TYPE},)
+override FASTBOOT_TYPE := 0
+endif
+USE_PAXB := yes
+USE_PAXC := yes
+USE_CHIMP := yes
+endif
+
+USE_CRMU_SRAM := yes
+
+# Disable FS4 clocks - they can be reenabled when needed by linux
+FS4_DISABLE_CLOCK := yes
+
+# Enable error logging by default for Stingray
+BCM_ELOG := yes
+
+# Enable FRU support by default for Stingray
+ifeq (${USE_FRU},)
+USE_FRU := no
+endif
+
+# Use single cluster
+ifeq (${USE_SINGLE_CLUSTER},yes)
+$(info Using Single Cluster)
+$(eval $(call add_define,USE_SINGLE_CLUSTER))
+endif
+
+# Use DDR
+ifeq (${USE_DDR},yes)
+$(info Using DDR)
+$(eval $(call add_define,USE_DDR))
+endif
+
+ifeq (${BOARD_CFG},)
+BOARD_CFG := bcm958742t
+endif
+
+# Use PAXB
+ifeq (${USE_PAXB},yes)
+$(info Using PAXB)
+$(eval $(call add_define,USE_PAXB))
+endif
+
+# Use FS4
+ifeq (${USE_FS4},yes)
+$(info Using FS4)
+$(eval $(call add_define,USE_FS4))
+endif
+
+# Use FS6
+ifeq (${USE_FS6},yes)
+$(info Using FS6)
+$(eval $(call add_define,USE_FS6))
+endif
+
+# Disable FS4 clock
+ifeq (${FS4_DISABLE_CLOCK},yes)
+$(info Using FS4_DISABLE_CLOCK)
+$(eval $(call add_define,FS4_DISABLE_CLOCK))
+endif
+
+ifneq (${NCSI_IO_DRIVE_STRENGTH_MA},)
+$(info Using NCSI_IO_DRIVE_STRENGTH_MA)
+$(eval $(call add_define,NCSI_IO_DRIVE_STRENGTH_MA))
+endif
+
+# Use NAND
+ifeq (${USE_NAND},$(filter yes, ${USE_NAND}))
+$(info Using NAND)
+$(eval $(call add_define,USE_NAND))
+endif
+
+# Enable Broadcom error logging support
+ifeq (${BCM_ELOG},yes)
+$(info Using BCM_ELOG)
+$(eval $(call add_define,BCM_ELOG))
+endif
+
+# BL31 build for standalone mode
+ifeq (${STANDALONE_BL31},yes)
+RESET_TO_BL31 := 1
+$(info Using RESET_TO_BL31)
+endif
+
+# BL31 force full frequency for all CPUs
+ifeq (${BL31_FORCE_CPU_FULL_FREQ},yes)
+$(info Using BL31_FORCE_CPU_FULL_FREQ)
+$(eval $(call add_define,BL31_FORCE_CPU_FULL_FREQ))
+endif
+
+# Enable non-secure accesses to CCN registers
+ifeq (${BL31_CCN_NONSECURE},yes)
+$(info Using BL31_CCN_NONSECURE)
+$(eval $(call add_define,BL31_CCN_NONSECURE))
+endif
+
+# Use ChiMP
+ifeq (${USE_CHIMP},yes)
+$(info Using ChiMP)
+$(eval $(call add_define,USE_CHIMP))
+endif
+
+# Use PAXC
+ifeq (${USE_PAXC},yes)
+$(info Using PAXC)
+$(eval $(call add_define,USE_PAXC))
+ifeq (${CHIMPFW_USE_SIDELOAD},yes)
+$(info Using ChiMP FW sideload)
+$(eval $(call add_define,CHIMPFW_USE_SIDELOAD))
+endif
+$(eval $(call add_define,FASTBOOT_TYPE))
+$(eval $(call add_define,CHIMP_FB1_ENTRY))
+endif
+
+ifeq (${DEFAULT_SWREG_CONFIG}, 1)
+$(eval $(call add_define,DEFAULT_SWREG_CONFIG))
+endif
+
+ifeq (${CHIMP_ALWAYS_NEEDS_QSPI},yes)
+$(eval $(call add_define,CHIMP_ALWAYS_NEEDS_QSPI))
+endif
+
+# For testing purposes, use memsys stubs. Remove once memsys is fully tested.
+USE_MEMSYS_STUBS := yes
+
+# Default, use BL1_RW area
+ifneq (${BL2_USE_BL1_RW},no)
+$(eval $(call add_define,USE_BL1_RW))
+endif
+
+# Default soft reset is L3
+$(eval $(call add_define,CONFIG_SOFT_RESET_L3))
+
+# Enable Chip OTP driver
+DRIVER_OCOTP_ENABLE := 1
+
+ifneq (${WARMBOOT_DDR_S3_SUPPORT},)
+DRIVER_SPI_ENABLE := 1
+endif
+
+include plat/brcm/board/common/board_common.mk
+
+SOC_DIR := brcm/board/stingray
+
+PLAT_INCLUDES += -Iplat/${SOC_DIR}/include/ \
+ -Iinclude/plat/brcm/common/ \
+ -Iplat/brcm/common/
+
+PLAT_BL_COMMON_SOURCES += lib/cpus/aarch64/cortex_a72.S \
+ plat/${SOC_DIR}/aarch64/plat_helpers.S \
+ drivers/ti/uart/aarch64/16550_console.S \
+ plat/${SOC_DIR}/src/tz_sec.c \
+ drivers/arm/tzc/tzc400.c \
+ plat/${SOC_DIR}/driver/plat_emmc.c \
+ plat/${SOC_DIR}/src/topology.c
+
+ifeq (${USE_CHIMP},yes)
+PLAT_BL_COMMON_SOURCES += drivers/brcm/chimp.c
+endif
+
+BL2_SOURCES += plat/${SOC_DIR}/driver/ihost_pll_config.c \
+ plat/${SOC_DIR}/src/bl2_setup.c \
+ plat/${SOC_DIR}/driver/swreg.c
+
+
+ifeq (${USE_DDR},yes)
+PLAT_INCLUDES += -Iplat/${SOC_DIR}/driver/ddr/soc/include
+else
+PLAT_INCLUDES += -Iplat/${SOC_DIR}/driver/ext_sram_init
+BL2_SOURCES += plat/${SOC_DIR}/driver/ext_sram_init/ext_sram_init.c
+endif
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+BRCM_GIC_SOURCES := ${GICV3_SOURCES} \
+ plat/common/plat_gicv3.c \
+ plat/brcm/common/brcm_gicv3.c
+
+BL31_SOURCES += \
+ drivers/arm/ccn/ccn.c \
+ plat/brcm/board/common/timer_sync.c \
+ plat/brcm/common/brcm_ccn.c \
+ plat/common/plat_psci_common.c \
+ plat/${SOC_DIR}/driver/ihost_pll_config.c \
+ plat/${SOC_DIR}/src/bl31_setup.c \
+ plat/${SOC_DIR}/src/fsx.c \
+ plat/${SOC_DIR}/src/iommu.c \
+ plat/${SOC_DIR}/src/sdio.c \
+ ${BRCM_GIC_SOURCES}
+
+ifneq (${NCSI_IO_DRIVE_STRENGTH_MA},)
+BL31_SOURCES += plat/${SOC_DIR}/src/ncsi.c
+endif
+
+ifeq (${USE_PAXB},yes)
+BL31_SOURCES += plat/${SOC_DIR}/src/paxb.c
+BL31_SOURCES += plat/${SOC_DIR}/src/sr_paxb_phy.c
+endif
+
+ifeq (${USE_PAXC},yes)
+BL31_SOURCES += plat/${SOC_DIR}/src/paxc.c
+endif
+
+ifdef SCP_BL2
+PLAT_INCLUDES += -Iplat/brcm/common/
+
+BL2_SOURCES += plat/brcm/common/brcm_mhu.c \
+ plat/brcm/common/brcm_scpi.c \
+ plat/${SOC_DIR}/src/scp_utils.c \
+ plat/${SOC_DIR}/src/scp_cmd.c \
+ drivers/brcm/scp.c
+
+BL31_SOURCES += plat/brcm/common/brcm_mhu.c \
+ plat/brcm/common/brcm_scpi.c \
+ plat/${SOC_DIR}/src/brcm_pm_ops.c
+else
+BL31_SOURCES += plat/${SOC_DIR}/src/ihost_pm.c \
+ plat/${SOC_DIR}/src/pm.c
+endif
+
+ifeq (${ELOG_SUPPORT},1)
+ifeq (${ELOG_STORE_MEDIA},DDR)
+BL2_SOURCES += plat/brcm/board/common/bcm_elog_ddr.c
+endif
+endif
+
+ifeq (${BL31_BOOT_PRELOADED_SCP}, 1)
+ifdef SCP_BL2
+SCP_CFG_DIR=$(dir ${SCP_BL2})
+PLAT_INCLUDES += -I${SCP_CFG_DIR}
+endif
+PLAT_INCLUDES += -Iplat/brcm/common/
+
+# By default use OPTEE Assigned memory
+PRELOADED_SCP_BASE ?= 0x8E000000
+PRELOADED_SCP_SIZE ?= 0x10000
+$(eval $(call add_define,PRELOADED_SCP_BASE))
+$(eval $(call add_define,PRELOADED_SCP_SIZE))
+$(eval $(call add_define,BL31_BOOT_PRELOADED_SCP))
+BL31_SOURCES += plat/${SOC_DIR}/src/scp_utils.c \
+ plat/${SOC_DIR}/src/scp_cmd.c \
+ drivers/brcm/scp.c
+endif
+
+# Do not execute the startup code on warm reset.
+PROGRAMMABLE_RESET_ADDRESS := 1
+
+# Nitro FW, config and Crash log uses secure DDR memory
+# Inaddition to above, Nitro master and slave is also secure
+ifneq ($(NITRO_SECURE_ACCESS),)
+$(eval $(call add_define,NITRO_SECURE_ACCESS))
+$(eval $(call add_define,DDR_NITRO_SECURE_REGION_START))
+$(eval $(call add_define,DDR_NITRO_SECURE_REGION_END))
+endif
diff --git a/plat/brcm/board/stingray/src/bl2_setup.c b/plat/brcm/board/stingray/src/bl2_setup.c
new file mode 100644
index 000000000..b2c8aec12
--- /dev/null
+++ b/plat/brcm/board/stingray/src/bl2_setup.c
@@ -0,0 +1,743 @@
+/*
+ * Copyright (c) 2016-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/sp805.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <chimp.h>
+#include <chip_id.h>
+#include <cmn_plat_util.h>
+#include <dmu.h>
+#include <emmc_api.h>
+#include <fru.h>
+#ifdef USE_GPIO
+#include <drivers/gpio.h>
+#include <iproc_gpio.h>
+#endif
+#include <platform_def.h>
+#include <sotp.h>
+#include <swreg.h>
+#include <sr_utils.h>
+#ifdef USE_DDR
+#include <ddr_init.h>
+#else
+#include <ext_sram_init.h>
+#endif
+#if DRIVER_OCOTP_ENABLE
+#include <ocotp.h>
+#endif
+#include "board_info.h"
+
+#define WORD_SIZE 8
+#define SWREG_AVS_OTP_OFFSET (13 * WORD_SIZE) /* 13th row byte offset */
+#define AON_GPIO_OTP_OFFSET (28 * WORD_SIZE) /* 28th row byte offset */
+#define BYTES_TO_READ 8
+
+/* OTP voltage step definitions */
+#define MVOLT_STEP_MAX 0x18 /* 1v */
+#define MVOLT_PER_STEP 10 /* 0.01mv per step */
+#define MVOLT_BASE 760 /* 0.76v */
+
+#define STEP_TO_UVOLTS(step) \
+ ((MVOLT_BASE + (MVOLT_PER_STEP * (step))) * 1000)
+
+#define GET_BITS(first, last, data) \
+ ((data >> first) & ((1 << (last - first + 1)) - 1))
+
+/*
+ * SW-REG OTP encoding:
+ *
+ * SWREG_bits[11:0] = OTP 13th row 12 bits[55:44]
+ * SWREG_bits[11:10] - Valid Bits (0x2 - valid, if not 0x2 - Invalid)
+ * SWREG_bits[9:5] - iHost03, iHost12
+ * SWREG_bits[4:0] - Core VDDC
+ */
+#define SWREG_OTP_BITS_START 12 /* 44th bit in MSB 32-bits */
+#define SWREG_OTP_BITS_END 23 /* 55th bit in MSB 32-bits */
+#define SWREG_VDDC_FIELD_START 0
+#define SWREG_VDDC_FIELD_END 4
+#define SWREG_IHOST_FIELD_START 5
+#define SWREG_IHOST_FIELD_END 9
+#define SWREG_VALID_BIT_START 10
+#define SWREG_VALID_BIT_END 11
+#define SWREG_VALID_BITS 0x2
+
+/*
+ * Row 13 bit 56 is programmed as '1' today. It is not being used, so plan
+ * is to flip this bit to '0' for B1 rev. Hence SW can leverage this bit
+ * to identify Bx chip to program different sw-regulators.
+ */
+#define SPARE_BIT 24
+
+#define IS_SR_B0(data) (((data) >> SPARE_BIT) & 0x1)
+
+#if DRIVER_OCOTP_ENABLE
+static struct otpc_map otp_stingray_map = {
+ .otpc_row_size = 2,
+ .data_r_offset = {0x10, 0x5c},
+ .data_w_offset = {0x2c, 0x64},
+ .word_size = 8,
+ .stride = 8,
+};
+#endif
+
+void plat_bcm_bl2_early_platform_setup(void)
+{
+ /* Select UART0 for AP via mux setting*/
+ if (PLAT_BRCM_BOOT_UART_BASE == UART0_BASE_ADDR) {
+ mmio_write_32(UART0_SIN_MODE_SEL_CONTROL, 1);
+ mmio_write_32(UART0_SOUT_MODE_SEL_CONTROL, 1);
+ }
+}
+
+#ifdef USE_NAND
+static void brcm_stingray_nand_init(void)
+{
+ unsigned int val;
+ unsigned int nand_idm_reset_control = 0x68e0a800;
+
+ VERBOSE(" stingray nand init start.\n");
+
+ /* Reset NAND */
+ VERBOSE(" - reset nand\n");
+ val = mmio_read_32((uintptr_t)(nand_idm_reset_control + 0x0));
+ mmio_write_32((uintptr_t)(nand_idm_reset_control + 0x0), val | 0x1);
+ udelay(500);
+ val = mmio_read_32((uintptr_t)(nand_idm_reset_control + 0x0));
+ mmio_write_32((uintptr_t)(nand_idm_reset_control + 0x0), val & ~0x1);
+ udelay(500);
+
+ VERBOSE(" stingray nand init done.\n");
+}
+#endif
+
+#if defined(USE_PAXB) || defined(USE_PAXC) || defined(USE_SATA)
+#define PCIE_RESCAL_CFG_0 0x40000130
+#define PCIE_CFG_RESCAL_RSTB_R (1 << 16)
+#define PCIE_CFG_RESCAL_PWRDNB_R (1 << 8)
+#define PCIE_RESCAL_STATUS_0 0x4000014c
+#define PCIE_STAT_PON_VALID_R (1 << 0)
+#define PCIE_RESCAL_OUTPUT_STATUS 0x40000154
+#define CDRU_PCIE_RESET_N_R (1 << CDRU_MISC_RESET_CONTROL__CDRU_PCIE_RESET_N_R)
+
+#ifdef EMULATION_SETUP
+static void brcm_stingray_pcie_reset(void)
+{
+}
+#else
+static void brcm_stingray_pcie_reset(void)
+{
+ unsigned int data;
+ int try;
+
+ if (bcm_chimp_is_nic_mode()) {
+ INFO("NIC mode detected; PCIe reset/rescal not executed\n");
+ return;
+ }
+
+ mmio_clrbits_32(CDRU_MISC_RESET_CONTROL, CDRU_PCIE_RESET_N_R);
+ mmio_setbits_32(CDRU_MISC_RESET_CONTROL, CDRU_PCIE_RESET_N_R);
+ /* Release reset */
+ mmio_setbits_32(PCIE_RESCAL_CFG_0, PCIE_CFG_RESCAL_RSTB_R);
+ mdelay(1);
+ /* Power UP */
+ mmio_setbits_32(PCIE_RESCAL_CFG_0,
+ (PCIE_CFG_RESCAL_RSTB_R | PCIE_CFG_RESCAL_PWRDNB_R));
+
+ try = 1000;
+ do {
+ udelay(1);
+ data = mmio_read_32(PCIE_RESCAL_STATUS_0);
+ try--;
+ } while ((data & PCIE_STAT_PON_VALID_R) == 0x0 && (try > 0));
+
+ if (try <= 0)
+ ERROR("PCIE_RESCAL_STATUS_0: 0x%x\n", data);
+
+ VERBOSE("PCIE_SATA_RESCAL_STATUS_0 0x%x.\n",
+ mmio_read_32(PCIE_RESCAL_STATUS_0));
+ VERBOSE("PCIE_SATA_RESCAL_OUTPUT_STATUS 0x%x.\n",
+ mmio_read_32(PCIE_RESCAL_OUTPUT_STATUS));
+ INFO("PCIE SATA Rescal Init done\n");
+}
+#endif /* EMULATION_SETUP */
+#endif /* USE_PAXB || USE_PAXC || USE_SATA */
+
+#ifdef USE_PAXC
+void brcm_stingray_chimp_check_and_fastboot(void)
+{
+ int fastboot_init_result;
+
+ if (bcm_chimp_is_nic_mode())
+ /* Do not wait here */
+ return;
+
+#if WARMBOOT_DDR_S3_SUPPORT
+ /*
+ * Currently DDR shmoo parameters and QSPI boot source are
+ * tied. DDR shmoo parameters are stored in QSPI, which is
+ * used for warmboot.
+ * Do not reset nitro for warmboot
+ */
+ if (is_warmboot() && (boot_source_get() == BOOT_SOURCE_QSPI))
+ return;
+#endif /* WARMBOOT_DDR_S3_SUPPORT */
+
+ /*
+ * Not in NIC mode,
+ * initiate fastboot (if enabled)
+ */
+ if (FASTBOOT_TYPE == CHIMP_FASTBOOT_NITRO_RESET) {
+
+ VERBOSE("Bring up Nitro/ChiMP\n");
+
+ if (boot_source_get() == BOOT_SOURCE_QSPI)
+ WARN("Nitro boots from QSPI when AP has booted from QSPI.\n");
+ brcm_stingray_set_qspi_mux(0);
+ VERBOSE("Nitro controls the QSPI\n");
+ }
+
+ fastboot_init_result = bcm_chimp_initiate_fastboot(FASTBOOT_TYPE);
+ if (fastboot_init_result && boot_source_get() != BOOT_SOURCE_QSPI)
+ ERROR("Nitro init error %d. Status: 0x%x; bpe_mod reg: 0x%x\n"
+ "fastboot register: 0x%x; handshake register 0x%x\n",
+ fastboot_init_result,
+ bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_STAT_REG),
+ bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_MODE_REG),
+ bcm_chimp_read_ctrl(CHIMP_REG_CTRL_FSTBOOT_PTR_REG),
+ bcm_chimp_read(CHIMP_REG_ECO_RESERVED));
+
+ /*
+ * CRMU watchdog kicks is an example, which is L1 reset,
+ * does not clear Nitro scratch pad ram.
+ * For Nitro resets: Clear the Nitro health status memory.
+ */
+ bcm_chimp_write((CHIMP_REG_CHIMP_SCPAD + CHIMP_HEALTH_STATUS_OFFSET),
+ 0);
+}
+#endif
+
+void set_ihost_vddc_swreg(uint32_t ihost_uvolts, uint32_t vddc_uvolts)
+{
+ NOTICE("ihost_uvolts: %duv, vddc_uvolts: %duv\n",
+ ihost_uvolts, vddc_uvolts);
+
+ set_swreg(VDDC_CORE, vddc_uvolts);
+ set_swreg(IHOST03, ihost_uvolts);
+ set_swreg(IHOST12, ihost_uvolts);
+}
+
+/*
+ * Reads SWREG AVS OTP bits (13th row) with ECC enabled and get voltage
+ * defined in OTP if valid OTP is found
+ */
+void read_avs_otp_bits(uint32_t *ihost_uvolts, uint32_t *vddc_uvolts)
+{
+ uint32_t offset = SWREG_AVS_OTP_OFFSET;
+ uint32_t ihost_step, vddc_step;
+ uint32_t avs_bits;
+ uint32_t buf[2];
+
+ if (bcm_otpc_read(offset, &buf[0], BYTES_TO_READ, 1) == -1)
+ return;
+
+ VERBOSE("AVS OTP %d ROW: 0x%x.0x%x\n",
+ offset/WORD_SIZE, buf[1], buf[0]);
+
+ /* get voltage readings from AVS OTP bits */
+ avs_bits = GET_BITS(SWREG_OTP_BITS_START,
+ SWREG_OTP_BITS_END,
+ buf[1]);
+
+ /* check for valid otp bits */
+ if (GET_BITS(SWREG_VALID_BIT_START, SWREG_VALID_BIT_END, avs_bits) !=
+ SWREG_VALID_BITS) {
+ WARN("Invalid AVS OTP bits at %d row\n", offset/WORD_SIZE);
+ return;
+ }
+
+ /* get ihost and vddc step value */
+ vddc_step = GET_BITS(SWREG_VDDC_FIELD_START,
+ SWREG_VDDC_FIELD_END,
+ avs_bits);
+
+ ihost_step = GET_BITS(SWREG_IHOST_FIELD_START,
+ SWREG_IHOST_FIELD_END,
+ avs_bits);
+
+ if ((ihost_step > MVOLT_STEP_MAX) || (vddc_step > MVOLT_STEP_MAX)) {
+ WARN("OTP entry invalid\n");
+ return;
+ }
+
+ /* get voltage in micro-volts */
+ *ihost_uvolts = STEP_TO_UVOLTS(ihost_step);
+ *vddc_uvolts = STEP_TO_UVOLTS(vddc_step);
+}
+
+/*
+ * This api reads otp bits and program internal swreg's - ihos12, ihost03,
+ * vddc_core and ddr_core based on different chip. External swreg's
+ * programming will be done from crmu.
+ *
+ * For A2 chip:
+ * Read OTP row 20, bit 50. This bit will be set for A2 chip. Once A2 chip is
+ * found, read AVS OTP row 13, 12bits[55:44], if valid otp bits are found
+ * then set ihost and vddc according to avs otp bits else set them to 0.94v
+ * and 0.91v respectively. Also update the firmware after setting voltage.
+ *
+ * For B0 chip:
+ * Read OTP row 13, bit 56. This bit will be set for B0 chip. Once B0 chip is
+ * found then set ihost and vddc to 0.95v and ddr_core to 1v. No AVS OTP bits
+ * are used get ihost/vddc voltages.
+ *
+ * For B1 chip:
+ * Read AVS OTP row 13, 12bits[55:44], if valid otp bits are found then set
+ * ihost and vddc according to avs otp bits else set them to 0.94v and 0.91v
+ * respectively.
+ */
+void set_swreg_based_on_otp(void)
+{
+ /* default voltage if no valid OTP */
+ uint32_t vddc_uvolts = VDDC_CORE_DEF_VOLT;
+ uint32_t ihost_uvolts = IHOST_DEF_VOLT;
+ uint32_t ddrc_uvolts;
+ uint32_t offset;
+ uint32_t buf[2];
+
+ offset = SWREG_AVS_OTP_OFFSET;
+ if (bcm_otpc_read(offset, &buf[0], BYTES_TO_READ, 1) == -1)
+ return;
+
+ VERBOSE("OTP %d ROW: 0x%x.0x%x\n",
+ offset/WORD_SIZE, buf[1], buf[0]);
+
+ if (IS_SR_B0(buf[1])) {
+ /* don't read AVS OTP for B0 */
+ ihost_uvolts = B0_IHOST_DEF_VOLT;
+ vddc_uvolts = B0_VDDC_CORE_DEF_VOLT;
+ ddrc_uvolts = B0_DDR_VDDC_DEF_VOLT;
+ } else {
+ read_avs_otp_bits(&ihost_uvolts, &vddc_uvolts);
+ }
+
+#if (IHOST_REG_TYPE == IHOST_REG_INTEGRATED) && \
+ (VDDC_REG_TYPE == VDDC_REG_INTEGRATED)
+ /* enable IHOST12 cluster before changing voltage */
+ NOTICE("Switching on the Regulator idx: %u\n",
+ SWREG_IHOST1_DIS);
+ mmio_clrsetbits_32(CRMU_SWREG_CTRL_ADDR,
+ BIT(SWREG_IHOST1_DIS),
+ BIT(SWREG_IHOST1_REG_RESETB));
+
+ /* wait for regulator supply gets stable */
+ while (!(mmio_read_32(CRMU_SWREG_STATUS_ADDR) &
+ (1 << SWREG_IHOST1_PMU_STABLE)))
+ ;
+
+ INFO("Regulator supply got stable\n");
+
+#ifndef DEFAULT_SWREG_CONFIG
+ swreg_firmware_update();
+#endif
+
+ set_ihost_vddc_swreg(ihost_uvolts, vddc_uvolts);
+#endif
+ if (IS_SR_B0(buf[1])) {
+ NOTICE("ddrc_uvolts: %duv\n", ddrc_uvolts);
+ set_swreg(DDR_VDDC, ddrc_uvolts);
+ }
+}
+
+#ifdef USE_DDR
+static struct ddr_info ddr_info;
+#endif
+#ifdef USE_FRU
+static struct fru_area_info fru_area[FRU_MAX_NR_AREAS];
+static struct fru_board_info board_info;
+static struct fru_time fru_tm;
+static uint8_t fru_tbl[BCM_MAX_FRU_LEN];
+
+static void board_detect_fru(void)
+{
+ uint32_t i, result;
+ int ret = -1;
+
+ result = bcm_emmc_init(false);
+ if (!result) {
+ ERROR("eMMC init failed\n");
+ return;
+ }
+
+ /* go through eMMC boot partitions looking for FRU table */
+ for (i = EMMC_BOOT_PARTITION1; i <= EMMC_BOOT_PARTITION2; i++) {
+ result = emmc_partition_select(i);
+ if (!result) {
+ ERROR("Switching to eMMC part %u failed\n", i);
+ return;
+ }
+
+ result = emmc_read(BCM_FRU_TBL_OFFSET, (uintptr_t)fru_tbl,
+ BCM_MAX_FRU_LEN, BCM_MAX_FRU_LEN);
+ if (!result) {
+ ERROR("Failed to read from eMMC part %u\n", i);
+ return;
+ }
+
+ /*
+ * Run sanity check and checksum to make sure valid FRU table
+ * is detected
+ */
+ ret = fru_validate(fru_tbl, fru_area);
+ if (ret < 0) {
+ WARN("FRU table not found in eMMC part %u\n", i);
+ continue;
+ }
+
+ /* parse DDR information from FRU table */
+ ret = fru_parse_ddr(fru_tbl, &fru_area[FRU_AREA_INTERNAL],
+ &ddr_info);
+ if (ret < 0) {
+ WARN("No FRU DDR info found in eMMC part %u\n", i);
+ continue;
+ }
+
+ /* parse board information from FRU table */
+ ret = fru_parse_board(fru_tbl, &fru_area[FRU_AREA_BOARD_INFO],
+ &board_info);
+ if (ret < 0) {
+ WARN("No FRU board info found in eMMC part %u\n", i);
+ continue;
+ }
+
+ /* if we reach here, valid FRU table is parsed */
+ break;
+ }
+
+ if (ret < 0) {
+ WARN("FRU table missing for this board\n");
+ return;
+ }
+
+ for (i = 0; i < BCM_MAX_NR_DDR; i++) {
+ INFO("DDR channel index: %d\n", ddr_info.mcb[i].idx);
+ INFO("DDR size %u GB\n", ddr_info.mcb[i].size_mb / 1024);
+ INFO("DDR ref ID by SW (Not MCB Ref ID) 0x%x\n",
+ ddr_info.mcb[i].ref_id);
+ }
+
+ fru_format_time(board_info.mfg_date, &fru_tm);
+
+ INFO("**** FRU board information ****\n");
+ INFO("Language 0x%x\n", board_info.lang);
+ INFO("Manufacturing Date %u.%02u.%02u, %02u:%02u\n",
+ fru_tm.year, fru_tm.month, fru_tm.day,
+ fru_tm.hour, fru_tm.min);
+ INFO("Manufacturing Date(Raw) 0x%x\n", board_info.mfg_date);
+ INFO("Manufacturer %s\n", board_info.manufacturer);
+ INFO("Product Name %s\n", board_info.product_name);
+ INFO("Serial number %s\n", board_info.serial_number);
+ INFO("Part number %s\n", board_info.part_number);
+ INFO("File ID %s\n", board_info.file_id);
+}
+#endif /* USE_FRU */
+
+#ifdef USE_GPIO
+
+#define INVALID_GPIO 0xffff
+
+static const int gpio_cfg_bitmap[MAX_NR_GPIOS] = {
+#ifdef BRD_DETECT_GPIO_BIT0
+ BRD_DETECT_GPIO_BIT0,
+#else
+ INVALID_GPIO,
+#endif
+#ifdef BRD_DETECT_GPIO_BIT1
+ BRD_DETECT_GPIO_BIT1,
+#else
+ INVALID_GPIO,
+#endif
+#ifdef BRD_DETECT_GPIO_BIT2
+ BRD_DETECT_GPIO_BIT2,
+#else
+ INVALID_GPIO,
+#endif
+#ifdef BRD_DETECT_GPIO_BIT3
+ BRD_DETECT_GPIO_BIT3,
+#else
+ INVALID_GPIO,
+#endif
+};
+
+static uint8_t gpio_bitmap;
+
+/*
+ * Use an odd number to avoid potential conflict with public GPIO level
+ * defines
+ */
+#define GPIO_STATE_FLOAT 15
+
+/*
+ * If GPIO_SUPPORT_FLOAT_DETECTION is disabled, simply return GPIO level
+ *
+ * If GPIO_SUPPORT_FLOAT_DETECTION is enabled, add additional test for possible
+ * pin floating (unconnected) scenario. This support is assuming externally
+ * applied pull up / pull down will have a stronger pull than the internal pull
+ * up / pull down.
+ */
+static uint8_t gpio_get_state(int gpio)
+{
+ uint8_t val;
+
+ /* set direction to GPIO input */
+ gpio_set_direction(gpio, GPIO_DIR_IN);
+
+#ifndef GPIO_SUPPORT_FLOAT_DETECTION
+ if (gpio_get_value(gpio) == GPIO_LEVEL_HIGH)
+ val = GPIO_LEVEL_HIGH;
+ else
+ val = GPIO_LEVEL_LOW;
+
+ return val;
+#else
+ /*
+ * Enable internal pull down. If GPIO level is still high, there must
+ * be an external pull up
+ */
+ gpio_set_pull(gpio, GPIO_PULL_DOWN);
+ if (gpio_get_value(gpio) == GPIO_LEVEL_HIGH) {
+ val = GPIO_LEVEL_HIGH;
+ goto exit;
+ }
+
+ /*
+ * Enable internal pull up. If GPIO level is still low, there must
+ * be an external pull down
+ */
+ gpio_set_pull(gpio, GPIO_PULL_UP);
+ if (gpio_get_value(gpio) == GPIO_LEVEL_LOW) {
+ val = GPIO_LEVEL_LOW;
+ goto exit;
+ }
+
+ /* if reached here, the pin must be not connected */
+ val = GPIO_STATE_FLOAT;
+
+exit:
+ /* make sure internall pull is disabled */
+ if (gpio_get_pull(gpio) != GPIO_PULL_NONE)
+ gpio_set_pull(gpio, GPIO_PULL_NONE);
+
+ return val;
+#endif
+}
+
+static void board_detect_gpio(void)
+{
+ unsigned int i, val;
+ int gpio;
+
+ iproc_gpio_init(IPROC_GPIO_S_BASE, IPROC_GPIO_NR,
+ IPROC_IOPAD_MODE_BASE, HSLS_IOPAD_BASE);
+
+ gpio_bitmap = 0;
+ for (i = 0; i < MAX_NR_GPIOS; i++) {
+ if (gpio_cfg_bitmap[i] == INVALID_GPIO)
+ continue;
+
+ /*
+ * Construct the bitmap based on GPIO value. Floating pin
+ * detection is a special case. As soon as a floating pin is
+ * detected, a special value of MAX_GPIO_BITMAP_VAL is
+ * assigned and we break out of the loop immediately
+ */
+ gpio = gpio_cfg_bitmap[i];
+ val = gpio_get_state(gpio);
+ if (val == GPIO_STATE_FLOAT) {
+ gpio_bitmap = MAX_GPIO_BITMAP_VAL;
+ break;
+ }
+
+ if (val == GPIO_LEVEL_HIGH)
+ gpio_bitmap |= BIT(i);
+ }
+
+ memcpy(&ddr_info, &gpio_ddr_info[gpio_bitmap], sizeof(ddr_info));
+ INFO("Board detection GPIO bitmap = 0x%x\n", gpio_bitmap);
+}
+#endif /* USE_GPIO */
+
+static void bcm_board_detect(void)
+{
+#ifdef DDR_LEGACY_MCB_SUPPORTED
+ /* Loading default DDR info */
+ memcpy(&ddr_info, &default_ddr_info, sizeof(ddr_info));
+#endif
+#ifdef USE_FRU
+ board_detect_fru();
+#endif
+#ifdef USE_GPIO
+ board_detect_gpio();
+#endif
+}
+
+static void dump_persistent_regs(void)
+{
+ NOTICE("pr0: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG0));
+ NOTICE("pr1: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG1));
+ NOTICE("pr2: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG2));
+ NOTICE("pr3: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG3));
+ NOTICE("pr4: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG4));
+ NOTICE("pr5: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG5));
+ NOTICE("pr6: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG6));
+ NOTICE("pr7: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG7));
+ NOTICE("pr8: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG8));
+ NOTICE("pr9: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG9));
+ NOTICE("pr10: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG10));
+ NOTICE("pr11: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG11));
+}
+
+void plat_bcm_bl2_plat_arch_setup(void)
+{
+ if (chip_get_rev_id_major() == CHIP_REV_MAJOR_AX) {
+ if (!(sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC) &
+ SOTP_ATF_WATCHDOG_ENABLE_MASK)) {
+ /*
+ * Stop sp805 watchdog timer immediately.
+ * It might has been set up by MCU patch earlier for
+ * eMMC workaround.
+ *
+ * Note the watchdog timer started in CRMU has a very
+ * short timeout and needs to be stopped immediately.
+ * Down below we restart it with a much longer timeout
+ * for BL2 and BL31
+ */
+ sp805_stop(ARM_SP805_TWDG_BASE);
+ }
+ }
+
+#if !BRCM_DISABLE_TRUSTED_WDOG
+ /*
+ * start secure watchdog for BL2 and BL31.
+ * Note that UART download can take a longer time,
+ * so do not allow watchdog for UART download,
+ * as this boot source is not a standard modus operandi.
+ */
+ if (boot_source_get() != BOOT_SOURCE_UART)
+ sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+#endif
+
+#ifdef BCM_ELOG
+ /* Ensure logging is started out fresh in BL2. */
+ mmio_write_32(BCM_ELOG_BL2_BASE, 0);
+#endif
+ /*
+ * In BL2, since we have very limited space to store logs, we only
+ * save logs that are >= the WARNING level.
+ */
+ bcm_elog_init((void *)BCM_ELOG_BL2_BASE, BCM_ELOG_BL2_SIZE,
+ LOG_LEVEL_WARNING);
+
+ dump_persistent_regs();
+
+ /* Read CRMU mailbox 0 */
+ NOTICE("RESET (reported by CRMU): 0x%x\n",
+ mmio_read_32(CRMU_READ_MAIL_BOX0));
+
+ /*
+ * All non-boot-source PADs are in forced input-mode at
+ * reset so clear the force on non-boot-source PADs using
+ * CDRU register.
+ */
+ mmio_clrbits_32((uintptr_t)CDRU_CHIP_IO_PAD_CONTROL,
+ (1 << CDRU_CHIP_IO_PAD_CONTROL__CDRU_IOMUX_FORCE_PAD_IN_R));
+
+#if DRIVER_OCOTP_ENABLE
+ bcm_otpc_init(&otp_stingray_map);
+#endif
+
+ set_swreg_based_on_otp();
+
+#if IHOST_PLL_FREQ != 0
+ bcm_set_ihost_pll_freq(0x0, IHOST_PLL_FREQ);
+#endif
+
+#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
+ /* The erasable unit of the eMMC is the "Erase Group";
+ * Erase group is measured in write blocks which are the
+ * basic writable units of the Device.
+ * The size of the Erase Group is a Device specific parameter
+ */
+ emmc_erase(EMMC_ERASE_START_BLOCK, EMMC_ERASE_BLOCK_COUNT,
+ EMMC_ERASE_PARTITION);
+#endif
+
+ bcm_board_detect();
+#ifdef DRIVER_EMMC_ENABLE
+ /* Initialize the card, if it is not */
+ if (bcm_emmc_init(true) == 0)
+ WARN("eMMC Card Initialization Failed!!!\n");
+#endif
+
+#if BL2_TEST_I2C
+ i2c_test();
+#endif
+
+#ifdef USE_DDR
+ ddr_initialize(&ddr_info);
+
+ ddr_secure_region_config(SECURE_DDR_BASE_ADDRESS,
+ SECURE_DDR_END_ADDRESS);
+#ifdef NITRO_SECURE_ACCESS
+ ddr_secure_region_config(DDR_NITRO_SECURE_REGION_START,
+ DDR_NITRO_SECURE_REGION_END);
+#endif
+#else
+ ext_sram_init();
+#endif
+
+#if BL2_TEST_MEM
+ ddr_test();
+#endif
+
+#ifdef USE_NAND
+ brcm_stingray_nand_init();
+#endif
+
+#if defined(USE_PAXB) || defined(USE_PAXC) || defined(USE_SATA)
+ brcm_stingray_pcie_reset();
+#endif
+
+#ifdef USE_PAXC
+ if (boot_source_get() != BOOT_SOURCE_QSPI)
+ brcm_stingray_chimp_check_and_fastboot();
+#endif
+
+#if ((!CLEAN_DDR || MMU_DISABLED))
+ /*
+ * Now DDR has been initialized. We want to copy all the logs in SRAM
+ * into DDR so we will have much more space to store the logs in the
+ * next boot stage
+ */
+ bcm_elog_copy_log((void *)BCM_ELOG_BL31_BASE,
+ MIN(BCM_ELOG_BL2_SIZE, BCM_ELOG_BL31_SIZE)
+ );
+
+ /*
+ * We are not yet at the end of BL2, but we can stop log here so we do
+ * not need to add 'bcm_elog_exit' to the standard BL2 code. The
+ * benefit of capturing BL2 logs after this is very minimal in a
+ * production system
+ * NOTE: BL2 logging must be exited before going forward to setup
+ * page tables
+ */
+ bcm_elog_exit();
+#endif
+}
diff --git a/plat/brcm/board/stingray/src/bl31_setup.c b/plat/brcm/board/stingray/src/bl31_setup.c
new file mode 100644
index 000000000..a2a274dcd
--- /dev/null
+++ b/plat/brcm/board/stingray/src/bl31_setup.c
@@ -0,0 +1,1068 @@
+/*
+ * Copyright (c) 2015 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <cortex_a72.h>
+#include <drivers/arm/sp805.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <plat/common/common_def.h>
+#include <plat/common/platform.h>
+
+#include <bl33_info.h>
+#include <chimp.h>
+#include <cmn_plat_util.h>
+#include <dmu.h>
+#include <fsx.h>
+#include <iommu.h>
+#include <ncsi.h>
+#include <paxb.h>
+#include <paxc.h>
+#include <platform_def.h>
+#include <sdio.h>
+#include <sr_utils.h>
+#include <timer_sync.h>
+
+/*******************************************************************************
+ * Perform any BL3-1 platform setup common to ARM standard platforms
+ ******************************************************************************/
+
+static void brcm_stingray_gain_qspi_control(void)
+{
+ if (boot_source_get() != BOOT_SOURCE_QSPI) {
+ if (bcm_chimp_is_nic_mode() &&
+ (!bcm_chimp_handshake_done())) {
+ /*
+ * Last chance to wait for ChiMP firmware to report
+ * "I am done" before grabbing the QSPI
+ */
+ WARN("ChiMP still not booted\n");
+#ifndef CHIMP_ALWAYS_NEEDS_QSPI
+ WARN("ChiMP is given the last chance to boot (%d s)\n",
+ CHIMP_HANDSHAKE_TIMEOUT_MS / 1000);
+
+ if (!bcm_chimp_wait_handshake()) {
+ ERROR("ChiMP failed to boot\n");
+ } else {
+ INFO("ChiMP booted successfully\n");
+ }
+#endif
+ }
+
+#ifndef CHIMP_ALWAYS_NEEDS_QSPI
+ INFO("AP grabs QSPI\n");
+ /*
+ * For QSPI boot sbl/bl1 has already taken care.
+ * For other boot sources QSPI needs to be muxed to
+ * AP for exclusive use
+ */
+ brcm_stingray_set_qspi_mux(1);
+ INFO("AP (bl31) gained control over QSPI\n");
+#endif
+ }
+}
+
+static void brcm_stingray_dma_pl330_init(void)
+{
+ unsigned int val;
+
+ VERBOSE("dma pl330 init start\n");
+
+ /* Set DMAC boot_manager_ns = 0x1 */
+ VERBOSE(" - configure boot security state\n");
+ mmio_setbits_32(DMAC_M0_IDM_IO_CONTROL_DIRECT, BOOT_MANAGER_NS);
+ /* Set boot_peripheral_ns[n:0] = 0xffffffff */
+ mmio_write_32(ICFG_DMAC_CONFIG_2, BOOT_PERIPHERAL_NS);
+ /* Set boot_irq_ns[n:0] = 0x0000ffff */
+ mmio_write_32(ICFG_DMAC_CONFIG_3, BOOT_IRQ_NS);
+
+ /* Set DMAC stream_id */
+ VERBOSE(" - configure stream_id = 0x6000\n");
+ val = (DMAC_STREAM_ID << DMAC_SID_SHIFT);
+ mmio_write_32(ICFG_DMAC_SID_ARADDR_CONTROL, val);
+ mmio_write_32(ICFG_DMAC_SID_AWADDR_CONTROL, val);
+
+ /* Reset DMAC */
+ VERBOSE(" - reset dma pl330\n");
+
+ mmio_setbits_32(DMAC_M0_IDM_RESET_CONTROL, 0x1);
+ udelay(500);
+
+ mmio_clrbits_32(DMAC_M0_IDM_RESET_CONTROL, 0x1);
+ udelay(500);
+
+ INFO("dma pl330 init done\n");
+}
+
+static void brcm_stingray_spi_pl022_init(uintptr_t idm_reset_control)
+{
+ VERBOSE("spi pl022 init start\n");
+
+ /* Reset APB SPI bridge */
+ VERBOSE(" - reset apb spi bridge\n");
+ mmio_setbits_32(idm_reset_control, 0x1);
+ udelay(500);
+
+ mmio_clrbits_32(idm_reset_control, 0x1);
+ udelay(500);
+
+ INFO("spi pl022 init done\n");
+}
+
+#define CDRU_SATA_RESET_N \
+ BIT(CDRU_MISC_RESET_CONTROL__CDRU_SATA_RESET_N_R)
+#define CDRU_MISC_CLK_SATA \
+ BIT(CDRU_MISC_CLK_ENABLE_CONTROL__CDRU_SATA_CLK_EN_R)
+#define CCN_CONFIG_CLK_ENABLE (1 << 2)
+#define MMU_CONFIG_CLK_ENABLE (0x3F << 16)
+
+#define SATA_SATA_TOP_CTRL_BUS_CTRL (SATA_BASE + 0x2044)
+#define DMA_BIT_CTRL_MASK 0x003
+#define DMA_DESCR_ENDIAN_CTRL (DMA_BIT_CTRL_MASK << 0x002)
+#define DMA_DATA_ENDIAN_CTRL (DMA_BIT_CTRL_MASK << 0x004)
+
+#define SATA_PORT_SATA3_PCB_REG8 (SATA_BASE + 0x2320)
+#define SATA_PORT_SATA3_PCB_REG11 (SATA_BASE + 0x232c)
+#define SATA_PORT_SATA3_PCB_BLOCK_ADDR (SATA_BASE + 0x233c)
+
+#define SATA3_AFE_TXRX_ACTRL 0x1d0
+/* TXDriver swing setting is 800mV */
+#define DFS_SWINGNOPE_VALUE (0x0 << 6)
+#define DFS_SWINGNOPE_MASK (0x3 << 6)
+
+#define DFS_SWINGPE_VALUE (0x1 << 4)
+#define DFS_SWINGPE_MASK (0x3 << 4)
+
+#define DFS_INJSTRENGTH_VALUE (0x0 << 4)
+#define DFS_INJSTRENGTH_MASK (0x3 << 4)
+
+#define DFS_INJEN (0x1 << 3)
+
+#define SATA_CORE_MEM_CTRL (SATA_BASE + 0x3a08)
+#define SATA_CORE_MEM_CTRL_ISO BIT(0)
+#define SATA_CORE_MEM_CTRL_ARRPOWEROKIN BIT(1)
+#define SATA_CORE_MEM_CTRL_ARRPOWERONIN BIT(2)
+#define SATA_CORE_MEM_CTRL_POWEROKIN BIT(3)
+#define SATA_CORE_MEM_CTRL_POWERONIN BIT(4)
+
+#define SATA0_IDM_RESET_CONTROL (SATA_BASE + 0x500800)
+#define SATA_APBT0_IDM_IO_CONTROL_DIRECT (SATA_BASE + 0x51a408)
+#define IO_CONTROL_DIRECT_CLK_ENABLE BIT(0)
+#define SATA_APBT0_IDM_RESET_CONTROL (SATA_BASE + 0x51a800)
+#define IDM_RESET_CONTROL_RESET BIT(0)
+
+#define NIC400_SATA_NOC_SECURITY1 0x6830000c
+#define SATA_NOC_SECURITY1_FIELD 0xf
+#define NIC400_SATA_NOC_SECURITY2 0x68300010
+#define SATA_NOC_SECURITY2_FIELD 0xf
+#define NIC400_SATA_NOC_SECURITY3 0x68300014
+#define SATA_NOC_SECURITY3_FIELD 0x1
+#define NIC400_SATA_NOC_SECURITY4 0x68300018
+#define SATA_NOC_SECURITY4_FIELD 0x1
+#define NIC400_SATA_NOC_SECURITY5 0x6830001c
+#define SATA_NOC_SECURITY5_FIELD 0xf
+#define NIC400_SATA_NOC_SECURITY6 0x68300020
+#define SATA_NOC_SECURITY6_FIELD 0x1
+#define NIC400_SATA_NOC_SECURITY7 0x68300024
+#define SATA_NOC_SECURITY7_FIELD 0xf
+#define NIC400_SATA_NOC_SECURITY8 0x68300028
+#define SATA_NOC_SECURITY8_FIELD 0xf
+#define NIC400_SATA_NOC_SECURITY9 0x6830002c
+#define SATA_NOC_SECURITY9_FIELD 0x1
+
+#define SATA_APBT_IDM_PORT_REG(port, reg) \
+ (((port/4) << 12) + reg)
+
+#define SATA_IDM_PORT_REG(port, reg) ((port << 12) + reg)
+
+#define SATA_PORT_REG(port, reg) \
+ (((port%4) << 16) + ((port/4) << 20) + reg)
+
+#define MAX_SATA_PORTS 8
+#define USE_SATA_PORTS 8
+
+#ifdef USE_SATA
+static const uint8_t sr_b0_sata_port[MAX_SATA_PORTS] = {
+ 0, 1, 2, 3, 4, 5, 6, 7
+};
+
+static uint32_t brcm_stingray_get_sata_port(unsigned int port)
+{
+ return sr_b0_sata_port[port];
+}
+
+static void brcm_stingray_sata_init(void)
+{
+ unsigned int port = 0;
+ uint32_t sata_port;
+
+ mmio_setbits_32(CDRU_MISC_CLK_ENABLE_CONTROL,
+ CDRU_MISC_CLK_SATA);
+
+ mmio_clrbits_32(CDRU_MISC_RESET_CONTROL, CDRU_SATA_RESET_N);
+ mmio_setbits_32(CDRU_MISC_RESET_CONTROL, CDRU_SATA_RESET_N);
+
+ for (port = 0; port < USE_SATA_PORTS; port++) {
+
+ sata_port = brcm_stingray_get_sata_port(port);
+ mmio_write_32(SATA_APBT_IDM_PORT_REG(sata_port,
+ SATA_APBT0_IDM_RESET_CONTROL),
+ 0x0);
+ mmio_setbits_32(SATA_APBT_IDM_PORT_REG(sata_port,
+ SATA_APBT0_IDM_IO_CONTROL_DIRECT),
+ IO_CONTROL_DIRECT_CLK_ENABLE);
+ mmio_write_32(SATA_IDM_PORT_REG(sata_port,
+ SATA0_IDM_RESET_CONTROL),
+ 0x0);
+
+ mmio_setbits_32(SATA_PORT_REG(sata_port, SATA_CORE_MEM_CTRL),
+ SATA_CORE_MEM_CTRL_ARRPOWERONIN);
+ mmio_setbits_32(SATA_PORT_REG(sata_port, SATA_CORE_MEM_CTRL),
+ SATA_CORE_MEM_CTRL_ARRPOWEROKIN);
+ mmio_setbits_32(SATA_PORT_REG(sata_port, SATA_CORE_MEM_CTRL),
+ SATA_CORE_MEM_CTRL_POWERONIN);
+ mmio_setbits_32(SATA_PORT_REG(sata_port, SATA_CORE_MEM_CTRL),
+ SATA_CORE_MEM_CTRL_POWEROKIN);
+ mmio_clrbits_32(SATA_PORT_REG(sata_port, SATA_CORE_MEM_CTRL),
+ SATA_CORE_MEM_CTRL_ISO);
+
+ mmio_clrbits_32(SATA_PORT_REG(sata_port,
+ SATA_SATA_TOP_CTRL_BUS_CTRL),
+ (DMA_DESCR_ENDIAN_CTRL | DMA_DATA_ENDIAN_CTRL));
+ }
+
+ mmio_setbits_32(NIC400_SATA_NOC_SECURITY1, SATA_NOC_SECURITY1_FIELD);
+ mmio_setbits_32(NIC400_SATA_NOC_SECURITY2, SATA_NOC_SECURITY2_FIELD);
+ mmio_setbits_32(NIC400_SATA_NOC_SECURITY3, SATA_NOC_SECURITY3_FIELD);
+ mmio_setbits_32(NIC400_SATA_NOC_SECURITY4, SATA_NOC_SECURITY4_FIELD);
+ mmio_setbits_32(NIC400_SATA_NOC_SECURITY5, SATA_NOC_SECURITY5_FIELD);
+ mmio_setbits_32(NIC400_SATA_NOC_SECURITY6, SATA_NOC_SECURITY6_FIELD);
+ mmio_setbits_32(NIC400_SATA_NOC_SECURITY7, SATA_NOC_SECURITY7_FIELD);
+ mmio_setbits_32(NIC400_SATA_NOC_SECURITY8, SATA_NOC_SECURITY8_FIELD);
+ mmio_setbits_32(NIC400_SATA_NOC_SECURITY9, SATA_NOC_SECURITY9_FIELD);
+
+ INFO("sata init done\n");
+}
+#else
+static void poweroff_sata_pll(void)
+{
+ /*
+ * SATA subsystem is clocked by LCPLL0 which is enabled by
+ * default by bootrom. Poweroff the PLL if SATA is not used
+ */
+
+ /* enable isolation */
+ mmio_setbits_32(CRMU_AON_CTRL1,
+ BIT(CRMU_AON_CTRL1__LCPLL0_ISO_IN));
+
+ /* Power off the SATA PLL/LDO */
+ mmio_clrbits_32(CRMU_AON_CTRL1,
+ (BIT(CRMU_AON_CTRL1__LCPLL0_PWRON_LDO) |
+ BIT(CRMU_AON_CTRL1__LCPLL0_PWR_ON)));
+}
+#endif
+
+#ifdef USE_AMAC
+#ifdef EMULATION_SETUP
+#define ICFG_AMAC_STRAP_CONFIG (HSLS_ICFG_REGS_BASE + 0xa5c)
+#define ICFG_AMAC_STRAP_DLL_BYPASS (1 << 2)
+#endif
+#define ICFG_AMAC_MAC_CTRL_REG (HSLS_ICFG_REGS_BASE + 0xa6c)
+#define ICFG_AMAC_MAC_FULL_DUPLEX (1 << 1)
+#define ICFG_AMAC_RGMII_PHY_CONFIG (HSLS_ICFG_REGS_BASE + 0xa60)
+#define ICFG_AMAC_SID_CONTROL (HSLS_ICFG_REGS_BASE + 0xb10)
+#define ICFG_AMAC_SID_SHIFT 5
+#define ICFG_AMAC_SID_AWADDR_OFFSET 0x0
+#define ICFG_AMAC_SID_ARADDR_OFFSET 0x4
+#define AMAC_RPHY_1000_DATARATE (1 << 20)
+#define AMAC_RPHY_FULL_DUPLEX (1 << 5)
+#define AMAC_RPHY_SPEED_OFFSET 2
+#define AMAC_RPHY_SPEED_MASK (7 << AMAC_RPHY_SPEED_OFFSET)
+#define AMAC_RPHY_1G_SPEED (2 << AMAC_RPHY_SPEED_OFFSET)
+#define ICFG_AMAC_MEM_PWR_CTRL (HSLS_ICFG_REGS_BASE + 0xa68)
+#define AMAC_ISO BIT(9)
+#define AMAC_STDBY BIT(8)
+#define AMAC_ARRPOWEROKIN BIT(7)
+#define AMAC_ARRPOWERONIN BIT(6)
+#define AMAC_POWEROKIN BIT(5)
+#define AMAC_POWERONIN BIT(4)
+
+#define AMAC_IDM0_IO_CONTROL_DIRECT (HSLS_IDM_REGS_BASE + 0x4408)
+#define AMAC_IDM0_ARCACHE_OFFSET 16
+#define AMAC_IDM0_AWCACHE_OFFSET 7
+#define AMAC_IDM0_ARCACHE_MASK (0xF << AMAC_IDM0_ARCACHE_OFFSET)
+#define AMAC_IDM0_AWCACHE_MASK (0xF << AMAC_IDM0_AWCACHE_OFFSET)
+/* ARCACHE - AWCACHE is 0xB7 for write-back no allocate */
+#define AMAC_IDM0_ARCACHE_VAL (0xb << AMAC_IDM0_ARCACHE_OFFSET)
+#define AMAC_IDM0_AWCACHE_VAL (0x7 << AMAC_IDM0_AWCACHE_OFFSET)
+
+static void brcm_stingray_amac_init(void)
+{
+ unsigned int val;
+ uintptr_t icfg_amac_sid = ICFG_AMAC_SID_CONTROL;
+
+ VERBOSE("amac init start\n");
+
+ val = SR_SID_VAL(0x3, 0x0, 0x4) << ICFG_AMAC_SID_SHIFT;
+ mmio_write_32(icfg_amac_sid + ICFG_AMAC_SID_AWADDR_OFFSET, val);
+ mmio_write_32(icfg_amac_sid + ICFG_AMAC_SID_ARADDR_OFFSET, val);
+
+ mmio_setbits_32(ICFG_AMAC_MEM_PWR_CTRL, AMAC_ARRPOWEROKIN);
+ mmio_setbits_32(ICFG_AMAC_MEM_PWR_CTRL, AMAC_ARRPOWERONIN);
+ mmio_setbits_32(ICFG_AMAC_MEM_PWR_CTRL, AMAC_POWEROKIN);
+ mmio_setbits_32(ICFG_AMAC_MEM_PWR_CTRL, AMAC_POWERONIN);
+ mmio_clrbits_32(ICFG_AMAC_MEM_PWR_CTRL, AMAC_ISO);
+ mmio_write_32(APBR_IDM_RESET_CONTROL, 0x0);
+ mmio_clrsetbits_32(ICFG_AMAC_RGMII_PHY_CONFIG, AMAC_RPHY_SPEED_MASK,
+ AMAC_RPHY_1G_SPEED); /*1 Gbps line rate*/
+ /* 1000 datarate set */
+ mmio_setbits_32(ICFG_AMAC_RGMII_PHY_CONFIG, AMAC_RPHY_1000_DATARATE);
+ /* full duplex */
+ mmio_setbits_32(ICFG_AMAC_RGMII_PHY_CONFIG, AMAC_RPHY_FULL_DUPLEX);
+#ifdef EMULATION_SETUP
+ /* DLL bypass */
+ mmio_setbits_32(ICFG_AMAC_STRAP_CONFIG, ICFG_AMAC_STRAP_DLL_BYPASS);
+#endif
+ /* serdes full duplex */
+ mmio_setbits_32(ICFG_AMAC_MAC_CTRL_REG, ICFG_AMAC_MAC_FULL_DUPLEX);
+ mmio_clrsetbits_32(AMAC_IDM0_IO_CONTROL_DIRECT, AMAC_IDM0_ARCACHE_MASK,
+ AMAC_IDM0_ARCACHE_VAL);
+ mmio_clrsetbits_32(AMAC_IDM0_IO_CONTROL_DIRECT, AMAC_IDM0_AWCACHE_MASK,
+ AMAC_IDM0_AWCACHE_VAL);
+ INFO("amac init done\n");
+}
+#endif /* USE_AMAC */
+
+static void brcm_stingray_pka_meminit(void)
+{
+ uintptr_t icfg_mem_ctrl = ICFG_PKA_MEM_PWR_CTRL;
+
+ VERBOSE("pka meminit start\n");
+
+ VERBOSE(" - arrpoweron\n");
+ mmio_setbits_32(icfg_mem_ctrl,
+ ICFG_PKA_MEM_PWR_CTRL__ARRPOWERONIN);
+ while (!(mmio_read_32(icfg_mem_ctrl) &
+ ICFG_PKA_MEM_PWR_CTRL__ARRPOWERONOUT))
+ ;
+
+ VERBOSE(" - arrpowerok\n");
+ mmio_setbits_32(icfg_mem_ctrl,
+ ICFG_PKA_MEM_PWR_CTRL__ARRPOWEROKIN);
+ while (!(mmio_read_32(icfg_mem_ctrl) &
+ ICFG_PKA_MEM_PWR_CTRL__ARRPOWEROKOUT))
+ ;
+
+ VERBOSE(" - poweron\n");
+ mmio_setbits_32(icfg_mem_ctrl,
+ ICFG_PKA_MEM_PWR_CTRL__POWERONIN);
+ while (!(mmio_read_32(icfg_mem_ctrl) &
+ ICFG_PKA_MEM_PWR_CTRL__POWERONOUT))
+ ;
+
+ VERBOSE(" - powerok\n");
+ mmio_setbits_32(icfg_mem_ctrl,
+ ICFG_PKA_MEM_PWR_CTRL__POWEROKIN);
+ while (!(mmio_read_32(icfg_mem_ctrl) &
+ ICFG_PKA_MEM_PWR_CTRL__POWEROKOUT))
+ ;
+
+ /* Wait sometime */
+ mdelay(1);
+
+ VERBOSE(" - remove isolation\n");
+ mmio_clrbits_32(icfg_mem_ctrl, ICFG_PKA_MEM_PWR_CTRL__ISO);
+
+ INFO("pka meminit done\n");
+}
+
+static void brcm_stingray_smmu_init(void)
+{
+ unsigned int val;
+ uintptr_t smmu_base = SMMU_BASE;
+
+ VERBOSE("smmu init start\n");
+
+ /* Configure SCR0 */
+ VERBOSE(" - configure scr0\n");
+ val = mmio_read_32(smmu_base + 0x0);
+ val |= (0x1 << 12);
+ mmio_write_32(smmu_base + 0x0, val);
+
+ /* Reserve context banks for secure masters */
+ arm_smmu_reserve_secure_cntxt();
+
+ /* Print configuration */
+ VERBOSE(" - scr0=0x%x scr1=0x%x scr2=0x%x\n",
+ mmio_read_32(smmu_base + 0x0),
+ mmio_read_32(smmu_base + 0x4),
+ mmio_read_32(smmu_base + 0x8));
+
+ VERBOSE(" - idr0=0x%x idr1=0x%x idr2=0x%x\n",
+ mmio_read_32(smmu_base + 0x20),
+ mmio_read_32(smmu_base + 0x24),
+ mmio_read_32(smmu_base + 0x28));
+
+ VERBOSE(" - idr3=0x%x idr4=0x%x idr5=0x%x\n",
+ mmio_read_32(smmu_base + 0x2c),
+ mmio_read_32(smmu_base + 0x30),
+ mmio_read_32(smmu_base + 0x34));
+
+ VERBOSE(" - idr6=0x%x idr7=0x%x\n",
+ mmio_read_32(smmu_base + 0x38),
+ mmio_read_32(smmu_base + 0x3c));
+
+ INFO("smmu init done\n");
+}
+
+static void brcm_stingray_dma_pl330_meminit(void)
+{
+ uintptr_t icfg_mem_ctrl = ICFG_DMAC_MEM_PWR_CTRL;
+
+ VERBOSE("dmac meminit start\n");
+
+ VERBOSE(" - arrpoweron\n");
+ mmio_setbits_32(icfg_mem_ctrl,
+ ICFG_DMAC_MEM_PWR_CTRL__ARRPOWERONIN);
+ while (!(mmio_read_32(icfg_mem_ctrl) &
+ ICFG_DMAC_MEM_PWR_CTRL__ARRPOWERONOUT))
+ ;
+
+ VERBOSE(" - arrpowerok\n");
+ mmio_setbits_32(icfg_mem_ctrl,
+ ICFG_DMAC_MEM_PWR_CTRL__ARRPOWEROKIN);
+ while (!(mmio_read_32(icfg_mem_ctrl) &
+ ICFG_DMAC_MEM_PWR_CTRL__ARRPOWEROKOUT))
+ ;
+
+ VERBOSE(" - poweron\n");
+ mmio_setbits_32(icfg_mem_ctrl,
+ ICFG_DMAC_MEM_PWR_CTRL__POWERONIN);
+ while (!(mmio_read_32(icfg_mem_ctrl) &
+ ICFG_DMAC_MEM_PWR_CTRL__POWERONOUT))
+ ;
+
+ VERBOSE(" - powerok\n");
+ mmio_setbits_32(icfg_mem_ctrl,
+ ICFG_DMAC_MEM_PWR_CTRL__POWEROKIN);
+ while (!(mmio_read_32(icfg_mem_ctrl) &
+ ICFG_DMAC_MEM_PWR_CTRL__POWEROKOUT))
+ ;
+
+ /* Wait sometime */
+ mdelay(1);
+
+ VERBOSE(" - remove isolation\n");
+ mmio_clrbits_32(icfg_mem_ctrl, ICFG_DMAC_MEM_PWR_CTRL__ISO);
+
+ INFO("dmac meminit done\n");
+}
+
+/* program the crmu access ranges for allowing non sec access*/
+static void brcm_stingray_crmu_access_init(void)
+{
+ /* Enable 0x6641c001 - 0x6641c701 for non secure access */
+ mmio_write_32(CRMU_CORE_ADDR_RANGE0_LOW, 0x6641c001);
+ mmio_write_32(CRMU_CORE_ADDR_RANGE0_LOW + 0x4, 0x6641c701);
+
+ /* Enable 0x6641d001 - 0x66424b01 for non secure access */
+ mmio_write_32(CRMU_CORE_ADDR_RANGE1_LOW, 0x6641d001);
+ mmio_write_32(CRMU_CORE_ADDR_RANGE1_LOW + 0x4, 0x66424b01);
+
+ /* Enable 0x66425001 - 0x66425f01 for non secure access */
+ mmio_write_32(CRMU_CORE_ADDR_RANGE2_LOW, 0x66425001);
+ mmio_write_32(CRMU_CORE_ADDR_RANGE2_LOW + 0x4, 0x66425f01);
+
+ INFO("crmu access init done\n");
+}
+
+static void brcm_stingray_scr_init(void)
+{
+ unsigned int val;
+ uintptr_t scr_base = SCR_BASE;
+ unsigned int clr_mask = SCR_AXCACHE_CONFIG_MASK;
+ unsigned int set_mask = SCR_TBUX_AXCACHE_CONFIG;
+
+ VERBOSE("scr init start\n");
+
+ /* awdomain=0x1 and ardomain=0x1 */
+ mmio_clrsetbits_32(scr_base + 0x0, clr_mask, set_mask);
+ val = mmio_read_32(scr_base + 0x0);
+ VERBOSE(" - set tbu0_config=0x%x\n", val);
+
+ /* awdomain=0x1 and ardomain=0x1 */
+ mmio_clrsetbits_32(scr_base + 0x4, clr_mask, set_mask);
+ val = mmio_read_32(scr_base + 0x4);
+ VERBOSE(" - set tbu1_config=0x%x\n", val);
+
+ /* awdomain=0x1 and ardomain=0x1 */
+ mmio_clrsetbits_32(scr_base + 0x8, clr_mask, set_mask);
+ val = mmio_read_32(scr_base + 0x8);
+ VERBOSE(" - set tbu2_config=0x%x\n", val);
+
+ /* awdomain=0x1 and ardomain=0x1 */
+ mmio_clrsetbits_32(scr_base + 0xc, clr_mask, set_mask);
+ val = mmio_read_32(scr_base + 0xc);
+ VERBOSE(" - set tbu3_config=0x%x\n", val);
+
+ /* awdomain=0x1 and ardomain=0x1 */
+ mmio_clrsetbits_32(scr_base + 0x10, clr_mask, set_mask);
+ val = mmio_read_32(scr_base + 0x10);
+ VERBOSE(" - set tbu4_config=0x%x\n", val);
+
+ /* awdomain=0x0 and ardomain=0x0 */
+ mmio_clrbits_32(scr_base + 0x14, clr_mask);
+ val = mmio_read_32(scr_base + 0x14);
+ VERBOSE(" - set gic_config=0x%x\n", val);
+
+ INFO("scr init done\n");
+}
+
+static void brcm_stingray_hsls_tzpcprot_init(void)
+{
+ unsigned int val;
+ uintptr_t tzpcdecprot_base = HSLS_TZPC_BASE;
+
+ VERBOSE("hsls tzpcprot init start\n");
+
+ /* Treat third-party masters as non-secured */
+ val = 0;
+ val |= BIT(6); /* SDIO1 */
+ val |= BIT(5); /* SDIO0 */
+ val |= BIT(0); /* AMAC */
+ mmio_write_32(tzpcdecprot_base + 0x810, val);
+
+ /* Print TZPC decode status registers */
+ VERBOSE(" - tzpcdecprot0=0x%x\n",
+ mmio_read_32(tzpcdecprot_base + 0x800));
+
+ VERBOSE(" - tzpcdecprot1=0x%x\n",
+ mmio_read_32(tzpcdecprot_base + 0x80c));
+
+ INFO("hsls tzpcprot init done\n");
+}
+
+#ifdef USE_I2S
+#define ICFG_AUDIO_POWER_CTRL (HSLS_ICFG_REGS_BASE + 0xaa8)
+#define ICFG_AUDIO_POWER_CTRL__POWERONIN BIT(0)
+#define ICFG_AUDIO_POWER_CTRL__POWEROKIN BIT(1)
+#define ICFG_AUDIO_POWER_CTRL__ARRPOWERONIN BIT(2)
+#define ICFG_AUDIO_POWER_CTRL__ARRPOWEROKIN BIT(3)
+#define ICFG_AUDIO_POWER_CTRL__POWERONOUT BIT(4)
+#define ICFG_AUDIO_POWER_CTRL__POWEROKOUT BIT(5)
+#define ICFG_AUDIO_POWER_CTRL__ARRPOWERONOUT BIT(6)
+#define ICFG_AUDIO_POWER_CTRL__ARRPOWEROKOUT BIT(7)
+#define ICFG_AUDIO_POWER_CTRL__ISO BIT(8)
+#define ICFG_AUDIO_SID_CONTROL (HSLS_ICFG_REGS_BASE + 0xaf8)
+#define ICFG_AUDIO_SID_SHIFT 5
+#define ICFG_AUDIO_SID_AWADDR_OFFSET 0x0
+#define ICFG_AUDIO_SID_ARADDR_OFFSET 0x4
+
+#define I2S_RESET_CONTROL (HSLS_IDM_REGS_BASE + 0x1800)
+#define I2S_IDM_IO_CONTROL (HSLS_IDM_REGS_BASE + 0x1408)
+#define IO_CONTROL_CLK_ENABLE BIT(0)
+#define I2S_IDM0_ARCACHE_OFFSET 16
+#define I2S_IDM0_AWCACHE_OFFSET 20
+#define I2S_IDM0_ARCACHE_MASK (0xF << I2S_IDM0_ARCACHE_OFFSET)
+#define I2S_IDM0_AWCACHE_MASK (0xF << I2S_IDM0_AWCACHE_OFFSET)
+/* ARCACHE - AWCACHE is 0x22 Normal Non-cacheable Non-bufferable. */
+#define I2S_IDM0_ARCACHE_VAL (0x2 << I2S_IDM0_ARCACHE_OFFSET)
+#define I2S_IDM0_AWCACHE_VAL (0x2 << I2S_IDM0_AWCACHE_OFFSET)
+
+static void brcm_stingray_audio_init(void)
+{
+ unsigned int val;
+ uintptr_t icfg_mem_ctrl = ICFG_AUDIO_POWER_CTRL;
+ uintptr_t icfg_audio_sid = ICFG_AUDIO_SID_CONTROL;
+
+ mmio_write_32(I2S_RESET_CONTROL, 0x0);
+
+ mmio_clrsetbits_32(I2S_IDM_IO_CONTROL, I2S_IDM0_ARCACHE_MASK,
+ I2S_IDM0_ARCACHE_VAL);
+
+ mmio_clrsetbits_32(I2S_IDM_IO_CONTROL, I2S_IDM0_AWCACHE_MASK,
+ I2S_IDM0_AWCACHE_VAL);
+
+ mmio_setbits_32(I2S_IDM_IO_CONTROL, IO_CONTROL_CLK_ENABLE);
+
+ VERBOSE("audio meminit start\n");
+
+ VERBOSE(" - configure stream_id = 0x6001\n");
+ val = SR_SID_VAL(0x3, 0x0, 0x1) << ICFG_AUDIO_SID_SHIFT;
+ mmio_write_32(icfg_audio_sid + ICFG_AUDIO_SID_AWADDR_OFFSET, val);
+ mmio_write_32(icfg_audio_sid + ICFG_AUDIO_SID_ARADDR_OFFSET, val);
+
+ VERBOSE(" - arrpoweron\n");
+ mmio_setbits_32(icfg_mem_ctrl,
+ ICFG_AUDIO_POWER_CTRL__ARRPOWERONIN);
+ while (!(mmio_read_32(icfg_mem_ctrl) &
+ ICFG_AUDIO_POWER_CTRL__ARRPOWERONOUT))
+ ;
+
+ VERBOSE(" - arrpowerok\n");
+ mmio_setbits_32(icfg_mem_ctrl,
+ ICFG_AUDIO_POWER_CTRL__ARRPOWEROKIN);
+ while (!(mmio_read_32(icfg_mem_ctrl) &
+ ICFG_AUDIO_POWER_CTRL__ARRPOWEROKOUT))
+ ;
+
+ VERBOSE(" - poweron\n");
+ mmio_setbits_32(icfg_mem_ctrl,
+ ICFG_AUDIO_POWER_CTRL__POWERONIN);
+ while (!(mmio_read_32(icfg_mem_ctrl) &
+ ICFG_AUDIO_POWER_CTRL__POWERONOUT))
+ ;
+
+ VERBOSE(" - powerok\n");
+ mmio_setbits_32(icfg_mem_ctrl,
+ ICFG_AUDIO_POWER_CTRL__POWEROKIN);
+ while (!(mmio_read_32(icfg_mem_ctrl) &
+ ICFG_AUDIO_POWER_CTRL__POWEROKOUT))
+ ;
+
+ /* Wait sometime */
+ mdelay(1);
+
+ VERBOSE(" - remove isolation\n");
+ mmio_clrbits_32(icfg_mem_ctrl, ICFG_AUDIO_POWER_CTRL__ISO);
+
+ INFO("audio meminit done\n");
+}
+#endif /* USE_I2S */
+
+/*
+ * These defines do not match the regfile but they are renamed in a way such
+ * that they are much more readible
+ */
+
+#define SCR_GPV_SMMU_NS (SCR_GPV_BASE + 0x28)
+#define SCR_GPV_GIC500_NS (SCR_GPV_BASE + 0x34)
+#define HSLS_GPV_NOR_S0_NS (HSLS_GPV_BASE + 0x14)
+#define HSLS_GPV_IDM1_NS (HSLS_GPV_BASE + 0x18)
+#define HSLS_GPV_IDM2_NS (HSLS_GPV_BASE + 0x1c)
+#define HSLS_SDIO0_SLAVE_NS (HSLS_GPV_BASE + 0x20)
+#define HSLS_SDIO1_SLAVE_NS (HSLS_GPV_BASE + 0x24)
+#define HSLS_GPV_APBY_NS (HSLS_GPV_BASE + 0x2c)
+#define HSLS_GPV_APBZ_NS (HSLS_GPV_BASE + 0x30)
+#define HSLS_GPV_APBX_NS (HSLS_GPV_BASE + 0x34)
+#define HSLS_GPV_APBS_NS (HSLS_GPV_BASE + 0x38)
+#define HSLS_GPV_QSPI_S0_NS (HSLS_GPV_BASE + 0x68)
+#define HSLS_GPV_APBR_NS (HSLS_GPV_BASE + 0x6c)
+#define FS4_CRYPTO_GPV_RM_SLAVE_NS (FS4_CRYPTO_GPV_BASE + 0x8)
+#define FS4_CRYPTO_GPV_APB_SWITCH_NS (FS4_CRYPTO_GPV_BASE + 0xc)
+#define FS4_RAID_GPV_RM_SLAVE_NS (FS4_RAID_GPV_BASE + 0x8)
+#define FS4_RAID_GPV_APB_SWITCH_NS (FS4_RAID_GPV_BASE + 0xc)
+#define FS4_CRYPTO_IDM_NS (NIC400_FS_NOC_ROOT + 0x1c)
+#define FS4_RAID_IDM_NS (NIC400_FS_NOC_ROOT + 0x28)
+
+#define FS4_CRYPTO_RING_COUNT 32
+#define FS4_CRYPTO_DME_COUNT 10
+#define FS4_CRYPTO_AE_COUNT 10
+#define FS4_CRYPTO_START_STREAM_ID 0x4000
+#define FS4_CRYPTO_MSI_DEVICE_ID 0x4100
+
+#define FS4_RAID_RING_COUNT 32
+#define FS4_RAID_DME_COUNT 8
+#define FS4_RAID_AE_COUNT 8
+#define FS4_RAID_START_STREAM_ID 0x4200
+#define FS4_RAID_MSI_DEVICE_ID 0x4300
+
+#define FS6_PKI_AXI_SLAVE_NS \
+ (NIC400_FS_NOC_ROOT + NIC400_FS_NOC_SECURITY2_OFFSET)
+
+#define FS6_PKI_AE_DME_APB_NS \
+ (NIC400_FS_NOC_ROOT + NIC400_FS_NOC_SECURITY7_OFFSET)
+#define FS6_PKI_IDM_IO_CONTROL_DIRECT 0x0
+#define FS6_PKI_IDM_RESET_CONTROL 0x0
+#define FS6_PKI_RING_COUNT 32
+#define FS6_PKI_DME_COUNT 1
+#define FS6_PKI_AE_COUNT 4
+#define FS6_PKI_START_STREAM_ID 0x4000
+#define FS6_PKI_MSI_DEVICE_ID 0x4100
+
+static void brcm_stingray_security_init(void)
+{
+ unsigned int val;
+
+ val = mmio_read_32(SCR_GPV_SMMU_NS);
+ val |= BIT(0); /* SMMU NS = 1 */
+ mmio_write_32(SCR_GPV_SMMU_NS, val);
+
+ val = mmio_read_32(SCR_GPV_GIC500_NS);
+ val |= BIT(0); /* GIC-500 NS = 1 */
+ mmio_write_32(SCR_GPV_GIC500_NS, val);
+
+ val = mmio_read_32(HSLS_GPV_NOR_S0_NS);
+ val |= BIT(0); /* NOR SLAVE NS = 1 */
+ mmio_write_32(HSLS_GPV_NOR_S0_NS, val);
+
+ val = mmio_read_32(HSLS_GPV_IDM1_NS);
+ val |= BIT(0); /* DMA IDM NS = 1 */
+ val |= BIT(1); /* I2S IDM NS = 1 */
+ val |= BIT(2); /* AMAC IDM NS = 1 */
+ val |= BIT(3); /* SDIO0 IDM NS = 1 */
+ val |= BIT(4); /* SDIO1 IDM NS = 1 */
+ val |= BIT(5); /* DS_3 IDM NS = 1 */
+ mmio_write_32(HSLS_GPV_IDM1_NS, val);
+
+ val = mmio_read_32(HSLS_GPV_IDM2_NS);
+ val |= BIT(2); /* QSPI IDM NS = 1 */
+ val |= BIT(1); /* NOR IDM NS = 1 */
+ val |= BIT(0); /* NAND IDM NS = 1 */
+ mmio_write_32(HSLS_GPV_IDM2_NS, val);
+
+ val = mmio_read_32(HSLS_GPV_APBY_NS);
+ val |= BIT(10); /* I2S NS = 1 */
+ val |= BIT(4); /* IOPAD NS = 1 */
+ val |= 0xf; /* UARTx NS = 1 */
+ mmio_write_32(HSLS_GPV_APBY_NS, val);
+
+ val = mmio_read_32(HSLS_GPV_APBZ_NS);
+ val |= BIT(2); /* RNG NS = 1 */
+ mmio_write_32(HSLS_GPV_APBZ_NS, val);
+
+ val = mmio_read_32(HSLS_GPV_APBS_NS);
+ val |= 0x3; /* SPIx NS = 1 */
+ mmio_write_32(HSLS_GPV_APBS_NS, val);
+
+ val = mmio_read_32(HSLS_GPV_APBR_NS);
+ val |= BIT(7); /* QSPI APB NS = 1 */
+ val |= BIT(6); /* NAND APB NS = 1 */
+ val |= BIT(5); /* NOR APB NS = 1 */
+ val |= BIT(4); /* AMAC APB NS = 1 */
+ val |= BIT(1); /* DMA S1 APB NS = 1 */
+ mmio_write_32(HSLS_GPV_APBR_NS, val);
+
+ val = mmio_read_32(HSLS_SDIO0_SLAVE_NS);
+ val |= BIT(0); /* SDIO0 NS = 1 */
+ mmio_write_32(HSLS_SDIO0_SLAVE_NS, val);
+
+ val = mmio_read_32(HSLS_SDIO1_SLAVE_NS);
+ val |= BIT(0); /* SDIO1 NS = 1 */
+ mmio_write_32(HSLS_SDIO1_SLAVE_NS, val);
+
+ val = mmio_read_32(HSLS_GPV_APBX_NS);
+ val |= BIT(14); /* SMBUS1 NS = 1 */
+ val |= BIT(13); /* GPIO NS = 1 */
+ val |= BIT(12); /* WDT NS = 1 */
+ val |= BIT(11); /* SMBUS0 NS = 1 */
+ val |= BIT(10); /* Timer7 NS = 1 */
+ val |= BIT(9); /* Timer6 NS = 1 */
+ val |= BIT(8); /* Timer5 NS = 1 */
+ val |= BIT(7); /* Timer4 NS = 1 */
+ val |= BIT(6); /* Timer3 NS = 1 */
+ val |= BIT(5); /* Timer2 NS = 1 */
+ val |= BIT(4); /* Timer1 NS = 1 */
+ val |= BIT(3); /* Timer0 NS = 1 */
+ val |= BIT(2); /* MDIO NS = 1 */
+ val |= BIT(1); /* PWM NS = 1 */
+ mmio_write_32(HSLS_GPV_APBX_NS, val);
+
+ val = mmio_read_32(HSLS_GPV_QSPI_S0_NS);
+ val |= BIT(0); /* QSPI NS = 1 */
+ mmio_write_32(HSLS_GPV_QSPI_S0_NS, val);
+
+#ifdef USE_FS4
+ val = 0x1; /* FS4 Crypto rm_slave */
+ mmio_write_32(FS4_CRYPTO_GPV_RM_SLAVE_NS, val);
+ val = 0x1; /* FS4 Crypto apb_switch */
+ mmio_write_32(FS4_CRYPTO_GPV_APB_SWITCH_NS, val);
+
+ val = 0x1; /* FS4 Raid rm_slave */
+ mmio_write_32(FS4_RAID_GPV_RM_SLAVE_NS, val);
+ val = 0x1; /* FS4 Raid apb_switch */
+ mmio_write_32(FS4_RAID_GPV_APB_SWITCH_NS, val);
+
+ val = 0x1; /* FS4 Crypto IDM */
+ mmio_write_32(FS4_CRYPTO_IDM_NS, val);
+ val = 0x1; /* FS4 RAID IDM */
+ mmio_write_32(FS4_RAID_IDM_NS, val);
+#endif
+
+#ifdef BL31_CCN_NONSECURE
+ /* Enable non-secure access to CCN registers */
+ mmio_write_32(OLY_MN_REGISTERS_NODE0_SECURE_ACCESS, 0x1);
+#endif
+
+#ifdef DDR_CTRL_PHY_NONSECURE
+ mmio_write_32(SCR_NOC_DDR_REGISTER_ACCESS, 0x1);
+#endif
+
+ paxc_mhb_ns_init();
+
+ /* unlock scr idm for non secure access */
+ mmio_write_32(SCR_NOC_SECURITY0, 0xffffffff);
+
+ INFO("security init done\r\n");
+}
+
+void brcm_gpio_pad_ns_init(void)
+{
+ /* configure all GPIO pads for non secure world access*/
+ mmio_write_32(GPIO_S_CNTRL_REG, 0xffffffff); /* 128-140 gpio pads */
+ mmio_write_32(GPIO_S_CNTRL_REG + 0x4, 0xffffffff); /* 96-127 gpio pad */
+ mmio_write_32(GPIO_S_CNTRL_REG + 0x8, 0xffffffff); /* 64-95 gpio pad */
+ mmio_write_32(GPIO_S_CNTRL_REG + 0xc, 0xffffffff); /* 32-63 gpio pad */
+ mmio_write_32(GPIO_S_CNTRL_REG + 0x10, 0xffffffff); /* 0-31 gpio pad */
+}
+
+#ifndef USE_DDR
+static void brcm_stingray_sram_ns_init(void)
+{
+ uintptr_t sram_root = TZC400_FS_SRAM_ROOT;
+ uintptr_t noc_root = NIC400_FS_NOC_ROOT;
+
+ mmio_write_32(sram_root + GATE_KEEPER_OFFSET, 1);
+ mmio_write_32(sram_root + REGION_ATTRIBUTES_0_OFFSET, 0xc0000000);
+ mmio_write_32(sram_root + REGION_ID_ACCESS_0_OFFSET, 0x00010001);
+ mmio_write_32(noc_root + NIC400_FS_NOC_SECURITY4_OFFSET, 0x1);
+ INFO(" stingray sram ns init done.\n");
+}
+#endif
+
+static void ccn_pre_init(void)
+{
+ /*
+ * Set WFC bit of RN-I nodes where FS4 is connected.
+ * This is required inorder to wait for read/write requests
+ * completion acknowledgment. Otherwise FS4 Ring Manager is
+ * getting stale data because of re-ordering of read/write
+ * requests at CCN level
+ */
+ mmio_setbits_32(OLY_RNI3PDVM_REGISTERS_NODE8_AUX_CTL,
+ OLY_RNI3PDVM_REGISTERS_NODE8_AUX_CTL_WFC);
+}
+
+static void ccn_post_init(void)
+{
+ mmio_setbits_32(OLY_HNI_REGISTERS_NODE0_PCIERC_RNI_NODEID_LIST,
+ SRP_RNI_PCIE_CONNECTED);
+ mmio_setbits_32(OLY_HNI_REGISTERS_NODE0_SA_AUX_CTL,
+ SA_AUX_CTL_SER_DEVNE_WR);
+
+ mmio_clrbits_32(OLY_HNI_REGISTERS_NODE0_POS_CONTROL,
+ POS_CONTROL_HNI_POS_EN);
+ mmio_clrbits_32(OLY_HNI_REGISTERS_NODE0_SA_AUX_CTL,
+ SA_AUX_CTL_POS_EARLY_WR_COMP_EN);
+}
+
+#ifndef BL31_BOOT_PRELOADED_SCP
+static void crmu_init(void)
+{
+ /*
+ * Configure CRMU for using SMMU
+ */
+
+ /*Program CRMU Stream ID */
+ mmio_write_32(CRMU_MASTER_AXI_ARUSER_CONFIG,
+ (CRMU_STREAM_ID << CRMU_SID_SHIFT));
+ mmio_write_32(CRMU_MASTER_AXI_AWUSER_CONFIG,
+ (CRMU_STREAM_ID << CRMU_SID_SHIFT));
+
+ /* Create Identity mapping */
+ arm_smmu_create_identity_map(DOMAIN_CRMU);
+
+ /* Enable Client Port for Secure Masters*/
+ arm_smmu_enable_secure_client_port();
+}
+#endif
+
+static void brcm_fsx_init(void)
+{
+#if defined(USE_FS4) && defined(USE_FS6)
+ #error "USE_FS4 and USE_FS6 should not be used together"
+#endif
+
+#ifdef USE_FS4
+ fsx_init(eFS4_CRYPTO, FS4_CRYPTO_RING_COUNT, FS4_CRYPTO_DME_COUNT,
+ FS4_CRYPTO_AE_COUNT, FS4_CRYPTO_START_STREAM_ID,
+ FS4_CRYPTO_MSI_DEVICE_ID, FS4_CRYPTO_IDM_IO_CONTROL_DIRECT,
+ FS4_CRYPTO_IDM_RESET_CONTROL, FS4_CRYPTO_BASE,
+ FS4_CRYPTO_DME_BASE);
+
+ fsx_init(eFS4_RAID, FS4_RAID_RING_COUNT, FS4_RAID_DME_COUNT,
+ FS4_RAID_AE_COUNT, FS4_RAID_START_STREAM_ID,
+ FS4_RAID_MSI_DEVICE_ID, FS4_RAID_IDM_IO_CONTROL_DIRECT,
+ FS4_RAID_IDM_RESET_CONTROL, FS4_RAID_BASE,
+ FS4_RAID_DME_BASE);
+
+ fsx_meminit("raid",
+ FS4_RAID_IDM_IO_CONTROL_DIRECT,
+ FS4_RAID_IDM_IO_STATUS);
+#endif
+}
+
+static void bcm_bl33_pass_info(void)
+{
+ struct bl33_info *info = (struct bl33_info *)BL33_SHARED_DDR_BASE;
+
+ if (sizeof(*info) > BL33_SHARED_DDR_SIZE)
+ WARN("bl33 shared area not reserved\n");
+
+ info->version = BL33_INFO_VERSION;
+ info->chip.chip_id = PLAT_CHIP_ID_GET;
+ info->chip.rev_id = PLAT_CHIP_REV_GET;
+}
+
+DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, CORTEX_A72_L2CTLR_EL1)
+
+void plat_bcm_bl31_early_platform_setup(void *from_bl2,
+ bl_params_t *plat_params_from_bl2)
+{
+#ifdef BL31_BOOT_PRELOADED_SCP
+ image_info_t scp_image_info;
+
+ scp_image_info.image_base = PRELOADED_SCP_BASE;
+ scp_image_info.image_size = PRELOADED_SCP_SIZE;
+ plat_bcm_bl2_plat_handle_scp_bl2(&scp_image_info);
+#endif
+ /*
+ * In BL31, logs are saved to DDR and we have much larger space to
+ * store logs. We can now afford to save all logs >= the 'INFO' level
+ */
+ bcm_elog_init((void *)BCM_ELOG_BL31_BASE, BCM_ELOG_BL31_SIZE,
+ LOG_LEVEL_INFO);
+
+ INFO("L2CTLR = 0x%lx\n", read_l2ctlr_el1());
+
+ brcm_timer_sync_init();
+
+ brcm_stingray_dma_pl330_init();
+
+ brcm_stingray_dma_pl330_meminit();
+
+ brcm_stingray_spi_pl022_init(APBS_IDM_IDM_RESET_CONTROL);
+
+#ifdef USE_AMAC
+ brcm_stingray_amac_init();
+#endif
+
+ brcm_stingray_sdio_init();
+
+#ifdef NCSI_IO_DRIVE_STRENGTH_MA
+ brcm_stingray_ncsi_init();
+#endif
+
+#ifdef USE_USB
+ xhci_phy_init();
+#endif
+
+#ifdef USE_SATA
+ brcm_stingray_sata_init();
+#else
+ poweroff_sata_pll();
+#endif
+
+ ccn_pre_init();
+
+ brcm_fsx_init();
+
+ brcm_stingray_smmu_init();
+
+ brcm_stingray_pka_meminit();
+
+ brcm_stingray_crmu_access_init();
+
+ brcm_stingray_scr_init();
+
+ brcm_stingray_hsls_tzpcprot_init();
+
+#ifdef USE_I2S
+ brcm_stingray_audio_init();
+#endif
+
+ ccn_post_init();
+
+ paxb_init();
+
+ paxc_init();
+
+#ifndef BL31_BOOT_PRELOADED_SCP
+ crmu_init();
+#endif
+
+ /* Note: this should be last thing because
+ * FS4 GPV registers only work after FS4 block
+ * (i.e. crypto,raid,cop) is out of reset.
+ */
+ brcm_stingray_security_init();
+
+ brcm_gpio_pad_ns_init();
+
+#ifndef USE_DDR
+ brcm_stingray_sram_ns_init();
+#endif
+
+#ifdef BL31_FORCE_CPU_FULL_FREQ
+ bcm_set_ihost_pll_freq(0x0, PLL_FREQ_FULL);
+#endif
+
+ brcm_stingray_gain_qspi_control();
+
+#ifdef USE_PAXC
+ /*
+ * Check that the handshake has occurred and report ChiMP status.
+ * This is required. Otherwise (especially on Palladium)
+ * Linux might have booted to the pcie stage whereas
+ * ChiMP has not yet booted. Note that nic_mode case has already
+ * been considered above.
+ */
+ if ((boot_source_get() != BOOT_SOURCE_QSPI) &&
+ (!bcm_chimp_is_nic_mode()) &&
+ (!bcm_chimp_wait_handshake())
+ ) {
+ /* Does ChiMP report an error ? */
+ uint32_t err;
+
+ err = bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_STAT_REG);
+ if ((err & CHIMP_ERROR_MASK) == 0)
+ /* ChiMP has not booted yet, but no error reported */
+ WARN("ChiMP not booted yet, but no error reported.\n");
+ }
+
+#if DEBUG
+ if (boot_source_get() != BOOT_SOURCE_QSPI)
+ INFO("Current ChiMP Status: 0x%x; bpe_mod reg: 0x%x\n"
+ "fastboot register: 0x%x; handshake register 0x%x\n",
+ bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_STAT_REG),
+ bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_MODE_REG),
+ bcm_chimp_read_ctrl(CHIMP_REG_CTRL_FSTBOOT_PTR_REG),
+ bcm_chimp_read(CHIMP_REG_ECO_RESERVED));
+#endif /* DEBUG */
+#endif
+
+#ifdef FS4_DISABLE_CLOCK
+ flush_dcache_range(
+ PLAT_BRCM_TRUSTED_SRAM_BASE,
+ PLAT_BRCM_TRUSTED_SRAM_SIZE);
+ fs4_disable_clocks(true, true, true);
+#endif
+
+ /* pass information to BL33 through shared DDR region */
+ bcm_bl33_pass_info();
+
+ /*
+ * We are not yet at the end of BL31, but we can stop log here so we do
+ * not need to add 'bcm_elog_exit' to the standard BL31 code. The
+ * benefit of capturing BL31 logs after this is very minimal in a
+ * production system
+ */
+ bcm_elog_exit();
+
+#if !BRCM_DISABLE_TRUSTED_WDOG
+ /*
+ * Secure watchdog was started earlier in BL2, now it's time to stop
+ * it
+ */
+ sp805_stop(ARM_SP805_TWDG_BASE);
+#endif
+}
diff --git a/plat/brcm/board/stingray/src/brcm_pm_ops.c b/plat/brcm/board/stingray/src/brcm_pm_ops.c
new file mode 100644
index 000000000..03a604c15
--- /dev/null
+++ b/plat/brcm/board/stingray/src/brcm_pm_ops.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 2017 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/ccn.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/spinlock.h>
+
+#include <brcm_scpi.h>
+#include <chimp.h>
+#include <cmn_plat_util.h>
+#include <plat_brcm.h>
+#include <platform_def.h>
+#include <sr_utils.h>
+
+#include "m0_cfg.h"
+
+
+#define CORE_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL0])
+#define CLUSTER_PWR_STATE(state) \
+ ((state)->pwr_domain_state[MPIDR_AFFLVL1])
+#define SYSTEM_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL2])
+
+#define VENDOR_RST_TYPE_SHIFT 4
+
+#if HW_ASSISTED_COHERENCY
+/*
+ * On systems where participant CPUs are cache-coherent, we can use spinlocks
+ * instead of bakery locks.
+ */
+spinlock_t event_lock;
+#define event_lock_get(_lock) spin_lock(&_lock)
+#define event_lock_release(_lock) spin_unlock(&_lock)
+
+#else
+/*
+ * Use bakery locks for state coordination as not all participants are
+ * cache coherent now.
+ */
+DEFINE_BAKERY_LOCK(event_lock);
+#define event_lock_get(_lock) bakery_lock_get(&_lock)
+#define event_lock_release(_lock) bakery_lock_release(&_lock)
+#endif
+
+static int brcm_pwr_domain_on(u_register_t mpidr)
+{
+ /*
+ * SCP takes care of powering up parent power domains so we
+ * only need to care about level 0
+ */
+ scpi_set_brcm_power_state(mpidr, scpi_power_on, scpi_power_on,
+ scpi_power_on);
+
+ return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Handler called when a power level has just been powered on after
+ * being turned off earlier. The target_state encodes the low power state that
+ * each level has woken up from. This handler would never be invoked with
+ * the system power domain uninitialized as either the primary would have taken
+ * care of it as part of cold boot or the first core awakened from system
+ * suspend would have already initialized it.
+ ******************************************************************************/
+static void brcm_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ unsigned long cluster_id = MPIDR_AFFLVL1_VAL(read_mpidr());
+
+ /* Assert that the system power domain need not be initialized */
+ assert(SYSTEM_PWR_STATE(target_state) == PLAT_LOCAL_STATE_RUN);
+
+ assert(CORE_PWR_STATE(target_state) == PLAT_LOCAL_STATE_OFF);
+
+ /*
+ * Perform the common cluster specific operations i.e enable coherency
+ * if this cluster was off.
+ */
+ if (CLUSTER_PWR_STATE(target_state) == PLAT_LOCAL_STATE_OFF) {
+ INFO("Cluster #%lu entering to snoop/dvm domain\n", cluster_id);
+ ccn_enter_snoop_dvm_domain(1 << cluster_id);
+ }
+
+ /* Program the gic per-cpu distributor or re-distributor interface */
+ plat_brcm_gic_pcpu_init();
+
+ /* Enable the gic cpu interface */
+ plat_brcm_gic_cpuif_enable();
+}
+
+static void brcm_power_down_common(void)
+{
+ unsigned int standbywfil2, standbywfi;
+ uint64_t mpidr = read_mpidr_el1();
+
+ switch (MPIDR_AFFLVL1_VAL(mpidr)) {
+ case 0x0:
+ standbywfi = CDRU_PROC_EVENT_CLEAR__IH0_CDRU_STANDBYWFI;
+ standbywfil2 = CDRU_PROC_EVENT_CLEAR__IH0_CDRU_STANDBYWFIL2;
+ break;
+ case 0x1:
+ standbywfi = CDRU_PROC_EVENT_CLEAR__IH1_CDRU_STANDBYWFI;
+ standbywfil2 = CDRU_PROC_EVENT_CLEAR__IH1_CDRU_STANDBYWFIL2;
+ break;
+ case 0x2:
+ standbywfi = CDRU_PROC_EVENT_CLEAR__IH2_CDRU_STANDBYWFI;
+ standbywfil2 = CDRU_PROC_EVENT_CLEAR__IH2_CDRU_STANDBYWFIL2;
+ break;
+ case 0x3:
+ standbywfi = CDRU_PROC_EVENT_CLEAR__IH3_CDRU_STANDBYWFI;
+ standbywfil2 = CDRU_PROC_EVENT_CLEAR__IH3_CDRU_STANDBYWFIL2;
+ break;
+ default:
+ ERROR("Invalid cluster #%llx\n", MPIDR_AFFLVL1_VAL(mpidr));
+ return;
+ }
+ /* Clear the WFI status bit */
+ event_lock_get(event_lock);
+ mmio_setbits_32(CDRU_PROC_EVENT_CLEAR,
+ (1 << (standbywfi + MPIDR_AFFLVL0_VAL(mpidr))) |
+ (1 << standbywfil2));
+ event_lock_release(event_lock);
+}
+
+/*
+ * Helper function to inform power down state to SCP.
+ */
+static void brcm_scp_suspend(const psci_power_state_t *target_state)
+{
+ uint32_t cluster_state = scpi_power_on;
+ uint32_t system_state = scpi_power_on;
+
+ /* Check if power down at system power domain level is requested */
+ if (SYSTEM_PWR_STATE(target_state) == PLAT_LOCAL_STATE_OFF)
+ system_state = scpi_power_retention;
+
+ /* Check if Cluster is to be turned off */
+ if (CLUSTER_PWR_STATE(target_state) == PLAT_LOCAL_STATE_OFF)
+ cluster_state = scpi_power_off;
+
+ /*
+ * Ask the SCP to power down the appropriate components depending upon
+ * their state.
+ */
+ scpi_set_brcm_power_state(read_mpidr_el1(),
+ scpi_power_off,
+ cluster_state,
+ system_state);
+}
+
+/*
+ * Helper function to turn off a CPU power domain and its parent power domains
+ * if applicable. Since SCPI doesn't differentiate between OFF and suspend, we
+ * call the suspend helper here.
+ */
+static void brcm_scp_off(const psci_power_state_t *target_state)
+{
+ brcm_scp_suspend(target_state);
+}
+
+static void brcm_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ unsigned long cluster_id = MPIDR_AFFLVL1_VAL(read_mpidr_el1());
+
+ assert(CORE_PWR_STATE(target_state) == PLAT_LOCAL_STATE_OFF);
+ /* Prevent interrupts from spuriously waking up this cpu */
+ plat_brcm_gic_cpuif_disable();
+
+ /* Turn redistributor off */
+ plat_brcm_gic_redistif_off();
+
+ /* If Cluster is to be turned off, disable coherency */
+ if (CLUSTER_PWR_STATE(target_state) == PLAT_LOCAL_STATE_OFF)
+ ccn_exit_snoop_dvm_domain(1 << cluster_id);
+
+ brcm_power_down_common();
+
+ brcm_scp_off(target_state);
+}
+
+/*******************************************************************************
+ * Handler called when the CPU power domain is about to enter standby.
+ ******************************************************************************/
+static void brcm_cpu_standby(plat_local_state_t cpu_state)
+{
+ unsigned int scr;
+
+ assert(cpu_state == PLAT_LOCAL_STATE_RET);
+
+ scr = read_scr_el3();
+ /*
+ * Enable the Non secure interrupt to wake the CPU.
+ * In GICv3 affinity routing mode, the non secure group1 interrupts use
+ * the PhysicalFIQ at EL3 whereas in GICv2, it uses the PhysicalIRQ.
+ * Enabling both the bits works for both GICv2 mode and GICv3 affinity
+ * routing mode.
+ */
+ write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT);
+ isb();
+ dsb();
+ wfi();
+
+ /*
+ * Restore SCR to the original value, synchronisation of scr_el3 is
+ * done by eret while el3_exit to save some execution cycles.
+ */
+ write_scr_el3(scr);
+}
+
+/*
+ * Helper function to shutdown the system via SCPI.
+ */
+static void __dead2 brcm_scp_sys_shutdown(void)
+{
+ /*
+ * Disable GIC CPU interface to prevent pending interrupt
+ * from waking up the AP from WFI.
+ */
+ plat_brcm_gic_cpuif_disable();
+
+ /* Flush and invalidate data cache */
+ dcsw_op_all(DCCISW);
+
+ /* Bring Cluster out of coherency domain as its going to die */
+ plat_brcm_interconnect_exit_coherency();
+
+ brcm_power_down_common();
+
+ /* Send the power down request to the SCP */
+ scpi_sys_power_state(scpi_system_shutdown);
+
+ wfi();
+ ERROR("BRCM System Off: operation not handled.\n");
+ panic();
+}
+
+/*
+ * Helper function to reset the system
+ */
+static void __dead2 brcm_scp_sys_reset(unsigned int reset_type)
+{
+ /*
+ * Disable GIC CPU interface to prevent pending interrupt
+ * from waking up the AP from WFI.
+ */
+ plat_brcm_gic_cpuif_disable();
+
+ /* Flush and invalidate data cache */
+ dcsw_op_all(DCCISW);
+
+ /* Bring Cluster out of coherency domain as its going to die */
+ plat_brcm_interconnect_exit_coherency();
+
+ brcm_power_down_common();
+
+ /* Send the system reset request to the SCP
+ *
+ * As per PSCI spec system power state could be
+ * 0-> Shutdown
+ * 1-> Reboot- Board level Reset
+ * 2-> Reset - SoC level Reset
+ *
+ * Spec allocates 8 bits, 2 nibble, for this. One nibble is sufficient
+ * for sending the state hence We are utilizing 2nd nibble for vendor
+ * define reset type.
+ */
+ scpi_sys_power_state((reset_type << VENDOR_RST_TYPE_SHIFT) |
+ scpi_system_reboot);
+
+ wfi();
+ ERROR("BRCM System Reset: operation not handled.\n");
+ panic();
+}
+
+static void __dead2 brcm_system_reset(void)
+{
+ unsigned int reset_type;
+
+ if (bcm_chimp_is_nic_mode())
+ reset_type = SOFT_RESET_L3;
+ else
+ reset_type = SOFT_SYS_RESET_L1;
+
+ brcm_scp_sys_reset(reset_type);
+}
+
+static int brcm_system_reset2(int is_vendor, int reset_type,
+ u_register_t cookie)
+{
+ if (!is_vendor) {
+ /* Architectural warm boot: only warm reset is supported */
+ reset_type = SOFT_RESET_L3;
+ } else {
+ uint32_t boot_source = (uint32_t)cookie;
+
+ boot_source &= BOOT_SOURCE_MASK;
+ brcm_stingray_set_straps(boot_source);
+ }
+ brcm_scp_sys_reset(reset_type);
+
+ /*
+ * brcm_scp_sys_reset cannot return (it is a __dead function),
+ * but brcm_system_reset2 has to return some value, even in
+ * this case.
+ */
+ return 0;
+}
+
+static int brcm_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+ /*
+ * Check if the non secure entrypoint lies within the non
+ * secure DRAM.
+ */
+ if ((entrypoint >= BRCM_NS_DRAM1_BASE) &&
+ (entrypoint < (BRCM_NS_DRAM1_BASE + BRCM_NS_DRAM1_SIZE)))
+ return PSCI_E_SUCCESS;
+#ifdef __aarch64__
+ if ((entrypoint >= BRCM_DRAM2_BASE) &&
+ (entrypoint < (BRCM_DRAM2_BASE + BRCM_DRAM2_SIZE)))
+ return PSCI_E_SUCCESS;
+
+ if ((entrypoint >= BRCM_DRAM3_BASE) &&
+ (entrypoint < (BRCM_DRAM3_BASE + BRCM_DRAM3_SIZE)))
+ return PSCI_E_SUCCESS;
+#endif
+
+ return PSCI_E_INVALID_ADDRESS;
+}
+
+/*******************************************************************************
+ * ARM standard platform handler called to check the validity of the power state
+ * parameter.
+ ******************************************************************************/
+static int brcm_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state)
+{
+ int pstate = psci_get_pstate_type(power_state);
+ int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
+ int i;
+
+ assert(req_state);
+
+ if (pwr_lvl > PLAT_MAX_PWR_LVL)
+ return PSCI_E_INVALID_PARAMS;
+
+ /* Sanity check the requested state */
+ if (pstate == PSTATE_TYPE_STANDBY) {
+ /*
+ * It's possible to enter standby only on power level 0
+ * Ignore any other power level.
+ */
+ if (pwr_lvl != MPIDR_AFFLVL0)
+ return PSCI_E_INVALID_PARAMS;
+
+ req_state->pwr_domain_state[MPIDR_AFFLVL0] =
+ PLAT_LOCAL_STATE_RET;
+ } else {
+ for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++)
+ req_state->pwr_domain_state[i] =
+ PLAT_LOCAL_STATE_OFF;
+ }
+
+ /*
+ * We expect the 'state id' to be zero.
+ */
+ if (psci_get_pstate_id(power_state))
+ return PSCI_E_INVALID_PARAMS;
+
+ return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Export the platform handlers via plat_brcm_psci_pm_ops. The ARM Standard
+ * platform will take care of registering the handlers with PSCI.
+ ******************************************************************************/
+plat_psci_ops_t plat_brcm_psci_pm_ops = {
+ .pwr_domain_on = brcm_pwr_domain_on,
+ .pwr_domain_on_finish = brcm_pwr_domain_on_finish,
+ .pwr_domain_off = brcm_pwr_domain_off,
+ .cpu_standby = brcm_cpu_standby,
+ .system_off = brcm_scp_sys_shutdown,
+ .system_reset = brcm_system_reset,
+ .system_reset2 = brcm_system_reset2,
+ .validate_ns_entrypoint = brcm_validate_ns_entrypoint,
+ .validate_power_state = brcm_validate_power_state,
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const struct plat_psci_ops **psci_ops)
+{
+ *psci_ops = &plat_brcm_psci_pm_ops;
+
+ /* Setup mailbox with entry point. */
+ mmio_write_64(CRMU_CFG_BASE + offsetof(M0CFG, core_cfg.rvbar),
+ sec_entrypoint);
+
+ return 0;
+}
diff --git a/plat/brcm/board/stingray/src/fsx.c b/plat/brcm/board/stingray/src/fsx.c
new file mode 100644
index 000000000..5725a2e2a
--- /dev/null
+++ b/plat/brcm/board/stingray/src/fsx.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 2019-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <plat/common/common_def.h>
+
+#include <fsx.h>
+#include <platform_def.h>
+#include <sr_utils.h>
+
+#define FS4_IDM_IO_CONTROL_DIRECT__SRAM_CLK_EN 0
+
+#define FS4_IDM_IO_CONTROL_DIRECT__MEM_POWERON 11
+#define FS4_IDM_IO_CONTROL_DIRECT__MEM_POWEROK 12
+#define FS4_IDM_IO_CONTROL_DIRECT__MEM_ARRPOWERON 13
+#define FS4_IDM_IO_CONTROL_DIRECT__MEM_ARRPOWEROK 14
+#define FS4_IDM_IO_CONTROL_DIRECT__MEM_ISO 15
+#define FS4_IDM_IO_CONTROL_DIRECT__CLK_EN 31
+
+#define FS4_IDM_IO_STATUS__MEM_POWERON 0
+#define FS4_IDM_IO_STATUS__MEM_POWEROK 1
+#define FS4_IDM_IO_STATUS__MEM_ARRPOWERON 2
+#define FS4_IDM_IO_STATUS__MEM_ARRPOWEROK 3
+#define FS4_IDM_IO_STATUS__MEM_ALLOK 0xf
+
+#define FS4_IDM_RESET_CONTROL__RESET 0
+
+#define FSX_RINGx_BASE(__b, __i) \
+ ((__b) + (__i) * 0x10000)
+
+#define FSX_RINGx_VERSION_NUMBER(__b, __i) \
+ (FSX_RINGx_BASE(__b, __i) + 0x0)
+
+#define FSX_RINGx_MSI_DEV_ID(__b, __i) \
+ (FSX_RINGx_BASE(__b, __i) + 0x44)
+
+#define FSX_COMM_RINGx_BASE(__b, __i) \
+ ((__b) + 0x200000 + (__i) * 0x100)
+
+#define FSX_COMM_RINGx_CONTROL(__b, __i) \
+ (FSX_COMM_RINGx_BASE(__b, __i) + 0x0)
+#define FSX_COMM_RINGx_CONTROL__AXI_ID 8
+#define FSX_COMM_RINGx_CONTROL__AXI_ID_MASK 0x1f
+#define FSX_COMM_RINGx_CONTROL__PRIORITY 4
+#define FSX_COMM_RINGx_CONTROL__PRIORITY_MASK 0x7
+#define FSX_COMM_RINGx_CONTROL__AE_GROUP 0
+#define FSX_COMM_RINGx_CONTROL__AE_GROUP_MASK 0x7
+
+#define FSX_COMM_RINGx_MSI_DEV_ID(__b, __i) \
+ (FSX_COMM_RINGx_BASE(__b, __i) + 0x4)
+
+#define FSX_AEx_BASE(__b, __i) \
+ ((__b) + 0x202000 + (__i) * 0x100)
+
+#define FSX_AEx_CONTROL_REGISTER(__b, __i) \
+ (FSX_AEx_BASE(__b, __i) + 0x0)
+#define FSX_AEx_CONTROL_REGISTER__ACTIVE 4
+#define FSX_AEx_CONTROL_REGISTER__GROUP_ID 0
+#define FSX_AEx_CONTROL_REGISTER__GROUP_ID_MASK 0x7
+
+#define FSX_COMM_RM_RING_SECURITY_SETTING 0x0
+
+#define FSX_COMM_RM_SSID_CONTROL 0x4
+#define FSX_COMM_RM_SSID_CONTROL__RING_BITS 5
+#define FSX_COMM_RM_SSID_CONTROL__MASK 0x3ff
+
+#define FSX_COMM_RM_CONTROL_REGISTER 0x8
+#define FSX_COMM_RM_CONTROL_REGISTER__CONFIG_DONE 2
+#define FSX_COMM_RM_CONTROL_REGISTER__AE_TIMEOUT 5
+#define FSX_COMM_RM_CONTROL_REGISTER__AE_LOCKING 7
+
+#define FSX_COMM_RM_TIMER_CONTROL_0 0xc
+#define FSX_COMM_RM_TIMER_CONTROL_0__FAST 16
+#define FSX_COMM_RM_TIMER_CONTROL_0__MEDIUM 0
+
+#define FSX_COMM_RM_TIMER_CONTROL_1 0x10
+#define FSX_COMM_RM_TIMER_CONTROL_1__SLOW 16
+#define FSX_COMM_RM_TIMER_CONTROL_1__IDLE 0
+
+#define FSX_COMM_RM_BURST_BD_THRESHOLD 0x14
+#define FSX_COMM_RM_BURST_BD_THRESHOLD_LOW 0
+#define FSX_COMM_RM_BURST_BD_THRESHOLD_HIGH 16
+
+#define FSX_COMM_RM_BURST_LENGTH 0x18
+#define FSX_COMM_RM_BURST_LENGTH__FOR_DDR_ADDR_GEN 16
+#define FSX_COMM_RM_BURST_LENGTH__FOR_DDR_ADDR_GEN_MASK 0x1ff
+#define FSX_COMM_RM_BURST_LENGTH__FOR_TOGGLE 0
+#define FSX_COMM_RM_BURST_LENGTH__FOR_TOGGLE_MASK 0x1ff
+
+#define FSX_COMM_RM_FIFO_THRESHOLD 0x1c
+#define FSX_COMM_RM_FIFO_THRESHOLD__BD_FIFO_FULL 16
+#define FSX_COMM_RM_FIFO_THRESHOLD__BD_FIFO_FULL_MASK 0x1ff
+#define FSX_COMM_RM_FIFO_THRESHOLD__AE_FIFO_FULL 0
+#define FSX_COMM_RM_FIFO_THRESHOLD__AE_FIFO_FULL_MASK 0x1f
+
+#define FSX_COMM_RM_AE_TIMEOUT 0x24
+
+#define FSX_COMM_RM_RING_FLUSH_TIMEOUT 0x2c
+
+#define FSX_COMM_RM_MEMORY_CONFIGURATION 0x30
+#define FSX_COMM_RM_MEMORY_CONFIGURATION__ARRPOWERONIN 12
+#define FSX_COMM_RM_MEMORY_CONFIGURATION__ARRPOWEROKIN 13
+#define FSX_COMM_RM_MEMORY_CONFIGURATION__POWERONIN 14
+#define FSX_COMM_RM_MEMORY_CONFIGURATION__POWEROKIN 15
+
+#define FSX_COMM_RM_AXI_CONTROL 0x34
+#define FSX_COMM_RM_AXI_CONTROL__WRITE_CHANNEL_EN 28
+#define FSX_COMM_RM_AXI_CONTROL__READ_CHANNEL_EN 24
+#define FSX_COMM_RM_AXI_CONTROL__AWQOS 20
+#define FSX_COMM_RM_AXI_CONTROL__ARQOS 16
+#define FSX_COMM_RM_AXI_CONTROL__AWPROT 12
+#define FSX_COMM_RM_AXI_CONTROL__ARPROT 8
+#define FSX_COMM_RM_AXI_CONTROL__AWCACHE 4
+#define FSX_COMM_RM_AXI_CONTROL__ARCACHE 0
+
+#define FSX_COMM_RM_CONFIG_INTERRUPT_STATUS_CLEAR 0x48
+
+#define FSX_COMM_RM_GROUP_PKT_EXTENSION_SUPPORT 0xc0
+
+#define FSX_COMM_RM_AXI_READ_BURST_THRESHOLD 0xc8
+#define FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MASK 0x1ff
+#define FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MAX 16
+#define FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MIN 0
+
+#define FSX_COMM_RM_GROUP_RING_COUNT 0xcc
+
+#define FSX_COMM_RM_MAIN_HW_INIT_DONE 0x12c
+#define FSX_COMM_RM_MAIN_HW_INIT_DONE__MASK 0x1
+
+#define FSX_DMEx_BASE(__b, __i) \
+ ((__b) + (__i) * 0x1000)
+
+#define FSX_DMEx_AXI_CONTROL(__b, __i) \
+ (FSX_DMEx_BASE(__b, __i) + 0x4)
+#define FSX_DMEx_AXI_CONTROL__WRITE_CHANNEL_EN 28
+#define FSX_DMEx_AXI_CONTROL__READ_CHANNEL_EN 24
+#define FSX_DMEx_AXI_CONTROL__AWQOS 20
+#define FSX_DMEx_AXI_CONTROL__ARQOS 16
+#define FSX_DMEx_AXI_CONTROL__AWCACHE 4
+#define FSX_DMEx_AXI_CONTROL__ARCACHE 0
+
+#define FSX_DMEx_WR_FIFO_THRESHOLD(__b, __i) \
+ (FSX_DMEx_BASE(__b, __i) + 0xc)
+#define FSX_DMEx_WR_FIFO_THRESHOLD__MASK 0x3ff
+#define FSX_DMEx_WR_FIFO_THRESHOLD__MAX 10
+#define FSX_DMEx_WR_FIFO_THRESHOLD__MIN 0
+
+#define FSX_DMEx_RD_FIFO_THRESHOLD(__b, __i) \
+ (FSX_DMEx_BASE(__b, __i) + 0x14)
+#define FSX_DMEx_RD_FIFO_THRESHOLD__MASK 0x3ff
+#define FSX_DMEx_RD_FIFO_THRESHOLD__MAX 10
+#define FSX_DMEx_RD_FIFO_THRESHOLD__MIN 0
+
+#define FS6_SUB_TOP_BASE 0x66D8F800
+#define FS6_PKI_DME_RESET 0x4
+#define PKI_DME_RESET 1
+
+char *fsx_type_names[] = {
+ "fs4-raid",
+ "fs4-crypto",
+ "fs6-pki",
+};
+
+void fsx_init(eFSX_TYPE fsx_type,
+ unsigned int ring_count,
+ unsigned int dme_count,
+ unsigned int ae_count,
+ unsigned int start_stream_id,
+ unsigned int msi_dev_id,
+ uintptr_t idm_io_control_direct,
+ uintptr_t idm_reset_control,
+ uintptr_t base,
+ uintptr_t dme_base)
+{
+ int try;
+ unsigned int i, v, data;
+ uintptr_t fs4_idm_io_control_direct = idm_io_control_direct;
+ uintptr_t fs4_idm_reset_control = idm_reset_control;
+ uintptr_t fsx_comm_rm = (base + 0x203000);
+
+ VERBOSE("fsx %s init start\n", fsx_type_names[fsx_type]);
+
+ if (fsx_type == eFS4_RAID || fsx_type == eFS4_CRYPTO) {
+ /* Enable FSx engine clock */
+ VERBOSE(" - enable fsx clock\n");
+ mmio_write_32(fs4_idm_io_control_direct,
+ (1U << FS4_IDM_IO_CONTROL_DIRECT__CLK_EN));
+ udelay(500);
+
+ /* Reset FSx engine */
+ VERBOSE(" - reset fsx\n");
+ v = mmio_read_32(fs4_idm_reset_control);
+ v |= (1 << FS4_IDM_RESET_CONTROL__RESET);
+ mmio_write_32(fs4_idm_reset_control, v);
+ udelay(500);
+ v = mmio_read_32(fs4_idm_reset_control);
+ v &= ~(1 << FS4_IDM_RESET_CONTROL__RESET);
+ mmio_write_32(fs4_idm_reset_control, v);
+ } else {
+ /*
+ * Default RM and AE are out of reset,
+ * So only DME Reset added here
+ */
+ v = mmio_read_32(FS6_SUB_TOP_BASE + FS6_PKI_DME_RESET);
+ v &= ~(PKI_DME_RESET);
+ mmio_write_32(FS6_SUB_TOP_BASE + FS6_PKI_DME_RESET, v);
+ }
+
+ /* Wait for HW-init done */
+ VERBOSE(" - wait for HW-init done\n");
+ try = 10000;
+ do {
+ udelay(1);
+ data = mmio_read_32(fsx_comm_rm +
+ FSX_COMM_RM_MAIN_HW_INIT_DONE);
+ try--;
+ } while (!(data & FSX_COMM_RM_MAIN_HW_INIT_DONE__MASK) && (try > 0));
+
+ if (try <= 0)
+ ERROR("fsx_comm_rm + 0x%x: 0x%x\n",
+ data, FSX_COMM_RM_MAIN_HW_INIT_DONE);
+
+ /* Make all rings non-secured */
+ VERBOSE(" - make all rings non-secured\n");
+ v = 0xffffffff;
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_RING_SECURITY_SETTING, v);
+
+ /* Set start stream-id for rings to */
+ VERBOSE(" - set start stream-id for rings to 0x%x\n",
+ start_stream_id);
+ v = start_stream_id >> FSX_COMM_RM_SSID_CONTROL__RING_BITS;
+ v &= FSX_COMM_RM_SSID_CONTROL__MASK;
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_SSID_CONTROL, v);
+
+ /* Set timer configuration */
+ VERBOSE(" - set timer configuration\n");
+ v = 0x0271 << FSX_COMM_RM_TIMER_CONTROL_0__MEDIUM;
+ v |= (0x0138 << FSX_COMM_RM_TIMER_CONTROL_0__FAST);
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_TIMER_CONTROL_0, v);
+ v = 0x09c4 << FSX_COMM_RM_TIMER_CONTROL_1__IDLE;
+ v |= (0x04e2 << FSX_COMM_RM_TIMER_CONTROL_1__SLOW);
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_TIMER_CONTROL_1, v);
+ v = 0x0000f424;
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_RING_FLUSH_TIMEOUT, v);
+
+ /* Set burst length and fifo threshold */
+ VERBOSE(" - set burst length, fifo and bd threshold\n");
+ v = 0x0;
+ v |= (0x8 << FSX_COMM_RM_BURST_LENGTH__FOR_DDR_ADDR_GEN);
+ v |= (0x8 << FSX_COMM_RM_BURST_LENGTH__FOR_TOGGLE);
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_BURST_LENGTH, v);
+ v = 0x0;
+ v |= (0x67 << FSX_COMM_RM_FIFO_THRESHOLD__BD_FIFO_FULL);
+ v |= (0x18 << FSX_COMM_RM_FIFO_THRESHOLD__AE_FIFO_FULL);
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_FIFO_THRESHOLD, v);
+ v = 0x0;
+ v |= (0x8 << FSX_COMM_RM_BURST_BD_THRESHOLD_LOW);
+ v |= (0x8 << FSX_COMM_RM_BURST_BD_THRESHOLD_HIGH);
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_BURST_BD_THRESHOLD, v);
+
+ /* Set memory configuration */
+ VERBOSE(" - set memory configuration\n");
+ v = 0x0;
+ v |= (1 << FSX_COMM_RM_MEMORY_CONFIGURATION__POWERONIN);
+ v |= (1 << FSX_COMM_RM_MEMORY_CONFIGURATION__POWEROKIN);
+ v |= (1 << FSX_COMM_RM_MEMORY_CONFIGURATION__ARRPOWERONIN);
+ v |= (1 << FSX_COMM_RM_MEMORY_CONFIGURATION__ARRPOWEROKIN);
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_MEMORY_CONFIGURATION, v);
+
+ /* AXI configuration for RM */
+ v = 0;
+ v |= (0x1 << FSX_COMM_RM_AXI_CONTROL__WRITE_CHANNEL_EN);
+ v |= (0x1 << FSX_COMM_RM_AXI_CONTROL__READ_CHANNEL_EN);
+ v |= (0xe << FSX_COMM_RM_AXI_CONTROL__AWQOS);
+ v |= (0xa << FSX_COMM_RM_AXI_CONTROL__ARQOS);
+ v |= (0x2 << FSX_COMM_RM_AXI_CONTROL__AWPROT);
+ v |= (0x2 << FSX_COMM_RM_AXI_CONTROL__ARPROT);
+ v |= (0xf << FSX_COMM_RM_AXI_CONTROL__AWCACHE);
+ v |= (0xf << FSX_COMM_RM_AXI_CONTROL__ARCACHE);
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_AXI_CONTROL, v);
+ VERBOSE(" - set AXI control = 0x%x\n",
+ mmio_read_32(fsx_comm_rm + FSX_COMM_RM_AXI_CONTROL));
+ v = 0x0;
+ v |= (0x10 << FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MAX);
+ v |= (0x10 << FSX_COMM_RM_AXI_READ_BURST_THRESHOLD__MIN);
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_AXI_READ_BURST_THRESHOLD, v);
+ VERBOSE(" - set AXI read burst threshold = 0x%x\n",
+ mmio_read_32(fsx_comm_rm + FSX_COMM_RM_AXI_READ_BURST_THRESHOLD));
+
+ /* Configure group ring count for all groups */
+ /* By default we schedule extended packets
+ * on all AEs/DMEs in a group.
+ */
+ v = (dme_count & 0xf) << 0;
+ v |= (dme_count & 0xf) << 4;
+ v |= (dme_count & 0xf) << 8;
+ v |= (dme_count & 0xf) << 12;
+ v |= (dme_count & 0xf) << 16;
+ v |= (dme_count & 0xf) << 20;
+ v |= (dme_count & 0xf) << 24;
+ v |= (dme_count & 0xf) << 28;
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_GROUP_RING_COUNT, v);
+
+ /*
+ * Due to HW issue spurious interrupts are getting generated.
+ * To fix sw needs to clear the config status interrupts
+ * before setting CONFIG_DONE.
+ */
+ mmio_write_32(fsx_comm_rm +
+ FSX_COMM_RM_CONFIG_INTERRUPT_STATUS_CLEAR,
+ 0xffffffff);
+
+ /* Configure RM control */
+ VERBOSE(" - configure RM control\n");
+ v = mmio_read_32(fsx_comm_rm + FSX_COMM_RM_CONTROL_REGISTER);
+ v |= (1 << FSX_COMM_RM_CONTROL_REGISTER__AE_LOCKING);
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_CONTROL_REGISTER, v);
+ v |= (1 << FSX_COMM_RM_CONTROL_REGISTER__CONFIG_DONE);
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_CONTROL_REGISTER, v);
+
+ /* Configure AE timeout */
+ VERBOSE(" - configure AE timeout\n");
+ v = 0x00003fff;
+ mmio_write_32(fsx_comm_rm + FSX_COMM_RM_AE_TIMEOUT, v);
+
+ /* Initialize all AEs */
+ for (i = 0; i < ae_count; i++) {
+ VERBOSE(" - initialize AE%d\n", i);
+ v = (0x1 << FSX_AEx_CONTROL_REGISTER__ACTIVE);
+ mmio_write_32(FSX_AEx_CONTROL_REGISTER(base, i), v);
+ }
+
+ /* Initialize all DMEs */
+ for (i = 0; i < dme_count; i++) {
+ VERBOSE(" - initialize DME%d\n", i);
+ v = 0;
+ v |= (0x1 << FSX_DMEx_AXI_CONTROL__WRITE_CHANNEL_EN);
+ v |= (0x1 << FSX_DMEx_AXI_CONTROL__READ_CHANNEL_EN);
+ v |= (0xe << FSX_DMEx_AXI_CONTROL__AWQOS);
+ v |= (0xa << FSX_DMEx_AXI_CONTROL__ARQOS);
+ v |= (0xf << FSX_DMEx_AXI_CONTROL__AWCACHE);
+ v |= (0xf << FSX_DMEx_AXI_CONTROL__ARCACHE);
+ mmio_write_32(FSX_DMEx_AXI_CONTROL(dme_base, i), v);
+ VERBOSE(" -- AXI_CONTROL = 0x%x\n",
+ mmio_read_32(FSX_DMEx_AXI_CONTROL(dme_base, i)));
+ v = 0;
+ v |= (0x4 << FSX_DMEx_WR_FIFO_THRESHOLD__MIN);
+ v |= (0x4 << FSX_DMEx_WR_FIFO_THRESHOLD__MAX);
+ mmio_write_32(FSX_DMEx_WR_FIFO_THRESHOLD(dme_base, i), v);
+ VERBOSE(" -- WR_FIFO_THRESHOLD = 0x%x\n",
+ mmio_read_32(FSX_DMEx_WR_FIFO_THRESHOLD(dme_base, i)));
+ v = 0;
+ v |= (0x4 << FSX_DMEx_RD_FIFO_THRESHOLD__MIN);
+ v |= (0x4 << FSX_DMEx_RD_FIFO_THRESHOLD__MAX);
+ mmio_write_32(FSX_DMEx_RD_FIFO_THRESHOLD(dme_base, i), v);
+ VERBOSE(" -- RD_FIFO_THRESHOLD = 0x%x\n",
+ mmio_read_32(FSX_DMEx_RD_FIFO_THRESHOLD(dme_base, i)));
+ }
+
+ /* Configure ring axi id and msi device id */
+ for (i = 0; i < ring_count; i++) {
+ VERBOSE(" - ring%d version=0x%x\n", i,
+ mmio_read_32(FSX_RINGx_VERSION_NUMBER(base, i)));
+ mmio_write_32(FSX_COMM_RINGx_MSI_DEV_ID(base, i),
+ msi_dev_id);
+ v = 0;
+ v |= ((i & FSX_COMM_RINGx_CONTROL__AXI_ID_MASK) <<
+ FSX_COMM_RINGx_CONTROL__AXI_ID);
+ mmio_write_32(FSX_COMM_RINGx_CONTROL(base, i), v);
+ }
+
+ INFO("fsx %s init done\n", fsx_type_names[fsx_type]);
+}
+
+void fsx_meminit(const char *name,
+ uintptr_t idm_io_control_direct,
+ uintptr_t idm_io_status)
+{
+ int try;
+ unsigned int val;
+
+ VERBOSE("fsx %s meminit start\n", name);
+
+ VERBOSE(" - arrpoweron\n");
+ mmio_setbits_32(idm_io_control_direct,
+ BIT(FS4_IDM_IO_CONTROL_DIRECT__MEM_ARRPOWERON));
+ while (!(mmio_read_32(idm_io_status) &
+ BIT(FS4_IDM_IO_STATUS__MEM_ARRPOWERON)))
+ ;
+
+ VERBOSE(" - arrpowerok\n");
+ mmio_setbits_32(idm_io_control_direct,
+ (1 << FS4_IDM_IO_CONTROL_DIRECT__MEM_ARRPOWEROK));
+ while (!(mmio_read_32(idm_io_status) &
+ BIT(FS4_IDM_IO_STATUS__MEM_ARRPOWEROK)))
+ ;
+
+ VERBOSE(" - poweron\n");
+ mmio_setbits_32(idm_io_control_direct,
+ (1 << FS4_IDM_IO_CONTROL_DIRECT__MEM_POWERON));
+ while (!(mmio_read_32(idm_io_status) &
+ BIT(FS4_IDM_IO_STATUS__MEM_POWERON)))
+ ;
+
+ VERBOSE(" - powerok\n");
+ mmio_setbits_32(idm_io_control_direct,
+ (1 << FS4_IDM_IO_CONTROL_DIRECT__MEM_POWEROK));
+ while (!(mmio_read_32(idm_io_status) &
+ BIT(FS4_IDM_IO_STATUS__MEM_POWEROK)))
+ ;
+
+ /* Final check on all power bits */
+ try = 10;
+ do {
+ val = mmio_read_32(idm_io_status);
+ if (val == FS4_IDM_IO_STATUS__MEM_ALLOK)
+ break;
+
+ /* Wait sometime */
+ mdelay(1);
+
+ try--;
+ } while (try > 0);
+
+ /* Remove memory isolation if things are fine. */
+ if (try <= 0) {
+ INFO(" - powerup failed\n");
+ } else {
+ VERBOSE(" - remove isolation\n");
+ mmio_clrbits_32(idm_io_control_direct,
+ (1 << FS4_IDM_IO_CONTROL_DIRECT__MEM_ISO));
+ VERBOSE(" - powerup done\n");
+ }
+
+ INFO("fsx %s meminit done\n", name);
+}
+
+void fs4_disable_clocks(bool disable_sram,
+ bool disable_crypto,
+ bool disable_raid)
+{
+ VERBOSE("fs4 disable clocks start\n");
+
+ if (disable_sram) {
+ VERBOSE(" - disable sram clock\n");
+ mmio_clrbits_32(FS4_SRAM_IDM_IO_CONTROL_DIRECT,
+ (1 << FS4_IDM_IO_CONTROL_DIRECT__SRAM_CLK_EN));
+ }
+
+ if (disable_crypto) {
+ VERBOSE(" - disable crypto clock\n");
+ mmio_setbits_32(CDRU_GENPLL5_CONTROL1,
+ CDRU_GENPLL5_CONTROL1__CHNL1_CRYPTO_AE_CLK);
+ }
+
+ if (disable_raid) {
+ VERBOSE(" - disable raid clock\n");
+ mmio_setbits_32(CDRU_GENPLL5_CONTROL1,
+ CDRU_GENPLL5_CONTROL1__CHNL2_RAID_AE_CLK);
+ }
+
+ if (disable_sram && disable_crypto && disable_raid) {
+ VERBOSE(" - disable root clock\n");
+ mmio_setbits_32(CDRU_GENPLL5_CONTROL1,
+ CDRU_GENPLL5_CONTROL1__CHNL0_DME_CLK);
+ mmio_setbits_32(CDRU_GENPLL2_CONTROL1,
+ CDRU_GENPLL2_CONTROL1__CHNL6_FS4_CLK);
+ }
+
+ INFO("fs4 disable clocks done\n");
+}
diff --git a/plat/brcm/board/stingray/src/ihost_pm.c b/plat/brcm/board/stingray/src/ihost_pm.c
new file mode 100644
index 000000000..9141d3e31
--- /dev/null
+++ b/plat/brcm/board/stingray/src/ihost_pm.c
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2016 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <dmu.h>
+#include <ihost_pm.h>
+#include <platform_def.h>
+
+#define CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_IHOST1 2
+#define CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_IHOST2 1
+#define CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_IHOST3 0
+#define CDRU_MISC_RESET_CONTROL__CDRU_IH1_RESET 9
+#define CDRU_MISC_RESET_CONTROL__CDRU_IH2_RESET 8
+#define CDRU_MISC_RESET_CONTROL__CDRU_IH3_RESET 7
+#define A72_CRM_SOFTRESETN_0 0x480
+#define A72_CRM_SOFTRESETN_1 0x484
+#define A72_CRM_DOMAIN_4_CONTROL 0x810
+#define A72_CRM_DOMAIN_4_CONTROL__DOMAIN_4_ISO_DFT 3
+#define A72_CRM_DOMAIN_4_CONTROL__DOMAIN_4_ISO_MEM 6
+#define A72_CRM_DOMAIN_4_CONTROL__DOMAIN_4_ISO_I_O 0
+#define A72_CRM_SUBSYSTEM_MEMORY_CONTROL_3 0xB4C
+#define MEMORY_PDA_HI_SHIFT 0x0
+#define A72_CRM_PLL_PWR_ON 0x70
+#define A72_CRM_PLL_PWR_ON__PLL0_ISO_PLLOUT 4
+#define A72_CRM_PLL_PWR_ON__PLL0_PWRON_LDO 1
+#define A72_CRM_PLL_PWR_ON__PLL0_PWRON_PLL 0
+#define A72_CRM_SUBSYSTEM_MEMORY_CONTROL_2 0xB48
+#define A72_CRM_PLL_INTERRUPT_STATUS 0x8c
+#define A72_CRM_PLL_INTERRUPT_STATUS__PLL0_LOCK_LOST_STATUS 8
+#define A72_CRM_PLL_INTERRUPT_STATUS__PLL0_LOCK_STATUS 9
+#define A72_CRM_INTERRUPT_ENABLE 0x4
+#define A72_CRM_INTERRUPT_ENABLE__PLL0_INT_ENABLE 4
+#define A72_CRM_PLL_INTERRUPT_ENABLE 0x88
+#define A72_CRM_PLL_INTERRUPT_ENABLE__PLL0_LOCK_STATUS_INT_ENB 9
+#define A72_CRM_PLL_INTERRUPT_ENABLE__PLL0_LOCK_LOST_STATUS_INT_ENB 8
+#define A72_CRM_PLL0_CFG0_CTRL 0x120
+#define A72_CRM_PLL0_CFG1_CTRL 0x124
+#define A72_CRM_PLL0_CFG2_CTRL 0x128
+#define A72_CRM_PLL0_CFG3_CTRL 0x12C
+#define A72_CRM_CORE_CONFIG_DBGCTRL__DBGROMADDRV 0
+#define A72_CRM_CORE_CONFIG_DBGCTRL 0xD50
+#define A72_CRM_CORE_CONFIG_DBGROM_LO 0xD54
+#define A72_CRM_CORE_CONFIG_DBGROM_HI 0xD58
+#define A72_CRM_SUBSYSTEM_CONFIG_1__DBGL1RSTDISABLE 2
+#define A72_CRM_SOFTRESETN_0__CRYSTAL26_SOFTRESETN 0
+#define A72_CRM_SOFTRESETN_0__CRM_PLL0_SOFTRESETN 1
+#define A72_CRM_AXI_CLK_DESC 0x304
+#define A72_CRM_ACP_CLK_DESC 0x308
+#define A72_CRM_ATB_CLK_DESC 0x30C
+#define A72_CRM_PCLKDBG_DESC 0x310
+#define A72_CRM_CLOCK_MODE_CONTROL 0x40
+#define A72_CRM_CLOCK_MODE_CONTROL__CLK_CHANGE_TRIGGER 0
+#define A72_CRM_CLOCK_CONTROL_0 0x200
+#define A72_CRM_CLOCK_CONTROL_0__ARM_HW_SW_ENABLE_SEL 0
+#define A72_CRM_CLOCK_CONTROL_0__AXI_HW_SW_ENABLE_SEL 2
+#define A72_CRM_CLOCK_CONTROL_0__ACP_HW_SW_ENABLE_SEL 4
+#define A72_CRM_CLOCK_CONTROL_0__ATB_HW_SW_ENABLE_SEL 6
+#define A72_CRM_CLOCK_CONTROL_0__PCLKDBG_HW_SW_ENA_SEL 8
+#define A72_CRM_CLOCK_CONTROL_1 0x204
+#define A72_CRM_CLOCK_CONTROL_1__TMON_HW_SW_ENABLE_SEL 6
+#define A72_CRM_CLOCK_CONTROL_1__APB_HW_SW_ENABLE_SEL 8
+#define A72_CRM_SOFTRESETN_0__CRYSTAL26_SOFTRESETN 0
+#define A72_CRM_SOFTRESETN_0__CRM_PLL0_SOFTRESETN 1
+#define A72_CRM_SOFTRESETN_0__AXI_SOFTRESETN 9
+#define A72_CRM_SOFTRESETN_0__ACP_SOFTRESETN 10
+#define A72_CRM_SOFTRESETN_0__ATB_SOFTRESETN 11
+#define A72_CRM_SOFTRESETN_0__PCLKDBG_SOFTRESETN 12
+#define A72_CRM_SOFTRESETN_0__TMON_SOFTRESETN 15
+#define A72_CRM_SOFTRESETN_0__L2_SOFTRESETN 3
+#define A72_CRM_SOFTRESETN_1__APB_SOFTRESETN 8
+
+/* core related regs */
+#define A72_CRM_DOMAIN_0_CONTROL 0x800
+#define A72_CRM_DOMAIN_0_CONTROL__DOMAIN_0_ISO_MEM 0x6
+#define A72_CRM_DOMAIN_0_CONTROL__DOMAIN_0_ISO_I_O 0x0
+#define A72_CRM_DOMAIN_1_CONTROL 0x804
+#define A72_CRM_DOMAIN_1_CONTROL__DOMAIN_1_ISO_MEM 0x6
+#define A72_CRM_DOMAIN_1_CONTROL__DOMAIN_1_ISO_I_O 0x0
+#define A72_CRM_CORE_CONFIG_RVBA0_LO 0xD10
+#define A72_CRM_CORE_CONFIG_RVBA0_MID 0xD14
+#define A72_CRM_CORE_CONFIG_RVBA0_HI 0xD18
+#define A72_CRM_CORE_CONFIG_RVBA1_LO 0xD20
+#define A72_CRM_CORE_CONFIG_RVBA1_MID 0xD24
+#define A72_CRM_CORE_CONFIG_RVBA1_HI 0xD28
+#define A72_CRM_SUBSYSTEM_CONFIG_0 0xC80
+#define A72_CRM_SUBSYSTEM_CONFIG_0__DBGPWRDUP_CFG_SHIFT 4
+#define A72_CRM_SOFTRESETN_0__COREPOR0_SOFTRESETN 4
+#define A72_CRM_SOFTRESETN_0__COREPOR1_SOFTRESETN 5
+#define A72_CRM_SOFTRESETN_1__CORE0_SOFTRESETN 0
+#define A72_CRM_SOFTRESETN_1__DEBUG0_SOFTRESETN 4
+#define A72_CRM_SOFTRESETN_1__CORE1_SOFTRESETN 1
+#define A72_CRM_SOFTRESETN_1__DEBUG1_SOFTRESETN 5
+
+#define SPROC_MEMORY_BISR 0
+
+static int cluster_power_status[PLAT_BRCM_CLUSTER_COUNT] = {CLUSTER_POWER_ON,
+ CLUSTER_POWER_OFF,
+ CLUSTER_POWER_OFF,
+ CLUSTER_POWER_OFF};
+
+void ihost_power_on_cluster(u_register_t mpidr)
+{
+ uint32_t rst, d2xs;
+ uint32_t cluster_id;
+ uint32_t ihost_base;
+#if SPROC_MEMORY_BISR
+ uint32_t bisr, cnt;
+#endif
+ cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+ uint32_t cluster0_freq_sel;
+
+ if (cluster_power_status[cluster_id] == CLUSTER_POWER_ON)
+ return;
+
+ cluster_power_status[cluster_id] = CLUSTER_POWER_ON;
+ INFO("enabling Cluster #%u\n", cluster_id);
+
+ switch (cluster_id) {
+ case 1:
+ rst = (1 << CDRU_MISC_RESET_CONTROL__CDRU_IH1_RESET);
+ d2xs = (1 << CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_IHOST1);
+#if SPROC_MEMORY_BISR
+ bisr = CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST1;
+#endif
+ break;
+ case 2:
+ rst = (1 << CDRU_MISC_RESET_CONTROL__CDRU_IH2_RESET);
+ d2xs = (1 << CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_IHOST2);
+#if SPROC_MEMORY_BISR
+ bisr = CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST2;
+#endif
+ break;
+ case 3:
+ rst = (1 << CDRU_MISC_RESET_CONTROL__CDRU_IH3_RESET);
+ d2xs = (1 << CDRU_CCN_REGISTER_CONTROL_1__D2XS_PD_IHOST3);
+#if SPROC_MEMORY_BISR
+ bisr = CRMU_BISR_PDG_MASK__CRMU_BISR_IHOST3;
+#endif
+ break;
+ default:
+ ERROR("Invalid cluster :%u\n", cluster_id);
+ return;
+ }
+
+ /* Releasing ihost resets */
+ mmio_setbits_32(CDRU_MISC_RESET_CONTROL, rst);
+
+ /* calculate cluster/ihost base address */
+ ihost_base = IHOST0_BASE + cluster_id * IHOST_ADDR_SPACE;
+
+ /* Remove Cluster IO isolation */
+ mmio_clrsetbits_32(ihost_base + A72_CRM_DOMAIN_4_CONTROL,
+ (1 << A72_CRM_DOMAIN_4_CONTROL__DOMAIN_4_ISO_I_O),
+ (1 << A72_CRM_DOMAIN_4_CONTROL__DOMAIN_4_ISO_DFT) |
+ (1 << A72_CRM_DOMAIN_4_CONTROL__DOMAIN_4_ISO_MEM));
+
+ /*
+ * Since BISR sequence requires that all cores of cluster should
+ * have removed I/O isolation hence doing same here.
+ */
+ /* Remove core0 memory IO isolations */
+ mmio_clrsetbits_32(ihost_base + A72_CRM_DOMAIN_0_CONTROL,
+ (1 << A72_CRM_DOMAIN_0_CONTROL__DOMAIN_0_ISO_I_O),
+ (1 << A72_CRM_DOMAIN_0_CONTROL__DOMAIN_0_ISO_MEM));
+
+ /* Remove core1 memory IO isolations */
+ mmio_clrsetbits_32(ihost_base + A72_CRM_DOMAIN_1_CONTROL,
+ (1 << A72_CRM_DOMAIN_1_CONTROL__DOMAIN_1_ISO_I_O),
+ (1 << A72_CRM_DOMAIN_1_CONTROL__DOMAIN_1_ISO_MEM));
+
+#if SPROC_MEMORY_BISR
+ mmio_setbits_32(CRMU_BISR_PDG_MASK, (1 << bisr));
+
+ if (!(mmio_read_32(CDRU_CHIP_STRAP_DATA_LSW) &
+ (1 << CDRU_CHIP_STRAP_DATA_LSW__BISR_BYPASS_MODE))) {
+ /* BISR completion would take max 2 usec */
+ cnt = 0;
+ while (cnt < 2) {
+ udelay(1);
+ if (mmio_read_32(CRMU_CHIP_OTPC_STATUS) &
+ (1 << CRMU_CHIP_OTPC_STATUS__OTP_BISR_LOAD_DONE))
+ break;
+ cnt++;
+ }
+ }
+
+ /* if BISR is not completed, need to be checked with ASIC team */
+ if (((mmio_read_32(CRMU_CHIP_OTPC_STATUS)) &
+ (1 << CRMU_CHIP_OTPC_STATUS__OTP_BISR_LOAD_DONE)) == 0) {
+ WARN("BISR did not completed and need to be addressed\n");
+ }
+#endif
+
+ /* PLL Power up. supply is already on. Turn on PLL LDO/PWR */
+ mmio_write_32(ihost_base + A72_CRM_PLL_PWR_ON,
+ (1 << A72_CRM_PLL_PWR_ON__PLL0_ISO_PLLOUT) |
+ (1 << A72_CRM_PLL_PWR_ON__PLL0_PWRON_LDO) |
+ (1 << A72_CRM_PLL_PWR_ON__PLL0_PWRON_PLL));
+
+ /* 1us in spec; Doubling it to be safe*/
+ udelay(2);
+
+ /* Remove PLL output ISO */
+ mmio_write_32(ihost_base + A72_CRM_PLL_PWR_ON,
+ (1 << A72_CRM_PLL_PWR_ON__PLL0_PWRON_LDO) |
+ (1 << A72_CRM_PLL_PWR_ON__PLL0_PWRON_PLL));
+
+ /*
+ * PLL0 Configuration Control Register
+ * these 4 registers drive the i_pll_ctrl[63:0] input of pll
+ * (16b per register).
+ * the values are derived from the spec (sections 8 and 10).
+ */
+
+ mmio_write_32(ihost_base + A72_CRM_PLL0_CFG0_CTRL, 0x00000000);
+ mmio_write_32(ihost_base + A72_CRM_PLL0_CFG1_CTRL, 0x00008400);
+ mmio_write_32(ihost_base + A72_CRM_PLL0_CFG2_CTRL, 0x00000001);
+ mmio_write_32(ihost_base + A72_CRM_PLL0_CFG3_CTRL, 0x00000000);
+
+ /* Read the freq_sel from cluster 0, which is up already */
+ cluster0_freq_sel = bcm_get_ihost_pll_freq(0);
+ bcm_set_ihost_pll_freq(cluster_id, cluster0_freq_sel);
+
+ udelay(1);
+
+ /* Release clock source reset */
+ mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_0,
+ (1 << A72_CRM_SOFTRESETN_0__CRYSTAL26_SOFTRESETN) |
+ (1 << A72_CRM_SOFTRESETN_0__CRM_PLL0_SOFTRESETN));
+
+ udelay(1);
+
+ /*
+ * Integer division for clks (divider value = n+1).
+ * These are the divisor of ARM PLL clock frequecy.
+ */
+ mmio_write_32(ihost_base + A72_CRM_AXI_CLK_DESC, 0x00000001);
+ mmio_write_32(ihost_base + A72_CRM_ACP_CLK_DESC, 0x00000001);
+ mmio_write_32(ihost_base + A72_CRM_ATB_CLK_DESC, 0x00000004);
+ mmio_write_32(ihost_base + A72_CRM_PCLKDBG_DESC, 0x0000000b);
+
+ /*
+ * clock change trigger - must set to take effect after clock
+ * source change
+ */
+ mmio_setbits_32(ihost_base + A72_CRM_CLOCK_MODE_CONTROL,
+ (1 << A72_CRM_CLOCK_MODE_CONTROL__CLK_CHANGE_TRIGGER));
+
+ /* turn on functional clocks */
+ mmio_setbits_32(ihost_base + A72_CRM_CLOCK_CONTROL_0,
+ (3 << A72_CRM_CLOCK_CONTROL_0__ARM_HW_SW_ENABLE_SEL) |
+ (3 << A72_CRM_CLOCK_CONTROL_0__AXI_HW_SW_ENABLE_SEL) |
+ (3 << A72_CRM_CLOCK_CONTROL_0__ACP_HW_SW_ENABLE_SEL) |
+ (3 << A72_CRM_CLOCK_CONTROL_0__ATB_HW_SW_ENABLE_SEL) |
+ (3 << A72_CRM_CLOCK_CONTROL_0__PCLKDBG_HW_SW_ENA_SEL));
+
+ mmio_setbits_32(ihost_base + A72_CRM_CLOCK_CONTROL_1,
+ (3 << A72_CRM_CLOCK_CONTROL_1__TMON_HW_SW_ENABLE_SEL) |
+ (3 << A72_CRM_CLOCK_CONTROL_1__APB_HW_SW_ENABLE_SEL));
+
+ /* Program D2XS Power Down Registers */
+ mmio_setbits_32(CDRU_CCN_REGISTER_CONTROL_1, d2xs);
+
+ /* Program Core Config Debug ROM Address Registers */
+ /* mark valid for Debug ROM base address */
+ mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_DBGCTRL,
+ (1 << A72_CRM_CORE_CONFIG_DBGCTRL__DBGROMADDRV));
+
+ /* Program Lo and HI address of coresight DBG rom address */
+ mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_DBGROM_LO,
+ (CORESIGHT_BASE_ADDR >> 12) & 0xffff);
+ mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_DBGROM_HI,
+ (CORESIGHT_BASE_ADDR >> 28) & 0xffff);
+
+ /*
+ * Release soft resets of different components.
+ * Order: Bus clocks --> PERIPH --> L2 --> cores
+ */
+
+ /* Bus clocks soft resets */
+ mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_0,
+ (1 << A72_CRM_SOFTRESETN_0__CRYSTAL26_SOFTRESETN) |
+ (1 << A72_CRM_SOFTRESETN_0__CRM_PLL0_SOFTRESETN) |
+ (1 << A72_CRM_SOFTRESETN_0__AXI_SOFTRESETN) |
+ (1 << A72_CRM_SOFTRESETN_0__ACP_SOFTRESETN) |
+ (1 << A72_CRM_SOFTRESETN_0__ATB_SOFTRESETN) |
+ (1 << A72_CRM_SOFTRESETN_0__PCLKDBG_SOFTRESETN));
+
+ mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_1,
+ (1 << A72_CRM_SOFTRESETN_1__APB_SOFTRESETN));
+
+ /* Periph component softreset */
+ mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_0,
+ (1 << A72_CRM_SOFTRESETN_0__TMON_SOFTRESETN));
+
+ /* L2 softreset */
+ mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_0,
+ (1 << A72_CRM_SOFTRESETN_0__L2_SOFTRESETN));
+
+ /* Enable and program Satellite timer */
+ ihost_enable_satellite_timer(cluster_id);
+}
+
+void ihost_power_on_secondary_core(u_register_t mpidr, uint64_t rvbar)
+{
+ uint32_t ihost_base;
+ uint32_t coreid = MPIDR_AFFLVL0_VAL(mpidr);
+ uint32_t cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+
+ ihost_base = IHOST0_BASE + cluster_id * IHOST_ADDR_SPACE;
+ INFO("programming core #%u\n", coreid);
+
+ if (coreid) {
+ /* program the entry point for core1 */
+ mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_RVBA1_LO,
+ rvbar & 0xFFFF);
+ mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_RVBA1_MID,
+ (rvbar >> 16) & 0xFFFF);
+ mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_RVBA1_HI,
+ (rvbar >> 32) & 0xFFFF);
+ } else {
+ /* program the entry point for core */
+ mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_RVBA0_LO,
+ rvbar & 0xFFFF);
+ mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_RVBA0_MID,
+ (rvbar >> 16) & 0xFFFF);
+ mmio_write_32(ihost_base + A72_CRM_CORE_CONFIG_RVBA0_HI,
+ (rvbar >> 32) & 0xFFFF);
+ }
+
+ /* Tell debug logic which processor is up */
+ mmio_setbits_32(ihost_base + A72_CRM_SUBSYSTEM_CONFIG_0,
+ (coreid ?
+ (2 << A72_CRM_SUBSYSTEM_CONFIG_0__DBGPWRDUP_CFG_SHIFT) :
+ (1 << A72_CRM_SUBSYSTEM_CONFIG_0__DBGPWRDUP_CFG_SHIFT)));
+
+ /* releasing soft resets for IHOST core */
+ mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_0,
+ (coreid ?
+ (1 << A72_CRM_SOFTRESETN_0__COREPOR1_SOFTRESETN) :
+ (1 << A72_CRM_SOFTRESETN_0__COREPOR0_SOFTRESETN)));
+
+ mmio_setbits_32(ihost_base + A72_CRM_SOFTRESETN_1,
+ (coreid ?
+ ((1 << A72_CRM_SOFTRESETN_1__CORE1_SOFTRESETN) |
+ (1 << A72_CRM_SOFTRESETN_1__DEBUG1_SOFTRESETN)) :
+ ((1 << A72_CRM_SOFTRESETN_1__CORE0_SOFTRESETN) |
+ (1 << A72_CRM_SOFTRESETN_1__DEBUG0_SOFTRESETN))));
+}
diff --git a/plat/brcm/board/stingray/src/iommu.c b/plat/brcm/board/stingray/src/iommu.c
new file mode 100644
index 000000000..de8b995db
--- /dev/null
+++ b/plat/brcm/board/stingray/src/iommu.c
@@ -0,0 +1,536 @@
+/*
+ * Copyright (c) 2017 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <iommu.h>
+#include <platform_def.h>
+
+#define SMMU_BASE 0x64000000
+#define ARM_SMMU_MAX_NUM_CNTXT_BANK 64
+#define SMMU_CTX_BANK_IDX_SECURE_CRMU 63
+#define ARM_SMMU_NUM_SECURE_MASTER 1
+#define ARM_SMMU_NSNUMCBO (ARM_SMMU_MAX_NUM_CNTXT_BANK - \
+ ARM_SMMU_NUM_SECURE_MASTER)
+#define ARM_SMMU_NSNUMSMRGO (ARM_SMMU_MAX_NUM_CNTXT_BANK - \
+ ARM_SMMU_NUM_SECURE_MASTER)
+/* Reserved Banks. */
+#define SMMU_CTX_BANK_IDX (SMMU_CTX_BANK_IDX_SECURE_CRMU - \
+ ARM_SMMU_NUM_SECURE_MASTER)
+#define NUM_OF_SMRS 1
+
+#define STG1_WITH_STG2_BYPASS 1
+#define ARM_LPAE_PGTBL_PHYS_CRMU 0x880000000
+#define ARM_LPAE_PGTBL_PHYS 0x880200000
+#define ARM_LPAE_PGTBL_PTE_CNT 512
+#define ARM_LPAE_PTE_L1_BLOCK_SIZE 0x40000000
+#define ARM_LPAE_PTE_L1_ADDR_MASK 0x0000FFFFC0000000UL
+#define ARM_LPAE_PTE_TABLE 0x2UL
+#define ARM_LPAE_PTE_VALID 0x1UL
+#define ARM_LPAE_PTE_ATTRINDX 2
+#define ARM_LPAE_PTE_NS 5
+#define ARM_LPAE_PTE_AP 6
+#define ARM_LPAE_PTE_AP_EL1_RW 0x0
+#define ARM_LPAE_PTE_AP_EL0_RW 0x1
+#define ARM_LPAE_PTE_SH 8
+#define ARM_LPAE_PTE_SH_NON 0x0
+#define ARM_LPAE_PTE_SH_OUTER 0x2
+#define ARM_LPAE_PTE_SH_INNER 0x3
+#define ARM_LPAE_PTE_AF 10
+#define ARM_SMMU_RES_SIZE 0x80000
+
+#define ARM_LPAE_PTE_NSTABLE 0x8000000000000000UL
+#define ARM_LPAE_PTE_L1_INDEX_SHIFT 30
+#define ARM_LPAE_PTE_L1_INDEX_MASK 0x1ff
+#define ARM_LPAE_PTE_L0_INDEX_SHIFT 39
+#define ARM_LPAE_PTE_L0_INDEX_MASK 0x1ff
+#define ARM_LPAE_PTE_TABLE_MASK ~(0xfffUL)
+/* Configuration registers */
+#define ARM_SMMU_GR0_sCR0 0x0
+#define sCR0_CLIENTPD (1 << 0)
+#define sCR0_GFRE (1 << 1)
+#define sCR0_GFIE (1 << 2)
+#define sCR0_GCFGFRE (1 << 4)
+#define sCR0_GCFGFIE (1 << 5)
+#define sCR0_USFCFG (1 << 10)
+#define sCR0_VMIDPNE (1 << 11)
+#define sCR0_PTM (1 << 12)
+#define sCR0_FB (1 << 13)
+#define sCR0_VMID16EN (1 << 31)
+#define sCR0_BSU_SHIFT 14
+#define sCR0_BSU_MASK 0x3
+#define ARM_SMMU_SMMU_SCR1 0x4
+#define SCR1_NSNUMCBO_MASK 0xFF
+#define SCR1_NSNUMCBO_SHIFT 0x0
+#define SCR1_NSNUMSMRGO_MASK 0xFF00
+#define SCR1_NSNUMSMRGO_SHIFT 0x8
+
+/* Identification registers */
+#define ARM_SMMU_GR0_ID0 0x20
+#define ARM_SMMU_GR0_ID1 0x24
+#define ARM_SMMU_GR0_ID2 0x28
+#define ARM_SMMU_GR0_ID3 0x2c
+#define ARM_SMMU_GR0_ID4 0x30
+#define ARM_SMMU_GR0_ID5 0x34
+#define ARM_SMMU_GR0_ID6 0x38
+#define ARM_SMMU_GR0_ID7 0x3c
+#define ARM_SMMU_GR0_sGFSR 0x48
+#define ARM_SMMU_GR0_sGFSYNR0 0x50
+#define ARM_SMMU_GR0_sGFSYNR1 0x54
+#define ARM_SMMU_GR0_sGFSYNR2 0x58
+
+#define ID1_PAGESIZE (1U << 31)
+#define ID1_NUMPAGENDXB_SHIFT 28
+#define ID1_NUMPAGENDXB_MASK 7
+#define ID1_NUMS2CB_SHIFT 16
+#define ID1_NUMS2CB_MASK 0xff
+#define ID1_NUMCB_SHIFT 0
+#define ID1_NUMCB_MASK 0xff
+
+/* SMMU global address space */
+#define ARM_SMMU_GR0(smmu) ((smmu)->base)
+#define ARM_SMMU_GR1(smmu) ((smmu)->base + (1 << (smmu)->pgshift))
+
+/* Stream mapping registers */
+#define ARM_SMMU_GR0_SMR(n) (0x800 + (n << 2))
+#define SMR_VALID (1U << 31)
+#define SMR_MASK_SHIFT 16
+#define SMR_ID_SHIFT 0
+
+#define ARM_SMMU_GR0_S2CR(n) (0xc00 + (n << 2))
+#define S2CR_CBNDX_SHIFT 0
+#define S2CR_CBNDX_MASK 0xff
+#define S2CR_TYPE_SHIFT 16
+#define S2CR_TYPE_MASK 0x3
+
+#define ARM_SMMU_GR1_CBA2R(n) (0x800 + (n << 2))
+#define CBA2R_RW64_32BIT (0 << 0)
+#define CBA2R_RW64_64BIT (1 << 0)
+#define CBA2R_VMID_SHIFT 16
+#define CBA2R_VMID_MASK 0xffff
+
+#define ARM_SMMU_GR1_CBAR(n) (0x0 + (n << 2))
+#define CBAR_VMID_SHIFT 0
+#define CBAR_VMID_MASK 0xff
+#define CBAR_S1_BPSHCFG_SHIFT 8
+#define CBAR_S1_BPSHCFG_MASK 3
+#define CBAR_S1_BPSHCFG_NSH 3
+#define CBAR_S1_MEMATTR_SHIFT 12
+#define CBAR_S1_MEMATTR_MASK 0xf
+#define CBAR_S1_MEMATTR_WB 0xf
+#define CBAR_TYPE_SHIFT 16
+#define CBAR_TYPE_MASK 0x3
+#define CBAR_TYPE_S2_TRANS (0 << CBAR_TYPE_SHIFT)
+#define CBAR_TYPE_S1_TRANS_S2_BYPASS (1 << CBAR_TYPE_SHIFT)
+#define CBAR_TYPE_S1_TRANS_S2_FAULT (2 << CBAR_TYPE_SHIFT)
+#define CBAR_TYPE_S1_TRANS_S2_TRANS (3 << CBAR_TYPE_SHIFT)
+#define CBAR_IRPTNDX_SHIFT 24
+#define CBAR_IRPTNDX_MASK 0xff
+
+/* Translation context bank */
+#define ARM_SMMU_CB_BASE(smmu) ((smmu)->base + ((smmu)->size >> 1))
+#define ARM_SMMU_CB(smmu, n) ((n) * (1 << (smmu)->pgshift))
+
+#define ARM_SMMU_CB_SCTLR 0x0
+#define ARM_SMMU_CB_ACTLR 0x4
+#define ARM_SMMU_CB_RESUME 0x8
+#define ARM_SMMU_CB_TTBCR2 0x10
+#define ARM_SMMU_CB_TTBR0 0x20
+#define ARM_SMMU_CB_TTBR1 0x28
+#define ARM_SMMU_CB_TTBCR 0x30
+#define ARM_SMMU_CB_CONTEXTIDR 0x34
+#define ARM_SMMU_CB_S1_MAIR0 0x38
+#define ARM_SMMU_CB_S1_MAIR1 0x3c
+#define ARM_SMMU_CB_PAR 0x50
+#define ARM_SMMU_CB_FSR 0x58
+#define ARM_SMMU_CB_FAR 0x60
+#define ARM_SMMU_CB_FSYNR0 0x68
+#define ARM_SMMU_CB_S1_TLBIVA 0x600
+#define ARM_SMMU_CB_S1_TLBIASID 0x610
+#define ARM_SMMU_CB_S1_TLBIVAL 0x620
+#define ARM_SMMU_CB_S2_TLBIIPAS2 0x630
+#define ARM_SMMU_CB_S2_TLBIIPAS2L 0x638
+#define ARM_SMMU_CB_ATS1PR 0x800
+#define ARM_SMMU_CB_ATSR 0x8f0
+
+#define SCTLR_S1_ASIDPNE (1 << 12)
+#define SCTLR_CFCFG (1 << 7)
+#define SCTLR_CFIE (1 << 6)
+#define SCTLR_CFRE (1 << 5)
+#define SCTLR_E (1 << 4)
+#define SCTLR_AFE (1 << 2)
+#define SCTLR_TRE (1 << 1)
+#define SCTLR_M (1 << 0)
+
+/* ARM LPAE configuration. */
+/**************************************************************/
+/* Register bits */
+#define ARM_32_LPAE_TCR_EAE (1 << 31)
+#define ARM_64_LPAE_S2_TCR_RES1 (1 << 31)
+
+#define ARM_LPAE_TCR_EPD1 (1 << 23)
+
+#define ARM_LPAE_TCR_TG0_4K (0 << 14)
+#define ARM_LPAE_TCR_TG0_64K (1 << 14)
+#define ARM_LPAE_TCR_TG0_16K (2 << 14)
+
+#define ARM_LPAE_TCR_SH0_SHIFT 12
+#define ARM_LPAE_TCR_SH0_MASK 0x3
+#define ARM_LPAE_TCR_SH_NS 0
+#define ARM_LPAE_TCR_SH_OS 2
+#define ARM_LPAE_TCR_SH_IS 3
+
+#define ARM_LPAE_TCR_ORGN0_SHIFT 10
+#define ARM_LPAE_TCR_IRGN0_SHIFT 8
+#define ARM_LPAE_TCR_RGN_MASK 0x3
+#define ARM_LPAE_TCR_RGN_NC 0
+#define ARM_LPAE_TCR_RGN_WBWA 1
+#define ARM_LPAE_TCR_RGN_WT 2
+#define ARM_LPAE_TCR_RGN_WB 3
+
+#define ARM_LPAE_TCR_SL0_SHIFT 6
+#define ARM_LPAE_TCR_SL0_MASK 0x3
+
+#define ARM_LPAE_TCR_T0SZ_SHIFT 0
+#define ARM_LPAE_TCR_SZ_MASK 0xf
+
+#define ARM_LPAE_TCR_PS_SHIFT 16
+#define ARM_LPAE_TCR_PS_MASK 0x7
+
+#define ARM_LPAE_TCR_IPS_SHIFT 32
+#define ARM_LPAE_TCR_IPS_MASK 0x7
+
+#define ARM_LPAE_TCR_PS_32_BIT 0x0ULL
+#define ARM_LPAE_TCR_PS_36_BIT 0x1ULL
+#define ARM_LPAE_TCR_PS_40_BIT 0x2ULL
+#define ARM_LPAE_TCR_PS_42_BIT 0x3ULL
+#define ARM_LPAE_TCR_PS_44_BIT 0x4ULL
+#define ARM_LPAE_TCR_PS_48_BIT 0x5ULL
+
+#define ARM_LPAE_MAIR_ATTR_SHIFT(n) ((n) << 3)
+#define ARM_LPAE_MAIR_ATTR_MASK 0xff
+#define ARM_LPAE_MAIR_ATTR_DEVICE 0x04
+#define ARM_LPAE_MAIR_ATTR_NC 0x44
+#define ARM_LPAE_MAIR_ATTR_WBRWA 0xff
+#define ARM_LPAE_MAIR_ATTR_IDX_NC 0
+#define ARM_LPAE_MAIR_ATTR_IDX_CACHE 1
+#define ARM_LPAE_MAIR_ATTR_IDX_DEV 2
+
+#define TTBRn_ASID_SHIFT 48
+#define TTBCR2_SEP_SHIFT 15
+#define TTBCR2_SEP_UPSTREAM (0x7 << TTBCR2_SEP_SHIFT)
+#define TTBCR2_AS (1 << 4)
+#define TTBCR_T0SZ(ia_bits) (64 - (ia_bits))
+
+#define S2CR_PRIVCFG_SHIFT 24
+#define S2CR_PRIVCFG_MASK 0x3
+
+/**************************************************************/
+
+uint16_t paxc_stream_ids[] = { 0x2000 };
+
+uint16_t paxc_stream_ids_mask[] = { 0x1fff };
+uint16_t crmu_stream_ids[] = { CRMU_STREAM_ID };
+uint16_t crmu_stream_ids_mask[] = { 0x0 };
+
+enum arm_smmu_s2cr_type {
+ S2CR_TYPE_TRANS,
+ S2CR_TYPE_BYPASS,
+ S2CR_TYPE_FAULT,
+};
+
+enum arm_smmu_s2cr_privcfg {
+ S2CR_PRIVCFG_DEFAULT,
+ S2CR_PRIVCFG_DIPAN,
+ S2CR_PRIVCFG_UNPRIV,
+ S2CR_PRIVCFG_PRIV,
+};
+
+struct arm_smmu_smr {
+ uint16_t mask;
+ uint16_t id;
+ uint32_t valid;
+};
+
+struct arm_smmu_s2cr {
+ int count;
+ enum arm_smmu_s2cr_type type;
+ enum arm_smmu_s2cr_privcfg privcfg;
+ uint8_t cbndx;
+};
+
+struct arm_smmu_cfg {
+ uint8_t cbndx;
+ uint8_t irptndx;
+ uint32_t cbar;
+};
+
+struct arm_smmu_device {
+ uint8_t *base;
+ uint32_t streams;
+ unsigned long size;
+ unsigned long pgshift;
+ unsigned long va_size;
+ unsigned long ipa_size;
+ unsigned long pa_size;
+ struct arm_smmu_smr smr[NUM_OF_SMRS];
+ struct arm_smmu_s2cr s2cr[NUM_OF_SMRS];
+ struct arm_smmu_cfg cfg[NUM_OF_SMRS];
+ uint16_t *stream_ids;
+ uint16_t *stream_ids_mask;
+};
+
+void arm_smmu_enable_secure_client_port(void)
+{
+ uintptr_t smmu_base = SMMU_BASE;
+
+ mmio_clrbits_32(smmu_base, sCR0_CLIENTPD);
+}
+
+void arm_smmu_reserve_secure_cntxt(void)
+{
+ uintptr_t smmu_base = SMMU_BASE;
+
+ mmio_clrsetbits_32(smmu_base + ARM_SMMU_SMMU_SCR1,
+ (SCR1_NSNUMSMRGO_MASK | SCR1_NSNUMCBO_MASK),
+ ((ARM_SMMU_NSNUMCBO << SCR1_NSNUMCBO_SHIFT) |
+ (ARM_SMMU_NSNUMSMRGO << SCR1_NSNUMSMRGO_SHIFT)));
+}
+
+static void arm_smmu_smr_cfg(struct arm_smmu_device *smmu, uint32_t index)
+{
+ uint32_t idx = smmu->cfg[index].cbndx;
+ struct arm_smmu_smr *smr = &smmu->smr[index];
+ uint32_t reg = smr->id << SMR_ID_SHIFT | smr->mask << SMR_MASK_SHIFT;
+
+ if (smr->valid)
+ reg |= SMR_VALID;
+
+ mmio_write_32((uintptr_t) (ARM_SMMU_GR0(smmu) +
+ ARM_SMMU_GR0_SMR(idx)), reg);
+}
+
+static void arm_smmu_s2cr_cfg(struct arm_smmu_device *smmu, uint32_t index)
+{
+ uint32_t idx = smmu->cfg[index].cbndx;
+ struct arm_smmu_s2cr *s2cr = &smmu->s2cr[index];
+
+ uint32_t reg = (s2cr->type & S2CR_TYPE_MASK) << S2CR_TYPE_SHIFT |
+ (s2cr->cbndx & S2CR_CBNDX_MASK) << S2CR_CBNDX_SHIFT |
+ (s2cr->privcfg & S2CR_PRIVCFG_MASK) << S2CR_PRIVCFG_SHIFT;
+
+ mmio_write_32((uintptr_t) (ARM_SMMU_GR0(smmu) +
+ ARM_SMMU_GR0_S2CR(idx)), reg);
+}
+
+static void smmu_set_pgtbl(struct arm_smmu_device *smmu,
+ enum iommu_domain dom,
+ uint64_t *pg_table_base)
+{
+ int i, l0_index, l1_index;
+ uint64_t addr, *pte, *l0_base, *l1_base;
+ uint64_t addr_space_limit;
+
+ if (dom == PCIE_PAXC) {
+ addr_space_limit = 0xffffffffff;
+ } else if (dom == DOMAIN_CRMU) {
+ addr_space_limit = 0xffffffff;
+ } else {
+ ERROR("dom is not supported\n");
+ return;
+ }
+
+ l0_base = pg_table_base;
+ /* clear L0 descriptors. */
+ for (i = 0; i < ARM_LPAE_PGTBL_PTE_CNT; i++)
+ l0_base[i] = 0x0;
+
+ addr = 0x0;
+ while (addr < addr_space_limit) {
+ /* find L0 pte */
+ l0_index = ((addr >> ARM_LPAE_PTE_L0_INDEX_SHIFT) &
+ ARM_LPAE_PTE_L0_INDEX_MASK);
+ l1_base = l0_base + ((l0_index + 1) * ARM_LPAE_PGTBL_PTE_CNT);
+
+ /* setup L0 pte if required */
+ pte = l0_base + l0_index;
+ if (*pte == 0x0) {
+ *pte |= ((uint64_t)l1_base & ARM_LPAE_PTE_TABLE_MASK);
+ if (dom == PCIE_PAXC)
+ *pte |= ARM_LPAE_PTE_NSTABLE;
+ *pte |= ARM_LPAE_PTE_TABLE;
+ *pte |= ARM_LPAE_PTE_VALID;
+ }
+
+ /* find L1 pte */
+ l1_index = ((addr >> ARM_LPAE_PTE_L1_INDEX_SHIFT) &
+ ARM_LPAE_PTE_L1_INDEX_MASK);
+ pte = l1_base + l1_index;
+
+ /* setup L1 pte */
+ *pte = 0x0;
+ *pte |= (addr & ARM_LPAE_PTE_L1_ADDR_MASK);
+ if (addr < 0x80000000) {
+ *pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV <<
+ ARM_LPAE_PTE_ATTRINDX);
+ if (dom == PCIE_PAXC)
+ *pte |= (1 << ARM_LPAE_PTE_NS);
+ } else {
+ *pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE <<
+ ARM_LPAE_PTE_ATTRINDX);
+ *pte |= (1 << ARM_LPAE_PTE_NS);
+ }
+ *pte |= (ARM_LPAE_PTE_AP_EL0_RW << ARM_LPAE_PTE_AP);
+ *pte |= (ARM_LPAE_PTE_SH_INNER << ARM_LPAE_PTE_SH);
+ *pte |= (1 << ARM_LPAE_PTE_AF);
+ *pte |= ARM_LPAE_PTE_VALID;
+
+ addr += ARM_LPAE_PTE_L1_BLOCK_SIZE;
+ }
+}
+
+void arm_smmu_create_identity_map(enum iommu_domain dom)
+{
+ struct arm_smmu_device iommu;
+ struct arm_smmu_device *smmu = &iommu;
+ uint32_t reg, reg2;
+ unsigned long long reg64;
+ uint32_t idx;
+ uint16_t asid;
+ unsigned int context_bank_index;
+ unsigned long long pg_table_base;
+
+ smmu->base = (uint8_t *) SMMU_BASE;
+ reg = mmio_read_32((uintptr_t) (ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_ID1));
+ smmu->pgshift = (reg & ID1_PAGESIZE) ? 16 : 12;
+ smmu->size = ARM_SMMU_RES_SIZE;
+ smmu->stream_ids = NULL;
+
+ switch (dom) {
+ case PCIE_PAXC:
+ smmu->stream_ids = &paxc_stream_ids[0];
+ smmu->stream_ids_mask = &paxc_stream_ids_mask[0];
+ smmu->streams = ARRAY_SIZE(paxc_stream_ids);
+ context_bank_index = SMMU_CTX_BANK_IDX;
+ pg_table_base = ARM_LPAE_PGTBL_PHYS;
+ break;
+ case DOMAIN_CRMU:
+ smmu->stream_ids = &crmu_stream_ids[0];
+ smmu->stream_ids_mask = &crmu_stream_ids_mask[0];
+ smmu->streams = ARRAY_SIZE(crmu_stream_ids);
+ context_bank_index = SMMU_CTX_BANK_IDX_SECURE_CRMU;
+ pg_table_base = ARM_LPAE_PGTBL_PHYS_CRMU;
+ break;
+ default:
+ ERROR("domain not supported\n");
+ return;
+ }
+
+ if (smmu->streams > NUM_OF_SMRS) {
+ INFO("can not support more than %d sids\n", NUM_OF_SMRS);
+ return;
+ }
+
+ /* set up iommu dev. */
+ for (idx = 0; idx < smmu->streams; idx++) {
+ /* S2CR. */
+ smmu->s2cr[idx].type = S2CR_TYPE_TRANS;
+ smmu->s2cr[idx].privcfg = S2CR_PRIVCFG_DEFAULT;
+ smmu->s2cr[idx].cbndx = context_bank_index;
+ smmu->cfg[idx].cbndx = context_bank_index;
+ smmu->cfg[idx].cbar = STG1_WITH_STG2_BYPASS << CBAR_TYPE_SHIFT;
+ arm_smmu_s2cr_cfg(smmu, idx);
+
+ /* SMR. */
+ smmu->smr[idx].mask = smmu->stream_ids_mask[idx];
+ smmu->smr[idx].id = smmu->stream_ids[idx];
+ smmu->smr[idx].valid = 1;
+ arm_smmu_smr_cfg(smmu, idx);
+
+ /* CBA2R. 64-bit Translation */
+ mmio_write_32((uintptr_t) (ARM_SMMU_GR1(smmu) +
+ ARM_SMMU_GR1_CBA2R(smmu->cfg[idx].cbndx)),
+ 0x1);
+ /* CBAR.*/
+ reg = smmu->cfg[idx].cbar;
+ reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) |
+ (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
+
+ mmio_write_32((uintptr_t) (ARM_SMMU_GR1(smmu) +
+ ARM_SMMU_GR1_CBAR(smmu->cfg[idx].cbndx)),
+ reg);
+
+ /* TTBCR. */
+ reg64 = (ARM_LPAE_TCR_SH_IS << ARM_LPAE_TCR_SH0_SHIFT) |
+ (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) |
+ (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
+ reg64 |= ARM_LPAE_TCR_TG0_4K;
+ reg64 |= (ARM_LPAE_TCR_PS_40_BIT << ARM_LPAE_TCR_IPS_SHIFT);
+ /* ias 40 bits.*/
+ reg64 |= TTBCR_T0SZ(40) << ARM_LPAE_TCR_T0SZ_SHIFT;
+ /* Disable speculative walks through TTBR1 */
+ reg64 |= ARM_LPAE_TCR_EPD1;
+ reg = (uint32_t) reg64;
+ reg2 = (uint32_t) (reg64 >> 32);
+ reg2 |= TTBCR2_SEP_UPSTREAM;
+ reg2 |= TTBCR2_AS;
+
+ mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
+ ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
+ ARM_SMMU_CB_TTBCR2), reg2);
+
+ mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
+ ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
+ ARM_SMMU_CB_TTBCR), reg);
+
+ /* TTBR0. */
+ asid = smmu->cfg[idx].cbndx;
+ reg64 = pg_table_base;
+ reg64 |= (unsigned long long) asid << TTBRn_ASID_SHIFT;
+
+ mmio_write_64((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
+ ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
+ ARM_SMMU_CB_TTBR0), reg64);
+ /* TTBR1. */
+ reg64 = 0;
+ reg64 |= (unsigned long long) asid << TTBRn_ASID_SHIFT;
+
+ mmio_write_64((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
+ ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
+ ARM_SMMU_CB_TTBR1), reg64);
+ /* MAIR. */
+ reg = (ARM_LPAE_MAIR_ATTR_NC
+ << ARM_LPAE_MAIR_ATTR_SHIFT
+ (ARM_LPAE_MAIR_ATTR_IDX_NC)) |
+ (ARM_LPAE_MAIR_ATTR_WBRWA <<
+ ARM_LPAE_MAIR_ATTR_SHIFT
+ (ARM_LPAE_MAIR_ATTR_IDX_CACHE)) |
+ (ARM_LPAE_MAIR_ATTR_DEVICE <<
+ ARM_LPAE_MAIR_ATTR_SHIFT
+ (ARM_LPAE_MAIR_ATTR_IDX_DEV));
+
+ mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
+ ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
+ ARM_SMMU_CB_S1_MAIR0), reg);
+
+ /* MAIR1. */
+ reg = 0;
+ mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
+ ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
+ ARM_SMMU_CB_S1_MAIR1), reg);
+ /* SCTLR. */
+ reg = SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE | SCTLR_M;
+ /* stage 1.*/
+ reg |= SCTLR_S1_ASIDPNE;
+ mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
+ ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
+ ARM_SMMU_CB_SCTLR), reg);
+ }
+ smmu_set_pgtbl(smmu, dom, (uint64_t *)pg_table_base);
+}
diff --git a/plat/brcm/board/stingray/src/ncsi.c b/plat/brcm/board/stingray/src/ncsi.c
new file mode 100644
index 000000000..58ea9e2d6
--- /dev/null
+++ b/plat/brcm/board/stingray/src/ncsi.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2019-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include <ncsi.h>
+#include <sr_def.h>
+#include <sr_utils.h>
+
+static const char *const io_drives[] = {
+ "2mA", "4mA", "6mA", "8mA",
+ "10mA", "12mA", "14mA", "16mA"
+};
+
+void brcm_stingray_ncsi_init(void)
+{
+ unsigned int i = 0;
+ unsigned int selx = 0;
+
+#if NCSI_IO_DRIVE_STRENGTH_MA == 2
+ selx = 0x0;
+#elif NCSI_IO_DRIVE_STRENGTH_MA == 4
+ selx = 0x1;
+#elif NCSI_IO_DRIVE_STRENGTH_MA == 6
+ selx = 0x2;
+#elif NCSI_IO_DRIVE_STRENGTH_MA == 8
+ selx = 0x3;
+#elif NCSI_IO_DRIVE_STRENGTH_MA == 10
+ selx = 0x4;
+#elif NCSI_IO_DRIVE_STRENGTH_MA == 12
+ selx = 0x5;
+#elif NCSI_IO_DRIVE_STRENGTH_MA == 14
+ selx = 0x6;
+#elif NCSI_IO_DRIVE_STRENGTH_MA == 16
+ selx = 0x7;
+#else
+ ERROR("Unsupported NCSI_IO_DRIVE_STRENGTH_MA. Please check it.\n");
+ return;
+#endif
+ INFO("ncsi io drives: %s\n", io_drives[selx]);
+
+ for (i = 0; i < NITRO_NCSI_IOPAD_CONTROL_NUM; i++) {
+ mmio_clrsetbits_32((NITRO_NCSI_IOPAD_CONTROL_BASE + (i * 4)),
+ PAD_SELX_MASK, PAD_SELX_VALUE(selx));
+ }
+
+ INFO("ncsi init done\n");
+}
diff --git a/plat/brcm/board/stingray/src/paxb.c b/plat/brcm/board/stingray/src/paxb.c
new file mode 100644
index 000000000..89f76d06a
--- /dev/null
+++ b/plat/brcm/board/stingray/src/paxb.c
@@ -0,0 +1,911 @@
+/*
+ * Copyright (c) 2016 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <paxb.h>
+#include <sr_def.h>
+#include <sr_utils.h>
+
+#define PCIE_CORE_PWR_ARR_POWERON 0x8
+#define PCIE_CORE_PWR_ARR_POWEROK 0x4
+#define PCIE_CORE_PWR_POWERON 0x2
+#define PCIE_CORE_PWR_POWEROK 0x1
+
+#define PCIE_CORE_USER_CFG (PCIE_CORE_BASE + 0x38)
+#define PCIE_PAXB_SMMU_SID_CFG (PCIE_CORE_BASE + 0x60)
+#ifdef SID_B8_D1_F1
+#define PAXB_SMMU_SID_CFG_BUS_WIDTH (0x8 << 8)
+#define PAXB_SMMU_SID_CFG_DEV_WIDTH (0x1 << 12)
+#define PAXB_SMMU_SID_CFG_FUN_WIDTH (0x1 << 16)
+#else
+#define PAXB_SMMU_SID_CFG_BUS_WIDTH (0x2 << 8)
+#define PAXB_SMMU_SID_CFG_DEV_WIDTH (0x5 << 12)
+#define PAXB_SMMU_SID_CFG_FUN_WIDTH (0x3 << 16)
+#endif
+
+#define PAXB_APB_TIMEOUT_COUNT_OFFSET 0x034
+
+/* allow up to 5 ms for each power switch to stabilize */
+#define PCIE_CORE_PWR_TIMEOUT_MS 5
+
+/* wait 1 microsecond for PCIe core soft reset */
+#define PCIE_CORE_SOFT_RST_DELAY_US 1
+
+/*
+ * List of PAXB APB registers
+ */
+#define PAXB_BASE 0x48000000
+#define PAXB_BASE_OFFSET 0x4000
+#define PAXB_OFFSET(core) (PAXB_BASE + \
+ (core) * PAXB_BASE_OFFSET)
+
+#define PAXB_CLK_CTRL_OFFSET 0x000
+#define PAXB_EP_PERST_SRC_SEL_MASK (1 << 2)
+#define PAXB_EP_MODE_PERST_MASK (1 << 1)
+#define PAXB_RC_PCIE_RST_OUT_MASK (1 << 0)
+
+#define PAXB_MAX_IMAP_WINDOWS 8
+#define PAXB_IMAP_REG_WIDTH 8
+#define PAXB_IMAP0_REG_WIDTH 4
+#define PAXB_AXUSER_REG_WIDTH 4
+
+#define PAXB_CFG_IND_ADDR_OFFSET 0x120
+#define PAXB_CFG_IND_DATA_OFFSET 0x124
+#define PAXB_CFG_IND_ADDR_MASK 0x1ffc
+#define PAXB_CFG_CFG_TYPE_MASK 0x1
+
+#define PAXB_EP_CFG_ADDR_OFFSET 0x1f8
+#define PAXB_EP_CFG_DATA_OFFSET 0x1fc
+#define PAXB_EP_CFG_ADDR_MASK 0xffc
+#define PAXB_EP_CFG_TYPE_MASK 0x1
+
+#define PAXB_0_DEFAULT_IMAP 0xed0
+#define DEFAULT_ADDR_INVALID BIT(0)
+#define PAXB_0_DEFAULT_IMAP_AXUSER 0xed8
+#define PAXB_0_DEFAULT_IMAP_AXCACHE 0xedc
+#define IMAP_AXCACHE 0xff
+#define OARR_VALID BIT(0)
+#define IMAP_VALID BIT(0)
+
+#define PAXB_IMAP0_BASE_OFFSET 0xc00
+#define PAXB_IARR0_BASE_OFFSET 0xd00
+#define PAXB_IMAP0_OFFSET(idx) (PAXB_IMAP0_BASE_OFFSET + \
+ (idx) * PAXB_IMAP0_REG_WIDTH)
+#define PAXB_IMAP0_WINDOW_SIZE 0x1000
+
+#define PAXB_IMAP2_OFFSET 0xcc0
+#define PAXB_IMAP0_REGS_TYPE_OFFSET 0xcd0
+#define PAXB_IARR2_LOWER_OFFSET 0xd10
+
+#define PAXB_IMAP3_BASE_OFFSET 0xe08
+#define PAXB_IMAP3_OFFSET(idx) (PAXB_IMAP3_BASE_OFFSET + \
+ (idx) * PAXB_IMAP_REG_WIDTH)
+
+#define PAXB_IMAP3_0_AXUSER_B_OFFSET 0xe48
+#define PAXB_IMAP3_0_AXUSER_OFFSET(idx) (PAXB_IMAP3_0_AXUSER_B_OFFSET + \
+ (idx) * PAXB_AXUSER_REG_WIDTH)
+
+#define PAXB_IMAP4_BASE_OFFSET 0xe70
+#define PAXB_IMAP4_OFFSET(idx) (PAXB_IMAP4_BASE_OFFSET + \
+ (idx) * PAXB_IMAP_REG_WIDTH)
+
+#define PAXB_IMAP4_0_AXUSER_B_OFFSET 0xeb0
+#define PAXB_IMAP4_0_AXUSER_OFFSET(idx) (PAXB_IMAP4_0_AXUSER_B_OFFSET + \
+ (idx) * PAXB_AXUSER_REG_WIDTH)
+
+#define PAXB_CFG_LINK_STATUS_OFFSET 0xf0c
+#define PAXB_CFG_PHYLINKUP_MASK (1 << 3)
+#define PAXB_CFG_DL_ACTIVE_MASK (1 << 2)
+
+#define PAXB_IMAP0_0_AXUSER_OFFSET 0xf60
+#define PAXB_IMAP2_AXUSER_OFFSET 0xfe0
+
+/* cacheable write-back, allocate on both reads and writes */
+#define IMAP_ARCACHE 0x0f0
+#define IMAP_AWCACHE 0xf00
+/* normal access, nonsecure access, and data access */
+/* AWQOS:0xe and ARQOS:0xa */
+/* AWPROT:0x2 and ARPROT:0x1 */
+#define IMAP_AXUSER 0x002e002a
+
+/*
+ * List of NIC security and PIPEMUX related registers
+ */
+#define SR_PCIE_NIC_SECURITY_BASE 0x58100000
+#define NS3Z_PCIE_NIC_SECURITY_BASE 0x48100000
+
+#define GITS_TRANSLATER 0x63c30000
+
+#define VENDOR_ID 0x14e4
+#define CFG_RC_DEV_ID 0x434
+#define CFG_RC_DEV_SUBID 0x438
+#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c
+#define PCI_CLASS_BRIDGE_MASK 0xffff00
+#define PCI_CLASS_BRIDGE_SHIFT 8
+#define PCI_CLASS_BRIDGE_PCI 0x0604
+
+/*
+ * List of PAXB RC configuration space registers
+ */
+
+/* first capability list entry */
+#define PCI_CAPABILITY_LIST_OFFSET 0x34
+#define PCI_CAPABILITY_SPEED_OFFSET 0xc
+#define PCI_EP_CAPABILITY_OFFSET 0x10
+
+#define CFG_RC_LINK_STATUS_CTRL_2 0x0dc
+#define CFG_RC_LINK_SPEED_SHIFT 0
+#define CFG_RC_LINK_SPEED_MASK (0xf << CFG_RC_LINK_SPEED_SHIFT)
+
+#define CFG_RC_DEVICE_CAP 0x4d4
+#define CFG_RC_DEVICE_CAP_MPS_SHIFT 0
+#define CFG_RC_DEVICE_CAP_MPS_MASK (0x7 << CFG_RC_DEVICE_CAP_MPS_SHIFT)
+/* MPS 256 bytes */
+#define CFG_RC_DEVICE_CAP_MPS_256B (0x1 << CFG_RC_DEVICE_CAP_MPS_SHIFT)
+/* MPS 512 bytes */
+#define CFG_RC_DEVICE_CAP_MPS_512B (0x2 << CFG_RC_DEVICE_CAP_MPS_SHIFT)
+
+#define CFG_RC_TL_FCIMM_NP_LIMIT 0xa10
+#define CFG_RC_TL_FCIMM_NP_VAL 0x01500000
+#define CFG_RC_TL_FCIMM_P_LIMIT 0xa14
+#define CFG_RC_TL_FCIMM_P_VAL 0x03408080
+
+#define CFG_RC_LINK_CAP 0x4dc
+#define CFG_RC_LINK_CAP_SPEED_SHIFT 0
+#define CFG_RC_LINK_CAP_SPEED_MASK (0xf << CFG_RC_LINK_CAP_SPEED_SHIFT)
+#define CFG_RC_LINK_CAP_WIDTH_SHIFT 4
+#define CFG_RC_LINK_CAP_WIDTH_MASK (0x1f << CFG_RC_LINK_CAP_WIDTH_SHIFT)
+
+#define CFG_LINK_CAP_RC 0x4f0
+#define CFG_RC_DL_ACTIVE_SHIFT 0
+#define CFG_RC_DL_ACTIVE_MASK (0x1 << CFG_RC_DL_ACTIVE_SHIFT)
+#define CFG_RC_SLOT_CLK_SHIFT 1
+#define CFG_RC_SLOT_CLK_MASK (0x1 << CFG_RC_SLOT_CLK_SHIFT)
+
+#define CFG_ROOT_CAP_RC 0x4f8
+#define CFG_ROOT_CAP_LTR_SHIFT 1
+#define CFG_ROOT_CAP_LTR_MASK (0x1 << CFG_ROOT_CAP_LTR_SHIFT)
+
+#define CFG_RC_CLKREQ_ENABLED 0x4fc
+#define CFG_RC_CLKREQ_ENABLED_SHIFT 0
+#define CFG_RC_CLKREQ_ENABLED_MASK (0x1 << CFG_RC_CLKREQ_ENABLED_SHIFT)
+
+#define CFG_RC_COEFF_ADDR 0x638
+
+#define CFG_RC_TL_CTRL_0 0x800
+#define RC_MEM_DW_CHK_MASK 0x03fe
+
+#define CFG_RC_PDL_CTRL_4 0x1010
+#define NPH_FC_INIT_SHIFT 24
+#define NPH_FC_INIT_MASK (U(0xff) << NPH_FC_INIT_SHIFT)
+#define PD_FC_INIT_SHIFT 12
+#define PD_FC_INIT_MASK (0xffff << PD_FC_INIT_SHIFT)
+
+#define CFG_RC_PDL_CTRL_5 0x1014
+#define PH_INIT_SHIFT 0
+#define PH_INIT_MASK (0xff << PH_INIT_SHIFT)
+
+#define DL_STATUS_OFFSET 0x1048
+#define PHYLINKUP BIT(13)
+
+#define PH_INIT 0x10
+#define PD_FC_INIT 0x100
+#define NPH_FC_INIT 0x8
+
+#define SRP_PH_INIT 0x7F
+#define SRP_PD_FC_INIT 0x200
+#define SRP_NPH_FC_INIT 0x7F
+
+#define CFG_ADDR_BUS_NUM_SHIFT 20
+#define CFG_ADDR_DEV_NUM_SHIFT 15
+#define CFG_ADDR_FUNC_NUM_SHIFT 12
+#define CFG_ADDR_REG_NUM_SHIFT 2
+#define CFG_ADDR_REG_NUM_MASK 0x00000ffc
+#define CFG_ADDR_CFG_TYPE_MASK 0x00000003
+
+#define DL_LINK_UP_TIMEOUT_MS 1000
+
+#define CFG_RETRY_STATUS 0xffff0001
+#define CRS_TIMEOUT_MS 5000
+
+/* create EP config data to write */
+#define DEF_BUS_NO 1 /* default bus 1 */
+#define DEF_SLOT_NO 0 /* default slot 0 */
+#define DEF_FN_NO 0 /* default fn 0 */
+
+#define EP_CONFIG_VAL(bus_no, slot, fn, where) \
+ (((bus_no) << CFG_ADDR_BUS_NUM_SHIFT) | \
+ ((slot) << CFG_ADDR_DEV_NUM_SHIFT) | \
+ ((fn) << CFG_ADDR_FUNC_NUM_SHIFT) | \
+ ((where) & CFG_ADDR_REG_NUM_MASK) | \
+ (1 & CFG_ADDR_CFG_TYPE_MASK))
+
+/* PAXB security offset */
+#define PAXB_SECURITY_IDM_OFFSET 0x1c
+#define PAXB_SECURITY_APB_OFFSET 0x24
+#define PAXB_SECURITY_ECAM_OFFSET 0x3c
+
+#define paxb_get_config(type) paxb_get_##type##_config()
+
+static unsigned int paxb_sec_reg_offset[] = {
+ 0x0c, /* PAXB0 AXI */
+ 0x10, /* PAXB1 AXI */
+ 0x14, /* PAXB2 AXI */
+ 0x18, /* PAXB3 AXI */
+ 0x20, /* PAXB4 AXI */
+ 0x28, /* PAXB5 AXI */
+ 0x2c, /* PAXB6 AXI */
+ 0x30, /* PAXB7 AXI */
+ 0x24, /* PAXB APB */
+};
+
+const paxb_cfg *paxb;
+
+/*
+ * Given a PIPEMUX strap and PCIe core index, this function returns 1 if a
+ * PCIe core needs to be enabled
+ */
+int pcie_core_needs_enable(unsigned int core_idx)
+{
+ if (paxb->core_needs_enable)
+ return paxb->core_needs_enable(core_idx);
+
+ return 0;
+}
+
+static void pcie_set_default_tx_coeff(uint32_t core_idx, uint32_t link_width)
+{
+ unsigned int lanes = 0;
+ uint32_t data, addr;
+
+ addr = CFG_RC_COEFF_ADDR;
+ for (lanes = 0; lanes < link_width; lanes = lanes + 2) {
+ data = paxb_rc_cfg_read(core_idx, addr);
+ data &= 0xf0f0f0f0;
+ data |= (7 & 0xf);
+ data |= (7 & 0xf) << 8;
+ data |= (7 & 0xf) << 16;
+ data |= (7 & 0xf) << 24;
+
+ paxb_rc_cfg_write(core_idx, addr, data);
+ addr += 4;
+ }
+}
+
+static int paxb_rc_link_init(void)
+{
+ uint32_t val, link_speed;
+ unsigned int link_width;
+ uint32_t core_idx;
+
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ link_width = paxb->get_link_width(core_idx);
+ if (!link_width) {
+ ERROR("Unsupported PIPEMUX\n");
+ return -EOPNOTSUPP;
+ }
+
+ link_speed = paxb->get_link_speed();
+ /* program RC's link cap reg to advertise proper link width */
+ val = paxb_rc_cfg_read(core_idx, CFG_RC_LINK_CAP);
+ val &= ~CFG_RC_LINK_CAP_WIDTH_MASK;
+ val |= (link_width << CFG_RC_LINK_CAP_WIDTH_SHIFT);
+ paxb_rc_cfg_write(core_idx, CFG_RC_LINK_CAP, val);
+
+ /* program RC's link cap reg to advertise proper link speed */
+ val = paxb_rc_cfg_read(core_idx, CFG_RC_LINK_CAP);
+ val &= ~CFG_RC_LINK_CAP_SPEED_MASK;
+ val |= link_speed << CFG_RC_LINK_CAP_SPEED_SHIFT;
+ paxb_rc_cfg_write(core_idx, CFG_RC_LINK_CAP, val);
+
+ /* also need to program RC's link status control register */
+ val = paxb_rc_cfg_read(core_idx, CFG_RC_LINK_STATUS_CTRL_2);
+ val &= ~(CFG_RC_LINK_SPEED_MASK);
+ val |= link_speed << CFG_RC_LINK_SPEED_SHIFT;
+ paxb_rc_cfg_write(core_idx, CFG_RC_LINK_STATUS_CTRL_2, val);
+
+#ifdef WAR_PLX_PRESET_PARITY_FAIL
+ /* WAR to avoid crash with PLX switch in GEN3*/
+ /* While PRESET, PLX switch is not fixing parity so disabled */
+ val = paxb_rc_cfg_read(core_idx, CFG_RC_REG_PHY_CTL_10);
+ val &= ~(PHY_CTL_10_GEN3_MATCH_PARITY);
+ paxb_rc_cfg_write(core_idx, CFG_RC_REG_PHY_CTL_10, val);
+#endif
+ pcie_set_default_tx_coeff(core_idx, link_width);
+ }
+ return 0;
+}
+
+#ifdef PAXB_LINKUP
+static void paxb_perst_ctrl(unsigned int core_idx, bool assert)
+{
+ uint32_t clk_ctrl = PAXB_OFFSET(core_idx) + PAXB_CLK_CTRL_OFFSET;
+
+ if (assert) {
+ mmio_clrbits_32(clk_ctrl, PAXB_EP_PERST_SRC_SEL_MASK |
+ PAXB_EP_MODE_PERST_MASK |
+ PAXB_RC_PCIE_RST_OUT_MASK);
+ udelay(250);
+ } else {
+ mmio_setbits_32(clk_ctrl, PAXB_RC_PCIE_RST_OUT_MASK);
+ mdelay(100);
+ }
+}
+
+static void paxb_start_link_up(void)
+{
+ unsigned int core_idx;
+ uint32_t val, timeout;
+
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ /* toggle PERST */
+ paxb_perst_ctrl(core_idx, true);
+ paxb_perst_ctrl(core_idx, false);
+
+ timeout = DL_LINK_UP_TIMEOUT_MS;
+ /* wait for Link up */
+ do {
+ val = mmio_read_32(PAXB_OFFSET(core_idx) +
+ PAXB_CFG_LINK_STATUS_OFFSET);
+ if (val & PAXB_CFG_DL_ACTIVE_MASK)
+ break;
+
+ mdelay(1);
+ } while (--timeout);
+
+ if (!timeout)
+ ERROR("PAXB core %u link is down\n", core_idx);
+ }
+}
+#endif
+
+static void pcie_core_soft_reset(unsigned int core_idx)
+{
+ uint32_t offset = core_idx * PCIE_CORE_PWR_OFFSET;
+ uintptr_t ctrl = (uintptr_t)(PCIE_CORE_SOFT_RST_CFG_BASE + offset);
+
+ /* Put PCIe core in soft reset */
+ mmio_clrbits_32(ctrl, PCIE_CORE_SOFT_RST);
+
+ /* Wait for 1 us before pulling PCIe core out of soft reset */
+ udelay(PCIE_CORE_SOFT_RST_DELAY_US);
+
+ mmio_setbits_32(ctrl, PCIE_CORE_SOFT_RST);
+}
+
+static int pcie_core_pwron_switch(uintptr_t ctrl, uintptr_t status,
+ uint32_t mask)
+{
+ uint32_t val;
+ unsigned int timeout = PCIE_CORE_PWR_TIMEOUT_MS;
+
+ /* enable switch */
+ mmio_setbits_32(ctrl, mask);
+
+ /* now wait for it to stabilize */
+ do {
+ val = mmio_read_32(status);
+ if ((val & mask) == mask)
+ return 0;
+ mdelay(1);
+ } while (--timeout);
+
+ return -EIO;
+}
+
+static int pcie_core_pwr_seq(uintptr_t ctrl, uintptr_t status)
+{
+ int ret;
+
+ /*
+ * Enable the switch with the following sequence:
+ * 1. Array weak switch output switch
+ * 2. Array strong switch
+ * 3. Weak switch output acknowledge
+ * 4. Strong switch output acknowledge
+ */
+ ret = pcie_core_pwron_switch(ctrl, status, PCIE_CORE_PWR_ARR_POWERON);
+ if (ret)
+ return ret;
+
+ ret = pcie_core_pwron_switch(ctrl, status, PCIE_CORE_PWR_ARR_POWEROK);
+ if (ret)
+ return ret;
+
+ ret = pcie_core_pwron_switch(ctrl, status, PCIE_CORE_PWR_POWERON);
+ if (ret)
+ return ret;
+
+ ret = pcie_core_pwron_switch(ctrl, status, PCIE_CORE_PWR_POWEROK);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/*
+ * This function enables PCIe core and PAXB memory buffer power, and then
+ * remove the PCIe core from isolation
+ */
+static int pcie_core_pwr_init(unsigned int core_idx)
+{
+ int ret;
+ uint32_t offset = core_idx * PCIE_CORE_PWR_OFFSET;
+ uintptr_t ctrl, status;
+
+ /* enable mem power to PCIe core */
+ ctrl = (uintptr_t)(PCIE_CORE_MEM_PWR_BASE + offset);
+ status = (uintptr_t)(PCIE_CORE_MEM_PWR_STATUS_BASE + offset);
+ ret = pcie_core_pwr_seq(ctrl, status);
+ if (ret) {
+ ERROR("PCIe core mem power failed\n");
+ return ret;
+ }
+
+ /* now enable mem power to PAXB wrapper */
+ ctrl = (uintptr_t)(PCIE_PAXB_MEM_PWR_BASE + offset);
+ status = (uintptr_t)(PCIE_PAXB_MEM_PWR_STATUS_BASE + offset);
+ ret = pcie_core_pwr_seq(ctrl, status);
+ if (ret) {
+ ERROR("PAXB mem power failed\n");
+ return ret;
+ }
+
+ /* now remove power isolation */
+ ctrl = (uintptr_t)(PCIE_CORE_ISO_CFG_BASE + offset);
+ mmio_clrbits_32(ctrl, PCIE_CORE_ISO | PCIE_CORE_MEM_ISO);
+
+ return 0;
+}
+
+static void pcie_ss_reset(void)
+{
+ mmio_setbits_32(CDRU_MISC_RESET_CONTROL,
+ 1 << CDRU_MISC_RESET_CONTROL__CDRU_PCIE_RESET_N_R);
+}
+
+/*
+ * This function reads the PIPEMUX strap, figures out all the PCIe cores that
+ * need to be enabled and enable the mem power for those cores
+ */
+static int pcie_cores_init(void)
+{
+ int ret = 0;
+ uint32_t core_idx;
+
+ if (paxb->pipemux_init) {
+ ret = paxb->pipemux_init();
+ if (ret)
+ return ret;
+ }
+
+ /* bring PCIe subsystem out of reset */
+ pcie_ss_reset();
+
+ /* power up all PCIe cores that will be used as RC */
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ ret = pcie_core_pwr_init(core_idx);
+ if (ret) {
+ ERROR("PCIe core %u power up failed\n", core_idx);
+ return ret;
+ }
+
+ pcie_core_soft_reset(core_idx);
+
+ VERBOSE("PCIe core %u is powered up\n", core_idx);
+ }
+
+ return ret;
+}
+
+void paxb_rc_cfg_write(unsigned int core_idx, unsigned int where,
+ uint32_t val)
+{
+ mmio_write_32(PAXB_OFFSET(core_idx) + PAXB_CFG_IND_ADDR_OFFSET,
+ (where & PAXB_CFG_IND_ADDR_MASK) |
+ PAXB_CFG_CFG_TYPE_MASK);
+ mmio_write_32(PAXB_OFFSET(core_idx) + PAXB_CFG_IND_DATA_OFFSET, val);
+}
+
+unsigned int paxb_rc_cfg_read(unsigned int core_idx, unsigned int where)
+{
+ unsigned int val;
+
+ mmio_write_32(PAXB_OFFSET(core_idx) + PAXB_CFG_IND_ADDR_OFFSET,
+ (where & PAXB_CFG_IND_ADDR_MASK) |
+ PAXB_CFG_CFG_TYPE_MASK);
+ val = mmio_read_32(PAXB_OFFSET(core_idx) + PAXB_CFG_IND_DATA_OFFSET);
+
+ return val;
+}
+
+static void paxb_cfg_mps(void)
+{
+ uint32_t val, core_idx, mps;
+
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ val = paxb_rc_cfg_read(core_idx, CFG_RC_DEVICE_CAP);
+ val &= ~CFG_RC_DEVICE_CAP_MPS_MASK;
+ mps = CFG_RC_DEVICE_CAP_MPS_256B;
+ if (core_idx == 0 || core_idx == 1 ||
+ core_idx == 6 || core_idx == 7) {
+ mps = CFG_RC_DEVICE_CAP_MPS_512B;
+ }
+ val |= mps;
+ paxb_rc_cfg_write(core_idx, CFG_RC_DEVICE_CAP, val);
+ }
+}
+
+static void paxb_cfg_dev_id(void)
+{
+ uint32_t val, core_idx;
+ uint32_t device_id;
+
+ device_id = paxb->device_id;
+
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ /* Set Core in RC mode */
+ mmio_setbits_32(PCIE_CORE_USER_CFG +
+ (core_idx * PCIE_CORE_PWR_OFFSET), 1);
+
+ /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
+ val = paxb_rc_cfg_read(core_idx, PCI_BRIDGE_CTRL_REG_OFFSET);
+ val &= ~PCI_CLASS_BRIDGE_MASK;
+ val |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
+ paxb_rc_cfg_write(core_idx, PCI_BRIDGE_CTRL_REG_OFFSET, val);
+
+ val = (VENDOR_ID << 16) | device_id;
+ paxb_rc_cfg_write(core_idx, CFG_RC_DEV_ID, val);
+
+ val = (device_id << 16) | VENDOR_ID;
+ paxb_rc_cfg_write(core_idx, CFG_RC_DEV_SUBID, val);
+ }
+}
+
+static void paxb_cfg_tgt_trn(void)
+{
+ uint32_t val, core_idx;
+
+ /*
+ * Disable all mem Rd/Wr size check so it allows target read/write
+ * transactions to be more than stipulated DW. As a result, PAXB root
+ * complex will not abort these read/write transcations beyond
+ * stipulated limit
+ */
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ val = paxb_rc_cfg_read(core_idx, CFG_RC_TL_CTRL_0);
+ val &= ~(RC_MEM_DW_CHK_MASK);
+ paxb_rc_cfg_write(core_idx, CFG_RC_TL_CTRL_0, val);
+ }
+}
+
+static void paxb_cfg_pdl_ctrl(void)
+{
+ uint32_t val, core_idx;
+ uint32_t nph, ph, pd;
+
+ /* increase the credit counter to 4 for non-posted header */
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ nph = NPH_FC_INIT;
+ ph = PH_INIT;
+ pd = PD_FC_INIT;
+
+ if (core_idx == 0 || core_idx == 1 ||
+ core_idx == 6 || core_idx == 7) {
+ nph = SRP_NPH_FC_INIT;
+ ph = SRP_PH_INIT;
+ pd = SRP_PD_FC_INIT;
+ }
+ val = paxb_rc_cfg_read(core_idx, CFG_RC_PDL_CTRL_4);
+ val &= ~NPH_FC_INIT_MASK;
+ val &= ~PD_FC_INIT_MASK;
+ val = val | (nph << NPH_FC_INIT_SHIFT);
+ val = val | (pd << PD_FC_INIT_SHIFT);
+ paxb_rc_cfg_write(core_idx, CFG_RC_PDL_CTRL_4, val);
+
+ val = paxb_rc_cfg_read(core_idx, CFG_RC_PDL_CTRL_5);
+ val &= ~PH_INIT_MASK;
+ val = val | (ph << PH_INIT_SHIFT);
+ paxb_rc_cfg_write(core_idx, CFG_RC_PDL_CTRL_5, val);
+
+ /*
+ * ASIC to give more optmized value after further investigation.
+ * till then this is important to have to get similar
+ * performance on all the slots.
+ */
+ paxb_rc_cfg_write(core_idx, CFG_RC_TL_FCIMM_NP_LIMIT,
+ CFG_RC_TL_FCIMM_NP_VAL);
+
+ paxb_rc_cfg_write(core_idx, CFG_RC_TL_FCIMM_P_LIMIT,
+ CFG_RC_TL_FCIMM_P_VAL);
+ }
+}
+
+static void paxb_cfg_clkreq(void)
+{
+ uint32_t val, core_idx;
+
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ val = paxb_rc_cfg_read(core_idx, CFG_RC_CLKREQ_ENABLED);
+ val &= ~CFG_RC_CLKREQ_ENABLED_MASK;
+ paxb_rc_cfg_write(core_idx, CFG_RC_CLKREQ_ENABLED, val);
+ }
+}
+
+static void paxb_cfg_dl_active(bool enable)
+{
+ uint32_t val, core_idx;
+
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ val = paxb_rc_cfg_read(core_idx, CFG_LINK_CAP_RC);
+ if (enable)
+ val |= CFG_RC_DL_ACTIVE_MASK;
+ else
+ val &= ~CFG_RC_DL_ACTIVE_MASK;
+ paxb_rc_cfg_write(core_idx, CFG_LINK_CAP_RC, val);
+ }
+}
+
+static void paxb_cfg_LTR(int enable)
+{
+ uint32_t val, core_idx;
+
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ val = paxb_rc_cfg_read(core_idx, CFG_ROOT_CAP_RC);
+ if (enable)
+ val |= CFG_ROOT_CAP_LTR_MASK;
+ else
+ val &= ~CFG_ROOT_CAP_LTR_MASK;
+ paxb_rc_cfg_write(core_idx, CFG_ROOT_CAP_RC, val);
+ }
+}
+
+static void paxb_ib_regs_bypass(void)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < paxb->num_cores; i++) {
+ if (!pcie_core_needs_enable(i))
+ continue;
+
+ /* Configure Default IMAP window */
+ mmio_write_32(PAXB_OFFSET(i) + PAXB_0_DEFAULT_IMAP,
+ DEFAULT_ADDR_INVALID);
+ mmio_write_32(PAXB_OFFSET(i) + PAXB_0_DEFAULT_IMAP_AXUSER,
+ IMAP_AXUSER);
+ mmio_write_32(PAXB_OFFSET(i) + PAXB_0_DEFAULT_IMAP_AXCACHE,
+ IMAP_AXCACHE);
+
+ /* Configure MSI IMAP window */
+ mmio_setbits_32(PAXB_OFFSET(i) +
+ PAXB_IMAP0_REGS_TYPE_OFFSET,
+ 0x1);
+ mmio_write_32(PAXB_OFFSET(i) + PAXB_IARR0_BASE_OFFSET,
+ GITS_TRANSLATER | OARR_VALID);
+ for (j = 0; j < PAXB_MAX_IMAP_WINDOWS; j++) {
+ mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP0_OFFSET(j),
+ (GITS_TRANSLATER +
+ (j * PAXB_IMAP0_WINDOW_SIZE)) |
+ IMAP_VALID);
+ }
+ }
+}
+
+static void paxb_ib_regs_init(void)
+{
+ unsigned int core_idx;
+
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ /* initialize IARR2 to zero */
+ mmio_write_32(PAXB_OFFSET(core_idx) + PAXB_IARR2_LOWER_OFFSET,
+ 0x0);
+ mmio_setbits_32(PAXB_OFFSET(core_idx) +
+ PAXB_IMAP0_REGS_TYPE_OFFSET,
+ 0x1);
+ }
+}
+
+static void paxb_cfg_apb_timeout(void)
+{
+ unsigned int core_idx;
+
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ /* allow unlimited timeout */
+ mmio_write_32(PAXB_OFFSET(core_idx) +
+ PAXB_APB_TIMEOUT_COUNT_OFFSET,
+ 0xFFFFFFFF);
+ }
+}
+
+static void paxb_smmu_cfg(void)
+{
+ unsigned int core_idx;
+ uint32_t offset;
+ uint32_t val;
+
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+
+ offset = core_idx * PCIE_CORE_PWR_OFFSET;
+ val = mmio_read_32(PCIE_PAXB_SMMU_SID_CFG + offset);
+ val &= ~(0xFFF00);
+ val |= (PAXB_SMMU_SID_CFG_FUN_WIDTH |
+ PAXB_SMMU_SID_CFG_DEV_WIDTH |
+ PAXB_SMMU_SID_CFG_BUS_WIDTH);
+ mmio_write_32(PCIE_PAXB_SMMU_SID_CFG + offset, val);
+ val = mmio_read_32(PCIE_PAXB_SMMU_SID_CFG + offset);
+ VERBOSE("smmu cfg reg 0x%x\n", val);
+ }
+}
+
+static void paxb_cfg_coherency(void)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < paxb->num_cores; i++) {
+ if (!pcie_core_needs_enable(i))
+ continue;
+
+#ifdef USE_DDR
+ mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP2_OFFSET,
+ IMAP_ARCACHE | IMAP_AWCACHE);
+#endif
+
+ mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP0_0_AXUSER_OFFSET,
+ IMAP_AXUSER);
+
+ mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP2_AXUSER_OFFSET,
+ IMAP_AXUSER);
+
+ for (j = 0; j < PAXB_MAX_IMAP_WINDOWS; j++) {
+#ifdef USE_DDR
+ mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP3_OFFSET(j),
+ IMAP_ARCACHE | IMAP_AWCACHE);
+ mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP4_OFFSET(j),
+ IMAP_ARCACHE | IMAP_AWCACHE);
+#endif
+ /* zero out IMAP0 mapping windows for MSI/MSI-X */
+ mmio_write_32(PAXB_OFFSET(i) + PAXB_IMAP0_OFFSET(j),
+ 0x0);
+
+ mmio_write_32(PAXB_OFFSET(i) +
+ PAXB_IMAP3_0_AXUSER_OFFSET(j),
+ IMAP_AXUSER);
+ mmio_write_32(PAXB_OFFSET(i) +
+ PAXB_IMAP4_0_AXUSER_OFFSET(j),
+ IMAP_AXUSER);
+ }
+ }
+}
+
+/*
+ * This function configures all PAXB related blocks to allow non-secure access
+ */
+void paxb_ns_init(enum paxb_type type)
+{
+ unsigned int reg;
+
+ switch (type) {
+ case PAXB_SR:
+ for (reg = 0; reg < ARRAY_SIZE(paxb_sec_reg_offset); reg++) {
+
+ mmio_setbits_32(SR_PCIE_NIC_SECURITY_BASE +
+ paxb_sec_reg_offset[reg], 0x1);
+ }
+ /* Enabled all PAXB's relevant IDM blocks access in non-secure mode */
+ mmio_setbits_32(SR_PCIE_NIC_SECURITY_BASE + PAXB_SECURITY_IDM_OFFSET,
+ 0xffff);
+ break;
+ case PAXB_NS3Z:
+ mmio_setbits_32(NS3Z_PCIE_NIC_SECURITY_BASE +
+ paxb_sec_reg_offset[0], 0x1);
+ mmio_setbits_32(NS3Z_PCIE_NIC_SECURITY_BASE +
+ PAXB_SECURITY_IDM_OFFSET, 0xffff);
+ mmio_setbits_32(NS3Z_PCIE_NIC_SECURITY_BASE +
+ PAXB_SECURITY_APB_OFFSET, 0x7);
+ mmio_setbits_32(NS3Z_PCIE_NIC_SECURITY_BASE +
+ PAXB_SECURITY_ECAM_OFFSET, 0x1);
+ break;
+ }
+}
+
+static int paxb_set_config(void)
+{
+ paxb = paxb_get_config(sr);
+ if (paxb)
+ return 0;
+
+ return -ENODEV;
+}
+
+void paxb_init(void)
+{
+ int ret;
+
+ ret = paxb_set_config();
+ if (ret)
+ return;
+
+ paxb_ns_init(paxb->type);
+
+ ret = pcie_cores_init();
+ if (ret)
+ return;
+
+ if (paxb->phy_init) {
+ ret = paxb->phy_init();
+ if (ret)
+ return;
+ }
+
+ paxb_cfg_dev_id();
+ paxb_cfg_tgt_trn();
+ paxb_cfg_pdl_ctrl();
+ if (paxb->type == PAXB_SR) {
+ paxb_ib_regs_init();
+ paxb_cfg_coherency();
+ } else
+ paxb_ib_regs_bypass();
+
+ paxb_cfg_apb_timeout();
+ paxb_smmu_cfg();
+ paxb_cfg_clkreq();
+ paxb_rc_link_init();
+
+ /* Stingray Doesn't support LTR */
+ paxb_cfg_LTR(false);
+ paxb_cfg_dl_active(true);
+
+ paxb_cfg_mps();
+
+#ifdef PAXB_LINKUP
+ paxb_start_link_up();
+#endif
+ INFO("PAXB init done\n");
+}
diff --git a/plat/brcm/board/stingray/src/paxc.c b/plat/brcm/board/stingray/src/paxc.c
new file mode 100644
index 000000000..44af4b010
--- /dev/null
+++ b/plat/brcm/board/stingray/src/paxc.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2017 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include <iommu.h>
+#include <platform_def.h>
+#include <sr_utils.h>
+
+#define PAXC_BASE 0x60400000
+#define PAXC_AXI_CFG_PF 0x10
+#define PAXC_AXI_CFG_PF_OFFSET(pf) (PAXC_AXI_CFG_PF + (pf) * 4)
+#define PAXC_ARPROT_PF_CFG 0x40
+#define PAXC_AWPROT_PF_CFG 0x44
+
+#define PAXC_ARQOS_PF_CFG 0x48
+#define PAXC_ARQOS_VAL 0xaaaaaaaa
+
+#define PAXC_AWQOS_PF_CFG 0x4c
+#define PAXC_AWQOS_VAL 0xeeeeeeee
+
+#define PAXC_CFG_IND_ADDR_OFFSET 0x1f0
+#define PAXC_CFG_IND_ADDR_MASK 0xffc
+#define PAXC_CFG_IND_DATA_OFFSET 0x1f4
+
+/* offsets for PAXC root complex configuration space registers */
+
+#define PAXC_CFG_ID_OFFSET 0x434
+#define PAXC_RC_VENDOR_ID 0x14e4
+#define PAXC_RC_VENDOR_ID_SHIFT 16
+
+#define PAXC_RC_DEVICE_ID 0xd750
+
+#define PAXC_CFG_LINK_CAP_OFFSET 0x4dc
+#define PAXC_RC_LINK_CAP_SPD_SHIFT 0
+#define PAXC_RC_LINK_CAP_SPD_MASK (0xf << PAXC_RC_LINK_CAP_SPD_SHIFT)
+#define PAXC_RC_LINK_CAP_SPD 3
+#define PAXC_RC_LINK_CAP_WIDTH_SHIFT 4
+#define PAXC_RC_LINK_CAP_WIDTH_MASK (0x1f << PAXC_RC_LINK_CAP_WIDTH_SHIFT)
+#define PAXC_RC_LINK_CAP_WIDTH 16
+
+/* offsets for MHB registers */
+
+#define MHB_BASE 0x60401000
+#define MHB_MEM_PWR_STATUS_PAXC (MHB_BASE + 0x1c0)
+#define MHB_PWR_ARR_POWERON 0x8
+#define MHB_PWR_ARR_POWEROK 0x4
+#define MHB_PWR_POWERON 0x2
+#define MHB_PWR_POWEROK 0x1
+#define MHB_PWR_STATUS_MASK (MHB_PWR_ARR_POWERON | \
+ MHB_PWR_ARR_POWEROK | \
+ MHB_PWR_POWERON | \
+ MHB_PWR_POWEROK)
+
+/* max number of PFs from Nitro that PAXC sees */
+#define MAX_NR_NITRO_PF 8
+
+#ifdef EMULATION_SETUP
+static void paxc_reg_dump(void)
+{
+}
+#else
+/* total number of PAXC registers */
+#define NR_PAXC_REGS 53
+static void paxc_reg_dump(void)
+{
+ uint32_t idx, offset = 0;
+
+ VERBOSE("PAXC register dump start\n");
+ for (idx = 0; idx < NR_PAXC_REGS; idx++, offset += 4)
+ VERBOSE("offset: 0x%x val: 0x%x\n", offset,
+ mmio_read_32(PAXC_BASE + offset));
+ VERBOSE("PAXC register dump end\n");
+}
+#endif /* EMULATION_SETUP */
+
+#ifdef EMULATION_SETUP
+static void mhb_reg_dump(void)
+{
+}
+#else
+#define NR_MHB_REGS 227
+static void mhb_reg_dump(void)
+{
+ uint32_t idx, offset = 0;
+
+ VERBOSE("MHB register dump start\n");
+ for (idx = 0; idx < NR_MHB_REGS; idx++, offset += 4)
+ VERBOSE("offset: 0x%x val: 0x%x\n", offset,
+ mmio_read_32(MHB_BASE + offset));
+ VERBOSE("MHB register dump end\n");
+}
+#endif /* EMULATION_SETUP */
+
+static void paxc_rc_cfg_write(uint32_t where, uint32_t val)
+{
+ mmio_write_32(PAXC_BASE + PAXC_CFG_IND_ADDR_OFFSET,
+ where & PAXC_CFG_IND_ADDR_MASK);
+ mmio_write_32(PAXC_BASE + PAXC_CFG_IND_DATA_OFFSET, val);
+}
+
+static uint32_t paxc_rc_cfg_read(uint32_t where)
+{
+ mmio_write_32(PAXC_BASE + PAXC_CFG_IND_ADDR_OFFSET,
+ where & PAXC_CFG_IND_ADDR_MASK);
+ return mmio_read_32(PAXC_BASE + PAXC_CFG_IND_DATA_OFFSET);
+}
+
+/*
+ * Function to program PAXC root complex link capability register
+ */
+static void paxc_cfg_link_cap(void)
+{
+ uint32_t val;
+
+ val = paxc_rc_cfg_read(PAXC_CFG_LINK_CAP_OFFSET);
+ val &= ~(PAXC_RC_LINK_CAP_SPD_MASK | PAXC_RC_LINK_CAP_WIDTH_MASK);
+ val |= (PAXC_RC_LINK_CAP_SPD << PAXC_RC_LINK_CAP_SPD_SHIFT) |
+ (PAXC_RC_LINK_CAP_WIDTH << PAXC_RC_LINK_CAP_WIDTH_SHIFT);
+ paxc_rc_cfg_write(PAXC_CFG_LINK_CAP_OFFSET, val);
+}
+
+/*
+ * Function to program PAXC root complex vendor ID and device ID
+ */
+static void paxc_cfg_id(void)
+{
+ uint32_t val;
+
+ val = (PAXC_RC_VENDOR_ID << PAXC_RC_VENDOR_ID_SHIFT) |
+ PAXC_RC_DEVICE_ID;
+ paxc_rc_cfg_write(PAXC_CFG_ID_OFFSET, val);
+}
+
+void paxc_init(void)
+{
+ unsigned int pf_index;
+ unsigned int val;
+
+ val = mmio_read_32(MHB_MEM_PWR_STATUS_PAXC);
+ if ((val & MHB_PWR_STATUS_MASK) != MHB_PWR_STATUS_MASK) {
+ INFO("PAXC not powered\n");
+ return;
+ }
+
+ paxc_cfg_id();
+ paxc_cfg_link_cap();
+
+ paxc_reg_dump();
+ mhb_reg_dump();
+
+#ifdef USE_DDR
+ /*
+ * Set AWCACHE and ARCACHE to 0xff (Cacheable write-back,
+ * allocate on both reads and writes) per
+ * recommendation from the ASIC team
+ */
+ val = 0xff;
+#else
+ /* disable IO cache if non-DDR memory is used, e.g., external SRAM */
+ val = 0x0;
+#endif
+ for (pf_index = 0; pf_index < MAX_NR_NITRO_PF; pf_index++)
+ mmio_write_32(PAXC_BASE + PAXC_AXI_CFG_PF_OFFSET(pf_index),
+ val);
+
+ /*
+ * Set ARPROT and AWPROT to enable non-secure access from
+ * PAXC to all PFs, PF0 to PF7
+ */
+ mmio_write_32(PAXC_BASE + PAXC_ARPROT_PF_CFG, 0x22222222);
+ mmio_write_32(PAXC_BASE + PAXC_AWPROT_PF_CFG, 0x22222222);
+
+ mmio_write_32(PAXC_BASE + PAXC_ARQOS_PF_CFG, PAXC_ARQOS_VAL);
+ mmio_write_32(PAXC_BASE + PAXC_AWQOS_PF_CFG, PAXC_AWQOS_VAL);
+
+ INFO("PAXC init done\n");
+}
+
+/*
+ * These defines do not match the regfile but they are renamed in a way such
+ * that they are much more readible
+ */
+
+#define MHB_NIC_SECURITY_BASE 0x60500000
+#define MHB_NIC_PAXC_AXI_NS 0x0008
+#define MHB_NIC_IDM_NS 0x000c
+#define MHB_NIC_MHB_APB_NS 0x0010
+#define MHB_NIC_NITRO_AXI_NS 0x0014
+#define MHB_NIC_PCIE_AXI_NS 0x0018
+#define MHB_NIC_PAXC_APB_NS 0x001c
+#define MHB_NIC_EP_APB_NS 0x0020
+
+#define MHB_NIC_PAXC_APB_S_IDM_SHIFT 5
+#define MHB_NIC_EP_APB_S_IDM_SHIFT 4
+#define MHB_NIC_MHB_APB_S_IDM_SHIFT 3
+#define MHB_NIC_PAXC_AXI_S_IDM_SHIFT 2
+#define MHB_NIC_PCIE_AXI_S_IDM_SHIFT 1
+#define MHB_NIC_NITRO_AXI_S_IDM_SHIFT 0
+
+#define NIC400_NITRO_TOP_NIC_SECURITY_BASE 0x60d00000
+
+#define NITRO_NIC_SECURITY_3_SHIFT 0x14
+#define NITRO_NIC_SECURITY_4_SHIFT 0x18
+#define NITRO_NIC_SECURITY_5_SHIFT 0x1c
+#define NITRO_NIC_SECURITY_6_SHIFT 0x20
+
+void paxc_mhb_ns_init(void)
+{
+ unsigned int val;
+ uintptr_t mhb_nic_gpv = MHB_NIC_SECURITY_BASE;
+#ifndef NITRO_SECURE_ACCESS
+ uintptr_t nic400_nitro_gpv = NIC400_NITRO_TOP_NIC_SECURITY_BASE;
+#endif /* NITRO_SECURE_ACCESS */
+
+ /* set PAXC AXI to allow non-secure access */
+ val = mmio_read_32(mhb_nic_gpv + MHB_NIC_PAXC_AXI_NS);
+ val |= 0x1;
+ mmio_write_32(mhb_nic_gpv + MHB_NIC_PAXC_AXI_NS, val);
+
+ /* set various MHB IDM interfaces to allow non-secure access */
+ val = mmio_read_32(mhb_nic_gpv + MHB_NIC_IDM_NS);
+ val |= (0x1 << MHB_NIC_PAXC_APB_S_IDM_SHIFT);
+ val |= (0x1 << MHB_NIC_EP_APB_S_IDM_SHIFT);
+ val |= (0x1 << MHB_NIC_MHB_APB_S_IDM_SHIFT);
+ val |= (0x1 << MHB_NIC_PAXC_AXI_S_IDM_SHIFT);
+ val |= (0x1 << MHB_NIC_PCIE_AXI_S_IDM_SHIFT);
+ val |= (0x1 << MHB_NIC_NITRO_AXI_S_IDM_SHIFT);
+ mmio_write_32(mhb_nic_gpv + MHB_NIC_IDM_NS, val);
+
+ /* set MHB APB to allow non-secure access */
+ val = mmio_read_32(mhb_nic_gpv + MHB_NIC_MHB_APB_NS);
+ val |= 0x1;
+ mmio_write_32(mhb_nic_gpv + MHB_NIC_MHB_APB_NS, val);
+
+ /* set Nitro AXI to allow non-secure access */
+ val = mmio_read_32(mhb_nic_gpv + MHB_NIC_NITRO_AXI_NS);
+ val |= 0x1;
+ mmio_write_32(mhb_nic_gpv + MHB_NIC_NITRO_AXI_NS, val);
+
+ /* set PCIe AXI to allow non-secure access */
+ val = mmio_read_32(mhb_nic_gpv + MHB_NIC_PCIE_AXI_NS);
+ val |= 0x1;
+ mmio_write_32(mhb_nic_gpv + MHB_NIC_PCIE_AXI_NS, val);
+
+ /* set PAXC APB to allow non-secure access */
+ val = mmio_read_32(mhb_nic_gpv + MHB_NIC_PAXC_APB_NS);
+ val |= 0x1;
+ mmio_write_32(mhb_nic_gpv + MHB_NIC_PAXC_APB_NS, val);
+
+ /* set EP APB to allow non-secure access */
+ val = mmio_read_32(mhb_nic_gpv + MHB_NIC_EP_APB_NS);
+ val |= 0x1;
+ mmio_write_32(mhb_nic_gpv + MHB_NIC_EP_APB_NS, val);
+
+#ifndef NITRO_SECURE_ACCESS
+ /* Set NIC400 to allow non-secure access */
+ mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_3_SHIFT, 0x1);
+ mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_4_SHIFT, 0x1);
+ mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_5_SHIFT, 0x1);
+ mmio_setbits_32(nic400_nitro_gpv + NITRO_NIC_SECURITY_6_SHIFT, 0x1);
+#endif /* NITRO_SECURE_ACCESS */
+}
diff --git a/plat/brcm/board/stingray/src/pm.c b/plat/brcm/board/stingray/src/pm.c
new file mode 100644
index 000000000..a5ac2e705
--- /dev/null
+++ b/plat/brcm/board/stingray/src/pm.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2015 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/ccn.h>
+#include <drivers/delay_timer.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/spinlock.h>
+#include <plat/common/platform.h>
+
+#ifdef USE_PAXC
+#include <chimp.h>
+#endif
+#include <cmn_plat_util.h>
+#include <ihost_pm.h>
+#include <plat_brcm.h>
+#include <platform_def.h>
+
+static uint64_t plat_sec_entrypoint;
+
+/*******************************************************************************
+ * SR handler called when a power domain is about to be turned on. The
+ * mpidr determines the CPU to be turned on.
+ ******************************************************************************/
+static int brcm_pwr_domain_on(u_register_t mpidr)
+{
+ int cpuid;
+
+ cpuid = plat_brcm_calc_core_pos(mpidr);
+ INFO("mpidr :%lu, cpuid:%d\n", mpidr, cpuid);
+
+#ifdef USE_SINGLE_CLUSTER
+ if (cpuid > 1)
+ return PSCI_E_INTERN_FAIL;
+#endif
+
+ ihost_power_on_cluster(mpidr);
+
+ ihost_power_on_secondary_core(mpidr, plat_sec_entrypoint);
+
+ return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * SR handler called when a power domain has just been powered on after
+ * being turned off earlier. The target_state encodes the low power state that
+ * each level has woken up from.
+ ******************************************************************************/
+static void brcm_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ unsigned long cluster_id = MPIDR_AFFLVL1_VAL(read_mpidr());
+
+ assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+ PLAT_LOCAL_STATE_OFF);
+
+ if (target_state->pwr_domain_state[MPIDR_AFFLVL1] ==
+ PLAT_LOCAL_STATE_OFF) {
+ INFO("Cluster #%lu entering to snoop/dvm domain\n", cluster_id);
+ ccn_enter_snoop_dvm_domain(1 << cluster_id);
+ }
+
+ /* Enable the gic cpu interface */
+ plat_brcm_gic_pcpu_init();
+
+ /* Program the gic per-cpu distributor or re-distributor interface */
+ plat_brcm_gic_cpuif_enable();
+
+ INFO("Gic Initialization done for this affinity instance\n");
+}
+
+static void __dead2 brcm_system_reset(void)
+{
+ uint32_t reset_type = SOFT_SYS_RESET_L1;
+
+#ifdef USE_PAXC
+ if (bcm_chimp_is_nic_mode())
+ reset_type = SOFT_RESET_L3;
+#endif
+ INFO("System rebooting - L%d...\n", reset_type);
+
+ plat_soft_reset(reset_type);
+
+ /* Prevent the function to return due to the attribute */
+ while (1)
+ ;
+}
+
+static int brcm_system_reset2(int is_vendor, int reset_type,
+ u_register_t cookie)
+{
+ INFO("System rebooting - L%d...\n", reset_type);
+
+ plat_soft_reset(reset_type);
+
+ /*
+ * plat_soft_reset cannot return (it is a __dead function),
+ * but brcm_system_reset2 has to return some value, even in
+ * this case.
+ */
+ return 0;
+}
+
+/*******************************************************************************
+ * Export the platform handlers via plat_brcm_psci_pm_ops. The ARM Standard
+ * platform will take care of registering the handlers with PSCI.
+ ******************************************************************************/
+const plat_psci_ops_t plat_brcm_psci_pm_ops = {
+ .pwr_domain_on = brcm_pwr_domain_on,
+ .pwr_domain_on_finish = brcm_pwr_domain_on_finish,
+ .system_reset = brcm_system_reset,
+ .system_reset2 = brcm_system_reset2
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ *psci_ops = &plat_brcm_psci_pm_ops;
+ plat_sec_entrypoint = sec_entrypoint;
+
+ return 0;
+}
diff --git a/plat/brcm/board/stingray/src/scp_cmd.c b/plat/brcm/board/stingray/src/scp_cmd.c
new file mode 100644
index 000000000..2aa95194a
--- /dev/null
+++ b/plat/brcm/board/stingray/src/scp_cmd.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <drivers/delay_timer.h>
+
+#include <platform_def.h>
+#include <scp.h>
+#include <scp_cmd.h>
+
+#include "m0_ipc.h"
+
+/*
+ * Reads a response from CRMU MAILBOX
+ * Assumes that access has been granted and locked.
+ * Note that this is just a temporary implementation until
+ * channels are introduced
+ */
+static void scp_read_response(crmu_response_t *resp)
+{
+ uint32_t code;
+
+ code = mmio_read_32(CRMU_MAIL_BOX0);
+ resp->completed = code & MCU_IPC_CMD_DONE_MASK;
+ resp->cmd = code & SCP_CMD_MASK;
+ resp->ret = (code & MCU_IPC_CMD_REPLY_MASK) >> MCU_IPC_CMD_REPLY_SHIFT;
+}
+
+/*
+ * Send a command to SCP and wait for timeout us.
+ * Return: 0 on success
+ * -1 if there was no proper reply from SCP
+ * >0 if there was a response from MCU, but
+ * command completed with an error.
+ */
+int scp_send_cmd(uint32_t cmd, uint32_t param, uint32_t timeout)
+{
+ int ret = -1;
+
+ mmio_write_32(CRMU_MAIL_BOX0, cmd);
+ mmio_write_32(CRMU_MAIL_BOX1, param);
+ do {
+ crmu_response_t scp_resp;
+
+ udelay(1);
+ scp_read_response(&scp_resp);
+ if (scp_resp.completed &&
+ (scp_resp.cmd == cmd)) {
+ /* This command has completed */
+ ret = scp_resp.ret;
+ break;
+ }
+ } while (--timeout);
+
+ return ret;
+}
diff --git a/plat/brcm/board/stingray/src/scp_utils.c b/plat/brcm/board/stingray/src/scp_utils.c
new file mode 100644
index 000000000..1d82ceff1
--- /dev/null
+++ b/plat/brcm/board/stingray/src/scp_utils.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2017-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+
+#include <bcm_elog_ddr.h>
+#include <brcm_mhu.h>
+#include <brcm_scpi.h>
+#include <chimp.h>
+#include <cmn_plat_util.h>
+#include <ddr_init.h>
+#include <scp.h>
+#include <scp_cmd.h>
+#include <scp_utils.h>
+
+#include "m0_cfg.h"
+#include "m0_ipc.h"
+
+#ifdef BCM_ELOG
+static void prepare_elog(void)
+{
+#if (CLEAN_DDR && !defined(MMU_DISABLED))
+ /*
+ * Now DDR has been initialized. We want to copy all the logs in SRAM
+ * into DDR so we will have much more space to store the logs in the
+ * next boot stage
+ */
+ bcm_elog_copy_log((void *)BCM_ELOG_BL31_BASE,
+ MIN(BCM_ELOG_BL2_SIZE, BCM_ELOG_BL31_SIZE)
+ );
+
+ /*
+ * We are almost at the end of BL2, and we can stop log here so we do
+ * not need to add 'bcm_elog_exit' to the standard BL2 code. The
+ * benefit of capturing BL2 logs after this is very minimal in a
+ * production system.
+ */
+ bcm_elog_exit();
+#endif
+
+ /*
+ * Notify CRMU that now it should pull logs from DDR instead of from
+ * FS4 SRAM.
+ */
+ SCP_WRITE_CFG(flash_log.can_use_ddr, 1);
+}
+#endif
+
+bool is_crmu_alive(void)
+{
+ return (scp_send_cmd(MCU_IPC_MCU_CMD_NOP, 0, SCP_CMD_DEFAULT_TIMEOUT_US)
+ == 0);
+}
+
+bool bcm_scp_issue_sys_reset(void)
+{
+ return (scp_send_cmd(MCU_IPC_MCU_CMD_L1_RESET, 0,
+ SCP_CMD_DEFAULT_TIMEOUT_US));
+}
+
+/*
+ * Note that this is just a temporary implementation until
+ * channels are introduced
+ */
+
+int plat_bcm_bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info)
+{
+ int scp_patch_activated, scp_patch_version;
+#ifndef EMULATION_SETUP
+ uint8_t active_ch_bitmap, i;
+#endif
+ uint32_t reset_state = 0;
+ uint32_t mcu_ap_init_param = 0;
+
+ /*
+ * First check if SCP patch has already been loaded
+ * Send NOP command and see if there is a valid response
+ */
+ scp_patch_activated =
+ (scp_send_cmd(MCU_IPC_MCU_CMD_NOP, 0,
+ SCP_CMD_DEFAULT_TIMEOUT_US) == 0);
+ if (scp_patch_activated) {
+ INFO("SCP Patch is already active.\n");
+
+ reset_state = SCP_READ_CFG(board_cfg.reset_state);
+ mcu_ap_init_param = SCP_READ_CFG(board_cfg.mcu_init_param);
+
+ /* Clear reset state, it's been already read */
+ SCP_WRITE_CFG(board_cfg.reset_state, 0);
+
+ if (mcu_ap_init_param & MCU_PATCH_LOADED_BY_NITRO) {
+ /*
+ * Reset "MCU_PATCH_LOADED_BY_NITRO" flag, but
+ * Preserve any other flags we don't deal with here
+ */
+ INFO("AP booted by Nitro\n");
+ SCP_WRITE_CFG(
+ board_cfg.mcu_init_param,
+ mcu_ap_init_param &
+ ~MCU_PATCH_LOADED_BY_NITRO
+ );
+ }
+ } else {
+ /*
+ * MCU Patch not loaded, so load it.
+ * MCU patch stamps critical points in REG9 (debug test-point)
+ * Display its last content here. This helps to locate
+ * where crash occurred if a CRMU watchdog kicked in.
+ */
+ int ret;
+
+ INFO("MCU Patch Point: 0x%x\n",
+ mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG9));
+
+ ret = download_scp_patch((void *)scp_bl2_image_info->image_base,
+ scp_bl2_image_info->image_size);
+ if (ret != 0)
+ return ret;
+
+ VERBOSE("SCP Patch loaded OK.\n");
+
+ ret = scp_send_cmd(MCU_IPC_MCU_CMD_INIT,
+ MCU_PATCH_LOADED_BY_AP,
+ SCP_CMD_SCP_BOOT_TIMEOUT_US);
+ if (ret) {
+ ERROR("SCP Patch could not initialize; error %d\n",
+ ret);
+ return ret;
+ }
+
+ INFO("SCP Patch successfully initialized.\n");
+ }
+
+ scp_patch_version = scp_send_cmd(MCU_IPC_MCU_CMD_GET_FW_VERSION, 0,
+ SCP_CMD_DEFAULT_TIMEOUT_US);
+ INFO("SCP Patch version :0x%x\n", scp_patch_version);
+
+ /* Next block just reports current AVS voltages (if applicable) */
+ {
+ uint16_t vcore_mv, ihost03_mv, ihost12_mv;
+
+ vcore_mv = SCP_READ_CFG16(vcore.millivolts) +
+ SCP_READ_CFG8(vcore.avs_cfg.additive_margin);
+ ihost03_mv = SCP_READ_CFG16(ihost03.millivolts) +
+ SCP_READ_CFG8(ihost03.avs_cfg.additive_margin);
+ ihost12_mv = SCP_READ_CFG16(ihost12.millivolts) +
+ SCP_READ_CFG8(ihost12.avs_cfg.additive_margin);
+
+ if (vcore_mv || ihost03_mv || ihost12_mv) {
+ INFO("AVS voltages from cfg (including margin)\n");
+ if (vcore_mv > 0)
+ INFO("%s\tVCORE: %dmv\n",
+ SCP_READ_CFG8(vcore.avs_cfg.avs_set) ?
+ "*" : "n/a", vcore_mv);
+ if (ihost03_mv > 0)
+ INFO("%s\tIHOST03: %dmv\n",
+ SCP_READ_CFG8(ihost03.avs_cfg.avs_set) ?
+ "*" : "n/a", ihost03_mv);
+ if (ihost12_mv > 0)
+ INFO("%s\tIHOST12: %dmv\n",
+ SCP_READ_CFG8(ihost12.avs_cfg.avs_set) ?
+ "*" : "n/a", ihost12_mv);
+ } else {
+ INFO("AVS settings not applicable\n");
+ }
+ }
+
+#if (CLEAN_DDR && !defined(MMU_DISABLED) && !defined(EMULATION_SETUP))
+ /* This will clean the DDR and enable ECC if set */
+ check_ddr_clean();
+#endif
+
+#if (WARMBOOT_DDR_S3_SUPPORT && ELOG_STORE_MEDIA_DDR)
+ elog_init_ddr_log();
+#endif
+
+#ifdef BCM_ELOG
+ /* Prepare ELOG to use DDR */
+ prepare_elog();
+#endif
+
+#ifndef EMULATION_SETUP
+ /* Ask ddr_init to save obtained DDR information into DDR */
+ ddr_info_save();
+#endif
+
+ /*
+ * Configure TMON DDR address.
+ * This cfg is common for all cases
+ */
+ SCP_WRITE_CFG(tmon_cfg.ddr_desc, TMON_SHARED_DDR_ADDRESS);
+
+ if (reset_state == SOFT_RESET_L3 && !mcu_ap_init_param) {
+ INFO("SCP configuration after L3 RESET done.\n");
+ return 0;
+ }
+
+ if (bcm_chimp_is_nic_mode())
+ /* Configure AP WDT to not reset the NIC interface */
+ SCP_WRITE_CFG(board_cfg.apwdt_reset_type, SOFT_RESET_L3);
+
+#if (WARMBOOT_DDR_S3_SUPPORT && ELOG_STORE_MEDIA_DDR)
+ /* When AP WDog triggers perform L3 reset if DDR err logging enabled */
+ SCP_WRITE_CFG(board_cfg.apwdt_reset_type, SOFT_RESET_L3);
+#endif
+
+#ifndef EMULATION_SETUP
+
+#ifdef DDR_SCRUB_ENA
+ ddr_scrub_enable();
+#endif
+ /* Fill the Active channel information */
+ active_ch_bitmap = get_active_ddr_channel();
+ for (i = 0; i < MAX_NR_DDR_CH; i++)
+ SCP_WRITE_CFG(ddr_cfg.ddr_cfg[i],
+ (active_ch_bitmap & BIT(i)) ? 1 : 0);
+#endif
+ return 0;
+}
diff --git a/plat/brcm/board/stingray/src/sdio.c b/plat/brcm/board/stingray/src/sdio.c
new file mode 100644
index 000000000..aa2b71acb
--- /dev/null
+++ b/plat/brcm/board/stingray/src/sdio.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2019-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <sdio.h>
+#include <sr_def.h>
+#include <sr_utils.h>
+
+const SDIO_CFG sr_sdio0_cfg = {
+ .cfg_base = SR_IPROC_SDIO0_CFG_BASE,
+ .sid_base = SR_IPROC_SDIO0_SID_BASE,
+ .io_ctrl_base = SR_IPROC_SDIO0_IOCTRL_BASE,
+ .pad_base = SR_IPROC_SDIO0_PAD_BASE,
+};
+const SDIO_CFG sr_sdio1_cfg = {
+ .cfg_base = SR_IPROC_SDIO1_CFG_BASE,
+ .sid_base = SR_IPROC_SDIO1_SID_BASE,
+ .io_ctrl_base = SR_IPROC_SDIO1_IOCTRL_BASE,
+ .pad_base = SR_IPROC_SDIO1_PAD_BASE,
+};
+
+void brcm_stingray_sdio_init(void)
+{
+ unsigned int val;
+ const SDIO_CFG *sdio0_cfg, *sdio1_cfg;
+
+ sdio0_cfg = &sr_sdio0_cfg;
+ sdio1_cfg = &sr_sdio1_cfg;
+
+ INFO("set sdio0 caps\n");
+ /* SDIO0 CAPS0 */
+ val = SDIO0_CAP0_CFG;
+ INFO("caps0 0x%x\n", val);
+ mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_CAP0, val);
+
+ /* SDIO0 CAPS1 */
+ val = SDIO0_CAP1_CFG;
+ INFO("caps1 0x%x\n", val);
+ mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_CAP1, val);
+
+ mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_0,
+ SDIO_PRESETVAL0);
+ mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_1,
+ SDIO_PRESETVAL1);
+ mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_2,
+ SDIO_PRESETVAL2);
+ mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_3,
+ SDIO_PRESETVAL3);
+ mmio_write_32(sdio0_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_4,
+ SDIO_PRESETVAL4);
+
+ val = SR_SID_VAL(0x3, 0x0, 0x2) << SDIO_SID_SHIFT;
+ mmio_write_32(sdio0_cfg->sid_base + ICFG_SDIO_SID_ARADDR, val);
+ mmio_write_32(sdio0_cfg->sid_base + ICFG_SDIO_SID_AWADDR, val);
+
+ val = mmio_read_32(sdio0_cfg->io_ctrl_base);
+ val &= ~(0xff << 23); /* Clear ARCACHE and AWCACHE */
+ val |= (0xb7 << 23); /* Set ARCACHE and AWCACHE */
+ mmio_write_32(sdio0_cfg->io_ctrl_base, val);
+
+ mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_CLK,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA0,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA1,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA2,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA3,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA4,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA5,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA6,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_DATA7,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio0_cfg->pad_base + PAD_SDIO_CMD,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+
+ INFO("set sdio1 caps\n");
+
+ /* SDIO1 CAPS0 */
+ val = SDIO1_CAP0_CFG;
+ INFO("caps0 0x%x\n", val);
+ mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_CAP0, val);
+ /* SDIO1 CAPS1 */
+ val = SDIO1_CAP1_CFG;
+ INFO("caps1 0x%x\n", val);
+ mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_CAP1, val);
+
+ mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_0,
+ SDIO_PRESETVAL0);
+ mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_1,
+ SDIO_PRESETVAL1);
+ mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_2,
+ SDIO_PRESETVAL2);
+ mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_3,
+ SDIO_PRESETVAL3);
+ mmio_write_32(sdio1_cfg->cfg_base + ICFG_SDIO_STRAPSTATUS_4,
+ SDIO_PRESETVAL4);
+
+ val = SR_SID_VAL(0x3, 0x0, 0x3) << SDIO_SID_SHIFT;
+ mmio_write_32(sdio1_cfg->sid_base + ICFG_SDIO_SID_ARADDR, val);
+ mmio_write_32(sdio1_cfg->sid_base + ICFG_SDIO_SID_AWADDR, val);
+
+ val = mmio_read_32(sdio1_cfg->io_ctrl_base);
+ val &= ~(0xff << 23); /* Clear ARCACHE and AWCACHE */
+ val |= (0xb7 << 23); /* Set ARCACHE and AWCACHE */
+ mmio_write_32(sdio1_cfg->io_ctrl_base, val);
+
+ mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_CLK,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA0,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA1,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA2,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA3,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA4,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA5,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA6,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_DATA7,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+ mmio_clrsetbits_32(sdio1_cfg->pad_base + PAD_SDIO_CMD,
+ PAD_SDIO_MASK, PAD_SDIO_VALUE);
+
+ INFO("sdio init done\n");
+}
diff --git a/plat/brcm/board/stingray/src/sr_paxb_phy.c b/plat/brcm/board/stingray/src/sr_paxb_phy.c
new file mode 100644
index 000000000..7380e09a3
--- /dev/null
+++ b/plat/brcm/board/stingray/src/sr_paxb_phy.c
@@ -0,0 +1,806 @@
+/*
+ * Copyright (c) 2019-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <paxb.h>
+#include <sr_def.h>
+#include <sr_utils.h>
+
+/* total number of PCIe Phys */
+#define NUM_OF_PCIE_SERDES 8
+
+#define CFG_RC_PMI_ADDR 0x1130
+#define PMI_RX_TERM_SEQ ((0x1 << 27) | (0x1ff << 16) | (0xd090))
+#define PMI_RX_TERM_VAL 0x4c00
+#define PMI_PLL_CTRL_4 0xd0b4
+#define PMI_SERDES_CLK_ENABLE (1 << 12)
+
+#define WAR_PLX_PRESET_PARITY_FAIL
+
+#define CFG_RC_REG_PHY_CTL_10 0x1838
+#define PHY_CTL_10_GEN3_MATCH_PARITY (1 << 15)
+
+#define PMI_X8_CORE0_7_PATCH_SEQ ((0x1 << 27) | (0x1ff << 16) | (0xd2a5))
+#define PMI_X8_CORE0_7_PATCH_VAL 0xd864
+
+#define PMI_ADDR_BCAST(addr) ((0x1 << 27) | (0x1ff << 16) | (addr))
+#define PMI_ADDR_LANE0(addr) ((0x1 << 27) | (addr))
+#define PMI_ADDR_LANE1(addr) ((0x1 << 27) | (0x1 << 16) | (addr))
+
+#define MERLIN16_PCIE_BLK2_PWRMGMT_7 ((0x1 << 27) | (0x1ff << 16) | 0x1208)
+#define MERLIN16_PCIE_BLK2_PWRMGMT_8 ((0x1 << 27) | (0x1ff << 16) | 0x1209)
+#define MERLIN16_AMS_TX_CTRL_5 ((0x1 << 27) | (0x1ff << 16) | 0xd0a5)
+#define MERLIN16_AMS_TX_CTRL_5_VAL \
+ ((1 << 13) | (1 << 12) | (1 << 11) | (1 << 10))
+#define MERLIN16_PCIE_BLK2_PWRMGMT_7_VAL 0x96
+#define MERLIN16_PCIE_BLK2_PWRMGMT_8_VAL 0x12c
+
+#define CFG_RC_PMI_WDATA 0x1134
+#define CFG_RC_WCMD_SHIFT 31
+#define CFG_RC_WCMD_MASK ((uint32_t)1U << CFG_RC_WCMD_SHIFT)
+#define CFG_RC_RCMD_SHIFT 30
+#define CFG_RC_RCMD_MASK ((uint32_t)1U << CFG_RC_RCMD_SHIFT)
+#define CFG_RC_RWCMD_MASK (CFG_RC_RCMD_MASK | CFG_RC_WCMD_MASK)
+#define CFG_RC_PMI_RDATA 0x1138
+#define CFG_RC_RACK_SHIFT 31
+#define CFG_RC_RACK_MASK ((uint32_t)1U << CFG_RC_RACK_SHIFT)
+
+/* allow up to 5 ms for PMI write to finish */
+#define PMI_TIMEOUT_MS 5
+
+/* in 2x8 RC mode, one needs to patch up Serdes 3 and 7 for link to come up */
+#define SERDES_PATCH_PIPEMUX_INDEX 0x3
+#define SERDES_PATCH_INDEX 0x8
+
+#define DSC_UC_CTRL 0xd00d
+#define DSC_UC_CTRL_RDY_CMD (1 << 7)
+#define LANE_DBG_RST_CTRL 0xd164
+#define UC_A_CLK_CTRL0 0xd200
+#define UC_A_RST_CTRL0 0xd201
+#define UC_A_AHB_CTRL0 0xd202
+#define UC_A_AHB_STAT0 0xd203
+#define UC_A_AHB_WADDR_LSW 0xd204
+#define UC_A_AHB_WADDR_MSW 0xd205
+#define UC_A_AHB_WDATA_LSW 0xd206
+#define UC_A_AHB_WDATA_MSW 0xd207
+#define UC_A_AHB_RADDR_LSW 0xd208
+#define UC_A_AHB_RADDR_MSW 0xd209
+#define UC_A_AHB_RDATA_LSW 0xd20a
+#define UC_A_AHB_RDATA_MSW 0xd20b
+#define UC_VERSION_NUM 0xd230
+#define DSC_SM_CTL22 0xd267
+#define UC_DBG1 0xd251
+
+#define LOAD_UC_CHECK 0
+#define UC_RAM_INIT_TIMEOUT 100
+#define UC_RAM_CONTROL 0xd225
+#define UC_INIT_TIMEOUT 100
+#define SIZE_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+#define SZ_4 4
+#define GET_2_BYTES(p, i) ((uint16_t)p[i] | (uint16_t)p[i+1] << 8)
+
+/*
+ * List of PCIe LCPLL related registers
+ *
+ * LCPLL channel 0 provides the Serdes pad clock when running in RC mode
+ */
+#define PCIE_LCPLL_BASE 0x40000000
+
+#define PCIE_LCPLL_CTRL0_OFFSET 0x00
+#define PCIE_LCPLL_RESETB_SHIFT 31
+#define PCIE_LCPLL_RESETB_MASK BIT(PCIE_LCPLL_RESETB_SHIFT)
+#define PCIE_LCPLL_P_RESETB_SHIFT 30
+#define PCIE_LCPLL_P_RESETB_MASK BIT(PCIE_LCPLL_P_RESETB_SHIFT)
+
+#define PCIE_LCPLL_CTRL3_OFFSET 0x0c
+#define PCIE_LCPLL_EN_CTRL_SHIFT 16
+#define PCIE_LCPLL_CM_ENA 0x1a
+#define PCIE_LCPLL_CM_BUF_ENA 0x18
+#define PCIE_LCPLL_D2C2_ENA 0x2
+#define PCIE_LCPLL_REF_CLK_SHIFT 1
+#define PCIE_LCPLL_REF_CLK_MASK BIT(PCIE_LCPLL_REF_CLK_SHIFT)
+#define PCIE_LCPLL_CTRL13_OFFSET 0x34
+#define PCIE_LCPLL_D2C2_CTRL_SHIFT 16
+#define PCIE_LCPLL_D2C2_TERM_DISC 0xe0
+
+#define PCIE_LCPLL_STATUS_OFFSET 0x40
+#define PCIE_LCPLL_LOCK_SHIFT 12
+#define PCIE_LCPLL_LOCK_MASK BIT(PCIE_LCPLL_LOCK_SHIFT)
+
+#define PCIE_PIPE_MUX_RC_MODE_OVERRIDE_CFG 0x114
+#define PCIE_TX_CLKMASTER_CTRL_OVERRIDE_CFG 0x11c
+
+/* wait 500 microseconds for PCIe LCPLL to power up */
+#define PCIE_LCPLL_DELAY_US 500
+
+/* allow up to 5 ms for PCIe LCPLL VCO to lock */
+#define PCIE_LCPLL_TIMEOUT_MS 5
+
+#define PCIE_PIPE_MUX_CONFIGURATION_CFG 0x4000010c
+
+#define PCIE_PIPEMUX_SHIFT 19
+#define PCIE_PIPEMUX_MASK 0xf
+
+/* keep track of PIPEMUX index to use */
+static unsigned int pipemux_idx;
+
+/*
+ * PCIe PIPEMUX lookup table
+ *
+ * Each array index represents a PIPEMUX strap setting
+ * The array element represents a bitmap where a set bit means the PCIe core
+ * needs to be enabled as RC
+ */
+static uint8_t pipemux_table[] = {
+ /* PIPEMUX = 0, EP 1x16 */
+ 0x00,
+ /* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
+ 0x80,
+ /* PIPEMUX = 2, EP 4x4 */
+ 0x00,
+ /* PIPEMUX = 3, RC 2x8, cores 0, 7 */
+ 0x81,
+ /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
+ 0xc3,
+ /* PIPEMUX = 5, RC 8x2, all 8 cores */
+ 0xff,
+ /* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
+ 0xcd,
+ /* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
+ 0xfd,
+ /* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
+ 0xf0,
+ /* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
+ 0xc0,
+ /* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
+ 0x42,
+ /* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
+ 0x3c,
+ /* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
+ 0xfc,
+ /* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
+ 0x4c,
+};
+
+/*
+ * Return 1 if pipemux strap is supported
+ */
+static int pipemux_strap_is_valid(uint32_t pipemux)
+{
+ if (pipemux < ARRAY_SIZE(pipemux_table))
+ return 1;
+ else
+ return 0;
+}
+
+/*
+ * Read the PCIe PIPEMUX from strap
+ */
+static uint32_t pipemux_strap_read(void)
+{
+ uint32_t pipemux;
+
+ pipemux = mmio_read_32(PCIE_PIPE_MUX_CONFIGURATION_CFG);
+ pipemux &= PCIE_PIPEMUX_MASK;
+ if (pipemux == PCIE_PIPEMUX_MASK) {
+ /* read the PCIe PIPEMUX strap setting */
+ pipemux = mmio_read_32(CDRU_CHIP_STRAP_DATA_LSW);
+ pipemux >>= PCIE_PIPEMUX_SHIFT;
+ pipemux &= PCIE_PIPEMUX_MASK;
+ }
+
+ return pipemux;
+}
+
+/*
+ * Store the PIPEMUX index (set for each boot)
+ */
+static void pipemux_save_index(unsigned int idx)
+{
+ pipemux_idx = idx;
+}
+
+static int paxb_sr_core_needs_enable(unsigned int core_idx)
+{
+ return !!((pipemux_table[pipemux_idx] >> core_idx) & 0x1);
+}
+
+static int pipemux_sr_init(void)
+{
+ uint32_t pipemux;
+
+ /* read the PCIe PIPEMUX strap setting */
+ pipemux = pipemux_strap_read();
+ if (!pipemux_strap_is_valid(pipemux)) {
+ ERROR("Invalid PCIe PIPEMUX strap %u\n", pipemux);
+ return -EIO;
+ }
+
+ /* no PCIe RC is needed */
+ if (!pipemux_table[pipemux]) {
+ WARN("PIPEMUX indicates no PCIe RC required\n");
+ return -ENODEV;
+ }
+
+ /* save the PIPEMUX strap */
+ pipemux_save_index(pipemux);
+
+ return 0;
+}
+
+/*
+ * PCIe RC serdes link width
+ *
+ * The array is first organized in rows as indexed by the PIPEMUX setting.
+ * Within each row, eight lane width entries are specified -- one entry
+ * per PCIe core, from 0 to 7.
+ *
+ * Note: The EP lanes/cores are not mapped in this table! EP cores are
+ * controlled and thus configured by Nitro.
+ */
+static uint8_t link_width_table[][NUM_OF_SR_PCIE_CORES] = {
+ /* PIPEMUX = 0, EP 1x16 */
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
+ {0, 0, 0, 0, 0, 0, 0, 8},
+ /* PIPEMUX = 2, EP 4x4 */
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* PIPEMUX = 3, RC 2x8, cores 0, 7 */
+ {8, 0, 0, 0, 0, 0, 0, 8},
+ /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
+ {4, 4, 0, 0, 0, 0, 4, 4},
+ /* PIPEMUX = 5, RC 8x2, all 8 cores */
+ {2, 2, 2, 2, 2, 2, 2, 2},
+ /* PIPEMUX = 6, RC 3x4 (cores 0, 6, 7), RC 2x2 (cores 2, 3) */
+ {4, 0, 2, 2, 0, 0, 4, 4},
+ /* PIPEMUX = 7, RC 1x4 (core 0), RC 6x2 (cores 2, 3, 4, 5, 6, 7 */
+ {4, 0, 2, 2, 2, 2, 2, 2},
+ /* PIPEMUX = 8, EP 1x8 + RC 4x2 (cores 4, 5, 6, 7) */
+ {0, 0, 0, 0, 2, 2, 2, 2},
+ /* PIPEMUX = 9, EP 1x8 + RC 2x4 (cores 6, 7) */
+ {0, 0, 0, 0, 0, 0, 4, 4},
+ /* PIPEMUX = 10, EP 2x4 + RC 2x4 (cores 1, 6) */
+ {0, 4, 0, 0, 0, 0, 4, 0},
+ /* PIPEMUX = 11, EP 2x4 + RC 4x2 (cores 2, 3, 4, 5) */
+ {0, 0, 2, 2, 2, 2, 0, 0},
+ /* PIPEMUX = 12, EP 1x4 + RC 6x2 (cores 2, 3, 4, 5, 6, 7) */
+ {0, 0, 2, 2, 2, 2, 2, 2},
+ /* PIPEMUX = 13, EP 2x4 + RC 1x4 (core 6) + RC 2x2 (cores 2, 3) */
+ {0, 0, 2, 2, 0, 0, 4, 0}
+};
+
+/*
+ * function for writes to the Serdes registers through the PMI interface
+ */
+static int paxb_pmi_write(unsigned int core_idx, uint32_t pmi, uint32_t val)
+{
+ uint32_t status;
+ unsigned int timeout = PMI_TIMEOUT_MS;
+
+ paxb_rc_cfg_write(core_idx, CFG_RC_PMI_ADDR, pmi);
+
+ val &= ~CFG_RC_RWCMD_MASK;
+ val |= CFG_RC_WCMD_MASK;
+ paxb_rc_cfg_write(core_idx, CFG_RC_PMI_WDATA, val);
+
+ do {
+ status = paxb_rc_cfg_read(core_idx, CFG_RC_PMI_WDATA);
+
+ /* wait for write command bit to clear */
+ if ((status & CFG_RC_WCMD_MASK) == 0)
+ return 0;
+ } while (--timeout);
+
+ return -EIO;
+}
+
+/*
+ * function for reads from the Serdes registers through the PMI interface
+ */
+static int paxb_pmi_read(unsigned int core_idx, uint32_t pmi, uint32_t *val)
+{
+ uint32_t status;
+ unsigned int timeout = PMI_TIMEOUT_MS;
+
+ paxb_rc_cfg_write(core_idx, CFG_RC_PMI_ADDR, pmi);
+
+ paxb_rc_cfg_write(core_idx, CFG_RC_PMI_WDATA, CFG_RC_RCMD_MASK);
+
+ do {
+ status = paxb_rc_cfg_read(core_idx, CFG_RC_PMI_RDATA);
+
+ /* wait for read ack bit set */
+ if ((status & CFG_RC_RACK_MASK)) {
+ *val = paxb_rc_cfg_read(core_idx, CFG_RC_PMI_RDATA);
+ return 0;
+ }
+ } while (--timeout);
+
+ return -EIO;
+}
+
+
+#ifndef BOARD_PCIE_EXT_CLK
+/*
+ * PCIe Override clock lookup table
+ *
+ * Each array index represents pcie override clock has been done
+ * by CFW or not.
+ */
+static uint8_t pcie_override_clk_table[] = {
+ /* PIPEMUX = 0, EP 1x16 */
+ 0x0,
+ /* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
+ 0x1,
+ /* PIPEMUX = 2, EP 4x4 */
+ 0x0,
+ /* PIPEMUX = 3, RC 2x8, cores 0, 7 */
+ 0x0,
+ /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
+ 0x0,
+ /* PIPEMUX = 5, RC 8x2, all 8 cores */
+ 0x0,
+ /* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
+ 0x0,
+ /* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
+ 0x0,
+ /* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
+ 0x0,
+ /* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
+ 0x0,
+ /* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
+ 0x0,
+ /* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
+ 0x0,
+ /* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
+ 0x0,
+ /* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
+ 0x0,
+};
+
+/*
+ * Bring up LCPLL channel 0 reference clock for PCIe serdes used in RC mode
+ */
+static int pcie_lcpll_init(void)
+{
+ uintptr_t reg;
+ unsigned int timeout = PCIE_LCPLL_TIMEOUT_MS;
+ uint32_t val;
+
+ if (pcie_override_clk_table[pipemux_idx]) {
+ /*
+ * Check rc_mode_override again to avoid halt
+ * because of cfw uninitialized lcpll.
+ */
+ reg = (uintptr_t)(PCIE_LCPLL_BASE +
+ PCIE_PIPE_MUX_RC_MODE_OVERRIDE_CFG);
+ val = mmio_read_32(reg);
+ if (val & 0x1)
+ return 0;
+ else
+ return -ENODEV;
+ }
+
+ /* power on PCIe LCPLL and its LDO */
+ reg = (uintptr_t)CRMU_AON_CTRL1;
+ mmio_setbits_32(reg, CRMU_PCIE_LCPLL_PWR_ON_MASK |
+ CRMU_PCIE_LCPLL_PWRON_LDO_MASK);
+ udelay(PCIE_LCPLL_DELAY_US);
+
+ /* remove isolation */
+ mmio_clrbits_32(reg, CRMU_PCIE_LCPLL_ISO_IN_MASK);
+ udelay(PCIE_LCPLL_DELAY_US);
+
+ /* disconnect termination */
+ reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL13_OFFSET);
+ mmio_setbits_32(reg, PCIE_LCPLL_D2C2_TERM_DISC <<
+ PCIE_LCPLL_D2C2_CTRL_SHIFT);
+
+ /* enable CML buf1/2 and D2C2 */
+ reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL3_OFFSET);
+ mmio_setbits_32(reg, PCIE_LCPLL_CM_ENA << PCIE_LCPLL_EN_CTRL_SHIFT);
+
+ /* select diff clock mux out as ref clock */
+ mmio_clrbits_32(reg, PCIE_LCPLL_REF_CLK_MASK);
+
+ /* delay for 500 microseconds per ASIC spec for PCIe LCPLL */
+ udelay(PCIE_LCPLL_DELAY_US);
+
+ /* now bring PCIe LCPLL out of reset */
+ reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL0_OFFSET);
+ mmio_setbits_32(reg, PCIE_LCPLL_RESETB_MASK);
+
+ /* wait for PLL to lock */
+ reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_STATUS_OFFSET);
+ do {
+ val = mmio_read_32(reg);
+ if ((val & PCIE_LCPLL_LOCK_MASK) == PCIE_LCPLL_LOCK_MASK) {
+ /* now bring the post divider out of reset */
+ reg = (uintptr_t)(PCIE_LCPLL_BASE +
+ PCIE_LCPLL_CTRL0_OFFSET);
+ mmio_setbits_32(reg, PCIE_LCPLL_P_RESETB_MASK);
+ VERBOSE("PCIe LCPLL locked\n");
+ return 0;
+ }
+ mdelay(1);
+ } while (--timeout);
+
+ ERROR("PCIe LCPLL failed to lock\n");
+ return -EIO;
+}
+#else
+/*
+ * Bring up EXT CLK reference clock for PCIe serdes used in RC mode
+ * XTAL_BYPASS (3 << 0)
+ * INTR_LC_REF (5 << 0)
+ * PD_CML_LC_REF_OUT (1 << 4)
+ * PD_CML_REF_CH_OUT (1 << 8)
+ * CLK_MASTER_SEL (1 << 11)
+ * CLK_MASTER_CTRL_A (1 << 12)
+ * CLK_MASTER_CTRL_B (2 << 14)
+ */
+static const uint16_t pcie_ext_clk[][NUM_OF_PCIE_SERDES] = {
+ /* PIPEMUX = 0, EP 1x16 */
+ {0},
+ /* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
+ {0},
+ /* PIPEMUX = 2, EP 4x4 */
+ {0},
+ /* PIPEMUX = 3, RC 2x8, cores 0, 7 */
+ {0x8803, 0x9115, 0x9115, 0x1115, 0x8803, 0x9115, 0x9115, 0x1115},
+ /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
+ {0x8803, 0x1115, 0x8915, 0x1115, 0x8803, 0x1115, 0x8915, 0x1115,},
+ /* PIPEMUX = 5, RC 8x2, all 8 cores */
+ {0x0803, 0x0915, 0x0915, 0x0915, 0x0803, 0x0915, 0x0915, 0x0915,},
+ /* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
+ {0},
+ /* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
+ {0},
+ /* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
+ {0},
+ /* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
+ {0},
+ /* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
+ {0},
+ /* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
+ {0},
+ /* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
+ {0},
+ /* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
+ {0},
+};
+
+static void pcie_ext_clk_init(void)
+{
+ unsigned int serdes;
+ uint32_t val;
+
+ for (serdes = 0; serdes < NUM_OF_PCIE_SERDES; serdes++) {
+ val = pcie_ext_clk[pipemux_idx][serdes];
+ if (!val)
+ return;
+ mmio_write_32(PCIE_CORE_RESERVED_CFG +
+ serdes * PCIE_CORE_PWR_OFFSET, val);
+ }
+ /* disable CML buf1/2 and enable D2C2 */
+ mmio_clrsetbits_32((PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL3_OFFSET),
+ PCIE_LCPLL_CM_BUF_ENA << PCIE_LCPLL_EN_CTRL_SHIFT,
+ PCIE_LCPLL_D2C2_ENA << PCIE_LCPLL_EN_CTRL_SHIFT);
+ mmio_write_32(PCIE_LCPLL_BASE + PCIE_TX_CLKMASTER_CTRL_OVERRIDE_CFG, 1);
+ INFO("Overriding Clocking - using REF clock from PAD...\n");
+}
+#endif
+
+static int load_uc(unsigned int core_idx)
+{
+ return 0;
+}
+
+static int paxb_serdes_gate_clock(unsigned int core_idx, int gate_clk)
+{
+ unsigned int link_width, serdes, nr_serdes;
+ uintptr_t pmi_base;
+ unsigned int rdata;
+ uint32_t core_offset = core_idx * PCIE_CORE_PWR_OFFSET;
+
+ link_width = paxb->get_link_width(core_idx);
+ if (!link_width) {
+ ERROR("Unsupported PIPEMUX\n");
+ return -EOPNOTSUPP;
+ }
+
+ nr_serdes = link_width / 2;
+ pmi_base = (uintptr_t)(PCIE_CORE_PMI_CFG_BASE + core_offset);
+
+ for (serdes = 0; serdes < nr_serdes; serdes++) {
+ mmio_write_32(pmi_base, serdes);
+ paxb_pmi_read(core_idx, PMI_ADDR_LANE0(PMI_PLL_CTRL_4), &rdata);
+ if (!gate_clk)
+ rdata |= PMI_SERDES_CLK_ENABLE;
+ else
+ rdata &= ~PMI_SERDES_CLK_ENABLE;
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(PMI_PLL_CTRL_4), rdata);
+ }
+ return 0;
+}
+
+static int paxb_gen3_serdes_init(unsigned int core_idx, uint32_t nSerdes)
+{
+ uint32_t rdata;
+ int serdes;
+ uintptr_t pmi_base;
+ unsigned int timeout;
+ unsigned int reg_d230, reg_d267;
+
+
+ pmi_base = (uintptr_t)(PCIE_CORE_PMI_CFG_BASE +
+ (core_idx * PCIE_CORE_PWR_OFFSET));
+
+ for (serdes = 0; serdes < nSerdes; serdes++) {
+ /* select the PMI interface */
+ mmio_write_32(pmi_base, serdes);
+
+ /* Clock enable */
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_CLK_CTRL0),
+ 0x3);
+
+ /* Release reset of master */
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_RST_CTRL0),
+ 0x1);
+
+ /* clearing PRAM memory */
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_AHB_CTRL0),
+ 0x100);
+
+ timeout = UC_RAM_INIT_TIMEOUT;
+ do {
+ paxb_pmi_read(core_idx,
+ PMI_ADDR_LANE0(UC_A_AHB_STAT0),
+ &rdata);
+ } while ((rdata & 0x01) == 0 && timeout--);
+
+ if (!timeout)
+ return -EIO;
+
+ timeout = UC_RAM_INIT_TIMEOUT;
+ do {
+ paxb_pmi_read(core_idx,
+ PMI_ADDR_LANE1(UC_A_AHB_STAT0),
+ &rdata);
+ } while ((rdata & 0x01) == 0 && timeout--);
+
+ if (!timeout)
+ return -EIO;
+
+ /* clearing PRAM memory */
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_AHB_CTRL0),
+ 0);
+
+ /* to identify 2 lane serdes */
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_DBG1), 0x1);
+
+ /* De-Assert Pram & master resets */
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_RST_CTRL0),
+ 0x9);
+
+ if (load_uc(core_idx))
+ return -EIO;
+
+ /* UC UC ready for command */
+ paxb_pmi_read(core_idx, PMI_ADDR_LANE0(DSC_UC_CTRL),
+ &rdata);
+ rdata |= DSC_UC_CTRL_RDY_CMD;
+ paxb_pmi_write(core_idx, PMI_ADDR_LANE0(DSC_UC_CTRL),
+ rdata);
+
+ paxb_pmi_read(core_idx, PMI_ADDR_LANE1(DSC_UC_CTRL),
+ &rdata);
+ rdata |= DSC_UC_CTRL_RDY_CMD;
+ paxb_pmi_write(core_idx, PMI_ADDR_LANE1(DSC_UC_CTRL),
+ rdata);
+
+ /* Lane reset */
+ paxb_pmi_write(core_idx,
+ PMI_ADDR_BCAST(LANE_DBG_RST_CTRL), 0x3);
+
+ /* De-Assert Core and Master resets */
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_RST_CTRL0),
+ 0x3);
+
+ timeout = UC_INIT_TIMEOUT;
+ while (timeout--) {
+ paxb_pmi_read(core_idx,
+ PMI_ADDR_LANE0(UC_VERSION_NUM),
+ &reg_d230);
+ paxb_pmi_read(core_idx,
+ PMI_ADDR_LANE0(DSC_SM_CTL22),
+ &reg_d267);
+
+ if (((reg_d230 & 0xffff) != 0) &
+ ((reg_d267 & 0xc000) == 0xc000)) {
+ break;
+ }
+ mdelay(1);
+ }
+
+ if (!timeout)
+ return -EIO;
+
+ timeout = UC_INIT_TIMEOUT;
+ while (timeout--) {
+ paxb_pmi_read(core_idx,
+ PMI_ADDR_LANE1(UC_VERSION_NUM),
+ &reg_d230);
+ paxb_pmi_read(core_idx,
+ PMI_ADDR_LANE1(DSC_SM_CTL22),
+ &reg_d267);
+
+ if (((reg_d230 & 0xffff) != 0) &
+ ((reg_d267 & 0xc000) == 0xc000)) {
+ break;
+ }
+ mdelay(1);
+ }
+
+ if (!timeout)
+ return -EIO;
+ }
+ return 0;
+}
+
+static int pcie_serdes_requires_patch(unsigned int serdes_idx)
+{
+ if (pipemux_idx != SERDES_PATCH_PIPEMUX_INDEX)
+ return 0;
+
+ return !!((SERDES_PATCH_INDEX >> serdes_idx) & 0x1);
+}
+
+static void pcie_tx_coeff_p7(unsigned int core_idx)
+{
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11b), 0x00aa);
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11c), 0x1155);
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11d), 0x2449);
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11e), 0x000f);
+ paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd307), 0x0001);
+}
+
+
+static unsigned int paxb_sr_get_rc_link_width(unsigned int core_idx)
+{
+ return link_width_table[pipemux_idx][core_idx];
+}
+
+static uint32_t paxb_sr_get_rc_link_speed(void)
+{
+ return GEN3_LINK_SPEED;
+}
+
+
+static int paxb_serdes_init(unsigned int core_idx, unsigned int nr_serdes)
+{
+ uint32_t core_offset = core_idx * PCIE_CORE_PWR_OFFSET;
+ unsigned int serdes;
+ uintptr_t pmi_base;
+ int ret;
+
+ /*
+ * Each serdes has a x2 link width
+ *
+ * Use PAXB to patch the serdes for proper RX termination through the
+ * PMI interface
+ */
+ pmi_base = (uintptr_t)(PCIE_CORE_PMI_CFG_BASE + core_offset);
+ for (serdes = 0; serdes < nr_serdes; serdes++) {
+ /* select the PMI interface */
+ mmio_write_32(pmi_base, serdes);
+
+ /* patch Serdes for RX termination */
+ ret = paxb_pmi_write(core_idx, PMI_RX_TERM_SEQ,
+ PMI_RX_TERM_VAL);
+ if (ret)
+ goto err_pmi;
+
+ ret = paxb_pmi_write(core_idx, MERLIN16_PCIE_BLK2_PWRMGMT_7,
+ MERLIN16_PCIE_BLK2_PWRMGMT_7_VAL);
+ if (ret)
+ goto err_pmi;
+
+ ret = paxb_pmi_write(core_idx, MERLIN16_PCIE_BLK2_PWRMGMT_8,
+ MERLIN16_PCIE_BLK2_PWRMGMT_8_VAL);
+ if (ret)
+ goto err_pmi;
+
+ ret = paxb_pmi_write(core_idx, MERLIN16_AMS_TX_CTRL_5,
+ MERLIN16_AMS_TX_CTRL_5_VAL);
+ if (ret)
+ goto err_pmi;
+
+ pcie_tx_coeff_p7(core_idx);
+
+ if (pcie_serdes_requires_patch(serdes)) {
+ if (((core_idx == 0) || (core_idx == 7))) {
+ ret = paxb_pmi_write(core_idx,
+ PMI_X8_CORE0_7_PATCH_SEQ,
+ PMI_X8_CORE0_7_PATCH_VAL);
+ if (ret)
+ goto err_pmi;
+ }
+ }
+ }
+
+ return 0;
+
+err_pmi:
+ ERROR("PCIe PMI write failed\n");
+ return ret;
+}
+
+static int paxb_sr_phy_init(void)
+{
+ int ret;
+ unsigned int core_idx;
+
+#ifndef BOARD_PCIE_EXT_CLK
+ ret = pcie_lcpll_init();
+ if (ret)
+ return ret;
+#else
+ pcie_ext_clk_init();
+#endif
+
+ for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
+ if (!pcie_core_needs_enable(core_idx))
+ continue;
+ unsigned int link_width;
+
+ paxb_serdes_gate_clock(core_idx, 0);
+
+ link_width = paxb->get_link_width(core_idx);
+ if (!link_width) {
+ ERROR("Unsupported PIPEMUX\n");
+ return -EOPNOTSUPP;
+ }
+
+ ret = paxb_serdes_init(core_idx, link_width / 2);
+ if (ret) {
+ ERROR("PCIe serdes initialization failed for core %u\n",
+ core_idx);
+ return ret;
+ }
+
+
+ ret = paxb_gen3_serdes_init(core_idx, link_width / 2);
+ if (ret) {
+ ERROR("PCIe GEN3 serdes initialization failed\n");
+ return ret;
+ }
+
+ }
+ return 0;
+}
+
+const paxb_cfg sr_paxb_cfg = {
+ .type = PAXB_SR,
+ .device_id = SR_B0_DEVICE_ID,
+ .pipemux_init = pipemux_sr_init,
+ .phy_init = paxb_sr_phy_init,
+ .core_needs_enable = paxb_sr_core_needs_enable,
+ .num_cores = NUM_OF_SR_PCIE_CORES,
+ .get_link_width = paxb_sr_get_rc_link_width,
+ .get_link_speed = paxb_sr_get_rc_link_speed,
+};
+
+const paxb_cfg *paxb_get_sr_config(void)
+{
+ return &sr_paxb_cfg;
+}
diff --git a/plat/brcm/board/stingray/src/topology.c b/plat/brcm/board/stingray/src/topology.c
new file mode 100644
index 000000000..24718e590
--- /dev/null
+++ b/plat/brcm/board/stingray/src/topology.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019-2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdint.h>
+
+#include <plat_brcm.h>
+#include <platform_def.h>
+
+/*
+ * On Stingray, the system power level is the highest power level.
+ * The first entry in the power domain descriptor specifies the
+ * number of system power domains i.e. 1.
+ */
+#define SR_PWR_DOMAINS_AT_MAX_PWR_LVL 1
+
+/*
+ * The Stingray power domain tree descriptor. The cluster power domains
+ * are arranged so that when the PSCI generic code creates the power
+ * domain tree, the indices of the CPU power domain nodes it allocates
+ * match the linear indices returned by plat_core_pos_by_mpidr()
+ * i.e. CLUSTER0 CPUs are allocated indices from 0 to 1 and the higher
+ * indices for other Cluster CPUs.
+ */
+const unsigned char sr_power_domain_tree_desc[] = {
+ /* No of root nodes */
+ SR_PWR_DOMAINS_AT_MAX_PWR_LVL,
+ /* No of children for the root node */
+ BRCM_CLUSTER_COUNT,
+ /* No of children for the first cluster node */
+ PLATFORM_CLUSTER0_CORE_COUNT,
+ /* No of children for the second cluster node */
+ PLATFORM_CLUSTER1_CORE_COUNT,
+ /* No of children for the third cluster node */
+ PLATFORM_CLUSTER2_CORE_COUNT,
+ /* No of children for the fourth cluster node */
+ PLATFORM_CLUSTER3_CORE_COUNT,
+};
+
+/*******************************************************************************
+ * This function returns the Stingray topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return sr_power_domain_tree_desc;
+}
+
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+ return plat_brcm_calc_core_pos(mpidr);
+}
diff --git a/plat/brcm/board/stingray/src/tz_sec.c b/plat/brcm/board/stingray/src/tz_sec.c
new file mode 100644
index 000000000..07b12a7a2
--- /dev/null
+++ b/plat/brcm/board/stingray/src/tz_sec.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2016 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/tzc400.h>
+#include <lib/mmio.h>
+
+#include <cmn_sec.h>
+#include <platform_def.h>
+
+/*
+ * Trust Zone controllers
+ */
+#define TZC400_FS_SRAM_ROOT 0x66d84000
+
+/*
+ * TZPC Master configure registers
+ */
+
+/* TZPC_TZPCDECPROT0set */
+#define TZPC0_MASTER_NS_BASE 0x68b40804
+#define TZPC0_SATA3_BIT 5
+#define TZPC0_SATA2_BIT 4
+#define TZPC0_SATA1_BIT 3
+#define TZPC0_SATA0_BIT 2
+#define TZPC0_USB3H1_BIT 1
+#define TZPC0_USB3H0_BIT 0
+#define TZPC0_MASTER_SEC_DEFAULT 0
+
+/* TZPC_TZPCDECPROT1set */
+#define TZPC1_MASTER_NS_BASE 0x68b40810
+#define TZPC1_SDIO1_BIT 6
+#define TZPC1_SDIO0_BIT 5
+#define TZPC1_AUDIO0_BIT 4
+#define TZPC1_USB2D_BIT 3
+#define TZPC1_USB2H1_BIT 2
+#define TZPC1_USB2H0_BIT 1
+#define TZPC1_AMAC0_BIT 0
+#define TZPC1_MASTER_SEC_DEFAULT 0
+
+
+struct tz_sec_desc {
+ uintptr_t addr;
+ uint32_t val;
+};
+
+static const struct tz_sec_desc tz_master_defaults[] = {
+{ TZPC0_MASTER_NS_BASE, TZPC0_MASTER_SEC_DEFAULT },
+{ TZPC1_MASTER_NS_BASE, TZPC1_MASTER_SEC_DEFAULT }
+};
+
+/*
+ * Initialize the TrustZone Controller for SRAM partitioning.
+ */
+static void bcm_tzc_setup(void)
+{
+ VERBOSE("Configuring SRAM TrustZone Controller\n");
+
+ /* Init the TZASC controller */
+ tzc400_init(TZC400_FS_SRAM_ROOT);
+
+ /*
+ * Close the entire SRAM space
+ * Region 0 covers the entire SRAM space
+ * None of the NS device can access it.
+ */
+ tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
+
+ /* Do raise an exception if a NS device tries to access secure memory */
+ tzc400_set_action(TZC_ACTION_ERR);
+}
+
+/*
+ * Configure TZ Master as NS_MASTER or SECURE_MASTER
+ * To set a Master to non-secure, use *_SET registers
+ * To set a Master to secure, use *_CLR registers (set + 0x4 address)
+ */
+static void tz_master_set(uint32_t base, uint32_t value, uint32_t ns)
+{
+ if (ns == SECURE_MASTER) {
+ mmio_write_32(base + 4, value);
+ } else {
+ mmio_write_32(base, value);
+ }
+}
+
+/*
+ * Initialize the secure environment for sdio.
+ */
+void plat_tz_sdio_ns_master_set(uint32_t ns)
+{
+ tz_master_set(TZPC1_MASTER_NS_BASE,
+ 1 << TZPC1_SDIO0_BIT,
+ ns);
+}
+
+/*
+ * Initialize the secure environment for usb.
+ */
+void plat_tz_usb_ns_master_set(uint32_t ns)
+{
+ tz_master_set(TZPC1_MASTER_NS_BASE,
+ 1 << TZPC1_USB2H0_BIT,
+ ns);
+}
+
+/*
+ * Set masters to default configuration.
+ *
+ * DMA security settings are programmed into the PL-330 controller and
+ * are not set by iProc TZPC registers.
+ * DMA always comes up as secure master (*NS bit is 0).
+ *
+ * Because the default reset values of TZPC are 0 (== Secure),
+ * ARM Verilog code makes all masters, including PCIe, come up as
+ * secure.
+ * However, SOTP has a bit called SOTP_ALLMASTER_NS that overrides
+ * TZPC and makes all masters non-secure for AB devices.
+ *
+ * Hence we first set all the TZPC bits to program all masters,
+ * including PCIe, as non-secure, then set the CLEAR_ALLMASTER_NS bit
+ * so that the SOTP_ALLMASTER_NS cannot override TZPC.
+ * now security settings for each masters come from TZPC
+ * (which makes all masters other than DMA as non-secure).
+ *
+ * During the boot, all masters other than DMA Ctrlr + list
+ * are non-secure in an AB Prod/AB Dev/AB Pending device.
+ *
+ */
+void plat_tz_master_default_cfg(void)
+{
+ int i;
+
+ /* Configure default secure and non-secure TZ Masters */
+ for (i = 0; i < ARRAY_SIZE(tz_master_defaults); i++) {
+ tz_master_set(tz_master_defaults[i].addr,
+ tz_master_defaults[i].val,
+ SECURE_MASTER);
+ tz_master_set(tz_master_defaults[i].addr,
+ ~tz_master_defaults[i].val,
+ NS_MASTER);
+ }
+
+ /* Clear all master NS */
+ mmio_setbits_32(SOTP_CHIP_CTRL,
+ 1 << SOTP_CLEAR_SYSCTRL_ALL_MASTER_NS);
+
+ /* Initialize TZ controller and Set SRAM to secure */
+ bcm_tzc_setup();
+}
diff --git a/plat/brcm/common/brcm_bl2_mem_params_desc.c b/plat/brcm/common/brcm_bl2_mem_params_desc.c
new file mode 100644
index 000000000..f711354bc
--- /dev/null
+++ b/plat/brcm/common/brcm_bl2_mem_params_desc.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Following descriptor provides BL image/ep information that gets used
+ * by BL2 to load the images and also subset of this information is
+ * passed to next BL image. The image loading sequence is managed by
+ * populating the images in required loading order. The image execution
+ * sequence is managed by populating the `next_handoff_image_id` with
+ * the next executable image id.
+ ******************************************************************************/
+static bl_mem_params_node_t bl2_mem_params_descs[] = {
+#ifdef SCP_BL2_BASE
+ /* Fill SCP_BL2 related information if it exists */
+ {
+ .image_id = SCP_BL2_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = SCP_BL2_BASE,
+ .image_info.image_max_size = PLAT_MAX_SCP_BL2_SIZE,
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+#endif /* SCP_BL2_BASE */
+
+ /* Fill BL31 related information */
+ {
+ .image_id = BL31_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL31_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
+#if DEBUG
+ .ep_info.args.arg3 = BRCM_BL31_PLAT_PARAM_VAL,
+#endif
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = BL31_BASE,
+ .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+
+#ifdef BL32_BASE
+ .next_handoff_image_id = BL32_IMAGE_ID,
+#else
+ .next_handoff_image_id = BL33_IMAGE_ID,
+#endif
+ },
+
+#ifdef BL32_BASE
+ /* Fill BL32 related information */
+ {
+ .image_id = BL32_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
+ .ep_info.pc = BL32_BASE,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
+#endif /* BL32_BASE */
+
+ /* Fill BL33 related information */
+ {
+ .image_id = BL33_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
+#ifdef PRELOADED_BL33_BASE
+ .ep_info.pc = PRELOADED_BL33_BASE,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+#else
+ .ep_info.pc = PLAT_BRCM_NS_IMAGE_OFFSET,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = PLAT_BRCM_NS_IMAGE_OFFSET,
+ .image_info.image_max_size = BRCM_DRAM1_SIZE,
+#endif /* PRELOADED_BL33_BASE */
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/brcm/common/brcm_bl2_setup.c b/plat/brcm/common/brcm_bl2_setup.c
new file mode 100644
index 000000000..9a7153b77
--- /dev/null
+++ b/plat/brcm/common/brcm_bl2_setup.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/arm/sp804_delay_timer.h>
+#include <lib/mmio.h>
+
+#include <bcm_console.h>
+#include <platform_def.h>
+#include <plat/brcm/common/plat_brcm.h>
+
+/* Data structure which holds the extents of the trusted SRAM for BL2 */
+static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
+
+/* Weak definitions may be overridden in specific BRCM platform */
+#pragma weak plat_bcm_bl2_platform_setup
+#pragma weak plat_bcm_bl2_plat_arch_setup
+#pragma weak plat_bcm_security_setup
+#pragma weak plat_bcm_bl2_plat_handle_scp_bl2
+#pragma weak plat_bcm_bl2_early_platform_setup
+
+void plat_bcm_bl2_early_platform_setup(void)
+{
+}
+
+void plat_bcm_bl2_platform_setup(void)
+{
+}
+
+void plat_bcm_bl2_plat_arch_setup(void)
+{
+}
+
+void plat_bcm_security_setup(void)
+{
+}
+
+void bcm_bl2_early_platform_setup(uintptr_t tb_fw_config,
+ meminfo_t *mem_layout)
+{
+ /* Initialize the console to provide early debug support */
+ bcm_console_boot_init();
+
+ /* Setup the BL2 memory layout */
+ bl2_tzram_layout = *mem_layout;
+
+ /* Initialise the IO layer and register platform IO devices */
+ plat_brcm_io_setup();
+
+ /* Log HW reset event */
+ INFO("RESET: 0x%x\n",
+ mmio_read_32(CRMU_RESET_EVENT_LOG));
+}
+
+void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ /* SoC specific setup */
+ plat_bcm_bl2_early_platform_setup();
+
+ /* Initialize delay timer driver using SP804 dual timer 0 */
+ sp804_timer_init(SP804_TIMER0_BASE,
+ SP804_TIMER0_CLKMULT, SP804_TIMER0_CLKDIV);
+
+ /* BRCM platforms generic setup */
+ bcm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1);
+}
+
+/*
+ * Perform Broadcom platform setup.
+ */
+void bcm_bl2_platform_setup(void)
+{
+ /* Initialize the secure environment */
+ plat_bcm_security_setup();
+}
+
+void bl2_platform_setup(void)
+{
+ bcm_bl2_platform_setup();
+ plat_bcm_bl2_platform_setup();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only initializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bcm_bl2_plat_arch_setup(void)
+{
+#ifndef MMU_DISABLED
+ if (!(read_sctlr_el1() & SCTLR_M_BIT)) {
+ const mmap_region_t bl_regions[] = {
+ MAP_REGION_FLAT(bl2_tzram_layout.total_base,
+ bl2_tzram_layout.total_size,
+ MT_MEMORY | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(BL_CODE_BASE,
+ BL_CODE_END - BL_CODE_BASE,
+ MT_CODE | MT_SECURE),
+ MAP_REGION_FLAT(BL_RO_DATA_BASE,
+ BL_RO_DATA_END - BL_RO_DATA_BASE,
+ MT_RO_DATA | MT_SECURE),
+#if USE_COHERENT_MEM
+ MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END -
+ BL_COHERENT_RAM_BASE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+#endif
+ {0}
+ };
+
+ setup_page_tables(bl_regions, plat_brcm_get_mmap());
+ enable_mmu_el1(0);
+ }
+#endif
+}
+
+void bl2_plat_arch_setup(void)
+{
+#ifdef ENA_MMU_BEFORE_DDR_INIT
+ /*
+ * Once MMU is enabled before DDR, MEMORY TESTS
+ * get affected as read/write transaction might occures from
+ * caches. So For running memory test, one should not set this
+ * flag.
+ */
+ bcm_bl2_plat_arch_setup();
+ plat_bcm_bl2_plat_arch_setup();
+#else
+ plat_bcm_bl2_plat_arch_setup();
+ bcm_bl2_plat_arch_setup();
+#endif
+}
+
+int bcm_bl2_handle_post_image_load(unsigned int image_id)
+{
+ int err = 0;
+
+ bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+
+ assert(bl_mem_params);
+
+ switch (image_id) {
+ case BL32_IMAGE_ID:
+ bl_mem_params->ep_info.spsr = brcm_get_spsr_for_bl32_entry();
+ break;
+
+ case BL33_IMAGE_ID:
+ /* BL33 expects to receive the primary CPU MPID (through r0) */
+ bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
+ bl_mem_params->ep_info.spsr = brcm_get_spsr_for_bl33_entry();
+ break;
+
+#ifdef SCP_BL2_BASE
+ case SCP_BL2_IMAGE_ID:
+ /* The subsequent handling of SCP_BL2 is platform specific */
+ err = bcm_bl2_handle_scp_bl2(&bl_mem_params->image_info);
+ if (err)
+ WARN("Failure in platform-specific handling of SCP_BL2 image.\n");
+ break;
+#endif
+ default:
+ /* Do nothing in default case */
+ break;
+ }
+
+ return err;
+}
+
+/*******************************************************************************
+ * This function can be used by the platforms to update/use image
+ * information for given `image_id`.
+ ******************************************************************************/
+int bcm_bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ return bcm_bl2_handle_post_image_load(image_id);
+}
+
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ return bcm_bl2_plat_handle_post_image_load(image_id);
+}
+
+#ifdef SCP_BL2_BASE
+int plat_bcm_bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info)
+{
+ return 0;
+}
+
+int bcm_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info)
+{
+ return plat_bcm_bl2_plat_handle_scp_bl2(scp_bl2_image_info);
+}
+#endif
diff --git a/plat/brcm/common/brcm_bl31_setup.c b/plat/brcm/common/brcm_bl31_setup.c
new file mode 100644
index 000000000..d3fa83da7
--- /dev/null
+++ b/plat/brcm/common/brcm_bl31_setup.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/sp804_delay_timer.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+
+#include <bcm_console.h>
+#include <plat_brcm.h>
+#include <platform_def.h>
+
+#ifdef BL33_SHARED_DDR_BASE
+struct bl33_info *bl33_info = (struct bl33_info *)BL33_SHARED_DDR_BASE;
+#endif
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/* Weak definitions may be overridden in specific BRCM platform */
+#pragma weak plat_bcm_bl31_early_platform_setup
+#pragma weak plat_brcm_pwrc_setup
+#pragma weak plat_brcm_security_setup
+
+void plat_brcm_security_setup(void)
+{
+
+}
+
+void plat_brcm_pwrc_setup(void)
+{
+
+}
+
+void plat_bcm_bl31_early_platform_setup(void *from_bl2,
+ bl_params_t *plat_params_from_bl2)
+{
+
+}
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+ entry_point_info_t *next_image_info;
+
+ assert(sec_state_is_valid(type));
+ next_image_info = (type == NON_SECURE)
+ ? &bl33_image_ep_info : &bl32_image_ep_info;
+ /*
+ * None of the images on the ARM development platforms can have 0x0
+ * as the entrypoint
+ */
+ if (next_image_info->pc)
+ return next_image_info;
+ else
+ return NULL;
+}
+
+/*******************************************************************************
+ * Perform any BL31 early platform setup common to ARM standard platforms.
+ * Here is an opportunity to copy parameters passed by the calling EL (S-EL1
+ * in BL2 & EL3 in BL1) before they are lost (potentially). This needs to be
+ * done before the MMU is initialized so that the memory layout can be used
+ * while creating page tables. BL2 has flushed this information to memory, so
+ * we are guaranteed to pick up good data.
+ ******************************************************************************/
+void __init brcm_bl31_early_platform_setup(void *from_bl2,
+ uintptr_t soc_fw_config,
+ uintptr_t hw_config,
+ void *plat_params_from_bl2)
+{
+ /* Initialize the console to provide early debug support */
+ bcm_console_boot_init();
+
+ /* Initialize delay timer driver using SP804 dual timer 0 */
+ sp804_timer_init(SP804_TIMER0_BASE,
+ SP804_TIMER0_CLKMULT, SP804_TIMER0_CLKDIV);
+
+#if RESET_TO_BL31
+ /* There are no parameters from BL2 if BL31 is a reset vector */
+ assert(from_bl2 == NULL);
+ assert(plat_params_from_bl2 == NULL);
+
+# ifdef BL32_BASE
+ /* Populate entry point information for BL32 */
+ SET_PARAM_HEAD(&bl32_image_ep_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+ SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+ bl32_image_ep_info.pc = BL32_BASE;
+ bl32_image_ep_info.spsr = brcm_get_spsr_for_bl32_entry();
+# endif /* BL32_BASE */
+
+ /* Populate entry point information for BL33 */
+ SET_PARAM_HEAD(&bl33_image_ep_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+ /*
+ * Tell BL31 where the non-trusted software image
+ * is located and the entry state information
+ */
+ bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+
+ bl33_image_ep_info.spsr = brcm_get_spsr_for_bl33_entry();
+ SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+# if ARM_LINUX_KERNEL_AS_BL33
+ /*
+ * According to the file ``Documentation/arm64/booting.txt`` of the
+ * Linux kernel tree, Linux expects the physical address of the device
+ * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
+ * must be 0.
+ */
+ bl33_image_ep_info.args.arg0 = (u_register_t)PRELOADED_DTB_BASE;
+ bl33_image_ep_info.args.arg1 = 0U;
+ bl33_image_ep_info.args.arg2 = 0U;
+ bl33_image_ep_info.args.arg3 = 0U;
+# endif
+
+#else /* RESET_TO_BL31 */
+
+ /*
+ * In debug builds, we pass a special value in 'plat_params_from_bl2'
+ * to verify platform parameters from BL2 to BL31.
+ * In release builds, it's not used.
+ */
+ assert(((unsigned long long)plat_params_from_bl2) ==
+ BRCM_BL31_PLAT_PARAM_VAL);
+
+ /*
+ * Check params passed from BL2 should not be NULL
+ */
+ bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
+
+ assert(params_from_bl2 != NULL);
+ assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
+ assert(params_from_bl2->h.version >= VERSION_2);
+
+ bl_params_node_t *bl_params = params_from_bl2->head;
+
+ /*
+ * Copy BL33 and BL32 (if present), entry point information.
+ * They are stored in Secure RAM, in BL2's address space.
+ */
+ while (bl_params != NULL) {
+ if (bl_params->image_id == BL32_IMAGE_ID &&
+ bl_params->image_info->h.attr != IMAGE_ATTRIB_SKIP_LOADING)
+ bl32_image_ep_info = *bl_params->ep_info;
+
+ if (bl_params->image_id == BL33_IMAGE_ID)
+ bl33_image_ep_info = *bl_params->ep_info;
+
+ bl_params = bl_params->next_params_info;
+ }
+
+ if (bl33_image_ep_info.pc == 0U)
+ panic();
+#endif /* RESET_TO_BL31 */
+
+#ifdef BL33_SHARED_DDR_BASE
+ /* Pass information to BL33 thorugh x0 */
+ bl33_image_ep_info.args.arg0 = (u_register_t)BL33_SHARED_DDR_BASE;
+ bl33_image_ep_info.args.arg1 = 0ULL;
+ bl33_image_ep_info.args.arg2 = 0ULL;
+ bl33_image_ep_info.args.arg3 = 0ULL;
+#endif
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+#ifdef BL31_LOG_LEVEL
+ SET_LOG_LEVEL(BL31_LOG_LEVEL);
+#endif
+
+ brcm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+
+ plat_bcm_bl31_early_platform_setup((void *)arg0, (void *)arg3);
+
+#ifdef DRIVER_CC_ENABLE
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ plat_brcm_interconnect_init();
+
+ /*
+ * Enable Interconnect coherency for the primary CPU's cluster.
+ * Earlier bootloader stages might already do this (e.g. Trusted
+ * Firmware's BL1 does it) but we can't assume so. There is no harm in
+ * executing this code twice anyway.
+ * Platform specific PSCI code will enable coherency for other
+ * clusters.
+ */
+ plat_brcm_interconnect_enter_coherency();
+#endif
+}
+
+/*******************************************************************************
+ * Perform any BL31 platform setup common to ARM standard platforms
+ ******************************************************************************/
+void brcm_bl31_platform_setup(void)
+{
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ plat_brcm_gic_driver_init();
+ plat_brcm_gic_init();
+
+ /* Initialize power controller before setting up topology */
+ plat_brcm_pwrc_setup();
+}
+
+/*******************************************************************************
+ * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM
+ * standard platforms
+ * Perform BL31 platform setup
+ ******************************************************************************/
+void brcm_bl31_plat_runtime_setup(void)
+{
+ console_switch_state(CONSOLE_FLAG_RUNTIME);
+
+ /* Initialize the runtime console */
+ bcm_console_runtime_init();
+}
+
+void bl31_platform_setup(void)
+{
+ brcm_bl31_platform_setup();
+
+ /* Initialize the secure environment */
+ plat_brcm_security_setup();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+ brcm_bl31_plat_runtime_setup();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup shared between
+ * ARM standard platforms. This only does basic initialization. Later
+ * architectural setup (bl31_arch_setup()) does not do anything platform
+ * specific.
+ ******************************************************************************/
+void __init brcm_bl31_plat_arch_setup(void)
+{
+#ifndef MMU_DISABLED
+ const mmap_region_t bl_regions[] = {
+ MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
+ MT_MEMORY | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
+ MT_CODE | MT_SECURE),
+ MAP_REGION_FLAT(BL_RO_DATA_BASE,
+ BL_RO_DATA_END - BL_RO_DATA_BASE,
+ MT_RO_DATA | MT_SECURE),
+#if USE_COHERENT_MEM
+ MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+#endif
+ {0}
+ };
+
+ setup_page_tables(bl_regions, plat_brcm_get_mmap());
+
+ enable_mmu_el3(0);
+#endif
+}
+
+void __init bl31_plat_arch_setup(void)
+{
+ brcm_bl31_plat_arch_setup();
+}
diff --git a/plat/brcm/common/brcm_ccn.c b/plat/brcm/common/brcm_ccn.c
new file mode 100644
index 000000000..9396aaad2
--- /dev/null
+++ b/plat/brcm/common/brcm_ccn.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <drivers/arm/ccn.h>
+
+#include <platform_def.h>
+
+static const unsigned char master_to_rn_id_map[] = {
+ PLAT_BRCM_CLUSTER_TO_CCN_ID_MAP
+};
+
+static const ccn_desc_t bcm_ccn_desc = {
+ .periphbase = PLAT_BRCM_CCN_BASE,
+ .num_masters = ARRAY_SIZE(master_to_rn_id_map),
+ .master_to_rn_id_map = master_to_rn_id_map
+};
+
+void plat_brcm_interconnect_init(void)
+{
+ ccn_init(&bcm_ccn_desc);
+}
+
+void plat_brcm_interconnect_enter_coherency(void)
+{
+ ccn_enter_snoop_dvm_domain(1 << MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
+}
+
+void plat_brcm_interconnect_exit_coherency(void)
+{
+ ccn_exit_snoop_dvm_domain(1 << MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
+}
diff --git a/plat/brcm/common/brcm_common.c b/plat/brcm/common/brcm_common.c
new file mode 100644
index 000000000..f23719df4
--- /dev/null
+++ b/plat/brcm/common/brcm_common.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <plat/common/platform.h>
+
+#include <plat_brcm.h>
+#include <platform_def.h>
+
+/* Weak definitions may be overridden in specific BRCM platform */
+#pragma weak plat_get_ns_image_entrypoint
+#pragma weak plat_brcm_get_mmap
+
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+ return PRELOADED_BL33_BASE;
+#else
+ return PLAT_BRCM_NS_IMAGE_OFFSET;
+#endif
+}
+
+uint32_t brcm_get_spsr_for_bl32_entry(void)
+{
+ /*
+ * The Secure Payload Dispatcher service is responsible for
+ * setting the SPSR prior to entry into the BL32 image.
+ */
+ return 0;
+}
+
+uint32_t brcm_get_spsr_for_bl33_entry(void)
+{
+ unsigned int mode;
+ uint32_t spsr;
+
+ /* Figure out what mode we enter the non-secure world in */
+ mode = el_implemented(2) ? MODE_EL2 : MODE_EL1;
+
+ /*
+ * TODO: Consider the possibility of specifying the SPSR in
+ * the FIP ToC and allowing the platform to have a say as
+ * well.
+ */
+ spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+}
+
+const mmap_region_t *plat_brcm_get_mmap(void)
+{
+ return plat_brcm_mmap;
+}
diff --git a/plat/brcm/common/brcm_gicv3.c b/plat/brcm/common/brcm_gicv3.c
new file mode 100644
index 000000000..c4137c0c3
--- /dev/null
+++ b/plat/brcm/common/brcm_gicv3.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/gicv3.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t brcm_rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+static const interrupt_prop_t brcm_interrupt_props[] = {
+ /* G1S interrupts */
+ PLAT_BRCM_G1S_IRQ_PROPS(INTR_GROUP1S),
+ /* G0 interrupts */
+ PLAT_BRCM_G0_IRQ_PROPS(INTR_GROUP0)
+};
+
+/*
+ * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
+ * to core position.
+ *
+ * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
+ * values read from GICR_TYPER don't have an MT field. To reuse the same
+ * translation used for CPUs, we insert MT bit read from the PE's MPIDR into
+ * that read from GICR_TYPER.
+ *
+ * Assumptions:
+ *
+ * - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
+ * - No CPUs implemented in the system use affinity level 3.
+ */
+static unsigned int brcm_gicv3_mpidr_hash(u_register_t mpidr)
+{
+ mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
+ return plat_core_pos_by_mpidr(mpidr);
+}
+
+static const gicv3_driver_data_t brcm_gic_data = {
+ .gicd_base = PLAT_BRCM_GICD_BASE,
+ .gicr_base = PLAT_BRCM_GICR_BASE,
+ .interrupt_props = brcm_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(brcm_interrupt_props),
+ .rdistif_num = PLATFORM_CORE_COUNT,
+ .rdistif_base_addrs = brcm_rdistif_base_addrs,
+ .mpidr_to_core_pos = brcm_gicv3_mpidr_hash
+};
+
+void plat_brcm_gic_driver_init(void)
+{
+ /* TODO Check if this is required to be initialized here
+ * after getting initialized in EL3, should we re-init this here
+ * in S-EL1
+ */
+ gicv3_driver_init(&brcm_gic_data);
+}
+
+void plat_brcm_gic_init(void)
+{
+ gicv3_distif_init();
+ gicv3_rdistif_init(plat_my_core_pos());
+ gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+void plat_brcm_gic_cpuif_enable(void)
+{
+ gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+void plat_brcm_gic_cpuif_disable(void)
+{
+ gicv3_cpuif_disable(plat_my_core_pos());
+}
+
+void plat_brcm_gic_pcpu_init(void)
+{
+ gicv3_rdistif_init(plat_my_core_pos());
+}
+
+void plat_brcm_gic_redistif_on(void)
+{
+ gicv3_rdistif_on(plat_my_core_pos());
+}
+
+void plat_brcm_gic_redistif_off(void)
+{
+ gicv3_rdistif_off(plat_my_core_pos());
+}
diff --git a/plat/brcm/common/brcm_image_load.c b/plat/brcm/common/brcm_image_load.c
new file mode 100644
index 000000000..ba02bdad4
--- /dev/null
+++ b/plat/brcm/common/brcm_image_load.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#include <plat/common/platform.h>
+
+#pragma weak plat_flush_next_bl_params
+#pragma weak plat_get_bl_image_load_info
+#pragma weak plat_get_next_bl_params
+
+/*******************************************************************************
+ * This function flushes the data structures so that they are visible
+ * in memory for the next BL image.
+ ******************************************************************************/
+void plat_flush_next_bl_params(void)
+{
+ flush_bl_params_desc();
+}
+
+/*******************************************************************************
+ * This function returns the list of loadable images.
+ ******************************************************************************/
+struct bl_load_info *plat_get_bl_image_load_info(void)
+{
+ return get_bl_load_info_from_mem_params_desc();
+}
+
+/*******************************************************************************
+ * This function returns the list of executable images.
+ ******************************************************************************/
+struct bl_params *plat_get_next_bl_params(void)
+{
+ bl_params_t *next_bl_params = get_next_bl_params_from_mem_params_desc();
+
+ populate_next_bl_params_config(next_bl_params);
+ return next_bl_params;
+}
diff --git a/plat/brcm/common/brcm_io_storage.c b/plat/brcm/common/brcm_io_storage.c
new file mode 100644
index 000000000..66ec29247
--- /dev/null
+++ b/plat/brcm/common/brcm_io_storage.c
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_fip.h>
+#include <drivers/io/io_memmap.h>
+#include <drivers/io/io_storage.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <cmn_plat_def.h>
+#include <cmn_plat_util.h>
+#include <plat_brcm.h>
+#include <platform_def.h>
+
+/* IO devices */
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_handle;
+static const io_dev_connector_t *memmap_dev_con;
+static uintptr_t memmap_dev_handle;
+
+static const io_block_spec_t fip_block_spec = {
+ .offset = PLAT_BRCM_FIP_BASE,
+ .length = PLAT_BRCM_FIP_MAX_SIZE
+};
+
+static const io_block_spec_t qspi_fip_block_spec = {
+ .offset = PLAT_BRCM_FIP_QSPI_BASE,
+ .length = PLAT_BRCM_FIP_MAX_SIZE
+};
+
+static const io_block_spec_t nand_fip_block_spec = {
+ .offset = PLAT_BRCM_FIP_NAND_BASE,
+ .length = PLAT_BRCM_FIP_MAX_SIZE
+};
+
+static const io_uuid_spec_t bl2_uuid_spec = {
+ .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
+};
+
+static const io_uuid_spec_t scp_bl2_uuid_spec = {
+ .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
+};
+
+static const io_uuid_spec_t bl31_uuid_spec = {
+ .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+};
+
+static const io_uuid_spec_t bl32_uuid_spec = {
+ .uuid = UUID_SECURE_PAYLOAD_BL32,
+};
+
+static const io_uuid_spec_t bl32_extra1_uuid_spec = {
+ .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
+};
+
+static const io_uuid_spec_t bl32_extra2_uuid_spec = {
+ .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
+};
+
+static const io_uuid_spec_t bl33_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+};
+
+static const io_uuid_spec_t tb_fw_config_uuid_spec = {
+ .uuid = UUID_TB_FW_CONFIG,
+};
+
+static const io_uuid_spec_t hw_config_uuid_spec = {
+ .uuid = UUID_HW_CONFIG,
+};
+
+static const io_uuid_spec_t soc_fw_config_uuid_spec = {
+ .uuid = UUID_SOC_FW_CONFIG,
+};
+
+static const io_uuid_spec_t tos_fw_config_uuid_spec = {
+ .uuid = UUID_TOS_FW_CONFIG,
+};
+
+static const io_uuid_spec_t nt_fw_config_uuid_spec = {
+ .uuid = UUID_NT_FW_CONFIG,
+};
+
+#if TRUSTED_BOARD_BOOT
+static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_BOOT_FW_CERT,
+};
+
+static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_KEY_CERT,
+};
+
+static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
+ .uuid = UUID_SCP_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
+ .uuid = UUID_SOC_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
+ .uuid = UUID_SCP_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
+ .uuid = UUID_SOC_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
+static int open_fip(const uintptr_t spec);
+static int open_memmap(const uintptr_t spec);
+static int open_qspi(const uintptr_t spec);
+static int open_nand(const uintptr_t spec);
+
+struct plat_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ int (*check)(const uintptr_t spec);
+};
+
+/* By default, BRCM platforms load images from the FIP */
+static const struct plat_io_policy policies[] = {
+ [FIP_IMAGE_ID] = {
+ &memmap_dev_handle,
+ (uintptr_t)&fip_block_spec,
+ open_memmap
+ },
+ [BL2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl2_uuid_spec,
+ open_fip
+ },
+ [SCP_BL2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&scp_bl2_uuid_spec,
+ open_fip
+ },
+ [BL31_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl31_uuid_spec,
+ open_fip
+ },
+ [BL32_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl32_uuid_spec,
+ open_fip
+ },
+ [BL32_EXTRA1_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl32_extra1_uuid_spec,
+ open_fip
+ },
+ [BL32_EXTRA2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl32_extra2_uuid_spec,
+ open_fip
+ },
+ [BL33_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl33_uuid_spec,
+ open_fip
+ },
+ [TB_FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tb_fw_config_uuid_spec,
+ open_fip
+ },
+ [HW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&hw_config_uuid_spec,
+ open_fip
+ },
+ [SOC_FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&soc_fw_config_uuid_spec,
+ open_fip
+ },
+ [TOS_FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tos_fw_config_uuid_spec,
+ open_fip
+ },
+ [NT_FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&nt_fw_config_uuid_spec,
+ open_fip
+ },
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_BOOT_FW_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tb_fw_cert_uuid_spec,
+ open_fip
+ },
+ [TRUSTED_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&trusted_key_cert_uuid_spec,
+ open_fip
+ },
+ [SCP_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&scp_fw_key_cert_uuid_spec,
+ open_fip
+ },
+ [SOC_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&soc_fw_key_cert_uuid_spec,
+ open_fip
+ },
+ [TRUSTED_OS_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tos_fw_key_cert_uuid_spec,
+ open_fip
+ },
+ [NON_TRUSTED_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&nt_fw_key_cert_uuid_spec,
+ open_fip
+ },
+ [SCP_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&scp_fw_cert_uuid_spec,
+ open_fip
+ },
+ [SOC_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&soc_fw_cert_uuid_spec,
+ open_fip
+ },
+ [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tos_fw_cert_uuid_spec,
+ open_fip
+ },
+ [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&nt_fw_cert_uuid_spec,
+ open_fip
+ },
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+/* By default, BRCM platforms load images from the FIP */
+static const struct plat_io_policy boot_source_policies[] = {
+ [BOOT_SOURCE_QSPI] = {
+ &memmap_dev_handle,
+ (uintptr_t)&qspi_fip_block_spec,
+ open_qspi
+ },
+ [BOOT_SOURCE_NAND] = {
+ &memmap_dev_handle,
+ (uintptr_t)&nand_fip_block_spec,
+ open_nand
+ },
+};
+
+/* Weak definitions may be overridden in specific brcm platform */
+#pragma weak plat_brcm_io_setup
+#pragma weak plat_brcm_process_flags
+
+static int open_fip(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ /* See if a Firmware Image Package is available */
+ result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+ if (result == 0) {
+ result = io_open(fip_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using FIP\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+
+static int open_memmap(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
+ if (result == 0) {
+ result = io_open(memmap_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using Memmap\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+static int open_qspi(const uintptr_t spec)
+{
+ return open_memmap(spec);
+}
+
+static int open_nand(const uintptr_t spec)
+{
+ return open_memmap(spec);
+}
+
+
+void brcm_io_setup(void)
+{
+ int io_result;
+ uint32_t boot_source;
+
+ io_result = register_io_dev_fip(&fip_dev_con);
+ assert(io_result == 0);
+
+ io_result = register_io_dev_memmap(&memmap_dev_con);
+ assert(io_result == 0);
+
+ /* Open connections to devices and cache the handles */
+ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
+ &fip_dev_handle);
+ assert(io_result == 0);
+
+ boot_source = boot_source_get();
+ switch (boot_source) {
+ case BOOT_SOURCE_QSPI:
+ case BOOT_SOURCE_NAND:
+ default:
+ io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
+ &memmap_dev_handle);
+ break;
+ }
+ assert(io_result == 0);
+
+ /* Ignore improbable errors in release builds */
+ (void)io_result;
+}
+
+void plat_brcm_io_setup(void)
+{
+ brcm_io_setup();
+}
+
+void plat_brcm_process_flags(uint16_t plat_toc_flags __unused)
+{
+ WARN("%s not implemented\n", __func__);
+}
+
+/*
+ * Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy
+ */
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+ uintptr_t *image_spec)
+{
+ int result;
+ const struct plat_io_policy *policy;
+ uint32_t boot_source;
+ uint16_t lcl_plat_toc_flg;
+
+ assert(image_id < ARRAY_SIZE(policies));
+
+ boot_source = boot_source_get();
+ if (image_id == FIP_IMAGE_ID)
+ policy = &boot_source_policies[boot_source];
+ else
+ policy = &policies[image_id];
+
+ result = policy->check(policy->image_spec);
+ if (result == 0) {
+ *image_spec = policy->image_spec;
+ *dev_handle = *(policy->dev_handle);
+
+ if (image_id == TRUSTED_BOOT_FW_CERT_ID) {
+ /*
+ * Process the header flags to perform
+ * such custom actions as speeding up PLL.
+ * CERT seems to be the first image accessed
+ * by BL1 so this is where we process the flags.
+ */
+ fip_dev_get_plat_toc_flag((io_dev_info_t *)fip_dev_handle,
+ &lcl_plat_toc_flg);
+ plat_brcm_process_flags(lcl_plat_toc_flg);
+ }
+ }
+
+ return result;
+}
diff --git a/plat/brcm/common/brcm_mhu.c b/plat/brcm/common/brcm_mhu.c
new file mode 100644
index 000000000..56f44e0f2
--- /dev/null
+++ b/plat/brcm/common/brcm_mhu.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <drivers/delay_timer.h>
+#include <lib/bakery_lock.h>
+
+#include <brcm_mhu.h>
+#include <platform_def.h>
+
+#include "m0_ipc.h"
+
+#define PLAT_MHU_INTR_REG AP_TO_SCP_MAILBOX1
+
+/* SCP MHU secure channel registers */
+#define SCP_INTR_S_STAT CRMU_IHOST_SW_PERSISTENT_REG11
+#define SCP_INTR_S_SET CRMU_IHOST_SW_PERSISTENT_REG11
+#define SCP_INTR_S_CLEAR CRMU_IHOST_SW_PERSISTENT_REG11
+
+/* CPU MHU secure channel registers */
+#define CPU_INTR_S_STAT CRMU_IHOST_SW_PERSISTENT_REG10
+#define CPU_INTR_S_SET CRMU_IHOST_SW_PERSISTENT_REG10
+#define CPU_INTR_S_CLEAR CRMU_IHOST_SW_PERSISTENT_REG10
+
+static DEFINE_BAKERY_LOCK(bcm_lock);
+
+/*
+ * Slot 31 is reserved because the MHU hardware uses this register bit to
+ * indicate a non-secure access attempt. The total number of available slots is
+ * therefore 31 [30:0].
+ */
+#define MHU_MAX_SLOT_ID 30
+
+void mhu_secure_message_start(unsigned int slot_id)
+{
+ int iter = 1000000;
+
+ assert(slot_id <= MHU_MAX_SLOT_ID);
+
+ bakery_lock_get(&bcm_lock);
+ /* Make sure any previous command has finished */
+ do {
+ if (!(mmio_read_32(PLAT_BRCM_MHU_BASE + CPU_INTR_S_STAT) &
+ (1 << slot_id)))
+ break;
+
+ udelay(1);
+
+ } while (--iter);
+
+ assert(iter != 0);
+}
+
+void mhu_secure_message_send(unsigned int slot_id)
+{
+ uint32_t response, iter = 1000000;
+
+ assert(slot_id <= MHU_MAX_SLOT_ID);
+ assert(!(mmio_read_32(PLAT_BRCM_MHU_BASE + CPU_INTR_S_STAT) &
+ (1 << slot_id)));
+
+ /* Send command to SCP */
+ mmio_setbits_32(PLAT_BRCM_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id);
+ mmio_write_32(CRMU_MAIL_BOX0, MCU_IPC_MCU_CMD_SCPI);
+ mmio_write_32(PLAT_BRCM_MHU_BASE + PLAT_MHU_INTR_REG, 0x1);
+
+ /* Wait until IPC transport acknowledges reception of SCP command */
+ do {
+ response = mmio_read_32(CRMU_MAIL_BOX0);
+ if ((response & ~MCU_IPC_CMD_REPLY_MASK) ==
+ (MCU_IPC_CMD_DONE_MASK | MCU_IPC_MCU_CMD_SCPI))
+ break;
+
+ udelay(1);
+
+ } while (--iter);
+
+ assert(iter != 0);
+}
+
+uint32_t mhu_secure_message_wait(void)
+{
+ /* Wait for response from SCP */
+ uint32_t response, iter = 1000000;
+
+ do {
+ response = mmio_read_32(PLAT_BRCM_MHU_BASE + SCP_INTR_S_STAT);
+ if (!response)
+ break;
+
+ udelay(1);
+ } while (--iter);
+ assert(iter != 0);
+
+ return response;
+}
+
+void mhu_secure_message_end(unsigned int slot_id)
+{
+ assert(slot_id <= MHU_MAX_SLOT_ID);
+
+ /*
+ * Clear any response we got by writing one in the relevant slot bit to
+ * the CLEAR register
+ */
+ mmio_clrbits_32(PLAT_BRCM_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id);
+ bakery_lock_release(&bcm_lock);
+}
+
+void mhu_secure_init(void)
+{
+ bakery_lock_init(&bcm_lock);
+
+ /*
+ * The STAT register resets to zero. Ensure it is in the expected state,
+ * as a stale or garbage value would make us think it's a message we've
+ * already sent.
+ */
+ mmio_write_32(PLAT_BRCM_MHU_BASE + CPU_INTR_S_STAT, 0);
+ mmio_write_32(PLAT_BRCM_MHU_BASE + SCP_INTR_S_STAT, 0);
+}
+
+void plat_brcm_pwrc_setup(void)
+{
+ mhu_secure_init();
+}
diff --git a/plat/brcm/common/brcm_mhu.h b/plat/brcm/common/brcm_mhu.h
new file mode 100644
index 000000000..6c89a34a6
--- /dev/null
+++ b/plat/brcm/common/brcm_mhu.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BRCM_MHU_H
+#define BRCM_MHU_H
+
+#include <stdint.h>
+
+void mhu_secure_message_start(unsigned int slot_id);
+void mhu_secure_message_send(unsigned int slot_id);
+uint32_t mhu_secure_message_wait(void);
+void mhu_secure_message_end(unsigned int slot_id);
+
+void mhu_secure_init(void);
+
+#endif /* BRCM_MHU_H */
diff --git a/plat/brcm/common/brcm_scpi.c b/plat/brcm/common/brcm_scpi.c
new file mode 100644
index 000000000..0a703cb90
--- /dev/null
+++ b/plat/brcm/common/brcm_scpi.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+
+#include <brcm_mhu.h>
+#include <brcm_scpi.h>
+#include <platform_def.h>
+
+#define SCPI_SHARED_MEM_SCP_TO_AP (PLAT_SCP_COM_SHARED_MEM_BASE)
+#define SCPI_SHARED_MEM_AP_TO_SCP (PLAT_SCP_COM_SHARED_MEM_BASE \
+ + 0x100)
+
+/* Header and payload addresses for commands from AP to SCP */
+#define SCPI_CMD_HEADER_AP_TO_SCP \
+ ((scpi_cmd_t *) SCPI_SHARED_MEM_AP_TO_SCP)
+#define SCPI_CMD_PAYLOAD_AP_TO_SCP \
+ ((void *) (SCPI_SHARED_MEM_AP_TO_SCP + sizeof(scpi_cmd_t)))
+
+/* Header and payload addresses for responses from SCP to AP */
+#define SCPI_RES_HEADER_SCP_TO_AP \
+ ((scpi_cmd_t *) SCPI_SHARED_MEM_SCP_TO_AP)
+#define SCPI_RES_PAYLOAD_SCP_TO_AP \
+ ((void *) (SCPI_SHARED_MEM_SCP_TO_AP + sizeof(scpi_cmd_t)))
+
+/* ID of the MHU slot used for the SCPI protocol */
+#define SCPI_MHU_SLOT_ID 0
+
+static void scpi_secure_message_start(void)
+{
+ mhu_secure_message_start(SCPI_MHU_SLOT_ID);
+}
+
+static void scpi_secure_message_send(size_t payload_size)
+{
+ /*
+ * Ensure that any write to the SCPI payload area is seen by SCP before
+ * we write to the MHU register. If these 2 writes were reordered by
+ * the CPU then SCP would read stale payload data
+ */
+ dmbst();
+
+ mhu_secure_message_send(SCPI_MHU_SLOT_ID);
+}
+
+static void scpi_secure_message_receive(scpi_cmd_t *cmd)
+{
+ uint32_t mhu_status;
+
+ assert(cmd != NULL);
+
+ mhu_status = mhu_secure_message_wait();
+
+ /* Expect an SCPI message, reject any other protocol */
+ if (mhu_status != (1 << SCPI_MHU_SLOT_ID)) {
+ ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n",
+ mhu_status);
+ panic();
+ }
+
+ /*
+ * Ensure that any read to the SCPI payload area is done after reading
+ * the MHU register. If these 2 reads were reordered then the CPU would
+ * read invalid payload data
+ */
+ dmbld();
+
+ memcpy(cmd, (void *) SCPI_SHARED_MEM_SCP_TO_AP, sizeof(*cmd));
+}
+
+static void scpi_secure_message_end(void)
+{
+ mhu_secure_message_end(SCPI_MHU_SLOT_ID);
+}
+
+int scpi_wait_ready(void)
+{
+ scpi_cmd_t scpi_cmd;
+
+ VERBOSE("Waiting for SCP_READY command...\n");
+
+ /* Get a message from the SCP */
+ scpi_secure_message_start();
+ scpi_secure_message_receive(&scpi_cmd);
+ scpi_secure_message_end();
+
+ /* We are expecting 'SCP Ready', produce correct error if it's not */
+ scpi_status_t status = SCP_OK;
+
+ if (scpi_cmd.id != SCPI_CMD_SCP_READY) {
+ ERROR("Unexpected SCP command: expected #%u, received #%u\n",
+ SCPI_CMD_SCP_READY, scpi_cmd.id);
+ status = SCP_E_SUPPORT;
+ } else if (scpi_cmd.size != 0) {
+ ERROR("SCP_READY cmd has incorrect size: expected 0, got %u\n",
+ scpi_cmd.size);
+ status = SCP_E_SIZE;
+ }
+
+ VERBOSE("Sending response for SCP_READY command\n");
+
+ /*
+ * Send our response back to SCP.
+ * We are using the same SCPI header, just update the status field.
+ */
+ scpi_cmd.status = status;
+ scpi_secure_message_start();
+ memcpy((void *) SCPI_SHARED_MEM_AP_TO_SCP, &scpi_cmd, sizeof(scpi_cmd));
+ scpi_secure_message_send(0);
+ scpi_secure_message_end();
+
+ return status == SCP_OK ? 0 : -1;
+}
+
+void scpi_set_brcm_power_state(unsigned int mpidr,
+ scpi_power_state_t cpu_state, scpi_power_state_t cluster_state,
+ scpi_power_state_t brcm_state)
+{
+ scpi_cmd_t *cmd;
+ uint32_t state = 0;
+ uint32_t *payload_addr;
+
+#if ARM_PLAT_MT
+ /*
+ * The current SCPI driver only caters for single-threaded platforms.
+ * Hence we ignore the thread ID (which is always 0) for such platforms.
+ */
+ state |= (mpidr >> MPIDR_AFF1_SHIFT) & 0x0f; /* CPU ID */
+ state |= ((mpidr >> MPIDR_AFF2_SHIFT) & 0x0f) << 4; /* Cluster ID */
+#else
+ state |= mpidr & 0x0f; /* CPU ID */
+ state |= (mpidr & 0xf00) >> 4; /* Cluster ID */
+#endif /* ARM_PLAT_MT */
+
+ state |= cpu_state << 8;
+ state |= cluster_state << 12;
+ state |= brcm_state << 16;
+
+ scpi_secure_message_start();
+
+ /* Populate the command header */
+ cmd = SCPI_CMD_HEADER_AP_TO_SCP;
+ cmd->id = SCPI_CMD_SET_POWER_STATE;
+ cmd->set = SCPI_SET_NORMAL;
+ cmd->sender = 0;
+ cmd->size = sizeof(state);
+ /* Populate the command payload */
+ payload_addr = SCPI_CMD_PAYLOAD_AP_TO_SCP;
+ *payload_addr = state;
+ scpi_secure_message_send(sizeof(state));
+
+ /*
+ * SCP does not reply to this command in order to avoid MHU interrupts
+ * from the sender, which could interfere with its power state request.
+ */
+ scpi_secure_message_end();
+}
+
+/*
+ * Query and obtain power state from SCP.
+ *
+ * In response to the query, SCP returns power states of all CPUs in all
+ * clusters of the system. The returned response is then filtered based on the
+ * supplied MPIDR. Power states of requested cluster and CPUs within are updated
+ * via. supplied non-NULL pointer arguments.
+ *
+ * Returns 0 on success, or -1 on errors.
+ */
+int scpi_get_brcm_power_state(unsigned int mpidr, unsigned int *cpu_state_p,
+ unsigned int *cluster_state_p)
+{
+ scpi_cmd_t *cmd;
+ scpi_cmd_t response;
+ int power_state, cpu, cluster, rc = -1;
+
+ /*
+ * Extract CPU and cluster membership of the given MPIDR. SCPI caters
+ * for only up to 0xf clusters, and 8 CPUs per cluster
+ */
+ cpu = mpidr & MPIDR_AFFLVL_MASK;
+ cluster = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+ if (cpu >= 8 || cluster >= 0xf)
+ return -1;
+
+ scpi_secure_message_start();
+
+ /* Populate request headers */
+ zeromem(SCPI_CMD_HEADER_AP_TO_SCP, sizeof(*cmd));
+ cmd = SCPI_CMD_HEADER_AP_TO_SCP;
+ cmd->id = SCPI_CMD_GET_POWER_STATE;
+
+ /*
+ * Send message and wait for SCP's response
+ */
+ scpi_secure_message_send(0);
+ scpi_secure_message_receive(&response);
+
+ if (response.status != SCP_OK)
+ goto exit;
+
+ /* Validate SCP response */
+ if (!CHECK_RESPONSE(response, cluster))
+ goto exit;
+
+ /* Extract power states for required cluster */
+ power_state = *(((uint16_t *) SCPI_RES_PAYLOAD_SCP_TO_AP) + cluster);
+ if (CLUSTER_ID(power_state) != cluster)
+ goto exit;
+
+ /* Update power state via. pointers */
+ if (cluster_state_p)
+ *cluster_state_p = CLUSTER_POWER_STATE(power_state);
+ if (cpu_state_p)
+ *cpu_state_p = CPU_POWER_STATE(power_state);
+ rc = 0;
+
+exit:
+ scpi_secure_message_end();
+ return rc;
+}
+
+uint32_t scpi_sys_power_state(scpi_system_state_t system_state)
+{
+ scpi_cmd_t *cmd;
+ uint8_t *payload_addr;
+
+ scpi_secure_message_start();
+
+ /* Populate the command header */
+ cmd = SCPI_CMD_HEADER_AP_TO_SCP;
+ cmd->id = SCPI_CMD_SYS_POWER_STATE;
+ cmd->set = 0;
+ cmd->sender = 0;
+ cmd->size = sizeof(*payload_addr);
+ /* Populate the command payload */
+ payload_addr = SCPI_CMD_PAYLOAD_AP_TO_SCP;
+ *payload_addr = system_state & 0xff;
+ scpi_secure_message_send(sizeof(*payload_addr));
+
+ scpi_secure_message_end();
+
+ return SCP_OK;
+}
diff --git a/plat/brcm/common/brcm_scpi.h b/plat/brcm/common/brcm_scpi.h
new file mode 100644
index 000000000..f3b658f62
--- /dev/null
+++ b/plat/brcm/common/brcm_scpi.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BRCM_SCPI_H
+#define BRCM_SCPI_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+/*
+ * An SCPI command consists of a header and a payload.
+ * The following structure describes the header. It is 64-bit long.
+ */
+typedef struct {
+ /* Command ID */
+ uint32_t id : 7;
+ /* Set ID. Identifies whether this is a standard or extended command. */
+ uint32_t set : 1;
+ /* Sender ID to match a reply. The value is sender specific. */
+ uint32_t sender : 8;
+ /* Size of the payload in bytes (0 - 511) */
+ uint32_t size : 9;
+ uint32_t reserved : 7;
+ /*
+ * Status indicating the success of a command.
+ * See the enum below.
+ */
+ uint32_t status;
+} scpi_cmd_t;
+
+typedef enum {
+ SCPI_SET_NORMAL = 0, /* Normal SCPI commands */
+ SCPI_SET_EXTENDED /* Extended SCPI commands */
+} scpi_set_t;
+
+enum {
+ SCP_OK = 0, /* Success */
+ SCP_E_PARAM, /* Invalid parameter(s) */
+ SCP_E_ALIGN, /* Invalid alignment */
+ SCP_E_SIZE, /* Invalid size */
+ SCP_E_HANDLER, /* Invalid handler or callback */
+ SCP_E_ACCESS, /* Invalid access or permission denied */
+ SCP_E_RANGE, /* Value out of range */
+ SCP_E_TIMEOUT, /* Time out has ocurred */
+ SCP_E_NOMEM, /* Invalid memory area or pointer */
+ SCP_E_PWRSTATE, /* Invalid power state */
+ SCP_E_SUPPORT, /* Feature not supported or disabled */
+ SCPI_E_DEVICE, /* Device error */
+ SCPI_E_BUSY, /* Device is busy */
+};
+
+typedef uint32_t scpi_status_t;
+typedef enum {
+ SCPI_CMD_SCP_READY = 0x01,
+ SCPI_CMD_SET_POWER_STATE = 0x03,
+ SCPI_CMD_GET_POWER_STATE = 0x04,
+ SCPI_CMD_SYS_POWER_STATE = 0x05
+} scpi_command_t;
+
+/*
+ * Macros to parse SCP response to GET_POWER_STATE command
+ *
+ * [3:0] : cluster ID
+ * [7:4] : cluster state: 0 = on; 3 = off; rest are reserved
+ * [15:8]: on/off state for individual CPUs in the cluster
+ *
+ * Payload is in little-endian
+ */
+#define CLUSTER_ID(_resp) ((_resp) & 0xf)
+#define CLUSTER_POWER_STATE(_resp) (((_resp) >> 4) & 0xf)
+
+/* Result is a bit mask of CPU on/off states in the cluster */
+#define CPU_POWER_STATE(_resp) (((_resp) >> 8) & 0xff)
+
+/*
+ * For GET_POWER_STATE, SCP returns the power states of every cluster. The
+ * size of response depends on the number of clusters in the system. The
+ * SCP-to-AP payload contains 2 bytes per cluster. Make sure the response is
+ * large enough to contain power states of a given cluster
+ */
+#define CHECK_RESPONSE(_resp, _clus) (_resp.size >= (((_clus) + 1) * 2))
+
+typedef enum {
+ scpi_power_on = 0,
+ scpi_power_retention = 1,
+ scpi_power_off = 3,
+} scpi_power_state_t;
+
+typedef enum {
+ scpi_system_shutdown = 0,
+ scpi_system_reboot = 1,
+ scpi_system_reset = 2
+} scpi_system_state_t;
+
+extern int scpi_wait_ready(void);
+extern void scpi_set_brcm_power_state(unsigned int mpidr,
+ scpi_power_state_t cpu_state,
+ scpi_power_state_t cluster_state,
+ scpi_power_state_t css_state);
+int scpi_get_brcm_power_state(unsigned int mpidr, unsigned int *cpu_state_p,
+ unsigned int *cluster_state_p);
+uint32_t scpi_sys_power_state(scpi_system_state_t system_state);
+
+#endif /* BRCM_SCPI_H */
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index f8d312952..ba4c366a9 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,7 @@
#if RAS_EXTENSION
#include <lib/extensions/ras.h>
#endif
+#include <lib/extensions/twed.h>
#include <lib/xlat_tables/xlat_mmu_helpers.h>
#include <plat/common/platform.h>
@@ -20,6 +21,7 @@
* platforms but may also be overridden by a platform if required.
*/
#pragma weak bl31_plat_runtime_setup
+#pragma weak plat_arm_set_twedel_scr_el3
#if SDEI_SUPPORT
#pragma weak plat_sdei_handle_masked_trigger
@@ -64,6 +66,18 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
}
#endif
+#if !ENABLE_BACKTRACE
+static const char *get_el_str(unsigned int el)
+{
+ if (el == MODE_EL3) {
+ return "EL3";
+ } else if (el == MODE_EL2) {
+ return "EL2";
+ }
+ return "S-EL1";
+}
+#endif /* !ENABLE_BACKTRACE */
+
/* RAS functions common to AArch64 ARM platforms */
void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
void *handle, uint64_t flags)
@@ -74,9 +88,30 @@ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
if (handled != 0)
return;
#endif
+ unsigned int level = (unsigned int)GET_EL(read_spsr_el3());
- ERROR("Unhandled External Abort received on 0x%lx at EL3!\n",
- read_mpidr_el1());
- ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome);
+ ERROR("Unhandled External Abort received on 0x%lx from %s\n",
+ read_mpidr_el1(), get_el_str(level));
+ ERROR("exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome);
+#if HANDLE_EA_EL3_FIRST
+ /* Skip backtrace for lower EL */
+ if (level != MODE_EL3) {
+ console_flush();
+ do_panic();
+ }
+#endif
panic();
}
+
+/*******************************************************************************
+ * In v8.6+ platforms with delayed trapping of WFE this hook sets the delay. It
+ * is a weak function definition so can be overridden depending on the
+ * requirements of a platform. The only hook provided is for the TWED fields
+ * in SCR_EL3, the TWED fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 should be
+ * configured as needed in lower exception levels.
+ ******************************************************************************/
+
+uint32_t plat_arm_set_twedel_scr_el3(void)
+{
+ return TWED_DISABLED;
+}
diff --git a/plat/common/aarch64/plat_ehf.c b/plat/common/aarch64/plat_ehf.c
new file mode 100644
index 000000000..da768843e
--- /dev/null
+++ b/plat/common/aarch64/plat_ehf.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, Broadcom
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl31/ehf.h>
+
+#include <platform_def.h>
+
+/*
+ * Enumeration of priority levels on ARM platforms.
+ */
+ehf_pri_desc_t plat_exceptions[] = {
+#if RAS_EXTENSION
+ /* RAS Priority */
+ EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_RAS_PRI),
+#endif
+
+#if SDEI_SUPPORT
+ /* Critical priority SDEI */
+ EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_CRITICAL_PRI),
+
+ /* Normal priority SDEI */
+ EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
+#endif
+#if SPM_MM
+ EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI),
+#endif
+ /* Plaform specific exceptions description */
+#ifdef PLAT_EHF_DESC
+ PLAT_EHF_DESC,
+#endif
+};
+
+/* Plug in ARM exceptions to Exception Handling Framework. */
+EHF_REGISTER_PRIORITIES(plat_exceptions, ARRAY_SIZE(plat_exceptions), PLAT_PRI_BITS);
diff --git a/plat/common/aarch64/platform_mp_stack.S b/plat/common/aarch64/platform_mp_stack.S
index f9780e80c..c0668ea78 100644
--- a/plat/common/aarch64/platform_mp_stack.S
+++ b/plat/common/aarch64/platform_mp_stack.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,7 +14,7 @@
.weak plat_set_my_stack
/* ---------------------------------------------------------------------
- * When the compatility layer is disabled, the platform APIs
+ * When the compatibility layer is disabled, the platform APIs
* plat_get_my_stack() and plat_set_my_stack() are supported by the
* platform and the previous APIs platform_get_stack() and
* platform_set_stack() are defined in terms of new APIs making use of
@@ -32,7 +32,7 @@
* -----------------------------------------------------
*/
func plat_get_my_stack
- mov x10, x30 // lr
+ mov x10, x30
get_my_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE
ret x10
endfunc plat_get_my_stack
@@ -45,14 +45,14 @@ endfunc plat_get_my_stack
* -----------------------------------------------------
*/
func plat_set_my_stack
- mov x9, x30 // lr
+ mov x9, x30
bl plat_get_my_stack
mov sp, x0
ret x9
endfunc plat_set_my_stack
/* -----------------------------------------------------
- * Per-cpu stacks in normal memory. Each cpu gets a
+ * Per-CPU stacks in normal memory. Each CPU gets a
* stack of PLATFORM_STACK_SIZE bytes.
* -----------------------------------------------------
*/
diff --git a/plat/common/plat_bl1_common.c b/plat/common/plat_bl1_common.c
index 5733781ac..1c6d68b2b 100644
--- a/plat/common/plat_bl1_common.c
+++ b/plat/common/plat_bl1_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,7 +27,9 @@
#pragma weak bl1_plat_fwu_done
#pragma weak bl1_plat_handle_pre_image_load
#pragma weak bl1_plat_handle_post_image_load
-
+#if MEASURED_BOOT
+#pragma weak bl1_plat_set_bl2_hash
+#endif
unsigned int bl1_plat_get_next_image_id(void)
{
@@ -58,7 +60,7 @@ struct image_desc *bl1_plat_get_image_desc(unsigned int image_id)
__dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved)
{
- while (1)
+ while (true)
wfi();
}
@@ -81,8 +83,8 @@ int bl1_plat_mem_check(uintptr_t mem_base, unsigned int mem_size,
*/
int bl1_plat_handle_post_image_load(unsigned int image_id)
{
- meminfo_t *bl2_tzram_layout;
- meminfo_t *bl1_tzram_layout;
+ meminfo_t *bl2_secram_layout;
+ meminfo_t *bl1_secram_layout;
image_desc_t *image_desc;
entry_point_info_t *ep_info;
@@ -97,7 +99,7 @@ int bl1_plat_handle_post_image_load(unsigned int image_id)
ep_info = &image_desc->ep_info;
/* Find out how much free trusted ram remains after BL1 load */
- bl1_tzram_layout = bl1_plat_sec_mem_layout();
+ bl1_secram_layout = bl1_plat_sec_mem_layout();
/*
* Create a new layout of memory for BL2 as seen by BL1 i.e.
@@ -106,13 +108,22 @@ int bl1_plat_handle_post_image_load(unsigned int image_id)
* to BL2. BL2 will read the memory layout before using its
* memory for other purposes.
*/
- bl2_tzram_layout = (meminfo_t *) bl1_tzram_layout->total_base;
+ bl2_secram_layout = (meminfo_t *) bl1_secram_layout->total_base;
- bl1_calc_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout);
+ bl1_calc_bl2_mem_layout(bl1_secram_layout, bl2_secram_layout);
- ep_info->args.arg1 = (uintptr_t)bl2_tzram_layout;
+ ep_info->args.arg1 = (uintptr_t)bl2_secram_layout;
VERBOSE("BL1: BL2 memory layout address = %p\n",
- (void *) bl2_tzram_layout);
+ (void *) bl2_secram_layout);
return 0;
}
+
+#if MEASURED_BOOT
+/*
+ * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB.
+ */
+void bl1_plat_set_bl2_hash(const image_desc_t *image_desc)
+{
+}
+#endif
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index b46656c7a..89b77ba6c 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -1,17 +1,19 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-#include <errno.h>
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/common/platform.h>
+#include <services/arm_arch_svc.h>
+#include <smccc_helpers.h>
+#include <tools_share/firmware_encrypted.h>
/*
* The following platform functions are weakly defined. The Platforms
@@ -23,6 +25,25 @@
#pragma weak bl2_plat_handle_pre_image_load
#pragma weak bl2_plat_handle_post_image_load
#pragma weak plat_try_next_boot_source
+#pragma weak plat_get_enc_key_info
+#pragma weak plat_is_smccc_feature_available
+#pragma weak plat_get_soc_version
+#pragma weak plat_get_soc_revision
+
+int32_t plat_get_soc_version(void)
+{
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+}
+
+int32_t plat_get_soc_revision(void)
+{
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+}
+
+int32_t plat_is_smccc_feature_available(u_register_t fid __unused)
+{
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+}
void bl2_el3_plat_prepare_exit(void)
{
@@ -54,6 +75,31 @@ int plat_try_next_boot_source(void)
}
/*
+ * Weak implementation to provide dummy decryption key only for test purposes,
+ * platforms must override this API for any real world firmware encryption
+ * use-case.
+ */
+int plat_get_enc_key_info(enum fw_enc_status_t fw_enc_status, uint8_t *key,
+ size_t *key_len, unsigned int *flags,
+ const uint8_t *img_id, size_t img_id_len)
+{
+#define DUMMY_FIP_ENC_KEY { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, \
+ 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, \
+ 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, \
+ 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef }
+
+ const uint8_t dummy_key[] = DUMMY_FIP_ENC_KEY;
+
+ assert(*key_len >= sizeof(dummy_key));
+
+ *key_len = sizeof(dummy_key);
+ memcpy(key, dummy_key, *key_len);
+ *flags = 0;
+
+ return 0;
+}
+
+/*
* Set up the page tables for the generic and platform-specific memory regions.
* The size of the Trusted SRAM seen by the BL image must be specified as well
* as an array specifying the generic memory regions which can be;
diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c
index 80ed8198b..c32e59f9c 100644
--- a/plat/common/plat_psci_common.c
+++ b/plat/common/plat_psci_common.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +10,7 @@
#include <arch.h>
#include <lib/pmf/pmf.h>
#include <lib/psci/psci.h>
+#include <lib/utils_def.h>
#include <plat/common/platform.h>
#if ENABLE_PSCI_STAT && ENABLE_PMF
@@ -16,9 +18,6 @@
#pragma weak plat_psci_stat_accounting_stop
#pragma weak plat_psci_stat_get_residency
-/* Ticks elapsed in one second by a signal of 1 MHz */
-#define MHZ_TICKS_PER_SEC 1000000U
-
/* Maximum time-stamp value read from architectural counters */
#ifdef __aarch64__
#define MAX_TS UINT64_MAX
@@ -64,7 +63,6 @@ static u_register_t calc_stat_residency(unsigned long long pwrupts,
/*
* Capture timestamp before entering a low power state.
- * No cache maintenance is required when capturing the timestamp.
* Cache maintenance may be needed when reading these timestamps.
*/
void plat_psci_stat_accounting_start(
@@ -72,12 +70,11 @@ void plat_psci_stat_accounting_start(
{
assert(state_info != NULL);
PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR,
- PMF_NO_CACHE_MAINT);
+ PMF_CACHE_MAINT);
}
/*
* Capture timestamp after exiting a low power state.
- * No cache maintenance is required when capturing the timestamp.
* Cache maintenance may be needed when reading these timestamps.
*/
void plat_psci_stat_accounting_stop(
@@ -85,7 +82,7 @@ void plat_psci_stat_accounting_stop(
{
assert(state_info != NULL);
PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_EXIT_LOW_PWR,
- PMF_NO_CACHE_MAINT);
+ PMF_CACHE_MAINT);
}
/*
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
new file mode 100644
index 000000000..8f4018c7c
--- /dev/null
+++ b/plat/common/plat_spmd_manifest.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <libfdt.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <platform_def.h>
+#include <services/spm_core_manifest.h>
+
+#define ATTRIBUTE_ROOT_NODE_STR "attribute"
+
+/*******************************************************************************
+ * SPMC attribute node parser
+ ******************************************************************************/
+static int manifest_parse_attribute(spmc_manifest_attribute_t *attr,
+ const void *fdt,
+ int node)
+{
+ uint32_t val32;
+ int rc;
+
+ assert((attr != NULL) && (fdt != NULL));
+
+ rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version);
+ if (rc != 0) {
+ ERROR("Missing FFA %s version in SPM Core manifest.\n",
+ "major");
+ return rc;
+ }
+
+ rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version);
+ if (rc != 0) {
+ ERROR("Missing FFA %s version in SPM Core manifest.\n",
+ "minor");
+ return rc;
+ }
+
+ rc = fdt_read_uint32(fdt, node, "spmc_id", &val32);
+ if (rc != 0) {
+ ERROR("Missing SPMC ID in manifest.\n");
+ return rc;
+ }
+
+ attr->spmc_id = val32 & 0xffff;
+
+ rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state);
+ if (rc != 0) {
+ NOTICE("%s not specified in SPM Core manifest.\n",
+ "Execution state");
+ }
+
+ rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size);
+ if (rc != 0) {
+ NOTICE("%s not specified in SPM Core manifest.\n",
+ "Binary size");
+ }
+
+ rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address);
+ if (rc != 0) {
+ NOTICE("%s not specified in SPM Core manifest.\n",
+ "Load address");
+ }
+
+ rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint);
+ if (rc != 0) {
+ NOTICE("%s not specified in SPM Core manifest.\n",
+ "Entry point");
+ }
+
+ VERBOSE("SPM Core manifest attribute section:\n");
+ VERBOSE(" version: %u.%u\n", attr->major_version, attr->minor_version);
+ VERBOSE(" spmc_id: 0x%x\n", attr->spmc_id);
+ VERBOSE(" binary_size: 0x%x\n", attr->binary_size);
+ VERBOSE(" load_address: 0x%llx\n", attr->load_address);
+ VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Root node handler
+ ******************************************************************************/
+static int manifest_parse_root(spmc_manifest_attribute_t *manifest,
+ const void *fdt,
+ int root)
+{
+ int node;
+
+ assert(manifest != NULL);
+
+ node = fdt_subnode_offset_namelen(fdt, root, ATTRIBUTE_ROOT_NODE_STR,
+ sizeof(ATTRIBUTE_ROOT_NODE_STR) - 1);
+ if (node < 0) {
+ ERROR("Root node doesn't contain subnode '%s'\n",
+ ATTRIBUTE_ROOT_NODE_STR);
+ return node;
+ }
+
+ return manifest_parse_attribute(manifest, fdt, node);
+}
+
+/*******************************************************************************
+ * Platform handler to parse a SPM Core manifest.
+ ******************************************************************************/
+int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest,
+ const void *pm_addr)
+{
+ int rc, unmap_ret;
+ uintptr_t pm_base, pm_base_align;
+ size_t mapped_size;
+
+ assert(manifest != NULL);
+ assert(pm_addr != NULL);
+
+ /*
+ * Assume TOS_FW_CONFIG is not necessarily aligned to a page
+ * boundary, thus calculate the remaining space between SPMC
+ * manifest start address and upper page limit.
+ *
+ */
+ pm_base = (uintptr_t)pm_addr;
+ pm_base_align = page_align(pm_base, UP);
+
+ if (pm_base == pm_base_align) {
+ /* Page aligned */
+ mapped_size = PAGE_SIZE;
+ } else {
+ mapped_size = pm_base_align - pm_base;
+ }
+
+ /* Check space within the page at least maps the FDT header */
+ if (mapped_size < sizeof(struct fdt_header)) {
+ ERROR("Error while mapping SPM Core manifest.\n");
+ return -EINVAL;
+ }
+
+ /* Map first SPMC manifest page in the SPMD translation regime */
+ pm_base_align = page_align(pm_base, DOWN);
+ rc = mmap_add_dynamic_region((unsigned long long)pm_base_align,
+ pm_base_align,
+ PAGE_SIZE,
+ MT_RO_DATA);
+ if (rc != 0) {
+ ERROR("Error while mapping SPM Core manifest (%d).\n", rc);
+ return rc;
+ }
+
+ rc = fdt_check_header(pm_addr);
+ if (rc != 0) {
+ ERROR("Wrong format for SPM Core manifest (%d).\n", rc);
+ goto exit_unmap;
+ }
+
+ /* Check SPMC manifest fits within the upper mapped page boundary */
+ if (mapped_size < fdt_totalsize(pm_addr)) {
+ ERROR("SPM Core manifest too large.\n");
+ rc = -EINVAL;
+ goto exit_unmap;
+ }
+
+ VERBOSE("Reading SPM Core manifest at address %p\n", pm_addr);
+
+ rc = fdt_node_offset_by_compatible(pm_addr, -1,
+ "arm,ffa-core-manifest-1.0");
+ if (rc < 0) {
+ ERROR("Unrecognized SPM Core manifest\n");
+ goto exit_unmap;
+ }
+
+ rc = manifest_parse_root(manifest, pm_addr, rc);
+
+exit_unmap:
+ unmap_ret = mmap_remove_dynamic_region(pm_base_align, PAGE_SIZE);
+ if (unmap_ret != 0) {
+ ERROR("Error while unmapping SPM Core manifest (%d).\n",
+ unmap_ret);
+ if (rc == 0) {
+ rc = unmap_ret;
+ }
+ }
+
+ return rc;
+}
diff --git a/plat/hisilicon/hikey/aarch64/hikey_helpers.S b/plat/hisilicon/hikey/aarch64/hikey_helpers.S
index 1752d3bb9..82a404ad3 100644
--- a/plat/hisilicon/hikey/aarch64/hikey_helpers.S
+++ b/plat/hisilicon/hikey/aarch64/hikey_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -62,10 +62,10 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush()
+ * void plat_crash_console_flush()
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : x0, x1
* ---------------------------------------------
*/
diff --git a/plat/hisilicon/hikey/hikey_bl1_setup.c b/plat/hisilicon/hikey/hikey_bl1_setup.c
index a97d76320..86e4fd637 100644
--- a/plat/hisilicon/hikey/hikey_bl1_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl1_setup.c
@@ -26,7 +26,7 @@
/* Data structure which holds the extents of the trusted RAM for BL1 */
static meminfo_t bl1_tzram_layout;
-static console_pl011_t console;
+static console_t console;
enum {
BOOT_NORMAL = 0,
diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c
index 96136ec12..feb7f8a46 100644
--- a/plat/hisilicon/hikey/hikey_bl2_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl2_setup.c
@@ -32,7 +32,7 @@
#define BL2_RW_BASE (BL_CODE_END)
static meminfo_t bl2_el3_tzram_layout;
-static console_pl011_t console;
+static console_t console;
enum {
BOOT_MODE_RECOVERY = 0,
diff --git a/plat/hisilicon/hikey/hikey_bl31_setup.c b/plat/hisilicon/hikey/hikey_bl31_setup.c
index 0326e9f3d..7d008e741 100644
--- a/plat/hisilicon/hikey/hikey_bl31_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl31_setup.c
@@ -27,7 +27,7 @@
static entry_point_info_t bl32_ep_info;
static entry_point_info_t bl33_ep_info;
-static console_pl011_t console;
+static console_t console;
/******************************************************************************
* On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk
index fbf743292..18197cf4d 100644
--- a/plat/hisilicon/hikey/platform.mk
+++ b/plat/hisilicon/hikey/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -126,17 +126,19 @@ include drivers/auth/mbedtls/mbedtls_x509.mk
AUTH_SOURCES := drivers/auth/auth_mod.c \
drivers/auth/crypto_mod.c \
drivers/auth/img_parser_mod.c \
- drivers/auth/tbbr/tbbr_cot.c
+ drivers/auth/tbbr/tbbr_cot_common.c
BL1_SOURCES += ${AUTH_SOURCES} \
plat/common/tbbr/plat_tbbr.c \
plat/hisilicon/hikey/hikey_tbbr.c \
- plat/hisilicon/hikey/hikey_rotpk.S
+ plat/hisilicon/hikey/hikey_rotpk.S \
+ drivers/auth/tbbr/tbbr_cot_bl1.c
BL2_SOURCES += ${AUTH_SOURCES} \
plat/common/tbbr/plat_tbbr.c \
plat/hisilicon/hikey/hikey_tbbr.c \
- plat/hisilicon/hikey/hikey_rotpk.S
+ plat/hisilicon/hikey/hikey_rotpk.S \
+ drivers/auth/tbbr/tbbr_cot_bl2.c
ROT_KEY = $(BUILD_PLAT)/rot_key.pem
ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
diff --git a/plat/hisilicon/hikey960/aarch64/hikey960_helpers.S b/plat/hisilicon/hikey960/aarch64/hikey960_helpers.S
index 606f2d0f9..5381369bc 100644
--- a/plat/hisilicon/hikey960/aarch64/hikey960_helpers.S
+++ b/plat/hisilicon/hikey960/aarch64/hikey960_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -66,10 +66,10 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush()
+ * void plat_crash_console_flush()
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : x0, x1
* ---------------------------------------------
*/
diff --git a/plat/hisilicon/hikey960/hikey960_bl1_setup.c b/plat/hisilicon/hikey960/hikey960_bl1_setup.c
index 4a7036cfc..0a2d062a5 100644
--- a/plat/hisilicon/hikey960/hikey960_bl1_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl1_setup.c
@@ -41,7 +41,7 @@ enum {
/* Data structure which holds the extents of the trusted RAM for BL1 */
static meminfo_t bl1_tzram_layout;
-static console_pl011_t console;
+static console_t console;
/******************************************************************************
* On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
diff --git a/plat/hisilicon/hikey960/hikey960_bl2_setup.c b/plat/hisilicon/hikey960/hikey960_bl2_setup.c
index 35d76921d..c1c2a8c59 100644
--- a/plat/hisilicon/hikey960/hikey960_bl2_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl2_setup.c
@@ -32,7 +32,7 @@
#define BL2_RW_BASE (BL_CODE_END)
static meminfo_t bl2_el3_tzram_layout;
-static console_pl011_t console;
+static console_t console;
extern int load_lpm3(void);
enum {
diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
index 9383265ec..f5f8ffed0 100644
--- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
@@ -29,7 +29,7 @@
static entry_point_info_t bl32_ep_info;
static entry_point_info_t bl33_ep_info;
-static console_pl011_t console;
+static console_t console;
/******************************************************************************
* On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
@@ -166,6 +166,7 @@ void bl31_platform_setup(void)
hikey960_edma_init();
hikey960_iomcu_dma_init();
+ hikey960_gpio_init();
hisi_ipc_init();
}
diff --git a/plat/hisilicon/hikey960/hikey960_bl_common.c b/plat/hisilicon/hikey960/hikey960_bl_common.c
index 89adccb2b..3c4a164ff 100644
--- a/plat/hisilicon/hikey960/hikey960_bl_common.c
+++ b/plat/hisilicon/hikey960/hikey960_bl_common.c
@@ -466,6 +466,13 @@ void hikey960_gpio_init(void)
pl061_gpio_register(GPIO19_BASE, 19);
pl061_gpio_register(GPIO20_BASE, 20);
pl061_gpio_register(GPIO21_BASE, 21);
+ pl061_gpio_register(GPIO22_BASE, 22);
+ pl061_gpio_register(GPIO23_BASE, 23);
+ pl061_gpio_register(GPIO24_BASE, 24);
+ pl061_gpio_register(GPIO25_BASE, 25);
+ pl061_gpio_register(GPIO26_BASE, 26);
+ pl061_gpio_register(GPIO27_BASE, 27);
+ pl061_gpio_register(GPIO28_BASE, 28);
/* PCIE_PERST_N output low */
gpio_set_direction(89, GPIO_DIR_OUT);
diff --git a/plat/hisilicon/hikey960/hikey960_pm.c b/plat/hisilicon/hikey960/hikey960_pm.c
index ede893ecb..f836508d5 100644
--- a/plat/hisilicon/hikey960/hikey960_pm.c
+++ b/plat/hisilicon/hikey960/hikey960_pm.c
@@ -11,6 +11,7 @@
#include <drivers/arm/cci.h>
#include <drivers/arm/gicv2.h>
#include <drivers/arm/pl011.h>
+#include <drivers/arm/pl061_gpio.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
@@ -33,7 +34,7 @@
#define AXI_CONF_BASE 0x820
static unsigned int uart_base;
-static console_pl011_t console;
+static console_t console;
static uintptr_t hikey960_sec_entrypoint;
static void hikey960_pwr_domain_standby(plat_local_state_t cpu_state)
@@ -116,6 +117,13 @@ void hikey960_pwr_domain_off(const psci_power_state_t *target_state)
}
}
+static void __dead2 hikey960_system_off(void)
+{
+ gpio_set_direction(176, GPIO_DIR_OUT);
+ gpio_set_value(176, GPIO_LEVEL_LOW);
+ panic();
+}
+
static void __dead2 hikey960_system_reset(void)
{
dsb();
@@ -293,7 +301,7 @@ static const plat_psci_ops_t hikey960_psci_ops = {
.pwr_domain_off = hikey960_pwr_domain_off,
.pwr_domain_suspend = hikey960_pwr_domain_suspend,
.pwr_domain_suspend_finish = hikey960_pwr_domain_suspend_finish,
- .system_off = NULL,
+ .system_off = hikey960_system_off,
.system_reset = hikey960_system_reset,
.validate_power_state = hikey960_validate_power_state,
.validate_ns_entrypoint = hikey960_validate_ns_entrypoint,
diff --git a/plat/hisilicon/hikey960/include/hi3660.h b/plat/hisilicon/hikey960/include/hi3660.h
index 7cc1ee0b8..17b495f21 100644
--- a/plat/hisilicon/hikey960/include/hi3660.h
+++ b/plat/hisilicon/hikey960/include/hi3660.h
@@ -260,6 +260,13 @@
#define GPIO17_BASE UL(0xE8A1C000)
#define GPIO20_BASE UL(0xE8A1F000)
#define GPIO21_BASE UL(0xE8A20000)
+#define GPIO22_BASE UL(0xFFF0B000)
+#define GPIO23_BASE UL(0xFFF0C000)
+#define GPIO24_BASE UL(0xFFF0D000)
+#define GPIO25_BASE UL(0xFFF0E000)
+#define GPIO26_BASE UL(0xFFF0F000)
+#define GPIO27_BASE UL(0xFFF10000)
+#define GPIO28_BASE UL(0xFFF1D000)
#define TZC_REG_BASE 0xE8A21000
#define TZC_STAT0_REG (TZC_REG_BASE + 0x800)
diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk
index 6cb53c7b6..fc2c209f8 100644
--- a/plat/hisilicon/hikey960/platform.mk
+++ b/plat/hisilicon/hikey960/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -19,7 +19,7 @@ endif
CRASH_CONSOLE_BASE := PL011_UART6_BASE
COLD_BOOT_SINGLE_CPU := 1
-PLAT_PL061_MAX_GPIOS := 176
+PLAT_PL061_MAX_GPIOS := 232
PROGRAMMABLE_RESET_ADDRESS := 1
ENABLE_SVE_FOR_NS := 0
PLAT_PARTITION_BLOCK_SIZE := 4096
@@ -95,12 +95,15 @@ BL2_SOURCES += lib/optee/optee_utils.c
endif
BL31_SOURCES += drivers/arm/cci/cci.c \
+ drivers/arm/pl061/pl061_gpio.c \
+ drivers/gpio/gpio.c \
lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a72.S \
lib/cpus/aarch64/cortex_a73.S \
plat/common/plat_psci_common.c \
plat/hisilicon/hikey960/aarch64/hikey960_helpers.S \
plat/hisilicon/hikey960/hikey960_bl31_setup.c \
+ plat/hisilicon/hikey960/hikey960_bl_common.c \
plat/hisilicon/hikey960/hikey960_pm.c \
plat/hisilicon/hikey960/hikey960_topology.c \
plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c \
@@ -115,17 +118,19 @@ include drivers/auth/mbedtls/mbedtls_x509.mk
AUTH_SOURCES := drivers/auth/auth_mod.c \
drivers/auth/crypto_mod.c \
drivers/auth/img_parser_mod.c \
- drivers/auth/tbbr/tbbr_cot.c
+ drivers/auth/tbbr/tbbr_cot_common.c
BL1_SOURCES += ${AUTH_SOURCES} \
plat/common/tbbr/plat_tbbr.c \
plat/hisilicon/hikey960/hikey960_tbbr.c \
- plat/hisilicon/hikey960/hikey960_rotpk.S
+ plat/hisilicon/hikey960/hikey960_rotpk.S \
+ drivers/auth/tbbr/tbbr_cot_bl1.c
BL2_SOURCES += ${AUTH_SOURCES} \
plat/common/tbbr/plat_tbbr.c \
plat/hisilicon/hikey960/hikey960_tbbr.c \
- plat/hisilicon/hikey960/hikey960_rotpk.S
+ plat/hisilicon/hikey960/hikey960_rotpk.S \
+ drivers/auth/tbbr/tbbr_cot_bl2.c
ROT_KEY = $(BUILD_PLAT)/rot_key.pem
ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
diff --git a/plat/hisilicon/poplar/aarch64/poplar_helpers.S b/plat/hisilicon/poplar/aarch64/poplar_helpers.S
index 928dbefcc..063ee6494 100644
--- a/plat/hisilicon/poplar/aarch64/poplar_helpers.S
+++ b/plat/hisilicon/poplar/aarch64/poplar_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -65,10 +65,10 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush()
+ * void plat_crash_console_flush()
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : r0
* ---------------------------------------------
*/
diff --git a/plat/hisilicon/poplar/bl1_plat_setup.c b/plat/hisilicon/poplar/bl1_plat_setup.c
index 08ad67c59..047ba6291 100644
--- a/plat/hisilicon/poplar/bl1_plat_setup.c
+++ b/plat/hisilicon/poplar/bl1_plat_setup.c
@@ -28,7 +28,7 @@
/* Data structure which holds the extents of the trusted RAM for BL1 */
static meminfo_t bl1_tzram_layout;
static meminfo_t bl2_tzram_layout;
-static console_pl011_t console;
+static console_t console;
/*
* Cannot use default weak implementation in bl1_main.c because BL1 RW data is
diff --git a/plat/hisilicon/poplar/bl2_plat_setup.c b/plat/hisilicon/poplar/bl2_plat_setup.c
index cc9d9754e..482935c4a 100644
--- a/plat/hisilicon/poplar/bl2_plat_setup.c
+++ b/plat/hisilicon/poplar/bl2_plat_setup.c
@@ -25,7 +25,7 @@
#include "plat_private.h"
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
-static console_pl011_t console;
+static console_t console;
/*******************************************************************************
* Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
diff --git a/plat/hisilicon/poplar/bl31_plat_setup.c b/plat/hisilicon/poplar/bl31_plat_setup.c
index 981ef376b..a4e17cabc 100644
--- a/plat/hisilicon/poplar/bl31_plat_setup.c
+++ b/plat/hisilicon/poplar/bl31_plat_setup.c
@@ -29,7 +29,7 @@
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
-static console_pl011_t console;
+static console_t console;
static void hisi_tzpc_sec_init(void)
{
diff --git a/plat/imx/common/aarch32/imx_uart_console.S b/plat/imx/common/aarch32/imx_uart_console.S
index 1c729b1d7..1a1229aab 100644
--- a/plat/imx/common/aarch32/imx_uart_console.S
+++ b/plat/imx/common/aarch32/imx_uart_console.S
@@ -20,7 +20,7 @@ func console_imx_uart_register
mov r4, r3
cmp r4, #0
beq register_fail
- str r0, [r4, #CONSOLE_T_DRVDATA]
+ str r0, [r4, #CONSOLE_T_BASE]
bl console_imx_uart_core_init
cmp r0, #0
@@ -35,16 +35,16 @@ register_fail:
endfunc console_imx_uart_register
func console_imx_uart_putc
- ldr r1, [r1, #CONSOLE_T_DRVDATA]
+ ldr r1, [r1, #CONSOLE_T_BASE]
b console_imx_uart_core_putc
endfunc console_imx_uart_putc
func console_imx_uart_getc
- ldr r0, [r0, #CONSOLE_T_DRVDATA]
+ ldr r0, [r0, #CONSOLE_T_BASE]
b console_imx_uart_core_getc
endfunc console_imx_uart_getc
func console_imx_uart_flush
- ldr r0, [r0, #CONSOLE_T_DRVDATA]
+ ldr r0, [r0, #CONSOLE_T_BASE]
b console_imx_uart_core_flush
endfunc console_imx_uart_flush
diff --git a/plat/imx/common/imx_ehf.c b/plat/imx/common/imx_ehf.c
new file mode 100644
index 000000000..a9396cd5e
--- /dev/null
+++ b/plat/imx/common/imx_ehf.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl31/ehf.h>
+
+#include <platform_def.h>
+
+ehf_pri_desc_t imx_exceptions[] = {
+#if SDEI_SUPPORT
+ /* Critical priority SDEI */
+ EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_CRITICAL_PRI),
+
+ /* Normal priority SDEI */
+ EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
+#endif
+};
+
+/* Plug in ARM exceptions to Exception Handling Framework. */
+EHF_REGISTER_PRIORITIES(imx_exceptions, ARRAY_SIZE(imx_exceptions), PLAT_PRI_BITS);
diff --git a/plat/imx/common/imx_sdei.c b/plat/imx/common/imx_sdei.c
new file mode 100644
index 000000000..4b6033fb6
--- /dev/null
+++ b/plat/imx/common/imx_sdei.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* SDEI configuration for ARM platforms */
+
+#include <bl31/ehf.h>
+#include <common/debug.h>
+#include <services/sdei.h>
+#include <lib/utils_def.h>
+
+#include <platform_def.h>
+
+/* Private event mappings */
+static sdei_ev_map_t imx_sdei_private[] = {
+ SDEI_DEFINE_EVENT_0(PLAT_SDEI_SGI_PRIVATE),
+};
+
+/* Shared event mappings */
+static sdei_ev_map_t imx_sdei_shared[] = {
+};
+
+void plat_sdei_setup(void)
+{
+ INFO("SDEI platform setup\n");
+}
+
+/* Export ARM SDEI events */
+REGISTER_SDEI_MAP(imx_sdei_private, imx_sdei_shared);
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
index 62048b696..f9f5577c4 100644
--- a/plat/imx/common/imx_sip_handler.c
+++ b/plat/imx/common/imx_sip_handler.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arch.h>
#include <stdlib.h>
#include <stdint.h>
#include <services/std_svc.h>
@@ -12,6 +13,7 @@
#include <common/debug.h>
#include <common/runtime_svc.h>
#include <imx_sip_svc.h>
+#include <lib/el3_runtime/context_mgmt.h>
#include <sci/sci.h>
#if defined(PLAT_imx8qm) || defined(PLAT_imx8qx)
@@ -185,3 +187,37 @@ uint64_t imx_buildinfo_handler(uint32_t smc_fid,
return ret;
}
+
+int imx_kernel_entry_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4)
+{
+ static entry_point_info_t bl33_image_ep_info;
+ entry_point_info_t *next_image_info;
+ unsigned int mode;
+
+ if (x1 < (PLAT_NS_IMAGE_OFFSET & 0xF0000000))
+ return SMC_UNK;
+
+ mode = MODE32_svc;
+
+ next_image_info = &bl33_image_ep_info;
+
+ next_image_info->pc = x1;
+
+ next_image_info->spsr = SPSR_MODE32(mode, SPSR_T_ARM, SPSR_E_LITTLE,
+ (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT));
+
+ next_image_info->args.arg0 = 0;
+ next_image_info->args.arg1 = 0;
+ next_image_info->args.arg2 = x3;
+
+ SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
+
+ cm_init_my_context(next_image_info);
+ cm_prepare_el3_exit(NON_SECURE);
+
+ return 0;
+}
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index 4893b9fa5..20e1479fb 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -26,6 +26,9 @@ static uintptr_t imx_sip_handler(unsigned int smc_fid,
u_register_t flags)
{
switch (smc_fid) {
+ case IMX_SIP_AARCH32:
+ SMC_RET1(handle, imx_kernel_entry_handler(smc_fid, x1, x2, x3, x4));
+ break;
#if defined(PLAT_imx8mq)
case IMX_SIP_GET_SOC_INFO:
SMC_RET1(handle, imx_soc_info_handler(smc_fid, x1, x2, x3));
diff --git a/plat/imx/common/imx_uart_console.S b/plat/imx/common/imx_uart_console.S
index 3bdeea26c..ceeb3a76c 100644
--- a/plat/imx/common/imx_uart_console.S
+++ b/plat/imx/common/imx_uart_console.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,7 +25,7 @@ func console_imx_uart_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_DRVDATA]
+ str x0, [x6, #CONSOLE_T_BASE]
bl console_imx_uart_init
cbz x0, register_fail
@@ -44,7 +44,7 @@ func console_imx_uart_init
endfunc console_imx_uart_init
func console_imx_uart_putc
- ldr x1, [x1, #CONSOLE_T_DRVDATA]
+ ldr x1, [x1, #CONSOLE_T_BASE]
cbz x1, putc_error
/* Prepare '\r' to '\n' */
@@ -68,7 +68,7 @@ putc_error:
endfunc console_imx_uart_putc
func console_imx_uart_getc
- ldr x0, [x0, #CONSOLE_T_DRVDATA]
+ ldr x0, [x0, #CONSOLE_T_BASE]
cbz x0, getc_error
1:
ldr w1, [x0, #UTS]
@@ -84,6 +84,5 @@ getc_error:
endfunc console_imx_uart_getc
func console_imx_uart_flush
- mov x0, #0
ret
endfunc console_imx_uart_flush
diff --git a/plat/imx/common/include/imx8_iomux.h b/plat/imx/common/include/imx8_iomux.h
index 0e93d9800..264c295bb 100644
--- a/plat/imx/common/include/imx8_iomux.h
+++ b/plat/imx/common/include/imx8_iomux.h
@@ -7,19 +7,19 @@
#ifndef IMX8_IOMUX_H
#define IMX8_IOMUX_H
-#define PADRING_IFMUX_EN_SHIFT 31
-#define PADRING_IFMUX_EN_MASK (1 << PADRING_IFMUX_EN_SHIFT)
-#define PADRING_GP_EN_SHIFT 30
-#define PADRING_GP_EN_MASK (1 << PADRING_GP_EN_SHIFT)
-#define PADRING_IFMUX_SHIFT 27
-#define PADRING_IFMUX_MASK (0x7 << PADRING_IFMUX_SHIFT)
-#define PADRING_CONFIG_SHIFT 25
-#define PADRING_CONFIG_MASK (0x3 << PADRING_CONFIG_SHIFT)
-#define PADRING_LPCONFIG_SHIFT 23
-#define PADRING_LPCONFIG_MASK (0x3 << PADRING_LPCONFIG_SHIFT)
-#define PADRING_PULL_SHIFT 5
-#define PADRING_PULL_MASK (0x3 << PADRING_PULL_SHIFT)
-#define PADRING_DSE_SHIFT 0
-#define PADRING_DSE_MASK (0x7 << PADRING_DSE_SHIFT)
+#define PADRING_IFMUX_EN_SHIFT U(31)
+#define PADRING_IFMUX_EN_MASK (U(0x1) << PADRING_IFMUX_EN_SHIFT)
+#define PADRING_GP_EN_SHIFT U(30)
+#define PADRING_GP_EN_MASK (U(0x1) << PADRING_GP_EN_SHIFT)
+#define PADRING_IFMUX_SHIFT U(27)
+#define PADRING_IFMUX_MASK (U(0x7) << PADRING_IFMUX_SHIFT)
+#define PADRING_CONFIG_SHIFT U(25)
+#define PADRING_CONFIG_MASK (U(0x3) << PADRING_CONFIG_SHIFT)
+#define PADRING_LPCONFIG_SHIFT U(23)
+#define PADRING_LPCONFIG_MASK (U(0x3) << PADRING_LPCONFIG_SHIFT)
+#define PADRING_PULL_SHIFT U(5)
+#define PADRING_PULL_MASK (U(0x3) << PADRING_PULL_SHIFT)
+#define PADRING_DSE_SHIFT U(0)
+#define PADRING_DSE_MASK (U(0x7) << PADRING_DSE_SHIFT)
#endif /* IMX8_IOMUX_H */
diff --git a/plat/imx/common/include/imx8_lpuart.h b/plat/imx/common/include/imx8_lpuart.h
index 0ea284fdf..26470e040 100644
--- a/plat/imx/common/include/imx8_lpuart.h
+++ b/plat/imx/common/include/imx8_lpuart.h
@@ -54,13 +54,8 @@
#include <stdint.h>
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_lpuart_t;
-
int console_lpuart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_lpuart_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
#endif /* IMX8_LPUART_H */
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 5898f7a81..0a2d750f9 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -28,6 +28,11 @@
#define IMX_SIP_MISC_SET_TEMP 0xC200000C
+#define IMX_SIP_AARCH32 0xC20000FD
+
+int imx_kernel_entry_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4);
#if defined(PLAT_imx8mq)
int imx_soc_info_handler(uint32_t smc_fid, u_register_t x1,
u_register_t x2, u_register_t x3);
diff --git a/plat/imx/common/include/imx_uart.h b/plat/imx/common/include/imx_uart.h
index cc1b5318e..6c4d62f57 100644
--- a/plat/imx/common/include/imx_uart.h
+++ b/plat/imx/common/include/imx_uart.h
@@ -11,13 +11,8 @@
#ifndef __ASSEMBLER__
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_uart_t;
-
int console_imx_uart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_uart_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
#endif /* IMX_UART_H */
diff --git a/plat/imx/common/lpuart_console.S b/plat/imx/common/lpuart_console.S
index d8dac2cea..ff01e3551 100644
--- a/plat/imx/common/lpuart_console.S
+++ b/plat/imx/common/lpuart_console.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,7 +20,7 @@ func console_lpuart_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_DRVDATA]
+ str x0, [x6, #CONSOLE_T_BASE]
bl console_lpuart_init
cbz x0, register_fail
@@ -39,7 +39,7 @@ func console_lpuart_init
endfunc console_lpuart_init
func console_lpuart_putc
- ldr x1, [x1, #CONSOLE_T_DRVDATA]
+ ldr x1, [x1, #CONSOLE_T_BASE]
cbz x1, putc_error
/* Prepare '\r' to '\n' */
cmp w0, #0xA
@@ -62,7 +62,7 @@ putc_error:
endfunc console_lpuart_putc
func console_lpuart_getc
- ldr x0, [x0, #CONSOLE_T_DRVDATA]
+ ldr x0, [x0, #CONSOLE_T_BASE]
cbz x0, getc_error
/* Check if the receive FIFO state */
ret
@@ -72,6 +72,5 @@ getc_error:
endfunc console_lpuart_getc
func console_lpuart_flush
- mov x0, #0
ret
endfunc console_lpuart_flush
diff --git a/plat/imx/common/plat_imx8_gic.c b/plat/imx/common/plat_imx8_gic.c
index afb9d1f1a..150e81e7d 100644
--- a/plat/imx/common/plat_imx8_gic.c
+++ b/plat/imx/common/plat_imx8_gic.c
@@ -22,6 +22,10 @@ uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
static const interrupt_prop_t g01s_interrupt_props[] = {
INTR_PROP_DESC(8, GIC_HIGHEST_SEC_PRIORITY,
INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+#if SDEI_SUPPORT
+ INTR_PROP_DESC(PLAT_SDEI_SGI_PRIVATE, PLAT_SDEI_NORMAL_PRI,
+ INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+#endif
};
static unsigned int plat_imx_mpidr_to_core_pos(unsigned long mpidr)
diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk
index 849ddcd76..3a95772b1 100644
--- a/plat/imx/imx7/common/imx7.mk
+++ b/plat/imx/imx7/common/imx7.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -58,12 +58,13 @@ include drivers/auth/mbedtls/mbedtls_x509.mk
AUTH_SOURCES := drivers/auth/auth_mod.c \
drivers/auth/crypto_mod.c \
drivers/auth/img_parser_mod.c \
- drivers/auth/tbbr/tbbr_cot.c
+ drivers/auth/tbbr/tbbr_cot_common.c
BL2_SOURCES += ${AUTH_SOURCES} \
plat/common/tbbr/plat_tbbr.c \
plat/imx/imx7/common/imx7_trusted_boot.c \
- plat/imx/imx7/common/imx7_rotpk.S
+ plat/imx/imx7/common/imx7_rotpk.S \
+ drivers/auth/tbbr/tbbr_cot_bl2.c
ROT_KEY = $(BUILD_PLAT)/rot_key.pem
ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
diff --git a/plat/imx/imx7/common/imx7_bl2_el3_common.c b/plat/imx/imx7/common/imx7_bl2_el3_common.c
index a1e2aafd4..7f156e306 100644
--- a/plat/imx/imx7/common/imx7_bl2_el3_common.c
+++ b/plat/imx/imx7/common/imx7_bl2_el3_common.c
@@ -150,7 +150,7 @@ static void imx7_setup_wdog_clocks(void)
void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2,
u_register_t arg3, u_register_t arg4)
{
- static console_imx_uart_t console;
+ static console_t console;
int console_scope = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME;
/* Initialize common components */
@@ -170,7 +170,7 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2,
PLAT_IMX7_BOOT_UART_CLK_IN_HZ,
PLAT_IMX7_CONSOLE_BAUDRATE,
&console);
- console_set_scope(&console.console, console_scope);
+ console_set_scope(&console, console_scope);
/* Open handles to persistent storage */
plat_imx7_io_setup();
diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c
index eb2801cea..1e55f058d 100644
--- a/plat/imx/imx8m/gpc_common.c
+++ b/plat/imx/imx8m/gpc_common.c
@@ -16,7 +16,9 @@
#include <imx8m_psci.h>
#include <plat_imx8.h>
-static uint32_t gpc_imr_offset[] = { 0x30, 0x40, 0x1c0, 0x1d0, };
+static uint32_t gpc_imr_offset[] = { IMR1_CORE0_A53, IMR1_CORE1_A53, IMR1_CORE2_A53, IMR1_CORE3_A53, };
+
+DEFINE_BAKERY_LOCK(gpc_lock);
#pragma weak imx_set_cpu_pwr_off
#pragma weak imx_set_cpu_pwr_on
@@ -38,16 +40,27 @@ void imx_set_cpu_secure_entry(unsigned int core_id, uintptr_t sec_entrypoint)
void imx_set_cpu_pwr_off(unsigned int core_id)
{
+
+ bakery_lock_get(&gpc_lock);
+
/* enable the wfi power down of the core */
mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id));
+
+ bakery_lock_release(&gpc_lock);
+
/* assert the pcg pcr bit of the core */
mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1);
}
void imx_set_cpu_pwr_on(unsigned int core_id)
{
+ bakery_lock_get(&gpc_lock);
+
/* clear the wfi power down bit of the core */
mmio_clrbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id));
+
+ bakery_lock_release(&gpc_lock);
+
/* assert the ncpuporeset */
mmio_clrbits_32(IMX_SRC_BASE + SRC_A53RCR1, (1 << core_id));
/* assert the pcg pcr bit of the core */
@@ -67,6 +80,8 @@ void imx_set_cpu_pwr_on(unsigned int core_id)
void imx_set_cpu_lpm(unsigned int core_id, bool pdn)
{
+ bakery_lock_get(&gpc_lock);
+
if (pdn) {
/* enable the core WFI PDN & IRQ PUP */
mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) |
@@ -80,6 +95,8 @@ void imx_set_cpu_lpm(unsigned int core_id, bool pdn)
/* deassert the pcg pcr bit of the core */
mmio_clrbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1);
}
+
+ bakery_lock_release(&gpc_lock);
}
/*
@@ -133,14 +150,12 @@ void imx_set_cluster_powerdown(unsigned int last_core, uint8_t power_state)
val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_AD);
val &= ~EN_L2_WFI_PDN;
/* L2 cache memory is on in WAIT mode */
- if (is_local_state_off(power_state))
+ if (is_local_state_off(power_state)) {
val |= (L2PGE | EN_PLAT_PDN);
- else
- val |= EN_PLAT_PDN;
+ imx_a53_plat_slot_config(true);
+ }
mmio_write_32(IMX_GPC_BASE + LPCR_A53_AD, val);
-
- imx_a53_plat_slot_config(true);
} else {
/* clear the slot and ack for cluster power down */
imx_a53_plat_slot_config(false);
diff --git a/plat/imx/imx8m/imx8m_psci_common.c b/plat/imx/imx8m/imx8m_psci_common.c
index d6416288e..dbb772dc1 100644
--- a/plat/imx/imx8m/imx8m_psci_common.c
+++ b/plat/imx/imx8m/imx8m_psci_common.c
@@ -192,7 +192,7 @@ void __dead2 imx_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
* drived by the 32K OSC, so delay 30us to make sure the counter
* is really running.
*/
- if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) {
+ if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
imx_set_rbc_count();
udelay(30);
}
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index 4c5f4f0d1..40110d778 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -97,7 +97,7 @@ void bl31_tzc380_setup(void)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_uart_t console;
+ static console_t console;
int i;
/* Enable CSU NS access permission */
@@ -114,7 +114,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
IMX_CONSOLE_BAUDRATE, &console);
/* This console is only used for boot stage */
- console_set_scope(&console.console, CONSOLE_FLAG_BOOT);
+ console_set_scope(&console, CONSOLE_FLAG_BOOT);
/*
* tell BL3-1 where the non-secure software image is located
diff --git a/plat/imx/imx8m/imx8mm/include/gpc_reg.h b/plat/imx/imx8m/imx8mm/include/gpc_reg.h
new file mode 100644
index 000000000..1a4eae546
--- /dev/null
+++ b/plat/imx/imx8m/imx8mm/include/gpc_reg.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GPC_REG_H
+#define GPC_REG_H
+
+#define LPCR_A53_BSC 0x0
+#define LPCR_A53_BSC2 0x108
+#define LPCR_A53_AD 0x4
+#define LPCR_M4 0x8
+#define SLPCR 0x14
+#define MST_CPU_MAPPING 0x18
+#define MLPCR 0x20
+#define PGC_ACK_SEL_A53 0x24
+#define IMR1_CORE0_A53 0x30
+#define IMR1_CORE1_A53 0x40
+#define IMR1_CORE2_A53 0x1C0
+#define IMR1_CORE3_A53 0x1D0
+#define IMR1_CORE0_M4 0x50
+#define SLT0_CFG 0xB0
+#define GPC_PU_PWRHSK 0x1FC
+#define PGC_CPU_0_1_MAPPING 0xEC
+#define CPU_PGC_UP_TRG 0xF0
+#define PU_PGC_UP_TRG 0xF8
+#define CPU_PGC_DN_TRG 0xFC
+#define PU_PGC_DN_TRG 0x104
+#define LPS_CPU1 0x114
+#define A53_CORE0_PGC 0x800
+#define A53_PLAT_PGC 0x900
+#define PLAT_PGC_PCR 0x900
+#define NOC_PGC_PCR 0xa40
+#define PGC_SCU_TIMING 0x910
+
+#define MASK_DSM_TRIGGER_A53 BIT(31)
+#define IRQ_SRC_A53_WUP BIT(30)
+#define IRQ_SRC_A53_WUP_SHIFT 30
+#define IRQ_SRC_C1 BIT(29)
+#define IRQ_SRC_C0 BIT(28)
+#define IRQ_SRC_C3 BIT(23)
+#define IRQ_SRC_C2 BIT(22)
+#define CPU_CLOCK_ON_LPM BIT(14)
+#define A53_CLK_ON_LPM BIT(14)
+#define MASTER0_LPM_HSK BIT(6)
+#define MASTER1_LPM_HSK BIT(7)
+#define MASTER2_LPM_HSK BIT(8)
+
+#define L2PGE BIT(31)
+#define EN_L2_WFI_PDN BIT(5)
+#define EN_PLAT_PDN BIT(4)
+
+#define SLPCR_EN_DSM BIT(31)
+#define SLPCR_RBC_EN BIT(30)
+#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17)
+#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16)
+#define SLPCR_VSTBY BIT(2)
+#define SLPCR_SBYOS BIT(1)
+#define SLPCR_BYPASS_PMIC_READY BIT(0)
+#define SLPCR_RBC_COUNT_SHIFT 24
+#define SLPCR_STBY_COUNT_SHFT 3
+
+#define A53_DUMMY_PDN_ACK BIT(15)
+#define A53_DUMMY_PUP_ACK BIT(31)
+#define A53_PLAT_PDN_ACK BIT(2)
+#define A53_PLAT_PUP_ACK BIT(18)
+#define NOC_PDN_SLT_CTRL BIT(10)
+#define NOC_PUP_SLT_CTRL BIT(11)
+#define NOC_PGC_PDN_ACK BIT(3)
+#define NOC_PGC_PUP_ACK BIT(19)
+
+#define PLAT_PUP_SLT_CTRL BIT(9)
+#define PLAT_PDN_SLT_CTRL BIT(8)
+
+#define SLT_PLAT_PDN BIT(8)
+#define SLT_PLAT_PUP BIT(9)
+
+#define MASTER1_MAPPING BIT(1)
+#define MASTER2_MAPPING BIT(2)
+
+#define MIPI_PWR_REQ BIT(0)
+#define PCIE_PWR_REQ BIT(1)
+#define OTG1_PWR_REQ BIT(2)
+#define OTG2_PWR_REQ BIT(3)
+#define HSIOMIX_PWR_REQ BIT(4)
+#define DDRMIX_PWR_REQ BIT(5)
+#define GPU2D_PWR_REQ BIT(6)
+#define GPUMIX_PWR_REQ BIT(7)
+#define VPUMIX_PWR_REQ BIT(8)
+#define GPU3D_PWR_REQ BIT(9)
+#define DISPMIX_PWR_REQ BIT(10)
+#define VPU_G1_PWR_REQ BIT(11)
+#define VPU_G2_PWR_REQ BIT(12)
+#define VPU_H1_PWR_REQ BIT(13)
+
+#define DDRMIX_ADB400_SYNC BIT(2)
+#define HSIOMIX_ADB400_SYNC (0x3 << 5)
+#define DISPMIX_ADB400_SYNC BIT(7)
+#define VPUMIX_ADB400_SYNC BIT(8)
+#define GPU3D_ADB400_SYNC BIT(9)
+#define GPU2D_ADB400_SYNC BIT(10)
+#define GPUMIX_ADB400_SYNC BIT(11)
+#define DDRMIX_ADB400_ACK BIT(20)
+#define HSIOMIX_ADB400_ACK (0x3 << 23)
+#define DISPMIX_ADB400_ACK BIT(25)
+#define VPUMIX_ADB400_ACK BIT(26)
+#define GPU3D_ADB400_ACK BIT(27)
+#define GPU2D_ADB400_ACK BIT(28)
+#define GPUMIX_ADB400_ACK BIT(29)
+
+#define MIPI_PGC 0xc00
+#define PCIE_PGC 0xc40
+#define OTG1_PGC 0xc80
+#define OTG2_PGC 0xcc0
+#define HSIOMIX_PGC 0xd00
+#define DDRMIX_PGC 0xd40
+#define GPU2D_PGC 0xd80
+#define GPUMIX_PGC 0xdc0
+#define VPUMIX_PGC 0xe00
+#define GPU3D_PGC 0xe40
+#define DISPMIX_PGC 0xe80
+#define VPU_G1_PGC 0xec0
+#define VPU_G2_PGC 0xf00
+#define VPU_H1_PGC 0xf40
+
+#define IRQ_IMR_NUM U(4)
+
+#endif /* GPC_REG_H */
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 56caab7ce..1041459c8 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -29,6 +29,11 @@
#define PLAT_WAIT_RET_STATE U(1)
#define PLAT_STOP_OFF_STATE U(3)
+#define PLAT_PRI_BITS U(3)
+#define PLAT_SDEI_CRITICAL_PRI 0x10
+#define PLAT_SDEI_NORMAL_PRI 0x20
+#define PLAT_SDEI_SGI_PRIVATE U(9)
+
#define BL31_BASE U(0x920000)
#define BL31_LIMIT U(0x940000)
@@ -47,7 +52,6 @@
#define HAB_RVT_BASE U(0x00000900) /* HAB_RVT for i.MX8MM */
-#define IMX_BOOT_UART_BASE U(0x30890000)
#define IMX_BOOT_UART_CLK_IN_HZ 24000000 /* Select 24MHz oscillator */
#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index c0cb6c2a5..ac636fa8f 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,11 +8,10 @@ PLAT_INCLUDES := -Iplat/imx/common/include \
-Iplat/imx/imx8m/include \
-Iplat/imx/imx8m/imx8mm/include
-IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \
- drivers/arm/gic/v3/arm_gicv3_common.c \
- drivers/arm/gic/v3/gic500.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/common/gic_common.c \
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+IMX_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
plat/imx/common/plat_imx8_gic.c
@@ -30,6 +29,8 @@ BL31_SOURCES += plat/imx/common/imx8_helpers.S \
plat/imx/common/imx_sip_handler.c \
plat/imx/common/imx_sip_svc.c \
plat/imx/common/imx_uart_console.S \
+ plat/imx/common/imx_ehf.c \
+ plat/imx/common/imx_sdei.c \
lib/xlat_tables/aarch64/xlat_tables.c \
lib/xlat_tables/xlat_tables_common.c \
lib/cpus/aarch64/cortex_a53.S \
@@ -51,3 +52,9 @@ $(eval $(call add_define,BL32_BASE))
BL32_SIZE ?= 0x2000000
$(eval $(call add_define,BL32_SIZE))
+
+IMX_BOOT_UART_BASE ?= 0x30890000
+$(eval $(call add_define,IMX_BOOT_UART_BASE))
+
+EL3_EXCEPTION_HANDLING := 1
+SDEI_SUPPORT := 1
diff --git a/plat/imx/imx8m/imx8mn/gpc.c b/plat/imx/imx8m/imx8mn/gpc.c
new file mode 100644
index 000000000..37d4226a6
--- /dev/null
+++ b/plat/imx/imx8m/imx8mn/gpc.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2019-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/smccc.h>
+#include <services/std_svc.h>
+
+#include <gpc.h>
+#include <imx_sip_svc.h>
+#include <platform_def.h>
+
+#define CCGR(x) (0x4000 + (x) * 0x10)
+
+void imx_gpc_init(void)
+{
+ unsigned int val;
+ int i;
+
+ /* mask all the wakeup irq by default */
+ for (i = 0; i < 4; i++) {
+ mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_A53 + i * 4, ~0x0);
+ mmio_write_32(IMX_GPC_BASE + IMR1_CORE1_A53 + i * 4, ~0x0);
+ mmio_write_32(IMX_GPC_BASE + IMR1_CORE2_A53 + i * 4, ~0x0);
+ mmio_write_32(IMX_GPC_BASE + IMR1_CORE3_A53 + i * 4, ~0x0);
+ mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_M4 + i * 4, ~0x0);
+ }
+
+ val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_BSC);
+ /* use GIC wake_request to wakeup C0~C3 from LPM */
+ val |= CORE_WKUP_FROM_GIC;
+ /* clear the MASTER0 LPM handshake */
+ val &= ~MASTER0_LPM_HSK;
+ mmio_write_32(IMX_GPC_BASE + LPCR_A53_BSC, val);
+
+ /* clear MASTER1 & MASTER2 mapping in CPU0(A53) */
+ mmio_clrbits_32(IMX_GPC_BASE + MST_CPU_MAPPING, (MASTER1_MAPPING |
+ MASTER2_MAPPING));
+
+ /* set all mix/PU in A53 domain */
+ mmio_write_32(IMX_GPC_BASE + PGC_CPU_0_1_MAPPING, 0xffff);
+
+ /*
+ * Set the CORE & SCU power up timing:
+ * SW = 0x1, SW2ISO = 0x1;
+ * the CPU CORE and SCU power up timming counter
+ * is drived by 32K OSC, each domain's power up
+ * latency is (SW + SW2ISO) / 32768
+ */
+ mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(0) + 0x4, 0x401);
+ mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(1) + 0x4, 0x401);
+ mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(2) + 0x4, 0x401);
+ mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(3) + 0x4, 0x401);
+ mmio_write_32(IMX_GPC_BASE + PLAT_PGC_PCR + 0x4, 0x401);
+ mmio_write_32(IMX_GPC_BASE + PGC_SCU_TIMING,
+ (0x59 << TMC_TMR_SHIFT) | 0x5B | (0x2 << TRC1_TMC_SHIFT));
+
+ /* set DUMMY PDN/PUP ACK by default for A53 domain */
+ mmio_write_32(IMX_GPC_BASE + PGC_ACK_SEL_A53,
+ A53_DUMMY_PUP_ACK | A53_DUMMY_PDN_ACK);
+
+ /* clear DSM by default */
+ val = mmio_read_32(IMX_GPC_BASE + SLPCR);
+ val &= ~SLPCR_EN_DSM;
+ /* enable the fast wakeup wait mode */
+ val |= SLPCR_A53_FASTWUP_WAIT_MODE;
+ /* clear the RBC */
+ val &= ~(0x3f << SLPCR_RBC_COUNT_SHIFT);
+ /* set the STBY_COUNT to 0x5, (128 * 30)us */
+ val &= ~(0x7 << SLPCR_STBY_COUNT_SHFT);
+ val |= (0x5 << SLPCR_STBY_COUNT_SHFT);
+ mmio_write_32(IMX_GPC_BASE + SLPCR, val);
+
+ /*
+ * USB PHY power up needs to make sure RESET bit in SRC is clear,
+ * otherwise, the PU power up bit in GPC will NOT self-cleared.
+ * only need to do it once.
+ */
+ mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1);
+
+ /* enable all the power domain by default */
+ for (i = 0; i < 103; i++)
+ mmio_write_32(IMX_CCM_BASE + CCGR(i), 0x3);
+ mmio_write_32(IMX_GPC_BASE + PU_PGC_UP_TRG, 0x485);
+}
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
new file mode 100644
index 000000000..d4705eeeb
--- /dev/null
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2019-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <context.h>
+#include <drivers/arm/tzc380.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <gpc.h>
+#include <imx_aipstz.h>
+#include <imx_uart.h>
+#include <imx_rdc.h>
+#include <imx8m_caam.h>
+#include <platform_def.h>
+#include <plat_imx8.h>
+
+static const mmap_region_t imx_mmap[] = {
+ GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP, {0},
+};
+
+static const struct aipstz_cfg aipstz[] = {
+ {IMX_AIPSTZ1, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {IMX_AIPSTZ2, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {IMX_AIPSTZ3, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {IMX_AIPSTZ4, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {0},
+};
+
+static const struct imx_rdc_cfg rdc[] = {
+ /* Master domain assignment */
+ RDC_MDAn(0x1, DID1),
+
+ /* peripherals domain permission */
+
+ /* memory region */
+ RDC_MEM_REGIONn(16, 0x0, 0x0, 0xff),
+ RDC_MEM_REGIONn(17, 0x0, 0x0, 0xff),
+ RDC_MEM_REGIONn(18, 0x0, 0x0, 0xff),
+
+ /* Sentinel */
+ {0},
+};
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/* get SPSR for BL33 entry */
+static uint32_t get_spsr_for_bl33_entry(void)
+{
+ unsigned long el_status;
+ unsigned long mode;
+ uint32_t spsr;
+
+ /* figure out what mode we enter the non-secure world */
+ el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+ el_status &= ID_AA64PFR0_ELX_MASK;
+
+ mode = (el_status) ? MODE_EL2 : MODE_EL1;
+
+ spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+}
+
+static void bl31_tzc380_setup(void)
+{
+ unsigned int val;
+
+ val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x28);
+ if ((val & GPR_TZASC_EN) != GPR_TZASC_EN)
+ return;
+
+ tzc380_init(IMX_TZASC_BASE);
+
+ /*
+ * Need to substact offset 0x40000000 from CPU address when
+ * programming tzasc region for i.mx8mn.
+ */
+
+ /* Enable 1G-5G S/NS RW */
+ tzc380_configure_region(0, 0x00000000, TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_4G) |
+ TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_ALL);
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ static console_t console;
+ int i;
+
+ /* Enable CSU NS access permission */
+ for (i = 0; i < 64; i++) {
+ mmio_write_32(IMX_CSU_BASE + i * 4, 0x00ff00ff);
+ }
+
+ imx_aipstz_init(aipstz);
+
+ imx_rdc_init(rdc);
+
+ imx8m_caam_init();
+
+ console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+ IMX_CONSOLE_BAUDRATE, &console);
+ /* This console is only used for boot stage */
+ console_set_scope(&console, CONSOLE_FLAG_BOOT);
+
+ /*
+ * tell BL3-1 where the non-secure software image is located
+ * and the entry state information.
+ */
+ bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
+ bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
+ SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+#ifdef SPD_opteed
+ /* Populate entry point information for BL32 */
+ SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
+ SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+ bl32_image_ep_info.pc = BL32_BASE;
+ bl32_image_ep_info.spsr = 0;
+
+ /* Pass TEE base and size to bl33 */
+ bl33_image_ep_info.args.arg1 = BL32_BASE;
+ bl33_image_ep_info.args.arg2 = BL32_SIZE;
+#endif
+
+ bl31_tzc380_setup();
+}
+
+void bl31_plat_arch_setup(void)
+{
+ mmap_add_region(BL31_BASE, BL31_BASE, (BL31_LIMIT - BL31_BASE),
+ MT_MEMORY | MT_RW | MT_SECURE);
+ mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, (BL_CODE_END - BL_CODE_BASE),
+ MT_MEMORY | MT_RO | MT_SECURE);
+#if USE_COHERENT_MEM
+ mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+ (BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE),
+ MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+ mmap_add(imx_mmap);
+
+ init_xlat_tables();
+
+ enable_mmu_el3(0);
+}
+
+void bl31_platform_setup(void)
+{
+ generic_delay_timer_init();
+
+ /* select the CKIL source to 32K OSC */
+ mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1);
+
+ plat_gic_driver_init();
+ plat_gic_init();
+
+ imx_gpc_init();
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
+{
+ if (type == NON_SECURE)
+ return &bl33_image_ep_info;
+ if (type == SECURE)
+ return &bl32_image_ep_info;
+
+ return NULL;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ return COUNTER_FREQUENCY;
+}
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_psci.c b/plat/imx/imx8m/imx8mn/imx8mn_psci.c
new file mode 100644
index 000000000..f541fc138
--- /dev/null
+++ b/plat/imx/imx8m/imx8mn/imx8mn_psci.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+
+#include <gpc.h>
+#include <imx8m_psci.h>
+#include <plat_imx8.h>
+
+static const plat_psci_ops_t imx_plat_psci_ops = {
+ .pwr_domain_on = imx_pwr_domain_on,
+ .pwr_domain_on_finish = imx_pwr_domain_on_finish,
+ .pwr_domain_off = imx_pwr_domain_off,
+ .validate_ns_entrypoint = imx_validate_ns_entrypoint,
+ .validate_power_state = imx_validate_power_state,
+ .cpu_standby = imx_cpu_standby,
+ .pwr_domain_suspend = imx_domain_suspend,
+ .pwr_domain_suspend_finish = imx_domain_suspend_finish,
+ .pwr_domain_pwr_down_wfi = imx_pwr_domain_pwr_down_wfi,
+ .get_sys_suspend_power_state = imx_get_sys_suspend_power_state,
+ .system_reset = imx_system_reset,
+ .system_off = imx_system_off,
+};
+
+/* export the platform specific psci ops */
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ /* sec_entrypoint is used for warm reset */
+ imx_mailbox_init(sec_entrypoint);
+
+ *psci_ops = &imx_plat_psci_ops;
+
+ return 0;
+}
diff --git a/plat/imx/imx8m/imx8mn/include/gpc_reg.h b/plat/imx/imx8m/imx8mn/include/gpc_reg.h
new file mode 100644
index 000000000..8a8136814
--- /dev/null
+++ b/plat/imx/imx8m/imx8mn/include/gpc_reg.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GPC_REG_H
+#define GPC_REG_H
+
+#define LPCR_A53_BSC 0x0
+#define LPCR_A53_BSC2 0x108
+#define LPCR_A53_AD 0x4
+#define LPCR_M4 0x8
+#define SLPCR 0x14
+#define MST_CPU_MAPPING 0x18
+#define MLPCR 0x20
+#define PGC_ACK_SEL_A53 0x24
+#define IMR1_CORE0_A53 0x30
+#define IMR1_CORE1_A53 0x40
+#define IMR1_CORE2_A53 0x1C0
+#define IMR1_CORE3_A53 0x1D0
+#define IMR1_CORE0_M4 0x50
+#define SLT0_CFG 0xB0
+#define GPC_PU_PWRHSK 0x1FC
+#define PGC_CPU_0_1_MAPPING 0xEC
+#define CPU_PGC_UP_TRG 0xF0
+#define PU_PGC_UP_TRG 0xF8
+#define CPU_PGC_DN_TRG 0xFC
+#define PU_PGC_DN_TRG 0x104
+#define LPS_CPU1 0x114
+#define A53_CORE0_PGC 0x800
+#define A53_PLAT_PGC 0x900
+#define PLAT_PGC_PCR 0x900
+#define NOC_PGC_PCR 0xa40
+#define PGC_SCU_TIMING 0x910
+
+#define MASK_DSM_TRIGGER_A53 BIT(31)
+#define IRQ_SRC_A53_WUP BIT(30)
+#define IRQ_SRC_A53_WUP_SHIFT 30
+#define IRQ_SRC_C1 BIT(29)
+#define IRQ_SRC_C0 BIT(28)
+#define IRQ_SRC_C3 BIT(23)
+#define IRQ_SRC_C2 BIT(22)
+#define CPU_CLOCK_ON_LPM BIT(14)
+#define A53_CLK_ON_LPM BIT(14)
+#define MASTER0_LPM_HSK BIT(6)
+#define MASTER1_LPM_HSK BIT(7)
+#define MASTER2_LPM_HSK BIT(8)
+
+#define L2PGE BIT(31)
+#define EN_L2_WFI_PDN BIT(5)
+#define EN_PLAT_PDN BIT(4)
+
+#define SLPCR_EN_DSM BIT(31)
+#define SLPCR_RBC_EN BIT(30)
+#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17)
+#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16)
+#define SLPCR_VSTBY BIT(2)
+#define SLPCR_SBYOS BIT(1)
+#define SLPCR_BYPASS_PMIC_READY BIT(0)
+#define SLPCR_RBC_COUNT_SHIFT 24
+#define SLPCR_STBY_COUNT_SHFT 3
+
+#define A53_DUMMY_PDN_ACK BIT(15)
+#define A53_DUMMY_PUP_ACK BIT(31)
+#define A53_PLAT_PDN_ACK BIT(2)
+#define A53_PLAT_PUP_ACK BIT(18)
+#define NOC_PDN_SLT_CTRL BIT(10)
+#define NOC_PUP_SLT_CTRL BIT(11)
+#define NOC_PGC_PDN_ACK BIT(3)
+#define NOC_PGC_PUP_ACK BIT(19)
+
+#define PLAT_PUP_SLT_CTRL BIT(9)
+#define PLAT_PDN_SLT_CTRL BIT(8)
+
+#define SLT_PLAT_PDN BIT(8)
+#define SLT_PLAT_PUP BIT(9)
+
+#define MASTER1_MAPPING BIT(1)
+#define MASTER2_MAPPING BIT(2)
+
+#define TMR_TCD2_SHIFT 0
+#define TMC_TMR_SHIFT 10
+#define TRC1_TMC_SHIFT 20
+
+#define MIPI_PWR_REQ BIT(0)
+#define OTG1_PWR_REQ BIT(2)
+#define HSIOMIX_PWR_REQ BIT(4)
+#define DDRMIX_PWR_REQ BIT(5)
+#define GPUMIX_PWR_REQ BIT(7)
+#define DISPMIX_PWR_REQ BIT(10)
+
+#define DDRMIX_ADB400_SYNC BIT(2)
+#define HSIOMIX_ADB400_SYNC BIT(5)
+#define DISPMIX_ADB400_SYNC BIT(7)
+#define GPUMIX_ADB400_SYNC (0x5 << 9)
+#define DDRMIX_ADB400_ACK BIT(20)
+#define HSIOMIX_ADB400_ACK BIT(23)
+#define DISPMIX_ADB400_ACK BIT(25)
+#define GPUMIX_ADB400_ACK (0x5 << 27)
+
+#define MIPI_PGC 0xc00
+#define OTG1_PGC 0xc80
+#define HSIOMIX_PGC 0xd00
+#define DDRMIX_PGC 0xd40
+#define GPUMIX_PGC 0xdc0
+#define DISPMIX_PGC 0xe80
+
+#define IRQ_IMR_NUM U(4)
+
+#endif /* GPC_REG_H */
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
new file mode 100644
index 000000000..2444e662e
--- /dev/null
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+#define PLATFORM_STACK_SIZE 0xB00
+#define CACHE_WRITEBACK_GRANULE 64
+
+#define PLAT_PRIMARY_CPU U(0x0)
+#define PLATFORM_MAX_CPU_PER_CLUSTER U(4)
+#define PLATFORM_CLUSTER_COUNT U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT U(4)
+#define PLATFORM_CLUSTER1_CORE_COUNT U(0)
+#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT)
+
+#define IMX_PWR_LVL0 MPIDR_AFFLVL0
+#define IMX_PWR_LVL1 MPIDR_AFFLVL1
+#define IMX_PWR_LVL2 MPIDR_AFFLVL2
+
+#define PWR_DOMAIN_AT_MAX_LVL U(1)
+#define PLAT_MAX_PWR_LVL U(2)
+#define PLAT_MAX_OFF_STATE U(4)
+#define PLAT_MAX_RET_STATE U(2)
+
+#define PLAT_WAIT_RET_STATE U(1)
+#define PLAT_STOP_OFF_STATE U(3)
+
+#define BL31_BASE U(0x960000)
+#define BL31_LIMIT U(0x980000)
+
+/* non-secure uboot base */
+#define PLAT_NS_IMAGE_OFFSET U(0x40200000)
+
+/* GICv3 base address */
+#define PLAT_GICD_BASE U(0x38800000)
+#define PLAT_GICR_BASE U(0x38880000)
+
+#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32)
+
+#define MAX_XLAT_TABLES 8
+#define MAX_MMAP_REGIONS 16
+
+#define HAB_RVT_BASE U(0x00000900) /* HAB_RVT for i.MX8MM */
+
+#define IMX_BOOT_UART_CLK_IN_HZ 24000000 /* Select 24MHz oscillator */
+#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
+#define PLAT_CRASH_UART_CLK_IN_HZ 24000000
+#define IMX_CONSOLE_BAUDRATE 115200
+
+#define IMX_AIPSTZ1 U(0x301f0000)
+#define IMX_AIPSTZ2 U(0x305f0000)
+#define IMX_AIPSTZ3 U(0x309f0000)
+#define IMX_AIPSTZ4 U(0x32df0000)
+
+#define IMX_AIPS_BASE U(0x30000000)
+#define IMX_AIPS_SIZE U(0xC00000)
+#define IMX_GPV_BASE U(0x32000000)
+#define IMX_GPV_SIZE U(0x800000)
+#define IMX_AIPS1_BASE U(0x30200000)
+#define IMX_AIPS4_BASE U(0x32c00000)
+#define IMX_ANAMIX_BASE U(0x30360000)
+#define IMX_CCM_BASE U(0x30380000)
+#define IMX_SRC_BASE U(0x30390000)
+#define IMX_GPC_BASE U(0x303a0000)
+#define IMX_RDC_BASE U(0x303d0000)
+#define IMX_CSU_BASE U(0x303e0000)
+#define IMX_WDOG_BASE U(0x30280000)
+#define IMX_SNVS_BASE U(0x30370000)
+#define IMX_NOC_BASE U(0x32700000)
+#define IMX_TZASC_BASE U(0x32F80000)
+#define IMX_IOMUX_GPR_BASE U(0x30340000)
+#define IMX_CAAM_BASE U(0x30900000)
+#define IMX_DDRC_BASE U(0x3d400000)
+#define IMX_DDRPHY_BASE U(0x3c000000)
+#define IMX_DDR_IPS_BASE U(0x3d000000)
+#define IMX_DDR_IPS_SIZE U(0x1800000)
+#define IMX_ROM_BASE U(0x0)
+
+#define IMX_GIC_BASE PLAT_GICD_BASE
+#define IMX_GIC_SIZE U(0x200000)
+
+#define WDOG_WSR U(0x2)
+#define WDOG_WCR_WDZST BIT(0)
+#define WDOG_WCR_WDBG BIT(1)
+#define WDOG_WCR_WDE BIT(2)
+#define WDOG_WCR_WDT BIT(3)
+#define WDOG_WCR_SRS BIT(4)
+#define WDOG_WCR_WDA BIT(5)
+#define WDOG_WCR_SRE BIT(6)
+#define WDOG_WCR_WDW BIT(7)
+
+#define SRC_A53RCR0 U(0x4)
+#define SRC_A53RCR1 U(0x8)
+#define SRC_OTG1PHY_SCR U(0x20)
+#define SRC_GPR1_OFFSET U(0x74)
+
+#define SNVS_LPCR U(0x38)
+#define SNVS_LPCR_SRTC_ENV BIT(0)
+#define SNVS_LPCR_DP_EN BIT(5)
+#define SNVS_LPCR_TOP BIT(6)
+
+#define IOMUXC_GPR10 U(0x28)
+#define GPR_TZASC_EN BIT(0)
+#define GPR_TZASC_EN_LOCK BIT(16)
+
+#define ANAMIX_MISC_CTL U(0x124)
+#define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50)
+
+#define MAX_CSU_NUM U(64)
+
+#define OCRAM_S_BASE U(0x00180000)
+#define OCRAM_S_SIZE U(0x8000)
+#define OCRAM_S_LIMIT (OCRAM_S_BASE + OCRAM_S_SIZE)
+#define SAVED_DRAM_TIMING_BASE OCRAM_S_BASE
+
+#define COUNTER_FREQUENCY 8000000 /* 8MHz */
+
+#define IMX_WDOG_B_RESET
+
+#define GIC_MAP MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW)
+#define AIPS_MAP MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW) /* AIPS map */
+#define OCRAM_S_MAP MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_DEVICE | MT_RW) /* OCRAM_S */
+#define DDRC_MAP MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW) /* DDRMIX */
+
+#endif /* platform_def.h */
diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk
new file mode 100644
index 000000000..8c4ad1c21
--- /dev/null
+++ b/plat/imx/imx8m/imx8mn/platform.mk
@@ -0,0 +1,56 @@
+#
+# Copyright 2019-2020 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES := -Iplat/imx/common/include \
+ -Iplat/imx/imx8m/include \
+ -Iplat/imx/imx8m/imx8mn/include
+# Translation tables library
+include lib/xlat_tables_v2/xlat_tables.mk
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+IMX_GIC_SOURCES := ${GICV3_SOURCES} \
+ plat/common/plat_gicv3.c \
+ plat/common/plat_psci_common.c \
+ plat/imx/common/plat_imx8_gic.c
+
+BL31_SOURCES += plat/imx/common/imx8_helpers.S \
+ plat/imx/imx8m/gpc_common.c \
+ plat/imx/imx8m/imx_aipstz.c \
+ plat/imx/imx8m/imx_rdc.c \
+ plat/imx/imx8m/imx8m_caam.c \
+ plat/imx/imx8m/imx8m_psci_common.c \
+ plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c \
+ plat/imx/imx8m/imx8mn/imx8mn_psci.c \
+ plat/imx/imx8m/imx8mn/gpc.c \
+ plat/imx/common/imx8_topology.c \
+ plat/imx/common/imx_sip_handler.c \
+ plat/imx/common/imx_sip_svc.c \
+ plat/imx/common/imx_uart_console.S \
+ lib/cpus/aarch64/cortex_a53.S \
+ drivers/arm/tzc/tzc380.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ ${IMX_GIC_SOURCES} \
+ ${XLAT_TABLES_LIB_SRCS}
+
+USE_COHERENT_MEM := 1
+RESET_TO_BL31 := 1
+A53_DISABLE_NON_TEMPORAL_HINT := 0
+
+ERRATA_A53_835769 := 1
+ERRATA_A53_843419 := 1
+ERRATA_A53_855873 := 1
+
+BL32_BASE ?= 0xbe000000
+$(eval $(call add_define,BL32_BASE))
+
+BL32_SIZE ?= 0x2000000
+$(eval $(call add_define,BL32_SIZE))
+
+IMX_BOOT_UART_BASE ?= 0x30890000
+$(eval $(call add_define,IMX_BOOT_UART_BASE))
diff --git a/plat/imx/imx8m/imx8mp/gpc.c b/plat/imx/imx8m/imx8mp/gpc.c
new file mode 100644
index 000000000..d660e3d88
--- /dev/null
+++ b/plat/imx/imx8m/imx8mp/gpc.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright 2019-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/smccc.h>
+#include <services/std_svc.h>
+
+#include <gpc.h>
+#include <imx_aipstz.h>
+#include <imx_sip_svc.h>
+#include <platform_def.h>
+
+#define CCGR(x) (0x4000 + (x) * 0x10)
+#define IMR_NUM U(5)
+
+struct imx_noc_setting {
+ uint32_t domain_id;
+ uint32_t start;
+ uint32_t end;
+ uint32_t prioriy;
+ uint32_t mode;
+ uint32_t socket_qos_en;
+};
+
+enum clk_type {
+ CCM_ROOT_SLICE,
+ CCM_CCGR,
+};
+
+struct clk_setting {
+ uint32_t offset;
+ uint32_t val;
+ enum clk_type type;
+};
+
+enum pu_domain_id {
+ /* hsio ss */
+ HSIOMIX,
+ PCIE_PHY,
+ USB1_PHY,
+ USB2_PHY,
+ MLMIX,
+ AUDIOMIX,
+ /* gpu ss */
+ GPUMIX,
+ GPU2D,
+ GPU3D,
+ /* vpu ss */
+ VPUMIX,
+ VPU_G1,
+ VPU_G2,
+ VPU_H1,
+ /* media ss */
+ MEDIAMIX,
+ MEDIAMIX_ISPDWP,
+ MIPI_PHY1,
+ MIPI_PHY2,
+ /* HDMI ss */
+ HDMIMIX,
+ HDMI_PHY,
+ DDRMIX,
+};
+
+/* PU domain, add some hole to minimize the uboot change */
+static struct imx_pwr_domain pu_domains[20] = {
+ [MIPI_PHY1] = IMX_PD_DOMAIN(MIPI_PHY1, false),
+ [PCIE_PHY] = IMX_PD_DOMAIN(PCIE_PHY, false),
+ [USB1_PHY] = IMX_PD_DOMAIN(USB1_PHY, true),
+ [USB2_PHY] = IMX_PD_DOMAIN(USB2_PHY, true),
+ [MLMIX] = IMX_MIX_DOMAIN(MLMIX, false),
+ [AUDIOMIX] = IMX_MIX_DOMAIN(AUDIOMIX, false),
+ [GPU2D] = IMX_PD_DOMAIN(GPU2D, false),
+ [GPUMIX] = IMX_MIX_DOMAIN(GPUMIX, false),
+ [VPUMIX] = IMX_MIX_DOMAIN(VPUMIX, false),
+ [GPU3D] = IMX_PD_DOMAIN(GPU3D, false),
+ [MEDIAMIX] = IMX_MIX_DOMAIN(MEDIAMIX, false),
+ [VPU_G1] = IMX_PD_DOMAIN(VPU_G1, false),
+ [VPU_G2] = IMX_PD_DOMAIN(VPU_G2, false),
+ [VPU_H1] = IMX_PD_DOMAIN(VPU_H1, false),
+ [HDMIMIX] = IMX_MIX_DOMAIN(HDMIMIX, false),
+ [HDMI_PHY] = IMX_PD_DOMAIN(HDMI_PHY, false),
+ [MIPI_PHY2] = IMX_PD_DOMAIN(MIPI_PHY2, false),
+ [HSIOMIX] = IMX_MIX_DOMAIN(HSIOMIX, false),
+ [MEDIAMIX_ISPDWP] = IMX_PD_DOMAIN(MEDIAMIX_ISPDWP, false),
+};
+
+static struct imx_noc_setting noc_setting[] = {
+ {MLMIX, 0x180, 0x180, 0x80000303, 0x0, 0x0},
+ {AUDIOMIX, 0x200, 0x200, 0x80000303, 0x0, 0x0},
+ {AUDIOMIX, 0x280, 0x480, 0x80000404, 0x0, 0x0},
+ {GPUMIX, 0x500, 0x580, 0x80000303, 0x0, 0x0},
+ {HDMIMIX, 0x600, 0x680, 0x80000202, 0x0, 0x1},
+ {HDMIMIX, 0x700, 0x700, 0x80000505, 0x0, 0x0},
+ {HSIOMIX, 0x780, 0x900, 0x80000303, 0x0, 0x0},
+ {MEDIAMIX, 0x980, 0xb80, 0x80000202, 0x0, 0x1},
+ {MEDIAMIX_ISPDWP, 0xc00, 0xd00, 0x80000505, 0x0, 0x0},
+ {VPU_G1, 0xd80, 0xd80, 0x80000303, 0x0, 0x0},
+ {VPU_G2, 0xe00, 0xe00, 0x80000303, 0x0, 0x0},
+ {VPU_H1, 0xe80, 0xe80, 0x80000303, 0x0, 0x0}
+};
+
+static struct clk_setting hsiomix_clk[] = {
+ { 0x8380, 0x0, CCM_ROOT_SLICE },
+ { 0x44d0, 0x0, CCM_CCGR },
+ { 0x45c0, 0x0, CCM_CCGR },
+};
+
+static struct aipstz_cfg aipstz5[] = {
+ {IMX_AIPSTZ5, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {0},
+};
+
+static unsigned int pu_domain_status;
+
+static void imx_noc_qos(unsigned int domain_id)
+{
+ unsigned int i;
+ uint32_t hurry;
+
+ if (domain_id == HDMIMIX) {
+ mmio_write_32(IMX_HDMI_CTL_BASE + TX_CONTROL1, 0x22018);
+ mmio_write_32(IMX_HDMI_CTL_BASE + TX_CONTROL1, 0x22010);
+
+ /* set GPR to make lcdif read hurry level 0x7 */
+ hurry = mmio_read_32(IMX_HDMI_CTL_BASE + TX_CONTROL0);
+ hurry |= 0x00077000;
+ mmio_write_32(IMX_HDMI_CTL_BASE + TX_CONTROL0, hurry);
+ }
+
+ if (domain_id == MEDIAMIX) {
+ /* handle mediamix special */
+ mmio_write_32(IMX_MEDIAMIX_CTL_BASE + RSTn_CSR, 0x1FFFFFF);
+ mmio_write_32(IMX_MEDIAMIX_CTL_BASE + CLK_EN_CSR, 0x1FFFFFF);
+ mmio_write_32(IMX_MEDIAMIX_CTL_BASE + RST_DIV, 0x40030000);
+
+ /* set GPR to make lcdif read hurry level 0x7 */
+ hurry = mmio_read_32(IMX_MEDIAMIX_CTL_BASE + LCDIF_ARCACHE_CTRL);
+ hurry |= 0xfc00;
+ mmio_write_32(IMX_MEDIAMIX_CTL_BASE + LCDIF_ARCACHE_CTRL, hurry);
+ /* set GPR to make isi write hurry level 0x7 */
+ hurry = mmio_read_32(IMX_MEDIAMIX_CTL_BASE + ISI_CACHE_CTRL);
+ hurry |= 0x1ff00000;
+ mmio_write_32(IMX_MEDIAMIX_CTL_BASE + ISI_CACHE_CTRL, hurry);
+ }
+
+ /* set MIX NoC */
+ for (i = 0; i < ARRAY_SIZE(noc_setting); i++) {
+ if (noc_setting[i].domain_id == domain_id) {
+ udelay(50);
+ uint32_t offset = noc_setting[i].start;
+
+ while (offset <= noc_setting[i].end) {
+ mmio_write_32(IMX_NOC_BASE + offset + 0x8, noc_setting[i].prioriy);
+ mmio_write_32(IMX_NOC_BASE + offset + 0xc, noc_setting[i].mode);
+ mmio_write_32(IMX_NOC_BASE + offset + 0x18, noc_setting[i].socket_qos_en);
+ offset += 0x80;
+ }
+ }
+ }
+}
+
+static void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on)
+{
+ struct imx_pwr_domain *pwr_domain = &pu_domains[domain_id];
+ unsigned int i;
+
+ if (domain_id == HSIOMIX) {
+ for (i = 0; i < ARRAY_SIZE(hsiomix_clk); i++) {
+ hsiomix_clk[i].val = mmio_read_32(IMX_CCM_BASE + hsiomix_clk[i].offset);
+ mmio_setbits_32(IMX_CCM_BASE + hsiomix_clk[i].offset,
+ hsiomix_clk[i].type == CCM_ROOT_SLICE ? BIT(28) : 0x3);
+ }
+ }
+
+ if (on) {
+ if (pwr_domain->need_sync) {
+ pu_domain_status |= (1 << domain_id);
+ }
+
+ if (domain_id == HDMIMIX) {
+ /* assert the reset */
+ mmio_write_32(IMX_HDMI_CTL_BASE + RTX_RESET_CTL0, 0x0);
+ /* enable all th function clock */
+ mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL0, 0xFFFFFFFF);
+ mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL1, 0x7ffff87e);
+ }
+
+ /* clear the PGC bit */
+ mmio_clrbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
+
+ /* power up the domain */
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, pwr_domain->pwr_req);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & pwr_domain->pwr_req)
+ ;
+
+ if (domain_id == HDMIMIX) {
+ /* wait for memory repair done for HDMIMIX */
+ while (!(mmio_read_32(IMX_SRC_BASE + 0x94) & BIT(8)))
+ ;
+ /* disable all the function clock */
+ mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL0, 0x0);
+ mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL1, 0x0);
+ /* deassert the reset */
+ mmio_write_32(IMX_HDMI_CTL_BASE + RTX_RESET_CTL0, 0xffffffff);
+ /* enable all the clock again */
+ mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL0, 0xFFFFFFFF);
+ mmio_write_32(IMX_HDMI_CTL_BASE + RTX_CLK_CTL1, 0x7ffff87e);
+ }
+
+ if (domain_id == HSIOMIX) {
+ /* enable HSIOMIX clock */
+ mmio_write_32(IMX_HSIOMIX_CTL_BASE, 0x2);
+ }
+
+ /* handle the ADB400 sync */
+ if (pwr_domain->need_sync) {
+ /* clear adb power down request */
+ mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
+
+ /* wait for adb power request ack */
+ while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack))
+ ;
+ }
+
+ imx_noc_qos(domain_id);
+
+ /* AIPS5 config is lost when audiomix is off, so need to re-init it */
+ if (domain_id == AUDIOMIX) {
+ imx_aipstz_init(aipstz5);
+ }
+ } else {
+ if (pwr_domain->always_on) {
+ return;
+ }
+
+ if (pwr_domain->need_sync) {
+ pu_domain_status &= ~(1 << domain_id);
+ }
+
+ /* handle the ADB400 sync */
+ if (pwr_domain->need_sync) {
+ /* set adb power down request */
+ mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
+
+ /* wait for adb power request ack */
+ while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack))
+ ;
+ }
+
+ /* set the PGC bit */
+ mmio_setbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
+
+ /*
+ * leave the G1, G2, H1 power domain on until VPUMIX power off,
+ * otherwise system will hang due to VPUMIX ACK
+ */
+ if (domain_id == VPU_H1 || domain_id == VPU_G1 || domain_id == VPU_G2) {
+ return;
+ }
+
+ if (domain_id == VPUMIX) {
+ mmio_write_32(IMX_GPC_BASE + PU_PGC_DN_TRG, VPU_G1_PWR_REQ |
+ VPU_G2_PWR_REQ | VPU_H1_PWR_REQ);
+
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & (VPU_G1_PWR_REQ |
+ VPU_G2_PWR_REQ | VPU_H1_PWR_REQ))
+ ;
+ }
+
+ /* power down the domain */
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, pwr_domain->pwr_req);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & pwr_domain->pwr_req)
+ ;
+
+ if (domain_id == HDMIMIX) {
+ /* disable all the clocks of HDMIMIX */
+ mmio_write_32(IMX_HDMI_CTL_BASE + 0x40, 0x0);
+ mmio_write_32(IMX_HDMI_CTL_BASE + 0x50, 0x0);
+ }
+ }
+
+ if (domain_id == HSIOMIX) {
+ for (i = 0; i < ARRAY_SIZE(hsiomix_clk); i++) {
+ mmio_write_32(IMX_CCM_BASE + hsiomix_clk[i].offset, hsiomix_clk[i].val);
+ }
+ }
+}
+
+void imx_gpc_init(void)
+{
+ uint32_t val;
+ unsigned int i;
+
+ /* mask all the wakeup irq by default */
+ for (i = 0; i < IMR_NUM; i++) {
+ mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_A53 + i * 4, ~0x0);
+ mmio_write_32(IMX_GPC_BASE + IMR1_CORE1_A53 + i * 4, ~0x0);
+ mmio_write_32(IMX_GPC_BASE + IMR1_CORE2_A53 + i * 4, ~0x0);
+ mmio_write_32(IMX_GPC_BASE + IMR1_CORE3_A53 + i * 4, ~0x0);
+ mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_M4 + i * 4, ~0x0);
+ }
+
+ val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_BSC);
+ /* use GIC wake_request to wakeup C0~C3 from LPM */
+ val |= CORE_WKUP_FROM_GIC;
+ /* clear the MASTER0 LPM handshake */
+ val &= ~MASTER0_LPM_HSK;
+ mmio_write_32(IMX_GPC_BASE + LPCR_A53_BSC, val);
+
+ /* clear MASTER1 & MASTER2 mapping in CPU0(A53) */
+ mmio_clrbits_32(IMX_GPC_BASE + MST_CPU_MAPPING, (MASTER1_MAPPING |
+ MASTER2_MAPPING));
+
+ /* set all mix/PU in A53 domain */
+ mmio_write_32(IMX_GPC_BASE + PGC_CPU_0_1_MAPPING, 0x3fffff);
+
+ /*
+ * Set the CORE & SCU power up timing:
+ * SW = 0x1, SW2ISO = 0x1;
+ * the CPU CORE and SCU power up timming counter
+ * is drived by 32K OSC, each domain's power up
+ * latency is (SW + SW2ISO) / 32768
+ */
+ mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(0) + 0x4, 0x401);
+ mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(1) + 0x4, 0x401);
+ mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(2) + 0x4, 0x401);
+ mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(3) + 0x4, 0x401);
+ mmio_write_32(IMX_GPC_BASE + PLAT_PGC_PCR + 0x4, 0x401);
+ mmio_write_32(IMX_GPC_BASE + PGC_SCU_TIMING,
+ (0x59 << TMC_TMR_SHIFT) | 0x5B | (0x2 << TRC1_TMC_SHIFT));
+
+ /* set DUMMY PDN/PUP ACK by default for A53 domain */
+ mmio_write_32(IMX_GPC_BASE + PGC_ACK_SEL_A53,
+ A53_DUMMY_PUP_ACK | A53_DUMMY_PDN_ACK);
+
+ /* clear DSM by default */
+ val = mmio_read_32(IMX_GPC_BASE + SLPCR);
+ val &= ~SLPCR_EN_DSM;
+ /* enable the fast wakeup wait/stop mode */
+ val |= SLPCR_A53_FASTWUP_WAIT_MODE;
+ val |= SLPCR_A53_FASTWUP_STOP_MODE;
+ /* clear the RBC */
+ val &= ~(0x3f << SLPCR_RBC_COUNT_SHIFT);
+ /* set the STBY_COUNT to 0x5, (128 * 30)us */
+ val &= ~(0x7 << SLPCR_STBY_COUNT_SHFT);
+ val |= (0x5 << SLPCR_STBY_COUNT_SHFT);
+ mmio_write_32(IMX_GPC_BASE + SLPCR, val);
+
+ /*
+ * USB PHY power up needs to make sure RESET bit in SRC is clear,
+ * otherwise, the PU power up bit in GPC will NOT self-cleared.
+ * only need to do it once.
+ */
+ mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1);
+ mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG2PHY_SCR, 0x1);
+
+ /* enable all the power domain by default */
+ for (i = 0; i < 101; i++) {
+ mmio_write_32(IMX_CCM_BASE + CCGR(i), 0x3);
+ }
+
+ for (i = 0; i < 20; i++) {
+ imx_gpc_pm_domain_enable(i, true);
+ }
+}
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
new file mode 100644
index 000000000..22fbd5e4b
--- /dev/null
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <context.h>
+#include <drivers/arm/tzc380.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <gpc.h>
+#include <imx_aipstz.h>
+#include <imx_uart.h>
+#include <imx_rdc.h>
+#include <imx8m_caam.h>
+#include <platform_def.h>
+#include <plat_imx8.h>
+
+static const mmap_region_t imx_mmap[] = {
+ GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP,
+ NOC_MAP, {0},
+};
+
+static const struct aipstz_cfg aipstz[] = {
+ {IMX_AIPSTZ1, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {IMX_AIPSTZ2, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {IMX_AIPSTZ3, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {IMX_AIPSTZ4, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, },
+ {0},
+};
+
+static const struct imx_rdc_cfg rdc[] = {
+ /* Master domain assignment */
+ RDC_MDAn(0x1, DID1),
+
+ /* peripherals domain permission */
+
+ /* memory region */
+
+ /* Sentinel */
+ {0},
+};
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/* get SPSR for BL33 entry */
+static uint32_t get_spsr_for_bl33_entry(void)
+{
+ unsigned long el_status;
+ unsigned long mode;
+ uint32_t spsr;
+
+ /* figure out what mode we enter the non-secure world */
+ el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+ el_status &= ID_AA64PFR0_ELX_MASK;
+
+ mode = (el_status) ? MODE_EL2 : MODE_EL1;
+
+ spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+}
+
+static void bl31_tzc380_setup(void)
+{
+ unsigned int val;
+
+ val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x28);
+ if ((val & GPR_TZASC_EN) != GPR_TZASC_EN)
+ return;
+
+ tzc380_init(IMX_TZASC_BASE);
+
+ /*
+ * Need to substact offset 0x40000000 from CPU address when
+ * programming tzasc region for i.mx8mp.
+ */
+
+ /* Enable 1G-5G S/NS RW */
+ tzc380_configure_region(0, 0x00000000, TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_4G) |
+ TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_ALL);
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ static console_t console;
+ unsigned int i;
+
+ /* Enable CSU NS access permission */
+ for (i = 0; i < 64; i++) {
+ mmio_write_32(IMX_CSU_BASE + i * 4, 0x00ff00ff);
+ }
+
+ imx_aipstz_init(aipstz);
+
+ imx_rdc_init(rdc);
+
+ imx8m_caam_init();
+
+ console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+ IMX_CONSOLE_BAUDRATE, &console);
+ /* This console is only used for boot stage */
+ console_set_scope(&console, CONSOLE_FLAG_BOOT);
+
+ /*
+ * tell BL3-1 where the non-secure software image is located
+ * and the entry state information.
+ */
+ bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
+ bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
+ SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+#ifdef SPD_opteed
+ /* Populate entry point information for BL32 */
+ SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
+ SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+ bl32_image_ep_info.pc = BL32_BASE;
+ bl32_image_ep_info.spsr = 0;
+
+ /* Pass TEE base and size to bl33 */
+ bl33_image_ep_info.args.arg1 = BL32_BASE;
+ bl33_image_ep_info.args.arg2 = BL32_SIZE;
+#endif
+
+ bl31_tzc380_setup();
+}
+
+void bl31_plat_arch_setup(void)
+{
+ mmap_add_region(BL31_BASE, BL31_BASE, (BL31_LIMIT - BL31_BASE),
+ MT_MEMORY | MT_RW | MT_SECURE);
+ mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, (BL_CODE_END - BL_CODE_BASE),
+ MT_MEMORY | MT_RO | MT_SECURE);
+#if USE_COHERENT_MEM
+ mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+ (BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE),
+ MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+ mmap_add(imx_mmap);
+
+ init_xlat_tables();
+
+ enable_mmu_el3(0);
+}
+
+void bl31_platform_setup(void)
+{
+ generic_delay_timer_init();
+
+ /* select the CKIL source to 32K OSC */
+ mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1);
+
+ plat_gic_driver_init();
+ plat_gic_init();
+
+ imx_gpc_init();
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
+{
+ if (type == NON_SECURE) {
+ return &bl33_image_ep_info;
+ }
+
+ if (type == SECURE) {
+ return &bl32_image_ep_info;
+ }
+
+ return NULL;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ return COUNTER_FREQUENCY;
+}
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_psci.c b/plat/imx/imx8m/imx8mp/imx8mp_psci.c
new file mode 100644
index 000000000..bc7b24679
--- /dev/null
+++ b/plat/imx/imx8m/imx8mp/imx8mp_psci.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+
+#include <gpc.h>
+#include <imx8m_psci.h>
+#include <plat_imx8.h>
+
+static const plat_psci_ops_t imx_plat_psci_ops = {
+ .pwr_domain_on = imx_pwr_domain_on,
+ .pwr_domain_on_finish = imx_pwr_domain_on_finish,
+ .pwr_domain_off = imx_pwr_domain_off,
+ .validate_ns_entrypoint = imx_validate_ns_entrypoint,
+ .validate_power_state = imx_validate_power_state,
+ .cpu_standby = imx_cpu_standby,
+ .pwr_domain_suspend = imx_domain_suspend,
+ .pwr_domain_suspend_finish = imx_domain_suspend_finish,
+ .pwr_domain_pwr_down_wfi = imx_pwr_domain_pwr_down_wfi,
+ .get_sys_suspend_power_state = imx_get_sys_suspend_power_state,
+ .system_reset = imx_system_reset,
+ .system_off = imx_system_off,
+};
+
+/* export the platform specific psci ops */
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ /* sec_entrypoint is used for warm reset */
+ imx_mailbox_init(sec_entrypoint);
+
+ *psci_ops = &imx_plat_psci_ops;
+
+ return 0;
+}
diff --git a/plat/imx/imx8m/imx8mp/include/gpc_reg.h b/plat/imx/imx8m/imx8mp/include/gpc_reg.h
new file mode 100644
index 000000000..7909937b2
--- /dev/null
+++ b/plat/imx/imx8m/imx8mp/include/gpc_reg.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GPC_REG_H
+#define GPC_REG_H
+
+#define LPCR_A53_BSC 0x0
+#define LPCR_A53_BSC2 0x180
+#define LPCR_A53_AD 0x4
+#define LPCR_M4 0x8
+#define SLPCR 0x14
+#define MST_CPU_MAPPING 0x18
+#define MLPCR 0x20
+#define PGC_ACK_SEL_A53 0x24
+#define IMR1_CORE0_A53 0x30
+#define IMR1_CORE1_A53 0x44
+#define IMR1_CORE2_A53 0x194
+#define IMR1_CORE3_A53 0x1A8
+#define IMR1_CORE0_M4 0x58
+
+#define SLT0_CFG 0x200
+#define GPC_PU_PWRHSK 0x190
+#define PGC_CPU_0_1_MAPPING 0x1CC
+#define CPU_PGC_UP_TRG 0xD0
+#define PU_PGC_UP_TRG 0xD8
+#define CPU_PGC_DN_TRG 0xDC
+#define PU_PGC_DN_TRG 0xE4
+#define LPS_CPU1 0xEC
+
+#define A53_CORE0_PGC 0x800
+#define A53_PLAT_PGC 0x900
+#define PLAT_PGC_PCR 0x900
+#define NOC_PGC_PCR 0xa40
+#define PGC_SCU_TIMING 0x910
+
+#define MASK_DSM_TRIGGER_A53 BIT(31)
+#define IRQ_SRC_A53_WUP BIT(30)
+#define IRQ_SRC_A53_WUP_SHIFT 30
+#define IRQ_SRC_C1 BIT(29)
+#define IRQ_SRC_C0 BIT(28)
+#define IRQ_SRC_C3 BIT(23)
+#define IRQ_SRC_C2 BIT(22)
+#define CPU_CLOCK_ON_LPM BIT(14)
+#define A53_CLK_ON_LPM BIT(14)
+#define MASTER0_LPM_HSK BIT(6)
+#define MASTER1_LPM_HSK BIT(7)
+#define MASTER2_LPM_HSK BIT(8)
+
+#define L2PGE BIT(31)
+#define EN_L2_WFI_PDN BIT(5)
+#define EN_PLAT_PDN BIT(4)
+
+#define SLPCR_EN_DSM BIT(31)
+#define SLPCR_RBC_EN BIT(30)
+#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17)
+#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16)
+#define SLPCR_VSTBY BIT(2)
+#define SLPCR_SBYOS BIT(1)
+#define SLPCR_BYPASS_PMIC_READY BIT(0)
+#define SLPCR_RBC_COUNT_SHIFT 24
+#define SLPCR_STBY_COUNT_SHFT 3
+
+#define A53_DUMMY_PDN_ACK BIT(30)
+#define A53_DUMMY_PUP_ACK BIT(31)
+#define A53_PLAT_PDN_ACK BIT(8)
+#define A53_PLAT_PUP_ACK BIT(9)
+
+#define NOC_PDN_SLT_CTRL BIT(12)
+#define NOC_PUP_SLT_CTRL BIT(13)
+#define NOC_PGC_PDN_ACK BIT(12)
+#define NOC_PGC_PUP_ACK BIT(13)
+
+#define PLAT_PUP_SLT_CTRL BIT(9)
+#define PLAT_PDN_SLT_CTRL BIT(8)
+
+#define SLT_PLAT_PDN BIT(8)
+#define SLT_PLAT_PUP BIT(9)
+
+#define MASTER1_MAPPING BIT(1)
+#define MASTER2_MAPPING BIT(2)
+
+#define TMR_TCD2_SHIFT 0
+#define TMC_TMR_SHIFT 10
+#define TRC1_TMC_SHIFT 20
+
+#define MIPI_PHY1_PWR_REQ BIT(0)
+#define PCIE_PHY_PWR_REQ BIT(1)
+#define USB1_PHY_PWR_REQ BIT(2)
+#define USB2_PHY_PWR_REQ BIT(3)
+#define MLMIX_PWR_REQ BIT(4)
+#define AUDIOMIX_PWR_REQ BIT(5)
+#define GPU2D_PWR_REQ BIT(6)
+#define GPUMIX_PWR_REQ BIT(7)
+#define VPUMIX_PWR_REQ BIT(8)
+#define GPU3D_PWR_REQ BIT(9)
+#define MEDIAMIX_PWR_REQ BIT(10)
+#define VPU_G1_PWR_REQ BIT(11)
+#define VPU_G2_PWR_REQ BIT(12)
+#define VPU_H1_PWR_REQ BIT(13)
+#define HDMIMIX_PWR_REQ BIT(14)
+#define HDMI_PHY_PWR_REQ BIT(15)
+#define MIPI_PHY2_PWR_REQ BIT(16)
+#define HSIOMIX_PWR_REQ BIT(17)
+#define MEDIAMIX_ISPDWP_PWR_REQ BIT(18)
+#define DDRMIX_PWR_REQ BIT(19)
+
+#define AUDIOMIX_ADB400_SYNC (BIT(4) | BIT(15))
+#define MLMIX_ADB400_SYNC (BIT(7) | BIT(8))
+#define GPUMIX_ADB400_SYNC BIT(9)
+#define VPUMIX_ADB400_SYNC BIT(10)
+#define DDRMIX_ADB400_SYNC BIT(11)
+#define HSIOMIX_ADB400_SYNC BIT(12)
+#define HDMIMIX_ADB400_SYNC BIT(13)
+#define MEDIAMIX_ADB400_SYNC BIT(14)
+
+#define AUDIOMIX_ADB400_ACK (BIT(20) | BIT(31))
+#define MLMIX_ADB400_ACK (BIT(23) | BIT(24))
+#define GPUMIX_ADB400_ACK BIT(25)
+#define VPUMIX_ADB400_ACK BIT(26)
+#define DDRMIX_ADB400_ACK BIT(27)
+#define HSIOMIX_ADB400_ACK BIT(28)
+#define HDMIMIX_ADB400_ACK BIT(29)
+#define MEDIAMIX_ADB400_ACK BIT(30)
+
+#define MIPI_PHY1_PGC 0xb00
+#define PCIE_PHY_PGC 0xb40
+#define USB1_PHY_PGC 0xb80
+#define USB2_PHY_PGC 0xbc0
+#define MLMIX_PGC 0xc00
+#define AUDIOMIX_PGC 0xc40
+#define GPU2D_PGC 0xc80
+#define GPUMIX_PGC 0xcc0
+#define VPUMIX_PGC 0xd00
+#define GPU3D_PGC 0xd40
+#define MEDIAMIX_PGC 0xd80
+#define VPU_G1_PGC 0xdc0
+#define VPU_G2_PGC 0xe00
+#define VPU_H1_PGC 0xe40
+#define HDMIMIX_PGC 0xe80
+#define HDMI_PHY_PGC 0xec0
+#define MIPI_PHY2_PGC 0xf00
+#define HSIOMIX_PGC 0xf40
+#define MEDIAMIX_ISPDWP_PGC 0xf80
+#define DDRMIX_PGC 0xfc0
+
+#define IRQ_IMR_NUM U(5)
+
+#endif /* GPC_REG_H */
diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h
new file mode 100644
index 000000000..644adc771
--- /dev/null
+++ b/plat/imx/imx8m/imx8mp/include/platform_def.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+#define PLATFORM_STACK_SIZE 0xB00
+#define CACHE_WRITEBACK_GRANULE 64
+
+#define PLAT_PRIMARY_CPU U(0x0)
+#define PLATFORM_MAX_CPU_PER_CLUSTER U(4)
+#define PLATFORM_CLUSTER_COUNT U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT U(4)
+#define PLATFORM_CLUSTER1_CORE_COUNT U(0)
+#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT)
+
+#define IMX_PWR_LVL0 MPIDR_AFFLVL0
+#define IMX_PWR_LVL1 MPIDR_AFFLVL1
+#define IMX_PWR_LVL2 MPIDR_AFFLVL2
+
+#define PWR_DOMAIN_AT_MAX_LVL U(1)
+#define PLAT_MAX_PWR_LVL U(2)
+#define PLAT_MAX_OFF_STATE U(4)
+#define PLAT_MAX_RET_STATE U(2)
+
+#define PLAT_WAIT_RET_STATE U(1)
+#define PLAT_STOP_OFF_STATE U(3)
+
+#define BL31_BASE U(0x960000)
+#define BL31_LIMIT U(0x980000)
+
+/* non-secure uboot base */
+#define PLAT_NS_IMAGE_OFFSET U(0x40200000)
+
+/* GICv3 base address */
+#define PLAT_GICD_BASE U(0x38800000)
+#define PLAT_GICR_BASE U(0x38880000)
+
+#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32)
+
+#define MAX_XLAT_TABLES 8
+#define MAX_MMAP_REGIONS 16
+
+#define HAB_RVT_BASE U(0x00000900) /* HAB_RVT for i.MX8MM */
+
+#define IMX_BOOT_UART_CLK_IN_HZ 24000000 /* Select 24MHz oscillator */
+#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
+#define PLAT_CRASH_UART_CLK_IN_HZ 24000000
+#define IMX_CONSOLE_BAUDRATE 115200
+
+#define IMX_AIPSTZ1 U(0x301f0000)
+#define IMX_AIPSTZ2 U(0x305f0000)
+#define IMX_AIPSTZ3 U(0x309f0000)
+#define IMX_AIPSTZ4 U(0x32df0000)
+#define IMX_AIPSTZ5 U(0x30df0000)
+
+#define IMX_AIPS_BASE U(0x30000000)
+#define IMX_AIPS_SIZE U(0x3000000)
+#define IMX_GPV_BASE U(0x32000000)
+#define IMX_GPV_SIZE U(0x800000)
+#define IMX_AIPS1_BASE U(0x30200000)
+#define IMX_AIPS4_BASE U(0x32c00000)
+#define IMX_ANAMIX_BASE U(0x30360000)
+#define IMX_CCM_BASE U(0x30380000)
+#define IMX_SRC_BASE U(0x30390000)
+#define IMX_GPC_BASE U(0x303a0000)
+#define IMX_RDC_BASE U(0x303d0000)
+#define IMX_CSU_BASE U(0x303e0000)
+#define IMX_WDOG_BASE U(0x30280000)
+#define IMX_SNVS_BASE U(0x30370000)
+#define IMX_NOC_BASE U(0x32700000)
+#define IMX_NOC_SIZE U(0x100000)
+#define IMX_TZASC_BASE U(0x32F80000)
+#define IMX_IOMUX_GPR_BASE U(0x30340000)
+#define IMX_CAAM_BASE U(0x30900000)
+#define IMX_DDRC_BASE U(0x3d400000)
+#define IMX_DDRPHY_BASE U(0x3c000000)
+#define IMX_DDR_IPS_BASE U(0x3d000000)
+#define IMX_DDR_IPS_SIZE U(0x1800000)
+#define IMX_ROM_BASE U(0x0)
+
+#define IMX_GIC_BASE PLAT_GICD_BASE
+#define IMX_GIC_SIZE U(0x200000)
+
+#define IMX_HSIOMIX_CTL_BASE U(0x32f10000)
+#define IMX_HDMI_CTL_BASE U(0x32fc0000)
+#define RTX_RESET_CTL0 U(0x20)
+#define RTX_CLK_CTL0 U(0x40)
+#define RTX_CLK_CTL1 U(0x50)
+#define TX_CONTROL0 U(0x200)
+#define TX_CONTROL1 U(0x220)
+
+#define IMX_MEDIAMIX_CTL_BASE U(0x32ec0000)
+#define RSTn_CSR U(0x0)
+#define CLK_EN_CSR U(0x4)
+#define RST_DIV U(0x8)
+#define LCDIF_ARCACHE_CTRL U(0x4c)
+#define ISI_CACHE_CTRL U(0x50)
+
+#define WDOG_WSR U(0x2)
+#define WDOG_WCR_WDZST BIT(0)
+#define WDOG_WCR_WDBG BIT(1)
+#define WDOG_WCR_WDE BIT(2)
+#define WDOG_WCR_WDT BIT(3)
+#define WDOG_WCR_SRS BIT(4)
+#define WDOG_WCR_WDA BIT(5)
+#define WDOG_WCR_SRE BIT(6)
+#define WDOG_WCR_WDW BIT(7)
+
+#define SRC_A53RCR0 U(0x4)
+#define SRC_A53RCR1 U(0x8)
+#define SRC_OTG1PHY_SCR U(0x20)
+#define SRC_OTG2PHY_SCR U(0x24)
+#define SRC_GPR1_OFFSET U(0x74)
+
+#define SNVS_LPCR U(0x38)
+#define SNVS_LPCR_SRTC_ENV BIT(0)
+#define SNVS_LPCR_DP_EN BIT(5)
+#define SNVS_LPCR_TOP BIT(6)
+
+#define IOMUXC_GPR10 U(0x28)
+#define GPR_TZASC_EN BIT(0)
+#define GPR_TZASC_EN_LOCK BIT(16)
+
+#define ANAMIX_MISC_CTL U(0x124)
+#define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50)
+
+#define MAX_CSU_NUM U(64)
+
+#define OCRAM_S_BASE U(0x00180000)
+#define OCRAM_S_SIZE U(0x8000)
+#define OCRAM_S_LIMIT (OCRAM_S_BASE + OCRAM_S_SIZE)
+#define SAVED_DRAM_TIMING_BASE OCRAM_S_BASE
+
+#define COUNTER_FREQUENCY 8000000 /* 8MHz */
+
+#define IMX_WDOG_B_RESET
+
+#define GIC_MAP MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW)
+#define AIPS_MAP MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW) /* AIPS map */
+#define OCRAM_S_MAP MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_MEMORY | MT_RW) /* OCRAM_S */
+#define DDRC_MAP MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW) /* DDRMIX */
+#define NOC_MAP MAP_REGION_FLAT(IMX_NOC_BASE, IMX_NOC_SIZE, MT_DEVICE | MT_RW) /* NOC QoS */
+
+#endif /* platform_def.h */
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
new file mode 100644
index 000000000..1d11e3df4
--- /dev/null
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -0,0 +1,56 @@
+#
+# Copyright 2019-2020 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES := -Iplat/imx/common/include \
+ -Iplat/imx/imx8m/include \
+ -Iplat/imx/imx8m/imx8mp/include
+# Translation tables library
+include lib/xlat_tables_v2/xlat_tables.mk
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+IMX_GIC_SOURCES := ${GICV3_SOURCES} \
+ plat/common/plat_gicv3.c \
+ plat/common/plat_psci_common.c \
+ plat/imx/common/plat_imx8_gic.c
+
+BL31_SOURCES += plat/imx/common/imx8_helpers.S \
+ plat/imx/imx8m/gpc_common.c \
+ plat/imx/imx8m/imx_aipstz.c \
+ plat/imx/imx8m/imx_rdc.c \
+ plat/imx/imx8m/imx8m_caam.c \
+ plat/imx/imx8m/imx8m_psci_common.c \
+ plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c \
+ plat/imx/imx8m/imx8mp/imx8mp_psci.c \
+ plat/imx/imx8m/imx8mp/gpc.c \
+ plat/imx/common/imx8_topology.c \
+ plat/imx/common/imx_sip_handler.c \
+ plat/imx/common/imx_sip_svc.c \
+ plat/imx/common/imx_uart_console.S \
+ lib/cpus/aarch64/cortex_a53.S \
+ drivers/arm/tzc/tzc380.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ ${IMX_GIC_SOURCES} \
+ ${XLAT_TABLES_LIB_SRCS}
+
+USE_COHERENT_MEM := 1
+RESET_TO_BL31 := 1
+A53_DISABLE_NON_TEMPORAL_HINT := 0
+
+ERRATA_A53_835769 := 1
+ERRATA_A53_843419 := 1
+ERRATA_A53_855873 := 1
+
+BL32_BASE ?= 0x56000000
+$(eval $(call add_define,BL32_BASE))
+
+BL32_SIZE ?= 0x2000000
+$(eval $(call add_define,BL32_SIZE))
+
+IMX_BOOT_UART_BASE ?= 0x30890000
+$(eval $(call add_define,IMX_BOOT_UART_BASE))
diff --git a/plat/imx/imx8m/imx8mq/gpc.c b/plat/imx/imx8m/imx8mq/gpc.c
index 942ae459c..367c9411d 100644
--- a/plat/imx/imx8m/imx8mq/gpc.c
+++ b/plat/imx/imx8m/imx8mq/gpc.c
@@ -19,9 +19,14 @@
/* use wfi power down the core */
void imx_set_cpu_pwr_off(unsigned int core_id)
{
+ bakery_lock_get(&gpc_lock);
+
/* enable the wfi power down of the core */
mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) |
(1 << (core_id + 20)));
+
+ bakery_lock_release(&gpc_lock);
+
/* assert the pcg pcr bit of the core */
mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1);
};
@@ -29,6 +34,8 @@ void imx_set_cpu_pwr_off(unsigned int core_id)
/* if out of lpm, we need to do reverse steps */
void imx_set_cpu_lpm(unsigned int core_id, bool pdn)
{
+ bakery_lock_get(&gpc_lock);
+
if (pdn) {
/* enable the core WFI PDN & IRQ PUP */
mmio_setbits_32(IMX_GPC_BASE + LPCR_A53_AD, COREx_WFI_PDN(core_id) |
@@ -42,6 +49,8 @@ void imx_set_cpu_lpm(unsigned int core_id, bool pdn)
/* deassert the pcg pcr bit of the core */
mmio_setbits_32(IMX_GPC_BASE + COREx_PGC_PCR(core_id), 0x1);
}
+
+ bakery_lock_release(&gpc_lock);
}
void imx_pup_pdn_slot_config(int last_core, bool pdn)
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index a347389a2..05b59705f 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
@@ -133,7 +133,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
imx8m_caam_init();
#if DEBUG_CONSOLE
- static console_uart_t console;
+ static console_t console;
console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
IMX_CONSOLE_BAUDRATE, &console);
diff --git a/plat/imx/imx8m/imx8mq/include/gpc_reg.h b/plat/imx/imx8m/imx8mq/include/gpc_reg.h
new file mode 100644
index 000000000..f171bd9d0
--- /dev/null
+++ b/plat/imx/imx8m/imx8mq/include/gpc_reg.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GPC_REG_H
+#define GPC_REG_H
+
+#define LPCR_A53_BSC 0x0
+#define LPCR_A53_BSC2 0x108
+#define LPCR_A53_AD 0x4
+#define LPCR_M4 0x8
+#define SLPCR 0x14
+#define MST_CPU_MAPPING 0x18
+#define MLPCR 0x20
+#define PGC_ACK_SEL_A53 0x24
+#define IMR1_CORE0_A53 0x30
+#define IMR1_CORE1_A53 0x40
+#define IMR1_CORE2_A53 0x1C0
+#define IMR1_CORE3_A53 0x1D0
+#define IMR1_CORE0_M4 0x50
+#define SLT0_CFG 0xB0
+#define GPC_PU_PWRHSK 0x1FC
+#define PGC_CPU_0_1_MAPPING 0xEC
+#define CPU_PGC_UP_TRG 0xF0
+#define PU_PGC_UP_TRG 0xF8
+#define CPU_PGC_DN_TRG 0xFC
+#define PU_PGC_DN_TRG 0x104
+#define LPS_CPU1 0x114
+#define A53_CORE0_PGC 0x800
+#define A53_PLAT_PGC 0x900
+#define PLAT_PGC_PCR 0x900
+#define NOC_PGC_PCR 0xa40
+#define PGC_SCU_TIMING 0x910
+
+#define MASK_DSM_TRIGGER_A53 BIT(31)
+#define IRQ_SRC_A53_WUP BIT(30)
+#define IRQ_SRC_A53_WUP_SHIFT 30
+#define IRQ_SRC_C1 BIT(29)
+#define IRQ_SRC_C0 BIT(28)
+#define IRQ_SRC_C3 BIT(23)
+#define IRQ_SRC_C2 BIT(22)
+#define CPU_CLOCK_ON_LPM BIT(14)
+#define A53_CLK_ON_LPM BIT(14)
+#define MASTER0_LPM_HSK BIT(6)
+#define MASTER1_LPM_HSK BIT(7)
+#define MASTER2_LPM_HSK BIT(8)
+
+#define L2PGE BIT(31)
+#define EN_L2_WFI_PDN BIT(5)
+#define EN_PLAT_PDN BIT(4)
+
+#define SLPCR_EN_DSM BIT(31)
+#define SLPCR_RBC_EN BIT(30)
+#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17)
+#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16)
+#define SLPCR_VSTBY BIT(2)
+#define SLPCR_SBYOS BIT(1)
+#define SLPCR_BYPASS_PMIC_READY BIT(0)
+#define SLPCR_RBC_COUNT_SHIFT 24
+#define SLPCR_STBY_COUNT_SHFT 3
+
+#define A53_DUMMY_PDN_ACK BIT(15)
+#define A53_DUMMY_PUP_ACK BIT(31)
+#define A53_PLAT_PDN_ACK BIT(2)
+#define A53_PLAT_PUP_ACK BIT(18)
+#define NOC_PDN_SLT_CTRL BIT(10)
+#define NOC_PUP_SLT_CTRL BIT(11)
+#define NOC_PGC_PDN_ACK BIT(3)
+#define NOC_PGC_PUP_ACK BIT(19)
+
+#define DDRMIX_PWR_REQ BIT(5)
+#define DDRMIX_ADB400_SYNC BIT(1)
+#define DDRMIX_ADB400_ACK BIT(18)
+#define DDRMIX_PGC 0xd40
+
+#define PLAT_PUP_SLT_CTRL BIT(9)
+#define PLAT_PDN_SLT_CTRL BIT(8)
+
+#define SLT_PLAT_PDN BIT(8)
+#define SLT_PLAT_PUP BIT(9)
+
+#define MASTER1_MAPPING BIT(1)
+#define MASTER2_MAPPING BIT(2)
+
+#define IRQ_IMR_NUM U(4)
+
+#endif /* GPC_REG_H */
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 80ebe4062..546101043 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,11 +8,10 @@ PLAT_INCLUDES := -Iplat/imx/common/include \
-Iplat/imx/imx8m/include \
-Iplat/imx/imx8m/imx8mq/include
-IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \
- drivers/arm/gic/v3/arm_gicv3_common.c \
- drivers/arm/gic/v3/gic500.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/common/gic_common.c \
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+IMX_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
plat/imx/common/plat_imx8_gic.c
diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h
index 139132c40..075da91b1 100644
--- a/plat/imx/imx8m/include/gpc.h
+++ b/plat/imx/imx8m/include/gpc.h
@@ -7,69 +7,7 @@
#ifndef IMX8M_GPC_H
#define IMX8M_GPC_H
-#define LPCR_A53_BSC 0x0
-#define LPCR_A53_BSC2 0x108
-#define LPCR_A53_AD 0x4
-#define LPCR_M4 0x8
-#define SLPCR 0x14
-#define MST_CPU_MAPPING 0x18
-#define MLPCR 0x20
-#define PGC_ACK_SEL_A53 0x24
-#define IMR1_CORE0_A53 0x30
-#define IMR1_CORE1_A53 0x40
-#define IMR1_CORE2_A53 0x1C0
-#define IMR1_CORE3_A53 0x1D0
-#define IMR1_CORE0_M4 0x50
-#define SLT0_CFG 0xB0
-#define GPC_PU_PWRHSK 0x1FC
-#define PGC_CPU_0_1_MAPPING 0xEC
-#define CPU_PGC_UP_TRG 0xF0
-#define PU_PGC_UP_TRG 0xF8
-#define CPU_PGC_DN_TRG 0xFC
-#define PU_PGC_DN_TRG 0x104
-#define A53_CORE0_PGC 0x800
-#define A53_PLAT_PGC 0x900
-#define PLAT_PGC_PCR 0x900
-#define PGC_SCU_TIMING 0x910
-
-#define MASK_DSM_TRIGGER_A53 BIT(31)
-#define IRQ_SRC_A53_WUP BIT(30)
-#define IRQ_SRC_A53_WUP_SHIFT 30
-#define IRQ_SRC_C1 BIT(29)
-#define IRQ_SRC_C0 BIT(28)
-#define IRQ_SRC_C3 BIT(23)
-#define IRQ_SRC_C2 BIT(22)
-#define CPU_CLOCK_ON_LPM BIT(14)
-#define A53_CLK_ON_LPM BIT(14)
-#define MASTER0_LPM_HSK BIT(6)
-
-#define L2PGE BIT(31)
-#define EN_L2_WFI_PDN BIT(5)
-#define EN_PLAT_PDN BIT(4)
-
-#define SLPCR_EN_DSM BIT(31)
-#define SLPCR_RBC_EN BIT(30)
-#define SLPCR_A53_FASTWUP_STOP_MODE BIT(17)
-#define SLPCR_A53_FASTWUP_WAIT_MODE BIT(16)
-#define SLPCR_VSTBY BIT(2)
-#define SLPCR_SBYOS BIT(1)
-#define SLPCR_BYPASS_PMIC_READY BIT(0)
-#define SLPCR_RBC_COUNT_SHIFT 24
-#define SLPCR_STBY_COUNT_SHFT 3
-
-#define A53_DUMMY_PDN_ACK BIT(15)
-#define A53_DUMMY_PUP_ACK BIT(31)
-#define A53_PLAT_PDN_ACK BIT(2)
-#define A53_PLAT_PUP_ACK BIT(18)
-
-#define PLAT_PUP_SLT_CTRL BIT(9)
-#define PLAT_PDN_SLT_CTRL BIT(8)
-
-#define SLT_PLAT_PDN BIT(8)
-#define SLT_PLAT_PUP BIT(9)
-
-#define MASTER1_MAPPING BIT(1)
-#define MASTER2_MAPPING BIT(2)
+#include <gpc_reg.h>
/* helper macro */
#define A53_LPM_MASK U(0xF)
@@ -78,7 +16,7 @@
#define LPM_MODE(local_state) ((local_state) == PLAT_WAIT_RET_STATE ? A53_LPM_WAIT : A53_LPM_STOP)
#define DSM_MODE_MASK BIT(31)
-
+#define CORE_WKUP_FROM_GIC (IRQ_SRC_C0 | IRQ_SRC_C1 | IRQ_SRC_C2 | IRQ_SRC_C3)
#define A53_CORE_WUP_SRC(core_id) (1 << ((core_id) < 2 ? 28 + (core_id) : 22 + (core_id) - 2))
#define COREx_PGC_PCR(core_id) (0x800 + (core_id) * 0x40)
#define COREx_WFI_PDN(core_id) (1 << ((core_id) < 2 ? (core_id) * 2 : ((core_id) - 2) * 2 + 16))
@@ -87,9 +25,37 @@
#define SLTx_CFG(n) ((SLT0_CFG + ((n) * 4)))
#define SLT_COREx_PUP(core_id) (0x2 << ((core_id) * 2))
-#define IRQ_IMR_NUM 4
#define IMR_MASK_ALL 0xffffffff
+#define IMX_PD_DOMAIN(name, on) \
+ { \
+ .pwr_req = name##_PWR_REQ, \
+ .pgc_offset = name##_PGC, \
+ .need_sync = false, \
+ .always_on = true, \
+ }
+
+#define IMX_MIX_DOMAIN(name, on) \
+ { \
+ .pwr_req = name##_PWR_REQ, \
+ .pgc_offset = name##_PGC, \
+ .adb400_sync = name##_ADB400_SYNC, \
+ .adb400_ack = name##_ADB400_ACK, \
+ .need_sync = true, \
+ .always_on = true, \
+ }
+
+struct imx_pwr_domain {
+ uint32_t pwr_req;
+ uint32_t adb400_sync;
+ uint32_t adb400_ack;
+ uint32_t pgc_offset;
+ bool need_sync;
+ bool always_on;
+};
+
+DECLARE_BAKERY_LOCK(gpc_lock);
+
/* function declare */
void imx_gpc_init(void);
void imx_set_cpu_secure_entry(unsigned int core_index, uintptr_t sec_entrypoint);
diff --git a/plat/imx/imx8m/include/imx_rdc.h b/plat/imx/imx8m/include/imx_rdc.h
index 6be8550da..e25b0e6d4 100644
--- a/plat/imx/imx8m/include/imx_rdc.h
+++ b/plat/imx/imx8m/include/imx_rdc.h
@@ -13,9 +13,9 @@
#define MDAn(x) (IMX_RDC_BASE + 0x200 + (x) * 4)
#define PDAPn(x) (IMX_RDC_BASE + 0x400 + (x) * 4)
-#define MRSAn(x) (IMX_RDC_BASE + 0x800 + (x) * 4)
-#define MREAn(x) (IMX_RDC_BASE + 0x804 + (x) * 4)
-#define MRCn(x) (IMX_RDC_BASE + 0x808 + (x) * 4)
+#define MRSAn(x) (IMX_RDC_BASE + 0x800 + (x) * 0x10)
+#define MREAn(x) (IMX_RDC_BASE + 0x804 + (x) * 0x10)
+#define MRCn(x) (IMX_RDC_BASE + 0x808 + (x) * 0x10)
#define LCK BIT(31)
#define SREQ BIT(30)
diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c
index 9232cbc2d..4ca6a5db4 100644
--- a/plat/imx/imx8qm/imx8qm_bl31_setup.c
+++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c
@@ -44,6 +44,22 @@ static entry_point_info_t bl33_image_ep_info;
(SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \
(SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
+#if defined(IMX_USE_UART0)
+#define IMX_RES_UART SC_R_UART_0
+#define IMX_PAD_UART_RX SC_P_UART0_RX
+#define IMX_PAD_UART_TX SC_P_UART0_TX
+#define IMX_PAD_UART_RTS_B SC_P_UART0_RTS_B
+#define IMX_PAD_UART_CTS_B SC_P_UART0_CTS_B
+#elif defined(IMX_USE_UART1)
+#define IMX_RES_UART SC_R_UART_1
+#define IMX_PAD_UART_RX SC_P_UART1_RX
+#define IMX_PAD_UART_TX SC_P_UART1_TX
+#define IMX_PAD_UART_RTS_B SC_P_UART1_RTS_B
+#define IMX_PAD_UART_CTS_B SC_P_UART1_CTS_B
+#else
+#error "Provide proper UART number in IMX_DEBUG_UART"
+#endif
+
const static int imx8qm_cci_map[] = {
CLUSTER0_CCI_SLVAE_IFACE,
CLUSTER1_CCI_SLVAE_IFACE
@@ -79,7 +95,7 @@ static void lpuart32_serial_setbrg(unsigned int base, int baudrate)
if (baudrate == 0)
panic();
- sc_pm_get_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate);
+ sc_pm_get_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate);
baud_diff = baudrate;
osr = 0;
@@ -295,22 +311,23 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
#if DEBUG_CONSOLE
- static console_lpuart_t console;
+ static console_t console;
#endif
if (sc_ipc_open(&ipc_handle, SC_IPC_BASE) != SC_ERR_NONE)
panic();
#if DEBUG_CONSOLE_A53
- sc_pm_set_resource_power_mode(ipc_handle, SC_R_UART_0, SC_PM_PW_MODE_ON);
+ sc_pm_set_resource_power_mode(ipc_handle, IMX_RES_UART,
+ SC_PM_PW_MODE_ON);
sc_pm_clock_rate_t rate = 80000000;
- sc_pm_set_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate);
- sc_pm_clock_enable(ipc_handle, SC_R_UART_0, 2, true, false);
+ sc_pm_set_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate);
+ sc_pm_clock_enable(ipc_handle, IMX_RES_UART, 2, true, false);
/* configure UART pads */
- sc_pad_set(ipc_handle, SC_P_UART0_RX, UART_PAD_CTRL);
- sc_pad_set(ipc_handle, SC_P_UART0_TX, UART_PAD_CTRL);
- sc_pad_set(ipc_handle, SC_P_UART0_RTS_B, UART_PAD_CTRL);
- sc_pad_set(ipc_handle, SC_P_UART0_CTS_B, UART_PAD_CTRL);
+ sc_pad_set(ipc_handle, IMX_PAD_UART_RX, UART_PAD_CTRL);
+ sc_pad_set(ipc_handle, IMX_PAD_UART_TX, UART_PAD_CTRL);
+ sc_pad_set(ipc_handle, IMX_PAD_UART_RTS_B, UART_PAD_CTRL);
+ sc_pad_set(ipc_handle, IMX_PAD_UART_CTS_B, UART_PAD_CTRL);
lpuart32_serial_init(IMX_BOOT_UART_BASE);
#endif
diff --git a/plat/imx/imx8qm/include/platform_def.h b/plat/imx/imx8qm/include/platform_def.h
index b54943da0..671c77f76 100644
--- a/plat/imx/imx8qm/include/platform_def.h
+++ b/plat/imx/imx8qm/include/platform_def.h
@@ -40,12 +40,22 @@
#define PLAT_CCI_BASE 0x52090000
#define CLUSTER0_CCI_SLVAE_IFACE 3
#define CLUSTER1_CCI_SLVAE_IFACE 4
+
+/* UART */
+#if defined(IMX_USE_UART0)
#define IMX_BOOT_UART_BASE 0x5a060000
+#elif defined(IMX_USE_UART1)
+#define IMX_BOOT_UART_BASE 0x5a070000
+#else
+#error "Provide proper UART number in IMX_DEBUG_UART"
+#endif
+
#define IMX_BOOT_UART_BAUDRATE 115200
#define IMX_BOOT_UART_CLK_IN_HZ 24000000
#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
#define PLAT__CRASH_UART_CLK_IN_HZ 24000000
#define IMX_CONSOLE_BAUDRATE 115200
+
#define SC_IPC_BASE 0x5d1b0000
#define IMX_GPT_LPCG_BASE 0x5d540000
#define IMX_GPT_BASE 0x5d140000
@@ -64,7 +74,6 @@
#define MAX_XLAT_TABLES 8
#define MAX_MMAP_REGIONS 12
-#define DEBUG_CONSOLE 0
-#define DEBUG_CONSOLE_A53 0
+#define DEBUG_CONSOLE_A53 DEBUG_CONSOLE
#endif /* PLATFORM_DEF_H */
diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk
index 3a772e51a..f35fa0020 100644
--- a/plat/imx/imx8qm/platform.mk
+++ b/plat/imx/imx8qm/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -7,11 +7,10 @@
PLAT_INCLUDES := -Iplat/imx/imx8qm/include \
-Iplat/imx/common/include \
-IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \
- drivers/arm/gic/v3/arm_gicv3_common.c \
- drivers/arm/gic/v3/gic500.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/common/gic_common.c \
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+IMX_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
plat/imx/common/plat_imx8_gic.c
@@ -41,3 +40,9 @@ ERRATA_A72_859971 := 1
ERRATA_A53_835769 := 1
ERRATA_A53_843419 := 1
ERRATA_A53_855873 := 1
+
+IMX_DEBUG_UART ?= 0
+$(eval $(call add_define,IMX_USE_UART${IMX_DEBUG_UART}))
+
+DEBUG_CONSOLE ?= 0
+$(eval $(call add_define,DEBUG_CONSOLE))
diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c
index 58c82ce60..3ff540017 100644
--- a/plat/imx/imx8qx/imx8qx_bl31_setup.c
+++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c
@@ -38,11 +38,43 @@ IMPORT_SYM(unsigned long, __RW_START__, BL31_RW_START);
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
+/* Default configuration for i.MX8QM/QXP MEK */
+#if defined(IMX_USE_UART0)
#define UART_PAD_CTRL (PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \
(SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \
(SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
(SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \
(SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
+#define IMX_RES_UART SC_R_UART_0
+#define IMX_PAD_UART_RX SC_P_UART0_RX
+#define IMX_PAD_UART_TX SC_P_UART0_TX
+
+/*
+ * On Toradex Colibri i.MX8QXP UART3 on the FLEXCAN2.
+ * Use custom pad control for this
+ */
+#elif defined(IMX_USE_UART3)
+/*
+ * FLEXCAN2_RX/TX pads are muxed to ADMA_UART3_RX/TX,
+ * For ref:
+ * 000b - ADMA_FLEXCAN2_RX
+ * 001b - ADMA_SAI3_RXD
+ * 010b - ADMA_UART3_RX
+ * 011b - ADMA_SAI1_RXFS
+ * 100b - LSIO_GPIO1_IO19
+ */
+#define UART_PAD_CTRL (PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \
+ (SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \
+ (2U << PADRING_IFMUX_SHIFT) | \
+ (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
+ (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \
+ (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
+#define IMX_RES_UART SC_R_UART_3
+#define IMX_PAD_UART_RX SC_P_FLEXCAN2_RX
+#define IMX_PAD_UART_TX SC_P_FLEXCAN2_TX
+#else
+#error "Provide proper UART configuration in IMX_DEBUG_UART"
+#endif
static const mmap_region_t imx_mmap[] = {
MAP_REGION_FLAT(IMX_REG_BASE, IMX_REG_SIZE, MT_DEVICE | MT_RW),
@@ -74,7 +106,7 @@ static void lpuart32_serial_setbrg(unsigned int base, int baudrate)
if (baudrate == 0)
panic();
- sc_pm_get_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate);
+ sc_pm_get_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate);
baud_diff = baudrate;
osr = 0;
@@ -255,20 +287,21 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
#if DEBUG_CONSOLE
- static console_lpuart_t console;
+ static console_t console;
#endif
if (sc_ipc_open(&ipc_handle, SC_IPC_BASE) != SC_ERR_NONE)
panic();
#if DEBUG_CONSOLE_A35
- sc_pm_set_resource_power_mode(ipc_handle, SC_R_UART_0, SC_PM_PW_MODE_ON);
+ sc_pm_set_resource_power_mode(ipc_handle, IMX_RES_UART,
+ SC_PM_PW_MODE_ON);
sc_pm_clock_rate_t rate = 80000000;
- sc_pm_set_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate);
- sc_pm_clock_enable(ipc_handle, SC_R_UART_0, 2, true, false);
+ sc_pm_set_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate);
+ sc_pm_clock_enable(ipc_handle, IMX_RES_UART, 2, true, false);
/* Configure UART pads */
- sc_pad_set(ipc_handle, SC_P_UART0_RX, UART_PAD_CTRL);
- sc_pad_set(ipc_handle, SC_P_UART0_TX, UART_PAD_CTRL);
+ sc_pad_set(ipc_handle, IMX_PAD_UART_RX, UART_PAD_CTRL);
+ sc_pad_set(ipc_handle, IMX_PAD_UART_TX, UART_PAD_CTRL);
lpuart32_serial_init(IMX_BOOT_UART_BASE);
#endif
diff --git a/plat/imx/imx8qx/include/platform_def.h b/plat/imx/imx8qx/include/platform_def.h
index 41475ffeb..b880e1bc7 100644
--- a/plat/imx/imx8qx/include/platform_def.h
+++ b/plat/imx/imx8qx/include/platform_def.h
@@ -38,7 +38,15 @@
#define PLAT_GICD_BASE 0x51a00000
#define PLAT_GICR_BASE 0x51b00000
+
+#if defined(IMX_USE_UART0)
#define IMX_BOOT_UART_BASE 0x5a060000
+#elif defined(IMX_USE_UART3)
+#define IMX_BOOT_UART_BASE 0x5a090000
+#else
+#error "Provide proper UART configuration in IMX_DEBUG_UART"
+#endif
+
#define IMX_BOOT_UART_BAUDRATE 115200
#define IMX_BOOT_UART_CLK_IN_HZ 24000000
#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
@@ -55,8 +63,6 @@
/* non-secure u-boot base */
#define PLAT_NS_IMAGE_OFFSET 0x80020000
-
-#define DEBUG_CONSOLE 0
-#define DEBUG_CONSOLE_A35 0
+#define DEBUG_CONSOLE_A35 DEBUG_CONSOLE
#endif /* PLATFORM_DEF_H */
diff --git a/plat/imx/imx8qx/platform.mk b/plat/imx/imx8qx/platform.mk
index d5629d124..b25be0742 100644
--- a/plat/imx/imx8qx/platform.mk
+++ b/plat/imx/imx8qx/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -7,11 +7,10 @@
PLAT_INCLUDES := -Iplat/imx/imx8qx/include \
-Iplat/imx/common/include \
-IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \
- drivers/arm/gic/v3/arm_gicv3_common.c \
- drivers/arm/gic/v3/gic500.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/common/gic_common.c \
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+IMX_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
plat/imx/common/plat_imx8_gic.c
@@ -33,3 +32,9 @@ include plat/imx/common/sci/sci_api.mk
USE_COHERENT_MEM := 1
RESET_TO_BL31 := 1
+
+IMX_DEBUG_UART ?= 0
+$(eval $(call add_define,IMX_USE_UART${IMX_DEBUG_UART}))
+
+DEBUG_CONSOLE ?= 0
+$(eval $(call add_define,DEBUG_CONSOLE))
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 9587d4859..f00294706 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,11 +15,13 @@
#include <drivers/ti/uart/uart_16550.h>
#include <lib/xlat_tables/xlat_tables.h>
+#include "agilex_mmc.h"
#include "agilex_clock_manager.h"
#include "agilex_memory_controller.h"
#include "agilex_pinmux.h"
#include "ccu/ncore_ccu.h"
#include "qspi/cadence_qspi.h"
+#include "socfpga_emac.h"
#include "socfpga_handoff.h"
#include "socfpga_mailbox.h"
#include "socfpga_private.h"
@@ -46,12 +48,12 @@ const mmap_region_t agilex_plat_mmap[] = {
{0},
};
-boot_source_type boot_source;
+boot_source_type boot_source = BOOT_SOURCE;
void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
u_register_t x2, u_register_t x4)
{
- static console_16550_t console;
+ static console_t console;
handoff reverse_handoff_ptr;
generic_delay_timer_init();
@@ -59,7 +61,6 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
if (socfpga_get_handoff(&reverse_handoff_ptr))
return;
config_pinmux(&reverse_handoff_ptr);
- boot_source = reverse_handoff_ptr.boot_source;
config_clkmgr_handoff(&reverse_handoff_ptr);
enable_nonsecure_access();
@@ -73,8 +74,10 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
socfpga_delay_timer_init();
init_ncore_ccu();
+ socfpga_emac_init();
init_hard_memory_controller();
mailbox_init();
+ agx_mmc_init();
if (!intel_mailbox_is_fpga_not_ready())
socfpga_bridges_enable();
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index 375483dd4..168236b64 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,8 +11,11 @@
#include <common/bl_common.h>
#include <drivers/arm/gicv2.h>
#include <drivers/ti/uart/uart_16550.h>
+#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables.h>
+#include "socfpga_mailbox.h"
+#include "socfpga_private.h"
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
@@ -34,7 +37,9 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_16550_t console;
+ static console_t console;
+
+ mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
&console);
@@ -44,23 +49,33 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
void *from_bl2 = (void *) arg0;
bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
-
assert(params_from_bl2 != NULL);
- assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
- assert(params_from_bl2->h.version >= VERSION_2);
/*
* Copy BL32 (if populated by BL31) and BL33 entry point information.
* They are stored in Secure RAM, in BL31's address space.
*/
- bl_params_node_t *bl_params = params_from_bl2->head;
+ if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
+ params_from_bl2->h.version >= VERSION_2) {
+
+ bl_params_node_t *bl_params = params_from_bl2->head;
+
+ while (bl_params) {
+ if (bl_params->image_id == BL33_IMAGE_ID)
+ bl33_image_ep_info = *bl_params->ep_info;
- while (bl_params) {
- if (bl_params->image_id == BL33_IMAGE_ID)
- bl33_image_ep_info = *bl_params->ep_info;
+ bl_params = bl_params->next_params_info;
+ }
+ } else {
+ struct socfpga_bl31_params *arg_from_bl2 =
+ (struct socfpga_bl31_params *) from_bl2;
- bl_params = bl_params->next_params_info;
+ assert(arg_from_bl2->h.type == PARAM_BL31);
+ assert(arg_from_bl2->h.version >= VERSION_1);
+
+ bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
+ bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
}
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
}
@@ -86,11 +101,19 @@ static const gicv2_driver_data_t plat_gicv2_gic_data = {
******************************************************************************/
void bl31_platform_setup(void)
{
+ socfpga_delay_timer_init();
+
/* Initialize the gic cpu and distributor interfaces */
gicv2_driver_init(&plat_gicv2_gic_data);
gicv2_distif_init();
gicv2_pcpu_distif_init();
gicv2_cpuif_enable();
+
+ /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */
+ mmio_write_64(PLAT_CPU_RELEASE_ADDR,
+ (uint64_t)plat_secondary_cpus_bl31_entry);
+
+ mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
}
const mmap_region_t plat_agilex_mmap[] = {
diff --git a/plat/intel/soc/agilex/include/agilex_clock_manager.h b/plat/intel/soc/agilex/include/agilex_clock_manager.h
index 8af6a60bc..20667f014 100644
--- a/plat/intel/soc/agilex/include/agilex_clock_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_clock_manager.h
@@ -89,6 +89,7 @@
/* Peripheral PLL Macros */
#define CLKMGR_PERPLL_EN_RESET 0x00000fff
+#define CLKMGR_PERPLL_EN_SDMMCCLK BIT(5)
#define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x) (((x) << 0) & 0x0000ffff)
/* Altera Macros */
diff --git a/plat/intel/soc/agilex/include/agilex_mmc.h b/plat/intel/soc/agilex/include/agilex_mmc.h
new file mode 100644
index 000000000..00f4ca5a8
--- /dev/null
+++ b/plat/intel/soc/agilex/include/agilex_mmc.h
@@ -0,0 +1,7 @@
+/*
+ * Copyright (c) 2020, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+void agx_mmc_init(void);
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index b4e09210f..6c9d81ceb 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -12,6 +12,7 @@
/* Platform Setting */
#define PLATFORM_MODEL PLAT_SOCFPGA_AGILEX
+#define BOOT_SOURCE BOOT_SOURCE_SDMMC
/* Register Mapping */
#define SOCFPGA_MMC_REG_BASE 0xff808000
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index f47c3f113..bf5cc1445 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -1,6 +1,6 @@
#
-# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -10,18 +10,23 @@ PLAT_INCLUDES := \
-Iplat/intel/soc/common/drivers/ \
-Iplat/intel/soc/common/include/
+# Include GICv2 driver files
+include drivers/arm/gic/v2/gicv2.mk
+AGX_GICv2_SOURCES := \
+ ${GICV2_SOURCES} \
+ plat/common/plat_gicv2.c
+
+
PLAT_BL_COMMON_SOURCES := \
- drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
+ ${AGX_GICv2_SOURCES} \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
drivers/ti/uart/aarch64/16550_console.S \
lib/xlat_tables/aarch64/xlat_tables.c \
lib/xlat_tables/xlat_tables_common.c \
- plat/common/plat_gicv2.c \
plat/intel/soc/common/aarch64/platform_common.c \
- plat/intel/soc/common/aarch64/plat_helpers.S
+ plat/intel/soc/common/aarch64/plat_helpers.S \
+ plat/intel/soc/common/socfpga_delay_timer.c
BL2_SOURCES += \
common/desc_image_load.c \
@@ -37,11 +42,12 @@ BL2_SOURCES += \
plat/intel/soc/agilex/bl2_plat_setup.c \
plat/intel/soc/agilex/soc/agilex_clock_manager.c \
plat/intel/soc/agilex/soc/agilex_memory_controller.c \
+ plat/intel/soc/agilex/soc/agilex_mmc.c \
plat/intel/soc/agilex/soc/agilex_pinmux.c \
plat/intel/soc/common/bl2_plat_mem_params_desc.c \
- plat/intel/soc/common/socfpga_delay_timer.c \
plat/intel/soc/common/socfpga_image_load.c \
plat/intel/soc/common/socfpga_storage.c \
+ plat/intel/soc/common/soc/socfpga_emac.c \
plat/intel/soc/common/soc/socfpga_handoff.c \
plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c \
diff --git a/plat/intel/soc/agilex/soc/agilex_clock_manager.c b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
index c6c48baea..4efd7131d 100644
--- a/plat/intel/soc/agilex/soc/agilex_clock_manager.c
+++ b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
@@ -47,14 +47,14 @@ uint32_t wait_fsm(void)
return 0;
}
-uint32_t pll_source_sync_config(uint32_t pll_mem_offset)
+uint32_t pll_source_sync_config(uint32_t pll_mem_offset, uint32_t data)
{
uint32_t val = 0;
uint32_t count = 0;
uint32_t req_status = 0;
val = (CLKMGR_MEM_WR | CLKMGR_MEM_REQ |
- CLKMGR_MEM_WDAT << CLKMGR_MEM_WDAT_OFFSET | CLKMGR_MEM_ADDR);
+ (data << CLKMGR_MEM_WDAT_OFFSET) | CLKMGR_MEM_ADDR);
mmio_write_32(pll_mem_offset, val);
do {
@@ -89,14 +89,17 @@ uint32_t pll_source_sync_read(uint32_t pll_mem_offset)
rdata = mmio_read_32(pll_mem_offset + 0x4);
INFO("rdata (%x) = %x\n", pll_mem_offset + 0x4, rdata);
- return 0;
+ return rdata;
}
void config_clkmgr_handoff(handoff *hoff_ptr)
{
uint32_t mdiv, mscnt, hscnt;
- uint32_t arefclk_div, drefclk_div;
+ uint32_t drefclk_div, refclk_div, rdata;
+ /* Set clock maanger into boot mode before running configuration */
+ mmio_setbits_32(CLKMGR_OFFSET + CLKMGR_CTRL,
+ CLKMGR_CTRL_BOOTMODE_SET_MSK);
/* Bypass all mainpllgrp's clocks */
mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASS, 0x7);
wait_fsm();
@@ -116,26 +119,24 @@ void config_clkmgr_handoff(handoff *hoff_ptr)
/* Setup main PLL dividers */
mdiv = CLKMGR_PLLM_MDIV(hoff_ptr->main_pll_pllm);
- arefclk_div = CLKMGR_PLLGLOB_AREFCLKDIV(
- hoff_ptr->main_pll_pllglob);
drefclk_div = CLKMGR_PLLGLOB_DREFCLKDIV(
hoff_ptr->main_pll_pllglob);
+ refclk_div = CLKMGR_PLLGLOB_REFCLKDIV(
+ hoff_ptr->main_pll_pllglob);
- mscnt = 100 / (mdiv / BIT(drefclk_div));
+ mscnt = 100 / (mdiv * BIT(drefclk_div));
if (!mscnt)
mscnt = 1;
- hscnt = (mdiv * mscnt * BIT(drefclk_div) / arefclk_div) - 4;
+ hscnt = (mdiv * mscnt * BIT(drefclk_div) / refclk_div) - 4;
- mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_VCOCALIB,
- CLKMGR_VCOCALIB_HSCNT_SET(hscnt) |
- CLKMGR_VCOCALIB_MSCNT_SET(mscnt));
-
- mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV,
- hoff_ptr->main_pll_nocdiv);
mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
- hoff_ptr->main_pll_pllglob);
+ hoff_ptr->main_pll_pllglob &
+ ~CLKMGR_PLLGLOB_RST_SET_MSK);
mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_FDBCK,
hoff_ptr->main_pll_fdbck);
+ mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_VCOCALIB,
+ CLKMGR_VCOCALIB_HSCNT_SET(hscnt) |
+ CLKMGR_VCOCALIB_MSCNT_SET(mscnt));
mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLC0,
hoff_ptr->main_pll_pllc0);
mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLC1,
@@ -150,33 +151,33 @@ void config_clkmgr_handoff(handoff *hoff_ptr)
hoff_ptr->main_pll_mpuclk);
mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCCLK,
hoff_ptr->main_pll_nocclk);
+ mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV,
+ hoff_ptr->main_pll_nocdiv);
/* Setup peripheral PLL dividers */
mdiv = CLKMGR_PLLM_MDIV(hoff_ptr->per_pll_pllm);
- arefclk_div = CLKMGR_PLLGLOB_AREFCLKDIV(
- hoff_ptr->per_pll_pllglob);
drefclk_div = CLKMGR_PLLGLOB_DREFCLKDIV(
hoff_ptr->per_pll_pllglob);
+ refclk_div = CLKMGR_PLLGLOB_REFCLKDIV(
+ hoff_ptr->per_pll_pllglob);
- mscnt = 100 / (mdiv / BIT(drefclk_div));
+
+ mscnt = 100 / (mdiv * BIT(drefclk_div));
if (!mscnt)
mscnt = 1;
- hscnt = (mdiv * mscnt * BIT(drefclk_div) / arefclk_div) - 4;
+ hscnt = (mdiv * mscnt * BIT(drefclk_div) / refclk_div) - 4;
+
+ mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
+ hoff_ptr->per_pll_pllglob &
+ ~CLKMGR_PLLGLOB_RST_SET_MSK);
+ mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_FDBCK,
+ hoff_ptr->per_pll_fdbck);
mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_VCOCALIB,
CLKMGR_VCOCALIB_HSCNT_SET(hscnt) |
CLKMGR_VCOCALIB_MSCNT_SET(mscnt));
- mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EMACCTL,
- hoff_ptr->per_pll_emacctl);
- mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_GPIODIV,
- CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(
- hoff_ptr->per_pll_gpiodiv));
- mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
- hoff_ptr->per_pll_pllglob);
- mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_FDBCK,
- hoff_ptr->per_pll_fdbck);
mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLC0,
hoff_ptr->per_pll_pllc0);
mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLC1,
@@ -187,6 +188,10 @@ void config_clkmgr_handoff(handoff *hoff_ptr)
hoff_ptr->per_pll_pllc3);
mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLM,
hoff_ptr->per_pll_pllm);
+ mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EMACCTL,
+ hoff_ptr->per_pll_emacctl);
+ mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_GPIODIV,
+ hoff_ptr->per_pll_gpiodiv);
/* Take both PLL out of reset and power up */
mmio_setbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
@@ -196,13 +201,16 @@ void config_clkmgr_handoff(handoff *hoff_ptr)
CLKMGR_PLLGLOB_PD_SET_MSK |
CLKMGR_PLLGLOB_RST_SET_MSK);
- wait_pll_lock();
+ rdata = pll_source_sync_read(CLKMGR_MAINPLL +
+ CLKMGR_MAINPLL_MEM);
+ pll_source_sync_config(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM,
+ rdata | 0x80);
- pll_source_sync_config(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM);
- pll_source_sync_read(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM);
+ rdata = pll_source_sync_read(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM);
+ pll_source_sync_config(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM,
+ rdata | 0x80);
- pll_source_sync_config(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM);
- pll_source_sync_read(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM);
+ wait_pll_lock();
/*Configure Ping Pong counters in altera group */
mmio_write_32(CLKMGR_ALTERA + CLKMGR_ALTERA_EMACACTR,
@@ -241,7 +249,7 @@ void config_clkmgr_handoff(handoff *hoff_ptr)
/* Clear loss lock interrupt status register that */
/* might be set during configuration */
- mmio_setbits_32(CLKMGR_OFFSET + CLKMGR_INTRCLR,
+ mmio_clrbits_32(CLKMGR_OFFSET + CLKMGR_INTRCLR,
CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK |
CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK);
diff --git a/plat/intel/soc/agilex/soc/agilex_mmc.c b/plat/intel/soc/agilex/soc/agilex_mmc.c
new file mode 100644
index 000000000..e05d92a03
--- /dev/null
+++ b/plat/intel/soc/agilex/soc/agilex_mmc.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2020, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/mmio.h>
+
+#include "socfpga_system_manager.h"
+#include "agilex_clock_manager.h"
+
+void agx_mmc_init(void)
+{
+ mmio_clrbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
+ CLKMGR_PERPLL_EN_SDMMCCLK);
+ mmio_write_32(SOCFPGA_SYSMGR(SDMMC),
+ SYSMGR_SDMMC_SMPLSEL(0) | SYSMGR_SDMMC_DRVSEL(3));
+ mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
+ CLKMGR_PERPLL_EN_SDMMCCLK);
+}
diff --git a/plat/intel/soc/agilex/soc/agilex_pinmux.c b/plat/intel/soc/agilex/soc/agilex_pinmux.c
index eff19473c..0b908cfa3 100644
--- a/plat/intel/soc/agilex/soc/agilex_pinmux.c
+++ b/plat/intel/soc/agilex/soc/agilex_pinmux.c
@@ -7,6 +7,7 @@
#include <lib/mmio.h>
#include "agilex_pinmux.h"
+#include "socfpga_system_manager.h"
const uint32_t sysmgr_pinmux_array_sel[] = {
0x00000000, 0x00000001, /* usb */
@@ -185,6 +186,12 @@ const uint32_t sysmgr_pinmux_array_iodelay[] = {
0x0000011c, 0x00000000
};
+void config_fpgaintf_mod(void)
+{
+ mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), 1<<8);
+}
+
+
void config_pinmux(handoff *hoff_ptr)
{
unsigned int i;
@@ -213,5 +220,6 @@ void config_pinmux(handoff *hoff_ptr)
hoff_ptr->pinmux_iodelay_array[i+1]);
}
+ config_fpgaintf_mod();
}
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index fce816b65..b4fce7b40 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -35,14 +35,12 @@ uint32_t directory_init(void)
uint32_t dir, sf, ret;
for (dir = 0; dir < subsystem_id.num_directory; dir++) {
-
- dir_sf_mtn = DIRECTORY_UNIT(dir, NCORE_DIRUSFMCR);
- dir_sf_en = DIRECTORY_UNIT(dir, NCORE_DIRUSFER);
-
for (sf = 0; sf < subsystem_id.num_snoop_filter; sf++) {
+ dir_sf_mtn = DIRECTORY_UNIT(dir, NCORE_DIRUSFMCR);
+ dir_sf_en = DIRECTORY_UNIT(dir, NCORE_DIRUSFER);
/* Initialize All Entries */
- mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(sf));
+ mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(dir));
/* Poll Active Bit */
ret = poll_active_bit(dir);
@@ -52,7 +50,7 @@ uint32_t directory_init(void)
}
/* Snoope Filter Enable */
- mmio_write_32(dir_sf_en, BIT(sf));
+ mmio_setbits_32(dir_sf_en, BIT(sf));
}
}
@@ -64,11 +62,8 @@ uint32_t coherent_agent_intfc_init(void)
uint32_t dir, ca, ca_id, ca_type, ca_snoop_en;
for (dir = 0; dir < subsystem_id.num_directory; dir++) {
-
- ca_snoop_en = DIRECTORY_UNIT(dir, NCORE_DIRUCASER0);
-
for (ca = 0; ca < subsystem_id.num_coh_agent; ca++) {
-
+ ca_snoop_en = DIRECTORY_UNIT(ca, NCORE_DIRUCASER0);
ca_id = mmio_read_32(COH_AGENT_UNIT(ca, NCORE_CAIUIDR));
/* Coh Agent Snoop Enable */
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 8a681e69d..55600ee69 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -134,6 +134,8 @@
#define PLAT_CPUID_RELEASE (BL_DATA_LIMIT - 16)
#define PLAT_SEC_ENTRY (BL_DATA_LIMIT - 8)
+#define PLAT_SEC_WARM_ENTRY 0
+
/*******************************************************************************
* Platform specific page table and MMU setup constants
******************************************************************************/
@@ -169,6 +171,14 @@
#define PLAT_UART_CLOCK (100000000)
/*******************************************************************************
+ * PHY related constants
+ ******************************************************************************/
+
+#define EMAC0_PHY_MODE PHY_INTERFACE_MODE_RGMII
+#define EMAC1_PHY_MODE PHY_INTERFACE_MODE_RGMII
+#define EMAC2_PHY_MODE PHY_INTERFACE_MODE_RGMII
+
+/*******************************************************************************
* System counter frequency related constants
******************************************************************************/
#define PLAT_SYS_COUNTER_FREQ_IN_TICKS (400000000)
diff --git a/plat/intel/soc/common/include/socfpga_emac.h b/plat/intel/soc/common/include/socfpga_emac.h
new file mode 100644
index 000000000..5b98006a3
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_emac.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_EMAC_H
+#define SOCFPGA_EMAC_H
+
+/* EMAC PHY Mode */
+
+#define PHY_INTERFACE_MODE_GMII_MII 0
+#define PHY_INTERFACE_MODE_RGMII 1
+#define PHY_INTERFACE_MODE_RMII 2
+#define PHY_INTERFACE_MODE_RESET 3
+
+/* Mask Definitions */
+
+#define PHY_INTF_SEL_MSK 0x3
+#define FPGAINTF_EN_3_EMAC_MSK(x) (1 << (x * 8))
+
+void socfpga_emac_init(void);
+
+#endif /* SOCFPGA_EMAC_H */
diff --git a/plat/intel/soc/common/include/socfpga_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h
index 889d13767..ba0f7f377 100644
--- a/plat/intel/soc/common/include/socfpga_handoff.h
+++ b/plat/intel/soc/common/include/socfpga_handoff.h
@@ -125,7 +125,6 @@ typedef struct handoff_t {
uint32_t misc_magic;
uint32_t misc_length;
uint32_t _pad_0x618_0x620[2];
- uint32_t boot_source;
} handoff;
int verify_handoff_image(handoff *hoff_ptr, handoff *reverse_hoff_ptr);
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index c4b9e5967..923c4f154 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,35 +9,16 @@
#include <lib/utils_def.h>
-#define MBOX_OFFSET 0xffa30000
-#define MBOX_MAX_JOB_ID 0xf
-#define MBOX_ATF_CLIENT_ID 0x1
-#define MBOX_JOB_ID 0x1
+#define MBOX_OFFSET 0xffa30000
-/* Mailbox interrupt flags and masks */
-#define MBOX_INT_FLAG_COE 0x1
-#define MBOX_INT_FLAG_RIE 0x2
-#define MBOX_INT_FLAG_UAE 0x100
-#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3)
-#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<8)))
+#define MBOX_ATF_CLIENT_ID 0x1U
+#define MBOX_MAX_JOB_ID 0xFU
+#define MBOX_MAX_IND_JOB_ID (MBOX_MAX_JOB_ID - 1U)
+#define MBOX_JOB_ID MBOX_MAX_JOB_ID
-/* Mailbox response and status */
-#define MBOX_RESP_BUFFER_SIZE 16
-#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x00000fff)
-#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12)
-#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28)
-#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24)
-#define MBOX_STATUS_UA_MASK (1<<8)
-/* Mailbox command and response */
-#define MBOX_CMD_FREE_OFFSET 0x14
-#define MBOX_CMD_BUFFER_SIZE 32
-#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28)
-#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24)
-#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12)
-#define MBOX_INDIRECT (1 << 11)
-#define MBOX_INSUFFICIENT_BUFFER -2
+/* Mailbox Shared Memory Register Map */
#define MBOX_CIN 0x00
#define MBOX_ROUT 0x04
#define MBOX_URG 0x08
@@ -48,37 +29,63 @@
#define MBOX_CMD_BUFFER 0x40
#define MBOX_RESP_BUFFER 0xC0
-#define MBOX_RESP_BUFFER_SIZE 16
-#define MBOX_RESP_OK 0
-#define MBOX_RESP_INVALID_CMD 1
-#define MBOX_RESP_UNKNOWN_BR 2
-#define MBOX_RESP_UNKNOWN 3
-#define MBOX_RESP_NOT_CONFIGURED 256
-
/* Mailbox SDM doorbell */
#define MBOX_DOORBELL_TO_SDM 0x400
#define MBOX_DOORBELL_FROM_SDM 0x480
-/* Mailbox QSPI commands */
-#define MBOX_CMD_RESTART 2
-#define MBOX_CMD_QSPI_OPEN 50
-#define MBOX_CMD_QSPI_CLOSE 51
-#define MBOX_CMD_QSPI_DIRECT 59
-#define MBOX_CMD_GET_IDCODE 16
-#define MBOX_CMD_QSPI_SET_CS 52
-/* Mailbox CANCEL command */
-#define MBOX_CMD_CANCEL 0x3
+/* Mailbox commands */
-/* Mailbox REBOOT commands */
-#define MBOX_CMD_REBOOT_HPS 71
+#define MBOX_CMD_NOOP 0x00
+#define MBOX_CMD_SYNC 0x01
+#define MBOX_CMD_RESTART 0x02
+#define MBOX_CMD_CANCEL 0x03
+#define MBOX_CMD_GET_IDCODE 0x10
+#define MBOX_CMD_REBOOT_HPS 0x47
-/* Generic error handling */
-#define MBOX_TIMEOUT -2047
+/* Reconfiguration Commands */
+#define MBOX_CONFIG_STATUS 0x04
+#define MBOX_RECONFIG 0x06
+#define MBOX_RECONFIG_DATA 0x08
+#define MBOX_RECONFIG_STATUS 0x09
+
+/* QSPI Commands */
+#define MBOX_CMD_QSPI_OPEN 0x32
+#define MBOX_CMD_QSPI_CLOSE 0x33
+#define MBOX_CMD_QSPI_SET_CS 0x34
+#define MBOX_CMD_QSPI_DIRECT 0x3B
+
+/* RSU Commands */
+#define MBOX_GET_SUBPARTITION_TABLE 0x5A
+#define MBOX_RSU_STATUS 0x5B
+#define MBOX_RSU_UPDATE 0x5C
+#define MBOX_HPS_STAGE_NOTIFY 0x5D
+
+
+/* Mailbox Definitions */
+
+#define CMD_DIRECT 0
+#define CMD_INDIRECT 1
+#define CMD_CASUAL 0
+#define CMD_URGENT 1
+
+#define MBOX_RESP_BUFFER_SIZE 16
+#define MBOX_CMD_BUFFER_SIZE 32
+
+/* Execution states for HPS_STAGE_NOTIFY */
+#define HPS_EXECUTION_STATE_FSBL 0
+#define HPS_EXECUTION_STATE_SSBL 1
+#define HPS_EXECUTION_STATE_OS 2
+
+/* Status Response */
+#define MBOX_RET_OK 0
+#define MBOX_RET_ERROR -1
#define MBOX_NO_RESPONSE -2
#define MBOX_WRONG_ID -3
+#define MBOX_BUFFER_FULL -4
+#define MBOX_TIMEOUT -2047
-/* Mailbox status */
+/* Reconfig Status Response */
#define RECONFIG_STATUS_STATE 0
#define RECONFIG_STATUS_PIN_STATUS 2
#define RECONFIG_STATUS_SOFTFUNC_STATUS 3
@@ -98,28 +105,62 @@
#define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO 0xf0000007
#define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR 0xf0000008
-/* Mailbox reconfiguration commands */
-#define MBOX_CONFIG_STATUS 4
-#define MBOX_RECONFIG 6
-#define MBOX_RECONFIG_DATA 8
-#define MBOX_RECONFIG_STATUS 9
+/* Mailbox Macros */
-void mailbox_set_int(int interrupt_input);
+/* Mailbox interrupt flags and masks */
+#define MBOX_INT_FLAG_COE 0x1
+#define MBOX_INT_FLAG_RIE 0x2
+#define MBOX_INT_FLAG_UAE 0x100
+#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3)
+#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<8)))
+
+/* Mailbox response and status */
+#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x00000fff)
+#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12)
+#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28)
+#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24)
+#define MBOX_STATUS_UA_MASK (1<<8)
+
+/* Mailbox command and response */
+#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28)
+#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24)
+#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12)
+#define MBOX_INDIRECT(val) ((val) << 11)
+#define MBOX_CMD_MASK(header) ((header) & 0x7ff)
+
+/* RSU Macros */
+#define RSU_VERSION_ACMF BIT(8)
+#define RSU_VERSION_ACMF_MASK 0xff00
+
+
+/* Mailbox Function Definitions */
+
+void mailbox_set_int(uint32_t interrupt_input);
int mailbox_init(void);
void mailbox_set_qspi_close(void);
void mailbox_set_qspi_open(void);
void mailbox_set_qspi_direct(void);
-int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
- int len, int urgent, uint32_t *response, int resp_len);
-int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
- int len, int urgent);
-int mailbox_read_response(int job_id, uint32_t *response, int resp_len);
-int mailbox_get_qspi_clock(void);
+
+int mailbox_send_cmd(uint32_t job_id, uint32_t cmd, uint32_t *args,
+ unsigned int len, uint32_t urgent, uint32_t *response,
+ unsigned int resp_len);
+int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args,
+ unsigned int len, unsigned int indirect);
+int mailbox_read_response(uint32_t *job_id, uint32_t *response,
+ unsigned int resp_len);
+unsigned int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf,
+ unsigned int resp_len);
+
void mailbox_reset_cold(void);
void mailbox_clear_response(void);
-uint32_t intel_mailbox_get_config_status(uint32_t cmd);
+int intel_mailbox_get_config_status(uint32_t cmd);
int intel_mailbox_is_fpga_not_ready(void);
+int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len);
+int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len);
+int mailbox_rsu_update(uint32_t *flash_offset);
+int mailbox_hps_stage_notify(uint32_t execution_stage);
+
#endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 6bb41f31b..92adfa3a7 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,28 +10,41 @@
/* SiP status response */
#define INTEL_SIP_SMC_STATUS_OK 0
-#define INTEL_SIP_SMC_STATUS_ERROR 0x4
#define INTEL_SIP_SMC_STATUS_BUSY 0x1
#define INTEL_SIP_SMC_STATUS_REJECTED 0x2
+#define INTEL_SIP_SMC_STATUS_ERROR 0x4
+#define INTEL_SIP_SMC_RSU_ERROR 0x7
+
/* SMC SiP service function identifier */
+
+/* FPGA Reconfig */
#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001
#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002
#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003
#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004
#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005
+
+/* Secure Register Access */
#define INTEL_SIP_SMC_REG_READ 0xC2000007
#define INTEL_SIP_SMC_REG_WRITE 0xC2000008
#define INTEL_SIP_SMC_REG_UPDATE 0xC2000009
+
+/* Remote System Update */
#define INTEL_SIP_SMC_RSU_STATUS 0xC200000B
#define INTEL_SIP_SMC_RSU_UPDATE 0xC200000C
-#define INTEL_SIP_LEGACY_SMC_ECC_DBE 0xC200000D
#define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E
#define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F
+/* Send Mailbox Command */
+#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E
+
+
+/* SiP Definitions */
+
/* FPGA config helpers */
#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000
-#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 16777216
+#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x2000000
/* SMC function IDs for SiP Service queries */
#define SIP_SVC_CALL_COUNT 0x8200ff00
@@ -42,4 +55,19 @@
#define SIP_SVC_VERSION_MAJOR 0
#define SIP_SVC_VERSION_MINOR 1
+
+/* Structure Definitions */
+struct fpga_config_info {
+ uint32_t addr;
+ int size;
+ int size_written;
+ uint32_t write_requested;
+ int subblocks_sent;
+ int block_number;
+};
+
+/* Function Definitions */
+
+bool is_address_in_ddr_range(uint64_t addr, uint64_t size);
+
#endif /* SOCFPGA_SIP_SVC_H */
diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h
index 68e30b894..8b42d47af 100644
--- a/plat/intel/soc/common/include/socfpga_system_manager.h
+++ b/plat/intel/soc/common/include/socfpga_system_manager.h
@@ -13,6 +13,13 @@
#define SOCFPGA_SYSMGR_SDMMC 0x28
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_2 0x6c
+
+#define SOCFPGA_SYSMGR_EMAC_0 0x44
+#define SOCFPGA_SYSMGR_EMAC_1 0x48
+#define SOCFPGA_SYSMGR_EMAC_2 0x4c
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_3 0x70
+
#define SOCFPGA_SYSMGR_NOC_TIMEOUT 0xc0
#define SOCFPGA_SYSMGR_NOC_IDLEREQ_SET 0xc4
#define SOCFPGA_SYSMGR_NOC_IDLEREQ_CLR 0xc8
@@ -27,6 +34,7 @@
/* Field Masking */
#define SYSMGR_SDMMC_DRVSEL(x) (((x) & 0x7) << 0)
+#define SYSMGR_SDMMC_SMPLSEL(x) (((x) & 0x7) << 4)
#define IDLE_DATA_LWSOC2FPGA BIT(0)
#define IDLE_DATA_SOC2FPGA BIT(4)
diff --git a/plat/intel/soc/common/soc/socfpga_emac.c b/plat/intel/soc/common/soc/socfpga_emac.c
new file mode 100644
index 000000000..cacfd53c4
--- /dev/null
+++ b/plat/intel/soc/common/soc/socfpga_emac.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2020, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include "socfpga_emac.h"
+#include "socfpga_reset_manager.h"
+#include "socfpga_system_manager.h"
+
+void socfpga_emac_init(void)
+{
+ mmio_setbits_32(SOCFPGA_RSTMGR(PER0MODRST),
+ RSTMGR_PER0MODRST_EMAC0 |
+ RSTMGR_PER0MODRST_EMAC1 |
+ RSTMGR_PER0MODRST_EMAC2);
+
+ mmio_clrsetbits_32(SOCFPGA_SYSMGR(EMAC_0),
+ PHY_INTF_SEL_MSK, EMAC0_PHY_MODE);
+ mmio_clrsetbits_32(SOCFPGA_SYSMGR(EMAC_1),
+ PHY_INTF_SEL_MSK, EMAC1_PHY_MODE);
+ mmio_clrsetbits_32(SOCFPGA_SYSMGR(EMAC_2),
+ PHY_INTF_SEL_MSK, EMAC2_PHY_MODE);
+
+ mmio_clrbits_32(SOCFPGA_SYSMGR(FPGAINTF_EN_3),
+ FPGAINTF_EN_3_EMAC_MSK(0) |
+ FPGAINTF_EN_3_EMAC_MSK(1) |
+ FPGAINTF_EN_3_EMAC_MSK(2));
+
+ mmio_clrbits_32(SOCFPGA_RSTMGR(PER0MODRST),
+ RSTMGR_PER0MODRST_EMAC0 |
+ RSTMGR_PER0MODRST_EMAC1 |
+ RSTMGR_PER0MODRST_EMAC2);
+}
+
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 8d7c1d663..aec94af94 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2020, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,188 +11,324 @@
#include "socfpga_mailbox.h"
#include "socfpga_sip_svc.h"
+
+static bool is_mailbox_cmdbuf_full(uint32_t cin)
+{
+ uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
+
+ return (((cin + 1U) % MBOX_CMD_BUFFER_SIZE) == cout);
+}
+
+static bool is_mailbox_cmdbuf_empty(uint32_t cin)
+{
+ uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
+
+ return (((cout + 1U) % MBOX_CMD_BUFFER_SIZE) == cin);
+}
+
+static int wait_for_mailbox_cmdbuf_empty(uint32_t cin)
+{
+ unsigned int timeout = 200U;
+
+ do {
+ if (is_mailbox_cmdbuf_empty(cin)) {
+ break;
+ }
+ mdelay(10U);
+ } while (--timeout != 0U);
+
+ if (timeout == 0U) {
+ return MBOX_TIMEOUT;
+ }
+
+ return MBOX_RET_OK;
+}
+
+static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout,
+ uint32_t data,
+ bool *is_doorbell_triggered)
+{
+ unsigned int timeout = 100U;
+
+ do {
+ if (is_mailbox_cmdbuf_full(*cin)) {
+ if (!(*is_doorbell_triggered)) {
+ mmio_write_32(MBOX_OFFSET +
+ MBOX_DOORBELL_TO_SDM, 1U);
+ *is_doorbell_triggered = true;
+ }
+ mdelay(10U);
+ } else {
+ mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER +
+ (*cin * 4), data);
+ (*cin)++;
+ *cin %= MBOX_CMD_BUFFER_SIZE;
+ mmio_write_32(MBOX_OFFSET + MBOX_CIN, *cin);
+ break;
+ }
+ } while (--timeout != 0U);
+
+ if (timeout == 0U) {
+ return MBOX_TIMEOUT;
+ }
+
+ if (*is_doorbell_triggered) {
+ int ret = wait_for_mailbox_cmdbuf_empty(*cin);
+ return ret;
+ }
+
+ return MBOX_RET_OK;
+}
+
static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
- int len)
+ unsigned int len)
{
- uint32_t cmd_free_offset;
- int i;
+ uint32_t sdm_read_offset, cmd_free_offset;
+ unsigned int i;
+ int ret;
+ bool is_doorbell_triggered = false;
cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN);
+ sdm_read_offset = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
- mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + (cmd_free_offset++ * 4),
- header_cmd);
+ ret = write_mailbox_cmd_buffer(&cmd_free_offset, sdm_read_offset,
+ header_cmd, &is_doorbell_triggered);
+ if (ret != 0) {
+ goto restart_mailbox;
+ }
+ for (i = 0U; i < len; i++) {
+ is_doorbell_triggered = false;
+ ret = write_mailbox_cmd_buffer(&cmd_free_offset,
+ sdm_read_offset, args[i],
+ &is_doorbell_triggered);
+ if (ret != 0) {
+ goto restart_mailbox;
+ }
+ }
- for (i = 0; i < len; i++) {
- cmd_free_offset %= MBOX_CMD_BUFFER_SIZE;
- mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER +
- (cmd_free_offset++ * 4), args[i]);
+ if (!is_doorbell_triggered) {
+ mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
}
- cmd_free_offset %= MBOX_CMD_BUFFER_SIZE;
- mmio_write_32(MBOX_OFFSET + MBOX_CIN, cmd_free_offset);
+ return MBOX_RET_OK;
- return 0;
+restart_mailbox:
+ /*
+ * Attempt to restart mailbox if the driver not able to write
+ * into mailbox command buffer
+ */
+ if (MBOX_CMD_MASK(header_cmd) != MBOX_CMD_RESTART) {
+ INFO("Mailbox timed out: Attempting mailbox reset\n");
+ ret = mailbox_init();
+
+ if (ret == MBOX_TIMEOUT) {
+ INFO("Error: Mailbox fail to restart\n");
+ }
+ }
+
+ return MBOX_TIMEOUT;
}
-int mailbox_read_response(int job_id, uint32_t *response, int resp_len)
+int mailbox_read_response(unsigned int *job_id, uint32_t *response,
+ unsigned int resp_len)
{
- int rin = 0;
- int rout = 0;
- int response_length = 0;
- int resp = 0;
- int total_resp_len = 0;
+ uint32_t rin;
+ uint32_t rout;
+ uint32_t resp_data;
+ unsigned int ret_resp_len;
- if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM))
- mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
+ if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) {
+ mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
+ }
rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
if (rout != rin) {
- resp = mmio_read_32(MBOX_OFFSET +
- MBOX_RESP_BUFFER + ((rout++)*4));
+ resp_data = mmio_read_32(MBOX_OFFSET +
+ MBOX_RESP_BUFFER + ((rout++)*4U));
rout %= MBOX_RESP_BUFFER_SIZE;
mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
- if (MBOX_RESP_CLIENT_ID(resp) != MBOX_ATF_CLIENT_ID ||
- MBOX_RESP_JOB_ID(resp) != job_id) {
+
+ if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) {
return MBOX_WRONG_ID;
}
- if (MBOX_RESP_ERR(resp) > 0) {
- INFO("Error in response: %x\n", resp);
- return -resp;
+ *job_id = MBOX_RESP_JOB_ID(resp_data);
+
+ ret_resp_len = MBOX_RESP_LEN(resp_data);
+
+ if (ret_resp_len != 0U) {
+ ret_resp_len = iterate_resp(ret_resp_len, response,
+ resp_len);
}
- response_length = MBOX_RESP_LEN(resp);
-
- while (response_length) {
-
- response_length--;
- resp = mmio_read_32(MBOX_OFFSET +
- MBOX_RESP_BUFFER +
- (rout)*4);
- if (response && resp_len) {
- *(response + total_resp_len) = resp;
- resp_len--;
- total_resp_len++;
- }
- rout++;
- rout %= MBOX_RESP_BUFFER_SIZE;
- mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
+
+ if (MBOX_RESP_ERR(resp_data) > 0U) {
+ INFO("Error in response: %x\n", resp_data);
+ return -MBOX_RESP_ERR(resp_data);
}
- return total_resp_len;
- }
+ return ret_resp_len;
+ }
return MBOX_NO_RESPONSE;
}
-int mailbox_poll_response(int job_id, int urgent, uint32_t *response,
- int resp_len)
+int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
+ unsigned int resp_len)
{
- int timeout = 0xFFFFFF;
- int rin = 0;
- int rout = 0;
- int response_length = 0;
- int resp = 0;
- int total_resp_len = 0;
-
- while (1) {
-
- while (timeout > 0 &&
- !(mmio_read_32(MBOX_OFFSET +
- MBOX_DOORBELL_FROM_SDM) & 1)) {
- timeout--;
- }
+ unsigned int timeout = 40U;
+ unsigned int sdm_loop = 255U;
+ unsigned int ret_resp_len;
+ uint32_t rin;
+ uint32_t rout;
+ uint32_t resp_data;
+
+ while (sdm_loop != 0U) {
+
+ do {
+ if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)
+ == 1U) {
+ break;
+ }
+ mdelay(10U);
+ } while (--timeout != 0U);
- if (!timeout) {
- INFO("Timed out waiting for SDM");
- return MBOX_TIMEOUT;
+ if (timeout == 0U) {
+ break;
}
- mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
+ mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
- if (urgent & 1) {
- mdelay(5);
+ if ((urgent & 1U) != 0U) {
+ mdelay(5U);
if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
MBOX_STATUS_UA_MASK) ^
(urgent & MBOX_STATUS_UA_MASK)) {
- mmio_write_32(MBOX_OFFSET + MBOX_URG, 0);
- return 0;
+ mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
+ return MBOX_RET_OK;
}
- mmio_write_32(MBOX_OFFSET + MBOX_URG, 0);
+ mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
INFO("Error: Mailbox did not get UA");
- return -1;
+ return MBOX_RET_ERROR;
}
rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
while (rout != rin) {
- resp = mmio_read_32(MBOX_OFFSET +
- MBOX_RESP_BUFFER + ((rout++)*4));
+ resp_data = mmio_read_32(MBOX_OFFSET +
+ MBOX_RESP_BUFFER + ((rout++)*4U));
rout %= MBOX_RESP_BUFFER_SIZE;
mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
- if (MBOX_RESP_CLIENT_ID(resp) != MBOX_ATF_CLIENT_ID ||
- MBOX_RESP_JOB_ID(resp) != job_id)
+ if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID
+ || MBOX_RESP_JOB_ID(resp_data) != job_id) {
continue;
+ }
+
+ ret_resp_len = MBOX_RESP_LEN(resp_data);
- if (MBOX_RESP_ERR(resp) > 0) {
- INFO("Error in response: %x\n", resp);
- return -MBOX_RESP_ERR(resp);
+ if (ret_resp_len != 0U) {
+ ret_resp_len = iterate_resp(ret_resp_len,
+ response,
+ resp_len);
}
- response_length = MBOX_RESP_LEN(resp);
-
- while (response_length) {
- response_length--;
- resp = mmio_read_32(MBOX_OFFSET +
- MBOX_RESP_BUFFER +
- (rout)*4);
- if (response && resp_len) {
- *(response + total_resp_len) = resp;
- resp_len--;
- total_resp_len++;
- }
- rout++;
- rout %= MBOX_RESP_BUFFER_SIZE;
- mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
+
+ if (MBOX_RESP_ERR(resp_data) > 0U) {
+ INFO("Error in response: %x\n", resp_data);
+ return -MBOX_RESP_ERR(resp_data);
}
- return total_resp_len;
+
+ return ret_resp_len;
}
+
+ sdm_loop--;
}
+
+ INFO("Timed out waiting for SDM\n");
+ return MBOX_TIMEOUT;
}
-int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
- int len, int urgent)
+unsigned int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf,
+ unsigned int resp_len)
{
- if (urgent)
- mmio_write_32(MBOX_OFFSET + MBOX_URG, 1);
+ unsigned int timeout, total_resp_len = 0U;
+ uint32_t resp_data;
+ uint32_t rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
+ uint32_t rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
+
+ while (mbox_resp_len > 0U) {
+ timeout = 100U;
+ mbox_resp_len--;
+ resp_data = mmio_read_32(MBOX_OFFSET +
+ MBOX_RESP_BUFFER +
+ (rout)*4U);
+
+ if ((resp_buf != NULL) && (resp_len != 0U)) {
+ *(resp_buf + total_resp_len)
+ = resp_data;
+ resp_len--;
+ total_resp_len++;
+ }
+ rout++;
+ rout %= MBOX_RESP_BUFFER_SIZE;
+ mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
+
+ do {
+ rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
+ if (rout == rin) {
+ mdelay(10U);
+ } else {
+ break;
+ }
+ timeout--;
+ } while ((mbox_resp_len > 0U) && (timeout != 0U));
+
+ if (timeout == 0U) {
+ INFO("Timed out waiting for SDM\n");
+ return MBOX_TIMEOUT;
+ }
+ }
+ return total_resp_len;
+}
- fill_mailbox_circular_buffer(MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
- MBOX_JOB_ID_CMD(job_id) |
- MBOX_CMD_LEN_CMD(len) |
- MBOX_INDIRECT |
- cmd, args, len);
+int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args,
+ unsigned int len, unsigned int indirect)
+{
+ int status;
+
+ status = fill_mailbox_circular_buffer(
+ MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
+ MBOX_JOB_ID_CMD(*job_id) |
+ MBOX_CMD_LEN_CMD(len) |
+ MBOX_INDIRECT(indirect) |
+ cmd, args, len);
+ if (status < 0) {
+ return status;
+ }
- mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
+ *job_id = (*job_id + 1U) % MBOX_MAX_IND_JOB_ID;
- return 0;
+ return MBOX_RET_OK;
}
-int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
- int len, int urgent, uint32_t *response, int resp_len)
+int mailbox_send_cmd(uint32_t job_id, uint32_t cmd, uint32_t *args,
+ unsigned int len, uint32_t urgent, uint32_t *response,
+ unsigned int resp_len)
{
int status = 0;
- if (urgent) {
+ if (urgent != 0U) {
urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
MBOX_STATUS_UA_MASK;
mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd);
+ mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
}
else {
@@ -203,10 +339,10 @@ int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
cmd, args, len);
}
- if (status)
+ if (status != 0) {
return status;
+ }
- mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
status = mailbox_poll_response(job_id, urgent, response, resp_len);
return status;
@@ -218,7 +354,7 @@ void mailbox_clear_response(void)
mmio_read_32(MBOX_OFFSET + MBOX_RIN));
}
-void mailbox_set_int(int interrupt)
+void mailbox_set_int(uint32_t interrupt)
{
mmio_write_32(MBOX_OFFSET+MBOX_INT, MBOX_COE_BIT(interrupt) |
@@ -229,90 +365,149 @@ void mailbox_set_int(int interrupt)
void mailbox_set_qspi_open(void)
{
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, 0, 0, 0, NULL, 0);
+ mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, NULL, 0U,
+ CMD_CASUAL, NULL, 0U);
}
void mailbox_set_qspi_direct(void)
{
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, NULL, 0);
+ mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, NULL, 0U,
+ CMD_CASUAL, NULL, 0U);
}
void mailbox_set_qspi_close(void)
{
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, 0, 0, 0, NULL, 0);
+ mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, NULL, 0U,
+ CMD_CASUAL, NULL, 0U);
}
-int mailbox_get_qspi_clock(void)
+void mailbox_qspi_set_cs(uint32_t device_select)
{
- mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0,
- NULL, 0);
-}
-
-void mailbox_qspi_set_cs(int device_select)
-{
- uint32_t cs_setting = device_select;
+ uint32_t cs_setting;
/* QSPI device select settings at 31:28 */
- cs_setting = (cs_setting << 28);
+ cs_setting = (device_select << 28);
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting,
- 1, 0, NULL, 0);
+ 1U, CMD_CASUAL, NULL, 0U);
}
void mailbox_reset_cold(void)
{
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, NULL, 0);
+ mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, NULL, 0U,
+ CMD_CASUAL, NULL, 0U);
+}
+
+int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, unsigned int resp_buf_len)
+{
+ return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE,
+ NULL, 0U, CMD_CASUAL, resp_buf,
+ resp_buf_len);
+}
+
+struct rsu_status_info {
+ uint64_t current_image;
+ uint64_t fail_image;
+ uint32_t state;
+ uint32_t version;
+ uint32_t error_location;
+ uint32_t error_details;
+ uint32_t retry_counter;
+};
+
+int mailbox_rsu_status(uint32_t *resp_buf, unsigned int resp_buf_len)
+{
+ int ret;
+ struct rsu_status_info *info = (struct rsu_status_info *)resp_buf;
+
+ info->retry_counter = ~0U;
+
+ ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0U,
+ CMD_CASUAL, resp_buf,
+ resp_buf_len);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (info->retry_counter != ~0U) {
+ if ((info->version & RSU_VERSION_ACMF_MASK) == 0U) {
+ info->version |= RSU_VERSION_ACMF;
+ }
+ }
+
+ return ret;
+}
+
+int mailbox_rsu_update(uint32_t *flash_offset)
+{
+ return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE,
+ flash_offset, 2U,
+ CMD_CASUAL, NULL, 0U);
+}
+
+int mailbox_hps_stage_notify(uint32_t execution_stage)
+{
+ return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY,
+ &execution_stage, 1U, CMD_CASUAL,
+ NULL, 0U);
}
int mailbox_init(void)
{
- int status = 0;
+ int status;
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
MBOX_INT_FLAG_UAE);
- mmio_write_32(MBOX_OFFSET + MBOX_URG, 0);
- mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
+ mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
+ mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
- status = mailbox_send_cmd(0, MBOX_CMD_RESTART, 0, 0, 1, NULL, 0);
+ status = mailbox_send_cmd(0U, MBOX_CMD_RESTART, NULL, 0U,
+ CMD_URGENT, NULL, 0U);
- if (status)
+ if (status != 0) {
return status;
+ }
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
MBOX_INT_FLAG_UAE);
- return 0;
+ return MBOX_RET_OK;
}
-uint32_t intel_mailbox_get_config_status(uint32_t cmd)
+int intel_mailbox_get_config_status(uint32_t cmd)
{
- uint32_t status, res;
- uint32_t response[6];
+ int status;
+ uint32_t res, response[6];
- status = mailbox_send_cmd(1, cmd, NULL, 0, 0, response,
- sizeof(response) / sizeof(response[0]));
+ status = mailbox_send_cmd(MBOX_JOB_ID, cmd, NULL, 0U, CMD_CASUAL,
+ response, ARRAY_SIZE(response));
- if (status < 0)
+ if (status < 0) {
return status;
+ }
res = response[RECONFIG_STATUS_STATE];
- if (res && res != MBOX_CFGSTAT_STATE_CONFIG)
+ if ((res != 0U) && (res != MBOX_CFGSTAT_STATE_CONFIG)) {
return res;
+ }
res = response[RECONFIG_STATUS_PIN_STATUS];
- if (!(res & PIN_STATUS_NSTATUS))
+ if ((res & PIN_STATUS_NSTATUS) == 0U) {
return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
+ }
res = response[RECONFIG_STATUS_SOFTFUNC_STATUS];
- if (res & SOFTFUNC_STATUS_SEU_ERROR)
+ if ((res & SOFTFUNC_STATUS_SEU_ERROR) != 0U) {
return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
+ }
- if ((res & SOFTFUNC_STATUS_CONF_DONE) &&
- (res & SOFTFUNC_STATUS_INIT_DONE))
- return 0;
+ if ((res & SOFTFUNC_STATUS_CONF_DONE) != 0U &&
+ (res & SOFTFUNC_STATUS_INIT_DONE) != 0U) {
+ return MBOX_RET_OK;
+ }
return MBOX_CFGSTAT_STATE_CONFIG;
}
@@ -321,8 +516,9 @@ int intel_mailbox_is_fpga_not_ready(void)
{
int ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS);
- if (ret && ret != MBOX_CFGSTAT_STATE_CONFIG)
+ if ((ret != MBOX_RET_OK) && (ret != MBOX_CFGSTAT_STATE_CONFIG)) {
ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS);
+ }
return ret;
}
diff --git a/plat/intel/soc/common/socfpga_delay_timer.c b/plat/intel/soc/common/socfpga_delay_timer.c
index ff8a556cf..c55cc9da6 100644
--- a/plat/intel/soc/common/socfpga_delay_timer.c
+++ b/plat/intel/soc/common/socfpga_delay_timer.c
@@ -36,4 +36,8 @@ void socfpga_delay_timer_init(void)
{
timer_init(&plat_timer_ops);
mmio_write_32(SOCFPGA_GLOBAL_TIMER, SOCFPGA_GLOBAL_TIMER_EN);
+
+ asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN));
+ asm volatile("msr cntp_tval_el0, %0" : : "r" (~0));
+
}
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index d8a6c1980..4b57b8f31 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -130,9 +130,19 @@ static void __dead2 socfpga_system_off(void)
panic();
}
+extern uint64_t intel_rsu_update_address;
+
static void __dead2 socfpga_system_reset(void)
{
- mailbox_reset_cold();
+ uint32_t addr_buf[2];
+
+ memcpy(addr_buf, &intel_rsu_update_address,
+ sizeof(intel_rsu_update_address));
+
+ if (intel_rsu_update_address)
+ mailbox_rsu_update(addr_buf);
+ else
+ mailbox_reset_cold();
while (1)
wfi();
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 41dae9e76..86a44556a 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,30 +14,15 @@
#include "socfpga_reset_manager.h"
#include "socfpga_sip_svc.h"
-/* Number of SiP Calls implemented */
-#define SIP_NUM_CALLS 0x3
/* Total buffer the driver can hold */
#define FPGA_CONFIG_BUFFER_SIZE 4
-static int current_block;
-static int read_block;
-static int current_buffer;
-static int send_id;
-static int rcv_id;
-static int max_blocks;
-static uint32_t bytes_per_block;
-static uint32_t blocks_submitted;
-static int is_partial_reconfig;
-
-struct fpga_config_info {
- uint32_t addr;
- int size;
- int size_written;
- uint32_t write_requested;
- int subblocks_sent;
- int block_number;
-};
+static int current_block, current_buffer;
+static int read_block, max_blocks, is_partial_reconfig;
+static uint32_t send_id, rcv_id;
+static uint32_t bytes_per_block, blocks_submitted;
+
/* SiP Service UUID */
DEFINE_SVC_UUID2(intl_svc_uid,
@@ -74,10 +59,8 @@ static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer)
args[2] = bytes_per_block;
buffer->size_written += args[2];
- mailbox_send_cmd_async(
- send_id++ % MBOX_MAX_JOB_ID,
- MBOX_RECONFIG_DATA,
- args, 3, 0);
+ mailbox_send_cmd_async(&send_id, MBOX_RECONFIG_DATA, args,
+ 3U, CMD_INDIRECT);
buffer->subblocks_sent++;
max_blocks--;
@@ -143,7 +126,7 @@ static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed)
}
static int intel_fpga_config_completed_write(uint32_t *completed_addr,
- uint32_t *count)
+ uint32_t *count, uint32_t *job_id)
{
uint32_t status = INTEL_SIP_SMC_STATUS_OK;
*count = 0;
@@ -153,14 +136,13 @@ static int intel_fpga_config_completed_write(uint32_t *completed_addr,
while (*count < 3) {
- resp_len = mailbox_read_response(rcv_id % MBOX_MAX_JOB_ID,
- resp, sizeof(resp) / sizeof(resp[0]));
+ resp_len = mailbox_read_response(job_id,
+ resp, ARRAY_SIZE(resp));
if (resp_len < 0)
break;
max_blocks++;
- rcv_id++;
if (mark_last_buffer_xfer_completed(
&completed_addr[*count]) == 0)
@@ -208,10 +190,10 @@ static int intel_fpga_config_start(uint32_t config_type)
mailbox_clear_response();
- mailbox_send_cmd(1, MBOX_CMD_CANCEL, 0, 0, 0, NULL, 0);
+ mailbox_send_cmd(1U, MBOX_CMD_CANCEL, NULL, 0U, CMD_CASUAL, NULL, 0U);
- status = mailbox_send_cmd(1, MBOX_RECONFIG, 0, 0, 0,
- response, sizeof(response) / sizeof(response[0]));
+ status = mailbox_send_cmd(1U, MBOX_RECONFIG, NULL, 0U, CMD_CASUAL,
+ response, ARRAY_SIZE(response));
if (status < 0)
return status;
@@ -232,8 +214,6 @@ static int intel_fpga_config_start(uint32_t config_type)
current_block = 0;
read_block = 0;
current_buffer = 0;
- send_id = 0;
- rcv_id = 0;
/* full reconfiguration */
if (!is_partial_reconfig) {
@@ -252,12 +232,16 @@ static bool is_fpga_config_buffer_full(void)
return true;
}
-static bool is_address_in_ddr_range(uint64_t addr)
+bool is_address_in_ddr_range(uint64_t addr, uint64_t size)
{
- if (addr >= DRAM_BASE && addr <= DRAM_BASE + DRAM_SIZE)
- return true;
+ if (size > (UINT64_MAX - addr))
+ return false;
+ if (addr < BL31_LIMIT)
+ return false;
+ if (addr + size > DRAM_BASE + DRAM_SIZE)
+ return false;
- return false;
+ return true;
}
static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
@@ -266,8 +250,7 @@ static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
intel_fpga_sdm_write_all();
- if (!is_address_in_ddr_range(mem) ||
- !is_address_in_ddr_range(mem + size) ||
+ if (!is_address_in_ddr_range(mem, size) ||
is_fpga_config_buffer_full())
return INTEL_SIP_SMC_STATUS_REJECTED;
@@ -365,6 +348,66 @@ uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask,
return INTEL_SIP_SMC_STATUS_ERROR;
}
+/* Intel Remote System Update (RSU) services */
+uint64_t intel_rsu_update_address;
+
+static uint32_t intel_rsu_status(uint64_t *respbuf, unsigned int respbuf_sz)
+{
+ if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0)
+ return INTEL_SIP_SMC_RSU_ERROR;
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_rsu_update(uint64_t update_address)
+{
+ intel_rsu_update_address = update_address;
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_rsu_notify(uint32_t execution_stage)
+{
+ if (mailbox_hps_stage_notify(execution_stage) < 0)
+ return INTEL_SIP_SMC_RSU_ERROR;
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz,
+ uint32_t *ret_stat)
+{
+ if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0)
+ return INTEL_SIP_SMC_RSU_ERROR;
+
+ *ret_stat = respbuf[8];
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+/* Mailbox services */
+static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, uint32_t len,
+ uint32_t urgent, uint32_t *response,
+ uint32_t resp_len, int *mbox_status,
+ int *len_in_resp)
+{
+ *len_in_resp = 0;
+ *mbox_status = 0;
+
+ if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len))
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+
+ int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent,
+ response, resp_len);
+
+ if (status < 0) {
+ *mbox_status = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *mbox_status = 0;
+ *len_in_resp = status;
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
/*
* This function is responsible for handling all SiP calls from the NS world
*/
@@ -378,10 +421,13 @@ uintptr_t sip_smc_handler(uint32_t smc_fid,
void *handle,
u_register_t flags)
{
- uint32_t val = 0;
+ uint32_t retval = 0;
uint32_t status = INTEL_SIP_SMC_STATUS_OK;
uint32_t completed_addr[3];
- uint32_t count = 0;
+ uint64_t rsu_respbuf[9];
+ u_register_t x5, x6;
+ int mbox_status, len_in_resp;
+
switch (smc_fid) {
case SIP_SVC_UID:
@@ -408,8 +454,8 @@ uintptr_t sip_smc_handler(uint32_t smc_fid,
case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE:
status = intel_fpga_config_completed_write(completed_addr,
- &count);
- switch (count) {
+ &retval, &rcv_id);
+ switch (retval) {
case 1:
SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
completed_addr[0], 0, 0);
@@ -434,17 +480,52 @@ uintptr_t sip_smc_handler(uint32_t smc_fid,
}
case INTEL_SIP_SMC_REG_READ:
- status = intel_secure_reg_read(x1, &val);
- SMC_RET3(handle, status, val, x1);
+ status = intel_secure_reg_read(x1, &retval);
+ SMC_RET3(handle, status, retval, x1);
case INTEL_SIP_SMC_REG_WRITE:
- status = intel_secure_reg_write(x1, (uint32_t)x2, &val);
- SMC_RET3(handle, status, val, x1);
+ status = intel_secure_reg_write(x1, (uint32_t)x2, &retval);
+ SMC_RET3(handle, status, retval, x1);
case INTEL_SIP_SMC_REG_UPDATE:
status = intel_secure_reg_update(x1, (uint32_t)x2,
- (uint32_t)x3, &val);
- SMC_RET3(handle, status, val, x1);
+ (uint32_t)x3, &retval);
+ SMC_RET3(handle, status, retval, x1);
+
+ case INTEL_SIP_SMC_RSU_STATUS:
+ status = intel_rsu_status(rsu_respbuf,
+ ARRAY_SIZE(rsu_respbuf));
+ if (status) {
+ SMC_RET1(handle, status);
+ } else {
+ SMC_RET4(handle, rsu_respbuf[0], rsu_respbuf[1],
+ rsu_respbuf[2], rsu_respbuf[3]);
+ }
+
+ case INTEL_SIP_SMC_RSU_UPDATE:
+ status = intel_rsu_update(x1);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_RSU_NOTIFY:
+ status = intel_rsu_notify(x1);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_RSU_RETRY_COUNTER:
+ status = intel_rsu_retry_counter((uint32_t *)rsu_respbuf,
+ ARRAY_SIZE(rsu_respbuf), &retval);
+ if (status) {
+ SMC_RET1(handle, status);
+ } else {
+ SMC_RET2(handle, status, retval);
+ }
+
+ case INTEL_SIP_SMC_MBOX_SEND_CMD:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4,
+ (uint32_t *)x5, x6, &mbox_status,
+ &len_in_resp);
+ SMC_RET4(handle, status, mbox_status, x5, len_in_resp);
default:
return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index 7d183db0d..721a6903c 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,6 +16,7 @@
#include <lib/xlat_tables/xlat_tables.h>
#include "qspi/cadence_qspi.h"
+#include "socfpga_emac.h"
#include "socfpga_handoff.h"
#include "socfpga_mailbox.h"
#include "socfpga_private.h"
@@ -45,12 +46,12 @@ const mmap_region_t plat_stratix10_mmap[] = {
{0},
};
-boot_source_type boot_source;
+boot_source_type boot_source = BOOT_SOURCE;
void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
u_register_t x2, u_register_t x4)
{
- static console_16550_t console;
+ static console_t console;
handoff reverse_handoff_ptr;
generic_delay_timer_init();
@@ -58,7 +59,6 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
if (socfpga_get_handoff(&reverse_handoff_ptr))
return;
config_pinmux(&reverse_handoff_ptr);
- boot_source = reverse_handoff_ptr.boot_source;
config_clkmgr_handoff(&reverse_handoff_ptr);
enable_nonsecure_access();
@@ -70,6 +70,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
console_16550_register(PLAT_UART0_BASE, get_uart_clk(), PLAT_BAUDRATE,
&console);
+ socfpga_emac_init();
socfpga_delay_timer_init();
init_hard_memory_controller();
mailbox_init();
diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c
index 29f57c467..128a8080d 100644
--- a/plat/intel/soc/stratix10/bl31_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl31_plat_setup.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,6 +16,7 @@
#include <plat/common/platform.h>
#include <platform_def.h>
+#include "socfpga_mailbox.h"
#include "socfpga_private.h"
#include "socfpga_reset_manager.h"
#include "socfpga_system_manager.h"
@@ -44,7 +45,9 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_16550_t console;
+ static console_t console;
+
+ mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
&console);
@@ -106,6 +109,8 @@ static const gicv2_driver_data_t plat_gicv2_gic_data = {
******************************************************************************/
void bl31_platform_setup(void)
{
+ socfpga_delay_timer_init();
+
/* Initialize the gic cpu and distributor interfaces */
gicv2_driver_init(&plat_gicv2_gic_data);
gicv2_distif_init();
@@ -115,6 +120,8 @@ void bl31_platform_setup(void)
/* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */
mmio_write_64(PLAT_CPU_RELEASE_ADDR,
(uint64_t)plat_secondary_cpus_bl31_entry);
+
+ mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
}
const mmap_region_t plat_stratix10_mmap[] = {
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index 9dc51514c..a2bd57b08 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -10,7 +10,8 @@
#include <platform_def.h>
/* Platform Setting */
-#define PLATFORM_MODEL PLAT_SOCFPGA_STRATIX10
+#define PLATFORM_MODEL PLAT_SOCFPGA_STRATIX10
+#define BOOT_SOURCE BOOT_SOURCE_SDMMC
/* Register Mapping */
#define SOCFPGA_MMC_REG_BASE 0xff808000
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index efbab24b3..8bbd01027 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -1,6 +1,6 @@
#
-# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -10,18 +10,23 @@ PLAT_INCLUDES := \
-Iplat/intel/soc/common/drivers/ \
-Iplat/intel/soc/common/include/
+# Include GICv2 driver files
+include drivers/arm/gic/v2/gicv2.mk
+AGX_GICv2_SOURCES := \
+ ${GICV2_SOURCES} \
+ plat/common/plat_gicv2.c
+
+
PLAT_BL_COMMON_SOURCES := \
- drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
+ ${AGX_GICv2_SOURCES} \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
drivers/ti/uart/aarch64/16550_console.S \
lib/xlat_tables/aarch64/xlat_tables.c \
lib/xlat_tables/xlat_tables_common.c \
- plat/common/plat_gicv2.c \
plat/intel/soc/common/aarch64/platform_common.c \
- plat/intel/soc/common/aarch64/plat_helpers.S
+ plat/intel/soc/common/aarch64/plat_helpers.S \
+ plat/intel/soc/common/socfpga_delay_timer.c
BL2_SOURCES += \
common/desc_image_load.c \
@@ -39,9 +44,9 @@ BL2_SOURCES += \
plat/intel/soc/stratix10/soc/s10_memory_controller.c \
plat/intel/soc/stratix10/soc/s10_pinmux.c \
plat/intel/soc/common/bl2_plat_mem_params_desc.c \
- plat/intel/soc/common/socfpga_delay_timer.c \
plat/intel/soc/common/socfpga_image_load.c \
plat/intel/soc/common/socfpga_storage.c \
+ plat/intel/soc/common/soc/socfpga_emac.c \
plat/intel/soc/common/soc/socfpga_handoff.c \
plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c \
diff --git a/plat/layerscape/common/aarch64/ls_console.S b/plat/layerscape/common/aarch64/ls_console.S
index f8948b4ab..fb8267bc0 100644
--- a/plat/layerscape/common/aarch64/ls_console.S
+++ b/plat/layerscape/common/aarch64/ls_console.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -81,7 +81,7 @@ endfunc console_ls_16550_core_init
.globl console_ls_16550_register
/* -----------------------------------------------
- * int console_ls_16550_register(console_ls_16550_t *console,
+ * int console_ls_16550_register(console_t *console,
* uintptr_t base, uint32_t clk, uint32_t baud)
* Function to initialize and register a new 16550
* console. Storage passed in for the console struct
@@ -89,7 +89,7 @@ endfunc console_ls_16550_core_init
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
- * x3 - pointer to empty console_ls_16550_t struct
+ * x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -----------------------------------------------
@@ -98,7 +98,7 @@ func console_ls_16550_register
mov x7, x30
mov x6, x3
cbz x6, register_fail
- str x0, [x6, #CONSOLE_T_16550_BASE]
+ str x0, [x6, #CONSOLE_T_BASE]
bl console_ls_16550_core_init
cbz x0, register_fail
@@ -150,7 +150,7 @@ func console_ls_16550_core_putc
endfunc console_ls_16550_core_putc
/* --------------------------------------------------------
- * int console_16550_putc(int c, console_ls_16550_t *console)
+ * int console_16550_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
@@ -164,7 +164,7 @@ func console_ls_16550_putc
cmp x1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x1, [x1, #CONSOLE_T_16550_BASE]
+ ldr x1, [x1, #CONSOLE_T_BASE]
b console_ls_16550_core_putc
endfunc console_ls_16550_putc
@@ -195,7 +195,7 @@ no_char:
endfunc console_ls_16550_core_getc
/* ---------------------------------------------
- * int console_ls_16550_getc(console_ls_16550_t *console)
+ * int console_ls_16550_getc(console_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 on if no character is available.
@@ -209,16 +209,16 @@ func console_ls_16550_getc
cmp x1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x0, [x0, #CONSOLE_T_16550_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_ls_16550_core_getc
endfunc console_ls_16550_getc
/* ---------------------------------------------
- * int console_ls_16550_core_flush(uintptr_t base_addr)
+ * void console_ls_16550_core_flush(uintptr_t base_addr)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - console base address
- * Out : return -1 on error else return 0.
+ * Out : void
* Clobber list : x0, x1
* ---------------------------------------------
*/
@@ -234,16 +234,15 @@ func console_ls_16550_core_flush
cmp w1, #(UARTLSR_TEMT | UARTLSR_THRE)
b.ne 1b
- mov w0, #0
ret
endfunc console_ls_16550_core_flush
/* ---------------------------------------------
- * int console_ls_16550_flush(console_ls_16550_t *console)
+ * void console_ls_16550_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - pointer to console_t structure
- * Out : return -1 on error else return 0.
+ * Out : void
* Clobber list : x0, x1
* ---------------------------------------------
*/
@@ -252,6 +251,6 @@ func console_ls_16550_flush
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr x0, [x0, #CONSOLE_T_16550_BASE]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_ls_16550_core_flush
endfunc console_ls_16550_flush
diff --git a/plat/layerscape/common/include/ls_16550.h b/plat/layerscape/common/include/ls_16550.h
index cb4514f3f..95a64ad34 100644
--- a/plat/layerscape/common/include/ls_16550.h
+++ b/plat/layerscape/common/include/ls_16550.h
@@ -61,17 +61,10 @@
#define UARTLSR_OVRF (1 << 2) /* Rx Overrun Error */
#define UARTLSR_RDR (1 << 2) /* Rx Data Ready */
-#define CONSOLE_T_16550_BASE CONSOLE_T_DRVDATA
-
#ifndef __ASSEMBLER__
#include <stdint.h>
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_ls_16550_t;
-
/*
* Initialize a new 16550 console instance and register it with the console
* framework. The |console| pointer must point to storage that will be valid
@@ -79,7 +72,7 @@ typedef struct {
* Its contents will be reinitialized from scratch.
*/
int console_ls_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_ls_16550_t *console);
+ console_t *console);
#endif /*__ASSEMBLER__*/
diff --git a/plat/layerscape/common/ls_bl1_setup.c b/plat/layerscape/common/ls_bl1_setup.c
index fff065efd..fa69be2e6 100644
--- a/plat/layerscape/common/ls_bl1_setup.c
+++ b/plat/layerscape/common/ls_bl1_setup.c
@@ -23,7 +23,7 @@ meminfo_t *bl1_plat_sec_mem_layout(void)
******************************************************************************/
void ls_bl1_early_platform_setup(void)
{
- static console_ls_16550_t console;
+ static console_t console;
#if !LS1043_DISABLE_TRUSTED_WDOG
/* TODO: Enable watchdog */
diff --git a/plat/layerscape/common/ls_bl2_setup.c b/plat/layerscape/common/ls_bl2_setup.c
index 35f42e1fb..6ca66bd47 100644
--- a/plat/layerscape/common/ls_bl2_setup.c
+++ b/plat/layerscape/common/ls_bl2_setup.c
@@ -23,7 +23,7 @@ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
******************************************************************************/
void ls_bl2_early_platform_setup(meminfo_t *mem_layout)
{
- static console_ls_16550_t console;
+ static console_t console;
/* Initialize the console to provide early debug support */
console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK,
diff --git a/plat/layerscape/common/ls_bl31_setup.c b/plat/layerscape/common/ls_bl31_setup.c
index 03e580768..7a91aef81 100644
--- a/plat/layerscape/common/ls_bl31_setup.c
+++ b/plat/layerscape/common/ls_bl31_setup.c
@@ -67,7 +67,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
void ls_bl31_early_platform_setup(void *from_bl2,
void *plat_params_from_bl2)
{
- static console_ls_16550_t console;
+ static console_t console;
/* Initialize the console to provide early debug support */
console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK,
@@ -182,7 +182,7 @@ void ls_bl31_platform_setup(void)
******************************************************************************/
void ls_bl31_plat_runtime_setup(void)
{
- static console_ls_16550_t console;
+ static console_t console;
/* Initialize the runtime console */
console_ls_16550_register(PLAT_LS1043_UART_BASE, PLAT_LS1043_UART_CLOCK,
diff --git a/plat/layerscape/common/tsp/ls_tsp_setup.c b/plat/layerscape/common/tsp/ls_tsp_setup.c
index f3b60276c..969d0b83b 100644
--- a/plat/layerscape/common/tsp/ls_tsp_setup.c
+++ b/plat/layerscape/common/tsp/ls_tsp_setup.c
@@ -30,7 +30,7 @@ gicv2_driver_data_t ls_gic_data = {
******************************************************************************/
void ls_tsp_early_platform_setup(void)
{
- static console_ls_16550_t console;
+ static console_t console;
/*
* Initialize a different console than already in use to display
* messages from TSP
diff --git a/plat/marvell/a3700/common/a3700_common.mk b/plat/marvell/a3700/common/a3700_common.mk
deleted file mode 100644
index 1e2756734..000000000
--- a/plat/marvell/a3700/common/a3700_common.mk
+++ /dev/null
@@ -1,171 +0,0 @@
-#
-# Copyright (C) 2018 Marvell International Ltd.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-# https://spdx.org/licenses
-#
-
-MARVELL_PLAT_BASE := plat/marvell
-MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell
-PLAT_FAMILY := a3700
-PLAT_FAMILY_BASE := $(MARVELL_PLAT_BASE)/$(PLAT_FAMILY)
-PLAT_INCLUDE_BASE := $(MARVELL_PLAT_INCLUDE_BASE)/$(PLAT_FAMILY)
-PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common
-MARVELL_DRV_BASE := drivers/marvell
-MARVELL_COMMON_BASE := $(MARVELL_PLAT_BASE)/common
-HANDLE_EA_EL3_FIRST := 1
-
-include $(MARVELL_PLAT_BASE)/marvell.mk
-
-#*********** A3700 *************
-DOIMAGEPATH := $(WTP)
-DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/linux/tbb_linux
-
-ifeq ($(MARVELL_SECURE_BOOT),1)
-DOIMAGE_CFG := $(DOIMAGEPATH)/atf-tim.txt
-IMAGESPATH := $(DOIMAGEPATH)/tim/trusted
-
-TIMNCFG := $(DOIMAGEPATH)/atf-timN.txt
-TIMNSIG := $(IMAGESPATH)/timnsign.txt
-TIM2IMGARGS := -i $(DOIMAGE_CFG) -n $(TIMNCFG)
-TIMN_IMAGE := $$(grep "Image Filename:" -m 1 $(TIMNCFG) | cut -c 17-)
-else #MARVELL_SECURE_BOOT
-DOIMAGE_CFG := $(DOIMAGEPATH)/atf-ntim.txt
-IMAGESPATH := $(DOIMAGEPATH)/tim/untrusted
-TIM2IMGARGS := -i $(DOIMAGE_CFG)
-endif #MARVELL_SECURE_BOOT
-
-TIMBUILD := $(DOIMAGEPATH)/script/buildtim.sh
-TIM2IMG := $(DOIMAGEPATH)/script/tim2img.pl
-
-# WTMI_IMG is used to specify the customized RTOS image running over
-# Service CPU (CM3 processor). By the default, it points to a
-# baremetal binary of fuse programming in A3700_utils.
-WTMI_IMG := $(DOIMAGEPATH)/wtmi/fuse/build/fuse.bin
-
-# WTMI_SYSINIT_IMG is used for the system early initialization,
-# such as AVS settings, clock-tree setup and dynamic DDR PHY training.
-# After the initialization is done, this image will be wiped out
-# from the memory and CM3 will continue with RTOS image or other application.
-WTMI_SYSINIT_IMG := $(DOIMAGEPATH)/wtmi/sys_init/build/sys_init.bin
-
-# WTMI_MULTI_IMG is composed of CM3 RTOS image (WTMI_IMG)
-# and sys-init image (WTMI_SYSINIT_IMG).
-WTMI_MULTI_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi.bin
-
-WTMI_ENC_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi-enc.bin
-BUILD_UART := uart-images
-
-SRCPATH := $(dir $(BL33))
-
-CLOCKSPRESET ?= CPU_800_DDR_800
-
-DDR_TOPOLOGY ?= 0
-
-BOOTDEV ?= SPINOR
-PARTNUM ?= 0
-
-TIM_IMAGE := $$(grep "Image Filename:" -m 1 $(DOIMAGE_CFG) | cut -c 17-)
-TIMBLDARGS := $(MARVELL_SECURE_BOOT) $(BOOTDEV) $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \
- $(DDR_TOPOLOGY) $(PARTNUM) $(DEBUG) $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 1
-TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \
- $(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0
-DOIMAGE_FLAGS := -r $(DOIMAGE_CFG) -v -D
-
-# GICV3
-$(eval $(call add_define,CONFIG_GICV3))
-
-# CCI-400
-$(eval $(call add_define,USE_CCI))
-
-MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/v3/gicv3_helpers.c \
- drivers/arm/gic/v3/arm_gicv3_common.c \
- plat/common/plat_gicv3.c \
- drivers/arm/gic/v3/gic500.c
-
-PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \
- -I$(PLAT_COMMON_BASE)/include \
- -I$(PLAT_INCLUDE_BASE)/common \
- -I$(MARVELL_DRV_BASE) \
- -I$/drivers/arm/gic/common/
-
-PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a3700_common.c \
- $(MARVELL_COMMON_BASE)/marvell_cci.c \
- $(MARVELL_DRV_BASE)/uart/a3700_console.S
-
-BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \
- lib/cpus/aarch64/cortex_a53.S
-
-BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/pm_src.c
-
-MARVELL_DRV := $(MARVELL_DRV_BASE)/comphy/phy-comphy-3700.c
-
-BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
- $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \
- $(PLAT_COMMON_BASE)/plat_pm.c \
- $(PLAT_COMMON_BASE)/dram_win.c \
- $(PLAT_COMMON_BASE)/io_addr_dec.c \
- $(PLAT_COMMON_BASE)/marvell_plat_config.c \
- $(PLAT_COMMON_BASE)/a3700_ea.c \
- $(PLAT_FAMILY_BASE)/$(PLAT)/plat_bl31_setup.c \
- $(MARVELL_COMMON_BASE)/marvell_ddr_info.c \
- $(MARVELL_COMMON_BASE)/marvell_gicv3.c \
- $(MARVELL_GIC_SOURCES) \
- drivers/arm/cci/cci.c \
- $(BL31_PORTING_SOURCES) \
- $(PLAT_COMMON_BASE)/a3700_sip_svc.c \
- $(MARVELL_DRV)
-
-mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL}
- $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin)
- $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE})
- $(shell truncate -s %4 ${BUILD_PLAT}/${BOOT_IMAGE})
- $(shell truncate -s %4 $(WTMI_IMG))
- @echo
- @echo "Building uart images"
- $(TIMBUILD) $(TIMBLDUARTARGS)
- @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG)
- @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG)
-ifeq ($(MARVELL_SECURE_BOOT),1)
- @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG)
- @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG)
-endif
- $(DOIMAGETOOL) $(DOIMAGE_FLAGS)
- @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi
- @rm -rf $(BUILD_PLAT)/$(BUILD_UART)*
- @mkdir $(BUILD_PLAT)/$(BUILD_UART)
- @mv -t $(BUILD_PLAT)/$(BUILD_UART) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG)
- @find . -name "*_h.*" |xargs cp -ut $(BUILD_PLAT)/$(BUILD_UART)
- @mv $(subst .bin,_h.bin,$(WTMI_MULTI_IMG)) $(BUILD_PLAT)/$(BUILD_UART)/wtmi_h.bin
- @tar czf $(BUILD_PLAT)/$(BUILD_UART).tgz -C $(BUILD_PLAT) ./$(BUILD_UART)
- @echo
- @echo "Building flash image"
- $(TIMBUILD) $(TIMBLDARGS)
- sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(DOIMAGE_CFG)
- sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(DOIMAGE_CFG)
-ifeq ($(MARVELL_SECURE_BOOT),1)
- @sed -i 's|WTMI_IMG|$(WTMI_MULTI_IMG)|1' $(TIMNCFG)
- @sed -i 's|BOOT_IMAGE|$(BUILD_PLAT)/$(BOOT_IMAGE)|1' $(TIMNCFG)
- @echo -e "\n\t=======================================================\n";
- @echo -e "\t Secure boot. Encrypting wtmi and boot-image \n";
- @echo -e "\t=======================================================\n";
- @truncate -s %16 $(WTMI_MULTI_IMG)
- @openssl enc -aes-256-cbc -e -in $(WTMI_MULTI_IMG) \
- -out $(WTMI_ENC_IMG) \
- -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
- -iv `cat $(IMAGESPATH)/iv.txt` -p
- @truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE);
- @openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \
- -out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \
- -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
- -iv `cat $(IMAGESPATH)/iv.txt` -p
-endif
- $(DOIMAGETOOL) $(DOIMAGE_FLAGS)
- @if [ -e "$(TIMNCFG)" ]; then $(DOIMAGETOOL) -r $(TIMNCFG); fi
- @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then sed -i 's|$(WTMI_MULTI_IMG)|$(WTMI_ENC_IMG)|1;s|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1;' $(TIMNCFG); fi
- $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE)
- @mv -t $(BUILD_PLAT) $(TIM_IMAGE) $(DOIMAGE_CFG) $(TIMN_IMAGE) $(TIMNCFG) $(WTMI_IMG) $(WTMI_SYSINIT_IMG) $(WTMI_MULTI_IMG)
- @if [ "$(MARVELL_SECURE_BOOT)" = "1" ]; then mv -t $(BUILD_PLAT) $(WTMI_ENC_IMG) OtpHash.txt; fi
- @find . -name "*.txt" | grep -E "CSK[[:alnum:]]_KeyHash.txt|Tim_msg.txt|TIMHash.txt" | xargs rm -f
diff --git a/plat/marvell/a8k/common/aarch64/plat_arch_config.c b/plat/marvell/a8k/common/aarch64/plat_arch_config.c
deleted file mode 100644
index 06dc84115..000000000
--- a/plat/marvell/a8k/common/aarch64/plat_arch_config.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2018 Marvell International Ltd.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- * https://spdx.org/licenses
- */
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <drivers/marvell/cache_llc.h>
-#include <lib/mmio.h>
-#include <plat/common/platform.h>
-
-#define CCU_HTC_ASET (MVEBU_CCU_BASE(MVEBU_AP0) + 0x264)
-#define MVEBU_IO_AFFINITY (0xF00)
-
-
-static void plat_enable_affinity(void)
-{
- int cluster_id;
- int affinity;
-
- /* set CPU Affinity */
- cluster_id = plat_my_core_pos() / PLAT_MARVELL_CLUSTER_CORE_COUNT;
- affinity = (MVEBU_IO_AFFINITY | (1 << cluster_id));
- mmio_write_32(CCU_HTC_ASET, affinity);
-
- /* set barier */
- isb();
-}
-
-void marvell_psci_arch_init(int die_index)
-{
-#if LLC_ENABLE
- /* check if LLC is in exclusive mode
- * as L2 is configured to UniqueClean eviction
- * (in a8k reset handler)
- */
- if (llc_is_exclusive(0) == 0)
- ERROR("LLC should be configured to exclusice mode\n");
-#endif
-
- /* Enable Affinity */
- plat_enable_affinity();
-}
diff --git a/plat/marvell/a3700/a3700/board/pm_src.c b/plat/marvell/armada/a3k/a3700/board/pm_src.c
index d6eca5d16..d6eca5d16 100644
--- a/plat/marvell/a3700/a3700/board/pm_src.c
+++ b/plat/marvell/armada/a3k/a3700/board/pm_src.c
diff --git a/plat/marvell/a3700/a3700/mvebu_def.h b/plat/marvell/armada/a3k/a3700/mvebu_def.h
index dad1085f8..dad1085f8 100644
--- a/plat/marvell/a3700/a3700/mvebu_def.h
+++ b/plat/marvell/armada/a3k/a3700/mvebu_def.h
diff --git a/plat/marvell/a3700/a3700/plat_bl31_setup.c b/plat/marvell/armada/a3k/a3700/plat_bl31_setup.c
index 6862a8670..6862a8670 100644
--- a/plat/marvell/a3700/a3700/plat_bl31_setup.c
+++ b/plat/marvell/armada/a3k/a3700/plat_bl31_setup.c
diff --git a/plat/marvell/a3700/a3700/platform.mk b/plat/marvell/armada/a3k/a3700/platform.mk
index 4f7ac08c4..050af4199 100644
--- a/plat/marvell/a3700/a3700/platform.mk
+++ b/plat/marvell/armada/a3k/a3700/platform.mk
@@ -5,6 +5,6 @@
# https://spdx.org/licenses
#
-include plat/marvell/a3700/common/a3700_common.mk
+include plat/marvell/armada/a3k/common/a3700_common.mk
-include plat/marvell/common/marvell_common.mk
+include plat/marvell/armada/common/marvell_common.mk
diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk
new file mode 100644
index 000000000..8775e8934
--- /dev/null
+++ b/plat/marvell/armada/a3k/common/a3700_common.mk
@@ -0,0 +1,233 @@
+#
+# Copyright (C) 2018-2021 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+MARVELL_PLAT_BASE := plat/marvell/armada
+MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell/armada
+PLAT_FAMILY := a3k
+PLAT_FAMILY_BASE := $(MARVELL_PLAT_BASE)/$(PLAT_FAMILY)
+PLAT_INCLUDE_BASE := $(MARVELL_PLAT_INCLUDE_BASE)/$(PLAT_FAMILY)
+PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common
+MARVELL_DRV_BASE := drivers/marvell
+MARVELL_COMMON_BASE := $(MARVELL_PLAT_BASE)/common
+HANDLE_EA_EL3_FIRST := 1
+
+include plat/marvell/marvell.mk
+
+#*********** A3700 *************
+
+# GICV3
+$(eval $(call add_define,CONFIG_GICV3))
+
+# CCI-400
+$(eval $(call add_define,USE_CCI))
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+MARVELL_GIC_SOURCES := ${GICV3_SOURCES} \
+ plat/common/plat_gicv3.c
+
+PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \
+ -I$(PLAT_COMMON_BASE)/include \
+ -I$(PLAT_INCLUDE_BASE)/common \
+ -I$(MARVELL_DRV_BASE) \
+ -I$/drivers/arm/gic/common/
+
+PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a3700_common.c \
+ $(MARVELL_DRV_BASE)/uart/a3700_console.S
+
+BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \
+ lib/cpus/aarch64/cortex_a53.S
+
+BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/pm_src.c
+
+MARVELL_DRV := $(MARVELL_DRV_BASE)/comphy/phy-comphy-3700.c
+
+BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
+ $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \
+ $(PLAT_COMMON_BASE)/plat_cci.c \
+ $(PLAT_COMMON_BASE)/plat_pm.c \
+ $(PLAT_COMMON_BASE)/dram_win.c \
+ $(PLAT_COMMON_BASE)/io_addr_dec.c \
+ $(PLAT_COMMON_BASE)/marvell_plat_config.c \
+ $(PLAT_COMMON_BASE)/a3700_ea.c \
+ $(PLAT_FAMILY_BASE)/$(PLAT)/plat_bl31_setup.c \
+ $(MARVELL_COMMON_BASE)/marvell_cci.c \
+ $(MARVELL_COMMON_BASE)/marvell_ddr_info.c \
+ $(MARVELL_COMMON_BASE)/marvell_gicv3.c \
+ $(MARVELL_GIC_SOURCES) \
+ drivers/arm/cci/cci.c \
+ $(BL31_PORTING_SOURCES) \
+ $(PLAT_COMMON_BASE)/a3700_sip_svc.c \
+ $(MARVELL_DRV)
+
+ifeq ($(CM3_SYSTEM_RESET),1)
+BL31_SOURCES += $(PLAT_COMMON_BASE)/cm3_system_reset.c
+endif
+
+ifdef WTP
+
+$(if $(wildcard $(value WTP)/*),,$(error "'WTP=$(value WTP)' was specified, but '$(value WTP)' directory does not exist"))
+$(if $(shell test -s "$(value WTP)/branch.txt" || git -C $(value WTP) rev-parse --show-cdup 2>&1),$(error "'WTP=$(value WTP)' was specified, but '$(value WTP)' does not contain valid Marvell a3700_utils release tarball nor git repository"))
+
+DOIMAGEPATH := $(WTP)
+DOIMAGETOOL := $(DOIMAGEPATH)/wtptp/src/TBB_Linux/release/TBB_linux
+
+BUILD_UART := uart-images
+UART_IMAGE := $(BUILD_UART).tgz.bin
+
+ifeq ($(MARVELL_SECURE_BOOT),1)
+DOIMAGE_CFG := $(BUILD_PLAT)/atf-tim.txt
+DOIMAGEUART_CFG := $(BUILD_PLAT)/$(BUILD_UART)/atf-tim.txt
+IMAGESPATH := $(DOIMAGEPATH)/tim/trusted
+TIMNCFG := $(BUILD_PLAT)/atf-timN.txt
+TIMNUARTCFG := $(BUILD_PLAT)/$(BUILD_UART)/atf-timN.txt
+TIMNSIG := $(IMAGESPATH)/timnsign.txt
+TIM2IMGARGS := -i $(DOIMAGE_CFG) -n $(TIMNCFG)
+TIMN_IMAGE := $$(grep "Image Filename:" -m 1 $(TIMNCFG) | cut -c 17-)
+else #MARVELL_SECURE_BOOT
+DOIMAGE_CFG := $(BUILD_PLAT)/atf-ntim.txt
+DOIMAGEUART_CFG := $(BUILD_PLAT)/$(BUILD_UART)/atf-ntim.txt
+IMAGESPATH := $(DOIMAGEPATH)/tim/untrusted
+TIM2IMGARGS := -i $(DOIMAGE_CFG)
+endif #MARVELL_SECURE_BOOT
+
+TIMBUILD := $(DOIMAGEPATH)/script/buildtim.sh
+TIM2IMG := $(DOIMAGEPATH)/script/tim2img.pl
+TIMDDRTOOL := $(DOIMAGEPATH)/tim/ddr/ddr_tool
+
+$(TIMBUILD): $(TIMDDRTOOL)
+
+# WTMI_IMG is used to specify the customized RTOS image running over
+# Service CPU (CM3 processor). By the default, it points to a
+# baremetal binary of fuse programming in A3700_utils.
+WTMI_IMG := $(DOIMAGEPATH)/wtmi/fuse/build/fuse.bin
+
+# WTMI_MULTI_IMG is composed of CM3 RTOS image (WTMI_IMG)
+# and sys-init image.
+WTMI_MULTI_IMG := $(DOIMAGEPATH)/wtmi/build/wtmi.bin
+
+WTMI_ENC_IMG := wtmi-enc.bin
+
+SRCPATH := $(dir $(BL33))
+
+CLOCKSPRESET ?= CPU_800_DDR_800
+
+DDR_TOPOLOGY ?= 0
+
+BOOTDEV ?= SPINOR
+PARTNUM ?= 0
+
+TIM_IMAGE := $$(grep "Image Filename:" -m 1 $(DOIMAGE_CFG) | cut -c 17-)
+TIMBLDARGS := $(MARVELL_SECURE_BOOT) $(BOOTDEV) $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \
+ $(DDR_TOPOLOGY) $(PARTNUM) $(DEBUG) $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 1
+TIMBLDUARTARGS := $(MARVELL_SECURE_BOOT) UART $(IMAGESPATH) $(DOIMAGEPATH) $(CLOCKSPRESET) \
+ $(DDR_TOPOLOGY) 0 0 $(DOIMAGEUART_CFG) $(TIMNUARTCFG) $(TIMNSIG) 0
+
+CRYPTOPP_LIBDIR ?= $(CRYPTOPP_PATH)
+CRYPTOPP_INCDIR ?= $(CRYPTOPP_PATH)
+
+$(DOIMAGETOOL): FORCE
+ $(if $(CRYPTOPP_LIBDIR),,$(error "Platform '$(PLAT)' for WTP image tool requires CRYPTOPP_PATH or CRYPTOPP_LIBDIR. Please set CRYPTOPP_PATH or CRYPTOPP_LIBDIR to point to the right directory"))
+ $(if $(CRYPTOPP_INCDIR),,$(error "Platform '$(PLAT)' for WTP image tool requires CRYPTOPP_PATH or CRYPTOPP_INCDIR. Please set CRYPTOPP_PATH or CRYPTOPP_INCDIR to point to the right directory"))
+ $(if $(wildcard $(CRYPTOPP_LIBDIR)/*),,$(error "Either 'CRYPTOPP_PATH' or 'CRYPTOPP_LIB' was set to '$(CRYPTOPP_LIBDIR)', but '$(CRYPTOPP_LIBDIR)' does not exist"))
+ $(if $(wildcard $(CRYPTOPP_INCDIR)/*),,$(error "Either 'CRYPTOPP_PATH' or 'CRYPTOPP_INCDIR' was set to '$(CRYPTOPP_INCDIR)', but '$(CRYPTOPP_INCDIR)' does not exist"))
+ifdef CRYPTOPP_PATH
+ $(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile
+endif
+ $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_LIBDIR) INCDIR=$(CRYPTOPP_INCDIR)
+
+$(WTMI_MULTI_IMG): FORCE
+ $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) WTMI_IMG=$(WTMI_IMG) DDR_TOPOLOGY=$(DDR_TOPOLOGY) CLOCKSPRESET=$(CLOCKSPRESET) WTMI
+
+$(BUILD_PLAT)/wtmi.bin: $(WTMI_MULTI_IMG)
+ $(Q)cp -a $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi.bin
+
+$(TIMDDRTOOL): FORCE
+ $(if $(value MV_DDR_PATH),,$(error "Platform '${PLAT}' for ddr tool requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory"))
+ $(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist"))
+ $(if $(shell test -s "$(value MV_DDR_PATH)/branch.txt" || git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid Marvell mv_ddr release tarball nor git repository"))
+ $(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) MV_DDR_PATH=$(MV_DDR_PATH) DDR_TOPOLOGY=$(DDR_TOPOLOGY) mv_ddr
+
+$(BUILD_PLAT)/$(UART_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(DOIMAGETOOL) $(TIMBUILD) $(TIMDDRTOOL)
+ @$(ECHO_BLANK_LINE)
+ @echo "Building uart images"
+ $(Q)mkdir -p $(BUILD_PLAT)/$(BUILD_UART)
+ $(Q)cp -a $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/$(BUILD_UART)/wtmi.bin
+ $(Q)cp -a $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/$(BUILD_UART)/$(BOOT_IMAGE)
+ $(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TIMBUILD) $(TIMBLDUARTARGS)
+ $(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(DOIMAGEUART_CFG)
+ $(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(DOIMAGEUART_CFG)
+ifeq ($(MARVELL_SECURE_BOOT),1)
+ $(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMNUARTCFG)
+ $(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMNUARTCFG)
+endif
+ $(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(DOIMAGETOOL) -r $(DOIMAGEUART_CFG) -v -D
+ifeq ($(MARVELL_SECURE_BOOT),1)
+ $(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(DOIMAGETOOL) -r $(TIMNUARTCFG)
+endif
+ $(Q)tar czf $(BUILD_PLAT)/$(UART_IMAGE) -C $(BUILD_PLAT) $(BUILD_UART)/$(TIM_IMAGE) $(BUILD_UART)/wtmi_h.bin $(BUILD_UART)/boot-image_h.bin
+ @$(ECHO_BLANK_LINE)
+ @echo "Built $@ successfully"
+ @$(ECHO_BLANK_LINE)
+
+$(BUILD_PLAT)/$(FLASH_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(DOIMAGETOOL) $(TIMBUILD) $(TIMDDRTOOL) $(TIM2IMG)
+ @$(ECHO_BLANK_LINE)
+ @echo "Building flash image"
+ $(Q)cd $(BUILD_PLAT) && $(TIMBUILD) $(TIMBLDARGS)
+ $(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(DOIMAGE_CFG)
+ $(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(DOIMAGE_CFG)
+ifeq ($(MARVELL_SECURE_BOOT),1)
+ $(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMNCFG)
+ $(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMNCFG)
+ @$(ECHO_BLANK_LINE)
+ @echo "=======================================================";
+ @echo " Secure boot. Encrypting wtmi and boot-image";
+ @echo "=======================================================";
+ @$(ECHO_BLANK_LINE)
+ $(Q)cp $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/wtmi-align.bin
+ $(Q)truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin
+ $(Q)openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \
+ -out $(BUILD_PLAT)/$(WTMI_ENC_IMG) \
+ -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
+ -iv `cat $(IMAGESPATH)/iv.txt` -p
+ $(Q)truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE);
+ $(Q)openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \
+ -out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \
+ -K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
+ -iv `cat $(IMAGESPATH)/iv.txt` -p
+endif
+ $(Q)cd $(BUILD_PLAT) && $(DOIMAGETOOL) -r $(DOIMAGE_CFG) -v -D
+ifeq ($(MARVELL_SECURE_BOOT),1)
+ $(Q)cd $(BUILD_PLAT) && $(DOIMAGETOOL) -r $(TIMNCFG)
+ $(Q)sed -i 's|wtmi.bin|$(WTMI_ENC_IMG)|1' $(TIMNCFG)
+ $(Q)sed -i 's|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1' $(TIMNCFG)
+endif
+ $(Q)cd $(BUILD_PLAT) && $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE)
+ @$(ECHO_BLANK_LINE)
+ @echo "Built $@ successfully"
+ @$(ECHO_BLANK_LINE)
+
+clean realclean distclean: mrvl_clean
+
+.PHONY: mrvl_clean
+mrvl_clean:
+ -$(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH) MV_DDR_PATH=$(MV_DDR_PATH) clean
+ -$(Q)$(MAKE) --no-print-directory -C $(DOIMAGEPATH)/wtptp/src/TBB_Linux -f TBB_linux.mak clean
+ifdef CRYPTOPP_PATH
+ -$(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile clean
+endif
+
+else # WTP
+
+$(BUILD_PLAT)/$(UART_IMAGE) $(BUILD_PLAT)/$(FLASH_IMAGE):
+ $(error "Platform '${PLAT}' for target '$@' requires WTP. Please set WTP to point to the right directory")
+
+endif # WTP
+
+.PHONY: mrvl_uart
+mrvl_uart: $(BUILD_PLAT)/$(UART_IMAGE)
diff --git a/plat/marvell/a3700/common/a3700_ea.c b/plat/marvell/armada/a3k/common/a3700_ea.c
index dd46beb55..dd46beb55 100644
--- a/plat/marvell/a3700/common/a3700_ea.c
+++ b/plat/marvell/armada/a3k/common/a3700_ea.c
diff --git a/plat/marvell/a3700/common/a3700_sip_svc.c b/plat/marvell/armada/a3k/common/a3700_sip_svc.c
index e8ac5fc08..e8ac5fc08 100644
--- a/plat/marvell/a3700/common/a3700_sip_svc.c
+++ b/plat/marvell/armada/a3k/common/a3700_sip_svc.c
diff --git a/plat/marvell/a3700/common/aarch64/a3700_common.c b/plat/marvell/armada/a3k/common/aarch64/a3700_common.c
index 63512853c..63512853c 100644
--- a/plat/marvell/a3700/common/aarch64/a3700_common.c
+++ b/plat/marvell/armada/a3k/common/aarch64/a3700_common.c
diff --git a/plat/marvell/a3700/common/aarch64/plat_helpers.S b/plat/marvell/armada/a3k/common/aarch64/plat_helpers.S
index 90d76f08e..90d76f08e 100644
--- a/plat/marvell/a3700/common/aarch64/plat_helpers.S
+++ b/plat/marvell/armada/a3k/common/aarch64/plat_helpers.S
diff --git a/plat/marvell/armada/a3k/common/cm3_system_reset.c b/plat/marvell/armada/a3k/common/cm3_system_reset.c
new file mode 100644
index 000000000..548ff5168
--- /dev/null
+++ b/plat/marvell/armada/a3k/common/cm3_system_reset.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 Marek Behun, CZ.NIC
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <mvebu_def.h>
+
+/* Cortex-M3 Secure Processor Mailbox Registers */
+#define MVEBU_RWTM_PARAM0_REG (MVEBU_RWTM_REG_BASE)
+#define MVEBU_RWTM_CMD_REG (MVEBU_RWTM_REG_BASE + 0x40)
+#define MVEBU_RWTM_HOST_INT_RESET_REG (MVEBU_RWTM_REG_BASE + 0xC8)
+#define MVEBU_RWTM_HOST_INT_MASK_REG (MVEBU_RWTM_REG_BASE + 0xCC)
+#define MVEBU_RWTM_HOST_INT_SP_COMPLETE BIT(0)
+
+#define MVEBU_RWTM_REBOOT_CMD 0x0009
+#define MVEBU_RWTM_REBOOT_MAGIC 0xDEADBEEF
+
+static inline bool rwtm_completed(void)
+{
+ return (mmio_read_32(MVEBU_RWTM_HOST_INT_RESET_REG) &
+ MVEBU_RWTM_HOST_INT_SP_COMPLETE) != 0;
+}
+
+static bool rwtm_wait(int ms)
+{
+ while (ms && !rwtm_completed()) {
+ mdelay(1);
+ --ms;
+ }
+
+ return rwtm_completed();
+}
+
+void cm3_system_reset(void)
+{
+ int tries = 5;
+
+ for (; tries > 0; --tries) {
+ mmio_clrbits_32(MVEBU_RWTM_HOST_INT_RESET_REG,
+ MVEBU_RWTM_HOST_INT_SP_COMPLETE);
+
+ mmio_write_32(MVEBU_RWTM_PARAM0_REG, MVEBU_RWTM_REBOOT_MAGIC);
+ mmio_write_32(MVEBU_RWTM_CMD_REG, MVEBU_RWTM_REBOOT_CMD);
+
+ if (rwtm_wait(10)) {
+ break;
+ }
+
+ mdelay(100);
+ }
+
+ /* If we reach here, the command is not implemented. */
+ ERROR("System reset command not implemented in WTMI firmware!\n");
+}
diff --git a/plat/marvell/a3700/common/dram_win.c b/plat/marvell/armada/a3k/common/dram_win.c
index 694f6d480..e89f29504 100644
--- a/plat/marvell/a3700/common/dram_win.c
+++ b/plat/marvell/armada/a3k/common/dram_win.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Marvell International Ltd.
+ * Copyright (C) 2018-2021 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
@@ -92,33 +92,35 @@ struct cpu_win_configuration mv_cpu_wins[CPU_WIN_CONFIG_MAX][MV_CPU_WIN_NUM] = {
},
/*
- * If total dram size is more than 2GB, now there is only one case - 4GB
- * dram; we will use below cpu windows configurations:
- * - Internal Regs, CCI-400, Boot Rom and PCIe windows are kept as
- * default;
- * - Use 4 CPU decode windows for DRAM, which cover 3.375GB DRAM;
- * DDR window 0 is configured in tim header with 2GB size, no need to
- * configure it again here;
+ * If total DRAM size is more than 2GB, now there is only one case:
+ * 4GB of DRAM; to better utilize address space (for maximization of
+ * DRAM usage), we will use the configuration of CPU windows below:
+ * - Internal Regs and Boot ROM windows are kept as default;
+ * - CCI-400 is moved from its default address to another address
+ * (this is actually done even if DRAM size is not more than 2 GB,
+ * because the firmware is compiled with that address as a
+ * constant);
+ * - PCIe window is moved to another address;
+ * - Use 4 CPU decode windows for DRAM, which cover 3.75GB DRAM;
+ * DDR window 0 is configured in tim header with 2G B size, no need
+ * to configure it again here;
*
- * 0xFFFFFFFF ---> |-----------------------|
- * | Boot ROM | 64KB
+ * 0xFFFFFFFF ---> +-----------------------+
+ * | Boot ROM | 64 KB
* 0xFFF00000 ---> +-----------------------+
* : :
- * 0xF0000000 ---> |-----------------------|
- * | PCIE | 128 MB
- * 0xE8000000 ---> |-----------------------|
- * | DDR window 3 | 128 MB
- * 0xE0000000 ---> +-----------------------+
- * : :
- * 0xD8010000 ---> |-----------------------|
- * | CCI Regs | 64 KB
- * 0xD8000000 ---> +-----------------------+
- * : :
+ * 0xFE010000 ---> +-----------------------+
+ * | CCI Regs | 64 KB
+ * 0xFE000000 ---> +-----------------------+
* : :
+ * 0xFA000000 ---> +-----------------------+
+ * | PCIE | 128 MB
+ * 0xF2000000 ---> +-----------------------+
+ * | DDR window 3 | 512 MB
* 0xD2000000 ---> +-----------------------+
- * | Internal Regs | 32MB
+ * | Internal Regs | 32 MB
* 0xD0000000 ---> |-----------------------|
- * | DDR window 2 | 256 MB
+ * | DDR window 2 | 256 MB
* 0xC0000000 ---> |-----------------------|
* | |
* | DDR window 1 | 1 GB
@@ -155,14 +157,14 @@ struct cpu_win_configuration mv_cpu_wins[CPU_WIN_CONFIG_MAX][MV_CPU_WIN_NUM] = {
0xc0000000},
{CPU_WIN_ENABLED,
CPU_WIN_TARGET_DRAM,
- 0xe0000000,
- 0x08000000,
- 0xe0000000},
+ 0xd2000000,
+ 0x20000000,
+ 0xd2000000},
{CPU_WIN_ENABLED,
CPU_WIN_TARGET_PCIE,
- 0xe8000000,
+ 0xf2000000,
0x08000000,
- 0xe8000000},
+ 0xf2000000},
},
};
diff --git a/plat/marvell/a3700/common/include/a3700_plat_def.h b/plat/marvell/armada/a3k/common/include/a3700_plat_def.h
index c7f40adc3..83d95616b 100644
--- a/plat/marvell/a3700/common/include/a3700_plat_def.h
+++ b/plat/marvell/armada/a3k/common/include/a3700_plat_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Marvell International Ltd.
+ * Copyright (C) 2018-2021 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
@@ -41,8 +41,14 @@
#define MVEBU_GICR_BASE 0x1D40000
#define MVEBU_GICC_BASE 0x1D80000
-/* CCI-400 */
-#define MVEBU_CCI_BASE 0x8000000
+/*
+ * CCI-400 base address
+ * This address is absolute, not relative to MVEBU_REGS_BASE.
+ * This is not the default CCI base address (that would be 0xD8000000).
+ * Rather we remap CCI to this address to better utilize the address space.
+ * (The remapping is done in plat/marvell/armada/a3k/common/plat_cci.c)
+ */
+#define MVEBU_CCI_BASE 0xFE000000
/*****************************************************************************
* North and south bridge register base
@@ -119,4 +125,10 @@
*/
#define MVEBU_COMPHY_REG_BASE (MVEBU_REGS_BASE + 0x18300)
+/*****************************************************************************
+ * Cortex-M3 Secure Processor Mailbox constants
+ *****************************************************************************
+ */
+#define MVEBU_RWTM_REG_BASE (MVEBU_REGS_BASE + 0xB0000)
+
#endif /* A3700_PLAT_DEF_H */
diff --git a/plat/marvell/a3700/common/include/a3700_pm.h b/plat/marvell/armada/a3k/common/include/a3700_pm.h
index cc6cf436a..44dbb9f7d 100644
--- a/plat/marvell/a3700/common/include/a3700_pm.h
+++ b/plat/marvell/armada/a3k/common/include/a3700_pm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Marvell International Ltd.
+ * Copyright (C) 2016-2020 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
@@ -48,4 +48,6 @@ struct pm_wake_up_src_config {
struct pm_wake_up_src_config *mv_wake_up_src_config_get(void);
+void cm3_system_reset(void);
+
#endif /* A3700_PM_H */
diff --git a/plat/marvell/a3700/common/include/ddr_info.h b/plat/marvell/armada/a3k/common/include/ddr_info.h
index 254f78c1b..254f78c1b 100644
--- a/plat/marvell/a3700/common/include/ddr_info.h
+++ b/plat/marvell/armada/a3k/common/include/ddr_info.h
diff --git a/plat/marvell/a3700/common/include/dram_win.h b/plat/marvell/armada/a3k/common/include/dram_win.h
index 26a013784..26a013784 100644
--- a/plat/marvell/a3700/common/include/dram_win.h
+++ b/plat/marvell/armada/a3k/common/include/dram_win.h
diff --git a/plat/marvell/a3700/common/include/io_addr_dec.h b/plat/marvell/armada/a3k/common/include/io_addr_dec.h
index 42ef30bc2..42ef30bc2 100644
--- a/plat/marvell/a3700/common/include/io_addr_dec.h
+++ b/plat/marvell/armada/a3k/common/include/io_addr_dec.h
diff --git a/plat/marvell/a3700/common/include/plat_macros.S b/plat/marvell/armada/a3k/common/include/plat_macros.S
index f689b4f39..f689b4f39 100644
--- a/plat/marvell/a3700/common/include/plat_macros.S
+++ b/plat/marvell/armada/a3k/common/include/plat_macros.S
diff --git a/plat/marvell/a3700/common/include/platform_def.h b/plat/marvell/armada/a3k/common/include/platform_def.h
index e6660d407..057ee2eb9 100644
--- a/plat/marvell/a3700/common/include/platform_def.h
+++ b/plat/marvell/armada/a3k/common/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016-2019 Marvell International Ltd.
+ * Copyright (C) 2016-2021 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
@@ -70,6 +70,14 @@
* PLAT_MARVELL_FIP_BASE = 0x4120000
*/
+/*
+ * Since BL33 is loaded by BL2 (and validated by BL31) to DRAM offset 0,
+ * it is allowed to load/copy images to 'NULL' pointers
+ */
+#if defined(IMAGE_BL2) || defined(IMAGE_BL31)
+#define PLAT_ALLOW_ZERO_ADDR_COPY
+#endif
+
#define PLAT_MARVELL_ATF_BASE 0x4000000
#define PLAT_MARVELL_ATF_LOAD_ADDR \
(PLAT_MARVELL_ATF_BASE + 0x100000)
@@ -81,11 +89,13 @@
#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2)
/* DRAM[2MB..66MB] is used as Trusted ROM */
#define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR
-/* 64 MB TODO: reduce this to minimum needed according to fip image size*/
-#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000
-/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */
-#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000
-#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */
+/* 4 MB for FIP image */
+#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x00400000
+/* Reserve 12M for SCP (Secure PayLoad) Trusted RAM
+ * OP-TEE SHMEM follows this region
+ */
+#define PLAT_MARVELL_TRUSTED_RAM_BASE 0x04400000
+#define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x00C00000 /* 12 MB DRAM */
/*
* PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
@@ -138,7 +148,7 @@
#define PLAT_MARVELL_SHARED_RAM_CACHED 1
/* CCI related constants */
-#define PLAT_MARVELL_CCI_BASE (MVEBU_REGS_BASE + MVEBU_CCI_BASE)
+#define PLAT_MARVELL_CCI_BASE MVEBU_CCI_BASE
#define PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX 3
#define PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX 4
@@ -169,8 +179,7 @@
#define PLAT_MARVELL_NSTIMER_FRAME_ID 1
/* Mailbox base address */
-#define PLAT_MARVELL_MAILBOX_BASE \
- (MARVELL_TRUSTED_SRAM_BASE + 0x400)
+#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_SHARED_RAM_BASE + 0x400)
#define PLAT_MARVELL_MAILBOX_SIZE 0x100
#define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */
@@ -218,15 +227,9 @@
#define CPU_DEC_RLR_REMAP_LOW_MASK \
(0xffff << CPU_DEC_BR_BASE_OFFS)
+#define CPU_DEC_CCI_BASE_REG (MVEBU_CPU_DEC_WIN_REG_BASE + 0xe0)
+
/* Securities */
#define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER
-#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE
-#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE
-
-#ifdef BL32
-#define BL32_BASE TRUSTED_DRAM_BASE
-#define BL32_LIMIT TRUSTED_DRAM_SIZE
-#endif
-
#endif /* PLATFORM_DEF_H */
diff --git a/plat/marvell/a3700/common/io_addr_dec.c b/plat/marvell/armada/a3k/common/io_addr_dec.c
index b27633cf2..b27633cf2 100644
--- a/plat/marvell/a3700/common/io_addr_dec.c
+++ b/plat/marvell/armada/a3k/common/io_addr_dec.c
diff --git a/plat/marvell/a3700/common/marvell_plat_config.c b/plat/marvell/armada/a3k/common/marvell_plat_config.c
index 3bf3d96bd..3bf3d96bd 100644
--- a/plat/marvell/a3700/common/marvell_plat_config.c
+++ b/plat/marvell/armada/a3k/common/marvell_plat_config.c
diff --git a/plat/marvell/armada/a3k/common/plat_cci.c b/plat/marvell/armada/a3k/common/plat_cci.c
new file mode 100644
index 000000000..56f091fef
--- /dev/null
+++ b/plat/marvell/armada/a3k/common/plat_cci.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 Marek Behun <marek.behun@nic.cz>
+ *
+ * Based on plat/marvell/armada/common/marvell_cci.c
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <drivers/arm/cci.h>
+#include <lib/mmio.h>
+
+#include <plat_marvell.h>
+
+static const int cci_map[] = {
+ PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX,
+ PLAT_MARVELL_CCI_CLUSTER1_SL_IFACE_IX
+};
+
+/*
+ * This redefines the weak definition in
+ * plat/marvell/armada/common/marvell_cci.c
+ */
+void plat_marvell_interconnect_init(void)
+{
+ /*
+ * To better utilize the address space, we remap CCI base address from
+ * the default (0xD8000000) to MVEBU_CCI_BASE.
+ * This has to be done here, rather than in cpu_wins_init(), because
+ * cpu_wins_init() is called later.
+ */
+ mmio_write_32(CPU_DEC_CCI_BASE_REG, MVEBU_CCI_BASE >> 20);
+
+ cci_init(PLAT_MARVELL_CCI_BASE, cci_map, ARRAY_SIZE(cci_map));
+}
diff --git a/plat/marvell/a3700/common/plat_pm.c b/plat/marvell/armada/a3k/common/plat_pm.c
index f8ce6fe29..2bae37e3f 100644
--- a/plat/marvell/a3700/common/plat_pm.c
+++ b/plat/marvell/armada/a3k/common/plat_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Marvell International Ltd.
+ * Copyright (C) 2018-2020 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
@@ -763,6 +763,11 @@ static void __dead2 a3700_system_off(void)
panic();
}
+#pragma weak cm3_system_reset
+void cm3_system_reset(void)
+{
+}
+
/*****************************************************************************
* A3700 handlers to reset the system
*****************************************************************************
@@ -780,6 +785,9 @@ static void __dead2 a3700_system_reset(void)
2 * sizeof(uint64_t));
#endif
+ /* Use Cortex-M3 secure coprocessor for system reset */
+ cm3_system_reset();
+
/* Trigger the warm reset */
mmio_write_32(MVEBU_WARM_RESET_REG, MVEBU_WARM_RESET_MAGIC);
diff --git a/plat/marvell/a8k/a70x0/board/dram_port.c b/plat/marvell/armada/a8k/a70x0/board/dram_port.c
index 4fca7e383..355770b65 100644
--- a/plat/marvell/a8k/a70x0/board/dram_port.c
+++ b/plat/marvell/armada/a8k/a70x0/board/dram_port.c
@@ -46,6 +46,7 @@ static struct mv_ddr_topology_map board_topology_map = {
MV_DDR_TEMP_LOW} }, /* temperature */
MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
+ NOT_COMBINED, /* ddr twin-die combined*/
{ {0} }, /* raw spd data */
{0}, /* timing parameters */
{ /* electrical configuration */
diff --git a/plat/marvell/a8k/a70x0/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c
index d126f5567..a40926102 100644
--- a/plat/marvell/a8k/a70x0/board/marvell_plat_config.c
+++ b/plat/marvell/armada/a8k/a70x0/board/marvell_plat_config.c
@@ -102,6 +102,12 @@ struct addr_map_win ccu_memory_map[] = { /* IO window */
#ifdef IMAGE_BLE
{0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */
#else
+#if LLC_SRAM
+ /* This entry is prepared for OP-TEE OS that enables the LLC SRAM
+ * and changes the window target to SRAM_TID.
+ */
+ {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, DRAM_0_TID},
+#endif
{0x00000000f2000000, 0xe000000, IO_0_TID},
{0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */
{0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */
diff --git a/plat/marvell/a8k/a70x0/mvebu_def.h b/plat/marvell/armada/a8k/a70x0/mvebu_def.h
index 72bca12e3..72bca12e3 100644
--- a/plat/marvell/a8k/a70x0/mvebu_def.h
+++ b/plat/marvell/armada/a8k/a70x0/mvebu_def.h
diff --git a/plat/marvell/a8k/a70x0_amc/platform.mk b/plat/marvell/armada/a8k/a70x0/platform.mk
index d3a01676e..39eb71254 100644
--- a/plat/marvell/a8k/a70x0_amc/platform.mk
+++ b/plat/marvell/armada/a8k/a70x0/platform.mk
@@ -14,6 +14,7 @@ DOIMAGE_SEC := tools/doimage/secure/sec_img_7K.cfg
MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c
-include plat/marvell/a8k/common/a8k_common.mk
+BOARD_DIR := $(shell dirname $(lastword $(MAKEFILE_LIST)))
+include plat/marvell/armada/a8k/common/a8k_common.mk
-include plat/marvell/common/marvell_common.mk
+include plat/marvell/armada/common/marvell_common.mk
diff --git a/plat/marvell/a8k/a70x0_amc/board/dram_port.c b/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c
index aecf6c567..9c8c97e09 100644
--- a/plat/marvell/a8k/a70x0_amc/board/dram_port.c
+++ b/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c
@@ -46,6 +46,7 @@ static struct mv_ddr_topology_map board_topology_map = {
MV_DDR_TEMP_LOW} }, /* temperature */
MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
+ NOT_COMBINED, /* ddr twin-die combined*/
{ {0} }, /* raw spd data */
{0}, /* timing parameters */
{ /* electrical configuration */
diff --git a/plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c
index f8a1c40be..3b68e91ba 100644
--- a/plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c
+++ b/plat/marvell/armada/a8k/a70x0_amc/board/marvell_plat_config.c
@@ -93,6 +93,12 @@ struct addr_map_win ccu_memory_map[] = {
#ifdef IMAGE_BLE
{0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */
#else
+#if LLC_SRAM
+ /* This entry is prepared for OP-TEE OS that enables the LLC SRAM
+ * and changes the window target to SRAM_TID.
+ */
+ {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, DRAM_0_TID},
+#endif
{0x00000000f2000000, 0xe000000, IO_0_TID},
{0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */
{0x0000000800000000, 0x200000000, IO_0_TID}, /* IO window */
diff --git a/plat/marvell/a8k/a70x0_amc/mvebu_def.h b/plat/marvell/armada/a8k/a70x0_amc/mvebu_def.h
index cedf3239a..cedf3239a 100644
--- a/plat/marvell/a8k/a70x0_amc/mvebu_def.h
+++ b/plat/marvell/armada/a8k/a70x0_amc/mvebu_def.h
diff --git a/plat/marvell/a8k/a70x0/platform.mk b/plat/marvell/armada/a8k/a70x0_amc/platform.mk
index d3a01676e..39eb71254 100644
--- a/plat/marvell/a8k/a70x0/platform.mk
+++ b/plat/marvell/armada/a8k/a70x0_amc/platform.mk
@@ -14,6 +14,7 @@ DOIMAGE_SEC := tools/doimage/secure/sec_img_7K.cfg
MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c
-include plat/marvell/a8k/common/a8k_common.mk
+BOARD_DIR := $(shell dirname $(lastword $(MAKEFILE_LIST)))
+include plat/marvell/armada/a8k/common/a8k_common.mk
-include plat/marvell/common/marvell_common.mk
+include plat/marvell/armada/common/marvell_common.mk
diff --git a/plat/marvell/a8k/a80x0/board/dram_port.c b/plat/marvell/armada/a8k/a80x0/board/dram_port.c
index 02f4ffb0a..381c87150 100644
--- a/plat/marvell/a8k/a80x0/board/dram_port.c
+++ b/plat/marvell/armada/a8k/a80x0/board/dram_port.c
@@ -52,8 +52,13 @@ static struct mv_ddr_topology_map board_topology_map = {
MV_DDR_FREQ_SAR, /* frequency */
0, 0, /* cas_l, cas_wl */
MV_DDR_TEMP_LOW} }, /* temperature */
+#if DDR32
+ MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
+#else
MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
+#endif
MV_DDR_CFG_SPD, /* ddr configuration data source */
+ NOT_COMBINED, /* ddr twin-die combined*/
{ {0} }, /* raw spd data */
{0}, /* timing parameters */
{ /* electrical configuration */
diff --git a/plat/marvell/a8k/a80x0/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c
index 7901dd225..4ccda14e9 100644
--- a/plat/marvell/a8k/a80x0/board/marvell_plat_config.c
+++ b/plat/marvell/armada/a8k/a80x0/board/marvell_plat_config.c
@@ -131,6 +131,12 @@ struct addr_map_win ccu_memory_map[] = {
#ifdef IMAGE_BLE
{0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */
#else
+#if LLC_SRAM
+ /* This entry is prepared for OP-TEE OS that enables the LLC SRAM
+ * and changes the window target to SRAM_TID.
+ */
+ {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, DRAM_0_TID},
+#endif
{0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */
{0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */
{0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */
diff --git a/plat/marvell/a8k/a80x0/board/phy-porting-layer.h b/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h
index abd85b5d2..afa3be158 100644
--- a/plat/marvell/a8k/a80x0/board/phy-porting-layer.h
+++ b/plat/marvell/armada/a8k/a80x0/board/phy-porting-layer.h
@@ -92,6 +92,7 @@ static const struct sata_params
.g3_rx_selmupf = 0x2,
.g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0,
.g3_rx_selmupi = 0x2,
+ .polarity_invert = COMPHY_POLARITY_NO_INVERT,
.valid = 0x1
}, /* Comphy1 */
{ 0 }, /* Comphy2 */
@@ -116,6 +117,7 @@ static const struct sata_params
.g3_rx_selmupf = 0x2,
.g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0,
.g3_rx_selmupi = 0x2,
+ .polarity_invert = COMPHY_POLARITY_NO_INVERT,
.valid = 0x1
}, /* Comphy3 */
{ 0 }, /* Comphy4 */
@@ -146,6 +148,7 @@ static const struct sata_params
.g3_rx_selmupf = 0x2,
.g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0,
.g3_rx_selmupi = 0x2,
+ .polarity_invert = COMPHY_POLARITY_NO_INVERT,
.valid = 0x1
}, /* Comphy1 */
{ 0 }, /* Comphy2 */
@@ -170,6 +173,7 @@ static const struct sata_params
.g3_rx_selmupf = 0x2,
.g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0,
.g3_rx_selmupi = 0x2,
+ .polarity_invert = COMPHY_POLARITY_NO_INVERT,
.valid = 0x1
}, /* Comphy3 */
{ 0 }, /* Comphy4 */
@@ -178,4 +182,11 @@ static const struct sata_params
},
},
};
+
+static const struct usb_params
+ usb_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = {
+ [0 ... AP_NUM-1][0 ... CP_NUM-1][0 ... MAX_LANE_NR-1] = {
+ .polarity_invert = COMPHY_POLARITY_NO_INVERT
+ },
+};
#endif /* PHY_PORTING_LAYER_H */
diff --git a/plat/marvell/a8k/a80x0/mvebu_def.h b/plat/marvell/armada/a8k/a80x0/mvebu_def.h
index 3fa119af6..3fa119af6 100644
--- a/plat/marvell/a8k/a80x0/mvebu_def.h
+++ b/plat/marvell/armada/a8k/a80x0/mvebu_def.h
diff --git a/plat/marvell/a8k/a80x0/platform.mk b/plat/marvell/armada/a8k/a80x0/platform.mk
index 00d24b278..115dd4a82 100644
--- a/plat/marvell/a8k/a80x0/platform.mk
+++ b/plat/marvell/armada/a8k/a80x0/platform.mk
@@ -14,7 +14,7 @@ DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg
MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c
-include plat/marvell/a8k/common/a8k_common.mk
+BOARD_DIR := $(shell dirname $(lastword $(MAKEFILE_LIST)))
+include plat/marvell/armada/a8k/common/a8k_common.mk
-include plat/marvell/common/marvell_common.mk
-PLAT_INCLUDES += -Iplat/marvell/a8k/a80x0/board
+include plat/marvell/armada/common/marvell_common.mk
diff --git a/plat/marvell/a8k/a80x0_mcbin/board/dram_port.c b/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c
index 25808523c..50a68b3a2 100644
--- a/plat/marvell/a8k/a80x0_mcbin/board/dram_port.c
+++ b/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c
@@ -48,6 +48,7 @@ static struct mv_ddr_topology_map board_topology_map = {
MV_DDR_TEMP_LOW} }, /* temperature */
MV_DDR_64BIT_BUS_MASK, /* subphys mask */
MV_DDR_CFG_SPD, /* ddr configuration data source */
+ NOT_COMBINED, /* ddr twin-die combined*/
{ {0} }, /* raw spd data */
{0}, /* timing parameters */
{ /* electrical configuration */
diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c
new file mode 100644
index 000000000..75a1b0c30
--- /dev/null
+++ b/plat/marvell/armada/a8k/a80x0_mcbin/board/marvell_plat_config.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <armada_common.h>
+
+/*
+ * If bootrom is currently at BLE there's no need to include the memory
+ * maps structure at this point
+ */
+#include <mvebu_def.h>
+#ifndef IMAGE_BLE
+
+/*****************************************************************************
+ * GPIO Configuration
+ *****************************************************************************
+ */
+#define MPP_CONTROL_REGISTER 0xf2440018
+#define MPP_CONTROL_MPP_SEL_52_MASK 0xf0000
+#define GPIO_DATA_OUT1_REGISTER 0xf2440140
+#define GPIO_DATA_OUT_EN_CTRL1_REGISTER 0xf2440144
+#define GPIO52_MASK 0x100000
+
+/* Reset PCIe via GPIO number 52 */
+int marvell_gpio_config(void)
+{
+ uint32_t reg;
+
+ reg = mmio_read_32(MPP_CONTROL_REGISTER);
+ reg |= MPP_CONTROL_MPP_SEL_52_MASK;
+ mmio_write_32(MPP_CONTROL_REGISTER, reg);
+
+ reg = mmio_read_32(GPIO_DATA_OUT1_REGISTER);
+ reg |= GPIO52_MASK;
+ mmio_write_32(GPIO_DATA_OUT1_REGISTER, reg);
+
+ reg = mmio_read_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER);
+ reg &= ~GPIO52_MASK;
+ mmio_write_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER, reg);
+ udelay(100);
+
+ return 0;
+}
+
+/*****************************************************************************
+ * AMB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win amb_memory_map[] = {
+ /* CP1 SPI1 CS0 Direct Mode access */
+ {0xf900, 0x1000000, AMB_SPI1_CS0_ID},
+};
+
+int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ *win = amb_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(amb_memory_map);
+
+ return 0;
+}
+#endif
+
+/*****************************************************************************
+ * IO WIN Configuration
+ *****************************************************************************
+ */
+struct addr_map_win io_win_memory_map[] = {
+ /* CP1 (MCI0) internal regs */
+ {0x00000000f4000000, 0x2000000, MCI_0_TID},
+#ifndef IMAGE_BLE
+ /* PCIe0-2 and SPI1_CS0 (RUNIT) on CP1*/
+ {0x00000000f9000000, 0x4000000, MCI_0_TID},
+ /* MCI 0 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID},
+ /* MCI 1 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID},
+#endif
+};
+
+uint32_t marvell_get_io_win_gcr_target(int ap_index)
+{
+ return PIDI_TID;
+}
+
+int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = io_win_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(io_win_memory_map);
+
+ return 0;
+}
+
+#ifndef IMAGE_BLE
+/*****************************************************************************
+ * IOB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win iob_memory_map_cp0[] = {
+ /* CP0 */
+ /* PEX1_X1 window */
+ {0x00000000f7000000, 0x1000000, PEX1_TID},
+ /* PEX2_X1 window */
+ {0x00000000f8000000, 0x1000000, PEX2_TID},
+ /* PEX0_X4 window */
+ {0x00000000f6000000, 0x1000000, PEX0_TID},
+ {0x00000000c0000000, 0x30000000, PEX0_TID},
+ {0x0000000800000000, 0x100000000, PEX0_TID},
+};
+
+struct addr_map_win iob_memory_map_cp1[] = {
+ /* CP1 */
+ /* SPI1_CS0 (RUNIT) window */
+ {0x00000000f9000000, 0x1000000, RUNIT_TID},
+ /* PEX1_X1 window */
+ {0x00000000fb000000, 0x1000000, PEX1_TID},
+ /* PEX2_X1 window */
+ {0x00000000fc000000, 0x1000000, PEX2_TID},
+ /* PEX0_X4 window */
+ {0x00000000fa000000, 0x1000000, PEX0_TID}
+};
+
+int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ switch (base) {
+ case MVEBU_CP_REGS_BASE(0):
+ *win = iob_memory_map_cp0;
+ *size = ARRAY_SIZE(iob_memory_map_cp0);
+ return 0;
+ case MVEBU_CP_REGS_BASE(1):
+ *win = iob_memory_map_cp1;
+ *size = ARRAY_SIZE(iob_memory_map_cp1);
+ return 0;
+ default:
+ *size = 0;
+ *win = 0;
+ return 1;
+ }
+}
+#endif
+
+/*****************************************************************************
+ * CCU Configuration
+ *****************************************************************************
+ */
+struct addr_map_win ccu_memory_map[] = {
+#ifdef IMAGE_BLE
+ {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */
+#else
+#if LLC_SRAM
+ /* This entry is prepared for OP-TEE OS that enables the LLC SRAM
+ * and changes the window target to SRAM_TID.
+ */
+ {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, DRAM_0_TID},
+#endif
+ {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */
+ {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */
+ {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */
+#endif
+};
+
+uint32_t marvell_get_ccu_gcr_target(int ap)
+{
+ return DRAM_0_TID;
+}
+
+int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = ccu_memory_map;
+ *size = ARRAY_SIZE(ccu_memory_map);
+
+ return 0;
+}
+
+/* In reference to #ifndef IMAGE_BLE, this part is used for BLE only. */
+
+/*****************************************************************************
+ * SKIP IMAGE Configuration
+ *****************************************************************************
+ */
+void *plat_marvell_get_skip_image_data(void)
+{
+ /* No recovery button on A8k-MCBIN board */
+ return NULL;
+}
diff --git a/plat/marvell/a8k/a80x0_mcbin/mvebu_def.h b/plat/marvell/armada/a8k/a80x0_mcbin/mvebu_def.h
index 3fa119af6..3fa119af6 100644
--- a/plat/marvell/a8k/a80x0_mcbin/mvebu_def.h
+++ b/plat/marvell/armada/a8k/a80x0_mcbin/mvebu_def.h
diff --git a/plat/marvell/a8k/a80x0_mcbin/platform.mk b/plat/marvell/armada/a8k/a80x0_mcbin/platform.mk
index 3749c3781..115dd4a82 100644
--- a/plat/marvell/a8k/a80x0_mcbin/platform.mk
+++ b/plat/marvell/armada/a8k/a80x0_mcbin/platform.mk
@@ -14,6 +14,7 @@ DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg
MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c
-include plat/marvell/a8k/common/a8k_common.mk
+BOARD_DIR := $(shell dirname $(lastword $(MAKEFILE_LIST)))
+include plat/marvell/armada/a8k/common/a8k_common.mk
-include plat/marvell/common/marvell_common.mk
+include plat/marvell/armada/common/marvell_common.mk
diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c b/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c
new file mode 100644
index 000000000..3879c983a
--- /dev/null
+++ b/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/mentor/mi2cv.h>
+#include <lib/mmio.h>
+
+#include <mv_ddr_if.h>
+#include <mvebu_def.h>
+#include <plat_marvell.h>
+
+#define MVEBU_AP_MPP_CTRL0_7_REG MVEBU_AP_MPP_REGS(0)
+#define MVEBU_AP_MPP_CTRL4_OFFS 16
+#define MVEBU_AP_MPP_CTRL5_OFFS 20
+#define MVEBU_AP_MPP_CTRL4_I2C0_SDA_ENA 0x3
+#define MVEBU_AP_MPP_CTRL5_I2C0_SCK_ENA 0x3
+
+#define MVEBU_CP_MPP_CTRL37_OFFS 20
+#define MVEBU_CP_MPP_CTRL38_OFFS 24
+#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2
+#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2
+
+#define MVEBU_MPP_CTRL_MASK 0xf
+
+/*
+ * This struct provides the DRAM training code with
+ * the appropriate board DRAM configuration
+ */
+static struct mv_ddr_topology_map board_topology_map = {
+ /* Board with 1CS 8Gb x4 devices of Micron 2400T */
+ DEBUG_LEVEL_ERROR,
+ 0x1, /* active interfaces */
+ /* cs_mask, mirror, dqs_swap, ck_swap X subphys */
+ { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0} },
+ /* TODO: double check if the speed bin is 2400T */
+ SPEED_BIN_DDR_2400T, /* speed_bin */
+ MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */
+ MV_DDR_DIE_CAP_8GBIT, /* die capacity */
+ MV_DDR_FREQ_SAR, /* frequency */
+ 0, 0, /* cas_l, cas_wl */
+ MV_DDR_TEMP_LOW} }, /* temperature */
+ MV_DDR_64BIT_BUS_MASK, /* subphys mask */
+ MV_DDR_CFG_SPD, /* ddr configuration data source */
+ NOT_COMBINED, /* ddr twin-die combined*/
+ { {0} }, /* raw spd data */
+ {0}, /* timing parameters */
+ { /* electrical configuration */
+ { /* memory electrical configuration */
+ MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */
+ {
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */
+ },
+ {
+ MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */
+ MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */
+ },
+ MV_DDR_DIC_RZQ_DIV7 /* dic */
+ },
+ { /* phy electrical configuration */
+ MV_DDR_OHM_30, /* data_drv_p */
+ MV_DDR_OHM_30, /* data_drv_n */
+ MV_DDR_OHM_30, /* ctrl_drv_p */
+ MV_DDR_OHM_30, /* ctrl_drv_n */
+ {
+ MV_DDR_OHM_60, /* odt_p 1cs */
+ MV_DDR_OHM_120 /* odt_p 2cs */
+ },
+ {
+ MV_DDR_OHM_60, /* odt_n 1cs */
+ MV_DDR_OHM_120 /* odt_n 2cs */
+ },
+ },
+ { /* mac electrical configuration */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */
+ MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */
+ },
+ }
+};
+
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
+{
+ /* Return the board topology as defined in the board code */
+ return &board_topology_map;
+}
+
+static void mpp_config(void)
+{
+ uint32_t val;
+ uintptr_t reg;
+
+ /* configure ap mmps 4, 5 to I2C */
+ reg = MVEBU_AP_MPP_CTRL0_7_REG;
+
+ val = mmio_read_32(reg);
+ val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_AP_MPP_CTRL4_OFFS) |
+ (MVEBU_MPP_CTRL_MASK << MVEBU_AP_MPP_CTRL5_OFFS));
+ val |= ((MVEBU_AP_MPP_CTRL4_I2C0_SDA_ENA << MVEBU_AP_MPP_CTRL4_OFFS) |
+ (MVEBU_AP_MPP_CTRL5_I2C0_SCK_ENA << MVEBU_AP_MPP_CTRL5_OFFS));
+
+ mmio_write_32(reg, val);
+}
+
+/*
+ * This function may modify the default DRAM parameters
+ * based on information received from SPD or bootloader
+ * configuration located on non volatile storage
+ */
+void plat_marvell_dram_update_topology(void)
+{
+ struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+ INFO("Gathering DRAM information\n");
+
+ if (tm->cfg_src == MV_DDR_CFG_SPD) {
+ /* configure MPPs to enable i2c */
+ mpp_config();
+ /* initialize the MVEBU_AP_I2C_BASE I2C bus */
+ i2c_init((void *)MVEBU_AP_I2C_BASE);
+ /* select SPD memory page 0 to access DRAM configuration */
+ i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1);
+ /* read data from spd */
+ i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes,
+ sizeof(tm->spd_data.all_bytes));
+ }
+}
diff --git a/plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a80x0_puzzle/board/marvell_plat_config.c
index fa4e144c9..0edc97745 100644
--- a/plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c
+++ b/plat/marvell/armada/a8k/a80x0_puzzle/board/marvell_plat_config.c
@@ -165,6 +165,9 @@ struct addr_map_win ccu_memory_map[] = {
#ifdef IMAGE_BLE
{0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */
#else
+#if LLC_SRAM
+ {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, SRAM_TID},
+#endif
{0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */
{0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */
{0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */
diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c b/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c
new file mode 100644
index 000000000..5147dd519
--- /dev/null
+++ b/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2020 Sartura Ltd.
+ * Author: Luka Kovacic <luka.kovacic@sartura.hr>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <armada_common.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <drivers/console.h>
+#include <plat_marvell.h>
+
+/*****************************************************************************
+ * Platform specific power off functions
+ * Power off PSU / Send command to power management MCU / ...
+ *****************************************************************************
+ */
+
+unsigned char add_xor_checksum(unsigned char *buf, unsigned char xor_len)
+{
+ unsigned char xor_sum = 0;
+ unsigned int i;
+
+ for (i = 0; i < xor_len; i++)
+ xor_sum ^= buf[i];
+
+ return xor_sum;
+}
+
+int system_power_off(void)
+{
+ static console_t console;
+
+ /* WT61P803 MCU system_off_now command */
+ unsigned char system_off_now[4] = { '@', 'C', '0' };
+ int i, len;
+
+ len = sizeof(system_off_now);
+ system_off_now[len - 1] = add_xor_checksum(system_off_now, len);
+
+ console_16550_register(PLAT_MARVELL_BOOT_UART_BASE + 0x100,
+ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, 115200, &console);
+
+ /* Send system_off_now to console */
+ for (i = 0; i < len; i++) {
+ console.putc(system_off_now[i], &console);
+ udelay(1000);
+ }
+
+ console.flush(&console);
+ (void)console_unregister(&console);
+
+ mdelay(100);
+
+ return 0;
+}
diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/mvebu_def.h b/plat/marvell/armada/a8k/a80x0_puzzle/mvebu_def.h
new file mode 100644
index 000000000..3fa119af6
--- /dev/null
+++ b/plat/marvell/armada/a8k/a80x0_puzzle/mvebu_def.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef MVEBU_DEF_H
+#define MVEBU_DEF_H
+
+#include <a8k_plat_def.h>
+
+#define CP_COUNT 2 /* A80x0 has both CP0 & CP1 */
+#define I2C_SPD_ADDR 0x53 /* Access SPD data */
+#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */
+
+#endif /* MVEBU_DEF_H */
diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/platform.mk b/plat/marvell/armada/a8k/a80x0_puzzle/platform.mk
new file mode 100644
index 000000000..3378d53d7
--- /dev/null
+++ b/plat/marvell/armada/a8k/a80x0_puzzle/platform.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+PCI_EP_SUPPORT := 0
+
+CP_NUM := 2
+$(eval $(call add_define,CP_NUM))
+
+DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg
+
+MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c
+
+BOARD_DIR := $(shell dirname $(lastword $(MAKEFILE_LIST)))
+include plat/marvell/armada/a8k/common/a8k_common.mk
+
+include plat/marvell/armada/common/marvell_common.mk
diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk
index bf79ebeec..63cfce22c 100644
--- a/plat/marvell/a8k/common/a8k_common.mk
+++ b/plat/marvell/armada/a8k/common/a8k_common.mk
@@ -1,17 +1,14 @@
#
-# Copyright (C) 2016 - 2018 Marvell International Ltd.
+# Copyright (C) 2016 - 2020 Marvell International Ltd.
#
# SPDX-License-Identifier: BSD-3-Clause
# https://spdx.org/licenses
-include tools/marvell/doimage/doimage.mk
-
PLAT_FAMILY := a8k
-PLAT_FAMILY_BASE := plat/marvell/$(PLAT_FAMILY)
-PLAT_INCLUDE_BASE := include/plat/marvell/$(PLAT_FAMILY)
-PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common
+PLAT_INCLUDE_BASE := include/plat/marvell/armada/$(PLAT_FAMILY)
+PLAT_COMMON_BASE := plat/marvell/armada/a8k/common
MARVELL_DRV_BASE := drivers/marvell
-MARVELL_COMMON_BASE := plat/marvell/common
+MARVELL_COMMON_BASE := plat/marvell/armada/common
MARVELL_SVC_TEST := 0
$(eval $(call add_define,MARVELL_SVC_TEST))
@@ -22,7 +19,7 @@ ERRATA_A72_859971 := 1
MSS_SUPPORT := 1
# Disable EL3 cache for power management
-BL31_CACHE_DISABLE := 1
+BL31_CACHE_DISABLE := 0
$(eval $(call add_define,BL31_CACHE_DISABLE))
$(eval $(call add_define,PCI_EP_SUPPORT))
@@ -34,11 +31,41 @@ $(eval $(call add_define,AP_NUM))
DOIMAGEPATH ?= tools/marvell/doimage
DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage
+include plat/marvell/marvell.mk
+include tools/marvell/doimage/doimage.mk
+
+ifeq (${MARVELL_SECURE_BOOT},1)
+DOIMAGE_SEC_FLAGS := -c $(DOIMAGE_SEC)
+DOIMAGE_LIBS_CHECK = \
+ if ! [ -d "/usr/include/mbedtls" ]; then \
+ echo "****************************************" >&2; \
+ echo "Missing mbedTLS installation! " >&2; \
+ echo "Please download it from \"tls.mbed.org\"" >&2; \
+ echo "Alternatively on Debian/Ubuntu system install" >&2; \
+ echo "\"libmbedtls-dev\" package" >&2; \
+ echo "Make sure to use version 2.1.0 or later" >&2; \
+ echo "****************************************" >&2; \
+ exit 1; \
+ else if ! [ -f "/usr/include/libconfig.h" ]; then \
+ echo "********************************************************" >&2; \
+ echo "Missing Libconfig installation!" >&2; \
+ echo "Please download it from \"www.hyperrealm.com/libconfig/\"" >&2; \
+ echo "Alternatively on Debian/Ubuntu system install packages" >&2; \
+ echo "\"libconfig8\" and \"libconfig8-dev\"" >&2; \
+ echo "********************************************************" >&2; \
+ exit 1; \
+ fi \
+ fi
+else #MARVELL_SECURE_BOOT
+DOIMAGE_LIBS_CHECK =
+DOIMAGE_SEC_FLAGS =
+endif #MARVELL_SECURE_BOOT
+
ROM_BIN_EXT ?= $(BUILD_PLAT)/ble.bin
DOIMAGE_FLAGS += -b $(ROM_BIN_EXT) $(NAND_DOIMAGE_FLAGS) $(DOIMAGE_SEC_FLAGS)
# Check whether to build system_power.c for the platform
-ifneq ("$(wildcard $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c)","")
+ifneq ("$(wildcard $(BOARD_DIR)/board/system_power.c)","")
SYSTEM_POWER_SUPPORT = 1
else
SYSTEM_POWER_SUPPORT = 0
@@ -52,15 +79,16 @@ MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
drivers/arm/gic/v2/gicv2_helpers.c \
plat/common/plat_gicv2.c
-PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \
+PLAT_INCLUDES := -I$(BOARD_DIR) \
+ -I$(BOARD_DIR)/board \
-I$(PLAT_COMMON_BASE)/include \
-I$(PLAT_INCLUDE_BASE)/common
PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a8k_common.c \
drivers/ti/uart/aarch64/16550_console.S
-BLE_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/dram_port.c \
- $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c
+BLE_PORTING_SOURCES := $(BOARD_DIR)/board/dram_port.c \
+ $(BOARD_DIR)/board/marvell_plat_config.c
MARVELL_MOCHI_DRV += $(MARVELL_DRV_BASE)/mochi/cp110_setup.c
@@ -85,12 +113,13 @@ MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \
$(MARVELL_DRV_BASE)/ccu.c \
$(MARVELL_DRV_BASE)/cache_llc.c \
$(MARVELL_DRV_BASE)/comphy/phy-comphy-cp110.c \
- $(MARVELL_DRV_BASE)/mc_trustzone/mc_trustzone.c
+ $(MARVELL_DRV_BASE)/mc_trustzone/mc_trustzone.c \
+ $(MARVELL_DRV_BASE)/mg_conf_cm3/mg_conf_cm3.c
-BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c
+BL31_PORTING_SOURCES := $(BOARD_DIR)/board/marvell_plat_config.c
ifeq ($(SYSTEM_POWER_SUPPORT),1)
-BL31_PORTING_SOURCES += $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c
+BL31_PORTING_SOURCES += $(BOARD_DIR)/board/system_power.c
endif
BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \
@@ -123,8 +152,21 @@ BLE_PATH ?= $(PLAT_COMMON_BASE)/ble
include ${BLE_PATH}/ble.mk
$(eval $(call MAKE_BL,e))
-mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} ${BUILD_PLAT}/ble.bin
- $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin)
- $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE})
- ${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE}
+clean realclean distclean: mrvl_clean
+
+.PHONY: mrvl_clean
+mrvl_clean:
+ @echo " Doimage CLEAN"
+ ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${DOIMAGEPATH} clean
+
+${DOIMAGETOOL}: FORCE
+ @$(DOIMAGE_LIBS_CHECK)
+ ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH}
+${BUILD_PLAT}/${FLASH_IMAGE}: ${ROM_BIN_EXT} ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL}
+ @${ECHO_BLANK_LINE}
+ @echo "Building flash image"
+ ${Q}${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE}
+ @${ECHO_BLANK_LINE}
+ @echo "Built $@ successfully"
+ @${ECHO_BLANK_LINE}
diff --git a/plat/marvell/a8k/common/aarch64/a8k_common.c b/plat/marvell/armada/a8k/common/aarch64/a8k_common.c
index 7c2bf318f..4332a76ea 100644
--- a/plat/marvell/a8k/common/aarch64/a8k_common.c
+++ b/plat/marvell/armada/a8k/common/aarch64/a8k_common.c
@@ -18,22 +18,27 @@
*/
#if IMAGE_BL1
const mmap_region_t plat_marvell_mmap[] = {
- MARVELL_MAP_SHARED_RAM,
+ MARVELL_MAP_SECURE_RAM,
MAP_DEVICE0,
{0}
};
#endif
#if IMAGE_BL2
const mmap_region_t plat_marvell_mmap[] = {
- MARVELL_MAP_SHARED_RAM,
+ MARVELL_MAP_SECURE_RAM,
MAP_DEVICE0,
MARVELL_MAP_DRAM,
+#ifdef SPD_opteed
+ MARVELL_MAP_OPTEE_CORE_MEM,
+ MARVELL_OPTEE_PAGEABLE_LOAD_MEM,
+#endif
{0}
};
#endif
#if IMAGE_BL2U
const mmap_region_t plat_marvell_mmap[] = {
+ MARVELL_MAP_SECURE_RAM,
MAP_DEVICE0,
{0}
};
@@ -48,7 +53,7 @@ const mmap_region_t plat_marvell_mmap[] = {
#if IMAGE_BL31
const mmap_region_t plat_marvell_mmap[] = {
- MARVELL_MAP_SHARED_RAM,
+ MARVELL_MAP_SECURE_RAM,
MAP_DEVICE0,
MARVELL_MAP_DRAM,
{0}
@@ -56,6 +61,7 @@ const mmap_region_t plat_marvell_mmap[] = {
#endif
#if IMAGE_BL32
const mmap_region_t plat_marvell_mmap[] = {
+ MARVELL_MAP_SECURE_RAM,
MAP_DEVICE0,
{0}
};
diff --git a/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c b/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c
new file mode 100644
index 000000000..d57651466
--- /dev/null
+++ b/plat/marvell/armada/a8k/common/aarch64/plat_arch_config.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/marvell/cache_llc.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+
+#define CCU_HTC_ASET (MVEBU_CCU_BASE(MVEBU_AP0) + 0x264)
+#define MVEBU_IO_AFFINITY (0xF00)
+#define MVEBU_SF_REG (MVEBU_REGS_BASE + 0x40)
+#define MVEBU_SF_EN BIT(8)
+#define MVEBU_DFX_REG(cluster_id) (MVEBU_REGS_BASE + 0x6F82A0 + \
+ (cluster_id) * 0x4)
+#define MVEBU_DFX_CLK_EN_POS 0x3
+#define MVEBU_DFX_CL0_CLK_OFFS 16
+#define MVEBU_DFX_CL0_CLK_MASK (0xF << MVEBU_DFX_CL0_CLK_OFFS)
+#define MVEBU_DFX_CL1_CLK_OFFS 8
+#define MVEBU_DFX_CL1_CLK_MASK (0xF << MVEBU_DFX_CL1_CLK_OFFS)
+
+#ifdef MVEBU_SOC_AP807
+static void plat_enable_snoop_filter(void)
+{
+ int cpu_id = plat_my_core_pos();
+
+ /* Snoop filter needs to be enabled once per cluster */
+ if (cpu_id % 2)
+ return;
+
+ mmio_setbits_32(MVEBU_SF_REG, MVEBU_SF_EN);
+}
+#endif
+
+#ifndef MVEBU_SOC_AP807
+static void plat_config_dfx_clock(void)
+{
+ int cluster_id = plat_my_core_pos();
+ uint32_t val;
+
+ /* DFX clock needs to be configured once per cluster */
+ if ((cluster_id % PLAT_MAX_CPUS_PER_CLUSTER) != 0) {
+ return;
+ }
+
+ val = mmio_read_32(MVEBU_DFX_REG(cluster_id / PLAT_MAX_CPUS_PER_CLUSTER));
+ if (cluster_id == 0) {
+ val &= ~MVEBU_DFX_CL0_CLK_MASK;
+ val |= (MVEBU_DFX_CLK_EN_POS << MVEBU_DFX_CL0_CLK_OFFS);
+ } else {
+ val &= ~MVEBU_DFX_CL1_CLK_MASK;
+ val |= (MVEBU_DFX_CLK_EN_POS << MVEBU_DFX_CL1_CLK_OFFS);
+ }
+ mmio_write_32(MVEBU_DFX_REG(cluster_id / PLAT_MAX_CPUS_PER_CLUSTER), val);
+}
+#endif
+
+static void plat_enable_affinity(void)
+{
+ int cluster_id;
+ int affinity;
+
+ /* set CPU Affinity */
+ cluster_id = plat_my_core_pos() / PLAT_MARVELL_CLUSTER_CORE_COUNT;
+ affinity = (MVEBU_IO_AFFINITY | (1 << cluster_id));
+ mmio_write_32(CCU_HTC_ASET, affinity);
+
+ /* set barier */
+ isb();
+}
+
+void marvell_psci_arch_init(int die_index)
+{
+#if LLC_ENABLE
+ /* check if LLC is in exclusive mode
+ * as L2 is configured to UniqueClean eviction
+ * (in a8k reset handler)
+ */
+ if (llc_is_exclusive(0) == 0)
+ ERROR("LLC should be configured to exclusice mode\n");
+#endif
+
+ /* Enable Affinity */
+ plat_enable_affinity();
+
+#ifdef MVEBU_SOC_AP807
+ plat_enable_snoop_filter();
+#else
+ plat_config_dfx_clock();
+#endif
+}
diff --git a/plat/marvell/a8k/common/aarch64/plat_helpers.S b/plat/marvell/armada/a8k/common/aarch64/plat_helpers.S
index fadc4c26b..fadc4c26b 100644
--- a/plat/marvell/a8k/common/aarch64/plat_helpers.S
+++ b/plat/marvell/armada/a8k/common/aarch64/plat_helpers.S
diff --git a/plat/marvell/a8k/common/ble/ble.ld.S b/plat/marvell/armada/a8k/common/ble/ble.ld.S
index d7a05928c..d7a05928c 100644
--- a/plat/marvell/a8k/common/ble/ble.ld.S
+++ b/plat/marvell/armada/a8k/common/ble/ble.ld.S
diff --git a/plat/marvell/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk
index b6a9cd291..78c62a010 100644
--- a/plat/marvell/a8k/common/ble/ble.mk
+++ b/plat/marvell/armada/a8k/common/ble/ble.mk
@@ -5,10 +5,10 @@
MV_DDR_PATH ?= drivers/marvell/mv_ddr
-MV_DDR_LIB = $(CURDIR)/$(BUILD_PLAT)/ble/mv_ddr_lib.a
-LIBC_LIB = $(CURDIR)/$(BUILD_PLAT)/lib/libc.a
-BLE_LIBS = $(MV_DDR_LIB) $(LIBC_LIB)
-PLAT_MARVELL = plat/marvell
+MV_DDR_LIB = $(BUILD_PLAT)/ble/mv_ddr_lib.a
+LIBC_LIB = $(BUILD_PLAT)/lib/libc.a
+BLE_LIBS = $(MV_DDR_LIB) $(LIBC_LIB)
+PLAT_MARVELL = plat/marvell/armada
BLE_SOURCES += $(BLE_PATH)/ble_main.c \
$(BLE_PATH)/ble_mem.S \
@@ -26,7 +26,5 @@ PLAT_INCLUDES += -I$(MV_DDR_PATH) \
BLE_LINKERFILE := $(BLE_PATH)/ble.ld.S
-FORCE:
-
$(MV_DDR_LIB): FORCE
- @+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(PLAT_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(CURDIR)/$(BUILD_PLAT)/ble
+ @+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(PLAT_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(BUILD_PLAT)/ble
diff --git a/plat/marvell/a8k/common/ble/ble_main.c b/plat/marvell/armada/a8k/common/ble/ble_main.c
index 5b3acec2d..5b3acec2d 100644
--- a/plat/marvell/a8k/common/ble/ble_main.c
+++ b/plat/marvell/armada/a8k/common/ble/ble_main.c
diff --git a/plat/marvell/a8k/common/ble/ble_mem.S b/plat/marvell/armada/a8k/common/ble/ble_mem.S
index a48d5463c..a48d5463c 100644
--- a/plat/marvell/a8k/common/ble/ble_mem.S
+++ b/plat/marvell/armada/a8k/common/ble/ble_mem.S
diff --git a/plat/marvell/a8k/common/include/a8k_plat_def.h b/plat/marvell/armada/a8k/common/include/a8k_plat_def.h
index de8031536..de8031536 100644
--- a/plat/marvell/a8k/common/include/a8k_plat_def.h
+++ b/plat/marvell/armada/a8k/common/include/a8k_plat_def.h
diff --git a/plat/marvell/a8k/common/include/ddr_info.h b/plat/marvell/armada/a8k/common/include/ddr_info.h
index e19036a26..e19036a26 100644
--- a/plat/marvell/a8k/common/include/ddr_info.h
+++ b/plat/marvell/armada/a8k/common/include/ddr_info.h
diff --git a/plat/marvell/a8k/common/include/mentor_i2c_plat.h b/plat/marvell/armada/a8k/common/include/mentor_i2c_plat.h
index e03c448a6..e03c448a6 100644
--- a/plat/marvell/a8k/common/include/mentor_i2c_plat.h
+++ b/plat/marvell/armada/a8k/common/include/mentor_i2c_plat.h
diff --git a/plat/marvell/a8k/common/include/plat_macros.S b/plat/marvell/armada/a8k/common/include/plat_macros.S
index 8faccf00b..8faccf00b 100644
--- a/plat/marvell/a8k/common/include/plat_macros.S
+++ b/plat/marvell/armada/a8k/common/include/plat_macros.S
diff --git a/plat/marvell/a8k/common/include/platform_def.h b/plat/marvell/armada/a8k/common/include/platform_def.h
index ec1c9036c..7d8505991 100644
--- a/plat/marvell/a8k/common/include/platform_def.h
+++ b/plat/marvell/armada/a8k/common/include/platform_def.h
@@ -92,13 +92,20 @@
#define PLAT_MARVELL_CORE_COUNT (PLAT_MARVELL_CLUSTER_COUNT * \
PLAT_MARVELL_CLUSTER_CORE_COUNT)
-/* DRAM[2MB..66MB] is used as Trusted ROM */
+#define PLAT_MAX_CPUS_PER_CLUSTER PLAT_MARVELL_CLUSTER_CORE_COUNT
+
+/* Part of DRAM that is used as Trusted ROM */
#define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR
-/* 64 MB TODO: reduce this to minimum needed according to fip image size */
-#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000
-/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */
-#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000
-#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */
+/* 4 MB for FIP image */
+#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x00400000
+/* Reserve 12MB for SCP (Secure PayLoad) Trusted RAM
+ * OP-TEE 4MB SHMEM follows this region
+ */
+#define PLAT_MARVELL_TRUSTED_RAM_BASE 0x04400000
+#define PLAT_MARVELL_TRUSTED_RAM_SIZE 0x00C00000 /* 12 MB DRAM */
+
+#define PLAT_MARVELL_LLC_SRAM_BASE 0x05400000
+#define PLAT_MARVELL_LLC_SRAM_SIZE 0x00100000 /* 1 MB SRAM */
/*
* PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
@@ -182,22 +189,14 @@
/* Mailbox base address (note the lower memory space
* is reserved for BLE data)
*/
-#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_TRUSTED_SRAM_BASE \
- + 0x400)
+#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_SHARED_RAM_BASE \
+ + 0x400)
#define PLAT_MARVELL_MAILBOX_SIZE 0x100
#define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */
/* Securities */
#define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER
-#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE
-#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE
-
-#ifdef BL32
-#define BL32_BASE TRUSTED_DRAM_BASE
-#define BL32_LIMIT TRUSTED_DRAM_SIZE
-#endif
-
#define MVEBU_PMU_IRQ_WA
#endif /* PLATFORM_DEF_H */
diff --git a/plat/marvell/a8k/common/mss/mss_a8k.mk b/plat/marvell/armada/a8k/common/mss/mss_a8k.mk
index 58f23d8dd..d8d492193 100644
--- a/plat/marvell/a8k/common/mss/mss_a8k.mk
+++ b/plat/marvell/armada/a8k/common/mss/mss_a8k.mk
@@ -5,10 +5,11 @@
# https://spdx.org/licenses
#
-PLAT_MARVELL := plat/marvell
+PLAT_MARVELL := plat/marvell/armada
A8K_MSS_SOURCE := $(PLAT_MARVELL)/a8k/common/mss
-BL2_SOURCES += $(A8K_MSS_SOURCE)/mss_bl2_setup.c
+BL2_SOURCES += $(A8K_MSS_SOURCE)/mss_bl2_setup.c \
+ $(MARVELL_MOCHI_DRV)
BL31_SOURCES += $(A8K_MSS_SOURCE)/mss_pm_ipc.c
diff --git a/plat/marvell/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c
index 728ee54a0..b919cb337 100644
--- a/plat/marvell/a8k/common/mss/mss_bl2_setup.c
+++ b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c
@@ -10,6 +10,7 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/marvell/ccu.h>
+#include <drivers/marvell/mochi/ap_setup.h>
#include <drivers/marvell/mochi/cp110_setup.h>
#include <lib/mmio.h>
@@ -18,9 +19,6 @@
#include "mss_scp_bootloader.h"
-/* IO windows configuration */
-#define IOW_GCR_OFFSET (0x70)
-
/* MSS windows configuration */
#define MSS_AEBR(base) (base + 0x160)
#define MSS_AIBR(base) (base + 0x164)
@@ -51,7 +49,7 @@ struct addr_map_win ccu_mem_map[] = {
*/
static int bl2_plat_mmap_init(void)
{
- int cfg_num, win_id, cfg_idx;
+ int cfg_num, win_id, cfg_idx, cp;
cfg_num = ARRAY_SIZE(ccu_mem_map);
@@ -65,14 +63,29 @@ static int bl2_plat_mmap_init(void)
* Do not touch CCU window 0,
* it's used for the internal registers access
*/
- for (cfg_idx = 0, win_id = 1; cfg_idx < cfg_num; cfg_idx++, win_id++) {
+ for (cfg_idx = 0, win_id = 1;
+ (win_id < MVEBU_CCU_MAX_WINS) && (cfg_idx < cfg_num); win_id++) {
+ /* Skip already enabled CCU windows */
+ if (ccu_is_win_enabled(MVEBU_AP0, win_id))
+ continue;
/* Enable required CCU windows */
ccu_win_check(&ccu_mem_map[cfg_idx]);
ccu_enable_win(MVEBU_AP0, &ccu_mem_map[cfg_idx], win_id);
+ cfg_idx++;
}
- /* Set the default target id to PIDI */
- mmio_write_32(MVEBU_IO_WIN_BASE(MVEBU_AP0) + IOW_GCR_OFFSET, PIDI_TID);
+ /* Config address for each cp other than cp0 */
+ for (cp = 1; cp < CP_COUNT; cp++)
+ update_cp110_default_win(cp);
+
+ /* There is need to configure IO_WIN windows again to overwrite
+ * temporary configuration done during update_cp110_default_win
+ */
+ init_io_win(MVEBU_AP0);
+
+ /* Open AMB bridge required for MG access */
+ for (cp = 0; cp < CP_COUNT; cp++)
+ cp110_amb_init(MVEBU_CP_REGS_BASE(cp));
return 0;
}
@@ -125,6 +138,8 @@ uint32_t bl2_plat_get_cp_count(int ap_idx)
if (revision == MVEBU_80X0_DEV_ID ||
revision == MVEBU_80X0_CP115_DEV_ID)
return 2;
+ else if (revision == MVEBU_CN9130_DEV_ID)
+ return CP_COUNT;
else
return 1;
}
diff --git a/plat/marvell/a8k/common/mss/mss_pm_ipc.c b/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.c
index a0705832f..a0705832f 100644
--- a/plat/marvell/a8k/common/mss/mss_pm_ipc.c
+++ b/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.c
diff --git a/plat/marvell/a8k/common/mss/mss_pm_ipc.h b/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.h
index 1dfa9fa03..1dfa9fa03 100644
--- a/plat/marvell/a8k/common/mss/mss_pm_ipc.h
+++ b/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.h
diff --git a/plat/marvell/a8k/common/plat_bl1_setup.c b/plat/marvell/armada/a8k/common/plat_bl1_setup.c
index f9521c871..f9521c871 100644
--- a/plat/marvell/a8k/common/plat_bl1_setup.c
+++ b/plat/marvell/armada/a8k/common/plat_bl1_setup.c
diff --git a/plat/marvell/a8k/common/plat_bl31_setup.c b/plat/marvell/armada/a8k/common/plat_bl31_setup.c
index 98b3966ae..552c9b298 100644
--- a/plat/marvell/a8k/common/plat_bl31_setup.c
+++ b/plat/marvell/armada/a8k/common/plat_bl31_setup.c
@@ -116,18 +116,15 @@ void bl31_plat_arch_setup(void)
marvell_bl31_plat_arch_setup();
for (cp = 0; cp < CP_COUNT; cp++) {
- /* configure cp110 for CP0*/
- if (cp == 1)
- mci_initialize(MVEBU_MCI0);
-
- /* initialize MCI & CP1 */
cp110_init(MVEBU_CP_REGS_BASE(cp),
STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP));
- /* Should be called only after setting IOB windows */
marvell_bl31_mpp_init(cp);
}
+ for (cp = 1; cp < CP_COUNT; cp++)
+ mci_link_tune(cp - 1);
+
/* initialize IPC between MSS and ATF */
if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM ||
mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE)
diff --git a/plat/marvell/a8k/common/plat_ble_setup.c b/plat/marvell/armada/a8k/common/plat_ble_setup.c
index 7f9e24278..e4e09fb41 100644
--- a/plat/marvell/a8k/common/plat_ble_setup.c
+++ b/plat/marvell/armada/a8k/common/plat_ble_setup.c
@@ -74,18 +74,11 @@
(0x24 << AVS_LOW_VDD_LIMIT_OFFSET) | \
(0x1 << AVS_SOFT_RESET_OFFSET) | \
(0x1 << AVS_ENABLE_OFFSET))
-/* VDD limit is 0.82V for all A3900 devices
- * AVS offsets are not the same as in A70x0
- */
-#define AVS_A3900_CLK_VALUE ((0x80u << 24) | \
- (0x2c2 << 13) | \
- (0x2c2 << 3) | \
- (0x1 << AVS_SOFT_RESET_OFFSET) | \
- (0x1 << AVS_ENABLE_OFFSET))
-/* VDD is 0.88V for 2GHz clock */
-#define AVS_A3900_HIGH_CLK_VALUE ((0x80u << 24) | \
- (0x2f5 << 13) | \
- (0x2f5 << 3) | \
+
+/* VDD is 0.88V for 2GHz clock on CN913x devices */
+#define AVS_AP807_CLK_VALUE ((0x80UL << 24) | \
+ (0x2dc << 13) | \
+ (0x2dc << 3) | \
(0x1 << AVS_SOFT_RESET_OFFSET) | \
(0x1 << AVS_ENABLE_OFFSET))
@@ -117,7 +110,6 @@
#define EFUSE_AP_LD0_REVID_MASK 0xF
#define EFUSE_AP_LD0_BIN_OFFS 16 /* LD0[80:79] */
#define EFUSE_AP_LD0_BIN_MASK 0x3
-#define EFUSE_AP_LD0_SWREV_OFFS 50 /* LD0[115:113] */
#define EFUSE_AP_LD0_SWREV_MASK 0x7
#ifndef MVEBU_SOC_AP807
@@ -131,16 +123,18 @@
#define EFUSE_AP_LD0_SVC2_OFFS 26 /* LD0[96:89] */
#define EFUSE_AP_LD0_SVC3_OFFS 34 /* LD0[104:97] */
#define EFUSE_AP_LD0_WP_MASK 0xFF
+ #define EFUSE_AP_LD0_SWREV_OFFS 50 /* LD0[115:113] */
#else
/* AP807 AVS work points in the LD0 eFuse
* SVC1 work point: LD0[91:81]
* SVC2 work point: LD0[102:92]
* SVC3 work point: LD0[113:103]
*/
- #define EFUSE_AP_LD0_SVC1_OFFS 17 /* LD0[91:81] */
- #define EFUSE_AP_LD0_SVC2_OFFS 28 /* LD0[102:92] */
- #define EFUSE_AP_LD0_SVC3_OFFS 39 /* LD0[113:103] */
- #define EFUSE_AP_LD0_WP_MASK 0x3FF
+ #define EFUSE_AP_LD0_SVC1_OFFS 18 /* LD0[91:81] */
+ #define EFUSE_AP_LD0_SVC2_OFFS 29 /* LD0[102:92] */
+ #define EFUSE_AP_LD0_SVC3_OFFS 40 /* LD0[113:103] */
+ #define EFUSE_AP_LD0_WP_MASK 0x7FF /* 10 data,1 parity */
+ #define EFUSE_AP_LD0_SWREV_OFFS 51 /* LD0[116:114] */
#endif
#define EFUSE_AP_LD0_SVC4_OFFS 42 /* LD0[112:105] */
@@ -223,11 +217,9 @@ static void ble_plat_avs_config(void)
FREQ_MODE_AP_SAR_REG_NUM)));
/* Check which SoC is running and act accordingly */
if (ble_get_ap_type() == CHIP_ID_AP807) {
- /* Increase CPU voltage for higher CPU clock */
- if (freq_mode == CPU_2000_DDR_1200_RCLK_1200)
- avs_val = AVS_A3900_HIGH_CLK_VALUE;
- else
- avs_val = AVS_A3900_CLK_VALUE;
+
+ avs_val = AVS_AP807_CLK_VALUE;
+
} else {
/* Check which SoC is running and act accordingly */
device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0));
@@ -381,6 +373,7 @@ static void ble_plat_svc_config(void)
uint64_t efuse;
uint32_t device_id, single_cluster;
uint16_t svc[4], perr[4], i, sw_ver;
+ uint8_t avs_data_bits, min_sw_ver, svc_fields;
unsigned int ap_type;
/* Set access to LD0 */
@@ -434,22 +427,28 @@ static void ble_plat_svc_config(void)
& EFUSE_AP_LD0_WP_MASK;
INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x, [3]=0x%x\n",
svc[0], svc[1], svc[2], svc[3]);
+ avs_data_bits = 7;
+ min_sw_ver = 2; /* parity check from sw revision 2 */
+ svc_fields = 4;
} else {
INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x\n",
svc[0], svc[1], svc[2]);
+ avs_data_bits = 10;
+ min_sw_ver = 1; /* parity check required from sw revision 1 */
+ svc_fields = 3;
}
/* Validate parity of SVC workpoint values */
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < svc_fields; i++) {
uint8_t parity, bit;
-
perr[i] = 0;
- for (bit = 1, parity = svc[i] & 1; bit < 7; bit++)
+ for (bit = 1, parity = (svc[i] & 1); bit < avs_data_bits; bit++)
parity ^= (svc[i] >> bit) & 1;
- /* Starting from SW version 2, the parity check is mandatory */
- if ((sw_ver > 1) && (parity != ((svc[i] >> 7) & 1)))
+ /* From SW version 1 or 2 (AP806/AP807), check parity */
+ if ((sw_ver >= min_sw_ver) &&
+ (parity != ((svc[i] >> avs_data_bits) & 1)))
perr[i] = 1; /* register the error */
}
@@ -463,7 +462,6 @@ static void ble_plat_svc_config(void)
NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n",
single_cluster == 0 ? "8040" : "8020", freq_pidi_mode);
switch (freq_pidi_mode) {
- case CPU_1800_DDR_1200_RCLK_1200:
case CPU_1800_DDR_1050_RCLK_1050:
if (perr[1])
goto perror;
@@ -540,8 +538,19 @@ static void ble_plat_svc_config(void)
if (perr[0])
goto perror;
avs_workpoint = svc[0];
- } else
- avs_workpoint = 0;
+ } else {
+#if MARVELL_SVC_TEST
+ reg_val = mmio_read_32(AVS_EN_CTRL_REG);
+ avs_workpoint = (reg_val &
+ AVS_VDD_LOW_LIMIT_MASK) >>
+ AVS_LOW_VDD_LIMIT_OFFSET;
+ NOTICE("7040 1600Mhz, avs = 0x%x\n",
+ avs_workpoint);
+#else
+ NOTICE("SVC: AVS work point not changed\n");
+ return;
+#endif
+ }
break;
}
} else if (device_id == MVEBU_3900_DEV_ID) {
@@ -564,6 +573,31 @@ static void ble_plat_svc_config(void)
avs_workpoint = svc[0];
break;
}
+ } else if (device_id == MVEBU_CN9130_DEV_ID) {
+ NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n",
+ "CN913x", freq_pidi_mode);
+ switch (freq_pidi_mode) {
+ case CPU_2200_DDR_1200_RCLK_1200:
+ if (perr[0])
+ goto perror;
+ avs_workpoint = svc[0];
+ break;
+ case CPU_2000_DDR_1200_RCLK_1200:
+ if (perr[1])
+ goto perror;
+ avs_workpoint = svc[1];
+ break;
+ case CPU_1600_DDR_1200_RCLK_1200:
+ if (perr[2])
+ goto perror;
+ avs_workpoint = svc[2];
+ break;
+ default:
+ ERROR("SVC: Unsupported Frequency 0x%x\n",
+ freq_pidi_mode);
+ return;
+
+ }
} else {
ERROR("SVC: Unsupported Device ID 0x%x\n", device_id);
return;
@@ -571,13 +605,17 @@ static void ble_plat_svc_config(void)
/* Set AVS control if needed */
if (avs_workpoint == 0) {
- ERROR("SVC: AVS work point not changed\n");
+ ERROR("SVC: You are using a frequency setup which is\n");
+ ERROR("Not supported by this device\n");
+ ERROR("This may result in malfunction of the device\n");
return;
}
/* Remove parity bit */
if (ap_type != CHIP_ID_AP807)
avs_workpoint &= 0x7F;
+ else
+ avs_workpoint &= 0x3FF;
/* Update WP from EEPROM if needed */
avs_workpoint = avs_update_from_eeprom(avs_workpoint);
diff --git a/plat/marvell/a8k/common/plat_pm.c b/plat/marvell/armada/a8k/common/plat_pm.c
index 96e95c271..96e95c271 100644
--- a/plat/marvell/a8k/common/plat_pm.c
+++ b/plat/marvell/armada/a8k/common/plat_pm.c
diff --git a/plat/marvell/a8k/common/plat_pm_trace.c b/plat/marvell/armada/a8k/common/plat_pm_trace.c
index f589ff31b..f589ff31b 100644
--- a/plat/marvell/a8k/common/plat_pm_trace.c
+++ b/plat/marvell/armada/a8k/common/plat_pm_trace.c
diff --git a/plat/marvell/a8k/common/plat_thermal.c b/plat/marvell/armada/a8k/common/plat_thermal.c
index a2fc0d0ab..a2fc0d0ab 100644
--- a/plat/marvell/a8k/common/plat_thermal.c
+++ b/plat/marvell/armada/a8k/common/plat_thermal.c
diff --git a/plat/marvell/common/aarch64/marvell_bl2_mem_params_desc.c b/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c
index 6a8e11c90..8d909dc59 100644
--- a/plat/marvell/common/aarch64/marvell_bl2_mem_params_desc.c
+++ b/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c
@@ -100,6 +100,45 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
.next_handoff_image_id = BL33_IMAGE_ID,
},
+
+ /*
+ * Fill BL32 external 1 related information.
+ * A typical use for extra1 image is with OP-TEE
+ * where it is the pager image.
+ */
+ {
+ .image_id = BL32_EXTRA1_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+
+ /*
+ * Fill BL32 external 2 related information.
+ * A typical use for extra2 image is with OP-TEE,
+ * where it is the paged image.
+ */
+ {
+ .image_id = BL32_EXTRA2_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+#ifdef SPD_opteed
+ .image_info.image_base = MARVELL_OPTEE_PAGEABLE_LOAD_BASE,
+ .image_info.image_max_size = MARVELL_OPTEE_PAGEABLE_LOAD_SIZE,
+#endif
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
# endif /* BL32_BASE */
/* Fill BL33 related information */
diff --git a/plat/marvell/common/aarch64/marvell_common.c b/plat/marvell/armada/common/aarch64/marvell_common.c
index 21a62d483..21a62d483 100644
--- a/plat/marvell/common/aarch64/marvell_common.c
+++ b/plat/marvell/armada/common/aarch64/marvell_common.c
diff --git a/plat/marvell/common/aarch64/marvell_helpers.S b/plat/marvell/armada/common/aarch64/marvell_helpers.S
index 6f625b95d..b798f17c5 100644
--- a/plat/marvell/common/aarch64/marvell_helpers.S
+++ b/plat/marvell/armada/common/aarch64/marvell_helpers.S
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
* Copyright (C) 2018 Marvell International Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -90,10 +91,10 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush()
+ * void plat_crash_console_flush()
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : r0
* ---------------------------------------------
*/
@@ -185,7 +186,7 @@ func disable_sram
/* Invalidate all ways */
ldr w1, =LLC_WAY_MASK
- ldr x0, =MASTER_L2X0_INV_WAY
+ ldr x0, =MASTER_LLC_INV_WAY
str w1, [x0]
/* Finally disable LLC */
diff --git a/plat/marvell/common/marvell_bl1_setup.c b/plat/marvell/armada/common/marvell_bl1_setup.c
index 7b7cef39b..7b7cef39b 100644
--- a/plat/marvell/common/marvell_bl1_setup.c
+++ b/plat/marvell/armada/common/marvell_bl1_setup.c
diff --git a/plat/marvell/common/marvell_bl2_setup.c b/plat/marvell/armada/common/marvell_bl2_setup.c
index 3c1c39112..3dfa82e0e 100644
--- a/plat/marvell/common/marvell_bl2_setup.c
+++ b/plat/marvell/armada/common/marvell_bl2_setup.c
@@ -17,6 +17,9 @@
#include <drivers/console.h>
#include <lib/utils.h>
+#ifdef SPD_opteed
+#include <optee_utils.h>
+#endif
#include <marvell_def.h>
#include <plat_marvell.h>
@@ -97,9 +100,29 @@ int marvell_bl2_handle_post_image_load(unsigned int image_id)
int err = 0;
bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+#ifdef SPD_opteed
+ bl_mem_params_node_t *pager_mem_params = NULL;
+ bl_mem_params_node_t *paged_mem_params = NULL;
+#endif /* SPD_opteed */
assert(bl_mem_params);
switch (image_id) {
+ case BL32_IMAGE_ID:
+#ifdef SPD_opteed
+ pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+ assert(pager_mem_params);
+
+ paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+ assert(paged_mem_params);
+
+ err = parse_optee_header(&bl_mem_params->ep_info,
+ &pager_mem_params->image_info,
+ &paged_mem_params->image_info);
+ if (err != 0)
+ WARN("OPTEE header parse error.\n");
+#endif /* SPD_opteed */
+ bl_mem_params->ep_info.spsr = marvell_get_spsr_for_bl32_entry();
+ break;
case BL33_IMAGE_ID:
/* BL33 expects to receive the primary CPU MPID (through r0) */
diff --git a/plat/marvell/common/marvell_bl31_setup.c b/plat/marvell/armada/common/marvell_bl31_setup.c
index 26ba90654..26ba90654 100644
--- a/plat/marvell/common/marvell_bl31_setup.c
+++ b/plat/marvell/armada/common/marvell_bl31_setup.c
diff --git a/plat/marvell/common/marvell_cci.c b/plat/marvell/armada/common/marvell_cci.c
index 80351aedc..80351aedc 100644
--- a/plat/marvell/common/marvell_cci.c
+++ b/plat/marvell/armada/common/marvell_cci.c
diff --git a/plat/marvell/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk
index f41d7a47f..04eb51c48 100644
--- a/plat/marvell/common/marvell_common.mk
+++ b/plat/marvell/armada/common/marvell_common.mk
@@ -3,11 +3,10 @@
# SPDX-License-Identifier: BSD-3-Clause
# https://spdx.org/licenses
-MARVELL_PLAT_BASE := plat/marvell
-MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell
+MARVELL_PLAT_BASE := plat/marvell/armada
+MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell/armada
-include $(MARVELL_PLAT_BASE)/version.mk
-include $(MARVELL_PLAT_BASE)/marvell.mk
+include plat/marvell/version.mk
VERSION_STRING +=(Marvell-${SUBVERSION})
@@ -16,6 +15,11 @@ SEPARATE_CODE_AND_RODATA := 1
# flag to switch from PLL to ARO
ARO_ENABLE := 0
$(eval $(call add_define,ARO_ENABLE))
+
+# Convert LLC to secure SRAM
+LLC_SRAM := 0
+$(eval $(call add_define,LLC_SRAM))
+
# Enable/Disable LLC
LLC_ENABLE := 1
$(eval $(call add_define,LLC_ENABLE))
@@ -53,6 +57,10 @@ BL2_SOURCES += drivers/io/io_fip.c \
$(MARVELL_PLAT_BASE)/common/aarch64/marvell_bl2_mem_params_desc.c \
$(MARVELL_PLAT_BASE)/common/marvell_image_load.c
+ifeq (${SPD},opteed)
+PLAT_INCLUDES += -Iinclude/lib
+BL2_SOURCES += lib/optee/optee_utils.c
+endif
BL31_SOURCES += $(MARVELL_PLAT_BASE)/common/marvell_bl31_setup.c \
$(MARVELL_PLAT_BASE)/common/marvell_pm.c \
@@ -64,9 +72,32 @@ BL31_SOURCES += $(MARVELL_PLAT_BASE)/common/marvell_bl31_setup.c \
# PSCI functionality
$(eval $(call add_define,CONFIG_ARM64))
+# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
+# in the FIP if the platform requires.
+ifneq ($(BL32_EXTRA1),)
+$(eval $(call TOOL_ADD_IMG,bl32_extra1,--tos-fw-extra1))
+endif
+ifneq ($(BL32_EXTRA2),)
+$(eval $(call TOOL_ADD_IMG,bl32_extra2,--tos-fw-extra2))
+endif
+
# MSS (SCP) build
ifeq (${MSS_SUPPORT}, 1)
include $(MARVELL_PLAT_BASE)/common/mss/mss_common.mk
endif
-fip: mrvl_flash
+$(BUILD_PLAT)/$(BOOT_IMAGE): $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(FIP_NAME)
+ $(if $(shell find $(BUILD_PLAT)/bl1.bin -type f -size +128k),$(error "Image '$(BUILD_PLAT)/bl1.bin' is bigger than 128kB"))
+ @cp $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+ @truncate -s %128K $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+ @cat $(BUILD_PLAT)/$(FIP_NAME) >> $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+ @truncate -s %4 $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+ @$(ECHO_BLANK_LINE)
+ @echo "Built $@ successfully"
+ @$(ECHO_BLANK_LINE)
+
+.PHONY: mrvl_bootimage
+mrvl_bootimage: $(BUILD_PLAT)/$(BOOT_IMAGE)
+
+.PHONY: mrvl_flash
+mrvl_flash: $(BUILD_PLAT)/$(FLASH_IMAGE)
diff --git a/plat/marvell/common/marvell_console.c b/plat/marvell/armada/common/marvell_console.c
index 22c5eb3af..c84b004be 100644
--- a/plat/marvell/common/marvell_console.c
+++ b/plat/marvell/armada/common/marvell_console.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,16 +14,15 @@
#ifdef PLAT_a3700
#include <drivers/marvell/uart/a3700_console.h>
-
-static console_a3700_t marvell_boot_console;
-static console_a3700_t marvell_runtime_console;
+#define console_marvell_register console_a3700_register
#else
#include <drivers/ti/uart/uart_16550.h>
-
-static console_16550_t marvell_boot_console;
-static console_16550_t marvell_runtime_console;
+#define console_marvell_register console_16550_register
#endif
+static console_t marvell_boot_console;
+static console_t marvell_runtime_console;
+
/*******************************************************************************
* Functions that set up the console
******************************************************************************/
@@ -32,15 +31,10 @@ static console_16550_t marvell_runtime_console;
void marvell_console_boot_init(void)
{
int rc =
-#ifdef PLAT_a3700
- console_a3700_register(
-#else
- console_16550_register(
-#endif
- PLAT_MARVELL_BOOT_UART_BASE,
- PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
- MARVELL_CONSOLE_BAUDRATE,
- &marvell_boot_console);
+ console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE,
+ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+ MARVELL_CONSOLE_BAUDRATE,
+ &marvell_boot_console);
if (rc == 0) {
/*
* The crash console doesn't use the multi console API, it uses
@@ -50,40 +44,33 @@ void marvell_console_boot_init(void)
panic();
}
- console_set_scope(&marvell_boot_console.console,
- CONSOLE_FLAG_BOOT);
+ console_set_scope(&marvell_boot_console, CONSOLE_FLAG_BOOT);
}
void marvell_console_boot_end(void)
{
- (void)console_flush();
+ console_flush();
- (void)console_unregister(&marvell_boot_console.console);
+ (void)console_unregister(&marvell_boot_console);
}
/* Initialize the runtime console */
void marvell_console_runtime_init(void)
{
int rc =
-#ifdef PLAT_a3700
- console_a3700_register(
-#else
- console_16550_register(
-#endif
- PLAT_MARVELL_BOOT_UART_BASE,
- PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
- MARVELL_CONSOLE_BAUDRATE,
- &marvell_runtime_console);
+ console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE,
+ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+ MARVELL_CONSOLE_BAUDRATE,
+ &marvell_runtime_console);
if (rc == 0)
panic();
- console_set_scope(&marvell_runtime_console.console,
- CONSOLE_FLAG_RUNTIME);
+ console_set_scope(&marvell_runtime_console, CONSOLE_FLAG_RUNTIME);
}
void marvell_console_runtime_end(void)
{
- (void)console_flush();
+ console_flush();
- (void)console_unregister(&marvell_runtime_console.console);
+ (void)console_unregister(&marvell_runtime_console);
}
diff --git a/plat/marvell/common/marvell_ddr_info.c b/plat/marvell/armada/common/marvell_ddr_info.c
index 734099652..734099652 100644
--- a/plat/marvell/common/marvell_ddr_info.c
+++ b/plat/marvell/armada/common/marvell_ddr_info.c
diff --git a/plat/marvell/common/marvell_gicv2.c b/plat/marvell/armada/common/marvell_gicv2.c
index 2505c9f84..2505c9f84 100644
--- a/plat/marvell/common/marvell_gicv2.c
+++ b/plat/marvell/armada/common/marvell_gicv2.c
diff --git a/plat/marvell/common/marvell_gicv3.c b/plat/marvell/armada/common/marvell_gicv3.c
index 0bd554570..0bd554570 100644
--- a/plat/marvell/common/marvell_gicv3.c
+++ b/plat/marvell/armada/common/marvell_gicv3.c
diff --git a/plat/marvell/common/marvell_image_load.c b/plat/marvell/armada/common/marvell_image_load.c
index be16b0898..be16b0898 100644
--- a/plat/marvell/common/marvell_image_load.c
+++ b/plat/marvell/armada/common/marvell_image_load.c
diff --git a/plat/marvell/common/marvell_io_storage.c b/plat/marvell/armada/common/marvell_io_storage.c
index 065f95688..2627ba4ef 100644
--- a/plat/marvell/common/marvell_io_storage.c
+++ b/plat/marvell/armada/common/marvell_io_storage.c
@@ -43,6 +43,15 @@ static const io_uuid_spec_t bl31_uuid_spec = {
static const io_uuid_spec_t bl32_uuid_spec = {
.uuid = UUID_SECURE_PAYLOAD_BL32,
};
+
+static const io_uuid_spec_t bl32_extra1_uuid_spec = {
+ .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
+};
+
+static const io_uuid_spec_t bl32_extra2_uuid_spec = {
+ .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
+};
+
static const io_uuid_spec_t bl33_uuid_spec = {
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
};
@@ -83,6 +92,16 @@ static const struct plat_io_policy policies[] = {
(uintptr_t)&bl32_uuid_spec,
open_fip
},
+ [BL32_EXTRA1_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl32_extra1_uuid_spec,
+ open_fip
+ },
+ [BL32_EXTRA2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl32_extra2_uuid_spec,
+ open_fip
+ },
[BL33_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl33_uuid_spec,
diff --git a/plat/marvell/common/marvell_pm.c b/plat/marvell/armada/common/marvell_pm.c
index 3c675b296..3c675b296 100644
--- a/plat/marvell/common/marvell_pm.c
+++ b/plat/marvell/armada/common/marvell_pm.c
diff --git a/plat/marvell/common/marvell_topology.c b/plat/marvell/armada/common/marvell_topology.c
index a40ff6f50..a40ff6f50 100644
--- a/plat/marvell/common/marvell_topology.c
+++ b/plat/marvell/armada/common/marvell_topology.c
diff --git a/plat/marvell/common/mrvl_sip_svc.c b/plat/marvell/armada/common/mrvl_sip_svc.c
index 0291024d7..0291024d7 100644
--- a/plat/marvell/common/mrvl_sip_svc.c
+++ b/plat/marvell/armada/common/mrvl_sip_svc.c
diff --git a/plat/marvell/common/mss/mss_common.mk b/plat/marvell/armada/common/mss/mss_common.mk
index 898b6dccc..4ab43596c 100644
--- a/plat/marvell/common/mss/mss_common.mk
+++ b/plat/marvell/armada/common/mss/mss_common.mk
@@ -6,14 +6,14 @@
#
-PLAT_MARVELL := plat/marvell
+PLAT_MARVELL := plat/marvell/armada
MSS_SOURCE := $(PLAT_MARVELL)/common/mss
BL2_SOURCES += $(MSS_SOURCE)/mss_scp_bootloader.c \
$(PLAT_MARVELL)/common/plat_delay_timer.c \
drivers/delay_timer/delay_timer.c \
$(MARVELL_DRV) \
- $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c
+ $(BOARD_DIR)/board/marvell_plat_config.c
BL31_SOURCES += $(MSS_SOURCE)/mss_ipc_drv.c
diff --git a/plat/marvell/common/mss/mss_ipc_drv.c b/plat/marvell/armada/common/mss/mss_ipc_drv.c
index 70ccfa5ac..70ccfa5ac 100644
--- a/plat/marvell/common/mss/mss_ipc_drv.c
+++ b/plat/marvell/armada/common/mss/mss_ipc_drv.c
diff --git a/plat/marvell/common/mss/mss_ipc_drv.h b/plat/marvell/armada/common/mss/mss_ipc_drv.h
index bcb4b2d8f..bcb4b2d8f 100644
--- a/plat/marvell/common/mss/mss_ipc_drv.h
+++ b/plat/marvell/armada/common/mss/mss_ipc_drv.h
diff --git a/plat/marvell/common/mss/mss_mem.h b/plat/marvell/armada/common/mss/mss_mem.h
index 5d68ac788..5d68ac788 100644
--- a/plat/marvell/common/mss/mss_mem.h
+++ b/plat/marvell/armada/common/mss/mss_mem.h
diff --git a/plat/marvell/common/mss/mss_scp_bl2_format.h b/plat/marvell/armada/common/mss/mss_scp_bl2_format.h
index 7cf8d3201..74dddc645 100644
--- a/plat/marvell/common/mss/mss_scp_bl2_format.h
+++ b/plat/marvell/armada/common/mss/mss_scp_bl2_format.h
@@ -8,12 +8,11 @@
#ifndef MSS_SCP_BL2_FORMAT_H
#define MSS_SCP_BL2_FORMAT_H
-#define MAX_NR_OF_FILES 5
+#define MAX_NR_OF_FILES 8
#define FILE_MAGIC 0xddd01ff
#define HEADER_VERSION 0x1
#define MSS_IDRAM_SIZE 0x10000 /* 64KB */
-#define MG_SRAM_SIZE 0x20000 /* 128KB */
/* Types definitions */
typedef struct file_header {
@@ -31,6 +30,7 @@ enum cm3_t {
MSS_CP3,
MG_CP0,
MG_CP1,
+ MG_CP2,
};
typedef struct img_header {
diff --git a/plat/marvell/common/mss/mss_scp_bootloader.c b/plat/marvell/armada/common/mss/mss_scp_bootloader.c
index 7e442c615..adf570ea9 100644
--- a/plat/marvell/common/mss/mss_scp_bootloader.c
+++ b/plat/marvell/armada/common/mss/mss_scp_bootloader.c
@@ -12,6 +12,7 @@
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
+#include <mg_conf_cm3/mg_conf_cm3.h>
#include <lib/mmio.h>
#include <plat_pm_trace.h>
@@ -225,12 +226,20 @@ static int load_img_to_cm3(enum cm3_t cm3_type,
}
break;
case MG_CP0:
- /* TODO: */
- NOTICE("Load image to CP0 MG not supported\n");
- break;
case MG_CP1:
- /* TODO: */
- NOTICE("Load image to CP1 MG not supported\n");
+ case MG_CP2:
+ cp_index = cm3_type - MG_CP0;
+ if (bl2_plat_get_cp_count(0) <= cp_index) {
+ NOTICE("Skipping MG CP%d related image\n",
+ cp_index);
+ break;
+ }
+ NOTICE("Load image to CP%d MG\n", cp_index);
+ ret = mg_image_load(single_img, image_size, cp_index);
+ if (ret != 0) {
+ ERROR("SCP Image load failed\n");
+ return -1;
+ }
break;
default:
ERROR("SCP_BL2 wrong img format (cm3_type=%d)\n", cm3_type);
@@ -261,7 +270,7 @@ static int split_and_load_bl2_image(void *image)
}
if (file_hdr->nr_of_imgs > MAX_NR_OF_FILES) {
- ERROR("SCP_BL2 concatenated image contains to many images\n");
+ ERROR("SCP_BL2 concatenated image contains too many images\n");
return -1;
}
diff --git a/plat/marvell/common/mss/mss_scp_bootloader.h b/plat/marvell/armada/common/mss/mss_scp_bootloader.h
index 4950d2472..4950d2472 100644
--- a/plat/marvell/common/mss/mss_scp_bootloader.h
+++ b/plat/marvell/armada/common/mss/mss_scp_bootloader.h
diff --git a/plat/marvell/common/plat_delay_timer.c b/plat/marvell/armada/common/plat_delay_timer.c
index 253975264..253975264 100644
--- a/plat/marvell/common/plat_delay_timer.c
+++ b/plat/marvell/armada/common/plat_delay_timer.c
diff --git a/plat/marvell/marvell.mk b/plat/marvell/marvell.mk
index d8be0dd17..b6a2b9995 100644
--- a/plat/marvell/marvell.mk
+++ b/plat/marvell/marvell.mk
@@ -16,39 +16,6 @@ $(eval $(call add_define,MARVELL_SECURE_BOOT))
PALLADIUM := 0
$(eval $(call add_define,PALLADIUM))
-ifeq (${MARVELL_SECURE_BOOT},1)
-DOIMAGE_SEC_FLAGS := -c $(DOIMAGE_SEC)
-DOIMAGE_LIBS_CHECK = \
- if ! [ -d "/usr/include/mbedtls" ]; then \
- echo "****************************************" >&2; \
- echo "Missing mbedTLS installation! " >&2; \
- echo "Please download it from \"tls.mbed.org\"" >&2; \
- echo "Alternatively on Debian/Ubuntu system install" >&2; \
- echo "\"libmbedtls-dev\" package" >&2; \
- echo "Make sure to use version 2.1.0 or later" >&2; \
- echo "****************************************" >&2; \
- exit 1; \
- else if ! [ -f "/usr/include/libconfig.h" ]; then \
- echo "********************************************************" >&2; \
- echo "Missing Libconfig installation!" >&2; \
- echo "Please download it from \"www.hyperrealm.com/libconfig/\"" >&2; \
- echo "Alternatively on Debian/Ubuntu system install packages" >&2; \
- echo "\"libconfig8\" and \"libconfig8-dev\"" >&2; \
- echo "********************************************************" >&2; \
- exit 1; \
- fi \
- fi
-else #MARVELL_SECURE_BOOT
-DOIMAGE_LIBS_CHECK =
-DOIMAGE_SEC_FLAGS =
-endif #MARVELL_SECURE_BOOT
-
-mrvl_clean:
- @echo " Doimage CLEAN"
- ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${DOIMAGEPATH} clean
-
-${DOIMAGETOOL}: mrvl_clean
- @$(DOIMAGE_LIBS_CHECK)
- ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} VERSION=$(SUBVERSION) WTMI_IMG=$(WTMI_IMG)
-
-
+# Set board to work with DDR 32bit
+DDR32 := 0
+$(eval $(call add_define,DDR32))
diff --git a/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c b/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c
new file mode 100644
index 000000000..0befadfc6
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/mentor/mi2cv.h>
+#include <lib/mmio.h>
+
+#include <mv_ddr_if.h>
+#include <mvebu_def.h>
+#include <plat_marvell.h>
+
+#define MVEBU_CP_MPP_CTRL37_OFFS 20
+#define MVEBU_CP_MPP_CTRL38_OFFS 24
+#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2
+#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2
+
+#define MVEBU_MPP_CTRL_MASK 0xf
+
+/*
+ * This struct provides the DRAM training code with
+ * the appropriate board DRAM configuration
+ */
+struct mv_ddr_iface dram_iface_ap0 = {
+ .ap_base = MVEBU_REGS_BASE_AP(0),
+ .state = MV_DDR_IFACE_NRDY,
+ .validation = MV_DDR_MEMORY_CHECK,
+ .sscg = SSCG_EN,
+ .id = 0,
+ .iface_base_addr = 0,
+ .tm = {
+ DEBUG_LEVEL_ERROR,
+ 0x1, /* active interfaces */
+ /* cs_mask, mirror, dqs_swap, ck_swap X subphys */
+ { { { {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0} },
+ SPEED_BIN_DDR_2400T, /* speed_bin */
+ MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */
+ MV_DDR_DIE_CAP_8GBIT, /* die capacity */
+ MV_DDR_FREQ_SAR, /* frequency */
+ 0, 0, /* cas_l, cas_wl */
+ MV_DDR_TEMP_LOW} }, /* temperature */
+#if DDR32
+ MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
+#else
+ MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
+#endif
+ MV_DDR_CFG_SPD, /* ddr configuration data src */
+ NOT_COMBINED, /* ddr twin-die combined*/
+ { {0} }, /* raw spd data */
+ {0}, /* timing parameters */
+ { /* electrical configuration */
+ { /* memory electrical configuration */
+ MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */
+ { /* rtt_park 1cs */
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV4,
+ /* rtt_park 2cs */
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV1
+ },
+ { /* rtt_wr 1cs */
+ MV_DDR_RTT_WR_DYN_ODT_OFF,
+ /* rtt_wr 2cs */
+ MV_DDR_RTT_WR_RZQ_DIV2
+ },
+ MV_DDR_DIC_RZQ_DIV7 /* dic */
+ },
+ { /* phy electrical configuration */
+ MV_DDR_OHM_30, /* data_drv_p */
+ MV_DDR_OHM_30, /* data_drv_n */
+ MV_DDR_OHM_30, /* ctrl_drv_p */
+ MV_DDR_OHM_30, /* ctrl_drv_n */
+ {
+ MV_DDR_OHM_60, /* odt_p 1cs */
+ MV_DDR_OHM_120 /* odt_p 2cs */
+ },
+ {
+ MV_DDR_OHM_60, /* odt_n 1cs */
+ MV_DDR_OHM_120 /* odt_n 2cs */
+ },
+ },
+ { /* mac electrical configuration */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */
+ MV_DDR_ODT_CFG_ALWAYS_ON,/* odtcfg_write */
+ MV_DDR_ODT_CFG_NORMAL /* odtcfg_read */
+ },
+ },
+ },
+};
+
+/* Pointer to the first DRAM interface in the system */
+struct mv_ddr_iface *ptr_iface = &dram_iface_ap0;
+
+struct mv_ddr_iface *mv_ddr_iface_get(void)
+{
+ /* Return current ddr interface */
+ return ptr_iface;
+}
+
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
+{
+ /* Return the board topology as defined in the board code */
+ return &ptr_iface->tm;
+}
+
+static void mpp_config(void)
+{
+ uintptr_t reg;
+ uint32_t val;
+
+ reg = MVEBU_CP_MPP_REGS(0, 4);
+ /* configure CP0 MPP 37 and 38 to i2c */
+ val = mmio_read_32(reg);
+ val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) |
+ (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS));
+ val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA <<
+ MVEBU_CP_MPP_CTRL37_OFFS) |
+ (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA <<
+ MVEBU_CP_MPP_CTRL38_OFFS);
+ mmio_write_32(reg, val);
+}
+
+/*
+ * This function may modify the default DRAM parameters
+ * based on information received from SPD or bootloader
+ * configuration located on non volatile storage
+ */
+void plat_marvell_dram_update_topology(void)
+{
+ struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+ INFO("Gathering DRAM information\n");
+
+ if (tm->cfg_src == MV_DDR_CFG_SPD) {
+ /* configure MPPs to enable i2c */
+ mpp_config();
+
+ /* initialize i2c */
+ i2c_init((void *)MVEBU_CP0_I2C_BASE);
+
+ /* select SPD memory page 0 to access DRAM configuration */
+ i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1);
+
+ /* read data from spd */
+ i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes,
+ sizeof(tm->spd_data.all_bytes));
+ }
+}
diff --git a/plat/marvell/octeontx/otx2/t91/t9130/board/marvell_plat_config.c b/plat/marvell/octeontx/otx2/t91/t9130/board/marvell_plat_config.c
new file mode 100644
index 000000000..7debd6582
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130/board/marvell_plat_config.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <armada_common.h>
+#include <mvebu_def.h>
+
+/*
+ * If bootrom is currently at BLE there's no need to include the memory
+ * maps structure at this point
+ */
+#ifndef IMAGE_BLE
+
+/*****************************************************************************
+ * AMB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win amb_memory_map_cp0[] = {
+ /* CP0 SPI1 CS0 Direct Mode access */
+ {0xe800, 0x2000000, AMB_SPI1_CS0_ID},
+};
+
+int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ switch (base) {
+ case MVEBU_CP_REGS_BASE(0):
+ *win = amb_memory_map_cp0;
+ *size = ARRAY_SIZE(amb_memory_map_cp0);
+ return 0;
+ case MVEBU_CP_REGS_BASE(1):
+ case MVEBU_CP_REGS_BASE(2):
+ default:
+ *size = 0;
+ *win = 0;
+ return 1;
+ }
+}
+#endif
+
+/*****************************************************************************
+ * IO WIN Configuration
+ *****************************************************************************
+ */
+struct addr_map_win io_win_memory_map[] = {
+#ifndef IMAGE_BLE
+ /* SB (MCi0) PCIe0-2 on CP1 */
+ {0x00000000e2000000, 0x3000000, MCI_0_TID},
+ /* SB (MCi1) PCIe0-2 on CP2 */
+ {0x00000000e5000000, 0x3000000, MCI_1_TID},
+ /* SB (MCi0) internal regs */
+ {0x00000000f4000000, 0x2000000, MCI_0_TID},
+ /* SB (MCi1) internal regs */
+ {0x00000000f6000000, 0x2000000, MCI_1_TID},
+ /* MCI 0 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID},
+ /* MCI 1 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID},
+#endif
+};
+
+/* Global Control Register - window default target */
+uint32_t marvell_get_io_win_gcr_target(int ap_index)
+{
+ /*
+ * PIDI == iMCIP AP to SB internal MoChi connection.
+ * In other words CP0
+ */
+ return PIDI_TID;
+}
+
+int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = io_win_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(io_win_memory_map);
+
+ return 0;
+}
+
+#ifndef IMAGE_BLE
+/*****************************************************************************
+ * IOB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win iob_memory_map_cp0[] = {
+ /* SPI1_CS0 (RUNIT) window */
+ {0x00000000e8000000, 0x2000000, RUNIT_TID},
+ /* PEX2_X1 window */
+ {0x00000000e1000000, 0x1000000, PEX2_TID},
+ /* PEX1_X1 window */
+ {0x00000000e0000000, 0x1000000, PEX1_TID},
+ /* PEX0_X4 window */
+ {0x00000000c0000000, 0x20000000, PEX0_TID},
+};
+
+struct addr_map_win iob_memory_map_cp1[] = {
+
+ /* PEX2_X1 window */
+ {0x00000000e4000000, 0x1000000, PEX2_TID},
+ /* PEX1_X1 window */
+ {0x00000000e3000000, 0x1000000, PEX1_TID},
+ /* PEX0_X4 window */
+ {0x00000000e2000000, 0x1000000, PEX0_TID},
+};
+
+struct addr_map_win iob_memory_map_cp2[] = {
+
+ /* PEX2_X1 window */
+ {0x00000000e7000000, 0x1000000, PEX2_TID},
+ /* PEX1_X1 window */
+ {0x00000000e6000000, 0x1000000, PEX1_TID},
+ /* PEX0_X4 window */
+ {0x00000000e5000000, 0x1000000, PEX0_TID},
+};
+
+int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ switch (base) {
+ case MVEBU_CP_REGS_BASE(0):
+ *win = iob_memory_map_cp0;
+ *size = ARRAY_SIZE(iob_memory_map_cp0);
+ return 0;
+ case MVEBU_CP_REGS_BASE(1):
+ *win = iob_memory_map_cp1;
+ *size = ARRAY_SIZE(iob_memory_map_cp1);
+ return 0;
+ case MVEBU_CP_REGS_BASE(2):
+ *win = iob_memory_map_cp2;
+ *size = ARRAY_SIZE(iob_memory_map_cp2);
+ return 0;
+ default:
+ *size = 0;
+ *win = 0;
+ return 1;
+ }
+}
+#endif
+
+/*****************************************************************************
+ * CCU Configuration
+ *****************************************************************************
+ */
+struct addr_map_win ccu_memory_map[] = { /* IO window */
+#ifdef IMAGE_BLE
+ {0x00000000f2000000, 0x6000000, IO_0_TID}, /* IO window */
+#else
+#if LLC_SRAM
+ {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, DRAM_0_TID},
+#endif
+ {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */
+ {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */
+ {0x0000002000000000, 0x70e000000, IO_0_TID}, /* IO for CV-OS */
+#endif
+};
+
+uint32_t marvell_get_ccu_gcr_target(int ap)
+{
+ return DRAM_0_TID;
+}
+
+int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = ccu_memory_map;
+ *size = ARRAY_SIZE(ccu_memory_map);
+
+ return 0;
+}
+
+#ifdef IMAGE_BLE
+/*****************************************************************************
+ * SKIP IMAGE Configuration
+ *****************************************************************************
+ */
+void *plat_get_skip_image_data(void)
+{
+ /* No recovery button on CN-9130 board? */
+ return NULL;
+}
+#endif
diff --git a/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h b/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h
new file mode 100644
index 000000000..6b554074c
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __PHY_PORTING_LAYER_H
+#define __PHY_PORTING_LAYER_H
+
+
+#define MAX_LANE_NR 6
+#define XFI_PARAMS static const struct xfi_params
+
+
+XFI_PARAMS xfi_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = {
+ /* AP0 */
+ {
+ /* CP 0 */
+ {
+ { 0 }, /* Comphy0 not relevant*/
+ { 0 }, /* Comphy1 not relevant*/
+ { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf,
+ .align90 = 0x5f,
+ .g1_dfe_res = 0x2, .g1_amp = 0x1c,
+ .g1_emph = 0xe,
+ .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1,
+ .g1_tx_emph_en = 0x1,
+ .g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1,
+ .g1_rx_selmufi = 0x0,
+ .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+ .valid = 1 }, /* Comphy2 */
+ { 0 }, /* Comphy3 not relevant*/
+ { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf,
+ .align90 = 0x5f,
+ .g1_dfe_res = 0x2, .g1_amp = 0x1c,
+ .g1_emph = 0xe,
+ .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1,
+ .g1_tx_emph_en = 0x1,
+ .g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1,
+ .g1_rx_selmufi = 0x0,
+ .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+ .valid = 1 }, /* Comphy4 */
+ { 0 }, /* Comphy5 not relevant*/
+ },
+#if CP_NUM > 1
+ /* CP 1 */
+ {
+ { 0 }, /* Comphy0 not relevant*/
+ { 0 }, /* Comphy1 not relevant*/
+ { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf,
+ .align90 = 0x5f,
+ .g1_dfe_res = 0x2, .g1_amp = 0x1c,
+ .g1_emph = 0xe,
+ .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1,
+ .g1_tx_emph_en = 0x1,
+ .g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1,
+ .g1_rx_selmufi = 0x0,
+ .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+ .valid = 1 }, /* Comphy2 */
+ { 0 }, /* Comphy3 not relevant*/
+ /* different from defaults */
+ { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf,
+ .align90 = 0x5f,
+ .g1_dfe_res = 0x2, .g1_amp = 0xc,
+ .g1_emph = 0x5,
+ .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1,
+ .g1_tx_emph_en = 0x1,
+ .g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1,
+ .g1_rx_selmufi = 0x0,
+ .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+ .valid = 1}, /* Comphy4 */
+ { 0 }, /* Comphy5 not relevant*/
+ },
+#if CP_NUM > 2
+ /* CP 2 */
+ {
+ { 0 }, /* Comphy0 not relevant*/
+ { 0 }, /* Comphy1 not relevant*/
+ { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf,
+ .align90 = 0x5f,
+ .g1_dfe_res = 0x2, .g1_amp = 0x1c,
+ .g1_emph = 0xe,
+ .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1,
+ .g1_tx_emph_en = 0x1,
+ .g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1,
+ .g1_rx_selmufi = 0x0,
+ .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+ .valid = 1 }, /* Comphy2 */
+ { 0 }, /* Comphy3 not relevant*/
+ { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf,
+ .align90 = 0x5f,
+ .g1_dfe_res = 0x2, .g1_amp = 0x1c,
+ .g1_emph = 0xe,
+ .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1,
+ .g1_tx_emph_en = 0x1,
+ .g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1,
+ .g1_rx_selmufi = 0x0,
+ .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+ .valid = 1 }, /* Comphy4 */
+ { 0 }, /* Comphy5 not relevant*/
+ },
+#endif
+#endif
+ },
+};
+
+#define SATA_PARAMS static const struct sata_params
+SATA_PARAMS sata_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = {
+ [0 ... AP_NUM-1][0 ... CP_NUM-1][0 ... MAX_LANE_NR-1] = {
+ .g1_amp = 0x8, .g2_amp = 0xa,
+ .g3_amp = 0x1e,
+ .g1_emph = 0x1, .g2_emph = 0x2,
+ .g3_emph = 0xe,
+ .g1_emph_en = 0x1, .g2_emph_en = 0x1,
+ .g3_emph_en = 0x1,
+ .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1,
+ .g3_tx_amp_adj = 0x1,
+ .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0,
+ .g3_tx_emph_en = 0x0,
+ .g1_tx_emph = 0x1, .g2_tx_emph = 0x1,
+ .g3_tx_emph = 0x1,
+ .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4,
+ .g3_ffe_cap_sel = 0xf,
+ .align90 = 0x61,
+ .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3,
+ .g3_rx_selmuff = 0x3,
+ .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0,
+ .g3_rx_selmufi = 0x3,
+ .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1,
+ .g3_rx_selmupf = 0x2,
+ .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0,
+ .g3_rx_selmupi = 0x2,
+ .polarity_invert = COMPHY_POLARITY_NO_INVERT,
+ .valid = 0x1
+ },
+};
+
+static const struct usb_params
+ usb_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = {
+ [0 ... AP_NUM-1][0 ... CP_NUM-1][0 ... MAX_LANE_NR-1] = {
+ .polarity_invert = COMPHY_POLARITY_NO_INVERT
+ },
+};
+#endif /* __PHY_PORTING_LAYER_H */
diff --git a/plat/marvell/octeontx/otx2/t91/t9130/mvebu_def.h b/plat/marvell/octeontx/otx2/t91/t9130/mvebu_def.h
new file mode 100644
index 000000000..490be7350
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130/mvebu_def.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MVEBU_DEF_H__
+#define __MVEBU_DEF_H__
+
+#include <a8k_plat_def.h>
+
+/*
+ * CN-9130 has single CP0 inside the package and 2 additional one
+ * from MoChi interface. In case of db-9130-modular board the MCI interface
+ * is routed to:
+ * - on-board CP115 (MCI0)
+ * - extension board CP115 (MCI1)
+ */
+#define CP_COUNT CP_NUM
+#define MVEBU_SOC_AP807 1
+#define I2C_SPD_ADDR 0x53 /* Access SPD data */
+#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */
+
+#endif /* __MVEBU_DEF_H__ */
diff --git a/plat/marvell/octeontx/otx2/t91/t9130/platform.mk b/plat/marvell/octeontx/otx2/t91/t9130/platform.mk
new file mode 100644
index 000000000..1e2716df0
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130/platform.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+PCI_EP_SUPPORT := 0
+
+CP_NUM := 1
+$(eval $(call add_define,CP_NUM))
+
+DOIMAGE_SEC := tools/doimage/secure/sec_img_7K.cfg
+
+MARVELL_MOCHI_DRV := drivers/marvell/mochi/ap807_setup.c
+
+BOARD_DIR := $(shell dirname $(lastword $(MAKEFILE_LIST)))
+include plat/marvell/armada/a8k/common/a8k_common.mk
+
+include plat/marvell/armada/common/marvell_common.mk
diff --git a/plat/marvell/version.mk b/plat/marvell/version.mk
index e072e12d5..bb2225537 100644
--- a/plat/marvell/version.mk
+++ b/plat/marvell/version.mk
@@ -1 +1 @@
-SUBVERSION = devel-18.12.0
+SUBVERSION = devel-18.12.2
diff --git a/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c b/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c
new file mode 100644
index 000000000..fca69130a
--- /dev/null
+++ b/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include "platform_def.h"
+#include "pmic_wrap_init.h"
+
+/* pmic wrap module wait_idle and read polling interval (in microseconds) */
+enum pwrap_polling_interval {
+ WAIT_IDLE_POLLING_DELAY_US = 1,
+ READ_POLLING_DELAY_US = 2
+};
+
+static uint32_t pwrap_check_idle(void *wacs_register, uint32_t timeout_us)
+{
+ uint32_t reg_rdata = 0U, retry;
+
+ retry = (timeout_us + WAIT_IDLE_POLLING_DELAY_US) /
+ WAIT_IDLE_POLLING_DELAY_US;
+ while (retry != 0) {
+ udelay(WAIT_IDLE_POLLING_DELAY_US);
+ reg_rdata = mmio_read_32((uintptr_t)wacs_register);
+ if (GET_WACS_FSM(reg_rdata) == SWINF_FSM_IDLE) {
+ break;
+ }
+ retry--;
+ };
+
+ if (retry == 0) {
+ /* timeout */
+ return E_PWR_WAIT_IDLE_TIMEOUT;
+ }
+
+ return 0U;
+}
+
+static uint32_t pwrap_check_vldclr(void *wacs_register, uint32_t timeout_us)
+{
+ uint32_t reg_rdata = 0U, retry;
+
+ retry = (timeout_us + READ_POLLING_DELAY_US) / READ_POLLING_DELAY_US;
+ while (retry != 0) {
+ udelay(READ_POLLING_DELAY_US);
+ reg_rdata = mmio_read_32((uintptr_t)wacs_register);
+ if (GET_WACS_FSM(reg_rdata) == SWINF_FSM_WFVLDCLR) {
+ break;
+ }
+ retry--;
+ };
+
+ if (retry == 0) {
+ /* timeout */
+ return E_PWR_WAIT_IDLE_TIMEOUT;
+ }
+
+ return 0U;
+}
+
+static int32_t pwrap_wacs2(uint32_t write, uint32_t adr, uint32_t wdata,
+ uint32_t *rdata, uint32_t init_check)
+{
+ uint32_t reg_rdata, return_value;
+
+ if (init_check != 0) {
+ if ((mmio_read_32((uintptr_t)&mtk_pwrap->init_done) & 0x1) == 0) {
+ ERROR("initialization isn't finished\n");
+ return E_PWR_NOT_INIT_DONE;
+ }
+ }
+
+ /* Wait for Software Interface FSM state to be IDLE. */
+ return_value = pwrap_check_idle(&mtk_pwrap->wacs2_sta,
+ PWRAP_WAIT_IDLE_US);
+ if (return_value != 0) {
+ return return_value;
+ }
+
+ /* Set the write data */
+ if (write == 1) {
+ /* Set the write data. */
+ mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_wdata, wdata);
+ }
+
+ /* Send the command. */
+ mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_cmd, (write << 29) | adr);
+
+ if (write == 0) {
+ /*
+ * Wait for Software Interface FSM state to be WFVLDCLR,
+ * read the data and clear the valid flag.
+ */
+ return_value = pwrap_check_vldclr(&mtk_pwrap->wacs2_sta,
+ PWRAP_READ_US);
+ if (return_value != 0) {
+ return return_value;
+ }
+
+ if (rdata == NULL) {
+ return E_PWR_INVALID_ARG;
+ }
+
+ reg_rdata = mmio_read_32((uintptr_t)&mtk_pwrap->wacs2_rdata);
+ *rdata = reg_rdata;
+ mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_vldclr, 0x1);
+ }
+
+ return return_value;
+}
+
+/* external API for pmic_wrap user */
+int32_t pwrap_read(uint32_t adr, uint32_t *rdata)
+{
+ return pwrap_wacs2(0, adr, 0, rdata, 1);
+}
+
+int32_t pwrap_write(uint32_t adr, uint32_t wdata)
+{
+ return pwrap_wacs2(1, adr, wdata, 0, 1);
+}
diff --git a/plat/mediatek/common/drivers/uart/8250_console.S b/plat/mediatek/common/drivers/uart/8250_console.S
index 94a6c02ab..7a946f9a3 100644
--- a/plat/mediatek/common/drivers/uart/8250_console.S
+++ b/plat/mediatek/common/drivers/uart/8250_console.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -149,16 +149,15 @@ getc_error:
endfunc console_core_getc
/* ---------------------------------------------
- * int console_core_flush(uintptr_t base_addr)
+ * void console_core_flush(uintptr_t base_addr)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - console base address
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : x0, x1
* ---------------------------------------------
*/
func console_core_flush
/* Placeholder */
- mov w0, #0
ret
endfunc console_core_flush
diff --git a/plat/mediatek/mt8183/drivers/uart/uart.c b/plat/mediatek/common/drivers/uart/uart.c
index 3c6a98036..b940eb339 100644
--- a/plat/mediatek/mt8183/drivers/uart/uart.c
+++ b/plat/mediatek/common/drivers/uart/uart.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,7 +9,7 @@
static struct mt_uart uart_save_addr[DRV_SUPPORT_UART_PORTS];
-static const unsigned int uart_base_addr[DRV_SUPPORT_UART_PORTS] = {
+static const uint32_t uart_base_addr[DRV_SUPPORT_UART_PORTS] = {
UART0_BASE,
UART1_BASE
};
@@ -99,13 +99,14 @@ void mt_uart_save(void)
void mt_console_uart_cg(int on)
{
- if (on)
+ if (on == 1) {
mmio_write_32(UART_CLOCK_GATE_CLR, UART0_CLOCK_GATE_BIT);
- else
+ } else {
mmio_write_32(UART_CLOCK_GATE_SET, UART0_CLOCK_GATE_BIT);
+ }
}
-int mt_console_uart_cg_status(void)
+uint32_t mt_console_uart_cg_status(void)
{
return mmio_read_32(UART_CLOCK_GATE_STA) & UART0_CLOCK_GATE_BIT;
}
diff --git a/plat/mediatek/common/mtk_plat_common.c b/plat/mediatek/common/mtk_plat_common.c
index a07a2981a..f57e4357d 100644
--- a/plat/mediatek/common/mtk_plat_common.c
+++ b/plat/mediatek/common/mtk_plat_common.c
@@ -10,8 +10,10 @@
#include <drivers/arm/cci.h>
#include <drivers/console.h>
#include <lib/mmio.h>
+#include <lib/smccc.h>
#include <lib/xlat_tables/xlat_tables.h>
#include <plat/common/platform.h>
+#include <services/arm_arch_svc.h>
#include <mtk_plat_common.h>
#include <mtk_sip_svc.h>
@@ -116,3 +118,33 @@ uint32_t plat_get_spsr_for_bl33_entry(void)
spsr = SPSR_MODE32(mode, 0, ee, daif);
return spsr;
}
+
+/*****************************************************************************
+ * plat_is_smccc_feature_available() - This function checks whether SMCCC
+ * feature is availabile for platform.
+ * @fid: SMCCC function id
+ *
+ * Return SMC_OK if SMCCC feature is available and SMC_ARCH_CALL_NOT_SUPPORTED
+ * otherwise.
+ *****************************************************************************/
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+ switch (fid) {
+ case SMCCC_ARCH_SOC_ID:
+ return SMC_ARCH_CALL_SUCCESS;
+ default:
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+ }
+}
+
+int32_t plat_get_soc_version(void)
+{
+ uint32_t manfid = (JEDEC_MTK_BKID << 24U) | (JEDEC_MTK_MFID << 16U);
+
+ return (int32_t)(manfid | (SOC_CHIP_ID & 0xFFFFU));
+}
+
+int32_t plat_get_soc_revision(void)
+{
+ return 0;
+}
diff --git a/plat/mediatek/common/mtk_plat_common.h b/plat/mediatek/common/mtk_plat_common.h
index 55f4c516e..919c17358 100644
--- a/plat/mediatek/common/mtk_plat_common.h
+++ b/plat/mediatek/common/mtk_plat_common.h
@@ -18,6 +18,9 @@
#define LINUX_KERNEL_32 0
#define SMC32_PARAM_MASK (0xFFFFFFFF)
+#define JEDEC_MTK_BKID U(4)
+#define JEDEC_MTK_MFID U(0x26)
+
struct atf_arg_t {
unsigned int atf_magic;
unsigned int tee_support;
diff --git a/plat/mediatek/mt6795/aarch64/plat_helpers.S b/plat/mediatek/mt6795/aarch64/plat_helpers.S
index 94f9eaef9..aaddb2bba 100644
--- a/plat/mediatek/mt6795/aarch64/plat_helpers.S
+++ b/plat/mediatek/mt6795/aarch64/plat_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -123,10 +123,10 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush(int c)
+ * void plat_crash_console_flush(int c)
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : x0, x1
* ---------------------------------------------
*/
diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S
index cf68b711e..3d881fc43 100644
--- a/plat/mediatek/mt6795/bl31.ld.S
+++ b/plat/mediatek/mt6795/bl31.ld.S
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <common/bl_common.ld.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
-#include <platform_def.h>
OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
@@ -38,20 +38,7 @@ SECTIONS
*(.text*)
*(.rodata*)
- /* Ensure 8-byte alignment for descriptors and ensure inclusion */
- . = ALIGN(8);
- __RT_SVC_DESCS_START__ = .;
- KEEP(*(rt_svc_descs))
- __RT_SVC_DESCS_END__ = .;
-
- /*
- * Ensure 8-byte alignment for cpu_ops so that its fields are also
- * aligned. Also ensure cpu_ops inclusion.
- */
- . = ALIGN(8);
- __CPU_OPS_START__ = .;
- KEEP(*(cpu_ops))
- __CPU_OPS_END__ = .;
+ RODATA_COMMON
__RO_END_UNALIGNED__ = .;
/*
@@ -72,74 +59,19 @@ SECTIONS
*/
__RW_START__ = . ;
- /*
- * .data must be placed at a lower address than the stacks if the stack
- * protector is enabled. Alternatively, the .data.stack_protector_canary
- * section can be placed independently of the main .data section.
- */
- .data . : {
- __DATA_START__ = .;
- *(.data*)
- __DATA_END__ = .;
- } >RAM
+ DATA_SECTION >RAM
#ifdef BL31_PROGBITS_LIMIT
ASSERT(. <= BL31_PROGBITS_LIMIT, "BL3-1 progbits has exceeded its limit.")
#endif
- stacks (NOLOAD) : {
- __STACKS_START__ = .;
- *(tzfw_normal_stacks)
- __STACKS_END__ = .;
- } >RAM
-
- /*
- * The .bss section gets initialised to 0 at runtime.
- * Its base address should be 16-byte aligned for better performance of the
- * zero-initialization code.
- */
- .bss (NOLOAD) : ALIGN(16) {
- __BSS_START__ = .;
- *(.bss*)
- *(COMMON)
-#if !USE_COHERENT_MEM
- /*
- * Bakery locks are stored in normal .bss memory
- *
- * Each lock's data is spread across multiple cache lines, one per CPU,
- * but multiple locks can share the same cache line.
- * The compiler will allocate enough memory for one CPU's bakery locks,
- * the remaining cache lines are allocated by the linker script
- */
- . = ALIGN(CACHE_WRITEBACK_GRANULE);
- __BAKERY_LOCK_START__ = .;
- __PERCPU_BAKERY_LOCK_START__ = .;
- *(bakery_lock)
- . = ALIGN(CACHE_WRITEBACK_GRANULE);
- __PERCPU_BAKERY_LOCK_END__ = .;
- __PERCPU_BAKERY_LOCK_SIZE__ = ABSOLUTE(__PERCPU_BAKERY_LOCK_END__ - __PERCPU_BAKERY_LOCK_START__);
- . = . + (__PERCPU_BAKERY_LOCK_SIZE__ * (PLATFORM_CORE_COUNT - 1));
- __BAKERY_LOCK_END__ = .;
-#ifdef PLAT_PERCPU_BAKERY_LOCK_SIZE
- ASSERT(__PERCPU_BAKERY_LOCK_SIZE__ == PLAT_PERCPU_BAKERY_LOCK_SIZE,
- "PLAT_PERCPU_BAKERY_LOCK_SIZE does not match bakery lock requirements");
-#endif
-#endif
- __BSS_END__ = .;
- __RW_END__ = .;
- } >RAM
+ STACK_SECTION >RAM
+ BSS_SECTION >RAM
+ __RW_END__ = __BSS_END__;
ASSERT(. <= BL31_LIMIT, "BL3-1 image has exceeded its limit.")
- /*
- * The xlat_table section is for full, aligned page tables (4K).
- * Removing them from .bss avoids forcing 4K alignment on
- * the .bss section. The tables are initialized to zero by the translation
- * tables library.
- */
- xlat_table (NOLOAD) : {
- *(xlat_table)
- } >RAM2
+ XLAT_TABLE_SECTION >RAM2
#if USE_COHERENT_MEM
/*
diff --git a/plat/mediatek/mt8173/bl31_plat_setup.c b/plat/mediatek/mt8173/bl31_plat_setup.c
index 73a479b50..bd7d0b0ee 100644
--- a/plat/mediatek/mt8173/bl31_plat_setup.c
+++ b/plat/mediatek/mt8173/bl31_plat_setup.c
@@ -100,7 +100,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_16550_t console;
+ static console_t console;
console_16550_register(MT8173_UART0_BASE, MT8173_UART_CLOCK, MT8173_BAUDRATE, &console);
diff --git a/plat/mediatek/mt8173/drivers/wdt/wdt.c b/plat/mediatek/mt8173/drivers/wdt/wdt.c
new file mode 100644
index 000000000..40f57eed2
--- /dev/null
+++ b/plat/mediatek/mt8173/drivers/wdt/wdt.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <mt8173_def.h>
+#include <plat_sip_calls.h>
+#include <lib/psci/psci.h>
+#include <smccc_helpers.h>
+#include <wdt.h>
+
+#define WDT_BASE (RGU_BASE + 0)
+#define WDT_MODE (WDT_BASE + 0x00)
+#define WDT_LENGTH (WDT_BASE + 0x04)
+#define WDT_RESTART (WDT_BASE + 0x08)
+#define WDT_SWRST (WDT_BASE + 0x14)
+
+#define WDT_MODE_DUAL_MODE 0x40
+#define WDT_MODE_IRQ 0x8
+#define WDT_MODE_KEY 0x22000000
+#define WDT_MODE_EXTEN 0x4
+#define WDT_MODE_EN 0x1
+#define WDT_LENGTH_KEY 0x8
+#define WDT_RESTART_KEY 0x1971
+#define WDT_SWRST_KEY 0x1209
+
+
+#define WDT_MIN_TIMEOUT 1
+#define WDT_MAX_TIMEOUT 31
+
+enum smcwd_call {
+ SMCWD_INFO = 0,
+ SMCWD_SET_TIMEOUT = 1,
+ SMCWD_ENABLE = 2,
+ SMCWD_PET = 3,
+};
+
+static int wdt_enabled_before_suspend;
+
+/*
+ * We expect the WDT registers to be correctly initialized by BL2 firmware
+ * (which may be board specific), so we do not reinitialize them here.
+ */
+
+void wdt_trigger_reset(void)
+{
+ mmio_write_32(WDT_SWRST, WDT_SWRST_KEY);
+}
+
+void wdt_pet(void)
+{
+ mmio_write_32(WDT_RESTART, WDT_RESTART_KEY);
+}
+
+int wdt_set_timeout(uint32_t timeout)
+{
+ /* One tick here equals 512 32KHz ticks. 512 / 32000 * 125 / 2 = 1 */
+ uint32_t ticks = timeout * 125 / 2;
+
+ if (timeout < WDT_MIN_TIMEOUT || timeout > WDT_MAX_TIMEOUT)
+ return PSCI_E_INVALID_PARAMS;
+
+ mmio_write_32(WDT_LENGTH, ticks << 5 | WDT_LENGTH_KEY);
+
+ return PSCI_E_SUCCESS;
+}
+
+void wdt_set_enable(int enable)
+{
+ if (enable)
+ wdt_pet();
+ mmio_clrsetbits_32(WDT_MODE, WDT_MODE_EN,
+ WDT_MODE_KEY | (enable ? WDT_MODE_EN : 0));
+}
+
+void wdt_suspend(void)
+{
+ wdt_enabled_before_suspend = mmio_read_32(WDT_MODE) & WDT_MODE_EN;
+ if (wdt_enabled_before_suspend)
+ wdt_set_enable(0);
+}
+
+void wdt_resume(void)
+{
+ if (wdt_enabled_before_suspend)
+ wdt_set_enable(1);
+}
+
+uint64_t wdt_smc_handler(uint32_t x1,
+ uint32_t x2,
+ void *handle)
+{
+ int ret;
+
+ switch (x1) {
+ case SMCWD_INFO:
+ SMC_RET3(handle, PSCI_E_SUCCESS,
+ WDT_MIN_TIMEOUT, WDT_MAX_TIMEOUT);
+ case SMCWD_SET_TIMEOUT:
+ ret = wdt_set_timeout(x2);
+ SMC_RET1(handle, ret);
+ case SMCWD_ENABLE:
+ wdt_set_enable(x2 > 0);
+ SMC_RET1(handle, PSCI_E_SUCCESS);
+ case SMCWD_PET:
+ wdt_pet();
+ SMC_RET1(handle, PSCI_E_SUCCESS);
+ default:
+ ERROR("Unimplemented SMCWD call (%d)\n", x1);
+ SMC_RET1(handle, PSCI_E_NOT_SUPPORTED);
+ }
+}
diff --git a/plat/mediatek/mt8173/drivers/wdt/wdt.h b/plat/mediatek/mt8173/drivers/wdt/wdt.h
new file mode 100644
index 000000000..7262a5717
--- /dev/null
+++ b/plat/mediatek/mt8173/drivers/wdt/wdt.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef WDT_H
+#define WDT_H
+
+#include "stdint.h"
+
+void wdt_pet(void);
+void wdt_resume(void);
+void wdt_set_enable(int enable);
+int wdt_set_timeout(uint32_t timeout);
+uint64_t wdt_smc_handler(uint32_t x1, uint32_t x2, void *handle);
+void wdt_suspend(void);
+void wdt_trigger_reset(void);
+
+#endif /* WDT_H */
diff --git a/plat/mediatek/mt8173/include/mt8173_def.h b/plat/mediatek/mt8173/include/mt8173_def.h
index 58962f03d..378b4da55 100644
--- a/plat/mediatek/mt8173/include/mt8173_def.h
+++ b/plat/mediatek/mt8173/include/mt8173_def.h
@@ -80,18 +80,6 @@
#define PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX 4
#define PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX 3
-/*******************************************************************************
- * WDT related constants
- ******************************************************************************/
-#define MTK_WDT_BASE (RGU_BASE + 0)
-#define MTK_WDT_SWRST (MTK_WDT_BASE + 0x0014)
-
-#define MTK_WDT_MODE_DUAL_MODE 0x0040
-#define MTK_WDT_MODE_IRQ 0x0008
-#define MTK_WDT_MODE_KEY 0x22000000
-#define MTK_WDT_MODE_EXTEN 0x0004
-#define MTK_WDT_SWRST_KEY 0x1209
-
/* FIQ platform related define */
#define MT_IRQ_SEC_SGI_0 8
#define MT_IRQ_SEC_SGI_1 9
diff --git a/plat/mediatek/mt8173/include/plat_sip_calls.h b/plat/mediatek/mt8173/include/plat_sip_calls.h
index 88202cc55..ce9951a67 100644
--- a/plat/mediatek/mt8173/include/plat_sip_calls.h
+++ b/plat/mediatek/mt8173/include/plat_sip_calls.h
@@ -10,7 +10,7 @@
/*******************************************************************************
* Plat SiP function constants
******************************************************************************/
-#define MTK_PLAT_SIP_NUM_CALLS 6
+#define MTK_PLAT_SIP_NUM_CALLS 7
#define MTK_SIP_PWR_ON_MTCMOS 0x82000402
#define MTK_SIP_PWR_OFF_MTCMOS 0x82000403
@@ -18,5 +18,6 @@
#define MTK_SIP_SET_HDCP_KEY_NUM 0x82000405
#define MTK_SIP_CLR_HDCP_KEY 0x82000406
#define MTK_SIP_SET_HDCP_KEY_EX 0x82000407
+#define MTK_SIP_SMC_WATCHDOG 0x82003D06
#endif /* PLAT_SIP_CALLS_H */
diff --git a/plat/mediatek/mt8173/include/platform_def.h b/plat/mediatek/mt8173/include/platform_def.h
index 22129db13..d34042218 100644
--- a/plat/mediatek/mt8173/include/platform_def.h
+++ b/plat/mediatek/mt8173/include/platform_def.h
@@ -51,6 +51,8 @@
PLATFORM_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT)
+#define SOC_CHIP_ID U(0x8173)
+
/*******************************************************************************
* Platform memory map related constants
******************************************************************************/
diff --git a/plat/mediatek/mt8173/plat_pm.c b/plat/mediatek/mt8173/plat_pm.c
index 67f1c731b..e72a3434e 100644
--- a/plat/mediatek/mt8173/plat_pm.c
+++ b/plat/mediatek/mt8173/plat_pm.c
@@ -27,6 +27,7 @@
#include <spm_hotplug.h>
#include <spm_mcdi.h>
#include <spm_suspend.h>
+#include <wdt.h>
#define MTK_PWR_LVL0 0
#define MTK_PWR_LVL1 1
@@ -350,6 +351,7 @@ static void plat_power_domain_suspend(const psci_power_state_t *state)
}
if (MTK_SYSTEM_PWR_STATE(state) == MTK_LOCAL_STATE_OFF) {
+ wdt_suspend();
disable_scu(mpidr);
generic_timer_backup();
spm_system_suspend();
@@ -409,6 +411,7 @@ static void plat_power_domain_suspend_finish(const psci_power_state_t *state)
plat_arm_gic_init();
spm_system_suspend_finish();
enable_scu(mpidr);
+ wdt_resume();
}
/* Perform the common cluster specific operations */
@@ -455,11 +458,7 @@ static void __dead2 plat_system_reset(void)
/* Write the System Configuration Control Register */
INFO("MTK System Reset\n");
- mmio_clrsetbits_32(MTK_WDT_BASE,
- (MTK_WDT_MODE_DUAL_MODE | MTK_WDT_MODE_IRQ),
- MTK_WDT_MODE_KEY);
- mmio_setbits_32(MTK_WDT_BASE, (MTK_WDT_MODE_KEY | MTK_WDT_MODE_EXTEN));
- mmio_setbits_32(MTK_WDT_SWRST, MTK_WDT_SWRST_KEY);
+ wdt_trigger_reset();
wfi();
ERROR("MTK System Reset: operation not handled.\n");
diff --git a/plat/mediatek/mt8173/plat_sip_calls.c b/plat/mediatek/mt8173/plat_sip_calls.c
index 102feb22a..da9b91dd6 100644
--- a/plat/mediatek/mt8173/plat_sip_calls.c
+++ b/plat/mediatek/mt8173/plat_sip_calls.c
@@ -12,6 +12,7 @@
#include <mtcmos.h>
#include <mtk_sip_svc.h>
#include <plat_sip_calls.h>
+#include <wdt.h>
/* Authorized secure register list */
enum {
@@ -102,6 +103,9 @@ uint64_t mediatek_plat_sip_handler(uint32_t smc_fid,
ret = crypt_clear_hdcp_key();
SMC_RET1(handle, ret);
+ case MTK_SIP_SMC_WATCHDOG:
+ return wdt_smc_handler(x1, x2, handle);
+
default:
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
break;
diff --git a/plat/mediatek/mt8173/platform.mk b/plat/mediatek/mt8173/platform.mk
index a66c49bb4..f62802cb9 100644
--- a/plat/mediatek/mt8173/platform.mk
+++ b/plat/mediatek/mt8173/platform.mk
@@ -15,6 +15,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
-I${MTK_PLAT_SOC}/drivers/rtc/ \
-I${MTK_PLAT_SOC}/drivers/spm/ \
-I${MTK_PLAT_SOC}/drivers/timer/ \
+ -I${MTK_PLAT_SOC}/drivers/wdt/ \
-I${MTK_PLAT_SOC}/include/
PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
@@ -50,6 +51,7 @@ BL31_SOURCES += common/desc_image_load.c \
${MTK_PLAT_SOC}/drivers/spm/spm_mcdi.c \
${MTK_PLAT_SOC}/drivers/spm/spm_suspend.c \
${MTK_PLAT_SOC}/drivers/timer/mt_cpuxgpt.c \
+ ${MTK_PLAT_SOC}/drivers/wdt/wdt.c \
${MTK_PLAT_SOC}/plat_pm.c \
${MTK_PLAT_SOC}/plat_sip_calls.c \
${MTK_PLAT_SOC}/plat_topology.c \
diff --git a/plat/mediatek/mt8183/bl31_plat_setup.c b/plat/mediatek/mt8183/bl31_plat_setup.c
index 8204d7717..7dac8a49b 100644
--- a/plat/mediatek/mt8183/bl31_plat_setup.c
+++ b/plat/mediatek/mt8183/bl31_plat_setup.c
@@ -16,6 +16,7 @@
#include <drivers/generic_delay_timer.h>
#include <mcucfg.h>
#include <mt_gic_v3.h>
+#include <mt_timer.h>
#include <lib/coreboot.h>
#include <lib/mmio.h>
#include <mtk_mcdi.h>
@@ -112,7 +113,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_16550_t console;
+ static console_t console;
params_early_setup(arg1);
@@ -148,6 +149,8 @@ void bl31_platform_setup(void)
mt_gic_driver_init();
mt_gic_init();
+ mt_systimer_init();
+
/* Init mcsi SF */
plat_mtk_cci_init_sf();
diff --git a/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c
index 64d854885..56d2ce26c 100644
--- a/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c
+++ b/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c
@@ -138,15 +138,9 @@ void emi_mpu_init(void)
(FORBIDDEN << 6));
emi_mpu_set_region_protection(0x52900000UL, 0x5FFFFFFFUL, 2,
(FORBIDDEN << 3 | FORBIDDEN << 6));
- emi_mpu_set_region_protection(0x60000000UL, 0x7FFFFFFFUL, 3,
+ emi_mpu_set_region_protection(0x60000000UL, 0xFFFFFFFFUL, 3,
(FORBIDDEN << 3 | FORBIDDEN << 6));
- emi_mpu_set_region_protection(0x80000000UL, 0x9FFFFFFFUL, 4,
- (FORBIDDEN << 3 | FORBIDDEN << 6));
- emi_mpu_set_region_protection(0xA0000000UL, 0xBFFFFFFFUL, 5,
- (FORBIDDEN << 3 | FORBIDDEN << 6));
- emi_mpu_set_region_protection(0xC0000000UL, 0xDFFFFFFFUL, 6,
- (FORBIDDEN << 3 | FORBIDDEN << 6));
- emi_mpu_set_region_protection(0xE0000000UL, 0xFFFFFFFFUL, 7,
+ emi_mpu_set_region_protection(0x100000000UL, 0x23FFFFFFFUL, 4,
(FORBIDDEN << 3 | FORBIDDEN << 6));
dump_emi_mpu_regions();
}
diff --git a/plat/mediatek/mt8183/drivers/timer/mt_timer.c b/plat/mediatek/mt8183/drivers/timer/mt_timer.c
new file mode 100644
index 000000000..0da4815b1
--- /dev/null
+++ b/plat/mediatek/mt8183/drivers/timer/mt_timer.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <mcucfg.h>
+#include <mt_timer.h>
+#include <platform_def.h>
+
+static void enable_systimer_compensation(void)
+{
+ unsigned int reg;
+
+ reg = mmio_read_32(CNTCR_REG);
+ reg &= ~COMP_15_EN;
+ reg |= COMP_20_EN;
+ mmio_write_32(CNTCR_REG, reg);
+
+ NOTICE("[systimer] CNTCR_REG(0x%x)\n", mmio_read_32(CNTCR_REG));
+}
+
+void mt_systimer_init(void)
+{
+ /* systimer is default on, so we only enable systimer compensation */
+ enable_systimer_compensation();
+}
diff --git a/plat/mediatek/mt8183/drivers/timer/mt_timer.h b/plat/mediatek/mt8183/drivers/timer/mt_timer.h
new file mode 100644
index 000000000..0b8edc517
--- /dev/null
+++ b/plat/mediatek/mt8183/drivers/timer/mt_timer.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_TIMER_H
+#define MT_TIMER_H
+
+
+#define SYSTIMER_BASE (0x10017000)
+#define CNTCR_REG (SYSTIMER_BASE + 0x0)
+#define CNTSR_REG (SYSTIMER_BASE + 0x4)
+
+#define COMP_15_EN (1 << 10)
+#define COMP_20_EN (1 << 11)
+
+void mt_systimer_init(void);
+
+#endif /* MT_TIMER_H */
diff --git a/plat/mediatek/mt8183/drivers/uart/uart.h b/plat/mediatek/mt8183/drivers/uart/uart.h
index be04c3509..062ce3adc 100644
--- a/plat/mediatek/mt8183/drivers/uart/uart.h
+++ b/plat/mediatek/mt8183/drivers/uart/uart.h
@@ -95,6 +95,6 @@ struct mt_uart {
void mt_uart_save(void);
void mt_uart_restore(void);
void mt_console_uart_cg(int on);
-int mt_console_uart_cg_status(void);
+uint32_t mt_console_uart_cg_status(void);
#endif /* __UART_H__ */
diff --git a/plat/mediatek/mt8183/include/platform_def.h b/plat/mediatek/mt8183/include/platform_def.h
index 49a0f805e..25ccfbc52 100644
--- a/plat/mediatek/mt8183/include/platform_def.h
+++ b/plat/mediatek/mt8183/include/platform_def.h
@@ -279,6 +279,8 @@ INTR_PROP_DESC(MT_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
PLATFORM_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT)
+#define SOC_CHIP_ID U(0x8183)
+
/*******************************************************************************
* Platform memory map related constants
******************************************************************************/
diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk
index 597e18b90..07da1afac 100644
--- a/plat/mediatek/mt8183/platform.mk
+++ b/plat/mediatek/mt8183/platform.mk
@@ -14,6 +14,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
-I${MTK_PLAT_SOC}/drivers/mcdi/ \
-I${MTK_PLAT_SOC}/drivers/spmc/ \
-I${MTK_PLAT_SOC}/drivers/gpio/ \
+ -I${MTK_PLAT_SOC}/drivers/timer/ \
-I${MTK_PLAT_SOC}/drivers/pmic/ \
-I${MTK_PLAT_SOC}/drivers/spm/ \
-I${MTK_PLAT_SOC}/drivers/sspm/ \
@@ -26,13 +27,12 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/aarch64/xlat_tables.c \
plat/common/plat_psci_common.c \
plat/common/aarch64/crash_console_helpers.S
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
BL31_SOURCES += common/desc_image_load.c \
drivers/arm/cci/cci.c \
- drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v3/arm_gicv3_common.c \
- drivers/arm/gic/v3/gicv3_helpers.c \
- drivers/arm/gic/v3/gic500.c \
- drivers/arm/gic/v3/gicv3_main.c \
+ ${GICV3_SOURCES} \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
drivers/gpio/gpio.c \
@@ -45,6 +45,7 @@ BL31_SOURCES += common/desc_image_load.c \
${MTK_PLAT}/common/mtk_plat_common.c \
${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init.c \
${MTK_PLAT}/common/drivers/rtc/rtc_common.c \
+ ${MTK_PLAT}/common/drivers/uart/uart.c \
${MTK_PLAT}/common/params_setup.c \
${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
${MTK_PLAT_SOC}/aarch64/platform_common.c \
@@ -58,7 +59,7 @@ BL31_SOURCES += common/desc_image_load.c \
${MTK_PLAT_SOC}/drivers/spm/spm_pmic_wrap.c \
${MTK_PLAT_SOC}/drivers/spm/spm_suspend.c \
${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \
- ${MTK_PLAT_SOC}/drivers/uart/uart.c \
+ ${MTK_PLAT_SOC}/drivers/timer/mt_timer.c \
${MTK_PLAT_SOC}/drivers/emi_mpu/emi_mpu.c \
${MTK_PLAT_SOC}/plat_pm.c \
${MTK_PLAT_SOC}/plat_topology.c \
diff --git a/plat/mediatek/mt8192/aarch64/plat_helpers.S b/plat/mediatek/mt8192/aarch64/plat_helpers.S
new file mode 100644
index 000000000..99274dec4
--- /dev/null
+++ b/plat/mediatek/mt8192/aarch64/plat_helpers.S
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+ .globl plat_is_my_cpu_primary
+ .globl plat_my_core_pos
+ .globl plat_mediatek_calc_core_pos
+
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ cmp x0, #PLAT_PRIMARY_CPU
+ cset x0, eq
+ ret
+endfunc plat_is_my_cpu_primary
+
+ /* -----------------------------------------------------
+ * unsigned int plat_my_core_pos(void)
+ * This function uses the plat_mediatek_calc_core_pos()
+ * definition to get the index of the calling CPU.
+ * -----------------------------------------------------
+ */
+func plat_my_core_pos
+ mrs x0, mpidr_el1
+ b plat_mediatek_calc_core_pos
+endfunc plat_my_core_pos
+
+ /* -----------------------------------------------------
+ * unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr);
+ *
+ * In ARMv8.2, AFF2 is cluster id, AFF1 is core id and
+ * AFF0 is thread id. There is only one cluster in ARMv8.2
+ * and one thread in current implementation.
+ *
+ * With this function: CorePos = CoreID (AFF1)
+ * we do it with x0 = (x0 >> 8) & 0xff
+ * -----------------------------------------------------
+ */
+func plat_mediatek_calc_core_pos
+ mov x1, #MPIDR_AFFLVL_MASK
+ and x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
+ ret
+endfunc plat_mediatek_calc_core_pos
diff --git a/plat/mediatek/mt8192/aarch64/platform_common.c b/plat/mediatek/mt8192/aarch64/platform_common.c
new file mode 100644
index 000000000..eb1bb4486
--- /dev/null
+++ b/plat/mediatek/mt8192/aarch64/platform_common.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Project Includes */
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+/* Platform Includes */
+#include <platform_def.h>
+
+/* Table of regions to map using the MMU. */
+const mmap_region_t plat_mmap[] = {
+ /* for TF text, RO, RW */
+ MAP_REGION_FLAT(MTK_DEV_RNG0_BASE, MTK_DEV_RNG0_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(MTK_DEV_RNG1_BASE, MTK_DEV_RNG1_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(MTK_DEV_RNG2_BASE, MTK_DEV_RNG2_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ { 0 }
+};
+
+/*******************************************************************************
+ * Macro generating the code for the function setting up the pagetables as per
+ * the platform memory map & initialize the mmu, for the given exception level
+ ******************************************************************************/
+void plat_configure_mmu_el3(uintptr_t total_base,
+ uintptr_t total_size,
+ uintptr_t ro_start,
+ uintptr_t ro_limit)
+{
+ mmap_add_region(total_base, total_base, total_size,
+ MT_RW_DATA | MT_SECURE);
+ mmap_add_region(ro_start, ro_start, ro_limit - ro_start,
+ MT_CODE | MT_SECURE);
+ mmap_add(plat_mmap);
+ init_xlat_tables();
+ enable_mmu_el3(0);
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ return SYS_COUNTER_FREQ_IN_TICKS;
+}
diff --git a/plat/mediatek/mt8192/bl31_plat_setup.c b/plat/mediatek/mt8192/bl31_plat_setup.c
new file mode 100644
index 000000000..9de4a2e62
--- /dev/null
+++ b/plat/mediatek/mt8192/bl31_plat_setup.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* System Includes */
+#include <assert.h>
+
+/* Project Includes */
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/coreboot.h>
+
+/* Platform Includes */
+#include <emi_mpu/emi_mpu.h>
+#include <gpio/mtgpio.h>
+#include <mt_gic_v3.h>
+#include <mt_timer.h>
+#include <mtk_dcm.h>
+#include <plat_params.h>
+#include <plat_private.h>
+
+static entry_point_info_t bl32_ep_info;
+static entry_point_info_t bl33_ep_info;
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+ entry_point_info_t *next_image_info;
+
+ next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info;
+ assert(next_image_info->h.type == PARAM_EP);
+
+ /* None of the images on this platform can have 0x0 as the entrypoint */
+ if (next_image_info->pc) {
+ return next_image_info;
+ } else {
+ return NULL;
+ }
+}
+
+/*******************************************************************************
+ * Perform any BL31 early platform setup. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
+ * are lost (potentially). This needs to be done before the MMU is initialized
+ * so that the memory layout can be used while creating page tables.
+ * BL2 has flushed this information to memory, so we are guaranteed to pick up
+ * good data.
+ ******************************************************************************/
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ static console_t console;
+
+ params_early_setup(arg1);
+
+#if COREBOOT
+ if (coreboot_serial.type) {
+ console_16550_register(coreboot_serial.baseaddr,
+ coreboot_serial.input_hertz,
+ coreboot_serial.baud,
+ &console);
+ }
+#else
+ console_16550_register(UART0_BASE, UART_CLOCK, UART_BAUDRATE, &console);
+#endif
+
+ NOTICE("MT8192 bl31_setup\n");
+
+ bl31_params_parse_helper(arg0, &bl32_ep_info, &bl33_ep_info);
+}
+
+
+/*******************************************************************************
+ * Perform any BL31 platform setup code
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+ /* Set dcm on */
+ if (!dcm_set_default()) {
+ ERROR("Failed to set default dcm on!!\n");
+ }
+
+ /* MPU Init */
+ emi_mpu_init();
+
+ /* Initialize the GIC driver, CPU and distributor interfaces */
+ mt_gic_driver_init();
+ mt_gic_init();
+
+ plat_mt8192_gpio_init();
+ mt_systimer_init();
+ generic_delay_timer_init();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl31_plat_arch_setup(void)
+{
+ plat_configure_mmu_el3(BL31_START,
+ BL31_END - BL31_START,
+ BL_CODE_BASE,
+ BL_CODE_END);
+}
diff --git a/plat/mediatek/mt8192/drivers/dcm/mtk_dcm.c b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm.c
new file mode 100644
index 000000000..dd8bf4eed
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mtk_dcm.h>
+#include <mtk_dcm_utils.h>
+
+static void dcm_armcore(bool mode)
+{
+ dcm_mp_cpusys_top_bus_pll_div_dcm(mode);
+ dcm_mp_cpusys_top_cpu_pll_div_0_dcm(mode);
+ dcm_mp_cpusys_top_cpu_pll_div_1_dcm(mode);
+}
+
+static void dcm_mcusys(bool on)
+{
+ dcm_mp_cpusys_top_adb_dcm(on);
+ dcm_mp_cpusys_top_apb_dcm(on);
+ dcm_mp_cpusys_top_cpubiu_dcm(on);
+ dcm_mp_cpusys_top_misc_dcm(on);
+ dcm_mp_cpusys_top_mp0_qdcm(on);
+ dcm_cpccfg_reg_emi_wfifo(on);
+ dcm_mp_cpusys_top_last_cor_idle_dcm(on);
+}
+
+static void dcm_stall(bool on)
+{
+ dcm_mp_cpusys_top_core_stall_dcm(on);
+ dcm_mp_cpusys_top_fcm_stall_dcm(on);
+}
+
+static bool check_dcm_state(void)
+{
+ bool ret = true;
+
+ ret &= dcm_mp_cpusys_top_bus_pll_div_dcm_is_on();
+ ret &= dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on();
+ ret &= dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on();
+
+ ret &= dcm_mp_cpusys_top_adb_dcm_is_on();
+ ret &= dcm_mp_cpusys_top_apb_dcm_is_on();
+ ret &= dcm_mp_cpusys_top_cpubiu_dcm_is_on();
+ ret &= dcm_mp_cpusys_top_misc_dcm_is_on();
+ ret &= dcm_mp_cpusys_top_mp0_qdcm_is_on();
+ ret &= dcm_cpccfg_reg_emi_wfifo_is_on();
+ ret &= dcm_mp_cpusys_top_last_cor_idle_dcm_is_on();
+
+ ret &= dcm_mp_cpusys_top_core_stall_dcm_is_on();
+ ret &= dcm_mp_cpusys_top_fcm_stall_dcm_is_on();
+
+ return ret;
+}
+
+bool dcm_set_default(void)
+{
+ dcm_armcore(true);
+ dcm_mcusys(true);
+ dcm_stall(true);
+
+ return check_dcm_state();
+}
diff --git a/plat/mediatek/mt8192/drivers/dcm/mtk_dcm.h b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm.h
new file mode 100644
index 000000000..ee98d0e38
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_DCM_H
+#define MTK_DCM_H
+
+#include <stdbool.h>
+
+bool dcm_set_default(void);
+
+#endif /* #ifndef MTK_DCM_H */
diff --git a/plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.c b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.c
new file mode 100644
index 000000000..15a700c2b
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.c
@@ -0,0 +1,562 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <mtk_dcm_utils.h>
+
+#define MP_CPUSYS_TOP_ADB_DCM_REG0_MASK (BIT(17))
+#define MP_CPUSYS_TOP_ADB_DCM_REG1_MASK (BIT(15) | \
+ BIT(16) | \
+ BIT(17) | \
+ BIT(18) | \
+ BIT(21))
+#define MP_CPUSYS_TOP_ADB_DCM_REG2_MASK (BIT(15) | \
+ BIT(16) | \
+ BIT(17) | \
+ BIT(18))
+#define MP_CPUSYS_TOP_ADB_DCM_REG0_ON (BIT(17))
+#define MP_CPUSYS_TOP_ADB_DCM_REG1_ON (BIT(15) | \
+ BIT(16) | \
+ BIT(17) | \
+ BIT(18) | \
+ BIT(21))
+#define MP_CPUSYS_TOP_ADB_DCM_REG2_ON (BIT(15) | \
+ BIT(16) | \
+ BIT(17) | \
+ BIT(18))
+#define MP_CPUSYS_TOP_ADB_DCM_REG0_OFF ((0x0 << 17))
+#define MP_CPUSYS_TOP_ADB_DCM_REG1_OFF ((0x0 << 15) | \
+ (0x0 << 16) | \
+ (0x0 << 17) | \
+ (0x0 << 18) | \
+ (0x0 << 21))
+#define MP_CPUSYS_TOP_ADB_DCM_REG2_OFF ((0x0 << 15) | \
+ (0x0 << 16) | \
+ (0x0 << 17) | \
+ (0x0 << 18))
+
+bool dcm_mp_cpusys_top_adb_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(MP_ADB_DCM_CFG0) &
+ MP_CPUSYS_TOP_ADB_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_ADB_DCM_REG0_ON);
+ ret &= ((mmio_read_32(MP_ADB_DCM_CFG4) &
+ MP_CPUSYS_TOP_ADB_DCM_REG1_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_ADB_DCM_REG1_ON);
+ ret &= ((mmio_read_32(MCUSYS_DCM_CFG0) &
+ MP_CPUSYS_TOP_ADB_DCM_REG2_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_ADB_DCM_REG2_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_adb_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_adb_dcm'" */
+ mmio_clrsetbits_32(MP_ADB_DCM_CFG0,
+ MP_CPUSYS_TOP_ADB_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_ADB_DCM_REG0_ON);
+ mmio_clrsetbits_32(MP_ADB_DCM_CFG4,
+ MP_CPUSYS_TOP_ADB_DCM_REG1_MASK,
+ MP_CPUSYS_TOP_ADB_DCM_REG1_ON);
+ mmio_clrsetbits_32(MCUSYS_DCM_CFG0,
+ MP_CPUSYS_TOP_ADB_DCM_REG2_MASK,
+ MP_CPUSYS_TOP_ADB_DCM_REG2_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_adb_dcm'" */
+ mmio_clrsetbits_32(MP_ADB_DCM_CFG0,
+ MP_CPUSYS_TOP_ADB_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_ADB_DCM_REG0_OFF);
+ mmio_clrsetbits_32(MP_ADB_DCM_CFG4,
+ MP_CPUSYS_TOP_ADB_DCM_REG1_MASK,
+ MP_CPUSYS_TOP_ADB_DCM_REG1_OFF);
+ mmio_clrsetbits_32(MCUSYS_DCM_CFG0,
+ MP_CPUSYS_TOP_ADB_DCM_REG2_MASK,
+ MP_CPUSYS_TOP_ADB_DCM_REG2_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_APB_DCM_REG0_MASK (BIT(5))
+#define MP_CPUSYS_TOP_APB_DCM_REG1_MASK (BIT(8))
+#define MP_CPUSYS_TOP_APB_DCM_REG2_MASK (BIT(16))
+#define MP_CPUSYS_TOP_APB_DCM_REG0_ON (BIT(5))
+#define MP_CPUSYS_TOP_APB_DCM_REG1_ON (BIT(8))
+#define MP_CPUSYS_TOP_APB_DCM_REG2_ON (BIT(16))
+#define MP_CPUSYS_TOP_APB_DCM_REG0_OFF ((0x0 << 5))
+#define MP_CPUSYS_TOP_APB_DCM_REG1_OFF ((0x0 << 8))
+#define MP_CPUSYS_TOP_APB_DCM_REG2_OFF ((0x0 << 16))
+
+bool dcm_mp_cpusys_top_apb_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(MP_MISC_DCM_CFG0) &
+ MP_CPUSYS_TOP_APB_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_APB_DCM_REG0_ON);
+ ret &= ((mmio_read_32(MCUSYS_DCM_CFG0) &
+ MP_CPUSYS_TOP_APB_DCM_REG1_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_APB_DCM_REG1_ON);
+ ret &= ((mmio_read_32(MP0_DCM_CFG0) &
+ MP_CPUSYS_TOP_APB_DCM_REG2_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_APB_DCM_REG2_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_apb_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_apb_dcm'" */
+ mmio_clrsetbits_32(MP_MISC_DCM_CFG0,
+ MP_CPUSYS_TOP_APB_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_APB_DCM_REG0_ON);
+ mmio_clrsetbits_32(MCUSYS_DCM_CFG0,
+ MP_CPUSYS_TOP_APB_DCM_REG1_MASK,
+ MP_CPUSYS_TOP_APB_DCM_REG1_ON);
+ mmio_clrsetbits_32(MP0_DCM_CFG0,
+ MP_CPUSYS_TOP_APB_DCM_REG2_MASK,
+ MP_CPUSYS_TOP_APB_DCM_REG2_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_apb_dcm'" */
+ mmio_clrsetbits_32(MP_MISC_DCM_CFG0,
+ MP_CPUSYS_TOP_APB_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_APB_DCM_REG0_OFF);
+ mmio_clrsetbits_32(MCUSYS_DCM_CFG0,
+ MP_CPUSYS_TOP_APB_DCM_REG1_MASK,
+ MP_CPUSYS_TOP_APB_DCM_REG1_OFF);
+ mmio_clrsetbits_32(MP0_DCM_CFG0,
+ MP_CPUSYS_TOP_APB_DCM_REG2_MASK,
+ MP_CPUSYS_TOP_APB_DCM_REG2_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK (BIT(11))
+#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON (BIT(11))
+#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_OFF ((0x0 << 11))
+
+bool dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(BUS_PLLDIV_CFG) &
+ MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_bus_pll_div_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_bus_pll_div_dcm'" */
+ mmio_clrsetbits_32(BUS_PLLDIV_CFG,
+ MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_bus_pll_div_dcm'" */
+ mmio_clrsetbits_32(BUS_PLLDIV_CFG,
+ MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK (BIT(0))
+#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON (BIT(0))
+#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_OFF ((0x0 << 0))
+
+bool dcm_mp_cpusys_top_core_stall_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(MP0_DCM_CFG7) &
+ MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_core_stall_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_core_stall_dcm'" */
+ mmio_clrsetbits_32(MP0_DCM_CFG7,
+ MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_core_stall_dcm'" */
+ mmio_clrsetbits_32(MP0_DCM_CFG7,
+ MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK ((0xffff << 0))
+#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON ((0xffff << 0))
+#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_OFF ((0x0 << 0))
+
+bool dcm_mp_cpusys_top_cpubiu_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(MCSI_DCM0) &
+ MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_cpubiu_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpubiu_dcm'" */
+ mmio_clrsetbits_32(MCSI_DCM0,
+ MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpubiu_dcm'" */
+ mmio_clrsetbits_32(MCSI_DCM0,
+ MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CPUBIU_DCM_REG0_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK (BIT(11))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON (BIT(11))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF ((0x0 << 11))
+
+bool dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(CPU_PLLDIV_CFG0) &
+ MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_cpu_pll_div_0_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_0_dcm'" */
+ mmio_clrsetbits_32(CPU_PLLDIV_CFG0,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_0_dcm'" */
+ mmio_clrsetbits_32(CPU_PLLDIV_CFG0,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK (BIT(11))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON (BIT(11))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF ((0x0 << 11))
+
+bool dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(CPU_PLLDIV_CFG1) &
+ MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_cpu_pll_div_1_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_1_dcm'" */
+ mmio_clrsetbits_32(CPU_PLLDIV_CFG1,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_1_dcm'" */
+ mmio_clrsetbits_32(CPU_PLLDIV_CFG1,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_MASK (BIT(11))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_ON (BIT(11))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_OFF ((0x0 << 11))
+
+bool dcm_mp_cpusys_top_cpu_pll_div_2_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(CPU_PLLDIV_CFG2) &
+ MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_cpu_pll_div_2_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_2_dcm'" */
+ mmio_clrsetbits_32(CPU_PLLDIV_CFG2,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_2_dcm'" */
+ mmio_clrsetbits_32(CPU_PLLDIV_CFG2,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_2_DCM_REG0_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_MASK (BIT(11))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_ON (BIT(11))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_OFF ((0x0 << 11))
+
+bool dcm_mp_cpusys_top_cpu_pll_div_3_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(CPU_PLLDIV_CFG3) &
+ MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_cpu_pll_div_3_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_3_dcm'" */
+ mmio_clrsetbits_32(CPU_PLLDIV_CFG3,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_3_dcm'" */
+ mmio_clrsetbits_32(CPU_PLLDIV_CFG3,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_3_DCM_REG0_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_MASK (BIT(11))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_ON (BIT(11))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_OFF ((0x0 << 11))
+
+bool dcm_mp_cpusys_top_cpu_pll_div_4_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(CPU_PLLDIV_CFG4) &
+ MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_cpu_pll_div_4_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_4_dcm'" */
+ mmio_clrsetbits_32(CPU_PLLDIV_CFG4,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_4_dcm'" */
+ mmio_clrsetbits_32(CPU_PLLDIV_CFG4,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_CPU_PLL_DIV_4_DCM_REG0_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK (BIT(4))
+#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON (BIT(4))
+#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_OFF ((0x0 << 4))
+
+bool dcm_mp_cpusys_top_fcm_stall_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(MP0_DCM_CFG7) &
+ MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_fcm_stall_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_fcm_stall_dcm'" */
+ mmio_clrsetbits_32(MP0_DCM_CFG7,
+ MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_fcm_stall_dcm'" */
+ mmio_clrsetbits_32(MP0_DCM_CFG7,
+ MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK ((0x1U << 31))
+#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON ((0x1U << 31))
+#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF ((0x0U << 31))
+
+bool dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(BUS_PLLDIV_CFG) &
+ MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_last_cor_idle_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_last_cor_idle_dcm'" */
+ mmio_clrsetbits_32(BUS_PLLDIV_CFG,
+ MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_last_cor_idle_dcm'" */
+ mmio_clrsetbits_32(BUS_PLLDIV_CFG,
+ MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_MISC_DCM_REG0_MASK (BIT(1) | \
+ BIT(4))
+#define MP_CPUSYS_TOP_MISC_DCM_REG0_ON (BIT(1) | \
+ BIT(4))
+#define MP_CPUSYS_TOP_MISC_DCM_REG0_OFF ((0x0 << 1) | \
+ (0x0 << 4))
+
+bool dcm_mp_cpusys_top_misc_dcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(MP_MISC_DCM_CFG0) &
+ MP_CPUSYS_TOP_MISC_DCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_MISC_DCM_REG0_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_misc_dcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_misc_dcm'" */
+ mmio_clrsetbits_32(MP_MISC_DCM_CFG0,
+ MP_CPUSYS_TOP_MISC_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_MISC_DCM_REG0_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_misc_dcm'" */
+ mmio_clrsetbits_32(MP_MISC_DCM_CFG0,
+ MP_CPUSYS_TOP_MISC_DCM_REG0_MASK,
+ MP_CPUSYS_TOP_MISC_DCM_REG0_OFF);
+ }
+}
+
+#define MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK (BIT(3))
+#define MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK (BIT(0) | \
+ BIT(1) | \
+ BIT(2) | \
+ BIT(3))
+#define MP_CPUSYS_TOP_MP0_QDCM_REG0_ON (BIT(3))
+#define MP_CPUSYS_TOP_MP0_QDCM_REG1_ON (BIT(0) | \
+ BIT(1) | \
+ BIT(2) | \
+ BIT(3))
+#define MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF ((0x0 << 3))
+#define MP_CPUSYS_TOP_MP0_QDCM_REG1_OFF ((0x0 << 0) | \
+ (0x0 << 1) | \
+ (0x0 << 2) | \
+ (0x0 << 3))
+
+bool dcm_mp_cpusys_top_mp0_qdcm_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(MP_MISC_DCM_CFG0) &
+ MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_MP0_QDCM_REG0_ON);
+ ret &= ((mmio_read_32(MP0_DCM_CFG0) &
+ MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK) ==
+ (unsigned int) MP_CPUSYS_TOP_MP0_QDCM_REG1_ON);
+
+ return ret;
+}
+
+void dcm_mp_cpusys_top_mp0_qdcm(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'mp_cpusys_top_mp0_qdcm'" */
+ mmio_clrsetbits_32(MP_MISC_DCM_CFG0,
+ MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK,
+ MP_CPUSYS_TOP_MP0_QDCM_REG0_ON);
+ mmio_clrsetbits_32(MP0_DCM_CFG0,
+ MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK,
+ MP_CPUSYS_TOP_MP0_QDCM_REG1_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'mp_cpusys_top_mp0_qdcm'" */
+ mmio_clrsetbits_32(MP_MISC_DCM_CFG0,
+ MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK,
+ MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF);
+ mmio_clrsetbits_32(MP0_DCM_CFG0,
+ MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK,
+ MP_CPUSYS_TOP_MP0_QDCM_REG1_OFF);
+ }
+}
+
+#define CPCCFG_REG_EMI_WFIFO_REG0_MASK (BIT(0) | \
+ BIT(1) | \
+ BIT(2) | \
+ BIT(3))
+#define CPCCFG_REG_EMI_WFIFO_REG0_ON (BIT(0) | \
+ BIT(1) | \
+ BIT(2) | \
+ BIT(3))
+#define CPCCFG_REG_EMI_WFIFO_REG0_OFF ((0x0 << 0) | \
+ (0x0 << 1) | \
+ (0x0 << 2) | \
+ (0x0 << 3))
+
+bool dcm_cpccfg_reg_emi_wfifo_is_on(void)
+{
+ bool ret = true;
+
+ ret &= ((mmio_read_32(EMI_WFIFO) &
+ CPCCFG_REG_EMI_WFIFO_REG0_MASK) ==
+ (unsigned int) CPCCFG_REG_EMI_WFIFO_REG0_ON);
+
+ return ret;
+}
+
+void dcm_cpccfg_reg_emi_wfifo(bool on)
+{
+ if (on) {
+ /* TINFO = "Turn ON DCM 'cpccfg_reg_emi_wfifo'" */
+ mmio_clrsetbits_32(EMI_WFIFO,
+ CPCCFG_REG_EMI_WFIFO_REG0_MASK,
+ CPCCFG_REG_EMI_WFIFO_REG0_ON);
+ } else {
+ /* TINFO = "Turn OFF DCM 'cpccfg_reg_emi_wfifo'" */
+ mmio_clrsetbits_32(EMI_WFIFO,
+ CPCCFG_REG_EMI_WFIFO_REG0_MASK,
+ CPCCFG_REG_EMI_WFIFO_REG0_OFF);
+ }
+}
+
diff --git a/plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.h b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.h
new file mode 100644
index 000000000..1cf78345e
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/dcm/mtk_dcm_utils.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_DCM_UTILS_H
+#define MTK_DCM_UTILS_H
+
+#include <stdbool.h>
+
+#include <mtk_dcm.h>
+#include <platform_def.h>
+
+/* Base */
+#define MP_CPUSYS_TOP_BASE (MCUCFG_BASE + 0x8000)
+#define CPCCFG_REG_BASE (MCUCFG_BASE + 0xA800)
+
+/* Register Definition */
+#define CPU_PLLDIV_CFG0 (MP_CPUSYS_TOP_BASE + 0x22a0)
+#define CPU_PLLDIV_CFG1 (MP_CPUSYS_TOP_BASE + 0x22a4)
+#define CPU_PLLDIV_CFG2 (MP_CPUSYS_TOP_BASE + 0x22a8)
+#define CPU_PLLDIV_CFG3 (MP_CPUSYS_TOP_BASE + 0x22ac)
+#define CPU_PLLDIV_CFG4 (MP_CPUSYS_TOP_BASE + 0x22b0)
+#define BUS_PLLDIV_CFG (MP_CPUSYS_TOP_BASE + 0x22e0)
+#define MCSI_DCM0 (MP_CPUSYS_TOP_BASE + 0x2440)
+#define MP_ADB_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x2500)
+#define MP_ADB_DCM_CFG4 (MP_CPUSYS_TOP_BASE + 0x2510)
+#define MP_MISC_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x2518)
+#define MCUSYS_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x25c0)
+#define EMI_WFIFO (CPCCFG_REG_BASE + 0x100)
+#define MP0_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x4880)
+#define MP0_DCM_CFG7 (MP_CPUSYS_TOP_BASE + 0x489c)
+
+/* MP_CPUSYS_TOP */
+bool dcm_mp_cpusys_top_adb_dcm_is_on(void);
+void dcm_mp_cpusys_top_adb_dcm(bool on);
+bool dcm_mp_cpusys_top_apb_dcm_is_on(void);
+void dcm_mp_cpusys_top_apb_dcm(bool on);
+bool dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(void);
+void dcm_mp_cpusys_top_bus_pll_div_dcm(bool on);
+bool dcm_mp_cpusys_top_core_stall_dcm_is_on(void);
+void dcm_mp_cpusys_top_core_stall_dcm(bool on);
+bool dcm_mp_cpusys_top_cpubiu_dcm_is_on(void);
+void dcm_mp_cpusys_top_cpubiu_dcm(bool on);
+bool dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(void);
+void dcm_mp_cpusys_top_cpu_pll_div_0_dcm(bool on);
+bool dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(void);
+void dcm_mp_cpusys_top_cpu_pll_div_1_dcm(bool on);
+bool dcm_mp_cpusys_top_cpu_pll_div_2_dcm_is_on(void);
+void dcm_mp_cpusys_top_cpu_pll_div_2_dcm(bool on);
+bool dcm_mp_cpusys_top_cpu_pll_div_3_dcm_is_on(void);
+void dcm_mp_cpusys_top_cpu_pll_div_3_dcm(bool on);
+bool dcm_mp_cpusys_top_cpu_pll_div_4_dcm_is_on(void);
+void dcm_mp_cpusys_top_cpu_pll_div_4_dcm(bool on);
+bool dcm_mp_cpusys_top_fcm_stall_dcm_is_on(void);
+void dcm_mp_cpusys_top_fcm_stall_dcm(bool on);
+bool dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(void);
+void dcm_mp_cpusys_top_last_cor_idle_dcm(bool on);
+bool dcm_mp_cpusys_top_misc_dcm_is_on(void);
+void dcm_mp_cpusys_top_misc_dcm(bool on);
+bool dcm_mp_cpusys_top_mp0_qdcm_is_on(void);
+void dcm_mp_cpusys_top_mp0_qdcm(bool on);
+/* CPCCFG_REG */
+bool dcm_cpccfg_reg_emi_wfifo_is_on(void);
+void dcm_cpccfg_reg_emi_wfifo(bool on);
+
+#endif
diff --git a/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
new file mode 100644
index 000000000..d5d7e2e29
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <emi_mpu.h>
+#include <lib/mmio.h>
+
+/*
+ * emi_mpu_set_region_protection: protect a region.
+ * @start: start address of the region
+ * @end: end address of the region
+ * @access_permission: EMI MPU access permission
+ * Return 0 for success, otherwise negative status code.
+ */
+static int _emi_mpu_set_protection(
+ unsigned long start, unsigned long end,
+ unsigned int apc)
+{
+ unsigned int dgroup;
+ unsigned int region;
+
+ region = (start >> 24) & 0xFF;
+ start &= 0x00FFFFFF;
+ dgroup = (end >> 24) & 0xFF;
+ end &= 0x00FFFFFF;
+
+ if ((region >= EMI_MPU_REGION_NUM) || (dgroup > EMI_MPU_DGROUP_NUM)) {
+ WARN("Region:%u or dgroup:%u is wrong!\n", region, dgroup);
+ return -1;
+ }
+
+ apc &= 0x80FFFFFF;
+
+ if ((start >= DRAM_OFFSET) && (end >= start)) {
+ start -= DRAM_OFFSET;
+ end -= DRAM_OFFSET;
+ } else {
+ WARN("start:0x%lx or end:0x%lx address is wrong!\n",
+ start, end);
+ return -2;
+ }
+
+ mmio_write_32(EMI_MPU_SA(region), start);
+ mmio_write_32(EMI_MPU_EA(region), end);
+ mmio_write_32(EMI_MPU_APC(region, dgroup), apc);
+
+ return 0;
+}
+
+void dump_emi_mpu_regions(void)
+{
+ unsigned long apc[EMI_MPU_DGROUP_NUM], sa, ea;
+
+ int region, i;
+
+ /* Only dump 8 regions(max: EMI_MPU_REGION_NUM --> 32) */
+ for (region = 0; region < 8; ++region) {
+ for (i = 0; i < EMI_MPU_DGROUP_NUM; ++i)
+ apc[i] = mmio_read_32(EMI_MPU_APC(region, i));
+ sa = mmio_read_32(EMI_MPU_SA(region));
+ ea = mmio_read_32(EMI_MPU_EA(region));
+
+ WARN("region %d:\n", region);
+ WARN("\tsa:0x%lx, ea:0x%lx, apc0: 0x%lx apc1: 0x%lx\n",
+ sa, ea, apc[0], apc[1]);
+ }
+}
+
+int emi_mpu_set_protection(struct emi_region_info_t *region_info)
+{
+ unsigned long start, end;
+ int i;
+
+ if (region_info->region >= EMI_MPU_REGION_NUM)
+ return -1;
+
+ start = (unsigned long)(region_info->start >> EMI_MPU_ALIGN_BITS) |
+ (region_info->region << 24);
+
+ for (i = EMI_MPU_DGROUP_NUM - 1; i >= 0; i--) {
+ end = (unsigned long)(region_info->end >> EMI_MPU_ALIGN_BITS) |
+ (i << 24);
+ _emi_mpu_set_protection(start, end, region_info->apc[i]);
+ }
+
+ return 0;
+}
+
+void emi_mpu_init(void)
+{
+ /* Set permission */
+ struct emi_region_info_t region_info;
+
+ /* PCE-e protect address(TODO) */
+ region_info.start = 0x80000000ULL;
+ region_info.end = 0x83FF0000ULL;
+ region_info.region = 1;
+ SET_ACCESS_PERMISSION(region_info.apc, 1,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+ FORBIDDEN, FORBIDDEN, NO_PROT,
+ NO_PROT /*FORBIDDEN*/);
+ emi_mpu_set_protection(&region_info);
+
+ /* Forbidden All */
+ region_info.start = 0x40000000ULL; /* dram base addr */
+ region_info.end = 0x1FFFF0000ULL;
+ region_info.region = 2;
+ SET_ACCESS_PERMISSION(region_info.apc, 1,
+ NO_PROT, NO_PROT, NO_PROT, NO_PROT,
+ NO_PROT, NO_PROT, NO_PROT, NO_PROT,
+ NO_PROT, NO_PROT, NO_PROT, NO_PROT,
+ NO_PROT, FORBIDDEN, NO_PROT, NO_PROT);
+ emi_mpu_set_protection(&region_info);
+
+ dump_emi_mpu_regions();
+}
+
diff --git a/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.h
new file mode 100644
index 000000000..0b1543197
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EMI_MPU_H
+#define EMI_MPU_H
+
+#include <platform_def.h>
+
+#define EMI_MPUP (EMI_BASE + 0x01D8)
+#define EMI_MPUQ (EMI_BASE + 0x01E0)
+#define EMI_MPUR (EMI_BASE + 0x01E8)
+#define EMI_MPUS (EMI_BASE + 0x01F0)
+#define EMI_MPUT (EMI_BASE + 0x01F8)
+#define EMI_MPUY (EMI_BASE + 0x0220)
+#define EMI_MPU_CTRL (EMI_MPU_BASE + 0x0000)
+#define EMI_MPUD0_ST (EMI_BASE + 0x0160)
+#define EMI_MPUD1_ST (EMI_BASE + 0x0164)
+#define EMI_MPUD2_ST (EMI_BASE + 0x0168)
+#define EMI_MPUD3_ST (EMI_BASE + 0x016C)
+#define EMI_MPUD0_ST2 (EMI_BASE + 0x0200)
+#define EMI_MPUD1_ST2 (EMI_BASE + 0x0204)
+#define EMI_MPUD2_ST2 (EMI_BASE + 0x0208)
+#define EMI_MPUD3_ST2 (EMI_BASE + 0x020C)
+
+#define EMI_PHY_OFFSET (0x40000000UL)
+
+#define NO_PROT (0)
+#define SEC_RW (1)
+#define SEC_RW_NSEC_R (2)
+#define SEC_RW_NSEC_W (3)
+#define SEC_R_NSEC_R (4)
+#define FORBIDDEN (5)
+#define SEC_R_NSEC_RW (6)
+
+#define SECURE_OS_MPU_REGION_ID (0)
+#define ATF_MPU_REGION_ID (1)
+
+#define EMI_MPU_SA0 (EMI_MPU_BASE + 0x100)
+#define EMI_MPU_EA0 (EMI_MPU_BASE + 0x200)
+#define EMI_MPU_SA(region) (EMI_MPU_SA0 + (region) * 4)
+#define EMI_MPU_EA(region) (EMI_MPU_EA0 + (region) * 4)
+
+#define EMI_MPU_APC0 (EMI_MPU_BASE + 0x300)
+#define EMI_MPU_APC(region, dgroup) (EMI_MPU_APC0 + (region) * 4 + \
+ (dgroup) * 0x100)
+
+#define EMI_MPU_CTRL_D0 (EMI_MPU_BASE + 0x800)
+#define EMI_MPU_CTRL_D(domain) (EMI_MPU_CTRL_D0 + domain * 4)
+#define EMI_RG_MASK_D0 (EMI_MPU_BASE + 0x900)
+#define EMI_RG_MASK_D(domain) (EMI_RG_MASK_D0 + domain * 4)
+
+#define EMI_MPU_DOMAIN_NUM 16
+#define EMI_MPU_REGION_NUM 32
+#define EMI_MPU_ALIGN_BITS 16
+#define DRAM_OFFSET (0x40000000 >> EMI_MPU_ALIGN_BITS)
+
+#define EMI_MPU_DGROUP_NUM (EMI_MPU_DOMAIN_NUM / 8)
+
+#if (EMI_MPU_DGROUP_NUM == 1)
+#define SET_ACCESS_PERMISSION(apc_ary, lock, d7, d6, d5, d4, d3, d2, d1, d0) \
+do { \
+ apc_ary[0] = 0; \
+ apc_ary[0] = \
+ (((unsigned int) d7) << 21) | (((unsigned int) d6) << 18) \
+ | (((unsigned int) d5) << 15) | (((unsigned int) d4) << 12) \
+ | (((unsigned int) d3) << 9) | (((unsigned int) d2) << 6) \
+ | (((unsigned int) d1) << 3) | ((unsigned int) d0) \
+ | (((unsigned int) lock) << 31); \
+} while (0)
+#elif (EMI_MPU_DGROUP_NUM == 2)
+#define SET_ACCESS_PERMISSION(apc_ary, lock, d15, d14, d13, d12, d11, d10, \
+ d9, d8, d7, d6, d5, d4, d3, d2, d1, d0) \
+do { \
+ apc_ary[1] = \
+ (((unsigned int) d15) << 21) | (((unsigned int) d14) << 18) \
+ | (((unsigned int) d13) << 15) | (((unsigned int) d12) << 12) \
+ | (((unsigned int) d11) << 9) | (((unsigned int) d10) << 6) \
+ | (((unsigned int) d9) << 3) | ((unsigned int) d8); \
+ apc_ary[0] = \
+ (((unsigned int) d7) << 21) | (((unsigned int) d6) << 18) \
+ | (((unsigned int) d5) << 15) | (((unsigned int) d4) << 12) \
+ | (((unsigned int) d3) << 9) | (((unsigned int) d2) << 6) \
+ | (((unsigned int) d1) << 3) | ((unsigned int) d0) \
+ | (((unsigned int) lock) << 31); \
+} while (0)
+#endif
+
+struct emi_region_info_t {
+ unsigned long long start;
+ unsigned long long end;
+ unsigned int region;
+ unsigned long apc[EMI_MPU_DGROUP_NUM];
+};
+
+void emi_mpu_init(void);
+int emi_mpu_set_protection(struct emi_region_info_t *region_info);
+void dump_emi_mpu_regions(void);
+
+#endif /* __EMI_MPU_H */
diff --git a/plat/mediatek/mt8192/drivers/gpio/mtgpio.c b/plat/mediatek/mt8192/drivers/gpio/mtgpio.c
new file mode 100644
index 000000000..e07b75a47
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/gpio/mtgpio.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/gpio.h>
+#include <lib/mmio.h>
+#include <mtgpio.h>
+#include <platform_def.h>
+
+/******************************************************************************
+ *Macro Definition
+ ******************************************************************************/
+#define GPIO_MODE_BITS 4
+#define MAX_GPIO_MODE_PER_REG 8
+#define MAX_GPIO_REG_BITS 32
+#define DIR_BASE (GPIO_BASE + 0x000)
+#define DOUT_BASE (GPIO_BASE + 0x100)
+#define DIN_BASE (GPIO_BASE + 0x200)
+#define MODE_BASE (GPIO_BASE + 0x300)
+#define SET 0x4
+#define CLR 0x8
+
+static void mt_set_gpio_dir_chip(uint32_t pin, int dir)
+{
+ uint32_t pos, bit;
+
+ assert(pin < MAX_GPIO_PIN);
+ assert(dir < MT_GPIO_DIR_MAX);
+
+ pos = pin / MAX_GPIO_REG_BITS;
+ bit = pin % MAX_GPIO_REG_BITS;
+
+ if (dir == MT_GPIO_DIR_IN) {
+ mmio_write_32(DIR_BASE + 0x10U * pos + CLR, 1U << bit);
+ } else {
+ mmio_write_32(DIR_BASE + 0x10U * pos + SET, 1U << bit);
+ }
+}
+
+static int mt_get_gpio_dir_chip(uint32_t pin)
+{
+ uint32_t pos, bit;
+ uint32_t reg;
+
+ assert(pin < MAX_GPIO_PIN);
+
+ pos = pin / MAX_GPIO_REG_BITS;
+ bit = pin % MAX_GPIO_REG_BITS;
+
+ reg = mmio_read_32(DIR_BASE + 0x10U * pos);
+ return (((reg & (1U << bit)) != 0U) ? MT_GPIO_DIR_OUT : MT_GPIO_DIR_IN);
+}
+
+static void mt_set_gpio_out_chip(uint32_t pin, int output)
+{
+ uint32_t pos, bit;
+
+ assert(pin < MAX_GPIO_PIN);
+ assert(output < MT_GPIO_OUT_MAX);
+
+ pos = pin / MAX_GPIO_REG_BITS;
+ bit = pin % MAX_GPIO_REG_BITS;
+
+ if (output == MT_GPIO_OUT_ZERO) {
+ mmio_write_32(DOUT_BASE + 0x10U * pos + CLR, 1U << bit);
+ } else {
+ mmio_write_32(DOUT_BASE + 0x10U * pos + SET, 1U << bit);
+ }
+}
+
+static int mt_get_gpio_in_chip(uint32_t pin)
+{
+ uint32_t pos, bit;
+ uint32_t reg;
+
+ assert(pin < MAX_GPIO_PIN);
+
+ pos = pin / MAX_GPIO_REG_BITS;
+ bit = pin % MAX_GPIO_REG_BITS;
+
+ reg = mmio_read_32(DIN_BASE + 0x10U * pos);
+ return (((reg & (1U << bit)) != 0U) ? 1 : 0);
+}
+
+static uintptr_t mt_gpio_find_reg_addr(uint32_t pin)
+{
+ uintptr_t reg_addr = 0U;
+ struct mt_pin_info gpio_info;
+
+ gpio_info = mt8192_pin_infos[pin];
+
+ switch (gpio_info.base & 0x0f) {
+ case 0:
+ reg_addr = IOCFG_RM_BASE;
+ break;
+ case 1:
+ reg_addr = IOCFG_BM_BASE;
+ break;
+ case 2:
+ reg_addr = IOCFG_BL_BASE;
+ break;
+ case 3:
+ reg_addr = IOCFG_BR_BASE;
+ break;
+ case 4:
+ reg_addr = IOCFG_LM_BASE;
+ break;
+ case 5:
+ reg_addr = IOCFG_LB_BASE;
+ break;
+ case 6:
+ reg_addr = IOCFG_RT_BASE;
+ break;
+ case 7:
+ reg_addr = IOCFG_LT_BASE;
+ break;
+ case 8:
+ reg_addr = IOCFG_TL_BASE;
+ break;
+ default:
+ break;
+ }
+
+ return reg_addr;
+}
+
+static void mt_gpio_set_spec_pull_pupd(uint32_t pin, int enable,
+ int select)
+{
+ uintptr_t reg1;
+ uintptr_t reg2;
+ struct mt_pin_info gpio_info;
+
+ gpio_info = mt8192_pin_infos[pin];
+ uint32_t bit = gpio_info.bit;
+
+ reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset;
+ reg2 = reg1 + (gpio_info.base & 0xf0);
+ if (enable == MT_GPIO_PULL_ENABLE) {
+ mmio_write_32(reg2 + SET, (1U << bit));
+ if (select == MT_GPIO_PULL_DOWN) {
+ mmio_write_32(reg1 + SET, (1U << bit));
+ } else {
+ mmio_write_32(reg1 + CLR, (1U << bit));
+ }
+ } else {
+ mmio_write_32(reg2 + CLR, (1U << bit));
+ mmio_write_32((reg2 + 0x010U) + CLR, (1U << bit));
+ }
+}
+
+static void mt_gpio_set_pull_pu_pd(uint32_t pin, int enable,
+ int select)
+{
+ uintptr_t reg1;
+ uintptr_t reg2;
+ struct mt_pin_info gpio_info;
+
+ gpio_info = mt8192_pin_infos[pin];
+ uint32_t bit = gpio_info.bit;
+
+ reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset;
+ reg2 = reg1 - (gpio_info.base & 0xf0);
+
+ if (enable == MT_GPIO_PULL_ENABLE) {
+ if (select == MT_GPIO_PULL_DOWN) {
+ mmio_write_32(reg1 + CLR, (1U << bit));
+ mmio_write_32(reg2 + SET, (1U << bit));
+ } else {
+ mmio_write_32(reg2 + CLR, (1U << bit));
+ mmio_write_32(reg1 + SET, (1U << bit));
+ }
+ } else {
+ mmio_write_32(reg1 + CLR, (1U << bit));
+ mmio_write_32(reg2 + CLR, (1U << bit));
+ }
+}
+
+static void mt_gpio_set_pull_chip(uint32_t pin, int enable,
+ int select)
+{
+ struct mt_pin_info gpio_info;
+
+ gpio_info = mt8192_pin_infos[pin];
+ if (gpio_info.flag) {
+ mt_gpio_set_spec_pull_pupd(pin, enable, select);
+ } else {
+ mt_gpio_set_pull_pu_pd(pin, enable, select);
+ }
+}
+
+static int mt_gpio_get_spec_pull_pupd(uint32_t pin)
+{
+ uintptr_t reg1;
+ uintptr_t reg2;
+ uint32_t r0;
+ uint32_t r1;
+
+ struct mt_pin_info gpio_info;
+
+ gpio_info = mt8192_pin_infos[pin];
+ uint32_t bit = gpio_info.bit;
+
+ reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset;
+ reg2 = reg1 + (gpio_info.base & 0xf0);
+
+ r0 = (mmio_read_32(reg2) >> bit) & 1U;
+ r1 = (mmio_read_32(reg2 + 0x010) >> bit) & 1U;
+ if (r0 == 0U && r1 == 0U) {
+ return MT_GPIO_PULL_NONE;
+ } else {
+ if (mmio_read_32(reg1) & (1U << bit)) {
+ return MT_GPIO_PULL_DOWN;
+ } else {
+ return MT_GPIO_PULL_UP;
+ }
+ }
+}
+
+static int mt_gpio_get_pull_pu_pd(uint32_t pin)
+{
+ uintptr_t reg1;
+ uintptr_t reg2;
+ uint32_t pu;
+ uint32_t pd;
+
+ struct mt_pin_info gpio_info;
+
+ gpio_info = mt8192_pin_infos[pin];
+ uint32_t bit = gpio_info.bit;
+
+ reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset;
+ reg2 = reg1 - (gpio_info.base & 0xf0);
+ pu = (mmio_read_32(reg1) >> bit) & 1U;
+ pd = (mmio_read_32(reg2) >> bit) & 1U;
+ if (pu == 1U) {
+ return MT_GPIO_PULL_UP;
+ } else if (pd == 1U) {
+ return MT_GPIO_PULL_DOWN;
+ } else {
+ return MT_GPIO_PULL_NONE;
+ }
+}
+
+static int mt_gpio_get_pull_chip(uint32_t pin)
+{
+ struct mt_pin_info gpio_info;
+
+ gpio_info = mt8192_pin_infos[pin];
+ if (gpio_info.flag) {
+ return mt_gpio_get_spec_pull_pupd(pin);
+ } else {
+ return mt_gpio_get_pull_pu_pd(pin);
+ }
+}
+
+static void mt_set_gpio_pull_select_chip(uint32_t pin, int sel)
+{
+ assert(pin < MAX_GPIO_PIN);
+
+ if (sel == MT_GPIO_PULL_NONE) {
+ mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_DISABLE, MT_GPIO_PULL_DOWN);
+ } else if (sel == MT_GPIO_PULL_UP) {
+ mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_ENABLE, MT_GPIO_PULL_UP);
+ } else if (sel == MT_GPIO_PULL_DOWN) {
+ mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_ENABLE, MT_GPIO_PULL_DOWN);
+ }
+}
+
+/* get pull-up or pull-down, regardless of resistor value */
+static int mt_get_gpio_pull_select_chip(uint32_t pin)
+{
+ assert(pin < MAX_GPIO_PIN);
+
+ return mt_gpio_get_pull_chip(pin);
+}
+
+static void mt_set_gpio_dir(int gpio, int direction)
+{
+ mt_set_gpio_dir_chip((uint32_t)gpio, direction);
+}
+
+static int mt_get_gpio_dir(int gpio)
+{
+ uint32_t pin;
+
+ pin = (uint32_t)gpio;
+ return mt_get_gpio_dir_chip(pin);
+}
+
+static void mt_set_gpio_pull(int gpio, int pull)
+{
+ uint32_t pin;
+
+ pin = (uint32_t)gpio;
+ mt_set_gpio_pull_select_chip(pin, pull);
+}
+
+static int mt_get_gpio_pull(int gpio)
+{
+ uint32_t pin;
+
+ pin = (uint32_t)gpio;
+ return mt_get_gpio_pull_select_chip(pin);
+}
+
+static void mt_set_gpio_out(int gpio, int value)
+{
+ uint32_t pin;
+
+ pin = (uint32_t)gpio;
+ mt_set_gpio_out_chip(pin, value);
+}
+
+static int mt_get_gpio_in(int gpio)
+{
+ uint32_t pin;
+
+ pin = (uint32_t)gpio;
+ return mt_get_gpio_in_chip(pin);
+}
+
+const gpio_ops_t mtgpio_ops = {
+ .get_direction = mt_get_gpio_dir,
+ .set_direction = mt_set_gpio_dir,
+ .get_value = mt_get_gpio_in,
+ .set_value = mt_set_gpio_out,
+ .set_pull = mt_set_gpio_pull,
+ .get_pull = mt_get_gpio_pull,
+};
+
+void plat_mt8192_gpio_init(void)
+{
+ gpio_init(&mtgpio_ops);
+}
diff --git a/plat/mediatek/mt8192/drivers/gpio/mtgpio.h b/plat/mediatek/mt8192/drivers/gpio/mtgpio.h
new file mode 100644
index 000000000..ca0c964f6
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/gpio/mtgpio.h
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_GPIO_H
+#define MT_GPIO_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <plat/common/common_def.h>
+
+/* Error Code No. */
+#define RSUCCESS 0
+#define ERACCESS 1
+#define ERINVAL 2
+#define ERWRAPPER 3
+#define MAX_GPIO_PIN MT_GPIO_BASE_MAX
+
+/* Enumeration for GPIO pin */
+typedef enum GPIO_PIN {
+ GPIO_UNSUPPORTED = -1,
+
+ GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7,
+ GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13, GPIO14, GPIO15,
+ GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23,
+ GPIO24, GPIO25, GPIO26, GPIO27, GPIO28, GPIO29, GPIO30, GPIO31,
+ GPIO32, GPIO33, GPIO34, GPIO35, GPIO36, GPIO37, GPIO38, GPIO39,
+ GPIO40, GPIO41, GPIO42, GPIO43, GPIO44, GPIO45, GPIO46, GPIO47,
+ GPIO48, GPIO49, GPIO50, GPIO51, GPIO52, GPIO53, GPIO54, GPIO55,
+ GPIO56, GPIO57, GPIO58, GPIO59, GPIO60, GPIO61, GPIO62, GPIO63,
+ GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70, GPIO71,
+ GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78, GPIO79,
+ GPIO80, GPIO81, GPIO82, GPIO83, GPIO84, GPIO85, GPIO86, GPIO87,
+ GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94, GPIO95,
+ GPIO96, GPIO97, GPIO98, GPIO99, GPIO100, GPIO101, GPIO102, GPIO103,
+ GPIO104, GPIO105, GPIO106, GPIO107, GPIO108, GPIO109, GPIO110, GPIO111,
+ GPIO112, GPIO113, GPIO114, GPIO115, GPIO116, GPIO117, GPIO118, GPIO119,
+ GPIO120, GPIO121, GPIO122, GPIO123, GPIO124, GPIO125, GPIO126, GPIO127,
+ GPIO128, GPIO129, GPIO130, GPIO131, GPIO132, GPIO133, GPIO134, GPIO135,
+ GPIO136, GPIO137, GPIO138, GPIO139, GPIO140, GPIO141, GPIO142, GPIO143,
+ GPIO144, GPIO145, GPIO146, GPIO147, GPIO148, GPIO149, GPIO150, GPIO151,
+ GPIO152, GPIO153, GPIO154, GPIO155, GPIO156, GPIO157, GPIO158, GPIO159,
+ GPIO160, GPIO161, GPIO162, GPIO163, GPIO164, GPIO165, GPIO166, GPIO167,
+ GPIO168, GPIO169, GPIO170, GPIO171, GPIO172, GPIO173, GPIO174, GPIO175,
+ GPIO176, GPIO177, GPIO178, GPIO179, GPIO180, GPIO181, GPIO182, GPIO183,
+ GPIO184, GPIO185, GPIO186, GPIO187, GPIO188, GPIO189, GPIO190, GPIO191,
+ GPIO192, GPIO193, GPIO194, GPIO195, GPIO196, GPIO197, GPIO198, GPIO199,
+ GPIO200, GPIO201, GPIO202, GPIO203, GPIO204, GPIO205, GPIO206, GPIO207,
+ GPIO208, GPIO209, GPIO210, GPIO211, GPIO212, GPIO213, GPIO214, GPIO215,
+ GPIO216, GPIO217, GPIO218, GPIO219,
+ MT_GPIO_BASE_MAX
+} GPIO_PIN;
+
+/* GPIO MODE CONTROL VALUE*/
+typedef enum {
+ GPIO_MODE_UNSUPPORTED = -1,
+ GPIO_MODE_GPIO = 0,
+ GPIO_MODE_00 = 0,
+ GPIO_MODE_01,
+ GPIO_MODE_02,
+ GPIO_MODE_03,
+ GPIO_MODE_04,
+ GPIO_MODE_05,
+ GPIO_MODE_06,
+ GPIO_MODE_07,
+
+ GPIO_MODE_MAX,
+ GPIO_MODE_DEFAULT = GPIO_MODE_00,
+} GPIO_MODE;
+
+/* GPIO DIRECTION */
+typedef enum {
+ MT_GPIO_DIR_UNSUPPORTED = -1,
+ MT_GPIO_DIR_OUT = 0,
+ MT_GPIO_DIR_IN = 1,
+ MT_GPIO_DIR_MAX,
+ MT_GPIO_DIR_DEFAULT = MT_GPIO_DIR_IN,
+} GPIO_DIR;
+
+/* GPIO PULL ENABLE*/
+typedef enum {
+ MT_GPIO_PULL_EN_UNSUPPORTED = -1,
+ MT_GPIO_PULL_DISABLE = 0,
+ MT_GPIO_PULL_ENABLE = 1,
+ MT_GPIO_PULL_ENABLE_R0 = 2,
+ MT_GPIO_PULL_ENABLE_R1 = 3,
+ MT_GPIO_PULL_ENABLE_R0R1 = 4,
+
+ MT_GPIO_PULL_EN_MAX,
+ MT_GPIO_PULL_EN_DEFAULT = MT_GPIO_PULL_ENABLE,
+} GPIO_PULL_EN;
+
+/* GPIO PULL-UP/PULL-DOWN*/
+typedef enum {
+ MT_GPIO_PULL_UNSUPPORTED = -1,
+ MT_GPIO_PULL_NONE = 0,
+ MT_GPIO_PULL_UP = 1,
+ MT_GPIO_PULL_DOWN = 2,
+ MT_GPIO_PULL_MAX,
+ MT_GPIO_PULL_DEFAULT = MT_GPIO_PULL_DOWN
+} GPIO_PULL;
+
+/* GPIO OUTPUT */
+typedef enum {
+ MT_GPIO_OUT_UNSUPPORTED = -1,
+ MT_GPIO_OUT_ZERO = 0,
+ MT_GPIO_OUT_ONE = 1,
+
+ MT_GPIO_OUT_MAX,
+ MT_GPIO_OUT_DEFAULT = MT_GPIO_OUT_ZERO,
+ MT_GPIO_DATA_OUT_DEFAULT = MT_GPIO_OUT_ZERO, /*compatible with DCT*/
+} GPIO_OUT;
+
+/* GPIO INPUT */
+typedef enum {
+ MT_GPIO_IN_UNSUPPORTED = -1,
+ MT_GPIO_IN_ZERO = 0,
+ MT_GPIO_IN_ONE = 1,
+
+ MT_GPIO_IN_MAX,
+} GPIO_IN;
+
+typedef struct {
+ uint32_t val;
+ uint32_t set;
+ uint32_t rst;
+ uint32_t _align1;
+} VAL_REGS;
+
+typedef struct {
+ VAL_REGS dir[7];
+ uint8_t rsv00[144];
+ VAL_REGS dout[7];
+ uint8_t rsv01[144];
+ VAL_REGS din[7];
+ uint8_t rsv02[144];
+ VAL_REGS mode[28];
+} GPIO_REGS;
+
+
+#define PIN(_id, _flag, _bit, _base, _offset) { \
+ .id = _id, \
+ .flag = _flag, \
+ .bit = _bit, \
+ .base = _base, \
+ .offset = _offset, \
+ }
+
+struct mt_pin_info {
+ uint8_t id;
+ uint8_t flag;
+ uint8_t bit;
+ uint16_t base;
+ uint16_t offset;
+};
+
+static const struct mt_pin_info mt8192_pin_infos[] = {
+ PIN(0, 0, 9, 0x23, 0xb0),
+ PIN(1, 0, 10, 0x23, 0xb0),
+ PIN(2, 0, 11, 0x23, 0xb0),
+ PIN(3, 0, 12, 0x23, 0xb0),
+ PIN(4, 0, 13, 0x23, 0xb0),
+ PIN(5, 0, 14, 0x23, 0xb0),
+ PIN(6, 0, 15, 0x23, 0xb0),
+ PIN(7, 0, 16, 0x23, 0xb0),
+ PIN(8, 0, 17, 0x23, 0xb0),
+ PIN(9, 0, 18, 0x23, 0xb0),
+ PIN(10, 1, 0, 0x15, 0x20),
+ PIN(11, 1, 1, 0x15, 0x20),
+ PIN(12, 1, 2, 0x15, 0x20),
+ PIN(13, 1, 3, 0x15, 0x20),
+ PIN(14, 1, 4, 0x15, 0x20),
+ PIN(15, 1, 5, 0x15, 0x20),
+ PIN(16, 0, 2, 0x17, 0x50),
+ PIN(17, 0, 3, 0x17, 0x50),
+ PIN(18, 0, 21, 0x36, 0xa0),
+ PIN(19, 0, 22, 0x36, 0xa0),
+ PIN(20, 0, 23, 0x36, 0xa0),
+ PIN(21, 0, 24, 0x36, 0xa0),
+ PIN(22, 0, 3, 0x21, 0x90),
+ PIN(23, 0, 4, 0x21, 0x90),
+ PIN(24, 0, 5, 0x21, 0x90),
+ PIN(25, 0, 6, 0x21, 0x90),
+ PIN(26, 0, 5, 0x22, 0x80),
+ PIN(27, 0, 6, 0x22, 0x80),
+ PIN(28, 0, 7, 0x22, 0x80),
+ PIN(29, 0, 8, 0x22, 0x80),
+ PIN(30, 0, 9, 0x22, 0x80),
+ PIN(31, 0, 27, 0x22, 0x70),
+ PIN(32, 0, 24, 0x22, 0x70),
+ PIN(33, 0, 26, 0x22, 0x70),
+ PIN(34, 0, 23, 0x22, 0x70),
+ PIN(35, 0, 25, 0x22, 0x70),
+ PIN(36, 0, 20, 0x21, 0x90),
+ PIN(37, 0, 21, 0x21, 0x90),
+ PIN(38, 0, 22, 0x21, 0x90),
+ PIN(39, 0, 23, 0x21, 0x90),
+ PIN(40, 0, 0, 0x17, 0x50),
+ PIN(41, 0, 1, 0x17, 0x50),
+ PIN(42, 0, 4, 0x17, 0x50),
+ PIN(43, 0, 25, 0x36, 0xa0),
+ PIN(44, 0, 26, 0x36, 0xa0),
+ PIN(45, 1, 9, 0x20, 0x60),
+ PIN(46, 1, 11, 0x20, 0x60),
+ PIN(47, 1, 10, 0x20, 0x60),
+ PIN(48, 1, 7, 0x20, 0x60),
+ PIN(49, 1, 8, 0x20, 0x60),
+ PIN(50, 1, 6, 0x20, 0x60),
+ PIN(51, 1, 0, 0x20, 0x60),
+ PIN(52, 1, 1, 0x20, 0x60),
+ PIN(53, 1, 5, 0x20, 0x60),
+ PIN(54, 1, 2, 0x20, 0x60),
+ PIN(55, 1, 4, 0x20, 0x60),
+ PIN(56, 1, 3, 0x20, 0x60),
+ PIN(57, 0, 1, 0x22, 0x80),
+ PIN(58, 0, 2, 0x22, 0x80),
+ PIN(59, 0, 3, 0x22, 0x80),
+ PIN(60, 0, 4, 0x22, 0x80),
+ PIN(61, 0, 28, 0x22, 0x70),
+ PIN(62, 0, 22, 0x22, 0x70),
+ PIN(63, 0, 0, 0x22, 0x70),
+ PIN(64, 0, 1, 0x22, 0x70),
+ PIN(65, 0, 12, 0x22, 0x70),
+ PIN(66, 0, 15, 0x22, 0x70),
+ PIN(67, 0, 16, 0x22, 0x70),
+ PIN(68, 0, 17, 0x22, 0x70),
+ PIN(69, 0, 18, 0x22, 0x70),
+ PIN(70, 0, 19, 0x22, 0x70),
+ PIN(71, 0, 20, 0x22, 0x70),
+ PIN(72, 0, 21, 0x22, 0x70),
+ PIN(73, 0, 2, 0x22, 0x70),
+ PIN(74, 0, 3, 0x22, 0x70),
+ PIN(75, 0, 4, 0x22, 0x70),
+ PIN(76, 0, 5, 0x22, 0x70),
+ PIN(77, 0, 6, 0x22, 0x70),
+ PIN(78, 0, 7, 0x22, 0x70),
+ PIN(79, 0, 8, 0x22, 0x70),
+ PIN(80, 0, 9, 0x22, 0x70),
+ PIN(81, 0, 10, 0x22, 0x70),
+ PIN(82, 0, 11, 0x22, 0x70),
+ PIN(83, 0, 13, 0x22, 0x70),
+ PIN(84, 0, 14, 0x22, 0x70),
+ PIN(85, 0, 31, 0x22, 0x70),
+ PIN(86, 0, 0, 0x22, 0x80),
+ PIN(87, 0, 29, 0x22, 0x70),
+ PIN(88, 0, 30, 0x22, 0x70),
+ PIN(89, 0, 24, 0x21, 0x90),
+ PIN(90, 0, 25, 0x21, 0x90),
+ PIN(91, 0, 0, 0x21, 0x90),
+ PIN(92, 0, 2, 0x21, 0xa0),
+ PIN(93, 0, 4, 0x21, 0xa0),
+ PIN(94, 0, 3, 0x21, 0xa0),
+ PIN(95, 0, 5, 0x21, 0xa0),
+ PIN(96, 0, 31, 0x21, 0x90),
+ PIN(97, 0, 26, 0x21, 0x90),
+ PIN(98, 0, 0, 0x21, 0xa0),
+ PIN(99, 0, 27, 0x21, 0x90),
+ PIN(100, 0, 28, 0x21, 0x90),
+ PIN(101, 0, 29, 0x21, 0x90),
+ PIN(102, 0, 30, 0x21, 0x90),
+ PIN(103, 0, 18, 0x21, 0x90),
+ PIN(104, 0, 17, 0x21, 0x90),
+ PIN(105, 0, 19, 0x21, 0x90),
+ PIN(106, 0, 16, 0x21, 0x90),
+ PIN(107, 0, 1, 0x21, 0x90),
+ PIN(108, 0, 2, 0x21, 0x90),
+ PIN(109, 0, 10, 0x21, 0x90),
+ PIN(110, 0, 7, 0x21, 0x90),
+ PIN(111, 0, 9, 0x21, 0x90),
+ PIN(112, 0, 11, 0x21, 0x90),
+ PIN(113, 0, 8, 0x21, 0x90),
+ PIN(114, 0, 14, 0x21, 0x90),
+ PIN(115, 0, 13, 0x21, 0x90),
+ PIN(116, 0, 15, 0x21, 0x90),
+ PIN(117, 0, 12, 0x21, 0x90),
+ PIN(118, 0, 23, 0x23, 0xb0),
+ PIN(119, 0, 29, 0x23, 0xb0),
+ PIN(120, 0, 28, 0x23, 0xb0),
+ PIN(121, 0, 2, 0x23, 0xc0),
+ PIN(122, 0, 27, 0x23, 0xb0),
+ PIN(123, 0, 1, 0x23, 0xc0),
+ PIN(124, 0, 26, 0x23, 0xb0),
+ PIN(125, 0, 0, 0x23, 0xc0),
+ PIN(126, 0, 19, 0x23, 0xb0),
+ PIN(127, 0, 20, 0x23, 0xb0),
+ PIN(128, 0, 21, 0x23, 0xb0),
+ PIN(129, 0, 22, 0x23, 0xb0),
+ PIN(130, 0, 6, 0x23, 0xb0),
+ PIN(131, 0, 7, 0x23, 0xb0),
+ PIN(132, 0, 8, 0x23, 0xb0),
+ PIN(133, 0, 3, 0x23, 0xb0),
+ PIN(134, 0, 4, 0x23, 0xb0),
+ PIN(135, 0, 5, 0x23, 0xb0),
+ PIN(136, 0, 0, 0x23, 0xb0),
+ PIN(137, 0, 1, 0x23, 0xb0),
+ PIN(138, 0, 2, 0x23, 0xb0),
+ PIN(139, 0, 25, 0x23, 0xb0),
+ PIN(140, 0, 31, 0x23, 0xb0),
+ PIN(141, 0, 24, 0x23, 0xb0),
+ PIN(142, 0, 30, 0x23, 0xb0),
+ PIN(143, 0, 6, 0x20, 0x70),
+ PIN(144, 0, 7, 0x20, 0x70),
+ PIN(145, 0, 8, 0x20, 0x70),
+ PIN(146, 0, 3, 0x20, 0x70),
+ PIN(147, 0, 4, 0x20, 0x70),
+ PIN(148, 0, 5, 0x20, 0x70),
+ PIN(149, 0, 0, 0x20, 0x70),
+ PIN(150, 0, 1, 0x20, 0x70),
+ PIN(151, 0, 2, 0x20, 0x70),
+ PIN(152, 1, 3, 0x36, 0x90),
+ PIN(153, 1, 2, 0x36, 0x90),
+ PIN(154, 1, 0, 0x36, 0x906),
+ PIN(155, 1, 1, 0x36, 0x90),
+ PIN(156, 0, 29, 0x36, 0xa0),
+ PIN(157, 0, 30, 0x36, 0xa0),
+ PIN(158, 0, 31, 0x36, 0xa0),
+ PIN(159, 0, 0, 0x36, 0xb0),
+ PIN(160, 0, 27, 0x36, 0xa04),
+ PIN(161, 0, 28, 0x36, 0xa0),
+ PIN(162, 0, 0, 0x36, 0xa0),
+ PIN(163, 0, 1, 0x36, 0xa0),
+ PIN(164, 0, 2, 0x36, 0xa0),
+ PIN(165, 0, 3, 0x36, 0xa0),
+ PIN(166, 0, 4, 0x36, 0xa0),
+ PIN(167, 0, 5, 0x36, 0xa0),
+ PIN(168, 0, 6, 0x36, 0xa0),
+ PIN(169, 0, 7, 0x36, 0xa0),
+ PIN(170, 0, 8, 0x36, 0xa0),
+ PIN(171, 0, 9, 0x36, 0xa0),
+ PIN(172, 0, 13, 0x36, 0xa0),
+ PIN(173, 0, 14, 0x36, 0xa0),
+ PIN(174, 0, 12, 0x36, 0xa0),
+ PIN(175, 0, 15, 0x36, 0xa0),
+ PIN(176, 0, 10, 0x36, 0xa0),
+ PIN(177, 0, 11, 0x36, 0xa0),
+ PIN(178, 0, 16, 0x36, 0xa0),
+ PIN(179, 0, 17, 0x36, 0xa0),
+ PIN(180, 0, 18, 0x36, 0xa0),
+ PIN(181, 0, 19, 0x36, 0xa0),
+ PIN(182, 0, 20, 0x36, 0xa0),
+ PIN(183, 1, 1, 0x18, 0x30),
+ PIN(184, 1, 2, 0x18, 0x30),
+ PIN(185, 1, 4, 0x18, 0x30),
+ PIN(186, 1, 6, 0x18, 0x30),
+ PIN(187, 1, 8, 0x18, 0x30),
+ PIN(188, 1, 3, 0x18, 0x30),
+ PIN(189, 1, 7, 0x18, 0x30),
+ PIN(190, 1, 9, 0x18, 0x30),
+ PIN(191, 1, 10, 0x18, 0x30),
+ PIN(192, 1, 0, 0x18, 0x30),
+ PIN(193, 1, 5, 0x18, 0x30),
+ PIN(194, 1, 11, 0x18, 0x30),
+ PIN(195, 0, 16, 0x14, 0x50),
+ PIN(196, 0, 6, 0x14, 0x50),
+ PIN(197, 0, 8, 0x14, 0x50),
+ PIN(198, 0, 7, 0x14, 0x50),
+ PIN(199, 0, 3, 0x14, 0x50),
+ PIN(200, 0, 6, 0x17, 0x50),
+ PIN(201, 0, 8, 0x17, 0x50),
+ PIN(202, 0, 15, 0x14, 0x50),
+ PIN(203, 0, 17, 0x14, 0x50),
+ PIN(204, 0, 5, 0x17, 0x50),
+ PIN(205, 0, 7, 0x17, 0x50),
+ PIN(206, 0, 18, 0x14, 0x50),
+ PIN(207, 0, 19, 0x14, 0x50),
+ PIN(208, 0, 20, 0x14, 0x50),
+ PIN(209, 0, 12, 0x14, 0x50),
+ PIN(210, 0, 11, 0x14, 0x50),
+ PIN(211, 0, 13, 0x14, 0x50),
+ PIN(212, 0, 10, 0x14, 0x50),
+ PIN(213, 0, 14, 0x14, 0x50),
+ PIN(214, 0, 0, 0x14, 0x50),
+ PIN(215, 0, 9, 0x14, 0x50),
+ PIN(216, 0, 4, 0x14, 0x50),
+ PIN(217, 0, 5, 0x14, 0x50),
+ PIN(218, 0, 1, 0x14, 0x50),
+ PIN(219, 0, 2, 0x14, 0x50),
+};
+
+void plat_mt8192_gpio_init(void);
+#endif /* MT_GPIO_H */
diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c
new file mode 100644
index 000000000..d6d4af742
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <lib/psci/psci.h>
+#include <lib/spinlock.h>
+
+#include <mt_cpu_pm_cpc.h>
+#include <mt_mcdi.h>
+#include <plat_mtk_lpm.h>
+#include <plat_pm.h>
+
+DEFINE_SYSREG_RW_FUNCS(dbgprcr_el1);
+
+static int plat_mt_lp_cpu_rc;
+
+static int pwr_state_prompt(unsigned int cpu, const psci_power_state_t *state)
+{
+ return 0;
+}
+
+static int pwr_state_reflect(unsigned int cpu, const psci_power_state_t *state)
+{
+ mtk_cpc_core_on_hint_clr(cpu);
+
+ if (IS_SYSTEM_SUSPEND_STATE(state)) {
+ mtk_cpc_time_sync();
+ }
+
+ return 0;
+}
+
+static int pwr_cpu_pwron(unsigned int cpu, const psci_power_state_t *state)
+{
+ return 0;
+}
+
+static int pwr_cpu_pwrdwn(unsigned int cpu, const psci_power_state_t *state)
+{
+ /* clear DBGPRCR.CORENPDRQ to allow CPU power down */
+ write_dbgprcr_el1(0ULL);
+
+ return 0;
+}
+
+static int pwr_cluster_pwron(unsigned int cpu, const psci_power_state_t *state)
+{
+ return 0;
+}
+
+static int pwr_cluster_pwrdwn(unsigned int cpu, const psci_power_state_t *state)
+{
+ return 0;
+}
+
+static int pwr_mcusys_pwron(unsigned int cpu, const psci_power_state_t *state)
+{
+ if (!IS_MCUSYS_OFF_STATE(state) || (plat_mt_lp_cpu_rc < 0)) {
+ return -1;
+ }
+
+ mtk_cpc_mcusys_off_reflect();
+
+ return 0;
+}
+
+static int pwr_mcusys_pwron_finished(unsigned int cpu,
+ const psci_power_state_t *state)
+{
+ if (!IS_MCUSYS_OFF_STATE(state) || (plat_mt_lp_cpu_rc < 0)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int pwr_mcusys_pwrdwn(unsigned int cpu, const psci_power_state_t *state)
+{
+ if (!IS_MCUSYS_OFF_STATE(state)) {
+ goto mt_pwr_mcusysoff_break;
+ }
+
+ if (mcdi_try_init() != 0) { /* not ready to process mcusys-off */
+ goto mt_pwr_mcusysoff_break;
+ }
+
+ return 0;
+
+mt_pwr_mcusysoff_break:
+
+ plat_mt_lp_cpu_rc = -1;
+
+ return -1;
+}
+
+static const struct mt_lpm_tz plat_pm = {
+ .pwr_prompt = pwr_state_prompt,
+ .pwr_reflect = pwr_state_reflect,
+ .pwr_cpu_on = pwr_cpu_pwron,
+ .pwr_cpu_dwn = pwr_cpu_pwrdwn,
+ .pwr_cluster_on = pwr_cluster_pwron,
+ .pwr_cluster_dwn = pwr_cluster_pwrdwn,
+ .pwr_mcusys_dwn = pwr_mcusys_pwrdwn,
+ .pwr_mcusys_on = pwr_mcusys_pwron,
+ .pwr_mcusys_on_finished = pwr_mcusys_pwron_finished
+};
+
+const struct mt_lpm_tz *mt_plat_cpu_pm_init(void)
+{
+ mtk_cpc_init();
+
+ if (mcdi_try_init() == 0) {
+ INFO("MCDI init done.\n");
+ }
+
+ return &plat_pm;
+}
diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.c b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.c
new file mode 100644
index 000000000..f8c51a199
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <drivers/delay_timer.h>
+
+#include <mt_cpu_pm_cpc.h>
+#include <mt_timer.h>
+
+struct mtk_cpc_dev {
+ int auto_off;
+ unsigned int auto_thres_tick;
+};
+
+static struct mtk_cpc_dev cpc;
+
+static int mtk_cpc_last_core_prot(uint32_t prot_req,
+ uint32_t resp_reg, uint32_t resp_ofs)
+{
+ uint32_t sta, retry;
+
+ retry = 0U;
+
+ while (retry++ < RETRY_CNT_MAX) {
+
+ mmio_write_32(CPC_MCUSYS_LAST_CORE_REQ, prot_req);
+
+ udelay(1U);
+
+ sta = (mmio_read_32(resp_reg) >> resp_ofs) & CPC_PROT_RESP_MASK;
+
+ if (sta == PROT_SUCCESS) {
+ return CPC_SUCCESS;
+ } else if (sta == PROT_GIVEUP) {
+ return CPC_ERR_FAIL;
+ }
+ }
+
+ return CPC_ERR_TIMEOUT;
+}
+
+int mtk_cpu_pm_mcusys_prot_aquire(void)
+{
+ return mtk_cpc_last_core_prot(
+ MCUSYS_PROT_SET,
+ CPC_MCUSYS_LAST_CORE_RESP,
+ MCUSYS_RESP_OFS);
+}
+
+void mtk_cpu_pm_mcusys_prot_release(void)
+{
+ mmio_write_32(CPC_MCUSYS_PWR_ON_MASK, MCUSYS_PROT_CLR);
+}
+
+int mtk_cpu_pm_cluster_prot_aquire(unsigned int cluster)
+{
+ return mtk_cpc_last_core_prot(
+ CPUSYS_PROT_SET,
+ CPC_MCUSYS_MP_LAST_CORE_RESP,
+ CPUSYS_RESP_OFS);
+}
+
+void mtk_cpu_pm_cluster_prot_release(unsigned int cluster)
+{
+ mmio_write_32(CPC_MCUSYS_PWR_ON_MASK, CPUSYS_PROT_CLR);
+}
+
+static void mtk_cpc_cluster_cnt_backup(void)
+{
+ uint32_t backup_cnt;
+ uint32_t curr_cnt;
+ uint32_t cnt_mask = GENMASK(14, 0);
+ uint32_t clr_mask = GENMASK(1, 0);
+
+ /* Single Cluster */
+ backup_cnt = mmio_read_32(CPC_CLUSTER_CNT_BACKUP);
+ curr_cnt = mmio_read_32(CPC_MCUSYS_CLUSTER_COUNTER);
+
+ /* Get off count if dormant count is 0 */
+ if ((curr_cnt & cnt_mask) == 0U) {
+ curr_cnt = (curr_cnt >> 16) & cnt_mask;
+ } else {
+ curr_cnt = curr_cnt & cnt_mask;
+ }
+
+ mmio_write_32(CPC_CLUSTER_CNT_BACKUP, backup_cnt + curr_cnt);
+ mmio_write_32(CPC_MCUSYS_CLUSTER_COUNTER_CLR, clr_mask);
+}
+
+static inline void mtk_cpc_mcusys_off_en(void)
+{
+ mmio_write_32(CPC_MCUSYS_PWR_CTRL, 1U);
+}
+
+static inline void mtk_cpc_mcusys_off_dis(void)
+{
+ mmio_write_32(CPC_MCUSYS_PWR_CTRL, 0U);
+}
+
+void mtk_cpc_mcusys_off_reflect(void)
+{
+ mtk_cpc_mcusys_off_dis();
+ mtk_cpu_pm_mcusys_prot_release();
+}
+
+int mtk_cpc_mcusys_off_prepare(void)
+{
+ if (mtk_cpu_pm_mcusys_prot_aquire() != CPC_SUCCESS) {
+ return CPC_ERR_FAIL;
+ }
+
+ mtk_cpc_cluster_cnt_backup();
+ mtk_cpc_mcusys_off_en();
+
+ return CPC_SUCCESS;
+}
+
+void mtk_cpc_core_on_hint_set(unsigned int cpu)
+{
+ mmio_write_32(CPC_MCUSYS_CPU_ON_SW_HINT_SET, BIT(cpu));
+}
+
+void mtk_cpc_core_on_hint_clr(unsigned int cpu)
+{
+ mmio_write_32(CPC_MCUSYS_CPU_ON_SW_HINT_CLR, BIT(cpu));
+}
+
+static void mtk_cpc_dump_timestamp(void)
+{
+ uint32_t id;
+
+ for (id = 0U; id < CPC_TRACE_ID_NUM; id++) {
+ mmio_write_32(CPC_MCUSYS_TRACE_SEL, id);
+
+ memcpy((void *)(uintptr_t)CPC_TRACE_SRAM(id),
+ (const void *)(uintptr_t)CPC_MCUSYS_TRACE_DATA,
+ CPC_TRACE_SIZE);
+ }
+}
+
+void mtk_cpc_time_sync(void)
+{
+ uint64_t kt;
+ uint32_t systime_l, systime_h;
+
+ kt = sched_clock();
+ systime_l = mmio_read_32(CNTSYS_L_REG);
+ systime_h = mmio_read_32(CNTSYS_H_REG);
+
+ /* sync kernel timer to cpc */
+ mmio_write_32(CPC_MCUSYS_CPC_KERNEL_TIME_L_BASE, (uint32_t)kt);
+ mmio_write_32(CPC_MCUSYS_CPC_KERNEL_TIME_H_BASE, (uint32_t)(kt >> 32));
+ /* sync system timer to cpc */
+ mmio_write_32(CPC_MCUSYS_CPC_SYSTEM_TIME_L_BASE, systime_l);
+ mmio_write_32(CPC_MCUSYS_CPC_SYSTEM_TIME_H_BASE, systime_h);
+}
+
+static void mtk_cpc_config(uint32_t cfg, uint32_t data)
+{
+ uint32_t val;
+ uint32_t reg = 0U;
+
+ switch (cfg) {
+ case CPC_SMC_CONFIG_PROF:
+ reg = CPC_MCUSYS_CPC_DBG_SETTING;
+ val = mmio_read_32(reg);
+ val = (data != 0U) ? (val | CPC_PROF_EN) : (val & ~CPC_PROF_EN);
+ break;
+ case CPC_SMC_CONFIG_AUTO_OFF:
+ reg = CPC_MCUSYS_CPC_FLOW_CTRL_CFG;
+ val = mmio_read_32(reg);
+ if (data != 0U) {
+ val |= CPC_AUTO_OFF_EN;
+ cpc.auto_off = 1;
+ } else {
+ val &= ~CPC_AUTO_OFF_EN;
+ cpc.auto_off = 0;
+ }
+ break;
+ case CPC_SMC_CONFIG_AUTO_OFF_THRES:
+ reg = CPC_MCUSYS_CPC_OFF_THRES;
+ cpc.auto_thres_tick = us_to_ticks(data);
+ val = cpc.auto_thres_tick;
+ break;
+ case CPC_SMC_CONFIG_CNT_CLR:
+ reg = CPC_MCUSYS_CLUSTER_COUNTER_CLR;
+ val = GENMASK(1, 0); /* clr_mask */
+ break;
+ case CPC_SMC_CONFIG_TIME_SYNC:
+ mtk_cpc_time_sync();
+ break;
+ default:
+ break;
+ }
+
+ if (reg != 0U) {
+ mmio_write_32(reg, val);
+ }
+}
+
+static uint32_t mtk_cpc_read_config(uint32_t cfg)
+{
+ uint32_t res = 0U;
+
+ switch (cfg) {
+ case CPC_SMC_CONFIG_PROF:
+ res = (mmio_read_32(CPC_MCUSYS_CPC_DBG_SETTING) & CPC_PROF_EN) ?
+ 1U : 0U;
+ break;
+ case CPC_SMC_CONFIG_AUTO_OFF:
+ res = cpc.auto_off;
+ break;
+ case CPC_SMC_CONFIG_AUTO_OFF_THRES:
+ res = ticks_to_us(cpc.auto_thres_tick);
+ break;
+ case CPC_SMC_CONFIG_CNT_CLR:
+ break;
+ default:
+ break;
+ }
+
+ return res;
+}
+
+uint64_t mtk_cpc_handler(uint64_t act, uint64_t arg1, uint64_t arg2)
+{
+ uint64_t res = 0ULL;
+
+ switch (act) {
+ case CPC_SMC_EVENT_DUMP_TRACE_DATA:
+ mtk_cpc_dump_timestamp();
+ break;
+ case CPC_SMC_EVENT_GIC_DPG_SET:
+ /* isolated_status = x2; */
+ break;
+ case CPC_SMC_EVENT_CPC_CONFIG:
+ mtk_cpc_config((uint32_t)arg1, (uint32_t)arg2);
+ break;
+ case CPC_SMC_EVENT_READ_CONFIG:
+ res = mtk_cpc_read_config((uint32_t)arg1);
+ break;
+ default:
+ break;
+ }
+
+ return res;
+}
+
+void mtk_cpc_init(void)
+{
+ mmio_write_32(CPC_MCUSYS_CPC_DBG_SETTING,
+ mmio_read_32(CPC_MCUSYS_CPC_DBG_SETTING)
+ | CPC_DBG_EN
+ | CPC_CALC_EN);
+
+ cpc.auto_off = 1;
+ cpc.auto_thres_tick = us_to_ticks(8000);
+
+ mmio_write_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG,
+ mmio_read_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG)
+ | CPC_OFF_PRE_EN
+ | (cpc.auto_off ? CPC_AUTO_OFF_EN : 0U));
+
+ mmio_write_32(CPC_MCUSYS_CPC_OFF_THRES, cpc.auto_thres_tick);
+}
diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.h b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.h
new file mode 100644
index 000000000..19dd6a283
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/mcdi/mt_cpu_pm_cpc.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_CPU_PM_CPC_H
+#define MT_CPU_PM_CPC_H
+
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <mcucfg.h>
+#include <platform_def.h>
+
+#define NEED_CPUSYS_PROT_WORKAROUND 1
+
+/* system sram registers */
+#define CPUIDLE_SRAM_REG(r) (uint32_t)(MTK_MCDI_SRAM_BASE + (r))
+
+/* db dump */
+#define CPC_TRACE_SIZE U(0x20)
+#define CPC_TRACE_ID_NUM U(10)
+#define CPC_TRACE_SRAM(id) (CPUIDLE_SRAM_REG(0x10) + (id) * CPC_TRACE_SIZE)
+
+/* buckup off count */
+#define CPC_CLUSTER_CNT_BACKUP CPUIDLE_SRAM_REG(0x1F0)
+#define CPC_MCUSYS_CNT CPUIDLE_SRAM_REG(0x1F4)
+
+/* CPC_MCUSYS_CPC_FLOW_CTRL_CFG(0xA814): debug setting */
+#define CPC_PWR_ON_SEQ_DIS BIT(1)
+#define CPC_PWR_ON_PRIORITY BIT(2)
+#define CPC_AUTO_OFF_EN BIT(5)
+#define CPC_DORMANT_WAIT_EN BIT(14)
+#define CPC_CTRL_EN BIT(16)
+#define CPC_OFF_PRE_EN BIT(29)
+
+/* CPC_MCUSYS_LAST_CORE_REQ(0xA818) : last core protection */
+#define CPUSYS_PROT_SET BIT(0)
+#define MCUSYS_PROT_SET BIT(8)
+#define CPUSYS_PROT_CLR BIT(8)
+#define MCUSYS_PROT_CLR BIT(9)
+
+#define CPC_PROT_RESP_MASK U(0x3)
+#define CPUSYS_RESP_OFS U(16)
+#define MCUSYS_RESP_OFS U(30)
+
+#define cpusys_resp(r) (((r) >> CPUSYS_RESP_OFS) & CPC_PROT_RESP_MASK)
+#define mcusys_resp(r) (((r) >> MCUSYS_RESP_OFS) & CPC_PROT_RESP_MASK)
+
+#define RETRY_CNT_MAX U(1000)
+
+#define PROT_RETRY U(0)
+#define PROT_SUCCESS U(1)
+#define PROT_GIVEUP U(2)
+
+/* CPC_MCUSYS_CPC_DBG_SETTING(0xAB00): debug setting */
+#define CPC_PROF_EN BIT(0)
+#define CPC_DBG_EN BIT(1)
+#define CPC_FREEZE BIT(2)
+#define CPC_CALC_EN BIT(3)
+
+enum {
+ CPC_SUCCESS = 0,
+
+ CPC_ERR_FAIL,
+ CPC_ERR_TIMEOUT,
+
+ NF_CPC_ERR
+};
+
+enum {
+ CPC_SMC_EVENT_DUMP_TRACE_DATA,
+ CPC_SMC_EVENT_GIC_DPG_SET,
+ CPC_SMC_EVENT_CPC_CONFIG,
+ CPC_SMC_EVENT_READ_CONFIG,
+
+ NF_CPC_SMC_EVENT
+};
+
+enum {
+ CPC_SMC_CONFIG_PROF,
+ CPC_SMC_CONFIG_AUTO_OFF,
+ CPC_SMC_CONFIG_AUTO_OFF_THRES,
+ CPC_SMC_CONFIG_CNT_CLR,
+ CPC_SMC_CONFIG_TIME_SYNC,
+
+ NF_CPC_SMC_CONFIG
+};
+
+#define us_to_ticks(us) ((us) * 13)
+#define ticks_to_us(tick) ((tick) / 13)
+
+int mtk_cpu_pm_cluster_prot_aquire(unsigned int cluster);
+void mtk_cpu_pm_cluster_prot_release(unsigned int cluster);
+
+void mtk_cpc_mcusys_off_reflect(void);
+int mtk_cpc_mcusys_off_prepare(void);
+
+void mtk_cpc_core_on_hint_set(unsigned int cpu);
+void mtk_cpc_core_on_hint_clr(unsigned int cpu);
+void mtk_cpc_time_sync(void);
+
+uint64_t mtk_cpc_handler(uint64_t act, uint64_t arg1, uint64_t arg2);
+void mtk_cpc_init(void);
+
+#endif /* MT_CPU_PM_CPC_H */
diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c b/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c
new file mode 100644
index 000000000..df741221d
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cdefs.h>
+
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <mt_mcdi.h>
+
+/* Read/Write */
+#define APMCU_MCUPM_MBOX_AP_READY U(0)
+#define APMCU_MCUPM_MBOX_RESERVED_1 U(1)
+#define APMCU_MCUPM_MBOX_RESERVED_2 U(2)
+#define APMCU_MCUPM_MBOX_RESERVED_3 U(3)
+#define APMCU_MCUPM_MBOX_PWR_CTRL_EN U(4)
+#define APMCU_MCUPM_MBOX_L3_CACHE_MODE U(5)
+#define APMCU_MCUPM_MBOX_BUCK_MODE U(6)
+#define APMCU_MCUPM_MBOX_ARMPLL_MODE U(7)
+/* Read only */
+#define APMCU_MCUPM_MBOX_TASK_STA U(8)
+#define APMCU_MCUPM_MBOX_RESERVED_9 U(9)
+#define APMCU_MCUPM_MBOX_RESERVED_10 U(10)
+#define APMCU_MCUPM_MBOX_RESERVED_11 U(11)
+
+/* CPC mode - Read/Write */
+#define APMCU_MCUPM_MBOX_WAKEUP_CPU U(12)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_PWR_CTRL_EN */
+#define MCUPM_MCUSYS_CTRL BIT(0)
+#define MCUPM_BUCK_CTRL BIT(1)
+#define MCUPM_ARMPLL_CTRL BIT(2)
+#define MCUPM_CM_CTRL BIT(3)
+#define MCUPM_PWR_CTRL_MASK GENMASK(3, 0)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_BUCK_MODE */
+#define MCUPM_BUCK_NORMAL_MODE U(0) /* default */
+#define MCUPM_BUCK_LP_MODE U(1)
+#define MCUPM_BUCK_OFF_MODE U(2)
+#define NF_MCUPM_BUCK_MODE U(3)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_ARMPLL_MODE */
+#define MCUPM_ARMPLL_ON U(0) /* default */
+#define MCUPM_ARMPLL_GATING U(1)
+#define MCUPM_ARMPLL_OFF U(2)
+#define NF_MCUPM_ARMPLL_MODE U(3)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_TASK_STA */
+#define MCUPM_TASK_UNINIT U(0)
+#define MCUPM_TASK_INIT U(1)
+#define MCUPM_TASK_INIT_FINISH U(2)
+#define MCUPM_TASK_WAIT U(3)
+#define MCUPM_TASK_RUN U(4)
+#define MCUPM_TASK_PAUSE U(5)
+
+#define SSPM_MBOX_3_BASE U(0x0c55fce0)
+
+#define MCDI_NOT_INIT 0
+#define MCDI_INIT_1 1
+#define MCDI_INIT_2 2
+#define MCDI_INIT_DONE 3
+
+static int mcdi_init_status __section("tzfw_coherent_mem");
+
+static inline uint32_t mcdi_mbox_read(uint32_t id)
+{
+ return mmio_read_32(SSPM_MBOX_3_BASE + (id << 2));
+}
+
+static inline void mcdi_mbox_write(uint32_t id, uint32_t val)
+{
+ mmio_write_32(SSPM_MBOX_3_BASE + (id << 2), val);
+}
+
+static void mtk_mcupm_pwr_ctrl_setting(uint32_t dev)
+{
+ mcdi_mbox_write(APMCU_MCUPM_MBOX_PWR_CTRL_EN, dev);
+}
+
+static void mtk_set_mcupm_pll_mode(uint32_t mode)
+{
+ if (mode < NF_MCUPM_ARMPLL_MODE) {
+ mcdi_mbox_write(APMCU_MCUPM_MBOX_ARMPLL_MODE, mode);
+ }
+}
+
+static void mtk_set_mcupm_buck_mode(uint32_t mode)
+{
+ if (mode < NF_MCUPM_BUCK_MODE) {
+ mcdi_mbox_write(APMCU_MCUPM_MBOX_BUCK_MODE, mode);
+ }
+}
+
+static int mtk_mcupm_is_ready(void)
+{
+ unsigned int sta = mcdi_mbox_read(APMCU_MCUPM_MBOX_TASK_STA);
+
+ return (sta == MCUPM_TASK_WAIT) || (sta == MCUPM_TASK_INIT_FINISH);
+}
+
+static int mcdi_init_1(void)
+{
+ unsigned int sta = mcdi_mbox_read(APMCU_MCUPM_MBOX_TASK_STA);
+
+ if (sta != MCUPM_TASK_INIT) {
+ return -1;
+ }
+
+ mtk_set_mcupm_pll_mode(MCUPM_ARMPLL_OFF);
+ mtk_set_mcupm_buck_mode(MCUPM_BUCK_OFF_MODE);
+
+ mtk_mcupm_pwr_ctrl_setting(
+ MCUPM_MCUSYS_CTRL |
+ MCUPM_BUCK_CTRL |
+ MCUPM_ARMPLL_CTRL);
+
+ mcdi_mbox_write(APMCU_MCUPM_MBOX_AP_READY, 1);
+
+ return 0;
+}
+
+static int mcdi_init_2(void)
+{
+ return mtk_mcupm_is_ready() ? 0 : -1;
+}
+
+int mcdi_try_init(void)
+{
+ if (mcdi_init_status == MCDI_INIT_DONE) {
+ return 0;
+ }
+
+ if (mcdi_init_status == MCDI_NOT_INIT) {
+ mcdi_init_status = MCDI_INIT_1;
+ }
+
+ if (mcdi_init_status == MCDI_INIT_1 && mcdi_init_1() == 0) {
+ mcdi_init_status = MCDI_INIT_2;
+ }
+
+ if (mcdi_init_status == MCDI_INIT_2 && mcdi_init_2() == 0) {
+ mcdi_init_status = MCDI_INIT_DONE;
+ }
+
+ return (mcdi_init_status == MCDI_INIT_DONE) ? 0 : mcdi_init_status;
+}
diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.h b/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.h
new file mode 100644
index 000000000..f3545aabf
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/mcdi/mt_mcdi.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_MCDI_H
+#define MT_MCDI_H
+
+int mcdi_try_init(void);
+
+#endif /* MT_MCDI_H */
diff --git a/plat/mediatek/mt8192/drivers/pmic/pmic.c b/plat/mediatek/mt8192/drivers/pmic/pmic.c
new file mode 100644
index 000000000..cca441397
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/pmic/pmic.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <pmic.h>
+#include <pmic_wrap_init.h>
+
+void pmic_power_off(void)
+{
+ pwrap_write(PMIC_PWRHOLD, 0x0);
+}
diff --git a/plat/mediatek/mt8192/drivers/pmic/pmic.h b/plat/mediatek/mt8192/drivers/pmic/pmic.h
new file mode 100644
index 000000000..aac22afa3
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/pmic/pmic.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PMIC_H
+#define PMIC_H
+
+#define PMIC_PWRHOLD 0xa08
+
+/* external API */
+void pmic_power_off(void);
+
+#endif /* PMIC_H */
diff --git a/plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h b/plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h
new file mode 100644
index 000000000..ae892ed5a
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PMIC_WRAP_INIT_H
+#define PMIC_WRAP_INIT_H
+
+#include <stdint.h>
+
+#include "platform_def.h"
+
+/* external API */
+int32_t pwrap_read(uint32_t adr, uint32_t *rdata);
+int32_t pwrap_write(uint32_t adr, uint32_t wdata);
+
+static struct mt8192_pmic_wrap_regs *const mtk_pwrap = (void *)PMIC_WRAP_BASE;
+
+/* PMIC_WRAP registers */
+struct mt8192_pmic_wrap_regs {
+ uint32_t init_done;
+ uint32_t reserved[799];
+ uint32_t wacs2_cmd;
+ uint32_t wacs2_wdata;
+ uint32_t reserved1[3];
+ uint32_t wacs2_rdata;
+ uint32_t reserved2[3];
+ uint32_t wacs2_vldclr;
+ uint32_t wacs2_sta;
+};
+
+#define GET_WACS_FSM(x) ((x >> 1) & 0x7)
+
+/* macro for SWINF_FSM */
+#define SWINF_FSM_IDLE (0x00)
+#define SWINF_FSM_REQ (0x02)
+#define SWINF_FSM_WFDLE (0x04)
+#define SWINF_FSM_WFVLDCLR (0x06)
+#define SWINF_INIT_DONE (0x01)
+
+/* timeout setting */
+#define PWRAP_READ_US 1000
+#define PWRAP_WAIT_IDLE_US 1000
+
+/* error information flag */
+enum pwrap_errno {
+ E_PWR_INVALID_ARG = 1,
+ E_PWR_INVALID_RW = 2,
+ E_PWR_INVALID_ADDR = 3,
+ E_PWR_INVALID_WDAT = 4,
+ E_PWR_INVALID_OP_MANUAL = 5,
+ E_PWR_NOT_IDLE_STATE = 6,
+ E_PWR_NOT_INIT_DONE = 7,
+ E_PWR_NOT_INIT_DONE_READ = 8,
+ E_PWR_WAIT_IDLE_TIMEOUT = 9,
+ E_PWR_WAIT_IDLE_TIMEOUT_READ = 10,
+ E_PWR_INIT_SIDLY_FAIL = 11,
+ E_PWR_RESET_TIMEOUT = 12,
+ E_PWR_TIMEOUT = 13,
+ E_PWR_INIT_RESET_SPI = 20,
+ E_PWR_INIT_SIDLY = 21,
+ E_PWR_INIT_REG_CLOCK = 22,
+ E_PWR_INIT_ENABLE_PMIC = 23,
+ E_PWR_INIT_DIO = 24,
+ E_PWR_INIT_CIPHER = 25,
+ E_PWR_INIT_WRITE_TEST = 26,
+ E_PWR_INIT_ENABLE_CRC = 27,
+ E_PWR_INIT_ENABLE_DEWRAP = 28,
+ E_PWR_INIT_ENABLE_EVENT = 29,
+ E_PWR_READ_TEST_FAIL = 30,
+ E_PWR_WRITE_TEST_FAIL = 31,
+ E_PWR_SWITCH_DIO = 32
+};
+
+#endif /* PMIC_WRAP_INIT_H */
diff --git a/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_common.h b/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_common.h
new file mode 100644
index 000000000..92c71bcdd
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_common.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_PTP3_H
+#define MTK_PTP3_H
+
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+/************************************************
+ * BIT Operation and REG r/w
+ ************************************************/
+#define ptp3_read(addr) mmio_read_32((uintptr_t)addr)
+#define ptp3_write(addr, val) mmio_write_32((uintptr_t)addr, val)
+
+/************************************************
+ * CPU info
+ ************************************************/
+#define NR_PTP3_CFG1_CPU U(8)
+#define PTP3_CFG1_CPU_START_ID U(0)
+#define PTP3_CFG1_MASK 0x00100000
+
+#define NR_PTP3_CFG2_CPU U(4)
+#define PTP3_CFG2_CPU_START_ID U(4)
+
+#define NR_PTP3_CFG3_CPU U(4)
+#define PTP3_CFG3_CPU_START_ID U(4)
+
+/************************************************
+ * config enum
+ ************************************************/
+enum PTP3_CFG {
+ PTP3_CFG_ADDR,
+ PTP3_CFG_VALUE,
+ NR_PTP3_CFG,
+};
+
+/************************************
+ * prototype
+ ************************************/
+/* init trigger for ptp3 feature */
+extern void ptp3_init(unsigned int core);
+extern void ptp3_deinit(unsigned int core);
+
+#endif /* MTK_PTP3_H */
diff --git a/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c b/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c
new file mode 100644
index 000000000..f1d849386
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/ptp3/mtk_ptp3_main.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved. \
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "mtk_ptp3_common.h"
+
+/************************************************
+ * Central control: turn on sysPi protection
+ ************************************************/
+static unsigned int ptp3_cfg1[NR_PTP3_CFG1_CPU][NR_PTP3_CFG] = {
+ {0x0C530610, 0x110842},
+ {0x0C530E10, 0x110842},
+ {0x0C531610, 0x110842},
+ {0x0C531E10, 0x110842},
+ {0x0C532610, 0x110842},
+ {0x0C532E10, 0x110842},
+ {0x0C533610, 0x110842},
+ {0x0C533E10, 0x110842}
+};
+static unsigned int ptp3_cfg2[NR_PTP3_CFG2_CPU][NR_PTP3_CFG] = {
+ {0x0C53B830, 0x68000},
+ {0x0C53BA30, 0x68000},
+ {0x0C53BC30, 0x68000},
+ {0x0C53BE30, 0x68000}
+};
+static unsigned int ptp3_cfg3[NR_PTP3_CFG3_CPU][NR_PTP3_CFG] = {
+ {0x0C532480, 0x7C607C6},
+ {0x0C532C80, 0x7C607C6},
+ {0x0C533480, 0x7C607C6},
+ {0x0C533C80, 0x7C607C6}
+};
+
+/************************************************
+ * API
+ ************************************************/
+void ptp3_init(unsigned int core)
+{
+ unsigned int _core;
+
+ /* Apply ptp3_cfg1 for core 0 to 7 */
+ if (core < NR_PTP3_CFG1_CPU) {
+ /* update ptp3_cfg1 */
+ ptp3_write(
+ ptp3_cfg1[core][PTP3_CFG_ADDR],
+ ptp3_cfg1[core][PTP3_CFG_VALUE]);
+ }
+
+ /* Apply ptp3_cfg2 for core 4 to 7 */
+ if (core >= PTP3_CFG2_CPU_START_ID) {
+ _core = core - PTP3_CFG2_CPU_START_ID;
+
+ if (_core < NR_PTP3_CFG2_CPU) {
+ /* update ptp3_cfg2 */
+ ptp3_write(
+ ptp3_cfg2[_core][PTP3_CFG_ADDR],
+ ptp3_cfg2[_core][PTP3_CFG_VALUE]);
+ }
+ }
+
+ /* Apply ptp3_cfg3 for core 4 to 7 */
+ if (core >= PTP3_CFG3_CPU_START_ID) {
+ _core = core - PTP3_CFG3_CPU_START_ID;
+
+ if (_core < NR_PTP3_CFG3_CPU) {
+ /* update ptp3_cfg3 */
+ ptp3_write(
+ ptp3_cfg3[_core][PTP3_CFG_ADDR],
+ ptp3_cfg3[_core][PTP3_CFG_VALUE]);
+ }
+ }
+}
+
+void ptp3_deinit(unsigned int core)
+{
+ if (core < NR_PTP3_CFG1_CPU) {
+ /* update ptp3_cfg1 */
+ ptp3_write(
+ ptp3_cfg1[core][PTP3_CFG_ADDR],
+ ptp3_cfg1[core][PTP3_CFG_VALUE] &
+ ~PTP3_CFG1_MASK);
+ }
+}
diff --git a/plat/mediatek/mt8192/drivers/rtc/rtc.c b/plat/mediatek/mt8192/drivers/rtc/rtc.c
new file mode 100644
index 000000000..124bc8fbe
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/rtc/rtc.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <rtc.h>
+
+
+static void RTC_Config_Interface(uint32_t addr, uint16_t data,
+ uint16_t mask, uint16_t shift)
+{
+ uint16_t pmic_reg;
+
+ pmic_reg = RTC_Read(addr);
+
+ pmic_reg &= ~(mask << shift);
+ pmic_reg |= (data << shift);
+
+ RTC_Write(addr, pmic_reg);
+}
+
+static int32_t rtc_disable_2sec_reboot(void)
+{
+ uint16_t reboot;
+
+ reboot = (RTC_Read(RTC_AL_SEC) & ~RTC_BBPU_2SEC_EN) &
+ ~RTC_BBPU_AUTO_PDN_SEL;
+ RTC_Write(RTC_AL_SEC, reboot);
+
+ return RTC_Write_Trigger();
+}
+
+static int32_t rtc_enable_k_eosc(void)
+{
+ uint16_t alm_dow, alm_sec;
+ int16_t ret;
+
+ /* Turning on eosc cali mode clock */
+ RTC_Config_Interface(PMIC_RG_SCK_TOP_CKPDN_CON0_CLR, 1,
+ PMIC_RG_RTC_EOSC32_CK_PDN_MASK,
+ PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT);
+
+ alm_sec = RTC_Read(RTC_AL_SEC) & (~RTC_LPD_OPT_MASK);
+ RTC_Write(RTC_AL_SEC, alm_sec);
+ ret = RTC_Write_Trigger();
+ if (ret == 0) {
+ return 0;
+ }
+
+ RTC_Write(RTC_CON, RTC_LPD_EN);
+ ret = RTC_Write_Trigger();
+ if (ret == 0) {
+ return 0;
+ }
+
+ RTC_Write(RTC_CON, RTC_LPD_RST);
+ ret = RTC_Write_Trigger();
+ if (ret == 0) {
+ return 0;
+ }
+
+ RTC_Write(RTC_CON, RTC_LPD_EN);
+ ret = RTC_Write_Trigger();
+ if (ret == 0) {
+ return 0;
+ }
+
+ RTC_Write(RTC_POWERKEY1, RTC_POWERKEY1_KEY);
+ RTC_Write(RTC_POWERKEY2, RTC_POWERKEY2_KEY);
+ ret = RTC_Write_Trigger();
+ if (ret == 0) {
+ return 0;
+ }
+
+ /* set RTC EOSC calibration period = 8sec */
+ alm_dow = (RTC_Read(RTC_AL_DOW) & (~RTC_RG_EOSC_CALI_TD_MASK)) |
+ RTC_RG_EOSC_CALI_TD_8SEC;
+ RTC_Write(RTC_AL_DOW, alm_dow);
+ ret = RTC_Write_Trigger();
+ if (ret == 0) {
+ return 0;
+ }
+
+ RTC_Write(RTC_BBPU,
+ RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
+ ret = RTC_Write_Trigger();
+ if (ret == 0) {
+ return 0;
+ }
+
+ /* Enable K EOSC mode :use solution1 of eosc cali to fix mt6359p 32K*/
+ RTC_Write(RTC_AL_YEA, (((RTC_Read(RTC_AL_YEA) | RTC_K_EOSC_RSV_0)
+ & (~RTC_K_EOSC_RSV_1)) | (RTC_K_EOSC_RSV_2)));
+ ret = RTC_Write_Trigger();
+ if (ret == 0) {
+ return 0;
+ }
+
+ INFO("[RTC] RTC_enable_k_eosc\n");
+
+ return 1;
+}
+
+void rtc_power_off_sequence(void)
+{
+ uint16_t bbpu;
+ int16_t ret;
+
+ ret = rtc_disable_2sec_reboot();
+ if (ret == 0) {
+ return;
+ }
+
+ ret = rtc_enable_k_eosc();
+ if (ret == 0) {
+ return;
+ }
+
+ bbpu = RTC_BBPU_KEY | RTC_BBPU_PWREN;
+
+ if (Writeif_unlock() != 0) {
+ RTC_Write(RTC_BBPU,
+ bbpu | RTC_BBPU_RESET_ALARM | RTC_BBPU_RESET_SPAR);
+ RTC_Write(RTC_AL_MASK, RTC_AL_MASK_DOW);
+ ret = RTC_Write_Trigger();
+ if (ret == 0) {
+ return;
+ }
+ mdelay(1);
+
+ bbpu = RTC_Read(RTC_BBPU);
+
+ if (((bbpu & RTC_BBPU_RESET_ALARM) > 0) ||
+ ((bbpu & RTC_BBPU_RESET_SPAR) > 0)) {
+ INFO("[RTC] timeout\n");
+ }
+
+ bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD;
+ RTC_Write(RTC_BBPU, bbpu);
+ ret = RTC_Write_Trigger();
+ if (ret == 0) {
+ return;
+ }
+ }
+}
diff --git a/plat/mediatek/mt8192/drivers/rtc/rtc.h b/plat/mediatek/mt8192/drivers/rtc/rtc.h
new file mode 100644
index 000000000..419bfe42c
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/rtc/rtc.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RTC_H
+#define RTC_H
+
+/* RTC registers */
+enum {
+ RTC_BBPU = 0x0588,
+ RTC_IRQ_STA = 0x058A,
+ RTC_IRQ_EN = 0x058C,
+ RTC_CII_EN = 0x058E
+};
+
+enum {
+ RTC_AL_SEC = 0x05A0,
+ RTC_AL_MIN = 0x05A2,
+ RTC_AL_HOU = 0x05A4,
+ RTC_AL_DOM = 0x05A6,
+ RTC_AL_DOW = 0x05A8,
+ RTC_AL_MTH = 0x05AA,
+ RTC_AL_YEA = 0x05AC,
+ RTC_AL_MASK = 0x0590
+};
+
+enum {
+ RTC_OSC32CON = 0x05AE,
+ RTC_CON = 0x05C4,
+ RTC_WRTGR = 0x05C2
+};
+
+enum {
+ RTC_POWERKEY1 = 0x05B0,
+ RTC_POWERKEY2 = 0x05B2
+};
+
+enum {
+ RTC_POWERKEY1_KEY = 0xA357,
+ RTC_POWERKEY2_KEY = 0x67D2
+};
+
+enum {
+ RTC_PDN1 = 0x05B4,
+ RTC_PDN2 = 0x05B6,
+ RTC_SPAR0 = 0x05B8,
+ RTC_SPAR1 = 0x05BA,
+ RTC_PROT = 0x05BC,
+ RTC_DIFF = 0x05BE,
+ RTC_CALI = 0x05C0
+};
+
+enum {
+ RTC_OSC32CON_UNLOCK1 = 0x1A57,
+ RTC_OSC32CON_UNLOCK2 = 0x2B68
+};
+
+enum {
+ RTC_LPD_EN = 0x0406,
+ RTC_LPD_RST = 0x040E
+};
+
+enum {
+ RTC_LPD_OPT_XOSC_AND_EOSC_LPD = 0U << 13,
+ RTC_LPD_OPT_EOSC_LPD = 1U << 13,
+ RTC_LPD_OPT_XOSC_LPD = 2U << 13,
+ RTC_LPD_OPT_F32K_CK_ALIVE = 3U << 13,
+};
+
+#define RTC_LPD_OPT_MASK (3U << 13)
+
+enum {
+ RTC_PROT_UNLOCK1 = 0x586A,
+ RTC_PROT_UNLOCK2 = 0x9136
+};
+
+enum {
+ RTC_BBPU_PWREN = 1U << 0,
+ RTC_BBPU_SPAR_SW = 1U << 1,
+ RTC_BBPU_RESET_SPAR = 1U << 2,
+ RTC_BBPU_RESET_ALARM = 1U << 3,
+ RTC_BBPU_CLRPKY = 1U << 4,
+ RTC_BBPU_RELOAD = 1U << 5,
+ RTC_BBPU_CBUSY = 1U << 6
+};
+
+enum {
+ RTC_AL_MASK_SEC = 1U << 0,
+ RTC_AL_MASK_MIN = 1U << 1,
+ RTC_AL_MASK_HOU = 1U << 2,
+ RTC_AL_MASK_DOM = 1U << 3,
+ RTC_AL_MASK_DOW = 1U << 4,
+ RTC_AL_MASK_MTH = 1U << 5,
+ RTC_AL_MASK_YEA = 1U << 6
+};
+
+enum {
+ RTC_BBPU_AUTO_PDN_SEL = 1U << 6,
+ RTC_BBPU_2SEC_CK_SEL = 1U << 7,
+ RTC_BBPU_2SEC_EN = 1U << 8,
+ RTC_BBPU_2SEC_MODE = 0x3 << 9,
+ RTC_BBPU_2SEC_STAT_CLEAR = 1U << 11,
+ RTC_BBPU_2SEC_STAT_STA = 1U << 12
+};
+
+enum {
+ RTC_BBPU_KEY = 0x43 << 8
+};
+
+enum {
+ RTC_EMBCK_SRC_SEL = 1 << 8,
+ RTC_EMBCK_SEL_MODE = 3 << 6,
+ RTC_XOSC32_ENB = 1 << 5,
+ RTC_REG_XOSC32_ENB = 1 << 15
+};
+
+enum {
+ RTC_K_EOSC_RSV_0 = 1 << 8,
+ RTC_K_EOSC_RSV_1 = 1 << 9,
+ RTC_K_EOSC_RSV_2 = 1 << 10
+};
+
+enum {
+ RTC_RG_EOSC_CALI_TD_1SEC = 3 << 5,
+ RTC_RG_EOSC_CALI_TD_2SEC = 4 << 5,
+ RTC_RG_EOSC_CALI_TD_4SEC = 5 << 5,
+ RTC_RG_EOSC_CALI_TD_8SEC = 6 << 5,
+ RTC_RG_EOSC_CALI_TD_16SEC = 7 << 5,
+ RTC_RG_EOSC_CALI_TD_MASK = 7 << 5
+};
+
+/* PMIC TOP Register Definition */
+enum {
+ PMIC_RG_TOP_CON = 0x0020,
+ PMIC_RG_TOP_CKPDN_CON1 = 0x0112,
+ PMIC_RG_TOP_CKPDN_CON1_SET = 0x0114,
+ PMIC_RG_TOP_CKPDN_CON1_CLR = 0x0116,
+ PMIC_RG_TOP_CKSEL_CON0 = 0x0118,
+ PMIC_RG_TOP_CKSEL_CON0_SET = 0x011A,
+ PMIC_RG_TOP_CKSEL_CON0_CLR = 0x011C
+};
+
+/* PMIC SCK Register Definition */
+enum {
+ PMIC_RG_SCK_TOP_CKPDN_CON0 = 0x0514,
+ PMIC_RG_SCK_TOP_CKPDN_CON0_SET = 0x0516,
+ PMIC_RG_SCK_TOP_CKPDN_CON0_CLR = 0x0518,
+ PMIC_RG_EOSC_CALI_CON0 = 0x53A
+};
+
+enum {
+ PMIC_EOSC_CALI_START_ADDR = 0x53A
+};
+
+enum {
+ PMIC_EOSC_CALI_START_MASK = 0x1,
+ PMIC_EOSC_CALI_START_SHIFT = 0
+};
+
+/* PMIC DCXO Register Definition */
+enum {
+ PMIC_RG_DCXO_CW00 = 0x0788,
+ PMIC_RG_DCXO_CW02 = 0x0790,
+ PMIC_RG_DCXO_CW08 = 0x079C,
+ PMIC_RG_DCXO_CW09 = 0x079E,
+ PMIC_RG_DCXO_CW09_CLR = 0x07A2,
+ PMIC_RG_DCXO_CW10 = 0x07A4,
+ PMIC_RG_DCXO_CW12 = 0x07A8,
+ PMIC_RG_DCXO_CW13 = 0x07AA,
+ PMIC_RG_DCXO_CW15 = 0x07AE,
+ PMIC_RG_DCXO_CW19 = 0x07B6,
+};
+
+enum {
+ PMIC_RG_SRCLKEN_IN0_HW_MODE_MASK = 0x1,
+ PMIC_RG_SRCLKEN_IN0_HW_MODE_SHIFT = 1,
+ PMIC_RG_SRCLKEN_IN1_HW_MODE_MASK = 0x1,
+ PMIC_RG_SRCLKEN_IN1_HW_MODE_SHIFT = 3,
+ PMIC_RG_RTC_EOSC32_CK_PDN_MASK = 0x1,
+ PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT = 2,
+ PMIC_RG_EOSC_CALI_TD_MASK = 0x7,
+ PMIC_RG_EOSC_CALI_TD_SHIFT = 5,
+ PMIC_RG_XO_EN32K_MAN_MASK = 0x1,
+ PMIC_RG_XO_EN32K_MAN_SHIFT = 0
+};
+
+/* external API */
+uint16_t RTC_Read(uint32_t addr);
+void RTC_Write(uint32_t addr, uint16_t data);
+int32_t rtc_busy_wait(void);
+int32_t RTC_Write_Trigger(void);
+int32_t Writeif_unlock(void);
+void rtc_power_off_sequence(void);
+
+#endif /* RTC_H */
diff --git a/plat/mediatek/mt8192/drivers/spmc/mtspmc.c b/plat/mediatek/mt8192/drivers/spmc/mtspmc.c
new file mode 100644
index 000000000..7ccebd6ab
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/spmc/mtspmc.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <mcucfg.h>
+#include <mtspmc.h>
+#include <mtspmc_private.h>
+
+
+void mcucfg_disable_gic_wakeup(uint32_t cluster, uint32_t cpu)
+{
+ mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(cpu));
+}
+
+void mcucfg_enable_gic_wakeup(uint32_t cluster, uint32_t cpu)
+{
+ mmio_clrbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(cpu));
+}
+
+void mcucfg_set_bootaddr(uint32_t cluster, uint32_t cpu, uintptr_t bootaddr)
+{
+ assert(cluster == 0U);
+
+ mmio_write_32(per_cpu(cluster, cpu, MCUCFG_BOOTADDR), bootaddr);
+}
+
+uintptr_t mcucfg_get_bootaddr(uint32_t cluster, uint32_t cpu)
+{
+ assert(cluster == 0U);
+
+ return (uintptr_t)mmio_read_32(per_cpu(cluster, cpu, MCUCFG_BOOTADDR));
+}
+
+void mcucfg_init_archstate(uint32_t cluster, uint32_t cpu, bool arm64)
+{
+ uint32_t reg;
+
+ assert(cluster == 0U);
+
+ reg = per_cluster(cluster, MCUCFG_INITARCH);
+
+ if (arm64) {
+ mmio_setbits_32(reg, MCUCFG_INITARCH_CPU_BIT(cpu));
+ } else {
+ mmio_clrbits_32(reg, MCUCFG_INITARCH_CPU_BIT(cpu));
+ }
+}
+
+/**
+ * Return subsystem's power state.
+ *
+ * @mask: mask to SPM_CPU_PWR_STATUS to query the power state
+ * of one subsystem.
+ * RETURNS:
+ * 0 (the subsys was powered off)
+ * 1 (the subsys was powered on)
+ */
+bool spm_get_powerstate(uint32_t mask)
+{
+ return (mmio_read_32(SPM_CPU_PWR_STATUS) & mask) != 0U;
+}
+
+bool spm_get_cluster_powerstate(uint32_t cluster)
+{
+ assert(cluster == 0U);
+
+ return spm_get_powerstate(MP0_CPUTOP);
+}
+
+bool spm_get_cpu_powerstate(uint32_t cluster, uint32_t cpu)
+{
+ uint32_t mask = BIT(cpu);
+
+ assert(cluster == 0U);
+
+ return spm_get_powerstate(mask);
+}
+
+int spmc_init(void)
+{
+ INFO("SPM: enable CPC mode\n");
+
+ mmio_write_32(SPM_POWERON_CONFIG_EN, PROJECT_CODE | BCLK_CG_EN);
+
+ mmio_setbits_32(per_cpu(0, 1, SPM_CPU_PWR), PWR_RST_B);
+ mmio_setbits_32(per_cpu(0, 2, SPM_CPU_PWR), PWR_RST_B);
+ mmio_setbits_32(per_cpu(0, 3, SPM_CPU_PWR), PWR_RST_B);
+ mmio_setbits_32(per_cpu(0, 4, SPM_CPU_PWR), PWR_RST_B);
+ mmio_setbits_32(per_cpu(0, 5, SPM_CPU_PWR), PWR_RST_B);
+ mmio_setbits_32(per_cpu(0, 6, SPM_CPU_PWR), PWR_RST_B);
+ mmio_setbits_32(per_cpu(0, 7, SPM_CPU_PWR), PWR_RST_B);
+
+ mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(1));
+ mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(2));
+ mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(3));
+ mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(4));
+ mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(5));
+ mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(6));
+ mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, GIC_WAKEUP_IGNORE(7));
+
+ mmio_clrbits_32(SPM_MCUSYS_PWR_CON, RESETPWRON_CONFIG);
+ mmio_clrbits_32(SPM_MP0_CPUTOP_PWR_CON, RESETPWRON_CONFIG);
+ mmio_clrbits_32(per_cpu(0, 0, SPM_CPU_PWR), RESETPWRON_CONFIG);
+
+ mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, CPC_CTRL_ENABLE);
+
+ return 0;
+}
+
+/**
+ * Power on a core with specified cluster and core index
+ *
+ * @cluster: the cluster ID of the CPU which to be powered on
+ * @cpu: the CPU ID of the CPU which to be powered on
+ */
+void spm_poweron_cpu(uint32_t cluster, uint32_t cpu)
+{
+ /* set to 0 after BIG VPROC bulk on & before B-core power on seq. */
+ if (cpu >= 4U) {
+ mmio_write_32(DREQ20_BIG_VPROC_ISO, 0U);
+ }
+
+ mmio_setbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, SSPM_ALL_PWR_CTRL_EN);
+ mmio_setbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWR_ON);
+
+ while (!spm_get_cpu_powerstate(cluster, cpu)) {
+ }
+
+ mmio_clrbits_32(MCUCFG_CPC_FLOW_CTRL_CFG, SSPM_ALL_PWR_CTRL_EN);
+
+ /* Enable Big CPU Last PC */
+ if (cpu >= 4U) {
+ mmio_clrbits_32(LAST_PC_REG(cpu), BIT(3));
+ }
+}
+
+/**
+ * Power off a core with specified cluster and core index
+ *
+ * @cluster: the cluster ID of the CPU which to be powered off
+ * @cpu: the CPU ID of the CPU which to be powered off
+ */
+void spm_poweroff_cpu(uint32_t cluster, uint32_t cpu)
+{
+ /* Set mp0_spmc_pwr_on_cpuX = 0 */
+ mmio_clrbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWR_ON);
+}
+
+/**
+ * Power off a cluster with specified index
+ *
+ * @cluster: the cluster index which to be powered off
+ */
+void spm_poweroff_cluster(uint32_t cluster)
+{
+ /* No need to power on/off cluster on single cluster platform */
+ assert(false);
+}
+
+/**
+ * Power on a cluster with specified index
+ *
+ * @cluster: the cluster index which to be powered on
+ */
+void spm_poweron_cluster(uint32_t cluster)
+{
+ /* No need to power on/off cluster on single cluster platform */
+ assert(false);
+}
diff --git a/plat/mediatek/mt8192/drivers/spmc/mtspmc.h b/plat/mediatek/mt8192/drivers/spmc/mtspmc.h
new file mode 100644
index 000000000..7ed2e6220
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/spmc/mtspmc.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTSPMC_H
+#define MTSPMC_H
+
+#include <stdint.h>
+
+int spmc_init(void);
+
+void spm_poweron_cpu(uint32_t cluster, uint32_t cpu);
+void spm_poweroff_cpu(uint32_t cluster, uint32_t cpu);
+
+void spm_poweroff_cluster(uint32_t cluster);
+void spm_poweron_cluster(uint32_t cluster);
+
+bool spm_get_cpu_powerstate(uint32_t cluster, uint32_t cpu);
+bool spm_get_cluster_powerstate(uint32_t cluster);
+bool spm_get_powerstate(uint32_t mask);
+
+void mcucfg_init_archstate(uint32_t cluster, uint32_t cpu, bool arm64);
+void mcucfg_set_bootaddr(uint32_t cluster, uint32_t cpu, uintptr_t bootaddr);
+uintptr_t mcucfg_get_bootaddr(uint32_t cluster, uint32_t cpu);
+
+void mcucfg_disable_gic_wakeup(uint32_t cluster, uint32_t cpu);
+void mcucfg_enable_gic_wakeup(uint32_t cluster, uint32_t cpu);
+
+#endif /* MTSPMC_H */
diff --git a/plat/mediatek/mt8192/drivers/spmc/mtspmc_private.h b/plat/mediatek/mt8192/drivers/spmc/mtspmc_private.h
new file mode 100644
index 000000000..ad782955d
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/spmc/mtspmc_private.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTSPMC_PRIVATE_H
+#define MTSPMC_PRIVATE_H
+
+#include <lib/utils_def.h>
+#include <platform_def.h>
+
+unsigned long read_cpuectlr(void);
+void write_cpuectlr(unsigned long cpuectlr);
+
+unsigned long read_cpupwrctlr_el1(void);
+void write_cpupwrctlr_el1(unsigned long cpuectlr);
+
+/*
+ * per_cpu/cluster helper
+ */
+struct per_cpu_reg {
+ unsigned int cluster_addr;
+ unsigned int cpu_stride;
+};
+
+#define per_cpu(cluster, cpu, reg) \
+ (reg[cluster].cluster_addr + (cpu << reg[cluster].cpu_stride))
+
+#define per_cluster(cluster, reg) (reg[cluster].cluster_addr)
+
+#define SPM_REG(ofs) (uint32_t)(SPM_BASE + (ofs))
+#define MCUCFG_REG(ofs) (uint32_t)(MCUCFG_BASE + (ofs))
+#define INFRACFG_AO_REG(ofs) (uint32_t)(INFRACFG_AO_BASE + (ofs))
+
+/* === SPMC related registers */
+#define SPM_POWERON_CONFIG_EN SPM_REG(0x000)
+/* bit-fields of SPM_POWERON_CONFIG_EN */
+#define PROJECT_CODE (U(0xb16) << 16)
+#define BCLK_CG_EN BIT(0)
+
+#define SPM_PWR_STATUS SPM_REG(0x16c)
+#define SPM_PWR_STATUS_2ND SPM_REG(0x170)
+#define SPM_CPU_PWR_STATUS SPM_REG(0x174)
+
+/* bit-fields of SPM_PWR_STATUS */
+#define MD BIT(0)
+#define CONN BIT(1)
+#define DDRPHY BIT(2)
+#define DISP BIT(3)
+#define MFG BIT(4)
+#define ISP BIT(5)
+#define INFRA BIT(6)
+#define VDEC BIT(7)
+#define MP0_CPUTOP BIT(8)
+#define MP0_CPU0 BIT(9)
+#define MP0_CPU1 BIT(10)
+#define MP0_CPU2 BIT(11)
+#define MP0_CPU3 BIT(12)
+#define MCUSYS BIT(14)
+#define MP0_CPU4 BIT(15)
+#define MP0_CPU5 BIT(16)
+#define MP0_CPU6 BIT(17)
+#define MP0_CPU7 BIT(18)
+#define VEN BIT(21)
+
+/* === SPMC related registers */
+#define SPM_MCUSYS_PWR_CON MCUCFG_REG(0xd200)
+#define SPM_MP0_CPUTOP_PWR_CON MCUCFG_REG(0xd204)
+#define SPM_MP0_CPU0_PWR_CON MCUCFG_REG(0xd208)
+#define SPM_MP0_CPU1_PWR_CON MCUCFG_REG(0xd20c)
+#define SPM_MP0_CPU2_PWR_CON MCUCFG_REG(0xd210)
+#define SPM_MP0_CPU3_PWR_CON MCUCFG_REG(0xd214)
+#define SPM_MP0_CPU4_PWR_CON MCUCFG_REG(0xd218)
+#define SPM_MP0_CPU5_PWR_CON MCUCFG_REG(0xd21c)
+#define SPM_MP0_CPU6_PWR_CON MCUCFG_REG(0xd220)
+#define SPM_MP0_CPU7_PWR_CON MCUCFG_REG(0xd224)
+
+/* bit fields of SPM_*_PWR_CON */
+#define PWR_ON_ACK BIT(31)
+#define VPROC_EXT_OFF BIT(7)
+#define DORMANT_EN BIT(6)
+#define RESETPWRON_CONFIG BIT(5)
+#define PWR_CLK_DIS BIT(4)
+#define PWR_ON BIT(2)
+#define PWR_RST_B BIT(0)
+
+/**** per_cpu registers for SPM_MP0_CPU?_PWR_CON */
+static const struct per_cpu_reg SPM_CPU_PWR[] = {
+ { .cluster_addr = SPM_MP0_CPU0_PWR_CON, .cpu_stride = 2U }
+};
+
+/**** per_cluster registers for SPM_MP0_CPUTOP_PWR_CON */
+static const struct per_cpu_reg SPM_CLUSTER_PWR[] = {
+ { .cluster_addr = SPM_MP0_CPUTOP_PWR_CON, .cpu_stride = 0U }
+};
+
+/* === MCUCFG related registers */
+/* aa64naa32 */
+#define MCUCFG_MP0_CLUSTER_CFG5 MCUCFG_REG(0xc8e4)
+/* reset vectors */
+#define MCUCFG_MP0_CLUSTER_CFG8 MCUCFG_REG(0xc900)
+#define MCUCFG_MP0_CLUSTER_CFG10 MCUCFG_REG(0xc908)
+#define MCUCFG_MP0_CLUSTER_CFG12 MCUCFG_REG(0xc910)
+#define MCUCFG_MP0_CLUSTER_CFG14 MCUCFG_REG(0xc918)
+#define MCUCFG_MP0_CLUSTER_CFG16 MCUCFG_REG(0xc920)
+#define MCUCFG_MP0_CLUSTER_CFG18 MCUCFG_REG(0xc928)
+#define MCUCFG_MP0_CLUSTER_CFG20 MCUCFG_REG(0xc930)
+#define MCUCFG_MP0_CLUSTER_CFG22 MCUCFG_REG(0xc938)
+
+/* MCUSYS DREQ BIG VPROC ISO control */
+#define DREQ20_BIG_VPROC_ISO MCUCFG_REG(0xad8c)
+
+/**** per_cpu registers for MCUCFG_MP0_CLUSTER_CFG? */
+static const struct per_cpu_reg MCUCFG_BOOTADDR[] = {
+ { .cluster_addr = MCUCFG_MP0_CLUSTER_CFG8, .cpu_stride = 3U }
+};
+
+/**** per_cpu registers for MCUCFG_MP0_CLUSTER_CFG5 */
+static const struct per_cpu_reg MCUCFG_INITARCH[] = {
+ { .cluster_addr = MCUCFG_MP0_CLUSTER_CFG5, .cpu_stride = 0U }
+};
+
+#define MCUCFG_INITARCH_CPU_BIT(cpu) BIT(16U + cpu)
+#define LAST_PC_REG(cpu) (MCUCFG_REG(0x308) + (cpu * 0x800))
+
+/* === CPC control */
+#define MCUCFG_CPC_FLOW_CTRL_CFG MCUCFG_REG(0xa814)
+#define MCUCFG_CPC_SPMC_PWR_STATUS MCUCFG_REG(0xa840)
+
+/* bit fields of CPC_FLOW_CTRL_CFG */
+#define CPC_CTRL_ENABLE BIT(16)
+#define SSPM_ALL_PWR_CTRL_EN BIT(13) /* for cpu-hotplug */
+#define GIC_WAKEUP_IGNORE(cpu) BIT(21 + cpu)
+
+/* bit fields of CPC_SPMC_PWR_STATUS */
+#define CORE_SPMC_PWR_ON_ACK GENMASK(15, 0)
+
+/* === APB Module infracfg_ao */
+#define INFRA_TOPAXI_PROTECTEN INFRACFG_AO_REG(0x0220)
+#define INFRA_TOPAXI_PROTECTEN_STA0 INFRACFG_AO_REG(0x0224)
+#define INFRA_TOPAXI_PROTECTEN_STA1 INFRACFG_AO_REG(0x0228)
+#define INFRA_TOPAXI_PROTECTEN_SET INFRACFG_AO_REG(0x02a0)
+#define INFRA_TOPAXI_PROTECTEN_CLR INFRACFG_AO_REG(0x02a4)
+#define INFRA_TOPAXI_PROTECTEN_1 INFRACFG_AO_REG(0x0250)
+#define INFRA_TOPAXI_PROTECTEN_STA0_1 INFRACFG_AO_REG(0x0254)
+#define INFRA_TOPAXI_PROTECTEN_STA1_1 INFRACFG_AO_REG(0x0258)
+#define INFRA_TOPAXI_PROTECTEN_1_SET INFRACFG_AO_REG(0x02a8)
+#define INFRA_TOPAXI_PROTECTEN_1_CLR INFRACFG_AO_REG(0x02ac)
+
+/* bit fields of INFRA_TOPAXI_PROTECTEN */
+#define MP0_SPMC_PROT_STEP1_0_MASK BIT(12)
+#define MP0_SPMC_PROT_STEP1_1_MASK (BIT(26) | BIT(12))
+
+/* === SPARK */
+#define VOLTAGE_04 U(0x40)
+#define VOLTAGE_05 U(0x60)
+
+#define PTP3_CPU0_SPMC_SW_CFG MCUCFG_REG(0x200)
+#define CPU0_ILDO_CONTROL5 MCUCFG_REG(0x334)
+#define CPU0_ILDO_CONTROL8 MCUCFG_REG(0x340)
+
+/* bit fields of CPU0_ILDO_CONTROL5 */
+#define ILDO_RET_VOSEL GENMASK(7, 0)
+
+/* bit fields of PTP3_CPU_SPMC_SW_CFG */
+#define SW_SPARK_EN BIT(0)
+
+/* bit fields of CPU0_ILDO_CONTROL8 */
+#define ILDO_BYPASS_B BIT(0)
+
+static const struct per_cpu_reg MCUCFG_SPARK[] = {
+ { .cluster_addr = PTP3_CPU0_SPMC_SW_CFG, .cpu_stride = 11U }
+};
+
+static const struct per_cpu_reg ILDO_CONTROL5[] = {
+ { .cluster_addr = CPU0_ILDO_CONTROL5, .cpu_stride = 11U }
+};
+
+static const struct per_cpu_reg ILDO_CONTROL8[] = {
+ { .cluster_addr = CPU0_ILDO_CONTROL8, .cpu_stride = 11U }
+};
+
+#endif /* MTSPMC_PRIVATE_H */
diff --git a/plat/mediatek/mt8192/drivers/timer/mt_timer.c b/plat/mediatek/mt8192/drivers/timer/mt_timer.c
new file mode 100644
index 000000000..08608854a
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/timer/mt_timer.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <lib/mmio.h>
+#include <mt_timer.h>
+#include <platform_def.h>
+
+
+uint64_t normal_time_base;
+uint64_t atf_time_base;
+
+void sched_clock_init(uint64_t normal_base, uint64_t atf_base)
+{
+ normal_time_base += normal_base;
+ atf_time_base = atf_base;
+}
+
+uint64_t sched_clock(void)
+{
+ uint64_t cval;
+ uint64_t rel_base;
+
+ rel_base = read_cntpct_el0() - atf_time_base;
+ cval = ((rel_base * 1000U) / SYS_COUNTER_FREQ_IN_MHZ)
+ - normal_time_base;
+ return cval;
+}
+
+void mt_systimer_init(void)
+{
+ /* Enable access in NS mode */
+ mmio_write_32(CNTWACR_REG, CNT_WRITE_ACCESS_CTL_MASK);
+ mmio_write_32(CNTRACR_REG, CNT_READ_ACCESS_CTL_MASK);
+}
diff --git a/plat/mediatek/mt8192/drivers/timer/mt_timer.h b/plat/mediatek/mt8192/drivers/timer/mt_timer.h
new file mode 100644
index 000000000..b35317715
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/timer/mt_timer.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_TIMER_H
+#define MT_TIMER_H
+
+#define SYSTIMER_BASE (0x10017000)
+#define CNTCR_REG (SYSTIMER_BASE + 0x0)
+#define CNTSR_REG (SYSTIMER_BASE + 0x4)
+#define CNTSYS_L_REG (SYSTIMER_BASE + 0x8)
+#define CNTSYS_H_REG (SYSTIMER_BASE + 0xc)
+#define CNTWACR_REG (SYSTIMER_BASE + 0x10)
+#define CNTRACR_REG (SYSTIMER_BASE + 0x14)
+
+#define TIEO_EN (1 << 3)
+#define COMP_15_EN (1 << 10)
+#define COMP_20_EN (1 << 11)
+#define COMP_25_EN (1 << 12)
+
+#define COMP_FEATURE_MASK (COMP_15_EN | COMP_20_EN | COMP_25_EN | TIEO_EN)
+#define COMP_15_MASK (COMP_15_EN)
+#define COMP_20_MASK (COMP_20_EN | TIEO_EN)
+#define COMP_25_MASK (COMP_20_EN | COMP_25_EN)
+
+#define CNT_WRITE_ACCESS_CTL_MASK (0x3FFFFF0U)
+#define CNT_READ_ACCESS_CTL_MASK (0x3FFFFFFU)
+
+void sched_clock_init(uint64_t normal_base, uint64_t atf_base);
+uint64_t sched_clock(void);
+void mt_systimer_init(void);
+
+#endif /* MT_TIMER_H */
diff --git a/plat/mediatek/mt8192/drivers/uart/uart.h b/plat/mediatek/mt8192/drivers/uart/uart.h
new file mode 100644
index 000000000..ac8b94dd1
--- /dev/null
+++ b/plat/mediatek/mt8192/drivers/uart/uart.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef UART_H
+#define UART_H
+
+#include <platform_def.h>
+
+/* UART HW information */
+#define HW_SUPPORT_UART_PORTS 2
+#define DRV_SUPPORT_UART_PORTS 2
+
+/* console UART clock cg */
+#define UART_CLOCK_GATE_SET (INFRACFG_AO_BASE + 0x80)
+#define UART_CLOCK_GATE_CLR (INFRACFG_AO_BASE + 0x84)
+#define UART_CLOCK_GATE_STA (INFRACFG_AO_BASE + 0x90)
+#define UART0_CLOCK_GATE_BIT (1U<<22)
+#define UART1_CLOCK_GATE_BIT (1U<<23)
+
+/* UART registers */
+#define UART_RBR(_baseaddr) (_baseaddr + 0x0)
+#define UART_THR(_baseaddr) (_baseaddr + 0x0)
+#define UART_IER(_baseaddr) (_baseaddr + 0x4)
+#define UART_IIR(_baseaddr) (_baseaddr + 0x8)
+#define UART_FCR(_baseaddr) (_baseaddr + 0x8)
+#define UART_LCR(_baseaddr) (_baseaddr + 0xc)
+#define UART_MCR(_baseaddr) (_baseaddr + 0x10)
+#define UART_LSR(_baseaddr) (_baseaddr + 0x14)
+#define UART_MSR(_baseaddr) (_baseaddr + 0x18)
+#define UART_SCR(_baseaddr) (_baseaddr + 0x1c)
+#define UART_DLL(_baseaddr) (_baseaddr + 0x0)
+#define UART_DLH(_baseaddr) (_baseaddr + 0x4)
+#define UART_EFR(_baseaddr) (_baseaddr + 0x8)
+#define UART_XON1(_baseaddr) (_baseaddr + 0x10)
+#define UART_XON2(_baseaddr) (_baseaddr + 0x14)
+#define UART_XOFF1(_baseaddr) (_baseaddr + 0x18)
+#define UART_XOFF2(_baseaddr) (_baseaddr + 0x1c)
+#define UART_AUTOBAUD(_baseaddr) (_baseaddr + 0x20)
+#define UART_HIGHSPEED(_baseaddr) (_baseaddr + 0x24)
+#define UART_SAMPLE_COUNT(_baseaddr) (_baseaddr + 0x28)
+#define UART_SAMPLE_POINT(_baseaddr) (_baseaddr + 0x2c)
+#define UART_AUTOBAUD_REG(_baseaddr) (_baseaddr + 0x30)
+#define UART_RATE_FIX_REG(_baseaddr) (_baseaddr + 0x34)
+#define UART_AUTO_BAUDSAMPLE(_baseaddr) (_baseaddr + 0x38)
+#define UART_GUARD(_baseaddr) (_baseaddr + 0x3c)
+#define UART_ESCAPE_DAT(_baseaddr) (_baseaddr + 0x40)
+#define UART_ESCAPE_EN(_baseaddr) (_baseaddr + 0x44)
+#define UART_SLEEP_EN(_baseaddr) (_baseaddr + 0x48)
+#define UART_DMA_EN(_baseaddr) (_baseaddr + 0x4c)
+#define UART_RXTRI_AD(_baseaddr) (_baseaddr + 0x50)
+#define UART_FRACDIV_L(_baseaddr) (_baseaddr + 0x54)
+#define UART_FRACDIV_M(_baseaddr) (_baseaddr + 0x58)
+#define UART_FCR_RD(_baseaddr) (_baseaddr + 0x5C)
+#define UART_USB_RX_SEL(_baseaddr) (_baseaddr + 0xB0)
+#define UART_SLEEP_REQ(_baseaddr) (_baseaddr + 0xB4)
+#define UART_SLEEP_ACK(_baseaddr) (_baseaddr + 0xB8)
+#define UART_SPM_SEL(_baseaddr) (_baseaddr + 0xBC)
+#define UART_LCR_DLAB 0x0080
+#define UART_LCR_MODE_B 0x00bf
+
+enum uart_port_ID {
+ UART_PORT0 = 0,
+ UART_PORT1
+};
+
+struct mt_uart_register {
+ uint32_t dll;
+ uint32_t dlh;
+ uint32_t ier;
+ uint32_t lcr;
+ uint32_t mcr;
+ uint32_t fcr;
+ uint32_t lsr;
+ uint32_t scr;
+ uint32_t efr;
+ uint32_t highspeed;
+ uint32_t sample_count;
+ uint32_t sample_point;
+ uint32_t fracdiv_l;
+ uint32_t fracdiv_m;
+ uint32_t escape_en;
+ uint32_t guard;
+ uint32_t rx_sel;
+};
+
+struct mt_uart {
+ unsigned long base;
+ struct mt_uart_register registers;
+};
+
+/* external API */
+void mt_uart_save(void);
+void mt_uart_restore(void);
+void mt_console_uart_cg(int on);
+uint32_t mt_console_uart_cg_status(void);
+
+#endif /* __UART_H__ */
diff --git a/plat/mediatek/mt8192/include/mcucfg.h b/plat/mediatek/mt8192/include/mcucfg.h
new file mode 100644
index 000000000..046cf7314
--- /dev/null
+++ b/plat/mediatek/mt8192/include/mcucfg.h
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MCUCFG_H
+#define MCUCFG_H
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#endif /* __ASSEMBLER__ */
+
+#include <platform_def.h>
+
+#define MCUCFG_REG(ofs) (uint32_t)(MCUCFG_BASE + (ofs))
+
+#define MP2_MISC_CONFIG_BOOT_ADDR_L(cpu) (MCUCFG_REG(0x2290) + ((cpu) * 8))
+#define MP2_MISC_CONFIG_BOOT_ADDR_H(cpu) (MCUCFG_REG(0x2294) + ((cpu) * 8))
+
+#define MP2_CPUCFG MCUCFG_REG(0x2208)
+
+#define MP2_CPU0_STANDBYWFE BIT(4)
+#define MP2_CPU1_STANDBYWFE BIT(5)
+
+#define MP0_CPUTOP_SPMC_CTL MCUCFG_REG(0x788)
+#define MP1_CPUTOP_SPMC_CTL MCUCFG_REG(0x78C)
+#define MP1_CPUTOP_SPMC_SRAM_CTL MCUCFG_REG(0x790)
+
+#define sw_spark_en BIT(0)
+#define sw_no_wait_for_q_channel BIT(1)
+#define sw_fsm_override BIT(2)
+#define sw_logic_pre1_pdb BIT(3)
+#define sw_logic_pre2_pdb BIT(4)
+#define sw_logic_pdb BIT(5)
+#define sw_iso BIT(6)
+#define sw_sram_sleepb (U(0x3F) << 7)
+#define sw_sram_isointb BIT(13)
+#define sw_clk_dis BIT(14)
+#define sw_ckiso BIT(15)
+#define sw_pd (U(0x3F) << 16)
+#define sw_hot_plug_reset BIT(22)
+#define sw_pwr_on_override_en BIT(23)
+#define sw_pwr_on BIT(24)
+#define sw_coq_dis BIT(25)
+#define logic_pdbo_all_off_ack BIT(26)
+#define logic_pdbo_all_on_ack BIT(27)
+#define logic_pre2_pdbo_all_on_ack BIT(28)
+#define logic_pre1_pdbo_all_on_ack BIT(29)
+
+
+#define CPUSYSx_CPUx_SPMC_CTL(cluster, cpu) \
+ (MCUCFG_REG(0x1c30) + cluster * 0x2000 + cpu * 4)
+
+#define CPUSYS0_CPU0_SPMC_CTL MCUCFG_REG(0x1c30)
+#define CPUSYS0_CPU1_SPMC_CTL MCUCFG_REG(0x1c34)
+#define CPUSYS0_CPU2_SPMC_CTL MCUCFG_REG(0x1c38)
+#define CPUSYS0_CPU3_SPMC_CTL MCUCFG_REG(0x1c3C)
+
+#define CPUSYS1_CPU0_SPMC_CTL MCUCFG_REG(0x3c30)
+#define CPUSYS1_CPU1_SPMC_CTL MCUCFG_REG(0x3c34)
+#define CPUSYS1_CPU2_SPMC_CTL MCUCFG_REG(0x3c38)
+#define CPUSYS1_CPU3_SPMC_CTL MCUCFG_REG(0x3c3C)
+
+#define cpu_sw_spark_en BIT(0)
+#define cpu_sw_no_wait_for_q_channel BIT(1)
+#define cpu_sw_fsm_override BIT(2)
+#define cpu_sw_logic_pre1_pdb BIT(3)
+#define cpu_sw_logic_pre2_pdb BIT(4)
+#define cpu_sw_logic_pdb BIT(5)
+#define cpu_sw_iso BIT(6)
+#define cpu_sw_sram_sleepb BIT(7)
+#define cpu_sw_sram_isointb BIT(8)
+#define cpu_sw_clk_dis BIT(9)
+#define cpu_sw_ckiso BIT(10)
+#define cpu_sw_pd (U(0x1F) << 11)
+#define cpu_sw_hot_plug_reset BIT(16)
+#define cpu_sw_powr_on_override_en BIT(17)
+#define cpu_sw_pwr_on BIT(18)
+#define cpu_spark2ldo_allswoff BIT(19)
+#define cpu_pdbo_all_on_ack BIT(20)
+#define cpu_pre2_pdbo_allon_ack BIT(21)
+#define cpu_pre1_pdbo_allon_ack BIT(22)
+
+/* CPC related registers */
+#define CPC_MCUSYS_CPC_OFF_THRES MCUCFG_REG(0xa714)
+#define CPC_MCUSYS_PWR_CTRL MCUCFG_REG(0xa804)
+#define CPC_MCUSYS_CPC_FLOW_CTRL_CFG MCUCFG_REG(0xa814)
+#define CPC_MCUSYS_LAST_CORE_REQ MCUCFG_REG(0xa818)
+#define CPC_MCUSYS_MP_LAST_CORE_RESP MCUCFG_REG(0xa81c)
+#define CPC_MCUSYS_LAST_CORE_RESP MCUCFG_REG(0xa824)
+#define CPC_MCUSYS_PWR_ON_MASK MCUCFG_REG(0xa828)
+#define CPC_MCUSYS_CPU_ON_SW_HINT_SET MCUCFG_REG(0xa8a8)
+#define CPC_MCUSYS_CPU_ON_SW_HINT_CLR MCUCFG_REG(0xa8ac)
+#define CPC_MCUSYS_CPC_DBG_SETTING MCUCFG_REG(0xab00)
+#define CPC_MCUSYS_CPC_KERNEL_TIME_L_BASE MCUCFG_REG(0xab04)
+#define CPC_MCUSYS_CPC_KERNEL_TIME_H_BASE MCUCFG_REG(0xab08)
+#define CPC_MCUSYS_CPC_SYSTEM_TIME_L_BASE MCUCFG_REG(0xab0c)
+#define CPC_MCUSYS_CPC_SYSTEM_TIME_H_BASE MCUCFG_REG(0xab10)
+#define CPC_MCUSYS_TRACE_SEL MCUCFG_REG(0xab14)
+#define CPC_MCUSYS_TRACE_DATA MCUCFG_REG(0xab20)
+#define CPC_MCUSYS_CLUSTER_COUNTER MCUCFG_REG(0xab70)
+#define CPC_MCUSYS_CLUSTER_COUNTER_CLR MCUCFG_REG(0xab74)
+
+#define SPARK2LDO MCUCFG_REG(0x2700)
+/* APB Module mcucfg */
+#define MP0_CA7_CACHE_CONFIG MCUCFG_REG(0x000)
+#define MP0_AXI_CONFIG MCUCFG_REG(0x02C)
+#define MP0_MISC_CONFIG0 MCUCFG_REG(0x030)
+#define MP0_MISC_CONFIG1 MCUCFG_REG(0x034)
+#define MP0_MISC_CONFIG2 MCUCFG_REG(0x038)
+#define MP0_MISC_CONFIG_BOOT_ADDR(cpu) (MP0_MISC_CONFIG2 + ((cpu) * 8))
+#define MP0_MISC_CONFIG3 MCUCFG_REG(0x03C)
+#define MP0_MISC_CONFIG9 MCUCFG_REG(0x054)
+#define MP0_CA7_MISC_CONFIG MCUCFG_REG(0x064)
+
+#define MP0_RW_RSVD0 MCUCFG_REG(0x06C)
+
+
+#define MP1_CA7_CACHE_CONFIG MCUCFG_REG(0x200)
+#define MP1_AXI_CONFIG MCUCFG_REG(0x22C)
+#define MP1_MISC_CONFIG0 MCUCFG_REG(0x230)
+#define MP1_MISC_CONFIG1 MCUCFG_REG(0x234)
+#define MP1_MISC_CONFIG2 MCUCFG_REG(0x238)
+#define MP1_MISC_CONFIG_BOOT_ADDR(cpu) (MP1_MISC_CONFIG2 + ((cpu) * 8))
+#define MP1_MISC_CONFIG3 MCUCFG_REG(0x23C)
+#define MP1_MISC_CONFIG9 MCUCFG_REG(0x254)
+#define MP1_CA7_MISC_CONFIG MCUCFG_REG(0x264)
+
+#define CCI_ADB400_DCM_CONFIG MCUCFG_REG(0x740)
+#define SYNC_DCM_CONFIG MCUCFG_REG(0x744)
+
+#define MP0_CLUSTER_CFG0 MCUCFG_REG(0xC8D0)
+
+#define MP0_SPMC MCUCFG_REG(0x788)
+#define MP1_SPMC MCUCFG_REG(0x78C)
+#define MP2_AXI_CONFIG MCUCFG_REG(0x220C)
+#define MP2_AXI_CONFIG_ACINACTM BIT(0)
+#define MP2_AXI_CONFIG_AINACTS BIT(4)
+
+#define MPx_AXI_CONFIG_ACINACTM BIT(4)
+#define MPx_AXI_CONFIG_AINACTS BIT(5)
+
+#define MPx_CA7_MISC_CONFIG_standbywfil2 BIT(28)
+
+#define MP0_CPU0_STANDBYWFE BIT(20)
+#define MP0_CPU1_STANDBYWFE BIT(21)
+#define MP0_CPU2_STANDBYWFE BIT(22)
+#define MP0_CPU3_STANDBYWFE BIT(23)
+
+#define MP1_CPU0_STANDBYWFE BIT(20)
+#define MP1_CPU1_STANDBYWFE BIT(21)
+#define MP1_CPU2_STANDBYWFE BIT(22)
+#define MP1_CPU3_STANDBYWFE BIT(23)
+
+#define CPUSYS0_SPARKVRETCNTRL MCUCFG_REG(0x1c00)
+#define CPUSYS0_SPARKEN MCUCFG_REG(0x1c04)
+#define CPUSYS0_AMUXSEL MCUCFG_REG(0x1c08)
+#define CPUSYS1_SPARKVRETCNTRL MCUCFG_REG(0x3c00)
+#define CPUSYS1_SPARKEN MCUCFG_REG(0x3c04)
+#define CPUSYS1_AMUXSEL MCUCFG_REG(0x3c08)
+
+#define MP2_PWR_RST_CTL MCUCFG_REG(0x2008)
+#define MP2_PTP3_CPUTOP_SPMC0 MCUCFG_REG(0x22A0)
+#define MP2_PTP3_CPUTOP_SPMC1 MCUCFG_REG(0x22A4)
+
+#define MP2_COQ MCUCFG_REG(0x22BC)
+#define MP2_COQ_SW_DIS BIT(0)
+
+#define MP2_CA15M_MON_SEL MCUCFG_REG(0x2400)
+#define MP2_CA15M_MON_L MCUCFG_REG(0x2404)
+
+#define CPUSYS2_CPU0_SPMC_CTL MCUCFG_REG(0x2430)
+#define CPUSYS2_CPU1_SPMC_CTL MCUCFG_REG(0x2438)
+#define CPUSYS2_CPU0_SPMC_STA MCUCFG_REG(0x2434)
+#define CPUSYS2_CPU1_SPMC_STA MCUCFG_REG(0x243C)
+
+#define MP0_CA7L_DBG_PWR_CTRL MCUCFG_REG(0x068)
+#define MP1_CA7L_DBG_PWR_CTRL MCUCFG_REG(0x268)
+#define BIG_DBG_PWR_CTRL MCUCFG_REG(0x75C)
+
+#define MP2_SW_RST_B BIT(0)
+#define MP2_TOPAON_APB_MASK BIT(1)
+
+#define B_SW_HOT_PLUG_RESET BIT(30)
+
+#define B_SW_PD_OFFSET 18U
+#define B_SW_PD (U(0x3f) << B_SW_PD_OFFSET)
+
+#define B_SW_SRAM_SLEEPB_OFFSET 12U
+#define B_SW_SRAM_SLEEPB (U(0x3f) << B_SW_SRAM_SLEEPB_OFFSET)
+
+#define B_SW_SRAM_ISOINTB BIT(9)
+#define B_SW_ISO BIT(8)
+#define B_SW_LOGIC_PDB BIT(7)
+#define B_SW_LOGIC_PRE2_PDB BIT(6)
+#define B_SW_LOGIC_PRE1_PDB BIT(5)
+#define B_SW_FSM_OVERRIDE BIT(4)
+#define B_SW_PWR_ON BIT(3)
+#define B_SW_PWR_ON_OVERRIDE_EN BIT(2)
+
+#define B_FSM_STATE_OUT_OFFSET (6U)
+#define B_FSM_STATE_OUT_MASK (U(0x1f) << B_FSM_STATE_OUT_OFFSET)
+#define B_SW_LOGIC_PDBO_ALL_OFF_ACK BIT(5)
+#define B_SW_LOGIC_PDBO_ALL_ON_ACK BIT(4)
+#define B_SW_LOGIC_PRE2_PDBO_ALL_ON_ACK BIT(3)
+#define B_SW_LOGIC_PRE1_PDBO_ALL_ON_ACK BIT(2)
+
+#define B_FSM_OFF (0U << B_FSM_STATE_OUT_OFFSET)
+#define B_FSM_ON (1U << B_FSM_STATE_OUT_OFFSET)
+#define B_FSM_RET (2U << B_FSM_STATE_OUT_OFFSET)
+
+#ifndef __ASSEMBLER__
+/* cpu boot mode */
+enum {
+ MP0_CPUCFG_64BIT_SHIFT = 12U,
+ MP1_CPUCFG_64BIT_SHIFT = 28U,
+ MP0_CPUCFG_64BIT = U(0xf) << MP0_CPUCFG_64BIT_SHIFT,
+ MP1_CPUCFG_64BIT = U(0xf) << MP1_CPUCFG_64BIT_SHIFT
+};
+
+enum {
+ MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT = 0U,
+ MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT = 4U,
+ MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT = 8U,
+ MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT = 12U,
+ MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT = 16U,
+
+ MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK =
+ U(0xf) << MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT,
+ MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK =
+ U(0xf) << MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT,
+ MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK =
+ U(0xf) << MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT,
+ MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK =
+ U(0xf) << MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT,
+ MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK =
+ U(0xf) << MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT
+};
+
+enum {
+ MP1_AINACTS_SHIFT = 4U,
+ MP1_AINACTS = 1U << MP1_AINACTS_SHIFT
+};
+
+enum {
+ MP1_SW_CG_GEN_SHIFT = 12U,
+ MP1_SW_CG_GEN = 1U << MP1_SW_CG_GEN_SHIFT
+};
+
+enum {
+ MP1_L2RSTDISABLE_SHIFT = 14U,
+ MP1_L2RSTDISABLE = 1U << MP1_L2RSTDISABLE_SHIFT
+};
+#endif /* __ASSEMBLER__ */
+
+#endif /* MCUCFG_H */
diff --git a/plat/mediatek/mt8192/include/mt_gic_v3.h b/plat/mediatek/mt8192/include/mt_gic_v3.h
new file mode 100644
index 000000000..c4ab44fa3
--- /dev/null
+++ b/plat/mediatek/mt8192/include/mt_gic_v3.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_GIC_V3_H
+#define MT_GIC_V3_H
+
+#include <drivers/arm/gicv3.h>
+#include <lib/mmio.h>
+
+void mt_gic_driver_init(void);
+void mt_gic_init(void);
+void mt_gic_set_pending(uint32_t irq);
+void mt_gic_distif_save(void);
+void mt_gic_distif_restore(void);
+void mt_gic_rdistif_init(void);
+void mt_gic_rdistif_save(void);
+void mt_gic_rdistif_restore(void);
+void mt_gic_rdistif_restore_all(void);
+void gic_sgi_save_all(void);
+void gic_sgi_restore_all(void);
+uint32_t mt_irq_get_pending(uint32_t irq);
+void mt_irq_set_pending(uint32_t irq);
+
+#endif /* MT_GIC_V3_H */
diff --git a/plat/mediatek/mt8192/include/plat_helpers.h b/plat/mediatek/mt8192/include/plat_helpers.h
new file mode 100644
index 000000000..9b550ee25
--- /dev/null
+++ b/plat/mediatek/mt8192/include/plat_helpers.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_HELPERS_H__
+#define __PLAT_HELPERS_H__
+
+unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr);
+
+#endif /* __PLAT_HELPERS_H__ */
diff --git a/plat/mediatek/mt8192/include/plat_macros.S b/plat/mediatek/mt8192/include/plat_macros.S
new file mode 100644
index 000000000..7d17e360a
--- /dev/null
+++ b/plat/mediatek/mt8192/include/plat_macros.S
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <platform_def.h>
+
+.section .rodata.gic_reg_name, "aS"
+gicc_regs:
+ .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+gicd_pend_reg:
+ .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \
+ " Offset:\t\t\tvalue\n"
+newline:
+ .asciz "\n"
+spacer:
+ .asciz ":\t\t0x"
+
+.section .rodata.cci_reg_name, "aS"
+cci_iface_regs:
+ .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
+
+ /* ---------------------------------------------
+ * The below macro prints out relevant GIC
+ * registers whenever an unhandled exception
+ * is taken in BL31.
+ * Clobbers: x0 - x10, x26, x27, sp
+ * ---------------------------------------------
+ */
+ .macro plat_crash_print_regs
+ /* To-do: GIC owner */
+ /* To-do: CCI owner */
+ .endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/mediatek/mt8192/include/plat_mt_cirq.h b/plat/mediatek/mt8192/include/plat_mt_cirq.h
new file mode 100644
index 000000000..bb8b4577f
--- /dev/null
+++ b/plat/mediatek/mt8192/include/plat_mt_cirq.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MT_CIRQ_H
+#define PLAT_MT_CIRQ_H
+
+#include <stdint.h>
+
+enum {
+ IRQ_MASK_HEADER = 0xF1F1F1F1,
+ IRQ_MASK_FOOTER = 0xF2F2F2F2
+};
+
+struct mtk_irq_mask {
+ uint32_t header; /* for error checking */
+ uint32_t mask0;
+ uint32_t mask1;
+ uint32_t mask2;
+ uint32_t mask3;
+ uint32_t mask4;
+ uint32_t mask5;
+ uint32_t mask6;
+ uint32_t mask7;
+ uint32_t mask8;
+ uint32_t mask9;
+ uint32_t mask10;
+ uint32_t mask11;
+ uint32_t mask12;
+ uint32_t footer; /* for error checking */
+};
+
+/*
+ * Define hardware register
+ */
+
+#define SYS_CIRQ_BASE U(0x10204000)
+#define CIRQ_REG_NUM U(14)
+#define CIRQ_IRQ_NUM U(439)
+#define CIRQ_SPI_START U(64)
+#define MD_WDT_IRQ_BIT_ID U(110)
+
+#define CIRQ_STA_BASE (SYS_CIRQ_BASE + U(0x000))
+#define CIRQ_ACK_BASE (SYS_CIRQ_BASE + U(0x080))
+#define CIRQ_MASK_BASE (SYS_CIRQ_BASE + U(0x100))
+#define CIRQ_MASK_SET_BASE (SYS_CIRQ_BASE + U(0x180))
+#define CIRQ_MASK_CLR_BASE (SYS_CIRQ_BASE + U(0x200))
+#define CIRQ_SENS_BASE (SYS_CIRQ_BASE + U(0x280))
+#define CIRQ_SENS_SET_BASE (SYS_CIRQ_BASE + U(0x300))
+#define CIRQ_SENS_CLR_BASE (SYS_CIRQ_BASE + U(0x380))
+#define CIRQ_POL_BASE (SYS_CIRQ_BASE + U(0x400))
+#define CIRQ_POL_SET_BASE (SYS_CIRQ_BASE + U(0x480))
+#define CIRQ_POL_CLR_BASE (SYS_CIRQ_BASE + U(0x500))
+#define CIRQ_CON (SYS_CIRQ_BASE + U(0x600))
+
+/*
+ * Register placement
+ */
+#define CIRQ_CON_EN_BITS U(0)
+#define CIRQ_CON_EDGE_ONLY_BITS U(1)
+#define CIRQ_CON_FLUSH_BITS U(2)
+#define CIRQ_CON_SW_RST_BITS U(20)
+#define CIRQ_CON_EVENT_BITS U(31)
+#define CIRQ_CON_BITS_MASK U(0x7)
+
+/*
+ * Register setting
+ */
+#define CIRQ_CON_EN U(0x1)
+#define CIRQ_CON_EDGE_ONLY U(0x1)
+#define CIRQ_CON_FLUSH U(0x1)
+#define CIRQ_SW_RESET U(0x1)
+
+/*
+ * Define constant
+ */
+#define CIRQ_CTRL_REG_NUM ((CIRQ_IRQ_NUM + 31U) / 32U)
+
+#define MT_CIRQ_POL_NEG U(0)
+#define MT_CIRQ_POL_POS U(1)
+
+#define IRQ_TO_CIRQ_NUM(irq) ((irq) - (32U + CIRQ_SPI_START))
+#define CIRQ_TO_IRQ_NUM(cirq) ((cirq) + (32U + CIRQ_SPI_START))
+
+/* GIC sensitive */
+#define SENS_EDGE U(0x2)
+#define SENS_LEVEL U(0x1)
+
+
+/*
+ * Define function prototypes.
+ */
+int mt_cirq_test(void);
+void mt_cirq_dump_reg(void);
+int mt_irq_mask_restore(struct mtk_irq_mask *mask);
+int mt_irq_mask_all(struct mtk_irq_mask *mask);
+void mt_cirq_clone_gic(void);
+void mt_cirq_enable(void);
+void mt_cirq_flush(void);
+void mt_cirq_disable(void);
+void mt_irq_unmask_for_sleep_ex(uint32_t irq);
+void set_wakeup_sources(uint32_t *list, uint32_t num_of_events);
+void mt_cirq_sw_reset(void);
+
+struct cirq_reg {
+ uint32_t reg_num;
+ uint32_t used;
+ uint32_t mask;
+ uint32_t pol;
+ uint32_t sen;
+ uint32_t pending;
+ uint32_t the_link;
+};
+
+struct cirq_events {
+ uint32_t num_reg;
+ uint32_t spi_start;
+ uint32_t num_of_events;
+ uint32_t *wakeup_events;
+ struct cirq_reg table[CIRQ_REG_NUM];
+ uint32_t dist_base;
+ uint32_t cirq_base;
+ uint32_t used_reg_head;
+};
+
+#endif /* PLAT_MT_CIRQ_H */
diff --git a/plat/mediatek/mt8192/include/plat_mtk_lpm.h b/plat/mediatek/mt8192/include/plat_mtk_lpm.h
new file mode 100644
index 000000000..8ba8b93a8
--- /dev/null
+++ b/plat/mediatek/mt8192/include/plat_mtk_lpm.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MTK_LPM_H
+#define PLAT_MTK_LPM_H
+
+#include <lib/psci/psci.h>
+#include <lib/utils_def.h>
+
+#define MT_IRQ_REMAIN_MAX U(8)
+#define MT_IRQ_REMAIN_CAT_LOG BIT(31)
+
+struct mt_irqremain {
+ unsigned int count;
+ unsigned int irqs[MT_IRQ_REMAIN_MAX];
+ unsigned int wakeupsrc_cat[MT_IRQ_REMAIN_MAX];
+ unsigned int wakeupsrc[MT_IRQ_REMAIN_MAX];
+};
+
+#define PLAT_RC_STATUS_READY BIT(0)
+#define PLAT_RC_STATUS_FEATURE_EN BIT(1)
+#define PLAT_RC_STATUS_UART_NONSLEEP BIT(31)
+
+struct mt_lpm_tz {
+ int (*pwr_prompt)(unsigned int cpu, const psci_power_state_t *state);
+ int (*pwr_reflect)(unsigned int cpu, const psci_power_state_t *state);
+
+ int (*pwr_cpu_on)(unsigned int cpu, const psci_power_state_t *state);
+ int (*pwr_cpu_dwn)(unsigned int cpu, const psci_power_state_t *state);
+
+ int (*pwr_cluster_on)(unsigned int cpu,
+ const psci_power_state_t *state);
+ int (*pwr_cluster_dwn)(unsigned int cpu,
+ const psci_power_state_t *state);
+
+ int (*pwr_mcusys_on)(unsigned int cpu, const psci_power_state_t *state);
+ int (*pwr_mcusys_on_finished)(unsigned int cpu,
+ const psci_power_state_t *state);
+ int (*pwr_mcusys_dwn)(unsigned int cpu,
+ const psci_power_state_t *state);
+};
+
+const struct mt_lpm_tz *mt_plat_cpu_pm_init(void);
+
+#endif /* PLAT_MTK_LPM_H */
diff --git a/plat/mediatek/mt8192/include/plat_pm.h b/plat/mediatek/mt8192/include/plat_pm.h
new file mode 100644
index 000000000..a2881cef6
--- /dev/null
+++ b/plat/mediatek/mt8192/include/plat_pm.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_PM_H
+#define PLAT_PM_H
+
+#include <lib/utils_def.h>
+
+#define MT_PLAT_PWR_STATE_CPU U(1)
+#define MT_PLAT_PWR_STATE_CLUSTER U(2)
+#define MT_PLAT_PWR_STATE_MCUSYS U(3)
+#define MT_PLAT_PWR_STATE_SUSPEND2IDLE U(8)
+#define MT_PLAT_PWR_STATE_SYSTEM_SUSPEND U(9)
+
+#define MTK_LOCAL_STATE_RUN U(0)
+#define MTK_LOCAL_STATE_RET U(1)
+#define MTK_LOCAL_STATE_OFF U(2)
+
+#define MTK_AFFLVL_CPU U(0)
+#define MTK_AFFLVL_CLUSTER U(1)
+#define MTK_AFFLVL_MCUSYS U(2)
+#define MTK_AFFLVL_SYSTEM U(3)
+
+#define IS_CLUSTER_OFF_STATE(s) \
+ is_local_state_off(s->pwr_domain_state[MTK_AFFLVL_CLUSTER])
+#define IS_MCUSYS_OFF_STATE(s) \
+ is_local_state_off(s->pwr_domain_state[MTK_AFFLVL_MCUSYS])
+#define IS_SYSTEM_SUSPEND_STATE(s) \
+ is_local_state_off(s->pwr_domain_state[MTK_AFFLVL_SYSTEM])
+
+#define IS_PLAT_SUSPEND_ID(stateid)\
+ ((stateid == MT_PLAT_PWR_STATE_SUSPEND2IDLE) \
+ || (stateid == MT_PLAT_PWR_STATE_SYSTEM_SUSPEND))
+
+#endif /* PLAT_PM_H */
diff --git a/plat/mediatek/mt8192/include/plat_private.h b/plat/mediatek/mt8192/include/plat_private.h
new file mode 100644
index 000000000..42ca415f9
--- /dev/null
+++ b/plat/mediatek/mt8192/include/plat_private.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_PRIVATE_H
+#define PLAT_PRIVATE_H
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+void plat_configure_mmu_el3(uintptr_t total_base,
+ uintptr_t total_size,
+ uintptr_t ro_start,
+ uintptr_t ro_limit);
+
+#endif /* PLAT_PRIVATE_H */
diff --git a/plat/mediatek/mt8192/include/plat_sip_calls.h b/plat/mediatek/mt8192/include/plat_sip_calls.h
new file mode 100644
index 000000000..0e423225c
--- /dev/null
+++ b/plat/mediatek/mt8192/include/plat_sip_calls.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_SIP_CALLS_H
+#define PLAT_SIP_CALLS_H
+
+/*******************************************************************************
+ * Plat SiP function constants
+ ******************************************************************************/
+#define MTK_PLAT_SIP_NUM_CALLS 0
+
+#endif /* PLAT_SIP_CALLS_H */
diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h
new file mode 100644
index 000000000..3e4441424
--- /dev/null
+++ b/plat/mediatek/mt8192/include/platform_def.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+
+#define PLAT_PRIMARY_CPU 0x0
+
+#define MT_GIC_BASE 0x0c000000
+#define PLAT_MT_CCI_BASE 0x0c500000
+#define MCUCFG_BASE 0x0c530000
+
+#define IO_PHYS 0x10000000
+
+/* Aggregate of all devices for MMU mapping */
+#define MTK_DEV_RNG0_BASE IO_PHYS
+#define MTK_DEV_RNG0_SIZE 0x10000000
+#define MTK_DEV_RNG1_BASE (IO_PHYS + 0x10000000)
+#define MTK_DEV_RNG1_SIZE 0x10000000
+#define MTK_DEV_RNG2_BASE 0x0c000000
+#define MTK_DEV_RNG2_SIZE 0x600000
+#define MTK_MCDI_SRAM_BASE 0x11B000
+#define MTK_MCDI_SRAM_MAP_SIZE 0x1000
+
+#define INFRACFG_AO_BASE (IO_PHYS + 0x00001000)
+#define GPIO_BASE (IO_PHYS + 0x00005000)
+#define SPM_BASE (IO_PHYS + 0x00006000)
+#define PMIC_WRAP_BASE (IO_PHYS + 0x00026000)
+#define EMI_BASE (IO_PHYS + 0x00219000)
+#define EMI_MPU_BASE (IO_PHYS + 0x00226000)
+#define IOCFG_RM_BASE (IO_PHYS + 0x01C20000)
+#define IOCFG_BM_BASE (IO_PHYS + 0x01D10000)
+#define IOCFG_BL_BASE (IO_PHYS + 0x01D30000)
+#define IOCFG_BR_BASE (IO_PHYS + 0x01D40000)
+#define IOCFG_LM_BASE (IO_PHYS + 0x01E20000)
+#define IOCFG_LB_BASE (IO_PHYS + 0x01E70000)
+#define IOCFG_RT_BASE (IO_PHYS + 0x01EA0000)
+#define IOCFG_LT_BASE (IO_PHYS + 0x01F20000)
+#define IOCFG_TL_BASE (IO_PHYS + 0x01F30000)
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define UART0_BASE (IO_PHYS + 0x01002000)
+#define UART1_BASE (IO_PHYS + 0x01003000)
+
+#define UART_BAUDRATE 115200
+
+/*******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
+#define SYS_COUNTER_FREQ_IN_TICKS 13000000
+#define SYS_COUNTER_FREQ_IN_MHZ 13
+
+/*******************************************************************************
+ * GIC-400 & interrupt handling related constants
+ ******************************************************************************/
+
+/* Base MTK_platform compatible GIC memory map */
+#define BASE_GICD_BASE MT_GIC_BASE
+#define MT_GIC_RDIST_BASE (MT_GIC_BASE + 0x40000)
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+#define PLATFORM_STACK_SIZE 0x800
+
+#define PLAT_MAX_PWR_LVL U(3)
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(9)
+
+#define PLATFORM_SYSTEM_COUNT U(1)
+#define PLATFORM_MCUSYS_COUNT U(1)
+#define PLATFORM_CLUSTER_COUNT U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT U(8)
+#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER U(8)
+
+#define SOC_CHIP_ID U(0x8192)
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define TZRAM_BASE 0x54600000
+#define TZRAM_SIZE 0x00030000
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL31 at the top of the Trusted SRAM (just below the shared memory, if
+ * present). BL31_BASE is calculated using the current BL31 debug size plus a
+ * little space for growth.
+ */
+#define BL31_BASE (TZRAM_BASE + 0x1000)
+#define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#define MAX_XLAT_TABLES 16
+#define MAX_MMAP_REGIONS 16
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT 6
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt8192/plat_mt_cirq.c b/plat/mediatek/mt8192/plat_mt_cirq.c
new file mode 100644
index 000000000..9002b7ee1
--- /dev/null
+++ b/plat/mediatek/mt8192/plat_mt_cirq.c
@@ -0,0 +1,552 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/gic_common.h>
+#include <lib/mmio.h>
+
+#include <mt_gic_v3.h>
+#include <plat_mt_cirq.h>
+#include <platform_def.h>
+
+static struct cirq_events cirq_all_events = {
+ .spi_start = CIRQ_SPI_START,
+};
+static uint32_t already_cloned;
+/*
+ * mt_irq_mask_restore: restore all interrupts
+ * @mask: pointer to struct mtk_irq_mask for storing the original mask value.
+ * Return 0 for success; return negative values for failure.
+ * (This is ONLY used for the idle current measurement by the factory mode.)
+ */
+int mt_irq_mask_restore(struct mtk_irq_mask *mask)
+{
+ if (mask == NULL) {
+ return -1;
+ }
+ if (mask->header != IRQ_MASK_HEADER) {
+ return -1;
+ }
+ if (mask->footer != IRQ_MASK_FOOTER) {
+ return -1;
+ }
+
+ mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x4),
+ mask->mask1);
+ mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x8),
+ mask->mask2);
+ mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0xc),
+ mask->mask3);
+ mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x10),
+ mask->mask4);
+ mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x14),
+ mask->mask5);
+ mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x18),
+ mask->mask6);
+ mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x1c),
+ mask->mask7);
+ mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x20),
+ mask->mask8);
+ mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x24),
+ mask->mask9);
+ mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x28),
+ mask->mask10);
+ mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x2c),
+ mask->mask11);
+ mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x30),
+ mask->mask12);
+ /* make sure dist changes happen */
+ dsb();
+
+ return 0;
+}
+
+/*
+ * mt_irq_mask_all: disable all interrupts
+ * @mask: pointer to struct mtk_irq_mask for storing the original mask value.
+ * Return 0 for success; return negative values for failure.
+ * (This is ONLY used for the idle current measurement by the factory mode.)
+ */
+int mt_irq_mask_all(struct mtk_irq_mask *mask)
+{
+ if (mask != NULL) {
+ /* for SPI */
+ mask->mask1 = mmio_read_32((BASE_GICD_BASE +
+ GICD_ISENABLER + 0x4));
+ mask->mask2 = mmio_read_32((BASE_GICD_BASE +
+ GICD_ISENABLER + 0x8));
+ mask->mask3 = mmio_read_32((BASE_GICD_BASE +
+ GICD_ISENABLER + 0xc));
+ mask->mask4 = mmio_read_32((BASE_GICD_BASE +
+ GICD_ISENABLER + 0x10));
+ mask->mask5 = mmio_read_32((BASE_GICD_BASE +
+ GICD_ISENABLER + 0x14));
+ mask->mask6 = mmio_read_32((BASE_GICD_BASE +
+ GICD_ISENABLER + 0x18));
+ mask->mask7 = mmio_read_32((BASE_GICD_BASE +
+ GICD_ISENABLER + 0x1c));
+ mask->mask8 = mmio_read_32((BASE_GICD_BASE +
+ GICD_ISENABLER + 0x20));
+ mask->mask9 = mmio_read_32((BASE_GICD_BASE +
+ GICD_ISENABLER + 0x24));
+ mask->mask10 = mmio_read_32((BASE_GICD_BASE +
+ GICD_ISENABLER + 0x28));
+ mask->mask11 = mmio_read_32((BASE_GICD_BASE +
+ GICD_ISENABLER + 0x2c));
+ mask->mask12 = mmio_read_32((BASE_GICD_BASE +
+ GICD_ISENABLER + 0x30));
+
+ /* for SPI */
+ mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x4),
+ 0xFFFFFFFF);
+ mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x8),
+ 0xFFFFFFFF);
+ mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0xC),
+ 0xFFFFFFFF);
+ mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x10),
+ 0xFFFFFFFF);
+ mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x14),
+ 0xFFFFFFFF);
+ mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x18),
+ 0xFFFFFFFF);
+ mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x1C),
+ 0xFFFFFFFF);
+ mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x20),
+ 0xFFFFFFFF);
+ mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x24),
+ 0xFFFFFFFF);
+ mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x28),
+ 0xFFFFFFFF);
+ mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x2c),
+ 0xFFFFFFFF);
+ mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x30),
+ 0xFFFFFFFF);
+ /* make sure distributor changes happen */
+ dsb();
+
+ mask->header = IRQ_MASK_HEADER;
+ mask->footer = IRQ_MASK_FOOTER;
+
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+static uint32_t mt_irq_get_pol(uint32_t irq)
+{
+#ifdef CIRQ_WITH_POLARITY
+ uint32_t reg;
+ uint32_t base = INT_POL_CTL0;
+
+ if (irq < 32U) {
+ return 0;
+ }
+
+ reg = ((irq - 32U) / 32U);
+
+ return mmio_read_32(base + reg * 4U);
+#else
+ return 0;
+#endif
+}
+
+unsigned int mt_irq_get_sens(unsigned int irq)
+{
+ unsigned int config;
+
+ /*
+ * 2'b10 edge
+ * 2'b01 level
+ */
+ config = mmio_read_32(MT_GIC_BASE + GICD_ICFGR + (irq / 16U) * 4U);
+ config = (config >> (irq % 16U) * 2U) & 0x3;
+
+ return config;
+}
+
+static void collect_all_wakeup_events(void)
+{
+ unsigned int i;
+ uint32_t gic_irq;
+ uint32_t cirq;
+ uint32_t cirq_reg;
+ uint32_t cirq_offset;
+ uint32_t mask;
+ uint32_t pol_mask;
+ uint32_t irq_offset;
+ uint32_t irq_mask;
+
+ if ((cirq_all_events.wakeup_events == NULL) ||
+ cirq_all_events.num_of_events == 0U) {
+ return;
+ }
+
+ for (i = 0U; i < cirq_all_events.num_of_events; i++) {
+ if (cirq_all_events.wakeup_events[i] > 0U) {
+ gic_irq = cirq_all_events.wakeup_events[i];
+ cirq = gic_irq - cirq_all_events.spi_start - 32U;
+ cirq_reg = cirq / 32U;
+ cirq_offset = cirq % 32U;
+ mask = 0x1 << cirq_offset;
+ irq_offset = gic_irq % 32U;
+ irq_mask = 0x1 << irq_offset;
+ /*
+ * CIRQ default masks all
+ */
+ cirq_all_events.table[cirq_reg].mask |= mask;
+ /*
+ * CIRQ default pol is low
+ */
+ pol_mask = mt_irq_get_pol(
+ cirq_all_events.wakeup_events[i])
+ & irq_mask;
+ /*
+ * 0 means rising
+ */
+ if (pol_mask == 0U) {
+ cirq_all_events.table[cirq_reg].pol |= mask;
+ }
+ /*
+ * CIRQ could monitor edge/level trigger
+ * cirq register (0: edge, 1: level)
+ */
+ if (mt_irq_get_sens(cirq_all_events.wakeup_events[i])
+ == SENS_EDGE) {
+ cirq_all_events.table[cirq_reg].sen |= mask;
+ }
+
+ cirq_all_events.table[cirq_reg].used = 1U;
+ cirq_all_events.table[cirq_reg].reg_num = cirq_reg;
+ }
+ }
+}
+
+/*
+ * mt_cirq_set_pol: Set the polarity for the specified SYS_CIRQ number.
+ * @cirq_num: the SYS_CIRQ number to set
+ * @pol: polarity to set
+ * @return:
+ * 0: set pol success
+ * -1: cirq num is out of range
+ */
+#ifdef CIRQ_WITH_POLARITY
+static int mt_cirq_set_pol(uint32_t cirq_num, uint32_t pol)
+{
+ uint32_t base;
+ uint32_t bit = 1U << (cirq_num % 32U);
+
+ if (cirq_num >= CIRQ_IRQ_NUM) {
+ return -1;
+ }
+
+ if (pol == MT_CIRQ_POL_NEG) {
+ base = (cirq_num / 32U) * 4U + CIRQ_POL_CLR_BASE;
+ } else if (pol == MT_CIRQ_POL_POS) {
+ base = (cirq_num / 32U) * 4U + CIRQ_POL_SET_BASE;
+ } else {
+ return -1;
+ }
+
+ mmio_write_32(base, bit);
+ return 0;
+}
+#endif
+
+/*
+ * mt_cirq_mask: Mask the specified SYS_CIRQ.
+ * @cirq_num: the SYS_CIRQ number to mask
+ * @return:
+ * 0: mask success
+ * -1: cirq num is out of range
+ */
+static int mt_cirq_mask(uint32_t cirq_num)
+{
+ uint32_t bit = 1U << (cirq_num % 32U);
+
+ if (cirq_num >= CIRQ_IRQ_NUM) {
+ return -1;
+ }
+
+ mmio_write_32((cirq_num / 32U) * 4U + CIRQ_MASK_SET_BASE, bit);
+
+ return 0;
+}
+
+/*
+ * mt_cirq_unmask: Unmask the specified SYS_CIRQ.
+ * @cirq_num: the SYS_CIRQ number to unmask
+ * @return:
+ * 0: umask success
+ * -1: cirq num is out of range
+ */
+static int mt_cirq_unmask(uint32_t cirq_num)
+{
+ uint32_t bit = 1U << (cirq_num % 32U);
+
+ if (cirq_num >= CIRQ_IRQ_NUM) {
+ return -1;
+ }
+
+ mmio_write_32((cirq_num / 32U) * 4U + CIRQ_MASK_CLR_BASE, bit);
+
+ return 0;
+}
+
+uint32_t mt_irq_get_en(uint32_t irq)
+{
+ uint32_t addr, st, val;
+
+ addr = BASE_GICD_BASE + GICD_ISENABLER + (irq / 32U) * 4U;
+ st = mmio_read_32(addr);
+
+ val = (st >> (irq % 32U)) & 1U;
+
+ return val;
+}
+
+static void __cirq_fast_clone(void)
+{
+ struct cirq_reg *reg;
+ unsigned int i;
+
+ for (i = 0U; i < CIRQ_REG_NUM ; ++i) {
+ uint32_t cirq_bit;
+
+ reg = &cirq_all_events.table[i];
+
+ if (reg->used == 0U) {
+ continue;
+ }
+
+ mmio_write_32(CIRQ_SENS_CLR_BASE + (reg->reg_num * 4U),
+ reg->sen);
+
+ for (cirq_bit = 0U; cirq_bit < 32U; ++cirq_bit) {
+ uint32_t val, cirq_id;
+ uint32_t gic_id;
+#ifdef CIRQ_WITH_POLARITY
+ uint32_t gic_bit, pol;
+#endif
+ uint32_t en;
+
+ val = ((1U << cirq_bit) & reg->mask);
+
+ if (val == 0U) {
+ continue;
+ }
+
+ cirq_id = (reg->reg_num << 5U) + cirq_bit;
+ gic_id = CIRQ_TO_IRQ_NUM(cirq_id);
+#ifdef CIRQ_WITH_POLARITY
+ gic_bit = (0x1U << ((gic_id - 32U) % 32U));
+ pol = mt_irq_get_pol(gic_id) & gic_bit;
+ if (pol != 0U) {
+ mt_cirq_set_pol(cirq_id, MT_CIRQ_POL_NEG);
+ } else {
+ mt_cirq_set_pol(cirq_id, MT_CIRQ_POL_POS);
+ }
+#endif
+ en = mt_irq_get_en(gic_id);
+ if (en == 1U) {
+ mt_cirq_unmask(cirq_id);
+ } else {
+ mt_cirq_mask(cirq_id);
+ }
+ }
+ }
+}
+
+static void cirq_fast_clone(void)
+{
+ if (already_cloned == 0U) {
+ collect_all_wakeup_events();
+ already_cloned = 1U;
+ }
+ __cirq_fast_clone();
+}
+
+void set_wakeup_sources(uint32_t *list, uint32_t num_of_events)
+{
+ cirq_all_events.num_of_events = num_of_events;
+ cirq_all_events.wakeup_events = list;
+}
+/*
+ * mt_cirq_clone_gic: Copy the setting from GIC to SYS_CIRQ
+ */
+void mt_cirq_clone_gic(void)
+{
+ cirq_fast_clone();
+}
+
+uint32_t mt_irq_get_pending_vec(uint32_t start_irq)
+{
+ uint32_t base = 0U;
+ uint32_t pending_vec = 0U;
+ uint32_t reg = start_irq / 32U;
+ uint32_t LSB_num, MSB_num;
+ uint32_t LSB_vec, MSB_vec;
+
+ base = BASE_GICD_BASE;
+
+ /* if start_irq is not aligned 32, do some assembling */
+ MSB_num = start_irq % 32U;
+ if (MSB_num != 0U) {
+ LSB_num = 32U - MSB_num;
+ LSB_vec = mmio_read_32(base + GICD_ISPENDR +
+ reg * 4U) >> MSB_num;
+ MSB_vec = mmio_read_32(base + GICD_ISPENDR +
+ (reg + 1U) * 4U) << LSB_num;
+ pending_vec = MSB_vec | LSB_vec;
+ } else {
+ pending_vec = mmio_read_32(base + GICD_ISPENDR + reg * 4);
+ }
+
+ return pending_vec;
+}
+
+static int mt_cirq_get_mask_vec(unsigned int i)
+{
+ return mmio_read_32((i * 4U) + CIRQ_MASK_BASE);
+}
+
+/*
+ * mt_cirq_ack_all: Ack all the interrupt on SYS_CIRQ
+ */
+void mt_cirq_ack_all(void)
+{
+ uint32_t ack_vec, pend_vec, mask_vec;
+ unsigned int i;
+
+ for (i = 0; i < CIRQ_CTRL_REG_NUM; i++) {
+ /*
+ * if a irq is pending & not masked, don't ack it
+ * , since cirq start irq might not be 32 aligned with gic,
+ * need an exotic API to get proper vector of pending irq
+ */
+ pend_vec = mt_irq_get_pending_vec(CIRQ_SPI_START
+ + (i + 1U) * 32U);
+ mask_vec = mt_cirq_get_mask_vec(i);
+ /* those should be acked are: "not (pending & not masked)",
+ */
+ ack_vec = (~pend_vec) | mask_vec;
+ mmio_write_32(CIRQ_ACK_BASE + (i * 4U), ack_vec);
+ }
+
+ /*
+ * make sure all cirq setting take effect
+ * before doing other things
+ */
+ dsb();
+}
+/*
+ * mt_cirq_enable: Enable SYS_CIRQ
+ */
+void mt_cirq_enable(void)
+{
+ uint32_t st;
+
+ /* level only */
+ mt_cirq_ack_all();
+
+ st = mmio_read_32(CIRQ_CON);
+ /*
+ * CIRQ could monitor edge/level trigger
+ */
+ st |= (CIRQ_CON_EN << CIRQ_CON_EN_BITS);
+
+ mmio_write_32(CIRQ_CON, (st & CIRQ_CON_BITS_MASK));
+}
+
+/*
+ * mt_cirq_disable: Disable SYS_CIRQ
+ */
+void mt_cirq_disable(void)
+{
+ uint32_t st;
+
+ st = mmio_read_32(CIRQ_CON);
+ st &= ~(CIRQ_CON_EN << CIRQ_CON_EN_BITS);
+ mmio_write_32(CIRQ_CON, (st & CIRQ_CON_BITS_MASK));
+}
+
+void mt_irq_unmask_for_sleep_ex(uint32_t irq)
+{
+ uint32_t mask;
+
+ mask = 1U << (irq % 32U);
+
+ mmio_write_32(BASE_GICD_BASE + GICD_ISENABLER +
+ ((irq / 32U) * 4U), mask);
+}
+
+void mt_cirq_mask_all(void)
+{
+ unsigned int i;
+
+ for (i = 0U; i < CIRQ_CTRL_REG_NUM; i++) {
+ mmio_write_32(CIRQ_MASK_SET_BASE + (i * 4U), 0xFFFFFFFF);
+ }
+ dsb();
+}
+
+static void cirq_fast_sw_flush(void)
+{
+ struct cirq_reg *reg;
+ unsigned int i;
+
+ for (i = 0U; i < CIRQ_REG_NUM ; ++i) {
+ uint32_t cirq_bit;
+
+ reg = &cirq_all_events.table[i];
+
+ if (reg->used == 0U) {
+ continue;
+ }
+
+ reg->pending = mmio_read_32(CIRQ_STA_BASE +
+ (reg->reg_num << 2U));
+ reg->pending &= reg->mask;
+
+ for (cirq_bit = 0U; cirq_bit < 32U; ++cirq_bit) {
+ uint32_t val, cirq_id;
+
+ val = (1U << cirq_bit) & reg->pending;
+ if (val == 0U) {
+ continue;
+ }
+
+ cirq_id = (reg->reg_num << 5U) + cirq_bit;
+ mt_irq_set_pending(CIRQ_TO_IRQ_NUM(cirq_id));
+ if (CIRQ_TO_IRQ_NUM(cirq_id) == MD_WDT_IRQ_BIT_ID) {
+ INFO("Set MD_WDT_IRQ pending in %s\n",
+ __func__);
+ }
+ }
+ }
+}
+
+/*
+ * mt_cirq_disable: Flush interrupt from SYS_CIRQ to GIC
+ */
+void mt_cirq_flush(void)
+{
+ cirq_fast_sw_flush();
+ mt_cirq_mask_all();
+ mt_cirq_ack_all();
+}
+
+void mt_cirq_sw_reset(void)
+{
+#ifdef CIRQ_NEED_SW_RESET
+ uint32_t st;
+
+ st = mmio_read_32(CIRQ_CON);
+ st |= (CIRQ_SW_RESET << CIRQ_CON_SW_RST_BITS);
+ mmio_write_32(CIRQ_CON, st);
+#endif
+}
diff --git a/plat/mediatek/mt8192/plat_mt_gic.c b/plat/mediatek/mt8192/plat_mt_gic.c
new file mode 100644
index 000000000..ae8d697a5
--- /dev/null
+++ b/plat/mediatek/mt8192/plat_mt_gic.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "../drivers/arm/gic/v3/gicv3_private.h"
+#include <bl31/interrupt_mgmt.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+
+#include <mt_gic_v3.h>
+#include <mtk_plat_common.h>
+#include <plat/common/platform.h>
+#include <plat_private.h>
+#include <platform_def.h>
+
+#define SGI_MASK 0xffff
+
+uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+static uint32_t rdist_has_saved[PLATFORM_CORE_COUNT];
+
+/* we save and restore the GICv3 context on system suspend */
+gicv3_dist_ctx_t dist_ctx;
+
+static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr)
+{
+ return plat_core_pos_by_mpidr(mpidr);
+}
+
+gicv3_driver_data_t mt_gicv3_data = {
+ .gicd_base = MT_GIC_BASE,
+ .gicr_base = MT_GIC_RDIST_BASE,
+ .rdistif_num = PLATFORM_CORE_COUNT,
+ .rdistif_base_addrs = rdistif_base_addrs,
+ .mpidr_to_core_pos = mt_mpidr_to_core_pos,
+};
+
+struct gic_chip_data {
+ /* All cores share the same configuration */
+ unsigned int saved_group;
+ unsigned int saved_enable;
+ unsigned int saved_conf0;
+ unsigned int saved_conf1;
+ unsigned int saved_grpmod;
+ /* Per-core sgi */
+ unsigned int saved_sgi[PLATFORM_CORE_COUNT];
+};
+
+static struct gic_chip_data gic_data;
+
+void mt_gic_driver_init(void)
+{
+ gicv3_driver_init(&mt_gicv3_data);
+}
+
+void mt_gic_set_pending(uint32_t irq)
+{
+ gicv3_set_interrupt_pending(irq, plat_my_core_pos());
+}
+
+void mt_gic_distif_save(void)
+{
+ gicv3_distif_save(&dist_ctx);
+}
+
+void mt_gic_distif_restore(void)
+{
+ gicv3_distif_init_restore(&dist_ctx);
+}
+
+void mt_gic_rdistif_init(void)
+{
+ unsigned int proc_num;
+ unsigned int index;
+ uintptr_t gicr_base;
+
+ proc_num = plat_my_core_pos();
+ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+
+ /* set all SGI/PPI as non-secure GROUP1 by default */
+ mmio_write_32(gicr_base + GICR_IGROUPR0, ~0U);
+ mmio_write_32(gicr_base + GICR_IGRPMODR0, 0x0);
+
+ /* setup the default PPI/SGI priorities */
+ for (index = 0; index < TOTAL_PCPU_INTR_NUM; index += 4U)
+ gicr_write_ipriorityr(gicr_base, index,
+ GICD_IPRIORITYR_DEF_VAL);
+}
+
+void mt_gic_rdistif_save(void)
+{
+ unsigned int proc_num;
+ uintptr_t gicr_base;
+
+ proc_num = plat_my_core_pos();
+ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+
+ gic_data.saved_group = mmio_read_32(gicr_base + GICR_IGROUPR0);
+ gic_data.saved_enable = mmio_read_32(gicr_base + GICR_ISENABLER0);
+ gic_data.saved_conf0 = mmio_read_32(gicr_base + GICR_ICFGR0);
+ gic_data.saved_conf1 = mmio_read_32(gicr_base + GICR_ICFGR1);
+ gic_data.saved_grpmod = mmio_read_32(gicr_base + GICR_IGRPMODR0);
+
+ rdist_has_saved[proc_num] = 1;
+}
+
+void mt_gic_rdistif_restore(void)
+{
+ unsigned int proc_num;
+ uintptr_t gicr_base;
+
+ proc_num = plat_my_core_pos();
+ if (rdist_has_saved[proc_num] == 1) {
+ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+ mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group);
+ mmio_write_32(gicr_base + GICR_ISENABLER0,
+ gic_data.saved_enable);
+ mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0);
+ mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1);
+ mmio_write_32(gicr_base + GICR_IGRPMODR0,
+ gic_data.saved_grpmod);
+ }
+}
+
+void mt_gic_rdistif_restore_all(void)
+{
+ unsigned int proc_num;
+ uintptr_t gicr_base;
+
+ for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) {
+ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+ mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group);
+ mmio_write_32(gicr_base + GICR_ISENABLER0,
+ gic_data.saved_enable);
+ mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0);
+ mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1);
+ mmio_write_32(gicr_base + GICR_IGRPMODR0,
+ gic_data.saved_grpmod);
+ }
+}
+
+void gic_sgi_save_all(void)
+{
+ unsigned int proc_num;
+ uintptr_t gicr_base;
+
+ for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) {
+ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+ gic_data.saved_sgi[proc_num] =
+ mmio_read_32(gicr_base + GICR_ISPENDR0) & SGI_MASK;
+ }
+}
+
+void gic_sgi_restore_all(void)
+{
+ unsigned int proc_num;
+ uintptr_t gicr_base;
+
+ for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) {
+ gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+ mmio_write_32(gicr_base + GICR_ICPENDR0, SGI_MASK);
+ mmio_write_32(gicr_base + GICR_ISPENDR0,
+ gic_data.saved_sgi[proc_num] & SGI_MASK);
+ }
+}
+
+void mt_gic_init(void)
+{
+ gicv3_distif_init();
+ gicv3_rdistif_init(plat_my_core_pos());
+ gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+uint32_t mt_irq_get_pending(uint32_t irq)
+{
+ uint32_t val;
+
+ val = mmio_read_32(BASE_GICD_BASE + GICD_ISPENDR +
+ irq / 32 * 4);
+ val = (val >> (irq % 32)) & 1U;
+ return val;
+}
+
+
+void mt_irq_set_pending(uint32_t irq)
+{
+ uint32_t bit = 1U << (irq % 32);
+
+ mmio_write_32(BASE_GICD_BASE + GICD_ISPENDR +
+ irq / 32 * 4, bit);
+}
diff --git a/plat/mediatek/mt8192/plat_pm.c b/plat/mediatek/mt8192/plat_pm.c
new file mode 100644
index 000000000..6a74c02dd
--- /dev/null
+++ b/plat/mediatek/mt8192/plat_pm.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* common headers */
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/gpio.h>
+#include <lib/psci/psci.h>
+
+/* platform specific headers */
+#include <mt_gic_v3.h>
+#include <mtk_ptp3_common.h>
+#include <mtspmc.h>
+#include <plat/common/platform.h>
+#include <plat_mtk_lpm.h>
+#include <plat_params.h>
+#include <plat_pm.h>
+#include <pmic.h>
+#include <rtc.h>
+
+/*
+ * Cluster state request:
+ * [0] : The CPU requires cluster power down
+ * [1] : The CPU requires cluster power on
+ */
+#define coordinate_cluster(onoff) write_clusterpwrdn_el1(onoff)
+#define coordinate_cluster_pwron() coordinate_cluster(1)
+#define coordinate_cluster_pwroff() coordinate_cluster(0)
+
+/* platform secure entry point */
+static uintptr_t secure_entrypoint;
+/* per-CPU power state */
+static unsigned int plat_power_state[PLATFORM_CORE_COUNT];
+
+/* platform CPU power domain - ops */
+static const struct mt_lpm_tz *plat_mt_pm;
+
+#define plat_mt_pm_invoke(_name, _cpu, _state) ({ \
+ int ret = -1; \
+ if (plat_mt_pm != NULL && plat_mt_pm->_name != NULL) { \
+ ret = plat_mt_pm->_name(_cpu, _state); \
+ } \
+ ret; })
+
+#define plat_mt_pm_invoke_no_check(_name, _cpu, _state) ({ \
+ if (plat_mt_pm != NULL && plat_mt_pm->_name != NULL) { \
+ (void) plat_mt_pm->_name(_cpu, _state); \
+ } \
+ })
+
+/*
+ * Common MTK_platform operations to power on/off a
+ * CPU in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request.
+ */
+
+static void plat_cpu_pwrdwn_common(unsigned int cpu,
+ const psci_power_state_t *state, unsigned int req_pstate)
+{
+ assert(cpu == plat_my_core_pos());
+
+ plat_mt_pm_invoke_no_check(pwr_cpu_dwn, cpu, state);
+
+ if ((psci_get_pstate_pwrlvl(req_pstate) >= MTK_AFFLVL_CLUSTER) ||
+ (req_pstate == 0U)) { /* hotplug off */
+ coordinate_cluster_pwroff();
+ }
+
+ /* Prevent interrupts from spuriously waking up this CPU */
+ mt_gic_rdistif_save();
+ gicv3_cpuif_disable(cpu);
+ gicv3_rdistif_off(cpu);
+ /* PTP3 config */
+ ptp3_deinit(cpu);
+}
+
+static void plat_cpu_pwron_common(unsigned int cpu,
+ const psci_power_state_t *state, unsigned int req_pstate)
+{
+ assert(cpu == plat_my_core_pos());
+
+ plat_mt_pm_invoke_no_check(pwr_cpu_on, cpu, state);
+
+ coordinate_cluster_pwron();
+
+ /* Enable the GIC CPU interface */
+ gicv3_rdistif_on(cpu);
+ gicv3_cpuif_enable(cpu);
+ mt_gic_rdistif_init();
+
+ /*
+ * If mcusys does power down before then restore
+ * all CPUs' GIC Redistributors
+ */
+ if (IS_MCUSYS_OFF_STATE(state)) {
+ mt_gic_rdistif_restore_all();
+ } else {
+ mt_gic_rdistif_restore();
+ }
+
+ /* PTP3 config */
+ ptp3_init(cpu);
+}
+
+/*
+ * Common MTK_platform operations to power on/off a
+ * cluster in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request.
+ */
+
+static void plat_cluster_pwrdwn_common(unsigned int cpu,
+ const psci_power_state_t *state, unsigned int req_pstate)
+{
+ assert(cpu == plat_my_core_pos());
+
+ if (plat_mt_pm_invoke(pwr_cluster_dwn, cpu, state) != 0) {
+ coordinate_cluster_pwron();
+
+ /* TODO: return on fail.
+ * Add a 'return' here before adding any code following
+ * the if-block.
+ */
+ }
+}
+
+static void plat_cluster_pwron_common(unsigned int cpu,
+ const psci_power_state_t *state, unsigned int req_pstate)
+{
+ assert(cpu == plat_my_core_pos());
+
+ if (plat_mt_pm_invoke(pwr_cluster_on, cpu, state) != 0) {
+ /* TODO: return on fail.
+ * Add a 'return' here before adding any code following
+ * the if-block.
+ */
+ }
+}
+
+/*
+ * Common MTK_platform operations to power on/off a
+ * mcusys in response to a CPU_ON, CPU_OFF or CPU_SUSPEND request.
+ */
+
+static void plat_mcusys_pwrdwn_common(unsigned int cpu,
+ const psci_power_state_t *state, unsigned int req_pstate)
+{
+ assert(cpu == plat_my_core_pos());
+
+ if (plat_mt_pm_invoke(pwr_mcusys_dwn, cpu, state) != 0) {
+ return; /* return on fail */
+ }
+
+ mt_gic_distif_save();
+ gic_sgi_save_all();
+}
+
+static void plat_mcusys_pwron_common(unsigned int cpu,
+ const psci_power_state_t *state, unsigned int req_pstate)
+{
+ assert(cpu == plat_my_core_pos());
+
+ if (plat_mt_pm_invoke(pwr_mcusys_on, cpu, state) != 0) {
+ return; /* return on fail */
+ }
+
+ mt_gic_init();
+ mt_gic_distif_restore();
+ gic_sgi_restore_all();
+
+ plat_mt_pm_invoke_no_check(pwr_mcusys_on_finished, cpu, state);
+}
+
+/*
+ * plat_psci_ops implementation
+ */
+
+static void plat_cpu_standby(plat_local_state_t cpu_state)
+{
+ uint64_t scr;
+
+ scr = read_scr_el3();
+ write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT);
+
+ isb();
+ dsb();
+ wfi();
+
+ write_scr_el3(scr);
+}
+
+static int plat_power_domain_on(u_register_t mpidr)
+{
+ unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr);
+ unsigned int cluster = 0U;
+
+ if (cpu >= PLATFORM_CORE_COUNT) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+
+ if (!spm_get_cluster_powerstate(cluster)) {
+ spm_poweron_cluster(cluster);
+ }
+
+ /* init CPU reset arch as AARCH64 */
+ mcucfg_init_archstate(cluster, cpu, true);
+ mcucfg_set_bootaddr(cluster, cpu, secure_entrypoint);
+ spm_poweron_cpu(cluster, cpu);
+
+ return PSCI_E_SUCCESS;
+}
+
+static void plat_power_domain_on_finish(const psci_power_state_t *state)
+{
+ unsigned long mpidr = read_mpidr_el1();
+ unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr);
+
+ assert(cpu < PLATFORM_CORE_COUNT);
+
+ /* Allow IRQs to wakeup this core in IDLE flow */
+ mcucfg_enable_gic_wakeup(0U, cpu);
+
+ if (IS_CLUSTER_OFF_STATE(state)) {
+ plat_cluster_pwron_common(cpu, state, 0U);
+ }
+
+ plat_cpu_pwron_common(cpu, state, 0U);
+}
+
+static void plat_power_domain_off(const psci_power_state_t *state)
+{
+ unsigned long mpidr = read_mpidr_el1();
+ unsigned int cpu = (unsigned int)plat_core_pos_by_mpidr(mpidr);
+
+ assert(cpu < PLATFORM_CORE_COUNT);
+
+ plat_cpu_pwrdwn_common(cpu, state, 0U);
+ spm_poweroff_cpu(0U, cpu);
+
+ /* prevent unintended IRQs from waking up the hot-unplugged core */
+ mcucfg_disable_gic_wakeup(0U, cpu);
+
+ if (IS_CLUSTER_OFF_STATE(state)) {
+ plat_cluster_pwrdwn_common(cpu, state, 0U);
+ }
+}
+
+static void plat_power_domain_suspend(const psci_power_state_t *state)
+{
+ unsigned int cpu = plat_my_core_pos();
+
+ assert(cpu < PLATFORM_CORE_COUNT);
+
+ plat_mt_pm_invoke_no_check(pwr_prompt, cpu, state);
+
+ /* Perform the common CPU specific operations */
+ plat_cpu_pwrdwn_common(cpu, state, plat_power_state[cpu]);
+
+ if (IS_CLUSTER_OFF_STATE(state)) {
+ /* Perform the common cluster specific operations */
+ plat_cluster_pwrdwn_common(cpu, state, plat_power_state[cpu]);
+ }
+
+ if (IS_MCUSYS_OFF_STATE(state)) {
+ /* Perform the common mcusys specific operations */
+ plat_mcusys_pwrdwn_common(cpu, state, plat_power_state[cpu]);
+ }
+}
+
+static void plat_power_domain_suspend_finish(const psci_power_state_t *state)
+{
+ unsigned int cpu = plat_my_core_pos();
+
+ assert(cpu < PLATFORM_CORE_COUNT);
+
+ if (IS_MCUSYS_OFF_STATE(state)) {
+ /* Perform the common mcusys specific operations */
+ plat_mcusys_pwron_common(cpu, state, plat_power_state[cpu]);
+ }
+
+ if (IS_CLUSTER_OFF_STATE(state)) {
+ /* Perform the common cluster specific operations */
+ plat_cluster_pwron_common(cpu, state, plat_power_state[cpu]);
+ }
+
+ /* Perform the common CPU specific operations */
+ plat_cpu_pwron_common(cpu, state, plat_power_state[cpu]);
+
+ plat_mt_pm_invoke_no_check(pwr_reflect, cpu, state);
+}
+
+static int plat_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state)
+{
+ unsigned int pstate = psci_get_pstate_type(power_state);
+ unsigned int aff_lvl = psci_get_pstate_pwrlvl(power_state);
+ unsigned int cpu = plat_my_core_pos();
+
+ if (pstate == PSTATE_TYPE_STANDBY) {
+ req_state->pwr_domain_state[0] = PLAT_MAX_RET_STATE;
+ } else {
+ unsigned int i;
+ unsigned int pstate_id = psci_get_pstate_id(power_state);
+ plat_local_state_t s = MTK_LOCAL_STATE_OFF;
+
+ /* Use pstate_id to be power domain state */
+ if (pstate_id > s) {
+ s = (plat_local_state_t)pstate_id;
+ }
+
+ for (i = 0U; i <= aff_lvl; i++) {
+ req_state->pwr_domain_state[i] = s;
+ }
+ }
+
+ plat_power_state[cpu] = power_state;
+ return PSCI_E_SUCCESS;
+}
+
+static void plat_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+ unsigned int lv;
+ unsigned int cpu = plat_my_core_pos();
+
+ for (lv = PSCI_CPU_PWR_LVL; lv <= PLAT_MAX_PWR_LVL; lv++) {
+ req_state->pwr_domain_state[lv] = PLAT_MAX_OFF_STATE;
+ }
+
+ plat_power_state[cpu] =
+ psci_make_powerstate(
+ MT_PLAT_PWR_STATE_SYSTEM_SUSPEND,
+ PSTATE_TYPE_POWERDOWN, PLAT_MAX_PWR_LVL);
+
+ flush_dcache_range((uintptr_t)
+ &plat_power_state[cpu],
+ sizeof(plat_power_state[cpu]));
+}
+
+static void __dead2 plat_mtk_system_off(void)
+{
+ INFO("MTK System Off\n");
+
+ rtc_power_off_sequence();
+ pmic_power_off();
+
+ wfi();
+ ERROR("MTK System Off: operation not handled.\n");
+ panic();
+}
+
+static void __dead2 plat_mtk_system_reset(void)
+{
+ struct bl_aux_gpio_info *gpio_reset = plat_get_mtk_gpio_reset();
+
+ INFO("MTK System Reset\n");
+
+ gpio_set_value(gpio_reset->index, gpio_reset->polarity);
+
+ wfi();
+ ERROR("MTK System Reset: operation not handled.\n");
+ panic();
+}
+
+static const plat_psci_ops_t plat_psci_ops = {
+ .system_reset = plat_mtk_system_reset,
+ .cpu_standby = plat_cpu_standby,
+ .pwr_domain_on = plat_power_domain_on,
+ .pwr_domain_on_finish = plat_power_domain_on_finish,
+ .pwr_domain_off = plat_power_domain_off,
+ .pwr_domain_suspend = plat_power_domain_suspend,
+ .pwr_domain_suspend_finish = plat_power_domain_suspend_finish,
+ .system_off = plat_mtk_system_off,
+ .validate_power_state = plat_validate_power_state,
+ .get_sys_suspend_power_state = plat_get_sys_suspend_power_state
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ *psci_ops = &plat_psci_ops;
+ secure_entrypoint = sec_entrypoint;
+
+ /*
+ * init the warm reset config for boot CPU
+ * reset arch as AARCH64
+ * reset addr as function bl31_warm_entrypoint()
+ */
+ mcucfg_init_archstate(0U, 0U, true);
+ mcucfg_set_bootaddr(0U, 0U, secure_entrypoint);
+
+ spmc_init();
+ plat_mt_pm = mt_plat_cpu_pm_init();
+
+ return 0;
+}
diff --git a/plat/mediatek/mt8192/plat_sip_calls.c b/plat/mediatek/mt8192/plat_sip_calls.c
new file mode 100644
index 000000000..f97684f77
--- /dev/null
+++ b/plat/mediatek/mt8192/plat_sip_calls.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+
+uintptr_t mediatek_plat_sip_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags)
+{
+
+ switch (smc_fid) {
+ default:
+ ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+ break;
+ }
+
+ SMC_RET1(handle, SMC_UNK);
+}
diff --git a/plat/mediatek/mt8192/plat_topology.c b/plat/mediatek/mt8192/plat_topology.c
new file mode 100644
index 000000000..8c1231a6e
--- /dev/null
+++ b/plat/mediatek/mt8192/plat_topology.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Project Includes */
+#include <arch.h>
+#include <arch_helpers.h>
+#include <lib/psci/psci.h>
+
+/* Platform Includes */
+#include <plat_helpers.h>
+#include <platform_def.h>
+
+const unsigned char mtk_power_domain_tree_desc[] = {
+ /* Number of root nodes */
+ PLATFORM_SYSTEM_COUNT,
+ /* Number of children for the root node */
+ PLATFORM_MCUSYS_COUNT,
+ /* Number of children for the mcusys node */
+ PLATFORM_CLUSTER_COUNT,
+ /* Number of children for the first cluster node */
+ PLATFORM_CLUSTER0_CORE_COUNT,
+};
+
+/*******************************************************************************
+ * This function returns the MT8192 default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return mtk_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+ unsigned int cluster_id, cpu_id;
+
+ if (read_mpidr() & MPIDR_MT_MASK) {
+ /* ARMv8.2 arch */
+ if (mpidr & (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT)) {
+ return -1;
+ }
+ return plat_mediatek_calc_core_pos(mpidr);
+ }
+
+ mpidr &= MPIDR_AFFINITY_MASK;
+
+ if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) {
+ return -1;
+ }
+
+ cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+ cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+ if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+ return -1;
+ }
+
+ /*
+ * Validate cpu_id by checking whether it represents a CPU in
+ * one of the two clusters present on the platform.
+ */
+ if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) {
+ return -1;
+ }
+
+ return (cpu_id + (cluster_id * 8));
+}
diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk
new file mode 100644
index 000000000..a5e7ee26a
--- /dev/null
+++ b/plat/mediatek/mt8192/platform.mk
@@ -0,0 +1,83 @@
+#
+# Copyright (c) 2020, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+MTK_PLAT := plat/mediatek
+MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
+
+PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
+ -I${MTK_PLAT_SOC}/include/ \
+ -I${MTK_PLAT_SOC}/drivers/ \
+ -I${MTK_PLAT_SOC}/drivers/dcm \
+ -I${MTK_PLAT_SOC}/drivers/emi_mpu/ \
+ -I${MTK_PLAT_SOC}/drivers/gpio/ \
+ -I${MTK_PLAT_SOC}/drivers/mcdi/ \
+ -I${MTK_PLAT_SOC}/drivers/pmic/ \
+ -I${MTK_PLAT_SOC}/drivers/ptp3/ \
+ -I${MTK_PLAT_SOC}/drivers/rtc/ \
+ -I${MTK_PLAT_SOC}/drivers/spmc/ \
+ -I${MTK_PLAT_SOC}/drivers/timer/ \
+ -I${MTK_PLAT_SOC}/drivers/uart/
+
+GICV3_SUPPORT_GIC600 := 1
+include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_BL_COMMON_SOURCES := ${GICV3_SOURCES} \
+ ${XLAT_TABLES_LIB_SRCS} \
+ plat/common/aarch64/crash_console_helpers.S \
+ plat/common/plat_psci_common.c
+
+BL31_SOURCES += common/desc_image_load.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ drivers/ti/uart/aarch64/16550_console.S \
+ drivers/gpio/gpio.c \
+ lib/bl_aux_params/bl_aux_params.c \
+ lib/cpus/aarch64/cortex_a55.S \
+ lib/cpus/aarch64/cortex_a76.S \
+ plat/common/plat_gicv3.c \
+ ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init_v2.c \
+ ${MTK_PLAT}/common/drivers/rtc/rtc_common.c \
+ ${MTK_PLAT}/common/drivers/uart/uart.c \
+ ${MTK_PLAT}/common/mtk_plat_common.c \
+ ${MTK_PLAT}/common/mtk_sip_svc.c \
+ ${MTK_PLAT}/common/params_setup.c \
+ ${MTK_PLAT_SOC}/aarch64/platform_common.c \
+ ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
+ ${MTK_PLAT_SOC}/bl31_plat_setup.c \
+ ${MTK_PLAT_SOC}/drivers/pmic/pmic.c \
+ ${MTK_PLAT_SOC}/drivers/rtc/rtc.c \
+ ${MTK_PLAT_SOC}/plat_pm.c \
+ ${MTK_PLAT_SOC}/plat_topology.c \
+ ${MTK_PLAT_SOC}/plat_mt_gic.c \
+ ${MTK_PLAT_SOC}/plat_mt_cirq.c \
+ ${MTK_PLAT_SOC}/plat_sip_calls.c \
+ ${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm.c \
+ ${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm_utils.c \
+ ${MTK_PLAT_SOC}/drivers/emi_mpu/emi_mpu.c \
+ ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \
+ ${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm.c \
+ ${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm_cpc.c \
+ ${MTK_PLAT_SOC}/drivers/mcdi/mt_mcdi.c \
+ ${MTK_PLAT_SOC}/drivers/ptp3/mtk_ptp3_main.c \
+ ${MTK_PLAT_SOC}/drivers/spmc/mtspmc.c \
+ ${MTK_PLAT_SOC}/drivers/timer/mt_timer.c
+
+# Configs for A76 and A55
+HW_ASSISTED_COHERENCY := 1
+USE_COHERENT_MEM := 0
+CTX_INCLUDE_AARCH32_REGS := 0
+
+# indicate the reset vector address can be programmed
+PROGRAMMABLE_RESET_ADDRESS := 1
+
+COLD_BOOT_SINGLE_CPU := 1
+
+MACH_MT8192 := 1
+$(eval $(call add_define,MACH_MT8192))
+
+include lib/coreboot/coreboot.mk
+
diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index 13ca6aaa2..6c8c4f018 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -1,14 +1,16 @@
/*
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+
#include <arch.h>
#include <asm_macros.S>
#include <assert_macros.S>
-#include <cpu_macros.S>
-#include <cortex_a53.h>
#include <cortex_a57.h>
+#include <cpu_macros.S>
+
#include <platform_def.h>
#include <tegra_def.h>
#include <tegra_platform.h>
@@ -18,21 +20,16 @@
/*******************************************************************************
* Implementation defined ACTLR_EL3 bit definitions
******************************************************************************/
-#define ACTLR_EL3_L2ACTLR_BIT (U(1) << 6)
-#define ACTLR_EL3_L2ECTLR_BIT (U(1) << 5)
-#define ACTLR_EL3_L2CTLR_BIT (U(1) << 4)
-#define ACTLR_EL3_CPUECTLR_BIT (U(1) << 1)
-#define ACTLR_EL3_CPUACTLR_BIT (U(1) << 0)
-#define ACTLR_EL3_ENABLE_ALL_MASK (ACTLR_EL3_L2ACTLR_BIT | \
- ACTLR_EL3_L2ECTLR_BIT | \
- ACTLR_EL3_L2CTLR_BIT | \
- ACTLR_EL3_CPUECTLR_BIT | \
- ACTLR_EL3_CPUACTLR_BIT)
-#define ACTLR_EL3_ENABLE_ALL_ACCESS (ACTLR_EL3_L2ACTLR_BIT | \
- ACTLR_EL3_L2ECTLR_BIT | \
- ACTLR_EL3_L2CTLR_BIT | \
- ACTLR_EL3_CPUECTLR_BIT | \
- ACTLR_EL3_CPUACTLR_BIT)
+#define ACTLR_ELx_L2ACTLR_BIT (U(1) << 6)
+#define ACTLR_ELx_L2ECTLR_BIT (U(1) << 5)
+#define ACTLR_ELx_L2CTLR_BIT (U(1) << 4)
+#define ACTLR_ELx_CPUECTLR_BIT (U(1) << 1)
+#define ACTLR_ELx_CPUACTLR_BIT (U(1) << 0)
+#define ACTLR_ELx_ENABLE_ALL_ACCESS (ACTLR_ELx_L2ACTLR_BIT | \
+ ACTLR_ELx_L2ECTLR_BIT | \
+ ACTLR_ELx_L2CTLR_BIT | \
+ ACTLR_ELx_CPUECTLR_BIT | \
+ ACTLR_ELx_CPUACTLR_BIT)
/* Global functions */
.globl plat_is_my_cpu_primary
@@ -43,6 +40,7 @@
.globl plat_crash_console_init
.globl plat_crash_console_putc
.globl plat_crash_console_flush
+ .weak plat_core_pos_by_mpidr
.globl tegra_secure_entrypoint
.globl plat_reset_handler
@@ -93,15 +91,11 @@
* -------------------------------------------------------
*/
mrs x0, actlr_el3
- mov x1, #ACTLR_EL3_ENABLE_ALL_MASK
- bic x0, x0, x1
- mov x1, #ACTLR_EL3_ENABLE_ALL_ACCESS
+ mov x1, #ACTLR_ELx_ENABLE_ALL_ACCESS
orr x0, x0, x1
msr actlr_el3, x0
mrs x0, actlr_el2
- mov x1, #ACTLR_EL3_ENABLE_ALL_MASK
- bic x0, x0, x1
- mov x1, #ACTLR_EL3_ENABLE_ALL_ACCESS
+ mov x1, #ACTLR_ELx_ENABLE_ALL_ACCESS
orr x0, x0, x1
msr actlr_el2, x0
isb
@@ -148,17 +142,14 @@ endfunc plat_is_my_cpu_primary
* unsigned int plat_my_core_pos(void);
*
* result: CorePos = CoreId + (ClusterId * cpus per cluster)
+ * Registers clobbered: x0, x8
* ----------------------------------------------------------
*/
func plat_my_core_pos
+ mov x8, x30
mrs x0, mpidr_el1
- and x1, x0, #MPIDR_CPU_MASK
- and x0, x0, #MPIDR_CLUSTER_MASK
- lsr x0, x0, #MPIDR_AFFINITY_BITS
- mov x2, #PLATFORM_MAX_CPUS_PER_CLUSTER
- mul x0, x0, x2
- add x0, x1, x0
- ret
+ bl plat_core_pos_by_mpidr
+ ret x8
endfunc plat_my_core_pos
/* -----------------------------------------------------
@@ -177,23 +168,6 @@ func plat_get_my_entrypoint
endfunc plat_get_my_entrypoint
/* -----------------------------------------------------
- * int platform_get_core_pos(int mpidr);
- *
- * result: CorePos = (ClusterId * cpus per cluster) +
- * CoreId
- * -----------------------------------------------------
- */
-func platform_get_core_pos
- and x1, x0, #MPIDR_CPU_MASK
- and x0, x0, #MPIDR_CLUSTER_MASK
- lsr x0, x0, #MPIDR_AFFINITY_BITS
- mov x2, #PLATFORM_MAX_CPUS_PER_CLUSTER
- mul x0, x0, x2
- add x0, x1, x0
- ret
-endfunc platform_get_core_pos
-
- /* -----------------------------------------------------
* void plat_secondary_cold_boot_setup (void);
*
* This function performs any platform specific actions
@@ -241,7 +215,8 @@ func plat_reset_handler
*/
mov x0, x17
mov x1, x18
- mov x2, #BL31_SIZE
+ adr x2, __RELA_END__
+ sub x2, x2, x18
_loop16:
cmp x2, #16
b.lo _loop1
@@ -281,6 +256,42 @@ _end: mov x0, x20
ret
endfunc plat_reset_handler
+ /* ------------------------------------------------------
+ * int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
+ *
+ * This function implements a part of the critical
+ * interface between the psci generic layer and the
+ * platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error
+ * code (-1) is returned in case the MPIDR is invalid.
+ *
+ * Clobbers: x0-x3
+ * ------------------------------------------------------
+ */
+func plat_core_pos_by_mpidr
+ lsr x1, x0, #MPIDR_AFF0_SHIFT
+ and x1, x1, #MPIDR_AFFLVL_MASK /* core id */
+ lsr x2, x0, #MPIDR_AFF1_SHIFT
+ and x2, x2, #MPIDR_AFFLVL_MASK /* cluster id */
+
+ /* core_id >= PLATFORM_MAX_CPUS_PER_CLUSTER */
+ mov x0, #-1
+ cmp x1, #(PLATFORM_MAX_CPUS_PER_CLUSTER - 1)
+ b.gt 1f
+
+ /* cluster_id >= PLATFORM_CLUSTER_COUNT */
+ cmp x2, #(PLATFORM_CLUSTER_COUNT - 1)
+ b.gt 1f
+
+ /* CorePos = CoreId + (ClusterId * cpus per cluster) */
+ mov x3, #PLATFORM_MAX_CPUS_PER_CLUSTER
+ mul x3, x3, x2
+ add x0, x1, x3
+
+1:
+ ret
+endfunc plat_core_pos_by_mpidr
+
/* ----------------------------------------
* Secure entrypoint function for CPU boot
* ----------------------------------------
diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
deleted file mode 100644
index 8c1b899f7..000000000
--- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <platform_def.h>
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-
-#include <smmu.h>
-#include <tegra_private.h>
-
-extern void memcpy16(void *dest, const void *src, unsigned int length);
-
-/* SMMU IDs currently supported by the driver */
-enum {
- TEGRA_SMMU0 = 0U,
- TEGRA_SMMU1,
- TEGRA_SMMU2
-};
-
-static uint32_t tegra_smmu_read_32(uint32_t smmu_id, uint32_t off)
-{
- uint32_t ret = 0U;
-
-#if defined(TEGRA_SMMU0_BASE)
- if (smmu_id == TEGRA_SMMU0) {
- ret = mmio_read_32(TEGRA_SMMU0_BASE + (uint64_t)off);
- }
-#endif
-
-#if defined(TEGRA_SMMU1_BASE)
- if (smmu_id == TEGRA_SMMU1) {
- ret = mmio_read_32(TEGRA_SMMU1_BASE + (uint64_t)off);
- }
-#endif
-
-#if defined(TEGRA_SMMU2_BASE)
- if (smmu_id == TEGRA_SMMU2) {
- ret = mmio_read_32(TEGRA_SMMU2_BASE + (uint64_t)off);
- }
-#endif
-
- return ret;
-}
-
-static void tegra_smmu_write_32(uint32_t smmu_id,
- uint32_t off, uint32_t val)
-{
-#if defined(TEGRA_SMMU0_BASE)
- if (smmu_id == TEGRA_SMMU0) {
- mmio_write_32(TEGRA_SMMU0_BASE + (uint64_t)off, val);
- }
-#endif
-
-#if defined(TEGRA_SMMU1_BASE)
- if (smmu_id == TEGRA_SMMU1) {
- mmio_write_32(TEGRA_SMMU1_BASE + (uint64_t)off, val);
- }
-#endif
-
-#if defined(TEGRA_SMMU2_BASE)
- if (smmu_id == TEGRA_SMMU2) {
- mmio_write_32(TEGRA_SMMU2_BASE + (uint64_t)off, val);
- }
-#endif
-}
-
-/*
- * Save SMMU settings before "System Suspend" to TZDRAM
- */
-void tegra_smmu_save_context(uint64_t smmu_ctx_addr)
-{
- uint32_t i, num_entries = 0;
- smmu_regs_t *smmu_ctx_regs;
- const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
- uint64_t tzdram_base = params_from_bl2->tzdram_base;
- uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size;
- uint32_t reg_id1, pgshift, cb_size;
-
- /* sanity check SMMU settings c*/
- reg_id1 = mmio_read_32((TEGRA_SMMU0_BASE + SMMU_GNSR0_IDR1));
- pgshift = ((reg_id1 & ID1_PAGESIZE) != 0U) ? 16U : 12U;
- cb_size = ((uint32_t)2 << pgshift) * \
- ((uint32_t)1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1U));
-
- assert(!((pgshift != PGSHIFT) || (cb_size != CB_SIZE)));
- assert((smmu_ctx_addr >= tzdram_base) && (smmu_ctx_addr <= tzdram_end));
-
- /* get SMMU context table */
- smmu_ctx_regs = plat_get_smmu_ctx();
- assert(smmu_ctx_regs != NULL);
-
- /*
- * smmu_ctx_regs[0].val contains the size of the context table minus
- * the last entry. Sanity check the table size before we start with
- * the context save operation.
- */
- while ((smmu_ctx_regs[num_entries].reg != 0xFFFFFFFFU)) {
- num_entries++;
- }
-
- /* panic if the sizes do not match */
- if (num_entries != smmu_ctx_regs[0].val) {
- ERROR("SMMU context size mismatch!");
- panic();
- }
-
- /* save SMMU register values */
- for (i = 1U; i < num_entries; i++) {
- smmu_ctx_regs[i].val = mmio_read_32(smmu_ctx_regs[i].reg);
- }
-
- /* increment by 1 to take care of the last entry */
- num_entries++;
-
- /* Save SMMU config settings */
- (void)memcpy16((uint8_t *)smmu_ctx_addr, (uint8_t *)smmu_ctx_regs,
- (sizeof(smmu_regs_t) * num_entries));
-
- /* save the SMMU table address */
- mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_LO,
- (uint32_t)smmu_ctx_addr);
- mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_HI,
- (uint32_t)(smmu_ctx_addr >> 32));
-}
-
-#define SMMU_NUM_CONTEXTS 64
-#define SMMU_CONTEXT_BANK_MAX_IDX 64
-
-/*
- * Init SMMU during boot or "System Suspend" exit
- */
-void tegra_smmu_init(void)
-{
- uint32_t val, cb_idx, smmu_id, ctx_base;
- uint32_t smmu_counter = plat_get_num_smmu_devices();
-
- for (smmu_id = 0U; smmu_id < smmu_counter; smmu_id++) {
- /* Program the SMMU pagesize and reset CACHE_LOCK bit */
- val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
- val |= SMMU_GSR0_PGSIZE_64K;
- val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
- tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
-
- /* reset CACHE LOCK bit for NS Aux. Config. Register */
- val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
- val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
- tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
-
- /* disable TCU prefetch for all contexts */
- ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS)
- + SMMU_CBn_ACTLR;
- for (cb_idx = 0; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
- val = tegra_smmu_read_32(smmu_id,
- ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx));
- val &= (uint32_t)~SMMU_CBn_ACTLR_CPRE_BIT;
- tegra_smmu_write_32(smmu_id, ctx_base +
- (SMMU_GSR0_PGSIZE_64K * cb_idx), val);
- }
-
- /* set CACHE LOCK bit for NS Aux. Config. Register */
- val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
- val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
- tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
-
- /* set CACHE LOCK bit for S Aux. Config. Register */
- val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
- val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
- tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
- }
-}
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index cbe3377b0..cb4886f1a 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,7 +17,6 @@
#include <bl31/bl31.h>
#include <common/bl_common.h>
#include <common/debug.h>
-#include <cortex_a53.h>
#include <cortex_a57.h>
#include <denver.h>
#include <drivers/console.h>
@@ -27,6 +27,7 @@
#include <memctrl.h>
#include <profiler.h>
+#include <smmu.h>
#include <tegra_def.h>
#include <tegra_platform.h>
#include <tegra_private.h>
@@ -34,21 +35,12 @@
/* length of Trusty's input parameters (in bytes) */
#define TRUSTY_PARAMS_LEN_BYTES (4096*2)
-extern void memcpy16(void *dest, const void *src, unsigned int length);
-
/*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout
* of trusted SRAM
******************************************************************************/
-
IMPORT_SYM(uint64_t, __RW_START__, BL31_RW_START);
-static const uint64_t BL31_RW_END = BL_END;
-static const uint64_t BL31_RODATA_BASE = BL_RO_DATA_BASE;
-static const uint64_t BL31_RODATA_END = BL_RO_DATA_END;
-static const uint64_t TEXT_START = BL_CODE_BASE;
-static const uint64_t TEXT_END = BL_CODE_END;
-
extern uint64_t tegra_bl31_phys_base;
static entry_point_info_t bl33_image_ep_info, bl32_image_ep_info;
@@ -65,35 +57,6 @@ static aapcs64_params_t bl32_args;
extern uint64_t ns_image_entrypoint;
/*******************************************************************************
- * The following platform setup functions are weakly defined. They
- * provide typical implementations that will be overridden by a SoC.
- ******************************************************************************/
-#pragma weak plat_early_platform_setup
-#pragma weak plat_get_bl31_params
-#pragma weak plat_get_bl31_plat_params
-#pragma weak plat_late_platform_setup
-
-void plat_early_platform_setup(void)
-{
- ; /* do nothing */
-}
-
-struct tegra_bl31_params *plat_get_bl31_params(void)
-{
- return NULL;
-}
-
-plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
-{
- return NULL;
-}
-
-void plat_late_platform_setup(void)
-{
- ; /* do nothing */
-}
-
-/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for
* security state specified. BL33 corresponds to the non-secure image type
* while BL32 corresponds to the secure image type.
@@ -130,15 +93,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
{
struct tegra_bl31_params *arg_from_bl2 = (struct tegra_bl31_params *) arg0;
plat_params_from_bl2_t *plat_params = (plat_params_from_bl2_t *)arg1;
- image_info_t bl32_img_info = { {0} };
- uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
int32_t ret;
/*
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
* there's no argument to relay from a previous bootloader. Platforms
- * might use custom ways to get arguments, so provide handlers which
- * they can override.
+ * might use custom ways to get arguments.
*/
if (arg_from_bl2 == NULL) {
arg_from_bl2 = plat_get_bl31_params();
@@ -193,20 +153,17 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
* location to store the boot profiler logs. Sanity check the
* address and initialise the profiler library, if it looks ok.
*/
- if (plat_params->boot_profiler_shmem_base != 0ULL) {
+ ret = bl31_check_ns_address(plat_params->boot_profiler_shmem_base,
+ PROFILER_SIZE_BYTES);
+ if (ret == (int32_t)0) {
- ret = bl31_check_ns_address(plat_params->boot_profiler_shmem_base,
- PROFILER_SIZE_BYTES);
- if (ret == (int32_t)0) {
+ /* store the membase for the profiler lib */
+ plat_bl31_params_from_bl2.boot_profiler_shmem_base =
+ plat_params->boot_profiler_shmem_base;
- /* store the membase for the profiler lib */
- plat_bl31_params_from_bl2.boot_profiler_shmem_base =
- plat_params->boot_profiler_shmem_base;
-
- /* initialise the profiler library */
- boot_profiler_init(plat_params->boot_profiler_shmem_base,
- TEGRA_TMRUS_BASE);
- }
+ /* initialise the profiler library */
+ boot_profiler_init(plat_params->boot_profiler_shmem_base,
+ TEGRA_TMRUS_BASE);
}
/*
@@ -223,48 +180,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
plat_early_platform_setup();
/*
- * Do initial security configuration to allow DRAM/device access.
- */
- tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base,
- (uint32_t)plat_bl31_params_from_bl2.tzdram_size);
-
- /*
- * The previous bootloader might not have placed the BL32 image
- * inside the TZDRAM. We check the BL32 image info to find out
- * the base/PC values and relocate the image if necessary.
- */
- if (arg_from_bl2->bl32_image_info != NULL) {
-
- bl32_img_info = *arg_from_bl2->bl32_image_info;
-
- /* Relocate BL32 if it resides outside of the TZDRAM */
- tzdram_start = plat_bl31_params_from_bl2.tzdram_base;
- tzdram_end = plat_bl31_params_from_bl2.tzdram_base +
- plat_bl31_params_from_bl2.tzdram_size;
- bl32_start = bl32_img_info.image_base;
- bl32_end = bl32_img_info.image_base + bl32_img_info.image_size;
-
- assert(tzdram_end > tzdram_start);
- assert(bl32_end > bl32_start);
- assert(bl32_image_ep_info.pc > tzdram_start);
- assert(bl32_image_ep_info.pc < tzdram_end);
-
- /* relocate BL32 */
- if ((bl32_start >= tzdram_end) || (bl32_end <= tzdram_start)) {
-
- INFO("Relocate BL32 to TZDRAM\n");
-
- (void)memcpy16((void *)(uintptr_t)bl32_image_ep_info.pc,
- (void *)(uintptr_t)bl32_start,
- bl32_img_info.image_size);
-
- /* clean up non-secure intermediate buffer */
- zeromem((void *)(uintptr_t)bl32_start,
- bl32_img_info.image_size);
- }
- }
-
- /*
* Add timestamp for platform early setup exit.
*/
boot_profiler_add_record("[TF] early setup exit");
@@ -318,12 +233,6 @@ void bl31_platform_setup(void)
tegra_memctrl_setup();
/*
- * Set up the TZRAM memory aperture to allow only secure world
- * access
- */
- tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
-
- /*
* Late setup handler to allow platforms to performs additional
* functionality.
* This handler gets called with MMU enabled.
@@ -344,24 +253,9 @@ void bl31_platform_setup(void)
void bl31_plat_runtime_setup(void)
{
/*
- * During cold boot, it is observed that the arbitration
- * bit is set in the Memory controller leading to false
- * error interrupts in the non-secure world. To avoid
- * this, clean the interrupt status register before
- * booting into the non-secure world
+ * Platform specific runtime setup
*/
- tegra_memctrl_clear_pending_interrupts();
-
- /*
- * During boot, USB3 and flash media (SDMMC/SATA) devices need
- * access to IRAM. Because these clients connect to the MC and
- * do not have a direct path to the IRAM, the MC implements AHB
- * redirection during boot to allow path to IRAM. In this mode
- * accesses to a programmed memory address aperture are directed
- * to the AHB bus, allowing access to the IRAM. This mode must be
- * disabled before we jump to the non-secure world.
- */
- tegra_memctrl_disable_ahb_redirection();
+ plat_runtime_setup();
/*
* Add final timestamp before exiting BL31.
@@ -377,15 +271,12 @@ void bl31_plat_runtime_setup(void)
void bl31_plat_arch_setup(void)
{
uint64_t rw_start = BL31_RW_START;
- uint64_t rw_size = BL31_RW_END - BL31_RW_START;
- uint64_t rodata_start = BL31_RODATA_BASE;
- uint64_t rodata_size = BL31_RODATA_END - BL31_RODATA_BASE;
- uint64_t code_base = TEXT_START;
- uint64_t code_size = TEXT_END - TEXT_START;
+ uint64_t rw_size = BL_END - BL31_RW_START;
+ uint64_t rodata_start = BL_RO_DATA_BASE;
+ uint64_t rodata_size = BL_RO_DATA_END - BL_RO_DATA_BASE;
+ uint64_t code_base = BL_CODE_BASE;
+ uint64_t code_size = BL_CODE_END - BL_CODE_BASE;
const mmap_region_t *plat_mmio_map = NULL;
-#if USE_COHERENT_MEM
- uint32_t coh_start, coh_size;
-#endif
const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
/*
@@ -412,15 +303,6 @@ void bl31_plat_arch_setup(void)
code_size,
MT_CODE | MT_SECURE);
-#if USE_COHERENT_MEM
- coh_start = total_base + (BL_COHERENT_RAM_BASE - BL31_RO_BASE);
- coh_size = BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE;
-
- mmap_add_region(coh_start, coh_start,
- coh_size,
- (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE);
-#endif
-
/* map TZDRAM used by BL31 as coherent memory */
if (TEGRA_TZRAM_BASE == tegra_bl31_phys_base) {
mmap_add_region(params_from_bl2->tzdram_base,
@@ -449,7 +331,15 @@ void bl31_plat_arch_setup(void)
int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
{
uint64_t end = base + size_in_bytes - U(1);
- int32_t ret = 0;
+
+ /*
+ * Sanity check the input values
+ */
+ if ((base == 0U) || (size_in_bytes == 0U)) {
+ ERROR("NS address 0x%llx (%lld bytes) is invalid\n",
+ base, size_in_bytes);
+ return -EINVAL;
+ }
/*
* Check if the NS DRAM address is valid
@@ -458,7 +348,7 @@ int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
(end > TEGRA_DRAM_END)) {
ERROR("NS address 0x%llx is out-of-bounds!\n", base);
- ret = -EFAULT;
+ return -EFAULT;
}
/*
@@ -467,9 +357,9 @@ int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
*/
if ((base < (uint64_t)TZDRAM_END) && (end > tegra_bl31_phys_base)) {
ERROR("NS address 0x%llx overlaps TZDRAM!\n", base);
- ret = -ENOTSUP;
+ return -ENOTSUP;
}
/* valid NS address */
- return ret;
+ return 0;
}
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index 34b5638ec..37910181c 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -1,37 +1,59 @@
#
-# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
PLAT_INCLUDES := -Iplat/nvidia/tegra/include/drivers \
-Iplat/nvidia/tegra/include/lib \
- -Iplat/nvidia/tegra/include \
- -Iplat/nvidia/tegra/include/${TARGET_SOC}
+ -Iplat/nvidia/tegra/include
include lib/xlat_tables_v2/xlat_tables.mk
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
-COMMON_DIR := plat/nvidia/tegra/common
+TEGRA_COMMON := plat/nvidia/tegra/common
+TEGRA_DRIVERS := plat/nvidia/tegra/drivers
+TEGRA_LIBS := plat/nvidia/tegra/lib
-TEGRA_GICv2_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+TEGRA_GICv3_SOURCES := $(GICV3_SOURCES) \
+ plat/common/plat_gicv3.c \
+ ${TEGRA_COMMON}/tegra_gicv3.c
+
+# Include GICv2 driver files
+include drivers/arm/gic/v2/gicv2.mk
+
+TEGRA_GICv2_SOURCES := ${GICV2_SOURCES} \
plat/common/plat_gicv2.c \
- ${COMMON_DIR}/tegra_gicv2.c
+ ${TEGRA_COMMON}/tegra_gicv2.c
+
+TEGRA_GICv3_SOURCES := drivers/arm/gic/common/gic_common.c \
+ drivers/arm/gic/v3/arm_gicv3_common.c \
+ drivers/arm/gic/v3/gicv3_main.c \
+ drivers/arm/gic/v3/gicv3_helpers.c \
+ plat/common/plat_gicv3.c \
+ ${TEGRA_COMMON}/tegra_gicv3.c
BL31_SOURCES += drivers/delay_timer/delay_timer.c \
drivers/io/io_storage.c \
plat/common/aarch64/crash_console_helpers.S \
- ${TEGRA_GICv2_SOURCES} \
- ${COMMON_DIR}/aarch64/tegra_helpers.S \
- ${COMMON_DIR}/drivers/pmc/pmc.c \
- ${COMMON_DIR}/lib/debug/profiler.c \
- ${COMMON_DIR}/tegra_bl31_setup.c \
- ${COMMON_DIR}/tegra_delay_timer.c \
- ${COMMON_DIR}/tegra_fiq_glue.c \
- ${COMMON_DIR}/tegra_io_storage.c \
- ${COMMON_DIR}/tegra_platform.c \
- ${COMMON_DIR}/tegra_pm.c \
- ${COMMON_DIR}/tegra_sip_calls.c \
- ${COMMON_DIR}/tegra_topology.c
+ ${TEGRA_LIBS}/debug/profiler.c \
+ ${TEGRA_COMMON}/aarch64/tegra_helpers.S \
+ ${TEGRA_LIBS}/debug/profiler.c \
+ ${TEGRA_COMMON}/tegra_bl31_setup.c \
+ ${TEGRA_COMMON}/tegra_delay_timer.c \
+ ${TEGRA_COMMON}/tegra_fiq_glue.c \
+ ${TEGRA_COMMON}/tegra_io_storage.c \
+ ${TEGRA_COMMON}/tegra_platform.c \
+ ${TEGRA_COMMON}/tegra_pm.c \
+ ${TEGRA_COMMON}/tegra_sip_calls.c \
+ ${TEGRA_COMMON}/tegra_sdei.c
+
+ifneq ($(ENABLE_STACK_PROTECTOR), 0)
+BL31_SOURCES += ${TEGRA_COMMON}/tegra_stack_protector.c
+endif
+ifeq (${EL3_EXCEPTION_HANDLING},1)
+BL31_SOURCES += plat/common/aarch64/plat_ehf.c
+endif
diff --git a/plat/nvidia/tegra/common/tegra_delay_timer.c b/plat/nvidia/tegra/common/tegra_delay_timer.c
index 63dcf410c..d9547c4a3 100644
--- a/plat/nvidia/tegra/common/tegra_delay_timer.c
+++ b/plat/nvidia/tegra/common/tegra_delay_timer.c
@@ -1,31 +1,57 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arch.h>
+
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <plat/common/platform.h>
#include <tegra_def.h>
#include <tegra_private.h>
-static uint32_t tegra_timerus_get_value(void)
+static uint32_t tegra_timer_get_value(void)
{
- return mmio_read_32(TEGRA_TMRUS_BASE);
+ /* enable cntps_tval_el1 timer, mask interrupt */
+ write_cntps_ctl_el1(CNTP_CTL_IMASK_BIT | CNTP_CTL_ENABLE_BIT);
+
+ /*
+ * Generic delay timer implementation expects the timer to be a down
+ * counter. The value is clipped from 64 to 32 bits.
+ */
+ return (uint32_t)(read_cntps_tval_el1());
}
/*
- * Initialise the on-chip free rolling us counter as the delay
- * timer.
+ * Initialise the architecture provided counter as the delay timer.
*/
void tegra_delay_timer_init(void)
{
- static const timer_ops_t tegra_timer_ops = {
- .get_timer_value = tegra_timerus_get_value,
- .clk_mult = 1,
- .clk_div = 1,
- };
+ static timer_ops_t tegra_timer_ops;
+
+ /* Value in ticks */
+ uint32_t multiplier = MHZ_TICKS_PER_SEC;
+
+ /* Value in ticks per second (Hz) */
+ uint32_t divider = plat_get_syscnt_freq2();
+
+ /* Reduce multiplier and divider by dividing them repeatedly by 10 */
+ while (((multiplier % 10U) == 0U) && ((divider % 10U) == 0U)) {
+ multiplier /= 10U;
+ divider /= 10U;
+ }
+
+ /* enable cntps_tval_el1 timer, mask interrupt */
+ write_cntps_ctl_el1(CNTP_CTL_IMASK_BIT | CNTP_CTL_ENABLE_BIT);
+ /* register the timer */
+ tegra_timer_ops.get_timer_value = tegra_timer_get_value;
+ tegra_timer_ops.clk_mult = multiplier;
+ tegra_timer_ops.clk_div = divider;
timer_init(&tegra_timer_ops);
}
diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c
index 60b559556..5309d98cd 100644
--- a/plat/nvidia/tegra/common/tegra_fiq_glue.c
+++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,11 +9,11 @@
#include <arch_helpers.h>
#include <bl31/interrupt_mgmt.h>
+#include <bl31/ehf.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <context.h>
#include <denver.h>
-#include <lib/bakery_lock.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <plat/common/platform.h>
@@ -25,8 +26,6 @@
/* Legacy FIQ used by earlier Tegra platforms */
#define LEGACY_FIQ_PPI_WDT 28U
-static DEFINE_BAKERY_LOCK(tegra_fiq_lock);
-
/*******************************************************************************
* Static variables
******************************************************************************/
@@ -37,29 +36,18 @@ static pcpu_fiq_state_t fiq_state[PLATFORM_CORE_COUNT];
/*******************************************************************************
* Handler for FIQ interrupts
******************************************************************************/
-static uint64_t tegra_fiq_interrupt_handler(uint32_t id,
- uint32_t flags,
- void *handle,
- void *cookie)
+static int tegra_fiq_interrupt_handler(unsigned int id, unsigned int flags,
+ void *handle, void *cookie)
{
cpu_context_t *ctx = cm_get_context(NON_SECURE);
el3_state_t *el3state_ctx = get_el3state_ctx(ctx);
uint32_t cpu = plat_my_core_pos();
- uint32_t irq;
- (void)id;
(void)flags;
(void)handle;
(void)cookie;
/*
- * Read the pending interrupt ID
- */
- irq = plat_ic_get_pending_interrupt_id();
-
- bakery_lock_get(&tegra_fiq_lock);
-
- /*
* Jump to NS world only if the NS world's FIQ handler has
* been registered
*/
@@ -94,7 +82,7 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id,
* disable the routing so that we can mark it as "complete" in the
* GIC later.
*/
- if (irq == LEGACY_FIQ_PPI_WDT) {
+ if (id == LEGACY_FIQ_PPI_WDT) {
tegra_fc_disable_fiq_to_ccplex_routing();
}
#endif
@@ -102,12 +90,7 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id,
/*
* Mark this interrupt as complete to avoid a FIQ storm.
*/
- if (irq < 1022U) {
- (void)plat_ic_acknowledge_interrupt();
- plat_ic_end_of_interrupt(irq);
- }
-
- bakery_lock_release(&tegra_fiq_lock);
+ plat_ic_end_of_interrupt(id);
return 0;
}
@@ -117,23 +100,13 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id,
******************************************************************************/
void tegra_fiq_handler_setup(void)
{
- uint32_t flags;
- int32_t rc;
-
/* return if already registered */
if (fiq_handler_active == 0U) {
/*
* Register an interrupt handler for FIQ interrupts generated for
* NS interrupt sources
*/
- flags = 0U;
- set_interrupt_rm_flag((flags), (NON_SECURE));
- rc = register_interrupt_type_handler(INTR_TYPE_EL3,
- tegra_fiq_interrupt_handler,
- flags);
- if (rc != 0) {
- panic();
- }
+ ehf_register_priority_handler(PLAT_TEGRA_WDT_PRIO, tegra_fiq_interrupt_handler);
/* handler is now active */
fiq_handler_active = 1;
@@ -155,7 +128,7 @@ int32_t tegra_fiq_get_intr_context(void)
{
cpu_context_t *ctx = cm_get_context(NON_SECURE);
gp_regs_t *gpregs_ctx = get_gpregs_ctx(ctx);
- const el1_sys_regs_t *el1state_ctx = get_sysregs_ctx(ctx);
+ const el1_sysregs_t *el1state_ctx = get_el1_sysregs_ctx(ctx);
uint32_t cpu = plat_my_core_pos();
uint64_t val;
diff --git a/plat/nvidia/tegra/common/tegra_gicv2.c b/plat/nvidia/tegra/common/tegra_gicv2.c
index 293df8d4f..012107e3b 100644
--- a/plat/nvidia/tegra/common/tegra_gicv2.c
+++ b/plat/nvidia/tegra/common/tegra_gicv2.c
@@ -1,20 +1,23 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-
#include <platform_def.h>
#include <common/bl_common.h>
#include <drivers/arm/gicv2.h>
#include <lib/utils.h>
+#include <plat/common/platform.h>
#include <tegra_private.h>
#include <tegra_def.h>
+static unsigned int tegra_target_masks[PLATFORM_CORE_COUNT];
+
/******************************************************************************
* Tegra common helper to setup the GICv2 driver data.
*****************************************************************************/
@@ -33,6 +36,8 @@ void tegra_gic_setup(const interrupt_prop_t *interrupt_props,
tegra_gic_data.gicc_base = TEGRA_GICC_BASE;
tegra_gic_data.interrupt_props = interrupt_props;
tegra_gic_data.interrupt_props_num = interrupt_props_num;
+ tegra_gic_data.target_masks = tegra_target_masks;
+ tegra_gic_data.target_masks_num = ARRAY_SIZE(tegra_target_masks);
gicv2_driver_init(&tegra_gic_data);
}
@@ -43,6 +48,7 @@ void tegra_gic_init(void)
{
gicv2_distif_init();
gicv2_pcpu_distif_init();
+ gicv2_set_pe_target_mask(plat_my_core_pos());
gicv2_cpuif_enable();
}
@@ -61,5 +67,6 @@ void tegra_gic_cpuif_deactivate(void)
void tegra_gic_pcpu_init(void)
{
gicv2_pcpu_distif_init();
+ gicv2_set_pe_target_mask(plat_my_core_pos());
gicv2_cpuif_enable();
}
diff --git a/plat/nvidia/tegra/common/tegra_gicv3.c b/plat/nvidia/tegra/common/tegra_gicv3.c
new file mode 100644
index 000000000..cba2f9b95
--- /dev/null
+++ b/plat/nvidia/tegra/common/tegra_gicv3.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/bl_common.h>
+#include <drivers/arm/gicv3.h>
+#include <lib/utils.h>
+
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <tegra_private.h>
+#include <tegra_def.h>
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+static unsigned int plat_tegra_mpidr_to_core_pos(unsigned long mpidr)
+{
+ return (unsigned int)plat_core_pos_by_mpidr(mpidr);
+}
+
+/******************************************************************************
+ * Tegra common helper to setup the GICv3 driver data.
+ *****************************************************************************/
+void tegra_gic_setup(const interrupt_prop_t *interrupt_props,
+ unsigned int interrupt_props_num)
+{
+ /*
+ * Tegra GIC configuration settings
+ */
+ static gicv3_driver_data_t tegra_gic_data;
+
+ /*
+ * Register Tegra GICv3 driver
+ */
+ tegra_gic_data.gicd_base = TEGRA_GICD_BASE;
+ tegra_gic_data.gicr_base = TEGRA_GICR_BASE;
+ tegra_gic_data.rdistif_num = PLATFORM_CORE_COUNT;
+ tegra_gic_data.rdistif_base_addrs = rdistif_base_addrs;
+ tegra_gic_data.mpidr_to_core_pos = plat_tegra_mpidr_to_core_pos;
+ tegra_gic_data.interrupt_props = interrupt_props;
+ tegra_gic_data.interrupt_props_num = interrupt_props_num;
+ gicv3_driver_init(&tegra_gic_data);
+
+ /* initialize the GICD and GICR */
+ tegra_gic_init();
+}
+
+/******************************************************************************
+ * Tegra common helper to initialize the GICv3 only driver.
+ *****************************************************************************/
+void tegra_gic_init(void)
+{
+ gicv3_distif_init();
+ gicv3_rdistif_init(plat_my_core_pos());
+ gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * Tegra common helper to disable the GICv3 CPU interface
+ *****************************************************************************/
+void tegra_gic_cpuif_deactivate(void)
+{
+ gicv3_cpuif_disable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * Tegra common helper to initialize the per cpu distributor interface
+ * in GICv3
+ *****************************************************************************/
+void tegra_gic_pcpu_init(void)
+{
+ gicv3_rdistif_init(plat_my_core_pos());
+ gicv3_cpuif_enable(plat_my_core_pos());
+}
diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c
index c1e420959..d45d9886f 100644
--- a/plat/nvidia/tegra/common/tegra_platform.c
+++ b/plat/nvidia/tegra/common/tegra_platform.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +8,8 @@
#include <arch_helpers.h>
#include <assert.h>
#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <services/arm_arch_svc.h>
#include <tegra_def.h>
#include <tegra_platform.h>
#include <tegra_private.h>
@@ -105,6 +108,13 @@ bool tegra_chipid_is_t210_b01(void)
return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2U));
}
+bool tegra_chipid_is_t194(void)
+{
+ uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
+
+ return (chip_id == TEGRA_CHIPID_TEGRA19);
+}
+
/*
* Read the chip ID value and derive the platform
*/
@@ -259,3 +269,47 @@ bool tegra_platform_is_virt_dev_kit(void)
{
return ((tegra_get_platform() == TEGRA_PLATFORM_VIRT_DEV_KIT) ? true : false);
}
+
+/*
+ * This function returns soc version which mainly consist of below fields
+ *
+ * soc_version[30:24] = JEP-106 continuation code for the SiP
+ * soc_version[23:16] = JEP-106 identification code with parity bit for the SiP
+ * soc_version[0:15] = chip identification
+ */
+int32_t plat_get_soc_version(void)
+{
+ uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK);
+ uint32_t manfid = (JEDEC_NVIDIA_BKID << 24) | (JEDEC_NVIDIA_MFID << 16);
+
+ return (int32_t)(manfid | (chip_id & 0xFFFF));
+}
+
+/*
+ * This function returns soc revision in below format
+ *
+ * soc_revision[8:15] = major version number
+ * soc_revision[0:7] = minor version number
+ */
+int32_t plat_get_soc_revision(void)
+{
+ return (int32_t)((tegra_get_chipid_major() << 8) | tegra_get_chipid_minor());
+}
+
+/*****************************************************************************
+ * plat_is_smccc_feature_available() - This function checks whether SMCCC feature
+ * is availabile for the platform or not.
+ * @fid: SMCCC function id
+ *
+ * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
+ * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
+ *****************************************************************************/
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+ switch (fid) {
+ case SMCCC_ARCH_SOC_ID:
+ return SMC_ARCH_CALL_SUCCESS;
+ default:
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+ }
+}
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index 39dc42c5b..ec34a850d 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,104 +28,13 @@
extern uint64_t tegra_bl31_phys_base;
extern uint64_t tegra_sec_entry_point;
-/*
- * The following platform setup functions are weakly defined. They
- * provide typical implementations that will be overridden by a SoC.
- */
-#pragma weak tegra_soc_pwr_domain_suspend_pwrdown_early
-#pragma weak tegra_soc_cpu_standby
-#pragma weak tegra_soc_pwr_domain_suspend
-#pragma weak tegra_soc_pwr_domain_on
-#pragma weak tegra_soc_pwr_domain_off
-#pragma weak tegra_soc_pwr_domain_on_finish
-#pragma weak tegra_soc_pwr_domain_power_down_wfi
-#pragma weak tegra_soc_prepare_system_reset
-#pragma weak tegra_soc_prepare_system_off
-#pragma weak tegra_soc_get_target_pwr_state
-
-int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
-{
- return PSCI_E_NOT_SUPPORTED;
-}
-
-int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
-{
- (void)cpu_state;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
-{
- (void)target_state;
- return PSCI_E_NOT_SUPPORTED;
-}
-
-int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
-{
- (void)mpidr;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
-{
- (void)target_state;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
-{
- (void)target_state;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
-{
- (void)target_state;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_prepare_system_reset(void)
-{
- return PSCI_E_SUCCESS;
-}
-
-__dead2 void tegra_soc_prepare_system_off(void)
-{
- ERROR("Tegra System Off: operation not handled.\n");
- panic();
-}
-
-plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
- const plat_local_state_t *states,
- uint32_t ncpu)
-{
- plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
- uint32_t num_cpu = ncpu;
- const plat_local_state_t *local_state = states;
-
- (void)lvl;
-
- assert(ncpu != 0U);
-
- do {
- temp = *local_state;
- if ((temp < target)) {
- target = temp;
- }
- --num_cpu;
- local_state++;
- } while (num_cpu != 0U);
-
- return target;
-}
-
/*******************************************************************************
* This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND`
* call to get the `power_state` parameter. This allows the platform to encode
* the appropriate State-ID field within the `power_state` parameter which can
* be utilized in `pwr_domain_suspend()` to suspend to system affinity level.
******************************************************************************/
-void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
+static void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
{
/* all affinities use system suspend state id */
for (uint32_t i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -135,7 +45,7 @@ void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
/*******************************************************************************
* Handler called when an affinity instance is about to enter standby.
******************************************************************************/
-void tegra_cpu_standby(plat_local_state_t cpu_state)
+static void tegra_cpu_standby(plat_local_state_t cpu_state)
{
u_register_t saved_scr_el3;
@@ -174,7 +84,7 @@ void tegra_cpu_standby(plat_local_state_t cpu_state)
* Handler called when an affinity instance is about to be turned on. The
* level and mpidr determine the affinity instance.
******************************************************************************/
-int32_t tegra_pwr_domain_on(u_register_t mpidr)
+static int32_t tegra_pwr_domain_on(u_register_t mpidr)
{
return tegra_soc_pwr_domain_on(mpidr);
}
@@ -183,9 +93,12 @@ int32_t tegra_pwr_domain_on(u_register_t mpidr)
* Handler called when a power domain is about to be turned off. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
-void tegra_pwr_domain_off(const psci_power_state_t *target_state)
+static void tegra_pwr_domain_off(const psci_power_state_t *target_state)
{
(void)tegra_soc_pwr_domain_off(target_state);
+
+ /* disable GICC */
+ tegra_gic_cpuif_deactivate();
}
/*******************************************************************************
@@ -203,17 +116,10 @@ void tegra_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_sta
* Handler called when a power domain is about to be suspended. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
-void tegra_pwr_domain_suspend(const psci_power_state_t *target_state)
+static void tegra_pwr_domain_suspend(const psci_power_state_t *target_state)
{
(void)tegra_soc_pwr_domain_suspend(target_state);
- /* Disable console if we are entering deep sleep. */
- if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
- PSTATE_ID_SOC_POWERDN) {
- (void)console_flush();
- console_switch_state(0);
- }
-
/* disable GICC */
tegra_gic_cpuif_deactivate();
}
@@ -222,12 +128,20 @@ void tegra_pwr_domain_suspend(const psci_power_state_t *target_state)
* Handler called at the end of the power domain suspend sequence. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
-__dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t
+static __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t
*target_state)
{
/* call the chip's power down handler */
(void)tegra_soc_pwr_domain_power_down_wfi(target_state);
+ /* Disable console if we are entering deep sleep. */
+ if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
+ PSTATE_ID_SOC_POWERDN) {
+ INFO("%s: complete. Entering System Suspend...\n", __func__);
+ console_flush();
+ console_switch_state(0);
+ }
+
wfi();
panic();
}
@@ -237,21 +151,23 @@ __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t
* being turned off earlier. The target_state encodes the low power state that
* each level has woken up from.
******************************************************************************/
-void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
+static void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
const plat_params_from_bl2_t *plat_params;
/*
- * Initialize the GIC cpu and distributor interfaces
- */
- tegra_gic_pcpu_init();
-
- /*
* Check if we are exiting from deep sleep.
*/
if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
PSTATE_ID_SOC_POWERDN) {
+ /*
+ * On entering System Suspend state, the GIC loses power
+ * completely. Initialize the GIC global distributor and
+ * GIC cpu interfaces.
+ */
+ tegra_gic_init();
+
/* Restart console output. */
console_switch_state(CONSOLE_FLAG_RUNTIME);
@@ -268,11 +184,11 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
(uint32_t)plat_params->tzdram_size);
+ } else {
/*
- * Set up the TZRAM memory aperture to allow only secure world
- * access
+ * Initialize the GIC cpu and distributor interfaces
*/
- tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
+ tegra_gic_pcpu_init();
}
/*
@@ -286,7 +202,7 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
* having been suspended earlier. The target_state encodes the low power state
* that each level has woken up from.
******************************************************************************/
-void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
+static void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
{
tegra_pwr_domain_on_finish(target_state);
}
@@ -294,7 +210,7 @@ void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
/*******************************************************************************
* Handler called when the system wants to be powered off
******************************************************************************/
-__dead2 void tegra_system_off(void)
+static __dead2 void tegra_system_off(void)
{
INFO("Powering down system...\n");
@@ -304,23 +220,23 @@ __dead2 void tegra_system_off(void)
/*******************************************************************************
* Handler called when the system wants to be restarted.
******************************************************************************/
-__dead2 void tegra_system_reset(void)
+static __dead2 void tegra_system_reset(void)
{
INFO("Restarting system...\n");
/* per-SoC system reset handler */
(void)tegra_soc_prepare_system_reset();
- /*
- * Program the PMC in order to restart the system.
- */
- tegra_pmc_system_reset();
+ /* wait for the system to reset */
+ for (;;) {
+ ;
+ }
}
/*******************************************************************************
* Handler called to check the validity of the power state parameter.
******************************************************************************/
-int32_t tegra_validate_power_state(uint32_t power_state,
+static int32_t tegra_validate_power_state(uint32_t power_state,
psci_power_state_t *req_state)
{
assert(req_state != NULL);
@@ -331,7 +247,7 @@ int32_t tegra_validate_power_state(uint32_t power_state,
/*******************************************************************************
* Platform handler called to check the validity of the non secure entrypoint.
******************************************************************************/
-int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
+static int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
{
int32_t ret = PSCI_E_INVALID_ADDRESS;
@@ -349,7 +265,7 @@ int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
/*******************************************************************************
* Export the platform handlers to enable psci to invoke them
******************************************************************************/
-static const plat_psci_ops_t tegra_plat_psci_ops = {
+static plat_psci_ops_t tegra_plat_psci_ops = {
.cpu_standby = tegra_cpu_standby,
.pwr_domain_on = tegra_pwr_domain_on,
.pwr_domain_off = tegra_pwr_domain_off,
@@ -386,6 +302,14 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
(void)tegra_soc_pwr_domain_on_finish(&target_state);
/*
+ * Disable System Suspend if the platform does not
+ * support it
+ */
+ if (!plat_supports_system_suspend()) {
+ tegra_plat_psci_ops.get_sys_suspend_power_state = NULL;
+ }
+
+ /*
* Initialize PSCI ops struct
*/
*psci_ops = &tegra_plat_psci_ops;
diff --git a/plat/nvidia/tegra/common/tegra_sdei.c b/plat/nvidia/tegra/common/tegra_sdei.c
new file mode 100644
index 000000000..9241b8172
--- /dev/null
+++ b/plat/nvidia/tegra/common/tegra_sdei.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* SDEI configuration for Tegra platforms */
+
+#include <platform_def.h>
+
+#include <bl31/ehf.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <lib/utils_def.h>
+#include <services/sdei.h>
+
+/* Private event mappings */
+static sdei_ev_map_t tegra_sdei_private[] = {
+ /* Event 0 definition */
+ SDEI_DEFINE_EVENT_0(TEGRA_SDEI_SGI_PRIVATE),
+
+ /* Dynamic private events */
+ SDEI_PRIVATE_EVENT(TEGRA_SDEI_DP_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_PRIVATE_EVENT(TEGRA_SDEI_DP_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_PRIVATE_EVENT(TEGRA_SDEI_DP_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+
+ /* General purpose explicit events */
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_0, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_1, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_2, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_3, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_4, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_5, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_6, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_7, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_8, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_9, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_10, SDEI_MAPF_CRITICAL),
+ SDEI_EXPLICIT_EVENT(TEGRA_SDEI_EP_EVENT_11, SDEI_MAPF_CRITICAL)
+};
+
+/* Shared event mappings */
+static sdei_ev_map_t tegra_sdei_shared[] = {
+ /* Dynamic shared events */
+ SDEI_SHARED_EVENT(TEGRA_SDEI_DS_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_SHARED_EVENT(TEGRA_SDEI_DS_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_SHARED_EVENT(TEGRA_SDEI_DS_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
+};
+
+void plat_sdei_setup(void)
+{
+ INFO("SDEI platform setup\n");
+}
+
+/* Export Tegra SDEI events */
+REGISTER_SDEI_MAP(tegra_sdei_private, tegra_sdei_shared);
diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c
index b8ba09562..80a2c4d0c 100644
--- a/plat/nvidia/tegra/common/tegra_sip_calls.c
+++ b/plat/nvidia/tegra/common/tegra_sip_calls.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -26,32 +27,6 @@
#define TEGRA_SIP_FIQ_NS_GET_CONTEXT 0x82000006
/*******************************************************************************
- * SoC specific SiP handler
- ******************************************************************************/
-#pragma weak plat_sip_handler
-int32_t plat_sip_handler(uint32_t smc_fid,
- uint64_t x1,
- uint64_t x2,
- uint64_t x3,
- uint64_t x4,
- const void *cookie,
- void *handle,
- uint64_t flags)
-{
- /* unused parameters */
- (void)smc_fid;
- (void)x1;
- (void)x2;
- (void)x3;
- (void)x4;
- (void)cookie;
- (void)handle;
- (void)flags;
-
- return -ENOTSUP;
-}
-
-/*******************************************************************************
* This function is responsible for handling all SiP calls
******************************************************************************/
uintptr_t tegra_sip_handler(uint32_t smc_fid,
@@ -77,6 +52,12 @@ uintptr_t tegra_sip_handler(uint32_t smc_fid,
switch (smc_fid) {
case TEGRA_SIP_NEW_VIDEOMEM_REGION:
+ /* Check whether Video memory resize is enabled */
+ if (mmio_read_32(TEGRA_MC_BASE + MC_VIDEO_PROTECT_REG_CTRL)
+ != MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED) {
+ ERROR("Video Memory Resize isn't enabled! \n");
+ SMC_RET1(handle, (uint64_t)-ENOTSUP);
+ }
/*
* Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
diff --git a/plat/nvidia/tegra/common/tegra_stack_protector.c b/plat/nvidia/tegra/common/tegra_stack_protector.c
new file mode 100644
index 000000000..f6c459a8e
--- /dev/null
+++ b/plat/nvidia/tegra/common/tegra_stack_protector.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ u_register_t seed;
+
+ /*
+ * Ideally, a random number should be returned instead. As the
+ * platform does not have any random number generator, this is
+ * better than nothing, but not really secure.
+ */
+ seed = mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET);
+ seed <<= 32;
+ seed |= mmio_read_32(TEGRA_TMRUS_BASE);
+
+ return seed ^ read_cntpct_el0();
+}
diff --git a/plat/nvidia/tegra/common/tegra_topology.c b/plat/nvidia/tegra/common/tegra_topology.c
deleted file mode 100644
index 205b05165..000000000
--- a/plat/nvidia/tegra/common/tegra_topology.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <arch.h>
-#include <lib/psci/psci.h>
-#include <plat/common/platform.h>
-
-#pragma weak plat_core_pos_by_mpidr
-
-/*******************************************************************************
- * This function implements a part of the critical interface between the psci
- * generic layer and the platform that allows the former to query the platform
- * to convert an MPIDR to a unique linear index. An error code (-1) is returned
- * in case the MPIDR is invalid.
- ******************************************************************************/
-int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
-{
- u_register_t cluster_id, cpu_id;
- int32_t result;
-
- cluster_id = (mpidr >> (u_register_t)MPIDR_AFF1_SHIFT) &
- (u_register_t)MPIDR_AFFLVL_MASK;
- cpu_id = (mpidr >> (u_register_t)MPIDR_AFF0_SHIFT) &
- (u_register_t)MPIDR_AFFLVL_MASK;
-
- /* CorePos = CoreId + (ClusterId * cpus per cluster) */
- result = (int32_t)cpu_id + ((int32_t)cluster_id *
- PLATFORM_MAX_CPUS_PER_CLUSTER);
-
- if (cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) {
- result = PSCI_E_NOT_PRESENT;
- }
-
- /*
- * Validate cpu_id by checking whether it represents a CPU in
- * one of the two clusters present on the platform.
- */
- if (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER) {
- result = PSCI_E_NOT_PRESENT;
- }
-
- return result;
-}
diff --git a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c b/plat/nvidia/tegra/drivers/bpmp/bpmp.c
index d7db604cc..d7db604cc 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
+++ b/plat/nvidia/tegra/drivers/bpmp/bpmp.c
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/drivers/bpmp_ipc/intf.c
index ae899c424..2e90d2547 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
+++ b/plat/nvidia/tegra/drivers/bpmp_ipc/intf.c
@@ -175,44 +175,39 @@ static int32_t tegra_bpmp_ipc_send_req_atomic(uint32_t mrq, void *p_out,
if ((p_out == NULL) || (size_out > IVC_DATA_SZ_BYTES) ||
(frame == NULL)) {
ERROR("%s: invalid parameters, exiting\n", __func__);
- ret = -EINVAL;
+ return -EINVAL;
}
- if (ret == 0) {
-
- /* prepare the command frame */
- frame->mrq = mrq;
- frame->flags = FLAG_DO_ACK;
- p_fdata = frame->data;
- (void)memcpy(p_fdata, p_out, (size_t)size_out);
+ /* prepare the command frame */
+ frame->mrq = mrq;
+ frame->flags = FLAG_DO_ACK;
+ p_fdata = frame->data;
+ (void)memcpy(p_fdata, p_out, (size_t)size_out);
- /* signal the slave */
- tegra_bpmp_signal_slave();
+ /* signal the slave */
+ tegra_bpmp_signal_slave();
- /* wait for slave to ack */
- ret = tegra_bpmp_wait_for_slave_ack();
- if (ret != 0) {
- ERROR("failed waiting for the slave to ack\n");
- }
+ /* wait for slave to ack */
+ ret = tegra_bpmp_wait_for_slave_ack();
+ if (ret < 0) {
+ ERROR("%s: wait for slave failed (%d)\n", __func__, ret);
+ return ret;
+ }
- /* retrieve the response frame */
- if ((size_in <= IVC_DATA_SZ_BYTES) && (p_in != NULL) &&
- (ret == 0)) {
+ /* retrieve the response frame */
+ if ((size_in <= IVC_DATA_SZ_BYTES) && (p_in != NULL)) {
- f_in = tegra_bpmp_get_cur_in_frame();
- if (f_in != NULL) {
- ERROR("Failed to get next input frame!\n");
- } else {
- (void)memcpy(p_in, p_fdata, (size_t)size_in);
- }
+ f_in = tegra_bpmp_get_cur_in_frame();
+ if (f_in != NULL) {
+ ERROR("Failed to get next input frame!\n");
+ } else {
+ (void)memcpy(p_in, p_fdata, (size_t)size_in);
}
+ }
- if (ret == 0) {
- ret = tegra_bpmp_free_master();
- if (ret != 0) {
- ERROR("Failed to free master\n");
- }
- }
+ ret = tegra_bpmp_free_master();
+ if (ret < 0) {
+ ERROR("%s: free master failed (%d)\n", __func__, ret);
}
return ret;
@@ -316,7 +311,7 @@ int tegra_bpmp_ipc_enable_clock(uint32_t clk_id)
/* prepare the MRQ_CLK command */
req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_ENABLE, clk_id);
- ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req),
+ ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req),
NULL, 0);
if (ret != 0) {
ERROR("%s: failed for module %d with error %d\n", __func__,
@@ -339,7 +334,7 @@ int tegra_bpmp_ipc_disable_clock(uint32_t clk_id)
/* prepare the MRQ_CLK command */
req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_DISABLE, clk_id);
- ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req),
+ ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req),
NULL, 0);
if (ret != 0) {
ERROR("%s: failed for module %d with error %d\n", __func__,
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/drivers/bpmp_ipc/intf.h
index 7059c3701..d85b906b8 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
+++ b/plat/nvidia/tegra/drivers/bpmp_ipc/intf.h
@@ -1,17 +1,17 @@
/*
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef INTF_H
-#define INTF_H
+#ifndef BPMP_INTF_H
+#define BPMP_INTF_H
/**
* Flags used in IPC req
*/
#define FLAG_DO_ACK (U(1) << 0)
-#define FLAG_RING_DOORBELL (U(1) << 1)
+#define FLAG_RING_DOORBELL (U(1) << 1)
/* Bit 1 is designated for CCPlex in secure world */
#define HSP_MASTER_CCPLEX_BIT (U(1) << 1)
@@ -77,16 +77,16 @@ struct __attribute__((packed)) mrq_reset_request {
*
*/
enum {
- CMD_CLK_GET_RATE = 1,
- CMD_CLK_SET_RATE = 2,
- CMD_CLK_ROUND_RATE = 3,
- CMD_CLK_GET_PARENT = 4,
- CMD_CLK_SET_PARENT = 5,
- CMD_CLK_IS_ENABLED = 6,
- CMD_CLK_ENABLE = 7,
- CMD_CLK_DISABLE = 8,
- CMD_CLK_GET_ALL_INFO = 14,
- CMD_CLK_GET_MAX_CLK_ID = 15,
+ CMD_CLK_GET_RATE = U(1),
+ CMD_CLK_SET_RATE = U(2),
+ CMD_CLK_ROUND_RATE = U(3),
+ CMD_CLK_GET_PARENT = U(4),
+ CMD_CLK_SET_PARENT = U(5),
+ CMD_CLK_IS_ENABLED = U(6),
+ CMD_CLK_ENABLE = U(7),
+ CMD_CLK_DISABLE = U(8),
+ CMD_CLK_GET_ALL_INFO = U(14),
+ CMD_CLK_GET_MAX_CLK_ID = U(15),
CMD_CLK_MAX,
};
@@ -124,4 +124,4 @@ struct mrq_clk_request {
*/
#define make_mrq_clk_cmd(cmd, id) (((cmd) << 24) | (id & 0xFFFFFF))
-#endif /* INTF_H */
+#endif /* BPMP_INTF_H */
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c b/plat/nvidia/tegra/drivers/bpmp_ipc/ivc.c
index 57daf6aeb..d964fc001 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c
+++ b/plat/nvidia/tegra/drivers/bpmp_ipc/ivc.c
@@ -8,6 +8,7 @@
#include <assert.h>
#include <common/debug.h>
#include <errno.h>
+#include <stdbool.h>
#include <stddef.h>
#include <string.h>
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/drivers/bpmp_ipc/ivc.h
index 42e6a1f7c..1b318213b 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
+++ b/plat/nvidia/tegra/drivers/bpmp_ipc/ivc.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef IVC_H
-#define IVC_H
+#ifndef BPMP_IVC_H
+#define BPMP_IVC_H
#include <lib/utils_def.h>
#include <stdint.h>
@@ -15,22 +15,21 @@
#define IVC_CHHDR_TX_FIELDS U(16)
#define IVC_CHHDR_RX_FIELDS U(16)
-struct ivc;
struct ivc_channel_header;
-/* callback handler for notify on receiving a response */
-typedef void (* ivc_notify_function)(const struct ivc *);
-
struct ivc {
struct ivc_channel_header *rx_channel;
struct ivc_channel_header *tx_channel;
uint32_t w_pos;
uint32_t r_pos;
- ivc_notify_function notify;
+ void (*notify)(const struct ivc *);
uint32_t nframes;
uint32_t frame_size;
};
+/* callback handler for notify on receiving a response */
+typedef void (* ivc_notify_function)(const struct ivc *);
+
int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base,
uint32_t nframes, uint32_t frame_size,
ivc_notify_function notify);
@@ -48,4 +47,4 @@ bool tegra_ivc_tx_empty(const struct ivc *ivc);
bool tegra_ivc_can_write(const struct ivc *ivc);
bool tegra_ivc_can_read(const struct ivc *ivc);
-#endif /* IVC_H */
+#endif /* BPMP_IVC_H */
diff --git a/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c b/plat/nvidia/tegra/drivers/flowctrl/flowctrl.c
index 8f5555459..8f5555459 100644
--- a/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c
+++ b/plat/nvidia/tegra/drivers/flowctrl/flowctrl.c
diff --git a/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c b/plat/nvidia/tegra/drivers/gpcdma/gpcdma.c
index d68cdfd4b..d68cdfd4b 100644
--- a/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c
+++ b/plat/nvidia/tegra/drivers/gpcdma/gpcdma.c
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c b/plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c
index 92fa273b5..b3dcd2a4b 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
+++ b/plat/nvidia/tegra/drivers/memctrl/memctrl_v1.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -92,20 +93,6 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
}
-/*
- * Secure the BL31 TZRAM aperture.
- *
- * phys_base = physical base of TZRAM aperture
- * size_in_bytes = size of aperture in bytes
- */
-void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
-{
- /*
- * The v1 hardware controller does not have any registers
- * for setting up the on-chip TZRAM.
- */
-}
-
static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
unsigned long long non_overlap_area_size)
{
@@ -117,7 +104,8 @@ static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */
non_overlap_area_start, /* VA */
non_overlap_area_size, /* size */
- MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */
+ MT_NS | MT_RW | MT_EXECUTE_NEVER |
+ MT_NON_CACHEABLE); /* attrs */
assert(ret == 0);
zeromem((void *)non_overlap_area_start, non_overlap_area_size);
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c
index 2f31906d8..92120b527 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,59 +21,24 @@
#include <smmu.h>
#include <tegra_def.h>
#include <tegra_platform.h>
+#include <tegra_private.h>
/* Video Memory base and size (live values) */
static uint64_t video_mem_base;
static uint64_t video_mem_size_mb;
/*
- * The following platform setup functions are weakly defined. They
- * provide typical implementations that will be overridden by a SoC.
- */
-#pragma weak plat_memctrl_tzdram_setup
-
-void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
-{
- ; /* do nothing */
-}
-
-/*
* Init Memory controller during boot.
*/
void tegra_memctrl_setup(void)
{
- uint32_t val;
- const uint32_t *mc_streamid_override_regs;
- uint32_t num_streamid_override_regs;
- const mc_streamid_security_cfg_t *mc_streamid_sec_cfgs;
- uint32_t num_streamid_sec_cfgs;
- const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
- uint32_t i;
-
INFO("Tegra Memory Controller (v2)\n");
- /* Program the SMMU pagesize */
+ /* Initialize the System memory management unit */
tegra_smmu_init();
- /* Get the settings from the platform */
- assert(plat_mc_settings != NULL);
- mc_streamid_override_regs = plat_mc_settings->streamid_override_cfg;
- num_streamid_override_regs = plat_mc_settings->num_streamid_override_cfgs;
- mc_streamid_sec_cfgs = plat_mc_settings->streamid_security_cfg;
- num_streamid_sec_cfgs = plat_mc_settings->num_streamid_security_cfgs;
-
- /* Program all the Stream ID overrides */
- for (i = 0; i < num_streamid_override_regs; i++)
- tegra_mc_streamid_write_32(mc_streamid_override_regs[i],
- MC_STREAM_ID_MAX);
-
- /* Program the security config settings for all Stream IDs */
- for (i = 0; i < num_streamid_sec_cfgs; i++) {
- val = mc_streamid_sec_cfgs[i].override_enable << 16 |
- mc_streamid_sec_cfgs[i].override_client_inputs << 8 |
- mc_streamid_sec_cfgs[i].override_client_ns_flag << 0;
- tegra_mc_streamid_write_32(mc_streamid_sec_cfgs[i].offset, val);
- }
+ /* allow platforms to program custom memory controller settings */
+ plat_memctrl_setup();
/*
* All requests at boot time, and certain requests during
@@ -90,21 +55,6 @@ void tegra_memctrl_setup(void)
*/
tegra_mc_write_32(MC_SMMU_BYPASS_CONFIG,
MC_SMMU_BYPASS_CONFIG_SETTINGS);
-
- /*
- * Re-configure MSS to allow ROC to deal with ordering of the
- * Memory Controller traffic. This is needed as the Memory Controller
- * boots with MSS having all control, but ROC provides a performance
- * boost as compared to MSS.
- */
- if (plat_mc_settings->reconfig_mss_clients != NULL) {
- plat_mc_settings->reconfig_mss_clients();
- }
-
- /* Program overrides for MC transactions */
- if (plat_mc_settings->set_txn_overrides != NULL) {
- plat_mc_settings->set_txn_overrides();
- }
}
/*
@@ -112,32 +62,23 @@ void tegra_memctrl_setup(void)
*/
void tegra_memctrl_restore_settings(void)
{
- const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
-
- assert(plat_mc_settings != NULL);
-
- /*
- * Re-configure MSS to allow ROC to deal with ordering of the
- * Memory Controller traffic. This is needed as the Memory Controller
- * resets during System Suspend with MSS having all control, but ROC
- * provides a performance boost as compared to MSS.
- */
- if (plat_mc_settings->reconfig_mss_clients != NULL) {
- plat_mc_settings->reconfig_mss_clients();
- }
-
- /* Program overrides for MC transactions */
- if (plat_mc_settings->set_txn_overrides != NULL) {
- plat_mc_settings->set_txn_overrides();
- }
+ /* restore platform's memory controller settings */
+ plat_memctrl_restore();
/* video memory carveout region */
if (video_mem_base != 0ULL) {
tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO,
(uint32_t)video_mem_base);
+ assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_LO)
+ == (uint32_t)video_mem_base);
tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
(uint32_t)(video_mem_base >> 32));
- tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size_mb);
+ assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_HI)
+ == (uint32_t)(video_mem_base >> 32));
+ tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB,
+ (uint32_t)video_mem_size_mb);
+ assert(tegra_mc_read_32(MC_VIDEO_PROTECT_SIZE_MB)
+ == (uint32_t)video_mem_size_mb);
/*
* MCE propagates the VideoMem configuration values across the
@@ -169,69 +110,62 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
*/
void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
{
- uint32_t index;
- uint32_t total_128kb_blocks = size_in_bytes >> 17;
- uint32_t residual_4kb_blocks = (size_in_bytes & (uint32_t)0x1FFFF) >> 12;
- uint32_t val;
+ ; /* do nothing */
+}
- INFO("Configuring TrustZone SRAM Memory Carveout\n");
+/*
+ * Save MC settings before "System Suspend" to TZDRAM
+ */
+void tegra_mc_save_context(uint64_t mc_ctx_addr)
+{
+ uint32_t i, num_entries = 0;
+ mc_regs_t *mc_ctx_regs;
+ const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+ uint64_t tzdram_base = params_from_bl2->tzdram_base;
+ uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size;
- /*
- * Reset the access configuration registers to restrict access
- * to the TZRAM aperture
- */
- for (index = MC_TZRAM_CLIENT_ACCESS0_CFG0;
- index < ((uint32_t)MC_TZRAM_CARVEOUT_CFG + (uint32_t)MC_GSC_CONFIG_REGS_SIZE);
- index += 4U) {
- tegra_mc_write_32(index, 0);
- }
+ assert((mc_ctx_addr >= tzdram_base) && (mc_ctx_addr <= tzdram_end));
- /*
- * Enable CPU access configuration registers to access the TZRAM aperture
- */
- if (!tegra_chipid_is_t186()) {
- val = tegra_mc_read_32(MC_TZRAM_CLIENT_ACCESS1_CFG0);
- val |= TZRAM_ALLOW_MPCORER | TZRAM_ALLOW_MPCOREW;
- tegra_mc_write_32(MC_TZRAM_CLIENT_ACCESS1_CFG0, val);
- }
+ /* get MC context table */
+ mc_ctx_regs = plat_memctrl_get_sys_suspend_ctx();
+ assert(mc_ctx_regs != NULL);
/*
- * Set the TZRAM base. TZRAM base must be 4k aligned, at least.
+ * mc_ctx_regs[0].val contains the size of the context table minus
+ * the last entry. Sanity check the table size before we start with
+ * the context save operation.
*/
- assert((phys_base & (uint64_t)0xFFF) == 0U);
- tegra_mc_write_32(MC_TZRAM_BASE_LO, (uint32_t)phys_base);
- tegra_mc_write_32(MC_TZRAM_BASE_HI,
- (uint32_t)(phys_base >> 32) & MC_GSC_BASE_HI_MASK);
+ while (mc_ctx_regs[num_entries].reg != 0xFFFFFFFFU) {
+ num_entries++;
+ }
- /*
- * Set the TZRAM size
- *
- * total size = (number of 128KB blocks) + (number of remaining 4KB
- * blocks)
- *
- */
- val = (residual_4kb_blocks << MC_GSC_SIZE_RANGE_4KB_SHIFT) |
- total_128kb_blocks;
- tegra_mc_write_32(MC_TZRAM_SIZE, val);
+ /* panic if the sizes do not match */
+ if (num_entries != mc_ctx_regs[0].val) {
+ ERROR("MC context size mismatch!");
+ panic();
+ }
- /*
- * Lock the configuration settings by disabling TZ-only lock
- * and locking the configuration against any future changes
- * at all.
- */
- val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG);
- val &= (uint32_t)~MC_GSC_ENABLE_TZ_LOCK_BIT;
- val |= MC_GSC_LOCK_CFG_SETTINGS_BIT;
- if (!tegra_chipid_is_t186()) {
- val |= MC_GSC_ENABLE_CPU_SECURE_BIT;
+ /* save MC register values */
+ for (i = 1U; i < num_entries; i++) {
+ mc_ctx_regs[i].val = mmio_read_32(mc_ctx_regs[i].reg);
}
- tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val);
- /*
- * MCE propagates the security configuration values across the
- * CCPLEX.
- */
- mce_update_gsc_tzram();
+ /* increment by 1 to take care of the last entry */
+ num_entries++;
+
+ /* Save MC config settings */
+ (void)memcpy((void *)mc_ctx_addr, mc_ctx_regs,
+ sizeof(mc_regs_t) * num_entries);
+
+ /* save the MC table address */
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_LO,
+ (uint32_t)mc_ctx_addr);
+ assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_LO)
+ == (uint32_t)mc_ctx_addr);
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_HI,
+ (uint32_t)(mc_ctx_addr >> 32));
+ assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_HI)
+ == (uint32_t)(mc_ctx_addr >> 32));
}
static void tegra_lock_videomem_nonoverlap(uint64_t phys_base,
@@ -300,56 +234,33 @@ static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
{
int ret;
+ INFO("Cleaning previous Video Memory Carveout\n");
+
/*
* Map the NS memory first, clean it and then unmap it.
*/
ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */
non_overlap_area_start, /* VA */
non_overlap_area_size, /* size */
- MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */
+ MT_DEVICE | MT_RW | MT_NS); /* attrs */
assert(ret == 0);
- zero_normalmem((void *)non_overlap_area_start, non_overlap_area_size);
+ zeromem((void *)non_overlap_area_start, non_overlap_area_size);
flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
- (void)mmap_remove_dynamic_region(non_overlap_area_start,
+ ret = mmap_remove_dynamic_region(non_overlap_area_start,
non_overlap_area_size);
+ assert(ret == 0);
}
-/*
- * Program the Video Memory carveout region
- *
- * phys_base = physical base of aperture
- * size_in_bytes = size of aperture in bytes
- */
-void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
+static void tegra_clear_videomem_nonoverlap(uintptr_t phys_base,
+ unsigned long size_in_bytes)
{
uintptr_t vmem_end_old = video_mem_base + (video_mem_size_mb << 20);
uintptr_t vmem_end_new = phys_base + size_in_bytes;
unsigned long long non_overlap_area_size;
/*
- * Setup the Memory controller to restrict CPU accesses to the Video
- * Memory region
- */
- INFO("Configuring Video Memory Carveout\n");
-
- /*
- * Configure Memory Controller directly for the first time.
- */
- if (video_mem_base == 0U)
- goto done;
-
- /*
- * Lock the non overlapping memory being cleared so that other masters
- * do not accidently write to it. The memory would be unlocked once
- * the non overlapping region is cleared and the new memory
- * settings take effect.
- */
- tegra_lock_videomem_nonoverlap(video_mem_base,
- video_mem_size_mb << 20);
-
- /*
* Clear the old regions now being exposed. The following cases
* can occur -
*
@@ -357,8 +268,6 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
* 2. clear old sub-region below new base
* 3. clear old sub-region above new end
*/
- INFO("Cleaning previous Video Memory Carveout\n");
-
if ((phys_base > vmem_end_old) || (video_mem_base > vmem_end_new)) {
tegra_clear_videomem(video_mem_base,
video_mem_size_mb << 20U);
@@ -372,26 +281,63 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
tegra_clear_videomem(vmem_end_new, non_overlap_area_size);
}
}
+}
+
+/*
+ * Program the Video Memory carveout region
+ *
+ * phys_base = physical base of aperture
+ * size_in_bytes = size of aperture in bytes
+ */
+void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
+{
+ /*
+ * Setup the Memory controller to restrict CPU accesses to the Video
+ * Memory region
+ */
+
+ INFO("Configuring Video Memory Carveout\n");
+
+ if (video_mem_base != 0U) {
+ /*
+ * Lock the non overlapping memory being cleared so that
+ * other masters do not accidently write to it. The memory
+ * would be unlocked once the non overlapping region is
+ * cleared and the new memory settings take effect.
+ */
+ tegra_lock_videomem_nonoverlap(video_mem_base,
+ video_mem_size_mb << 20);
+ }
-done:
/* program the Videomem aperture */
tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base);
tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
(uint32_t)(phys_base >> 32));
tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20);
- /* unlock the previous locked nonoverlapping aperture */
- tegra_unlock_videomem_nonoverlap();
-
- /* store new values */
- video_mem_base = phys_base;
- video_mem_size_mb = size_in_bytes >> 20;
+ /* Redundancy check for Video Protect setting */
+ assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_LO)
+ == (uint32_t)phys_base);
+ assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_HI)
+ == (uint32_t)(phys_base >> 32));
+ assert(tegra_mc_read_32(MC_VIDEO_PROTECT_SIZE_MB)
+ == (size_in_bytes >> 20));
/*
* MCE propagates the VideoMem configuration values across the
* CCPLEX.
*/
- mce_update_gsc_videomem();
+ (void)mce_update_gsc_videomem();
+
+ /* Clear the non-overlapping memory */
+ if (video_mem_base != 0U) {
+ tegra_clear_videomem_nonoverlap(phys_base, size_in_bytes);
+ tegra_unlock_videomem_nonoverlap();
+ }
+
+ /* store new values */
+ video_mem_base = phys_base;
+ video_mem_size_mb = (uint64_t)size_in_bytes >> 20;
}
/*
diff --git a/plat/nvidia/tegra/common/drivers/pmc/pmc.c b/plat/nvidia/tegra/drivers/pmc/pmc.c
index 6c5a73baf..6c5a73baf 100644
--- a/plat/nvidia/tegra/common/drivers/pmc/pmc.c
+++ b/plat/nvidia/tegra/drivers/pmc/pmc.c
diff --git a/plat/nvidia/tegra/drivers/smmu/smmu.c b/plat/nvidia/tegra/drivers/smmu/smmu.c
new file mode 100644
index 000000000..4189b00b1
--- /dev/null
+++ b/plat/nvidia/tegra/drivers/smmu/smmu.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <platform_def.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+
+#include <smmu.h>
+#include <tegra_platform.h>
+#include <tegra_private.h>
+
+extern void memcpy16(void *dest, const void *src, unsigned int length);
+
+#define SMMU_NUM_CONTEXTS 64U
+#define SMMU_CONTEXT_BANK_MAX_IDX 64U
+
+#define MISMATCH_DETECTED 0x55AA55AAU
+
+/*
+ * Init SMMU during boot or "System Suspend" exit
+ */
+void tegra_smmu_init(void)
+{
+ uint32_t val, cb_idx, smmu_id, ctx_base;
+ uint32_t num_smmu_devices = plat_get_num_smmu_devices();
+
+ for (smmu_id = 0U; smmu_id < num_smmu_devices; smmu_id++) {
+ /* Program the SMMU pagesize and reset CACHE_LOCK bit */
+ val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
+ val |= SMMU_GSR0_PGSIZE_64K;
+ val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+ tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
+
+ /* reset CACHE LOCK bit for NS Aux. Config. Register */
+ val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
+ val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+ tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
+
+ /* disable TCU prefetch for all contexts */
+ ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS)
+ + SMMU_CBn_ACTLR;
+ for (cb_idx = 0U; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
+ val = tegra_smmu_read_32(smmu_id,
+ ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx));
+ val &= (uint32_t)~SMMU_CBn_ACTLR_CPRE_BIT;
+ tegra_smmu_write_32(smmu_id, ctx_base +
+ (SMMU_GSR0_PGSIZE_64K * cb_idx), val);
+ }
+
+ /* set CACHE LOCK bit for NS Aux. Config. Register */
+ val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
+ val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+ tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
+
+ /* set CACHE LOCK bit for S Aux. Config. Register */
+ val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
+ val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+ tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
+ }
+}
+
+/*
+ * Verify SMMU settings have not been altered during boot
+ */
+void tegra_smmu_verify(void)
+{
+ uint32_t cb_idx, ctx_base, smmu_id, val;
+ uint32_t num_smmu_devices = plat_get_num_smmu_devices();
+ uint32_t mismatch = 0U;
+
+ for (smmu_id = 0U; smmu_id < num_smmu_devices; smmu_id++) {
+ /* check PGSIZE_64K bit inr S Aux. Config. Register */
+ val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
+ if (0U == (val & SMMU_GSR0_PGSIZE_64K)) {
+ ERROR("%s: PGSIZE_64K Mismatch - smmu_id=%d, GSR0_SECURE_ACR=%x\n",
+ __func__, smmu_id, val);
+ mismatch = MISMATCH_DETECTED;
+ }
+
+ /* check CACHE LOCK bit in S Aux. Config. Register */
+ if (0U == (val & SMMU_ACR_CACHE_LOCK_ENABLE_BIT)) {
+ ERROR("%s: CACHE_LOCK Mismatch - smmu_id=%d, GSR0_SECURE_ACR=%x\n",
+ __func__, smmu_id, val);
+ mismatch = MISMATCH_DETECTED;
+ }
+
+ /* check CACHE LOCK bit in NS Aux. Config. Register */
+ val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
+ if (0U == (val & SMMU_ACR_CACHE_LOCK_ENABLE_BIT)) {
+ ERROR("%s: Mismatch - smmu_id=%d, GNSR_ACR=%x\n",
+ __func__, smmu_id, val);
+ mismatch = MISMATCH_DETECTED;
+ }
+
+ /* verify TCU prefetch for all contexts is disabled */
+ ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) +
+ SMMU_CBn_ACTLR;
+ for (cb_idx = 0U; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
+ val = tegra_smmu_read_32(smmu_id,
+ ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx));
+ if (0U != (val & SMMU_CBn_ACTLR_CPRE_BIT)) {
+ ERROR("%s: Mismatch - smmu_id=%d, cb_idx=%d, GSR0_PGSIZE_64K=%x\n",
+ __func__, smmu_id, cb_idx, val);
+ mismatch = MISMATCH_DETECTED;
+ }
+ }
+ }
+
+ /* Treat configuration mismatch as fatal */
+ if ((mismatch == MISMATCH_DETECTED) && tegra_platform_is_silicon()) {
+ panic();
+ }
+}
diff --git a/plat/nvidia/tegra/common/drivers/spe/shared_console.S b/plat/nvidia/tegra/drivers/spe/shared_console.S
index a3e110ec9..d1b18dd44 100644
--- a/plat/nvidia/tegra/common/drivers/spe/shared_console.S
+++ b/plat/nvidia/tegra/drivers/spe/shared_console.S
@@ -1,16 +1,18 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
+#include <assert_macros.S>
#include <console_macros.S>
#define CONSOLE_NUM_BYTES_SHIFT 24
#define CONSOLE_FLUSH_DATA_TO_PORT (1 << 26)
#define CONSOLE_RING_DOORBELL (1 << 31)
#define CONSOLE_IS_BUSY (1 << 31)
-#define CONSOLE_WRITE (CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT)
+#define CONSOLE_TIMEOUT 0xC000 /* 50 ms */
/*
* This file contains a driver implementation to make use of the
@@ -30,24 +32,44 @@
.globl console_spe_flush
.globl console_spe_register
+.macro check_if_console_is_ready base, tmp1, tmp2, label
+ /* wait until spe is ready or timeout expires */
+ mrs \tmp2, cntps_tval_el1
+1: ldr \tmp1, [\base]
+ and \tmp1, \tmp1, #CONSOLE_IS_BUSY
+ cbz \tmp1, 2f
+ mrs \tmp1, cntps_tval_el1
+ sub \tmp1, \tmp2, \tmp1
+ cmp \tmp1, #CONSOLE_TIMEOUT
+ b.lt 1b
+ b \label
+2:
+.endm
+
/* -------------------------------------------------
* int console_spe_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
- * console_spe_t *console);
+ * console_t *console);
* Function to initialize and register a new spe
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
- * x3 - pointer to empty console_spe_t struct
+ * x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -------------------------------------------------
*/
func console_spe_register
+ /* Check the input base address */
+ cbz x0, register_fail
+
+ /* Dont use clock or baud rate, so ok to overwrite them */
+ check_if_console_is_ready x0, x1, x2, register_fail
+
cbz x3, register_fail
- str x0, [x3, #CONSOLE_T_DRVDATA]
+ str x0, [x3, #CONSOLE_T_BASE]
mov x0, x3
finish_console_register spe putc=1, getc=1, flush=1
@@ -63,7 +85,7 @@ endfunc console_spe_register
* In : w0 - character to be printed
* x1 - console base address
* Out : return -1 on error else return character.
- * Clobber list : x2
+ * Clobber list : x2, x3
* --------------------------------------------------------
*/
func console_spe_core_putc
@@ -72,29 +94,24 @@ func console_spe_core_putc
/* Prepend '\r' to '\n' */
cmp w0, #0xA
- b.ne 2f
+ b.ne not_eol
- /* wait until spe is ready */
-1: ldr w2, [x1]
- and w2, w2, #CONSOLE_IS_BUSY
- cbnz w2, 1b
+ check_if_console_is_ready x1, x2, x3, putc_error
/* spe is ready */
mov w2, #0xD /* '\r' */
and w2, w2, #0xFF
- mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT))
+ mov w3, #(CONSOLE_RING_DOORBELL | (1 << CONSOLE_NUM_BYTES_SHIFT))
orr w2, w2, w3
str w2, [x1]
- /* wait until spe is ready */
-2: ldr w2, [x1]
- and w2, w2, #CONSOLE_IS_BUSY
- cbnz w2, 2b
+not_eol:
+ check_if_console_is_ready x1, x2, x3, putc_error
/* spe is ready */
mov w2, w0
and w2, w2, #0xFF
- mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT))
+ mov w3, #(CONSOLE_RING_DOORBELL | (1 << CONSOLE_NUM_BYTES_SHIFT))
orr w2, w2, w3
str w2, [x1]
@@ -105,7 +122,7 @@ putc_error:
endfunc console_spe_core_putc
/* --------------------------------------------------------
- * int console_spe_putc(int c, console_spe_t *console)
+ * int console_spe_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
@@ -115,12 +132,12 @@ endfunc console_spe_core_putc
* --------------------------------------------------------
*/
func console_spe_putc
- ldr x1, [x1, #CONSOLE_T_DRVDATA]
+ ldr x1, [x1, #CONSOLE_T_BASE]
b console_spe_core_putc
endfunc console_spe_putc
/* ---------------------------------------------
- * int console_spe_getc(console_spe_t *console)
+ * int console_spe_getc(console_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 if no character is available.
@@ -135,37 +152,36 @@ func console_spe_getc
endfunc console_spe_getc
/* -------------------------------------------------
- * int console_spe_core_flush(uintptr_t base_addr)
+ * void console_spe_core_flush(uintptr_t base_addr)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - console base address
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : x0, x1
* -------------------------------------------------
*/
func console_spe_core_flush
- cbz x0, flush_error
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
/* flush console */
- mov w1, #CONSOLE_WRITE
+ mov w1, #(CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT)
str w1, [x0]
- mov w0, #0
- ret
-flush_error:
- mov w0, #-1
ret
endfunc console_spe_core_flush
/* ---------------------------------------------
- * int console_spe_flush(console_spe_t *console)
+ * void console_spe_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - pointer to console_t structure
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : x0, x1
* ---------------------------------------------
*/
func console_spe_flush
- ldr x0, [x0, #CONSOLE_T_DRVDATA]
+ ldr x0, [x0, #CONSOLE_T_BASE]
b console_spe_core_flush
endfunc console_spe_flush
diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
index a0d02c949..401a07a24 100644
--- a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
+++ b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
@@ -19,11 +19,6 @@
#define TEGRA_RESET_ID_GPCDMA U(70)
/**
- * Clock identifier for the SE device
- */
-#define TEGRA_CLK_SE U(124)
-
-/**
* Function to initialise the IPC with the bpmp
*/
int32_t tegra_bpmp_ipc_init(void);
diff --git a/plat/nvidia/tegra/include/drivers/flowctrl.h b/plat/nvidia/tegra/include/drivers/flowctrl.h
index 54336b044..e5ab600b4 100644
--- a/plat/nvidia/tegra/include/drivers/flowctrl.h
+++ b/plat/nvidia/tegra/include/drivers/flowctrl.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +10,8 @@
#include <lib/mmio.h>
+#include <stdbool.h>
+
#include <tegra_def.h>
#define FLOWCTRL_HALT_CPU0_EVENTS (0x0U)
diff --git a/plat/nvidia/tegra/include/drivers/mce.h b/plat/nvidia/tegra/include/drivers/mce.h
index 4470b6b8b..5f1bb4f28 100644
--- a/plat/nvidia/tegra/include/drivers/mce.h
+++ b/plat/nvidia/tegra/include/drivers/mce.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -69,7 +69,6 @@ int mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
int mce_update_reset_vector(void);
int mce_update_gsc_videomem(void);
int mce_update_gsc_tzdram(void);
-int mce_update_gsc_tzram(void);
__dead2 void mce_enter_ccplex_state(uint32_t state_idx);
void mce_update_cstate_info(const mce_cstate_info_t *cstate);
void mce_verify_firmware_version(void);
diff --git a/plat/nvidia/tegra/include/drivers/memctrl.h b/plat/nvidia/tegra/include/drivers/memctrl.h
index d5ef60d0c..cc8509526 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,7 +11,6 @@
void tegra_memctrl_setup(void);
void tegra_memctrl_restore_settings(void);
void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes);
-void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes);
void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes);
void tegra_memctrl_disable_ahb_redirection(void);
void tegra_memctrl_clear_pending_interrupts(void);
diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
index a4085e247..9af3027ea 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,58 +8,9 @@
#ifndef MEMCTRL_V2_H
#define MEMCTRL_V2_H
-#include <tegra_def.h>
-
-#ifndef __ASSEMBLER__
-
-#include <lib/mmio.h>
-#include <stdint.h>
-
-/*******************************************************************************
- * Structure to hold the transaction override settings to use to override
- * client inputs
- ******************************************************************************/
-typedef struct mc_txn_override_cfg {
- uint32_t offset;
- uint8_t cgid_tag;
-} mc_txn_override_cfg_t;
-
-#define mc_make_txn_override_cfg(off, val) \
- { \
- .offset = MC_TXN_OVERRIDE_CONFIG_ ## off, \
- .cgid_tag = MC_TXN_OVERRIDE_ ## val \
- }
-
-/*******************************************************************************
- * Structure to hold the Stream ID to use to override client inputs
- ******************************************************************************/
-typedef struct mc_streamid_override_cfg {
- uint32_t offset;
- uint8_t stream_id;
-} mc_streamid_override_cfg_t;
+#include <arch.h>
-/*******************************************************************************
- * Structure to hold the Stream ID Security Configuration settings
- ******************************************************************************/
-typedef struct mc_streamid_security_cfg {
- char *name;
- uint32_t offset;
- int override_enable;
- int override_client_inputs;
- int override_client_ns_flag;
-} mc_streamid_security_cfg_t;
-
-#define OVERRIDE_DISABLE 1U
-#define OVERRIDE_ENABLE 0U
-#define CLIENT_FLAG_SECURE 0U
-#define CLIENT_FLAG_NON_SECURE 1U
-#define CLIENT_INPUTS_OVERRIDE 1U
-#define CLIENT_INPUTS_NO_OVERRIDE 0U
-/*******************************************************************************
- * StreamID to indicate no SMMU translations (requests to be steered on the
- * SMMU bypass path)
- ******************************************************************************/
-#define MC_STREAM_ID_MAX 0x7FU
+#include <tegra_def.h>
/*******************************************************************************
* Memory Controller SMMU Bypass config register
@@ -74,29 +26,38 @@ typedef struct mc_streamid_security_cfg {
#define MC_SMMU_BYPASS_CONFIG_SETTINGS (MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \
MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID)
-#define mc_make_sec_cfg(off, ns, ovrrd, access) \
+#ifndef __ASSEMBLER__
+
+#include <assert.h>
+
+typedef struct mc_regs {
+ uint32_t reg;
+ uint32_t val;
+} mc_regs_t;
+
+#define mc_smmu_bypass_cfg \
{ \
- .name = # off, \
- .offset = MC_STREAMID_OVERRIDE_TO_SECURITY_CFG( \
- MC_STREAMID_OVERRIDE_CFG_ ## off), \
- .override_client_ns_flag = CLIENT_FLAG_ ## ns, \
- .override_client_inputs = CLIENT_INPUTS_ ## ovrrd, \
- .override_enable = OVERRIDE_ ## access \
+ .reg = TEGRA_MC_BASE + MC_SMMU_BYPASS_CONFIG, \
+ .val = 0x00000000U, \
}
-/*******************************************************************************
- * Structure to hold Memory Controller's Configuration settings
- ******************************************************************************/
-typedef struct tegra_mc_settings {
- const uint32_t *streamid_override_cfg;
- uint32_t num_streamid_override_cfgs;
- const mc_streamid_security_cfg_t *streamid_security_cfg;
- uint32_t num_streamid_security_cfgs;
- const mc_txn_override_cfg_t *txn_override_cfg;
- uint32_t num_txn_override_cfgs;
- void (*reconfig_mss_clients)(void);
- void (*set_txn_overrides)(void);
-} tegra_mc_settings_t;
+#define _START_OF_TABLE_ \
+ { \
+ .reg = 0xCAFE05C7U, \
+ .val = 0x00000000U, \
+ }
+
+#define _END_OF_TABLE_ \
+ { \
+ .reg = 0xFFFFFFFFU, \
+ .val = 0xFFFFFFFFU, \
+ }
+
+#endif /* __ASSEMBLER__ */
+
+#ifndef __ASSEMBLER__
+
+#include <lib/mmio.h>
static inline uint32_t tegra_mc_read_32(uint32_t off)
{
@@ -108,6 +69,7 @@ static inline void tegra_mc_write_32(uint32_t off, uint32_t val)
mmio_write_32(TEGRA_MC_BASE + off, val);
}
+#if defined(TEGRA_MC_STREAMID_BASE)
static inline uint32_t tegra_mc_streamid_read_32(uint32_t off)
{
return mmio_read_32(TEGRA_MC_STREAMID_BASE + off);
@@ -116,54 +78,21 @@ static inline uint32_t tegra_mc_streamid_read_32(uint32_t off)
static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val)
{
mmio_write_32(TEGRA_MC_STREAMID_BASE + off, val);
+ assert(mmio_read_32(TEGRA_MC_STREAMID_BASE + off) == val);
}
+#endif
-#define mc_set_pcfifo_unordered_boot_so_mss(id, client) \
- ((uint32_t)~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
- MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED)
-
-#define mc_set_pcfifo_ordered_boot_so_mss(id, client) \
- MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_ORDERED
+void plat_memctrl_setup(void);
-#define mc_set_tsa_passthrough(client) \
- { \
- mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
- (TSA_CONFIG_STATIC0_CSW_##client##_RESET & \
- (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
- (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
- }
-
-#define mc_set_tsa_w_passthrough(client) \
- { \
- mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
- (TSA_CONFIG_STATIC0_CSW_RESET_W & \
- (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
- (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
- }
-
-#define mc_set_tsa_r_passthrough(client) \
- { \
- mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSR_##client, \
- (TSA_CONFIG_STATIC0_CSR_RESET_R & \
- (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
- (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
- }
-
-#define mc_set_txn_override(client, normal_axi_id, so_dev_axi_id, normal_override, so_dev_override) \
- { \
- tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
- MC_TXN_OVERRIDE_##normal_axi_id | \
- MC_TXN_OVERRIDE_CONFIG_COH_PATH_##so_dev_override##_SO_DEV | \
- MC_TXN_OVERRIDE_CONFIG_COH_PATH_##normal_override##_NORMAL | \
- MC_TXN_OVERRIDE_CONFIG_CGID_##so_dev_axi_id); \
- }
+void plat_memctrl_restore(void);
+mc_regs_t *plat_memctrl_get_sys_suspend_ctx(void);
/*******************************************************************************
- * Handler to read memory configuration settings
+ * Handler to save MC settings before "System Suspend" to TZDRAM
*
- * Implemented by SoCs under tegra/soc/txxx
+ * Implemented by Tegra common memctrl_v2 driver under common/drivers/memctrl
******************************************************************************/
-tegra_mc_settings_t *tegra_get_mc_settings(void);
+void tegra_mc_save_context(uint64_t mc_ctx_addr);
/*******************************************************************************
* Handler to program the scratch registers with TZDRAM settings for the
diff --git a/plat/nvidia/tegra/include/drivers/pmc.h b/plat/nvidia/tegra/include/drivers/pmc.h
index 32252a28b..8752b84c6 100644
--- a/plat/nvidia/tegra/include/drivers/pmc.h
+++ b/plat/nvidia/tegra/include/drivers/pmc.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,27 +19,37 @@
#define PMC_DPD_ENABLE_0 U(0x24)
#define PMC_PWRGATE_STATUS U(0x38)
#define PMC_PWRGATE_TOGGLE U(0x30)
-#define PMC_SECURE_SCRATCH0 U(0xb0)
-#define PMC_SECURE_SCRATCH5 U(0xc4)
+#define PMC_SCRATCH1 U(0x54)
#define PMC_CRYPTO_OP_0 U(0xf4)
#define PMC_TOGGLE_START U(0x100)
+#define PMC_SCRATCH31 U(0x118)
+#define PMC_SCRATCH32 U(0x11C)
+#define PMC_SCRATCH33 U(0x120)
#define PMC_SCRATCH39 U(0x138)
+#define PMC_SCRATCH40 U(0x13C)
#define PMC_SCRATCH41 U(0x140)
-#define PMC_SECURE_SCRATCH6 U(0x224)
-#define PMC_SECURE_SCRATCH7 U(0x228)
-#define PMC_SECURE_DISABLE2 U(0x2c4)
+#define PMC_SCRATCH42 U(0x144)
+#define PMC_SCRATCH43 U(0x22C)
+#define PMC_SCRATCH44 U(0x230)
+#define PMC_SCRATCH45 U(0x234)
+#define PMC_SCRATCH46 U(0x238)
+#define PMC_SCRATCH47 U(0x23C)
+#define PMC_SCRATCH48 U(0x240)
+#define PMC_SCRATCH50 U(0x248)
+#define PMC_SCRATCH51 U(0x24C)
+#define PMC_TSC_MULT_0 U(0x2B4)
+#define PMC_STICKY_BIT U(0x2C0)
+#define PMC_SECURE_DISABLE2 U(0x2C4)
#define PMC_SECURE_DISABLE2_WRITE22_ON (U(1) << 28)
-#define PMC_SECURE_SCRATCH8 U(0x300)
-#define PMC_SECURE_SCRATCH79 U(0x41c)
#define PMC_FUSE_CONTROL_0 U(0x450)
-#define PMC_SECURE_SCRATCH22 U(0x338)
-#define PMC_SECURE_DISABLE3 U(0x2d8)
+#define PMC_SECURE_DISABLE3 U(0x2D8)
#define PMC_SECURE_DISABLE3_WRITE34_ON (U(1) << 20)
#define PMC_SECURE_DISABLE3_WRITE35_ON (U(1) << 22)
+#define PMC_SECURE_SCRATCH22 U(0x338)
#define PMC_SECURE_SCRATCH34 U(0x368)
#define PMC_SECURE_SCRATCH35 U(0x36c)
-#define PMC_SECURE_SCRATCH80 U(0xa98)
-#define PMC_SECURE_SCRATCH119 U(0xb34)
+#define PMC_SCRATCH56 U(0x600)
+#define PMC_SCRATCH57 U(0x604)
#define PMC_SCRATCH201 U(0x844)
static inline uint32_t tegra_pmc_read_32(uint32_t off)
diff --git a/plat/nvidia/tegra/include/drivers/security_engine.h b/plat/nvidia/tegra/include/drivers/security_engine.h
index 8a249249b..5ae625793 100644
--- a/plat/nvidia/tegra/include/drivers/security_engine.h
+++ b/plat/nvidia/tegra/include/drivers/security_engine.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -55,5 +55,6 @@ void tegra_se_init(void);
int tegra_se_suspend(void);
void tegra_se_resume(void);
int tegra_se_save_tzram(void);
+int32_t tegra_se_save_sha256_hash(uint64_t bl31_base, uint32_t src_len_inbyte);
#endif /* SECURITY_ENGINE_H */
diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h
index 424a91aea..1de9af6e5 100644
--- a/plat/nvidia/tegra/include/drivers/smmu.h
+++ b/plat/nvidia/tegra/include/drivers/smmu.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,566 +13,7 @@
#include <memctrl_v2.h>
#include <tegra_def.h>
-/*******************************************************************************
- * SMMU Register constants
- ******************************************************************************/
-#define SMMU_CBn_SCTLR (0x0U)
-#define SMMU_CBn_SCTLR_STAGE2 (0x0U)
#define SMMU_CBn_ACTLR (0x4U)
-#define SMMU_CBn_RESUME (0x8U)
-#define SMMU_CBn_TCR2 (0x10U)
-#define SMMU_CBn_TTBR0_LO (0x20U)
-#define SMMU_CBn_TTBR0_HI (0x24U)
-#define SMMU_CBn_TTBR1_LO (0x28U)
-#define SMMU_CBn_TTBR1_HI (0x2cU)
-#define SMMU_CBn_TCR_LPAE (0x30U)
-#define SMMU_CBn_TCR (0x30U)
-#define SMMU_CBn_TCR_EAE_1 (0x30U)
-#define SMMU_CBn_TCR (0x30U)
-#define SMMU_CBn_CONTEXTIDR (0x34U)
-#define SMMU_CBn_CONTEXTIDR_EAE_1 (0x34U)
-#define SMMU_CBn_PRRR_MAIR0 (0x38U)
-#define SMMU_CBn_NMRR_MAIR1 (0x3cU)
-#define SMMU_CBn_SMMU_CBn_PAR (0x50U)
-#define SMMU_CBn_SMMU_CBn_PAR0 (0x50U)
-#define SMMU_CBn_SMMU_CBn_PAR1 (0x54U)
-/* SMMU_CBn_SMMU_CBn_PAR0_Fault (0x50U) */
-/* SMMU_CBn_SMMU_CBn_PAR0_Fault (0x54U) */
-#define SMMU_CBn_FSR (0x58U)
-#define SMMU_CBn_FSRRESTORE (0x5cU)
-#define SMMU_CBn_FAR_LO (0x60U)
-#define SMMU_CBn_FAR_HI (0x64U)
-#define SMMU_CBn_FSYNR0 (0x68U)
-#define SMMU_CBn_IPAFAR_LO (0x70U)
-#define SMMU_CBn_IPAFAR_HI (0x74U)
-#define SMMU_CBn_TLBIVA_LO (0x600U)
-#define SMMU_CBn_TLBIVA_HI (0x604U)
-#define SMMU_CBn_TLBIVA_AARCH_32 (0x600U)
-#define SMMU_CBn_TLBIVAA_LO (0x608U)
-#define SMMU_CBn_TLBIVAA_HI (0x60cU)
-#define SMMU_CBn_TLBIVAA_AARCH_32 (0x608U)
-#define SMMU_CBn_TLBIASID (0x610U)
-#define SMMU_CBn_TLBIALL (0x618U)
-#define SMMU_CBn_TLBIVAL_LO (0x620U)
-#define SMMU_CBn_TLBIVAL_HI (0x624U)
-#define SMMU_CBn_TLBIVAL_AARCH_32 (0x618U)
-#define SMMU_CBn_TLBIVAAL_LO (0x628U)
-#define SMMU_CBn_TLBIVAAL_HI (0x62cU)
-#define SMMU_CBn_TLBIVAAL_AARCH_32 (0x628U)
-#define SMMU_CBn_TLBIIPAS2_LO (0x630U)
-#define SMMU_CBn_TLBIIPAS2_HI (0x634U)
-#define SMMU_CBn_TLBIIPAS2L_LO (0x638U)
-#define SMMU_CBn_TLBIIPAS2L_HI (0x63cU)
-#define SMMU_CBn_TLBSYNC (0x7f0U)
-#define SMMU_CBn_TLBSTATUS (0x7f4U)
-#define SMMU_CBn_ATSR (0x800U)
-#define SMMU_CBn_PMEVCNTR0 (0xe00U)
-#define SMMU_CBn_PMEVCNTR1 (0xe04U)
-#define SMMU_CBn_PMEVCNTR2 (0xe08U)
-#define SMMU_CBn_PMEVCNTR3 (0xe0cU)
-#define SMMU_CBn_PMEVTYPER0 (0xe80U)
-#define SMMU_CBn_PMEVTYPER1 (0xe84U)
-#define SMMU_CBn_PMEVTYPER2 (0xe88U)
-#define SMMU_CBn_PMEVTYPER3 (0xe8cU)
-#define SMMU_CBn_PMCFGR (0xf00U)
-#define SMMU_CBn_PMCR (0xf04U)
-#define SMMU_CBn_PMCEID (0xf20U)
-#define SMMU_CBn_PMCNTENSE (0xf40U)
-#define SMMU_CBn_PMCNTENCLR (0xf44U)
-#define SMMU_CBn_PMCNTENSET (0xf48U)
-#define SMMU_CBn_PMINTENCLR (0xf4cU)
-#define SMMU_CBn_PMOVSCLR (0xf50U)
-#define SMMU_CBn_PMOVSSET (0xf58U)
-#define SMMU_CBn_PMAUTHSTATUS (0xfb8U)
-#define SMMU_GNSR0_CR0 (0x0U)
-#define SMMU_GNSR0_CR2 (0x8U)
-#define SMMU_GNSR0_ACR (0x10U)
-#define SMMU_GNSR0_IDR0 (0x20U)
-#define SMMU_GNSR0_IDR1 (0x24U)
-#define SMMU_GNSR0_IDR2 (0x28U)
-#define SMMU_GNSR0_IDR7 (0x3cU)
-#define SMMU_GNSR0_GFAR_LO (0x40U)
-#define SMMU_GNSR0_GFAR_HI (0x44U)
-#define SMMU_GNSR0_GFSR (0x48U)
-#define SMMU_GNSR0_GFSRRESTORE (0x4cU)
-#define SMMU_GNSR0_GFSYNR0 (0x50U)
-#define SMMU_GNSR0_GFSYNR1 (0x54U)
-#define SMMU_GNSR0_GFSYNR1_v2 (0x54U)
-#define SMMU_GNSR0_TLBIVMID (0x64U)
-#define SMMU_GNSR0_TLBIALLNSNH (0x68U)
-#define SMMU_GNSR0_TLBIALLH (0x6cU)
-#define SMMU_GNSR0_TLBGSYNC (0x70U)
-#define SMMU_GNSR0_TLBGSTATUS (0x74U)
-#define SMMU_GNSR0_TLBIVAH_LO (0x78U)
-#define SMMU_GNSR0_TLBIVALH64_LO (0xb0U)
-#define SMMU_GNSR0_TLBIVALH64_HI (0xb4U)
-#define SMMU_GNSR0_TLBIVMIDS1 (0xb8U)
-#define SMMU_GNSR0_TLBIVAH64_LO (0xc0U)
-#define SMMU_GNSR0_TLBIVAH64_HI (0xc4U)
-#define SMMU_GNSR0_SMR0 (0x800U)
-#define SMMU_GNSR0_SMRn (0x800U)
-#define SMMU_GNSR0_SMR1 (0x804U)
-#define SMMU_GNSR0_SMR2 (0x808U)
-#define SMMU_GNSR0_SMR3 (0x80cU)
-#define SMMU_GNSR0_SMR4 (0x810U)
-#define SMMU_GNSR0_SMR5 (0x814U)
-#define SMMU_GNSR0_SMR6 (0x818U)
-#define SMMU_GNSR0_SMR7 (0x81cU)
-#define SMMU_GNSR0_SMR8 (0x820U)
-#define SMMU_GNSR0_SMR9 (0x824U)
-#define SMMU_GNSR0_SMR10 (0x828U)
-#define SMMU_GNSR0_SMR11 (0x82cU)
-#define SMMU_GNSR0_SMR12 (0x830U)
-#define SMMU_GNSR0_SMR13 (0x834U)
-#define SMMU_GNSR0_SMR14 (0x838U)
-#define SMMU_GNSR0_SMR15 (0x83cU)
-#define SMMU_GNSR0_SMR16 (0x840U)
-#define SMMU_GNSR0_SMR17 (0x844U)
-#define SMMU_GNSR0_SMR18 (0x848U)
-#define SMMU_GNSR0_SMR19 (0x84cU)
-#define SMMU_GNSR0_SMR20 (0x850U)
-#define SMMU_GNSR0_SMR21 (0x854U)
-#define SMMU_GNSR0_SMR22 (0x858U)
-#define SMMU_GNSR0_SMR23 (0x85cU)
-#define SMMU_GNSR0_SMR24 (0x860U)
-#define SMMU_GNSR0_SMR25 (0x864U)
-#define SMMU_GNSR0_SMR26 (0x868U)
-#define SMMU_GNSR0_SMR27 (0x86cU)
-#define SMMU_GNSR0_SMR28 (0x870U)
-#define SMMU_GNSR0_SMR29 (0x874U)
-#define SMMU_GNSR0_SMR30 (0x878U)
-#define SMMU_GNSR0_SMR31 (0x87cU)
-#define SMMU_GNSR0_SMR32 (0x880U)
-#define SMMU_GNSR0_SMR33 (0x884U)
-#define SMMU_GNSR0_SMR34 (0x888U)
-#define SMMU_GNSR0_SMR35 (0x88cU)
-#define SMMU_GNSR0_SMR36 (0x890U)
-#define SMMU_GNSR0_SMR37 (0x894U)
-#define SMMU_GNSR0_SMR38 (0x898U)
-#define SMMU_GNSR0_SMR39 (0x89cU)
-#define SMMU_GNSR0_SMR40 (0x8a0U)
-#define SMMU_GNSR0_SMR41 (0x8a4U)
-#define SMMU_GNSR0_SMR42 (0x8a8U)
-#define SMMU_GNSR0_SMR43 (0x8acU)
-#define SMMU_GNSR0_SMR44 (0x8b0U)
-#define SMMU_GNSR0_SMR45 (0x8b4U)
-#define SMMU_GNSR0_SMR46 (0x8b8U)
-#define SMMU_GNSR0_SMR47 (0x8bcU)
-#define SMMU_GNSR0_SMR48 (0x8c0U)
-#define SMMU_GNSR0_SMR49 (0x8c4U)
-#define SMMU_GNSR0_SMR50 (0x8c8U)
-#define SMMU_GNSR0_SMR51 (0x8ccU)
-#define SMMU_GNSR0_SMR52 (0x8d0U)
-#define SMMU_GNSR0_SMR53 (0x8d4U)
-#define SMMU_GNSR0_SMR54 (0x8d8U)
-#define SMMU_GNSR0_SMR55 (0x8dcU)
-#define SMMU_GNSR0_SMR56 (0x8e0U)
-#define SMMU_GNSR0_SMR57 (0x8e4U)
-#define SMMU_GNSR0_SMR58 (0x8e8U)
-#define SMMU_GNSR0_SMR59 (0x8ecU)
-#define SMMU_GNSR0_SMR60 (0x8f0U)
-#define SMMU_GNSR0_SMR61 (0x8f4U)
-#define SMMU_GNSR0_SMR62 (0x8f8U)
-#define SMMU_GNSR0_SMR63 (0x8fcU)
-#define SMMU_GNSR0_SMR64 (0x900U)
-#define SMMU_GNSR0_SMR65 (0x904U)
-#define SMMU_GNSR0_SMR66 (0x908U)
-#define SMMU_GNSR0_SMR67 (0x90cU)
-#define SMMU_GNSR0_SMR68 (0x910U)
-#define SMMU_GNSR0_SMR69 (0x914U)
-#define SMMU_GNSR0_SMR70 (0x918U)
-#define SMMU_GNSR0_SMR71 (0x91cU)
-#define SMMU_GNSR0_SMR72 (0x920U)
-#define SMMU_GNSR0_SMR73 (0x924U)
-#define SMMU_GNSR0_SMR74 (0x928U)
-#define SMMU_GNSR0_SMR75 (0x92cU)
-#define SMMU_GNSR0_SMR76 (0x930U)
-#define SMMU_GNSR0_SMR77 (0x934U)
-#define SMMU_GNSR0_SMR78 (0x938U)
-#define SMMU_GNSR0_SMR79 (0x93cU)
-#define SMMU_GNSR0_SMR80 (0x940U)
-#define SMMU_GNSR0_SMR81 (0x944U)
-#define SMMU_GNSR0_SMR82 (0x948U)
-#define SMMU_GNSR0_SMR83 (0x94cU)
-#define SMMU_GNSR0_SMR84 (0x950U)
-#define SMMU_GNSR0_SMR85 (0x954U)
-#define SMMU_GNSR0_SMR86 (0x958U)
-#define SMMU_GNSR0_SMR87 (0x95cU)
-#define SMMU_GNSR0_SMR88 (0x960U)
-#define SMMU_GNSR0_SMR89 (0x964U)
-#define SMMU_GNSR0_SMR90 (0x968U)
-#define SMMU_GNSR0_SMR91 (0x96cU)
-#define SMMU_GNSR0_SMR92 (0x970U)
-#define SMMU_GNSR0_SMR93 (0x974U)
-#define SMMU_GNSR0_SMR94 (0x978U)
-#define SMMU_GNSR0_SMR95 (0x97cU)
-#define SMMU_GNSR0_SMR96 (0x980U)
-#define SMMU_GNSR0_SMR97 (0x984U)
-#define SMMU_GNSR0_SMR98 (0x988U)
-#define SMMU_GNSR0_SMR99 (0x98cU)
-#define SMMU_GNSR0_SMR100 (0x990U)
-#define SMMU_GNSR0_SMR101 (0x994U)
-#define SMMU_GNSR0_SMR102 (0x998U)
-#define SMMU_GNSR0_SMR103 (0x99cU)
-#define SMMU_GNSR0_SMR104 (0x9a0U)
-#define SMMU_GNSR0_SMR105 (0x9a4U)
-#define SMMU_GNSR0_SMR106 (0x9a8U)
-#define SMMU_GNSR0_SMR107 (0x9acU)
-#define SMMU_GNSR0_SMR108 (0x9b0U)
-#define SMMU_GNSR0_SMR109 (0x9b4U)
-#define SMMU_GNSR0_SMR110 (0x9b8U)
-#define SMMU_GNSR0_SMR111 (0x9bcU)
-#define SMMU_GNSR0_SMR112 (0x9c0U)
-#define SMMU_GNSR0_SMR113 (0x9c4U)
-#define SMMU_GNSR0_SMR114 (0x9c8U)
-#define SMMU_GNSR0_SMR115 (0x9ccU)
-#define SMMU_GNSR0_SMR116 (0x9d0U)
-#define SMMU_GNSR0_SMR117 (0x9d4U)
-#define SMMU_GNSR0_SMR118 (0x9d8U)
-#define SMMU_GNSR0_SMR119 (0x9dcU)
-#define SMMU_GNSR0_SMR120 (0x9e0U)
-#define SMMU_GNSR0_SMR121 (0x9e4U)
-#define SMMU_GNSR0_SMR122 (0x9e8U)
-#define SMMU_GNSR0_SMR123 (0x9ecU)
-#define SMMU_GNSR0_SMR124 (0x9f0U)
-#define SMMU_GNSR0_SMR125 (0x9f4U)
-#define SMMU_GNSR0_SMR126 (0x9f8U)
-#define SMMU_GNSR0_SMR127 (0x9fcU)
-#define SMMU_GNSR0_S2CR0 (0xc00U)
-#define SMMU_GNSR0_S2CRn (0xc00U)
-#define SMMU_GNSR0_S2CRn (0xc00U)
-#define SMMU_GNSR0_S2CR1 (0xc04U)
-#define SMMU_GNSR0_S2CR2 (0xc08U)
-#define SMMU_GNSR0_S2CR3 (0xc0cU)
-#define SMMU_GNSR0_S2CR4 (0xc10U)
-#define SMMU_GNSR0_S2CR5 (0xc14U)
-#define SMMU_GNSR0_S2CR6 (0xc18U)
-#define SMMU_GNSR0_S2CR7 (0xc1cU)
-#define SMMU_GNSR0_S2CR8 (0xc20U)
-#define SMMU_GNSR0_S2CR9 (0xc24U)
-#define SMMU_GNSR0_S2CR10 (0xc28U)
-#define SMMU_GNSR0_S2CR11 (0xc2cU)
-#define SMMU_GNSR0_S2CR12 (0xc30U)
-#define SMMU_GNSR0_S2CR13 (0xc34U)
-#define SMMU_GNSR0_S2CR14 (0xc38U)
-#define SMMU_GNSR0_S2CR15 (0xc3cU)
-#define SMMU_GNSR0_S2CR16 (0xc40U)
-#define SMMU_GNSR0_S2CR17 (0xc44U)
-#define SMMU_GNSR0_S2CR18 (0xc48U)
-#define SMMU_GNSR0_S2CR19 (0xc4cU)
-#define SMMU_GNSR0_S2CR20 (0xc50U)
-#define SMMU_GNSR0_S2CR21 (0xc54U)
-#define SMMU_GNSR0_S2CR22 (0xc58U)
-#define SMMU_GNSR0_S2CR23 (0xc5cU)
-#define SMMU_GNSR0_S2CR24 (0xc60U)
-#define SMMU_GNSR0_S2CR25 (0xc64U)
-#define SMMU_GNSR0_S2CR26 (0xc68U)
-#define SMMU_GNSR0_S2CR27 (0xc6cU)
-#define SMMU_GNSR0_S2CR28 (0xc70U)
-#define SMMU_GNSR0_S2CR29 (0xc74U)
-#define SMMU_GNSR0_S2CR30 (0xc78U)
-#define SMMU_GNSR0_S2CR31 (0xc7cU)
-#define SMMU_GNSR0_S2CR32 (0xc80U)
-#define SMMU_GNSR0_S2CR33 (0xc84U)
-#define SMMU_GNSR0_S2CR34 (0xc88U)
-#define SMMU_GNSR0_S2CR35 (0xc8cU)
-#define SMMU_GNSR0_S2CR36 (0xc90U)
-#define SMMU_GNSR0_S2CR37 (0xc94U)
-#define SMMU_GNSR0_S2CR38 (0xc98U)
-#define SMMU_GNSR0_S2CR39 (0xc9cU)
-#define SMMU_GNSR0_S2CR40 (0xca0U)
-#define SMMU_GNSR0_S2CR41 (0xca4U)
-#define SMMU_GNSR0_S2CR42 (0xca8U)
-#define SMMU_GNSR0_S2CR43 (0xcacU)
-#define SMMU_GNSR0_S2CR44 (0xcb0U)
-#define SMMU_GNSR0_S2CR45 (0xcb4U)
-#define SMMU_GNSR0_S2CR46 (0xcb8U)
-#define SMMU_GNSR0_S2CR47 (0xcbcU)
-#define SMMU_GNSR0_S2CR48 (0xcc0U)
-#define SMMU_GNSR0_S2CR49 (0xcc4U)
-#define SMMU_GNSR0_S2CR50 (0xcc8U)
-#define SMMU_GNSR0_S2CR51 (0xcccU)
-#define SMMU_GNSR0_S2CR52 (0xcd0U)
-#define SMMU_GNSR0_S2CR53 (0xcd4U)
-#define SMMU_GNSR0_S2CR54 (0xcd8U)
-#define SMMU_GNSR0_S2CR55 (0xcdcU)
-#define SMMU_GNSR0_S2CR56 (0xce0U)
-#define SMMU_GNSR0_S2CR57 (0xce4U)
-#define SMMU_GNSR0_S2CR58 (0xce8U)
-#define SMMU_GNSR0_S2CR59 (0xcecU)
-#define SMMU_GNSR0_S2CR60 (0xcf0U)
-#define SMMU_GNSR0_S2CR61 (0xcf4U)
-#define SMMU_GNSR0_S2CR62 (0xcf8U)
-#define SMMU_GNSR0_S2CR63 (0xcfcU)
-#define SMMU_GNSR0_S2CR64 (0xd00U)
-#define SMMU_GNSR0_S2CR65 (0xd04U)
-#define SMMU_GNSR0_S2CR66 (0xd08U)
-#define SMMU_GNSR0_S2CR67 (0xd0cU)
-#define SMMU_GNSR0_S2CR68 (0xd10U)
-#define SMMU_GNSR0_S2CR69 (0xd14U)
-#define SMMU_GNSR0_S2CR70 (0xd18U)
-#define SMMU_GNSR0_S2CR71 (0xd1cU)
-#define SMMU_GNSR0_S2CR72 (0xd20U)
-#define SMMU_GNSR0_S2CR73 (0xd24U)
-#define SMMU_GNSR0_S2CR74 (0xd28U)
-#define SMMU_GNSR0_S2CR75 (0xd2cU)
-#define SMMU_GNSR0_S2CR76 (0xd30U)
-#define SMMU_GNSR0_S2CR77 (0xd34U)
-#define SMMU_GNSR0_S2CR78 (0xd38U)
-#define SMMU_GNSR0_S2CR79 (0xd3cU)
-#define SMMU_GNSR0_S2CR80 (0xd40U)
-#define SMMU_GNSR0_S2CR81 (0xd44U)
-#define SMMU_GNSR0_S2CR82 (0xd48U)
-#define SMMU_GNSR0_S2CR83 (0xd4cU)
-#define SMMU_GNSR0_S2CR84 (0xd50U)
-#define SMMU_GNSR0_S2CR85 (0xd54U)
-#define SMMU_GNSR0_S2CR86 (0xd58U)
-#define SMMU_GNSR0_S2CR87 (0xd5cU)
-#define SMMU_GNSR0_S2CR88 (0xd60U)
-#define SMMU_GNSR0_S2CR89 (0xd64U)
-#define SMMU_GNSR0_S2CR90 (0xd68U)
-#define SMMU_GNSR0_S2CR91 (0xd6cU)
-#define SMMU_GNSR0_S2CR92 (0xd70U)
-#define SMMU_GNSR0_S2CR93 (0xd74U)
-#define SMMU_GNSR0_S2CR94 (0xd78U)
-#define SMMU_GNSR0_S2CR95 (0xd7cU)
-#define SMMU_GNSR0_S2CR96 (0xd80U)
-#define SMMU_GNSR0_S2CR97 (0xd84U)
-#define SMMU_GNSR0_S2CR98 (0xd88U)
-#define SMMU_GNSR0_S2CR99 (0xd8cU)
-#define SMMU_GNSR0_S2CR100 (0xd90U)
-#define SMMU_GNSR0_S2CR101 (0xd94U)
-#define SMMU_GNSR0_S2CR102 (0xd98U)
-#define SMMU_GNSR0_S2CR103 (0xd9cU)
-#define SMMU_GNSR0_S2CR104 (0xda0U)
-#define SMMU_GNSR0_S2CR105 (0xda4U)
-#define SMMU_GNSR0_S2CR106 (0xda8U)
-#define SMMU_GNSR0_S2CR107 (0xdacU)
-#define SMMU_GNSR0_S2CR108 (0xdb0U)
-#define SMMU_GNSR0_S2CR109 (0xdb4U)
-#define SMMU_GNSR0_S2CR110 (0xdb8U)
-#define SMMU_GNSR0_S2CR111 (0xdbcU)
-#define SMMU_GNSR0_S2CR112 (0xdc0U)
-#define SMMU_GNSR0_S2CR113 (0xdc4U)
-#define SMMU_GNSR0_S2CR114 (0xdc8U)
-#define SMMU_GNSR0_S2CR115 (0xdccU)
-#define SMMU_GNSR0_S2CR116 (0xdd0U)
-#define SMMU_GNSR0_S2CR117 (0xdd4U)
-#define SMMU_GNSR0_S2CR118 (0xdd8U)
-#define SMMU_GNSR0_S2CR119 (0xddcU)
-#define SMMU_GNSR0_S2CR120 (0xde0U)
-#define SMMU_GNSR0_S2CR121 (0xde4U)
-#define SMMU_GNSR0_S2CR122 (0xde8U)
-#define SMMU_GNSR0_S2CR123 (0xdecU)
-#define SMMU_GNSR0_S2CR124 (0xdf0U)
-#define SMMU_GNSR0_S2CR125 (0xdf4U)
-#define SMMU_GNSR0_S2CR126 (0xdf8U)
-#define SMMU_GNSR0_S2CR127 (0xdfcU)
-#define SMMU_GNSR0_PIDR0 (0xfe0U)
-#define SMMU_GNSR0_PIDR1 (0xfe4U)
-#define SMMU_GNSR0_PIDR2 (0xfe8U)
-#define SMMU_GNSR0_PIDR3 (0xfecU)
-#define SMMU_GNSR0_PIDR4 (0xfd0U)
-#define SMMU_GNSR0_PIDR5 (0xfd4U)
-#define SMMU_GNSR0_PIDR6 (0xfd8U)
-#define SMMU_GNSR0_PIDR7 (0xfdcU)
-#define SMMU_GNSR0_CIDR0 (0xff0U)
-#define SMMU_GNSR0_CIDR1 (0xff4U)
-#define SMMU_GNSR0_CIDR2 (0xff8U)
-#define SMMU_GNSR0_CIDR3 (0xffcU)
-#define SMMU_GNSR1_CBAR0 (0x0U)
-#define SMMU_GNSR1_CBARn (0x0U)
-#define SMMU_GNSR1_CBFRSYNRA0 (0x400U)
-#define SMMU_GNSR1_CBA2R0 (0x800U)
-#define SMMU_GNSR1_CBAR1 (0x4U)
-#define SMMU_GNSR1_CBFRSYNRA1 (0x404U)
-#define SMMU_GNSR1_CBA2R1 (0x804U)
-#define SMMU_GNSR1_CBAR2 (0x8U)
-#define SMMU_GNSR1_CBFRSYNRA2 (0x408U)
-#define SMMU_GNSR1_CBA2R2 (0x808U)
-#define SMMU_GNSR1_CBAR3 (0xcU)
-#define SMMU_GNSR1_CBFRSYNRA3 (0x40cU)
-#define SMMU_GNSR1_CBA2R3 (0x80cU)
-#define SMMU_GNSR1_CBAR4 (0x10U)
-#define SMMU_GNSR1_CBFRSYNRA4 (0x410U)
-#define SMMU_GNSR1_CBA2R4 (0x810U)
-#define SMMU_GNSR1_CBAR5 (0x14U)
-#define SMMU_GNSR1_CBFRSYNRA5 (0x414U)
-#define SMMU_GNSR1_CBA2R5 (0x814U)
-#define SMMU_GNSR1_CBAR6 (0x18U)
-#define SMMU_GNSR1_CBFRSYNRA6 (0x418U)
-#define SMMU_GNSR1_CBA2R6 (0x818U)
-#define SMMU_GNSR1_CBAR7 (0x1cU)
-#define SMMU_GNSR1_CBFRSYNRA7 (0x41cU)
-#define SMMU_GNSR1_CBA2R7 (0x81cU)
-#define SMMU_GNSR1_CBAR8 (0x20U)
-#define SMMU_GNSR1_CBFRSYNRA8 (0x420U)
-#define SMMU_GNSR1_CBA2R8 (0x820U)
-#define SMMU_GNSR1_CBAR9 (0x24U)
-#define SMMU_GNSR1_CBFRSYNRA9 (0x424U)
-#define SMMU_GNSR1_CBA2R9 (0x824U)
-#define SMMU_GNSR1_CBAR10 (0x28U)
-#define SMMU_GNSR1_CBFRSYNRA10 (0x428U)
-#define SMMU_GNSR1_CBA2R10 (0x828U)
-#define SMMU_GNSR1_CBAR11 (0x2cU)
-#define SMMU_GNSR1_CBFRSYNRA11 (0x42cU)
-#define SMMU_GNSR1_CBA2R11 (0x82cU)
-#define SMMU_GNSR1_CBAR12 (0x30U)
-#define SMMU_GNSR1_CBFRSYNRA12 (0x430U)
-#define SMMU_GNSR1_CBA2R12 (0x830U)
-#define SMMU_GNSR1_CBAR13 (0x34U)
-#define SMMU_GNSR1_CBFRSYNRA13 (0x434U)
-#define SMMU_GNSR1_CBA2R13 (0x834U)
-#define SMMU_GNSR1_CBAR14 (0x38U)
-#define SMMU_GNSR1_CBFRSYNRA14 (0x438U)
-#define SMMU_GNSR1_CBA2R14 (0x838U)
-#define SMMU_GNSR1_CBAR15 (0x3cU)
-#define SMMU_GNSR1_CBFRSYNRA15 (0x43cU)
-#define SMMU_GNSR1_CBA2R15 (0x83cU)
-#define SMMU_GNSR1_CBAR16 (0x40U)
-#define SMMU_GNSR1_CBFRSYNRA16 (0x440U)
-#define SMMU_GNSR1_CBA2R16 (0x840U)
-#define SMMU_GNSR1_CBAR17 (0x44U)
-#define SMMU_GNSR1_CBFRSYNRA17 (0x444U)
-#define SMMU_GNSR1_CBA2R17 (0x844U)
-#define SMMU_GNSR1_CBAR18 (0x48U)
-#define SMMU_GNSR1_CBFRSYNRA18 (0x448U)
-#define SMMU_GNSR1_CBA2R18 (0x848U)
-#define SMMU_GNSR1_CBAR19 (0x4cU)
-#define SMMU_GNSR1_CBFRSYNRA19 (0x44cU)
-#define SMMU_GNSR1_CBA2R19 (0x84cU)
-#define SMMU_GNSR1_CBAR20 (0x50U)
-#define SMMU_GNSR1_CBFRSYNRA20 (0x450U)
-#define SMMU_GNSR1_CBA2R20 (0x850U)
-#define SMMU_GNSR1_CBAR21 (0x54U)
-#define SMMU_GNSR1_CBFRSYNRA21 (0x454U)
-#define SMMU_GNSR1_CBA2R21 (0x854U)
-#define SMMU_GNSR1_CBAR22 (0x58U)
-#define SMMU_GNSR1_CBFRSYNRA22 (0x458U)
-#define SMMU_GNSR1_CBA2R22 (0x858U)
-#define SMMU_GNSR1_CBAR23 (0x5cU)
-#define SMMU_GNSR1_CBFRSYNRA23 (0x45cU)
-#define SMMU_GNSR1_CBA2R23 (0x85cU)
-#define SMMU_GNSR1_CBAR24 (0x60U)
-#define SMMU_GNSR1_CBFRSYNRA24 (0x460U)
-#define SMMU_GNSR1_CBA2R24 (0x860U)
-#define SMMU_GNSR1_CBAR25 (0x64U)
-#define SMMU_GNSR1_CBFRSYNRA25 (0x464U)
-#define SMMU_GNSR1_CBA2R25 (0x864U)
-#define SMMU_GNSR1_CBAR26 (0x68U)
-#define SMMU_GNSR1_CBFRSYNRA26 (0x468U)
-#define SMMU_GNSR1_CBA2R26 (0x868U)
-#define SMMU_GNSR1_CBAR27 (0x6cU)
-#define SMMU_GNSR1_CBFRSYNRA27 (0x46cU)
-#define SMMU_GNSR1_CBA2R27 (0x86cU)
-#define SMMU_GNSR1_CBAR28 (0x70U)
-#define SMMU_GNSR1_CBFRSYNRA28 (0x470U)
-#define SMMU_GNSR1_CBA2R28 (0x870U)
-#define SMMU_GNSR1_CBAR29 (0x74U)
-#define SMMU_GNSR1_CBFRSYNRA29 (0x474U)
-#define SMMU_GNSR1_CBA2R29 (0x874U)
-#define SMMU_GNSR1_CBAR30 (0x78U)
-#define SMMU_GNSR1_CBFRSYNRA30 (0x478U)
-#define SMMU_GNSR1_CBA2R30 (0x878U)
-#define SMMU_GNSR1_CBAR31 (0x7cU)
-#define SMMU_GNSR1_CBFRSYNRA31 (0x47cU)
-#define SMMU_GNSR1_CBA2R31 (0x87cU)
-#define SMMU_GNSR1_CBAR32 (0x80U)
-#define SMMU_GNSR1_CBFRSYNRA32 (0x480U)
-#define SMMU_GNSR1_CBA2R32 (0x880U)
-#define SMMU_GNSR1_CBAR33 (0x84U)
-#define SMMU_GNSR1_CBFRSYNRA33 (0x484U)
-#define SMMU_GNSR1_CBA2R33 (0x884U)
-#define SMMU_GNSR1_CBAR34 (0x88U)
-#define SMMU_GNSR1_CBFRSYNRA34 (0x488U)
-#define SMMU_GNSR1_CBA2R34 (0x888U)
-#define SMMU_GNSR1_CBAR35 (0x8cU)
-#define SMMU_GNSR1_CBFRSYNRA35 (0x48cU)
-#define SMMU_GNSR1_CBA2R35 (0x88cU)
-#define SMMU_GNSR1_CBAR36 (0x90U)
-#define SMMU_GNSR1_CBFRSYNRA36 (0x490U)
-#define SMMU_GNSR1_CBA2R36 (0x890U)
-#define SMMU_GNSR1_CBAR37 (0x94U)
-#define SMMU_GNSR1_CBFRSYNRA37 (0x494U)
-#define SMMU_GNSR1_CBA2R37 (0x894U)
-#define SMMU_GNSR1_CBAR38 (0x98U)
-#define SMMU_GNSR1_CBFRSYNRA38 (0x498U)
-#define SMMU_GNSR1_CBA2R38 (0x898U)
-#define SMMU_GNSR1_CBAR39 (0x9cU)
-#define SMMU_GNSR1_CBFRSYNRA39 (0x49cU)
-#define SMMU_GNSR1_CBA2R39 (0x89cU)
-#define SMMU_GNSR1_CBAR40 (0xa0U)
-#define SMMU_GNSR1_CBFRSYNRA40 (0x4a0U)
-#define SMMU_GNSR1_CBA2R40 (0x8a0U)
-#define SMMU_GNSR1_CBAR41 (0xa4U)
-#define SMMU_GNSR1_CBFRSYNRA41 (0x4a4U)
-#define SMMU_GNSR1_CBA2R41 (0x8a4U)
-#define SMMU_GNSR1_CBAR42 (0xa8U)
-#define SMMU_GNSR1_CBFRSYNRA42 (0x4a8U)
-#define SMMU_GNSR1_CBA2R42 (0x8a8U)
-#define SMMU_GNSR1_CBAR43 (0xacU)
-#define SMMU_GNSR1_CBFRSYNRA43 (0x4acU)
-#define SMMU_GNSR1_CBA2R43 (0x8acU)
-#define SMMU_GNSR1_CBAR44 (0xb0U)
-#define SMMU_GNSR1_CBFRSYNRA44 (0x4b0U)
-#define SMMU_GNSR1_CBA2R44 (0x8b0U)
-#define SMMU_GNSR1_CBAR45 (0xb4U)
-#define SMMU_GNSR1_CBFRSYNRA45 (0x4b4U)
-#define SMMU_GNSR1_CBA2R45 (0x8b4U)
-#define SMMU_GNSR1_CBAR46 (0xb8U)
-#define SMMU_GNSR1_CBFRSYNRA46 (0x4b8U)
-#define SMMU_GNSR1_CBA2R46 (0x8b8U)
-#define SMMU_GNSR1_CBAR47 (0xbcU)
-#define SMMU_GNSR1_CBFRSYNRA47 (0x4bcU)
-#define SMMU_GNSR1_CBA2R47 (0x8bcU)
-#define SMMU_GNSR1_CBAR48 (0xc0U)
-#define SMMU_GNSR1_CBFRSYNRA48 (0x4c0U)
-#define SMMU_GNSR1_CBA2R48 (0x8c0U)
-#define SMMU_GNSR1_CBAR49 (0xc4U)
-#define SMMU_GNSR1_CBFRSYNRA49 (0x4c4U)
-#define SMMU_GNSR1_CBA2R49 (0x8c4U)
-#define SMMU_GNSR1_CBAR50 (0xc8U)
-#define SMMU_GNSR1_CBFRSYNRA50 (0x4c8U)
-#define SMMU_GNSR1_CBA2R50 (0x8c8U)
-#define SMMU_GNSR1_CBAR51 (0xccU)
-#define SMMU_GNSR1_CBFRSYNRA51 (0x4ccU)
-#define SMMU_GNSR1_CBA2R51 (0x8ccU)
-#define SMMU_GNSR1_CBAR52 (0xd0U)
-#define SMMU_GNSR1_CBFRSYNRA52 (0x4d0U)
-#define SMMU_GNSR1_CBA2R52 (0x8d0U)
-#define SMMU_GNSR1_CBAR53 (0xd4U)
-#define SMMU_GNSR1_CBFRSYNRA53 (0x4d4U)
-#define SMMU_GNSR1_CBA2R53 (0x8d4U)
-#define SMMU_GNSR1_CBAR54 (0xd8U)
-#define SMMU_GNSR1_CBFRSYNRA54 (0x4d8U)
-#define SMMU_GNSR1_CBA2R54 (0x8d8U)
-#define SMMU_GNSR1_CBAR55 (0xdcU)
-#define SMMU_GNSR1_CBFRSYNRA55 (0x4dcU)
-#define SMMU_GNSR1_CBA2R55 (0x8dcU)
-#define SMMU_GNSR1_CBAR56 (0xe0U)
-#define SMMU_GNSR1_CBFRSYNRA56 (0x4e0U)
-#define SMMU_GNSR1_CBA2R56 (0x8e0U)
-#define SMMU_GNSR1_CBAR57 (0xe4U)
-#define SMMU_GNSR1_CBFRSYNRA57 (0x4e4U)
-#define SMMU_GNSR1_CBA2R57 (0x8e4U)
-#define SMMU_GNSR1_CBAR58 (0xe8U)
-#define SMMU_GNSR1_CBFRSYNRA58 (0x4e8U)
-#define SMMU_GNSR1_CBA2R58 (0x8e8U)
-#define SMMU_GNSR1_CBAR59 (0xecU)
-#define SMMU_GNSR1_CBFRSYNRA59 (0x4ecU)
-#define SMMU_GNSR1_CBA2R59 (0x8ecU)
-#define SMMU_GNSR1_CBAR60 (0xf0U)
-#define SMMU_GNSR1_CBFRSYNRA60 (0x4f0U)
-#define SMMU_GNSR1_CBA2R60 (0x8f0U)
-#define SMMU_GNSR1_CBAR61 (0xf4U)
-#define SMMU_GNSR1_CBFRSYNRA61 (0x4f4U)
-#define SMMU_GNSR1_CBA2R61 (0x8f4U)
-#define SMMU_GNSR1_CBAR62 (0xf8U)
-#define SMMU_GNSR1_CBFRSYNRA62 (0x4f8U)
-#define SMMU_GNSR1_CBA2R62 (0x8f8U)
-#define SMMU_GNSR1_CBAR63 (0xfcU)
-#define SMMU_GNSR1_CBFRSYNRA63 (0x4fcU)
-#define SMMU_GNSR1_CBA2R63 (0x8fcU)
/*******************************************************************************
* SMMU Global Secure Aux. Configuration Register
@@ -581,269 +23,70 @@
#define SMMU_GSR0_PGSIZE_SHIFT 16U
#define SMMU_GSR0_PGSIZE_4K (0U << SMMU_GSR0_PGSIZE_SHIFT)
#define SMMU_GSR0_PGSIZE_64K (1U << SMMU_GSR0_PGSIZE_SHIFT)
-#define SMMU_ACR_CACHE_LOCK_ENABLE_BIT (1U << 26)
+#define SMMU_ACR_CACHE_LOCK_ENABLE_BIT (1ULL << 26U)
+#define SMMU_GSR0_PER (0x20200U)
/*******************************************************************************
* SMMU Global Aux. Control Register
******************************************************************************/
#define SMMU_CBn_ACTLR_CPRE_BIT (1ULL << 1U)
-/*******************************************************************************
- * SMMU configuration constants
- ******************************************************************************/
-#define ID1_PAGESIZE (1U << 31U)
-#define ID1_NUMPAGENDXB_SHIFT 28U
-#define ID1_NUMPAGENDXB_MASK 7U
-#define ID1_NUMS2CB_SHIFT 16U
-#define ID1_NUMS2CB_MASK 0xffU
-#define ID1_NUMCB_SHIFT 0U
-#define ID1_NUMCB_MASK 0xffU
-#define PGSHIFT 16U
-#define CB_SIZE 0x800000U
+/* SMMU IDs currently supported by the driver */
+enum {
+ TEGRA_SMMU0 = 0U,
+ TEGRA_SMMU1 = 1U,
+ TEGRA_SMMU2 = 2U
+};
-typedef struct smmu_regs {
- uint32_t reg;
- uint32_t val;
-} smmu_regs_t;
+static inline uint32_t tegra_smmu_read_32(uint32_t smmu_id, uint32_t off)
+{
+ uint32_t ret = 0U;
-#define mc_make_sid_override_cfg(name) \
- { \
- .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \
- .val = 0x00000000U, \
+#if defined(TEGRA_SMMU0_BASE)
+ if (smmu_id == TEGRA_SMMU0) {
+ ret = mmio_read_32(TEGRA_SMMU0_BASE + (uint64_t)off);
}
+#endif
-#define mc_make_sid_security_cfg(name) \
- { \
- .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(MC_STREAMID_OVERRIDE_CFG_ ## name), \
- .val = 0x00000000U, \
+#if defined(TEGRA_SMMU1_BASE)
+ if (smmu_id == TEGRA_SMMU1) {
+ ret = mmio_read_32(TEGRA_SMMU1_BASE + (uint64_t)off);
}
+#endif
-#define smmu_make_gnsr0_sec_cfg(base_addr, name) \
- { \
- .reg = base_addr + SMMU_GNSR0_ ## name, \
- .val = 0x00000000U, \
+#if defined(TEGRA_SMMU2_BASE)
+ if (smmu_id == TEGRA_SMMU2) {
+ ret = mmio_read_32(TEGRA_SMMU2_BASE + (uint64_t)off);
}
+#endif
-/*
- * On ARM-SMMU, conditional offset to access secure aliases of non-secure registers
- * is 0x400. So, add it to register address
- */
-#define smmu_make_gnsr0_nsec_cfg(base_addr, name) \
- { \
- .reg = base_addr + 0x400U + SMMU_GNSR0_ ## name, \
- .val = 0x00000000U, \
- }
-
-#define smmu_make_gnsr0_smr_cfg(base_addr, n) \
- { \
- .reg = base_addr + SMMU_GNSR0_SMR ## n, \
- .val = 0x00000000U, \
- }
-
-#define smmu_make_gnsr0_s2cr_cfg(base_addr, n) \
- { \
- .reg = base_addr + SMMU_GNSR0_S2CR ## n, \
- .val = 0x00000000U, \
- }
+ return ret;
+}
-#define smmu_make_gnsr1_cbar_cfg(base_addr, n) \
- { \
- .reg = base_addr + (1U << PGSHIFT) + SMMU_GNSR1_CBAR ## n, \
- .val = 0x00000000U, \
+static inline void tegra_smmu_write_32(uint32_t smmu_id,
+ uint32_t off, uint32_t val)
+{
+#if defined(TEGRA_SMMU0_BASE)
+ if (smmu_id == TEGRA_SMMU0) {
+ mmio_write_32(TEGRA_SMMU0_BASE + (uint64_t)off, val);
}
+#endif
-#define smmu_make_gnsr1_cba2r_cfg(base_addr, n) \
- { \
- .reg = base_addr + (1U << PGSHIFT) + SMMU_GNSR1_CBA2R ## n, \
- .val = 0x00000000U, \
+#if defined(TEGRA_SMMU1_BASE)
+ if (smmu_id == TEGRA_SMMU1) {
+ mmio_write_32(TEGRA_SMMU1_BASE + (uint64_t)off, val);
}
+#endif
-#define smmu_make_cb_cfg(base_addr, name, n) \
- { \
- .reg = base_addr + (CB_SIZE >> 1) + (n * (1 << PGSHIFT)) \
- + SMMU_CBn_ ## name, \
- .val = 0x00000000U, \
+#if defined(TEGRA_SMMU2_BASE)
+ if (smmu_id == TEGRA_SMMU2) {
+ mmio_write_32(TEGRA_SMMU2_BASE + (uint64_t)off, val);
}
-
-#define smmu_make_smrg_group(base_addr, n) \
- smmu_make_gnsr0_smr_cfg(base_addr, n), \
- smmu_make_gnsr0_s2cr_cfg(base_addr, n), \
- smmu_make_gnsr1_cbar_cfg(base_addr, n), \
- smmu_make_gnsr1_cba2r_cfg(base_addr, n) /* don't put "," here. */
-
-#define smmu_make_cb_group(base_addr, n) \
- smmu_make_cb_cfg(base_addr, SCTLR, n), \
- smmu_make_cb_cfg(base_addr, TCR2, n), \
- smmu_make_cb_cfg(base_addr, TTBR0_LO, n), \
- smmu_make_cb_cfg(base_addr, TTBR0_HI, n), \
- smmu_make_cb_cfg(base_addr, TCR, n), \
- smmu_make_cb_cfg(base_addr, PRRR_MAIR0, n),\
- smmu_make_cb_cfg(base_addr, FSR, n), \
- smmu_make_cb_cfg(base_addr, FAR_LO, n), \
- smmu_make_cb_cfg(base_addr, FAR_HI, n), \
- smmu_make_cb_cfg(base_addr, FSYNR0, n) /* don't put "," here. */
-
-#define smmu_make_cfg(base_addr) \
- smmu_make_gnsr0_nsec_cfg(base_addr, CR0), \
- smmu_make_gnsr0_sec_cfg(base_addr, IDR0), \
- smmu_make_gnsr0_sec_cfg(base_addr, IDR1), \
- smmu_make_gnsr0_sec_cfg(base_addr, IDR2), \
- smmu_make_gnsr0_nsec_cfg(base_addr, GFSR), \
- smmu_make_gnsr0_nsec_cfg(base_addr, GFSYNR0), \
- smmu_make_gnsr0_nsec_cfg(base_addr, GFSYNR1), \
- smmu_make_gnsr0_nsec_cfg(base_addr, TLBGSTATUS),\
- smmu_make_gnsr0_nsec_cfg(base_addr, PIDR2), \
- smmu_make_smrg_group(base_addr, 0), \
- smmu_make_smrg_group(base_addr, 1), \
- smmu_make_smrg_group(base_addr, 2), \
- smmu_make_smrg_group(base_addr, 3), \
- smmu_make_smrg_group(base_addr, 4), \
- smmu_make_smrg_group(base_addr, 5), \
- smmu_make_smrg_group(base_addr, 6), \
- smmu_make_smrg_group(base_addr, 7), \
- smmu_make_smrg_group(base_addr, 8), \
- smmu_make_smrg_group(base_addr, 9), \
- smmu_make_smrg_group(base_addr, 10), \
- smmu_make_smrg_group(base_addr, 11), \
- smmu_make_smrg_group(base_addr, 12), \
- smmu_make_smrg_group(base_addr, 13), \
- smmu_make_smrg_group(base_addr, 14), \
- smmu_make_smrg_group(base_addr, 15), \
- smmu_make_smrg_group(base_addr, 16), \
- smmu_make_smrg_group(base_addr, 17), \
- smmu_make_smrg_group(base_addr, 18), \
- smmu_make_smrg_group(base_addr, 19), \
- smmu_make_smrg_group(base_addr, 20), \
- smmu_make_smrg_group(base_addr, 21), \
- smmu_make_smrg_group(base_addr, 22), \
- smmu_make_smrg_group(base_addr, 23), \
- smmu_make_smrg_group(base_addr, 24), \
- smmu_make_smrg_group(base_addr, 25), \
- smmu_make_smrg_group(base_addr, 26), \
- smmu_make_smrg_group(base_addr, 27), \
- smmu_make_smrg_group(base_addr, 28), \
- smmu_make_smrg_group(base_addr, 29), \
- smmu_make_smrg_group(base_addr, 30), \
- smmu_make_smrg_group(base_addr, 31), \
- smmu_make_smrg_group(base_addr, 32), \
- smmu_make_smrg_group(base_addr, 33), \
- smmu_make_smrg_group(base_addr, 34), \
- smmu_make_smrg_group(base_addr, 35), \
- smmu_make_smrg_group(base_addr, 36), \
- smmu_make_smrg_group(base_addr, 37), \
- smmu_make_smrg_group(base_addr, 38), \
- smmu_make_smrg_group(base_addr, 39), \
- smmu_make_smrg_group(base_addr, 40), \
- smmu_make_smrg_group(base_addr, 41), \
- smmu_make_smrg_group(base_addr, 42), \
- smmu_make_smrg_group(base_addr, 43), \
- smmu_make_smrg_group(base_addr, 44), \
- smmu_make_smrg_group(base_addr, 45), \
- smmu_make_smrg_group(base_addr, 46), \
- smmu_make_smrg_group(base_addr, 47), \
- smmu_make_smrg_group(base_addr, 48), \
- smmu_make_smrg_group(base_addr, 49), \
- smmu_make_smrg_group(base_addr, 50), \
- smmu_make_smrg_group(base_addr, 51), \
- smmu_make_smrg_group(base_addr, 52), \
- smmu_make_smrg_group(base_addr, 53), \
- smmu_make_smrg_group(base_addr, 54), \
- smmu_make_smrg_group(base_addr, 55), \
- smmu_make_smrg_group(base_addr, 56), \
- smmu_make_smrg_group(base_addr, 57), \
- smmu_make_smrg_group(base_addr, 58), \
- smmu_make_smrg_group(base_addr, 59), \
- smmu_make_smrg_group(base_addr, 60), \
- smmu_make_smrg_group(base_addr, 61), \
- smmu_make_smrg_group(base_addr, 62), \
- smmu_make_smrg_group(base_addr, 63), \
- smmu_make_cb_group(base_addr, 0), \
- smmu_make_cb_group(base_addr, 1), \
- smmu_make_cb_group(base_addr, 2), \
- smmu_make_cb_group(base_addr, 3), \
- smmu_make_cb_group(base_addr, 4), \
- smmu_make_cb_group(base_addr, 5), \
- smmu_make_cb_group(base_addr, 6), \
- smmu_make_cb_group(base_addr, 7), \
- smmu_make_cb_group(base_addr, 8), \
- smmu_make_cb_group(base_addr, 9), \
- smmu_make_cb_group(base_addr, 10), \
- smmu_make_cb_group(base_addr, 11), \
- smmu_make_cb_group(base_addr, 12), \
- smmu_make_cb_group(base_addr, 13), \
- smmu_make_cb_group(base_addr, 14), \
- smmu_make_cb_group(base_addr, 15), \
- smmu_make_cb_group(base_addr, 16), \
- smmu_make_cb_group(base_addr, 17), \
- smmu_make_cb_group(base_addr, 18), \
- smmu_make_cb_group(base_addr, 19), \
- smmu_make_cb_group(base_addr, 20), \
- smmu_make_cb_group(base_addr, 21), \
- smmu_make_cb_group(base_addr, 22), \
- smmu_make_cb_group(base_addr, 23), \
- smmu_make_cb_group(base_addr, 24), \
- smmu_make_cb_group(base_addr, 25), \
- smmu_make_cb_group(base_addr, 26), \
- smmu_make_cb_group(base_addr, 27), \
- smmu_make_cb_group(base_addr, 28), \
- smmu_make_cb_group(base_addr, 29), \
- smmu_make_cb_group(base_addr, 30), \
- smmu_make_cb_group(base_addr, 31), \
- smmu_make_cb_group(base_addr, 32), \
- smmu_make_cb_group(base_addr, 33), \
- smmu_make_cb_group(base_addr, 34), \
- smmu_make_cb_group(base_addr, 35), \
- smmu_make_cb_group(base_addr, 36), \
- smmu_make_cb_group(base_addr, 37), \
- smmu_make_cb_group(base_addr, 38), \
- smmu_make_cb_group(base_addr, 39), \
- smmu_make_cb_group(base_addr, 40), \
- smmu_make_cb_group(base_addr, 41), \
- smmu_make_cb_group(base_addr, 42), \
- smmu_make_cb_group(base_addr, 43), \
- smmu_make_cb_group(base_addr, 44), \
- smmu_make_cb_group(base_addr, 45), \
- smmu_make_cb_group(base_addr, 46), \
- smmu_make_cb_group(base_addr, 47), \
- smmu_make_cb_group(base_addr, 48), \
- smmu_make_cb_group(base_addr, 49), \
- smmu_make_cb_group(base_addr, 50), \
- smmu_make_cb_group(base_addr, 51), \
- smmu_make_cb_group(base_addr, 52), \
- smmu_make_cb_group(base_addr, 53), \
- smmu_make_cb_group(base_addr, 54), \
- smmu_make_cb_group(base_addr, 55), \
- smmu_make_cb_group(base_addr, 56), \
- smmu_make_cb_group(base_addr, 57), \
- smmu_make_cb_group(base_addr, 58), \
- smmu_make_cb_group(base_addr, 59), \
- smmu_make_cb_group(base_addr, 60), \
- smmu_make_cb_group(base_addr, 61), \
- smmu_make_cb_group(base_addr, 62), \
- smmu_make_cb_group(base_addr, 63) /* don't put "," here. */
-
-#define smmu_bypass_cfg \
- { \
- .reg = TEGRA_MC_BASE + MC_SMMU_BYPASS_CONFIG, \
- .val = 0x00000000U, \
- }
-
-#define _START_OF_TABLE_ \
- { \
- .reg = 0xCAFE05C7U, \
- .val = 0x00000000U, \
- }
-
-#define _END_OF_TABLE_ \
- { \
- .reg = 0xFFFFFFFFU, \
- .val = 0xFFFFFFFFU, \
- }
-
+#endif
+}
void tegra_smmu_init(void);
-void tegra_smmu_save_context(uint64_t smmu_ctx_addr);
-smmu_regs_t *plat_get_smmu_ctx(void);
+void tegra_smmu_verify(void);
uint32_t plat_get_num_smmu_devices(void);
#endif /* SMMU_H */
diff --git a/plat/nvidia/tegra/include/drivers/spe.h b/plat/nvidia/tegra/include/drivers/spe.h
index 0d6d69d10..e0f871408 100644
--- a/plat/nvidia/tegra/include/drivers/spe.h
+++ b/plat/nvidia/tegra/include/drivers/spe.h
@@ -11,11 +11,6 @@
#include <drivers/console.h>
-typedef struct {
- console_t console;
- uintptr_t base;
-} console_spe_t;
-
/*
* Initialize a new spe console instance and register it with the console
* framework. The |console| pointer must point to storage that will be valid
@@ -23,6 +18,6 @@ typedef struct {
* Its contents will be reinitialized from scratch.
*/
int console_spe_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
- console_spe_t *console);
+ console_t *console);
#endif /* SPE_H */
diff --git a/plat/nvidia/tegra/include/plat_macros.S b/plat/nvidia/tegra/include/plat_macros.S
index 4f01e3306..2dc3b4152 100644
--- a/plat/nvidia/tegra/include/plat_macros.S
+++ b/plat/nvidia/tegra/include/plat_macros.S
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,6 +28,7 @@ spacer:
* ---------------------------------------------
*/
.macro plat_crash_print_regs
+#ifdef TEGRA_GICC_BASE
mov_imm x16, TEGRA_GICC_BASE
/* gicc base address is now in x16 */
@@ -37,7 +39,7 @@ spacer:
ldr w10, [x16, #GICC_CTLR]
/* Store to the crash buf and print to cosole */
bl str_in_crash_buf_print
-
+#endif
/* Print the GICD_ISPENDR regs */
mov_imm x16, TEGRA_GICD_BASE
add x7, x16, #GICD_ISPENDR
diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h
index eb55def4a..84b3297e0 100644
--- a/plat/nvidia/tegra/include/platform_def.h
+++ b/plat/nvidia/tegra/include/platform_def.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,6 +13,19 @@
#include <tegra_def.h>
+/*******************************************************************************
+ * Check and error if SEPARATE_CODE_AND_RODATA is not set to 1
+ ******************************************************************************/
+#if !SEPARATE_CODE_AND_RODATA
+#error "SEPARATE_CODE_AND_RODATA should be set to 1"
+#endif
+
+/*
+ * Platform binary types for linking
+ */
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
/*
* Platform binary types for linking
*/
@@ -33,7 +47,7 @@
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \
PLATFORM_MAX_CPUS_PER_CLUSTER)
#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \
- PLATFORM_CLUSTER_COUNT + 1)
+ PLATFORM_CLUSTER_COUNT + U(1))
/*******************************************************************************
* Platform console related constants
@@ -52,7 +66,6 @@
/*******************************************************************************
* BL31 specific defines.
******************************************************************************/
-#define BL31_SIZE U(0x40000)
#define BL31_BASE TZDRAM_BASE
#define BL31_LIMIT (TZDRAM_BASE + BL31_SIZE - 1)
#define BL32_BASE (TZDRAM_BASE + BL31_SIZE)
@@ -72,4 +85,48 @@
#define MAX_IO_DEVICES U(0)
#define MAX_IO_HANDLES U(0)
+/*******************************************************************************
+ * Platforms macros to support SDEI
+ ******************************************************************************/
+#define TEGRA_SDEI_SGI_PRIVATE U(8)
+
+/*******************************************************************************
+ * Platform macros to support exception handling framework
+ ******************************************************************************/
+#define PLAT_PRI_BITS U(3)
+#define PLAT_RAS_PRI U(0x10)
+#define PLAT_SDEI_CRITICAL_PRI U(0x20)
+#define PLAT_SDEI_NORMAL_PRI U(0x30)
+#define PLAT_TEGRA_WDT_PRIO U(0x40)
+
+#define PLAT_EHF_DESC EHF_PRI_DESC(PLAT_PRI_BITS,\
+ PLAT_TEGRA_WDT_PRIO)
+
+/*******************************************************************************
+ * SDEI events
+ ******************************************************************************/
+/* SDEI dynamic private event numbers */
+#define TEGRA_SDEI_DP_EVENT_0 U(100)
+#define TEGRA_SDEI_DP_EVENT_1 U(101)
+#define TEGRA_SDEI_DP_EVENT_2 U(102)
+
+/* SDEI dynamic shared event numbers */
+#define TEGRA_SDEI_DS_EVENT_0 U(200)
+#define TEGRA_SDEI_DS_EVENT_1 U(201)
+#define TEGRA_SDEI_DS_EVENT_2 U(202)
+
+/* SDEI explicit events */
+#define TEGRA_SDEI_EP_EVENT_0 U(300)
+#define TEGRA_SDEI_EP_EVENT_1 U(301)
+#define TEGRA_SDEI_EP_EVENT_2 U(302)
+#define TEGRA_SDEI_EP_EVENT_3 U(303)
+#define TEGRA_SDEI_EP_EVENT_4 U(304)
+#define TEGRA_SDEI_EP_EVENT_5 U(305)
+#define TEGRA_SDEI_EP_EVENT_6 U(306)
+#define TEGRA_SDEI_EP_EVENT_7 U(307)
+#define TEGRA_SDEI_EP_EVENT_8 U(308)
+#define TEGRA_SDEI_EP_EVENT_9 U(309)
+#define TEGRA_SDEI_EP_EVENT_10 U(310)
+#define TEGRA_SDEI_EP_EVENT_11 U(311)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h
index dfed2aa60..6b87655e3 100644
--- a/plat/nvidia/tegra/include/t132/tegra_def.h
+++ b/plat/nvidia/tegra/include/t132/tegra_def.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +11,11 @@
#include <lib/utils_def.h>
/*******************************************************************************
+ * Platform BL31 specific defines.
+ ******************************************************************************/
+#define BL31_SIZE U(0x40000)
+
+/*******************************************************************************
* This value is used by the PSCI implementation during the `SYSTEM_SUSPEND`
* call as the `state-id` field in the 'power state' parameter.
******************************************************************************/
@@ -103,6 +109,8 @@
#define MC_VIDEO_PROTECT_BASE_HI U(0x978)
#define MC_VIDEO_PROTECT_BASE_LO U(0x648)
#define MC_VIDEO_PROTECT_SIZE_MB U(0x64c)
+#define MC_VIDEO_PROTECT_REG_CTRL U(0x650)
+#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3)
/*******************************************************************************
* Tegra TZRAM constants
@@ -110,4 +118,10 @@
#define TEGRA_TZRAM_BASE U(0x7C010000)
#define TEGRA_TZRAM_SIZE U(0x10000)
+/*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define TEGRA_DRAM_BASE ULL(0x80000000)
+#define TEGRA_DRAM_END ULL(0x27FFFFFFF)
+
#endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h
index 9e2c02b4b..4514e1477 100644
--- a/plat/nvidia/tegra/include/t186/tegra186_private.h
+++ b/plat/nvidia/tegra/include/t186/tegra186_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,10 +7,6 @@
#ifndef TEGRA186_PRIVATE_H
#define TEGRA186_PRIVATE_H
-void tegra186_cpu_reset_handler(void);
-uint64_t tegra186_get_cpu_reset_handler_base(void);
-uint64_t tegra186_get_cpu_reset_handler_size(void);
-uint64_t tegra186_get_smmu_ctx_offset(void);
-void tegra186_set_system_suspend_entry(void);
+uint64_t tegra186_get_mc_ctx_size(void);
#endif /* TEGRA186_PRIVATE_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index da050a895..a971cec93 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +11,11 @@
#include <lib/utils_def.h>
/*******************************************************************************
+ * Platform BL31 specific defines.
+ ******************************************************************************/
+#define BL31_SIZE U(0x40000)
+
+/*******************************************************************************
* MCE apertures used by the ARI interface
*
* Aperture 0 - Cpu0 (ARM Cortex A-57)
@@ -72,6 +78,12 @@
#define TEGRA186_SEC_IRQ_TARGET_MASK U(0xF3) /* 4 A57 - 2 Denver */
/*******************************************************************************
+ * Clock identifier for the SE device
+ ******************************************************************************/
+#define TEGRA186_CLK_SE U(103)
+#define TEGRA_CLK_SE TEGRA186_CLK_SE
+
+/*******************************************************************************
* Tegra Miscellanous register constants
******************************************************************************/
#define TEGRA_MISC_BASE U(0x00100000)
@@ -156,6 +168,8 @@
#define MC_VIDEO_PROTECT_BASE_HI U(0x978)
#define MC_VIDEO_PROTECT_BASE_LO U(0x648)
#define MC_VIDEO_PROTECT_SIZE_MB U(0x64C)
+#define MC_VIDEO_PROTECT_REG_CTRL U(0x650)
+#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3)
/*
* Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the
@@ -212,6 +226,14 @@
#define RNG_MUTEX_WATCHDOG_NS_LIMIT U(0xFE0)
/*******************************************************************************
+ * Tegra HSP doorbell #0 constants
+ ******************************************************************************/
+#define TEGRA_HSP_DBELL_BASE U(0x03C90000)
+#define HSP_DBELL_1_ENABLE U(0x104)
+#define HSP_DBELL_3_TRIGGER U(0x300)
+#define HSP_DBELL_3_ENABLE U(0x304)
+
+/*******************************************************************************
* Tegra Clock and Reset Controller constants
******************************************************************************/
#define TEGRA_CAR_RESET_BASE U(0x05000000)
@@ -237,6 +259,7 @@
* Tegra scratch registers constants
******************************************************************************/
#define TEGRA_SCRATCH_BASE U(0x0C390000)
+#define SECURE_SCRATCH_RSV0_HI U(0x654)
#define SECURE_SCRATCH_RSV1_LO U(0x658)
#define SECURE_SCRATCH_RSV1_HI U(0x65C)
#define SECURE_SCRATCH_RSV6 U(0x680)
@@ -246,12 +269,21 @@
#define SECURE_SCRATCH_RSV53_HI U(0x7FC)
#define SECURE_SCRATCH_RSV55_LO U(0x808)
#define SECURE_SCRATCH_RSV55_HI U(0x80C)
+#define SECURE_SCRATCH_RSV63_LO U(0x848)
+#define SECURE_SCRATCH_RSV63_HI U(0x84C)
+#define SECURE_SCRATCH_RSV64_LO U(0x850)
+#define SECURE_SCRATCH_RSV64_HI U(0x854)
+#define SECURE_SCRATCH_RSV65_LO U(0x858)
+#define SECURE_SCRATCH_RSV65_HI U(0x85c)
+#define SECURE_SCRATCH_RSV66_LO U(0x860)
+#define SECURE_SCRATCH_RSV66_HI U(0x864)
+#define SECURE_SCRATCH_RSV68_LO U(0x870)
#define SCRATCH_RESET_VECTOR_LO SECURE_SCRATCH_RSV1_LO
#define SCRATCH_RESET_VECTOR_HI SECURE_SCRATCH_RSV1_HI
#define SCRATCH_SECURE_BOOTP_FCFG SECURE_SCRATCH_RSV6
-#define SCRATCH_SMMU_TABLE_ADDR_LO SECURE_SCRATCH_RSV11_LO
-#define SCRATCH_SMMU_TABLE_ADDR_HI SECURE_SCRATCH_RSV11_HI
+#define SCRATCH_MC_TABLE_ADDR_LO SECURE_SCRATCH_RSV11_LO
+#define SCRATCH_MC_TABLE_ADDR_HI SECURE_SCRATCH_RSV11_HI
#define SCRATCH_BL31_PARAMS_ADDR SECURE_SCRATCH_RSV53_LO
#define SCRATCH_BL31_PLAT_PARAMS_ADDR SECURE_SCRATCH_RSV53_HI
#define SCRATCH_TZDRAM_ADDR_LO SECURE_SCRATCH_RSV55_LO
@@ -279,4 +311,17 @@
#define TEGRA_TZRAM_BASE U(0x30000000)
#define TEGRA_TZRAM_SIZE U(0x40000)
+/*******************************************************************************
+ * Tegra CCPLEX-BPMP IPC constants
+ ******************************************************************************/
+#define TEGRA_BPMP_IPC_TX_PHYS_BASE U(0x3004C000)
+#define TEGRA_BPMP_IPC_RX_PHYS_BASE U(0x3004D000)
+#define TEGRA_BPMP_IPC_CH_MAP_SIZE U(0x1000) /* 4KB */
+
+/*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define TEGRA_DRAM_BASE ULL(0x80000000)
+#define TEGRA_DRAM_END ULL(0x27FFFFFFF)
+
#endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra_mc_def.h b/plat/nvidia/tegra/include/t186/tegra_mc_def.h
index d051a150a..fa447725b 100644
--- a/plat/nvidia/tegra/include/t186/tegra_mc_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_mc_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -282,4 +282,117 @@
#define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1U << 24)
#define MC_CLIENT_HOTRESET_STATUS1 0x974U
+#ifndef __ASSEMBLER__
+
+/*******************************************************************************
+ * Structure to hold the transaction override settings to use to override
+ * client inputs
+ ******************************************************************************/
+typedef struct mc_txn_override_cfg {
+ uint32_t offset;
+ uint8_t cgid_tag;
+} mc_txn_override_cfg_t;
+
+#define mc_make_txn_override_cfg(off, val) \
+ { \
+ .offset = MC_TXN_OVERRIDE_CONFIG_ ## off, \
+ .cgid_tag = MC_TXN_OVERRIDE_ ## val \
+ }
+
+/*******************************************************************************
+ * Structure to hold the Stream ID to use to override client inputs
+ ******************************************************************************/
+typedef struct mc_streamid_override_cfg {
+ uint32_t offset;
+ uint8_t stream_id;
+} mc_streamid_override_cfg_t;
+
+/*******************************************************************************
+ * Structure to hold the Stream ID Security Configuration settings
+ ******************************************************************************/
+typedef struct mc_streamid_security_cfg {
+ char *name;
+ uint32_t offset;
+ uint32_t override_enable;
+ uint32_t override_client_inputs;
+ uint32_t override_client_ns_flag;
+} mc_streamid_security_cfg_t;
+
+#define OVERRIDE_DISABLE 1U
+#define OVERRIDE_ENABLE 0U
+#define CLIENT_FLAG_SECURE 0U
+#define CLIENT_FLAG_NON_SECURE 1U
+#define CLIENT_INPUTS_OVERRIDE 1U
+#define CLIENT_INPUTS_NO_OVERRIDE 0U
+
+/*******************************************************************************
+ * StreamID to indicate no SMMU translations (requests to be steered on the
+ * SMMU bypass path)
+ ******************************************************************************/
+#define MC_STREAM_ID_MAX 0x7FU
+
+#define mc_make_sec_cfg(off, ns, ovrrd, access) \
+ { \
+ .name = # off, \
+ .offset = MC_STREAMID_OVERRIDE_TO_SECURITY_CFG( \
+ MC_STREAMID_OVERRIDE_CFG_ ## off), \
+ .override_client_ns_flag = CLIENT_FLAG_ ## ns, \
+ .override_client_inputs = CLIENT_INPUTS_ ## ovrrd, \
+ .override_enable = OVERRIDE_ ## access \
+ }
+
+#define mc_make_sid_override_cfg(name) \
+ { \
+ .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \
+ .val = 0x00000000U, \
+ }
+
+#define mc_make_sid_security_cfg(name) \
+ { \
+ .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(MC_STREAMID_OVERRIDE_CFG_ ## name), \
+ .val = 0x00000000U, \
+ }
+
+#define mc_set_pcfifo_unordered_boot_so_mss(id, client) \
+ ((uint32_t)~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
+ MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED)
+
+#define mc_set_pcfifo_ordered_boot_so_mss(id, client) \
+ MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_ORDERED
+
+#define mc_set_tsa_passthrough(client) \
+ do { \
+ mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
+ (TSA_CONFIG_STATIC0_CSW_##client##_RESET & \
+ (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+ (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+ } while (0)
+
+#define mc_set_tsa_w_passthrough(client) \
+ do { \
+ mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
+ (TSA_CONFIG_STATIC0_CSW_RESET_W & \
+ (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+ (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+ } while (0)
+
+#define mc_set_tsa_r_passthrough(client) \
+ { \
+ mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSR_##client, \
+ (TSA_CONFIG_STATIC0_CSR_RESET_R & \
+ (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+ (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+ } while (0)
+
+#define mc_set_txn_override(client, normal_axi_id, so_dev_axi_id, normal_override, so_dev_override) \
+ do { \
+ tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
+ MC_TXN_OVERRIDE_##normal_axi_id | \
+ MC_TXN_OVERRIDE_CONFIG_COH_PATH_##so_dev_override##_SO_DEV | \
+ MC_TXN_OVERRIDE_CONFIG_COH_PATH_##normal_override##_NORMAL | \
+ MC_TXN_OVERRIDE_CONFIG_CGID_##so_dev_axi_id); \
+ } while (0)
+
+#endif /* __ASSEMBLER__ */
+
#endif /* TEGRA_MC_DEF_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra194_private.h b/plat/nvidia/tegra/include/t194/tegra194_private.h
index 8f1deb2a3..c5a51e951 100644
--- a/plat/nvidia/tegra/include/t194/tegra194_private.h
+++ b/plat/nvidia/tegra/include/t194/tegra194_private.h
@@ -10,7 +10,7 @@
void tegra194_cpu_reset_handler(void);
uint64_t tegra194_get_cpu_reset_handler_base(void);
uint64_t tegra194_get_cpu_reset_handler_size(void);
-uint64_t tegra194_get_smmu_ctx_offset(void);
+uint64_t tegra194_get_mc_ctx_offset(void);
void tegra194_set_system_suspend_entry(void);
#endif /* TEGRA194_PRIVATE_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra194_ras_private.h b/plat/nvidia/tegra/include/t194/tegra194_ras_private.h
new file mode 100644
index 000000000..336461af3
--- /dev/null
+++ b/plat/nvidia/tegra/include/t194/tegra194_ras_private.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA194_RAS_PRIVATE
+#define TEGRA194_RAS_PRIVATE
+
+#include <stdint.h>
+
+/* Implementation defined RAS error and corresponding error message */
+struct ras_error {
+ const char *error_msg;
+ /* IERR(bits[15:8]) from ERR<n>STATUS */
+ uint8_t error_code;
+};
+
+/* RAS error node-specific auxiliary data */
+struct ras_aux_data {
+ /* name for current RAS node. */
+ const char *name;
+ /* point to null-terminated ras_error array to convert error code to msg. */
+ const struct ras_error *error_records;
+ /*
+ * function to return an value which needs to be programmed into ERXCTLR_EL1
+ * to enable all specified RAS errors for current node.
+ */
+ uint64_t (*err_ctrl)(void);
+};
+
+/* IFU Uncorrectable RAS ERROR */
+#define IFU_UNCORR_RAS_ERROR_LIST(X)
+
+/* JSR_RET Uncorrectable RAS ERROR */
+#define JSR_RET_UNCORR_RAS_ERROR_LIST(X) \
+ /* Name, ERR_CTRL, IERR, ISA Desc */ \
+ X(JSR_RET, 35, 0x13, "Floating Point Register File Parity Error") \
+ X(JSR_RET, 34, 0x12, "Integer Register File Parity Error") \
+ X(JSR_RET, 33, 0x11, "Garbage Bundle") \
+ X(JSR_RET, 32, 0x10, "Bundle Completion Timeout")
+
+/* JSR_MTS Uncorrectable RAS ERROR */
+#define JSR_MTS_UNCORR_RAS_ERROR_LIST(X) \
+ /* Name, ERR_CTRL, IERR, ISA Desc */ \
+ X(JSR_MTS, 40, 0x28, "CoreSight Access Error") \
+ X(JSR_MTS, 39, 0x27, "Dual Execution Uncorrectable Error") \
+ X(JSR_MTS, 37, 0x25, "CTU MMIO Region") \
+ X(JSR_MTS, 36, 0x24, "MTS MMCRAB Region Access") \
+ X(JSR_MTS, 35, 0x23, "MTS_CARVEOUT Access from ARM SW") \
+ X(JSR_MTS, 34, 0x22, "NAFLL PLL Failure to Lock") \
+ X(JSR_MTS, 32, 0x20, "Internal Uncorrectable MTS Error")
+
+/* LSD_STQ Uncorrectable RAS ERROR */
+#define LSD_STQ_UNCORR_RAS_ERROR_LIST(X) \
+ /* Name, ERR_CTRL, IERR, ISA Desc */ \
+ X(LSD_STQ, 41, 0x39, "Coherent Cache Data Store Multi-Line ECC Error") \
+ X(LSD_STQ, 40, 0x38, "Coherent Cache Data Store Uncorrectable ECC Error") \
+ X(LSD_STQ, 38, 0x36, "Coherent Cache Data Load Uncorrectable ECC Error") \
+ X(LSD_STQ, 33, 0x31, "Coherent Cache Tag Store Parity Error") \
+ X(LSD_STQ, 32, 0x30, "Coherent Cache Tag Load Parity Error")
+
+/* LSD_DCC Uncorrectable RAS ERROR */
+#define LSD_DCC_UNCORR_RAS_ERROR_LIST(X) \
+ /* Name, ERR_CTRL, IERR, ISA Desc */ \
+ X(LSD_DCC, 41, 0x49, "BTU Copy Mini-Cache PPN Multi-Hit Error") \
+ X(LSD_DCC, 39, 0x47, "Coherent Cache Data Uncorrectable ECC Error") \
+ X(LSD_DCC, 37, 0x45, "Version Cache Byte-Enable Parity Error") \
+ X(LSD_DCC, 36, 0x44, "Version Cache Data Uncorrectable ECC Error") \
+ X(LSD_DCC, 33, 0x41, "BTU Copy Coherent Cache PPN Parity Error") \
+ X(LSD_DCC, 32, 0x40, "BTU Copy Coherent Cache VPN Parity Error")
+
+/* LSD_L1HPF Uncorrectable RAS ERROR */
+#define LSD_L1HPF_UNCORR_RAS_ERROR_LIST(X)
+
+/* L2 Uncorrectable RAS ERROR */
+#define L2_UNCORR_RAS_ERROR_LIST(X) \
+ /* Name, ERR_CTRL, IERR, ISA Desc */ \
+ X(L2, 56, 0x68, "URT Timeout") \
+ X(L2, 55, 0x67, "L2 Protocol Violation") \
+ X(L2, 54, 0x66, "SCF to L2 Slave Error Read") \
+ X(L2, 53, 0x65, "SCF to L2 Slave Error Write") \
+ X(L2, 52, 0x64, "SCF to L2 Decode Error Read") \
+ X(L2, 51, 0x63, "SCF to L2 Decode Error Write") \
+ X(L2, 50, 0x62, "SCF to L2 Request Response Interface Parity Errors") \
+ X(L2, 49, 0x61, "SCF to L2 Advance notice interface parity errors") \
+ X(L2, 48, 0x60, "SCF to L2 Filldata Parity Errors") \
+ X(L2, 47, 0x5F, "SCF to L2 UnCorrectable ECC Data Error on interface") \
+ X(L2, 45, 0x5D, "Core 1 to L2 Parity Error") \
+ X(L2, 44, 0x5C, "Core 0 to L2 Parity Error") \
+ X(L2, 43, 0x5B, "L2 Multi-Hit") \
+ X(L2, 42, 0x5A, "L2 URT Tag Parity Error") \
+ X(L2, 41, 0x59, "L2 NTT Tag Parity Error") \
+ X(L2, 40, 0x58, "L2 MLT Tag Parity Error") \
+ X(L2, 39, 0x57, "L2 URD Data") \
+ X(L2, 38, 0x56, "L2 NTP Data") \
+ X(L2, 36, 0x54, "L2 MLC Uncorrectable Clean") \
+ X(L2, 35, 0x53, "L2 URD Uncorrectable Dirty") \
+ X(L2, 34, 0x52, "L2 MLC Uncorrectable Dirty")
+
+/* CLUSTER_CLOCKS Uncorrectable RAS ERROR */
+#define CLUSTER_CLOCKS_UNCORR_RAS_ERROR_LIST(X) \
+ /* Name, ERR_CTRL, IERR, ISA Desc */ \
+ X(CLUSTER_CLOCKS, 32, 0xE4, "Frequency Monitor Error")
+
+/* MMU Uncorrectable RAS ERROR */
+#define MMU_UNCORR_RAS_ERROR_LIST(X)
+
+/* L3 Uncorrectable RAS ERROR */
+#define L3_UNCORR_RAS_ERROR_LIST(X) \
+ /* Name, ERR_CTRL, IERR, ISA Desc */ \
+ X(L3, 43, 0x7B, "SNOC Interface Parity Error") \
+ X(L3, 42, 0x7A, "MCF Interface Parity Error") \
+ X(L3, 41, 0x79, "L3 Tag Parity Error") \
+ X(L3, 40, 0x78, "L3 Dir Parity Error") \
+ X(L3, 39, 0x77, "L3 Uncorrectable ECC Error") \
+ X(L3, 37, 0x75, "Multi-Hit CAM Error") \
+ X(L3, 36, 0x74, "Multi-Hit Tag Error") \
+ X(L3, 35, 0x73, "Unrecognized Command Error") \
+ X(L3, 34, 0x72, "L3 Protocol Error")
+
+/* CCPMU Uncorrectable RAS ERROR */
+#define CCPMU_UNCORR_RAS_ERROR_LIST(X) \
+ /* Name, ERR_CTRL, IERR, ISA Desc */ \
+ X(CCPMU, 40, 0x87, "CoreSight Access Error") \
+ X(CCPMU, 36, 0x84, "MCE Ucode Error") \
+ X(CCPMU, 35, 0x83, "MCE IL1 Parity Error") \
+ X(CCPMU, 34, 0x82, "MCE Timeout Error") \
+ X(CCPMU, 33, 0x81, "CRAB Access Error") \
+ X(CCPMU, 32, 0x80, "MCE Memory Access Error")
+
+/* SCF_IOB Uncorrectable RAS ERROR */
+#define SCF_IOB_UNCORR_RAS_ERROR_LIST(X) \
+ /* Name, ERR_CTRL, IERR, ISA Desc */ \
+ X(SCF_IOB, 41, 0x99, "Request parity error") \
+ X(SCF_IOB, 40, 0x98, "Putdata parity error") \
+ X(SCF_IOB, 39, 0x97, "Uncorrectable ECC on Putdata") \
+ X(SCF_IOB, 38, 0x96, "CBB Interface Error") \
+ X(SCF_IOB, 37, 0x95, "MMCRAB Error") \
+ X(SCF_IOB, 36, 0x94, "IHI Interface Error") \
+ X(SCF_IOB, 35, 0x93, "CRI Error") \
+ X(SCF_IOB, 34, 0x92, "TBX Interface Error") \
+ X(SCF_IOB, 33, 0x91, "EVP Interface Error")
+
+/* SCF_SNOC Uncorrectable RAS ERROR */
+#define SCF_SNOC_UNCORR_RAS_ERROR_LIST(X) \
+ /* Name, ERR_CTRL, IERR, ISA Desc */ \
+ X(SCF_SNOC, 42, 0xAA, "Misc Client Parity Error") \
+ X(SCF_SNOC, 41, 0xA9, "Misc Filldata Parity Error") \
+ X(SCF_SNOC, 40, 0xA8, "Uncorrectable ECC Misc Client") \
+ X(SCF_SNOC, 39, 0xA7, "DVMU Interface Parity Error") \
+ X(SCF_SNOC, 38, 0xA6, "DVMU Interface Timeout Error") \
+ X(SCF_SNOC, 37, 0xA5, "CPE Request Error") \
+ X(SCF_SNOC, 36, 0xA4, "CPE Response Error") \
+ X(SCF_SNOC, 35, 0xA3, "CPE Timeout Error") \
+ X(SCF_SNOC, 34, 0xA2, "Uncorrectable Carveout Error")
+
+/* SCF_CTU Uncorrectable RAS ERROR */
+#define SCF_CTU_UNCORR_RAS_ERROR_LIST(X) \
+ /* Name, ERR_CTRL, IERR, ISA Desc */ \
+ X(SCF_CTU, 39, 0xB7, "Timeout error for TRC_DMA request") \
+ X(SCF_CTU, 38, 0xB6, "Timeout error for CTU Snp") \
+ X(SCF_CTU, 37, 0xB5, "Parity error in CTU TAG RAM") \
+ X(SCF_CTU, 36, 0xB3, "Parity error in CTU DATA RAM") \
+ X(SCF_CTU, 35, 0xB4, "Parity error for Cluster Rsp") \
+ X(SCF_CTU, 34, 0xB2, "Parity error for TRL requests from 9 agents") \
+ X(SCF_CTU, 33, 0xB1, "Parity error for MCF request") \
+ X(SCF_CTU, 32, 0xB0, "TRC DMA fillsnoop parity error")
+
+/* CMU_CLOCKS Uncorrectable RAS ERROR */
+#define CMU_CLOCKS_UNCORR_RAS_ERROR_LIST(X) \
+ /* Name, ERR_CTRL, IERR, ISA Desc */ \
+ X(CMU_CLOCKS, 39, 0xC7, "Cluster 3 frequency monitor error") \
+ X(CMU_CLOCKS, 38, 0xC6, "Cluster 2 frequency monitor error") \
+ X(CMU_CLOCKS, 37, 0xC5, "Cluster 1 frequency monitor error") \
+ X(CMU_CLOCKS, 36, 0xC3, "Cluster 0 frequency monitor error") \
+ X(CMU_CLOCKS, 35, 0xC4, "Voltage error on ADC1 Monitored Logic") \
+ X(CMU_CLOCKS, 34, 0xC2, "Voltage error on ADC0 Monitored Logic") \
+ X(CMU_CLOCKS, 33, 0xC1, "Lookup Table 1 Parity Error") \
+ X(CMU_CLOCKS, 32, 0xC0, "Lookup Table 0 Parity Error")
+
+/*
+ * Define one ras_error entry.
+ *
+ * This macro wille be used to to generate ras_error records for each node
+ * defined by <NODE_NAME>_UNCORR_RAS_ERROR_LIST macro.
+ */
+#define DEFINE_ONE_RAS_ERROR_MSG(unit, ras_bit, ierr, msg) \
+ { \
+ .error_msg = (msg), \
+ .error_code = (ierr) \
+ },
+
+/*
+ * Set one implementation defined bit in ERR<n>CTLR
+ *
+ * This macro will be used to collect all defined ERR_CTRL bits for each node
+ * defined by <NODE_NAME>_UNCORR_RAS_ERROR_LIST macro.
+ */
+#define DEFINE_ENABLE_RAS_BIT(unit, ras_bit, ierr, msg) \
+ do { \
+ val |= (1ULL << ras_bit##U); \
+ } while (0);
+
+/* Represent one RAS node with 0 or more error bits (ERR_CTLR) enabled */
+#define DEFINE_ONE_RAS_NODE(node) \
+static const struct ras_error node##_uncorr_ras_errors[] = { \
+ node##_UNCORR_RAS_ERROR_LIST(DEFINE_ONE_RAS_ERROR_MSG) \
+ { \
+ NULL, \
+ 0U \
+ }, \
+}; \
+static inline uint64_t node##_err_ctrl(void) \
+{ \
+ uint64_t val = 0ULL; \
+ node##_UNCORR_RAS_ERROR_LIST(DEFINE_ENABLE_RAS_BIT) \
+ return val; \
+}
+
+#define DEFINE_ONE_RAS_AUX_DATA(node) \
+ { \
+ .name = #node, \
+ .error_records = node##_uncorr_ras_errors, \
+ .err_ctrl = &node##_err_ctrl \
+ },
+
+#define PER_CORE_RAS_NODE_LIST(X) \
+ X(IFU) \
+ X(JSR_RET) \
+ X(JSR_MTS) \
+ X(LSD_STQ) \
+ X(LSD_DCC) \
+ X(LSD_L1HPF)
+
+#define PER_CORE_RAS_GROUP_NODES PER_CORE_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA)
+
+#define PER_CLUSTER_RAS_NODE_LIST(X) \
+ X(L2) \
+ X(CLUSTER_CLOCKS) \
+ X(MMU)
+
+#define PER_CLUSTER_RAS_GROUP_NODES PER_CLUSTER_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA)
+
+#define SCF_L3_BANK_RAS_NODE_LIST(X) X(L3)
+
+/* we have 4 SCF_L3 nodes:3*256 + L3_Bank_ID(0-3) */
+#define SCF_L3_BANK_RAS_GROUP_NODES \
+ SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA) \
+ SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA) \
+ SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA) \
+ SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA)
+
+#define CCPLEX_RAS_NODE_LIST(X) \
+ X(CCPMU) \
+ X(SCF_IOB) \
+ X(SCF_SNOC) \
+ X(SCF_CTU) \
+ X(CMU_CLOCKS)
+
+#define CCPLEX_RAS_GROUP_NODES CCPLEX_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA)
+
+#endif /* TEGRA194_RAS_PRIVATE */
diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h
index df1d65630..abe193fcd 100644
--- a/plat/nvidia/tegra/include/t194/tegra_def.h
+++ b/plat/nvidia/tegra/include/t194/tegra_def.h
@@ -10,6 +10,17 @@
#include <lib/utils_def.h>
/*******************************************************************************
+ * Platform BL31 specific defines.
+ ******************************************************************************/
+#define BL31_SIZE U(0x40000)
+
+/*******************************************************************************
+ * Chip specific cluster and cpu numbers
+ ******************************************************************************/
+#define PLATFORM_CLUSTER_COUNT U(4)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER U(2)
+
+/*******************************************************************************
* Chip specific page table and MMU setup constants
******************************************************************************/
#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 40)
@@ -43,6 +54,12 @@
#define TEGRA194_SEC_IRQ_TARGET_MASK U(0xFF) /* 8 Carmel */
/*******************************************************************************
+ * Clock identifier for the SE device
+ ******************************************************************************/
+#define TEGRA194_CLK_SE U(124)
+#define TEGRA_CLK_SE TEGRA194_CLK_SE
+
+/*******************************************************************************
* Tegra Miscellanous register constants
******************************************************************************/
#define TEGRA_MISC_BASE U(0x00100000)
@@ -93,6 +110,8 @@
#define MC_VIDEO_PROTECT_BASE_HI U(0x978)
#define MC_VIDEO_PROTECT_BASE_LO U(0x648)
#define MC_VIDEO_PROTECT_SIZE_MB U(0x64c)
+#define MC_VIDEO_PROTECT_REG_CTRL U(0x650)
+#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3)
/*
* Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the
@@ -197,6 +216,16 @@
* Tegra scratch registers constants
******************************************************************************/
#define TEGRA_SCRATCH_BASE U(0x0C390000)
+#define SECURE_SCRATCH_RSV68_LO U(0x284)
+#define SECURE_SCRATCH_RSV68_HI U(0x288)
+#define SECURE_SCRATCH_RSV69_LO U(0x28C)
+#define SECURE_SCRATCH_RSV69_HI U(0x290)
+#define SECURE_SCRATCH_RSV70_LO U(0x294)
+#define SECURE_SCRATCH_RSV70_HI U(0x298)
+#define SECURE_SCRATCH_RSV71_LO U(0x29C)
+#define SECURE_SCRATCH_RSV71_HI U(0x2A0)
+#define SECURE_SCRATCH_RSV72_LO U(0x2A4)
+#define SECURE_SCRATCH_RSV72_HI U(0x2A8)
#define SECURE_SCRATCH_RSV75 U(0x2BC)
#define SECURE_SCRATCH_RSV81_LO U(0x2EC)
#define SECURE_SCRATCH_RSV81_HI U(0x2F0)
@@ -215,8 +244,8 @@
#define SCRATCH_BL31_PLAT_PARAMS_HI_ADDR_SHIFT U(16)
#define SCRATCH_BL31_PLAT_PARAMS_LO_ADDR SECURE_SCRATCH_RSV81_HI
#define SCRATCH_SECURE_BOOTP_FCFG SECURE_SCRATCH_RSV97
-#define SCRATCH_SMMU_TABLE_ADDR_LO SECURE_SCRATCH_RSV99_LO
-#define SCRATCH_SMMU_TABLE_ADDR_HI SECURE_SCRATCH_RSV99_HI
+#define SCRATCH_MC_TABLE_ADDR_LO SECURE_SCRATCH_RSV99_LO
+#define SCRATCH_MC_TABLE_ADDR_HI SECURE_SCRATCH_RSV99_HI
#define SCRATCH_RESET_VECTOR_LO SECURE_SCRATCH_RSV109_LO
#define SCRATCH_RESET_VECTOR_HI SECURE_SCRATCH_RSV109_HI
@@ -257,6 +286,12 @@
#define TEGRA_GPCDMA_RST_CLR_REG_OFFSET U(0x6A0008)
/*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define TEGRA_DRAM_BASE ULL(0x80000000)
+#define TEGRA_DRAM_END ULL(0xFFFFFFFFF)
+
+/*******************************************************************************
* XUSB STREAMIDs
******************************************************************************/
#define TEGRA_SID_XUSB_HOST U(0x1b)
@@ -266,4 +301,26 @@
#define TEGRA_SID_XUSB_VF2 U(0x5f)
#define TEGRA_SID_XUSB_VF3 U(0x60)
+/*******************************************************************************
+ * SCR addresses and expected settings
+ ******************************************************************************/
+#define SCRATCH_RSV68_SCR U(0x0C398110)
+#define SCRATCH_RSV68_SCR_VAL U(0x38000101)
+#define SCRATCH_RSV71_SCR U(0x0C39811C)
+#define SCRATCH_RSV71_SCR_VAL U(0x38000101)
+#define SCRATCH_RSV72_SCR U(0x0C398120)
+#define SCRATCH_RSV72_SCR_VAL U(0x38000101)
+#define SCRATCH_RSV75_SCR U(0x0C39812C)
+#define SCRATCH_RSV75_SCR_VAL U(0x3A000005)
+#define SCRATCH_RSV81_SCR U(0x0C398144)
+#define SCRATCH_RSV81_SCR_VAL U(0x3A000105)
+#define SCRATCH_RSV97_SCR U(0x0C398184)
+#define SCRATCH_RSV97_SCR_VAL U(0x38000101)
+#define SCRATCH_RSV99_SCR U(0x0C39818C)
+#define SCRATCH_RSV99_SCR_VAL U(0x38000101)
+#define SCRATCH_RSV109_SCR U(0x0C3981B4)
+#define SCRATCH_RSV109_SCR_VAL U(0x38000101)
+#define MISCREG_SCR_SCRTZWELCK U(0x00109000)
+#define MISCREG_SCR_SCRTZWELCK_VAL U(0x30000100)
+
#endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra_mc_def.h b/plat/nvidia/tegra/include/t194/tegra_mc_def.h
deleted file mode 100644
index 34bdd7557..000000000
--- a/plat/nvidia/tegra/include/t194/tegra_mc_def.h
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TEGRA_MC_DEF_H
-#define TEGRA_MC_DEF_H
-
-/*******************************************************************************
- * Memory Controller Order_id registers
- ******************************************************************************/
-#define MC_CLIENT_ORDER_ID_9 U(0x2a24)
-#define MC_CLIENT_ORDER_ID_9_RESET_VAL 0x00000000U
-#define MC_CLIENT_ORDER_ID_9_XUSB_HOSTW_MASK (0x3U << 12)
-#define MC_CLIENT_ORDER_ID_9_XUSB_HOSTW_ORDER_ID (3U << 12)
-
-#define MC_CLIENT_ORDER_ID_27 U(0x2a6c)
-#define MC_CLIENT_ORDER_ID_27_RESET_VAL 0x00000000U
-#define MC_CLIENT_ORDER_ID_27_PCIE0W_MASK (0x3U << 4)
-#define MC_CLIENT_ORDER_ID_27_PCIE0W_ORDER_ID (2U << 4)
-
-#define MC_CLIENT_ORDER_ID_28 U(0x2a70)
-#define MC_CLIENT_ORDER_ID_28_RESET_VAL 0x00000000U
-#define MC_CLIENT_ORDER_ID_28_PCIE4W_MASK (0x3U << 4)
-#define MC_CLIENT_ORDER_ID_28_PCIE4W_ORDER_ID (3U << 4)
-#define MC_CLIENT_ORDER_ID_28_PCIE5W_MASK (0x3U << 12)
-#define MC_CLIENT_ORDER_ID_28_PCIE5W_ORDER_ID (1U << 12)
-
-#define mc_client_order_id(val, id, client) \
- ((val & ~MC_CLIENT_ORDER_ID_##id##_##client##_MASK) | \
- MC_CLIENT_ORDER_ID_##id##_##client##_ORDER_ID)
-
-/*******************************************************************************
- * Memory Controller's VC ID configuration registers
- ******************************************************************************/
-#define VC_NISO 0U
-#define VC_SISO 1U
-#define VC_ISO 2U
-
-#define MC_HUB_PC_VC_ID_0 U(0x2a78)
-#define MC_HUB_PC_VC_ID_0_RESET_VAL 0x00020100U
-#define MC_HUB_PC_VC_ID_0_APB_VC_ID_MASK (0x3U << 8)
-#define MC_HUB_PC_VC_ID_0_APB_VC_ID (VC_NISO << 8)
-
-#define MC_HUB_PC_VC_ID_2 U(0x2a80)
-#define MC_HUB_PC_VC_ID_2_RESET_VAL 0x10001000U
-#define MC_HUB_PC_VC_ID_2_SD_VC_ID_MASK (0x3U << 28)
-#define MC_HUB_PC_VC_ID_2_SD_VC_ID (VC_NISO << 28)
-
-#define MC_HUB_PC_VC_ID_4 U(0x2a88)
-#define MC_HUB_PC_VC_ID_4_RESET_VAL 0x10020011U
-#define MC_HUB_PC_VC_ID_4_NIC_VC_ID_MASK (0x3U << 28)
-#define MC_HUB_PC_VC_ID_4_NIC_VC_ID (VC_NISO << 28)
-
-#define MC_HUB_PC_VC_ID_12 U(0x2aa8)
-#define MC_HUB_PC_VC_ID_12_RESET_VAL 0x11001011U
-#define MC_HUB_PC_VC_ID_12_UFSHCPC2_VC_ID_MASK (0x3U << 12)
-#define MC_HUB_PC_VC_ID_12_UFSHCPC2_VC_ID (VC_NISO << 12)
-
-#define mc_hub_vc_id(val, id, client) \
- ((val & ~MC_HUB_PC_VC_ID_##id##_##client##_VC_ID_MASK) | \
- MC_HUB_PC_VC_ID_##id##_##client##_VC_ID)
-
-/*******************************************************************************
- * Memory Controller's PCFIFO client configuration registers
- ******************************************************************************/
-#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0U
-
-#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4U
-#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20200000U
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0U << 17)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1U << 17)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0U << 21)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1U << 21)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0U << 29)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_ORDERED (1U << 29)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1U << 29)
-
-#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8U
-#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x00002800U
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0U << 11)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1U << 11)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0U << 13)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_ORDERED (1U << 13)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1U << 13)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_TSECSWR_UNORDERED (0U << 21)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_TSECSWR_MASK (1U << 21)
-
-#define MC_PCFIFO_CLIENT_CONFIG3 0xddcU
-#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0x08000080U
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWA_UNORDERED (0U << 4)
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWA_MASK (1U << 4)
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCW_UNORDERED (0U << 6)
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCW_MASK (1U << 6)
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0U << 7)
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1U << 7)
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_VICSWR_UNORDERED (0U << 13)
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_VICSWR_MASK (1U << 13)
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_APEW_UNORDERED (0U << 27)
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_APEW_MASK (1U << 27)
-
-#define MC_PCFIFO_CLIENT_CONFIG4 0xde0U
-#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0x5552a022U
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0U << 1)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1U << 1)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0U << 5)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1U << 5)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_TSECSWRB_UNORDERED (0U << 7)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_TSECSWRB_MASK (1U << 7)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0U << 13)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1U << 13)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0U << 15)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1U << 15)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0U << 17)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1U << 17)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPW_UNORDERED (0U << 20)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPW_MASK (1U << 20)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0U << 22)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1U << 22)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONW_UNORDERED (0U << 24)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONW_MASK (1U << 24)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0U << 26)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1U << 26)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEW_UNORDERED (0U << 28)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEW_MASK (1U << 28)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0U << 30)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1U << 30)
-
-#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4U
-#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0x20000001U
-#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0U << 0)
-#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1U << 0)
-#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_VIFALW_UNORDERED (0U << 30)
-#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_VIFALW_MASK (1U << 30)
-
-#define MC_PCFIFO_CLIENT_CONFIG6 0xb90U
-#define MC_PCFIFO_CLIENT_CONFIG6_RESET_VAL 0xaa280000U
-#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEW_UNORDERED (0U << 19)
-#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEW_MASK (1U << 19)
-#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEDMAW_UNORDERED (0U << 21)
-#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEDMAW_MASK (1U << 21)
-#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE0W_UNORDERED (0U << 25)
-#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE0W_MASK (1U << 25)
-#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE1W_ORDERED (1U << 27)
-#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE1W_MASK (1U << 27)
-#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE2W_ORDERED (1U << 29)
-#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE2W_MASK (1U << 29)
-#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE3W_ORDERED (1U << 31)
-#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE3W_MASK (1U << 31)
-
-#define MC_PCFIFO_CLIENT_CONFIG7 0xaccU
-#define MC_PCFIFO_CLIENT_CONFIG7_RESET_VAL 0x0000000aU
-#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE4W_UNORDERED (0U << 1)
-#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE4W_MASK (1U << 1)
-#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE5W_UNORDERED (0U << 3)
-#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE5W_MASK (1U << 3)
-
-/*******************************************************************************
- * StreamID to indicate no SMMU translations (requests to be steered on the
- * SMMU bypass path)
- ******************************************************************************/
-#define MC_STREAM_ID_MAX 0x7FU
-
-/*******************************************************************************
- * Stream ID Override Config registers
- ******************************************************************************/
-#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA 0x660U
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD 0xe0U
-#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR 0x3f8U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA1 0x758U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0RDC 0x640U
-#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA 0x5f0U
-#define MC_STREAMID_OVERRIDE_CFG_BPMPR 0x498U
-#define MC_STREAMID_OVERRIDE_CFG_APEDMAR 0x4f8U
-#define MC_STREAMID_OVERRIDE_CFG_AXISR 0x460U
-#define MC_STREAMID_OVERRIDE_CFG_TSECSRD 0x2a0U
-#define MC_STREAMID_OVERRIDE_CFG_DLA0FALRDB 0x5f8U
-#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1 0x788U
-#define MC_STREAMID_OVERRIDE_CFG_MPCOREW 0x1c8U
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD1 0x780U
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR 0x250U
-#define MC_STREAMID_OVERRIDE_CFG_MIU1R 0x540U
-#define MC_STREAMID_OVERRIDE_CFG_MIU0R 0x530U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE1W 0x6d8U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1WRA 0x678U
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW 0x258U
-#define MC_STREAMID_OVERRIDE_CFG_AXIAPW 0x418U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB 0x338U
-#define MC_STREAMID_OVERRIDE_CFG_SATAW 0x1e8U
-#define MC_STREAMID_OVERRIDE_CFG_DLA0WRA 0x600U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE3R 0x6f0U
-#define MC_STREAMID_OVERRIDE_CFG_MIU3W 0x588U
-#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR 0x4e8U
-#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR 0xb0U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA 0x320U
-#define MC_STREAMID_OVERRIDE_CFG_MIU2R 0x570U
-#define MC_STREAMID_OVERRIDE_CFG_APEDMAW 0x500U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE2AW 0x6e8U
-#define MC_STREAMID_OVERRIDE_CFG_SESWR 0x408U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB1 0x770U
-#define MC_STREAMID_OVERRIDE_CFG_AXISW 0x468U
-#define MC_STREAMID_OVERRIDE_CFG_DLA1FALRDB 0x618U
-#define MC_STREAMID_OVERRIDE_CFG_AONDMAW 0x4d0U
-#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB 0x438U
-#define MC_STREAMID_OVERRIDE_CFG_ISPWB 0x238U
-#define MC_STREAMID_OVERRIDE_CFG_HDAR 0xa8U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA 0x300U
-#define MC_STREAMID_OVERRIDE_CFG_ETRW 0x428U
-#define MC_STREAMID_OVERRIDE_CFG_RCEDMAW 0x6a8U
-#define MC_STREAMID_OVERRIDE_CFG_TSECSWR 0x2a8U
-#define MC_STREAMID_OVERRIDE_CFG_ETRR 0x420U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCR 0x310U
-#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD 0x3f0U
-#define MC_STREAMID_OVERRIDE_CFG_AONDMAR 0x4c8U
-#define MC_STREAMID_OVERRIDE_CFG_SCER 0x4d8U
-#define MC_STREAMID_OVERRIDE_CFG_MIU5W 0x7e8U
-#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD 0x6b0U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE4R 0x700U
-#define MC_STREAMID_OVERRIDE_CFG_ISPWA 0x230U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE0W 0x6c8U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE5R1 0x778U
-#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA 0x610U
-#define MC_STREAMID_OVERRIDE_CFG_VICSWR 0x368U
-#define MC_STREAMID_OVERRIDE_CFG_SESRD 0x400U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCW 0x330U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB 0x318U
-#define MC_STREAMID_OVERRIDE_CFG_ISPFALW 0x720U
-#define MC_STREAMID_OVERRIDE_CFG_EQOSW 0x478U
-#define MC_STREAMID_OVERRIDE_CFG_RCEDMAR 0x6a0U
-#define MC_STREAMID_OVERRIDE_CFG_RCER 0x690U
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR 0x3c8U
-#define MC_STREAMID_OVERRIDE_CFG_UFSHCR 0x480U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE4W 0x708U
-#define MC_STREAMID_OVERRIDE_CFG_VICSRD 0x360U
-#define MC_STREAMID_OVERRIDE_CFG_APER 0x3d0U
-#define MC_STREAMID_OVERRIDE_CFG_MIU7R 0x8U
-#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD 0x7c8U
-#define MC_STREAMID_OVERRIDE_CFG_MIU7W 0x10U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA1 0x768U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1WRC 0x688U
-#define MC_STREAMID_OVERRIDE_CFG_AONW 0x4c0U
-#define MC_STREAMID_OVERRIDE_CFG_MIU4W 0x598U
-#define MC_STREAMID_OVERRIDE_CFG_HDAW 0x1a8U
-#define MC_STREAMID_OVERRIDE_CFG_BPMPW 0x4a0U
-#define MC_STREAMID_OVERRIDE_CFG_DLA1WRA 0x620U
-#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA1 0x748U
-#define MC_STREAMID_OVERRIDE_CFG_MIU1W 0x548U
-#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1 0x508U
-#define MC_STREAMID_OVERRIDE_CFG_VICSRD1 0x510U
-#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW 0x4b0U
-#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SWR 0x7d8U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0WRC 0x658U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE5R 0x710U
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR 0x260U
-#define MC_STREAMID_OVERRIDE_CFG_UFSHCW 0x488U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1WRB 0x680U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0WRB 0x650U
-#define MC_STREAMID_OVERRIDE_CFG_DLA1FALWRB 0x628U
-#define MC_STREAMID_OVERRIDE_CFG_NVENC1SWR 0x6b8U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE0R 0x6c0U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE3W 0x6f8U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA 0x630U
-#define MC_STREAMID_OVERRIDE_CFG_MIU6W 0x7f8U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE1R 0x6d0U
-#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD1 0x7d0U
-#define MC_STREAMID_OVERRIDE_CFG_DLA0FALWRB 0x608U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1RDC 0x670U
-#define MC_STREAMID_OVERRIDE_CFG_MIU0W 0x538U
-#define MC_STREAMID_OVERRIDE_CFG_MIU2W 0x578U
-#define MC_STREAMID_OVERRIDE_CFG_MPCORER 0x138U
-#define MC_STREAMID_OVERRIDE_CFG_AXIAPR 0x410U
-#define MC_STREAMID_OVERRIDE_CFG_AONR 0x4b8U
-#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR 0x4a8U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB 0x638U
-#define MC_STREAMID_OVERRIDE_CFG_VIFALW 0x5e8U
-#define MC_STREAMID_OVERRIDE_CFG_MIU6R 0x7f0U
-#define MC_STREAMID_OVERRIDE_CFG_EQOSR 0x470U
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD 0x3c0U
-#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB 0x430U
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 0x518U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB1 0x760U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE0R1 0x798U
-#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW 0x4f0U
-#define MC_STREAMID_OVERRIDE_CFG_APEW 0x3d8U
-#define MC_STREAMID_OVERRIDE_CFG_MIU5R 0x7e0U
-#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA1 0x750U
-#define MC_STREAMID_OVERRIDE_CFG_PVA0WRA 0x648U
-#define MC_STREAMID_OVERRIDE_CFG_ISPFALR 0x228U
-#define MC_STREAMID_OVERRIDE_CFG_PTCR 0x0U
-#define MC_STREAMID_OVERRIDE_CFG_MIU4R 0x590U
-#define MC_STREAMID_OVERRIDE_CFG_ISPRA 0x220U
-#define MC_STREAMID_OVERRIDE_CFG_VIFALR 0x5e0U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE2AR 0x6e0U
-#define MC_STREAMID_OVERRIDE_CFG_RCEW 0x698U
-#define MC_STREAMID_OVERRIDE_CFG_ISPRA1 0x790U
-#define MC_STREAMID_OVERRIDE_CFG_SCEW 0x4e0U
-#define MC_STREAMID_OVERRIDE_CFG_MIU3R 0x580U
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW 0x268U
-#define MC_STREAMID_OVERRIDE_CFG_SATAR 0xf8U
-#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR 0x490U
-#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB 0x668U
-#define MC_STREAMID_OVERRIDE_CFG_VIW 0x390U
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR 0x158U
-#define MC_STREAMID_OVERRIDE_CFG_PCIE5W 0x718U
-
-/*******************************************************************************
- * Macro to calculate Security cfg register addr from StreamID Override register
- ******************************************************************************/
-#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) ((addr) + (uint32_t)sizeof(uint32_t))
-
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV (0U << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV (1U << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV (2U << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV (3U << 4)
-
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL (0U << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL (1U << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL (2U << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL (3U << 8)
-
-#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO (0U << 12)
-#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID (1U << 12)
-
-/*******************************************************************************
- * Memory Controller transaction override config registers
- ******************************************************************************/
-#define MC_TXN_OVERRIDE_CONFIG_HDAR 0x10a8U
-#define MC_TXN_OVERRIDE_CONFIG_DLA1WRA 0x1624U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE1W 0x16dcU
-#define MC_TXN_OVERRIDE_CONFIG_PVA0RDC 0x1644U
-#define MC_TXN_OVERRIDE_CONFIG_PTCR 0x1000U
-#define MC_TXN_OVERRIDE_CONFIG_EQOSW 0x1478U
-#define MC_TXN_OVERRIDE_CONFIG_MPCOREW 0x11c8U
-#define MC_TXN_OVERRIDE_CONFIG_DLA1FALWRB 0x162cU
-#define MC_TXN_OVERRIDE_CONFIG_AXISR 0x1460U
-#define MC_TXN_OVERRIDE_CONFIG_PVA0WRB 0x1654U
-#define MC_TXN_OVERRIDE_CONFIG_MIU6R 0x17f4U
-#define MC_TXN_OVERRIDE_CONFIG_MIU5R 0x17e4U
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD1 0x1784U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE0R 0x16c4U
-#define MC_TXN_OVERRIDE_CONFIG_EQOSR 0x1470U
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD 0x10e0U
-#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD1 0x178cU
-#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB1 0x1774U
-#define MC_TXN_OVERRIDE_CONFIG_NVENC1SWR 0x16bcU
-#define MC_TXN_OVERRIDE_CONFIG_VICSRD1 0x1510U
-#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR 0x14a8U
-#define MC_TXN_OVERRIDE_CONFIG_VIW 0x1390U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE5R 0x1714U
-#define MC_TXN_OVERRIDE_CONFIG_AXISW 0x1468U
-#define MC_TXN_OVERRIDE_CONFIG_MIU6W 0x17fcU
-#define MC_TXN_OVERRIDE_CONFIG_UFSHCR 0x1480U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE0R1 0x179cU
-#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB1 0x1764U
-#define MC_TXN_OVERRIDE_CONFIG_TSECSWR 0x12a8U
-#define MC_TXN_OVERRIDE_CONFIG_MIU7R 0x1008U
-#define MC_TXN_OVERRIDE_CONFIG_SATAR 0x10f8U
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW 0x1258U
-#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA 0x15f4U
-#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB 0x1438U
-#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SWR 0x17dcU
-#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA1 0x176cU
-#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB 0x166cU
-#define MC_TXN_OVERRIDE_CONFIG_AONDMAW 0x14d0U
-#define MC_TXN_OVERRIDE_CONFIG_AONW 0x14c0U
-#define MC_TXN_OVERRIDE_CONFIG_ETRR 0x1420U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE2AW 0x16ecU
-#define MC_TXN_OVERRIDE_CONFIG_PCIE1R 0x16d4U
-#define MC_TXN_OVERRIDE_CONFIG_PVA1RDC 0x1674U
-#define MC_TXN_OVERRIDE_CONFIG_PVA0WRA 0x164cU
-#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB 0x1430U
-#define MC_TXN_OVERRIDE_CONFIG_MIU1W 0x1548U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE0W 0x16ccU
-#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD 0x17ccU
-#define MC_TXN_OVERRIDE_CONFIG_MIU7W 0x1010U
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1 0x1518U
-#define MC_TXN_OVERRIDE_CONFIG_MIU3R 0x1580U
-#define MC_TXN_OVERRIDE_CONFIG_MIU3W 0x158cU
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR 0x1250U
-#define MC_TXN_OVERRIDE_CONFIG_SESRD 0x1400U
-#define MC_TXN_OVERRIDE_CONFIG_SCER 0x14d8U
-#define MC_TXN_OVERRIDE_CONFIG_MPCORER 0x1138U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA 0x1320U
-#define MC_TXN_OVERRIDE_CONFIG_HDAW 0x11a8U
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR 0x13c8U
-#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA 0x1634U
-#define MC_TXN_OVERRIDE_CONFIG_AONDMAR 0x14c8U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB 0x1338U
-#define MC_TXN_OVERRIDE_CONFIG_ISPFALR 0x1228U
-#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA1 0x175cU
-#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD 0x16b4U
-#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1 0x1508U
-#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA 0x1664U
-#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA1 0x174cU
-#define MC_TXN_OVERRIDE_CONFIG_ISPWB 0x1238U
-#define MC_TXN_OVERRIDE_CONFIG_APEW 0x13d8U
-#define MC_TXN_OVERRIDE_CONFIG_AXIAPR 0x1410U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE2AR 0x16e4U
-#define MC_TXN_OVERRIDE_CONFIG_ISPFALW 0x1724U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCR 0x1310U
-#define MC_TXN_OVERRIDE_CONFIG_MIU2W 0x1578U
-#define MC_TXN_OVERRIDE_CONFIG_RCER 0x1694U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE4W 0x170cU
-#define MC_TXN_OVERRIDE_CONFIG_BPMPW 0x14a0U
-#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR 0x1490U
-#define MC_TXN_OVERRIDE_CONFIG_ISPRA 0x1220U
-#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR 0x13f8U
-#define MC_TXN_OVERRIDE_CONFIG_VICSRD 0x1360U
-#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD1 0x17d4U
-#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA 0x1614U
-#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW 0x14f0U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCW 0x1330U
-#define MC_TXN_OVERRIDE_CONFIG_DLA1FALRDB 0x161cU
-#define MC_TXN_OVERRIDE_CONFIG_APEDMAR 0x14f8U
-#define MC_TXN_OVERRIDE_CONFIG_RCEW 0x169cU
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB 0x1318U
-#define MC_TXN_OVERRIDE_CONFIG_DLA0WRA 0x1604U
-#define MC_TXN_OVERRIDE_CONFIG_VIFALR 0x15e4U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE3R 0x16f4U
-#define MC_TXN_OVERRIDE_CONFIG_MIU1R 0x1540U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE5W 0x171cU
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR 0x1260U
-#define MC_TXN_OVERRIDE_CONFIG_MIU0W 0x1538U
-#define MC_TXN_OVERRIDE_CONFIG_DLA0FALWRB 0x160cU
-#define MC_TXN_OVERRIDE_CONFIG_VIFALW 0x15ecU
-#define MC_TXN_OVERRIDE_CONFIG_DLA0FALRDB 0x15fcU
-#define MC_TXN_OVERRIDE_CONFIG_PCIE3W 0x16fcU
-#define MC_TXN_OVERRIDE_CONFIG_MIU0R 0x1530U
-#define MC_TXN_OVERRIDE_CONFIG_PVA0WRC 0x165cU
-#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR 0x14e8U
-#define MC_TXN_OVERRIDE_CONFIG_APEDMAW 0x1500U
-#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR 0x10b0U
-#define MC_TXN_OVERRIDE_CONFIG_SESWR 0x1408U
-#define MC_TXN_OVERRIDE_CONFIG_AXIAPW 0x1418U
-#define MC_TXN_OVERRIDE_CONFIG_MIU4R 0x1594U
-#define MC_TXN_OVERRIDE_CONFIG_MIU4W 0x159cU
-#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD 0x13f0U
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD 0x13c0U
-#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW 0x14b0U
-#define MC_TXN_OVERRIDE_CONFIG_APER 0x13d0U
-#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA1 0x1754U
-#define MC_TXN_OVERRIDE_CONFIG_PVA1WRB 0x1684U
-#define MC_TXN_OVERRIDE_CONFIG_ISPWA 0x1230U
-#define MC_TXN_OVERRIDE_CONFIG_PVA1WRC 0x168cU
-#define MC_TXN_OVERRIDE_CONFIG_RCEDMAR 0x16a4U
-#define MC_TXN_OVERRIDE_CONFIG_ISPRA1 0x1794U
-#define MC_TXN_OVERRIDE_CONFIG_AONR 0x14b8U
-#define MC_TXN_OVERRIDE_CONFIG_RCEDMAW 0x16acU
-#define MC_TXN_OVERRIDE_CONFIG_UFSHCW 0x1488U
-#define MC_TXN_OVERRIDE_CONFIG_ETRW 0x1428U
-#define MC_TXN_OVERRIDE_CONFIG_SATAW 0x11e8U
-#define MC_TXN_OVERRIDE_CONFIG_VICSWR 0x1368U
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR 0x1158U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE5R1 0x177cU
-#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB 0x163cU
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA 0x1300U
-#define MC_TXN_OVERRIDE_CONFIG_PVA1WRA 0x167cU
-#define MC_TXN_OVERRIDE_CONFIG_MIU5W 0x17ecU
-#define MC_TXN_OVERRIDE_CONFIG_BPMPR 0x1498U
-#define MC_TXN_OVERRIDE_CONFIG_MIU2R 0x1570U
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW 0x1268U
-#define MC_TXN_OVERRIDE_CONFIG_TSECSRD 0x12a0U
-#define MC_TXN_OVERRIDE_CONFIG_PCIE4R 0x1704U
-#define MC_TXN_OVERRIDE_CONFIG_SCEW 0x14e0U
-
-#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID (1U << 0)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV (2U << 4)
-#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT (1U << 12)
-
-/*******************************************************************************
- * Non-SO_DEV transactions override values for CGID_TAG bitfield for the
- * MC_TXN_OVERRIDE_CONFIG_{module} registers
- ******************************************************************************/
-#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT 0U
-#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID 1U
-#define MC_TXN_OVERRIDE_CGID_TAG_ZERO 2U
-#define MC_TXN_OVERRIDE_CGID_TAG_ADR 3U
-#define MC_TXN_OVERRIDE_CGID_TAG_MASK 3ULL
-
-/*******************************************************************************
- * Memory Controller Reset Control registers
- ******************************************************************************/
-#define MC_CLIENT_HOTRESET_CTRL0 0x200U
-#define MC_CLIENT_HOTRESET_CTRL0_RESET_VAL 0U
-#define MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB (1U << 0)
-#define MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB (1U << 6)
-#define MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB (1U << 7)
-#define MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB (1U << 8)
-#define MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB (1U << 9)
-#define MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB (1U << 11)
-#define MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB (1U << 15)
-#define MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB (1U << 17)
-#define MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB (1U << 18)
-#define MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB (1U << 19)
-#define MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB (1U << 20)
-#define MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB (1U << 22)
-#define MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB (1U << 29)
-#define MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB (1U << 30)
-#define MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB (1U << 31)
-#define MC_CLIENT_HOTRESET_STATUS0 0x204U
-#define MC_CLIENT_HOTRESET_CTRL1 0x970U
-#define MC_CLIENT_HOTRESET_CTRL1_RESET_VAL 0U
-#define MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB (1U << 0)
-#define MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB (1U << 2)
-#define MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB (1U << 5)
-#define MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB (1U << 6)
-#define MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB (1U << 7)
-#define MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB (1U << 8)
-#define MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB (1U << 12)
-#define MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB (1U << 13)
-#define MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB (1U << 17)
-#define MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB (1U << 18)
-#define MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB (1U << 19)
-#define MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB (1U << 20)
-#define MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB (1U << 21)
-#define MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB (1U << 22)
-#define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1U << 23)
-#define MC_CLIENT_HOTRESET_CTRL1_VIFAL_FLUSH_ENB (1U << 26)
-#define MC_CLIENT_HOTRESET_CTRL1_RCE_FLUSH_ENB (1U << 31)
-#define MC_CLIENT_HOTRESET_STATUS1 0x974U
-#define MC_CLIENT_HOTRESET_CTRL2 0x97cU
-#define MC_CLIENT_HOTRESET_CTRL2_RESET_VAL 0U
-#define MC_CLIENT_HOTRESET_CTRL2_RCEDMA_FLUSH_ENB (1U << 0)
-#define MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB (1U << 2)
-#define MC_CLIENT_HOTRESET_CTRL2_PCIE5A_FLUSH_ENB (1U << 4)
-#define MC_CLIENT_HOTRESET_CTRL2_AONDMA_FLUSH_ENB (1U << 9)
-#define MC_CLIENT_HOTRESET_CTRL2_BPMPDMA_FLUSH_ENB (1U << 10)
-#define MC_CLIENT_HOTRESET_CTRL2_SCEDMA_FLUSH_ENB (1U << 11)
-#define MC_CLIENT_HOTRESET_CTRL2_APEDMA_FLUSH_ENB (1U << 14)
-#define MC_CLIENT_HOTRESET_CTRL2_PCIE3A_FLUSH_ENB (1U << 16)
-#define MC_CLIENT_HOTRESET_CTRL2_PCIE3_FLUSH_ENB (1U << 17)
-#define MC_CLIENT_HOTRESET_CTRL2_PCIE0A_FLUSH_ENB (1U << 22)
-#define MC_CLIENT_HOTRESET_CTRL2_PCIE0A2_FLUSH_ENB (1U << 23)
-#define MC_CLIENT_HOTRESET_CTRL2_PCIE4A_FLUSH_ENB (1U << 25)
-#define MC_CLIENT_HOTRESET_STATUS2 0x1898U
-
-#define MC_COALESCE_CTRL 0x2930U
-#define MC_COALESCE_CTRL_COALESCER_ENABLE (1U << 31)
-#define MC_COALESCE_CONFIG_6_0 0x294cU
-#define MC_COALESCE_CONFIG_6_0_PVA0RDC_COALESCER_ENABLED (1U << 8)
-#define MC_COALESCE_CONFIG_6_0_PVA1RDC_COALESCER_ENABLED (1U << 14)
-
-/*******************************************************************************
- * Tegra TSA Controller constants
- ******************************************************************************/
-#define TEGRA_TSA_BASE U(0x02000000)
-
-#define TSA_CONFIG_STATIC0_CSR_RESET_R 0x20000000U
-#define TSA_CONFIG_STATIC0_CSW_RESET_W 0x20001000U
-#define TSA_CONFIG_STATIC0_CSW_RESET_SO_DEV 0x20001000U
-
-#define TSA_CONFIG_STATIC0_CSW_PCIE1W 0x1004U
-#define TSA_CONFIG_STATIC0_CSW_PCIE2AW 0x1008U
-#define TSA_CONFIG_STATIC0_CSW_PCIE3W 0x100cU
-#define TSA_CONFIG_STATIC0_CSW_PCIE4W 0x1028U
-#define TSA_CONFIG_STATIC0_CSW_XUSB_DEVW 0x2004U
-#define TSA_CONFIG_STATIC0_CSR_SATAR 0x2010U
-#define TSA_CONFIG_STATIC0_CSW_SATAW 0x2014U
-#define TSA_CONFIG_STATIC0_CSW_PCIE0W 0x2020U
-#define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW 0x202cU
-#define TSA_CONFIG_STATIC0_CSW_NVENC1SWR 0x3004U
-#define TSA_CONFIG_STATIC0_CSW_NVENCSWR 0x3010U
-#define TSA_CONFIG_STATIC0_CSW_NVDEC1SWR 0x4004U
-#define TSA_CONFIG_STATIC0_CSR_ISPFALR 0x4010U
-#define TSA_CONFIG_STATIC0_CSW_ISPWA 0x4014U
-#define TSA_CONFIG_STATIC0_CSW_ISPWB 0x4018U
-#define TSA_CONFIG_STATIC0_CSW_ISPFALW 0x401cU
-#define TSA_CONFIG_STATIC0_CSW_NVDECSWR 0x5004U
-#define TSA_CONFIG_STATIC0_CSR_EQOSR 0x5010U
-#define TSA_CONFIG_STATIC0_CSW_EQOSW 0x5014U
-#define TSA_CONFIG_STATIC0_CSR_SDMMCRAB 0x5020U
-#define TSA_CONFIG_STATIC0_CSW_SDMMCWAB 0x5024U
-#define TSA_CONFIG_STATIC0_CSW_UFSHCW 0x6004U
-#define TSA_CONFIG_STATIC0_CSR_SDMMCR 0x6010U
-#define TSA_CONFIG_STATIC0_CSR_SDMMCRA 0x6014U
-#define TSA_CONFIG_STATIC0_CSW_SDMMCW 0x6018U
-#define TSA_CONFIG_STATIC0_CSW_SDMMCWA 0x601cU
-#define TSA_CONFIG_STATIC0_CSR_RCER 0x6030U
-#define TSA_CONFIG_STATIC0_CSR_RCEDMAR 0x6034U
-#define TSA_CONFIG_STATIC0_CSW_RCEW 0x6038U
-#define TSA_CONFIG_STATIC0_CSW_RCEDMAW 0x603cU
-#define TSA_CONFIG_STATIC0_CSR_SCER 0x6050U
-#define TSA_CONFIG_STATIC0_CSR_SCEDMAR 0x6054U
-#define TSA_CONFIG_STATIC0_CSW_SCEW 0x6058U
-#define TSA_CONFIG_STATIC0_CSW_SCEDMAW 0x605cU
-#define TSA_CONFIG_STATIC0_CSR_AXIAPR 0x7004U
-#define TSA_CONFIG_STATIC0_CSR_ETRR 0x7008U
-#define TSA_CONFIG_STATIC0_CSR_HOST1XDMAR 0x700cU
-#define TSA_CONFIG_STATIC0_CSW_AXIAPW 0x7010U
-#define TSA_CONFIG_STATIC0_CSW_ETRW 0x7014U
-#define TSA_CONFIG_STATIC0_CSR_NVJPGSRD 0x8004U
-#define TSA_CONFIG_STATIC0_CSW_NVJPGSWR 0x8008U
-#define TSA_CONFIG_STATIC0_CSR_AXISR 0x8014U
-#define TSA_CONFIG_STATIC0_CSW_AXISW 0x8018U
-#define TSA_CONFIG_STATIC0_CSR_BPMPR 0x9004U
-#define TSA_CONFIG_STATIC0_CSR_BPMPDMAR 0x9008U
-#define TSA_CONFIG_STATIC0_CSW_BPMPW 0x900cU
-#define TSA_CONFIG_STATIC0_CSW_BPMPDMAW 0x9010U
-#define TSA_CONFIG_STATIC0_CSR_SESRD 0x9024U
-#define TSA_CONFIG_STATIC0_CSR_TSECSRD 0x9028U
-#define TSA_CONFIG_STATIC0_CSR_TSECSRDB 0x902cU
-#define TSA_CONFIG_STATIC0_CSW_SESWR 0x9030U
-#define TSA_CONFIG_STATIC0_CSW_TSECSWR 0x9034U
-#define TSA_CONFIG_STATIC0_CSW_TSECSWRB 0x9038U
-#define TSA_CONFIG_STATIC0_CSW_PCIE5W 0xb004U
-#define TSA_CONFIG_STATIC0_CSW_VICSWR 0xc004U
-#define TSA_CONFIG_STATIC0_CSR_APER 0xd004U
-#define TSA_CONFIG_STATIC0_CSR_APEDMAR 0xd008U
-#define TSA_CONFIG_STATIC0_CSW_APEW 0xd00cU
-#define TSA_CONFIG_STATIC0_CSW_APEDMAW 0xd010U
-#define TSA_CONFIG_STATIC0_CSR_HDAR 0xf004U
-#define TSA_CONFIG_STATIC0_CSW_HDAW 0xf008U
-#define TSA_CONFIG_STATIC0_CSR_NVDISPLAYR 0xf014U
-#define TSA_CONFIG_STATIC0_CSR_VIFALR 0x10004U
-#define TSA_CONFIG_STATIC0_CSW_VIW 0x10008U
-#define TSA_CONFIG_STATIC0_CSW_VIFALW 0x1000cU
-#define TSA_CONFIG_STATIC0_CSR_AONR 0x12004U
-#define TSA_CONFIG_STATIC0_CSR_AONDMAR 0x12008U
-#define TSA_CONFIG_STATIC0_CSW_AONW 0x1200cU
-#define TSA_CONFIG_STATIC0_CSW_AONDMAW 0x12010U
-#define TSA_CONFIG_STATIC0_CSR_PCIE1R 0x14004U
-#define TSA_CONFIG_STATIC0_CSR_PCIE2AR 0x14008U
-#define TSA_CONFIG_STATIC0_CSR_PCIE3R 0x1400cU
-#define TSA_CONFIG_STATIC0_CSR_PCIE4R 0x14028U
-#define TSA_CONFIG_STATIC0_CSR_XUSB_DEVR 0x15004U
-#define TSA_CONFIG_STATIC0_CSR_XUSB_HOSTR 0x15010U
-#define TSA_CONFIG_STATIC0_CSR_UFSHCR 0x16004U
-#define TSA_CONFIG_STATIC0_CSW_DLA1WRA 0x18004U
-#define TSA_CONFIG_STATIC0_CSR_DLA1FALRDB 0x18010U
-#define TSA_CONFIG_STATIC0_CSW_DLA1FALWRB 0x18014U
-#define TSA_CONFIG_STATIC0_CSW_DLA0WRA 0x19004U
-#define TSA_CONFIG_STATIC0_CSR_DLA0FALRDB 0x19010U
-#define TSA_CONFIG_STATIC0_CSW_DLA0FALWRB 0x19014U
-#define TSA_CONFIG_STATIC0_CSR_PVA1RDC 0x1a004U
-#define TSA_CONFIG_STATIC0_CSW_PVA1WRC 0x1a008U
-#define TSA_CONFIG_STATIC0_CSW_PVA1WRA 0x1a014U
-#define TSA_CONFIG_STATIC0_CSW_PVA1WRB 0x1a020U
-#define TSA_CONFIG_STATIC0_CSW_PVA0WRB 0x1b004U
-#define TSA_CONFIG_STATIC0_CSR_PVA0RDC 0x1b010U
-#define TSA_CONFIG_STATIC0_CSW_PVA0WRC 0x1b014U
-#define TSA_CONFIG_STATIC0_CSW_PVA0WRA 0x1b020U
-#define TSA_CONFIG_STATIC0_CSR_NVENC1SRD 0x1d004U
-#define TSA_CONFIG_STATIC0_CSR_NVENCSRD 0x1d010U
-#define TSA_CONFIG_STATIC0_CSR_NVDEC1SRD 0x1e004U
-#define TSA_CONFIG_STATIC0_CSR_ISPRA 0x1e010U
-#define TSA_CONFIG_STATIC0_CSR_NVDECSRD 0x1f004U
-#define TSA_CONFIG_STATIC0_CSR_PCIE0R 0x21004U
-#define TSA_CONFIG_STATIC0_CSR_PCIE5R 0x23004U
-#define TSA_CONFIG_STATIC0_CSR_VICSRD 0x24004U
-#define TSA_CONFIG_STATIC0_CSR_DLA1RDA 0x26004U
-#define TSA_CONFIG_STATIC0_CSR_DLA0RDA 0x27004U
-#define TSA_CONFIG_STATIC0_CSR_PVA1RDA 0x28004U
-#define TSA_CONFIG_STATIC0_CSR_PVA1RDB 0x28010U
-#define TSA_CONFIG_STATIC0_CSR_PVA0RDB 0x29004U
-#define TSA_CONFIG_STATIC0_CSR_PVA0RDA 0x29010U
-
-#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK (ULL(0x3) << 11)
-#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU (ULL(0) << 11)
-#define TSA_CONFIG_CSW_SO_DEV_HUBID_MASK (ULL(0x3) << 15)
-#define TSA_CONFIG_CSW_SO_DEV_HUB2 (ULL(2) << 15)
-
-#define REORDER_DEPTH_LIMIT 16
-#define TSA_CONFIG_CSW_REORDER_DEPTH_LIMIT_MASK (ULL(0x7FF) << 21)
-#define reorder_depth_limit(limit) (ULL(limit) << 21)
-
-#define tsa_read_32(client) \
- mmio_read_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client)
-
-#define mc_set_tsa_hub2(val, client) \
- { \
- mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
- ((val & ~TSA_CONFIG_CSW_SO_DEV_HUBID_MASK) | \
- TSA_CONFIG_CSW_SO_DEV_HUB2)); \
- }
-
-#define mc_set_tsa_depth_limit(limit, client) \
- { \
- uint32_t val = mmio_read_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client); \
- mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
- ((val & ~TSA_CONFIG_CSW_REORDER_DEPTH_LIMIT_MASK) | \
- reorder_depth_limit(limit))); \
- }
-
-#endif /* TEGRA_MC_DEF_H */
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index bbcfdc5c1..81b25e036 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +11,11 @@
#include <lib/utils_def.h>
/*******************************************************************************
+ * Platform BL31 specific defines.
+ ******************************************************************************/
+#define BL31_SIZE U(0x40000)
+
+/*******************************************************************************
* Power down state IDs
******************************************************************************/
#define PSTATE_ID_CORE_POWERDN U(7)
@@ -43,6 +49,11 @@
#define SC7ENTRY_FW_HEADER_SIZE_BYTES U(0x400)
/*******************************************************************************
+ * Counter-timer physical secure timer PPI
+ ******************************************************************************/
+#define TEGRA210_TIMER1_IRQ 32
+
+/*******************************************************************************
* iRAM memory constants
******************************************************************************/
#define TEGRA_IRAM_BASE U(0x40000000)
@@ -143,6 +154,9 @@
#define SE_CLK_ENB_BIT (U(1) << 31)
#define TEGRA_CLK_OUT_ENB_W U(0x364)
#define ENTROPY_RESET_BIT (U(1) << 21)
+#define TEGRA_CLK_RST_CTL_CLK_SRC_SE U(0x42C)
+#define SE_CLK_SRC_MASK (U(7) << 29)
+#define SE_CLK_SRC_CLK_M (U(6) << 29)
#define TEGRA_RST_DEV_SET_V U(0x430)
#define SE_RESET_BIT (U(1) << 31)
#define HDA_RESET_BIT (U(1) << 29)
@@ -231,6 +245,8 @@
#define MC_VIDEO_PROTECT_BASE_HI U(0x978)
#define MC_VIDEO_PROTECT_BASE_LO U(0x648)
#define MC_VIDEO_PROTECT_SIZE_MB U(0x64c)
+#define MC_VIDEO_PROTECT_REG_CTRL U(0x650)
+#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3)
/* SMMU configuration registers*/
#define MC_SMMU_PPCS_ASID_0 0x270U
@@ -268,4 +284,10 @@
#define TEGRA_TZRAM_CARVEOUT_BASE U(0x7C04C000)
#define TEGRA_TZRAM_CARVEOUT_SIZE U(0x4000)
+/*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define TEGRA_DRAM_BASE ULL(0x80000000)
+#define TEGRA_DRAM_END ULL(0x27FFFFFFF)
+
#endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h
index d83ce48b8..b8297fd93 100644
--- a/plat/nvidia/tegra/include/tegra_platform.h
+++ b/plat/nvidia/tegra/include/tegra_platform.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -29,6 +30,13 @@
#define TEGRA_CHIPID_TEGRA13 U(0x13)
#define TEGRA_CHIPID_TEGRA21 U(0x21)
#define TEGRA_CHIPID_TEGRA18 U(0x18)
+#define TEGRA_CHIPID_TEGRA19 U(0x19)
+
+/*******************************************************************************
+ * JEDEC Standard Manufacturer's Identification Code and Bank ID
+ ******************************************************************************/
+#define JEDEC_NVIDIA_MFID U(0x6B)
+#define JEDEC_NVIDIA_BKID U(3)
#ifndef __ASSEMBLER__
@@ -45,6 +53,7 @@ bool tegra_chipid_is_t132(void);
bool tegra_chipid_is_t186(void);
bool tegra_chipid_is_t210(void);
bool tegra_chipid_is_t210_b01(void);
+bool tegra_chipid_is_t194(void);
/*
* Tegra platform identifiers
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index 761acdea5..cc2ad869c 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +9,7 @@
#define TEGRA_PRIVATE_H
#include <platform_def.h>
+#include <stdbool.h>
#include <arch.h>
#include <arch_helpers.h>
@@ -18,12 +20,6 @@
#include <tegra_gic.h>
/*******************************************************************************
- * Tegra DRAM memory base address
- ******************************************************************************/
-#define TEGRA_DRAM_BASE ULL(0x80000000)
-#define TEGRA_DRAM_END ULL(0x27FFFFFFF)
-
-/*******************************************************************************
* Implementation defined ACTLR_EL1 bit definitions
******************************************************************************/
#define ACTLR_EL1_PMSTATE_MASK (ULL(0xF) << 0)
@@ -51,6 +47,8 @@ typedef struct plat_params_from_bl2 {
uint64_t sc7entry_fw_size;
/* System Suspend Entry Firmware base address */
uint64_t sc7entry_fw_base;
+ /* Enable dual execution */
+ uint8_t enable_ccplex_lock_step;
} plat_params_from_bl2_t;
/*******************************************************************************
@@ -70,6 +68,11 @@ struct tegra_bl31_params {
image_info_t *bl33_image_info;
};
+/*******************************************************************************
+* To suppress Coverity MISRA C-2012 Rule 2.2 violations
+*******************************************************************************/
+#define UNUSED_FUNC_NOP() asm("nop")
+
/* Declarations for plat_psci_handlers.c */
int32_t tegra_soc_validate_power_state(uint32_t power_state,
psci_power_state_t *req_state);
@@ -82,6 +85,9 @@ struct tegra_bl31_params *plat_get_bl31_params(void);
plat_params_from_bl2_t *plat_get_bl31_plat_params(void);
void plat_early_platform_setup(void);
void plat_late_platform_setup(void);
+void plat_relocate_bl32_image(const image_info_t *bl32_img_info);
+bool plat_supports_system_suspend(void);
+void plat_runtime_setup(void);
/* Declarations for plat_secondary.c */
void plat_secondary_setup(void);
@@ -89,7 +95,7 @@ int32_t plat_lock_cpu_vectors(void);
/* Declarations for tegra_fiq_glue.c */
void tegra_fiq_handler_setup(void);
-int tegra_fiq_get_intr_context(void);
+int32_t tegra_fiq_get_intr_context(void);
void tegra_fiq_set_ns_entrypoint(uint64_t entrypoint);
/* Declarations for tegra_security.c */
@@ -106,24 +112,12 @@ int32_t tegra_soc_pwr_domain_on(u_register_t mpidr);
int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state);
int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state);
int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state);
int32_t tegra_soc_prepare_system_reset(void);
__dead2 void tegra_soc_prepare_system_off(void);
plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
const plat_local_state_t *states,
uint32_t ncpu);
-void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state);
-void tegra_cpu_standby(plat_local_state_t cpu_state);
-int32_t tegra_pwr_domain_on(u_register_t mpidr);
-void tegra_pwr_domain_off(const psci_power_state_t *target_state);
-void tegra_pwr_domain_suspend(const psci_power_state_t *target_state);
-void __dead2 tegra_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
-void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state);
-void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state);
-__dead2 void tegra_system_off(void);
-__dead2 void tegra_system_reset(void);
-int32_t tegra_validate_power_state(uint32_t power_state,
- psci_power_state_t *req_state);
-int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint);
/* Declarations for tegraXXX_pm.c */
int tegra_prepare_cpu_suspend(unsigned int id, unsigned int afflvl);
@@ -156,4 +150,9 @@ int plat_sip_handler(uint32_t smc_fid,
void *handle,
uint64_t flags);
+#if RAS_EXTENSION
+void tegra194_ras_enable(void);
+void tegra194_ras_corrected_err_clear(uint64_t *cookie);
+#endif
+
#endif /* TEGRA_PRIVATE_H */
diff --git a/plat/nvidia/tegra/common/lib/debug/profiler.c b/plat/nvidia/tegra/lib/debug/profiler.c
index dd76a4e96..dd76a4e96 100644
--- a/plat/nvidia/tegra/common/lib/debug/profiler.c
+++ b/plat/nvidia/tegra/lib/debug/profiler.c
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index 0917d8701..6ed1cdf0b 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -1,5 +1,6 @@
#
# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -12,13 +13,17 @@ $(eval $(call add_define,CRASH_REPORTING))
# enable assert() for release/debug builds
ENABLE_ASSERTIONS := 1
-PLAT_LOG_LEVEL_ASSERT := 40
+PLAT_LOG_LEVEL_ASSERT := 50
$(eval $(call add_define,PLAT_LOG_LEVEL_ASSERT))
# enable dynamic memory mapping
PLAT_XLAT_TABLES_DYNAMIC := 1
$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
+# Enable exception handling at EL3
+EL3_EXCEPTION_HANDLING := 1
+GICV2_G0_FOR_EL3 := 1
+
# Enable PSCI v1.0 extended state ID format
PSCI_EXTENDED_STATE_ID := 1
@@ -28,32 +33,49 @@ SEPARATE_CODE_AND_RODATA := 1
# do not use coherent memory
USE_COHERENT_MEM := 0
-# do not enable SVE
-ENABLE_SVE_FOR_NS := 0
-
# enable D-cache early during CPU warmboot
WARMBOOT_ENABLE_DCACHE_EARLY := 1
# remove the standard libc
OVERRIDE_LIBC := 1
-include plat/nvidia/tegra/common/tegra_common.mk
-include ${SOC_DIR}/platform_${TARGET_SOC}.mk
+# Flag to enable WDT FIQ interrupt handling for Tegra SoCs
+# prior to Tegra186
+ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING ?= 0
+
+# Flag to allow relocation of BL32 image to TZDRAM during boot
+RELOCATE_BL32_IMAGE ?= 0
+
+# Enable stack protection
+ENABLE_STACK_PROTECTOR := strong
+
+# Enable SDEI
+SDEI_SUPPORT := 1
# modify BUILD_PLAT to point to SoC specific build directory
BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE}
+include plat/nvidia/tegra/common/tegra_common.mk
+include ${SOC_DIR}/platform_${TARGET_SOC}.mk
+
+$(eval $(call add_define,ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING))
+$(eval $(call add_define,RELOCATE_BL32_IMAGE))
+
# platform cflags (enable signed comparisons, disable stdlib)
-TF_CFLAGS += -Wsign-compare -nostdlib
+TF_CFLAGS += -nostdlib
# override with necessary libc files for the Tegra platform
override LIBC_SRCS := $(addprefix lib/libc/, \
+ aarch64/setjmp.S \
assert.c \
+ memchr.c \
+ memcmp.c \
memcpy.c \
memmove.c \
memset.c \
printf.c \
putchar.c \
+ strrchr.c \
strlen.c \
snprintf.c)
diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
index bd3f46fcc..0e2edf096 100644
--- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -35,6 +36,30 @@
static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER];
+plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
+ const plat_local_state_t *states,
+ uint32_t ncpu)
+{
+ plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
+ uint32_t num_cpu = ncpu;
+ const plat_local_state_t *local_state = states;
+
+ (void)lvl;
+
+ assert(ncpu != 0U);
+
+ do {
+ temp = *local_state;
+ if ((temp < target)) {
+ target = temp;
+ }
+ --num_cpu;
+ local_state++;
+ } while (num_cpu != 0U);
+
+ return target;
+}
+
int32_t tegra_soc_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state)
{
@@ -112,6 +137,12 @@ int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
return PSCI_E_SUCCESS;
}
+int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
+{
+ (void)cpu_state;
+ return PSCI_E_SUCCESS;
+}
+
int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
uint64_t val;
@@ -139,6 +170,16 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
return PSCI_E_SUCCESS;
}
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+ return PSCI_E_NOT_SUPPORTED;
+}
+
+int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+{
+ return PSCI_E_SUCCESS;
+}
+
int tegra_soc_prepare_system_reset(void)
{
/*
@@ -152,5 +193,16 @@ int tegra_soc_prepare_system_reset(void)
/* Wait 1 ms to make sure clock source/device logic is stabilized. */
mdelay(1);
+ /*
+ * Program the PMC in order to restart the system.
+ */
+ tegra_pmc_system_reset();
+
return PSCI_E_SUCCESS;
}
+
+__dead2 void tegra_soc_prepare_system_off(void)
+{
+ ERROR("Tegra System Off: operation not handled.\n");
+ panic();
+}
diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c
index df6267897..49e8b5d88 100644
--- a/plat/nvidia/tegra/soc/t132/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t132/plat_setup.c
@@ -1,13 +1,16 @@
/*
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
+#include <assert.h>
#include <common/bl_common.h>
#include <drivers/console.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <memctrl.h>
#include <plat/common/platform.h>
#include <tegra_def.h>
#include <tegra_platform.h>
@@ -91,7 +94,7 @@ static uint32_t tegra132_uart_addresses[TEGRA132_MAX_UART_PORTS + 1] = {
******************************************************************************/
void plat_enable_console(int32_t id)
{
- static console_16550_t uart_console;
+ static console_t uart_console;
uint32_t console_clock;
if ((id > 0) && (id < TEGRA132_MAX_UART_PORTS)) {
@@ -108,7 +111,7 @@ void plat_enable_console(int32_t id)
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&uart_console);
- console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&uart_console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
}
@@ -121,3 +124,78 @@ void plat_gic_setup(void)
tegra_gic_setup(NULL, 0);
tegra_gic_init();
}
+
+/*******************************************************************************
+ * Return pointer to the BL31 params from previous bootloader
+ ******************************************************************************/
+struct tegra_bl31_params *plat_get_bl31_params(void)
+{
+ return NULL;
+}
+
+/*******************************************************************************
+ * Return pointer to the BL31 platform params from previous bootloader
+ ******************************************************************************/
+plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
+{
+ return NULL;
+}
+
+/*******************************************************************************
+ * Handler for early platform setup
+ ******************************************************************************/
+void plat_early_platform_setup(void)
+{
+ plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+
+ /* Verify chip id is t132 */
+ assert(tegra_chipid_is_t132());
+
+ /*
+ * Do initial security configuration to allow DRAM/device access.
+ */
+ tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
+ (uint32_t)plat_params->tzdram_size);
+}
+
+/*******************************************************************************
+ * Handler for late platform setup
+ ******************************************************************************/
+void plat_late_platform_setup(void)
+{
+ ; /* do nothing */
+}
+
+/*******************************************************************************
+ * Handler to indicate support for System Suspend
+ ******************************************************************************/
+bool plat_supports_system_suspend(void)
+{
+ return true;
+}
+
+/*******************************************************************************
+ * Platform specific runtime setup.
+ ******************************************************************************/
+void plat_runtime_setup(void)
+{
+ /*
+ * During cold boot, it is observed that the arbitration
+ * bit is set in the Memory controller leading to false
+ * error interrupts in the non-secure world. To avoid
+ * this, clean the interrupt status register before
+ * booting into the non-secure world
+ */
+ tegra_memctrl_clear_pending_interrupts();
+
+ /*
+ * During boot, USB3 and flash media (SDMMC/SATA) devices need
+ * access to IRAM. Because these clients connect to the MC and
+ * do not have a direct path to the IRAM, the MC implements AHB
+ * redirection during boot to allow path to IRAM. In this mode
+ * accesses to a programmed memory address aperture are directed
+ * to the AHB bus, allowing access to the IRAM. This mode must be
+ * disabled before we jump to the non-secure world.
+ */
+ tegra_memctrl_disable_ahb_redirection();
+}
diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk
index bb7b7ee66..9534c07b9 100644
--- a/plat/nvidia/tegra/soc/t132/platform_t132.mk
+++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk
@@ -1,5 +1,6 @@
#
# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -19,10 +20,15 @@ $(eval $(call add_define,MAX_XLAT_TABLES))
MAX_MMAP_REGIONS := 8
$(eval $(call add_define,MAX_MMAP_REGIONS))
-BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
+# platform files
+PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t132
+
+BL31_SOURCES += ${TEGRA_GICv2_SOURCES} \
+ drivers/ti/uart/aarch64/16550_console.S \
lib/cpus/aarch64/denver.S \
- ${COMMON_DIR}/drivers/flowctrl/flowctrl.c \
- ${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \
+ ${TEGRA_DRIVERS}/flowctrl/flowctrl.c \
+ ${TEGRA_DRIVERS}/memctrl/memctrl_v1.c \
+ ${TEGRA_DRIVERS}/pmc/pmc.c \
${SOC_DIR}/plat_psci_handlers.c \
${SOC_DIR}/plat_sip_calls.c \
${SOC_DIR}/plat_setup.c \
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
index 9e42b2bcb..54d3b2ccd 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -386,14 +387,6 @@ int32_t mce_update_gsc_tzdram(void)
}
/*******************************************************************************
- * Handler to update carveout values for TZ SysRAM aperture
- ******************************************************************************/
-int32_t mce_update_gsc_tzram(void)
-{
- return mce_update_ccplex_gsc(TEGRA_ARI_GSC_TZRAM);
-}
-
-/*******************************************************************************
* Handler to shutdown/reset the entire system
******************************************************************************/
__dead2 void mce_enter_ccplex_state(uint32_t state_idx)
diff --git a/plat/nvidia/tegra/soc/t186/drivers/se/se.c b/plat/nvidia/tegra/soc/t186/drivers/se/se.c
new file mode 100644
index 000000000..25f8cd028
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/drivers/se/se.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <drivers/delay_timer.h>
+#include <errno.h>
+#include <string.h>
+
+#include <bpmp_ipc.h>
+#include <pmc.h>
+#include <security_engine.h>
+#include <tegra_private.h>
+
+#include "se_private.h"
+
+/*******************************************************************************
+ * Constants and Macros
+ ******************************************************************************/
+#define SE0_MAX_BUSY_TIMEOUT_MS U(100) /* 100ms */
+#define BYTES_IN_WORD U(4)
+#define SHA256_MAX_HASH_RESULT U(7)
+#define SHA256_DST_SIZE U(32)
+#define SHA_FIRST_OP U(1)
+#define MAX_SHA_ENGINE_CHUNK_SIZE U(0xFFFFFF)
+#define SHA256_MSG_LENGTH_ONETIME U(0xffff)
+
+/*
+ * Check that SE operation has completed after kickoff
+ * This function is invoked after an SE operation has been started,
+ * and it checks the following conditions:
+ * 1. SE0_INT_STATUS = SE0_OP_DONE
+ * 2. SE0_STATUS = IDLE
+ * 3. SE0_ERR_STATUS is clean.
+ */
+static int32_t tegra_se_operation_complete(void)
+{
+ uint32_t val = 0U;
+
+ /* Read SE0 interrupt register to ensure H/W operation complete */
+ val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET);
+ if (SE0_INT_OP_DONE(val) == SE0_INT_OP_DONE_CLEAR) {
+ ERROR("%s: Engine busy state too many times! val = 0x%x\n",
+ __func__, val);
+ return -ETIMEDOUT;
+ }
+
+ /* Read SE0 status idle to ensure H/W operation complete */
+ val = tegra_se_read_32(SE0_SHA_STATUS_0);
+ if (val != SE0_SHA_STATUS_IDLE) {
+ ERROR("%s: Idle state timeout! val = 0x%x\n", __func__,
+ val);
+ return -ETIMEDOUT;
+ }
+
+ /* Ensure that no errors are thrown during operation */
+ val = tegra_se_read_32(SE0_ERR_STATUS_REG_OFFSET);
+ if (val != SE0_ERR_STATUS_CLEAR) {
+ ERROR("%s: Error during SE operation! val = 0x%x",
+ __func__, val);
+ return -ENOTSUP;
+ }
+
+ return 0;
+}
+
+/*
+ * Security engine primitive normal operations
+ */
+static int32_t tegra_se_start_normal_operation(uint64_t src_addr,
+ uint32_t nbytes, uint32_t last_buf, uint32_t src_len_inbytes)
+{
+ int32_t ret = 0;
+ uint32_t val = 0U;
+ uint32_t src_in_lo;
+ uint32_t src_in_msb;
+ uint32_t src_in_hi;
+
+ if ((src_addr == 0UL) || (nbytes == 0U))
+ return -EINVAL;
+
+ src_in_lo = (uint32_t)src_addr;
+ src_in_msb = ((uint32_t)(src_addr >> 32U) & 0xffU);
+ src_in_hi = ((src_in_msb << SE0_IN_HI_ADDR_HI_0_MSB_SHIFT) |
+ (nbytes & 0xffffffU));
+
+ /* set SRC_IN_ADDR_LO and SRC_IN_ADDR_HI*/
+ tegra_se_write_32(SE0_IN_ADDR, src_in_lo);
+ tegra_se_write_32(SE0_IN_HI_ADDR_HI, src_in_hi);
+
+ val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET);
+ if (val > 0U) {
+ tegra_se_write_32(SE0_INT_STATUS_REG_OFFSET, 0x00000U);
+ }
+
+ /* Enable SHA interrupt for SE0 Operation */
+ tegra_se_write_32(SE0_SHA_INT_ENABLE, 0x1aU);
+
+ /* flush to DRAM for SE to use the updated contents */
+ flush_dcache_range(src_addr, src_len_inbytes);
+
+ /* Start SHA256 operation */
+ if (last_buf == 1U) {
+ tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START |
+ SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD);
+ } else {
+ tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START);
+ }
+
+ /* Wait for SE-operation to finish */
+ udelay(SE0_MAX_BUSY_TIMEOUT_MS * 100U);
+
+ /* Check SE0 operation status */
+ ret = tegra_se_operation_complete();
+ if (ret != 0) {
+ ERROR("SE operation complete Failed! 0x%x", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int32_t tegra_se_calculate_sha256_hash(uint64_t src_addr,
+ uint32_t src_len_inbyte)
+{
+ uint32_t val, last_buf, i;
+ int32_t ret = 0;
+ uint32_t operations;
+ uint64_t src_len_inbits;
+ uint32_t len_bits_msb;
+ uint32_t len_bits_lsb;
+ uint32_t number_of_operations, max_bytes, bytes_left, remaining_bytes;
+
+ if (src_len_inbyte > MAX_SHA_ENGINE_CHUNK_SIZE) {
+ ERROR("SHA input chunk size too big: 0x%x\n", src_len_inbyte);
+ return -EINVAL;
+ }
+
+ if (src_addr == 0UL) {
+ return -EINVAL;
+ }
+
+ /* number of bytes per operation */
+ max_bytes = SHA256_HASH_SIZE_BYTES * SHA256_MSG_LENGTH_ONETIME;
+
+ src_len_inbits = src_len_inbyte * 8U;
+ len_bits_msb = (uint32_t)(src_len_inbits >> 32U);
+ len_bits_lsb = (uint32_t)(src_len_inbits & 0xFFFFFFFF);
+
+ /* program SE0_CONFIG for SHA256 operation */
+ val = SE0_CONFIG_ENC_ALG_SHA | SE0_CONFIG_ENC_MODE_SHA256 |
+ SE0_CONFIG_DEC_ALG_NOP | SE0_CONFIG_DST_HASHREG;
+ tegra_se_write_32(SE0_SHA_CONFIG, val);
+
+ /* set SE0_SHA_MSG_LENGTH registers */
+ tegra_se_write_32(SE0_SHA_MSG_LENGTH_0, len_bits_lsb);
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb);
+ tegra_se_write_32(SE0_SHA_MSG_LENGTH_1, len_bits_msb);
+
+ /* zero out unused SE0_SHA_MSG_LENGTH and SE0_SHA_MSG_LEFT */
+ tegra_se_write_32(SE0_SHA_MSG_LENGTH_2, 0U);
+ tegra_se_write_32(SE0_SHA_MSG_LENGTH_3, 0U);
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_1, 0U);
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_2, 0U);
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_3, 0U);
+
+ number_of_operations = src_len_inbyte / max_bytes;
+ remaining_bytes = src_len_inbyte % max_bytes;
+ if (remaining_bytes > 0U) {
+ number_of_operations += 1U;
+ }
+
+ /*
+ * 1. Operations == 1: program SE0_SHA_TASK register to initiate SHA256
+ * hash generation by setting
+ * 1(SE0_SHA_CONFIG_HW_INIT_HASH) to SE0_SHA_TASK
+ * and start SHA256-normal operation.
+ * 2. 1 < Operations < number_of_operations: program SE0_SHA_TASK to
+ * 0(SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE) to load
+ * intermediate SHA256 digest result from
+ * HASH_RESULT register to continue SHA256
+ * generation and start SHA256-normal operation.
+ * 3. Operations == number_of_operations: continue with step 2 and set
+ * max_bytes to bytes_left to process final
+ * hash-result generation and
+ * start SHA256-normal operation.
+ */
+ bytes_left = src_len_inbyte;
+ for (operations = 1U; operations <= number_of_operations;
+ operations++) {
+ if (operations == SHA_FIRST_OP) {
+ val = SE0_SHA_CONFIG_HW_INIT_HASH;
+ } else {
+ /* Load intermediate SHA digest result to
+ * SHA:HASH_RESULT(0..7) to continue the SHA
+ * calculation and tell the SHA engine to use it.
+ */
+ for (i = 0U; (i / BYTES_IN_WORD) <=
+ SHA256_MAX_HASH_RESULT; i += BYTES_IN_WORD) {
+ val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 +
+ i);
+ tegra_se_write_32(SE0_SHA_HASH_RESULT_0 + i,
+ val);
+ }
+ val = SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE;
+ if (len_bits_lsb <= (max_bytes * 8U)) {
+ len_bits_lsb = (remaining_bytes * 8U);
+ } else {
+ len_bits_lsb -= (max_bytes * 8U);
+ }
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb);
+ }
+ tegra_se_write_32(SE0_SHA_TASK_CONFIG, val);
+
+ max_bytes = (SHA256_HASH_SIZE_BYTES *
+ SHA256_MSG_LENGTH_ONETIME);
+ if (bytes_left < max_bytes) {
+ max_bytes = bytes_left;
+ last_buf = 1U;
+ } else {
+ bytes_left = bytes_left - max_bytes;
+ last_buf = 0U;
+ }
+ /* start operation */
+ ret = tegra_se_start_normal_operation(src_addr, max_bytes,
+ last_buf, src_len_inbyte);
+ if (ret != 0) {
+ ERROR("Error during SE operation! 0x%x", ret);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Handler to generate SHA256 and save SHA256 hash to PMC-Scratch register.
+ */
+int32_t tegra_se_save_sha256_hash(uint64_t bl31_base, uint32_t src_len_inbyte)
+{
+ int32_t ret = 0;
+ uint32_t val = 0U, hash_offset = 0U, scratch_offset = 0U, security;
+
+ /*
+ * Set SE_SOFT_SETTINGS=SE_SECURE to prevent NS process to change SE
+ * registers.
+ */
+ security = tegra_se_read_32(SE0_SECURITY);
+ tegra_se_write_32(SE0_SECURITY, security | SE0_SECURITY_SE_SOFT_SETTING);
+
+ ret = tegra_se_calculate_sha256_hash(bl31_base, src_len_inbyte);
+ if (ret != 0L) {
+ ERROR("%s: SHA256 generation failed\n", __func__);
+ return ret;
+ }
+
+ /*
+ * Reset SE_SECURE to previous value.
+ */
+ tegra_se_write_32(SE0_SECURITY, security);
+
+ /* read SHA256_HASH_RESULT and save to PMC Scratch registers */
+ scratch_offset = SECURE_SCRATCH_TZDRAM_SHA256_HASH_START;
+ while (scratch_offset <= SECURE_SCRATCH_TZDRAM_SHA256_HASH_END) {
+
+ val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 + hash_offset);
+ mmio_write_32(TEGRA_SCRATCH_BASE + scratch_offset, val);
+
+ hash_offset += BYTES_IN_WORD;
+ scratch_offset += BYTES_IN_WORD;
+ }
+
+ return ret;
+}
+
diff --git a/plat/nvidia/tegra/soc/t186/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t186/drivers/se/se_private.h
new file mode 100644
index 000000000..7aa0dd691
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/drivers/se/se_private.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SE_PRIVATE_H
+#define SE_PRIVATE_H
+
+#include <lib/utils_def.h>
+
+/* SE0 security register */
+#define SE0_SECURITY U(0x18)
+#define SE0_SECURITY_SE_SOFT_SETTING (((uint32_t)1) << 16U)
+
+/* SE0 config register */
+#define SE0_SHA_CONFIG U(0x104)
+#define SE0_SHA_TASK_CONFIG U(0x108)
+#define SE0_SHA_CONFIG_HW_INIT_HASH ((1U) << 0U)
+#define SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE U(0)
+
+#define SE0_CONFIG_ENC_ALG_SHIFT U(12)
+#define SE0_CONFIG_ENC_ALG_SHA \
+ (((uint32_t)3) << SE0_CONFIG_ENC_ALG_SHIFT)
+#define SE0_CONFIG_DEC_ALG_SHIFT U(8)
+#define SE0_CONFIG_DEC_ALG_NOP \
+ (((uint32_t)0) << SE0_CONFIG_DEC_ALG_SHIFT)
+#define SE0_CONFIG_DST_SHIFT U(2)
+#define SE0_CONFIG_DST_HASHREG \
+ (((uint32_t)1) << SE0_CONFIG_DST_SHIFT)
+#define SHA256_HASH_SIZE_BYTES U(256)
+
+#define SE0_CONFIG_ENC_MODE_SHIFT U(24)
+#define SE0_CONFIG_ENC_MODE_SHA256 \
+ (((uint32_t)5) << SE0_CONFIG_ENC_MODE_SHIFT)
+
+/* SHA input message length */
+#define SE0_SHA_MSG_LENGTH_0 U(0x11c)
+#define SE0_SHA_MSG_LENGTH_1 U(0x120)
+#define SE0_SHA_MSG_LENGTH_2 U(0x124)
+#define SE0_SHA_MSG_LENGTH_3 U(0x128)
+
+/* SHA input message left */
+#define SE0_SHA_MSG_LEFT_0 U(0x12c)
+#define SE0_SHA_MSG_LEFT_1 U(0x130)
+#define SE0_SHA_MSG_LEFT_2 U(0x134)
+#define SE0_SHA_MSG_LEFT_3 U(0x138)
+
+/* SE Hash Result */
+#define SE0_SHA_HASH_RESULT_0 U(0x13c)
+
+/* SE OPERATION */
+#define SE0_OPERATION_REG_OFFSET U(0x17c)
+#define SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT U(16)
+#define SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD \
+ (((uint32_t)0x1) << SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT)
+#define SE0_OPERATION_SHIFT U(0)
+#define SE0_OP_START \
+ (((uint32_t)0x1) << SE0_OPERATION_SHIFT)
+
+/* SE Interrupt */
+#define SE0_SHA_INT_ENABLE U(0x180)
+
+#define SE0_INT_STATUS_REG_OFFSET U(0x184)
+#define SE0_INT_OP_DONE_SHIFT U(4)
+#define SE0_INT_OP_DONE_CLEAR \
+ (((uint32_t)0) << SE0_INT_OP_DONE_SHIFT)
+#define SE0_INT_OP_DONE(x) \
+ ((x) & (((uint32_t)0x1) << SE0_INT_OP_DONE_SHIFT))
+
+/* SE SHA status */
+#define SE0_SHA_STATUS_0 U(0x188)
+#define SE0_SHA_STATUS_IDLE U(0)
+
+/* SE error status */
+#define SE0_ERR_STATUS_REG_OFFSET U(0x18c)
+#define SE0_ERR_STATUS_CLEAR U(0)
+#define SE0_IN_ADDR U(0x10c)
+#define SE0_IN_HI_ADDR_HI U(0x110)
+#define SE0_IN_HI_ADDR_HI_0_MSB_SHIFT U(24)
+
+/* SE error status */
+#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_START SECURE_SCRATCH_RSV63_LO
+#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_END SECURE_SCRATCH_RSV66_HI
+
+/*******************************************************************************
+ * Inline functions definition
+ ******************************************************************************/
+
+static inline uint32_t tegra_se_read_32(uint32_t offset)
+{
+ return mmio_read_32((uint32_t)(TEGRA_SE0_BASE + offset));
+}
+
+static inline void tegra_se_write_32(uint32_t offset, uint32_t val)
+{
+ mmio_write_32(((uint32_t)(TEGRA_SE0_BASE + offset)), val);
+}
+
+#endif /* SE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
index df943969e..81de674bc 100644
--- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,36 +10,17 @@
#include <mce.h>
#include <memctrl_v2.h>
+#include <tegra186_private.h>
#include <tegra_mc_def.h>
#include <tegra_platform.h>
+#include <tegra_private.h>
+
+extern uint64_t tegra_bl31_phys_base;
/*******************************************************************************
* Array to hold stream_id override config register offsets
******************************************************************************/
const static uint32_t tegra186_streamid_override_regs[] = {
- MC_STREAMID_OVERRIDE_CFG_PTCR,
- MC_STREAMID_OVERRIDE_CFG_AFIR,
- MC_STREAMID_OVERRIDE_CFG_HDAR,
- MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR,
- MC_STREAMID_OVERRIDE_CFG_NVENCSRD,
- MC_STREAMID_OVERRIDE_CFG_SATAR,
- MC_STREAMID_OVERRIDE_CFG_MPCORER,
- MC_STREAMID_OVERRIDE_CFG_NVENCSWR,
- MC_STREAMID_OVERRIDE_CFG_AFIW,
- MC_STREAMID_OVERRIDE_CFG_HDAW,
- MC_STREAMID_OVERRIDE_CFG_MPCOREW,
- MC_STREAMID_OVERRIDE_CFG_SATAW,
- MC_STREAMID_OVERRIDE_CFG_ISPRA,
- MC_STREAMID_OVERRIDE_CFG_ISPWA,
- MC_STREAMID_OVERRIDE_CFG_ISPWB,
- MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR,
- MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW,
- MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR,
- MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW,
- MC_STREAMID_OVERRIDE_CFG_TSECSRD,
- MC_STREAMID_OVERRIDE_CFG_TSECSWR,
- MC_STREAMID_OVERRIDE_CFG_GPUSRD,
- MC_STREAMID_OVERRIDE_CFG_GPUSWR,
MC_STREAMID_OVERRIDE_CFG_SDMMCRA,
MC_STREAMID_OVERRIDE_CFG_SDMMCRAA,
MC_STREAMID_OVERRIDE_CFG_SDMMCR,
@@ -47,47 +29,6 @@ const static uint32_t tegra186_streamid_override_regs[] = {
MC_STREAMID_OVERRIDE_CFG_SDMMCWAA,
MC_STREAMID_OVERRIDE_CFG_SDMMCW,
MC_STREAMID_OVERRIDE_CFG_SDMMCWAB,
- MC_STREAMID_OVERRIDE_CFG_VICSRD,
- MC_STREAMID_OVERRIDE_CFG_VICSWR,
- MC_STREAMID_OVERRIDE_CFG_VIW,
- MC_STREAMID_OVERRIDE_CFG_NVDECSRD,
- MC_STREAMID_OVERRIDE_CFG_NVDECSWR,
- MC_STREAMID_OVERRIDE_CFG_APER,
- MC_STREAMID_OVERRIDE_CFG_APEW,
- MC_STREAMID_OVERRIDE_CFG_NVJPGSRD,
- MC_STREAMID_OVERRIDE_CFG_NVJPGSWR,
- MC_STREAMID_OVERRIDE_CFG_SESRD,
- MC_STREAMID_OVERRIDE_CFG_SESWR,
- MC_STREAMID_OVERRIDE_CFG_ETRR,
- MC_STREAMID_OVERRIDE_CFG_ETRW,
- MC_STREAMID_OVERRIDE_CFG_TSECSRDB,
- MC_STREAMID_OVERRIDE_CFG_TSECSWRB,
- MC_STREAMID_OVERRIDE_CFG_GPUSRD2,
- MC_STREAMID_OVERRIDE_CFG_GPUSWR2,
- MC_STREAMID_OVERRIDE_CFG_AXISR,
- MC_STREAMID_OVERRIDE_CFG_AXISW,
- MC_STREAMID_OVERRIDE_CFG_EQOSR,
- MC_STREAMID_OVERRIDE_CFG_EQOSW,
- MC_STREAMID_OVERRIDE_CFG_UFSHCR,
- MC_STREAMID_OVERRIDE_CFG_UFSHCW,
- MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR,
- MC_STREAMID_OVERRIDE_CFG_BPMPR,
- MC_STREAMID_OVERRIDE_CFG_BPMPW,
- MC_STREAMID_OVERRIDE_CFG_BPMPDMAR,
- MC_STREAMID_OVERRIDE_CFG_BPMPDMAW,
- MC_STREAMID_OVERRIDE_CFG_AONR,
- MC_STREAMID_OVERRIDE_CFG_AONW,
- MC_STREAMID_OVERRIDE_CFG_AONDMAR,
- MC_STREAMID_OVERRIDE_CFG_AONDMAW,
- MC_STREAMID_OVERRIDE_CFG_SCER,
- MC_STREAMID_OVERRIDE_CFG_SCEW,
- MC_STREAMID_OVERRIDE_CFG_SCEDMAR,
- MC_STREAMID_OVERRIDE_CFG_SCEDMAW,
- MC_STREAMID_OVERRIDE_CFG_APEDMAR,
- MC_STREAMID_OVERRIDE_CFG_APEDMAW,
- MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1,
- MC_STREAMID_OVERRIDE_CFG_VICSRD1,
- MC_STREAMID_OVERRIDE_CFG_NVDECSRD1
};
/*******************************************************************************
@@ -95,71 +36,71 @@ const static uint32_t tegra186_streamid_override_regs[] = {
******************************************************************************/
const static mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = {
mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(GPUSWR2, SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(GPUSRD, SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(ISPWA, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(VIW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(ISPRA, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE),
+ mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, DISABLE),
mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, DISABLE),
+ mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+ mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(GPUSWR, SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+ mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(ISPWB, NON_SECURE, OVERRIDE, ENABLE),
mc_make_sec_cfg(GPUSRD2, SECURE, NO_OVERRIDE, DISABLE),
mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
@@ -461,16 +402,8 @@ static void tegra186_memctrl_reconfig_mss_clients(void)
static void tegra186_memctrl_set_overrides(void)
{
- const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
- const mc_txn_override_cfg_t *mc_txn_override_cfgs;
- uint32_t num_txn_override_cfgs;
uint32_t i, val;
- /* Get the settings from the platform */
- assert(plat_mc_settings != NULL);
- mc_txn_override_cfgs = plat_mc_settings->txn_override_cfg;
- num_txn_override_cfgs = plat_mc_settings->num_txn_override_cfgs;
-
/*
* Set the MC_TXN_OVERRIDE registers for write clients.
*/
@@ -502,35 +435,226 @@ static void tegra186_memctrl_set_overrides(void)
/*
* Settings for Tegra186 silicon rev. A02 and onwards.
*/
- for (i = 0; i < num_txn_override_cfgs; i++) {
- val = tegra_mc_read_32(mc_txn_override_cfgs[i].offset);
+ for (i = 0; i < ARRAY_SIZE(tegra186_txn_override_cfgs); i++) {
+ val = tegra_mc_read_32(tegra186_txn_override_cfgs[i].offset);
val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
- tegra_mc_write_32(mc_txn_override_cfgs[i].offset,
- val | mc_txn_override_cfgs[i].cgid_tag);
+ tegra_mc_write_32(tegra186_txn_override_cfgs[i].offset,
+ val | tegra186_txn_override_cfgs[i].cgid_tag);
}
}
}
+
/*******************************************************************************
- * Struct to hold the memory controller settings
+ * Array to hold MC context for Tegra186
******************************************************************************/
-static tegra_mc_settings_t tegra186_mc_settings = {
- .streamid_override_cfg = tegra186_streamid_override_regs,
- .num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_streamid_override_regs),
- .streamid_security_cfg = tegra186_streamid_sec_cfgs,
- .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra186_streamid_sec_cfgs),
- .txn_override_cfg = tegra186_txn_override_cfgs,
- .num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_txn_override_cfgs),
- .reconfig_mss_clients = tegra186_memctrl_reconfig_mss_clients,
- .set_txn_overrides = tegra186_memctrl_set_overrides,
+static __attribute__((aligned(16))) mc_regs_t tegra186_mc_context[] = {
+ _START_OF_TABLE_,
+ mc_make_sid_security_cfg(SCEW),
+ mc_make_sid_security_cfg(AFIR),
+ mc_make_sid_security_cfg(NVDISPLAYR1),
+ mc_make_sid_security_cfg(XUSB_DEVR),
+ mc_make_sid_security_cfg(VICSRD1),
+ mc_make_sid_security_cfg(NVENCSWR),
+ mc_make_sid_security_cfg(TSECSRDB),
+ mc_make_sid_security_cfg(AXISW),
+ mc_make_sid_security_cfg(SDMMCWAB),
+ mc_make_sid_security_cfg(AONDMAW),
+ mc_make_sid_security_cfg(GPUSWR2),
+ mc_make_sid_security_cfg(SATAW),
+ mc_make_sid_security_cfg(UFSHCW),
+ mc_make_sid_security_cfg(AFIW),
+ mc_make_sid_security_cfg(SDMMCR),
+ mc_make_sid_security_cfg(SCEDMAW),
+ mc_make_sid_security_cfg(UFSHCR),
+ mc_make_sid_security_cfg(SDMMCWAA),
+ mc_make_sid_security_cfg(APEDMAW),
+ mc_make_sid_security_cfg(SESWR),
+ mc_make_sid_security_cfg(MPCORER),
+ mc_make_sid_security_cfg(PTCR),
+ mc_make_sid_security_cfg(BPMPW),
+ mc_make_sid_security_cfg(ETRW),
+ mc_make_sid_security_cfg(GPUSRD),
+ mc_make_sid_security_cfg(VICSWR),
+ mc_make_sid_security_cfg(SCEDMAR),
+ mc_make_sid_security_cfg(HDAW),
+ mc_make_sid_security_cfg(ISPWA),
+ mc_make_sid_security_cfg(EQOSW),
+ mc_make_sid_security_cfg(XUSB_HOSTW),
+ mc_make_sid_security_cfg(TSECSWR),
+ mc_make_sid_security_cfg(SDMMCRAA),
+ mc_make_sid_security_cfg(APER),
+ mc_make_sid_security_cfg(VIW),
+ mc_make_sid_security_cfg(APEW),
+ mc_make_sid_security_cfg(AXISR),
+ mc_make_sid_security_cfg(SDMMCW),
+ mc_make_sid_security_cfg(BPMPDMAW),
+ mc_make_sid_security_cfg(ISPRA),
+ mc_make_sid_security_cfg(NVDECSWR),
+ mc_make_sid_security_cfg(XUSB_DEVW),
+ mc_make_sid_security_cfg(NVDECSRD),
+ mc_make_sid_security_cfg(MPCOREW),
+ mc_make_sid_security_cfg(NVDISPLAYR),
+ mc_make_sid_security_cfg(BPMPDMAR),
+ mc_make_sid_security_cfg(NVJPGSWR),
+ mc_make_sid_security_cfg(NVDECSRD1),
+ mc_make_sid_security_cfg(TSECSRD),
+ mc_make_sid_security_cfg(NVJPGSRD),
+ mc_make_sid_security_cfg(SDMMCWA),
+ mc_make_sid_security_cfg(SCER),
+ mc_make_sid_security_cfg(XUSB_HOSTR),
+ mc_make_sid_security_cfg(VICSRD),
+ mc_make_sid_security_cfg(AONDMAR),
+ mc_make_sid_security_cfg(AONW),
+ mc_make_sid_security_cfg(SDMMCRA),
+ mc_make_sid_security_cfg(HOST1XDMAR),
+ mc_make_sid_security_cfg(EQOSR),
+ mc_make_sid_security_cfg(SATAR),
+ mc_make_sid_security_cfg(BPMPR),
+ mc_make_sid_security_cfg(HDAR),
+ mc_make_sid_security_cfg(SDMMCRAB),
+ mc_make_sid_security_cfg(ETRR),
+ mc_make_sid_security_cfg(AONR),
+ mc_make_sid_security_cfg(APEDMAR),
+ mc_make_sid_security_cfg(SESRD),
+ mc_make_sid_security_cfg(NVENCSRD),
+ mc_make_sid_security_cfg(GPUSWR),
+ mc_make_sid_security_cfg(TSECSWRB),
+ mc_make_sid_security_cfg(ISPWB),
+ mc_make_sid_security_cfg(GPUSRD2),
+ mc_make_sid_override_cfg(APER),
+ mc_make_sid_override_cfg(VICSRD),
+ mc_make_sid_override_cfg(NVENCSRD),
+ mc_make_sid_override_cfg(NVJPGSWR),
+ mc_make_sid_override_cfg(AONW),
+ mc_make_sid_override_cfg(BPMPR),
+ mc_make_sid_override_cfg(BPMPW),
+ mc_make_sid_override_cfg(HDAW),
+ mc_make_sid_override_cfg(NVDISPLAYR1),
+ mc_make_sid_override_cfg(APEDMAR),
+ mc_make_sid_override_cfg(AFIR),
+ mc_make_sid_override_cfg(AXISR),
+ mc_make_sid_override_cfg(VICSRD1),
+ mc_make_sid_override_cfg(TSECSRD),
+ mc_make_sid_override_cfg(BPMPDMAW),
+ mc_make_sid_override_cfg(MPCOREW),
+ mc_make_sid_override_cfg(XUSB_HOSTR),
+ mc_make_sid_override_cfg(GPUSWR),
+ mc_make_sid_override_cfg(XUSB_DEVR),
+ mc_make_sid_override_cfg(UFSHCW),
+ mc_make_sid_override_cfg(XUSB_HOSTW),
+ mc_make_sid_override_cfg(SDMMCWAB),
+ mc_make_sid_override_cfg(SATAW),
+ mc_make_sid_override_cfg(SCEDMAR),
+ mc_make_sid_override_cfg(HOST1XDMAR),
+ mc_make_sid_override_cfg(SDMMCWA),
+ mc_make_sid_override_cfg(APEDMAW),
+ mc_make_sid_override_cfg(SESWR),
+ mc_make_sid_override_cfg(AXISW),
+ mc_make_sid_override_cfg(AONDMAW),
+ mc_make_sid_override_cfg(TSECSWRB),
+ mc_make_sid_override_cfg(MPCORER),
+ mc_make_sid_override_cfg(ISPWB),
+ mc_make_sid_override_cfg(AONR),
+ mc_make_sid_override_cfg(BPMPDMAR),
+ mc_make_sid_override_cfg(HDAR),
+ mc_make_sid_override_cfg(SDMMCRA),
+ mc_make_sid_override_cfg(ETRW),
+ mc_make_sid_override_cfg(GPUSWR2),
+ mc_make_sid_override_cfg(EQOSR),
+ mc_make_sid_override_cfg(TSECSWR),
+ mc_make_sid_override_cfg(ETRR),
+ mc_make_sid_override_cfg(NVDECSRD),
+ mc_make_sid_override_cfg(TSECSRDB),
+ mc_make_sid_override_cfg(SDMMCRAA),
+ mc_make_sid_override_cfg(NVDECSRD1),
+ mc_make_sid_override_cfg(SDMMCR),
+ mc_make_sid_override_cfg(NVJPGSRD),
+ mc_make_sid_override_cfg(SCEDMAW),
+ mc_make_sid_override_cfg(SDMMCWAA),
+ mc_make_sid_override_cfg(APEW),
+ mc_make_sid_override_cfg(AONDMAR),
+ mc_make_sid_override_cfg(PTCR),
+ mc_make_sid_override_cfg(SCER),
+ mc_make_sid_override_cfg(ISPRA),
+ mc_make_sid_override_cfg(ISPWA),
+ mc_make_sid_override_cfg(VICSWR),
+ mc_make_sid_override_cfg(SESRD),
+ mc_make_sid_override_cfg(SDMMCW),
+ mc_make_sid_override_cfg(SDMMCRAB),
+ mc_make_sid_override_cfg(EQOSW),
+ mc_make_sid_override_cfg(GPUSRD2),
+ mc_make_sid_override_cfg(SCEW),
+ mc_make_sid_override_cfg(GPUSRD),
+ mc_make_sid_override_cfg(NVDECSWR),
+ mc_make_sid_override_cfg(XUSB_DEVW),
+ mc_make_sid_override_cfg(SATAR),
+ mc_make_sid_override_cfg(NVDISPLAYR),
+ mc_make_sid_override_cfg(VIW),
+ mc_make_sid_override_cfg(UFSHCR),
+ mc_make_sid_override_cfg(NVENCSWR),
+ mc_make_sid_override_cfg(AFIW),
+ mc_smmu_bypass_cfg, /* TBU settings */
+ _END_OF_TABLE_,
};
/*******************************************************************************
- * Handler to return the pointer to the memory controller's settings struct
+ * Handler to return the pointer to the MC's context struct
+ ******************************************************************************/
+mc_regs_t *plat_memctrl_get_sys_suspend_ctx(void)
+{
+ /* index of _END_OF_TABLE_ */
+ tegra186_mc_context[0].val = (uint32_t)(ARRAY_SIZE(tegra186_mc_context)) - 1U;
+
+ return tegra186_mc_context;
+}
+
+void plat_memctrl_setup(void)
+{
+ uint32_t val;
+ unsigned int i;
+
+ /* Program all the Stream ID overrides */
+ for (i = 0U; i < ARRAY_SIZE(tegra186_streamid_override_regs); i++) {
+ tegra_mc_streamid_write_32(tegra186_streamid_override_regs[i],
+ MC_STREAM_ID_MAX);
+ }
+
+ /* Program the security config settings for all Stream IDs */
+ for (i = 0U; i < ARRAY_SIZE(tegra186_streamid_sec_cfgs); i++) {
+ val = (tegra186_streamid_sec_cfgs[i].override_enable << 16) |
+ (tegra186_streamid_sec_cfgs[i].override_client_inputs << 8) |
+ (tegra186_streamid_sec_cfgs[i].override_client_ns_flag << 0);
+ tegra_mc_streamid_write_32(tegra186_streamid_sec_cfgs[i].offset, val);
+ }
+
+ /*
+ * Re-configure MSS to allow ROC to deal with ordering of the
+ * Memory Controller traffic. This is needed as the Memory Controller
+ * boots with MSS having all control, but ROC provides a performance
+ * boost as compared to MSS.
+ */
+ tegra186_memctrl_reconfig_mss_clients();
+
+ /* Program overrides for MC transactions */
+ tegra186_memctrl_set_overrides();
+}
+
+/*******************************************************************************
+ * Handler to restore platform specific settings to the memory controller
******************************************************************************/
-tegra_mc_settings_t *tegra_get_mc_settings(void)
+void plat_memctrl_restore(void)
{
- return &tegra186_mc_settings;
+ /*
+ * Re-configure MSS to allow ROC to deal with ordering of the
+ * Memory Controller traffic. This is needed as the Memory Controller
+ * boots with MSS having all control, but ROC provides a performance
+ * boost as compared to MSS.
+ */
+ tegra186_memctrl_reconfig_mss_clients();
+
+ /* Program overrides for MC transactions */
+ tegra186_memctrl_set_overrides();
}
/*******************************************************************************
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index 11394c0ce..af4182e24 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -1,10 +1,12 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
+#include <stdbool.h>
#include <string.h>
#include <arch.h>
@@ -18,9 +20,11 @@
#include <lib/psci/psci.h>
#include <plat/common/platform.h>
+#include <bpmp_ipc.h>
#include <mce.h>
+#include <memctrl_v2.h>
+#include <security_engine.h>
#include <smmu.h>
-#include <stdbool.h>
#include <t18x_ari.h>
#include <tegra186_private.h>
#include <tegra_private.h>
@@ -68,6 +72,11 @@ int32_t tegra_soc_validate_power_state(uint32_t power_state,
case PSTATE_ID_CORE_IDLE:
case PSTATE_ID_CORE_POWERDN:
+ if (psci_get_pstate_type(power_state) != PSTATE_TYPE_POWERDOWN) {
+ ret = PSCI_E_INVALID_PARAMS;
+ break;
+ }
+
/* Core powerdown request */
req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id;
req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
@@ -83,6 +92,12 @@ int32_t tegra_soc_validate_power_state(uint32_t power_state,
return ret;
}
+int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
+{
+ (void)cpu_state;
+ return PSCI_E_SUCCESS;
+}
+
int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
const plat_local_state_t *pwr_domain_state;
@@ -90,7 +105,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
uint32_t cpu = plat_my_core_pos();
const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
mce_cstate_info_t cstate_info = { 0 };
- uint64_t smmu_ctx_base;
+ uint64_t mc_ctx_base;
uint32_t val;
/* get the state ID */
@@ -123,10 +138,9 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG);
mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val);
- /* save SMMU context to TZDRAM */
- smmu_ctx_base = params_from_bl2->tzdram_base +
- tegra186_get_smmu_ctx_offset();
- tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
+ /* save MC context to TZDRAM */
+ mc_ctx_base = params_from_bl2->tzdram_base;
+ tegra_mc_save_context((uintptr_t)mc_ctx_base);
/* Prepare for system suspend */
cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7;
@@ -148,9 +162,6 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
(uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
- /* set system suspend state for house-keeping */
- tegra186_set_system_suspend_entry();
-
} else {
; /* do nothing */
}
@@ -273,22 +284,67 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta
uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
TEGRA186_STATE_ID_MASK;
uint64_t val;
+ uint64_t src_len_in_bytes = (uint64_t)(((uintptr_t)(&__BL31_END__) -
+ (uintptr_t)BL31_BASE));
+ int32_t ret;
if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+ val = params_from_bl2->tzdram_base +
+ tegra186_get_mc_ctx_size();
+
+ /* Initialise communication channel with BPMP */
+ assert(tegra_bpmp_ipc_init() == 0);
+
+ /* Enable SE clock */
+ ret = tegra_bpmp_ipc_enable_clock(TEGRA186_CLK_SE);
+ if (ret != 0) {
+ ERROR("Failed to enable clock\n");
+ return ret;
+ }
+
+ /*
+ * Generate/save SHA256 of ATF during SC7 entry
+ */
+ if (tegra_se_save_sha256_hash(BL31_BASE,
+ (uint32_t)src_len_in_bytes) != 0) {
+ ERROR("Hash calculation failed. Reboot\n");
+ (void)tegra_soc_prepare_system_reset();
+ }
+
/*
* The TZRAM loses power when we enter system suspend. To
* allow graceful exit from system suspend, we need to copy
* BL3-1 over to TZDRAM.
*/
val = params_from_bl2->tzdram_base +
- tegra186_get_cpu_reset_handler_size();
+ tegra186_get_mc_ctx_size();
memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
(uintptr_t)BL31_END - (uintptr_t)BL31_BASE);
+
+ /*
+ * Save code base and size; this would be used by SC7-RF to
+ * verify binary
+ */
+ mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV68_LO,
+ (uint32_t)val);
+ mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV0_HI,
+ (uint32_t)src_len_in_bytes);
+
+ ret = tegra_bpmp_ipc_disable_clock(TEGRA186_CLK_SE);
+ if (ret != 0) {
+ ERROR("Failed to disable clock\n");
+ return ret;
+ }
}
return PSCI_E_SUCCESS;
}
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+ return PSCI_E_NOT_SUPPORTED;
+}
+
int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
{
int32_t ret = PSCI_E_SUCCESS;
diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c
index 16508093e..fbb550af9 100644
--- a/plat/nvidia/tegra/soc/t186/plat_secondary.c
+++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,56 +12,30 @@
#include <lib/mmio.h>
#include <mce.h>
-#include <tegra186_private.h>
#include <tegra_def.h>
#include <tegra_private.h>
-#define MISCREG_AA64_RST_LOW 0x2004U
-#define MISCREG_AA64_RST_HIGH 0x2008U
-
#define SCRATCH_SECURE_RSV1_SCRATCH_0 0x658U
#define SCRATCH_SECURE_RSV1_SCRATCH_1 0x65CU
#define CPU_RESET_MODE_AA64 1U
-extern void memcpy16(void *dest, const void *src, unsigned int length);
-
/*******************************************************************************
* Setup secondary CPU vectors
******************************************************************************/
void plat_secondary_setup(void)
{
uint32_t addr_low, addr_high;
- const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
- uint64_t cpu_reset_handler_base, cpu_reset_handler_size;
INFO("Setting up secondary CPU boot\n");
- /*
- * The BL31 code resides in the TZSRAM which loses state
- * when we enter System Suspend. Copy the wakeup trampoline
- * code to TZDRAM to help us exit from System Suspend.
- */
- cpu_reset_handler_base = tegra186_get_cpu_reset_handler_base();
- cpu_reset_handler_size = tegra186_get_cpu_reset_handler_size();
- (void)memcpy16((void *)(uintptr_t)params_from_bl2->tzdram_base,
- (const void *)(uintptr_t)cpu_reset_handler_base,
- cpu_reset_handler_size);
-
/* TZDRAM base will be used as the "resume" address */
- addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64;
- addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU);
-
- /* write lower 32 bits first, then the upper 11 bits */
- mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low);
- mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high);
+ addr_low = (uintptr_t)&tegra_secure_entrypoint | CPU_RESET_MODE_AA64;
+ addr_high = (uintptr_t)(((uintptr_t)&tegra_secure_entrypoint >> 32U) & 0x7ffU);
/* save reset vector to be used during SYSTEM_SUSPEND exit */
mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO,
addr_low);
mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI,
addr_high);
-
- /* update reset vector address to the CCPLEX */
- (void)mce_update_reset_vector();
}
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index 1018caa94..d6d090aba 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +12,7 @@
#include <bl31/interrupt_mgmt.h>
#include <common/bl_common.h>
#include <common/debug.h>
+#include <common/ep_info.h>
#include <common/interrupt_props.h>
#include <context.h>
#include <cortex_a57.h>
@@ -19,14 +21,19 @@
#include <drivers/arm/gicv2.h>
#include <drivers/console.h>
#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <mce.h>
+#include <memctrl.h>
+#include <smmu.h>
#include <tegra_def.h>
#include <tegra_platform.h>
#include <tegra_private.h>
+extern void memcpy16(void *dest, const void *src, unsigned int length);
+
/*******************************************************************************
* Tegra186 CPU numbers in cluster #0
*******************************************************************************
@@ -101,6 +108,12 @@ static const mmap_region_t tegra_mmap[] = {
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000U, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(TEGRA_HSP_DBELL_BASE, 0x10000U, /* 64KB */
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(TEGRA_BPMP_IPC_TX_PHYS_BASE, TEGRA_BPMP_IPC_CH_MAP_SIZE, /* 4KB */
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(TEGRA_BPMP_IPC_RX_PHYS_BASE, TEGRA_BPMP_IPC_CH_MAP_SIZE, /* 4KB */
+ MT_DEVICE | MT_RW | MT_SECURE),
{0}
};
@@ -145,7 +158,7 @@ static uint32_t tegra186_uart_addresses[TEGRA186_MAX_UART_PORTS + 1] = {
******************************************************************************/
void plat_enable_console(int32_t id)
{
- static console_16550_t uart_console;
+ static console_t uart_console;
uint32_t console_clock;
if ((id > 0) && (id < TEGRA186_MAX_UART_PORTS)) {
@@ -162,7 +175,7 @@ void plat_enable_console(int32_t id)
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&uart_console);
- console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&uart_console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
}
@@ -174,10 +187,20 @@ void plat_early_platform_setup(void)
{
uint64_t impl, val;
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+ const struct tegra_bl31_params *arg_from_bl2 = plat_get_bl31_params();
+
+ /* Verify chip id is t186 */
+ assert(tegra_chipid_is_t186());
/* sanity check MCE firmware compatibility */
mce_verify_firmware_version();
+ /*
+ * Do initial security configuration to allow DRAM/device access.
+ */
+ tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
+ (uint32_t)plat_params->tzdram_size);
+
impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
/*
@@ -191,13 +214,30 @@ void plat_early_platform_setup(void)
val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
write_l2ctlr_el1(val);
}
+
+ /*
+ * The previous bootloader might not have placed the BL32 image
+ * inside the TZDRAM. Platform handler to allow relocation of BL32
+ * image to TZDRAM memory. This behavior might change per platform.
+ */
+ plat_relocate_bl32_image(arg_from_bl2->bl32_image_info);
+}
+
+/*******************************************************************************
+ * Handler for late platform setup
+ ******************************************************************************/
+void plat_late_platform_setup(void)
+{
+ ; /* do nothing */
}
/* Secure IRQs for Tegra186 */
static const interrupt_prop_t tegra186_interrupt_props[] = {
- INTR_PROP_DESC(TEGRA186_TOP_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(TEGRA186_TOP_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
- INTR_PROP_DESC(TEGRA186_AON_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_PROP_DESC(TEGRA186_AON_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE)
};
@@ -277,3 +317,81 @@ int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
return ret;
}
+
+/*******************************************************************************
+ * Handler to relocate BL32 image to TZDRAM
+ ******************************************************************************/
+void plat_relocate_bl32_image(const image_info_t *bl32_img_info)
+{
+ const plat_params_from_bl2_t *plat_bl31_params = plat_get_bl31_plat_params();
+ const entry_point_info_t *bl32_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
+ uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
+
+ if ((bl32_img_info != NULL) && (bl32_ep_info != NULL)) {
+
+ /* Relocate BL32 if it resides outside of the TZDRAM */
+ tzdram_start = plat_bl31_params->tzdram_base;
+ tzdram_end = plat_bl31_params->tzdram_base +
+ plat_bl31_params->tzdram_size;
+ bl32_start = bl32_img_info->image_base;
+ bl32_end = bl32_img_info->image_base + bl32_img_info->image_size;
+
+ assert(tzdram_end > tzdram_start);
+ assert(bl32_end > bl32_start);
+ assert(bl32_ep_info->pc > tzdram_start);
+ assert(bl32_ep_info->pc < tzdram_end);
+
+ /* relocate BL32 */
+ if ((bl32_start >= tzdram_end) || (bl32_end <= tzdram_start)) {
+
+ INFO("Relocate BL32 to TZDRAM\n");
+
+ (void)memcpy16((void *)(uintptr_t)bl32_ep_info->pc,
+ (void *)(uintptr_t)bl32_start,
+ bl32_img_info->image_size);
+
+ /* clean up non-secure intermediate buffer */
+ zeromem((void *)(uintptr_t)bl32_start,
+ bl32_img_info->image_size);
+ }
+ }
+}
+
+/*******************************************************************************
+ * Handler to indicate support for System Suspend
+ ******************************************************************************/
+bool plat_supports_system_suspend(void)
+{
+ return true;
+}
+/*******************************************************************************
+ * Platform specific runtime setup.
+ ******************************************************************************/
+void plat_runtime_setup(void)
+{
+ /*
+ * During cold boot, it is observed that the arbitration
+ * bit is set in the Memory controller leading to false
+ * error interrupts in the non-secure world. To avoid
+ * this, clean the interrupt status register before
+ * booting into the non-secure world
+ */
+ tegra_memctrl_clear_pending_interrupts();
+
+ /*
+ * During boot, USB3 and flash media (SDMMC/SATA) devices need
+ * access to IRAM. Because these clients connect to the MC and
+ * do not have a direct path to the IRAM, the MC implements AHB
+ * redirection during boot to allow path to IRAM. In this mode
+ * accesses to a programmed memory address aperture are directed
+ * to the AHB bus, allowing access to the IRAM. This mode must be
+ * disabled before we jump to the non-secure world.
+ */
+ tegra_memctrl_disable_ahb_redirection();
+
+ /*
+ * Verify the integrity of the previously configured SMMU(s)
+ * settings
+ */
+ tegra_smmu_verify();
+}
diff --git a/plat/nvidia/tegra/soc/t186/plat_smmu.c b/plat/nvidia/tegra/soc/t186/plat_smmu.c
index b4a7fe596..f1bc235e8 100644
--- a/plat/nvidia/tegra/soc/t186/plat_smmu.c
+++ b/plat/nvidia/tegra/soc/t186/plat_smmu.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,171 +14,6 @@
#define MAX_NUM_SMMU_DEVICES U(1)
/*******************************************************************************
- * Array to hold SMMU context for Tegra186
- ******************************************************************************/
-static __attribute__((aligned(16))) smmu_regs_t tegra186_smmu_context[] = {
- _START_OF_TABLE_,
- mc_make_sid_security_cfg(SCEW),
- mc_make_sid_security_cfg(AFIR),
- mc_make_sid_security_cfg(NVDISPLAYR1),
- mc_make_sid_security_cfg(XUSB_DEVR),
- mc_make_sid_security_cfg(VICSRD1),
- mc_make_sid_security_cfg(NVENCSWR),
- mc_make_sid_security_cfg(TSECSRDB),
- mc_make_sid_security_cfg(AXISW),
- mc_make_sid_security_cfg(SDMMCWAB),
- mc_make_sid_security_cfg(AONDMAW),
- mc_make_sid_security_cfg(GPUSWR2),
- mc_make_sid_security_cfg(SATAW),
- mc_make_sid_security_cfg(UFSHCW),
- mc_make_sid_security_cfg(AFIW),
- mc_make_sid_security_cfg(SDMMCR),
- mc_make_sid_security_cfg(SCEDMAW),
- mc_make_sid_security_cfg(UFSHCR),
- mc_make_sid_security_cfg(SDMMCWAA),
- mc_make_sid_security_cfg(APEDMAW),
- mc_make_sid_security_cfg(SESWR),
- mc_make_sid_security_cfg(MPCORER),
- mc_make_sid_security_cfg(PTCR),
- mc_make_sid_security_cfg(BPMPW),
- mc_make_sid_security_cfg(ETRW),
- mc_make_sid_security_cfg(GPUSRD),
- mc_make_sid_security_cfg(VICSWR),
- mc_make_sid_security_cfg(SCEDMAR),
- mc_make_sid_security_cfg(HDAW),
- mc_make_sid_security_cfg(ISPWA),
- mc_make_sid_security_cfg(EQOSW),
- mc_make_sid_security_cfg(XUSB_HOSTW),
- mc_make_sid_security_cfg(TSECSWR),
- mc_make_sid_security_cfg(SDMMCRAA),
- mc_make_sid_security_cfg(APER),
- mc_make_sid_security_cfg(VIW),
- mc_make_sid_security_cfg(APEW),
- mc_make_sid_security_cfg(AXISR),
- mc_make_sid_security_cfg(SDMMCW),
- mc_make_sid_security_cfg(BPMPDMAW),
- mc_make_sid_security_cfg(ISPRA),
- mc_make_sid_security_cfg(NVDECSWR),
- mc_make_sid_security_cfg(XUSB_DEVW),
- mc_make_sid_security_cfg(NVDECSRD),
- mc_make_sid_security_cfg(MPCOREW),
- mc_make_sid_security_cfg(NVDISPLAYR),
- mc_make_sid_security_cfg(BPMPDMAR),
- mc_make_sid_security_cfg(NVJPGSWR),
- mc_make_sid_security_cfg(NVDECSRD1),
- mc_make_sid_security_cfg(TSECSRD),
- mc_make_sid_security_cfg(NVJPGSRD),
- mc_make_sid_security_cfg(SDMMCWA),
- mc_make_sid_security_cfg(SCER),
- mc_make_sid_security_cfg(XUSB_HOSTR),
- mc_make_sid_security_cfg(VICSRD),
- mc_make_sid_security_cfg(AONDMAR),
- mc_make_sid_security_cfg(AONW),
- mc_make_sid_security_cfg(SDMMCRA),
- mc_make_sid_security_cfg(HOST1XDMAR),
- mc_make_sid_security_cfg(EQOSR),
- mc_make_sid_security_cfg(SATAR),
- mc_make_sid_security_cfg(BPMPR),
- mc_make_sid_security_cfg(HDAR),
- mc_make_sid_security_cfg(SDMMCRAB),
- mc_make_sid_security_cfg(ETRR),
- mc_make_sid_security_cfg(AONR),
- mc_make_sid_security_cfg(APEDMAR),
- mc_make_sid_security_cfg(SESRD),
- mc_make_sid_security_cfg(NVENCSRD),
- mc_make_sid_security_cfg(GPUSWR),
- mc_make_sid_security_cfg(TSECSWRB),
- mc_make_sid_security_cfg(ISPWB),
- mc_make_sid_security_cfg(GPUSRD2),
- mc_make_sid_override_cfg(APER),
- mc_make_sid_override_cfg(VICSRD),
- mc_make_sid_override_cfg(NVENCSRD),
- mc_make_sid_override_cfg(NVJPGSWR),
- mc_make_sid_override_cfg(AONW),
- mc_make_sid_override_cfg(BPMPR),
- mc_make_sid_override_cfg(BPMPW),
- mc_make_sid_override_cfg(HDAW),
- mc_make_sid_override_cfg(NVDISPLAYR1),
- mc_make_sid_override_cfg(APEDMAR),
- mc_make_sid_override_cfg(AFIR),
- mc_make_sid_override_cfg(AXISR),
- mc_make_sid_override_cfg(VICSRD1),
- mc_make_sid_override_cfg(TSECSRD),
- mc_make_sid_override_cfg(BPMPDMAW),
- mc_make_sid_override_cfg(MPCOREW),
- mc_make_sid_override_cfg(XUSB_HOSTR),
- mc_make_sid_override_cfg(GPUSWR),
- mc_make_sid_override_cfg(XUSB_DEVR),
- mc_make_sid_override_cfg(UFSHCW),
- mc_make_sid_override_cfg(XUSB_HOSTW),
- mc_make_sid_override_cfg(SDMMCWAB),
- mc_make_sid_override_cfg(SATAW),
- mc_make_sid_override_cfg(SCEDMAR),
- mc_make_sid_override_cfg(HOST1XDMAR),
- mc_make_sid_override_cfg(SDMMCWA),
- mc_make_sid_override_cfg(APEDMAW),
- mc_make_sid_override_cfg(SESWR),
- mc_make_sid_override_cfg(AXISW),
- mc_make_sid_override_cfg(AONDMAW),
- mc_make_sid_override_cfg(TSECSWRB),
- mc_make_sid_override_cfg(MPCORER),
- mc_make_sid_override_cfg(ISPWB),
- mc_make_sid_override_cfg(AONR),
- mc_make_sid_override_cfg(BPMPDMAR),
- mc_make_sid_override_cfg(HDAR),
- mc_make_sid_override_cfg(SDMMCRA),
- mc_make_sid_override_cfg(ETRW),
- mc_make_sid_override_cfg(GPUSWR2),
- mc_make_sid_override_cfg(EQOSR),
- mc_make_sid_override_cfg(TSECSWR),
- mc_make_sid_override_cfg(ETRR),
- mc_make_sid_override_cfg(NVDECSRD),
- mc_make_sid_override_cfg(TSECSRDB),
- mc_make_sid_override_cfg(SDMMCRAA),
- mc_make_sid_override_cfg(NVDECSRD1),
- mc_make_sid_override_cfg(SDMMCR),
- mc_make_sid_override_cfg(NVJPGSRD),
- mc_make_sid_override_cfg(SCEDMAW),
- mc_make_sid_override_cfg(SDMMCWAA),
- mc_make_sid_override_cfg(APEW),
- mc_make_sid_override_cfg(AONDMAR),
- mc_make_sid_override_cfg(PTCR),
- mc_make_sid_override_cfg(SCER),
- mc_make_sid_override_cfg(ISPRA),
- mc_make_sid_override_cfg(ISPWA),
- mc_make_sid_override_cfg(VICSWR),
- mc_make_sid_override_cfg(SESRD),
- mc_make_sid_override_cfg(SDMMCW),
- mc_make_sid_override_cfg(SDMMCRAB),
- mc_make_sid_override_cfg(EQOSW),
- mc_make_sid_override_cfg(GPUSRD2),
- mc_make_sid_override_cfg(SCEW),
- mc_make_sid_override_cfg(GPUSRD),
- mc_make_sid_override_cfg(NVDECSWR),
- mc_make_sid_override_cfg(XUSB_DEVW),
- mc_make_sid_override_cfg(SATAR),
- mc_make_sid_override_cfg(NVDISPLAYR),
- mc_make_sid_override_cfg(VIW),
- mc_make_sid_override_cfg(UFSHCR),
- mc_make_sid_override_cfg(NVENCSWR),
- mc_make_sid_override_cfg(AFIW),
- smmu_make_cfg(TEGRA_SMMU0_BASE),
- smmu_bypass_cfg, /* TBU settings */
- _END_OF_TABLE_,
-};
-
-/*******************************************************************************
- * Handler to return the pointer to the SMMU's context struct
- ******************************************************************************/
-smmu_regs_t *plat_get_smmu_ctx(void)
-{
- /* index of _END_OF_TABLE_ */
- tegra186_smmu_context[0].val = (uint32_t)(ARRAY_SIZE(tegra186_smmu_context)) - 1U;
-
- return tegra186_smmu_context;
-}
-
-/*******************************************************************************
* Handler to return the support SMMU devices number
******************************************************************************/
uint32_t plat_get_num_smmu_devices(void)
diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S
index db692349e..2fc2046d0 100644
--- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S
+++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,135 +12,30 @@
#include <plat/common/common_def.h>
#include <tegra_def.h>
-#define TEGRA186_STATE_SYSTEM_SUSPEND 0x5C7
-#define TEGRA186_STATE_SYSTEM_RESUME 0x600D
-#define TEGRA186_SMMU_CTX_SIZE 0x420
+#define TEGRA186_MC_CTX_SIZE 0x93
- .globl tegra186_cpu_reset_handler
-
-/* CPU reset handler routine */
-func tegra186_cpu_reset_handler _align=4
- /* check if we are exiting system suspend state */
- adr x0, __tegra186_system_suspend_state
- ldr x1, [x0]
- mov x2, #TEGRA186_STATE_SYSTEM_SUSPEND
- lsl x2, x2, #16
- add x2, x2, #TEGRA186_STATE_SYSTEM_SUSPEND
- cmp x1, x2
- bne boot_cpu
-
- /* set system resume state */
- mov x1, #TEGRA186_STATE_SYSTEM_RESUME
- lsl x1, x1, #16
- mov x2, #TEGRA186_STATE_SYSTEM_RESUME
- add x1, x1, x2
- str x1, [x0]
- dsb sy
-
- /* prepare to relocate to TZSRAM */
- mov x0, #BL31_BASE
- adr x1, __tegra186_cpu_reset_handler_end
- adr x2, __tegra186_cpu_reset_handler_data
- ldr x2, [x2, #8]
-
- /* memcpy16 */
-m_loop16:
- cmp x2, #16
- b.lt m_loop1
- ldp x3, x4, [x1], #16
- stp x3, x4, [x0], #16
- sub x2, x2, #16
- b m_loop16
- /* copy byte per byte */
-m_loop1:
- cbz x2, boot_cpu
- ldrb w3, [x1], #1
- strb w3, [x0], #1
- subs x2, x2, #1
- b.ne m_loop1
-
-boot_cpu:
- adr x0, __tegra186_cpu_reset_handler_data
- ldr x0, [x0]
- br x0
-endfunc tegra186_cpu_reset_handler
+ .globl tegra186_get_mc_ctx_size
/*
- * Tegra186 reset data (offset 0x0 - 0x430)
+ * Tegra186 reset data (offset 0x0 - 0x420)
*
- * 0x000: secure world's entrypoint
- * 0x008: BL31 size (RO + RW)
- * 0x00C: SMMU context start
- * 0x42C: SMMU context end
+ * 0x000: MC context start
+ * 0x420: MC context end
*/
.align 4
- .type __tegra186_cpu_reset_handler_data, %object
- .globl __tegra186_cpu_reset_handler_data
-__tegra186_cpu_reset_handler_data:
- .quad tegra_secure_entrypoint
- .quad __BL31_END__ - BL31_BASE
-
- .globl __tegra186_system_suspend_state
-__tegra186_system_suspend_state:
- .quad 0
-
- .align 4
- .globl __tegra186_smmu_context
-__tegra186_smmu_context:
- .rept TEGRA186_SMMU_CTX_SIZE
+__tegra186_mc_context:
+ .rept TEGRA186_MC_CTX_SIZE
.quad 0
.endr
- .size __tegra186_cpu_reset_handler_data, \
- . - __tegra186_cpu_reset_handler_data
.align 4
- .globl __tegra186_cpu_reset_handler_end
-__tegra186_cpu_reset_handler_end:
+__tegra186_mc_context_end:
- .globl tegra186_get_cpu_reset_handler_size
- .globl tegra186_get_cpu_reset_handler_base
- .globl tegra186_get_smmu_ctx_offset
- .globl tegra186_set_system_suspend_entry
-
-/* return size of the CPU reset handler */
-func tegra186_get_cpu_reset_handler_size
- adr x0, __tegra186_cpu_reset_handler_end
- adr x1, tegra186_cpu_reset_handler
- sub x0, x0, x1
- ret
-endfunc tegra186_get_cpu_reset_handler_size
-
-/* return the start address of the CPU reset handler */
-func tegra186_get_cpu_reset_handler_base
- adr x0, tegra186_cpu_reset_handler
- ret
-endfunc tegra186_get_cpu_reset_handler_base
-
-/* return the size of the SMMU context */
-func tegra186_get_smmu_ctx_offset
- adr x0, __tegra186_smmu_context
- adr x1, tegra186_cpu_reset_handler
+/* return the size of the MC context */
+func tegra186_get_mc_ctx_size
+ adr x0, __tegra186_mc_context_end
+ adr x1, __tegra186_mc_context
sub x0, x0, x1
ret
-endfunc tegra186_get_smmu_ctx_offset
-
-/* set system suspend state before SC7 entry */
-func tegra186_set_system_suspend_entry
- mov x0, #TEGRA_MC_BASE
- mov x3, #MC_SECURITY_CFG3_0
- ldr w1, [x0, x3]
- lsl x1, x1, #32
- mov x3, #MC_SECURITY_CFG0_0
- ldr w2, [x0, x3]
- orr x3, x1, x2 /* TZDRAM base */
- adr x0, __tegra186_system_suspend_state
- adr x1, tegra186_cpu_reset_handler
- sub x2, x0, x1 /* offset in TZDRAM */
- mov x0, #TEGRA186_STATE_SYSTEM_SUSPEND
- lsl x0, x0, #16
- add x0, x0, #TEGRA186_STATE_SYSTEM_SUSPEND
- str x0, [x3, x2] /* set value in TZDRAM */
- dsb sy
- ret
-endfunc tegra186_set_system_suspend_entry
+endfunc tegra186_get_mc_ctx_size
diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk
index fe158536c..5275b8e65 100644
--- a/plat/nvidia/tegra/soc/t186/platform_t186.mk
+++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk
@@ -1,5 +1,6 @@
#
# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -13,10 +14,12 @@ $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS))
RESET_TO_BL31 := 1
-PROGRAMMABLE_RESET_ADDRESS := 1
+PROGRAMMABLE_RESET_ADDRESS := 0
COLD_BOOT_SINGLE_CPU := 1
+RELOCATE_BL32_IMAGE := 1
+
# platform settings
TZDRAM_BASE := 0x30000000
$(eval $(call add_define,TZDRAM_BASE))
@@ -27,25 +30,30 @@ $(eval $(call add_define,PLATFORM_CLUSTER_COUNT))
PLATFORM_MAX_CPUS_PER_CLUSTER := 4
$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
-MAX_XLAT_TABLES := 24
+MAX_XLAT_TABLES := 25
$(eval $(call add_define,MAX_XLAT_TABLES))
-MAX_MMAP_REGIONS := 25
+MAX_MMAP_REGIONS := 30
$(eval $(call add_define,MAX_MMAP_REGIONS))
# platform files
-PLAT_INCLUDES += -I${SOC_DIR}/drivers/include
+PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t186 \
+ -I${SOC_DIR}/drivers/include
-BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
+BL31_SOURCES += ${TEGRA_GICv2_SOURCES} \
+ drivers/ti/uart/aarch64/16550_console.S \
lib/cpus/aarch64/denver.S \
lib/cpus/aarch64/cortex_a57.S \
- ${COMMON_DIR}/drivers/gpcdma/gpcdma.c \
- ${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \
- ${COMMON_DIR}/drivers/smmu/smmu.c \
+ ${TEGRA_DRIVERS}/bpmp_ipc/intf.c \
+ ${TEGRA_DRIVERS}/bpmp_ipc/ivc.c \
+ ${TEGRA_DRIVERS}/gpcdma/gpcdma.c \
+ ${TEGRA_DRIVERS}/memctrl/memctrl_v2.c \
+ ${TEGRA_DRIVERS}/smmu/smmu.c \
${SOC_DIR}/drivers/mce/mce.c \
${SOC_DIR}/drivers/mce/ari.c \
${SOC_DIR}/drivers/mce/nvg.c \
${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \
+ $(SOC_DIR)/drivers/se/se.c \
${SOC_DIR}/plat_memctrl.c \
${SOC_DIR}/plat_psci_handlers.c \
${SOC_DIR}/plat_setup.c \
@@ -64,3 +72,6 @@ ERRATA_A57_826977 := 1
ERRATA_A57_828024 := 1
ERRATA_A57_829520 := 1
ERRATA_A57_833471 := 1
+
+# Enable higher performance Non-cacheable load forwarding
+A57_ENABLE_NONCACHEABLE_LOAD_FWD := 1
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
index 1fe3aad39..ef169808e 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
@@ -56,8 +56,10 @@ int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx);
int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time);
int32_t nvg_roc_clean_cache_trbits(void);
void nvg_enable_strict_checking_mode(void);
+void nvg_verify_strict_checking_mode(void);
void nvg_system_shutdown(void);
void nvg_system_reboot(void);
+void nvg_clear_hsm_corr_status(void);
/* declarations for assembly functions */
void nvg_set_request_data(uint64_t req, uint64_t data);
@@ -69,7 +71,9 @@ uint64_t nvg_cache_inval_all(void);
/* MCE helper functions */
void mce_enable_strict_checking(void);
+void mce_verify_strict_checking(void);
void mce_system_shutdown(void);
void mce_system_reboot(void);
+void mce_clear_hsm_corr_status(void);
#endif /* MCE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/se.h b/plat/nvidia/tegra/soc/t194/drivers/include/se.h
index e7cf88d05..7de55a74d 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/se.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/se.h
@@ -7,6 +7,8 @@
#ifndef SE_H
#define SE_H
+int32_t tegra_se_calculate_save_sha256(uint64_t src_addr,
+ uint32_t src_len_inbyte);
int32_t tegra_se_suspend(void);
void tegra_se_resume(void);
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
index ccc46655a..7a68a4303 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
@@ -7,6 +7,8 @@
#ifndef T194_NVG_H
#define T194_NVG_H
+#include <lib/utils_def.h>
+
/**
* t194_nvg.h - Header for the NVIDIA Generic interface (NVG).
* Official documentation for this interface is included as part
@@ -19,123 +21,127 @@
* occur when there is only new functionality.
*/
enum {
- TEGRA_NVG_VERSION_MAJOR = 6,
- TEGRA_NVG_VERSION_MINOR = 6
+ TEGRA_NVG_VERSION_MAJOR = U(6),
+ TEGRA_NVG_VERSION_MINOR = U(7)
};
typedef enum {
- TEGRA_NVG_CHANNEL_VERSION = 0,
- TEGRA_NVG_CHANNEL_POWER_PERF = 1,
- TEGRA_NVG_CHANNEL_POWER_MODES = 2,
- TEGRA_NVG_CHANNEL_WAKE_TIME = 3,
- TEGRA_NVG_CHANNEL_CSTATE_INFO = 4,
- TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND = 5,
- TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND = 6,
- TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND = 8,
- TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST = 10,
- TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE = 11,
- TEGRA_NVG_CHANNEL_NUM_CORES = 20,
- TEGRA_NVG_CHANNEL_UNIQUE_LOGICAL_ID = 21,
- TEGRA_NVG_CHANNEL_LOGICAL_TO_PHYSICAL_MAPPING = 22,
- TEGRA_NVG_CHANNEL_LOGICAL_TO_MPIDR = 23,
- TEGRA_NVG_CHANNEL_SHUTDOWN = 42,
- TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = 43,
- TEGRA_NVG_CHANNEL_ONLINE_CORE = 44,
- TEGRA_NVG_CHANNEL_CC3_CTRL = 45,
- TEGRA_NVG_CHANNEL_CCPLEX_CACHE_CONTROL = 49,
- TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC = 50,
- TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL = 53,
- TEGRA_NVG_CHANNEL_SECURITY_CONFIG = 54,
- TEGRA_NVG_CHANNEL_DEBUG_CONFIG = 55,
- TEGRA_NVG_CHANNEL_DDA_SNOC_MCF = 56,
- TEGRA_NVG_CHANNEL_DDA_MCF_ORD1 = 57,
- TEGRA_NVG_CHANNEL_DDA_MCF_ORD2 = 58,
- TEGRA_NVG_CHANNEL_DDA_MCF_ORD3 = 59,
- TEGRA_NVG_CHANNEL_DDA_MCF_ISO = 60,
- TEGRA_NVG_CHANNEL_DDA_MCF_SISO = 61,
- TEGRA_NVG_CHANNEL_DDA_MCF_NISO = 62,
- TEGRA_NVG_CHANNEL_DDA_MCF_NISO_REMOTE = 63,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_ISO = 64,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_SISO = 65,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO = 66,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO_REMOTE = 67,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3FILL = 68,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3WR = 69,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_L3RD_DMA = 70,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_MCFRD_DMA = 71,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_GLOBAL = 72,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_LL = 73,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3D = 74,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_RD = 75,
- TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_WR = 76,
- TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = 77,
- TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = 78,
- TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = 79,
+ TEGRA_NVG_CHANNEL_VERSION = U(0),
+ TEGRA_NVG_CHANNEL_POWER_PERF = U(1),
+ TEGRA_NVG_CHANNEL_POWER_MODES = U(2),
+ TEGRA_NVG_CHANNEL_WAKE_TIME = U(3),
+ TEGRA_NVG_CHANNEL_CSTATE_INFO = U(4),
+ TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND = U(5),
+ TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND = U(6),
+ TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND = U(8),
+ TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST = U(10),
+ TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE = U(11),
+ TEGRA_NVG_CHANNEL_NUM_CORES = U(20),
+ TEGRA_NVG_CHANNEL_UNIQUE_LOGICAL_ID = U(21),
+ TEGRA_NVG_CHANNEL_LOGICAL_TO_PHYSICAL_MAPPING = U(22),
+ TEGRA_NVG_CHANNEL_LOGICAL_TO_MPIDR = U(23),
+ TEGRA_NVG_CHANNEL_SHUTDOWN = U(42),
+ TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = U(43),
+ TEGRA_NVG_CHANNEL_ONLINE_CORE = U(44),
+ TEGRA_NVG_CHANNEL_CC3_CTRL = U(45),
+ TEGRA_NVG_CHANNEL_CCPLEX_CACHE_CONTROL = U(49),
+ TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC = U(50),
+ TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL = U(53),
+ TEGRA_NVG_CHANNEL_SECURITY_CONFIG = U(54),
+ TEGRA_NVG_CHANNEL_DEBUG_CONFIG = U(55),
+ TEGRA_NVG_CHANNEL_DDA_SNOC_MCF = U(56),
+ TEGRA_NVG_CHANNEL_DDA_MCF_ORD1 = U(57),
+ TEGRA_NVG_CHANNEL_DDA_MCF_ORD2 = U(58),
+ TEGRA_NVG_CHANNEL_DDA_MCF_ORD3 = U(59),
+ TEGRA_NVG_CHANNEL_DDA_MCF_ISO = U(60),
+ TEGRA_NVG_CHANNEL_DDA_MCF_SISO = U(61),
+ TEGRA_NVG_CHANNEL_DDA_MCF_NISO = U(62),
+ TEGRA_NVG_CHANNEL_DDA_MCF_NISO_REMOTE = U(63),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_ISO = U(64),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_SISO = U(65),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO = U(66),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO_REMOTE = U(67),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3FILL = U(68),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3WR = U(69),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_L3RD_DMA = U(70),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_MCFRD_DMA = U(71),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_GLOBAL = U(72),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_LL = U(73),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3D = U(74),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_RD = U(75),
+ TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_WR = U(76),
+ TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = U(77),
+ TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = U(78),
+ TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = U(79),
+ TEGRA_NVG_CHANNEL_RT_SAFE_MASK = U(80),
+ TEGRA_NVG_CHANNEL_RT_WINDOW_US = U(81),
+ TEGRA_NVG_CHANNEL_RT_FWD_PROGRESS_US = U(82),
TEGRA_NVG_CHANNEL_LAST_INDEX
} tegra_nvg_channel_id_t;
typedef enum {
- NVG_STAT_QUERY_SC7_ENTRIES = 1,
- NVG_STAT_QUERY_CC6_ENTRIES = 6,
- NVG_STAT_QUERY_CG7_ENTRIES = 7,
- NVG_STAT_QUERY_C6_ENTRIES = 10,
- NVG_STAT_QUERY_C7_ENTRIES = 14,
- NVG_STAT_QUERY_SC7_RESIDENCY_SUM = 32,
- NVG_STAT_QUERY_CC6_RESIDENCY_SUM = 41,
- NVG_STAT_QUERY_CG7_RESIDENCY_SUM = 46,
- NVG_STAT_QUERY_C6_RESIDENCY_SUM = 51,
- NVG_STAT_QUERY_C7_RESIDENCY_SUM = 56,
- NVG_STAT_QUERY_SC7_ENTRY_TIME_SUM = 60,
- NVG_STAT_QUERY_CC6_ENTRY_TIME_SUM = 61,
- NVG_STAT_QUERY_CG7_ENTRY_TIME_SUM = 62,
- NVG_STAT_QUERY_C6_ENTRY_TIME_SUM = 63,
- NVG_STAT_QUERY_C7_ENTRY_TIME_SUM = 64,
- NVG_STAT_QUERY_SC7_EXIT_TIME_SUM = 70,
- NVG_STAT_QUERY_CC6_EXIT_TIME_SUM = 71,
- NVG_STAT_QUERY_CG7_EXIT_TIME_SUM = 72,
- NVG_STAT_QUERY_C6_EXIT_TIME_SUM = 73,
- NVG_STAT_QUERY_C7_EXIT_TIME_SUM = 74,
- NVG_STAT_QUERY_SC7_ENTRY_LAST = 80,
- NVG_STAT_QUERY_CC6_ENTRY_LAST = 81,
- NVG_STAT_QUERY_CG7_ENTRY_LAST = 82,
- NVG_STAT_QUERY_C6_ENTRY_LAST = 83,
- NVG_STAT_QUERY_C7_ENTRY_LAST = 84,
- NVG_STAT_QUERY_SC7_EXIT_LAST = 90,
- NVG_STAT_QUERY_CC6_EXIT_LAST = 91,
- NVG_STAT_QUERY_CG7_EXIT_LAST = 92,
- NVG_STAT_QUERY_C6_EXIT_LAST = 93,
- NVG_STAT_QUERY_C7_EXIT_LAST = 94
+ NVG_STAT_QUERY_SC7_ENTRIES = U(1),
+ NVG_STAT_QUERY_CC6_ENTRIES = U(6),
+ NVG_STAT_QUERY_CG7_ENTRIES = U(7),
+ NVG_STAT_QUERY_C6_ENTRIES = U(10),
+ NVG_STAT_QUERY_C7_ENTRIES = U(14),
+ NVG_STAT_QUERY_SC7_RESIDENCY_SUM = U(32),
+ NVG_STAT_QUERY_CC6_RESIDENCY_SUM = U(41),
+ NVG_STAT_QUERY_CG7_RESIDENCY_SUM = U(46),
+ NVG_STAT_QUERY_C6_RESIDENCY_SUM = U(51),
+ NVG_STAT_QUERY_C7_RESIDENCY_SUM = U(56),
+ NVG_STAT_QUERY_SC7_ENTRY_TIME_SUM = U(60),
+ NVG_STAT_QUERY_CC6_ENTRY_TIME_SUM = U(61),
+ NVG_STAT_QUERY_CG7_ENTRY_TIME_SUM = U(62),
+ NVG_STAT_QUERY_C6_ENTRY_TIME_SUM = U(63),
+ NVG_STAT_QUERY_C7_ENTRY_TIME_SUM = U(64),
+ NVG_STAT_QUERY_SC7_EXIT_TIME_SUM = U(70),
+ NVG_STAT_QUERY_CC6_EXIT_TIME_SUM = U(71),
+ NVG_STAT_QUERY_CG7_EXIT_TIME_SUM = U(72),
+ NVG_STAT_QUERY_C6_EXIT_TIME_SUM = U(73),
+ NVG_STAT_QUERY_C7_EXIT_TIME_SUM = U(74),
+ NVG_STAT_QUERY_SC7_ENTRY_LAST = U(80),
+ NVG_STAT_QUERY_CC6_ENTRY_LAST = U(81),
+ NVG_STAT_QUERY_CG7_ENTRY_LAST = U(82),
+ NVG_STAT_QUERY_C6_ENTRY_LAST = U(83),
+ NVG_STAT_QUERY_C7_ENTRY_LAST = U(84),
+ NVG_STAT_QUERY_SC7_EXIT_LAST = U(90),
+ NVG_STAT_QUERY_CC6_EXIT_LAST = U(91),
+ NVG_STAT_QUERY_CG7_EXIT_LAST = U(92),
+ NVG_STAT_QUERY_C6_EXIT_LAST = U(93),
+ NVG_STAT_QUERY_C7_EXIT_LAST = U(94)
+
} tegra_nvg_stat_query_t;
typedef enum {
- TEGRA_NVG_CORE_C0 = 0,
- TEGRA_NVG_CORE_C1 = 1,
- TEGRA_NVG_CORE_C6 = 6,
- TEGRA_NVG_CORE_C7 = 7,
- TEGRA_NVG_CORE_WARMRSTREQ = 8
+ TEGRA_NVG_CORE_C0 = U(0),
+ TEGRA_NVG_CORE_C1 = U(1),
+ TEGRA_NVG_CORE_C6 = U(6),
+ TEGRA_NVG_CORE_C7 = U(7),
+ TEGRA_NVG_CORE_WARMRSTREQ = U(8)
} tegra_nvg_core_sleep_state_t;
typedef enum {
- TEGRA_NVG_SHUTDOWN = 0U,
- TEGRA_NVG_REBOOT = 1U
+ TEGRA_NVG_SHUTDOWN = U(0),
+ TEGRA_NVG_REBOOT = U(1)
} tegra_nvg_shutdown_reboot_state_t;
typedef enum {
- TEGRA_NVG_CLUSTER_CC0 = 0,
- TEGRA_NVG_CLUSTER_AUTO_CC1 = 1,
- TEGRA_NVG_CLUSTER_CC6 = 6
+ TEGRA_NVG_CLUSTER_CC0 = U(0),
+ TEGRA_NVG_CLUSTER_AUTO_CC1 = U(1),
+ TEGRA_NVG_CLUSTER_CC6 = U(6)
} tegra_nvg_cluster_sleep_state_t;
typedef enum {
- TEGRA_NVG_CG_CG0 = 0,
- TEGRA_NVG_CG_CG7 = 7
+ TEGRA_NVG_CG_CG0 = U(0),
+ TEGRA_NVG_CG_CG7 = U(7)
} tegra_nvg_cluster_group_sleep_state_t;
typedef enum {
- TEGRA_NVG_SYSTEM_SC0 = 0,
- TEGRA_NVG_SYSTEM_SC7 = 7,
- TEGRA_NVG_SYSTEM_SC8 = 8
+ TEGRA_NVG_SYSTEM_SC0 = U(0),
+ TEGRA_NVG_SYSTEM_SC7 = U(7),
+ TEGRA_NVG_SYSTEM_SC8 = U(8)
} tegra_nvg_system_sleep_state_t;
// ---------------------------------------------------------------------------
@@ -145,95 +151,95 @@ typedef enum {
typedef union {
uint64_t flat;
struct nvg_version_channel_t {
- uint32_t minor_version : 32;
- uint32_t major_version : 32;
+ uint32_t minor_version : U(32);
+ uint32_t major_version : U(32);
} bits;
} nvg_version_data_t;
typedef union {
uint64_t flat;
- struct nvg_power_perf_channel_t {
- uint32_t perf_per_watt : 1;
- uint32_t reserved_31_1 : 31;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t perf_per_watt : U(1);
+ uint32_t reserved_31_1 : U(31);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_power_perf_channel_t;
typedef union {
uint64_t flat;
- struct nvg_power_modes_channel_t {
- uint32_t low_battery : 1;
- uint32_t reserved_1_1 : 1;
- uint32_t battery_save : 1;
- uint32_t reserved_31_3 : 29;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t low_battery : U(1);
+ uint32_t reserved_1_1 : U(1);
+ uint32_t battery_save : U(1);
+ uint32_t reserved_31_3 : U(29);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_power_modes_channel_t;
typedef union nvg_channel_1_data_u {
uint64_t flat;
struct nvg_channel_1_data_s {
- uint32_t perf_per_watt_mode : 1;
- uint32_t reserved_31_1 : 31;
- uint32_t reserved_63_32 : 32;
+ uint32_t perf_per_watt_mode : U(1);
+ uint32_t reserved_31_1 : U(31);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_channel_1_data_t;
typedef union {
uint64_t flat;
- struct nvg_ccplex_cache_control_channel_t {
- uint32_t gpu_ways : 5;
- uint32_t reserved_7_5 : 3;
- uint32_t gpu_only_ways : 5;
- uint32_t reserved_31_13 : 19;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t gpu_ways : U(5);
+ uint32_t reserved_7_5 : U(3);
+ uint32_t gpu_only_ways : U(5);
+ uint32_t reserved_31_13 : U(19);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_ccplex_cache_control_channel_t;
typedef union nvg_channel_2_data_u {
uint64_t flat;
struct nvg_channel_2_data_s {
- uint32_t reserved_1_0 : 2;
- uint32_t battery_saver_mode : 1;
- uint32_t reserved_31_3 : 29;
- uint32_t reserved_63_32 : 32;
+ uint32_t reserved_1_0 : U(2);
+ uint32_t battery_saver_mode : U(1);
+ uint32_t reserved_31_3 : U(29);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_channel_2_data_t;
typedef union {
uint64_t flat;
- struct nvg_wake_time_channel_t {
- uint32_t wake_time : 32;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t wake_time : U(32);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_wake_time_channel_t;
typedef union {
uint64_t flat;
- struct nvg_cstate_info_channel_t {
- uint32_t cluster_state : 3;
- uint32_t reserved_6_3 : 4;
- uint32_t update_cluster : 1;
- uint32_t cg_cstate : 3;
- uint32_t reserved_14_11 : 4;
- uint32_t update_cg : 1;
- uint32_t system_cstate : 4;
- uint32_t reserved_22_20 : 3;
- uint32_t update_system : 1;
- uint32_t reserved_30_24 : 7;
- uint32_t update_wake_mask : 1;
+ struct {
+ uint32_t cluster_state : U(3);
+ uint32_t reserved_6_3 : U(4);
+ uint32_t update_cluster : U(1);
+ uint32_t cg_cstate : U(3);
+ uint32_t reserved_14_11 : U(4);
+ uint32_t update_cg : U(1);
+ uint32_t system_cstate : U(4);
+ uint32_t reserved_22_20 : U(3);
+ uint32_t update_system : U(1);
+ uint32_t reserved_30_24 : U(7);
+ uint32_t update_wake_mask : U(1);
union {
- uint32_t flat : 32;
+ uint32_t flat : U(32);
struct {
- uint32_t vfiq : 1;
- uint32_t virq : 1;
- uint32_t fiq : 1;
- uint32_t irq : 1;
- uint32_t serror : 1;
- uint32_t reserved_10_5 : 6;
- uint32_t fiqout : 1;
- uint32_t irqout : 1;
- uint32_t reserved_31_13 : 19;
+ uint32_t vfiq : U(1);
+ uint32_t virq : U(1);
+ uint32_t fiq : U(1);
+ uint32_t irq : U(1);
+ uint32_t serror : U(1);
+ uint32_t reserved_10_5 : U(6);
+ uint32_t fiqout : U(1);
+ uint32_t irqout : U(1);
+ uint32_t reserved_31_13 : U(19);
} carmel;
} wake_mask;
} bits;
@@ -241,184 +247,183 @@ typedef union {
typedef union {
uint64_t flat;
- struct nvg_lower_bound_channel_t {
- uint32_t crossover_value : 32;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t crossover_value : U(32);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_lower_bound_channel_t;
typedef union {
uint64_t flat;
- struct nvg_cstate_stat_query_channel_t {
- uint32_t unit_id : 4;
- uint32_t reserved_15_4 : 12;
- uint32_t stat_id : 16;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t unit_id : U(4);
+ uint32_t reserved_15_4 : U(12);
+ uint32_t stat_id : U(16);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_cstate_stat_query_channel_t;
typedef union {
uint64_t flat;
- struct nvg_num_cores_channel_t {
- uint32_t num_cores : 4;
- uint32_t reserved_31_4 : 28;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t num_cores : U(4);
+ uint32_t reserved_31_4 : U(28);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_num_cores_channel_t;
typedef union {
uint64_t flat;
- struct nvg_unique_logical_id_channel_t {
- uint32_t unique_core_id : 3;
- uint32_t reserved_31_3 : 29;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t unique_core_id : U(3);
+ uint32_t reserved_31_3 : U(29);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_unique_logical_id_channel_t;
typedef union {
uint64_t flat;
- struct nvg_logical_to_physical_mappings_channel_t {
- uint32_t lcore0_pcore_id : 4;
- uint32_t lcore1_pcore_id : 4;
- uint32_t lcore2_pcore_id : 4;
- uint32_t lcore3_pcore_id : 4;
- uint32_t lcore4_pcore_id : 4;
- uint32_t lcore5_pcore_id : 4;
- uint32_t lcore6_pcore_id : 4;
- uint32_t lcore7_pcore_id : 4;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t lcore0_pcore_id : U(4);
+ uint32_t lcore1_pcore_id : U(4);
+ uint32_t lcore2_pcore_id : U(4);
+ uint32_t lcore3_pcore_id : U(4);
+ uint32_t lcore4_pcore_id : U(4);
+ uint32_t lcore5_pcore_id : U(4);
+ uint32_t lcore6_pcore_id : U(4);
+ uint32_t lcore7_pcore_id : U(4);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_logical_to_physical_mappings_channel_t;
typedef union {
uint64_t flat;
struct nvg_logical_to_mpidr_channel_write_t {
- uint32_t lcore_id : 3;
- uint32_t reserved_31_3 : 29;
- uint32_t reserved_63_32 : 32;
+ uint32_t lcore_id : U(3);
+ uint32_t reserved_31_3 : U(29);
+ uint32_t reserved_63_32 : U(32);
} write;
struct nvg_logical_to_mpidr_channel_read_t {
- uint32_t mpidr : 32;
- uint32_t reserved_63_32 : 32;
+ uint32_t mpidr : U(32);
+ uint32_t reserved_63_32 : U(32);
} read;
} nvg_logical_to_mpidr_channel_t;
typedef union {
uint64_t flat;
- struct nvg_is_sc7_allowed_channel_t {
- uint32_t is_sc7_allowed : 1;
- uint32_t reserved_31_1 : 31;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t is_sc7_allowed : U(1);
+ uint32_t reserved_31_1 : U(31);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_is_sc7_allowed_channel_t;
typedef union {
uint64_t flat;
- struct nvg_core_online_channel_t {
- uint32_t core_id : 4;
- uint32_t reserved_31_4 : 28;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t core_id : U(4);
+ uint32_t reserved_31_4 : U(28);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_core_online_channel_t;
typedef union {
uint64_t flat;
- struct nvg_cc3_control_channel_t {
- uint32_t freq_req : 9;
- uint32_t reserved_30_9 : 22;
- uint32_t enable : 1;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t freq_req : U(9);
+ uint32_t reserved_30_9 : U(22);
+ uint32_t enable : U(1);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_cc3_control_channel_t;
typedef enum {
- TEGRA_NVG_CHANNEL_UPDATE_GSC_ALL = 0,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_NVDEC = 1,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR1 = 2,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR2 = 3,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECA = 4,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECB = 5,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP = 6,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_APE = 7,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_SPE = 8,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_SCE = 9,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_APR = 10,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM = 11,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_TSEC = 12,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_RCE = 13,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_MCE = 14,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_SE_SC7 = 15,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_SPE = 16,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_RCE = 17,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_TZ_TO_BPMP = 18,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR1 = 19,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_NS_TO_BPMP = 20,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_OEM_SC7 = 21,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_SPE_SCE_BPMP = 22,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_SC7_RESUME_FW = 23,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_CAMERA_TASKLIST = 24,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_XUSB = 25,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_CV = 26,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR2 = 27,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_HYPERVISOR_SW = 28,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_SMMU_PAGETABLES = 29,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_30 = 30,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_31 = 31,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM = 32,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_NVLINK = 33,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_SBS = 34,
- TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR = 35,
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_ALL = U(0),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_NVDEC = U(1),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR1 = U(2),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR2 = U(3),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECA = U(4),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECB = U(5),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP = U(6),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_APE = U(7),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_SPE = U(8),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_SCE = U(9),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_APR = U(10),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM = U(11),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_TSEC = U(12),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_RCE = U(13),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_MCE = U(14),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_SE_SC7 = U(15),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_SPE = U(16),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_RCE = U(17),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_TZ_TO_BPMP = U(18),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR1 = U(19),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_NS_TO_BPMP = U(20),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_OEM_SC7 = U(21),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_SPE_SCE_BPMP = U(22),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_SC7_RESUME_FW = U(23),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_CAMERA_TASKLIST = U(24),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_XUSB = U(25),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_CV = U(26),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR2 = U(27),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_HYPERVISOR_SW = U(28),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_SMMU_PAGETABLES = U(29),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_30 = U(30),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_31 = U(31),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM = U(32),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_NVLINK = U(33),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_SBS = U(34),
+ TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR = U(35),
TEGRA_NVG_CHANNEL_UPDATE_GSC_LAST_INDEX
} tegra_nvg_channel_update_gsc_gsc_enum_t;
typedef union {
uint64_t flat;
- struct nvg_update_ccplex_gsc_channel_t {
- uint32_t gsc_enum : 16;
- uint32_t reserved_31_16 : 16;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t gsc_enum : U(16);
+ uint32_t reserved_31_16 : U(16);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_update_ccplex_gsc_channel_t;
typedef union {
uint64_t flat;
struct nvg_security_config_channel_t {
- uint32_t strict_checking_enabled : 1;
- uint32_t strict_checking_locked : 1;
- uint32_t reserved_31_2 : 30;
- uint32_t reserved_63_32 : 32;
+ uint32_t strict_checking_enabled : U(1);
+ uint32_t strict_checking_locked : U(1);
+ uint32_t reserved_31_2 : U(30);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_security_config_t;
typedef union {
uint64_t flat;
struct nvg_shutdown_channel_t {
- uint32_t reboot : 1;
- uint32_t reserved_31_1 : 31;
- uint32_t reserved_63_32 : 32;
+ uint32_t reboot : U(1);
+ uint32_t reserved_31_1 : U(31);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_shutdown_t;
typedef union {
uint64_t flat;
struct nvg_debug_config_channel_t {
- uint32_t enter_debug_state_on_mca : 1;
- uint32_t reserved_31_1 : 31;
- uint32_t reserved_63_32 : 32;
+ uint32_t enter_debug_state_on_mca : U(1);
+ uint32_t reserved_31_1 : U(31);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_debug_config_t;
typedef union {
uint64_t flat;
- struct nvg_hsm_error_ctrl_channel_t {
- uint32_t uncorr : 1;
- uint32_t corr : 1;
- uint32_t reserved_31_2 : 30;
- uint32_t reserved_63_32 : 32;
+ struct {
+ uint32_t uncorr : U(1);
+ uint32_t corr : U(1);
+ uint32_t reserved_31_2 : U(30);
+ uint32_t reserved_63_32 : U(32);
} bits;
} nvg_hsm_error_ctrl_channel_t;
extern nvg_debug_config_t nvg_debug_config;
-#endif
-
+#endif /* T194_NVG_H */
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
index 00c671bcc..e3d5bd513 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
@@ -116,25 +116,6 @@ int32_t mce_update_gsc_tzdram(void)
}
/*******************************************************************************
- * Handler to update carveout values for TZ SysRAM aperture
- ******************************************************************************/
-int32_t mce_update_gsc_tzram(void)
-{
- int32_t ret;
-
- /*
- * MCE firmware is not running on simulation platforms.
- */
- if (mce_firmware_not_supported()) {
- ret = -EINVAL;
- } else {
- ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM);
- }
-
- return ret;
-}
-
-/*******************************************************************************
* Handler to issue the UPDATE_CSTATE_INFO request
******************************************************************************/
void mce_update_cstate_info(const mce_cstate_info_t *cstate)
@@ -236,6 +217,15 @@ void mce_enable_strict_checking(void)
nvg_enable_strict_checking_mode();
}
}
+void mce_verify_strict_checking(void)
+{
+ bool is_silicon = tegra_platform_is_silicon();
+ bool is_fpga = tegra_platform_is_fpga();
+
+ if (is_silicon || is_fpga) {
+ nvg_verify_strict_checking_mode();
+ }
+}
#endif
/*******************************************************************************
@@ -253,3 +243,11 @@ void mce_system_reboot(void)
{
nvg_system_reboot();
}
+
+/*******************************************************************************
+ * Handler to clear CCPLEX->HSM correctable RAS error signal.
+ ******************************************************************************/
+void mce_clear_hsm_corr_status(void)
+{
+ nvg_clear_hsm_corr_status();
+}
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
index 1012cdf11..f76ab14a6 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
@@ -4,19 +4,22 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+#include <errno.h>
+
#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <denver.h>
-#include <errno.h>
#include <lib/mmio.h>
+
#include <mce_private.h>
#include <platform_def.h>
#include <t194_nvg.h>
#include <tegra_private.h>
-#define ID_AFR0_EL1_CACHE_OPS_SHIFT 12
-#define ID_AFR0_EL1_CACHE_OPS_MASK 0xFU
+#define ID_AFR0_EL1_CACHE_OPS_SHIFT U(12)
+#define ID_AFR0_EL1_CACHE_OPS_MASK U(0xF)
/*
* Reports the major and minor version of this interface.
*
@@ -209,7 +212,16 @@ void nvg_enable_strict_checking_mode(void)
uint64_t params = (uint64_t)(STRICT_CHECKING_ENABLED_SET |
STRICT_CHECKING_LOCKED_SET);
- nvg_set_request_data(TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params);
+ nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params);
+}
+
+void nvg_verify_strict_checking_mode(void)
+{
+ uint64_t params = (uint64_t)(STRICT_CHECKING_ENABLED_SET |
+ STRICT_CHECKING_LOCKED_SET);
+
+ nvg_set_request((uint64_t)TEGRA_NVG_CHANNEL_SECURITY_CONFIG);
+ assert(params == (uint64_t)nvg_get_result());
}
#endif
@@ -221,7 +233,8 @@ void nvg_enable_strict_checking_mode(void)
void nvg_system_reboot(void)
{
/* issue command for reboot */
- nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_REBOOT);
+ nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SHUTDOWN,
+ (uint64_t)TEGRA_NVG_REBOOT);
}
/*
@@ -232,5 +245,18 @@ void nvg_system_reboot(void)
void nvg_system_shutdown(void)
{
/* issue command for shutdown */
- nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_SHUTDOWN);
+ nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SHUTDOWN,
+ (uint64_t)TEGRA_NVG_SHUTDOWN);
+}
+
+/*
+ * Request to clear CCPLEX->HSM correctable error signal.
+ * NVGDATA[1]: A write of 1 clears the CCPLEX->HSM correctable error signal,
+ * A write of 0 has no effect.
+ */
+void nvg_clear_hsm_corr_status(void)
+{
+ nvg_hsm_error_ctrl_channel_t status = { .bits = { .corr = 1U, }, };
+
+ nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL, status.flat);
}
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
index 3a2e959d0..31b0e2678 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/se/se.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
@@ -15,6 +15,7 @@
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
+#include <se.h>
#include <tegra_platform.h>
#include "se_private.h"
@@ -22,10 +23,17 @@
/*******************************************************************************
* Constants and Macros
******************************************************************************/
-#define ERR_STATUS_SW_CLEAR U(0xFFFFFFFF)
-#define INT_STATUS_SW_CLEAR U(0xFFFFFFFF)
-#define MAX_TIMEOUT_MS U(100) /* Timeout in 100ms */
-#define NUM_SE_REGS_TO_SAVE U(4)
+#define ERR_STATUS_SW_CLEAR U(0xFFFFFFFF)
+#define INT_STATUS_SW_CLEAR U(0xFFFFFFFF)
+#define MAX_TIMEOUT_MS U(1000) /* Max. timeout of 1s */
+#define NUM_SE_REGS_TO_SAVE U(4)
+
+#define BYTES_IN_WORD U(4)
+#define SHA256_MAX_HASH_RESULT U(7)
+#define SHA256_DST_SIZE U(32)
+#define SHA_FIRST_OP U(1)
+#define MAX_SHA_ENGINE_CHUNK_SIZE U(0xFFFFFF)
+#define SHA256_MSG_LENGTH_ONETIME U(0xFFFF)
/*******************************************************************************
* Data structure and global variables
@@ -54,7 +62,7 @@ static bool tegra_se_is_operation_complete(void)
*/
do {
val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS);
- se_is_busy = !!(val & CTX_SAVE_AUTO_SE_BUSY);
+ se_is_busy = ((val & CTX_SAVE_AUTO_SE_BUSY) != 0U);
/* sleep until SE finishes */
if (se_is_busy) {
@@ -175,6 +183,270 @@ static int32_t tegra_se_save_context(void)
}
/*
+ * Check that SE operation has completed after kickoff
+ * This function is invoked after an SE operation has been started,
+ * and it checks the following conditions:
+ * 1. SE0_INT_STATUS = SE0_OP_DONE
+ * 2. SE0_STATUS = IDLE
+ * 3. SE0_ERR_STATUS is clean.
+ */
+static int32_t tegra_se_sha256_hash_operation_complete(void)
+{
+ uint32_t val = 0U;
+
+ /* Poll the SE interrupt register to ensure H/W operation complete */
+ val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET);
+ while (SE0_INT_OP_DONE(val) == SE0_INT_OP_DONE_CLEAR) {
+ val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET);
+ if (SE0_INT_OP_DONE(val) != SE0_INT_OP_DONE_CLEAR) {
+ break;
+ }
+ }
+
+ /* Poll the SE status idle to ensure H/W operation complete */
+ val = tegra_se_read_32(SE0_SHA_STATUS_0);
+ while (val != SE0_SHA_STATUS_IDLE) {
+ val = tegra_se_read_32(SE0_SHA_STATUS_0);
+ if (val == SE0_SHA_STATUS_IDLE) {
+ break;
+ }
+ }
+
+ /* Ensure that no errors are thrown during operation */
+ val = tegra_se_read_32(SE0_ERR_STATUS_REG_OFFSET);
+ if (val != 0U) {
+ ERROR("%s: error during SE operation! 0x%x", __func__,
+ val);
+ return -ENOTSUP;
+ }
+
+ return 0;
+}
+
+/*
+ * Security engine primitive normal operations
+ */
+static int32_t tegra_se_start_normal_operation(uint64_t src_addr,
+ uint32_t nbytes, uint32_t last_buf, uint32_t src_len_inbytes)
+{
+ uint32_t val = 0U;
+ uint32_t src_in_lo;
+ uint32_t src_in_msb;
+ uint32_t src_in_hi;
+ int32_t ret = 0;
+
+ if ((src_addr == 0ULL) || (nbytes == 0U))
+ return -EINVAL;
+
+ src_in_lo = (uint32_t)src_addr;
+ src_in_msb = (uint32_t)((src_addr >> 32U) & 0xFFU);
+ src_in_hi = ((src_in_msb << SE0_IN_HI_ADDR_HI_0_MSB_SHIFT) |
+ (nbytes & MAX_SHA_ENGINE_CHUNK_SIZE));
+
+ /* set SRC_IN_ADDR_LO and SRC_IN_ADDR_HI*/
+ tegra_se_write_32(SE0_IN_ADDR, src_in_lo);
+ tegra_se_write_32(SE0_IN_HI_ADDR_HI, src_in_hi);
+
+ val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET);
+ if (val > 0U) {
+ tegra_se_write_32(SE0_INT_STATUS_REG_OFFSET, 0x0U);
+ }
+
+ /* Enable SHA interrupt for SE0 Operation */
+ tegra_se_write_32(SE0_SHA_INT_ENABLE, 0x1aU);
+
+ /* flush to DRAM for SE to use the updated contents */
+ flush_dcache_range(src_addr, src_len_inbytes);
+
+ /* Start SHA256 operation */
+ if (last_buf == 1U) {
+ tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START |
+ SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD);
+ } else {
+ tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START);
+ }
+
+ return ret;
+}
+
+static int32_t tegra_se_calculate_sha256_hash(uint64_t src_addr,
+ uint32_t src_len_inbyte)
+{
+ uint32_t val, last_buf, i;
+ int32_t ret = 0;
+ uint32_t operations;
+ uint64_t src_len_inbits;
+ uint32_t len_bits_msb;
+ uint32_t len_bits_lsb;
+ uint32_t number_of_operations, max_bytes, bytes_left, remaining_bytes;
+
+ if (src_len_inbyte > MAX_SHA_ENGINE_CHUNK_SIZE) {
+ ERROR("SHA input chunk size too big: 0x%x\n", src_len_inbyte);
+ return -EINVAL;
+ }
+
+ if (src_addr == 0ULL) {
+ return -EINVAL;
+ }
+
+ /* number of bytes per operation */
+ max_bytes = (SHA256_HASH_SIZE_BYTES * SHA256_MSG_LENGTH_ONETIME);
+
+ src_len_inbits = (uint32_t)(src_len_inbyte * 8U);
+ len_bits_msb = (uint32_t)(src_len_inbits >> 32U);
+ len_bits_lsb = (uint32_t)src_len_inbits;
+
+ /* program SE0_CONFIG for SHA256 operation */
+ val = (uint32_t)(SE0_CONFIG_ENC_ALG_SHA | SE0_CONFIG_ENC_MODE_SHA256 |
+ SE0_CONFIG_DEC_ALG_NOP | SE0_CONFIG_DST_HASHREG);
+ tegra_se_write_32(SE0_SHA_CONFIG, val);
+
+ /* set SE0_SHA_MSG_LENGTH registers */
+ tegra_se_write_32(SE0_SHA_MSG_LENGTH_0, len_bits_lsb);
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb);
+ tegra_se_write_32(SE0_SHA_MSG_LENGTH_1, len_bits_msb);
+
+ /* zero out unused SE0_SHA_MSG_LENGTH and SE0_SHA_MSG_LEFT */
+ tegra_se_write_32(SE0_SHA_MSG_LENGTH_2, 0U);
+ tegra_se_write_32(SE0_SHA_MSG_LENGTH_3, 0U);
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_1, 0U);
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_2, 0U);
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_3, 0U);
+
+ number_of_operations = (src_len_inbyte / max_bytes);
+ remaining_bytes = (src_len_inbyte % max_bytes);
+ if (remaining_bytes > 0U) {
+ number_of_operations += 1U;
+ }
+
+ /*
+ * 1. Operations == 1: program SE0_SHA_TASK register to initiate SHA256
+ * hash generation by setting
+ * 1(SE0_SHA_CONFIG_HW_INIT_HASH) to SE0_SHA_TASK
+ * and start SHA256-normal operation.
+ * 2. 1 < Operations < number_of_operations: program SE0_SHA_TASK to
+ * 0(SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE) to load
+ * intermediate SHA256 digest result from
+ * HASH_RESULT register to continue SHA256
+ * generation and start SHA256-normal operation.
+ * 3. Operations == number_of_operations: continue with step 2 and set
+ * max_bytes to bytes_left to process final
+ * hash-result generation and start SHA256-normal
+ * operation.
+ */
+ bytes_left = src_len_inbyte;
+ for (operations = 1U; operations <= number_of_operations;
+ operations++) {
+ if (operations == SHA_FIRST_OP) {
+ val = SE0_SHA_CONFIG_HW_INIT_HASH;
+ } else {
+ /* Load intermediate SHA digest result to
+ * SHA:HASH_RESULT(0..7) to continue the SHA
+ * calculation and tell the SHA engine to use it.
+ */
+ for (i = 0U; (i / BYTES_IN_WORD) <=
+ SHA256_MAX_HASH_RESULT; i += BYTES_IN_WORD) {
+ val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 +
+ i);
+ tegra_se_write_32(SE0_SHA_HASH_RESULT_0 + i,
+ val);
+ }
+ val = SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE;
+ if (len_bits_lsb <= (max_bytes * 8U)) {
+ len_bits_lsb = (remaining_bytes * 8U);
+ } else {
+ len_bits_lsb -= (max_bytes * 8U);
+ }
+ tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb);
+ }
+ tegra_se_write_32(SE0_SHA_TASK_CONFIG, val);
+
+ max_bytes = (SHA256_HASH_SIZE_BYTES *
+ SHA256_MSG_LENGTH_ONETIME);
+ if (bytes_left < max_bytes) {
+ max_bytes = bytes_left;
+ last_buf = 1U;
+ } else {
+ bytes_left = bytes_left - max_bytes;
+ last_buf = 0U;
+ }
+ /* start operation */
+ ret = tegra_se_start_normal_operation(src_addr, max_bytes,
+ last_buf, src_len_inbyte);
+ if (ret != 0) {
+ ERROR("Error during SE operation! 0x%x", ret);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+static int32_t tegra_se_save_sha256_pmc_scratch(void)
+{
+ uint32_t val = 0U, hash_offset = 0U, scratch_offset = 0U;
+ int32_t ret;
+
+ /* Check SE0 operation status */
+ ret = tegra_se_sha256_hash_operation_complete();
+ if (ret != 0) {
+ ERROR("SE operation complete Failed! 0x%x", ret);
+ return ret;
+ }
+
+ for (scratch_offset = SECURE_SCRATCH_TZDRAM_SHA256_HASH_START;
+ scratch_offset <= SECURE_SCRATCH_TZDRAM_SHA256_HASH_END;
+ scratch_offset += BYTES_IN_WORD) {
+ val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 + hash_offset);
+ mmio_write_32((uint32_t)(TEGRA_SCRATCH_BASE + scratch_offset),
+ val);
+ hash_offset += BYTES_IN_WORD;
+ }
+ return 0;
+}
+
+/*
+ * Handler to generate SHA256 and save HASH-result to pmc-scratch register
+ */
+int32_t tegra_se_calculate_save_sha256(uint64_t src_addr,
+ uint32_t src_len_inbyte)
+{
+ uint32_t security;
+ int32_t val = 0;
+
+ /* Set SE_SOFT_SETTINGS=SE_SECURE to prevent NS process to change SE
+ * registers.
+ */
+ security = tegra_se_read_32(SE0_SECURITY);
+ tegra_se_write_32(SE0_SECURITY, security | SE0_SECURITY_SE_SOFT_SETTING);
+
+ /* Bootrom enable IN_ID bit in SE0_SHA_GSCID_0 register during SC7-exit, causing
+ * SE0 ignores SE0 operation, and therefore failure of 2nd iteration of SC7 cycle.
+ */
+ tegra_se_write_32(SE0_SHA_GSCID_0, 0x0U);
+
+ /* Calculate SHA256 of BL31 */
+ val = tegra_se_calculate_sha256_hash(src_addr, src_len_inbyte);
+ if (val != 0) {
+ ERROR("%s: SHA256 generation failed\n", __func__);
+ return val;
+ }
+
+ /*
+ * Reset SE_SECURE to previous value.
+ */
+ tegra_se_write_32(SE0_SECURITY, security);
+
+ /* copy sha256_dst to PMC Scratch register */
+ val = tegra_se_save_sha256_pmc_scratch();
+ if (val != 0) {
+ ERROR("%s: SE0 status Error.\n", __func__);
+ }
+
+ return val;
+}
+
+/*
* Handler to power down the SE hardware blocks - SE, RNG1 and PKA1. This
* needs to be called only during System Suspend.
*/
@@ -186,7 +458,8 @@ int32_t tegra_se_suspend(void)
assert(tegra_bpmp_ipc_init() == 0);
/* Enable SE clock before SE context save */
- tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+ ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE);
+ assert(ret == 0);
/* save SE registers */
se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT);
@@ -201,7 +474,8 @@ int32_t tegra_se_suspend(void)
}
/* Disable SE clock after SE context save */
- tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+ ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE);
+ assert(ret == 0);
return ret;
}
@@ -211,11 +485,14 @@ int32_t tegra_se_suspend(void)
*/
void tegra_se_resume(void)
{
+ int32_t ret = 0;
+
/* initialise communication channel with BPMP */
assert(tegra_bpmp_ipc_init() == 0);
/* Enable SE clock before SE context restore */
- tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+ ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE);
+ assert(ret == 0);
/*
* When TZ takes over after System Resume, TZ should first reconfigure
@@ -229,5 +506,6 @@ void tegra_se_resume(void)
mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]);
/* Disable SE clock after SE context restore */
- tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+ ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE);
+ assert(ret == 0);
}
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
index a2c5d1c38..fc118aaa1 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
@@ -9,6 +9,86 @@
#define SE_PRIVATE_H
#include <lib/utils_def.h>
+#include <tegra_def.h>
+
+/* SE0 security register */
+#define SE0_SECURITY U(0x18)
+#define SE0_SECURITY_SE_SOFT_SETTING (((uint32_t)1) << 16U)
+
+/* SE0 SHA GSCID register */
+#define SE0_SHA_GSCID_0 U(0x100)
+
+/* SE0 config register */
+#define SE0_SHA_CONFIG U(0x104)
+#define SE0_SHA_TASK_CONFIG U(0x108)
+#define SE0_SHA_CONFIG_HW_INIT_HASH (((uint32_t)1) << 0U)
+#define SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE U(0)
+
+#define SE0_CONFIG_ENC_ALG_SHIFT U(12)
+#define SE0_CONFIG_ENC_ALG_SHA \
+ (((uint32_t)3) << SE0_CONFIG_ENC_ALG_SHIFT)
+#define SE0_CONFIG_DEC_ALG_SHIFT U(8)
+#define SE0_CONFIG_DEC_ALG_NOP \
+ (((uint32_t)0) << SE0_CONFIG_DEC_ALG_SHIFT)
+#define SE0_CONFIG_DST_SHIFT U(2)
+#define SE0_CONFIG_DST_HASHREG \
+ (((uint32_t)1) << SE0_CONFIG_DST_SHIFT)
+#define SHA256_HASH_SIZE_BYTES U(256)
+
+#define SE0_CONFIG_ENC_MODE_SHIFT U(24)
+#define SE0_CONFIG_ENC_MODE_SHA256 \
+ (((uint32_t)5) << SE0_CONFIG_ENC_MODE_SHIFT)
+
+/* SHA input message length */
+#define SE0_IN_ADDR U(0x10c)
+#define SE0_IN_HI_ADDR_HI U(0x110)
+#define SE0_IN_HI_ADDR_HI_0_MSB_SHIFT U(24)
+
+/* SHA input message length */
+#define SE0_SHA_MSG_LENGTH_0 U(0x11c)
+#define SE0_SHA_MSG_LENGTH_1 U(0x120)
+#define SE0_SHA_MSG_LENGTH_2 U(0x124)
+#define SE0_SHA_MSG_LENGTH_3 U(0x128)
+
+/* SHA input message left */
+#define SE0_SHA_MSG_LEFT_0 U(0x12c)
+#define SE0_SHA_MSG_LEFT_1 U(0x130)
+#define SE0_SHA_MSG_LEFT_2 U(0x134)
+#define SE0_SHA_MSG_LEFT_3 U(0x138)
+
+/* SE HASH-RESULT */
+#define SE0_SHA_HASH_RESULT_0 U(0x13c)
+
+/* SE OPERATION */
+#define SE0_OPERATION_REG_OFFSET U(0x17c)
+#define SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT U(16)
+#define SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD \
+ ((uint32_t)0x1 << SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT)
+#define SE0_OPERATION_SHIFT U(0)
+#define SE0_OP_START \
+ (((uint32_t)0x1) << SE0_OPERATION_SHIFT)
+
+/* SE Interrupt */
+#define SE0_SHA_INT_ENABLE U(0x180)
+
+#define SE0_INT_STATUS_REG_OFFSET U(0x184)
+#define SE0_INT_OP_DONE_SHIFT U(4)
+#define SE0_INT_OP_DONE_CLEAR \
+ (((uint32_t)0U) << SE0_INT_OP_DONE_SHIFT)
+#define SE0_INT_OP_DONE(x) \
+ ((x) & (((uint32_t)0x1U) << SE0_INT_OP_DONE_SHIFT))
+
+/* SE SHA Status */
+#define SE0_SHA_STATUS_0 U(0x188)
+#define SE0_SHA_STATUS_IDLE U(0)
+
+/* SE error status */
+#define SE0_ERR_STATUS_REG_OFFSET U(0x18c)
+#define SE0_ERR_STATUS_CLEAR U(0)
+
+/* SE error status */
+#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_START SECURE_SCRATCH_RSV68_LO
+#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_END SECURE_SCRATCH_RSV71_HI
/* SE0_INT_ENABLE_0 */
#define SE0_INT_ENABLE U(0x88)
@@ -20,7 +100,7 @@
/* SE0_SHA_INT_STATUS_0 */
#define SHA_INT_STATUS U(0x184)
-#define SHA_SE_OP_DONE (U(1) << 4)
+#define SHA_SE_OP_DONE (U(1) << 4)
/* SE0_SHA_ERR_STATUS_0 */
#define SHA_ERR_STATUS U(0x18C)
@@ -74,12 +154,12 @@
static inline uint32_t tegra_se_read_32(uint32_t offset)
{
- return mmio_read_32(TEGRA_SE0_BASE + offset);
+ return mmio_read_32((uint32_t)(TEGRA_SE0_BASE + offset));
}
static inline void tegra_se_write_32(uint32_t offset, uint32_t val)
{
- mmio_write_32(TEGRA_SE0_BASE + offset, val);
+ mmio_write_32((uint32_t)(TEGRA_SE0_BASE + offset), val);
}
#endif /* SE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c
index bb1dd6706..9ddcacf31 100644
--- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c
@@ -8,693 +8,43 @@
#include <common/bl_common.h>
#include <mce.h>
#include <memctrl_v2.h>
-#include <tegra_mc_def.h>
#include <tegra_platform.h>
+#include <tegra_private.h>
/*******************************************************************************
- * Array to hold stream_id override config register offsets
+ * Array to hold MC context for Tegra194
******************************************************************************/
-const static uint32_t tegra194_streamid_override_regs[] = {
- MC_STREAMID_OVERRIDE_CFG_HDAR,
- MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR,
- MC_STREAMID_OVERRIDE_CFG_NVENCSRD,
- MC_STREAMID_OVERRIDE_CFG_SATAR,
- MC_STREAMID_OVERRIDE_CFG_NVENCSWR,
- MC_STREAMID_OVERRIDE_CFG_HDAW,
- MC_STREAMID_OVERRIDE_CFG_SATAW,
- MC_STREAMID_OVERRIDE_CFG_ISPRA,
- MC_STREAMID_OVERRIDE_CFG_ISPFALR,
- MC_STREAMID_OVERRIDE_CFG_ISPWA,
- MC_STREAMID_OVERRIDE_CFG_ISPWB,
- MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR,
- MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW,
- MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR,
- MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW,
- MC_STREAMID_OVERRIDE_CFG_TSECSRD,
- MC_STREAMID_OVERRIDE_CFG_TSECSWR,
- MC_STREAMID_OVERRIDE_CFG_SDMMCRA,
- MC_STREAMID_OVERRIDE_CFG_SDMMCR,
- MC_STREAMID_OVERRIDE_CFG_SDMMCRAB,
- MC_STREAMID_OVERRIDE_CFG_SDMMCWA,
- MC_STREAMID_OVERRIDE_CFG_SDMMCW,
- MC_STREAMID_OVERRIDE_CFG_SDMMCWAB,
- MC_STREAMID_OVERRIDE_CFG_VICSRD,
- MC_STREAMID_OVERRIDE_CFG_VICSWR,
- MC_STREAMID_OVERRIDE_CFG_VIW,
- MC_STREAMID_OVERRIDE_CFG_NVDECSRD,
- MC_STREAMID_OVERRIDE_CFG_NVDECSWR,
- MC_STREAMID_OVERRIDE_CFG_APER,
- MC_STREAMID_OVERRIDE_CFG_APEW,
- MC_STREAMID_OVERRIDE_CFG_NVJPGSRD,
- MC_STREAMID_OVERRIDE_CFG_NVJPGSWR,
- MC_STREAMID_OVERRIDE_CFG_SESRD,
- MC_STREAMID_OVERRIDE_CFG_SESWR,
- MC_STREAMID_OVERRIDE_CFG_AXIAPR,
- MC_STREAMID_OVERRIDE_CFG_AXIAPW,
- MC_STREAMID_OVERRIDE_CFG_ETRR,
- MC_STREAMID_OVERRIDE_CFG_ETRW,
- MC_STREAMID_OVERRIDE_CFG_TSECSRDB,
- MC_STREAMID_OVERRIDE_CFG_TSECSWRB,
- MC_STREAMID_OVERRIDE_CFG_AXISR,
- MC_STREAMID_OVERRIDE_CFG_AXISW,
- MC_STREAMID_OVERRIDE_CFG_EQOSR,
- MC_STREAMID_OVERRIDE_CFG_EQOSW,
- MC_STREAMID_OVERRIDE_CFG_UFSHCR,
- MC_STREAMID_OVERRIDE_CFG_UFSHCW,
- MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR,
- MC_STREAMID_OVERRIDE_CFG_BPMPR,
- MC_STREAMID_OVERRIDE_CFG_BPMPW,
- MC_STREAMID_OVERRIDE_CFG_BPMPDMAR,
- MC_STREAMID_OVERRIDE_CFG_BPMPDMAW,
- MC_STREAMID_OVERRIDE_CFG_AONR,
- MC_STREAMID_OVERRIDE_CFG_AONW,
- MC_STREAMID_OVERRIDE_CFG_AONDMAR,
- MC_STREAMID_OVERRIDE_CFG_AONDMAW,
- MC_STREAMID_OVERRIDE_CFG_SCER,
- MC_STREAMID_OVERRIDE_CFG_SCEW,
- MC_STREAMID_OVERRIDE_CFG_SCEDMAR,
- MC_STREAMID_OVERRIDE_CFG_SCEDMAW,
- MC_STREAMID_OVERRIDE_CFG_APEDMAR,
- MC_STREAMID_OVERRIDE_CFG_APEDMAW,
- MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1,
- MC_STREAMID_OVERRIDE_CFG_VICSRD1,
- MC_STREAMID_OVERRIDE_CFG_NVDECSRD1,
- MC_STREAMID_OVERRIDE_CFG_VIFALR,
- MC_STREAMID_OVERRIDE_CFG_VIFALW,
- MC_STREAMID_OVERRIDE_CFG_DLA0RDA,
- MC_STREAMID_OVERRIDE_CFG_DLA0FALRDB,
- MC_STREAMID_OVERRIDE_CFG_DLA0WRA,
- MC_STREAMID_OVERRIDE_CFG_DLA0FALWRB,
- MC_STREAMID_OVERRIDE_CFG_DLA1RDA,
- MC_STREAMID_OVERRIDE_CFG_DLA1FALRDB,
- MC_STREAMID_OVERRIDE_CFG_DLA1WRA,
- MC_STREAMID_OVERRIDE_CFG_DLA1FALWRB,
- MC_STREAMID_OVERRIDE_CFG_PVA0RDA,
- MC_STREAMID_OVERRIDE_CFG_PVA0RDB,
- MC_STREAMID_OVERRIDE_CFG_PVA0RDC,
- MC_STREAMID_OVERRIDE_CFG_PVA0WRA,
- MC_STREAMID_OVERRIDE_CFG_PVA0WRB,
- MC_STREAMID_OVERRIDE_CFG_PVA0WRC,
- MC_STREAMID_OVERRIDE_CFG_PVA1RDA,
- MC_STREAMID_OVERRIDE_CFG_PVA1RDB,
- MC_STREAMID_OVERRIDE_CFG_PVA1RDC,
- MC_STREAMID_OVERRIDE_CFG_PVA1WRA,
- MC_STREAMID_OVERRIDE_CFG_PVA1WRB,
- MC_STREAMID_OVERRIDE_CFG_PVA1WRC,
- MC_STREAMID_OVERRIDE_CFG_RCER,
- MC_STREAMID_OVERRIDE_CFG_RCEW,
- MC_STREAMID_OVERRIDE_CFG_RCEDMAR,
- MC_STREAMID_OVERRIDE_CFG_RCEDMAW,
- MC_STREAMID_OVERRIDE_CFG_NVENC1SRD,
- MC_STREAMID_OVERRIDE_CFG_NVENC1SWR,
- MC_STREAMID_OVERRIDE_CFG_PCIE0R,
- MC_STREAMID_OVERRIDE_CFG_PCIE0W,
- MC_STREAMID_OVERRIDE_CFG_PCIE1R,
- MC_STREAMID_OVERRIDE_CFG_PCIE1W,
- MC_STREAMID_OVERRIDE_CFG_PCIE2AR,
- MC_STREAMID_OVERRIDE_CFG_PCIE2AW,
- MC_STREAMID_OVERRIDE_CFG_PCIE3R,
- MC_STREAMID_OVERRIDE_CFG_PCIE3W,
- MC_STREAMID_OVERRIDE_CFG_PCIE4R,
- MC_STREAMID_OVERRIDE_CFG_PCIE4W,
- MC_STREAMID_OVERRIDE_CFG_PCIE5R,
- MC_STREAMID_OVERRIDE_CFG_PCIE5W,
- MC_STREAMID_OVERRIDE_CFG_ISPFALW,
- MC_STREAMID_OVERRIDE_CFG_DLA0RDA1,
- MC_STREAMID_OVERRIDE_CFG_DLA1RDA1,
- MC_STREAMID_OVERRIDE_CFG_PVA0RDA1,
- MC_STREAMID_OVERRIDE_CFG_PVA0RDB1,
- MC_STREAMID_OVERRIDE_CFG_PVA1RDA1,
- MC_STREAMID_OVERRIDE_CFG_PVA1RDB1,
- MC_STREAMID_OVERRIDE_CFG_PCIE5R1,
- MC_STREAMID_OVERRIDE_CFG_NVENCSRD1,
- MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1,
- MC_STREAMID_OVERRIDE_CFG_ISPRA1,
- MC_STREAMID_OVERRIDE_CFG_PCIE0R1,
- MC_STREAMID_OVERRIDE_CFG_MIU0R,
- MC_STREAMID_OVERRIDE_CFG_MIU0W,
- MC_STREAMID_OVERRIDE_CFG_MIU1R,
- MC_STREAMID_OVERRIDE_CFG_MIU1W,
- MC_STREAMID_OVERRIDE_CFG_MIU2R,
- MC_STREAMID_OVERRIDE_CFG_MIU2W,
- MC_STREAMID_OVERRIDE_CFG_MIU3R,
- MC_STREAMID_OVERRIDE_CFG_MIU3W
+static __attribute__((aligned(16))) mc_regs_t tegra194_mc_context[] = {
+ _START_OF_TABLE_,
+ mc_smmu_bypass_cfg, /* TBU settings */
+ _END_OF_TABLE_,
};
/*******************************************************************************
- * Array to hold the security configs for stream IDs
+ * Handler to return the pointer to the MC's context struct
******************************************************************************/
-const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = {
- mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(ISPRA, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(ISPFALR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(ISPWA, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(ISPWB, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(VIW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(AXIAPR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(AXIAPW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE),
- mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(VIFALR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(VIFALW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(DLA0RDA, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(DLA0FALRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(DLA0WRA, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(DLA0FALWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(DLA1RDA, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(DLA1FALRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(DLA1WRA, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(DLA1FALWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA0RDA, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA0RDB, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA0RDC, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA0WRA, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA0WRB, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA0WRC, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA1RDA, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA1RDB, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA1RDC, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA1WRA, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA1WRB, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA1WRC, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(RCER, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(RCEW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(RCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(RCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVENC1SRD, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVENC1SWR, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE0R, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE0W, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE1R, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE1W, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE2AR, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE2AW, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE3R, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE3W, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE4R, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE4W, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE5R, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE5W, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(ISPFALW, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(DLA0RDA1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(DLA1RDA1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA0RDA1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA0RDB1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA1RDA1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PVA1RDB1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE5R1, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVENCSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(NVENC1SRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(ISPRA1, NON_SECURE, NO_OVERRIDE, ENABLE),
- mc_make_sec_cfg(PCIE0R1, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(MIU0R, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(MIU0W, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(MIU1R, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(MIU1W, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(MIU2R, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(MIU2W, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(MIU3R, NON_SECURE, OVERRIDE, ENABLE),
- mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, ENABLE),
-};
-
-/* To be called by common memctrl_v2.c */
-static void tegra194_memctrl_reconfig_mss_clients(void)
+mc_regs_t *plat_memctrl_get_sys_suspend_ctx(void)
{
- uint32_t reg_val, wdata_0, wdata_1, wdata_2;
-
- wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB;
- if (tegra_platform_is_silicon()) {
- wdata_0 |= MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB;
- }
-
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
-
- /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
- do {
- reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
- } while ((reg_val & wdata_0) != wdata_0);
-
- wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB|
- MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_VIFAL_FLUSH_ENB;
- if (tegra_platform_is_silicon()) {
- wdata_1 |= MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_RCE_FLUSH_ENB;
- }
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
- /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
- do {
- reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
- } while ((reg_val & wdata_1) != wdata_1);
-
- wdata_2 = MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_AONDMA_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_BPMPDMA_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_SCEDMA_FLUSH_ENB;
- if (tegra_platform_is_silicon()) {
- wdata_2 |= MC_CLIENT_HOTRESET_CTRL2_RCEDMA_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE5A_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE3A_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE3_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE0A_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE0A2_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL2_PCIE4A_FLUSH_ENB;
- }
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL2, wdata_2);
- /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
- do {
- reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS2);
- } while ((reg_val & wdata_2) != wdata_2);
-
- /*
- * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and
- * strongly ordered MSS clients.
- *
- * MC clients with default SO_DEV override still enabled at TSA:
- * EQOSW, SATAW, XUSB_DEVW, XUSB_HOSTW, PCIe0w, PCIe1w, PCIe2w,
- * PCIe3w, PCIe4w and PCIe5w.
- */
- mc_set_tsa_w_passthrough(AONDMAW);
- mc_set_tsa_w_passthrough(AONW);
- mc_set_tsa_w_passthrough(APEDMAW);
- mc_set_tsa_w_passthrough(APEW);
- mc_set_tsa_w_passthrough(AXISW);
- mc_set_tsa_w_passthrough(BPMPDMAW);
- mc_set_tsa_w_passthrough(BPMPW);
- mc_set_tsa_w_passthrough(EQOSW);
- mc_set_tsa_w_passthrough(ETRW);
- mc_set_tsa_w_passthrough(RCEDMAW);
- mc_set_tsa_w_passthrough(RCEW);
- mc_set_tsa_w_passthrough(SCEDMAW);
- mc_set_tsa_w_passthrough(SCEW);
- mc_set_tsa_w_passthrough(SDMMCW);
- mc_set_tsa_w_passthrough(SDMMCWA);
- mc_set_tsa_w_passthrough(SDMMCWAB);
- mc_set_tsa_w_passthrough(SESWR);
- mc_set_tsa_w_passthrough(TSECSWR);
- mc_set_tsa_w_passthrough(TSECSWRB);
- mc_set_tsa_w_passthrough(UFSHCW);
- mc_set_tsa_w_passthrough(VICSWR);
- mc_set_tsa_w_passthrough(VIFALW);
- /*
- * set HUB2 as SO_DEV_HUBID
- */
- reg_val = tsa_read_32(PCIE0W);
- mc_set_tsa_hub2(reg_val, PCIE0W);
- reg_val = tsa_read_32(PCIE1W);
- mc_set_tsa_hub2(reg_val, PCIE1W);
- reg_val = tsa_read_32(PCIE2AW);
- mc_set_tsa_hub2(reg_val, PCIE2AW);
- reg_val = tsa_read_32(PCIE3W);
- mc_set_tsa_hub2(reg_val, PCIE3W);
- reg_val = tsa_read_32(PCIE4W);
- mc_set_tsa_hub2(reg_val, PCIE4W);
- reg_val = tsa_read_32(SATAW);
- mc_set_tsa_hub2(reg_val, SATAW);
- reg_val = tsa_read_32(XUSB_DEVW);
- mc_set_tsa_hub2(reg_val, XUSB_DEVW);
- reg_val = tsa_read_32(XUSB_HOSTW);
- mc_set_tsa_hub2(reg_val, XUSB_HOSTW);
-
- /*
- * Hw Bug: 200385660, 200394107
- * PCIE datapath hangs when there are more than 28 outstanding
- * requests on data backbone for x1 controller. This is seen
- * on third party PCIE IP, C1 - PCIE1W, C2 - PCIE2AW and C3 - PCIE3W.
- *
- * Setting Reorder depth limit, 16 which is < 28.
- */
- mc_set_tsa_depth_limit(REORDER_DEPTH_LIMIT, PCIE1W);
- mc_set_tsa_depth_limit(REORDER_DEPTH_LIMIT, PCIE2AW);
- mc_set_tsa_depth_limit(REORDER_DEPTH_LIMIT, PCIE3W);
-
- /* Ordered MC Clients on Xavier are EQOS, SATA, XUSB, PCIe1 and PCIe3
- * ISO clients(DISP, VI, EQOS) should never snoop caches and
- * don't need ROC/PCFIFO ordering.
- * ISO clients(EQOS) that need ordering should use PCFIFO ordering
- * and bypass ROC ordering by using FORCE_NON_COHERENT path.
- * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence
- * over SMMU attributes.
- * Force all Normal memory transactions from ISO and non-ISO to be
- * non-coherent(bypass ROC, avoid cache snoop to avoid perf hit).
- * Force the SO_DEV transactions from ordered ISO clients(EQOS) to
- * non-coherent path and enable MC PCFIFO interlock for ordering.
- * Force the SO_DEV transactions from ordered non-ISO clients (PCIe,
- * XUSB, SATA) to coherent so that the transactions are
- * ordered by ROC.
- * PCFIFO ensure write ordering.
- * Read after Write ordering is maintained/enforced by MC clients.
- * Clients that need PCIe type write ordering must
- * go through ROC ordering.
- * Ordering enable for Read clients is not necessary.
- * R5's and A9 would get necessary ordering from AXI and
- * don't need ROC ordering enable:
- * - MMIO ordering is through dev mapping and MMIO
- * accesses bypass SMMU.
- * - Normal memory is accessed through SMMU and ordering is
- * ensured by client and AXI.
- * - Ack point for Normal memory is WCAM in MC.
- * - MMIO's can be early acked and AXI ensures dev memory ordering,
- * Client ensures read/write direction change ordering.
- * - See Bug 200312466 for more details.
- */
- mc_set_txn_override(AONDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(AONDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(AONR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(AONW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(APEDMAR, CGID_TAG_ADR, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(APEDMAW, CGID_TAG_ADR, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(APER, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(APEW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AXISR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(AXISW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(BPMPDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(BPMPDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(BPMPR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(BPMPW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(EQOSR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(EQOSW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(ETRR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ETRW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(HOST1XDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(MPCORER, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MPCOREW, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(NVDISPLAYR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVDISPLAYR1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(PCIE0R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE0R1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE0W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE1R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE1W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- if (tegra_platform_is_silicon()) {
- mc_set_txn_override(PCIE2AR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE2AW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE3R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE3W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE4R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE4W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE5R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE5W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(PCIE5R1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- }
- mc_set_txn_override(PTCR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(RCEDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(RCEDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(RCER, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(RCEW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SATAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(SATAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(SCEDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SCEDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SCER, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SCEW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SDMMCR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SDMMCRAB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SDMMCRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SDMMCW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SDMMCWA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SDMMCWAB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- /*
- * TO DO: make SESRD/WR FORCE_COHERENT once SE+TZ with SMMU is enabled.
- */
- mc_set_txn_override(SESRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(SESWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(TSECSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(TSECSRDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(TSECSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(TSECSWRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(UFSHCR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(UFSHCW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(VICSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(VICSRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(VICSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(VIFALR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(VIFALW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(XUSB_DEVR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(XUSB_DEVW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(XUSB_HOSTR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(XUSB_HOSTW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP);
- mc_set_txn_override(AXIAPR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(AXIAPW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA0FALRDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA0FALWRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA0RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA0RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA0WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA1FALRDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA1FALWRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA1RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA1RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(DLA1WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(HDAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(HDAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(ISPFALR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ISPFALW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ISPRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ISPRA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ISPWA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ISPWB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVDEC1SRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVDEC1SRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVDEC1SWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVDECSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVDECSRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVDECSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVENC1SRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVENC1SRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVENC1SWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVENCSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVENCSRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVENCSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVJPGSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(NVJPGSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0RDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0RDB1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0RDC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0WRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA0WRC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1RDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1RDB1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1RDC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1WRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(PVA1WRC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(VIW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
-
- if (tegra_platform_is_silicon()) {
- mc_set_txn_override(MIU0R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU0W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU1R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU1W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU2R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU2W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU3R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU3W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU4R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU4W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU5R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU5W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU6R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU6W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU7R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(MIU7W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- }
-
- /*
- * At this point, ordering can occur at SCF. So, remove PCFIFO's
- * control over ordering requests.
- *
- * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for
- * boot and strongly ordered MSS clients
- */
- reg_val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) &
- mc_set_pcfifo_unordered_boot_so_mss(2, TSECSWR);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, reg_val);
-
- reg_val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWA) &
- mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCW) &
- mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB) &
- mc_set_pcfifo_unordered_boot_so_mss(3, VICSWR) &
- mc_set_pcfifo_unordered_boot_so_mss(3, APEW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, reg_val);
-
- reg_val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) &
- mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, TSECSWRB) &
- mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, BPMPW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, AONW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, SCEW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
- /* EQOSW has PCFIFO order enabled. */
- reg_val |= mc_set_pcfifo_unordered_boot_so_mss(4, EQOSW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, reg_val);
-
- reg_val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW) &
- mc_set_pcfifo_unordered_boot_so_mss(5, VIFALW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, reg_val);
-
- reg_val = MC_PCFIFO_CLIENT_CONFIG6_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(6, RCEW) &
- mc_set_pcfifo_unordered_boot_so_mss(6, RCEDMAW) &
- mc_set_pcfifo_unordered_boot_so_mss(6, PCIE0W);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG6, reg_val);
-
- reg_val = MC_PCFIFO_CLIENT_CONFIG7_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(7, PCIE4W) &
- mc_set_pcfifo_unordered_boot_so_mss(7, PCIE5W);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG7, reg_val);
-
- /* Set Order Id only for the clients having non zero order id */
- reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_9_RESET_VAL, 9, XUSB_HOSTW);
- tegra_mc_write_32(MC_CLIENT_ORDER_ID_9, reg_val);
-
- reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_27_RESET_VAL, 27, PCIE0W);
- tegra_mc_write_32(MC_CLIENT_ORDER_ID_27, reg_val);
-
- reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_28_RESET_VAL, 28, PCIE4W);
- reg_val = mc_client_order_id(reg_val, 28, PCIE5W);
- tegra_mc_write_32(MC_CLIENT_ORDER_ID_28, reg_val);
-
- /*
- * Set VC Id only for the clients having different reset values like
- * SDMMCRAB, SDMMCWAB, SESRD, SESWR, TSECSRD,TSECSRDB, TSECSWR and
- * TSECSWRB clients
- */
- reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_0_RESET_VAL, 0, APB);
- tegra_mc_write_32(MC_HUB_PC_VC_ID_0, reg_val);
+ /* index of _END_OF_TABLE_ */
+ tegra194_mc_context[0].val = (uint32_t)ARRAY_SIZE(tegra194_mc_context) - 1U;
- /* SDMMCRAB and SDMMCWAB clients */
- reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_2_RESET_VAL, 2, SD);
- tegra_mc_write_32(MC_HUB_PC_VC_ID_2, reg_val);
-
- reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_4_RESET_VAL, 4, NIC);
- tegra_mc_write_32(MC_HUB_PC_VC_ID_4, reg_val);
-
- reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_12_RESET_VAL, 12, UFSHCPC2);
- tegra_mc_write_32(MC_HUB_PC_VC_ID_12, reg_val);
-
- wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
-
- wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
-
- wdata_2 = MC_CLIENT_HOTRESET_CTRL2_RESET_VAL;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL2, wdata_2);
-
- reg_val = MC_COALESCE_CTRL_COALESCER_ENABLE;
- tegra_mc_write_32(MC_COALESCE_CTRL, reg_val);
-
- /*
- * WAR to hardware bug 1953865: Coalescer must be disabled
- * for PVA0RDC and PVA1RDC interfaces.
- */
- reg_val = tegra_mc_read_32(MC_COALESCE_CONFIG_6_0);
- reg_val &= ~(MC_COALESCE_CONFIG_6_0_PVA0RDC_COALESCER_ENABLED |
- MC_COALESCE_CONFIG_6_0_PVA1RDC_COALESCER_ENABLED);
- tegra_mc_write_32(MC_COALESCE_CONFIG_6_0, reg_val);
+ return tegra194_mc_context;
}
/*******************************************************************************
- * Struct to hold the memory controller settings
+ * Handler to restore platform specific settings to the memory controller
******************************************************************************/
-static tegra_mc_settings_t tegra194_mc_settings = {
- .streamid_override_cfg = tegra194_streamid_override_regs,
- .num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_override_regs),
- .streamid_security_cfg = tegra194_streamid_sec_cfgs,
- .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs),
- .reconfig_mss_clients = tegra194_memctrl_reconfig_mss_clients
-};
+void plat_memctrl_restore(void)
+{
+ UNUSED_FUNC_NOP(); /* do nothing */
+}
/*******************************************************************************
- * Handler to return the pointer to the memory controller's settings struct
+ * Handler to program platform specific settings to the memory controller
******************************************************************************/
-tegra_mc_settings_t *tegra_get_mc_settings(void)
+void plat_memctrl_setup(void)
{
- return &tegra194_mc_settings;
+ UNUSED_FUNC_NOP(); /* do nothing */
}
/*******************************************************************************
@@ -704,6 +54,8 @@ tegra_mc_settings_t *tegra_get_mc_settings(void)
void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
{
uint32_t sec_reg_ctrl = tegra_mc_read_32(MC_SECURITY_CFG_REG_CTRL_0);
+ uint32_t phys_base_lo = (uint32_t)phys_base & 0xFFF00000;
+ uint32_t phys_base_hi = (uint32_t)(phys_base >> 32);
/*
* Check TZDRAM carveout register access status. Setup TZDRAM fence
@@ -718,8 +70,8 @@ void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
*/
INFO("Configuring TrustZone DRAM Memory Carveout\n");
- tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base);
- tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32));
+ tegra_mc_write_32(MC_SECURITY_CFG0_0, phys_base_lo);
+ tegra_mc_write_32(MC_SECURITY_CFG3_0, phys_base_hi);
tegra_mc_write_32(MC_SECURITY_CFG1_0, (uint32_t)(size_in_bytes >> 20));
/*
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index cc8be128a..41a85ee7c 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -10,14 +10,17 @@
#include <string.h>
#include <arch_helpers.h>
+#include <bpmp_ipc.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <context.h>
+#include <drivers/delay_timer.h>
#include <denver.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/psci/psci.h>
#include <mce.h>
#include <mce_private.h>
+#include <memctrl_v2.h>
#include <plat/common/platform.h>
#include <se.h>
#include <smmu.h>
@@ -44,14 +47,6 @@ static struct t19x_psci_percpu_data {
uint32_t wake_time;
} __aligned(CACHE_WRITEBACK_GRANULE) t19x_percpu_data[PLATFORM_CORE_COUNT];
-/*
- * tegra_fake_system_suspend acts as a boolean var controlling whether
- * we are going to take fake system suspend code or normal system suspend code
- * path. This variable is set inside the sip call handlers, when the kernel
- * requests an SIP call to set the suspend debug flags.
- */
-bool tegra_fake_system_suspend;
-
int32_t tegra_soc_validate_power_state(uint32_t power_state,
psci_power_state_t *req_state)
{
@@ -78,19 +73,16 @@ int32_t tegra_soc_validate_power_state(uint32_t power_state,
switch (state_id) {
case PSTATE_ID_CORE_IDLE:
+ if (psci_get_pstate_type(power_state) != PSTATE_TYPE_STANDBY) {
+ ret = PSCI_E_INVALID_PARAMS;
+ break;
+ }
+
/* Core idle request */
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
req_state->pwr_domain_state[MPIDR_AFFLVL1] = PSCI_LOCAL_STATE_RUN;
break;
- case PSTATE_ID_CORE_POWERDN:
-
- /* Core powerdown request */
- req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id;
- req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
-
- break;
-
default:
ERROR("%s: unsupported state id (%d)\n", __func__, state_id);
ret = PSCI_E_INVALID_PARAMS;
@@ -122,9 +114,9 @@ int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
const plat_local_state_t *pwr_domain_state;
- uint8_t stateid_afflvl0, stateid_afflvl2;
+ uint8_t stateid_afflvl2;
plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
- uint64_t smmu_ctx_base;
+ uint64_t mc_ctx_base;
uint32_t val;
mce_cstate_info_t sc7_cstate_info = {
.cluster = (uint32_t)TEGRA_NVG_CLUSTER_CC6,
@@ -133,34 +125,23 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
.system_state_force = 1U,
.update_wake_mask = 1U,
};
- uint32_t cpu = plat_my_core_pos();
int32_t ret = 0;
/* get the state ID */
pwr_domain_state = target_state->pwr_domain_state;
- stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0] &
- TEGRA194_STATE_ID_MASK;
stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
TEGRA194_STATE_ID_MASK;
- if ((stateid_afflvl0 == PSTATE_ID_CORE_POWERDN)) {
-
- /* Enter CPU powerdown */
- (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
- (uint64_t)TEGRA_NVG_CORE_C7,
- t19x_percpu_data[cpu].wake_time,
- 0U);
-
- } else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+ if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
/* save 'Secure Boot' Processor Feature Config Register */
val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG);
mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val);
- /* save SMMU context */
- smmu_ctx_base = params_from_bl2->tzdram_base +
- tegra194_get_smmu_ctx_offset();
- tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
+ /* save MC context */
+ mc_ctx_base = params_from_bl2->tzdram_base +
+ tegra194_get_mc_ctx_offset();
+ tegra_mc_save_context((uintptr_t)mc_ctx_base);
/*
* Suspend SE, RNG1 and PKA1 only on silcon and fpga,
@@ -171,32 +152,27 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
assert(ret == 0);
}
- if (!tegra_fake_system_suspend) {
-
- /* Prepare for system suspend */
- mce_update_cstate_info(&sc7_cstate_info);
+ /* Prepare for system suspend */
+ mce_update_cstate_info(&sc7_cstate_info);
- do {
- val = (uint32_t)mce_command_handler(
- (uint32_t)MCE_CMD_IS_SC7_ALLOWED,
- (uint32_t)TEGRA_NVG_CORE_C7,
- MCE_CORE_SLEEP_TIME_INFINITE,
- 0U);
- } while (val == 0U);
-
- /* Instruct the MCE to enter system suspend state */
- ret = mce_command_handler(
- (uint64_t)MCE_CMD_ENTER_CSTATE,
- (uint64_t)TEGRA_NVG_CORE_C7,
+ do {
+ val = (uint32_t)mce_command_handler(
+ (uint32_t)MCE_CMD_IS_SC7_ALLOWED,
+ (uint32_t)TEGRA_NVG_CORE_C7,
MCE_CORE_SLEEP_TIME_INFINITE,
0U);
- assert(ret == 0);
-
- /* set system suspend state for house-keeping */
- tegra194_set_system_suspend_entry();
- }
- } else {
- ; /* do nothing */
+ } while (val == 0U);
+
+ /* Instruct the MCE to enter system suspend state */
+ ret = mce_command_handler(
+ (uint64_t)MCE_CMD_ENTER_CSTATE,
+ (uint64_t)TEGRA_NVG_CORE_C7,
+ MCE_CORE_SLEEP_TIME_INFINITE,
+ 0U);
+ assert(ret == 0);
+
+ /* set system suspend state for house-keeping */
+ tegra194_set_system_suspend_entry();
}
return PSCI_E_SUCCESS;
@@ -234,15 +210,6 @@ static plat_local_state_t tegra_get_afflvl1_pwr_state(const plat_local_state_t *
plat_local_state_t target = states[core_pos];
mce_cstate_info_t cstate_info = { 0 };
- /* CPU suspend */
- if (target == PSTATE_ID_CORE_POWERDN) {
-
- /* Program default wake mask */
- cstate_info.wake_mask = TEGRA194_CORE_WAKE_MASK;
- cstate_info.update_wake_mask = 1;
- mce_update_cstate_info(&cstate_info);
- }
-
/* CPU off */
if (target == PLAT_MAX_OFF_STATE) {
@@ -300,10 +267,34 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta
plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
TEGRA194_STATE_ID_MASK;
+ uint64_t src_len_in_bytes = (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE;
uint64_t val;
- u_register_t ns_sctlr_el1;
+ int32_t ret = PSCI_E_SUCCESS;
if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+ val = params_from_bl2->tzdram_base +
+ tegra194_get_cpu_reset_handler_size();
+
+ /* initialise communication channel with BPMP */
+ ret = tegra_bpmp_ipc_init();
+ assert(ret == 0);
+
+ /* Enable SE clock before SE context save */
+ ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE);
+ assert(ret == 0);
+
+ /*
+ * It is very unlikely that the BL31 image would be
+ * bigger than 2^32 bytes
+ */
+ assert(src_len_in_bytes < UINT32_MAX);
+
+ if (tegra_se_calculate_save_sha256(BL31_BASE,
+ (uint32_t)src_len_in_bytes) != 0) {
+ ERROR("Hash calculation failed. Reboot\n");
+ (void)tegra_soc_prepare_system_reset();
+ }
+
/*
* The TZRAM loses power when we enter system suspend. To
* allow graceful exit from system suspend, we need to copy
@@ -312,34 +303,19 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta
val = params_from_bl2->tzdram_base +
tegra194_get_cpu_reset_handler_size();
memcpy((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
- (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE);
+ src_len_in_bytes);
- /*
- * In fake suspend mode, ensure that the loopback procedure
- * towards system suspend exit is started, instead of calling
- * WFI. This is done by disabling both MMU's of EL1 & El3
- * and calling tegra_secure_entrypoint().
- */
- if (tegra_fake_system_suspend) {
-
- /*
- * Disable EL1's MMU.
- */
- ns_sctlr_el1 = read_sctlr_el1();
- ns_sctlr_el1 &= (~((u_register_t)SCTLR_M_BIT));
- write_sctlr_el1(ns_sctlr_el1);
-
- /*
- * Disable MMU to power up the CPU in a "clean"
- * state
- */
- disable_mmu_el3();
- tegra_secure_entrypoint();
- panic();
- }
+ /* Disable SE clock after SE context save */
+ ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE);
+ assert(ret == 0);
}
- return PSCI_E_SUCCESS;
+ return ret;
+}
+
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+ return PSCI_E_NOT_SUPPORTED;
}
int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
@@ -367,7 +343,11 @@ int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
+ const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+ uint8_t enable_ccplex_lock_step = params_from_bl2->enable_ccplex_lock_step;
uint8_t stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
+ cpu_context_t *ctx = cm_get_context(NON_SECURE);
+ uint64_t actlr_elx;
/*
* Reset power state info for CPUs when onlining, we set
@@ -376,6 +356,10 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
* will re-init this info from non-secure software when the
* core come online.
*/
+ actlr_elx = read_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1));
+ actlr_elx &= ~DENVER_CPU_PMSTATE_MASK;
+ actlr_elx |= DENVER_CPU_PMSTATE_C1;
+ write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx));
/*
* Check if we are exiting from deep sleep and restore SE
@@ -434,24 +418,46 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_HOST_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_HOST);
+ assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+ XUSB_PADCTL_HOST_AXI_STREAMID_PF_0) == TEGRA_SID_XUSB_HOST);
mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_HOST_AXI_STREAMID_VF_0, TEGRA_SID_XUSB_VF0);
+ assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+ XUSB_PADCTL_HOST_AXI_STREAMID_VF_0) == TEGRA_SID_XUSB_VF0);
mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_HOST_AXI_STREAMID_VF_1, TEGRA_SID_XUSB_VF1);
+ assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+ XUSB_PADCTL_HOST_AXI_STREAMID_VF_1) == TEGRA_SID_XUSB_VF1);
mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_HOST_AXI_STREAMID_VF_2, TEGRA_SID_XUSB_VF2);
+ assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+ XUSB_PADCTL_HOST_AXI_STREAMID_VF_2) == TEGRA_SID_XUSB_VF2);
mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_HOST_AXI_STREAMID_VF_3, TEGRA_SID_XUSB_VF3);
+ assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+ XUSB_PADCTL_HOST_AXI_STREAMID_VF_3) == TEGRA_SID_XUSB_VF3);
mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV);
+ assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+ XUSB_PADCTL_DEV_AXI_STREAMID_PF_0) == TEGRA_SID_XUSB_DEV);
}
+ }
- /*
- * Reset power state info for the last core doing SC7
- * entry and exit, we set deepest power state as CC7
- * and SC7 for SC7 entry which may not be requested by
- * non-secure SW which controls idle states.
- */
+ /*
+ * Enable dual execution optimized translations for all ELx.
+ */
+ if (enable_ccplex_lock_step != 0U) {
+ actlr_elx = read_actlr_el3();
+ actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL3;
+ write_actlr_el3(actlr_elx);
+
+ actlr_elx = read_actlr_el2();
+ actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL2;
+ write_actlr_el2(actlr_elx);
+
+ actlr_elx = read_actlr_el1();
+ actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL1;
+ write_actlr_el1(actlr_elx);
}
return PSCI_E_SUCCESS;
diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c
new file mode 100644
index 000000000..0c4c6fad6
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_ras.c
@@ -0,0 +1,501 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <lib/bakery_lock.h>
+#include <lib/cassert.h>
+#include <lib/extensions/ras.h>
+#include <lib/utils_def.h>
+#include <services/sdei.h>
+
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <tegra194_ras_private.h>
+#include <tegra_def.h>
+#include <tegra_platform.h>
+#include <tegra_private.h>
+
+/*
+ * ERR<n>FR bits[63:32], it indicates supported RAS errors which can be enabled
+ * by setting corresponding bits in ERR<n>CTLR
+ */
+#define ERR_FR_EN_BITS_MASK 0xFFFFFFFF00000000ULL
+
+/*
+ * Number of RAS errors will be cleared per 'tegra194_ras_corrected_err_clear'
+ * function call.
+ */
+#define RAS_ERRORS_PER_CALL 8
+
+/*
+ * the max possible RAS node index value.
+ */
+#define RAS_NODE_INDEX_MAX 0x1FFFFFFFU
+
+/* bakery lock for platform RAS handler. */
+static DEFINE_BAKERY_LOCK(ras_handler_lock);
+#define ras_lock() bakery_lock_get(&ras_handler_lock)
+#define ras_unlock() bakery_lock_release(&ras_handler_lock)
+
+/*
+ * Function to handle an External Abort received at EL3.
+ * This function is invoked by RAS framework.
+ */
+static void tegra194_ea_handler(unsigned int ea_reason, uint64_t syndrome,
+ void *cookie, void *handle, uint64_t flags)
+{
+ int32_t ret;
+
+ ras_lock();
+
+ ERROR("MPIDR 0x%lx: exception reason=%u syndrome=0x%llx\n",
+ read_mpidr(), ea_reason, syndrome);
+
+ /* Call RAS EA handler */
+ ret = ras_ea_handler(ea_reason, syndrome, cookie, handle, flags);
+ if (ret != 0) {
+ ERROR("RAS error handled!\n");
+ ret = sdei_dispatch_event(TEGRA_SDEI_EP_EVENT_0 +
+ plat_my_core_pos());
+ if (ret != 0)
+ ERROR("sdei_dispatch_event returned %d\n", ret);
+ } else {
+ ERROR("Not a RAS error!\n");
+ }
+
+ ras_unlock();
+}
+
+/*
+ * Function to enable all supported RAS error report.
+ *
+ * Uncorrected errors are set to report as External abort (SError)
+ * Corrected errors are set to report as interrupt.
+ */
+void tegra194_ras_enable(void)
+{
+ VERBOSE("%s\n", __func__);
+
+ /* skip RAS enablement if not a silicon platform. */
+ if (!tegra_platform_is_silicon()) {
+ return;
+ }
+
+ /*
+ * Iterate for each group(num_idx ERRSELRs starting from idx_start)
+ * use normal for loop instead of for_each_err_record_info to get rid
+ * of MISRA noise..
+ */
+ for (uint32_t i = 0U; i < err_record_mappings.num_err_records; i++) {
+
+ const struct err_record_info *info = &err_record_mappings.err_records[i];
+
+ uint32_t idx_start = info->sysreg.idx_start;
+ uint32_t num_idx = info->sysreg.num_idx;
+ const struct ras_aux_data *aux_data = (const struct ras_aux_data *)info->aux_data;
+
+ assert(aux_data != NULL);
+
+ for (uint32_t j = 0; j < num_idx; j++) {
+
+ /* ERR<n>CTLR register value. */
+ uint64_t err_ctrl = 0ULL;
+ /* all supported errors for this node. */
+ uint64_t err_fr;
+ /* uncorrectable errors */
+ uint64_t uncorr_errs;
+ /* correctable errors */
+ uint64_t corr_errs;
+
+ /*
+ * Catch error if something wrong with the RAS aux data
+ * record table.
+ */
+ assert(aux_data[j].err_ctrl != NULL);
+
+ /*
+ * Write to ERRSELR_EL1 to select the RAS error node.
+ * Always program this at first to select corresponding
+ * RAS node before any other RAS register r/w.
+ */
+ ser_sys_select_record(idx_start + j);
+
+ err_fr = read_erxfr_el1() & ERR_FR_EN_BITS_MASK;
+ uncorr_errs = aux_data[j].err_ctrl();
+ corr_errs = ~uncorr_errs & err_fr;
+
+ /* enable error reporting */
+ ERR_CTLR_ENABLE_FIELD(err_ctrl, ED);
+
+ /* enable SError reporting for uncorrectable errors */
+ if ((uncorr_errs & err_fr) != 0ULL) {
+ ERR_CTLR_ENABLE_FIELD(err_ctrl, UE);
+ }
+
+ /* generate interrupt for corrected errors. */
+ if (corr_errs != 0ULL) {
+ ERR_CTLR_ENABLE_FIELD(err_ctrl, CFI);
+ }
+
+ /* enable the supported errors */
+ err_ctrl |= err_fr;
+
+ VERBOSE("errselr_el1:0x%x, erxfr:0x%llx, err_ctrl:0x%llx\n",
+ idx_start + j, err_fr, err_ctrl);
+
+ /* enable specified errors, or set to 0 if no supported error */
+ write_erxctlr_el1(err_ctrl);
+
+ /*
+ * Check if all the bit settings have been enabled to detect
+ * uncorrected/corrected errors, if not assert.
+ */
+ assert(read_erxctlr_el1() == err_ctrl);
+ }
+ }
+}
+
+/*
+ * Function to clear RAS ERR<n>STATUS for corrected RAS error.
+ *
+ * This function clears number of 'RAS_ERRORS_PER_CALL' RAS errors at most.
+ * 'cookie' - in/out cookie parameter to specify/store last visited RAS
+ * error record index. it is set to '0' to indicate no more RAS
+ * error record to clear.
+ */
+void tegra194_ras_corrected_err_clear(uint64_t *cookie)
+{
+ /*
+ * 'last_node' and 'last_idx' represent last visited RAS node index from
+ * previous function call. they are set to 0 when first smc call is made
+ * or all RAS error are visited by followed multipile smc calls.
+ */
+ union prev_record {
+ struct record {
+ uint32_t last_node;
+ uint32_t last_idx;
+ } rec;
+ uint64_t value;
+ } prev;
+
+ uint64_t clear_ce_status = 0ULL;
+ int32_t nerrs_per_call = RAS_ERRORS_PER_CALL;
+ uint32_t i;
+
+ if (cookie == NULL) {
+ return;
+ }
+
+ prev.value = *cookie;
+
+ if ((prev.rec.last_node >= RAS_NODE_INDEX_MAX) ||
+ (prev.rec.last_idx >= RAS_NODE_INDEX_MAX)) {
+ return;
+ }
+
+ ERR_STATUS_SET_FIELD(clear_ce_status, AV, 0x1UL);
+ ERR_STATUS_SET_FIELD(clear_ce_status, V, 0x1UL);
+ ERR_STATUS_SET_FIELD(clear_ce_status, OF, 0x1UL);
+ ERR_STATUS_SET_FIELD(clear_ce_status, MV, 0x1UL);
+ ERR_STATUS_SET_FIELD(clear_ce_status, CE, 0x3UL);
+
+
+ for (i = prev.rec.last_node; i < err_record_mappings.num_err_records; i++) {
+
+ const struct err_record_info *info = &err_record_mappings.err_records[i];
+ uint32_t idx_start = info->sysreg.idx_start;
+ uint32_t num_idx = info->sysreg.num_idx;
+
+ uint32_t j;
+
+ j = (i == prev.rec.last_node && prev.value != 0UL) ?
+ (prev.rec.last_idx + 1U) : 0U;
+
+ for (; j < num_idx; j++) {
+
+ uint64_t status;
+ uint32_t err_idx = idx_start + j;
+
+ if (err_idx >= RAS_NODE_INDEX_MAX) {
+ return;
+ }
+
+ write_errselr_el1(err_idx);
+ status = read_erxstatus_el1();
+
+ if (ERR_STATUS_GET_FIELD(status, CE) != 0U) {
+ write_erxstatus_el1(clear_ce_status);
+ }
+
+ --nerrs_per_call;
+
+ /* only clear 'nerrs_per_call' errors each time. */
+ if (nerrs_per_call <= 0) {
+ prev.rec.last_idx = j;
+ prev.rec.last_node = i;
+ /* save last visited error record index
+ * into cookie.
+ */
+ *cookie = prev.value;
+
+ return;
+ }
+ }
+ }
+
+ /*
+ * finish if all ras error records are checked or provided index is out
+ * of range.
+ */
+ *cookie = 0ULL;
+ return;
+}
+
+/* Function to probe an error from error record group. */
+static int32_t tegra194_ras_record_probe(const struct err_record_info *info,
+ int *probe_data)
+{
+ /* Skip probing if not a silicon platform */
+ if (!tegra_platform_is_silicon()) {
+ return 0;
+ }
+
+ return ser_probe_sysreg(info->sysreg.idx_start, info->sysreg.num_idx, probe_data);
+}
+
+/* Function to handle error from one given node */
+static int32_t tegra194_ras_node_handler(uint32_t errselr, const char *name,
+ const struct ras_error *errors, uint64_t status)
+{
+ bool found = false;
+ uint32_t ierr = (uint32_t)ERR_STATUS_GET_FIELD(status, IERR);
+ uint32_t serr = (uint32_t)ERR_STATUS_GET_FIELD(status, SERR);
+ uint64_t val = 0;
+
+ /* not a valid error. */
+ if (ERR_STATUS_GET_FIELD(status, V) == 0U) {
+ return 0;
+ }
+
+ ERR_STATUS_SET_FIELD(val, V, 1);
+
+ /* keep the log print same as linux arm64_ras driver. */
+ ERROR("**************************************\n");
+ ERROR("RAS Error in %s, ERRSELR_EL1=0x%x:\n", name, errselr);
+ ERROR("\tStatus = 0x%llx\n", status);
+
+ /* Print uncorrectable errror information. */
+ if (ERR_STATUS_GET_FIELD(status, UE) != 0U) {
+
+ ERR_STATUS_SET_FIELD(val, UE, 1);
+ ERR_STATUS_SET_FIELD(val, UET, 1);
+
+ /* IERR to error message */
+ for (uint32_t i = 0; errors[i].error_msg != NULL; i++) {
+ if (ierr == errors[i].error_code) {
+ ERROR("\tIERR = %s: 0x%x\n",
+ errors[i].error_msg, ierr);
+
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ ERROR("\tUnknown IERR: 0x%x\n", ierr);
+ }
+
+ ERROR("SERR = %s: 0x%x\n", ras_serr_to_str(serr), serr);
+
+ /* Overflow, multiple errors have been detected. */
+ if (ERR_STATUS_GET_FIELD(status, OF) != 0U) {
+ ERROR("\tOverflow (there may be more errors) - "
+ "Uncorrectable\n");
+ ERR_STATUS_SET_FIELD(val, OF, 1);
+ }
+
+ ERROR("\tUncorrectable (this is fatal)\n");
+
+ /* Miscellaneous Register Valid. */
+ if (ERR_STATUS_GET_FIELD(status, MV) != 0U) {
+ ERROR("\tMISC0 = 0x%lx\n", read_erxmisc0_el1());
+ ERROR("\tMISC1 = 0x%lx\n", read_erxmisc1_el1());
+ ERR_STATUS_SET_FIELD(val, MV, 1);
+ }
+
+ /* Address Valid. */
+ if (ERR_STATUS_GET_FIELD(status, AV) != 0U) {
+ ERROR("\tADDR = 0x%lx\n", read_erxaddr_el1());
+ ERR_STATUS_SET_FIELD(val, AV, 1);
+ }
+
+ /* Deferred error */
+ if (ERR_STATUS_GET_FIELD(status, DE) != 0U) {
+ ERROR("\tDeferred error\n");
+ ERR_STATUS_SET_FIELD(val, DE, 1);
+ }
+
+ } else {
+ /* For corrected error, simply clear it. */
+ VERBOSE("corrected RAS error is cleared: ERRSELR_EL1:0x%x, "
+ "IERR:0x%x, SERR:0x%x\n", errselr, ierr, serr);
+ ERR_STATUS_SET_FIELD(val, CE, 1);
+ }
+
+ ERROR("**************************************\n");
+
+ /* Write to clear reported errors. */
+ write_erxstatus_el1(val);
+
+ /* error handled */
+ return 0;
+}
+
+/* Function to handle one error node from an error record group. */
+static int32_t tegra194_ras_record_handler(const struct err_record_info *info,
+ int probe_data, const struct err_handler_data *const data __unused)
+{
+ uint32_t num_idx = info->sysreg.num_idx;
+ uint32_t idx_start = info->sysreg.idx_start;
+ const struct ras_aux_data *aux_data = info->aux_data;
+ const struct ras_error *errors;
+ uint32_t offset;
+ const char *node_name;
+
+ uint64_t status = 0ULL;
+
+ VERBOSE("%s\n", __func__);
+
+ assert(probe_data >= 0);
+ assert((uint32_t)probe_data < num_idx);
+
+ offset = (uint32_t)probe_data;
+ errors = aux_data[offset].error_records;
+ node_name = aux_data[offset].name;
+
+ assert(errors != NULL);
+
+ /* Write to ERRSELR_EL1 to select the error record */
+ ser_sys_select_record(idx_start + offset);
+
+ /* Retrieve status register from the error record */
+ status = read_erxstatus_el1();
+
+ return tegra194_ras_node_handler(idx_start + offset, node_name,
+ errors, status);
+}
+
+
+/* Instantiate RAS nodes */
+PER_CORE_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE)
+PER_CLUSTER_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE)
+SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE)
+CCPLEX_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE)
+
+/* Instantiate RAS node groups */
+static struct ras_aux_data per_core_ras_group[] = {
+ PER_CORE_RAS_GROUP_NODES
+};
+CASSERT(ARRAY_SIZE(per_core_ras_group) < RAS_NODE_INDEX_MAX,
+ assert_max_per_core_ras_group_size);
+
+static struct ras_aux_data per_cluster_ras_group[] = {
+ PER_CLUSTER_RAS_GROUP_NODES
+};
+CASSERT(ARRAY_SIZE(per_cluster_ras_group) < RAS_NODE_INDEX_MAX,
+ assert_max_per_cluster_ras_group_size);
+
+static struct ras_aux_data scf_l3_ras_group[] = {
+ SCF_L3_BANK_RAS_GROUP_NODES
+};
+CASSERT(ARRAY_SIZE(scf_l3_ras_group) < RAS_NODE_INDEX_MAX,
+ assert_max_scf_l3_ras_group_size);
+
+static struct ras_aux_data ccplex_ras_group[] = {
+ CCPLEX_RAS_GROUP_NODES
+};
+CASSERT(ARRAY_SIZE(ccplex_ras_group) < RAS_NODE_INDEX_MAX,
+ assert_max_ccplex_ras_group_size);
+
+/*
+ * We have same probe and handler for each error record group, use a macro to
+ * simply the record definition.
+ */
+#define ADD_ONE_ERR_GROUP(errselr_start, group) \
+ ERR_RECORD_SYSREG_V1((errselr_start), (uint32_t)ARRAY_SIZE((group)), \
+ &tegra194_ras_record_probe, \
+ &tegra194_ras_record_handler, (group))
+
+/* RAS error record group information */
+static struct err_record_info carmel_ras_records[] = {
+ /*
+ * Per core ras error records
+ * ERRSELR starts from 0*256 + Logical_CPU_ID*16 + 0 to
+ * 0*256 + Logical_CPU_ID*16 + 5 for each group.
+ * 8 cores/groups, 6 * 8 nodes in total.
+ */
+ ADD_ONE_ERR_GROUP(0x000, per_core_ras_group),
+ ADD_ONE_ERR_GROUP(0x010, per_core_ras_group),
+ ADD_ONE_ERR_GROUP(0x020, per_core_ras_group),
+ ADD_ONE_ERR_GROUP(0x030, per_core_ras_group),
+ ADD_ONE_ERR_GROUP(0x040, per_core_ras_group),
+ ADD_ONE_ERR_GROUP(0x050, per_core_ras_group),
+ ADD_ONE_ERR_GROUP(0x060, per_core_ras_group),
+ ADD_ONE_ERR_GROUP(0x070, per_core_ras_group),
+
+ /*
+ * Per cluster ras error records
+ * ERRSELR starts from 2*256 + Logical_Cluster_ID*16 + 0 to
+ * 2*256 + Logical_Cluster_ID*16 + 3.
+ * 4 clusters/groups, 3 * 4 nodes in total.
+ */
+ ADD_ONE_ERR_GROUP(0x200, per_cluster_ras_group),
+ ADD_ONE_ERR_GROUP(0x210, per_cluster_ras_group),
+ ADD_ONE_ERR_GROUP(0x220, per_cluster_ras_group),
+ ADD_ONE_ERR_GROUP(0x230, per_cluster_ras_group),
+
+ /*
+ * SCF L3_Bank ras error records
+ * ERRSELR: 3*256 + L3_Bank_ID, L3_Bank_ID: 0-3
+ * 1 groups, 4 nodes in total.
+ */
+ ADD_ONE_ERR_GROUP(0x300, scf_l3_ras_group),
+
+ /*
+ * CCPLEX ras error records
+ * ERRSELR: 4*256 + Unit_ID, Unit_ID: 0 - 4
+ * 1 groups, 5 nodes in total.
+ */
+ ADD_ONE_ERR_GROUP(0x400, ccplex_ras_group),
+};
+
+CASSERT(ARRAY_SIZE(carmel_ras_records) < RAS_NODE_INDEX_MAX,
+ assert_max_carmel_ras_records_size);
+
+REGISTER_ERR_RECORD_INFO(carmel_ras_records);
+
+/* dummy RAS interrupt */
+static struct ras_interrupt carmel_ras_interrupts[] = {};
+REGISTER_RAS_INTERRUPTS(carmel_ras_interrupts);
+
+/*******************************************************************************
+ * RAS handler for the platform
+ ******************************************************************************/
+void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
+ void *handle, uint64_t flags)
+{
+#if RAS_EXTENSION
+ tegra194_ea_handler(ea_reason, syndrome, cookie, handle, flags);
+#else
+ ERROR("Unhandled External Abort received on 0x%llx at EL3!\n",
+ read_mpidr_el1());
+ ERROR(" exception reason=%u syndrome=0x%lx\n", ea_reason, syndrome);
+ panic();
+#endif
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_secondary.c b/plat/nvidia/tegra/soc/t194/plat_secondary.c
index c397c91ba..1cb14add0 100644
--- a/plat/nvidia/tegra/soc/t194/plat_secondary.c
+++ b/plat/nvidia/tegra/soc/t194/plat_secondary.c
@@ -1,18 +1,23 @@
/*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+#include <string.h>
+
#include <arch_helpers.h>
#include <common/debug.h>
#include <lib/mmio.h>
+
#include <mce.h>
-#include <string.h>
#include <tegra194_private.h>
#include <tegra_def.h>
#include <tegra_private.h>
+extern uint64_t tegra_bl31_phys_base;
+
#define MISCREG_AA64_RST_LOW 0x2004U
#define MISCREG_AA64_RST_HIGH 0x2008U
@@ -25,10 +30,14 @@ void plat_secondary_setup(void)
{
uint32_t addr_low, addr_high;
plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
- uint64_t cpu_reset_handler_base, cpu_reset_handler_size;
+ uint64_t cpu_reset_handler_base, cpu_reset_handler_size, tzdram_addr;
+ uint64_t src_len_bytes = BL_END - tegra_bl31_phys_base;
INFO("Setting up secondary CPU boot\n");
+ tzdram_addr = params_from_bl2->tzdram_base +
+ tegra194_get_cpu_reset_handler_size();
+
/*
* The BL31 code resides in the TZSRAM which loses state
* when we enter System Suspend. Copy the wakeup trampoline
@@ -46,11 +55,21 @@ void plat_secondary_setup(void)
/* write lower 32 bits first, then the upper 11 bits */
mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low);
+ assert(mmio_read_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW) == addr_low);
mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high);
+ assert(mmio_read_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH) == addr_high);
/* save reset vector to be used during SYSTEM_SUSPEND exit */
mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO,
addr_low);
+ assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO) == addr_low);
mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI,
addr_high);
+ assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI) == addr_high);
+ mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO,
+ (uint32_t)tzdram_addr);
+ assert(mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO) == (uint32_t)tzdram_addr);
+ mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI,
+ (uint32_t)src_len_bytes);
+ assert(mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI) == (uint32_t)src_len_bytes);
}
diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c
index 912dcc6f9..8f7d1e9a1 100644
--- a/plat/nvidia/tegra/soc/t194/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t194/plat_setup.c
@@ -20,10 +20,11 @@
#include <bl31/interrupt_mgmt.h>
#include <mce.h>
#include <mce_private.h>
+#include <memctrl.h>
#include <plat/common/platform.h>
+#include <smmu.h>
#include <spe.h>
#include <tegra_def.h>
-#include <tegra_mc_def.h>
#include <tegra_platform.h>
#include <tegra_private.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
@@ -32,6 +33,27 @@
#define TEGRA_CONSOLE_SPE_ID 0xFE
/*******************************************************************************
+ * Structure to store the SCR addresses and its expected settings.
+ *******************************************************************************
+ */
+typedef struct {
+ uint32_t scr_addr;
+ uint32_t scr_val;
+} scr_settings_t;
+
+static const scr_settings_t t194_scr_settings[] = {
+ { SCRATCH_RSV68_SCR, SCRATCH_RSV68_SCR_VAL },
+ { SCRATCH_RSV71_SCR, SCRATCH_RSV71_SCR_VAL },
+ { SCRATCH_RSV72_SCR, SCRATCH_RSV72_SCR_VAL },
+ { SCRATCH_RSV75_SCR, SCRATCH_RSV75_SCR_VAL },
+ { SCRATCH_RSV81_SCR, SCRATCH_RSV81_SCR_VAL },
+ { SCRATCH_RSV97_SCR, SCRATCH_RSV97_SCR_VAL },
+ { SCRATCH_RSV99_SCR, SCRATCH_RSV99_SCR_VAL },
+ { SCRATCH_RSV109_SCR, SCRATCH_RSV109_SCR_VAL },
+ { MISCREG_SCR_SCRTZWELCK, MISCREG_SCR_SCRTZWELCK_VAL }
+};
+
+/*******************************************************************************
* The Tegra power domain tree has a single system level power domain i.e. a
* single root node. The first entry in the power domain descriptor specifies
* the number of power domains at the highest power level.
@@ -66,8 +88,6 @@ const uint8_t *plat_get_power_domain_tree_desc(void)
static const mmap_region_t tegra_mmap[] = {
MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x4000U, /* 16KB */
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
- MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000U, /* 128KB */
- (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
MAP_REGION_FLAT(TEGRA_GPCDMA_BASE, 0x10000U, /* 64KB */
(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x8000U, /* 32KB */
@@ -163,18 +183,18 @@ void plat_enable_console(int32_t id)
uint32_t console_clock = 0U;
#if ENABLE_CONSOLE_SPE
- static console_spe_t spe_console;
+ static console_t spe_console;
if (id == TEGRA_CONSOLE_SPE_ID) {
(void)console_spe_register(TEGRA_CONSOLE_SPE_BASE,
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&spe_console);
- console_set_scope(&spe_console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&spe_console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
#else
- static console_16550_t uart_console;
+ static console_t uart_console;
if ((id > 0) && (id < TEGRA194_MAX_UART_PORTS)) {
/*
@@ -190,20 +210,55 @@ void plat_enable_console(int32_t id)
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&uart_console);
- console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&uart_console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
#endif
}
/*******************************************************************************
+ * Verify SCR settings
+ ******************************************************************************/
+static inline bool tegra194_is_scr_valid(void)
+{
+ uint32_t scr_val;
+ bool ret = true;
+
+ for (uint8_t i = 0U; i < ARRAY_SIZE(t194_scr_settings); i++) {
+ scr_val = mmio_read_32((uintptr_t)t194_scr_settings[i].scr_addr);
+ if (scr_val != t194_scr_settings[i].scr_val) {
+ ERROR("Mismatch at SCR addr = 0x%x\n", t194_scr_settings[i].scr_addr);
+ ret = false;
+ }
+ }
+ return ret;
+}
+
+/*******************************************************************************
* Handler for early platform setup
******************************************************************************/
void plat_early_platform_setup(void)
{
+ const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+ uint8_t enable_ccplex_lock_step = params_from_bl2->enable_ccplex_lock_step;
+ uint64_t actlr_elx;
+
+ /* Verify chip id is t194 */
+ assert(tegra_chipid_is_t194());
+
+ /* Verify SCR settings */
+ if (tegra_platform_is_silicon()) {
+ assert(tegra194_is_scr_valid());
+ }
+
/* sanity check MCE firmware compatibility */
mce_verify_firmware_version();
+#if RAS_EXTENSION
+ /* Enable Uncorrectable RAS error */
+ tegra194_ras_enable();
+#endif
+
/*
* Program XUSB STREAMIDs
* ======================
@@ -239,24 +294,59 @@ void plat_early_platform_setup(void)
mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_HOST_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_HOST);
+ assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+ XUSB_PADCTL_HOST_AXI_STREAMID_PF_0) == TEGRA_SID_XUSB_HOST);
mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_HOST_AXI_STREAMID_VF_0, TEGRA_SID_XUSB_VF0);
+ assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+ XUSB_PADCTL_HOST_AXI_STREAMID_VF_0) == TEGRA_SID_XUSB_VF0);
mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_HOST_AXI_STREAMID_VF_1, TEGRA_SID_XUSB_VF1);
+ assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+ XUSB_PADCTL_HOST_AXI_STREAMID_VF_1) == TEGRA_SID_XUSB_VF1);
mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_HOST_AXI_STREAMID_VF_2, TEGRA_SID_XUSB_VF2);
+ assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+ XUSB_PADCTL_HOST_AXI_STREAMID_VF_2) == TEGRA_SID_XUSB_VF2);
mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_HOST_AXI_STREAMID_VF_3, TEGRA_SID_XUSB_VF3);
+ assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+ XUSB_PADCTL_HOST_AXI_STREAMID_VF_3) == TEGRA_SID_XUSB_VF3);
mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV);
+ assert(mmio_read_32(TEGRA_XUSB_PADCTL_BASE +
+ XUSB_PADCTL_DEV_AXI_STREAMID_PF_0) == TEGRA_SID_XUSB_DEV);
+ }
+
+ /*
+ * Enable dual execution optimized translations for all ELx.
+ */
+ if (enable_ccplex_lock_step != 0U) {
+ actlr_elx = read_actlr_el3();
+ actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL3;
+ write_actlr_el3(actlr_elx);
+ /* check if the bit is actually set */
+ assert((read_actlr_el3() & DENVER_CPU_ENABLE_DUAL_EXEC_EL3) != 0ULL);
+
+ actlr_elx = read_actlr_el2();
+ actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL2;
+ write_actlr_el2(actlr_elx);
+ /* check if the bit is actually set */
+ assert((read_actlr_el2() & DENVER_CPU_ENABLE_DUAL_EXEC_EL2) != 0ULL);
+
+ actlr_elx = read_actlr_el1();
+ actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL1;
+ write_actlr_el1(actlr_elx);
+ /* check if the bit is actually set */
+ assert((read_actlr_el1() & DENVER_CPU_ENABLE_DUAL_EXEC_EL1) != 0ULL);
}
}
/* Secure IRQs for Tegra194 */
static const interrupt_prop_t tegra194_interrupt_props[] = {
- INTR_PROP_DESC(TEGRA194_TOP_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
- INTR_PROP_DESC(TEGRA194_AON_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_PROP_DESC(TEGRA194_TOP_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE)
};
@@ -304,6 +394,9 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
return (plat_params_from_bl2_t *)(uintptr_t)val;
}
+/*******************************************************************************
+ * Handler for late platform setup
+ ******************************************************************************/
void plat_late_platform_setup(void)
{
#if ENABLE_STRICT_CHECKING_MODE
@@ -312,5 +405,45 @@ void plat_late_platform_setup(void)
* enabling TZSRAM and TZDRAM
*/
mce_enable_strict_checking();
+ mce_verify_strict_checking();
#endif
}
+
+/*******************************************************************************
+ * Handler to indicate support for System Suspend
+ ******************************************************************************/
+bool plat_supports_system_suspend(void)
+{
+ return true;
+}
+
+/*******************************************************************************
+ * Platform specific runtime setup.
+ ******************************************************************************/
+void plat_runtime_setup(void)
+{
+ /*
+ * During cold boot, it is observed that the arbitration
+ * bit is set in the Memory controller leading to false
+ * error interrupts in the non-secure world. To avoid
+ * this, clean the interrupt status register before
+ * booting into the non-secure world
+ */
+ tegra_memctrl_clear_pending_interrupts();
+
+ /*
+ * During boot, USB3 and flash media (SDMMC/SATA) devices need
+ * access to IRAM. Because these clients connect to the MC and
+ * do not have a direct path to the IRAM, the MC implements AHB
+ * redirection during boot to allow path to IRAM. In this mode
+ * accesses to a programmed memory address aperture are directed
+ * to the AHB bus, allowing access to the IRAM. This mode must be
+ * disabled before we jump to the non-secure world.
+ */
+ tegra_memctrl_disable_ahb_redirection();
+
+ /*
+ * Verify the integrity of the previously configured SMMU(s) settings
+ */
+ tegra_smmu_verify();
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
index 8873358cd..1eef55912 100644
--- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,18 +12,19 @@
#include <common/debug.h>
#include <errno.h>
#include <mce.h>
+#include <mce_private.h>
#include <memctrl.h>
#include <common/runtime_svc.h>
#include <tegra_private.h>
#include <tegra_platform.h>
+#include <smmu.h>
#include <stdbool.h>
-extern bool tegra_fake_system_suspend;
-
/*******************************************************************************
* Tegra194 SiP SMCs
******************************************************************************/
-#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND 0xC2FFFE03U
+#define TEGRA_SIP_GET_SMMU_PER 0xC200FF00U
+#define TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS 0xC200FF01U
/*******************************************************************************
* This function is responsible for handling all T194 SiP calls
@@ -37,26 +38,65 @@ int32_t plat_sip_handler(uint32_t smc_fid,
void *handle,
uint64_t flags)
{
- int32_t ret = -ENOTSUP;
+ int32_t ret = 0;
+ uint32_t i, smmu_per[6] = {0};
+ uint32_t num_smmu_devices = plat_get_num_smmu_devices();
+ uint64_t per[3] = {0ULL};
(void)x1;
(void)x4;
(void)cookie;
(void)flags;
- if (smc_fid == TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND) {
+ switch (smc_fid) {
+ case TEGRA_SIP_GET_SMMU_PER:
+
+ /* make sure we dont go past the array length */
+ assert(num_smmu_devices <= ARRAY_SIZE(smmu_per));
+
+ /* read all supported SMMU_PER records */
+ for (i = 0U; i < num_smmu_devices; i++) {
+ smmu_per[i] = tegra_smmu_read_32(i, SMMU_GSR0_PER);
+ }
+
+ /* pack results into 3 64bit variables. */
+ per[0] = smmu_per[0] | ((uint64_t)smmu_per[1] << 32U);
+ per[1] = smmu_per[2] | ((uint64_t)smmu_per[3] << 32U);
+ per[2] = smmu_per[4] | ((uint64_t)smmu_per[5] << 32U);
+
+ /* provide the results via X1-X3 CPU registers */
+ write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, per[0]);
+ write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X2, per[1]);
+ write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X3, per[2]);
+
+ break;
+
+#if RAS_EXTENSION
+ case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS:
+ {
/*
- * System suspend mode is set if the platform ATF is
- * running on VDK and there is a debug SIP call. This mode
- * ensures that the debug path is exercised, instead of
- * regular code path to suit the pre-silicon platform needs.
- * This includes replacing the call to WFI, with calls to
- * system suspend exit procedures.
- */
- if (tegra_platform_is_virt_dev_kit()) {
- tegra_fake_system_suspend = true;
- ret = 0;
+ * clear all RAS error records for corrected errors at first.
+ * x1 shall be 0 for first SMC call after FHI is asserted.
+ * */
+ uint64_t local_x1 = x1;
+
+ tegra194_ras_corrected_err_clear(&local_x1);
+ if (local_x1 == 0ULL) {
+ /* clear HSM corrected error status after all corrected
+ * RAS errors are cleared.
+ */
+ mce_clear_hsm_corr_status();
}
+
+ write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, local_x1);
+
+ break;
+ }
+#endif
+
+ default:
+ ret = -ENOTSUP;
+ break;
}
return ret;
diff --git a/plat/nvidia/tegra/soc/t194/plat_smmu.c b/plat/nvidia/tegra/soc/t194/plat_smmu.c
index 3b4a3803c..310e95104 100644
--- a/plat/nvidia/tegra/soc/t194/plat_smmu.c
+++ b/plat/nvidia/tegra/soc/t194/plat_smmu.c
@@ -8,7 +8,6 @@
#include <common/debug.h>
#include <smmu.h>
#include <tegra_def.h>
-#include <tegra_mc_def.h>
#define BOARD_SYSTEM_FPGA_BASE U(1)
#define BASE_CONFIG_SMMU_DEVICES U(2)
@@ -20,276 +19,6 @@ static uint32_t tegra_misc_read_32(uint32_t off)
}
/*******************************************************************************
- * Array to hold SMMU context for Tegra194
- ******************************************************************************/
-static __attribute__((aligned(16))) smmu_regs_t tegra194_smmu_context[] = {
- _START_OF_TABLE_,
- mc_make_sid_security_cfg(HDAR),
- mc_make_sid_security_cfg(HOST1XDMAR),
- mc_make_sid_security_cfg(NVENCSRD),
- mc_make_sid_security_cfg(SATAR),
- mc_make_sid_security_cfg(NVENCSWR),
- mc_make_sid_security_cfg(HDAW),
- mc_make_sid_security_cfg(SATAW),
- mc_make_sid_security_cfg(ISPRA),
- mc_make_sid_security_cfg(ISPFALR),
- mc_make_sid_security_cfg(ISPWA),
- mc_make_sid_security_cfg(ISPWB),
- mc_make_sid_security_cfg(XUSB_HOSTR),
- mc_make_sid_security_cfg(XUSB_HOSTW),
- mc_make_sid_security_cfg(XUSB_DEVR),
- mc_make_sid_security_cfg(XUSB_DEVW),
- mc_make_sid_security_cfg(TSECSRD),
- mc_make_sid_security_cfg(TSECSWR),
- mc_make_sid_security_cfg(SDMMCRA),
- mc_make_sid_security_cfg(SDMMCR),
- mc_make_sid_security_cfg(SDMMCRAB),
- mc_make_sid_security_cfg(SDMMCWA),
- mc_make_sid_security_cfg(SDMMCW),
- mc_make_sid_security_cfg(SDMMCWAB),
- mc_make_sid_security_cfg(VICSRD),
- mc_make_sid_security_cfg(VICSWR),
- mc_make_sid_security_cfg(VIW),
- mc_make_sid_security_cfg(NVDECSRD),
- mc_make_sid_security_cfg(NVDECSWR),
- mc_make_sid_security_cfg(APER),
- mc_make_sid_security_cfg(APEW),
- mc_make_sid_security_cfg(NVJPGSRD),
- mc_make_sid_security_cfg(NVJPGSWR),
- mc_make_sid_security_cfg(SESRD),
- mc_make_sid_security_cfg(SESWR),
- mc_make_sid_security_cfg(AXIAPR),
- mc_make_sid_security_cfg(AXIAPW),
- mc_make_sid_security_cfg(ETRR),
- mc_make_sid_security_cfg(ETRW),
- mc_make_sid_security_cfg(TSECSRDB),
- mc_make_sid_security_cfg(TSECSWRB),
- mc_make_sid_security_cfg(AXISR),
- mc_make_sid_security_cfg(AXISW),
- mc_make_sid_security_cfg(EQOSR),
- mc_make_sid_security_cfg(EQOSW),
- mc_make_sid_security_cfg(UFSHCR),
- mc_make_sid_security_cfg(UFSHCW),
- mc_make_sid_security_cfg(NVDISPLAYR),
- mc_make_sid_security_cfg(BPMPR),
- mc_make_sid_security_cfg(BPMPW),
- mc_make_sid_security_cfg(BPMPDMAR),
- mc_make_sid_security_cfg(BPMPDMAW),
- mc_make_sid_security_cfg(AONR),
- mc_make_sid_security_cfg(AONW),
- mc_make_sid_security_cfg(AONDMAR),
- mc_make_sid_security_cfg(AONDMAW),
- mc_make_sid_security_cfg(SCER),
- mc_make_sid_security_cfg(SCEW),
- mc_make_sid_security_cfg(SCEDMAR),
- mc_make_sid_security_cfg(SCEDMAW),
- mc_make_sid_security_cfg(APEDMAR),
- mc_make_sid_security_cfg(APEDMAW),
- mc_make_sid_security_cfg(NVDISPLAYR1),
- mc_make_sid_security_cfg(VICSRD1),
- mc_make_sid_security_cfg(NVDECSRD1),
- mc_make_sid_security_cfg(VIFALR),
- mc_make_sid_security_cfg(VIFALW),
- mc_make_sid_security_cfg(DLA0RDA),
- mc_make_sid_security_cfg(DLA0FALRDB),
- mc_make_sid_security_cfg(DLA0WRA),
- mc_make_sid_security_cfg(DLA0FALWRB),
- mc_make_sid_security_cfg(DLA1RDA),
- mc_make_sid_security_cfg(DLA1FALRDB),
- mc_make_sid_security_cfg(DLA1WRA),
- mc_make_sid_security_cfg(DLA1FALWRB),
- mc_make_sid_security_cfg(PVA0RDA),
- mc_make_sid_security_cfg(PVA0RDB),
- mc_make_sid_security_cfg(PVA0RDC),
- mc_make_sid_security_cfg(PVA0WRA),
- mc_make_sid_security_cfg(PVA0WRB),
- mc_make_sid_security_cfg(PVA0WRC),
- mc_make_sid_security_cfg(PVA1RDA),
- mc_make_sid_security_cfg(PVA1RDB),
- mc_make_sid_security_cfg(PVA1RDC),
- mc_make_sid_security_cfg(PVA1WRA),
- mc_make_sid_security_cfg(PVA1WRB),
- mc_make_sid_security_cfg(PVA1WRC),
- mc_make_sid_security_cfg(RCER),
- mc_make_sid_security_cfg(RCEW),
- mc_make_sid_security_cfg(RCEDMAR),
- mc_make_sid_security_cfg(RCEDMAW),
- mc_make_sid_security_cfg(NVENC1SRD),
- mc_make_sid_security_cfg(NVENC1SWR),
- mc_make_sid_security_cfg(PCIE0R),
- mc_make_sid_security_cfg(PCIE0W),
- mc_make_sid_security_cfg(PCIE1R),
- mc_make_sid_security_cfg(PCIE1W),
- mc_make_sid_security_cfg(PCIE2AR),
- mc_make_sid_security_cfg(PCIE2AW),
- mc_make_sid_security_cfg(PCIE3R),
- mc_make_sid_security_cfg(PCIE3W),
- mc_make_sid_security_cfg(PCIE4R),
- mc_make_sid_security_cfg(PCIE4W),
- mc_make_sid_security_cfg(PCIE5R),
- mc_make_sid_security_cfg(PCIE5W),
- mc_make_sid_security_cfg(ISPFALW),
- mc_make_sid_security_cfg(DLA0RDA1),
- mc_make_sid_security_cfg(DLA1RDA1),
- mc_make_sid_security_cfg(PVA0RDA1),
- mc_make_sid_security_cfg(PVA0RDB1),
- mc_make_sid_security_cfg(PVA1RDA1),
- mc_make_sid_security_cfg(PVA1RDB1),
- mc_make_sid_security_cfg(PCIE5R1),
- mc_make_sid_security_cfg(NVENCSRD1),
- mc_make_sid_security_cfg(NVENC1SRD1),
- mc_make_sid_security_cfg(ISPRA1),
- mc_make_sid_security_cfg(PCIE0R1),
- mc_make_sid_security_cfg(MIU0R),
- mc_make_sid_security_cfg(MIU0W),
- mc_make_sid_security_cfg(MIU1R),
- mc_make_sid_security_cfg(MIU1W),
- mc_make_sid_security_cfg(MIU2R),
- mc_make_sid_security_cfg(MIU2W),
- mc_make_sid_security_cfg(MIU3R),
- mc_make_sid_security_cfg(MIU3W),
- mc_make_sid_override_cfg(HDAR),
- mc_make_sid_override_cfg(HOST1XDMAR),
- mc_make_sid_override_cfg(NVENCSRD),
- mc_make_sid_override_cfg(SATAR),
- mc_make_sid_override_cfg(NVENCSWR),
- mc_make_sid_override_cfg(HDAW),
- mc_make_sid_override_cfg(SATAW),
- mc_make_sid_override_cfg(ISPRA),
- mc_make_sid_override_cfg(ISPFALR),
- mc_make_sid_override_cfg(ISPWA),
- mc_make_sid_override_cfg(ISPWB),
- mc_make_sid_override_cfg(XUSB_HOSTR),
- mc_make_sid_override_cfg(XUSB_HOSTW),
- mc_make_sid_override_cfg(XUSB_DEVR),
- mc_make_sid_override_cfg(XUSB_DEVW),
- mc_make_sid_override_cfg(TSECSRD),
- mc_make_sid_override_cfg(TSECSWR),
- mc_make_sid_override_cfg(SDMMCRA),
- mc_make_sid_override_cfg(SDMMCR),
- mc_make_sid_override_cfg(SDMMCRAB),
- mc_make_sid_override_cfg(SDMMCWA),
- mc_make_sid_override_cfg(SDMMCW),
- mc_make_sid_override_cfg(SDMMCWAB),
- mc_make_sid_override_cfg(VICSRD),
- mc_make_sid_override_cfg(VICSWR),
- mc_make_sid_override_cfg(VIW),
- mc_make_sid_override_cfg(NVDECSRD),
- mc_make_sid_override_cfg(NVDECSWR),
- mc_make_sid_override_cfg(APER),
- mc_make_sid_override_cfg(APEW),
- mc_make_sid_override_cfg(NVJPGSRD),
- mc_make_sid_override_cfg(NVJPGSWR),
- mc_make_sid_override_cfg(SESRD),
- mc_make_sid_override_cfg(SESWR),
- mc_make_sid_override_cfg(AXIAPR),
- mc_make_sid_override_cfg(AXIAPW),
- mc_make_sid_override_cfg(ETRR),
- mc_make_sid_override_cfg(ETRW),
- mc_make_sid_override_cfg(TSECSRDB),
- mc_make_sid_override_cfg(TSECSWRB),
- mc_make_sid_override_cfg(AXISR),
- mc_make_sid_override_cfg(AXISW),
- mc_make_sid_override_cfg(EQOSR),
- mc_make_sid_override_cfg(EQOSW),
- mc_make_sid_override_cfg(UFSHCR),
- mc_make_sid_override_cfg(UFSHCW),
- mc_make_sid_override_cfg(NVDISPLAYR),
- mc_make_sid_override_cfg(BPMPR),
- mc_make_sid_override_cfg(BPMPW),
- mc_make_sid_override_cfg(BPMPDMAR),
- mc_make_sid_override_cfg(BPMPDMAW),
- mc_make_sid_override_cfg(AONR),
- mc_make_sid_override_cfg(AONW),
- mc_make_sid_override_cfg(AONDMAR),
- mc_make_sid_override_cfg(AONDMAW),
- mc_make_sid_override_cfg(SCER),
- mc_make_sid_override_cfg(SCEW),
- mc_make_sid_override_cfg(SCEDMAR),
- mc_make_sid_override_cfg(SCEDMAW),
- mc_make_sid_override_cfg(APEDMAR),
- mc_make_sid_override_cfg(APEDMAW),
- mc_make_sid_override_cfg(NVDISPLAYR1),
- mc_make_sid_override_cfg(VICSRD1),
- mc_make_sid_override_cfg(NVDECSRD1),
- mc_make_sid_override_cfg(VIFALR),
- mc_make_sid_override_cfg(VIFALW),
- mc_make_sid_override_cfg(DLA0RDA),
- mc_make_sid_override_cfg(DLA0FALRDB),
- mc_make_sid_override_cfg(DLA0WRA),
- mc_make_sid_override_cfg(DLA0FALWRB),
- mc_make_sid_override_cfg(DLA1RDA),
- mc_make_sid_override_cfg(DLA1FALRDB),
- mc_make_sid_override_cfg(DLA1WRA),
- mc_make_sid_override_cfg(DLA1FALWRB),
- mc_make_sid_override_cfg(PVA0RDA),
- mc_make_sid_override_cfg(PVA0RDB),
- mc_make_sid_override_cfg(PVA0RDC),
- mc_make_sid_override_cfg(PVA0WRA),
- mc_make_sid_override_cfg(PVA0WRB),
- mc_make_sid_override_cfg(PVA0WRC),
- mc_make_sid_override_cfg(PVA1RDA),
- mc_make_sid_override_cfg(PVA1RDB),
- mc_make_sid_override_cfg(PVA1RDC),
- mc_make_sid_override_cfg(PVA1WRA),
- mc_make_sid_override_cfg(PVA1WRB),
- mc_make_sid_override_cfg(PVA1WRC),
- mc_make_sid_override_cfg(RCER),
- mc_make_sid_override_cfg(RCEW),
- mc_make_sid_override_cfg(RCEDMAR),
- mc_make_sid_override_cfg(RCEDMAW),
- mc_make_sid_override_cfg(NVENC1SRD),
- mc_make_sid_override_cfg(NVENC1SWR),
- mc_make_sid_override_cfg(PCIE0R),
- mc_make_sid_override_cfg(PCIE0W),
- mc_make_sid_override_cfg(PCIE1R),
- mc_make_sid_override_cfg(PCIE1W),
- mc_make_sid_override_cfg(PCIE2AR),
- mc_make_sid_override_cfg(PCIE2AW),
- mc_make_sid_override_cfg(PCIE3R),
- mc_make_sid_override_cfg(PCIE3W),
- mc_make_sid_override_cfg(PCIE4R),
- mc_make_sid_override_cfg(PCIE4W),
- mc_make_sid_override_cfg(PCIE5R),
- mc_make_sid_override_cfg(PCIE5W),
- mc_make_sid_override_cfg(ISPFALW),
- mc_make_sid_override_cfg(DLA0RDA1),
- mc_make_sid_override_cfg(DLA1RDA1),
- mc_make_sid_override_cfg(PVA0RDA1),
- mc_make_sid_override_cfg(PVA0RDB1),
- mc_make_sid_override_cfg(PVA1RDA1),
- mc_make_sid_override_cfg(PVA1RDB1),
- mc_make_sid_override_cfg(PCIE5R1),
- mc_make_sid_override_cfg(NVENCSRD1),
- mc_make_sid_override_cfg(NVENC1SRD1),
- mc_make_sid_override_cfg(ISPRA1),
- mc_make_sid_override_cfg(PCIE0R1),
- mc_make_sid_override_cfg(MIU0R),
- mc_make_sid_override_cfg(MIU0W),
- mc_make_sid_override_cfg(MIU1R),
- mc_make_sid_override_cfg(MIU1W),
- mc_make_sid_override_cfg(MIU2R),
- mc_make_sid_override_cfg(MIU2W),
- mc_make_sid_override_cfg(MIU3R),
- mc_make_sid_override_cfg(MIU3W),
- smmu_make_cfg(TEGRA_SMMU0_BASE),
- smmu_make_cfg(TEGRA_SMMU2_BASE),
- smmu_bypass_cfg, /* TBU settings */
- _END_OF_TABLE_,
-};
-
-/*******************************************************************************
- * Handler to return the pointer to the SMMU's context struct
- ******************************************************************************/
-smmu_regs_t *plat_get_smmu_ctx(void)
-{
- /* index of _END_OF_TABLE_ */
- tegra194_smmu_context[0].val = (uint32_t)ARRAY_SIZE(tegra194_smmu_context) - 1U;
-
- return tegra194_smmu_context;
-}
-
-/*******************************************************************************
* Handler to return the support SMMU devices number
******************************************************************************/
uint32_t plat_get_num_smmu_devices(void)
diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
index 540c2019c..0ff5407e3 100644
--- a/plat/nvidia/tegra/soc/t194/plat_trampoline.S
+++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
@@ -12,7 +12,7 @@
#define TEGRA194_STATE_SYSTEM_SUSPEND 0x5C7
#define TEGRA194_STATE_SYSTEM_RESUME 0x600D
-#define TEGRA194_SMMU_CTX_SIZE 0x80D
+#define TEGRA194_MC_CTX_SIZE 0xFB
.align 4
.globl tegra194_cpu_reset_handler
@@ -58,6 +58,13 @@ m_loop1:
subs x2, x2, #1
b.ne m_loop1
+ /*
+ * Synchronization barriers to make sure that memory is flushed out
+ * before we start execution in SysRAM.
+ */
+ dsb sy
+ isb
+
boot_cpu:
adr x0, __tegra194_cpu_reset_handler_data
ldr x0, [x0]
@@ -69,8 +76,8 @@ endfunc tegra194_cpu_reset_handler
*
* 0x0000: secure world's entrypoint
* 0x0008: BL31 size (RO + RW)
- * 0x0010: SMMU context start
- * 0x2490: SMMU context end
+ * 0x0010: MC context start
+ * 0x2490: MC context end
*/
.align 4
@@ -79,14 +86,13 @@ endfunc tegra194_cpu_reset_handler
__tegra194_cpu_reset_handler_data:
.quad tegra_secure_entrypoint
.quad __BL31_END__ - BL31_BASE
-
.globl __tegra194_system_suspend_state
__tegra194_system_suspend_state:
.quad 0
.align 4
-__tegra194_smmu_context:
- .rept TEGRA194_SMMU_CTX_SIZE
+__tegra194_mc_context:
+ .rept TEGRA194_MC_CTX_SIZE
.quad 0
.endr
.size __tegra194_cpu_reset_handler_data, \
@@ -98,7 +104,7 @@ __tegra194_cpu_reset_handler_end:
.globl tegra194_get_cpu_reset_handler_size
.globl tegra194_get_cpu_reset_handler_base
- .globl tegra194_get_smmu_ctx_offset
+ .globl tegra194_get_mc_ctx_offset
.globl tegra194_set_system_suspend_entry
/* return size of the CPU reset handler */
@@ -115,13 +121,13 @@ func tegra194_get_cpu_reset_handler_base
ret
endfunc tegra194_get_cpu_reset_handler_base
-/* return the size of the SMMU context */
-func tegra194_get_smmu_ctx_offset
- adr x0, __tegra194_smmu_context
+/* return the size of the MC context */
+func tegra194_get_mc_ctx_offset
+ adr x0, __tegra194_mc_context
adr x1, tegra194_cpu_reset_handler
sub x0, x0, x1
ret
-endfunc tegra194_get_smmu_ctx_offset
+endfunc tegra194_get_mc_ctx_offset
/* set system suspend state before SC7 entry */
func tegra194_set_system_suspend_entry
diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk
index 78766fcbe..339375f83 100644
--- a/plat/nvidia/tegra/soc/t194/platform_t194.mk
+++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk
@@ -24,28 +24,27 @@ COLD_BOOT_SINGLE_CPU := 1
TZDRAM_BASE := 0x40000000
$(eval $(call add_define,TZDRAM_BASE))
-PLATFORM_CLUSTER_COUNT := 4
-$(eval $(call add_define,PLATFORM_CLUSTER_COUNT))
-
-PLATFORM_MAX_CPUS_PER_CLUSTER := 2
-$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
-
MAX_XLAT_TABLES := 25
$(eval $(call add_define,MAX_XLAT_TABLES))
MAX_MMAP_REGIONS := 30
$(eval $(call add_define,MAX_MMAP_REGIONS))
+# enable RAS handling
+HANDLE_EA_EL3_FIRST := 1
+RAS_EXTENSION := 1
+
# platform files
-PLAT_INCLUDES += -I${SOC_DIR}/drivers/include
+PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t194 \
+ -I${SOC_DIR}/drivers/include
-BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
+BL31_SOURCES += ${TEGRA_GICv2_SOURCES} \
+ drivers/ti/uart/aarch64/16550_console.S \
lib/cpus/aarch64/denver.S \
- ${COMMON_DIR}/drivers/bpmp_ipc/intf.c \
- ${COMMON_DIR}/drivers/bpmp_ipc/ivc.c \
- ${COMMON_DIR}/drivers/gpcdma/gpcdma.c \
- ${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \
- ${COMMON_DIR}/drivers/smmu/smmu.c \
+ ${TEGRA_DRIVERS}/bpmp_ipc/intf.c \
+ ${TEGRA_DRIVERS}/bpmp_ipc/ivc.c \
+ ${TEGRA_DRIVERS}/memctrl/memctrl_v2.c \
+ ${TEGRA_DRIVERS}/smmu/smmu.c \
${SOC_DIR}/drivers/mce/mce.c \
${SOC_DIR}/drivers/mce/nvg.c \
${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \
@@ -58,6 +57,27 @@ BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
${SOC_DIR}/plat_smmu.c \
${SOC_DIR}/plat_trampoline.S
+ifeq (${USE_GPC_DMA}, 1)
+BL31_SOURCES += ${TEGRA_DRIVERS}/gpcdma/gpcdma.c
+endif
+
ifeq (${ENABLE_CONSOLE_SPE},1)
-BL31_SOURCES += ${COMMON_DIR}/drivers/spe/shared_console.S
+BL31_SOURCES += ${TEGRA_DRIVERS}/spe/shared_console.S
+endif
+
+# RAS sources
+ifeq (${RAS_EXTENSION},1)
+BL31_SOURCES += lib/extensions/ras/std_err_record.c \
+ lib/extensions/ras/ras_common.c \
+ ${SOC_DIR}/plat_ras.c
+endif
+
+# SPM dispatcher
+ifeq (${SPD},spmd)
+# include device tree helper library
+include lib/libfdt/libfdt.mk
+# sources to support spmd
+BL31_SOURCES += plat/common/plat_spmd_manifest.c \
+ common/fdt_wrappers.c \
+ ${LIBFDT_SRCS}
endif
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
index 352107d2c..c44b0fc46 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,6 +15,9 @@
* PMC registers
*/
+/* SC7 context save scratch register for T210 */
+#define PMC_SCRATCH43_REG_OFFSET U(0x22C)
+
/* Secure scratch registers */
#define PMC_SECURE_SCRATCH4_OFFSET 0xC0U
#define PMC_SECURE_SCRATCH5_OFFSET 0xC4U
@@ -435,6 +438,7 @@
((x) & ((0x1U) << SE_TZRAM_OP_REQ_SHIFT))
/* SE Interrupt */
+#define SE_INT_ENABLE_REG_OFFSET U(0xC)
#define SE_INT_STATUS_REG_OFFSET 0x10U
#define SE_INT_OP_DONE_SHIFT 4
#define SE_INT_OP_DONE_CLEAR \
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
index d5e049126..48608583d 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,8 +20,8 @@
* Constants and Macros
******************************************************************************/
-#define TIMEOUT_100MS 100U // Timeout in 100ms
-#define RNG_AES_KEY_INDEX 1
+#define TIMEOUT_100MS 100U /* Timeout in 100ms */
+#define RNG_AES_KEY_INDEX 1
/*******************************************************************************
* Data structure and global variables
@@ -68,14 +68,12 @@
* #--------------------------------#
*/
-/* Known pattern data */
-static const uint32_t se_ctx_known_pattern_data[SE_CTX_KNOWN_PATTERN_SIZE_WORDS] = {
+/* Known pattern data for T210 */
+static const uint8_t se_ctx_known_pattern_data[SE_CTX_KNOWN_PATTERN_SIZE] = {
/* 128 bit AES block */
- 0x0C0D0E0F,
- 0x08090A0B,
- 0x04050607,
- 0x00010203,
-};
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+ };
/* SE input and output linked list buffers */
static tegra_se_io_lst_t se1_src_ll_buf;
@@ -85,6 +83,9 @@ static tegra_se_io_lst_t se1_dst_ll_buf;
static tegra_se_io_lst_t se2_src_ll_buf;
static tegra_se_io_lst_t se2_dst_ll_buf;
+/* SE1 context buffer, 132 blocks */
+static __aligned(64) uint8_t se1_ctx_buf[SE_CTX_DRBG_BUFER_SIZE];
+
/* SE1 security engine device handle */
static tegra_se_dev_t se_dev_1 = {
.se_num = 1,
@@ -97,10 +98,10 @@ static tegra_se_dev_t se_dev_1 = {
/* Setup DST buffers for SE operations */
.dst_ll_buf = &se1_dst_ll_buf,
/* Setup context save destination */
- .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE),
+ .ctx_save_buf = (uint32_t *)&se1_ctx_buf
};
-/* SE2 security engine device handle */
+/* SE2 security engine device handle (T210B01 only) */
static tegra_se_dev_t se_dev_2 = {
.se_num = 2,
/* Setup base address for se */
@@ -112,7 +113,7 @@ static tegra_se_dev_t se_dev_2 = {
/* Setup DST buffers for SE operations */
.dst_ll_buf = &se2_dst_ll_buf,
/* Setup context save destination */
- .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE + 0x1000),
+ .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE + 0x1000)
};
static bool ecid_valid;
@@ -202,18 +203,6 @@ static int32_t tegra_se_operation_complete(const tegra_se_dev_t *se_dev)
}
/*
- * Returns true if the SE engine is configured to perform SE context save in
- * hardware.
- */
-static inline bool tegra_se_atomic_save_enabled(const tegra_se_dev_t *se_dev)
-{
- uint32_t val;
-
- val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
- return (SE_CTX_SAVE_AUTO_ENABLE(val) == SE_CTX_SAVE_AUTO_EN);
-}
-
-/*
* Wait for SE engine to be idle and clear pending interrupts before
* starting the next SE operation.
*/
@@ -223,6 +212,9 @@ static int32_t tegra_se_operation_prepare(const tegra_se_dev_t *se_dev)
uint32_t val = 0;
uint32_t timeout;
+ /* disable SE interrupt to prevent interrupt issued by SE operation */
+ tegra_se_write_32(se_dev, SE_INT_ENABLE_REG_OFFSET, 0U);
+
/* Wait for previous operation to finish */
val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
for (timeout = 0; (val != 0U) && (timeout < TIMEOUT_100MS); timeout++) {
@@ -629,19 +621,19 @@ static int tegra_se_lp_rsakeytable_context_save(tegra_se_dev_t *se_dev)
{
uint32_t val = 0;
int ret = 0;
- /* First the modulus and then the exponent must be
+ /* For T210, First the modulus and then exponent must be
* encrypted and saved. This is repeated for SLOT 0
* and SLOT 1. Hence the order:
- * SLOT 0 exponent : RSA_KEY_INDEX : 0
* SLOT 0 modulus : RSA_KEY_INDEX : 1
- * SLOT 1 exponent : RSA_KEY_INDEX : 2
+ * SLOT 0 exponent : RSA_KEY_INDEX : 0
* SLOT 1 modulus : RSA_KEY_INDEX : 3
+ * SLOT 1 exponent : RSA_KEY_INDEX : 2
*/
const unsigned int key_index_mod[TEGRA_SE_RSA_KEYSLOT_COUNT][2] = {
/* RSA key slot 0 */
- {SE_RSA_KEY_INDEX_SLOT0_EXP, SE_RSA_KEY_INDEX_SLOT0_MOD},
+ {SE_RSA_KEY_INDEX_SLOT0_MOD, SE_RSA_KEY_INDEX_SLOT0_EXP},
/* RSA key slot 1 */
- {SE_RSA_KEY_INDEX_SLOT1_EXP, SE_RSA_KEY_INDEX_SLOT1_MOD},
+ {SE_RSA_KEY_INDEX_SLOT1_MOD, SE_RSA_KEY_INDEX_SLOT1_EXP},
};
se_dev->dst_ll_buf->last_buff_num = 0;
@@ -876,8 +868,8 @@ static int tegra_se_context_save_sw(tegra_se_dev_t *se_dev)
/* Write lp context buffer address into PMC scratch register */
if (se_dev->se_num == 1) {
- /* SE context address */
- mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SECURE_SCRATCH117_OFFSET,
+ /* SE context address, support T210 only */
+ mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SCRATCH43_REG_OFFSET,
((uint64_t)(se_dev->ctx_save_buf)));
} else if (se_dev->se_num == 2) {
/* SE2 & PKA1 context address */
@@ -909,7 +901,10 @@ void tegra_se_init(void)
/* Generate random SRK to initialize DRBG */
tegra_se_generate_srk(&se_dev_1);
- tegra_se_generate_srk(&se_dev_2);
+
+ if (tegra_chipid_is_t210_b01()) {
+ tegra_se_generate_srk(&se_dev_2);
+ }
/* determine if ECID is valid */
val = mmio_read_32(TEGRA_FUSE_BASE + FUSE_JTAG_SECUREID_VALID);
@@ -932,6 +927,13 @@ static void tegra_se_enable_clocks(void)
val &= ~ENTROPY_RESET_BIT;
mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W, val);
+ /*
+ * Switch SE clock source to CLK_M, to make sure SE clock
+ * is on when saving SE context
+ */
+ mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_RST_CTL_CLK_SRC_SE,
+ SE_CLK_SRC_CLK_M);
+
/* Enable SE clock */
val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V);
val |= SE_CLK_ENB_BIT;
@@ -975,43 +977,25 @@ int32_t tegra_se_suspend(void)
tegra_se_enable_clocks();
- if (tegra_se_atomic_save_enabled(&se_dev_2) &&
- tegra_se_atomic_save_enabled(&se_dev_1)) {
- /* Atomic context save se2 and pka1 */
+ if (tegra_chipid_is_t210_b01()) {
+ /* It is T210 B01, Atomic context save se2 and pka1 */
INFO("%s: SE2/PKA1 atomic context save\n", __func__);
- if (ret == 0) {
- ret = tegra_se_context_save_atomic(&se_dev_2);
- }
-
- /* Atomic context save se */
- if (ret == 0) {
- INFO("%s: SE1 atomic context save\n", __func__);
- ret = tegra_se_context_save_atomic(&se_dev_1);
+ ret = tegra_se_context_save_atomic(&se_dev_2);
+ if (ret != 0) {
+ ERROR("%s: SE2 ctx save failed (%d)\n", __func__, ret);
}
- if (ret == 0) {
- INFO("%s: SE atomic context save done\n", __func__);
- }
- } else if (!tegra_se_atomic_save_enabled(&se_dev_2) &&
- !tegra_se_atomic_save_enabled(&se_dev_1)) {
- /* SW context save se2 and pka1 */
- INFO("%s: SE2/PKA1 legacy(SW) context save\n", __func__);
- if (ret == 0) {
- ret = tegra_se_context_save_sw(&se_dev_2);
- }
-
- /* SW context save se */
- if (ret == 0) {
- INFO("%s: SE1 legacy(SW) context save\n", __func__);
- ret = tegra_se_context_save_sw(&se_dev_1);
- }
-
- if (ret == 0) {
- INFO("%s: SE SW context save done\n", __func__);
+ ret = tegra_se_context_save_atomic(&se_dev_1);
+ if (ret != 0) {
+ ERROR("%s: SE1 ctx save failed (%d)\n", __func__, ret);
}
} else {
- ERROR("%s: One SE set for atomic CTX save, the other is not\n",
- __func__);
+ /* It is T210, SW context save se */
+ INFO("%s: SE1 legacy(SW) context save\n", __func__);
+ ret = tegra_se_context_save_sw(&se_dev_1);
+ if (ret != 0) {
+ ERROR("%s: SE1 ctx save failed (%d)\n", __func__, ret);
+ }
}
tegra_se_disable_clocks();
@@ -1080,5 +1064,8 @@ static void tegra_se_warm_boot_resume(const tegra_se_dev_t *se_dev)
void tegra_se_resume(void)
{
tegra_se_warm_boot_resume(&se_dev_1);
- tegra_se_warm_boot_resume(&se_dev_2);
+
+ if (tegra_chipid_is_t210_b01()) {
+ tegra_se_warm_boot_resume(&se_dev_2);
+ }
}
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 12241c2f3..7f73ea506 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -184,6 +185,12 @@ plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
return target;
}
+int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
+{
+ (void)cpu_state;
+ return PSCI_E_SUCCESS;
+}
+
int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
u_register_t mpidr = read_mpidr();
@@ -203,12 +210,9 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
assert((stateid_afflvl1 == PLAT_MAX_OFF_STATE) ||
(stateid_afflvl1 == PSTATE_ID_SOC_POWERDN));
- if (tegra_chipid_is_t210_b01()) {
-
- /* Suspend se/se2 and pka1 */
- if (tegra_se_suspend() != 0) {
- ret = PSCI_E_INTERN_FAIL;
- }
+ /* Suspend se/se2 and pka1 for T210 B01 and se for T210 */
+ if (tegra_se_suspend() != 0) {
+ ret = PSCI_E_INTERN_FAIL;
}
} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) {
@@ -387,6 +391,15 @@ int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
*/
tegra_reset_all_dma_masters();
+ /*
+ * Mark PMC as accessible to the non-secure world
+ * to allow the COP to execute System Suspend
+ * sequence
+ */
+ val = mmio_read_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE);
+ val &= ~PMC_SECURITY_EN_BIT;
+ mmio_write_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE, val);
+
/* clean up IRAM of any cruft */
zeromem((void *)(uintptr_t)TEGRA_IRAM_BASE,
TEGRA_IRAM_A_SIZE);
@@ -412,6 +425,11 @@ int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
return PSCI_E_SUCCESS;
}
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+ return PSCI_E_NOT_SUPPORTED;
+}
+
int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
@@ -468,12 +486,14 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
tegra_bpmp_resume();
}
- /* sc7entry-fw is part of TZDRAM area */
if (plat_params->sc7entry_fw_base != 0U) {
+ /* sc7entry-fw is part of TZDRAM area */
offset = plat_params->tzdram_base - plat_params->sc7entry_fw_base;
tegra_memctrl_tzdram_setup(plat_params->sc7entry_fw_base,
plat_params->tzdram_size + offset);
+ }
+ if (!tegra_chipid_is_t210_b01()) {
/* restrict PMC access to secure world */
val = mmio_read_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE);
val |= PMC_SECURITY_EN_BIT;
@@ -514,6 +534,13 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
}
/*
+ * Mark this CPU as ON in the cpu_powergate_mask[],
+ * so that we use Flow Controller for all subsequent
+ * power ups.
+ */
+ cpu_powergate_mask[plat_my_core_pos()] = 1;
+
+ /*
* T210 has a dedicated ARMv7 boot and power mgmt processor, BPMP. It's
* used for power management and boot purposes. Inform the BPMP that
* we have completed the cluster power up.
@@ -521,10 +548,11 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
tegra_fc_lock_active_cluster();
/*
- * Resume PMC hardware block for Tegra210 platforms supporting sc7entry-fw
- */
- if (!tegra_chipid_is_t210_b01() && (plat_params->sc7entry_fw_base != 0U))
+ * Resume PMC hardware block for Tegra210 platforms
+ */
+ if (!tegra_chipid_is_t210_b01()) {
tegra_pmc_resume();
+ }
return PSCI_E_SUCCESS;
}
@@ -540,7 +568,6 @@ int tegra_soc_pwr_domain_on(u_register_t mpidr)
/* Turn on CPU using flow controller or PMC */
if (cpu_powergate_mask[cpu] == 0) {
tegra_pmc_cpu_on(cpu);
- cpu_powergate_mask[cpu] = 1;
} else {
tegra_fc_cpu_on(cpu);
}
@@ -567,5 +594,16 @@ int tegra_soc_prepare_system_reset(void)
/* Wait 1 ms to make sure clock source/device logic is stabilized. */
mdelay(1);
+ /*
+ * Program the PMC in order to restart the system.
+ */
+ tegra_pmc_system_reset();
+
return PSCI_E_SUCCESS;
}
+
+__dead2 void tegra_soc_prepare_system_off(void)
+{
+ ERROR("Tegra System Off: operation not handled.\n");
+ panic();
+}
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index bfa818419..68cd38ec3 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -118,7 +119,7 @@ static uint32_t tegra210_uart_addresses[TEGRA210_MAX_UART_PORTS + 1] = {
******************************************************************************/
void plat_enable_console(int32_t id)
{
- static console_16550_t uart_console;
+ static console_t uart_console;
uint32_t console_clock;
if ((id > 0) && (id < TEGRA210_MAX_UART_PORTS)) {
@@ -135,12 +136,28 @@ void plat_enable_console(int32_t id)
console_clock,
TEGRA_CONSOLE_BAUDRATE,
&uart_console);
- console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&uart_console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
}
}
/*******************************************************************************
+ * Return pointer to the BL31 params from previous bootloader
+ ******************************************************************************/
+struct tegra_bl31_params *plat_get_bl31_params(void)
+{
+ return NULL;
+}
+
+/*******************************************************************************
+ * Return pointer to the BL31 platform params from previous bootloader
+ ******************************************************************************/
+plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
+{
+ return NULL;
+}
+
+/*******************************************************************************
* Handler for early platform setup
******************************************************************************/
void plat_early_platform_setup(void)
@@ -148,6 +165,15 @@ void plat_early_platform_setup(void)
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
uint64_t val;
+ /* Verify chip id is t210 */
+ assert(tegra_chipid_is_t210());
+
+ /*
+ * Do initial security configuration to allow DRAM/device access.
+ */
+ tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
+ (uint32_t)plat_params->tzdram_size);
+
/* platform parameter passed by the previous bootloader */
if (plat_params->l2_ecc_parity_prot_dis != 1) {
/* Enable ECC Parity Protection for Cortex-A57 CPUs */
@@ -157,17 +183,22 @@ void plat_early_platform_setup(void)
}
/* Initialize security engine driver */
- if (tegra_chipid_is_t210_b01()) {
- tegra_se_init();
- }
+ tegra_se_init();
}
/* Secure IRQs for Tegra186 */
static const interrupt_prop_t tegra210_interrupt_props[] = {
- INTR_PROP_DESC(TEGRA210_WDT_CPU_LEGACY_FIQ, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(TEGRA210_TIMER1_IRQ, PLAT_TEGRA_WDT_PRIO,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(TEGRA210_WDT_CPU_LEGACY_FIQ, PLAT_TEGRA_WDT_PRIO,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
};
+/*******************************************************************************
+ * Handler for late platform setup
+ ******************************************************************************/
void plat_late_platform_setup(void)
{
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
@@ -216,6 +247,13 @@ void plat_late_platform_setup(void)
val |= PMC_SECURITY_EN_BIT;
mmio_write_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE, val);
}
+
+ if (!tegra_chipid_is_t210_b01()) {
+ /* restrict PMC access to secure world */
+ val = mmio_read_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE);
+ val |= PMC_SECURITY_EN_BIT;
+ mmio_write_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE, val);
+ }
}
/*******************************************************************************
@@ -235,3 +273,46 @@ void plat_gic_setup(void)
*/
tegra_fc_enable_fiq_to_ccplex_routing();
}
+/*******************************************************************************
+ * Handler to indicate support for System Suspend
+ ******************************************************************************/
+bool plat_supports_system_suspend(void)
+{
+ const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+
+ /*
+ * sc7entry-fw is only supported by Tegra210 SoCs.
+ */
+ if (!tegra_chipid_is_t210_b01() && (plat_params->sc7entry_fw_base != 0U)) {
+ return true;
+ } else if (tegra_chipid_is_t210_b01()) {
+ return true;
+ } else {
+ return false;
+ }
+}
+/*******************************************************************************
+ * Platform specific runtime setup.
+ ******************************************************************************/
+void plat_runtime_setup(void)
+{
+ /*
+ * During cold boot, it is observed that the arbitration
+ * bit is set in the Memory controller leading to false
+ * error interrupts in the non-secure world. To avoid
+ * this, clean the interrupt status register before
+ * booting into the non-secure world
+ */
+ tegra_memctrl_clear_pending_interrupts();
+
+ /*
+ * During boot, USB3 and flash media (SDMMC/SATA) devices need
+ * access to IRAM. Because these clients connect to the MC and
+ * do not have a direct path to the IRAM, the MC implements AHB
+ * redirection during boot to allow path to IRAM. In this mode
+ * accesses to a programmed memory address aperture are directed
+ * to the AHB bus, allowing access to the IRAM. This mode must be
+ * disabled before we jump to the non-secure world.
+ */
+ tegra_memctrl_disable_ahb_redirection();
+}
diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
index 7e0f5c1d8..904f8d62e 100644
--- a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -50,24 +51,32 @@ int plat_sip_handler(uint32_t smc_fid,
if (!ns)
SMC_RET1(handle, SMC_UNK);
- switch (smc_fid) {
- case TEGRA_SIP_PMC_COMMANDS:
-
+ if (smc_fid == TEGRA_SIP_PMC_COMMANDS) {
/* check the address is within PMC range and is 4byte aligned */
if ((x2 >= TEGRA_PMC_SIZE) || (x2 & 0x3))
return -EINVAL;
- /* pmc_secure_scratch registers are not accessible */
- if (((x2 >= PMC_SECURE_SCRATCH0) && (x2 <= PMC_SECURE_SCRATCH5)) ||
- ((x2 >= PMC_SECURE_SCRATCH6) && (x2 <= PMC_SECURE_SCRATCH7)) ||
- ((x2 >= PMC_SECURE_SCRATCH8) && (x2 <= PMC_SECURE_SCRATCH79)) ||
- ((x2 >= PMC_SECURE_SCRATCH80) && (x2 <= PMC_SECURE_SCRATCH119)))
- return -EFAULT;
-
+ switch (x2) {
+ /* Black listed PMC registers */
+ case PMC_SCRATCH1:
+ case PMC_SCRATCH31 ... PMC_SCRATCH33:
+ case PMC_SCRATCH40:
+ case PMC_SCRATCH42:
+ case PMC_SCRATCH43 ... PMC_SCRATCH48:
+ case PMC_SCRATCH50 ... PMC_SCRATCH51:
+ case PMC_SCRATCH56 ... PMC_SCRATCH57:
/* PMC secure-only registers are not accessible */
- if ((x2 == PMC_DPD_ENABLE_0) || (x2 == PMC_FUSE_CONTROL_0) ||
- (x2 == PMC_CRYPTO_OP_0))
+ case PMC_DPD_ENABLE_0:
+ case PMC_FUSE_CONTROL_0:
+ case PMC_CRYPTO_OP_0:
+ case PMC_TSC_MULT_0:
+ case PMC_STICKY_BIT:
+ ERROR("%s: error offset=0x%llx\n", __func__, x2);
return -EFAULT;
+ default:
+ /* Valid register */
+ break;
+ }
/* Perform PMC read/write */
if (x1 == PMC_READ) {
@@ -78,13 +87,8 @@ int plat_sip_handler(uint32_t smc_fid,
} else {
return -EINVAL;
}
-
- break;
-
- default:
- ERROR("%s: unsupported function ID\n", __func__);
+ } else {
return -ENOTSUP;
}
-
return 0;
}
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index a11aef4dd..724cfc3c0 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -1,5 +1,6 @@
#
# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -22,21 +23,23 @@ $(eval $(call add_define,MAX_XLAT_TABLES))
MAX_MMAP_REGIONS := 16
$(eval $(call add_define,MAX_MMAP_REGIONS))
-ENABLE_WDT_LEGACY_FIQ_HANDLING := 1
-$(eval $(call add_define,ENABLE_WDT_LEGACY_FIQ_HANDLING))
+ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING := 1
-PLAT_INCLUDES += -I${SOC_DIR}/drivers/se
+PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t210 \
+ -I${SOC_DIR}/drivers/se
-BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
+BL31_SOURCES += ${TEGRA_GICv2_SOURCES} \
+ drivers/ti/uart/aarch64/16550_console.S \
lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a57.S \
- ${COMMON_DIR}/drivers/bpmp/bpmp.c \
- ${COMMON_DIR}/drivers/flowctrl/flowctrl.c \
- ${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \
+ ${TEGRA_DRIVERS}/bpmp/bpmp.c \
+ ${TEGRA_DRIVERS}/flowctrl/flowctrl.c \
+ ${TEGRA_DRIVERS}/memctrl/memctrl_v1.c \
+ ${TEGRA_DRIVERS}/pmc/pmc.c \
${SOC_DIR}/plat_psci_handlers.c \
${SOC_DIR}/plat_setup.c \
${SOC_DIR}/drivers/se/security_engine.c \
- ${SOC_DIR}/plat_secondary.c \
+ ${SOC_DIR}/plat_secondary.c \
${SOC_DIR}/plat_sip_calls.c
# Enable workarounds for selected Cortex-A57 erratas.
@@ -44,7 +47,6 @@ A57_DISABLE_NON_TEMPORAL_HINT := 1
ERRATA_A57_826974 := 1
ERRATA_A57_826977 := 1
ERRATA_A57_828024 := 1
-ERRATA_A57_829520 := 1
ERRATA_A57_833471 := 1
# Enable workarounds for selected Cortex-A53 erratas.
@@ -55,3 +57,6 @@ ERRATA_A53_855873 := 1
# Skip L1 $ flush when powering down Cortex-A57 CPUs
SKIP_A57_L1_FLUSH_PWR_DWN := 1
+
+# Enable higher performance Non-cacheable load forwarding
+A57_ENABLE_NONCACHEABLE_LOAD_FWD := 1
diff --git a/plat/nxp/common/plat_make_helper/plat_build_macros.mk b/plat/nxp/common/plat_make_helper/plat_build_macros.mk
new file mode 100644
index 000000000..bba5e36ff
--- /dev/null
+++ b/plat/nxp/common/plat_make_helper/plat_build_macros.mk
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2020, NXP.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+
+define SET_NXP_MAKE_FLAG
+$1 := yes
+$2_$1 := yes
+endef
diff --git a/plat/qemu/common/aarch32/plat_helpers.S b/plat/qemu/common/aarch32/plat_helpers.S
index 15e860b42..5e346d585 100644
--- a/plat/qemu/common/aarch32/plat_helpers.S
+++ b/plat/qemu/common/aarch32/plat_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -125,10 +125,10 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush(int c)
+ * void plat_crash_console_flush(int c)
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : x0, x1
* ---------------------------------------------
*/
diff --git a/plat/qemu/common/aarch64/plat_helpers.S b/plat/qemu/common/aarch64/plat_helpers.S
index dbcdc2d39..08b281735 100644
--- a/plat/qemu/common/aarch64/plat_helpers.S
+++ b/plat/qemu/common/aarch64/plat_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,7 +32,8 @@ endfunc plat_my_core_pos
func plat_qemu_calc_core_pos
and x1, x0, #MPIDR_CPU_MASK
and x0, x0, #MPIDR_CLUSTER_MASK
- add x0, x1, x0, LSR #6
+ add x0, x1, x0, LSR #(MPIDR_AFFINITY_BITS -\
+ PLATFORM_CPU_PER_CLUSTER_SHIFT)
ret
endfunc plat_qemu_calc_core_pos
@@ -121,10 +122,10 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush(int c)
+ * void plat_crash_console_flush(int c)
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : x0, x1
* ---------------------------------------------
*/
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index 365cfb7f0..47ec79114 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -1,5 +1,6 @@
+
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,7 +26,7 @@
#ifdef DEVICE2_BASE
#define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \
DEVICE2_SIZE, \
- MT_DEVICE | MT_RO | MT_SECURE)
+ MT_DEVICE | MT_RW | MT_SECURE)
#endif
#define MAP_SHARED_RAM MAP_REGION_FLAT(SHARED_RAM_BASE, \
@@ -77,7 +78,11 @@ static const mmap_region_t plat_qemu_mmap[] = {
MAP_DEVICE2,
#endif
MAP_NS_DRAM0,
+#if SPM_MM
+ QEMU_SP_IMAGE_MMAP,
+#else
MAP_BL32_MEM,
+#endif
{0}
};
#endif
@@ -88,7 +93,15 @@ static const mmap_region_t plat_qemu_mmap[] = {
#ifdef MAP_DEVICE1
MAP_DEVICE1,
#endif
+#ifdef MAP_DEVICE2
+ MAP_DEVICE2,
+#endif
+#if SPM_MM
+ MAP_NS_DRAM0,
+ QEMU_SPM_BUF_EL3_MMAP,
+#else
MAP_BL32_MEM,
+#endif
{0}
};
#endif
@@ -99,6 +112,9 @@ static const mmap_region_t plat_qemu_mmap[] = {
#ifdef MAP_DEVICE1
MAP_DEVICE1,
#endif
+#ifdef MAP_DEVICE2
+ MAP_DEVICE2,
+#endif
{0}
};
#endif
diff --git a/plat/qemu/common/qemu_console.c b/plat/qemu/common/qemu_console.c
index fec182892..1f00f8a72 100644
--- a/plat/qemu/common/qemu_console.c
+++ b/plat/qemu/common/qemu_console.c
@@ -9,7 +9,7 @@
#include <drivers/console.h>
#include <drivers/arm/pl011.h>
-static console_pl011_t console;
+static console_t console;
void qemu_console_init(void)
{
@@ -17,7 +17,7 @@ void qemu_console_init(void)
PLAT_QEMU_BOOT_UART_CLK_IN_HZ,
PLAT_QEMU_CONSOLE_BAUDRATE, &console);
- console_set_scope(&console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME);
}
diff --git a/plat/qemu/common/qemu_io_storage.c b/plat/qemu/common/qemu_io_storage.c
index 0e81cd199..1107e443f 100644
--- a/plat/qemu/common/qemu_io_storage.c
+++ b/plat/qemu/common/qemu_io_storage.c
@@ -12,6 +12,7 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/io/io_driver.h>
+#include <drivers/io/io_encrypted.h>
#include <drivers/io/io_fip.h>
#include <drivers/io/io_memmap.h>
#include <drivers/io/io_semihosting.h>
@@ -47,6 +48,10 @@ static const io_dev_connector_t *memmap_dev_con;
static uintptr_t memmap_dev_handle;
static const io_dev_connector_t *sh_dev_con;
static uintptr_t sh_dev_handle;
+#ifndef DECRYPTION_SUPPORT_none
+static const io_dev_connector_t *enc_dev_con;
+static uintptr_t enc_dev_handle;
+#endif
static const io_block_spec_t fip_block_spec = {
.offset = PLAT_QEMU_FIP_BASE,
@@ -172,10 +177,11 @@ static const io_file_spec_t sh_file_spec[] = {
#endif /* TRUSTED_BOARD_BOOT */
};
-
-
static int open_fip(const uintptr_t spec);
static int open_memmap(const uintptr_t spec);
+#ifndef DECRYPTION_SUPPORT_none
+static int open_enc_fip(const uintptr_t spec);
+#endif
struct plat_io_policy {
uintptr_t *dev_handle;
@@ -190,16 +196,46 @@ static const struct plat_io_policy policies[] = {
(uintptr_t)&fip_block_spec,
open_memmap
},
+ [ENC_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)NULL,
+ open_fip
+ },
[BL2_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl2_uuid_spec,
open_fip
},
+#if ENCRYPT_BL31 && !defined(DECRYPTION_SUPPORT_none)
+ [BL31_IMAGE_ID] = {
+ &enc_dev_handle,
+ (uintptr_t)&bl31_uuid_spec,
+ open_enc_fip
+ },
+#else
[BL31_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl31_uuid_spec,
open_fip
},
+#endif
+#if ENCRYPT_BL32 && !defined(DECRYPTION_SUPPORT_none)
+ [BL32_IMAGE_ID] = {
+ &enc_dev_handle,
+ (uintptr_t)&bl32_uuid_spec,
+ open_enc_fip
+ },
+ [BL32_EXTRA1_IMAGE_ID] = {
+ &enc_dev_handle,
+ (uintptr_t)&bl32_extra1_uuid_spec,
+ open_enc_fip
+ },
+ [BL32_EXTRA2_IMAGE_ID] = {
+ &enc_dev_handle,
+ (uintptr_t)&bl32_extra2_uuid_spec,
+ open_enc_fip
+ },
+#else
[BL32_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl32_uuid_spec,
@@ -215,6 +251,7 @@ static const struct plat_io_policy policies[] = {
(uintptr_t)&bl32_extra2_uuid_spec,
open_fip
},
+#endif
[BL33_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl33_uuid_spec,
@@ -271,7 +308,7 @@ static int open_fip(const uintptr_t spec)
/* See if a Firmware Image Package is available */
result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
- if (result == 0) {
+ if (result == 0 && spec != (uintptr_t)NULL) {
result = io_open(fip_dev_handle, spec, &local_image_handle);
if (result == 0) {
VERBOSE("Using FIP\n");
@@ -281,6 +318,25 @@ static int open_fip(const uintptr_t spec)
return result;
}
+#ifndef DECRYPTION_SUPPORT_none
+static int open_enc_fip(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ /* See if an encrypted FIP is available */
+ result = io_dev_init(enc_dev_handle, (uintptr_t)ENC_IMAGE_ID);
+ if (result == 0) {
+ result = io_open(enc_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using encrypted FIP\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+#endif
+
static int open_memmap(const uintptr_t spec)
{
int result;
@@ -333,6 +389,15 @@ void plat_qemu_io_setup(void)
&memmap_dev_handle);
assert(io_result == 0);
+#ifndef DECRYPTION_SUPPORT_none
+ io_result = register_io_dev_enc(&enc_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(enc_dev_con, (uintptr_t)NULL,
+ &enc_dev_handle);
+ assert(io_result == 0);
+#endif
+
/* Register the additional IO devices on this platform */
io_result = register_io_dev_sh(&sh_dev_con);
assert(io_result == 0);
diff --git a/plat/qemu/common/qemu_spm.c b/plat/qemu/common/qemu_spm.c
new file mode 100644
index 000000000..93dd2b37d
--- /dev/null
+++ b/plat/qemu/common/qemu_spm.c
@@ -0,0 +1,138 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2020, Linaro Limited and Contributors. All rights reserved.
+ */
+
+#include <libfdt.h>
+
+#include <bl31/ehf.h>
+#include <common/debug.h>
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <services/spm_mm_partition.h>
+
+#include <platform_def.h>
+
+/* Region equivalent to MAP_DEVICE1 suitable for mapping at EL0 */
+#define MAP_DEVICE1_EL0 MAP_REGION_FLAT(DEVICE1_BASE, \
+ DEVICE1_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+mmap_region_t plat_qemu_secure_partition_mmap[] = {
+ QEMU_SP_IMAGE_NS_BUF_MMAP, /* must be placed at first entry */
+ MAP_DEVICE1_EL0, /* for the UART */
+ QEMU_SP_IMAGE_MMAP,
+ QEMU_SPM_BUF_EL0_MMAP,
+ QEMU_SP_IMAGE_RW_MMAP,
+ MAP_SECURE_VARSTORE,
+ {0}
+};
+
+/*
+ * Boot information passed to a secure partition during initialisation.
+ * Linear indices in MP information will be filled at runtime.
+ */
+static spm_mm_mp_info_t sp_mp_info[] = {
+ [0] = {0x80000000, 0},
+ [1] = {0x80000001, 0},
+ [2] = {0x80000002, 0},
+ [3] = {0x80000003, 0},
+ [4] = {0x80000004, 0},
+ [5] = {0x80000005, 0},
+ [6] = {0x80000006, 0},
+ [7] = {0x80000007, 0}
+};
+
+spm_mm_boot_info_t plat_qemu_secure_partition_boot_info = {
+ .h.type = PARAM_SP_IMAGE_BOOT_INFO,
+ .h.version = VERSION_1,
+ .h.size = sizeof(spm_mm_boot_info_t),
+ .h.attr = 0,
+ .sp_mem_base = PLAT_QEMU_SP_IMAGE_BASE,
+ .sp_mem_limit = BL32_LIMIT,
+ .sp_image_base = PLAT_QEMU_SP_IMAGE_BASE,
+ .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE,
+ .sp_heap_base = PLAT_QEMU_SP_IMAGE_HEAP_BASE,
+ .sp_ns_comm_buf_base = PLAT_QEMU_SP_IMAGE_NS_BUF_BASE,
+ .sp_shared_buf_base = PLAT_SPM_BUF_BASE,
+ .sp_image_size = PLAT_QEMU_SP_IMAGE_SIZE,
+ .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
+ .sp_heap_size = PLAT_QEMU_SP_IMAGE_HEAP_SIZE,
+ .sp_ns_comm_buf_size = PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE,
+ .sp_shared_buf_size = PLAT_SPM_BUF_SIZE,
+ .num_sp_mem_regions = PLAT_QEMU_SP_IMAGE_NUM_MEM_REGIONS,
+ .num_cpus = PLATFORM_CORE_COUNT,
+ .mp_info = sp_mp_info
+};
+
+/* Enumeration of priority levels on QEMU platforms. */
+ehf_pri_desc_t qemu_exceptions[] = {
+ EHF_PRI_DESC(QEMU_PRI_BITS, PLAT_SP_PRI)
+};
+
+int dt_add_ns_buf_node(uintptr_t *base)
+{
+ uintptr_t addr;
+ size_t size;
+ uintptr_t ns_buf_addr;
+ int node;
+ int err;
+ void *fdt = (void *)ARM_PRELOADED_DTB_BASE;
+
+ err = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE);
+ if (err < 0) {
+ ERROR("Invalid Device Tree at %p: error %d\n", fdt, err);
+ return err;
+ }
+
+ /*
+ * reserved-memory for standaloneMM non-secure buffer
+ * is allocated at the top of the first system memory region.
+ */
+ node = fdt_path_offset(fdt, "/memory");
+
+ err = fdt_get_reg_props_by_index(fdt, node, 0, &addr, &size);
+ if (err < 0) {
+ ERROR("Failed to get the memory node information\n");
+ return err;
+ }
+ INFO("System RAM @ 0x%lx - 0x%lx\n", addr, addr + size - 1);
+
+ ns_buf_addr = addr + (size - PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE);
+ INFO("reserved-memory for spm-mm @ 0x%lx - 0x%llx\n", ns_buf_addr,
+ ns_buf_addr + PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE - 1);
+
+ err = fdt_add_reserved_memory(fdt, "ns-buf-spm-mm", ns_buf_addr,
+ PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE);
+ if (err < 0) {
+ ERROR("Failed to add the reserved-memory node\n");
+ return err;
+ }
+
+ *base = ns_buf_addr;
+ return 0;
+}
+
+/* Plug in QEMU exceptions to Exception Handling Framework. */
+EHF_REGISTER_PRIORITIES(qemu_exceptions, ARRAY_SIZE(qemu_exceptions),
+ QEMU_PRI_BITS);
+
+const mmap_region_t *plat_get_secure_partition_mmap(void *cookie)
+{
+ uintptr_t ns_buf_base;
+
+ dt_add_ns_buf_node(&ns_buf_base);
+
+ plat_qemu_secure_partition_mmap[0].base_pa = ns_buf_base;
+ plat_qemu_secure_partition_mmap[0].base_va = ns_buf_base;
+ plat_qemu_secure_partition_boot_info.sp_ns_comm_buf_base = ns_buf_base;
+
+ return plat_qemu_secure_partition_mmap;
+}
+
+const spm_mm_boot_info_t *
+plat_get_secure_partition_boot_info(void *cookie)
+{
+ return &plat_qemu_secure_partition_boot_info;
+}
diff --git a/plat/qemu/common/qemu_stack_protector.c b/plat/qemu/common/qemu_stack_protector.c
index c226158ad..15ce3d6d2 100644
--- a/plat/qemu/common/qemu_stack_protector.c
+++ b/plat/qemu/common/qemu_stack_protector.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,17 +7,25 @@
#include <stdint.h>
#include <arch_helpers.h>
+#include <arch_features.h>
#include <plat/common/platform.h>
#define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL)
u_register_t plat_get_stack_protector_canary(void)
{
+#if ENABLE_FEAT_RNG
+ /* Use the RNDR instruction if the CPU supports it */
+ if (is_armv8_5_rng_present()) {
+ return read_rndr();
+ }
+#endif
+
/*
- * Ideally, a random number should be returned instead of the
+ * Ideally, a random number should be returned above. If a random
+ * number generator is not supported, return instead a
* combination of a timer's value and a compile-time constant.
- * As the virt platform does not have any random number generator,
- * this is better than nothing but not necessarily really secure.
+ * This is better than nothing but not necessarily really secure.
*/
return RANDOM_CANARY_VALUE ^ read_cntpct_el0();
}
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index cce992ff9..e6bb1e6a9 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -24,6 +24,14 @@
#define PLATFORM_CLUSTER1_CORE_COUNT U(0)
#else
#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4)
+/*
+ * Define the number of cores per cluster used in calculating core position.
+ * The cluster number is shifted by this value and added to the core ID,
+ * so its value represents log2(cores/cluster).
+ * Default is 2**(2) = 4 cores per cluster.
+ */
+#define PLATFORM_CPU_PER_CLUSTER_SHIFT U(2)
+
#define PLATFORM_CLUSTER_COUNT U(2)
#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER
#define PLATFORM_CLUSTER1_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER
@@ -172,7 +180,7 @@
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#define MAX_MMAP_REGIONS 11
#define MAX_XLAT_TABLES 6
-#define MAX_IO_DEVICES 3
+#define MAX_IO_DEVICES 4
#define MAX_IO_HANDLES 4
/*
@@ -196,8 +204,8 @@
#define QEMU_FLASH1_BASE 0x04000000
#define QEMU_FLASH1_SIZE 0x04000000
-#define PLAT_QEMU_FIP_BASE QEMU_FLASH1_BASE
-#define PLAT_QEMU_FIP_MAX_SIZE QEMU_FLASH1_SIZE
+#define PLAT_QEMU_FIP_BASE 0x00040000
+#define PLAT_QEMU_FIP_MAX_SIZE 0x00400000
#define DEVICE0_BASE 0x08000000
#define DEVICE0_SIZE 0x01000000
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index b95bf5a51..14bf049be 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -15,6 +15,7 @@ ifeq (${ARM_ARCH_MAJOR},7)
MARCH32_DIRECTIVE := -mcpu=cortex-a15
$(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING))
$(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER))
+$(eval $(call add_define,ARMV7_SUPPORTS_VFP))
# Qemu expects a BL32 boot stage.
NEED_BL32 := yes
endif # ARMv7
@@ -58,18 +59,20 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
AUTH_SOURCES := drivers/auth/auth_mod.c \
drivers/auth/crypto_mod.c \
drivers/auth/img_parser_mod.c \
- drivers/auth/tbbr/tbbr_cot.c
+ drivers/auth/tbbr/tbbr_cot_common.c
BL1_SOURCES += ${AUTH_SOURCES} \
bl1/tbbr/tbbr_img_desc.c \
plat/common/tbbr/plat_tbbr.c \
${PLAT_QEMU_COMMON_PATH}/qemu_trusted_boot.c \
- $(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S
+ $(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S \
+ drivers/auth/tbbr/tbbr_cot_bl1.c
BL2_SOURCES += ${AUTH_SOURCES} \
plat/common/tbbr/plat_tbbr.c \
${PLAT_QEMU_COMMON_PATH}/qemu_trusted_boot.c \
- $(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S
+ $(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S \
+ drivers/auth/tbbr/tbbr_cot_bl2.c
ROT_KEY = $(BUILD_PLAT)/rot_key.pem
ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
@@ -81,7 +84,7 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
certificates: $(ROT_KEY)
- $(ROT_KEY):
+ $(ROT_KEY): | $(BUILD_PLAT)
@echo " OPENSSL $@"
$(Q)openssl genrsa 2048 > $@ 2>/dev/null
@@ -127,15 +130,21 @@ ifeq ($(add-lib-optee),yes)
BL2_SOURCES += lib/optee/optee_utils.c
endif
+ifneq (${DECRYPTION_SUPPORT},none)
+BL1_SOURCES += drivers/io/io_encrypted.c
+BL2_SOURCES += drivers/io/io_encrypted.c
+endif
+
QEMU_GICV2_SOURCES := drivers/arm/gic/v2/gicv2_helpers.c \
drivers/arm/gic/v2/gicv2_main.c \
drivers/arm/gic/common/gic_common.c \
plat/common/plat_gicv2.c \
${PLAT_QEMU_COMMON_PATH}/qemu_gicv2.c
-QEMU_GICV3_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/common/gic_common.c \
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+QEMU_GICV3_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
${PLAT_QEMU_COMMON_PATH}/qemu_gicv3.c
@@ -164,11 +173,19 @@ endif
# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
# in the FIP if the platform requires.
ifneq ($(BL32_EXTRA1),)
+ifneq (${DECRYPTION_SUPPORT},none)
+$(eval $(call TOOL_ADD_IMG,bl32_extra1,--tos-fw-extra1,,$(ENCRYPT_BL32)))
+else
$(eval $(call TOOL_ADD_IMG,bl32_extra1,--tos-fw-extra1))
endif
+endif
ifneq ($(BL32_EXTRA2),)
+ifneq (${DECRYPTION_SUPPORT},none)
+$(eval $(call TOOL_ADD_IMG,bl32_extra2,--tos-fw-extra2,,$(ENCRYPT_BL32)))
+else
$(eval $(call TOOL_ADD_IMG,bl32_extra2,--tos-fw-extra2))
endif
+endif
SEPARATE_CODE_AND_RODATA := 1
ENABLE_STACK_PROTECTOR := 0
diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h
index f44b9f6e0..b69c2ebef 100644
--- a/plat/qemu/qemu_sbsa/include/platform_def.h
+++ b/plat/qemu/qemu_sbsa/include/platform_def.h
@@ -1,10 +1,11 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright (c) 2019, Linaro Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, Linaro Limited and Contributors.
+ * All rights reserved.
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <arch.h>
#include <plat/common/common_def.h>
@@ -15,13 +16,17 @@
#define PLATFORM_STACK_SIZE 0x1000
-#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4)
-#define PLATFORM_CLUSTER_COUNT U(2)
-#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER
-#define PLATFORM_CLUSTER1_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER
-#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \
- PLATFORM_CLUSTER1_CORE_COUNT)
-
+#define PLATFORM_MAX_CPUS_PER_CLUSTER U(8)
+/*
+ * Define the number of cores per cluster used in calculating core position.
+ * The cluster number is shifted by this value and added to the core ID,
+ * so its value represents log2(cores/cluster).
+ * Default is 2**(3) = 8 cores per cluster.
+ */
+#define PLATFORM_CPU_PER_CLUSTER_SHIFT U(3)
+#define PLATFORM_CLUSTER_COUNT U(64)
+#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \
+ PLATFORM_MAX_CPUS_PER_CLUSTER)
#define QEMU_PRIMARY_CPU U(0)
#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \
@@ -84,7 +89,7 @@
*/
#define SHARED_RAM_BASE SEC_SRAM_BASE
-#define SHARED_RAM_SIZE 0x00001000
+#define SHARED_RAM_SIZE 0x00002000
#define PLAT_QEMU_TRUSTED_MAILBOX_BASE SHARED_RAM_BASE
#define PLAT_QEMU_TRUSTED_MAILBOX_SIZE (8 + PLAT_QEMU_HOLD_SIZE)
@@ -107,9 +112,10 @@
* Put BL1 RW at the top of the Secure SRAM. BL1_RW_BASE is calculated using
* the current BL1 RW debug size plus a little space for growth.
*/
+#define BL1_SIZE 0x12000
#define BL1_RO_BASE SEC_ROM_BASE
#define BL1_RO_LIMIT (SEC_ROM_BASE + SEC_ROM_SIZE)
-#define BL1_RW_BASE (BL1_RW_LIMIT - 0x12000)
+#define BL1_RW_BASE (BL1_RW_LIMIT - BL1_SIZE)
#define BL1_RW_LIMIT (BL_RAM_BASE + BL_RAM_SIZE)
/*
@@ -118,7 +124,8 @@
* Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
* size plus a little space for growth.
*/
-#define BL2_BASE (BL31_BASE - 0x1D000)
+#define BL2_SIZE 0x1D000
+#define BL2_BASE (BL31_BASE - BL2_SIZE)
#define BL2_LIMIT BL31_BASE
/*
@@ -127,8 +134,9 @@
* Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
* current BL3-1 debug size plus a little space for growth.
*/
-#define BL31_BASE (BL31_LIMIT - 0x20000)
-#define BL31_LIMIT (BL_RAM_BASE + BL_RAM_SIZE)
+#define BL31_SIZE 0x300000
+#define BL31_BASE (BL31_LIMIT - BL31_SIZE)
+#define BL31_LIMIT (BL1_RW_BASE)
#define BL31_PROGBITS_LIMIT BL1_RW_BASE
@@ -138,12 +146,11 @@
* BL3-2 can execute from Secure SRAM, or Secure DRAM.
*/
#define BL32_SRAM_BASE BL_RAM_BASE
-#define BL32_SRAM_LIMIT BL31_BASE
-#define BL32_DRAM_BASE SEC_DRAM_BASE
-#define BL32_DRAM_LIMIT (SEC_DRAM_BASE + SEC_DRAM_SIZE)
+#define BL32_SRAM_LIMIT BL2_BASE
#define BL32_MEM_BASE BL_RAM_BASE
-#define BL32_MEM_SIZE BL_RAM_SIZE
+#define BL32_MEM_SIZE (BL_RAM_SIZE - BL1_SIZE - \
+ BL2_SIZE - BL31_SIZE)
#define BL32_BASE BL32_SRAM_BASE
#define BL32_LIMIT BL32_SRAM_LIMIT
@@ -152,11 +159,21 @@
#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 42)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 42)
+#if SPM_MM
+#define MAX_MMAP_REGIONS 12
+#define MAX_XLAT_TABLES 12
+#else
#define MAX_MMAP_REGIONS 11
-#define MAX_XLAT_TABLES 10
+#define MAX_XLAT_TABLES 11
+#endif
#define MAX_IO_DEVICES 3
#define MAX_IO_HANDLES 4
+#if SPM_MM && defined(IMAGE_BL31)
+# define PLAT_SP_IMAGE_MMAP_REGIONS 30
+# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 20
+#endif
+
/*
* PL011 related constants
*/
@@ -165,6 +182,10 @@
#define UART0_CLK_IN_HZ 1
#define UART1_CLK_IN_HZ 1
+/* Secure UART */
+#define UART2_BASE 0x60040000
+#define UART2_CLK_IN_HZ 1
+
#define PLAT_QEMU_BOOT_UART_BASE UART0_BASE
#define PLAT_QEMU_BOOT_UART_CLK_IN_HZ UART0_CLK_IN_HZ
@@ -179,14 +200,17 @@
#define QEMU_FLASH1_SIZE 0x10000000
#define PLAT_QEMU_FIP_BASE 0x00008000
-#define PLAT_QEMU_FIP_MAX_SIZE 0x00020000
+#define PLAT_QEMU_FIP_MAX_SIZE 0x00400000
/* This is map from GIC_DIST up to last CPU (255) GIC_REDISTR */
#define DEVICE0_BASE 0x40000000
#define DEVICE0_SIZE 0x04080000
/* This is map from NORMAL_UART up to SECURE_UART_MM */
#define DEVICE1_BASE 0x60000000
-#define DEVICE1_SIZE 0x00041000
+#define DEVICE1_SIZE 0x10041000
+/* This is a map for SECURE_EC */
+#define DEVICE2_BASE 0x50000000
+#define DEVICE2_SIZE 0x00001000
/*
* GIC related constants
@@ -233,11 +257,122 @@
* DT related constants
*/
#define PLAT_QEMU_DT_BASE NS_DRAM0_BASE
-#define PLAT_QEMU_DT_MAX_SIZE 0x10000
+#define PLAT_QEMU_DT_MAX_SIZE 0x100000
/*
* System counter
*/
#define SYS_COUNTER_FREQ_IN_TICKS ((1000 * 1000 * 1000) / 16)
-#endif /* __PLATFORM_DEF_H__ */
+#if SPM_MM
+#define PLAT_QEMU_SP_IMAGE_BASE BL_RAM_BASE
+#define PLAT_QEMU_SP_IMAGE_SIZE ULL(0x300000)
+
+#ifdef IMAGE_BL2
+/* In BL2 all memory allocated to the SPM Payload image is marked as RW. */
+# define QEMU_SP_IMAGE_MMAP MAP_REGION_FLAT( \
+ PLAT_QEMU_SP_IMAGE_BASE, \
+ PLAT_QEMU_SP_IMAGE_SIZE, \
+ MT_MEMORY | MT_RW | \
+ MT_SECURE)
+#elif IMAGE_BL31
+/* All SPM Payload memory is marked as code in S-EL0 */
+# define QEMU_SP_IMAGE_MMAP MAP_REGION2(PLAT_QEMU_SP_IMAGE_BASE, \
+ PLAT_QEMU_SP_IMAGE_BASE, \
+ PLAT_QEMU_SP_IMAGE_SIZE, \
+ MT_CODE | MT_SECURE | \
+ MT_USER, \
+ PAGE_SIZE)
+#endif
+
+/*
+ * EL3 -> S-EL0 secure shared memory
+ */
+#define PLAT_SPM_BUF_PCPU_SIZE ULL(0x10000)
+#define PLAT_SPM_BUF_SIZE (PLATFORM_CORE_COUNT * \
+ PLAT_SPM_BUF_PCPU_SIZE)
+#define PLAT_SPM_BUF_BASE (BL32_LIMIT - PLAT_SPM_BUF_SIZE)
+
+#define QEMU_SPM_BUF_EL3_MMAP MAP_REGION_FLAT(PLAT_SPM_BUF_BASE, \
+ PLAT_SPM_BUF_SIZE, \
+ MT_RW_DATA | MT_SECURE)
+
+#define QEMU_SPM_BUF_EL0_MMAP MAP_REGION2(PLAT_SPM_BUF_BASE, \
+ PLAT_SPM_BUF_BASE, \
+ PLAT_SPM_BUF_SIZE, \
+ MT_RO_DATA | MT_SECURE | \
+ MT_USER, \
+ PAGE_SIZE)
+
+/*
+ * Shared memory between Normal world and S-EL0 for
+ * passing data during service requests. It will be marked as RW and NS.
+ * This buffer is allocated at the top of NS_DRAM, the base address is
+ * overridden in SPM initialization.
+ */
+#define PLAT_QEMU_SP_IMAGE_NS_BUF_BASE (PLAT_QEMU_DT_BASE + \
+ PLAT_QEMU_DT_MAX_SIZE)
+#define PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE ULL(0x200000)
+
+#define QEMU_SP_IMAGE_NS_BUF_MMAP MAP_REGION2( \
+ PLAT_QEMU_SP_IMAGE_NS_BUF_BASE, \
+ PLAT_QEMU_SP_IMAGE_NS_BUF_BASE, \
+ PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE, \
+ MT_RW_DATA | MT_NS | \
+ MT_USER, \
+ PAGE_SIZE)
+
+#define PLAT_SP_IMAGE_NS_BUF_BASE PLAT_QEMU_SP_IMAGE_NS_BUF_BASE
+#define PLAT_SP_IMAGE_NS_BUF_SIZE PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE
+
+#define PLAT_QEMU_SP_IMAGE_HEAP_BASE (PLAT_QEMU_SP_IMAGE_BASE + \
+ PLAT_QEMU_SP_IMAGE_SIZE)
+#define PLAT_QEMU_SP_IMAGE_HEAP_SIZE ULL(0x800000)
+
+#define PLAT_SP_IMAGE_STACK_BASE (PLAT_QEMU_SP_IMAGE_HEAP_BASE + \
+ PLAT_QEMU_SP_IMAGE_HEAP_SIZE)
+#define PLAT_SP_IMAGE_STACK_PCPU_SIZE ULL(0x10000)
+#define QEMU_SP_IMAGE_STACK_TOTAL_SIZE (PLATFORM_CORE_COUNT * \
+ PLAT_SP_IMAGE_STACK_PCPU_SIZE)
+
+#define QEMU_SP_IMAGE_RW_MMAP MAP_REGION2( \
+ PLAT_QEMU_SP_IMAGE_HEAP_BASE, \
+ PLAT_QEMU_SP_IMAGE_HEAP_BASE, \
+ (QEMU_SP_IMAGE_STACK_TOTAL_SIZE + \
+ PLAT_QEMU_SP_IMAGE_HEAP_SIZE), \
+ MT_RW_DATA | MT_SECURE | \
+ MT_USER, \
+ PAGE_SIZE)
+
+/*
+ * Secure variable storage is located at Secure Flash.
+ */
+#if SPM_MM
+#define QEMU_SECURE_VARSTORE_BASE 0x01000000
+#define QEMU_SECURE_VARSTORE_SIZE 0x00100000
+#define MAP_SECURE_VARSTORE MAP_REGION_FLAT( \
+ QEMU_SECURE_VARSTORE_BASE, \
+ QEMU_SECURE_VARSTORE_SIZE, \
+ MT_MEMORY | MT_RW | \
+ MT_SECURE | MT_USER)
+#endif
+
+/* Total number of memory regions with distinct properties */
+#define PLAT_QEMU_SP_IMAGE_NUM_MEM_REGIONS 6
+
+/*
+ * Name of the section to put the translation tables used by the S-EL1/S-EL0
+ * context of a Secure Partition.
+ */
+#define PLAT_SP_IMAGE_XLAT_SECTION_NAME "qemu_sp_xlat_table"
+#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME "qemu_sp_xlat_table"
+
+/* Cookies passed to the Secure Partition at boot. Not used by QEMU platforms.*/
+#define PLAT_SPM_COOKIE_0 ULL(0)
+#define PLAT_SPM_COOKIE_1 ULL(0)
+#endif
+
+#define QEMU_PRI_BITS 2
+#define PLAT_SP_PRI 0x20
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 51832d0ff..d45f3f156 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019, Linaro Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2020, Linaro Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,6 +8,12 @@ CRASH_REPORTING := 1
include lib/libfdt/libfdt.mk
+ifeq (${SPM_MM},1)
+NEED_BL32 := yes
+EL3_EXCEPTION_HANDLING := 1
+GICV2_G0_FOR_EL3 := 1
+endif
+
# Enable new version of image loading on QEMU platforms
LOAD_IMAGE_V2 := 1
@@ -41,9 +47,8 @@ BL1_SOURCES += drivers/io/io_semihosting.c \
${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S \
${PLAT_QEMU_COMMON_PATH}/qemu_bl1_setup.c
-BL1_SOURCES += lib/cpus/aarch64/aem_generic.S \
- lib/cpus/aarch64/cortex_a53.S \
- lib/cpus/aarch64/cortex_a57.S
+BL1_SOURCES += lib/cpus/aarch64/cortex_a57.S \
+ lib/cpus/aarch64/cortex_a72.S
BL2_SOURCES += drivers/io/io_semihosting.c \
drivers/io/io_storage.c \
@@ -62,23 +67,28 @@ BL2_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c \
common/desc_image_load.c
endif
-QEMU_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/common/gic_common.c \
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+QEMU_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
${PLAT_QEMU_COMMON_PATH}/qemu_gicv3.c
-BL31_SOURCES += lib/cpus/aarch64/aem_generic.S \
- lib/cpus/aarch64/cortex_a53.S \
- lib/cpus/aarch64/cortex_a57.S \
+BL31_SOURCES += lib/cpus/aarch64/cortex_a57.S \
+ lib/cpus/aarch64/cortex_a72.S \
lib/semihosting/semihosting.c \
lib/semihosting/${ARCH}/semihosting_call.S \
plat/common/plat_psci_common.c \
- ${PLAT_QEMU_COMMON_PATH}/qemu_pm.c \
- ${PLAT_QEMU_COMMON_PATH}/topology.c \
+ ${PLAT_QEMU_PATH}/sbsa_pm.c \
+ ${PLAT_QEMU_PATH}/sbsa_topology.c \
${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S \
${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c \
+ common/fdt_fixup.c \
+ common/fdt_wrappers.c \
${QEMU_GIC_SOURCES}
+ifeq (${SPM_MM},1)
+ BL31_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_spm.c
+endif
SEPARATE_CODE_AND_RODATA := 1
ENABLE_STACK_PROTECTOR := 0
diff --git a/plat/qemu/qemu_sbsa/sbsa_pm.c b/plat/qemu/qemu_sbsa/sbsa_pm.c
new file mode 100644
index 000000000..8d1e1d48c
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/sbsa_pm.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2020, Nuvia Inc
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+#include "sbsa_private.h"
+
+#define ADP_STOPPED_APPLICATION_EXIT 0x20026
+
+/*
+ * Define offset and commands for the fake EC device
+ */
+#define SBSA_SECURE_EC_OFFSET 0x50000000
+
+#define SBSA_SECURE_EC_CMD_SHUTDOWN 0x01
+#define SBSA_SECURE_EC_CMD_REBOOT 0x02
+
+/*
+ * The secure entry point to be used on warm reset.
+ */
+static unsigned long secure_entrypoint;
+
+/* Make composite power state parameter till power level 0 */
+#if PSCI_EXTENDED_STATE_ID
+
+#define qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \
+ (((lvl0_state) << PSTATE_ID_SHIFT) | \
+ ((type) << PSTATE_TYPE_SHIFT))
+#else
+#define qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \
+ (((lvl0_state) << PSTATE_ID_SHIFT) | \
+ ((pwr_lvl) << PSTATE_PWR_LVL_SHIFT) | \
+ ((type) << PSTATE_TYPE_SHIFT))
+#endif /* PSCI_EXTENDED_STATE_ID */
+
+
+#define qemu_make_pwrstate_lvl1(lvl1_state, lvl0_state, pwr_lvl, type) \
+ (((lvl1_state) << PLAT_LOCAL_PSTATE_WIDTH) | \
+ qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type))
+
+
+
+/*
+ * The table storing the valid idle power states. Ensure that the
+ * array entries are populated in ascending order of state-id to
+ * enable us to use binary search during power state validation.
+ * The table must be terminated by a NULL entry.
+ */
+static const unsigned int qemu_pm_idle_states[] = {
+ /* State-id - 0x01 */
+ qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_RET,
+ MPIDR_AFFLVL0, PSTATE_TYPE_STANDBY),
+ /* State-id - 0x02 */
+ qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_OFF,
+ MPIDR_AFFLVL0, PSTATE_TYPE_POWERDOWN),
+ /* State-id - 0x22 */
+ qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_OFF, PLAT_LOCAL_STATE_OFF,
+ MPIDR_AFFLVL1, PSTATE_TYPE_POWERDOWN),
+ 0
+};
+
+/*******************************************************************************
+ * Platform handler called to check the validity of the power state
+ * parameter. The power state parameter has to be a composite power state.
+ ******************************************************************************/
+static int qemu_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state)
+{
+ unsigned int state_id;
+ unsigned int i;
+
+ assert(req_state != NULL);
+
+ /*
+ * Currently we are using a linear search for finding the matching
+ * entry in the idle power state array. This can be made a binary
+ * search if the number of entries justifies the additional complexity.
+ */
+ for (i = 0U; qemu_pm_idle_states[i] != 0U; i++) {
+ if (power_state == qemu_pm_idle_states[i]) {
+ break;
+ }
+ }
+
+ /* Return error if entry not found in the idle state array */
+ if (qemu_pm_idle_states[i] == 0U) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+
+ i = 0U;
+ state_id = psci_get_pstate_id(power_state);
+
+ /* Parse the State ID and populate the state info parameter */
+ while (state_id != 0U) {
+ req_state->pwr_domain_state[i++] = state_id &
+ PLAT_LOCAL_PSTATE_MASK;
+ state_id >>= PLAT_LOCAL_PSTATE_WIDTH;
+ }
+
+ return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Platform handler called when a CPU is about to enter standby.
+ ******************************************************************************/
+static void qemu_cpu_standby(plat_local_state_t cpu_state)
+{
+
+ assert(cpu_state == PLAT_LOCAL_STATE_RET);
+
+ /*
+ * Enter standby state
+ * dsb is good practice before using wfi to enter low power states
+ */
+ dsb();
+ wfi();
+}
+
+/*******************************************************************************
+ * Platform handler called when a power domain is about to be turned on. The
+ * mpidr determines the CPU to be turned on.
+ ******************************************************************************/
+static int qemu_pwr_domain_on(u_register_t mpidr)
+{
+ int pos = plat_core_pos_by_mpidr(mpidr);
+ uint64_t *hold_base = (uint64_t *)PLAT_QEMU_HOLD_BASE;
+
+ if (pos < 0) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+
+ hold_base[pos] = PLAT_QEMU_HOLD_STATE_GO;
+ dsb();
+ sev();
+
+ return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Platform handler called when a power domain is about to be turned off. The
+ * target_state encodes the power state that each level should transition to.
+ ******************************************************************************/
+static void qemu_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ qemu_pwr_gic_off();
+}
+
+void __dead2 plat_secondary_cold_boot_setup(void);
+
+static void __dead2
+qemu_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
+{
+ disable_mmu_el3();
+ plat_secondary_cold_boot_setup();
+}
+
+/*******************************************************************************
+ * Platform handler called when a power domain is about to be suspended. The
+ * target_state encodes the power state that each level should transition to.
+ ******************************************************************************/
+void qemu_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+ assert(false);
+}
+
+/*******************************************************************************
+ * Platform handler called when a power domain has just been powered on after
+ * being turned off earlier. The target_state encodes the low power state that
+ * each level has woken up from.
+ ******************************************************************************/
+void qemu_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+ PLAT_LOCAL_STATE_OFF);
+
+ qemu_pwr_gic_on_finish();
+}
+
+/*******************************************************************************
+ * Platform handler called when a power domain has just been powered on after
+ * having been suspended earlier. The target_state encodes the low power state
+ * that each level has woken up from.
+ ******************************************************************************/
+void qemu_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
+{
+ assert(false);
+}
+
+/*******************************************************************************
+ * Platform handlers to shutdown/reboot the system
+ ******************************************************************************/
+static void __dead2 qemu_system_off(void)
+{
+ mmio_write_32(SBSA_SECURE_EC_OFFSET, SBSA_SECURE_EC_CMD_SHUTDOWN);
+ panic();
+}
+
+static void __dead2 qemu_system_reset(void)
+{
+ mmio_write_32(SBSA_SECURE_EC_OFFSET, SBSA_SECURE_EC_CMD_REBOOT);
+ panic();
+}
+
+static const plat_psci_ops_t plat_qemu_psci_pm_ops = {
+ .cpu_standby = qemu_cpu_standby,
+ .pwr_domain_on = qemu_pwr_domain_on,
+ .pwr_domain_off = qemu_pwr_domain_off,
+ .pwr_domain_pwr_down_wfi = qemu_pwr_domain_pwr_down_wfi,
+ .pwr_domain_suspend = qemu_pwr_domain_suspend,
+ .pwr_domain_on_finish = qemu_pwr_domain_on_finish,
+ .pwr_domain_suspend_finish = qemu_pwr_domain_suspend_finish,
+ .system_off = qemu_system_off,
+ .system_reset = qemu_system_reset,
+ .validate_power_state = qemu_validate_power_state
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ uintptr_t *mailbox = (uintptr_t *)PLAT_QEMU_TRUSTED_MAILBOX_BASE;
+
+ *mailbox = sec_entrypoint;
+ secure_entrypoint = (unsigned long)sec_entrypoint;
+ *psci_ops = &plat_qemu_psci_pm_ops;
+
+ return 0;
+}
diff --git a/plat/qemu/qemu_sbsa/sbsa_private.h b/plat/qemu/qemu_sbsa/sbsa_private.h
new file mode 100644
index 000000000..a9f4601de
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/sbsa_private.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020, Nuvia Inc
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SBSA_PRIVATE_H
+#define SBSA_PRIVATE_H
+
+#include <stdint.h>
+
+unsigned int plat_qemu_calc_core_pos(u_register_t mpidr);
+
+void qemu_pwr_gic_on_finish(void);
+void qemu_pwr_gic_off(void);
+
+#endif /* SBSA_PRIVATE_H */
diff --git a/plat/qemu/qemu_sbsa/sbsa_topology.c b/plat/qemu/qemu_sbsa/sbsa_topology.c
new file mode 100644
index 000000000..bd8d16b9a
--- /dev/null
+++ b/plat/qemu/qemu_sbsa/sbsa_topology.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2020, Nuvia Inc
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <common/debug.h>
+
+#include <platform_def.h>
+#include "sbsa_private.h"
+
+/* The power domain tree descriptor */
+static unsigned char power_domain_tree_desc[PLATFORM_CLUSTER_COUNT + 1];
+
+/*******************************************************************************
+ * This function returns the sbsa-ref default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ unsigned int i;
+
+ power_domain_tree_desc[0] = PLATFORM_CLUSTER_COUNT;
+
+ for (i = 0U; i < PLATFORM_CLUSTER_COUNT; i++) {
+ power_domain_tree_desc[i + 1] = PLATFORM_MAX_CPUS_PER_CLUSTER;
+ }
+
+ return power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+ unsigned int cluster_id, cpu_id;
+
+ mpidr &= MPIDR_AFFINITY_MASK;
+ if ((mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0U) {
+ ERROR("Invalid MPIDR\n");
+ return -1;
+ }
+
+ cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+ cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+ if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+ ERROR("cluster_id >= PLATFORM_CLUSTER_COUNT define\n");
+ return -1;
+ }
+
+ if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) {
+ ERROR("cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER define\n");
+ return -1;
+ }
+
+ return plat_qemu_calc_core_pos(mpidr);
+}
diff --git a/plat/qti/common/inc/aarch64/plat_macros.S b/plat/qti/common/inc/aarch64/plat_macros.S
new file mode 100644
index 000000000..2e292fb19
--- /dev/null
+++ b/plat/qti/common/inc/aarch64/plat_macros.S
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_MACROS_S__
+#define __PLAT_MACROS_S__
+
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/arm/gicv3.h>
+
+#include <platform_def.h>
+
+.section .rodata.gic_reg_name, "aS"
+/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */
+gicc_regs:
+ .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+
+/* Applicable only to GICv3 with SRE enabled */
+icc_regs:
+ .asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", ""
+
+/* Registers common to both GICv2 and GICv3 */
+gicd_pend_reg:
+ .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \
+ " Offset:\t\t\tvalue\n"
+newline:
+ .asciz "\n"
+spacer:
+ .asciz ":\t\t0x"
+
+/** Macro : plat_crash_print_regs
+ * This macro allows the crash reporting routine to print GIC registers
+ * in case of an unhandled exception in BL31. This aids in debugging and
+ * this macro can be defined to be empty in case GIC register reporting is
+ * not desired.
+ * The below required platform porting macro
+ * prints out relevant GIC registers whenever an
+ * unhandled exception is taken in BL31.
+ * Clobbers: x0 - x10, x26, x27, sp
+ * ---------------------------------------------
+ */
+ .macro plat_crash_print_regs
+print_gic_regs:
+ ldr x26, =QTI_GICD_BASE
+ ldr x27, =QTI_GICC_BASE
+
+ /* Check for GICv3 system register access */
+ mrs x7, id_aa64pfr0_el1
+ ubfx x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH
+ cmp x7, #1
+ b.ne print_gicv2
+
+ /* Check for SRE enable */
+ mrs x8, ICC_SRE_EL3
+ tst x8, #ICC_SRE_SRE_BIT
+ b.eq print_gicv2
+
+ /* Load the icc reg list to x6 */
+ adr x6, icc_regs
+ /* Load the icc regs to gp regs used by str_in_crash_buf_print */
+ mrs x8, ICC_HPPIR0_EL1
+ mrs x9, ICC_HPPIR1_EL1
+ mrs x10, ICC_CTLR_EL3
+ /* Store to the crash buf and print to console */
+ bl str_in_crash_buf_print
+ b print_gic_common
+
+print_gicv2:
+ /* Load the gicc reg list to x6 */
+ adr x6, gicc_regs
+ /* Load the gicc regs to gp regs used by str_in_crash_buf_print */
+ ldr w8, [x27, #GICC_HPPIR]
+ ldr w9, [x27, #GICC_AHPPIR]
+ ldr w10, [x27, #GICC_CTLR]
+ /* Store to the crash buf and print to console */
+ bl str_in_crash_buf_print
+
+print_gic_common:
+ /* Print the GICD_ISPENDR regs */
+ add x7, x26, #GICD_ISPENDR
+ adr x4, gicd_pend_reg
+ bl asm_print_str
+gicd_ispendr_loop:
+ sub x4, x7, x26
+ cmp x4, #0x280
+ b.eq exit_print_gic_regs
+ bl asm_print_hex
+
+ adr x4, spacer
+ bl asm_print_str
+
+ ldr x4, [x7], #8
+ bl asm_print_hex
+
+ adr x4, newline
+ bl asm_print_str
+ b gicd_ispendr_loop
+exit_print_gic_regs:
+
+ .endm
+
+#endif /* __PLAT_MACROS_S__ */
diff --git a/plat/qti/common/inc/qti_board_def.h b/plat/qti/common/inc/qti_board_def.h
new file mode 100644
index 000000000..c95e4c0c3
--- /dev/null
+++ b/plat/qti/common/inc/qti_board_def.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QTI_BOARD_DEF_H
+#define QTI_BOARD_DEF_H
+
+/*
+ * Required platform porting definitions common to all ARM
+ * development platforms
+ */
+
+/*
+ * Defines used to retrieve QTI SOC Version
+ */
+#define JEDEC_QTI_BKID U(0x0)
+#define JEDEC_QTI_MFID U(0x70)
+#define QTI_SOC_CONTINUATION_SHIFT U(24)
+#define QTI_SOC_IDENTIFICATION_SHIFT U(16)
+
+/* Size of cacheable stacks */
+#define PLATFORM_STACK_SIZE 0x1000
+
+/*
+ * PLAT_QTI_MMAP_ENTRIES depends on the number of entries in the
+ * plat_qti_mmap array defined for each BL stage.
+ */
+#define PLAT_QTI_MMAP_ENTRIES 12
+
+/*
+ * Platform specific page table and MMU setup constants
+ */
+#define MAX_XLAT_TABLES 12
+
+#endif /* QTI_BOARD_DEF_H */
diff --git a/plat/qti/common/inc/qti_cpu.h b/plat/qti/common/inc/qti_cpu.h
new file mode 100644
index 000000000..3eda02bbb
--- /dev/null
+++ b/plat/qti/common/inc/qti_cpu.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTI_CPU_H
+#define QTI_CPU_H
+
+/* KRYO-4xx Gold MIDR */
+#define QTI_KRYO4_GOLD_MIDR 0x517F804D
+
+/* KRYO-4xx Silver MIDR */
+#define QTI_KRYO4_SILVER_MIDR 0x517F805D
+
+#endif /* QTI_CPU_H */
diff --git a/plat/qti/common/inc/qti_interrupt_svc.h b/plat/qti/common/inc/qti_interrupt_svc.h
new file mode 100644
index 000000000..59bde8681
--- /dev/null
+++ b/plat/qti/common/inc/qti_interrupt_svc.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTI_INTERRUPT_SVC_H
+#define QTI_INTERRUPT_SVC_H
+
+int qti_interrupt_svc_init(void);
+
+#endif /* QTI_INTERRUPT_SVC_H */
diff --git a/plat/qti/common/inc/qti_plat.h b/plat/qti/common/inc/qti_plat.h
new file mode 100644
index 000000000..4d9d3204a
--- /dev/null
+++ b/plat/qti/common/inc/qti_plat.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTI_PLAT_H
+#define QTI_PLAT_H
+
+#include <stdint.h>
+
+#include <common/bl_common.h>
+#include <lib/cassert.h>
+#include <lib/el3_runtime/cpu_data.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+/*
+ * Utility functions common to QTI platforms
+ */
+int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size,
+ unsigned int attr);
+int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size);
+
+/*
+ * Utility functions common to ARM standard platforms
+ */
+void qti_setup_page_tables(uintptr_t total_base,
+ size_t total_size,
+ uintptr_t code_start,
+ uintptr_t code_limit,
+ uintptr_t rodata_start,
+ uintptr_t rodata_limit,
+ uintptr_t coh_start, uintptr_t coh_limit);
+
+/*
+ * Mandatory functions required in ARM standard platforms
+ */
+void plat_qti_gic_driver_init(void);
+void plat_qti_gic_init(void);
+void plat_qti_gic_cpuif_enable(void);
+void plat_qti_gic_cpuif_disable(void);
+void plat_qti_gic_pcpu_init(void);
+
+/*
+ * Optional functions required in ARM standard platforms
+ */
+unsigned int plat_qti_core_pos_by_mpidr(u_register_t mpidr);
+unsigned int plat_qti_my_cluster_pos(void);
+
+void gic_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr);
+
+void qti_pmic_prepare_reset(void);
+void qti_pmic_prepare_shutdown(void);
+
+#endif /* QTI_PLAT_H */
diff --git a/plat/qti/common/inc/qti_rng.h b/plat/qti/common/inc/qti_rng.h
new file mode 100644
index 000000000..62c31f36c
--- /dev/null
+++ b/plat/qti/common/inc/qti_rng.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTI_RNG_H
+#define QTI_RNG_H
+
+#include <stdint.h>
+
+int qti_rng_get_data(uint8_t *out, uint32_t out_len);
+
+#endif /* QTI_RNG_H */
diff --git a/plat/qti/common/inc/qti_uart_console.h b/plat/qti/common/inc/qti_uart_console.h
new file mode 100644
index 000000000..c5a65d618
--- /dev/null
+++ b/plat/qti/common/inc/qti_uart_console.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTI_UART_CONSOLE_H
+#define QTI_UART_CONSOLE_H
+
+#include <drivers/console.h>
+
+#ifndef __ASSEMBLER__
+
+int qti_console_uart_register(console_t *console, uintptr_t uart_base_addr);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* QTI_UART_CONSOLE_H */
diff --git a/plat/qti/common/inc/spmi_arb.h b/plat/qti/common/inc/spmi_arb.h
new file mode 100644
index 000000000..362f7406c
--- /dev/null
+++ b/plat/qti/common/inc/spmi_arb.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMI_ARB_H
+#define SPMI_ARB_H
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * WARNING: This driver does not arbitrate access with the kernel. These APIs
+ * must only be called when the kernel is known to be quiesced (such as before
+ * boot or while the system is shutting down).
+ ******************************************************************************/
+
+/* 32-bit addresses combine (U)SID, PID and register address. */
+
+int spmi_arb_read8(uint32_t addr);
+int spmi_arb_write8(uint32_t addr, uint8_t data);
+
+#endif /* SPMI_ARB_H */
diff --git a/plat/qti/common/src/aarch64/qti_helpers.S b/plat/qti/common/src/aarch64/qti_helpers.S
new file mode 100644
index 000000000..c1ea7b32f
--- /dev/null
+++ b/plat/qti/common/src/aarch64/qti_helpers.S
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <drivers/arm/gicv2.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/console.h>
+
+#include <platform_def.h>
+
+ .globl plat_my_core_pos
+ .globl plat_qti_core_pos_by_mpidr
+ .globl plat_reset_handler
+ .globl plat_panic_handler
+
+ /* -----------------------------------------------------
+ * unsigned int plat_qti_core_pos_by_mpidr(uint64_t mpidr)
+ * Helper function to calculate the core position.
+ * With this function:
+ * CorePos = (ClusterId * 4) + CoreId
+ * - In ARM v8 (MPIDR_EL1[24]=0)
+ * ClusterId = MPIDR_EL1[15:8]
+ * CoreId = MPIDR_EL1[7:0]
+ * - In ARM v8.1 (MPIDR_EL1[24]=1)
+ * ClusterId = MPIDR_EL1[23:15]
+ * CoreId = MPIDR_EL1[15:8]
+ * Clobbers: x0 & x1.
+ * -----------------------------------------------------
+ */
+func plat_qti_core_pos_by_mpidr
+ mrs x1, mpidr_el1
+ tst x1, #MPIDR_MT_MASK
+ beq plat_qti_core_pos_by_mpidr_no_mt
+ /* Right shift mpidr by one affinity level when MT=1. */
+ lsr x0, x0, #MPIDR_AFFINITY_BITS
+plat_qti_core_pos_by_mpidr_no_mt:
+ and x1, x0, #MPIDR_CPU_MASK
+ and x0, x0, #MPIDR_CLUSTER_MASK
+ add x0, x1, x0, LSR #6
+ ret
+endfunc plat_qti_core_pos_by_mpidr
+
+ /* --------------------------------------------------------------------
+ * void plat_panic_handler(void)
+ * calls SDI and reset system
+ * --------------------------------------------------------------------
+ */
+func plat_panic_handler
+ msr spsel, #0
+ bl plat_set_my_stack
+ b qtiseclib_panic
+endfunc plat_panic_handler
+
+ /* -----------------------------------------------------
+ * unsigned int plat_my_core_pos(void)
+ * This function uses the plat_qti_calc_core_pos()
+ * definition to get the index of the calling CPU
+ * Clobbers: x0 & x1.
+ * -----------------------------------------------------
+ */
+func plat_my_core_pos
+ mrs x0, mpidr_el1
+ b plat_qti_core_pos_by_mpidr
+endfunc plat_my_core_pos
+
+func plat_reset_handler
+ /* save the lr */
+ mov x18, x30
+
+ /* Serialize CPUSS boot setup. Multi core enter simultaneously. */
+ ldr x0, =g_qti_cpuss_boot_lock
+ bl spin_lock
+
+ /* pass cold boot status. */
+ ldr w0, g_qti_bl31_cold_booted
+ /* Execuete CPUSS boot set up on every core. */
+ bl qtiseclib_cpuss_reset_asm
+
+ ldr x0, =g_qti_cpuss_boot_lock
+ bl spin_unlock
+
+ ret x18
+endfunc plat_reset_handler
diff --git a/plat/qti/common/src/aarch64/qti_kryo4_gold.S b/plat/qti/common/src/aarch64/qti_kryo4_gold.S
new file mode 100644
index 000000000..a1b40c8d1
--- /dev/null
+++ b/plat/qti/common/src/aarch64/qti_kryo4_gold.S
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+
+#include <plat_macros.S>
+#include <qti_cpu.h>
+
+ .p2align 3
+
+/* -------------------------------------------------
+ * The CPU Ops reset function for Kryo-3 Gold
+ * -------------------------------------------------
+ */
+func qti_kryo4_gold_reset_func
+#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715
+ adr x0, wa_cve_2017_5715_bpiall_vbar
+ msr vbar_el3, x0
+ isb
+#endif
+
+ mov x19, x30
+
+ bl qtiseclib_kryo4_gold_reset_asm
+
+ ret x19
+
+endfunc qti_kryo4_gold_reset_func
+
+/* ----------------------------------------------------
+ * The CPU Ops core power down function for Kryo-3 Gold
+ * ----------------------------------------------------
+ */
+func qti_kryo4_gold_core_pwr_dwn
+ ret
+endfunc qti_kryo4_gold_core_pwr_dwn
+
+/* -------------------------------------------------------
+ * The CPU Ops cluster power down function for Kryo-3 Gold
+ * -------------------------------------------------------
+ */
+func qti_kryo4_gold_cluster_pwr_dwn
+ ret
+endfunc qti_kryo4_gold_cluster_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Kryo4 Gold. Must follow AAPCS.
+ */
+func qti_kryo4_gold_errata_report
+ /* TODO : Need to add support. Required only for debug bl31 image.*/
+ ret
+endfunc qti_kryo4_gold_errata_report
+#endif
+
+/* ---------------------------------------------
+ * This function provides kryo4_gold specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ASCII and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.qti_kryo4_gold_regs, "aS"
+qti_kryo4_gold_regs: /* The ASCII list of register names to be reported */
+ .asciz ""
+
+func qti_kryo4_gold_cpu_reg_dump
+ adr x6, qti_kryo4_gold_regs
+ ret
+endfunc qti_kryo4_gold_cpu_reg_dump
+
+declare_cpu_ops qti_kryo4_gold, QTI_KRYO4_GOLD_MIDR, \
+ qti_kryo4_gold_reset_func, \
+ qti_kryo4_gold_core_pwr_dwn, \
+ qti_kryo4_gold_cluster_pwr_dwn
diff --git a/plat/qti/common/src/aarch64/qti_kryo4_silver.S b/plat/qti/common/src/aarch64/qti_kryo4_silver.S
new file mode 100644
index 000000000..183eeb0fa
--- /dev/null
+++ b/plat/qti/common/src/aarch64/qti_kryo4_silver.S
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+
+#include <plat_macros.S>
+#include <qti_cpu.h>
+
+ .p2align 3
+
+/* -------------------------------------------------
+ * The CPU Ops reset function for Kryo-3 Silver
+ * -------------------------------------------------
+ */
+func qti_kryo4_silver_reset_func
+ mov x19, x30
+
+ bl qtiseclib_kryo4_silver_reset_asm
+
+ ret x19
+
+endfunc qti_kryo4_silver_reset_func
+
+/* ------------------------------------------------------
+ * The CPU Ops core power down function for Kryo-3 Silver
+ * ------------------------------------------------------
+ */
+func qti_kryo4_silver_core_pwr_dwn
+ ret
+endfunc qti_kryo4_silver_core_pwr_dwn
+
+/* ---------------------------------------------------------
+ * The CPU Ops cluster power down function for Kryo-3 Silver
+ * ---------------------------------------------------------
+ */
+func qti_kryo4_silver_cluster_pwr_dwn
+ ret
+endfunc qti_kryo4_silver_cluster_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Kryo4 Silver. Must follow AAPCS.
+ */
+func qti_kryo4_silver_errata_report
+ /* TODO : Need to add support. Required only for debug bl31 image.*/
+ ret
+endfunc qti_kryo4_silver_errata_report
+#endif
+
+
+/* ---------------------------------------------
+ * This function provides kryo4_silver specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ASCII and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.qti_kryo4_silver_regs, "aS"
+qti_kryo4_silver_regs: /* The ASCII list of register names to be reported */
+ .asciz ""
+
+func qti_kryo4_silver_cpu_reg_dump
+ adr x6, qti_kryo4_silver_regs
+ ret
+endfunc qti_kryo4_silver_cpu_reg_dump
+
+
+declare_cpu_ops qti_kryo4_silver, QTI_KRYO4_SILVER_MIDR, \
+ qti_kryo4_silver_reset_func, \
+ qti_kryo4_silver_core_pwr_dwn, \
+ qti_kryo4_silver_cluster_pwr_dwn
diff --git a/plat/qti/common/src/aarch64/qti_uart_console.S b/plat/qti/common/src/aarch64/qti_uart_console.S
new file mode 100644
index 000000000..2eb33d97a
--- /dev/null
+++ b/plat/qti/common/src/aarch64/qti_uart_console.S
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <console_macros.S>
+
+#include <platform_def.h>
+#include <qti_uart_console.h>
+
+/*
+ * This driver implements console logging into a ring buffer.
+ */
+
+ .globl qti_console_uart_register
+
+ /* -----------------------------------------------
+ * int qti_console_uart_register(console_t *console,
+ * uintptr_t uart_base_addr)
+ * Registers uart console instance.
+ * In: x0 - pointer to empty console_t struct
+ * x1 - start address of uart block.
+ * Out: x0 - 1 to indicate success
+ * Clobber list: x0, x1, x14
+ * -----------------------------------------------
+ */
+func qti_console_uart_register
+ str x1, [x0, #CONSOLE_T_BASE] /* Save UART base. */
+ finish_console_register uart putc=1, flush=1
+endfunc qti_console_uart_register
+
+ /* -----------------------------------------------
+ * int qti_console_uart_puts(int c, console_t *console)
+ * Writes a character to the UART console.
+ * The character must be preserved in x0.
+ * In: x0 - character to be stored
+ * x1 - pointer to console_t struct
+ * Clobber list: x1, x2
+ * -----------------------------------------------
+ */
+func console_uart_putc
+ /* set x1 = UART base. */
+ ldr x1, [x1, #CONSOLE_T_BASE]
+
+ /* Loop until M_GENI_CMD_ACTIVE bit not clear. */
+1: ldr w2, [x1, #GENI_STATUS_REG]
+ and w2, w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
+ cmp w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
+ b.eq 1b
+
+ /* Transmit data. */
+ cmp w0, #0xA
+ b.ne 3f
+
+ /* Add '\r' when input char is '\n' */
+ mov w2, #0x1
+ mov w0, #0xD
+ str w2, [x1, #UART_TX_TRANS_LEN_REG]
+ mov w2, #GENI_M_CMD_TX
+ str w2, [x1, #GENI_M_CMD0_REG]
+ str w0, [x1, #GENI_TX_FIFOn_REG]
+ mov w0, #0xA
+
+ /* Loop until M_GENI_CMD_ACTIVE bit not clear. */
+2: ldr w2, [x1, #GENI_STATUS_REG]
+ and w2, w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
+ cmp w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
+ b.eq 2b
+
+ /* Transmit i/p data. */
+3: mov w2, #0x1
+ str w2, [x1, #UART_TX_TRANS_LEN_REG]
+ mov w2, #GENI_M_CMD_TX
+ str w2, [x1, #GENI_M_CMD0_REG]
+ str w0, [x1, #GENI_TX_FIFOn_REG]
+
+ ret
+endfunc console_uart_putc
+
+ /* -----------------------------------------------
+ * int qti_console_uart_flush(console_t *console)
+ * In: x0 - pointer to console_t struct
+ * Out: x0 - 0 for success
+ * Clobber list: x0, x1
+ * -----------------------------------------------
+ */
+func console_uart_flush
+ /* set x0 = UART base. */
+ ldr x0, [x0, #CONSOLE_T_BASE]
+
+ /* Loop until M_GENI_CMD_ACTIVE bit not clear. */
+1: ldr w1, [x0, #GENI_STATUS_REG]
+ and w1, w1, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
+ cmp w1, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
+ b.eq 1b
+
+ mov w0, #0
+ ret
+endfunc console_uart_flush
diff --git a/plat/qti/common/src/pm8998.c b/plat/qti/common/src/pm8998.c
new file mode 100644
index 000000000..b189a8b86
--- /dev/null
+++ b/plat/qti/common/src/pm8998.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/delay_timer.h>
+
+#include <qti_plat.h>
+#include <spmi_arb.h>
+
+/*
+ * This driver implements PON support for PM8998-compatible PMICs. This can
+ * include other part numbers like PM6150.
+ */
+
+#define PON_PS_HOLD_RESET_CTL 0x85a
+#define RESET_TYPE_WARM_RESET 1
+#define RESET_TYPE_SHUTDOWN 4
+
+#define PON_PS_HOLD_RESET_CTL2 0x85b
+#define S2_RESET_EN BIT(7)
+
+static void configure_ps_hold(uint32_t reset_type)
+{
+ /* QTI recommends disabling reset for 10 cycles before reconfiguring. */
+ spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, 0);
+ mdelay(1);
+
+ spmi_arb_write8(PON_PS_HOLD_RESET_CTL, reset_type);
+ spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, S2_RESET_EN);
+ mdelay(1);
+}
+
+void qti_pmic_prepare_reset(void)
+{
+ configure_ps_hold(RESET_TYPE_WARM_RESET);
+}
+
+void qti_pmic_prepare_shutdown(void)
+{
+ configure_ps_hold(RESET_TYPE_SHUTDOWN);
+}
diff --git a/plat/qti/common/src/qti_bl31_setup.c b/plat/qti/common/src/qti_bl31_setup.c
new file mode 100644
index 000000000..b2bc5436f
--- /dev/null
+++ b/plat/qti/common/src/qti_bl31_setup.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/bl_aux_params/bl_aux_params.h>
+#include <lib/coreboot.h>
+#include <lib/spinlock.h>
+
+#include <platform.h>
+#include <qti_interrupt_svc.h>
+#include <qti_plat.h>
+#include <qti_uart_console.h>
+#include <qtiseclib_interface.h>
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl33_image_ep_info;
+
+/*
+ * Variable to hold counter frequency for the CPU's generic timer. In this
+ * platform coreboot image configure counter frequency for boot core before
+ * reaching TF-A.
+ */
+static uint64_t g_qti_cpu_cntfrq;
+
+/*
+ * Lock variable to serialize cpuss reset execution.
+ */
+spinlock_t g_qti_cpuss_boot_lock __attribute__ ((section("tzfw_coherent_mem"),
+ aligned(CACHE_WRITEBACK_GRANULE))) = {0x0};
+
+/*
+ * Variable to hold bl31 cold boot status. Default value 0x0 means yet to boot.
+ * Any other value means cold booted.
+ */
+uint32_t g_qti_bl31_cold_booted __attribute__ ((section("tzfw_coherent_mem"))) = 0x0;
+
+/*******************************************************************************
+ * Perform any BL31 early platform setup common to ARM standard platforms.
+ * Here is an opportunity to copy parameters passed by the calling EL (S-EL1
+ * in BL2 & S-EL3 in BL1) before they are lost (potentially). This needs to be
+ * done before the MMU is initialized so that the memory layout can be used
+ * while creating page tables. BL2 has flushed this information to memory, so
+ * we are guaranteed to pick up good data.
+ ******************************************************************************/
+void bl31_early_platform_setup(u_register_t from_bl2,
+ u_register_t plat_params_from_bl2)
+{
+
+ g_qti_cpu_cntfrq = read_cntfrq_el0();
+
+ bl_aux_params_parse(plat_params_from_bl2, NULL);
+
+#if COREBOOT
+ if (coreboot_serial.baseaddr != 0) {
+ static console_t g_qti_console_uart;
+
+ qti_console_uart_register(&g_qti_console_uart,
+ coreboot_serial.baseaddr);
+ }
+#endif
+
+ /*
+ * Tell BL31 where the non-trusted software image
+ * is located and the entry state information
+ */
+ bl31_params_parse_helper(from_bl2, NULL, &bl33_image_ep_info);
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ bl31_early_platform_setup(arg0, arg1);
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl31_plat_arch_setup(void)
+{
+ qti_setup_page_tables(BL_CODE_BASE,
+ BL_COHERENT_RAM_END - BL_CODE_BASE,
+ BL_CODE_BASE,
+ BL_CODE_END,
+ BL_RO_DATA_BASE,
+ BL_RO_DATA_END,
+ BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END);
+ enable_mmu_el3(0);
+}
+
+/*******************************************************************************
+ * Perform any BL31 platform setup common to ARM standard platforms
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+ generic_delay_timer_init();
+ /* Initialize the GIC driver, CPU and distributor interfaces */
+ plat_qti_gic_driver_init();
+ plat_qti_gic_init();
+ qti_interrupt_svc_init();
+ qtiseclib_bl31_platform_setup();
+
+ /* set boot state to cold boot complete. */
+ g_qti_bl31_cold_booted = 0x1;
+}
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for the
+ * security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+ /* QTI platform don't have BL32 implementation. */
+ assert(type == NON_SECURE);
+ assert(bl33_image_ep_info.h.type == PARAM_EP);
+ assert(bl33_image_ep_info.h.attr == NON_SECURE);
+ /*
+ * None of the images on the platforms can have 0x0
+ * as the entrypoint.
+ */
+ if (bl33_image_ep_info.pc) {
+ return &bl33_image_ep_info;
+ } else {
+ return NULL;
+ }
+}
+
+/*******************************************************************************
+ * This function is used by the architecture setup code to retrieve the counter
+ * frequency for the CPU's generic timer. This value will be programmed into the
+ * CNTFRQ_EL0 register. In Arm standard platforms, it returns the base frequency
+ * of the system counter, which is retrieved from the first entry in the
+ * frequency modes table. This will be used later in warm boot (psci_arch_setup)
+ * of CPUs to set when CPU frequency.
+ ******************************************************************************/
+unsigned int plat_get_syscnt_freq2(void)
+{
+ assert(g_qti_cpu_cntfrq != 0);
+ return g_qti_cpu_cntfrq;
+}
diff --git a/plat/qti/common/src/qti_common.c b/plat/qti/common/src/qti_common.c
new file mode 100644
index 000000000..da0eaec44
--- /dev/null
+++ b/plat/qti/common/src/qti_common.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <services/arm_arch_svc.h>
+
+#include <platform_def.h>
+#include <qti_plat.h>
+#include <qtiseclib_interface.h>
+
+/*
+ * Table of regions for various BL stages to map using the MMU.
+ * This doesn't include TZRAM as the 'mem_layout' argument passed to
+ * qti_configure_mmu_elx() will give the available subset of that,
+ */
+
+const mmap_region_t plat_qti_mmap[] = {
+ MAP_REGION_FLAT(QTI_DEVICE_BASE, QTI_DEVICE_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(QTI_AOP_CMD_DB_BASE, QTI_AOP_CMD_DB_SIZE,
+ MT_NS | MT_RO | MT_EXECUTE_NEVER),
+ {0}
+};
+
+CASSERT(ARRAY_SIZE(plat_qti_mmap) <= MAX_MMAP_REGIONS, assert_max_mmap_regions);
+
+
+bool qti_is_overlap_atf_rg(unsigned long long addr, size_t size)
+{
+ if (addr > addr + size
+ || (BL31_BASE < addr + size && BL31_LIMIT > addr)) {
+ return true;
+ }
+ return false;
+}
+
+/*
+ * unsigned int plat_qti_my_cluster_pos(void)
+ * definition to get the cluster index of the calling CPU.
+ * - In ARM v8 (MPIDR_EL1[24]=0)
+ * ClusterId = MPIDR_EL1[15:8]
+ * - In ARM v8.1 & Later version (MPIDR_EL1[24]=1)
+ * ClusterId = MPIDR_EL1[23:15]
+ */
+unsigned int plat_qti_my_cluster_pos(void)
+{
+ unsigned int mpidr, cluster_id;
+
+ mpidr = read_mpidr_el1();
+ if ((mpidr & MPIDR_MT_MASK) == 0) { /* MT not supported */
+ cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+ } else { /* MT supported */
+ cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
+ }
+ assert(cluster_id < PLAT_CLUSTER_COUNT);
+ return cluster_id;
+}
+
+/*
+ * Set up the page tables for the generic and platform-specific memory regions.
+ * The extents of the generic memory regions are specified by the function
+ * arguments and consist of:
+ * - Trusted SRAM seen by the BL image;
+ * - Code section;
+ * - Read-only data section;
+ * - Coherent memory region, if applicable.
+ */
+void qti_setup_page_tables(uintptr_t total_base,
+ size_t total_size,
+ uintptr_t code_start,
+ uintptr_t code_limit,
+ uintptr_t rodata_start,
+ uintptr_t rodata_limit,
+ uintptr_t coh_start, uintptr_t coh_limit)
+{
+ /*
+ * Map the Trusted SRAM with appropriate memory attributes.
+ * Subsequent mappings will adjust the attributes for specific regions.
+ */
+ VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n",
+ (void *)total_base, (void *)(total_base + total_size));
+ mmap_add_region(total_base, total_base,
+ total_size, MT_MEMORY | MT_RW | MT_SECURE);
+
+ /* Re-map the code section */
+ VERBOSE("Code region: %p - %p\n",
+ (void *)code_start, (void *)code_limit);
+ mmap_add_region(code_start, code_start,
+ code_limit - code_start, MT_CODE | MT_SECURE);
+
+ /* Re-map the read-only data section */
+ VERBOSE("Read-only data region: %p - %p\n",
+ (void *)rodata_start, (void *)rodata_limit);
+ mmap_add_region(rodata_start, rodata_start,
+ rodata_limit - rodata_start, MT_RO_DATA | MT_SECURE);
+
+ /* Re-map the coherent memory region */
+ VERBOSE("Coherent region: %p - %p\n",
+ (void *)coh_start, (void *)coh_limit);
+ mmap_add_region(coh_start, coh_start,
+ coh_limit - coh_start, MT_DEVICE | MT_RW | MT_SECURE);
+
+ /* Now (re-)map the platform-specific memory regions */
+ mmap_add(plat_qti_mmap);
+
+ /* Create the page tables to reflect the above mappings */
+ init_xlat_tables();
+}
+
+static inline void qti_align_mem_region(uintptr_t addr, size_t size,
+ uintptr_t *aligned_addr,
+ size_t *aligned_size)
+{
+ *aligned_addr = round_down(addr, PAGE_SIZE);
+ *aligned_size = round_up(addr - *aligned_addr + size, PAGE_SIZE);
+}
+
+int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size,
+ unsigned int attr)
+{
+ uintptr_t aligned_pa;
+ size_t aligned_size;
+
+ qti_align_mem_region(base_pa, size, &aligned_pa, &aligned_size);
+
+ if (qti_is_overlap_atf_rg(base_pa, size)) {
+ /* Memory shouldn't overlap with TF-A range. */
+ return -EPERM;
+ }
+
+ return mmap_add_dynamic_region(aligned_pa, aligned_pa, aligned_size,
+ attr);
+}
+
+int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
+{
+ qti_align_mem_region(base_va, size, &base_va, &size);
+ return mmap_remove_dynamic_region(base_va, size);
+}
+
+/*
+ * This function returns soc version which mainly consist of below fields
+ *
+ * soc_version[30:24] = JEP-106 continuation code for the SiP
+ * soc_version[23:16] = JEP-106 identification code with parity bit for the SiP
+ * soc_version[0:15] = Implementation defined SoC ID
+ */
+int32_t plat_get_soc_version(void)
+{
+ uint32_t soc_version = (QTI_SOC_VERSION & QTI_SOC_VERSION_MASK);
+ uint32_t jep106az_code = (JEDEC_QTI_BKID << QTI_SOC_CONTINUATION_SHIFT)
+ | (JEDEC_QTI_MFID << QTI_SOC_IDENTIFICATION_SHIFT);
+ return (int32_t)(jep106az_code | (soc_version));
+}
+
+/*
+ * This function returns soc revision in below format
+ *
+ * soc_revision[0:30] = SOC revision of specific SOC
+ */
+int32_t plat_get_soc_revision(void)
+{
+ return mmio_read_32(QTI_SOC_REVISION_REG) & QTI_SOC_REVISION_MASK;
+}
+
+/*****************************************************************************
+ * plat_is_smccc_feature_available() - This function checks whether SMCCC feature
+ * is availabile for the platform or not.
+ * @fid: SMCCC function id
+ *
+ * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
+ * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
+ *****************************************************************************/
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+ switch (fid) {
+ case SMCCC_ARCH_SOC_ID:
+ return SMC_ARCH_CALL_SUCCESS;
+ default:
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+ }
+}
diff --git a/plat/qti/common/src/qti_gic_v3.c b/plat/qti/common/src/qti_gic_v3.c
new file mode 100644
index 000000000..a5e0ae7b0
--- /dev/null
+++ b/plat/qti/common/src/qti_gic_v3.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <drivers/arm/gicv3.h>
+
+#include <platform.h>
+#include <platform_def.h>
+#include <qti_plat.h>
+#include <qtiseclib_defs.h>
+#include <qtiseclib_defs_plat.h>
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+/* Array of interrupts to be configured by the gic driver */
+static const interrupt_prop_t qti_interrupt_props[] = {
+ INTR_PROP_DESC(QTISECLIB_INT_ID_CPU_WAKEUP_SGI,
+ GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_RESET_SGI, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_SEC_WDOG_BARK, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_NON_SEC_WDOG_BITE,
+ GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+ GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CLT_SEC,
+ GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CLT_NONSEC,
+ GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CFG_SEC,
+ GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CFG_NONSEC,
+ GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_XPU_SEC, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_XPU_NON_SEC, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+#ifdef QTISECLIB_INT_ID_A1_NOC_ERROR
+ INTR_PROP_DESC(QTISECLIB_INT_ID_A1_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+#endif
+ INTR_PROP_DESC(QTISECLIB_INT_ID_A2_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_CONFIG_NOC_ERROR,
+ GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_DC_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_MEM_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
+ INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_SYSTEM_NOC_ERROR,
+ GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+ INTR_PROP_DESC(QTISECLIB_INT_ID_MMSS_NOC_ERROR,
+ GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+ GIC_INTR_CFG_EDGE),
+};
+
+const gicv3_driver_data_t qti_gic_data = {
+ .gicd_base = QTI_GICD_BASE,
+ .gicr_base = QTI_GICR_BASE,
+ .interrupt_props = qti_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(qti_interrupt_props),
+ .rdistif_num = PLATFORM_CORE_COUNT,
+ .rdistif_base_addrs = rdistif_base_addrs,
+ .mpidr_to_core_pos = plat_qti_core_pos_by_mpidr
+};
+
+void plat_qti_gic_driver_init(void)
+{
+ /*
+ * The GICv3 driver is initialized in EL3 and does not need
+ * to be initialized again in SEL1. This is because the S-EL1
+ * can use GIC system registers to manage interrupts and does
+ * not need GIC interface base addresses to be configured.
+ */
+ gicv3_driver_init(&qti_gic_data);
+}
+
+/******************************************************************************
+ * ARM common helper to initialize the GIC. Only invoked by BL31
+ *****************************************************************************/
+void plat_qti_gic_init(void)
+{
+ unsigned int i;
+
+ gicv3_distif_init();
+ gicv3_rdistif_init(plat_my_core_pos());
+ gicv3_cpuif_enable(plat_my_core_pos());
+
+ /* Route secure spi interrupt to ANY. */
+ for (i = 0; i < ARRAY_SIZE(qti_interrupt_props); i++) {
+ unsigned int int_id = qti_interrupt_props[i].intr_num;
+
+ if (plat_ic_is_spi(int_id)) {
+ gicv3_set_spi_routing(int_id, GICV3_IRM_ANY, 0x0);
+ }
+ }
+}
+
+void gic_set_spi_routing(unsigned int id, unsigned int irm, u_register_t target)
+{
+ gicv3_set_spi_routing(id, irm, target);
+}
+
+/******************************************************************************
+ * ARM common helper to enable the GIC CPU interface
+ *****************************************************************************/
+void plat_qti_gic_cpuif_enable(void)
+{
+ gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * ARM common helper to disable the GIC CPU interface
+ *****************************************************************************/
+void plat_qti_gic_cpuif_disable(void)
+{
+ gicv3_cpuif_disable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * ARM common helper to initialize the per-CPU redistributor interface in GICv3
+ *****************************************************************************/
+void plat_qti_gic_pcpu_init(void)
+{
+ gicv3_rdistif_init(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * ARM common helpers to power GIC redistributor interface
+ *****************************************************************************/
+void plat_qti_gic_redistif_on(void)
+{
+ gicv3_rdistif_on(plat_my_core_pos());
+}
+
+void plat_qti_gic_redistif_off(void)
+{
+ gicv3_rdistif_off(plat_my_core_pos());
+}
diff --git a/plat/qti/common/src/qti_interrupt_svc.c b/plat/qti/common/src/qti_interrupt_svc.c
new file mode 100644
index 000000000..89cd7b555
--- /dev/null
+++ b/plat/qti/common/src/qti_interrupt_svc.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <bl31/interrupt_mgmt.h>
+#include <drivers/arm/gic_common.h>
+#include <lib/el3_runtime/context_mgmt.h>
+
+#include <platform.h>
+#include <qti_interrupt_svc.h>
+#include <qtiseclib_interface.h>
+
+#define QTI_INTR_INVALID_INT_NUM 0xFFFFFFFFU
+
+/*
+ * Top-level EL3 interrupt handler.
+ */
+static uint64_t qti_el3_interrupt_handler(uint32_t id, uint32_t flags,
+ void *handle, void *cookie)
+{
+ uint32_t irq = QTI_INTR_INVALID_INT_NUM;
+
+ /*
+ * EL3 non-interruptible. Interrupt shouldn't occur when we are at
+ * EL3 / Secure.
+ */
+ assert(handle != cm_get_context(SECURE));
+
+ irq = plat_ic_acknowledge_interrupt();
+
+ qtiseclib_invoke_isr(irq, handle);
+
+ /* End of Interrupt. */
+ if (irq < 1022U) {
+ plat_ic_end_of_interrupt(irq);
+ }
+
+ return (uint64_t) handle;
+}
+
+int qti_interrupt_svc_init(void)
+{
+ int ret;
+ uint64_t flags = 0U;
+
+ /*
+ * Route EL3 interrupts to EL3 when in Non-secure.
+ * Note: EL3 won't have interrupt enable
+ * & we don't have S-EL1 support.
+ */
+ set_interrupt_rm_flag(flags, NON_SECURE);
+
+ /* Register handler for EL3 interrupts */
+ ret = register_interrupt_type_handler(INTR_TYPE_EL3,
+ qti_el3_interrupt_handler, flags);
+ assert(ret == 0);
+
+ return ret;
+}
diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c
new file mode 100644
index 000000000..5f1b7aa1d
--- /dev/null
+++ b/plat/qti/common/src/qti_pm.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+
+#include <platform.h>
+#include <platform_def.h>
+#include <qti_cpu.h>
+#include <qti_plat.h>
+#include <qtiseclib_cb_interface.h>
+#include <qtiseclib_defs_plat.h>
+#include <qtiseclib_interface.h>
+
+#define QTI_LOCAL_PSTATE_WIDTH 4
+#define QTI_LOCAL_PSTATE_MASK ((1 << QTI_LOCAL_PSTATE_WIDTH) - 1)
+
+/* Make composite power state parameter till level 0 */
+#define qti_make_pwrstate_lvl0(lvl0_state, type) \
+ (((lvl0_state) << PSTATE_ID_SHIFT) | ((type) << PSTATE_TYPE_SHIFT))
+
+/* Make composite power state parameter till level 1 */
+#define qti_make_pwrstate_lvl1(lvl1_state, lvl0_state, type) \
+ (((lvl1_state) << QTI_LOCAL_PSTATE_WIDTH) | \
+ qti_make_pwrstate_lvl0(lvl0_state, type))
+
+/* Make composite power state parameter till level 2 */
+#define qti_make_pwrstate_lvl2(lvl2_state, lvl1_state, lvl0_state, type) \
+ (((lvl2_state) << (QTI_LOCAL_PSTATE_WIDTH * 2)) | \
+ qti_make_pwrstate_lvl1(lvl1_state, lvl0_state, type))
+
+/* Make composite power state parameter till level 3 */
+#define qti_make_pwrstate_lvl3(lvl3_state, lvl2_state, lvl1_state, lvl0_state, type) \
+ (((lvl3_state) << (QTI_LOCAL_PSTATE_WIDTH * 3)) | \
+ qti_make_pwrstate_lvl2(lvl2_state, lvl1_state, lvl0_state, type))
+
+/* QTI_CORE_PWRDN_EN_MASK happens to be same across all CPUs */
+#define QTI_CORE_PWRDN_EN_MASK 1
+
+/* cpu power control happens to be same across all CPUs */
+_DEFINE_SYSREG_WRITE_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7)
+_DEFINE_SYSREG_READ_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7)
+
+const unsigned int qti_pm_idle_states[] = {
+ qti_make_pwrstate_lvl0(QTI_LOCAL_STATE_OFF,
+ PSTATE_TYPE_POWERDOWN),
+ qti_make_pwrstate_lvl0(QTI_LOCAL_STATE_DEEPOFF,
+ PSTATE_TYPE_POWERDOWN),
+ qti_make_pwrstate_lvl1(QTI_LOCAL_STATE_DEEPOFF,
+ QTI_LOCAL_STATE_DEEPOFF,
+ PSTATE_TYPE_POWERDOWN),
+ qti_make_pwrstate_lvl2(QTI_LOCAL_STATE_OFF,
+ QTI_LOCAL_STATE_DEEPOFF,
+ QTI_LOCAL_STATE_DEEPOFF,
+ PSTATE_TYPE_POWERDOWN),
+ qti_make_pwrstate_lvl3(QTI_LOCAL_STATE_OFF,
+ QTI_LOCAL_STATE_DEEPOFF,
+ QTI_LOCAL_STATE_DEEPOFF,
+ QTI_LOCAL_STATE_DEEPOFF,
+ PSTATE_TYPE_POWERDOWN),
+ 0,
+};
+
+/*******************************************************************************
+ * QTI standard platform handler called to check the validity of the power
+ * state parameter. The power state parameter has to be a composite power
+ * state.
+ ******************************************************************************/
+int qti_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state)
+{
+ unsigned int state_id;
+ int i;
+
+ assert(req_state);
+
+ /*
+ * Currently we are using a linear search for finding the matching
+ * entry in the idle power state array. This can be made a binary
+ * search if the number of entries justify the additional complexity.
+ */
+ for (i = 0; !!qti_pm_idle_states[i]; i++) {
+ if (power_state == qti_pm_idle_states[i])
+ break;
+ }
+
+ /* Return error if entry not found in the idle state array */
+ if (!qti_pm_idle_states[i])
+ return PSCI_E_INVALID_PARAMS;
+
+ i = 0;
+ state_id = psci_get_pstate_id(power_state);
+
+ /* Parse the State ID and populate the state info parameter */
+ while (state_id) {
+ req_state->pwr_domain_state[i++] = state_id &
+ QTI_LOCAL_PSTATE_MASK;
+ state_id >>= QTI_LOCAL_PSTATE_WIDTH;
+ }
+
+ return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * PLATFORM FUNCTIONS
+ ******************************************************************************/
+
+static void qti_set_cpupwrctlr_val(void)
+{
+ unsigned long val;
+
+ val = read_cpu_pwrctrl_val();
+ val |= QTI_CORE_PWRDN_EN_MASK;
+ write_cpu_pwrctrl_val(val);
+
+ isb();
+}
+
+/**
+ * CPU power on function - ideally we want a wrapper since this function is
+ * target specific. But to unblock teams.
+ */
+static int qti_cpu_power_on(u_register_t mpidr)
+{
+ int core_pos = plat_core_pos_by_mpidr(mpidr);
+
+ /* If not valid mpidr, return error */
+ if (core_pos < 0 || core_pos >= QTISECLIB_PLAT_CORE_COUNT) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+
+ return qtiseclib_psci_node_power_on(mpidr);
+}
+
+static bool is_cpu_off(const psci_power_state_t *target_state)
+{
+ if ((target_state->pwr_domain_state[QTI_PWR_LVL0] ==
+ QTI_LOCAL_STATE_OFF) ||
+ (target_state->pwr_domain_state[QTI_PWR_LVL0] ==
+ QTI_LOCAL_STATE_DEEPOFF)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static void qti_cpu_power_on_finish(const psci_power_state_t *target_state)
+{
+ const uint8_t *pwr_states =
+ (const uint8_t *)target_state->pwr_domain_state;
+ qtiseclib_psci_node_on_finish(pwr_states);
+
+ if (is_cpu_off(target_state)) {
+ plat_qti_gic_cpuif_enable();
+ }
+}
+
+static void qti_cpu_standby(plat_local_state_t cpu_state)
+{
+}
+
+static void qti_node_power_off(const psci_power_state_t *target_state)
+{
+ qtiseclib_psci_node_power_off((const uint8_t *)
+ target_state->pwr_domain_state);
+ if (is_cpu_off(target_state)) {
+ plat_qti_gic_cpuif_disable();
+ qti_set_cpupwrctlr_val();
+ }
+}
+
+static void qti_node_suspend(const psci_power_state_t *target_state)
+{
+ qtiseclib_psci_node_suspend((const uint8_t *)target_state->
+ pwr_domain_state);
+ if (is_cpu_off(target_state)) {
+ plat_qti_gic_cpuif_disable();
+ qti_set_cpupwrctlr_val();
+ }
+}
+
+static void qti_node_suspend_finish(const psci_power_state_t *target_state)
+{
+ const uint8_t *pwr_states =
+ (const uint8_t *)target_state->pwr_domain_state;
+ qtiseclib_psci_node_suspend_finish(pwr_states);
+ if (is_cpu_off(target_state)) {
+ plat_qti_gic_cpuif_enable();
+ }
+}
+
+__dead2 void qti_domain_power_down_wfi(const psci_power_state_t *target_state)
+{
+
+ /* For now just do WFI - add any target specific handling if needed */
+ psci_power_down_wfi();
+ /* We should never reach here */
+}
+
+static __dead2 void assert_ps_hold(void)
+{
+ mmio_write_32(QTI_PS_HOLD_REG, 0);
+ mdelay(1000);
+
+ /* Should be dead before reaching this. */
+ panic();
+}
+
+__dead2 void qti_system_off(void)
+{
+ qti_pmic_prepare_shutdown();
+ assert_ps_hold();
+}
+
+__dead2 void qti_system_reset(void)
+{
+ qti_pmic_prepare_reset();
+ assert_ps_hold();
+}
+
+void qti_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+ int i = 0;
+ unsigned int state_id, power_state;
+ int size = ARRAY_SIZE(qti_pm_idle_states);
+
+ /*
+ * Find deepest state.
+ * The arm_pm_idle_states[] array has last element by default 0,
+ * so the real deepest state is second last element of that array.
+ */
+ power_state = qti_pm_idle_states[size - 2];
+ state_id = psci_get_pstate_id(power_state);
+
+ /* Parse the State ID and populate the state info parameter */
+ while (state_id) {
+ req_state->pwr_domain_state[i++] =
+ state_id & QTI_LOCAL_PSTATE_MASK;
+ state_id >>= QTI_LOCAL_PSTATE_WIDTH;
+ }
+}
+
+/*
+ * Structure containing platform specific PSCI operations. Common
+ * PSCI layer will use this.
+ */
+const plat_psci_ops_t plat_qti_psci_pm_ops = {
+ .pwr_domain_on = qti_cpu_power_on,
+ .pwr_domain_on_finish = qti_cpu_power_on_finish,
+ .cpu_standby = qti_cpu_standby,
+ .pwr_domain_off = qti_node_power_off,
+ .pwr_domain_suspend = qti_node_suspend,
+ .pwr_domain_suspend_finish = qti_node_suspend_finish,
+ .pwr_domain_pwr_down_wfi = qti_domain_power_down_wfi,
+ .system_off = qti_system_off,
+ .system_reset = qti_system_reset,
+ .get_node_hw_state = NULL,
+ .translate_power_state_by_mpidr = NULL,
+ .get_sys_suspend_power_state = qti_get_sys_suspend_power_state,
+ .validate_power_state = qti_validate_power_state,
+};
+
+/**
+ * The QTI Standard platform definition of platform porting API
+ * `plat_setup_psci_ops`.
+ */
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ int err;
+
+ err = qtiseclib_psci_init((uintptr_t)bl31_warm_entrypoint);
+ if (err == PSCI_E_SUCCESS) {
+ *psci_ops = &plat_qti_psci_pm_ops;
+ }
+
+ return err;
+}
diff --git a/plat/qti/common/src/qti_rng.c b/plat/qti/common/src/qti_rng.c
new file mode 100644
index 000000000..f63f3b85d
--- /dev/null
+++ b/plat/qti/common/src/qti_rng.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stddef.h>
+
+#include <lib/mmio.h>
+
+#include <qti_rng.h>
+#include <qti_rng_io.h>
+
+int qti_rng_get_data(uint8_t *out, uint32_t out_len)
+{
+ uint32_t tmp_rndm = 0;
+ uint32_t bytes_left = out_len;
+ int i = 0;
+
+ if (NULL == out || 0 == out_len) {
+ return -1;
+ }
+
+ /*
+ * RNG HW initialized at previous boot image.
+ * RNG clocks are expected to be ON.
+ */
+
+ do {
+ /* There is no data to read */
+ if ((mmio_read_32(SEC_PRNG_STATUS) &
+ SEC_PRNG_STATUS_DATA_AVAIL_BMSK) == 0) {
+ continue;
+ }
+
+ while ((tmp_rndm = mmio_read_32(SEC_PRNG_DATA_OUT)) == 0) {
+ ;
+ }
+
+ for (i = 0; i < 4; i++) {
+ *out = (uint8_t) (tmp_rndm >> (8 * i));
+
+ out++;
+ bytes_left--;
+
+ if (bytes_left == 0) {
+ break;
+ }
+ }
+
+ } while (bytes_left != 0);
+
+ return 0;
+}
diff --git a/plat/qti/common/src/qti_stack_protector.c b/plat/qti/common/src/qti_stack_protector.c
new file mode 100644
index 000000000..572830f9c
--- /dev/null
+++ b/plat/qti/common/src/qti_stack_protector.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <platform.h>
+#include <platform_def.h>
+#include <qti_rng.h>
+#include <qtiseclib_interface.h>
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ u_register_t random = 0x0;
+
+ /*
+ * get random data , the below API doesn't return random = 0 on success
+ */
+ qti_rng_get_data((uint8_t *) &random, sizeof(random));
+ assert(random != 0x0);
+
+ return random;
+}
diff --git a/plat/qti/common/src/qti_syscall.c b/plat/qti/common/src/qti_syscall.c
new file mode 100644
index 000000000..a7601b657
--- /dev/null
+++ b/plat/qti/common/src/qti_syscall.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <context.h>
+#include <lib/coreboot.h>
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <smccc_helpers.h>
+#include <tools_share/uuid.h>
+
+#include <qti_plat.h>
+#include <qti_secure_io_cfg.h>
+#include <qtiseclib_interface.h>
+/*
+ * SIP service - SMC function IDs for SiP Service queries
+ *
+ */
+#define QTI_SIP_SVC_CALL_COUNT_ID U(0x0200ff00)
+#define QTI_SIP_SVC_UID_ID U(0x0200ff01)
+/* 0x8200ff02 is reserved*/
+#define QTI_SIP_SVC_VERSION_ID U(0x0200ff03)
+
+/*
+ * Syscall's to allow Non Secure world accessing peripheral/IO memory
+ * those are secure/proteced BUT not required to be secure.
+ */
+#define QTI_SIP_SVC_SECURE_IO_READ_ID U(0x02000501)
+#define QTI_SIP_SVC_SECURE_IO_WRITE_ID U(0x02000502)
+
+/*
+ * Syscall's to assigns a list of intermediate PAs from a
+ * source Virtual Machine (VM) to a destination VM.
+ */
+#define QTI_SIP_SVC_MEM_ASSIGN_ID U(0x02000C16)
+
+#define QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID U(0x1)
+#define QTI_SIP_SVC_SECURE_IO_WRITE_PARAM_ID U(0x2)
+#define QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID U(0x1117)
+
+#define QTI_SIP_SVC_CALL_COUNT U(0x3)
+#define QTI_SIP_SVC_VERSION_MAJOR U(0x0)
+#define QTI_SIP_SVC_VERSION_MINOR U(0x0)
+
+#define QTI_VM_LAST U(44)
+#define SIZE4K U(0x1000)
+#define QTI_VM_MAX_LIST_SIZE U(0x20)
+
+#define FUNCID_OEN_NUM_MASK ((FUNCID_OEN_MASK << FUNCID_OEN_SHIFT)\
+ |(FUNCID_NUM_MASK << FUNCID_NUM_SHIFT))
+
+enum {
+ QTI_SIP_SUCCESS = 0,
+ QTI_SIP_NOT_SUPPORTED = -1,
+ QTI_SIP_PREEMPTED = -2,
+ QTI_SIP_INVALID_PARAM = -3,
+};
+
+/* QTI SiP Service UUID */
+DEFINE_SVC_UUID2(qti_sip_svc_uid,
+ 0x43864748, 0x217f, 0x41ad, 0xaa, 0x5a,
+ 0xba, 0xe7, 0x0f, 0xa5, 0x52, 0xaf);
+
+static bool qti_is_secure_io_access_allowed(u_register_t addr)
+{
+ int i = 0;
+
+ for (i = 0; i < ARRAY_SIZE(qti_secure_io_allowed_regs); i++) {
+ if ((uintptr_t) addr == qti_secure_io_allowed_regs[i]) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool qti_mem_assign_validate_param(memprot_info_t *mem_info,
+ u_register_t u_num_mappings,
+ uint32_t *source_vm_list,
+ u_register_t src_vm_list_cnt,
+ memprot_dst_vm_perm_info_t *dest_vm_list,
+ u_register_t dst_vm_list_cnt)
+{
+ int i;
+
+ if (!source_vm_list || !dest_vm_list || !mem_info
+ || (src_vm_list_cnt == 0)
+ || (src_vm_list_cnt >= QTI_VM_LAST) || (dst_vm_list_cnt == 0)
+ || (dst_vm_list_cnt >= QTI_VM_LAST) || (u_num_mappings == 0)
+ || u_num_mappings > QTI_VM_MAX_LIST_SIZE) {
+ ERROR("vm count is 0 or more then QTI_VM_LAST or empty list\n");
+ ERROR("source_vm_list %p dest_vm_list %p mem_info %p src_vm_list_cnt %u dst_vm_list_cnt %u u_num_mappings %u\n",
+ source_vm_list, dest_vm_list, mem_info,
+ (unsigned int)src_vm_list_cnt,
+ (unsigned int)dst_vm_list_cnt,
+ (unsigned int)u_num_mappings);
+ return false;
+ }
+ for (i = 0; i < u_num_mappings; i++) {
+ if ((mem_info[i].mem_addr & (SIZE4K - 1))
+ || (mem_info[i].mem_size == 0)
+ || (mem_info[i].mem_size & (SIZE4K - 1))) {
+ ERROR("mem_info passed buffer 0x%x or size 0x%x is not 4k aligned\n",
+ (unsigned int)mem_info[i].mem_addr,
+ (unsigned int)mem_info[i].mem_size);
+ return false;
+ }
+
+ if ((mem_info[i].mem_addr + mem_info[i].mem_size) <
+ mem_info[i].mem_addr) {
+ ERROR("overflow in mem_addr 0x%x add mem_size 0x%x\n",
+ (unsigned int)mem_info[i].mem_addr,
+ (unsigned int)mem_info[i].mem_size);
+ return false;
+ }
+ coreboot_memory_t mem_type = coreboot_get_memory_type(
+ mem_info[i].mem_addr,
+ mem_info[i].mem_size);
+ if (mem_type != CB_MEM_RAM && mem_type != CB_MEM_RESERVED) {
+ ERROR("memory region not in CB MEM RAM or RESERVED area: region start 0x%x size 0x%x\n",
+ (unsigned int)mem_info[i].mem_addr,
+ (unsigned int)mem_info[i].mem_size);
+ return false;
+ }
+ }
+ for (i = 0; i < src_vm_list_cnt; i++) {
+ if (source_vm_list[i] >= QTI_VM_LAST) {
+ ERROR("source_vm_list[%d] 0x%x is more then QTI_VM_LAST\n",
+ i, (unsigned int)source_vm_list[i]);
+ return false;
+ }
+ }
+ for (i = 0; i < dst_vm_list_cnt; i++) {
+ if (dest_vm_list[i].dst_vm >= QTI_VM_LAST) {
+ ERROR("dest_vm_list[%d] 0x%x is more then QTI_VM_LAST\n",
+ i, (unsigned int)dest_vm_list[i].dst_vm);
+ return false;
+ }
+ }
+ return true;
+}
+
+static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3, u_register_t x4)
+{
+ uintptr_t dyn_map_start = 0, dyn_map_end = 0;
+ size_t dyn_map_size = 0;
+ u_register_t x6, x7;
+ int ret = QTI_SIP_NOT_SUPPORTED;
+ u_register_t x5 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X5);
+
+ if (smc_cc == SMC_32) {
+ x5 = (uint32_t) x5;
+ }
+ /* Validate input arg count & retrieve arg3-6 from NS Buffer. */
+ if ((x1 != QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID) || (x5 == 0x0)) {
+ ERROR("invalid mem_assign param id or no mapping info\n");
+ goto unmap_return;
+ }
+
+ /* Map NS Buffer. */
+ dyn_map_start = x5;
+ dyn_map_size =
+ (smc_cc ==
+ SMC_32) ? (sizeof(uint32_t) * 4) : (sizeof(uint64_t) * 4);
+ if (qti_mmap_add_dynamic_region(dyn_map_start, dyn_map_size,
+ (MT_NS | MT_RO_DATA)) != 0) {
+ ERROR("map failed for params NS Buffer %x %x\n",
+ (unsigned int)dyn_map_start, (unsigned int)dyn_map_size);
+ goto unmap_return;
+ }
+ /* Retrieve indirect args. */
+ if (smc_cc == SMC_32) {
+ x6 = *((uint32_t *) x5 + 1);
+ x7 = *((uint32_t *) x5 + 2);
+ x5 = *(uint32_t *) x5;
+ } else {
+ x6 = *((uint64_t *) x5 + 1);
+ x7 = *((uint64_t *) x5 + 2);
+ x5 = *(uint64_t *) x5;
+ }
+ /* Un-Map NS Buffer. */
+ if (qti_mmap_remove_dynamic_region(dyn_map_start, dyn_map_size) != 0) {
+ ERROR("unmap failed for params NS Buffer %x %x\n",
+ (unsigned int)dyn_map_start, (unsigned int)dyn_map_size);
+ goto unmap_return;
+ }
+
+ /*
+ * Map NS Buffers.
+ * arg0,2,4 points to buffers & arg1,3,5 hold sizes.
+ * MAP api's fail to map if it's already mapped. Let's
+ * find lowest start & highest end address, then map once.
+ */
+ dyn_map_start = MIN(x2, x4);
+ dyn_map_start = MIN(dyn_map_start, x6);
+ dyn_map_end = MAX((x2 + x3), (x4 + x5));
+ dyn_map_end = MAX(dyn_map_end, (x6 + x7));
+ dyn_map_size = dyn_map_end - dyn_map_start;
+
+ if (qti_mmap_add_dynamic_region(dyn_map_start, dyn_map_size,
+ (MT_NS | MT_RO_DATA)) != 0) {
+ ERROR("map failed for params NS Buffer2 %x %x\n",
+ (unsigned int)dyn_map_start, (unsigned int)dyn_map_size);
+ goto unmap_return;
+ }
+ memprot_info_t *mem_info_p = (memprot_info_t *) x2;
+ uint32_t u_num_mappings = x3 / sizeof(memprot_info_t);
+ uint32_t *source_vm_list_p = (uint32_t *) x4;
+ uint32_t src_vm_list_cnt = x5 / sizeof(uint32_t);
+ memprot_dst_vm_perm_info_t *dest_vm_list_p =
+ (memprot_dst_vm_perm_info_t *) x6;
+ uint32_t dst_vm_list_cnt =
+ x7 / sizeof(memprot_dst_vm_perm_info_t);
+ if (qti_mem_assign_validate_param(mem_info_p, u_num_mappings,
+ source_vm_list_p, src_vm_list_cnt,
+ dest_vm_list_p,
+ dst_vm_list_cnt) != true) {
+ ERROR("Param validation failed\n");
+ goto unmap_return;
+ }
+
+ memprot_info_t mem_info[QTI_VM_MAX_LIST_SIZE];
+ /* Populating the arguments */
+ for (int i = 0; i < u_num_mappings; i++) {
+ mem_info[i].mem_addr = mem_info_p[i].mem_addr;
+ mem_info[i].mem_size = mem_info_p[i].mem_size;
+ }
+
+ memprot_dst_vm_perm_info_t dest_vm_list[QTI_VM_LAST];
+
+ for (int i = 0; i < dst_vm_list_cnt; i++) {
+ dest_vm_list[i].dst_vm = dest_vm_list_p[i].dst_vm;
+ dest_vm_list[i].dst_vm_perm = dest_vm_list_p[i].dst_vm_perm;
+ dest_vm_list[i].ctx = dest_vm_list_p[i].ctx;
+ dest_vm_list[i].ctx_size = dest_vm_list_p[i].ctx_size;
+ }
+
+ uint32_t source_vm_list[QTI_VM_LAST];
+
+ for (int i = 0; i < src_vm_list_cnt; i++) {
+ source_vm_list[i] = source_vm_list_p[i];
+ }
+ /* Un-Map NS Buffers. */
+ if (qti_mmap_remove_dynamic_region(dyn_map_start,
+ dyn_map_size) != 0) {
+ ERROR("unmap failed for params NS Buffer %x %x\n",
+ (unsigned int)dyn_map_start, (unsigned int)dyn_map_size);
+ goto unmap_return;
+ }
+ /* Invoke API lib api. */
+ ret = qtiseclib_mem_assign(mem_info, u_num_mappings,
+ source_vm_list, src_vm_list_cnt,
+ dest_vm_list, dst_vm_list_cnt);
+
+ if (ret == 0) {
+ SMC_RET2(handle, QTI_SIP_SUCCESS, ret);
+ }
+unmap_return:
+ /* Un-Map NS Buffers if mapped */
+ if (dyn_map_start && dyn_map_size) {
+ qti_mmap_remove_dynamic_region(dyn_map_start, dyn_map_size);
+ }
+
+ SMC_RET2(handle, QTI_SIP_INVALID_PARAM, ret);
+}
+
+/*
+ * This function handles QTI specific syscalls. Currently only SiP calls are present.
+ * Both FAST & YIELD type call land here.
+ */
+static uintptr_t qti_sip_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie, void *handle, u_register_t flags)
+{
+ uint32_t l_smc_fid = smc_fid & FUNCID_OEN_NUM_MASK;
+
+ if (GET_SMC_CC(smc_fid) == SMC_32) {
+ x1 = (uint32_t) x1;
+ x2 = (uint32_t) x2;
+ x3 = (uint32_t) x3;
+ x4 = (uint32_t) x4;
+ }
+
+ switch (l_smc_fid) {
+ case QTI_SIP_SVC_CALL_COUNT_ID:
+ {
+ SMC_RET1(handle, QTI_SIP_SVC_CALL_COUNT);
+ break;
+ }
+ case QTI_SIP_SVC_UID_ID:
+ {
+ /* Return UID to the caller */
+ SMC_UUID_RET(handle, qti_sip_svc_uid);
+ break;
+ }
+ case QTI_SIP_SVC_VERSION_ID:
+ {
+ /* Return the version of current implementation */
+ SMC_RET2(handle, QTI_SIP_SVC_VERSION_MAJOR,
+ QTI_SIP_SVC_VERSION_MINOR);
+ break;
+ }
+ case QTI_SIP_SVC_SECURE_IO_READ_ID:
+ {
+ if ((x1 == QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID) &&
+ qti_is_secure_io_access_allowed(x2)) {
+ SMC_RET2(handle, QTI_SIP_SUCCESS,
+ *((volatile uint32_t *)x2));
+ }
+ SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
+ break;
+ }
+ case QTI_SIP_SVC_SECURE_IO_WRITE_ID:
+ {
+ if ((x1 == QTI_SIP_SVC_SECURE_IO_WRITE_PARAM_ID) &&
+ qti_is_secure_io_access_allowed(x2)) {
+ *((volatile uint32_t *)x2) = x3;
+ SMC_RET1(handle, QTI_SIP_SUCCESS);
+ }
+ SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
+ break;
+ }
+ case QTI_SIP_SVC_MEM_ASSIGN_ID:
+ {
+ return qti_sip_mem_assign(handle, GET_SMC_CC(smc_fid),
+ x1, x2, x3, x4);
+ break;
+ }
+ default:
+ {
+ SMC_RET1(handle, QTI_SIP_NOT_SUPPORTED);
+ }
+ }
+ return (uintptr_t) handle;
+}
+
+/* Define a runtime service descriptor for both fast & yield SiP calls */
+DECLARE_RT_SVC(qti_sip_fast_svc, OEN_SIP_START,
+ OEN_SIP_END, SMC_TYPE_FAST, NULL, qti_sip_handler);
+
+DECLARE_RT_SVC(qti_sip_yield_svc, OEN_SIP_START,
+ OEN_SIP_END, SMC_TYPE_YIELD, NULL, qti_sip_handler);
diff --git a/plat/qti/common/src/qti_topology.c b/plat/qti/common/src/qti_topology.c
new file mode 100644
index 000000000..bf2e3f3b7
--- /dev/null
+++ b/plat/qti/common/src/qti_topology.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+
+#include <platform_def.h>
+#include <qti_plat.h>
+
+/* The QTI power domain tree descriptor */
+const unsigned char qti_power_domain_tree_desc[] = {
+ /* One domain to represent PDC */
+ PLAT_PDC_COUNT,
+ /* One domain to represent RSC */
+ PLAT_RSC_COUNT,
+ /* There is one top-level FCM cluster */
+ PLAT_CLUSTER_COUNT,
+ /* No. of cores in the FCM cluster */
+ PLAT_CLUSTER0_CORE_COUNT
+};
+
+/*******************************************************************************
+ * This function returns the ARM default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return qti_power_domain_tree_desc;
+}
+
+/** Function: plat_core_pos_by_mpidr
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ */
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+ int core_linear_index = plat_qti_core_pos_by_mpidr(mpidr);
+
+ if (core_linear_index < PLATFORM_CORE_COUNT) {
+ return core_linear_index;
+ } else {
+ return -1;
+ }
+}
diff --git a/plat/qti/common/src/spmi_arb.c b/plat/qti/common/src/spmi_arb.c
new file mode 100644
index 000000000..16e85a6fc
--- /dev/null
+++ b/plat/qti/common/src/spmi_arb.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <spmi_arb.h>
+
+#define REG_APID_MAP(apid) (0x0C440900U + 4U * i)
+#define NUM_APID 0x80
+
+#define PPID_MASK (0xfffU << 8)
+
+#define REG_ARB_CMD(apid) (0x0C600000U + 0x10000U * apid)
+/* These are opcodes specific to this SPMI arbitrator, *not* SPMI commands. */
+#define OPC_EXT_WRITEL 0
+#define OPC_EXT_READL 1
+
+#define REG_ARB_STATUS(apid) (0x0C600008U + 0x10000U * apid)
+#define ARB_STATUS_DONE BIT(0)
+#define ARB_STATUS_FAILURE BIT(1)
+#define ARB_STATUS_DENIED BIT(2)
+#define ARB_STATUS_DROPPED BIT(3)
+
+/* Fake status to report driver errors. */
+#define ARB_FAKE_STATUS_TIMEOUT BIT(8)
+
+#define REG_ARB_RDATA0(apid) (0x0C600018U + 0x10000U * apid)
+#define REG_ARB_WDATA0(apid) (0x0C600010U + 0x10000U * apid)
+
+static int addr_to_apid(uint32_t addr)
+{
+ unsigned int i;
+
+ for (i = 0U; i < NUM_APID; i++) {
+ uint32_t reg = mmio_read_32(REG_APID_MAP(i));
+ if ((reg != 0U) && ((addr & PPID_MASK) == (reg & PPID_MASK))) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static int wait_for_done(uint16_t apid)
+{
+ unsigned int timeout = 100;
+
+ while (timeout-- != 0U) {
+ uint32_t status = mmio_read_32(REG_ARB_STATUS(apid));
+ if ((status & ARB_STATUS_DONE) != 0U) {
+ if ((status & ARB_STATUS_FAILURE) != 0U ||
+ (status & ARB_STATUS_DENIED) != 0U ||
+ (status & ARB_STATUS_DROPPED) != 0U) {
+ return status & 0xff;
+ }
+ return 0;
+ }
+ mdelay(1);
+ }
+ ERROR("SPMI_ARB timeout!\n");
+ return ARB_FAKE_STATUS_TIMEOUT;
+}
+
+static void arb_command(uint16_t apid, uint8_t opcode, uint32_t addr,
+ uint8_t bytes)
+{
+ mmio_write_32(REG_ARB_CMD(apid), (uint32_t)opcode << 27 |
+ (addr & 0xff) << 4 | (bytes - 1));
+}
+
+int spmi_arb_read8(uint32_t addr)
+{
+ int apid = addr_to_apid(addr);
+
+ if (apid < 0) {
+ return apid;
+ }
+
+ arb_command(apid, OPC_EXT_READL, addr, 1);
+
+ int ret = wait_for_done(apid);
+ if (ret != 0) {
+ ERROR("SPMI_ARB read error [0x%x]: 0x%x\n", addr, ret);
+ return ret;
+ }
+
+ return mmio_read_32(REG_ARB_RDATA0(apid)) & 0xff;
+}
+
+int spmi_arb_write8(uint32_t addr, uint8_t data)
+{
+ int apid = addr_to_apid(addr);
+
+ if (apid < 0) {
+ return apid;
+ }
+
+ mmio_write_32(REG_ARB_WDATA0(apid), data);
+ arb_command(apid, OPC_EXT_WRITEL, addr, 1);
+
+ int ret = wait_for_done(apid);
+ if (ret != 0) {
+ ERROR("SPMI_ARB write error [0x%x] = 0x%x: 0x%x\n",
+ addr, data, ret);
+ }
+
+ return ret;
+}
diff --git a/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h
new file mode 100644
index 000000000..deef41c5b
--- /dev/null
+++ b/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTISECLIB_CB_INTERFACE_H
+#define QTISECLIB_CB_INTERFACE_H
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <qtiseclib_defs.h>
+
+/* Standard Library API's */
+void *qtiseclib_cb_memcpy(void *dst, const void *src, size_t len);
+int qtiseclib_cb_strcmp(const char *s1, const char *s2);
+void *qtiseclib_cb_memset(void *s, int c, size_t n);
+void *qtiseclib_cb_memmove(void *dest, const void *src, size_t n);
+
+#define QTISECLIB_CB_ERROR(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_ERROR, __VA_ARGS__)
+#define QTISECLIB_CB_NOTICE(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_NOTICE, __VA_ARGS__)
+#define QTISECLIB_CB_WARN(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_WARNING, __VA_ARGS__)
+#define QTISECLIB_CB_INFO(...) qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_INFO, __VA_ARGS__)
+
+void qtiseclib_cb_log(unsigned int loglvl, const char *fmt, ...);
+
+void qtiseclib_cb_spin_lock(qtiseclib_cb_spinlock_t *lock);
+void qtiseclib_cb_spin_unlock(qtiseclib_cb_spinlock_t *lock);
+
+unsigned int qtiseclib_cb_plat_my_core_pos(void);
+int qtiseclib_cb_plat_core_pos_by_mpidr(u_register_t mpidr);
+unsigned int qtiseclib_cb_plat_my_cluster_pos(void);
+
+/* GIC platform wrappers */
+void qtiseclib_cb_gic_pcpu_init(void);
+void qtiseclib_cb_ic_raise_sgi(int sgi_num, u_register_t target);
+void qtiseclib_cb_set_spi_routing(unsigned int id, unsigned int irm,
+ u_register_t target);
+/* Crash reporting api's wrappers */
+void qtiseclib_cb_switch_console_to_crash_state(void);
+
+void qtiseclib_cb_udelay(uint32_t usec);
+
+void qtiseclib_cb_console_flush(void);
+
+#if QTI_SDI_BUILD
+int qtiseclib_cb_mmap_remove_dynamic_region(uintptr_t base_va, size_t size);
+int qtiseclib_cb_mmap_add_dynamic_region(unsigned long long base_pa,
+ size_t size,
+ qtiseclib_mmap_attr_t attr);
+
+void qtiseclib_cb_flush_dcache_all(void);
+void qtiseclib_cb_get_ns_ctx(qtiseclib_dbg_a64_ctxt_regs_type *ns_ctx);
+#endif
+
+#endif /* QTISECLIB_CB_INTERFACE_H */
diff --git a/plat/qti/qtiseclib/inc/qtiseclib_defs.h b/plat/qti/qtiseclib/inc/qtiseclib_defs.h
new file mode 100644
index 000000000..2afefe1c8
--- /dev/null
+++ b/plat/qti/qtiseclib/inc/qtiseclib_defs.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTISECLIB_DEFS_H
+#define QTISECLIB_DEFS_H
+
+#include <stdint.h>
+
+#ifndef u_register_t
+typedef uintptr_t u_register_t;
+#endif
+
+/*
+ * Different Log Level supported in qtiseclib.
+ * TODO: Currently no filtering done on QTISECLIB logs.
+ */
+#define QTISECLIB_LOG_LEVEL_NONE 0
+#define QTISECLIB_LOG_LEVEL_ERROR 10
+#define QTISECLIB_LOG_LEVEL_NOTICE 20
+#define QTISECLIB_LOG_LEVEL_WARNING 30
+#define QTISECLIB_LOG_LEVEL_INFO 40
+#define QTISECLIB_LOG_LEVEL_VERBOSE 50
+
+#define QTI_GICV3_IRM_PE 0
+#define QTI_GICV3_IRM_ANY 1
+
+/* Common interrupt number/ID defs. */
+#define QTISECLIB_INT_ID_RESET_SGI (0xf)
+#define QTISECLIB_INT_ID_CPU_WAKEUP_SGI (0x8)
+
+#define QTISECLIB_INT_INVALID_INT_NUM (0xFFFFFFFFU)
+
+typedef struct qtiseclib_cb_spinlock {
+ volatile uint32_t lock;
+} qtiseclib_cb_spinlock_t;
+
+#if QTI_SDI_BUILD
+/* External CPU Dump Structure - 64 bit EL */
+typedef struct {
+ uint64_t x0;
+ uint64_t x1;
+ uint64_t x2;
+ uint64_t x3;
+ uint64_t x4;
+ uint64_t x5;
+ uint64_t x6;
+ uint64_t x7;
+ uint64_t x8;
+ uint64_t x9;
+ uint64_t x10;
+ uint64_t x11;
+ uint64_t x12;
+ uint64_t x13;
+ uint64_t x14;
+ uint64_t x15;
+ uint64_t x16;
+ uint64_t x17;
+ uint64_t x18;
+ uint64_t x19;
+ uint64_t x20;
+ uint64_t x21;
+ uint64_t x22;
+ uint64_t x23;
+ uint64_t x24;
+ uint64_t x25;
+ uint64_t x26;
+ uint64_t x27;
+ uint64_t x28;
+ uint64_t x29;
+ uint64_t x30;
+ uint64_t pc;
+ uint64_t currentEL;
+ uint64_t sp_el3;
+ uint64_t elr_el3;
+ uint64_t spsr_el3;
+ uint64_t sp_el2;
+ uint64_t elr_el2;
+ uint64_t spsr_el2;
+ uint64_t sp_el1;
+ uint64_t elr_el1;
+ uint64_t spsr_el1;
+ uint64_t sp_el0;
+ uint64_t __reserved1;
+ uint64_t __reserved2;
+ uint64_t __reserved3;
+ uint64_t __reserved4;
+ uint64_t __reserved5;
+ uint64_t __reserved6;
+ uint64_t __reserved7;
+ uint64_t __reserved8;
+} qtiseclib_dbg_a64_ctxt_regs_type;
+
+typedef enum qtiseclib_mmap_attr_s {
+ QTISECLIB_MAP_NS_RO_XN_DATA = 1,
+ QTISECLIB_MAP_RW_XN_NC_DATA = 2,
+ QTISECLIB_MAP_RW_XN_DATA = 3,
+} qtiseclib_mmap_attr_t;
+
+#endif /* QTI_SDI_BUILD */
+
+#endif /* QTISECLIB_DEFS_H */
diff --git a/plat/qti/qtiseclib/inc/qtiseclib_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_interface.h
new file mode 100644
index 000000000..315bd6bc7
--- /dev/null
+++ b/plat/qti/qtiseclib/inc/qtiseclib_interface.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTISECLIB_INTERFACE_H
+#define QTISECLIB_INTERFACE_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <qtiseclib_defs.h>
+
+typedef struct memprot_ipa_info_s {
+ uint64_t mem_addr;
+ uint64_t mem_size;
+} memprot_info_t;
+
+typedef struct memprot_dst_vm_perm_info_s {
+ uint32_t dst_vm;
+ uint32_t dst_vm_perm;
+ uint64_t ctx;
+ uint32_t ctx_size;
+} memprot_dst_vm_perm_info_t;
+
+/*
+ * QTISECLIB Published API's.
+ */
+
+/*
+ * Assembly API's
+ */
+
+/*
+ * CPUSS common reset handler for all CPU wake up (both cold & warm boot).
+ * Executes on all core. This API assume serialization across CPU
+ * already taken care before invoking.
+ *
+ * Clobbers: x0 - x17, x30
+ */
+void qtiseclib_cpuss_reset_asm(uint32_t bl31_cold_boot_state);
+
+/*
+ * Execute CPU (Kryo4 gold) specific reset handler / system initialization.
+ * This takes care of executing required CPU errata's.
+ *
+ * Clobbers: x0 - x16
+ */
+void qtiseclib_kryo4_gold_reset_asm(void);
+
+/*
+ * Execute CPU (Kryo4 silver) specific reset handler / system initialization.
+ * This takes care of executing required CPU errata's.
+ *
+ * Clobbers: x0 - x16
+ */
+void qtiseclib_kryo4_silver_reset_asm(void);
+
+/*
+ * C Api's
+ */
+void qtiseclib_bl31_platform_setup(void);
+void qtiseclib_invoke_isr(uint32_t irq, void *handle);
+void qtiseclib_panic(void);
+
+int qtiseclib_mem_assign(const memprot_info_t *mem_info,
+ uint32_t mem_info_list_cnt,
+ const uint32_t *source_vm_list,
+ uint32_t src_vm_list_cnt,
+ const memprot_dst_vm_perm_info_t *dest_vm_list,
+ uint32_t dst_vm_list_cnt);
+
+int qtiseclib_psci_init(uintptr_t warmboot_entry);
+int qtiseclib_psci_node_power_on(u_register_t mpidr);
+void qtiseclib_psci_node_on_finish(const uint8_t *states);
+void qtiseclib_psci_cpu_standby(uint8_t pwr_state);
+void qtiseclib_psci_node_power_off(const uint8_t *states);
+void qtiseclib_psci_node_suspend(const uint8_t *states);
+void qtiseclib_psci_node_suspend_finish(const uint8_t *states);
+void qtiseclib_disable_cluster_coherency(uint8_t state);
+
+#endif /* QTISECLIB_INTERFACE_H */
diff --git a/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h b/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h
new file mode 100644
index 000000000..3ecee2022
--- /dev/null
+++ b/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTISECLIB_DEFS_PLAT_H
+#define QTISECLIB_DEFS_PLAT_H
+
+#define QTISECLIB_PLAT_CLUSTER_COUNT 1
+#define QTISECLIB_PLAT_CORE_COUNT 8
+
+#define BL31_BASE 0x80b00000
+#define BL31_SIZE 0x00100000
+
+/* Chipset specific secure interrupt number/ID defs. */
+#define QTISECLIB_INT_ID_SEC_WDOG_BARK (0x204)
+#define QTISECLIB_INT_ID_NON_SEC_WDOG_BITE (0x21)
+
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_SEC (0xE6)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_NONSEC (0xE7)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_SEC (0xE8)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_NONSEC (0xE9)
+
+#define QTISECLIB_INT_ID_XPU_SEC (0xE3)
+#define QTISECLIB_INT_ID_XPU_NON_SEC (0xE4)
+
+#define QTISECLIB_INT_ID_A2_NOC_ERROR (0x194)
+#define QTISECLIB_INT_ID_CONFIG_NOC_ERROR (0xE2)
+#define QTISECLIB_INT_ID_DC_NOC_ERROR (0x122)
+#define QTISECLIB_INT_ID_MEM_NOC_ERROR (0x6C)
+#define QTISECLIB_INT_ID_SYSTEM_NOC_ERROR (0xC6)
+#define QTISECLIB_INT_ID_MMSS_NOC_ERROR (0xBA)
+
+#endif /* QTISECLIB_DEFS_PLAT_H */
diff --git a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
new file mode 100644
index 000000000..bb552c66b
--- /dev/null
+++ b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <context.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/delay_timer.h>
+#include <lib/coreboot.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/spinlock.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include <platform.h>
+#include <qti_plat.h>
+#include <qtiseclib_cb_interface.h>
+
+void *qtiseclib_cb_memcpy(void *dst, const void *src, size_t len)
+{
+ return memcpy(dst, src, len);
+}
+
+int qtiseclib_cb_strcmp(const char *s1, const char *s2)
+{
+ return strcmp(s1, s2);
+}
+
+void *qtiseclib_cb_memset(void *s, int c, size_t n)
+{
+ return memset(s, c, n);
+}
+
+void *qtiseclib_cb_memmove(void *dest, const void *src, size_t n)
+{
+ return memmove(dest, src, n);
+}
+
+/* Printing logs below or equal LOG_LEVEL from QTISECLIB. */
+void qtiseclib_cb_log(unsigned int loglvl, const char *fmt, ...)
+{
+ if (loglvl <= LOG_LEVEL) {
+ va_list argp;
+ static spinlock_t qti_log_lock;
+ uint64_t uptime = read_cntpct_el0();
+
+ va_start(argp, fmt);
+
+ spin_lock(&qti_log_lock);
+ printf("QTISECLIB [%x%08x]",
+ (uint32_t) ((uptime >> 32) & 0xFFFFFFFF),
+ (uint32_t) (uptime & 0xFFFFFFFF));
+ vprintf(fmt, argp);
+ putchar('\n');
+ spin_unlock(&qti_log_lock);
+
+ va_end(argp);
+ }
+}
+
+void qtiseclib_cb_spin_lock(qtiseclib_cb_spinlock_t *lock)
+{
+ spin_lock((spinlock_t *) lock);
+}
+
+void qtiseclib_cb_spin_unlock(qtiseclib_cb_spinlock_t *lock)
+{
+ spin_unlock((spinlock_t *) lock);
+}
+
+unsigned int qtiseclib_cb_plat_my_core_pos(void)
+{
+ return plat_my_core_pos();
+}
+
+int qtiseclib_cb_plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+ return plat_core_pos_by_mpidr(mpidr);
+}
+
+unsigned int qtiseclib_cb_plat_my_cluster_pos(void)
+{
+ return plat_qti_my_cluster_pos();
+}
+
+/* GIC platform functions */
+void qtiseclib_cb_gic_pcpu_init(void)
+{
+ plat_qti_gic_pcpu_init();
+}
+
+void qtiseclib_cb_ic_raise_sgi(int sgi_num, u_register_t target)
+{
+ plat_ic_raise_el3_sgi(sgi_num, target);
+}
+
+void qtiseclib_cb_set_spi_routing(unsigned int id, unsigned int irm,
+ u_register_t target)
+{
+ assert(QTI_GICV3_IRM_PE == GICV3_IRM_PE);
+ assert(QTI_GICV3_IRM_ANY == GICV3_IRM_ANY);
+ gic_set_spi_routing(id, irm, target);
+}
+
+/* Crash reporting api's wrappers */
+void qtiseclib_cb_switch_console_to_crash_state(void)
+{
+ console_switch_state(CONSOLE_FLAG_CRASH);
+}
+
+void qtiseclib_cb_udelay(uint32_t usec)
+{
+ udelay(usec);
+}
+
+void qtiseclib_cb_console_flush(void)
+{
+ return console_flush();
+}
+
+#if QTI_SDI_BUILD
+void qtiseclib_cb_get_ns_ctx(qtiseclib_dbg_a64_ctxt_regs_type *qti_ns_ctx)
+{
+ void *ctx;
+
+ ctx = cm_get_context(NON_SECURE);
+
+ qti_ns_ctx->spsr_el3 =
+ read_ctx_reg(get_el3state_ctx(ctx), CTX_SPSR_EL3);
+ qti_ns_ctx->elr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_ELR_EL3);
+
+ qti_ns_ctx->spsr_el1 =
+ read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SPSR_EL1);
+ qti_ns_ctx->elr_el1 =
+ read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_ELR_EL1);
+ qti_ns_ctx->sp_el1 = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SP_EL1);
+
+ qti_ns_ctx->x0 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0);
+ qti_ns_ctx->x1 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1);
+ qti_ns_ctx->x2 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2);
+ qti_ns_ctx->x3 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3);
+ qti_ns_ctx->x4 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X4);
+ qti_ns_ctx->x5 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X5);
+ qti_ns_ctx->x6 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X6);
+ qti_ns_ctx->x7 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X7);
+ qti_ns_ctx->x8 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X8);
+ qti_ns_ctx->x9 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X9);
+ qti_ns_ctx->x10 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X10);
+ qti_ns_ctx->x11 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X11);
+ qti_ns_ctx->x12 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X12);
+ qti_ns_ctx->x13 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X13);
+ qti_ns_ctx->x14 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X14);
+ qti_ns_ctx->x15 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X15);
+ qti_ns_ctx->x16 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X16);
+ qti_ns_ctx->x17 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X17);
+ qti_ns_ctx->x18 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X18);
+ qti_ns_ctx->x19 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X19);
+ qti_ns_ctx->x20 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X20);
+ qti_ns_ctx->x21 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X21);
+ qti_ns_ctx->x22 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X22);
+ qti_ns_ctx->x23 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X23);
+ qti_ns_ctx->x24 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X24);
+ qti_ns_ctx->x25 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X25);
+ qti_ns_ctx->x26 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X26);
+ qti_ns_ctx->x27 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X27);
+ qti_ns_ctx->x28 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X28);
+ qti_ns_ctx->x29 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X29);
+ qti_ns_ctx->x30 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_LR);
+ qti_ns_ctx->sp_el0 =
+ read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_SP_EL0);
+}
+
+void qtiseclib_cb_flush_dcache_all(void)
+{
+ dcsw_op_all(DCCISW);
+}
+
+int qtiseclib_cb_mmap_add_dynamic_region(unsigned long long base_pa,
+ size_t size,
+ qtiseclib_mmap_attr_t attr)
+{
+ unsigned int l_attr = 0;
+
+ if (attr == QTISECLIB_MAP_NS_RO_XN_DATA) {
+ l_attr = MT_NS | MT_RO | MT_EXECUTE_NEVER;
+ } else if (attr == QTISECLIB_MAP_RW_XN_NC_DATA) {
+ l_attr = MT_RW | MT_NON_CACHEABLE | MT_EXECUTE_NEVER;
+ } else if (attr == QTISECLIB_MAP_RW_XN_DATA) {
+ l_attr = MT_RW | MT_EXECUTE_NEVER;
+ }
+ return qti_mmap_add_dynamic_region(base_pa, size, l_attr);
+}
+
+int qtiseclib_cb_mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
+{
+ return qti_mmap_remove_dynamic_region(base_va, size);
+}
+#endif
+
diff --git a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
new file mode 100644
index 000000000..9c93d51da
--- /dev/null
+++ b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include <qtiseclib_defs.h>
+#include <qtiseclib_interface.h>
+
+/*
+ * This file contains dummy implementation of QTISECLIB Published API's.
+ * which will be used to compile PLATFORM successfully when
+ * qtiseclib is not available
+ */
+
+/*
+ * CPUSS common reset handler for all CPU wake up (both cold & warm boot).
+ * Executes on all core. This API assume serialization across CPU
+ * already taken care before invoking.
+ *
+ * Clobbers: x0 - x17, x30
+ */
+void qtiseclib_cpuss_reset_asm(uint32_t bl31_cold_boot_state)
+{
+}
+
+/*
+ * Execute CPU (Kryo4 gold) specific reset handler / system initialization.
+ * This takes care of executing required CPU errata's.
+ *
+ * Clobbers: x0 - x16
+ */
+void qtiseclib_kryo4_gold_reset_asm(void)
+{
+}
+
+/*
+ * Execute CPU (Kryo4 silver) specific reset handler / system initialization.
+ * This takes care of executing required CPU errata's.
+ *
+ * Clobbers: x0 - x16
+ */
+void qtiseclib_kryo4_silver_reset_asm(void)
+{
+}
+
+/*
+ * C Api's
+ */
+void qtiseclib_bl31_platform_setup(void)
+{
+ ERROR("Please use QTISECLIB_PATH while building TF-A\n");
+ ERROR("Please refer docs/plat/qti.rst for more details.\n");
+ panic();
+}
+
+void qtiseclib_invoke_isr(uint32_t irq, void *handle)
+{
+}
+
+void qtiseclib_panic(void)
+{
+}
+
+int
+qtiseclib_mem_assign(const memprot_info_t *mem_info,
+ uint32_t mem_info_list_cnt,
+ const uint32_t *source_vm_list,
+ uint32_t src_vm_list_cnt,
+ const memprot_dst_vm_perm_info_t *dest_vm_list,
+ uint32_t dst_vm_list_cnt)
+{
+ return 0;
+}
+
+int qtiseclib_psci_init(uintptr_t warmboot_entry)
+{
+ return 0;
+}
+
+int qtiseclib_psci_node_power_on(u_register_t mpidr)
+{
+ return 0;
+}
+
+void qtiseclib_psci_node_on_finish(const uint8_t *states)
+{
+}
+
+void qtiseclib_psci_cpu_standby(uint8_t pwr_state)
+{
+}
+
+void qtiseclib_psci_node_power_off(const uint8_t *states)
+{
+}
+
+void qtiseclib_psci_node_suspend(const uint8_t *states)
+{
+}
+
+void qtiseclib_psci_node_suspend_finish(const uint8_t *states)
+{
+}
+
+void qtiseclib_disable_cluster_coherency(uint8_t state)
+{
+}
+
diff --git a/plat/qti/sc7180/inc/platform_def.h b/plat/qti/sc7180/inc/platform_def.h
new file mode 100644
index 000000000..b0798a63f
--- /dev/null
+++ b/plat/qti/sc7180/inc/platform_def.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+/* Enable the dynamic translation tables library. */
+#define PLAT_XLAT_TABLES_DYNAMIC 1
+
+#include <common_def.h>
+
+#include <qti_board_def.h>
+#include <qtiseclib_defs_plat.h>
+
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/*
+ * MPIDR_PRIMARY_CPU
+ * You just need to have the correct core_affinity_val i.e. [7:0]
+ * and cluster_affinity_val i.e. [15:8]
+ * the other bits will be ignored
+ */
+/*----------------------------------------------------------------------------*/
+#define MPIDR_PRIMARY_CPU 0x0000
+/*----------------------------------------------------------------------------*/
+
+#define QTI_PWR_LVL0 MPIDR_AFFLVL0
+#define QTI_PWR_LVL1 MPIDR_AFFLVL1
+#define QTI_PWR_LVL2 MPIDR_AFFLVL2
+#define QTI_PWR_LVL3 MPIDR_AFFLVL3
+
+/*
+ * Macros for local power states encoded by State-ID field
+ * within the power-state parameter.
+ */
+/* Local power state for power domains in Run state. */
+#define QTI_LOCAL_STATE_RUN 0
+/*
+ * Local power state for clock-gating. Valid only for CPU and not cluster power
+ * domains
+ */
+#define QTI_LOCAL_STATE_STB 1
+/*
+ * Local power state for retention. Valid for CPU and cluster power
+ * domains
+ */
+#define QTI_LOCAL_STATE_RET 2
+/*
+ * Local power state for OFF/power down. Valid for CPU, cluster, RSC and PDC
+ * power domains
+ */
+#define QTI_LOCAL_STATE_OFF 3
+/*
+ * Local power state for DEEPOFF/power rail down. Valid for CPU, cluster and RSC
+ * power domains
+ */
+#define QTI_LOCAL_STATE_DEEPOFF 4
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE QTI_LOCAL_STATE_RET
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE QTI_LOCAL_STATE_DEEPOFF
+
+/******************************************************************************
+ * Required platform porting definitions common to all ARM standard platforms
+ *****************************************************************************/
+
+/*
+ * Platform specific page table and MMU setup constants.
+ */
+#define MAX_MMAP_REGIONS (PLAT_QTI_MMAP_ENTRIES)
+
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 36)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 36)
+
+#define ARM_CACHE_WRITEBACK_SHIFT 6
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_GRANULE (1 << ARM_CACHE_WRITEBACK_SHIFT)
+
+/*
+ * One cache line needed for bakery locks on ARM platforms
+ */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE)
+
+/*----------------------------------------------------------------------------*/
+/* PSCI power domain topology definitions */
+/*----------------------------------------------------------------------------*/
+/* One domain each to represent RSC and PDC level */
+#define PLAT_PDC_COUNT 1
+#define PLAT_RSC_COUNT 1
+
+/* There is one top-level FCM cluster */
+#define PLAT_CLUSTER_COUNT 1
+
+/* No. of cores in the FCM cluster */
+#define PLAT_CLUSTER0_CORE_COUNT 8
+
+#define PLATFORM_CORE_COUNT (PLAT_CLUSTER0_CORE_COUNT)
+
+#define PLAT_NUM_PWR_DOMAINS (PLAT_PDC_COUNT +\
+ PLAT_RSC_COUNT +\
+ PLAT_CLUSTER_COUNT +\
+ PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_PWR_LVL 3
+
+/*****************************************************************************/
+/* Memory mapped Generic timer interfaces */
+/*****************************************************************************/
+
+/*----------------------------------------------------------------------------*/
+/* GIC-600 constants */
+/*----------------------------------------------------------------------------*/
+#define BASE_GICD_BASE 0x17A00000
+#define BASE_GICR_BASE 0x17A60000
+#define BASE_GICC_BASE 0x0
+#define BASE_GICH_BASE 0x0
+#define BASE_GICV_BASE 0x0
+
+#define QTI_GICD_BASE BASE_GICD_BASE
+#define QTI_GICR_BASE BASE_GICR_BASE
+#define QTI_GICC_BASE BASE_GICC_BASE
+
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/* UART related constants. */
+/*----------------------------------------------------------------------------*/
+/* BASE ADDRESS OF DIFFERENT REGISTER SPACES IN HW */
+#define GENI4_CFG 0x0
+#define GENI4_IMAGE_REGS 0x100
+#define GENI4_DATA 0x600
+
+/* COMMON STATUS/CONFIGURATION REGISTERS AND MASKS */
+#define GENI_STATUS_REG (GENI4_CFG + 0x00000040)
+#define GENI_STATUS_M_GENI_CMD_ACTIVE_MASK (0x1)
+#define UART_TX_TRANS_LEN_REG (GENI4_IMAGE_REGS + 0x00000170)
+/* MASTER/TX ENGINE REGISTERS */
+#define GENI_M_CMD0_REG (GENI4_DATA + 0x00000000)
+/* FIFO, STATUS REGISTERS AND MASKS */
+#define GENI_TX_FIFOn_REG (GENI4_DATA + 0x00000100)
+
+#define GENI_M_CMD_TX (0x08000000)
+
+/*----------------------------------------------------------------------------*/
+/* Device address space for mapping. Excluding starting 4K */
+/*----------------------------------------------------------------------------*/
+#define QTI_DEVICE_BASE 0x1000
+#define QTI_DEVICE_SIZE (0x80000000 - QTI_DEVICE_BASE)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL31 at DDR as per memory map. BL31_BASE is calculated using the
+ * current BL31 debug size plus a little space for growth.
+ */
+#define BL31_LIMIT (BL31_BASE + BL31_SIZE)
+
+/*----------------------------------------------------------------------------*/
+/* AOSS registers */
+/*----------------------------------------------------------------------------*/
+#define QTI_PS_HOLD_REG 0x0C264000
+/*----------------------------------------------------------------------------*/
+/* AOP CMD DB address space for mapping */
+/*----------------------------------------------------------------------------*/
+#define QTI_AOP_CMD_DB_BASE 0x80820000
+#define QTI_AOP_CMD_DB_SIZE 0x00020000
+/*----------------------------------------------------------------------------*/
+/* SOC hw version register */
+/*----------------------------------------------------------------------------*/
+#define QTI_SOC_VERSION U(0x7180)
+#define QTI_SOC_VERSION_MASK U(0xFFFF)
+#define QTI_SOC_REVISION_REG 0x1FC8000
+#define QTI_SOC_REVISION_MASK U(0xFFFF)
+/*----------------------------------------------------------------------------*/
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/qti/sc7180/inc/qti_rng_io.h b/plat/qti/sc7180/inc/qti_rng_io.h
new file mode 100644
index 000000000..f50234f2b
--- /dev/null
+++ b/plat/qti/sc7180/inc/qti_rng_io.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QTI_RNG_IO_H
+#define QTI_RNG_IO_H
+
+#define SEC_PRNG_STATUS 0x00791004
+#define SEC_PRNG_STATUS_DATA_AVAIL_BMSK 0x1
+#define SEC_PRNG_DATA_OUT 0x00791000
+
+
+#endif /* QTI_RNG_IO_H */
+
diff --git a/plat/qti/sc7180/inc/qti_secure_io_cfg.h b/plat/qti/sc7180/inc/qti_secure_io_cfg.h
new file mode 100644
index 000000000..3de636ddd
--- /dev/null
+++ b/plat/qti/sc7180/inc/qti_secure_io_cfg.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QTI_SECURE_IO_CFG_H
+#define QTI_SECURE_IO_CFG_H
+
+#include <stdint.h>
+
+/*
+ * List of peripheral/IO memory areas that are protected from
+ * non-secure world but not required to be secure.
+ */
+
+#define APPS_SMMU_TBU_PWR_STATUS 0x15002204
+#define APPS_SMMU_CUSTOM_CFG 0x15002300
+#define APPS_SMMU_STATS_SYNC_INV_TBU_ACK 0x150025DC
+#define APPS_SMMU_SAFE_SEC_CFG 0x15002648
+#define APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR 0x15002670
+
+static const uintptr_t qti_secure_io_allowed_regs[] = {
+ APPS_SMMU_TBU_PWR_STATUS,
+ APPS_SMMU_CUSTOM_CFG,
+ APPS_SMMU_STATS_SYNC_INV_TBU_ACK,
+ APPS_SMMU_SAFE_SEC_CFG,
+ APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR,
+};
+
+#endif /* QTI_SECURE_IO_CFG_H */
diff --git a/plat/qti/sc7180/platform.mk b/plat/qti/sc7180/platform.mk
new file mode 100644
index 000000000..ec560d036
--- /dev/null
+++ b/plat/qti/sc7180/platform.mk
@@ -0,0 +1,119 @@
+#
+# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Make for SC7180 QTI platform.
+
+QTI_PLAT_PATH := plat/qti
+CHIPSET := ${PLAT}
+
+# Turn On Separate code & data.
+SEPARATE_CODE_AND_RODATA := 1
+USE_COHERENT_MEM := 1
+WARMBOOT_ENABLE_DCACHE_EARLY := 1
+
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT := 0
+
+# Enable PSCI v1.0 extended state ID format
+PSCI_EXTENDED_STATE_ID := 1
+ARM_RECOM_STATE_ID_ENC := 1
+
+COLD_BOOT_SINGLE_CPU := 1
+PROGRAMMABLE_RESET_ADDRESS := 1
+
+RESET_TO_BL31 := 0
+
+MULTI_CONSOLE_API := 1
+
+QTI_SDI_BUILD := 0
+$(eval $(call assert_boolean,QTI_SDI_BUILD))
+$(eval $(call add_define,QTI_SDI_BUILD))
+
+#disable CTX_INCLUDE_AARCH32_REGS to support sc7180 gold cores
+override CTX_INCLUDE_AARCH32_REGS := 0
+WORKAROUND_CVE_2017_5715 := 0
+DYNAMIC_WORKAROUND_CVE_2018_3639 := 1
+# Enable stack protector.
+ENABLE_STACK_PROTECTOR := strong
+
+
+QTI_EXTERNAL_INCLUDES := -I${QTI_PLAT_PATH}/${CHIPSET}/inc \
+ -I${QTI_PLAT_PATH}/common/inc \
+ -I${QTI_PLAT_PATH}/common/inc/$(ARCH) \
+ -I${QTI_PLAT_PATH}/qtiseclib/inc \
+ -I${QTI_PLAT_PATH}/qtiseclib/inc/${CHIPSET} \
+
+QTI_BL31_SOURCES := $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S \
+ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_silver.S \
+ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_gold.S \
+ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S \
+ $(QTI_PLAT_PATH)/common/src/pm8998.c \
+ $(QTI_PLAT_PATH)/common/src/qti_stack_protector.c \
+ $(QTI_PLAT_PATH)/common/src/qti_common.c \
+ $(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c \
+ $(QTI_PLAT_PATH)/common/src/qti_gic_v3.c \
+ $(QTI_PLAT_PATH)/common/src/qti_interrupt_svc.c \
+ $(QTI_PLAT_PATH)/common/src/qti_syscall.c \
+ $(QTI_PLAT_PATH)/common/src/qti_topology.c \
+ $(QTI_PLAT_PATH)/common/src/qti_pm.c \
+ $(QTI_PLAT_PATH)/common/src/qti_rng.c \
+ $(QTI_PLAT_PATH)/common/src/spmi_arb.c \
+ $(QTI_PLAT_PATH)/qtiseclib/src/qtiseclib_cb_interface.c \
+
+
+PLAT_INCLUDES := -Iinclude/plat/common/ \
+
+PLAT_INCLUDES += ${QTI_EXTERNAL_INCLUDES}
+
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} \
+ plat/common/aarch64/crash_console_helpers.S \
+ common/desc_image_load.c \
+ lib/bl_aux_params/bl_aux_params.c \
+
+include lib/coreboot/coreboot.mk
+
+#PSCI Sources.
+PSCI_SOURCES := plat/common/plat_psci_common.c \
+
+# GIC-600 configuration
+GICV3_SUPPORT_GIC600 := 1
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+#Timer sources
+TIMER_SOURCES := drivers/delay_timer/generic_delay_timer.c \
+ drivers/delay_timer/delay_timer.c \
+
+#GIC sources.
+GIC_SOURCES := plat/common/plat_gicv3.c \
+ ${GICV3_SOURCES} \
+
+BL31_SOURCES += ${QTI_BL31_SOURCES} \
+ ${PSCI_SOURCES} \
+ ${GIC_SOURCES} \
+ ${TIMER_SOURCES} \
+
+LIB_QTI_PATH := ${QTI_PLAT_PATH}/qtiseclib/lib/${CHIPSET}
+
+
+# Override this on the command line to point to the qtiseclib library which
+# will be available in coreboot.org
+QTISECLIB_PATH ?=
+
+ifeq ($(QTISECLIB_PATH),)
+# if No lib then use stub implementation for qtiseclib interface
+$(warning QTISECLIB_PATH is not provided while building, using stub implementation. \
+ Please refer docs/plat/qti.rst for more details \
+ THIS FIRMWARE WILL NOT BOOT!)
+BL31_SOURCES += plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
+else
+# use library provided by QTISECLIB_PATH
+LDFLAGS += -L $(dir $(QTISECLIB_PATH))
+LDLIBS += -l$(patsubst lib%.a,%,$(notdir $(QTISECLIB_PATH)))
+endif
+
diff --git a/plat/renesas/rcar/aarch64/plat_helpers.S b/plat/renesas/common/aarch64/plat_helpers.S
index 138d98807..ec21f2510 100644
--- a/plat/renesas/rcar/aarch64/plat_helpers.S
+++ b/plat/renesas/common/aarch64/plat_helpers.S
@@ -295,7 +295,7 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush()
+ * void plat_crash_console_flush()
* ---------------------------------------------
*/
func plat_crash_console_flush
diff --git a/plat/renesas/rcar/aarch64/platform_common.c b/plat/renesas/common/aarch64/platform_common.c
index b0a88cb6b..b0a88cb6b 100644
--- a/plat/renesas/rcar/aarch64/platform_common.c
+++ b/plat/renesas/common/aarch64/platform_common.c
diff --git a/plat/renesas/rcar/bl2_cpg_init.c b/plat/renesas/common/bl2_cpg_init.c
index c3ca9ea16..677a57d04 100644
--- a/plat/renesas/rcar/bl2_cpg_init.c
+++ b/plat/renesas/common/bl2_cpg_init.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,8 +7,8 @@
#include <common/debug.h>
#include <lib/mmio.h>
-#include "rcar_def.h"
#include "cpg_registers.h"
+#include "rcar_def.h"
#include "rcar_private.h"
static void bl2_secure_cpg_init(void);
@@ -18,7 +18,7 @@ static void bl2_realtime_cpg_init_h3(void);
static void bl2_system_cpg_init_h3(void);
#endif
-#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3)
+#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) || (RCAR_LSI == RZ_G2M)
static void bl2_realtime_cpg_init_m3(void);
static void bl2_system_cpg_init_m3(void);
#endif
@@ -77,7 +77,7 @@ static void bl2_secure_cpg_init(void)
stop_cr5 = 0xBFFFFFFFU;
#endif
- /** Secure Module Stop Control Registers */
+ /* Secure Module Stop Control Registers */
cpg_write(SCMSTPCR0, 0xFFFFFFFFU);
cpg_write(SCMSTPCR1, 0xFFFFFFFFU);
cpg_write(SCMSTPCR2, stop_cr2);
@@ -91,7 +91,7 @@ static void bl2_secure_cpg_init(void)
cpg_write(SCMSTPCR10, 0xFFFFFFFFU);
cpg_write(SCMSTPCR11, 0xFFFFFFFFU);
- /** Secure Software Reset Access Enable Control Registers */
+ /* Secure Software Reset Access Enable Control Registers */
cpg_write(SCSRSTECR0, 0x00000000U);
cpg_write(SCSRSTECR1, 0x00000000U);
cpg_write(SCSRSTECR2, reset_cr2);
@@ -149,10 +149,10 @@ static void bl2_system_cpg_init_h3(void)
}
#endif
-#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3)
+#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) || (RCAR_LSI == RZ_G2M)
static void bl2_realtime_cpg_init_m3(void)
{
- /** Realtime Module Stop Control Registers */
+ /* Realtime Module Stop Control Registers */
cpg_write(RMSTPCR0, 0x00200000U);
cpg_write(RMSTPCR1, 0xFFFFFFFFU);
cpg_write(RMSTPCR2, 0x040E0FDCU);
@@ -169,7 +169,7 @@ static void bl2_realtime_cpg_init_m3(void)
static void bl2_system_cpg_init_m3(void)
{
- /** System Module Stop Control Registers */
+ /* System Module Stop Control Registers */
cpg_write(SMSTPCR0, 0x00200000U);
cpg_write(SMSTPCR1, 0xFFFFFFFFU);
cpg_write(SMSTPCR2, 0x040E2FDCU);
@@ -188,7 +188,7 @@ static void bl2_system_cpg_init_m3(void)
#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3N)
static void bl2_realtime_cpg_init_m3n(void)
{
- /** Realtime Module Stop Control Registers */
+ /* Realtime Module Stop Control Registers */
cpg_write(RMSTPCR0, 0x00210000U);
cpg_write(RMSTPCR1, 0xFFFFFFFFU);
cpg_write(RMSTPCR2, 0x040E0FDCU);
@@ -362,7 +362,7 @@ void bl2_cpg_init(void)
}
#elif (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N)
bl2_realtime_cpg_init_h3();
-#elif RCAR_LSI == RCAR_M3
+#elif (RCAR_LSI == RCAR_M3) || (RCAR_LSI == RZ_G2M)
bl2_realtime_cpg_init_m3();
#elif RCAR_LSI == RCAR_M3N
bl2_realtime_cpg_init_m3n();
@@ -408,7 +408,7 @@ void bl2_system_cpg_init(void)
}
#elif (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N)
bl2_system_cpg_init_h3();
-#elif RCAR_LSI == RCAR_M3
+#elif (RCAR_LSI == RCAR_M3) || (RCAR_LSI == RZ_G2M)
bl2_system_cpg_init_m3();
#elif RCAR_LSI == RCAR_M3N
bl2_system_cpg_init_m3n();
diff --git a/plat/renesas/rcar/bl2_interrupt_error.c b/plat/renesas/common/bl2_interrupt_error.c
index d9a4b8e62..d9a4b8e62 100644
--- a/plat/renesas/rcar/bl2_interrupt_error.c
+++ b/plat/renesas/common/bl2_interrupt_error.c
diff --git a/plat/renesas/rcar/bl2_plat_mem_params_desc.c b/plat/renesas/common/bl2_plat_mem_params_desc.c
index bf2706d53..bf2706d53 100644
--- a/plat/renesas/rcar/bl2_plat_mem_params_desc.c
+++ b/plat/renesas/common/bl2_plat_mem_params_desc.c
diff --git a/plat/renesas/common/bl2_secure_setting.c b/plat/renesas/common/bl2_secure_setting.c
new file mode 100644
index 000000000..095d1f62a
--- /dev/null
+++ b/plat/renesas/common/bl2_secure_setting.c
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include "axi_registers.h"
+#include "lifec_registers.h"
+#include "micro_delay.h"
+
+static void lifec_security_setting(void);
+static void axi_security_setting(void);
+
+static const struct {
+ uint32_t reg;
+ uint32_t val;
+} lifec[] = {
+ /*
+ * LIFEC0 (SECURITY) settings
+ * Security attribute setting for master ports
+ * Bit 0: ARM realtime core (Cortex-R7) master port
+ * 0: Non-Secure
+ */
+ { SEC_SRC, 0x0000001EU },
+ /*
+ * Security attribute setting for slave ports 0 to 15
+ * {SEC_SEL0, 0xFFFFFFFFU},
+ * {SEC_SEL1, 0xFFFFFFFFU},
+ * {SEC_SEL2, 0xFFFFFFFFU},
+ * Bit19: AXI-Bus (Main Memory domain AXI) slave ports
+ * 0: registers accessed from secure resource only
+ * Bit 9: DBSC4 register access slave ports.
+ * 0: registers accessed from secure resource only.
+ */
+#if (LIFEC_DBSC_PROTECT_ENABLE == 1)
+ { SEC_SEL3, 0xFFF7FDFFU },
+#else /* LIFEC_DBSC_PROTECT_ENABLE == 1 */
+ { SEC_SEL3, 0xFFFFFFFFU },
+#endif /* LIFEC_DBSC_PROTECT_ENABLE == 1 */
+ /*
+ * {SEC_SEL4, 0xFFFFFFFFU},
+ * Bit 6: Boot ROM slave ports.
+ * 0: registers accessed from secure resource only
+ */
+ { SEC_SEL5, 0xFFFFFFBFU },
+ /*
+ * Bit13: SCEG PKA (secure APB) slave ports
+ * 0: registers accessed from secure resource only
+ * 1: Reserved[R-Car E3]
+ * Bit12: SCEG PKA (public APB) slave ports
+ * 0: registers accessed from secure resource only
+ * 1: Reserved[R-Car E3]
+ * Bit10: SCEG Secure Core slave ports
+ * 0: registers accessed from secure resource only
+ */
+#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3)
+ { SEC_SEL6, 0xFFFFFBFFU },
+#else /* (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) */
+ { SEC_SEL6, 0xFFFFCBFFU },
+#endif /* (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) */
+ /*
+ * {SEC_SEL7, 0xFFFFFFFFU},
+ * {SEC_SEL8, 0xFFFFFFFFU},
+ * {SEC_SEL9, 0xFFFFFFFFU},
+ * {SEC_SEL10, 0xFFFFFFFFU},
+ * {SEC_SEL11, 0xFFFFFFFFU},
+ * {SEC_SEL12, 0xFFFFFFFFU},
+ * Bit22: RPC slave ports.
+ * 0: registers accessed from secure resource only.
+ */
+#if (RCAR_RPC_HYPERFLASH_LOCKED == 1)
+ { SEC_SEL13, 0xFFBFFFFFU },
+#endif /* (RCAR_RPC_HYPERFLASH_LOCKED == 1) */
+ /*
+ * Bit27: System Timer (SCMT) slave ports
+ * 0: registers accessed from secure resource only
+ * Bit26: System Watchdog Timer (SWDT) slave ports
+ * 0: registers accessed from secure resource only
+ */
+ { SEC_SEL14, 0xF3FFFFFFU },
+ /*
+ * Bit13: RST slave ports.
+ * 0: registers accessed from secure resource only
+ * Bit 7: Life Cycle 0 slave ports
+ * 0: registers accessed from secure resource only
+ */
+ { SEC_SEL15, 0xFFFFFF3FU },
+ /*
+ * Security group 0 attribute setting for master ports 0
+ * Security group 1 attribute setting for master ports 0
+ * {SEC_GRP0CR0, 0x00000000U},
+ * {SEC_GRP1CR0, 0x00000000U},
+ * Security group 0 attribute setting for master ports 1
+ * Security group 1 attribute setting for master ports 1
+ * {SEC_GRP0CR1, 0x00000000U},
+ * {SEC_GRP1CR1, 0x00000000U},
+ * Security group 0 attribute setting for master ports 2
+ * Security group 1 attribute setting for master ports 2
+ * Bit17: SCEG Secure Core master ports.
+ * SecurityGroup3
+ */
+ { SEC_GRP0CR2, 0x00020000U },
+ { SEC_GRP1CR2, 0x00020000U },
+ /*
+ * Security group 0 attribute setting for master ports 3
+ * Security group 1 attribute setting for master ports 3
+ * {SEC_GRP0CR3, 0x00000000U},
+ * {SEC_GRP1CR3, 0x00000000U},
+ * Security group 0 attribute setting for slave ports 0
+ * Security group 1 attribute setting for slave ports 0
+ * {SEC_GRP0COND0, 0x00000000U},
+ * {SEC_GRP1COND0, 0x00000000U},
+ * Security group 0 attribute setting for slave ports 1
+ * Security group 1 attribute setting for slave ports 1
+ * {SEC_GRP0COND1, 0x00000000U},
+ * {SEC_GRP1COND1, 0x00000000U},
+ * Security group 0 attribute setting for slave ports 2
+ * Security group 1 attribute setting for slave ports 2
+ * {SEC_GRP0COND2, 0x00000000U},
+ * {SEC_GRP1COND2, 0x00000000U},
+ * Security group 0 attribute setting for slave ports 3
+ * Security group 1 attribute setting for slave ports 3
+ * Bit19: AXI-Bus (Main Memory domain AXI) slave ports.
+ * SecurityGroup3
+ * Bit 9: DBSC4 register access slave ports.
+ * SecurityGroup3
+ */
+#if (LIFEC_DBSC_PROTECT_ENABLE == 1)
+ { SEC_GRP0COND3, 0x00080200U },
+ { SEC_GRP1COND3, 0x00080200U },
+#else /* (LIFEC_DBSC_PROTECT_ENABLE == 1) */
+ { SEC_GRP0COND3, 0x00000000U },
+ { SEC_GRP1COND3, 0x00000000U },
+#endif /* (LIFEC_DBSC_PROTECT_ENABLE == 1) */
+ /*
+ * Security group 0 attribute setting for slave ports 4
+ * Security group 1 attribute setting for slave ports 4
+ * {SEC_GRP0COND4, 0x00000000U},
+ * {SEC_GRP1COND4, 0x00000000U},
+ * Security group 0 attribute setting for slave ports 5
+ * Security group 1 attribute setting for slave ports 5
+ * Bit 6: Boot ROM slave ports
+ * SecurityGroup3
+ */
+ { SEC_GRP0COND5, 0x00000040U },
+ { SEC_GRP1COND5, 0x00000040U },
+ /*
+ * Security group 0 attribute setting for slave ports 6
+ * Security group 1 attribute setting for slave ports 6
+ * Bit13: SCEG PKA (secure APB) slave ports
+ * SecurityGroup3
+ * Reserved[R-Car E3]
+ * Bit12: SCEG PKA (public APB) slave ports
+ * SecurityGroup3
+ * Reserved[R-Car E3]
+ * Bit10: SCEG Secure Core slave ports
+ * SecurityGroup3
+ */
+#if RCAR_LSI == RCAR_E3
+ { SEC_GRP0COND6, 0x00000400U },
+ { SEC_GRP1COND6, 0x00000400U },
+#else /* RCAR_LSI == RCAR_E3 */
+ { SEC_GRP0COND6, 0x00003400U },
+ { SEC_GRP1COND6, 0x00003400U },
+#endif /* RCAR_LSI == RCAR_E3 */
+ /*
+ * Security group 0 attribute setting for slave ports 7
+ * Security group 1 attribute setting for slave ports 7
+ * {SEC_GRP0COND7, 0x00000000U},
+ * {SEC_GRP1COND7, 0x00000000U},
+ * Security group 0 attribute setting for slave ports 8
+ * Security group 1 attribute setting for slave ports 8
+ * {SEC_GRP0COND8, 0x00000000U},
+ * {SEC_GRP1COND8, 0x00000000U},
+ * Security group 0 attribute setting for slave ports 9
+ * Security group 1 attribute setting for slave ports 9
+ * {SEC_GRP0COND9, 0x00000000U},
+ * {SEC_GRP1COND9, 0x00000000U},
+ * Security group 0 attribute setting for slave ports 10
+ * Security group 1 attribute setting for slave ports 10
+ * {SEC_GRP0COND10, 0x00000000U},
+ * {SEC_GRP1COND10, 0x00000000U},
+ * Security group 0 attribute setting for slave ports 11
+ * Security group 1 attribute setting for slave ports 11
+ * {SEC_GRP0COND11, 0x00000000U},
+ * {SEC_GRP1COND11, 0x00000000U},
+ * Security group 0 attribute setting for slave ports 12
+ * Security group 1 attribute setting for slave ports 12
+ * {SEC_GRP0COND12, 0x00000000U},
+ * {SEC_GRP1COND12, 0x00000000U},
+ * Security group 0 attribute setting for slave ports 13
+ * Security group 1 attribute setting for slave ports 13
+ * Bit22: RPC slave ports.
+ * SecurityGroup3
+ */
+#if (RCAR_RPC_HYPERFLASH_LOCKED == 1)
+ { SEC_GRP0COND13, 0x00400000U },
+ { SEC_GRP1COND13, 0x00400000U },
+#endif /* (RCAR_RPC_HYPERFLASH_LOCKED == 1) */
+ /*
+ * Security group 0 attribute setting for slave ports 14
+ * Security group 1 attribute setting for slave ports 14
+ * Bit26: System Timer (SCMT) slave ports
+ * SecurityGroup3
+ * Bit27: System Watchdog Timer (SWDT) slave ports
+ * SecurityGroup3
+ */
+ { SEC_GRP0COND14, 0x0C000000U },
+ { SEC_GRP1COND14, 0x0C000000U },
+ /*
+ * Security group 0 attribute setting for slave ports 15
+ * Security group 1 attribute setting for slave ports 15
+ * Bit13: RST slave ports
+ * SecurityGroup3
+ * Bit 7: Life Cycle 0 slave ports
+ * SecurityGroup3
+ * Bit 6: TDBG slave ports
+ * SecurityGroup3
+ */
+ { SEC_GRP0COND15, 0x000000C0U },
+ { SEC_GRP1COND15, 0x000000C0U },
+ /*
+ * Security write protection attribute setting slave ports 0
+ * {SEC_READONLY0, 0x00000000U},
+ * Security write protection attribute setting slave ports 1
+ * {SEC_READONLY1, 0x00000000U},
+ * Security write protection attribute setting slave ports 2
+ * {SEC_READONLY2, 0x00000000U},
+ * Security write protection attribute setting slave ports 3
+ * {SEC_READONLY3, 0x00000000U},
+ * Security write protection attribute setting slave ports 4
+ * {SEC_READONLY4, 0x00000000U},
+ * Security write protection attribute setting slave ports 5
+ * {SEC_READONLY5, 0x00000000U},
+ * Security write protection attribute setting slave ports 6
+ * {SEC_READONLY6, 0x00000000U},
+ * Security write protection attribute setting slave ports 7
+ * {SEC_READONLY7, 0x00000000U},
+ * Security write protection attribute setting slave ports 8
+ * {SEC_READONLY8, 0x00000000U},
+ * Security write protection attribute setting slave ports 9
+ * {SEC_READONLY9, 0x00000000U},
+ * Security write protection attribute setting slave ports 10
+ * {SEC_READONLY10, 0x00000000U},
+ * Security write protection attribute setting slave ports 11
+ * {SEC_READONLY11, 0x00000000U},
+ * Security write protection attribute setting slave ports 12
+ * {SEC_READONLY12, 0x00000000U},
+ * Security write protection attribute setting slave ports 13
+ * {SEC_READONLY13, 0x00000000U},
+ * Security write protection attribute setting slave ports 14
+ * {SEC_READONLY14, 0x00000000U},
+ * Security write protection attribute setting slave ports 15
+ * {SEC_READONLY15, 0x00000000U}
+ */
+};
+
+/* AXI settings */
+static const struct {
+ uint32_t reg;
+ uint32_t val;
+} axi[] = {
+ /*
+ * DRAM protection
+ * AXI dram protected area division
+ */
+ {AXI_DPTDIVCR0, 0x0E0403F0U},
+ {AXI_DPTDIVCR1, 0x0E0407E0U},
+ {AXI_DPTDIVCR2, 0x0E080000U},
+ {AXI_DPTDIVCR3, 0x0E080000U},
+ {AXI_DPTDIVCR4, 0x0E080000U},
+ {AXI_DPTDIVCR5, 0x0E080000U},
+ {AXI_DPTDIVCR6, 0x0E080000U},
+ {AXI_DPTDIVCR7, 0x0E080000U},
+ {AXI_DPTDIVCR8, 0x0E080000U},
+ {AXI_DPTDIVCR9, 0x0E080000U},
+ {AXI_DPTDIVCR10, 0x0E080000U},
+ {AXI_DPTDIVCR11, 0x0E080000U},
+ {AXI_DPTDIVCR12, 0x0E080000U},
+ {AXI_DPTDIVCR13, 0x0E080000U},
+ {AXI_DPTDIVCR14, 0x0E080000U},
+ /* AXI dram protected area setting */
+ {AXI_DPTCR0, 0x0E000000U},
+ {AXI_DPTCR1, 0x0E000E0EU},
+ {AXI_DPTCR2, 0x0E000000U},
+ {AXI_DPTCR3, 0x0E000000U},
+ {AXI_DPTCR4, 0x0E000000U},
+ {AXI_DPTCR5, 0x0E000000U},
+ {AXI_DPTCR6, 0x0E000000U},
+ {AXI_DPTCR7, 0x0E000000U},
+ {AXI_DPTCR8, 0x0E000000U},
+ {AXI_DPTCR9, 0x0E000000U},
+ {AXI_DPTCR10, 0x0E000000U},
+ {AXI_DPTCR11, 0x0E000000U},
+ {AXI_DPTCR12, 0x0E000000U},
+ {AXI_DPTCR13, 0x0E000000U},
+ {AXI_DPTCR14, 0x0E000000U},
+ {AXI_DPTCR15, 0x0E000000U},
+ /*
+ * SRAM ptotection
+ * AXI sram protected area division
+ */
+ {AXI_SPTDIVCR0, 0x0E0E6304U},
+ {AXI_SPTDIVCR1, 0x0E0E6360U},
+ {AXI_SPTDIVCR2, 0x0E0E6360U},
+ {AXI_SPTDIVCR3, 0x0E0E6360U},
+ {AXI_SPTDIVCR4, 0x0E0E6360U},
+ {AXI_SPTDIVCR5, 0x0E0E6360U},
+ {AXI_SPTDIVCR6, 0x0E0E6360U},
+ {AXI_SPTDIVCR7, 0x0E0E6360U},
+ {AXI_SPTDIVCR8, 0x0E0E6360U},
+ {AXI_SPTDIVCR9, 0x0E0E6360U},
+ {AXI_SPTDIVCR10, 0x0E0E6360U},
+ {AXI_SPTDIVCR11, 0x0E0E6360U},
+ {AXI_SPTDIVCR12, 0x0E0E6360U},
+ {AXI_SPTDIVCR13, 0x0E0E6360U},
+ {AXI_SPTDIVCR14, 0x0E0E6360U},
+ /* AXI sram protected area setting */
+ {AXI_SPTCR0, 0x0E000E0EU},
+ {AXI_SPTCR1, 0x0E000000U},
+ {AXI_SPTCR2, 0x0E000000U},
+ {AXI_SPTCR3, 0x0E000000U},
+ {AXI_SPTCR4, 0x0E000000U},
+ {AXI_SPTCR5, 0x0E000000U},
+ {AXI_SPTCR6, 0x0E000000U},
+ {AXI_SPTCR7, 0x0E000000U},
+ {AXI_SPTCR8, 0x0E000000U},
+ {AXI_SPTCR9, 0x0E000000U},
+ {AXI_SPTCR10, 0x0E000000U},
+ {AXI_SPTCR11, 0x0E000000U},
+ {AXI_SPTCR12, 0x0E000000U},
+ {AXI_SPTCR13, 0x0E000000U},
+ {AXI_SPTCR14, 0x0E000000U},
+ {AXI_SPTCR15, 0x0E000000U}
+};
+
+static void lifec_security_setting(void)
+{
+ uint32_t i;
+
+ for (i = 0; i < ARRAY_SIZE(lifec); i++)
+ mmio_write_32(lifec[i].reg, lifec[i].val);
+}
+
+/* SRAM/DRAM protection setting */
+static void axi_security_setting(void)
+{
+ uint32_t i;
+
+ for (i = 0; i < ARRAY_SIZE(axi); i++)
+ mmio_write_32(axi[i].reg, axi[i].val);
+}
+
+void bl2_secure_setting(void)
+{
+ lifec_security_setting();
+ axi_security_setting();
+ rcar_micro_delay(10U);
+}
diff --git a/plat/renesas/rcar/bl31_plat_setup.c b/plat/renesas/common/bl31_plat_setup.c
index 7bc0d8e27..93798acfb 100644
--- a/plat/renesas/rcar/bl31_plat_setup.c
+++ b/plat/renesas/common/bl31_plat_setup.c
@@ -28,7 +28,7 @@ static const uint64_t BL31_RO_LIMIT = BL_CODE_END;
#if USE_COHERENT_MEM
static const uint64_t BL31_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE;
static const uint64_t BL31_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END;
-#endif
+#endif /* USE_COHERENT_MEM */
extern void plat_rcar_gic_driver_init(void);
extern void plat_rcar_gic_init(void);
@@ -84,11 +84,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
NOTICE("BL3-1 : Rev.%s\n", version_of_renesas);
#if RCAR_LSI != RCAR_D3
- if (RCAR_CLUSTER_A53A57 == rcar_pwrc_get_cluster()) {
+ if (rcar_pwrc_get_cluster() == RCAR_CLUSTER_A53A57) {
plat_cci_init();
plat_cci_enable();
}
-#endif
+#endif /* RCAR_LSI != RCAR_D3 */
}
void bl31_plat_arch_setup(void)
@@ -98,7 +98,7 @@ void bl31_plat_arch_setup(void)
BL31_RO_BASE, BL31_RO_LIMIT
#if USE_COHERENT_MEM
, BL31_COHERENT_RAM_BASE, BL31_COHERENT_RAM_LIMIT
-#endif
+#endif /* USE_COHERENT_MEM */
);
rcar_pwrc_code_copy_to_system_ram();
}
@@ -113,17 +113,20 @@ void bl31_platform_setup(void)
rcar_pwrc_setup();
#if 0
- /* TODO: there is a broad number of rcar-gen3 SoC configurations; to
- support all of them, Renesas use the pwrc driver to discover what
- cores are on/off before announcing the topology.
- This code hasnt been ported yet
- */
+ /*
+ * TODO: there is a broad number of rcar-gen3 SoC configurations; to
+ * support all of them, Renesas use the pwrc driver to discover what
+ * cores are on/off before announcing the topology.
+ * This code hasnt been ported yet
+ */
rcar_setup_topology();
#endif
- /* mask should match the kernel's MPIDR_HWID_BITMASK so the core can be
- identified during cpuhotplug (check the kernel's psci migrate set of
- functions */
+ /*
+ * mask should match the kernel's MPIDR_HWID_BITMASK so the core can be
+ * identified during cpuhotplug (check the kernel's psci migrate set of
+ * functions
+ */
rcar_boot_mpidr = read_mpidr_el1() & 0x0000ffffU;
}
diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk
new file mode 100644
index 000000000..984ab5bac
--- /dev/null
+++ b/plat/renesas/common/common.mk
@@ -0,0 +1,132 @@
+#
+# Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PROGRAMMABLE_RESET_ADDRESS := 0
+COLD_BOOT_SINGLE_CPU := 1
+ARM_CCI_PRODUCT_ID := 500
+TRUSTED_BOARD_BOOT := 1
+RESET_TO_BL31 := 1
+GENERATE_COT := 1
+BL2_AT_EL3 := 1
+ENABLE_SVE_FOR_NS := 0
+MULTI_CONSOLE_API := 1
+
+CRASH_REPORTING := 1
+HANDLE_EA_EL3_FIRST := 1
+
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
+ifeq (${SPD},none)
+ SPD_NONE:=1
+ $(eval $(call add_define,SPD_NONE))
+endif
+
+# LSI setting common define
+RCAR_H3:=0
+RCAR_M3:=1
+RCAR_M3N:=2
+RCAR_E3:=3
+RCAR_H3N:=4
+RCAR_D3:=5
+RCAR_V3M:=6
+RCAR_AUTO:=99
+RZ_G2M:=100
+$(eval $(call add_define,RCAR_H3))
+$(eval $(call add_define,RCAR_M3))
+$(eval $(call add_define,RCAR_M3N))
+$(eval $(call add_define,RCAR_E3))
+$(eval $(call add_define,RCAR_H3N))
+$(eval $(call add_define,RCAR_D3))
+$(eval $(call add_define,RCAR_V3M))
+$(eval $(call add_define,RCAR_AUTO))
+$(eval $(call add_define,RZ_G2M))
+
+RCAR_CUT_10:=0
+RCAR_CUT_11:=1
+RCAR_CUT_13:=3
+RCAR_CUT_20:=10
+RCAR_CUT_30:=20
+$(eval $(call add_define,RCAR_CUT_10))
+$(eval $(call add_define,RCAR_CUT_11))
+$(eval $(call add_define,RCAR_CUT_13))
+$(eval $(call add_define,RCAR_CUT_20))
+$(eval $(call add_define,RCAR_CUT_30))
+
+# Enable workarounds for selected Cortex-A53 erratas.
+ERRATA_A53_835769 := 1
+ERRATA_A53_843419 := 1
+ERRATA_A53_855873 := 1
+
+# Enable workarounds for selected Cortex-A57 erratas.
+ERRATA_A57_859972 := 1
+ERRATA_A57_813419 := 1
+
+PLAT_INCLUDES := -Iplat/renesas/common/include/registers \
+ -Iplat/renesas/common/include \
+ -Iplat/renesas/common
+
+PLAT_BL_COMMON_SOURCES := drivers/renesas/common/iic_dvfs/iic_dvfs.c \
+ plat/renesas/common/rcar_common.c
+
+RCAR_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
+ drivers/arm/gic/v2/gicv2_main.c \
+ drivers/arm/gic/v2/gicv2_helpers.c \
+ plat/common/plat_gicv2.c
+
+BL2_SOURCES += ${RCAR_GIC_SOURCES} \
+ lib/cpus/aarch64/cortex_a53.S \
+ lib/cpus/aarch64/cortex_a57.S \
+ ${LIBFDT_SRCS} \
+ common/desc_image_load.c \
+ plat/renesas/common/aarch64/platform_common.c \
+ plat/renesas/common/aarch64/plat_helpers.S \
+ plat/renesas/common/bl2_interrupt_error.c \
+ plat/renesas/common/bl2_secure_setting.c \
+ plat/renesas/common/plat_storage.c \
+ plat/renesas/common/bl2_plat_mem_params_desc.c \
+ plat/renesas/common/plat_image_load.c \
+ plat/renesas/common/bl2_cpg_init.c \
+ drivers/renesas/common/console/rcar_printf.c \
+ drivers/renesas/common/scif/scif.S \
+ drivers/renesas/common/common.c \
+ drivers/renesas/common/io/io_emmcdrv.c \
+ drivers/renesas/common/io/io_memdrv.c \
+ drivers/renesas/common/io/io_rcar.c \
+ drivers/renesas/common/auth/auth_mod.c \
+ drivers/renesas/common/rpc/rpc_driver.c \
+ drivers/renesas/common/dma/dma_driver.c \
+ drivers/renesas/common/avs/avs_driver.c \
+ drivers/renesas/common/delay/micro_delay.c \
+ drivers/renesas/common/emmc/emmc_interrupt.c \
+ drivers/renesas/common/emmc/emmc_utility.c \
+ drivers/renesas/common/emmc/emmc_mount.c \
+ drivers/renesas/common/emmc/emmc_init.c \
+ drivers/renesas/common/emmc/emmc_read.c \
+ drivers/renesas/common/emmc/emmc_cmd.c \
+ drivers/renesas/common/watchdog/swdt.c \
+ drivers/renesas/common/rom/rom_api.c \
+ drivers/io/io_storage.c
+
+BL31_SOURCES += ${RCAR_GIC_SOURCES} \
+ lib/cpus/aarch64/cortex_a53.S \
+ lib/cpus/aarch64/cortex_a57.S \
+ plat/common/plat_psci_common.c \
+ plat/renesas/common/plat_topology.c \
+ plat/renesas/common/aarch64/plat_helpers.S \
+ plat/renesas/common/aarch64/platform_common.c \
+ plat/renesas/common/bl31_plat_setup.c \
+ plat/renesas/common/plat_pm.c \
+ drivers/renesas/common/console/rcar_console.S \
+ drivers/renesas/common/console/rcar_printf.c \
+ drivers/renesas/common/delay/micro_delay.c \
+ drivers/renesas/common/pwrc/call_sram.S \
+ drivers/renesas/common/pwrc/pwrc.c \
+ drivers/renesas/common/common.c \
+ drivers/arm/cci/cci.c
+
+include lib/xlat_tables_v2/xlat_tables.mk
+include drivers/auth/mbedtls/mbedtls_crypto.mk
+PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/renesas/rcar/include/plat.ld.S b/plat/renesas/common/include/plat.ld.S
index 7aef324c4..7aef324c4 100644
--- a/plat/renesas/rcar/include/plat.ld.S
+++ b/plat/renesas/common/include/plat.ld.S
diff --git a/plat/renesas/rcar/include/plat_macros.S b/plat/renesas/common/include/plat_macros.S
index 927cd39e8..927cd39e8 100644
--- a/plat/renesas/rcar/include/plat_macros.S
+++ b/plat/renesas/common/include/plat_macros.S
diff --git a/plat/renesas/rcar/include/platform_def.h b/plat/renesas/common/include/platform_def.h
index b7f0ca113..73787140b 100644
--- a/plat/renesas/rcar/include/platform_def.h
+++ b/plat/renesas/common/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -29,20 +29,20 @@
/* Size of cacheable stacks */
#if IMAGE_BL1
#if TRUSTED_BOARD_BOOT
-#define PLATFORM_STACK_SIZE U(0x1000)
+#define PLATFORM_STACK_SIZE U(0x1000)
#else
-#define PLATFORM_STACK_SIZE U(0x440)
+#define PLATFORM_STACK_SIZE U(0x440)
#endif
#elif IMAGE_BL2
#if TRUSTED_BOARD_BOOT
-#define PLATFORM_STACK_SIZE U(0x1000)
+#define PLATFORM_STACK_SIZE U(0x1000)
#else
-#define PLATFORM_STACK_SIZE U(0x400)
+#define PLATFORM_STACK_SIZE U(0x400)
#endif
#elif IMAGE_BL31
-#define PLATFORM_STACK_SIZE U(0x400)
+#define PLATFORM_STACK_SIZE U(0x400)
#elif IMAGE_BL32
-#define PLATFORM_STACK_SIZE U(0x440)
+#define PLATFORM_STACK_SIZE U(0x440)
#endif
#define BL332_IMAGE_ID (NS_BL2U_IMAGE_ID + 1)
@@ -97,11 +97,13 @@
#define MAX_IO_DEVICES U(3)
#define MAX_IO_HANDLES U(4)
-/*******************************************************************************
+/*
+ ******************************************************************************
* BL2 specific defines.
- ******************************************************************************/
-/* Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
- * size plus a little space for growth. */
+ ******************************************************************************
+ * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
+ * size plus a little space for growth.
+ */
#define RCAR_SYSRAM_BASE U(0xE6300000)
#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3)
#define BL2_LIMIT U(0xE6320000)
@@ -121,17 +123,19 @@
#endif
#define RCAR_SYSRAM_SIZE (BL2_BASE - RCAR_SYSRAM_BASE)
-/*******************************************************************************
+/*
+ ******************************************************************************
* BL31 specific defines.
- ******************************************************************************/
-/* Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
- * current BL3-1 debug size plus a little space for growth. */
+ ******************************************************************************
+ * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
+ * current BL3-1 debug size plus a little space for growth.
+ */
#define BL31_BASE (RCAR_TRUSTED_SRAM_BASE)
#define BL31_LIMIT (RCAR_TRUSTED_SRAM_BASE + \
RCAR_TRUSTED_SRAM_SIZE)
-#define RCAR_BL31_LOG_BASE (0x44040000)
-#define RCAR_BL31_SDRAM_BTM (RCAR_BL31_LOG_BASE + 0x14000)
-#define RCAR_BL31_LOG_SIZE (RCAR_BL31_SDRAM_BTM - RCAR_BL31_LOG_BASE)
+#define RCAR_BL31_LOG_BASE (0x44040000)
+#define RCAR_BL31_SDRAM_BTM (RCAR_BL31_LOG_BASE + 0x14000)
+#define RCAR_BL31_LOG_SIZE (RCAR_BL31_SDRAM_BTM - RCAR_BL31_LOG_BASE)
#define BL31_SRAM_BASE (DEVICE_SRAM_BASE)
#define BL31_SRAM_LIMIT (DEVICE_SRAM_BASE + DEVICE_SRAM_SIZE)
@@ -176,7 +180,7 @@
* Declarations and constants to access the mailboxes safely. Each mailbox is
* aligned on the biggest cache line size in the platform. This is known only
* to the platform as it might have a combination of integrated and external
- * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * caches. Such alignment ensures that two mailboxes do not sit on the same cache
* line at any cache level. They could belong to different cpus/clusters &
* get written while being protected by different locks causing corruption of
* a valid mailbox address.
diff --git a/plat/renesas/rcar/include/rcar_def.h b/plat/renesas/common/include/rcar_def.h
index 0ffbfe979..6c5b29561 100644
--- a/plat/renesas/rcar/include/rcar_def.h
+++ b/plat/renesas/common/include/rcar_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -33,13 +33,13 @@
#define DRAM1_SIZE U(0x80000000)
#define DRAM1_NS_BASE (DRAM1_BASE + U(0x10000000))
#define DRAM1_NS_SIZE (DRAM1_SIZE - DRAM1_NS_BASE)
-#define DRAM_40BIT_BASE ULL(0x0400000000)
-#define DRAM_40BIT_SIZE ULL(0x0400000000)
-#define DRAM_PROTECTED_BASE ULL(0x43F00000)
-#define DRAM_40BIT_PROTECTED_BASE ULL(0x0403F00000)
-#define DRAM_PROTECTED_SIZE ULL(0x03F00000)
-#define RCAR_BL31_CRASH_BASE U(0x4403F000)
-#define RCAR_BL31_CRASH_SIZE U(0x00001000)
+#define DRAM_40BIT_BASE ULL(0x0400000000)
+#define DRAM_40BIT_SIZE ULL(0x0400000000)
+#define DRAM_PROTECTED_BASE ULL(0x43F00000)
+#define DRAM_40BIT_PROTECTED_BASE ULL(0x0403F00000)
+#define DRAM_PROTECTED_SIZE ULL(0x03F00000)
+#define RCAR_BL31_CRASH_BASE U(0x4403F000)
+#define RCAR_BL31_CRASH_SIZE U(0x00001000)
/* Entrypoint mailboxes */
#define MBOX_BASE RCAR_SHARED_MEM_BASE
#define MBOX_SIZE 0x200
@@ -47,15 +47,19 @@
#define PARAMS_BASE (MBOX_BASE + MBOX_SIZE)
#define BOOT_KIND_BASE (RCAR_SHARED_MEM_BASE + \
RCAR_SHARED_MEM_SIZE - 0x100)
-/* The number of regions like RO(code), coherent and data required by
- * different BL stages which need to be mapped in the MMU */
+/*
+ * The number of regions like RO(code), coherent and data required by
+ * different BL stages which need to be mapped in the MMU
+ */
#if USE_COHERENT_MEM
#define RCAR_BL_REGIONS (3)
#else
#define RCAR_BL_REGIONS (2)
#endif
-/* The RCAR_MAX_MMAP_REGIONS depend on the number of entries in rcar_mmap[]
- * defined for each BL stage in rcar_common.c. */
+/*
+ * The RCAR_MAX_MMAP_REGIONS depends on the number of entries in rcar_mmap[]
+ * defined for each BL stage in rcar_common.c.
+ */
#if IMAGE_BL2
#define RCAR_MMAP_ENTRIES (9)
#endif
@@ -73,24 +77,24 @@
/* BL33 */
#define NS_IMAGE_OFFSET (DRAM1_BASE + U(0x09000000))
/* BL31 */
-#define RCAR_DEVICE_BASE DEVICE_RCAR_BASE
-#define RCAR_DEVICE_SIZE (0x1A000000)
-#define RCAR_LOG_RES_SIZE (512/8)
-#define RCAR_LOG_HEADER_SIZE (16)
-#define RCAR_LOG_OTHER_SIZE (RCAR_LOG_HEADER_SIZE + \
+#define RCAR_DEVICE_BASE DEVICE_RCAR_BASE
+#define RCAR_DEVICE_SIZE (0x1A000000)
+#define RCAR_LOG_RES_SIZE (64)
+#define RCAR_LOG_HEADER_SIZE (16)
+#define RCAR_LOG_OTHER_SIZE (RCAR_LOG_HEADER_SIZE + \
RCAR_LOG_RES_SIZE)
-#define RCAR_BL31_LOG_MAX (RCAR_BL31_LOG_SIZE - \
+#define RCAR_BL31_LOG_MAX (RCAR_BL31_LOG_SIZE - \
RCAR_LOG_OTHER_SIZE)
-#define RCAR_CRASH_STACK RCAR_BL31_CRASH_BASE
-#define AARCH64_SPACE_BASE ULL(0x00000000000)
-#define AARCH64_SPACE_SIZE ULL(0x10000000000)
+#define RCAR_CRASH_STACK RCAR_BL31_CRASH_BASE
+#define AARCH64_SPACE_BASE ULL(0x00000000000)
+#define AARCH64_SPACE_SIZE ULL(0x10000000000)
/* CCI related constants */
#define CCI500_BASE U(0xF1200000)
#define CCI500_CLUSTER0_SL_IFACE_IX (2)
#define CCI500_CLUSTER1_SL_IFACE_IX (3)
#define CCI500_CLUSTER0_SL_IFACE_IX_FOR_M3 (1)
#define CCI500_CLUSTER1_SL_IFACE_IX_FOR_M3 (2)
-#define RCAR_CCI_BASE CCI500_BASE
+#define RCAR_CCI_BASE CCI500_BASE
/* GIC */
#define RCAR_GICD_BASE U(0xF1010000)
#define RCAR_GICR_BASE U(0xF1010000)
@@ -106,47 +110,47 @@
#define ARM_IRQ_SEC_SGI_5 U(13)
#define ARM_IRQ_SEC_SGI_6 U(14)
#define ARM_IRQ_SEC_SGI_7 U(15)
-#define ARM_IRQ_SEC_RPC U(70)
-#define ARM_IRQ_SEC_TIMER U(166)
-#define ARM_IRQ_SEC_TIMER_UP U(171)
-#define ARM_IRQ_SEC_WDT U(173)
-#define ARM_IRQ_SEC_CRYPT U(102)
-#define ARM_IRQ_SEC_CRYPT_SecPKA U(97)
-#define ARM_IRQ_SEC_CRYPT_PubPKA U(98)
+#define ARM_IRQ_SEC_RPC U(70)
+#define ARM_IRQ_SEC_TIMER U(166)
+#define ARM_IRQ_SEC_TIMER_UP U(171)
+#define ARM_IRQ_SEC_WDT U(173)
+#define ARM_IRQ_SEC_CRYPT U(102)
+#define ARM_IRQ_SEC_CRYPT_SecPKA U(97)
+#define ARM_IRQ_SEC_CRYPT_PubPKA U(98)
/* Timer control */
-#define RCAR_CNTC_BASE U(0xE6080000)
+#define RCAR_CNTC_BASE U(0xE6080000)
/* Reset */
-#define RCAR_CPGWPR U(0xE6150900) /* CPG write protect */
-#define RCAR_MODEMR U(0xE6160060) /* Mode pin */
-#define RCAR_CA57RESCNT U(0xE6160040) /* Reset control A57 */
-#define RCAR_CA53RESCNT U(0xE6160044) /* Reset control A53 */
-#define RCAR_SRESCR U(0xE6160110) /* Soft Power On Reset */
-#define RCAR_CA53WUPCR U(0xE6151010) /* Wake-up control A53 */
-#define RCAR_CA57WUPCR U(0xE6152010) /* Wake-up control A57 */
-#define RCAR_CA53PSTR U(0xE6151040) /* Power status A53 */
-#define RCAR_CA57PSTR U(0xE6152040) /* Power status A57 */
-#define RCAR_CA53CPU0CR U(0xE6151100) /* CPU control A53 */
-#define RCAR_CA57CPU0CR U(0xE6152100) /* CPU control A57 */
-#define RCAR_CA53CPUCMCR U(0xE6151184) /* Common power A53 */
-#define RCAR_CA57CPUCMCR U(0xE6152184) /* Common power A57 */
-#define RCAR_WUPMSKCA57 U(0xE6180014) /* Wake-up mask A57 */
-#define RCAR_WUPMSKCA53 U(0xE6180018) /* Wake-up mask A53 */
+#define RCAR_CPGWPR U(0xE6150900) /* CPG write protect */
+#define RCAR_MODEMR U(0xE6160060) /* Mode pin */
+#define RCAR_CA57RESCNT U(0xE6160040) /* Reset control A57 */
+#define RCAR_CA53RESCNT U(0xE6160044) /* Reset control A53 */
+#define RCAR_SRESCR U(0xE6160110) /* Soft Power On Reset */
+#define RCAR_CA53WUPCR U(0xE6151010) /* Wake-up control A53 */
+#define RCAR_CA57WUPCR U(0xE6152010) /* Wake-up control A57 */
+#define RCAR_CA53PSTR U(0xE6151040) /* Power status A53 */
+#define RCAR_CA57PSTR U(0xE6152040) /* Power status A57 */
+#define RCAR_CA53CPU0CR U(0xE6151100) /* CPU control A53 */
+#define RCAR_CA57CPU0CR U(0xE6152100) /* CPU control A57 */
+#define RCAR_CA53CPUCMCR U(0xE6151184) /* Common power A53 */
+#define RCAR_CA57CPUCMCR U(0xE6152184) /* Common power A57 */
+#define RCAR_WUPMSKCA57 U(0xE6180014) /* Wake-up mask A57 */
+#define RCAR_WUPMSKCA53 U(0xE6180018) /* Wake-up mask A53 */
/* SYSC */
-#define RCAR_PWRSR3 U(0xE6180140) /* Power stat A53-SCU */
-#define RCAR_PWRSR5 U(0xE61801C0) /* Power stat A57-SCU */
-#define RCAR_SYSCIER U(0xE618000C) /* Interrupt enable */
-#define RCAR_SYSCIMR U(0xE6180010) /* Interrupt mask */
-#define RCAR_SYSCSR U(0xE6180000) /* SYSC status */
-#define RCAR_PWRONCR3 U(0xE618014C) /* Power resume A53-SCU */
-#define RCAR_PWRONCR5 U(0xE61801CC) /* Power resume A57-SCU */
-#define RCAR_PWROFFCR3 U(0xE6180144) /* Power shutof A53-SCU */
-#define RCAR_PWROFFCR5 U(0xE61801C4) /* Power shutof A57-SCU */
-#define RCAR_PWRER3 U(0xE6180154) /* shutoff/resume error */
-#define RCAR_PWRER5 U(0xE61801D4) /* shutoff/resume error */
-#define RCAR_SYSCISR U(0xE6180004) /* Interrupt status */
-#define RCAR_SYSCISCR U(0xE6180008) /* Interrupt stat clear */
+#define RCAR_PWRSR3 U(0xE6180140) /* Power stat A53-SCU */
+#define RCAR_PWRSR5 U(0xE61801C0) /* Power stat A57-SCU */
+#define RCAR_SYSCIER U(0xE618000C) /* Interrupt enable */
+#define RCAR_SYSCIMR U(0xE6180010) /* Interrupt mask */
+#define RCAR_SYSCSR U(0xE6180000) /* SYSC status */
+#define RCAR_PWRONCR3 U(0xE618014C) /* Power resume A53-SCU */
+#define RCAR_PWRONCR5 U(0xE61801CC) /* Power resume A57-SCU */
+#define RCAR_PWROFFCR3 U(0xE6180144) /* Power shutoff A53-SCU */
+#define RCAR_PWROFFCR5 U(0xE61801C4) /* Power shutoff A57-SCU */
+#define RCAR_PWRER3 U(0xE6180154) /* shutoff/resume error */
+#define RCAR_PWRER5 U(0xE61801D4) /* shutoff/resume error */
+#define RCAR_SYSCISR U(0xE6180004) /* Interrupt status */
+#define RCAR_SYSCISCR U(0xE6180008) /* Interrupt stat clear */
/* Product register */
-#define RCAR_PRR U(0xFFF00044)
+#define RCAR_PRR U(0xFFF00044)
#define RCAR_M3_CUT_VER11 U(0x00000010) /* M3 Ver.1.1/Ver.1.2 */
#define RCAR_MAJOR_MASK U(0x000000F0)
#define RCAR_MINOR_MASK U(0x0000000F)
@@ -198,39 +202,39 @@
/* Memory mapped Generic timer interfaces */
#define ARM_SYS_CNTCTL_BASE RCAR_CNTC_BASE
/* MODEMR PLL masks and bitfield values */
-#define CHECK_MD13_MD14 U(0x6000)
-#define MD14_MD13_TYPE_0 U(0x0000) /* MD14=0 MD13=0 */
-#define MD14_MD13_TYPE_1 U(0x2000) /* MD14=0 MD13=1 */
-#define MD14_MD13_TYPE_2 U(0x4000) /* MD14=1 MD13=0 */
-#define MD14_MD13_TYPE_3 U(0x6000) /* MD14=1 MD13=1 */
+#define CHECK_MD13_MD14 U(0x6000)
+#define MD14_MD13_TYPE_0 U(0x0000) /* MD14=0 MD13=0 */
+#define MD14_MD13_TYPE_1 U(0x2000) /* MD14=0 MD13=1 */
+#define MD14_MD13_TYPE_2 U(0x4000) /* MD14=1 MD13=0 */
+#define MD14_MD13_TYPE_3 U(0x6000) /* MD14=1 MD13=1 */
/* Frequency of EXTAL(Hz) */
-#define EXTAL_MD14_MD13_TYPE_0 U(8333300) /* MD14=0 MD13=0 */
-#define EXTAL_MD14_MD13_TYPE_1 U(10000000) /* MD14=0 MD13=1 */
-#define EXTAL_MD14_MD13_TYPE_2 U(12500000) /* MD14=1 MD13=0 */
-#define EXTAL_MD14_MD13_TYPE_3 U(16666600) /* MD14=1 MD13=1 */
-#define EXTAL_SALVATOR_XS U(8320000) /* Salvator-XS */
+#define EXTAL_MD14_MD13_TYPE_0 U(8333300) /* MD14=0 MD13=0 */
+#define EXTAL_MD14_MD13_TYPE_1 U(10000000) /* MD14=0 MD13=1 */
+#define EXTAL_MD14_MD13_TYPE_2 U(12500000) /* MD14=1 MD13=0 */
+#define EXTAL_MD14_MD13_TYPE_3 U(16666600) /* MD14=1 MD13=1 */
+#define EXTAL_SALVATOR_XS U(8320000) /* Salvator-XS */
#define EXTAL_EBISU U(24000000) /* Ebisu */
#define EXTAL_DRAAK U(24000000) /* Draak */
-/* CPG write protect registers */
-#define CPGWPR_PASSWORD (0x5A5AFFFFU)
-#define CPGWPCR_PASSWORD (0xA5A50000U)
+/* CPG write protect registers */
+#define CPGWPR_PASSWORD (0x5A5AFFFFU)
+#define CPGWPCR_PASSWORD (0xA5A50000U)
/* CA5x Debug Resource control registers */
-#define CPG_CA57DBGRCR (CPG_BASE + 0x2180U)
-#define CPG_CA53DBGRCR (CPG_BASE + 0x1180U)
-#define DBGCPUPREN ((uint32_t)1U << 19U)
-#define CPG_PLL0CR (CPG_BASE + 0x00D8U)
-#define CPG_PLL2CR (CPG_BASE + 0x002CU)
-#define CPG_PLL4CR (CPG_BASE + 0x01F4U)
+#define CPG_CA57DBGRCR (CPG_BASE + 0x2180U)
+#define CPG_CA53DBGRCR (CPG_BASE + 0x1180U)
+#define DBGCPUPREN ((uint32_t)1U << 19U)
+#define CPG_PLL0CR (CPG_BASE + 0x00D8U)
+#define CPG_PLL2CR (CPG_BASE + 0x002CU)
+#define CPG_PLL4CR (CPG_BASE + 0x01F4U)
#define CPG_CPGWPCR (CPG_BASE + 0x0904U)
/* RST Registers */
-#define RST_BASE (0xE6160000U)
-#define RST_WDTRSTCR (RST_BASE + 0x0054U)
+#define RST_BASE (0xE6160000U)
+#define RST_WDTRSTCR (RST_BASE + 0x0054U)
#define RST_MODEMR (RST_BASE + 0x0060U)
-#define WDTRSTCR_PASSWORD (0xA55A0000U)
-#define WDTRSTCR_RWDT_RSTMSK ((uint32_t)1U << 0U)
+#define WDTRSTCR_PASSWORD (0xA55A0000U)
+#define WDTRSTCR_RWDT_RSTMSK ((uint32_t)1U << 0U)
/* MFIS Registers */
-#define MFISWPCNTR_PASSWORD (0xACCE0000U)
-#define MFISWPCNTR (0xE6260900U)
+#define MFISWPCNTR_PASSWORD (0xACCE0000U)
+#define MFISWPCNTR (0xE6260900U)
/* IPMMU registers */
#define IPMMU_MM_BASE (0xE67B0000U)
#define IPMMUMM_IMSCTLR (IPMMU_MM_BASE + 0x0500U)
@@ -263,8 +267,8 @@
#define IPMMU_DS1_BASE (0xE7740000U)
#define IPMMUDS1_IMSCTLR (IPMMU_DS1_BASE + 0x0500U)
/* ARMREG registers */
-#define P_ARMREG_SEC_CTRL (0xE62711F0U)
-#define P_ARMREG_SEC_CTRL_PROT (0x00000001U)
+#define P_ARMREG_SEC_CTRL (0xE62711F0U)
+#define P_ARMREG_SEC_CTRL_PROT (0x00000001U)
/* MIDR */
#define MIDR_CA57 (0x0D07U << MIDR_PN_SHIFT)
#define MIDR_CA53 (0x0D03U << MIDR_PN_SHIFT)
@@ -279,28 +283,28 @@
#define RCAR_COLD_BOOT (0x00U)
#define RCAR_WARM_BOOT (0x01U)
#if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR
-#define KEEP10_MAGIC (0x55U)
+#define KEEP10_MAGIC (0x55U)
#endif
/* lossy registers */
-#define LOSSY_PARAMS_BASE (0x47FD7000U)
-#define AXI_DCMPAREACRA0 (0xE6784100U)
-#define AXI_DCMPAREACRB0 (0xE6784104U)
+#define LOSSY_PARAMS_BASE (0x47FD7000U)
+#define AXI_DCMPAREACRA0 (0xE6784100U)
+#define AXI_DCMPAREACRB0 (0xE6784104U)
#define LOSSY_ENABLE (0x80000000U)
#define LOSSY_DISABLE (0x00000000U)
#define LOSSY_FMT_YUVPLANAR (0x00000000U)
#define LOSSY_FMT_YUV422INTLV (0x20000000U)
#define LOSSY_FMT_ARGB8888 (0x40000000U)
-#define LOSSY_ST_ADDR0 (0x54000000U)
-#define LOSSY_END_ADDR0 (0x57000000U)
-#define LOSSY_FMT0 LOSSY_FMT_YUVPLANAR
-#define LOSSY_ENA_DIS0 LOSSY_ENABLE
-#define LOSSY_ST_ADDR1 0x0U
-#define LOSSY_END_ADDR1 0x0U
-#define LOSSY_FMT1 LOSSY_FMT_ARGB8888
-#define LOSSY_ENA_DIS1 LOSSY_DISABLE
-#define LOSSY_ST_ADDR2 0x0U
-#define LOSSY_END_ADDR2 0x0U
-#define LOSSY_FMT2 LOSSY_FMT_YUV422INTLV
-#define LOSSY_ENA_DIS2 LOSSY_DISABLE
+#define LOSSY_ST_ADDR0 (0x54000000U)
+#define LOSSY_END_ADDR0 (0x57000000U)
+#define LOSSY_FMT0 LOSSY_FMT_YUVPLANAR
+#define LOSSY_ENA_DIS0 LOSSY_ENABLE
+#define LOSSY_ST_ADDR1 0x0U
+#define LOSSY_END_ADDR1 0x0U
+#define LOSSY_FMT1 LOSSY_FMT_ARGB8888
+#define LOSSY_ENA_DIS1 LOSSY_DISABLE
+#define LOSSY_ST_ADDR2 0x0U
+#define LOSSY_END_ADDR2 0x0U
+#define LOSSY_FMT2 LOSSY_FMT_YUV422INTLV
+#define LOSSY_ENA_DIS2 LOSSY_DISABLE
#endif /* RCAR_DEF_H */
diff --git a/plat/renesas/rcar/include/rcar_private.h b/plat/renesas/common/include/rcar_private.h
index a76c0238b..36f4ca540 100644
--- a/plat/renesas/rcar/include/rcar_private.h
+++ b/plat/renesas/common/include/rcar_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,12 +7,12 @@
#ifndef RCAR_PRIVATE_H
#define RCAR_PRIVATE_H
-#include <platform_def.h>
-
#include <common/bl_common.h>
#include <lib/bakery_lock.h>
#include <lib/el3_runtime/cpu_data.h>
+#include <platform_def.h>
+
typedef volatile struct mailbox {
unsigned long value __aligned(CACHE_WRITEBACK_GRANULE);
} mailbox_t;
@@ -62,17 +62,18 @@ typedef struct rcar_cpu_data {
*/
#define rcar_lock_init(_lock_arg)
-#define rcar_lock_get(_lock_arg) \
- bakery_lock_get(_lock_arg, \
+#define rcar_lock_get(_lock_arg) \
+ bakery_lock_get(_lock_arg, \
CPU_DATA_PLAT_PCPU_OFFSET + RCAR_CPU_DATA_LOCK_OFFSET)
#define rcar_lock_release(_lock_arg) \
- bakery_lock_release(_lock_arg, \
+ bakery_lock_release(_lock_arg, \
CPU_DATA_PLAT_PCPU_OFFSET + RCAR_CPU_DATA_LOCK_OFFSET)
-/* Ensure that the size of the RCAR specific per-cpu data structure and the size
+/*
+ * Ensure that the size of the RCAR specific per-cpu data structure and the size
* of the memory allocated in generic per-cpu data for the platform are the same
*/
-CASSERT(PLAT_PCPU_DATA_SIZE == sizeof(rcar_cpu_data_t),
+CASSERT(sizeof(rcar_cpu_data_t) == PLAT_PCPU_DATA_SIZE,
rcar_pcpu_data_size_mismatch);
#endif
/*
@@ -84,7 +85,7 @@ void rcar_configure_mmu_el3(unsigned long total_base,
#if USE_COHERENT_MEM
, unsigned long coh_start, unsigned long coh_limit
#endif
- );
+ );
void rcar_setup_topology(void);
void rcar_cci_disable(void);
diff --git a/plat/renesas/rcar/include/rcar_version.h b/plat/renesas/common/include/rcar_version.h
index 2d400e064..67cbd71ab 100644
--- a/plat/renesas/rcar/include/rcar_version.h
+++ b/plat/renesas/common/include/rcar_version.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,8 +9,8 @@
#include <arch_helpers.h>
-#define VERSION_OF_RENESAS "2.0.4"
-#define VERSION_OF_RENESAS_MAXLEN (128)
+#define VERSION_OF_RENESAS "2.0.6"
+#define VERSION_OF_RENESAS_MAXLEN 128
extern const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN];
diff --git a/plat/renesas/rcar/include/registers/axi_registers.h b/plat/renesas/common/include/registers/axi_registers.h
index 36cd58bd9..36cd58bd9 100644
--- a/plat/renesas/rcar/include/registers/axi_registers.h
+++ b/plat/renesas/common/include/registers/axi_registers.h
diff --git a/plat/renesas/rcar/include/registers/cpg_registers.h b/plat/renesas/common/include/registers/cpg_registers.h
index 0d698d9c1..0d698d9c1 100644
--- a/plat/renesas/rcar/include/registers/cpg_registers.h
+++ b/plat/renesas/common/include/registers/cpg_registers.h
diff --git a/plat/renesas/common/include/registers/lifec_registers.h b/plat/renesas/common/include/registers/lifec_registers.h
new file mode 100644
index 000000000..5f49e52c0
--- /dev/null
+++ b/plat/renesas/common/include/registers/lifec_registers.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef LIFEC_REGISTERS_H
+#define LIFEC_REGISTERS_H
+
+#define LIFEC_SEC_BASE (0xE6110000U)
+
+#define SEC_SRC (LIFEC_SEC_BASE + 0x0008U)
+#define SEC_SEL0 (LIFEC_SEC_BASE + 0x0030U)
+#define SEC_SEL1 (LIFEC_SEC_BASE + 0x0034U)
+#define SEC_SEL2 (LIFEC_SEC_BASE + 0x0038U)
+#define SEC_SEL3 (LIFEC_SEC_BASE + 0x003CU)
+#define SEC_SEL4 (LIFEC_SEC_BASE + 0x0058U)
+#define SEC_SEL5 (LIFEC_SEC_BASE + 0x005CU)
+#define SEC_SEL6 (LIFEC_SEC_BASE + 0x0060U)
+#define SEC_SEL7 (LIFEC_SEC_BASE + 0x0064U)
+#define SEC_SEL8 (LIFEC_SEC_BASE + 0x0068U)
+#define SEC_SEL9 (LIFEC_SEC_BASE + 0x006CU)
+#define SEC_SEL10 (LIFEC_SEC_BASE + 0x0070U)
+#define SEC_SEL11 (LIFEC_SEC_BASE + 0x0074U)
+#define SEC_SEL12 (LIFEC_SEC_BASE + 0x0078U)
+#define SEC_SEL13 (LIFEC_SEC_BASE + 0x007CU)
+#define SEC_SEL14 (LIFEC_SEC_BASE + 0x0080U)
+#define SEC_SEL15 (LIFEC_SEC_BASE + 0x0084U)
+#define SEC_GRP0CR0 (LIFEC_SEC_BASE + 0x0138U)
+#define SEC_GRP1CR0 (LIFEC_SEC_BASE + 0x013CU)
+#define SEC_GRP0CR1 (LIFEC_SEC_BASE + 0x0140U)
+#define SEC_GRP1CR1 (LIFEC_SEC_BASE + 0x0144U)
+#define SEC_GRP0CR2 (LIFEC_SEC_BASE + 0x0148U)
+#define SEC_GRP1CR2 (LIFEC_SEC_BASE + 0x014CU)
+#define SEC_GRP0CR3 (LIFEC_SEC_BASE + 0x0150U)
+#define SEC_GRP1CR3 (LIFEC_SEC_BASE + 0x0154U)
+#define SEC_GRP0COND0 (LIFEC_SEC_BASE + 0x0158U)
+#define SEC_GRP1COND0 (LIFEC_SEC_BASE + 0x015CU)
+#define SEC_GRP0COND1 (LIFEC_SEC_BASE + 0x0160U)
+#define SEC_GRP1COND1 (LIFEC_SEC_BASE + 0x0164U)
+#define SEC_GRP0COND2 (LIFEC_SEC_BASE + 0x0168U)
+#define SEC_GRP1COND2 (LIFEC_SEC_BASE + 0x016CU)
+#define SEC_GRP0COND3 (LIFEC_SEC_BASE + 0x0170U)
+#define SEC_GRP1COND3 (LIFEC_SEC_BASE + 0x0174U)
+#define SEC_GRP0COND4 (LIFEC_SEC_BASE + 0x0178U)
+#define SEC_GRP1COND4 (LIFEC_SEC_BASE + 0x017CU)
+#define SEC_GRP0COND5 (LIFEC_SEC_BASE + 0x0180U)
+#define SEC_GRP1COND5 (LIFEC_SEC_BASE + 0x0184U)
+#define SEC_GRP0COND6 (LIFEC_SEC_BASE + 0x0188U)
+#define SEC_GRP1COND6 (LIFEC_SEC_BASE + 0x018CU)
+#define SEC_GRP0COND7 (LIFEC_SEC_BASE + 0x0190U)
+#define SEC_GRP1COND7 (LIFEC_SEC_BASE + 0x0194U)
+#define SEC_GRP0COND8 (LIFEC_SEC_BASE + 0x0198U)
+#define SEC_GRP1COND8 (LIFEC_SEC_BASE + 0x019CU)
+#define SEC_GRP0COND9 (LIFEC_SEC_BASE + 0x01A0U)
+#define SEC_GRP1COND9 (LIFEC_SEC_BASE + 0x01A4U)
+#define SEC_GRP0COND10 (LIFEC_SEC_BASE + 0x01A8U)
+#define SEC_GRP1COND10 (LIFEC_SEC_BASE + 0x01ACU)
+#define SEC_GRP0COND11 (LIFEC_SEC_BASE + 0x01B0U)
+#define SEC_GRP1COND11 (LIFEC_SEC_BASE + 0x01B4U)
+#define SEC_GRP0COND12 (LIFEC_SEC_BASE + 0x01B8U)
+#define SEC_GRP1COND12 (LIFEC_SEC_BASE + 0x01BCU)
+#define SEC_GRP0COND13 (LIFEC_SEC_BASE + 0x01C0U)
+#define SEC_GRP1COND13 (LIFEC_SEC_BASE + 0x01C4U)
+#define SEC_GRP0COND14 (LIFEC_SEC_BASE + 0x01C8U)
+#define SEC_GRP1COND14 (LIFEC_SEC_BASE + 0x01CCU)
+#define SEC_GRP0COND15 (LIFEC_SEC_BASE + 0x01D0U)
+#define SEC_GRP1COND15 (LIFEC_SEC_BASE + 0x01D4U)
+#define SEC_READONLY0 (LIFEC_SEC_BASE + 0x01D8U)
+#define SEC_READONLY1 (LIFEC_SEC_BASE + 0x01DCU)
+#define SEC_READONLY2 (LIFEC_SEC_BASE + 0x01E0U)
+#define SEC_READONLY3 (LIFEC_SEC_BASE + 0x01E4U)
+#define SEC_READONLY4 (LIFEC_SEC_BASE + 0x01E8U)
+#define SEC_READONLY5 (LIFEC_SEC_BASE + 0x01ECU)
+#define SEC_READONLY6 (LIFEC_SEC_BASE + 0x01F0U)
+#define SEC_READONLY7 (LIFEC_SEC_BASE + 0x01F4U)
+#define SEC_READONLY8 (LIFEC_SEC_BASE + 0x01F8U)
+#define SEC_READONLY9 (LIFEC_SEC_BASE + 0x01FCU)
+#define SEC_READONLY10 (LIFEC_SEC_BASE + 0x0200U)
+#define SEC_READONLY11 (LIFEC_SEC_BASE + 0x0204U)
+#define SEC_READONLY12 (LIFEC_SEC_BASE + 0x0208U)
+#define SEC_READONLY13 (LIFEC_SEC_BASE + 0x020CU)
+#define SEC_READONLY14 (LIFEC_SEC_BASE + 0x0210U)
+#define SEC_READONLY15 (LIFEC_SEC_BASE + 0x0214U)
+
+#define LIFEC_SAFE_BASE (0xE6120000U)
+#define SAFE_GRP0CR0 (LIFEC_SAFE_BASE + 0x0138U)
+#define SAFE_GRP1CR0 (LIFEC_SAFE_BASE + 0x013CU)
+#define SAFE_GRP0CR1 (LIFEC_SAFE_BASE + 0x0140U)
+#define SAFE_GRP1CR1 (LIFEC_SAFE_BASE + 0x0144U)
+#define SAFE_GRP0CR2 (LIFEC_SAFE_BASE + 0x0148U)
+#define SAFE_GRP1CR2 (LIFEC_SAFE_BASE + 0x014CU)
+#define SAFE_GRP0CR3 (LIFEC_SAFE_BASE + 0x0150U)
+#define SAFE_GRP1CR3 (LIFEC_SAFE_BASE + 0x0154U)
+#define SAFE_GRP0COND0 (LIFEC_SAFE_BASE + 0x0158U)
+#define SAFE_GRP1COND0 (LIFEC_SAFE_BASE + 0x015CU)
+#define SAFE_GRP0COND1 (LIFEC_SAFE_BASE + 0x0160U)
+#define SAFE_GRP1COND1 (LIFEC_SAFE_BASE + 0x0164U)
+#define SAFE_GRP0COND2 (LIFEC_SAFE_BASE + 0x0168U)
+#define SAFE_GRP1COND2 (LIFEC_SAFE_BASE + 0x016CU)
+#define SAFE_GRP0COND3 (LIFEC_SAFE_BASE + 0x0170U)
+#define SAFE_GRP1COND3 (LIFEC_SAFE_BASE + 0x0174U)
+#define SAFE_GRP0COND4 (LIFEC_SAFE_BASE + 0x0178U)
+#define SAFE_GRP1COND4 (LIFEC_SAFE_BASE + 0x017CU)
+#define SAFE_GRP0COND5 (LIFEC_SAFE_BASE + 0x0180U)
+#define SAFE_GRP1COND5 (LIFEC_SAFE_BASE + 0x0184U)
+#define SAFE_GRP0COND6 (LIFEC_SAFE_BASE + 0x0188U)
+#define SAFE_GRP1COND6 (LIFEC_SAFE_BASE + 0x018CU)
+#define SAFE_GRP0COND7 (LIFEC_SAFE_BASE + 0x0190U)
+#define SAFE_GRP1COND7 (LIFEC_SAFE_BASE + 0x0194U)
+#define SAFE_GRP0COND8 (LIFEC_SAFE_BASE + 0x0198U)
+#define SAFE_GRP1COND8 (LIFEC_SAFE_BASE + 0x019CU)
+#define SAFE_GRP0COND9 (LIFEC_SAFE_BASE + 0x01A0U)
+#define SAFE_GRP1COND9 (LIFEC_SAFE_BASE + 0x01A4U)
+#define SAFE_GRP0COND10 (LIFEC_SAFE_BASE + 0x01A8U)
+#define SAFE_GRP1COND10 (LIFEC_SAFE_BASE + 0x01ACU)
+#define SAFE_GRP0COND11 (LIFEC_SAFE_BASE + 0x01B0U)
+#define SAFE_GRP1COND11 (LIFEC_SAFE_BASE + 0x01B4U)
+#define SAFE_GRP0COND12 (LIFEC_SAFE_BASE + 0x01B8U)
+#define SAFE_GRP1COND12 (LIFEC_SAFE_BASE + 0x01BCU)
+#define SAFE_GRP0COND13 (LIFEC_SAFE_BASE + 0x01C0U)
+#define SAFE_GRP1COND13 (LIFEC_SAFE_BASE + 0x01C4U)
+#define SAFE_GRP0COND14 (LIFEC_SAFE_BASE + 0x01C8U)
+#define SAFE_GRP1COND14 (LIFEC_SAFE_BASE + 0x01CCU)
+#define SAFE_GRP0COND15 (LIFEC_SAFE_BASE + 0x01D0U)
+#define SAFE_GRP1COND15 (LIFEC_SAFE_BASE + 0x01D4U)
+#define SAFE_READONLY0 (LIFEC_SAFE_BASE + 0x01D8U)
+#define SAFE_READONLY1 (LIFEC_SAFE_BASE + 0x01DCU)
+#define SAFE_READONLY2 (LIFEC_SAFE_BASE + 0x01E0U)
+#define SAFE_READONLY3 (LIFEC_SAFE_BASE + 0x01E4U)
+#define SAFE_READONLY4 (LIFEC_SAFE_BASE + 0x01E8U)
+#define SAFE_READONLY5 (LIFEC_SAFE_BASE + 0x01ECU)
+#define SAFE_READONLY6 (LIFEC_SAFE_BASE + 0x01F0U)
+#define SAFE_READONLY7 (LIFEC_SAFE_BASE + 0x01F4U)
+#define SAFE_READONLY8 (LIFEC_SAFE_BASE + 0x01F8U)
+#define SAFE_READONLY9 (LIFEC_SAFE_BASE + 0x01FCU)
+#define SAFE_READONLY10 (LIFEC_SAFE_BASE + 0x0200U)
+#define SAFE_READONLY11 (LIFEC_SAFE_BASE + 0x0204U)
+#define SAFE_READONLY12 (LIFEC_SAFE_BASE + 0x0208U)
+#define SAFE_READONLY13 (LIFEC_SAFE_BASE + 0x020CU)
+#define SAFE_READONLY14 (LIFEC_SAFE_BASE + 0x0210U)
+#define SAFE_READONLY15 (LIFEC_SAFE_BASE + 0x0214U)
+
+#endif /* LIFEC_REGISTERS_H */
diff --git a/plat/renesas/rcar/plat_image_load.c b/plat/renesas/common/plat_image_load.c
index 9d814a6e5..9d814a6e5 100644
--- a/plat/renesas/rcar/plat_image_load.c
+++ b/plat/renesas/common/plat_image_load.c
diff --git a/plat/renesas/rcar/plat_pm.c b/plat/renesas/common/plat_pm.c
index 6fc47b95c..6a9ad450d 100644
--- a/plat/renesas/rcar/plat_pm.c
+++ b/plat/renesas/common/plat_pm.c
@@ -6,8 +6,6 @@
#include <errno.h>
-#include <platform_def.h>
-
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <common/debug.h>
@@ -19,17 +17,20 @@
#include <plat/common/platform.h>
#include "iic_dvfs.h"
+#include "platform_def.h"
#include "pwrc.h"
#include "rcar_def.h"
#include "rcar_private.h"
+#if RCAR_GEN3_ULCB
#include "ulcb_cpld.h"
+#endif /* RCAR_GEN3_ULCB */
-#define DVFS_SET_VID_0V (0x00)
-#define P_ALL_OFF (0x80)
-#define KEEPON_DDR1C (0x08)
-#define KEEPON_DDR0C (0x04)
-#define KEEPON_DDR1 (0x02)
-#define KEEPON_DDR0 (0x01)
+#define DVFS_SET_VID_0V (0x00)
+#define P_ALL_OFF (0x80)
+#define KEEPON_DDR1C (0x08)
+#define KEEPON_DDR0C (0x04)
+#define KEEPON_DDR1 (0x02)
+#define KEEPON_DDR0 (0x01)
#define SYSTEM_PWR_STATE(s) ((s)->pwr_domain_state[PLAT_MAX_PWR_LVL])
#define CLUSTER_PWR_STATE(s) ((s)->pwr_domain_state[MPIDR_AFFLVL1])
@@ -200,20 +201,20 @@ static void __dead2 rcar_system_reset(void)
error = rcar_iic_dvfs_send(PMIC, REG_KEEP10, KEEP10_MAGIC);
if (error) {
- ERROR("Failed send KEEP10 magic ret=%d \n", error);
+ ERROR("Failed send KEEP10 magic ret=%d\n", error);
goto done;
}
error = rcar_iic_dvfs_receive(PMIC, BKUP_MODE_CNT, &mode);
if (error) {
- ERROR("Failed recieve BKUP_Mode_Cnt ret=%d \n", error);
+ ERROR("Failed receive BKUP_Mode_Cnt ret=%d\n", error);
goto done;
}
mode |= KEEPON_DDR1C | KEEPON_DDR0C | KEEPON_DDR1 | KEEPON_DDR0;
error = rcar_iic_dvfs_send(PMIC, BKUP_MODE_CNT, mode);
if (error) {
- ERROR("Failed send KEEPON_DDRx ret=%d \n", error);
+ ERROR("Failed send KEEPON_DDRx ret=%d\n", error);
goto done;
}
@@ -292,7 +293,7 @@ static const plat_psci_ops_t rcar_plat_psci_ops = {
.system_reset = rcar_system_reset,
.validate_power_state = rcar_validate_power_state,
#if RCAR_SYSTEM_SUSPEND
- .get_sys_suspend_power_state = rcar_get_sys_suspend_power_state,
+ .get_sys_suspend_power_state = rcar_get_sys_suspend_power_state,
#endif
};
diff --git a/plat/renesas/rcar/plat_storage.c b/plat/renesas/common/plat_storage.c
index 05e3d9f0d..652456103 100644
--- a/plat/renesas/rcar/plat_storage.c
+++ b/plat/renesas/common/plat_storage.c
@@ -1,23 +1,22 @@
/*
- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <string.h>
-#include <platform_def.h>
-
#include <common/debug.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_storage.h>
#include <drivers/io/io_semihosting.h>
#include "io_common.h"
-#include "io_rcar.h"
#include "io_memdrv.h"
#include "io_emmcdrv.h"
#include "io_private.h"
+#include "io_rcar.h"
+#include <platform_def.h>
static uintptr_t emmcdrv_dev_handle;
static uintptr_t memdrv_dev_handle;
@@ -167,7 +166,7 @@ static int32_t open_rcar(const uintptr_t spec);
struct plat_io_policy {
uintptr_t *dev_handle;
uintptr_t image_spec;
- int32_t(*check) (const uintptr_t spec);
+ int32_t (*check)(const uintptr_t spec);
};
static const struct plat_io_policy policies[] = {
@@ -305,7 +304,7 @@ static const struct plat_io_policy policies[] = {
(uintptr_t) &bl338_cert_file_spec,
&open_rcar}, {
#else
- {
+ {
#endif
0, 0, 0}
};
@@ -322,16 +321,11 @@ static io_drv_spec_t io_drv_spec_emmcdrv = {
0,
};
-static struct plat_io_policy drv_policies[]
- __attribute__ ((section(".data"))) = {
+static struct plat_io_policy drv_policies[] __attribute__ ((section(".data"))) = {
/* FLASH_DEV_ID */
- {
- &memdrv_dev_handle,
- (uintptr_t) &io_drv_spec_memdrv, &open_memmap,},
- /* EMMC_DEV_ID */
- {
- &emmcdrv_dev_handle,
- (uintptr_t) &io_drv_spec_emmcdrv, &open_emmcdrv,}
+ { &memdrv_dev_handle, (uintptr_t) &io_drv_spec_memdrv, &open_memmap, },
+ /* EMMC_DEV_ID */
+ { &emmcdrv_dev_handle, (uintptr_t) &io_drv_spec_emmcdrv, &open_emmcdrv, }
};
static int32_t open_rcar(const uintptr_t spec)
diff --git a/plat/renesas/rcar/plat_topology.c b/plat/renesas/common/plat_topology.c
index 0d5880d7a..0d5880d7a 100644
--- a/plat/renesas/rcar/plat_topology.c
+++ b/plat/renesas/common/plat_topology.c
diff --git a/plat/renesas/rcar/rcar_common.c b/plat/renesas/common/rcar_common.c
index 4ea753f2d..dec7229b3 100644
--- a/plat/renesas/rcar/rcar_common.c
+++ b/plat/renesas/common/rcar_common.c
@@ -70,8 +70,8 @@ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
#include <drivers/renesas/rcar/console/console.h>
-static console_rcar_t rcar_boot_console;
-static console_rcar_t rcar_runtime_console;
+static console_t rcar_boot_console;
+static console_t rcar_runtime_console;
void rcar_console_boot_init(void)
{
@@ -81,7 +81,7 @@ void rcar_console_boot_init(void)
if (!ret)
panic();
- console_set_scope(&rcar_boot_console.console, CONSOLE_FLAG_BOOT);
+ console_set_scope(&rcar_boot_console, CONSOLE_FLAG_BOOT);
}
void rcar_console_boot_end(void)
@@ -96,7 +96,7 @@ void rcar_console_runtime_init(void)
if (!ret)
panic();
- console_set_scope(&rcar_boot_console.console, CONSOLE_FLAG_RUNTIME);
+ console_set_scope(&rcar_boot_console, CONSOLE_FLAG_RUNTIME);
}
void rcar_console_runtime_end(void)
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index 578892eb3..add2a4f9b 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -16,6 +16,8 @@
#include <common/debug.h>
#include <common/desc_image_load.h>
#include <drivers/console.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_storage.h>
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
#include <plat/common/platform.h>
@@ -33,6 +35,7 @@
#endif
#include "io_common.h"
+#include "io_rcar.h"
#include "qos_init.h"
#include "rcar_def.h"
#include "rcar_private.h"
@@ -131,6 +134,7 @@ static void unsigned_num_print(unsigned long long int unum, unsigned int radix,
while (--i >= 0)
*string++ = num_buf[i];
+ *string = 0;
}
#if (RCAR_LOSSY_ENABLE == 1)
@@ -382,10 +386,28 @@ cold_boot:
return 0;
}
+static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest)
+{
+ uint32_t cert, len;
+ int ret;
+
+ ret = rcar_get_certificate(certid, &cert);
+ if (ret) {
+ ERROR("%s : cert file load error", __func__);
+ return 1;
+ }
+
+ rcar_read_certificate((uint64_t) cert, &len, dest);
+
+ return 0;
+}
+
int bl2_plat_handle_post_image_load(unsigned int image_id)
{
static bl2_to_bl31_params_mem_t *params;
bl_mem_params_node_t *bl_mem_params;
+ uintptr_t dest;
+ int ret;
if (!params) {
params = (bl2_to_bl31_params_mem_t *) PARAMS_BASE;
@@ -396,8 +418,17 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
switch (image_id) {
case BL31_IMAGE_ID:
+ ret = rcar_get_dest_addr_from_cert(SOC_FW_CONTENT_CERT_ID,
+ &dest);
+ if (!ret)
+ bl_mem_params->image_info.image_base = dest;
break;
case BL32_IMAGE_ID:
+ ret = rcar_get_dest_addr_from_cert(TRUSTED_OS_FW_CONTENT_CERT_ID,
+ &dest);
+ if (!ret)
+ bl_mem_params->image_info.image_base = dest;
+
memcpy(&params->bl32_ep_info, &bl_mem_params->ep_info,
sizeof(entry_point_info_t));
break;
diff --git a/plat/renesas/rcar/bl2_secure_setting.c b/plat/renesas/rcar/bl2_secure_setting.c
deleted file mode 100644
index 7473df5a2..000000000
--- a/plat/renesas/rcar/bl2_secure_setting.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <lib/mmio.h>
-#include <lib/utils_def.h>
-
-#include "axi_registers.h"
-#include "lifec_registers.h"
-#include "micro_delay.h"
-
-static void lifec_security_setting(void);
-static void axi_security_setting(void);
-
-static const struct {
- uint32_t reg;
- uint32_t val;
-} lifec[] = {
- /** LIFEC0 (SECURITY) settings */
- /* Security attribute setting for master ports */
- /* Bit 0: ARM realtime core (Cortex-R7) master port */
- /* 0: Non-Secure */
- {
- SEC_SRC, 0x0000001EU},
- /** Security attribute setting for slave ports 0 to 15 */
- /* {SEC_SEL0, 0xFFFFFFFFU}, */
- /* {SEC_SEL1, 0xFFFFFFFFU}, */
- /* {SEC_SEL2, 0xFFFFFFFFU}, */
- /* Bit19: AXI-Bus (Main Memory domain AXI) slave ports */
- /* 0: registers accessed from secure resource only */
- /* Bit 9: DBSC4 register access slave ports. */
- /* 0: registers accessed from secure resource only. */
-#if (LIFEC_DBSC_PROTECT_ENABLE == 1)
- {
- SEC_SEL3, 0xFFF7FDFFU},
-#else
- {
- SEC_SEL3, 0xFFFFFFFFU},
-#endif
- /* {SEC_SEL4, 0xFFFFFFFFU}, */
- /* Bit 6: Boot ROM slave ports. */
- /* 0: registers accessed from secure resource only */
- {
- SEC_SEL5, 0xFFFFFFBFU},
- /* Bit13: SCEG PKA (secure APB) slave ports */
- /* 0: registers accessed from secure resource only */
- /* 1: Reserved[R-Car E3] */
- /* Bit12: SCEG PKA (public APB) slave ports */
- /* 0: registers accessed from secure resource only */
- /* 1: Reserved[R-Car E3] */
- /* Bit10: SCEG Secure Core slave ports */
- /* 0: registers accessed from secure resource only */
-#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3)
- {
- SEC_SEL6, 0xFFFFFBFFU},
-#else
- {
- SEC_SEL6, 0xFFFFCBFFU},
-#endif
- /* {SEC_SEL7, 0xFFFFFFFFU}, */
- /* {SEC_SEL8, 0xFFFFFFFFU}, */
- /* {SEC_SEL9, 0xFFFFFFFFU}, */
- /* {SEC_SEL10, 0xFFFFFFFFU}, */
- /* {SEC_SEL11, 0xFFFFFFFFU}, */
- /* {SEC_SEL12, 0xFFFFFFFFU}, */
- /* Bit22: RPC slave ports. */
- /* 0: registers accessed from secure resource only. */
-#if (RCAR_RPC_HYPERFLASH_LOCKED == 1)
- {SEC_SEL13, 0xFFBFFFFFU},
-#endif
- /* Bit27: System Timer (SCMT) slave ports */
- /* 0: registers accessed from secure resource only */
- /* Bit26: System Watchdog Timer (SWDT) slave ports */
- /* 0: registers accessed from secure resource only */
- {
- SEC_SEL14, 0xF3FFFFFFU},
- /* Bit13: RST slave ports. */
- /* 0: registers accessed from secure resource only */
- /* Bit 7: Life Cycle 0 slave ports */
- /* 0: registers accessed from secure resource only */
- {
- SEC_SEL15, 0xFFFFFF3FU},
- /** Security group 0 attribute setting for master ports 0 */
- /** Security group 1 attribute setting for master ports 0 */
- /* {SEC_GRP0CR0, 0x00000000U}, */
- /* {SEC_GRP1CR0, 0x00000000U}, */
- /** Security group 0 attribute setting for master ports 1 */
- /** Security group 1 attribute setting for master ports 1 */
- /* {SEC_GRP0CR1, 0x00000000U}, */
- /* {SEC_GRP1CR1, 0x00000000U}, */
- /** Security group 0 attribute setting for master ports 2 */
- /** Security group 1 attribute setting for master ports 2 */
- /* Bit17: SCEG Secure Core master ports. */
- /* SecurityGroup3 */
- {
- SEC_GRP0CR2, 0x00020000U}, {
- SEC_GRP1CR2, 0x00020000U},
- /** Security group 0 attribute setting for master ports 3 */
- /** Security group 1 attribute setting for master ports 3 */
- /* {SEC_GRP0CR3, 0x00000000U}, */
- /* {SEC_GRP1CR3, 0x00000000U}, */
- /** Security group 0 attribute setting for slave ports 0 */
- /** Security group 1 attribute setting for slave ports 0 */
- /* {SEC_GRP0COND0, 0x00000000U}, */
- /* {SEC_GRP1COND0, 0x00000000U}, */
- /** Security group 0 attribute setting for slave ports 1 */
- /** Security group 1 attribute setting for slave ports 1 */
- /* {SEC_GRP0COND1, 0x00000000U}, */
- /* {SEC_GRP1COND1, 0x00000000U}, */
- /** Security group 0 attribute setting for slave ports 2 */
- /** Security group 1 attribute setting for slave ports 2 */
- /* {SEC_GRP0COND2, 0x00000000U}, */
- /* {SEC_GRP1COND2, 0x00000000U}, */
- /** Security group 0 attribute setting for slave ports 3 */
- /** Security group 1 attribute setting for slave ports 3 */
- /* Bit19: AXI-Bus (Main Memory domain AXI) slave ports. */
- /* SecurityGroup3 */
- /* Bit 9: DBSC4 register access slave ports. */
- /* SecurityGroup3 */
-#if (LIFEC_DBSC_PROTECT_ENABLE == 1)
- {
- SEC_GRP0COND3, 0x00080200U}, {
- SEC_GRP1COND3, 0x00080200U},
-#else
- {
- SEC_GRP0COND3, 0x00000000U}, {
- SEC_GRP1COND3, 0x00000000U},
-#endif
- /** Security group 0 attribute setting for slave ports 4 */
- /** Security group 1 attribute setting for slave ports 4 */
- /* {SEC_GRP0COND4, 0x00000000U}, */
- /* {SEC_GRP1COND4, 0x00000000U}, */
- /** Security group 0 attribute setting for slave ports 5 */
- /** Security group 1 attribute setting for slave ports 5 */
- /* Bit 6: Boot ROM slave ports */
- /* SecurityGroup3 */
- {
- SEC_GRP0COND5, 0x00000040U}, {
- SEC_GRP1COND5, 0x00000040U},
- /** Security group 0 attribute setting for slave ports 6 */
- /** Security group 1 attribute setting for slave ports 6 */
- /* Bit13: SCEG PKA (secure APB) slave ports */
- /* SecurityGroup3 */
- /* Reserved[R-Car E3] */
- /* Bit12: SCEG PKA (public APB) slave ports */
- /* SecurityGroup3 */
- /* Reserved[R-Car E3] */
- /* Bit10: SCEG Secure Core slave ports */
- /* SecurityGroup3 */
-#if RCAR_LSI == RCAR_E3
- {
- SEC_GRP0COND6, 0x00000400U}, {
- SEC_GRP1COND6, 0x00000400U},
-#else
- {
- SEC_GRP0COND6, 0x00003400U}, {
- SEC_GRP1COND6, 0x00003400U},
-#endif
- /** Security group 0 attribute setting for slave ports 7 */
- /** Security group 1 attribute setting for slave ports 7 */
- /* {SEC_GRP0COND7, 0x00000000U}, */
- /* {SEC_GRP1COND7, 0x00000000U}, */
- /** Security group 0 attribute setting for slave ports 8 */
- /** Security group 1 attribute setting for slave ports 8 */
- /* {SEC_GRP0COND8, 0x00000000U}, */
- /* {SEC_GRP1COND8, 0x00000000U}, */
- /** Security group 0 attribute setting for slave ports 9 */
- /** Security group 1 attribute setting for slave ports 9 */
- /* {SEC_GRP0COND9, 0x00000000U}, */
- /* {SEC_GRP1COND9, 0x00000000U}, */
- /** Security group 0 attribute setting for slave ports 10 */
- /** Security group 1 attribute setting for slave ports 10 */
- /* {SEC_GRP0COND10, 0x00000000U}, */
- /* {SEC_GRP1COND10, 0x00000000U}, */
- /** Security group 0 attribute setting for slave ports 11 */
- /** Security group 1 attribute setting for slave ports 11 */
- /* {SEC_GRP0COND11, 0x00000000U}, */
- /* {SEC_GRP1COND11, 0x00000000U}, */
- /** Security group 0 attribute setting for slave ports 12 */
- /** Security group 1 attribute setting for slave ports 12 */
- /* {SEC_GRP0COND12, 0x00000000U}, */
- /* {SEC_GRP1COND12, 0x00000000U}, */
- /** Security group 0 attribute setting for slave ports 13 */
- /** Security group 1 attribute setting for slave ports 13 */
- /* Bit22: RPC slave ports. */
- /* SecurityGroup3 */
-#if (RCAR_RPC_HYPERFLASH_LOCKED == 1)
- {SEC_GRP0COND13, 0x00400000U},
- {SEC_GRP1COND13, 0x00400000U},
-#endif
- /** Security group 0 attribute setting for slave ports 14 */
- /** Security group 1 attribute setting for slave ports 14 */
- /* Bit26: System Timer (SCMT) slave ports */
- /* SecurityGroup3 */
- /* Bit27: System Watchdog Timer (SWDT) slave ports */
- /* SecurityGroup3 */
- {
- SEC_GRP0COND14, 0x0C000000U}, {
- SEC_GRP1COND14, 0x0C000000U},
- /** Security group 0 attribute setting for slave ports 15 */
- /** Security group 1 attribute setting for slave ports 15 */
- /* Bit13: RST slave ports */
- /* SecurityGroup3 */
- /* Bit 7: Life Cycle 0 slave ports */
- /* SecurityGroup3 */
- /* Bit 6: TDBG slave ports */
- /* SecurityGroup3 */
- {
- SEC_GRP0COND15, 0x000000C0U}, {
- SEC_GRP1COND15, 0x000000C0U},
- /** Security write protection attribute setting slave ports 0 */
- /* {SEC_READONLY0, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 1 */
- /* {SEC_READONLY1, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 2 */
- /* {SEC_READONLY2, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 3 */
- /* {SEC_READONLY3, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 4 */
- /* {SEC_READONLY4, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 5 */
- /* {SEC_READONLY5, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 6 */
- /* {SEC_READONLY6, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 7 */
- /* {SEC_READONLY7, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 8 */
- /* {SEC_READONLY8, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 9 */
- /* {SEC_READONLY9, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 10 */
- /* {SEC_READONLY10, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 11 */
- /* {SEC_READONLY11, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 12 */
- /* {SEC_READONLY12, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 13 */
- /* {SEC_READONLY13, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 14 */
- /* {SEC_READONLY14, 0x00000000U}, */
- /** Security write protection attribute setting slave ports 15 */
- /* {SEC_READONLY15, 0x00000000U} */
-};
-
-/* AXI settings */
-static const struct {
- uint32_t reg;
- uint32_t val;
-} axi[] = {
- /* DRAM protection */
- /* AXI dram protected area division */
- {
- AXI_DPTDIVCR0, 0x0E0403F0U}, {
- AXI_DPTDIVCR1, 0x0E0407E0U}, {
- AXI_DPTDIVCR2, 0x0E080000U}, {
- AXI_DPTDIVCR3, 0x0E080000U}, {
- AXI_DPTDIVCR4, 0x0E080000U}, {
- AXI_DPTDIVCR5, 0x0E080000U}, {
- AXI_DPTDIVCR6, 0x0E080000U}, {
- AXI_DPTDIVCR7, 0x0E080000U}, {
- AXI_DPTDIVCR8, 0x0E080000U}, {
- AXI_DPTDIVCR9, 0x0E080000U}, {
- AXI_DPTDIVCR10, 0x0E080000U}, {
- AXI_DPTDIVCR11, 0x0E080000U}, {
- AXI_DPTDIVCR12, 0x0E080000U}, {
- AXI_DPTDIVCR13, 0x0E080000U}, {
- AXI_DPTDIVCR14, 0x0E080000U},
- /* AXI dram protected area setting */
- {
- AXI_DPTCR0, 0x0E000000U}, {
- AXI_DPTCR1, 0x0E000E0EU}, {
- AXI_DPTCR2, 0x0E000000U}, {
- AXI_DPTCR3, 0x0E000000U}, {
- AXI_DPTCR4, 0x0E000000U}, {
- AXI_DPTCR5, 0x0E000000U}, {
- AXI_DPTCR6, 0x0E000000U}, {
- AXI_DPTCR7, 0x0E000000U}, {
- AXI_DPTCR8, 0x0E000000U}, {
- AXI_DPTCR9, 0x0E000000U}, {
- AXI_DPTCR10, 0x0E000000U}, {
- AXI_DPTCR11, 0x0E000000U}, {
- AXI_DPTCR12, 0x0E000000U}, {
- AXI_DPTCR13, 0x0E000000U}, {
- AXI_DPTCR14, 0x0E000000U}, {
- AXI_DPTCR15, 0x0E000000U},
- /* SRAM ptotection */
- /* AXI sram protected area division */
- {
- AXI_SPTDIVCR0, 0x0E0E6304U}, {
- AXI_SPTDIVCR1, 0x0E0E6360U}, {
- AXI_SPTDIVCR2, 0x0E0E6360U}, {
- AXI_SPTDIVCR3, 0x0E0E6360U}, {
- AXI_SPTDIVCR4, 0x0E0E6360U}, {
- AXI_SPTDIVCR5, 0x0E0E6360U}, {
- AXI_SPTDIVCR6, 0x0E0E6360U}, {
- AXI_SPTDIVCR7, 0x0E0E6360U}, {
- AXI_SPTDIVCR8, 0x0E0E6360U}, {
- AXI_SPTDIVCR9, 0x0E0E6360U}, {
- AXI_SPTDIVCR10, 0x0E0E6360U}, {
- AXI_SPTDIVCR11, 0x0E0E6360U}, {
- AXI_SPTDIVCR12, 0x0E0E6360U}, {
- AXI_SPTDIVCR13, 0x0E0E6360U}, {
- AXI_SPTDIVCR14, 0x0E0E6360U},
- /* AXI sram protected area setting */
- {
- AXI_SPTCR0, 0x0E000E0EU}, {
- AXI_SPTCR1, 0x0E000000U}, {
- AXI_SPTCR2, 0x0E000000U}, {
- AXI_SPTCR3, 0x0E000000U}, {
- AXI_SPTCR4, 0x0E000000U}, {
- AXI_SPTCR5, 0x0E000000U}, {
- AXI_SPTCR6, 0x0E000000U}, {
- AXI_SPTCR7, 0x0E000000U}, {
- AXI_SPTCR8, 0x0E000000U}, {
- AXI_SPTCR9, 0x0E000000U}, {
- AXI_SPTCR10, 0x0E000000U}, {
- AXI_SPTCR11, 0x0E000000U}, {
- AXI_SPTCR12, 0x0E000000U}, {
- AXI_SPTCR13, 0x0E000000U}, {
- AXI_SPTCR14, 0x0E000000U}, {
- AXI_SPTCR15, 0x0E000000U}
-};
-
-static void lifec_security_setting(void)
-{
- uint32_t i;
-
- for (i = 0; i < ARRAY_SIZE(lifec); i++)
- mmio_write_32(lifec[i].reg, lifec[i].val);
-}
-
-/* SRAM/DRAM protection setting */
-static void axi_security_setting(void)
-{
- uint32_t i;
-
- for (i = 0; i < ARRAY_SIZE(axi); i++)
- mmio_write_32(axi[i].reg, axi[i].val);
-}
-
-void bl2_secure_setting(void)
-{
- const uint32_t delay = 10;
-
- lifec_security_setting();
- axi_security_setting();
- rcar_micro_delay(delay);
-
- return;
-}
diff --git a/plat/renesas/rcar/include/registers/lifec_registers.h b/plat/renesas/rcar/include/registers/lifec_registers.h
deleted file mode 100644
index de78760ae..000000000
--- a/plat/renesas/rcar/include/registers/lifec_registers.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef LIFEC_REGISTERS_H
-#define LIFEC_REGISTERS_H
-
-#define LIFEC_SEC_BASE (0xE6110000U)
-
-#define SEC_SRC (LIFEC_SEC_BASE + 0x0008U)
-#define SEC_SEL0 (LIFEC_SEC_BASE + 0x0030U)
-#define SEC_SEL1 (LIFEC_SEC_BASE + 0x0034U)
-#define SEC_SEL2 (LIFEC_SEC_BASE + 0x0038U)
-#define SEC_SEL3 (LIFEC_SEC_BASE + 0x003CU)
-#define SEC_SEL4 (LIFEC_SEC_BASE + 0x0058U)
-#define SEC_SEL5 (LIFEC_SEC_BASE + 0x005CU)
-#define SEC_SEL6 (LIFEC_SEC_BASE + 0x0060U)
-#define SEC_SEL7 (LIFEC_SEC_BASE + 0x0064U)
-#define SEC_SEL8 (LIFEC_SEC_BASE + 0x0068U)
-#define SEC_SEL9 (LIFEC_SEC_BASE + 0x006CU)
-#define SEC_SEL10 (LIFEC_SEC_BASE + 0x0070U)
-#define SEC_SEL11 (LIFEC_SEC_BASE + 0x0074U)
-#define SEC_SEL12 (LIFEC_SEC_BASE + 0x0078U)
-#define SEC_SEL13 (LIFEC_SEC_BASE + 0x007CU)
-#define SEC_SEL14 (LIFEC_SEC_BASE + 0x0080U)
-#define SEC_SEL15 (LIFEC_SEC_BASE + 0x0084U)
-#define SEC_GRP0CR0 (LIFEC_SEC_BASE + 0x0138U)
-#define SEC_GRP1CR0 (LIFEC_SEC_BASE + 0x013CU)
-#define SEC_GRP0CR1 (LIFEC_SEC_BASE + 0x0140U)
-#define SEC_GRP1CR1 (LIFEC_SEC_BASE + 0x0144U)
-#define SEC_GRP0CR2 (LIFEC_SEC_BASE + 0x0148U)
-#define SEC_GRP1CR2 (LIFEC_SEC_BASE + 0x014CU)
-#define SEC_GRP0CR3 (LIFEC_SEC_BASE + 0x0150U)
-#define SEC_GRP1CR3 (LIFEC_SEC_BASE + 0x0154U)
-#define SEC_GRP0COND0 (LIFEC_SEC_BASE + 0x0158U)
-#define SEC_GRP1COND0 (LIFEC_SEC_BASE + 0x015CU)
-#define SEC_GRP0COND1 (LIFEC_SEC_BASE + 0x0160U)
-#define SEC_GRP1COND1 (LIFEC_SEC_BASE + 0x0164U)
-#define SEC_GRP0COND2 (LIFEC_SEC_BASE + 0x0168U)
-#define SEC_GRP1COND2 (LIFEC_SEC_BASE + 0x016CU)
-#define SEC_GRP0COND3 (LIFEC_SEC_BASE + 0x0170U)
-#define SEC_GRP1COND3 (LIFEC_SEC_BASE + 0x0174U)
-#define SEC_GRP0COND4 (LIFEC_SEC_BASE + 0x0178U)
-#define SEC_GRP1COND4 (LIFEC_SEC_BASE + 0x017CU)
-#define SEC_GRP0COND5 (LIFEC_SEC_BASE + 0x0180U)
-#define SEC_GRP1COND5 (LIFEC_SEC_BASE + 0x0184U)
-#define SEC_GRP0COND6 (LIFEC_SEC_BASE + 0x0188U)
-#define SEC_GRP1COND6 (LIFEC_SEC_BASE + 0x018CU)
-#define SEC_GRP0COND7 (LIFEC_SEC_BASE + 0x0190U)
-#define SEC_GRP1COND7 (LIFEC_SEC_BASE + 0x0194U)
-#define SEC_GRP0COND8 (LIFEC_SEC_BASE + 0x0198U)
-#define SEC_GRP1COND8 (LIFEC_SEC_BASE + 0x019CU)
-#define SEC_GRP0COND9 (LIFEC_SEC_BASE + 0x01A0U)
-#define SEC_GRP1COND9 (LIFEC_SEC_BASE + 0x01A4U)
-#define SEC_GRP0COND10 (LIFEC_SEC_BASE + 0x01A8U)
-#define SEC_GRP1COND10 (LIFEC_SEC_BASE + 0x01ACU)
-#define SEC_GRP0COND11 (LIFEC_SEC_BASE + 0x01B0U)
-#define SEC_GRP1COND11 (LIFEC_SEC_BASE + 0x01B4U)
-#define SEC_GRP0COND12 (LIFEC_SEC_BASE + 0x01B8U)
-#define SEC_GRP1COND12 (LIFEC_SEC_BASE + 0x01BCU)
-#define SEC_GRP0COND13 (LIFEC_SEC_BASE + 0x01C0U)
-#define SEC_GRP1COND13 (LIFEC_SEC_BASE + 0x01C4U)
-#define SEC_GRP0COND14 (LIFEC_SEC_BASE + 0x01C8U)
-#define SEC_GRP1COND14 (LIFEC_SEC_BASE + 0x01CCU)
-#define SEC_GRP0COND15 (LIFEC_SEC_BASE + 0x01D0U)
-#define SEC_GRP1COND15 (LIFEC_SEC_BASE + 0x01D4U)
-#define SEC_READONLY0 (LIFEC_SEC_BASE + 0x01D8U)
-#define SEC_READONLY1 (LIFEC_SEC_BASE + 0x01DCU)
-#define SEC_READONLY2 (LIFEC_SEC_BASE + 0x01E0U)
-#define SEC_READONLY3 (LIFEC_SEC_BASE + 0x01E4U)
-#define SEC_READONLY4 (LIFEC_SEC_BASE + 0x01E8U)
-#define SEC_READONLY5 (LIFEC_SEC_BASE + 0x01ECU)
-#define SEC_READONLY6 (LIFEC_SEC_BASE + 0x01F0U)
-#define SEC_READONLY7 (LIFEC_SEC_BASE + 0x01F4U)
-#define SEC_READONLY8 (LIFEC_SEC_BASE + 0x01F8U)
-#define SEC_READONLY9 (LIFEC_SEC_BASE + 0x01FCU)
-#define SEC_READONLY10 (LIFEC_SEC_BASE + 0x0200U)
-#define SEC_READONLY11 (LIFEC_SEC_BASE + 0x0204U)
-#define SEC_READONLY12 (LIFEC_SEC_BASE + 0x0208U)
-#define SEC_READONLY13 (LIFEC_SEC_BASE + 0x020CU)
-#define SEC_READONLY14 (LIFEC_SEC_BASE + 0x0210U)
-#define SEC_READONLY15 (LIFEC_SEC_BASE + 0x0214U)
-
-#define LIFEC_SAFE_BASE (0xE6120000U)
-#define SAFE_GRP0CR0 (LIFEC_SAFE_BASE + 0x0138U)
-#define SAFE_GRP1CR0 (LIFEC_SAFE_BASE + 0x013CU)
-#define SAFE_GRP0CR1 (LIFEC_SAFE_BASE + 0x0140U)
-#define SAFE_GRP1CR1 (LIFEC_SAFE_BASE + 0x0144U)
-#define SAFE_GRP0CR2 (LIFEC_SAFE_BASE + 0x0148U)
-#define SAFE_GRP1CR2 (LIFEC_SAFE_BASE + 0x014CU)
-#define SAFE_GRP0CR3 (LIFEC_SAFE_BASE + 0x0150U)
-#define SAFE_GRP1CR3 (LIFEC_SAFE_BASE + 0x0154U)
-#define SAFE_GRP0COND0 (LIFEC_SAFE_BASE + 0x0158U)
-#define SAFE_GRP1COND0 (LIFEC_SAFE_BASE + 0x015CU)
-#define SAFE_GRP0COND1 (LIFEC_SAFE_BASE + 0x0160U)
-#define SAFE_GRP1COND1 (LIFEC_SAFE_BASE + 0x0164U)
-#define SAFE_GRP0COND2 (LIFEC_SAFE_BASE + 0x0168U)
-#define SAFE_GRP1COND2 (LIFEC_SAFE_BASE + 0x016CU)
-#define SAFE_GRP0COND3 (LIFEC_SAFE_BASE + 0x0170U)
-#define SAFE_GRP1COND3 (LIFEC_SAFE_BASE + 0x0174U)
-#define SAFE_GRP0COND4 (LIFEC_SAFE_BASE + 0x0178U)
-#define SAFE_GRP1COND4 (LIFEC_SAFE_BASE + 0x017CU)
-#define SAFE_GRP0COND5 (LIFEC_SAFE_BASE + 0x0180U)
-#define SAFE_GRP1COND5 (LIFEC_SAFE_BASE + 0x0184U)
-#define SAFE_GRP0COND6 (LIFEC_SAFE_BASE + 0x0188U)
-#define SAFE_GRP1COND6 (LIFEC_SAFE_BASE + 0x018CU)
-#define SAFE_GRP0COND7 (LIFEC_SAFE_BASE + 0x0190U)
-#define SAFE_GRP1COND7 (LIFEC_SAFE_BASE + 0x0194U)
-#define SAFE_GRP0COND8 (LIFEC_SAFE_BASE + 0x0198U)
-#define SAFE_GRP1COND8 (LIFEC_SAFE_BASE + 0x019CU)
-#define SAFE_GRP0COND9 (LIFEC_SAFE_BASE + 0x01A0U)
-#define SAFE_GRP1COND9 (LIFEC_SAFE_BASE + 0x01A4U)
-#define SAFE_GRP0COND10 (LIFEC_SAFE_BASE + 0x01A8U)
-#define SAFE_GRP1COND10 (LIFEC_SAFE_BASE + 0x01ACU)
-#define SAFE_GRP0COND11 (LIFEC_SAFE_BASE + 0x01B0U)
-#define SAFE_GRP1COND11 (LIFEC_SAFE_BASE + 0x01B4U)
-#define SAFE_GRP0COND12 (LIFEC_SAFE_BASE + 0x01B8U)
-#define SAFE_GRP1COND12 (LIFEC_SAFE_BASE + 0x01BCU)
-#define SAFE_GRP0COND13 (LIFEC_SAFE_BASE + 0x01C0U)
-#define SAFE_GRP1COND13 (LIFEC_SAFE_BASE + 0x01C4U)
-#define SAFE_GRP0COND14 (LIFEC_SAFE_BASE + 0x01C8U)
-#define SAFE_GRP1COND14 (LIFEC_SAFE_BASE + 0x01CCU)
-#define SAFE_GRP0COND15 (LIFEC_SAFE_BASE + 0x01D0U)
-#define SAFE_GRP1COND15 (LIFEC_SAFE_BASE + 0x01D4U)
-#define SAFE_READONLY0 (LIFEC_SAFE_BASE + 0x01D8U)
-#define SAFE_READONLY1 (LIFEC_SAFE_BASE + 0x01DCU)
-#define SAFE_READONLY2 (LIFEC_SAFE_BASE + 0x01E0U)
-#define SAFE_READONLY3 (LIFEC_SAFE_BASE + 0x01E4U)
-#define SAFE_READONLY4 (LIFEC_SAFE_BASE + 0x01E8U)
-#define SAFE_READONLY5 (LIFEC_SAFE_BASE + 0x01ECU)
-#define SAFE_READONLY6 (LIFEC_SAFE_BASE + 0x01F0U)
-#define SAFE_READONLY7 (LIFEC_SAFE_BASE + 0x01F4U)
-#define SAFE_READONLY8 (LIFEC_SAFE_BASE + 0x01F8U)
-#define SAFE_READONLY9 (LIFEC_SAFE_BASE + 0x01FCU)
-#define SAFE_READONLY10 (LIFEC_SAFE_BASE + 0x0200U)
-#define SAFE_READONLY11 (LIFEC_SAFE_BASE + 0x0204U)
-#define SAFE_READONLY12 (LIFEC_SAFE_BASE + 0x0208U)
-#define SAFE_READONLY13 (LIFEC_SAFE_BASE + 0x020CU)
-#define SAFE_READONLY14 (LIFEC_SAFE_BASE + 0x0210U)
-#define SAFE_READONLY15 (LIFEC_SAFE_BASE + 0x0214U)
-
-#endif /* LIFEC_REGISTERS_H */
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index 4c41dd341..5e4978c0a 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -1,56 +1,10 @@
#
-# Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved.
+# Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
-PROGRAMMABLE_RESET_ADDRESS := 0
-COLD_BOOT_SINGLE_CPU := 1
-ARM_CCI_PRODUCT_ID := 500
-TRUSTED_BOARD_BOOT := 1
-RESET_TO_BL31 := 1
-GENERATE_COT := 1
-BL2_AT_EL3 := 1
-ENABLE_SVE_FOR_NS := 0
-MULTI_CONSOLE_API := 1
-
-CRASH_REPORTING := 1
-HANDLE_EA_EL3_FIRST := 1
-
-$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
-
-ifeq (${SPD},none)
- SPD_NONE:=1
- $(eval $(call add_define,SPD_NONE))
-endif
-
-# LSI setting common define
-RCAR_H3:=0
-RCAR_M3:=1
-RCAR_M3N:=2
-RCAR_E3:=3
-RCAR_H3N:=4
-RCAR_D3:=5
-RCAR_V3M:=6
-RCAR_AUTO:=99
-$(eval $(call add_define,RCAR_H3))
-$(eval $(call add_define,RCAR_M3))
-$(eval $(call add_define,RCAR_M3N))
-$(eval $(call add_define,RCAR_E3))
-$(eval $(call add_define,RCAR_H3N))
-$(eval $(call add_define,RCAR_D3))
-$(eval $(call add_define,RCAR_V3M))
-$(eval $(call add_define,RCAR_AUTO))
-RCAR_CUT_10:=0
-RCAR_CUT_11:=1
-RCAR_CUT_13:=3
-RCAR_CUT_20:=10
-RCAR_CUT_30:=20
-$(eval $(call add_define,RCAR_CUT_10))
-$(eval $(call add_define,RCAR_CUT_11))
-$(eval $(call add_define,RCAR_CUT_13))
-$(eval $(call add_define,RCAR_CUT_20))
-$(eval $(call add_define,RCAR_CUT_30))
+include plat/renesas/common/common.mk
ifndef LSI
$(error "Error: Unknown LSI. Please use LSI=<LSI name> to specify the LSI")
@@ -339,105 +293,32 @@ ifeq (${RCAR_SYSTEM_RESET_KEEPON_DDR},1)
endif
endif
-# Enable workarounds for selected Cortex-A53 erratas.
-ERRATA_A53_835769 := 1
-ERRATA_A53_843419 := 1
-ERRATA_A53_855873 := 1
-
-# Enable workarounds for selected Cortex-A57 erratas.
-ERRATA_A57_859972 := 1
-ERRATA_A57_813419 := 1
-
include drivers/renesas/rcar/ddr/ddr.mk
include drivers/renesas/rcar/qos/qos.mk
include drivers/renesas/rcar/pfc/pfc.mk
include lib/libfdt/libfdt.mk
-PLAT_INCLUDES := -Idrivers/renesas/rcar/ddr \
+PLAT_INCLUDES += -Idrivers/renesas/rcar/ddr \
-Idrivers/renesas/rcar/qos \
- -Idrivers/renesas/rcar/iic_dvfs \
-Idrivers/renesas/rcar/board \
-Idrivers/renesas/rcar/cpld/ \
- -Idrivers/renesas/rcar/avs \
- -Idrivers/renesas/rcar/delay \
- -Idrivers/renesas/rcar/rom \
- -Idrivers/renesas/rcar/scif \
- -Idrivers/renesas/rcar/emmc \
- -Idrivers/renesas/rcar/pwrc \
- -Idrivers/renesas/rcar/io \
- -Iplat/renesas/rcar/include/registers \
- -Iplat/renesas/rcar/include \
- -Iplat/renesas/rcar
-
-PLAT_BL_COMMON_SOURCES := drivers/renesas/rcar/iic_dvfs/iic_dvfs.c \
- plat/renesas/rcar/rcar_common.c
-
-RCAR_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
- plat/common/plat_gicv2.c
-
-BL2_SOURCES += ${RCAR_GIC_SOURCES} \
- lib/cpus/aarch64/cortex_a53.S \
- lib/cpus/aarch64/cortex_a57.S \
- ${LIBFDT_SRCS} \
- common/desc_image_load.c \
- plat/renesas/rcar/aarch64/platform_common.c \
- plat/renesas/rcar/aarch64/plat_helpers.S \
- plat/renesas/rcar/bl2_interrupt_error.c \
- plat/renesas/rcar/bl2_secure_setting.c \
- plat/renesas/rcar/bl2_plat_setup.c \
- plat/renesas/rcar/plat_storage.c \
- plat/renesas/rcar/bl2_plat_mem_params_desc.c \
- plat/renesas/rcar/plat_image_load.c \
- plat/renesas/rcar/bl2_cpg_init.c \
- drivers/renesas/rcar/console/rcar_printf.c \
- drivers/renesas/rcar/scif/scif.S \
- drivers/renesas/rcar/common.c \
- drivers/renesas/rcar/io/io_emmcdrv.c \
- drivers/renesas/rcar/io/io_memdrv.c \
- drivers/renesas/rcar/io/io_rcar.c \
- drivers/renesas/rcar/auth/auth_mod.c \
- drivers/renesas/rcar/rpc/rpc_driver.c \
- drivers/renesas/rcar/dma/dma_driver.c \
- drivers/renesas/rcar/avs/avs_driver.c \
- drivers/renesas/rcar/delay/micro_delay.c \
- drivers/renesas/rcar/emmc/emmc_interrupt.c \
- drivers/renesas/rcar/emmc/emmc_utility.c \
- drivers/renesas/rcar/emmc/emmc_mount.c \
- drivers/renesas/rcar/emmc/emmc_init.c \
- drivers/renesas/rcar/emmc/emmc_read.c \
- drivers/renesas/rcar/emmc/emmc_cmd.c \
- drivers/renesas/rcar/watchdog/swdt.c \
- drivers/renesas/rcar/rom/rom_api.c \
- drivers/renesas/rcar/board/board.c \
- drivers/io/io_storage.c
-
-BL31_SOURCES += ${RCAR_GIC_SOURCES} \
- lib/cpus/aarch64/cortex_a53.S \
- lib/cpus/aarch64/cortex_a57.S \
- plat/common/plat_psci_common.c \
- plat/renesas/rcar/plat_topology.c \
- plat/renesas/rcar/aarch64/plat_helpers.S \
- plat/renesas/rcar/aarch64/platform_common.c \
- plat/renesas/rcar/bl31_plat_setup.c \
- plat/renesas/rcar/plat_pm.c \
- drivers/renesas/rcar/console/rcar_console.S \
- drivers/renesas/rcar/console/rcar_printf.c \
- drivers/renesas/rcar/delay/micro_delay.c \
- drivers/renesas/rcar/pwrc/call_sram.S \
- drivers/renesas/rcar/pwrc/pwrc.c \
- drivers/renesas/rcar/common.c \
- drivers/arm/cci/cci.c
+ -Idrivers/renesas/common \
+ -Idrivers/renesas/common/iic_dvfs \
+ -Idrivers/renesas/common/avs \
+ -Idrivers/renesas/common/delay \
+ -Idrivers/renesas/common/rom \
+ -Idrivers/renesas/common/scif \
+ -Idrivers/renesas/common/emmc \
+ -Idrivers/renesas/common/pwrc \
+ -Idrivers/renesas/common/io
+
+BL2_SOURCES += plat/renesas/rcar/bl2_plat_setup.c \
+ drivers/renesas/rcar/board/board.c
ifeq (${RCAR_GEN3_ULCB},1)
BL31_SOURCES += drivers/renesas/rcar/cpld/ulcb_cpld.c
endif
-include lib/xlat_tables_v2/xlat_tables.mk
-include drivers/auth/mbedtls/mbedtls_crypto.mk
-PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
-
# build the layout images for the bootrom and the necessary srecords
rcar: rcar_layout_tool rcar_srecord
distclean realclean clean: clean_layout_tool clean_srecord
diff --git a/plat/renesas/rzg/bl2_plat_setup.c b/plat/renesas/rzg/bl2_plat_setup.c
new file mode 100644
index 000000000..13f413b55
--- /dev/null
+++ b/plat/renesas/rzg/bl2_plat_setup.c
@@ -0,0 +1,909 @@
+/*
+ * Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <bl1/bl1.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/console.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_storage.h>
+#include <libfdt.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <platform_def.h>
+#include <plat/common/platform.h>
+
+#include "avs_driver.h"
+#include "board.h"
+#include "boot_init_dram.h"
+#include "cpg_registers.h"
+#include "emmc_def.h"
+#include "emmc_hal.h"
+#include "emmc_std.h"
+#include "io_common.h"
+#include "io_rcar.h"
+#include "qos_init.h"
+#include "rcar_def.h"
+#include "rcar_private.h"
+#include "rcar_version.h"
+#include "rom_api.h"
+
+#define MAX_DRAM_CHANNELS 4
+/*
+ * DDR ch0 has a shadow area mapped in 32bit address space.
+ * Physical address 0x4_0000_0000 - 0x4_7fff_ffff in 64bit space
+ * is mapped to 0x4000_0000 - 0xbfff_ffff in 32bit space.
+ */
+#define MAX_DRAM_SIZE_CH0_32BIT_ADDR_SPACE 0x80000000ULL
+
+#if RCAR_BL2_DCACHE == 1
+/*
+ * Following symbols are only used during plat_arch_setup() only
+ * when RCAR_BL2_DCACHE is enabled.
+ */
+static const uint64_t BL2_RO_BASE = BL_CODE_BASE;
+static const uint64_t BL2_RO_LIMIT = BL_CODE_END;
+
+#if USE_COHERENT_MEM
+static const uint64_t BL2_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE;
+static const uint64_t BL2_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END;
+#endif /* USE_COHERENT_MEM */
+
+#endif /* RCAR_BL2_DCACHE */
+
+extern void plat_rcar_gic_driver_init(void);
+extern void plat_rcar_gic_init(void);
+extern void bl2_enter_bl31(const struct entry_point_info *bl_ep_info);
+extern void bl2_system_cpg_init(void);
+extern void bl2_secure_setting(void);
+extern void bl2_cpg_init(void);
+extern void rcar_io_emmc_setup(void);
+extern void rcar_io_setup(void);
+extern void rcar_swdt_release(void);
+extern void rcar_swdt_init(void);
+extern void rcar_rpc_init(void);
+extern void rcar_dma_init(void);
+extern void rzg_pfc_init(void);
+
+static void bl2_init_generic_timer(void);
+
+/* RZ/G2 product check */
+#if RCAR_LSI == RZ_G2M
+#define TARGET_PRODUCT PRR_PRODUCT_M3
+#define TARGET_NAME "RZ/G2M"
+#elif RCAR_LSI == RCAR_AUTO
+#define TARGET_NAME "RZ/G2M"
+#endif /* RCAR_LSI == RZ_G2M */
+
+#define GPIO_INDT (GPIO_INDT1)
+#define GPIO_BKUP_TRG_SHIFT (1U << 8U)
+
+CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t) + 0x100)
+ < (RCAR_SHARED_MEM_BASE + RCAR_SHARED_MEM_SIZE),
+ assert_bl31_params_do_not_fit_in_shared_memory);
+
+static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
+
+/* FDT with DRAM configuration */
+uint64_t fdt_blob[PAGE_SIZE_4KB / sizeof(uint64_t)];
+static void *fdt = (void *)fdt_blob;
+
+static void unsigned_num_print(uint64_t unum, unsigned int radix, char *string)
+{
+ /* Just need enough space to store 64 bit decimal integer */
+ char num_buf[20];
+ int i = 0;
+ unsigned int rem;
+
+ do {
+ rem = unum % radix;
+ if (rem < 0xaU) {
+ num_buf[i] = '0' + rem;
+ } else {
+ num_buf[i] = 'a' + (rem - 0xaU);
+ }
+ i++;
+ unum /= radix;
+ } while (unum > 0U);
+
+ while (--i >= 0) {
+ *string++ = num_buf[i];
+ }
+ *string = 0;
+}
+
+#if RCAR_LOSSY_ENABLE == 1
+typedef struct bl2_lossy_info {
+ uint32_t magic;
+ uint32_t a0;
+ uint32_t b0;
+} bl2_lossy_info_t;
+
+static void bl2_lossy_gen_fdt(uint32_t no, uint64_t start_addr,
+ uint64_t end_addr, uint32_t format,
+ uint32_t enable, int fcnlnode)
+{
+ const uint64_t fcnlsize = cpu_to_fdt64(end_addr - start_addr);
+ char nodename[40] = { 0 };
+ int ret, node;
+
+ /* Ignore undefined addresses */
+ if (start_addr == 0UL && end_addr == 0UL) {
+ return;
+ }
+
+ snprintf(nodename, sizeof(nodename), "lossy-decompression@");
+ unsigned_num_print(start_addr, 16, nodename + strlen(nodename));
+
+ node = ret = fdt_add_subnode(fdt, fcnlnode, nodename);
+ if (ret < 0) {
+ NOTICE("BL2: Cannot create FCNL node (ret=%i)\n", ret);
+ panic();
+ }
+
+ ret = fdt_setprop_string(fdt, node, "compatible",
+ "renesas,lossy-decompression");
+ if (ret < 0) {
+ NOTICE("BL2: Cannot add FCNL compat string %s (ret=%i)\n",
+ "renesas,lossy-decompression", ret);
+ panic();
+ }
+
+ ret = fdt_appendprop_string(fdt, node, "compatible",
+ "shared-dma-pool");
+ if (ret < 0) {
+ NOTICE("BL2: Cannot append FCNL compat string %s (ret=%i)\n",
+ "shared-dma-pool", ret);
+ panic();
+ }
+
+ ret = fdt_setprop_u64(fdt, node, "reg", start_addr);
+ if (ret < 0) {
+ NOTICE("BL2: Cannot add FCNL reg prop (ret=%i)\n", ret);
+ panic();
+ }
+
+ ret = fdt_appendprop(fdt, node, "reg", &fcnlsize, sizeof(fcnlsize));
+ if (ret < 0) {
+ NOTICE("BL2: Cannot append FCNL reg size prop (ret=%i)\n", ret);
+ panic();
+ }
+
+ ret = fdt_setprop(fdt, node, "no-map", NULL, 0);
+ if (ret < 0) {
+ NOTICE("BL2: Cannot add FCNL no-map prop (ret=%i)\n", ret);
+ panic();
+ }
+
+ ret = fdt_setprop_u32(fdt, node, "renesas,formats", format);
+ if (ret < 0) {
+ NOTICE("BL2: Cannot add FCNL formats prop (ret=%i)\n", ret);
+ panic();
+ }
+}
+
+static void bl2_lossy_setting(uint32_t no, uint64_t start_addr,
+ uint64_t end_addr, uint32_t format,
+ uint32_t enable, int fcnlnode)
+{
+ bl2_lossy_info_t info;
+ uint32_t reg;
+
+ bl2_lossy_gen_fdt(no, start_addr, end_addr, format, enable, fcnlnode);
+
+ reg = format | (start_addr >> 20);
+ mmio_write_32(AXI_DCMPAREACRA0 + 0x8U * no, reg);
+ mmio_write_32(AXI_DCMPAREACRB0 + 0x8U * no, end_addr >> 20);
+ mmio_write_32(AXI_DCMPAREACRA0 + 0x8U * no, reg | enable);
+
+ info.magic = 0x12345678U;
+ info.a0 = mmio_read_32(AXI_DCMPAREACRA0 + 0x8U * no);
+ info.b0 = mmio_read_32(AXI_DCMPAREACRB0 + 0x8U * no);
+
+ mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no, info.magic);
+ mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x4U, info.a0);
+ mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x8U, info.b0);
+
+ NOTICE(" Entry %d: DCMPAREACRAx:0x%x DCMPAREACRBx:0x%x\n", no,
+ mmio_read_32(AXI_DCMPAREACRA0 + 0x8U * no),
+ mmio_read_32(AXI_DCMPAREACRB0 + 0x8U * no));
+}
+#endif /* RCAR_LOSSY_ENABLE == 1 */
+
+void bl2_plat_flush_bl31_params(void)
+{
+ uint32_t product_cut, product, cut;
+ uint32_t boot_dev, boot_cpu;
+ uint32_t reg;
+
+ reg = mmio_read_32(RCAR_MODEMR);
+ boot_dev = reg & MODEMR_BOOT_DEV_MASK;
+
+ if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 ||
+ boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) {
+ emmc_terminate();
+ }
+
+ if ((reg & MODEMR_BOOT_CPU_MASK) != MODEMR_BOOT_CPU_CR7) {
+ bl2_secure_setting();
+ }
+
+ reg = mmio_read_32(RCAR_PRR);
+ product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK);
+ product = reg & PRR_PRODUCT_MASK;
+ cut = reg & PRR_CUT_MASK;
+
+ if (!((product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) ||
+ (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20))) {
+ /* Disable MFIS write protection */
+ mmio_write_32(MFISWPCNTR, MFISWPCNTR_PASSWORD | 1U);
+ }
+
+ reg = mmio_read_32(RCAR_MODEMR);
+ boot_cpu = reg & MODEMR_BOOT_CPU_MASK;
+ if (boot_cpu == MODEMR_BOOT_CPU_CA57 ||
+ boot_cpu == MODEMR_BOOT_CPU_CA53) {
+ if (product_cut == PRR_PRODUCT_H3_CUT20) {
+ mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE);
+ mmio_write_32(IPMMUVI1_IMSCTLR, IMSCTLR_DISCACHE);
+ mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE);
+ mmio_write_32(IPMMUPV1_IMSCTLR, IMSCTLR_DISCACHE);
+ mmio_write_32(IPMMUPV2_IMSCTLR, IMSCTLR_DISCACHE);
+ mmio_write_32(IPMMUPV3_IMSCTLR, IMSCTLR_DISCACHE);
+ } else if (product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) ||
+ product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11)) {
+ mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE);
+ mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE);
+ } else if ((product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) ||
+ (product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_11))) {
+ mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE);
+ mmio_write_32(IPMMUVP0_IMSCTLR, IMSCTLR_DISCACHE);
+ mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE);
+ }
+
+ if (product_cut == (PRR_PRODUCT_H3_CUT20) ||
+ product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) ||
+ product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11) ||
+ product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) {
+ mmio_write_32(IPMMUHC_IMSCTLR, IMSCTLR_DISCACHE);
+ mmio_write_32(IPMMURT_IMSCTLR, IMSCTLR_DISCACHE);
+ mmio_write_32(IPMMUMP_IMSCTLR, IMSCTLR_DISCACHE);
+
+ mmio_write_32(IPMMUDS0_IMSCTLR, IMSCTLR_DISCACHE);
+ mmio_write_32(IPMMUDS1_IMSCTLR, IMSCTLR_DISCACHE);
+ }
+ }
+
+ mmio_write_32(IPMMUMM_IMSCTLR, IPMMUMM_IMSCTLR_ENABLE);
+ mmio_write_32(IPMMUMM_IMAUXCTLR, IPMMUMM_IMAUXCTLR_NMERGE40_BIT);
+
+ rcar_swdt_release();
+ bl2_system_cpg_init();
+
+#if RCAR_BL2_DCACHE == 1
+ /* Disable data cache (clean and invalidate) */
+ disable_mmu_el3();
+#endif /* RCAR_BL2_DCACHE == 1 */
+}
+
+static uint32_t is_ddr_backup_mode(void)
+{
+#if RCAR_SYSTEM_SUSPEND
+ static uint32_t reason = RCAR_COLD_BOOT;
+ static uint32_t once;
+
+ if (once != 0U) {
+ return reason;
+ }
+
+ once = 1;
+ if ((mmio_read_32(GPIO_INDT) & GPIO_BKUP_TRG_SHIFT) == 0U) {
+ return reason;
+ }
+
+ reason = RCAR_WARM_BOOT;
+ return reason;
+#else /* RCAR_SYSTEM_SUSPEND */
+ return RCAR_COLD_BOOT;
+#endif /* RCAR_SYSTEM_SUSPEND */
+}
+
+int bl2_plat_handle_pre_image_load(unsigned int image_id)
+{
+ u_register_t *boot_kind = (void *)BOOT_KIND_BASE;
+ bl_mem_params_node_t *bl_mem_params;
+
+ if (image_id != BL31_IMAGE_ID) {
+ return 0;
+ }
+
+ bl_mem_params = get_bl_mem_params_node(image_id);
+
+ if (is_ddr_backup_mode() != RCAR_COLD_BOOT) {
+ *boot_kind = RCAR_WARM_BOOT;
+ flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind));
+
+ console_flush();
+ bl2_plat_flush_bl31_params();
+
+ /* will not return */
+ bl2_enter_bl31(&bl_mem_params->ep_info);
+ }
+
+ *boot_kind = RCAR_COLD_BOOT;
+ flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind));
+
+ return 0;
+}
+
+static uint64_t rzg_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest)
+{
+ uint32_t cert, len;
+ int err;
+
+ err = rcar_get_certificate(certid, &cert);
+ if (err != 0) {
+ ERROR("%s : cert file load error", __func__);
+ return 1U;
+ }
+
+ rcar_read_certificate((uint64_t)cert, &len, dest);
+
+ return 0U;
+}
+
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ static bl2_to_bl31_params_mem_t *params;
+ bl_mem_params_node_t *bl_mem_params;
+ uintptr_t dest;
+ uint64_t ret;
+
+ if (params == NULL) {
+ params = (bl2_to_bl31_params_mem_t *)PARAMS_BASE;
+ memset((void *)PARAMS_BASE, 0, sizeof(*params));
+ }
+
+ bl_mem_params = get_bl_mem_params_node(image_id);
+
+ switch (image_id) {
+ case BL31_IMAGE_ID:
+ ret = rzg_get_dest_addr_from_cert(SOC_FW_CONTENT_CERT_ID,
+ &dest);
+ if (ret == 0U) {
+ bl_mem_params->image_info.image_base = dest;
+ }
+ break;
+ case BL32_IMAGE_ID:
+ ret = rzg_get_dest_addr_from_cert(TRUSTED_OS_FW_CONTENT_CERT_ID,
+ &dest);
+ if (ret == 0U) {
+ bl_mem_params->image_info.image_base = dest;
+ }
+
+ memcpy(&params->bl32_ep_info, &bl_mem_params->ep_info,
+ sizeof(entry_point_info_t));
+ break;
+ case BL33_IMAGE_ID:
+ memcpy(&params->bl33_ep_info, &bl_mem_params->ep_info,
+ sizeof(entry_point_info_t));
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+struct meminfo *bl2_plat_sec_mem_layout(void)
+{
+ return &bl2_tzram_layout;
+}
+
+static void bl2_populate_compatible_string(void *dt)
+{
+ uint32_t board_type;
+ uint32_t board_rev;
+ uint32_t reg;
+ int ret;
+
+ fdt_setprop_u32(dt, 0, "#address-cells", 2);
+ fdt_setprop_u32(dt, 0, "#size-cells", 2);
+
+ /* Populate compatible string */
+ rzg_get_board_type(&board_type, &board_rev);
+ switch (board_type) {
+ case BOARD_HIHOPE_RZ_G2M:
+ ret = fdt_setprop_string(dt, 0, "compatible",
+ "hoperun,hihope-rzg2m");
+ break;
+ default:
+ NOTICE("BL2: Cannot set compatible string, board unsupported\n");
+ panic();
+ break;
+ }
+
+ if (ret < 0) {
+ NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret);
+ panic();
+ }
+
+ reg = mmio_read_32(RCAR_PRR);
+ switch (reg & PRR_PRODUCT_MASK) {
+ case PRR_PRODUCT_M3:
+ ret = fdt_appendprop_string(dt, 0, "compatible",
+ "renesas,r8a774a1");
+ break;
+ default:
+ NOTICE("BL2: Cannot set compatible string, SoC unsupported\n");
+ panic();
+ break;
+ }
+
+ if (ret < 0) {
+ NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret);
+ panic();
+ }
+}
+
+static int bl2_add_memory_node(uint64_t start, uint64_t size)
+{
+ char nodename[32] = { 0 };
+ uint64_t fdtsize;
+ int ret, node;
+
+ fdtsize = cpu_to_fdt64(size);
+
+ snprintf(nodename, sizeof(nodename), "memory@");
+ unsigned_num_print(start, 16, nodename + strlen(nodename));
+ node = ret = fdt_add_subnode(fdt, 0, nodename);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = fdt_setprop_string(fdt, node, "device_type", "memory");
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = fdt_setprop_u64(fdt, node, "reg", start);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return fdt_appendprop(fdt, node, "reg", &fdtsize, sizeof(fdtsize));
+}
+
+static void bl2_advertise_dram_entries(uint64_t dram_config[8])
+{
+ uint64_t start, size;
+ int ret, chan;
+
+ for (chan = 0; chan < MAX_DRAM_CHANNELS; chan++) {
+ start = dram_config[2 * chan];
+ size = dram_config[2 * chan + 1];
+ if (size == 0U) {
+ continue;
+ }
+
+ NOTICE("BL2: CH%d: %llx - %llx, %lld %siB\n",
+ chan, start, start + size - 1U,
+ (size >> 30) ? : size >> 20,
+ (size >> 30) ? "G" : "M");
+ }
+
+ /*
+ * We add the DT nodes in reverse order here. The fdt_add_subnode()
+ * adds the DT node before the first existing DT node, so we have
+ * to add them in reverse order to get nodes sorted by address in
+ * the resulting DT.
+ */
+ for (chan = MAX_DRAM_CHANNELS - 1; chan >= 0; chan--) {
+ start = dram_config[2 * chan];
+ size = dram_config[2 * chan + 1];
+ if (size == 0U) {
+ continue;
+ }
+
+ /*
+ * Channel 0 is mapped in 32bit space and the first
+ * 128 MiB are reserved
+ */
+ if (chan == 0) {
+ /*
+ * Maximum DDR size in Channel 0 for 32 bit space is 2GB, Add DT node
+ * for remaining region in 64 bit address space
+ */
+ if (size > MAX_DRAM_SIZE_CH0_32BIT_ADDR_SPACE) {
+ start = dram_config[chan] + MAX_DRAM_SIZE_CH0_32BIT_ADDR_SPACE;
+ size -= MAX_DRAM_SIZE_CH0_32BIT_ADDR_SPACE;
+ ret = bl2_add_memory_node(start, size);
+ if (ret < 0) {
+ goto err;
+ }
+ }
+ start = 0x48000000U;
+ size -= 0x8000000U;
+ }
+
+ ret = bl2_add_memory_node(start, size);
+ if (ret < 0) {
+ goto err;
+ }
+ }
+
+ return;
+err:
+ NOTICE("BL2: Cannot add memory node to FDT (ret=%i)\n", ret);
+ panic();
+}
+
+static void bl2_advertise_dram_size(uint32_t product)
+{
+ uint64_t dram_config[8] = {
+ [0] = 0x400000000ULL,
+ [2] = 0x500000000ULL,
+ [4] = 0x600000000ULL,
+ [6] = 0x700000000ULL,
+ };
+
+ switch (product) {
+ case PRR_PRODUCT_M3:
+ /* 4GB(2GBx2 2ch split) */
+ dram_config[1] = 0x80000000ULL;
+ dram_config[5] = 0x80000000ULL;
+ break;
+ default:
+ NOTICE("BL2: Detected invalid DRAM entries\n");
+ break;
+ }
+
+ bl2_advertise_dram_entries(dram_config);
+}
+
+void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2,
+ u_register_t arg3, u_register_t arg4)
+{
+ uint32_t reg, midr, boot_dev, boot_cpu, type, rev;
+ uint32_t product, product_cut, major, minor;
+ int32_t ret;
+ const char *str;
+ const char *unknown = "unknown";
+ const char *cpu_ca57 = "CA57";
+ const char *cpu_ca53 = "CA53";
+ const char *product_g2m = "G2M";
+ const char *boot_hyper80 = "HyperFlash(80MHz)";
+ const char *boot_qspi40 = "QSPI Flash(40MHz)";
+ const char *boot_qspi80 = "QSPI Flash(80MHz)";
+ const char *boot_emmc25x1 = "eMMC(25MHz x1)";
+ const char *boot_emmc50x8 = "eMMC(50MHz x8)";
+ const char *boot_hyper160 = "HyperFlash(160MHz)";
+#if RZG_LCS_STATE_DETECTION_ENABLE
+ uint32_t lcs;
+ const char *lcs_secure = "SE";
+ const char *lcs_cm = "CM";
+ const char *lcs_dm = "DM";
+ const char *lcs_sd = "SD";
+ const char *lcs_fa = "FA";
+#endif /* RZG_LCS_STATE_DETECTION_ENABLE */
+
+#if (RCAR_LOSSY_ENABLE == 1)
+ int fcnlnode;
+#endif /* (RCAR_LOSSY_ENABLE == 1) */
+
+ bl2_init_generic_timer();
+
+ reg = mmio_read_32(RCAR_MODEMR);
+ boot_dev = reg & MODEMR_BOOT_DEV_MASK;
+ boot_cpu = reg & MODEMR_BOOT_CPU_MASK;
+
+ bl2_cpg_init();
+
+ if (boot_cpu == MODEMR_BOOT_CPU_CA57 ||
+ boot_cpu == MODEMR_BOOT_CPU_CA53) {
+ rzg_pfc_init();
+ rcar_console_boot_init();
+ }
+
+ plat_rcar_gic_driver_init();
+ plat_rcar_gic_init();
+ rcar_swdt_init();
+
+ /* FIQ interrupts are taken to EL3 */
+ write_scr_el3(read_scr_el3() | SCR_FIQ_BIT);
+
+ write_daifclr(DAIF_FIQ_BIT);
+
+ reg = read_midr();
+ midr = reg & (MIDR_PN_MASK << MIDR_PN_SHIFT);
+ switch (midr) {
+ case MIDR_CA57:
+ str = cpu_ca57;
+ break;
+ case MIDR_CA53:
+ str = cpu_ca53;
+ break;
+ default:
+ str = unknown;
+ break;
+ }
+
+ NOTICE("BL2: RZ/G2 Initial Program Loader(%s) Rev.%s\n", str,
+ version_of_renesas);
+
+ reg = mmio_read_32(RCAR_PRR);
+ product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK);
+ product = reg & PRR_PRODUCT_MASK;
+
+ switch (product) {
+ case PRR_PRODUCT_M3:
+ str = product_g2m;
+ break;
+ default:
+ str = unknown;
+ break;
+ }
+
+ if ((product == PRR_PRODUCT_M3) &&
+ ((reg & RCAR_MAJOR_MASK) == PRR_PRODUCT_20)) {
+ if ((reg & PRR_CUT_MASK) == RCAR_M3_CUT_VER11) {
+ /* M3 Ver.1.1 or Ver.1.2 */
+ NOTICE("BL2: PRR is RZ/%s Ver.1.1 / Ver.1.2\n", str);
+ } else {
+ NOTICE("BL2: PRR is RZ/%s Ver.1.%d\n", str,
+ (reg & RCAR_MINOR_MASK) + RCAR_M3_MINOR_OFFSET);
+ }
+ } else {
+ major = (reg & RCAR_MAJOR_MASK) >> RCAR_MAJOR_SHIFT;
+ major = major + RCAR_MAJOR_OFFSET;
+ minor = reg & RCAR_MINOR_MASK;
+ NOTICE("BL2: PRR is RZ/%s Ver.%d.%d\n", str, major, minor);
+ }
+
+ rzg_get_board_type(&type, &rev);
+
+ switch (type) {
+ case BOARD_HIHOPE_RZ_G2M:
+ break;
+ default:
+ type = BOARD_UNKNOWN;
+ break;
+ }
+
+ if (type == BOARD_UNKNOWN || rev == BOARD_REV_UNKNOWN) {
+ NOTICE("BL2: Board is %s Rev.---\n", GET_BOARD_NAME(type));
+ } else {
+ NOTICE("BL2: Board is %s Rev.%d.%d\n",
+ GET_BOARD_NAME(type),
+ GET_BOARD_MAJOR(rev), GET_BOARD_MINOR(rev));
+ }
+
+#if RCAR_LSI != RCAR_AUTO
+ if (product != TARGET_PRODUCT) {
+ ERROR("BL2: IPL was been built for the %s.\n", TARGET_NAME);
+ ERROR("BL2: Please write the correct IPL to flash memory.\n");
+ panic();
+ }
+#endif /* RCAR_LSI != RCAR_AUTO */
+ rcar_avs_init();
+ rcar_avs_setting();
+
+ switch (boot_dev) {
+ case MODEMR_BOOT_DEV_HYPERFLASH160:
+ str = boot_hyper160;
+ break;
+ case MODEMR_BOOT_DEV_HYPERFLASH80:
+ str = boot_hyper80;
+ break;
+ case MODEMR_BOOT_DEV_QSPI_FLASH40:
+ str = boot_qspi40;
+ break;
+ case MODEMR_BOOT_DEV_QSPI_FLASH80:
+ str = boot_qspi80;
+ break;
+ case MODEMR_BOOT_DEV_EMMC_25X1:
+ str = boot_emmc25x1;
+ break;
+ case MODEMR_BOOT_DEV_EMMC_50X8:
+ str = boot_emmc50x8;
+ break;
+ default:
+ str = unknown;
+ break;
+ }
+ NOTICE("BL2: Boot device is %s\n", str);
+
+ rcar_avs_setting();
+
+#if RZG_LCS_STATE_DETECTION_ENABLE
+ reg = rcar_rom_get_lcs(&lcs);
+ if (reg != 0U) {
+ str = unknown;
+ goto lcm_state;
+ }
+
+ switch (lcs) {
+ case LCS_CM:
+ str = lcs_cm;
+ break;
+ case LCS_DM:
+ str = lcs_dm;
+ break;
+ case LCS_SD:
+ str = lcs_sd;
+ break;
+ case LCS_SE:
+ str = lcs_secure;
+ break;
+ case LCS_FA:
+ str = lcs_fa;
+ break;
+ default:
+ str = unknown;
+ break;
+ }
+
+lcm_state:
+ NOTICE("BL2: LCM state is %s\n", str);
+#endif /* RZG_LCS_STATE_DETECTION_ENABLE */
+
+ rcar_avs_end();
+ is_ddr_backup_mode();
+
+ bl2_tzram_layout.total_base = BL31_BASE;
+ bl2_tzram_layout.total_size = BL31_LIMIT - BL31_BASE;
+
+ if (boot_cpu == MODEMR_BOOT_CPU_CA57 ||
+ boot_cpu == MODEMR_BOOT_CPU_CA53) {
+ ret = rzg_dram_init();
+ if (ret != 0) {
+ NOTICE("BL2: Failed to DRAM initialize (%d).\n", ret);
+ panic();
+ }
+ rzg_qos_init();
+ }
+
+ /* Set up FDT */
+ ret = fdt_create_empty_tree(fdt, sizeof(fdt_blob));
+ if (ret != 0) {
+ NOTICE("BL2: Cannot allocate FDT for U-Boot (ret=%i)\n", ret);
+ panic();
+ }
+
+ /* Add platform compatible string */
+ bl2_populate_compatible_string(fdt);
+
+ /* Print DRAM layout */
+ bl2_advertise_dram_size(product);
+
+ if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 ||
+ boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) {
+ if (rcar_emmc_init() != EMMC_SUCCESS) {
+ NOTICE("BL2: Failed to eMMC driver initialize.\n");
+ panic();
+ }
+ rcar_emmc_memcard_power(EMMC_POWER_ON);
+ if (rcar_emmc_mount() != EMMC_SUCCESS) {
+ NOTICE("BL2: Failed to eMMC mount operation.\n");
+ panic();
+ }
+ } else {
+ rcar_rpc_init();
+ rcar_dma_init();
+ }
+
+ reg = mmio_read_32(RST_WDTRSTCR);
+ reg &= ~WDTRSTCR_RWDT_RSTMSK;
+ reg |= WDTRSTCR_PASSWORD;
+ mmio_write_32(RST_WDTRSTCR, reg);
+
+ mmio_write_32(CPG_CPGWPR, CPGWPR_PASSWORD);
+ mmio_write_32(CPG_CPGWPCR, CPGWPCR_PASSWORD);
+
+ reg = mmio_read_32(RCAR_PRR);
+ if ((reg & RCAR_CPU_MASK_CA57) == RCAR_CPU_HAVE_CA57) {
+ mmio_write_32(CPG_CA57DBGRCR,
+ DBGCPUPREN | mmio_read_32(CPG_CA57DBGRCR));
+ }
+
+ if ((reg & RCAR_CPU_MASK_CA53) == RCAR_CPU_HAVE_CA53) {
+ mmio_write_32(CPG_CA53DBGRCR,
+ DBGCPUPREN | mmio_read_32(CPG_CA53DBGRCR));
+ }
+
+ if (product_cut == PRR_PRODUCT_H3_CUT10) {
+ reg = mmio_read_32(CPG_PLL2CR);
+ reg &= ~((uint32_t)1 << 5);
+ mmio_write_32(CPG_PLL2CR, reg);
+
+ reg = mmio_read_32(CPG_PLL4CR);
+ reg &= ~((uint32_t)1 << 5);
+ mmio_write_32(CPG_PLL4CR, reg);
+
+ reg = mmio_read_32(CPG_PLL0CR);
+ reg &= ~((uint32_t)1 << 12);
+ mmio_write_32(CPG_PLL0CR, reg);
+ }
+#if (RCAR_LOSSY_ENABLE == 1)
+ NOTICE("BL2: Lossy Decomp areas\n");
+
+ fcnlnode = fdt_add_subnode(fdt, 0, "reserved-memory");
+ if (fcnlnode < 0) {
+ NOTICE("BL2: Cannot create reserved mem node (ret=%i)\n",
+ fcnlnode);
+ panic();
+ }
+
+ bl2_lossy_setting(0, LOSSY_ST_ADDR0, LOSSY_END_ADDR0,
+ LOSSY_FMT0, LOSSY_ENA_DIS0, fcnlnode);
+ bl2_lossy_setting(1, LOSSY_ST_ADDR1, LOSSY_END_ADDR1,
+ LOSSY_FMT1, LOSSY_ENA_DIS1, fcnlnode);
+ bl2_lossy_setting(2, LOSSY_ST_ADDR2, LOSSY_END_ADDR2,
+ LOSSY_FMT2, LOSSY_ENA_DIS2, fcnlnode);
+#endif /* RCAR_LOSSY_ENABLE */
+
+ fdt_pack(fdt);
+ NOTICE("BL2: FDT at %p\n", fdt);
+
+ if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 ||
+ boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) {
+ rcar_io_emmc_setup();
+ } else {
+ rcar_io_setup();
+ }
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+#if RCAR_BL2_DCACHE == 1
+ NOTICE("BL2: D-Cache enable\n");
+ rcar_configure_mmu_el3(BL2_BASE,
+ BL2_END - BL2_BASE,
+ BL2_RO_BASE, BL2_RO_LIMIT
+#if USE_COHERENT_MEM
+ , BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_LIMIT
+#endif /* USE_COHERENT_MEM */
+ );
+#endif /* RCAR_BL2_DCACHE == 1 */
+}
+
+void bl2_platform_setup(void)
+{
+ /*
+ * Place holder for performing any platform initialization specific
+ * to BL2.
+ */
+}
+
+static void bl2_init_generic_timer(void)
+{
+ uint32_t reg_cntfid;
+ uint32_t modemr;
+ uint32_t modemr_pll;
+ uint32_t pll_table[] = {
+ EXTAL_MD14_MD13_TYPE_0, /* MD14/MD13 : 0b00 */
+ EXTAL_MD14_MD13_TYPE_1, /* MD14/MD13 : 0b01 */
+ EXTAL_MD14_MD13_TYPE_2, /* MD14/MD13 : 0b10 */
+ EXTAL_MD14_MD13_TYPE_3 /* MD14/MD13 : 0b11 */
+ };
+
+ modemr = mmio_read_32(RCAR_MODEMR);
+ modemr_pll = (modemr & MODEMR_BOOT_PLL_MASK);
+
+ /* Set frequency data in CNTFID0 */
+ reg_cntfid = pll_table[modemr_pll >> MODEMR_BOOT_PLL_SHIFT];
+
+ /* Update memory mapped and register based frequency */
+ write_cntfrq_el0((u_register_t)reg_cntfid);
+ mmio_write_32(ARM_SYS_CNTCTL_BASE + (uintptr_t)CNTFID_OFF, reg_cntfid);
+ /* Enable counter */
+ mmio_setbits_32(RCAR_CNTC_BASE + (uintptr_t)CNTCR_OFF,
+ (uint32_t)CNTCR_EN);
+}
diff --git a/plat/renesas/rzg/platform.mk b/plat/renesas/rzg/platform.mk
new file mode 100644
index 000000000..421cbbe64
--- /dev/null
+++ b/plat/renesas/rzg/platform.mk
@@ -0,0 +1,222 @@
+#
+# Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/renesas/common/common.mk
+
+ifndef LSI
+ $(error "Error: Unknown LSI. Please use LSI=<LSI name> to specify the LSI")
+else
+ ifeq (${LSI},AUTO)
+ RCAR_LSI:=${RCAR_AUTO}
+ else ifeq (${LSI},G2M)
+ RCAR_LSI:=${RZ_G2M}
+ ifndef LSI_CUT
+ # enable compatible function.
+ RCAR_LSI_CUT_COMPAT := 1
+ $(eval $(call add_define,RCAR_LSI_CUT_COMPAT))
+ else
+ # disable compatible function.
+ ifeq (${LSI_CUT},10)
+ RCAR_LSI_CUT:=0
+ else ifeq (${LSI_CUT},11)
+ RCAR_LSI_CUT:=1
+ else ifeq (${LSI_CUT},13)
+ RCAR_LSI_CUT:=3
+ else ifeq (${LSI_CUT},30)
+ RCAR_LSI_CUT:=20
+ else
+ $(error "Error: ${LSI_CUT} is not supported.")
+ endif
+ $(eval $(call add_define,RCAR_LSI_CUT))
+ endif
+ else
+ $(error "Error: ${LSI} is not supported.")
+ endif
+ $(eval $(call add_define,RCAR_LSI))
+endif
+
+# Process RZG_LCS_STATE_DETECTION_ENABLE flag
+# Enable to get LCS state information
+ifndef RZG_LCS_STATE_DETECTION_ENABLE
+RZG_LCS_STATE_DETECTION_ENABLE := 0
+endif
+$(eval $(call add_define,RZG_LCS_STATE_DETECTION_ENABLE))
+
+# Process RCAR_SECURE_BOOT flag
+ifndef RCAR_SECURE_BOOT
+RCAR_SECURE_BOOT := 0
+endif
+$(eval $(call add_define,RCAR_SECURE_BOOT))
+
+# LCS state of RZ/G2 Chip is all CM.
+# However certain chips(RZ/G2M and RZ/G2E) have incorrect factory Fuse settings
+# which results in getting incorrect LCS states
+# if need to enable RCAR_SECURE_BOOT, make sure the chip has proper factory Fuse settings.
+ifeq (${RCAR_SECURE_BOOT},1)
+ ifeq (${RZG_LCS_STATE_DETECTION_ENABLE},0)
+ $(error "Error: Please check the chip has proper factory Fuse settings and set RZG_LCS_STATE_DETECTION_ENABLE to enable.")
+ endif
+endif
+
+# lock RPC HYPERFLASH access by default
+# unlock to repogram the ATF firmware from u-boot
+ifndef RCAR_RPC_HYPERFLASH_LOCKED
+RCAR_RPC_HYPERFLASH_LOCKED := 1
+endif
+$(eval $(call add_define,RCAR_RPC_HYPERFLASH_LOCKED))
+
+# Process RCAR_QOS_TYPE flag
+ifndef RCAR_QOS_TYPE
+RCAR_QOS_TYPE := 0
+endif
+$(eval $(call add_define,RCAR_QOS_TYPE))
+
+# Process RCAR_DRAM_SPLIT flag
+ifndef RCAR_DRAM_SPLIT
+RCAR_DRAM_SPLIT := 0
+endif
+$(eval $(call add_define,RCAR_DRAM_SPLIT))
+
+# Process RCAR_BL33_EXECUTION_EL flag
+ifndef RCAR_BL33_EXECUTION_EL
+RCAR_BL33_EXECUTION_EL := 0
+endif
+$(eval $(call add_define,RCAR_BL33_EXECUTION_EL))
+
+# Process RCAR_AVS_SETTING_ENABLE flag
+ifndef AVS_SETTING_ENABLE
+AVS_SETTING_ENABLE := 0
+endif
+$(eval $(call add_define,AVS_SETTING_ENABLE))
+
+# Process RCAR_LOSSY_ENABLE flag
+ifndef RCAR_LOSSY_ENABLE
+RCAR_LOSSY_ENABLE := 0
+endif
+$(eval $(call add_define,RCAR_LOSSY_ENABLE))
+
+# Process LIFEC_DBSC_PROTECT_ENABLE flag
+ifndef LIFEC_DBSC_PROTECT_ENABLE
+LIFEC_DBSC_PROTECT_ENABLE := 1
+endif
+$(eval $(call add_define,LIFEC_DBSC_PROTECT_ENABLE))
+
+# Process RCAR_GEN3_ULCB flag
+ifndef RCAR_GEN3_ULCB
+RCAR_GEN3_ULCB := 0
+endif
+
+# Process RCAR_REF_INT flag
+ifndef RCAR_REF_INT
+RCAR_REF_INT :=0
+endif
+$(eval $(call add_define,RCAR_REF_INT))
+
+# Process RCAR_REWT_TRAINING flag
+ifndef RCAR_REWT_TRAINING
+RCAR_REWT_TRAINING := 1
+endif
+$(eval $(call add_define,RCAR_REWT_TRAINING))
+
+# Process RCAR_SYSTEM_SUSPEND flag
+ifndef RCAR_SYSTEM_SUSPEND
+RCAR_SYSTEM_SUSPEND := 0
+endif
+$(eval $(call add_define,RCAR_SYSTEM_SUSPEND))
+
+# Process RCAR_DRAM_LPDDR4_MEMCONF flag
+ifndef RCAR_DRAM_LPDDR4_MEMCONF
+RCAR_DRAM_LPDDR4_MEMCONF :=1
+endif
+$(eval $(call add_define,RCAR_DRAM_LPDDR4_MEMCONF))
+
+# Process RCAR_DRAM_DDR3L_MEMCONF flag
+ifndef RCAR_DRAM_DDR3L_MEMCONF
+RCAR_DRAM_DDR3L_MEMCONF :=1
+endif
+$(eval $(call add_define,RCAR_DRAM_DDR3L_MEMCONF))
+
+# Process RCAR_DRAM_DDR3L_MEMDUAL flag
+ifndef RCAR_DRAM_DDR3L_MEMDUAL
+RCAR_DRAM_DDR3L_MEMDUAL :=1
+endif
+$(eval $(call add_define,RCAR_DRAM_DDR3L_MEMDUAL))
+
+# Process RCAR_BL33_ARG0 flag
+ifdef RCAR_BL33_ARG0
+$(eval $(call add_define,RCAR_BL33_ARG0))
+endif
+
+#Process RCAR_BL2_DCACHE flag
+ifndef RCAR_BL2_DCACHE
+RCAR_BL2_DCACHE := 0
+endif
+$(eval $(call add_define,RCAR_BL2_DCACHE))
+
+# Process RCAR_DRAM_CHANNEL flag
+ifndef RCAR_DRAM_CHANNEL
+RCAR_DRAM_CHANNEL :=15
+endif
+$(eval $(call add_define,RCAR_DRAM_CHANNEL))
+
+#Process RCAR_SYSTEM_RESET_KEEPON_DDR flag
+ifndef RCAR_SYSTEM_RESET_KEEPON_DDR
+RCAR_SYSTEM_RESET_KEEPON_DDR := 0
+endif
+$(eval $(call add_define,RCAR_SYSTEM_RESET_KEEPON_DDR))
+
+include drivers/renesas/rzg/ddr/ddr.mk
+include drivers/renesas/rzg/qos/qos.mk
+include drivers/renesas/rzg/pfc/pfc.mk
+include lib/libfdt/libfdt.mk
+
+PLAT_INCLUDES += -Idrivers/renesas/rzg/ddr \
+ -Idrivers/renesas/rzg/qos \
+ -Idrivers/renesas/rzg/board \
+ -Idrivers/renesas/common \
+ -Idrivers/renesas/common/iic_dvfs \
+ -Idrivers/renesas/common/avs \
+ -Idrivers/renesas/common/delay \
+ -Idrivers/renesas/common/rom \
+ -Idrivers/renesas/common/scif \
+ -Idrivers/renesas/common/emmc \
+ -Idrivers/renesas/common/pwrc \
+ -Idrivers/renesas/common/io
+
+BL2_SOURCES += plat/renesas/rzg/bl2_plat_setup.c \
+ drivers/renesas/rzg/board/board.c
+
+# build the layout images for the bootrom and the necessary srecords
+rzg: rzg_layout_create rzg_srecord
+distclean realclean clean: clean_layout_tool clean_srecord
+
+# layout images
+LAYOUT_TOOLPATH ?= tools/renesas/rzg_layout_create
+
+clean_layout_tool:
+ @echo "clean layout tool"
+ ${Q}${MAKE} -C ${LAYOUT_TOOLPATH} clean
+
+.PHONY: rzg_layout_create
+rzg_layout_create:
+ @echo "generating layout srecs"
+ ${Q}${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
+
+# srecords
+SREC_PATH = ${BUILD_PLAT}
+BL2_ELF_SRC = ${SREC_PATH}/bl2/bl2.elf
+BL31_ELF_SRC = ${SREC_PATH}/bl31/bl31.elf
+
+clean_srecord:
+ @echo "clean bl2 and bl31 srecs"
+ rm -f ${SREC_PATH}/bl2.srec ${SREC_PATH}/bl31.srec
+
+.PHONY: rzg_srecord
+rzg_srecord: $(BL2_ELF_SRC) $(BL31_ELF_SRC)
+ @echo "generating srec: ${SREC_PATH}/bl2.srec"
+ $(Q)$(OC) -O srec --srec-forceS3 ${BL2_ELF_SRC} ${SREC_PATH}/bl2.srec
+ @echo "generating srec: ${SREC_PATH}/bl31.srec"
+ $(Q)$(OC) -O srec --srec-forceS3 ${BL31_ELF_SRC} ${SREC_PATH}/bl31.srec
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
index 11321d773..881625e4c 100644
--- a/plat/rockchip/common/bl31_plat_setup.c
+++ b/plat/rockchip/common/bl31_plat_setup.c
@@ -55,7 +55,7 @@ void params_early_setup(u_register_t plat_param_from_bl2)
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_16550_t console;
+ static console_t console;
struct rockchip_bl31_params *arg_from_bl2 = (struct rockchip_bl31_params *) arg0;
params_early_setup(arg1);
diff --git a/plat/rockchip/common/drivers/parameter/ddr_parameter.h b/plat/rockchip/common/drivers/parameter/ddr_parameter.h
index 61349c44c..25c93a191 100644
--- a/plat/rockchip/common/drivers/parameter/ddr_parameter.h
+++ b/plat/rockchip/common/drivers/parameter/ddr_parameter.h
@@ -35,8 +35,8 @@ struct param_ddr_usage {
uint64_t ns_top[DDR_REGION_NR_MAX];
uint32_t s_nr;
- uint64_t s_base[DDR_REGION_NR_MAX];
- uint64_t s_top[DDR_REGION_NR_MAX];
+ uint64_t s_base[DDR_REGION_NR_MAX + 1];
+ uint64_t s_top[DDR_REGION_NR_MAX + 1];
};
struct param_ddr_usage ddr_region_usage_parse(uint64_t addr, uint64_t max_mb);
diff --git a/plat/rockchip/common/params_setup.c b/plat/rockchip/common/params_setup.c
index b2fd2011e..aec53eee2 100644
--- a/plat/rockchip/common/params_setup.c
+++ b/plat/rockchip/common/params_setup.c
@@ -37,7 +37,8 @@ static int dt_process_fdt(u_register_t param_from_bl2)
static uint32_t rk_uart_base = PLAT_RK_UART_BASE;
static uint32_t rk_uart_baudrate = PLAT_RK_UART_BAUDRATE;
static uint32_t rk_uart_clock = PLAT_RK_UART_CLOCK;
-static uint8_t fdt_buffer[0x10000];
+#define FDT_BUFFER_SIZE 0x20000
+static uint8_t fdt_buffer[FDT_BUFFER_SIZE];
void *plat_get_fdt(void)
{
@@ -136,7 +137,7 @@ static int dt_process_fdt(u_register_t param_from_bl2)
void *fdt = plat_get_fdt();
int ret;
- ret = fdt_open_into((void *)param_from_bl2, fdt, 0x10000);
+ ret = fdt_open_into((void *)param_from_bl2, fdt, FDT_BUFFER_SIZE);
if (ret < 0)
return ret;
@@ -229,12 +230,27 @@ static bool rk_aux_param_handler(struct bl_aux_param_header *param)
void params_early_setup(u_register_t plat_param_from_bl2)
{
+ int ret;
+
/*
* Test if this is a FDT passed as a platform-specific parameter
* block.
*/
- if (!dt_process_fdt(plat_param_from_bl2))
+ ret = dt_process_fdt(plat_param_from_bl2);
+ if (!ret) {
+ return;
+ } else if (ret != -FDT_ERR_BADMAGIC) {
+ /*
+ * If we found an FDT but couldn't parse it (e.g. corrupt, not
+ * enough space), return and don't attempt to parse the param
+ * as something else, since we know that will also fail. All
+ * we're doing is setting up UART, this doesn't need to be
+ * fatal.
+ */
+ WARN("%s: found FDT but could not parse: error %d\n",
+ __func__, ret);
return;
+ }
bl_aux_params_parse(plat_param_from_bl2, rk_aux_param_handler);
}
diff --git a/plat/rockchip/common/rockchip_stack_protector.c b/plat/rockchip/common/rockchip_stack_protector.c
new file mode 100644
index 000000000..18989779e
--- /dev/null
+++ b/plat/rockchip/common/rockchip_stack_protector.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <plat/common/platform.h>
+
+#define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL)
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ /*
+ * Ideally, a random number should be returned instead of the
+ * combination of a timer's value and a compile-time constant.
+ * As the virt platform does not have any random number generator,
+ * this is better than nothing but not necessarily really secure.
+ */
+ return RANDOM_CANARY_VALUE ^ read_cntpct_el0();
+}
+
diff --git a/plat/rockchip/common/sp_min_plat_setup.c b/plat/rockchip/common/sp_min_plat_setup.c
index 3f8767ecb..0f104ef61 100644
--- a/plat/rockchip/common/sp_min_plat_setup.c
+++ b/plat/rockchip/common/sp_min_plat_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -51,7 +51,7 @@ unsigned int plat_is_my_cpu_primary(void);
void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- static console_16550_t console;
+ static console_t console;
struct rockchip_bl31_params *arg_from_bl2 = (struct rockchip_bl31_params *) arg0;
params_early_setup(arg1);
diff --git a/plat/rockchip/px30/platform.mk b/plat/rockchip/px30/platform.mk
index 87cf18704..e2b497685 100644
--- a/plat/rockchip/px30/platform.mk
+++ b/plat/rockchip/px30/platform.mk
@@ -36,8 +36,11 @@ PLAT_BL_COMMON_SOURCES := lib/bl_aux_params/bl_aux_params.c \
lib/xlat_tables/aarch64/xlat_tables.c \
plat/common/plat_psci_common.c
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES += ${RK_PLAT_COMMON}/rockchip_stack_protector.c
+endif
+
BL31_SOURCES += ${RK_GIC_SOURCES} \
- common/desc_image_load.c \
drivers/arm/cci/cci.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk
index fef459855..bbf351995 100644
--- a/plat/rockchip/rk3328/platform.mk
+++ b/plat/rockchip/rk3328/platform.mk
@@ -34,6 +34,10 @@ PLAT_BL_COMMON_SOURCES := lib/bl_aux_params/bl_aux_params.c \
plat/common/aarch64/crash_console_helpers.S \
plat/common/plat_psci_common.c
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES += ${RK_PLAT_COMMON}/rockchip_stack_protector.c
+endif
+
BL31_SOURCES += ${RK_GIC_SOURCES} \
drivers/arm/cci/cci.c \
drivers/ti/uart/aarch64/16550_console.S \
diff --git a/plat/rockchip/rk3368/include/platform_def.h b/plat/rockchip/rk3368/include/platform_def.h
index 12115b4f0..519a025c9 100644
--- a/plat/rockchip/rk3368/include/platform_def.h
+++ b/plat/rockchip/rk3368/include/platform_def.h
@@ -48,7 +48,7 @@
PLATFORM_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT)
-#define PLAT_RK_CLST_TO_CPUID_SHIFT 8
+#define PLAT_RK_CLST_TO_CPUID_SHIFT 6
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
@@ -86,7 +86,7 @@
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define MAX_XLAT_TABLES 8
-#define MAX_MMAP_REGIONS 16
+#define MAX_MMAP_REGIONS 20
/*******************************************************************************
* Declarations and constants to access the mailboxes safely. Each mailbox is
diff --git a/plat/rockchip/rk3368/platform.mk b/plat/rockchip/rk3368/platform.mk
index 8812378b1..ce93c6839 100644
--- a/plat/rockchip/rk3368/platform.mk
+++ b/plat/rockchip/rk3368/platform.mk
@@ -32,6 +32,10 @@ PLAT_BL_COMMON_SOURCES := lib/bl_aux_params/bl_aux_params.c \
plat/common/aarch64/crash_console_helpers.S \
plat/common/plat_psci_common.c
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES += ${RK_PLAT_COMMON}/rockchip_stack_protector.c
+endif
+
BL31_SOURCES += ${RK_GIC_SOURCES} \
drivers/arm/cci/cci.c \
drivers/ti/uart/aarch64/16550_console.S \
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index d58215dcf..dad9f4d96 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -24,20 +24,23 @@ PLAT_INCLUDES := -I${RK_PLAT_COMMON}/ \
-I${RK_PLAT_SOC}/include/ \
-I${RK_PLAT_SOC}/include/shared/ \
-RK_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v3/arm_gicv3_common.c \
- drivers/arm/gic/v3/gic500.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/v3/gicv3_helpers.c \
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+RK_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
${RK_PLAT}/common/rockchip_gicv3.c
-PLAT_BL_COMMON_SOURCES := lib/bl_aux_params/bl_aux_params.c \
+PLAT_BL_COMMON_SOURCES := lib/bl_aux_params/bl_aux_params.c \
lib/xlat_tables/xlat_tables_common.c \
lib/xlat_tables/aarch64/xlat_tables.c \
plat/common/aarch64/crash_console_helpers.S \
plat/common/plat_psci_common.c
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES += ${RK_PLAT_COMMON}/rockchip_stack_protector.c
+endif
+
BL31_SOURCES += ${RK_GIC_SOURCES} \
drivers/arm/cci/cci.c \
drivers/ti/uart/aarch64/16550_console.S \
diff --git a/plat/rpi/rpi4/aarch64/plat_helpers.S b/plat/rpi/common/aarch64/plat_helpers.S
index 083c30e71..f045e2113 100644
--- a/plat/rpi/rpi4/aarch64/plat_helpers.S
+++ b/plat/rpi/common/aarch64/plat_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,8 +10,6 @@
#include <platform_def.h>
#include <cortex_a72.h>
-#include "../include/rpi_hw.h"
-
.globl plat_crash_console_flush
.globl plat_crash_console_init
.globl plat_crash_console_putc
@@ -22,6 +20,7 @@
.globl plat_reset_handler
.globl plat_rpi3_calc_core_pos
.globl plat_secondary_cold_boot_setup
+ .globl plat_rpi_get_model
/* -----------------------------------------------------
* unsigned int plat_my_core_pos(void)
@@ -58,27 +57,29 @@ endfunc plat_rpi3_calc_core_pos
func plat_is_my_cpu_primary
mrs x0, mpidr_el1
and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
- cmp x0, #RPI4_PRIMARY_CPU
+ cmp x0, #RPI_PRIMARY_CPU
cset w0, eq
ret
endfunc plat_is_my_cpu_primary
/* -----------------------------------------------------
- * void plat_secondary_cold_boot_setup (void);
+ * void plat_wait_for_warm_boot (void);
*
* This function performs any platform specific actions
- * needed for a secondary cpu after a cold reset e.g
- * mark the cpu's presence, mechanism to place it in a
- * holding pen etc.
+ * needed for a CPU to be put into holding pen to wait
+ * for a warm boot request.
+ * The function will never return.
* -----------------------------------------------------
*/
-func plat_secondary_cold_boot_setup
- /* Calculate address of our hold entry */
+func plat_wait_for_warm_boot
+ /*
+ * Calculate address of our hold entry.
+ * As the function will never return, there is no need to save LR.
+ */
bl plat_my_core_pos
lsl x0, x0, #3
mov_imm x2, PLAT_RPI3_TM_HOLD_BASE
add x0, x0, x2
-
/*
* This code runs way before requesting the warmboot of this core,
* so it is possible to clear the mailbox before getting a request
@@ -98,6 +99,19 @@ poll_mailbox:
mov_imm x0, PLAT_RPI3_TM_ENTRYPOINT
ldr x1, [x0]
br x1
+endfunc plat_wait_for_warm_boot
+
+ /* -----------------------------------------------------
+ * void plat_secondary_cold_boot_setup (void);
+ *
+ * This function performs any platform specific actions
+ * needed for a secondary cpu after a cold reset e.g
+ * mark the cpu's presence, mechanism to place it in a
+ * holding pen etc.
+ * -----------------------------------------------------
+ */
+func plat_secondary_cold_boot_setup
+ b plat_wait_for_warm_boot
endfunc plat_secondary_cold_boot_setup
/* ---------------------------------------------------------------------
@@ -112,9 +126,24 @@ endfunc plat_secondary_cold_boot_setup
* ---------------------------------------------------------------------
*/
func plat_get_my_entrypoint
- /* TODO: support warm boot */
- mov x0, #0
- ret
+ mov x1, x30
+ bl plat_is_my_cpu_primary
+ /*
+ * Secondaries always cold boot.
+ */
+ cbz w0, 1f
+ /*
+ * Primaries warm boot if they are requested
+ * to power off.
+ */
+ mov_imm x0, PLAT_RPI3_TM_HOLD_BASE
+ ldr x0, [x0]
+ cmp x0, PLAT_RPI3_TM_HOLD_STATE_BSP_OFF
+ adr x0, plat_wait_for_warm_boot
+ csel x0, x0, xzr, eq
+ ret x1
+1: mov x0, #0
+ ret x1
endfunc plat_get_my_entrypoint
/* ---------------------------------------------
@@ -135,7 +164,7 @@ endfunc platform_mem_init
* ---------------------------------------------
*/
func plat_crash_console_init
- mov_imm x0, PLAT_RPI3_UART_BASE
+ mov_imm x0, PLAT_RPI_MINI_UART_BASE
mov x1, xzr
mov x2, xzr
b console_16550_core_init
@@ -149,28 +178,55 @@ endfunc plat_crash_console_init
* ---------------------------------------------
*/
func plat_crash_console_putc
- mov_imm x1, PLAT_RPI3_UART_BASE
+ mov_imm x1, PLAT_RPI_MINI_UART_BASE
b console_16550_core_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush()
+ * void plat_crash_console_flush()
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : x0, x1
* ---------------------------------------------
*/
func plat_crash_console_flush
- mov_imm x0, PLAT_RPI3_UART_BASE
+ mov_imm x0, PLAT_RPI_MINI_UART_BASE
b console_16550_core_flush
endfunc plat_crash_console_flush
/* ---------------------------------------------
+ * int plat_rpi_get_model()
+ * Macro to determine whether we are running on
+ * a Raspberry Pi 3 or 4. Just checks the MIDR for
+ * being either a Cortex-A72 or a Cortex-A53.
+ * Out : return 4 if RPi4, 3 otherwise.
+ * Clobber list : x0
+ * ---------------------------------------------
+ */
+ .macro _plat_rpi_get_model
+ mrs x0, midr_el1
+ and x0, x0, #0xf0 /* Isolate low byte of part number */
+ cmp w0, #0x80 /* Cortex-A72 (RPi4) is 0xd08, A53 is 0xd03 */
+ mov w0, #3
+ csinc w0, w0, w0, ne
+ .endm
+
+ func plat_rpi_get_model
+ _plat_rpi_get_model
+ ret
+ endfunc plat_rpi_get_model
+
+ /* ---------------------------------------------
* void plat_reset_handler(void);
* ---------------------------------------------
*/
func plat_reset_handler
+ /* L2 cache setup only needed on RPi4 */
+ _plat_rpi_get_model
+ cmp w0, #4
+ b.ne 1f
+
/* ------------------------------------------------
* Set L2 read/write cache latency:
* - L2 Data RAM latency: 3 cycles (0b010)
@@ -183,5 +239,6 @@ func plat_reset_handler
msr CORTEX_A72_L2CTLR_EL1, x0
isb
+1:
ret
endfunc plat_reset_handler
diff --git a/plat/rpi/common/include/rpi_shared.h b/plat/rpi/common/include/rpi_shared.h
index de8357162..ddf239eb5 100644
--- a/plat/rpi/common/include/rpi_shared.h
+++ b/plat/rpi/common/include/rpi_shared.h
@@ -14,7 +14,7 @@
******************************************************************************/
/* Utility functions */
-void rpi3_console_init(unsigned int base_clk_rate);
+void rpi3_console_init(void);
void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size,
uintptr_t code_start, uintptr_t code_limit,
uintptr_t rodata_start, uintptr_t rodata_limit
@@ -36,4 +36,6 @@ void plat_rpi3_io_setup(void);
/* VideoCore firmware commands */
int rpi3_vc_hardware_get_board_revision(uint32_t *revision);
+int plat_rpi_get_model(void);
+
#endif /* RPI3_PRIVATE_H */
diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c
index ff3369427..ef88bf10e 100644
--- a/plat/rpi/common/rpi3_common.c
+++ b/plat/rpi/common/rpi3_common.c
@@ -13,7 +13,9 @@
#include <common/debug.h>
#include <bl31/interrupt_mgmt.h>
#include <drivers/console.h>
+#include <drivers/rpi3/gpio/rpi3_gpio.h>
#include <drivers/ti/uart/uart_16550.h>
+#include <drivers/arm/pl011.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <rpi_hw.h>
@@ -102,18 +104,35 @@ static const mmap_region_t plat_rpi3_mmap[] = {
/*******************************************************************************
* Function that sets up the console
******************************************************************************/
-static console_16550_t rpi3_console;
+static console_t rpi3_console;
-void rpi3_console_init(unsigned int base_clk_rate)
+
+static bool rpi3_use_mini_uart(void)
+{
+ return rpi3_gpio_get_select(14) == RPI3_GPIO_FUNC_ALT5;
+}
+
+void rpi3_console_init(void)
{
int console_scope = CONSOLE_FLAG_BOOT;
-#if RPI3_RUNTIME_UART != -1
- console_scope |= CONSOLE_FLAG_RUNTIME;
-#endif
- int rc = console_16550_register(PLAT_RPI3_UART_BASE,
- base_clk_rate,
- PLAT_RPI3_UART_BAUDRATE,
- &rpi3_console);
+ int rc;
+
+ if (RPI3_RUNTIME_UART != -1)
+ console_scope |= CONSOLE_FLAG_RUNTIME;
+
+ rpi3_gpio_init();
+
+ if (rpi3_use_mini_uart())
+ rc = console_16550_register(PLAT_RPI_MINI_UART_BASE,
+ 0,
+ PLAT_RPI_UART_BAUDRATE,
+ &rpi3_console);
+ else
+ rc = console_pl011_register(PLAT_RPI_PL011_UART_BASE,
+ PLAT_RPI_PL011_UART_CLOCK,
+ PLAT_RPI_UART_BAUDRATE,
+ &rpi3_console);
+
if (rc == 0) {
/*
* The crash console doesn't use the multi console API, it uses
@@ -123,7 +142,7 @@ void rpi3_console_init(unsigned int base_clk_rate)
panic();
}
- console_set_scope(&rpi3_console.console, console_scope);
+ console_set_scope(&rpi3_console, console_scope);
}
/*******************************************************************************
diff --git a/plat/rpi/common/rpi3_pm.c b/plat/rpi/common/rpi3_pm.c
index 2a6bf076b..86c61f7a6 100644
--- a/plat/rpi/common/rpi3_pm.c
+++ b/plat/rpi/common/rpi3_pm.c
@@ -140,11 +140,14 @@ static int rpi3_pwr_domain_on(u_register_t mpidr)
{
int rc = PSCI_E_SUCCESS;
unsigned int pos = plat_core_pos_by_mpidr(mpidr);
- uint64_t *hold_base = (uint64_t *)PLAT_RPI3_TM_HOLD_BASE;
+ uintptr_t hold_base = PLAT_RPI3_TM_HOLD_BASE;
assert(pos < PLATFORM_CORE_COUNT);
- hold_base[pos] = PLAT_RPI3_TM_HOLD_STATE_GO;
+ hold_base += pos * PLAT_RPI3_TM_HOLD_ENTRY_SIZE;
+
+ mmio_write_64(hold_base, PLAT_RPI3_TM_HOLD_STATE_GO);
+ /* No cache maintenance here, hold_base is mapped as device memory. */
/* Make sure that the write has completed */
dsb();
@@ -171,6 +174,32 @@ static void rpi3_pwr_domain_on_finish(const psci_power_state_t *target_state)
#endif
}
+static void __dead2 rpi3_pwr_down_wfi(
+ const psci_power_state_t *target_state)
+{
+ uintptr_t hold_base = PLAT_RPI3_TM_HOLD_BASE;
+ unsigned int pos = plat_my_core_pos();
+
+ if (pos == 0) {
+ /*
+ * The secondaries will always be in a wait
+ * for warm boot on reset, but the BSP needs
+ * to be able to distinguish between waiting
+ * for warm boot (e.g. after psci_off, waiting
+ * for psci_on) and a cold boot.
+ */
+ mmio_write_64(hold_base, PLAT_RPI3_TM_HOLD_STATE_BSP_OFF);
+ /* No cache maintenance here, we run with caches off already. */
+ dsb();
+ isb();
+ }
+
+ write_rmr_el3(RMR_EL3_RR_BIT | RMR_EL3_AA64_BIT);
+
+ while (1)
+ ;
+}
+
/*******************************************************************************
* Platform handlers for system reset and system off.
******************************************************************************/
@@ -236,6 +265,7 @@ static const plat_psci_ops_t plat_rpi3_psci_pm_ops = {
.pwr_domain_pwr_down_wfi = rpi3_pwr_domain_pwr_down_wfi,
.pwr_domain_on = rpi3_pwr_domain_on,
.pwr_domain_on_finish = rpi3_pwr_domain_on_finish,
+ .pwr_domain_pwr_down_wfi = rpi3_pwr_down_wfi,
.system_off = rpi3_system_off,
.system_reset = rpi3_system_reset,
.validate_power_state = rpi3_validate_power_state,
diff --git a/plat/rpi/rpi3/aarch64/plat_helpers.S b/plat/rpi/rpi3/aarch64/plat_helpers.S
deleted file mode 100644
index 24278bdf6..000000000
--- a/plat/rpi/rpi3/aarch64/plat_helpers.S
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <assert_macros.S>
-#include <platform_def.h>
-
-#include "../include/rpi_hw.h"
-
- .globl plat_crash_console_flush
- .globl plat_crash_console_init
- .globl plat_crash_console_putc
- .globl platform_mem_init
- .globl plat_get_my_entrypoint
- .globl plat_is_my_cpu_primary
- .globl plat_my_core_pos
- .globl plat_rpi3_calc_core_pos
- .globl plat_secondary_cold_boot_setup
-
- /* -----------------------------------------------------
- * unsigned int plat_my_core_pos(void)
- *
- * This function uses the plat_rpi3_calc_core_pos()
- * definition to get the index of the calling CPU.
- * -----------------------------------------------------
- */
-func plat_my_core_pos
- mrs x0, mpidr_el1
- b plat_rpi3_calc_core_pos
-endfunc plat_my_core_pos
-
- /* -----------------------------------------------------
- * unsigned int plat_rpi3_calc_core_pos(u_register_t mpidr);
- *
- * CorePos = (ClusterId * 4) + CoreId
- * -----------------------------------------------------
- */
-func plat_rpi3_calc_core_pos
- and x1, x0, #MPIDR_CPU_MASK
- and x0, x0, #MPIDR_CLUSTER_MASK
- add x0, x1, x0, LSR #6
- ret
-endfunc plat_rpi3_calc_core_pos
-
- /* -----------------------------------------------------
- * unsigned int plat_is_my_cpu_primary (void);
- *
- * Find out whether the current cpu is the primary
- * cpu.
- * -----------------------------------------------------
- */
-func plat_is_my_cpu_primary
- mrs x0, mpidr_el1
- and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
- cmp x0, #RPI3_PRIMARY_CPU
- cset w0, eq
- ret
-endfunc plat_is_my_cpu_primary
-
- /* -----------------------------------------------------
- * void plat_secondary_cold_boot_setup (void);
- *
- * This function performs any platform specific actions
- * needed for a secondary cpu after a cold reset e.g
- * mark the cpu's presence, mechanism to place it in a
- * holding pen etc.
- * -----------------------------------------------------
- */
-func plat_secondary_cold_boot_setup
- /* Calculate address of our hold entry */
- bl plat_my_core_pos
- lsl x0, x0, #3
- mov_imm x2, PLAT_RPI3_TM_HOLD_BASE
- add x0, x0, x2
-
- /*
- * This code runs way before requesting the warmboot of this core,
- * so it is possible to clear the mailbox before getting a request
- * to boot.
- */
- mov x1, PLAT_RPI3_TM_HOLD_STATE_WAIT
- str x1,[x0]
-
- /* Wait until we have a go */
-poll_mailbox:
- wfe
- ldr x1, [x0]
- cmp x1, PLAT_RPI3_TM_HOLD_STATE_GO
- bne poll_mailbox
-
- /* Jump to the provided entrypoint */
- mov_imm x0, PLAT_RPI3_TM_ENTRYPOINT
- ldr x1, [x0]
- br x1
-endfunc plat_secondary_cold_boot_setup
-
- /* ---------------------------------------------------------------------
- * uintptr_t plat_get_my_entrypoint (void);
- *
- * Main job of this routine is to distinguish between a cold and a warm
- * boot.
- *
- * This functions returns:
- * - 0 for a cold boot.
- * - Any other value for a warm boot.
- * ---------------------------------------------------------------------
- */
-func plat_get_my_entrypoint
- /* TODO: support warm boot */
- mov x0, #0
- ret
-endfunc plat_get_my_entrypoint
-
- /* ---------------------------------------------
- * void platform_mem_init (void);
- *
- * No need to carry out any memory initialization.
- * ---------------------------------------------
- */
-func platform_mem_init
- ret
-endfunc platform_mem_init
-
- /* ---------------------------------------------
- * int plat_crash_console_init(void)
- * Function to initialize the crash console
- * without a C Runtime to print crash report.
- * Clobber list : x0 - x3
- * ---------------------------------------------
- */
-func plat_crash_console_init
- mov_imm x0, PLAT_RPI3_UART_BASE
- mov_imm x1, PLAT_RPI3_UART_CLK_IN_HZ
- mov_imm x2, PLAT_RPI3_UART_BAUDRATE
- b console_16550_core_init
-endfunc plat_crash_console_init
-
- /* ---------------------------------------------
- * int plat_crash_console_putc(int c)
- * Function to print a character on the crash
- * console without a C Runtime.
- * Clobber list : x1, x2
- * ---------------------------------------------
- */
-func plat_crash_console_putc
- mov_imm x1, PLAT_RPI3_UART_BASE
- b console_16550_core_putc
-endfunc plat_crash_console_putc
-
- /* ---------------------------------------------
- * int plat_crash_console_flush()
- * Function to force a write of all buffered
- * data that hasn't been output.
- * Out : return -1 on error else return 0.
- * Clobber list : x0, x1
- * ---------------------------------------------
- */
-func plat_crash_console_flush
- mov_imm x0, PLAT_RPI3_UART_BASE
- b console_16550_core_flush
-endfunc plat_crash_console_flush
diff --git a/plat/rpi/rpi3/include/platform_def.h b/plat/rpi/rpi3/include/platform_def.h
index e308f70a6..f44d1f526 100644
--- a/plat/rpi/rpi3/include/platform_def.h
+++ b/plat/rpi/rpi3/include/platform_def.h
@@ -24,7 +24,7 @@
#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER
#define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT
-#define RPI3_PRIMARY_CPU U(0)
+#define RPI_PRIMARY_CPU U(0)
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1
#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \
@@ -153,6 +153,7 @@
#define PLAT_RPI3_TM_HOLD_STATE_WAIT ULL(0)
#define PLAT_RPI3_TM_HOLD_STATE_GO ULL(1)
+#define PLAT_RPI3_TM_HOLD_STATE_BSP_OFF ULL(2)
/*
* BL1 specific defines.
@@ -249,9 +250,10 @@
/*
* Serial-related constants.
*/
-#define PLAT_RPI3_UART_BASE RPI3_MINI_UART_BASE
-#define PLAT_RPI3_UART_CLK_IN_HZ RPI3_MINI_UART_CLK_IN_HZ
-#define PLAT_RPI3_UART_BAUDRATE ULL(115200)
+#define PLAT_RPI_MINI_UART_BASE RPI3_MINI_UART_BASE
+#define PLAT_RPI_PL011_UART_BASE RPI3_PL011_UART_BASE
+#define PLAT_RPI_PL011_UART_CLOCK RPI3_PL011_UART_CLOCK
+#define PLAT_RPI_UART_BAUDRATE ULL(115200)
/*
* System counter
diff --git a/plat/rpi/rpi3/include/rpi_hw.h b/plat/rpi/rpi3/include/rpi_hw.h
index 01d5b4a0f..2aecab379 100644
--- a/plat/rpi/rpi3/include/rpi_hw.h
+++ b/plat/rpi/rpi3/include/rpi_hw.h
@@ -77,11 +77,15 @@
#define RPI3_RNG_INT_MASK_DISABLE U(0x1)
/*
- * Serial port (called 'Mini UART' in the BCM docucmentation).
+ * Serial ports:
+ * 'Mini UART' in the BCM docucmentation is the 8250 compatible UART.
+ * There is also a PL011 UART, multiplexed to the same pins.
*/
#define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040)
#define RPI3_MINI_UART_BASE (RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET)
-#define RPI3_MINI_UART_CLK_IN_HZ ULL(500000000)
+#define RPI3_IO_PL011_UART_OFFSET ULL(0x00201000)
+#define RPI3_PL011_UART_BASE (RPI_IO_BASE + RPI3_IO_PL011_UART_OFFSET)
+#define RPI3_PL011_UART_CLOCK ULL(48000000)
/*
* GPIO controller
diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk
index a21a7709a..6c239230d 100644
--- a/plat/rpi/rpi3/platform.mk
+++ b/plat/rpi/rpi3/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -11,6 +11,11 @@ PLAT_INCLUDES := -Iplat/rpi/common/include \
-Iplat/rpi/rpi3/include
PLAT_BL_COMMON_SOURCES := drivers/ti/uart/aarch64/16550_console.S \
+ drivers/arm/pl011/aarch64/pl011_console.S \
+ drivers/gpio/gpio.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/rpi3/gpio/rpi3_gpio.c \
+ plat/rpi/common/aarch64/plat_helpers.S \
plat/rpi/common/rpi3_common.c \
${XLAT_TABLES_LIB_SRCS}
@@ -19,7 +24,6 @@ BL1_SOURCES += drivers/io/io_fip.c \
drivers/io/io_storage.c \
lib/cpus/aarch64/cortex_a53.S \
plat/common/aarch64/platform_mp_stack.S \
- plat/rpi/rpi3/aarch64/plat_helpers.S \
plat/rpi/rpi3/rpi3_bl1_setup.c \
plat/rpi/common/rpi3_io_storage.c \
drivers/rpi3/mailbox/rpi3_mbox.c \
@@ -29,15 +33,11 @@ BL2_SOURCES += common/desc_image_load.c \
drivers/io/io_fip.c \
drivers/io/io_memmap.c \
drivers/io/io_storage.c \
- drivers/gpio/gpio.c \
- drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
- drivers/rpi3/gpio/rpi3_gpio.c \
drivers/io/io_block.c \
drivers/mmc/mmc.c \
drivers/rpi3/sdhost/rpi3_sdhost.c \
plat/common/aarch64/platform_mp_stack.S \
- plat/rpi/rpi3/aarch64/plat_helpers.S \
plat/rpi/rpi3/aarch64/rpi3_bl2_mem_params_desc.c \
plat/rpi/rpi3/rpi3_bl2_setup.c \
plat/rpi/common/rpi3_image_load.c \
@@ -45,7 +45,6 @@ BL2_SOURCES += common/desc_image_load.c \
BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
plat/common/plat_psci_common.c \
- plat/rpi/rpi3/aarch64/plat_helpers.S \
plat/rpi/rpi3/rpi3_bl31_setup.c \
plat/rpi/common/rpi3_pm.c \
plat/rpi/common/rpi3_topology.c \
@@ -186,18 +185,20 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
AUTH_SOURCES := drivers/auth/auth_mod.c \
drivers/auth/crypto_mod.c \
drivers/auth/img_parser_mod.c \
- drivers/auth/tbbr/tbbr_cot.c
+ drivers/auth/tbbr/tbbr_cot_common.c
BL1_SOURCES += ${AUTH_SOURCES} \
bl1/tbbr/tbbr_img_desc.c \
plat/common/tbbr/plat_tbbr.c \
plat/rpi/common/rpi3_trusted_boot.c \
- plat/rpi/common/rpi3_rotpk.S
+ plat/rpi/common/rpi3_rotpk.S \
+ drivers/auth/tbbr/tbbr_cot_bl1.c
BL2_SOURCES += ${AUTH_SOURCES} \
plat/common/tbbr/plat_tbbr.c \
plat/rpi/common/rpi3_trusted_boot.c \
- plat/rpi/common/rpi3_rotpk.S
+ plat/rpi/common/rpi3_rotpk.S \
+ drivers/auth/tbbr/tbbr_cot_bl2.c
ROT_KEY = $(BUILD_PLAT)/rot_key.pem
ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
@@ -209,7 +210,7 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
certificates: $(ROT_KEY)
- $(ROT_KEY):
+ $(ROT_KEY): | $(BUILD_PLAT)
@echo " OPENSSL $@"
$(Q)openssl genrsa 2048 > $@ 2>/dev/null
diff --git a/plat/rpi/rpi3/rpi3_bl1_setup.c b/plat/rpi/rpi3/rpi3_bl1_setup.c
index dcce76e47..3ac30e0f0 100644
--- a/plat/rpi/rpi3/rpi3_bl1_setup.c
+++ b/plat/rpi/rpi3/rpi3_bl1_setup.c
@@ -35,7 +35,7 @@ void bl1_early_platform_setup(void)
0x80000000);
/* Initialize the console to provide early debug support */
- rpi3_console_init(PLAT_RPI3_UART_CLK_IN_HZ);
+ rpi3_console_init();
/* Allow BL1 to see the whole Trusted RAM */
bl1_tzram_layout.total_base = BL_RAM_BASE;
diff --git a/plat/rpi/rpi3/rpi3_bl2_setup.c b/plat/rpi/rpi3/rpi3_bl2_setup.c
index 44827c63a..db7181794 100644
--- a/plat/rpi/rpi3/rpi3_bl2_setup.c
+++ b/plat/rpi/rpi3/rpi3_bl2_setup.c
@@ -24,17 +24,6 @@
/* Data structure which holds the extents of the trusted SRAM for BL2 */
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
-/* rpi3 GPIO setup function. */
-static void rpi3_gpio_setup(void)
-{
- struct rpi3_gpio_params params;
-
- memset(&params, 0, sizeof(struct rpi3_gpio_params));
- params.reg_base = RPI3_GPIO_BASE;
-
- rpi3_gpio_init(&params);
-}
-
/* Data structure which holds the MMC info */
static struct mmc_device_info mmc_info;
@@ -62,13 +51,13 @@ void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
meminfo_t *mem_layout = (meminfo_t *) arg1;
/* Initialize the console to provide early debug support */
- rpi3_console_init(PLAT_RPI3_UART_CLK_IN_HZ);
+ rpi3_console_init();
/* Enable arch timer */
generic_delay_timer_init();
/* Setup GPIO driver */
- rpi3_gpio_setup();
+ rpi3_gpio_init();
/* Setup the BL2 memory layout */
bl2_tzram_layout = *mem_layout;
diff --git a/plat/rpi/rpi3/rpi3_bl31_setup.c b/plat/rpi/rpi3/rpi3_bl31_setup.c
index 24a56139b..59157536b 100644
--- a/plat/rpi/rpi3/rpi3_bl31_setup.c
+++ b/plat/rpi/rpi3/rpi3_bl31_setup.c
@@ -72,7 +72,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
{
/* Initialize the console to provide early debug support */
- rpi3_console_init(PLAT_RPI3_UART_CLK_IN_HZ);
+ rpi3_console_init();
/*
* In debug builds, a special value is passed in 'arg1' to verify
diff --git a/plat/rpi/rpi4/include/platform_def.h b/plat/rpi/rpi4/include/platform_def.h
index a9ecdba20..6787ebfee 100644
--- a/plat/rpi/rpi4/include/platform_def.h
+++ b/plat/rpi/rpi4/include/platform_def.h
@@ -24,7 +24,7 @@
#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER
#define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT
-#define RPI4_PRIMARY_CPU U(0)
+#define RPI_PRIMARY_CPU U(0)
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1
#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \
@@ -93,6 +93,7 @@
#define PLAT_RPI3_TM_HOLD_STATE_WAIT ULL(0)
#define PLAT_RPI3_TM_HOLD_STATE_GO ULL(1)
+#define PLAT_RPI3_TM_HOLD_STATE_BSP_OFF ULL(2)
/*
* BL31 specific defines.
@@ -126,8 +127,10 @@
/*
* Serial-related constants.
*/
-#define PLAT_RPI3_UART_BASE RPI3_MINI_UART_BASE
-#define PLAT_RPI3_UART_BAUDRATE ULL(115200)
+#define PLAT_RPI_MINI_UART_BASE RPI4_MINI_UART_BASE
+#define PLAT_RPI_PL011_UART_BASE RPI4_PL011_UART_BASE
+#define PLAT_RPI_PL011_UART_CLOCK RPI4_PL011_UART_CLOCK
+#define PLAT_RPI_UART_BAUDRATE ULL(115200)
/*
* System counter
diff --git a/plat/rpi/rpi4/include/rpi_hw.h b/plat/rpi/rpi4/include/rpi_hw.h
index b1dd4e92e..718510610 100644
--- a/plat/rpi/rpi4/include/rpi_hw.h
+++ b/plat/rpi/rpi4/include/rpi_hw.h
@@ -77,10 +77,15 @@
#define RPI3_RNG_INT_MASK_DISABLE U(0x1)
/*
- * Serial port (called 'Mini UART' in the Broadcom documentation).
+ * Serial ports:
+ * 'Mini UART' in the BCM docucmentation is the 8250 compatible UART.
+ * There is also a PL011 UART, multiplexed to the same pins.
*/
-#define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040)
-#define RPI3_MINI_UART_BASE (RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET)
+#define RPI4_IO_MINI_UART_OFFSET ULL(0x00215040)
+#define RPI4_MINI_UART_BASE (RPI_IO_BASE + RPI4_IO_MINI_UART_OFFSET)
+#define RPI4_IO_PL011_UART_OFFSET ULL(0x00201000)
+#define RPI4_PL011_UART_BASE (RPI_IO_BASE + RPI4_IO_PL011_UART_OFFSET)
+#define RPI4_PL011_UART_CLOCK ULL(48000000)
/*
* GPIO controller
diff --git a/plat/rpi/rpi4/platform.mk b/plat/rpi/rpi4/platform.mk
index 2038021a0..0744bceb4 100644
--- a/plat/rpi/rpi4/platform.mk
+++ b/plat/rpi/rpi4/platform.mk
@@ -11,15 +11,19 @@ PLAT_INCLUDES := -Iplat/rpi/common/include \
-Iplat/rpi/rpi4/include
PLAT_BL_COMMON_SOURCES := drivers/ti/uart/aarch64/16550_console.S \
+ drivers/arm/pl011/aarch64/pl011_console.S \
plat/rpi/common/rpi3_common.c \
${XLAT_TABLES_LIB_SRCS}
BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \
- plat/rpi/rpi4/aarch64/plat_helpers.S \
+ plat/rpi/common/aarch64/plat_helpers.S \
plat/rpi/rpi4/aarch64/armstub8_header.S \
drivers/arm/gic/common/gic_common.c \
drivers/arm/gic/v2/gicv2_helpers.c \
drivers/arm/gic/v2/gicv2_main.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/gpio/gpio.c \
+ drivers/rpi3/gpio/rpi3_gpio.c \
plat/common/plat_gicv2.c \
plat/rpi/rpi4/rpi4_bl31_setup.c \
plat/rpi/common/rpi3_pm.c \
diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c
index 9e3b53979..cfacd1fe1 100644
--- a/plat/rpi/rpi4/rpi4_bl31_setup.c
+++ b/plat/rpi/rpi4/rpi4_bl31_setup.c
@@ -17,6 +17,7 @@
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
#include <libfdt.h>
#include <drivers/arm/gicv2.h>
@@ -132,14 +133,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
/* Early GPU firmware revisions need a little break here. */
ldelay(100000);
- /*
- * Initialize the console to provide early debug support.
- * We rely on the GPU firmware to have initialised the UART correctly,
- * as the baud base clock rate differs across GPU firmware revisions.
- * Providing a base clock of 0 lets the 16550 UART init routine skip
- * the initial enablement and baud rate setup.
- */
- rpi3_console_init(0);
+ /* Initialize the console to provide early debug support. */
+ rpi3_console_init();
bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry();
@@ -206,13 +201,6 @@ void bl31_plat_arch_setup(void)
enable_mmu_el3(0);
}
-static uint32_t dtb_size(const void *dtb)
-{
- const uint32_t *dtb_header = dtb;
-
- return fdt32_to_cpu(dtb_header[1]);
-}
-
static void rpi4_prepare_dtb(void)
{
void *dtb = (void *)rpi4_get_dtb_address();
@@ -256,7 +244,7 @@ static void rpi4_prepare_dtb(void)
if (ret < 0)
ERROR("Failed to pack Device Tree at %p: error %d\n", dtb, ret);
- clean_dcache_range((uintptr_t)dtb, dtb_size(dtb));
+ clean_dcache_range((uintptr_t)dtb, fdt_blob_size(dtb));
INFO("Changed device tree to advertise PSCI.\n");
}
diff --git a/plat/socionext/synquacer/include/plat.ld.S b/plat/socionext/synquacer/include/plat.ld.S
index a06fe2adb..af7a172db 100644
--- a/plat/socionext/synquacer/include/plat.ld.S
+++ b/plat/socionext/synquacer/include/plat.ld.S
@@ -25,7 +25,6 @@ SECTIONS
*/
sp_xlat_table (NOLOAD) : ALIGN(PAGE_SIZE) {
*(sp_xlat_table)
- *(.bss.sp_base_xlat_table)
} >SP_DRAM
}
diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h
index 7158bfaf3..2f8613a7e 100644
--- a/plat/socionext/synquacer/include/platform_def.h
+++ b/plat/socionext/synquacer/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -80,7 +80,6 @@
#define DRAMINFO_BASE 0x2E00FFC0
#define PLAT_SQ_MHU_BASE 0x45000000
-#define PLAT_MHUV2_BASE 0xFFFFFFFF /* MHUV2 is not supported */
#define PLAT_SQ_SCP_COM_SHARED_MEM_BASE 0x45400000
#define SCPI_CMD_GET_DRAMINFO 0x1
@@ -145,6 +144,7 @@
#define PLAT_SP_IMAGE_MMAP_REGIONS 30
#define PLAT_SP_IMAGE_MAX_XLAT_TABLES 20
#define PLAT_SP_IMAGE_XLAT_SECTION_NAME "sp_xlat_table"
+#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME "sp_xlat_table"
#define PLAT_SQ_UART1_BASE PLAT_SQ_BOOT_UART_BASE
#define PLAT_SQ_UART1_SIZE ULL(0x1000)
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index ab1f69e68..dcd5d31ee 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -30,10 +30,11 @@ PLAT_BL_COMMON_SOURCES += $(PLAT_PATH)/sq_helpers.S \
drivers/delay_timer/generic_delay_timer.c \
${XLAT_TABLES_LIB_SRCS}
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
BL31_SOURCES += drivers/arm/ccn/ccn.c \
- drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v3/gicv3_helpers.c \
- drivers/arm/gic/v3/gicv3_main.c \
+ ${GICV3_SOURCES} \
lib/cpus/aarch64/cortex_a53.S \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index b86402179..9723ef9f0 100644
--- a/plat/socionext/synquacer/sq_bl31_setup.c
+++ b/plat/socionext/synquacer/sq_bl31_setup.c
@@ -16,7 +16,7 @@
#include <lib/mmio.h>
#include <sq_common.h>
-static console_pl011_t console;
+static console_t console;
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
@@ -69,8 +69,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
PLAT_SQ_BOOT_UART_CLK_IN_HZ,
SQ_CONSOLE_BAUDRATE, &console);
- console_set_scope(&console.console, CONSOLE_FLAG_BOOT |
- CONSOLE_FLAG_RUNTIME);
+ console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
/* There are no parameters from BL2 if BL31 is a reset vector */
assert(arg0 == 0U);
diff --git a/plat/socionext/synquacer/sq_helpers.S b/plat/socionext/synquacer/sq_helpers.S
index 558aa15f6..7a2d97b33 100644
--- a/plat/socionext/synquacer/sq_helpers.S
+++ b/plat/socionext/synquacer/sq_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -98,10 +98,10 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/*
- * int plat_crash_console_flush(int c)
+ * void plat_crash_console_flush(int c)
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : x0, x1
*/
func plat_crash_console_flush
diff --git a/plat/socionext/uniphier/include/platform_def.h b/plat/socionext/uniphier/include/platform_def.h
index 7c6341d14..b23386d8b 100644
--- a/plat/socionext/uniphier/include/platform_def.h
+++ b/plat/socionext/uniphier/include/platform_def.h
@@ -62,7 +62,6 @@
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
-#define PLAT_XLAT_TABLES_DYNAMIC 1
#define MAX_XLAT_TABLES 9
#define MAX_MMAP_REGIONS 13
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index 8e96b68bb..6edd181f4 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -14,6 +14,16 @@ override ENABLE_SVE_FOR_NS := 0
# UNIPHIER_MEM_BASE so that all TF images are loaded at their link addresses.
override ENABLE_PIE := 1
+ALLOW_RO_XLAT_TABLES := 1
+
+ifeq ($(ALLOW_RO_XLAT_TABLES),1)
+BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES
+BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES
+endif
+
+# The dynamic xlat table is only used in BL2
+BL2_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
+
# Cortex-A53 revision r0p4-51rel0
# needed for LD20, unneeded for LD11, PXs3 (no ACE)
ERRATA_A53_855873 := 1
@@ -55,10 +65,11 @@ BL2_SOURCES += common/desc_image_load.c \
$(PLAT_PATH)/uniphier_scp.c \
$(PLAT_PATH)/uniphier_usb.c
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
BL31_SOURCES += drivers/arm/cci/cci.c \
- drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v3/gicv3_helpers.c \
- drivers/arm/gic/v3/gicv3_main.c \
+ ${GICV3_SOURCES} \
lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a72.S \
plat/common/plat_gicv3.c \
@@ -81,7 +92,8 @@ include drivers/auth/mbedtls/mbedtls_x509.mk
BL2_SOURCES += drivers/auth/auth_mod.c \
drivers/auth/crypto_mod.c \
drivers/auth/img_parser_mod.c \
- drivers/auth/tbbr/tbbr_cot.c \
+ drivers/auth/tbbr/tbbr_cot_common.c \
+ drivers/auth/tbbr/tbbr_cot_bl2.c \
plat/common/tbbr/plat_tbbr.c \
$(PLAT_PATH)/uniphier_rotpk.S \
$(PLAT_PATH)/uniphier_tbbr.c
diff --git a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c
index 4f58b683c..4bbb2595c 100644
--- a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c
+++ b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c
@@ -4,16 +4,24 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <errno.h>
+
#include <platform_def.h>
#include <common/bl_common.h>
-#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <plat/common/platform.h>
#include "../uniphier.h"
+static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN;
+
void tsp_early_platform_setup(void)
{
- uniphier_console_setup();
+ uniphier_soc = uniphier_get_soc_id();
+ if (uniphier_soc == UNIPHIER_SOC_UNKNOWN)
+ plat_error_handler(-ENOTSUP);
+
+ uniphier_console_setup(uniphier_soc);
}
void tsp_platform_setup(void)
@@ -22,6 +30,5 @@ void tsp_platform_setup(void)
void tsp_plat_arch_setup(void)
{
- uniphier_mmap_setup();
- enable_mmu_el1(0);
+ uniphier_mmap_setup(uniphier_soc);
}
diff --git a/plat/socionext/uniphier/uniphier.h b/plat/socionext/uniphier/uniphier.h
index 729dc5caa..ee520ad23 100644
--- a/plat/socionext/uniphier/uniphier.h
+++ b/plat/socionext/uniphier/uniphier.h
@@ -25,7 +25,8 @@ unsigned int uniphier_get_boot_device(unsigned int soc);
#define UNIPHIER_BOOT_DEVICE_EMMC 0
#define UNIPHIER_BOOT_DEVICE_NAND 1
#define UNIPHIER_BOOT_DEVICE_NOR 2
-#define UNIPHIER_BOOT_DEVICE_USB 3
+#define UNIPHIER_BOOT_DEVICE_SD 3
+#define UNIPHIER_BOOT_DEVICE_USB 4
#define UNIPHIER_BOOT_DEVICE_RSV 0xffffffff
unsigned int uniphier_get_boot_master(unsigned int soc);
@@ -34,11 +35,13 @@ unsigned int uniphier_get_boot_master(unsigned int soc);
#define UNIPHIER_BOOT_MASTER_SCP 1
#define UNIPHIER_BOOT_MASTER_EXT 2
-void uniphier_console_setup(void);
+void uniphier_console_setup(unsigned int soc);
struct io_block_dev_spec;
-int uniphier_emmc_init(struct io_block_dev_spec **block_dev_spec);
-int uniphier_nand_init(struct io_block_dev_spec **block_dev_spec);
+int uniphier_emmc_init(unsigned int soc,
+ struct io_block_dev_spec **block_dev_spec);
+int uniphier_nand_init(unsigned int soc,
+ struct io_block_dev_spec **block_dev_spec);
int uniphier_usb_init(unsigned int soc,
struct io_block_dev_spec **block_dev_spec);
@@ -54,7 +57,7 @@ void uniphier_scp_open_com(void);
void uniphier_scp_system_off(void);
void uniphier_scp_system_reset(void);
-void uniphier_mmap_setup(void);
+void uniphier_mmap_setup(unsigned int soc);
void uniphier_cci_init(unsigned int soc);
void uniphier_cci_enable(void);
@@ -66,6 +69,8 @@ void uniphier_gic_cpuif_enable(void);
void uniphier_gic_cpuif_disable(void);
void uniphier_gic_pcpu_init(void);
+void uniphier_psci_init(unsigned int soc);
+
unsigned int uniphier_calc_core_pos(u_register_t mpidr);
#endif /* UNIPHIER_H */
diff --git a/plat/socionext/uniphier/uniphier_bl2_setup.c b/plat/socionext/uniphier/uniphier_bl2_setup.c
index 11d837cf4..4524610c0 100644
--- a/plat/socionext/uniphier/uniphier_bl2_setup.c
+++ b/plat/socionext/uniphier/uniphier_bl2_setup.c
@@ -21,43 +21,40 @@
#include "uniphier.h"
-#define UNIPHIER_IMAGE_BUF_OFFSET 0x04300000UL
-#define UNIPHIER_IMAGE_BUF_SIZE 0x00100000UL
+#define UNIPHIER_IMAGE_BUF_OFFSET 0x03800000UL
+#define UNIPHIER_IMAGE_BUF_SIZE 0x00800000UL
static uintptr_t uniphier_mem_base = UNIPHIER_MEM_BASE;
+static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN;
static int uniphier_bl2_kick_scp;
void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
u_register_t x2, u_register_t x3)
{
- uniphier_console_setup();
+ uniphier_soc = uniphier_get_soc_id();
+ if (uniphier_soc == UNIPHIER_SOC_UNKNOWN)
+ plat_error_handler(-ENOTSUP);
+
+ uniphier_console_setup(uniphier_soc);
}
void bl2_el3_plat_arch_setup(void)
{
- unsigned int soc;
int skip_scp = 0;
int ret;
- uniphier_mmap_setup();
- enable_mmu_el3(0);
+ uniphier_mmap_setup(uniphier_soc);
/* add relocation offset (run-time-address - link-address) */
uniphier_mem_base += BL_CODE_BASE - BL2_BASE;
- soc = uniphier_get_soc_id();
- if (soc == UNIPHIER_SOC_UNKNOWN) {
- ERROR("unsupported SoC\n");
- plat_error_handler(-ENOTSUP);
- }
-
- ret = uniphier_io_setup(soc, uniphier_mem_base);
+ ret = uniphier_io_setup(uniphier_soc, uniphier_mem_base);
if (ret) {
ERROR("failed to setup io devices\n");
plat_error_handler(ret);
}
- switch (uniphier_get_boot_master(soc)) {
+ switch (uniphier_get_boot_master(uniphier_soc)) {
case UNIPHIER_BOOT_MASTER_THIS:
INFO("Booting from this SoC\n");
skip_scp = 1;
diff --git a/plat/socionext/uniphier/uniphier_bl31_setup.c b/plat/socionext/uniphier/uniphier_bl31_setup.c
index 47f2378bc..c2baebde9 100644
--- a/plat/socionext/uniphier/uniphier_bl31_setup.c
+++ b/plat/socionext/uniphier/uniphier_bl31_setup.c
@@ -14,13 +14,13 @@
#include <common/debug.h>
#include <drivers/console.h>
#include <lib/mmio.h>
-#include <lib/xlat_tables/xlat_mmu_helpers.h>
#include <plat/common/platform.h>
#include "uniphier.h"
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
+static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN;
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
{
@@ -37,7 +37,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
bl_params_node_t *bl_params = ((bl_params_t *)from_bl2)->head;
- uniphier_console_setup();
+ uniphier_soc = uniphier_get_soc_id();
+ if (uniphier_soc == UNIPHIER_SOC_UNKNOWN)
+ plat_error_handler(-ENOTSUP);
+
+ uniphier_console_setup(uniphier_soc);
while (bl_params) {
if (bl_params->image_id == BL32_IMAGE_ID)
@@ -53,32 +57,33 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
panic();
}
-#define UNIPHIER_SYS_CNTCTL_BASE 0x60E00000
+static const uintptr_t uniphier_cntctl_base[] = {
+ [UNIPHIER_SOC_LD11] = 0x60e00000,
+ [UNIPHIER_SOC_LD20] = 0x60e00000,
+ [UNIPHIER_SOC_PXS3] = 0x60e00000,
+};
void bl31_platform_setup(void)
{
- unsigned int soc;
+ uintptr_t cntctl_base;
- soc = uniphier_get_soc_id();
- if (soc == UNIPHIER_SOC_UNKNOWN) {
- ERROR("unsupported SoC\n");
- plat_error_handler(-ENOTSUP);
- }
-
- uniphier_cci_init(soc);
+ uniphier_cci_init(uniphier_soc);
uniphier_cci_enable();
/* Initialize the GIC driver, cpu and distributor interfaces */
- uniphier_gic_driver_init(soc);
+ uniphier_gic_driver_init(uniphier_soc);
uniphier_gic_init();
+ assert(uniphier_soc < ARRAY_SIZE(uniphier_cntctl_base));
+ cntctl_base = uniphier_cntctl_base[uniphier_soc];
+
/* Enable and initialize the System level generic timer */
- mmio_write_32(UNIPHIER_SYS_CNTCTL_BASE + CNTCR_OFF,
- CNTCR_FCREQ(0U) | CNTCR_EN);
+ mmio_write_32(cntctl_base + CNTCR_OFF, CNTCR_FCREQ(0U) | CNTCR_EN);
+
+ uniphier_psci_init(uniphier_soc);
}
void bl31_plat_arch_setup(void)
{
- uniphier_mmap_setup();
- enable_mmu_el3(0);
+ uniphier_mmap_setup(uniphier_soc);
}
diff --git a/plat/socionext/uniphier/uniphier_boot_device.c b/plat/socionext/uniphier/uniphier_boot_device.c
index 462c0859c..36a9908be 100644
--- a/plat/socionext/uniphier/uniphier_boot_device.c
+++ b/plat/socionext/uniphier/uniphier_boot_device.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,22 +13,29 @@
#include "uniphier.h"
-#define UNIPHIER_PINMON0 0x5f900100
-#define UNIPHIER_PINMON2 0x5f900108
+#define UNIPHIER_PINMON0 0x0
+#define UNIPHIER_PINMON2 0x8
-static int uniphier_ld11_is_usb_boot(uint32_t pinmon)
+static const uintptr_t uniphier_pinmon_base[] = {
+ [UNIPHIER_SOC_LD11] = 0x5f900100,
+ [UNIPHIER_SOC_LD20] = 0x5f900100,
+ [UNIPHIER_SOC_PXS3] = 0x5f900100,
+};
+
+static bool uniphier_ld11_is_usb_boot(uint32_t pinmon)
{
return !!(~pinmon & 0x00000080);
}
-static int uniphier_ld20_is_usb_boot(uint32_t pinmon)
+static bool uniphier_ld20_is_usb_boot(uint32_t pinmon)
{
return !!(~pinmon & 0x00000780);
}
-static int uniphier_pxs3_is_usb_boot(uint32_t pinmon)
+static bool uniphier_pxs3_is_usb_boot(uint32_t pinmon)
{
- uint32_t pinmon2 = mmio_read_32(UNIPHIER_PINMON2);
+ uintptr_t pinmon_base = uniphier_pinmon_base[UNIPHIER_SOC_PXS3];
+ uint32_t pinmon2 = mmio_read_32(pinmon_base + UNIPHIER_PINMON2);
return !!(pinmon2 & BIT(31));
}
@@ -106,20 +113,25 @@ static unsigned int uniphier_pxs3_get_boot_device(uint32_t pinmon)
}
struct uniphier_boot_device_info {
- int (*is_usb_boot)(uint32_t pinmon);
+ bool have_boot_swap;
+ bool (*is_sd_boot)(uint32_t pinmon);
+ bool (*is_usb_boot)(uint32_t pinmon);
unsigned int (*get_boot_device)(uint32_t pinmon);
};
static const struct uniphier_boot_device_info uniphier_boot_device_info[] = {
[UNIPHIER_SOC_LD11] = {
+ .have_boot_swap = true,
.is_usb_boot = uniphier_ld11_is_usb_boot,
.get_boot_device = uniphier_ld11_get_boot_device,
},
[UNIPHIER_SOC_LD20] = {
+ .have_boot_swap = true,
.is_usb_boot = uniphier_ld20_is_usb_boot,
.get_boot_device = uniphier_ld11_get_boot_device,
},
[UNIPHIER_SOC_PXS3] = {
+ .have_boot_swap = true,
.is_usb_boot = uniphier_pxs3_is_usb_boot,
.get_boot_device = uniphier_pxs3_get_boot_device,
},
@@ -128,17 +140,24 @@ static const struct uniphier_boot_device_info uniphier_boot_device_info[] = {
unsigned int uniphier_get_boot_device(unsigned int soc)
{
const struct uniphier_boot_device_info *info;
+ uintptr_t pinmon_base;
uint32_t pinmon;
assert(soc < ARRAY_SIZE(uniphier_boot_device_info));
info = &uniphier_boot_device_info[soc];
- pinmon = mmio_read_32(UNIPHIER_PINMON0);
+ assert(soc < ARRAY_SIZE(uniphier_boot_device_info));
+ pinmon_base = uniphier_pinmon_base[soc];
+
+ pinmon = mmio_read_32(pinmon_base + UNIPHIER_PINMON0);
- if (!(pinmon & BIT(29)))
+ if (info->have_boot_swap && !(pinmon & BIT(29)))
return UNIPHIER_BOOT_DEVICE_NOR;
- if (info->is_usb_boot(pinmon))
+ if (info->is_sd_boot && info->is_sd_boot(pinmon))
+ return UNIPHIER_BOOT_DEVICE_SD;
+
+ if (info->is_usb_boot && info->is_usb_boot(pinmon))
return UNIPHIER_BOOT_DEVICE_USB;
return info->get_boot_device(pinmon);
@@ -155,7 +174,12 @@ unsigned int uniphier_get_boot_master(unsigned int soc)
assert(soc < ARRAY_SIZE(uniphier_have_onchip_scp));
if (uniphier_have_onchip_scp[soc]) {
- if (mmio_read_32(UNIPHIER_PINMON0) & BIT(27))
+ uintptr_t pinmon_base;
+
+ assert(soc < ARRAY_SIZE(uniphier_boot_device_info));
+ pinmon_base = uniphier_pinmon_base[soc];
+
+ if (mmio_read_32(pinmon_base + UNIPHIER_PINMON0) & BIT(27))
return UNIPHIER_BOOT_MASTER_THIS;
else
return UNIPHIER_BOOT_MASTER_SCP;
diff --git a/plat/socionext/uniphier/uniphier_console.S b/plat/socionext/uniphier/uniphier_console.S
index 1113c6e81..48927f414 100644
--- a/plat/socionext/uniphier/uniphier_console.S
+++ b/plat/socionext/uniphier/uniphier_console.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,7 +17,7 @@
*/
.globl uniphier_console_putc
func uniphier_console_putc
- ldr x1, [x1, #CONSOLE_T_DRVDATA]
+ ldr x1, [x1, #CONSOLE_T_BASE]
/* Wait until the transmitter FIFO gets empty */
0: ldr w2, [x1, #UNIPHIER_UART_LSR]
@@ -36,7 +36,7 @@ endfunc uniphier_console_putc
*/
.globl uniphier_console_getc
func uniphier_console_getc
- ldr x0, [x0, #CONSOLE_T_DRVDATA]
+ ldr x0, [x0, #CONSOLE_T_BASE]
ldr w1, [x0, #UNIPHIER_UART_LSR]
tbz w1, #UNIPHIER_UART_LSR_DR_BIT, 0f
@@ -55,12 +55,11 @@ endfunc uniphier_console_getc
*/
.global uniphier_console_flush
func uniphier_console_flush
- ldr x0, [x0, #CONSOLE_T_DRVDATA]
+ ldr x0, [x0, #CONSOLE_T_BASE]
/* wait until the transmitter gets empty */
0: ldr w1, [x0, #UNIPHIER_UART_LSR]
tbz w1, #UNIPHIER_UART_LSR_TEMT_BIT, 0b
- mov w0, #0
ret
endfunc uniphier_console_flush
diff --git a/plat/socionext/uniphier/uniphier_console_setup.c b/plat/socionext/uniphier/uniphier_console_setup.c
index 64ee79714..9fda26e93 100644
--- a/plat/socionext/uniphier/uniphier_console_setup.c
+++ b/plat/socionext/uniphier/uniphier_console_setup.c
@@ -1,9 +1,11 @@
/*
- * Copyright (c) 2019, Socionext Inc. All rights reserved.
+ * Copyright (c) 2019-2020, Socionext Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+
#include <drivers/console.h>
#include <errno.h>
#include <lib/mmio.h>
@@ -12,44 +14,46 @@
#include "uniphier.h"
#include "uniphier_console.h"
-#define UNIPHIER_UART_BASE 0x54006800
-#define UNIPHIER_UART_END 0x54006c00
#define UNIPHIER_UART_OFFSET 0x100
-
-struct uniphier_console {
- struct console console;
- uintptr_t base;
-};
+#define UNIPHIER_UART_NR_PORTS 4
/* These callbacks are implemented in assembly to use crash_console_helpers.S */
int uniphier_console_putc(int character, struct console *console);
int uniphier_console_getc(struct console *console);
-int uniphier_console_flush(struct console *console);
+void uniphier_console_flush(struct console *console);
-static struct uniphier_console uniphier_console = {
- .console = {
- .flags = CONSOLE_FLAG_BOOT |
+static console_t uniphier_console = {
+ .flags = CONSOLE_FLAG_BOOT |
#if DEBUG
- CONSOLE_FLAG_RUNTIME |
+ CONSOLE_FLAG_RUNTIME |
#endif
- CONSOLE_FLAG_CRASH |
- CONSOLE_FLAG_TRANSLATE_CRLF,
- .putc = uniphier_console_putc,
- .getc = uniphier_console_getc,
- .flush = uniphier_console_flush,
- },
+ CONSOLE_FLAG_CRASH |
+ CONSOLE_FLAG_TRANSLATE_CRLF,
+ .putc = uniphier_console_putc,
+ .getc = uniphier_console_getc,
+ .flush = uniphier_console_flush,
+};
+
+static const uintptr_t uniphier_uart_base[] = {
+ [UNIPHIER_SOC_LD11] = 0x54006800,
+ [UNIPHIER_SOC_LD20] = 0x54006800,
+ [UNIPHIER_SOC_PXS3] = 0x54006800,
};
/*
* There are 4 UART ports available on this platform. By default, we want to
* use the same one as used in the previous firmware stage.
*/
-static uintptr_t uniphier_console_get_base(void)
+static uintptr_t uniphier_console_get_base(unsigned int soc)
{
- uintptr_t base = UNIPHIER_UART_BASE;
+ uintptr_t base, end;
uint32_t div;
- while (base < UNIPHIER_UART_END) {
+ assert(soc < ARRAY_SIZE(uniphier_uart_base));
+ base = uniphier_uart_base[soc];
+ end = base + UNIPHIER_UART_OFFSET * UNIPHIER_UART_NR_PORTS;
+
+ while (base < end) {
div = mmio_read_32(base + UNIPHIER_UART_DLR);
if (div)
return base;
@@ -66,16 +70,16 @@ static void uniphier_console_init(uintptr_t base)
UNIPHIER_UART_LCR_WLEN8 << 8);
}
-void uniphier_console_setup(void)
+void uniphier_console_setup(unsigned int soc)
{
uintptr_t base;
- base = uniphier_console_get_base();
+ base = uniphier_console_get_base(soc);
if (!base)
plat_error_handler(-EINVAL);
uniphier_console.base = base;
- console_register(&uniphier_console.console);
+ console_register(&uniphier_console);
/*
* The hardware might be still printing characters queued up in the
diff --git a/plat/socionext/uniphier/uniphier_emmc.c b/plat/socionext/uniphier/uniphier_emmc.c
index d666ba781..b3d23cbed 100644
--- a/plat/socionext/uniphier/uniphier_emmc.c
+++ b/plat/socionext/uniphier/uniphier_emmc.c
@@ -87,7 +87,12 @@ struct uniphier_mmc_cmd {
unsigned int is_data;
};
-static int uniphier_emmc_block_addressing;
+struct uniphier_emmc_host {
+ uintptr_t base;
+ bool is_block_addressing;
+};
+
+static struct uniphier_emmc_host uniphier_emmc_host;
static int uniphier_emmc_send_cmd(uintptr_t host_base,
struct uniphier_mmc_cmd *cmd)
@@ -157,7 +162,8 @@ static int uniphier_emmc_switch_part(uintptr_t host_base, int part_num)
return uniphier_emmc_send_cmd(host_base, &cmd);
}
-static int uniphier_emmc_is_over_2gb(uintptr_t host_base)
+static int uniphier_emmc_check_device_size(uintptr_t host_base,
+ bool *is_block_addressing)
{
struct uniphier_mmc_cmd cmd = {0};
uint32_t csd40, csd72; /* CSD[71:40], CSD[103:72] */
@@ -174,7 +180,10 @@ static int uniphier_emmc_is_over_2gb(uintptr_t host_base)
csd40 = mmio_read_32(host_base + SDHCI_RESPONSE + 4);
csd72 = mmio_read_32(host_base + SDHCI_RESPONSE + 8);
- return !(~csd40 & 0xffc00380) && !(~csd72 & 0x3);
+ /* C_SIZE == 0xfff && C_SIZE_MULT == 0x7 ? */
+ *is_block_addressing = !(~csd40 & 0xffc00380) && !(~csd72 & 0x3);
+
+ return 0;
}
static int uniphier_emmc_load_image(uintptr_t host_base,
@@ -210,15 +219,15 @@ static int uniphier_emmc_load_image(uintptr_t host_base,
static size_t uniphier_emmc_read(int lba, uintptr_t buf, size_t size)
{
- uintptr_t host_base = 0x5a000200;
int ret;
inv_dcache_range(buf, size);
- if (!uniphier_emmc_block_addressing)
+ if (!uniphier_emmc_host.is_block_addressing)
lba *= 512;
- ret = uniphier_emmc_load_image(host_base, lba, buf, size / 512);
+ ret = uniphier_emmc_load_image(uniphier_emmc_host.base,
+ lba, buf, size / 512);
inv_dcache_range(buf, size);
@@ -232,10 +241,10 @@ static struct io_block_dev_spec uniphier_emmc_dev_spec = {
.block_size = 512,
};
-static int uniphier_emmc_hw_init(void)
+static int uniphier_emmc_hw_init(struct uniphier_emmc_host *host)
{
- uintptr_t host_base = 0x5a000200;
struct uniphier_mmc_cmd cmd = {0};
+ uintptr_t host_base = uniphier_emmc_host.base;
int ret;
/*
@@ -253,12 +262,11 @@ static int uniphier_emmc_hw_init(void)
while (mmio_read_8(host_base + SDHCI_SOFTWARE_RESET))
;
- ret = uniphier_emmc_is_over_2gb(host_base);
- if (ret < 0)
+ ret = uniphier_emmc_check_device_size(host_base,
+ &uniphier_emmc_host.is_block_addressing);
+ if (ret)
return ret;
- uniphier_emmc_block_addressing = ret;
-
cmd.cmdarg = UNIPHIER_EMMC_RCA << 16;
/* select card again */
@@ -274,11 +282,23 @@ static int uniphier_emmc_hw_init(void)
return 0;
}
-int uniphier_emmc_init(struct io_block_dev_spec **block_dev_spec)
+static const uintptr_t uniphier_emmc_base[] = {
+ [UNIPHIER_SOC_LD11] = 0x5a000200,
+ [UNIPHIER_SOC_LD20] = 0x5a000200,
+ [UNIPHIER_SOC_PXS3] = 0x5a000200,
+};
+
+int uniphier_emmc_init(unsigned int soc,
+ struct io_block_dev_spec **block_dev_spec)
{
int ret;
- ret = uniphier_emmc_hw_init();
+ assert(soc < ARRAY_SIZE(uniphier_emmc_base));
+ uniphier_emmc_host.base = uniphier_emmc_base[soc];
+ if (uniphier_emmc_host.base == 0UL)
+ return -ENOTSUP;
+
+ ret = uniphier_emmc_hw_init(&uniphier_emmc_host);
if (ret)
return ret;
diff --git a/plat/socionext/uniphier/uniphier_image_desc.c b/plat/socionext/uniphier/uniphier_image_desc.c
index 8c232ba31..dd62d1ebb 100644
--- a/plat/socionext/uniphier/uniphier_image_desc.c
+++ b/plat/socionext/uniphier/uniphier_image_desc.c
@@ -14,9 +14,9 @@
#include "uniphier.h"
#define UNIPHIER_BL33_OFFSET 0x04000000UL
-#define UNIPHIER_BL33_MAX_SIZE 0x00100000UL
+#define UNIPHIER_BL33_MAX_SIZE 0x00800000UL
-#define UNIPHIER_SCP_OFFSET 0x04100000UL
+#define UNIPHIER_SCP_OFFSET 0x04800000UL
#define UNIPHIER_SCP_MAX_SIZE 0x00020000UL
static struct bl_mem_params_node uniphier_image_descs[] = {
diff --git a/plat/socionext/uniphier/uniphier_io_storage.c b/plat/socionext/uniphier/uniphier_io_storage.c
index 89c8718b4..92e15b09a 100644
--- a/plat/socionext/uniphier/uniphier_io_storage.c
+++ b/plat/socionext/uniphier/uniphier_io_storage.c
@@ -21,13 +21,12 @@
#include "uniphier.h"
#define UNIPHIER_ROM_REGION_BASE 0x00000000ULL
-#define UNIPHIER_ROM_REGION_SIZE 0x10000000ULL
+#define UNIPHIER_ROM_REGION_SIZE 0x04000000ULL
-#define UNIPHIER_OCM_REGION_BASE 0x30000000ULL
#define UNIPHIER_OCM_REGION_SIZE 0x00040000ULL
-#define UNIPHIER_BLOCK_BUF_OFFSET 0x04200000UL
-#define UNIPHIER_BLOCK_BUF_SIZE 0x00100000UL
+#define UNIPHIER_BLOCK_BUF_OFFSET 0x03000000UL
+#define UNIPHIER_BLOCK_BUF_SIZE 0x00800000UL
static const io_dev_connector_t *uniphier_fip_dev_con;
static uintptr_t uniphier_fip_dev_handle;
@@ -249,24 +248,24 @@ static int uniphier_io_fip_setup(void)
return io_dev_open(uniphier_fip_dev_con, 0, &uniphier_fip_dev_handle);
}
-static int uniphier_io_emmc_setup(unsigned int soc_id, size_t buffer_offset)
+static int uniphier_io_emmc_setup(unsigned int soc, size_t buffer_offset)
{
struct io_block_dev_spec *block_dev_spec;
int ret;
- ret = uniphier_emmc_init(&block_dev_spec);
+ ret = uniphier_emmc_init(soc, &block_dev_spec);
if (ret)
return ret;
return uniphier_io_block_setup(0x20000, block_dev_spec, buffer_offset);
}
-static int uniphier_io_nand_setup(unsigned int soc_id, size_t buffer_offset)
+static int uniphier_io_nand_setup(unsigned int soc, size_t buffer_offset)
{
struct io_block_dev_spec *block_dev_spec;
int ret;
- ret = uniphier_nand_init(&block_dev_spec);
+ ret = uniphier_nand_init(soc, &block_dev_spec);
if (ret)
return ret;
@@ -278,12 +277,20 @@ static int uniphier_io_nor_setup(unsigned int soc_id, size_t buffer_offset)
return uniphier_io_memmap_setup(0x70000);
}
-static int uniphier_io_usb_setup(unsigned int soc_id, size_t buffer_offset)
+static const uintptr_t uniphier_ocm_base[] = {
+ [UNIPHIER_SOC_LD11] = 0x30000000,
+ [UNIPHIER_SOC_LD20] = 0x30000000,
+ [UNIPHIER_SOC_PXS3] = 0x30000000,
+};
+
+static int uniphier_io_rom_api_setup(unsigned int soc)
{
- struct io_block_dev_spec *block_dev_spec;
+ uintptr_t ocm_base;
int ret;
- /* use ROM API for loading images from USB storage */
+ assert(soc < ARRAY_SIZE(uniphier_ocm_base));
+ ocm_base = uniphier_ocm_base[soc];
+
ret = mmap_add_dynamic_region(UNIPHIER_ROM_REGION_BASE,
UNIPHIER_ROM_REGION_BASE,
UNIPHIER_ROM_REGION_SIZE,
@@ -296,14 +303,26 @@ static int uniphier_io_usb_setup(unsigned int soc_id, size_t buffer_offset)
* load functions provided by the ROM use this memory region as a work
* area, but do not cater to cache coherency.
*/
- ret = mmap_add_dynamic_region(UNIPHIER_OCM_REGION_BASE,
- UNIPHIER_OCM_REGION_BASE,
+ ret = mmap_add_dynamic_region(ocm_base, ocm_base,
UNIPHIER_OCM_REGION_SIZE,
MT_DEVICE | MT_RW | MT_SECURE);
if (ret)
return ret;
- ret = uniphier_usb_init(soc_id, &block_dev_spec);
+ return 0;
+}
+
+static int uniphier_io_usb_setup(unsigned int soc, size_t buffer_offset)
+{
+ struct io_block_dev_spec *block_dev_spec;
+ int ret;
+
+ /* use ROM API for loading images from USB storage */
+ ret = uniphier_io_rom_api_setup(soc);
+ if (ret)
+ return ret;
+
+ ret = uniphier_usb_init(soc, &block_dev_spec);
if (ret)
return ret;
diff --git a/plat/socionext/uniphier/uniphier_nand.c b/plat/socionext/uniphier/uniphier_nand.c
index 3925177ed..71cb96c0a 100644
--- a/plat/socionext/uniphier/uniphier_nand.c
+++ b/plat/socionext/uniphier/uniphier_nand.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
#include <stdint.h>
#include <platform_def.h>
@@ -237,8 +238,7 @@ static int uniphier_nand_hw_init(struct uniphier_nand *nand)
for (i = 0; i < ARRAY_SIZE(nand->bbt); i++)
nand->bbt[i] = UNIPHIER_NAND_BBT_UNKNOWN;
- nand->host_base = 0x68000000;
- nand->reg_base = 0x68100000;
+ nand->reg_base = nand->host_base + 0x100000;
nand->pages_per_block =
mmio_read_32(nand->reg_base + DENALI_PAGES_PER_BLOCK);
@@ -255,10 +255,22 @@ static int uniphier_nand_hw_init(struct uniphier_nand *nand)
return 0;
}
-int uniphier_nand_init(struct io_block_dev_spec **block_dev_spec)
+static const uintptr_t uniphier_nand_base[] = {
+ [UNIPHIER_SOC_LD11] = 0x68000000,
+ [UNIPHIER_SOC_LD20] = 0x68000000,
+ [UNIPHIER_SOC_PXS3] = 0x68000000,
+};
+
+int uniphier_nand_init(unsigned int soc,
+ struct io_block_dev_spec **block_dev_spec)
{
int ret;
+ assert(soc < ARRAY_SIZE(uniphier_nand_base));
+ uniphier_nand.host_base = uniphier_nand_base[soc];
+ if (!uniphier_nand.host_base)
+ return -ENOTSUP;
+
ret = uniphier_nand_hw_init(&uniphier_nand);
if (ret)
return ret;
diff --git a/plat/socionext/uniphier/uniphier_psci.c b/plat/socionext/uniphier/uniphier_psci.c
index 2acc87440..a371705b1 100644
--- a/plat/socionext/uniphier/uniphier_psci.c
+++ b/plat/socionext/uniphier/uniphier_psci.c
@@ -1,9 +1,11 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+
#include <arch_helpers.h>
#include <common/debug.h>
#include <errno.h>
@@ -12,15 +14,18 @@
#include "uniphier.h"
-#define UNIPHIER_ROM_RSV0 0x59801200
+#define UNIPHIER_ROM_RSV0 0x0
-#define UNIPHIER_SLFRSTSEL 0x61843010
+#define UNIPHIER_SLFRSTSEL 0x10
#define UNIPHIER_SLFRSTSEL_MASK GENMASK(1, 0)
-#define UNIPHIER_SLFRSTCTL 0x61843014
+#define UNIPHIER_SLFRSTCTL 0x14
#define UNIPHIER_SLFRSTCTL_RST BIT(0)
#define MPIDR_AFFINITY_INVALID ((u_register_t)-1)
+static uintptr_t uniphier_rom_rsv_base;
+static uintptr_t uniphier_slfrst_base;
+
uintptr_t uniphier_sec_entrypoint;
void uniphier_warmboot_entrypoint(void);
@@ -34,7 +39,7 @@ static int uniphier_psci_pwr_domain_on(u_register_t mpidr)
flush_dcache_range((uint64_t)&uniphier_holding_pen_release,
sizeof(uniphier_holding_pen_release));
- mmio_write_64(UNIPHIER_ROM_RSV0,
+ mmio_write_64(uniphier_rom_rsv_base + UNIPHIER_ROM_RSV0,
(uint64_t)&uniphier_warmboot_entrypoint);
sev();
@@ -71,8 +76,10 @@ static void __dead2 uniphier_psci_pwr_domain_pwr_down_wfi(
static void uniphier_self_system_reset(void)
{
- mmio_clrbits_32(UNIPHIER_SLFRSTSEL, UNIPHIER_SLFRSTSEL_MASK);
- mmio_setbits_32(UNIPHIER_SLFRSTCTL, UNIPHIER_SLFRSTCTL_RST);
+ mmio_clrbits_32(uniphier_slfrst_base + UNIPHIER_SLFRSTSEL,
+ UNIPHIER_SLFRSTSEL_MASK);
+ mmio_setbits_32(uniphier_slfrst_base + UNIPHIER_SLFRSTCTL,
+ UNIPHIER_SLFRSTCTL_RST);
}
static void __dead2 uniphier_psci_system_off(void)
@@ -114,13 +121,40 @@ static const struct plat_psci_ops uniphier_psci_ops = {
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const struct plat_psci_ops **psci_ops)
{
- unsigned int soc;
+ uniphier_sec_entrypoint = sec_entrypoint;
+ flush_dcache_range((uint64_t)&uniphier_sec_entrypoint,
+ sizeof(uniphier_sec_entrypoint));
- soc = uniphier_get_soc_id();
- if (soc == UNIPHIER_SOC_UNKNOWN) {
- ERROR("unsupported SoC\n");
- return -ENOTSUP;
- }
+ *psci_ops = &uniphier_psci_ops;
+
+ return 0;
+}
+
+struct uniphier_psci_ctrl_base {
+ uintptr_t rom_rsv_base;
+ uintptr_t slfrst_base;
+};
+
+static const struct uniphier_psci_ctrl_base uniphier_psci_ctrl_base[] = {
+ [UNIPHIER_SOC_LD11] = {
+ .rom_rsv_base = 0x59801200,
+ .slfrst_base = 0x61843000,
+ },
+ [UNIPHIER_SOC_LD20] = {
+ .rom_rsv_base = 0x59801200,
+ .slfrst_base = 0x61843000,
+ },
+ [UNIPHIER_SOC_PXS3] = {
+ .rom_rsv_base = 0x59801200,
+ .slfrst_base = 0x61843000,
+ },
+};
+
+void uniphier_psci_init(unsigned int soc)
+{
+ assert(soc < ARRAY_SIZE(uniphier_psci_ctrl_base));
+ uniphier_rom_rsv_base = uniphier_psci_ctrl_base[soc].rom_rsv_base;
+ uniphier_slfrst_base = uniphier_psci_ctrl_base[soc].slfrst_base;
if (uniphier_get_boot_master(soc) == UNIPHIER_BOOT_MASTER_SCP) {
uniphier_psci_scp_mode = uniphier_scp_is_running();
@@ -130,12 +164,4 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
if (uniphier_psci_scp_mode)
uniphier_scp_open_com();
}
-
- uniphier_sec_entrypoint = sec_entrypoint;
- flush_dcache_range((uint64_t)&uniphier_sec_entrypoint,
- sizeof(uniphier_sec_entrypoint));
-
- *psci_ops = &uniphier_psci_ops;
-
- return 0;
}
diff --git a/plat/socionext/uniphier/uniphier_soc_info.c b/plat/socionext/uniphier/uniphier_soc_info.c
index 377532deb..0e7a2d11a 100644
--- a/plat/socionext/uniphier/uniphier_soc_info.c
+++ b/plat/socionext/uniphier/uniphier_soc_info.c
@@ -4,18 +4,25 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <common/bl_common.h>
#include <lib/mmio.h>
#include "uniphier.h"
-#define UNIPHIER_REVISION 0x5f800000
+#define UNIPHIER_REVISION 0x5f800000UL
+#define UNIPHIER_REVISION_NEW 0x1f800000UL
static unsigned int uniphier_get_revision_field(unsigned int mask,
unsigned int shift)
{
- uint32_t revision = mmio_read_32(UNIPHIER_REVISION);
+ uintptr_t reg;
- return (revision >> shift) & mask;
+ if (BL_CODE_BASE >= 0x80000000UL)
+ reg = UNIPHIER_REVISION;
+ else
+ reg = UNIPHIER_REVISION_NEW;
+
+ return (mmio_read_32(reg) >> shift) & mask;
}
unsigned int uniphier_get_soc_type(void)
diff --git a/plat/socionext/uniphier/uniphier_xlat_setup.c b/plat/socionext/uniphier/uniphier_xlat_setup.c
index 18d2f9e93..5043f4b59 100644
--- a/plat/socionext/uniphier/uniphier_xlat_setup.c
+++ b/plat/socionext/uniphier/uniphier_xlat_setup.c
@@ -4,15 +4,37 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+
#include <platform_def.h>
#include <common/debug.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include "uniphier.h"
+
+struct uniphier_reg_region {
+ uintptr_t base;
+ size_t size;
+};
-#define UNIPHIER_REG_REGION_BASE 0x50000000ULL
-#define UNIPHIER_REG_REGION_SIZE 0x20000000ULL
+static const struct uniphier_reg_region uniphier_reg_region[] = {
+ [UNIPHIER_SOC_LD11] = {
+ .base = 0x50000000UL,
+ .size = 0x20000000UL,
+ },
+ [UNIPHIER_SOC_LD20] = {
+ .base = 0x50000000UL,
+ .size = 0x20000000UL,
+ },
+ [UNIPHIER_SOC_PXS3] = {
+ .base = 0x50000000UL,
+ .size = 0x20000000UL,
+ },
+};
-void uniphier_mmap_setup(void)
+void uniphier_mmap_setup(unsigned int soc)
{
VERBOSE("Trusted RAM seen by this BL image: %p - %p\n",
(void *)BL_CODE_BASE, (void *)BL_END);
@@ -35,9 +57,25 @@ void uniphier_mmap_setup(void)
MT_DEVICE | MT_RW | MT_SECURE);
/* register region */
- mmap_add_region(UNIPHIER_REG_REGION_BASE, UNIPHIER_REG_REGION_BASE,
- UNIPHIER_REG_REGION_SIZE,
+ assert(soc < ARRAY_SIZE(uniphier_reg_region));
+ mmap_add_region(uniphier_reg_region[soc].base,
+ uniphier_reg_region[soc].base,
+ uniphier_reg_region[soc].size,
MT_DEVICE | MT_RW | MT_SECURE);
init_xlat_tables();
+
+ enable_mmu(0);
+
+#if PLAT_RO_XLAT_TABLES
+ {
+ int ret;
+
+ ret = xlat_make_tables_readonly();
+ if (ret) {
+ ERROR("Failed to make translation tables read-only.");
+ plat_error_handler(ret);
+ }
+ }
+#endif
}
diff --git a/plat/ti/k3/board/generic/board.mk b/plat/ti/k3/board/generic/board.mk
index a34221454..ef74cd64c 100644
--- a/plat/ti/k3/board/generic/board.mk
+++ b/plat/ti/k3/board/generic/board.mk
@@ -13,5 +13,12 @@ $(eval $(call add_define,PRELOADED_BL33_BASE))
K3_HW_CONFIG_BASE ?= 0x82000000
$(eval $(call add_define,K3_HW_CONFIG_BASE))
+# Define sec_proxy usage as the full prioritized communication scheme
+K3_SEC_PROXY_LITE := 0
+$(eval $(call add_define,K3_SEC_PROXY_LITE))
+
+# System coherency is managed in hardware
+USE_COHERENT_MEM := 1
+
PLAT_INCLUDES += \
-Iplat/ti/k3/board/generic/include \
diff --git a/plat/ti/k3/board/lite/board.mk b/plat/ti/k3/board/lite/board.mk
new file mode 100644
index 000000000..76246be47
--- /dev/null
+++ b/plat/ti/k3/board/lite/board.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL32_BASE ?= 0x9e800000
+$(eval $(call add_define,BL32_BASE))
+
+PRELOADED_BL33_BASE ?= 0x80080000
+$(eval $(call add_define,PRELOADED_BL33_BASE))
+
+K3_HW_CONFIG_BASE ?= 0x82000000
+$(eval $(call add_define,K3_HW_CONFIG_BASE))
+
+# Define sec_proxy usage as the lite version
+K3_SEC_PROXY_LITE := 1
+$(eval $(call add_define,K3_SEC_PROXY_LITE))
+
+# We dont have system level coherency capability
+USE_COHERENT_MEM := 0
+
+PLAT_INCLUDES += \
+ -Iplat/ti/k3/board/lite/include \
diff --git a/plat/ti/k3/board/lite/include/board_def.h b/plat/ti/k3/board/lite/include/board_def.h
new file mode 100644
index 000000000..7c7ea62c1
--- /dev/null
+++ b/plat/ti/k3/board/lite/include/board_def.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BOARD_DEF_H
+#define BOARD_DEF_H
+
+#include <lib/utils_def.h>
+
+/* The ports must be in order and contiguous */
+#define K3_CLUSTER0_CORE_COUNT U(4)
+#define K3_CLUSTER1_CORE_COUNT U(0)
+#define K3_CLUSTER2_CORE_COUNT U(0)
+#define K3_CLUSTER3_CORE_COUNT U(0)
+
+/*
+ * This RAM will be used for the bootloader including code, bss, and stacks.
+ * It may need to be increased if BL31 grows in size.
+ * Current computation assumes data structures necessary for GIC and ARM for
+ * a single cluster of 4 processor.
+ */
+#define SEC_SRAM_BASE 0x70000000 /* Base of SRAM */
+#define SEC_SRAM_SIZE 0x0001a000 /* 104k */
+
+#define PLAT_MAX_OFF_STATE U(2)
+#define PLAT_MAX_RET_STATE U(1)
+
+#define PLAT_PROC_START_ID 32
+#define PLAT_PROC_DEVICE_START_ID 135
+#define PLAT_CLUSTER_DEVICE_START_ID 134
+
+#endif /* BOARD_DEF_H */
diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
index ee1eecf78..a0bfdee36 100644
--- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
+++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
@@ -97,11 +97,16 @@ static struct k3_sec_proxy_mbox spm = {
.data_end_offset = 0x3C,
},
.threads = {
+#if !K3_SEC_PROXY_LITE
SP_THREAD(SP_NOTIFY),
SP_THREAD(SP_RESPONSE),
SP_THREAD(SP_HIGH_PRIORITY),
SP_THREAD(SP_LOW_PRIORITY),
SP_THREAD(SP_NOTIFY_RESP),
+#else
+ SP_THREAD(SP_RESPONSE),
+ SP_THREAD(SP_HIGH_PRIORITY),
+#endif /* K3_SEC_PROXY_LITE */
},
};
@@ -261,9 +266,14 @@ int k3_sec_proxy_send(enum k3_sec_proxy_chan_id id, const struct k3_sec_proxy_ms
/*
* 'data_reg' indicates next register to write. If we did not already
* write on tx complete reg(last reg), we must do so for transmit
+ * In addition, we also need to make sure all intermediate data
+ * registers(if any required), are reset to 0 for TISCI backward
+ * compatibility to be maintained.
*/
- if (data_reg <= spm.desc.data_end_offset)
- mmio_write_32(spt->data + spm.desc.data_end_offset, 0);
+ while (data_reg <= spm.desc.data_end_offset) {
+ mmio_write_32(spt->data + data_reg, 0);
+ data_reg += sizeof(uint32_t);
+ }
VERBOSE("Message successfully sent on thread %s\n", spt->name);
diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
index 6c4f5dfff..f4b0b4bac 100644
--- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
+++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
@@ -16,13 +16,28 @@
* enum k3_sec_proxy_chan_id - Secure Proxy thread IDs
*
* These the available IDs used in k3_sec_proxy_{send,recv}()
+ * There are two schemes we use:
+ * * if K3_SEC_PROXY_LITE = 1, we just have two threads to talk
+ * * if K3_SEC_PROXY_LITE = 0, we have the full fledged
+ * communication scheme available.
*/
enum k3_sec_proxy_chan_id {
+#if !K3_SEC_PROXY_LITE
SP_NOTIFY = 0,
SP_RESPONSE,
SP_HIGH_PRIORITY,
SP_LOW_PRIORITY,
SP_NOTIFY_RESP,
+#else
+ SP_RESPONSE = 8,
+ /*
+ * Note: TISCI documentation indicates "low priority", but in reality
+ * with a single thread, there is no low or high priority.. This usage
+ * is more appropriate for TF-A since we can reduce the churn as a
+ * result.
+ */
+ SP_HIGH_PRIORITY,
+#endif /* K3_SEC_PROXY_LITE */
};
/**
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
index e390efee6..2c3313c43 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -1163,6 +1163,7 @@ int ti_sci_core_reboot(void)
ERROR("Message alloc failed (%d)\n", ret);
return ret;
}
+ req.domain = TI_SCI_DOMAIN_FULL_SOC_RESET;
ret = ti_sci_do_xfer(&xfer);
if (ret) {
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
index 2d23f9a9c..310bf459d 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
@@ -95,12 +95,15 @@ struct ti_sci_msg_resp_version {
/**
* struct ti_sci_msg_req_reboot - Reboot the SoC
* @hdr: Generic Header
+ * @domain: Domain to be reset, 0 for full SoC reboot
*
* Request type is TI_SCI_MSG_SYS_RESET, responded with a generic
* ACK/NACK message.
*/
struct ti_sci_msg_req_reboot {
struct ti_sci_msg_hdr hdr;
+#define TI_SCI_DOMAIN_FULL_SOC_RESET 0x0
+ uint8_t domain;
} __packed;
/**
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index 8bd736292..ac4e60e4d 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -13,6 +13,7 @@
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <common/debug.h>
+#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <k3_console.h>
@@ -23,6 +24,7 @@
const mmap_region_t plat_k3_mmap[] = {
MAP_REGION_FLAT(K3_USART_BASE, K3_USART_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(K3_GIC_BASE, K3_GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(K3_GTC_BASE, K3_GTC_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SEC_PROXY_RT_BASE, SEC_PROXY_RT_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
@@ -127,6 +129,38 @@ void platform_mem_init(void)
unsigned int plat_get_syscnt_freq2(void)
{
+ uint32_t gtc_freq;
+ uint32_t gtc_ctrl;
+
+ /* Lets try and provide basic diagnostics - cost is low */
+ gtc_ctrl = mmio_read_32(K3_GTC_BASE + K3_GTC_CNTCR_OFFSET);
+ /* Did the bootloader fail to enable timer and OS guys are confused? */
+ if ((gtc_ctrl & K3_GTC_CNTCR_EN_MASK) == 0U) {
+ ERROR("GTC is disabled! Timekeeping broken. Fix Bootloader\n");
+ }
+ /*
+ * If debug will not pause time, we will have issues like
+ * drivers timing out while debugging, in cases of OS like Linux,
+ * RCU stall errors, which can be hard to differentiate vs real issues.
+ */
+ if ((gtc_ctrl & K3_GTC_CNTCR_HDBG_MASK) == 0U) {
+ WARN("GTC: Debug access doesn't stop time. Fix Bootloader\n");
+ }
+
+ gtc_freq = mmio_read_32(K3_GTC_BASE + K3_GTC_CNTFID0_OFFSET);
+ /* Many older bootloaders may have missed programming FID0 register */
+ if (gtc_freq != 0U) {
+ return gtc_freq;
+ }
+
+ /*
+ * We could have just warned about this, but this can have serious
+ * hard to debug side effects if we are NOT sure what the actual
+ * frequency is. Lets make sure people don't miss this.
+ */
+ ERROR("GTC_CNTFID0 is 0! Assuming %d Hz. Fix Bootloader\n",
+ SYS_COUNTER_FREQ_IN_TICKS);
+
return SYS_COUNTER_FREQ_IN_TICKS;
}
diff --git a/plat/ti/k3/common/k3_console.c b/plat/ti/k3/common/k3_console.c
index ba0ddacec..8c44c17e2 100644
--- a/plat/ti/k3/common/k3_console.c
+++ b/plat/ti/k3/common/k3_console.c
@@ -13,7 +13,7 @@
void bl31_console_setup(void)
{
- static console_16550_t console;
+ static console_t console;
/* Initialize the console to provide early debug support */
console_16550_register(K3_USART_BASE, K3_USART_CLK_SPEED,
diff --git a/plat/ti/k3/common/k3_helpers.S b/plat/ti/k3/common/k3_helpers.S
index 3afca591e..f4f7d18ea 100644
--- a/plat/ti/k3/common/k3_helpers.S
+++ b/plat/ti/k3/common/k3_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -141,10 +141,10 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush()
+ * void plat_crash_console_flush()
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : x0, x1
* ---------------------------------------------
*/
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index d6ed7667e..050074007 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -203,6 +203,13 @@ void k3_pwr_domain_on_finish(const psci_power_state_t *target_state)
k3_gic_cpuif_enable();
}
+static void __dead2 k3_system_off(void)
+{
+ ERROR("System Off: operation not handled.\n");
+ while (true)
+ wfi();
+}
+
static void __dead2 k3_system_reset(void)
{
/* Send the system reset request to system firmware */
@@ -232,6 +239,7 @@ static const plat_psci_ops_t k3_plat_psci_ops = {
.pwr_domain_on = k3_pwr_domain_on,
.pwr_domain_off = k3_pwr_domain_off,
.pwr_domain_on_finish = k3_pwr_domain_on_finish,
+ .system_off = k3_system_off,
.system_reset = k3_system_reset,
.validate_power_state = k3_validate_power_state,
.validate_ns_entrypoint = k3_validate_ns_entrypoint
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index 7956497ae..ab7366b7e 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -11,9 +11,8 @@ COLD_BOOT_SINGLE_CPU := 1
# We can choose where a core starts executing
PROGRAMMABLE_RESET_ADDRESS:= 1
-# System coherency is managed in hardware
+# ARM coherency is managed in hardware
WARMBOOT_ENABLE_DCACHE_EARLY := 1
-USE_COHERENT_MEM := 1
# A53 erratum for SoC. (enable them all)
ERRATA_A53_826319 := 1
@@ -21,9 +20,11 @@ ERRATA_A53_835769 := 1
ERRATA_A53_836870 := 1
ERRATA_A53_843419 := 1
ERRATA_A53_855873 := 1
+ERRATA_A53_1530924 := 1
# A72 Erratum for SoC
ERRATA_A72_859971 := 1
+ERRATA_A72_1319367 := 1
CRASH_REPORTING := 1
HANDLE_EA_EL3_FIRST := 1
@@ -37,6 +38,9 @@ ENABLE_PIE := 1
TI_16550_MDR_QUIRK := 1
$(eval $(call add_define,TI_16550_MDR_QUIRK))
+K3_USART := 0
+$(eval $(call add_define,K3_USART))
+
# Allow customizing the UART baud rate
K3_USART_BAUD := 115200
$(eval $(call add_define,K3_USART_BAUD))
@@ -53,10 +57,11 @@ K3_CONSOLE_SOURCES += \
drivers/ti/uart/aarch64/16550_console.S \
${PLAT_PATH}/common/k3_console.c \
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
K3_GIC_SOURCES += \
- drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/v3/gicv3_helpers.c \
+ ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
${PLAT_PATH}/common/k3_gicv3.c \
diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h
index 690c68e5c..f12fb0b21 100644
--- a/plat/ti/k3/include/platform_def.h
+++ b/plat/ti/k3/include/platform_def.h
@@ -91,7 +91,7 @@
/* Platform default console definitions */
#ifndef K3_USART_BASE
-#define K3_USART_BASE 0x02800000
+#define K3_USART_BASE (0x02800000 + 0x10000 * K3_USART)
#endif
/* USART has a default size for address space */
@@ -150,15 +150,33 @@
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_EDGE)
+
+#define K3_GTC_BASE 0x00A90000
+/* We just need 20 byte offset, but simpler to just remap the 64K page in */
+#define K3_GTC_SIZE 0x10000
+#define K3_GTC_CNTCR_OFFSET 0x00
+#define K3_GTC_CNTCR_EN_MASK 0x01
+#define K3_GTC_CNTCR_HDBG_MASK 0x02
+#define K3_GTC_CNTFID0_OFFSET 0x20
+
#define K3_GIC_BASE 0x01800000
#define K3_GIC_SIZE 0x200000
+#if !K3_SEC_PROXY_LITE
#define SEC_PROXY_DATA_BASE 0x32C00000
#define SEC_PROXY_DATA_SIZE 0x80000
#define SEC_PROXY_SCFG_BASE 0x32800000
#define SEC_PROXY_SCFG_SIZE 0x80000
#define SEC_PROXY_RT_BASE 0x32400000
#define SEC_PROXY_RT_SIZE 0x80000
+#else
+#define SEC_PROXY_DATA_BASE 0x4D000000
+#define SEC_PROXY_DATA_SIZE 0x80000
+#define SEC_PROXY_SCFG_BASE 0x4A400000
+#define SEC_PROXY_SCFG_SIZE 0x80000
+#define SEC_PROXY_RT_BASE 0x4A600000
+#define SEC_PROXY_RT_SIZE 0x80000
+#endif /* K3_SEC_PROXY_LITE */
#define SEC_PROXY_TIMEOUT_US 1000000
#define SEC_PROXY_MAX_MESSAGE_SIZE 56
diff --git a/plat/ti/k3/platform.mk b/plat/ti/k3/platform.mk
index 65d5cc2a4..2de21aa7b 100644
--- a/plat/ti/k3/platform.mk
+++ b/plat/ti/k3/platform.mk
@@ -11,4 +11,4 @@ include ${PLAT_PATH}/common/plat_common.mk
include ${PLAT_PATH}/board/${TARGET_BOARD}/board.mk
# modify BUILD_PLAT to point to board specific build directory
-BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_BOARD}/${BUILD_TYPE}
+BUILD_PLAT := $(abspath ${BUILD_BASE})/${PLAT}/${TARGET_BOARD}/${BUILD_TYPE}
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index c83d25b0d..5dcceaea2 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -18,6 +18,8 @@
#include "pm_ipi.h"
+#define ERROR_CODE_MASK 0xFFFFU
+
DEFINE_BAKERY_LOCK(pm_secure_lock);
/**
@@ -230,7 +232,7 @@ enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
if (ret != PM_RET_SUCCESS)
goto unlock;
- ret = pm_ipi_buff_read(proc, value, count);
+ ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, value, count));
unlock:
bakery_lock_release(&pm_secure_lock);
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index a5cf05e9a..5e870ff5f 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -22,7 +22,7 @@
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
-static console_pl011_t versal_runtime_console;
+static console_t versal_runtime_console;
/*
* Return a pointer to the 'entry_point_info' structure of the next image for
@@ -34,8 +34,9 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
{
assert(sec_state_is_valid(type));
- if (type == NON_SECURE)
+ if (type == NON_SECURE) {
return &bl33_image_ep_info;
+ }
return &bl32_image_ep_info;
}
@@ -68,10 +69,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
VERSAL_UART_CLOCK,
VERSAL_UART_BAUDRATE,
&versal_runtime_console);
- if (rc == 0)
+ if (rc == 0) {
panic();
+ }
- console_set_scope(&versal_runtime_console.console, CONSOLE_FLAG_BOOT |
+ console_set_scope(&versal_runtime_console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME);
/* Initialize the platform config for future decision making */
@@ -97,7 +99,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
enum fsbl_handoff ret = fsbl_atf_handover(&bl32_image_ep_info,
&bl33_image_ep_info,
atf_handoff_addr);
- if (ret == FSBL_HANDOFF_NO_STRUCT) {
+ if (ret == FSBL_HANDOFF_NO_STRUCT || ret == FSBL_HANDOFF_INVAL_STRUCT) {
bl31_set_default_config();
} else if (ret != FSBL_HANDOFF_SUCCESS) {
panic();
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index 9a9b7c017..810e5d877 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -7,6 +7,7 @@
#ifndef VERSAL_DEF_H
#define VERSAL_DEF_H
+#include <plat/arm/common/smccc_def.h>
#include <plat/common/common_def.h>
/* List all consoles */
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index 39550858a..fda42dfda 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -59,7 +59,9 @@ static void versal_pwr_domain_suspend(const psci_power_state_t *target_state)
plat_versal_gic_cpuif_disable();
- plat_versal_gic_save();
+ if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
+ plat_versal_gic_save();
+ }
state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
@@ -99,11 +101,9 @@ static void versal_pwr_domain_suspend_finish(
/* APU was turned off, so restore GIC context */
if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
plat_versal_gic_resume();
- plat_versal_gic_cpuif_enable();
- } else {
- plat_versal_gic_cpuif_enable();
- plat_versal_gic_pcpu_init();
}
+
+ plat_versal_gic_cpuif_enable();
}
void versal_pwr_domain_on_finish(const psci_power_state_t *target_state)
diff --git a/plat/xilinx/versal/plat_versal.c b/plat/xilinx/versal/plat_versal.c
index a080a76a9..107eae66b 100644
--- a/plat/xilinx/versal/plat_versal.c
+++ b/plat/xilinx/versal/plat_versal.c
@@ -9,11 +9,13 @@
int plat_core_pos_by_mpidr(u_register_t mpidr)
{
- if (mpidr & MPIDR_CLUSTER_MASK)
+ if (mpidr & MPIDR_CLUSTER_MASK) {
return -1;
+ }
- if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT)
+ if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT) {
return -1;
+ }
return versal_calc_core_pos(mpidr);
}
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 1e231cce8..16396dc18 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -43,15 +43,14 @@ PLAT_INCLUDES := -Iinclude/plat/arm/common/ \
-Iplat/xilinx/versal/include/ \
-Iplat/xilinx/versal/pm_service/
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
lib/xlat_tables/aarch64/xlat_tables.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
- drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v3/arm_gicv3_common.c \
- drivers/arm/gic/v3/gic500.c \
- drivers/arm/gic/v3/gicv3_main.c \
- drivers/arm/gic/v3/gicv3_helpers.c \
+ ${GICV3_SOURCES} \
drivers/arm/pl011/aarch64/pl011_console.S \
plat/common/aarch64/crash_console_helpers.S \
plat/arm/common/arm_cci.c \
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index dbe94e624..3cdd9d051 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,6 +14,7 @@
#include <plat/common/platform.h>
#include "pm_api_sys.h"
#include "pm_client.h"
+#include "pm_defs.h"
/*********************************************************************
* Target module IDs macros
@@ -84,6 +85,22 @@ enum pm_ret_status pm_get_api_version(unsigned int *version)
}
/**
+ * pm_init_finalize() - Call to notify PMC PM firmware that master has power
+ * management enabled and that it has finished its
+ * initialization
+ *
+ * @return Status returned by the PMU firmware
+ */
+enum pm_ret_status pm_init_finalize(void)
+{
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMU */
+ PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, PM_INIT_FINALIZE);
+ return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
+
+/**
* pm_self_suspend() - PM call for processor to suspend itself
* @nid Node id of the processor or subsystem
* @latency Requested maximum wakeup latency (not supported)
@@ -554,6 +571,22 @@ enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent)
return pm_ipi_send_sync(primary_proc, payload, parent, 1);
}
+/**
+ * pm_clock_get_rate() - Get the rate value for the clock
+ * @clk_id Clock ID
+ * @rate: Buffer to store clock rate value
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate)
+{
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMC */
+ PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_GETRATE, clk_id);
+
+ return pm_ipi_send_sync(primary_proc, payload, clk_rate, 2);
+}
/**
* pm_pll_set_param() - Set PLL parameter
@@ -689,12 +722,31 @@ enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype)
enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t *data)
{
+ uint32_t ret;
+ uint32_t version;
uint32_t payload[PAYLOAD_ARG_CNT];
+ uint32_t fw_api_version;
/* Send request to the PMC */
PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_QUERY_DATA, qid, arg1,
arg2, arg3);
- return pm_ipi_send_sync(primary_proc, payload, data, 4);
+
+ ret = pm_feature_check(PM_QUERY_DATA, &version);
+ if (PM_RET_SUCCESS == ret) {
+ fw_api_version = version & 0xFFFF ;
+ if ((2U == fw_api_version) &&
+ ((XPM_QID_CLOCK_GET_NAME == qid) ||
+ (XPM_QID_PINCTRL_GET_FUNCTION_NAME == qid))) {
+ ret = pm_ipi_send_sync(primary_proc, payload, data, 8);
+ ret = data[0];
+ data[0] = data[1];
+ data[1] = data[2];
+ data[2] = data[3];
+ } else {
+ ret = pm_ipi_send_sync(primary_proc, payload, data, 4);
+ }
+ }
+ return ret;
}
/**
* pm_api_ioctl() - PM IOCTL API for device control and configs
@@ -780,7 +832,7 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version)
switch (api_id) {
case PM_GET_CALLBACK_DATA:
case PM_GET_TRUSTZONE_VERSION:
- case PM_INIT_FINALIZE:
+ case PM_LOAD_PDI:
*version = (PM_API_BASE_VERSION << 16);
return PM_RET_SUCCESS;
case PM_GET_API_VERSION:
@@ -798,6 +850,7 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version)
case PM_SET_REQUIREMENT:
case PM_RESET_ASSERT:
case PM_RESET_GET_STATUS:
+ case PM_GET_CHIPID:
case PM_PINCTRL_REQUEST:
case PM_PINCTRL_RELEASE:
case PM_PINCTRL_GET_FUNCTION:
@@ -805,7 +858,6 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version)
case PM_PINCTRL_CONFIG_PARAM_GET:
case PM_PINCTRL_CONFIG_PARAM_SET:
case PM_IOCTL:
- case PM_QUERY_DATA:
case PM_CLOCK_ENABLE:
case PM_CLOCK_DISABLE:
case PM_CLOCK_GETSTATE:
@@ -813,16 +865,20 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version)
case PM_CLOCK_GETDIVIDER:
case PM_CLOCK_SETPARENT:
case PM_CLOCK_GETPARENT:
+ case PM_CLOCK_GETRATE:
case PM_PLL_SET_PARAMETER:
case PM_PLL_GET_PARAMETER:
case PM_PLL_SET_MODE:
case PM_PLL_GET_MODE:
case PM_FEATURE_CHECK:
+ case PM_INIT_FINALIZE:
+ case PM_SET_MAX_LATENCY:
+ case PM_REGISTER_NOTIFIER:
*version = (PM_API_BASE_VERSION << 16);
break;
- case PM_LOAD_PDI:
- *version = (PM_API_BASE_VERSION << 16);
- return PM_RET_SUCCESS;
+ case PM_QUERY_DATA:
+ *version = (PM_API_QUERY_DATA_VERSION << 16);
+ break;
default:
*version = 0U;
return PM_RET_ERROR_NOFEATURE;
@@ -883,3 +939,45 @@ enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
device_id, type);
return pm_ipi_send_sync(primary_proc, payload, result, 1);
}
+
+/**
+ * pm_set_max_latency() - PM call to change in the maximum wake-up latency
+ * requirements for a specific device currently
+ * used by that CPU.
+ * @device_id Device ID
+ * @latency Latency value
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency)
+{
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMC */
+ PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_SET_MAX_LATENCY,
+ device_id, latency);
+
+ return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
+
+/**
+ * pm_register_notifier() - PM call to register a subsystem to be notified
+ * about the device event
+ * @device_id Device ID for the Node to which the event is related
+ * @event Event in question
+ * @wake Wake subsystem upon capturing the event if value 1
+ * @enable Enable the registration for value 1, disable for value 0
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
+ uint32_t wake, uint32_t enable)
+{
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMC */
+ PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_REGISTER_NOTIFIER,
+ device_id, event, wake, enable);
+
+ return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h
index 4de592a2f..84867b638 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.h
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,6 +15,7 @@
**********************************************************/
enum pm_ret_status pm_get_api_version(unsigned int *version);
+enum pm_ret_status pm_init_finalize(void);
enum pm_ret_status pm_self_suspend(uint32_t nid,
unsigned int latency,
unsigned int state,
@@ -52,6 +53,7 @@ enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider);
enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider);
enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent);
enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent);
+enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate);
enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
uint32_t value);
enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
@@ -72,4 +74,7 @@ enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
enum pm_opchar_type type,
uint32_t *result);
+enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency);
+enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
+ uint32_t wake, uint32_t enable);
#endif /* PM_API_SYS_H */
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 5b47838e9..9ab921ee7 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -113,8 +113,9 @@ static enum pm_device_node_idx irq_to_pm_node_idx(unsigned int irq)
/**
* pm_client_set_wakeup_sources - Set all devices with enabled interrupts as
* wake sources in the LibPM.
+ * @node_id: Node id of processor
*/
-static void pm_client_set_wakeup_sources(void)
+static void pm_client_set_wakeup_sources(uint32_t node_id)
{
uint32_t reg_num;
uint32_t device_id;
@@ -147,7 +148,7 @@ static void pm_client_set_wakeup_sources(void)
(!pm_wakeup_nodes_set[node_idx])) {
/* Get device ID from node index */
device_id = PERIPH_DEVID(node_idx);
- ret = pm_set_wakeup_source(XPM_DEVID_ACPU_0,
+ ret = pm_set_wakeup_source(node_id,
device_id, 1);
pm_wakeup_nodes_set[node_idx] = !ret;
}
@@ -167,7 +168,7 @@ void pm_client_suspend(const struct pm_proc *proc, unsigned int state)
bakery_lock_get(&pm_client_secure_lock);
if (state == PM_STATE_SUSPEND_TO_RAM)
- pm_client_set_wakeup_sources();
+ pm_client_set_wakeup_sources(proc->node_id);
/* Set powerdown request */
mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) |
diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h
index 966b00bb5..793f75009 100644
--- a/plat/xilinx/versal/pm_service/pm_defs.h
+++ b/plat/xilinx/versal/pm_service/pm_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -39,10 +39,13 @@
/* PM API Versions */
#define PM_API_BASE_VERSION 1U
+#define PM_API_QUERY_DATA_VERSION 2U
+
/* PM API ids */
#define PM_GET_API_VERSION 1U
#define PM_GET_DEVICE_STATUS 3U
#define PM_GET_OP_CHARACTERISTIC 4U
+#define PM_REGISTER_NOTIFIER 5U
#define PM_REQ_SUSPEND 6U
#define PM_SELF_SUSPEND 7U
#define PM_FORCE_POWERDOWN 8U
@@ -53,6 +56,7 @@
#define PM_REQUEST_DEVICE 13U
#define PM_RELEASE_DEVICE 14U
#define PM_SET_REQUIREMENT 15U
+#define PM_SET_MAX_LATENCY 16U
#define PM_RESET_ASSERT 17U
#define PM_RESET_GET_STATUS 18U
#define PM_INIT_FINALIZE 21U
@@ -163,4 +167,25 @@ enum pm_ret_status {
PM_RET_ERROR_TIMEOUT = 2006,
PM_RET_ERROR_NODE_USED = 2007
};
+
+/**
+ * Qids
+ */
+enum pm_query_id {
+ XPM_QID_INVALID,
+ XPM_QID_CLOCK_GET_NAME,
+ XPM_QID_CLOCK_GET_TOPOLOGY,
+ XPM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS,
+ XPM_QID_CLOCK_GET_MUXSOURCES,
+ XPM_QID_CLOCK_GET_ATTRIBUTES,
+ XPM_QID_PINCTRL_GET_NUM_PINS,
+ XPM_QID_PINCTRL_GET_NUM_FUNCTIONS,
+ XPM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS,
+ XPM_QID_PINCTRL_GET_FUNCTION_NAME,
+ XPM_QID_PINCTRL_GET_FUNCTION_GROUPS,
+ XPM_QID_PINCTRL_GET_PIN_GROUPS,
+ XPM_QID_CLOCK_GET_NUM_CLOCKS,
+ XPM_QID_CLOCK_GET_MAX_DIVISOR,
+ XPM_QID_PLD_GET_PARENT,
+};
#endif /* PM_DEFS_H */
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index a3a9f4316..2ed6d2701 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -159,13 +159,14 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
}
case PM_INIT_FINALIZE:
- SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS);
+ ret = pm_init_finalize();
+ SMC_RET1(handle, (uint64_t)ret);
case PM_GET_CALLBACK_DATA:
{
uint32_t result[4] = {0};
- pm_get_callbackdata(result, sizeof(result));
+ pm_get_callbackdata(result, ARRAY_SIZE(result));
SMC_RET2(handle,
(uint64_t)result[0] | ((uint64_t)result[1] << 32),
(uint64_t)result[2] | ((uint64_t)result[3] << 32));
@@ -214,14 +215,15 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
case PM_QUERY_DATA:
{
- uint32_t data[4] = { 0 };
+ uint32_t data[8] = { 0 };
ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], data);
+ pm_arg[3], data);
+
SMC_RET2(handle, (uint64_t)ret | ((uint64_t)data[0] << 32),
- (uint64_t)data[1] | ((uint64_t)data[2] << 32));
- }
+ (uint64_t)data[1] | ((uint64_t)data[2] << 32));
+ }
case PM_CLOCK_ENABLE:
ret = pm_clock_enable(pm_arg[0]);
SMC_RET1(handle, (uint64_t)ret);
@@ -262,6 +264,15 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
}
+ case PM_CLOCK_GETRATE:
+ {
+ uint32_t rate[2] = { 0 };
+
+ ret = pm_clock_get_rate(pm_arg[0], rate);
+ SMC_RET2(handle, (uint64_t)ret | ((uint64_t)rate[0] << 32),
+ rate[1]);
+ }
+
case PM_PLL_SET_PARAMETER:
ret = pm_pll_set_param(pm_arg[0], pm_arg[1], pm_arg[2]);
SMC_RET1(handle, (uint64_t)ret);
@@ -321,6 +332,18 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)result << 32));
}
+ case PM_SET_MAX_LATENCY:
+ {
+ ret = pm_set_max_latency(pm_arg[0], pm_arg[1]);
+ SMC_RET1(handle, (uint64_t)ret);
+ }
+
+ case PM_REGISTER_NOTIFIER:
+ {
+ ret = pm_register_notifier(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);
+ SMC_RET1(handle, (uint64_t)ret);
+ }
+
default:
WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S b/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
index beba66405..7eab337e9 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -106,10 +106,10 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
- * int plat_crash_console_flush()
+ * void plat_crash_console_flush()
* Function to force a write of all buffered
* data that hasn't been output.
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : r0
* ---------------------------------------------
*/
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 6e0e811d4..d4cd7f65b 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -32,8 +32,9 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
{
assert(sec_state_is_valid(type));
- if (type == NON_SECURE)
+ if (type == NON_SECURE) {
return &bl33_image_ep_info;
+ }
return &bl32_image_ep_info;
}
@@ -62,12 +63,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
{
uint64_t atf_handoff_addr;
/* Register the console to provide early debug support */
- static console_cdns_t bl31_boot_console;
+ static console_t bl31_boot_console;
(void)console_cdns_register(ZYNQMP_UART_BASE,
zynqmp_get_uart_clk(),
ZYNQMP_UART_BAUDRATE,
&bl31_boot_console);
- console_set_scope(&bl31_boot_console.console,
+ console_set_scope(&bl31_boot_console,
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT);
/* Initialize the platform config for future decision making */
@@ -99,14 +100,18 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
enum fsbl_handoff ret = fsbl_atf_handover(&bl32_image_ep_info,
&bl33_image_ep_info,
atf_handoff_addr);
- if (ret == FSBL_HANDOFF_NO_STRUCT)
+ if (ret == FSBL_HANDOFF_NO_STRUCT) {
bl31_set_default_config();
- else if (ret != FSBL_HANDOFF_SUCCESS)
+ } else if (ret != FSBL_HANDOFF_SUCCESS) {
panic();
+ }
+ }
+ if (bl32_image_ep_info.pc) {
+ VERBOSE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
+ }
+ if (bl33_image_ep_info.pc) {
+ VERBOSE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
}
-
- NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
- NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
}
/* Enable the test setup */
@@ -134,12 +139,14 @@ static interrupt_type_handler_t type_el3_interrupt_table[MAX_INTR_EL3];
int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
{
/* Validate 'handler' and 'id' parameters */
- if (!handler || id >= MAX_INTR_EL3)
+ if (!handler || id >= MAX_INTR_EL3) {
return -EINVAL;
+ }
/* Check if a handler has already been registered */
- if (type_el3_interrupt_table[id])
+ if (type_el3_interrupt_table[id]) {
return -EALREADY;
+ }
type_el3_interrupt_table[id] = handler;
@@ -154,8 +161,9 @@ static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
intr_id = plat_ic_get_pending_interrupt_id();
handler = type_el3_interrupt_table[intr_id];
- if (handler != NULL)
+ if (handler != NULL) {
handler(intr_id, flags, handle, cookie);
+ }
return 0;
}
@@ -178,8 +186,9 @@ void bl31_plat_runtime_setup(void)
set_interrupt_rm_flag(flags, NON_SECURE);
rc = register_interrupt_type_handler(INTR_TYPE_EL3,
rdo_el3_interrupt_handler, flags);
- if (rc)
+ if (rc) {
panic();
+ }
#endif
}
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 5d335d945..f47463000 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,7 @@
#ifndef ZYNQMP_DEF_H
#define ZYNQMP_DEF_H
+#include <plat/arm/common/smccc_def.h>
#include <plat/common/common_def.h>
#define ZYNQMP_CONSOLE_ID_cadence 1
@@ -340,12 +341,22 @@
#define PGGS_BASEADDR (0xFFD80050U)
#define PGGS_NUM_REGS U(4)
-/* Warm restart boot health status register and mask */
-#define PM_BOOT_HEALTH_STATUS_REG (GGS_BASEADDR + U(0x10))
+/* PMU GGS4 register 4 is used for warm restart boot health status */
+#define PMU_GLOBAL_GEN_STORAGE4 (GGS_BASEADDR + 0x10)
+/* Warm restart boot health status mask */
#define PM_BOOT_HEALTH_STATUS_MASK U(0x01)
+/* WDT restart scope shift and mask */
+#define RESTART_SCOPE_SHIFT (3)
+#define RESTART_SCOPE_MASK (0x3U << RESTART_SCOPE_SHIFT)
/*AFI registers */
#define AFIFM6_WRCTRL U(13)
#define FABRIC_WIDTH U(3)
+/* CSUDMA Module Base Address*/
+#define CSUDMA_BASE 0xFFC80000
+
+/* RSA-CORE Module Base Address*/
+#define RSA_CORE_BASE 0xFFCE0000
+
#endif /* ZYNQMP_DEF_H */
diff --git a/plat/xilinx/zynqmp/plat_zynqmp.c b/plat/xilinx/zynqmp/plat_zynqmp.c
index 906ce1b7f..58a52a3bf 100644
--- a/plat/xilinx/zynqmp/plat_zynqmp.c
+++ b/plat/xilinx/zynqmp/plat_zynqmp.c
@@ -9,11 +9,13 @@
int plat_core_pos_by_mpidr(u_register_t mpidr)
{
- if (mpidr & MPIDR_CLUSTER_MASK)
+ if (mpidr & MPIDR_CLUSTER_MASK) {
return -1;
+ }
- if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT)
+ if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT) {
return -1;
+ }
return zynqmp_calc_core_pos(mpidr);
}
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 44f20f69f..1cd168f7d 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -59,13 +59,14 @@ PLAT_INCLUDES := -Iinclude/plat/arm/common/ \
-Iplat/xilinx/zynqmp/include/ \
-Iplat/xilinx/zynqmp/pm_service/ \
+# Include GICv2 driver files
+include drivers/arm/gic/v2/gicv2.mk
+
PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
lib/xlat_tables/aarch64/xlat_tables.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
- drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
+ ${GICV2_SOURCES} \
drivers/cadence/uart/aarch64/cdns_console.S \
plat/arm/common/arm_cci.c \
plat/arm/common/arm_common.c \
@@ -95,6 +96,8 @@ BL31_SOURCES += drivers/arm/cci/cci.c \
plat/xilinx/zynqmp/pm_service/pm_api_clock.c \
plat/xilinx/zynqmp/pm_service/pm_client.c
+BL31_CPPFLAGS += -fno-jump-tables
+
ifneq (${RESET_TO_BL31},1)
$(error "Using BL31 as the reset vector is only one option supported on ZynqMP. Please set RESET_TO_BL31 to 1.")
endif
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 852f92763..0cc517ec9 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -129,12 +129,26 @@
.div = NA_DIV, \
}
-#define GENERIC_DIV(id) \
+#define GENERIC_DIV1 \
{ \
- .type = TYPE_DIV##id, \
- .offset = PERIPH_DIV##id##_SHIFT, \
- .width = PERIPH_DIV##id##_WIDTH, \
+ .type = TYPE_DIV1, \
+ .offset = PERIPH_DIV1_SHIFT, \
+ .width = PERIPH_DIV1_WIDTH, \
+ .clkflags = CLK_SET_RATE_NO_REPARENT | \
+ CLK_IS_BASIC, \
+ .typeflags = CLK_DIVIDER_ONE_BASED | \
+ CLK_DIVIDER_ALLOW_ZERO, \
+ .mult = NA_MULT, \
+ .div = NA_DIV, \
+ }
+
+#define GENERIC_DIV2 \
+ { \
+ .type = TYPE_DIV2, \
+ .offset = PERIPH_DIV2_SHIFT, \
+ .width = PERIPH_DIV2_WIDTH, \
.clkflags = CLK_SET_RATE_NO_REPARENT | \
+ CLK_SET_RATE_PARENT | \
CLK_IS_BASIC, \
.typeflags = CLK_DIVIDER_ONE_BASED | \
CLK_DIVIDER_ALLOW_ZERO, \
@@ -340,25 +354,25 @@ static struct pm_clock_node acpu_nodes[] = {
static struct pm_clock_node generic_mux_div_nodes[] = {
GENERIC_MUX,
- GENERIC_DIV(1),
+ GENERIC_DIV1,
};
static struct pm_clock_node generic_mux_div_gate_nodes[] = {
GENERIC_MUX,
- GENERIC_DIV(1),
+ GENERIC_DIV1,
GENERIC_GATE,
};
static struct pm_clock_node generic_mux_div_unused_gate_nodes[] = {
GENERIC_MUX,
- GENERIC_DIV(1),
+ GENERIC_DIV1,
IGNORE_UNUSED_GATE,
};
static struct pm_clock_node generic_mux_div_div_gate_nodes[] = {
GENERIC_MUX,
- GENERIC_DIV(1),
- GENERIC_DIV(2),
+ GENERIC_DIV1,
+ GENERIC_DIV2,
GENERIC_GATE,
};
@@ -410,8 +424,8 @@ static struct pm_clock_node dp_audio_video_ref_nodes[] = {
static struct pm_clock_node usb_nodes[] = {
GENERIC_MUX,
- GENERIC_DIV(1),
- GENERIC_DIV(2),
+ GENERIC_DIV1,
+ GENERIC_DIV2,
{
.type = TYPE_GATE,
.offset = USB_GATE_SHIFT,
@@ -2432,10 +2446,11 @@ enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks)
*
* @return Returns success. In case of error, name data is 0.
*/
-enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name)
+void pm_api_clock_get_name(unsigned int clock_id, char *name)
{
if (clock_id == CLK_MAX)
- memcpy(name, END_OF_CLK, CLK_NAME_LEN);
+ memcpy(name, END_OF_CLK, sizeof(END_OF_CLK) > CLK_NAME_LEN ?
+ CLK_NAME_LEN : sizeof(END_OF_CLK));
else if (!pm_clock_valid(clock_id))
memset(name, 0, CLK_NAME_LEN);
else if (clock_id < CLK_MAX_OUTPUT_CLK)
@@ -2443,8 +2458,6 @@ enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name)
else
memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
CLK_NAME_LEN);
-
- return PM_RET_SUCCESS;
}
/**
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
index 301ed24b6..5efd63ff5 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -294,7 +294,7 @@ struct pm_pll *pm_clock_get_pll(enum clock_id clock_id);
struct pm_pll *pm_clock_get_pll_by_related_clk(enum clock_id clock_id);
uint8_t pm_clock_has_div(unsigned int clock_id, enum pm_clock_div_id div_id);
-enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name);
+void pm_api_clock_get_name(unsigned int clock_id, char *name);
enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks);
enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
unsigned int index,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index 60e80d907..f165fb022 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -282,17 +282,29 @@ static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
{
unsigned int shift;
enum pm_ret_status ret;
+ unsigned int val, mask;
- if (nid == NODE_SD_0)
+ if (nid == NODE_SD_0) {
shift = 0;
- else if (nid == NODE_SD_1)
+ mask = ZYNQMP_SD0_DLL_RST_MASK;
+ } else if (nid == NODE_SD_1) {
shift = ZYNQMP_SD_TAP_OFFSET;
- else
+ mask = ZYNQMP_SD1_DLL_RST_MASK;
+ } else {
return PM_RET_ERROR_ARGS;
+ }
- ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
- if (ret != PM_RET_SUCCESS)
+ ret = pm_mmio_read(ZYNQMP_SD_DLL_CTRL, &val);
+ if (ret != PM_RET_SUCCESS) {
return ret;
+ }
+
+ if ((val & mask) == 0) {
+ ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
+ if (ret != PM_RET_SUCCESS) {
+ return ret;
+ }
+ }
if (type == PM_TAPDELAY_INPUT) {
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
@@ -300,9 +312,15 @@ static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
(ZYNQMP_SD_ITAPCHGWIN << shift));
if (ret != PM_RET_SUCCESS)
goto reset_release;
- ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
- (ZYNQMP_SD_ITAPDLYENA_MASK << shift),
- (ZYNQMP_SD_ITAPDLYENA << shift));
+ if (value == 0)
+ ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
+ (ZYNQMP_SD_ITAPDLYENA_MASK <<
+ shift), 0);
+ else
+ ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
+ (ZYNQMP_SD_ITAPDLYENA_MASK <<
+ shift), (ZYNQMP_SD_ITAPDLYENA <<
+ shift));
if (ret != PM_RET_SUCCESS)
goto reset_release;
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
@@ -314,8 +332,7 @@ static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
(ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
} else if (type == PM_TAPDELAY_OUTPUT) {
ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
- (ZYNQMP_SD_OTAPDLYENA_MASK << shift),
- (ZYNQMP_SD_OTAPDLYENA << shift));
+ (ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
if (ret != PM_RET_SUCCESS)
goto reset_release;
ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
@@ -326,7 +343,10 @@ static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
}
reset_release:
- pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
+ if ((val & mask) == 0) {
+ (void)pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
+ }
+
return ret;
}
@@ -575,7 +595,7 @@ static enum pm_ret_status pm_ioctl_ulpi_reset(void)
*/
static enum pm_ret_status pm_ioctl_set_boot_health_status(unsigned int value)
{
- return pm_mmio_write(PM_BOOT_HEALTH_STATUS_REG,
+ return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4,
PM_BOOT_HEALTH_STATUS_MASK, value);
}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 4b8dfb614..9a6b497f3 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -19,39 +19,6 @@
#include "pm_common.h"
#include "pm_ipi.h"
-#define PINCTRL_FUNCTION_MASK U(0xFE)
-#define PINCTRL_VOLTAGE_STATUS_MASK U(0x01)
-#define NFUNCS_PER_PIN U(13)
-#define PINCTRL_NUM_MIOS U(78)
-#define MAX_PIN_PER_REG U(26)
-#define PINCTRL_BANK_ADDR_STEP U(28)
-
-#define PINCTRL_DRVSTRN0_REG_OFFSET U(0)
-#define PINCTRL_DRVSTRN1_REG_OFFSET U(4)
-#define PINCTRL_SCHCMOS_REG_OFFSET U(8)
-#define PINCTRL_PULLCTRL_REG_OFFSET U(12)
-#define PINCTRL_PULLSTAT_REG_OFFSET U(16)
-#define PINCTRL_SLEWCTRL_REG_OFFSET U(20)
-#define PINCTRL_VOLTAGE_STAT_REG_OFFSET U(24)
-
-#define IOU_SLCR_BANK1_CTRL5 U(0XFF180164)
-
-#define PINCTRL_CFG_ADDR_OFFSET(addr, reg, miopin) \
- ((addr) + 4 * PINCTRL_NUM_MIOS + PINCTRL_BANK_ADDR_STEP * \
- ((miopin) / MAX_PIN_PER_REG) + (reg))
-
-#define PINCTRL_PIN_OFFSET(_miopin) \
- ((_miopin) - (MAX_PIN_PER_REG * ((_miopin) / MAX_PIN_PER_REG)))
-
-#define PINCTRL_REGVAL_TO_PIN_CONFIG(_pin, _val) \
- (((_val) >> PINCTRL_PIN_OFFSET(_pin)) & 0x1)
-
-static uint8_t pm_pinctrl_mux[NFUNCS_PER_PIN] = {
- 0x02, 0x04, 0x08, 0x10, 0x18,
- 0x00, 0x20, 0x40, 0x60, 0x80,
- 0xA0, 0xC0, 0xE0
-};
-
struct pinctrl_function {
char name[FUNCTION_NAME_LEN];
uint16_t (*groups)[];
@@ -2604,18 +2571,13 @@ enum pm_ret_status pm_api_pinctrl_get_num_func_groups(unsigned int fid,
*
* This function is used by master to get name of function specified
* by given function ID.
- *
- * @return Returns success. In case of error, name data is 0.
*/
-enum pm_ret_status pm_api_pinctrl_get_function_name(unsigned int fid,
- char *name)
+void pm_api_pinctrl_get_function_name(unsigned int fid, char *name)
{
if (fid >= MAX_FUNCTION)
memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN);
else
memcpy(name, pinctrl_functions[fid].name, FUNCTION_NAME_LEN);
-
- return PM_RET_SUCCESS;
}
/**
@@ -2713,330 +2675,3 @@ enum pm_ret_status pm_api_pinctrl_get_pin_groups(unsigned int pin,
return PM_RET_SUCCESS;
}
-
-/**
- * pm_api_pinctrl_get_function() - Read function id set for the given pin
- * @pin Pin number
- * @nid Node ID of function currently set for given pin
- *
- * This function provides the function currently set for the given pin.
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_api_pinctrl_get_function(unsigned int pin,
- unsigned int *id)
-{
- unsigned int i = 0, j = 0;
- enum pm_ret_status ret = PM_RET_SUCCESS;
- unsigned int ctrlreg, val, gid;
- uint16_t *grps;
-
- ctrlreg = IOU_SLCR_BASEADDR + 4U * pin;
- ret = pm_mmio_read(ctrlreg, &val);
- if (ret != PM_RET_SUCCESS)
- return ret;
-
- val &= PINCTRL_FUNCTION_MASK;
-
- for (i = 0; i < NFUNCS_PER_PIN; i++)
- if (val == pm_pinctrl_mux[i])
- break;
-
- if (i == NFUNCS_PER_PIN)
- return PM_RET_ERROR_NOTSUPPORTED;
-
- gid = *(*zynqmp_pin_groups[pin].groups + i);
-
- for (i = 0; i < MAX_FUNCTION; i++) {
- grps = *pinctrl_functions[i].groups;
- if (grps == NULL)
- continue;
- if (val != pinctrl_functions[i].regval)
- continue;
-
- for (j = 0; grps[j] != (uint16_t)END_OF_GROUPS; j++) {
- if (gid == grps[j]) {
- *id = i;
- goto done;
- }
- }
- }
- if (i == MAX_FUNCTION)
- ret = PM_RET_ERROR_ARGS;
-done:
- return ret;
-}
-
-/**
- * pm_api_pinctrl_set_function() - Set function id set for the given pin
- * @pin Pin number
- * @nid Node ID of function to set for given pin
- *
- * This function provides the function currently set for the given pin.
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_api_pinctrl_set_function(unsigned int pin,
- unsigned int fid)
-{
- int i, j;
- unsigned int ctrlreg, val;
- uint16_t *pgrps, *fgrps;
-
- ctrlreg = IOU_SLCR_BASEADDR + 4U * pin;
- val = pinctrl_functions[fid].regval;
-
- for (i = 0; i < NFUNCS_PER_PIN; i++)
- if (val == pm_pinctrl_mux[i])
- break;
-
- if (i == NFUNCS_PER_PIN)
- return PM_RET_ERROR_NOTSUPPORTED;
-
- pgrps = *zynqmp_pin_groups[pin].groups;
- if (!pgrps)
- return PM_RET_ERROR_NOTSUPPORTED;
-
- fgrps = *pinctrl_functions[fid].groups;
- if (!fgrps)
- return PM_RET_ERROR_NOTSUPPORTED;
-
- for (i = 0; fgrps[i] != (uint16_t)END_OF_GROUPS; i++)
- for (j = 0; pgrps[j] != (uint16_t)END_OF_GROUPS; j++)
- if (fgrps[i] == pgrps[j])
- goto match;
-
- return PM_RET_ERROR_NOTSUPPORTED;
-
-match:
- return pm_mmio_write(ctrlreg, PINCTRL_FUNCTION_MASK, val);
-}
-
-/**
- * pm_api_pinctrl_set_config() - Set configuration parameter for given pin
- * @pin: Pin for which configuration is to be set
- * @param: Configuration parameter to be set
- * @value: Value to be set for configuration parameter
- *
- * This function sets value of requested configuration parameter for given pin.
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_api_pinctrl_set_config(unsigned int pin,
- unsigned int param,
- unsigned int value)
-{
- enum pm_ret_status ret;
- unsigned int ctrlreg, mask, val, offset;
-
- if (param >= PINCTRL_CONFIG_MAX)
- return PM_RET_ERROR_NOTSUPPORTED;
-
- if (pin >= PINCTRL_NUM_MIOS)
- return PM_RET_ERROR_ARGS;
-
- mask = 1 << PINCTRL_PIN_OFFSET(pin);
-
- switch (param) {
- case PINCTRL_CONFIG_SLEW_RATE:
- if (value != PINCTRL_SLEW_RATE_FAST &&
- value != PINCTRL_SLEW_RATE_SLOW)
- return PM_RET_ERROR_ARGS;
-
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_SLEWCTRL_REG_OFFSET,
- pin);
- val = value << PINCTRL_PIN_OFFSET(pin);
- ret = pm_mmio_write(ctrlreg, mask, val);
- break;
- case PINCTRL_CONFIG_BIAS_STATUS:
- if (value != PINCTRL_BIAS_ENABLE &&
- value != PINCTRL_BIAS_DISABLE)
- return PM_RET_ERROR_ARGS;
-
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_PULLSTAT_REG_OFFSET,
- pin);
-
- offset = PINCTRL_PIN_OFFSET(pin);
- if (ctrlreg == IOU_SLCR_BANK1_CTRL5)
- offset = (offset < 12U) ?
- (offset + 14U) : (offset - 12U);
-
- val = value << offset;
- mask = 1 << offset;
- ret = pm_mmio_write(ctrlreg, mask, val);
- break;
- case PINCTRL_CONFIG_PULL_CTRL:
-
- if (value != PINCTRL_BIAS_PULL_DOWN &&
- value != PINCTRL_BIAS_PULL_UP)
- return PM_RET_ERROR_ARGS;
-
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_PULLSTAT_REG_OFFSET,
- pin);
-
- offset = PINCTRL_PIN_OFFSET(pin);
- if (ctrlreg == IOU_SLCR_BANK1_CTRL5)
- offset = (offset < 12U) ?
- (offset + 14U) : (offset - 12U);
-
- val = PINCTRL_BIAS_ENABLE << offset;
- ret = pm_mmio_write(ctrlreg, 1 << offset, val);
- if (ret != PM_RET_SUCCESS)
- return ret;
-
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_PULLCTRL_REG_OFFSET,
- pin);
- val = value << PINCTRL_PIN_OFFSET(pin);
- ret = pm_mmio_write(ctrlreg, mask, val);
- break;
- case PINCTRL_CONFIG_SCHMITT_CMOS:
- if (value != PINCTRL_INPUT_TYPE_CMOS &&
- value != PINCTRL_INPUT_TYPE_SCHMITT)
- return PM_RET_ERROR_ARGS;
-
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_SCHCMOS_REG_OFFSET,
- pin);
-
- val = value << PINCTRL_PIN_OFFSET(pin);
- ret = pm_mmio_write(ctrlreg, mask, val);
- break;
- case PINCTRL_CONFIG_DRIVE_STRENGTH:
- if (value > PINCTRL_DRIVE_STRENGTH_12MA)
- return PM_RET_ERROR_ARGS;
-
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_DRVSTRN0_REG_OFFSET,
- pin);
- val = (value >> 1) << PINCTRL_PIN_OFFSET(pin);
- ret = pm_mmio_write(ctrlreg, mask, val);
- if (ret)
- return ret;
-
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_DRVSTRN1_REG_OFFSET,
- pin);
- val = (value & 0x01U) << PINCTRL_PIN_OFFSET(pin);
- ret = pm_mmio_write(ctrlreg, mask, val);
- break;
- default:
- ERROR("Invalid parameter %u\n", param);
- ret = PM_RET_ERROR_NOTSUPPORTED;
- break;
- }
-
- return ret;
-}
-
-/**
- * pm_api_pinctrl_get_config() - Get configuration parameter value for given pin
- * @pin: Pin for which configuration is to be read
- * @param: Configuration parameter to be read
- * @value: buffer to store value of configuration parameter
- *
- * This function reads value of requested configuration parameter for given pin.
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_api_pinctrl_get_config(unsigned int pin,
- unsigned int param,
- unsigned int *value)
-{
- enum pm_ret_status ret;
- unsigned int ctrlreg, val;
-
- if (param >= PINCTRL_CONFIG_MAX)
- return PM_RET_ERROR_NOTSUPPORTED;
-
- if (pin >= PINCTRL_NUM_MIOS)
- return PM_RET_ERROR_ARGS;
-
- switch (param) {
- case PINCTRL_CONFIG_SLEW_RATE:
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_SLEWCTRL_REG_OFFSET,
- pin);
-
- ret = pm_mmio_read(ctrlreg, &val);
- if (ret != PM_RET_SUCCESS)
- return ret;
-
- *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
- break;
- case PINCTRL_CONFIG_BIAS_STATUS:
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_PULLSTAT_REG_OFFSET,
- pin);
-
- ret = pm_mmio_read(ctrlreg, &val);
- if (ret)
- return ret;
-
- if (ctrlreg == IOU_SLCR_BANK1_CTRL5)
- val = ((val & 0x3FFF) << 12) | ((val >> 14) & 0xFFF);
-
- *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
- break;
- case PINCTRL_CONFIG_PULL_CTRL:
-
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_PULLCTRL_REG_OFFSET,
- pin);
-
- ret = pm_mmio_read(ctrlreg, &val);
- if (ret)
- return ret;
-
- *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
- break;
- case PINCTRL_CONFIG_SCHMITT_CMOS:
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_SCHCMOS_REG_OFFSET,
- pin);
-
- ret = pm_mmio_read(ctrlreg, &val);
- if (ret)
- return ret;
-
- *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
- break;
- case PINCTRL_CONFIG_DRIVE_STRENGTH:
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_DRVSTRN0_REG_OFFSET,
- pin);
- ret = pm_mmio_read(ctrlreg, &val);
- if (ret)
- return ret;
-
- *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val) << 1;
-
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_DRVSTRN1_REG_OFFSET,
- pin);
- ret = pm_mmio_read(ctrlreg, &val);
- if (ret)
- return ret;
-
- *value |= PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
- break;
- case PINCTRL_CONFIG_VOLTAGE_STATUS:
- ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
- PINCTRL_VOLTAGE_STAT_REG_OFFSET,
- pin);
-
- ret = pm_mmio_read(ctrlreg, &val);
- if (ret)
- return ret;
-
- *value = val & PINCTRL_VOLTAGE_STATUS_MASK;
- break;
- default:
- return PM_RET_ERROR_NOTSUPPORTED;
- }
-
- return PM_RET_SUCCESS;
-}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
index 9923c00ba..2b8fca3cd 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -709,18 +709,7 @@ enum {
#define PINCTRL_DRIVE_STRENGTH_8MA 2U
#define PINCTRL_DRIVE_STRENGTH_12MA 3U
-enum pm_ret_status pm_api_pinctrl_set_function(unsigned int pin,
- unsigned int fid);
-enum pm_ret_status pm_api_pinctrl_get_function(unsigned int pin,
- unsigned int *id);
-enum pm_ret_status pm_api_pinctrl_set_config(unsigned int pin,
- unsigned int param,
- unsigned int value);
-enum pm_ret_status pm_api_pinctrl_get_config(unsigned int pin,
- unsigned int param,
- unsigned int *value);
-enum pm_ret_status pm_api_pinctrl_get_function_name(unsigned int fid,
- char *name);
+void pm_api_pinctrl_get_function_name(unsigned int fid, char *name);
enum pm_ret_status pm_api_pinctrl_get_function_groups(unsigned int fid,
unsigned int index,
uint16_t *groups);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index b1720d9f6..9a53408fd 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -65,6 +65,10 @@ unsigned int pm_get_shutdown_scope(void)
PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4); \
}
+#define EM_PACK_PAYLOAD1(pl, arg0) { \
+ pl[0] = (uint16_t)(0xE) << 16 | (uint16_t)arg0; \
+}
+
/**
* pm_self_suspend() - PM call for processor to suspend itself
* @nid Node id of the processor or subsystem
@@ -655,7 +659,11 @@ void pm_get_callbackdata(uint32_t *data, size_t count)
*/
enum pm_ret_status pm_pinctrl_request(unsigned int pin)
{
- return PM_RET_SUCCESS;
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMU */
+ PM_PACK_PAYLOAD2(payload, PM_PINCTRL_REQUEST, pin);
+ return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}
/**
@@ -668,37 +676,44 @@ enum pm_ret_status pm_pinctrl_request(unsigned int pin)
*/
enum pm_ret_status pm_pinctrl_release(unsigned int pin)
{
- return PM_RET_SUCCESS;
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMU */
+ PM_PACK_PAYLOAD2(payload, PM_PINCTRL_RELEASE, pin);
+ return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}
/**
* pm_pinctrl_get_function() - Read function id set for the given pin
* @pin Pin number
- * @nid Node ID of function currently set for given pin
+ * @fid ID of function currently set for given pin
*
* This function provides the function currently set for the given pin.
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_pinctrl_get_function(unsigned int pin,
- enum pm_node_id *nid)
+enum pm_ret_status pm_pinctrl_get_function(unsigned int pin, unsigned int *fid)
{
- return pm_api_pinctrl_get_function(pin, nid);
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ PM_PACK_PAYLOAD2(payload, PM_PINCTRL_GET_FUNCTION, pin);
+ return pm_ipi_send_sync(primary_proc, payload, fid, 1);
}
/**
* pm_pinctrl_set_function() - Set function id set for the given pin
* @pin Pin number
- * @nid Node ID of function to set for given pin
- *
- * This function provides the function currently set for the given pin.
+ * @fid ID of function to set for given pin
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_pinctrl_set_function(unsigned int pin,
- enum pm_node_id nid)
+enum pm_ret_status pm_pinctrl_set_function(unsigned int pin, unsigned int fid)
{
- return pm_api_pinctrl_set_function(pin, (unsigned int)nid);
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMU */
+ PM_PACK_PAYLOAD3(payload, PM_PINCTRL_SET_FUNCTION, pin, fid);
+ return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}
/**
@@ -715,24 +730,30 @@ enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
unsigned int param,
unsigned int *value)
{
- return pm_api_pinctrl_get_config(pin, param, value);
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ PM_PACK_PAYLOAD3(payload, PM_PINCTRL_CONFIG_PARAM_GET, pin, param);
+ return pm_ipi_send_sync(primary_proc, payload, value, 1);
}
/**
- * pm_pinctrl_set_config() - Read value of requested config param for given pin
+ * pm_pinctrl_set_config() - Set value of requested config param for given pin
* @pin Pin number
* @param Parameter to set
* @value Parameter value to set
*
- * This function provides the configuration parameter value for the given pin.
- *
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
unsigned int param,
unsigned int value)
{
- return pm_api_pinctrl_set_config(pin, param, value);
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMU */
+ PM_PACK_PAYLOAD4(payload, PM_PINCTRL_CONFIG_PARAM_SET, pin, param,
+ value);
+ return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
}
/**
@@ -793,12 +814,10 @@ static enum pm_ret_status pm_clock_get_num_clocks(uint32_t *nclocks)
*
* This function is used by master to get nmae of clock specified
* by given clock ID.
- *
- * @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_clock_get_name(unsigned int clock_id, char *name)
+static void pm_clock_get_name(unsigned int clock_id, char *name)
{
- return pm_api_clock_get_name(clock_id, name);
+ pm_api_clock_get_name(clock_id, name);
}
/**
@@ -907,7 +926,13 @@ static enum pm_ret_status pm_clock_gate(unsigned int clock_id,
/* Send request to the PMU */
PM_PACK_PAYLOAD2(payload, api_id, clock_id);
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+
+ /* If action fails due to the lack of permissions filter the error */
+ if (status == PM_RET_ERROR_ACCESS)
+ status = PM_RET_SUCCESS;
+
+ return status;
}
/**
@@ -1229,13 +1254,10 @@ static enum pm_ret_status pm_pinctrl_get_num_function_groups(unsigned int fid,
*
* This function is used by master to get name of function specified
* by given function Id
- *
- * Return: Returns status, either success or error+reason.
*/
-static enum pm_ret_status pm_pinctrl_get_function_name(unsigned int fid,
- char *name)
+static void pm_pinctrl_get_function_name(unsigned int fid, char *name)
{
- return pm_api_pinctrl_get_function_name(fid, name);
+ pm_api_pinctrl_get_function_name(fid, name);
}
/**
@@ -1295,78 +1317,58 @@ static enum pm_ret_status pm_pinctrl_get_pin_groups(unsigned int pin_id,
* @data Returned output data
*
* This function returns requested data.
- *
- * @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_query_data(enum pm_query_id qid,
- unsigned int arg1,
- unsigned int arg2,
- unsigned int arg3,
- unsigned int *data)
+void pm_query_data(enum pm_query_id qid, unsigned int arg1, unsigned int arg2,
+ unsigned int arg3, unsigned int *data)
{
- enum pm_ret_status ret;
-
switch (qid) {
case PM_QID_CLOCK_GET_NAME:
- ret = pm_clock_get_name(arg1, (char *)data);
+ pm_clock_get_name(arg1, (char *)data);
break;
case PM_QID_CLOCK_GET_TOPOLOGY:
- ret = pm_clock_get_topology(arg1, arg2, &data[1]);
- data[0] = (unsigned int)ret;
+ data[0] = pm_clock_get_topology(arg1, arg2, &data[1]);
break;
case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
- ret = pm_clock_get_fixedfactor_params(arg1, &data[1], &data[2]);
- data[0] = (unsigned int)ret;
+ data[0] = pm_clock_get_fixedfactor_params(arg1, &data[1],
+ &data[2]);
break;
case PM_QID_CLOCK_GET_PARENTS:
- ret = pm_clock_get_parents(arg1, arg2, &data[1]);
- data[0] = (unsigned int)ret;
+ data[0] = pm_clock_get_parents(arg1, arg2, &data[1]);
break;
case PM_QID_CLOCK_GET_ATTRIBUTES:
- ret = pm_clock_get_attributes(arg1, &data[1]);
- data[0] = (unsigned int)ret;
+ data[0] = pm_clock_get_attributes(arg1, &data[1]);
break;
case PM_QID_PINCTRL_GET_NUM_PINS:
- ret = pm_pinctrl_get_num_pins(&data[1]);
- data[0] = (unsigned int)ret;
+ data[0] = pm_pinctrl_get_num_pins(&data[1]);
break;
case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
- ret = pm_pinctrl_get_num_functions(&data[1]);
- data[0] = (unsigned int)ret;
+ data[0] = pm_pinctrl_get_num_functions(&data[1]);
break;
case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
- ret = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
- data[0] = (unsigned int)ret;
+ data[0] = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
break;
case PM_QID_PINCTRL_GET_FUNCTION_NAME:
- ret = pm_pinctrl_get_function_name(arg1, (char *)data);
+ pm_pinctrl_get_function_name(arg1, (char *)data);
break;
case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
- ret = pm_pinctrl_get_function_groups(arg1, arg2,
- (uint16_t *)&data[1]);
- data[0] = (unsigned int)ret;
+ data[0] = pm_pinctrl_get_function_groups(arg1, arg2,
+ (uint16_t *)&data[1]);
break;
case PM_QID_PINCTRL_GET_PIN_GROUPS:
- ret = pm_pinctrl_get_pin_groups(arg1, arg2,
- (uint16_t *)&data[1]);
- data[0] = (unsigned int)ret;
+ data[0] = pm_pinctrl_get_pin_groups(arg1, arg2,
+ (uint16_t *)&data[1]);
break;
case PM_QID_CLOCK_GET_NUM_CLOCKS:
- ret = pm_clock_get_num_clocks(&data[1]);
- data[0] = (unsigned int)ret;
+ data[0] = pm_clock_get_num_clocks(&data[1]);
break;
case PM_QID_CLOCK_GET_MAX_DIVISOR:
- ret = pm_clock_get_max_divisor(arg1, arg2, &data[1]);
- data[0] = (unsigned int)ret;
+ data[0] = pm_clock_get_max_divisor(arg1, arg2, &data[1]);
break;
default:
- ret = PM_RET_ERROR_ARGS;
+ data[0] = PM_RET_ERROR_ARGS;
WARN("Unimplemented query service call: 0x%x\n", qid);
- break;
}
-
- return ret;
}
enum pm_ret_status pm_sha_hash(uint32_t address_high,
@@ -1548,3 +1550,101 @@ enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode)
PM_PACK_PAYLOAD2(payload, PM_PLL_GET_MODE, nid);
return pm_ipi_send_sync(primary_proc, payload, mode, 1);
}
+
+/**
+ * pm_register_access() - PM API for register read/write access data
+ *
+ * @register_access_id Register_access_id which says register read/write
+ *
+ * @address Address of the register to be accessed
+ *
+ * @mask Mask value to be used while writing value
+ *
+ * @value Value to be written to register
+ *
+ * @out Returned output data
+ *
+ * This function returns requested data.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_register_access(unsigned int register_access_id,
+ unsigned int address,
+ unsigned int mask,
+ unsigned int value,
+ unsigned int *out)
+{
+ enum pm_ret_status ret;
+
+ if (((ZYNQMP_CSU_BASEADDR & address) != ZYNQMP_CSU_BASEADDR) &&
+ ((CSUDMA_BASE & address) != CSUDMA_BASE) &&
+ ((RSA_CORE_BASE & address) != RSA_CORE_BASE) &&
+ ((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE))
+ return PM_RET_ERROR_ACCESS;
+
+ switch (register_access_id) {
+ case CONFIG_REG_WRITE:
+ ret = pm_mmio_write(address, mask, value);
+ break;
+ case CONFIG_REG_READ:
+ ret = pm_mmio_read(address, out);
+ break;
+ default:
+ ret = PM_RET_ERROR_ARGS;
+ WARN("Unimplemented register_access call\n\r");
+ }
+ return ret;
+}
+
+/**
+ * pm_efuse_access() - To program or read efuse bits.
+ *
+ * This function provides access to the xilskey library to program/read
+ * efuse bits.
+ *
+ * address_low: lower 32-bit Linear memory space address
+ * address_high: higher 32-bit Linear memory space address
+ *
+ * value: Returned output value
+ *
+ * @return Returns status, either success or error+reason
+ *
+ */
+enum pm_ret_status pm_efuse_access(uint32_t address_high,
+ uint32_t address_low,
+ uint32_t *value)
+{
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMU */
+ PM_PACK_PAYLOAD3(payload, PM_EFUSE_ACCESS, address_high, address_low);
+
+ return pm_ipi_send_sync(primary_proc, payload, value, 1);
+}
+
+enum pm_ret_status em_set_action(unsigned int *value)
+{
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMU */
+ EM_PACK_PAYLOAD1(payload, EM_SET_ACTION);
+ return pm_ipi_send_sync(primary_proc, payload, value, 1);
+}
+
+enum pm_ret_status em_remove_action(unsigned int *value)
+{
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMU */
+ EM_PACK_PAYLOAD1(payload, EM_REMOVE_ACTION);
+ return pm_ipi_send_sync(primary_proc, payload, value, 1);
+}
+
+enum pm_ret_status em_send_errors(unsigned int *value)
+{
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Send request to the PMU */
+ EM_PACK_PAYLOAD1(payload, EM_SEND_ERRORS);
+ return pm_ipi_send_sync(primary_proc, payload, value, 1);
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index ff66d3f02..b0c26529d 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -28,6 +28,11 @@ enum pm_query_id {
PM_QID_CLOCK_GET_MAX_DIVISOR,
};
+enum pm_register_access_id {
+ CONFIG_REG_WRITE,
+ CONFIG_REG_READ,
+};
+
/**********************************************************
* System-level API function declarations
**********************************************************/
@@ -151,11 +156,8 @@ enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
unsigned int parent_id);
enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
unsigned int *parent_id);
-enum pm_ret_status pm_query_data(enum pm_query_id qid,
- unsigned int arg1,
- unsigned int arg2,
- unsigned int arg3,
- unsigned int *data);
+void pm_query_data(enum pm_query_id qid, unsigned int arg1, unsigned int arg2,
+ unsigned int arg3, unsigned int *data);
enum pm_ret_status pm_sha_hash(uint32_t address_high,
uint32_t address_low,
uint32_t size,
@@ -178,6 +180,11 @@ enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
enum pm_ret_status pm_aes_engine(uint32_t address_high,
uint32_t address_low,
uint32_t *value);
+enum pm_ret_status pm_register_access(unsigned int register_access_id,
+ unsigned int address,
+ unsigned int mask,
+ unsigned int value,
+ unsigned int *out);
enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
enum pm_pll_param param_id,
@@ -189,5 +196,10 @@ enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode);
enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode);
+enum pm_ret_status pm_efuse_access(uint32_t address_high,
+ uint32_t address_low, uint32_t *value);
+enum pm_ret_status em_set_action(unsigned int *value);
+enum pm_ret_status em_remove_action(unsigned int *value);
+enum pm_ret_status em_send_errors(unsigned int *value);
#endif /* PM_API_SYS_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
index cae36c9d8..3324431dd 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,7 +18,7 @@
* (PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR
*/
#define PM_VERSION_MAJOR 1
-#define PM_VERSION_MINOR 0
+#define PM_VERSION_MINOR 1
#define PM_VERSION ((PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR)
@@ -33,6 +33,7 @@
#define PM_STATE_CPU_IDLE 0x0U
#define PM_STATE_SUSPEND_TO_RAM 0xFU
+#define EM_FUNID_NUM_MASK 0xF0000U
/*********************************************************************
* Enum definitions
********************************************************************/
@@ -97,6 +98,9 @@ enum pm_api_id {
PM_PLL_GET_PARAMETER,
PM_PLL_SET_MODE,
PM_PLL_GET_MODE,
+ /* PM Register Access API */
+ PM_REGISTER_ACCESS,
+ PM_EFUSE_ACCESS,
PM_API_MAX
};
@@ -215,26 +219,29 @@ enum pm_opchar_type {
/**
* @PM_RET_SUCCESS: success
- * @PM_RET_ERROR_ARGS: illegal arguments provided
+ * @PM_RET_ERROR_ARGS: illegal arguments provided (deprecated)
+ * @PM_RET_ERROR_NOTSUPPORTED: feature not supported (deprecated)
+ * @PM_RET_ERROR_INTERNAL: internal error
+ * @PM_RET_ERROR_CONFLICT: conflict
* @PM_RET_ERROR_ACCESS: access rights violation
+ * @PM_RET_ERROR_INVALID_NODE: invalid node
+ * @PM_RET_ERROR_DOUBLE_REQ: duplicate request for same node
+ * @PM_RET_ERROR_ABORT_SUSPEND: suspend procedure has been aborted
* @PM_RET_ERROR_TIMEOUT: timeout in communication with PMU
- * @PM_RET_ERROR_NOTSUPPORTED: feature not supported
- * @PM_RET_ERROR_PROC: node is not a processor node
- * @PM_RET_ERROR_API_ID: illegal API ID
- * @PM_RET_ERROR_OTHER: other error
+ * @PM_RET_ERROR_NODE_USED: node is already in use
*/
enum pm_ret_status {
PM_RET_SUCCESS,
- PM_RET_ERROR_ARGS,
- PM_RET_ERROR_ACCESS,
- PM_RET_ERROR_TIMEOUT,
- PM_RET_ERROR_NOTSUPPORTED,
- PM_RET_ERROR_PROC,
- PM_RET_ERROR_API_ID,
- PM_RET_ERROR_FAILURE,
- PM_RET_ERROR_COMMUNIC,
- PM_RET_ERROR_DOUBLEREQ,
- PM_RET_ERROR_OTHER,
+ PM_RET_ERROR_ARGS = 1,
+ PM_RET_ERROR_NOTSUPPORTED = 4,
+ PM_RET_ERROR_INTERNAL = 2000,
+ PM_RET_ERROR_CONFLICT = 2001,
+ PM_RET_ERROR_ACCESS = 2002,
+ PM_RET_ERROR_INVALID_NODE = 2003,
+ PM_RET_ERROR_DOUBLE_REQ = 2004,
+ PM_RET_ERROR_ABORT_SUSPEND = 2005,
+ PM_RET_ERROR_TIMEOUT = 2006,
+ PM_RET_ERROR_NODE_USED = 2007
};
/**
@@ -317,4 +324,13 @@ enum pm_clock_div_id {
PM_CLOCK_DIV1_ID,
};
+/**
+ * EM API IDs
+ */
+enum em_api_id {
+ EM_SET_ACTION = 1,
+ EM_REMOVE_ACTION,
+ EM_SEND_ERRORS,
+};
+
#endif /* PM_DEFS_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index 98dbe7d6e..a49bda8d2 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -29,8 +29,8 @@
#define PM_SET_SUSPEND_MODE 0xa02
#define PM_GET_TRUSTZONE_VERSION 0xa03
-/* !0 - UP, 0 - DOWN */
-static int32_t pm_up = 0;
+/* pm_up = !0 - UP, pm_up = 0 - DOWN */
+static int32_t pm_up, ipi_irq_flag;
#if ZYNQMP_WDT_RESTART
static spinlock_t inc_lock;
@@ -142,6 +142,8 @@ static uint64_t __unused __dead2 zynqmp_sgi7_irq(uint32_t id, uint32_t flags,
void *handle, void *cookie)
{
int i;
+ uint32_t value;
+
/* enter wfi and stay there */
INFO("Entering wfi\n");
@@ -156,8 +158,9 @@ static uint64_t __unused __dead2 zynqmp_sgi7_irq(uint32_t id, uint32_t flags,
spin_unlock(&inc_lock);
if (active_cores == 0) {
- pm_system_shutdown(PMF_SHUTDOWN_TYPE_RESET,
- PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM);
+ pm_mmio_read(PMU_GLOBAL_GEN_STORAGE4, &value);
+ value = (value & RESTART_SCOPE_MASK) >> RESTART_SCOPE_SHIFT;
+ pm_system_shutdown(PMF_SHUTDOWN_TYPE_RESET, value);
}
/* enter wfi and stay there */
@@ -210,6 +213,15 @@ int pm_setup(void)
status = pm_ipi_init(primary_proc);
+ ret = pm_get_api_version(&pm_ctx.api_version);
+ if (pm_ctx.api_version < PM_VERSION) {
+ ERROR("BL31: Platform Management API version error. Expected: "
+ "v%d.%d - Found: v%d.%d\n", PM_VERSION_MAJOR,
+ PM_VERSION_MINOR, pm_ctx.api_version >> 16,
+ pm_ctx.api_version & 0xFFFF);
+ return -EINVAL;
+ }
+
#if ZYNQMP_WDT_RESTART
status = pm_wdt_restart_setup();
if (status)
@@ -321,22 +333,21 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
case PM_GET_API_VERSION:
/* Check is PM API version already verified */
- if (pm_ctx.api_version == PM_VERSION) {
+ if (pm_ctx.api_version >= PM_VERSION) {
+ if (!ipi_irq_flag) {
+ /*
+ * Enable IPI IRQ
+ * assume the rich OS is OK to handle callback IRQs now.
+ * Even if we were wrong, it would not enable the IRQ in
+ * the GIC.
+ */
+ pm_ipi_irq_enable(primary_proc);
+ ipi_irq_flag = 1;
+ }
SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
- ((uint64_t)PM_VERSION << 32));
+ ((uint64_t)pm_ctx.api_version << 32));
}
- ret = pm_get_api_version(&pm_ctx.api_version);
- /*
- * Enable IPI IRQ
- * assume the rich OS is OK to handle callback IRQs now.
- * Even if we were wrong, it would not enable the IRQ in
- * the GIC.
- */
- pm_ipi_irq_enable(primary_proc);
- SMC_RET1(handle, (uint64_t)ret |
- ((uint64_t)pm_ctx.api_version << 32));
-
case PM_SET_CONFIGURATION:
ret = pm_set_configuration(pm_arg[0]);
SMC_RET1(handle, (uint64_t)ret);
@@ -423,7 +434,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
{
uint32_t result[4] = {0};
- pm_get_callbackdata(result, (sizeof(result)/sizeof(uint32_t)));
+ pm_get_callbackdata(result, ARRAY_SIZE(result));
SMC_RET2(handle,
(uint64_t)result[0] | ((uint64_t)result[1] << 32),
(uint64_t)result[2] | ((uint64_t)result[3] << 32));
@@ -474,8 +485,8 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
{
uint32_t data[4] = { 0 };
- ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], data);
+ pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
+ pm_arg[3], data);
SMC_RET2(handle, (uint64_t)data[0] | ((uint64_t)data[1] << 32),
(uint64_t)data[2] | ((uint64_t)data[3] << 32));
}
@@ -606,8 +617,78 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)mode << 32));
}
+ case PM_REGISTER_ACCESS:
+ {
+ uint32_t value;
+
+ ret = pm_register_access(pm_arg[0], pm_arg[1], pm_arg[2],
+ pm_arg[3], &value);
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ }
+
+ case PM_EFUSE_ACCESS:
+ {
+ uint32_t value;
+
+ ret = pm_efuse_access(pm_arg[0], pm_arg[1], &value);
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ }
+
default:
WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
}
}
+
+/**
+ * em_smc_handler() - SMC handler for EM-API calls coming from EL1/EL2.
+ * @smc_fid - Function Identifier
+ * @x1 - x4 - Arguments
+ * @cookie - Unused
+ * @handler - Pointer to caller's context structure
+ *
+ * @return - Unused
+ *
+ * Determines that smc_fid is valid and supported EM SMC Function ID from the
+ * list of em_api_ids, otherwise completes the request with
+ * the unknown SMC Function ID
+ *
+ * The SMC calls for EM service are forwarded from SIP Service SMC handler
+ * function with rt_svc_handle signature
+ */
+uint64_t em_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+ uint64_t x4, void *cookie, void *handle, uint64_t flags)
+{
+ enum pm_ret_status ret;
+
+ switch (smc_fid & FUNCID_NUM_MASK) {
+ /* EM API Functions */
+ case EM_SET_ACTION:
+ {
+ uint32_t value;
+
+ ret = em_set_action(&value);
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ }
+
+ case EM_REMOVE_ACTION:
+ {
+ uint32_t value;
+
+ ret = em_remove_action(&value);
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ }
+
+ case EM_SEND_ERRORS:
+ {
+ uint32_t value;
+
+ ret = em_send_errors(&value);
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ }
+
+ default:
+ WARN("Unimplemented EM Service Call: 0x%x\n", smc_fid);
+ SMC_RET1(handle, SMC_UNK);
+ }
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
index 0968f64cb..abadd4065 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,4 +14,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
uint64_t x4, void *cookie, void *handle,
uint64_t flags);
+uint64_t em_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+ uint64_t x4, void *cookie, void *handle,
+ uint64_t flags);
#endif /* PM_SVC_MAIN_H */
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index 9b182749c..114da33d6 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,6 +25,9 @@
#define PM_FID_MASK 0xf000u
#define PM_FID_VALUE 0u
#define IPI_FID_VALUE 0x1000u
+#define EM_FID_MASK 0xf0000u
+#define EM_FID_VALUE 0xE0000u
+#define is_em_fid(_fid) (((_fid) & EM_FID_MASK) == EM_FID_VALUE)
#define is_pm_fid(_fid) (((_fid) & PM_FID_MASK) == PM_FID_VALUE)
#define is_ipi_fid(_fid) (((_fid) & PM_FID_MASK) == IPI_FID_VALUE)
@@ -41,9 +44,7 @@ DEFINE_SVC_UUID2(zynqmp_sip_uuid,
static int32_t sip_svc_setup(void)
{
/* PM implementation as SiP Service */
- pm_setup();
-
- return 0;
+ return pm_setup();
}
/**
@@ -61,8 +62,12 @@ uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
void *handle,
u_register_t flags)
{
+ /* Let EM SMC handler deal with EM-related requests */
+ if (is_em_fid(smc_fid)) {
+ return em_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
+ flags);
+ } else if (is_pm_fid(smc_fid)) {
/* Let PM SMC handler deal with PM-related requests */
- if (is_pm_fid(smc_fid)) {
return pm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
flags);
}
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index 7f0ac74cf..5e770f75c 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -21,12 +21,12 @@ void tsp_early_platform_setup(void)
* Register a different console than already in use to display
* messages from TSP
*/
- static console_cdns_t tsp_boot_console;
+ static console_t tsp_boot_console;
(void)console_cdns_register(ZYNQMP_UART_BASE,
zynqmp_get_uart_clk(),
ZYNQMP_UART_BAUDRATE,
&tsp_boot_console);
- console_set_scope(&tsp_boot_console.console,
+ console_set_scope(&tsp_boot_console,
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT);
/* Initialize the platform config for future decision making */