Merge pull request #1745 from svenauhagen/bugfix/a8k
authorAntonio Niño Díaz <antonio.ninodiaz@arm.com>
Thu, 31 Jan 2019 10:22:50 +0000 (10:22 +0000)
committerGitHub <noreply@github.com>
Thu, 31 Jan 2019 10:22:50 +0000 (10:22 +0000)
Armada8k GPIO Register macro fix

459 files changed:
Makefile
bl1/bl1_private.h
bl2/bl2_private.h
bl31/bl31.ld.S
bl31/bl31.mk
bl31/bl31_main.c
bl32/sp_min/sp_min.ld.S
bl32/sp_min/sp_min_main.c
bl32/tsp/tsp_main.c
bl32/tsp/tsp_timer.c
common/backtrace/backtrace.c
common/desc_image_load.c
docs/auth-framework.rst
docs/change-log.rst
docs/coding-guidelines.rst [new file with mode: 0644]
docs/firmware-design.rst
docs/firmware-update.rst
docs/plat/nvidia-tegra.rst
docs/plat/warp7.rst
docs/porting-guide.rst
docs/psci-lib-integration-guide.rst
docs/ras.rst
docs/secure-partition-manager-design.rst
docs/user-guide.rst
drivers/arm/ccn/ccn.c
drivers/arm/css/mhu/css_mhu.c [new file with mode: 0644]
drivers/arm/css/mhu/css_mhu_doorbell.c [new file with mode: 0644]
drivers/arm/css/scmi/scmi_ap_core_proto.c [new file with mode: 0644]
drivers/arm/css/scmi/scmi_common.c [new file with mode: 0644]
drivers/arm/css/scmi/scmi_private.h [new file with mode: 0644]
drivers/arm/css/scmi/scmi_pwr_dmn_proto.c [new file with mode: 0644]
drivers/arm/css/scmi/scmi_sys_pwr_proto.c [new file with mode: 0644]
drivers/arm/css/scp/css_bom_bootloader.c [new file with mode: 0644]
drivers/arm/css/scp/css_pm_scmi.c [new file with mode: 0644]
drivers/arm/css/scp/css_pm_scpi.c [new file with mode: 0644]
drivers/arm/css/scp/css_sds.c [new file with mode: 0644]
drivers/arm/css/scpi/css_scpi.c [new file with mode: 0644]
drivers/arm/css/sds/aarch32/sds_helpers.S [new file with mode: 0644]
drivers/arm/css/sds/aarch64/sds_helpers.S [new file with mode: 0644]
drivers/arm/css/sds/sds.c [new file with mode: 0644]
drivers/arm/css/sds/sds_private.h [new file with mode: 0644]
drivers/arm/fvp/fvp_pwrc.c [new file with mode: 0644]
drivers/console/multi_console.c
drivers/mmc/mmc.c
drivers/partition/partition.c
drivers/renesas/rcar/cpld/ulcb_cpld.c
drivers/renesas/rcar/pwrc/pwrc.c
drivers/renesas/rcar/pwrc/pwrc.h
drivers/rpi3/gpio/rpi3_gpio.c [new file with mode: 0644]
drivers/st/bsec/bsec.c [new file with mode: 0644]
drivers/st/clk/stm32mp1_clkfunc.c
drivers/st/ddr/stm32mp1_ddr.c
drivers/st/ddr/stm32mp1_ram.c
drivers/st/gpio/stm32_gpio.c
drivers/st/i2c/stm32_i2c.c [new file with mode: 0644]
drivers/st/io/io_stm32image.c
drivers/st/mmc/stm32_sdmmc2.c
drivers/st/pmic/stm32_i2c.c [deleted file]
drivers/st/pmic/stm32mp1_pmic.c [deleted file]
drivers/st/pmic/stm32mp_pmic.c [new file with mode: 0644]
drivers/st/pmic/stpmic1.c [new file with mode: 0644]
drivers/st/pmic/stpmu1.c [deleted file]
drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
drivers/synopsys/ufs/dw_ufs.c
drivers/ufs/ufs.c
fdts/stm32mp15-ddr.dtsi
fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
fdts/stm32mp157-pinctrl.dtsi
fdts/stm32mp157c-ed1.dts
fdts/stm32mp157c-ev1.dts
fdts/stm32mp157c.dtsi
fdts/stm32mp157caa-pinctrl.dtsi
include/arch/aarch32/arch.h
include/arch/aarch32/arch_features.h [new file with mode: 0644]
include/arch/aarch32/arch_helpers.h
include/arch/aarch64/arch.h
include/arch/aarch64/arch_features.h [new file with mode: 0644]
include/arch/aarch64/arch_helpers.h
include/common/bl_common.h
include/common/desc_image_load.h
include/drivers/arm/css/css_mhu.h [new file with mode: 0644]
include/drivers/arm/css/css_mhu_doorbell.h [new file with mode: 0644]
include/drivers/arm/css/css_scp.h [new file with mode: 0644]
include/drivers/arm/css/css_scpi.h [new file with mode: 0644]
include/drivers/arm/css/scmi.h [new file with mode: 0644]
include/drivers/arm/css/sds.h [new file with mode: 0644]
include/drivers/arm/fvp/fvp_pwrc.h [new file with mode: 0644]
include/drivers/arm/gicv3.h
include/drivers/rpi3/gpio/rpi3_gpio.h [new file with mode: 0644]
include/drivers/st/bsec.h [new file with mode: 0644]
include/drivers/st/stm32_gpio.h
include/drivers/st/stm32mp1_ddr.h
include/drivers/st/stm32mp1_ddr_regs.h
include/drivers/st/stm32mp1_pmic.h [deleted file]
include/drivers/st/stm32mp1_rcc.h
include/drivers/st/stm32mp_pmic.h [new file with mode: 0644]
include/drivers/st/stpmic1.h [new file with mode: 0644]
include/drivers/st/stpmu1.h [deleted file]
include/dt-bindings/interrupt-controller/arm-gic.h [new file with mode: 0644]
include/dt-bindings/pinctrl/stm32-pinfunc.h
include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
include/lib/xlat_tables/xlat_tables_arch.h
include/lib/xlat_tables/xlat_tables_v2_helpers.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/common/plat_arm.h
include/plat/arm/css/common/css_def.h
include/services/mm_svc.h
include/services/secure_partition.h
include/services/spm_svc.h
lib/aarch32/arm32_aeabi_divmod.c
lib/el3_runtime/aarch64/context_mgmt.c
lib/utils/mem_region.c
lib/xlat_tables/aarch32/xlat_tables.c
lib/xlat_tables/aarch64/xlat_tables.c
lib/xlat_tables/xlat_tables_private.h
lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
lib/xlat_tables_v2/xlat_tables_core.c
lib/xlat_tables_v2/xlat_tables_private.h
maintainers.rst
make_helpers/build_macros.mk
make_helpers/defaults.mk
plat/arm/board/common/aarch32/board_arm_helpers.S
plat/arm/board/common/aarch64/board_arm_helpers.S
plat/arm/board/common/board_arm_trusted_boot.c
plat/arm/board/common/board_common.mk
plat/arm/board/fvp/aarch32/fvp_helpers.S
plat/arm/board/fvp/aarch64/fvp_helpers.S
plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c [deleted file]
plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.h [deleted file]
plat/arm/board/fvp/fvp_bl1_setup.c
plat/arm/board/fvp/fvp_bl2_el3_setup.c
plat/arm/board/fvp/fvp_bl2_setup.c
plat/arm/board/fvp/fvp_bl2u_setup.c
plat/arm/board/fvp/fvp_bl31_setup.c
plat/arm/board/fvp/fvp_common.c
plat/arm/board/fvp/fvp_io_storage.c
plat/arm/board/fvp/fvp_pm.c
plat/arm/board/fvp/fvp_private.h
plat/arm/board/fvp/fvp_security.c
plat/arm/board/fvp/fvp_topology.c
plat/arm/board/fvp/fvp_trusted_boot.c
plat/arm/board/fvp/include/plat.ld.S
plat/arm/board/fvp/include/plat_macros.S
plat/arm/board/fvp/include/platform_def.h
plat/arm/board/fvp/platform.mk
plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
plat/arm/board/fvp/sp_min/sp_min-fvp.mk
plat/arm/board/fvp/tsp/fvp_tsp_setup.c
plat/arm/board/fvp/tsp/tsp-fvp.mk
plat/arm/board/juno/aarch32/juno_helpers.S
plat/arm/board/juno/aarch64/juno_helpers.S
plat/arm/board/juno/include/platform_def.h
plat/arm/board/juno/juno_bl1_setup.c
plat/arm/board/juno/juno_bl2_setup.c
plat/arm/board/juno/juno_common.c
plat/arm/board/juno/juno_err.c
plat/arm/board/juno/juno_pm.c
plat/arm/board/juno/juno_security.c
plat/arm/board/juno/juno_stack_protector.c
plat/arm/board/juno/juno_topology.c
plat/arm/board/juno/juno_trng.c
plat/arm/board/juno/juno_tzmp1_def.h
plat/arm/board/juno/platform.mk
plat/arm/board/n1sdp/include/platform_def.h
plat/arm/board/n1sdp/n1sdp_bl31_setup.c
plat/arm/board/n1sdp/n1sdp_plat.c
plat/arm/board/n1sdp/n1sdp_topology.c
plat/arm/common/arm_bl1_fwu.c
plat/arm/common/arm_bl1_setup.c
plat/arm/common/arm_bl2_el3_setup.c
plat/arm/common/arm_bl2_setup.c
plat/arm/common/arm_bl2u_setup.c
plat/arm/common/arm_bl31_setup.c
plat/arm/common/arm_cci.c
plat/arm/common/arm_ccn.c
plat/arm/common/arm_common.c
plat/arm/common/arm_common.mk
plat/arm/common/arm_console.c
plat/arm/common/arm_dyn_cfg.c
plat/arm/common/arm_dyn_cfg_helpers.c
plat/arm/common/arm_err.c
plat/arm/common/arm_gicv2.c
plat/arm/common/arm_gicv3.c
plat/arm/common/arm_image_load.c
plat/arm/common/arm_io_storage.c
plat/arm/common/arm_nor_psci_mem_protect.c
plat/arm/common/arm_pm.c
plat/arm/common/arm_sip_svc.c
plat/arm/common/arm_topology.c
plat/arm/common/arm_tzc400.c
plat/arm/common/arm_tzc_dmc500.c
plat/arm/common/execution_state_switch.c
plat/arm/common/sp_min/arm_sp_min_setup.c
plat/arm/common/tsp/arm_tsp_setup.c
plat/arm/css/common/aarch32/css_helpers.S
plat/arm/css/common/aarch64/css_helpers.S
plat/arm/css/common/css_bl1_setup.c
plat/arm/css/common/css_bl2_setup.c
plat/arm/css/common/css_bl2u_setup.c
plat/arm/css/common/css_common.mk
plat/arm/css/common/css_pm.c
plat/arm/css/common/css_topology.c
plat/arm/css/common/sp_min/css_sp_min.mk
plat/arm/css/drivers/mhu/css_mhu.c [deleted file]
plat/arm/css/drivers/mhu/css_mhu.h [deleted file]
plat/arm/css/drivers/mhu/css_mhu_doorbell.c [deleted file]
plat/arm/css/drivers/mhu/css_mhu_doorbell.h [deleted file]
plat/arm/css/drivers/scmi/scmi.h [deleted file]
plat/arm/css/drivers/scmi/scmi_ap_core_proto.c [deleted file]
plat/arm/css/drivers/scmi/scmi_common.c [deleted file]
plat/arm/css/drivers/scmi/scmi_private.h [deleted file]
plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c [deleted file]
plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c [deleted file]
plat/arm/css/drivers/scp/css_bom_bootloader.c [deleted file]
plat/arm/css/drivers/scp/css_pm_scmi.c [deleted file]
plat/arm/css/drivers/scp/css_pm_scpi.c [deleted file]
plat/arm/css/drivers/scp/css_scp.h [deleted file]
plat/arm/css/drivers/scp/css_sds.c [deleted file]
plat/arm/css/drivers/scpi/css_scpi.c [deleted file]
plat/arm/css/drivers/scpi/css_scpi.h [deleted file]
plat/arm/css/drivers/sds/aarch32/sds_helpers.S [deleted file]
plat/arm/css/drivers/sds/aarch64/sds_helpers.S [deleted file]
plat/arm/css/drivers/sds/sds.c [deleted file]
plat/arm/css/drivers/sds/sds.h [deleted file]
plat/arm/css/drivers/sds/sds_private.h [deleted file]
plat/arm/css/sgi/include/sgi_base_platform_def.h
plat/arm/css/sgi/sgi_bl31_setup.c
plat/arm/css/sgi/sgi_image_load.c
plat/arm/css/sgi/sgi_plat.c
plat/arm/css/sgi/sgi_ras.c
plat/arm/css/sgi/sgi_topology.c
plat/arm/css/sgm/include/platform_oid.h
plat/arm/css/sgm/include/sgm_base_platform_def.h
plat/arm/css/sgm/sgm_bl1_setup.c
plat/arm/css/sgm/sgm_bl31_setup.c
plat/arm/css/sgm/sgm_mmap_config.c
plat/arm/css/sgm/sgm_plat_config.c
plat/arm/css/sgm/sgm_security.c
plat/arm/css/sgm/sgm_topology.c
plat/arm/css/sgm/tsp/sgm_tsp_setup.c
plat/arm/soc/common/soc_css.mk
plat/arm/soc/common/soc_css_security.c
plat/hisilicon/hikey/hikey_bl1_setup.c
plat/hisilicon/hikey960/hikey960_bl1_setup.c
plat/hisilicon/hikey960/hikey960_def.h
plat/hisilicon/hikey960/include/platform_def.h
plat/hisilicon/poplar/bl1_plat_setup.c
plat/imx/common/imx8_psci.c
plat/imx/common/imx_sip_handler.c [new file with mode: 0644]
plat/imx/common/imx_sip_svc.c [new file with mode: 0644]
plat/imx/common/imx_uart_console.S
plat/imx/common/include/imx_sip_svc.h [new file with mode: 0644]
plat/imx/common/include/imx_uart.h
plat/imx/common/include/plat_imx8.h
plat/imx/common/include/sci/sci.h
plat/imx/common/include/sci/svc/misc/sci_misc_api.h [new file with mode: 0644]
plat/imx/common/include/sci/svc/timer/sci_timer_api.h [new file with mode: 0644]
plat/imx/common/lpuart_console.S
plat/imx/common/plat_imx8_gic.c
plat/imx/common/sci/imx8_mu.c
plat/imx/common/sci/imx8_mu.h
plat/imx/common/sci/sci_api.mk
plat/imx/common/sci/svc/misc/misc_rpc_clnt.c [new file with mode: 0644]
plat/imx/common/sci/svc/misc/sci_misc_rpc.h [new file with mode: 0644]
plat/imx/common/sci/svc/timer/sci_timer_rpc.h [new file with mode: 0644]
plat/imx/common/sci/svc/timer/timer_rpc_clnt.c [new file with mode: 0644]
plat/imx/imx7/warp7/include/platform_def.h
plat/imx/imx7/warp7/platform.mk
plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c
plat/imx/imx7/warp7/warp7_io_storage.c
plat/imx/imx7/warp7/warp7_rotpk.S [new file with mode: 0644]
plat/imx/imx7/warp7/warp7_trusted_boot.c [new file with mode: 0644]
plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
plat/imx/imx8m/imx8mq/platform.mk
plat/imx/imx8qm/imx8qm_bl31_setup.c
plat/imx/imx8qm/imx8qm_psci.c
plat/imx/imx8qm/include/platform_def.h
plat/imx/imx8qm/include/sec_rsrc.h
plat/imx/imx8qm/platform.mk
plat/imx/imx8qx/imx8qx_bl31_setup.c
plat/imx/imx8qx/imx8qx_psci.c
plat/imx/imx8qx/include/platform_def.h
plat/imx/imx8qx/include/sec_rsrc.h
plat/imx/imx8qx/platform.mk
plat/layerscape/common/ls_bl1_setup.c
plat/marvell/common/marvell_bl1_setup.c
plat/mediatek/mt8173/bl31_plat_setup.c
plat/mediatek/mt8173/plat_pm.c
plat/mediatek/mt8173/platform.mk
plat/nvidia/tegra/common/aarch64/tegra_helpers.S
plat/nvidia/tegra/common/drivers/bpmp/bpmp.c [new file with mode: 0644]
plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c [new file with mode: 0644]
plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h [new file with mode: 0644]
plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c [new file with mode: 0644]
plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h [new file with mode: 0644]
plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c [new file with mode: 0644]
plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
plat/nvidia/tegra/common/drivers/smmu/smmu.c
plat/nvidia/tegra/common/drivers/spe/shared_console.S [new file with mode: 0644]
plat/nvidia/tegra/common/lib/debug/profiler.c [new file with mode: 0644]
plat/nvidia/tegra/common/tegra_bl31_setup.c
plat/nvidia/tegra/common/tegra_common.mk
plat/nvidia/tegra/common/tegra_fiq_glue.c
plat/nvidia/tegra/common/tegra_platform.c
plat/nvidia/tegra/common/tegra_pm.c
plat/nvidia/tegra/common/tegra_sip_calls.c
plat/nvidia/tegra/common/tegra_topology.c
plat/nvidia/tegra/include/drivers/bpmp.h [new file with mode: 0644]
plat/nvidia/tegra/include/drivers/bpmp_ipc.h [new file with mode: 0644]
plat/nvidia/tegra/include/drivers/gpcdma.h [new file with mode: 0644]
plat/nvidia/tegra/include/drivers/memctrl.h
plat/nvidia/tegra/include/drivers/memctrl_v2.h
plat/nvidia/tegra/include/drivers/security_engine.h [new file with mode: 0644]
plat/nvidia/tegra/include/drivers/smmu.h
plat/nvidia/tegra/include/lib/profiler.h [new file with mode: 0644]
plat/nvidia/tegra/include/platform_def.h
plat/nvidia/tegra/include/t132/tegra_def.h
plat/nvidia/tegra/include/t186/tegra186_private.h [new file with mode: 0644]
plat/nvidia/tegra/include/t186/tegra_def.h
plat/nvidia/tegra/include/t186/tegra_mc_def.h [new file with mode: 0644]
plat/nvidia/tegra/include/t210/tegra_def.h
plat/nvidia/tegra/include/tegra_platform.h
plat/nvidia/tegra/include/tegra_private.h
plat/nvidia/tegra/platform.mk
plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
plat/nvidia/tegra/soc/t132/plat_setup.c
plat/nvidia/tegra/soc/t132/plat_sip_calls.c
plat/nvidia/tegra/soc/t132/platform_t132.mk
plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h
plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
plat/nvidia/tegra/soc/t186/plat_memctrl.c
plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
plat/nvidia/tegra/soc/t186/plat_secondary.c
plat/nvidia/tegra/soc/t186/plat_setup.c
plat/nvidia/tegra/soc/t186/plat_sip_calls.c
plat/nvidia/tegra/soc/t186/plat_smmu.c
plat/nvidia/tegra/soc/t186/plat_trampoline.S
plat/nvidia/tegra/soc/t186/platform_t186.mk
plat/nvidia/tegra/soc/t210/drivers/se/se_private.h [new file with mode: 0644]
plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c [new file with mode: 0644]
plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
plat/nvidia/tegra/soc/t210/plat_setup.c
plat/nvidia/tegra/soc/t210/platform_t210.mk
plat/qemu/qemu_private.h
plat/renesas/rcar/bl2_cpg_init.c
plat/renesas/rcar/include/rcar_def.h
plat/renesas/rcar/plat_pm.c
plat/renesas/rcar/platform.mk
plat/rockchip/common/rockchip_gicv2.c
plat/rockchip/rk3328/rk3328_def.h
plat/rockchip/rk3368/rk3368_def.h
plat/rpi3/platform.mk
plat/rpi3/rpi3_bl1_setup.c
plat/rpi3/rpi3_bl2_setup.c
plat/rpi3/rpi3_bl31_setup.c
plat/rpi3/rpi3_hw.h
plat/rpi3/rpi3_io_storage.c
plat/rpi3/rpi3_pm.c
plat/socionext/synquacer/include/plat.ld.S [new file with mode: 0644]
plat/socionext/synquacer/include/platform_def.h
plat/socionext/synquacer/platform.mk
plat/socionext/synquacer/sq_bl31_setup.c
plat/socionext/synquacer/sq_spm.c [new file with mode: 0644]
plat/st/stm32mp1/bl2_io_storage.c
plat/st/stm32mp1/bl2_plat_setup.c
plat/st/stm32mp1/include/platform_def.h
plat/st/stm32mp1/include/stm32mp1_dt.h
plat/st/stm32mp1/include/stm32mp1_private.h
plat/st/stm32mp1/include/stm32mp1_smc.h [new file with mode: 0644]
plat/st/stm32mp1/platform.mk
plat/st/stm32mp1/services/bsec_svc.c [new file with mode: 0644]
plat/st/stm32mp1/services/bsec_svc.h [new file with mode: 0644]
plat/st/stm32mp1/services/stm32mp1_svc_setup.c [new file with mode: 0644]
plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
plat/st/stm32mp1/sp_min/sp_min_setup.c
plat/st/stm32mp1/stm32mp1_common.c
plat/st/stm32mp1/stm32mp1_def.h
plat/st/stm32mp1/stm32mp1_dt.c
plat/st/stm32mp1/stm32mp1_gic.c
plat/st/stm32mp1/stm32mp1_helper.S
plat/st/stm32mp1/stm32mp1_pm.c
plat/st/stm32mp1/stm32mp1_security.c
plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
plat/ti/k3/common/drivers/ti_sci/ti_sci.c
plat/ti/k3/common/drivers/ti_sci/ti_sci.h
plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
plat/ti/k3/common/k3_bl31_setup.c
plat/ti/k3/common/k3_gicv3.c
plat/ti/k3/common/k3_psci.c
plat/ti/k3/common/plat_common.mk
plat/ti/k3/include/k3_gicv3.h
plat/ti/k3/include/platform_def.h
plat/xilinx/common/include/ipi.h [new file with mode: 0644]
plat/xilinx/common/include/pm_common.h [new file with mode: 0644]
plat/xilinx/common/include/pm_ipi.h [new file with mode: 0644]
plat/xilinx/common/ipi.c [new file with mode: 0644]
plat/xilinx/common/pm_service/pm_ipi.c [new file with mode: 0644]
plat/xilinx/zynqmp/aarch64/zynqmp_common.c
plat/xilinx/zynqmp/bl31_zynqmp_setup.c
plat/xilinx/zynqmp/include/plat_ipi.h [new file with mode: 0644]
plat/xilinx/zynqmp/include/plat_macros.S
plat/xilinx/zynqmp/include/plat_pm_common.h [new file with mode: 0644]
plat/xilinx/zynqmp/include/plat_private.h [new file with mode: 0644]
plat/xilinx/zynqmp/include/platform_def.h
plat/xilinx/zynqmp/include/zynqmp_def.h [new file with mode: 0644]
plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c
plat/xilinx/zynqmp/plat_psci.c
plat/xilinx/zynqmp/plat_startup.c
plat/xilinx/zynqmp/plat_zynqmp.c
plat/xilinx/zynqmp/platform.mk
plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
plat/xilinx/zynqmp/pm_service/pm_client.c
plat/xilinx/zynqmp/pm_service/pm_client.h
plat/xilinx/zynqmp/pm_service/pm_common.h [deleted file]
plat/xilinx/zynqmp/pm_service/pm_ipi.c [deleted file]
plat/xilinx/zynqmp/pm_service/pm_ipi.h [deleted file]
plat/xilinx/zynqmp/pm_service/pm_svc_main.c
plat/xilinx/zynqmp/sip_svc_setup.c
plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
plat/xilinx/zynqmp/zynqmp_def.h [deleted file]
plat/xilinx/zynqmp/zynqmp_ipi.c
plat/xilinx/zynqmp/zynqmp_ipi.h [deleted file]
plat/xilinx/zynqmp/zynqmp_private.h [deleted file]
readme.rst
services/spd/opteed/teesmc_opteed.h
services/spd/tlkd/tlkd_main.c
services/spd/trusty/smcall.h
services/spd/trusty/trusty.c
services/spd/tspd/tspd_main.c
services/std_svc/sdei/sdei_private.h
services/std_svc/spm_deprecated/aarch64/spm_helpers.S [deleted file]
services/std_svc/spm_deprecated/aarch64/spm_shim_exceptions.S [deleted file]
services/std_svc/spm_deprecated/spm.mk [deleted file]
services/std_svc/spm_deprecated/spm_main.c [deleted file]
services/std_svc/spm_deprecated/spm_private.h [deleted file]
services/std_svc/spm_deprecated/spm_setup.c [deleted file]
services/std_svc/spm_deprecated/spm_shim_private.h [deleted file]
services/std_svc/spm_deprecated/spm_xlat.c [deleted file]
services/std_svc/spm_mm/aarch64/spm_helpers.S [new file with mode: 0644]
services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S [new file with mode: 0644]
services/std_svc/spm_mm/spm.mk [new file with mode: 0644]
services/std_svc/spm_mm/spm_main.c [new file with mode: 0644]
services/std_svc/spm_mm/spm_private.h [new file with mode: 0644]
services/std_svc/spm_mm/spm_setup.c [new file with mode: 0644]
services/std_svc/spm_mm/spm_shim_private.h [new file with mode: 0644]
services/std_svc/spm_mm/spm_xlat.c [new file with mode: 0644]
services/std_svc/std_svc_setup.c
tools/fiptool/fiptool.c

index 3de7b3f6b195fe353d144ac24247c2467ef5bf48..4e606a2ca92dd3440cf9627f7a3ba7f83158297f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -242,6 +242,7 @@ TF_LDFLAGS          +=      --gc-sections
 TF_LDFLAGS             +=      $(TF_LDFLAGS_$(ARCH))
 
 DTC_FLAGS              +=      -I dts -O dtb
+DTC_CPPFLAGS           +=      -nostdinc -Iinclude -undef -x assembler-with-cpp
 
 ################################################################################
 # Common sources and include directories
@@ -584,7 +585,6 @@ $(eval $(call assert_boolean,CREATE_KEYS))
 $(eval $(call assert_boolean,CTX_INCLUDE_AARCH32_REGS))
 $(eval $(call assert_boolean,CTX_INCLUDE_FPREGS))
 $(eval $(call assert_boolean,DEBUG))
-$(eval $(call assert_boolean,DISABLE_PEDANTIC))
 $(eval $(call assert_boolean,DYN_DISABLE_AUTH))
 $(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING))
 $(eval $(call assert_boolean,ENABLE_AMU))
@@ -613,7 +613,7 @@ $(eval $(call assert_boolean,RESET_TO_BL31))
 $(eval $(call assert_boolean,SAVE_KEYS))
 $(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
 $(eval $(call assert_boolean,SPIN_ON_BL1_EXIT))
-$(eval $(call assert_boolean,SPM_DEPRECATED))
+$(eval $(call assert_boolean,SPM_MM))
 $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
 $(eval $(call assert_boolean,USE_COHERENT_MEM))
 $(eval $(call assert_boolean,USE_ROMLIB))
@@ -667,7 +667,7 @@ $(eval $(call add_define,RECLAIM_INIT_CODE))
 $(eval $(call add_define,SMCCC_MAJOR_VERSION))
 $(eval $(call add_define,SPD_${SPD}))
 $(eval $(call add_define,SPIN_ON_BL1_EXIT))
-$(eval $(call add_define,SPM_DEPRECATED))
+$(eval $(call add_define,SPM_MM))
 $(eval $(call add_define,TRUSTED_BOARD_BOOT))
 $(eval $(call add_define,USE_COHERENT_MEM))
 $(eval $(call add_define,USE_ROMLIB))
index bdbf80f32d1e4edc98db28bcfec7ed0c5c6b4a4d..927c7b8a2631f259ff4756ce7f58fcbbde3dc989 100644 (file)
@@ -9,16 +9,7 @@
 
 #include <stdint.h>
 
-#include <lib/utils_def.h>
-
-/*******************************************************************************
- * Declarations of linker defined symbols which will tell us where BL1 lives
- * in Trusted ROM and RAM
- ******************************************************************************/
-IMPORT_SYM(uintptr_t, __BL1_ROM_END__,   BL1_ROM_END);
-
-IMPORT_SYM(uintptr_t, __BL1_RAM_START__, BL1_RAM_BASE);
-IMPORT_SYM(uintptr_t, __BL1_RAM_END__,   BL1_RAM_LIMIT);
+#include <common/bl_common.h>
 
 /******************************************
  * Function prototypes
@@ -36,4 +27,5 @@ register_t bl1_fwu_smc_handler(unsigned int smc_fid,
                void *cookie,
                void *handle,
                unsigned int flags);
+
 #endif /* BL1_PRIVATE_H */
index 01f6c6bd2c83c3150d00add303bbbf7df9abe4ae..b1704d282f3f93749ad5d0a46afd16df838d4b6e 100644 (file)
@@ -7,22 +7,7 @@
 #ifndef BL2_PRIVATE_H
 #define BL2_PRIVATE_H
 
-#if BL2_IN_XIP_MEM
-
-#include <stdint.h>
-
-/*******************************************************************************
- * Declarations of linker defined symbols which will tell us where BL2 lives
- * in Trusted ROM and RAM
- ******************************************************************************/
-extern uintptr_t __BL2_ROM_END__;
-#define BL2_ROM_END (uintptr_t)(&__BL2_ROM_END__)
-
-extern uintptr_t __BL2_RAM_START__;
-extern uintptr_t __BL2_RAM_END__;
-#define BL2_RAM_BASE (uintptr_t)(&__BL2_RAM_START__)
-#define BL2_RAM_LIMIT (uintptr_t)(&__BL2_RAM_END__)
-#endif
+#include <common/bl_common.h>
 
 /******************************************
  * Forward declarations
index 5925e0ca0ce16ab03abefabd53f4e8337f52b30f..1af196209d3589f6dc62a0aed24ca83415eaf988 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -143,6 +143,10 @@ SECTIONS
            "cpu_ops not defined for this platform.")
 
 #if ENABLE_SPM
+#ifndef SPM_SHIM_EXCEPTIONS_VMA
+#define SPM_SHIM_EXCEPTIONS_VMA         RAM
+#endif
+
     /*
      * Exception vectors of the SPM shim layer. They must be aligned to a 2K
      * address, but we need to place them in a separate page so that we can set
@@ -156,7 +160,10 @@ SECTIONS
         *(.spm_shim_exceptions)
         . = ALIGN(PAGE_SIZE);
         __SPM_SHIM_EXCEPTIONS_END__ = .;
-    } >RAM
+    } >SPM_SHIM_EXCEPTIONS_VMA AT>RAM
+
+    PROVIDE(__SPM_SHIM_EXCEPTIONS_LMA__ = LOADADDR(spm_shim_exceptions));
+    . = LOADADDR(spm_shim_exceptions) + SIZEOF(spm_shim_exceptions);
 #endif
 
     /*
@@ -240,7 +247,7 @@ SECTIONS
          * Time-stamps are stored in normal .bss memory
          *
          * The compiler will allocate enough memory for one CPU's time-stamps,
-         * the remaining memory for other CPU's is allocated by the
+         * the remaining memory for other CPUs is allocated by the
          * linker script
          */
         . = ALIGN(CACHE_WRITEBACK_GRANULE);
index eddd164f39087d2cfd353c39e06e990e5de893fc..89f5896ac0fc3387762eb0dfdd9556cd13c73f68 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,12 +8,12 @@
 # Include SPM Makefile
 ################################################################################
 ifeq (${ENABLE_SPM},1)
-  ifeq (${SPM_DEPRECATED},1)
+  ifeq (${SPM_MM},1)
     ifeq (${EL3_EXCEPTION_HANDLING},0)
       $(error EL3_EXCEPTION_HANDLING must be 1 for SPM support)
     endif
-    $(info Including deprecated SPM makefile)
-    include services/std_svc/spm_deprecated/spm.mk
+    $(info Including makefile of SPM based on MM)
+    include services/std_svc/spm_mm/spm.mk
   else
     $(info Including SPM makefile)
     include services/std_svc/spm/spm.mk
index 927cda2f9f0d548d646ef71eb7e6d721b299b8ae..da35f75edab72e0a84fd8ac23cfa90e81c82c161 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -68,7 +68,7 @@ void __init bl31_lib_init(void)
  * before passing control to the bootloader or an Operating System. This
  * function calls runtime_svc_init() which initializes all registered runtime
  * services. The run time services would setup enough context for the core to
- * swtich to the next exception level. When this function returns, the core will
+ * switch to the next exception level. When this function returns, the core will
  * switch to the programmed exception level via. an ERET.
  ******************************************************************************/
 void bl31_main(void)
@@ -96,13 +96,13 @@ void bl31_main(void)
         * decide which is the next image (BL32 or BL33) and how to execute it.
         * If the SPD runtime service is present, it would want to pass control
         * to BL32 first in S-EL1. In that case, SPD would have registered a
-        * function to intialize bl32 where it takes responsibility of entering
+        * function to initialize bl32 where it takes responsibility of entering
         * S-EL1 and returning control back to bl31_main. Once this is done we
         * can prepare entry into BL33 as normal.
         */
 
        /*
-        * If SPD had registerd an init hook, invoke it.
+        * If SPD had registered an init hook, invoke it.
         */
        if (bl32_init != NULL) {
                INFO("BL31: Initializing BL32\n");
index ba9d3421213cf21b89328e3b873bb695a91f657a..3cd427d75248cf5b447a6ca27fe85f4241479996 100644 (file)
@@ -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
  */
@@ -167,7 +167,7 @@ SECTIONS
          * Time-stamps are stored in normal .bss memory
          *
          * The compiler will allocate enough memory for one CPU's time-stamps,
-         * the remaining memory for other CPU's is allocated by the
+         * the remaining memory for other CPUs is allocated by the
          * linker script
          */
         . = ALIGN(CACHE_WRITEBACK_GRANULE);
index 3cb19901f33cde93e270eff2b4ebcd516677ad1d..f39e33b6b57fa3eadcb00624d1b7f4288b0ca9ef 100644 (file)
@@ -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
  */
@@ -35,7 +35,7 @@ static void *sp_min_cpu_ctx_ptr[PLATFORM_CORE_COUNT];
 static smc_ctx_t sp_min_smc_context[PLATFORM_CORE_COUNT];
 
 /******************************************************************************
- * Define the smccc helper library API's
+ * Define the smccc helper library APIs
  *****************************************************************************/
 void *smc_get_ctx(unsigned int security_state)
 {
index 24efa6189d93c9e61eb4102788228c1332a107df..e042d96a09b788b091d87cec3e84f2ad595da358 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -362,7 +362,7 @@ tsp_args_t *tsp_smc_handler(uint64_t func,
 
        /*
         * Request a service back from dispatcher/secure monitor. This call
-        * return and thereafter resume exectuion
+        * return and thereafter resume execution
         */
        tsp_get_magic(service_args);
 
@@ -395,7 +395,7 @@ tsp_args_t *tsp_smc_handler(uint64_t func,
 }
 
 /*******************************************************************************
- * TSP smc abort handler. This function is called when aborting a preemtped
+ * TSP smc abort handler. This function is called when aborting a preempted
  * yielding SMC request. It should cleanup all resources owned by the SMC
  * handler such as locks or dynamically allocated memory so following SMC
  * request are executed in a clean environment.
index 35928634dcedb0f9b8996e20f580f69d0939fba9..d1ff2b0becce8c92200ca42ab6f04e671a1fa95a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,7 +80,7 @@ void tsp_generic_timer_save(void)
 }
 
 /*******************************************************************************
- * This function restores the timer context post cpu resummption
+ * This function restores the timer context post cpu resumption
  ******************************************************************************/
 void tsp_generic_timer_restore(void)
 {
index bf60a08a9bb2d883f31cac74cf5d055cd9ba4444..ecc65c92e1859e78c9c0a054be2b29cdf331c13c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -231,7 +231,7 @@ static void unwind_stack(struct frame_record *fr, uintptr_t current_pc,
  * Usage of the trace: addr2line can be used to map the addresses to function
  * and source code location when given the ELF file compiled with debug
  * information. The "-i" flag is highly recommended to improve display of
- * inlined function. The *.dump files generated when buildidng each image can
+ * inlined function. The *.dump files generated when building each image can
  * also be used.
  *
  * WARNING: In case of corrupted stack, this function could display security
index ada02f8dd66945969a230251c4d4bd07a6f64931..405bb83486efc863fa17ec216b8cbd15973fec6d 100644 (file)
@@ -20,11 +20,28 @@ static bl_params_t next_bl_params;
  ******************************************************************************/
 void flush_bl_params_desc(void)
 {
-       flush_dcache_range((uintptr_t)bl_mem_params_desc_ptr,
-                       sizeof(*bl_mem_params_desc_ptr) * bl_mem_params_desc_num);
+       flush_bl_params_desc_args(bl_mem_params_desc_ptr,
+               bl_mem_params_desc_num,
+               &next_bl_params);
+}
+
+/*******************************************************************************
+ * This function flushes the data structures specified as arguments so that they
+ * are visible in memory for the next BL image.
+ ******************************************************************************/
+void flush_bl_params_desc_args(bl_mem_params_node_t *mem_params_desc_ptr,
+       unsigned int mem_params_desc_num,
+       bl_params_t *next_bl_params_ptr)
+{
+       assert(mem_params_desc_ptr != NULL);
+       assert(mem_params_desc_num != 0U);
+       assert(next_bl_params_ptr != NULL);
+
+       flush_dcache_range((uintptr_t)mem_params_desc_ptr,
+               sizeof(*mem_params_desc_ptr) * mem_params_desc_num);
 
-       flush_dcache_range((uintptr_t)&next_bl_params,
-                       sizeof(next_bl_params));
+       flush_dcache_range((uintptr_t)next_bl_params_ptr,
+                       sizeof(*next_bl_params_ptr));
 }
 
 /*******************************************************************************
index c934824809ad9fdab9e5487c2bcfcbf0807ba00c..e0b569f31b1e7ad0169d203360abe247241f0d6e 100644 (file)
@@ -160,7 +160,7 @@ These components are responsible for initiating the authentication process for a
 particular image in BL1 or BL2. For each BL image that requires authentication,
 the Generic code asks recursively the Authentication module what is the parent
 image until either an authenticated image or the ROT is reached. Then the
-Generic code calls the IO framewotk to load the image and calls the
+Generic code calls the IO framework to load the image and calls the
 Authentication module to authenticate it, following the CoT from ROT to Image.
 
 TF-A Platform Port (PP)
@@ -422,7 +422,7 @@ An IPL for each type must be registered using the following macro:
 -  ``_name``: a string containing the IPL name for debugging purposes.
 -  ``_init``: initialization function pointer.
 -  ``_check_int``: check image integrity function pointer.
--  ``_get_param``: extract authentication parameter funcion pointer.
+-  ``_get_param``: extract authentication parameter function pointer.
 
 The ``init()`` function will be used to initialize the IPL.
 
@@ -925,7 +925,7 @@ three functions:
 The mbedTLS library algorithm support is configured by the
 ``TF_MBEDTLS_KEY_ALG`` variable which can take in 3 values: `rsa`, `ecdsa` or
 `rsa+ecdsa`. This variable allows the Makefile to include the corresponding
-sources in the build for the various algorthms. Setting the variable to
+sources in the build for the various algorithms. Setting the variable to
 `rsa+ecdsa` enables support for both rsa and ecdsa algorithms in the mbedTLS
 library.
 
index d329e83641ba62860597f874b2456aa8cd998e9b..11fcf2186c669b3675de0d2fd8cee62d3a70ce3c 100644 (file)
@@ -10,7 +10,7 @@ Trusted Firmware-A - version 2.0
 New Features
 ------------
 
--  Removal of a number of deprecated API's
+-  Removal of a number of deprecated APIs
 
    -  A new Platform Compatibility Policy document has been created which
       references a wiki page that maintains a listing of deprecated
@@ -20,7 +20,7 @@ New Features
       from the code base.
 
    -  Various Arm and partner platforms have been updated to remove the use of
-      removed API's in this release.
+      removed APIs in this release.
 
    -  This release is otherwise unchanged from 1.6 release
 
@@ -130,7 +130,7 @@ New Features
       the clang linker is not used because it is unable to link TF-A objects
       due to immaturity of clang linker functionality at this time.
 
--  Refactor support API's into Libraries
+-  Refactor support APIs into Libraries
 
    -  Evolve libfdt, mbed TLS library and standard C library sources as
       proper libraries that TF-A may be linked against.
@@ -435,7 +435,7 @@ New features
 
    -  Introduced APIs to get and set the memory attributes of a region.
 
-   -  Added support to manage both priviledge levels in translation regimes that
+   -  Added support to manage both privilege levels in translation regimes that
       describe translations for 2 Exception levels, specifically the EL1&0
       translation regime, and extended the memory map region attributes to
       include specifying Non-privileged access.
@@ -683,7 +683,7 @@ New features
 -  Enhancements to Firmware Update feature:
 
    -  The FWU logic now checks for overlapping images to prevent execution of
-      unauthenticated arbitary code.
+      unauthenticated arbitrary code.
 
    -  Introduced new FWU_SMC_IMAGE_RESET SMC that changes the image loading
       state machine to go from COPYING, COPIED or AUTHENTICATED states to
@@ -855,7 +855,7 @@ New features
 
    -  Essential control registers are fully initialised on EL3 start-up, when
       initialising the non-secure and secure context structures and when
-      preparing to leave EL3 for a lower EL. This gives better alignement with
+      preparing to leave EL3 for a lower EL. This gives better alignment with
       the Arm ARM which states that software must initialise RES0 and RES1
       fields with 0 / 1.
 
@@ -1345,7 +1345,7 @@ New features
 -  It is now possible to specify the name of the FIP at build time by defining
    the ``FIP_NAME`` variable.
 
--  Issues with depedencies on the 'fiptool' makefile target have been
+-  Issues with dependencies on the 'fiptool' makefile target have been
    rectified. The ``fip_create`` tool is now rebuilt whenever its source files
    change.
 
@@ -1376,7 +1376,7 @@ New features
       the secure world. This can be done by setting the build flag
       ``FVP_TSP_RAM_LOCATION`` to the value ``dram``.
 
--  Separate transation tables are created for each boot loader image. The
+-  Separate translation tables are created for each boot loader image. The
    ``IMAGE_BLx`` build options are used to do this. This allows each stage to
    create mappings only for areas in the memory map that it needs.
 
@@ -1530,7 +1530,7 @@ New features
    -  Clarified the platform porting interface to the TSP.
 
    -  Reworked the TSPD setup code to support the alternate BL3-2
-      intialization flow where BL3-1 generic code hands control to BL3-2,
+      initialization flow where BL3-1 generic code hands control to BL3-2,
       rather than expecting the TSPD to hand control directly to BL3-2.
 
    -  Considerable rework to PSCI generic code to support CPU specific
@@ -1569,7 +1569,7 @@ Issues resolved since last release
 
 -  Removed the concept of top/bottom image loading. The image loader now
    automatically detects the position of the image inside the current memory
-   layout and updates the layout to minimize fragementation. This resolves the
+   layout and updates the layout to minimize fragmentation. This resolves the
    image loader limitations of previously releases. There are currently no
    plans to support dynamic image loading.
 
diff --git a/docs/coding-guidelines.rst b/docs/coding-guidelines.rst
new file mode 100644 (file)
index 0000000..5a30e91
--- /dev/null
@@ -0,0 +1,553 @@
+Trusted Firmware-A Coding Guidelines
+====================================
+
+.. section-numbering::
+    :suffix: .
+
+.. contents::
+
+The following sections contain TF coding guidelines. They are continually
+evolving and should not be considered "set in stone". Feel free to question them
+and provide feedback.
+
+Some of the guidelines may also apply to other codebases.
+
+**Note:** the existing TF codebase does not necessarily comply with all the
+below guidelines but the intent is for it to do so eventually.
+
+Checkpatch overrides
+--------------------
+
+Some checkpatch warnings in the TF codebase are deliberately ignored. These
+include:
+
+- ``**WARNING: line over 80 characters**``: Although the codebase should
+  generally conform to the 80 character limit this is overly restrictive in some
+  cases.
+
+- ``**WARNING: Use of volatile is usually wrong``: see
+  `Why the “volatile” type class should not be used`_ . Although this document
+  contains some very useful information, there are several legimate uses of the
+  volatile keyword within the TF codebase.
+
+Headers and inclusion
+---------------------
+
+Header guards
+^^^^^^^^^^^^^
+
+For a header file called "some_driver.h" the style used by the Trusted Firmware
+is:
+
+.. code:: c
+
+  #ifndef SOME_DRIVER_H
+  #define SOME_DRIVER_H
+
+  <header content>
+
+  #endif /* SOME_DRIVER_H */
+
+Include statement ordering
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+All header files that are included by a source file must use the following,
+grouped ordering. This is to improve readability (by making it easier to quickly
+read through the list of headers) and maintainability.
+
+#. *System* includes: Header files from the standard *C* library, such as
+   ``stddef.h`` and ``string.h``.
+
+#. *Project* includes: Header files under the ``include/`` directory within TF
+   are *project* includes.
+
+#. *Platform* includes: Header files relating to a single, specific platform,
+   and which are located under the ``plat/<platform_name>`` directory within TF,
+   are *platform* includes.
+
+Within each group, ``#include`` statements must be in alphabetical order,
+taking both the file and directory names into account.
+
+Groups must be separated by a single blank line for clarity.
+
+The example below illustrates the ordering rules using some contrived header
+file names; this type of name reuse should be otherwise avoided.
+.. code:: c
+
+  #include <string.h>
+
+  #include <a_dir/example/a_header.h>
+  #include <a_dir/example/b_header.h>
+  #include <a_dir/test/a_header.h>
+  #include <b_dir/example/a_header.h>
+
+  #include "./a_header.h"
+
+Include statement variants
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Two variants of the ``#include`` directive are acceptable in the TF codebase.
+Correct use of the two styles improves readability by suggesting the location
+of the included header and reducing ambiguity in cases where generic and
+platform-specific headers share a name.
+
+For header files that are in the same directory as the source file that is
+including them, use the ``"..."`` variant.
+
+For header files that are **not** in the same directory as the source file that
+is including them, use the ``<...>`` variant.
+
+Example (bl1_fwu.c):
+.. code:: c
+
+  #include <assert.h>
+  #include <errno.h>
+  #include <string.h>
+
+  #include "bl1_private.h"
+
+Platform include paths
+^^^^^^^^^^^^^^^^^^^^^^
+
+Platforms are allowed to add more include paths to be passed to the compiler.
+The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in
+particular for the file ``platform_def.h``.
+
+Example:
+.. code:: c
+
+  PLAT_INCLUDES  += -Iinclude/plat/myplat/include
+
+Types and typedefs
+------------------
+
+Use of built-in *C* and *libc* data types
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The TF codebase should be kept as portable as possible, especially since both
+64-bit and 32-bit platforms are supported. To help with this, the following data
+type usage guidelines should be followed:
+
+- Where possible, use the built-in *C* data types for variable storage (for
+  example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
+  types. Most code is typically only concerned with the minimum size of the
+  data stored, which the built-in *C* types guarantee.
+
+- Avoid using the exact-size standard *C99* types in general (for example,
+  ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
+  compiler from making optimizations. There are legitimate uses for them,
+  for example to represent data of a known structure. When using them in struct
+  definitions, consider how padding in the struct will work across architectures.
+  For example, extra padding may be introduced in AArch32 systems if a struct
+  member crosses a 32-bit boundary.
+
+- Use ``int`` as the default integer type - it's likely to be the fastest on all
+  systems. Also this can be assumed to be 32-bit as a consequence of the
+  `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
+  Standard for the Arm 64-bit Architecture`_ .
+
+- Avoid use of ``short`` as this may end up being slower than ``int`` in some
+  systems. If a variable must be exactly 16-bit, use ``int16_t`` or
+  ``uint16_t``.
+
+- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
+  that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
+  at least 64-bit, use ``long long``.
+
+- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
+
+- Use ``unsigned`` for integers that can never be negative (counts,
+  indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
+  rules (10.X), where signed and unsigned types are considered different
+  essential types. Choosing the correct type will aid this. MISRA static
+  analysers will pick up any implicit signed/unsigned conversions that may lead
+  to unexpected behaviour.
+
+- For pointer types:
+
+  - If an argument in a function declaration is pointing to a known type then
+    simply use a pointer to that type (for example: ``struct my_struct *``).
+
+  - If a variable (including an argument in a function declaration) is pointing
+    to a general, memory-mapped address, an array of pointers or another
+    structure that is likely to require pointer arithmetic then use
+    ``uintptr_t``. This will reduce the amount of casting required in the code.
+    Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
+    may work but is less portable.
+
+  - For other pointer arguments in a function declaration, use ``void *``. This
+    includes pointers to types that are abstracted away from the known API and
+    pointers to arbitrary data. This allows the calling function to pass a
+    pointer argument to the function without any explicit casting (the cast to
+    ``void *`` is implicit). The function implementation can then do the
+    appropriate casting to a specific type.
+
+  - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
+
+- Use ``size_t`` when storing the ``sizeof()`` something.
+
+- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
+  can also return an error code; the signed type allows for a negative return
+  code in case of error. This practice should be used sparingly.
+
+- Use ``u_register_t`` when it's important to store the contents of a register
+  in its native size (32-bit in AArch32 and 64-bit in AArch64). This is not a
+  standard *C99* type but is widely available in libc implementations,
+  including the FreeBSD version included with the TF codebase. Where possible,
+  cast the variable to a more appropriate type before interpreting the data. For
+  example, the following struct in ``ep_info.h`` could use this type to minimize
+  the storage required for the set of registers:
+
+.. code:: c
+
+    typedef struct aapcs64_params {
+            u_register_t arg0;
+            u_register_t arg1;
+            u_register_t arg2;
+            u_register_t arg3;
+            u_register_t arg4;
+            u_register_t arg5;
+            u_register_t arg6;
+            u_register_t arg7;
+    } aapcs64_params_t;
+
+
+    If some code wants to operate on ``arg0`` and knows that it represents a
+    32-bit unsigned integer on all systems, cast it to ``unsigned int``.
+
+These guidelines should be updated if additional types are needed.
+
+Avoid anonymous typedefs of structs/enums in headers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, the following definition:
+
+.. code:: c
+
+  typedef struct {
+          int arg1;
+          int arg2;
+  } my_struct_t;
+
+
+is better written as:
+
+.. code:: c
+
+  struct my_struct {
+          int arg1;
+          int arg2;
+  };
+
+This allows function declarations in other header files that depend on the
+struct/enum to forward declare the struct/enum instead of including the
+entire header:
+
+.. code:: c
+
+  #include <my_struct.h>
+  void my_func(my_struct_t *arg);
+
+instead of:
+
+.. code:: c
+
+  struct my_struct;
+  void my_func(struct my_struct *arg);
+
+Some TF definitions use both a struct/enum name **and** a typedef name. This
+is discouraged for new definitions as it makes it difficult for TF to comply
+with MISRA rule 8.3, which states that "All declarations of an object or
+function shall use the same names and type qualifiers".
+
+The Linux coding standards also discourage new typedefs and checkpatch emits
+a warning for this.
+
+Existing typedefs will be retained for compatibility.
+
+Error handling and robustness
+-----------------------------
+
+Using CASSERT to check for compile time data errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Where possible, use the ``CASSERT`` macro to check the validity of data known at
+compile time instead of checking validity at runtime, to avoid unnecessary
+runtime code.
+
+For example, this can be used to check that the assembler's and compiler's views
+of the size of an array is the same.
+
+.. code:: c
+
+  #include <cassert.h>
+
+  define MY_STRUCT_SIZE 8 /* Used by assembler source files */
+
+  struct my_struct {
+      uint32_t arg1;
+      uint32_t arg2;
+  };
+
+  CASSERT(MY_STRUCT_SIZE == sizeof(struct my_struct), assert_my_struct_size_mismatch);
+
+
+If ``MY_STRUCT_SIZE`` in the above example were wrong then the compiler would
+emit an error like this:
+
+.. code:: c
+
+  my_struct.h:10:1: error: size of array ‘assert_my_struct_size_mismatch’ is negative
+
+
+Using assert() to check for programming errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In general, each secure world TF image (BL1, BL2, BL31 and BL32) should be
+treated as a tightly integrated package; the image builder should be aware of
+and responsible for all functionality within the image, even if code within that
+image is provided by multiple entities. This allows us to be more aggressive in
+interpreting invalid state or bad function arguments as programming errors using
+``assert()``, including arguments passed across platform porting interfaces.
+This is in contrast to code in a Linux environment, which is less tightly
+integrated and may attempt to be more defensive by passing the error back up the
+call stack.
+
+Where possible, badly written TF code should fail early using ``assert()``. This
+helps reduce the amount of untested conditional code. By default these
+statements are not compiled into release builds, although this can be overridden
+using the ``ENABLE_ASSERTIONS`` build flag.
+
+Examples:
+
+- Bad argument supplied to library function
+- Bad argument provided by platform porting function
+- Internal secure world image state is inconsistent
+
+
+Handling integration errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Each secure world image may be provided by a different entity (for example, a
+Trusted Boot vendor may provide the BL2 image, a TEE vendor may provide the BL32
+image and the OEM/SoC vendor may provide the other images).
+
+An image may contain bugs that are only visible when the images are integrated.
+The system integrator may not even have access to the debug variants of all the
+images in order to check if asserts are firing. For example, the release variant
+of BL1 may have already been burnt into the SoC. Therefore, TF code that detects
+an integration error should _not_ consider this a programming error, and should
+always take action, even in release builds.
+
+If an integration error is considered non-critical it should be treated as a
+recoverable error. If the error is considered critical it should be treated as
+an unexpected unrecoverable error.
+
+Handling recoverable errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **must not** crash when supplied with bad data from an external
+source. For example, data from the normal world or a hardware device. Similarly,
+the secure world **must not** crash if it detects a non-critical problem within
+itself or the system. It must make every effort to recover from the problem by
+emitting a ``WARN`` message, performing any necessary error handling and
+continuing.
+
+Examples:
+
+- Secure world receives SMC from normal world with bad arguments.
+- Secure world receives SMC from normal world at an unexpected time.
+- BL31 receives SMC from BL32 with bad arguments.
+- BL31 receives SMC from BL32 at unexpected time.
+- Secure world receives recoverable error from hardware device. Retrying the
+  operation may help here.
+- Non-critical secure world service is not functioning correctly.
+- BL31 SPD discovers minor configuration problem with corresponding SP.
+
+Handling unrecoverable errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In some cases it may not be possible for the secure world to recover from an
+error. This situation should be handled in one of the following ways:
+
+1. If the unrecoverable error is unexpected then emit an ``ERROR`` message and
+   call ``panic()``. This will end up calling the platform-specific function
+   ``plat_panic_handler()``.
+2. If the unrecoverable error is expected to occur in certain circumstances,
+   then emit an ``ERROR`` message and call the platform-specific function
+   ``plat_error_handler()``.
+
+Cases 1 and 2 are subtly different. A platform may implement ``plat_panic_handler``
+and ``plat_error_handler`` in the same way (for example, by waiting for a secure
+watchdog to time-out or by invoking an interface on the platform's power
+controller to reset the platform). However, ``plat_error_handler`` may take
+additional action for some errors (for example, it may set a flag so the
+platform resets into a different mode). Also, ``plat_panic_handler()`` may
+implement additional debug functionality (for example, invoking a hardware
+breakpoint).
+
+Examples of unexpected unrecoverable errors:
+
+- BL32 receives an unexpected SMC response from BL31 that it is unable to
+  recover from.
+- BL31 Trusted OS SPD code discovers that BL2 has not loaded the corresponding
+  Trusted OS, which is critical for platform operation.
+- Secure world discovers that a critical hardware device is an unexpected and
+  unrecoverable state.
+- Secure world receives an unexpected and unrecoverable error from a critical
+  hardware device.
+- Secure world discovers that it is running on unsupported hardware.
+
+Examples of expected unrecoverable errors:
+
+- BL1/BL2 fails to load the next image due to missing/corrupt firmware on disk.
+- BL1/BL2 fails to authenticate the next image due to an invalid certificate.
+- Secure world continuously receives recoverable errors from a hardware device
+  but is unable to proceed without a valid response.
+
+Handling critical unresponsiveness
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If the secure world is waiting for a response from an external source (for
+example, the normal world or a hardware device) which is critical for continued
+operation, it must not wait indefinitely. It must have a mechanism (for example,
+a secure watchdog) for resetting itself and/or the external source to prevent
+the system from executing in this state indefinitely.
+
+Examples:
+
+- BL1 is waiting for the normal world to raise an SMC to proceed to the next
+  stage of the secure firmware update process.
+- A Trusted OS is waiting for a response from a proxy in the normal world that
+  is critical for continued operation.
+- Secure world is waiting for a hardware response that is critical for continued
+  operation.
+
+Security considerations
+-----------------------
+
+Part of the security of a platform is handling errors correctly, as described in
+the previous section. There are several other security considerations covered in
+this section.
+
+Do not leak secrets to the normal world
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **must not** leak secrets to the normal world, for example in
+response to an SMC.
+
+Handling Denial of Service attacks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **should never** crash or become unusable due to receiving too
+many normal world requests (a *Denial of Service* or *DoS* attack). It should
+have a mechanism for throttling or ignoring normal world requests.
+
+Performance considerations
+--------------------------
+
+Avoid printf and use logging macros
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
+which wrap ``tf_log`` and which allow the logging call to be compiled-out
+depending on the ``make`` command. Use these macros to avoid print statements
+being compiled unconditionally into the binary.
+
+Each logging macro has a numerical log level:
+
+.. code:: c
+
+  #define LOG_LEVEL_NONE    0
+  #define LOG_LEVEL_ERROR   10
+  #define LOG_LEVEL_NOTICE  20
+  #define LOG_LEVEL_WARNING 30
+  #define LOG_LEVEL_INFO    40
+  #define LOG_LEVEL_VERBOSE 50
+
+
+By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
+be compiled into debug builds and all statements with a log level
+``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
+overridden from the command line or by the platform makefile (although it may be
+necessary to clean the build directory first). For example, to enable
+``VERBOSE`` logging on FVP:
+
+``make PLAT=fvp LOG_LEVEL=50 all``
+
+Use const data where possible
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, the following code:
+
+.. code:: c
+
+  struct my_struct {
+          int arg1;
+          int arg2;
+  };
+
+  void init(struct my_struct *ptr);
+
+  void main(void)
+  {
+          struct my_struct x;
+          x.arg1 = 1;
+          x.arg2 = 2;
+          init(&x);
+  }
+
+is better written as:
+
+.. code:: c
+
+  struct my_struct {
+          int arg1;
+          int arg2;
+  };
+
+  void init(const struct my_struct *ptr);
+
+  void main(void)
+  {
+          const struct my_struct x = { 1, 2 };
+          init(&x);
+  }
+
+This allows the linker to put the data in a read-only data section instead of a
+writeable data section, which may result in a smaller and faster binary. Note
+that this may require dependent functions (``init()`` in the above example) to
+have ``const`` arguments, assuming they don't need to modify the data.
+
+Library and driver code
+-----------------------
+
+TF library code (under ``lib/`` and ``include/lib``) is any code that provides a
+reusable interface to other code, potentially even to code outside of TF.
+
+In some systems drivers must conform to a specific driver framework to provide
+services to the rest of the system. TF has no driver framework and the
+distinction between a driver and library is somewhat subjective.
+
+A driver (under ``drivers/`` and ``include/drivers/``) is defined as code that
+interfaces with hardware via a memory mapped interface.
+
+Some drivers (for example, the Arm CCI driver in ``include/drivers/arm/cci.h``)
+provide a general purpose API to that specific hardware. Other drivers (for
+example, the Arm PL011 console driver in ``drivers/arm/pl011/pl011_console.S``)
+provide a specific hardware implementation of a more abstract library API. In
+the latter case there may potentially be multiple drivers for the same hardware
+device.
+
+Neither libraries nor drivers should depend on platform-specific code. If they
+require platform-specific data (for example, a base address) to operate then
+they should provide an initialization function that takes the platform-specific
+data as arguments.
+
+TF common code (under ``common/`` and ``include/common/``) is code that is re-used
+by other generic (non-platform-specific) TF code. It is effectively internal
+library code.
+
+.. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html
+.. _`Procedure Call Standard for the Arm Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
+.. _`Procedure Call Standard for the Arm 64-bit Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
index 21a4d53a6e505d3aba8525639932784864f4f906..06fdbacdd2f248582ddfc54cbf46b1acd3988150 100644 (file)
@@ -203,7 +203,7 @@ BL1 performs minimal architectural initialization as follows.
 
    The ``plat_report_exception()`` implementation on the Arm FVP port programs
    the Versatile Express System LED register in the following format to
-   indicate the occurence of an unexpected exception:
+   indicate the occurrence of an unexpected exception:
 
    ::
 
@@ -1684,6 +1684,21 @@ an example.
 Note: Loading the BL32 image in TZC secured DRAM doesn't change the memory
 layout of the other images in Trusted SRAM.
 
+CONFIG section in memory layouts shown below contains:
+
+::
+
+    +--------------------+
+    |bl2_mem_params_descs|
+    |--------------------|
+    |     fw_configs     |
+    +--------------------+
+
+``bl2_mem_params_descs`` contains parameters passed from BL2 to next the
+BL image during boot.
+
+``fw_configs`` includes soc_fw_config, tos_fw_config and tb_fw_config.
+
 **FVP with TSP in Trusted SRAM with firmware configs :**
 (These diagrams only cover the AArch64 case)
 
@@ -1708,7 +1723,7 @@ layout of the other images in Trusted SRAM.
                |          |  <<<<<<<<<<<<<  |----------------|
                |          |  <<<<<<<<<<<<<  |     BL32       |
     0x04002000 +----------+                 +----------------+
-               |fw_configs|
+               |  CONFIG  |
     0x04001000 +----------+
                |  Shared  |
     0x04000000 +----------+
@@ -1745,7 +1760,7 @@ layout of the other images in Trusted SRAM.
                |              |  <<<<<<<<<<<<<  | BL31 PROGBITS  |
                |              |                 +----------------+
                +--------------+
-               |  fw_configs  |
+               |    CONFIG    |
     0x04001000 +--------------+
                |    Shared    |
     0x04000000 +--------------+
@@ -1779,7 +1794,7 @@ layout of the other images in Trusted SRAM.
                |          |  <<<<<<<<<<<<<  | BL31 PROGBITS  |
                |          |                 +----------------+
     0x04002000 +----------+
-               |fw_configs|
+               |  CONFIG  |
     0x04001000 +----------+
                |  Shared  |
     0x04000000 +----------+
@@ -1991,7 +2006,7 @@ Coherent memory usage in PSCI implementation
 The ``psci_non_cpu_pd_nodes`` data structure stores the platform's power domain
 tree information for state management of power domains. By default, this data
 structure is allocated in the coherent memory region in TF-A because it can be
-accessed by multple CPUs, either with caches enabled or disabled.
+accessed by multiple CPUs, either with caches enabled or disabled.
 
 .. code:: c
 
@@ -2031,7 +2046,7 @@ cache lines after these fields are written.
 
 The field ``local_state`` can be concurrently accessed by multiple CPUs in
 different cache states. A Lamport's Bakery lock ``psci_locks`` is used to ensure
-mutual exlusion to this field and a clean and invalidate is needed after it
+mutual exclusion to this field and a clean and invalidate is needed after it
 is written.
 
 Bakery lock data
@@ -2225,7 +2240,7 @@ appropriately map the code region as executable and the read-only data as
 execute-never.
 
 This has an impact on memory footprint, as padding bytes need to be introduced
-between the code and read-only data to ensure the segragation of the two. To
+between the code and read-only data to ensure the segregation of the two. To
 limit the memory cost, this flag also changes the memory layout such that the
 code and exception vectors are now contiguous, like so:
 
@@ -2352,12 +2367,12 @@ has finished and be used for runtime data.
 
 The build option ``RECLAIM_INIT_CODE`` can be set to mark this boot time code
 with a ``.text.init.*`` attribute which can be filtered and placed suitably
-within the BL image for later reclaimation by the platform. The platform can
-specify the fiter and the memory region for this init section in BL31 via the
+within the BL image for later reclamation by the platform. The platform can
+specify the filter and the memory region for this init section in BL31 via the
 plat.ld.S linker script. For example, on the FVP, this section is placed
 overlapping the secondary CPU stacks so that after the cold boot is done, this
 memory can be reclaimed for the stacks. The init memory section is initially
-mapped with ``RO``, ``EXECUTE`` attributes. After BL31 initilization has
+mapped with ``RO``, ``EXECUTE`` attributes. After BL31 initialization has
 completed, the FVP changes the attributes of this section to ``RW``,
 ``EXECUTE_NEVER`` allowing it to be used for runtime data. The memory attributes
 are changed within the ``bl31_plat_runtime_setup`` platform hook. The init
@@ -2553,7 +2568,7 @@ extension is mandatory to support the TF-A bootloader and runtime services.
 
 Platform implementing an Armv7-A system can to define from its target
 Cortex-A architecture through ``ARM_CORTEX_A<X> = yes`` in their
-``plaform.mk`` script. For example ``ARM_CORTEX_A15=yes`` for a
+``platform.mk`` script. For example ``ARM_CORTEX_A15=yes`` for a
 Cortex-A15 target.
 
 Platform can also set ``ARM_WITH_NEON=yes`` to enable neon support.
index e10e148a5adb64339a7dc1cb5dc5ecd4ff46680f..3ee57bcbb055c42ed23bf36f9a2a01a492a49fdf 100644 (file)
@@ -266,14 +266,14 @@ FWU\_SMC\_IMAGE\_AUTH
         if (image_id is invalid) return -EPERM
         if (secure world caller)
             if (image_id state is not RESET) return -EPERM
-            if (image_addr/image_size is not mappped into BL1) return -ENOMEM
+            if (image_addr/image_size is not mapped into BL1) return -ENOMEM
         else // normal world caller
             if (image_id is secure image)
                 if (image_id state is not COPIED) return -EPERM
             else // image_id is non-secure image
                 if (image_id state is not RESET) return -EPERM
                 if (image_addr/image_size is in secure memory) return -ENOMEM
-                if (image_addr/image_size not mappped into BL1) return -ENOMEM
+                if (image_addr/image_size not mapped into BL1) return -ENOMEM
 
 This SMC authenticates the image specified by ``image_id``. If the image is in the
 RESET state, BL1 authenticates the image in place using the provided
index 56dfacfc89d40493dd2ddcff126fb639e2280aa5..90d2ae132b2d3c618379608dae472b34ccb2358f 100644 (file)
@@ -80,6 +80,10 @@ uint64\_t tzdram\_size;
 uint64\_t tzdram\_base;
 /* UART port ID \*/
 int uart\_id;
+/* L2 ECC parity protection disable flag \*/
+int l2\_ecc\_parity\_prot\_dis;
+/* SHMEM base address for storing the boot logs \*/
+uint64\_t boot\_profiler\_shmem\_base;
 } plat\_params\_from\_bl2\_t;
 
 Power Management
index 51c2609bab18bfeffe4f47559780ef9bb76ed9b2..6c04d91ec3399c9299cc75e0f6ea9a7de921b344 100644 (file)
@@ -31,36 +31,84 @@ https://git.linaro.org/landing-teams/working/mbl/u-boot.git
     make warp7_bl33_defconfig;
     make u-boot.imx arch=ARM CROSS_COMPILE=arm-linux-gnueabihf-
 
-## TF-A:
+## OP-TEE:
 
-https://github.com/ARM-software/arm-trusted-firmware.git
+https://github.com/OP-TEE/optee_os.git
 
 .. code:: shell
 
-    make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=warp7 ARCH=aarch32 ARM_ARCH_MAJOR=7 ARM_CORTEX_A7=yes AARCH32_SP=optee all
-    /path/to/u-boot/tools/mkimage -n /path/to/u-boot/u-boot.cfgout -T imximage -e 0x9df00000 -d ./build/warp7/debug/bl2.bin ./build/warp7/debug/bl2.bin.imx
+    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- PLATFORM=imx PLATFORM_FLAVOR=mx7swarp7 ARCH=arm CFG_PAGEABLE_ADDR=0 CFG_DT_ADDR=0x83000000 CFG_NS_ENTRY_ADDR=0x87800000
 
-## OP-TEE:
+## TF-A:
 
-https://github.com/OP-TEE/optee_os.git
+https://github.com/ARM-software/arm-trusted-firmware.git
 
-.. code:: shell
+The following commands assume that a directory exits in the top-level TFA build
+directory "fiptool_images". "fiptool_images" contains
 
-    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- PLATFORM=imx PLATFORM_FLAVOR=mx7swarp7 ARCH=arm CFG_PAGEABLE_ADDR=0 CFG_DT_ADDR=0x83000000 CFG_NS_ENTRY_ADDR=0x87800000
+- u-boot.bin
+  The binary output from the u-boot instructions above
 
+- tee-header_v2.bin
+- tee-pager_v2.bin
+- tee-pageable_v2.bin
+  Binary outputs from the previous OPTEE build steps
 
-## FIP:
+It is also assumed copy of mbedtls is available on the path path ../mbedtls
+  https://github.com/ARMmbed/mbedtls.git
+  At the time of writing HEAD points to 0592ea772aee48ca1e6d9eb84eca8e143033d973
 
 .. code:: shell
 
     mkdir fiptool_images
-    cp /path/to/uboot/u-boot.bin fiptool_images
     cp /path/to/optee/out/arm-plat-imx/core/tee-header_v2.bin fiptool_images
     cp /path/to/optee/out/arm-plat-imx/core/tee-pager_v2.bin fiptool_images
     cp /path/to/optee/out/arm-plat-imx/core/tee-pageable_v2.bin fiptool_images
+
+    make CROSS_COMPILE=${CROSS_COMPILE} PLAT=warp7 ARCH=aarch32 ARM_ARCH_MAJOR=7 \
+         ARM_CORTEX_A7=yes AARCH32_SP=optee PLAT_WARP7_UART=1 GENERATE_COT=1 \
+         TRUSTED_BOARD_BOOT=1 USE_TBBR_DEFS=1 MBEDTLS_DIR=../mbedtls \
+         NEED_BL32=yes BL32=fiptool_images/tee-header_v2.bin \
+         BL32_EXTRA1=fiptool_images/tee-pager_v2.bin \
+         BL32_EXTRA2=fiptool_images/tee-pageable_v2.bin \
+         BL33=fiptool_images/u-boot.bin certificates all
+
+    /path/to/u-boot/tools/mkimage -n /path/to/u-boot/u-boot.cfgout -T imximage -e 0x9df00000 -d ./build/warp7/debug/bl2.bin ./build/warp7/debug/bl2.bin.imx
+
+## FIP:
+
+.. code:: shell
+
+    cp /path/to/uboot/u-boot.bin fiptool_images
     cp /path/to/linux/arch/boot/dts/imx7s-warp.dtb fiptool_images
-    tools/fiptool/fiptool create --tos-fw fiptool_images/tee-header_v2.bin --tos-fw-extra1 fiptool_images/tee-pager_v2.bin --tos-fw-extra2 fiptool_images/tee-pageable_v2.bin --nt-fw fiptool_images/u-boot.bin --hw-config fiptool_images/imx7s-warp.dtb warp7.fip
 
+    tools/cert_create/cert_create -n --rot-key "build/warp7/debug/rot_key.pem" \
+               --tfw-nvctr 0 \
+               --ntfw-nvctr 0 \
+               --trusted-key-cert fiptool_images/trusted-key-cert.key-crt \
+               --tb-fw=build/warp7/debug/bl2.bin \
+               --tb-fw-cert fiptool_images/trusted-boot-fw.key-crt\
+               --tos-fw fiptool_images/tee-header_v2.bin \
+               --tos-fw-cert fiptool_images/tee-header_v2.bin.crt \
+               --tos-fw-key-cert fiptool_images/tee-header_v2.bin.key-crt \
+               --tos-fw-extra1 fiptool_images/tee-pager_v2.bin \
+               --tos-fw-extra2 fiptool_images/tee-pageable_v2.bin \
+               --nt-fw fiptool_images/u-boot.bin \
+               --nt-fw-cert fiptool_images/u-boot.bin.crt \
+               --nt-fw-key-cert fiptool_images/u-boot.bin.key-crt \
+               --hw-config fiptool_images/imx7s-warp.dtb
+
+    tools/fiptool/fiptool create --tos-fw fiptool_images/tee-header_v2.bin \
+              --tos-fw-extra1 fiptool_images/tee-pager_v2.bin \
+              --tos-fw-extra2 fiptool_images/tee-pageable_v2.bin \
+              --nt-fw fiptool_images/u-boot.bin \
+              --hw-config fiptool_images/imx7s-warp.dtb \
+              --tos-fw-cert fiptool_images/tee-header_v2.bin.crt \
+              --tos-fw-key-cert fiptool_images/tee-header_v2.bin.key-crt \
+              --nt-fw-cert fiptool_images/u-boot.bin.crt \
+              --nt-fw-key-cert fiptool_images/u-boot.bin.key-crt \
+              --trusted-key-cert fiptool_images/trusted-key-cert.key-crt \
+              --tb-fw-cert fiptool_images/trusted-boot-fw.key-crt warp7.fip
 
 # Deploy Images
 
index f1a26f42eda281ce4d194a71cc09c3f9b1655f34..7fc529708c5fca370e82f27c987a5aff82d54a03 100644 (file)
@@ -390,7 +390,7 @@ also be defined:
 -  **#define : SCP\_BL2\_IMAGE\_ID**
 
    SCP\_BL2 image identifier, used by BL2 to load SCP\_BL2 into secure memory
-   from platform storage before being transfered to the SCP.
+   from platform storage before being transferred to the SCP.
 
 -  **#define : SCP\_FW\_KEY\_CERT\_ID**
 
@@ -439,9 +439,9 @@ platform, the following constants must also be defined:
 -  **#define : TSP\_SEC\_MEM\_SIZE**
 
    Defines the size of the secure memory used by the BL32 image on the
-   platform. ``TSP_SEC_MEM_BASE`` and ``TSP_SEC_MEM_SIZE`` must fully accomodate
-   the memory required by the BL32 image, defined by ``BL32_BASE`` and
-   ``BL32_LIMIT``.
+   platform. ``TSP_SEC_MEM_BASE`` and ``TSP_SEC_MEM_SIZE`` must fully
+   accommodate the memory required by the BL32 image, defined by ``BL32_BASE``
+   and ``BL32_LIMIT``.
 
 -  **#define : TSP\_IRQ\_SEC\_PHY\_TIMER**
 
@@ -821,11 +821,11 @@ Function : plat\_my\_core\_pos()
     Argument : void
     Return   : unsigned int
 
-This funtion returns the index of the calling CPU which is used as a
+This function returns the index of the calling CPU which is used as a
 CPU-specific linear index into blocks of memory (for example while allocating
 per-CPU stacks). This function will be invoked very early in the
 initialization sequence which mandates that this function should be
-implemented in assembly and should not rely on the avalability of a C
+implemented in assembly and should not rely on the availability of a C
 runtime environment. This function can clobber x0 - x8 and must preserve
 x9 - x29.
 
@@ -929,7 +929,7 @@ Function : plat\_reset\_handler()
 
 A platform may need to do additional initialization after reset. This function
 allows the platform to do the platform specific intializations. Platform
-specific errata workarounds could also be implemented here. The api should
+specific errata workarounds could also be implemented here. The API should
 preserve the values of callee saved registers x19 to x29.
 
 The default implementation doesn't do anything. If a platform needs to override
@@ -1543,7 +1543,7 @@ The AP Firmware Updater Configuration, BL2U, is an optional part of the FWU
 process and is executed only by the primary CPU. BL1 passes control to BL2U at
 ``BL2U_BASE``. BL2U executes in Secure-EL1 and is responsible for:
 
-#. (Optional) Transfering the optional SCP\_BL2U binary image from AP secure
+#. (Optional) Transferring the optional SCP\_BL2U binary image from AP secure
    memory to SCP RAM. BL2U uses the SCP\_BL2U ``image_info`` passed by BL1.
    ``SCP_BL2U_BASE`` defines the address in AP secure memory where SCP\_BL2U
    should be copied from. Subsequent handling of the SCP\_BL2U image is
@@ -1649,7 +1649,7 @@ CPUs. BL31 executes at EL3 and is responsible for:
    implementation.
 
 #. Optionally passing control to the BL32 image, pre-loaded at a platform-
-   specific address by BL2. BL31 exports a set of apis that allow runtime
+   specific address by BL2. BL31 exports a set of APIs that allow runtime
    services to specify the security state in which the next image should be
    executed and run the corresponding image. On ARM platforms, BL31 uses the
    ``bl_params`` list populated by BL2 in memory to do this.
@@ -1800,7 +1800,7 @@ defined by the translation library, and can be found in the file
 ``include/lib/xlat_tables/xlat_mmu_helpers.h``.
 
 On DynamIQ systems, this function must not use stack while enabling MMU, which
-is how the function in xlat table library version 2 is implementated.
+is how the function in xlat table library version 2 is implemented.
 
 Function : plat\_get\_syscnt\_freq2() [mandatory]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2030,7 +2030,7 @@ Function : plat\_get\_power\_domain\_tree\_desc() [mandatory]
 
 This function returns a pointer to the byte array containing the power domain
 topology tree description. The format and method to construct this array are
-described in `Power Domain Topology Design`_. The BL31 PSCI initilization code
+described in `Power Domain Topology Design`_. The BL31 PSCI initialization code
 requires this array to be described by the platform, either statically or
 dynamically, to initialize the power domain topology tree. In case the array
 is populated dynamically, then plat\_core\_pos\_by\_mpidr() and
@@ -2070,7 +2070,7 @@ plat\_psci\_ops.cpu\_standby()
 
 Perform the platform-specific actions to enter the standby state for a cpu
 indicated by the passed argument. This provides a fast path for CPU standby
-wherein overheads of PSCI state management and lock acquistion is avoided.
+wherein overheads of PSCI state management and lock acquisition is avoided.
 For this handler to be invoked by the PSCI ``CPU_SUSPEND`` API implementation,
 the suspend state type specified in the ``power-state`` parameter should be
 STANDBY and the target power domain level specified should be the CPU. The
@@ -2345,7 +2345,7 @@ state or EL3/S-EL1 in the secure state. The design of this framework is
 described in the `IMF Design Guide`_
 
 A platform should export the following APIs to support the IMF. The following
-text briefly describes each api and its implementation in Arm standard
+text briefly describes each API and its implementation in Arm standard
 platforms. The API implementation depends upon the type of interrupt controller
 present in the platform. Arm standard platform layer supports both
 `Arm Generic Interrupt Controller version 2.0 (GICv2)`_
@@ -2552,7 +2552,7 @@ Crash Reporting mechanism (in BL31)
 
 BL31 implements a crash reporting mechanism which prints the various registers
 of the CPU to enable quick crash analysis and debugging. This mechanism relies
-on the platform implementating ``plat_crash_console_init``,
+on the platform implementing ``plat_crash_console_init``,
 ``plat_crash_console_putc`` and ``plat_crash_console_flush``.
 
 The file ``plat/common/aarch64/crash_console_helpers.S`` contains sample
index d86fc29e667376abbdede6ea5d7fce3656eda575..1be224088d666c0b304f8f18a5b18e32174f2cec 100644 (file)
@@ -240,7 +240,7 @@ As explained in `Secure payload power management callback`_,
 the EL3 Runtime Software may want to perform some bookkeeping during power
 management operations. This function is used to register the ``spd_pm_ops_t``
 (first argument) callbacks with the PSCI library which will be called
-ppropriately during power management. Calling this function is optional and
+appropriately during power management. Calling this function is optional and
 need to be called by the primary CPU during the cold boot sequence after
 ``psci_setup()`` has completed.
 
index 4c82022b6fd084f59d11b85f72454b5bf0012d4c..cea74e9af3d443699fabd2606703e5d7febe52ef 100644 (file)
@@ -203,8 +203,8 @@ doesn't return.
 Engaging the RAS framework
 --------------------------
 
-Enabling RAS support is a platform choice conjunctional of three distinct but
-related build options:
+Enabling RAS support is a platform choice constructed from three distinct, but
+related, build options:
 
 -  ``RAS_EXTENSION=1`` includes the RAS framework in the run time firmware;
 
@@ -244,7 +244,7 @@ allocate the highest secure priority for RAS handling.
 
 .. __: exception-handling.rst#partitioning-priority-levels
 
-Handling of both `interrrupt`__ and `non-interrupt`__ exceptions follow the
+Handling of both `interrupt`__ and `non-interrupt`__ exceptions follow the
 sequences outlined in the |EHF| documentation. I.e., for interrupts, the
 priority management is implicit; but for non-interrupt exceptions, they're
 explicit using `EHF APIs`__.
index 73406b202440632d34c7e9ae721c0283ac917bda..3c301d0bffc11cd2eb354036d47ccaee504963f6 100644 (file)
@@ -309,7 +309,7 @@ SPM to delegate service requests to the Secure Partition. The interface also
 allows the Secure Partition to:
 
 - Register with the SPM a service that it provides.
-- Indicate completion of a service request delagated by the SPM
+- Indicate completion of a service request delegated by the SPM
 
 Miscellaneous interfaces
 ------------------------
index 103f1c727da531fe64c4ad2ab4d2e282c3728de2..e22733ef21da011c895ce55941e821c999dc66e0 100644 (file)
@@ -86,6 +86,46 @@ Download the TF-A source code from Github:
 
     git clone https://github.com/ARM-software/arm-trusted-firmware.git
 
+Checking source code style
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Trusted Firmware follows the `Linux Coding Style`_ . When making changes to the
+source, for submission to the project, the source must be in compliance with
+this style guide.
+
+Additional, project-specific guidelines are defined in the `Trusted Firmware-A
+Coding Guidelines`_ document.
+
+To assist with coding style compliance, the project Makefile contains two
+targets which both utilise the `checkpatch.pl` script that ships with the Linux
+source tree. The project also defines certain *checkpatch* options in the
+``.checkpatch.conf`` file in the top-level directory.
+
+**Note:** Checkpatch errors will gate upstream merging of pull requests.
+Checkpatch warnings will not gate merging but should be reviewed and fixed if
+possible.
+
+To check the entire source tree, you must first download copies of
+``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
+in the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH``
+environment variable to point to ``checkpatch.pl`` (with the other 2 files in
+the same directory) and build the `checkcodebase` target:
+
+::
+
+    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
+
+To just check the style on the files that differ between your local branch and
+the remote master, use:
+
+::
+
+    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
+
+If you wish to check your patch against something other than the remote master,
+set the ``BASE_COMMIT`` variable to your desired branch. By default, ``BASE_COMMIT``
+is set to ``origin/master``.
+
 Building TF-A
 -------------
 
@@ -108,7 +148,7 @@ Building TF-A
    ``CC`` needs to point to the clang or armclang binary, which will
    also select the clang or armclang assembler. Be aware that the
    GNU linker is used by default.  In case of being needed the linker
-   can be overriden using the ``LD`` variable. Clang linker version 6 is
+   can be overridden using the ``LD`` variable. Clang linker version 6 is
    known to work with TF-A.
 
    In both cases ``CROSS_COMPILE`` should be set as described above.
@@ -357,8 +397,8 @@ Common build options
    supports the format used by GCC when T32 interworking is disabled. For this
    reason enabling this option in AArch32 will force the compiler to only
    generate A32 code. This option is enabled by default only in AArch64 debug
-   builds, but this behaviour can be overriden in each platform's Makefile or in
-   the build command line.
+   builds, but this behaviour can be overridden in each platform's Makefile or
+   in the build command line.
 
 -  ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM
    feature. MPAM is an optional Armv8.4 extension that enables various memory
@@ -428,7 +468,7 @@ Common build options
    handled at EL3, and a panic will result. This is supported only for AArch64
    builds.
 
--  ``FAULT_INJECTION_SUPPORT``: ARMv8.4 externsions introduced support for fault
+-  ``FAULT_INJECTION_SUPPORT``: ARMv8.4 extensions introduced support for fault
    injection from lower ELs, and this build option enables lower ELs to use
    Error Records accessed via System Registers to inject faults. This is
    applicable only to AArch64 builds.
@@ -930,34 +970,6 @@ An additional boot loader binary file is created in the ``build`` directory:
 
     build/<platform>/<build-type>/bl32.bin
 
-Checking source code style
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When making changes to the source for submission to the project, the source
-must be in compliance with the Linux style guide, and to assist with this check
-the project Makefile contains two targets, which both utilise the
-``checkpatch.pl`` script that ships with the Linux source tree.
-
-To check the entire source tree, you must first download copies of
-``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
-in the `Linux master tree`_ scripts directory, then set the ``CHECKPATCH``
-environment variable to point to ``checkpatch.pl`` (with the other 2 files in
-the same directory) and build the target checkcodebase:
-
-::
-
-    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
-
-To just check the style on the files that differ between your local branch and
-the remote master, use:
-
-::
-
-    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
-
-If you wish to check your patch against something other than the remote master,
-set the ``BASE_COMMIT`` variable to your desired branch. By default, ``BASE_COMMIT``
-is set to ``origin/master``.
 
 Building and using the FIP tool
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2054,6 +2066,7 @@ wakeup interrupt from RTC.
 .. _Instructions for using Linaro's deliverables on Juno: https://community.arm.com/dev-platforms/w/docs/303/juno
 .. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
 .. _Development Studio 5 (DS-5): http://www.arm.com/products/tools/software-tools/ds-5/index.php
+.. _`Linux Coding Style`: https://www.kernel.org/doc/html/latest/process/coding-style.html
 .. _Linux master tree: https://github.com/torvalds/linux/tree/master/
 .. _Dia: https://wiki.gnome.org/Apps/Dia/Download
 .. _here: psci-lib-integration-guide.rst
@@ -2069,3 +2082,4 @@ wakeup interrupt from RTC.
 .. _Juno Getting Started Guide: http://infocenter.arm.com/help/topic/com.arm.doc.dui0928e/DUI0928E_juno_arm_development_platform_gsg.pdf
 .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
 .. _Secure Partition Manager Design guide: secure-partition-manager-design.rst
+.. _`Trusted Firmware-A Coding Guidelines`: coding-guidelines.rst
index 64b1626970f473043f333e9f72938d0cd930e5e9..d184054ee9b6802c75ba8e906844cc25272fd703 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -370,7 +370,7 @@ void ccn_exit_dvm_domain(unsigned long long master_iface_map)
  * system. The state is expected to be one of NO_L3, SF_ONLY, L3_HAM or
  * L3_FAM. Instead of comparing the states reported by all HN-Fs, the state of
  * the first present HN-F node is reported. Since the driver does not export an
- * interface to program them seperately, there is no reason to perform this
+ * interface to program them separately, there is no reason to perform this
  * check. An HN-F could report that the L3 cache is transitioning from one mode
  * to another e.g. HNF_PM_NOL3_2_SFONLY. In this case, the function waits for
  * the transition to complete and reports the final state.
@@ -383,7 +383,7 @@ unsigned int ccn_get_l3_run_mode(void)
        assert(ccn_plat_desc->periphbase);
 
        /*
-        * Wait for a L3 cache paritition to enter any run mode. The pstate
+        * Wait for a L3 cache partition to enter any run mode. The pstate
         * parameter is read from an HN-F P-state status register. A non-zero
         * value in bits[1:0] means that the cache is transitioning to a run
         * mode.
@@ -428,7 +428,7 @@ void ccn_set_l3_run_mode(unsigned int mode)
        region_id = HNF_REGION_ID_START;
        FOR_EACH_PRESENT_REGION_ID(region_id, mn_hnf_id_map) {
                /*
-                * Wait for a L3 cache paritition to enter a target run
+                * Wait for a L3 cache partition to enter a target run
                 * mode. The pstate parameter is read from an HN-F P-state
                 * status register.
                 */
@@ -584,7 +584,7 @@ void ccn_write_node_reg(node_types_t node_type, unsigned int node_id,
                return;
        }
 
-       /* Setting the value of Auxilary Control Register of the Node */
+       /* Setting the value of Auxiliary Control Register of the Node */
        ccn_reg_write(ccn_plat_desc->periphbase, region_id, reg_offset, val);
        VERBOSE("Value is successfully written at address 0x%lx.\n",
                        (ccn_plat_desc->periphbase
@@ -611,7 +611,7 @@ unsigned long long ccn_read_node_reg(node_types_t node_type,
                return ULL(0);
        }
 
-       /* Setting the value of Auxilary Control Register of the Node */
+       /* Setting the value of Auxiliary Control Register of the Node */
        val = ccn_reg_read(ccn_plat_desc->periphbase, region_id, reg_offset);
        VERBOSE("Value is successfully read from address 0x%lx.\n",
                        (ccn_plat_desc->periphbase
diff --git a/drivers/arm/css/mhu/css_mhu.c b/drivers/arm/css/mhu/css_mhu.c
new file mode 100644 (file)
index 0000000..b7faf7e
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <drivers/arm/css/css_mhu.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+#include <plat/arm/common/plat_arm.h>
+
+/* SCP MHU secure channel registers */
+#define SCP_INTR_S_STAT                0x200
+#define SCP_INTR_S_SET         0x208
+#define SCP_INTR_S_CLEAR       0x210
+
+/* CPU MHU secure channel registers */
+#define CPU_INTR_S_STAT                0x300
+#define CPU_INTR_S_SET         0x308
+#define CPU_INTR_S_CLEAR       0x310
+
+ARM_INSTANTIATE_LOCK;
+
+/* Weak definition may be overridden in specific CSS based platform */
+#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(unsigned int slot_id)
+{
+       assert(slot_id <= MHU_MAX_SLOT_ID);
+
+       arm_lock_get();
+
+       /* Make sure any previous command has finished */
+       while (mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) &
+                                                       (1 << slot_id))
+               ;
+}
+
+void mhu_secure_message_send(unsigned int slot_id)
+{
+       assert(slot_id <= MHU_MAX_SLOT_ID);
+       assert(!(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) &
+                                                       (1 << slot_id)));
+
+       /* Send command to SCP */
+       mmio_write_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id);
+}
+
+uint32_t mhu_secure_message_wait(void)
+{
+       /* Wait for response from SCP */
+       uint32_t response;
+       while (!(response = mmio_read_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_STAT)))
+               ;
+
+       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_write_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id);
+
+       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_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0);
+}
+
+void __init plat_arm_pwrc_setup(void)
+{
+       mhu_secure_init();
+}
diff --git a/drivers/arm/css/mhu/css_mhu_doorbell.c b/drivers/arm/css/mhu/css_mhu_doorbell.c
new file mode 100644 (file)
index 0000000..8858742
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+
+void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info)
+{
+       MHU_RING_DOORBELL(plat_info->db_reg_addr,
+                       plat_info->db_modify_mask,
+                       plat_info->db_preserve_mask);
+       return;
+}
+
+void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info)
+{
+       /* wake receiver */
+       MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR);
+
+       /* wait for receiver to acknowledge its ready */
+       while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0)
+               ;
+
+       MHU_RING_DOORBELL(plat_info->db_reg_addr,
+                       plat_info->db_modify_mask,
+                       plat_info->db_preserve_mask);
+
+       /* clear the access request for the receiver */
+       MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR);
+
+       return;
+}
diff --git a/drivers/arm/css/scmi/scmi_ap_core_proto.c b/drivers/arm/css/scmi/scmi_ap_core_proto.c
new file mode 100644 (file)
index 0000000..2caccc2
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018, 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 <drivers/arm/css/scmi.h>
+
+#include "scmi_private.h"
+
+/*
+ * API to set the SCMI AP core reset address and attributes
+ */
+int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr)
+{
+       mailbox_mem_t *mbx_mem;
+       int token = 0, ret;
+       scmi_channel_t *ch = (scmi_channel_t *)p;
+
+       validate_scmi_channel(ch);
+
+       scmi_get_channel(ch);
+
+       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
+       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_AP_CORE_PROTO_ID,
+                       SCMI_AP_CORE_RESET_ADDR_SET_MSG, token);
+       mbx_mem->len = SCMI_AP_CORE_RESET_ADDR_SET_MSG_LEN;
+       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
+       SCMI_PAYLOAD_ARG3(mbx_mem->payload, reset_addr & 0xffffffff,
+               reset_addr >> 32, attr);
+
+       scmi_send_sync_command(ch);
+
+       /* Get the return values */
+       SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret);
+       assert(mbx_mem->len == SCMI_AP_CORE_RESET_ADDR_SET_RESP_LEN);
+       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
+
+       scmi_put_channel(ch);
+
+       return ret;
+}
+
+/*
+ * API to get the SCMI AP core reset address and attributes
+ */
+int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr)
+{
+       mailbox_mem_t *mbx_mem;
+       int token = 0, ret;
+       scmi_channel_t *ch = (scmi_channel_t *)p;
+       uint32_t lo_addr, hi_addr;
+
+       validate_scmi_channel(ch);
+
+       scmi_get_channel(ch);
+
+       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
+       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_AP_CORE_PROTO_ID,
+                       SCMI_AP_CORE_RESET_ADDR_GET_MSG, token);
+       mbx_mem->len = SCMI_AP_CORE_RESET_ADDR_GET_MSG_LEN;
+       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
+
+       scmi_send_sync_command(ch);
+
+       /* Get the return values */
+       SCMI_PAYLOAD_RET_VAL4(mbx_mem->payload, ret, lo_addr, hi_addr, *attr);
+       *reset_addr = lo_addr | (uint64_t)hi_addr << 32;
+       assert(mbx_mem->len == SCMI_AP_CORE_RESET_ADDR_GET_RESP_LEN);
+       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
+
+       scmi_put_channel(ch);
+
+       return ret;
+}
diff --git a/drivers/arm/css/scmi/scmi_common.c b/drivers/arm/css/scmi/scmi_common.c
new file mode 100644 (file)
index 0000000..e2c353d
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2017-2018, 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 <drivers/arm/css/scmi.h>
+
+#include "scmi_private.h"
+
+#if HW_ASSISTED_COHERENCY
+#define scmi_lock_init(lock)
+#define scmi_lock_get(lock)            spin_lock(lock)
+#define scmi_lock_release(lock)                spin_unlock(lock)
+#else
+#define scmi_lock_init(lock)           bakery_lock_init(lock)
+#define scmi_lock_get(lock)            bakery_lock_get(lock)
+#define scmi_lock_release(lock)                bakery_lock_release(lock)
+#endif
+
+
+/*
+ * Private helper function to get exclusive access to SCMI channel.
+ */
+void scmi_get_channel(scmi_channel_t *ch)
+{
+       assert(ch->lock);
+       scmi_lock_get(ch->lock);
+
+       /* Make sure any previous command has finished */
+       assert(SCMI_IS_CHANNEL_FREE(
+                       ((mailbox_mem_t *)(ch->info->scmi_mbx_mem))->status));
+}
+
+/*
+ * Private helper function to transfer ownership of channel from AP to SCP.
+ */
+void scmi_send_sync_command(scmi_channel_t *ch)
+{
+       mailbox_mem_t *mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
+
+       SCMI_MARK_CHANNEL_BUSY(mbx_mem->status);
+
+       /*
+        * Ensure that any write to the SCMI payload area is seen by SCP before
+        * we write to the doorbell register. If these 2 writes were reordered
+        * by the CPU then SCP would read stale payload data
+        */
+       dmbst();
+
+       ch->info->ring_doorbell(ch->info);
+       /*
+        * Ensure that the write to the doorbell register is ordered prior to
+        * checking whether the channel is free.
+        */
+       dmbsy();
+
+       /* Wait for channel to be free */
+       while (!SCMI_IS_CHANNEL_FREE(mbx_mem->status))
+               ;
+
+       /*
+        * Ensure that any read to the SCMI payload area is done after reading
+        * mailbox status. If these 2 reads were reordered then the CPU would
+        * read invalid payload data
+        */
+       dmbld();
+}
+
+/*
+ * Private helper function to release exclusive access to SCMI channel.
+ */
+void scmi_put_channel(scmi_channel_t *ch)
+{
+       /* Make sure any previous command has finished */
+       assert(SCMI_IS_CHANNEL_FREE(
+                       ((mailbox_mem_t *)(ch->info->scmi_mbx_mem))->status));
+
+       assert(ch->lock);
+       scmi_lock_release(ch->lock);
+}
+
+/*
+ * API to query the SCMI protocol version.
+ */
+int scmi_proto_version(void *p, uint32_t proto_id, uint32_t *version)
+{
+       mailbox_mem_t *mbx_mem;
+       int token = 0, ret;
+       scmi_channel_t *ch = (scmi_channel_t *)p;
+
+       validate_scmi_channel(ch);
+
+       scmi_get_channel(ch);
+
+       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
+       mbx_mem->msg_header = SCMI_MSG_CREATE(proto_id, SCMI_PROTO_VERSION_MSG,
+                                                       token);
+       mbx_mem->len = SCMI_PROTO_VERSION_MSG_LEN;
+       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
+
+       scmi_send_sync_command(ch);
+
+       /* Get the return values */
+       SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *version);
+       assert(mbx_mem->len == SCMI_PROTO_VERSION_RESP_LEN);
+       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
+
+       scmi_put_channel(ch);
+
+       return ret;
+}
+
+/*
+ * API to query the protocol message attributes for a SCMI protocol.
+ */
+int scmi_proto_msg_attr(void *p, uint32_t proto_id,
+               uint32_t command_id, uint32_t *attr)
+{
+       mailbox_mem_t *mbx_mem;
+       int token = 0, ret;
+       scmi_channel_t *ch = (scmi_channel_t *)p;
+
+       validate_scmi_channel(ch);
+
+       scmi_get_channel(ch);
+
+       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
+       mbx_mem->msg_header = SCMI_MSG_CREATE(proto_id,
+                               SCMI_PROTO_MSG_ATTR_MSG, token);
+       mbx_mem->len = SCMI_PROTO_MSG_ATTR_MSG_LEN;
+       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
+       SCMI_PAYLOAD_ARG1(mbx_mem->payload, command_id);
+
+       scmi_send_sync_command(ch);
+
+       /* Get the return values */
+       SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *attr);
+       assert(mbx_mem->len == SCMI_PROTO_MSG_ATTR_RESP_LEN);
+       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
+
+       scmi_put_channel(ch);
+
+       return ret;
+}
+
+/*
+ * SCMI Driver initialization API. Returns initialized channel on success
+ * or NULL on error. The return type is an opaque void pointer.
+ */
+void *scmi_init(scmi_channel_t *ch)
+{
+       uint32_t version;
+       int ret;
+
+       assert(ch && ch->info);
+       assert(ch->info->db_reg_addr);
+       assert(ch->info->db_modify_mask);
+       assert(ch->info->db_preserve_mask);
+       assert(ch->info->ring_doorbell != NULL);
+
+       assert(ch->lock);
+
+       scmi_lock_init(ch->lock);
+
+       ch->is_initialized = 1;
+
+       ret = scmi_proto_version(ch, SCMI_PWR_DMN_PROTO_ID, &version);
+       if (ret != SCMI_E_SUCCESS) {
+               WARN("SCMI power domain protocol version message failed");
+               goto error;
+       }
+
+       if (!is_scmi_version_compatible(SCMI_PWR_DMN_PROTO_VER, version)) {
+               WARN("SCMI power domain protocol version 0x%x incompatible with driver version 0x%x",
+                       version, SCMI_PWR_DMN_PROTO_VER);
+               goto error;
+       }
+
+       VERBOSE("SCMI power domain protocol version 0x%x detected\n", version);
+
+       ret = scmi_proto_version(ch, SCMI_SYS_PWR_PROTO_ID, &version);
+       if ((ret != SCMI_E_SUCCESS)) {
+               WARN("SCMI system power protocol version message failed");
+               goto error;
+       }
+
+       if (!is_scmi_version_compatible(SCMI_SYS_PWR_PROTO_VER, version)) {
+               WARN("SCMI system power management protocol version 0x%x incompatible with driver version 0x%x",
+                       version, SCMI_SYS_PWR_PROTO_VER);
+               goto error;
+       }
+
+       VERBOSE("SCMI system power management protocol version 0x%x detected\n",
+                                               version);
+
+       INFO("SCMI driver initialized\n");
+
+       return (void *)ch;
+
+error:
+       ch->is_initialized = 0;
+       return NULL;
+}
diff --git a/drivers/arm/css/scmi/scmi_private.h b/drivers/arm/css/scmi/scmi_private.h
new file mode 100644 (file)
index 0000000..6530573
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SCMI_PRIVATE_H
+#define SCMI_PRIVATE_H
+
+#include <lib/mmio.h>
+
+/*
+ * SCMI power domain management protocol message and response lengths. It is
+ * calculated as sum of length in bytes of the message header (4) and payload
+ * area (the number of bytes of parameters or return values in the payload).
+ */
+#define SCMI_PROTO_VERSION_MSG_LEN             4
+#define SCMI_PROTO_VERSION_RESP_LEN            12
+
+#define SCMI_PROTO_MSG_ATTR_MSG_LEN            8
+#define SCMI_PROTO_MSG_ATTR_RESP_LEN           12
+
+#define SCMI_AP_CORE_RESET_ADDR_SET_MSG_LEN    16
+#define SCMI_AP_CORE_RESET_ADDR_SET_RESP_LEN   8
+
+#define SCMI_AP_CORE_RESET_ADDR_GET_MSG_LEN    4
+#define SCMI_AP_CORE_RESET_ADDR_GET_RESP_LEN   20
+
+#define SCMI_PWR_STATE_SET_MSG_LEN             16
+#define SCMI_PWR_STATE_SET_RESP_LEN            8
+
+#define SCMI_PWR_STATE_GET_MSG_LEN             8
+#define SCMI_PWR_STATE_GET_RESP_LEN            12
+
+#define SCMI_SYS_PWR_STATE_SET_MSG_LEN         12
+#define SCMI_SYS_PWR_STATE_SET_RESP_LEN                8
+
+#define SCMI_SYS_PWR_STATE_GET_MSG_LEN         4
+#define SCMI_SYS_PWR_STATE_GET_RESP_LEN                12
+
+/* SCMI message header format bit field */
+#define SCMI_MSG_ID_SHIFT              0
+#define SCMI_MSG_ID_WIDTH              8
+#define SCMI_MSG_ID_MASK               ((1 << SCMI_MSG_ID_WIDTH) - 1)
+
+#define SCMI_MSG_TYPE_SHIFT            8
+#define SCMI_MSG_TYPE_WIDTH            2
+#define SCMI_MSG_TYPE_MASK             ((1 << SCMI_MSG_TYPE_WIDTH) - 1)
+
+#define SCMI_MSG_PROTO_ID_SHIFT                10
+#define SCMI_MSG_PROTO_ID_WIDTH                8
+#define SCMI_MSG_PROTO_ID_MASK         ((1 << SCMI_MSG_PROTO_ID_WIDTH) - 1)
+
+#define SCMI_MSG_TOKEN_SHIFT           18
+#define SCMI_MSG_TOKEN_WIDTH           10
+#define SCMI_MSG_TOKEN_MASK            ((1 << SCMI_MSG_TOKEN_WIDTH) - 1)
+
+
+/* SCMI mailbox flags */
+#define SCMI_FLAG_RESP_POLL    0
+#define SCMI_FLAG_RESP_INT     1
+
+/* SCMI power domain protocol `POWER_STATE_SET` message flags */
+#define SCMI_PWR_STATE_SET_FLAG_SYNC   0
+#define SCMI_PWR_STATE_SET_FLAG_ASYNC  1
+
+/*
+ * Helper macro to create an SCMI message header given protocol, message id
+ * and token.
+ */
+#define SCMI_MSG_CREATE(_protocol, _msg_id, _token)                            \
+       ((((_protocol) & SCMI_MSG_PROTO_ID_MASK) << SCMI_MSG_PROTO_ID_SHIFT) |  \
+       (((_msg_id) & SCMI_MSG_ID_MASK) << SCMI_MSG_ID_SHIFT) |                 \
+       (((_token) & SCMI_MSG_TOKEN_MASK) << SCMI_MSG_TOKEN_SHIFT))
+
+/* Helper macro to get the token from a SCMI message header */
+#define SCMI_MSG_GET_TOKEN(_msg)                               \
+       (((_msg) >> SCMI_MSG_TOKEN_SHIFT) & SCMI_MSG_TOKEN_MASK)
+
+/* SCMI Channel Status bit fields */
+#define SCMI_CH_STATUS_RES0_MASK       0xFFFFFFFE
+#define SCMI_CH_STATUS_FREE_SHIFT      0
+#define SCMI_CH_STATUS_FREE_WIDTH      1
+#define SCMI_CH_STATUS_FREE_MASK       ((1 << SCMI_CH_STATUS_FREE_WIDTH) - 1)
+
+/* Helper macros to check and write the channel status */
+#define SCMI_IS_CHANNEL_FREE(status)                                   \
+       (!!(((status) >> SCMI_CH_STATUS_FREE_SHIFT) & SCMI_CH_STATUS_FREE_MASK))
+
+#define SCMI_MARK_CHANNEL_BUSY(status) do {                            \
+               assert(SCMI_IS_CHANNEL_FREE(status));                   \
+               (status) &= ~(SCMI_CH_STATUS_FREE_MASK <<               \
+                               SCMI_CH_STATUS_FREE_SHIFT);             \
+       } while (0)
+
+/* Helper macros to copy arguments to the mailbox payload */
+#define SCMI_PAYLOAD_ARG1(payld_arr, arg1)                             \
+               mmio_write_32((uintptr_t)&payld_arr[0], arg1)
+
+#define SCMI_PAYLOAD_ARG2(payld_arr, arg1, arg2)       do {            \
+               SCMI_PAYLOAD_ARG1(payld_arr, arg1);                     \
+               mmio_write_32((uintptr_t)&payld_arr[1], arg2);          \
+       } while (0)
+
+#define SCMI_PAYLOAD_ARG3(payld_arr, arg1, arg2, arg3) do {            \
+               SCMI_PAYLOAD_ARG2(payld_arr, arg1, arg2);               \
+               mmio_write_32((uintptr_t)&payld_arr[2], arg3);          \
+       } while (0)
+
+/* Helper macros to read return values from the mailbox payload */
+#define SCMI_PAYLOAD_RET_VAL1(payld_arr, val1)                         \
+               (val1) = mmio_read_32((uintptr_t)&payld_arr[0])
+
+#define SCMI_PAYLOAD_RET_VAL2(payld_arr, val1, val2)   do {            \
+               SCMI_PAYLOAD_RET_VAL1(payld_arr, val1);                 \
+               (val2) = mmio_read_32((uintptr_t)&payld_arr[1]);        \
+       } while (0)
+
+#define SCMI_PAYLOAD_RET_VAL3(payld_arr, val1, val2, val3)     do {    \
+               SCMI_PAYLOAD_RET_VAL2(payld_arr, val1, val2);           \
+               (val3) = mmio_read_32((uintptr_t)&payld_arr[2]);        \
+       } while (0)
+
+#define SCMI_PAYLOAD_RET_VAL4(payld_arr, val1, val2, val3, val4)       do {    \
+               SCMI_PAYLOAD_RET_VAL3(payld_arr, val1, val2, val3);             \
+               (val4) = mmio_read_32((uintptr_t)&payld_arr[3]);                \
+       } while (0)
+
+/*
+ * Private data structure for representing the mailbox memory layout. Refer
+ * the SCMI specification for more details.
+ */
+typedef struct mailbox_mem {
+       uint32_t res_a; /* Reserved */
+       volatile uint32_t status;
+       uint64_t res_b; /* Reserved */
+       uint32_t flags;
+       volatile uint32_t len;
+       uint32_t msg_header;
+       uint32_t payload[];
+} mailbox_mem_t;
+
+
+/* Private APIs for use within SCMI driver */
+void scmi_get_channel(scmi_channel_t *ch);
+void scmi_send_sync_command(scmi_channel_t *ch);
+void scmi_put_channel(scmi_channel_t *ch);
+
+static inline void validate_scmi_channel(scmi_channel_t *ch)
+{
+       assert(ch && ch->is_initialized);
+       assert(ch->info && ch->info->scmi_mbx_mem);
+}
+
+#endif /* SCMI_PRIVATE_H */
diff --git a/drivers/arm/css/scmi/scmi_pwr_dmn_proto.c b/drivers/arm/css/scmi/scmi_pwr_dmn_proto.c
new file mode 100644 (file)
index 0000000..70165de
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017, 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 <drivers/arm/css/scmi.h>
+
+#include "scmi_private.h"
+
+/*
+ * API to set the SCMI power domain power state.
+ */
+int scmi_pwr_state_set(void *p, uint32_t domain_id,
+                                       uint32_t scmi_pwr_state)
+{
+       mailbox_mem_t *mbx_mem;
+       int token = 0, ret;
+
+       /*
+        * Only asynchronous mode of `set power state` command is allowed on
+        * application processors.
+        */
+       uint32_t pwr_state_set_msg_flag = SCMI_PWR_STATE_SET_FLAG_ASYNC;
+       scmi_channel_t *ch = (scmi_channel_t *)p;
+
+       validate_scmi_channel(ch);
+
+       scmi_get_channel(ch);
+
+       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
+       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_PWR_DMN_PROTO_ID,
+                       SCMI_PWR_STATE_SET_MSG, token);
+       mbx_mem->len = SCMI_PWR_STATE_SET_MSG_LEN;
+       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
+       SCMI_PAYLOAD_ARG3(mbx_mem->payload, pwr_state_set_msg_flag,
+                                               domain_id, scmi_pwr_state);
+
+       scmi_send_sync_command(ch);
+
+       /* Get the return values */
+       SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret);
+       assert(mbx_mem->len == SCMI_PWR_STATE_SET_RESP_LEN);
+       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
+
+       scmi_put_channel(ch);
+
+       return ret;
+}
+
+/*
+ * API to get the SCMI power domain power state.
+ */
+int scmi_pwr_state_get(void *p, uint32_t domain_id,
+                                       uint32_t *scmi_pwr_state)
+{
+       mailbox_mem_t *mbx_mem;
+       int token = 0, ret;
+       scmi_channel_t *ch = (scmi_channel_t *)p;
+
+       validate_scmi_channel(ch);
+
+       scmi_get_channel(ch);
+
+       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
+       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_PWR_DMN_PROTO_ID,
+                       SCMI_PWR_STATE_GET_MSG, token);
+       mbx_mem->len = SCMI_PWR_STATE_GET_MSG_LEN;
+       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
+       SCMI_PAYLOAD_ARG1(mbx_mem->payload, domain_id);
+
+       scmi_send_sync_command(ch);
+
+       /* Get the return values */
+       SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *scmi_pwr_state);
+       assert(mbx_mem->len == SCMI_PWR_STATE_GET_RESP_LEN);
+       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
+
+       scmi_put_channel(ch);
+
+       return ret;
+}
diff --git a/drivers/arm/css/scmi/scmi_sys_pwr_proto.c b/drivers/arm/css/scmi/scmi_sys_pwr_proto.c
new file mode 100644 (file)
index 0000000..a27c4a5
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017, 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 <drivers/arm/css/scmi.h>
+
+#include "scmi_private.h"
+
+/*
+ * API to set the SCMI system power state
+ */
+int scmi_sys_pwr_state_set(void *p, uint32_t flags, uint32_t system_state)
+{
+       mailbox_mem_t *mbx_mem;
+       int token = 0, ret;
+       scmi_channel_t *ch = (scmi_channel_t *)p;
+
+       validate_scmi_channel(ch);
+
+       scmi_get_channel(ch);
+
+       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
+       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_SYS_PWR_PROTO_ID,
+                       SCMI_SYS_PWR_STATE_SET_MSG, token);
+       mbx_mem->len = SCMI_SYS_PWR_STATE_SET_MSG_LEN;
+       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
+       SCMI_PAYLOAD_ARG2(mbx_mem->payload, flags, system_state);
+
+       scmi_send_sync_command(ch);
+
+       /* Get the return values */
+       SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret);
+       assert(mbx_mem->len == SCMI_SYS_PWR_STATE_SET_RESP_LEN);
+       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
+
+       scmi_put_channel(ch);
+
+       return ret;
+}
+
+/*
+ * API to get the SCMI system power state
+ */
+int scmi_sys_pwr_state_get(void *p, uint32_t *system_state)
+{
+       mailbox_mem_t *mbx_mem;
+       int token = 0, ret;
+       scmi_channel_t *ch = (scmi_channel_t *)p;
+
+       validate_scmi_channel(ch);
+
+       scmi_get_channel(ch);
+
+       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
+       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_SYS_PWR_PROTO_ID,
+                       SCMI_SYS_PWR_STATE_GET_MSG, token);
+       mbx_mem->len = SCMI_SYS_PWR_STATE_GET_MSG_LEN;
+       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
+
+       scmi_send_sync_command(ch);
+
+       /* Get the return values */
+       SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *system_state);
+       assert(mbx_mem->len == SCMI_SYS_PWR_STATE_GET_RESP_LEN);
+       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
+
+       scmi_put_channel(ch);
+
+       return ret;
+}
diff --git a/drivers/arm/css/scp/css_bom_bootloader.c b/drivers/arm/css/scp/css_bom_bootloader.c
new file mode 100644 (file)
index 0000000..1fc1270
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/css/css_mhu.h>
+#include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/css_scpi.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+/* ID of the MHU slot used for the BOM protocol */
+#define BOM_MHU_SLOT_ID                0
+
+/* Boot commands sent from AP -> SCP */
+#define BOOT_CMD_INFO  0x00
+#define BOOT_CMD_DATA  0x01
+
+/* BOM command header */
+typedef struct {
+       uint32_t id : 8;
+       uint32_t reserved : 24;
+} bom_cmd_t;
+
+typedef struct {
+       uint32_t image_size;
+       uint32_t checksum;
+} cmd_info_payload_t;
+
+/*
+ * Unlike the SCPI protocol, the boot protocol uses the same memory region
+ * for both AP -> SCP and SCP -> AP transfers; define the address of this...
+ */
+#define BOM_SHARED_MEM         PLAT_CSS_SCP_COM_SHARED_MEM_BASE
+#define BOM_CMD_HEADER         ((bom_cmd_t *) BOM_SHARED_MEM)
+#define BOM_CMD_PAYLOAD                ((void *) (BOM_SHARED_MEM + sizeof(bom_cmd_t)))
+
+typedef struct {
+       /* Offset from the base address of the Trusted RAM */
+       uint32_t offset;
+       uint32_t block_size;
+} cmd_data_payload_t;
+
+/*
+ * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31
+ * usually resides except when ARM_BL31_IN_DRAM is
+ * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into shared RAM and
+ * the tb_fw_config.
+ */
+CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2);
+CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2);
+
+CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow);
+CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow);
+
+static void scp_boot_message_start(void)
+{
+       mhu_secure_message_start(BOM_MHU_SLOT_ID);
+}
+
+static void scp_boot_message_send(size_t payload_size)
+{
+       /* Ensure that any write to the BOM 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();
+
+       /* Send command to SCP */
+       mhu_secure_message_send(BOM_MHU_SLOT_ID);
+}
+
+static uint32_t scp_boot_message_wait(size_t size)
+{
+       uint32_t mhu_status;
+
+       mhu_status = mhu_secure_message_wait();
+
+       /* Expect an SCP Boot Protocol message, reject any other protocol */
+       if (mhu_status != (1 << BOM_MHU_SLOT_ID)) {
+               ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n",
+                       mhu_status);
+               panic();
+       }
+
+       /* Ensure that any read to the BOM payload area is done after reading
+        * the MHU register. If these 2 reads were reordered then the CPU would
+        * read invalid payload data */
+       dmbld();
+
+       return *(uint32_t *) BOM_SHARED_MEM;
+}
+
+static void scp_boot_message_end(void)
+{
+       mhu_secure_message_end(BOM_MHU_SLOT_ID);
+}
+
+int css_scp_boot_image_xfer(void *image, unsigned int image_size)
+{
+       uint32_t response;
+       uint32_t checksum;
+       cmd_info_payload_t *cmd_info_payload;
+       cmd_data_payload_t *cmd_data_payload;
+
+       assert((uintptr_t) image == SCP_BL2_BASE);
+
+       if ((image_size == 0) || (image_size % 4 != 0)) {
+               ERROR("Invalid size for the SCP_BL2 image. Must be a multiple of "
+                       "4 bytes and not zero (current size = 0x%x)\n",
+                       image_size);
+               return -1;
+       }
+
+       /* Extract the checksum from the image */
+       checksum = *(uint32_t *) image;
+       image = (char *) image + sizeof(checksum);
+       image_size -= sizeof(checksum);
+
+       mhu_secure_init();
+
+       VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n");
+
+       /*
+        * Send information about the SCP firmware image about to be transferred
+        * to SCP
+        */
+       scp_boot_message_start();
+
+       BOM_CMD_HEADER->id = BOOT_CMD_INFO;
+       cmd_info_payload = BOM_CMD_PAYLOAD;
+       cmd_info_payload->image_size = image_size;
+       cmd_info_payload->checksum = checksum;
+
+       scp_boot_message_send(sizeof(*cmd_info_payload));
+#if CSS_DETECT_PRE_1_7_0_SCP
+       {
+               const uint32_t deprecated_scp_nack_cmd = 0x404;
+               uint32_t mhu_status;
+
+               VERBOSE("Detecting SCP version incompatibility\n");
+
+               mhu_status = mhu_secure_message_wait();
+               if (mhu_status == deprecated_scp_nack_cmd) {
+                       ERROR("Detected an incompatible version of the SCP firmware.\n");
+                       ERROR("Only versions from v1.7.0 onwards are supported.\n");
+                       ERROR("Please update the SCP firmware.\n");
+                       return -1;
+               }
+
+               VERBOSE("SCP version looks OK\n");
+       }
+#endif /* CSS_DETECT_PRE_1_7_0_SCP */
+       response = scp_boot_message_wait(sizeof(response));
+       scp_boot_message_end();
+
+       if (response != 0) {
+               ERROR("SCP BOOT_CMD_INFO returned error %u\n", response);
+               return -1;
+       }
+
+       VERBOSE("Transferring SCP_BL2 image to SCP\n");
+
+       /* Transfer SCP_BL2 image to SCP */
+       scp_boot_message_start();
+
+       BOM_CMD_HEADER->id = BOOT_CMD_DATA;
+       cmd_data_payload = BOM_CMD_PAYLOAD;
+       cmd_data_payload->offset = (uintptr_t) image - ARM_TRUSTED_SRAM_BASE;
+       cmd_data_payload->block_size = image_size;
+
+       scp_boot_message_send(sizeof(*cmd_data_payload));
+       response = scp_boot_message_wait(sizeof(response));
+       scp_boot_message_end();
+
+       if (response != 0) {
+               ERROR("SCP BOOT_CMD_DATA returned error %u\n", response);
+               return -1;
+       }
+
+       return 0;
+}
+
+int css_scp_boot_ready(void)
+{
+       VERBOSE("Waiting for SCP to signal it is ready to go on\n");
+
+       /* Wait for SCP to signal it's ready */
+       return scpi_wait_ready();
+}
diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
new file mode 100644 (file)
index 0000000..1966c44
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2017-2018, 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 <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+/*
+ * This file implements the SCP helper functions using SCMI protocol.
+ */
+
+/*
+ * SCMI power state parameter bit field encoding for ARM CSS platforms.
+ *
+ * 31  20 19       16 15      12 11       8 7        4 3         0
+ * +-------------------------------------------------------------+
+ * | SBZ | Max level |  Level 3 |  Level 2 |  Level 1 |  Level 0 |
+ * |     |           |   state  |   state  |   state  |   state  |
+ * +-------------------------------------------------------------+
+ *
+ * `Max level` encodes the highest level that has a valid power state
+ * encoded in the power state.
+ */
+#define SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT       16
+#define SCMI_PWR_STATE_MAX_PWR_LVL_WIDTH       4
+#define SCMI_PWR_STATE_MAX_PWR_LVL_MASK                \
+                               ((1 << SCMI_PWR_STATE_MAX_PWR_LVL_WIDTH) - 1)
+#define SCMI_SET_PWR_STATE_MAX_PWR_LVL(_power_state, _max_level)               \
+               (_power_state) |= ((_max_level) & SCMI_PWR_STATE_MAX_PWR_LVL_MASK)\
+                               << SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT
+#define SCMI_GET_PWR_STATE_MAX_PWR_LVL(_power_state)           \
+               (((_power_state) >> SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT)   \
+                               & SCMI_PWR_STATE_MAX_PWR_LVL_MASK)
+
+#define SCMI_PWR_STATE_LVL_WIDTH               4
+#define SCMI_PWR_STATE_LVL_MASK                        \
+                               ((1 << SCMI_PWR_STATE_LVL_WIDTH) - 1)
+#define SCMI_SET_PWR_STATE_LVL(_power_state, _level, _level_state)             \
+               (_power_state) |= ((_level_state) & SCMI_PWR_STATE_LVL_MASK)    \
+                               << (SCMI_PWR_STATE_LVL_WIDTH * (_level))
+#define SCMI_GET_PWR_STATE_LVL(_power_state, _level)           \
+               (((_power_state) >> (SCMI_PWR_STATE_LVL_WIDTH * (_level))) &    \
+                               SCMI_PWR_STATE_LVL_MASK)
+
+/*
+ * The SCMI power state enumeration for a power domain level
+ */
+typedef enum {
+       scmi_power_state_off = 0,
+       scmi_power_state_on = 1,
+       scmi_power_state_sleep = 2,
+} scmi_power_state_t;
+
+/*
+ * The global handle for invoking the SCMI driver APIs after the driver
+ * has been initialized.
+ */
+static void *scmi_handle;
+
+/* The SCMI channel global object */
+static scmi_channel_t channel;
+
+ARM_SCMI_INSTANTIATE_LOCK;
+
+/*
+ * Helper function to suspend a CPU power domain and its parent power domains
+ * if applicable.
+ */
+void css_scp_suspend(const struct psci_power_state *target_state)
+{
+       int ret;
+
+       /* At least power domain level 0 should be specified to be suspended */
+       assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
+                                               ARM_LOCAL_STATE_OFF);
+
+       /* Check if power down at system power domain level is requested */
+       if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) {
+               /* Issue SCMI command for SYSTEM_SUSPEND */
+               ret = scmi_sys_pwr_state_set(scmi_handle,
+                               SCMI_SYS_PWR_FORCEFUL_REQ,
+                               SCMI_SYS_PWR_SUSPEND);
+               if (ret != SCMI_E_SUCCESS) {
+                       ERROR("SCMI system power domain suspend return 0x%x unexpected\n",
+                                       ret);
+                       panic();
+               }
+               return;
+       }
+#if !HW_ASSISTED_COHERENCY
+       int lvl;
+       uint32_t scmi_pwr_state = 0;
+       /*
+        * If we reach here, then assert that power down at system power domain
+        * level is running.
+        */
+       assert(css_system_pwr_state(target_state) == ARM_LOCAL_STATE_RUN);
+
+       /* For level 0, specify `scmi_power_state_sleep` as the power state */
+       SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, ARM_PWR_LVL0,
+                                               scmi_power_state_sleep);
+
+       for (lvl = ARM_PWR_LVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
+               if (target_state->pwr_domain_state[lvl] == ARM_LOCAL_STATE_RUN)
+                       break;
+
+               assert(target_state->pwr_domain_state[lvl] ==
+                                                       ARM_LOCAL_STATE_OFF);
+               /*
+                * Specify `scmi_power_state_off` as power state for higher
+                * levels.
+                */
+               SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl,
+                                               scmi_power_state_off);
+       }
+
+       SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
+
+       ret = scmi_pwr_state_set(scmi_handle,
+               plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()],
+               scmi_pwr_state);
+
+       if (ret != SCMI_E_SUCCESS) {
+               ERROR("SCMI set power state command return 0x%x unexpected\n",
+                               ret);
+               panic();
+       }
+#endif
+}
+
+/*
+ * Helper function to turn off a CPU power domain and its parent power domains
+ * if applicable.
+ */
+void css_scp_off(const struct psci_power_state *target_state)
+{
+       int lvl = 0, ret;
+       uint32_t scmi_pwr_state = 0;
+
+       /* At-least the CPU level should be specified to be OFF */
+       assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
+                                                       ARM_LOCAL_STATE_OFF);
+
+       /* PSCI CPU OFF cannot be used to turn OFF system power domain */
+       assert(css_system_pwr_state(target_state) == ARM_LOCAL_STATE_RUN);
+
+       for (; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
+               if (target_state->pwr_domain_state[lvl] == ARM_LOCAL_STATE_RUN)
+                       break;
+
+               assert(target_state->pwr_domain_state[lvl] ==
+                                                       ARM_LOCAL_STATE_OFF);
+               SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl,
+                               scmi_power_state_off);
+       }
+
+       SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
+
+       ret = scmi_pwr_state_set(scmi_handle,
+               plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()],
+               scmi_pwr_state);
+
+       if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) {
+               ERROR("SCMI set power state command return 0x%x unexpected\n",
+                               ret);
+               panic();
+       }
+}
+
+/*
+ * Helper function to turn ON a CPU power domain and its parent power domains
+ * if applicable.
+ */
+void css_scp_on(u_register_t mpidr)
+{
+       int lvl = 0, ret, core_pos;
+       uint32_t scmi_pwr_state = 0;
+
+       for (; lvl <= PLAT_MAX_PWR_LVL; lvl++)
+               SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl,
+                               scmi_power_state_on);
+
+       SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
+
+       core_pos = plat_core_pos_by_mpidr(mpidr);
+       assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);
+
+       ret = scmi_pwr_state_set(scmi_handle,
+               plat_css_core_pos_to_scmi_dmn_id_map[core_pos],
+               scmi_pwr_state);
+
+       if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) {
+               ERROR("SCMI set power state command return 0x%x unexpected\n",
+                               ret);
+               panic();
+       }
+}
+
+/*
+ * Helper function to get the power state of a power domain node as reported
+ * by the SCP.
+ */
+int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level)
+{
+       int ret, cpu_idx;
+       uint32_t scmi_pwr_state = 0, lvl_state;
+
+       /* We don't support get power state at the system power domain level */
+       if ((power_level > PLAT_MAX_PWR_LVL) ||
+                       (power_level == CSS_SYSTEM_PWR_DMN_LVL)) {
+               WARN("Invalid power level %u specified for SCMI get power state\n",
+                               power_level);
+               return PSCI_E_INVALID_PARAMS;
+       }
+
+       cpu_idx = plat_core_pos_by_mpidr(mpidr);
+       assert(cpu_idx > -1);
+
+       ret = scmi_pwr_state_get(scmi_handle,
+               plat_css_core_pos_to_scmi_dmn_id_map[cpu_idx],
+               &scmi_pwr_state);
+
+       if (ret != SCMI_E_SUCCESS) {
+               WARN("SCMI get power state command return 0x%x unexpected\n",
+                               ret);
+               return PSCI_E_INVALID_PARAMS;
+       }
+
+       /*
+        * Find the maximum power level described in the get power state
+        * command. If it is less than the requested power level, then assume
+        * the requested power level is ON.
+        */
+       if (SCMI_GET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state) < power_level)
+               return HW_ON;
+
+       lvl_state = SCMI_GET_PWR_STATE_LVL(scmi_pwr_state, power_level);
+       if (lvl_state == scmi_power_state_on)
+               return HW_ON;
+
+       assert((lvl_state == scmi_power_state_off) ||
+                               (lvl_state == scmi_power_state_sleep));
+       return HW_OFF;
+}
+
+void __dead2 css_scp_system_off(int state)
+{
+       int ret;
+
+       /*
+        * Disable GIC CPU interface to prevent pending interrupt from waking
+        * up the AP from WFI.
+        */
+       plat_arm_gic_cpuif_disable();
+
+       /*
+        * Issue SCMI command. First issue a graceful
+        * request and if that fails force the request.
+        */
+       ret = scmi_sys_pwr_state_set(scmi_handle,
+                       SCMI_SYS_PWR_FORCEFUL_REQ,
+                       state);
+
+       if (ret != SCMI_E_SUCCESS) {
+               ERROR("SCMI system power state set 0x%x returns unexpected 0x%x\n",
+                       state, ret);
+               panic();
+       }
+       wfi();
+       ERROR("CSS set power state: operation not handled.\n");
+       panic();
+}
+
+/*
+ * Helper function to shutdown the system via SCMI.
+ */
+void __dead2 css_scp_sys_shutdown(void)
+{
+       css_scp_system_off(SCMI_SYS_PWR_SHUTDOWN);
+}
+
+/*
+ * Helper function to reset the system via SCMI.
+ */
+void __dead2 css_scp_sys_reboot(void)
+{
+       css_scp_system_off(SCMI_SYS_PWR_COLD_RESET);
+}
+
+static int scmi_ap_core_init(scmi_channel_t *ch)
+{
+#if PROGRAMMABLE_RESET_ADDRESS
+       uint32_t version;
+       int ret;
+
+       ret = scmi_proto_version(ch, SCMI_AP_CORE_PROTO_ID, &version);
+       if (ret != SCMI_E_SUCCESS) {
+               WARN("SCMI AP core protocol version message failed\n");
+               return -1;
+       }
+
+       if (!is_scmi_version_compatible(SCMI_AP_CORE_PROTO_VER, version)) {
+               WARN("SCMI AP core protocol version 0x%x incompatible with driver version 0x%x\n",
+                       version, SCMI_AP_CORE_PROTO_VER);
+               return -1;
+       }
+       INFO("SCMI AP core protocol version 0x%x detected\n", version);
+#endif
+       return 0;
+}
+
+void __init plat_arm_pwrc_setup(void)
+{
+       channel.info = plat_css_get_scmi_info();
+       channel.lock = ARM_SCMI_LOCK_GET_INSTANCE;
+       scmi_handle = scmi_init(&channel);
+       if (scmi_handle == NULL) {
+               ERROR("SCMI Initialization failed\n");
+               panic();
+       }
+       if (scmi_ap_core_init(&channel) < 0) {
+               ERROR("SCMI AP core protocol initialization failed\n");
+               panic();
+       }
+}
+
+/******************************************************************************
+ * This function overrides the default definition for ARM platforms. Initialize
+ * the SCMI driver, query capability via SCMI and modify the PSCI capability
+ * based on that.
+ *****************************************************************************/
+const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops)
+{
+       uint32_t msg_attr;
+       int ret;
+
+       assert(scmi_handle);
+
+       /* Check that power domain POWER_STATE_SET message is supported */
+       ret = scmi_proto_msg_attr(scmi_handle, SCMI_PWR_DMN_PROTO_ID,
+                               SCMI_PWR_STATE_SET_MSG, &msg_attr);
+       if (ret != SCMI_E_SUCCESS) {
+               ERROR("Set power state command is not supported by SCMI\n");
+               panic();
+       }
+
+       /*
+        * Don't support PSCI NODE_HW_STATE call if SCMI doesn't support
+        * POWER_STATE_GET message.
+        */
+       ret = scmi_proto_msg_attr(scmi_handle, SCMI_PWR_DMN_PROTO_ID,
+                               SCMI_PWR_STATE_GET_MSG, &msg_attr);
+       if (ret != SCMI_E_SUCCESS)
+               ops->get_node_hw_state = NULL;
+
+       /* Check if the SCMI SYSTEM_POWER_STATE_SET message is supported */
+       ret = scmi_proto_msg_attr(scmi_handle, SCMI_SYS_PWR_PROTO_ID,
+                               SCMI_SYS_PWR_STATE_SET_MSG, &msg_attr);
+       if (ret != SCMI_E_SUCCESS) {
+               /* System power management operations are not supported */
+               ops->system_off = NULL;
+               ops->system_reset = NULL;
+               ops->get_sys_suspend_power_state = NULL;
+       } else {
+               if (!(msg_attr & SCMI_SYS_PWR_SUSPEND_SUPPORTED)) {
+                       /*
+                        * System power management protocol is available, but
+                        * it does not support SYSTEM SUSPEND.
+                        */
+                       ops->get_sys_suspend_power_state = NULL;
+               }
+               if (!(msg_attr & SCMI_SYS_PWR_WARM_RESET_SUPPORTED)) {
+                       /*
+                        * WARM reset is not available.
+                        */
+                       ops->system_reset2 = NULL;
+               }
+       }
+
+       return ops;
+}
+
+int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie)
+{
+       if (is_vendor || (reset_type != PSCI_RESET2_SYSTEM_WARM_RESET))
+               return PSCI_E_INVALID_PARAMS;
+
+       css_scp_system_off(SCMI_SYS_PWR_WARM_RESET);
+       /*
+        * css_scp_system_off cannot return (it is a __dead function),
+        * but css_system_reset2 has to return some value, even in
+        * this case.
+        */
+       return 0;
+}
+
+#if PROGRAMMABLE_RESET_ADDRESS
+void plat_arm_program_trusted_mailbox(uintptr_t address)
+{
+       int ret;
+
+       assert(scmi_handle);
+       ret = scmi_ap_core_set_reset_addr(scmi_handle, address,
+               SCMI_AP_CORE_LOCK_ATTR);
+       if (ret != SCMI_E_SUCCESS) {
+               ERROR("CSS: Failed to program reset address: %d\n", ret);
+               panic();
+       }
+}
+#endif
diff --git a/drivers/arm/css/scp/css_pm_scpi.c b/drivers/arm/css/scp/css_pm_scpi.c
new file mode 100644 (file)
index 0000000..b4019ce
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2016-2018, 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 <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/css_scpi.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+/*
+ * This file implements the SCP power management functions using SCPI protocol.
+ */
+
+/*
+ * Helper function to inform power down state to SCP.
+ */
+void css_scp_suspend(const struct psci_power_state *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 (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF)
+               system_state = scpi_power_retention;
+
+       /* Cluster is to be turned off, so disable coherency */
+       if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
+               cluster_state = scpi_power_off;
+
+       /*
+        * Ask the SCP to power down the appropriate components depending upon
+        * their state.
+        */
+       scpi_set_css_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.
+ */
+void css_scp_off(const struct psci_power_state *target_state)
+{
+       css_scp_suspend(target_state);
+}
+
+/*
+ * Helper function to turn ON a CPU power domain and its parent power domains
+ * if applicable.
+ */
+void css_scp_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_css_power_state(mpidr, scpi_power_on, scpi_power_on,
+                                scpi_power_on);
+}
+
+/*
+ * Helper function to get the power state of a power domain node as reported
+ * by the SCP.
+ */
+int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level)
+{
+       int rc, element;
+       unsigned int cpu_state, cluster_state;
+
+       /*
+        * The format of 'power_level' is implementation-defined, but 0 must
+        * mean a CPU. We also allow 1 to denote the cluster
+        */
+       if (power_level != ARM_PWR_LVL0 && power_level != ARM_PWR_LVL1)
+               return PSCI_E_INVALID_PARAMS;
+
+       /* Query SCP */
+       rc = scpi_get_css_power_state(mpidr, &cpu_state, &cluster_state);
+       if (rc != 0)
+               return PSCI_E_INVALID_PARAMS;
+
+       /* Map power states of CPU and cluster to expected PSCI return codes */
+       if (power_level == ARM_PWR_LVL0) {
+               /*
+                * The CPU state returned by SCP is an 8-bit bit mask
+                * corresponding to each CPU in the cluster
+                */
+#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.
+                */
+               element = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+#else
+               element = mpidr & MPIDR_AFFLVL_MASK;
+#endif  /* ARM_PLAT_MT */
+               return CSS_CPU_PWR_STATE(cpu_state, element) ==
+                       CSS_CPU_PWR_STATE_ON ? HW_ON : HW_OFF;
+       } else {
+               assert(cluster_state == CSS_CLUSTER_PWR_STATE_ON ||
+                               cluster_state == CSS_CLUSTER_PWR_STATE_OFF);
+               return cluster_state == CSS_CLUSTER_PWR_STATE_ON ? HW_ON :
+                       HW_OFF;
+       }
+}
+
+/*
+ * Helper function to shutdown the system via SCPI.
+ */
+void __dead2 css_scp_sys_shutdown(void)
+{
+       uint32_t response;
+
+       /*
+        * Disable GIC CPU interface to prevent pending interrupt
+        * from waking up the AP from WFI.
+        */
+       plat_arm_gic_cpuif_disable();
+
+       /* Send the power down request to the SCP */
+       response = scpi_sys_power_state(scpi_system_shutdown);
+
+       if (response != SCP_OK) {
+               ERROR("CSS System Off: SCP error %u.\n", response);
+               panic();
+       }
+       wfi();
+       ERROR("CSS System Off: operation not handled.\n");
+       panic();
+}
+
+/*
+ * Helper function to reset the system via SCPI.
+ */
+void __dead2 css_scp_sys_reboot(void)
+{
+       uint32_t response;
+
+       /*
+        * Disable GIC CPU interface to prevent pending interrupt
+        * from waking up the AP from WFI.
+        */
+       plat_arm_gic_cpuif_disable();
+
+       /* Send the system reset request to the SCP */
+       response = scpi_sys_power_state(scpi_system_reboot);
+
+       if (response != SCP_OK) {
+               ERROR("CSS System Reset: SCP error %u.\n", response);
+               panic();
+       }
+       wfi();
+       ERROR("CSS System Reset: operation not handled.\n");
+       panic();
+}
diff --git a/drivers/arm/css/scp/css_sds.c b/drivers/arm/css/scp/css_sds.c
new file mode 100644 (file)
index 0000000..e42ee10
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/sds.h>
+#include <drivers/delay_timer.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+int css_scp_boot_image_xfer(void *image, unsigned int image_size)
+{
+       int ret;
+       unsigned int image_offset, image_flags;
+
+       ret = sds_init();
+       if (ret != SDS_OK) {
+               ERROR("SCP SDS initialization failed\n");
+               panic();
+       }
+
+       VERBOSE("Writing SCP image metadata\n");
+       image_offset = (uintptr_t) image - ARM_TRUSTED_SRAM_BASE;
+       ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_ADDR_OFFSET,
+                       &image_offset, SDS_SCP_IMG_ADDR_SIZE,
+                       SDS_ACCESS_MODE_NON_CACHED);
+       if (ret != SDS_OK)
+               goto sds_fail;
+
+       ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_SIZE_OFFSET,
+                       &image_size, SDS_SCP_IMG_SIZE_SIZE,
+                       SDS_ACCESS_MODE_NON_CACHED);
+       if (ret != SDS_OK)
+               goto sds_fail;
+
+       VERBOSE("Marking SCP image metadata as valid\n");
+       image_flags = SDS_SCP_IMG_VALID_FLAG_BIT;
+       ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_FLAG_OFFSET,
+                       &image_flags, SDS_SCP_IMG_FLAG_SIZE,
+                       SDS_ACCESS_MODE_NON_CACHED);
+       if (ret != SDS_OK)
+               goto sds_fail;
+
+       return 0;
+sds_fail:
+       ERROR("SCP SDS write to SCP IMG struct failed\n");
+       panic();
+}
+
+/*
+ * API to wait for SCP to signal till it's ready after booting the transferred
+ * image.
+ */
+int css_scp_boot_ready(void)
+{
+       uint32_t scp_feature_availability_flags;
+       int ret, retry = CSS_SCP_READY_10US_RETRIES;
+
+
+       VERBOSE("Waiting for SCP RAM to complete its initialization process\n");
+
+       /* Wait for the SCP RAM Firmware to complete its initialization process */
+       while (retry > 0) {
+               ret = sds_struct_read(SDS_FEATURE_AVAIL_STRUCT_ID, 0,
+                               &scp_feature_availability_flags,
+                               SDS_FEATURE_AVAIL_SIZE,
+                               SDS_ACCESS_MODE_NON_CACHED);
+               if (ret == SDS_ERR_STRUCT_NOT_FINALIZED)
+                       continue;
+
+               if (ret != SDS_OK) {
+                       ERROR(" sds_struct_read failed\n");
+                       panic();
+               }
+
+               if (scp_feature_availability_flags &
+                               SDS_FEATURE_AVAIL_SCP_RAM_READY_BIT)
+                       return 0;
+
+               udelay(10);
+               retry--;
+       }
+
+       ERROR("Timeout of %d ms expired waiting for SCP RAM Ready flag\n",
+                       CSS_SCP_READY_10US_RETRIES/100);
+
+       plat_panic_handler();
+}
diff --git a/drivers/arm/css/scpi/css_scpi.c b/drivers/arm/css/scpi/css_scpi.c
new file mode 100644 (file)
index 0000000..4b73265
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2014-2018, 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 <drivers/arm/css/css_mhu.h>
+#include <drivers/arm/css/css_scpi.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#define SCPI_SHARED_MEM_SCP_TO_AP      PLAT_CSS_SCP_COM_SHARED_MEM_BASE
+#define SCPI_SHARED_MEM_AP_TO_SCP      (PLAT_CSS_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 command #%u, got command #%u\n",
+                     SCPI_CMD_SCP_READY, scpi_cmd.id);
+               status = SCP_E_SUPPORT;
+       } else if (scpi_cmd.size != 0) {
+               ERROR("SCP_READY command 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_css_power_state(unsigned int mpidr,
+               scpi_power_state_t cpu_state, scpi_power_state_t cluster_state,
+               scpi_power_state_t css_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 |= css_state << 16;
+
+       scpi_secure_message_start();
+
+       /* Populate the command header */
+       cmd = SCPI_CMD_HEADER_AP_TO_SCP;
+       cmd->id = SCPI_CMD_SET_CSS_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 CSS 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_css_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
+        */
+#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.
+        */
+       cpu = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+       cluster = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
+#else
+       cpu = mpidr & MPIDR_AFFLVL_MASK;
+       cluster = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+#endif  /* ARM_PLAT_MT */
+       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_CSS_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_cmd_t response;
+
+       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_receive(&response);
+
+       scpi_secure_message_end();
+
+       return response.status;
+}
diff --git a/drivers/arm/css/sds/aarch32/sds_helpers.S b/drivers/arm/css/sds/aarch32/sds_helpers.S
new file mode 100644 (file)
index 0000000..13ff0e1
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <drivers/arm/css/sds.h>
+#include <platform_def.h>
+
+#include "../sds_private.h"
+
+       .globl  sds_get_primary_cpu_id
+
+       /*
+        * int sds_get_primary_cpu_id(void);
+        * Return the primary CPU ID from SDS Structure
+        * Returns CPUID on success or -1 on failure
+        */
+func sds_get_primary_cpu_id
+       ldr     r0, =PLAT_ARM_SDS_MEM_BASE
+       ldr     r2, =SDS_REGION_SIGNATURE
+       ldr     r1, [r0]
+       ubfx    r3, r1, #0, #16
+
+       /* Check if the SDS region signature found */
+       cmp     r2, r3
+       bne     2f
+
+       /* Get the structure count from region descriptor in r1 */
+       ubfx    r1, r1, #SDS_REGION_STRUCT_COUNT_SHIFT, #SDS_REGION_STRUCT_COUNT_WIDTH
+       cmp     r1, #0
+       beq     2f
+       add     r0, r0, #SDS_REGION_DESC_SIZE
+
+       /* Initialize the loop iterator count in r3 */
+       mov     r3, #0
+loop_begin:
+       ldrh    r2, [r0]
+       cmp     r2, #SDS_AP_CPU_INFO_STRUCT_ID
+       bne     continue_loop
+
+       /* We have found the required structure */
+       ldr     r0, [r0,#(SDS_HEADER_SIZE + SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET)]
+       bx      lr
+continue_loop:
+       /* Increment the loop counter and exit loop if counter == structure count */
+       add     r3, r3, #0x1
+       cmp     r1, r3
+       beq     2f
+
+       /* Read the 2nd word in header */
+       ldr     r2, [r0,#4]
+       /* Get the structure size from header */
+       ubfx    r2, r2, #SDS_HEADER_STRUCT_SIZE_SHIFT, #SDS_HEADER_STRUCT_SIZE_WIDTH
+       /* Add the structure size and SDS HEADER SIZE to point to next header */
+       add     r2, r2, #SDS_HEADER_SIZE
+       add     r0, r0, r2
+       b       loop_begin
+2:
+       mov     r0, #0xffffffff
+       bx      lr
+endfunc sds_get_primary_cpu_id
diff --git a/drivers/arm/css/sds/aarch64/sds_helpers.S b/drivers/arm/css/sds/aarch64/sds_helpers.S
new file mode 100644 (file)
index 0000000..3256c2b
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <drivers/arm/css/sds.h>
+#include <platform_def.h>
+
+#include "../sds_private.h"
+
+       .globl  sds_get_primary_cpu_id
+
+       /*
+        * int sds_get_primary_cpu_id(void);
+        * Return the primary CPI ID from SDS Structure
+        * Returns CPUID on success or -1 on failure
+        */
+func sds_get_primary_cpu_id
+       mov_imm x0, PLAT_ARM_SDS_MEM_BASE
+       mov     w2, #SDS_REGION_SIGNATURE
+       ldr     w1, [x0]
+
+       /* Check if the SDS region signature found */
+       cmp     w2, w1, uxth
+       b.ne    2f
+
+       /* Get the structure count from region descriptor in `w1 */
+       ubfx    w1, w1, #SDS_REGION_STRUCT_COUNT_SHIFT, #SDS_REGION_STRUCT_COUNT_WIDTH
+       cbz     w1, 2f
+       add     x0, x0, #SDS_REGION_DESC_SIZE
+
+       /* Initialize the loop iterator count in w3 */
+       mov     w3, #0
+loop_begin:
+       ldrh    w2, [x0]
+       cmp     w2, #SDS_AP_CPU_INFO_STRUCT_ID
+       b.ne    continue_loop
+
+       /* We have found the required structure */
+       ldr     w0, [x0,#(SDS_HEADER_SIZE + SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET)]
+       ret
+continue_loop:
+       /* Increment the loop counter and exit loop if counter == structure count */
+       add     w3, w3, #0x1
+       cmp     w1, w3
+       b.eq    2f
+
+       /* Read the 2nd word in header */
+       ldr     w2, [x0,#4]
+       /* Get the structure size from header */
+       ubfx    x2, x2, #SDS_HEADER_STRUCT_SIZE_SHIFT, #SDS_HEADER_STRUCT_SIZE_WIDTH
+       /* Add the structure size and SDS HEADER SIZE to point to next header */
+       add     x2, x2, #SDS_HEADER_SIZE
+       add     x0, x0, x2
+       b       loop_begin
+2:
+       mov     w0, #0xffffffff
+       ret
+endfunc sds_get_primary_cpu_id
diff --git a/drivers/arm/css/sds/sds.c b/drivers/arm/css/sds/sds.c
new file mode 100644 (file)
index 0000000..1fb196c
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/css/sds.h>
+#include <platform_def.h>
+
+#include "sds_private.h"
+
+/*
+ * Variables used to track and maintain the state of the memory region reserved
+ * for usage by the SDS framework.
+ */
+
+/* Pointer to the base of the SDS memory region */
+static uintptr_t sds_mem_base;
+
+/* Size of the SDS memory region in bytes */
+static size_t sds_mem_size;
+
+/*
+ * Perform some non-exhaustive tests to determine whether any of the fields
+ * within a Structure Header contain obviously invalid data.
+ * Returns SDS_OK on success, SDS_ERR_FAIL on error.
+ */
+static int sds_struct_is_valid(uintptr_t header)
+{
+       size_t struct_size = GET_SDS_HEADER_STRUCT_SIZE(header);
+
+       /* Zero is not a valid identifier */
+       if (GET_SDS_HEADER_ID(header) == 0)
+               return SDS_ERR_FAIL;
+
+       /* Check SDS Schema version */
+       if (GET_SDS_HEADER_VERSION(header) == SDS_REGION_SCH_VERSION)
+               return SDS_ERR_FAIL;
+
+       /* The SDS Structure sizes have to be multiple of 8 */
+       if ((struct_size == 0) || ((struct_size % 8) != 0))
+               return SDS_ERR_FAIL;
+
+       if (struct_size > sds_mem_size)
+               return SDS_ERR_FAIL;
+
+       return SDS_OK;
+}
+
+/*
+ * Validate the SDS structure headers.
+ * Returns SDS_OK on success, SDS_ERR_FAIL on error.
+ */
+static int validate_sds_struct_headers(void)
+{
+       unsigned int i, structure_count;
+       uintptr_t header;
+
+       structure_count = GET_SDS_REGION_STRUCTURE_COUNT(sds_mem_base);
+
+       if (structure_count == 0)
+               return SDS_ERR_FAIL;
+
+       header = sds_mem_base + SDS_REGION_DESC_SIZE;
+
+       /* Iterate over structure headers and validate each one */
+       for (i = 0; i < structure_count; i++) {
+               if (sds_struct_is_valid(header) != SDS_OK) {
+                       WARN("SDS: Invalid structure header detected\n");
+                       return SDS_ERR_FAIL;
+               }
+               header += GET_SDS_HEADER_STRUCT_SIZE(header) + SDS_HEADER_SIZE;
+       }
+       return SDS_OK;
+}
+
+/*
+ * Get the structure header pointer corresponding to the structure ID.
+ * Returns SDS_OK on success, SDS_ERR_STRUCT_NOT_FOUND on error.
+ */
+static int get_struct_header(uint32_t structure_id, struct_header_t **header)
+{
+       unsigned int i, structure_count;
+       uintptr_t current_header;
+
+       assert(header);
+
+       structure_count = GET_SDS_REGION_STRUCTURE_COUNT(sds_mem_base);
+       if (structure_count == 0)
+               return SDS_ERR_STRUCT_NOT_FOUND;
+
+       current_header = ((uintptr_t)sds_mem_base) + SDS_REGION_DESC_SIZE;
+
+       /* Iterate over structure headers to find one with a matching ID */
+       for (i = 0; i < structure_count; i++) {
+               if (GET_SDS_HEADER_ID(current_header) == structure_id) {
+                       *header = (struct_header_t *)current_header;
+                       return SDS_OK;
+               }
+               current_header += GET_SDS_HEADER_STRUCT_SIZE(current_header) +
+                                               SDS_HEADER_SIZE;
+       }
+
+       *header = NULL;
+       return SDS_ERR_STRUCT_NOT_FOUND;
+}
+
+/*
+ * Check if a structure header corresponding to the structure ID exists.
+ * Returns SDS_OK if structure header exists else SDS_ERR_STRUCT_NOT_FOUND
+ * if not found.
+ */
+int sds_struct_exists(unsigned int structure_id)
+{
+       struct_header_t *header = NULL;
+       int ret;
+
+       ret = get_struct_header(structure_id, &header);
+       if (ret == SDS_OK) {
+               assert(header);
+       }
+
+       return ret;
+}
+
+/*
+ * Read from field in the structure corresponding to `structure_id`.
+ * `fld_off` is the offset to the field in the structure and `mode`
+ * indicates whether cache maintenance need to performed prior to the read.
+ * The `data` is the pointer to store the read data of size specified by `size`.
+ * Returns SDS_OK on success or corresponding error codes on failure.
+ */
+int sds_struct_read(uint32_t structure_id, unsigned int fld_off,
+               void *data, size_t size, sds_access_mode_t mode)
+{
+       int status;
+       uintptr_t field_base;
+       struct_header_t *header = NULL;
+
+       if (!data)
+               return SDS_ERR_INVALID_PARAMS;
+
+       /* Check if a structure with this ID exists */
+       status = get_struct_header(structure_id, &header);
+       if (status != SDS_OK)
+               return status;
+
+       assert(header);
+
+       if (mode == SDS_ACCESS_MODE_CACHED)
+               inv_dcache_range((uintptr_t)header, SDS_HEADER_SIZE + size);
+
+       if (!IS_SDS_HEADER_VALID(header)) {
+               WARN("SDS: Reading from un-finalized structure 0x%x\n",
+                               structure_id);
+               return SDS_ERR_STRUCT_NOT_FINALIZED;
+       }
+
+       if ((fld_off + size) > GET_SDS_HEADER_STRUCT_SIZE(header))
+               return SDS_ERR_FAIL;
+
+       field_base = (uintptr_t)header + SDS_HEADER_SIZE + fld_off;
+       if (check_uptr_overflow(field_base, size - 1))
+               return SDS_ERR_FAIL;
+
+       /* Copy the required field in the struct */
+       memcpy(data, (void *)field_base, size);
+
+       return SDS_OK;
+}
+
+/*
+ * Write to the field in the structure corresponding to `structure_id`.
+ * `fld_off` is the offset to the field in the structure and `mode`
+ * indicates whether cache maintenance need to performed for the write.
+ * The `data` is the pointer to data of size specified by `size`.
+ * Returns SDS_OK on success or corresponding error codes on failure.
+ */
+int sds_struct_write(uint32_t structure_id, unsigned int fld_off,
+               void *data, size_t size, sds_access_mode_t mode)
+{
+       int status;
+       uintptr_t field_base;
+       struct_header_t *header = NULL;
+
+       if (!data)
+               return SDS_ERR_INVALID_PARAMS;
+
+       /* Check if a structure with this ID exists */
+       status = get_struct_header(structure_id, &header);
+       if (status != SDS_OK)
+               return status;
+
+       assert(header);
+
+       if (mode == SDS_ACCESS_MODE_CACHED)
+               inv_dcache_range((uintptr_t)header, SDS_HEADER_SIZE + size);
+
+       if (!IS_SDS_HEADER_VALID(header)) {
+               WARN("SDS: Writing to un-finalized structure 0x%x\n",
+                               structure_id);
+               return SDS_ERR_STRUCT_NOT_FINALIZED;
+       }
+
+       if ((fld_off + size) > GET_SDS_HEADER_STRUCT_SIZE(header))
+               return SDS_ERR_FAIL;
+
+       field_base = (uintptr_t)header + SDS_HEADER_SIZE + fld_off;
+       if (check_uptr_overflow(field_base, size - 1))
+               return SDS_ERR_FAIL;
+
+       /* Copy the required field in the struct */
+       memcpy((void *)field_base, data, size);
+
+       if (mode == SDS_ACCESS_MODE_CACHED)
+               flush_dcache_range((uintptr_t)field_base, size);
+
+       return SDS_OK;
+}
+
+/*
+ * Initialize the SDS driver. Also verifies the SDS version and sanity of
+ * the SDS structure headers.
+ * Returns SDS_OK on success, SDS_ERR_FAIL on error.
+ */
+int sds_init(void)
+{
+       sds_mem_base = (uintptr_t)PLAT_ARM_SDS_MEM_BASE;
+
+       if (!IS_SDS_REGION_VALID(sds_mem_base)) {
+               WARN("SDS: No valid SDS Memory Region found\n");
+               return SDS_ERR_FAIL;
+       }
+
+       if (GET_SDS_REGION_SCHEMA_VERSION(sds_mem_base)
+                               != SDS_REGION_SCH_VERSION) {
+               WARN("SDS: Unsupported SDS schema version\n");
+               return SDS_ERR_FAIL;
+       }
+
+       sds_mem_size = GET_SDS_REGION_SIZE(sds_mem_base);
+       if (sds_mem_size > PLAT_ARM_SDS_MEM_SIZE_MAX) {
+               WARN("SDS: SDS Memory Region exceeds size limit\n");
+               return SDS_ERR_FAIL;
+       }
+
+       INFO("SDS: Detected SDS Memory Region (%zu bytes)\n", sds_mem_size);
+
+       if (validate_sds_struct_headers() != SDS_OK)
+               return SDS_ERR_FAIL;
+
+       return SDS_OK;
+}
diff --git a/drivers/arm/css/sds/sds_private.h b/drivers/arm/css/sds/sds_private.h
new file mode 100644 (file)
index 0000000..2101dd0
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SDS_PRIVATE_H
+#define SDS_PRIVATE_H
+
+/* SDS Header defines */
+#define SDS_HEADER_ID_SHIFT                    0
+#define SDS_HEADER_ID_WIDTH                    16
+#define SDS_HEADER_ID_MASK                     ((1 << SDS_HEADER_ID_WIDTH) - 1)
+
+#define SDS_HEADER_MINOR_VERSION_WIDTH         8
+#define SDS_HEADER_MINOR_VERSION_SHIFT         16
+#define SDS_HEADER_MAJOR_VERSION_WIDTH         8
+
+#define MAKE_SDS_HEADER_VERSION(major, minor)  \
+       (((((major) & 0xff) << SDS_HEADER_MINOR_VERSION_WIDTH) | ((minor) & 0xff)))
+#define SDS_HEADER_VERSION_MASK                        \
+       ((1 << (SDS_HEADER_MINOR_VERSION_WIDTH + SDS_HEADER_MAJOR_VERSION_WIDTH)) - 1)
+
+#define SDS_HEADER_VERSION                     MAKE_SDS_HEADER_VERSION(1, 0)
+#define SDS_HEADER_STRUCT_SIZE_WIDTH           23
+#define SDS_HEADER_STRUCT_SIZE_SHIFT           1
+#define SDS_HEADER_STRUCT_SIZE_MASK            ((1 << SDS_HEADER_STRUCT_SIZE_WIDTH) - 1)
+#define SDS_HEADER_VALID_MASK                  0x1
+#define SDS_HEADER_VALID_SHIFT                 0
+#define SDS_HEADER_SIZE                                0x8
+
+/* Arbitrary, 16 bit value that indicates a valid SDS Memory Region */
+#define SDS_REGION_SIGNATURE                   0xAA7A
+#define SDS_REGION_SIGNATURE_WIDTH             16
+#define SDS_REGION_SIGNATURE_SHIFT             0
+#define SDS_REGION_SIGNATURE_MASK              ((1 << SDS_REGION_SIGNATURE_WIDTH) - 1)
+
+#define SDS_REGION_STRUCT_COUNT_SHIFT          16
+#define SDS_REGION_STRUCT_COUNT_WIDTH          8
+#define SDS_REGION_STRUCT_COUNT_MASK           ((1 << SDS_REGION_STRUCT_COUNT_WIDTH) - 1)
+
+#define SDS_REGION_SCH_MINOR_SHIFT             24
+#define SDS_REGION_SCH_MINOR_WIDTH             4
+#define SDS_REGION_SCH_MINOR_MASK              ((1 << SDS_REGION_SCH_MINOR_WIDTH) - 1)
+
+#define SDS_REGION_SCH_MAJOR_SHIFT             28
+#define SDS_REGION_SCH_MAJOR_WIDTH             4
+#define SDS_REGION_SCH_MAJOR_MASK              ((1 << SDS_REGION_SCH_MAJOR_WIDTH) - 1)
+
+#define SDS_REGION_SCH_VERSION_MASK            \
+       ((1 << (SDS_REGION_SCH_MINOR_WIDTH + SDS_REGION_SCH_MAJOR_WIDTH)) - 1)
+
+#define MAKE_SDS_REGION_SCH_VERSION(maj, min)  \
+       ((((maj) & SDS_REGION_SCH_MAJOR_MASK) << SDS_REGION_SCH_MINOR_WIDTH) |  \
+       ((min) & SDS_REGION_SCH_MINOR_MASK))
+
+#define SDS_REGION_SCH_VERSION                 MAKE_SDS_REGION_SCH_VERSION(1, 0)
+#define SDS_REGION_REGIONSIZE_OFFSET           0x4
+#define SDS_REGION_DESC_SIZE                   0x8
+
+#ifndef __ASSEMBLY__
+#include <stddef.h>
+#include <stdint.h>
+
+/* Header containing Shared Data Structure metadata */
+typedef struct structure_header {
+       uint32_t reg[2];
+} struct_header_t;
+
+#define GET_SDS_HEADER_ID(_header)                     \
+       ((((struct_header_t *)(_header))->reg[0]) & SDS_HEADER_ID_MASK)
+#define GET_SDS_HEADER_VERSION(_header)                        \
+       (((((struct_header_t *)(_header))->reg[0]) >> SDS_HEADER_MINOR_VERSION_SHIFT)\
+       & SDS_HEADER_VERSION_MASK)
+#define GET_SDS_HEADER_STRUCT_SIZE(_header)            \
+       (((((struct_header_t *)(_header))->reg[1]) >> SDS_HEADER_STRUCT_SIZE_SHIFT)\
+       & SDS_HEADER_STRUCT_SIZE_MASK)
+#define IS_SDS_HEADER_VALID(_header)                   \
+       ((((struct_header_t *)(_header))->reg[1]) & SDS_HEADER_VALID_MASK)
+#define GET_SDS_STRUCT_FIELD(_header, _field_offset)   \
+       ((((uint8_t *)(_header)) + sizeof(struct_header_t)) + (_field_offset))
+
+/* Region Descriptor describing the SDS Memory Region */
+typedef struct region_descriptor {
+       uint32_t reg[2];
+} region_desc_t;
+
+#define IS_SDS_REGION_VALID(region)                    \
+       (((((region_desc_t *)(region))->reg[0]) & SDS_REGION_SIGNATURE_MASK) == SDS_REGION_SIGNATURE)
+#define GET_SDS_REGION_STRUCTURE_COUNT(region)         \
+       (((((region_desc_t *)(region))->reg[0]) >> SDS_REGION_STRUCT_COUNT_SHIFT)\
+       & SDS_REGION_STRUCT_COUNT_MASK)
+#define GET_SDS_REGION_SCHEMA_VERSION(region)          \
+       (((((region_desc_t *)(region))->reg[0]) >> SDS_REGION_SCH_MINOR_SHIFT)\
+       & SDS_REGION_SCH_VERSION_MASK)
+#define GET_SDS_REGION_SIZE(region)            ((((region_desc_t *)(region))->reg[1]))
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* SDS_PRIVATE_H */
diff --git a/drivers/arm/fvp/fvp_pwrc.c b/drivers/arm/fvp/fvp_pwrc.c
new file mode 100644 (file)
index 0000000..75a2b66
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/fvp/fvp_pwrc.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+/*
+ * TODO: Someday there will be a generic power controller api. At the moment
+ * each platform has its own pwrc so just exporting functions is fine.
+ */
+ARM_INSTANTIATE_LOCK;
+
+unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr)
+{
+       return PSYSR_WK(fvp_pwrc_read_psysr(mpidr));
+}
+
+unsigned int fvp_pwrc_read_psysr(u_register_t mpidr)
+{
+       unsigned int rc;
+       arm_lock_get();
+       mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr);
+       rc = mmio_read_32(PWRC_BASE + PSYSR_OFF);
+       arm_lock_release();
+       return rc;
+}
+
+void fvp_pwrc_write_pponr(u_register_t mpidr)
+{
+       arm_lock_get();
+       mmio_write_32(PWRC_BASE + PPONR_OFF, (unsigned int) mpidr);
+       arm_lock_release();
+}
+
+void fvp_pwrc_write_ppoffr(u_register_t mpidr)
+{
+       arm_lock_get();
+       mmio_write_32(PWRC_BASE + PPOFFR_OFF, (unsigned int) mpidr);
+       arm_lock_release();
+}
+
+void fvp_pwrc_set_wen(u_register_t mpidr)
+{
+       arm_lock_get();
+       mmio_write_32(PWRC_BASE + PWKUPR_OFF,
+                     (unsigned int) (PWKUPR_WEN | mpidr));
+       arm_lock_release();
+}
+
+void fvp_pwrc_clr_wen(u_register_t mpidr)
+{
+       arm_lock_get();
+       mmio_write_32(PWRC_BASE + PWKUPR_OFF,
+                     (unsigned int) mpidr);
+       arm_lock_release();
+}
+
+void fvp_pwrc_write_pcoffr(u_register_t mpidr)
+{
+       arm_lock_get();
+       mmio_write_32(PWRC_BASE + PCOFFR_OFF, (unsigned int) mpidr);
+       arm_lock_release();
+}
+
+/* Nothing else to do here apart from initializing the lock */
+void __init plat_arm_pwrc_setup(void)
+{
+       arm_lock_init();
+}
+
+
+
index e94de35c7ce27d287a397c16c2ec0c16477bc1dc..a135959232c3def79d96c1fe6895a69d11691dc2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -76,7 +76,7 @@ int console_putc(int c)
        console_t *console;
 
        for (console = console_list; console != NULL; console = console->next)
-               if (console->flags & console_state) {
+               if ((console->flags & console_state) && console->putc) {
                        int ret = console->putc(c, console);
                        if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err))
                                err = ret;
@@ -93,7 +93,7 @@ int console_getc(void)
        do {    /* Keep polling while at least one console works correctly. */
                for (console = console_list; console != NULL;
                     console = console->next)
-                       if (console->flags & console_state) {
+                       if ((console->flags & console_state) && console->getc) {
                                int ret = console->getc(console);
                                if (ret >= 0)
                                        return ret;
@@ -111,7 +111,7 @@ int console_flush(void)
        console_t *console;
 
        for (console = console_list; console != NULL; console = console->next)
-               if (console->flags & console_state) {
+               if ((console->flags & console_state) && console->flush) {
                        int ret = console->flush(console);
                        if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err))
                                err = ret;
index 50e87c1db4f29beceb626a21f6b4a0b2e7ed32bd..77d683c459d4660180f314bbfaf879a4d2aefeb6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -300,7 +300,7 @@ static int mmc_fill_device_info(void)
                break;
        }
 
-       if (ret != 0) {
+       if (ret < 0) {
                return ret;
        }
 
@@ -405,7 +405,7 @@ static int mmc_send_op_cond(void)
                        return 0;
                }
 
-               mdelay(1);
+               mdelay(10);
        }
 
        ERROR("CMD1 failed after %d retries\n", SEND_OP_COND_MAX_RETRIES);
index 07869acf50789f95c47b51663b05294b69186deb..6fa3df0f268cdf1e2919df812086e1ce3c866a4a 100644 (file)
@@ -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
  */
@@ -16,7 +16,7 @@
 #include <plat/common/platform.h>
 
 static uint8_t mbr_sector[PARTITION_BLOCK_SIZE];
-partition_entry_list_t list;
+static partition_entry_list_t list;
 
 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
 static void dump_entries(int num)
@@ -75,7 +75,7 @@ static int load_mbr_header(uintptr_t image_handle, mbr_entry_t *mbr_entry)
 
 /*
  * Load GPT header and check the GPT signature.
- * If partiton numbers could be found, check & update it.
+ * If partition numbers could be found, check & update it.
  */
 static int load_gpt_header(uintptr_t image_handle)
 {
index 6b0361497e0dc4a15aeebcc6798dd0f5f63512b9..4830853739bffc234deb20d441d886a5d38bb907 100644 (file)
@@ -24,6 +24,9 @@
 #define GPIO_INOUTSEL2         0xE6052004
 #define GPIO_INOUTSEL6         0xE6055404
 
+/* General IO/Interrupt Switching Register */
+#define GPIO_IOINTSEL6         0xE6055400
+
 /* GPIO/perihperal function select */
 #define PFC_GPSR2              0xE6060108
 #define PFC_GPSR6              0xE6060118
@@ -93,6 +96,7 @@ static void cpld_init(void)
        gpio_pfc(PFC_GPSR2, SSTBZ);
        gpio_pfc(PFC_GPSR6, MOSI);
 
+       gpio_set_value(GPIO_IOINTSEL6, SCLK, 0);
        gpio_set_value(GPIO_OUTDT6, SCLK, 0);
        gpio_set_value(GPIO_OUTDT2, SSTBZ, 1);
        gpio_set_value(GPIO_OUTDT6, MOSI, 0);
index b005caff69a57ee5ed903e2581ae20d98ed2588d..d7f088094b884294efd77596dae1c1e9ad5002b3 100644 (file)
@@ -768,3 +768,43 @@ count_ca57:
 done:
        return count;
 }
+
+int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr)
+{
+       uint64_t i;
+       uint64_t j;
+       uint64_t cpu_count;
+       uintptr_t reg_PSTR;
+       uint32_t status;
+       uint64_t my_cpu;
+       int32_t rtn;
+       uint32_t my_cluster_type;
+
+       const uint32_t cluster_type[PLATFORM_CLUSTER_COUNT] = {
+                       RCAR_CLUSTER_CA53,
+                       RCAR_CLUSTER_CA57
+       };
+       const uintptr_t registerPSTR[PLATFORM_CLUSTER_COUNT] = {
+                       RCAR_CA53PSTR,
+                       RCAR_CA57PSTR
+       };
+
+       my_cluster_type = rcar_pwrc_get_cluster();
+
+       rtn = 0;
+       my_cpu = mpidr & ((uint64_t)(MPIDR_CPU_MASK));
+       for (i = 0U; i < ((uint64_t)(PLATFORM_CLUSTER_COUNT)); i++) {
+               cpu_count = rcar_pwrc_get_cpu_num(cluster_type[i]);
+               reg_PSTR = registerPSTR[i];
+               for (j = 0U; j < cpu_count; j++) {
+                       if ((my_cluster_type != cluster_type[i]) || (my_cpu != j)) {
+                               status = mmio_read_32(reg_PSTR) >> (j * 4U);
+                               if ((status & 0x00000003U) == 0U) {
+                                       rtn--;
+                               }
+                       }
+               }
+       }
+       return (rtn);
+
+}
index 3cdac694c9e6f82875fd9e050034964141bcde53..d4d6fc4412d03bee4bdc89efba798fd18770f6cd 100644 (file)
@@ -44,6 +44,7 @@ void rcar_pwrc_enable_interrupt_wakeup(uint64_t mpidr);
 void rcar_pwrc_clusteroff(uint64_t mpidr);
 void rcar_pwrc_cpuoff(uint64_t mpidr);
 void rcar_pwrc_cpuon(uint64_t mpidr);
+int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr);
 void rcar_pwrc_setup(void);
 
 uint32_t rcar_pwrc_get_cpu_wkr(uint64_t mpidr);
diff --git a/drivers/rpi3/gpio/rpi3_gpio.c b/drivers/rpi3/gpio/rpi3_gpio.c
new file mode 100644 (file)
index 0000000..b39808f
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2019, Linaro Limited
+ * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include <assert.h>
+#include <lib/mmio.h>
+#include <drivers/delay_timer.h>
+#include <drivers/rpi3/gpio/rpi3_gpio.h>
+
+static struct rpi3_gpio_params rpi3_gpio_params;
+
+static int rpi3_gpio_get_direction(int gpio);
+static void rpi3_gpio_set_direction(int gpio, int direction);
+static int rpi3_gpio_get_value(int gpio);
+static void rpi3_gpio_set_value(int gpio, int value);
+static void rpi3_gpio_set_pull(int gpio, int pull);
+
+static const gpio_ops_t rpi3_gpio_ops = {
+       .get_direction  = rpi3_gpio_get_direction,
+       .set_direction  = rpi3_gpio_set_direction,
+       .get_value      = rpi3_gpio_get_value,
+       .set_value      = rpi3_gpio_set_value,
+       .set_pull       = rpi3_gpio_set_pull,
+};
+
+/**
+ * Get selection of GPIO pinmux settings.
+ *
+ * @param gpio The pin number of GPIO. From 0 to 53.
+ * @return The selection of pinmux. RPI3_GPIO_FUNC_INPUT: input,
+ *                                  RPI3_GPIO_FUNC_OUTPUT: output,
+ *                                  RPI3_GPIO_FUNC_ALT0: alt-0,
+ *                                  RPI3_GPIO_FUNC_ALT1: alt-1,
+ *                                  RPI3_GPIO_FUNC_ALT2: alt-2,
+ *                                  RPI3_GPIO_FUNC_ALT3: alt-3,
+ *                                  RPI3_GPIO_FUNC_ALT4: alt-4,
+ *                                  RPI3_GPIO_FUNC_ALT5: alt-5
+ */
+int rpi3_gpio_get_select(int gpio)
+{
+       int ret;
+       uintptr_t reg_base = rpi3_gpio_params.reg_base;
+       int regN = gpio / 10;
+       int shift = 3 * (gpio % 10);
+       uintptr_t reg_sel = reg_base + RPI3_GPIO_GPFSEL(regN);
+       uint32_t sel = mmio_read_32(reg_sel);
+
+       ret = (sel >> shift) & 0x07;
+
+       return ret;
+}
+
+/**
+ * Set selection of GPIO pinmux settings.
+ *
+ * @param gpio The pin number of GPIO. From 0 to 53.
+ * @param fsel The selection of pinmux. RPI3_GPIO_FUNC_INPUT: input,
+ *                                      RPI3_GPIO_FUNC_OUTPUT: output,
+ *                                      RPI3_GPIO_FUNC_ALT0: alt-0,
+ *                                      RPI3_GPIO_FUNC_ALT1: alt-1,
+ *                                      RPI3_GPIO_FUNC_ALT2: alt-2,
+ *                                      RPI3_GPIO_FUNC_ALT3: alt-3,
+ *                                      RPI3_GPIO_FUNC_ALT4: alt-4,
+ *                                      RPI3_GPIO_FUNC_ALT5: alt-5
+ */
+void rpi3_gpio_set_select(int gpio, int fsel)
+{
+       uintptr_t reg_base = rpi3_gpio_params.reg_base;
+       int regN = gpio / 10;
+       int shift = 3 * (gpio % 10);
+       uintptr_t reg_sel = reg_base + RPI3_GPIO_GPFSEL(regN);
+       uint32_t sel = mmio_read_32(reg_sel);
+       uint32_t mask = U(0x07) << shift;
+
+       sel = (sel & (~mask)) | ((fsel << shift) & mask);
+       mmio_write_32(reg_sel, sel);
+}
+
+static int rpi3_gpio_get_direction(int gpio)
+{
+       int result = rpi3_gpio_get_select(gpio);
+
+       if (result == RPI3_GPIO_FUNC_INPUT)
+               return GPIO_DIR_IN;
+       else if (result == RPI3_GPIO_FUNC_OUTPUT)
+               return GPIO_DIR_OUT;
+
+       return GPIO_DIR_IN;
+}
+
+static void rpi3_gpio_set_direction(int gpio, int direction)
+{
+       switch (direction) {
+       case GPIO_DIR_IN:
+               rpi3_gpio_set_select(gpio, RPI3_GPIO_FUNC_INPUT);
+               break;
+       case GPIO_DIR_OUT:
+               rpi3_gpio_set_select(gpio, RPI3_GPIO_FUNC_OUTPUT);
+               break;
+       }
+}
+
+static int rpi3_gpio_get_value(int gpio)
+{
+       uintptr_t reg_base = rpi3_gpio_params.reg_base;
+       int regN = gpio / 32;
+       int shift = gpio % 32;
+       uintptr_t reg_lev = reg_base + RPI3_GPIO_GPLEV(regN);
+       uint32_t value = mmio_read_32(reg_lev);
+
+       if ((value >> shift) & 0x01)
+               return GPIO_LEVEL_HIGH;
+       return GPIO_LEVEL_LOW;
+}
+
+static void rpi3_gpio_set_value(int gpio, int value)
+{
+       uintptr_t reg_base = rpi3_gpio_params.reg_base;
+       int regN = gpio / 32;
+       int shift = gpio % 32;
+       uintptr_t reg_set = reg_base + RPI3_GPIO_GPSET(regN);
+       uintptr_t reg_clr = reg_base + RPI3_GPIO_GPSET(regN);
+
+       switch (value) {
+       case GPIO_LEVEL_LOW:
+               mmio_write_32(reg_clr, U(1) << shift);
+               break;
+       case GPIO_LEVEL_HIGH:
+               mmio_write_32(reg_set, U(1) << shift);
+               break;
+       }
+}
+
+static void rpi3_gpio_set_pull(int gpio, int pull)
+{
+       uintptr_t reg_base = rpi3_gpio_params.reg_base;
+       int regN = gpio / 32;
+       int shift = gpio % 32;
+       uintptr_t reg_pud = reg_base + RPI3_GPIO_GPPUD;
+       uintptr_t reg_clk = reg_base + RPI3_GPIO_GPPUDCLK(regN);
+
+       switch (pull) {
+       case GPIO_PULL_NONE:
+               mmio_write_32(reg_pud, 0x0);
+               break;
+       case GPIO_PULL_UP:
+               mmio_write_32(reg_pud, 0x2);
+               break;
+       case GPIO_PULL_DOWN:
+               mmio_write_32(reg_pud, 0x1);
+               break;
+       }
+       mdelay(150);
+       mmio_write_32(reg_clk, U(1) << shift);
+       mdelay(150);
+       mmio_write_32(reg_clk, 0x0);
+       mmio_write_32(reg_pud, 0x0);
+}
+
+void rpi3_gpio_init(struct rpi3_gpio_params *params)
+{
+       assert(params != 0);
+       memcpy(&rpi3_gpio_params, params, sizeof(struct rpi3_gpio_params));
+       gpio_init(&rpi3_gpio_ops);
+}
diff --git a/drivers/st/bsec/bsec.c b/drivers/st/bsec/bsec.c
new file mode 100644 (file)
index 0000000..aaecf1f
--- /dev/null
@@ -0,0 +1,913 @@
+/*
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <limits.h>
+
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/st/bsec.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+
+#define BSEC_IP_VERSION_1_0    0x10
+#define BSEC_COMPAT            "st,stm32mp15-bsec"
+
+#define OTP_ACCESS_SIZE (round_up(OTP_MAX_SIZE, __WORD_BIT) / __WORD_BIT)
+
+static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __unused;
+
+static uint32_t bsec_power_safmem(bool power);
+
+/* BSEC access protection */
+static spinlock_t bsec_spinlock;
+static uintptr_t bsec_base;
+
+static void bsec_lock(void)
+{
+       const uint32_t mask = SCTLR_M_BIT | SCTLR_C_BIT;
+
+       /* Lock is currently required only when MMU and cache are enabled */
+       if ((read_sctlr() & mask) == mask) {
+               spin_lock(&bsec_spinlock);
+       }
+}
+
+static void bsec_unlock(void)
+{
+       const uint32_t mask = SCTLR_M_BIT | SCTLR_C_BIT;
+
+       /* Unlock is required only when MMU and cache are enabled */
+       if ((read_sctlr() & mask) == mask) {
+               spin_unlock(&bsec_spinlock);
+       }
+}
+
+static int bsec_get_dt_node(struct dt_node_info *info)
+{
+       int node;
+
+       node = dt_get_node(info, -1, BSEC_COMPAT);
+       if (node < 0) {
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       return node;
+}
+
+#if defined(IMAGE_BL32)
+static void enable_non_secure_access(uint32_t otp)
+{
+       otp_nsec_access[otp / __WORD_BIT] |= BIT(otp % __WORD_BIT);
+
+       if (bsec_shadow_register(otp) != BSEC_OK) {
+               panic();
+       }
+}
+
+static bool non_secure_can_access(uint32_t otp)
+{
+       return (otp_nsec_access[otp / __WORD_BIT] &
+               BIT(otp % __WORD_BIT)) != 0;
+}
+
+static int bsec_dt_otp_nsec_access(void *fdt, int bsec_node)
+{
+       int bsec_subnode;
+
+       fdt_for_each_subnode(bsec_subnode, fdt, bsec_node) {
+               const fdt32_t *cuint;
+               uint32_t reg;
+               uint32_t i;
+               uint32_t size;
+               uint8_t status;
+
+               cuint = fdt_getprop(fdt, bsec_subnode, "reg", NULL);
+               if (cuint == NULL) {
+                       panic();
+               }
+
+               reg = fdt32_to_cpu(*cuint) / sizeof(uint32_t);
+               if (reg < STM32MP1_UPPER_OTP_START) {
+                       continue;
+               }
+
+               status = fdt_get_status(bsec_subnode);
+               if ((status & DT_NON_SECURE) == 0U)  {
+                       continue;
+               }
+
+               size = fdt32_to_cpu(*(cuint + 1)) / sizeof(uint32_t);
+
+               if ((fdt32_to_cpu(*(cuint + 1)) % sizeof(uint32_t)) != 0) {
+                       size++;
+               }
+
+               for (i = reg; i < (reg + size); i++) {
+                       enable_non_secure_access(i);
+               }
+       }
+
+       return 0;
+}
+#endif
+
+static uint32_t otp_bank_offset(uint32_t otp)
+{
+       assert(otp <= STM32MP1_OTP_MAX_ID);
+
+       return ((otp & ~BSEC_OTP_MASK) >> BSEC_OTP_BANK_SHIFT) *
+              sizeof(uint32_t);
+}
+
+static uint32_t bsec_check_error(uint32_t otp)
+{
+       uint32_t bit = BIT(otp & BSEC_OTP_MASK);
+       uint32_t bank = otp_bank_offset(otp);
+
+       if ((mmio_read_32(bsec_base + BSEC_DISTURBED_OFF + bank) & bit) != 0U) {
+               return BSEC_DISTURBED;
+       }
+
+       if ((mmio_read_32(bsec_base + BSEC_ERROR_OFF + bank) & bit) != 0U) {
+               return BSEC_ERROR;
+       }
+
+       return BSEC_OK;
+}
+
+/*
+ * bsec_probe: initialize BSEC driver.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_probe(void)
+{
+       void *fdt;
+       int node;
+       struct dt_node_info bsec_info;
+
+       if (fdt_get_address(&fdt) == 0) {
+               panic();
+       }
+
+       node = bsec_get_dt_node(&bsec_info);
+       if (node < 0) {
+               panic();
+       }
+
+       bsec_base = bsec_info.base;
+
+#if defined(IMAGE_BL32)
+       bsec_dt_otp_nsec_access(fdt, node);
+#endif
+       return BSEC_OK;
+}
+
+/*
+ * bsec_get_base: return BSEC base address.
+ */
+uint32_t bsec_get_base(void)
+{
+       return bsec_base;
+}
+
+/*
+ * bsec_set_config: enable and configure BSEC.
+ * cfg: pointer to param structure used to set register.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_config(struct bsec_config *cfg)
+{
+       uint32_t value;
+       int32_t result;
+
+       value = ((((uint32_t)cfg->freq << BSEC_CONF_FRQ_SHIFT) &
+                                               BSEC_CONF_FRQ_MASK) |
+                (((uint32_t)cfg->pulse_width << BSEC_CONF_PRG_WIDTH_SHIFT) &
+                                               BSEC_CONF_PRG_WIDTH_MASK) |
+                (((uint32_t)cfg->tread << BSEC_CONF_TREAD_SHIFT) &
+                                               BSEC_CONF_TREAD_MASK));
+
+       bsec_lock();
+
+       mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, value);
+
+       bsec_unlock();
+
+       result = bsec_power_safmem((bool)cfg->power &
+                                  BSEC_CONF_POWER_UP_MASK);
+       if (result != BSEC_OK) {
+               return result;
+       }
+
+       value = ((((uint32_t)cfg->upper_otp_lock << UPPER_OTP_LOCK_SHIFT) &
+                                               UPPER_OTP_LOCK_MASK) |
+                (((uint32_t)cfg->den_lock << DENREG_LOCK_SHIFT) &
+                                               DENREG_LOCK_MASK) |
+                (((uint32_t)cfg->prog_lock << GPLOCK_LOCK_SHIFT) &
+                                               GPLOCK_LOCK_MASK));
+
+       bsec_lock();
+
+       mmio_write_32(bsec_base + BSEC_OTP_LOCK_OFF, value);
+
+       bsec_unlock();
+
+       return BSEC_OK;
+}
+
+/*
+ * bsec_get_config: return config parameters set in BSEC registers.
+ * cfg: config param return.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_get_config(struct bsec_config *cfg)
+{
+       uint32_t value;
+
+       if (cfg == NULL) {
+               return BSEC_INVALID_PARAM;
+       }
+
+       value = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
+       cfg->power = (uint8_t)((value & BSEC_CONF_POWER_UP_MASK) >>
+                                               BSEC_CONF_POWER_UP_SHIFT);
+       cfg->freq = (uint8_t)((value & BSEC_CONF_FRQ_MASK) >>
+                                               BSEC_CONF_FRQ_SHIFT);
+       cfg->pulse_width = (uint8_t)((value & BSEC_CONF_PRG_WIDTH_MASK) >>
+                                               BSEC_CONF_PRG_WIDTH_SHIFT);
+       cfg->tread = (uint8_t)((value & BSEC_CONF_TREAD_MASK) >>
+                                               BSEC_CONF_TREAD_SHIFT);
+
+       value = mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF);
+       cfg->upper_otp_lock = (uint8_t)((value & UPPER_OTP_LOCK_MASK) >>
+                                               UPPER_OTP_LOCK_SHIFT);
+       cfg->den_lock = (uint8_t)((value & DENREG_LOCK_MASK) >>
+                                               DENREG_LOCK_SHIFT);
+       cfg->prog_lock = (uint8_t)((value & GPLOCK_LOCK_MASK) >>
+                                               GPLOCK_LOCK_SHIFT);
+
+       return BSEC_OK;
+}
+
+/*
+ * bsec_shadow_register: copy SAFMEM OTP to BSEC data.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_shadow_register(uint32_t otp)
+{
+       uint32_t result;
+       bool power_up = false;
+
+       if (otp > STM32MP1_OTP_MAX_ID) {
+               return BSEC_INVALID_PARAM;
+       }
+
+       /* Check if shadowing of OTP is locked */
+       if (bsec_read_sr_lock(otp)) {
+               VERBOSE("BSEC: OTP %i is locked and will not be refreshed\n",
+                       otp);
+       }
+
+       if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+               result = bsec_power_safmem(true);
+
+               if (result != BSEC_OK) {
+                       return result;
+               }
+
+               power_up = true;
+       }
+
+       bsec_lock();
+
+       /* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
+       mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_READ);
+
+       while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+               ;
+       }
+
+       result = bsec_check_error(otp);
+
+       bsec_unlock();
+
+       if (power_up) {
+               if (bsec_power_safmem(false) != BSEC_OK) {
+                       panic();
+               }
+       }
+
+       return result;
+}
+
+/*
+ * bsec_read_otp: read an OTP data value.
+ * val: read value.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_otp(uint32_t *val, uint32_t otp)
+{
+       uint32_t result;
+
+       if (otp > STM32MP1_OTP_MAX_ID) {
+               return BSEC_INVALID_PARAM;
+       }
+
+       bsec_lock();
+
+       *val = mmio_read_32(bsec_base + BSEC_OTP_DATA_OFF +
+                           (otp * sizeof(uint32_t)));
+
+       result = bsec_check_error(otp);
+
+       bsec_unlock();
+
+       return result;
+}
+
+/*
+ * bsec_write_otp: write value in BSEC data register.
+ * val: value to write.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_write_otp(uint32_t val, uint32_t otp)
+{
+       uint32_t result;
+
+       if (otp > STM32MP1_OTP_MAX_ID) {
+               return BSEC_INVALID_PARAM;
+       }
+
+       /* Check if programming of OTP is locked */
+       if (bsec_read_sw_lock(otp)) {
+               VERBOSE("BSEC: OTP %i is locked and write will be ignored\n",
+                       otp);
+       }
+
+       bsec_lock();
+
+       mmio_write_32(bsec_base + BSEC_OTP_DATA_OFF +
+                     (otp * sizeof(uint32_t)), val);
+
+       result = bsec_check_error(otp);
+
+       bsec_unlock();
+
+       return result;
+}
+
+/*
+ * bsec_program_otp: program a bit in SAFMEM after the prog.
+ *     The OTP data is not refreshed.
+ * val: value to program.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
+{
+       uint32_t result;
+       bool power_up = false;
+
+       if (otp > STM32MP1_OTP_MAX_ID) {
+               return BSEC_INVALID_PARAM;
+       }
+
+       /* Check if programming of OTP is locked */
+       if (bsec_read_sp_lock(otp)) {
+               WARN("BSEC: OTP locked, prog will be ignored\n");
+       }
+
+       if ((mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF) &
+            BIT(BSEC_LOCK_PROGRAM)) != 0U) {
+               WARN("BSEC: GPLOCK activated, prog will be ignored\n");
+       }
+
+       if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+               result = bsec_power_safmem(true);
+
+               if (result != BSEC_OK) {
+                       return result;
+               }
+
+               power_up = true;
+       }
+
+       bsec_lock();
+
+       /* Set value in write register */
+       mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, val);
+
+       /* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
+       mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE);
+
+       while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+               ;
+       }
+
+       if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+               result = BSEC_PROG_FAIL;
+       } else {
+               result = bsec_check_error(otp);
+       }
+
+       bsec_unlock();
+
+       if (power_up) {
+               if (bsec_power_safmem(false) != BSEC_OK) {
+                       panic();
+               }
+       }
+
+       return result;
+}
+
+/*
+ * bsec_permanent_lock_otp: permanent lock of OTP in SAFMEM.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_permanent_lock_otp(uint32_t otp)
+{
+       uint32_t result;
+       bool power_up = false;
+       uint32_t data;
+       uint32_t addr;
+
+       if (otp > STM32MP1_OTP_MAX_ID) {
+               return BSEC_INVALID_PARAM;
+       }
+
+       if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+               result = bsec_power_safmem(true);
+
+               if (result != BSEC_OK) {
+                       return result;
+               }
+
+               power_up = true;
+       }
+
+       if (otp < STM32MP1_UPPER_OTP_START) {
+               addr = otp >> ADDR_LOWER_OTP_PERLOCK_SHIFT;
+               data = DATA_LOWER_OTP_PERLOCK_BIT <<
+                      ((otp & DATA_LOWER_OTP_PERLOCK_MASK) << 1U);
+       } else {
+               addr = (otp >> ADDR_UPPER_OTP_PERLOCK_SHIFT) + 2U;
+               data = DATA_UPPER_OTP_PERLOCK_BIT <<
+                      (otp & DATA_UPPER_OTP_PERLOCK_MASK);
+       }
+
+       bsec_lock();
+
+       /* Set value in write register */
+       mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, data);
+
+       /* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
+       mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF,
+                     addr | BSEC_WRITE | BSEC_LOCK);
+
+       while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+               ;
+       }
+
+       if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+               result = BSEC_PROG_FAIL;
+       } else {
+               result = bsec_check_error(otp);
+       }
+
+       bsec_unlock();
+
+       if (power_up) {
+               if (bsec_power_safmem(false) != BSEC_OK) {
+                       panic();
+               }
+       }
+
+       return result;
+}
+
+/*
+ * bsec_write_debug_conf: write value in debug feature
+ *     to enable/disable debug service.
+ * val: value to write.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_write_debug_conf(uint32_t val)
+{
+       uint32_t result = BSEC_ERROR;
+       uint32_t masked_val = val & BSEC_DEN_ALL_MSK;
+
+       bsec_lock();
+
+       mmio_write_32(bsec_base + BSEC_DEN_OFF, masked_val);
+
+       if ((mmio_read_32(bsec_base + BSEC_DEN_OFF) ^ masked_val) == 0U) {
+               result = BSEC_OK;
+       }
+
+       bsec_unlock();
+
+       return result;
+}
+
+/*
+ * bsec_read_debug_conf: read debug configuration.
+ */
+uint32_t bsec_read_debug_conf(void)
+{
+       return mmio_read_32(bsec_base + BSEC_DEN_OFF);
+}
+
+/*
+ * bsec_get_status: return status register value.
+ */
+uint32_t bsec_get_status(void)
+{
+       return mmio_read_32(bsec_base + BSEC_OTP_STATUS_OFF);
+}
+
+/*
+ * bsec_get_hw_conf: return hardware configuration.
+ */
+uint32_t bsec_get_hw_conf(void)
+{
+       return mmio_read_32(bsec_base + BSEC_IPHW_CFG_OFF);
+}
+
+/*
+ * bsec_get_version: return BSEC version.
+ */
+uint32_t bsec_get_version(void)
+{
+       return mmio_read_32(bsec_base + BSEC_IPVR_OFF);
+}
+
+/*
+ * bsec_get_id: return BSEC ID.
+ */
+uint32_t bsec_get_id(void)
+{
+       return mmio_read_32(bsec_base + BSEC_IP_ID_OFF);
+}
+
+/*
+ * bsec_get_magic_id: return BSEC magic number.
+ */
+uint32_t bsec_get_magic_id(void)
+{
+       return mmio_read_32(bsec_base + BSEC_IP_MAGIC_ID_OFF);
+}
+
+/*
+ * bsec_write_sr_lock: write shadow-read lock.
+ * otp: OTP number.
+ * value: value to write in the register.
+ *     Must be always 1.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_write_sr_lock(uint32_t otp, uint32_t value)
+{
+       bool result = false;
+       uint32_t bank = otp_bank_offset(otp);
+       uint32_t bank_value;
+       uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+
+       bsec_lock();
+
+       bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
+
+       if ((bank_value & otp_mask) == value) {
+               /*
+                * In case of write don't need to write,
+                * the lock is already set.
+                */
+               if (value != 0U) {
+                       result = true;
+               }
+       } else {
+               if (value != 0U) {
+                       bank_value = bank_value | otp_mask;
+               } else {
+                       bank_value = bank_value & ~otp_mask;
+               }
+
+               /*
+                * We can write 0 in all other OTP
+                * if the lock is activated in one of other OTP.
+                * Write 0 has no effect.
+                */
+               mmio_write_32(bsec_base + BSEC_SRLOCK_OFF + bank, bank_value);
+               result = true;
+       }
+
+       bsec_unlock();
+
+       return result;
+}
+
+/*
+ * bsec_read_sr_lock: read shadow-read lock.
+ * otp: OTP number.
+ * return: true if otp is locked, else false.
+ */
+bool bsec_read_sr_lock(uint32_t otp)
+{
+       uint32_t bank = otp_bank_offset(otp);
+       uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+       uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
+
+       return (bank_value & otp_mask) != 0U;
+}
+
+/*
+ * bsec_write_sw_lock: write shadow-write lock.
+ * otp: OTP number.
+ * value: Value to write in the register.
+ *     Must be always 1.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_write_sw_lock(uint32_t otp, uint32_t value)
+{
+       bool result = false;
+       uint32_t bank = otp_bank_offset(otp);
+       uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+       uint32_t bank_value;
+
+       bsec_lock();
+
+       bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
+
+       if ((bank_value & otp_mask) == value) {
+               /*
+                * In case of write don't need to write,
+                * the lock is already set.
+                */
+               if (value != 0U) {
+                       result = true;
+               }
+       } else {
+               if (value != 0U) {
+                       bank_value = bank_value | otp_mask;
+               } else {
+                       bank_value = bank_value & ~otp_mask;
+               }
+
+               /*
+                * We can write 0 in all other OTP
+                * if the lock is activated in one of other OTP.
+                * Write 0 has no effect.
+                */
+               mmio_write_32(bsec_base + BSEC_SWLOCK_OFF + bank, bank_value);
+               result = true;
+       }
+
+       bsec_unlock();
+
+       return result;
+}
+
+/*
+ * bsec_read_sw_lock: read shadow-write lock.
+ * otp: OTP number.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_read_sw_lock(uint32_t otp)
+{
+       uint32_t bank = otp_bank_offset(otp);
+       uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+       uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
+
+       return (bank_value & otp_mask) != 0U;
+}
+
+/*
+ * bsec_write_sp_lock: write shadow-program lock.
+ * otp: OTP number.
+ * value: Value to write in the register.
+ *     Must be always 1.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_write_sp_lock(uint32_t otp, uint32_t value)
+{
+       bool result = false;
+       uint32_t bank = otp_bank_offset(otp);
+       uint32_t bank_value;
+       uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+
+       bsec_lock();
+
+       bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
+
+       if ((bank_value & otp_mask) == value) {
+               /*
+                * In case of write don't need to write,
+                * the lock is already set.
+                */
+               if (value != 0U) {
+                       result = true;
+               }
+       } else {
+               if (value != 0U) {
+                       bank_value = bank_value | otp_mask;
+               } else {
+                       bank_value = bank_value & ~otp_mask;
+               }
+
+               /*
+                * We can write 0 in all other OTP
+                * if the lock is activated in one of other OTP.
+                * Write 0 has no effect.
+                */
+               mmio_write_32(bsec_base + BSEC_SPLOCK_OFF + bank, bank_value);
+               result = true;
+       }
+
+       bsec_unlock();
+
+       return result;
+}
+
+/*
+ * bsec_read_sp_lock: read shadow-program lock.
+ * otp: OTP number.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_read_sp_lock(uint32_t otp)
+{
+       uint32_t bank = otp_bank_offset(otp);
+       uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+       uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
+
+       return (bank_value & otp_mask) != 0U;
+}
+
+/*
+ * bsec_wr_lock: Read permanent lock status.
+ * otp: OTP number.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_wr_lock(uint32_t otp)
+{
+       uint32_t bank = otp_bank_offset(otp);
+       uint32_t lock_bit = BIT(otp & BSEC_OTP_MASK);
+
+       if ((mmio_read_32(bsec_base + BSEC_WRLOCK_OFF + bank) &
+            lock_bit) != 0U) {
+               /*
+                * In case of write don't need to write,
+                * the lock is already set.
+                */
+               return true;
+       }
+
+       return false;
+}
+
+/*
+ * bsec_otp_lock: Lock Upper OTP or Global programming or debug enable
+ * service: Service to lock see header file.
+ * value: Value to write must always set to 1 (only use for debug purpose).
+ * return: BSEC_OK if succeed.
+ */
+uint32_t bsec_otp_lock(uint32_t service, uint32_t value)
+{
+       uintptr_t reg = bsec_base + BSEC_OTP_LOCK_OFF;
+
+       switch (service) {
+       case BSEC_LOCK_UPPER_OTP:
+               mmio_write_32(reg, value << BSEC_LOCK_UPPER_OTP);
+               break;
+       case BSEC_LOCK_DEBUG:
+               mmio_write_32(reg, value << BSEC_LOCK_DEBUG);
+               break;
+       case BSEC_LOCK_PROGRAM:
+               mmio_write_32(reg, value << BSEC_LOCK_PROGRAM);
+               break;
+       default:
+               return BSEC_INVALID_PARAM;
+       }
+
+       return BSEC_OK;
+}
+
+/*
+ * bsec_power_safmem: Activate or deactivate SAFMEM power.
+ * power: true to power up, false to power down.
+ * return: BSEC_OK if succeed.
+ */
+static uint32_t bsec_power_safmem(bool power)
+{
+       uint32_t register_val;
+       uint32_t timeout = BSEC_TIMEOUT_VALUE;
+
+       bsec_lock();
+
+       register_val = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
+
+       if (power) {
+               register_val |= BSEC_CONF_POWER_UP_MASK;
+       } else {
+               register_val &= ~BSEC_CONF_POWER_UP_MASK;
+       }
+
+       mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, register_val);
+
+       /* Waiting loop */
+       if (power) {
+               while (((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) &&
+                      (timeout != 0U)) {
+                       timeout--;
+               }
+       } else {
+               while (((bsec_get_status() & BSEC_MODE_PWR_MASK) != 0U) &&
+                      (timeout != 0U)) {
+                       timeout--;
+               }
+       }
+
+       bsec_unlock();
+
+       if (timeout == 0U) {
+               return BSEC_TIMEOUT;
+       }
+
+       return BSEC_OK;
+}
+
+/*
+ * bsec_mode_is_closed_device: read OTP secure sub-mode.
+ * return: false if open_device and true of closed_device.
+ */
+bool bsec_mode_is_closed_device(void)
+{
+       uint32_t value;
+
+       if ((bsec_shadow_register(DATA0_OTP) != BSEC_OK) ||
+           (bsec_read_otp(&value, DATA0_OTP) != BSEC_OK)) {
+               return true;
+       }
+
+       return (value & DATA0_OTP_SECURED) == DATA0_OTP_SECURED;
+}
+
+/*
+ * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value
+ * otp_value: read value.
+ * word: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word)
+{
+       uint32_t result;
+
+       result = bsec_shadow_register(word);
+       if (result != BSEC_OK) {
+               ERROR("BSEC: %u Shadowing Error %i\n", word, result);
+               return result;
+       }
+
+       result = bsec_read_otp(otp_value, word);
+       if (result != BSEC_OK) {
+               ERROR("BSEC: %u Read Error %i\n", word, result);
+       }
+
+       return result;
+}
+
+/*
+ * bsec_check_nsec_access_rights: check non-secure access rights to target OTP.
+ * otp: OTP number.
+ * return: BSEC_OK if authorized access.
+ */
+uint32_t bsec_check_nsec_access_rights(uint32_t otp)
+{
+#if defined(IMAGE_BL32)
+       if (otp > STM32MP1_OTP_MAX_ID) {
+               return BSEC_INVALID_PARAM;
+       }
+
+       if (otp >= STM32MP1_UPPER_OTP_START) {
+               /* Check if BSEC is in OTP-SECURED closed_device state. */
+               if (bsec_mode_is_closed_device()) {
+                       if (!non_secure_can_access(otp)) {
+                               return BSEC_ERROR;
+                       }
+               }
+       }
+#endif
+
+       return BSEC_OK;
+}
+
index 1d92271063c8f4a054845c2979e555675d9a7fd0..19dfe1b25417df5f9146157851edf2dcbd0d3819 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,11 +31,19 @@ const char *stm32mp_osc_node_label[NB_OSC] = {
        [_USB_PHY_48] = "ck_usbo_48m"
 };
 
+/*******************************************************************************
+ * This function returns the RCC node in the device tree.
+ ******************************************************************************/
+static int fdt_get_rcc_node(void *fdt)
+{
+       return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+}
+
 /*******************************************************************************
  * This function reads the frequency of an oscillator from its name.
  * It reads the value indicated inside the device tree.
- * Returns 0 if success, and a negative value else.
- * If success, value is stored in the second parameter.
+ * Returns 0 on success, and a negative FDT/ERRNO error code on failure.
+ * On success, value is stored in the second parameter.
  ******************************************************************************/
 int fdt_osc_read_freq(const char *name, uint32_t *freq)
 {
@@ -127,7 +135,7 @@ bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name)
 
 /*******************************************************************************
  * This function reads a value of a oscillator property from its id.
- * Returns value if success, and a default value if property not found.
+ * Returns value on success, and a default value if property not found.
  * Default value is passed as parameter.
  ******************************************************************************/
 uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
@@ -240,7 +248,7 @@ int fdt_rcc_read_uint32_array(const char *prop_name,
 /*******************************************************************************
  * This function gets the subnode offset in rcc-clk section from its name.
  * It reads the values indicated inside the device tree.
- * Returns offset if success, and a negative value else.
+ * Returns offset on success, and a negative FDT/ERRNO error code on failure.
  ******************************************************************************/
 int fdt_rcc_subnode_offset(const char *name)
 {
@@ -251,7 +259,7 @@ int fdt_rcc_subnode_offset(const char *name)
                return -ENOENT;
        }
 
-       node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+       node = fdt_get_rcc_node(fdt);
        if (node < 0) {
                return -FDT_ERR_NOTFOUND;
        }
@@ -280,7 +288,7 @@ const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
                return NULL;
        }
 
-       node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+       node = fdt_get_rcc_node(fdt);
        if (node < 0) {
                return NULL;
        }
@@ -297,7 +305,7 @@ const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
 /*******************************************************************************
  * This function gets the secure status for rcc node.
  * It reads secure-status in device tree.
- * Returns 1 if rcc is available from secure world, 0 else.
+ * Returns true if rcc is available from secure world, false if not.
  ******************************************************************************/
 bool fdt_get_rcc_secure_status(void)
 {
@@ -308,18 +316,18 @@ bool fdt_get_rcc_secure_status(void)
                return false;
        }
 
-       node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_COMPAT);
+       node = fdt_get_rcc_node(fdt);
        if (node < 0) {
                return false;
        }
 
-       return fdt_check_secure_status(node);
+       return (fdt_get_status(node) & DT_SECURE) != 0U;
 }
 
 /*******************************************************************************
  * This function reads the stgen base address.
  * It reads the value indicated inside the device tree.
- * Returns address if success, and NULL value else.
+ * Returns address on success, and NULL value on failure.
  ******************************************************************************/
 uintptr_t fdt_get_stgen_base(void)
 {
@@ -347,7 +355,7 @@ uintptr_t fdt_get_stgen_base(void)
 /*******************************************************************************
  * This function gets the clock ID of the given node.
  * It reads the value indicated inside the device tree.
- * Returns ID if success, and a negative value else.
+ * Returns ID on success, and a negative FDT/ERRNO error code on failure.
  ******************************************************************************/
 int fdt_get_clock_id(int node)
 {
index aca04504f6ca6f9ce5cb54a5faedf091677954fa..79aff6e739058f0f15e2915eab7381abbc261f8d 100644 (file)
@@ -1,9 +1,10 @@
 /*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
 
+#include <errno.h>
 #include <stddef.h>
 
 #include <platform_def.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp_pmic.h>
 #include <drivers/st/stm32mp1_clk.h>
 #include <drivers/st/stm32mp1_ddr.h>
 #include <drivers/st/stm32mp1_ddr_regs.h>
-#include <drivers/st/stm32mp1_pmic.h>
 #include <drivers/st/stm32mp1_pwr.h>
 #include <drivers/st/stm32mp1_ram.h>
 #include <drivers/st/stm32mp1_rcc.h>
@@ -233,40 +234,67 @@ struct ddr_reg_info {
 
 static const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = {
        [REG_REG] = {
-               "static", ddr_reg, ARRAY_SIZE(ddr_reg), DDR_BASE
+               .name = "static",
+               .desc = ddr_reg,
+               .size = ARRAY_SIZE(ddr_reg),
+               .base = DDR_BASE
        },
        [REG_TIMING] = {
-               "timing", ddr_timing, ARRAY_SIZE(ddr_timing), DDR_BASE
+               .name = "timing",
+               .desc = ddr_timing,
+               .size = ARRAY_SIZE(ddr_timing),
+               .base = DDR_BASE
        },
        [REG_PERF] = {
-               "perf", ddr_perf, ARRAY_SIZE(ddr_perf), DDR_BASE
+               .name = "perf",
+               .desc = ddr_perf,
+               .size = ARRAY_SIZE(ddr_perf),
+               .base = DDR_BASE
        },
        [REG_MAP] = {
-               "map", ddr_map, ARRAY_SIZE(ddr_map), DDR_BASE
+               .name = "map",
+               .desc = ddr_map,
+               .size = ARRAY_SIZE(ddr_map),
+               .base = DDR_BASE
        },
        [REGPHY_REG] = {
-               "static", ddrphy_reg, ARRAY_SIZE(ddrphy_reg), DDRPHY_BASE
+               .name = "static",
+               .desc = ddrphy_reg,
+               .size = ARRAY_SIZE(ddrphy_reg),
+               .base = DDRPHY_BASE
        },
        [REGPHY_TIMING] = {
-               "timing", ddrphy_timing, ARRAY_SIZE(ddrphy_timing), DDRPHY_BASE
+               .name = "timing",
+               .desc = ddrphy_timing,
+               .size = ARRAY_SIZE(ddrphy_timing),
+               .base = DDRPHY_BASE
        },
        [REGPHY_CAL] = {
-               "cal", ddrphy_cal, ARRAY_SIZE(ddrphy_cal), DDRPHY_BASE
+               .name = "cal",
+               .desc = ddrphy_cal,
+               .size = ARRAY_SIZE(ddrphy_cal),
+               .base = DDRPHY_BASE
        },
        [REG_DYN] = {
-               "dyn", ddr_dyn, ARRAY_SIZE(ddr_dyn), DDR_BASE
+               .name = "dyn",
+               .desc = ddr_dyn,
+               .size = ARRAY_SIZE(ddr_dyn),
+               .base = DDR_BASE
        },
        [REGPHY_DYN] = {
-               "dyn", ddrphy_dyn, ARRAY_SIZE(ddrphy_dyn), DDRPHY_BASE
+               .name = "dyn",
+               .desc = ddrphy_dyn,
+               .size = ARRAY_SIZE(ddrphy_dyn),
+               .base = DDRPHY_BASE
        },
 };
 
-static uint32_t get_base_addr(const struct ddr_info *priv, enum base_type base)
+static uintptr_t get_base_addr(const struct ddr_info *priv, enum base_type base)
 {
        if (base == DDRPHY_BASE) {
-               return (uint32_t)priv->phy;
+               return (uintptr_t)priv->phy;
        } else {
-               return (uint32_t)priv->ctl;
+               return (uintptr_t)priv->ctl;
        }
 }
 
@@ -275,21 +303,22 @@ static void set_reg(const struct ddr_info *priv,
                    const void *param)
 {
        unsigned int i;
-       unsigned int *ptr, value;
+       unsigned int value;
        enum base_type base = ddr_registers[type].base;
-       uint32_t base_addr = get_base_addr(priv, base);
+       uintptr_t base_addr = get_base_addr(priv, base);
        const struct reg_desc *desc = ddr_registers[type].desc;
 
        VERBOSE("init %s\n", ddr_registers[type].name);
        for (i = 0; i < ddr_registers[type].size; i++) {
-               ptr = (unsigned int *)(base_addr + desc[i].offset);
+               uintptr_t ptr = base_addr + desc[i].offset;
+
                if (desc[i].par_offset == INVALID_OFFSET) {
                        ERROR("invalid parameter offset for %s", desc[i].name);
                        panic();
                } else {
-                       value = *((uint32_t *)((uint32_t)param +
+                       value = *((uint32_t *)((uintptr_t)param +
                                               desc[i].par_offset));
-                       mmio_write_32((uint32_t)ptr, value);
+                       mmio_write_32(ptr, value);
                }
        }
 }
@@ -305,15 +334,15 @@ static void stm32mp1_ddrphy_idone_wait(struct stm32mp1_ddrphy *phy)
        time0 = start;
 
        do {
-               pgsr = mmio_read_32((uint32_t)&phy->pgsr);
+               pgsr = mmio_read_32((uintptr_t)&phy->pgsr);
                time = get_timer(start);
                if (time != time0) {
-                       VERBOSE("  > [0x%x] pgsr = 0x%x &\n",
-                               (uint32_t)&phy->pgsr, pgsr);
-                       VERBOSE("    [0x%x] pir = 0x%x (time=%x)\n",
-                               (uint32_t)&phy->pir,
-                               mmio_read_32((uint32_t)&phy->pir),
-                               (uint32_t)time);
+                       VERBOSE("  > [0x%lx] pgsr = 0x%x &\n",
+                               (uintptr_t)&phy->pgsr, pgsr);
+                       VERBOSE("    [0x%lx] pir = 0x%x (time=%lx)\n",
+                               (uintptr_t)&phy->pir,
+                               mmio_read_32((uintptr_t)&phy->pir),
+                               time);
                }
 
                time0 = time;
@@ -341,18 +370,18 @@ static void stm32mp1_ddrphy_idone_wait(struct stm32mp1_ddrphy *phy)
                        error++;
                }
        } while ((pgsr & DDRPHYC_PGSR_IDONE) == 0U && error == 0);
-       VERBOSE("\n[0x%x] pgsr = 0x%x\n",
-               (uint32_t)&phy->pgsr, pgsr);
+       VERBOSE("\n[0x%lx] pgsr = 0x%x\n",
+               (uintptr_t)&phy->pgsr, pgsr);
 }
 
 static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir)
 {
        uint32_t pir_init = pir | DDRPHYC_PIR_INIT;
 
-       mmio_write_32((uint32_t)&phy->pir, pir_init);
-       VERBOSE("[0x%x] pir = 0x%x -> 0x%x\n",
-               (uint32_t)&phy->pir, pir_init,
-               mmio_read_32((uint32_t)&phy->pir));
+       mmio_write_32((uintptr_t)&phy->pir, pir_init);
+       VERBOSE("[0x%lx] pir = 0x%x -> 0x%x\n",
+               (uintptr_t)&phy->pir, pir_init,
+               mmio_read_32((uintptr_t)&phy->pir));
 
        /* Need to wait 10 configuration clock before start polling */
        udelay(10);
@@ -364,9 +393,9 @@ static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir)
 /* Start quasi dynamic register update */
 static void stm32mp1_start_sw_done(struct stm32mp1_ddrctl *ctl)
 {
-       mmio_clrbits_32((uint32_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
-       VERBOSE("[0x%x] swctl = 0x%x\n",
-               (uint32_t)&ctl->swctl,  mmio_read_32((uint32_t)&ctl->swctl));
+       mmio_clrbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
+       VERBOSE("[0x%lx] swctl = 0x%x\n",
+               (uintptr_t)&ctl->swctl,  mmio_read_32((uintptr_t)&ctl->swctl));
 }
 
 /* Wait quasi dynamic register update */
@@ -375,15 +404,15 @@ static void stm32mp1_wait_sw_done_ack(struct stm32mp1_ddrctl *ctl)
        unsigned long start;
        uint32_t swstat;
 
-       mmio_setbits_32((uint32_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
-       VERBOSE("[0x%x] swctl = 0x%x\n",
-               (uint32_t)&ctl->swctl, mmio_read_32((uint32_t)&ctl->swctl));
+       mmio_setbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
+       VERBOSE("[0x%lx] swctl = 0x%x\n",
+               (uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl));
 
        start = get_timer(0);
        do {
-               swstat = mmio_read_32((uint32_t)&ctl->swstat);
-               VERBOSE("[0x%x] swstat = 0x%x ",
-                       (uint32_t)&ctl->swstat, swstat);
+               swstat = mmio_read_32((uintptr_t)&ctl->swstat);
+               VERBOSE("[0x%lx] swstat = 0x%x ",
+                       (uintptr_t)&ctl->swstat, swstat);
                VERBOSE("timer in ms 0x%x = start 0x%lx\r",
                        get_timer(0), start);
                if (get_timer(start) > plat_get_syscnt_freq2()) {
@@ -391,8 +420,8 @@ static void stm32mp1_wait_sw_done_ack(struct stm32mp1_ddrctl *ctl)
                }
        } while ((swstat & DDRCTRL_SWSTAT_SW_DONE_ACK) == 0U);
 
-       VERBOSE("[0x%x] swstat = 0x%x\n",
-               (uint32_t)&ctl->swstat, swstat);
+       VERBOSE("[0x%lx] swstat = 0x%x\n",
+               (uintptr_t)&ctl->swstat, swstat);
 }
 
 /* Wait quasi dynamic register update */
@@ -406,11 +435,11 @@ static void stm32mp1_wait_operating_mode(struct ddr_info *priv, uint32_t mode)
 
        start = get_timer(0);
        for ( ; ; ) {
-               stat = mmio_read_32((uint32_t)&priv->ctl->stat);
+               stat = mmio_read_32((uintptr_t)&priv->ctl->stat);
                operating_mode = stat & DDRCTRL_STAT_OPERATING_MODE_MASK;
                selref_type = stat & DDRCTRL_STAT_SELFREF_TYPE_MASK;
-               VERBOSE("[0x%x] stat = 0x%x\n",
-                       (uint32_t)&priv->ctl->stat, stat);
+               VERBOSE("[0x%lx] stat = 0x%x\n",
+                       (uintptr_t)&priv->ctl->stat, stat);
                VERBOSE("timer in ms 0x%x = start 0x%lx\r",
                        get_timer(0), start);
                if (get_timer(start) > plat_get_syscnt_freq2()) {
@@ -441,8 +470,8 @@ static void stm32mp1_wait_operating_mode(struct ddr_info *priv, uint32_t mode)
                }
        }
 
-       VERBOSE("[0x%x] stat = 0x%x\n",
-               (uint32_t)&priv->ctl->stat, stat);
+       VERBOSE("[0x%lx] stat = 0x%x\n",
+               (uintptr_t)&priv->ctl->stat, stat);
 }
 
 /* Mode Register Writes (MRW or MRS) */
@@ -459,7 +488,7 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr,
         *    No write should be performed to MRCTRL0 and MRCTRL1
         *    if MRSTAT.mr_wr_busy = 1.
         */
-       while ((mmio_read_32((uint32_t)&priv->ctl->mrstat) &
+       while ((mmio_read_32((uintptr_t)&priv->ctl->mrstat) &
                DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) {
                ;
        }
@@ -472,14 +501,14 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr,
                  DDRCTRL_MRCTRL0_MR_RANK_ALL |
                  (((uint32_t)addr << DDRCTRL_MRCTRL0_MR_ADDR_SHIFT) &
                   DDRCTRL_MRCTRL0_MR_ADDR_MASK);
-       mmio_write_32((uint32_t)&priv->ctl->mrctrl0, mrctrl0);
-       VERBOSE("[0x%x] mrctrl0 = 0x%x (0x%x)\n",
-               (uint32_t)&priv->ctl->mrctrl0,
-               mmio_read_32((uint32_t)&priv->ctl->mrctrl0), mrctrl0);
-       mmio_write_32((uint32_t)&priv->ctl->mrctrl1, data);
-       VERBOSE("[0x%x] mrctrl1 = 0x%x\n",
-               (uint32_t)&priv->ctl->mrctrl1,
-               mmio_read_32((uint32_t)&priv->ctl->mrctrl1));
+       mmio_write_32((uintptr_t)&priv->ctl->mrctrl0, mrctrl0);
+       VERBOSE("[0x%lx] mrctrl0 = 0x%x (0x%x)\n",
+               (uintptr_t)&priv->ctl->mrctrl0,
+               mmio_read_32((uintptr_t)&priv->ctl->mrctrl0), mrctrl0);
+       mmio_write_32((uintptr_t)&priv->ctl->mrctrl1, data);
+       VERBOSE("[0x%lx] mrctrl1 = 0x%x\n",
+               (uintptr_t)&priv->ctl->mrctrl1,
+               mmio_read_32((uintptr_t)&priv->ctl->mrctrl1));
 
        /*
         * 3. In a separate APB transaction, write the MRCTRL0.mr_wr to 1. This
@@ -489,22 +518,22 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr,
         *    initiated until it is deasserted.
         */
        mrctrl0 |= DDRCTRL_MRCTRL0_MR_WR;
-       mmio_write_32((uint32_t)&priv->ctl->mrctrl0, mrctrl0);
+       mmio_write_32((uintptr_t)&priv->ctl->mrctrl0, mrctrl0);
 
-       while ((mmio_read_32((uint32_t)&priv->ctl->mrstat) &
+       while ((mmio_read_32((uintptr_t)&priv->ctl->mrstat) &
               DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) {
                ;
        }
 
-       VERBOSE("[0x%x] mrctrl0 = 0x%x\n",
-               (uint32_t)&priv->ctl->mrctrl0, mrctrl0);
+       VERBOSE("[0x%lx] mrctrl0 = 0x%x\n",
+               (uintptr_t)&priv->ctl->mrctrl0, mrctrl0);
 }
 
 /* Switch DDR3 from DLL-on to DLL-off */
 static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
 {
-       uint32_t mr1 = mmio_read_32((uint32_t)&priv->phy->mr1);
-       uint32_t mr2 = mmio_read_32((uint32_t)&priv->phy->mr2);
+       uint32_t mr1 = mmio_read_32((uintptr_t)&priv->phy->mr1);
+       uint32_t mr2 = mmio_read_32((uintptr_t)&priv->phy->mr2);
        uint32_t dbgcam;
 
        VERBOSE("mr1: 0x%x\n", mr1);
@@ -514,10 +543,10 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
         * 1. Set the DBG1.dis_hif = 1.
         *    This prevents further reads/writes being received on the HIF.
         */
-       mmio_setbits_32((uint32_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
-       VERBOSE("[0x%x] dbg1 = 0x%x\n",
-               (uint32_t)&priv->ctl->dbg1,
-               mmio_read_32((uint32_t)&priv->ctl->dbg1));
+       mmio_setbits_32((uintptr_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+       VERBOSE("[0x%lx] dbg1 = 0x%x\n",
+               (uintptr_t)&priv->ctl->dbg1,
+               mmio_read_32((uintptr_t)&priv->ctl->dbg1));
 
        /*
         * 2. Ensure all commands have been flushed from the uMCTL2 by polling
@@ -528,9 +557,9 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
         *    DBGCAM.dbg_hpr_q_depth = 0.
         */
        do {
-               dbgcam = mmio_read_32((uint32_t)&priv->ctl->dbgcam);
-               VERBOSE("[0x%x] dbgcam = 0x%x\n",
-                       (uint32_t)&priv->ctl->dbgcam, dbgcam);
+               dbgcam = mmio_read_32((uintptr_t)&priv->ctl->dbgcam);
+               VERBOSE("[0x%lx] dbgcam = 0x%x\n",
+                       (uintptr_t)&priv->ctl->dbgcam, dbgcam);
        } while ((((dbgcam & DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY) ==
                   DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY)) &&
                 ((dbgcam & DDRCTRL_DBGCAM_DBG_Q_DEPTH) == 0U));
@@ -574,11 +603,11 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
         *    PWRCTL.selfref_sw = 1, and polling STAT.operating_mode to ensure
         *    the DDRC has entered self-refresh.
         */
-       mmio_setbits_32((uint32_t)&priv->ctl->pwrctl,
+       mmio_setbits_32((uintptr_t)&priv->ctl->pwrctl,
                        DDRCTRL_PWRCTL_SELFREF_SW);
-       VERBOSE("[0x%x] pwrctl = 0x%x\n",
-               (uint32_t)&priv->ctl->pwrctl,
-               mmio_read_32((uint32_t)&priv->ctl->pwrctl));
+       VERBOSE("[0x%lx] pwrctl = 0x%x\n",
+               (uintptr_t)&priv->ctl->pwrctl,
+               mmio_read_32((uintptr_t)&priv->ctl->pwrctl));
 
        /*
         * 8. Wait until STAT.operating_mode[1:0]==11 indicating that the
@@ -594,10 +623,10 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
         */
        stm32mp1_start_sw_done(priv->ctl);
 
-       mmio_setbits_32((uint32_t)&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE);
-       VERBOSE("[0x%x] mstr = 0x%x\n",
-               (uint32_t)&priv->ctl->mstr,
-               mmio_read_32((uint32_t)&priv->ctl->mstr));
+       mmio_setbits_32((uintptr_t)&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE);
+       VERBOSE("[0x%lx] mstr = 0x%x\n",
+               (uintptr_t)&priv->ctl->mstr,
+               mmio_read_32((uintptr_t)&priv->ctl->mstr));
 
        stm32mp1_wait_sw_done_ack(priv->ctl);
 
@@ -611,26 +640,26 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
 
        /* Change Bypass Mode Frequency Range */
        if (stm32mp1_clk_get_rate(DDRPHYC) < 100000000U) {
-               mmio_clrbits_32((uint32_t)&priv->phy->dllgcr,
+               mmio_clrbits_32((uintptr_t)&priv->phy->dllgcr,
                                DDRPHYC_DLLGCR_BPS200);
        } else {
-               mmio_setbits_32((uint32_t)&priv->phy->dllgcr,
+               mmio_setbits_32((uintptr_t)&priv->phy->dllgcr,
                                DDRPHYC_DLLGCR_BPS200);
        }
 
-       mmio_setbits_32((uint32_t)&priv->phy->acdllcr, DDRPHYC_ACDLLCR_DLLDIS);
+       mmio_setbits_32((uintptr_t)&priv->phy->acdllcr, DDRPHYC_ACDLLCR_DLLDIS);
 
-       mmio_setbits_32((uint32_t)&priv->phy->dx0dllcr,
+       mmio_setbits_32((uintptr_t)&priv->phy->dx0dllcr,
                        DDRPHYC_DXNDLLCR_DLLDIS);
-       mmio_setbits_32((uint32_t)&priv->phy->dx1dllcr,
+       mmio_setbits_32((uintptr_t)&priv->phy->dx1dllcr,
                        DDRPHYC_DXNDLLCR_DLLDIS);
-       mmio_setbits_32((uint32_t)&priv->phy->dx2dllcr,
+       mmio_setbits_32((uintptr_t)&priv->phy->dx2dllcr,
                        DDRPHYC_DXNDLLCR_DLLDIS);
-       mmio_setbits_32((uint32_t)&priv->phy->dx3dllcr,
+       mmio_setbits_32((uintptr_t)&priv->phy->dx3dllcr,
                        DDRPHYC_DXNDLLCR_DLLDIS);
 
        /* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
-       mmio_clrbits_32((uint32_t)&priv->ctl->pwrctl,
+       mmio_clrbits_32((uintptr_t)&priv->ctl->pwrctl,
                        DDRCTRL_PWRCTL_SELFREF_SW);
        stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
 
@@ -646,20 +675,20 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
         */
 
        /* 15. Write DBG1.dis_hif = 0 to re-enable reads and writes. */
-       mmio_clrbits_32((uint32_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
-       VERBOSE("[0x%x] dbg1 = 0x%x\n",
-               (uint32_t)&priv->ctl->dbg1,
-               mmio_read_32((uint32_t)&priv->ctl->dbg1));
+       mmio_clrbits_32((uintptr_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+       VERBOSE("[0x%lx] dbg1 = 0x%x\n",
+               (uintptr_t)&priv->ctl->dbg1,
+               mmio_read_32((uintptr_t)&priv->ctl->dbg1));
 }
 
 static void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl)
 {
        stm32mp1_start_sw_done(ctl);
        /* Quasi-dynamic register update*/
-       mmio_setbits_32((uint32_t)&ctl->rfshctl3,
+       mmio_setbits_32((uintptr_t)&ctl->rfshctl3,
                        DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
-       mmio_clrbits_32((uint32_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
-       mmio_clrbits_32((uint32_t)&ctl->dfimisc,
+       mmio_clrbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
+       mmio_clrbits_32((uintptr_t)&ctl->dfimisc,
                        DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
        stm32mp1_wait_sw_done_ack(ctl);
 }
@@ -669,14 +698,14 @@ static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl,
 {
        stm32mp1_start_sw_done(ctl);
        if ((rfshctl3 & DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH) == 0U) {
-               mmio_clrbits_32((uint32_t)&ctl->rfshctl3,
+               mmio_clrbits_32((uintptr_t)&ctl->rfshctl3,
                                DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
        }
        if ((pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN) != 0U) {
-               mmio_setbits_32((uint32_t)&ctl->pwrctl,
+               mmio_setbits_32((uintptr_t)&ctl->pwrctl,
                                DDRCTRL_PWRCTL_POWERDOWN_EN);
        }
-       mmio_setbits_32((uint32_t)&ctl->dfimisc,
+       mmio_setbits_32((uintptr_t)&ctl->dfimisc,
                        DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
        stm32mp1_wait_sw_done_ack(ctl);
 }
@@ -694,12 +723,14 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
                       struct stm32mp1_ddr_config *config)
 {
        uint32_t pir;
-       int ret;
+       int ret = -EINVAL;
 
        if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) {
                ret = board_ddr_power_init(STM32MP_DDR3);
-       } else {
+       } else if ((config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) != 0U) {
                ret = board_ddr_power_init(STM32MP_LPDDR2);
+       } else {
+               ERROR("DDR type not supported\n");
        }
 
        if (ret != 0) {
@@ -707,7 +738,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
        }
 
        VERBOSE("name = %s\n", config->info.name);
-       VERBOSE("speed = %d MHz\n", config->info.speed);
+       VERBOSE("speed = %d kHz\n", config->info.speed);
        VERBOSE("size  = 0x%x\n", config->info.size);
 
        /* DDR INIT SEQUENCE */
@@ -746,11 +777,11 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
 
        /* 1.5. initialize registers ddr_umctl2 */
        /* Stop uMCTL2 before PHY is ready */
-       mmio_clrbits_32((uint32_t)&priv->ctl->dfimisc,
+       mmio_clrbits_32((uintptr_t)&priv->ctl->dfimisc,
                        DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
-       VERBOSE("[0x%x] dfimisc = 0x%x\n",
-               (uint32_t)&priv->ctl->dfimisc,
-               mmio_read_32((uint32_t)&priv->ctl->dfimisc));
+       VERBOSE("[0x%lx] dfimisc = 0x%x\n",
+               (uintptr_t)&priv->ctl->dfimisc,
+               mmio_read_32((uintptr_t)&priv->ctl->dfimisc));
 
        set_reg(priv, REG_REG, &config->c_reg);
 
@@ -759,23 +790,23 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
             (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE))
            == (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) {
                VERBOSE("deactivate DLL OFF in mstr\n");
-               mmio_clrbits_32((uint32_t)&priv->ctl->mstr,
+               mmio_clrbits_32((uintptr_t)&priv->ctl->mstr,
                                DDRCTRL_MSTR_DLL_OFF_MODE);
-               VERBOSE("[0x%x] mstr = 0x%x\n",
-                       (uint32_t)&priv->ctl->mstr,
-                       mmio_read_32((uint32_t)&priv->ctl->mstr));
+               VERBOSE("[0x%lx] mstr = 0x%x\n",
+                       (uintptr_t)&priv->ctl->mstr,
+                       mmio_read_32((uintptr_t)&priv->ctl->mstr));
        }
 
        set_reg(priv, REG_TIMING, &config->c_timing);
        set_reg(priv, REG_MAP, &config->c_map);
 
        /* Skip CTRL init, SDRAM init is done by PHY PUBL */
-       mmio_clrsetbits_32((uint32_t)&priv->ctl->init0,
+       mmio_clrsetbits_32((uintptr_t)&priv->ctl->init0,
                           DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK,
                           DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL);
-       VERBOSE("[0x%x] init0 = 0x%x\n",
-               (uint32_t)&priv->ctl->init0,
-               mmio_read_32((uint32_t)&priv->ctl->init0));
+       VERBOSE("[0x%lx] init0 = 0x%x\n",
+               (uintptr_t)&priv->ctl->init0,
+               mmio_read_32((uintptr_t)&priv->ctl->init0));
 
        set_reg(priv, REG_PERF, &config->c_perf);
 
@@ -797,10 +828,10 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
             (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE))
            == (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) {
                VERBOSE("deactivate DLL OFF in mr1\n");
-               mmio_clrbits_32((uint32_t)&priv->phy->mr1, BIT(0));
-               VERBOSE("[0x%x] mr1 = 0x%x\n",
-                       (uint32_t)&priv->phy->mr1,
-                       mmio_read_32((uint32_t)&priv->phy->mr1));
+               mmio_clrbits_32((uintptr_t)&priv->phy->mr1, BIT(0));
+               VERBOSE("[0x%lx] mr1 = 0x%x\n",
+                       (uintptr_t)&priv->phy->mr1,
+                       mmio_read_32((uintptr_t)&priv->phy->mr1));
        }
 
        /*
@@ -830,11 +861,11 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
         */
        stm32mp1_start_sw_done(priv->ctl);
 
-       mmio_setbits_32((uint32_t)&priv->ctl->dfimisc,
+       mmio_setbits_32((uintptr_t)&priv->ctl->dfimisc,
                        DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
-       VERBOSE("[0x%x] dfimisc = 0x%x\n",
-               (uint32_t)&priv->ctl->dfimisc,
-               mmio_read_32((uint32_t)&priv->ctl->dfimisc));
+       VERBOSE("[0x%lx] dfimisc = 0x%x\n",
+               (uintptr_t)&priv->ctl->dfimisc,
+               mmio_read_32((uintptr_t)&priv->ctl->dfimisc));
 
        stm32mp1_wait_sw_done_ack(priv->ctl);
 
@@ -884,14 +915,16 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
                                 config->c_reg.pwrctl);
 
        /* Enable uMCTL2 AXI port 0 */
-       mmio_setbits_32((uint32_t)&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
-       VERBOSE("[0x%x] pctrl_0 = 0x%x\n",
-               (uint32_t)&priv->ctl->pctrl_0,
-               mmio_read_32((uint32_t)&priv->ctl->pctrl_0));
+       mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_0,
+                       DDRCTRL_PCTRL_N_PORT_EN);
+       VERBOSE("[0x%lx] pctrl_0 = 0x%x\n",
+               (uintptr_t)&priv->ctl->pctrl_0,
+               mmio_read_32((uintptr_t)&priv->ctl->pctrl_0));
 
        /* Enable uMCTL2 AXI port 1 */
-       mmio_setbits_32((uint32_t)&priv->ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN);
-       VERBOSE("[0x%x] pctrl_1 = 0x%x\n",
-               (uint32_t)&priv->ctl->pctrl_1,
-               mmio_read_32((uint32_t)&priv->ctl->pctrl_1));
+       mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_1,
+                       DDRCTRL_PCTRL_N_PORT_EN);
+       VERBOSE("[0x%lx] pctrl_1 = 0x%x\n",
+               (uintptr_t)&priv->ctl->pctrl_1,
+               mmio_read_32((uintptr_t)&priv->ctl->pctrl_1));
 }
index 127b6c7c1c85ea08107a2c54ccd2d876f993bb6e..e65fbeaa2692f093c820376caa609a75d02a5f14 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -25,7 +25,7 @@
 
 static struct ddr_info ddr_priv_data;
 
-int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed)
 {
        unsigned long ddrphy_clk, ddr_clk, mem_speed_hz;
 
@@ -33,10 +33,10 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
 
        ddrphy_clk = stm32mp1_clk_get_rate(DDRPHYC);
 
-       VERBOSE("DDR: mem_speed (%d MHz), RCC %ld MHz\n",
-               mem_speed, ddrphy_clk / 1000U / 1000U);
+       VERBOSE("DDR: mem_speed (%d kHz), RCC %ld kHz\n",
+               mem_speed, ddrphy_clk / 1000U);
 
-       mem_speed_hz = (uint32_t)mem_speed * 1000U * 1000U;
+       mem_speed_hz = mem_speed * 1000U;
 
        /* Max 10% frequency delta */
        if (ddrphy_clk > mem_speed_hz) {
@@ -44,9 +44,9 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
        } else {
                ddr_clk = mem_speed_hz - ddrphy_clk;
        }
-       if (ddr_clk > mem_speed_hz) {
-               ERROR("DDR expected freq %d MHz, current is %ld MHz\n",
-                     mem_speed, ddrphy_clk / 1000U / 1000U);
+       if (ddr_clk > (mem_speed_hz / 10)) {
+               ERROR("DDR expected freq %d kHz, current is %ld kHz\n",
+                     mem_speed, ddrphy_clk / 1000U);
                return -1;
        }
        return 0;
@@ -208,11 +208,16 @@ static int stm32mp1_ddr_setup(void)
                return -EINVAL;
        }
 
-       config.info.speed =
-               (uint16_t)fdt_read_uint32_default(node, "st,mem-speed",
-                                                 STM32MP1_DDR_SPEED_DFLT);
-       config.info.size = fdt_read_uint32_default(node, "st,mem-size",
-                                                  STM32MP1_DDR_SIZE_DFLT);
+       config.info.speed = fdt_read_uint32_default(node, "st,mem-speed", 0);
+       if (!config.info.speed) {
+               VERBOSE("%s: no st,mem-speed\n", __func__);
+               return -EINVAL;
+       }
+       config.info.size = fdt_read_uint32_default(node, "st,mem-size", 0);
+       if (!config.info.size) {
+               VERBOSE("%s: no st,mem-size\n", __func__);
+               return -EINVAL;
+       }
        config.info.name = fdt_getprop(fdt, node, "st,mem-name", &len);
        if (config.info.name == NULL) {
                VERBOSE("%s: no st,mem-name\n", __func__);
@@ -222,7 +227,7 @@ static int stm32mp1_ddr_setup(void)
 
        for (idx = 0; idx < ARRAY_SIZE(param); idx++) {
                ret = fdt_read_uint32_array(node, param[idx].name,
-                                           (void *)((uint32_t)&config +
+                                           (void *)((uintptr_t)&config +
                                                     param[idx].offset),
                                            param[idx].size);
 
@@ -261,8 +266,8 @@ static int stm32mp1_ddr_setup(void)
        VERBOSE("%s : ram size(%x, %x)\n", __func__,
                (uint32_t)priv->info.base, (uint32_t)priv->info.size);
 
-       dcsw_op_all(DC_OP_CISW);
        write_sctlr(read_sctlr() & ~SCTLR_C_BIT);
+       dcsw_op_all(DC_OP_CISW);
 
        uret = ddr_test_data_bus();
        if (uret != 0U) {
index 9591e3738d3d922ce450dbbd50c62e78ee3731b6..d217c4501b6f8ca8d0b041211726440aff959b77 100644 (file)
 /*
- * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
+#include <errno.h>
 #include <stdbool.h>
 
+#include <libfdt.h>
+
+#include <platform_def.h>
+
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/st/stm32_gpio.h>
+#include <drivers/st/stm32mp1_clk.h>
+#include <drivers/st/stm32mp1_clkfunc.h>
 #include <lib/mmio.h>
+#include <lib/utils_def.h>
 
-static bool check_gpio(uint32_t bank, uint32_t pin)
+#define DT_GPIO_BANK_SHIFT     12
+#define DT_GPIO_BANK_MASK      GENMASK(16, 12)
+#define DT_GPIO_PIN_SHIFT      8
+#define DT_GPIO_PIN_MASK       GENMASK(11, 8)
+#define DT_GPIO_MODE_MASK      GENMASK(7, 0)
+
+/*******************************************************************************
+ * This function gets GPIO bank node in DT.
+ * Returns node offset if status is okay in DT, else return 0
+ ******************************************************************************/
+static int ckeck_gpio_bank(void *fdt, uint32_t bank, int pinctrl_node)
 {
-       if (pin > GPIO_PIN_MAX) {
-               ERROR("%s: wrong pin number (%d)\n", __func__, pin);
-               return false;
-       }
+       int pinctrl_subnode;
+       uint32_t bank_offset = stm32_get_gpio_bank_offset(bank);
 
-       if ((bank > GPIO_BANK_K) && (bank != GPIO_BANK_Z)) {
-               ERROR("%s: wrong GPIO bank number (%d)\n", __func__, bank);
-               return false;
+       fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) {
+               const fdt32_t *cuint;
+
+               if (fdt_getprop(fdt, pinctrl_subnode,
+                               "gpio-controller", NULL) == NULL) {
+                       continue;
+               }
+
+               cuint = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL);
+               if (cuint == NULL) {
+                       continue;
+               }
+
+               if ((fdt32_to_cpu(*cuint) == bank_offset) &&
+                   (fdt_get_status(pinctrl_subnode) != DT_DISABLED)) {
+                       return pinctrl_subnode;
+               }
        }
 
-       return true;
+       return 0;
 }
 
-void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
-             uint32_t pull, uint32_t alternate)
+/*******************************************************************************
+ * This function gets the pin settings from DT information.
+ * When analyze and parsing is done, set the GPIO registers.
+ * Returns 0 on success and a negative FDT error code on failure.
+ ******************************************************************************/
+static int dt_set_gpio_config(void *fdt, int node, uint8_t status)
 {
-       volatile uint32_t bank_address;
+       const fdt32_t *cuint, *slewrate;
+       int len;
+       int pinctrl_node;
+       uint32_t i;
+       uint32_t speed = GPIO_SPEED_LOW;
+       uint32_t pull = GPIO_NO_PULL;
 
-       if (!check_gpio(bank, pin)) {
-               return;
+       cuint = fdt_getprop(fdt, node, "pinmux", &len);
+       if (cuint == NULL) {
+               return -FDT_ERR_NOTFOUND;
        }
 
-       if (bank == GPIO_BANK_Z) {
-               bank_address = STM32_GPIOZ_BANK;
+       pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node));
+       if (pinctrl_node < 0) {
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       slewrate = fdt_getprop(fdt, node, "slew-rate", NULL);
+       if (slewrate != NULL) {
+               speed = fdt32_to_cpu(*slewrate);
+       }
+
+       if (fdt_getprop(fdt, node, "bias-pull-up", NULL) != NULL) {
+               pull = GPIO_PULL_UP;
+       } else if (fdt_getprop(fdt, node, "bias-pull-down", NULL) != NULL) {
+               pull = GPIO_PULL_DOWN;
        } else {
-               bank_address = STM32_GPIOA_BANK +
-                       (bank * STM32_GPIO_BANK_OFFSET);
+               VERBOSE("No bias configured in node %d\n", node);
+       }
+
+       for (i = 0U; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+               uint32_t pincfg;
+               uint32_t bank;
+               uint32_t pin;
+               uint32_t mode;
+               uint32_t alternate = GPIO_ALTERNATE_(0);
+               int bank_node;
+               int clk;
+
+               pincfg = fdt32_to_cpu(*cuint);
+               cuint++;
+
+               bank = (pincfg & DT_GPIO_BANK_MASK) >> DT_GPIO_BANK_SHIFT;
+
+               pin = (pincfg & DT_GPIO_PIN_MASK) >> DT_GPIO_PIN_SHIFT;
+
+               mode = pincfg & DT_GPIO_MODE_MASK;
+
+               switch (mode) {
+               case 0:
+                       mode = GPIO_MODE_INPUT;
+                       break;
+               case 1 ... 16:
+                       alternate = mode - 1U;
+                       mode = GPIO_MODE_ALTERNATE;
+                       break;
+               case 17:
+                       mode = GPIO_MODE_ANALOG;
+                       break;
+               default:
+                       mode = GPIO_MODE_OUTPUT;
+                       break;
+               }
+
+               if (fdt_getprop(fdt, node, "drive-open-drain", NULL) != NULL) {
+                       mode |= GPIO_OPEN_DRAIN;
+               }
+
+               bank_node = ckeck_gpio_bank(fdt, bank, pinctrl_node);
+               if (bank_node == 0) {
+                       ERROR("PINCTRL inconsistent in DT\n");
+                       panic();
+               }
+
+               clk = fdt_get_clock_id(bank_node);
+               if (clk < 0) {
+                       return -FDT_ERR_NOTFOUND;
+               }
+
+               /* Platform knows the clock: assert it is okay */
+               assert((unsigned long)clk == stm32_get_gpio_bank_clock(bank));
+
+               set_gpio(bank, pin, mode, speed, pull, alternate, status);
+       }
+
+       return 0;
+}
+
+/*******************************************************************************
+ * This function gets the pin settings from DT information.
+ * When analyze and parsing is done, set the GPIO registers.
+ * Returns 0 on success and a negative FDT/ERRNO error code on failure.
+ ******************************************************************************/
+int dt_set_pinctrl_config(int node)
+{
+       const fdt32_t *cuint;
+       int lenp = 0;
+       uint32_t i;
+       uint8_t status = fdt_get_status(node);
+       void *fdt;
+
+       if (fdt_get_address(&fdt) == 0) {
+               return -ENOENT;
+       }
+
+       if (status == DT_DISABLED) {
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       cuint = fdt_getprop(fdt, node, "pinctrl-0", &lenp);
+       if (cuint == NULL) {
+               return -FDT_ERR_NOTFOUND;
        }
 
-       mmio_clrbits_32(bank_address + GPIO_MODE_OFFSET,
+       for (i = 0; i < ((uint32_t)lenp / 4U); i++) {
+               int p_node, p_subnode;
+
+               p_node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+               if (p_node < 0) {
+                       return -FDT_ERR_NOTFOUND;
+               }
+
+               fdt_for_each_subnode(p_subnode, fdt, p_node) {
+                       int ret = dt_set_gpio_config(fdt, p_subnode, status);
+
+                       if (ret < 0) {
+                               return ret;
+                       }
+               }
+
+               cuint++;
+       }
+
+       return 0;
+}
+
+void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
+             uint32_t pull, uint32_t alternate, uint8_t status)
+{
+       uintptr_t base = stm32_get_gpio_bank_base(bank);
+       unsigned long clock = stm32_get_gpio_bank_clock(bank);
+
+       assert(pin <= GPIO_PIN_MAX);
+
+       stm32mp1_clk_enable(clock);
+
+       mmio_clrbits_32(base + GPIO_MODE_OFFSET,
                        ((uint32_t)GPIO_MODE_MASK << (pin << 1)));
-       mmio_setbits_32(bank_address + GPIO_MODE_OFFSET,
+       mmio_setbits_32(base + GPIO_MODE_OFFSET,
                        (mode & ~GPIO_OPEN_DRAIN) << (pin << 1));
 
        if ((mode & GPIO_OPEN_DRAIN) != 0U) {
-               mmio_setbits_32(bank_address + GPIO_TYPE_OFFSET,
-                               BIT(pin));
+               mmio_setbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
+       } else {
+               mmio_clrbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
        }
 
-       mmio_clrbits_32(bank_address + GPIO_SPEED_OFFSET,
+       mmio_clrbits_32(base + GPIO_SPEED_OFFSET,
                        ((uint32_t)GPIO_SPEED_MASK << (pin << 1)));
-       mmio_setbits_32(bank_address + GPIO_SPEED_OFFSET, speed << (pin << 1));
+       mmio_setbits_32(base + GPIO_SPEED_OFFSET, speed << (pin << 1));
 
-       mmio_clrbits_32(bank_address + GPIO_PUPD_OFFSET,
+       mmio_clrbits_32(base + GPIO_PUPD_OFFSET,
                        ((uint32_t)GPIO_PULL_MASK << (pin << 1)));
-       mmio_setbits_32(bank_address + GPIO_PUPD_OFFSET, pull << (pin << 1));
+       mmio_setbits_32(base + GPIO_PUPD_OFFSET, pull << (pin << 1));
 
        if (pin < GPIO_ALT_LOWER_LIMIT) {
-               mmio_clrbits_32(bank_address + GPIO_AFRL_OFFSET,
+               mmio_clrbits_32(base + GPIO_AFRL_OFFSET,
                                ((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2)));
-               mmio_setbits_32(bank_address + GPIO_AFRL_OFFSET,
+               mmio_setbits_32(base + GPIO_AFRL_OFFSET,
                                alternate << (pin << 2));
        } else {
-               mmio_clrbits_32(bank_address + GPIO_AFRH_OFFSET,
+               mmio_clrbits_32(base + GPIO_AFRH_OFFSET,
                                ((uint32_t)GPIO_ALTERNATE_MASK <<
                                 ((pin - GPIO_ALT_LOWER_LIMIT) << 2)));
-               mmio_setbits_32(bank_address + GPIO_AFRH_OFFSET,
+               mmio_setbits_32(base + GPIO_AFRH_OFFSET,
                                alternate << ((pin - GPIO_ALT_LOWER_LIMIT) <<
                                              2));
        }
 
        VERBOSE("GPIO %u mode set to 0x%x\n", bank,
-               mmio_read_32(bank_address + GPIO_MODE_OFFSET));
+               mmio_read_32(base + GPIO_MODE_OFFSET));
        VERBOSE("GPIO %u speed set to 0x%x\n", bank,
-               mmio_read_32(bank_address + GPIO_SPEED_OFFSET));
+               mmio_read_32(base + GPIO_SPEED_OFFSET));
        VERBOSE("GPIO %u mode pull to 0x%x\n", bank,
-               mmio_read_32(bank_address + GPIO_PUPD_OFFSET));
+               mmio_read_32(base + GPIO_PUPD_OFFSET));
        VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank,
-               mmio_read_32(bank_address + GPIO_AFRL_OFFSET));
+               mmio_read_32(base + GPIO_AFRL_OFFSET));
        VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank,
-               mmio_read_32(bank_address + GPIO_AFRH_OFFSET));
+               mmio_read_32(base + GPIO_AFRH_OFFSET));
+
+       stm32mp1_clk_disable((unsigned long)clock);
+}
+
+void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure)
+{
+       uintptr_t base = stm32_get_gpio_bank_base(bank);
+       int clock = stm32_get_gpio_bank_clock(bank);
+
+       assert(pin <= GPIO_PIN_MAX);
+
+       stm32mp1_clk_enable((unsigned long)clock);
+
+       if (secure) {
+               mmio_setbits_32(base + GPIO_SECR_OFFSET, BIT(pin));
+       } else {
+               mmio_clrbits_32(base + GPIO_SECR_OFFSET, BIT(pin));
+       }
+
+       stm32mp1_clk_disable((unsigned long)clock);
 }
diff --git a/drivers/st/i2c/stm32_i2c.c b/drivers/st/i2c/stm32_i2c.c
new file mode 100644 (file)
index 0000000..2be7afe
--- /dev/null
@@ -0,0 +1,852 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <arch_helpers.h>
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32_i2c.h>
+#include <lib/mmio.h>
+
+/* STM32 I2C registers offsets */
+#define I2C_CR1                        0x00U
+#define I2C_CR2                        0x04U
+#define I2C_OAR1               0x08U
+#define I2C_OAR2               0x0CU
+#define I2C_TIMINGR            0x10U
+#define I2C_TIMEOUTR           0x14U
+#define I2C_ISR                        0x18U
+#define I2C_ICR                        0x1CU
+#define I2C_PECR               0x20U
+#define I2C_RXDR               0x24U
+#define I2C_TXDR               0x28U
+
+#define MAX_DELAY              0xFFFFFFFFU
+
+/* I2C TIMING clear register Mask */
+#define TIMING_CLEAR_MASK      0xF0FFFFFFU
+/* Timeout 25 ms */
+#define I2C_TIMEOUT_BUSY       25U
+
+#define MAX_NBYTE_SIZE         255U
+
+static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
+                                   uint16_t dev_addr, uint16_t mem_addr,
+                                   uint16_t mem_add_size, uint32_t timeout,
+                                   uint32_t tick_start);
+static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+                                  uint16_t mem_addr, uint16_t mem_add_size,
+                                  uint32_t timeout, uint32_t tick_start);
+
+/* Private functions to handle flags during polling transfer */
+static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
+                        uint8_t awaited_value, uint32_t timeout,
+                        uint32_t tick_start);
+static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint32_t timeout,
+                        uint32_t tick_start);
+static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint32_t timeout,
+                        uint32_t tick_start);
+static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint32_t timeout,
+                         uint32_t tick_start);
+
+/* Private function to flush TXDR register */
+static void i2c_flush_txdr(struct i2c_handle_s *hi2c);
+
+/* Private function to start, restart or stop a transfer */
+static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+                               uint16_t size, uint32_t i2c_mode,
+                               uint32_t request);
+
+/*
+ * @brief  Initialize the I2C device.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_init(struct i2c_handle_s *hi2c)
+{
+       if (hi2c == NULL) {
+               return -ENOENT;
+       }
+
+       if (hi2c->i2c_state == I2C_STATE_RESET) {
+               hi2c->lock = 0;
+       }
+
+       hi2c->i2c_state = I2C_STATE_BUSY;
+
+       /* Disable the selected I2C peripheral */
+       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
+
+       /* Configure I2Cx: Frequency range */
+       mmio_write_32(hi2c->i2c_base_addr + I2C_TIMINGR,
+                     hi2c->i2c_init.timing & TIMING_CLEAR_MASK);
+
+       /* Disable Own Address1 before set the Own Address1 configuration */
+       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR1, I2C_OAR1_OA1EN);
+
+       /* Configure I2Cx: Own Address1 and ack own address1 mode */
+       if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
+               mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
+                             I2C_OAR1_OA1EN | hi2c->i2c_init.own_address1);
+       } else { /* I2C_ADDRESSINGMODE_10BIT */
+               mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
+                             I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE |
+                             hi2c->i2c_init.own_address1);
+       }
+
+       /* Configure I2Cx: Addressing Master mode */
+       if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_10BIT) {
+               mmio_write_32(hi2c->i2c_base_addr + I2C_CR2, I2C_CR2_ADD10);
+       }
+
+       /*
+        * Enable the AUTOEND by default, and enable NACK
+        * (should be disable only during Slave process)
+        */
+       mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
+                       I2C_CR2_AUTOEND | I2C_CR2_NACK);
+
+       /* Disable Own Address2 before set the Own Address2 configuration */
+       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR2, I2C_DUALADDRESS_ENABLE);
+
+       /* Configure I2Cx: Dual mode and Own Address2 */
+       mmio_write_32(hi2c->i2c_base_addr + I2C_OAR2,
+                     hi2c->i2c_init.dual_address_mode |
+                     hi2c->i2c_init.own_address2 |
+                     (hi2c->i2c_init.own_address2_masks << 8));
+
+       /* Configure I2Cx: Generalcall and NoStretch mode */
+       mmio_write_32(hi2c->i2c_base_addr + I2C_CR1,
+                     hi2c->i2c_init.general_call_mode |
+                     hi2c->i2c_init.no_stretch_mode);
+
+       /* Enable the selected I2C peripheral */
+       mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
+
+       hi2c->i2c_err = I2C_ERROR_NONE;
+       hi2c->i2c_state = I2C_STATE_READY;
+       hi2c->i2c_mode = I2C_MODE_NONE;
+
+       return 0;
+}
+
+/*
+ * @brief  Write an amount of data in blocking mode to a specific memory address
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  dev_addr: Target device address
+ * @param  mem_addr: Internal memory address
+ * @param  mem_add_size: size of internal memory address
+ * @param  p_data: Pointer to data buffer
+ * @param  size: Amount of data to be sent
+ * @param  timeout: timeout duration
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_mem_write(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+                       uint16_t mem_addr, uint16_t mem_add_size,
+                       uint8_t *p_data, uint16_t size, uint32_t timeout)
+{
+       uint32_t tickstart;
+
+       if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
+               return -EBUSY;
+       }
+
+       if ((p_data == NULL) || (size == 0U)) {
+               return -EINVAL;
+       }
+
+       hi2c->lock = 1;
+
+       tickstart = (uint32_t)read_cntpct_el0();
+
+       if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, I2C_TIMEOUT_BUSY,
+                         tickstart) != 0) {
+               return -EIO;
+       }
+
+       hi2c->i2c_state     = I2C_STATE_BUSY_TX;
+       hi2c->i2c_mode      = I2C_MODE_MEM;
+       hi2c->i2c_err = I2C_ERROR_NONE;
+
+       hi2c->p_buff  = p_data;
+       hi2c->xfer_count = size;
+
+       /* Send Slave Address and Memory Address */
+       if (i2c_request_memory_write(hi2c, dev_addr, mem_addr, mem_add_size,
+                                    timeout, tickstart) != 0) {
+               hi2c->lock = 0;
+               return -EIO;
+       }
+
+       /*
+        * Set NBYTES to write and reload
+        * if hi2c->xfer_count > MAX_NBYTE_SIZE
+        */
+       if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
+               hi2c->xfer_size = MAX_NBYTE_SIZE;
+               i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
+                                   I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
+       } else {
+               hi2c->xfer_size = hi2c->xfer_count;
+               i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
+                                   I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
+       }
+
+       do {
+               if (i2c_wait_txis(hi2c, timeout, tickstart) != 0) {
+                       return -EIO;
+               }
+
+               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR, *hi2c->p_buff);
+               hi2c->p_buff++;
+               hi2c->xfer_count--;
+               hi2c->xfer_size--;
+
+               if ((hi2c->xfer_count != 0U) && (hi2c->xfer_size == 0U)) {
+                       /* Wait until TCR flag is set */
+                       if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout,
+                                         tickstart) != 0) {
+                               return -EIO;
+               }
+
+                       if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
+                               hi2c->xfer_size = MAX_NBYTE_SIZE;
+                               i2c_transfer_config(hi2c, dev_addr,
+                                                   hi2c->xfer_size,
+                                                   I2C_RELOAD_MODE,
+                                                   I2C_NO_STARTSTOP);
+                       } else {
+                               hi2c->xfer_size = hi2c->xfer_count;
+                               i2c_transfer_config(hi2c, dev_addr,
+                                                   hi2c->xfer_size,
+                                                   I2C_AUTOEND_MODE,
+                                                   I2C_NO_STARTSTOP);
+                       }
+               }
+
+       } while (hi2c->xfer_count > 0U);
+
+       /*
+        * No need to Check TC flag, with AUTOEND mode the stop
+        * is automatically generated.
+        * Wait until STOPF flag is reset.
+        */
+       if (i2c_wait_stop(hi2c, timeout, tickstart) != 0) {
+               return -EIO;
+       }
+
+       mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
+
+       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
+
+       hi2c->i2c_state = I2C_STATE_READY;
+       hi2c->i2c_mode  = I2C_MODE_NONE;
+
+       hi2c->lock = 0;
+
+       return 0;
+}
+
+/*
+ * @brief  Read an amount of data in blocking mode from a specific memory
+ *        address
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  dev_addr: Target device address
+ * @param  mem_addr: Internal memory address
+ * @param  mem_add_size: size of internal memory address
+ * @param  p_data: Pointer to data buffer
+ * @param  size: Amount of data to be sent
+ * @param  timeout: timeout duration
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_mem_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+                      uint16_t mem_addr, uint16_t mem_add_size,
+                      uint8_t *p_data, uint16_t size, uint32_t timeout)
+{
+       uint32_t tickstart;
+
+       if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
+               return -EBUSY;
+       }
+
+       if ((p_data == NULL) || (size == 0U)) {
+               return  -EINVAL;
+       }
+
+       hi2c->lock = 1;
+
+       tickstart = (uint32_t)read_cntpct_el0();
+
+       if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, I2C_TIMEOUT_BUSY,
+                         tickstart) != 0) {
+               return -EIO;
+       }
+
+       hi2c->i2c_state     = I2C_STATE_BUSY_RX;
+       hi2c->i2c_mode      = I2C_MODE_MEM;
+       hi2c->i2c_err = I2C_ERROR_NONE;
+
+       hi2c->p_buff  = p_data;
+       hi2c->xfer_count = size;
+
+       /* Send Slave Address and Memory Address */
+       if (i2c_request_memory_read(hi2c, dev_addr, mem_addr, mem_add_size,
+                                   timeout, tickstart) != 0) {
+               hi2c->lock = 0;
+               return -EIO;
+       }
+
+       /*
+        * Send Slave Address.
+        * Set NBYTES to write and reload if hi2c->xfer_count > MAX_NBYTE_SIZE
+        * and generate RESTART.
+        */
+       if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
+               hi2c->xfer_size = MAX_NBYTE_SIZE;
+               i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
+                                   I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
+       } else {
+               hi2c->xfer_size = hi2c->xfer_count;
+               i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
+                                   I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
+       }
+
+       do {
+               if (i2c_wait_flag(hi2c, I2C_FLAG_RXNE, 0, timeout,
+                                 tickstart) != 0) {
+                       return -EIO;
+               }
+
+               *hi2c->p_buff = mmio_read_8(hi2c->i2c_base_addr + I2C_RXDR);
+               hi2c->p_buff++;
+               hi2c->xfer_size--;
+               hi2c->xfer_count--;
+
+               if ((hi2c->xfer_count != 0U) && (hi2c->xfer_size == 0U)) {
+                       if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout,
+                                         tickstart) != 0) {
+                               return -EIO;
+                       }
+
+                       if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
+                               hi2c->xfer_size = MAX_NBYTE_SIZE;
+                               i2c_transfer_config(hi2c, dev_addr,
+                                                   hi2c->xfer_size,
+                                                   I2C_RELOAD_MODE,
+                                                   I2C_NO_STARTSTOP);
+                       } else {
+                               hi2c->xfer_size = hi2c->xfer_count;
+                               i2c_transfer_config(hi2c, dev_addr,
+                                                   hi2c->xfer_size,
+                                                   I2C_AUTOEND_MODE,
+                                                   I2C_NO_STARTSTOP);
+                       }
+               }
+       } while (hi2c->xfer_count > 0U);
+
+       /*
+        * No need to Check TC flag, with AUTOEND mode the stop
+        * is automatically generated
+        * Wait until STOPF flag is reset
+        */
+       if (i2c_wait_stop(hi2c, timeout, tickstart) != 0) {
+               return -EIO;
+       }
+
+       mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
+
+       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
+
+       hi2c->i2c_state = I2C_STATE_READY;
+       hi2c->i2c_mode  = I2C_MODE_NONE;
+
+       hi2c->lock = 0;
+
+       return 0;
+}
+
+/*
+ * @brief  Checks if target device is ready for communication.
+ * @note   This function is used with Memory devices
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  dev_addr: Target device address
+ * @param  trials: Number of trials
+ * @param  timeout: timeout duration
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c,
+                             uint16_t dev_addr, uint32_t trials,
+                             uint32_t timeout)
+{
+       uint32_t i2c_trials = 0U;
+
+       if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
+               return -EBUSY;
+       }
+
+       if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_BUSY) !=
+           0U) {
+               return -EBUSY;
+       }
+
+       hi2c->lock = 1;
+
+       hi2c->i2c_state = I2C_STATE_BUSY;
+       hi2c->i2c_err = I2C_ERROR_NONE;
+
+       do {
+               uint32_t tickstart;
+
+               /* Generate Start */
+               if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
+                       mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
+                                     (((uint32_t)dev_addr & I2C_CR2_SADD) |
+                                      I2C_CR2_START | I2C_CR2_AUTOEND) &
+                                      ~I2C_CR2_RD_WRN);
+               } else {
+                       mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
+                                     (((uint32_t)dev_addr & I2C_CR2_SADD) |
+                                      I2C_CR2_START | I2C_CR2_ADD10) &
+                                     ~I2C_CR2_RD_WRN);
+               }
+
+               /*
+                * No need to Check TC flag, with AUTOEND mode the stop
+                * is automatically generated
+                * Wait until STOPF flag is set or a NACK flag is set
+                */
+               tickstart = (uint32_t)read_cntpct_el0();
+               while (((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+                        (I2C_FLAG_STOPF | I2C_FLAG_AF)) == 0U) &&
+                      (hi2c->i2c_state != I2C_STATE_TIMEOUT)) {
+                       if (timeout != MAX_DELAY) {
+                               if ((((uint32_t)read_cntpct_el0() - tickstart) >
+                                    timeout) || (timeout == 0U)) {
+                                       hi2c->i2c_state = I2C_STATE_READY;
+
+                                       hi2c->i2c_err |=
+                                               I2C_ERROR_TIMEOUT;
+
+                                       hi2c->lock = 0;
+
+                                       return -EIO;
+                               }
+                       }
+               }
+
+               /* Check if the NACKF flag has not been set */
+               if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+                    I2C_FLAG_AF) == 0U) {
+                       if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
+                                         tickstart) != 0) {
+                               return -EIO;
+                       }
+
+                       mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
+                                     I2C_FLAG_STOPF);
+
+                       hi2c->i2c_state = I2C_STATE_READY;
+
+                       hi2c->lock = 0;
+
+                       return 0;
+               }
+
+               if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
+                                 tickstart) != 0) {
+                       return -EIO;
+               }
+
+               mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
+
+               mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
+
+               if (i2c_trials == trials) {
+                       mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
+                                       I2C_CR2_STOP);
+
+                       if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
+                                         tickstart) != 0) {
+                               return -EIO;
+                       }
+
+                       mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
+                                     I2C_FLAG_STOPF);
+               }
+
+               i2c_trials++;
+       } while (i2c_trials < trials);
+
+       hi2c->i2c_state = I2C_STATE_READY;
+
+       hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+
+       hi2c->lock = 0;
+
+       return -EIO;
+}
+
+/*
+ * @brief  Master sends target device address followed by internal memory
+ *        address for write request.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  dev_addr: Target device address
+ * @param  mem_addr: Internal memory address
+ * @param  mem_add_size: size of internal memory address
+ * @param  timeout: timeout duration
+ * @param  tick_start Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
+                                   uint16_t dev_addr, uint16_t mem_addr,
+                                   uint16_t mem_add_size, uint32_t timeout,
+                                   uint32_t tick_start)
+{
+       i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_RELOAD_MODE,
+                           I2C_GENERATE_START_WRITE);
+
+       if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
+               return -EIO;
+       }
+
+       if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
+               /* Send Memory Address */
+               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+                            (uint8_t)(mem_addr & 0x00FFU));
+       } else {
+               /* Send MSB of Memory Address */
+               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+                            (uint8_t)((mem_addr & 0xFF00U) >> 8));
+
+               /* Wait until TXIS flag is set */
+               if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
+                       return -EIO;
+               }
+
+               /* Send LSB of Memory Address */
+               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+                            (uint8_t)(mem_addr & 0x00FFU));
+       }
+
+       if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout, tick_start) !=
+           0) {
+               return -EIO;
+       }
+
+       return 0;
+}
+
+/*
+ * @brief  Master sends target device address followed by internal memory
+ *        address for read request.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  dev_addr: Target device address
+ * @param  mem_addr: Internal memory address
+ * @param  mem_add_size: size of internal memory address
+ * @param  timeout: timeout duration
+ * @param  tick_start Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+                                  uint16_t mem_addr, uint16_t mem_add_size,
+                                  uint32_t timeout, uint32_t tick_start)
+{
+       i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_SOFTEND_MODE,
+                           I2C_GENERATE_START_WRITE);
+
+       if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
+               return -EIO;
+       }
+
+       if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
+               /* Send Memory Address */
+               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+                            (uint8_t)(mem_addr & 0x00FFU));
+       } else {
+               /* Send MSB of Memory Address */
+               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+                            (uint8_t)((mem_addr & 0xFF00U) >> 8));
+
+               /* Wait until TXIS flag is set */
+               if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
+                       return -EIO;
+               }
+
+               /* Send LSB of Memory Address */
+               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+                            (uint8_t)(mem_addr & 0x00FFU));
+       }
+
+       if (i2c_wait_flag(hi2c, I2C_FLAG_TC, 0, timeout, tick_start) != 0) {
+               return -EIO;
+       }
+
+       return 0;
+}
+
+/*
+ * @brief  I2C Tx data register flush process.
+ * @param  hi2c: I2C handle.
+ * @retval None
+ */
+static void i2c_flush_txdr(struct i2c_handle_s *hi2c)
+{
+       /*
+        * If a pending TXIS flag is set,
+        * write a dummy data in TXDR to clear it.
+        */
+       if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXIS) !=
+           0U) {
+               mmio_write_32(hi2c->i2c_base_addr + I2C_TXDR, 0);
+       }
+
+       /* Flush TX register if not empty */
+       if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXE) ==
+           0U) {
+               mmio_setbits_32(hi2c->i2c_base_addr + I2C_ISR,
+                               I2C_FLAG_TXE);
+       }
+}
+
+/*
+ * @brief  This function handles I2C Communication timeout.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  flag: Specifies the I2C flag to check.
+ * @param  awaited_value: The awaited bit value for the flag (0 or 1).
+ * @param  timeout: timeout duration
+ * @param  tick_start: Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
+                        uint8_t awaited_value, uint32_t timeout,
+                        uint32_t tick_start)
+{
+       uint8_t flag_check;
+
+       do {
+               flag_check = ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+                              flag) == flag) ? 1U : 0U;
+
+               if (timeout != MAX_DELAY) {
+                       if ((((uint32_t)read_cntpct_el0() - tick_start) >
+                            timeout) || (timeout == 0U)) {
+                               hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+                               hi2c->i2c_state = I2C_STATE_READY;
+                               hi2c->i2c_mode = I2C_MODE_NONE;
+
+                               hi2c->lock = 0;
+                               return -EIO;
+                       }
+               }
+       } while (flag_check == awaited_value);
+
+       return 0;
+}
+
+/*
+ * @brief  This function handles I2C Communication timeout for specific usage
+ *        of TXIS flag.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  timeout: timeout duration
+ * @param  tick_start: Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint32_t timeout,
+                        uint32_t tick_start)
+{
+       while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+               I2C_FLAG_TXIS) == 0U) {
+               if (i2c_ack_failed(hi2c, timeout, tick_start) != 0) {
+                       return -EIO;
+               }
+
+               if (timeout != MAX_DELAY) {
+                       if ((((uint32_t)read_cntpct_el0() - tick_start) >
+                            timeout) || (timeout == 0U)) {
+                               hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+                               hi2c->i2c_state = I2C_STATE_READY;
+                               hi2c->i2c_mode = I2C_MODE_NONE;
+
+                               hi2c->lock = 0;
+
+                               return -EIO;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * @brief  This function handles I2C Communication timeout for specific
+ *        usage of STOP flag.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  timeout: timeout duration
+ * @param  tick_start: Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint32_t timeout,
+                        uint32_t tick_start)
+{
+       while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+                I2C_FLAG_STOPF) == 0U) {
+               if (i2c_ack_failed(hi2c, timeout, tick_start) != 0) {
+                       return -EIO;
+               }
+
+               if ((((uint32_t)read_cntpct_el0() - tick_start) > timeout) ||
+                   (timeout == 0U)) {
+                       hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+                       hi2c->i2c_state = I2C_STATE_READY;
+                       hi2c->i2c_mode = I2C_MODE_NONE;
+
+                       hi2c->lock = 0;
+
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * @brief  This function handles Acknowledge failed detection during
+ *        an I2C Communication.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  timeout: timeout duration
+ * @param  tick_start: Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint32_t timeout,
+                         uint32_t tick_start)
+{
+       if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_AF) == 0U) {
+               return 0;
+       }
+
+       /*
+        * Wait until STOP Flag is reset.
+        * AutoEnd should be initiate after AF.
+        */
+       while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+               I2C_FLAG_STOPF) == 0U) {
+               if (timeout != MAX_DELAY) {
+                       if ((((uint32_t)read_cntpct_el0() - tick_start) >
+                            timeout) || (timeout == 0U)) {
+                               hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+                               hi2c->i2c_state = I2C_STATE_READY;
+                               hi2c->i2c_mode = I2C_MODE_NONE;
+
+                               hi2c->lock = 0;
+
+                               return -EIO;
+                       }
+               }
+       }
+
+       mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
+
+       mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
+
+       i2c_flush_txdr(hi2c);
+
+       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
+
+       hi2c->i2c_err |= I2C_ERROR_AF;
+       hi2c->i2c_state = I2C_STATE_READY;
+       hi2c->i2c_mode = I2C_MODE_NONE;
+
+       hi2c->lock = 0;
+
+       return -EIO;
+}
+
+/*
+ * @brief  Handles I2Cx communication when starting transfer or during transfer
+ *        (TC or TCR flag are set).
+ * @param  hi2c: I2C handle.
+ * @param  dev_addr: Specifies the slave address to be programmed.
+ * @param  size: Specifies the number of bytes to be programmed.
+ *   This parameter must be a value between 0 and 255.
+ * @param  i2c_mode: New state of the I2C START condition generation.
+ *   This parameter can be one of the following values:
+ *     @arg @ref I2C_RELOAD_MODE: Enable Reload mode .
+ *     @arg @ref I2C_AUTOEND_MODE: Enable Automatic end mode.
+ *     @arg @ref I2C_SOFTEND_MODE: Enable Software end mode.
+ * @param  request: New state of the I2C START condition generation.
+ *   This parameter can be one of the following values:
+ *     @arg @ref I2C_NO_STARTSTOP: Don't Generate stop and start condition.
+ *     @arg @ref I2C_GENERATE_STOP: Generate stop condition
+ *                                  (size should be set to 0).
+ *     @arg @ref I2C_GENERATE_START_READ: Generate Restart for read request.
+ *     @arg @ref I2C_GENERATE_START_WRITE: Generate Restart for write request.
+ * @retval None
+ */
+static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+                               uint16_t size, uint32_t i2c_mode,
+                               uint32_t request)
+{
+       uint32_t clr_value, set_value;
+
+       clr_value = (I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD |
+                    I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_STOP) |
+               (I2C_CR2_RD_WRN & (request >> (31U - I2C_CR2_RD_WRN_OFFSET)));
+
+       set_value = ((uint32_t)dev_addr & I2C_CR2_SADD) |
+               (((uint32_t)size << I2C_CR2_NBYTES_OFFSET) & I2C_CR2_NBYTES) |
+               i2c_mode | request;
+
+       mmio_clrsetbits_32(hi2c->i2c_base_addr + I2C_CR2, clr_value, set_value);
+}
+
+/*
+ * @brief  Configure I2C Analog noise filter.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2Cx peripheral
+ * @param  analog_filter: New state of the Analog filter.
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_config_analog_filter(struct i2c_handle_s *hi2c,
+                                  uint32_t analog_filter)
+{
+       if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
+               return -EBUSY;
+       }
+
+       hi2c->lock = 1;
+
+       hi2c->i2c_state = I2C_STATE_BUSY;
+
+       /* Disable the selected I2C peripheral */
+       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
+
+       /* Reset I2Cx ANOFF bit */
+       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_ANFOFF);
+
+       /* Set analog filter bit*/
+       mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, analog_filter);
+
+       /* Enable the selected I2C peripheral */
+       mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
+
+       hi2c->i2c_state = I2C_STATE_READY;
+
+       hi2c->lock = 0;
+
+       return 0;
+}
index 0164a2d43da4688fe9d647aa88fdc32e7caedc59..dc2977d5a62a570e0269ff71af70c743eff80ffd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -94,6 +94,8 @@ static int stm32image_dev_open(const uintptr_t init_params,
        for (i = 0; i < STM32_PART_NUM; i++) {
                memcpy(stm32image_dev.part_info[i].name,
                       device_info->part_info[i].name, MAX_PART_NAME_SIZE);
+               stm32image_dev.part_info[i].binary_type =
+                       device_info->part_info[i].binary_type;
                stm32image_dev.part_info[i].part_offset =
                        device_info->part_info[i].part_offset;
                stm32image_dev.part_info[i].bkp_offset =
@@ -193,21 +195,29 @@ static int stm32image_partition_size(io_entity_t *entity, size_t *length)
                result = io_read(backend_handle, (uintptr_t)header,
                                 MAX_LBA_SIZE, (size_t *)&bytes_read);
                if (result != 0) {
-                       ERROR("%s: io_read (%i)\n", __func__, result);
-                       break;
+                       if (current_part->bkp_offset == 0U) {
+                               ERROR("%s: io_read (%i)\n", __func__, result);
+                       }
+                       header->magic = 0;
                }
 
                if ((header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) ||
                    (header->binary_type != current_part->binary_type) ||
                    (header->image_length >= stm32image_dev.device_size)) {
-                       WARN("%s: partition %s wrong header\n",
-                            __func__, current_part->name);
+                       VERBOSE("%s: partition %s not found at %x\n",
+                               __func__, current_part->name, *stm32_img);
+
+                       if (current_part->bkp_offset == 0U) {
+                               result = -ENOMEM;
+                               break;
+                       }
 
                        /* Header not correct, check next offset for backup */
                        *stm32_img += current_part->bkp_offset;
                        if (*stm32_img > stm32image_dev.device_size) {
                                /* No backup found, end of device reached */
-                               WARN("Out of memory\n");
+                               WARN("%s : partition %s not found\n",
+                                    __func__, current_part->name);
                                result = -ENOMEM;
                                break;
                        }
@@ -221,9 +231,13 @@ static int stm32image_partition_size(io_entity_t *entity, size_t *length)
                return result;
        }
 
-       *length = header->image_length;
+       if (header->image_length < stm32image_dev.lba_size) {
+               *length = stm32image_dev.lba_size;
+       } else {
+               *length = header->image_length;
+       }
 
-       INFO("STM32 Image size : %i\n", *length);
+       INFO("STM32 Image size : %lu\n", (unsigned long)*length);
 
        return 0;
 }
@@ -266,11 +280,10 @@ static int check_header(boot_api_image_header_t *header, uintptr_t buffer)
 static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
                                     size_t length, size_t *length_read)
 {
-       int result = 0, offset, local_length = 0;
+       int result = 0;
        uint8_t *local_buffer = (uint8_t *)buffer;
        boot_api_image_header_t *header =
                (boot_api_image_header_t *)first_lba_buffer;
-       uintptr_t backend_handle;
 
        assert(entity != NULL);
        assert(buffer != 0U);
@@ -279,8 +292,17 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
        *length_read = 0U;
 
        while (*length_read == 0U) {
+               int offset;
+               int local_length;
+               uintptr_t backend_handle;
+
                if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) {
                        /* Check for backup as image is corrupted */
+                       if (current_part->bkp_offset == 0U) {
+                               result = -ENOMEM;
+                               break;
+                       }
+
                        *stm32_img += current_part->bkp_offset;
                        if (*stm32_img >= stm32image_dev.device_size) {
                                /* End of device reached */
@@ -342,8 +364,8 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
                if (result != 0) {
                        ERROR("%s: io_read (%i)\n", __func__, result);
                        *length_read = 0;
-                       io_close(backend_handle);
-                       break;
+                       header->magic = 0;
+                       continue;
                }
 
                result = check_header(header, buffer);
@@ -351,8 +373,6 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
                        ERROR("Header check failed\n");
                        *length_read = 0;
                        header->magic = 0;
-                       io_close(backend_handle);
-                       break;
                }
 
                io_close(backend_handle);
index 05f5ae17c9d802da9f0ad0edbb1b7cc62585992b..57812d89930b54e40b7b1f79f636570356bda8a4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +17,7 @@
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
 #include <drivers/mmc.h>
+#include <drivers/st/stm32_gpio.h>
 #include <drivers/st/stm32_sdmmc2.h>
 #include <drivers/st/stm32mp1_clk.h>
 #include <drivers/st/stm32mp1_rcc.h>
@@ -470,12 +471,11 @@ static int stm32_sdmmc2_prepare(int lba, uintptr_t buf, size_t size)
        }
 
        /* Prepare CMD 16*/
-       mmio_write_32(base + SDMMC_DTIMER, UINT32_MAX);
+       mmio_write_32(base + SDMMC_DTIMER, 0);
 
        mmio_write_32(base + SDMMC_DLENR, 0);
 
-       mmio_clrsetbits_32(base + SDMMC_DCTRLR,
-                          SDMMC_DCTRLR_CLEAR_MASK, SDMMC_DCTRLR_DTDIR);
+       mmio_write_32(base + SDMMC_DCTRLR, 0);
 
        zeromem(&cmd, sizeof(struct mmc_cmd));
 
@@ -643,7 +643,7 @@ static int stm32_sdmmc2_dt_get_config(void)
                return -FDT_ERR_NOTFOUND;
        }
 
-       if (fdt_check_status(sdmmc_node) == 0) {
+       if (fdt_get_status(sdmmc_node) == DT_DISABLED) {
                return -FDT_ERR_NOTFOUND;
        }
 
@@ -667,15 +667,15 @@ static int stm32_sdmmc2_dt_get_config(void)
        cuint++;
        sdmmc2_params.reset_id = fdt32_to_cpu(*cuint);
 
-       if ((fdt_getprop(fdt, sdmmc_node, "st,pin-ckin", NULL)) != NULL) {
+       if ((fdt_getprop(fdt, sdmmc_node, "st,use-ckin", NULL)) != NULL) {
                sdmmc2_params.pin_ckin = SDMMC_CLKCR_SELCLKRX_0;
        }
 
-       if ((fdt_getprop(fdt, sdmmc_node, "st,dirpol", NULL)) != NULL) {
+       if ((fdt_getprop(fdt, sdmmc_node, "st,sig-dir", NULL)) != NULL) {
                sdmmc2_params.dirpol = SDMMC_POWER_DIRPOL;
        }
 
-       if ((fdt_getprop(fdt, sdmmc_node, "st,negedge", NULL)) != NULL) {
+       if ((fdt_getprop(fdt, sdmmc_node, "st,neg-edge", NULL)) != NULL) {
                sdmmc2_params.negedge = SDMMC_CLKCR_NEGEDGE;
        }
 
diff --git a/drivers/st/pmic/stm32_i2c.c b/drivers/st/pmic/stm32_i2c.c
deleted file mode 100644 (file)
index f861ba2..0000000
+++ /dev/null
@@ -1,852 +0,0 @@
-/*
- * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#include <arch_helpers.h>
-#include <drivers/delay_timer.h>
-#include <drivers/st/stm32_i2c.h>
-#include <lib/mmio.h>
-
-/* STM32 I2C registers offsets */
-#define I2C_CR1                        0x00U
-#define I2C_CR2                        0x04U
-#define I2C_OAR1               0x08U
-#define I2C_OAR2               0x0CU
-#define I2C_TIMINGR            0x10U
-#define I2C_TIMEOUTR           0x14U
-#define I2C_ISR                        0x18U
-#define I2C_ICR                        0x1CU
-#define I2C_PECR               0x20U
-#define I2C_RXDR               0x24U
-#define I2C_TXDR               0x28U
-
-#define MAX_DELAY              0xFFFFFFFFU
-
-/* I2C TIMING clear register Mask */
-#define TIMING_CLEAR_MASK      0xF0FFFFFFU
-/* Timeout 25 ms */
-#define I2C_TIMEOUT_BUSY       25U
-
-#define MAX_NBYTE_SIZE         255U
-
-static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
-                                   uint16_t dev_addr, uint16_t mem_addr,
-                                   uint16_t mem_add_size, uint32_t timeout,
-                                   uint32_t tick_start);
-static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
-                                  uint16_t mem_addr, uint16_t mem_add_size,
-                                  uint32_t timeout, uint32_t tick_start);
-
-/* Private functions to handle flags during polling transfer */
-static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
-                        uint8_t awaited_value, uint32_t timeout,
-                        uint32_t tick_start);
-static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint32_t timeout,
-                        uint32_t tick_start);
-static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint32_t timeout,
-                        uint32_t tick_start);
-static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint32_t timeout,
-                         uint32_t tick_start);
-
-/* Private function to flush TXDR register */
-static void i2c_flush_txdr(struct i2c_handle_s *hi2c);
-
-/* Private function to start, restart or stop a transfer */
-static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
-                               uint16_t size, uint32_t i2c_mode,
-                               uint32_t request);
-
-/*
- * @brief  Initialize the I2C device.
- * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
- *               the configuration information for the specified I2C.
- * @retval 0 if OK, negative value else
- */
-int stm32_i2c_init(struct i2c_handle_s *hi2c)
-{
-       if (hi2c == NULL) {
-               return -ENOENT;
-       }
-
-       if (hi2c->i2c_state == I2C_STATE_RESET) {
-               hi2c->lock = 0;
-       }
-
-       hi2c->i2c_state = I2C_STATE_BUSY;
-
-       /* Disable the selected I2C peripheral */
-       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
-
-       /* Configure I2Cx: Frequency range */
-       mmio_write_32(hi2c->i2c_base_addr + I2C_TIMINGR,
-                     hi2c->i2c_init.timing & TIMING_CLEAR_MASK);
-
-       /* Disable Own Address1 before set the Own Address1 configuration */
-       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR1, I2C_OAR1_OA1EN);
-
-       /* Configure I2Cx: Own Address1 and ack own address1 mode */
-       if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
-               mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
-                             I2C_OAR1_OA1EN | hi2c->i2c_init.own_address1);
-       } else { /* I2C_ADDRESSINGMODE_10BIT */
-               mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
-                             I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE |
-                             hi2c->i2c_init.own_address1);
-       }
-
-       /* Configure I2Cx: Addressing Master mode */
-       if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_10BIT) {
-               mmio_write_32(hi2c->i2c_base_addr + I2C_CR2, I2C_CR2_ADD10);
-       }
-
-       /*
-        * Enable the AUTOEND by default, and enable NACK
-        * (should be disable only during Slave process)
-        */
-       mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
-                       I2C_CR2_AUTOEND | I2C_CR2_NACK);
-
-       /* Disable Own Address2 before set the Own Address2 configuration */
-       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR2, I2C_DUALADDRESS_ENABLE);
-
-       /* Configure I2Cx: Dual mode and Own Address2 */
-       mmio_write_32(hi2c->i2c_base_addr + I2C_OAR2,
-                     hi2c->i2c_init.dual_address_mode |
-                     hi2c->i2c_init.own_address2 |
-                     (hi2c->i2c_init.own_address2_masks << 8));
-
-       /* Configure I2Cx: Generalcall and NoStretch mode */
-       mmio_write_32(hi2c->i2c_base_addr + I2C_CR1,
-                     hi2c->i2c_init.general_call_mode |
-                     hi2c->i2c_init.no_stretch_mode);
-
-       /* Enable the selected I2C peripheral */
-       mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
-
-       hi2c->i2c_err = I2C_ERROR_NONE;
-       hi2c->i2c_state = I2C_STATE_READY;
-       hi2c->i2c_mode = I2C_MODE_NONE;
-
-       return 0;
-}
-
-/*
- * @brief  Write an amount of data in blocking mode to a specific memory address
- * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
- *               the configuration information for the specified I2C.
- * @param  dev_addr: Target device address
- * @param  mem_addr: Internal memory address
- * @param  mem_add_size: size of internal memory address
- * @param  p_data: Pointer to data buffer
- * @param  size: Amount of data to be sent
- * @param  timeout: timeout duration
- * @retval 0 if OK, negative value else
- */
-int stm32_i2c_mem_write(struct i2c_handle_s *hi2c, uint16_t dev_addr,
-                       uint16_t mem_addr, uint16_t mem_add_size,
-                       uint8_t *p_data, uint16_t size, uint32_t timeout)
-{
-       uint32_t tickstart;
-
-       if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
-               return -EBUSY;
-       }
-
-       if ((p_data == NULL) || (size == 0U)) {
-               return -EINVAL;
-       }
-
-       hi2c->lock = 1;
-
-       tickstart = (uint32_t)read_cntpct_el0();
-
-       if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, I2C_TIMEOUT_BUSY,
-                         tickstart) != 0) {
-               return -EIO;
-       }
-
-       hi2c->i2c_state     = I2C_STATE_BUSY_TX;
-       hi2c->i2c_mode      = I2C_MODE_MEM;
-       hi2c->i2c_err = I2C_ERROR_NONE;
-
-       hi2c->p_buff  = p_data;
-       hi2c->xfer_count = size;
-
-       /* Send Slave Address and Memory Address */
-       if (i2c_request_memory_write(hi2c, dev_addr, mem_addr, mem_add_size,
-                                    timeout, tickstart) != 0) {
-               hi2c->lock = 0;
-               return -EIO;
-       }
-
-       /*
-        * Set NBYTES to write and reload
-        * if hi2c->xfer_count > MAX_NBYTE_SIZE
-        */
-       if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
-               hi2c->xfer_size = MAX_NBYTE_SIZE;
-               i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
-                                   I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
-       } else {
-               hi2c->xfer_size = hi2c->xfer_count;
-               i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
-                                   I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
-       }
-
-       do {
-               if (i2c_wait_txis(hi2c, timeout, tickstart) != 0) {
-                       return -EIO;
-               }
-
-               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR, *hi2c->p_buff);
-               hi2c->p_buff++;
-               hi2c->xfer_count--;
-               hi2c->xfer_size--;
-
-               if ((hi2c->xfer_count != 0U) && (hi2c->xfer_size == 0U)) {
-                       /* Wait until TCR flag is set */
-                       if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout,
-                                         tickstart) != 0) {
-                               return -EIO;
-               }
-
-                       if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
-                               hi2c->xfer_size = MAX_NBYTE_SIZE;
-                               i2c_transfer_config(hi2c, dev_addr,
-                                                   hi2c->xfer_size,
-                                                   I2C_RELOAD_MODE,
-                                                   I2C_NO_STARTSTOP);
-                       } else {
-                               hi2c->xfer_size = hi2c->xfer_count;
-                               i2c_transfer_config(hi2c, dev_addr,
-                                                   hi2c->xfer_size,
-                                                   I2C_AUTOEND_MODE,
-                                                   I2C_NO_STARTSTOP);
-                       }
-               }
-
-       } while (hi2c->xfer_count > 0U);
-
-       /*
-        * No need to Check TC flag, with AUTOEND mode the stop
-        * is automatically generated.
-        * Wait until STOPF flag is reset.
-        */
-       if (i2c_wait_stop(hi2c, timeout, tickstart) != 0) {
-               return -EIO;
-       }
-
-       mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
-
-       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
-
-       hi2c->i2c_state = I2C_STATE_READY;
-       hi2c->i2c_mode  = I2C_MODE_NONE;
-
-       hi2c->lock = 0;
-
-       return 0;
-}
-
-/*
- * @brief  Read an amount of data in blocking mode from a specific memory
- *        address
- * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
- *               the configuration information for the specified I2C.
- * @param  dev_addr: Target device address
- * @param  mem_addr: Internal memory address
- * @param  mem_add_size: size of internal memory address
- * @param  p_data: Pointer to data buffer
- * @param  size: Amount of data to be sent
- * @param  timeout: timeout duration
- * @retval 0 if OK, negative value else
- */
-int stm32_i2c_mem_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
-                      uint16_t mem_addr, uint16_t mem_add_size,
-                      uint8_t *p_data, uint16_t size, uint32_t timeout)
-{
-       uint32_t tickstart;
-
-       if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
-               return -EBUSY;
-       }
-
-       if ((p_data == NULL) || (size == 0U)) {
-               return  -EINVAL;
-       }
-
-       hi2c->lock = 1;
-
-       tickstart = (uint32_t)read_cntpct_el0();
-
-       if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, I2C_TIMEOUT_BUSY,
-                         tickstart) != 0) {
-               return -EIO;
-       }
-
-       hi2c->i2c_state     = I2C_STATE_BUSY_RX;
-       hi2c->i2c_mode      = I2C_MODE_MEM;
-       hi2c->i2c_err = I2C_ERROR_NONE;
-
-       hi2c->p_buff  = p_data;
-       hi2c->xfer_count = size;
-
-       /* Send Slave Address and Memory Address */
-       if (i2c_request_memory_read(hi2c, dev_addr, mem_addr, mem_add_size,
-                                   timeout, tickstart) != 0) {
-               hi2c->lock = 0;
-               return -EIO;
-       }
-
-       /*
-        * Send Slave Address.
-        * Set NBYTES to write and reload if hi2c->xfer_count > MAX_NBYTE_SIZE
-        * and generate RESTART.
-        */
-       if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
-               hi2c->xfer_size = MAX_NBYTE_SIZE;
-               i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
-                                   I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
-       } else {
-               hi2c->xfer_size = hi2c->xfer_count;
-               i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
-                                   I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
-       }
-
-       do {
-               if (i2c_wait_flag(hi2c, I2C_FLAG_RXNE, 0, timeout,
-                                 tickstart) != 0) {
-                       return -EIO;
-               }
-
-               *hi2c->p_buff = mmio_read_8(hi2c->i2c_base_addr + I2C_RXDR);
-               hi2c->p_buff++;
-               hi2c->xfer_size--;
-               hi2c->xfer_count--;
-
-               if ((hi2c->xfer_count != 0U) && (hi2c->xfer_size == 0U)) {
-                       if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout,
-                                         tickstart) != 0) {
-                               return -EIO;
-                       }
-
-                       if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
-                               hi2c->xfer_size = MAX_NBYTE_SIZE;
-                               i2c_transfer_config(hi2c, dev_addr,
-                                                   hi2c->xfer_size,
-                                                   I2C_RELOAD_MODE,
-                                                   I2C_NO_STARTSTOP);
-                       } else {
-                               hi2c->xfer_size = hi2c->xfer_count;
-                               i2c_transfer_config(hi2c, dev_addr,
-                                                   hi2c->xfer_size,
-                                                   I2C_AUTOEND_MODE,
-                                                   I2C_NO_STARTSTOP);
-                       }
-               }
-       } while (hi2c->xfer_count > 0U);
-
-       /*
-        * No need to Check TC flag, with AUTOEND mode the stop
-        * is automatically generated
-        * Wait until STOPF flag is reset
-        */
-       if (i2c_wait_stop(hi2c, timeout, tickstart) != 0) {
-               return -EIO;
-       }
-
-       mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
-
-       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
-
-       hi2c->i2c_state = I2C_STATE_READY;
-       hi2c->i2c_mode  = I2C_MODE_NONE;
-
-       hi2c->lock = 0;
-
-       return 0;
-}
-
-/*
- * @brief  Checks if target device is ready for communication.
- * @note   This function is used with Memory devices
- * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
- *               the configuration information for the specified I2C.
- * @param  dev_addr: Target device address
- * @param  trials: Number of trials
- * @param  timeout: timeout duration
- * @retval 0 if OK, negative value else
- */
-int stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c,
-                             uint16_t dev_addr, uint32_t trials,
-                             uint32_t timeout)
-{
-       uint32_t i2c_trials = 0U;
-
-       if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
-               return -EBUSY;
-       }
-
-       if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_BUSY) !=
-           0U) {
-               return -EBUSY;
-       }
-
-       hi2c->lock = 1;
-
-       hi2c->i2c_state = I2C_STATE_BUSY;
-       hi2c->i2c_err = I2C_ERROR_NONE;
-
-       do {
-               uint32_t tickstart;
-
-               /* Generate Start */
-               if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
-                       mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
-                                     (((uint32_t)dev_addr & I2C_CR2_SADD) |
-                                      I2C_CR2_START | I2C_CR2_AUTOEND) &
-                                      ~I2C_CR2_RD_WRN);
-               } else {
-                       mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
-                                     (((uint32_t)dev_addr & I2C_CR2_SADD) |
-                                      I2C_CR2_START | I2C_CR2_ADD10) &
-                                     ~I2C_CR2_RD_WRN);
-               }
-
-               /*
-                * No need to Check TC flag, with AUTOEND mode the stop
-                * is automatically generated
-                * Wait until STOPF flag is set or a NACK flag is set
-                */
-               tickstart = (uint32_t)read_cntpct_el0();
-               while (((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
-                        (I2C_FLAG_STOPF | I2C_FLAG_AF)) == 0U) &&
-                      (hi2c->i2c_state != I2C_STATE_TIMEOUT)) {
-                       if (timeout != MAX_DELAY) {
-                               if ((((uint32_t)read_cntpct_el0() - tickstart) >
-                                    timeout) || (timeout == 0U)) {
-                                       hi2c->i2c_state = I2C_STATE_READY;
-
-                                       hi2c->i2c_err |=
-                                               I2C_ERROR_TIMEOUT;
-
-                                       hi2c->lock = 0;
-
-                                       return -EIO;
-                               }
-                       }
-               }
-
-               /* Check if the NACKF flag has not been set */
-               if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
-                    I2C_FLAG_AF) == 0U) {
-                       if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
-                                         tickstart) != 0) {
-                               return -EIO;
-                       }
-
-                       mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
-                                     I2C_FLAG_STOPF);
-
-                       hi2c->i2c_state = I2C_STATE_READY;
-
-                       hi2c->lock = 0;
-
-                       return 0;
-               }
-
-               if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
-                                 tickstart) != 0) {
-                       return -EIO;
-               }
-
-               mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
-
-               mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
-
-               if (i2c_trials == trials) {
-                       mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
-                                       I2C_CR2_STOP);
-
-                       if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
-                                         tickstart) != 0) {
-                               return -EIO;
-                       }
-
-                       mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
-                                     I2C_FLAG_STOPF);
-               }
-
-               i2c_trials++;
-       } while (i2c_trials < trials);
-
-       hi2c->i2c_state = I2C_STATE_READY;
-
-       hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
-
-       hi2c->lock = 0;
-
-       return -EIO;
-}
-
-/*
- * @brief  Master sends target device address followed by internal memory
- *        address for write request.
- * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
- *               the configuration information for the specified I2C.
- * @param  dev_addr: Target device address
- * @param  mem_addr: Internal memory address
- * @param  mem_add_size: size of internal memory address
- * @param  timeout: timeout duration
- * @param  tick_start Tick start value
- * @retval 0 if OK, negative value else
- */
-static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
-                                   uint16_t dev_addr, uint16_t mem_addr,
-                                   uint16_t mem_add_size, uint32_t timeout,
-                                   uint32_t tick_start)
-{
-       i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_RELOAD_MODE,
-                           I2C_GENERATE_START_WRITE);
-
-       if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
-               return -EIO;
-       }
-
-       if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
-               /* Send Memory Address */
-               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
-                            (uint8_t)(mem_addr & 0x00FFU));
-       } else {
-               /* Send MSB of Memory Address */
-               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
-                            (uint8_t)((mem_addr & 0xFF00U) >> 8));
-
-               /* Wait until TXIS flag is set */
-               if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
-                       return -EIO;
-               }
-
-               /* Send LSB of Memory Address */
-               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
-                            (uint8_t)(mem_addr & 0x00FFU));
-       }
-
-       if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout, tick_start) !=
-           0) {
-               return -EIO;
-       }
-
-       return 0;
-}
-
-/*
- * @brief  Master sends target device address followed by internal memory
- *        address for read request.
- * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
- *               the configuration information for the specified I2C.
- * @param  dev_addr: Target device address
- * @param  mem_addr: Internal memory address
- * @param  mem_add_size: size of internal memory address
- * @param  timeout: timeout duration
- * @param  tick_start Tick start value
- * @retval 0 if OK, negative value else
- */
-static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
-                                  uint16_t mem_addr, uint16_t mem_add_size,
-                                  uint32_t timeout, uint32_t tick_start)
-{
-       i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_SOFTEND_MODE,
-                           I2C_GENERATE_START_WRITE);
-
-       if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
-               return -EIO;
-       }
-
-       if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
-               /* Send Memory Address */
-               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
-                            (uint8_t)(mem_addr & 0x00FFU));
-       } else {
-               /* Send MSB of Memory Address */
-               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
-                            (uint8_t)((mem_addr & 0xFF00U) >> 8));
-
-               /* Wait until TXIS flag is set */
-               if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
-                       return -EIO;
-               }
-
-               /* Send LSB of Memory Address */
-               mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
-                            (uint8_t)(mem_addr & 0x00FFU));
-       }
-
-       if (i2c_wait_flag(hi2c, I2C_FLAG_TC, 0, timeout, tick_start) != 0) {
-               return -EIO;
-       }
-
-       return 0;
-}
-
-/*
- * @brief  I2C Tx data register flush process.
- * @param  hi2c: I2C handle.
- * @retval None
- */
-static void i2c_flush_txdr(struct i2c_handle_s *hi2c)
-{
-       /*
-        * If a pending TXIS flag is set,
-        * write a dummy data in TXDR to clear it.
-        */
-       if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXIS) !=
-           0U) {
-               mmio_write_32(hi2c->i2c_base_addr + I2C_TXDR, 0);
-       }
-
-       /* Flush TX register if not empty */
-       if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXE) ==
-           0U) {
-               mmio_setbits_32(hi2c->i2c_base_addr + I2C_ISR,
-                               I2C_FLAG_TXE);
-       }
-}
-
-/*
- * @brief  This function handles I2C Communication timeout.
- * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
- *               the configuration information for the specified I2C.
- * @param  flag: Specifies the I2C flag to check.
- * @param  awaited_value: The awaited bit value for the flag (0 or 1).
- * @param  timeout: timeout duration
- * @param  tick_start: Tick start value
- * @retval 0 if OK, negative value else
- */
-static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
-                        uint8_t awaited_value, uint32_t timeout,
-                        uint32_t tick_start)
-{
-       uint8_t flag_check;
-
-       do {
-               flag_check = ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
-                              flag) == flag) ? 1U : 0U;
-
-               if (timeout != MAX_DELAY) {
-                       if ((((uint32_t)read_cntpct_el0() - tick_start) >
-                            timeout) || (timeout == 0U)) {
-                               hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
-                               hi2c->i2c_state = I2C_STATE_READY;
-                               hi2c->i2c_mode = I2C_MODE_NONE;
-
-                               hi2c->lock = 0;
-                               return -EIO;
-                       }
-               }
-       } while (flag_check == awaited_value);
-
-       return 0;
-}
-
-/*
- * @brief  This function handles I2C Communication timeout for specific usage
- *        of TXIS flag.
- * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
- *               the configuration information for the specified I2C.
- * @param  timeout: timeout duration
- * @param  tick_start: Tick start value
- * @retval 0 if OK, negative value else
- */
-static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint32_t timeout,
-                        uint32_t tick_start)
-{
-       while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
-               I2C_FLAG_TXIS) == 0U) {
-               if (i2c_ack_failed(hi2c, timeout, tick_start) != 0) {
-                       return -EIO;
-               }
-
-               if (timeout != MAX_DELAY) {
-                       if ((((uint32_t)read_cntpct_el0() - tick_start) >
-                            timeout) || (timeout == 0U)) {
-                               hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
-                               hi2c->i2c_state = I2C_STATE_READY;
-                               hi2c->i2c_mode = I2C_MODE_NONE;
-
-                               hi2c->lock = 0;
-
-                               return -EIO;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-/*
- * @brief  This function handles I2C Communication timeout for specific
- *        usage of STOP flag.
- * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
- *               the configuration information for the specified I2C.
- * @param  timeout: timeout duration
- * @param  tick_start: Tick start value
- * @retval 0 if OK, negative value else
- */
-static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint32_t timeout,
-                        uint32_t tick_start)
-{
-       while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
-                I2C_FLAG_STOPF) == 0U) {
-               if (i2c_ack_failed(hi2c, timeout, tick_start) != 0) {
-                       return -EIO;
-               }
-
-               if ((((uint32_t)read_cntpct_el0() - tick_start) > timeout) ||
-                   (timeout == 0U)) {
-                       hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
-                       hi2c->i2c_state = I2C_STATE_READY;
-                       hi2c->i2c_mode = I2C_MODE_NONE;
-
-                       hi2c->lock = 0;
-
-                       return -EIO;
-               }
-       }
-
-       return 0;
-}
-
-/*
- * @brief  This function handles Acknowledge failed detection during
- *        an I2C Communication.
- * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
- *               the configuration information for the specified I2C.
- * @param  timeout: timeout duration
- * @param  tick_start: Tick start value
- * @retval 0 if OK, negative value else
- */
-static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint32_t timeout,
-                         uint32_t tick_start)
-{
-       if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_AF) == 0U) {
-               return 0;
-       }
-
-       /*
-        * Wait until STOP Flag is reset.
-        * AutoEnd should be initiate after AF.
-        */
-       while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
-               I2C_FLAG_STOPF) == 0U) {
-               if (timeout != MAX_DELAY) {
-                       if ((((uint32_t)read_cntpct_el0() - tick_start) >
-                            timeout) || (timeout == 0U)) {
-                               hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
-                               hi2c->i2c_state = I2C_STATE_READY;
-                               hi2c->i2c_mode = I2C_MODE_NONE;
-
-                               hi2c->lock = 0;
-
-                               return -EIO;
-                       }
-               }
-       }
-
-       mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
-
-       mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
-
-       i2c_flush_txdr(hi2c);
-
-       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
-
-       hi2c->i2c_err |= I2C_ERROR_AF;
-       hi2c->i2c_state = I2C_STATE_READY;
-       hi2c->i2c_mode = I2C_MODE_NONE;
-
-       hi2c->lock = 0;
-
-       return -EIO;
-}
-
-/*
- * @brief  Handles I2Cx communication when starting transfer or during transfer
- *        (TC or TCR flag are set).
- * @param  hi2c: I2C handle.
- * @param  dev_addr: Specifies the slave address to be programmed.
- * @param  size: Specifies the number of bytes to be programmed.
- *   This parameter must be a value between 0 and 255.
- * @param  i2c_mode: New state of the I2C START condition generation.
- *   This parameter can be one of the following values:
- *     @arg @ref I2C_RELOAD_MODE: Enable Reload mode .
- *     @arg @ref I2C_AUTOEND_MODE: Enable Automatic end mode.
- *     @arg @ref I2C_SOFTEND_MODE: Enable Software end mode.
- * @param  request: New state of the I2C START condition generation.
- *   This parameter can be one of the following values:
- *     @arg @ref I2C_NO_STARTSTOP: Don't Generate stop and start condition.
- *     @arg @ref I2C_GENERATE_STOP: Generate stop condition
- *                                  (size should be set to 0).
- *     @arg @ref I2C_GENERATE_START_READ: Generate Restart for read request.
- *     @arg @ref I2C_GENERATE_START_WRITE: Generate Restart for write request.
- * @retval None
- */
-static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
-                               uint16_t size, uint32_t i2c_mode,
-                               uint32_t request)
-{
-       uint32_t clr_value, set_value;
-
-       clr_value = (I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD |
-                    I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_STOP) |
-               (I2C_CR2_RD_WRN & (request >> (31U - I2C_CR2_RD_WRN_OFFSET)));
-
-       set_value = ((uint32_t)dev_addr & I2C_CR2_SADD) |
-               (((uint32_t)size << I2C_CR2_NBYTES_OFFSET) & I2C_CR2_NBYTES) |
-               i2c_mode | request;
-
-       mmio_clrsetbits_32(hi2c->i2c_base_addr + I2C_CR2, clr_value, set_value);
-}
-
-/*
- * @brief  Configure I2C Analog noise filter.
- * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
- *               the configuration information for the specified I2Cx peripheral
- * @param  analog_filter: New state of the Analog filter.
- * @retval 0 if OK, negative value else
- */
-int stm32_i2c_config_analog_filter(struct i2c_handle_s *hi2c,
-                                  uint32_t analog_filter)
-{
-       if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
-               return -EBUSY;
-       }
-
-       hi2c->lock = 1;
-
-       hi2c->i2c_state = I2C_STATE_BUSY;
-
-       /* Disable the selected I2C peripheral */
-       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
-
-       /* Reset I2Cx ANOFF bit */
-       mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_ANFOFF);
-
-       /* Set analog filter bit*/
-       mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, analog_filter);
-
-       /* Enable the selected I2C peripheral */
-       mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
-
-       hi2c->i2c_state = I2C_STATE_READY;
-
-       hi2c->lock = 0;
-
-       return 0;
-}
diff --git a/drivers/st/pmic/stm32mp1_pmic.c b/drivers/st/pmic/stm32mp1_pmic.c
deleted file mode 100644 (file)
index c5bdfc0..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <errno.h>
-#include <stdbool.h>
-
-#include <libfdt.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <drivers/delay_timer.h>
-#include <drivers/st/stm32_gpio.h>
-#include <drivers/st/stm32mp1_clk.h>
-#include <drivers/st/stm32mp1_pmic.h>
-#include <drivers/st/stpmu1.h>
-#include <lib/mmio.h>
-#include <lib/utils_def.h>
-
-/* I2C Timing hard-coded value, for I2C clock source is HSI at 64MHz */
-#define I2C_TIMING                     0x10D07DB5
-
-#define I2C_TIMEOUT                    0xFFFFF
-
-#define MASK_RESET_BUCK3               BIT(2)
-
-#define STPMU1_LDO12356_OUTPUT_MASK    (uint8_t)(GENMASK(6, 2))
-#define STPMU1_LDO12356_OUTPUT_SHIFT   2
-#define STPMU1_LDO3_MODE               (uint8_t)(BIT(7))
-#define STPMU1_LDO3_DDR_SEL            31U
-#define STPMU1_LDO3_1800000            (9U << STPMU1_LDO12356_OUTPUT_SHIFT)
-
-#define STPMU1_BUCK_OUTPUT_SHIFT       2
-#define STPMU1_BUCK3_1V8               (39U << STPMU1_BUCK_OUTPUT_SHIFT)
-
-#define STPMU1_DEFAULT_START_UP_DELAY_MS       1
-
-static struct i2c_handle_s i2c_handle;
-static uint32_t pmic_i2c_addr;
-
-static int dt_get_pmic_node(void *fdt)
-{
-       return fdt_node_offset_by_compatible(fdt, -1, "st,stpmu1");
-}
-
-bool dt_check_pmic(void)
-{
-       int node;
-       void *fdt;
-
-       if (fdt_get_address(&fdt) == 0) {
-               return false;
-       }
-
-       node = dt_get_pmic_node(fdt);
-       if (node < 0) {
-               VERBOSE("%s: No PMIC node found in DT\n", __func__);
-               return false;
-       }
-
-       return fdt_check_status(node);
-}
-
-static int dt_pmic_i2c_config(struct dt_node_info *i2c_info)
-{
-       int pmic_node, i2c_node;
-       void *fdt;
-       const fdt32_t *cuint;
-
-       if (fdt_get_address(&fdt) == 0) {
-               return -ENOENT;
-       }
-
-       pmic_node = dt_get_pmic_node(fdt);
-       if (pmic_node < 0) {
-               return -FDT_ERR_NOTFOUND;
-       }
-
-       cuint = fdt_getprop(fdt, pmic_node, "reg", NULL);
-       if (cuint == NULL) {
-               return -FDT_ERR_NOTFOUND;
-       }
-
-       pmic_i2c_addr = fdt32_to_cpu(*cuint) << 1;
-       if (pmic_i2c_addr > UINT16_MAX) {
-               return -EINVAL;
-       }
-
-       i2c_node = fdt_parent_offset(fdt, pmic_node);
-       if (i2c_node < 0) {
-               return -FDT_ERR_NOTFOUND;
-       }
-
-       dt_fill_device_info(i2c_info, i2c_node);
-       if (i2c_info->base == 0U) {
-               return -FDT_ERR_NOTFOUND;
-       }
-
-       return dt_set_pinctrl_config(i2c_node);
-}
-
-int dt_pmic_enable_boot_on_regulators(void)
-{
-       int pmic_node, regulators_node, regulator_node;
-       void *fdt;
-
-       if (fdt_get_address(&fdt) == 0) {
-               return -ENOENT;
-       }
-
-       pmic_node = dt_get_pmic_node(fdt);
-       if (pmic_node < 0) {
-               return -FDT_ERR_NOTFOUND;
-       }
-
-       regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators");
-
-       fdt_for_each_subnode(regulator_node, fdt, regulators_node) {
-               const fdt32_t *cuint;
-               const char *node_name;
-               uint16_t voltage;
-
-               if (fdt_getprop(fdt, regulator_node, "regulator-boot-on",
-                               NULL) == NULL) {
-                       continue;
-               }
-
-               cuint = fdt_getprop(fdt, regulator_node,
-                                   "regulator-min-microvolt", NULL);
-               if (cuint == NULL) {
-                       continue;
-               }
-
-               /* DT uses microvolts, whereas driver awaits millivolts */
-               voltage = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
-               node_name = fdt_get_name(fdt, regulator_node, NULL);
-
-               if (stpmu1_is_regulator_enabled(node_name) == 0U) {
-                       int status;
-
-                       status = stpmu1_regulator_voltage_set(node_name,
-                                                             voltage);
-                       if (status != 0) {
-                               return status;
-                       }
-
-                       status = stpmu1_regulator_enable(node_name);
-                       if (status != 0) {
-                               return status;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-void initialize_pmic_i2c(void)
-{
-       int ret;
-       struct dt_node_info i2c_info;
-
-       if (dt_pmic_i2c_config(&i2c_info) != 0) {
-               ERROR("I2C configuration failed\n");
-               panic();
-       }
-
-       if (stm32mp1_clk_enable((uint32_t)i2c_info.clock) < 0) {
-               ERROR("I2C clock enable failed\n");
-               panic();
-       }
-
-       /* Initialize PMIC I2C */
-       i2c_handle.i2c_base_addr                = i2c_info.base;
-       i2c_handle.i2c_init.timing              = I2C_TIMING;
-       i2c_handle.i2c_init.own_address1        = pmic_i2c_addr;
-       i2c_handle.i2c_init.addressing_mode     = I2C_ADDRESSINGMODE_7BIT;
-       i2c_handle.i2c_init.dual_address_mode   = I2C_DUALADDRESS_DISABLE;
-       i2c_handle.i2c_init.own_address2        = 0;
-       i2c_handle.i2c_init.own_address2_masks  = I2C_OAR2_OA2NOMASK;
-       i2c_handle.i2c_init.general_call_mode   = I2C_GENERALCALL_DISABLE;
-       i2c_handle.i2c_init.no_stretch_mode     = I2C_NOSTRETCH_DISABLE;
-
-       ret = stm32_i2c_init(&i2c_handle);
-       if (ret != 0) {
-               ERROR("Cannot initialize I2C %x (%d)\n",
-                     i2c_handle.i2c_base_addr, ret);
-               panic();
-       }
-
-       ret = stm32_i2c_config_analog_filter(&i2c_handle,
-                                            I2C_ANALOGFILTER_ENABLE);
-       if (ret != 0) {
-               ERROR("Cannot initialize I2C analog filter (%d)\n", ret);
-               panic();
-       }
-
-       ret = stm32_i2c_is_device_ready(&i2c_handle, (uint16_t)pmic_i2c_addr, 1,
-                                       I2C_TIMEOUT);
-       if (ret != 0) {
-               ERROR("I2C device not ready (%d)\n", ret);
-               panic();
-       }
-
-       stpmu1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr);
-}
-
-void initialize_pmic(void)
-{
-       int status;
-       uint8_t read_val;
-
-       initialize_pmic_i2c();
-
-       status = stpmu1_register_read(VERSION_STATUS_REG, &read_val);
-       if (status != 0) {
-               panic();
-       }
-
-       INFO("PMIC version = 0x%x\n", read_val);
-
-       /* Keep VDD on during the reset cycle */
-       status = stpmu1_register_update(MASK_RESET_BUCK_REG,
-                                       MASK_RESET_BUCK3,
-                                       MASK_RESET_BUCK3);
-       if (status != 0) {
-               panic();
-       }
-}
-
-int pmic_ddr_power_init(enum ddr_type ddr_type)
-{
-       bool buck3_at_1v8 = false;
-       uint8_t read_val;
-       int status;
-
-       switch (ddr_type) {
-       case STM32MP_DDR3:
-               /* Set LDO3 to sync mode */
-               status = stpmu1_register_read(LDO3_CONTROL_REG, &read_val);
-               if (status != 0) {
-                       return status;
-               }
-
-               read_val &= ~STPMU1_LDO3_MODE;
-               read_val &= ~STPMU1_LDO12356_OUTPUT_MASK;
-               read_val |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT;
-
-               status = stpmu1_register_write(LDO3_CONTROL_REG, read_val);
-               if (status != 0) {
-                       return status;
-               }
-
-               status = stpmu1_regulator_voltage_set("buck2", 1350);
-               if (status != 0) {
-                       return status;
-               }
-
-               status = stpmu1_regulator_enable("buck2");
-               if (status != 0) {
-                       return status;
-               }
-
-               mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
-
-               status = stpmu1_regulator_enable("vref_ddr");
-               if (status != 0) {
-                       return status;
-               }
-
-               mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
-
-               status = stpmu1_regulator_enable("ldo3");
-               if (status != 0) {
-                       return status;
-               }
-
-               mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
-               break;
-
-       case STM32MP_LPDDR2:
-               /*
-                * Set LDO3 to 1.8V
-                * Set LDO3 to bypass mode if BUCK3 = 1.8V
-                * Set LDO3 to normal mode if BUCK3 != 1.8V
-                */
-               status = stpmu1_register_read(BUCK3_CONTROL_REG, &read_val);
-               if (status != 0) {
-                       return status;
-               }
-
-               if ((read_val & STPMU1_BUCK3_1V8) == STPMU1_BUCK3_1V8) {
-                       buck3_at_1v8 = true;
-               }
-
-               status = stpmu1_register_read(LDO3_CONTROL_REG, &read_val);
-               if (status != 0) {
-                       return status;
-               }
-
-               read_val &= ~STPMU1_LDO3_MODE;
-               read_val &= ~STPMU1_LDO12356_OUTPUT_MASK;
-               read_val |= STPMU1_LDO3_1800000;
-               if (buck3_at_1v8) {
-                       read_val |= STPMU1_LDO3_MODE;
-               }
-
-               status = stpmu1_register_write(LDO3_CONTROL_REG, read_val);
-               if (status != 0) {
-                       return status;
-               }
-
-               status = stpmu1_regulator_voltage_set("buck2", 1200);
-               if (status != 0) {
-                       return status;
-               }
-
-               status = stpmu1_regulator_enable("ldo3");
-               if (status != 0) {
-                       return status;
-               }
-
-               mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
-
-               status = stpmu1_regulator_enable("buck2");
-               if (status != 0) {
-                       return status;
-               }
-
-               mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
-
-               status = stpmu1_regulator_enable("vref_ddr");
-               if (status != 0) {
-                       return status;
-               }
-
-               mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
-               break;
-
-       default:
-               break;
-       };
-
-       return 0;
-}
diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c
new file mode 100644 (file)
index 0000000..6beabc1
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp_pmic.h>
+#include <drivers/st/stm32_gpio.h>
+#include <drivers/st/stm32mp1_clk.h>
+#include <drivers/st/stpmic1.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+/* I2C Timing hard-coded value, for I2C clock source is HSI at 64MHz */
+#define I2C_TIMING                     0x10D07DB5
+
+#define I2C_TIMEOUT                    0xFFFFF
+
+#define MASK_RESET_BUCK3               BIT(2)
+
+#define STPMIC1_LDO12356_OUTPUT_MASK   (uint8_t)(GENMASK(6, 2))
+#define STPMIC1_LDO12356_OUTPUT_SHIFT  2
+#define STPMIC1_LDO3_MODE              (uint8_t)(BIT(7))
+#define STPMIC1_LDO3_DDR_SEL           31U
+#define STPMIC1_LDO3_1800000           (9U << STPMIC1_LDO12356_OUTPUT_SHIFT)
+
+#define STPMIC1_BUCK_OUTPUT_SHIFT      2
+#define STPMIC1_BUCK3_1V8              (39U << STPMIC1_BUCK_OUTPUT_SHIFT)
+
+#define STPMIC1_DEFAULT_START_UP_DELAY_MS      1
+
+static struct i2c_handle_s i2c_handle;
+static uint32_t pmic_i2c_addr;
+
+static int dt_get_pmic_node(void *fdt)
+{
+       return fdt_node_offset_by_compatible(fdt, -1, "st,stpmic1");
+}
+
+bool dt_check_pmic(void)
+{
+       int node;
+       void *fdt;
+
+       if (fdt_get_address(&fdt) == 0) {
+               return false;
+       }
+
+       node = dt_get_pmic_node(fdt);
+       if (node < 0) {
+               VERBOSE("%s: No PMIC node found in DT\n", __func__);
+               return false;
+       }
+
+       return fdt_get_status(node);
+}
+
+static int dt_pmic_i2c_config(struct dt_node_info *i2c_info)
+{
+       int pmic_node, i2c_node;
+       void *fdt;
+       const fdt32_t *cuint;
+
+       if (fdt_get_address(&fdt) == 0) {
+               return -ENOENT;
+       }
+
+       pmic_node = dt_get_pmic_node(fdt);
+       if (pmic_node < 0) {
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       cuint = fdt_getprop(fdt, pmic_node, "reg", NULL);
+       if (cuint == NULL) {
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       pmic_i2c_addr = fdt32_to_cpu(*cuint) << 1;
+       if (pmic_i2c_addr > UINT16_MAX) {
+               return -EINVAL;
+       }
+
+       i2c_node = fdt_parent_offset(fdt, pmic_node);
+       if (i2c_node < 0) {
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       dt_fill_device_info(i2c_info, i2c_node);
+       if (i2c_info->base == 0U) {
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       return dt_set_pinctrl_config(i2c_node);
+}
+
+int dt_pmic_enable_boot_on_regulators(void)
+{
+       int pmic_node, regulators_node, regulator_node;
+       void *fdt;
+
+       if (fdt_get_address(&fdt) == 0) {
+               return -ENOENT;
+       }
+
+       pmic_node = dt_get_pmic_node(fdt);
+       if (pmic_node < 0) {
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators");
+
+       fdt_for_each_subnode(regulator_node, fdt, regulators_node) {
+               const fdt32_t *cuint;
+               const char *node_name;
+               uint16_t voltage;
+
+               if (fdt_getprop(fdt, regulator_node, "regulator-boot-on",
+                               NULL) == NULL) {
+                       continue;
+               }
+
+               cuint = fdt_getprop(fdt, regulator_node,
+                                   "regulator-min-microvolt", NULL);
+               if (cuint == NULL) {
+                       continue;
+               }
+
+               /* DT uses microvolts, whereas driver awaits millivolts */
+               voltage = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
+               node_name = fdt_get_name(fdt, regulator_node, NULL);
+
+               if (stpmic1_is_regulator_enabled(node_name) == 0U) {
+                       int status;
+
+                       status = stpmic1_regulator_voltage_set(node_name,
+                                                              voltage);
+                       if (status != 0) {
+                               return status;
+                       }
+
+                       status = stpmic1_regulator_enable(node_name);
+                       if (status != 0) {
+                               return status;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+void initialize_pmic_i2c(void)
+{
+       int ret;
+       struct dt_node_info i2c_info;
+
+       if (dt_pmic_i2c_config(&i2c_info) != 0) {
+               ERROR("I2C configuration failed\n");
+               panic();
+       }
+
+       if (stm32mp1_clk_enable((uint32_t)i2c_info.clock) < 0) {
+               ERROR("I2C clock enable failed\n");
+               panic();
+       }
+
+       /* Initialize PMIC I2C */
+       i2c_handle.i2c_base_addr                = i2c_info.base;
+       i2c_handle.i2c_init.timing              = I2C_TIMING;
+       i2c_handle.i2c_init.own_address1        = pmic_i2c_addr;
+       i2c_handle.i2c_init.addressing_mode     = I2C_ADDRESSINGMODE_7BIT;
+       i2c_handle.i2c_init.dual_address_mode   = I2C_DUALADDRESS_DISABLE;
+       i2c_handle.i2c_init.own_address2        = 0;
+       i2c_handle.i2c_init.own_address2_masks  = I2C_OAR2_OA2NOMASK;
+       i2c_handle.i2c_init.general_call_mode   = I2C_GENERALCALL_DISABLE;
+       i2c_handle.i2c_init.no_stretch_mode     = I2C_NOSTRETCH_DISABLE;
+
+       ret = stm32_i2c_init(&i2c_handle);
+       if (ret != 0) {
+               ERROR("Cannot initialize I2C %x (%d)\n",
+                     i2c_handle.i2c_base_addr, ret);
+               panic();
+       }
+
+       ret = stm32_i2c_config_analog_filter(&i2c_handle,
+                                            I2C_ANALOGFILTER_ENABLE);
+       if (ret != 0) {
+               ERROR("Cannot initialize I2C analog filter (%d)\n", ret);
+               panic();
+       }
+
+       ret = stm32_i2c_is_device_ready(&i2c_handle, (uint16_t)pmic_i2c_addr, 1,
+                                       I2C_TIMEOUT);
+       if (ret != 0) {
+               ERROR("I2C device not ready (%d)\n", ret);
+               panic();
+       }
+
+       stpmic1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr);
+}
+
+void initialize_pmic(void)
+{
+       int status;
+       uint8_t read_val;
+
+       initialize_pmic_i2c();
+
+       status = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
+       if (status != 0) {
+               panic();
+       }
+
+       INFO("PMIC version = 0x%x\n", read_val);
+
+       /* Keep VDD on during the reset cycle */
+       status = stpmic1_register_update(MASK_RESET_BUCK_REG,
+                                       MASK_RESET_BUCK3,
+                                       MASK_RESET_BUCK3);
+       if (status != 0) {
+               panic();
+       }
+}
+
+int pmic_ddr_power_init(enum ddr_type ddr_type)
+{
+       bool buck3_at_1v8 = false;
+       uint8_t read_val;
+       int status;
+
+       switch (ddr_type) {
+       case STM32MP_DDR3:
+               /* Set LDO3 to sync mode */
+               status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
+               if (status != 0) {
+                       return status;
+               }
+
+               read_val &= ~STPMIC1_LDO3_MODE;
+               read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
+               read_val |= STPMIC1_LDO3_DDR_SEL <<
+                           STPMIC1_LDO12356_OUTPUT_SHIFT;
+
+               status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
+               if (status != 0) {
+                       return status;
+               }
+
+               status = stpmic1_regulator_voltage_set("buck2", 1350);
+               if (status != 0) {
+                       return status;
+               }
+
+               status = stpmic1_regulator_enable("buck2");
+               if (status != 0) {
+                       return status;
+               }
+
+               mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+               status = stpmic1_regulator_enable("vref_ddr");
+               if (status != 0) {
+                       return status;
+               }
+
+               mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+               status = stpmic1_regulator_enable("ldo3");
+               if (status != 0) {
+                       return status;
+               }
+
+               mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+               break;
+
+       case STM32MP_LPDDR2:
+               /*
+                * Set LDO3 to 1.8V
+                * Set LDO3 to bypass mode if BUCK3 = 1.8V
+                * Set LDO3 to normal mode if BUCK3 != 1.8V
+                */
+               status = stpmic1_register_read(BUCK3_CONTROL_REG, &read_val);
+               if (status != 0) {
+                       return status;
+               }
+
+               if ((read_val & STPMIC1_BUCK3_1V8) == STPMIC1_BUCK3_1V8) {
+                       buck3_at_1v8 = true;
+               }
+
+               status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
+               if (status != 0) {
+                       return status;
+               }
+
+               read_val &= ~STPMIC1_LDO3_MODE;
+               read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
+               read_val |= STPMIC1_LDO3_1800000;
+               if (buck3_at_1v8) {
+                       read_val |= STPMIC1_LDO3_MODE;
+               }
+
+               status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
+               if (status != 0) {
+                       return status;
+               }
+
+               status = stpmic1_regulator_voltage_set("buck2", 1200);
+               if (status != 0) {
+                       return status;
+               }
+
+               status = stpmic1_regulator_enable("ldo3");
+               if (status != 0) {
+                       return status;
+               }
+
+               mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+               status = stpmic1_regulator_enable("buck2");
+               if (status != 0) {
+                       return status;
+               }
+
+               mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+               status = stpmic1_regulator_enable("vref_ddr");
+               if (status != 0) {
+                       return status;
+               }
+
+               mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+               break;
+
+       default:
+               break;
+       };
+
+       return 0;
+}
diff --git a/drivers/st/pmic/stpmic1.c b/drivers/st/pmic/stpmic1.c
new file mode 100644 (file)
index 0000000..465996d
--- /dev/null
@@ -0,0 +1,762 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/st/stpmic1.h>
+#include <plat/common/platform.h>
+
+struct regul_struct {
+       const char *dt_node_name;
+       const uint16_t *voltage_table;
+       uint8_t voltage_table_size;
+       uint8_t control_reg;
+       uint8_t low_power_reg;
+       uint8_t pull_down_reg;
+       uint8_t pull_down;
+       uint8_t mask_reset_reg;
+       uint8_t mask_reset;
+};
+
+static struct i2c_handle_s *pmic_i2c_handle;
+static uint16_t pmic_i2c_addr;
+
+/* Voltage tables in mV */
+static const uint16_t buck1_voltage_table[] = {
+       725,
+       725,
+       725,
+       725,
+       725,
+       725,
+       750,
+       775,
+       800,
+       825,
+       850,
+       875,
+       900,
+       925,
+       950,
+       975,
+       1000,
+       1025,
+       1050,
+       1075,
+       1100,
+       1125,
+       1150,
+       1175,
+       1200,
+       1225,
+       1250,
+       1275,
+       1300,
+       1325,
+       1350,
+       1375,
+       1400,
+       1425,
+       1450,
+       1475,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+       1500,
+};
+
+static const uint16_t buck2_voltage_table[] = {
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1050,
+       1050,
+       1100,
+       1100,
+       1150,
+       1150,
+       1200,
+       1200,
+       1250,
+       1250,
+       1300,
+       1300,
+       1350,
+       1350,
+       1400,
+       1400,
+       1450,
+       1450,
+       1500,
+};
+
+static const uint16_t buck3_voltage_table[] = {
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1000,
+       1100,
+       1100,
+       1100,
+       1100,
+       1200,
+       1200,
+       1200,
+       1200,
+       1300,
+       1300,
+       1300,
+       1300,
+       1400,
+       1400,
+       1400,
+       1400,
+       1500,
+       1600,
+       1700,
+       1800,
+       1900,
+       2000,
+       2100,
+       2200,
+       2300,
+       2400,
+       2500,
+       2600,
+       2700,
+       2800,
+       2900,
+       3000,
+       3100,
+       3200,
+       3300,
+       3400,
+};
+
+static const uint16_t buck4_voltage_table[] = {
+       600,
+       625,
+       650,
+       675,
+       700,
+       725,
+       750,
+       775,
+       800,
+       825,
+       850,
+       875,
+       900,
+       925,
+       950,
+       975,
+       1000,
+       1025,
+       1050,
+       1075,
+       1100,
+       1125,
+       1150,
+       1175,
+       1200,
+       1225,
+       1250,
+       1275,
+       1300,
+       1300,
+       1350,
+       1350,
+       1400,
+       1400,
+       1450,
+       1450,
+       1500,
+       1600,
+       1700,
+       1800,
+       1900,
+       2000,
+       2100,
+       2200,
+       2300,
+       2400,
+       2500,
+       2600,
+       2700,
+       2800,
+       2900,
+       3000,
+       3100,
+       3200,
+       3300,
+       3400,
+       3500,
+       3600,
+       3700,
+       3800,
+       3900,
+};
+
+static const uint16_t ldo1_voltage_table[] = {
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1800,
+       1900,
+       2000,
+       2100,
+       2200,
+       2300,
+       2400,
+       2500,
+       2600,
+       2700,
+       2800,
+       2900,
+       3000,
+       3100,
+       3200,
+       3300,
+};
+
+static const uint16_t ldo2_voltage_table[] = {
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1800,
+       1900,
+       2000,
+       2100,
+       2200,
+       2300,
+       2400,
+       2500,
+       2600,
+       2700,
+       2800,
+       2900,
+       3000,
+       3100,
+       3200,
+       3300,
+};
+
+static const uint16_t ldo3_voltage_table[] = {
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1800,
+       1900,
+       2000,
+       2100,
+       2200,
+       2300,
+       2400,
+       2500,
+       2600,
+       2700,
+       2800,
+       2900,
+       3000,
+       3100,
+       3200,
+       3300,
+       3300,
+       3300,
+       3300,
+       3300,
+       3300,
+       3300,
+       500,
+       0xFFFF, /* VREFDDR */
+};
+
+static const uint16_t ldo5_voltage_table[] = {
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1700,
+       1800,
+       1900,
+       2000,
+       2100,
+       2200,
+       2300,
+       2400,
+       2500,
+       2600,
+       2700,
+       2800,
+       2900,
+       3000,
+       3100,
+       3200,
+       3300,
+       3400,
+       3500,
+       3600,
+       3700,
+       3800,
+       3900,
+};
+
+static const uint16_t ldo6_voltage_table[] = {
+       900,
+       1000,
+       1100,
+       1200,
+       1300,
+       1400,
+       1500,
+       1600,
+       1700,
+       1800,
+       1900,
+       2000,
+       2100,
+       2200,
+       2300,
+       2400,
+       2500,
+       2600,
+       2700,
+       2800,
+       2900,
+       3000,
+       3100,
+       3200,
+       3300,
+};
+
+static const uint16_t ldo4_voltage_table[] = {
+       3300,
+};
+
+static const uint16_t vref_ddr_voltage_table[] = {
+       3300,
+};
+
+/* Table of Regulators in PMIC SoC */
+static const struct regul_struct regulators_table[] = {
+       {
+               .dt_node_name   = "buck1",
+               .voltage_table  = buck1_voltage_table,
+               .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
+               .control_reg    = BUCK1_CONTROL_REG,
+               .low_power_reg  = BUCK1_PWRCTRL_REG,
+               .pull_down_reg  = BUCK_PULL_DOWN_REG,
+               .pull_down      = BUCK1_PULL_DOWN_SHIFT,
+               .mask_reset_reg = MASK_RESET_BUCK_REG,
+               .mask_reset     = BUCK1_MASK_RESET,
+       },
+       {
+               .dt_node_name   = "buck2",
+               .voltage_table  = buck2_voltage_table,
+               .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
+               .control_reg    = BUCK2_CONTROL_REG,
+               .low_power_reg  = BUCK2_PWRCTRL_REG,
+               .pull_down_reg  = BUCK_PULL_DOWN_REG,
+               .pull_down      = BUCK2_PULL_DOWN_SHIFT,
+               .mask_reset_reg = MASK_RESET_BUCK_REG,
+               .mask_reset     = BUCK2_MASK_RESET,
+       },
+       {
+               .dt_node_name   = "buck3",
+               .voltage_table  = buck3_voltage_table,
+               .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
+               .control_reg    = BUCK3_CONTROL_REG,
+               .low_power_reg  = BUCK3_PWRCTRL_REG,
+               .pull_down_reg  = BUCK_PULL_DOWN_REG,
+               .pull_down      = BUCK3_PULL_DOWN_SHIFT,
+               .mask_reset_reg = MASK_RESET_BUCK_REG,
+               .mask_reset     = BUCK3_MASK_RESET,
+       },
+       {
+               .dt_node_name   = "buck4",
+               .voltage_table  = buck4_voltage_table,
+               .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
+               .control_reg    = BUCK4_CONTROL_REG,
+               .low_power_reg  = BUCK4_PWRCTRL_REG,
+               .pull_down_reg  = BUCK_PULL_DOWN_REG,
+               .pull_down      = BUCK4_PULL_DOWN_SHIFT,
+               .mask_reset_reg = MASK_RESET_BUCK_REG,
+               .mask_reset     = BUCK4_MASK_RESET,
+       },
+       {
+               .dt_node_name   = "ldo1",
+               .voltage_table  = ldo1_voltage_table,
+               .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
+               .control_reg    = LDO1_CONTROL_REG,
+               .low_power_reg  = LDO1_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = LDO1_MASK_RESET,
+       },
+       {
+               .dt_node_name   = "ldo2",
+               .voltage_table  = ldo2_voltage_table,
+               .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
+               .control_reg    = LDO2_CONTROL_REG,
+               .low_power_reg  = LDO2_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = LDO2_MASK_RESET,
+       },
+       {
+               .dt_node_name   = "ldo3",
+               .voltage_table  = ldo3_voltage_table,
+               .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
+               .control_reg    = LDO3_CONTROL_REG,
+               .low_power_reg  = LDO3_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = LDO3_MASK_RESET,
+       },
+       {
+               .dt_node_name   = "ldo4",
+               .voltage_table  = ldo4_voltage_table,
+               .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
+               .control_reg    = LDO4_CONTROL_REG,
+               .low_power_reg  = LDO4_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = LDO4_MASK_RESET,
+       },
+       {
+               .dt_node_name   = "ldo5",
+               .voltage_table  = ldo5_voltage_table,
+               .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
+               .control_reg    = LDO5_CONTROL_REG,
+               .low_power_reg  = LDO5_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = LDO5_MASK_RESET,
+       },
+       {
+               .dt_node_name   = "ldo6",
+               .voltage_table  = ldo6_voltage_table,
+               .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
+               .control_reg    = LDO6_CONTROL_REG,
+               .low_power_reg  = LDO6_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = LDO6_MASK_RESET,
+       },
+       {
+               .dt_node_name   = "vref_ddr",
+               .voltage_table  = vref_ddr_voltage_table,
+               .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
+               .control_reg    = VREF_DDR_CONTROL_REG,
+               .low_power_reg  = VREF_DDR_PWRCTRL_REG,
+               .mask_reset_reg = MASK_RESET_LDO_REG,
+               .mask_reset     = VREF_DDR_MASK_RESET,
+       },
+};
+
+#define MAX_REGUL      ARRAY_SIZE(regulators_table)
+
+static const struct regul_struct *get_regulator_data(const char *name)
+{
+       uint8_t i;
+
+       for (i = 0 ; i < MAX_REGUL ; i++) {
+               if (strncmp(name, regulators_table[i].dt_node_name,
+                           strlen(regulators_table[i].dt_node_name)) == 0) {
+                       return &regulators_table[i];
+               }
+       }
+
+       /* Regulator not found */
+       panic();
+       return NULL;
+}
+
+static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
+{
+       const struct regul_struct *regul = get_regulator_data(name);
+       uint8_t i;
+
+       for (i = 0 ; i < regul->voltage_table_size ; i++) {
+               if (regul->voltage_table[i] == millivolts) {
+                       return i;
+               }
+       }
+
+       /* Voltage not found */
+       panic();
+
+       return 0;
+}
+
+int stpmic1_powerctrl_on(void)
+{
+       return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
+                                      PWRCTRL_PIN_VALID);
+}
+
+int stpmic1_switch_off(void)
+{
+       return stpmic1_register_update(MAIN_CONTROL_REG, 1,
+                                      SOFTWARE_SWITCH_OFF_ENABLED);
+}
+
+int stpmic1_regulator_enable(const char *name)
+{
+       const struct regul_struct *regul = get_regulator_data(name);
+
+       return stpmic1_register_update(regul->control_reg, BIT(0), BIT(0));
+}
+
+int stpmic1_regulator_disable(const char *name)
+{
+       const struct regul_struct *regul = get_regulator_data(name);
+
+       return stpmic1_register_update(regul->control_reg, 0, BIT(0));
+}
+
+uint8_t stpmic1_is_regulator_enabled(const char *name)
+{
+       uint8_t val;
+       const struct regul_struct *regul = get_regulator_data(name);
+
+       if (stpmic1_register_read(regul->control_reg, &val) != 0) {
+               panic();
+       }
+
+       return (val & 0x1U);
+}
+
+int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
+{
+       uint8_t voltage_index = voltage_to_index(name, millivolts);
+       const struct regul_struct *regul = get_regulator_data(name);
+       uint8_t mask;
+
+       /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
+       if (strncmp(name, "buck", 4) == 0) {
+               mask = BUCK_VOLTAGE_MASK;
+       } else if ((strncmp(name, "ldo", 3) == 0) &&
+                  (strncmp(name, "ldo4", 4) != 0)) {
+               mask = LDO_VOLTAGE_MASK;
+       } else {
+               return 0;
+       }
+
+       return stpmic1_register_update(regul->control_reg,
+                                      voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
+                                      mask);
+}
+
+int stpmic1_regulator_pull_down_set(const char *name)
+{
+       const struct regul_struct *regul = get_regulator_data(name);
+
+       if (regul->pull_down_reg != 0) {
+               return stpmic1_register_update(regul->pull_down_reg,
+                                              BIT(regul->pull_down),
+                                              LDO_BUCK_PULL_DOWN_MASK <<
+                                              regul->pull_down);
+       }
+
+       return 0;
+}
+
+int stpmic1_regulator_mask_reset_set(const char *name)
+{
+       const struct regul_struct *regul = get_regulator_data(name);
+
+       return stpmic1_register_update(regul->mask_reset_reg,
+                                      BIT(regul->mask_reset),
+                                      LDO_BUCK_RESET_MASK <<
+                                      regul->mask_reset);
+}
+
+int stpmic1_regulator_voltage_get(const char *name)
+{
+       const struct regul_struct *regul = get_regulator_data(name);
+       uint8_t value;
+       uint8_t mask;
+
+       /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
+       if (strncmp(name, "buck", 4) == 0) {
+               mask = BUCK_VOLTAGE_MASK;
+       } else if ((strncmp(name, "ldo", 3) == 0) &&
+                  (strncmp(name, "ldo4", 4) != 0)) {
+               mask = LDO_VOLTAGE_MASK;
+       } else {
+               return 0;
+       }
+
+       if (stpmic1_register_read(regul->control_reg, &value))
+               return -1;
+
+       value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
+
+       if (value > regul->voltage_table_size)
+               return -1;
+
+       return (int)regul->voltage_table[value];
+}
+
+int stpmic1_register_read(uint8_t register_id,  uint8_t *value)
+{
+       return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
+                                 (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT,
+                                 value, 1, 100000);
+}
+
+int stpmic1_register_write(uint8_t register_id, uint8_t value)
+{
+       int status;
+
+       status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
+                                    (uint16_t)register_id,
+                                    I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
+
+#if ENABLE_ASSERTIONS
+       if (status != 0) {
+               return status;
+       }
+
+       if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
+               uint8_t readval;
+
+               status = stpmic1_register_read(register_id, &readval);
+               if (status != 0) {
+                       return status;
+               }
+
+               if (readval != value) {
+                       return -1;
+               }
+       }
+#endif
+
+       return status;
+}
+
+int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
+{
+       int status;
+       uint8_t val;
+
+       status = stpmic1_register_read(register_id, &val);
+       if (status != 0) {
+               return status;
+       }
+
+       val = (val & ~mask) | (value & mask);
+
+       return stpmic1_register_write(register_id, val);
+}
+
+void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
+{
+       pmic_i2c_handle = i2c_handle;
+       pmic_i2c_addr = i2c_addr;
+}
+
+void stpmic1_dump_regulators(void)
+{
+       uint32_t i;
+
+       for (i = 0U; i < MAX_REGUL; i++) {
+               const char *name __unused = regulators_table[i].dt_node_name;
+
+               VERBOSE("PMIC regul %s: %sable, %dmV",
+                       name,
+                       stpmic1_is_regulator_enabled(name) ? "en" : "dis",
+                       stpmic1_regulator_voltage_get(name));
+       }
+}
+
+int stpmic1_get_version(unsigned long *version)
+{
+       int rc;
+       uint8_t read_val;
+
+       rc = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
+       if (rc) {
+               return -1;
+       }
+
+       *version = (unsigned long)read_val;
+
+       return 0;
+}
diff --git a/drivers/st/pmic/stpmu1.c b/drivers/st/pmic/stpmu1.c
deleted file mode 100644 (file)
index 9c36bf6..0000000
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <string.h>
-
-#include <common/debug.h>
-#include <drivers/st/stpmu1.h>
-#include <plat/common/platform.h>
-
-struct regul_struct {
-       const char *dt_node_name;
-       const uint16_t *voltage_table;
-       uint8_t voltage_table_size;
-       uint8_t control_reg;
-       uint8_t low_power_reg;
-};
-
-static struct i2c_handle_s *stpmu_i2c_handle;
-static uint16_t stpmu_i2c_addr;
-
-/* Voltage tables in mV */
-static const uint16_t buck1_voltage_table[] = {
-       600,
-       625,
-       650,
-       675,
-       700,
-       725,
-       750,
-       775,
-       800,
-       825,
-       850,
-       875,
-       900,
-       925,
-       950,
-       975,
-       1000,
-       1025,
-       1050,
-       1075,
-       1100,
-       1125,
-       1150,
-       1175,
-       1200,
-       1225,
-       1250,
-       1275,
-       1300,
-       1325,
-       1350,
-       1350,
-};
-
-static const uint16_t buck2_voltage_table[] = {
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1050,
-       1050,
-       1100,
-       1100,
-       1150,
-       1150,
-       1200,
-       1200,
-       1250,
-       1250,
-       1300,
-       1300,
-       1350,
-       1350,
-       1400,
-       1400,
-       1450,
-       1450,
-       1500,
-};
-
-static const uint16_t buck3_voltage_table[] = {
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1000,
-       1100,
-       1100,
-       1100,
-       1100,
-       1200,
-       1200,
-       1200,
-       1200,
-       1300,
-       1300,
-       1300,
-       1300,
-       1400,
-       1400,
-       1400,
-       1400,
-       1500,
-       1600,
-       1700,
-       1800,
-       1900,
-       2000,
-       2100,
-       2200,
-       2300,
-       2400,
-       2500,
-       2600,
-       2700,
-       2800,
-       2900,
-       3000,
-       3100,
-       3200,
-       3300,
-       3400,
-};
-
-static const uint16_t buck4_voltage_table[] = {
-       600,
-       625,
-       650,
-       675,
-       700,
-       725,
-       750,
-       775,
-       800,
-       825,
-       850,
-       875,
-       900,
-       925,
-       950,
-       975,
-       1000,
-       1025,
-       1050,
-       1075,
-       1100,
-       1125,
-       1150,
-       1175,
-       1200,
-       1225,
-       1250,
-       1275,
-       1300,
-       1300,
-       1350,
-       1350,
-       1400,
-       1400,
-       1450,
-       1450,
-       1500,
-       1600,
-       1700,
-       1800,
-       1900,
-       2000,
-       2100,
-       2200,
-       2300,
-       2400,
-       2500,
-       2600,
-       2700,
-       2800,
-       2900,
-       3000,
-       3100,
-       3200,
-       3300,
-       3400,
-       3500,
-       3600,
-       3700,
-       3800,
-       3900,
-};
-
-static const uint16_t ldo1_voltage_table[] = {
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1800,
-       1900,
-       2000,
-       2100,
-       2200,
-       2300,
-       2400,
-       2500,
-       2600,
-       2700,
-       2800,
-       2900,
-       3000,
-       3100,
-       3200,
-       3300,
-};
-
-static const uint16_t ldo2_voltage_table[] = {
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1800,
-       1900,
-       2000,
-       2100,
-       2200,
-       2300,
-       2400,
-       2500,
-       2600,
-       2700,
-       2800,
-       2900,
-       3000,
-       3100,
-       3200,
-       3300,
-};
-
-static const uint16_t ldo3_voltage_table[] = {
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1800,
-       1900,
-       2000,
-       2100,
-       2200,
-       2300,
-       2400,
-       2500,
-       2600,
-       2700,
-       2800,
-       2900,
-       3000,
-       3100,
-       3200,
-       3300,
-       3300,
-       3300,
-       3300,
-       3300,
-       3300,
-       3300,
-       0xFFFF, /* VREFDDR */
-};
-
-static const uint16_t ldo5_voltage_table[] = {
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1700,
-       1800,
-       1900,
-       2000,
-       2100,
-       2200,
-       2300,
-       2400,
-       2500,
-       2600,
-       2700,
-       2800,
-       2900,
-       3000,
-       3100,
-       3200,
-       3300,
-       3400,
-       3500,
-       3600,
-       3700,
-       3800,
-       3900,
-};
-
-static const uint16_t ldo6_voltage_table[] = {
-       900,
-       1000,
-       1100,
-       1200,
-       1300,
-       1400,
-       1500,
-       1600,
-       1700,
-       1800,
-       1900,
-       2000,
-       2100,
-       2200,
-       2300,
-       2400,
-       2500,
-       2600,
-       2700,
-       2800,
-       2900,
-       3000,
-       3100,
-       3200,
-       3300,
-};
-
-static const uint16_t ldo4_voltage_table[] = {
-       3300,
-};
-
-static const uint16_t vref_ddr_voltage_table[] = {
-       3300,
-};
-
-/* Table of Regulators in PMIC SoC */
-static const struct regul_struct regulators_table[] = {
-       {
-               .dt_node_name   = "buck1",
-               .voltage_table  = buck1_voltage_table,
-               .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
-               .control_reg    = BUCK1_CONTROL_REG,
-               .low_power_reg  = BUCK1_PWRCTRL_REG,
-       },
-       {
-               .dt_node_name   = "buck2",
-               .voltage_table  = buck2_voltage_table,
-               .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
-               .control_reg    = BUCK2_CONTROL_REG,
-               .low_power_reg  = BUCK2_PWRCTRL_REG,
-       },
-       {
-               .dt_node_name   = "buck3",
-               .voltage_table  = buck3_voltage_table,
-               .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
-               .control_reg    = BUCK3_CONTROL_REG,
-               .low_power_reg  = BUCK3_PWRCTRL_REG,
-       },
-       {
-               .dt_node_name   = "buck4",
-               .voltage_table  = buck4_voltage_table,
-               .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
-               .control_reg    = BUCK4_CONTROL_REG,
-               .low_power_reg  = BUCK4_PWRCTRL_REG,
-       },
-       {
-               .dt_node_name   = "ldo1",
-               .voltage_table  = ldo1_voltage_table,
-               .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
-               .control_reg    = LDO1_CONTROL_REG,
-               .low_power_reg  = LDO1_PWRCTRL_REG,
-       },
-       {
-               .dt_node_name   = "ldo2",
-               .voltage_table  = ldo2_voltage_table,
-               .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
-               .control_reg    = LDO2_CONTROL_REG,
-               .low_power_reg  = LDO2_PWRCTRL_REG,
-       },
-       {
-               .dt_node_name   = "ldo3",
-               .voltage_table  = ldo3_voltage_table,
-               .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
-               .control_reg    = LDO3_CONTROL_REG,
-               .low_power_reg  = LDO3_PWRCTRL_REG,
-       },
-       {
-               .dt_node_name   = "ldo4",
-               .voltage_table  = ldo4_voltage_table,
-               .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
-               .control_reg    = LDO4_CONTROL_REG,
-               .low_power_reg  = LDO4_PWRCTRL_REG,
-       },
-       {
-               .dt_node_name   = "ldo5",
-               .voltage_table  = ldo5_voltage_table,
-               .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
-               .control_reg    = LDO5_CONTROL_REG,
-               .low_power_reg  = LDO5_PWRCTRL_REG,
-       },
-       {
-               .dt_node_name   = "ldo6",
-               .voltage_table  = ldo6_voltage_table,
-               .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
-               .control_reg    = LDO6_CONTROL_REG,
-               .low_power_reg  = LDO6_PWRCTRL_REG,
-       },
-       {
-               .dt_node_name   = "vref_ddr",
-               .voltage_table  = vref_ddr_voltage_table,
-               .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
-               .control_reg    = VREF_DDR_CONTROL_REG,
-               .low_power_reg  = VREF_DDR_PWRCTRL_REG,
-       },
-};
-
-#define MAX_REGUL  ARRAY_SIZE(regulators_table)
-
-static const struct regul_struct *stpmu1_get_regulator_data(const char *name)
-{
-       uint8_t i;
-
-       for (i = 0 ; i < MAX_REGUL ; i++) {
-               if (strncmp(name, regulators_table[i].dt_node_name,
-                           strlen(regulators_table[i].dt_node_name)) == 0) {
-                       return &regulators_table[i];
-               }
-       }
-
-       /* Regulator not found */
-       panic();
-       return NULL;
-}
-
-static uint8_t stpmu1_voltage_find_index(const char *name,
-                                        uint16_t millivolts)
-{
-       const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-       uint8_t i;
-
-       for (i = 0 ; i < regul->voltage_table_size ; i++) {
-               if (regul->voltage_table[i] == millivolts) {
-                       return i;
-               }
-       }
-
-       /* Voltage not found */
-       panic();
-
-       return 0;
-}
-
-int stpmu1_switch_off(void)
-{
-       return stpmu1_register_update(MAIN_CONTROL_REG, 1,
-                                     SOFTWARE_SWITCH_OFF_ENABLED);
-}
-
-int stpmu1_regulator_enable(const char *name)
-{
-       const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-
-       return stpmu1_register_update(regul->control_reg, BIT(0), BIT(0));
-}
-
-int stpmu1_regulator_disable(const char *name)
-{
-       const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-
-       return stpmu1_register_update(regul->control_reg, 0, BIT(0));
-}
-
-uint8_t stpmu1_is_regulator_enabled(const char *name)
-{
-       uint8_t val;
-       const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-
-       if (stpmu1_register_read(regul->control_reg, &val) != 0) {
-               panic();
-       }
-
-       return (val & 0x1U);
-}
-
-int stpmu1_regulator_voltage_set(const char *name, uint16_t millivolts)
-{
-       uint8_t voltage_index = stpmu1_voltage_find_index(name, millivolts);
-       const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-
-       return stpmu1_register_update(regul->control_reg, voltage_index << 2,
-                                     0xFC);
-}
-
-int stpmu1_register_read(uint8_t register_id,  uint8_t *value)
-{
-       return stm32_i2c_mem_read(stpmu_i2c_handle, stpmu_i2c_addr,
-                                   (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT,
-                                   value, 1, 100000);
-}
-
-int stpmu1_register_write(uint8_t register_id, uint8_t value)
-{
-       int status;
-
-       status = stm32_i2c_mem_write(stpmu_i2c_handle, stpmu_i2c_addr,
-                                    (uint16_t)register_id,
-                                    I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
-
-       if (status != 0) {
-               return status;
-       }
-
-       if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
-               uint8_t readval;
-
-               status = stpmu1_register_read(register_id, &readval);
-               if (status != 0) {
-                       return status;
-               }
-
-               if (readval != value) {
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-int stpmu1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
-{
-       int status;
-       uint8_t val;
-
-       status = stpmu1_register_read(register_id, &val);
-       if (status != 0) {
-               return status;
-       }
-
-       /* Clear bits to update */
-       val &= ~mask;
-
-       /* Update appropriate bits*/
-       val |= (value & mask);
-
-       /* Send new value on I2C Bus */
-       return stpmu1_register_write(register_id, val);
-}
-
-void stpmu1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
-{
-       stpmu_i2c_handle = i2c_handle;
-       stpmu_i2c_addr = i2c_addr;
-}
index 62997bc0d82421e9cd2d8acdaaf6b7b61af468e6..c289c88fd8b464e091be89bd4d5dbe32a6e72a15 100644 (file)
@@ -1137,13 +1137,13 @@ uint32_t recovery_from_backup_mode(void)
 
    /*  ddr backupmode end */
    if (ddrBackup) {
-      NOTICE("[WARM_BOOT]");
+      NOTICE("BL2: [WARM_BOOT]\n");
    } else {
-      NOTICE("[COLD_BOOT]");
+      NOTICE("BL2: [COLD_BOOT]\n");
    } /*  ddrBackup */
    err = rcar_dram_update_boot_status(ddrBackup);
    if (err) {
-      NOTICE("[BOOT_STATUS_UPDATE_ERROR]");
+      NOTICE("BL2: [BOOT_STATUS_UPDATE_ERROR]\n");
       return INITDRAM_ERR_I;
    } /*  err */
 
@@ -1672,9 +1672,9 @@ int32_t rcar_dram_init(void)
     md = *((volatile uint32_t*)RST_MODEMR);
     ddr = (md & 0x00080000) >> 19;
     if (ddr == 0x0) {
-       NOTICE("BL2: DDR1584(%s)", RCAR_E3_DDR_VERSION);
+       NOTICE("BL2: DDR1584(%s)\n", RCAR_E3_DDR_VERSION);
     } else if(ddr == 0x1){
-       NOTICE("BL2: DDR1856(%s)", RCAR_E3_DDR_VERSION);
+       NOTICE("BL2: DDR1856(%s)\n", RCAR_E3_DDR_VERSION);
     } /*  ddr */
 
     rcar_dram_get_boot_status(&ddrBackup);
@@ -1691,8 +1691,6 @@ int32_t rcar_dram_init(void)
         failcount = 1;
     } /*  dataL */
 
-    NOTICE("..%d\n", failcount); /*  rev.0.05 */
-
     if (failcount == 0) {
        return INITDRAM_OK;
     } else {
index 78f0f114603b775a8251c65537c510151ffe7763..f4bfdde1c4fe6ae35198cc4263b9ce059e9d5335 100644 (file)
@@ -2826,7 +2826,7 @@ static uint32_t pll3_freq(uint32_t on)
        set_freqchgack(0);
 
        if (timeout) {
-               FATAL_MSG("Time out[2]");
+               FATAL_MSG("BL2: Time out[2]\n");
                return (1);
        }
        return (0);
@@ -3012,13 +3012,13 @@ static uint32_t init_ddr(void)
        ***********************************************************************/
 #ifdef DDR_BACKUPMODE
        if (ddrBackup) {
-               NOTICE("[WARM_BOOT]");
+               NOTICE("BL2: [WARM_BOOT]\n");
        } else {
-               NOTICE("[COLD_BOOT]");
+               NOTICE("BL2: [COLD_BOOT]\n");
        }
        err = rcar_dram_update_boot_status(ddrBackup);
        if (err) {
-               NOTICE("[BOOT_STATUS_UPDATE_ERROR]");
+               NOTICE("BL2: [BOOT_STATUS_UPDATE_ERROR]\n");
                return INITDRAM_ERR_I;
        }
 #endif
index c7c8fc22d2491d6120bff5e4a496e169a1cceeac..6bed981db0b6f647dc1c1b12d0636343886c428e 100644 (file)
@@ -183,7 +183,7 @@ static int dwufs_phy_set_pwr_mode(ufs_params_t *params)
        return 0;
 }
 
-const ufs_ops_t dw_ufs_ops = {
+static const ufs_ops_t dw_ufs_ops = {
        .phy_init               = dwufs_phy_init,
        .phy_set_pwr_mode       = dwufs_phy_set_pwr_mode,
 };
index 2351c9b04e90dbe407e03ab933659b4d22051e7c..b2c1046123f103951eb1d2e92b24053e38907db1 100644 (file)
@@ -591,7 +591,7 @@ void ufs_write_desc(int idn, int index, uintptr_t buf, size_t size)
        ufs_query(QUERY_WRITE_DESC, idn, index, 0, buf, size);
 }
 
-void ufs_read_capacity(int lun, unsigned int *num, unsigned int *size)
+static void ufs_read_capacity(int lun, unsigned int *num, unsigned int *size)
 {
        utp_utrd_t utrd;
        resp_upiu_t *resp;
index be4e2c3721734b40944b2976ca073c4c546e7e0f..1a5c51c978e329c5c18c4996caca5ee3b8c0ffed 100644 (file)
@@ -5,7 +5,7 @@
 
 / {
        soc {
-               ddr: ddr@0x5A003000{
+               ddr: ddr@5A003000{
 
                        compatible = "st,stm32mp1-ddr";
 
index 58a4cdc8c25ec781ba0d15f724bee2b044e097d8..82e710468d5c2b592f6637b34fba4f082c68da25 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
  */
 
-/* STM32MP157C ED1 and ED2 BOARD configuration
+/* STM32MP157C ED1 BOARD configuration
  * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology.
  * Reference used NT5CC256M16DP-DI from NANYA
  *
  * timing mode optimized
  * Scheduling/QoS options : type = 2
  * address mapping : RBC
+ * Tc > + 85C : N
  */
 
-#define DDR_MEM_NAME "DDR3-1066 bin G 2x4Gb 533MHz v1.39"
-#define DDR_MEM_SPEED 533
+#define DDR_MEM_NAME "DDR3-1066/888 bin G 2x4Gb 533MHz v1.41"
+#define DDR_MEM_SPEED 533000
 #define DDR_MEM_SIZE 0x40000000
 
 #define DDR_MSTR 0x00040401
@@ -62,7 +63,7 @@
 #define DDR_ADDRMAP11 0x00000000
 #define DDR_ODTCFG 0x06000600
 #define DDR_ODTMAP 0x00000001
-#define DDR_SCHED 0x00001201
+#define DDR_SCHED 0x00000C01
 #define DDR_SCHED1 0x00000000
 #define DDR_PERFHPR1 0x01000001
 #define DDR_PERFLPR1 0x08000200
 #define DDR_PCCFG 0x00000010
 #define DDR_PCFGR_0 0x00010000
 #define DDR_PCFGW_0 0x00000000
-#define DDR_PCFGQOS0_0 0x02100B03
+#define DDR_PCFGQOS0_0 0x02100C03
 #define DDR_PCFGQOS1_0 0x00800100
-#define DDR_PCFGWQOS0_0 0x01100B03
+#define DDR_PCFGWQOS0_0 0x01100C03
 #define DDR_PCFGWQOS1_0 0x01000200
 #define DDR_PCFGR_1 0x00010000
 #define DDR_PCFGW_1 0x00000000
-#define DDR_PCFGQOS0_1 0x02100B03
-#define DDR_PCFGQOS1_1 0x00800000
-#define DDR_PCFGWQOS0_1 0x01100B03
+#define DDR_PCFGQOS0_1 0x02100C03
+#define DDR_PCFGQOS1_1 0x00800040
+#define DDR_PCFGWQOS0_1 0x01100C03
 #define DDR_PCFGWQOS1_1 0x01000200
 #define DDR_PGCR 0x01442E02
 #define DDR_PTR0 0x0022AA5B
index 21bd34e0bd72e02aa0e238a0593f64b089a384e7..9dcd7b5e1788043382b1f1c4860a30efb2f5391d 100644 (file)
@@ -3,13 +3,14 @@
  * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
-
 #include <dt-bindings/pinctrl/stm32-pinfunc.h>
+
 / {
        soc {
-               pinctrl: pin-controller {
+               pinctrl: pin-controller@50002000 {
                        #address-cells = <1>;
                        #size-cells = <1>;
+                       compatible = "st,stm32mp157-pinctrl";
                        ranges = <0 0x50002000 0xa400>;
                        pins-are-numbered;
 
                                status = "disabled";
                        };
 
-                       uart4_pins_a: uart4@0 {
+                       qspi_bk1_pins_a: qspi-bk1-0 {
                                pins1 {
-                                       pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
+                                       pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
+                                                <STM32_PINMUX('F', 9, AF10)>, /* QSPI_BK1_IO1 */
+                                                <STM32_PINMUX('F', 7, AF9)>, /* QSPI_BK1_IO2 */
+                                                <STM32_PINMUX('F', 6, AF9)>; /* QSPI_BK1_IO3 */
                                        bias-disable;
                                        drive-push-pull;
-                                       slew-rate = <0>;
+                                       slew-rate = <1>;
                                };
                                pins2 {
-                                       pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
-                                       bias-disable;
+                                       pinmux = <STM32_PINMUX('B', 6, AF10)>; /* QSPI_BK1_NCS */
+                                       bias-pull-up;
+                                       drive-push-pull;
+                                       slew-rate = <1>;
                                };
                        };
 
-                       usart3_pins_a: usart3@0 {
+                       qspi_bk2_pins_a: qspi-bk2-0 {
                                pins1 {
-                                       pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
-                                                <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
+                                       pinmux = <STM32_PINMUX('H', 2, AF9)>, /* QSPI_BK2_IO0 */
+                                                <STM32_PINMUX('H', 3, AF9)>, /* QSPI_BK2_IO1 */
+                                                <STM32_PINMUX('G', 10, AF11)>, /* QSPI_BK2_IO2 */
+                                                <STM32_PINMUX('G', 7, AF11)>; /* QSPI_BK2_IO3 */
                                        bias-disable;
                                        drive-push-pull;
-                                       slew-rate = <0>;
+                                       slew-rate = <1>;
                                };
                                pins2 {
-                                       pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
-                                                <STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */
-                                       bias-disable;
+                                       pinmux = <STM32_PINMUX('C', 0, AF10)>; /* QSPI_BK2_NCS */
+                                       bias-pull-up;
+                                       drive-push-pull;
+                                       slew-rate = <1>;
                                };
                        };
 
-                       sdmmc1_b4_pins_a: sdmmc1-b4@0 {
+                       qspi_clk_pins_a: qspi-clk-0 {
                                pins {
+                                       pinmux = <STM32_PINMUX('F', 10, AF9)>; /* QSPI_CLK */
+                                       bias-disable;
+                                       drive-push-pull;
+                                       slew-rate = <3>;
+                               };
+                       };
+
+                       sdmmc1_b4_pins_a: sdmmc1-b4-0 {
+                               pins1 {
                                        pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
                                                 <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
                                                 <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
                                                 <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
-                                                <STM32_PINMUX('C', 12, AF12)>, /* SDMMC1_CK */
                                                 <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
-                                       slew-rate = <3>;
+                                       slew-rate = <1>;
+                                       drive-push-pull;
+                                       bias-disable;
+                               };
+                               pins2 {
+                                       pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
+                                       slew-rate = <2>;
                                        drive-push-pull;
                                        bias-disable;
                                };
                        };
 
-                       sdmmc1_dir_pins_a: sdmmc1-dir@0 {
+                       sdmmc1_dir_pins_a: sdmmc1-dir-0 {
                                pins1 {
                                        pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
                                                 <STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */
                                                 <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
-                                       slew-rate = <3>;
+                                       slew-rate = <1>;
                                        drive-push-pull;
                                        bias-pull-up;
                                };
                                };
                        };
 
-                       sdmmc2_b4_pins_a: sdmmc2-b4@0 {
-                               pins {
+                       sdmmc1_dir_pins_b: sdmmc1-dir-1 {
+                               pins1 {
+                                       pinmux = <STM32_PINMUX('E', 12, AF8)>, /* SDMMC1_D0DIR */
+                                                <STM32_PINMUX('E', 14, AF11)>, /* SDMMC1_D123DIR */
+                                                <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
+                                       slew-rate = <3>;
+                                       drive-push-pull;
+                                       bias-pull-up;
+                               };
+                               pins2 {
+                                       pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
+                                       bias-pull-up;
+                               };
+                       };
+
+                       sdmmc2_b4_pins_a: sdmmc2-b4-0 {
+                               pins1 {
                                        pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
                                                 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
                                                 <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
                                                 <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
-                                                <STM32_PINMUX('E', 3, AF9)>, /* SDMMC2_CK */
                                                 <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
-                                       slew-rate = <3>;
+                                       slew-rate = <1>;
+                                       drive-push-pull;
+                                       bias-pull-up;
+                               };
+                               pins2 {
+                                       pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
+                                       slew-rate = <2>;
                                        drive-push-pull;
                                        bias-pull-up;
                                };
                        };
 
-                       sdmmc2_d47_pins_a: sdmmc2-d47@0 {
+                       sdmmc2_d47_pins_a: sdmmc2-d47-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
                                                 <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
                                                 <STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */
                                                 <STM32_PINMUX('D', 3, AF9)>; /* SDMMC2_D7 */
-                                       slew-rate = <3>;
+                                       slew-rate = <1>;
                                        drive-push-pull;
                                        bias-pull-up;
                                };
                        };
+
+                       uart4_pins_a: uart4-0 {
+                               pins1 {
+                                       pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
+                                       bias-disable;
+                                       drive-push-pull;
+                                       slew-rate = <0>;
+                               };
+                               pins2 {
+                                       pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
+                                       bias-disable;
+                               };
+                       };
+
+                       usart3_pins_a: usart3-0 {
+                               pins1 {
+                                       pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
+                                                <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
+                                       bias-disable;
+                                       drive-push-pull;
+                                       slew-rate = <0>;
+                               };
+                               pins2 {
+                                       pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
+                                                <STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */
+                                       bias-disable;
+                               };
+                       };
                };
 
-               pinctrl_z: pin-controller-z {
+               pinctrl_z: pin-controller-z@54004000 {
                        #address-cells = <1>;
                        #size-cells = <1>;
+                       compatible = "st,stm32mp157-z-pinctrl";
                        ranges = <0 0x54004000 0x400>;
                        pins-are-numbered;
 
                                status = "disabled";
                        };
 
-                       i2c4_pins_a: i2c4@0 {
+                       i2c4_pins_a: i2c4-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
                                                 <STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */
index e3dabe8b2b5e64dbcf54903e76d25232ad1587a1..a97e8053bac5a520d6201ceca3ed95457a70cb21 100644 (file)
@@ -3,20 +3,26 @@
  * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
-
 /dts-v1/;
 
 #include "stm32mp157c.dtsi"
 #include "stm32mp157caa-pinctrl.dtsi"
 
 / {
-       model = "STMicroelectronics STM32MP157C-ED1 pmic eval daughter";
+       model = "STMicroelectronics STM32MP157C eval daughter";
        compatible = "st,stm32mp157c-ed1", "st,stm32mp157";
 
        chosen {
-               bootargs = "earlyprintk console=ttyS3,115200 root=/dev/ram";
-               stdout-path = "serial3:115200n8";
+               stdout-path = "serial0:115200n8";
        };
+
+       aliases {
+               serial0 = &uart4;
+       };
+};
+
+&clk_hse {
+       st,digbypass;
 };
 
 &i2c4 {
        i2c-scl-falling-time-ns = <20>;
        status = "okay";
 
-       pmic: stpmu1@33 {
-               compatible = "st,stpmu1";
+       pmic: stpmic@33 {
+               compatible = "st,stpmic1";
                reg = <0x33>;
+               interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
                status = "okay";
 
-               st,main_control_register = <0x04>;
-               st,vin_control_register = <0xc0>;
-               st,usb_control_register = <0x30>;
+               st,main-control-register = <0x04>;
+               st,vin-control-register = <0xc0>;
+               st,usb-control-register = <0x30>;
 
                regulators {
-                       compatible = "st,stpmu1-regulators";
+                       compatible = "st,stpmic1-regulators";
+
+                       ldo1-supply = <&v3v3>;
+                       ldo2-supply = <&v3v3>;
+                       ldo3-supply = <&vdd_ddr>;
+                       ldo5-supply = <&v3v3>;
+                       ldo6-supply = <&v3v3>;
+
+                       vddcore: buck1 {
+                               regulator-name = "vddcore";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-initial-mode = <0>;
+                               regulator-over-current-protection;
+                       };
+
+                       vdd_ddr: buck2 {
+                               regulator-name = "vdd_ddr";
+                               regulator-min-microvolt = <1350000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-initial-mode = <0>;
+                               regulator-over-current-protection;
+                       };
+
+                       vdd: buck3 {
+                               regulator-name = "vdd";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                               st,mask-reset;
+                               regulator-initial-mode = <0>;
+                               regulator-over-current-protection;
+                       };
 
                        v3v3: buck4 {
                                regulator-name = "v3v3";
                                regulator-min-microvolt = <3300000>;
                                regulator-max-microvolt = <3300000>;
-                               regulator-boot-on;
+                               regulator-always-on;
                                regulator-over-current-protection;
-                               regulator-initial-mode = <8>;
-
-                               regulator-state-standby {
-                                       regulator-suspend-microvolt = <3300000>;
-                                       regulator-unchanged-in-suspend;
-                                       regulator-mode = <8>;
-                               };
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                               regulator-state-disk {
-                                       regulator-off-in-suspend;
-                               };
+                               regulator-initial-mode = <0>;
+                       };
+
+                       vdda: ldo1 {
+                               regulator-name = "vdda";
+                               regulator-min-microvolt = <2900000>;
+                               regulator-max-microvolt = <2900000>;
+                       };
+
+                       v2v8: ldo2 {
+                               regulator-name = "v2v8";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                       };
+
+                       vtt_ddr: ldo3 {
+                               regulator-name = "vtt_ddr";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-always-on;
+                               regulator-over-current-protection;
+                       };
+
+                       vdd_usb: ldo4 {
+                               regulator-name = "vdd_usb";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
                        };
 
                        vdd_sd: ldo5 {
                                regulator-min-microvolt = <2900000>;
                                regulator-max-microvolt = <2900000>;
                                regulator-boot-on;
+                       };
 
-                               regulator-state-standby {
-                                       regulator-suspend-microvolt = <2900000>;
-                                       regulator-unchanged-in-suspend;
-                               };
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                               regulator-state-disk {
-                                       regulator-off-in-suspend;
-                               };
+                       v1v8: ldo6 {
+                               regulator-name = "v1v8";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                       };
+
+                       vref_ddr: vref_ddr {
+                               regulator-name = "vref_ddr";
+                               regulator-always-on;
+                               regulator-over-current-protection;
                        };
                };
        };
 };
 
 &iwdg2 {
-       instance = <2>;
        timeout-sec = <32>;
        status = "okay";
 };
        status = "okay";
 };
 
+&rtc {
+       status = "okay";
+};
+
 &sdmmc1 {
        pinctrl-names = "default";
        pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
        broken-cd;
-       st,dirpol;
-       st,negedge;
-       st,pin-ckin;
+       st,sig-dir;
+       st,neg-edge;
+       st,use-ckin;
        bus-width = <4>;
+       vmmc-supply = <&vdd_sd>;
        sd-uhs-sdr12;
        sd-uhs-sdr25;
        sd-uhs-sdr50;
        non-removable;
        no-sd;
        no-sdio;
-       st,dirpol;
-       st,negedge;
+       st,neg-edge;
        bus-width = <8>;
+       vmmc-supply = <&v3v3>;
+       vqmmc-supply = <&v3v3>;
+       mmc-ddr-3_3v;
        status = "okay";
 };
 
 &uart4 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart4_pins_a>;
-       resets = <&rcc UART4_R>;
        status = "okay";
 };
 
 
 /* CLOCK init */
 &rcc {
+       secure-status = "disabled";
        st,clksrc = <
                CLK_MPU_PLL1P
                CLK_AXI_PLL2P
                CLK_FMC_ACLK
                CLK_QSPI_ACLK
                CLK_ETH_DISABLED
-               CLK_SDMMC12_PLL3R
+               CLK_SDMMC12_PLL4P
                CLK_DSI_DSIPLL
                CLK_STGEN_HSE
                CLK_USBPHY_HSE
                CLK_SPI45_HSI
                CLK_SPI6_HSI
                CLK_I2C46_HSI
-               CLK_SDMMC3_PLL3R
+               CLK_SDMMC3_PLL4P
                CLK_USBO_USBPHY
                CLK_ADC_CKPER
                CLK_CEC_LSE
                CLK_UART35_HSI
                CLK_UART6_HSI
                CLK_UART78_HSI
-               CLK_SPDIF_PLL3Q
+               CLK_SPDIF_PLL4P
                CLK_FDCAN_PLL4Q
                CLK_SAI1_PLL3Q
                CLK_SAI2_PLL3Q
                CLK_SAI3_PLL3Q
                CLK_SAI4_PLL3Q
-               CLK_RNG1_CSI
-               CLK_RNG2_CSI
+               CLK_RNG1_LSI
+               CLK_RNG2_LSI
                CLK_LPTIM1_PCLK1
                CLK_LPTIM23_PCLK3
-               CLK_LPTIM45_PCLK3
+               CLK_LPTIM45_LSE
        >;
 
        /* VCO = 1300.0 MHz => P = 650 (CPU) */
                frac = < 0x1400 >;
        };
 
-       /* VCO = 786.4 MHz => P = 197, Q = 49, R = 98 */
+       /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
        pll3: st,pll@2 {
-               cfg = < 2 97 3 15 7 PQR(1,1,1) >;
-               frac = < 0x9ba >;
+               cfg = < 1 33 1 16 36 PQR(1,1,1) >;
+               frac = < 0x1a04 >;
        };
 
-       /* VCO = 508.0 MHz => P = 56, Q = 56, R = 56 */
+       /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
        pll4: st,pll@3 {
-               cfg = < 5 126 8 8 8 PQR(1,1,1) >;
+               cfg = < 3 98 5 7 7 PQR(1,1,1) >;
        };
 };
 
index 98a9d350049a2c383d5b1d216385123b2b6d7634..cfde8ed90eeecb8c951cd00c293255795ccec956 100644 (file)
@@ -3,23 +3,65 @@
  * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
-
 /dts-v1/;
+
 #include "stm32mp157c-ed1.dts"
 
 / {
-       model = "STMicroelectronics STM32MP157C-EV1 pmic eval daughter on eval mother";
+       model = "STMicroelectronics STM32MP157C eval daughter on eval mother";
        compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157";
 
        chosen {
-               bootargs = "earlyprintk console=ttyS3,115200 root=/dev/ram";
-               stdout-path = "serial3:115200n8";
+               stdout-path = "serial0:115200n8";
+       };
+
+       aliases {
+               serial1 = &usart3;
+       };
+};
+
+&fmc {
+       status = "okay";
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       nand: nand@0 {
+               reg = <0>;
+               nand-on-flash-bbt;
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+};
+
+&qspi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>;
+       reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "okay";
+
+       flash0: mx66l51235l@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-rx-bus-width = <4>;
+               spi-max-frequency = <108000000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+
+       flash1: mx66l51235l@1 {
+               compatible = "jedec,spi-nor";
+               reg = <1>;
+               spi-rx-bus-width = <4>;
+               spi-max-frequency = <108000000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
        };
 };
 
 &usart3 {
        pinctrl-names = "default";
        pinctrl-0 = <&usart3_pins_a>;
-       resets = <&rcc USART3_R>;
        status = "disabled";
 };
index 8b13c0e38066d4bbb23939b46e55b27493d19393..0ec7ecb783ef7fa09bd797d182a9ee75d74fdce7 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
-
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/stm32mp1-clks.h>
 #include <dt-bindings/reset/stm32mp1-resets.h>
 
        #address-cells = <1>;
        #size-cells = <1>;
 
-       aliases {
-               serial0 = &usart1;
-               serial1 = &usart2;
-               serial2 = &usart3;
-               serial3 = &uart4;
-               serial4 = &uart5;
-               serial5 = &usart6;
-               serial6 = &uart7;
-               serial7 = &uart8;
+       intc: interrupt-controller@a0021000 {
+               compatible = "arm,cortex-a7-gic";
+               #interrupt-cells = <3>;
+               interrupt-controller;
+               reg = <0xa0021000 0x1000>,
+                     <0xa0022000 0x2000>;
        };
 
        clocks {
@@ -56,7 +53,7 @@
                clk_i2s_ckin: i2s_ckin {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
-                       clock-frequency = <64000000>;
+                       clock-frequency = <0>;
                };
 
                clk_dsi_phy: ck_dsi_phy {
                        compatible = "fixed-clock";
                        clock-frequency = <0>;
                };
-
-               clk_usbo_48m: ck_usbo_48m {
-                       #clock-cells = <0>;
-                       compatible = "fixed-clock";
-                       clock-frequency = <48000000>;
-               };
        };
 
        soc {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
+               interrupt-parent = <&intc>;
                ranges;
 
                usart2: serial@4000e000 {
-                       compatible = "st,stm32h7-usart";
+                       compatible = "st,stm32h7-uart";
                        reg = <0x4000e000 0x400>;
                        clocks = <&rcc USART2_K>;
+                       resets = <&rcc USART2_R>;
                        status = "disabled";
                };
 
                usart3: serial@4000f000 {
-                       compatible = "st,stm32h7-usart";
+                       compatible = "st,stm32h7-uart";
                        reg = <0x4000f000 0x400>;
                        clocks = <&rcc USART3_K>;
+                       resets = <&rcc USART3_R>;
                        status = "disabled";
                };
 
@@ -96,6 +90,7 @@
                        compatible = "st,stm32h7-uart";
                        reg = <0x40010000 0x400>;
                        clocks = <&rcc UART4_K>;
+                       resets = <&rcc UART4_R>;
                        status = "disabled";
                };
 
                        compatible = "st,stm32h7-uart";
                        reg = <0x40011000 0x400>;
                        clocks = <&rcc UART5_K>;
+                       resets = <&rcc UART5_R>;
                        status = "disabled";
                };
 
                        compatible = "st,stm32h7-uart";
                        reg = <0x40018000 0x400>;
                        clocks = <&rcc UART7_K>;
+                       resets = <&rcc UART7_R>;
                        status = "disabled";
                };
 
                        compatible = "st,stm32h7-uart";
                        reg = <0x40019000 0x400>;
                        clocks = <&rcc UART8_K>;
+                       resets = <&rcc UART8_R>;
                        status = "disabled";
                };
 
                usart6: serial@44003000 {
-                       compatible = "st,stm32h7-usart";
+                       compatible = "st,stm32h7-uart";
                        reg = <0x44003000 0x400>;
                        clocks = <&rcc USART6_K>;
+                       resets = <&rcc USART6_R>;
                        status = "disabled";
                };
 
                sdmmc3: sdmmc@48004000 {
                        compatible = "st,stm32-sdmmc2";
                        reg = <0x48004000 0x400>, <0x48005000 0x400>;
-                       reg-names = "sdmmc", "delay";
                        clocks = <&rcc SDMMC3_K>;
+                       clock-names = "apb_pclk";
                        resets = <&rcc SDMMC3_R>;
                        cap-sd-highspeed;
                        cap-mmc-highspeed;
                };
 
                rcc: rcc@50000000 {
-                       compatible = "syscon", "st,stm32mp1-rcc";
+                       compatible = "st,stm32mp1-rcc", "syscon";
+                       reg = <0x50000000 0x1000>;
                        #clock-cells = <1>;
                        #reset-cells = <1>;
-                       reg = <0x50000000 0x1000>;
+                       interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
                };
 
-               rcc_reboot: rcc-reboot@50000000 {
-                               compatible = "syscon-reboot";
-                               regmap = <&rcc>;
-                               offset = <0x404>;
-                               mask = <0x1>;
+               pwr: pwr@50001000 {
+                       compatible = "st,stm32mp1-pwr", "syscon", "simple-mfd";
+                       reg = <0x50001000 0x400>;
+               };
+
+               exti: interrupt-controller@5000d000 {
+                       compatible = "st,stm32mp1-exti", "syscon";
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       reg = <0x5000d000 0x400>;
+
+                       /* exti_pwr is an extra interrupt controller used for
+                        * EXTI 55 to 60. It's mapped on pwr interrupt
+                        * controller.
+                        */
+                       exti_pwr: exti-pwr {
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               interrupt-parent = <&pwr>;
+                               st,irq-number = <6>;
+                       };
                };
 
                rng1: rng@54003000 {
                        status = "disabled";
                };
 
-               fmc_nand: fmc_nand@58002000 {
-                       compatible = "st,stm32mp1-fmc";
+               fmc: nand-controller@58002000 {
+                       compatible = "st,stm32mp15-fmc2";
                        reg = <0x58002000 0x1000>,
-                             <0x80000000 0x40000>,
-                             <0x81000000 0x40000>,
-                             <0x88000000 0x40000>,
-                             <0x89000000 0x40000>;
+                             <0x80000000 0x1000>,
+                             <0x88010000 0x1000>,
+                             <0x88020000 0x1000>,
+                             <0x81000000 0x1000>,
+                             <0x89010000 0x1000>,
+                             <0x89020000 0x1000>;
                        clocks = <&rcc FMC_K>;
                        resets = <&rcc FMC_R>;
                        status = "disabled";
                qspi: qspi@58003000 {
                        compatible = "st,stm32f469-qspi";
                        reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
+                       reg-names = "qspi", "qspi_mm";
                        clocks = <&rcc QSPI_K>;
+                       resets = <&rcc QSPI_R>;
                        status = "disabled";
                };
 
                sdmmc1: sdmmc@58005000 {
                        compatible = "st,stm32-sdmmc2";
                        reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
-                       reg-names = "sdmmc", "delay";
                        clocks = <&rcc SDMMC1_K>;
+                       clock-names = "apb_pclk";
                        resets = <&rcc SDMMC1_R>;
                        cap-sd-highspeed;
                        cap-mmc-highspeed;
                sdmmc2: sdmmc@58007000 {
                        compatible = "st,stm32-sdmmc2";
                        reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
-                       reg-names = "sdmmc", "delay";
                        clocks = <&rcc SDMMC2_K>;
+                       clock-names = "apb_pclk";
                        resets = <&rcc SDMMC2_R>;
                        cap-sd-highspeed;
                        cap-mmc-highspeed;
                        status = "disabled";
                };
 
-               iwdg2: iwdg@5a002000 {
+               iwdg2: watchdog@5a002000 {
                        compatible = "st,stm32mp1-iwdg";
                        reg = <0x5a002000 0x400>;
                        clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
                };
 
                usart1: serial@5c000000 {
-                       compatible = "st,stm32h7-usart";
+                       compatible = "st,stm32h7-uart";
                        reg = <0x5c000000 0x400>;
+                       interrupt-names = "event", "wakeup";
+                       interrupts-extended = <&intc GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&exti 26 1>;
                        clocks = <&rcc USART1_K>;
+                       resets = <&rcc USART1_R>;
+                       status = "disabled";
+               };
+
+               spi6: spi@5c001000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "st,stm32h7-spi";
+                       reg = <0x5c001000 0x400>;
+                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc SPI6_K>;
+                       resets = <&rcc SPI6_R>;
                        status = "disabled";
                };
 
                i2c4: i2c@5c002000 {
                        compatible = "st,stm32f7-i2c";
                        reg = <0x5c002000 0x400>;
+                       interrupt-names = "event", "error", "wakeup";
+                       interrupts-extended = <&intc GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&exti 24 1>;
                        clocks = <&rcc I2C4_K>;
                        resets = <&rcc I2C4_R>;
                        #address-cells = <1>;
                        reg = <0x5c004000 0x400>;
                        clocks = <&rcc RTCAPB>, <&rcc RTC>;
                        clock-names = "pclk", "rtc_ck";
+                       interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&exti 19 1>;
+                       status = "disabled";
+               };
+
+               bsec: nvmem@5c005000 {
+                       compatible = "st,stm32mp15-bsec";
+                       reg = <0x5c005000 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ts_cal1: calib@5c {
+                               reg = <0x5c 0x2>;
+                       };
+                       ts_cal2: calib@5e {
+                               reg = <0x5e 0x2>;
+                       };
+               };
+
+               i2c6: i2c@5c009000 {
+                       compatible = "st,stm32f7-i2c";
+                       reg = <0x5c009000 0x400>;
+                       interrupt-names = "event", "error", "wakeup";
+                       interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&exti 54 1>;
+                       clocks = <&rcc I2C6_K>;
+                       resets = <&rcc I2C6_R>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
                };
        };
 };
index 774561aed901c80ed7277b7aa98b83fa79d84a89..9b9cd086c2b157286b0524f145d0bb4a7dac47c7 100644 (file)
@@ -7,8 +7,8 @@
 #include "stm32mp157-pinctrl.dtsi"
 / {
        soc {
-               pinctrl: pin-controller {
-                       compatible = "st,stm32mp157caa-pinctrl";
+               pinctrl: pin-controller@50002000 {
+                       st,package = <STM32MP157CAA>;
 
                        gpioa: gpio@50002000 {
                                status = "okay";
@@ -77,8 +77,8 @@
                        };
                };
 
-               pinctrl_z: pin-controller-z {
-                       compatible = "st,stm32mp157caa-z-pinctrl";
+               pinctrl_z: pin-controller-z@54004000 {
+                       st,package = <STM32MP157CAA>;
 
                        gpioz: gpio@54004000 {
                                status = "okay";
index cbe272c23ecda07af1a1b16891635756e7a2b492..4af3e903763851ecdf4fb00ec8482a112aefeaac 100644 (file)
@@ -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
  */
 /* CSSELR definitions */
 #define LEVEL_SHIFT            U(1)
 
-/* ID_PFR0 AMU definitions */
+/* ID_MMFR4 definitions */
+#define ID_MMFR4_CNP_SHIFT     U(12)
+#define ID_MMFR4_CNP_LENGTH    U(4)
+#define ID_MMFR4_CNP_MASK      U(0xf)
+
+/* ID_PFR0 definitions */
 #define ID_PFR0_AMU_SHIFT      U(20)
 #define ID_PFR0_AMU_LENGTH     U(4)
 #define ID_PFR0_AMU_MASK       U(0xf)
 
-/* ID_PFR0 DIT definitions */
 #define ID_PFR0_DIT_SHIFT      U(24)
 #define ID_PFR0_DIT_LENGTH     U(4)
 #define ID_PFR0_DIT_MASK       U(0xf)
 #define DCISW          p15, 0, c7, c6, 2
 #define CTR            p15, 0, c0, c0, 1
 #define CNTFRQ         p15, 0, c14, c0, 0
+#define ID_MMFR4       p15, 0, c0, c2, 6
 #define ID_PFR0                p15, 0, c0, c1, 0
 #define ID_PFR1                p15, 0, c0, c1, 1
 #define MAIR0          p15, 0, c10, c2, 0
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
new file mode 100644 (file)
index 0000000..d934102
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ARCH_FEATURES_H
+#define ARCH_FEATURES_H
+
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+
+static inline bool is_armv8_2_ttcnp_present(void)
+{
+       return ((read_id_mmfr4() >> ID_MMFR4_CNP_SHIFT) &
+               ID_MMFR4_CNP_MASK) != 0U;
+}
+
+#endif /* ARCH_FEATURES_H */
index c2773c139262d26a8ed28f3824de49f8dee28c77..64ddc86fe1e721b90c7633343dafa4d1cf8931da 100644 (file)
@@ -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
  */
@@ -214,6 +214,7 @@ DEFINE_SYSREG_RW_FUNCS(cpsr)
  ******************************************************************************/
 DEFINE_COPROCR_READ_FUNC(mpidr, MPIDR)
 DEFINE_COPROCR_READ_FUNC(midr, MIDR)
+DEFINE_COPROCR_READ_FUNC(id_mmfr4, ID_MMFR4)
 DEFINE_COPROCR_READ_FUNC(id_pfr0, ID_PFR0)
 DEFINE_COPROCR_READ_FUNC(id_pfr1, ID_PFR1)
 DEFINE_COPROCR_READ_FUNC(isr, ISR)
index 8a44d83f0c679b648e3d76c080373e3a5d33f577..76c3e277bd095456e8bdb845883a28df20547336 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #define ID_AA64PFR0_GIC_WIDTH  U(4)
 #define ID_AA64PFR0_GIC_MASK   ((ULL(1) << ID_AA64PFR0_GIC_WIDTH) - ULL(1))
 
-/* ID_AA64MMFR0_EL1 definitions */
-#define ID_AA64MMFR0_EL1_PARANGE_SHIFT U(0)
-#define ID_AA64MMFR0_EL1_PARANGE_MASK  ULL(0xf)
-
 /* ID_AA64ISAR1_EL1 definitions */
 #define ID_AA64ISAR1_GPI_SHIFT U(28)
 #define ID_AA64ISAR1_GPI_WIDTH U(4)
 #define ID_AA64ISAR1_APA_MASK \
        (((ULL(1) << ID_AA64ISAR1_APA_WIDTH) - ULL(1)) << ID_AA64ISAR1_APA_SHIFT)
 
+/* ID_AA64MMFR0_EL1 definitions */
+#define ID_AA64MMFR0_EL1_PARANGE_SHIFT U(0)
+#define ID_AA64MMFR0_EL1_PARANGE_MASK  ULL(0xf)
+
 #define PARANGE_0000   U(32)
 #define PARANGE_0001   U(36)
 #define PARANGE_0010   U(40)
 #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED     ULL(0x1)
 #define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED ULL(0x0)
 
+/* ID_AA64MMFR2_EL1 definitions */
+#define ID_AA64MMFR2_EL1               S3_0_C0_C7_2
+
+#define ID_AA64MMFR2_EL1_ST_SHIFT      U(28)
+#define ID_AA64MMFR2_EL1_ST_MASK       ULL(0xf)
+
+#define ID_AA64MMFR2_EL1_CNP_SHIFT     U(0)
+#define ID_AA64MMFR2_EL1_CNP_MASK      ULL(0xf)
+
 /* ID_AA64PFR1_EL1 definitions */
 #define ID_AA64PFR1_EL1_SSBS_SHIFT     U(4)
 #define ID_AA64PFR1_EL1_SSBS_MASK      ULL(0xf)
 
 #define TCR_TxSZ_MIN           ULL(16)
 #define TCR_TxSZ_MAX           ULL(39)
+#define TCR_TxSZ_MAX_TTST      ULL(48)
 
 /* (internal) physical address size bits in EL3/EL1 */
 #define TCR_PS_BITS_4GB                ULL(0x0)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
new file mode 100644 (file)
index 0000000..9bf43bf
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ARCH_FEATURES_H
+#define ARCH_FEATURES_H
+
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+
+static inline bool is_armv8_2_ttcnp_present(void)
+{
+       return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_CNP_SHIFT) &
+               ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
+}
+
+static inline bool is_armv8_4_ttst_present(void)
+{
+       return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
+               ID_AA64MMFR2_EL1_ST_MASK) == 1U;
+}
+
+#endif /* ARCH_FEATURES_H */
index b912b4223afb0ec069521d1d360f43d71d3eb115..4e459bbb9adbd19d2fd67056b1cf25e93dfda0ec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -185,6 +185,7 @@ DEFINE_SYSREG_READ_FUNC(id_pfr1_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1)
+DEFINE_SYSREG_READ_FUNC(id_afr0_el1)
 DEFINE_SYSREG_READ_FUNC(CurrentEl)
 DEFINE_SYSREG_READ_FUNC(ctr_el0)
 DEFINE_SYSREG_RW_FUNCS(daif)
@@ -449,6 +450,9 @@ DEFINE_RENAME_SYSREG_READ_FUNC(erxaddr_el1, ERXADDR_EL1)
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc0_el1, ERXMISC0_EL1)
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)
 
+/* Armv8.2 Registers */
+DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)
+
 /* Armv8.3 Pointer Authentication Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(apgakeylo_el1, APGAKeyLo_EL1)
 
index c12b08bb7db510ead862ee98af41e35f297778dd..f7b3b9c7d2918e967db4ca69b69303df047db1c8 100644 (file)
@@ -78,7 +78,12 @@ IMPORT_SYM(unsigned long, __RO_START__,              BL_CODE_BASE);
 IMPORT_SYM(unsigned long, __RO_END__,          BL_CODE_END);
 #endif
 
-#if defined(IMAGE_BL2)
+#if defined(IMAGE_BL1)
+IMPORT_SYM(uintptr_t, __BL1_ROM_END__,   BL1_ROM_END);
+
+IMPORT_SYM(uintptr_t, __BL1_RAM_START__, BL1_RAM_BASE);
+IMPORT_SYM(uintptr_t, __BL1_RAM_END__,   BL1_RAM_LIMIT);
+#elif defined(IMAGE_BL2)
 IMPORT_SYM(unsigned long, __BL2_END__,         BL2_END);
 #elif defined(IMAGE_BL2U)
 IMPORT_SYM(unsigned long, __BL2U_END__,                BL2U_END);
@@ -89,6 +94,17 @@ IMPORT_SYM(unsigned long, __BL31_END__,              BL31_END);
 IMPORT_SYM(unsigned long, __BL32_END__,                BL32_END);
 #endif /* IMAGE_BLX */
 
+/* The following symbols are only exported from the BL2 at EL3 linker script. */
+#if BL2_IN_XIP_MEM && defined(IMAGE_BL2)
+extern uintptr_t __BL2_ROM_END__;
+#define BL2_ROM_END (uintptr_t)(&__BL2_ROM_END__)
+
+extern uintptr_t __BL2_RAM_START__;
+extern uintptr_t __BL2_RAM_END__;
+#define BL2_RAM_BASE (uintptr_t)(&__BL2_RAM_START__)
+#define BL2_RAM_LIMIT (uintptr_t)(&__BL2_RAM_END__)
+#endif /* BL2_IN_XIP_MEM */
+
 /*
  * The next 2 constants identify the extents of the coherent memory region.
  * These addresses are used by the MMU setup code and therefore they must be
index f2f26ea9959ab6b78ed1c335f7f3d9a1b9d70b59..e46eb2796688d044a1b56f8ce8a288a51382f9b8 100644 (file)
@@ -31,6 +31,9 @@ extern unsigned int bl_mem_params_desc_num;
 
 /* BL image loading utility functions */
 void flush_bl_params_desc(void);
+void flush_bl_params_desc_args(bl_mem_params_node_t *mem_params_desc_ptr,
+       unsigned int mem_params_desc_num,
+       bl_params_t *next_bl_params_ptr);
 int get_bl_params_node_index(unsigned int image_id);
 bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id);
 bl_load_info_t *get_bl_load_info_from_mem_params_desc(void);
diff --git a/include/drivers/arm/css/css_mhu.h b/include/drivers/arm/css/css_mhu.h
new file mode 100644 (file)
index 0000000..ff04ae4
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CSS_MHU_H
+#define CSS_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 /* CSS_MHU_H */
diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h
new file mode 100644 (file)
index 0000000..ecee563
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CSS_MHU_DOORBELL_H
+#define CSS_MHU_DOORBELL_H
+
+#include <stdint.h>
+
+#include <lib/mmio.h>
+
+/* MHUv2 Base Address */
+#define MHUV2_BASE_ADDR                PLAT_CSS_MHU_BASE
+
+/* MHUv2 Control Registers Offsets */
+#define MHU_V2_MSG_NO_CAP_OFFSET               0xF80
+#define MHU_V2_ACCESS_REQ_OFFSET               0xF88
+#define MHU_V2_ACCESS_READY_OFFSET             0xF8C
+
+#define SENDER_REG_STAT(_channel)      (0x20 * (_channel))
+#define SENDER_REG_SET(_channel)       ((0x20 * (_channel)) + 0xC)
+
+/* Helper macro to ring doorbell */
+#define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask)    do {    \
+               uint32_t db = mmio_read_32(addr) & (preserve_mask);     \
+               mmio_write_32(addr, db | (modify_mask));                \
+       } while (0)
+
+#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)
+
+struct scmi_channel_plat_info;
+void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info);
+void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info);
+
+#endif /* CSS_MHU_DOORBELL_H */
diff --git a/include/drivers/arm/css/css_scp.h b/include/drivers/arm/css/css_scp.h
new file mode 100644 (file)
index 0000000..f3c08c5
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CSS_SCP_H
+#define CSS_SCP_H
+
+#include <stdint.h>
+
+#include <platform_def.h>
+
+#include <lib/cassert.h>
+
+/* Forward declarations */
+struct psci_power_state;
+
+/* API for power management by SCP */
+int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie);
+void css_scp_suspend(const struct psci_power_state *target_state);
+void css_scp_off(const struct psci_power_state *target_state);
+void css_scp_on(u_register_t mpidr);
+int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level);
+void __dead2 css_scp_sys_shutdown(void);
+void __dead2 css_scp_sys_reboot(void);
+void __dead2 css_scp_system_off(int state);
+
+/* API for SCP Boot Image transfer. Return 0 on success, -1 on error */
+int css_scp_boot_image_xfer(void *image, unsigned int image_size);
+
+/*
+ * API to wait for SCP to signal till it's ready after booting the transferred
+ * image.
+ */
+int css_scp_boot_ready(void);
+
+#if CSS_LOAD_SCP_IMAGES
+
+/*
+ * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31
+ * usually resides except when ARM_BL31_IN_DRAM is
+ * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into tb_fw_config.
+ */
+CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2);
+CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2);
+
+CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow);
+CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow);
+#endif
+
+#endif /* CSS_SCP_H */
diff --git a/include/drivers/arm/css/css_scpi.h b/include/drivers/arm/css/css_scpi.h
new file mode 100644 (file)
index 0000000..68fc60a
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CSS_SCPI_H
+#define CSS_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_CSS_POWER_STATE = 0x03,
+       SCPI_CMD_GET_CSS_POWER_STATE = 0x04,
+       SCPI_CMD_SYS_POWER_STATE = 0x05
+} scpi_command_t;
+
+/*
+ * Macros to parse SCP response to GET_CSS_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_CSS_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;
+
+int scpi_wait_ready(void);
+void scpi_set_css_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_css_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 /* CSS_SCPI_H */
diff --git a/include/drivers/arm/css/scmi.h b/include/drivers/arm/css/scmi.h
new file mode 100644 (file)
index 0000000..df259f7
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SCMI_H
+#define SCMI_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <lib/bakery_lock.h>
+#include <lib/psci/psci.h>
+#include <lib/spinlock.h>
+
+/* Supported SCMI Protocol Versions */
+#define SCMI_AP_CORE_PROTO_VER                 MAKE_SCMI_VERSION(1, 0)
+#define SCMI_PWR_DMN_PROTO_VER                 MAKE_SCMI_VERSION(1, 0)
+#define SCMI_SYS_PWR_PROTO_VER                 MAKE_SCMI_VERSION(1, 0)
+
+#define GET_SCMI_MAJOR_VER(ver)                        (((ver) >> 16) & 0xffff)
+#define GET_SCMI_MINOR_VER(ver)                        ((ver) & 0xffff)
+
+#define MAKE_SCMI_VERSION(maj, min)    \
+                       ((((maj) & 0xffff) << 16) | ((min) & 0xffff))
+
+/* Macro to check if the driver is compatible with the SCMI version reported */
+#define is_scmi_version_compatible(drv, scmi)                          \
+       ((GET_SCMI_MAJOR_VER(drv) == GET_SCMI_MAJOR_VER(scmi)) &&       \
+       (GET_SCMI_MINOR_VER(drv) <= GET_SCMI_MINOR_VER(scmi)))
+
+/* SCMI Protocol identifiers */
+#define SCMI_PWR_DMN_PROTO_ID                  0x11
+#define SCMI_SYS_PWR_PROTO_ID                  0x12
+/* The AP core protocol is a CSS platform-specific extension */
+#define SCMI_AP_CORE_PROTO_ID                  0x90
+
+/* Mandatory messages IDs for all SCMI protocols */
+#define SCMI_PROTO_VERSION_MSG                 0x0
+#define SCMI_PROTO_ATTR_MSG                    0x1
+#define SCMI_PROTO_MSG_ATTR_MSG                        0x2
+
+/* SCMI power domain management protocol message IDs */
+#define SCMI_PWR_STATE_SET_MSG                 0x4
+#define SCMI_PWR_STATE_GET_MSG                 0x5
+
+/* SCMI system power management protocol message IDs */
+#define SCMI_SYS_PWR_STATE_SET_MSG             0x3
+#define SCMI_SYS_PWR_STATE_GET_MSG             0x4
+
+/* SCMI AP core protocol message IDs */
+#define SCMI_AP_CORE_RESET_ADDR_SET_MSG                0x3
+#define SCMI_AP_CORE_RESET_ADDR_GET_MSG                0x4
+
+/* Helper macros for system power management protocol commands */
+
+/*
+ * Macros to describe the bit-fields of the `attribute` of system power domain
+ * protocol PROTOCOL_MSG_ATTRIBUTE message.
+ */
+#define SYS_PWR_ATTR_WARM_RESET_SHIFT          31
+#define SCMI_SYS_PWR_WARM_RESET_SUPPORTED      (1U << SYS_PWR_ATTR_WARM_RESET_SHIFT)
+
+#define SYS_PWR_ATTR_SUSPEND_SHIFT             30
+#define SCMI_SYS_PWR_SUSPEND_SUPPORTED         (1 << SYS_PWR_ATTR_SUSPEND_SHIFT)
+
+/*
+ * Macros to describe the bit-fields of the `flags` parameter of system power
+ * domain protocol SYSTEM_POWER_STATE_SET message.
+ */
+#define SYS_PWR_SET_GRACEFUL_REQ_SHIFT         0
+#define SCMI_SYS_PWR_GRACEFUL_REQ              (1 << SYS_PWR_SET_GRACEFUL_REQ_SHIFT)
+#define SCMI_SYS_PWR_FORCEFUL_REQ              (0 << SYS_PWR_SET_GRACEFUL_REQ_SHIFT)
+
+/*
+ * Macros to describe the `system_state` parameter of system power
+ * domain protocol SYSTEM_POWER_STATE_SET message.
+ */
+#define SCMI_SYS_PWR_SHUTDOWN                  0x0
+#define SCMI_SYS_PWR_COLD_RESET                        0x1
+#define SCMI_SYS_PWR_WARM_RESET                        0x2
+#define SCMI_SYS_PWR_POWER_UP                  0x3
+#define SCMI_SYS_PWR_SUSPEND                   0x4
+
+/*
+ * Macros to describe the bit-fields of the `attribute` of AP core protocol
+ * AP_CORE_RESET_ADDR set/get messages.
+ */
+#define SCMI_AP_CORE_LOCK_ATTR_SHIFT           0x0
+#define SCMI_AP_CORE_LOCK_ATTR                 (1U << SCMI_AP_CORE_LOCK_ATTR_SHIFT)
+
+/* SCMI Error code definitions */
+#define SCMI_E_QUEUED                  1
+#define SCMI_E_SUCCESS                 0
+#define SCMI_E_NOT_SUPPORTED           -1
+#define SCMI_E_INVALID_PARAM           -2
+#define SCMI_E_DENIED                  -3
+#define SCMI_E_NOT_FOUND               -4
+#define SCMI_E_OUT_OF_RANGE            -5
+#define SCMI_E_BUSY                    -6
+
+/*
+ * SCMI driver platform information. The details of the doorbell mechanism
+ * can be found in the SCMI specification.
+ */
+typedef struct scmi_channel_plat_info {
+       /* SCMI mailbox memory */
+       uintptr_t scmi_mbx_mem;
+       /* The door bell register address */
+       uintptr_t db_reg_addr;
+       /* The bit mask that need to be preserved when ringing doorbell */
+       uint32_t db_preserve_mask;
+       /* The bit mask that need to be set to ring doorbell */
+       uint32_t db_modify_mask;
+       /* The handler for ringing doorbell */
+       void (*ring_doorbell)(struct scmi_channel_plat_info *plat_info);
+       /* cookie is unused now. But added for future enhancements. */
+       void *cookie;
+} scmi_channel_plat_info_t;
+
+
+#if HW_ASSISTED_COHERENCY
+typedef spinlock_t scmi_lock_t;
+#else
+typedef bakery_lock_t scmi_lock_t;
+#endif
+
+/*
+ * Structure to represent an SCMI channel.
+ */
+typedef struct scmi_channel {
+       scmi_channel_plat_info_t *info;
+        /* The lock for channel access */
+       scmi_lock_t *lock;
+       /* Indicate whether the channel is initialized */
+       int is_initialized;
+} scmi_channel_t;
+
+/* External Common API */
+void *scmi_init(scmi_channel_t *ch);
+int scmi_proto_msg_attr(void *p, uint32_t proto_id, uint32_t command_id,
+                                               uint32_t *attr);
+int scmi_proto_version(void *p, uint32_t proto_id, uint32_t *version);
+
+/*
+ * Power domain protocol commands. Refer to the SCMI specification for more
+ * details on these commands.
+ */
+int scmi_pwr_state_set(void *p, uint32_t domain_id, uint32_t scmi_pwr_state);
+int scmi_pwr_state_get(void *p, uint32_t domain_id, uint32_t *scmi_pwr_state);
+
+/*
+ * System power management protocol commands. Refer SCMI specification for more
+ * details on these commands.
+ */
+int scmi_sys_pwr_state_set(void *p, uint32_t flags, uint32_t system_state);
+int scmi_sys_pwr_state_get(void *p, uint32_t *system_state);
+
+/* SCMI AP core configuration protocol commands. */
+int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr);
+int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr);
+
+/* API to get the platform specific SCMI channel information. */
+scmi_channel_plat_info_t *plat_css_get_scmi_info();
+
+/* API to override default PSCI callbacks for platforms that support SCMI. */
+const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops);
+
+#endif /* SCMI_H */
diff --git a/include/drivers/arm/css/sds.h b/include/drivers/arm/css/sds.h
new file mode 100644 (file)
index 0000000..114ae92
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SDS_H
+#define SDS_H
+
+/* SDS Structure Identifier defines */
+/* AP CPU INFO defines */
+#define SDS_AP_CPU_INFO_STRUCT_ID              1
+#define SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET   0x0
+#define SDS_AP_CPU_INFO_PRIMARY_CPUID_SIZE     0x4
+
+/* ROM Firmware Version defines */
+#define SDS_ROM_VERSION_STRUCT_ID              2
+#define SDS_ROM_VERSION_OFFSET                 0x0
+#define SDS_ROM_VERSION_SIZE                   0x4
+
+/* RAM Firmware version defines */
+#define SDS_RAM_VERSION_STRUCT_ID              3
+#define SDS_RAM_VERSION_OFFSET                 0x0
+#define SDS_RAM_VERSION_SIZE                   0x4
+
+/* Platform Identity defines */
+#define SDS_PLATFORM_IDENTITY_STRUCT_ID                4
+#define SDS_PLATFORM_IDENTITY_ID_OFFSET                0x0
+#define SDS_PLATFORM_IDENTITY_ID_SIZE          0x4
+#define SDS_PLATFORM_IDENTITY_ID_CONFIG_SHIFT  28
+#define SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH  4
+#define SDS_PLATFORM_IDENTITY_ID_CONFIG_MASK   \
+       ((1 << SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH) - 1)
+
+#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_OFFSET 0x4
+#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_SIZE   0x4
+
+/* Reset Syndrome defines */
+#define SDS_RESET_SYNDROME_STRUCT_ID           5
+#define SDS_RESET_SYNDROME_OFFSET              0
+#define SDS_RESET_SYNDROME_SIZE                        4
+#define SDS_RESET_SYNDROME_POW_ON_RESET_BIT    (1 << 0)
+#define SDS_RESET_SYNDROME_SCP_WD_RESET_BIT    (1 << 1)
+#define SDS_RESET_SYNDROME_AP_WD_RESET_BIT     (1 << 2)
+#define SDS_RESET_SYNDROME_SYS_RESET_REQ_BIT   (1 << 3)
+#define SDS_RESET_SYNDROME_M3_LOCKUP_BIT       (1 << 4)
+
+/* SCP Firmware Feature Availability defines */
+#define SDS_FEATURE_AVAIL_STRUCT_ID            6
+#define SDS_FEATURE_AVAIL_OFFSET               0
+#define SDS_FEATURE_AVAIL_SIZE                 4
+#define SDS_FEATURE_AVAIL_SCP_RAM_READY_BIT    (1 << 0)
+#define SDS_FEATURE_AVAIL_DMC_READY_BIT                (1 << 1)
+#define SDS_FEATURE_AVAIL_MSG_IF_READY_BIT     (1 << 2)
+
+/* SCP BL2 Image Metadata defines */
+#define SDS_SCP_IMG_STRUCT_ID                  9
+#define SDS_SCP_IMG_FLAG_OFFSET                        0
+#define SDS_SCP_IMG_FLAG_SIZE                  4
+#define SDS_SCP_IMG_VALID_FLAG_BIT             (1 << 0)
+#define SDS_SCP_IMG_ADDR_OFFSET                        4
+#define SDS_SCP_IMG_ADDR_SIZE                  4
+#define SDS_SCP_IMG_SIZE_OFFSET                        8
+#define SDS_SCP_IMG_SIZE_SIZE                  4
+
+/* SDS Driver Error Codes */
+#define SDS_OK                         0
+#define SDS_ERR_FAIL                   -1
+#define SDS_ERR_INVALID_PARAMS         -2
+#define SDS_ERR_STRUCT_NOT_FOUND       -3
+#define SDS_ERR_STRUCT_NOT_FINALIZED   -4
+
+#ifndef __ASSEMBLY__
+#include <stddef.h>
+#include <stdint.h>
+
+typedef enum {
+       SDS_ACCESS_MODE_NON_CACHED,
+       SDS_ACCESS_MODE_CACHED,
+} sds_access_mode_t;
+
+int sds_init(void);
+int sds_struct_exists(unsigned int structure_id);
+int sds_struct_read(uint32_t structure_id, unsigned int fld_off, void *data,
+               size_t size, sds_access_mode_t mode);
+int sds_struct_write(uint32_t structure_id, unsigned int fld_off, void *data,
+               size_t size, sds_access_mode_t mode);
+#endif /*__ASSEMBLY__ */
+
+#endif /* SDS_H */
diff --git a/include/drivers/arm/fvp/fvp_pwrc.h b/include/drivers/arm/fvp/fvp_pwrc.h
new file mode 100644 (file)
index 0000000..ca173f3
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_PWRC_H
+#define FVP_PWRC_H
+
+/* FVP Power controller register offset etc */
+#define PPOFFR_OFF             U(0x0)
+#define PPONR_OFF              U(0x4)
+#define PCOFFR_OFF             U(0x8)
+#define PWKUPR_OFF             U(0xc)
+#define PSYSR_OFF              U(0x10)
+
+#define PWKUPR_WEN             BIT_32(31)
+
+#define PSYSR_AFF_L2           BIT_32(31)
+#define PSYSR_AFF_L1           BIT_32(30)
+#define PSYSR_AFF_L0           BIT_32(29)
+#define PSYSR_WEN              BIT_32(28)
+#define PSYSR_PC               BIT_32(27)
+#define PSYSR_PP               BIT_32(26)
+
+#define PSYSR_WK_SHIFT         24
+#define PSYSR_WK_WIDTH         0x2
+#define PSYSR_WK_MASK          ((1U << PSYSR_WK_WIDTH) - 1U)
+#define PSYSR_WK(x)            ((x) >> PSYSR_WK_SHIFT) & PSYSR_WK_MASK
+
+#define WKUP_COLD              U(0x0)
+#define WKUP_RESET             U(0x1)
+#define WKUP_PPONR             U(0x2)
+#define WKUP_GICREQ            U(0x3)
+
+#define PSYSR_INVALID          U(0xffffffff)
+
+#ifndef __ASSEMBLY__
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * Function & variable prototypes
+ ******************************************************************************/
+void fvp_pwrc_write_pcoffr(u_register_t mpidr);
+void fvp_pwrc_write_ppoffr(u_register_t mpidr);
+void fvp_pwrc_write_pponr(u_register_t mpidr);
+void fvp_pwrc_set_wen(u_register_t mpidr);
+void fvp_pwrc_clr_wen(u_register_t mpidr);
+unsigned int fvp_pwrc_read_psysr(u_register_t mpidr);
+unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* FVP_PWRC_H */
index 2382697748b585e3e85972efcc0c36aaedceb04f..72221acb0fc96d9dd51dbd6922abf91498fdc249 100644 (file)
@@ -84,6 +84,7 @@
 #define GICR_PCPUBASE_SHIFT    0x11
 #define GICR_SGIBASE_OFFSET    U(65536)        /* 64 KB */
 #define GICR_CTLR              U(0x0)
+#define GICR_IIDR              U(0x04)
 #define GICR_TYPER             U(0x08)
 #define GICR_WAKER             U(0x14)
 #define GICR_PROPBASER         U(0x70)
diff --git a/include/drivers/rpi3/gpio/rpi3_gpio.h b/include/drivers/rpi3/gpio/rpi3_gpio.h
new file mode 100644 (file)
index 0000000..159a2e0
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019, Linaro Limited
+ * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RPI3_GPIO_H
+#define RPI3_GPIO_H
+
+#include <stdint.h>
+#include <drivers/gpio.h>
+
+struct rpi3_gpio_params {
+       uintptr_t       reg_base;
+};
+
+void rpi3_gpio_init(struct rpi3_gpio_params *params);
+int rpi3_gpio_get_select(int gpio);
+void rpi3_gpio_set_select(int gpio, int fsel);
+
+#define RPI3_GPIO_GPFSEL(n)    ((n) * U(0x04))
+#define RPI3_GPIO_GPSET(n)     (((n) * U(0x04)) + U(0x1C))
+#define RPI3_GPIO_GPCLR(n)     (((n) * U(0x04)) + U(0x28))
+#define RPI3_GPIO_GPLEV(n)     (((n) * U(0x04)) + U(0x34))
+#define RPI3_GPIO_GPPUD                U(0x94)
+#define RPI3_GPIO_GPPUDCLK(n)  (((n) * U(0x04)) + U(0x98))
+
+#define RPI3_GPIO_FUNC_INPUT   U(0)
+#define RPI3_GPIO_FUNC_OUTPUT  U(1)
+#define RPI3_GPIO_FUNC_ALT0    U(4)
+#define RPI3_GPIO_FUNC_ALT1    U(5)
+#define RPI3_GPIO_FUNC_ALT2    U(6)
+#define RPI3_GPIO_FUNC_ALT3    U(7)
+#define RPI3_GPIO_FUNC_ALT4    U(3)
+#define RPI3_GPIO_FUNC_ALT5    U(2)
+
+#endif  /* RPI3_GPIO_H */
diff --git a/include/drivers/st/bsec.h b/include/drivers/st/bsec.h
new file mode 100644 (file)
index 0000000..2171550
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BSEC_H
+#define BSEC_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <lib/utils_def.h>
+
+/*
+ * IP configuration
+ */
+#define BSEC_OTP_MASK                  GENMASK(4, 0)
+#define BSEC_OTP_BANK_SHIFT            5
+#define BSEC_TIMEOUT_VALUE             0xFFFF
+
+#define ADDR_LOWER_OTP_PERLOCK_SHIFT   0x03
+#define DATA_LOWER_OTP_PERLOCK_BIT     0x03U /* 2 significants bits are used */
+#define DATA_LOWER_OTP_PERLOCK_MASK    GENMASK(2, 0)
+#define ADDR_UPPER_OTP_PERLOCK_SHIFT   0x04
+#define DATA_UPPER_OTP_PERLOCK_BIT     0x01U /* 1 significants bits are used */
+#define DATA_UPPER_OTP_PERLOCK_MASK    GENMASK(3, 0)
+
+/*
+ * Return status
+ */
+#define BSEC_OK                                0U
+#define BSEC_ERROR                     0xFFFFFFFFU
+#define BSEC_DISTURBED                 0xFFFFFFFEU
+#define BSEC_INVALID_PARAM             0xFFFFFFFCU
+#define BSEC_PROG_FAIL                 0xFFFFFFFBU
+#define BSEC_LOCK_FAIL                 0xFFFFFFFAU
+#define BSEC_WRITE_FAIL                        0xFFFFFFF9U
+#define BSEC_SHADOW_FAIL               0xFFFFFFF8U
+#define BSEC_TIMEOUT                   0xFFFFFFF7U
+
+/*
+ * BSEC REGISTER OFFSET (base relative)
+ */
+#define BSEC_OTP_CONF_OFF              0x000U
+#define BSEC_OTP_CTRL_OFF              0x004U
+#define BSEC_OTP_WRDATA_OFF            0x008U
+#define BSEC_OTP_STATUS_OFF            0x00CU
+#define BSEC_OTP_LOCK_OFF              0x010U
+#define BSEC_DEN_OFF                   0x014U
+#define BSEC_DISTURBED_OFF             0x01CU
+#define BSEC_DISTURBED1_OFF            0x020U
+#define BSEC_DISTURBED2_OFF            0x024U
+#define BSEC_ERROR_OFF                 0x034U
+#define BSEC_ERROR1_OFF                        0x038U
+#define BSEC_ERROR2_OFF                        0x03CU
+#define BSEC_WRLOCK_OFF                        0x04CU /* Safmem permanent lock */
+#define BSEC_WRLOCK1_OFF               0x050U
+#define BSEC_WRLOCK2_OFF               0x054U
+#define BSEC_SPLOCK_OFF                        0x064U /* Program safmem sticky lock */
+#define BSEC_SPLOCK1_OFF               0x068U
+#define BSEC_SPLOCK2_OFF               0x06CU
+#define BSEC_SWLOCK_OFF                        0x07CU /* Write in OTP sticky lock */
+#define BSEC_SWLOCK1_OFF               0x080U
+#define BSEC_SWLOCK2_OFF               0x084U
+#define BSEC_SRLOCK_OFF                        0x094U /* Shadowing sticky lock */
+#define BSEC_SRLOCK1_OFF               0x098U
+#define BSEC_SRLOCK2_OFF               0x09CU
+#define BSEC_JTAG_IN_OFF               0x0ACU
+#define BSEC_JTAG_OUT_OFF              0x0B0U
+#define BSEC_SCRATCH_OFF               0x0B4U
+#define BSEC_OTP_DATA_OFF              0x200U
+#define BSEC_IPHW_CFG_OFF              0xFF0U
+#define BSEC_IPVR_OFF                  0xFF4U
+#define BSEC_IP_ID_OFF                 0xFF8U
+#define BSEC_IP_MAGIC_ID_OFF           0xFFCU
+
+/*
+ * BSEC_CONFIGURATION Register
+ */
+#define BSEC_CONF_POWER_UP_MASK                BIT(0)
+#define BSEC_CONF_POWER_UP_SHIFT       0
+#define BSEC_CONF_FRQ_MASK             GENMASK(2, 1)
+#define BSEC_CONF_FRQ_SHIFT            1
+#define BSEC_CONF_PRG_WIDTH_MASK       GENMASK(6, 3)
+#define BSEC_CONF_PRG_WIDTH_SHIFT      3
+#define BSEC_CONF_TREAD_MASK           GENMASK(8, 7)
+#define BSEC_CONF_TREAD_SHIFT          7
+
+/*
+ * BSEC_CONTROL Register
+ */
+#define BSEC_READ                      0x000U
+#define BSEC_WRITE                     0x100U
+#define BSEC_LOCK                      0x200U
+
+/*
+ * BSEC_OTP_LOCK register
+ */
+#define UPPER_OTP_LOCK_MASK            BIT(0)
+#define UPPER_OTP_LOCK_SHIFT           0
+#define DENREG_LOCK_MASK               BIT(2)
+#define DENREG_LOCK_SHIFT              2
+#define GPLOCK_LOCK_MASK               BIT(4)
+#define GPLOCK_LOCK_SHIFT              4
+
+/*
+ * BSEC_OTP_STATUS Register
+ */
+#define BSEC_MODE_STATUS_MASK          GENMASK(2, 0)
+#define BSEC_MODE_BUSY_MASK            BIT(3)
+#define BSEC_MODE_PROGFAIL_MASK                BIT(4)
+#define BSEC_MODE_PWR_MASK             BIT(5)
+#define BSEC_MODE_BIST1_LOCK_MASK      BIT(6)
+#define BSEC_MODE_BIST2_LOCK_MASK      BIT(7)
+
+/* OTP MODE*/
+#define BSEC_MODE_OPEN1                        0x00
+#define BSEC_MODE_SECURED              0x01
+#define BSEC_MODE_OPEN2                        0x02
+#define BSEC_MODE_INVALID              0x04
+
+/* BSEC_DENABLE Register */
+#define BSEC_HDPEN                     BIT(4)
+#define BSEC_SPIDEN                    BIT(5)
+#define BSEC_SPINDEN                   BIT(6)
+#define BSEC_DBGSWGEN                  BIT(10)
+#define BSEC_DEN_ALL_MSK               GENMASK(10, 0)
+
+/* BSEC_FENABLE Register */
+#define BSEC_FEN_ALL_MSK               GENMASK(14, 0)
+
+/*
+ * OTP Lock services definition
+ * Value must corresponding to the bit number in the register
+ */
+#define BSEC_LOCK_UPPER_OTP            0x00
+#define BSEC_LOCK_DEBUG                        0x02
+#define BSEC_LOCK_PROGRAM              0x03
+
+/* Values for struct bsec_config::freq */
+#define FREQ_10_20_MHZ                 0x0
+#define FREQ_20_30_MHZ                 0x1
+#define FREQ_30_45_MHZ                 0x2
+#define FREQ_45_67_MHZ                 0x3
+
+/*
+ * Device info structure, providing device-specific functions and a means of
+ * adding driver-specific state
+ */
+struct bsec_config {
+       uint8_t tread;          /* SAFMEM Reading current level default 0 */
+       uint8_t pulse_width;    /* SAFMEM Programming pulse width default 1 */
+       uint8_t freq;           /* SAFMEM CLOCK see freq value define
+                                * default FREQ_45_67_MHZ
+                                */
+       uint8_t power;          /* Power up SAFMEM. 1 power up, 0 power off */
+       uint8_t prog_lock;      /* Programming Sticky lock
+                                * 1 programming is locked until next reset
+                                */
+       uint8_t den_lock;       /* Debug enable sticky lock
+                                * 1 debug enable is locked until next reset
+                                */
+       uint8_t upper_otp_lock; /* Shadowing of upper OTP sticky lock
+                                * 1 shadowing of upper OTP is locked
+                                * until next reset
+                                */
+};
+
+uint32_t bsec_probe(void);
+uint32_t bsec_get_base(void);
+
+uint32_t bsec_set_config(struct bsec_config *cfg);
+uint32_t bsec_get_config(struct bsec_config *cfg);
+
+uint32_t bsec_shadow_register(uint32_t otp);
+uint32_t bsec_read_otp(uint32_t *val, uint32_t otp);
+uint32_t bsec_write_otp(uint32_t val, uint32_t otp);
+uint32_t bsec_program_otp(uint32_t val, uint32_t otp);
+uint32_t bsec_permanent_lock_otp(uint32_t otp);
+
+uint32_t bsec_write_debug_conf(uint32_t val);
+uint32_t bsec_read_debug_conf(void);
+uint32_t bsec_write_feature_conf(uint32_t val);
+uint32_t bsec_read_feature_conf(uint32_t *val);
+
+uint32_t bsec_get_status(void);
+uint32_t bsec_get_hw_conf(void);
+uint32_t bsec_get_version(void);
+uint32_t bsec_get_id(void);
+uint32_t bsec_get_magic_id(void);
+
+bool bsec_write_sr_lock(uint32_t otp, uint32_t value);
+bool bsec_read_sr_lock(uint32_t otp);
+bool bsec_write_sw_lock(uint32_t otp, uint32_t value);
+bool bsec_read_sw_lock(uint32_t otp);
+bool bsec_write_sp_lock(uint32_t otp, uint32_t value);
+bool bsec_read_sp_lock(uint32_t otp);
+bool bsec_wr_lock(uint32_t otp);
+uint32_t bsec_otp_lock(uint32_t service, uint32_t value);
+
+bool bsec_mode_is_closed_device(void);
+uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word);
+uint32_t bsec_check_nsec_access_rights(uint32_t otp);
+
+#endif /* BSEC_H */
index acd95ecabf8bfe6b70baf920ba650196e049a064..4320eafcdaf07c8458a00c3928fb5c8fe3f9aaad 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,10 +9,6 @@
 
 #include <lib/utils_def.h>
 
-#define STM32_GPIOA_BANK       U(0x50002000)
-#define STM32_GPIOZ_BANK       U(0x54004000)
-#define STM32_GPIO_BANK_OFFSET U(0x1000)
-
 #define GPIO_MODE_OFFSET       U(0x00)
 #define GPIO_TYPE_OFFSET       U(0x04)
 #define GPIO_SPEED_OFFSET      U(0x08)
 #define GPIO_BSRR_OFFSET       U(0x18)
 #define GPIO_AFRL_OFFSET       U(0x20)
 #define GPIO_AFRH_OFFSET       U(0x24)
+#define GPIO_SECR_OFFSET       U(0x30)
 
 #define GPIO_ALT_LOWER_LIMIT   U(0x08)
 
-#define GPIO_BANK_A            U(0x00)
-#define GPIO_BANK_B            U(0x01)
-#define GPIO_BANK_C            U(0x02)
-#define GPIO_BANK_D            U(0x03)
-#define GPIO_BANK_E            U(0x04)
-#define GPIO_BANK_F            U(0x05)
-#define GPIO_BANK_G            U(0x06)
-#define GPIO_BANK_H            U(0x07)
-#define GPIO_BANK_I            U(0x08)
-#define GPIO_BANK_J            U(0x09)
-#define GPIO_BANK_K            U(0x0A)
-#define GPIO_BANK_Z            U(0x19)
-
-#define GPIO_PIN_0             U(0x00)
-#define GPIO_PIN_1             U(0x01)
-#define GPIO_PIN_2             U(0x02)
-#define GPIO_PIN_3             U(0x03)
-#define GPIO_PIN_4             U(0x04)
-#define GPIO_PIN_5             U(0x05)
-#define GPIO_PIN_6             U(0x06)
-#define GPIO_PIN_7             U(0x07)
-#define GPIO_PIN_8             U(0x08)
-#define GPIO_PIN_9             U(0x09)
-#define GPIO_PIN_10            U(0x0A)
-#define GPIO_PIN_11            U(0x0B)
-#define GPIO_PIN_12            U(0x0C)
-#define GPIO_PIN_13            U(0x0D)
-#define GPIO_PIN_14            U(0x0E)
-#define GPIO_PIN_15            U(0x0F)
-#define GPIO_PIN_MAX           GPIO_PIN_15
+#define GPIO_PIN_(_x)          U(_x)
+#define GPIO_PIN_MAX           GPIO_PIN_(15)
 
-#define GPIO_ALTERNATE_0       0x00
-#define GPIO_ALTERNATE_1       0x01
-#define GPIO_ALTERNATE_2       0x02
-#define GPIO_ALTERNATE_3       0x03
-#define GPIO_ALTERNATE_4       0x04
-#define GPIO_ALTERNATE_5       0x05
-#define GPIO_ALTERNATE_6       0x06
-#define GPIO_ALTERNATE_7       0x07
-#define GPIO_ALTERNATE_8       0x08
-#define GPIO_ALTERNATE_9       0x09
-#define GPIO_ALTERNATE_10      0x0A
-#define GPIO_ALTERNATE_11      0x0B
-#define GPIO_ALTERNATE_12      0x0C
-#define GPIO_ALTERNATE_13      0x0D
-#define GPIO_ALTERNATE_14      0x0E
-#define GPIO_ALTERNATE_15      0x0F
+#define GPIO_ALTERNATE_(_x)    U(_x)
 #define GPIO_ALTERNATE_MASK    U(0x0F)
 
 #define GPIO_MODE_INPUT                0x00
@@ -82,8 +36,8 @@
 
 #define GPIO_SPEED_LOW         0x00
 #define GPIO_SPEED_MEDIUM      0x01
-#define GPIO_SPEED_FAST                0x02
-#define GPIO_SPEED_HIGH                0x03
+#define GPIO_SPEED_HIGH                0x02
+#define GPIO_SPEED_VERY_HIGH   0x03
 #define GPIO_SPEED_MASK                U(0x03)
 
 #define GPIO_NO_PULL           0x00
 #ifndef __ASSEMBLY__
 #include <stdint.h>
 
+int dt_set_pinctrl_config(int node);
 void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
-             uint32_t pull, uint32_t alternate);
+             uint32_t pull, uint32_t alternate, uint8_t status);
+void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure);
 #endif /*__ASSEMBLY__*/
 
 #endif /* STM32_GPIO_H */
index 363e3020c26d2ac81d54baf37afc7426c457127a..4ab37d6b44a156db210033886fb0b53475305134 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -153,7 +153,7 @@ struct stm32mp1_ddrphy_cal {
 
 struct stm32mp1_ddr_info {
        const char *name;
-       uint16_t speed; /* in MHZ */
+       uint32_t speed; /* in kHZ */
        uint32_t size;  /* Memory size in byte = col * row * width */
 };
 
@@ -168,7 +168,7 @@ struct stm32mp1_ddr_config {
        struct stm32mp1_ddrphy_cal p_cal;
 };
 
-int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed);
+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed);
 void stm32mp1_ddr_init(struct ddr_info *priv,
                       struct stm32mp1_ddr_config *config);
 #endif /* STM32MP1_DDR_H */
index bfcd5e21042d94091665c3d6f422c2a85436ac10..342239a52de3a6f40db2b1264c1d97f65186b483 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -247,11 +247,14 @@ struct stm32mp1_ddrphy {
 #define DDRCTRL_DBGSTAT                                0x310
 #define DDRCTRL_SWCTL                          0x320
 #define DDRCTRL_SWSTAT                         0x324
+#define DDRCTRL_PSTAT                          0x3FC
 #define DDRCTRL_PCTRL_0                                0x490
 #define DDRCTRL_PCTRL_1                                0x540
 
 /* DDR Controller Register fields */
 #define DDRCTRL_MSTR_DDR3                      BIT(0)
+#define DDRCTRL_MSTR_LPDDR2                    BIT(2)
+#define DDRCTRL_MSTR_LPDDR3                    BIT(3)
 #define DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK       GENMASK(13, 12)
 #define DDRCTRL_MSTR_DATA_BUS_WIDTH_FULL       0
 #define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF       BIT(12)
@@ -269,7 +272,7 @@ struct stm32mp1_ddrphy {
 /* Only one rank supported */
 #define DDRCTRL_MRCTRL0_MR_RANK_SHIFT          4
 #define DDRCTRL_MRCTRL0_MR_RANK_ALL \
-               (0x1U << DDRCTRL_MRCTRL0_MR_RANK_SHIFT)
+                                       BIT(DDRCTRL_MRCTRL0_MR_RANK_SHIFT)
 #define DDRCTRL_MRCTRL0_MR_ADDR_SHIFT          12
 #define DDRCTRL_MRCTRL0_MR_ADDR_MASK           GENMASK(15, 12)
 #define DDRCTRL_MRCTRL0_MR_WR                  BIT(31)
@@ -367,6 +370,7 @@ struct stm32mp1_ddrphy {
 
 #define DDRPHYC_DLLGCR_BPS200                  BIT(23)
 
+#define DDRPHYC_ACDLLCR_DLLSRST                        BIT(30)
 #define DDRPHYC_ACDLLCR_DLLDIS                 BIT(31)
 
 #define DDRPHYC_PTR0_TDLLSRST_OFFSET           0
diff --git a/include/drivers/st/stm32mp1_pmic.h b/include/drivers/st/stm32mp1_pmic.h
deleted file mode 100644 (file)
index 75f8e61..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STM32MP1_PMIC_H
-#define STM32MP1_PMIC_H
-
-#include <stdbool.h>
-
-#include <platform_def.h>
-
-bool dt_check_pmic(void);
-int dt_pmic_enable_boot_on_regulators(void);
-void initialize_pmic_i2c(void);
-void initialize_pmic(void);
-int pmic_ddr_power_init(enum ddr_type ddr_type);
-
-#endif /* STM32MP1_PMIC_H */
index fd406c57e76c3649ebfea32352bd3655c281b965..2f29e84d595e4c19c1bcd26d377f9a4c0fc130a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #define RCC_MP_AHB6ENCLRR              U(0x21C)
 #define RCC_MP_TZAHB6ENSETR            U(0x220)
 #define RCC_MP_TZAHB6ENCLRR            U(0x224)
+#define RCC_MC_APB4ENSETR              U(0x280)
+#define RCC_MC_APB4ENCLRR              U(0x284)
+#define RCC_MC_APB5ENSETR              U(0x288)
+#define RCC_MC_APB5ENCLRR              U(0x28C)
+#define RCC_MC_AHB5ENSETR              U(0x290)
+#define RCC_MC_AHB5ENCLRR              U(0x294)
+#define RCC_MC_AHB6ENSETR              U(0x298)
+#define RCC_MC_AHB6ENCLRR              U(0x29C)
 #define RCC_MP_APB4LPENSETR            U(0x300)
 #define RCC_MP_APB4LPENCLRR            U(0x304)
 #define RCC_MP_APB5LPENSETR            U(0x308)
 #define RCC_MP_AHB6LPENCLRR            U(0x31C)
 #define RCC_MP_TZAHB6LPENSETR          U(0x320)
 #define RCC_MP_TZAHB6LPENCLRR          U(0x324)
+#define RCC_MC_APB4LPENSETR            U(0x380)
+#define RCC_MC_APB4LPENCLRR            U(0x384)
+#define RCC_MC_APB5LPENSETR            U(0x388)
+#define RCC_MC_APB5LPENCLRR            U(0x38C)
+#define RCC_MC_AHB5LPENSETR            U(0x390)
+#define RCC_MC_AHB5LPENCLRR            U(0x394)
+#define RCC_MC_AHB6LPENSETR            U(0x398)
+#define RCC_MC_AHB6LPENCLRR            U(0x39C)
 #define RCC_BR_RSTSCLRR                        U(0x400)
 #define RCC_MP_GRSTCSETR               U(0x404)
 #define RCC_MP_RSTSCLRR                        U(0x408)
 #define RCC_MP_AHB4ENCLRR              U(0xA2C)
 #define RCC_MP_MLAHBENSETR             U(0xA38)
 #define RCC_MP_MLAHBENCLRR             U(0xA3C)
+#define RCC_MC_APB1ENSETR              U(0xA80)
+#define RCC_MC_APB1ENCLRR              U(0xA84)
+#define RCC_MC_APB2ENSETR              U(0xA88)
+#define RCC_MC_APB2ENCLRR              U(0xA8C)
+#define RCC_MC_APB3ENSETR              U(0xA90)
+#define RCC_MC_APB3ENCLRR              U(0xA94)
+#define RCC_MC_AHB2ENSETR              U(0xA98)
+#define RCC_MC_AHB2ENCLRR              U(0xA9C)
+#define RCC_MC_AHB3ENSETR              U(0xAA0)
+#define RCC_MC_AHB3ENCLRR              U(0xAA4)
+#define RCC_MC_AHB4ENSETR              U(0xAA8)
+#define RCC_MC_AHB4ENCLRR              U(0xAAC)
+#define RCC_MC_AXIMENSETR              U(0xAB0)
+#define RCC_MC_AXIMENCLRR              U(0xAB4)
+#define RCC_MC_MLAHBENSETR             U(0xAB8)
+#define RCC_MC_MLAHBENCLRR             U(0xABC)
 #define RCC_MP_APB1LPENSETR            U(0xB00)
 #define RCC_MP_APB1LPENCLRR            U(0xB04)
 #define RCC_MP_APB2LPENSETR            U(0xB08)
 #define RCC_MP_AXIMLPENCLRR            U(0xB34)
 #define RCC_MP_MLAHBLPENSETR           U(0xB38)
 #define RCC_MP_MLAHBLPENCLRR           U(0xB3C)
+#define RCC_MC_APB1LPENSETR            U(0xB80)
+#define RCC_MC_APB1LPENCLRR            U(0xB84)
+#define RCC_MC_APB2LPENSETR            U(0xB88)
+#define RCC_MC_APB2LPENCLRR            U(0xB8C)
+#define RCC_MC_APB3LPENSETR            U(0xB90)
+#define RCC_MC_APB3LPENCLRR            U(0xB94)
+#define RCC_MC_AHB2LPENSETR            U(0xB98)
+#define RCC_MC_AHB2LPENCLRR            U(0xB9C)
+#define RCC_MC_AHB3LPENSETR            U(0xBA0)
+#define RCC_MC_AHB3LPENCLRR            U(0xBA4)
+#define RCC_MC_AHB4LPENSETR            U(0xBA8)
+#define RCC_MC_AHB4LPENCLRR            U(0xBAC)
+#define RCC_MC_AXIMLPENSETR            U(0xBB0)
+#define RCC_MC_AXIMLPENCLRR            U(0xBB4)
+#define RCC_MC_MLAHBLPENSETR           U(0xBB8)
+#define RCC_MC_MLAHBLPENCLRR           U(0xBBC)
+#define RCC_MC_RSTSCLRR                        U(0xC00)
+#define RCC_MC_CIER                    U(0xC14)
+#define RCC_MC_CIFR                    U(0xC18)
 #define RCC_VERR                       U(0xFF4)
 #define RCC_IDR                                U(0xFF8)
 #define RCC_SIDR                       U(0xFFC)
 
+#define RCC_OFFSET_MASK                        GENMASK(11, 0)
+
 /* Values for RCC_TZCR register */
 #define RCC_TZCR_TZEN                  BIT(0)
 
 #define RCC_MPUDIV_MASK                        GENMASK(2, 0)
 #define RCC_AXIDIV_MASK                        GENMASK(2, 0)
 
+/* Used for TIMER Prescaler */
+#define RCC_TIMGXPRER_TIMGXPRE         BIT(0)
+
 /* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */
 #define RCC_MP_ENCLRR_OFFSET           U(4)
 
 #define RCC_BDCR_LSEON                 BIT(0)
 #define RCC_BDCR_LSEBYP                        BIT(1)
 #define RCC_BDCR_LSERDY                        BIT(2)
+#define RCC_BDCR_DIGBYP                        BIT(3)
 #define RCC_BDCR_LSEDRV_MASK           GENMASK(5, 4)
 #define RCC_BDCR_LSEDRV_SHIFT          4
 #define RCC_BDCR_LSECSSON              BIT(8)
 /* Used for all RCC_PLL<n>CR registers */
 #define RCC_PLLNCR_PLLON               BIT(0)
 #define RCC_PLLNCR_PLLRDY              BIT(1)
+#define RCC_PLLNCR_SSCG_CTRL           BIT(2)
 #define RCC_PLLNCR_DIVPEN              BIT(4)
 #define RCC_PLLNCR_DIVQEN              BIT(5)
 #define RCC_PLLNCR_DIVREN              BIT(6)
 
 /* Used for RCC_OCENSETR and RCC_OCENCLRR registers */
 #define RCC_OCENR_HSION                        BIT(0)
+#define RCC_OCENR_HSIKERON             BIT(1)
 #define RCC_OCENR_CSION                        BIT(4)
+#define RCC_OCENR_CSIKERON             BIT(5)
+#define RCC_OCENR_DIGBYP               BIT(7)
 #define RCC_OCENR_HSEON                        BIT(8)
+#define RCC_OCENR_HSEKERON             BIT(9)
 #define RCC_OCENR_HSEBYP               BIT(10)
 #define RCC_OCENR_HSECSSON             BIT(11)
 
 
 /* Fields of RCC_HSICFGR register */
 #define RCC_HSICFGR_HSIDIV_MASK                GENMASK(1, 0)
+#define RCC_HSICFGR_HSITRIM_SHIFT      8
+#define RCC_HSICFGR_HSITRIM_MASK       GENMASK(14, 8)
+#define RCC_HSICFGR_HSICAL_SHIFT       16
+#define RCC_HSICFGR_HSICAL_MASK                GENMASK(27, 16)
+
+/* Fields of RCC_CSICFGR register */
+#define RCC_CSICFGR_CSITRIM_SHIFT      8
+#define RCC_CSICFGR_CSITRIM_MASK       GENMASK(12, 8)
+#define RCC_CSICFGR_CSICAL_SHIFT       16
+#define RCC_CSICFGR_CSICAL_MASK                GENMASK(23, 16)
 
 /* Used for RCC_MCO related operations */
 #define RCC_MCOCFG_MCOON               BIT(12)
 #define RCC_DBGCFGR_DBGCKEN            BIT(8)
 
 /* RCC register fields for reset reasons */
-#define  RCC_MP_RSTSCLRR_PORRSTF       BIT(0)
-#define  RCC_MP_RSTSCLRR_BORRSTF       BIT(1)
-#define  RCC_MP_RSTSCLRR_PADRSTF       BIT(2)
-#define  RCC_MP_RSTSCLRR_HCSSRSTF      BIT(3)
-#define  RCC_MP_RSTSCLRR_VCORERSTF     BIT(4)
-#define  RCC_MP_RSTSCLRR_MPSYSRSTF     BIT(6)
-#define  RCC_MP_RSTSCLRR_IWDG1RSTF     BIT(8)
-#define  RCC_MP_RSTSCLRR_IWDG2RSTF     BIT(9)
-#define  RCC_MP_RSTSCLRR_STDBYRSTF     BIT(11)
-#define  RCC_MP_RSTSCLRR_CSTDBYRSTF    BIT(12)
+#define RCC_MP_RSTSCLRR_PORRSTF                BIT(0)
+#define RCC_MP_RSTSCLRR_BORRSTF                BIT(1)
+#define RCC_MP_RSTSCLRR_PADRSTF                BIT(2)
+#define RCC_MP_RSTSCLRR_HCSSRSTF       BIT(3)
+#define RCC_MP_RSTSCLRR_VCORERSTF      BIT(4)
+#define RCC_MP_RSTSCLRR_MPSYSRSTF      BIT(6)
+#define RCC_MP_RSTSCLRR_MCSYSRSTF      BIT(7)
+#define RCC_MP_RSTSCLRR_IWDG1RSTF      BIT(8)
+#define RCC_MP_RSTSCLRR_IWDG2RSTF      BIT(9)
+#define RCC_MP_RSTSCLRR_STDBYRSTF      BIT(11)
+#define RCC_MP_RSTSCLRR_CSTDBYRSTF     BIT(12)
+#define RCC_MP_RSTSCLRR_MPUP0RSTF      BIT(13)
+#define RCC_MP_RSTSCLRR_MPUP1RSTF      BIT(14)
 
 /* Global Reset Register */
 #define RCC_MP_GRSTCSETR_MPSYSRST      BIT(0)
+#define RCC_MP_GRSTCSETR_MPUP0RST      BIT(4)
+#define RCC_MP_GRSTCSETR_MPUP1RST      BIT(5)
 
 /* Clock Source Interrupt Flag Register */
 #define RCC_MP_CIFR_MASK               U(0x110F1F)
+#define RCC_MP_CIFR_LSIRDYF            BIT(0)
+#define RCC_MP_CIFR_LSERDYF            BIT(1)
+#define RCC_MP_CIFR_HSIRDYF            BIT(2)
+#define RCC_MP_CIFR_HSERDYF            BIT(3)
+#define RCC_MP_CIFR_CSIRDYF            BIT(4)
+#define RCC_MP_CIFR_PLL1DYF            BIT(8)
+#define RCC_MP_CIFR_PLL2DYF            BIT(9)
+#define RCC_MP_CIFR_PLL3DYF            BIT(10)
+#define RCC_MP_CIFR_PLL4DYF            BIT(11)
 #define RCC_MP_CIFR_WKUPF              BIT(20)
 
 /* Stop Request Set Register */
 /* Values of RCC_MP_APB1ENSETR register */
 #define RCC_MP_APB1ENSETR_UART4EN      BIT(16)
 
+/* Values of RCC_MP_APB5ENSETR register */
+#define RCC_MP_APB5ENSETR_SPI6EN       BIT(0)
+#define RCC_MP_APB5ENSETR_I2C4EN       BIT(2)
+#define RCC_MP_APB5ENSETR_I2C6EN       BIT(3)
+#define RCC_MP_APB5ENSETR_USART1EN     BIT(4)
+#define RCC_MP_APB5ENSETR_RTCAPBEN     BIT(8)
+#define RCC_MP_APB5ENSETR_IWDG1APBEN   BIT(15)
+
 /* Values of RCC_MP_AHB4ENSETR register */
 #define RCC_MP_AHB4ENSETR_GPIOGEN      BIT(6)
+#define RCC_MP_AHB4ENSETR_GPIOHEN      BIT(7)
+
+/* Values of RCC_MP_AHB5ENSETR register */
+#define RCC_MP_AHB5ENSETR_GPIOZEN      BIT(0)
+#define RCC_MP_AHB5ENSETR_CRYP1EN      BIT(4)
+#define RCC_MP_AHB5ENSETR_HASH1EN      BIT(5)
+#define RCC_MP_AHB5ENSETR_RNG1EN       BIT(6)
+
+/* Values of RCC_MP_IWDGFZSETR register */
+#define RCC_MP_IWDGFZSETR_IWDG1                BIT(0)
+#define RCC_MP_IWDGFZSETR_IWDG2                BIT(1)
+
+/* Values of RCC_PWRLPDLYCR register */
+#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK  GENMASK(21, 0)
 
 #endif /* STM32MP1_RCC_H */
diff --git a/include/drivers/st/stm32mp_pmic.h b/include/drivers/st/stm32mp_pmic.h
new file mode 100644 (file)
index 0000000..700039b
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP_PMIC_H
+#define STM32MP_PMIC_H
+
+#include <stdbool.h>
+
+#include <platform_def.h>
+
+bool dt_check_pmic(void);
+int dt_pmic_enable_boot_on_regulators(void);
+void initialize_pmic_i2c(void);
+void initialize_pmic(void);
+int pmic_ddr_power_init(enum ddr_type ddr_type);
+
+#endif /* STM32MP_PMIC_H */
diff --git a/include/drivers/st/stpmic1.h b/include/drivers/st/stpmic1.h
new file mode 100644 (file)
index 0000000..f7e293b
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STPMIC1_H
+#define STPMIC1_H
+
+#include <drivers/st/stm32_i2c.h>
+#include <lib/utils_def.h>
+
+#define TURN_ON_REG                    0x1U
+#define TURN_OFF_REG                   0x2U
+#define ICC_LDO_TURN_OFF_REG           0x3U
+#define ICC_BUCK_TURN_OFF_REG          0x4U
+#define RESET_STATUS_REG               0x5U
+#define VERSION_STATUS_REG             0x6U
+#define MAIN_CONTROL_REG               0x10U
+#define PADS_PULL_REG                  0x11U
+#define BUCK_PULL_DOWN_REG             0x12U
+#define LDO14_PULL_DOWN_REG            0x13U
+#define LDO56_PULL_DOWN_REG            0x14U
+#define VIN_CONTROL_REG                        0x15U
+#define PONKEY_TIMER_REG               0x16U
+#define MASK_RANK_BUCK_REG             0x17U
+#define MASK_RESET_BUCK_REG            0x18U
+#define MASK_RANK_LDO_REG              0x19U
+#define MASK_RESET_LDO_REG             0x1AU
+#define WATCHDOG_CONTROL_REG           0x1BU
+#define WATCHDOG_TIMER_REG             0x1CU
+#define BUCK_ICC_TURNOFF_REG           0x1DU
+#define LDO_ICC_TURNOFF_REG            0x1EU
+#define BUCK_APM_CONTROL_REG           0x1FU
+#define BUCK1_CONTROL_REG              0x20U
+#define BUCK2_CONTROL_REG              0x21U
+#define BUCK3_CONTROL_REG              0x22U
+#define BUCK4_CONTROL_REG              0x23U
+#define VREF_DDR_CONTROL_REG           0x24U
+#define LDO1_CONTROL_REG               0x25U
+#define LDO2_CONTROL_REG               0x26U
+#define LDO3_CONTROL_REG               0x27U
+#define LDO4_CONTROL_REG               0x28U
+#define LDO5_CONTROL_REG               0x29U
+#define LDO6_CONTROL_REG               0x2AU
+#define BUCK1_PWRCTRL_REG              0x30U
+#define BUCK2_PWRCTRL_REG              0x31U
+#define BUCK3_PWRCTRL_REG              0x32U
+#define BUCK4_PWRCTRL_REG              0x33U
+#define VREF_DDR_PWRCTRL_REG           0x34U
+#define LDO1_PWRCTRL_REG               0x35U
+#define LDO2_PWRCTRL_REG               0x36U
+#define LDO3_PWRCTRL_REG               0x37U
+#define LDO4_PWRCTRL_REG               0x38U
+#define LDO5_PWRCTRL_REG               0x39U
+#define LDO6_PWRCTRL_REG               0x3AU
+#define FREQUENCY_SPREADING_REG                0x3BU
+#define USB_CONTROL_REG                        0x40U
+#define ITLATCH1_REG                   0x50U
+#define ITLATCH2_REG                   0x51U
+#define ITLATCH3_REG                   0x52U
+#define ITLATCH4_REG                   0x53U
+#define ITSETLATCH1_REG                        0x60U
+#define ITSETLATCH2_REG                        0x61U
+#define ITSETLATCH3_REG                        0x62U
+#define ITSETLATCH4_REG                        0x63U
+#define ITCLEARLATCH1_REG              0x70U
+#define ITCLEARLATCH2_REG              0x71U
+#define ITCLEARLATCH3_REG              0x72U
+#define ITCLEARLATCH4_REG              0x73U
+#define ITMASK1_REG                    0x80U
+#define ITMASK2_REG                    0x81U
+#define ITMASK3_REG                    0x82U
+#define ITMASK4_REG                    0x83U
+#define ITSETMASK1_REG                 0x90U
+#define ITSETMASK2_REG                 0x91U
+#define ITSETMASK3_REG                 0x92U
+#define ITSETMASK4_REG                 0x93U
+#define ITCLEARMASK1_REG               0xA0U
+#define ITCLEARMASK2_REG               0xA1U
+#define ITCLEARMASK3_REG               0xA2U
+#define ITCLEARMASK4_REG               0xA3U
+#define ITSOURCE1_REG                  0xB0U
+#define ITSOURCE2_REG                  0xB1U
+#define ITSOURCE3_REG                  0xB2U
+#define ITSOURCE4_REG                  0xB3U
+
+/* Registers masks */
+#define LDO_VOLTAGE_MASK               0x7CU
+#define BUCK_VOLTAGE_MASK              0xFCU
+#define LDO_BUCK_VOLTAGE_SHIFT         2
+#define LDO_BUCK_ENABLE_MASK           0x01U
+#define LDO_BUCK_HPLP_ENABLE_MASK      0x02U
+#define LDO_BUCK_HPLP_SHIFT            1
+#define LDO_BUCK_RANK_MASK             0x01U
+#define LDO_BUCK_RESET_MASK            0x01U
+#define LDO_BUCK_PULL_DOWN_MASK                0x03U
+
+/* Pull down register */
+#define BUCK1_PULL_DOWN_SHIFT          0
+#define BUCK2_PULL_DOWN_SHIFT          2
+#define BUCK3_PULL_DOWN_SHIFT          4
+#define BUCK4_PULL_DOWN_SHIFT          6
+#define VREF_DDR_PULL_DOWN_SHIFT       4
+
+/* Buck Mask reset register */
+#define BUCK1_MASK_RESET               0
+#define BUCK2_MASK_RESET               1
+#define BUCK3_MASK_RESET               2
+#define BUCK4_MASK_RESET               3
+
+/* LDO Mask reset register */
+#define LDO1_MASK_RESET                        0
+#define LDO2_MASK_RESET                        1
+#define LDO3_MASK_RESET                        2
+#define LDO4_MASK_RESET                        3
+#define LDO5_MASK_RESET                        4
+#define LDO6_MASK_RESET                        5
+#define VREF_DDR_MASK_RESET            6
+
+/* Main PMIC Control Register (MAIN_CONTROL_REG) */
+#define ICC_EVENT_ENABLED              BIT(4)
+#define PWRCTRL_POLARITY_HIGH          BIT(3)
+#define PWRCTRL_PIN_VALID              BIT(2)
+#define RESTART_REQUEST_ENABLED                BIT(1)
+#define SOFTWARE_SWITCH_OFF_ENABLED    BIT(0)
+
+/* Main PMIC PADS Control Register (PADS_PULL_REG) */
+#define WAKEUP_DETECTOR_DISABLED       BIT(4)
+#define PWRCTRL_PD_ACTIVE              BIT(3)
+#define PWRCTRL_PU_ACTIVE              BIT(2)
+#define WAKEUP_PD_ACTIVE               BIT(1)
+#define PONKEY_PU_ACTIVE               BIT(0)
+
+/* Main PMIC VINLOW Control Register (VIN_CONTROL_REGC DMSC) */
+#define SWIN_DETECTOR_ENABLED          BIT(7)
+#define SWOUT_DETECTOR_ENABLED          BIT(6)
+#define VINLOW_HYST_MASK               0x3
+#define VINLOW_HYST_SHIFT              4
+#define VINLOW_THRESHOLD_MASK          0x7
+#define VINLOW_THRESHOLD_SHIFT         1
+#define VINLOW_ENABLED                 0x01
+#define VINLOW_CTRL_REG_MASK           0xFF
+
+/* USB Control Register */
+#define BOOST_OVP_DISABLED             BIT(7)
+#define VBUS_OTG_DETECTION_DISABLED    BIT(6)
+#define OCP_LIMIT_HIGH                 BIT(3)
+#define SWIN_SWOUT_ENABLED             BIT(2)
+#define USBSW_OTG_SWITCH_ENABLED       BIT(1)
+
+int stpmic1_powerctrl_on(void);
+int stpmic1_switch_off(void);
+int stpmic1_register_read(uint8_t register_id, uint8_t *value);
+int stpmic1_register_write(uint8_t register_id, uint8_t value);
+int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask);
+int stpmic1_regulator_enable(const char *name);
+int stpmic1_regulator_disable(const char *name);
+uint8_t stpmic1_is_regulator_enabled(const char *name);
+int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts);
+int stpmic1_regulator_voltage_get(const char *name);
+int stpmic1_regulator_pull_down_set(const char *name);
+int stpmic1_regulator_mask_reset_set(const char *name);
+void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr);
+
+int stpmic1_get_version(unsigned long *version);
+void stpmic1_dump_regulators(void);
+
+#endif /* STPMIC1_H */
diff --git a/include/drivers/st/stpmu1.h b/include/drivers/st/stpmu1.h
deleted file mode 100644 (file)
index e75d9a6..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STPMU1_H
-#define STPMU1_H
-
-#include <drivers/st/stm32_i2c.h>
-#include <lib/utils_def.h>
-
-#define TURN_ON_REG                    0x1U
-#define TURN_OFF_REG                   0x2U
-#define ICC_LDO_TURN_OFF_REG           0x3U
-#define ICC_BUCK_TURN_OFF_REG          0x4U
-#define RESET_STATUS_REG               0x5U
-#define VERSION_STATUS_REG             0x6U
-#define MAIN_CONTROL_REG               0x10U
-#define PADS_PULL_REG                  0x11U
-#define BUCK_PULL_DOWN_REG             0x12U
-#define LDO14_PULL_DOWN_REG            0x13U
-#define LDO56_PULL_DOWN_REG            0x14U
-#define VIN_CONTROL_REG                        0x15U
-#define PONKEY_TIMER_REG               0x16U
-#define MASK_RANK_BUCK_REG             0x17U
-#define MASK_RESET_BUCK_REG            0x18U
-#define MASK_RANK_LDO_REG              0x19U
-#define MASK_RESET_LDO_REG             0x1AU
-#define WATCHDOG_CONTROL_REG           0x1BU
-#define WATCHDOG_TIMER_REG             0x1CU
-#define BUCK_ICC_TURNOFF_REG           0x1DU
-#define LDO_ICC_TURNOFF_REG            0x1EU
-#define BUCK_APM_CONTROL_REG           0x1FU
-#define BUCK1_CONTROL_REG              0x20U
-#define BUCK2_CONTROL_REG              0x21U
-#define BUCK3_CONTROL_REG              0x22U
-#define BUCK4_CONTROL_REG              0x23U
-#define VREF_DDR_CONTROL_REG           0x24U
-#define LDO1_CONTROL_REG               0x25U
-#define LDO2_CONTROL_REG               0x26U
-#define LDO3_CONTROL_REG               0x27U
-#define LDO4_CONTROL_REG               0x28U
-#define LDO5_CONTROL_REG               0x29U
-#define LDO6_CONTROL_REG               0x2AU
-#define BUCK1_PWRCTRL_REG              0x30U
-#define BUCK2_PWRCTRL_REG              0x31U
-#define BUCK3_PWRCTRL_REG              0x32U
-#define BUCK4_PWRCTRL_REG              0x33U
-#define VREF_DDR_PWRCTRL_REG           0x34U
-#define LDO1_PWRCTRL_REG               0x35U
-#define LDO2_PWRCTRL_REG               0x36U
-#define LDO3_PWRCTRL_REG               0x37U
-#define LDO4_PWRCTRL_REG               0x38U
-#define LDO5_PWRCTRL_REG               0x39U
-#define LDO6_PWRCTRL_REG               0x3AU
-#define FREQUENCY_SPREADING_REG                0x3BU
-#define USB_CONTROL_REG                        0x40U
-#define ITLATCH1_REG                   0x50U
-#define ITLATCH2_REG                   0x51U
-#define ITLATCH3_REG                   0x52U
-#define ITLATCH4_REG                   0x53U
-#define ITSETLATCH1_REG                        0x60U
-#define ITSETLATCH2_REG                        0x61U
-#define ITSETLATCH3_REG                        0x62U
-#define ITSETLATCH4_REG                        0x63U
-#define ITCLEARLATCH1_REG              0x70U
-#define ITCLEARLATCH2_REG              0x71U
-#define ITCLEARLATCH3_REG              0x72U
-#define ITCLEARLATCH4_REG              0x73U
-#define ITMASK1_REG                    0x80U
-#define ITMASK2_REG                    0x81U
-#define ITMASK3_REG                    0x82U
-#define ITMASK4_REG                    0x83U
-#define ITSETMASK1_REG                 0x90U
-#define ITSETMASK2_REG                 0x91U
-#define ITSETMASK3_REG                 0x92U
-#define ITSETMASK4_REG                 0x93U
-#define ITCLEARMASK1_REG               0xA0U
-#define ITCLEARMASK2_REG               0xA1U
-#define ITCLEARMASK3_REG               0xA2U
-#define ITCLEARMASK4_REG               0xA3U
-#define ITSOURCE1_REG                  0xB0U
-#define ITSOURCE2_REG                  0xB1U
-#define ITSOURCE3_REG                  0xB2U
-#define ITSOURCE4_REG                  0xB3U
-#define LDO_VOLTAGE_MASK               0x7CU
-#define BUCK_VOLTAGE_MASK              0xFCU
-#define LDO_BUCK_VOLTAGE_SHIFT         2
-#define LDO_ENABLE_MASK                        0x01U
-#define BUCK_ENABLE_MASK               0x01U
-#define BUCK_HPLP_ENABLE_MASK          0x02U
-#define LDO_HPLP_ENABLE_MASK           0x02U
-#define LDO_BUCK_HPLP_SHIFT            1
-#define LDO_BUCK_RANK_MASK             0x01U
-#define LDO_BUCK_RESET_MASK            0x01U
-#define LDO_BUCK_PULL_DOWN_MASK                0x03U
-
-/* Main PMIC Control Register (MAIN_CONTROL_REG) */
-#define ICC_EVENT_ENABLED              BIT(4)
-#define PWRCTRL_POLARITY_HIGH          BIT(3)
-#define PWRCTRL_PIN_VALID              BIT(2)
-#define RESTART_REQUEST_ENABLED                BIT(1)
-#define SOFTWARE_SWITCH_OFF_ENABLED    BIT(0)
-
-/* Main PMIC PADS Control Register (PADS_PULL_REG) */
-#define WAKEUP_DETECTOR_DISABLED       BIT(4)
-#define PWRCTRL_PD_ACTIVE              BIT(3)
-#define PWRCTRL_PU_ACTIVE              BIT(2)
-#define WAKEUP_PD_ACTIVE               BIT(1)
-#define PONKEY_PU_ACTIVE               BIT(0)
-
-/* Main PMIC VINLOW Control Register (VIN_CONTROL_REGC DMSC) */
-#define SWIN_DETECTOR_ENABLED          BIT(7)
-#define SWOUT_DETECTOR_ENABLED          BIT(6)
-#define VINLOW_HYST_MASK               0x3
-#define VINLOW_HYST_SHIFT              4
-#define VINLOW_THRESHOLD_MASK          0x7
-#define VINLOW_THRESHOLD_SHIFT         1
-#define VINLOW_ENABLED                 0x01
-#define VINLOW_CTRL_REG_MASK           0xFF
-
-/* USB Control Register */
-#define BOOST_OVP_DISABLED             BIT(7)
-#define VBUS_OTG_DETECTION_DISABLED    BIT(6)
-#define OCP_LIMIT_HIGH                 BIT(3)
-#define SWIN_SWOUT_ENABLED             BIT(2)
-#define USBSW_OTG_SWITCH_ENABLED       BIT(1)
-
-int stpmu1_switch_off(void);
-int stpmu1_register_read(uint8_t register_id, uint8_t *value);
-int stpmu1_register_write(uint8_t register_id, uint8_t value);
-int stpmu1_register_update(uint8_t register_id, uint8_t value, uint8_t mask);
-int stpmu1_regulator_enable(const char *name);
-int stpmu1_regulator_disable(const char *name);
-uint8_t stpmu1_is_regulator_enabled(const char *name);
-int stpmu1_regulator_voltage_set(const char *name, uint16_t millivolts);
-void stpmu1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr);
-
-#endif /* STPMU1_H */
diff --git a/include/dt-bindings/interrupt-controller/arm-gic.h b/include/dt-bindings/interrupt-controller/arm-gic.h
new file mode 100644 (file)
index 0000000..aa9158c
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
+/*
+ * This header provides constants for the ARM GIC.
+ */
+
+#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_ARM_GIC_H
+#define _DT_BINDINGS_INTERRUPT_CONTROLLER_ARM_GIC_H
+
+/* interrupt specifier cell 0 */
+
+#define GIC_SPI 0
+#define GIC_PPI 1
+
+#define IRQ_TYPE_NONE          0
+#define IRQ_TYPE_EDGE_RISING   1
+#define IRQ_TYPE_EDGE_FALLING  2
+#define IRQ_TYPE_EDGE_BOTH     (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
+#define IRQ_TYPE_LEVEL_HIGH    4
+#define IRQ_TYPE_LEVEL_LOW     8
+
+#endif
index e2f1f1b44d68024829d4f75f0d3c6144b27b2e9d..7f6e4b94ddd739073d480d7c5573a4872b36f809 100644 (file)
 
 #define STM32_PINMUX(port, line, mode) (((PIN_NO(port, line)) << 8) | (mode))
 
+/*  package information */
+#define STM32MP157CAA  0x1
+#define STM32MP157CAB  0x2
+#define STM32MP157CAC  0x4
+#define STM32MP157CAD  0x8
+
 #endif /* _DT_BINDINGS_STM32_PINFUNC_H */
index a333d1e4e3a3462100ae5493823aa9b276fcc8b8..30eb5e9ec4991abe318a8aeb7a10eb9fb967c2d4 100644 (file)
@@ -63,8 +63,7 @@
  * is 1.
  *
  * Note that this macro assumes that the given virtual address space size is
- * valid. Therefore, the caller is expected to check it is the case using the
- * CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
+ * valid.
  */
 #define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_sz)                 \
        (((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) ?  \
index cc5624c91e3a95eeee5d6d4d7793d4578e8792ad..3014c8fea44d21953375ecf48c9508ca6c114915 100644 (file)
@@ -43,14 +43,22 @@ unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr);
  * state.
  *
  * TCR.TxSZ is calculated as 64 minus the width of said address space.
- * The value of TCR.TxSZ must be in the range 16 to 39 [1], which means that
- * the virtual address space width must be in the range 48 to 25 bits.
+ * The value of TCR.TxSZ must be in the range 16 to 39 [1] or 48 [2],
+ * depending on Small Translation Table Support which means that
+ * the virtual address space width must be in the range 48 to 25 or 16 bits.
  *
  * [1] See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
  * information:
  * Page 1730: 'Input address size', 'For all translation stages'.
+ * [2] See section 12.2.55 in the ARMv8-A Architecture Reference Manual
+ * (DDI 0487D.a)
  */
+/* Maximum value of TCR_ELx.T(0,1)SZ is 39 */
 #define MIN_VIRT_ADDR_SPACE_SIZE       (ULL(1) << (U(64) - TCR_TxSZ_MAX))
+
+/* Maximum value of TCR_ELx.T(0,1)SZ is 48 */
+#define MIN_VIRT_ADDR_SPACE_SIZE_TTST  \
+                               (ULL(1) << (U(64) - TCR_TxSZ_MAX_TTST))
 #define MAX_VIRT_ADDR_SPACE_SIZE       (ULL(1) << (U(64) - TCR_TxSZ_MIN))
 
 /*
@@ -58,9 +66,13 @@ unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr);
  * virtual address space size. For a 4 KB page size,
  * - level 0 supports virtual address spaces of widths 48 to 40 bits;
  * - level 1 from 39 to 31;
- * - level 2 from 30 to 25.
+ * - level 2 from 30 to 22.
+ * - level 3 from 21 to 16.
  *
- * Wider or narrower address spaces are not supported. As a result, level 3
+ * Small Translation Table (Armv8.4-TTST) support allows the starting level
+ * of the translation table from 3 for 4KB granularity. See section 12.2.55 in
+ * the ARMv8-A Architecture Reference Manual (DDI 0487D.a). In Armv8.3 and below
+ * wider or narrower address spaces are not supported. As a result, level 3
  * cannot be used as initial lookup level with 4 KB granularity. See section
  * D4.2.5 in the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
  * information.
@@ -71,13 +83,14 @@ unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr);
  * is 1.
  *
  * Note that this macro assumes that the given virtual address space size is
- * valid. Therefore, the caller is expected to check it is the case using the
- * CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
+ * valid.
  */
 #define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_sz)         \
        (((_virt_addr_space_sz) > (ULL(1) << L0_XLAT_ADDRESS_SHIFT))    \
        ? 0U                                                            \
-        : (((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) \
-        ? 1U : 2U))
+       : (((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT))  \
+       ? 1U                                                            \
+       : (((_virt_addr_space_sz) > (ULL(1) << L2_XLAT_ADDRESS_SHIFT))  \
+       ? 2U : 3U)))
 
 #endif /* XLAT_TABLES_AARCH64_H */
index 251b0206ac050f6d6d591307cf300a2139d29b6e..723753403be174d4e30e7d271a83d033c8a336c8 100644 (file)
 #include "aarch64/xlat_tables_aarch64.h"
 #endif
 
-/*
- * Evaluates to 1 if the given virtual address space size is valid, or 0 if it's
- * not.
- *
- * A valid size is one that is a power of 2 and is within the architectural
- * limits. Not that these limits are different for AArch32 and AArch64.
- */
-#define CHECK_VIRT_ADDR_SPACE_SIZE(size)                       \
-       (((unsigned long long)(size) >= MIN_VIRT_ADDR_SPACE_SIZE) &&    \
-       ((unsigned long long)(size) <= MAX_VIRT_ADDR_SPACE_SIZE) &&     \
-       IS_POWER_OF_TWO(size))
-
 /*
  * Evaluates to 1 if the given physical address space size is a power of 2,
  * or 0 if it's not.
index ce5cf820a0e5132c06d639d47fd4bc0b05dc0a28..6a1be3258ce00e48002368f9527a5cf69ad78554 100644 (file)
@@ -125,9 +125,6 @@ struct xlat_ctx {
 #define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count,                \
                        _xlat_tables_count, _virt_addr_space_size,      \
                        _phy_addr_space_size, _xlat_regime, _section_name)\
-       CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size),      \
-               assert_invalid_virtual_addr_space_size_for_##_ctx_name);\
-                                                                       \
        CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size),        \
                assert_invalid_physical_addr_space_sizefor_##_ctx_name);\
                                                                        \
index 6cca38909ac2a291ef418bcf173a737e0049c868..a77ea96ef391bd9a7d147103f5ece3efc5394c84 100644 (file)
@@ -8,11 +8,10 @@
 #define BOARD_CSS_DEF_H
 
 #include <lib/utils_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
 #include <plat/common/common_def.h>
 
-#include <soc_css_def.h>
-#include <v2m_def.h>
-
 /*
  * Definitions common to all ARM CSS-based development platforms
  */
index c5de407af511bf1f04fca23f310cb3282c38dc8e..6a6979c9c3a5eef1d024ab445368b82730f4ac07 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef V2M_DEF_H
 #define V2M_DEF_H
 
-#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <lib/utils_def.h>
 
 /* V2M motherboard system registers & offsets */
 #define V2M_SYSREGS_BASE               UL(0x1c010000)
index 4e9c70aa10626b271c556c01a362144ef67f58fb..62623c1bf0340967b172c6099acd4a763f1dba72 100644 (file)
@@ -6,8 +6,6 @@
 #ifndef ARM_DEF_H
 #define ARM_DEF_H
 
-#include <platform_def.h>
-
 #include <arch.h>
 #include <common/interrupt_props.h>
 #include <common/tbbr/tbbr_img_def.h>
  * 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_TB_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_TB_FW_CONFIG_LIMIT
+#define ARM_BL2_MEM_DESC_LIMIT         (ARM_BL2_MEM_DESC_BASE +        \
+                                                       (PAGE_SIZE / 2U))
+
+/*
+ * Define limit of firmware configuration memory:
+ * ARM_TB_FW_CONFIG + ARM_BL2_MEM_DESC memory
+ */
+#define ARM_FW_CONFIG_LIMIT            (ARM_BL_RAM_BASE + PAGE_SIZE)
 
 /*******************************************************************************
  * BL1 specific defines.
  * SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM (excluding
  * the page reserved for fw_configs) to BL32
  */
-#  define BL32_BASE                    ARM_TB_FW_CONFIG_LIMIT
+#  define BL32_BASE                    ARM_FW_CONFIG_LIMIT
 #  define BL32_LIMIT                   (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
 # else
 /* Put BL32 below BL2 in the Trusted SRAM.*/
 #  define TSP_SEC_MEM_BASE             ARM_BL_RAM_BASE
 #  define TSP_SEC_MEM_SIZE             ARM_BL_RAM_SIZE
 #  define TSP_PROGBITS_LIMIT           BL31_BASE
-#  define BL32_BASE                    ARM_TB_FW_CONFIG_LIMIT
+#  define BL32_BASE                    ARM_FW_CONFIG_LIMIT
 #  define BL32_LIMIT                   BL31_BASE
 # elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_DRAM_ID
 #  define TSP_SEC_MEM_BASE             PLAT_ARM_TRUSTED_DRAM_BASE
index bdcbc96aff31d5eecd7dfab0c7740fb7d839bf36..16c806ba6c301d6fff8dc7f87a3ef16bd752ae3e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,8 +9,6 @@
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
-#include <arm_def.h>
-
 /*
  * Reserve 4 MiB for binaries of Secure Partitions and Resource Description
  * blobs.
@@ -34,7 +32,7 @@
 #define PLAT_SPM_HEAP_BASE     (PLAT_SP_PACKAGE_BASE + PLAT_SP_PACKAGE_SIZE)
 #define PLAT_SPM_HEAP_SIZE     (BL32_LIMIT - BL32_BASE - PLAT_SP_PACKAGE_SIZE)
 
-#if SPM_DEPRECATED
+#if SPM_MM
 
 /*
  * If BL31 is placed in DRAM, place the Secure Partition in DRAM right after the
  * requests. Mapped as RW and NS. Placed after the shared memory between EL3 and
  * S-EL0.
  */
-#define ARM_SP_IMAGE_NS_BUF_BASE       (PLAT_SPM_BUF_BASE + PLAT_SPM_BUF_SIZE)
-#define ARM_SP_IMAGE_NS_BUF_SIZE       ULL(0x10000)
+#define PLAT_SP_IMAGE_NS_BUF_BASE      (PLAT_SPM_BUF_BASE + PLAT_SPM_BUF_SIZE)
+#define PLAT_SP_IMAGE_NS_BUF_SIZE      ULL(0x10000)
 #define ARM_SP_IMAGE_NS_BUF_MMAP       MAP_REGION2(                            \
-                                               ARM_SP_IMAGE_NS_BUF_BASE,       \
-                                               ARM_SP_IMAGE_NS_BUF_BASE,       \
-                                               ARM_SP_IMAGE_NS_BUF_SIZE,       \
+                                               PLAT_SP_IMAGE_NS_BUF_BASE,      \
+                                               PLAT_SP_IMAGE_NS_BUF_BASE,      \
+                                               PLAT_SP_IMAGE_NS_BUF_SIZE,      \
                                                MT_RW_DATA | MT_NS | MT_USER,   \
                                                PAGE_SIZE)
 
 /* Total number of memory regions with distinct properties */
 #define ARM_SP_IMAGE_NUM_MEM_REGIONS   6
 
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
 
 /* Cookies passed to the Secure Partition at boot. Not used by ARM platforms. */
 #define PLAT_SPM_COOKIE_0              ULL(0)
index 628160824535d458065d864c2c89ea67bfb88ce8..9d6786f5e3e71c75d642ac9818357fd535f046eb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -38,7 +38,7 @@ typedef struct arm_tzc_regions_info {
  *   - Region 1 with secure access only;
  *   - the remaining DRAM regions access from the given Non-Secure masters.
  ******************************************************************************/
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
 #define ARM_TZC_REGIONS_DEF                                            \
        {ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END,                  \
                TZC_REGION_S_RDWR, 0},                                  \
@@ -46,8 +46,8 @@ typedef struct arm_tzc_regions_info {
                PLAT_ARM_TZC_NS_DEV_ACCESS},                            \
        {ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS,       \
                PLAT_ARM_TZC_NS_DEV_ACCESS},                            \
-       {ARM_SP_IMAGE_NS_BUF_BASE, (ARM_SP_IMAGE_NS_BUF_BASE +          \
-               ARM_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE,       \
+       {PLAT_SP_IMAGE_NS_BUF_BASE, (PLAT_SP_IMAGE_NS_BUF_BASE +        \
+               PLAT_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE,      \
                PLAT_ARM_TZC_NS_DEV_ACCESS}
 
 #else
@@ -188,6 +188,7 @@ void arm_bl2_plat_arch_setup(void);
 uint32_t arm_get_spsr_for_bl32_entry(void);
 uint32_t arm_get_spsr_for_bl33_entry(void);
 int arm_bl2_handle_post_image_load(unsigned int image_id);
+struct bl_params *arm_get_next_bl_params(void);
 
 /* BL2 at EL3 functions */
 void arm_bl2_el3_early_platform_setup(void);
index 6b355a4e9e6fdcbcbf2d4ac4b3a6c8e60f16c98e..575db04f4067fc5f05647b3358a064eec8dbde32 100644 (file)
@@ -11,8 +11,6 @@
 #include <drivers/arm/gic_common.h>
 #include <drivers/arm/tzc400.h>
 
-#include <arm_def.h>
-
 /*************************************************************************
  * Definitions common to all ARM Compute SubSystems (CSS)
  *************************************************************************/
index c81e9048140eea6063ce07ce9073b3728e70bb88..c11132696ca3d8eee027011a81d81091c1f7f3c7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #ifndef MM_SVC_H
 #define MM_SVC_H
 
-#if SPM_DEPRECATED
+#if SPM_MM
 
 #include <lib/utils_def.h>
 
@@ -30,6 +30,6 @@
 #define MM_COMMUNICATE_AARCH64         U(0xC4000041)
 #define MM_COMMUNICATE_AARCH32         U(0x84000041)
 
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
 
 #endif /* MM_SVC_H */
index 47f63684f35e9e4e011deffcf95441a17d4fb13c..0510f80ece0bf4166bf5f343159216dba2ab42ca 100644 (file)
@@ -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
  */
@@ -7,7 +7,7 @@
 #ifndef SECURE_PARTITION_H
 #define SECURE_PARTITION_H
 
-#if SPM_DEPRECATED
+#if SPM_MM
 
 #include <stdint.h>
 
@@ -49,6 +49,6 @@ typedef struct secure_partition_boot_info {
        secure_partition_mp_info_t      *mp_info;
 } secure_partition_boot_info_t;
 
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
 
 #endif /* SECURE_PARTITION_H */
index fcb409b293d35a85f710919d5fd9591f1684ff74..57912e883488bb73c94e7a3a03d047d17aabec65 100644 (file)
@@ -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
  */
@@ -7,7 +7,7 @@
 #ifndef SPM_SVC_H
 #define SPM_SVC_H
 
-#if SPM_DEPRECATED
+#if SPM_MM
 
 #include <lib/utils_def.h>
 
@@ -61,7 +61,7 @@
 #define SPM_DENIED             -3
 #define SPM_NO_MEMORY          -5
 
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
 
 #ifndef __ASSEMBLY__
 
@@ -69,7 +69,7 @@
 
 int32_t spm_setup(void);
 
-#if SPM_DEPRECATED
+#if SPM_MM
 
 uint64_t spm_smc_handler(uint32_t smc_fid,
                         uint64_t x1,
@@ -83,7 +83,7 @@ uint64_t spm_smc_handler(uint32_t smc_fid,
 /* Helper to enter a Secure Partition */
 uint64_t spm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3);
 
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
 
 #endif /* __ASSEMBLY__ */
 
index a8f2e74200f7786edcd69de35098f634eb2007ad..0b36cb6cf43d63a462db210bc18c5ee1faca93e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
  *     unsigned denominator);
  */
 
-/* struct qr - stores qutient/remainder to handle divmod EABI interfaces. */
+/* struct qr - stores quotient/remainder to handle divmod EABI interfaces. */
 struct qr {
        unsigned int q;         /* computed quotient */
        unsigned int r;         /* computed remainder */
-       unsigned int q_n;       /* specficies if quotient shall be negative */
-       unsigned int r_n;       /* specficies if remainder shall be negative */
+       unsigned int q_n;       /* specifies if quotient shall be negative */
+       unsigned int r_n;       /* specifies if remainder shall be negative */
 };
 
 static void uint_div_qr(unsigned int numerator, unsigned int denominator,
index 8a5764ce235f6a126f3cfb3c77f7f7f364d28155..b956491e3e84b7efc79a32b79a7e895333cfa030 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -55,7 +55,7 @@ void __init cm_init(void)
  * The security state to initialize is determined by the SECURE attribute
  * of the entry_point_info.
  *
- * The EE and ST attributes are used to configure the endianess and secure
+ * The EE and ST attributes are used to configure the endianness and secure
  * timer availability for the new execution context.
  *
  * To prepare the register state for entry call cm_prepare_el3_exit() and
@@ -124,7 +124,7 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
 
 #ifdef IMAGE_BL31
        /*
-        * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ rounting as
+        * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
         *  indicated by the interrupt routing model for BL31.
         */
        scr_el3 |= get_scr_el3_from_routing_model(security_state);
@@ -175,7 +175,7 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
 
        /*
         * Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2
-        * and other EL2 registers are set up by cm_preapre_ns_entry() as they
+        * and other EL2 registers are set up by cm_prepare_ns_entry() as they
         * are not part of the stored cpu_context.
         */
        write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
@@ -350,7 +350,7 @@ void cm_prepare_el3_exit(uint32_t security_state)
                                        | CPTR_EL2_TFP_BIT));
 
                        /*
-                        * Initiliase CNTHCTL_EL2. All fields are
+                        * Initialise CNTHCTL_EL2. All fields are
                         * architecturally UNKNOWN on reset and are set to zero
                         * except for field(s) listed below.
                         *
index 662f6a05aee3345dab886f4f7621e76fc9a6acdc..08bccf64bae99f0eb6e4331d1ca87fde5f426af2 100644 (file)
@@ -6,7 +6,9 @@
 
 #include <assert.h>
 
+#include <common/debug.h>
 #include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
 
 /*
  * All the regions defined in mem_region_t must have the following properties
index 468a9e7dd695140608cf5f6d8c7db91212ef4dec..4b01b9b7ab171f5ebdecfeabe1442ee56c19e85c 100644 (file)
@@ -55,6 +55,11 @@ void init_xlat_tables(void)
 {
        unsigned long long max_pa;
        uintptr_t max_va;
+
+       assert(PLAT_VIRT_ADDR_SPACE_SIZE >= MIN_VIRT_ADDR_SPACE_SIZE);
+       assert(PLAT_VIRT_ADDR_SPACE_SIZE <= MAX_VIRT_ADDR_SPACE_SIZE);
+       assert(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE));
+
        print_mmap();
        init_xlation_table(0U, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
                                                &max_va, &max_pa);
index 71f491a2192183b86aabebd0dc8524d691781291..e64fd3ef73218cbfd57000365dace96116f100b8 100644 (file)
@@ -10,7 +10,7 @@
 #include <platform_def.h>
 
 #include <arch.h>
-#include <arch_helpers.h>
+#include <arch_features.h>
 #include <common/bl_common.h>
 #include <lib/utils.h>
 #include <lib/xlat_tables/xlat_tables.h>
@@ -79,6 +79,21 @@ static unsigned long long get_max_supported_pa(void)
 
        return (1ULL << pa_range_bits_arr[pa_range]) - 1ULL;
 }
+
+/*
+ * Return minimum virtual address space size supported by the architecture
+ */
+static uintptr_t xlat_get_min_virt_addr_space_size(void)
+{
+       uintptr_t ret;
+
+       if (is_armv8_4_ttst_present())
+               ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
+       else
+               ret = MIN_VIRT_ADDR_SPACE_SIZE;
+
+       return ret;
+}
 #endif /* ENABLE_ASSERTIONS */
 
 unsigned int xlat_arch_current_el(void)
@@ -104,6 +119,12 @@ void init_xlat_tables(void)
 {
        unsigned long long max_pa;
        uintptr_t max_va;
+
+       assert(PLAT_VIRT_ADDR_SPACE_SIZE >=
+               (xlat_get_min_virt_addr_space_size() - 1U));
+       assert(PLAT_VIRT_ADDR_SPACE_SIZE <= MAX_VIRT_ADDR_SPACE_SIZE);
+       assert(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE));
+
        print_mmap();
        init_xlation_table(0U, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
                           &max_va, &max_pa);
index 4390f34ead7e390170caf92bd74f2efc9f6b77bd..82bc70cd013f031c614b4bee3d452b7b127cb146 100644 (file)
@@ -16,9 +16,6 @@
 #error xlat tables v2 must be used with HW_ASSISTED_COHERENCY
 #endif
 
-CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(PLAT_VIRT_ADDR_SPACE_SIZE),
-       assert_valid_virt_addr_space_size);
-
 CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(PLAT_PHY_ADDR_SPACE_SIZE),
        assert_valid_phy_addr_space_size);
 
index 349b6c4d50d9362890eb392412311d7185c5a62e..b69c6702ba9d10c6601db0d4f776496b7b7afac2 100644 (file)
@@ -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
  */
@@ -10,6 +10,7 @@
 #include <platform_def.h>
 
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <lib/cassert.h>
 #include <lib/utils_def.h>
@@ -44,6 +45,14 @@ unsigned long long xlat_arch_get_max_supported_pa(void)
        /* Physical address space size for long descriptor format. */
        return (1ULL << 40) - 1ULL;
 }
+
+/*
+ * Return minimum virtual address space size supported by the architecture
+ */
+uintptr_t xlat_get_min_virt_addr_space_size(void)
+{
+       return MIN_VIRT_ADDR_SPACE_SIZE;
+}
 #endif /* ENABLE_ASSERTIONS*/
 
 bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
@@ -192,7 +201,12 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags,
        if (max_va != UINT32_MAX) {
                uintptr_t virtual_addr_space_size = max_va + 1U;
 
-               assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
+               assert(virtual_addr_space_size >=
+                       xlat_get_min_virt_addr_space_size());
+               assert(virtual_addr_space_size <=
+                       MAX_VIRT_ADDR_SPACE_SIZE);
+               assert(IS_POWER_OF_TWO(virtual_addr_space_size));
+
                /*
                 * __builtin_ctzll(0) is undefined but here we are guaranteed
                 * that virtual_addr_space_size is in the range [1, UINT32_MAX].
@@ -219,13 +233,10 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags,
        /* Set TTBR0 bits as well */
        ttbr0 = (uint64_t)(uintptr_t) base_table;
 
-#if ARM_ARCH_AT_LEAST(8, 2)
-       /*
-        * Enable CnP bit so as to share page tables with all PEs. This
-        * is mandatory for ARMv8.2 implementations.
-        */
-       ttbr0 |= TTBR_CNP_BIT;
-#endif
+       if (is_armv8_2_ttcnp_present()) {
+               /* Enable CnP bit so as to share page tables with all PEs. */
+               ttbr0 |= TTBR_CNP_BIT;
+       }
 
        /* Now populate MMU configuration */
        params[MMU_CFG_MAIR] = mair;
index a803d8357f85f42d80bd82fca0fdc4486791bedd..e7593dde76581799be3c0c3d6f8cf8c68a855fe5 100644 (file)
@@ -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
  */
@@ -9,6 +9,7 @@
 #include <stdint.h>
 
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <lib/cassert.h>
 #include <lib/utils_def.h>
@@ -100,6 +101,21 @@ unsigned long long xlat_arch_get_max_supported_pa(void)
 
        return (1ULL << pa_range_bits_arr[pa_range]) - 1ULL;
 }
+
+/*
+ * Return minimum virtual address space size supported by the architecture
+ */
+uintptr_t xlat_get_min_virt_addr_space_size(void)
+{
+       uintptr_t ret;
+
+       if (is_armv8_4_ttst_present())
+               ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
+       else
+               ret = MIN_VIRT_ADDR_SPACE_SIZE;
+
+       return ret;
+}
 #endif /* ENABLE_ASSERTIONS*/
 
 bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
@@ -220,7 +236,11 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags,
        assert(max_va < ((uint64_t)UINTPTR_MAX));
 
        virtual_addr_space_size = (uintptr_t)max_va + 1U;
-       assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
+
+       assert(virtual_addr_space_size >=
+               xlat_get_min_virt_addr_space_size());
+       assert(virtual_addr_space_size <= MAX_VIRT_ADDR_SPACE_SIZE);
+       assert(IS_POWER_OF_TWO(virtual_addr_space_size));
 
        /*
         * __builtin_ctzll(0) is undefined but here we are guaranteed that
@@ -266,13 +286,10 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags,
        /* Set TTBR bits as well */
        ttbr0 = (uint64_t) base_table;
 
-#if ARM_ARCH_AT_LEAST(8, 2)
-       /*
-        * Enable CnP bit so as to share page tables with all PEs. This
-        * is mandatory for ARMv8.2 implementations.
-        */
-       ttbr0 |= TTBR_CNP_BIT;
-#endif
+       if (is_armv8_2_ttcnp_present()) {
+               /* Enable CnP bit so as to share page tables with all PEs. */
+               ttbr0 |= TTBR_CNP_BIT;
+       }
 
        params[MMU_CFG_MAIR] = mair;
        params[MMU_CFG_TCR] = tcr;
index c49554f1f12dc0eedb31e8e51d37b077fa50ca17..4820b4f8052f2936e27c074c62b1213a0e7894ab 100644 (file)
@@ -1146,6 +1146,11 @@ void __init init_xlat_tables_ctx(xlat_ctx_t *ctx)
 
        mmap_region_t *mm = ctx->mmap;
 
+       assert(ctx->va_max_address >=
+               (xlat_get_min_virt_addr_space_size() - 1U));
+       assert(ctx->va_max_address <= (MAX_VIRT_ADDR_SPACE_SIZE - 1U));
+       assert(IS_POWER_OF_TWO(ctx->va_max_address + 1U));
+
        xlat_mmap_print(mm);
 
        /* All tables must be zeroed before mapping any region. */
index fc709554bb0bf76462d5ff7e26954171187e542c..70ef395235d004b85e05d8de3753326c5ce08d78 100644 (file)
@@ -102,4 +102,9 @@ bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx);
 /* Returns true if the data cache is enabled at the current EL. */
 bool is_dcache_enabled(void);
 
+/*
+ * Returns minimum virtual address space size supported by the architecture
+ */
+uintptr_t xlat_get_min_virt_addr_space_size(void);
+
 #endif /* XLAT_TABLES_PRIVATE_H */
index 37766ed433b67ca45e74f46e7ba4f32c7235088d..f53dda52973fd9b882df1e53a9521b3ea3270f15 100644 (file)
@@ -144,6 +144,13 @@ NXP i.MX 8 platform port
 :F: docs/plat/imx8.rst
 :F: plat/imx/
 
+NXP i.MX8M platform port
+------------------------
+:M: Jacky Bai <ping.bai@nxp.com>
+:G: `JackyBai`_
+:F: doc/plat/imx8m.rst
+:F: plat/imx/imx8m/
+
 OP-TEE dispatcher
 -----------------
 :M: Jens Wiklander <jens.wiklander@linaro.org>
@@ -241,6 +248,7 @@ Xilinx platform port
 .. _etienne-lms: https://github.com/etienne-lms
 .. _glneo: https://github.com/glneo
 .. _hzhuang1: https://github.com/hzhuang1
+.. _JackyBai: https://github.com/JackyBai
 .. _jenswi-linaro: https://github.com/jenswi-linaro
 .. _ldts: https://github.com/ldts
 .. _niej: https://github.com/niej
index d60a5bf0ee8dc9d1629f197922d213e6f081e2f7..73b84c38a3988f776a474b514db6360db445c06f 100644 (file)
@@ -216,10 +216,11 @@ define MAKE_C
 $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 $(eval IMAGE := IMAGE_BL$(call uppercase,$(3)))
+$(eval BL_CFLAGS := $(BL$(call uppercase,$(3))_CFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs
        $$(ECHO) "  CC      $$<"
-       $$(Q)$$(CC) $$(TF_CFLAGS) $$(CFLAGS) -D$(IMAGE) $(MAKE_DEP) -c $$< -o $$@
+       $$(Q)$$(CC) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CFLAGS) -D$(IMAGE) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -463,7 +464,7 @@ $(eval DTBDEP := $(patsubst %.dtb,%.d,$(DOBJ)))
 $(DOBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | fdt_dirs
        $${ECHO} "  CPP     $$<"
        $(eval DTBS       := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
-       $$(Q)$$(CPP) $$(CPPFLAGS) -x assembler-with-cpp -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
+       $$(Q)$$(PP) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
        $${ECHO} "  DTC     $$<"
        $$(Q)$$(DTC) $$(DTC_FLAGS) -i fdts -d $(DTBDEP) -o $$@ $(DPRE)
 
index a55e729b84659171a4d9993799d48101044097bb..8ef1bb9f8892e6319eba8638c732a453ce77f74e 100644 (file)
@@ -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
 #
@@ -162,8 +162,8 @@ SPD                         := none
 # For including the Secure Partition Manager
 ENABLE_SPM                     := 0
 
-# Use the deprecated SPM based on MM
-SPM_DEPRECATED                 := 1
+# Use the SPM based on MM
+SPM_MM                         := 1
 
 # Flag to introduce an infinite loop in BL1 just before it exits into the next
 # image. This is meant to help debugging the post-BL2 phase.
index 320bfb3c349e1e20b7a0bef854d45ebc32ab73b8..8c636933453718feb37f744446fd1c19e9bd4e72 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <asm_macros.S>
 #include <common/bl_common.h>
-#include <v2m_def.h>
+#include <platform_def.h>
 
        .globl  plat_report_exception
 
index 5a905244f48bf653bee913a0715e96ddc782f403..cde6b007c12d728ee8b1593b72b208724501f7ed 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <asm_macros.S>
 #include <common/bl_common.h>
-#include <v2m_def.h>
+#include <platform_def.h>
 
        .globl  plat_report_exception
 
index 64ca3c36d8c705e969ed3e939252ca8709624f75..e3c6805ac66d26514732a21d4305beafb2ba8387 100644 (file)
@@ -11,8 +11,7 @@
 #include <lib/cassert.h>
 #include <plat/common/platform.h>
 #include <tools_share/tbbr_oid.h>
-
-#include <arm_def.h>
+#include <platform_def.h>
 
 /* SHA256 algorithm */
 #define SHA256_BYTES                   32
index 487aad7399ac6e046fec18fbd6183131b1b8b7ed..b98dfd48b28a87ae48810cdfce33afe627b4c0be 100644 (file)
@@ -4,8 +4,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-PLAT_INCLUDES          +=      -Iinclude/plat/arm/board/common/
-
 PLAT_BL_COMMON_SOURCES +=      drivers/arm/pl011/${ARCH}/pl011_console.S       \
                                plat/arm/board/common/${ARCH}/board_arm_helpers.S
 
index 5d88546986f658f0193c96b4be7c8509b6d6bc26..9985c1ddbc4c7d7b1baa57d6cc35ee5ac47f50f2 100644 (file)
@@ -6,9 +6,8 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <platform_def.h>
-#include "../drivers/pwrc/fvp_pwrc.h"
-#include "../fvp_def.h"
 
        .globl  plat_secondary_cold_boot_setup
        .globl  plat_get_my_entrypoint
index 0f905151b4ae5860e77cf0a2e9943914999f8ef7..09f19f6c351eaedece2937913aafa64b7f3d1bd9 100644 (file)
@@ -8,10 +8,8 @@
 #include <asm_macros.S>
 #include <drivers/arm/gicv2.h>
 #include <drivers/arm/gicv3.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <platform_def.h>
-#include <v2m_def.h>
-#include "../drivers/pwrc/fvp_pwrc.h"
-#include "../fvp_def.h"
 
        .globl  plat_secondary_cold_boot_setup
        .globl  plat_get_my_entrypoint
diff --git a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c b/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c
deleted file mode 100644 (file)
index c48bb07..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <lib/bakery_lock.h>
-#include <lib/mmio.h>
-
-#include <plat_arm.h>
-
-#include "../../fvp_def.h"
-#include "../../fvp_private.h"
-#include "fvp_pwrc.h"
-
-/*
- * TODO: Someday there will be a generic power controller api. At the moment
- * each platform has its own pwrc so just exporting functions is fine.
- */
-ARM_INSTANTIATE_LOCK;
-
-unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr)
-{
-       return PSYSR_WK(fvp_pwrc_read_psysr(mpidr));
-}
-
-unsigned int fvp_pwrc_read_psysr(u_register_t mpidr)
-{
-       unsigned int rc;
-       arm_lock_get();
-       mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr);
-       rc = mmio_read_32(PWRC_BASE + PSYSR_OFF);
-       arm_lock_release();
-       return rc;
-}
-
-void fvp_pwrc_write_pponr(u_register_t mpidr)
-{
-       arm_lock_get();
-       mmio_write_32(PWRC_BASE + PPONR_OFF, (unsigned int) mpidr);
-       arm_lock_release();
-}
-
-void fvp_pwrc_write_ppoffr(u_register_t mpidr)
-{
-       arm_lock_get();
-       mmio_write_32(PWRC_BASE + PPOFFR_OFF, (unsigned int) mpidr);
-       arm_lock_release();
-}
-
-void fvp_pwrc_set_wen(u_register_t mpidr)
-{
-       arm_lock_get();
-       mmio_write_32(PWRC_BASE + PWKUPR_OFF,
-                     (unsigned int) (PWKUPR_WEN | mpidr));
-       arm_lock_release();
-}
-
-void fvp_pwrc_clr_wen(u_register_t mpidr)
-{
-       arm_lock_get();
-       mmio_write_32(PWRC_BASE + PWKUPR_OFF,
-                     (unsigned int) mpidr);
-       arm_lock_release();
-}
-
-void fvp_pwrc_write_pcoffr(u_register_t mpidr)
-{
-       arm_lock_get();
-       mmio_write_32(PWRC_BASE + PCOFFR_OFF, (unsigned int) mpidr);
-       arm_lock_release();
-}
-
-/* Nothing else to do here apart from initializing the lock */
-void __init plat_arm_pwrc_setup(void)
-{
-       arm_lock_init();
-}
-
-
-
diff --git a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.h b/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.h
deleted file mode 100644 (file)
index 324f3e2..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef FVP_PWRC_H
-#define FVP_PWRC_H
-
-/* FVP Power controller register offset etc */
-#define PPOFFR_OFF             U(0x0)
-#define PPONR_OFF              U(0x4)
-#define PCOFFR_OFF             U(0x8)
-#define PWKUPR_OFF             U(0xc)
-#define PSYSR_OFF              U(0x10)
-
-#define PWKUPR_WEN             BIT_32(31)
-
-#define PSYSR_AFF_L2           BIT_32(31)
-#define PSYSR_AFF_L1           BIT_32(30)
-#define PSYSR_AFF_L0           BIT_32(29)
-#define PSYSR_WEN              BIT_32(28)
-#define PSYSR_PC               BIT_32(27)
-#define PSYSR_PP               BIT_32(26)
-
-#define PSYSR_WK_SHIFT         24
-#define PSYSR_WK_WIDTH         0x2
-#define PSYSR_WK_MASK          ((1U << PSYSR_WK_WIDTH) - 1U)
-#define PSYSR_WK(x)            ((x) >> PSYSR_WK_SHIFT) & PSYSR_WK_MASK
-
-#define WKUP_COLD              U(0x0)
-#define WKUP_RESET             U(0x1)
-#define WKUP_PPONR             U(0x2)
-#define WKUP_GICREQ            U(0x3)
-
-#define PSYSR_INVALID          U(0xffffffff)
-
-#ifndef __ASSEMBLY__
-
-/*******************************************************************************
- * Function & variable prototypes
- ******************************************************************************/
-void fvp_pwrc_write_pcoffr(u_register_t mpidr);
-void fvp_pwrc_write_ppoffr(u_register_t mpidr);
-void fvp_pwrc_write_pponr(u_register_t mpidr);
-void fvp_pwrc_set_wen(u_register_t mpidr);
-void fvp_pwrc_clr_wen(u_register_t mpidr);
-unsigned int fvp_pwrc_read_psysr(u_register_t mpidr);
-unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr);
-
-#endif /*__ASSEMBLY__*/
-
-#endif /* FVP_PWRC_H */
index d6e82f50d90a76e178085ff13a2e55670373559b..75090e87cb5040ab2c90bdd6cb1535063bc14d49 100644 (file)
@@ -5,10 +5,9 @@
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
 #include "fvp_private.h"
 
 /*******************************************************************************
index 69f2f7adf70bd90bc7416d5dbe1e51e1464a76d2..7def56a7098a72b6ceb6721989c31489ad514e00 100644 (file)
@@ -4,7 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
 #include "fvp_private.h"
 
 void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
index 13e74fd9a3a6b1cece1d9caed9502f5eafd4f962..d28094993d06f089e82b2997ca613b6e0807b7db 100644 (file)
@@ -7,11 +7,10 @@
 #include <drivers/arm/sp804_delay_timer.h>
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <platform_def.h>
 
-#include <plat_arm.h>
-#include <v2m_def.h>
-#include "fvp_def.h"
 #include "fvp_private.h"
 
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
index c51e287f613d39f18a16b7f5f2960d4c42b4592e..a8db055678a8b9c2fc80263a6111f552fa4310aa 100644 (file)
@@ -4,10 +4,10 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <platform_def.h>
 
-#include <plat_arm.h>
-#include "fvp_def.h"
 #include "fvp_private.h"
 
 void bl2u_early_platform_setup(struct meminfo *mem_layout, void *plat_info)
index 5f2121c528c44b7981c789d4f59a386dce0cebfe..7f28b202d692762fc308c7c9a8b79c7f7e316869 100644 (file)
@@ -5,10 +5,10 @@
  */
 
 #include <drivers/arm/smmu_v3.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_config.h>
-#include <plat_arm.h>
 #include "fvp_private.h"
 
 void __init bl31_early_platform_setup2(u_register_t arg0,
index 31a61de4e7aee40d63c7cbbd1911b16009a7c2ec..b885b47a462b58d0d6e6e77891811e335c839c51 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <drivers/arm/gicv2.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_compat.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 <services/secure_partition.h>
 
-#include <arm_config.h>
-#include <arm_def.h>
-#include <arm_spm_def.h>
-#include <plat_arm.h>
-#include <v2m_def.h>
-
-#include "../fvp_def.h"
 #include "fvp_private.h"
 
 /* Defines for GIC Driver build time selection */
@@ -98,10 +94,10 @@ const mmap_region_t plat_arm_mmap[] = {
        ARM_MAP_BL1_RW,
 #endif
 #endif /* TRUSTED_BOARD_BOOT */
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
        ARM_SP_IMAGE_MMAP,
 #endif
-#if ENABLE_SPM && !SPM_DEPRECATED
+#if ENABLE_SPM && !SPM_MM
        PLAT_MAP_SP_PACKAGE_MEM_RW,
 #endif
 #if ARM_BL31_IN_DRAM
@@ -129,16 +125,16 @@ const mmap_region_t plat_arm_mmap[] = {
        MAP_DEVICE0,
        MAP_DEVICE1,
        ARM_V2M_MAP_MEM_PROTECT,
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
        ARM_SPM_BUF_EL3_MMAP,
 #endif
-#if ENABLE_SPM && !SPM_DEPRECATED
+#if ENABLE_SPM && !SPM_MM
        PLAT_MAP_SP_PACKAGE_MEM_RO,
 #endif
        {0}
 };
 
-#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_DEPRECATED
+#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_MM
 const mmap_region_t plat_arm_secure_partition_mmap[] = {
        V2M_MAP_IOFPGA_EL0, /* for the UART */
        MAP_REGION_FLAT(DEVICE0_BASE,                           \
@@ -192,7 +188,7 @@ static unsigned int get_interconnect_master(void)
 }
 #endif
 
-#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_DEPRECATED
+#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_MM
 /*
  * Boot information passed to a secure partition during initialisation. Linear
  * indices in MP information will be filled at runtime.
@@ -218,12 +214,12 @@ const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
        .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 = ARM_SP_IMAGE_NS_BUF_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 = ARM_SP_IMAGE_NS_BUF_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,
index e186b3083872359cc442379ebd007aacc00adc90..9c4c1d574b0dcf3b60d07595d7e80ff483675654 100644 (file)
 #include <drivers/io/io_semihosting.h>
 #include <drivers/io/io_storage.h>
 #include <lib/semihosting.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/common_def.h>
 
-#include <plat_arm.h>
-
 /* Semihosting filenames */
 #define BL2_IMAGE_NAME                 "bl2.bin"
 #define BL31_IMAGE_NAME                        "bl31.bin"
index 7da246bd60953e1ef65271ffcf9bf322d6c52b3a..ecf0b0135bc9e3b190777ab477541f7604e43baf 100644 (file)
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/arm/gicv3.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <lib/extensions/spe.h>
 #include <lib/mmio.h>
 #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 <arm_config.h>
-#include <plat_arm.h>
-#include <v2m_def.h>
-
-#include "../../../../drivers/arm/gic/v3/gicv3_private.h"
-#include "drivers/pwrc/fvp_pwrc.h"
-#include "fvp_def.h"
 #include "fvp_private.h"
 
 
index e7dea9944dc008a490003753f36605b189de39d2..3d9653739c90098c8fad955cdbe0c67a30fd5f67 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef FVP_PRIVATE_H
 #define FVP_PRIVATE_H
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*******************************************************************************
  * Function and variable prototypes
index 028522cfefd9ceb31aa4d8c61d5e645036c1d933..80ec2171b061686a2746d9518c354c27227d3a70 100644 (file)
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <arm_config.h>
-#include <plat_arm.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*
  * We assume that all security programming is done by the primary core.
index 3384a2f7045bd27729a034a5db0572c61f6a8cb4..9823fb3b383c40c2ec4589541a055f01ab134785 100644 (file)
@@ -7,13 +7,12 @@
 #include <platform_def.h>
 
 #include <arch.h>
+#include <drivers/arm/fvp/fvp_pwrc.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 <plat_arm.h>
-#include <arm_config.h>
-#include "drivers/pwrc/fvp_pwrc.h"
-
 /* The FVP power domain tree descriptor */
 static unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 2];
 
index c18bfb21375eaae841243fdeb92cc284a58df976..0d160cb1ddad33c1aca33cfec406db98d1db2ba9 100644 (file)
@@ -9,10 +9,9 @@
 #include <string.h>
 
 #include <plat/common/platform.h>
+#include <platform_def.h>
 #include <tools_share/tbbr_oid.h>
 
-#include "fvp_def.h"
-
 /*
  * Store a new non-volatile counter value. On some FVP versions, the
  * non-volatile counters are RO. On these versions we expect the values in the
index ad2d46c436f7f56517add722f1a100ded799eede..f024f551ae5ad26d6a71fd012970abc99b64e5d3 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef PLAT_LD_S
 #define PLAT_LD_S
 
-#include <arm_tzc_dram.ld.S>
-#include <arm_reclaim_init.ld.S>
+#include <plat/arm/common/arm_tzc_dram.ld.S>
+#include <plat/arm/common/arm_reclaim_init.ld.S>
 
 #endif /* PLAT_LD_S */
index 6be8b093f6682ef4da7bd65525e5104c06690458..57f59248eaf6ef975bac969e1346c3fcd92d4fdf 100644 (file)
@@ -7,8 +7,7 @@
 #define PLAT_MACROS_S
 
 #include <arm_macros.S>
-#include <v2m_def.h>
-#include "../fvp_def.h"
+#include <platform_def.h>
 
        /* ---------------------------------------------
         * The below required platform porting macro
index ca4bd53996aac20401bec6d9e4eb1d35a78e0931..fcf363d7c4a828ea5ebafe5ec1e7c8d2bfe813a1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,25 +7,13 @@
 #ifndef PLATFORM_DEF_H
 #define PLATFORM_DEF_H
 
-/* Enable the dynamic translation tables library. */
-#ifdef AARCH32
-# if defined(IMAGE_BL32) && RESET_TO_SP_MIN
-#  define PLAT_XLAT_TABLES_DYNAMIC     1
-# endif
-#else
-# if defined(IMAGE_BL31) && (RESET_TO_BL31 || (ENABLE_SPM && !SPM_DEPRECATED))
-#  define PLAT_XLAT_TABLES_DYNAMIC     1
-# endif
-#endif /* AARCH32 */
-
 #include <drivers/arm/tzc400.h>
 #include <lib/utils_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/common/common_def.h>
 
-#include <arm_def.h>
-#include <arm_spm_def.h>
-#include <v2m_def.h>
-
 #include "../fvp_def.h"
 
 /* Required platform porting definitions */
  * calculated using the current BL31 PROGBITS debug size plus the sizes of
  * BL2 and BL1-RW
  */
-#if ENABLE_SPM && !SPM_DEPRECATED
+#if ENABLE_SPM && !SPM_MM
 #define PLAT_ARM_MAX_BL31_SIZE         UL(0x60000)
 #else
 #define PLAT_ARM_MAX_BL31_SIZE         UL(0x3B000)
 #define PLAT_ARM_PRIVATE_SDEI_EVENTS   ARM_SDEI_PRIVATE_EVENTS
 #define PLAT_ARM_SHARED_SDEI_EVENTS    ARM_SDEI_SHARED_EVENTS
 
-#define PLAT_ARM_SP_IMAGE_STACK_BASE   (ARM_SP_IMAGE_NS_BUF_BASE +     \
-                                        ARM_SP_IMAGE_NS_BUF_SIZE)
+#define PLAT_ARM_SP_IMAGE_STACK_BASE   (PLAT_SP_IMAGE_NS_BUF_BASE +    \
+                                        PLAT_SP_IMAGE_NS_BUF_SIZE)
 
 #define PLAT_SP_PRI                    PLAT_RAS_PRI
 
index 3b60daadd0513ab7b473c10b3ed1108c55a64f61..f79ac466b403feed9f75ba51b5f7c2c7d9f1f5a4 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -146,14 +146,14 @@ endif
 BL2U_SOURCES           +=      plat/arm/board/fvp/fvp_bl2u_setup.c             \
                                ${FVP_SECURITY_SOURCES}
 
-BL31_SOURCES           +=      drivers/arm/smmu/smmu_v3.c                      \
+BL31_SOURCES           +=      drivers/arm/fvp/fvp_pwrc.c                      \
+                               drivers/arm/smmu/smmu_v3.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_pm.c                     \
                                plat/arm/board/fvp/fvp_topology.c               \
                                plat/arm/board/fvp/aarch64/fvp_helpers.S        \
-                               plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c      \
                                plat/arm/common/arm_nor_psci_mem_protect.c      \
                                ${FVP_CPU_LIBS}                                 \
                                ${FVP_GIC_SOURCES}                              \
@@ -231,6 +231,22 @@ ifeq (${ARCH},aarch32)
     NEED_BL32 := yes
 endif
 
+# Enable the dynamic translation tables library.
+ifeq (${ARCH},aarch32)
+    ifeq (${RESET_TO_SP_MIN},1)
+        BL32_CFLAGS    +=      -DPLAT_XLAT_TABLES_DYNAMIC=1
+    endif
+else
+    ifeq (${RESET_TO_BL31},1)
+        BL31_CFLAGS    +=      -DPLAT_XLAT_TABLES_DYNAMIC=1
+    endif
+    ifeq (${ENABLE_SPM},1)
+        ifeq (${SPM_MM},0)
+            BL31_CFLAGS        +=      -DPLAT_XLAT_TABLES_DYNAMIC=1
+        endif
+    endif
+endif
+
 # Add support for platform supplied linker script for BL31 build
 $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
 
index 7c89c27e3d262c17dd107c3c01fe9987fcfff801..88c91e6feb183a31ee61d57c6523f2b96caf09ff 100644 (file)
@@ -4,7 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
 #include "../fvp_private.h"
 
 void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
index 8b17c9b736d6f1be497cc398fb211967d94e93bf..0250a5f1a2096e1f2cfe810e574aa88e9bc1e45d 100644 (file)
@@ -5,10 +5,10 @@
 #
 
 # SP_MIN source files specific to FVP platform
-BL32_SOURCES           +=      drivers/cfi/v2m/v2m_flash.c                     \
+BL32_SOURCES           +=      drivers/arm/fvp/fvp_pwrc.c                      \
+                               drivers/cfi/v2m/v2m_flash.c                     \
                                lib/utils/mem_region.c                          \
                                plat/arm/board/fvp/aarch32/fvp_helpers.S        \
-                               plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c      \
                                plat/arm/board/fvp/fvp_pm.c                     \
                                plat/arm/board/fvp/fvp_topology.c               \
                                plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c    \
index 86d265a38d0e80453f395df3c4601c30844a6eea..3c8a9639cd5dbe9131db7d71f461aac33bd4174b 100644 (file)
@@ -4,7 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
 #include "../fvp_private.h"
 
 void tsp_early_platform_setup(void)
index 861fe7208076a272190f3637f306074d96d8a4ee..ab3f225a4fe237b815e72aba39c30fb060b41b74 100644 (file)
@@ -5,8 +5,8 @@
 #
 
 # TSP source files specific to FVP platform
-BL32_SOURCES           +=      plat/arm/board/fvp/aarch64/fvp_helpers.S        \
-                               plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c      \
+BL32_SOURCES           +=      drivers/arm/fvp/fvp_pwrc.c                      \
+                               plat/arm/board/fvp/aarch64/fvp_helpers.S        \
                                plat/arm/board/fvp/fvp_topology.c               \
                                plat/arm/board/fvp/tsp/fvp_tsp_setup.c          \
                                ${FVP_GIC_SOURCES}
index 080a8ddcc5b9f9187baaadb4e22609a2241bb6d4..8f9561c895c0912e8e5d2acb894a834fde368655 100644 (file)
@@ -11,9 +11,7 @@
 #include <cortex_a57.h>
 #include <cortex_a72.h>
 #include <cpu_macros.S>
-#include <v2m_def.h>
-#include "../juno_def.h"
-
+#include <platform_def.h>
 
        .globl  plat_reset_handler
        .globl  plat_arm_calc_core_pos
index 373f2fc89385c194a4705d7dbca88c6c6c678657..c94fa3eadba22af0e5c25306b47b2d86981066ea 100644 (file)
 #include <cortex_a57.h>
 #include <cortex_a72.h>
 #include <cpu_macros.S>
-#include <css_def.h>
-#include <v2m_def.h>
-#include "../juno_def.h"
-
+#include <platform_def.h>
 
        .globl  plat_reset_handler
        .globl  plat_arm_calc_core_pos
index ed82879afc2102a5c7f6eb184eb92b3a9bd77336..ddbc9b7f5ae70235ed167b088c5a62c4a5c027b0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,29 +7,17 @@
 #ifndef PLATFORM_DEF_H
 #define PLATFORM_DEF_H
 
-/* Enable the dynamic translation tables library. */
-#ifdef AARCH32
-# if defined(IMAGE_BL32) && RESET_TO_SP_MIN
-#  define PLAT_XLAT_TABLES_DYNAMIC     1
-# endif
-#else
-# if defined(IMAGE_BL31) && RESET_TO_BL31
-#  define PLAT_XLAT_TABLES_DYNAMIC     1
-# endif
-#endif /* AARCH32 */
-
-
 #include <drivers/arm/tzc400.h>
 #if TRUSTED_BOARD_BOOT
 #include <drivers/auth/mbedtls/mbedtls_config.h>
 #endif
+#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/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
 #include <plat/common/common_def.h>
 
-#include <arm_def.h>
-#include <board_css_def.h>
-#include <css_def.h>
-#include <soc_css_def.h>
-#include <v2m_def.h>
 #include "../juno_def.h"
 
 /* Required platform porting definitions */
 #elif TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA
 # define PLAT_ARM_MAX_BL2_SIZE         UL(0x1D000)
 #else
-# define PLAT_ARM_MAX_BL2_SIZE         UL(0x1C000)
+# define PLAT_ARM_MAX_BL2_SIZE         UL(0x1D000)
 #endif
 #else
 # define PLAT_ARM_MAX_BL2_SIZE         UL(0xF000)
index e751ab69c368d388cb8fdc0a75582835b9ad6d7b..f72a6ff1af2f5251cc4b6a475272de29267537d7 100644 (file)
@@ -9,12 +9,11 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <common/tbbr/tbbr_img_def.h>
+#include <drivers/arm/css/sds.h>
 #include <drivers/arm/sp805.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-
-#include <plat_arm.h>
-#include <sds.h>
-#include <v2m_def.h>
+#include <platform_def.h>
 
 void juno_reset_to_aarch32_state(void);
 
index 56f05eb185a9dee5f553c5cf8583103b9de67e93..95ef77c0d04b4c7e4a028875928c484e4362ce55 100644 (file)
@@ -8,8 +8,7 @@
 
 #include <common/bl_common.h>
 #include <common/desc_image_load.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 #if JUNO_AARCH32_EL3_RUNTIME
 /*******************************************************************************
index 2e6b01134f7dc6e55bbe4bcde0397e55d895243e..118c19ab709b22bc76a86317c556bfc042f0921d 100644 (file)
@@ -3,8 +3,9 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include <arm_def.h>
-#include <plat_arm.h>
+
+#include <platform_def.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*
  * Table of memory regions for different BL stages to map using the MMU.
index 69daa1ae0e5e5cca724502422ee3baf986e1c732..f80ff24525b7e3879e41684b002d02f74bb2280b 100644 (file)
@@ -8,8 +8,7 @@
 
 #include <arch_helpers.h>
 #include <plat/common/platform.h>
-
-#include <v2m_def.h>
+#include <platform_def.h>
 
 /*
  * Juno error handler
index dbf7b6c69198e64e91b4a33c6a032e4e85ce6331..cc80651bc26e3311f095b53d49ac7e466d9cbfa4 100644 (file)
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
-#include <scmi.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
 
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
 {
index b0df837912d681794a5ba6c7dc9c064ee4c2db40..9d7f0e4218fbda8eeee00b01fe806a08cd4ae3bb 100644 (file)
@@ -7,10 +7,10 @@
 #include <common/debug.h>
 #include <drivers/arm/nic_400.h>
 #include <lib/mmio.h>
+#include <platform_def.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
 
-#include <plat_arm.h>
-#include <soc_css.h>
-#include "juno_def.h"
 #include "juno_tzmp1_def.h"
 
 #ifdef JUNO_TZMP1
index ff05b5d468882010796a185749fe610b17367473..236eb5ba37d2582345d72cb88faa4f9dd904d2b5 100644 (file)
@@ -7,9 +7,9 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <lib/utils.h>
+#include <platform_def.h>
 
 #include "juno_decl.h"
-#include "juno_def.h"
 
 u_register_t plat_get_stack_protector_canary(void)
 {
index 51b99aca7f883a76fb92ef7a0d730f7e4f4c139b..ca5c344d61b5eec0e109c5a54905e965abc472c7 100644 (file)
@@ -4,14 +4,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
 #include <plat/common/platform.h>
-
-#include <arm_def.h>
-#include <css_pm.h>
-#include <plat_arm.h>
-#include "juno_def.h"
-#include "../../css/drivers/scmi/scmi.h"
-#include "../../css/drivers/mhu/css_mhu_doorbell.h"
+#include <platform_def.h>
 
 #if CSS_USE_SCMI_SDS_DRIVER
 static scmi_channel_plat_info_t juno_scmi_plat_info = {
index 505fb02667aa7206f8b6cd3aeb47890c887e64a7..7869d3e3352b954ad7ab4966c88fef89b9e7d09e 100644 (file)
@@ -9,9 +9,9 @@
 
 #include <lib/mmio.h>
 #include <lib/utils_def.h>
+#include <platform_def.h>
 
 #include "juno_decl.h"
-#include "juno_def.h"
 
 #define NSAMPLE_CLOCKS 1 /* min 1 cycle, max 231 cycles */
 #define NRETRIES       5
index 5d0978c9c05c69f9dce4547cd1a6802a347f9ffa..4186d02dc153fdfce844e73ec57a7ada3ce0e59e 100644 (file)
@@ -7,8 +7,6 @@
 #ifndef JUNO_TZMP1_DEF_H
 #define JUNO_TZMP1_DEF_H
 
-#include <plat_arm.h>
-
 /*
  * Public memory regions for both protected and non-protected mode
  *
index aec2b9bc5e71b5d1d7ebc8b223d1d4e1c2869250..6575811a669f23bfb83e99991fde93291186605e 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -26,9 +26,7 @@ endif
 # SCP during power management operations and for SCP RAM Firmware transfer.
 CSS_USE_SCMI_SDS_DRIVER                :=      1
 
-PLAT_INCLUDES          :=      -Iplat/arm/board/juno/include           \
-                               -Iplat/arm/css/drivers/scmi             \
-                               -Iplat/arm/css/drivers/sds
+PLAT_INCLUDES          :=      -Iplat/arm/board/juno/include
 
 PLAT_BL_COMMON_SOURCES :=      plat/arm/board/juno/${ARCH}/juno_helpers.S \
                                plat/arm/board/juno/juno_common.c
@@ -88,7 +86,7 @@ BL31_SOURCES          +=      drivers/cfi/v2m/v2m_flash.c             \
                                ${JUNO_SECURITY_SOURCES}
 
 ifeq (${CSS_USE_SCMI_SDS_DRIVER},1)
-BL1_SOURCES            +=      plat/arm/css/drivers/sds/sds.c
+BL1_SOURCES            +=      drivers/arm/css/sds/sds.c
 endif
 
 endif
@@ -134,6 +132,17 @@ SKIP_A57_L1_FLUSH_PWR_DWN  :=       1
 # Do not enable SVE
 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
+    endif
+else
+    ifeq (${RESET_TO_BL31},1)
+        BL31_CFLAGS    +=      -DPLAT_XLAT_TABLES_DYNAMIC=1
+    endif
+endif
+
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk
 include plat/arm/soc/common/soc_css.mk
index 1556ac7678922daf7318e48724aebdad4ae37e59..7b8c367a2d4aea840ac0d9a865114f107ad66379 100644 (file)
@@ -7,8 +7,9 @@
 #ifndef PLATFORM_DEF_H
 #define PLATFORM_DEF_H
 
-#include <arm_def.h>
-#include <css_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                        0x2A400000
index d044b7ccf3ca68f6a0d4491daded7764ec0cddfa..18a0deaba35cce0ba2f0eaf5dadcc52805ac94d9 100644 (file)
@@ -6,9 +6,9 @@
 
 #include <platform_def.h>
 
-#include "../../css/drivers/scmi/scmi.h"
-#include "../../css/drivers/mhu/css_mhu_doorbell.h"
-#include <plat_arm.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
 
 static scmi_channel_plat_info_t n1sdp_scmi_plat_info = {
                .scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE,
index 3bf1fe6c24862564705d744511b8a498e798641a..6905896c8e4540de7f8d220b14db53b058a1f56b 100644 (file)
@@ -8,11 +8,9 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
 /*
  * Table of regions to map using the MMU.
  * Replace or extend the below regions as required
index c3b4550d0928d87a543677e747b69f789e4497b0..edf1170997956c6e26be2faa7779c43f0e644a2b 100644 (file)
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /* Topology */
 typedef struct n1sdp_topology {
index cd92aa8ed0fce3d1ef8aa8f51243d050c20f5b30..124c1af53138665137fe49c0661080dc97d73739 100644 (file)
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
 /* Struct to keep track of usable memory */
 typedef struct bl1_mem_info {
        uintptr_t mem_base;
index e28211cfa7e86db32eac499136664e51151b6bc1..fd4809c16294cdf80c357d5b61109c22caa48bf8 100644 (file)
 #include <drivers/arm/sp805.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>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
-#include "../../../bl1/bl1_private.h"
-
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak bl1_early_platform_setup
 #pragma weak bl1_plat_arch_setup
index 0c1f63ed4157d8269092528c8170d9c822a24a23..0c01c872eada2a244c73f4c1e9d3f0eba9e3c827 100644 (file)
@@ -7,10 +7,9 @@
 #include <assert.h>
 
 #include <drivers/generic_delay_timer.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-
-#include <arm_def.h>
-#include <plat_arm.h>
+#include <platform_def.h>
 
 #pragma weak bl2_el3_early_platform_setup
 #pragma weak bl2_el3_plat_arch_setup
index 9319004eae5fb55c067992914c706dd2a76767e7..32617f68d92eb2f13c559c99a2104c9c0cab7179 100644 (file)
 #include <lib/optee_utils.h>
 #endif
 #include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
 /* Data structure which holds the extents of the trusted SRAM for BL2 */
 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
 
index 0dc66e647ec1e3f83579bd07dcadf61a633c8a38..9f44b9e6c656ef173a6c75f5514920b29b378ed0 100644 (file)
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <drivers/generic_delay_timer.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak bl2u_platform_setup
 #pragma weak bl2u_early_platform_setup
index 41151c2c8286188016de414d4804e44fb72d4edf..8e1a26300e8d12cfc3e5843478be42b7b34aab48 100644 (file)
 #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>
-
-#include <arm_def.h>
-#include <plat_arm.h>
+#include <platform_def.h>
 
 /*
  * Placeholder variables for copying the arguments that have been passed to
index 7ee997e29641e1821453526fb768f0261db18693..3795fc52f0f59811b987e13349fa9841ff3decab 100644 (file)
@@ -9,8 +9,7 @@
 #include <arch.h>
 #include <drivers/arm/cci.h>
 #include <lib/utils.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 static const int cci_map[] = {
        PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX,
index 6aa56f217dabd080658859c94ff0c79d0440fcef..2e681ca1f17c57c671f03850a88b73db84c386d2 100644 (file)
@@ -8,8 +8,7 @@
 
 #include <arch.h>
 #include <drivers/arm/ccn.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 static const unsigned char master_to_rn_id_map[] = {
        PLAT_ARM_CLUSTER_TO_CCN_ID_MAP
index 4cd2ce3d6b3ce151b35dae0a117530df7c1ba0b9..5361d4ad169760a7eca197e583bdf19f7de54428 100644 (file)
 #include <common/romlib.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <services/secure_partition.h>
 
-#include <plat_arm.h>
-
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak plat_get_ns_image_entrypoint
 #pragma weak plat_arm_get_mmap
index a8ac286f753232e3e32632bc7447a8a6eb3a5f06..f18a9af698268d4cd5f78dee06c8abc3f065c31a 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -141,9 +141,6 @@ ifeq (${ARM_CRYPTOCELL_INTEG},1)
     endif
 endif
 
-PLAT_INCLUDES          +=      -Iinclude/common/tbbr                           \
-                               -Iinclude/plat/arm/common
-
 ifeq (${ARCH}, aarch64)
 PLAT_INCLUDES          +=      -Iinclude/plat/arm/common/aarch64
 endif
@@ -240,7 +237,7 @@ BL31_SOURCES                +=      lib/extensions/ras/std_err_record.c             \
 endif
 
 # SPM uses libfdt in Arm platforms
-ifeq (${SPM_DEPRECATED},0)
+ifeq (${SPM_MM},0)
 ifeq (${ENABLE_SPM},1)
 BL31_SOURCES           +=      common/fdt_wrappers.c                   \
                                plat/common/plat_spm_rd.c               \
@@ -257,8 +254,6 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
                                drivers/auth/img_parser_mod.c                   \
                                drivers/auth/tbbr/tbbr_cot.c                    \
 
-    PLAT_INCLUDES      +=      -Iinclude/bl1/tbbr
-
     BL1_SOURCES                +=      ${AUTH_SOURCES}                                 \
                                bl1/tbbr/tbbr_img_desc.c                        \
                                plat/arm/common/arm_bl1_fwu.c                   \
index 29cb378275803b901e9907d8da58f5d45d579d07..03670858ca3b640fc8ae3600dffbcf97306cf086 100644 (file)
@@ -11,8 +11,7 @@
 #include <common/debug.h>
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*******************************************************************************
  * Functions that set up the console
index 6c6dc568ca34d1ad6e5e51621ae966b16caeb66e..1c58649ba51c59695940d6c63ad798d0b7eb067b 100644 (file)
 #if TRUSTED_BOARD_BOOT
 #include <drivers/auth/mbedtls/mbedtls_config.h>
 #endif
+#include <plat/arm/common/arm_dyn_cfg_helpers.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_dyn_cfg_helpers.h>
-#include <plat_arm.h>
-
 /* Variable to store the address to TB_FW_CONFIG passed from BL1 */
 static void *tb_fw_cfg_dtb;
 static size_t tb_fw_cfg_dtb_size;
index bf2f15643d54cb4e6357819f64cc2e4982b99b91..36d37f8f66069ae4091d765eeb9a59e3a1b2e3bb 100644 (file)
@@ -10,9 +10,8 @@
 
 #include <common/desc_image_load.h>
 #include <common/fdt_wrappers.h>
-
-#include <arm_dyn_cfg_helpers.h>
-#include <plat_arm.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"
index 8650d48a7d7e43e99c76bf9b15e807984e0eae3f..e77f5dc5c8c43a1dd4faa689068e6492c0d3bcee 100644 (file)
 #include <common/debug.h>
 #include <drivers/cfi/v2m_flash.h>
 #include <drivers/console.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
 #pragma weak plat_arm_error_handler
 
 /*
index fc848c19878389a664f85791a38b4969b22139c1..80a845fa12b2c6f7d95a03c6c13b37b9da65001a 100644 (file)
@@ -7,10 +7,9 @@
 #include <platform_def.h>
 
 #include <drivers/arm/gicv2.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
 /******************************************************************************
  * The following functions are defined as weak to allow a platform to override
  * the way the GICv2 driver is initialised and used.
index 0f6690a0b9dfbb8fa939c127077e6200afa81f19..93bebf34702c360049d4a49d28fe46cc4ed88017 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,11 +9,9 @@
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
 /******************************************************************************
  * The following functions are defined as weak to allow a platform to override
  * the way the GICv3 driver is initialised and used.
@@ -152,7 +150,7 @@ void plat_arm_gic_save(void)
         * If an ITS is available, save its context before
         * the Redistributor using:
         * gicv3_its_save_disable(gits_base, &its_ctx[i])
-        * Additionnaly, an implementation-defined sequence may
+        * Additionally, an implementation-defined sequence may
         * be required to save the whole ITS state.
         */
 
index 791f05ed705978ba736359c79917ec852084172b..2faaa76c4319be2213daa0a49624a7e5a069ef87 100644 (file)
@@ -4,17 +4,17 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <common/bl_common.h>
 #include <common/desc_image_load.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
 #pragma weak plat_flush_next_bl_params
 #pragma weak plat_get_bl_image_load_info
 #pragma weak plat_get_next_bl_params
 
+static bl_params_t *next_bl_params_cpy_ptr;
 
 /*******************************************************************************
  * This function flushes the data structures so that they are visible
  ******************************************************************************/
 void plat_flush_next_bl_params(void)
 {
-       flush_bl_params_desc();
+       assert(next_bl_params_cpy_ptr != NULL);
+
+       flush_bl_params_desc_args(bl_mem_params_desc_ptr,
+               bl_mem_params_desc_num,
+               next_bl_params_cpy_ptr);
 }
 
 /*******************************************************************************
@@ -34,12 +38,53 @@ struct bl_load_info *plat_get_bl_image_load_info(void)
 }
 
 /*******************************************************************************
- * This function returns the list of executable images.
+ * ARM helper function to return the list of executable images.Since the default
+ * descriptors are allocated within BL2 RW memory, this prevents BL31/BL32
+ * overlay of BL2 memory. Hence this function also copies the descriptors to a
+ * pre-allocated memory indicated by ARM_BL2_MEM_DESC_BASE.
  ******************************************************************************/
-struct bl_params *plat_get_next_bl_params(void)
+struct bl_params *arm_get_next_bl_params(void)
 {
-       bl_params_t *next_bl_params = get_next_bl_params_from_mem_params_desc();
+       bl_mem_params_node_t *bl2_mem_params_descs_cpy
+                       = (bl_mem_params_node_t *)ARM_BL2_MEM_DESC_BASE;
+       const bl_params_t *next_bl_params;
+
+       next_bl_params_cpy_ptr =
+               (bl_params_t *)(ARM_BL2_MEM_DESC_BASE +
+               (bl_mem_params_desc_num * sizeof(bl_mem_params_node_t)));
+
+       /*
+        * Copy the memory descriptors to ARM_BL2_MEM_DESC_BASE area.
+        */
+       (void) memcpy(bl2_mem_params_descs_cpy, bl_mem_params_desc_ptr,
+               (bl_mem_params_desc_num * sizeof(bl_mem_params_node_t)));
+
+       /*
+        * Modify the global 'bl_mem_params_desc_ptr' to point to the
+        * copied location.
+        */
+       bl_mem_params_desc_ptr = bl2_mem_params_descs_cpy;
+
+       next_bl_params = get_next_bl_params_from_mem_params_desc();
+       assert(next_bl_params != NULL);
+
+       /*
+        * Copy 'next_bl_params' to the reserved location after the copied
+        * memory descriptors.
+        */
+       (void) memcpy(next_bl_params_cpy_ptr, next_bl_params,
+                                               (sizeof(bl_params_t)));
 
-       populate_next_bl_params_config(next_bl_params);
-       return next_bl_params;
+       populate_next_bl_params_config(next_bl_params_cpy_ptr);
+
+       return next_bl_params_cpy_ptr;
+}
+
+/*******************************************************************************
+ * This function returns the list of executable images
+ ******************************************************************************/
+struct bl_params *plat_get_next_bl_params(void)
+{
+       return arm_get_next_bl_params();
 }
+
index d7c5cac2463e9cc3f7106fcf1b131a7aa60429a2..fc1eb490e93374254763bdef8faba89177f5cf0a 100644 (file)
 #include <drivers/io/io_memmap.h>
 #include <drivers/io/io_storage.h>
 #include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <tools_share/firmware_image_package.h>
 
-#include <plat_arm.h>
-
 /* IO devices */
 static const io_dev_connector_t *fip_dev_con;
 static uintptr_t fip_dev_handle;
index 4ae57e5344cc965f590f4b74fcd25352b50ff0c1..dfbd12900c69e73961c83188d5b46c0c14345ae2 100644 (file)
@@ -11,8 +11,7 @@
 #include <lib/psci/psci.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*
  * DRAM1 is used also to load the NS boot loader. For this reason we
index acfd9089955af64ebaa7229f180d35f91fa95780..cb87bafdd0bff45d4431580b5046dbc00f4aff89 100644 (file)
 
 #include <arch_helpers.h>
 #include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
 /* Allow ARM Standard platforms to override these functions */
 #pragma weak plat_arm_program_trusted_mailbox
 
index 6b0f7e7be8ab475ac13e136d5e6d27033186782c..3d308a3351f7bcfe8d9524520d1a43f05d672220 100644 (file)
@@ -9,11 +9,10 @@
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <lib/pmf/pmf.h>
+#include <plat/arm/common/arm_sip_svc.h>
+#include <plat/arm/common/plat_arm.h>
 #include <tools_share/uuid.h>
 
-#include <arm_sip_svc.h>
-#include <plat_arm.h>
-
 /* ARM SiP Service UUID */
 DEFINE_SVC_UUID2(arm_sip_svc_uid,
        0x556d75e2, 0x6033, 0xb54b, 0xb5, 0x75,
index 6986e52b0380a4eea7eee8c7209567b8008154e4..37047bcf39c8de0deabc0eb576fd4fde6a9e7c6b 100644 (file)
@@ -7,8 +7,7 @@
 #include <platform_def.h>
 
 #include <arch.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*******************************************************************************
  * This function validates an MPIDR by checking whether it falls within the
index 0346fa1845d088f364a1cd39d44b8c5001a6bef7..34e650f196220be1ca7d4f2256da9f0a44be1fa3 100644 (file)
@@ -8,10 +8,7 @@
 
 #include <common/debug.h>
 #include <drivers/arm/tzc400.h>
-
-#include <arm_def.h>
-#include <arm_spm_def.h>
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak plat_arm_security_setup
index bea3867d37536d1b1f088bd7f22c4a6ed476f971..e9f897f4d293d3627259077daa1c827c4b2b0138 100644 (file)
@@ -10,9 +10,7 @@
 
 #include <common/debug.h>
 #include <drivers/arm/tzc_dmc500.h>
-
-#include <arm_def.h>
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*******************************************************************************
  * Initialize the DMC500-TrustZone Controller for ARM standard platforms.
index e3134102dd68391aeb8fcecd2ff550f61b0c6bd7..d471130294f1a71d32105482f894596ba18b9404 100644 (file)
 #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>
 
-#include <arm_sip_svc.h>
-#include <plat_arm.h>
-
 /*
  * Handle SMC from a lower exception level to switch its execution state
  * (either from AArch64 to AArch32, or vice versa).
index 967b551e4e725573e864c77730f9dfba10bdd011..c0ea027b846839ad23df7ea53d37d0fa5275e8fb 100644 (file)
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
 #include <lib/mmio.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
 static entry_point_info_t bl33_image_ep_info;
 
 /* Weak definitions may be overridden in specific ARM standard platform */
index a3d2f7157cae67872adae1c3bcc43423482cc006..2965ccd40cb44f640411f7281ada2f0a102407b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,9 +13,7 @@
 #include <common/debug.h>
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
-
-#include <arm_def.h>
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 #define BL32_END (unsigned long)(&__BL32_END__)
 
@@ -78,7 +76,7 @@ void tsp_platform_setup(void)
 void tsp_plat_arch_setup(void)
 {
 #if USE_COHERENT_MEM
-       /* Ensure ARM platforms dont use coherent memory in TSP */
+       /* Ensure ARM platforms don't use coherent memory in TSP */
        assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U);
 #endif
 
index 80aa24c62887262d34e16bf59a2725428e5137df..d47e13daf50b0df53a00b597e05f9dcfbb152dc0 100644 (file)
@@ -3,10 +3,11 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+
 #include <arch.h>
 #include <asm_macros.S>
 #include <cpu_macros.S>
-#include <css_def.h>
+#include <platform_def.h>
 
        .weak   plat_secondary_cold_boot_setup
        .weak   plat_get_my_entrypoint
index 5096d8d957118233c221e87ccdfc0bc3d075afa7..01669be6ebcac2e36785f7d5fb22d7f1e4c7c7db 100644 (file)
@@ -3,10 +3,11 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+
 #include <arch.h>
 #include <asm_macros.S>
 #include <cpu_macros.S>
-#include <css_def.h>
+#include <platform_def.h>
 
        .weak   plat_secondary_cold_boot_setup
        .weak   plat_get_my_entrypoint
index ae0f01133f631865c1137d70d79f625c36dbedc8..596cc3d676c20cc1345b2959b3a6e885e56cf98a 100644 (file)
@@ -6,11 +6,10 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-#include <soc_css.h>
-
 void bl1_platform_setup(void)
 {
        arm_bl1_platform_setup();
index c1c7868b8b2198a87168a8aa9a44b604befd36d9..002c6eb934f5a10105bc2a828419bf1eba935347 100644 (file)
@@ -8,13 +8,11 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
-
-#include <css_def.h>
-#include <plat_arm.h>
-
-#include "../drivers/scp/css_scp.h"
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
 
 /* Weak definition may be overridden in specific CSS based platform */
 #pragma weak plat_arm_bl2_handle_scp_bl2
index 564e98f705a2def3d317389af991b363c175ff42..15cf4f665fd8b6c1d3e055eb0033e28d30a568e3 100644 (file)
@@ -6,12 +6,10 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
-#include "../drivers/scp/css_scp.h"
-
 /* Weak definition may be overridden in specific CSS based platform */
 #pragma weak bl2u_plat_handle_scp_bl2u
 
index ca1edab1754ca3cd72d56a34abf5ad43a6862c6c..2fbbe4560361b19643d4262389f3d605abee66be 100644 (file)
@@ -11,8 +11,7 @@ CSS_LOAD_SCP_IMAGES   ?=      1
 # By default, SCMI driver is disabled for CSS platforms
 CSS_USE_SCMI_SDS_DRIVER        ?=      0
 
-PLAT_INCLUDES          +=      -Iinclude/plat/arm/css/common                   \
-                               -Iinclude/plat/arm/css/common/aarch64
+PLAT_INCLUDES          +=      -Iinclude/plat/arm/css/common/aarch64
 
 
 PLAT_BL_COMMON_SOURCES +=      plat/arm/css/common/${ARCH}/css_helpers.S
@@ -27,16 +26,16 @@ BL31_SOURCES                +=      plat/arm/css/common/css_pm.c                    \
                                plat/arm/css/common/css_topology.c
 
 ifeq (${CSS_USE_SCMI_SDS_DRIVER},0)
-BL31_SOURCES           +=      plat/arm/css/drivers/scp/css_pm_scpi.c          \
-                               plat/arm/css/drivers/mhu/css_mhu.c              \
-                               plat/arm/css/drivers/scpi/css_scpi.c
+BL31_SOURCES           +=      drivers/arm/css/mhu/css_mhu.c                   \
+                               drivers/arm/css/scp/css_pm_scpi.c               \
+                               drivers/arm/css/scpi/css_scpi.c
 else
-BL31_SOURCES           +=      plat/arm/css/drivers/scp/css_pm_scmi.c          \
-                               plat/arm/css/drivers/scmi/scmi_ap_core_proto.c  \
-                               plat/arm/css/drivers/scmi/scmi_common.c         \
-                               plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c  \
-                               plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c  \
-                               plat/arm/css/drivers/mhu/css_mhu_doorbell.c
+BL31_SOURCES           +=      drivers/arm/css/mhu/css_mhu_doorbell.c          \
+                               drivers/arm/css/scmi/scmi_ap_core_proto.c       \
+                               drivers/arm/css/scmi/scmi_common.c              \
+                               drivers/arm/css/scmi/scmi_pwr_dmn_proto.c       \
+                               drivers/arm/css/scmi/scmi_sys_pwr_proto.c       \
+                               drivers/arm/css/scp/css_pm_scmi.c
 endif
 
 # Process CSS_LOAD_SCP_IMAGES flag
@@ -50,19 +49,19 @@ ifeq (${CSS_LOAD_SCP_IMAGES},1)
   endif
 
   ifeq (${CSS_USE_SCMI_SDS_DRIVER},1)
-    BL2U_SOURCES       +=      plat/arm/css/drivers/scp/css_sds.c      \
-                               plat/arm/css/drivers/sds/sds.c
+    BL2U_SOURCES       +=      drivers/arm/css/scp/css_sds.c                   \
+                               drivers/arm/css/sds/sds.c
 
-    BL2_SOURCES                +=      plat/arm/css/drivers/scp/css_sds.c      \
-                               plat/arm/css/drivers/sds/sds.c
+    BL2_SOURCES                +=      drivers/arm/css/scp/css_sds.c                   \
+                               drivers/arm/css/sds/sds.c
   else
-    BL2U_SOURCES       +=      plat/arm/css/drivers/scp/css_bom_bootloader.c   \
-                               plat/arm/css/drivers/mhu/css_mhu.c              \
-                               plat/arm/css/drivers/scpi/css_scpi.c
+    BL2U_SOURCES       +=      drivers/arm/css/mhu/css_mhu.c                   \
+                               drivers/arm/css/scp/css_bom_bootloader.c        \
+                               drivers/arm/css/scpi/css_scpi.c
 
-    BL2_SOURCES                +=      plat/arm/css/drivers/scp/css_bom_bootloader.c   \
-                               plat/arm/css/drivers/mhu/css_mhu.c              \
-                               plat/arm/css/drivers/scpi/css_scpi.c
+    BL2_SOURCES                +=      drivers/arm/css/mhu/css_mhu.c                   \
+                               drivers/arm/css/scp/css_bom_bootloader.c        \
+                               drivers/arm/css/scpi/css_scpi.c
     # Enable option to detect whether the SCP ROM firmware in use predates version
     # 1.7.0 and therefore, is incompatible.
     CSS_DETECT_PRE_1_7_0_SCP   :=      1
@@ -74,7 +73,7 @@ ifeq (${CSS_LOAD_SCP_IMAGES},1)
 endif
 
 ifeq (${CSS_USE_SCMI_SDS_DRIVER},1)
-  PLAT_BL_COMMON_SOURCES       +=      plat/arm/css/drivers/sds/${ARCH}/sds_helpers.S
+  PLAT_BL_COMMON_SOURCES       +=      drivers/arm/css/sds/${ARCH}/sds_helpers.S
 endif
 
 # Process CSS_USE_SCMI_SDS_DRIVER flag
index 8a156e675dfa14c2f762c1d1e108c58c642a88d7..f6fc6aa7aab3b1c623ed03449ac4fc93fe70851e 100644 (file)
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
 #include <lib/cassert.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
 #include <plat/common/platform.h>
 
-#include <css_pm.h>
-#include <plat_arm.h>
-
-#include "../drivers/scp/css_scp.h"
-
 /* Allow CSS platforms to override `plat_arm_psci_pm_ops` */
 #pragma weak plat_arm_psci_pm_ops
 
index 8ac223230812d99093fa79f1426e7a1428b8525c..8aca7449fb61c325a8285a227d3dfbeff9f42cd0 100644 (file)
@@ -6,10 +6,9 @@
 
 #include <assert.h>
 
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
 #if ARM_PLAT_MT
 #pragma weak plat_arm_get_cpu_pe_count
 #endif
index 9fb280c86a95bb48893be2918ae6a20e7255b947..6523a164b76ca92f691d12c335e84944126f44b7 100644 (file)
@@ -9,13 +9,13 @@ BL32_SOURCES          +=      plat/arm/css/common/css_pm.c                    \
                                plat/arm/css/common/css_topology.c
 
 ifeq (${CSS_USE_SCMI_SDS_DRIVER},0)
-BL32_SOURCES           +=      plat/arm/css/drivers/scp/css_pm_scpi.c          \
-                               plat/arm/css/drivers/mhu/css_mhu.c              \
-                               plat/arm/css/drivers/scpi/css_scpi.c
+BL32_SOURCES           +=      drivers/arm/css/mhu/css_mhu.c                   \
+                               drivers/arm/css/scp/css_pm_scpi.c               \
+                               drivers/arm/css/scpi/css_scpi.c
 else
-BL32_SOURCES           +=      plat/arm/css/drivers/scp/css_pm_scmi.c          \
-                               plat/arm/css/drivers/scmi/scmi_common.c         \
-                               plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c  \
-                               plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c  \
-                               plat/arm/css/drivers/mhu/css_mhu_doorbell.c
+BL32_SOURCES           +=      drivers/arm/css/mhu/css_mhu_doorbell.c          \
+                               drivers/arm/css/scp/css_pm_scmi.c               \
+                               drivers/arm/css/scmi/scmi_common.c              \
+                               drivers/arm/css/scmi/scmi_pwr_dmn_proto.c       \
+                               drivers/arm/css/scmi/scmi_sys_pwr_proto.c
 endif
diff --git a/plat/arm/css/drivers/mhu/css_mhu.c b/plat/arm/css/drivers/mhu/css_mhu.c
deleted file mode 100644 (file)
index e13818f..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <platform_def.h>
-
-#include <arch_helpers.h>
-#include <lib/bakery_lock.h>
-#include <lib/mmio.h>
-
-#include <css_def.h>
-#include <plat_arm.h>
-
-#include "css_mhu.h"
-
-/* SCP MHU secure channel registers */
-#define SCP_INTR_S_STAT                0x200
-#define SCP_INTR_S_SET         0x208
-#define SCP_INTR_S_CLEAR       0x210
-
-/* CPU MHU secure channel registers */
-#define CPU_INTR_S_STAT                0x300
-#define CPU_INTR_S_SET         0x308
-#define CPU_INTR_S_CLEAR       0x310
-
-ARM_INSTANTIATE_LOCK;
-
-/* Weak definition may be overridden in specific CSS based platform */
-#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(unsigned int slot_id)
-{
-       assert(slot_id <= MHU_MAX_SLOT_ID);
-
-       arm_lock_get();
-
-       /* Make sure any previous command has finished */
-       while (mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) &
-                                                       (1 << slot_id))
-               ;
-}
-
-void mhu_secure_message_send(unsigned int slot_id)
-{
-       assert(slot_id <= MHU_MAX_SLOT_ID);
-       assert(!(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) &
-                                                       (1 << slot_id)));
-
-       /* Send command to SCP */
-       mmio_write_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id);
-}
-
-uint32_t mhu_secure_message_wait(void)
-{
-       /* Wait for response from SCP */
-       uint32_t response;
-       while (!(response = mmio_read_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_STAT)))
-               ;
-
-       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_write_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id);
-
-       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_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0);
-}
-
-void __init plat_arm_pwrc_setup(void)
-{
-       mhu_secure_init();
-}
diff --git a/plat/arm/css/drivers/mhu/css_mhu.h b/plat/arm/css/drivers/mhu/css_mhu.h
deleted file mode 100644 (file)
index ff04ae4..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CSS_MHU_H
-#define CSS_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 /* CSS_MHU_H */
diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c b/plat/arm/css/drivers/mhu/css_mhu_doorbell.c
deleted file mode 100644 (file)
index b3203c2..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <arch_helpers.h>
-
-#include "css_mhu_doorbell.h"
-#include "../scmi/scmi.h"
-
-void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info)
-{
-       MHU_RING_DOORBELL(plat_info->db_reg_addr,
-                       plat_info->db_modify_mask,
-                       plat_info->db_preserve_mask);
-       return;
-}
-
-void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info)
-{
-       /* wake receiver */
-       MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR);
-
-       /* wait for receiver to acknowledge its ready */
-       while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0)
-               ;
-
-       MHU_RING_DOORBELL(plat_info->db_reg_addr,
-                       plat_info->db_modify_mask,
-                       plat_info->db_preserve_mask);
-
-       /* clear the access request for the recevier */
-       MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR);
-
-       return;
-}
diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.h b/plat/arm/css/drivers/mhu/css_mhu_doorbell.h
deleted file mode 100644 (file)
index ecee563..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CSS_MHU_DOORBELL_H
-#define CSS_MHU_DOORBELL_H
-
-#include <stdint.h>
-
-#include <lib/mmio.h>
-
-/* MHUv2 Base Address */
-#define MHUV2_BASE_ADDR                PLAT_CSS_MHU_BASE
-
-/* MHUv2 Control Registers Offsets */
-#define MHU_V2_MSG_NO_CAP_OFFSET               0xF80
-#define MHU_V2_ACCESS_REQ_OFFSET               0xF88
-#define MHU_V2_ACCESS_READY_OFFSET             0xF8C
-
-#define SENDER_REG_STAT(_channel)      (0x20 * (_channel))
-#define SENDER_REG_SET(_channel)       ((0x20 * (_channel)) + 0xC)
-
-/* Helper macro to ring doorbell */
-#define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask)    do {    \
-               uint32_t db = mmio_read_32(addr) & (preserve_mask);     \
-               mmio_write_32(addr, db | (modify_mask));                \
-       } while (0)
-
-#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)
-
-struct scmi_channel_plat_info;
-void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info);
-void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info);
-
-#endif /* CSS_MHU_DOORBELL_H */
diff --git a/plat/arm/css/drivers/scmi/scmi.h b/plat/arm/css/drivers/scmi/scmi.h
deleted file mode 100644 (file)
index df259f7..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SCMI_H
-#define SCMI_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <lib/bakery_lock.h>
-#include <lib/psci/psci.h>
-#include <lib/spinlock.h>
-
-/* Supported SCMI Protocol Versions */
-#define SCMI_AP_CORE_PROTO_VER                 MAKE_SCMI_VERSION(1, 0)
-#define SCMI_PWR_DMN_PROTO_VER                 MAKE_SCMI_VERSION(1, 0)
-#define SCMI_SYS_PWR_PROTO_VER                 MAKE_SCMI_VERSION(1, 0)
-
-#define GET_SCMI_MAJOR_VER(ver)                        (((ver) >> 16) & 0xffff)
-#define GET_SCMI_MINOR_VER(ver)                        ((ver) & 0xffff)
-
-#define MAKE_SCMI_VERSION(maj, min)    \
-                       ((((maj) & 0xffff) << 16) | ((min) & 0xffff))
-
-/* Macro to check if the driver is compatible with the SCMI version reported */
-#define is_scmi_version_compatible(drv, scmi)                          \
-       ((GET_SCMI_MAJOR_VER(drv) == GET_SCMI_MAJOR_VER(scmi)) &&       \
-       (GET_SCMI_MINOR_VER(drv) <= GET_SCMI_MINOR_VER(scmi)))
-
-/* SCMI Protocol identifiers */
-#define SCMI_PWR_DMN_PROTO_ID                  0x11
-#define SCMI_SYS_PWR_PROTO_ID                  0x12
-/* The AP core protocol is a CSS platform-specific extension */
-#define SCMI_AP_CORE_PROTO_ID                  0x90
-
-/* Mandatory messages IDs for all SCMI protocols */
-#define SCMI_PROTO_VERSION_MSG                 0x0
-#define SCMI_PROTO_ATTR_MSG                    0x1
-#define SCMI_PROTO_MSG_ATTR_MSG                        0x2
-
-/* SCMI power domain management protocol message IDs */
-#define SCMI_PWR_STATE_SET_MSG                 0x4
-#define SCMI_PWR_STATE_GET_MSG                 0x5
-
-/* SCMI system power management protocol message IDs */
-#define SCMI_SYS_PWR_STATE_SET_MSG             0x3
-#define SCMI_SYS_PWR_STATE_GET_MSG             0x4
-
-/* SCMI AP core protocol message IDs */
-#define SCMI_AP_CORE_RESET_ADDR_SET_MSG                0x3
-#define SCMI_AP_CORE_RESET_ADDR_GET_MSG                0x4
-
-/* Helper macros for system power management protocol commands */
-
-/*
- * Macros to describe the bit-fields of the `attribute` of system power domain
- * protocol PROTOCOL_MSG_ATTRIBUTE message.
- */
-#define SYS_PWR_ATTR_WARM_RESET_SHIFT          31
-#define SCMI_SYS_PWR_WARM_RESET_SUPPORTED      (1U << SYS_PWR_ATTR_WARM_RESET_SHIFT)
-
-#define SYS_PWR_ATTR_SUSPEND_SHIFT             30
-#define SCMI_SYS_PWR_SUSPEND_SUPPORTED         (1 << SYS_PWR_ATTR_SUSPEND_SHIFT)
-
-/*
- * Macros to describe the bit-fields of the `flags` parameter of system power
- * domain protocol SYSTEM_POWER_STATE_SET message.
- */
-#define SYS_PWR_SET_GRACEFUL_REQ_SHIFT         0
-#define SCMI_SYS_PWR_GRACEFUL_REQ              (1 << SYS_PWR_SET_GRACEFUL_REQ_SHIFT)
-#define SCMI_SYS_PWR_FORCEFUL_REQ              (0 << SYS_PWR_SET_GRACEFUL_REQ_SHIFT)
-
-/*
- * Macros to describe the `system_state` parameter of system power
- * domain protocol SYSTEM_POWER_STATE_SET message.
- */
-#define SCMI_SYS_PWR_SHUTDOWN                  0x0
-#define SCMI_SYS_PWR_COLD_RESET                        0x1
-#define SCMI_SYS_PWR_WARM_RESET                        0x2
-#define SCMI_SYS_PWR_POWER_UP                  0x3
-#define SCMI_SYS_PWR_SUSPEND                   0x4
-
-/*
- * Macros to describe the bit-fields of the `attribute` of AP core protocol
- * AP_CORE_RESET_ADDR set/get messages.
- */
-#define SCMI_AP_CORE_LOCK_ATTR_SHIFT           0x0
-#define SCMI_AP_CORE_LOCK_ATTR                 (1U << SCMI_AP_CORE_LOCK_ATTR_SHIFT)
-
-/* SCMI Error code definitions */
-#define SCMI_E_QUEUED                  1
-#define SCMI_E_SUCCESS                 0
-#define SCMI_E_NOT_SUPPORTED           -1
-#define SCMI_E_INVALID_PARAM           -2
-#define SCMI_E_DENIED                  -3
-#define SCMI_E_NOT_FOUND               -4
-#define SCMI_E_OUT_OF_RANGE            -5
-#define SCMI_E_BUSY                    -6
-
-/*
- * SCMI driver platform information. The details of the doorbell mechanism
- * can be found in the SCMI specification.
- */
-typedef struct scmi_channel_plat_info {
-       /* SCMI mailbox memory */
-       uintptr_t scmi_mbx_mem;
-       /* The door bell register address */
-       uintptr_t db_reg_addr;
-       /* The bit mask that need to be preserved when ringing doorbell */
-       uint32_t db_preserve_mask;
-       /* The bit mask that need to be set to ring doorbell */
-       uint32_t db_modify_mask;
-       /* The handler for ringing doorbell */
-       void (*ring_doorbell)(struct scmi_channel_plat_info *plat_info);
-       /* cookie is unused now. But added for future enhancements. */
-       void *cookie;
-} scmi_channel_plat_info_t;
-
-
-#if HW_ASSISTED_COHERENCY
-typedef spinlock_t scmi_lock_t;
-#else
-typedef bakery_lock_t scmi_lock_t;
-#endif
-
-/*
- * Structure to represent an SCMI channel.
- */
-typedef struct scmi_channel {
-       scmi_channel_plat_info_t *info;
-        /* The lock for channel access */
-       scmi_lock_t *lock;
-       /* Indicate whether the channel is initialized */
-       int is_initialized;
-} scmi_channel_t;
-
-/* External Common API */
-void *scmi_init(scmi_channel_t *ch);
-int scmi_proto_msg_attr(void *p, uint32_t proto_id, uint32_t command_id,
-                                               uint32_t *attr);
-int scmi_proto_version(void *p, uint32_t proto_id, uint32_t *version);
-
-/*
- * Power domain protocol commands. Refer to the SCMI specification for more
- * details on these commands.
- */
-int scmi_pwr_state_set(void *p, uint32_t domain_id, uint32_t scmi_pwr_state);
-int scmi_pwr_state_get(void *p, uint32_t domain_id, uint32_t *scmi_pwr_state);
-
-/*
- * System power management protocol commands. Refer SCMI specification for more
- * details on these commands.
- */
-int scmi_sys_pwr_state_set(void *p, uint32_t flags, uint32_t system_state);
-int scmi_sys_pwr_state_get(void *p, uint32_t *system_state);
-
-/* SCMI AP core configuration protocol commands. */
-int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr);
-int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr);
-
-/* API to get the platform specific SCMI channel information. */
-scmi_channel_plat_info_t *plat_css_get_scmi_info();
-
-/* API to override default PSCI callbacks for platforms that support SCMI. */
-const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops);
-
-#endif /* SCMI_H */
diff --git a/plat/arm/css/drivers/scmi/scmi_ap_core_proto.c b/plat/arm/css/drivers/scmi/scmi_ap_core_proto.c
deleted file mode 100644 (file)
index e495dcc..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2018, 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 "scmi.h"
-#include "scmi_private.h"
-
-/*
- * API to set the SCMI AP core reset address and attributes
- */
-int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr)
-{
-       mailbox_mem_t *mbx_mem;
-       int token = 0, ret;
-       scmi_channel_t *ch = (scmi_channel_t *)p;
-
-       validate_scmi_channel(ch);
-
-       scmi_get_channel(ch);
-
-       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
-       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_AP_CORE_PROTO_ID,
-                       SCMI_AP_CORE_RESET_ADDR_SET_MSG, token);
-       mbx_mem->len = SCMI_AP_CORE_RESET_ADDR_SET_MSG_LEN;
-       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
-       SCMI_PAYLOAD_ARG3(mbx_mem->payload, reset_addr & 0xffffffff,
-               reset_addr >> 32, attr);
-
-       scmi_send_sync_command(ch);
-
-       /* Get the return values */
-       SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret);
-       assert(mbx_mem->len == SCMI_AP_CORE_RESET_ADDR_SET_RESP_LEN);
-       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
-
-       scmi_put_channel(ch);
-
-       return ret;
-}
-
-/*
- * API to get the SCMI AP core reset address and attributes
- */
-int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr)
-{
-       mailbox_mem_t *mbx_mem;
-       int token = 0, ret;
-       scmi_channel_t *ch = (scmi_channel_t *)p;
-       uint32_t lo_addr, hi_addr;
-
-       validate_scmi_channel(ch);
-
-       scmi_get_channel(ch);
-
-       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
-       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_AP_CORE_PROTO_ID,
-                       SCMI_AP_CORE_RESET_ADDR_GET_MSG, token);
-       mbx_mem->len = SCMI_AP_CORE_RESET_ADDR_GET_MSG_LEN;
-       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
-
-       scmi_send_sync_command(ch);
-
-       /* Get the return values */
-       SCMI_PAYLOAD_RET_VAL4(mbx_mem->payload, ret, lo_addr, hi_addr, *attr);
-       *reset_addr = lo_addr | (uint64_t)hi_addr << 32;
-       assert(mbx_mem->len == SCMI_AP_CORE_RESET_ADDR_GET_RESP_LEN);
-       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
-
-       scmi_put_channel(ch);
-
-       return ret;
-}
diff --git a/plat/arm/css/drivers/scmi/scmi_common.c b/plat/arm/css/drivers/scmi/scmi_common.c
deleted file mode 100644 (file)
index 1b4ecb2..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2017-2018, 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 "scmi.h"
-#include "scmi_private.h"
-
-#if HW_ASSISTED_COHERENCY
-#define scmi_lock_init(lock)
-#define scmi_lock_get(lock)            spin_lock(lock)
-#define scmi_lock_release(lock)                spin_unlock(lock)
-#else
-#define scmi_lock_init(lock)           bakery_lock_init(lock)
-#define scmi_lock_get(lock)            bakery_lock_get(lock)
-#define scmi_lock_release(lock)                bakery_lock_release(lock)
-#endif
-
-
-/*
- * Private helper function to get exclusive access to SCMI channel.
- */
-void scmi_get_channel(scmi_channel_t *ch)
-{
-       assert(ch->lock);
-       scmi_lock_get(ch->lock);
-
-       /* Make sure any previous command has finished */
-       assert(SCMI_IS_CHANNEL_FREE(
-                       ((mailbox_mem_t *)(ch->info->scmi_mbx_mem))->status));
-}
-
-/*
- * Private helper function to transfer ownership of channel from AP to SCP.
- */
-void scmi_send_sync_command(scmi_channel_t *ch)
-{
-       mailbox_mem_t *mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
-
-       SCMI_MARK_CHANNEL_BUSY(mbx_mem->status);
-
-       /*
-        * Ensure that any write to the SCMI payload area is seen by SCP before
-        * we write to the doorbell register. If these 2 writes were reordered
-        * by the CPU then SCP would read stale payload data
-        */
-       dmbst();
-
-       ch->info->ring_doorbell(ch->info);
-       /*
-        * Ensure that the write to the doorbell register is ordered prior to
-        * checking whether the channel is free.
-        */
-       dmbsy();
-
-       /* Wait for channel to be free */
-       while (!SCMI_IS_CHANNEL_FREE(mbx_mem->status))
-               ;
-
-       /*
-        * Ensure that any read to the SCMI payload area is done after reading
-        * mailbox status. If these 2 reads were reordered then the CPU would
-        * read invalid payload data
-        */
-       dmbld();
-}
-
-/*
- * Private helper function to release exclusive access to SCMI channel.
- */
-void scmi_put_channel(scmi_channel_t *ch)
-{
-       /* Make sure any previous command has finished */
-       assert(SCMI_IS_CHANNEL_FREE(
-                       ((mailbox_mem_t *)(ch->info->scmi_mbx_mem))->status));
-
-       assert(ch->lock);
-       scmi_lock_release(ch->lock);
-}
-
-/*
- * API to query the SCMI protocol version.
- */
-int scmi_proto_version(void *p, uint32_t proto_id, uint32_t *version)
-{
-       mailbox_mem_t *mbx_mem;
-       int token = 0, ret;
-       scmi_channel_t *ch = (scmi_channel_t *)p;
-
-       validate_scmi_channel(ch);
-
-       scmi_get_channel(ch);
-
-       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
-       mbx_mem->msg_header = SCMI_MSG_CREATE(proto_id, SCMI_PROTO_VERSION_MSG,
-                                                       token);
-       mbx_mem->len = SCMI_PROTO_VERSION_MSG_LEN;
-       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
-
-       scmi_send_sync_command(ch);
-
-       /* Get the return values */
-       SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *version);
-       assert(mbx_mem->len == SCMI_PROTO_VERSION_RESP_LEN);
-       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
-
-       scmi_put_channel(ch);
-
-       return ret;
-}
-
-/*
- * API to query the protocol message attributes for a SCMI protocol.
- */
-int scmi_proto_msg_attr(void *p, uint32_t proto_id,
-               uint32_t command_id, uint32_t *attr)
-{
-       mailbox_mem_t *mbx_mem;
-       int token = 0, ret;
-       scmi_channel_t *ch = (scmi_channel_t *)p;
-
-       validate_scmi_channel(ch);
-
-       scmi_get_channel(ch);
-
-       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
-       mbx_mem->msg_header = SCMI_MSG_CREATE(proto_id,
-                               SCMI_PROTO_MSG_ATTR_MSG, token);
-       mbx_mem->len = SCMI_PROTO_MSG_ATTR_MSG_LEN;
-       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
-       SCMI_PAYLOAD_ARG1(mbx_mem->payload, command_id);
-
-       scmi_send_sync_command(ch);
-
-       /* Get the return values */
-       SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *attr);
-       assert(mbx_mem->len == SCMI_PROTO_MSG_ATTR_RESP_LEN);
-       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
-
-       scmi_put_channel(ch);
-
-       return ret;
-}
-
-/*
- * SCMI Driver initialization API. Returns initialized channel on success
- * or NULL on error. The return type is an opaque void pointer.
- */
-void *scmi_init(scmi_channel_t *ch)
-{
-       uint32_t version;
-       int ret;
-
-       assert(ch && ch->info);
-       assert(ch->info->db_reg_addr);
-       assert(ch->info->db_modify_mask);
-       assert(ch->info->db_preserve_mask);
-       assert(ch->info->ring_doorbell != NULL);
-
-       assert(ch->lock);
-
-       scmi_lock_init(ch->lock);
-
-       ch->is_initialized = 1;
-
-       ret = scmi_proto_version(ch, SCMI_PWR_DMN_PROTO_ID, &version);
-       if (ret != SCMI_E_SUCCESS) {
-               WARN("SCMI power domain protocol version message failed");
-               goto error;
-       }
-
-       if (!is_scmi_version_compatible(SCMI_PWR_DMN_PROTO_VER, version)) {
-               WARN("SCMI power domain protocol version 0x%x incompatible with driver version 0x%x",
-                       version, SCMI_PWR_DMN_PROTO_VER);
-               goto error;
-       }
-
-       VERBOSE("SCMI power domain protocol version 0x%x detected\n", version);
-
-       ret = scmi_proto_version(ch, SCMI_SYS_PWR_PROTO_ID, &version);
-       if ((ret != SCMI_E_SUCCESS)) {
-               WARN("SCMI system power protocol version message failed");
-               goto error;
-       }
-
-       if (!is_scmi_version_compatible(SCMI_SYS_PWR_PROTO_VER, version)) {
-               WARN("SCMI system power management protocol version 0x%x incompatible with driver version 0x%x",
-                       version, SCMI_SYS_PWR_PROTO_VER);
-               goto error;
-       }
-
-       VERBOSE("SCMI system power management protocol version 0x%x detected\n",
-                                               version);
-
-       INFO("SCMI driver initialized\n");
-
-       return (void *)ch;
-
-error:
-       ch->is_initialized = 0;
-       return NULL;
-}
diff --git a/plat/arm/css/drivers/scmi/scmi_private.h b/plat/arm/css/drivers/scmi/scmi_private.h
deleted file mode 100644 (file)
index 6530573..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SCMI_PRIVATE_H
-#define SCMI_PRIVATE_H
-
-#include <lib/mmio.h>
-
-/*
- * SCMI power domain management protocol message and response lengths. It is
- * calculated as sum of length in bytes of the message header (4) and payload
- * area (the number of bytes of parameters or return values in the payload).
- */
-#define SCMI_PROTO_VERSION_MSG_LEN             4
-#define SCMI_PROTO_VERSION_RESP_LEN            12
-
-#define SCMI_PROTO_MSG_ATTR_MSG_LEN            8
-#define SCMI_PROTO_MSG_ATTR_RESP_LEN           12
-
-#define SCMI_AP_CORE_RESET_ADDR_SET_MSG_LEN    16
-#define SCMI_AP_CORE_RESET_ADDR_SET_RESP_LEN   8
-
-#define SCMI_AP_CORE_RESET_ADDR_GET_MSG_LEN    4
-#define SCMI_AP_CORE_RESET_ADDR_GET_RESP_LEN   20
-
-#define SCMI_PWR_STATE_SET_MSG_LEN             16
-#define SCMI_PWR_STATE_SET_RESP_LEN            8
-
-#define SCMI_PWR_STATE_GET_MSG_LEN             8
-#define SCMI_PWR_STATE_GET_RESP_LEN            12
-
-#define SCMI_SYS_PWR_STATE_SET_MSG_LEN         12
-#define SCMI_SYS_PWR_STATE_SET_RESP_LEN                8
-
-#define SCMI_SYS_PWR_STATE_GET_MSG_LEN         4
-#define SCMI_SYS_PWR_STATE_GET_RESP_LEN                12
-
-/* SCMI message header format bit field */
-#define SCMI_MSG_ID_SHIFT              0
-#define SCMI_MSG_ID_WIDTH              8
-#define SCMI_MSG_ID_MASK               ((1 << SCMI_MSG_ID_WIDTH) - 1)
-
-#define SCMI_MSG_TYPE_SHIFT            8
-#define SCMI_MSG_TYPE_WIDTH            2
-#define SCMI_MSG_TYPE_MASK             ((1 << SCMI_MSG_TYPE_WIDTH) - 1)
-
-#define SCMI_MSG_PROTO_ID_SHIFT                10
-#define SCMI_MSG_PROTO_ID_WIDTH                8
-#define SCMI_MSG_PROTO_ID_MASK         ((1 << SCMI_MSG_PROTO_ID_WIDTH) - 1)
-
-#define SCMI_MSG_TOKEN_SHIFT           18
-#define SCMI_MSG_TOKEN_WIDTH           10
-#define SCMI_MSG_TOKEN_MASK            ((1 << SCMI_MSG_TOKEN_WIDTH) - 1)
-
-
-/* SCMI mailbox flags */
-#define SCMI_FLAG_RESP_POLL    0
-#define SCMI_FLAG_RESP_INT     1
-
-/* SCMI power domain protocol `POWER_STATE_SET` message flags */
-#define SCMI_PWR_STATE_SET_FLAG_SYNC   0
-#define SCMI_PWR_STATE_SET_FLAG_ASYNC  1
-
-/*
- * Helper macro to create an SCMI message header given protocol, message id
- * and token.
- */
-#define SCMI_MSG_CREATE(_protocol, _msg_id, _token)                            \
-       ((((_protocol) & SCMI_MSG_PROTO_ID_MASK) << SCMI_MSG_PROTO_ID_SHIFT) |  \
-       (((_msg_id) & SCMI_MSG_ID_MASK) << SCMI_MSG_ID_SHIFT) |                 \
-       (((_token) & SCMI_MSG_TOKEN_MASK) << SCMI_MSG_TOKEN_SHIFT))
-
-/* Helper macro to get the token from a SCMI message header */
-#define SCMI_MSG_GET_TOKEN(_msg)                               \
-       (((_msg) >> SCMI_MSG_TOKEN_SHIFT) & SCMI_MSG_TOKEN_MASK)
-
-/* SCMI Channel Status bit fields */
-#define SCMI_CH_STATUS_RES0_MASK       0xFFFFFFFE
-#define SCMI_CH_STATUS_FREE_SHIFT      0
-#define SCMI_CH_STATUS_FREE_WIDTH      1
-#define SCMI_CH_STATUS_FREE_MASK       ((1 << SCMI_CH_STATUS_FREE_WIDTH) - 1)
-
-/* Helper macros to check and write the channel status */
-#define SCMI_IS_CHANNEL_FREE(status)                                   \
-       (!!(((status) >> SCMI_CH_STATUS_FREE_SHIFT) & SCMI_CH_STATUS_FREE_MASK))
-
-#define SCMI_MARK_CHANNEL_BUSY(status) do {                            \
-               assert(SCMI_IS_CHANNEL_FREE(status));                   \
-               (status) &= ~(SCMI_CH_STATUS_FREE_MASK <<               \
-                               SCMI_CH_STATUS_FREE_SHIFT);             \
-       } while (0)
-
-/* Helper macros to copy arguments to the mailbox payload */
-#define SCMI_PAYLOAD_ARG1(payld_arr, arg1)                             \
-               mmio_write_32((uintptr_t)&payld_arr[0], arg1)
-
-#define SCMI_PAYLOAD_ARG2(payld_arr, arg1, arg2)       do {            \
-               SCMI_PAYLOAD_ARG1(payld_arr, arg1);                     \
-               mmio_write_32((uintptr_t)&payld_arr[1], arg2);          \
-       } while (0)
-
-#define SCMI_PAYLOAD_ARG3(payld_arr, arg1, arg2, arg3) do {            \
-               SCMI_PAYLOAD_ARG2(payld_arr, arg1, arg2);               \
-               mmio_write_32((uintptr_t)&payld_arr[2], arg3);          \
-       } while (0)
-
-/* Helper macros to read return values from the mailbox payload */
-#define SCMI_PAYLOAD_RET_VAL1(payld_arr, val1)                         \
-               (val1) = mmio_read_32((uintptr_t)&payld_arr[0])
-
-#define SCMI_PAYLOAD_RET_VAL2(payld_arr, val1, val2)   do {            \
-               SCMI_PAYLOAD_RET_VAL1(payld_arr, val1);                 \
-               (val2) = mmio_read_32((uintptr_t)&payld_arr[1]);        \
-       } while (0)
-
-#define SCMI_PAYLOAD_RET_VAL3(payld_arr, val1, val2, val3)     do {    \
-               SCMI_PAYLOAD_RET_VAL2(payld_arr, val1, val2);           \
-               (val3) = mmio_read_32((uintptr_t)&payld_arr[2]);        \
-       } while (0)
-
-#define SCMI_PAYLOAD_RET_VAL4(payld_arr, val1, val2, val3, val4)       do {    \
-               SCMI_PAYLOAD_RET_VAL3(payld_arr, val1, val2, val3);             \
-               (val4) = mmio_read_32((uintptr_t)&payld_arr[3]);                \
-       } while (0)
-
-/*
- * Private data structure for representing the mailbox memory layout. Refer
- * the SCMI specification for more details.
- */
-typedef struct mailbox_mem {
-       uint32_t res_a; /* Reserved */
-       volatile uint32_t status;
-       uint64_t res_b; /* Reserved */
-       uint32_t flags;
-       volatile uint32_t len;
-       uint32_t msg_header;
-       uint32_t payload[];
-} mailbox_mem_t;
-
-
-/* Private APIs for use within SCMI driver */
-void scmi_get_channel(scmi_channel_t *ch);
-void scmi_send_sync_command(scmi_channel_t *ch);
-void scmi_put_channel(scmi_channel_t *ch);
-
-static inline void validate_scmi_channel(scmi_channel_t *ch)
-{
-       assert(ch && ch->is_initialized);
-       assert(ch->info && ch->info->scmi_mbx_mem);
-}
-
-#endif /* SCMI_PRIVATE_H */
diff --git a/plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c b/plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c
deleted file mode 100644 (file)
index f315621..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2017, 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 "scmi.h"
-#include "scmi_private.h"
-
-/*
- * API to set the SCMI power domain power state.
- */
-int scmi_pwr_state_set(void *p, uint32_t domain_id,
-                                       uint32_t scmi_pwr_state)
-{
-       mailbox_mem_t *mbx_mem;
-       int token = 0, ret;
-
-       /*
-        * Only asynchronous mode of `set power state` command is allowed on
-        * application processors.
-        */
-       uint32_t pwr_state_set_msg_flag = SCMI_PWR_STATE_SET_FLAG_ASYNC;
-       scmi_channel_t *ch = (scmi_channel_t *)p;
-
-       validate_scmi_channel(ch);
-
-       scmi_get_channel(ch);
-
-       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
-       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_PWR_DMN_PROTO_ID,
-                       SCMI_PWR_STATE_SET_MSG, token);
-       mbx_mem->len = SCMI_PWR_STATE_SET_MSG_LEN;
-       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
-       SCMI_PAYLOAD_ARG3(mbx_mem->payload, pwr_state_set_msg_flag,
-                                               domain_id, scmi_pwr_state);
-
-       scmi_send_sync_command(ch);
-
-       /* Get the return values */
-       SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret);
-       assert(mbx_mem->len == SCMI_PWR_STATE_SET_RESP_LEN);
-       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
-
-       scmi_put_channel(ch);
-
-       return ret;
-}
-
-/*
- * API to get the SCMI power domain power state.
- */
-int scmi_pwr_state_get(void *p, uint32_t domain_id,
-                                       uint32_t *scmi_pwr_state)
-{
-       mailbox_mem_t *mbx_mem;
-       int token = 0, ret;
-       scmi_channel_t *ch = (scmi_channel_t *)p;
-
-       validate_scmi_channel(ch);
-
-       scmi_get_channel(ch);
-
-       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
-       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_PWR_DMN_PROTO_ID,
-                       SCMI_PWR_STATE_GET_MSG, token);
-       mbx_mem->len = SCMI_PWR_STATE_GET_MSG_LEN;
-       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
-       SCMI_PAYLOAD_ARG1(mbx_mem->payload, domain_id);
-
-       scmi_send_sync_command(ch);
-
-       /* Get the return values */
-       SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *scmi_pwr_state);
-       assert(mbx_mem->len == SCMI_PWR_STATE_GET_RESP_LEN);
-       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
-
-       scmi_put_channel(ch);
-
-       return ret;
-}
diff --git a/plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c b/plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c
deleted file mode 100644 (file)
index 03c3c06..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2017, 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 "scmi.h"
-#include "scmi_private.h"
-
-/*
- * API to set the SCMI system power state
- */
-int scmi_sys_pwr_state_set(void *p, uint32_t flags, uint32_t system_state)
-{
-       mailbox_mem_t *mbx_mem;
-       int token = 0, ret;
-       scmi_channel_t *ch = (scmi_channel_t *)p;
-
-       validate_scmi_channel(ch);
-
-       scmi_get_channel(ch);
-
-       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
-       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_SYS_PWR_PROTO_ID,
-                       SCMI_SYS_PWR_STATE_SET_MSG, token);
-       mbx_mem->len = SCMI_SYS_PWR_STATE_SET_MSG_LEN;
-       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
-       SCMI_PAYLOAD_ARG2(mbx_mem->payload, flags, system_state);
-
-       scmi_send_sync_command(ch);
-
-       /* Get the return values */
-       SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret);
-       assert(mbx_mem->len == SCMI_SYS_PWR_STATE_SET_RESP_LEN);
-       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
-
-       scmi_put_channel(ch);
-
-       return ret;
-}
-
-/*
- * API to get the SCMI system power state
- */
-int scmi_sys_pwr_state_get(void *p, uint32_t *system_state)
-{
-       mailbox_mem_t *mbx_mem;
-       int token = 0, ret;
-       scmi_channel_t *ch = (scmi_channel_t *)p;
-
-       validate_scmi_channel(ch);
-
-       scmi_get_channel(ch);
-
-       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
-       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_SYS_PWR_PROTO_ID,
-                       SCMI_SYS_PWR_STATE_GET_MSG, token);
-       mbx_mem->len = SCMI_SYS_PWR_STATE_GET_MSG_LEN;
-       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
-
-       scmi_send_sync_command(ch);
-
-       /* Get the return values */
-       SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *system_state);
-       assert(mbx_mem->len == SCMI_SYS_PWR_STATE_GET_RESP_LEN);
-       assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
-
-       scmi_put_channel(ch);
-
-       return ret;
-}
diff --git a/plat/arm/css/drivers/scp/css_bom_bootloader.c b/plat/arm/css/drivers/scp/css_bom_bootloader.c
deleted file mode 100644 (file)
index 27c9e1d..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <stdint.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <plat/common/platform.h>
-
-#include <css_def.h>
-
-#include "../mhu/css_mhu.h"
-#include "../scpi/css_scpi.h"
-#include "css_scp.h"
-
-/* ID of the MHU slot used for the BOM protocol */
-#define BOM_MHU_SLOT_ID                0
-
-/* Boot commands sent from AP -> SCP */
-#define BOOT_CMD_INFO  0x00
-#define BOOT_CMD_DATA  0x01
-
-/* BOM command header */
-typedef struct {
-       uint32_t id : 8;
-       uint32_t reserved : 24;
-} bom_cmd_t;
-
-typedef struct {
-       uint32_t image_size;
-       uint32_t checksum;
-} cmd_info_payload_t;
-
-/*
- * Unlike the SCPI protocol, the boot protocol uses the same memory region
- * for both AP -> SCP and SCP -> AP transfers; define the address of this...
- */
-#define BOM_SHARED_MEM         PLAT_CSS_SCP_COM_SHARED_MEM_BASE
-#define BOM_CMD_HEADER         ((bom_cmd_t *) BOM_SHARED_MEM)
-#define BOM_CMD_PAYLOAD                ((void *) (BOM_SHARED_MEM + sizeof(bom_cmd_t)))
-
-typedef struct {
-       /* Offset from the base address of the Trusted RAM */
-       uint32_t offset;
-       uint32_t block_size;
-} cmd_data_payload_t;
-
-/*
- * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31
- * usually resides except when ARM_BL31_IN_DRAM is
- * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into shared RAM and
- * the tb_fw_config.
- */
-CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2);
-CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2);
-
-CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow);
-CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow);
-
-static void scp_boot_message_start(void)
-{
-       mhu_secure_message_start(BOM_MHU_SLOT_ID);
-}
-
-static void scp_boot_message_send(size_t payload_size)
-{
-       /* Ensure that any write to the BOM 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();
-
-       /* Send command to SCP */
-       mhu_secure_message_send(BOM_MHU_SLOT_ID);
-}
-
-static uint32_t scp_boot_message_wait(size_t size)
-{
-       uint32_t mhu_status;
-
-       mhu_status = mhu_secure_message_wait();
-
-       /* Expect an SCP Boot Protocol message, reject any other protocol */
-       if (mhu_status != (1 << BOM_MHU_SLOT_ID)) {
-               ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n",
-                       mhu_status);
-               panic();
-       }
-
-       /* Ensure that any read to the BOM payload area is done after reading
-        * the MHU register. If these 2 reads were reordered then the CPU would
-        * read invalid payload data */
-       dmbld();
-
-       return *(uint32_t *) BOM_SHARED_MEM;
-}
-
-static void scp_boot_message_end(void)
-{
-       mhu_secure_message_end(BOM_MHU_SLOT_ID);
-}
-
-int css_scp_boot_image_xfer(void *image, unsigned int image_size)
-{
-       uint32_t response;
-       uint32_t checksum;
-       cmd_info_payload_t *cmd_info_payload;
-       cmd_data_payload_t *cmd_data_payload;
-
-       assert((uintptr_t) image == SCP_BL2_BASE);
-
-       if ((image_size == 0) || (image_size % 4 != 0)) {
-               ERROR("Invalid size for the SCP_BL2 image. Must be a multiple of "
-                       "4 bytes and not zero (current size = 0x%x)\n",
-                       image_size);
-               return -1;
-       }
-
-       /* Extract the checksum from the image */
-       checksum = *(uint32_t *) image;
-       image = (char *) image + sizeof(checksum);
-       image_size -= sizeof(checksum);
-
-       mhu_secure_init();
-
-       VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n");
-
-       /*
-        * Send information about the SCP firmware image about to be transferred
-        * to SCP
-        */
-       scp_boot_message_start();
-
-       BOM_CMD_HEADER->id = BOOT_CMD_INFO;
-       cmd_info_payload = BOM_CMD_PAYLOAD;
-       cmd_info_payload->image_size = image_size;
-       cmd_info_payload->checksum = checksum;
-
-       scp_boot_message_send(sizeof(*cmd_info_payload));
-#if CSS_DETECT_PRE_1_7_0_SCP
-       {
-               const uint32_t deprecated_scp_nack_cmd = 0x404;
-               uint32_t mhu_status;
-
-               VERBOSE("Detecting SCP version incompatibility\n");
-
-               mhu_status = mhu_secure_message_wait();
-               if (mhu_status == deprecated_scp_nack_cmd) {
-                       ERROR("Detected an incompatible version of the SCP firmware.\n");
-                       ERROR("Only versions from v1.7.0 onwards are supported.\n");
-                       ERROR("Please update the SCP firmware.\n");
-                       return -1;
-               }
-
-               VERBOSE("SCP version looks OK\n");
-       }
-#endif /* CSS_DETECT_PRE_1_7_0_SCP */
-       response = scp_boot_message_wait(sizeof(response));
-       scp_boot_message_end();
-
-       if (response != 0) {
-               ERROR("SCP BOOT_CMD_INFO returned error %u\n", response);
-               return -1;
-       }
-
-       VERBOSE("Transferring SCP_BL2 image to SCP\n");
-
-       /* Transfer SCP_BL2 image to SCP */
-       scp_boot_message_start();
-
-       BOM_CMD_HEADER->id = BOOT_CMD_DATA;
-       cmd_data_payload = BOM_CMD_PAYLOAD;
-       cmd_data_payload->offset = (uintptr_t) image - ARM_TRUSTED_SRAM_BASE;
-       cmd_data_payload->block_size = image_size;
-
-       scp_boot_message_send(sizeof(*cmd_data_payload));
-       response = scp_boot_message_wait(sizeof(response));
-       scp_boot_message_end();
-
-       if (response != 0) {
-               ERROR("SCP BOOT_CMD_DATA returned error %u\n", response);
-               return -1;
-       }
-
-       return 0;
-}
-
-int css_scp_boot_ready(void)
-{
-       VERBOSE("Waiting for SCP to signal it is ready to go on\n");
-
-       /* Wait for SCP to signal it's ready */
-       return scpi_wait_ready();
-}
diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c
deleted file mode 100644 (file)
index bd6b595..0000000
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Copyright (c) 2017-2018, 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 <plat/common/platform.h>
-
-#include <css_def.h>
-#include <css_pm.h>
-#include <plat_arm.h>
-
-#include "../scmi/scmi.h"
-#include "css_scp.h"
-
-/*
- * This file implements the SCP helper functions using SCMI protocol.
- */
-
-/*
- * SCMI power state parameter bit field encoding for ARM CSS platforms.
- *
- * 31  20 19       16 15      12 11       8 7        4 3         0
- * +-------------------------------------------------------------+
- * | SBZ | Max level |  Level 3 |  Level 2 |  Level 1 |  Level 0 |
- * |     |           |   state  |   state  |   state  |   state  |
- * +-------------------------------------------------------------+
- *
- * `Max level` encodes the highest level that has a valid power state
- * encoded in the power state.
- */
-#define SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT       16
-#define SCMI_PWR_STATE_MAX_PWR_LVL_WIDTH       4
-#define SCMI_PWR_STATE_MAX_PWR_LVL_MASK                \
-                               ((1 << SCMI_PWR_STATE_MAX_PWR_LVL_WIDTH) - 1)
-#define SCMI_SET_PWR_STATE_MAX_PWR_LVL(_power_state, _max_level)               \
-               (_power_state) |= ((_max_level) & SCMI_PWR_STATE_MAX_PWR_LVL_MASK)\
-                               << SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT
-#define SCMI_GET_PWR_STATE_MAX_PWR_LVL(_power_state)           \
-               (((_power_state) >> SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT)   \
-                               & SCMI_PWR_STATE_MAX_PWR_LVL_MASK)
-
-#define SCMI_PWR_STATE_LVL_WIDTH               4
-#define SCMI_PWR_STATE_LVL_MASK                        \
-                               ((1 << SCMI_PWR_STATE_LVL_WIDTH) - 1)
-#define SCMI_SET_PWR_STATE_LVL(_power_state, _level, _level_state)             \
-               (_power_state) |= ((_level_state) & SCMI_PWR_STATE_LVL_MASK)    \
-                               << (SCMI_PWR_STATE_LVL_WIDTH * (_level))
-#define SCMI_GET_PWR_STATE_LVL(_power_state, _level)           \
-               (((_power_state) >> (SCMI_PWR_STATE_LVL_WIDTH * (_level))) &    \
-                               SCMI_PWR_STATE_LVL_MASK)
-
-/*
- * The SCMI power state enumeration for a power domain level
- */
-typedef enum {
-       scmi_power_state_off = 0,
-       scmi_power_state_on = 1,
-       scmi_power_state_sleep = 2,
-} scmi_power_state_t;
-
-/*
- * The global handle for invoking the SCMI driver APIs after the driver
- * has been initialized.
- */
-static void *scmi_handle;
-
-/* The SCMI channel global object */
-static scmi_channel_t channel;
-
-ARM_SCMI_INSTANTIATE_LOCK;
-
-/*
- * Helper function to suspend a CPU power domain and its parent power domains
- * if applicable.
- */
-void css_scp_suspend(const struct psci_power_state *target_state)
-{
-       int ret;
-
-       /* At least power domain level 0 should be specified to be suspended */
-       assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
-                                               ARM_LOCAL_STATE_OFF);
-
-       /* Check if power down at system power domain level is requested */
-       if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) {
-               /* Issue SCMI command for SYSTEM_SUSPEND */
-               ret = scmi_sys_pwr_state_set(scmi_handle,
-                               SCMI_SYS_PWR_FORCEFUL_REQ,
-                               SCMI_SYS_PWR_SUSPEND);
-               if (ret != SCMI_E_SUCCESS) {
-                       ERROR("SCMI system power domain suspend return 0x%x unexpected\n",
-                                       ret);
-                       panic();
-               }
-               return;
-       }
-#if !HW_ASSISTED_COHERENCY
-       int lvl;
-       uint32_t scmi_pwr_state = 0;
-       /*
-        * If we reach here, then assert that power down at system power domain
-        * level is running.
-        */
-       assert(css_system_pwr_state(target_state) == ARM_LOCAL_STATE_RUN);
-
-       /* For level 0, specify `scmi_power_state_sleep` as the power state */
-       SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, ARM_PWR_LVL0,
-                                               scmi_power_state_sleep);
-
-       for (lvl = ARM_PWR_LVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
-               if (target_state->pwr_domain_state[lvl] == ARM_LOCAL_STATE_RUN)
-                       break;
-
-               assert(target_state->pwr_domain_state[lvl] ==
-                                                       ARM_LOCAL_STATE_OFF);
-               /*
-                * Specify `scmi_power_state_off` as power state for higher
-                * levels.
-                */
-               SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl,
-                                               scmi_power_state_off);
-       }
-
-       SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
-
-       ret = scmi_pwr_state_set(scmi_handle,
-               plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()],
-               scmi_pwr_state);
-
-       if (ret != SCMI_E_SUCCESS) {
-               ERROR("SCMI set power state command return 0x%x unexpected\n",
-                               ret);
-               panic();
-       }
-#endif
-}
-
-/*
- * Helper function to turn off a CPU power domain and its parent power domains
- * if applicable.
- */
-void css_scp_off(const struct psci_power_state *target_state)
-{
-       int lvl = 0, ret;
-       uint32_t scmi_pwr_state = 0;
-
-       /* At-least the CPU level should be specified to be OFF */
-       assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
-                                                       ARM_LOCAL_STATE_OFF);
-
-       /* PSCI CPU OFF cannot be used to turn OFF system power domain */
-       assert(css_system_pwr_state(target_state) == ARM_LOCAL_STATE_RUN);
-
-       for (; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
-               if (target_state->pwr_domain_state[lvl] == ARM_LOCAL_STATE_RUN)
-                       break;
-
-               assert(target_state->pwr_domain_state[lvl] ==
-                                                       ARM_LOCAL_STATE_OFF);
-               SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl,
-                               scmi_power_state_off);
-       }
-
-       SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
-
-       ret = scmi_pwr_state_set(scmi_handle,
-               plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()],
-               scmi_pwr_state);
-
-       if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) {
-               ERROR("SCMI set power state command return 0x%x unexpected\n",
-                               ret);
-               panic();
-       }
-}
-
-/*
- * Helper function to turn ON a CPU power domain and its parent power domains
- * if applicable.
- */
-void css_scp_on(u_register_t mpidr)
-{
-       int lvl = 0, ret, core_pos;
-       uint32_t scmi_pwr_state = 0;
-
-       for (; lvl <= PLAT_MAX_PWR_LVL; lvl++)
-               SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl,
-                               scmi_power_state_on);
-
-       SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
-
-       core_pos = plat_core_pos_by_mpidr(mpidr);
-       assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);
-
-       ret = scmi_pwr_state_set(scmi_handle,
-               plat_css_core_pos_to_scmi_dmn_id_map[core_pos],
-               scmi_pwr_state);
-
-       if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) {
-               ERROR("SCMI set power state command return 0x%x unexpected\n",
-                               ret);
-               panic();
-       }
-}
-
-/*
- * Helper function to get the power state of a power domain node as reported
- * by the SCP.
- */
-int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level)
-{
-       int ret, cpu_idx;
-       uint32_t scmi_pwr_state = 0, lvl_state;
-
-       /* We don't support get power state at the system power domain level */
-       if ((power_level > PLAT_MAX_PWR_LVL) ||
-                       (power_level == CSS_SYSTEM_PWR_DMN_LVL)) {
-               WARN("Invalid power level %u specified for SCMI get power state\n",
-                               power_level);
-               return PSCI_E_INVALID_PARAMS;
-       }
-
-       cpu_idx = plat_core_pos_by_mpidr(mpidr);
-       assert(cpu_idx > -1);
-
-       ret = scmi_pwr_state_get(scmi_handle,
-               plat_css_core_pos_to_scmi_dmn_id_map[cpu_idx],
-               &scmi_pwr_state);
-
-       if (ret != SCMI_E_SUCCESS) {
-               WARN("SCMI get power state command return 0x%x unexpected\n",
-                               ret);
-               return PSCI_E_INVALID_PARAMS;
-       }
-
-       /*
-        * Find the maximum power level described in the get power state
-        * command. If it is less than the requested power level, then assume
-        * the requested power level is ON.
-        */
-       if (SCMI_GET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state) < power_level)
-               return HW_ON;
-
-       lvl_state = SCMI_GET_PWR_STATE_LVL(scmi_pwr_state, power_level);
-       if (lvl_state == scmi_power_state_on)
-               return HW_ON;
-
-       assert((lvl_state == scmi_power_state_off) ||
-                               (lvl_state == scmi_power_state_sleep));
-       return HW_OFF;
-}
-
-void __dead2 css_scp_system_off(int state)
-{
-       int ret;
-
-       /*
-        * Disable GIC CPU interface to prevent pending interrupt from waking
-        * up the AP from WFI.
-        */
-       plat_arm_gic_cpuif_disable();
-
-       /*
-        * Issue SCMI command. First issue a graceful
-        * request and if that fails force the request.
-        */
-       ret = scmi_sys_pwr_state_set(scmi_handle,
-                       SCMI_SYS_PWR_FORCEFUL_REQ,
-                       state);
-
-       if (ret != SCMI_E_SUCCESS) {
-               ERROR("SCMI system power state set 0x%x returns unexpected 0x%x\n",
-                       state, ret);
-               panic();
-       }
-       wfi();
-       ERROR("CSS set power state: operation not handled.\n");
-       panic();
-}
-
-/*
- * Helper function to shutdown the system via SCMI.
- */
-void __dead2 css_scp_sys_shutdown(void)
-{
-       css_scp_system_off(SCMI_SYS_PWR_SHUTDOWN);
-}
-
-/*
- * Helper function to reset the system via SCMI.
- */
-void __dead2 css_scp_sys_reboot(void)
-{
-       css_scp_system_off(SCMI_SYS_PWR_COLD_RESET);
-}
-
-static int scmi_ap_core_init(scmi_channel_t *ch)
-{
-#if PROGRAMMABLE_RESET_ADDRESS
-       uint32_t version;
-       int ret;
-
-       ret = scmi_proto_version(ch, SCMI_AP_CORE_PROTO_ID, &version);
-       if (ret != SCMI_E_SUCCESS) {
-               WARN("SCMI AP core protocol version message failed\n");
-               return -1;
-       }
-
-       if (!is_scmi_version_compatible(SCMI_AP_CORE_PROTO_VER, version)) {
-               WARN("SCMI AP core protocol version 0x%x incompatible with driver version 0x%x\n",
-                       version, SCMI_AP_CORE_PROTO_VER);
-               return -1;
-       }
-       INFO("SCMI AP core protocol version 0x%x detected\n", version);
-#endif
-       return 0;
-}
-
-void __init plat_arm_pwrc_setup(void)
-{
-       channel.info = plat_css_get_scmi_info();
-       channel.lock = ARM_SCMI_LOCK_GET_INSTANCE;
-       scmi_handle = scmi_init(&channel);
-       if (scmi_handle == NULL) {
-               ERROR("SCMI Initialization failed\n");
-               panic();
-       }
-       if (scmi_ap_core_init(&channel) < 0) {
-               ERROR("SCMI AP core protocol initialization failed\n");
-               panic();
-       }
-}
-
-/******************************************************************************
- * This function overrides the default definition for ARM platforms. Initialize
- * the SCMI driver, query capability via SCMI and modify the PSCI capability
- * based on that.
- *****************************************************************************/
-const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops)
-{
-       uint32_t msg_attr;
-       int ret;
-
-       assert(scmi_handle);
-
-       /* Check that power domain POWER_STATE_SET message is supported */
-       ret = scmi_proto_msg_attr(scmi_handle, SCMI_PWR_DMN_PROTO_ID,
-                               SCMI_PWR_STATE_SET_MSG, &msg_attr);
-       if (ret != SCMI_E_SUCCESS) {
-               ERROR("Set power state command is not supported by SCMI\n");
-               panic();
-       }
-
-       /*
-        * Don't support PSCI NODE_HW_STATE call if SCMI doesn't support
-        * POWER_STATE_GET message.
-        */
-       ret = scmi_proto_msg_attr(scmi_handle, SCMI_PWR_DMN_PROTO_ID,
-                               SCMI_PWR_STATE_GET_MSG, &msg_attr);
-       if (ret != SCMI_E_SUCCESS)
-               ops->get_node_hw_state = NULL;
-
-       /* Check if the SCMI SYSTEM_POWER_STATE_SET message is supported */
-       ret = scmi_proto_msg_attr(scmi_handle, SCMI_SYS_PWR_PROTO_ID,
-                               SCMI_SYS_PWR_STATE_SET_MSG, &msg_attr);
-       if (ret != SCMI_E_SUCCESS) {
-               /* System power management operations are not supported */
-               ops->system_off = NULL;
-               ops->system_reset = NULL;
-               ops->get_sys_suspend_power_state = NULL;
-       } else {
-               if (!(msg_attr & SCMI_SYS_PWR_SUSPEND_SUPPORTED)) {
-                       /*
-                        * System power management protocol is available, but
-                        * it does not support SYSTEM SUSPEND.
-                        */
-                       ops->get_sys_suspend_power_state = NULL;
-               }
-               if (!(msg_attr & SCMI_SYS_PWR_WARM_RESET_SUPPORTED)) {
-                       /*
-                        * WARM reset is not available.
-                        */
-                       ops->system_reset2 = NULL;
-               }
-       }
-
-       return ops;
-}
-
-int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie)
-{
-       if (is_vendor || (reset_type != PSCI_RESET2_SYSTEM_WARM_RESET))
-               return PSCI_E_INVALID_PARAMS;
-
-       css_scp_system_off(SCMI_SYS_PWR_WARM_RESET);
-       /*
-        * css_scp_system_off cannot return (it is a __dead function),
-        * but css_system_reset2 has to return some value, even in
-        * this case.
-        */
-       return 0;
-}
-
-#if PROGRAMMABLE_RESET_ADDRESS
-void plat_arm_program_trusted_mailbox(uintptr_t address)
-{
-       int ret;
-
-       assert(scmi_handle);
-       ret = scmi_ap_core_set_reset_addr(scmi_handle, address,
-               SCMI_AP_CORE_LOCK_ATTR);
-       if (ret != SCMI_E_SUCCESS) {
-               ERROR("CSS: Failed to program reset address: %d\n", ret);
-               panic();
-       }
-}
-#endif
diff --git a/plat/arm/css/drivers/scp/css_pm_scpi.c b/plat/arm/css/drivers/scp/css_pm_scpi.c
deleted file mode 100644 (file)
index f53ac30..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2016-2018, 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 <css_pm.h>
-#include <plat_arm.h>
-
-#include "../scpi/css_scpi.h"
-#include "css_scp.h"
-
-/*
- * This file implements the SCP power management functions using SCPI protocol.
- */
-
-/*
- * Helper function to inform power down state to SCP.
- */
-void css_scp_suspend(const struct psci_power_state *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 (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF)
-               system_state = scpi_power_retention;
-
-       /* Cluster is to be turned off, so disable coherency */
-       if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
-               cluster_state = scpi_power_off;
-
-       /*
-        * Ask the SCP to power down the appropriate components depending upon
-        * their state.
-        */
-       scpi_set_css_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.
- */
-void css_scp_off(const struct psci_power_state *target_state)
-{
-       css_scp_suspend(target_state);
-}
-
-/*
- * Helper function to turn ON a CPU power domain and its parent power domains
- * if applicable.
- */
-void css_scp_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_css_power_state(mpidr, scpi_power_on, scpi_power_on,
-                                scpi_power_on);
-}
-
-/*
- * Helper function to get the power state of a power domain node as reported
- * by the SCP.
- */
-int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level)
-{
-       int rc, element;
-       unsigned int cpu_state, cluster_state;
-
-       /*
-        * The format of 'power_level' is implementation-defined, but 0 must
-        * mean a CPU. We also allow 1 to denote the cluster
-        */
-       if (power_level != ARM_PWR_LVL0 && power_level != ARM_PWR_LVL1)
-               return PSCI_E_INVALID_PARAMS;
-
-       /* Query SCP */
-       rc = scpi_get_css_power_state(mpidr, &cpu_state, &cluster_state);
-       if (rc != 0)
-               return PSCI_E_INVALID_PARAMS;
-
-       /* Map power states of CPU and cluster to expected PSCI return codes */
-       if (power_level == ARM_PWR_LVL0) {
-               /*
-                * The CPU state returned by SCP is an 8-bit bit mask
-                * corresponding to each CPU in the cluster
-                */
-#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.
-                */
-               element = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-#else
-               element = mpidr & MPIDR_AFFLVL_MASK;
-#endif  /* ARM_PLAT_MT */
-               return CSS_CPU_PWR_STATE(cpu_state, element) ==
-                       CSS_CPU_PWR_STATE_ON ? HW_ON : HW_OFF;
-       } else {
-               assert(cluster_state == CSS_CLUSTER_PWR_STATE_ON ||
-                               cluster_state == CSS_CLUSTER_PWR_STATE_OFF);
-               return cluster_state == CSS_CLUSTER_PWR_STATE_ON ? HW_ON :
-                       HW_OFF;
-       }
-}
-
-/*
- * Helper function to shutdown the system via SCPI.
- */
-void __dead2 css_scp_sys_shutdown(void)
-{
-       uint32_t response;
-
-       /*
-        * Disable GIC CPU interface to prevent pending interrupt
-        * from waking up the AP from WFI.
-        */
-       plat_arm_gic_cpuif_disable();
-
-       /* Send the power down request to the SCP */
-       response = scpi_sys_power_state(scpi_system_shutdown);
-
-       if (response != SCP_OK) {
-               ERROR("CSS System Off: SCP error %u.\n", response);
-               panic();
-       }
-       wfi();
-       ERROR("CSS System Off: operation not handled.\n");
-       panic();
-}
-
-/*
- * Helper function to reset the system via SCPI.
- */
-void __dead2 css_scp_sys_reboot(void)
-{
-       uint32_t response;
-
-       /*
-        * Disable GIC CPU interface to prevent pending interrupt
-        * from waking up the AP from WFI.
-        */
-       plat_arm_gic_cpuif_disable();
-
-       /* Send the system reset request to the SCP */
-       response = scpi_sys_power_state(scpi_system_reboot);
-
-       if (response != SCP_OK) {
-               ERROR("CSS System Reset: SCP error %u.\n", response);
-               panic();
-       }
-       wfi();
-       ERROR("CSS System Reset: operation not handled.\n");
-       panic();
-}
diff --git a/plat/arm/css/drivers/scp/css_scp.h b/plat/arm/css/drivers/scp/css_scp.h
deleted file mode 100644 (file)
index f3c08c5..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CSS_SCP_H
-#define CSS_SCP_H
-
-#include <stdint.h>
-
-#include <platform_def.h>
-
-#include <lib/cassert.h>
-
-/* Forward declarations */
-struct psci_power_state;
-
-/* API for power management by SCP */
-int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie);
-void css_scp_suspend(const struct psci_power_state *target_state);
-void css_scp_off(const struct psci_power_state *target_state);
-void css_scp_on(u_register_t mpidr);
-int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level);
-void __dead2 css_scp_sys_shutdown(void);
-void __dead2 css_scp_sys_reboot(void);
-void __dead2 css_scp_system_off(int state);
-
-/* API for SCP Boot Image transfer. Return 0 on success, -1 on error */
-int css_scp_boot_image_xfer(void *image, unsigned int image_size);
-
-/*
- * API to wait for SCP to signal till it's ready after booting the transferred
- * image.
- */
-int css_scp_boot_ready(void);
-
-#if CSS_LOAD_SCP_IMAGES
-
-/*
- * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31
- * usually resides except when ARM_BL31_IN_DRAM is
- * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into tb_fw_config.
- */
-CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2);
-CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2);
-
-CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow);
-CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow);
-#endif
-
-#endif /* CSS_SCP_H */
diff --git a/plat/arm/css/drivers/scp/css_sds.c b/plat/arm/css/drivers/scp/css_sds.c
deleted file mode 100644 (file)
index c152abc..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <stdint.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <drivers/delay_timer.h>
-#include <plat/common/platform.h>
-
-#include <css_def.h>
-
-#include "css_scp.h"
-#include "../sds/sds.h"
-
-int css_scp_boot_image_xfer(void *image, unsigned int image_size)
-{
-       int ret;
-       unsigned int image_offset, image_flags;
-
-       ret = sds_init();
-       if (ret != SDS_OK) {
-               ERROR("SCP SDS initialization failed\n");
-               panic();
-       }
-
-       VERBOSE("Writing SCP image metadata\n");
-       image_offset = (uintptr_t) image - ARM_TRUSTED_SRAM_BASE;
-       ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_ADDR_OFFSET,
-                       &image_offset, SDS_SCP_IMG_ADDR_SIZE,
-                       SDS_ACCESS_MODE_NON_CACHED);
-       if (ret != SDS_OK)
-               goto sds_fail;
-
-       ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_SIZE_OFFSET,
-                       &image_size, SDS_SCP_IMG_SIZE_SIZE,
-                       SDS_ACCESS_MODE_NON_CACHED);
-       if (ret != SDS_OK)
-               goto sds_fail;
-
-       VERBOSE("Marking SCP image metadata as valid\n");
-       image_flags = SDS_SCP_IMG_VALID_FLAG_BIT;
-       ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_FLAG_OFFSET,
-                       &image_flags, SDS_SCP_IMG_FLAG_SIZE,
-                       SDS_ACCESS_MODE_NON_CACHED);
-       if (ret != SDS_OK)
-               goto sds_fail;
-
-       return 0;
-sds_fail:
-       ERROR("SCP SDS write to SCP IMG struct failed\n");
-       panic();
-}
-
-/*
- * API to wait for SCP to signal till it's ready after booting the transferred
- * image.
- */
-int css_scp_boot_ready(void)
-{
-       uint32_t scp_feature_availability_flags;
-       int ret, retry = CSS_SCP_READY_10US_RETRIES;
-
-
-       VERBOSE("Waiting for SCP RAM to complete its initialization process\n");
-
-       /* Wait for the SCP RAM Firmware to complete its initialization process */
-       while (retry > 0) {
-               ret = sds_struct_read(SDS_FEATURE_AVAIL_STRUCT_ID, 0,
-                               &scp_feature_availability_flags,
-                               SDS_FEATURE_AVAIL_SIZE,
-                               SDS_ACCESS_MODE_NON_CACHED);
-               if (ret == SDS_ERR_STRUCT_NOT_FINALIZED)
-                       continue;
-
-               if (ret != SDS_OK) {
-                       ERROR(" sds_struct_read failed\n");
-                       panic();
-               }
-
-               if (scp_feature_availability_flags &
-                               SDS_FEATURE_AVAIL_SCP_RAM_READY_BIT)
-                       return 0;
-
-               udelay(10);
-               retry--;
-       }
-
-       ERROR("Timeout of %d ms expired waiting for SCP RAM Ready flag\n",
-                       CSS_SCP_READY_10US_RETRIES/100);
-
-       plat_panic_handler();
-}
diff --git a/plat/arm/css/drivers/scpi/css_scpi.c b/plat/arm/css/drivers/scpi/css_scpi.c
deleted file mode 100644 (file)
index 42bf3b8..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2014-2018, 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 <css_def.h>
-
-#include "../mhu/css_mhu.h"
-#include "css_scpi.h"
-
-#define SCPI_SHARED_MEM_SCP_TO_AP      PLAT_CSS_SCP_COM_SHARED_MEM_BASE
-#define SCPI_SHARED_MEM_AP_TO_SCP      (PLAT_CSS_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 command #%u, got command #%u\n",
-                     SCPI_CMD_SCP_READY, scpi_cmd.id);
-               status = SCP_E_SUPPORT;
-       } else if (scpi_cmd.size != 0) {
-               ERROR("SCP_READY command 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_css_power_state(unsigned int mpidr,
-               scpi_power_state_t cpu_state, scpi_power_state_t cluster_state,
-               scpi_power_state_t css_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 |= css_state << 16;
-
-       scpi_secure_message_start();
-
-       /* Populate the command header */
-       cmd = SCPI_CMD_HEADER_AP_TO_SCP;
-       cmd->id = SCPI_CMD_SET_CSS_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 CSS 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_css_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
-        */
-#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.
-        */
-       cpu = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-       cluster = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
-#else
-       cpu = mpidr & MPIDR_AFFLVL_MASK;
-       cluster = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-#endif  /* ARM_PLAT_MT */
-       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_CSS_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_cmd_t response;
-
-       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_receive(&response);
-
-       scpi_secure_message_end();
-
-       return response.status;
-}
diff --git a/plat/arm/css/drivers/scpi/css_scpi.h b/plat/arm/css/drivers/scpi/css_scpi.h
deleted file mode 100644 (file)
index 68fc60a..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CSS_SCPI_H
-#define CSS_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_CSS_POWER_STATE = 0x03,
-       SCPI_CMD_GET_CSS_POWER_STATE = 0x04,
-       SCPI_CMD_SYS_POWER_STATE = 0x05
-} scpi_command_t;
-
-/*
- * Macros to parse SCP response to GET_CSS_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_CSS_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;
-
-int scpi_wait_ready(void);
-void scpi_set_css_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_css_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 /* CSS_SCPI_H */
diff --git a/plat/arm/css/drivers/sds/aarch32/sds_helpers.S b/plat/arm/css/drivers/sds/aarch32/sds_helpers.S
deleted file mode 100644 (file)
index f68cb35..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2017, 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 "../sds.h"
-#include "../sds_private.h"
-
-       .globl  sds_get_primary_cpu_id
-
-       /*
-        * int sds_get_primary_cpu_id(void);
-        * Return the primary CPU ID from SDS Structure
-        * Returns CPUID on success or -1 on failure
-        */
-func sds_get_primary_cpu_id
-       ldr     r0, =PLAT_ARM_SDS_MEM_BASE
-       ldr     r2, =SDS_REGION_SIGNATURE
-       ldr     r1, [r0]
-       ubfx    r3, r1, #0, #16
-
-       /* Check if the SDS region signature found */
-       cmp     r2, r3
-       bne     2f
-
-       /* Get the structure count from region descriptor in r1 */
-       ubfx    r1, r1, #SDS_REGION_STRUCT_COUNT_SHIFT, #SDS_REGION_STRUCT_COUNT_WIDTH
-       cmp     r1, #0
-       beq     2f
-       add     r0, r0, #SDS_REGION_DESC_SIZE
-
-       /* Initialize the loop iterator count in r3 */
-       mov     r3, #0
-loop_begin:
-       ldrh    r2, [r0]
-       cmp     r2, #SDS_AP_CPU_INFO_STRUCT_ID
-       bne     continue_loop
-
-       /* We have found the required structure */
-       ldr     r0, [r0,#(SDS_HEADER_SIZE + SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET)]
-       bx      lr
-continue_loop:
-       /* Increment the loop counter and exit loop if counter == structure count */
-       add     r3, r3, #0x1
-       cmp     r1, r3
-       beq     2f
-
-       /* Read the 2nd word in header */
-       ldr     r2, [r0,#4]
-       /* Get the structure size from header */
-       ubfx    r2, r2, #SDS_HEADER_STRUCT_SIZE_SHIFT, #SDS_HEADER_STRUCT_SIZE_WIDTH
-       /* Add the structure size and SDS HEADER SIZE to point to next header */
-       add     r2, r2, #SDS_HEADER_SIZE
-       add     r0, r0, r2
-       b       loop_begin
-2:
-       mov     r0, #0xffffffff
-       bx      lr
-endfunc sds_get_primary_cpu_id
diff --git a/plat/arm/css/drivers/sds/aarch64/sds_helpers.S b/plat/arm/css/drivers/sds/aarch64/sds_helpers.S
deleted file mode 100644 (file)
index 3b9c562..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2017, 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 "../sds.h"
-#include "../sds_private.h"
-
-       .globl  sds_get_primary_cpu_id
-
-       /*
-        * int sds_get_primary_cpu_id(void);
-        * Return the primary CPI ID from SDS Structure
-        * Returns CPUID on success or -1 on failure
-        */
-func sds_get_primary_cpu_id
-       mov_imm x0, PLAT_ARM_SDS_MEM_BASE
-       mov     w2, #SDS_REGION_SIGNATURE
-       ldr     w1, [x0]
-
-       /* Check if the SDS region signature found */
-       cmp     w2, w1, uxth
-       b.ne    2f
-
-       /* Get the structure count from region descriptor in `w1 */
-       ubfx    w1, w1, #SDS_REGION_STRUCT_COUNT_SHIFT, #SDS_REGION_STRUCT_COUNT_WIDTH
-       cbz     w1, 2f
-       add     x0, x0, #SDS_REGION_DESC_SIZE
-
-       /* Initialize the loop iterator count in w3 */
-       mov     w3, #0
-loop_begin:
-       ldrh    w2, [x0]
-       cmp     w2, #SDS_AP_CPU_INFO_STRUCT_ID
-       b.ne    continue_loop
-
-       /* We have found the required structure */
-       ldr     w0, [x0,#(SDS_HEADER_SIZE + SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET)]
-       ret
-continue_loop:
-       /* Increment the loop counter and exit loop if counter == structure count */
-       add     w3, w3, #0x1
-       cmp     w1, w3
-       b.eq    2f
-
-       /* Read the 2nd word in header */
-       ldr     w2, [x0,#4]
-       /* Get the structure size from header */
-       ubfx    x2, x2, #SDS_HEADER_STRUCT_SIZE_SHIFT, #SDS_HEADER_STRUCT_SIZE_WIDTH
-       /* Add the structure size and SDS HEADER SIZE to point to next header */
-       add     x2, x2, #SDS_HEADER_SIZE
-       add     x0, x0, x2
-       b       loop_begin
-2:
-       mov     w0, #0xffffffff
-       ret
-endfunc sds_get_primary_cpu_id
diff --git a/plat/arm/css/drivers/sds/sds.c b/plat/arm/css/drivers/sds/sds.c
deleted file mode 100644 (file)
index 3eeb0dc..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-
-#include <css_def.h>
-#include "sds.h"
-#include "sds_private.h"
-
-/*
- * Variables used to track and maintain the state of the memory region reserved
- * for usage by the SDS framework.
- */
-
-/* Pointer to the base of the SDS memory region */
-static uintptr_t sds_mem_base;
-
-/* Size of the SDS memory region in bytes */
-static size_t sds_mem_size;
-
-/*
- * Perform some non-exhaustive tests to determine whether any of the fields
- * within a Structure Header contain obviously invalid data.
- * Returns SDS_OK on success, SDS_ERR_FAIL on error.
- */
-static int sds_struct_is_valid(uintptr_t header)
-{
-       size_t struct_size = GET_SDS_HEADER_STRUCT_SIZE(header);
-
-       /* Zero is not a valid identifier */
-       if (GET_SDS_HEADER_ID(header) == 0)
-               return SDS_ERR_FAIL;
-
-       /* Check SDS Schema version */
-       if (GET_SDS_HEADER_VERSION(header) == SDS_REGION_SCH_VERSION)
-               return SDS_ERR_FAIL;
-
-       /* The SDS Structure sizes have to be multiple of 8 */
-       if ((struct_size == 0) || ((struct_size % 8) != 0))
-               return SDS_ERR_FAIL;
-
-       if (struct_size > sds_mem_size)
-               return SDS_ERR_FAIL;
-
-       return SDS_OK;
-}
-
-/*
- * Validate the SDS structure headers.
- * Returns SDS_OK on success, SDS_ERR_FAIL on error.
- */
-static int validate_sds_struct_headers(void)
-{
-       unsigned int i, structure_count;
-       uintptr_t header;
-
-       structure_count = GET_SDS_REGION_STRUCTURE_COUNT(sds_mem_base);
-
-       if (structure_count == 0)
-               return SDS_ERR_FAIL;
-
-       header = sds_mem_base + SDS_REGION_DESC_SIZE;
-
-       /* Iterate over structure headers and validate each one */
-       for (i = 0; i < structure_count; i++) {
-               if (sds_struct_is_valid(header) != SDS_OK) {
-                       WARN("SDS: Invalid structure header detected\n");
-                       return SDS_ERR_FAIL;
-               }
-               header += GET_SDS_HEADER_STRUCT_SIZE(header) + SDS_HEADER_SIZE;
-       }
-       return SDS_OK;
-}
-
-/*
- * Get the structure header pointer corresponding to the structure ID.
- * Returns SDS_OK on success, SDS_ERR_STRUCT_NOT_FOUND on error.
- */
-static int get_struct_header(uint32_t structure_id, struct_header_t **header)
-{
-       unsigned int i, structure_count;
-       uintptr_t current_header;
-
-       assert(header);
-
-       structure_count = GET_SDS_REGION_STRUCTURE_COUNT(sds_mem_base);
-       if (structure_count == 0)
-               return SDS_ERR_STRUCT_NOT_FOUND;
-
-       current_header = ((uintptr_t)sds_mem_base) + SDS_REGION_DESC_SIZE;
-
-       /* Iterate over structure headers to find one with a matching ID */
-       for (i = 0; i < structure_count; i++) {
-               if (GET_SDS_HEADER_ID(current_header) == structure_id) {
-                       *header = (struct_header_t *)current_header;
-                       return SDS_OK;
-               }
-               current_header += GET_SDS_HEADER_STRUCT_SIZE(current_header) +
-                                               SDS_HEADER_SIZE;
-       }
-
-       *header = NULL;
-       return SDS_ERR_STRUCT_NOT_FOUND;
-}
-
-/*
- * Check if a structure header corresponding to the structure ID exists.
- * Returns SDS_OK if structure header exists else SDS_ERR_STRUCT_NOT_FOUND
- * if not found.
- */
-int sds_struct_exists(unsigned int structure_id)
-{
-       struct_header_t *header = NULL;
-       int ret;
-
-       ret = get_struct_header(structure_id, &header);
-       if (ret == SDS_OK) {
-               assert(header);
-       }
-
-       return ret;
-}
-
-/*
- * Read from field in the structure corresponding to `structure_id`.
- * `fld_off` is the offset to the field in the structure and `mode`
- * indicates whether cache maintenance need to performed prior to the read.
- * The `data` is the pointer to store the read data of size specified by `size`.
- * Returns SDS_OK on success or corresponding error codes on failure.
- */
-int sds_struct_read(uint32_t structure_id, unsigned int fld_off,
-               void *data, size_t size, sds_access_mode_t mode)
-{
-       int status;
-       uintptr_t field_base;
-       struct_header_t *header = NULL;
-
-       if (!data)
-               return SDS_ERR_INVALID_PARAMS;
-
-       /* Check if a structure with this ID exists */
-       status = get_struct_header(structure_id, &header);
-       if (status != SDS_OK)
-               return status;
-
-       assert(header);
-
-       if (mode == SDS_ACCESS_MODE_CACHED)
-               inv_dcache_range((uintptr_t)header, SDS_HEADER_SIZE + size);
-
-       if (!IS_SDS_HEADER_VALID(header)) {
-               WARN("SDS: Reading from un-finalized structure 0x%x\n",
-                               structure_id);
-               return SDS_ERR_STRUCT_NOT_FINALIZED;
-       }
-
-       if ((fld_off + size) > GET_SDS_HEADER_STRUCT_SIZE(header))
-               return SDS_ERR_FAIL;
-
-       field_base = (uintptr_t)header + SDS_HEADER_SIZE + fld_off;
-       if (check_uptr_overflow(field_base, size - 1))
-               return SDS_ERR_FAIL;
-
-       /* Copy the required field in the struct */
-       memcpy(data, (void *)field_base, size);
-
-       return SDS_OK;
-}
-
-/*
- * Write to the field in the structure corresponding to `structure_id`.
- * `fld_off` is the offset to the field in the structure and `mode`
- * indicates whether cache maintenance need to performed for the write.
- * The `data` is the pointer to data of size specified by `size`.
- * Returns SDS_OK on success or corresponding error codes on failure.
- */
-int sds_struct_write(uint32_t structure_id, unsigned int fld_off,
-               void *data, size_t size, sds_access_mode_t mode)
-{
-       int status;
-       uintptr_t field_base;
-       struct_header_t *header = NULL;
-
-       if (!data)
-               return SDS_ERR_INVALID_PARAMS;
-
-       /* Check if a structure with this ID exists */
-       status = get_struct_header(structure_id, &header);
-       if (status != SDS_OK)
-               return status;
-
-       assert(header);
-
-       if (mode == SDS_ACCESS_MODE_CACHED)
-               inv_dcache_range((uintptr_t)header, SDS_HEADER_SIZE + size);
-
-       if (!IS_SDS_HEADER_VALID(header)) {
-               WARN("SDS: Writing to un-finalized structure 0x%x\n",
-                               structure_id);
-               return SDS_ERR_STRUCT_NOT_FINALIZED;
-       }
-
-       if ((fld_off + size) > GET_SDS_HEADER_STRUCT_SIZE(header))
-               return SDS_ERR_FAIL;
-
-       field_base = (uintptr_t)header + SDS_HEADER_SIZE + fld_off;
-       if (check_uptr_overflow(field_base, size - 1))
-               return SDS_ERR_FAIL;
-
-       /* Copy the required field in the struct */
-       memcpy((void *)field_base, data, size);
-
-       if (mode == SDS_ACCESS_MODE_CACHED)
-               flush_dcache_range((uintptr_t)field_base, size);
-
-       return SDS_OK;
-}
-
-/*
- * Initialize the SDS driver. Also verifies the SDS version and sanity of
- * the SDS structure headers.
- * Returns SDS_OK on success, SDS_ERR_FAIL on error.
- */
-int sds_init(void)
-{
-       sds_mem_base = (uintptr_t)PLAT_ARM_SDS_MEM_BASE;
-
-       if (!IS_SDS_REGION_VALID(sds_mem_base)) {
-               WARN("SDS: No valid SDS Memory Region found\n");
-               return SDS_ERR_FAIL;
-       }
-
-       if (GET_SDS_REGION_SCHEMA_VERSION(sds_mem_base)
-                               != SDS_REGION_SCH_VERSION) {
-               WARN("SDS: Unsupported SDS schema version\n");
-               return SDS_ERR_FAIL;
-       }
-
-       sds_mem_size = GET_SDS_REGION_SIZE(sds_mem_base);
-       if (sds_mem_size > PLAT_ARM_SDS_MEM_SIZE_MAX) {
-               WARN("SDS: SDS Memory Region exceeds size limit\n");
-               return SDS_ERR_FAIL;
-       }
-
-       INFO("SDS: Detected SDS Memory Region (%zu bytes)\n", sds_mem_size);
-
-       if (validate_sds_struct_headers() != SDS_OK)
-               return SDS_ERR_FAIL;
-
-       return SDS_OK;
-}
diff --git a/plat/arm/css/drivers/sds/sds.h b/plat/arm/css/drivers/sds/sds.h
deleted file mode 100644 (file)
index 114ae92..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SDS_H
-#define SDS_H
-
-/* SDS Structure Identifier defines */
-/* AP CPU INFO defines */
-#define SDS_AP_CPU_INFO_STRUCT_ID              1
-#define SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET   0x0
-#define SDS_AP_CPU_INFO_PRIMARY_CPUID_SIZE     0x4
-
-/* ROM Firmware Version defines */
-#define SDS_ROM_VERSION_STRUCT_ID              2
-#define SDS_ROM_VERSION_OFFSET                 0x0
-#define SDS_ROM_VERSION_SIZE                   0x4
-
-/* RAM Firmware version defines */
-#define SDS_RAM_VERSION_STRUCT_ID              3
-#define SDS_RAM_VERSION_OFFSET                 0x0
-#define SDS_RAM_VERSION_SIZE                   0x4
-
-/* Platform Identity defines */
-#define SDS_PLATFORM_IDENTITY_STRUCT_ID                4
-#define SDS_PLATFORM_IDENTITY_ID_OFFSET                0x0
-#define SDS_PLATFORM_IDENTITY_ID_SIZE          0x4
-#define SDS_PLATFORM_IDENTITY_ID_CONFIG_SHIFT  28
-#define SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH  4
-#define SDS_PLATFORM_IDENTITY_ID_CONFIG_MASK   \
-       ((1 << SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH) - 1)
-
-#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_OFFSET 0x4
-#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_SIZE   0x4
-
-/* Reset Syndrome defines */
-#define SDS_RESET_SYNDROME_STRUCT_ID           5
-#define SDS_RESET_SYNDROME_OFFSET              0
-#define SDS_RESET_SYNDROME_SIZE                        4
-#define SDS_RESET_SYNDROME_POW_ON_RESET_BIT    (1 << 0)
-#define SDS_RESET_SYNDROME_SCP_WD_RESET_BIT    (1 << 1)
-#define SDS_RESET_SYNDROME_AP_WD_RESET_BIT     (1 << 2)
-#define SDS_RESET_SYNDROME_SYS_RESET_REQ_BIT   (1 << 3)
-#define SDS_RESET_SYNDROME_M3_LOCKUP_BIT       (1 << 4)
-
-/* SCP Firmware Feature Availability defines */
-#define SDS_FEATURE_AVAIL_STRUCT_ID            6
-#define SDS_FEATURE_AVAIL_OFFSET               0
-#define SDS_FEATURE_AVAIL_SIZE                 4
-#define SDS_FEATURE_AVAIL_SCP_RAM_READY_BIT    (1 << 0)
-#define SDS_FEATURE_AVAIL_DMC_READY_BIT                (1 << 1)
-#define SDS_FEATURE_AVAIL_MSG_IF_READY_BIT     (1 << 2)
-
-/* SCP BL2 Image Metadata defines */
-#define SDS_SCP_IMG_STRUCT_ID                  9
-#define SDS_SCP_IMG_FLAG_OFFSET                        0
-#define SDS_SCP_IMG_FLAG_SIZE                  4
-#define SDS_SCP_IMG_VALID_FLAG_BIT             (1 << 0)
-#define SDS_SCP_IMG_ADDR_OFFSET                        4
-#define SDS_SCP_IMG_ADDR_SIZE                  4
-#define SDS_SCP_IMG_SIZE_OFFSET                        8
-#define SDS_SCP_IMG_SIZE_SIZE                  4
-
-/* SDS Driver Error Codes */
-#define SDS_OK                         0
-#define SDS_ERR_FAIL                   -1
-#define SDS_ERR_INVALID_PARAMS         -2
-#define SDS_ERR_STRUCT_NOT_FOUND       -3
-#define SDS_ERR_STRUCT_NOT_FINALIZED   -4
-
-#ifndef __ASSEMBLY__
-#include <stddef.h>
-#include <stdint.h>
-
-typedef enum {
-       SDS_ACCESS_MODE_NON_CACHED,
-       SDS_ACCESS_MODE_CACHED,
-} sds_access_mode_t;
-
-int sds_init(void);
-int sds_struct_exists(unsigned int structure_id);
-int sds_struct_read(uint32_t structure_id, unsigned int fld_off, void *data,
-               size_t size, sds_access_mode_t mode);
-int sds_struct_write(uint32_t structure_id, unsigned int fld_off, void *data,
-               size_t size, sds_access_mode_t mode);
-#endif /*__ASSEMBLY__ */
-
-#endif /* SDS_H */
diff --git a/plat/arm/css/drivers/sds/sds_private.h b/plat/arm/css/drivers/sds/sds_private.h
deleted file mode 100644 (file)
index 2101dd0..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SDS_PRIVATE_H
-#define SDS_PRIVATE_H
-
-/* SDS Header defines */
-#define SDS_HEADER_ID_SHIFT                    0
-#define SDS_HEADER_ID_WIDTH                    16
-#define SDS_HEADER_ID_MASK                     ((1 << SDS_HEADER_ID_WIDTH) - 1)
-
-#define SDS_HEADER_MINOR_VERSION_WIDTH         8
-#define SDS_HEADER_MINOR_VERSION_SHIFT         16
-#define SDS_HEADER_MAJOR_VERSION_WIDTH         8
-
-#define MAKE_SDS_HEADER_VERSION(major, minor)  \
-       (((((major) & 0xff) << SDS_HEADER_MINOR_VERSION_WIDTH) | ((minor) & 0xff)))
-#define SDS_HEADER_VERSION_MASK                        \
-       ((1 << (SDS_HEADER_MINOR_VERSION_WIDTH + SDS_HEADER_MAJOR_VERSION_WIDTH)) - 1)
-
-#define SDS_HEADER_VERSION                     MAKE_SDS_HEADER_VERSION(1, 0)
-#define SDS_HEADER_STRUCT_SIZE_WIDTH           23
-#define SDS_HEADER_STRUCT_SIZE_SHIFT           1
-#define SDS_HEADER_STRUCT_SIZE_MASK            ((1 << SDS_HEADER_STRUCT_SIZE_WIDTH) - 1)
-#define SDS_HEADER_VALID_MASK                  0x1
-#define SDS_HEADER_VALID_SHIFT                 0
-#define SDS_HEADER_SIZE                                0x8
-
-/* Arbitrary, 16 bit value that indicates a valid SDS Memory Region */
-#define SDS_REGION_SIGNATURE                   0xAA7A
-#define SDS_REGION_SIGNATURE_WIDTH             16
-#define SDS_REGION_SIGNATURE_SHIFT             0
-#define SDS_REGION_SIGNATURE_MASK              ((1 << SDS_REGION_SIGNATURE_WIDTH) - 1)
-
-#define SDS_REGION_STRUCT_COUNT_SHIFT          16
-#define SDS_REGION_STRUCT_COUNT_WIDTH          8
-#define SDS_REGION_STRUCT_COUNT_MASK           ((1 << SDS_REGION_STRUCT_COUNT_WIDTH) - 1)
-
-#define SDS_REGION_SCH_MINOR_SHIFT             24
-#define SDS_REGION_SCH_MINOR_WIDTH             4
-#define SDS_REGION_SCH_MINOR_MASK              ((1 << SDS_REGION_SCH_MINOR_WIDTH) - 1)
-
-#define SDS_REGION_SCH_MAJOR_SHIFT             28
-#define SDS_REGION_SCH_MAJOR_WIDTH             4
-#define SDS_REGION_SCH_MAJOR_MASK              ((1 << SDS_REGION_SCH_MAJOR_WIDTH) - 1)
-
-#define SDS_REGION_SCH_VERSION_MASK            \
-       ((1 << (SDS_REGION_SCH_MINOR_WIDTH + SDS_REGION_SCH_MAJOR_WIDTH)) - 1)
-
-#define MAKE_SDS_REGION_SCH_VERSION(maj, min)  \
-       ((((maj) & SDS_REGION_SCH_MAJOR_MASK) << SDS_REGION_SCH_MINOR_WIDTH) |  \
-       ((min) & SDS_REGION_SCH_MINOR_MASK))
-
-#define SDS_REGION_SCH_VERSION                 MAKE_SDS_REGION_SCH_VERSION(1, 0)
-#define SDS_REGION_REGIONSIZE_OFFSET           0x4
-#define SDS_REGION_DESC_SIZE                   0x8
-
-#ifndef __ASSEMBLY__
-#include <stddef.h>
-#include <stdint.h>
-
-/* Header containing Shared Data Structure metadata */
-typedef struct structure_header {
-       uint32_t reg[2];
-} struct_header_t;
-
-#define GET_SDS_HEADER_ID(_header)                     \
-       ((((struct_header_t *)(_header))->reg[0]) & SDS_HEADER_ID_MASK)
-#define GET_SDS_HEADER_VERSION(_header)                        \
-       (((((struct_header_t *)(_header))->reg[0]) >> SDS_HEADER_MINOR_VERSION_SHIFT)\
-       & SDS_HEADER_VERSION_MASK)
-#define GET_SDS_HEADER_STRUCT_SIZE(_header)            \
-       (((((struct_header_t *)(_header))->reg[1]) >> SDS_HEADER_STRUCT_SIZE_SHIFT)\
-       & SDS_HEADER_STRUCT_SIZE_MASK)
-#define IS_SDS_HEADER_VALID(_header)                   \
-       ((((struct_header_t *)(_header))->reg[1]) & SDS_HEADER_VALID_MASK)
-#define GET_SDS_STRUCT_FIELD(_header, _field_offset)   \
-       ((((uint8_t *)(_header)) + sizeof(struct_header_t)) + (_field_offset))
-
-/* Region Descriptor describing the SDS Memory Region */
-typedef struct region_descriptor {
-       uint32_t reg[2];
-} region_desc_t;
-
-#define IS_SDS_REGION_VALID(region)                    \
-       (((((region_desc_t *)(region))->reg[0]) & SDS_REGION_SIGNATURE_MASK) == SDS_REGION_SIGNATURE)
-#define GET_SDS_REGION_STRUCTURE_COUNT(region)         \
-       (((((region_desc_t *)(region))->reg[0]) >> SDS_REGION_STRUCT_COUNT_SHIFT)\
-       & SDS_REGION_STRUCT_COUNT_MASK)
-#define GET_SDS_REGION_SCHEMA_VERSION(region)          \
-       (((((region_desc_t *)(region))->reg[0]) >> SDS_REGION_SCH_MINOR_SHIFT)\
-       & SDS_REGION_SCH_VERSION_MASK)
-#define GET_SDS_REGION_SIZE(region)            ((((region_desc_t *)(region))->reg[1]))
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* SDS_PRIVATE_H */
index ad7ab81d958536f204945fda1f7e8395d888d03e..c0e655586137f674b42c2412ff1be796d45e9fb3 100644 (file)
@@ -9,15 +9,14 @@
 
 #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>
 
-#include <arm_def.h>
-#include <arm_spm_def.h>
-#include <board_css_def.h>
-#include <css_def.h>
-#include <soc_css_def.h>
-#include <v2m_def.h>
-
 #define PLATFORM_CORE_COUNT            (PLAT_ARM_CLUSTER_COUNT *       \
                                        CSS_SGI_MAX_CPUS_PER_CLUSTER * \
                                        CSS_SGI_MAX_PE_PER_CPU)
 /* Allocate 128KB for CPER buffers */
 #define PLAT_SP_BUF_BASE                       ULL(0x20000)
 
-#define PLAT_ARM_SP_IMAGE_STACK_BASE           (ARM_SP_IMAGE_NS_BUF_BASE + \
-                                               ARM_SP_IMAGE_NS_BUF_SIZE + \
+#define PLAT_ARM_SP_IMAGE_STACK_BASE           (PLAT_SP_IMAGE_NS_BUF_BASE + \
+                                               PLAT_SP_IMAGE_NS_BUF_SIZE + \
                                                PLAT_SP_BUF_BASE)
 
 /* Platform specific SMC FID's used for RAS */
        SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_1, SDEI_MAPF_CRITICAL),
 #define PLAT_ARM_SHARED_SDEI_EVENTS
 
-#define ARM_SP_CPER_BUF_BASE                   (ARM_SP_IMAGE_NS_BUF_BASE + \
-                                               ARM_SP_IMAGE_NS_BUF_SIZE)
+#define ARM_SP_CPER_BUF_BASE                   (PLAT_SP_IMAGE_NS_BUF_BASE + \
+                                               PLAT_SP_IMAGE_NS_BUF_SIZE)
 #define ARM_SP_CPER_BUF_SIZE                   ULL(0x20000)
 #define ARM_SP_CPER_BUF_MMAP                   MAP_REGION2(            \
                                                ARM_SP_CPER_BUF_BASE,   \
                                                PAGE_SIZE)
 
 #else
-#define PLAT_ARM_SP_IMAGE_STACK_BASE   (ARM_SP_IMAGE_NS_BUF_BASE +     \
-                                        ARM_SP_IMAGE_NS_BUF_SIZE)
+#define PLAT_ARM_SP_IMAGE_STACK_BASE   (PLAT_SP_IMAGE_NS_BUF_BASE +    \
+                                        PLAT_SP_IMAGE_NS_BUF_SIZE)
 #endif /* RAS_EXTENSION */
 
 /* Platform ID address */
index 617a62b775db7f07316d42f3e72783c38a61f4b3..bfcb521a3525de1e1f7f84f5112932e08a5ccf9f 100644 (file)
 
 #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_arm.h>
 #include <sgi_ras.h>
 #include <sgi_variant.h>
 
-#include "../../css/drivers/scmi/scmi.h"
-#include "../../css/drivers/mhu/css_mhu_doorbell.h"
-
 sgi_platform_info_t sgi_plat_info;
 
 static scmi_channel_plat_info_t sgi575_scmi_plat_info = {
index 1ed219d65350386a31e25084aca71edf3a04994c..a2f10dcc7f716394238e29aa86ac925dd4fcef30 100644 (file)
@@ -9,6 +9,7 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <common/desc_image_load.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
 #include <sgi_variant.h>
@@ -72,14 +73,11 @@ static int plat_sgi_append_config_node(void)
 bl_params_t *plat_get_next_bl_params(void)
 {
        int ret;
-       bl_params_t *next_bl_params;
 
        ret = plat_sgi_append_config_node();
        if (ret != 0)
                panic();
 
-       next_bl_params = get_next_bl_params_from_mem_params_desc();
-       populate_next_bl_params_config(next_bl_params);
-
-       return next_bl_params;
+       return arm_get_next_bl_params();
 }
+
index 79f3e5b55d0c11da0d2ca0b0180879bec0577fc1..83ca30c87e57c29f6b4df78850f093ee85cc2350 100644 (file)
 #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 <services/secure_partition.h>
 
-#include <arm_def.h>
-#include <arm_spm_def.h>
-#include <plat_arm.h>
-#include "../../../../bl1/bl1_private.h"
-
 #if USE_COHERENT_MEM
 /*
  * The next 2 constants identify the extents of the coherent memory region.
@@ -127,12 +123,12 @@ const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
        .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 = ARM_SP_IMAGE_NS_BUF_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 = ARM_SP_IMAGE_NS_BUF_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,
index a6a32d150d1bd5a6f5985df7dd42c1d2a8caa90d..0001ffdde973f89eb48dbc36746d8023ee056de4 100644 (file)
 #include <bl31/interrupt_mgmt.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/extensions/ras.h>
+#include <plat/arm/common/arm_spm_def.h>
 #include <plat/common/platform.h>
 #include <services/mm_svc.h>
 #include <services/sdei.h>
 #include <services/spm_svc.h>
 
-#include <arm_spm_def.h>
 #include <sgi_ras.h>
 
 static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
index 2921c0c276e5f441855c655ea1e6f5a76c7d7243..dafaf40bf986029ef1145a6f166b9fc1a9550b51 100644 (file)
@@ -4,7 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
 #include <sgi_variant.h>
 
 /* Topology */
index 18d41e3dfffe33e11d4390c2d0a8a8b807d7ed9f..fd1854a038abd54bf57a472df2d180ea8ebc6e7d 100644 (file)
@@ -3,7 +3,8 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include "../../../../../include/plat/arm/board/common/board_arm_oid.h"
+
+#include <plat/arm/board/common/board_arm_oid.h>
 
 /*
  * Required platform OIDs
index e3fa3f30e6ac76c90de4e0c0f104190200b0e9c7..4647e742fa895e1fe2c59e5c90e89851ea7f272f 100644 (file)
@@ -9,14 +9,13 @@
 
 #include <drivers/arm/tzc400.h>
 #include <drivers/arm/tzc_common.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/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
 #include <plat/common/common_def.h>
 
-#include <arm_def.h>
-#include <board_css_def.h>
-#include <css_def.h>
-#include <soc_css_def.h>
-#include <v2m_def.h>
-
 /* CPU topology */
 #define PLAT_ARM_CLUSTER_COUNT         1
 #define PLAT_ARM_CLUSTER_CORE_COUNT    8
index 8b7c5dabbea31858976dc52ad6b8dd55612f799d..203651598d0ee125d6204351d3b9f22592b438df 100644 (file)
@@ -6,10 +6,10 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
 
-#include <plat_arm.h>
 #include <sgm_plat_config.h>
-#include <soc_css.h>
 
 void bl1_early_platform_setup(void)
 {
index 7967cb59c4de29bccdb1b65495b72ed1d6b1a306..7e92ac8350097a78a17fe0104a040149f2d08f04 100644 (file)
@@ -6,13 +6,12 @@
 
 #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_arm.h>
 #include <sgm_plat_config.h>
 
-#include "../../css/drivers/scmi/scmi.h"
-#include "../../css/drivers/mhu/css_mhu_doorbell.h"
-
 static scmi_channel_plat_info_t sgm775_scmi_plat_info = {
                .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
                .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
index a4df9ab19afa20342fb047a3ad555631d7226f5e..e5b4b0338735a0e6e8ad527595c93bf266c58a2f 100644 (file)
@@ -8,9 +8,8 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
 #include <sgm_variant.h>
 
 /*
index 2a43487f1a721b66b2c210b7cc2ce1c288dc4e38..d9e65c513fecc83f52251dbb0f0a34e5f28656fd 100644 (file)
@@ -10,8 +10,8 @@
 #include <platform_def.h>
 
 #include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
 
-#include <plat_arm.h>
 #include <sgm_plat_config.h>
 #include <sgm_variant.h>
 
index 548ec7bd59e0ba06463e4264d500f7df4105223d..21d53069af5631ebed00f534056fe0be94185ef5 100644 (file)
@@ -6,10 +6,10 @@
 
 #include <common/debug.h>
 #include <drivers/arm/tzc_dmc500.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
 
-#include <plat_arm.h>
 #include <sgm_variant.h>
-#include <soc_css.h>
 
 /* Is populated with the DMC-500 controllers base addresses */
 static tzc_dmc500_driver_data_t plat_driver_data;
index ce72464482cb55928f0bbe16acdfd2c1e63aece9..2d9552d7cb83ed62e4d02a51bb6efad61d557d51 100644 (file)
@@ -4,7 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
 #include <sgm_plat_config.h>
 
 /*******************************************************************************
index 39bba94a3016d53aed216df8e91d0116b20ae979..5f40c4c8241487372b0cd78d6b425a1fa27c0451 100644 (file)
@@ -4,7 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
 #include <sgm_plat_config.h>
 
 void tsp_early_platform_setup(void)
index e00946744a7b7e0deec231f6f987ea4b5ba73dc7..8cad2a58d7aeb22acb25b5291b31d33875ab7883 100644 (file)
@@ -4,8 +4,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-PLAT_INCLUDES          +=      -Iinclude/plat/arm/soc/common/
-
 #PLAT_BL_COMMON_SOURCES        +=
 
 BL1_SOURCES            +=      plat/arm/soc/common/soc_css_security.c
index bbc5dcdc553edc8b21aa4d732e11c2f676d3e9ec..4f6bf61b0ccc4272114b2f0156350515cc39491a 100644 (file)
@@ -8,10 +8,7 @@
 
 #include <drivers/arm/nic_400.h>
 #include <lib/mmio.h>
-
-#include <board_css_def.h>
-#include <soc_css.h>
-#include <soc_css_def.h>
+#include <plat/arm/soc/common/soc_css.h>
 
 void soc_css_init_nic400(void)
 {
index a08bdfa72b64f3458eb79608e0f02ba1df26dbcd..a97d763201e305097f3d5862895dd8f0d299429b 100644 (file)
@@ -22,7 +22,6 @@
 #include <hikey_def.h>
 #include <hikey_layout.h>
 
-#include "../../../bl1/bl1_private.h"
 #include "hikey_private.h"
 
 /* Data structure which holds the extents of the trusted RAM for BL1 */
index 38bdbe41767dda18482168fd1c3969662700a813..4a7036cfc742b276c7d2a8436dee75df18413451 100644 (file)
@@ -25,7 +25,6 @@
 #include <plat/common/platform.h>
 
 #include <hi3660.h>
-#include "../../../bl1/bl1_private.h"
 #include "hikey960_def.h"
 #include "hikey960_private.h"
 
index d977c7989ce00dc8a69a34f5fc6b547609ff52f5..4ea3acd5100f3e763795962823b21de9273410a9 100644 (file)
@@ -11,7 +11,7 @@
 #include <plat/common/common_def.h>
 
 #define DDR_BASE                       0x0
-#define DDR_SIZE                       0xC0000000
+#define DDR_SIZE                       0xE0000000
 
 #define DEVICE_BASE                    0xE0000000
 #define DEVICE_SIZE                    0x20000000
index 3e2d79daafd90e4c1c2d2aabf92d381cb0f75d39..7c3c10238d67179d6b2fd913a2b39f0d10148e9e 100644 (file)
 #endif
 
 #ifdef IMAGE_BL2
-#ifdef SPD_opteed
 #define MAX_XLAT_TABLES                        4
-#else
-#define MAX_XLAT_TABLES                        3
-#endif
 #endif
 
 #define MAX_MMAP_REGIONS               16
index eb8ffe4fd00dcc7ac5ffad8b9425f702ff04a3ed..08ad67c5956626d3a74c559182fbafe53ecfe1cd 100644 (file)
@@ -22,7 +22,6 @@
 #include <lib/mmio.h>
 #include <plat/common/platform.h>
 
-#include "../../../bl1/bl1_private.h"
 #include "hi3798cv200.h"
 #include "plat_private.h"
 
index 588d8b4e253b481611c335188f6e4ab8ce2433df..91d33705d7d9ac3ab4264b5f510b479322ccd9af 100644 (file)
@@ -32,8 +32,22 @@ void __dead2 imx_system_reset(void)
 int imx_validate_power_state(unsigned int power_state,
                         psci_power_state_t *req_state)
 {
-       /* TODO */
-       return PSCI_E_INVALID_PARAMS;
+       int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
+       int pwr_type = psci_get_pstate_type(power_state);
+       int state_id = psci_get_pstate_id(power_state);
+
+       if (pwr_lvl > PLAT_MAX_PWR_LVL)
+               return PSCI_E_INVALID_PARAMS;
+
+       if (pwr_type == PSTATE_TYPE_POWERDOWN) {
+               req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
+               if (!state_id)
+                       req_state->pwr_domain_state[MPIDR_AFFLVL1] = PLAT_MAX_RET_STATE;
+               else
+                       req_state->pwr_domain_state[MPIDR_AFFLVL1] = PLAT_MAX_OFF_STATE;
+       }
+
+       return PSCI_E_SUCCESS;
 }
 
 void imx_get_sys_suspend_power_state(psci_power_state_t *req_state)
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
new file mode 100644 (file)
index 0000000..55639cd
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <std_svc.h>
+#include <string.h>
+#include <platform_def.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <imx_sip_svc.h>
+#include <sci/sci.h>
+
+#ifdef PLAT_IMX8QM
+const static int ap_cluster_index[PLATFORM_CLUSTER_COUNT] = {
+       SC_R_A53, SC_R_A72,
+};
+#endif
+
+static int imx_srtc_set_time(uint32_t year_mon,
+                       unsigned long day_hour,
+                       unsigned long min_sec)
+{
+       return sc_timer_set_rtc_time(ipc_handle,
+               year_mon >> 16, year_mon & 0xffff,
+               day_hour >> 16, day_hour & 0xffff,
+               min_sec >> 16, min_sec & 0xffff);
+}
+
+int imx_srtc_handler(uint32_t smc_fid,
+                   void *handle,
+                   u_register_t x1,
+                   u_register_t x2,
+                   u_register_t x3,
+                   u_register_t x4)
+{
+       int ret;
+
+       switch (x1) {
+       case IMX_SIP_SRTC_SET_TIME:
+               ret = imx_srtc_set_time(x2, x3, x4);
+               break;
+       default:
+               ret = SMC_UNK;
+       }
+
+       SMC_RET1(handle, ret);
+}
+
+static void imx_cpufreq_set_target(uint32_t cluster_id, unsigned long freq)
+{
+       sc_pm_clock_rate_t rate = (sc_pm_clock_rate_t)freq;
+
+#ifdef PLAT_IMX8QM
+       sc_pm_set_clock_rate(ipc_handle, ap_cluster_index[cluster_id], SC_PM_CLK_CPU, &rate);
+#endif
+#ifdef PLAT_IMX8QX
+       sc_pm_set_clock_rate(ipc_handle, SC_R_A35, SC_PM_CLK_CPU, &rate);
+#endif
+}
+
+int imx_cpufreq_handler(uint32_t smc_fid,
+                   u_register_t x1,
+                   u_register_t x2,
+                   u_register_t x3)
+{
+       switch (x1) {
+       case IMX_SIP_SET_CPUFREQ:
+               imx_cpufreq_set_target(x2, x3);
+               break;
+       default:
+               return SMC_UNK;
+       }
+
+       return 0;
+}
+
+static bool wakeup_src_irqsteer;
+
+bool imx_is_wakeup_src_irqsteer(void)
+{
+       return wakeup_src_irqsteer;
+}
+
+int imx_wakeup_src_handler(uint32_t smc_fid,
+                   u_register_t x1,
+                   u_register_t x2,
+                   u_register_t x3)
+{
+       switch (x1) {
+       case IMX_SIP_WAKEUP_SRC_IRQSTEER:
+               wakeup_src_irqsteer = true;
+               break;
+       case IMX_SIP_WAKEUP_SRC_SCU:
+               wakeup_src_irqsteer = false;
+               break;
+       default:
+               return SMC_UNK;
+       }
+
+       return SMC_OK;
+}
+
+int imx_otp_handler(uint32_t smc_fid,
+               void *handle,
+               u_register_t x1,
+               u_register_t x2)
+{
+       int ret;
+       uint32_t fuse;
+
+       switch (smc_fid) {
+       case IMX_SIP_OTP_READ:
+               ret = sc_misc_otp_fuse_read(ipc_handle, x1, &fuse);
+               SMC_RET2(handle, ret, fuse);
+               break;
+       case IMX_SIP_OTP_WRITE:
+               ret = sc_misc_otp_fuse_write(ipc_handle, x1, x2);
+               SMC_RET1(handle, ret);
+               break;
+       default:
+               ret = SMC_UNK;
+               SMC_RET1(handle, ret);
+               break;
+       }
+
+       return ret;
+}
+
+int imx_misc_set_temp_handler(uint32_t smc_fid,
+                   u_register_t x1,
+                   u_register_t x2,
+                   u_register_t x3,
+                   u_register_t x4)
+{
+       return sc_misc_set_temp(ipc_handle, x1, x2, x3, x4);
+}
+
+static uint64_t imx_get_commit_hash(u_register_t x2,
+                   u_register_t x3,
+                   u_register_t x4)
+{
+       /* Parse the version_string */
+       char *parse = (char *)version_string;
+       uint64_t hash = 0;
+
+       do {
+               parse = strchr(parse, '-');
+               if (parse) {
+                       parse += 1;
+                       if (*(parse) == 'g') {
+                               /* Default is 7 hexadecimal digits */
+                               memcpy((void *)&hash, (void *)(parse + 1), 7);
+                               break;
+                       }
+               }
+
+       } while (parse != NULL);
+
+       return hash;
+}
+
+uint64_t imx_buildinfo_handler(uint32_t smc_fid,
+                   u_register_t x1,
+                   u_register_t x2,
+                   u_register_t x3,
+                   u_register_t x4)
+{
+       uint64_t ret;
+
+       switch (x1) {
+       case IMX_SIP_BUILDINFO_GET_COMMITHASH:
+               ret = imx_get_commit_hash(x2, x3, x4);
+               break;
+       default:
+               return SMC_UNK;
+       }
+
+       return ret;
+}
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
new file mode 100644 (file)
index 0000000..c27fbf2
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/pmf/pmf.h>
+#include <tools_share/uuid.h>
+#include <imx_sip_svc.h>
+
+static int32_t imx_sip_setup(void)
+{
+       return 0;
+}
+
+static uintptr_t imx_sip_handler(unsigned int 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) {
+#if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX))
+       case  IMX_SIP_SRTC:
+               return imx_srtc_handler(smc_fid, handle, x1, x2, x3, x4);
+       case  IMX_SIP_CPUFREQ:
+               SMC_RET1(handle, imx_cpufreq_handler(smc_fid, x1, x2, x3));
+               break;
+       case  IMX_SIP_WAKEUP_SRC:
+               SMC_RET1(handle, imx_wakeup_src_handler(smc_fid, x1, x2, x3));
+       case IMX_SIP_OTP_READ:
+       case IMX_SIP_OTP_WRITE:
+               return imx_otp_handler(smc_fid, handle, x1, x2);
+       case IMX_SIP_MISC_SET_TEMP:
+               SMC_RET1(handle, imx_misc_set_temp_handler(smc_fid, x1, x2, x3, x4));
+#endif
+       case  IMX_SIP_BUILDINFO:
+               SMC_RET1(handle, imx_buildinfo_handler(smc_fid, x1, x2, x3, x4));
+       default:
+               WARN("Unimplemented i.MX SiP Service Call: 0x%x\n", smc_fid);
+               SMC_RET1(handle, SMC_UNK);
+               break;
+       }
+}
+
+/* Define a runtime service descriptor for fast SMC calls */
+DECLARE_RT_SVC(
+               imx_sip_svc,
+               OEN_SIP_START,
+               OEN_SIP_END,
+               SMC_TYPE_FAST,
+               imx_sip_setup,
+               imx_sip_handler
+);
index 7dbde795b9eba316a6e67d94459677b555283d26..03ec3133e304af03a672153de817da450ea1b24c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #define UTS   0xb4 /* UART Test Register (mx31) */
 #define  URXD_RX_DATA    (0xFF)
 
-       .globl  console_uart_register
-       .globl  console_uart_init
-       .globl  console_uart_putc
-       .globl  console_uart_getc
+       .globl  console_imx_uart_register
+       .globl  console_imx_uart_init
+       .globl  console_imx_uart_putc
+       .globl  console_imx_uart_getc
+       .globl  console_imx_uart_flush
 
 func console_imx_uart_register
        mov     x7, x30
@@ -32,7 +33,7 @@ func console_imx_uart_register
 
        mov     x0, x6
        mov     x30, x7
-       finish_console_register imx_uart putc=1, getc=1
+       finish_console_register imx_uart putc=1, getc=1, flush=1
 
 register_fail:
        ret     x7
@@ -82,3 +83,8 @@ getc_error:
        mov     w0, #-1
        ret
 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/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
new file mode 100644 (file)
index 0000000..648be37
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __IMX_SIP_SVC_H__
+#define __IMX_SIP_SVC_H__
+
+/* SMC function IDs for SiP Service queries */
+#define IMX_SIP_CPUFREQ                        0xC2000001
+#define IMX_SIP_SET_CPUFREQ            0x00
+
+#define IMX_SIP_SRTC                   0xC2000002
+#define IMX_SIP_SRTC_SET_TIME          0x00
+
+#define IMX_SIP_BUILDINFO                      0xC2000003
+#define IMX_SIP_BUILDINFO_GET_COMMITHASH       0x00
+
+#define IMX_SIP_WAKEUP_SRC             0xC2000009
+#define IMX_SIP_WAKEUP_SRC_SCU         0x1
+#define IMX_SIP_WAKEUP_SRC_IRQSTEER    0x2
+
+#define IMX_SIP_OTP_READ               0xC200000A
+#define IMX_SIP_OTP_WRITE              0xC200000B
+
+#define IMX_SIP_MISC_SET_TEMP          0xC200000C
+
+#if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX))
+int imx_cpufreq_handler(uint32_t smc_fid, u_register_t x1,
+                       u_register_t x2, u_register_t x3);
+int imx_srtc_handler(uint32_t smc_fid, void *handle, u_register_t x1,
+                    u_register_t x2, u_register_t x3, u_register_t x4);
+int imx_wakeup_src_handler(uint32_t smc_fid, u_register_t x1,
+                          u_register_t x2, u_register_t x3);
+int imx_otp_handler(uint32_t smc_fid, void *handle,
+                   u_register_t x1, u_register_t x2);
+int imx_misc_set_temp_handler(uint32_t smc_fid, u_register_t x1,
+                             u_register_t x2, u_register_t x3,
+                             u_register_t x4);
+uint64_t imx_buildinfo_handler(uint32_t smc_fid, u_register_t x1,
+                              u_register_t x2, u_register_t x3,
+                              u_register_t x4);
+#endif
+
+#endif /* __IMX_SIP_SVC_H__ */
index a251024f162db155dc3aad5fe37047ce8cbc729b..1b52e2f0b8878223c875573d9e2840d8a0fe511d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,7 +16,7 @@ typedef struct {
        uintptr_t base;
 } console_uart_t;
 
-int console_uart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
+int console_imx_uart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
                           console_uart_t *console);
 #endif /*__ASSEMBLY__*/
 
index 8d83173fdb78f1d34d4b23448eac79a120307948..be99b970f5e0901e254b046686ab16a5f71018ed 100644 (file)
 #include <drivers/arm/gicv3.h>
 #include <lib/psci/psci.h>
 
+struct plat_gic_ctx {
+       gicv3_redist_ctx_t rdist_ctx[PLATFORM_CORE_COUNT];
+       gicv3_dist_ctx_t dist_ctx;
+};
+
 unsigned int plat_calc_core_pos(uint64_t mpidr);
 void imx_mailbox_init(uintptr_t base_addr);
 void plat_gic_driver_init(void);
@@ -23,5 +28,8 @@ void __dead2 imx_system_reset(void);
 int imx_validate_power_state(unsigned int power_state,
                        psci_power_state_t *req_state);
 void imx_get_sys_suspend_power_state(psci_power_state_t *req_state);
+bool imx_is_wakeup_src_irqsteer(void);
+void plat_gic_save(unsigned int proc_num, struct plat_gic_ctx *ctx);
+void plat_gic_restore(unsigned int proc_num, struct plat_gic_ctx *ctx);
 
 #endif /* PLAT_IMX8_H */
index f0a25027c24dea04a2c404e5b9deea5e4bb18795..2c45bb8b0bab5f691979c45387e6eac8ca06d9ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,5 +15,7 @@
 #include <sci/svc/pad/sci_pad_api.h>
 #include <sci/svc/pm/sci_pm_api.h>
 #include <sci/svc/rm/sci_rm_api.h>
+#include <sci/svc/timer/sci_timer_api.h>
+#include <sci/svc/misc/sci_misc_api.h>
 
 #endif /* SCI_H */
diff --git a/plat/imx/common/include/sci/svc/misc/sci_misc_api.h b/plat/imx/common/include/sci/svc/misc/sci_misc_api.h
new file mode 100644 (file)
index 0000000..d9dd49d
--- /dev/null
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Miscellaneous (MISC) function.
+ *
+ * @addtogroup MISC_SVC (SVC) Miscellaneous Service
+ *
+ * Module for the Miscellaneous (MISC) service.
+ *
+ * @{
+ */
+
+#ifndef SC_MISC_API_H
+#define SC_MISC_API_H
+
+/* Includes */
+
+#include <sci/svc/rm/sci_rm_api.h>
+#include <sci/sci_types.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_MISC_DMA_GRP_W       5U     /* Width of sc_misc_dma_group_t */
+/*@}*/
+
+/*! Max DMA channel priority group */
+#define SC_MISC_DMA_GRP_MAX     31U
+
+/*!
+ * @name Defines for sc_misc_boot_status_t
+ */
+/*@{*/
+#define SC_MISC_BOOT_STATUS_SUCCESS     0U     /* Success */
+#define SC_MISC_BOOT_STATUS_SECURITY    1U     /* Security violation */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_seco_auth_cmd_t
+ */
+/*@{*/
+#define SC_MISC_SECO_AUTH_SECO_FW       0U     /* SECO Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_TX_FW    1U     /* HDMI TX Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_RX_FW    2U     /* HDMI RX Firmware */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_temp_t
+ */
+/*@{*/
+#define SC_MISC_TEMP                    0U     /* Temp sensor */
+#define SC_MISC_TEMP_HIGH               1U     /* Temp high alarm */
+#define SC_MISC_TEMP_LOW                2U     /* Temp low alarm */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_seco_auth_cmd_t
+ */
+/*@{*/
+#define SC_MISC_AUTH_CONTAINER          0U     /* Authenticate container */
+#define SC_MISC_VERIFY_IMAGE            1U     /* Verify image */
+#define SC_MISC_REL_CONTAINER           2U     /* Release container */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to store a DMA channel priority group.
+ */
+typedef uint8_t sc_misc_dma_group_t;
+
+/*!
+ * This type is used report boot status.
+ */
+typedef uint8_t sc_misc_boot_status_t;
+
+/*!
+ * This type is used to issue SECO authenticate commands.
+ */
+typedef uint8_t sc_misc_seco_auth_cmd_t;
+
+/*!
+ * This type is used report boot status.
+ */
+typedef uint8_t sc_misc_temp_t;
+
+/* Functions */
+
+/*!
+ * @name Control Functions
+ * @{
+ */
+
+/*!
+ * This function sets a miscellaneous control value.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource the control is associated with
+ * @param[in]     ctrl        control to change
+ * @param[in]     val         value to apply to the control
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ *   of the owner
+ *
+ * Refer to the [Control List](@ref CONTROLS) for valid control values.
+ */
+sc_err_t sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+                            sc_ctrl_t ctrl, uint32_t val);
+
+/*!
+ * This function gets a miscellaneous control value.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource the control is associated with
+ * @param[in]     ctrl        control to get
+ * @param[out]    val         pointer to return the control value
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ *   of the owner
+ *
+ * Refer to the [Control List](@ref CONTROLS) for valid control values.
+ */
+sc_err_t sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource,
+                            sc_ctrl_t ctrl, uint32_t *val);
+
+/* @} */
+
+/*!
+ * @name DMA Functions
+ * @{
+ */
+
+/*!
+ * This function configures the max DMA channel priority group for a
+ * partition.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     pt          handle of partition to assign \a max
+ * @param[in]     max         max priority group (0-31)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent
+ *   of the affected partition
+ *
+ * Valid \a max range is 0-31 with 0 being the lowest and 31 the highest.
+ * Default is the max priority group for the parent partition of \a pt.
+ */
+sc_err_t sc_misc_set_max_dma_group(sc_ipc_t ipc, sc_rm_pt_t pt,
+                                  sc_misc_dma_group_t max);
+
+/*!
+ * This function configures the priority group for a DMA channel.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    DMA channel resource
+ * @param[in]     group       priority group (0-31)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or parent
+ *   of the owner of the DMA channel
+ *
+ * Valid \a group range is 0-31 with 0 being the lowest and 31 the highest.
+ * The max value of \a group is limited by the partition max set using
+ * sc_misc_set_max_dma_group().
+ */
+sc_err_t sc_misc_set_dma_group(sc_ipc_t ipc, sc_rsrc_t resource,
+                              sc_misc_dma_group_t group);
+
+/* @} */
+
+/*!
+ * @name Security Functions
+ * @{
+ */
+
+/*!
+ * This function loads a SECO image.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     addr_src    address of image source
+ * @param[in]     addr_dst    address of image destination
+ * @param[in]     len         length of image to load
+ * @param[in]     fw          SC_TRUE = firmware load
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to load images via the SECO. Examples include SECO
+ * Firmware and IVT/CSF data used for authentication. These are usually
+ * loaded into SECO TCM. \a addr_src is in secure memory.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+                                sc_faddr_t addr_dst, uint32_t len,
+                                sc_bool_t fw);
+
+/*!
+ * This function is used to authenticate a SECO image or command.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     cmd         authenticate command
+ * @param[in]     addr        address of/or metadata
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to authenticate a SECO image or issue a security
+ * command. \a addr often points to an container. It is also
+ * just data (or even unused) for some commands.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_authenticate(sc_ipc_t ipc,
+                                  sc_misc_seco_auth_cmd_t cmd,
+                                  sc_faddr_t addr);
+
+/*!
+ * This function securely writes a group of fuse words.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     addr        address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function securely enables debug.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     addr        address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function updates the lifecycle of the device.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     lifecycle   new lifecycle
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This message is used for going from Open to NXP Closed to OEM Closed.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t lifecycle);
+
+/*!
+ * This function updates the lifecycle to one of the return lifecycles.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     addr        address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * To switch back to NXP states (Full Field Return), message must be signed
+ * by NXP SRK. For OEM States (Partial Field Return), must be signed by OEM
+ * SRK.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function is used to return the SECO FW build info.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    version     pointer to return build number
+ * @param[out]    commit      pointer to return commit ID (git SHA-1)
+ */
+void sc_misc_seco_build_info(sc_ipc_t ipc, uint32_t *version, uint32_t *commit);
+
+/*!
+ * This function is used to return SECO chip info.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    lc          pointer to return lifecycle
+ * @param[out]    monotonic   pointer to return monotonic counter
+ * @param[out]    uid_l       pointer to return UID (lower 32 bits)
+ * @param[out]    uid_h       pointer to return UID (upper 32 bits)
+ */
+sc_err_t sc_misc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+                               uint16_t *monotonic, uint32_t *uid_l,
+                               uint32_t *uid_h);
+
+/* @} */
+
+/*!
+ * @name Debug Functions
+ * @{
+ */
+
+/*!
+ * This function is used output a debug character from the SCU UART.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     ch          character to output
+ */
+void sc_misc_debug_out(sc_ipc_t ipc, uint8_t ch);
+
+/*!
+ * This function starts/stops emulation waveform capture.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     enable      flag to enable/disable capture
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_UNAVAILABLE if not running on emulation
+ */
+sc_err_t sc_misc_waveform_capture(sc_ipc_t ipc, sc_bool_t enable);
+
+/*!
+ * This function is used to return the SCFW build info.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    build       pointer to return build number
+ * @param[out]    commit      pointer to return commit ID (git SHA-1)
+ */
+void sc_misc_build_info(sc_ipc_t ipc, uint32_t *build, uint32_t *commit);
+
+/*!
+ * This function is used to return the device's unique ID.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    id_l        pointer to return lower 32-bit of ID [31:0]
+ * @param[out]    id_h        pointer to return upper 32-bits of ID [63:32]
+ */
+void sc_misc_unique_id(sc_ipc_t ipc, uint32_t *id_l, uint32_t *id_h);
+
+/* @} */
+
+/*!
+ * @name Other Functions
+ * @{
+ */
+
+/*!
+ * This function configures the ARI match value for PCIe/SATA resources.
+ *
+ * @param[in]     ipc          IPC handle
+ * @param[in]     resource     match resource
+ * @param[in]     resource_mst PCIe/SATA master to match
+ * @param[in]     ari          ARI to match
+ * @param[in]     enable       enable match or not
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or parent
+ *   of the owner of the resource and translation
+ *
+ * For PCIe, the ARI is the 16-bit value that includes the bus number,
+ * device number, and function number. For SATA, this value includes the
+ * FISType and PM_Port.
+ */
+sc_err_t sc_misc_set_ari(sc_ipc_t ipc, sc_rsrc_t resource,
+                        sc_rsrc_t resource_mst, uint16_t ari,
+                        sc_bool_t enable);
+
+/*!
+ * This function reports boot status.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     status      boot status
+ *
+ * This is used by SW partitions to report status of boot. This is
+ * normally used to report a boot failure.
+ */
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status);
+
+/*!
+ * This function tells the SCFW that a CPU is done booting.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     cpu         CPU that is done booting
+ *
+ * This is called by early booting CPUs to report they are done with
+ * initialization. After starting early CPUs, the SCFW halts the
+ * booting process until they are done. During this time, early
+ * CPUs can call the SCFW with lower latency as the SCFW is idle.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the CPU owner
+ */
+sc_err_t sc_misc_boot_done(sc_ipc_t ipc, sc_rsrc_t cpu);
+
+/*!
+ * This function reads a given fuse word index.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     word        fuse word index
+ * @param[out]    val         fuse read value
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_NOACCESS if read operation failed
+ * - SC_ERR_LOCKED if read operation is locked
+ */
+sc_err_t sc_misc_otp_fuse_read(sc_ipc_t ipc, uint32_t word, uint32_t *val);
+
+/*!
+ * This function writes a given fuse word index.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     word        fuse word index
+ * @param[in]     val         fuse write value
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_NOACCESS if write operation failed
+ * - SC_ERR_LOCKED if write operation is locked
+ */
+sc_err_t sc_misc_otp_fuse_write(sc_ipc_t ipc, uint32_t word, uint32_t val);
+
+/*!
+ * This function sets a temp sensor alarm.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource with sensor
+ * @param[in]     temp        alarm to set
+ * @param[in]     celsius     whole part of temp to set
+ * @param[in]     tenths      fractional part of temp to set
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * This function will enable the alarm interrupt if the temp requested is
+ * not the min/max temp. This enable automatically clears when the alarm
+ * occurs and this function has to be called again to re-enable.
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if parameters invalid
+ */
+sc_err_t sc_misc_set_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+                         sc_misc_temp_t temp, int16_t celsius, int8_t tenths);
+
+/*!
+ * This function gets a temp sensor value.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource with sensor
+ * @param[in]     temp        value to get (sensor or alarm)
+ * @param[out]    celsius     whole part of temp to get
+ * @param[out]    tenths      fractional part of temp to get
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if parameters invalid
+ */
+sc_err_t sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+                         sc_misc_temp_t temp, int16_t *celsius,
+                         int8_t *tenths);
+
+/*!
+ * This function returns the boot device.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    dev         pointer to return boot device
+ */
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *dev);
+
+/*!
+ * This function returns the current status of the ON/OFF button.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    status      pointer to return button status
+ */
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status);
+
+/* @} */
+
+#endif                         /* SC_MISC_API_H */
+
+/**@}*/
diff --git a/plat/imx/common/include/sci/svc/timer/sci_timer_api.h b/plat/imx/common/include/sci/svc/timer/sci_timer_api.h
new file mode 100644 (file)
index 0000000..f8423ab
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Timer function.
+ *
+ * @addtogroup TIMER_SVC (SVC) Timer Service
+ *
+ * Module for the Timer service. This includes support for the watchdog, RTC,
+ * and system counter. Note every resource partition has a watchdog it can
+ * use.
+ *
+ * @{
+ */
+
+#ifndef SC_TIMER_API_H
+#define SC_TIMER_API_H
+
+/* Includes */
+
+#include <sci/sci_types.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_TIMER_ACTION_W   3U /* Width of sc_timer_wdog_action_t */
+/*@}*/
+
+/*!
+ * @name Defines for sc_timer_wdog_action_t
+ */
+/*@{*/
+#define SC_TIMER_WDOG_ACTION_PARTITION      0U /* Reset partition */
+#define SC_TIMER_WDOG_ACTION_WARM           1U /* Warm reset system */
+#define SC_TIMER_WDOG_ACTION_COLD           2U /* Cold reset system */
+#define SC_TIMER_WDOG_ACTION_BOARD          3U /* Reset board */
+#define SC_TIMER_WDOG_ACTION_IRQ            4U /* Only generate IRQs */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to configure the watchdog action.
+ */
+typedef uint8_t sc_timer_wdog_action_t;
+
+/*!
+ * This type is used to declare a watchdog time value in milliseconds.
+ */
+typedef uint32_t sc_timer_wdog_time_t;
+
+/* Functions */
+
+/*!
+ * @name Watchdog Functions
+ * @{
+ */
+
+/*!
+ * This function sets the watchdog timeout in milliseconds. If not
+ * set then the timeout defaults to the max. Once locked this value
+ * cannot be changed.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     timeout     timeout period for the watchdog
+ *
+ * @return Returns an error code (SC_ERR_NONE = success, SC_ERR_LOCKED
+ *         = locked).
+ */
+sc_err_t sc_timer_set_wdog_timeout(sc_ipc_t ipc, sc_timer_wdog_time_t timeout);
+
+/*!
+ * This function sets the watchdog pre-timeout in milliseconds. If not
+ * set then the pre-timeout defaults to the max. Once locked this value
+ * cannot be changed.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     pre_timeout pre-timeout period for the watchdog
+ *
+ * When the pre-timeout expires an IRQ will be generated. Note this timeout
+ * clears when the IRQ is triggered. An IRQ is generated for the failing
+ * partition and all of its child partitions.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_set_wdog_pre_timeout(sc_ipc_t ipc,
+                                      sc_timer_wdog_time_t pre_timeout);
+
+/*!
+ * This function starts the watchdog.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     lock        boolean indicating the lock status
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * If \a lock is set then the watchdog cannot be stopped or the timeout
+ * period changed.
+ */
+sc_err_t sc_timer_start_wdog(sc_ipc_t ipc, sc_bool_t lock);
+
+/*!
+ * This function stops the watchdog if it is not locked.
+ *
+ * @param[in]     ipc         IPC handle
+ *
+ * @return Returns an error code (SC_ERR_NONE = success, SC_ERR_LOCKED
+ *         = locked).
+ */
+sc_err_t sc_timer_stop_wdog(sc_ipc_t ipc);
+
+/*!
+ * This function pings (services, kicks) the watchdog resetting the time
+ * before expiration back to the timeout.
+ *
+ * @param[in]     ipc         IPC handle
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_ping_wdog(sc_ipc_t ipc);
+
+/*!
+ * This function gets the status of the watchdog. All arguments are
+ * in milliseconds.
+ *
+ * @param[in]     ipc             IPC handle
+ * @param[out]    timeout         pointer to return the timeout
+ * @param[out]    max_timeout     pointer to return the max timeout
+ * @param[out]    remaining_time  pointer to return the time remaining
+ *                                until trigger
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_get_wdog_status(sc_ipc_t ipc,
+                                 sc_timer_wdog_time_t *timeout,
+                                 sc_timer_wdog_time_t *max_timeout,
+                                 sc_timer_wdog_time_t *remaining_time);
+
+/*!
+ * This function gets the status of the watchdog of a partition. All
+ * arguments are in milliseconds.
+ *
+ * @param[in]     ipc             IPC handle
+ * @param[in]     pt              partition to query
+ * @param[out]    enb             pointer to return enable status
+ * @param[out]    timeout         pointer to return the timeout
+ * @param[out]    remaining_time  pointer to return the time remaining
+ *                                until trigger
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_pt_get_wdog_status(sc_ipc_t ipc, sc_rm_pt_t pt,
+                                    sc_bool_t *enb,
+                                    sc_timer_wdog_time_t *timeout,
+                                    sc_timer_wdog_time_t *remaining_time);
+
+/*!
+ * This function configures the action to be taken when a watchdog
+ * expires.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     pt          partition to affect
+ * @param[in]     action      action to take
+ *
+ * Default action is inherited from the parent.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid parameters,
+ * - SC_ERR_NOACCESS if caller's partition is not the SYSTEM owner,
+ * - SC_ERR_LOCKED if the watchdog is locked
+ */
+sc_err_t sc_timer_set_wdog_action(sc_ipc_t ipc,
+                                 sc_rm_pt_t pt, sc_timer_wdog_action_t action);
+
+/* @} */
+
+/*!
+ * @name Real-Time Clock (RTC) Functions
+ * @{
+ */
+
+/*!
+ * This function sets the RTC time. Only the owner of the SC_R_SYSTEM
+ * resource can set the time.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     year        year (min 1970)
+ * @param[in]     mon         month (1-12)
+ * @param[in]     day         day of the month (1-31)
+ * @param[in]     hour        hour (0-23)
+ * @param[in]     min         minute (0-59)
+ * @param[in]     sec         second (0-59)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters,
+ * - SC_ERR_NOACCESS if caller's partition is not the SYSTEM owner
+ */
+sc_err_t sc_timer_set_rtc_time(sc_ipc_t ipc, uint16_t year, uint8_t mon,
+                              uint8_t day, uint8_t hour, uint8_t min,
+                              uint8_t sec);
+
+/*!
+ * This function gets the RTC time.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    year        pointer to return year (min 1970)
+ * @param[out]    mon         pointer to return month (1-12)
+ * @param[out]    day         pointer to return day of the month (1-31)
+ * @param[out]    hour        pointer to return hour (0-23)
+ * @param[out]    min         pointer to return minute (0-59)
+ * @param[out]    sec         pointer to return second (0-59)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_get_rtc_time(sc_ipc_t ipc, uint16_t *year, uint8_t *mon,
+                              uint8_t *day, uint8_t *hour, uint8_t *min,
+                              uint8_t *sec);
+
+/*!
+ * This function gets the RTC time in seconds since 1/1/1970.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    sec         pointer to return second
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_get_rtc_sec1970(sc_ipc_t ipc, uint32_t *sec);
+
+/*!
+ * This function sets the RTC alarm.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     year        year (min 1970)
+ * @param[in]     mon         month (1-12)
+ * @param[in]     day         day of the month (1-31)
+ * @param[in]     hour        hour (0-23)
+ * @param[in]     min         minute (0-59)
+ * @param[in]     sec         second (0-59)
+ *
+ * Note this alarm setting clears when the alarm is triggered.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_set_rtc_alarm(sc_ipc_t ipc, uint16_t year, uint8_t mon,
+                               uint8_t day, uint8_t hour, uint8_t min,
+                               uint8_t sec);
+
+/*!
+ * This function sets the RTC alarm (periodic mode).
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     sec         period in seconds
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_set_rtc_periodic_alarm(sc_ipc_t ipc, uint32_t sec);
+
+/*!
+ * This function cancels the RTC alarm.
+ *
+ * @param[in]     ipc         IPC handle
+ *
+ * Note this alarm setting clears when the alarm is triggered.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_cancel_rtc_alarm(sc_ipc_t ipc);
+
+/*!
+ * This function sets the RTC calibration value. Only the owner of the SC_R_SYSTEM
+ * resource can set the calibration.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     count       calbration count (-16 to 15)
+ *
+ * The calibration value is a 5-bit value including the sign bit, which is
+ * implemented in 2's complement. It is added or subtracted from the RTC on
+ * a perdiodic basis, once per 32768 cycles of the RTC clock.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_set_rtc_calb(sc_ipc_t ipc, int8_t count);
+
+/* @} */
+
+/*!
+ * @name System Counter (SYSCTR) Functions
+ * @{
+ */
+
+/*!
+ * This function sets the SYSCTR alarm.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     ticks       number of 8MHz cycles
+ *
+ * Note this alarm setting clears when the alarm is triggered.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_set_sysctr_alarm(sc_ipc_t ipc, uint64_t ticks);
+
+/*!
+ * This function sets the SYSCTR alarm (periodic mode).
+ *
+ * @param[in]     ipc          IPC handle
+ * @param[in]     ticks        number of 8MHz cycles
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_set_sysctr_periodic_alarm(sc_ipc_t ipc, uint64_t ticks);
+
+/*!
+ * This function cancels the SYSCTR alarm.
+ *
+ * @param[in]     ipc         IPC handle
+ *
+ * Note this alarm setting clears when the alarm is triggered.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_cancel_sysctr_alarm(sc_ipc_t ipc);
+
+/* @} */
+
+#endif                         /* SC_TIMER_API_H */
+
+/**@}*/
index 668fd624964ab0e1bccd0091b97f1bf026909bda..01628680f770832e9a42f229d94e48b73e5de1ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,6 +15,7 @@
        .globl  console_lpuart_init
        .globl  console_lpuart_putc
        .globl  console_lpuart_getc
+       .globl  console_lpuart_flush
 
 func console_lpuart_register
        mov     x7, x30
@@ -27,7 +28,7 @@ func console_lpuart_register
 
        mov     x0, x6
        mov     x30, x7
-       finish_console_register lpuart putc=1, getc=1
+       finish_console_register lpuart putc=1, getc=1, flush=1
 
 register_fail:
        ret     x7
@@ -70,3 +71,8 @@ getc_error:
        mov     w0, #-1
        ret
 endfunc console_lpuart_getc
+
+func console_lpuart_flush
+       mov     x0, #0
+       ret
+endfunc console_lpuart_flush
index aec0b6c9b13a143cec6f0b3aeda6b4da674fd95b..27c525b720ebad5f1628b6020fa71e03cdfacc85 100644 (file)
@@ -73,3 +73,19 @@ void plat_gic_pcpu_init(void)
 {
        gicv3_rdistif_init(plat_my_core_pos());
 }
+
+void plat_gic_save(unsigned int proc_num, struct plat_gic_ctx *ctx)
+{
+       /* save the gic rdist/dist context */
+       for (int i = 0; i < PLATFORM_CORE_COUNT; i++)
+               gicv3_rdistif_save(i, &ctx->rdist_ctx[i]);
+       gicv3_distif_save(&ctx->dist_ctx);
+}
+
+void plat_gic_restore(unsigned int proc_num, struct plat_gic_ctx *ctx)
+{
+       /* restore the gic rdist/dist context */
+       gicv3_distif_init_restore(&ctx->dist_ctx);
+       for (int i = 0; i < PLATFORM_CORE_COUNT; i++)
+               gicv3_rdistif_init_restore(i, &ctx->rdist_ctx[i]);
+}
index 26d9bdfef9671c8a7ca5f7f024ea366668b84a22..66e956d8a05198df354cdebbe30a7eaa98280a17 100644 (file)
@@ -8,6 +8,21 @@
 
 #include "imx8_mu.h"
 
+void MU_Resume(uint32_t base)
+{
+       uint32_t reg, i;
+
+       reg = mmio_read_32(base + MU_ACR_OFFSET1);
+       /* Clear GIEn, RIEn, TIEn, GIRn and ABFn. */
+       reg &= ~(MU_CR_GIEn_MASK1 | MU_CR_RIEn_MASK1 | MU_CR_TIEn_MASK1
+                       | MU_CR_GIRn_MASK1 | MU_CR_Fn_MASK1);
+       mmio_write_32(base + MU_ACR_OFFSET1, reg);
+
+       /* Enable all RX interrupts */
+       for (i = 0; i < MU_RR_COUNT; i++)
+               MU_EnableRxFullInt(base, i);
+}
+
 void MU_EnableRxFullInt(uint32_t base, uint32_t index)
 {
        uint32_t reg = mmio_read_32(base + MU_ACR_OFFSET1);
index 8c78877283026dceccdfae2d0ff161fd9a8fac69..edcac7bf3d0ce29d5f64ab2749428641e0fb6764 100644 (file)
@@ -33,3 +33,4 @@ void MU_SendMessage(uint32_t base, uint32_t regIndex, uint32_t msg);
 void MU_ReceiveMsg(uint32_t base, uint32_t regIndex, uint32_t *msg);
 void MU_EnableGeneralInt(uint32_t base, uint32_t index);
 void MU_EnableRxFullInt(uint32_t base, uint32_t index);
+void MU_Resume(uint32_t base);
index b277877ec87d6ec74106912786a31d2403f01c07..92c7190ea19fa7a0ef112575e868a4e9589e4bba 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,4 +8,6 @@ BL31_SOURCES    +=      plat/imx/common/sci/ipc.c                       \
                        plat/imx/common/sci/imx8_mu.c                   \
                        plat/imx/common/sci/svc/pad/pad_rpc_clnt.c      \
                        plat/imx/common/sci/svc/pm/pm_rpc_clnt.c        \
-                       plat/imx/common/sci/svc/rm/rm_rpc_clnt.c
+                       plat/imx/common/sci/svc/rm/rm_rpc_clnt.c        \
+                       plat/imx/common/sci/svc/timer/timer_rpc_clnt.c  \
+                       plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
diff --git a/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c b/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
new file mode 100644 (file)
index 0000000..080de6a
--- /dev/null
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * File containing client-side RPC functions for the MISC service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup MISC_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <sci/sci_types.h>
+#include <sci/svc/rm/sci_rm_api.h>
+#include <sci/svc/misc/sci_misc_api.h>
+#include <sci/sci_rpc.h>
+#include <stdlib.h>
+#include "sci_misc_rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+                            sc_ctrl_t ctrl, uint32_t val)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_CONTROL;
+       RPC_U32(&msg, 0U) = (uint32_t)ctrl;
+       RPC_U32(&msg, 4U) = (uint32_t)val;
+       RPC_U16(&msg, 8U) = (uint16_t)resource;
+       RPC_SIZE(&msg) = 4U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource,
+                            sc_ctrl_t ctrl, uint32_t *val)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_CONTROL;
+       RPC_U32(&msg, 0U) = (uint32_t)ctrl;
+       RPC_U16(&msg, 4U) = (uint16_t)resource;
+       RPC_SIZE(&msg) = 3U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (val != NULL)
+               *val = RPC_U32(&msg, 0U);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_max_dma_group(sc_ipc_t ipc, sc_rm_pt_t pt,
+                                  sc_misc_dma_group_t max)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_MAX_DMA_GROUP;
+       RPC_U8(&msg, 0U) = (uint8_t)pt;
+       RPC_U8(&msg, 1U) = (uint8_t)max;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_dma_group(sc_ipc_t ipc, sc_rsrc_t resource,
+                              sc_misc_dma_group_t group)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_DMA_GROUP;
+       RPC_U16(&msg, 0U) = (uint16_t)resource;
+       RPC_U8(&msg, 2U) = (uint8_t)group;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+                                sc_faddr_t addr_dst, uint32_t len,
+                                sc_bool_t fw)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_IMAGE_LOAD;
+       RPC_U32(&msg, 0U) = (uint32_t)(addr_src >> 32U);
+       RPC_U32(&msg, 4U) = (uint32_t)addr_src;
+       RPC_U32(&msg, 8U) = (uint32_t)(addr_dst >> 32U);
+       RPC_U32(&msg, 12U) = (uint32_t)addr_dst;
+       RPC_U32(&msg, 16U) = (uint32_t)len;
+       RPC_U8(&msg, 20U) = (uint8_t)fw;
+       RPC_SIZE(&msg) = 7U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_authenticate(sc_ipc_t ipc,
+                                  sc_misc_seco_auth_cmd_t cmd, sc_faddr_t addr)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_AUTHENTICATE;
+       RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+       RPC_U32(&msg, 4U) = (uint32_t)addr;
+       RPC_U8(&msg, 8U) = (uint8_t)cmd;
+       RPC_SIZE(&msg) = 4U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_FUSE_WRITE;
+       RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+       RPC_U32(&msg, 4U) = (uint32_t)addr;
+       RPC_SIZE(&msg) = 3U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_ENABLE_DEBUG;
+       RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+       RPC_U32(&msg, 4U) = (uint32_t)addr;
+       RPC_SIZE(&msg) = 3U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t lifecycle)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_FORWARD_LIFECYCLE;
+       RPC_U32(&msg, 0U) = (uint32_t)lifecycle;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_RETURN_LIFECYCLE;
+       RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+       RPC_U32(&msg, 4U) = (uint32_t)addr;
+       RPC_SIZE(&msg) = 3U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+void sc_misc_seco_build_info(sc_ipc_t ipc, uint32_t *version, uint32_t *commit)
+{
+       sc_rpc_msg_t msg;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_BUILD_INFO;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (version != NULL)
+               *version = RPC_U32(&msg, 0U);
+
+       if (commit != NULL)
+               *commit = RPC_U32(&msg, 4U);
+}
+
+sc_err_t sc_misc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+                               uint16_t *monotonic, uint32_t *uid_l,
+                               uint32_t *uid_h)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_CHIP_INFO;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (uid_l != NULL)
+               *uid_l = RPC_U32(&msg, 0U);
+
+       if (uid_h != NULL)
+               *uid_h = RPC_U32(&msg, 4U);
+
+       if (lc != NULL)
+               *lc = RPC_U16(&msg, 8U);
+
+       if (monotonic != NULL)
+               *monotonic = RPC_U16(&msg, 10U);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+void sc_misc_debug_out(sc_ipc_t ipc, uint8_t ch)
+{
+       sc_rpc_msg_t msg;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_DEBUG_OUT;
+       RPC_U8(&msg, 0U) = (uint8_t)ch;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+}
+
+sc_err_t sc_misc_waveform_capture(sc_ipc_t ipc, sc_bool_t enable)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_WAVEFORM_CAPTURE;
+       RPC_U8(&msg, 0U) = (uint8_t)enable;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+void sc_misc_build_info(sc_ipc_t ipc, uint32_t *build, uint32_t *commit)
+{
+       sc_rpc_msg_t msg;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BUILD_INFO;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (build != NULL)
+               *build = RPC_U32(&msg, 0U);
+
+       if (commit != NULL)
+               *commit = RPC_U32(&msg, 4U);
+}
+
+void sc_misc_unique_id(sc_ipc_t ipc, uint32_t *id_l, uint32_t *id_h)
+{
+       sc_rpc_msg_t msg;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_UNIQUE_ID;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (id_l != NULL)
+               *id_l = RPC_U32(&msg, 0U);
+
+       if (id_h != NULL)
+               *id_h = RPC_U32(&msg, 4U);
+}
+
+sc_err_t sc_misc_set_ari(sc_ipc_t ipc, sc_rsrc_t resource,
+                        sc_rsrc_t resource_mst, uint16_t ari, sc_bool_t enable)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_ARI;
+       RPC_U16(&msg, 0U) = (uint16_t)resource;
+       RPC_U16(&msg, 2U) = (uint16_t)resource_mst;
+       RPC_U16(&msg, 4U) = (uint16_t)ari;
+       RPC_U8(&msg, 6U) = (uint8_t)enable;
+       RPC_SIZE(&msg) = 3U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
+{
+       sc_rpc_msg_t msg;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BOOT_STATUS;
+       RPC_U8(&msg, 0U) = (uint8_t)status;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_TRUE);
+}
+
+sc_err_t sc_misc_boot_done(sc_ipc_t ipc, sc_rsrc_t cpu)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BOOT_DONE;
+       RPC_U16(&msg, 0U) = (uint16_t)cpu;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_otp_fuse_read(sc_ipc_t ipc, uint32_t word, uint32_t *val)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_OTP_FUSE_READ;
+       RPC_U32(&msg, 0U) = (uint32_t)word;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (val != NULL)
+               *val = RPC_U32(&msg, 0U);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_otp_fuse_write(sc_ipc_t ipc, uint32_t word, uint32_t val)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_OTP_FUSE_WRITE;
+       RPC_U32(&msg, 0U) = (uint32_t)word;
+       RPC_U32(&msg, 4U) = (uint32_t)val;
+       RPC_SIZE(&msg) = 3U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+                         sc_misc_temp_t temp, int16_t celsius, int8_t tenths)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_TEMP;
+       RPC_U16(&msg, 0U) = (uint16_t)resource;
+       RPC_I16(&msg, 2U) = (int16_t) celsius;
+       RPC_U8(&msg, 4U) = (uint8_t)temp;
+       RPC_I8(&msg, 5U) = (int8_t) tenths;
+       RPC_SIZE(&msg) = 3U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+                         sc_misc_temp_t temp, int16_t *celsius,
+                         int8_t *tenths)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_TEMP;
+       RPC_U16(&msg, 0U) = (uint16_t)resource;
+       RPC_U8(&msg, 2U) = (uint8_t)temp;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (celsius != NULL)
+               *celsius = RPC_I16(&msg, 0U);
+
+       result = RPC_R8(&msg);
+       if (tenths != NULL)
+               *tenths = RPC_I8(&msg, 2U);
+
+       return (sc_err_t)result;
+}
+
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *dev)
+{
+       sc_rpc_msg_t msg;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_BOOT_DEV;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (dev != NULL)
+               *dev = RPC_U16(&msg, 0U);
+}
+
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status)
+{
+       sc_rpc_msg_t msg;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+       RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_BUTTON_STATUS;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (status != NULL)
+               *status = RPC_U8(&msg, 0U);
+}
+
+/**@}*/
diff --git a/plat/imx/common/sci/svc/misc/sci_misc_rpc.h b/plat/imx/common/sci/svc/misc/sci_misc_rpc.h
new file mode 100644 (file)
index 0000000..03b1a51
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file for the MISC RPC implementation.
+ *
+ * @addtogroup MISC_SVC
+ * @{
+ */
+
+#ifndef SC_MISC_RPC_H
+#define SC_MISC_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC MISC function calls
+ */
+/*@{*/
+#define MISC_FUNC_UNKNOWN 0    /* Unknown function */
+#define MISC_FUNC_SET_CONTROL 1U       /* Index for misc_set_control() RPC call */
+#define MISC_FUNC_GET_CONTROL 2U       /* Index for misc_get_control() RPC call */
+#define MISC_FUNC_SET_MAX_DMA_GROUP 4U /* Index for misc_set_max_dma_group() RPC call */
+#define MISC_FUNC_SET_DMA_GROUP 5U     /* Index for misc_set_dma_group() RPC call */
+#define MISC_FUNC_SECO_IMAGE_LOAD 8U   /* Index for misc_seco_image_load() RPC call */
+#define MISC_FUNC_SECO_AUTHENTICATE 9U /* Index for misc_seco_authenticate() RPC call */
+#define MISC_FUNC_SECO_FUSE_WRITE 20U  /* Index for misc_seco_fuse_write() RPC call */
+#define MISC_FUNC_SECO_ENABLE_DEBUG 21U        /* Index for misc_seco_enable_debug() RPC call */
+#define MISC_FUNC_SECO_FORWARD_LIFECYCLE 22U   /* Index for misc_seco_forward_lifecycle() RPC call */
+#define MISC_FUNC_SECO_RETURN_LIFECYCLE 23U    /* Index for misc_seco_return_lifecycle() RPC call */
+#define MISC_FUNC_SECO_BUILD_INFO 24U  /* Index for misc_seco_build_info() RPC call */
+#define MISC_FUNC_SECO_CHIP_INFO 25U   /* Index for misc_seco_chip_info() RPC call */
+#define MISC_FUNC_DEBUG_OUT 10U        /* Index for misc_debug_out() RPC call */
+#define MISC_FUNC_WAVEFORM_CAPTURE 6U  /* Index for misc_waveform_capture() RPC call */
+#define MISC_FUNC_BUILD_INFO 15U       /* Index for misc_build_info() RPC call */
+#define MISC_FUNC_UNIQUE_ID 19U        /* Index for misc_unique_id() RPC call */
+#define MISC_FUNC_SET_ARI 3U   /* Index for misc_set_ari() RPC call */
+#define MISC_FUNC_BOOT_STATUS 7U       /* Index for misc_boot_status() RPC call */
+#define MISC_FUNC_BOOT_DONE 14U        /* Index for misc_boot_done() RPC call */
+#define MISC_FUNC_OTP_FUSE_READ 11U    /* Index for misc_otp_fuse_read() RPC call */
+#define MISC_FUNC_OTP_FUSE_WRITE 17U   /* Index for misc_otp_fuse_write() RPC call */
+#define MISC_FUNC_SET_TEMP 12U /* Index for misc_set_temp() RPC call */
+#define MISC_FUNC_GET_TEMP 13U /* Index for misc_get_temp() RPC call */
+#define MISC_FUNC_GET_BOOT_DEV 16U     /* Index for misc_get_boot_dev() RPC call */
+#define MISC_FUNC_GET_BUTTON_STATUS 18U        /* Index for misc_get_button_status() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming MISC RPC request.
+ *
+ * @param[in]     caller_pt   caller partition
+ * @param[in]     msg         pointer to RPC message
+ */
+void misc_dispatch(sc_rm_pt_t caller_pt, sc_rpc_msg_t *msg);
+
+/*!
+ * This function translates and dispatches an MISC RPC request.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     msg         pointer to RPC message
+ */
+void misc_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
+
+#endif                         /* SC_MISC_RPC_H */
+
+/**@}*/
diff --git a/plat/imx/common/sci/svc/timer/sci_timer_rpc.h b/plat/imx/common/sci/svc/timer/sci_timer_rpc.h
new file mode 100644 (file)
index 0000000..6716399
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file for the TIMER RPC implementation.
+ *
+ * @addtogroup TIMER_SVC
+ * @{
+ */
+
+#ifndef SC_TIMER_RPC_H
+#define SC_TIMER_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC TIMER function calls
+ */
+/*@{*/
+#define TIMER_FUNC_UNKNOWN 0   /* Unknown function */
+#define TIMER_FUNC_SET_WDOG_TIMEOUT 1U /* Index for timer_set_wdog_timeout() RPC call */
+#define TIMER_FUNC_SET_WDOG_PRE_TIMEOUT 12U    /* Index for timer_set_wdog_pre_timeout() RPC call */
+#define TIMER_FUNC_START_WDOG 2U       /* Index for timer_start_wdog() RPC call */
+#define TIMER_FUNC_STOP_WDOG 3U        /* Index for timer_stop_wdog() RPC call */
+#define TIMER_FUNC_PING_WDOG 4U        /* Index for timer_ping_wdog() RPC call */
+#define TIMER_FUNC_GET_WDOG_STATUS 5U  /* Index for timer_get_wdog_status() RPC call */
+#define TIMER_FUNC_PT_GET_WDOG_STATUS 13U      /* Index for timer_pt_get_wdog_status() RPC call */
+#define TIMER_FUNC_SET_WDOG_ACTION 10U /* Index for timer_set_wdog_action() RPC call */
+#define TIMER_FUNC_SET_RTC_TIME 6U     /* Index for timer_set_rtc_time() RPC call */
+#define TIMER_FUNC_GET_RTC_TIME 7U     /* Index for timer_get_rtc_time() RPC call */
+#define TIMER_FUNC_GET_RTC_SEC1970 9U  /* Index for timer_get_rtc_sec1970() RPC call */
+#define TIMER_FUNC_SET_RTC_ALARM 8U    /* Index for timer_set_rtc_alarm() RPC call */
+#define TIMER_FUNC_SET_RTC_PERIODIC_ALARM 14U  /* Index for timer_set_rtc_periodic_alarm() RPC call */
+#define TIMER_FUNC_CANCEL_RTC_ALARM 15U        /* Index for timer_cancel_rtc_alarm() RPC call */
+#define TIMER_FUNC_SET_RTC_CALB 11U    /* Index for timer_set_rtc_calb() RPC call */
+#define TIMER_FUNC_SET_SYSCTR_ALARM 16U        /* Index for timer_set_sysctr_alarm() RPC call */
+#define TIMER_FUNC_SET_SYSCTR_PERIODIC_ALARM 17U       /* Index for timer_set_sysctr_periodic_alarm() RPC call */
+#define TIMER_FUNC_CANCEL_SYSCTR_ALARM 18U     /* Index for timer_cancel_sysctr_alarm() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming TIMER RPC request.
+ *
+ * @param[in]     caller_pt   caller partition
+ * @param[in]     msg         pointer to RPC message
+ */
+void timer_dispatch(sc_rm_pt_t caller_pt, sc_rpc_msg_t *msg);
+
+/*!
+ * This function translates and dispatches an TIMER RPC request.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     msg         pointer to RPC message
+ */
+void timer_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
+
+#endif                         /* SC_TIMER_RPC_H */
+
+/**@}*/
diff --git a/plat/imx/common/sci/svc/timer/timer_rpc_clnt.c b/plat/imx/common/sci/svc/timer/timer_rpc_clnt.c
new file mode 100644 (file)
index 0000000..a82be96
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * File containing client-side RPC functions for the TIMER service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup TIMER_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <sci/sci_types.h>
+#include <sci/svc/rm/sci_rm_api.h>
+#include <sci/svc/timer/sci_timer_api.h>
+#include <sci/sci_rpc.h>
+#include <stdlib.h>
+#include "sci_timer_rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_timer_set_wdog_timeout(sc_ipc_t ipc, sc_timer_wdog_time_t timeout)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_WDOG_TIMEOUT;
+       RPC_U32(&msg, 0U) = (uint32_t)timeout;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_wdog_pre_timeout(sc_ipc_t ipc,
+                                      sc_timer_wdog_time_t pre_timeout)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_WDOG_PRE_TIMEOUT;
+       RPC_U32(&msg, 0U) = (uint32_t)pre_timeout;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_start_wdog(sc_ipc_t ipc, sc_bool_t lock)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_START_WDOG;
+       RPC_U8(&msg, 0U) = (uint8_t)lock;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_stop_wdog(sc_ipc_t ipc)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_STOP_WDOG;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_ping_wdog(sc_ipc_t ipc)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_PING_WDOG;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_get_wdog_status(sc_ipc_t ipc,
+                                 sc_timer_wdog_time_t *timeout,
+                                 sc_timer_wdog_time_t *max_timeout,
+                                 sc_timer_wdog_time_t *remaining_time)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_GET_WDOG_STATUS;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (timeout != NULL)
+               *timeout = RPC_U32(&msg, 0U);
+
+       if (max_timeout != NULL)
+               *max_timeout = RPC_U32(&msg, 4U);
+
+       if (remaining_time != NULL)
+               *remaining_time = RPC_U32(&msg, 8U);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_pt_get_wdog_status(sc_ipc_t ipc, sc_rm_pt_t pt,
+                                    sc_bool_t *enb,
+                                    sc_timer_wdog_time_t *timeout,
+                                    sc_timer_wdog_time_t *remaining_time)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_PT_GET_WDOG_STATUS;
+       RPC_U8(&msg, 0U) = (uint8_t)pt;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (timeout != NULL)
+               *timeout = RPC_U32(&msg, 0U);
+
+       if (remaining_time != NULL)
+               *remaining_time = RPC_U32(&msg, 4U);
+
+       result = RPC_R8(&msg);
+       if (enb != NULL)
+               *enb = RPC_U8(&msg, 8U);
+
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_wdog_action(sc_ipc_t ipc,
+                                 sc_rm_pt_t pt, sc_timer_wdog_action_t action)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_WDOG_ACTION;
+       RPC_U8(&msg, 0U) = (uint8_t)pt;
+       RPC_U8(&msg, 1U) = (uint8_t)action;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_rtc_time(sc_ipc_t ipc, uint16_t year, uint8_t mon,
+                              uint8_t day, uint8_t hour, uint8_t min,
+                              uint8_t sec)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_RTC_TIME;
+       RPC_U16(&msg, 0U) = (uint16_t)year;
+       RPC_U8(&msg, 2U) = (uint8_t)mon;
+       RPC_U8(&msg, 3U) = (uint8_t)day;
+       RPC_U8(&msg, 4U) = (uint8_t)hour;
+       RPC_U8(&msg, 5U) = (uint8_t)min;
+       RPC_U8(&msg, 6U) = (uint8_t)sec;
+       RPC_SIZE(&msg) = 3U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_get_rtc_time(sc_ipc_t ipc, uint16_t *year, uint8_t *mon,
+                              uint8_t *day, uint8_t *hour, uint8_t *min,
+                              uint8_t *sec)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_GET_RTC_TIME;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (year != NULL)
+               *year = RPC_U16(&msg, 0U);
+
+       result = RPC_R8(&msg);
+       if (mon != NULL)
+               *mon = RPC_U8(&msg, 2U);
+
+       if (day != NULL)
+               *day = RPC_U8(&msg, 3U);
+
+       if (hour != NULL)
+               *hour = RPC_U8(&msg, 4U);
+
+       if (min != NULL)
+               *min = RPC_U8(&msg, 5U);
+
+       if (sec != NULL)
+               *sec = RPC_U8(&msg, 6U);
+
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_get_rtc_sec1970(sc_ipc_t ipc, uint32_t *sec)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_GET_RTC_SEC1970;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       if (sec != NULL)
+               *sec = RPC_U32(&msg, 0U);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_rtc_alarm(sc_ipc_t ipc, uint16_t year, uint8_t mon,
+                               uint8_t day, uint8_t hour, uint8_t min,
+                               uint8_t sec)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_RTC_ALARM;
+       RPC_U16(&msg, 0U) = (uint16_t)year;
+       RPC_U8(&msg, 2U) = (uint8_t)mon;
+       RPC_U8(&msg, 3U) = (uint8_t)day;
+       RPC_U8(&msg, 4U) = (uint8_t)hour;
+       RPC_U8(&msg, 5U) = (uint8_t)min;
+       RPC_U8(&msg, 6U) = (uint8_t)sec;
+       RPC_SIZE(&msg) = 3U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_rtc_periodic_alarm(sc_ipc_t ipc, uint32_t sec)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_RTC_PERIODIC_ALARM;
+       RPC_U32(&msg, 0U) = (uint32_t)sec;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_cancel_rtc_alarm(sc_ipc_t ipc)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_CANCEL_RTC_ALARM;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_rtc_calb(sc_ipc_t ipc, int8_t count)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_RTC_CALB;
+       RPC_I8(&msg, 0U) = (int8_t) count;
+       RPC_SIZE(&msg) = 2U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_sysctr_alarm(sc_ipc_t ipc, uint64_t ticks)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_SYSCTR_ALARM;
+       RPC_U32(&msg, 0U) = (uint32_t)(ticks >> 32U);
+       RPC_U32(&msg, 4U) = (uint32_t)ticks;
+       RPC_SIZE(&msg) = 3U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_sysctr_periodic_alarm(sc_ipc_t ipc, uint64_t ticks)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_SYSCTR_PERIODIC_ALARM;
+       RPC_U32(&msg, 0U) = (uint32_t)(ticks >> 32U);
+       RPC_U32(&msg, 4U) = (uint32_t)ticks;
+       RPC_SIZE(&msg) = 3U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_cancel_sysctr_alarm(sc_ipc_t ipc)
+{
+       sc_rpc_msg_t msg;
+       uint8_t result;
+
+       RPC_VER(&msg) = SC_RPC_VERSION;
+       RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+       RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_CANCEL_SYSCTR_ALARM;
+       RPC_SIZE(&msg) = 1U;
+
+       sc_call_rpc(ipc, &msg, SC_FALSE);
+
+       result = RPC_R8(&msg);
+       return (sc_err_t)result;
+}
+
+/**@}*/
index a931c8062ec40b5c8b6a69ee3cba02822eba7c99..d58382f38316532f001ea4a959cd8dd8e90519af 100644 (file)
 #define WARP7_DTB_BASE                 (DRAM_BASE + 0x03000000)
 #define WARP7_DTB_LIMIT                        (WARP7_DTB_BASE + WARP7_DTB_SIZE)
 
+/* Define the absolute location of DTB Overlay 0x83100000 - 0x83101000 */
+#define WARP7_DTB_OVERLAY_SIZE         0x00001000
+#define WARP7_DTB_OVERLAY_BASE         WARP7_DTB_LIMIT
+#define WARP7_DTB_OVERLAY_LIMIT                (WARP7_DTB_OVERLAY_BASE + \
+                                        WARP7_DTB_OVERLAY_SIZE)
+
 /*
  * BL2 specific defines.
  *
  *            |       DDR       | BL33/U-BOOT
  * 0x87800000 +-----------------+
  *            |       DDR       | Unallocated
+ * 0x83101000 +-----------------+
+ *            |       DDR       | DTB Overlay
  * 0x83100000 +-----------------+
  *            |       DDR       | DTB
  * 0x83000000 +-----------------+
index a77186582745f8d7313f76bd2130770ee090552f..f7bd4ae5ba153d046b48e49fb7b2327ff14ccf94 100644 (file)
@@ -62,6 +62,43 @@ BL2_SOURCES          +=      common/desc_image_load.c                        \
                                plat/imx/imx7/warp7/warp7_image_load.c          \
                                ${XLAT_TABLES_LIB_SRCS}
 
+ifneq (${TRUSTED_BOARD_BOOT},0)
+
+include drivers/auth/mbedtls/mbedtls_crypto.mk
+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
+
+BL2_SOURCES            +=      ${AUTH_SOURCES}                                 \
+                               plat/common/tbbr/plat_tbbr.c                    \
+                               plat/imx/imx7/warp7/warp7_trusted_boot.c        \
+                               plat/imx/imx7/warp7/warp7_rotpk.S
+
+ROT_KEY             = $(BUILD_PLAT)/rot_key.pem
+ROTPK_HASH          = $(BUILD_PLAT)/rotpk_sha256.bin
+
+$(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
+$(eval $(call MAKE_LIB_DIRS))
+
+$(BUILD_PLAT)/bl2/warp7_rotpk.o: $(ROTPK_HASH)
+
+certificates: $(ROT_KEY)
+
+$(ROT_KEY): | $(BUILD_PLAT)
+       @echo "  OPENSSL $@"
+       @if [ ! -f $(ROT_KEY) ]; then \
+               openssl genrsa 2048 > $@ 2>/dev/null; \
+       fi
+
+$(ROTPK_HASH): $(ROT_KEY)
+       @echo "  OPENSSL $@"
+       $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+       openssl dgst -sha256 -binary > $@ 2>/dev/null
+endif
+
 # Build config flags
 # ------------------
 
@@ -86,6 +123,21 @@ USE_COHERENT_MEM            := 1
 PLAT_WARP7_UART                        :=1
 $(eval $(call add_define,PLAT_WARP7_UART))
 
+# Add the build options to pack BLx images and kernel device tree
+# in the FIP if the platform requires.
+ifneq ($(BL2),)
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
+endif
+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
+ifneq ($(HW_CONFIG),)
+$(eval $(call TOOL_ADD_IMG,HW_CONFIG,--hw-config))
+endif
+
 # Verify build config
 # -------------------
 
index 032ed7b194986847c8d35c1bb756c65dd0126b3e..08baf199545dd37d40a407fbfd9682e9c274f320 100644 (file)
@@ -290,12 +290,13 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2,
        imx_wdog_init();
 
        /* Print out the expected memory map */
-       VERBOSE("\tOPTEE      0x%08x-0x%08x\n", WARP7_OPTEE_BASE, WARP7_OPTEE_LIMIT);
-       VERBOSE("\tATF/BL2    0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT);
-       VERBOSE("\tSHRAM      0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT);
-       VERBOSE("\tFIP        0x%08x-0x%08x\n", WARP7_FIP_BASE, WARP7_FIP_LIMIT);
-       VERBOSE("\tDTB        0x%08x-0x%08x\n", WARP7_DTB_BASE, WARP7_DTB_LIMIT);
-       VERBOSE("\tUBOOT/BL33 0x%08x-0x%08x\n", WARP7_UBOOT_BASE, WARP7_UBOOT_LIMIT);
+       VERBOSE("\tOPTEE       0x%08x-0x%08x\n", WARP7_OPTEE_BASE, WARP7_OPTEE_LIMIT);
+       VERBOSE("\tATF/BL2     0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT);
+       VERBOSE("\tSHRAM       0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT);
+       VERBOSE("\tFIP         0x%08x-0x%08x\n", WARP7_FIP_BASE, WARP7_FIP_LIMIT);
+       VERBOSE("\tDTB-OVERLAY 0x%08x-0x%08x\n", WARP7_DTB_OVERLAY_BASE, WARP7_DTB_OVERLAY_LIMIT);
+       VERBOSE("\tDTB         0x%08x-0x%08x\n", WARP7_DTB_BASE, WARP7_DTB_LIMIT);
+       VERBOSE("\tUBOOT/BL33  0x%08x-0x%08x\n", WARP7_UBOOT_BASE, WARP7_UBOOT_LIMIT);
 }
 
 /*
index a29e14198f753544487b0c756eed11c25906d3d1..c670d423cdcf5912bd7a065d754d7a5ccbd5dbac 100644 (file)
@@ -27,16 +27,6 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
 
                .next_handoff_image_id = BL33_IMAGE_ID,
        },
-       {
-               .image_id = HW_CONFIG_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 = WARP7_DTB_BASE,
-               .image_info.image_max_size = WARP7_DTB_SIZE,
-               .next_handoff_image_id = INVALID_IMAGE_ID,
-       },
        {
                .image_id = BL32_EXTRA1_IMAGE_ID,
 
index b9cace09063ca8886e1d497bf7a88f86226efb42..fcfb5036bf3ce9d5f2639be897122b7b8079f08b 100644 (file)
@@ -60,10 +60,6 @@ static const io_uuid_spec_t bl32_uuid_spec = {
        .uuid = UUID_SECURE_PAYLOAD_BL32,
 };
 
-static const io_uuid_spec_t hw_config_uuid_spec = {
-       .uuid = UUID_HW_CONFIG,
-};
-
 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
        .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
 };
@@ -76,6 +72,32 @@ static const io_uuid_spec_t bl33_uuid_spec = {
        .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
 };
 
+#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 tos_fw_key_cert_uuid_spec = {
+       .uuid = UUID_TRUSTED_OS_FW_KEY_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_key_cert_uuid_spec = {
+       .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
+       .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
 /* TODO: this structure is replicated multiple times. rationalize it ! */
 struct plat_io_policy {
        uintptr_t *dev_handle;
@@ -112,16 +134,43 @@ static const struct plat_io_policy policies[] = {
                (uintptr_t)&bl32_extra2_uuid_spec,
                open_fip
        },
-       [HW_CONFIG_ID] = {
+       [BL33_IMAGE_ID] = {
                &fip_dev_handle,
-               (uintptr_t)&hw_config_uuid_spec,
+               (uintptr_t)&bl33_uuid_spec,
                open_fip
        },
-       [BL33_IMAGE_ID] = {
+#if TRUSTED_BOARD_BOOT
+       [TRUSTED_BOOT_FW_CERT_ID] = {
                &fip_dev_handle,
-               (uintptr_t)&bl33_uuid_spec,
+               (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
+       },
+       [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
+       },
+       [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 */
 };
 
 static int open_fip(const uintptr_t spec)
diff --git a/plat/imx/imx7/warp7/warp7_rotpk.S b/plat/imx/imx7/warp7/warp7_rotpk.S
new file mode 100644 (file)
index 0000000..f74b6d2
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+       .global warp7_rotpk_hash
+       .global warp7_rotpk_hash_end
+warp7_rotpk_hash:
+       /* DER header */
+       .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+       .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+       /* SHA256 */
+       .incbin ROTPK_HASH
+warp7_rotpk_hash_end:
diff --git a/plat/imx/imx7/warp7/warp7_trusted_boot.c b/plat/imx/imx7/warp7/warp7_trusted_boot.c
new file mode 100644 (file)
index 0000000..8157cd5
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+
+extern char warp7_rotpk_hash[], warp7_rotpk_hash_end[];
+
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+                       unsigned int *flags)
+{
+       *key_ptr = warp7_rotpk_hash;
+       *key_len = warp7_rotpk_hash_end - warp7_rotpk_hash;
+       *flags = ROTPK_IS_HASH;
+
+       return 0;
+}
+
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+       *nv_ctr = 0;
+
+       return 0;
+}
+
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+       return 1;
+}
index f4e6ee746e80aa0fa61f660d9cc52acb7c557040..b18edd96d1b5833bced178d7552363b01316ee1c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -87,7 +87,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 #if DEBUG_CONSOLE
        static console_uart_t console;
 
-       console_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+       console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
                IMX_CONSOLE_BAUDRATE, &console);
 #endif
        /*
index 0255268fac8b1ef4b129eea76708bff93f95d6d5..2681e57c21b50c52ab74cf37534a0d12945d7b89 100644 (file)
@@ -34,3 +34,7 @@ USE_COHERENT_MEM      :=      1
 RESET_TO_BL31          :=      1
 A53_DISABLE_NON_TEMPORAL_HINT := 0
 MULTI_CONSOLE_API      :=      1
+
+ERRATA_A53_835769      :=      1
+ERRATA_A53_843419      :=      1
+ERRATA_A53_855873      :=      1
index a00695cc3e4b3597c81aaaea11e4d385b0adca0e..c76de646164db2a8d4c90f1724957561e2406b11 100644 (file)
@@ -49,11 +49,7 @@ const static int imx8qm_cci_map[] = {
 };
 
 static const mmap_region_t imx_mmap[] = {
-       MAP_REGION_FLAT(IMX_BOOT_UART_BASE, IMX_BOOT_UART_SIZE, MT_DEVICE | MT_RW),
-       MAP_REGION_FLAT(SC_IPC_BASE, SC_IPC_SIZE, MT_DEVICE | MT_RW),
-       MAP_REGION_FLAT(PLAT_GICD_BASE, PLAT_GICD_SIZE, MT_DEVICE | MT_RW),
-       MAP_REGION_FLAT(PLAT_GICR_BASE, PLAT_GICR_SIZE, MT_DEVICE | MT_RW),
-       MAP_REGION_FLAT(PLAT_CCI_BASE, PLAT_CCI_SIZE, MT_DEVICE | MT_RW),
+       MAP_REGION_FLAT(IMX_REG_BASE, IMX_REG_SIZE, MT_DEVICE | MT_RW),
        {0}
 };
 
@@ -324,6 +320,10 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 
        /* turn on MU1 for non-secure OS/Hypervisor */
        sc_pm_set_resource_power_mode(ipc_handle, SC_R_MU_1A, SC_PM_PW_MODE_ON);
+       /* Turn on GPT_0's power & clock for non-secure OS/Hypervisor */
+       sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+       sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
+       mmio_write_32(IMX_GPT_LPCG_BASE, mmio_read_32(IMX_GPT_LPCG_BASE) | (1 << 25));
 
        /*
         * create new partition for non-secure OS/Hypervisor
index 833048dcfd2ab8200438f60953c238cc732ec356..bdba37c6eb3f1643e27e0d5ecb50b887dc0a8414 100644 (file)
@@ -17,6 +17,8 @@
 #include <plat_imx8.h>
 #include <sci/sci.h>
 
+#include "../../common/sci/imx8_mu.h"
+
 #define CORE_PWR_STATE(state) \
        ((state)->pwr_domain_state[MPIDR_AFFLVL0])
 #define CLUSTER_PWR_STATE(state) \
@@ -29,44 +31,70 @@ const static int ap_core_index[PLATFORM_CORE_COUNT] = {
        SC_R_A53_3, SC_R_A72_0, SC_R_A72_1,
 };
 
+/* save gic dist/redist context when GIC is poewr down */
+static struct plat_gic_ctx imx_gicv3_ctx;
+static unsigned int gpt_lpcg, gpt_reg[2];
+
+static void imx_enable_irqstr_wakeup(void)
+{
+       uint32_t irq_mask;
+       gicv3_dist_ctx_t *dist_ctx = &imx_gicv3_ctx.dist_ctx;
+
+       /* put IRQSTR into ON mode */
+       sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON);
+
+       /* enable the irqsteer to handle wakeup irq */
+       mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x1);
+       for (int i = 0; i < 15; i++) {
+               irq_mask = dist_ctx->gicd_isenabler[i];
+               mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x3c - 0x4 * i, irq_mask);
+       }
+
+       /* set IRQSTR low power mode */
+       if (imx_is_wakeup_src_irqsteer())
+               sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_STBY);
+       else
+               sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF);
+}
+
+static void imx_disable_irqstr_wakeup(void)
+{
+       /* put IRQSTR into ON from STBY mode */
+       sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON);
+
+       /* disable the irqsteer */
+       mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x0);
+       for (int i = 0; i < 16; i++)
+               mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x4 + 0x4 * i, 0x0);
+
+       /* put IRQSTR into OFF mode */
+       sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF);
+}
+
 int imx_pwr_domain_on(u_register_t mpidr)
 {
        int ret = PSCI_E_SUCCESS;
-       unsigned int cluster_id, cpu_id;
-
-       cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
-       cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
-
-       printf("imx_pwr_domain_on cluster_id %d, cpu_id %d\n", cluster_id, cpu_id);
-
-       if (cluster_id == 0) {
-               sc_pm_set_resource_power_mode(ipc_handle, SC_R_A53,
-                       SC_PM_PW_MODE_ON);
-               if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id],
-                       SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
-                       ERROR("cluster0 core %d power on failed!\n", cpu_id);
-                       ret = PSCI_E_INTERN_FAIL;
-               }
-
-               if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id],
-                       true, BL31_BASE) != SC_ERR_NONE) {
-                       ERROR("boot cluster0 core %d failed!\n", cpu_id);
-                       ret = PSCI_E_INTERN_FAIL;
-               }
-       } else {
-               sc_pm_set_resource_power_mode(ipc_handle, SC_R_A72,
-                       SC_PM_PW_MODE_ON);
-               if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id + 4],
-                       SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
-                       ERROR(" cluster1 core %d power on failed!\n", cpu_id);
-                       ret = PSCI_E_INTERN_FAIL;
-               }
-
-               if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id + 4],
-                       true, BL31_BASE) != SC_ERR_NONE) {
-                       ERROR("boot cluster1 core %d failed!\n", cpu_id);
-                       ret = PSCI_E_INTERN_FAIL;
-               }
+       unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+       unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+
+       sc_pm_set_resource_power_mode(ipc_handle, cluster_id == 0 ?
+               SC_R_A53 : SC_R_A72, SC_PM_PW_MODE_ON);
+
+       if (cluster_id == 1)
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
+
+       if (sc_pm_set_resource_power_mode(ipc_handle,
+               ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+               SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
+               ERROR("core %d power on failed!\n", cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id);
+               ret = PSCI_E_INTERN_FAIL;
+       }
+
+       if (sc_pm_cpu_start(ipc_handle,
+               ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+               true, BL31_BASE) != SC_ERR_NONE) {
+               ERROR("boot core %d failed!\n", cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id);
+               ret = PSCI_E_INTERN_FAIL;
        }
 
        return ret;
@@ -91,11 +119,14 @@ void imx_pwr_domain_off(const psci_power_state_t *target_state)
 
        plat_gic_cpuif_disable();
        sc_pm_req_cpu_low_power_mode(ipc_handle,
-               ap_core_index[cpu_id + cluster_id * 4],
-               SC_PM_PW_MODE_OFF,
-               SC_PM_WAKE_SRC_NONE);
-       if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
-               cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+               ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+               SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_NONE);
+
+       if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
+               cci_disable_snoop_dvm_reqs(cluster_id);
+               if (cluster_id == 1)
+                       sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
+       }
        printf("turn off cluster:%d core:%d\n", cluster_id, cpu_id);
 }
 
@@ -105,24 +136,148 @@ void imx_domain_suspend(const psci_power_state_t *target_state)
        unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
        unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
 
-       plat_gic_cpuif_disable();
+       if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+               plat_gic_cpuif_disable();
+               sc_pm_set_cpu_resume(ipc_handle,
+                       ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+                       true, BL31_BASE);
+               sc_pm_req_cpu_low_power_mode(ipc_handle,
+                       ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+                       SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+       } else {
+               dsb();
+               write_scr_el3(read_scr_el3() | SCR_FIQ_BIT);
+               isb();
+       }
 
-       cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+       if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
+               cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+               if (cluster_id == 1)
+                       sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
+       }
 
-       sc_pm_set_cpu_resume_addr(ipc_handle,
-               ap_core_index[cpu_id + cluster_id * 4], BL31_BASE);
-       sc_pm_req_cpu_low_power_mode(ipc_handle,
-               ap_core_index[cpu_id + cluster_id * 4],
-               SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+       if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) {
+               plat_gic_cpuif_disable();
+
+               /* save gic context */
+               plat_gic_save(cpu_id, &imx_gicv3_ctx);
+               /* enable the irqsteer for wakeup */
+               imx_enable_irqstr_wakeup();
+
+               cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+
+               /* Put GIC in LP mode. */
+               sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_OFF);
+               /* Save GPT clock and registers, then turn off its power */
+               gpt_lpcg = mmio_read_32(IMX_GPT_LPCG_BASE);
+               gpt_reg[0] = mmio_read_32(IMX_GPT_BASE);
+               gpt_reg[1] = mmio_read_32(IMX_GPT_BASE + 0x4);
+               sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_OFF);
+
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_OFF);
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF);
+
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF);
+
+               sc_pm_set_cpu_resume(ipc_handle,
+                       ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+                       true, BL31_BASE);
+               if (imx_is_wakeup_src_irqsteer())
+                       sc_pm_req_cpu_low_power_mode(ipc_handle,
+                               ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+                               SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_IRQSTEER);
+               else
+                       sc_pm_req_cpu_low_power_mode(ipc_handle,
+                               ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+                               SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_SCU);
+       }
 }
 
 void imx_domain_suspend_finish(const psci_power_state_t *target_state)
 {
        u_register_t mpidr = read_mpidr_el1();
+       unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+       unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
 
-       cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+       /* check the system level status */
+       if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) {
+               MU_Resume(SC_IPC_BASE);
 
-       plat_gic_cpuif_enable();
+               sc_pm_req_cpu_low_power_mode(ipc_handle,
+                       ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+                       SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC);
+
+               /* Put GIC/IRQSTR back to high power mode. */
+               sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_ON);
+
+               /* Turn GPT power and restore its clock and registers */
+               sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+               sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
+               mmio_write_32(IMX_GPT_BASE, gpt_reg[0]);
+               mmio_write_32(IMX_GPT_BASE + 0x4, gpt_reg[1]);
+               mmio_write_32(IMX_GPT_LPCG_BASE, gpt_lpcg);
+
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON);
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON);
+
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON);
+
+               cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+
+               /* restore gic context */
+               plat_gic_restore(cpu_id, &imx_gicv3_ctx);
+               /* disable the irqsteer wakeup */
+               imx_disable_irqstr_wakeup();
+
+               plat_gic_cpuif_enable();
+       }
+
+       /* check the cluster level power status */
+       if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
+               cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+               if (cluster_id == 1)
+                       sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
+       }
+
+       /* check the core level power status */
+       if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+               sc_pm_set_cpu_resume(ipc_handle,
+                       ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+                       false, BL31_BASE);
+               sc_pm_req_cpu_low_power_mode(ipc_handle,
+                       ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+                       SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC);
+               plat_gic_cpuif_enable();
+       } else {
+               write_scr_el3(read_scr_el3() & (~SCR_FIQ_BIT));
+               isb();
+       }
 }
 
 int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
@@ -149,26 +304,23 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
        imx_mailbox_init(sec_entrypoint);
        *psci_ops = &imx_plat_psci_ops;
 
-       /* Request low power mode for cluster/cci, only need to do once */
-       sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
-       sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_OFF);
-       sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF);
-
-       /* Request RUN and LP modes for DDR, system interconnect etc. */
-       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53,
-               SC_PM_SYS_IF_DDR, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
-       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72,
-               SC_PM_SYS_IF_DDR, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
-       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53,
-               SC_PM_SYS_IF_MU, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
-       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72,
-               SC_PM_SYS_IF_MU, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
-       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53,
-               SC_PM_SYS_IF_INTERCONNECT, SC_PM_PW_MODE_ON,
-               SC_PM_PW_MODE_STBY);
-       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72,
-               SC_PM_SYS_IF_INTERCONNECT, SC_PM_PW_MODE_ON,
-               SC_PM_PW_MODE_STBY);
+       /* make sure system sources power ON in low power mode by default */
+       sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON);
+       sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
+       sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON);
+
+       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR,
+               SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR,
+               SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU,
+               SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU,
+               SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT,
+               SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT,
+               SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
 
        return 0;
 }
index 1d0bdf9a71de434f0be56c09110d069e9ab419a4..946be76592f78a5e1a101948ce039d78690e0235 100644 (file)
 #define BL31_LIMIT                     0x80020000
 
 #define PLAT_GICD_BASE                 0x51a00000
-#define PLAT_GICD_SIZE                 0x10000
 #define PLAT_GICR_BASE                 0x51b00000
-#define PLAT_GICR_SIZE                 0xc0000
 #define PLAT_CCI_BASE                  0x52090000
-#define PLAT_CCI_SIZE                  0x10000
 #define CLUSTER0_CCI_SLVAE_IFACE       3
 #define CLUSTER1_CCI_SLVAE_IFACE       4
 #define IMX_BOOT_UART_BASE             0x5a060000
-#define IMX_BOOT_UART_SIZE             0x1000
 #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 SC_IPC_SIZE                    0x10000
+#define IMX_GPT_LPCG_BASE              0x5d540000
+#define IMX_GPT_BASE                   0x5d140000
+#define IMX_WUP_IRQSTR_BASE            0x51090000
+#define IMX_REG_BASE                   0x50000000
+#define IMX_REG_SIZE                   0x10000000
 
 #define COUNTER_FREQUENCY              8000000 /* 8MHz */
 
index a623cd3f1546956a70a94e98ddc1cd37e8a6869d..d16d05128ec09b193e8bbc87ca165b521d998ab8 100644 (file)
@@ -19,12 +19,14 @@ sc_rsrc_t secure_rsrcs[] = {
        SC_R_GIC_SMMU,
        SC_R_CCI,
        SC_R_SYSTEM,
-       SC_R_IRQSTR_SCU2
+       SC_R_IRQSTR_SCU2,
+       SC_R_GPT_0
 };
 
 /* resources that have register access for non-secure domain */
 sc_rsrc_t ns_access_allowed[] = {
        SC_R_GIC,
        SC_R_GIC_SMMU,
-       SC_R_CCI
+       SC_R_CCI,
+       SC_R_GPT_0
 };
index dc45e901d885950e8deb5c35b1dbcc9cdf0b0f58..ed6108d8db2d9439e0aa5a725af8b0a857067335 100644 (file)
@@ -22,6 +22,8 @@ BL31_SOURCES          +=      plat/imx/common/lpuart_console.S        \
                                plat/imx/imx8qm/imx8qm_psci.c           \
                                plat/imx/common/imx8_topology.c         \
                                plat/imx/common/imx8_psci.c             \
+                               plat/imx/common/imx_sip_svc.c           \
+                               plat/imx/common/imx_sip_handler.c       \
                                lib/xlat_tables/aarch64/xlat_tables.c           \
                                lib/xlat_tables/xlat_tables_common.c            \
                                lib/cpus/aarch64/cortex_a53.S                   \
@@ -36,3 +38,7 @@ RESET_TO_BL31         :=      1
 A53_DISABLE_NON_TEMPORAL_HINT := 0
 MULTI_CONSOLE_API      :=      1
 ERRATA_A72_859971      :=      1
+
+ERRATA_A53_835769      :=      1
+ERRATA_A53_843419      :=      1
+ERRATA_A53_855873      :=      1
index c90794a89395b8cf058dfa532e9f543411f567e3..bfe4052848be78898fd55c178fa9b2416366eaa0 100644 (file)
@@ -44,10 +44,7 @@ static entry_point_info_t bl33_image_ep_info;
                        (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
 
 static const mmap_region_t imx_mmap[] = {
-       MAP_REGION_FLAT(IMX_BOOT_UART_BASE, IMX_BOOT_UART_SIZE, MT_DEVICE | MT_RW),
-       MAP_REGION_FLAT(SC_IPC_BASE, SC_IPC_SIZE, MT_DEVICE | MT_RW),
-       MAP_REGION_FLAT(PLAT_GICD_BASE, PLAT_GICD_SIZE, MT_DEVICE | MT_RW),
-       MAP_REGION_FLAT(PLAT_GICR_BASE, PLAT_GICR_SIZE, MT_DEVICE | MT_RW),
+       MAP_REGION_FLAT(IMX_REG_BASE, IMX_REG_SIZE, MT_DEVICE | MT_RW),
        {0}
 };
 
@@ -281,6 +278,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
        /* Turn on MU1 for non-secure OS/Hypervisor */
        sc_pm_set_resource_power_mode(ipc_handle, SC_R_MU_1A, SC_PM_PW_MODE_ON);
 
+       /* Turn on GPT_0's power & clock for non-secure OS/Hypervisor */
+       sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+       sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
+       mmio_write_32(IMX_GPT0_LPCG_BASE, mmio_read_32(IMX_GPT0_LPCG_BASE) | (1 << 25));
+
        /*
         * create new partition for non-secure OS/Hypervisor
         * uses global structs defined in sec_rsrc.h
index 94c2e2b1e10d5819d3948ee1f155fa7fda20af26..aab3a2dae888b80fb9ccd6ca8da2a15840a44fa2 100644 (file)
 #include <plat_imx8.h>
 #include <sci/sci.h>
 
+#include "../../common/sci/imx8_mu.h"
+
 const static int ap_core_index[PLATFORM_CORE_COUNT] = {
        SC_R_A35_0, SC_R_A35_1, SC_R_A35_2, SC_R_A35_3
 };
 
+/* save gic dist/redist context when GIC is power down */
+static struct plat_gic_ctx imx_gicv3_ctx;
+static unsigned int gpt_lpcg, gpt_reg[2];
+
+static void imx_enable_irqstr_wakeup(void)
+{
+       uint32_t irq_mask;
+       gicv3_dist_ctx_t *dist_ctx = &imx_gicv3_ctx.dist_ctx;
+
+       /* put IRQSTR into ON mode */
+       sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON);
+
+       /* enable the irqsteer to handle wakeup irq */
+       mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x1);
+       for (int i = 0; i < 15; i++) {
+               irq_mask = dist_ctx->gicd_isenabler[i];
+               mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x3c - 0x4 * i, irq_mask);
+       }
+
+       /* set IRQSTR low power mode */
+       if (imx_is_wakeup_src_irqsteer())
+               sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_STBY);
+       else
+               sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF);
+}
+
+static void imx_disable_irqstr_wakeup(void)
+{
+       /* Put IRQSTEER back to ON mode */
+       sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON);
+
+       /* disable the irqsteer */
+       mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x0);
+       for (int i = 0; i < 16; i++)
+               mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x4 + 0x4 * i, 0x0);
+
+       /* Put IRQSTEER into OFF mode */
+       sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF);
+}
+
 int imx_pwr_domain_on(u_register_t mpidr)
 {
        int ret = PSCI_E_SUCCESS;
@@ -71,11 +113,52 @@ void imx_domain_suspend(const psci_power_state_t *target_state)
        u_register_t mpidr = read_mpidr_el1();
        unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
 
-       plat_gic_cpuif_disable();
+       if (is_local_state_off(target_state->pwr_domain_state[MPIDR_AFFLVL0])) {
+               plat_gic_cpuif_disable();
+               sc_pm_set_cpu_resume(ipc_handle, ap_core_index[cpu_id], true, BL31_BASE);
+               sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+                       SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+       } else {
+               dsb();
+               write_scr_el3(read_scr_el3() | SCR_FIQ_BIT);
+               isb();
+       }
 
-       sc_pm_set_cpu_resume_addr(ipc_handle, ap_core_index[cpu_id], BL31_BASE);
-       sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
-               SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+       if (is_local_state_off(target_state->pwr_domain_state[MPIDR_AFFLVL1]))
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_OFF);
+
+       if (is_local_state_retn(target_state->pwr_domain_state[PLAT_MAX_PWR_LVL])) {
+               plat_gic_cpuif_disable();
+
+               /* save gic context */
+               plat_gic_save(cpu_id, &imx_gicv3_ctx);
+               /* enable the irqsteer for wakeup */
+               imx_enable_irqstr_wakeup();
+
+               /* Save GPT clock and registers, then turn off its power */
+               gpt_lpcg = mmio_read_32(IMX_GPT0_LPCG_BASE);
+               gpt_reg[0] = mmio_read_32(IMX_GPT0_BASE);
+               gpt_reg[1] = mmio_read_32(IMX_GPT0_BASE + 0x4);
+               sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_OFF);
+
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_OFF);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_DDR,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_MU,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_INTERCONNECT,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+
+               /* Put GIC in OFF mode. */
+               sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_OFF);
+               sc_pm_set_cpu_resume(ipc_handle, ap_core_index[cpu_id], true, BL31_BASE);
+               if (imx_is_wakeup_src_irqsteer())
+                       sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+                               SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_IRQSTEER);
+               else
+                       sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+                               SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_SCU);
+       }
 }
 
 void imx_domain_suspend_finish(const psci_power_state_t *target_state)
@@ -83,10 +166,51 @@ void imx_domain_suspend_finish(const psci_power_state_t *target_state)
        u_register_t mpidr = read_mpidr_el1();
        unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
 
-       sc_pm_req_low_power_mode(ipc_handle, ap_core_index[cpu_id],
-               SC_PM_PW_MODE_ON);
+       if (is_local_state_retn(target_state->pwr_domain_state[PLAT_MAX_PWR_LVL])) {
+               MU_Resume(SC_IPC_BASE);
 
-       plat_gic_cpuif_enable();
+               sc_pm_req_low_power_mode(ipc_handle, ap_core_index[cpu_id], SC_PM_PW_MODE_ON);
+               sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+                       SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC);
+
+               /* Put GIC back to high power mode. */
+               sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_ON);
+
+               /* restore gic context */
+               plat_gic_restore(cpu_id, &imx_gicv3_ctx);
+
+               /* Turn on GPT power and restore its clock and registers */
+               sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+               sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
+               mmio_write_32(IMX_GPT0_BASE, gpt_reg[0]);
+               mmio_write_32(IMX_GPT0_BASE + 0x4, gpt_reg[1]);
+               mmio_write_32(IMX_GPT0_LPCG_BASE, gpt_lpcg);
+
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_ON);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_DDR,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_MU,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+               sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_INTERCONNECT,
+                       SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+
+               /* disable the irqsteer wakeup */
+               imx_disable_irqstr_wakeup();
+
+               plat_gic_cpuif_enable();
+       }
+
+       if (is_local_state_off(target_state->pwr_domain_state[MPIDR_AFFLVL1]))
+               sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_ON);
+
+       if (is_local_state_off(target_state->pwr_domain_state[MPIDR_AFFLVL0])) {
+               sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+                       SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC);
+               plat_gic_cpuif_enable();
+       } else {
+               write_scr_el3(read_scr_el3() & (~SCR_FIQ_BIT));
+               isb();
+       }
 }
 
 static const plat_psci_ops_t imx_plat_psci_ops = {
@@ -108,17 +232,15 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
        imx_mailbox_init(sec_entrypoint);
        *psci_ops = &imx_plat_psci_ops;
 
-       /* Request low power mode for A35 cluster, only need to do once */
-       sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_OFF);
-
-       /* Request RUN and LP modes for DDR, system interconnect etc. */
-       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35,
-               SC_PM_SYS_IF_DDR, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
-       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35,
-               SC_PM_SYS_IF_MU, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
-       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35,
-               SC_PM_SYS_IF_INTERCONNECT, SC_PM_PW_MODE_ON,
-               SC_PM_PW_MODE_STBY);
+       /* make sure system sources power ON in low power mode by default */
+       sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_ON);
+
+       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_DDR,
+               SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_MU,
+               SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+       sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_INTERCONNECT,
+               SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
 
        return 0;
 }
index 1239340d022429d8544ccf6b3250d7c3e517c760..3a3fac86f3025a72125d3cf7b1e9c98a962c15e9 100644 (file)
 #define MAX_MMAP_REGIONS               8
 
 #define PLAT_GICD_BASE                 0x51a00000
-#define PLAT_GICD_SIZE                 0x10000
 #define PLAT_GICR_BASE                 0x51b00000
-#define PLAT_GICR_SIZE                 0xc0000
 #define IMX_BOOT_UART_BASE             0x5a060000
-#define IMX_BOOT_UART_SIZE             0x1000
 #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 SC_IPC_SIZE                    0x10000
+#define IMX_GPT0_LPCG_BASE             0x5d540000
+#define IMX_GPT0_BASE                  0x5d140000
+#define IMX_WUP_IRQSTR_BASE            0x51090000
+#define IMX_REG_BASE                   0x50000000
+#define IMX_REG_SIZE                   0x10000000
 
 #define COUNTER_FREQUENCY              8000000
 
index 37c9f66376771d8341e857ce88a56c4039463220..b7fe0e811293c90fa3316ba3e1889d50450ed58e 100644 (file)
@@ -14,10 +14,12 @@ sc_rsrc_t secure_rsrcs[] = {
        SC_R_A35_3,
        SC_R_GIC,
        SC_R_SYSTEM,
-       SC_R_IRQSTR_SCU2
+       SC_R_IRQSTR_SCU2,
+       SC_R_GPT_0
 };
 
 /* resources that have register access for non-secure domain */
 sc_rsrc_t ns_access_allowed[] = {
        SC_R_GIC,
+       SC_R_GPT_0
 };
index a831bf2f05f1181fc4b3b8ee63a38ca686917020..eeb1f34ed4955b23708ede07a3c87506aa9f7738 100644 (file)
@@ -21,6 +21,8 @@ BL31_SOURCES          +=      plat/imx/common/lpuart_console.S        \
                                plat/imx/imx8qx/imx8qx_psci.c           \
                                plat/imx/common/imx8_topology.c         \
                                plat/imx/common/imx8_psci.c             \
+                               plat/imx/common/imx_sip_svc.c           \
+                               plat/imx/common/imx_sip_handler.c       \
                                plat/common/plat_psci_common.c          \
                                lib/xlat_tables/xlat_tables_common.c    \
                                lib/xlat_tables/aarch64/xlat_tables.c   \
index fb929fef1f0313eb5baa9ced0afe2b3c689fd668..163b35c4812b16d191a6e057162746c749e5370c 100644 (file)
@@ -4,11 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/bl_common.h>
 #include <common/debug.h>
 
 #include "ls_16550.h"
 #include "plat_ls.h"
-#include "../../../bl1/bl1_private.h"
 
 /* Data structure which holds the extents of the trusted SRAM for BL1*/
 static meminfo_t bl1_tzram_layout;
index 8f722102502a77eeb923b07c1efb631132ded575..7b7cef39be841360aa10bb7ab666ce372db7e753 100644 (file)
@@ -8,7 +8,6 @@
 #include <platform_def.h>
 
 #include <bl1/bl1.h>
-#include <bl1/bl1_private.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/arm/sp805.h>
index bd384a1d418f7ee9160a2f2c7fa9ee83caaa31a9..dd23e63e6d747c56de24161cfa82dc6f197aa6c3 100644 (file)
 #include <drivers/console.h>
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 
 #include <mcucfg.h>
 #include <mtcmos.h>
 #include <mtk_plat_common.h>
-#include <plat_arm.h>
 #include <plat_private.h>
 #include <spm.h>
 
index 9673d2c28924230c1277e9fb0cb34fa6496fec02..1b52470d574994ffda4d6152dc0e3365b45925d6 100644 (file)
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
 
 #include <mcucfg.h>
 #include <mt8173_def.h>
 #include <mt_cpuxgpt.h> /* generic_timer_backup() */
-#include <plat_arm.h>
 #include <plat_private.h>
 #include <power_tracer.h>
 #include <rtc.h>
index 294aea4f8b3606d982ef8056536f1fe19c5eda4f..0726efe45d25b31d96a92db5471daf968b0d06c7 100644 (file)
@@ -9,7 +9,6 @@ MTK_PLAT_SOC            :=      ${MTK_PLAT}/${PLAT}
 
 PLAT_INCLUDES          :=      -I${MTK_PLAT}/common/                           \
                                -I${MTK_PLAT}/common/drivers/uart/              \
-                               -Iinclude/plat/arm/common                       \
                                -Iinclude/plat/arm/common/aarch64               \
                                -I${MTK_PLAT_SOC}/drivers/crypt/                \
                                -I${MTK_PLAT_SOC}/drivers/mtcmos/               \
index 0476ba8262364c7b17ce17ef52c7b2b9bc96a571..b47be6dc4b9a8e22c5330592cf6613c87bafc296 100644 (file)
 #include <cortex_a57.h>
 #include <platform_def.h>
 #include <tegra_def.h>
+#include <tegra_platform.h>
 
 #define MIDR_PN_CORTEX_A57             0xD07
 
 /*******************************************************************************
  * Implementation defined ACTLR_EL3 bit definitions
  ******************************************************************************/
-#define ACTLR_EL3_L2ACTLR_BIT          (1 << 6)
-#define ACTLR_EL3_L2ECTLR_BIT          (1 << 5)
-#define ACTLR_EL3_L2CTLR_BIT           (1 << 4)
-#define ACTLR_EL3_CPUECTLR_BIT         (1 << 1)
-#define ACTLR_EL3_CPUACTLR_BIT         (1 << 0)
+#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)
+                                                               ACTLR_EL3_L2ECTLR_BIT | \
+                                                               ACTLR_EL3_L2CTLR_BIT | \
+                                                               ACTLR_EL3_CPUECTLR_BIT | \
+                                                               ACTLR_EL3_CPUACTLR_BIT)
 
        /* Global functions */
        .globl  plat_is_my_cpu_primary
@@ -45,7 +51,6 @@
        .globl  ns_image_entrypoint
        .globl  tegra_bl31_phys_base
        .globl  tegra_console_base
-       .globl  tegra_enable_l2_ecc_parity_prot
 
        /* ---------------------
         * Common CPU init code
         * Enable L2 and CPU ECTLR RW access from non-secure world
         * -------------------------------------------------------
         */
-       mov     x0, #ACTLR_EL3_ENABLE_ALL_ACCESS
+       mrs     x0, actlr_el3
+       mov     x1, #ACTLR_EL3_ENABLE_ALL_MASK
+       bic     x0, x0, x1
+       mov     x1, #ACTLR_EL3_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
+       orr     x0, x0, x1
        msr     actlr_el2, x0
        isb
 
-       /* -------------------------------------------------------
-        * Enable L2 ECC and Parity Protection
-        * -------------------------------------------------------
-        */
-       adr     x0, tegra_enable_l2_ecc_parity_prot
-       ldr     x0, [x0]
-       cbz     x0, 1f
-       mrs     x0, CORTEX_A57_L2CTLR_EL1
-       and     x1, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT
-       cbnz    x1, 1f
-       orr     x0, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT
-       msr     CORTEX_A57_L2CTLR_EL1, x0
-       isb
-
        /* --------------------------------
         * Enable the cycle count register
         * --------------------------------
@@ -144,17 +144,20 @@ func plat_is_my_cpu_primary
        ret
 endfunc plat_is_my_cpu_primary
 
-       /* -----------------------------------------------------
+       /* ----------------------------------------------------------
         * unsigned int plat_my_core_pos(void);
         *
-        * result: CorePos = CoreId + (ClusterId << 2)
-        * -----------------------------------------------------
+        * result: CorePos = CoreId + (ClusterId * cpus per cluster)
+        * ----------------------------------------------------------
         */
 func plat_my_core_pos
        mrs     x0, mpidr_el1
        and     x1, x0, #MPIDR_CPU_MASK
        and     x0, x0, #MPIDR_CLUSTER_MASK
-       add     x0, x1, x0, LSR #6
+       lsr     x0, x0, #MPIDR_AFFINITY_BITS
+       mov     x2, #PLATFORM_MAX_CPUS_PER_CLUSTER
+       mul     x0, x0, x2
+       add     x0, x1, x0
        ret
 endfunc plat_my_core_pos
 
@@ -176,14 +179,17 @@ endfunc plat_get_my_entrypoint
        /* -----------------------------------------------------
         * int platform_get_core_pos(int mpidr);
         *
-        * With this function: CorePos = (ClusterId * 4) +
-        *                                CoreId
+        * result: CorePos = (ClusterId * cpus per cluster) +
+        *                   CoreId
         * -----------------------------------------------------
         */
 func platform_get_core_pos
        and     x1, x0, #MPIDR_CPU_MASK
        and     x0, x0, #MPIDR_CLUSTER_MASK
-       add     x0, x1, x0, LSR #6
+       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
 
@@ -326,6 +332,23 @@ func tegra_secure_entrypoint _align=6
 
 #if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
 
+       /* --------------------------------------------------------
+        * Skip the invalidate BTB workaround for Tegra210B01 SKUs.
+        * --------------------------------------------------------
+        */
+       mov     x0, #TEGRA_MISC_BASE
+       add     x0, x0, #HARDWARE_REVISION_OFFSET
+       ldr     w1, [x0]
+       lsr     w1, w1, #CHIP_ID_SHIFT
+       and     w1, w1, #CHIP_ID_MASK
+       cmp     w1, #TEGRA_CHIPID_TEGRA21       /* T210? */
+       b.ne    2f
+       ldr     w1, [x0]
+       lsr     w1, w1, #MAJOR_VERSION_SHIFT
+       and     w1, w1, #MAJOR_VERSION_MASK
+       cmp     w1, #0x02                       /* T210 B01? */
+       b.eq    2f
+
        /* -------------------------------------------------------
         * Invalidate BTB along with I$ to remove any stale
         * entries from the branch predictor array.
@@ -382,7 +405,7 @@ func tegra_secure_entrypoint _align=6
        .rept   65
        nop
        .endr
-
+2:
        /* --------------------------------------------------
         * Do not insert instructions here
         * --------------------------------------------------
@@ -397,31 +420,6 @@ restore_oslock:
        mov     x0, #1
        msr     oslar_el1, x0
 
-       cpu_init_common
-
-       /* ---------------------------------------------------------------------
-        * The initial state of the Architectural feature trap register
-        * (CPTR_EL3) is unknown and it must be set to a known state. All
-        * feature traps are disabled. Some bits in this register are marked as
-        * Reserved and should not be modified.
-        *
-        * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
-        *  or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
-        * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
-        *  to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
-        *  access to trace functionality is not supported, this bit is RES0.
-        * CPTR_EL3.TFP: This causes instructions that access the registers
-        *  associated with Floating Point and Advanced SIMD execution to trap
-        *  to EL3 when executed from any exception level, unless trapped to EL1
-        *  or EL2.
-        * ---------------------------------------------------------------------
-        */
-       mrs     x1, cptr_el3
-       bic     w1, w1, #TCPAC_BIT
-       bic     w1, w1, #TTA_BIT
-       bic     w1, w1, #TFP_BIT
-       msr     cptr_el3, x1
-
        /* --------------------------------------------------
         * Get secure world's entry point and jump to it
         * --------------------------------------------------
@@ -460,10 +458,3 @@ tegra_bl31_phys_base:
         */
 tegra_console_base:
        .quad   0
-
-       /* --------------------------------------------------
-        * Enable L2 ECC and Parity Protection
-        * --------------------------------------------------
-        */
-tegra_enable_l2_ecc_parity_prot:
-       .quad   0
diff --git a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
new file mode 100644 (file)
index 0000000..1c5d2e1
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bpmp.h>
+#include <common/debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stdbool.h>
+#include <string.h>
+#include <tegra_def.h>
+
+#define BPMP_TIMEOUT   2
+
+static uint32_t channel_base[NR_CHANNELS];
+static uint32_t bpmp_init_state = BPMP_INIT_PENDING;
+
+static uint32_t channel_field(unsigned int ch)
+{
+       return mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET) & CH_MASK(ch);
+}
+
+static bool master_free(unsigned int ch)
+{
+       return channel_field(ch) == MA_FREE(ch);
+}
+
+static bool master_acked(unsigned int ch)
+{
+       return channel_field(ch) == MA_ACKD(ch);
+}
+
+static void signal_slave(unsigned int ch)
+{
+       mmio_write_32(TEGRA_RES_SEMA_BASE + CLR_OFFSET, CH_MASK(ch));
+}
+
+static void free_master(unsigned int ch)
+{
+       mmio_write_32(TEGRA_RES_SEMA_BASE + CLR_OFFSET,
+                     MA_ACKD(ch) ^ MA_FREE(ch));
+}
+
+/* should be called with local irqs disabled */
+int32_t tegra_bpmp_send_receive_atomic(int mrq, const void *ob_data, int ob_sz,
+               void *ib_data, int ib_sz)
+{
+       unsigned int ch = (unsigned int)plat_my_core_pos();
+       mb_data_t *p = (mb_data_t *)(uintptr_t)channel_base[ch];
+       int32_t ret = -ETIMEDOUT, timeout = 0;
+
+       if (bpmp_init_state == BPMP_INIT_COMPLETE) {
+
+               /* loop until BPMP is free */
+               for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) {
+                       if (master_free(ch) == true) {
+                               break;
+                       }
+
+                       mdelay(1);
+               }
+
+               if (timeout != BPMP_TIMEOUT) {
+
+                       /* generate the command struct */
+                       p->code = mrq;
+                       p->flags = DO_ACK;
+                       (void)memcpy((void *)p->data, ob_data, (size_t)ob_sz);
+
+                       /* signal command ready to the BPMP */
+                       signal_slave(ch);
+                       mmio_write_32(TEGRA_PRI_ICTLR_BASE + CPU_IEP_FIR_SET,
+                                     (1U << INT_SHR_SEM_OUTBOX_FULL));
+
+                       /* loop until the command is executed */
+                       for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) {
+                               if (master_acked(ch) == true) {
+                                       break;
+                               }
+
+                               mdelay(1);
+                       }
+
+                       if (timeout != BPMP_TIMEOUT) {
+
+                               /* get the command response */
+                               (void)memcpy(ib_data, (const void *)p->data,
+                                            (size_t)ib_sz);
+
+                               /* return error code */
+                               ret = p->code;
+
+                               /* free this channel */
+                               free_master(ch);
+                       }
+               }
+
+       } else {
+               /* return error code */
+               ret = -EINVAL;
+       }
+
+       if (timeout == BPMP_TIMEOUT) {
+               ERROR("Timed out waiting for bpmp's response\n");
+       }
+
+       return ret;
+}
+
+int tegra_bpmp_init(void)
+{
+       uint32_t val, base;
+       unsigned int ch;
+       int ret = 0;
+
+       if (bpmp_init_state != BPMP_INIT_COMPLETE) {
+
+               /* check if the bpmp processor is alive. */
+               val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET);
+               if (val != SIGN_OF_LIFE) {
+                       ERROR("BPMP precessor not available\n");
+                       return -ENOTSUP;
+               }
+
+               /* check if clock for the atomics block is enabled */
+               val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_ENB_V);
+               if ((val & CAR_ENABLE_ATOMICS) == 0) {
+                       ERROR("Clock to the atomics block is disabled\n");
+               }
+
+               /* check if the atomics block is out of reset */
+               val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_CLR_V);
+               if ((val & CAR_ENABLE_ATOMICS) == CAR_ENABLE_ATOMICS) {
+                       ERROR("Reset to the atomics block is asserted\n");
+               }
+
+               /* base address to get the result from Atomics */
+               base = TEGRA_ATOMICS_BASE + RESULT0_REG_OFFSET;
+
+               /* channel area is setup by BPMP before signaling handshake */
+               for (ch = 0; ch < NR_CHANNELS; ch++) {
+
+                       /* issue command to get the channel base address */
+                       mmio_write_32(base, (ch << TRIGGER_ID_SHIFT) |
+                                     ATOMIC_CMD_GET);
+
+                       /* get the base address for the channel */
+                       channel_base[ch] = mmio_read_32(base);
+
+                       /* increment result register offset */
+                       base += 4U;
+               }
+
+               /* mark state as "initialized" */
+               bpmp_init_state = BPMP_INIT_COMPLETE;
+
+               /* the channel values have to be visible across all cpus */
+               flush_dcache_range((uint64_t)channel_base, sizeof(channel_base));
+               flush_dcache_range((uint64_t)&bpmp_init_state,
+                                  sizeof(bpmp_init_state));
+
+               INFO("%s: done\n", __func__);
+       }
+
+       return ret;
+}
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
new file mode 100644 (file)
index 0000000..7faa2f0
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bpmp_ipc.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <tegra_def.h>
+#include <utils_def.h>
+
+#include "intf.h"
+#include "ivc.h"
+
+/**
+ * Holds IVC channel data
+ */
+struct ccplex_bpmp_channel_data {
+       /* Buffer for incoming data */
+       struct frame_data *ib;
+
+       /* Buffer for outgoing data */
+       struct frame_data *ob;
+};
+
+static struct ccplex_bpmp_channel_data s_channel;
+static struct ivc ivc_ccplex_bpmp_channel;
+
+/*
+ * Helper functions to access the HSP doorbell registers
+ */
+static inline uint32_t hsp_db_read(uint32_t reg)
+{
+       return mmio_read_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg));
+}
+
+static inline void hsp_db_write(uint32_t reg, uint32_t val)
+{
+       mmio_write_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg), val);
+}
+
+/*******************************************************************************
+ *      IVC wrappers for CCPLEX <-> BPMP communication.
+ ******************************************************************************/
+
+static void tegra_bpmp_ring_bpmp_doorbell(void);
+
+/*
+ * Get the next frame where data can be written.
+ */
+static struct frame_data *tegra_bpmp_get_next_out_frame(void)
+{
+       struct frame_data *frame;
+       const struct ivc *ch = &ivc_ccplex_bpmp_channel;
+
+       frame = (struct frame_data *)tegra_ivc_write_get_next_frame(ch);
+       if (frame == NULL) {
+               ERROR("%s: Error in getting next frame, exiting\n", __func__);
+       } else {
+               s_channel.ob = frame;
+       }
+
+       return frame;
+}
+
+static void tegra_bpmp_signal_slave(void)
+{
+       (void)tegra_ivc_write_advance(&ivc_ccplex_bpmp_channel);
+       tegra_bpmp_ring_bpmp_doorbell();
+}
+
+static int32_t tegra_bpmp_free_master(void)
+{
+       return tegra_ivc_read_advance(&ivc_ccplex_bpmp_channel);
+}
+
+static bool tegra_bpmp_slave_acked(void)
+{
+       struct frame_data *frame;
+       bool ret = true;
+
+       frame = (struct frame_data *)tegra_ivc_read_get_next_frame(&ivc_ccplex_bpmp_channel);
+       if (frame == NULL) {
+               ret = false;
+       } else {
+               s_channel.ib = frame;
+       }
+
+       return ret;
+}
+
+static struct frame_data *tegra_bpmp_get_cur_in_frame(void)
+{
+       return s_channel.ib;
+}
+
+/*
+ * Enables BPMP to ring CCPlex doorbell
+ */
+static void tegra_bpmp_enable_ccplex_doorbell(void)
+{
+       uint32_t reg;
+
+       reg = hsp_db_read(HSP_DBELL_1_ENABLE);
+       reg |= HSP_MASTER_BPMP_BIT;
+       hsp_db_write(HSP_DBELL_1_ENABLE, reg);
+}
+
+/*
+ * CCPlex rings the BPMP doorbell
+ */
+static void tegra_bpmp_ring_bpmp_doorbell(void)
+{
+       /*
+        * Any writes to this register has the same effect,
+        * uses master ID of the write transaction and set
+        * corresponding flag.
+        */
+       hsp_db_write(HSP_DBELL_3_TRIGGER, HSP_MASTER_CCPLEX_BIT);
+}
+
+/*
+ * Returns true if CCPLex can ring BPMP doorbell, otherwise false.
+ * This also signals that BPMP is up and ready.
+ */
+static bool tegra_bpmp_can_ccplex_ring_doorbell(void)
+{
+       uint32_t reg;
+
+       /* check if ccplex can communicate with bpmp */
+       reg = hsp_db_read(HSP_DBELL_3_ENABLE);
+
+       return ((reg & HSP_MASTER_CCPLEX_BIT) != 0U);
+}
+
+static int32_t tegra_bpmp_wait_for_slave_ack(void)
+{
+       uint32_t timeout = TIMEOUT_RESPONSE_FROM_BPMP_US;
+
+       while (!tegra_bpmp_slave_acked() && (timeout != 0U)) {
+               udelay(1);
+               timeout--;
+       };
+
+       return ((timeout == 0U) ? -ETIMEDOUT : 0);
+}
+
+/*
+ * Notification from the ivc layer
+ */
+static void tegra_bpmp_ivc_notify(const struct ivc *ivc)
+{
+       (void)(ivc);
+
+       tegra_bpmp_ring_bpmp_doorbell();
+}
+
+/*
+ * Atomic send/receive API, which means it waits until slave acks
+ */
+static int32_t tegra_bpmp_ipc_send_req_atomic(uint32_t mrq, void *p_out,
+                       uint32_t size_out, void *p_in, uint32_t size_in)
+{
+       struct frame_data *frame = tegra_bpmp_get_next_out_frame();
+       const struct frame_data *f_in = NULL;
+       int32_t ret = 0;
+       void *p_fdata;
+
+       if ((p_out == NULL) || (size_out > IVC_DATA_SZ_BYTES) ||
+           (frame == NULL)) {
+               ERROR("%s: invalid parameters, exiting\n", __func__);
+               ret = -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);
+
+               /* 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");
+               }
+
+               /* retrieve the response frame */
+               if ((size_in <= IVC_DATA_SZ_BYTES) && (p_in != NULL) &&
+                   (ret == 0)) {
+
+                       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");
+                       }
+               }
+       }
+
+       return ret;
+}
+
+/*
+ * Initializes the BPMP<--->CCPlex communication path.
+ */
+int32_t tegra_bpmp_ipc_init(void)
+{
+       size_t msg_size;
+       uint32_t frame_size, timeout;
+       int32_t error = 0;
+
+       /* allow bpmp to ring CCPLEX's doorbell */
+       tegra_bpmp_enable_ccplex_doorbell();
+
+       /* wait for BPMP to actually ring the doorbell */
+       timeout = TIMEOUT_RESPONSE_FROM_BPMP_US;
+       while ((timeout != 0U) && !tegra_bpmp_can_ccplex_ring_doorbell()) {
+               udelay(1); /* bpmp turn-around time */
+               timeout--;
+       }
+
+       if (timeout == 0U) {
+               ERROR("%s: BPMP firmware is not ready\n", __func__);
+               return -ENOTSUP;
+       }
+
+       INFO("%s: BPMP handshake completed\n", __func__);
+
+       msg_size = tegra_ivc_align(IVC_CMD_SZ_BYTES);
+       frame_size = (uint32_t)tegra_ivc_total_queue_size(msg_size);
+       if (frame_size > TEGRA_BPMP_IPC_CH_MAP_SIZE) {
+               ERROR("%s: carveout size is not sufficient\n", __func__);
+               return -EINVAL;
+       }
+
+       error = tegra_ivc_init(&ivc_ccplex_bpmp_channel,
+                               (uint32_t)TEGRA_BPMP_IPC_RX_PHYS_BASE,
+                               (uint32_t)TEGRA_BPMP_IPC_TX_PHYS_BASE,
+                               1U, frame_size, tegra_bpmp_ivc_notify);
+       if (error != 0) {
+
+               ERROR("%s: IVC init failed (%d)\n", __func__, error);
+
+       } else {
+
+               /* reset channel */
+               tegra_ivc_channel_reset(&ivc_ccplex_bpmp_channel);
+
+               /* wait for notification from BPMP */
+               while (tegra_ivc_channel_notified(&ivc_ccplex_bpmp_channel) != 0) {
+                       /*
+                        * Interrupt BPMP with doorbell each time after
+                        * tegra_ivc_channel_notified() returns non zero
+                        * value.
+                        */
+                       tegra_bpmp_ring_bpmp_doorbell();
+               }
+
+               INFO("%s: All communication channels initialized\n", __func__);
+       }
+
+       return error;
+}
+
+/* Handler to reset a hardware module */
+int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id)
+{
+       int32_t ret;
+       struct mrq_reset_request req = {
+               .cmd = (uint32_t)CMD_RESET_MODULE,
+               .reset_id = rst_id
+       };
+
+       /* only GPCDMA/XUSB_PADCTL resets are supported */
+       assert((rst_id == TEGRA_RESET_ID_XUSB_PADCTL) ||
+              (rst_id == TEGRA_RESET_ID_GPCDMA));
+
+       ret = tegra_bpmp_ipc_send_req_atomic(MRQ_RESET, &req,
+                       (uint32_t)sizeof(req), NULL, 0);
+       if (ret != 0) {
+               ERROR("%s: failed for module %d with error %d\n", __func__,
+                     rst_id, ret);
+       }
+
+       return ret;
+}
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
new file mode 100644 (file)
index 0000000..689f8bb
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef INTF_H
+#define INTF_H
+
+/**
+ * Flags used in IPC req
+ */
+#define FLAG_DO_ACK                    (U(1) << 0)
+#define FLAG_RING_DOORBELL             (U(1) << 1)
+
+/* Bit 1 is designated for CCPlex in secure world */
+#define HSP_MASTER_CCPLEX_BIT          (U(1) << 1)
+/* Bit 19 is designated for BPMP in non-secure world */
+#define HSP_MASTER_BPMP_BIT            (U(1) << 19)
+/* Timeout to receive response from BPMP is 1 sec */
+#define TIMEOUT_RESPONSE_FROM_BPMP_US  U(1000000) /* in microseconds */
+
+/**
+ * IVC protocol defines and command/response frame
+ */
+
+/**
+ * IVC specific defines
+ */
+#define IVC_CMD_SZ_BYTES               U(128)
+#define IVC_DATA_SZ_BYTES              U(120)
+
+/**
+ * Holds frame data for an IPC request
+ */
+struct frame_data {
+       /* Identification as to what kind of data is being transmitted */
+       uint32_t mrq;
+
+       /* Flags for slave as to how to respond back */
+       uint32_t flags;
+
+       /* Actual data being sent */
+       uint8_t data[IVC_DATA_SZ_BYTES];
+};
+
+/**
+ * Commands send to the BPMP firmware
+ */
+
+/**
+ * MRQ code to issue a module reset command to BPMP
+ */
+#define MRQ_RESET                      U(20)
+
+/**
+ * Reset sub-commands
+ */
+#define CMD_RESET_ASSERT               U(1)
+#define CMD_RESET_DEASSERT             U(2)
+#define CMD_RESET_MODULE               U(3)
+
+/**
+ * Used by the sender of an #MRQ_RESET message to request BPMP to
+ * assert or deassert a given reset line.
+ */
+struct __attribute__((packed)) mrq_reset_request {
+       /* reset action to perform (mrq_reset_commands) */
+       uint32_t cmd;
+       /* id of the reset to affected */
+       uint32_t reset_id;
+};
+
+#endif /* INTF_H */
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c
new file mode 100644 (file)
index 0000000..4212eca
--- /dev/null
@@ -0,0 +1,653 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "ivc.h"
+
+/*
+ * IVC channel reset protocol.
+ *
+ * Each end uses its tx_channel.state to indicate its synchronization state.
+ */
+enum {
+       /*
+        * This value is zero for backwards compatibility with services that
+        * assume channels to be initially zeroed. Such channels are in an
+        * initially valid state, but cannot be asynchronously reset, and must
+        * maintain a valid state at all times.
+        *
+        * The transmitting end can enter the established state from the sync or
+        * ack state when it observes the receiving endpoint in the ack or
+        * established state, indicating that has cleared the counters in our
+        * rx_channel.
+        */
+       ivc_state_established = U(0),
+
+       /*
+        * If an endpoint is observed in the sync state, the remote endpoint is
+        * allowed to clear the counters it owns asynchronously with respect to
+        * the current endpoint. Therefore, the current endpoint is no longer
+        * allowed to communicate.
+        */
+       ivc_state_sync = U(1),
+
+       /*
+        * When the transmitting end observes the receiving end in the sync
+        * state, it can clear the w_count and r_count and transition to the ack
+        * state. If the remote endpoint observes us in the ack state, it can
+        * return to the established state once it has cleared its counters.
+        */
+       ivc_state_ack = U(2)
+};
+
+/*
+ * This structure is divided into two-cache aligned parts, the first is only
+ * written through the tx_channel pointer, while the second is only written
+ * through the rx_channel pointer. This delineates ownership of the cache lines,
+ * which is critical to performance and necessary in non-cache coherent
+ * implementations.
+ */
+struct ivc_channel_header {
+       struct {
+               /* fields owned by the transmitting end */
+               uint32_t w_count;
+               uint32_t state;
+               uint32_t w_rsvd[IVC_CHHDR_TX_FIELDS - 2];
+       };
+       struct {
+               /* fields owned by the receiving end */
+               uint32_t r_count;
+               uint32_t r_rsvd[IVC_CHHDR_RX_FIELDS - 1];
+       };
+};
+
+static inline bool ivc_channel_empty(const struct ivc *ivc,
+               volatile const struct ivc_channel_header *ch)
+{
+       /*
+        * This function performs multiple checks on the same values with
+        * security implications, so sample the counters' current values in
+        * shared memory to ensure that these checks use the same values.
+        */
+       uint32_t wr_count = ch->w_count;
+       uint32_t rd_count = ch->r_count;
+       bool ret = false;
+
+       (void)ivc;
+
+       /*
+        * Perform an over-full check to prevent denial of service attacks where
+        * a server could be easily fooled into believing that there's an
+        * extremely large number of frames ready, since receivers are not
+        * expected to check for full or over-full conditions.
+        *
+        * Although the channel isn't empty, this is an invalid case caused by
+        * a potentially malicious peer, so returning empty is safer, because it
+        * gives the impression that the channel has gone silent.
+        */
+       if (((wr_count - rd_count) > ivc->nframes) || (wr_count == rd_count)) {
+               ret = true;
+       }
+
+       return ret;
+}
+
+static inline bool ivc_channel_full(const struct ivc *ivc,
+               volatile const struct ivc_channel_header *ch)
+{
+       uint32_t wr_count = ch->w_count;
+       uint32_t rd_count = ch->r_count;
+
+       (void)ivc;
+
+       /*
+        * Invalid cases where the counters indicate that the queue is over
+        * capacity also appear full.
+        */
+       return ((wr_count - rd_count) >= ivc->nframes);
+}
+
+static inline uint32_t ivc_channel_avail_count(const struct ivc *ivc,
+               volatile const struct ivc_channel_header *ch)
+{
+       uint32_t wr_count = ch->w_count;
+       uint32_t rd_count = ch->r_count;
+
+       (void)ivc;
+
+       /*
+        * This function isn't expected to be used in scenarios where an
+        * over-full situation can lead to denial of service attacks. See the
+        * comment in ivc_channel_empty() for an explanation about special
+        * over-full considerations.
+        */
+       return (wr_count - rd_count);
+}
+
+static inline void ivc_advance_tx(struct ivc *ivc)
+{
+       ivc->tx_channel->w_count++;
+
+       if (ivc->w_pos == (ivc->nframes - (uint32_t)1U)) {
+               ivc->w_pos = 0U;
+       } else {
+               ivc->w_pos++;
+       }
+}
+
+static inline void ivc_advance_rx(struct ivc *ivc)
+{
+       ivc->rx_channel->r_count++;
+
+       if (ivc->r_pos == (ivc->nframes - (uint32_t)1U)) {
+               ivc->r_pos = 0U;
+       } else {
+               ivc->r_pos++;
+       }
+}
+
+static inline int32_t ivc_check_read(const struct ivc *ivc)
+{
+       /*
+        * tx_channel->state is set locally, so it is not synchronized with
+        * state from the remote peer. The remote peer cannot reset its
+        * transmit counters until we've acknowledged its synchronization
+        * request, so no additional synchronization is required because an
+        * asynchronous transition of rx_channel->state to ivc_state_ack is not
+        * allowed.
+        */
+       if (ivc->tx_channel->state != ivc_state_established) {
+               return -ECONNRESET;
+       }
+
+       /*
+       * Avoid unnecessary invalidations when performing repeated accesses to
+       * an IVC channel by checking the old queue pointers first.
+       * Synchronization is only necessary when these pointers indicate empty
+       * or full.
+       */
+       if (!ivc_channel_empty(ivc, ivc->rx_channel)) {
+               return 0;
+       }
+
+       return ivc_channel_empty(ivc, ivc->rx_channel) ? -ENOMEM : 0;
+}
+
+static inline int32_t ivc_check_write(const struct ivc *ivc)
+{
+       if (ivc->tx_channel->state != ivc_state_established) {
+               return -ECONNRESET;
+       }
+
+       if (!ivc_channel_full(ivc, ivc->tx_channel)) {
+               return 0;
+       }
+
+       return ivc_channel_full(ivc, ivc->tx_channel) ? -ENOMEM : 0;
+}
+
+bool tegra_ivc_can_read(const struct ivc *ivc)
+{
+       return ivc_check_read(ivc) == 0;
+}
+
+bool tegra_ivc_can_write(const struct ivc *ivc)
+{
+       return ivc_check_write(ivc) == 0;
+}
+
+bool tegra_ivc_tx_empty(const struct ivc *ivc)
+{
+       return ivc_channel_empty(ivc, ivc->tx_channel);
+}
+
+static inline uintptr_t calc_frame_offset(uint32_t frame_index,
+       uint32_t frame_size, uint32_t frame_offset)
+{
+    return ((uintptr_t)frame_index * (uintptr_t)frame_size) +
+           (uintptr_t)frame_offset;
+}
+
+static void *ivc_frame_pointer(const struct ivc *ivc,
+                               volatile const struct ivc_channel_header *ch,
+                               uint32_t frame)
+{
+       assert(frame < ivc->nframes);
+       return (void *)((uintptr_t)(&ch[1]) +
+               calc_frame_offset(frame, ivc->frame_size, 0));
+}
+
+int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read)
+{
+       const void *src;
+       int32_t result;
+
+       if (buf == NULL) {
+               return -EINVAL;
+       }
+
+       if (max_read > ivc->frame_size) {
+               return -E2BIG;
+       }
+
+       result = ivc_check_read(ivc);
+       if (result != 0) {
+               return result;
+       }
+
+       /*
+        * Order observation of w_pos potentially indicating new data before
+        * data read.
+        */
+       dmbish();
+
+       src = ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos);
+
+       (void)memcpy(buf, src, max_read);
+
+       ivc_advance_rx(ivc);
+
+       /*
+        * Ensure our write to r_pos occurs before our read from w_pos.
+        */
+       dmbish();
+
+       /*
+        * Notify only upon transition from full to non-full.
+        * The available count can only asynchronously increase, so the
+        * worst possible side-effect will be a spurious notification.
+        */
+       if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) {
+               ivc->notify(ivc);
+       }
+
+       return (int32_t)max_read;
+}
+
+/* directly peek at the next frame rx'ed */
+void *tegra_ivc_read_get_next_frame(const struct ivc *ivc)
+{
+       if (ivc_check_read(ivc) != 0) {
+               return NULL;
+       }
+
+       /*
+        * Order observation of w_pos potentially indicating new data before
+        * data read.
+        */
+       dmbld();
+
+       return ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos);
+}
+
+int32_t tegra_ivc_read_advance(struct ivc *ivc)
+{
+       /*
+        * No read barriers or synchronization here: the caller is expected to
+        * have already observed the channel non-empty. This check is just to
+        * catch programming errors.
+        */
+       int32_t result = ivc_check_read(ivc);
+       if (result != 0) {
+               return result;
+       }
+
+       ivc_advance_rx(ivc);
+
+       /*
+        * Ensure our write to r_pos occurs before our read from w_pos.
+        */
+       dmbish();
+
+       /*
+        * Notify only upon transition from full to non-full.
+        * The available count can only asynchronously increase, so the
+        * worst possible side-effect will be a spurious notification.
+        */
+       if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) {
+               ivc->notify(ivc);
+       }
+
+       return 0;
+}
+
+int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size)
+{
+       void *p;
+       int32_t result;
+
+       if ((buf == NULL) || (ivc == NULL)) {
+               return -EINVAL;
+       }
+
+       if (size > ivc->frame_size) {
+               return -E2BIG;
+       }
+
+       result = ivc_check_write(ivc);
+       if (result != 0) {
+               return result;
+       }
+
+       p = ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos);
+
+       (void)memset(p, 0, ivc->frame_size);
+       (void)memcpy(p, buf, size);
+
+       /*
+        * Ensure that updated data is visible before the w_pos counter
+        * indicates that it is ready.
+        */
+       dmbst();
+
+       ivc_advance_tx(ivc);
+
+       /*
+        * Ensure our write to w_pos occurs before our read from r_pos.
+        */
+       dmbish();
+
+       /*
+        * Notify only upon transition from empty to non-empty.
+        * The available count can only asynchronously decrease, so the
+        * worst possible side-effect will be a spurious notification.
+        */
+       if (ivc_channel_avail_count(ivc, ivc->tx_channel) == 1U) {
+               ivc->notify(ivc);
+       }
+
+       return (int32_t)size;
+}
+
+/* directly poke at the next frame to be tx'ed */
+void *tegra_ivc_write_get_next_frame(const struct ivc *ivc)
+{
+       if (ivc_check_write(ivc) != 0) {
+               return NULL;
+       }
+
+       return ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos);
+}
+
+/* advance the tx buffer */
+int32_t tegra_ivc_write_advance(struct ivc *ivc)
+{
+       int32_t result = ivc_check_write(ivc);
+
+       if (result != 0) {
+               return result;
+       }
+
+       /*
+        * Order any possible stores to the frame before update of w_pos.
+        */
+       dmbst();
+
+       ivc_advance_tx(ivc);
+
+       /*
+        * Ensure our write to w_pos occurs before our read from r_pos.
+        */
+       dmbish();
+
+       /*
+        * Notify only upon transition from empty to non-empty.
+        * The available count can only asynchronously decrease, so the
+        * worst possible side-effect will be a spurious notification.
+        */
+       if (ivc_channel_avail_count(ivc, ivc->tx_channel) == (uint32_t)1U) {
+               ivc->notify(ivc);
+       }
+
+       return 0;
+}
+
+void tegra_ivc_channel_reset(const struct ivc *ivc)
+{
+       ivc->tx_channel->state = ivc_state_sync;
+       ivc->notify(ivc);
+}
+
+/*
+ * ===============================================================
+ *  IVC State Transition Table - see tegra_ivc_channel_notified()
+ * ===============================================================
+ *
+ *     local   remote  action
+ *     -----   ------  -----------------------------------
+ *     SYNC    EST     <none>
+ *     SYNC    ACK     reset counters; move to EST; notify
+ *     SYNC    SYNC    reset counters; move to ACK; notify
+ *     ACK     EST     move to EST; notify
+ *     ACK     ACK     move to EST; notify
+ *     ACK     SYNC    reset counters; move to ACK; notify
+ *     EST     EST     <none>
+ *     EST     ACK     <none>
+ *     EST     SYNC    reset counters; move to ACK; notify
+ *
+ * ===============================================================
+ */
+int32_t tegra_ivc_channel_notified(struct ivc *ivc)
+{
+       uint32_t peer_state;
+
+       /* Copy the receiver's state out of shared memory. */
+       peer_state = ivc->rx_channel->state;
+
+       if (peer_state == (uint32_t)ivc_state_sync) {
+               /*
+                * Order observation of ivc_state_sync before stores clearing
+                * tx_channel.
+                */
+               dmbld();
+
+               /*
+                * Reset tx_channel counters. The remote end is in the SYNC
+                * state and won't make progress until we change our state,
+                * so the counters are not in use at this time.
+                */
+               ivc->tx_channel->w_count = 0U;
+               ivc->rx_channel->r_count = 0U;
+
+               ivc->w_pos = 0U;
+               ivc->r_pos = 0U;
+
+               /*
+                * Ensure that counters appear cleared before new state can be
+                * observed.
+                */
+               dmbst();
+
+               /*
+                * Move to ACK state. We have just cleared our counters, so it
+                * is now safe for the remote end to start using these values.
+                */
+               ivc->tx_channel->state = ivc_state_ack;
+
+               /*
+                * Notify remote end to observe state transition.
+                */
+               ivc->notify(ivc);
+
+       } else if ((ivc->tx_channel->state == (uint32_t)ivc_state_sync) &&
+                       (peer_state == (uint32_t)ivc_state_ack)) {
+               /*
+                * Order observation of ivc_state_sync before stores clearing
+                * tx_channel.
+                */
+               dmbld();
+
+               /*
+                * Reset tx_channel counters. The remote end is in the ACK
+                * state and won't make progress until we change our state,
+                * so the counters are not in use at this time.
+                */
+               ivc->tx_channel->w_count = 0U;
+               ivc->rx_channel->r_count = 0U;
+
+               ivc->w_pos = 0U;
+               ivc->r_pos = 0U;
+
+               /*
+                * Ensure that counters appear cleared before new state can be
+                * observed.
+                */
+               dmbst();
+
+               /*
+                * Move to ESTABLISHED state. We know that the remote end has
+                * already cleared its counters, so it is safe to start
+                * writing/reading on this channel.
+                */
+               ivc->tx_channel->state = ivc_state_established;
+
+               /*
+                * Notify remote end to observe state transition.
+                */
+               ivc->notify(ivc);
+
+       } else if (ivc->tx_channel->state == (uint32_t)ivc_state_ack) {
+               /*
+                * At this point, we have observed the peer to be in either
+                * the ACK or ESTABLISHED state. Next, order observation of
+                * peer state before storing to tx_channel.
+                */
+               dmbld();
+
+               /*
+                * Move to ESTABLISHED state. We know that we have previously
+                * cleared our counters, and we know that the remote end has
+                * cleared its counters, so it is safe to start writing/reading
+                * on this channel.
+                */
+               ivc->tx_channel->state = ivc_state_established;
+
+               /*
+                * Notify remote end to observe state transition.
+                */
+               ivc->notify(ivc);
+
+       } else {
+               /*
+                * There is no need to handle any further action. Either the
+                * channel is already fully established, or we are waiting for
+                * the remote end to catch up with our current state. Refer
+                * to the diagram in "IVC State Transition Table" above.
+                */
+       }
+
+       return ((ivc->tx_channel->state == (uint32_t)ivc_state_established) ? 0 : -EAGAIN);
+}
+
+size_t tegra_ivc_align(size_t size)
+{
+       return (size + (IVC_ALIGN - 1U)) & ~(IVC_ALIGN - 1U);
+}
+
+size_t tegra_ivc_total_queue_size(size_t queue_size)
+{
+       if ((queue_size & (IVC_ALIGN - 1U)) != 0U) {
+               ERROR("queue_size (%d) must be %d-byte aligned\n",
+                               (int32_t)queue_size, IVC_ALIGN);
+               return 0;
+       }
+       return queue_size + sizeof(struct ivc_channel_header);
+}
+
+static int32_t check_ivc_params(uintptr_t queue_base1, uintptr_t queue_base2,
+               uint32_t nframes, uint32_t frame_size)
+{
+       assert((offsetof(struct ivc_channel_header, w_count)
+                               & (IVC_ALIGN - 1U)) == 0U);
+       assert((offsetof(struct ivc_channel_header, r_count)
+                               & (IVC_ALIGN - 1U)) == 0U);
+       assert((sizeof(struct ivc_channel_header) & (IVC_ALIGN - 1U)) == 0U);
+
+       if (((uint64_t)nframes * (uint64_t)frame_size) >= 0x100000000ULL) {
+               ERROR("nframes * frame_size overflows\n");
+               return -EINVAL;
+       }
+
+       /*
+        * The headers must at least be aligned enough for counters
+        * to be accessed atomically.
+        */
+       if ((queue_base1 & (IVC_ALIGN - 1U)) != 0U) {
+               ERROR("ivc channel start not aligned: %lx\n", queue_base1);
+               return -EINVAL;
+       }
+       if ((queue_base2 & (IVC_ALIGN - 1U)) != 0U) {
+               ERROR("ivc channel start not aligned: %lx\n", queue_base2);
+               return -EINVAL;
+       }
+
+       if ((frame_size & (IVC_ALIGN - 1U)) != 0U) {
+               ERROR("frame size not adequately aligned: %u\n",
+                               frame_size);
+               return -EINVAL;
+       }
+
+       if (queue_base1 < queue_base2) {
+               if ((queue_base1 + ((uint64_t)frame_size * nframes)) > queue_base2) {
+                       ERROR("queue regions overlap: %lx + %x, %x\n",
+                                       queue_base1, frame_size,
+                                       frame_size * nframes);
+                       return -EINVAL;
+               }
+       } else {
+               if ((queue_base2 + ((uint64_t)frame_size * nframes)) > queue_base1) {
+                       ERROR("queue regions overlap: %lx + %x, %x\n",
+                                       queue_base2, frame_size,
+                                       frame_size * nframes);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+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)
+{
+       int32_t result;
+
+       /* sanity check input params */
+       if ((ivc == NULL) || (notify == NULL)) {
+               return -EINVAL;
+       }
+
+       result = check_ivc_params(rx_base, tx_base, nframes, frame_size);
+       if (result != 0) {
+               return result;
+       }
+
+       /*
+        * All sizes that can be returned by communication functions should
+        * fit in a 32-bit integer.
+        */
+       if (frame_size > (1u << 31)) {
+               return -E2BIG;
+       }
+
+       ivc->rx_channel = (struct ivc_channel_header *)rx_base;
+       ivc->tx_channel = (struct ivc_channel_header *)tx_base;
+       ivc->notify = notify;
+       ivc->frame_size = frame_size;
+       ivc->nframes = nframes;
+       ivc->w_pos = 0U;
+       ivc->r_pos = 0U;
+
+       INFO("%s: done\n", __func__);
+
+       return 0;
+}
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
new file mode 100644 (file)
index 0000000..f34d6cf
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IVC_H
+#define IVC_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <utils_def.h>
+
+#define IVC_ALIGN              U(64)
+#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;
+       uint32_t nframes;
+       uint32_t frame_size;
+};
+
+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);
+size_t tegra_ivc_total_queue_size(size_t queue_size);
+size_t tegra_ivc_align(size_t size);
+int32_t tegra_ivc_channel_notified(struct ivc *ivc);
+void tegra_ivc_channel_reset(const struct ivc *ivc);
+int32_t tegra_ivc_write_advance(struct ivc *ivc);
+void *tegra_ivc_write_get_next_frame(const struct ivc *ivc);
+int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size);
+int32_t tegra_ivc_read_advance(struct ivc *ivc);
+void *tegra_ivc_read_get_next_frame(const struct ivc *ivc);
+int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read);
+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 */
diff --git a/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c b/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c
new file mode 100644 (file)
index 0000000..64e84ac
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <gpcdma.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stdbool.h>
+#include <tegra_def.h>
+#include <utils_def.h>
+
+/* DMA channel registers */
+#define DMA_CH_CSR                             U(0x0)
+#define DMA_CH_CSR_WEIGHT_SHIFT                        U(10)
+#define DMA_CH_CSR_XFER_MODE_SHIFT             U(21)
+#define DMA_CH_CSR_DMA_MODE_MEM2MEM            U(4)
+#define DMA_CH_CSR_DMA_MODE_FIXEDPATTERN       U(6)
+#define DMA_CH_CSR_IRQ_MASK_ENABLE             (U(1) << 15)
+#define DMA_CH_CSR_RUN_ONCE                    (U(1) << 27)
+#define DMA_CH_CSR_ENABLE                      (U(1) << 31)
+
+#define DMA_CH_STAT                            U(0x4)
+#define DMA_CH_STAT_BUSY                       (U(1) << 31)
+
+#define DMA_CH_SRC_PTR                         U(0xC)
+
+#define DMA_CH_DST_PTR                         U(0x10)
+
+#define DMA_CH_HI_ADR_PTR                      U(0x14)
+#define DMA_CH_HI_ADR_PTR_SRC_MASK             U(0xFF)
+#define DMA_CH_HI_ADR_PTR_DST_SHIFT            U(16)
+#define DMA_CH_HI_ADR_PTR_DST_MASK             U(0xFF)
+
+#define DMA_CH_MC_SEQ                          U(0x18)
+#define DMA_CH_MC_SEQ_REQ_CNT_SHIFT            U(25)
+#define DMA_CH_MC_SEQ_REQ_CNT_VAL              U(0x10)
+#define DMA_CH_MC_SEQ_BURST_SHIFT              U(23)
+#define DMA_CH_MC_SEQ_BURST_16_WORDS           U(0x3)
+
+#define DMA_CH_WORD_COUNT                      U(0x20)
+#define DMA_CH_FIXED_PATTERN                   U(0x34)
+#define DMA_CH_TZ                              U(0x38)
+#define DMA_CH_TZ_ACCESS_ENABLE                        U(0)
+#define DMA_CH_TZ_ACCESS_DISABLE               U(3)
+
+#define MAX_TRANSFER_SIZE                      (1U*1024U*1024U*1024U)  /* 1GB */
+#define GPCDMA_TIMEOUT_MS                      U(100)
+#define GPCDMA_RESET_BIT                       (U(1) << 1)
+
+static bool init_done;
+
+static void tegra_gpcdma_write32(uint32_t offset, uint32_t val)
+{
+       mmio_write_32(TEGRA_GPCDMA_BASE + offset, val);
+}
+
+static uint32_t tegra_gpcdma_read32(uint32_t offset)
+{
+       return mmio_read_32(TEGRA_GPCDMA_BASE + offset);
+}
+
+static void tegra_gpcdma_init(void)
+{
+       /* assert reset for DMA engine */
+       mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPCDMA_RST_SET_REG_OFFSET,
+                     GPCDMA_RESET_BIT);
+
+       udelay(2);
+
+       /* de-assert reset for DMA engine */
+       mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPCDMA_RST_CLR_REG_OFFSET,
+                     GPCDMA_RESET_BIT);
+}
+
+static void tegra_gpcdma_memcpy_priv(uint64_t dst_addr, uint64_t src_addr,
+                                    uint32_t num_bytes, uint32_t mode)
+{
+       uint32_t val, timeout = 0;
+       int32_t ret = 0;
+
+       /* sanity check byte count */
+       if ((num_bytes > MAX_TRANSFER_SIZE) || ((num_bytes & 0x3U) != U(0))) {
+               ret = -EINVAL;
+       }
+
+       /* initialise GPCDMA block */
+       if (!init_done) {
+               tegra_gpcdma_init();
+               init_done = true;
+       }
+
+       /* make sure channel isn't busy */
+       val = tegra_gpcdma_read32(DMA_CH_STAT);
+       if ((val & DMA_CH_STAT_BUSY) == DMA_CH_STAT_BUSY) {
+               ERROR("DMA channel is busy\n");
+               ret = -EBUSY;
+       }
+
+       if (ret == 0) {
+
+               /* disable any DMA transfers */
+               tegra_gpcdma_write32(DMA_CH_CSR, 0);
+
+               /* enable DMA access to TZDRAM */
+               tegra_gpcdma_write32(DMA_CH_TZ, DMA_CH_TZ_ACCESS_ENABLE);
+
+               /* configure MC sequencer */
+               val = (DMA_CH_MC_SEQ_REQ_CNT_VAL << DMA_CH_MC_SEQ_REQ_CNT_SHIFT) |
+                     (DMA_CH_MC_SEQ_BURST_16_WORDS << DMA_CH_MC_SEQ_BURST_SHIFT);
+               tegra_gpcdma_write32(DMA_CH_MC_SEQ, val);
+
+               /* reset fixed pattern */
+               tegra_gpcdma_write32(DMA_CH_FIXED_PATTERN, 0);
+
+               /* populate src and dst address registers */
+               tegra_gpcdma_write32(DMA_CH_SRC_PTR, (uint32_t)src_addr);
+               tegra_gpcdma_write32(DMA_CH_DST_PTR, (uint32_t)dst_addr);
+
+               val = (uint32_t)((src_addr >> 32) & DMA_CH_HI_ADR_PTR_SRC_MASK);
+               val |= (uint32_t)(((dst_addr >> 32) & DMA_CH_HI_ADR_PTR_DST_MASK) <<
+                       DMA_CH_HI_ADR_PTR_DST_SHIFT);
+               tegra_gpcdma_write32(DMA_CH_HI_ADR_PTR, val);
+
+               /* transfer size (in words) */
+               tegra_gpcdma_write32(DMA_CH_WORD_COUNT, ((num_bytes >> 2) - 1U));
+
+               /* populate value for CSR */
+               val = (mode << DMA_CH_CSR_XFER_MODE_SHIFT) |
+                     DMA_CH_CSR_RUN_ONCE | (U(1) << DMA_CH_CSR_WEIGHT_SHIFT) |
+                     DMA_CH_CSR_IRQ_MASK_ENABLE;
+               tegra_gpcdma_write32(DMA_CH_CSR, val);
+
+               /* enable transfer */
+               val = tegra_gpcdma_read32(DMA_CH_CSR);
+               val |= DMA_CH_CSR_ENABLE;
+               tegra_gpcdma_write32(DMA_CH_CSR, val);
+
+               /* wait till transfer completes */
+               do {
+
+                       /* read the status */
+                       val = tegra_gpcdma_read32(DMA_CH_STAT);
+                       if ((val & DMA_CH_STAT_BUSY) != DMA_CH_STAT_BUSY) {
+                               break;
+                       }
+
+                       mdelay(1);
+                       timeout++;
+
+               } while (timeout < GPCDMA_TIMEOUT_MS);
+
+               /* flag timeout error */
+               if (timeout == GPCDMA_TIMEOUT_MS) {
+                       ERROR("DMA transfer timed out\n");
+               }
+
+               dsbsy();
+
+               /* disable DMA access to TZDRAM */
+               tegra_gpcdma_write32(DMA_CH_TZ, DMA_CH_TZ_ACCESS_DISABLE);
+               isb();
+       }
+}
+
+/*******************************************************************************
+ * Memcpy using GPCDMA block (Mem2Mem copy)
+ ******************************************************************************/
+void tegra_gpcdma_memcpy(uint64_t dst_addr, uint64_t src_addr,
+                        uint32_t num_bytes)
+{
+       tegra_gpcdma_memcpy_priv(dst_addr, src_addr, num_bytes,
+                                DMA_CH_CSR_DMA_MODE_MEM2MEM);
+}
+
+/*******************************************************************************
+ * Memset using GPCDMA block (Fixed pattern write)
+ ******************************************************************************/
+void tegra_gpcdma_zeromem(uint64_t dst_addr, uint32_t num_bytes)
+{
+       tegra_gpcdma_memcpy_priv(dst_addr, 0, num_bytes,
+                                DMA_CH_CSR_DMA_MODE_FIXEDPATTERN);
+}
index 58f49d05f6e8f483241efe0c99f27a86e170c806..92fa273b54c66f1eed2d6accb2d7ddacef3afa86 100644 (file)
@@ -109,13 +109,16 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
 static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
                                 unsigned long long non_overlap_area_size)
 {
+       int ret;
+
        /*
         * Map the NS memory first, clean it and then unmap it.
         */
-       mmap_add_dynamic_region(non_overlap_area_start, /* PA */
+       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 */
+       assert(ret == 0);
 
        zeromem((void *)non_overlap_area_start, non_overlap_area_size);
        flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
@@ -206,3 +209,16 @@ void tegra_memctrl_disable_ahb_redirection(void)
        /* lock the aperture registers */
        tegra_mc_write_32(MC_IRAM_REG_CTRL, MC_DISABLE_IRAM_CFG_WRITES);
 }
+
+void tegra_memctrl_clear_pending_interrupts(void)
+{
+       uint32_t mcerr;
+
+       /* check if there are any pending interrupts */
+       mcerr = mmio_read_32(TEGRA_MC_BASE + MC_INTSTATUS);
+
+       if (mcerr != (uint32_t)0U) { /* should not see error here */
+               WARN("MC_INTSTATUS = 0x%x (should be zero)\n", mcerr);
+               mmio_write_32((TEGRA_MC_BASE + MC_INTSTATUS),  mcerr);
+       }
+}
index 55b9152232ca1258cdc5fc50a89e297069084658..a3ef5e13137640c321ed90e4a4f98aebbabd776b 100644 (file)
 static uint64_t video_mem_base;
 static uint64_t video_mem_size_mb;
 
-static void tegra_memctrl_reconfig_mss_clients(void)
-{
-#if ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS
-       uint32_t val, wdata_0, wdata_1;
-
-       /*
-        * Assert Memory Controller's HOTRESET_FLUSH_ENABLE signal for
-        * boot and strongly ordered MSS clients to flush existing memory
-        * traffic and stall future requests.
-        */
-       val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
-       assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL);
-
-       wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB |
-#if ENABLE_AFI_DEVICE
-                 MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB |
-#endif
-                 MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
-                 MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
-                 MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB;
-       tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
-
-       /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
-       do {
-               val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
-       } while ((val & wdata_0) != wdata_0);
-
-       /* Wait one more time due to SW WAR for known legacy issue */
-       do {
-               val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
-       } while ((val & wdata_0) != wdata_0);
-
-       val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
-       assert(val == MC_CLIENT_HOTRESET_CTRL1_RESET_VAL);
-
-       wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB |
-                 MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB |
-                 MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB |
-                 MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB |
-                 MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB |
-                 MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB |
-                 MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB |
-                 MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB |
-                 MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB |
-                 MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB;
-       tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
-
-       /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
-       do {
-               val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
-       } while ((val & wdata_1) != wdata_1);
-
-       /* Wait one more time due to SW WAR for known legacy issue */
-       do {
-               val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
-       } while ((val & wdata_1) != wdata_1);
-
-       /*
-        * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and
-        * strongly ordered MSS clients. ROC needs to be single point
-        * of control on overriding the memory type. So, remove TSA's
-        * memtype override.
-        */
-#if ENABLE_AFI_DEVICE
-       mc_set_tsa_passthrough(AFIW);
-#endif
-       mc_set_tsa_passthrough(HDAW);
-       mc_set_tsa_passthrough(SATAW);
-       mc_set_tsa_passthrough(XUSB_HOSTW);
-       mc_set_tsa_passthrough(XUSB_DEVW);
-       mc_set_tsa_passthrough(SDMMCWAB);
-       mc_set_tsa_passthrough(APEDMAW);
-       mc_set_tsa_passthrough(SESWR);
-       mc_set_tsa_passthrough(ETRW);
-       mc_set_tsa_passthrough(AXISW);
-       mc_set_tsa_passthrough(EQOSW);
-       mc_set_tsa_passthrough(UFSHCW);
-       mc_set_tsa_passthrough(BPMPDMAW);
-       mc_set_tsa_passthrough(AONDMAW);
-       mc_set_tsa_passthrough(SCEDMAW);
-
-       /*
-        * Change COH_PATH_OVERRIDE_SO_DEV from NO_OVERRIDE -> FORCE_COHERENT
-        * for boot and strongly ordered MSS clients. This steers all sodev
-        * transactions to ROC.
-        *
-        * Change AXID_OVERRIDE/AXID_OVERRIDE_SO_DEV only for some clients
-        * whose AXI IDs we know and trust.
-        */
-
-#if ENABLE_AFI_DEVICE
-       /* Match AFIW */
-       mc_set_forced_coherent_so_dev_cfg(AFIR);
-#endif
-
-       /*
-        * See bug 200131110 comment #35 - there are no normal requests
-        * and AWID for SO/DEV requests is hardcoded in RTL for a
-        * particular PCIE controller
-        */
-#if ENABLE_AFI_DEVICE
-       mc_set_forced_coherent_so_dev_cfg(AFIW);
-#endif
-       mc_set_forced_coherent_cfg(HDAR);
-       mc_set_forced_coherent_cfg(HDAW);
-       mc_set_forced_coherent_cfg(SATAR);
-       mc_set_forced_coherent_cfg(SATAW);
-       mc_set_forced_coherent_cfg(XUSB_HOSTR);
-       mc_set_forced_coherent_cfg(XUSB_HOSTW);
-       mc_set_forced_coherent_cfg(XUSB_DEVR);
-       mc_set_forced_coherent_cfg(XUSB_DEVW);
-       mc_set_forced_coherent_cfg(SDMMCRAB);
-       mc_set_forced_coherent_cfg(SDMMCWAB);
-
-       /* Match APEDMAW */
-       mc_set_forced_coherent_axid_so_dev_cfg(APEDMAR);
-
-       /*
-        * See bug 200131110 comment #35 - AWID for normal requests
-        * is 0x80 and AWID for SO/DEV requests is 0x01
-        */
-       mc_set_forced_coherent_axid_so_dev_cfg(APEDMAW);
-       mc_set_forced_coherent_cfg(SESRD);
-       mc_set_forced_coherent_cfg(SESWR);
-       mc_set_forced_coherent_cfg(ETRR);
-       mc_set_forced_coherent_cfg(ETRW);
-       mc_set_forced_coherent_cfg(AXISR);
-       mc_set_forced_coherent_cfg(AXISW);
-       mc_set_forced_coherent_cfg(EQOSR);
-       mc_set_forced_coherent_cfg(EQOSW);
-       mc_set_forced_coherent_cfg(UFSHCR);
-       mc_set_forced_coherent_cfg(UFSHCW);
-       mc_set_forced_coherent_cfg(BPMPDMAR);
-       mc_set_forced_coherent_cfg(BPMPDMAW);
-       mc_set_forced_coherent_cfg(AONDMAR);
-       mc_set_forced_coherent_cfg(AONDMAW);
-       mc_set_forced_coherent_cfg(SCEDMAR);
-       mc_set_forced_coherent_cfg(SCEDMAW);
-
-       /*
-        * At this point, ordering can occur at ROC. So, remove PCFIFO's
-        * control over ordering requests.
-        *
-        * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for
-        * boot and strongly ordered MSS clients
-        */
-       val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL &
-#if ENABLE_AFI_DEVICE
-               mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) &
-#endif
-               mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) &
-               mc_set_pcfifo_unordered_boot_so_mss(1, SATAW);
-       tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val);
-
-       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, XUSB_DEVW);
-       tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, val);
-
-       val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL &
-               mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB);
-       tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, val);
-
-       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, AXISW) &
-               mc_set_pcfifo_unordered_boot_so_mss(4, EQOSW) &
-               mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
-               mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
-               mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
-               mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
-       tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val);
-
-       val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
-               mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW);
-       tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val);
-
-       /*
-        * At this point, ordering can occur at ROC. SMMU need not
-        * reorder any requests.
-        *
-        * Change SMMU_*_ORDERED_CLIENT from ORDERED -> UNORDERED
-        * for boot and strongly ordered MSS clients
-        */
-       val = MC_SMMU_CLIENT_CONFIG1_RESET_VAL &
-#if ENABLE_AFI_DEVICE
-               mc_set_smmu_unordered_boot_so_mss(1, AFIW) &
-#endif
-               mc_set_smmu_unordered_boot_so_mss(1, HDAW) &
-               mc_set_smmu_unordered_boot_so_mss(1, SATAW);
-       tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG1, val);
-
-       val = MC_SMMU_CLIENT_CONFIG2_RESET_VAL &
-               mc_set_smmu_unordered_boot_so_mss(2, XUSB_HOSTW) &
-               mc_set_smmu_unordered_boot_so_mss(2, XUSB_DEVW);
-       tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG2, val);
-
-       val = MC_SMMU_CLIENT_CONFIG3_RESET_VAL &
-               mc_set_smmu_unordered_boot_so_mss(3, SDMMCWAB);
-       tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG3, val);
-
-       val = MC_SMMU_CLIENT_CONFIG4_RESET_VAL &
-               mc_set_smmu_unordered_boot_so_mss(4, SESWR) &
-               mc_set_smmu_unordered_boot_so_mss(4, ETRW) &
-               mc_set_smmu_unordered_boot_so_mss(4, AXISW) &
-               mc_set_smmu_unordered_boot_so_mss(4, EQOSW) &
-               mc_set_smmu_unordered_boot_so_mss(4, UFSHCW) &
-               mc_set_smmu_unordered_boot_so_mss(4, BPMPDMAW) &
-               mc_set_smmu_unordered_boot_so_mss(4, AONDMAW) &
-               mc_set_smmu_unordered_boot_so_mss(4, SCEDMAW);
-       tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG4, val);
-
-       val = MC_SMMU_CLIENT_CONFIG5_RESET_VAL &
-               mc_set_smmu_unordered_boot_so_mss(5, APEDMAW);
-       tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG5, val);
-
-       /*
-        * Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS
-        * clients to allow memory traffic from all clients to start passing
-        * through ROC
-        */
-       val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
-       assert(val == wdata_0);
-
-       wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL;
-       tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
-
-       val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
-       assert(val == wdata_1);
-
-       wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL;
-       tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
-
-#endif
-}
+/*
+ * 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
 
-static void tegra_memctrl_set_overrides(void)
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
 {
-       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);
-       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.
-        */
-       if ((tegra_chipid_is_t186()) &&
-           (!tegra_platform_is_silicon() ||
-           (tegra_platform_is_silicon() && (tegra_get_chipid_minor() == 1)))) {
-
-               /*
-                * GPU and NVENC settings for Tegra186 simulation and
-                * Silicon rev. A01
-                */
-               val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR);
-               val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
-               tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR,
-                       val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
-
-               val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2);
-               val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
-               tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2,
-                       val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
-
-               val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR);
-               val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
-               tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR,
-                       val | MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID);
-
-       } else {
-
-               /*
-                * 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);
-                       val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
-                       tegra_mc_write_32(mc_txn_override_cfgs[i].offset,
-                               val | mc_txn_override_cfgs[i].cgid_tag);
-               }
-       }
+       ; /* do nothing */
 }
 
 /*
@@ -324,17 +46,16 @@ void tegra_memctrl_setup(void)
        uint32_t num_streamid_override_regs;
        const mc_streamid_security_cfg_t *mc_streamid_sec_cfgs;
        uint32_t num_streamid_sec_cfgs;
-       tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
+       const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
        uint32_t i;
 
        INFO("Tegra Memory Controller (v2)\n");
 
-#if ENABLE_SMMU_DEVICE
        /* Program the SMMU pagesize */
        tegra_smmu_init();
-#endif
+
        /* Get the settings from the platform */
-       assert(plat_mc_settings);
+       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;
@@ -375,10 +96,14 @@ void tegra_memctrl_setup(void)
         * boots with MSS having all control, but ROC provides a performance
         * boost as compared to MSS.
         */
-       tegra_memctrl_reconfig_mss_clients();
+       if (plat_mc_settings->reconfig_mss_clients != NULL) {
+               plat_mc_settings->reconfig_mss_clients();
+       }
 
        /* Program overrides for MC transactions */
-       tegra_memctrl_set_overrides();
+       if (plat_mc_settings->set_txn_overrides != NULL) {
+               plat_mc_settings->set_txn_overrides();
+       }
 }
 
 /*
@@ -386,19 +111,27 @@ 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.
         */
-       tegra_memctrl_reconfig_mss_clients();
+       if (plat_mc_settings->reconfig_mss_clients != NULL) {
+               plat_mc_settings->reconfig_mss_clients();
+       }
 
        /* Program overrides for MC transactions */
-       tegra_memctrl_set_overrides();
+       if (plat_mc_settings->set_txn_overrides != NULL) {
+               plat_mc_settings->set_txn_overrides();
+       }
 
        /* video memory carveout region */
-       if (video_mem_base) {
+       if (video_mem_base != 0ULL) {
                tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO,
                                  (uint32_t)video_mem_base);
                tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
@@ -422,34 +155,9 @@ void tegra_memctrl_restore_settings(void)
 void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
 {
        /*
-        * Setup the Memory controller to allow only secure accesses to
-        * the TZDRAM carveout
+        * Perform platform specific steps.
         */
-       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_CFG1_0, size_in_bytes >> 20);
-
-       /*
-        * When TZ encryption enabled,
-        * We need setup TZDRAM before CPU to access TZ Carveout,
-        * otherwise CPU will fetch non-decrypted data.
-        * So save TZDRAM setting for retore by SC7 resume FW.
-        */
-
-       mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_LO,
-                                       tegra_mc_read_32(MC_SECURITY_CFG0_0));
-       mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_HI,
-                                       tegra_mc_read_32(MC_SECURITY_CFG3_0));
-       mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV54_HI,
-                                       tegra_mc_read_32(MC_SECURITY_CFG1_0));
-
-       /*
-        * MCE propagates the security configuration values across the
-        * CCPLEX.
-        */
-       mce_update_gsc_tzdram();
+       plat_memctrl_tzdram_setup(phys_base, size_in_bytes);
 }
 
 /*
@@ -471,12 +179,21 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
         * Reset the access configuration registers to restrict access
         * to the TZRAM aperture
         */
-       for (index = MC_TZRAM_CLIENT_ACCESS_CFG0;
+       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);
        }
 
+       /*
+        * 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);
+       }
+
        /*
         * Set the TZRAM base. TZRAM base must be 4k aligned, at least.
         */
@@ -502,8 +219,11 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
         * at all.
         */
        val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG);
-       val &= ~MC_GSC_ENABLE_TZ_LOCK_BIT;
+       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;
+       }
        tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val);
 
        /*
@@ -577,18 +297,21 @@ static void tegra_unlock_videomem_nonoverlap(void)
 static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
                                 unsigned long long non_overlap_area_size)
 {
+       int ret;
+
        /*
         * Map the NS memory first, clean it and then unmap it.
         */
-       mmap_add_dynamic_region(non_overlap_area_start, /* PA */
+       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 */
+       assert(ret == 0);
 
        zero_normalmem((void *)non_overlap_area_start, non_overlap_area_size);
        flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
 
-       mmap_remove_dynamic_region(non_overlap_area_start,
+       (void)mmap_remove_dynamic_region(non_overlap_area_start,
                non_overlap_area_size);
 }
 
@@ -635,17 +358,19 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
         */
        INFO("Cleaning previous Video Memory Carveout\n");
 
-       if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) {
+       if ((phys_base > vmem_end_old) || (video_mem_base > vmem_end_new)) {
                tegra_clear_videomem(video_mem_base,
-                                    (uint64_t)video_mem_size_mb << 20);
+                                    (uint32_t)video_mem_size_mb << 20U);
        } else {
                if (video_mem_base < phys_base) {
                        non_overlap_area_size = phys_base - video_mem_base;
-                       tegra_clear_videomem(video_mem_base, non_overlap_area_size);
+                       tegra_clear_videomem(video_mem_base,
+                                       (uint32_t)non_overlap_area_size);
                }
                if (vmem_end_old > vmem_end_new) {
                        non_overlap_area_size = vmem_end_old - vmem_end_new;
-                       tegra_clear_videomem(vmem_end_new, non_overlap_area_size);
+                       tegra_clear_videomem(vmem_end_new,
+                                       (uint32_t)non_overlap_area_size);
                }
        }
 
@@ -677,3 +402,8 @@ void tegra_memctrl_disable_ahb_redirection(void)
 {
        ; /* do nothing */
 }
+
+void tegra_memctrl_clear_pending_interrupts(void)
+{
+       ; /* do nothing */
+}
index 610f32f1eb56561312bec02b5b2c467ff46758f7..8c1b899f77ed4ba66cb8a1e956d0590d3929038b 100644 (file)
@@ -19,47 +19,55 @@ extern void memcpy16(void *dest, const void *src, unsigned int length);
 
 /* SMMU IDs currently supported by the driver */
 enum {
-       TEGRA_SMMU0,
+       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)
-               return mmio_read_32(TEGRA_SMMU0_BASE + off);
+       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)
-               return mmio_read_32(TEGRA_SMMU1_BASE + off);
+       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)
-               return mmio_read_32(TEGRA_SMMU2_BASE + off);
+       if (smmu_id == TEGRA_SMMU2) {
+               ret = mmio_read_32(TEGRA_SMMU2_BASE + (uint64_t)off);
+       }
 #endif
 
-       return 0;
+       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 + off, val);
+       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 + off, val);
+       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 + off, val);
+       if (smmu_id == TEGRA_SMMU2) {
+               mmio_write_32(TEGRA_SMMU2_BASE + (uint64_t)off, val);
+       }
 #endif
 }
 
@@ -70,52 +78,55 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr)
 {
        uint32_t i, num_entries = 0;
        smmu_regs_t *smmu_ctx_regs;
-       plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+       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) ? 16 : 12;
-       cb_size = (2 << pgshift) * \
-       (1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1));
+       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);
+       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].val != 0xFFFFFFFFU) {
+       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)
+       if (num_entries != smmu_ctx_regs[0].val) {
+               ERROR("SMMU context size mismatch!");
                panic();
+       }
 
        /* save SMMU register values */
-       for (i = 1; i < num_entries; i++)
+       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 */
-       memcpy16((void *)(uintptr_t)smmu_ctx_addr, (void *)smmu_ctx_regs,
-                (sizeof(smmu_regs_t) * num_entries));
+       (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 + SECURE_SCRATCH_RSV11_LO,
+       mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_LO,
                (uint32_t)smmu_ctx_addr);
-       mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_HI,
+       mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_HI,
                (uint32_t)(smmu_ctx_addr >> 32));
 }
 
@@ -128,17 +139,18 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr)
 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 = 0; smmu_id < NUM_SMMU_DEVICES; smmu_id++) {
+       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 &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+               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 &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+               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 */
@@ -147,19 +159,19 @@ void tegra_smmu_init(void)
                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 &= ~SMMU_CBn_ACTLR_CPRE_BIT;
+                       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 |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+               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 |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+               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/drivers/spe/shared_console.S b/plat/nvidia/tegra/common/drivers/spe/shared_console.S
new file mode 100644 (file)
index 0000000..a9f0334
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <asm_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)
+
+       /*
+        * This file contains a driver implementation to make use of the
+        * real console implementation provided by the SPE firmware running
+        * SoCs after Tegra186.
+        *
+        * This console is shared by multiple components and the SPE firmware
+        * finally displays everything on the UART port.
+        */
+
+       .globl  console_core_init
+       .globl  console_core_putc
+       .globl  console_core_getc
+       .globl  console_core_flush
+
+       /* -----------------------------------------------
+        * int console_core_init(uintptr_t base_addr,
+        * unsigned int uart_clk, unsigned int baud_rate)
+        * Function to initialize the console without a
+        * C Runtime to print debug information. This
+        * function will be accessed by console_init and
+        * crash reporting.
+        * In: x0 - console base address
+        *     w1 - Uart clock in Hz
+        *     w2 - Baud rate
+        * Out: return 1 on success else 0 on error
+        * Clobber list : x1, x2
+        * -----------------------------------------------
+        */
+func console_core_init
+       /* Check the input base address */
+       cbz     x0, core_init_fail
+       mov     w0, #1
+       ret
+core_init_fail:
+       mov     w0, wzr
+       ret
+endfunc console_core_init
+
+       /* --------------------------------------------------------
+        * int console_core_putc(int c, uintptr_t base_addr)
+        * 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
+        *      x1 - console base address
+        * Out : return -1 on error else return character.
+        * Clobber list : x2
+        * --------------------------------------------------------
+        */
+func console_core_putc
+       /* Check the input parameter */
+       cbz     x1, putc_error
+
+       /* wait until spe is ready */
+1:     ldr     w2, [x1]
+       and     w2, w2, #CONSOLE_IS_BUSY
+       cbnz    w2, 1b
+
+       /* spe is ready */
+       mov     w2, w0
+       and     w2, w2, #0xFF
+       mov     w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT))
+       orr     w2, w2, w3
+       str     w2, [x1]
+
+       ret
+putc_error:
+       mov     w0, #-1
+       ret
+endfunc console_core_putc
+
+       /* ---------------------------------------------
+        * int console_core_getc(uintptr_t base_addr)
+        * Function to get a character from the console.
+        * It returns the character grabbed on success
+        * or -1 on error.
+        * In : x0 - console base address
+        * Clobber list : x0, x1
+        * ---------------------------------------------
+        */
+func console_core_getc
+       mov     w0, #-1
+       ret
+endfunc console_core_getc
+
+       /* ---------------------------------------------
+        * int 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.
+        * Clobber list : x0, x1
+        * ---------------------------------------------
+        */
+func console_core_flush
+       cbz     x0, flush_error
+
+       /* flush console */
+       mov     w1, #CONSOLE_WRITE
+       str     w1, [x0]
+       mov     w0, #0
+       ret
+flush_error:
+       mov     w0, #-1
+       ret
+endfunc console_core_flush
diff --git a/plat/nvidia/tegra/common/lib/debug/profiler.c b/plat/nvidia/tegra/common/lib/debug/profiler.c
new file mode 100644 (file)
index 0000000..d4c3f95
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*******************************************************************************
+ * The profiler stores the timestamps captured during cold boot to the shared
+ * memory for the non-secure world. The non-secure world driver parses the
+ * shared memory block and writes the contents to a file on the device, which
+ * can be later extracted for analysis.
+ *
+ * Profiler memory map
+ *
+ * TOP     ---------------------------      ---
+ *            Trusted OS timestamps         3KB
+ *         ---------------------------      ---
+ *         Trusted Firmware timestamps      1KB
+ * BASE    ---------------------------      ---
+ *
+ ******************************************************************************/
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <mmio.h>
+#include <profiler.h>
+#include <stdbool.h>
+#include <string.h>
+#include <utils_def.h>
+#include <xlat_tables_v2.h>
+
+static uint64_t shmem_base_addr;
+
+#define MAX_PROFILER_RECORDS   U(16)
+#define TAG_LEN_BYTES          U(56)
+
+/*******************************************************************************
+ * Profiler entry format
+ ******************************************************************************/
+typedef struct {
+       /* text explaining the timestamp location in code */
+       uint8_t tag[TAG_LEN_BYTES];
+       /* timestamp value */
+       uint64_t timestamp;
+} profiler_rec_t;
+
+static profiler_rec_t *head, *cur, *tail;
+static uint32_t tmr;
+static bool is_shmem_buf_mapped;
+
+/*******************************************************************************
+ * Initialise the profiling library
+ ******************************************************************************/
+void boot_profiler_init(uint64_t shmem_base, uint32_t tmr_base)
+{
+       uint64_t shmem_end_base;
+
+       assert(shmem_base != ULL(0));
+       assert(tmr_base != U(0));
+
+       /* store the buffer address */
+       shmem_base_addr = shmem_base;
+
+       /* calculate the base address of the last record */
+       shmem_end_base = shmem_base + (sizeof(profiler_rec_t) *
+                        (MAX_PROFILER_RECORDS - U(1)));
+
+       /* calculate the head, tail and cur values */
+       head = (profiler_rec_t *)shmem_base;
+       tail = (profiler_rec_t *)shmem_end_base;
+       cur = head;
+
+       /* timer used to get the current timestamp */
+       tmr = tmr_base;
+}
+
+/*******************************************************************************
+ * Add tag and timestamp to profiler
+ ******************************************************************************/
+void boot_profiler_add_record(const char *str)
+{
+       unsigned int len;
+
+       /* calculate the length of the tag */
+       if (((unsigned int)strlen(str) + U(1)) > TAG_LEN_BYTES) {
+               len = TAG_LEN_BYTES;
+       } else {
+               len = (unsigned int)strlen(str) + U(1);
+       }
+
+       if (head != NULL) {
+
+               /*
+                * The profiler runs with/without MMU enabled. Check
+                * if MMU is enabled and memmap the shmem buffer, in
+                * case it is.
+                */
+               if ((!is_shmem_buf_mapped) &&
+                   ((read_sctlr_el3() & SCTLR_M_BIT) != U(0))) {
+
+                       (void)mmap_add_dynamic_region(shmem_base_addr,
+                                       shmem_base_addr,
+                                       PROFILER_SIZE_BYTES,
+                                       (MT_NS | MT_RW | MT_EXECUTE_NEVER));
+
+                       is_shmem_buf_mapped = true;
+               }
+
+               /* write the tag and timestamp to buffer */
+               (void)snprintf((char *)cur->tag, len, "%s", str);
+               cur->timestamp = mmio_read_32(tmr);
+
+               /* start from head if we reached the end */
+               if (cur == tail) {
+                       cur = head;
+               } else {
+                       cur++;
+               }
+       }
+}
+
+/*******************************************************************************
+ * Deinint the profiler
+ ******************************************************************************/
+void boot_profiler_deinit(void)
+{
+       if (shmem_base_addr != ULL(0)) {
+
+               /* clean up resources */
+               cur = NULL;
+               head = NULL;
+               tail = NULL;
+
+               /* flush the shmem for it to be visible to the NS world */
+               flush_dcache_range(shmem_base_addr, PROFILER_SIZE_BYTES);
+
+               /* unmap the shmem buffer */
+               if (is_shmem_buf_mapped) {
+                       (void)mmap_remove_dynamic_region(shmem_base_addr,
+                                       PROFILER_SIZE_BYTES);
+               }
+       }
+}
index b49665027165dfabb52e34cb3bbe6ed89786a071..908e4f2dd4d51a6101996bdbff3982ebb5b3a488 100644 (file)
@@ -26,7 +26,9 @@
 #include <plat/common/platform.h>
 
 #include <memctrl.h>
+#include <profiler.h>
 #include <tegra_def.h>
+#include <tegra_platform.h>
 #include <tegra_private.h>
 
 /* length of Trusty's input parameters (in bytes) */
@@ -39,20 +41,19 @@ extern void memcpy16(void *dest, const void *src, unsigned int length);
  * of trusted SRAM
  ******************************************************************************/
 
-IMPORT_SYM(unsigned long, __RW_START__,                BL31_RW_START);
-IMPORT_SYM(unsigned long, __RW_END__,          BL31_RW_END);
-IMPORT_SYM(unsigned long, __RODATA_START__,    BL31_RODATA_BASE);
-IMPORT_SYM(unsigned long, __RODATA_END__,      BL31_RODATA_END);
-IMPORT_SYM(unsigned long, __TEXT_START__,      TEXT_START);
-IMPORT_SYM(unsigned long, __TEXT_END__,                TEXT_END);
+IMPORT_SYM(uint64_t, __RW_START__,     BL31_RW_START);
+IMPORT_SYM(uint64_t, __RW_END__,       BL31_RW_END);
+IMPORT_SYM(uint64_t, __RODATA_START__, BL31_RODATA_BASE);
+IMPORT_SYM(uint64_t, __RODATA_END__,   BL31_RODATA_END);
+IMPORT_SYM(uint64_t, __TEXT_START__,   TEXT_START);
+IMPORT_SYM(uint64_t, __TEXT_END__,     TEXT_END);
 
 extern uint64_t tegra_bl31_phys_base;
 extern uint64_t tegra_console_base;
 
-
 static entry_point_info_t bl33_image_ep_info, bl32_image_ep_info;
 static plat_params_from_bl2_t plat_bl31_params_from_bl2 = {
-       .tzdram_size = (uint64_t)TZDRAM_SIZE
+       .tzdram_size = TZDRAM_SIZE
 };
 static unsigned long bl32_mem_size;
 static unsigned long bl32_boot_params;
@@ -69,6 +70,7 @@ extern uint64_t ns_image_entrypoint;
 #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)
 {
@@ -85,6 +87,11 @@ 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
@@ -92,14 +99,16 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
  ******************************************************************************/
 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
 {
-       if (type == NON_SECURE)
-               return &bl33_image_ep_info;
+       entry_point_info_t *ep =  NULL;
 
        /* return BL32 entry point info if it is valid */
-       if (type == SECURE && bl32_image_ep_info.pc)
-               return &bl32_image_ep_info;
+       if (type == NON_SECURE) {
+               ep = &bl33_image_ep_info;
+       } else if ((type == SECURE) && (bl32_image_ep_info.pc != 0U)) {
+               ep = &bl32_image_ep_info;
+       }
 
-       return NULL;
+       return ep;
 }
 
 /*******************************************************************************
@@ -122,6 +131,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
        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;
+       uint32_t console_clock;
+       int32_t ret;
 
        /*
         * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
@@ -129,20 +140,22 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
         * might use custom ways to get arguments, so provide handlers which
         * they can override.
         */
-       if (arg_from_bl2 == NULL)
+       if (arg_from_bl2 == NULL) {
                arg_from_bl2 = plat_get_bl31_params();
-       if (plat_params == NULL)
+       }
+       if (plat_params == NULL) {
                plat_params = plat_get_bl31_plat_params();
+       }
 
        /*
         * Copy BL3-3, BL3-2 entry point information.
         * They are stored in Secure RAM, in BL2's address space.
         */
-       assert(arg_from_bl2);
-       assert(arg_from_bl2->bl33_ep_info);
+       assert(arg_from_bl2 != NULL);
+       assert(arg_from_bl2->bl33_ep_info != NULL);
        bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
 
-       if (arg_from_bl2->bl32_ep_info) {
+       if (arg_from_bl2->bl32_ep_info != NULL) {
                bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
                bl32_mem_size = arg_from_bl2->bl32_ep_info->args.arg0;
                bl32_boot_params = arg_from_bl2->bl32_ep_info->args.arg2;
@@ -151,18 +164,29 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
        /*
         * Parse platform specific parameters - TZDRAM aperture base and size
         */
-       assert(plat_params);
+       assert(plat_params != NULL);
        plat_bl31_params_from_bl2.tzdram_base = plat_params->tzdram_base;
        plat_bl31_params_from_bl2.tzdram_size = plat_params->tzdram_size;
        plat_bl31_params_from_bl2.uart_id = plat_params->uart_id;
+       plat_bl31_params_from_bl2.l2_ecc_parity_prot_dis = plat_params->l2_ecc_parity_prot_dis;
 
        /*
         * It is very important that we run either from TZDRAM or TZSRAM base.
         * Add an explicit check here.
         */
-       if ((plat_bl31_params_from_bl2.tzdram_base != BL31_BASE) &&
-           (TEGRA_TZRAM_BASE != BL31_BASE))
+       if ((plat_bl31_params_from_bl2.tzdram_base != (uint64_t)BL31_BASE) &&
+           (TEGRA_TZRAM_BASE != BL31_BASE)) {
                panic();
+       }
+
+       /*
+        * Reference clock used by the FPGAs is a lot slower.
+        */
+       if (tegra_platform_is_fpga()) {
+               console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
+       } else {
+               console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
+       }
 
        /*
         * Get the base address of the UART controller to be used for the
@@ -170,31 +194,60 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
         */
        tegra_console_base = plat_get_console_from_id(plat_params->uart_id);
 
-       if (tegra_console_base != (uint64_t)0) {
+       if (tegra_console_base != 0U) {
                /*
                 * Configure the UART port to be used as the console
                 */
-               console_init(tegra_console_base, TEGRA_BOOT_UART_CLK_IN_HZ,
-                       TEGRA_CONSOLE_BAUDRATE);
+               (void)console_init(tegra_console_base, console_clock,
+                            TEGRA_CONSOLE_BAUDRATE);
        }
 
+       /*
+        * The previous bootloader passes the base address of the shared memory
+        * location to store the boot profiler logs. Sanity check the
+        * address and initilise 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) {
+
+                       /* 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);
+               }
+       }
+
+       /*
+        * Add timestamp for platform early setup entry.
+        */
+       boot_profiler_add_record("[TF] early setup entry");
+
        /*
         * Initialize delay timer
         */
        tegra_delay_timer_init();
 
+       /* Early platform setup for Tegra SoCs */
+       plat_early_platform_setup();
+
        /*
         * Do initial security configuration to allow DRAM/device access.
         */
        tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base,
-                       plat_bl31_params_from_bl2.tzdram_size);
+                       (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) {
+       if (arg_from_bl2->bl32_image_info != NULL) {
 
                bl32_img_info = *arg_from_bl2->bl32_image_info;
 
@@ -211,11 +264,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
                assert(bl32_image_ep_info.pc < tzdram_end);
 
                /* relocate BL32 */
-               if (bl32_start >= tzdram_end || bl32_end <= tzdram_start) {
+               if ((bl32_start >= tzdram_end) || (bl32_end <= tzdram_start)) {
 
                        INFO("Relocate BL32 to TZDRAM\n");
 
-                       memcpy16((void *)(uintptr_t)bl32_image_ep_info.pc,
+                       (void)memcpy16((void *)(uintptr_t)bl32_image_ep_info.pc,
                                 (void *)(uintptr_t)bl32_start,
                                 bl32_img_info.image_size);
 
@@ -225,8 +278,10 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
                }
        }
 
-       /* Early platform setup for Tegra SoCs */
-       plat_early_platform_setup();
+       /*
+        * Add timestamp for platform early setup exit.
+        */
+       boot_profiler_add_record("[TF] early setup exit");
 
        INFO("BL3-1: Boot CPU: %s Processor [%lx]\n",
             (((read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK)
@@ -239,6 +294,14 @@ void plat_trusty_set_boot_args(aapcs64_params_t *args)
        args->arg0 = bl32_mem_size;
        args->arg1 = bl32_boot_params;
        args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+
+       /* update EKS size */
+       if (args->arg4 != 0U) {
+               args->arg2 = args->arg4;
+       }
+
+       /* Profiler Carveout Base */
+       args->arg3 = args->arg5;
 }
 #endif
 
@@ -247,7 +310,10 @@ void plat_trusty_set_boot_args(aapcs64_params_t *args)
  ******************************************************************************/
 void bl31_platform_setup(void)
 {
-       uint32_t tmp_reg;
+       /*
+        * Add timestamp for platform setup entry.
+        */
+       boot_profiler_add_record("[TF] plat setup entry");
 
        /* Initialize the gic cpu and distributor interfaces */
        plat_gic_setup();
@@ -268,9 +334,17 @@ void bl31_platform_setup(void)
         */
        tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
 
-       /* Set the next EL to be AArch64 */
-       tmp_reg = SCR_RES1_BITS | SCR_RW_BIT;
-       write_scr(tmp_reg);
+       /*
+        * Late setup handler to allow platforms to performs additional
+        * functionality.
+        * This handler gets called with MMU enabled.
+        */
+       plat_late_platform_setup();
+
+       /*
+        * Add timestamp for platform setup exit.
+        */
+       boot_profiler_add_record("[TF] plat setup exit");
 
        INFO("BL3-1: Tegra platform setup complete\n");
 }
@@ -280,6 +354,15 @@ 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
+        */
+       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
@@ -290,6 +373,12 @@ void bl31_plat_runtime_setup(void)
         * disabled before we jump to the non-secure world.
         */
        tegra_memctrl_disable_ahb_redirection();
+
+       /*
+        * Add final timestamp before exiting BL31.
+        */
+       boot_profiler_add_record("[TF] bl31 exit");
+       boot_profiler_deinit();
 }
 
 /*******************************************************************************
@@ -298,17 +387,22 @@ void bl31_plat_runtime_setup(void)
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
-       unsigned long rw_start = BL31_RW_START;
-       unsigned long rw_size = BL31_RW_END - BL31_RW_START;
-       unsigned long rodata_start = BL31_RODATA_BASE;
-       unsigned long rodata_size = BL31_RODATA_END - BL31_RODATA_BASE;
-       unsigned long code_base = TEXT_START;
-       unsigned long code_size = TEXT_END - TEXT_START;
+       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;
        const mmap_region_t *plat_mmio_map = NULL;
 #if USE_COHERENT_MEM
-       unsigned long coh_start, coh_size;
+       uint32_t coh_start, coh_size;
 #endif
-       plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+       const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+
+       /*
+        * Add timestamp for arch setup entry.
+        */
+       boot_profiler_add_record("[TF] arch setup entry");
 
        /* add memory regions */
        mmap_add_region(rw_start, rw_start,
@@ -335,21 +429,22 @@ void bl31_plat_arch_setup(void)
 
        mmap_add_region(coh_start, coh_start,
                        coh_size,
-                       MT_DEVICE | MT_RW | MT_SECURE);
+                       (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE);
 #endif
 
        /* map on-chip free running uS timer */
-       mmap_add_region(page_align((uint64_t)TEGRA_TMRUS_BASE, 0),
-                       page_align((uint64_t)TEGRA_TMRUS_BASE, 0),
-                       (uint64_t)TEGRA_TMRUS_SIZE,
-                       MT_DEVICE | MT_RO | MT_SECURE);
+       mmap_add_region(page_align(TEGRA_TMRUS_BASE, 0),
+                       page_align(TEGRA_TMRUS_BASE, 0),
+                       TEGRA_TMRUS_SIZE,
+                       (uint8_t)MT_DEVICE | (uint8_t)MT_RO | (uint8_t)MT_SECURE);
 
        /* add MMIO space */
        plat_mmio_map = plat_get_mmio_map();
-       if (plat_mmio_map)
+       if (plat_mmio_map != NULL) {
                mmap_add(plat_mmio_map);
-       else
+       } else {
                WARN("MMIO map not available\n");
+       }
 
        /* set up translation tables */
        init_xlat_tables();
@@ -357,33 +452,41 @@ void bl31_plat_arch_setup(void)
        /* enable the MMU */
        enable_mmu_el3(0);
 
+       /*
+        * Add timestamp for arch setup exit.
+        */
+       boot_profiler_add_record("[TF] arch setup exit");
+
        INFO("BL3-1: Tegra: MMU enabled\n");
 }
 
 /*******************************************************************************
  * Check if the given NS DRAM range is valid
  ******************************************************************************/
-int bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
+int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
 {
-       uint64_t end = base + size_in_bytes;
+       uint64_t end = base + size_in_bytes - U(1);
+       int32_t ret = 0;
 
        /*
         * Check if the NS DRAM address is valid
         */
-       if ((base < TEGRA_DRAM_BASE) || (end > TEGRA_DRAM_END)) {
+       if ((base < TEGRA_DRAM_BASE) || (base >= TEGRA_DRAM_END) ||
+           (end > TEGRA_DRAM_END)) {
+
                ERROR("NS address is out-of-bounds!\n");
-               return -EFAULT;
+               ret = -EFAULT;
        }
 
        /*
         * TZDRAM aperture contains the BL31 and BL32 images, so we need
         * to check if the NS DRAM range overlaps the TZDRAM aperture.
         */
-       if ((base < TZDRAM_END) && (end > tegra_bl31_phys_base)) {
+       if ((base < (uint64_t)TZDRAM_END) && (end > tegra_bl31_phys_base)) {
                ERROR("NS address overlaps TZDRAM!\n");
-               return -ENOTSUP;
+               ret = -ENOTSUP;
        }
 
        /* valid NS address */
-       return 0;
+       return ret;
 }
index 6a0854ee25333af9c48d4044efb3ef87ac92f9cd..d9eec4d37c0701510fd4d87be10710a062584142 100644 (file)
@@ -5,6 +5,7 @@
 #
 
 PLAT_INCLUDES          :=      -Iplat/nvidia/tegra/include/drivers \
+                               -Iplat/nvidia/tegra/include/lib \
                                -Iplat/nvidia/tegra/include \
                                -Iplat/nvidia/tegra/include/${TARGET_SOC}
 
@@ -21,10 +22,10 @@ TEGRA_GICv2_SOURCES :=      drivers/arm/gic/common/gic_common.c             \
 
 BL31_SOURCES           +=      drivers/console/aarch64/console.S               \
                                drivers/delay_timer/delay_timer.c               \
-                               drivers/ti/uart/aarch64/16550_console.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                  \
index 0b663cef429fd67e5abb0eba73bcad5f061d7fa4..cab2e5ec583ead2c9f70a675d230e1f13ba25aa8 100644 (file)
@@ -41,6 +41,11 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id,
        uint32_t cpu = plat_my_core_pos();
        uint32_t irq;
 
+       (void)id;
+       (void)flags;
+       (void)handle;
+       (void)cookie;
+
        bakery_lock_get(&tegra_fiq_lock);
 
        /*
@@ -60,7 +65,7 @@ static uint64_t tegra_fiq_interrupt_handler(uint32_t id,
         * Set the new ELR to continue execution in the NS world using the
         * FIQ handler registered earlier.
         */
-       assert(ns_fiq_handler_addr);
+       assert(ns_fiq_handler_addr != 0ULL);
        write_ctx_reg((el3state_ctx), (uint32_t)(CTX_ELR_EL3), (ns_fiq_handler_addr));
 
        /*
index 10edf9229c423c14aa7ac0808019488765639cd8..c1e42095935d7285c333c2891125ee1e8efe63d8 100644 (file)
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, 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 <tegra_def.h>
 #include <tegra_platform.h>
 #include <tegra_private.h>
  * Tegra platforms
  ******************************************************************************/
 typedef enum tegra_platform {
-       TEGRA_PLATFORM_SILICON = 0,
+       TEGRA_PLATFORM_SILICON = 0U,
        TEGRA_PLATFORM_QT,
        TEGRA_PLATFORM_FPGA,
        TEGRA_PLATFORM_EMULATION,
+       TEGRA_PLATFORM_LINSIM,
+       TEGRA_PLATFORM_UNIT_FPGA,
+       TEGRA_PLATFORM_VIRT_DEV_KIT,
        TEGRA_PLATFORM_MAX,
 } tegra_platform_t;
 
 /*******************************************************************************
  * Tegra macros defining all the SoC minor versions
  ******************************************************************************/
-#define TEGRA_MINOR_QT                 0
-#define TEGRA_MINOR_FPGA               1
-#define TEGRA_MINOR_EMULATION_MIN      2
-#define TEGRA_MINOR_EMULATION_MAX      10
+#define TEGRA_MINOR_QT                 U(0)
+#define TEGRA_MINOR_FPGA               U(1)
+#define TEGRA_MINOR_ASIM_QT            U(2)
+#define TEGRA_MINOR_ASIM_LINSIM                U(3)
+#define TEGRA_MINOR_DSIM_ASIM_LINSIM   U(4)
+#define TEGRA_MINOR_UNIT_FPGA          U(5)
+#define TEGRA_MINOR_VIRT_DEV_KIT       U(6)
 
 /*******************************************************************************
- * Tegra major, minor version helper macros
+ * Tegra macros defining all the SoC pre_si_platform
  ******************************************************************************/
-#define MAJOR_VERSION_SHIFT            0x4
-#define MAJOR_VERSION_MASK             0xF
-#define MINOR_VERSION_SHIFT            0x10
-#define MINOR_VERSION_MASK             0xF
-#define CHIP_ID_SHIFT                  8
-#define CHIP_ID_MASK                   0xFF
-
-/*******************************************************************************
- * Tegra chip ID values
- ******************************************************************************/
-typedef enum tegra_chipid {
-       TEGRA_CHIPID_TEGRA13 = 0x13,
-       TEGRA_CHIPID_TEGRA21 = 0x21,
-       TEGRA_CHIPID_TEGRA18 = 0x18,
-} tegra_chipid_t;
+#define TEGRA_PRE_SI_QT                        U(1)
+#define TEGRA_PRE_SI_FPGA              U(2)
+#define TEGRA_PRE_SI_UNIT_FPGA         U(3)
+#define TEGRA_PRE_SI_ASIM_QT           U(4)
+#define TEGRA_PRE_SI_ASIM_LINSIM       U(5)
+#define TEGRA_PRE_SI_DSIM_ASIM_LINSIM  U(6)
+#define TEGRA_PRE_SI_VDK               U(8)
 
 /*
  * Read the chip ID value
@@ -73,25 +71,38 @@ uint32_t tegra_get_chipid_minor(void)
        return (tegra_get_chipid() >> MINOR_VERSION_SHIFT) & MINOR_VERSION_MASK;
 }
 
-uint8_t tegra_chipid_is_t132(void)
+/*
+ * Read the chip's pre_si_platform valus from the chip ID value
+ */
+static uint32_t tegra_get_chipid_pre_si_platform(void)
 {
-       uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
+       return (tegra_get_chipid() >> PRE_SI_PLATFORM_SHIFT) & PRE_SI_PLATFORM_MASK;
+}
+
+bool tegra_chipid_is_t132(void)
+{
+       uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK);
 
        return (chip_id == TEGRA_CHIPID_TEGRA13);
 }
 
-uint8_t tegra_chipid_is_t210(void)
+bool tegra_chipid_is_t186(void)
 {
        uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
 
-       return (chip_id == TEGRA_CHIPID_TEGRA21);
+       return (chip_id == TEGRA_CHIPID_TEGRA18);
 }
 
-uint8_t tegra_chipid_is_t186(void)
+bool tegra_chipid_is_t210(void)
 {
        uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
 
-       return (chip_id == TEGRA_CHIPID_TEGRA18);
+       return (chip_id == TEGRA_CHIPID_TEGRA21);
+}
+
+bool tegra_chipid_is_t210_b01(void)
+{
+       return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2U));
 }
 
 /*
@@ -99,54 +110,152 @@ uint8_t tegra_chipid_is_t186(void)
  */
 static tegra_platform_t tegra_get_platform(void)
 {
-       uint32_t major = tegra_get_chipid_major();
-       uint32_t minor = tegra_get_chipid_minor();
+       uint32_t major, minor, pre_si_platform;
+       tegra_platform_t ret;
 
-       /* Actual silicon platforms have a non-zero major version */
-       if (major > 0)
-               return TEGRA_PLATFORM_SILICON;
+       /* get the major/minor chip ID values */
+       major = tegra_get_chipid_major();
+       minor = tegra_get_chipid_minor();
+       pre_si_platform = tegra_get_chipid_pre_si_platform();
 
-       /*
-        * The minor version number is used by simulation platforms
-        */
+       if (major == 0U) {
+               /*
+                * The minor version number is used by simulation platforms
+                */
+               switch (minor) {
+               /*
+                * Cadence's QuickTurn emulation system is a Solaris-based
+                * chip emulation system
+                */
+               case TEGRA_MINOR_QT:
+               case TEGRA_MINOR_ASIM_QT:
+                       ret = TEGRA_PLATFORM_QT;
+                       break;
 
-       /*
-        * Cadence's QuickTurn emulation system is a Solaris-based
-        * chip emulation system
-        */
-       if (minor == TEGRA_MINOR_QT)
-               return TEGRA_PLATFORM_QT;
+               /*
+                * FPGAs are used during early software/hardware development
+                */
+               case TEGRA_MINOR_FPGA:
+                       ret = TEGRA_PLATFORM_FPGA;
+                       break;
+               /*
+                * Linsim is a reconfigurable, clock-driven, mixed RTL/cmodel
+                * simulation framework.
+                */
+               case TEGRA_MINOR_ASIM_LINSIM:
+               case TEGRA_MINOR_DSIM_ASIM_LINSIM:
+                       ret = TEGRA_PLATFORM_LINSIM;
+                       break;
 
-       /*
-        * FPGAs are used during early software/hardware development
-        */
-       if (minor == TEGRA_MINOR_FPGA)
-               return TEGRA_PLATFORM_FPGA;
+               /*
+                * Unit FPGAs run the actual hardware block IP on the FPGA with
+                * the other parts of the system using Linsim.
+                */
+               case TEGRA_MINOR_UNIT_FPGA:
+                       ret = TEGRA_PLATFORM_UNIT_FPGA;
+                       break;
+               /*
+                * The Virtualizer Development Kit (VDK) is the standard chip
+                * development from Synopsis.
+                */
+               case TEGRA_MINOR_VIRT_DEV_KIT:
+                       ret = TEGRA_PLATFORM_VIRT_DEV_KIT;
+                       break;
 
-       /* Minor version reserved for other emulation platforms */
-       if ((minor > TEGRA_MINOR_FPGA) && (minor <= TEGRA_MINOR_EMULATION_MAX))
-               return TEGRA_PLATFORM_EMULATION;
+               default:
+                       ret = TEGRA_PLATFORM_MAX;
+                       break;
+               }
 
-       /* unsupported platform */
-       return TEGRA_PLATFORM_MAX;
+       } else if (pre_si_platform > 0U) {
+
+               switch (pre_si_platform) {
+               /*
+                * Cadence's QuickTurn emulation system is a Solaris-based
+                * chip emulation system
+                */
+               case TEGRA_PRE_SI_QT:
+               case TEGRA_PRE_SI_ASIM_QT:
+                       ret = TEGRA_PLATFORM_QT;
+                       break;
+
+               /*
+                * FPGAs are used during early software/hardware development
+                */
+               case TEGRA_PRE_SI_FPGA:
+                       ret = TEGRA_PLATFORM_FPGA;
+                       break;
+               /*
+                * Linsim is a reconfigurable, clock-driven, mixed RTL/cmodel
+                * simulation framework.
+                */
+               case TEGRA_PRE_SI_ASIM_LINSIM:
+               case TEGRA_PRE_SI_DSIM_ASIM_LINSIM:
+                       ret = TEGRA_PLATFORM_LINSIM;
+                       break;
+
+               /*
+                * Unit FPGAs run the actual hardware block IP on the FPGA with
+                * the other parts of the system using Linsim.
+                */
+               case TEGRA_PRE_SI_UNIT_FPGA:
+                       ret = TEGRA_PLATFORM_UNIT_FPGA;
+                       break;
+               /*
+                * The Virtualizer Development Kit (VDK) is the standard chip
+                * development from Synopsis.
+                */
+               case TEGRA_PRE_SI_VDK:
+                       ret = TEGRA_PLATFORM_VIRT_DEV_KIT;
+                       break;
+
+               default:
+                       ret = TEGRA_PLATFORM_MAX;
+                       break;
+               }
+
+       } else {
+               /* Actual silicon platforms have a non-zero major version */
+               ret = TEGRA_PLATFORM_SILICON;
+       }
+
+       return ret;
+}
+
+bool tegra_platform_is_silicon(void)
+{
+       return ((tegra_get_platform() == TEGRA_PLATFORM_SILICON) ? true : false);
 }
 
-uint8_t tegra_platform_is_silicon(void)
+bool tegra_platform_is_qt(void)
 {
-       return (tegra_get_platform() == TEGRA_PLATFORM_SILICON);
+       return ((tegra_get_platform() == TEGRA_PLATFORM_QT) ? true : false);
 }
 
-uint8_t tegra_platform_is_qt(void)
+bool tegra_platform_is_linsim(void)
 {
-       return (tegra_get_platform() == TEGRA_PLATFORM_QT);
+       tegra_platform_t plat = tegra_get_platform();
+
+       return (((plat == TEGRA_PLATFORM_LINSIM) ||
+              (plat == TEGRA_PLATFORM_UNIT_FPGA)) ? true : false);
 }
 
-uint8_t tegra_platform_is_fpga(void)
+bool tegra_platform_is_fpga(void)
 {
-       return (tegra_get_platform() == TEGRA_PLATFORM_FPGA);
+       return ((tegra_get_platform() == TEGRA_PLATFORM_FPGA) ? true : false);
 }
 
-uint8_t tegra_platform_is_emulation(void)
+bool tegra_platform_is_emulation(void)
 {
        return (tegra_get_platform() == TEGRA_PLATFORM_EMULATION);
 }
+
+bool tegra_platform_is_unit_fpga(void)
+{
+       return ((tegra_get_platform() == TEGRA_PLATFORM_UNIT_FPGA) ? true : false);
+}
+
+bool tegra_platform_is_virt_dev_kit(void)
+{
+       return ((tegra_get_platform() == TEGRA_PLATFORM_VIRT_DEV_KIT) ? true : false);
+}
index 8361ddd3d35602fcefadd3e07c78f67a75b464a8..2805272712c0c8f642f7f5b076196a090b432864 100644 (file)
@@ -21,6 +21,7 @@
 #include <memctrl.h>
 #include <pmc.h>
 #include <tegra_def.h>
+#include <tegra_platform.h>
 #include <tegra_private.h>
 
 extern uint64_t tegra_bl31_phys_base;
@@ -49,37 +50,42 @@ uint8_t tegra_fake_system_suspend;
 #pragma weak tegra_soc_prepare_system_off
 #pragma weak tegra_soc_get_target_pwr_state
 
-int tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+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_suspend(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
+       (void)target_state;
        return PSCI_E_NOT_SUPPORTED;
 }
 
-int tegra_soc_pwr_domain_on(u_register_t mpidr)
+int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
 {
+       (void)mpidr;
        return PSCI_E_SUCCESS;
 }
 
-int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
+       (void)target_state;
        return PSCI_E_SUCCESS;
 }
 
-int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
+       (void)target_state;
        return PSCI_E_SUCCESS;
 }
 
-int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
 {
+       (void)target_state;
        return PSCI_E_SUCCESS;
 }
 
-int tegra_soc_prepare_system_reset(void)
+int32_t tegra_soc_prepare_system_reset(void)
 {
        return PSCI_E_SUCCESS;
 }
@@ -90,19 +96,26 @@ __dead2 void tegra_soc_prepare_system_off(void)
        panic();
 }
 
-plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
+plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
                                             const plat_local_state_t *states,
-                                            unsigned int ncpu)
+                                            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);
+       assert(ncpu != 0U);
 
        do {
-               temp = *states++;
-               if ((temp < target))
+               temp = *local_state;
+               if ((temp < target)) {
                        target = temp;
-       } while (--ncpu);
+               }
+               --num_cpu;
+               local_state++;
+       } while (num_cpu != 0U);
 
        return target;
 }
@@ -116,8 +129,9 @@ plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
 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++)
+       for (uint32_t i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) {
                req_state->pwr_domain_state[i] = PSTATE_ID_SOC_POWERDN;
+       }
 }
 
 /*******************************************************************************
@@ -125,6 +139,8 @@ void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
  ******************************************************************************/
 void tegra_cpu_standby(plat_local_state_t cpu_state)
 {
+       (void)cpu_state;
+
        /*
         * Enter standby state
         * dsb is good practice before using wfi to enter low power states
@@ -137,7 +153,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.
  ******************************************************************************/
-int tegra_pwr_domain_on(u_register_t mpidr)
+int32_t tegra_pwr_domain_on(u_register_t mpidr)
 {
        return tegra_soc_pwr_domain_on(mpidr);
 }
@@ -148,7 +164,7 @@ int tegra_pwr_domain_on(u_register_t mpidr)
  ******************************************************************************/
 void tegra_pwr_domain_off(const psci_power_state_t *target_state)
 {
-       tegra_soc_pwr_domain_off(target_state);
+       (void)tegra_soc_pwr_domain_off(target_state);
 }
 
 /*******************************************************************************
@@ -168,12 +184,13 @@ void tegra_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_sta
  ******************************************************************************/
 void tegra_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
-       tegra_soc_pwr_domain_suspend(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)
-               console_uninit();
+                       PSTATE_ID_SOC_POWERDN) {
+               (void)console_uninit();
+       }
 
        /* disable GICC */
        tegra_gic_cpuif_deactivate();
@@ -190,7 +207,7 @@ __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t
        uint64_t rmr_el3 = 0;
 
        /* call the chip's power down handler */
-       tegra_soc_pwr_domain_power_down_wfi(target_state);
+       (void)tegra_soc_pwr_domain_power_down_wfi(target_state);
 
        /*
         * If we are in fake system suspend mode, ensure we start doing
@@ -221,7 +238,8 @@ __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t
  ******************************************************************************/
 void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
-       plat_params_from_bl2_t *plat_params;
+       const plat_params_from_bl2_t *plat_params;
+       uint32_t console_clock;
 
        /*
         * Initialize the GIC cpu and distributor interfaces
@@ -234,10 +252,19 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
        if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
                        PSTATE_ID_SOC_POWERDN) {
 
+               /*
+                * Reference clock used by the FPGAs is a lot slower.
+                */
+               if (tegra_platform_is_fpga()) {
+                       console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
+               } else {
+                       console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
+               }
+
                /* Initialize the runtime console */
-               if (tegra_console_base != (uint64_t)0) {
-                       console_init(tegra_console_base, TEGRA_BOOT_UART_CLK_IN_HZ,
-                               TEGRA_CONSOLE_BAUDRATE);
+               if (tegra_console_base != 0ULL) {
+                       (void)console_init(tegra_console_base, console_clock,
+                                    TEGRA_CONSOLE_BAUDRATE);
                }
 
                /*
@@ -251,7 +278,7 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
                 */
                plat_params = bl31_get_plat_params();
                tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
-                       plat_params->tzdram_size);
+                       (uint32_t)plat_params->tzdram_size);
 
                /*
                 * Set up the TZRAM memory aperture to allow only secure world
@@ -263,7 +290,7 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
        /*
         * Reset hardware settings.
         */
-       tegra_soc_pwr_domain_on_finish(target_state);
+       (void)tegra_soc_pwr_domain_on_finish(target_state);
 }
 
 /*******************************************************************************
@@ -294,7 +321,7 @@ __dead2 void tegra_system_reset(void)
        INFO("Restarting system...\n");
 
        /* per-SoC system reset handler */
-       tegra_soc_prepare_system_reset();
+       (void)tegra_soc_prepare_system_reset();
 
        /*
         * Program the PMC in order to restart the system.
@@ -305,10 +332,10 @@ __dead2 void tegra_system_reset(void)
 /*******************************************************************************
  * Handler called to check the validity of the power state parameter.
  ******************************************************************************/
-int32_t tegra_validate_power_state(unsigned int power_state,
+int32_t tegra_validate_power_state(uint32_t power_state,
                                   psci_power_state_t *req_state)
 {
-       assert(req_state);
+       assert(req_state != NULL);
 
        return tegra_soc_validate_power_state(power_state, req_state);
 }
@@ -316,16 +343,19 @@ int32_t tegra_validate_power_state(unsigned int power_state,
 /*******************************************************************************
  * Platform handler called to check the validity of the non secure entrypoint.
  ******************************************************************************/
-int tegra_validate_ns_entrypoint(uintptr_t entrypoint)
+int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
 {
+       int32_t ret = PSCI_E_INVALID_ADDRESS;
+
        /*
         * Check if the non secure entrypoint lies within the non
         * secure DRAM.
         */
-       if ((entrypoint >= TEGRA_DRAM_BASE) && (entrypoint <= TEGRA_DRAM_END))
-               return PSCI_E_SUCCESS;
+       if ((entrypoint >= TEGRA_DRAM_BASE) && (entrypoint <= TEGRA_DRAM_END)) {
+               ret = PSCI_E_SUCCESS;
+       }
 
-       return PSCI_E_INVALID_ADDRESS;
+       return ret;
 }
 
 /*******************************************************************************
@@ -365,7 +395,7 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
        /*
         * Reset hardware settings.
         */
-       tegra_soc_pwr_domain_on_finish(&target_state);
+       (void)tegra_soc_pwr_domain_on_finish(&target_state);
 
        /*
         * Initialize PSCI ops struct
index e50d12faf89de0165c7a858fd73bdf4c0e9dbfdc..4955b2fc17d6d8b2be6f25c306db5c053e58482c 100644 (file)
  ******************************************************************************/
 extern uint8_t tegra_fake_system_suspend;
 
-
 /*******************************************************************************
  * SoC specific SiP handler
  ******************************************************************************/
 #pragma weak plat_sip_handler
-int plat_sip_handler(uint32_t smc_fid,
+int32_t plat_sip_handler(uint32_t smc_fid,
                     uint64_t x1,
                     uint64_t x2,
                     uint64_t x3,
                     uint64_t x4,
-                    void *cookie,
+                    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;
 }
 
@@ -60,113 +69,113 @@ uintptr_t tegra_sip_handler(uint32_t smc_fid,
                            void *handle,
                            u_register_t flags)
 {
-       uint32_t regval;
-       int err;
+       uint32_t regval, local_x2_32 = (uint32_t)x2;
+       int32_t err;
 
        /* Check if this is a SoC specific SiP */
        err = plat_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
-       if (err == 0)
-               SMC_RET1(handle, (uint64_t)err);
-
-       switch (smc_fid) {
-
-       case TEGRA_SIP_NEW_VIDEOMEM_REGION:
-
-               /* clean up the high bits */
-               x2 = (uint32_t)x2;
-
-               /*
-                * Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
-                * or falls outside of the valid DRAM range
-                */
-               err = bl31_check_ns_address(x1, x2);
-               if (err)
-                       SMC_RET1(handle, err);
-
-               /*
-                * Check if Video Memory is aligned to 1MB.
-                */
-               if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) {
-                       ERROR("Unaligned Video Memory base address!\n");
-                       SMC_RET1(handle, -ENOTSUP);
-               }
-
-               /*
-                * The GPU is the user of the Video Memory region. In order to
-                * transition to the new memory region smoothly, we program the
-                * new base/size ONLY if the GPU is in reset mode.
-                */
-               regval = mmio_read_32(TEGRA_CAR_RESET_BASE +
-                                     TEGRA_GPU_RESET_REG_OFFSET);
-               if ((regval & GPU_RESET_BIT) == 0U) {
-                       ERROR("GPU not in reset! Video Memory setup failed\n");
-                       SMC_RET1(handle, -ENOTSUP);
-               }
-
-               /* new video memory carveout settings */
-               tegra_memctrl_videomem_setup(x1, x2);
+       if (err == 0) {
 
-               SMC_RET1(handle, 0);
-               break;
+               SMC_RET1(handle, (uint64_t)err);
 
-       /*
-        * The NS world registers the address of its handler to be
-        * used for processing the FIQ. This is normally used by the
-        * NS FIQ debugger driver to detect system hangs by programming
-        * a watchdog timer to fire a FIQ interrupt.
-        */
-       case TEGRA_SIP_FIQ_NS_ENTRYPOINT:
+       } else {
+
+               switch (smc_fid) {
+
+               case TEGRA_SIP_NEW_VIDEOMEM_REGION:
+
+                       /*
+                        * Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
+                        * or falls outside of the valid DRAM range
+                       */
+                       err = bl31_check_ns_address(x1, local_x2_32);
+                       if (err != 0) {
+                               SMC_RET1(handle, (uint64_t)err);
+                       }
+
+                       /*
+                        * Check if Video Memory is aligned to 1MB.
+                        */
+                       if (((x1 & 0xFFFFFU) != 0U) || ((local_x2_32 & 0xFFFFFU) != 0U)) {
+                               ERROR("Unaligned Video Memory base address!\n");
+                               SMC_RET1(handle, (uint64_t)-ENOTSUP);
+                       }
+
+                       /*
+                        * The GPU is the user of the Video Memory region. In order to
+                        * transition to the new memory region smoothly, we program the
+                        * new base/size ONLY if the GPU is in reset mode.
+                        */
+                       regval = mmio_read_32(TEGRA_CAR_RESET_BASE +
+                                             TEGRA_GPU_RESET_REG_OFFSET);
+                       if ((regval & GPU_RESET_BIT) == 0U) {
+                               ERROR("GPU not in reset! Video Memory setup failed\n");
+                               SMC_RET1(handle, (uint64_t)-ENOTSUP);
+                       }
+
+                       /* new video memory carveout settings */
+                       tegra_memctrl_videomem_setup(x1, local_x2_32);
 
-               if (!x1)
-                       SMC_RET1(handle, SMC_UNK);
+                       SMC_RET1(handle, 0);
 
                /*
-                * TODO: Check if x1 contains a valid DRAM address
+                * The NS world registers the address of its handler to be
+                * used for processing the FIQ. This is normally used by the
+                * NS FIQ debugger driver to detect system hangs by programming
+                * a watchdog timer to fire a FIQ interrupt.
                 */
+               case TEGRA_SIP_FIQ_NS_ENTRYPOINT:
 
-               /* store the NS world's entrypoint */
-               tegra_fiq_set_ns_entrypoint(x1);
-
-               SMC_RET1(handle, 0);
-               break;
+                       if (x1 == 0U) {
+                               SMC_RET1(handle, SMC_UNK);
+                       }
 
-       /*
-        * The NS world's FIQ handler issues this SMC to get the NS EL1/EL0
-        * CPU context when the FIQ interrupt was triggered. This allows the
-        * NS world to understand the CPU state when the watchdog interrupt
-        * triggered.
-        */
-       case TEGRA_SIP_FIQ_NS_GET_CONTEXT:
+                       /*
+                        * TODO: Check if x1 contains a valid DRAM address
+                        */
 
-               /* retrieve context registers when FIQ triggered */
-               tegra_fiq_get_intr_context();
+                       /* store the NS world's entrypoint */
+                       tegra_fiq_set_ns_entrypoint(x1);
 
-               SMC_RET0(handle);
-               break;
-
-       case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND:
-               /*
-                * System suspend fake mode is set if we are on VDK and we make
-                * a debug SIP call. This mode ensures that we excercise debug
-                * path instead of the regular code path to suit the pre-silicon
-                * platform needs. These include replacing the call to WFI by
-                * a warm reset request.
-                */
-               if (tegra_platform_is_emulation() != 0U) {
-
-                       tegra_fake_system_suspend = 1;
                        SMC_RET1(handle, 0);
-               }
 
                /*
-                * We return to the external world as if this SIP is not
-                * implemented in case, we are not running on VDK.
+                * The NS world's FIQ handler issues this SMC to get the NS EL1/EL0
+                * CPU context when the FIQ interrupt was triggered. This allows the
+                * NS world to understand the CPU state when the watchdog interrupt
+                * triggered.
                 */
-               break;
-
-       default:
-               ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
-               break;
+               case TEGRA_SIP_FIQ_NS_GET_CONTEXT:
+
+                       /* retrieve context registers when FIQ triggered */
+                       (void)tegra_fiq_get_intr_context();
+
+                       SMC_RET0(handle);
+
+               case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND:
+                       /*
+                        * System suspend fake mode is set if we are on VDK and we make
+                        * a debug SIP call. This mode ensures that we excercise debug
+                        * path instead of the regular code path to suit the pre-silicon
+                        * platform needs. These include replacing the call to WFI by
+                        * a warm reset request.
+                        */
+                       if (tegra_platform_is_virt_dev_kit() != false) {
+
+                               tegra_fake_system_suspend = 1;
+                               SMC_RET1(handle, 0);
+                       }
+
+                       /*
+                        * We return to the external world as if this SIP is not
+                        * implemented in case, we are not running on VDK.
+                        */
+                       break;
+
+               default:
+                       ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+                       break;
+               }
        }
 
        SMC_RET1(handle, SMC_UNK);
@@ -176,9 +185,9 @@ uintptr_t tegra_sip_handler(uint32_t smc_fid,
 DECLARE_RT_SVC(
        tegra_sip_fast,
 
-       OEN_SIP_START,
-       OEN_SIP_END,
-       SMC_TYPE_FAST,
-       NULL,
-       tegra_sip_handler
+       (OEN_SIP_START),
+       (OEN_SIP_END),
+       (SMC_TYPE_FAST),
+       (NULL),
+       (tegra_sip_handler)
 );
index 893f28ff24137b6f5b8a434ab54301b485f6ecc3..14631a776c7079f8d949218214f259b3d3aaa70d 100644 (file)
@@ -7,41 +7,42 @@
 #include <platform_def.h>
 
 #include <arch.h>
+#include <platform.h>
 #include <lib/psci/psci.h>
 
-extern const unsigned char tegra_power_domain_tree_desc[];
 #pragma weak plat_core_pos_by_mpidr
 
-/*******************************************************************************
- * This function returns the Tegra default topology tree information.
- ******************************************************************************/
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
-       return tegra_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)
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
 {
-       unsigned int cluster_id, cpu_id;
+       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;
 
-       cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-       cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & 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 >= PLATFORM_CLUSTER_COUNT)
-               return PSCI_E_NOT_PRESENT;
+       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 >= PLATFORM_MAX_CPUS_PER_CLUSTER)
-               return PSCI_E_NOT_PRESENT;
+       if (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER) {
+               result = PSCI_E_NOT_PRESENT;
+       }
 
-       return (cpu_id + (cluster_id * 4));
+       return result;
 }
diff --git a/plat/nvidia/tegra/include/drivers/bpmp.h b/plat/nvidia/tegra/include/drivers/bpmp.h
new file mode 100644 (file)
index 0000000..03da6f6
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BPMP_H
+#define BPMP_H
+
+#include <stdint.h>
+
+/* macro to enable clock to the Atomics block */
+#define CAR_ENABLE_ATOMICS     (1U << 16)
+
+/* command to get the channel base addresses from bpmp */
+#define ATOMIC_CMD_GET         4U
+
+/* Hardware IRQ # used to signal bpmp of an incoming command */
+#define INT_SHR_SEM_OUTBOX_FULL        6U
+
+/* macros to decode the bpmp's state */
+#define CH_MASK(ch)            ((uint32_t)0x3 << ((ch) * 2U))
+#define MA_FREE(ch)            ((uint32_t)0x2 << ((ch) * 2U))
+#define MA_ACKD(ch)            ((uint32_t)0x3 << ((ch) * 2U))
+
+/* response from bpmp to indicate it has powered up */
+#define SIGN_OF_LIFE           0xAAAAAAAAU
+
+/* flags to indicate bpmp driver's state */
+#define BPMP_INIT_COMPLETE     0xBEEFF00DU
+#define BPMP_INIT_PENDING      0xDEADBEEFU
+
+/* requests serviced by the bpmp */
+#define MRQ_PING               0
+#define MRQ_QUERY_TAG          1
+#define MRQ_DO_IDLE            2
+#define MRQ_TOLERATE_IDLE      3
+#define MRQ_MODULE_LOAD                4
+#define MRQ_MODULE_UNLOAD      5
+#define MRQ_SWITCH_CLUSTER     6
+#define MRQ_TRACE_MODIFY       7
+#define MRQ_WRITE_TRACE                8
+#define MRQ_THREADED_PING      9
+#define MRQ_CPUIDLE_USAGE      10
+#define MRQ_MODULE_MAIL                11
+#define MRQ_SCX_ENABLE         12
+#define MRQ_BPMPIDLE_USAGE     14
+#define MRQ_HEAP_USAGE         15
+#define MRQ_SCLK_SKIP_SET_RATE 16
+#define MRQ_ENABLE_SUSPEND     17
+#define MRQ_PASR_MASK          18
+#define MRQ_DEBUGFS            19
+#define MRQ_THERMAL            27
+
+/* Tegra PM states as known to BPMP */
+#define TEGRA_PM_CC1           9
+#define TEGRA_PM_CC4           12
+#define TEGRA_PM_CC6           14
+#define TEGRA_PM_CC7           15
+#define TEGRA_PM_SC1           17
+#define TEGRA_PM_SC2           18
+#define TEGRA_PM_SC3           19
+#define TEGRA_PM_SC4           20
+#define TEGRA_PM_SC7           23
+
+/* flag to indicate if entry into a CCx power state is allowed */
+#define BPMP_CCx_ALLOWED       0U
+
+/* number of communication channels to interact with the bpmp */
+#define NR_CHANNELS            4U
+
+/* flag to ask bpmp to acknowledge command packet */
+#define NO_ACK                 (0U << 0U)
+#define DO_ACK                 (1U << 0U)
+
+/* size of the command/response data */
+#define MSG_DATA_MAX_SZ                120U
+
+/**
+ * command/response packet to/from the bpmp
+ *
+ * command
+ * -------
+ * code: MRQ_* command
+ * flags: DO_ACK or NO_ACK
+ * data:
+ *     [0] = cpu #
+ *     [1] = cluster power state (TEGRA_PM_CCx)
+ *     [2] = system power state (TEGRA_PM_SCx)
+ *
+ * response
+ * ---------
+ * code: error code
+ * flags: not used
+ * data:
+ *     [0-3] = response value
+ */
+typedef struct mb_data {
+       int32_t code;
+       uint32_t flags;
+       uint8_t data[MSG_DATA_MAX_SZ];
+} mb_data_t;
+
+/**
+ * Function to initialise the interface with the bpmp
+ */
+int tegra_bpmp_init(void);
+
+/**
+ * Handler to send a MRQ_* command to the bpmp
+ */
+int32_t tegra_bpmp_send_receive_atomic(int mrq, const void *ob_data, int ob_sz,
+               void *ib_data, int ib_sz);
+
+#endif /* BPMP_H */
diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
new file mode 100644 (file)
index 0000000..9304150
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __BPMP_IPC_H__
+#define __BPMP_IPC_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <utils_def.h>
+
+/**
+ * Currently supported reset identifiers
+ */
+#define TEGRA_RESET_ID_XUSB_PADCTL     U(114)
+#define TEGRA_RESET_ID_GPCDMA          U(70)
+
+/**
+ * Function to initialise the IPC with the bpmp
+ */
+int32_t tegra_bpmp_ipc_init(void);
+
+/**
+ * Handler to reset a module
+ */
+int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id);
+
+#endif /* __BPMP_IPC_H__ */
diff --git a/plat/nvidia/tegra/include/drivers/gpcdma.h b/plat/nvidia/tegra/include/drivers/gpcdma.h
new file mode 100644 (file)
index 0000000..fb5486a
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __GPCDMA_H__
+#define __GPCDMA_H__
+
+#include <stdint.h>
+
+void tegra_gpcdma_memcpy(uint64_t dst_addr, uint64_t src_addr,
+                           uint32_t num_bytes);
+void tegra_gpcdma_zeromem(uint64_t dst_addr, uint32_t num_bytes);
+
+#endif /* __GPCDMA_H__ */
index 17427cbec959f20d78e570fde0ba46b4a06a7930..d5ef60d0ca3393d43bdeaab6f4455eccd67c5b42 100644 (file)
@@ -13,5 +13,6 @@ 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);
 
 #endif /* MEMCTRL_H */
index 957ff54c12fe9a28c69537c1135af7bd8db09620..f5b0ed4d32923b1c26e57679ffd6f6183b5591f4 100644 (file)
 
 #ifndef __ASSEMBLY__
 
+#include <mmio.h>
 #include <stdint.h>
 
-/*******************************************************************************
- * StreamID to indicate no SMMU translations (requests to be steered on the
- * SMMU bypass path)
- ******************************************************************************/
-#define MC_STREAM_ID_MAX                       0x7F
-
-/*******************************************************************************
- * Stream ID Override Config registers
- ******************************************************************************/
-#define MC_STREAMID_OVERRIDE_CFG_PTCR          0x000
-#define MC_STREAMID_OVERRIDE_CFG_AFIR          0x070
-#define MC_STREAMID_OVERRIDE_CFG_HDAR          0x0A8
-#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR    0x0B0
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD      0x0E0
-#define MC_STREAMID_OVERRIDE_CFG_SATAR         0x0F8
-#define MC_STREAMID_OVERRIDE_CFG_MPCORER       0x138
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR      0x158
-#define MC_STREAMID_OVERRIDE_CFG_AFIW          0x188
-#define MC_STREAMID_OVERRIDE_CFG_HDAW          0x1A8
-#define MC_STREAMID_OVERRIDE_CFG_MPCOREW       0x1C8
-#define MC_STREAMID_OVERRIDE_CFG_SATAW         0x1E8
-#define MC_STREAMID_OVERRIDE_CFG_ISPRA         0x220
-#define MC_STREAMID_OVERRIDE_CFG_ISPWA         0x230
-#define MC_STREAMID_OVERRIDE_CFG_ISPWB         0x238
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR    0x250
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW    0x258
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR     0x260
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW     0x268
-#define MC_STREAMID_OVERRIDE_CFG_TSECSRD       0x2A0
-#define MC_STREAMID_OVERRIDE_CFG_TSECSWR       0x2A8
-#define MC_STREAMID_OVERRIDE_CFG_GPUSRD                0x2C0
-#define MC_STREAMID_OVERRIDE_CFG_GPUSWR                0x2C8
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA       0x300
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAA      0x308
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCR                0x310
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB      0x318
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA       0x320
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAA      0x328
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCW                0x330
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB      0x338
-#define MC_STREAMID_OVERRIDE_CFG_VICSRD                0x360
-#define MC_STREAMID_OVERRIDE_CFG_VICSWR                0x368
-#define MC_STREAMID_OVERRIDE_CFG_VIW           0x390
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD      0x3C0
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR      0x3C8
-#define MC_STREAMID_OVERRIDE_CFG_APER          0x3D0
-#define MC_STREAMID_OVERRIDE_CFG_APEW          0x3D8
-#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD      0x3F0
-#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR      0x3F8
-#define MC_STREAMID_OVERRIDE_CFG_SESRD         0x400
-#define MC_STREAMID_OVERRIDE_CFG_SESWR         0x408
-#define MC_STREAMID_OVERRIDE_CFG_ETRR          0x420
-#define MC_STREAMID_OVERRIDE_CFG_ETRW          0x428
-#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB      0x430
-#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB      0x438
-#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2       0x440
-#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2       0x448
-#define MC_STREAMID_OVERRIDE_CFG_AXISR         0x460
-#define MC_STREAMID_OVERRIDE_CFG_AXISW         0x468
-#define MC_STREAMID_OVERRIDE_CFG_EQOSR         0x470
-#define MC_STREAMID_OVERRIDE_CFG_EQOSW         0x478
-#define MC_STREAMID_OVERRIDE_CFG_UFSHCR                0x480
-#define MC_STREAMID_OVERRIDE_CFG_UFSHCW                0x488
-#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR    0x490
-#define MC_STREAMID_OVERRIDE_CFG_BPMPR         0x498
-#define MC_STREAMID_OVERRIDE_CFG_BPMPW         0x4A0
-#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR      0x4A8
-#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW      0x4B0
-#define MC_STREAMID_OVERRIDE_CFG_AONR          0x4B8
-#define MC_STREAMID_OVERRIDE_CFG_AONW          0x4C0
-#define MC_STREAMID_OVERRIDE_CFG_AONDMAR       0x4C8
-#define MC_STREAMID_OVERRIDE_CFG_AONDMAW       0x4D0
-#define MC_STREAMID_OVERRIDE_CFG_SCER          0x4D8
-#define MC_STREAMID_OVERRIDE_CFG_SCEW          0x4E0
-#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR       0x4E8
-#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW       0x4F0
-#define MC_STREAMID_OVERRIDE_CFG_APEDMAR       0x4F8
-#define MC_STREAMID_OVERRIDE_CFG_APEDMAW       0x500
-#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1   0x508
-#define MC_STREAMID_OVERRIDE_CFG_VICSRD1       0x510
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1     0x518
-
-/*******************************************************************************
- * Macro to calculate Security cfg register addr from StreamID Override register
- ******************************************************************************/
-#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) (addr + sizeof(uint32_t))
-
-/*******************************************************************************
- * Memory Controller transaction override config registers
- ******************************************************************************/
-#define MC_TXN_OVERRIDE_CONFIG_HDAR            0x10a8
-#define MC_TXN_OVERRIDE_CONFIG_BPMPW           0x14a0
-#define MC_TXN_OVERRIDE_CONFIG_PTCR            0x1000
-#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR      0x1490
-#define MC_TXN_OVERRIDE_CONFIG_EQOSW           0x1478
-#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR                0x13f8
-#define MC_TXN_OVERRIDE_CONFIG_ISPRA           0x1220
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAA                0x1328
-#define MC_TXN_OVERRIDE_CONFIG_VICSRD          0x1360
-#define MC_TXN_OVERRIDE_CONFIG_MPCOREW         0x11c8
-#define MC_TXN_OVERRIDE_CONFIG_GPUSRD          0x12c0
-#define MC_TXN_OVERRIDE_CONFIG_AXISR           0x1460
-#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW         0x14f0
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCW          0x1330
-#define MC_TXN_OVERRIDE_CONFIG_EQOSR           0x1470
-#define MC_TXN_OVERRIDE_CONFIG_APEDMAR         0x14f8
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD                0x10e0
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB                0x1318
-#define MC_TXN_OVERRIDE_CONFIG_VICSRD1         0x1510
-#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR                0x14a8
-#define MC_TXN_OVERRIDE_CONFIG_VIW             0x1390
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAA                0x1308
-#define MC_TXN_OVERRIDE_CONFIG_AXISW           0x1468
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR       0x1260
-#define MC_TXN_OVERRIDE_CONFIG_UFSHCR          0x1480
-#define MC_TXN_OVERRIDE_CONFIG_TSECSWR         0x12a8
-#define MC_TXN_OVERRIDE_CONFIG_GPUSWR          0x12c8
-#define MC_TXN_OVERRIDE_CONFIG_SATAR           0x10f8
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW      0x1258
-#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB                0x1438
-#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2         0x1440
-#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR         0x14e8
-#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2         0x1448
-#define MC_TXN_OVERRIDE_CONFIG_AONDMAW         0x14d0
-#define MC_TXN_OVERRIDE_CONFIG_APEDMAW         0x1500
-#define MC_TXN_OVERRIDE_CONFIG_AONW            0x14c0
-#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR      0x10b0
-#define MC_TXN_OVERRIDE_CONFIG_ETRR            0x1420
-#define MC_TXN_OVERRIDE_CONFIG_SESWR           0x1408
-#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD                0x13f0
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD                0x13c0
-#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB                0x1430
-#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW                0x14b0
-#define MC_TXN_OVERRIDE_CONFIG_APER            0x13d0
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1       0x1518
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR      0x1250
-#define MC_TXN_OVERRIDE_CONFIG_ISPWA           0x1230
-#define MC_TXN_OVERRIDE_CONFIG_SESRD           0x1400
-#define MC_TXN_OVERRIDE_CONFIG_SCER            0x14d8
-#define MC_TXN_OVERRIDE_CONFIG_AONR            0x14b8
-#define MC_TXN_OVERRIDE_CONFIG_MPCORER         0x1138
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA         0x1320
-#define MC_TXN_OVERRIDE_CONFIG_HDAW            0x11a8
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR                0x13c8
-#define MC_TXN_OVERRIDE_CONFIG_UFSHCW          0x1488
-#define MC_TXN_OVERRIDE_CONFIG_AONDMAR         0x14c8
-#define MC_TXN_OVERRIDE_CONFIG_SATAW           0x11e8
-#define MC_TXN_OVERRIDE_CONFIG_ETRW            0x1428
-#define MC_TXN_OVERRIDE_CONFIG_VICSWR          0x1368
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR                0x1158
-#define MC_TXN_OVERRIDE_CONFIG_AFIR            0x1070
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB                0x1338
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA         0x1300
-#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1     0x1508
-#define MC_TXN_OVERRIDE_CONFIG_ISPWB           0x1238
-#define MC_TXN_OVERRIDE_CONFIG_BPMPR           0x1498
-#define MC_TXN_OVERRIDE_CONFIG_APEW            0x13d8
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCR          0x1310
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW       0x1268
-#define MC_TXN_OVERRIDE_CONFIG_TSECSRD         0x12a0
-#define MC_TXN_OVERRIDE_CONFIG_AFIW            0x1188
-#define MC_TXN_OVERRIDE_CONFIG_SCEW            0x14e0
-
 /*******************************************************************************
  * Structure to hold the transaction override settings to use to override
  * client inputs
@@ -210,12 +48,31 @@ typedef struct mc_streamid_security_cfg {
        int override_client_ns_flag;
 } mc_streamid_security_cfg_t;
 
-#define OVERRIDE_DISABLE                               1
-#define OVERRIDE_ENABLE                                        0
-#define CLIENT_FLAG_SECURE                             0
-#define CLIENT_FLAG_NON_SECURE                         1
-#define CLIENT_INPUTS_OVERRIDE                         1
-#define CLIENT_INPUTS_NO_OVERRIDE                      0
+#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
+
+/*******************************************************************************
+ * Memory Controller SMMU Bypass config register
+ ******************************************************************************/
+#define MC_SMMU_BYPASS_CONFIG                  0x1820U
+#define MC_SMMU_BYPASS_CTRL_MASK               0x3U
+#define MC_SMMU_BYPASS_CTRL_SHIFT              0U
+#define MC_SMMU_CTRL_TBU_BYPASS_ALL            (0U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_RSVD                  (1U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID   (2U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_BYPASS_NONE           (3U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT (1U << 31)
+#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) \
        { \
@@ -237,178 +94,10 @@ typedef struct tegra_mc_settings {
        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;
 
-#endif /* __ASSEMBLY__ */
-
-/*******************************************************************************
- * Memory Controller SMMU Bypass config register
- ******************************************************************************/
-#define MC_SMMU_BYPASS_CONFIG                  0x1820
-#define MC_SMMU_BYPASS_CTRL_MASK               0x3
-#define MC_SMMU_BYPASS_CTRL_SHIFT              0
-#define MC_SMMU_CTRL_TBU_BYPASS_ALL            (0 << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_CTRL_TBU_RSVD                  (1 << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID   (2 << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_CTRL_TBU_BYPASS_NONE           (3 << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT (1 << 31)
-#define MC_SMMU_BYPASS_CONFIG_SETTINGS         (MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \
-                                                MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID)
-
-#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID      (1 << 0)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV        (2 << 4)
-#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT (1 << 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       0
-#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID 1
-#define MC_TXN_OVERRIDE_CGID_TAG_ZERO          2
-#define MC_TXN_OVERRIDE_CGID_TAG_ADR           3
-#define MC_TXN_OVERRIDE_CGID_TAG_MASK          3
-
-/*******************************************************************************
- * Memory Controller Reset Control registers
- ******************************************************************************/
-#define MC_CLIENT_HOTRESET_CTRL0                       0x200
-#define  MC_CLIENT_HOTRESET_CTRL0_RESET_VAL            0
-#define  MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB                (1 << 0)
-#define  MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB         (1 << 6)
-#define  MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB                (1 << 7)
-#define  MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB       (1 << 8)
-#define  MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB     (1 << 9)
-#define  MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB      (1 << 11)
-#define  MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB       (1 << 15)
-#define  MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB         (1 << 17)
-#define  MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB                (1 << 18)
-#define  MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB  (1 << 19)
-#define  MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB   (1 << 20)
-#define  MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB       (1 << 22)
-#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB    (1 << 29)
-#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB    (1 << 30)
-#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB    (1 << 31)
-#define MC_CLIENT_HOTRESET_STATUS0                     0x204
-#define MC_CLIENT_HOTRESET_CTRL1                       0x970
-#define  MC_CLIENT_HOTRESET_CTRL1_RESET_VAL            0
-#define  MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB    (1 << 0)
-#define  MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB                (1 << 2)
-#define  MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB      (1 << 5)
-#define  MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB                (1 << 6)
-#define  MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB         (1 << 7)
-#define  MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB      (1 << 8)
-#define  MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB                (1 << 12)
-#define  MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB      (1 << 13)
-#define  MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB       (1 << 18)
-#define  MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB       (1 << 19)
-#define  MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB      (1 << 20)
-#define  MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB  (1 << 21)
-#define  MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB       (1 << 22)
-#define  MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB                (1 << 23)
-#define  MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB                (1 << 24)
-#define MC_CLIENT_HOTRESET_STATUS1                     0x974
-
-/*******************************************************************************
- * Memory Controller's PCFIFO client configuration registers
- ******************************************************************************/
-#define MC_PCFIFO_CLIENT_CONFIG1                       0xdd4
-#define  MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL            0x20000
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED        (0 << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK     (1 << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED        (0 << 21)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK     (1 << 21)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0 << 29)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK    (1 << 29)
-
-#define MC_PCFIFO_CLIENT_CONFIG2                       0xdd8
-#define  MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL            0x20000
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED  (0 << 11)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK       (1 << 11)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED   (0 << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK        (1 << 13)
-
-#define MC_PCFIFO_CLIENT_CONFIG3                       0xddc
-#define  MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL            0
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED    (0 << 7)
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1 << 7)
-
-#define MC_PCFIFO_CLIENT_CONFIG4               0xde0
-#define  MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL    0
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0 << 1)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK    (1 << 1)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED        (0 << 5)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK     (1 << 5)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0 << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK    (1 << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0 << 15)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK    (1 << 15)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED      (0 << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK   (1 << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED    (0 << 22)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1 << 22)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED     (0 << 26)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK  (1 << 26)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED     (0 << 30)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK  (1 << 30)
-
-#define MC_PCFIFO_CLIENT_CONFIG5               0xbf4
-#define  MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL    0
-#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED     (0 << 0)
-#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK  (1 << 0)
-
-/*******************************************************************************
- * Memory Controller's SMMU client configuration registers
- ******************************************************************************/
-#define MC_SMMU_CLIENT_CONFIG1                         0x44
-#define  MC_SMMU_CLIENT_CONFIG1_RESET_VAL              0x20000
-#define  MC_SMMU_CLIENT_CONFIG1_AFIW_UNORDERED         (0 << 17)
-#define  MC_SMMU_CLIENT_CONFIG1_AFIW_MASK              (1 << 17)
-#define  MC_SMMU_CLIENT_CONFIG1_HDAW_UNORDERED         (0 << 21)
-#define  MC_SMMU_CLIENT_CONFIG1_HDAW_MASK              (1 << 21)
-#define  MC_SMMU_CLIENT_CONFIG1_SATAW_UNORDERED                (0 << 29)
-#define  MC_SMMU_CLIENT_CONFIG1_SATAW_MASK             (1 << 29)
-
-#define MC_SMMU_CLIENT_CONFIG2                         0x48
-#define  MC_SMMU_CLIENT_CONFIG2_RESET_VAL              0x20000
-#define  MC_SMMU_CLIENT_CONFIG2_XUSB_HOSTW_UNORDERED   (0 << 11)
-#define  MC_SMMU_CLIENT_CONFIG2_XUSB_HOSTW_MASK                (1 << 11)
-#define  MC_SMMU_CLIENT_CONFIG2_XUSB_DEVW_UNORDERED    (0 << 13)
-#define  MC_SMMU_CLIENT_CONFIG2_XUSB_DEVW_MASK         (1 << 13)
-
-#define MC_SMMU_CLIENT_CONFIG3                         0x4c
-#define  MC_SMMU_CLIENT_CONFIG3_RESET_VAL              0
-#define  MC_SMMU_CLIENT_CONFIG3_SDMMCWAB_UNORDERED     (0 << 7)
-#define  MC_SMMU_CLIENT_CONFIG3_SDMMCWAB_MASK          (1 << 7)
-
-#define MC_SMMU_CLIENT_CONFIG4                         0xb9c
-#define  MC_SMMU_CLIENT_CONFIG4_RESET_VAL              0
-#define  MC_SMMU_CLIENT_CONFIG4_SESWR_UNORDERED                (0 << 1)
-#define  MC_SMMU_CLIENT_CONFIG4_SESWR_MASK             (1 << 1)
-#define  MC_SMMU_CLIENT_CONFIG4_ETRW_UNORDERED         (0 << 5)
-#define  MC_SMMU_CLIENT_CONFIG4_ETRW_MASK              (1 << 5)
-#define  MC_SMMU_CLIENT_CONFIG4_AXISW_UNORDERED                (0 << 13)
-#define  MC_SMMU_CLIENT_CONFIG4_AXISW_MASK             (1 << 13)
-#define  MC_SMMU_CLIENT_CONFIG4_EQOSW_UNORDERED                (0 << 15)
-#define  MC_SMMU_CLIENT_CONFIG4_EQOSW_MASK             (1 << 15)
-#define  MC_SMMU_CLIENT_CONFIG4_UFSHCW_UNORDERED       (0 << 17)
-#define  MC_SMMU_CLIENT_CONFIG4_UFSHCW_MASK            (1 << 17)
-#define  MC_SMMU_CLIENT_CONFIG4_BPMPDMAW_UNORDERED     (0 << 22)
-#define  MC_SMMU_CLIENT_CONFIG4_BPMPDMAW_MASK          (1 << 22)
-#define  MC_SMMU_CLIENT_CONFIG4_AONDMAW_UNORDERED      (0 << 26)
-#define  MC_SMMU_CLIENT_CONFIG4_AONDMAW_MASK           (1 << 26)
-#define  MC_SMMU_CLIENT_CONFIG4_SCEDMAW_UNORDERED      (0 << 30)
-#define  MC_SMMU_CLIENT_CONFIG4_SCEDMAW_MASK           (1 << 30)
-
-#define MC_SMMU_CLIENT_CONFIG5                         0xbac
-#define  MC_SMMU_CLIENT_CONFIG5_RESET_VAL              0
-#define  MC_SMMU_CLIENT_CONFIG5_APEDMAW_UNORDERED      (0 << 0)
-#define  MC_SMMU_CLIENT_CONFIG5_APEDMAW_MASK   (1 << 0)
-
-#ifndef __ASSEMBLY__
-
-#include <lib/mmio.h>
-
 static inline uint32_t tegra_mc_read_32(uint32_t off)
 {
        return mmio_read_32(TEGRA_MC_BASE + off);
@@ -430,40 +119,43 @@ static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val)
 }
 
 #define mc_set_pcfifo_unordered_boot_so_mss(id, client) \
-       (~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
+       ((uint32_t)~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
         MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED)
 
-#define mc_set_smmu_unordered_boot_so_mss(id, client) \
-       (~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) \
        { \
                mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
                        (TSA_CONFIG_STATIC0_CSW_##client##_RESET & \
-                        ~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
-                       TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+                        (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+                       (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
        }
 
-#define mc_set_forced_coherent_cfg(client) \
+#define mc_set_tsa_w_passthrough(client) \
        { \
-               tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
-                       MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV); \
+               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_forced_coherent_so_dev_cfg(client) \
+#define mc_set_tsa_r_passthrough(client) \
        { \
-               tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
-                       MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV | \
-                       MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_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_forced_coherent_axid_so_dev_cfg(client) \
+#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_CONFIG_COH_PATH_OVERRIDE_SO_DEV | \
-                       MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID | \
-                       MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_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); \
        }
 
 /*******************************************************************************
@@ -473,6 +165,14 @@ static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val)
  ******************************************************************************/
 tegra_mc_settings_t *tegra_get_mc_settings(void);
 
-#endif /* __ASSMEBLY__ */
+/*******************************************************************************
+ * Handler to program the scratch registers with TZDRAM settings for the
+ * resume firmware.
+ *
+ * Implemented by SoCs under tegra/soc/txxx
+ ******************************************************************************/
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes);
+
+#endif /* __ASSEMBLY__ */
 
 #endif /* MEMCTRL_V2_H */
diff --git a/plat/nvidia/tegra/include/drivers/security_engine.h b/plat/nvidia/tegra/include/drivers/security_engine.h
new file mode 100644 (file)
index 0000000..4ab2f9a
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURITY_ENGINE_H
+#define SECURITY_ENGINE_H
+
+/*******************************************************************************
+ * Structure definition
+ ******************************************************************************/
+
+/* Security Engine Linked List */
+struct tegra_se_ll {
+       /* DMA buffer address */
+       uint32_t addr;
+       /* Data length in DMA buffer */
+       uint32_t data_len;
+};
+
+#define SE_LL_MAX_BUFFER_NUM                   4
+typedef struct tegra_se_io_lst {
+       volatile uint32_t last_buff_num;
+       volatile struct tegra_se_ll buffer[SE_LL_MAX_BUFFER_NUM];
+} tegra_se_io_lst_t __attribute__((aligned(4)));
+
+/* SE device structure */
+typedef struct tegra_se_dev {
+       /* Security Engine ID */
+       const int se_num;
+       /* SE base address */
+       const uint64_t se_base;
+       /* SE context size in AES blocks */
+       const uint32_t ctx_size_blks;
+       /* pointer to source linked list buffer */
+       tegra_se_io_lst_t *src_ll_buf;
+       /* pointer to destination linked list buffer */
+       tegra_se_io_lst_t *dst_ll_buf;
+       /* LP context buffer pointer */
+       uint32_t *ctx_save_buf;
+} tegra_se_dev_t;
+
+/* PKA1 device structure */
+typedef struct tegra_pka_dev {
+       /* PKA1 base address */
+       uint64_t pka_base;
+} tegra_pka_dev_t;
+
+/*******************************************************************************
+ * Public interface
+ ******************************************************************************/
+void tegra_se_init(void);
+int tegra_se_suspend(void);
+void tegra_se_resume(void);
+int tegra_se_save_tzram(void);
+
+#endif /* SECURITY_ENGINE_H */
index 9582a67ed376c799723e08797c245357d85406ee..41b0c518761986129dcce683ed60c418587e62e2 100644 (file)
 /*******************************************************************************
  * SMMU Global Aux. Control Register
  ******************************************************************************/
-#define SMMU_CBn_ACTLR_CPRE_BIT                        (1U << 1)
+#define SMMU_CBn_ACTLR_CPRE_BIT                        (1ULL << 1U)
 
 /*******************************************************************************
  * SMMU configuration constants
  ******************************************************************************/
-#define ID1_PAGESIZE                           (1U << 31)
+#define ID1_PAGESIZE                           (1U << 31U)
 #define ID1_NUMPAGENDXB_SHIFT                  28U
 #define ID1_NUMPAGENDXB_MASK                   7U
 #define ID1_NUMS2CB_SHIFT                      16U
@@ -705,5 +705,6 @@ typedef struct smmu_regs {
 void tegra_smmu_init(void);
 void tegra_smmu_save_context(uint64_t smmu_ctx_addr);
 smmu_regs_t *plat_get_smmu_ctx(void);
+uint32_t plat_get_num_smmu_devices(void);
 
 #endif /* SMMU_H */
diff --git a/plat/nvidia/tegra/include/lib/profiler.h b/plat/nvidia/tegra/include/lib/profiler.h
new file mode 100644 (file)
index 0000000..60f8d80
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PROFILER_H__
+#define __PROFILER_H__
+
+/*******************************************************************************
+ * Number of bytes of memory used by the profiler on Tegra
+ ******************************************************************************/
+#define PROFILER_SIZE_BYTES    U(0x1000)
+
+void boot_profiler_init(uint64_t shmem_base, uint32_t tmr_base);
+void boot_profiler_add_record(const char *str);
+void boot_profiler_deinit(void);
+
+#endif /* __PROFILER_H__ */
index d10dc262aa91fa15066c3125c84a7c4f24f7d01c..0a0126b1e094d8232af8064fa8c55b5aa1b34177 100644 (file)
@@ -34,7 +34,8 @@
  * Platform console related constants
  ******************************************************************************/
 #define TEGRA_CONSOLE_BAUDRATE         U(115200)
-#define TEGRA_BOOT_UART_CLK_IN_HZ      U(408000000)
+#define TEGRA_BOOT_UART_CLK_13_MHZ     U(13000000)
+#define TEGRA_BOOT_UART_CLK_408_MHZ    U(408000000)
 
 /*******************************************************************************
  * Platform memory map related constants
index 1f58caabb5206beb841bc390055e44a601a9e4e1..fd75fbce6fafa792d101c467f6fd0e63192e2bd7 100644 (file)
@@ -83,6 +83,9 @@
  ******************************************************************************/
 #define TEGRA_MC_BASE                  U(0x70019000)
 
+/* Memory Controller Interrupt Status */
+#define MC_INTSTATUS                   0x00U
+
 /* TZDRAM carveout configuration registers */
 #define MC_SECURITY_CFG0_0             U(0x70)
 #define MC_SECURITY_CFG1_0             U(0x74)
diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h
new file mode 100644 (file)
index 0000000..9e2c02b
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#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);
+
+#endif /* TEGRA186_PRIVATE_H */
index 3abba55165ec75921e7706e19952b24b54b6083d..231f93ac8164983847bc28bcc3ad660a0402bd67 100644 (file)
 #define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW              U(0x15018)
 #define  TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW_RESET       U(0x1100)
 
-#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK           (U(0x3) << 11)
-#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU                (U(0) << 11)
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK           (ULL(0x3) << 11)
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU                (ULL(0) << 11)
+
+/*******************************************************************************
+ * Tegra General Purpose Centralised DMA constants
+ ******************************************************************************/
+#define TEGRA_GPCDMA_BASE              ULL(0x2610000)
 
 /*******************************************************************************
  * Tegra Memory Controller constants
 /* General Security Carveout register macros */
 #define MC_GSC_CONFIG_REGS_SIZE                U(0x40)
 #define MC_GSC_LOCK_CFG_SETTINGS_BIT   (U(1) << 1)
-#define MC_GSC_ENABLE_TZ_LOCK_BIT      (U(1) << 0)
+#define MC_GSC_ENABLE_TZ_LOCK_BIT      (ULL(1) << 0)
 #define MC_GSC_SIZE_RANGE_4KB_SHIFT    U(27)
 #define MC_GSC_BASE_LO_SHIFT           U(12)
 #define MC_GSC_BASE_LO_MASK            U(0xFFFFF)
 #define MC_GSC_BASE_HI_SHIFT           U(0)
 #define MC_GSC_BASE_HI_MASK            U(3)
+#define MC_GSC_ENABLE_CPU_SECURE_BIT    (U(1) << 31)
 
 /* TZDRAM carveout configuration registers */
 #define MC_SECURITY_CFG0_0             U(0x70)
 #define MC_SECURITY_CFG1_0             U(0x74)
 #define MC_SECURITY_CFG3_0             U(0x9BC)
 
+#define MC_SECURITY_BOM_MASK           (U(0xFFF) << 20)
+#define MC_SECURITY_SIZE_MB_MASK       (U(0x1FFF) << 0)
+#define MC_SECURITY_BOM_HI_MASK                (U(0x3) << 0)
+
 /* Video Memory carveout configuration registers */
 #define MC_VIDEO_PROTECT_BASE_HI       U(0x978)
 #define MC_VIDEO_PROTECT_BASE_LO       U(0x648)
 #define MC_TZRAM_BASE_LO               U(0x2194)
 #define MC_TZRAM_BASE_HI               U(0x2198)
 #define MC_TZRAM_SIZE                  U(0x219C)
-#define MC_TZRAM_CLIENT_ACCESS_CFG0    U(0x21A0)
+#define MC_TZRAM_CLIENT_ACCESS0_CFG0   U(0x21A0)
+#define MC_TZRAM_CLIENT_ACCESS1_CFG0   U(0x21A4)
+#define  TZRAM_ALLOW_MPCORER           (U(1) << 7)
+#define  TZRAM_ALLOW_MPCOREW           (U(1) << 25)
 
 /*******************************************************************************
  * Tegra UART Controller constants
 #define TEGRA_CAR_RESET_BASE           U(0x05000000)
 #define TEGRA_GPU_RESET_REG_OFFSET     U(0x30)
 #define  GPU_RESET_BIT                 (U(1) << 0)
+#define TEGRA_GPCDMA_RST_SET_REG_OFFSET        U(0x6A0004)
+#define TEGRA_GPCDMA_RST_CLR_REG_OFFSET        U(0x6A0008)
 
 /*******************************************************************************
  * Tegra micro-seconds timer constants
 #define  SECURE_SCRATCH_RSV11_HI       U(0x6AC)
 #define  SECURE_SCRATCH_RSV53_LO       U(0x7F8)
 #define  SECURE_SCRATCH_RSV53_HI       U(0x7FC)
-#define  SECURE_SCRATCH_RSV54_HI       U(0x804)
 #define  SECURE_SCRATCH_RSV55_LO       U(0x808)
 #define  SECURE_SCRATCH_RSV55_HI       U(0x80C)
 
+#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_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
+#define SCRATCH_TZDRAM_ADDR_HI         SECURE_SCRATCH_RSV55_HI
+
 /*******************************************************************************
  * Tegra Memory Mapped Control Register Access constants
  ******************************************************************************/
diff --git a/plat/nvidia/tegra/include/t186/tegra_mc_def.h b/plat/nvidia/tegra/include/t186/tegra_mc_def.h
new file mode 100644 (file)
index 0000000..d051a15
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA_MC_DEF_H
+#define TEGRA_MC_DEF_H
+
+/*******************************************************************************
+ * 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                    0x20000U
+#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_MASK            (1U << 29)
+
+#define MC_PCFIFO_CLIENT_CONFIG2                               0xdd8U
+#define  MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL                    0x20000U
+#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_MASK                (1U << 13)
+
+#define MC_PCFIFO_CLIENT_CONFIG3                               0xddcU
+#define  MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL                    0U
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED    (0U << 7)
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK         (1U << 7)
+
+#define MC_PCFIFO_CLIENT_CONFIG4                               0xde0U
+#define  MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL                    0U
+#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_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_ORDERED                 (1U << 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_BPMPDMAW_UNORDERED    (0U << 22)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK         (1U << 22)
+#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_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                    0U
+#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED     (0U << 0)
+#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK          (1U << 0)
+
+/*******************************************************************************
+ * Stream ID Override Config registers
+ ******************************************************************************/
+#define MC_STREAMID_OVERRIDE_CFG_PTCR                          0x000U
+#define MC_STREAMID_OVERRIDE_CFG_AFIR                          0x070U
+#define MC_STREAMID_OVERRIDE_CFG_HDAR                          0x0A8U
+#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR                    0x0B0U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD                      0x0E0U
+#define MC_STREAMID_OVERRIDE_CFG_SATAR                         0x0F8U
+#define MC_STREAMID_OVERRIDE_CFG_MPCORER                       0x138U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR                      0x158U
+#define MC_STREAMID_OVERRIDE_CFG_AFIW                          0x188U
+#define MC_STREAMID_OVERRIDE_CFG_HDAW                          0x1A8U
+#define MC_STREAMID_OVERRIDE_CFG_MPCOREW                       0x1C8U
+#define MC_STREAMID_OVERRIDE_CFG_SATAW                         0x1E8U
+#define MC_STREAMID_OVERRIDE_CFG_ISPRA                         0x220U
+#define MC_STREAMID_OVERRIDE_CFG_ISPWA                         0x230U
+#define MC_STREAMID_OVERRIDE_CFG_ISPWB                         0x238U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR                    0x250U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW                    0x258U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR                     0x260U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW                     0x268U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRD                       0x2A0U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWR                       0x2A8U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSRD                                0x2C0U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSWR                                0x2C8U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA                       0x300U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAA                      0x308U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCR                                0x310U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB                      0x318U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA                       0x320U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAA                      0x328U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCW                                0x330U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB                      0x338U
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD                                0x360U
+#define MC_STREAMID_OVERRIDE_CFG_VICSWR                                0x368U
+#define MC_STREAMID_OVERRIDE_CFG_VIW                           0x390U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD                      0x3C0U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR                      0x3C8U
+#define MC_STREAMID_OVERRIDE_CFG_APER                          0x3D0U
+#define MC_STREAMID_OVERRIDE_CFG_APEW                          0x3D8U
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD                      0x3F0U
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR                      0x3F8U
+#define MC_STREAMID_OVERRIDE_CFG_SESRD                         0x400U
+#define MC_STREAMID_OVERRIDE_CFG_SESWR                         0x408U
+#define MC_STREAMID_OVERRIDE_CFG_ETRR                          0x420U
+#define MC_STREAMID_OVERRIDE_CFG_ETRW                          0x428U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB                      0x430U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB                      0x438U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2                       0x440U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2                       0x448U
+#define MC_STREAMID_OVERRIDE_CFG_AXISR                         0x460U
+#define MC_STREAMID_OVERRIDE_CFG_AXISW                         0x468U
+#define MC_STREAMID_OVERRIDE_CFG_EQOSR                         0x470U
+#define MC_STREAMID_OVERRIDE_CFG_EQOSW                         0x478U
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCR                                0x480U
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCW                                0x488U
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR                    0x490U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPR                         0x498U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPW                         0x4A0U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR                      0x4A8U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW                      0x4B0U
+#define MC_STREAMID_OVERRIDE_CFG_AONR                          0x4B8U
+#define MC_STREAMID_OVERRIDE_CFG_AONW                          0x4C0U
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAR                       0x4C8U
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAW                       0x4D0U
+#define MC_STREAMID_OVERRIDE_CFG_SCER                          0x4D8U
+#define MC_STREAMID_OVERRIDE_CFG_SCEW                          0x4E0U
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR                       0x4E8U
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW                       0x4F0U
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAR                       0x4F8U
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAW                       0x500U
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1                   0x508U
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD1                       0x510U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1                     0x518U
+
+/*******************************************************************************
+ * 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_BPMPW                           0x14a0U
+#define MC_TXN_OVERRIDE_CONFIG_PTCR                            0x1000U
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR                      0x1490U
+#define MC_TXN_OVERRIDE_CONFIG_EQOSW                           0x1478U
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR                                0x13f8U
+#define MC_TXN_OVERRIDE_CONFIG_ISPRA                           0x1220U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAA                                0x1328U
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD                          0x1360U
+#define MC_TXN_OVERRIDE_CONFIG_MPCOREW                         0x11c8U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSRD                          0x12c0U
+#define MC_TXN_OVERRIDE_CONFIG_AXISR                           0x1460U
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW                         0x14f0U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCW                          0x1330U
+#define MC_TXN_OVERRIDE_CONFIG_EQOSR                           0x1470U
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAR                         0x14f8U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD                                0x10e0U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB                                0x1318U
+#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_SDMMCRAA                                0x1308U
+#define MC_TXN_OVERRIDE_CONFIG_AXISW                           0x1468U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR                       0x1260U
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCR                          0x1480U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWR                         0x12a8U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSWR                          0x12c8U
+#define MC_TXN_OVERRIDE_CONFIG_SATAR                           0x10f8U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW                      0x1258U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB                                0x1438U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2                         0x1440U
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR                         0x14e8U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2                         0x1448U
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAW                         0x14d0U
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAW                         0x1500U
+#define MC_TXN_OVERRIDE_CONFIG_AONW                            0x14c0U
+#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR                      0x10b0U
+#define MC_TXN_OVERRIDE_CONFIG_ETRR                            0x1420U
+#define MC_TXN_OVERRIDE_CONFIG_SESWR                           0x1408U
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD                                0x13f0U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD                                0x13c0U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB                                0x1430U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW                                0x14b0U
+#define MC_TXN_OVERRIDE_CONFIG_APER                            0x13d0U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1                       0x1518U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR                      0x1250U
+#define MC_TXN_OVERRIDE_CONFIG_ISPWA                           0x1230U
+#define MC_TXN_OVERRIDE_CONFIG_SESRD                           0x1400U
+#define MC_TXN_OVERRIDE_CONFIG_SCER                            0x14d8U
+#define MC_TXN_OVERRIDE_CONFIG_AONR                            0x14b8U
+#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_UFSHCW                          0x1488U
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAR                         0x14c8U
+#define MC_TXN_OVERRIDE_CONFIG_SATAW                           0x11e8U
+#define MC_TXN_OVERRIDE_CONFIG_ETRW                            0x1428U
+#define MC_TXN_OVERRIDE_CONFIG_VICSWR                          0x1368U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR                                0x1158U
+#define MC_TXN_OVERRIDE_CONFIG_AFIR                            0x1070U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB                                0x1338U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA                         0x1300U
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1                     0x1508U
+#define MC_TXN_OVERRIDE_CONFIG_ISPWB                           0x1238U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPR                           0x1498U
+#define MC_TXN_OVERRIDE_CONFIG_APEW                            0x13d8U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCR                          0x1310U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW                       0x1268U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRD                         0x12a0U
+#define MC_TXN_OVERRIDE_CONFIG_AFIW                            0x1188U
+#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 << 18)
+#define  MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB               (1U << 19)
+#define  MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB              (1U << 20)
+#define  MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB          (1U << 21)
+#define  MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB               (1U << 22)
+#define  MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB                        (1U << 23)
+#define  MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB                        (1U << 24)
+#define MC_CLIENT_HOTRESET_STATUS1                             0x974U
+
+#endif /* TEGRA_MC_DEF_H */
index 14cdfd59dbdbe09610f66b9683b34bae91777c66..75919e11e4c5441ea969c99404f941aa0b326433 100644 (file)
 #define PLAT_MAX_RET_STATE             U(1)
 #define PLAT_MAX_OFF_STATE             (PSTATE_ID_SOC_POWERDN + U(1))
 
+/*******************************************************************************
+ * iRAM memory constants
+ ******************************************************************************/
+#define TEGRA_IRAM_BASE                        0x40000000
+
 /*******************************************************************************
  * GIC memory map
  ******************************************************************************/
                                         ENABLE_WRAP_INCR_MASTER1_BIT | \
                                         ENABLE_WRAP_INCR_MASTER0_BIT)
 
+/*******************************************************************************
+ * Tegra Resource Semaphore constants
+ ******************************************************************************/
+#define TEGRA_RES_SEMA_BASE            0x60001000UL
+#define  STA_OFFSET                    0UL
+#define  SET_OFFSET                    4UL
+#define  CLR_OFFSET                    8UL
+
+/*******************************************************************************
+ * Tegra Primary Interrupt Controller constants
+ ******************************************************************************/
+#define TEGRA_PRI_ICTLR_BASE           0x60004000UL
+#define  CPU_IEP_FIR_SET               0x18UL
+
 /*******************************************************************************
  * Tegra micro-seconds timer constants
  ******************************************************************************/
 #define TEGRA_CAR_RESET_BASE           U(0x60006000)
 #define TEGRA_GPU_RESET_REG_OFFSET     U(0x28C)
 #define  GPU_RESET_BIT                 (U(1) << 24)
+#define TEGRA_RST_DEV_CLR_V            U(0x434)
+#define TEGRA_CLK_ENB_V                        U(0x440)
+
+/* SE Clock Offsets */
+#define TEGRA_RST_DEVICES_V            0x358UL
+#define  SE_RESET_BIT                  (0x1UL << 31)
+#define TEGRA_RST_DEVICES_W             0x35CUL
+#define  ENTROPY_CLK_ENB_BIT           (0x1UL << 21)
+#define TEGRA_CLK_OUT_ENB_V            0x360UL
+#define  SE_CLK_ENB_BIT                        (0x1UL << 31)
+#define TEGRA_CLK_OUT_ENB_W            0x364UL
+#define  ENTROPY_RESET_BIT             (0x1UL << 21)
 
 /*******************************************************************************
  * Tegra Flow Controller constants
  ******************************************************************************/
 #define TEGRA_FLOWCTRL_BASE            U(0x60007000)
 
+/*******************************************************************************
+ * Tegra AHB arbitration controller
+ ******************************************************************************/
+#define TEGRA_AHB_ARB_BASE             0x6000C000UL
+
 /*******************************************************************************
  * Tegra Secure Boot Controller constants
  ******************************************************************************/
 #define TEGRA_UARTD_BASE               U(0x70006300)
 #define TEGRA_UARTE_BASE               U(0x70006400)
 
+/*******************************************************************************
+ * Tegra Fuse Controller related constants
+ ******************************************************************************/
+#define TEGRA_FUSE_BASE                        0x7000F800UL
+#define FUSE_BOOT_SECURITY_INFO                0x268UL
+#define FUSE_ATOMIC_SAVE_CARVEOUT_EN   (0x1U << 7)
+#define FUSE_JTAG_SECUREID_VALID       (0x104UL)
+#define ECID_VALID                     (0x1UL)
+
+
 /*******************************************************************************
  * Tegra Power Mgmt Controller constants
  ******************************************************************************/
 #define TEGRA_PMC_BASE                 U(0x7000E400)
 
+/*******************************************************************************
+ * Tegra Atomics constants
+ ******************************************************************************/
+#define TEGRA_ATOMICS_BASE             0x70016000UL
+#define  TRIGGER0_REG_OFFSET           0UL
+#define  TRIGGER_WIDTH_SHIFT           4UL
+#define  TRIGGER_ID_SHIFT              16UL
+#define  RESULT0_REG_OFFSET            0xC00UL
+
 /*******************************************************************************
  * Tegra Memory Controller constants
  ******************************************************************************/
 #define TEGRA_MC_BASE                  U(0x70019000)
 
+/* Memory Controller Interrupt Status */
+#define MC_INTSTATUS                   0x00U
+
 /* TZDRAM carveout configuration registers */
 #define MC_SECURITY_CFG0_0             U(0x70)
 #define MC_SECURITY_CFG1_0             U(0x74)
 #define MC_VIDEO_PROTECT_BASE_LO       U(0x648)
 #define MC_VIDEO_PROTECT_SIZE_MB       U(0x64c)
 
+/* SMMU configuration registers*/
+#define MC_SMMU_PPCS_ASID_0            0x270U
+#define  PPCS_SMMU_ENABLE              (0x1U << 31)
+
+/*******************************************************************************
+ * Tegra SE constants
+ ******************************************************************************/
+#define TEGRA_SE1_BASE                 U(0x70012000)
+#define TEGRA_SE2_BASE                 U(0x70412000)
+#define TEGRA_PKA1_BASE                        U(0x70420000)
+#define TEGRA_SE2_RANGE_SIZE           U(0x2000)
+#define SE_TZRAM_SECURITY              U(0x4)
+
 /*******************************************************************************
  * Tegra TZRAM constants
  ******************************************************************************/
 #define TEGRA_TZRAM_BASE               U(0x7C010000)
 #define TEGRA_TZRAM_SIZE               U(0x10000)
 
+/*******************************************************************************
+ * Tegra TZRAM carveout constants
+ ******************************************************************************/
+#define TEGRA_TZRAM_CARVEOUT_BASE      U(0x7C04C000)
+#define TEGRA_TZRAM_CARVEOUT_SIZE      U(0x4000)
+
 #endif /* TEGRA_DEF_H */
index 63a0e01e34a0191706abd9b35ff821cb5b356974..13c92e0ebde63a1fc649470b0794a19eaf58adf6 100644 (file)
@@ -8,27 +8,55 @@
 #define TEGRA_PLATFORM_H
 
 #include <cdefs.h>
+#include <stdbool.h>
+#include <utils_def.h>
+
+/*******************************************************************************
+ * Tegra major, minor version helper macros
+ ******************************************************************************/
+#define MAJOR_VERSION_SHIFT            U(0x4)
+#define MAJOR_VERSION_MASK             U(0xF)
+#define MINOR_VERSION_SHIFT            U(0x10)
+#define MINOR_VERSION_MASK             U(0xF)
+#define CHIP_ID_SHIFT                  U(8)
+#define CHIP_ID_MASK                   U(0xFF)
+#define PRE_SI_PLATFORM_SHIFT          U(0x14)
+#define PRE_SI_PLATFORM_MASK           U(0xF)
+
+/*******************************************************************************
+ * Tegra chip ID values
+ ******************************************************************************/
+#define TEGRA_CHIPID_TEGRA13           U(0x13)
+#define TEGRA_CHIPID_TEGRA21           U(0x21)
+#define TEGRA_CHIPID_TEGRA18           U(0x18)
+
+#ifndef __ASSEMBLY__
 
 /*
- * Tegra chip major/minor version
+ * Tegra chip ID major/minor identifiers
  */
 uint32_t tegra_get_chipid_major(void);
 uint32_t tegra_get_chipid_minor(void);
 
 /*
- * Tegra chip identifiers
+ * Tegra chip ID identifiers
  */
-uint8_t tegra_chipid_is_t132(void);
-uint8_t tegra_chipid_is_t210(void);
-uint8_t tegra_chipid_is_t186(void);
-
+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);
 
 /*
  * Tegra platform identifiers
  */
-uint8_t tegra_platform_is_silicon(void);
-uint8_t tegra_platform_is_qt(void);
-uint8_t tegra_platform_is_emulation(void);
-uint8_t tegra_platform_is_fpga(void);
+bool tegra_platform_is_silicon(void);
+bool tegra_platform_is_qt(void);
+bool tegra_platform_is_emulation(void);
+bool tegra_platform_is_linsim(void);
+bool tegra_platform_is_fpga(void);
+bool tegra_platform_is_unit_fpga(void);
+bool tegra_platform_is_virt_dev_kit(void);
+
+#endif /* __ASSEMBLY__ */
 
 #endif /* TEGRA_PLATFORM_H */
index 93223cc2413a09e80b4d12090f30514d7514821b..68b462425e014f3996ab5dc251be5d460cf72d64 100644 (file)
 #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)
+
+/*******************************************************************************
+ * Implementation defined ACTLR_EL2 bit definitions
+ ******************************************************************************/
+#define ACTLR_EL2_PMSTATE_MASK         (ULL(0xF) << 0)
+
 /*******************************************************************************
  * Struct for parameters received from BL2
  ******************************************************************************/
@@ -31,9 +41,18 @@ typedef struct plat_params_from_bl2 {
        /* TZ memory base */
        uint64_t tzdram_base;
        /* UART port ID */
-       int uart_id;
+       int32_t uart_id;
+       /* L2 ECC parity protection disable flag */
+       int32_t l2_ecc_parity_prot_dis;
+       /* SHMEM base address for storing the boot logs */
+       uint64_t boot_profiler_shmem_base;
 } plat_params_from_bl2_t;
 
+/*******************************************************************************
+ * Helper function to access l2ctlr_el1 register on Cortex-A57 CPUs
+ ******************************************************************************/
+DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, CORTEX_A57_L2CTLR_EL1)
+
 /*******************************************************************************
  * Struct describing parameters passed to bl31
  ******************************************************************************/
@@ -47,19 +66,21 @@ struct tegra_bl31_params {
 };
 
 /* Declarations for plat_psci_handlers.c */
-int32_t tegra_soc_validate_power_state(unsigned int power_state,
+int32_t tegra_soc_validate_power_state(uint32_t power_state,
                psci_power_state_t *req_state);
 
 /* Declarations for plat_setup.c */
 const mmap_region_t *plat_get_mmio_map(void);
-uint32_t plat_get_console_from_id(int id);
+uint32_t plat_get_console_from_id(int32_t id);
 void plat_gic_setup(void);
 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);
 
 /* Declarations for plat_secondary.c */
 void plat_secondary_setup(void);
-int plat_lock_cpu_vectors(void);
+int32_t plat_lock_cpu_vectors(void);
 
 /* Declarations for tegra_fiq_glue.c */
 void tegra_fiq_handler_setup(void);
@@ -75,7 +96,30 @@ extern uint8_t tegra_fake_system_suspend;
 
 void tegra_pm_system_suspend_entry(void);
 void tegra_pm_system_suspend_exit(void);
-int tegra_system_suspended(void);
+int32_t tegra_system_suspended(void);
+int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state);
+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_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);
@@ -83,8 +127,7 @@ int tegra_prepare_cpu_on_finish(unsigned long mpidr);
 
 /* Declarations for tegra_bl31_setup.c */
 plat_params_from_bl2_t *bl31_get_plat_params(void);
-int bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes);
-void plat_early_platform_setup(void);
+int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes);
 
 /* Declarations for tegra_delay_timer.c */
 void tegra_delay_timer_init(void);
@@ -92,4 +135,22 @@ void tegra_delay_timer_init(void);
 void tegra_secure_entrypoint(void);
 void tegra186_cpu_reset_handler(void);
 
+/* Declarations for tegra_sip_calls.c */
+uintptr_t tegra_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);
+int 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);
+
 #endif /* TEGRA_PRIVATE_H */
index 33548b7201cdb6acfc803beae445da9c07a5a76d..614d2a26db1c310d53ecb5f80fc12ee3d3196ebb 100644 (file)
@@ -12,6 +12,8 @@ $(eval $(call add_define,CRASH_REPORTING))
 
 # enable assert() for release/debug builds
 ENABLE_ASSERTIONS      :=      1
+PLAT_LOG_LEVEL_ASSERT  :=      40
+$(eval $(call add_define,PLAT_LOG_LEVEL_ASSERT))
 
 # enable dynamic memory mapping
 PLAT_XLAT_TABLES_DYNAMIC :=    1
@@ -29,11 +31,14 @@ 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
+
 include plat/nvidia/tegra/common/tegra_common.mk
 include ${SOC_DIR}/platform_${TARGET_SOC}.mk
 
 # modify BUILD_PLAT to point to SoC specific build directory
 BUILD_PLAT     :=      ${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE}
 
-# enable signed comparison checks
-TF_CFLAGS      += -Wsign-compare
+# platform cflags (enable signed comparisons, disable stdlib)
+TF_CFLAGS      += -Wsign-compare -nostdlib
index 7226120b0494f09abcc4974512072fa10a5c91c6..bd3f46fcca8260abe7075215c51b410af2fc6b02 100644 (file)
@@ -98,19 +98,24 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
 
 int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
+       uint64_t val;
+
        tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK);
 
        /* Disable DCO operations */
        denver_disable_dco();
 
        /* Power down the CPU */
-       write_actlr_el1(DENVER_CPU_STATE_POWER_DOWN);
+       val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
+       write_actlr_el1(val | DENVER_CPU_STATE_POWER_DOWN);
 
        return PSCI_E_SUCCESS;
 }
 
 int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
+       uint64_t val;
+
 #if ENABLE_ASSERTIONS
        int cpu = read_mpidr() & MPIDR_CPU_MASK;
 
@@ -128,7 +133,8 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
        denver_disable_dco();
 
        /* Program the suspend state ID */
-       write_actlr_el1(target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]);
+       val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
+       write_actlr_el1(val | target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]);
 
        return PSCI_E_SUCCESS;
 }
index f72b73ed52d4f2c495ca033b47b59dcbc175de4c..3f9cda965fa3c062d1645a148a9c02b335ed3329 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,25 +7,10 @@
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
-
+#include <platform.h>
 #include <tegra_def.h>
 #include <tegra_private.h>
 
-/*******************************************************************************
- * 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.
- *******************************************************************************
- */
-const unsigned char tegra_power_domain_tree_desc[] = {
-       /* No of root nodes */
-       1,
-       /* No of clusters */
-       PLATFORM_CLUSTER_COUNT,
-       /* No of CPU cores */
-       PLATFORM_CORE_COUNT,
-};
-
 /* sets of MMIO ranges setup */
 #define MMIO_RANGE_0_ADDR      0x50000000
 #define MMIO_RANGE_1_ADDR      0x60000000
@@ -54,6 +39,29 @@ const mmap_region_t *plat_get_mmio_map(void)
        return tegra_mmap;
 }
 
+/*******************************************************************************
+ * 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.
+ *******************************************************************************
+ */
+const unsigned char tegra_power_domain_tree_desc[] = {
+       /* No of root nodes */
+       1,
+       /* No of clusters */
+       PLATFORM_CLUSTER_COUNT,
+       /* No of CPU cores */
+       PLATFORM_CORE_COUNT,
+};
+
+/*******************************************************************************
+ * This function returns the Tegra default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+       return tegra_power_domain_tree_desc;
+}
+
 unsigned int plat_get_syscnt_freq2(void)
 {
        return 12000000;
index 02dd1cd56ca670d2c4202f568d880da5b4c312fd..90c6bb2a1b5a3a232396cf298b752b01b4e9c0e1 100644 (file)
@@ -38,7 +38,7 @@ int plat_sip_handler(uint32_t smc_fid,
                     uint64_t x2,
                     uint64_t x3,
                     uint64_t x4,
-                    void *cookie,
+                    const void *cookie,
                     void *handle,
                     uint64_t flags)
 {
index f15ee747b3427100a5ad25a75adb0c379709c18a..bb7b7ee6615db74418b0993ef84b5a4703f8ede6 100644 (file)
@@ -19,7 +19,8 @@ $(eval $(call add_define,MAX_XLAT_TABLES))
 MAX_MMAP_REGIONS               := 8
 $(eval $(call add_define,MAX_MMAP_REGIONS))
 
-BL31_SOURCES           +=      lib/cpus/aarch64/denver.S               \
+BL31_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      \
                                ${SOC_DIR}/plat_psci_handlers.c         \
index 96a5525a6be5bc7a9dd4dd20b1ab219fa4d98dc0..203f61a5d98278d512f82f8d70ae75b4a285e803 100644 (file)
 #define MCA_ARG_FINISH_MASK                    U(0xFF)
 
 /*******************************************************************************
- * Uncore PERFMON ARI struct
+ * Uncore PERFMON ARI macros
  ******************************************************************************/
 #define UNCORE_PERFMON_CMD_READ                        U(0)
 #define UNCORE_PERFMON_CMD_WRITE               U(1)
 
 #define UNCORE_PERFMON_CMD_MASK                        U(0xFF)
-#define UNCORE_PERFMON_CMD_SHIFT               U(24)
 #define UNCORE_PERFMON_UNIT_GRP_MASK           U(0xF)
 #define UNCORE_PERFMON_SELECTOR_MASK           U(0xF)
 #define UNCORE_PERFMON_REG_MASK                        U(0xFF)
 #define UNCORE_PERFMON_CTR_MASK                        U(0xFF)
 #define UNCORE_PERFMON_RESP_STATUS_MASK                U(0xFF)
-#define UNCORE_PERFMON_RESP_STATUS_SHIFT       U(24)
 
 /*******************************************************************************
  * Structure populated by arch specific code to export routines which perform
index 1429a6158dfb82a49e04e6803007a8805ba492e6..a57bc11b9c86f1db287970b36f11d5258798af8a 100644 (file)
@@ -35,8 +35,8 @@
 #define ARI_REQUEST_VALID_BIT          (1U << 8)
 #define ARI_EVT_MASK_STANDBYWFI_BIT    (1U << 7)
 
-/* default timeout (ms) to wait for ARI completion */
-#define ARI_MAX_RETRY_COUNT            2000
+/* default timeout (us) to wait for ARI completion */
+#define ARI_MAX_RETRY_COUNT            U(2000000)
 
 /*******************************************************************************
  * ARI helper functions
@@ -80,7 +80,7 @@ static inline void ari_clobber_response(uint32_t ari_base)
 static int32_t ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req,
                uint32_t lo, uint32_t hi)
 {
-       uint32_t retries = ARI_MAX_RETRY_COUNT;
+       uint32_t retries = (uint32_t)ARI_MAX_RETRY_COUNT;
        uint32_t status;
        int32_t ret = 0;
 
@@ -99,9 +99,9 @@ static int32_t ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t r
                ret = 0;
        } else {
                /* For shutdown/reboot commands, we dont have to check for timeouts */
-               if ((req == (uint32_t)TEGRA_ARI_MISC_CCPLEX) &&
-                   ((lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) ||
-                    (lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT))) {
+               if ((req == TEGRA_ARI_MISC_CCPLEX) &&
+                   ((lo == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) ||
+                    (lo == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT))) {
                                ret = 0;
                } else {
                        /*
@@ -115,8 +115,8 @@ static int32_t ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t r
                                        break;
                                }
 
-                               /* delay 1 ms */
-                               mdelay(1);
+                               /* delay 1 us */
+                               udelay(1);
 
                                /* decrement the retry count */
                                retries--;
@@ -151,7 +151,7 @@ int32_t ari_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time)
 
                /* Enter the cstate, to be woken up after wake_time (TSC ticks) */
                ret = ari_request_wait(ari_base, ARI_EVT_MASK_STANDBYWFI_BIT,
-               TEGRA_ARI_ENTER_CSTATE, state, wake_time);
+                       (uint32_t)TEGRA_ARI_ENTER_CSTATE, state, wake_time);
        }
 
        return ret;
@@ -161,38 +161,38 @@ int32_t ari_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccp
        uint32_t system, uint8_t sys_state_force, uint32_t wake_mask,
        uint8_t update_wake_mask)
 {
-       uint32_t val = 0U;
+       uint64_t val = 0U;
 
        /* clean the previous response state */
        ari_clobber_response(ari_base);
 
        /* update CLUSTER_CSTATE? */
        if (cluster != 0U) {
-               val |= (cluster & (uint32_t)CLUSTER_CSTATE_MASK) |
-                       (uint32_t)CLUSTER_CSTATE_UPDATE_BIT;
+               val |= (cluster & CLUSTER_CSTATE_MASK) |
+                       CLUSTER_CSTATE_UPDATE_BIT;
        }
 
        /* update CCPLEX_CSTATE? */
        if (ccplex != 0U) {
-               val |= ((ccplex & (uint32_t)CCPLEX_CSTATE_MASK) << (uint32_t)CCPLEX_CSTATE_SHIFT) |
-                       (uint32_t)CCPLEX_CSTATE_UPDATE_BIT;
+               val |= ((ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT) |
+                       CCPLEX_CSTATE_UPDATE_BIT;
        }
 
        /* update SYSTEM_CSTATE? */
        if (system != 0U) {
-               val |= ((system & (uint32_t)SYSTEM_CSTATE_MASK) << (uint32_t)SYSTEM_CSTATE_SHIFT) |
-                      (((uint32_t)sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) |
-                       (uint32_t)SYSTEM_CSTATE_UPDATE_BIT);
+               val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) |
+                      (((uint64_t)sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) |
+                       SYSTEM_CSTATE_UPDATE_BIT);
        }
 
        /* update wake mask value? */
        if (update_wake_mask != 0U) {
-               val |= (uint32_t)CSTATE_WAKE_MASK_UPDATE_BIT;
+               val |= CSTATE_WAKE_MASK_UPDATE_BIT;
        }
 
        /* set the updated cstate info */
-       return ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CSTATE_INFO, val,
-                       wake_mask);
+       return ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_UPDATE_CSTATE_INFO,
+                               (uint32_t)val, wake_mask);
 }
 
 int32_t ari_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time)
@@ -208,8 +208,8 @@ int32_t ari_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t tim
                ari_clobber_response(ari_base);
 
                /* update crossover threshold time */
-               ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CROSSOVER,
-                       type, time);
+               ret = ari_request_wait(ari_base, 0U,
+                               (uint32_t)TEGRA_ARI_UPDATE_CROSSOVER, type, time);
        }
 
        return ret;
@@ -227,7 +227,8 @@ uint64_t ari_read_cstate_stats(uint32_t ari_base, uint32_t state)
                /* clean the previous response state */
                ari_clobber_response(ari_base);
 
-               ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_CSTATE_STATS, state, 0U);
+               ret = ari_request_wait(ari_base, 0U,
+                               (uint32_t)TEGRA_ARI_CSTATE_STATS, state, 0U);
                if (ret != 0) {
                        result = EINVAL;
                } else {
@@ -243,8 +244,8 @@ int32_t ari_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats
        ari_clobber_response(ari_base);
 
        /* write the cstate stats */
-       return ari_request_wait(ari_base, 0U, TEGRA_ARI_WRITE_CSTATE_STATS, state,
-                       stats);
+       return ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_WRITE_CSTATE_STATS,
+                       state, stats);
 }
 
 uint64_t ari_enumeration_misc(uint32_t ari_base, uint32_t cmd, uint32_t data)
@@ -261,7 +262,7 @@ uint64_t ari_enumeration_misc(uint32_t ari_base, uint32_t cmd, uint32_t data)
                local_data = 0U;
        }
 
-       ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_MISC, cmd, local_data);
+       ret = ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_MISC, cmd, local_data);
        if (ret != 0) {
                resp = (uint64_t)ret;
        } else {
@@ -281,8 +282,8 @@ int32_t ari_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time
        /* clean the previous response state */
        ari_clobber_response(ari_base);
 
-       ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_IS_CCX_ALLOWED, state & 0x7U,
-                       wake_time);
+       ret = ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_IS_CCX_ALLOWED,
+                       state & 0x7U, wake_time);
        if (ret != 0) {
                ERROR("%s: failed (%d)\n", __func__, ret);
                result = 0U;
@@ -299,18 +300,16 @@ int32_t ari_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time
        int32_t ret, result;
 
        /* check for allowed power state */
-       if ((state != TEGRA_ARI_CORE_C0) &&
-           (state != TEGRA_ARI_CORE_C1) &&
-           (state != TEGRA_ARI_CORE_C6) &&
-           (state != TEGRA_ARI_CORE_C7)) {
+       if ((state != TEGRA_ARI_CORE_C0) && (state != TEGRA_ARI_CORE_C1) &&
+           (state != TEGRA_ARI_CORE_C6) && (state != TEGRA_ARI_CORE_C7)) {
                ERROR("%s: unknown cstate (%d)\n", __func__, state);
                result = EINVAL;
        } else {
                /* clean the previous response state */
                ari_clobber_response(ari_base);
 
-               ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_IS_SC7_ALLOWED, state,
-                               wake_time);
+               ret = ari_request_wait(ari_base, 0U,
+                       (uint32_t)TEGRA_ARI_IS_SC7_ALLOWED, state, wake_time);
                if (ret != 0) {
                        ERROR("%s: failed (%d)\n", __func__, ret);
                        result = 0;
@@ -325,10 +324,10 @@ int32_t ari_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time
 
 int32_t ari_online_core(uint32_t ari_base, uint32_t core)
 {
-       uint64_t cpu = read_mpidr() & (uint64_t)(MPIDR_CPU_MASK);
-       uint64_t cluster = (read_mpidr() & (uint64_t)(MPIDR_CLUSTER_MASK)) >>
-                          (uint64_t)(MPIDR_AFFINITY_BITS);
-       uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+       uint64_t cpu = read_mpidr() & (MPIDR_CPU_MASK);
+       uint64_t cluster = (read_mpidr() & (MPIDR_CLUSTER_MASK)) >>
+                          (MPIDR_AFFINITY_BITS);
+       uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
        int32_t ret;
 
        /* construct the current CPU # */
@@ -342,14 +341,14 @@ int32_t ari_online_core(uint32_t ari_base, uint32_t core)
                /*
                 * The Denver cluster has 2 CPUs only - 0, 1.
                 */
-               if ((impl == (uint32_t)DENVER_IMPL) &&
-                   ((core == 2U) || (core == 3U))) {
+               if ((impl == DENVER_IMPL) && ((core == 2U) || (core == 3U))) {
                        ERROR("%s: unknown core id (%d)\n", __func__, core);
                        ret = EINVAL;
                } else {
                        /* clean the previous response state */
                        ari_clobber_response(ari_base);
-                       ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_ONLINE_CORE, core, 0U);
+                       ret = ari_request_wait(ari_base, 0U,
+                               (uint32_t)TEGRA_ARI_ONLINE_CORE, core, 0U);
                }
        }
 
@@ -377,7 +376,8 @@ int32_t ari_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t en
                ((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
                ((enable != 0U) ? MCE_AUTO_CC3_ENABLE_BIT : 0U));
 
-       return ari_request_wait(ari_base, 0U, TEGRA_ARI_CC3_CTRL, val, 0U);
+       return ari_request_wait(ari_base, 0U,
+                       (uint32_t)TEGRA_ARI_CC3_CTRL, val, 0U);
 }
 
 int32_t ari_reset_vector_update(uint32_t ari_base)
@@ -389,7 +389,8 @@ int32_t ari_reset_vector_update(uint32_t ari_base)
         * Need to program the CPU reset vector one time during cold boot
         * and SC7 exit
         */
-       (void)ari_request_wait(ari_base, 0U, TEGRA_ARI_COPY_MISCREG_AA64_RST, 0U, 0U);
+       (void)ari_request_wait(ari_base, 0U,
+                       (uint32_t)TEGRA_ARI_COPY_MISCREG_AA64_RST, 0U, 0U);
 
        return 0;
 }
@@ -399,8 +400,8 @@ int32_t ari_roc_flush_cache_trbits(uint32_t ari_base)
        /* clean the previous response state */
        ari_clobber_response(ari_base);
 
-       return ari_request_wait(ari_base, 0U, TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS,
-                       0U, 0U);
+       return ari_request_wait(ari_base, 0U,
+                       (uint32_t)TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS, 0U, 0U);
 }
 
 int32_t ari_roc_flush_cache(uint32_t ari_base)
@@ -408,8 +409,8 @@ int32_t ari_roc_flush_cache(uint32_t ari_base)
        /* clean the previous response state */
        ari_clobber_response(ari_base);
 
-       return ari_request_wait(ari_base, 0U, TEGRA_ARI_ROC_FLUSH_CACHE_ONLY,
-                       0U, 0U);
+       return ari_request_wait(ari_base, 0U,
+                       (uint32_t)TEGRA_ARI_ROC_FLUSH_CACHE_ONLY, 0U, 0U);
 }
 
 int32_t ari_roc_clean_cache(uint32_t ari_base)
@@ -417,8 +418,8 @@ int32_t ari_roc_clean_cache(uint32_t ari_base)
        /* clean the previous response state */
        ari_clobber_response(ari_base);
 
-       return ari_request_wait(ari_base, 0U, TEGRA_ARI_ROC_CLEAN_CACHE_ONLY,
-                       0U, 0U);
+       return ari_request_wait(ari_base, 0U,
+                       (uint32_t)TEGRA_ARI_ROC_CLEAN_CACHE_ONLY, 0U, 0U);
 }
 
 uint64_t ari_read_write_mca(uint32_t ari_base, uint64_t cmd, uint64_t *data)
@@ -435,7 +436,7 @@ uint64_t ari_read_write_mca(uint32_t ari_base, uint64_t cmd, uint64_t *data)
        ari_write_32(ari_base, (uint32_t)cmd, ARI_RESPONSE_DATA_LO);
        ari_write_32(ari_base, (uint32_t)(cmd >> 32U), ARI_RESPONSE_DATA_HI);
 
-       ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_MCA,
+       ret = ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_MCA,
                               (uint32_t)mca_arg_data,
                               (uint32_t)(mca_arg_data >> 32U));
        if (ret == 0) {
@@ -465,7 +466,7 @@ int32_t ari_update_ccplex_gsc(uint32_t ari_base, uint32_t gsc_idx)
 {
        int32_t ret = 0;
        /* sanity check GSC ID */
-       if (gsc_idx > (uint32_t)TEGRA_ARI_GSC_VPR_IDX) {
+       if (gsc_idx > TEGRA_ARI_GSC_VPR_IDX) {
                ret = EINVAL;
        } else {
                /* clean the previous response state */
@@ -476,7 +477,8 @@ int32_t ari_update_ccplex_gsc(uint32_t ari_base, uint32_t gsc_idx)
                 * the ID, from the MC registers and update the internal GSC registers
                 * of the CCPLEX.
                 */
-               (void)ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CCPLEX_GSC, gsc_idx, 0U);
+               (void)ari_request_wait(ari_base, 0U,
+                               (uint32_t)TEGRA_ARI_UPDATE_CCPLEX_GSC, gsc_idx, 0U);
        }
 
        return ret;
@@ -490,17 +492,18 @@ void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx)
        /*
         * The MCE will shutdown or restart the entire system
         */
-       (void)ari_request_wait(ari_base, 0U, TEGRA_ARI_MISC_CCPLEX, state_idx, 0U);
+       (void)ari_request_wait(ari_base, 0U,
+                       (uint32_t)TEGRA_ARI_MISC_CCPLEX, state_idx, 0U);
 }
 
 int32_t ari_read_write_uncore_perfmon(uint32_t ari_base, uint64_t req,
                uint64_t *data)
 {
        int32_t ret, result;
-       uint32_t val;
-       uint8_t req_cmd, req_status;
+       uint32_t val, req_status;
+       uint8_t req_cmd;
 
-       req_cmd = (uint8_t)(req >> UNCORE_PERFMON_CMD_SHIFT);
+       req_cmd = (uint8_t)(req & UNCORE_PERFMON_CMD_MASK);
 
        /* clean the previous response state */
        ari_clobber_response(ari_base);
@@ -517,20 +520,20 @@ int32_t ari_read_write_uncore_perfmon(uint32_t ari_base, uint64_t req,
                val = (req_cmd == UNCORE_PERFMON_CMD_WRITE) ?
                        (uint32_t)*data : 0U;
 
-               ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_PERFMON, val,
-                                      (uint32_t)req);
+               ret = ari_request_wait(ari_base, 0U,
+                       (uint32_t)TEGRA_ARI_PERFMON, val, (uint32_t)req);
                if (ret != 0) {
                        result = ret;
                } else {
                        /* read the command status value */
-                       req_status = (uint8_t)ari_get_response_high(ari_base) &
+                       req_status = ari_get_response_high(ari_base) &
                                         UNCORE_PERFMON_RESP_STATUS_MASK;
 
                        /*
                         * For "read" commands get the data from the uncore
                         * perfmon registers
                         */
-                       req_status >>= UNCORE_PERFMON_RESP_STATUS_SHIFT;
+                       req_status &= UNCORE_PERFMON_RESP_STATUS_MASK;
                        if ((req_status == 0U) && (req_cmd == UNCORE_PERFMON_CMD_READ)) {
                                *data = ari_get_response_low(ari_base);
                        }
@@ -555,6 +558,7 @@ void ari_misc_ccplex(uint32_t ari_base, uint32_t index, uint32_t value)
        } else {
                /* clean the previous response state */
                ari_clobber_response(ari_base);
-               (void)ari_request_wait(ari_base, 0U, TEGRA_ARI_MISC_CCPLEX, index, value);
+               (void)ari_request_wait(ari_base, 0U,
+                       (uint32_t)TEGRA_ARI_MISC_CCPLEX, index, value);
        }
 }
index 828ad3cbdd1757702fb19f3c3ab38e603454e735..9e42b2bcbf1093025cbaac4e41992c6e80f7d809 100644 (file)
@@ -111,8 +111,8 @@ static mce_config_t mce_cfg_table[MCE_ARI_APERTURES_MAX] = {
 static uint32_t mce_get_curr_cpu_ari_base(void)
 {
        uint64_t mpidr = read_mpidr();
-       uint64_t cpuid = mpidr & (uint64_t)MPIDR_CPU_MASK;
-       uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+       uint64_t cpuid = mpidr & MPIDR_CPU_MASK;
+       uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
 
        /*
         * T186 has 2 CPU clusters, one with Denver CPUs and the other with
@@ -131,9 +131,9 @@ static uint32_t mce_get_curr_cpu_ari_base(void)
 static arch_mce_ops_t *mce_get_curr_cpu_ops(void)
 {
        uint64_t mpidr = read_mpidr();
-       uint64_t cpuid = mpidr & (uint64_t)MPIDR_CPU_MASK;
-       uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) &
-                       (uint64_t)MIDR_IMPL_MASK;
+       uint64_t cpuid = mpidr & MPIDR_CPU_MASK;
+       uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) &
+                       MIDR_IMPL_MASK;
 
        /*
         * T186 has 2 CPU clusters, one with Denver CPUs and the other with
@@ -170,121 +170,89 @@ int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
        cpu_ari_base = mce_get_curr_cpu_ari_base();
 
        switch (cmd) {
-       case MCE_CMD_ENTER_CSTATE:
+       case (uint64_t)MCE_CMD_ENTER_CSTATE:
                ret = ops->enter_cstate(cpu_ari_base, arg0, arg1);
-               if (ret < 0) {
-                       ERROR("%s: enter_cstate failed(%d)\n", __func__, ret);
-               }
 
                break;
 
-       case MCE_CMD_UPDATE_CSTATE_INFO:
+       case (uint64_t)MCE_CMD_UPDATE_CSTATE_INFO:
                /*
                 * get the parameters required for the update cstate info
                 * command
                 */
-               arg3 = read_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X4));
-               arg4 = read_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X5));
-               arg5 = read_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X6));
+               arg3 = read_ctx_reg(gp_regs, CTX_GPREG_X4);
+               arg4 = read_ctx_reg(gp_regs, CTX_GPREG_X5);
+               arg5 = read_ctx_reg(gp_regs, CTX_GPREG_X6);
 
                ret = ops->update_cstate_info(cpu_ari_base, (uint32_t)arg0,
                                (uint32_t)arg1, (uint32_t)arg2, (uint8_t)arg3,
                                (uint32_t)arg4, (uint8_t)arg5);
-               if (ret < 0) {
-                       ERROR("%s: update_cstate_info failed(%d)\n",
-                               __func__, ret);
-               }
 
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X4), (0));
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X5), (0));
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X6), (0));
+               write_ctx_reg(gp_regs, CTX_GPREG_X4, (0ULL));
+               write_ctx_reg(gp_regs, CTX_GPREG_X5, (0ULL));
+               write_ctx_reg(gp_regs, CTX_GPREG_X6, (0ULL));
 
                break;
 
-       case MCE_CMD_UPDATE_CROSSOVER_TIME:
+       case (uint64_t)MCE_CMD_UPDATE_CROSSOVER_TIME:
                ret = ops->update_crossover_time(cpu_ari_base, arg0, arg1);
-               if (ret < 0) {
-                       ERROR("%s: update_crossover_time failed(%d)\n",
-                               __func__, ret);
-               }
 
                break;
 
-       case MCE_CMD_READ_CSTATE_STATS:
+       case (uint64_t)MCE_CMD_READ_CSTATE_STATS:
                ret64 = ops->read_cstate_stats(cpu_ari_base, arg0);
 
                /* update context to return cstate stats value */
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (ret64));
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X2), (ret64));
+               write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
+               write_ctx_reg(gp_regs, CTX_GPREG_X2, (ret64));
 
                break;
 
-       case MCE_CMD_WRITE_CSTATE_STATS:
+       case (uint64_t)MCE_CMD_WRITE_CSTATE_STATS:
                ret = ops->write_cstate_stats(cpu_ari_base, arg0, arg1);
-               if (ret < 0) {
-                       ERROR("%s: write_cstate_stats failed(%d)\n",
-                               __func__, ret);
-               }
 
                break;
 
-       case MCE_CMD_IS_CCX_ALLOWED:
+       case (uint64_t)MCE_CMD_IS_CCX_ALLOWED:
                ret = ops->is_ccx_allowed(cpu_ari_base, arg0, arg1);
-               if (ret < 0) {
-                       ERROR("%s: is_ccx_allowed failed(%d)\n", __func__, ret);
-                       break;
-               }
 
                /* update context to return CCx status value */
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1),
-                             (uint64_t)(ret));
+               write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint64_t)(ret));
 
                break;
 
-       case MCE_CMD_IS_SC7_ALLOWED:
+       case (uint64_t)MCE_CMD_IS_SC7_ALLOWED:
                ret = ops->is_sc7_allowed(cpu_ari_base, arg0, arg1);
-               if (ret < 0) {
-                       ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
-                       break;
-               }
 
                /* update context to return SC7 status value */
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1),
-                             (uint64_t)(ret));
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X3),
-                             (uint64_t)(ret));
+               write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint64_t)(ret));
+               write_ctx_reg(gp_regs, CTX_GPREG_X3, (uint64_t)(ret));
 
                break;
 
-       case MCE_CMD_ONLINE_CORE:
+       case (uint64_t)MCE_CMD_ONLINE_CORE:
                ret = ops->online_core(cpu_ari_base, arg0);
-               if (ret < 0) {
-                       ERROR("%s: online_core failed(%d)\n", __func__, ret);
-               }
 
                break;
 
-       case MCE_CMD_CC3_CTRL:
+       case (uint64_t)MCE_CMD_CC3_CTRL:
                ret = ops->cc3_ctrl(cpu_ari_base, arg0, arg1, arg2);
-               if (ret < 0) {
-                       ERROR("%s: cc3_ctrl failed(%d)\n", __func__, ret);
-               }
 
                break;
 
-       case MCE_CMD_ECHO_DATA:
+       case (uint64_t)MCE_CMD_ECHO_DATA:
                ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_ECHO,
                                arg0);
 
                /* update context to return if echo'd data matched source */
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1),
-                             ((ret64 == arg0) ? 1ULL : 0ULL));
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X2),
-                             ((ret64 == arg0) ? 1ULL : 0ULL));
+               write_ctx_reg(gp_regs, CTX_GPREG_X1, ((ret64 == arg0) ?
+                             1ULL : 0ULL));
+               write_ctx_reg(gp_regs, CTX_GPREG_X2, ((ret64 == arg0) ?
+                             1ULL : 0ULL));
 
                break;
 
-       case MCE_CMD_READ_VERSIONS:
+       case (uint64_t)MCE_CMD_READ_VERSIONS:
                ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION,
                        arg0);
 
@@ -292,68 +260,56 @@ int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
                 * version = minor(63:32) | major(31:0). Update context
                 * to return major and minor version number.
                 */
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1),
-                             (ret64));
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X2),
-                             (ret64 >> 32ULL));
+               write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
+               write_ctx_reg(gp_regs, CTX_GPREG_X2, (ret64 >> 32ULL));
 
                break;
 
-       case MCE_CMD_ENUM_FEATURES:
+       case (uint64_t)MCE_CMD_ENUM_FEATURES:
                ret64 = ops->call_enum_misc(cpu_ari_base,
                                TEGRA_ARI_MISC_FEATURE_LEAF_0, arg0);
 
                /* update context to return features value */
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (ret64));
+               write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
 
                break;
 
-       case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
+       case (uint64_t)MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
                ret = ops->roc_flush_cache_trbits(cpu_ari_base);
-               if (ret < 0) {
-                       ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
-                               ret);
-               }
 
                break;
 
-       case MCE_CMD_ROC_FLUSH_CACHE:
+       case (uint64_t)MCE_CMD_ROC_FLUSH_CACHE:
                ret = ops->roc_flush_cache(cpu_ari_base);
-               if (ret < 0) {
-                       ERROR("%s: flush cache failed(%d)\n", __func__, ret);
-               }
 
                break;
 
-       case MCE_CMD_ROC_CLEAN_CACHE:
+       case (uint64_t)MCE_CMD_ROC_CLEAN_CACHE:
                ret = ops->roc_clean_cache(cpu_ari_base);
-               if (ret < 0) {
-                       ERROR("%s: clean cache failed(%d)\n", __func__, ret);
-               }
 
                break;
 
-       case MCE_CMD_ENUM_READ_MCA:
+       case (uint64_t)MCE_CMD_ENUM_READ_MCA:
                ret64 = ops->read_write_mca(cpu_ari_base, arg0, &arg1);
 
                /* update context to return MCA data/error */
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (ret64));
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X2), (arg1));
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X3), (ret64));
+               write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
+               write_ctx_reg(gp_regs, CTX_GPREG_X2, (arg1));
+               write_ctx_reg(gp_regs, CTX_GPREG_X3, (ret64));
 
                break;
 
-       case MCE_CMD_ENUM_WRITE_MCA:
+       case (uint64_t)MCE_CMD_ENUM_WRITE_MCA:
                ret64 = ops->read_write_mca(cpu_ari_base, arg0, &arg1);
 
                /* update context to return MCA error */
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (ret64));
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X3), (ret64));
+               write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
+               write_ctx_reg(gp_regs, CTX_GPREG_X3, (ret64));
 
                break;
 
 #if ENABLE_CHIP_VERIFICATION_HARNESS
-       case MCE_CMD_ENABLE_LATIC:
+       case (uint64_t)MCE_CMD_ENABLE_LATIC:
                /*
                 * This call is not for production use. The constant value,
                 * 0xFFFF0000, is specific to allowing for enabling LATIC on
@@ -371,14 +327,14 @@ int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
                break;
 #endif
 
-       case MCE_CMD_UNCORE_PERFMON_REQ:
+       case (uint64_t)MCE_CMD_UNCORE_PERFMON_REQ:
                ret = ops->read_write_uncore_perfmon(cpu_ari_base, arg0, &arg1);
 
                /* update context to return data */
-               write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (arg1));
+               write_ctx_reg(gp_regs, CTX_GPREG_X1, (arg1));
                break;
 
-       case MCE_CMD_MISC_CCPLEX:
+       case (uint64_t)MCE_CMD_MISC_CCPLEX:
                ops->misc_ccplex(cpu_ari_base, arg0, arg1);
 
                break;
index 1ac3710daf5a348e4c732e21048dc4fbdaf30f13..cbc9aa3a6897780f9009bd61dadd745540f60265 100644 (file)
 
 #include <mce_private.h>
 #include <t18x_ari.h>
+#include <tegra_private.h>
 
 int32_t nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time)
 {
        int32_t ret = 0;
+       uint64_t val = 0ULL;
 
        (void)ari_base;
 
@@ -28,10 +30,11 @@ int32_t nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time)
                ret = EINVAL;
        } else {
                /* time (TSC ticks) until the core is expected to get a wake event */
-               nvg_set_request_data(TEGRA_NVG_CHANNEL_WAKE_TIME, wake_time);
+               nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_WAKE_TIME, wake_time);
 
                /* set the core cstate */
-               write_actlr_el1(state);
+               val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
+               write_actlr_el1(val | (uint64_t)state);
        }
 
        return ret;
@@ -78,7 +81,7 @@ int32_t nvg_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccp
        val |= ((uint64_t)wake_mask << CSTATE_WAKE_MASK_SHIFT);
 
        /* set the updated cstate info */
-       nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_INFO, val);
+       nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_CSTATE_INFO, val);
 
        return 0;
 }
@@ -189,7 +192,7 @@ int32_t nvg_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time
                                ((uint64_t)state & MCE_SC7_ALLOWED_MASK);
 
                /* issue command to check if SC7 is allowed */
-               nvg_set_request_data(TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED, val);
+               nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED, val);
 
                /* 1 = SC7 allowed, 0 = SC7 not allowed */
                ret = (nvg_get_result() != 0ULL) ? 1 : 0;
@@ -200,15 +203,14 @@ int32_t nvg_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time
 
 int32_t nvg_online_core(uint32_t ari_base, uint32_t core)
 {
-       uint64_t cpu = read_mpidr() & (uint64_t)MPIDR_CPU_MASK;
-       uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) &
-                       (uint64_t)MIDR_IMPL_MASK;
+       uint64_t cpu = read_mpidr() & MPIDR_CPU_MASK;
+       uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
        int32_t ret = 0;
 
        (void)ari_base;
 
        /* sanity check code id */
-       if ((core >= (uint32_t)MCE_CORE_ID_MAX) || (cpu == core)) {
+       if ((core >= MCE_CORE_ID_MAX) || (cpu == core)) {
                ERROR("%s: unsupported core id (%d)\n", __func__, core);
                ret = EINVAL;
        } else {
@@ -220,7 +222,7 @@ int32_t nvg_online_core(uint32_t ari_base, uint32_t core)
                        ret = EINVAL;
                } else {
                        /* get a core online */
-                       nvg_set_request_data(TEGRA_NVG_CHANNEL_ONLINE_CORE,
+                       nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_ONLINE_CORE,
                                ((uint64_t)core & MCE_CORE_ID_MASK));
                }
        }
@@ -248,7 +250,7 @@ int32_t nvg_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t en
                ((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
                ((enable != 0U) ? MCE_AUTO_CC3_ENABLE_BIT : 0U));
 
-       nvg_set_request_data(TEGRA_NVG_CHANNEL_CC3_CTRL, (uint64_t)val);
+       nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_CC3_CTRL, (uint64_t)val);
 
        return 0;
 }
index 38dffb22e5967d860f69a6479d990510baf5f8f1..376ee86df9bda7bccf535e905c33bcc9a808918b 100644 (file)
@@ -4,9 +4,13 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <common/bl_common.h>
 
+#include <mce.h>
 #include <memctrl_v2.h>
+#include <tegra_mc_def.h>
+#include <tegra_platform.h>
 
 /*******************************************************************************
  * Array to hold stream_id override config register offsets
@@ -201,16 +205,330 @@ const static mc_txn_override_cfg_t tegra186_txn_override_cfgs[] = {
        mc_make_txn_override_cfg(SCEW, CGID_TAG_ADR),
 };
 
+static void tegra186_memctrl_reconfig_mss_clients(void)
+{
+#if ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS
+       uint32_t val, wdata_0, wdata_1;
+
+       /*
+        * Assert Memory Controller's HOTRESET_FLUSH_ENABLE signal for
+        * boot and strongly ordered MSS clients to flush existing memory
+        * traffic and stall future requests.
+        */
+       val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
+       assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL);
+
+       wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB |
+#if ENABLE_AFI_DEVICE
+                 MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB |
+#endif
+                 MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
+                 MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
+                 MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB;
+       tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
+
+       /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+       do {
+               val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+       } while ((val & wdata_0) != wdata_0);
+
+       /* Wait one more time due to SW WAR for known legacy issue */
+       do {
+               val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+       } while ((val & wdata_0) != wdata_0);
+
+       val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
+       assert(val == MC_CLIENT_HOTRESET_CTRL1_RESET_VAL);
+
+       wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB |
+                 MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB |
+                 MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB |
+                 MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB |
+                 MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB |
+                 MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB |
+                 MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB |
+                 MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB |
+                 MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB |
+                 MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB;
+       tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
+
+       /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+       do {
+               val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+       } while ((val & wdata_1) != wdata_1);
+
+       /* Wait one more time due to SW WAR for known legacy issue */
+       do {
+               val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+       } while ((val & wdata_1) != wdata_1);
+
+       /*
+        * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and
+        * strongly ordered MSS clients. ROC needs to be single point
+        * of control on overriding the memory type. So, remove TSA's
+        * memtype override.
+        *
+        * MC clients with default SO_DEV override still enabled at TSA:
+        * AONW, BPMPW, SCEW, APEW
+        */
+#if ENABLE_AFI_DEVICE
+       mc_set_tsa_passthrough(AFIW);
+#endif
+       mc_set_tsa_passthrough(HDAW);
+       mc_set_tsa_passthrough(SATAW);
+       mc_set_tsa_passthrough(XUSB_HOSTW);
+       mc_set_tsa_passthrough(XUSB_DEVW);
+       mc_set_tsa_passthrough(SDMMCWAB);
+       mc_set_tsa_passthrough(APEDMAW);
+       mc_set_tsa_passthrough(SESWR);
+       mc_set_tsa_passthrough(ETRW);
+       mc_set_tsa_passthrough(AXISW);
+       mc_set_tsa_passthrough(EQOSW);
+       mc_set_tsa_passthrough(UFSHCW);
+       mc_set_tsa_passthrough(BPMPDMAW);
+       mc_set_tsa_passthrough(AONDMAW);
+       mc_set_tsa_passthrough(SCEDMAW);
+
+       /* Parker has no IO Coherency support and need the following:
+        * Ordered MC Clients on Parker are AFI, EQOS, SATA, XUSB.
+        * 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.
+        *
+        * CGID_TAG_ADR is only present from T186 A02. As this code is common
+        *    between A01 and A02, tegra_memctrl_set_overrides() programs
+        *    CGID_TAG_ADR for the necessary clients on A02.
+        */
+       mc_set_txn_override(HDAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(BPMPW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(PTCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(NVDISPLAYR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(EQOSW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(NVJPGSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(ISPRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SDMMCWAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(VICSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(MPCOREW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+       mc_set_txn_override(GPUSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(AXISR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SCEDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SDMMCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(EQOSR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       /* See bug 200131110 comment #35*/
+       mc_set_txn_override(APEDMAR, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(NVENCSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SDMMCRAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(VICSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(BPMPDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(VIW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SDMMCRAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(AXISW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(XUSB_DEVR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(UFSHCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(TSECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(GPUSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SATAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(XUSB_HOSTW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+       mc_set_txn_override(TSECSWRB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(GPUSRD2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SCEDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(GPUSWR2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(AONDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       /* See bug 200131110 comment #35*/
+       mc_set_txn_override(APEDMAW, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(AONW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(HOST1XDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(ETRR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SESWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(NVJPGSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(NVDECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(TSECSRDB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(BPMPDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(APER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(NVDECSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(XUSB_HOSTR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(ISPWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SESRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SCER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(AONR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(MPCORER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+       mc_set_txn_override(SDMMCWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(HDAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(NVDECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(UFSHCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(AONDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SATAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+       mc_set_txn_override(ETRW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(VICSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(NVENCSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       /* See bug 200131110 comment #35 */
+       mc_set_txn_override(AFIR, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SDMMCWAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SDMMCRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(NVDISPLAYR1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(ISPWB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(BPMPR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(APEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(SDMMCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       mc_set_txn_override(XUSB_DEVW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+       mc_set_txn_override(TSECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+       /*
+        * See bug 200131110 comment #35 - there are no normal requests
+        * and AWID for SO/DEV requests is hardcoded in RTL for a
+        * particular PCIE controller
+        */
+       mc_set_txn_override(AFIW, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_COHERENT);
+       mc_set_txn_override(SCEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+
+       /*
+        * At this point, ordering can occur at ROC. So, remove PCFIFO's
+        * control over ordering requests.
+        *
+        * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for
+        * boot and strongly ordered MSS clients
+        */
+       val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL &
+#if ENABLE_AFI_DEVICE
+               mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) &
+#endif
+               mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) &
+               mc_set_pcfifo_unordered_boot_so_mss(1, SATAW);
+       tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val);
+
+       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, XUSB_DEVW);
+       tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, val);
+
+       val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL &
+               mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB);
+       tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, val);
+
+       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, AXISW) &
+               mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
+               mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
+               mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
+               mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
+       /* EQOSW is the only client that has PCFIFO order enabled. */
+       val |= mc_set_pcfifo_ordered_boot_so_mss(4, EQOSW);
+       tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val);
+
+       val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
+               mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW);
+       tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val);
+
+       /*
+        * Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS
+        * clients to allow memory traffic from all clients to start passing
+        * through ROC
+        */
+       val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
+       assert(val == wdata_0);
+
+       wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL;
+       tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
+
+       val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
+       assert(val == wdata_1);
+
+       wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL;
+       tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
+
+#endif
+}
+
+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.
+        */
+       if ((tegra_chipid_is_t186()) &&
+           (!tegra_platform_is_silicon() ||
+           (tegra_platform_is_silicon() && (tegra_get_chipid_minor() == 1U)))) {
+
+               /*
+                * GPU and NVENC settings for Tegra186 simulation and
+                * Silicon rev. A01
+                */
+               val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR);
+               val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+               tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR,
+                       val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
+
+               val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2);
+               val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+               tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2,
+                       val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
+
+               val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR);
+               val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+               tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR,
+                       val | MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID);
+
+       } else {
+
+               /*
+                * 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);
+                       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);
+               }
+       }
+}
+
 /*******************************************************************************
  * Struct to hold the memory controller settings
  ******************************************************************************/
 static tegra_mc_settings_t tegra186_mc_settings = {
        .streamid_override_cfg = tegra186_streamid_override_regs,
-       .num_streamid_override_cfgs = ARRAY_SIZE(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 = ARRAY_SIZE(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 = ARRAY_SIZE(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,
 };
 
 /*******************************************************************************
@@ -220,3 +538,45 @@ tegra_mc_settings_t *tegra_get_mc_settings(void)
 {
        return &tegra186_mc_settings;
 }
+
+/*******************************************************************************
+ * Handler to program the scratch registers with TZDRAM settings for the
+ * resume firmware
+ ******************************************************************************/
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
+{
+       uint32_t val;
+
+       /*
+        * Setup the Memory controller to allow only secure accesses to
+        * the TZDRAM carveout
+        */
+       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_CFG1_0, size_in_bytes >> 20);
+
+       /*
+        * When TZ encryption is enabled, we need to setup TZDRAM
+        * before CPU accesses TZ Carveout, else CPU will fetch
+        * non-decrypted data. So save TZDRAM setting for SC7 resume
+        * FW to restore.
+        *
+        * Scratch registers map:
+        *  RSV55_0 = CFG1[12:0] | CFG0[31:20]
+        *  RSV55_1 = CFG3[1:0]
+        */
+       val = tegra_mc_read_32(MC_SECURITY_CFG1_0) & MC_SECURITY_SIZE_MB_MASK;
+       val |= tegra_mc_read_32(MC_SECURITY_CFG0_0) & MC_SECURITY_BOM_MASK;
+       mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_LO, val);
+
+       val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK;
+       mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_HI, val);
+
+       /*
+        * MCE propagates the security configuration values across the
+        * CCPLEX.
+        */
+       (void)mce_update_gsc_tzdram();
+}
index fb94bcedf97bdd3231e2918a26ed73eff36e8861..09e257d53fba750cbf6e8a5eebf2e9e225c63f9a 100644 (file)
@@ -12,6 +12,7 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <context.h>
+#include <cortex_a57.h>
 #include <denver.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/psci/psci.h>
 
 #include <mce.h>
 #include <smmu.h>
+#include <stdbool.h>
 #include <t18x_ari.h>
+#include <tegra186_private.h>
 #include <tegra_private.h>
 
 extern void memcpy16(void *dest, const void *src, unsigned int length);
 
-extern void prepare_cpu_pwr_dwn(void);
-extern void tegra186_cpu_reset_handler(void);
-extern uint32_t __tegra186_cpu_reset_handler_end,
-               __tegra186_smmu_context;
-
 /* state id mask */
-#define TEGRA186_STATE_ID_MASK         0xF
+#define TEGRA186_STATE_ID_MASK         0xFU
 /* constants to get power state's wake time */
-#define TEGRA186_WAKE_TIME_MASK                0x0FFFFFF0
-#define TEGRA186_WAKE_TIME_SHIFT       4
+#define TEGRA186_WAKE_TIME_MASK                0x0FFFFFF0U
+#define TEGRA186_WAKE_TIME_SHIFT       4U
 /* default core wake mask for CPU_SUSPEND */
-#define TEGRA186_CORE_WAKE_MASK                0x180c
+#define TEGRA186_CORE_WAKE_MASK                0x180cU
 /* context size to save during system suspend */
-#define TEGRA186_SE_CONTEXT_SIZE       3
+#define TEGRA186_SE_CONTEXT_SIZE       3U
 
 static uint32_t se_regs[TEGRA186_SE_CONTEXT_SIZE];
-static struct t18x_psci_percpu_data {
-       unsigned int wake_time;
-} __aligned(CACHE_WRITEBACK_GRANULE) percpu_data[PLATFORM_CORE_COUNT];
-
-/* System power down state */
-uint32_t tegra186_system_powerdn_state = TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF;
+static struct tegra_psci_percpu_data {
+       uint32_t wake_time;
+} __aligned(CACHE_WRITEBACK_GRANULE) tegra_percpu_data[PLATFORM_CORE_COUNT];
 
-int32_t tegra_soc_validate_power_state(unsigned int power_state,
+int32_t tegra_soc_validate_power_state(uint32_t power_state,
                                        psci_power_state_t *req_state)
 {
-       int state_id = psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK;
-       int cpu = plat_my_core_pos();
+       uint8_t state_id = (uint8_t)psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK;
+       uint32_t cpu = plat_my_core_pos();
+       int32_t ret = PSCI_E_SUCCESS;
 
        /* save the core wake time (in TSC ticks)*/
-       percpu_data[cpu].wake_time = (power_state & TEGRA186_WAKE_TIME_MASK)
+       tegra_percpu_data[cpu].wake_time = (power_state & TEGRA186_WAKE_TIME_MASK)
                        << TEGRA186_WAKE_TIME_SHIFT;
 
        /*
@@ -64,8 +60,8 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
         * from DRAM in that function, because the L2 cache is not flushed
         * unless the cluster is entering CC6/CC7.
         */
-       clean_dcache_range((uint64_t)&percpu_data[cpu],
-                       sizeof(percpu_data[cpu]));
+       clean_dcache_range((uint64_t)&tegra_percpu_data[cpu],
+                       sizeof(tegra_percpu_data[cpu]));
 
        /* Sanity check the requested state id */
        switch (state_id) {
@@ -80,18 +76,19 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
 
        default:
                ERROR("%s: unsupported state id (%d)\n", __func__, state_id);
-               return PSCI_E_INVALID_PARAMS;
+               ret = PSCI_E_INVALID_PARAMS;
+               break;
        }
 
-       return PSCI_E_SUCCESS;
+       return ret;
 }
 
-int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
        const plat_local_state_t *pwr_domain_state;
-       unsigned int stateid_afflvl0, stateid_afflvl2;
-       int cpu = plat_my_core_pos();
-       plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+       uint8_t stateid_afflvl0, stateid_afflvl2;
+       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;
        uint32_t val;
@@ -108,9 +105,9 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 
                /* Enter CPU idle/powerdown */
                val = (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ?
-                       TEGRA_ARI_CORE_C6 : TEGRA_ARI_CORE_C7;
-               (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, val,
-                               percpu_data[cpu].wake_time, 0);
+                       (uint32_t)TEGRA_ARI_CORE_C6 : (uint32_t)TEGRA_ARI_CORE_C7;
+               (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, (uint64_t)val,
+                               tegra_percpu_data[cpu].wake_time, 0U);
 
        } else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
 
@@ -124,121 +121,156 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 
                /* save 'Secure Boot' Processor Feature Config Register */
                val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG);
-               mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV6, val);
+               mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val);
 
                /* save SMMU context to TZDRAM */
                smmu_ctx_base = params_from_bl2->tzdram_base +
-                       ((uintptr_t)&__tegra186_smmu_context -
-                        (uintptr_t)tegra186_cpu_reset_handler);
+                               tegra186_get_smmu_ctx_offset();
                tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
 
                /* Prepare for system suspend */
-               cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
-               cstate_info.system = TEGRA_ARI_SYSTEM_SC7;
+               cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7;
+               cstate_info.system = (uint32_t)TEGRA_ARI_SYSTEM_SC7;
                cstate_info.system_state_force = 1;
                cstate_info.update_wake_mask = 1;
                mce_update_cstate_info(&cstate_info);
 
                /* Loop until system suspend is allowed */
                do {
-                       val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED,
-                                       TEGRA_ARI_CORE_C7,
+                       val = (uint32_t)mce_command_handler(
+                                       (uint64_t)MCE_CMD_IS_SC7_ALLOWED,
+                                       (uint64_t)TEGRA_ARI_CORE_C7,
                                        MCE_CORE_SLEEP_TIME_INFINITE,
-                                       0);
-               } while (val == 0);
+                                       0U);
+               } while (val == 0U);
 
                /* Instruct the MCE to enter system suspend state */
-               (void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
-                       TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0);
+               (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 */
        }
 
        return PSCI_E_SUCCESS;
 }
 
 /*******************************************************************************
- * Platform handler to calculate the proper target power level at the
- * specified affinity level
+ * Helper function to check if this is the last ON CPU in the cluster
  ******************************************************************************/
-plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
-                                            const plat_local_state_t *states,
-                                            unsigned int ncpu)
+static bool tegra_last_cpu_in_cluster(const plat_local_state_t *states,
+                       uint32_t ncpu)
 {
-       plat_local_state_t target = *states;
-       int cpu = plat_my_core_pos(), ret, cluster_powerdn = 1;
-       int core_pos = read_mpidr() & MPIDR_CPU_MASK;
-       mce_cstate_info_t cstate_info = { 0 };
+       plat_local_state_t target;
+       bool last_on_cpu = true;
+       uint32_t num_cpus = ncpu, pos = 0;
+
+       do {
+               target = states[pos];
+               if (target != PLAT_MAX_OFF_STATE) {
+                       last_on_cpu = false;
+               }
+               --num_cpus;
+               pos++;
+       } while (num_cpus != 0U);
 
-       /* get the power state at this level */
-       if (lvl == MPIDR_AFFLVL1)
-               target = *(states + core_pos);
-       if (lvl == MPIDR_AFFLVL2)
-               target = *(states + cpu);
+       return last_on_cpu;
+}
 
-       /* CPU suspend */
-       if (lvl == MPIDR_AFFLVL1 && target == PSTATE_ID_CORE_POWERDN) {
+/*******************************************************************************
+ * Helper function to get target power state for the cluster
+ ******************************************************************************/
+static plat_local_state_t tegra_get_afflvl1_pwr_state(const plat_local_state_t *states,
+                       uint32_t ncpu)
+{
+       uint32_t core_pos = (uint32_t)read_mpidr() & (uint32_t)MPIDR_CPU_MASK;
+       uint32_t cpu = plat_my_core_pos();
+       int32_t ret;
+       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 = TEGRA186_CORE_WAKE_MASK;
                cstate_info.update_wake_mask = 1;
                mce_update_cstate_info(&cstate_info);
 
                /* Check if CCx state is allowed. */
-               ret = mce_command_handler(MCE_CMD_IS_CCX_ALLOWED,
-                               TEGRA_ARI_CORE_C7, percpu_data[cpu].wake_time,
-                               0);
-               if (ret)
-                       return PSTATE_ID_CORE_POWERDN;
+               ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED,
+                               (uint64_t)TEGRA_ARI_CORE_C7,
+                               tegra_percpu_data[cpu].wake_time,
+                               0U);
+               if (ret == 0) {
+                       target = PSCI_LOCAL_STATE_RUN;
+               }
        }
 
        /* CPU off */
-       if (lvl == MPIDR_AFFLVL1 && target == PLAT_MAX_OFF_STATE) {
-
-               /* find out the number of ON cpus in the cluster */
-               do {
-                       target = *states++;
-                       if (target != PLAT_MAX_OFF_STATE)
-                               cluster_powerdn = 0;
-               } while (--ncpu);
-
+       if (target == PLAT_MAX_OFF_STATE) {
                /* Enable cluster powerdn from last CPU in the cluster */
-               if (cluster_powerdn) {
-
+               if (tegra_last_cpu_in_cluster(states, ncpu)) {
                        /* Enable CC7 state and turn off wake mask */
-                       cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
+                       cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7;
                        cstate_info.update_wake_mask = 1;
                        mce_update_cstate_info(&cstate_info);
 
                        /* Check if CCx state is allowed. */
-                       ret = mce_command_handler(MCE_CMD_IS_CCX_ALLOWED,
-                                                 TEGRA_ARI_CORE_C7,
+                       ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED,
+                                                 (uint64_t)TEGRA_ARI_CORE_C7,
                                                  MCE_CORE_SLEEP_TIME_INFINITE,
-                                                 0);
-                       if (ret)
-                               return PSTATE_ID_CORE_POWERDN;
+                                                 0U);
+                       if (ret == 0) {
+                               target = PSCI_LOCAL_STATE_RUN;
+                       }
 
                } else {
 
                        /* Turn off wake_mask */
                        cstate_info.update_wake_mask = 1;
                        mce_update_cstate_info(&cstate_info);
+                       target = PSCI_LOCAL_STATE_RUN;
                }
        }
 
+       return target;
+}
+
+/*******************************************************************************
+ * Platform handler to calculate the proper target power level at the
+ * specified affinity level
+ ******************************************************************************/
+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 = PSCI_LOCAL_STATE_RUN;
+       uint32_t cpu = plat_my_core_pos();
+
        /* System Suspend */
-       if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
-           (target == PSTATE_ID_SOC_POWERDN))
-               return PSTATE_ID_SOC_POWERDN;
+       if ((lvl == (uint32_t)MPIDR_AFFLVL2) &&
+           (states[cpu] == PSTATE_ID_SOC_POWERDN)) {
+               target = PSTATE_ID_SOC_POWERDN;
+       }
 
-       /* default state */
-       return PSCI_LOCAL_STATE_RUN;
+       /* CPU off, CPU suspend */
+       if (lvl == (uint32_t)MPIDR_AFFLVL1) {
+               target = tegra_get_afflvl1_pwr_state(states, ncpu);
+       }
+
+       /* target cluster/system state */
+       return target;
 }
 
-int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
 {
        const plat_local_state_t *pwr_domain_state =
                target_state->pwr_domain_state;
-       plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
-       unsigned int stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
+       const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+       uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
                TEGRA186_STATE_ID_MASK;
        uint64_t val;
 
@@ -249,8 +281,7 @@ int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
                 * BL3-1 over to TZDRAM.
                 */
                val = params_from_bl2->tzdram_base +
-                       ((uintptr_t)&__tegra186_cpu_reset_handler_end -
-                        (uintptr_t)tegra186_cpu_reset_handler);
+                       tegra186_get_cpu_reset_handler_size();
                memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
                         (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE);
        }
@@ -258,30 +289,48 @@ int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
        return PSCI_E_SUCCESS;
 }
 
-int tegra_soc_pwr_domain_on(u_register_t mpidr)
+int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
 {
-       uint32_t target_cpu = mpidr & MPIDR_CPU_MASK;
-       uint32_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >>
+       int32_t ret = PSCI_E_SUCCESS;
+       uint64_t target_cpu = mpidr & MPIDR_CPU_MASK;
+       uint64_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >>
                        MPIDR_AFFINITY_BITS;
 
-       if (target_cluster > MPIDR_AFFLVL1) {
+       if (target_cluster > ((uint32_t)PLATFORM_CLUSTER_COUNT - 1U)) {
+
                ERROR("%s: unsupported CPU (0x%lx)\n", __func__, mpidr);
-               return PSCI_E_NOT_PRESENT;
-       }
+               ret = PSCI_E_NOT_PRESENT;
 
-       /* construct the target CPU # */
-       target_cpu |= (target_cluster << 2);
+       } else {
+               /* construct the target CPU # */
+               target_cpu |= (target_cluster << 2);
 
-       mce_command_handler(MCE_CMD_ONLINE_CORE, target_cpu, 0, 0);
+               (void)mce_command_handler((uint64_t)MCE_CMD_ONLINE_CORE, target_cpu, 0U, 0U);
+       }
 
-       return PSCI_E_SUCCESS;
+       return ret;
 }
 
-int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
-       int stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
-       int stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0];
+       uint8_t stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
+       uint8_t stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0];
        mce_cstate_info_t cstate_info = { 0 };
+       uint64_t impl, val;
+       const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+
+       impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+
+       /*
+        * Enable ECC and Parity Protection for Cortex-A57 CPUs (Tegra186
+        * A02p and beyond).
+        */
+       if ((plat_params->l2_ecc_parity_prot_dis != 1) && (impl != DENVER_IMPL)) {
+
+               val = read_l2ctlr_el1();
+               val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
+               write_l2ctlr_el1(val);
+       }
 
        /*
         * Reset power state info for CPUs when onlining, we set
@@ -292,7 +341,7 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
         */
        if (stateid_afflvl0 == PLAT_MAX_OFF_STATE) {
 
-               cstate_info.cluster = TEGRA_ARI_CLUSTER_CC1;
+               cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC1;
                cstate_info.update_wake_mask = 1;
                mce_update_cstate_info(&cstate_info);
        }
@@ -319,8 +368,8 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
                 * and SC7 for SC7 entry which may not be requested by
                 * non-secure SW which controls idle states.
                 */
-               cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
-               cstate_info.system = TEGRA_ARI_SYSTEM_SC1;
+               cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7;
+               cstate_info.system = (uint32_t)TEGRA_ARI_SYSTEM_SC1;
                cstate_info.update_wake_mask = 1;
                mce_update_cstate_info(&cstate_info);
        }
@@ -328,65 +377,28 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
        return PSCI_E_SUCCESS;
 }
 
-int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
-       int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+       uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+
+       (void)target_state;
 
        /* Disable Denver's DCO operations */
-       if (impl == DENVER_IMPL)
+       if (impl == DENVER_IMPL) {
                denver_disable_dco();
+       }
 
        /* Turn off CPU */
-       (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7,
-                       MCE_CORE_SLEEP_TIME_INFINITE, 0);
+       (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
+                       (uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
 
        return PSCI_E_SUCCESS;
 }
 
 __dead2 void tegra_soc_prepare_system_off(void)
 {
-       mce_cstate_info_t cstate_info = { 0 };
-       uint32_t val;
-
-       if (tegra186_system_powerdn_state == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) {
-
-               /* power off the entire system */
-               mce_enter_ccplex_state(tegra186_system_powerdn_state);
-
-       } else if (tegra186_system_powerdn_state == TEGRA_ARI_SYSTEM_SC8) {
-
-               /* Prepare for quasi power down */
-               cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
-               cstate_info.system = TEGRA_ARI_SYSTEM_SC8;
-               cstate_info.system_state_force = 1;
-               cstate_info.update_wake_mask = 1;
-               mce_update_cstate_info(&cstate_info);
-
-               /* loop until other CPUs power down */
-               do {
-                       val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED,
-                                       TEGRA_ARI_CORE_C7,
-                                       MCE_CORE_SLEEP_TIME_INFINITE,
-                                       0);
-               } while (val == 0);
-
-               /* Enter quasi power down state */
-               (void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
-                       TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0);
-
-               /* disable GICC */
-               tegra_gic_cpuif_deactivate();
-
-               /* power down core */
-               prepare_cpu_pwr_dwn();
-
-               /* flush L1/L2 data caches */
-               dcsw_op_all(DCCISW);
-
-       } else {
-               ERROR("%s: unsupported power down state (%d)\n", __func__,
-                       tegra186_system_powerdn_state);
-       }
+       /* power off the entire system */
+       mce_enter_ccplex_state((uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF);
 
        wfi();
 
@@ -396,9 +408,9 @@ __dead2 void tegra_soc_prepare_system_off(void)
        }
 }
 
-int tegra_soc_prepare_system_reset(void)
+int32_t tegra_soc_prepare_system_reset(void)
 {
-       mce_enter_ccplex_state(TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT);
+       mce_enter_ccplex_state((uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT);
 
        return PSCI_E_SUCCESS;
 }
index 4485e2733a034a2c1eeb94ecf7d7c325ef17e276..16508093ea2de2b4919d0a07fb6a2b49e2767f56 100644 (file)
 #include <lib/mmio.h>
 
 #include <mce.h>
+#include <tegra186_private.h>
 #include <tegra_def.h>
 #include <tegra_private.h>
 
-#define MISCREG_CPU_RESET_VECTOR       0x2000
-#define MISCREG_AA64_RST_LOW           0x2004
-#define MISCREG_AA64_RST_HIGH          0x2008
+#define MISCREG_AA64_RST_LOW           0x2004U
+#define MISCREG_AA64_RST_HIGH          0x2008U
 
-#define SCRATCH_SECURE_RSV1_SCRATCH_0  0x658
-#define SCRATCH_SECURE_RSV1_SCRATCH_1  0x65C
+#define SCRATCH_SECURE_RSV1_SCRATCH_0  0x658U
+#define SCRATCH_SECURE_RSV1_SCRATCH_1  0x65CU
 
-#define CPU_RESET_MODE_AA64            1
+#define CPU_RESET_MODE_AA64            1U
 
 extern void memcpy16(void *dest, const void *src, unsigned int length);
 
-extern uint64_t tegra_bl31_phys_base;
-extern uint64_t __tegra186_cpu_reset_handler_end;
-
 /*******************************************************************************
  * Setup secondary CPU vectors
  ******************************************************************************/
 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;
+       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");
 
-       if ((tegra_bl31_phys_base >= TEGRA_TZRAM_BASE) &&
-           (tegra_bl31_phys_base <= (TEGRA_TZRAM_BASE + TEGRA_TZRAM_SIZE))) {
-
-               /*
-                * 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 = params_from_bl2->tzdram_base;
-               memcpy16((void *)((uintptr_t)cpu_reset_handler_base),
-                        (void *)(uintptr_t)tegra186_cpu_reset_handler,
-                        (uintptr_t)&__tegra186_cpu_reset_handler_end -
-                        (uintptr_t)tegra186_cpu_reset_handler);
-
-       } else {
-               cpu_reset_handler_base = (uintptr_t)tegra_secure_entrypoint;
-       }
-
-       addr_low = (uint32_t)cpu_reset_handler_base | CPU_RESET_MODE_AA64;
-       addr_high = (uint32_t)((cpu_reset_handler_base >> 32) & 0x7ff);
+       /*
+        * 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);
 
        /* save reset vector to be used during SYSTEM_SUSPEND exit */
-       mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_0,
+       mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO,
                        addr_low);
-       mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_1,
+       mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI,
                        addr_high);
 
        /* update reset vector address to the CCPLEX */
-       mce_update_reset_vector();
+       (void)mce_update_reset_vector();
 }
index 15dbd163907db3f12c54baddbebb6afb55460b30..fd109e563a4517989259f21a5abe69a2972057f0 100644 (file)
 #include <tegra_platform.h>
 #include <tegra_private.h>
 
-DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, CORTEX_A57_L2CTLR_EL1)
-extern uint64_t tegra_enable_l2_ecc_parity_prot;
-
 /*******************************************************************************
  * Tegra186 CPU numbers in cluster #0
  *******************************************************************************
  */
-#define TEGRA186_CLUSTER0_CORE2                2
-#define TEGRA186_CLUSTER0_CORE3                3
+#define TEGRA186_CLUSTER0_CORE2                2U
+#define TEGRA186_CLUSTER0_CORE3                3U
 
 /*******************************************************************************
  * The Tegra power domain tree has a single system level power domain i.e. a
@@ -43,7 +40,7 @@ extern uint64_t tegra_enable_l2_ecc_parity_prot;
  * the number of power domains at the highest power level.
  *******************************************************************************
  */
-const unsigned char tegra_power_domain_tree_desc[] = {
+static const uint8_t tegra_power_domain_tree_desc[] = {
        /* No of root nodes */
        1,
        /* No of clusters */
@@ -54,45 +51,53 @@ const unsigned char tegra_power_domain_tree_desc[] = {
        PLATFORM_MAX_CPUS_PER_CLUSTER
 };
 
+/*******************************************************************************
+ * This function returns the Tegra default topology tree information.
+ ******************************************************************************/
+const uint8_t *plat_get_power_domain_tree_desc(void)
+{
+       return tegra_power_domain_tree_desc;
+}
+
 /*
  * Table of regions to map using the MMU.
  */
 static const mmap_region_t tegra_mmap[] = {
-       MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000, /* 64KB */
+       MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000U, /* 64KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000, /* 128KB */
+       MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000U, /* 128KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000, /* 64KB */
+       MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000U, /* 64KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000, /* 64KB */
+       MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000U, /* 64KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB - UART A, B*/
+       MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000U, /* 128KB - UART A, B*/
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000, /* 128KB - UART C, G */
+       MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000U, /* 128KB - UART C, G */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000, /* 192KB - UART D, E, F */
+       MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000U, /* 192KB - UART D, E, F */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000, /* 64KB */
+       MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000U, /* 64KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000, /* 128KB */
+       MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000U, /* 128KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000, /* 64KB */
+       MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000U, /* 64KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x10000, /* 64KB */
+       MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x10000U, /* 64KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000, /* 64KB */
+       MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000U, /* 64KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000, /* 64KB */
+       MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000U, /* 64KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000, /* 256KB */
+       MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000U, /* 256KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000, /* 64KB */
+       MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000U, /* 64KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000, /* 384KB */
+       MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000U, /* 384KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_ARM_ACTMON_CTR_BASE, 0x20000, /* 128KB - ARM/Denver */
+       MAP_REGION_FLAT(TEGRA_ARM_ACTMON_CTR_BASE, 0x20000U, /* 128KB - ARM/Denver */
                        MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000, /* 64KB */
+       MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000U, /* 64KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
        {0}
 };
@@ -109,7 +114,7 @@ const mmap_region_t *plat_get_mmio_map(void)
 /*******************************************************************************
  * Handler to get the System Counter Frequency
  ******************************************************************************/
-unsigned int plat_get_syscnt_freq2(void)
+uint32_t plat_get_syscnt_freq2(void)
 {
        return 31250000;
 }
@@ -136,56 +141,42 @@ static uint32_t tegra186_uart_addresses[TEGRA186_MAX_UART_PORTS + 1] = {
 /*******************************************************************************
  * Retrieve the UART controller base to be used as the console
  ******************************************************************************/
-uint32_t plat_get_console_from_id(int id)
+uint32_t plat_get_console_from_id(int32_t id)
 {
-       if (id > TEGRA186_MAX_UART_PORTS)
-               return 0;
+       uint32_t ret;
 
-       return tegra186_uart_addresses[id];
-}
+       if (id > TEGRA186_MAX_UART_PORTS) {
+               ret = 0;
+       } else {
+               ret = tegra186_uart_addresses[id];
+       }
 
-/* represent chip-version as concatenation of major (15:12), minor (11:8) and subrev (7:0) */
-#define TEGRA186_VER_A02P      0x1201
+       return ret;
+}
 
 /*******************************************************************************
  * Handler for early platform setup
  ******************************************************************************/
 void plat_early_platform_setup(void)
 {
-       int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
-       uint32_t chip_subrev, val;
+       uint64_t impl, val;
+       const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
 
        /* sanity check MCE firmware compatibility */
        mce_verify_firmware_version();
 
+       impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+
        /*
-        * Enable ECC and Parity Protection for Cortex-A57 CPUs
-        * for Tegra A02p SKUs
+        * Enable ECC and Parity Protection for Cortex-A57 CPUs (Tegra186
+        * A02p and beyond).
         */
-       if (impl != DENVER_IMPL) {
-
-               /* get the major, minor and sub-version values */
-               chip_subrev = mmio_read_32(TEGRA_FUSE_BASE + OPT_SUBREVISION) &
-                             SUBREVISION_MASK;
-
-               /* prepare chip version number */
-               val = (tegra_get_chipid_major() << 12) |
-                     (tegra_get_chipid_minor() << 8) |
-                      chip_subrev;
+       if ((plat_params->l2_ecc_parity_prot_dis != 1) &&
+           (impl != (uint64_t)DENVER_IMPL)) {
 
-               /* enable L2 ECC for Tegra186 A02P and beyond */
-               if (val >= TEGRA186_VER_A02P) {
-
-                       val = read_l2ctlr_el1();
-                       val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
-                       write_l2ctlr_el1(val);
-
-                       /*
-                        * Set the flag to enable ECC/Parity Protection
-                        * when we exit System Suspend or Cluster Powerdn
-                        */
-                       tegra_enable_l2_ecc_parity_prot = 1;
-               }
+               val = read_l2ctlr_el1();
+               val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
+               write_l2ctlr_el1(val);
        }
 }
 
@@ -208,8 +199,9 @@ void plat_gic_setup(void)
         * Initialize the FIQ handler only if the platform supports any
         * FIQ interrupt sources.
         */
-       if (sizeof(tegra186_interrupt_props) > 0)
+       if (sizeof(tegra186_interrupt_props) > 0U) {
                tegra_fiq_handler_setup();
+       }
 }
 
 /*******************************************************************************
@@ -219,7 +211,7 @@ struct tegra_bl31_params *plat_get_bl31_params(void)
 {
        uint32_t val;
 
-       val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_LO);
+       val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PARAMS_ADDR);
 
        return (struct tegra_bl31_params *)(uintptr_t)val;
 }
@@ -231,7 +223,7 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
 {
        uint32_t val;
 
-       val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_HI);
+       val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PLAT_PARAMS_ADDR);
 
        return (plat_params_from_bl2_t *)(uintptr_t)val;
 }
@@ -242,33 +234,34 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
  * 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)
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
 {
-       unsigned int cluster_id, cpu_id, pos;
+       u_register_t cluster_id, cpu_id, pos;
+       int32_t ret;
 
-       cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-       cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+       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;
 
        /*
         * Validate cluster_id by checking whether it represents
         * one of the two clusters present on the platform.
-        */
-       if (cluster_id >= PLATFORM_CLUSTER_COUNT)
-               return 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 >= PLATFORM_MAX_CPUS_PER_CLUSTER)
-               return PSCI_E_NOT_PRESENT;
-
-       /* calculate the core position */
-       pos = cpu_id + (cluster_id << 2);
-
-       /* check for non-existent CPUs */
-       if (pos == TEGRA186_CLUSTER0_CORE2 || pos == TEGRA186_CLUSTER0_CORE3)
-               return PSCI_E_NOT_PRESENT;
+       if ((cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) ||
+           (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER)) {
+               ret = PSCI_E_NOT_PRESENT;
+       } else {
+               /* calculate the core position */
+               pos = cpu_id + (cluster_id << 2U);
+
+               /* check for non-existent CPUs */
+               if ((pos == TEGRA186_CLUSTER0_CORE2) || (pos == TEGRA186_CLUSTER0_CORE3)) {
+                       ret = PSCI_E_NOT_PRESENT;
+               } else {
+                       ret = (int32_t)pos;
+               }
+       }
 
-       return pos;
+       return ret;
 }
index bf98fcf648b6c3599513bfa47406379b1b33b43a..4de8a9efb9a987f261bd717d6ee4d81e73546e4f 100644 (file)
 #include <t18x_ari.h>
 #include <tegra_private.h>
 
-extern uint32_t tegra186_system_powerdn_state;
-
 /*******************************************************************************
  * Offset to read the ref_clk counter value
  ******************************************************************************/
-#define REF_CLK_OFFSET         4
+#define REF_CLK_OFFSET         4ULL
 
 /*******************************************************************************
  * Tegra186 SiP SMCs
  ******************************************************************************/
-#define TEGRA_SIP_SYSTEM_SHUTDOWN_STATE                        0xC2FFFE01
 #define TEGRA_SIP_GET_ACTMON_CLK_COUNTERS              0xC2FFFE02
 #define TEGRA_SIP_MCE_CMD_ENTER_CSTATE                 0xC2FFFF00
 #define TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO           0xC2FFFF01
@@ -38,7 +35,7 @@ extern uint32_t tegra186_system_powerdn_state;
 #define TEGRA_SIP_MCE_CMD_READ_CSTATE_STATS            0xC2FFFF03
 #define TEGRA_SIP_MCE_CMD_WRITE_CSTATE_STATS           0xC2FFFF04
 #define TEGRA_SIP_MCE_CMD_IS_SC7_ALLOWED               0xC2FFFF05
-#define TEGRA_SIP_MCE_CMD_ONLINE_CORE                  0xC2FFFF06
+
 #define TEGRA_SIP_MCE_CMD_CC3_CTRL                     0xC2FFFF07
 #define TEGRA_SIP_MCE_CMD_ECHO_DATA                    0xC2FFFF08
 #define TEGRA_SIP_MCE_CMD_READ_VERSIONS                        0xC2FFFF09
@@ -55,33 +52,39 @@ extern uint32_t tegra186_system_powerdn_state;
 /*******************************************************************************
  * This function is responsible for handling all T186 SiP calls
  ******************************************************************************/
-int plat_sip_handler(uint32_t smc_fid,
+int32_t plat_sip_handler(uint32_t smc_fid,
                     uint64_t x1,
                     uint64_t x2,
                     uint64_t x3,
                     uint64_t x4,
-                    void *cookie,
+                    const void *cookie,
                     void *handle,
                     uint64_t flags)
 {
-       int mce_ret;
-       int impl, cpu;
+       int32_t mce_ret, ret = 0;
+       uint32_t impl, cpu;
        uint32_t base, core_clk_ctr, ref_clk_ctr;
+       uint32_t local_smc_fid = smc_fid;
+       uint64_t local_x1 = x1, local_x2 = x2, local_x3 = x3;
+
+       (void)x4;
+       (void)cookie;
+       (void)flags;
 
        if (((smc_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_32) {
                /* 32-bit function, clear top parameter bits */
 
-               x1 = (uint32_t)x1;
-               x2 = (uint32_t)x2;
-               x3 = (uint32_t)x3;
+               local_x1 = (uint32_t)x1;
+               local_x2 = (uint32_t)x2;
+               local_x3 = (uint32_t)x3;
        }
 
        /*
         * Convert SMC FID to SMC64, to support SMC32/SMC64 configurations
         */
-       smc_fid |= (SMC_64 << FUNCID_CC_SHIFT);
+       local_smc_fid |= (SMC_64 << FUNCID_CC_SHIFT);
 
-       switch (smc_fid) {
+       switch (local_smc_fid) {
        /*
         * Micro Coded Engine (MCE) commands reside in the 0x82FFFF00 -
         * 0x82FFFFFF SiP SMC space
@@ -106,41 +109,13 @@ int plat_sip_handler(uint32_t smc_fid,
        case TEGRA_SIP_MCE_CMD_MISC_CCPLEX:
 
                /* clean up the high bits */
-               smc_fid &= MCE_CMD_MASK;
+               local_smc_fid &= MCE_CMD_MASK;
 
                /* execute the command and store the result */
-               mce_ret = mce_command_handler(smc_fid, x1, x2, x3);
-               write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X0,
-                             (uint64_t)mce_ret);
-
-               return 0;
-
-       case TEGRA_SIP_SYSTEM_SHUTDOWN_STATE:
-
-               /* clean up the high bits */
-               x1 = (uint32_t)x1;
-
-               /*
-                * SC8 is a special Tegra186 system state where the CPUs and
-                * DRAM are powered down but the other subsystem is still
-                * alive.
-                */
-               if ((x1 == TEGRA_ARI_SYSTEM_SC8) ||
-                   (x1 == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF)) {
-
-                       tegra186_system_powerdn_state = x1;
-                       flush_dcache_range(
-                               (uintptr_t)&tegra186_system_powerdn_state,
-                               sizeof(tegra186_system_powerdn_state));
-
-               } else {
-
-                       ERROR("%s: unhandled powerdn state (%d)\n", __func__,
-                               (uint32_t)x1);
-                       return -ENOTSUP;
-               }
-
-               return 0;
+               mce_ret = mce_command_handler(local_smc_fid, local_x1, local_x2, local_x3);
+               write_ctx_reg(get_gpregs_ctx(handle),
+                             CTX_GPREG_X0, (uint64_t)(mce_ret));
+               break;
 
        /*
         * This function ID reads the Activity monitor's core/ref clock
@@ -155,28 +130,30 @@ int plat_sip_handler(uint32_t smc_fid,
                impl = ((uint32_t)x2 >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
 
                /* sanity check target CPU number */
-               if (cpu > PLATFORM_MAX_CPUS_PER_CLUSTER)
-                       return -EINVAL;
-
-               /* get the base address for the current CPU */
-               base = (impl == DENVER_IMPL) ? TEGRA_DENVER_ACTMON_CTR_BASE :
-                       TEGRA_ARM_ACTMON_CTR_BASE;
-
-               /* read the clock counter values */
-               core_clk_ctr = mmio_read_32(base + (8 * cpu));
-               ref_clk_ctr = mmio_read_32(base + (8 * cpu) + REF_CLK_OFFSET);
-
-               /* return the counter values as two different parameters */
-               write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1,
-                             (uint64_t)core_clk_ctr);
-               write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X2,
-                             (uint64_t)ref_clk_ctr);
+               if (cpu > (uint32_t)PLATFORM_MAX_CPUS_PER_CLUSTER) {
+                       ret = -EINVAL;
+               } else {
+                       /* get the base address for the current CPU */
+                       base = (impl == DENVER_IMPL) ? TEGRA_DENVER_ACTMON_CTR_BASE :
+                               TEGRA_ARM_ACTMON_CTR_BASE;
+
+                       /* read the clock counter values */
+                       core_clk_ctr = mmio_read_32(base + (8ULL * cpu));
+                       ref_clk_ctr = mmio_read_32(base + (8ULL * cpu) + REF_CLK_OFFSET);
+
+                       /* return the counter values as two different parameters */
+                       write_ctx_reg(get_gpregs_ctx(handle),
+                                     CTX_GPREG_X1, (core_clk_ctr));
+                       write_ctx_reg(get_gpregs_ctx(handle),
+                                     CTX_GPREG_X2, (ref_clk_ctr));
+               }
 
-               return 0;
+               break;
 
        default:
+               ret = -ENOTSUP;
                break;
        }
 
-       return -ENOTSUP;
+       return ret;
 }
index 19e065c18dfd81fdcd678871aa37a2f3633d7670..95f6def9be4a8a62c965059fd3e6c13da7ff1377 100644 (file)
@@ -8,6 +8,9 @@
 
 #include <smmu.h>
 #include <tegra_def.h>
+#include <tegra_mc_def.h>
+
+#define MAX_NUM_SMMU_DEVICES   U(1)
 
 /*******************************************************************************
  * Array to hold SMMU context for Tegra186
@@ -305,7 +308,15 @@ static __attribute__((aligned(16))) smmu_regs_t tegra186_smmu_context[] = {
 smmu_regs_t *plat_get_smmu_ctx(void)
 {
        /* index of _END_OF_TABLE_ */
-       tegra186_smmu_context[0].val = ARRAY_SIZE(tegra186_smmu_context) - 1;
+       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)
+{
+       return MAX_NUM_SMMU_DEVICES;
+}
index 69ca798f9c8dbebf6e066ead2d8435f61cfc74c7..e3393e90ea524b862ae9bb32a5ec65ae5336ac8c 100644 (file)
 #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
 
        .globl  tegra186_cpu_reset_handler
 
 /* CPU reset handler routine */
 func tegra186_cpu_reset_handler _align=4
-       /*
-        * The TZRAM loses state during System Suspend. We use this
-        * information to decide if the reset handler is running after a
-        * System Suspend. Resume from system suspend requires restoring
-        * the entire state from TZDRAM to TZRAM.
-        */
-       mov     x0, #BL31_BASE
-       ldr     x0, [x0]
-       cbnz    x0, boot_cpu
+       /* 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
 
-       /* resume from system suspend */
+       /* 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
@@ -69,6 +78,12 @@ endfunc tegra186_cpu_reset_handler
 __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
@@ -80,3 +95,50 @@ __tegra186_smmu_context:
        .align 4
        .globl  __tegra186_cpu_reset_handler_end
 __tegra186_cpu_reset_handler_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
+       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
index c9053238bc5edfacfd58a34cbbb20886fabce1f2..fdeb886cda3015f16674a6e506e9a4152957f600 100644 (file)
@@ -11,18 +11,9 @@ $(eval $(call add_define,ENABLE_AFI_DEVICE))
 ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS        := 1
 $(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS))
 
-RELOCATE_TO_BL31_BASE                  := 1
-$(eval $(call add_define,RELOCATE_TO_BL31_BASE))
-
 ENABLE_CHIP_VERIFICATION_HARNESS       := 0
 $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS))
 
-ENABLE_SMMU_DEVICE                     := 1
-$(eval $(call add_define,ENABLE_SMMU_DEVICE))
-
-NUM_SMMU_DEVICES                       := 1
-$(eval $(call add_define,NUM_SMMU_DEVICES))
-
 RESET_TO_BL31                          := 1
 
 PROGRAMMABLE_RESET_ADDRESS             := 1
@@ -48,8 +39,10 @@ $(eval $(call add_define,MAX_MMAP_REGIONS))
 # platform files
 PLAT_INCLUDES          +=      -I${SOC_DIR}/drivers/include
 
-BL31_SOURCES           +=      lib/cpus/aarch64/denver.S               \
+BL31_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       \
                                ${SOC_DIR}/drivers/mce/mce.c            \
@@ -64,3 +57,13 @@ BL31_SOURCES         +=      lib/cpus/aarch64/denver.S               \
                                ${SOC_DIR}/plat_smmu.c                  \
                                ${SOC_DIR}/plat_trampoline.S
 
+# Enable workarounds for selected Cortex-A57 erratas.
+A57_DISABLE_NON_TEMPORAL_HINT  :=      1
+ERRATA_A57_806969              :=      1
+ERRATA_A57_813419              :=      1
+ERRATA_A57_813420              :=      1
+ERRATA_A57_826974              :=      1
+ERRATA_A57_826977              :=      1
+ERRATA_A57_828024              :=      1
+ERRATA_A57_829520              :=      1
+ERRATA_A57_833471              :=      1
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
new file mode 100644 (file)
index 0000000..be1f9cc
--- /dev/null
@@ -0,0 +1,659 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SE_PRIVATE_H
+#define SE_PRIVATE_H
+
+#include <stdbool.h>
+#include <security_engine.h>
+
+/*
+ * PMC registers
+ */
+
+/* Secure scratch registers */
+#define PMC_SECURE_SCRATCH4_OFFSET             0xC0U
+#define PMC_SECURE_SCRATCH5_OFFSET             0xC4U
+#define PMC_SECURE_SCRATCH6_OFFSET             0x224U
+#define PMC_SECURE_SCRATCH7_OFFSET             0x228U
+#define PMC_SECURE_SCRATCH116_OFFSET           0xB28U
+#define PMC_SECURE_SCRATCH117_OFFSET           0xB2CU
+#define PMC_SECURE_SCRATCH120_OFFSET           0xB38U
+#define PMC_SECURE_SCRATCH121_OFFSET           0xB3CU
+#define PMC_SECURE_SCRATCH122_OFFSET           0xB40U
+#define PMC_SECURE_SCRATCH123_OFFSET           0xB44U
+
+/*
+ * AHB arbitration memory write queue
+ */
+#define ARAHB_MEM_WRQUE_MST_ID_OFFSET          0xFCU
+#define ARAHB_MST_ID_SE2_MASK                  (0x1U << 13)
+#define ARAHB_MST_ID_SE_MASK                   (0x1U << 14)
+
+/**
+ * SE registers
+ */
+#define TEGRA_SE_AES_KEYSLOT_COUNT             16
+#define SE_MAX_LAST_BLOCK_SIZE                 0xFFFFF
+
+/* SE Status register */
+#define SE_STATUS_OFFSET                       0x800U
+#define SE_STATUS_SHIFT                                0
+#define SE_STATUS_IDLE \
+               ((0U) << SE_STATUS_SHIFT)
+#define SE_STATUS_BUSY \
+               ((1U) << SE_STATUS_SHIFT)
+#define SE_STATUS(x)   \
+               ((x) & ((0x3U) << SE_STATUS_SHIFT))
+
+#define SE_MEM_INTERFACE_SHIFT                 2
+#define SE_MEM_INTERFACE_IDLE                  0
+#define SE_MEM_INTERFACE_BUSY                  1
+#define SE_MEM_INTERFACE(x)    ((x) << SE_STATUS_SHIFT)
+
+/* SE register definitions */
+#define SE_SECURITY_REG_OFFSET                 0x0
+#define SE_SECURITY_TZ_LOCK_SOFT_SHIFT         5
+#define SE_SECURE                              0x0
+#define SE_SECURITY_TZ_LOCK_SOFT(x)    ((x) << SE_SECURITY_TZ_LOCK_SOFT_SHIFT)
+
+#define SE_SEC_ENG_DIS_SHIFT                   1
+#define SE_DISABLE_FALSE                       0
+#define SE_DISABLE_TRUE                                1
+#define SE_SEC_ENG_DISABLE(x)((x) << SE_SEC_ENG_DIS_SHIFT)
+
+/* SE config register */
+#define SE_CONFIG_REG_OFFSET                   0x14U
+#define SE_CONFIG_ENC_ALG_SHIFT                12
+#define SE_CONFIG_ENC_ALG_AES_ENC      \
+               ((1U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG_RNG  \
+               ((2U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG_SHA  \
+               ((3U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG_RSA  \
+               ((4U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG_NOP  \
+               ((0U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG(x)   \
+               ((x) & ((0xFU) << SE_CONFIG_ENC_ALG_SHIFT))
+
+#define SE_CONFIG_DEC_ALG_SHIFT                8
+#define SE_CONFIG_DEC_ALG_AES  \
+               ((1U) << SE_CONFIG_DEC_ALG_SHIFT)
+#define SE_CONFIG_DEC_ALG_NOP  \
+               ((0U) << SE_CONFIG_DEC_ALG_SHIFT)
+#define SE_CONFIG_DEC_ALG(x)   \
+               ((x) & ((0xFU) << SE_CONFIG_DEC_ALG_SHIFT))
+
+#define SE_CONFIG_DST_SHIFT                    2
+#define SE_CONFIG_DST_MEMORY   \
+               ((0U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST_HASHREG  \
+               ((1U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST_KEYTAB   \
+               ((2U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST_SRK      \
+               ((3U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST_RSAREG   \
+               ((4U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST(x)       \
+               ((x) & ((0x7U) << SE_CONFIG_DST_SHIFT))
+
+#define SE_CONFIG_ENC_MODE_SHIFT               24
+#define SE_CONFIG_ENC_MODE_KEY128      \
+                       ((0UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_KEY192      \
+                       ((1UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_KEY256      \
+                       ((2UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA1                                \
+                       ((0UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA224      \
+                       ((4UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA256      \
+                       ((5UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA384      \
+                       ((6UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA512      \
+                       ((7UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE(x)\
+                       ((x) & ((0xFFUL) << SE_CONFIG_ENC_MODE_SHIFT))
+
+#define SE_CONFIG_DEC_MODE_SHIFT               16
+#define SE_CONFIG_DEC_MODE_KEY128      \
+                       ((0UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_KEY192      \
+                       ((1UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_KEY256      \
+                       ((2UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA1                                \
+                       ((0UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA224      \
+                       ((4UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA256      \
+                       ((5UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA384      \
+                       ((6UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA512      \
+                       ((7UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE(x)\
+                       ((x) & ((0xFFUL) << SE_CONFIG_DEC_MODE_SHIFT))
+
+
+/* DRBG random number generator config */
+#define SE_RNG_CONFIG_REG_OFFSET               0x340
+
+#define DRBG_MODE_SHIFT                                0
+#define DRBG_MODE_NORMAL               \
+               ((0U) << DRBG_MODE_SHIFT)
+#define DRBG_MODE_FORCE_INSTANTION  \
+               ((1U) << DRBG_MODE_SHIFT)
+#define DRBG_MODE_FORCE_RESEED   \
+               ((2U) << DRBG_MODE_SHIFT)
+#define SE_RNG_CONFIG_MODE(x)   \
+               ((x) & ((0x3U) << DRBG_MODE_SHIFT))
+
+#define DRBG_SRC_SHIFT                         2
+#define DRBG_SRC_NONE     \
+               ((0U) << DRBG_SRC_SHIFT)
+#define DRBG_SRC_ENTROPY       \
+               ((1U) << DRBG_SRC_SHIFT)
+#define DRBG_SRC_LFSR     \
+               ((2U) << DRBG_SRC_SHIFT)
+#define SE_RNG_SRC_CONFIG_MODE(x)   \
+               ((x) & ((0x3U) << DRBG_SRC_SHIFT))
+
+/* DRBG random number generator entropy config */
+
+#define SE_RNG_SRC_CONFIG_REG_OFFSET           0x344U
+
+#define DRBG_RO_ENT_SRC_SHIFT                  1
+#define DRBG_RO_ENT_SRC_ENABLE \
+               ((1U) << DRBG_RO_ENT_SRC_SHIFT)
+#define DRBG_RO_ENT_SRC_DISABLE        \
+               ((0U) << DRBG_RO_ENT_SRC_SHIFT)
+#define SE_RNG_SRC_CONFIG_RO_ENT_SRC(x)        \
+               ((x) & ((0x1U) << DRBG_RO_ENT_SRC_SHIFT))
+
+#define DRBG_RO_ENT_SRC_LOCK_SHIFT             0
+#define DRBG_RO_ENT_SRC_LOCK_ENABLE    \
+               ((1U) << DRBG_RO_ENT_SRC_LOCK_SHIFT)
+#define DRBG_RO_ENT_SRC_LOCK_DISABLE   \
+               ((0U) << DRBG_RO_ENT_SRC_LOCK_SHIFT)
+#define SE_RNG_SRC_CONFIG_RO_ENT_SRC_LOCK(x)   \
+               ((x) & ((0x1U) << DRBG_RO_ENT_SRC_LOCK_SHIFT))
+
+#define DRBG_RO_ENT_IGNORE_MEM_SHIFT           12
+#define DRBG_RO_ENT_IGNORE_MEM_ENABLE  \
+               ((1U) << DRBG_RO_ENT_IGNORE_MEM_SHIFT)
+#define DRBG_RO_ENT_IGNORE_MEM_DISABLE \
+               ((0U) << DRBG_RO_ENT_IGNORE_MEM_SHIFT)
+#define SE_RNG_SRC_CONFIG_RO_ENT_IGNORE_MEM(x) \
+               ((x) & ((0x1U) << DRBG_RO_ENT_IGNORE_MEM_SHIFT))
+
+#define SE_RNG_RESEED_INTERVAL_REG_OFFSET      0x348
+
+/* SE CRYPTO */
+#define SE_CRYPTO_REG_OFFSET                   0x304
+#define SE_CRYPTO_HASH_SHIFT                   0
+#define SE_CRYPTO_HASH_DISABLE \
+               ((0U) << SE_CRYPTO_HASH_SHIFT)
+#define SE_CRYPTO_HASH_ENABLE  \
+               ((1U) << SE_CRYPTO_HASH_SHIFT)
+
+#define SE_CRYPTO_XOR_POS_SHIFT                        1
+#define SE_CRYPTO_XOR_BYPASS   \
+               ((0U) << SE_CRYPTO_XOR_POS_SHIFT)
+#define SE_CRYPTO_XOR_TOP      \
+               ((2U) << SE_CRYPTO_XOR_POS_SHIFT)
+#define SE_CRYPTO_XOR_BOTTOM   \
+               ((3U) << SE_CRYPTO_XOR_POS_SHIFT)
+
+#define SE_CRYPTO_INPUT_SEL_SHIFT              3
+#define SE_CRYPTO_INPUT_AHB    \
+               ((0U) << SE_CRYPTO_INPUT_SEL_SHIFT)
+#define SE_CRYPTO_INPUT_RANDOM \
+               ((1U) << SE_CRYPTO_INPUT_SEL_SHIFT)
+#define SE_CRYPTO_INPUT_AESOUT \
+               ((2U) << SE_CRYPTO_INPUT_SEL_SHIFT)
+#define SE_CRYPTO_INPUT_LNR_CTR \
+               ((3U) << SE_CRYPTO_INPUT_SEL_SHIFT)
+
+#define SE_CRYPTO_VCTRAM_SEL_SHIFT              5
+#define SE_CRYPTO_VCTRAM_AHB   \
+               ((0U) << SE_CRYPTO_VCTRAM_SEL_SHIFT)
+#define SE_CRYPTO_VCTRAM_AESOUT \
+               ((2U) << SE_CRYPTO_VCTRAM_SEL_SHIFT)
+#define SE_CRYPTO_VCTRAM_PREVAHB       \
+               ((3U) << SE_CRYPTO_VCTRAM_SEL_SHIFT)
+
+#define SE_CRYPTO_IV_SEL_SHIFT                  7
+#define SE_CRYPTO_IV_ORIGINAL  \
+               ((0U) << SE_CRYPTO_IV_SEL_SHIFT)
+#define SE_CRYPTO_IV_UPDATED   \
+               ((1U) << SE_CRYPTO_IV_SEL_SHIFT)
+
+#define SE_CRYPTO_CORE_SEL_SHIFT               8
+#define SE_CRYPTO_CORE_DECRYPT \
+               ((0U) << SE_CRYPTO_CORE_SEL_SHIFT)
+#define SE_CRYPTO_CORE_ENCRYPT \
+               ((1U) << SE_CRYPTO_CORE_SEL_SHIFT)
+
+#define SE_CRYPTO_KEY_INDEX_SHIFT              24
+#define SE_CRYPTO_KEY_INDEX(x) (x << SE_CRYPTO_KEY_INDEX_SHIFT)
+
+#define SE_CRYPTO_MEMIF_AHB    \
+               ((0U) << SE_CRYPTO_MEMIF_SHIFT)
+#define SE_CRYPTO_MEMIF_MCCIF  \
+               ((1U) << SE_CRYPTO_MEMIF_SHIFT)
+#define SE_CRYPTO_MEMIF_SHIFT                  31
+
+/* KEY TABLE */
+#define SE_KEYTABLE_REG_OFFSET                 0x31C
+
+/* KEYIV PKT - key slot */
+#define SE_KEYTABLE_SLOT_SHIFT                 4
+#define SE_KEYTABLE_SLOT(x)    (x << SE_KEYTABLE_SLOT_SHIFT)
+
+/* KEYIV PKT - KEYIV select */
+#define SE_KEYIV_PKT_KEYIV_SEL_SHIFT           3
+#define SE_CRYPTO_KEYIV_KEY    \
+               ((0U) << SE_KEYIV_PKT_KEYIV_SEL_SHIFT)
+#define SE_CRYPTO_KEYIV_IVS    \
+               ((1U) << SE_KEYIV_PKT_KEYIV_SEL_SHIFT)
+
+/* KEYIV PKT - IV select */
+#define SE_KEYIV_PKT_IV_SEL_SHIFT              2
+#define SE_CRYPTO_KEYIV_IVS_OIV        \
+               ((0U) << SE_KEYIV_PKT_IV_SEL_SHIFT)
+#define SE_CRYPTO_KEYIV_IVS_UIV \
+               ((1U) << SE_KEYIV_PKT_IV_SEL_SHIFT)
+
+/* KEYIV PKT - key word */
+#define SE_KEYIV_PKT_KEY_WORD_SHIFT            0
+#define SE_KEYIV_PKT_KEY_WORD(x)       \
+               ((x) << SE_KEYIV_PKT_KEY_WORD_SHIFT)
+
+/* KEYIV PKT - iv word */
+#define SE_KEYIV_PKT_IV_WORD_SHIFT             0
+#define SE_KEYIV_PKT_IV_WORD(x)                \
+               ((x) << SE_KEYIV_PKT_IV_WORD_SHIFT)
+
+/* SE OPERATION */
+#define SE_OPERATION_REG_OFFSET                0x8U
+#define SE_OPERATION_SHIFT                     0
+#define SE_OP_ABORT    \
+               ((0x0U) << SE_OPERATION_SHIFT)
+#define SE_OP_START    \
+               ((0x1U) << SE_OPERATION_SHIFT)
+#define SE_OP_RESTART  \
+               ((0x2U) << SE_OPERATION_SHIFT)
+#define SE_OP_CTX_SAVE \
+               ((0x3U) << SE_OPERATION_SHIFT)
+#define SE_OP_RESTART_IN       \
+               ((0x4U) << SE_OPERATION_SHIFT)
+#define SE_OPERATION(x)        \
+               ((x) & ((0x7U) << SE_OPERATION_SHIFT))
+
+/* SE CONTEXT */
+#define SE_CTX_SAVE_CONFIG_REG_OFFSET          0x70
+#define SE_CTX_SAVE_WORD_QUAD_SHIFT            0
+#define SE_CTX_SAVE_WORD_QUAD(x)       \
+               (x << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_WORD_QUAD_KEYS_0_3 \
+               ((0U) << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_WORD_QUAD_KEYS_4_7 \
+               ((1U) << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_WORD_QUAD_ORIG_IV  \
+               ((2U) << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_WORD_QUAD_UPD_IV   \
+               ((3U) << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+
+#define SE_CTX_SAVE_KEY_INDEX_SHIFT            8
+#define SE_CTX_SAVE_KEY_INDEX(x)       (x << SE_CTX_SAVE_KEY_INDEX_SHIFT)
+
+#define SE_CTX_SAVE_STICKY_WORD_QUAD_SHIFT     24
+#define SE_CTX_SAVE_STICKY_WORD_QUAD_STICKY_0_3        \
+               ((0U) << SE_CTX_SAVE_STICKY_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_STICKY_WORD_QUAD_STICKY_4_7        \
+               ((1U) << SE_CTX_SAVE_STICKY_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_STICKY_WORD_QUAD(x)        \
+               (x << SE_CTX_SAVE_STICKY_WORD_QUAD_SHIFT)
+
+#define SE_CTX_SAVE_SRC_SHIFT                  29
+#define SE_CTX_SAVE_SRC_STICKY_BITS    \
+               ((0U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_RSA_KEYTABLE   \
+               ((1U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_AES_KEYTABLE   \
+               ((2U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_PKA1_STICKY_BITS       \
+               ((3U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_MEM    \
+               ((4U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_SRK    \
+               ((6U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_PKA1_KEYTABLE  \
+               ((7U) << SE_CTX_SAVE_SRC_SHIFT)
+
+#define SE_CTX_STICKY_WORD_QUAD_SHIFT          24
+#define SE_CTX_STICKY_WORD_QUAD_WORDS_0_3 \
+               ((0U) << SE_CTX_STICKY_WORD_QUAD_SHIFT)
+#define SE_CTX_STICKY_WORD_QUAD_WORDS_4_7 \
+               ((1U) << SE_CTX_STICKY_WORD_QUAD_SHIFT)
+#define SE_CTX_STICKY_WORD_QUAD(x)      (x << SE_CTX_STICKY_WORD_QUAD_SHIFT)
+
+#define SE_CTX_SAVE_RSA_KEY_INDEX_SHIFT                16
+#define SE_CTX_SAVE_RSA_KEY_INDEX(x)                           \
+                       (x << SE_CTX_SAVE_RSA_KEY_INDEX_SHIFT)
+
+#define SE_CTX_RSA_WORD_QUAD_SHIFT             12
+#define SE_CTX_RSA_WORD_QUAD(x)        \
+                       (x << SE_CTX_RSA_WORD_QUAD_SHIFT)
+
+#define SE_CTX_PKA1_WORD_QUAD_L_SHIFT          0
+#define SE_CTX_PKA1_WORD_QUAD_L_SIZE           \
+                       ((true ? 4:0) - \
+                       (false ? 4:0) + 1)
+#define SE_CTX_PKA1_WORD_QUAD_L(x)\
+                       (((x) << SE_CTX_PKA1_WORD_QUAD_L_SHIFT) & 0x1f)
+
+#define SE_CTX_PKA1_WORD_QUAD_H_SHIFT          12
+#define SE_CTX_PKA1_WORD_QUAD_H(x)\
+                       ((((x) >> SE_CTX_PKA1_WORD_QUAD_L_SIZE) & 0xf) \
+                       << SE_CTX_PKA1_WORD_QUAD_H_SHIFT)
+
+#define SE_RSA_KEY_INDEX_SLOT0_EXP             0
+#define SE_RSA_KEY_INDEX_SLOT0_MOD             1
+#define SE_RSA_KEY_INDEX_SLOT1_EXP             2
+#define SE_RSA_KEY_INDEX_SLOT1_MOD             3
+
+
+/* SE_CTX_SAVE_AUTO */
+#define SE_CTX_SAVE_AUTO_REG_OFFSET            0x74U
+
+/* Enable */
+#define SE_CTX_SAVE_AUTO_ENABLE_SHIFT          0
+#define SE_CTX_SAVE_AUTO_DIS   \
+               ((0U) << SE_CTX_SAVE_AUTO_ENABLE_SHIFT)
+#define SE_CTX_SAVE_AUTO_EN    \
+               ((1U) << SE_CTX_SAVE_AUTO_ENABLE_SHIFT)
+#define SE_CTX_SAVE_AUTO_ENABLE(x)     \
+               ((x) & ((0x1U) << SE_CTX_SAVE_AUTO_ENABLE_SHIFT))
+
+/* Lock */
+#define SE_CTX_SAVE_AUTO_LOCK_SHIFT            8
+#define SE_CTX_SAVE_AUTO_LOCK_EN       \
+               ((1U) << SE_CTX_SAVE_AUTO_LOCK_SHIFT)
+#define SE_CTX_SAVE_AUTO_LOCK_DIS      \
+               ((0U) << SE_CTX_SAVE_AUTO_LOCK_SHIFT)
+#define SE_CTX_SAVE_AUTO_LOCK(x)       \
+               ((x) & ((0x1U) << SE_CTX_SAVE_AUTO_LOCK_SHIFT))
+
+/* Current context save number of blocks*/
+#define SE_CTX_SAVE_AUTO_CURR_CNT_SHIFT                16
+#define SE_CTX_SAVE_AUTO_CURR_CNT_MASK                 0x3FFU
+#define SE_CTX_SAVE_GET_BLK_COUNT(x)   \
+               (((x) >> SE_CTX_SAVE_AUTO_CURR_CNT_SHIFT) & \
+               SE_CTX_SAVE_AUTO_CURR_CNT_MASK)
+
+#define SE_CTX_SAVE_SIZE_BLOCKS_SE1            133
+#define SE_CTX_SAVE_SIZE_BLOCKS_SE2            646
+
+/* SE TZRAM OPERATION - only for SE1 */
+#define SE_TZRAM_OPERATION                     0x540U
+
+#define SE_TZRAM_OP_MODE_SHIFT                 1
+#define SE_TZRAM_OP_COMMAND_INIT               1
+#define SE_TZRAM_OP_COMMAND_SHIFT              0
+#define SE_TZRAM_OP_MODE_SAVE          \
+               ((0U) << SE_TZRAM_OP_MODE_SHIFT)
+#define SE_TZRAM_OP_MODE_RESTORE       \
+               ((1U) << SE_TZRAM_OP_MODE_SHIFT)
+#define SE_TZRAM_OP_MODE(x)            \
+               ((x) & ((0x1U) << SE_TZRAM_OP_MODE_SHIFT))
+
+#define SE_TZRAM_OP_BUSY_SHIFT                 2
+#define SE_TZRAM_OP_BUSY_OFF   \
+               ((0U) << SE_TZRAM_OP_BUSY_SHIFT)
+#define SE_TZRAM_OP_BUSY_ON    \
+               ((1U) << SE_TZRAM_OP_BUSY_SHIFT)
+#define SE_TZRAM_OP_BUSY(x)    \
+               ((x) & ((0x1U) << SE_TZRAM_OP_BUSY_SHIFT))
+
+#define SE_TZRAM_OP_REQ_SHIFT                  0
+#define SE_TZRAM_OP_REQ_IDLE   \
+               ((0U) << SE_TZRAM_OP_REQ_SHIFT)
+#define SE_TZRAM_OP_REQ_INIT   \
+               ((1U) << SE_TZRAM_OP_REQ_SHIFT)
+#define SE_TZRAM_OP_REQ(x)     \
+               ((x) & ((0x1U) << SE_TZRAM_OP_REQ_SHIFT))
+
+/* SE Interrupt */
+#define SE_INT_STATUS_REG_OFFSET               0x10U
+#define SE_INT_OP_DONE_SHIFT                   4
+#define SE_INT_OP_DONE_CLEAR   \
+               ((0U) << SE_INT_OP_DONE_SHIFT)
+#define SE_INT_OP_DONE_ACTIVE  \
+               ((1U) << SE_INT_OP_DONE_SHIFT)
+#define SE_INT_OP_DONE(x)      \
+               ((x) & ((0x1U) << SE_INT_OP_DONE_SHIFT))
+
+/* SE TZRAM SECURITY */
+#define SE_TZRAM_SEC_REG_OFFSET                        0x4
+
+#define SE_TZRAM_SEC_SETTING_SHIFT              0
+#define SE_TZRAM_SECURE                \
+               ((0UL) << SE_TZRAM_SEC_SETTING_SHIFT)
+#define SE_TZRAM_NONSECURE      \
+               ((1UL) << SE_TZRAM_SEC_SETTING_SHIFT)
+#define SE_TZRAM_SEC_SETTING(x)                \
+               ((x) & ((0x1UL) << SE_TZRAM_SEC_SETTING_SHIFT))
+
+/* PKA1 KEY SLOTS */
+#define TEGRA_SE_PKA1_KEYSLOT_COUNT            4
+
+
+/* SE error status */
+#define SE_ERR_STATUS_REG_OFFSET               0x804U
+#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET      0x330
+#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0
+#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD(x)    \
+                       (x << SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT)
+
+#define SE_KEY_INDEX_SHIFT                     8
+#define SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(x)    (x << SE_KEY_INDEX_SHIFT)
+
+
+/* SE linked list (LL) register */
+#define SE_IN_LL_ADDR_REG_OFFSET               0x18U
+#define SE_OUT_LL_ADDR_REG_OFFSET              0x24U
+#define SE_BLOCK_COUNT_REG_OFFSET              0x318U
+
+/* AES data sizes */
+#define TEGRA_SE_KEY_256_SIZE                  32
+#define TEGRA_SE_KEY_192_SIZE                  24
+#define TEGRA_SE_KEY_128_SIZE                  16
+#define TEGRA_SE_AES_BLOCK_SIZE                16
+#define TEGRA_SE_AES_MIN_KEY_SIZE              16
+#define TEGRA_SE_AES_MAX_KEY_SIZE              32
+#define TEGRA_SE_AES_IV_SIZE                   16
+
+#define TEGRA_SE_RNG_IV_SIZE                   16
+#define TEGRA_SE_RNG_DT_SIZE                   16
+#define TEGRA_SE_RNG_KEY_SIZE                  16
+#define TEGRA_SE_RNG_SEED_SIZE (TEGRA_SE_RNG_IV_SIZE + \
+                                                                       TEGRA_SE_RNG_KEY_SIZE + \
+                                                                       TEGRA_SE_RNG_DT_SIZE)
+#define TEGRA_SE_RSA512_DIGEST_SIZE            64
+#define TEGRA_SE_RSA1024_DIGEST_SIZE           128
+#define TEGRA_SE_RSA1536_DIGEST_SIZE           192
+#define TEGRA_SE_RSA2048_DIGEST_SIZE           256
+
+#define SE_KEY_TABLE_ACCESS_REG_OFFSET         0x284
+#define SE_KEY_READ_DISABLE_SHIFT              0
+
+#define SE_CTX_BUFER_SIZE                      1072
+#define SE_CTX_DRBG_BUFER_SIZE                 2112
+
+/* SE blobs size in bytes */
+#define SE_CTX_SAVE_RSA_KEY_LENGTH             1024
+#define SE_CTX_SAVE_RANDOM_DATA_SIZE           16
+#define SE_CTX_SAVE_STICKY_BITS_SIZE           16
+#define SE2_CONTEXT_SAVE_PKA1_STICKY_BITS_LENGTH 16
+#define SE2_CONTEXT_SAVE_PKA1_KEYS_LENGTH      8192
+#define SE_CTX_KNOWN_PATTERN_SIZE              16
+#define SE_CTX_KNOWN_PATTERN_SIZE_WORDS                (SE_CTX_KNOWN_PATTERN_SIZE/4)
+
+/* SE RSA */
+#define TEGRA_SE_RSA_KEYSLOT_COUNT             2
+#define SE_RSA_KEY_SIZE_REG_OFFSET             0x404
+#define SE_RSA_EXP_SIZE_REG_OFFSET             0x408
+#define SE_RSA_MAX_EXP_BIT_SIZE                        2048
+#define SE_RSA_MAX_EXP_SIZE32  \
+               (SE_RSA_MAX_EXP_BIT_SIZE >> 5)
+#define SE_RSA_MAX_MOD_BIT_SIZE                        2048
+#define SE_RSA_MAX_MOD_SIZE32  \
+               (SE_RSA_MAX_MOD_BIT_SIZE >> 5)
+
+/* SE_RSA_KEYTABLE_ADDR */
+#define SE_RSA_KEYTABLE_ADDR                   0x420
+#define RSA_KEY_PKT_WORD_ADDR_SHIFT            0
+#define RSA_KEY_PKT_EXPMOD_SEL_SHIFT   \
+               ((6U) << RSA_KEY_PKT_WORD_ADDR_SHIFT)
+#define RSA_KEY_MOD    \
+               ((1U) << RSA_KEY_PKT_EXPMOD_SEL_SHIFT)
+#define RSA_KEY_EXP    \
+               ((0U) << RSA_KEY_PKT_EXPMOD_SEL_SHIFT)
+#define RSA_KEY_PKT_SLOT_SHIFT                 7
+#define RSA_KEY_SLOT_1 \
+               ((0U) << RSA_KEY_PKT_SLOT_SHIFT)
+#define RSA_KEY_SLOT_2 \
+               ((1U) << RSA_KEY_PKT_SLOT_SHIFT)
+#define RSA_KEY_PKT_INPUT_MODE_SHIFT           8
+#define RSA_KEY_REG_INPUT      \
+               ((0U) << RSA_KEY_PKT_INPUT_MODE_SHIFT)
+#define RSA_KEY_DMA_INPUT      \
+               ((1U) << RSA_KEY_PKT_INPUT_MODE_SHIFT)
+
+/* SE_RSA_KEYTABLE_DATA */
+#define SE_RSA_KEYTABLE_DATA                   0x424
+
+/* SE_RSA_CONFIG register */
+#define SE_RSA_CONFIG                          0x400
+#define RSA_KEY_SLOT_SHIFT                     24
+#define RSA_KEY_SLOT(x) \
+               ((x) << RSA_KEY_SLOT_SHIFT)
+
+/*******************************************************************************
+ * Structure definition
+ ******************************************************************************/
+
+/* SE context blob */
+#pragma pack(push, 1)
+typedef struct tegra_aes_key_slot {
+       /* 0 - 7 AES key */
+       uint32_t key[8];
+       /* 8 - 11 Original IV */
+       uint32_t oiv[4];
+       /* 12 - 15 Updated IV */
+       uint32_t uiv[4];
+} tegra_se_aes_key_slot_t;
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+typedef struct tegra_se_context {
+       /* random number */
+       unsigned char rand_data[SE_CTX_SAVE_RANDOM_DATA_SIZE];
+       /* Sticky bits */
+       unsigned char sticky_bits[SE_CTX_SAVE_STICKY_BITS_SIZE * 2];
+       /* AES key slots */
+       tegra_se_aes_key_slot_t key_slots[TEGRA_SE_AES_KEYSLOT_COUNT];
+       /* RSA key slots */
+       unsigned char rsa_keys[SE_CTX_SAVE_RSA_KEY_LENGTH];
+} tegra_se_context_t;
+#pragma pack(pop)
+
+/* PKA context blob */
+#pragma pack(push, 1)
+typedef struct tegra_pka_context {
+       unsigned char sticky_bits[SE2_CONTEXT_SAVE_PKA1_STICKY_BITS_LENGTH];
+       unsigned char pka_keys[SE2_CONTEXT_SAVE_PKA1_KEYS_LENGTH];
+} tegra_pka_context_t;
+#pragma pack(pop)
+
+/* SE context blob */
+#pragma pack(push, 1)
+typedef struct tegra_se_context_blob {
+       /* SE context */
+       tegra_se_context_t se_ctx;
+       /* Known Pattern */
+       unsigned char known_pattern[SE_CTX_KNOWN_PATTERN_SIZE];
+} tegra_se_context_blob_t;
+#pragma pack(pop)
+
+/* SE2 and PKA1 context blob */
+#pragma pack(push, 1)
+typedef struct tegra_se2_context_blob {
+       /* SE2 context */
+       tegra_se_context_t se_ctx;
+       /* PKA1 context */
+       tegra_pka_context_t pka_ctx;
+       /* Known Pattern */
+       unsigned char known_pattern[SE_CTX_KNOWN_PATTERN_SIZE];
+} tegra_se2_context_blob_t;
+#pragma pack(pop)
+
+/* SE AES key type 128bit, 192bit, 256bit */
+typedef enum {
+       SE_AES_KEY128,
+       SE_AES_KEY192,
+       SE_AES_KEY256,
+} tegra_se_aes_key_type_t;
+
+/* SE RSA key slot */
+typedef struct tegra_se_rsa_key_slot {
+       /* 0 - 63 exponent key */
+       uint32_t exponent[SE_RSA_MAX_EXP_SIZE32];
+       /* 64 - 127 modulus key */
+       uint32_t modulus[SE_RSA_MAX_MOD_SIZE32];
+} tegra_se_rsa_key_slot_t;
+
+
+/*******************************************************************************
+ * Inline functions definition
+ ******************************************************************************/
+
+static inline uint32_t tegra_se_read_32(const tegra_se_dev_t *dev, uint32_t offset)
+{
+       return mmio_read_32(dev->se_base + offset);
+}
+
+static inline void tegra_se_write_32(const tegra_se_dev_t *dev, uint32_t offset, uint32_t val)
+{
+       mmio_write_32(dev->se_base + offset, val);
+}
+
+static inline uint32_t tegra_pka_read_32(tegra_pka_dev_t *dev, uint32_t offset)
+{
+       return mmio_read_32(dev->pka_base + offset);
+}
+
+static inline void tegra_pka_write_32(tegra_pka_dev_t *dev, uint32_t offset,
+uint32_t val)
+{
+       mmio_write_32(dev->pka_base + offset, val);
+}
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+int tegra_se_start_normal_operation(const tegra_se_dev_t *, uint32_t);
+int tegra_se_start_ctx_save_operation(const tegra_se_dev_t *, uint32_t);
+
+#endif /* SE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
new file mode 100644 (file)
index 0000000..e0a0d6c
--- /dev/null
@@ -0,0 +1,1084 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <common/debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <psci.h>
+#include <se_private.h>
+#include <security_engine.h>
+#include <tegra_platform.h>
+
+/*******************************************************************************
+ * Constants and Macros
+ ******************************************************************************/
+
+#define TIMEOUT_100MS  100U    // Timeout in 100ms
+#define RNG_AES_KEY_INDEX   1
+
+/*******************************************************************************
+ * Data structure and global variables
+ ******************************************************************************/
+
+/* The security engine contexts are formatted as follows:
+ *
+ * SE1 CONTEXT:
+ * #--------------------------------#
+ * |        Random Data   1 Block   |
+ * #--------------------------------#
+ * |        Sticky Bits   2 Blocks  |
+ * #--------------------------------#
+ * | Key Table           64 Blocks  |
+ * |     For each Key (x16):        |
+ * |      Key:         2 Blocks     |
+ * |      Original-IV: 1 Block      |
+ * |      Updated-IV:  1 Block      |
+ * #--------------------------------#
+ * |        RSA Keys     64 Blocks  |
+ * #--------------------------------#
+ * |        Known Pattern 1 Block   |
+ * #--------------------------------#
+ *
+ * SE2/PKA1 CONTEXT:
+ * #--------------------------------#
+ * |        Random Data   1 Block   |
+ * #--------------------------------#
+ * |        Sticky Bits   2 Blocks  |
+ * #--------------------------------#
+ * | Key Table           64 Blocks  |
+ * |     For each Key (x16):        |
+ * |      Key:         2 Blocks     |
+ * |      Original-IV: 1 Block      |
+ * |      Updated-IV:  1 Block      |
+ * #--------------------------------#
+ * |        RSA Keys     64 Blocks  |
+ * #--------------------------------#
+ * |        PKA sticky bits 1 Block |
+ * #--------------------------------#
+ * |        PKA keys    512 Blocks  |
+ * #--------------------------------#
+ * |        Known Pattern 1 Block   |
+ * #--------------------------------#
+ */
+
+/* Known pattern data */
+static const uint32_t se_ctx_known_pattern_data[SE_CTX_KNOWN_PATTERN_SIZE_WORDS] = {
+       /* 128 bit AES block */
+       0x0C0D0E0F,
+       0x08090A0B,
+       0x04050607,
+       0x00010203,
+};
+
+/* SE input and output linked list buffers */
+static tegra_se_io_lst_t se1_src_ll_buf;
+static tegra_se_io_lst_t se1_dst_ll_buf;
+
+/* SE2 input and output linked list buffers */
+static tegra_se_io_lst_t se2_src_ll_buf;
+static tegra_se_io_lst_t se2_dst_ll_buf;
+
+/* SE1 security engine device handle */
+static tegra_se_dev_t se_dev_1 = {
+       .se_num = 1,
+       /* Setup base address for se */
+       .se_base = TEGRA_SE1_BASE,
+       /* Setup context size in AES blocks */
+       .ctx_size_blks = SE_CTX_SAVE_SIZE_BLOCKS_SE1,
+       /* Setup SRC buffers for SE operations */
+       .src_ll_buf = &se1_src_ll_buf,
+       /* 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),
+};
+
+/* SE2 security engine device handle */
+static tegra_se_dev_t se_dev_2 = {
+       .se_num = 2,
+       /* Setup base address for se */
+       .se_base = TEGRA_SE2_BASE,
+       /* Setup context size in AES blocks */
+       .ctx_size_blks = SE_CTX_SAVE_SIZE_BLOCKS_SE2,
+       /* Setup SRC buffers for SE operations */
+       .src_ll_buf = &se2_src_ll_buf,
+       /* 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),
+};
+
+static bool ecid_valid;
+
+/*******************************************************************************
+ * Functions Definition
+ ******************************************************************************/
+
+static void tegra_se_make_data_coherent(const tegra_se_dev_t *se_dev)
+{
+       flush_dcache_range(((uint64_t)(se_dev->src_ll_buf)),
+                       sizeof(tegra_se_io_lst_t));
+       flush_dcache_range(((uint64_t)(se_dev->dst_ll_buf)),
+                       sizeof(tegra_se_io_lst_t));
+}
+
+/*
+ * 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. SE_INT_STATUS = SE_OP_DONE
+ * 2. SE_STATUS = IDLE
+ * 3. AHB bus data transfer complete.
+ * 4. SE_ERR_STATUS is clean.
+ */
+static int32_t tegra_se_operation_complete(const tegra_se_dev_t *se_dev)
+{
+       uint32_t val = 0;
+       int32_t ret = 0;
+       uint32_t timeout;
+
+       /* Poll the SE interrupt register to ensure H/W operation complete */
+       val = tegra_se_read_32(se_dev, SE_INT_STATUS_REG_OFFSET);
+       for (timeout = 0; (SE_INT_OP_DONE(val) == SE_INT_OP_DONE_CLEAR) &&
+                       (timeout < TIMEOUT_100MS); timeout++) {
+               mdelay(1);
+               val = tegra_se_read_32(se_dev, SE_INT_STATUS_REG_OFFSET);
+       }
+
+       if (timeout == TIMEOUT_100MS) {
+               ERROR("%s: ERR: Atomic context save operation timeout!\n",
+                               __func__);
+               ret = -ETIMEDOUT;
+       }
+
+       /* Poll the SE status idle to ensure H/W operation complete */
+       if (ret == 0) {
+               val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
+               for (timeout = 0; (val != 0U) && (timeout < TIMEOUT_100MS);
+                               timeout++) {
+                       mdelay(1);
+                       val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
+               }
+
+               if (timeout == TIMEOUT_100MS) {
+                       ERROR("%s: ERR: MEM_INTERFACE and SE state "
+                                       "idle state timeout.\n", __func__);
+                       ret = -ETIMEDOUT;
+               }
+       }
+
+       /* Check AHB bus transfer complete */
+       if (ret == 0) {
+               val = mmio_read_32(TEGRA_AHB_ARB_BASE + ARAHB_MEM_WRQUE_MST_ID_OFFSET);
+               for (timeout = 0; ((val & (ARAHB_MST_ID_SE_MASK | ARAHB_MST_ID_SE2_MASK)) != 0U) &&
+                               (timeout < TIMEOUT_100MS); timeout++) {
+                       mdelay(1);
+                       val = mmio_read_32(TEGRA_AHB_ARB_BASE + ARAHB_MEM_WRQUE_MST_ID_OFFSET);
+               }
+
+               if (timeout == TIMEOUT_100MS) {
+                       ERROR("%s: SE write over AHB timeout.\n", __func__);
+                       ret = -ETIMEDOUT;
+               }
+       }
+
+       /* Ensure that no errors are thrown during operation */
+       if (ret == 0) {
+               val = tegra_se_read_32(se_dev, SE_ERR_STATUS_REG_OFFSET);
+               if (val != 0U) {
+                       ERROR("%s: error during SE operation! 0x%x", __func__, val);
+                       ret = -ENOTSUP;
+               }
+       }
+
+       return ret;
+}
+
+/*
+ * 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.
+ */
+static int32_t tegra_se_operation_prepare(const tegra_se_dev_t *se_dev)
+{
+       int32_t ret = 0;
+       uint32_t val = 0;
+       uint32_t timeout;
+
+       /* 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++) {
+               mdelay(1);
+               val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
+       }
+
+       if (timeout == TIMEOUT_100MS) {
+               ERROR("%s: ERR: SE status is not idle!\n", __func__);
+               ret = -ETIMEDOUT;
+       }
+
+       /* Clear any pending interrupts from  previous operation */
+       val = tegra_se_read_32(se_dev, SE_INT_STATUS_REG_OFFSET);
+       tegra_se_write_32(se_dev, SE_INT_STATUS_REG_OFFSET, val);
+       return ret;
+}
+
+/*
+ * SE atomic context save. At SC7 entry, SE driver triggers the
+ * hardware automatically performs the context save operation.
+ */
+static int32_t tegra_se_context_save_atomic(const tegra_se_dev_t *se_dev)
+{
+       int32_t ret = 0;
+       uint32_t val = 0;
+       uint32_t blk_count_limit = 0;
+       uint32_t block_count;
+
+       /* Check that previous operation is finalized */
+       ret = tegra_se_operation_prepare(se_dev);
+
+       /* Read the context save progress counter: block_count
+        * Ensure no previous context save has been triggered
+        * SE_CTX_SAVE_AUTO.CURR_CNT == 0
+        */
+       if (ret == 0) {
+               val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
+               block_count = SE_CTX_SAVE_GET_BLK_COUNT(val);
+               if (block_count != 0U) {
+                       ERROR("%s: ctx_save triggered multiple times\n",
+                                       __func__);
+                       ret = -EALREADY;
+               }
+       }
+
+       /* Set the destination block count when the context save complete */
+       if (ret == 0) {
+               blk_count_limit = block_count + se_dev->ctx_size_blks;
+       }
+
+       /* Program SE_CONFIG register as for RNG operation
+        * SE_CONFIG.ENC_ALG = RNG
+        * SE_CONFIG.DEC_ALG = NOP
+        * SE_CONFIG.ENC_MODE is ignored
+        * SE_CONFIG.DEC_MODE is ignored
+        * SE_CONFIG.DST = MEMORY
+        */
+       if (ret == 0) {
+               val = (SE_CONFIG_ENC_ALG_RNG |
+                       SE_CONFIG_DEC_ALG_NOP |
+                       SE_CONFIG_DST_MEMORY);
+               tegra_se_write_32(se_dev, SE_CONFIG_REG_OFFSET, val);
+
+               tegra_se_make_data_coherent(se_dev);
+
+               /* SE_CTX_SAVE operation */
+               tegra_se_write_32(se_dev, SE_OPERATION_REG_OFFSET,
+                               SE_OP_CTX_SAVE);
+
+               ret = tegra_se_operation_complete(se_dev);
+       }
+
+       /* Check that context has written the correct number of blocks */
+       if (ret == 0) {
+               val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
+               if (SE_CTX_SAVE_GET_BLK_COUNT(val) != blk_count_limit) {
+                       ERROR("%s: expected %d blocks but %d were written\n",
+                                       __func__, blk_count_limit, val);
+                       ret = -ECANCELED;
+               }
+       }
+
+       return ret;
+}
+
+/*
+ * Security engine primitive operations, including normal operation
+ * and the context save operation.
+ */
+static int tegra_se_perform_operation(const tegra_se_dev_t *se_dev, uint32_t nbytes,
+                                       bool context_save)
+{
+       uint32_t nblocks = nbytes / TEGRA_SE_AES_BLOCK_SIZE;
+       int ret = 0;
+
+       assert(se_dev);
+
+       /* Use device buffers for in and out */
+       tegra_se_write_32(se_dev, SE_OUT_LL_ADDR_REG_OFFSET, ((uint64_t)(se_dev->dst_ll_buf)));
+       tegra_se_write_32(se_dev, SE_IN_LL_ADDR_REG_OFFSET, ((uint64_t)(se_dev->src_ll_buf)));
+
+       /* Check that previous operation is finalized */
+       ret = tegra_se_operation_prepare(se_dev);
+       if (ret != 0) {
+               goto op_error;
+       }
+
+       /* Program SE operation size */
+       if (nblocks) {
+               tegra_se_write_32(se_dev, SE_BLOCK_COUNT_REG_OFFSET, nblocks - 1);
+       }
+
+       /* Make SE LL data coherent before the SE operation */
+       tegra_se_make_data_coherent(se_dev);
+
+       /* Start hardware operation */
+       if (context_save)
+               tegra_se_write_32(se_dev, SE_OPERATION_REG_OFFSET, SE_OP_CTX_SAVE);
+       else
+               tegra_se_write_32(se_dev, SE_OPERATION_REG_OFFSET, SE_OP_START);
+
+       /* Wait for operation to finish */
+       ret = tegra_se_operation_complete(se_dev);
+
+op_error:
+       return ret;
+}
+
+/*
+ * Normal security engine operations other than the context save
+ */
+int tegra_se_start_normal_operation(const tegra_se_dev_t *se_dev, uint32_t nbytes)
+{
+       return tegra_se_perform_operation(se_dev, nbytes, false);
+}
+
+/*
+ * Security engine context save operation
+ */
+int tegra_se_start_ctx_save_operation(const tegra_se_dev_t *se_dev, uint32_t nbytes)
+{
+       return tegra_se_perform_operation(se_dev, nbytes, true);
+}
+
+/*
+ * Security Engine sequence to generat SRK
+ * SE and SE2 will generate different SRK by different
+ * entropy seeds.
+ */
+static int tegra_se_generate_srk(const tegra_se_dev_t *se_dev)
+{
+       int ret = PSCI_E_INTERN_FAIL;
+       uint32_t val;
+
+       /* Confgure the following hardware register settings:
+        * SE_CONFIG.DEC_ALG = NOP
+        * SE_CONFIG.ENC_ALG = RNG
+        * SE_CONFIG.DST = SRK
+        * SE_OPERATION.OP = START
+        * SE_CRYPTO_LAST_BLOCK = 0
+        */
+       se_dev->src_ll_buf->last_buff_num = 0;
+       se_dev->dst_ll_buf->last_buff_num = 0;
+
+       /* Configure random number generator */
+       if (ecid_valid)
+               val = (DRBG_MODE_FORCE_INSTANTION | DRBG_SRC_ENTROPY);
+       else
+               val = (DRBG_MODE_FORCE_RESEED | DRBG_SRC_ENTROPY);
+       tegra_se_write_32(se_dev, SE_RNG_CONFIG_REG_OFFSET, val);
+
+       /* Configure output destination = SRK */
+       val = (SE_CONFIG_ENC_ALG_RNG |
+               SE_CONFIG_DEC_ALG_NOP |
+               SE_CONFIG_DST_SRK);
+       tegra_se_write_32(se_dev, SE_CONFIG_REG_OFFSET, val);
+
+       /* Perform hardware operation */
+       ret = tegra_se_start_normal_operation(se_dev, 0);
+
+       return ret;
+}
+
+/*
+ * Generate plain text random data to some memory location using
+ * SE/SE2's SP800-90 random number generator. The random data size
+ * must be some multiple of the AES block size (16 bytes).
+ */
+static int tegra_se_lp_generate_random_data(tegra_se_dev_t *se_dev)
+{
+       int ret = 0;
+       uint32_t val;
+
+       /* Set some arbitrary memory location to store the random data */
+       se_dev->dst_ll_buf->last_buff_num = 0;
+       if (!se_dev->ctx_save_buf) {
+               ERROR("%s: ERR: context save buffer NULL pointer!\n", __func__);
+               return PSCI_E_NOT_PRESENT;
+       }
+       se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(((tegra_se_context_t *)
+                                       se_dev->ctx_save_buf)->rand_data)));
+       se_dev->dst_ll_buf->buffer[0].data_len = SE_CTX_SAVE_RANDOM_DATA_SIZE;
+
+
+       /* Confgure the following hardware register settings:
+        * SE_CONFIG.DEC_ALG = NOP
+        * SE_CONFIG.ENC_ALG = RNG
+        * SE_CONFIG.ENC_MODE = KEY192
+        * SE_CONFIG.DST = MEMORY
+        */
+       val = (SE_CONFIG_ENC_ALG_RNG |
+               SE_CONFIG_DEC_ALG_NOP |
+               SE_CONFIG_ENC_MODE_KEY192 |
+               SE_CONFIG_DST_MEMORY);
+       tegra_se_write_32(se_dev, SE_CONFIG_REG_OFFSET, val);
+
+       /* Program the RNG options in SE_CRYPTO_CONFIG as follows:
+        * XOR_POS = BYPASS
+        * INPUT_SEL = RANDOM (Entropy or LFSR)
+        * HASH_ENB = DISABLE
+        */
+       val = (SE_CRYPTO_INPUT_RANDOM |
+               SE_CRYPTO_XOR_BYPASS |
+               SE_CRYPTO_CORE_ENCRYPT |
+               SE_CRYPTO_HASH_DISABLE |
+               SE_CRYPTO_KEY_INDEX(RNG_AES_KEY_INDEX) |
+               SE_CRYPTO_IV_ORIGINAL);
+       tegra_se_write_32(se_dev, SE_CRYPTO_REG_OFFSET, val);
+
+       /* Configure RNG */
+       if (ecid_valid)
+               val = (DRBG_MODE_FORCE_INSTANTION | DRBG_SRC_LFSR);
+       else
+               val = (DRBG_MODE_FORCE_RESEED | DRBG_SRC_LFSR);
+       tegra_se_write_32(se_dev, SE_RNG_CONFIG_REG_OFFSET, val);
+
+       /* SE normal operation */
+       ret = tegra_se_start_normal_operation(se_dev, SE_CTX_SAVE_RANDOM_DATA_SIZE);
+
+       return ret;
+}
+
+/*
+ * Encrypt memory blocks with SRK as part of the security engine context.
+ * The data blocks include: random data and the known pattern data, where
+ * the random data is the first block and known pattern is the last block.
+ */
+static int tegra_se_lp_data_context_save(tegra_se_dev_t *se_dev,
+               uint64_t src_addr, uint64_t dst_addr, uint32_t data_size)
+{
+       int ret = 0;
+
+       se_dev->src_ll_buf->last_buff_num = 0;
+       se_dev->dst_ll_buf->last_buff_num = 0;
+       se_dev->src_ll_buf->buffer[0].addr = src_addr;
+       se_dev->src_ll_buf->buffer[0].data_len = data_size;
+       se_dev->dst_ll_buf->buffer[0].addr = dst_addr;
+       se_dev->dst_ll_buf->buffer[0].data_len = data_size;
+
+       /* By setting the context source from memory and calling the context save
+        * operation, the SE encrypts the memory data with SRK.
+        */
+       tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, SE_CTX_SAVE_SRC_MEM);
+
+       ret = tegra_se_start_ctx_save_operation(se_dev, data_size);
+
+       return ret;
+}
+
+/*
+ * Context save the key table access control sticky bits and
+ * security status of each key-slot. The encrypted sticky-bits are
+ * 32 bytes (2 AES blocks) and formatted as the following structure:
+ * {   bit in registers                        bit in context save
+ *     SECURITY_0[4]                           158
+ *     SE_RSA_KEYTABLE_ACCE4SS_1[2:0]          157:155
+ *     SE_RSA_KEYTABLE_ACCE4SS_0[2:0]          154:152
+ *     SE_RSA_SECURITY_PERKEY_0[1:0]           151:150
+ *     SE_CRYPTO_KEYTABLE_ACCESS_15[7:0]       149:142
+ *     ...,
+ *     SE_CRYPTO_KEYTABLE_ACCESS_0[7:0]        29:22
+ *     SE_CRYPTO_SECURITY_PERKEY_0[15:0]       21:6
+ *     SE_TZRAM_SECURITY_0[1:0]                5:4
+ *     SE_SECURITY_0[16]                       3:3
+ *     SE_SECURITY_0[2:0] }                    2:0
+ */
+static int tegra_se_lp_sticky_bits_context_save(tegra_se_dev_t *se_dev)
+{
+       int ret = PSCI_E_INTERN_FAIL;
+       uint32_t val = 0;
+
+       se_dev->dst_ll_buf->last_buff_num = 0;
+       if (!se_dev->ctx_save_buf) {
+               ERROR("%s: ERR: context save buffer NULL pointer!\n", __func__);
+               return PSCI_E_NOT_PRESENT;
+       }
+       se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(((tegra_se_context_t *)
+                                               se_dev->ctx_save_buf)->sticky_bits)));
+       se_dev->dst_ll_buf->buffer[0].data_len = SE_CTX_SAVE_STICKY_BITS_SIZE;
+
+       /*
+        * The 1st AES block save the sticky-bits context 1 - 16 bytes (0 - 3 words).
+        * The 2nd AES block save the sticky-bits context 17 - 32 bytes (4 - 7 words).
+        */
+       for (int i = 0; i < 2; i++) {
+               val = SE_CTX_SAVE_SRC_STICKY_BITS |
+                       SE_CTX_SAVE_STICKY_WORD_QUAD(i);
+               tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+               /* SE context save operation */
+               ret = tegra_se_start_ctx_save_operation(se_dev,
+                               SE_CTX_SAVE_STICKY_BITS_SIZE);
+               if (ret)
+                       break;
+               se_dev->dst_ll_buf->buffer[0].addr += SE_CTX_SAVE_STICKY_BITS_SIZE;
+       }
+
+       return ret;
+}
+
+static int tegra_se_aeskeytable_context_save(tegra_se_dev_t *se_dev)
+{
+       uint32_t val = 0;
+       int ret = 0;
+
+       se_dev->dst_ll_buf->last_buff_num = 0;
+       if (!se_dev->ctx_save_buf) {
+               ERROR("%s: ERR: context save buffer NULL pointer!\n", __func__);
+               ret = -EINVAL;
+               goto aes_keytable_save_err;
+       }
+
+       /* AES key context save */
+       for (int slot = 0; slot < TEGRA_SE_AES_KEYSLOT_COUNT; slot++) {
+               se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+                                               ((tegra_se_context_t *)se_dev->
+                                                ctx_save_buf)->key_slots[slot].key)));
+               se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_KEY_128_SIZE;
+               for (int i = 0; i < 2; i++) {
+                       val = SE_CTX_SAVE_SRC_AES_KEYTABLE |
+                               SE_CTX_SAVE_KEY_INDEX(slot) |
+                               SE_CTX_SAVE_WORD_QUAD(i);
+                       tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+                       /* SE context save operation */
+                       ret = tegra_se_start_ctx_save_operation(se_dev,
+                                       TEGRA_SE_KEY_128_SIZE);
+                       if (ret) {
+                               ERROR("%s: ERR: AES key CTX_SAVE OP failed, "
+                                               "slot=%d, word_quad=%d.\n",
+                                               __func__, slot, i);
+                               goto aes_keytable_save_err;
+                       }
+                       se_dev->dst_ll_buf->buffer[0].addr += TEGRA_SE_KEY_128_SIZE;
+               }
+
+               /* OIV context save */
+               se_dev->dst_ll_buf->last_buff_num = 0;
+               se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+                                               ((tegra_se_context_t *)se_dev->
+                                                ctx_save_buf)->key_slots[slot].oiv)));
+               se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_AES_IV_SIZE;
+
+               val = SE_CTX_SAVE_SRC_AES_KEYTABLE |
+                       SE_CTX_SAVE_KEY_INDEX(slot) |
+                       SE_CTX_SAVE_WORD_QUAD_ORIG_IV;
+               tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+               /* SE context save operation */
+               ret = tegra_se_start_ctx_save_operation(se_dev, TEGRA_SE_AES_IV_SIZE);
+               if (ret) {
+                       ERROR("%s: ERR: OIV CTX_SAVE OP failed, slot=%d.\n",
+                                       __func__, slot);
+                       goto aes_keytable_save_err;
+               }
+
+               /* UIV context save */
+               se_dev->dst_ll_buf->last_buff_num = 0;
+               se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+                                               ((tegra_se_context_t *)se_dev->
+                                                ctx_save_buf)->key_slots[slot].uiv)));
+               se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_AES_IV_SIZE;
+
+               val = SE_CTX_SAVE_SRC_AES_KEYTABLE |
+                       SE_CTX_SAVE_KEY_INDEX(slot) |
+                       SE_CTX_SAVE_WORD_QUAD_UPD_IV;
+               tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+               /* SE context save operation */
+               ret = tegra_se_start_ctx_save_operation(se_dev, TEGRA_SE_AES_IV_SIZE);
+               if (ret) {
+                       ERROR("%s: ERR: UIV CTX_SAVE OP failed, slot=%d\n",
+                                       __func__, slot);
+                       goto aes_keytable_save_err;
+               }
+       }
+
+aes_keytable_save_err:
+       return ret;
+}
+
+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
+        * 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 1 modulus : RSA_KEY_INDEX : 3
+        */
+       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},
+               /* RSA key slot 1 */
+               {SE_RSA_KEY_INDEX_SLOT1_EXP, SE_RSA_KEY_INDEX_SLOT1_MOD},
+       };
+
+       se_dev->dst_ll_buf->last_buff_num = 0;
+       se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+                                       ((tegra_se_context_t *)se_dev->
+                                        ctx_save_buf)->rsa_keys)));
+       se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_KEY_128_SIZE;
+
+       for (int slot = 0; slot < TEGRA_SE_RSA_KEYSLOT_COUNT; slot++) {
+               /* loop for modulus and exponent */
+               for (int index = 0; index < 2; index++) {
+                       for (int word_quad = 0; word_quad < 16; word_quad++) {
+                               val = SE_CTX_SAVE_SRC_RSA_KEYTABLE |
+                                       SE_CTX_SAVE_RSA_KEY_INDEX(
+                                               key_index_mod[slot][index]) |
+                                       SE_CTX_RSA_WORD_QUAD(word_quad);
+                               tegra_se_write_32(se_dev,
+                                       SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+                               /* SE context save operation */
+                               ret = tegra_se_start_ctx_save_operation(se_dev,
+                                               TEGRA_SE_KEY_128_SIZE);
+                               if (ret) {
+                                       ERROR("%s: ERR: slot=%d.\n",
+                                               __func__, slot);
+                                       goto rsa_keytable_save_err;
+                               }
+
+                               /* Update the pointer to the next word quad */
+                               se_dev->dst_ll_buf->buffer[0].addr +=
+                                       TEGRA_SE_KEY_128_SIZE;
+                       }
+               }
+       }
+
+rsa_keytable_save_err:
+       return ret;
+}
+
+static int tegra_se_pkakeytable_sticky_bits_save(tegra_se_dev_t *se_dev)
+{
+       int ret = 0;
+
+       se_dev->dst_ll_buf->last_buff_num = 0;
+       se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+                                       ((tegra_se2_context_blob_t *)se_dev->
+                                        ctx_save_buf)->pka_ctx.sticky_bits)));
+       se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_AES_BLOCK_SIZE;
+
+       /* PKA1 sticky bits are 1 AES block (16 bytes) */
+       tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET,
+                       SE_CTX_SAVE_SRC_PKA1_STICKY_BITS |
+                       SE_CTX_STICKY_WORD_QUAD_WORDS_0_3);
+
+       /* SE context save operation */
+       ret = tegra_se_start_ctx_save_operation(se_dev, 0);
+       if (ret) {
+               ERROR("%s: ERR: PKA1 sticky bits CTX_SAVE OP failed\n",
+                               __func__);
+               goto pka_sticky_bits_save_err;
+       }
+
+pka_sticky_bits_save_err:
+       return ret;
+}
+
+static int tegra_se_pkakeytable_context_save(tegra_se_dev_t *se_dev)
+{
+       uint32_t val = 0;
+       int ret = 0;
+
+       se_dev->dst_ll_buf->last_buff_num = 0;
+       se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+                                       ((tegra_se2_context_blob_t *)se_dev->
+                                        ctx_save_buf)->pka_ctx.pka_keys)));
+       se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_KEY_128_SIZE;
+
+       /* for each slot, save word quad 0-127 */
+       for (int slot = 0; slot < TEGRA_SE_PKA1_KEYSLOT_COUNT; slot++) {
+               for (int word_quad = 0; word_quad < 512/4; word_quad++) {
+                       val = SE_CTX_SAVE_SRC_PKA1_KEYTABLE |
+                               SE_CTX_PKA1_WORD_QUAD_L((slot * 128) +
+                                               word_quad) |
+                               SE_CTX_PKA1_WORD_QUAD_H((slot * 128) +
+                                               word_quad);
+                       tegra_se_write_32(se_dev,
+                                       SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+                       /* SE context save operation */
+                       ret = tegra_se_start_ctx_save_operation(se_dev,
+                                       TEGRA_SE_KEY_128_SIZE);
+                       if (ret) {
+                               ERROR("%s: ERR: pka1 keytable ctx save error\n",
+                                               __func__);
+                               goto pka_keytable_save_err;
+                       }
+
+                       /* Update the pointer to the next word quad */
+                       se_dev->dst_ll_buf->buffer[0].addr +=
+                               TEGRA_SE_KEY_128_SIZE;
+               }
+       }
+
+pka_keytable_save_err:
+       return ret;
+}
+
+static int tegra_se_save_SRK(tegra_se_dev_t *se_dev)
+{
+       tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET,
+                       SE_CTX_SAVE_SRC_SRK);
+
+       /* SE context save operation */
+       return tegra_se_start_ctx_save_operation(se_dev, 0);
+}
+
+/*
+ *  Lock both SE from non-TZ clients.
+ */
+static inline void tegra_se_lock(tegra_se_dev_t *se_dev)
+{
+       uint32_t val;
+
+       assert(se_dev);
+       val = tegra_se_read_32(se_dev, SE_SECURITY_REG_OFFSET);
+       val |= SE_SECURITY_TZ_LOCK_SOFT(SE_SECURE);
+       tegra_se_write_32(se_dev, SE_SECURITY_REG_OFFSET, val);
+}
+
+/*
+ * Use SRK to encrypt SE state and save to TZRAM carveout
+ */
+static int tegra_se_context_save_sw(tegra_se_dev_t *se_dev)
+{
+       int err = 0;
+
+       assert(se_dev);
+
+       /* Lock entire SE/SE2 as TZ protected */
+       tegra_se_lock(se_dev);
+
+       INFO("%s: generate SRK\n", __func__);
+       /* Generate SRK */
+       err = tegra_se_generate_srk(se_dev);
+       if (err) {
+               ERROR("%s: ERR: SRK generation failed\n", __func__);
+               return err;
+       }
+
+       INFO("%s: generate random data\n", __func__);
+       /* Generate random data */
+       err = tegra_se_lp_generate_random_data(se_dev);
+       if (err) {
+               ERROR("%s: ERR: LP random pattern generation failed\n", __func__);
+               return err;
+       }
+
+       INFO("%s: encrypt random data\n", __func__);
+       /* Encrypt the random data block */
+       err = tegra_se_lp_data_context_save(se_dev,
+               ((uint64_t)(&(((tegra_se_context_t *)se_dev->
+                                       ctx_save_buf)->rand_data))),
+               ((uint64_t)(&(((tegra_se_context_t *)se_dev->
+                                       ctx_save_buf)->rand_data))),
+               SE_CTX_SAVE_RANDOM_DATA_SIZE);
+       if (err) {
+               ERROR("%s: ERR: random pattern encryption failed\n", __func__);
+               return err;
+       }
+
+       INFO("%s: save SE sticky bits\n", __func__);
+       /* Save AES sticky bits context */
+       err = tegra_se_lp_sticky_bits_context_save(se_dev);
+       if (err) {
+               ERROR("%s: ERR: sticky bits context save failed\n", __func__);
+               return err;
+       }
+
+       INFO("%s: save AES keytables\n", __func__);
+       /* Save AES key table context */
+       err = tegra_se_aeskeytable_context_save(se_dev);
+       if (err) {
+               ERROR("%s: ERR: LP keytable save failed\n", __func__);
+               return err;
+       }
+
+       /* RSA key slot table context save */
+       INFO("%s: save RSA keytables\n", __func__);
+       err = tegra_se_lp_rsakeytable_context_save(se_dev);
+       if (err) {
+               ERROR("%s: ERR: rsa key table context save failed\n", __func__);
+               return err;
+       }
+
+       /* Only SE2 has an interface with PKA1; thus, PKA1's context is saved
+        * via SE2.
+        */
+       if (se_dev->se_num == 2) {
+               /* Encrypt PKA1 sticky bits on SE2 only */
+               INFO("%s: save PKA sticky bits\n", __func__);
+               err = tegra_se_pkakeytable_sticky_bits_save(se_dev);
+               if (err) {
+                       ERROR("%s: ERR: PKA sticky bits context save failed\n", __func__);
+                       return err;
+               }
+
+               /* Encrypt PKA1 keyslots on SE2 only */
+               INFO("%s: save PKA keytables\n", __func__);
+               err = tegra_se_pkakeytable_context_save(se_dev);
+               if (err) {
+                       ERROR("%s: ERR: PKA key table context save failed\n", __func__);
+                       return err;
+               }
+       }
+
+       /* Encrypt known pattern */
+       if (se_dev->se_num == 1) {
+               err = tegra_se_lp_data_context_save(se_dev,
+                       ((uint64_t)(&se_ctx_known_pattern_data)),
+                       ((uint64_t)(&(((tegra_se_context_blob_t *)se_dev->ctx_save_buf)->known_pattern))),
+                       SE_CTX_KNOWN_PATTERN_SIZE);
+       } else if (se_dev->se_num == 2) {
+               err = tegra_se_lp_data_context_save(se_dev,
+                       ((uint64_t)(&se_ctx_known_pattern_data)),
+                       ((uint64_t)(&(((tegra_se2_context_blob_t *)se_dev->ctx_save_buf)->known_pattern))),
+                       SE_CTX_KNOWN_PATTERN_SIZE);
+       }
+       if (err) {
+               ERROR("%s: ERR: save LP known pattern failure\n", __func__);
+               return err;
+       }
+
+       /* 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,
+                               ((uint64_t)(se_dev->ctx_save_buf)));
+       } else if (se_dev->se_num == 2) {
+               /* SE2 & PKA1 context address */
+               mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SECURE_SCRATCH116_OFFSET,
+                               ((uint64_t)(se_dev->ctx_save_buf)));
+       }
+
+       /* Saves SRK to PMC secure scratch registers for BootROM, which
+        * verifies and restores the security engine context on warm boot.
+        */
+       err = tegra_se_save_SRK(se_dev);
+       if (err < 0) {
+               ERROR("%s: ERR: LP SRK save failure\n", __func__);
+               return err;
+       }
+
+       INFO("%s: SE context save done \n", __func__);
+
+       return err;
+}
+
+/*
+ * Initialize the SE engine handle
+ */
+void tegra_se_init(void)
+{
+       uint32_t val = 0;
+       INFO("%s: start SE init\n", __func__);
+
+       /* Generate random SRK to initialize DRBG */
+       tegra_se_generate_srk(&se_dev_1);
+       tegra_se_generate_srk(&se_dev_2);
+
+       /* determine if ECID is valid */
+       val = mmio_read_32(TEGRA_FUSE_BASE + FUSE_JTAG_SECUREID_VALID);
+       ecid_valid = (val == ECID_VALID);
+
+       INFO("%s: SE init done\n", __func__);
+}
+
+static void tegra_se_enable_clocks(void)
+{
+       uint32_t val = 0;
+
+       /* Enable entropy clock */
+       val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W);
+       val |= ENTROPY_CLK_ENB_BIT;
+       mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W, val);
+
+       /* De-Assert Entropy Reset */
+       val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W);
+       val &= ~ENTROPY_RESET_BIT;
+       mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W, val);
+
+       /* Enable SE clock */
+       val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V);
+       val |= SE_CLK_ENB_BIT;
+       mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V, val);
+
+       /* De-Assert SE Reset */
+       val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_V);
+       val &= ~SE_RESET_BIT;
+       mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_V, val);
+}
+
+static void tegra_se_disable_clocks(void)
+{
+       uint32_t val = 0;
+
+       /* Disable entropy clock */
+       val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W);
+       val &= ~ENTROPY_CLK_ENB_BIT;
+       mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W, val);
+
+       /* Disable SE clock */
+       val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V);
+       val &= ~SE_CLK_ENB_BIT;
+       mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V, val);
+}
+
+/*
+ * Security engine power suspend entry point.
+ * This function is invoked from PSCI power domain suspend handler.
+ */
+int32_t tegra_se_suspend(void)
+{
+       int32_t ret = 0;
+       uint32_t val = 0;
+
+       /* SE does not use SMMU in EL3, disable SMMU.
+        * This will be re-enabled by kernel on resume */
+       val = mmio_read_32(TEGRA_MC_BASE + MC_SMMU_PPCS_ASID_0);
+       val &= ~PPCS_SMMU_ENABLE;
+       mmio_write_32(TEGRA_MC_BASE + MC_SMMU_PPCS_ASID_0, val);
+
+       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 */
+               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);
+               }
+
+               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__);
+               }
+       } else {
+               ERROR("%s: One SE set for atomic CTX save, the other is not\n",
+                        __func__);
+       }
+
+       tegra_se_disable_clocks();
+
+       return ret;
+}
+
+/*
+ * Save TZRAM to shadow TZRAM in AON
+ */
+int32_t tegra_se_save_tzram(void)
+{
+       uint32_t val = 0;
+       int32_t ret = 0;
+       uint32_t timeout;
+
+       INFO("%s: SE TZRAM save start\n", __func__);
+       tegra_se_enable_clocks();
+
+       val = (SE_TZRAM_OP_REQ_INIT | SE_TZRAM_OP_MODE_SAVE);
+       tegra_se_write_32(&se_dev_1, SE_TZRAM_OPERATION, val);
+
+       val = tegra_se_read_32(&se_dev_1, SE_TZRAM_OPERATION);
+       for (timeout = 0; (SE_TZRAM_OP_BUSY(val) == SE_TZRAM_OP_BUSY_ON) &&
+                       (timeout < TIMEOUT_100MS); timeout++) {
+               mdelay(1);
+               val = tegra_se_read_32(&se_dev_1, SE_TZRAM_OPERATION);
+       }
+
+       if (timeout == TIMEOUT_100MS) {
+               ERROR("%s: ERR: TZRAM save timeout!\n", __func__);
+               ret = -ETIMEDOUT;
+       }
+
+       if (ret == 0) {
+               INFO("%s: SE TZRAM save done!\n", __func__);
+       }
+
+       tegra_se_disable_clocks();
+
+       return ret;
+}
+
+/*
+ * The function is invoked by SE resume
+ */
+static void tegra_se_warm_boot_resume(const tegra_se_dev_t *se_dev)
+{
+       uint32_t val;
+
+       assert(se_dev);
+
+       /* Lock RNG source to ENTROPY on resume */
+       val = DRBG_RO_ENT_IGNORE_MEM_ENABLE |
+               DRBG_RO_ENT_SRC_LOCK_ENABLE |
+               DRBG_RO_ENT_SRC_ENABLE;
+       tegra_se_write_32(se_dev, SE_RNG_SRC_CONFIG_REG_OFFSET, val);
+
+       /* Set a random value to SRK to initialize DRBG */
+       tegra_se_generate_srk(se_dev);
+}
+
+/*
+ * The function is invoked on SC7 resume
+ */
+void tegra_se_resume(void)
+{
+       tegra_se_warm_boot_resume(&se_dev_1);
+       tegra_se_warm_boot_resume(&se_dev_2);
+}
index 27786d3ca66c5415c92b30c8ce5331b14781a5e7..f52d975d833534c8d12f7ee41acd7a0f4fd214a6 100644 (file)
@@ -1,13 +1,11 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
-
-#include <platform_def.h>
-
+#include <cortex_a57.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
 #include <lib/psci/psci.h>
 #include <plat/common/platform.h>
 
+#include <bpmp.h>
 #include <flowctrl.h>
 #include <pmc.h>
+#include <platform_def.h>
+#include <security_engine.h>
 #include <tegra_def.h>
 #include <tegra_private.h>
+#include <tegra_platform.h>
 
 /*
  * Register used to clear CPU reset signals. Each CPU has two reset
@@ -55,7 +57,7 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
                 * Cluster powerdown/idle request only for afflvl 1
                 */
                req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
-               req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id;
+               req_state->pwr_domain_state[MPIDR_AFFLVL0] = PSTATE_ID_CORE_POWERDN;
 
                break;
 
@@ -87,9 +89,11 @@ plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
                                             const plat_local_state_t *states,
                                             unsigned int ncpu)
 {
-       plat_local_state_t target = *states;
+       plat_local_state_t target = PSCI_LOCAL_STATE_RUN;
        int cpu = plat_my_core_pos();
        int core_pos = read_mpidr() & MPIDR_CPU_MASK;
+       uint32_t bpmp_reply, data[3];
+       int ret;
 
        /* get the power state at this level */
        if (lvl == MPIDR_AFFLVL1)
@@ -97,19 +101,71 @@ plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
        if (lvl == MPIDR_AFFLVL2)
                target = *(states + cpu);
 
-       /* Cluster idle/power-down */
-       if ((lvl == MPIDR_AFFLVL1) && ((target == PSTATE_ID_CLUSTER_IDLE) ||
-           (target == PSTATE_ID_CLUSTER_POWERDN))) {
-               return target;
-       }
+       if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_IDLE)) {
+
+               /* initialize the bpmp interface */
+               ret = tegra_bpmp_init();
+               if (ret != 0U) {
+
+                       /* Cluster idle not allowed */
+                       target = PSCI_LOCAL_STATE_RUN;
+               } else {
+
+                       /* Cluster idle */
+                       data[0] = (uint32_t)cpu;
+                       data[1] = TEGRA_PM_CC6;
+                       data[2] = TEGRA_PM_SC1;
+                       ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
+                                       (void *)&data, (int)sizeof(data),
+                                       (void *)&bpmp_reply,
+                                       (int)sizeof(bpmp_reply));
+
+                       /* check if cluster idle entry is allowed */
+                       if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+
+                               /* Cluster idle not allowed */
+                               target = PSCI_LOCAL_STATE_RUN;
+                       }
+               }
 
-       /* System Suspend */
-       if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
-           (target == PSTATE_ID_SOC_POWERDN))
-               return PSTATE_ID_SOC_POWERDN;
+       } else if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_POWERDN)) {
+
+               /* initialize the bpmp interface */
+               ret = tegra_bpmp_init();
+               if (ret != 0U) {
+
+                       /* Cluster power down not allowed */
+                       target = PSCI_LOCAL_STATE_RUN;
+               } else {
+
+                       /* Cluster power-down */
+                       data[0] = (uint32_t)cpu;
+                       data[1] = TEGRA_PM_CC7;
+                       data[2] = TEGRA_PM_SC1;
+                       ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
+                                       (void *)&data, (int)sizeof(data),
+                                       (void *)&bpmp_reply,
+                                       (int)sizeof(bpmp_reply));
+
+                       /* check if cluster power down is allowed */
+                       if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+
+                               /* Cluster power down not allowed */
+                               target = PSCI_LOCAL_STATE_RUN;
+                       }
+               }
+
+       } else if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
+           (target == PSTATE_ID_SOC_POWERDN)) {
+
+               /* System Suspend */
+               target = PSTATE_ID_SOC_POWERDN;
+
+       } else {
+               ; /* do nothing */
+       }
 
-       /* default state */
-       return PSCI_LOCAL_STATE_RUN;
+       return target;
 }
 
 int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
@@ -120,27 +176,33 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
        unsigned int stateid_afflvl2 = pwr_domain_state[MPIDR_AFFLVL2];
        unsigned int stateid_afflvl1 = pwr_domain_state[MPIDR_AFFLVL1];
        unsigned int stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0];
+       int ret = PSCI_E_SUCCESS;
 
        if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
 
                assert((stateid_afflvl0 == PLAT_MAX_OFF_STATE) ||
-                      (stateid_afflvl0 == PSTATE_ID_SOC_POWERDN));
+                       (stateid_afflvl0 == PSTATE_ID_SOC_POWERDN));
                assert((stateid_afflvl1 == PLAT_MAX_OFF_STATE) ||
-                      (stateid_afflvl1 == PSTATE_ID_SOC_POWERDN));
+                       (stateid_afflvl1 == PSTATE_ID_SOC_POWERDN));
 
-               /* suspend the entire soc */
-               tegra_fc_soc_powerdn(mpidr);
+               if (tegra_chipid_is_t210_b01()) {
+
+                       /* Suspend se/se2 and pka1 */
+                       if (tegra_se_suspend() != 0) {
+                               ret = PSCI_E_INTERN_FAIL;
+                       }
+               }
 
        } else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) {
 
-               assert(stateid_afflvl0 == PSTATE_ID_CLUSTER_IDLE);
+               assert(stateid_afflvl0 == PSTATE_ID_CORE_POWERDN);
 
                /* Prepare for cluster idle */
                tegra_fc_cluster_idle(mpidr);
 
        } else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_POWERDN) {
 
-               assert(stateid_afflvl0 == PSTATE_ID_CLUSTER_POWERDN);
+               assert(stateid_afflvl0 == PSTATE_ID_CORE_POWERDN);
 
                /* Prepare for cluster powerdn */
                tegra_fc_cluster_powerdn(mpidr);
@@ -151,8 +213,30 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
                tegra_fc_cpu_powerdn(mpidr);
 
        } else {
-               ERROR("%s: Unknown state id\n", __func__);
-               return PSCI_E_NOT_SUPPORTED;
+               ERROR("%s: Unknown state id (%d, %d, %d)\n", __func__,
+                       stateid_afflvl2, stateid_afflvl1, stateid_afflvl0);
+               ret = PSCI_E_NOT_SUPPORTED;
+       }
+
+       return ret;
+}
+
+int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+{
+       u_register_t mpidr = read_mpidr();
+       const plat_local_state_t *pwr_domain_state =
+               target_state->pwr_domain_state;
+       unsigned int stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL];
+
+       if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+
+               if (tegra_chipid_is_t210_b01()) {
+                       /* Save tzram contents */
+                       tegra_se_save_tzram();
+               }
+
+               /* enter system suspend */
+               tegra_fc_soc_powerdn(mpidr);
        }
 
        return PSCI_E_SUCCESS;
@@ -160,14 +244,30 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 
 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();
        uint32_t val;
 
+       /* platform parameter passed by the previous bootloader */
+       if (plat_params->l2_ecc_parity_prot_dis != 1) {
+               /* Enable ECC Parity Protection for Cortex-A57 CPUs */
+               val = read_l2ctlr_el1();
+               val |= (uint64_t)CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
+               write_l2ctlr_el1(val);
+       }
+
        /*
         * Check if we are exiting from SOC_POWERDN.
         */
        if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
                        PLAT_SYS_SUSPEND_STATE_ID) {
 
+               /*
+                * Security engine resume
+                */
+               if (tegra_chipid_is_t210_b01()) {
+                       tegra_se_resume();
+               }
+
                /*
                 * Lock scratch registers which hold the CPU vectors
                 */
@@ -231,7 +331,7 @@ int tegra_soc_prepare_system_reset(void)
         * for the PMC APB clock would not be changed due to system reset.
         */
        mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_BURST_POLICY,
-                      SCLK_BURST_POLICY_DEFAULT);
+               SCLK_BURST_POLICY_DEFAULT);
        mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_RATE, 0);
 
        /* Wait 1 ms to make sure clock source/device logic is stabilized. */
index c7f7165c0a7fdcdc29ef4cfb66f31ee1da25c818..6246dde90f98e6dac708fecd6e36909aec9014c4 100644 (file)
@@ -1,34 +1,21 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch_helpers.h>
+#include <bpmp.h>
+#include <cortex_a57.h>
 #include <common/bl_common.h>
 #include <drivers/console.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
-
+#include <platform.h>
+#include <security_engine.h>
 #include <tegra_def.h>
+#include <tegra_platform.h>
 #include <tegra_private.h>
 
-/*******************************************************************************
- * 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.
- *******************************************************************************
- */
-const unsigned char tegra_power_domain_tree_desc[] = {
-       /* No of root nodes */
-       1,
-       /* No of clusters */
-       PLATFORM_CLUSTER_COUNT,
-       /* No of CPU cores - cluster0 */
-       PLATFORM_MAX_CPUS_PER_CLUSTER,
-       /* No of CPU cores - cluster1 */
-       PLATFORM_MAX_CPUS_PER_CLUSTER
-};
-
 /* sets of MMIO ranges setup */
 #define MMIO_RANGE_0_ADDR      0x50000000
 #define MMIO_RANGE_1_ADDR      0x60000000
@@ -39,6 +26,8 @@ const unsigned char tegra_power_domain_tree_desc[] = {
  * Table of regions to map using the MMU.
  */
 static const mmap_region_t tegra_mmap[] = {
+       MAP_REGION_FLAT(TEGRA_IRAM_BASE, 0x40000, /* 256KB */
+                       MT_DEVICE | MT_RW | MT_SECURE),
        MAP_REGION_FLAT(MMIO_RANGE_0_ADDR, MMIO_RANGE_SIZE,
                        MT_DEVICE | MT_RW | MT_SECURE),
        MAP_REGION_FLAT(MMIO_RANGE_1_ADDR, MMIO_RANGE_SIZE,
@@ -53,10 +42,43 @@ static const mmap_region_t tegra_mmap[] = {
  ******************************************************************************/
 const mmap_region_t *plat_get_mmio_map(void)
 {
+       /* Add the map region for security engine SE2 */
+       if (tegra_chipid_is_t210_b01()) {
+               mmap_add_region((uint64_t)TEGRA_SE2_BASE,
+                               (uint64_t)TEGRA_SE2_BASE,
+                               (uint64_t)TEGRA_SE2_RANGE_SIZE,
+                               MT_DEVICE | MT_RW | MT_SECURE);
+       }
+
        /* MMIO space */
        return tegra_mmap;
 }
 
+/*******************************************************************************
+ * 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.
+ *******************************************************************************
+ */
+const unsigned char tegra_power_domain_tree_desc[] = {
+       /* No of root nodes */
+       1,
+       /* No of clusters */
+       PLATFORM_CLUSTER_COUNT,
+       /* No of CPU cores - cluster0 */
+       PLATFORM_MAX_CPUS_PER_CLUSTER,
+       /* No of CPU cores - cluster1 */
+       PLATFORM_MAX_CPUS_PER_CLUSTER
+};
+
+/*******************************************************************************
+ * This function returns the Tegra default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+       return tegra_power_domain_tree_desc;
+}
+
 /*******************************************************************************
  * Handler to get the System Counter Frequency
  ******************************************************************************/
@@ -93,6 +115,28 @@ uint32_t plat_get_console_from_id(int id)
        return tegra210_uart_addresses[id];
 }
 
+/*******************************************************************************
+ * Handler for early platform setup
+ ******************************************************************************/
+void plat_early_platform_setup(void)
+{
+       const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+       uint64_t val;
+
+       /* platform parameter passed by the previous bootloader */
+       if (plat_params->l2_ecc_parity_prot_dis != 1) {
+               /* Enable ECC Parity Protection for Cortex-A57 CPUs */
+               val = read_l2ctlr_el1();
+               val |= (uint64_t)CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
+               write_l2ctlr_el1(val);
+       }
+
+       /* Initialize security engine driver */
+       if (tegra_chipid_is_t210_b01()) {
+               tegra_se_init();
+       }
+}
+
 /*******************************************************************************
  * Initialize the GIC and SGIs
  ******************************************************************************/
index b0a474c88e89c79ef4e1de5f037a0fa71402d722..e23d7e360b6f1fef6d1f54e7e1046e0d16516142 100644 (file)
@@ -16,18 +16,23 @@ $(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                                := 4
+MAX_XLAT_TABLES                                := 10
 $(eval $(call add_define,MAX_XLAT_TABLES))
 
-MAX_MMAP_REGIONS                       := 8
+MAX_MMAP_REGIONS                       := 15
 $(eval $(call add_define,MAX_MMAP_REGIONS))
 
-BL31_SOURCES           +=      lib/cpus/aarch64/cortex_a53.S                   \
+PLAT_INCLUDES          +=      -I${SOC_DIR}/drivers/se
+
+BL31_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      \
                                ${SOC_DIR}/plat_psci_handlers.c                 \
                                ${SOC_DIR}/plat_setup.c                         \
+                               ${SOC_DIR}/drivers/se/security_engine.c         \
                                ${SOC_DIR}/plat_secondary.c
 
 # Enable workarounds for selected Cortex-A57 erratas.
index ab2bf1ba3407d6834029e385f21e7ecd7ea322ad..754831ab5af38caaf87d36e9d224c04a42ed4bc3 100644 (file)
@@ -9,8 +9,6 @@
 
 #include <stdint.h>
 
-#include "../../bl1/bl1_private.h"
-
 void qemu_configure_mmu_svc_mon(unsigned long total_base,
                        unsigned long total_size,
                        unsigned long code_start, unsigned long code_limit,
index 883fc9a16ba3bf30452036888a412217fa8e1a51..1dff69035b122ee86628199d3973e3d1f51a09c0 100644 (file)
@@ -28,7 +28,7 @@ static void bl2_realtime_cpg_init_m3n(void);
 static void bl2_system_cpg_init_m3n(void);
 #endif
 
-#if (RCAR_LSI == RCAR_E3)
+#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_E3)
 static void bl2_realtime_cpg_init_e3(void);
 static void bl2_system_cpg_init_e3(void);
 #endif
@@ -193,7 +193,7 @@ static void bl2_system_cpg_init_m3n(void)
 }
 #endif
 
-#if (RCAR_LSI == RCAR_E3)
+#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_E3)
 static void bl2_realtime_cpg_init_e3(void)
 {
        /* Realtime Module Stop Control Registers */
@@ -251,6 +251,9 @@ void bl2_cpg_init(void)
                case RCAR_PRODUCT_M3N:
                        bl2_realtime_cpg_init_m3n();
                        break;
+               case RCAR_PRODUCT_E3:
+                       bl2_realtime_cpg_init_e3();
+                       break;
                default:
                        panic();
                        break;
@@ -284,6 +287,9 @@ void bl2_system_cpg_init(void)
        case RCAR_PRODUCT_M3N:
                bl2_system_cpg_init_m3n();
                break;
+       case RCAR_PRODUCT_E3:
+               bl2_system_cpg_init_e3();
+               break;
        default:
                panic();
                break;
index 1829e59c1dbce9217df920eb8b95b266440ecb84..3bb03f2e5cb3cf14596e8c4575c7a25921913070 100644 (file)
 #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 */
-/* CPU Auxiliary Control Register */
-#define RCAR_CA57_DIS_LOAD_PASS_STORE  (ULL(1) << 55)
 /* CPG write protect registers         */
 #define        CPGWPR_PASSWORD                 (0x5A5AFFFFU)
 #define        CPGWPCR_PASSWORD                (0xA5A50000U)
index 245a45a32d310f408f519ea174edd66042d70069..47eda9a0218fe4b82866b8a21298f7b3330bbc9e 100644 (file)
@@ -175,7 +175,7 @@ static void __dead2 rcar_system_off(void)
        uint64_t cpu = read_mpidr_el1() & 0x0000ffff;
        int32_t rtn_on;
 
-       rtn_on = cpu_on_check(cpu);
+       rtn_on = rcar_pwrc_cpu_on_check(cpu);
 
        if (cpu == rcar_boot_mpidr)
                panic();
index b9c080259e335f0ecf27973df3af3636052a630f..629a3cf98cdd32ba726e74c13e64cbd1c2a1f110 100644 (file)
@@ -4,7 +4,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-PROGRAMMABLE_RESET_ADDRESS     := 1
+PROGRAMMABLE_RESET_ADDRESS     := 0
 COLD_BOOT_SINGLE_CPU           := 1
 ARM_CCI_PRODUCT_ID             := 500
 TRUSTED_BOARD_BOOT             := 1
index 222a88261a9d58338832fdc6be0f19a514a44e8e..8db2b30d1854f4f69f787fc4be458551b9ca9b6b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #pragma weak plat_rockchip_gic_pcpu_init
 
 /******************************************************************************
- * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
- * interrupts.
+ * List of interrupts.
  *****************************************************************************/
 static const interrupt_prop_t g0_interrupt_props[] = {
-       PLAT_RK_GICV2_G1S_IRQS
+       PLAT_RK_GICV2_G0_IRQS
 };
 
 /*
index 4704a72edb50a3c168e6136cd0c464e67aa3c0f8..0ce13ad129d615f8223de8b71db124505d287441 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #define RK_IRQ_SEC_SGI_7       15
 
 /*
- * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
- * terminology. On a GICv2 system or mode, the lists will be merged and treated
- * as Group 0 interrupts.
+ * Define a list of Group 0 interrupts.
  */
-#define PLAT_RK_GICV2_G1S_IRQS                                         \
+#define PLAT_RK_GICV2_G0_IRQS                                          \
        INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,  \
-                      GICV2_INTR_GROUP1, GIC_INTR_CFG_LEVEL),          \
+                      GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),          \
        INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,      \
-                      GICV2_INTR_GROUP1, GIC_INTR_CFG_LEVEL)
+                      GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
 
 #define SHARE_MEM_BASE          0x100000/* [1MB, 1MB+60K]*/
 #define SHARE_MEM_PAGE_NUM      15
index a7be7c367d8fee54f8763cc2ceb2cc14a2d16abc..10ac77b1ed349777004101fab5442a666968a95a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #define RK_IRQ_SEC_SGI_7       15
 
 /*
- * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
- * terminology. On a GICv2 system or mode, the lists will be merged and treated
- * as Group 0 interrupts.
+ * Define a list of Group 0 interrupts.
  */
-#define PLAT_RK_GICV2_G1S_IRQS                                         \
+#define PLAT_RK_GICV2_G0_IRQS                                          \
        INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,  \
-                      GICV2_INTR_GROUP1, GIC_INTR_CFG_LEVEL)
+                      GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
 
 #endif /* RK3368_DEF_H */
index 559f31634822b395d7863b7ee9cc5ce4daf8a96b..ded92bd3db7240ede2095793e060893dd03847c7 100644 (file)
@@ -27,6 +27,10 @@ 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           \
                                plat/common/aarch64/platform_mp_stack.S \
                                plat/rpi3/aarch64/plat_helpers.S        \
                                plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c \
@@ -130,7 +134,9 @@ endif
 $(eval $(call add_define,RPI3_BL32_RAM_LOCATION_ID))
 $(eval $(call add_define,RPI3_BL33_IN_AARCH32))
 $(eval $(call add_define,RPI3_DIRECT_LINUX_BOOT))
+ifdef RPI3_PRELOADED_DTB_BASE
 $(eval $(call add_define,RPI3_PRELOADED_DTB_BASE))
+endif
 $(eval $(call add_define,RPI3_RUNTIME_UART))
 $(eval $(call add_define,RPI3_USE_UEFI_MAP))
 
index ea4215d83e1952780d152bb9fd8bdbc168cc51d0..b869e9da891790c193a2edb9911439a2b0818f08 100644 (file)
@@ -13,7 +13,6 @@
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
-#include "../../bl1/bl1_private.h"
 #include "rpi3_private.h"
 
 /* Data structure which holds the extents of the trusted SRAM for BL1 */
index 53a2c72b8c5cc118c01d1d2cc7a4947e8c5a6acf..09f0562129ab8e610e4a4ffce40c2afdfa206c90 100644 (file)
 #include <lib/optee_utils.h>
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/rpi3/gpio/rpi3_gpio.h>
 
 #include "rpi3_private.h"
 
 /* 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);
+}
+
 /*******************************************************************************
  * BL1 has passed the extents of the trusted SRAM that should be visible to BL2
  * in x0. This memory layout is sitting at the base of the free trusted SRAM.
@@ -35,6 +48,12 @@ void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
        /* Initialize the console to provide early debug support */
        rpi3_console_init();
 
+       /* Enable arch timer */
+       generic_delay_timer_init();
+
+       /* Setup GPIO driver */
+       rpi3_gpio_setup();
+
        /* Setup the BL2 memory layout */
        bl2_tzram_layout = *mem_layout;
 
index af7f806cd15132bdb16fffcd8f23e179ae79944c..d5c691e198e83e1be4b28ee280abb66f968de35b 100644 (file)
@@ -141,6 +141,7 @@ void bl31_plat_arch_setup(void)
        enable_mmu_el3(0);
 }
 
+#ifdef RPI3_PRELOADED_DTB_BASE
 /*
  * Add information to the device tree (if any) about the reserved DRAM used by
  * the Trusted Firmware.
@@ -204,6 +205,7 @@ static void rpi3_dtb_add_mem_rsv(void)
        INFO("rpi3: Reserved 0x%llx - 0x%llx in DTB\n", SEC_SRAM_BASE,
             SEC_SRAM_BASE + SEC_SRAM_SIZE);
 }
+#endif
 
 void bl31_platform_setup(void)
 {
index 9d86eb8809db804046629f5e5c0ef50e359252fc..61d1837726e40b87a3928ce0af1e5f734572c84b 100644 (file)
 #define RPI3_MINI_UART_BASE            (RPI3_IO_BASE + RPI3_IO_MINI_UART_OFFSET)
 #define RPI3_MINI_UART_CLK_IN_HZ       ULL(500000000)
 
+/*
+ * GPIO controller
+ */
+#define RPI3_IO_GPIO_OFFSET            ULL(0x00200000)
+#define RPI3_GPIO_BASE                 (RPI3_IO_BASE + RPI3_IO_GPIO_OFFSET)
+
 /*
  * Local interrupt controller
  */
index 7e66deb72e1b2ca8d61ad34d4b3ab44abbd93718..49c6a760ca4fd3458c0fe11d206a253f2c2bfac5 100644 (file)
@@ -133,11 +133,6 @@ static const struct plat_io_policy policies[] = {
                (uintptr_t)&bl32_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,
index 3a077d37aadbe3fe7682224b557f0f448a8c2b66..4f586b51408774dc80ab1fa24b3a30bf6ede0bfa 100644 (file)
@@ -140,7 +140,7 @@ static int rpi3_pwr_domain_on(u_register_t mpidr)
  * being turned off earlier. The target_state encodes the low power state that
  * each level has woken up from.
  ******************************************************************************/
-void rpi3_pwr_domain_on_finish(const psci_power_state_t *target_state)
+static void rpi3_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
        assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
                                        PLAT_LOCAL_STATE_OFF);
diff --git a/plat/socionext/synquacer/include/plat.ld.S b/plat/socionext/synquacer/include/plat.ld.S
new file mode 100644 (file)
index 0000000..1b7f699
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SYNQUACER_PLAT_LD_S__
+#define SYNQUACER_PLAT_LD_S__
+
+#include <xlat_tables_defs.h>
+
+#define SPM_SHIM_EXCEPTIONS_VMA                SP_DRAM
+
+MEMORY {
+       SP_DRAM (rw): ORIGIN = PLAT_SQ_SP_PRIV_BASE, LENGTH = PLAT_SQ_SP_PRIV_SIZE
+}
+
+SECTIONS
+{
+       /*
+        * Put the page tables in secure DRAM so that the PTW can make cacheable
+        * accesses, as the core SPM code expects. (The SRAM on SynQuacer does
+        * not support inner shareable WBWA mappings so it is mapped normal
+        * non-cacheable)
+        */
+       sp_xlat_table (NOLOAD) : ALIGN(PAGE_SIZE) {
+               *(sp_xlat_table)
+               *(.bss.sp_base_xlat_table)
+       } >SP_DRAM
+}
+
+#endif /* SYNQUACER_PLAT_LD_S__ */
index de6be7d231f4c89fd3de48e48cf42c042f801b9f..0cec81b8d0dce67aec7191422cb15bd98424b740 100644 (file)
@@ -29,8 +29,8 @@
 
 #define PLAT_PHY_ADDR_SPACE_SIZE       (1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE      (1ULL << 32)
-#define MAX_XLAT_TABLES                        4
-#define MAX_MMAP_REGIONS               6
+#define MAX_XLAT_TABLES                        8
+#define MAX_MMAP_REGIONS               8
 
 #define PLATFORM_STACK_SIZE            0x400
 
 #define BL31_SIZE                      0x00080000
 #define BL31_LIMIT                     (BL31_BASE + BL31_SIZE)
 
+#define BL32_BASE                      0xfc000000
+#define BL32_SIZE                      0x03c00000
+#define BL32_LIMIT                     (BL32_BASE + BL32_SIZE)
+
 #define PLAT_SQ_CCN_BASE               0x32000000
 #define PLAT_SQ_CLUSTER_TO_CCN_ID_MAP                                  \
                                        0,      /* Cluster 0 */         \
 
 #define PLAT_SQ_GPIO_BASE              0x51000000
 
+#define PLAT_SPM_BUF_BASE              (BL32_LIMIT - 32 * PLAT_SPM_BUF_SIZE)
+#define PLAT_SPM_BUF_SIZE              ULL(0x10000)
+#define PLAT_SPM_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)
+
+#define PLAT_SP_IMAGE_NS_BUF_BASE      BL32_LIMIT
+#define PLAT_SP_IMAGE_NS_BUF_SIZE      ULL(0x200000)
+#define PLAT_SP_IMAGE_NS_BUF_MMAP      MAP_REGION2(PLAT_SP_IMAGE_NS_BUF_BASE, \
+                                                   PLAT_SP_IMAGE_NS_BUF_BASE, \
+                                                   PLAT_SP_IMAGE_NS_BUF_SIZE, \
+                                                   MT_RW_DATA | MT_NS | \
+                                                   MT_USER, PAGE_SIZE)
+
+#define PLAT_SP_IMAGE_STACK_PCPU_SIZE  ULL(0x10000)
+#define PLAT_SP_IMAGE_STACK_SIZE       (32 * PLAT_SP_IMAGE_STACK_PCPU_SIZE)
+#define PLAT_SP_IMAGE_STACK_BASE       (PLAT_SQ_SP_HEAP_BASE + PLAT_SQ_SP_HEAP_SIZE)
+
+#define PLAT_SQ_SP_IMAGE_SIZE          ULL(0x200000)
+#define PLAT_SQ_SP_IMAGE_MMAP          MAP_REGION2(BL32_BASE, BL32_BASE, \
+                                                   PLAT_SQ_SP_IMAGE_SIZE, \
+                                                   MT_CODE | MT_SECURE | \
+                                                   MT_USER, PAGE_SIZE)
+
+#define PLAT_SQ_SP_HEAP_BASE           (BL32_BASE + PLAT_SQ_SP_IMAGE_SIZE)
+#define PLAT_SQ_SP_HEAP_SIZE           ULL(0x800000)
+
+#define PLAT_SQ_SP_IMAGE_RW_MMAP       MAP_REGION2(PLAT_SQ_SP_HEAP_BASE, \
+                                                   PLAT_SQ_SP_HEAP_BASE, \
+                                                   (PLAT_SQ_SP_HEAP_SIZE + \
+                                                    PLAT_SP_IMAGE_STACK_SIZE), \
+                                                   MT_RW_DATA | MT_SECURE | \
+                                                   MT_USER, PAGE_SIZE)
+
+#define PLAT_SQ_SP_PRIV_BASE           (PLAT_SP_IMAGE_STACK_BASE + \
+                                        PLAT_SP_IMAGE_STACK_SIZE)
+#define PLAT_SQ_SP_PRIV_SIZE           ULL(0x40000)
+
+#define PLAT_SP_PRI                    0x20
+#define PLAT_PRI_BITS                  2
+#define PLAT_SPM_COOKIE_0              ULL(0)
+#define PLAT_SPM_COOKIE_1              ULL(0)
+
+/* Total number of memory regions with distinct properties */
+#define PLAT_SP_IMAGE_NUM_MEM_REGIONS  6
+
+#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_SQ_UART1_BASE             PLAT_SQ_BOOT_UART_BASE
+#define PLAT_SQ_UART1_SIZE             ULL(0x1000)
+#define PLAT_SQ_UART1_MMAP             MAP_REGION_FLAT(PLAT_SQ_UART1_BASE, \
+                                                       PLAT_SQ_UART1_SIZE, \
+                                                       MT_DEVICE | MT_RW | \
+                                                       MT_NS | MT_PRIVILEGED)
+
+#define PLAT_SQ_PERIPH_BASE            0x50000000
+#define PLAT_SQ_PERIPH_SIZE            ULL(0x8000000)
+#define PLAT_SQ_PERIPH_MMAP            MAP_REGION_FLAT(PLAT_SQ_PERIPH_BASE, \
+                                                       PLAT_SQ_PERIPH_SIZE, \
+                                                       MT_DEVICE | MT_RW | \
+                                                       MT_NS | MT_USER)
+
+#define PLAT_SQ_FLASH_BASE             0x08000000
+#define PLAT_SQ_FLASH_SIZE             ULL(0x8000000)
+#define PLAT_SQ_FLASH_MMAP             MAP_REGION_FLAT(PLAT_SQ_FLASH_BASE, \
+                                                       PLAT_SQ_FLASH_SIZE, \
+                                                       MT_DEVICE | MT_RW | \
+                                                       MT_NS | MT_USER)
+
 #endif /* PLATFORM_DEF_H */
index 1bee20abbb66ae21a7063c890b8e35ecdaa463e4..53c39a0fc9c87ffac15710ed126bd3498d450fb5 100644 (file)
@@ -17,10 +17,6 @@ ERRATA_A53_855873            := 1
 # Libraries
 include lib/xlat_tables_v2/xlat_tables.mk
 
-ifeq (${SPD},opteed)
-TF_CFLAGS_aarch64      +=      -DBL32_BASE=0xfc000000
-endif
-
 PLAT_PATH              :=      plat/socionext/synquacer
 PLAT_INCLUDES          :=      -I$(PLAT_PATH)/include          \
                                -I$(PLAT_PATH)/drivers/scpi     \
@@ -47,3 +43,9 @@ BL31_SOURCES          +=      drivers/arm/ccn/ccn.c                   \
                                $(PLAT_PATH)/sq_xlat_setup.c            \
                                $(PLAT_PATH)/drivers/scpi/sq_scpi.c     \
                                $(PLAT_PATH)/drivers/mhu/sq_mhu.c
+
+ifeq (${ENABLE_SPM},1)
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
+BL31_SOURCES           +=      $(PLAT_PATH)/sq_spm.c
+endif
index f8d252622c7c72f5a8ffbe7618c3d3e27e5faea6..fef84efd7d8238d644466aaf812ad2bbe1092faf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,6 +21,10 @@ static console_pl011_t console;
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
 
+IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_START__, SPM_SHIM_EXCEPTIONS_START);
+IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_END__,   SPM_SHIM_EXCEPTIONS_END);
+IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_LMA__,   SPM_SHIM_EXCEPTIONS_LMA);
+
 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
 {
        assert(sec_state_is_valid(type));
@@ -76,7 +80,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
        /* Initialize power controller before setting up topology */
        plat_sq_pwrc_setup();
 
-#ifdef BL32_BASE
+#ifdef SPD_opteed
        struct draminfo di = {0};
 
        scpi_get_draminfo(&di);
@@ -98,7 +102,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
        } else {
                NOTICE("OP-TEE has not been loaded by SCP firmware\n");
        }
-#endif /* BL32_BASE */
+#endif /* SPD_opteed */
 
        /* Populate entry point information for BL33 */
        SET_PARAM_HEAD(&bl33_image_ep_info,
@@ -155,8 +159,27 @@ void bl31_plat_runtime_setup(void)
 
 void bl31_plat_arch_setup(void)
 {
-       sq_mmap_setup(BL31_BASE, BL31_SIZE, NULL);
+       static const mmap_region_t secure_partition_mmap[] = {
+#if ENABLE_SPM && SPM_MM
+               MAP_REGION_FLAT(PLAT_SPM_BUF_BASE,
+                               PLAT_SPM_BUF_SIZE,
+                               MT_RW_DATA | MT_SECURE),
+               MAP_REGION_FLAT(PLAT_SQ_SP_PRIV_BASE,
+                               PLAT_SQ_SP_PRIV_SIZE,
+                               MT_RW_DATA | MT_SECURE),
+#endif
+               {0},
+       };
+
+       sq_mmap_setup(BL31_BASE, BL31_SIZE, secure_partition_mmap);
        enable_mmu_el3(XLAT_TABLE_NC);
+
+#if ENABLE_SPM && SPM_MM
+       memcpy((void *)SPM_SHIM_EXCEPTIONS_START,
+              (void *)SPM_SHIM_EXCEPTIONS_LMA,
+              (uintptr_t)SPM_SHIM_EXCEPTIONS_END -
+              (uintptr_t)SPM_SHIM_EXCEPTIONS_START);
+#endif
 }
 
 void bl31_plat_enable_mmu(uint32_t flags)
diff --git a/plat/socionext/synquacer/sq_spm.c b/plat/socionext/synquacer/sq_spm.c
new file mode 100644 (file)
index 0000000..01cce17
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <bl31/ehf.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <services/secure_partition.h>
+
+static const mmap_region_t plat_arm_secure_partition_mmap[] = {
+       PLAT_SQ_FLASH_MMAP,
+       PLAT_SQ_UART1_MMAP,
+       PLAT_SQ_PERIPH_MMAP,
+       PLAT_SQ_SP_IMAGE_MMAP,
+       PLAT_SP_IMAGE_NS_BUF_MMAP,
+       PLAT_SQ_SP_IMAGE_RW_MMAP,
+       PLAT_SPM_SPM_BUF_EL0_MMAP,
+       {0}
+};
+
+/*
+ * Boot information passed to a secure partition during initialisation. Linear
+ * indices in MP information will be filled at runtime.
+ */
+static secure_partition_mp_info_t sp_mp_info[] = {
+       {0x80000000, 0}, {0x80000001, 0}, {0x80000100, 0}, {0x80000101, 0},
+       {0x80000200, 0}, {0x80000201, 0}, {0x80000300, 0}, {0x80000301, 0},
+       {0x80000400, 0}, {0x80000401, 0}, {0x80000500, 0}, {0x80000501, 0},
+       {0x80000600, 0}, {0x80000601, 0}, {0x80000700, 0}, {0x80000701, 0},
+       {0x80000800, 0}, {0x80000801, 0}, {0x80000900, 0}, {0x80000901, 0},
+       {0x80000a00, 0}, {0x80000a01, 0}, {0x80000b00, 0}, {0x80000b01, 0},
+};
+
+const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
+       .h.type                 = PARAM_SP_IMAGE_BOOT_INFO,
+       .h.version              = VERSION_1,
+       .h.size                 = sizeof(secure_partition_boot_info_t),
+       .h.attr                 = 0,
+       .sp_mem_base            = BL32_BASE,
+       .sp_mem_limit           = BL32_LIMIT,
+       .sp_image_base          = BL32_BASE,
+       .sp_stack_base          = PLAT_SP_IMAGE_STACK_BASE,
+       .sp_heap_base           = PLAT_SQ_SP_HEAP_BASE,
+       .sp_ns_comm_buf_base    = PLAT_SP_IMAGE_NS_BUF_BASE,
+       .sp_shared_buf_base     = PLAT_SPM_BUF_BASE,
+       .sp_image_size          = PLAT_SQ_SP_IMAGE_SIZE,
+       .sp_pcpu_stack_size     = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
+       .sp_heap_size           = PLAT_SQ_SP_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     = PLAT_SP_IMAGE_NUM_MEM_REGIONS,
+       .num_cpus               = PLATFORM_CORE_COUNT,
+       .mp_info                = sp_mp_info,
+};
+
+const struct mmap_region *plat_get_secure_partition_mmap(void *cookie)
+{
+       return plat_arm_secure_partition_mmap;
+}
+
+const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
+               void *cookie)
+{
+       return &plat_arm_secure_partition_boot_info;
+}
+
+static ehf_pri_desc_t sq_exceptions[] = {
+       EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI),
+};
+EHF_REGISTER_PRIORITIES(sq_exceptions, ARRAY_SIZE(sq_exceptions), PLAT_PRI_BITS);
index 45a352e0c5a12434cb97f24df0722463e8094f89..8ccbc246c9a13fcd77d91a8c270ec015fb48e050 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -58,13 +58,26 @@ static const io_block_dev_spec_t mmc_block_dev_spec = {
 static uintptr_t storage_dev_handle;
 static const io_dev_connector_t *mmc_dev_con;
 
-#define IMG_IDX_BL33           0
+static const io_block_spec_t bl32_block_spec = {
+       .offset = BL32_BASE,
+       .length = STM32MP1_BL32_SIZE
+};
+
+static const io_block_spec_t bl2_block_spec = {
+       .offset = BL2_BASE,
+       .length = STM32MP1_BL2_SIZE,
+};
 
 static const struct stm32image_part_info bl33_partition_spec = {
        .name = BL33_IMAGE_NAME,
        .binary_type = BL33_BINARY_TYPE,
 };
 
+enum {
+       IMG_IDX_BL33,
+       IMG_IDX_NUM
+};
+
 static struct stm32image_device_info stm32image_dev_info_spec = {
        .lba_size = MMC_BLOCK_SIZE,
        .part_info[IMG_IDX_BL33] = {
@@ -73,19 +86,12 @@ static struct stm32image_device_info stm32image_dev_info_spec = {
        },
 };
 
-static io_block_spec_t stm32image_block_spec;
-
-static const io_dev_connector_t *stm32image_dev_con;
-
-static const io_block_spec_t bl32_block_spec = {
-       .offset = BL32_BASE,
-       .length = STM32MP1_BL32_SIZE
+static io_block_spec_t stm32image_block_spec = {
+       .offset = 0,
+       .length = 0,
 };
 
-static const io_block_spec_t bl2_block_spec = {
-       .offset = BL2_BASE,
-       .length = STM32MP1_BL2_SIZE,
-};
+static const io_dev_connector_t *stm32image_dev_con;
 
 static int open_dummy(const uintptr_t spec);
 static int open_image(const uintptr_t spec);
@@ -160,83 +166,18 @@ static void print_boot_device(boot_api_context_t *boot_context)
        }
 }
 
-static void print_reset_reason(void)
-{
-       uint32_t rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
-
-       if (rstsr == 0U) {
-               WARN("Reset reason unknown\n");
-               return;
-       }
-
-       INFO("Reset reason (0x%x):\n", rstsr);
-
-       if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U) {
-               if ((rstsr & RCC_MP_RSTSCLRR_STDBYRSTF) != 0U) {
-                       INFO("System exits from STANDBY\n");
-                       return;
-               }
-
-               if ((rstsr & RCC_MP_RSTSCLRR_CSTDBYRSTF) != 0U) {
-                       INFO("MPU exits from CSTANDBY\n");
-                       return;
-               }
-       }
-
-       if ((rstsr & RCC_MP_RSTSCLRR_PORRSTF) != 0U) {
-               INFO("  Power-on Reset (rst_por)\n");
-               return;
-       }
-
-       if ((rstsr & RCC_MP_RSTSCLRR_BORRSTF) != 0U) {
-               INFO("  Brownout Reset (rst_bor)\n");
-               return;
-       }
-
-       if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) {
-               INFO("  System reset generated by MPU (MPSYSRST)\n");
-               return;
-       }
-
-       if ((rstsr & RCC_MP_RSTSCLRR_HCSSRSTF) != 0U) {
-               INFO("  Reset due to a clock failure on HSE\n");
-               return;
-       }
-
-       if ((rstsr & RCC_MP_RSTSCLRR_IWDG1RSTF) != 0U) {
-               INFO("  IWDG1 Reset (rst_iwdg1)\n");
-               return;
-       }
-
-       if ((rstsr & RCC_MP_RSTSCLRR_IWDG2RSTF) != 0U) {
-               INFO("  IWDG2 Reset (rst_iwdg2)\n");
-               return;
-       }
-
-       if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
-               INFO("  Pad Reset from NRST\n");
-               return;
-       }
-
-       if ((rstsr & RCC_MP_RSTSCLRR_VCORERSTF) != 0U) {
-               INFO("  Reset due to a failure of VDD_CORE\n");
-               return;
-       }
-
-       ERROR("  Unidentified reset reason\n");
-}
-
 void stm32mp1_io_setup(void)
 {
        int io_result __unused;
+       uint8_t idx;
+       struct stm32image_part_info *part;
        struct stm32_sdmmc2_params params;
        struct mmc_device_info device_info;
        uintptr_t mmc_default_instance;
+       const partition_entry_t *entry;
        boot_api_context_t *boot_context =
                (boot_api_context_t *)stm32mp1_get_boot_ctx_address();
 
-       print_reset_reason();
-
        print_boot_device(boot_context);
 
        if ((boot_context->boot_partition_used_toboot == 1U) ||
@@ -255,7 +196,7 @@ void stm32mp1_io_setup(void)
        switch (boot_context->boot_interface_selected) {
        case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
        case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
-               dmb();
+               dmbsy();
 
                memset(&params, 0, sizeof(struct stm32_sdmmc2_params));
 
@@ -309,14 +250,19 @@ void stm32mp1_io_setup(void)
 
                stm32image_dev_info_spec.device_size =
                        stm32_sdmmc2_mmc_get_device_size();
-               stm32image_dev_info_spec.part_info[IMG_IDX_BL33].part_offset =
-                       get_partition_entry(BL33_IMAGE_NAME)->start;
-               stm32image_dev_info_spec.part_info[IMG_IDX_BL33].bkp_offset =
-                       get_partition_entry(BL33_IMAGE_NAME)->length;
-
-               stm32image_block_spec.offset = 0;
-               stm32image_block_spec.length =
-                       get_partition_entry(BL33_IMAGE_NAME)->length;
+
+               for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
+                       part = &stm32image_dev_info_spec.part_info[idx];
+                       entry = get_partition_entry(part->name);
+                       if (entry == NULL) {
+                               ERROR("Partition %s not found\n",
+                                     part->name);
+                               panic();
+                       }
+
+                       part->part_offset = entry->start;
+                       part->bkp_offset = 0U;
+               }
 
                /*
                 * Re-open MMC with io_mmc, for better perfs compared to
index 6af65fd26edc50e8405044075f79fed29f6f25db..a1ffd5a9db5a05d572add84f5251e314dbb6887a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,8 +16,8 @@
 #include <drivers/delay_timer.h>
 #include <drivers/generic_delay_timer.h>
 #include <drivers/st/stm32_console.h>
+#include <drivers/st/stm32mp_pmic.h>
 #include <drivers/st/stm32mp1_clk.h>
-#include <drivers/st/stm32mp1_pmic.h>
 #include <drivers/st/stm32mp1_pwr.h>
 #include <drivers/st/stm32mp1_ram.h>
 #include <drivers/st/stm32mp1_rcc.h>
 
 static struct console_stm32 console;
 
-void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
-                                 u_register_t arg2, u_register_t arg3)
+static void print_reset_reason(void)
+{
+       uint32_t rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
+
+       if (rstsr == 0U) {
+               WARN("Reset reason unknown\n");
+               return;
+       }
+
+       INFO("Reset reason (0x%x):\n", rstsr);
+
+       if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U) {
+               if ((rstsr & RCC_MP_RSTSCLRR_STDBYRSTF) != 0U) {
+                       INFO("System exits from STANDBY\n");
+                       return;
+               }
+
+               if ((rstsr & RCC_MP_RSTSCLRR_CSTDBYRSTF) != 0U) {
+                       INFO("MPU exits from CSTANDBY\n");
+                       return;
+               }
+       }
+
+       if ((rstsr & RCC_MP_RSTSCLRR_PORRSTF) != 0U) {
+               INFO("  Power-on Reset (rst_por)\n");
+               return;
+       }
+
+       if ((rstsr & RCC_MP_RSTSCLRR_BORRSTF) != 0U) {
+               INFO("  Brownout Reset (rst_bor)\n");
+               return;
+       }
+
+       if ((rstsr & RCC_MP_RSTSCLRR_MCSYSRSTF) != 0U) {
+               if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
+                       INFO("  System reset generated by MCU (MCSYSRST)\n");
+               } else {
+                       INFO("  Local reset generated by MCU (MCSYSRST)\n");
+               }
+               return;
+       }
+
+       if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) {
+               INFO("  System reset generated by MPU (MPSYSRST)\n");
+               return;
+       }
+
+       if ((rstsr & RCC_MP_RSTSCLRR_HCSSRSTF) != 0U) {
+               INFO("  Reset due to a clock failure on HSE\n");
+               return;
+       }
+
+       if ((rstsr & RCC_MP_RSTSCLRR_IWDG1RSTF) != 0U) {
+               INFO("  IWDG1 Reset (rst_iwdg1)\n");
+               return;
+       }
+
+       if ((rstsr & RCC_MP_RSTSCLRR_IWDG2RSTF) != 0U) {
+               INFO("  IWDG2 Reset (rst_iwdg2)\n");
+               return;
+       }
+
+       if ((rstsr & RCC_MP_RSTSCLRR_MPUP0RSTF) != 0U) {
+               INFO("  MPU Processor 0 Reset\n");
+               return;
+       }
+
+       if ((rstsr & RCC_MP_RSTSCLRR_MPUP1RSTF) != 0U) {
+               INFO("  MPU Processor 1 Reset\n");
+               return;
+       }
+
+       if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
+               INFO("  Pad Reset from NRST\n");
+               return;
+       }
+
+       if ((rstsr & RCC_MP_RSTSCLRR_VCORERSTF) != 0U) {
+               INFO("  Reset due to a failure of VDD_CORE\n");
+               return;
+       }
+
+       ERROR("  Unidentified reset reason\n");
+}
+
+void bl2_el3_early_platform_setup(u_register_t arg0,
+                                 u_register_t arg1 __unused,
+                                 u_register_t arg2 __unused,
+                                 u_register_t arg3 __unused)
 {
        stm32mp1_save_boot_ctx_address(arg0);
 }
@@ -59,12 +146,38 @@ void bl2_platform_setup(void)
 void bl2_el3_plat_arch_setup(void)
 {
        int32_t result;
-       struct dt_node_info dt_dev_info;
+       struct dt_node_info dt_uart_info;
        const char *board_model;
        boot_api_context_t *boot_context =
                (boot_api_context_t *)stm32mp1_get_boot_ctx_address();
        uint32_t clk_rate;
 
+       mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+                       BL_CODE_END - BL_CODE_BASE,
+                       MT_CODE | MT_SECURE);
+
+       /* Prevent corruption of preloaded BL32 */
+       mmap_add_region(BL32_BASE, BL32_BASE,
+                       BL32_LIMIT - BL32_BASE,
+                       MT_MEMORY | MT_RO | MT_SECURE);
+
+       /* Map non secure DDR for BL33 load and DDR training area restore */
+       mmap_add_region(STM32MP1_DDR_BASE,
+                       STM32MP1_DDR_BASE,
+                       STM32MP1_DDR_MAX_SIZE,
+                       MT_MEMORY | MT_RW | MT_NS);
+
+       /* Prevent corruption of preloaded Device Tree */
+       mmap_add_region(DTB_BASE, DTB_BASE,
+                       DTB_LIMIT - DTB_BASE,
+                       MT_MEMORY | MT_RO | MT_SECURE);
+
+       configure_mmu();
+
+       if (dt_open_and_check() < 0) {
+               panic();
+       }
+
        /*
         * Disable the backup domain write protection.
         * The protection is enable at each reset by hardware
@@ -88,28 +201,8 @@ void bl2_el3_plat_arch_setup(void)
                mmio_clrbits_32(RCC_BASE + RCC_BDCR, RCC_BDCR_VSWRST);
        }
 
-       mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
-                       BL_CODE_END - BL_CODE_BASE,
-                       MT_CODE | MT_SECURE);
-
-       /* Prevent corruption of preloaded BL32 */
-       mmap_add_region(BL32_BASE, BL32_BASE,
-                       BL32_LIMIT - BL32_BASE,
-                       MT_MEMORY | MT_RO | MT_SECURE);
-
-       /* Prevent corruption of preloaded Device Tree */
-       mmap_add_region(DTB_BASE, DTB_BASE,
-                       DTB_LIMIT - DTB_BASE,
-                       MT_MEMORY | MT_RO | MT_SECURE);
-
-       configure_mmu();
-
        generic_delay_timer_init();
 
-       if (dt_open_and_check() < 0) {
-               panic();
-       }
-
        if (stm32mp1_clk_probe() < 0) {
                panic();
        }
@@ -118,12 +211,12 @@ void bl2_el3_plat_arch_setup(void)
                panic();
        }
 
-       result = dt_get_stdout_uart_info(&dt_dev_info);
+       result = dt_get_stdout_uart_info(&dt_uart_info);
 
        if ((result <= 0) ||
-           (dt_dev_info.status == 0U) ||
-           (dt_dev_info.clock < 0) ||
-           (dt_dev_info.reset < 0)) {
+           (dt_uart_info.status == 0U) ||
+           (dt_uart_info.clock < 0) ||
+           (dt_uart_info.reset < 0)) {
                goto skip_console_init;
        }
 
@@ -131,25 +224,25 @@ void bl2_el3_plat_arch_setup(void)
                goto skip_console_init;
        }
 
-       if (stm32mp1_clk_enable((unsigned long)dt_dev_info.clock) != 0) {
+       if (stm32mp1_clk_enable((unsigned long)dt_uart_info.clock) != 0) {
                goto skip_console_init;
        }
 
-       stm32mp1_reset_assert((uint32_t)dt_dev_info.reset);
+       stm32mp1_reset_assert((uint32_t)dt_uart_info.reset);
        udelay(2);
-       stm32mp1_reset_deassert((uint32_t)dt_dev_info.reset);
+       stm32mp1_reset_deassert((uint32_t)dt_uart_info.reset);
        mdelay(1);
 
-       clk_rate = stm32mp1_clk_get_rate((unsigned long)dt_dev_info.clock);
+       clk_rate = stm32mp1_clk_get_rate((unsigned long)dt_uart_info.clock);
 
-       if (console_stm32_register(dt_dev_info.base, clk_rate,
+       if (console_stm32_register(dt_uart_info.base, clk_rate,
                                   STM32MP1_UART_BAUDRATE, &console) == 0) {
                panic();
        }
 
        board_model = dt_get_board_model();
        if (board_model != NULL) {
-               NOTICE("%s\n", board_model);
+               NOTICE("Model: %s\n", board_model);
        }
 
 skip_console_init:
@@ -162,5 +255,7 @@ skip_console_init:
 
        stm32mp1_arch_security_setup();
 
+       print_reset_reason();
+
        stm32mp1_io_setup();
 }
index 1b4df163bbc0aef167a1d2a0132024ab2a04cc1b..6d3d36dbad4e7a556779b237c1da20b10bdcc926 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,8 +30,8 @@
 #define BL33_BINARY_TYPE               U(0x0)
 
 #define STM32MP1_PRIMARY_CPU           U(0x0)
+#define STM32MP1_SECONDARY_CPU         U(0x1)
 
-#define PLATFORM_CACHE_LINE_SIZE       64
 #define PLATFORM_CLUSTER_COUNT         ULL(1)
 #define PLATFORM_CLUSTER0_CORE_COUNT   U(2)
 #define PLATFORM_CLUSTER1_CORE_COUNT   U(0)
@@ -39,9 +39,9 @@
                                         PLATFORM_CLUSTER0_CORE_COUNT)
 #define PLATFORM_MAX_CPUS_PER_CLUSTER  2
 
-#define MAX_IO_DEVICES                 4
-#define MAX_IO_HANDLES                 4
-#define MAX_IO_BLOCK_DEVICES           1
+#define MAX_IO_DEVICES                 U(4)
+#define MAX_IO_HANDLES                 U(4)
+#define MAX_IO_BLOCK_DEVICES           U(1)
 
 /*******************************************************************************
  * BL2 specific defines.
@@ -81,8 +81,8 @@
 /*******************************************************************************
  * 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 PLAT_PHY_ADDR_SPACE_SIZE       (ULL(1) << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE      (ULL(1) << 32)
 
 /*******************************************************************************
  * Declarations and constants to access the mailboxes safely. Each mailbox is
        INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER,           \
                       GIC_HIGHEST_SEC_PRIORITY,        \
                       grp, GIC_INTR_CFG_LEVEL),        \
-       INTR_PROP_DESC(STM32MP1_IRQ_TAMPSERRS,          \
-                      GIC_HIGHEST_SEC_PRIORITY,        \
-                      grp, GIC_INTR_CFG_LEVEL),        \
        INTR_PROP_DESC(STM32MP1_IRQ_AXIERRIRQ,          \
                       GIC_HIGHEST_SEC_PRIORITY,        \
                       grp, GIC_INTR_CFG_LEVEL),        \
index 19549ee9767b2b8b3323f81586b660ad8f025123..d5640c1fd5607c229dd397d26882c83d1f9f2bb3 100644 (file)
@@ -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
  */
@@ -9,12 +9,16 @@
 
 #include <stdbool.h>
 
+#define DT_DISABLED            U(0)
+#define DT_NON_SECURE          U(1)
+#define DT_SECURE              U(2)
+#define DT_SHARED              (DT_NON_SECURE | DT_SECURE)
+
 struct dt_node_info {
        uint32_t base;
        int32_t clock;
        int32_t reset;
-       bool status;
-       bool sec_status;
+       uint32_t status;
 };
 
 /*******************************************************************************
@@ -23,13 +27,11 @@ struct dt_node_info {
 int dt_open_and_check(void);
 int fdt_get_address(void **fdt_addr);
 bool fdt_check_node(int node);
-bool fdt_check_status(int node);
-bool fdt_check_secure_status(int node);
+uint32_t fdt_get_status(int node);
 uint32_t fdt_read_uint32_default(int node, const char *prop_name,
                                 uint32_t dflt_value);
 int fdt_read_uint32_array(int node, const char *prop_name,
                          uint32_t *array, uint32_t count);
-int dt_set_pinctrl_config(int node);
 int dt_set_stdout_pinctrl(void);
 void dt_fill_device_info(struct dt_node_info *info, int node);
 int dt_get_node(struct dt_node_info *info, int offset, const char *compat);
index 3404bc685037fa0826b4daf30bb8207e753bfd6f..04c9a9ad5fb566230eb23d1ca1bf8d97d768b1af 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,4 +21,8 @@ uintptr_t stm32mp1_get_boot_ctx_address(void);
 void stm32mp1_gic_pcpu_init(void);
 void stm32mp1_gic_init(void);
 
+uintptr_t stm32_get_gpio_bank_base(unsigned int bank);
+unsigned long stm32_get_gpio_bank_clock(unsigned int bank);
+uint32_t stm32_get_gpio_bank_offset(unsigned int bank);
+
 #endif /* STM32MP1_PRIVATE_H */
diff --git a/plat/st/stm32mp1/include/stm32mp1_smc.h b/plat/st/stm32mp1/include/stm32mp1_smc.h
new file mode 100644 (file)
index 0000000..b872758
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP1_SMC_H
+#define STM32MP1_SMC_H
+
+/*
+ * SMC function IDs for STM32 Service queries
+ * STM32 SMC services use the space between 0x82000000 and 0x8200FFFF
+ * like this is defined in SMC calling Convention by ARM
+ * for SiP (silicon Partner)
+ * https://developer.arm.com/docs/den0028/latest
+ */
+
+/* Secure Service access from Non-secure */
+
+/*
+ * STM32_SMC_BSEC call API
+ *
+ * Argument a0: (input) SMCC ID
+ *             (output) status return code
+ * Argument a1: (input) Service ID (STM32_SMC_BSEC_xxx)
+ * Argument a2: (input) OTP index
+ *             (output) OTP read value, if applicable
+ * Argument a3: (input) OTP value if applicable
+ */
+#define STM32_SMC_BSEC                 0x82001003
+
+/* SMC function IDs for SiP Service queries */
+#define STM32_SIP_SVC_CALL_COUNT       0x8200ff00
+#define STM32_SIP_SVC_UID              0x8200ff01
+/*                                     0x8200ff02 is reserved */
+#define STM32_SIP_SVC_VERSION          0x8200ff03
+
+/* STM32 SiP Service Calls version numbers */
+#define STM32_SIP_SVC_VERSION_MAJOR    0x0
+#define STM32_SIP_SVC_VERSION_MINOR    0x1
+
+/* Number of STM32 SiP Calls implemented */
+#define STM32_COMMON_SIP_NUM_CALLS     4
+
+/* Service for BSEC */
+#define STM32_SMC_READ_SHADOW          0x01
+#define STM32_SMC_PROG_OTP             0x02
+#define STM32_SMC_WRITE_SHADOW         0x03
+#define STM32_SMC_READ_OTP             0x04
+
+#endif /* STM32MP1_SMC_H */
index 60852c6b4f965e940a6ab81f99584ba182f0c110..4288f23d9140ee574ef02ac99ce0b37375a82b09 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -24,8 +24,8 @@ $(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES))
 PLAT_INCLUDES          :=      -Iplat/st/stm32mp1/include/
 
 # Device tree
-STM32_DTB_FILE_NAME    ?=      stm32mp157c-ev1.dtb
-FDT_SOURCES            :=      $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32_DTB_FILE_NAME)))
+DTB_FILE_NAME          ?=      stm32mp157c-ev1.dtb
+FDT_SOURCES            :=      $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(DTB_FILE_NAME)))
 DTC_FLAGS              +=      -Wno-unit_address_vs_reg
 
 include lib/libfdt/libfdt.mk
@@ -47,13 +47,14 @@ PLAT_BL_COMMON_SOURCES      +=      ${LIBFDT_SRCS}                                          \
                                drivers/arm/tzc/tzc400.c                                \
                                drivers/delay_timer/delay_timer.c                       \
                                drivers/delay_timer/generic_delay_timer.c               \
+                               drivers/st/bsec/bsec.c                                  \
                                drivers/st/clk/stm32mp1_clk.c                           \
                                drivers/st/clk/stm32mp1_clkfunc.c                       \
                                drivers/st/ddr/stm32mp1_ddr_helpers.c                   \
                                drivers/st/gpio/stm32_gpio.c                            \
-                               drivers/st/pmic/stm32_i2c.c                             \
-                               drivers/st/pmic/stm32mp1_pmic.c                         \
-                               drivers/st/pmic/stpmu1.c                                \
+                               drivers/st/i2c/stm32_i2c.c                              \
+                               drivers/st/pmic/stm32mp_pmic.c                          \
+                               drivers/st/pmic/stpmic1.c                               \
                                drivers/st/reset/stm32mp1_reset.c                       \
                                plat/st/stm32mp1/stm32mp1_context.c                     \
                                plat/st/stm32mp1/stm32mp1_dt.c                          \
@@ -82,13 +83,13 @@ BL2_SOURCES         +=      common/desc_image_load.c                                \
 
 # Macros and rules to build TF binary
 STM32_TF_ELF_LDFLAGS   :=      --hash-style=gnu --as-needed
-STM32_DT_BASENAME      :=      $(STM32_DTB_FILE_NAME:.dtb=)
+STM32_DT_BASENAME      :=      $(DTB_FILE_NAME:.dtb=)
 STM32_TF_STM32         :=      ${BUILD_PLAT}/tf-a-${STM32_DT_BASENAME}.stm32
 STM32_TF_BINARY                :=      $(STM32_TF_STM32:.stm32=.bin)
 STM32_TF_MAPFILE       :=      $(STM32_TF_STM32:.stm32=.map)
 STM32_TF_LINKERFILE    :=      $(STM32_TF_STM32:.stm32=.ld)
 STM32_TF_ELF           :=      $(STM32_TF_STM32:.stm32=.elf)
-STM32_TF_DTBFILE       :=      ${BUILD_PLAT}/fdts/${STM32_DTB_FILE_NAME}
+STM32_TF_DTBFILE       :=      ${BUILD_PLAT}/fdts/${DTB_FILE_NAME}
 STM32_TF_OBJS          :=      ${BUILD_PLAT}/stm32mp1.o
 
 # Variables for use with stm32image
@@ -131,7 +132,7 @@ ${STM32_TF_OBJS}:   plat/st/stm32mp1/stm32mp1.S bl2 ${BL32_DEP} ${STM32_TF_DTBFILE
                                -DDTB_BIN_PATH=\"${STM32_TF_DTBFILE}\" \
                                -c plat/st/stm32mp1/stm32mp1.S -o $@
 
-${STM32_TF_LINKERFILE}:        plat/st/stm32mp1/stm32mp1.ld.S
+${STM32_TF_LINKERFILE}:        plat/st/stm32mp1/stm32mp1.ld.S ${BUILD_PLAT}
                        @echo "  LDS     $<"
                        ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} -P -E $< -o $@
 
diff --git a/plat/st/stm32mp1/services/bsec_svc.c b/plat/st/stm32mp1/services/bsec_svc.c
new file mode 100644 (file)
index 0000000..2a60e43
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/st/bsec.h>
+
+#include <stm32mp1_smc.h>
+
+#include "bsec_svc.h"
+
+uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3,
+                  uint32_t *ret_otp_value)
+{
+       uint32_t result;
+       uint32_t tmp_data = 0U;
+
+       switch (x1) {
+       case STM32_SMC_READ_SHADOW:
+               result = bsec_read_otp(ret_otp_value, x2);
+               break;
+       case STM32_SMC_PROG_OTP:
+               *ret_otp_value = 0U;
+               result = bsec_program_otp(x3, x2);
+               break;
+       case STM32_SMC_WRITE_SHADOW:
+               *ret_otp_value = 0;
+               result = bsec_write_otp(x3, x2);
+               break;
+       case STM32_SMC_READ_OTP:
+               *ret_otp_value = 0;
+               result = bsec_read_otp(&tmp_data, x2);
+               if (result != BSEC_OK) {
+                       break;
+               }
+
+               result = bsec_shadow_register(x2);
+               if (result != BSEC_OK) {
+                       break;
+               }
+
+               result = bsec_read_otp(ret_otp_value, x2);
+               if (result != BSEC_OK) {
+                       break;
+               }
+
+               result = bsec_write_otp(tmp_data, x2);
+               break;
+
+       default:
+               result = BSEC_ERROR;
+               break;
+       }
+
+       return result;
+}
diff --git a/plat/st/stm32mp1/services/bsec_svc.h b/plat/st/stm32mp1/services/bsec_svc.h
new file mode 100644 (file)
index 0000000..06752ef
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BSEC_SVC_H
+#define BSEC_SVC_H
+
+#include <stdint.h>
+
+/* version of this service */
+/* must be increase at each structure modification */
+#define BSEC_SERVICE_VERSION           0x01U
+
+uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3,
+                  uint32_t *ret_otp_value);
+
+#endif /* BSEC_SVC_H */
diff --git a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c
new file mode 100644 (file)
index 0000000..72af9ff
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/psci/psci.h>
+#include <tools_share/uuid.h>
+
+#include <stm32mp1_smc.h>
+
+#include "bsec_svc.h"
+
+/* STM32 SiP Service UUID */
+DEFINE_SVC_UUID2(stm32_sip_svc_uid,
+                0xa778aa50, 0xf49b, 0x144a, 0x8a, 0x5e,
+                0x26, 0x4d, 0x59, 0x94, 0xc2, 0x14);
+
+/* Setup STM32MP1 Standard Services */
+static int32_t stm32mp1_svc_setup(void)
+{
+       /*
+        * PSCI is the only specification implemented as a Standard Service.
+        * Invoke PSCI setup from here.
+        */
+       return 0;
+}
+
+/*
+ * Top-level Standard Service SMC handler. This handler will in turn dispatch
+ * calls to PSCI SMC handler.
+ */
+static uintptr_t stm32mp1_svc_smc_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 ret1 = 0U, ret2 = 0U;
+       bool ret_uid = false, ret2_enabled = false;
+
+       switch (smc_fid) {
+       case STM32_SIP_SVC_CALL_COUNT:
+               ret1 = STM32_COMMON_SIP_NUM_CALLS;
+               break;
+
+       case STM32_SIP_SVC_UID:
+               /* Return UUID to the caller */
+               ret_uid = true;
+               break;
+
+       case STM32_SIP_SVC_VERSION:
+               /* Return the version of current implementation */
+               ret1 = STM32_SIP_SVC_VERSION_MAJOR;
+               ret2 = STM32_SIP_SVC_VERSION_MINOR;
+               ret2_enabled = true;
+               break;
+
+       case STM32_SMC_BSEC:
+               ret1 = bsec_main(x1, x2, x3, &ret2);
+               ret2_enabled = true;
+               break;
+
+       default:
+               WARN("Unimplemented STM32MP1 Service Call: 0x%x\n", smc_fid);
+               ret1 = SMC_UNK;
+               break;
+       }
+
+       if (ret_uid) {
+               SMC_UUID_RET(handle, stm32_sip_svc_uid);
+       }
+
+       if (ret2_enabled) {
+               SMC_RET2(handle, ret1, ret2);
+       }
+
+       SMC_RET1(handle, ret1);
+}
+
+/* Register Standard Service Calls as runtime service */
+DECLARE_RT_SVC(stm32mp1_sip_svc,
+              OEN_SIP_START,
+              OEN_SIP_END,
+              SMC_TYPE_FAST,
+              stm32mp1_svc_setup,
+              stm32mp1_svc_smc_handler
+);
index 9fde153879489af0d725b0c69688c08df77316e6..4188cc58ae3d275b3a1fccde92e4b5fa54ef9caf 100644 (file)
@@ -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
 #
@@ -19,3 +19,7 @@ BL32_SOURCES          +=      drivers/arm/gic/common/gic_common.c     \
 
 # Generic PSCI
 BL32_SOURCES           +=      plat/common/plat_psci_common.c
+
+# stm32mp1 specific services
+BL32_SOURCES           +=      plat/st/stm32mp1/services/bsec_svc.c            \
+                               plat/st/stm32mp1/services/stm32mp1_svc_setup.c
index f5413797cf014e32b10ede5d143f99397dbdc7f7..0d76fb7e3ea316f5e2296ccbfb426b10542858ab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <context.h>
+#include <drivers/arm/gicv2.h>
 #include <drivers/arm/tzc400.h>
 #include <drivers/generic_delay_timer.h>
+#include <drivers/st/bsec.h>
 #include <drivers/st/stm32_console.h>
+#include <drivers/st/stm32_gpio.h>
 #include <drivers/st/stm32mp1_clk.h>
 #include <dt-bindings/clock/stm32mp1-clks.h>
 #include <lib/el3_runtime/context_mgmt.h>
@@ -40,7 +43,7 @@ static struct console_stm32 console;
  ******************************************************************************/
 void sp_min_plat_fiq_handler(uint32_t id)
 {
-       switch (id) {
+       switch (id & INT_ID_MASK) {
        case STM32MP1_IRQ_TZC400:
                ERROR("STM32MP1_IRQ_TZC400 generated\n");
                panic();
@@ -50,7 +53,7 @@ void sp_min_plat_fiq_handler(uint32_t id)
                panic();
                break;
        default:
-               ERROR("SECURE IT handler not define for it : %i", id);
+               ERROR("SECURE IT handler not define for it : %u", id);
                break;
        }
 }
@@ -80,7 +83,7 @@ entry_point_info_t *sp_min_plat_get_bl33_ep_info(void)
 void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
                                  u_register_t arg2, u_register_t arg3)
 {
-       struct dt_node_info dt_dev_info;
+       struct dt_node_info dt_uart_info;
        int result;
        bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
 
@@ -110,14 +113,18 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
                panic();
        }
 
+       if (bsec_probe() != 0) {
+               panic();
+       }
+
        if (stm32mp1_clk_probe() < 0) {
                panic();
        }
 
-       result = dt_get_stdout_uart_info(&dt_dev_info);
+       result = dt_get_stdout_uart_info(&dt_uart_info);
 
-       if ((result > 0) && dt_dev_info.status) {
-               if (console_stm32_register(dt_dev_info.base, 0,
+       if ((result > 0) && (dt_uart_info.status != 0U)) {
+               if (console_stm32_register(dt_uart_info.base, 0,
                                           STM32MP1_UART_BAUDRATE, &console) ==
                    0) {
                        panic();
@@ -142,6 +149,16 @@ void sp_min_platform_setup(void)
        generic_delay_timer_init();
 
        stm32mp1_gic_init();
+
+       /* Unlock ETZPC securable peripherals */
+#define STM32MP1_ETZPC_BASE    0x5C007000U
+#define ETZPC_DECPROT0         0x010U
+       mmio_write_32(STM32MP1_ETZPC_BASE + ETZPC_DECPROT0, 0xFFFFFFFF);
+
+       /* Set GPIO bank Z as non secure */
+       for (uint32_t pin = 0U; pin < STM32MP_GPIOZ_PIN_MAX_COUNT; pin++) {
+               set_gpio_secure_cfg(GPIO_BANK_Z, pin, false);
+       }
 }
 
 void sp_min_plat_arch_setup(void)
index b54f313ffec25c725fb63df8d7a4e5f3123e0450..cd93d2eef7a3e3ff29652e195be395f0eebeec94 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,7 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/arm/gicv2.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
                                        MT_SECURE | \
                                        MT_EXECUTE_NEVER)
 
-#define MAP_DDR                MAP_REGION_FLAT(STM32MP1_DDR_BASE, \
-                                       STM32MP1_DDR_MAX_SIZE, \
-                                       MT_MEMORY | \
-                                       MT_RW | \
-                                       MT_SECURE | \
-                                       MT_EXECUTE_NEVER)
-
-#define MAP_DDR_NS     MAP_REGION_FLAT(STM32MP1_DDR_BASE, \
-                                       STM32MP1_DDR_MAX_SIZE, \
-                                       MT_MEMORY | \
-                                       MT_RW | \
-                                       MT_NS | \
-                                       MT_EXECUTE_NEVER)
-
 #if defined(IMAGE_BL2)
 static const mmap_region_t stm32mp1_mmap[] = {
        MAP_SRAM,
        MAP_DEVICE1,
        MAP_DEVICE2,
-       MAP_DDR,
        {0}
 };
 #endif
@@ -67,7 +53,6 @@ static const mmap_region_t stm32mp1_mmap[] = {
        MAP_SRAM,
        MAP_DEVICE1,
        MAP_DEVICE2,
-       MAP_DDR_NS,
        {0}
 };
 #endif
@@ -102,3 +87,37 @@ uintptr_t stm32mp1_get_boot_ctx_address(void)
 {
        return boot_ctx_address;
 }
+
+uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
+{
+       switch (bank) {
+       case GPIO_BANK_A ... GPIO_BANK_K:
+               return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
+       case GPIO_BANK_Z:
+               return GPIOZ_BASE;
+       default:
+               panic();
+       }
+}
+
+/* Return clock ID on success, negative value on error */
+unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
+{
+       switch (bank) {
+       case GPIO_BANK_A ... GPIO_BANK_K:
+               return GPIOA + (bank - GPIO_BANK_A);
+       case GPIO_BANK_Z:
+               return GPIOZ;
+       default:
+               panic();
+       }
+}
+
+uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
+{
+       if (bank == GPIO_BANK_Z) {
+               return 0;
+       } else {
+               return bank * GPIO_BANK_OFFSET;
+       }
+}
index 15f0432b394a3a1dca91c1b365362171056955cb..8cd5aeb26c6c368089671d58601b7a5091707aaf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -111,6 +111,39 @@ enum ddr_type {
  ******************************************************************************/
 #define PWR_BASE                       U(0x50001000)
 
+/*******************************************************************************
+ * STM32MP1 GPIO
+ ******************************************************************************/
+#define GPIOA_BASE                     U(0x50002000)
+#define GPIOB_BASE                     U(0x50003000)
+#define GPIOC_BASE                     U(0x50004000)
+#define GPIOD_BASE                     U(0x50005000)
+#define GPIOE_BASE                     U(0x50006000)
+#define GPIOF_BASE                     U(0x50007000)
+#define GPIOG_BASE                     U(0x50008000)
+#define GPIOH_BASE                     U(0x50009000)
+#define GPIOI_BASE                     U(0x5000A000)
+#define GPIOJ_BASE                     U(0x5000B000)
+#define GPIOK_BASE                     U(0x5000C000)
+#define GPIOZ_BASE                     U(0x54004000)
+#define GPIO_BANK_OFFSET               U(0x1000)
+
+/* Bank IDs used in GPIO driver API */
+#define GPIO_BANK_A                    U(0)
+#define GPIO_BANK_B                    U(1)
+#define GPIO_BANK_C                    U(2)
+#define GPIO_BANK_D                    U(3)
+#define GPIO_BANK_E                    U(4)
+#define GPIO_BANK_F                    U(5)
+#define GPIO_BANK_G                    U(6)
+#define GPIO_BANK_H                    U(7)
+#define GPIO_BANK_I                    U(8)
+#define GPIO_BANK_J                    U(9)
+#define GPIO_BANK_K                    U(10)
+#define GPIO_BANK_Z                    U(25)
+
+#define STM32MP_GPIOZ_PIN_MAX_COUNT    8
+
 /*******************************************************************************
  * STM32MP1 UART
  ******************************************************************************/
@@ -122,16 +155,21 @@ enum ddr_type {
 #define USART6_BASE                    U(0x44003000)
 #define UART7_BASE                     U(0x40018000)
 #define UART8_BASE                     U(0x40019000)
-#define STM32MP1_DEBUG_USART_BASE      UART4_BASE
-#define STM32MP1_UART_BAUDRATE         115200
+#define STM32MP1_UART_BAUDRATE         U(115200)
 
-/*******************************************************************************
- * STM32MP1 GIC-400
- ******************************************************************************/
-#define STM32MP1_GICD_BASE             U(0xA0021000)
-#define STM32MP1_GICC_BASE             U(0xA0022000)
-#define STM32MP1_GICH_BASE             U(0xA0024000)
-#define STM32MP1_GICV_BASE             U(0xA0026000)
+/* For UART crash console */
+#define STM32MP1_DEBUG_USART_BASE      UART4_BASE
+/* UART4 on HSI@64MHz, TX on GPIOG11 Alternate 6 */
+#define STM32MP1_DEBUG_USART_CLK_FRQ   64000000
+#define DEBUG_UART_TX_GPIO_BANK_ADDRESS        GPIOG_BASE
+#define DEBUG_UART_TX_GPIO_BANK_CLK_REG        RCC_MP_AHB4ENSETR
+#define DEBUG_UART_TX_GPIO_BANK_CLK_EN RCC_MP_AHB4ENSETR_GPIOGEN
+#define DEBUG_UART_TX_GPIO_PORT                11
+#define DEBUG_UART_TX_GPIO_ALTERNATE   6
+#define DEBUG_UART_TX_CLKSRC_REG       RCC_UART24CKSELR
+#define DEBUG_UART_TX_CLKSRC           RCC_UART24CKSELR_HSI
+#define DEBUG_UART_TX_EN_REG           RCC_MP_APB1ENSETR
+#define DEBUG_UART_TX_EN               RCC_MP_APB1ENSETR_UART4EN
 
 /*******************************************************************************
  * STM32MP1 TZC (TZ400)
@@ -149,10 +187,7 @@ enum ddr_type {
 #define STM32MP1_TZC_ETH_ID            U(10)
 #define STM32MP1_TZC_DAP_ID            U(15)
 
-#define STM32MP1_MEMORY_NS             0
-#define STM32MP1_MEMORY_SECURE         1
-
-#define STM32MP1_FILTER_BIT_ALL                3
+#define STM32MP1_FILTER_BIT_ALL                U(3)
 
 /*******************************************************************************
  * STM32MP1 SDMMC
@@ -167,6 +202,21 @@ enum ddr_type {
 #define STM32MP1_EMMC_NORMAL_SPEED_MAX_FREQ    26000000        /*26 MHz*/
 #define STM32MP1_EMMC_HIGH_SPEED_MAX_FREQ      52000000        /*52 MHz*/
 
+/*******************************************************************************
+ * STM32MP1 BSEC / OTP
+ ******************************************************************************/
+#define STM32MP1_OTP_MAX_ID            0x5FU
+#define STM32MP1_UPPER_OTP_START       0x20U
+
+#define OTP_MAX_SIZE                   (STM32MP1_OTP_MAX_ID + 1U)
+
+/* OTP offsets */
+#define DATA0_OTP                      U(0)
+
+/* OTP mask */
+/* DATA0 */
+#define DATA0_OTP_SECURED              BIT(6)
+
 /*******************************************************************************
  * STM32MP1 TAMP
  ******************************************************************************/
index 29e936aff8d71cb1f39dbcc0e976e2a0f65d544b..8493b87864c21721a23085313826d2531cb3ba4d 100644 (file)
@@ -1,10 +1,11 @@
 /*
- * 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
  */
 
 #include <assert.h>
+#include <errno.h>
 
 #include <libfdt.h>
 
 #include <drivers/st/stm32mp1_ddr.h>
 #include <drivers/st/stm32mp1_ram.h>
 
-#include <stm32mp1_dt.h>
-
-#define DT_GPIO_BANK_SHIFT     12
-#define DT_GPIO_BANK_MASK      0x1F000U
-#define DT_GPIO_PIN_SHIFT      8
-#define DT_GPIO_PIN_MASK       0xF00U
-#define DT_GPIO_MODE_MASK      0xFFU
-
 static int fdt_checked;
 
 static void *fdt = (void *)(uintptr_t)STM32MP1_DTB_BASE;
 
-/*******************************************************************************
- * This function gets the pin settings from DT information.
- * When analyze and parsing is done, set the GPIO registers.
- * Return 0 on success, else return a negative FDT_ERR_xxx error code.
- ******************************************************************************/
-static int dt_set_gpio_config(int node)
-{
-       const fdt32_t *cuint, *slewrate;
-       int len, pinctrl_node, pinctrl_subnode;
-       uint32_t i;
-       uint32_t speed = GPIO_SPEED_LOW;
-       uint32_t pull = GPIO_NO_PULL;
-
-       cuint = fdt_getprop(fdt, node, "pinmux", &len);
-       if (cuint == NULL) {
-               return -FDT_ERR_NOTFOUND;
-       }
-
-       pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node));
-       if (pinctrl_node < 0) {
-               return -FDT_ERR_NOTFOUND;
-       }
-
-       slewrate = fdt_getprop(fdt, node, "slew-rate", NULL);
-       if (slewrate != NULL) {
-               speed = fdt32_to_cpu(*slewrate);
-       }
-
-       if (fdt_getprop(fdt, node, "bias-pull-up", NULL) != NULL) {
-               pull = GPIO_PULL_UP;
-       } else if (fdt_getprop(fdt, node, "bias-pull-down", NULL) != NULL) {
-               pull = GPIO_PULL_DOWN;
-       } else {
-               VERBOSE("No bias configured in node %d\n", node);
-       }
-
-       for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
-               uint32_t pincfg;
-               uint32_t bank;
-               uint32_t pin;
-               uint32_t mode;
-               uint32_t alternate = GPIO_ALTERNATE_0;
-
-               pincfg = fdt32_to_cpu(*cuint);
-               cuint++;
-
-               bank = (pincfg & DT_GPIO_BANK_MASK) >> DT_GPIO_BANK_SHIFT;
-
-               pin = (pincfg & DT_GPIO_PIN_MASK) >> DT_GPIO_PIN_SHIFT;
-
-               mode = pincfg & DT_GPIO_MODE_MASK;
-
-               switch (mode) {
-               case 0:
-                       mode = GPIO_MODE_INPUT;
-                       break;
-               case 1 ... 16:
-                       alternate = mode - 1U;
-                       mode = GPIO_MODE_ALTERNATE;
-                       break;
-               case 17:
-                       mode = GPIO_MODE_ANALOG;
-                       break;
-               default:
-                       mode = GPIO_MODE_OUTPUT;
-                       break;
-               }
-
-               if (fdt_getprop(fdt, node, "drive-open-drain", NULL) != NULL) {
-                       mode |= GPIO_OPEN_DRAIN;
-               }
-
-               fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) {
-                       uint32_t bank_offset;
-                       const fdt32_t *cuint2;
-
-                       if (fdt_getprop(fdt, pinctrl_subnode,
-                                       "gpio-controller", NULL) == NULL) {
-                               continue;
-                       }
-
-                       cuint2 = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL);
-                       if (cuint2 == NULL) {
-                               continue;
-                       }
-
-                       if (bank == GPIO_BANK_Z) {
-                               bank_offset = 0;
-                       } else {
-                               bank_offset = bank * STM32_GPIO_BANK_OFFSET;
-                       }
-
-                       if (fdt32_to_cpu(*cuint2) == bank_offset) {
-                               int clk_id = fdt_get_clock_id(pinctrl_subnode);
-
-                               if (clk_id < 0) {
-                                       return -FDT_ERR_NOTFOUND;
-                               }
-
-                               if (stm32mp1_clk_enable((unsigned long)clk_id) <
-                                   0) {
-                                       return -FDT_ERR_BADVALUE;
-                               }
-
-                               break;
-                       }
-               }
-
-               set_gpio(bank, pin, mode, speed, pull, alternate);
-       }
-
-       return 0;
-}
-
 /*******************************************************************************
  * This function checks device tree file with its header.
- * Returns 0 if success, and a negative value else.
+ * Returns 0 on success and a negative FDT error code on failure.
  ******************************************************************************/
 int dt_open_and_check(void)
 {
@@ -174,7 +53,7 @@ int fdt_get_address(void **fdt_addr)
 
 /*******************************************************************************
  * This function check the presence of a node (generic use of fdt library).
- * Returns true if present, false else.
+ * Returns true if present, else return false.
  ******************************************************************************/
 bool fdt_check_node(int node)
 {
@@ -187,37 +66,30 @@ bool fdt_check_node(int node)
 }
 
 /*******************************************************************************
- * This function check the status of a node (generic use of fdt library).
- * Returns true if "okay" or missing, false else.
+ * This function return global node status (generic use of fdt library).
  ******************************************************************************/
-bool fdt_check_status(int node)
+uint32_t fdt_get_status(int node)
 {
+       uint32_t status = DT_DISABLED;
        int len;
        const char *cchar;
 
        cchar = fdt_getprop(fdt, node, "status", &len);
-       if (cchar == NULL) {
-               return true;
+       if ((cchar == NULL) ||
+           (strncmp(cchar, "okay", (size_t)len) == 0)) {
+               status |= DT_NON_SECURE;
        }
 
-       return strncmp(cchar, "okay", (size_t)len) == 0;
-}
-
-/*******************************************************************************
- * This function check the secure-status of a node (generic use of fdt library).
- * Returns true if "okay" or missing, false else.
- ******************************************************************************/
-bool fdt_check_secure_status(int node)
-{
-       int len;
-       const char *cchar;
-
        cchar = fdt_getprop(fdt, node, "secure-status", &len);
        if (cchar == NULL) {
-               return true;
+               if (status == DT_NON_SECURE) {
+                       status |= DT_SECURE;
+               }
+       } else if (strncmp(cchar, "okay", (size_t)len) == 0) {
+               status |= DT_SECURE;
        }
 
-       return strncmp(cchar, "okay", (size_t)len) == 0;
+       return status;
 }
 
 /*******************************************************************************
@@ -245,7 +117,7 @@ uint32_t fdt_read_uint32_default(int node, const char *prop_name,
  * (generic use of fdt library).
  * It reads the values inside the device tree, from property name and node.
  * The number of parameters is also indicated as entry parameter.
- * Returns 0 if success, and a negative value else.
+ * Returns 0 on success and a negative FDT error code on failure.
  * If success, values are stored at the third parameter address.
  ******************************************************************************/
 int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array,
@@ -273,53 +145,10 @@ int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array,
        return 0;
 }
 
-/*******************************************************************************
- * This function gets the pin settings from DT information.
- * When analyze and parsing is done, set the GPIO registers.
- * Returns 0 if success, and a negative value else.
- ******************************************************************************/
-int dt_set_pinctrl_config(int node)
-{
-       const fdt32_t *cuint;
-       int lenp = 0;
-       uint32_t i;
-
-       if (!fdt_check_status(node)) {
-               return -FDT_ERR_NOTFOUND;
-       }
-
-       cuint = fdt_getprop(fdt, node, "pinctrl-0", &lenp);
-       if (cuint == NULL) {
-               return -FDT_ERR_NOTFOUND;
-       }
-
-       for (i = 0; i < ((uint32_t)lenp / 4U); i++) {
-               int phandle_node, phandle_subnode;
-
-               phandle_node =
-                       fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
-               if (phandle_node < 0) {
-                       return -FDT_ERR_NOTFOUND;
-               }
-
-               fdt_for_each_subnode(phandle_subnode, fdt, phandle_node) {
-                       int ret = dt_set_gpio_config(phandle_subnode);
-
-                       if (ret < 0) {
-                               return ret;
-                       }
-               }
-
-               cuint++;
-       }
-
-       return 0;
-}
-
 /*******************************************************************************
  * This function gets the stdout pin configuration information from the DT.
  * And then calls the sub-function to treat it and set GPIO registers.
- * Returns 0 if success, and a negative value else.
+ * Returns 0 on success and a negative FDT error code on failure.
  ******************************************************************************/
 int dt_set_stdout_pinctrl(void)
 {
@@ -363,13 +192,12 @@ void dt_fill_device_info(struct dt_node_info *info, int node)
                info->reset = -1;
        }
 
-       info->status = fdt_check_status(node);
-       info->sec_status = fdt_check_secure_status(node);
+       info->status = fdt_get_status(node);
 }
 
 /*******************************************************************************
  * This function retrieve the generic information from DT.
- * Returns node if success, and a negative value else.
+ * Returns node on success and a negative FDT error code on failure.
  ******************************************************************************/
 int dt_get_node(struct dt_node_info *info, int offset, const char *compat)
 {
@@ -387,7 +215,7 @@ int dt_get_node(struct dt_node_info *info, int offset, const char *compat)
 
 /*******************************************************************************
  * This function gets the UART instance info of stdout from the DT.
- * Returns node if success, and a negative value else.
+ * Returns node on success and a negative FDT error code on failure.
  ******************************************************************************/
 int dt_get_stdout_uart_info(struct dt_node_info *info)
 {
@@ -448,7 +276,7 @@ int dt_get_stdout_node_offset(void)
 
 /*******************************************************************************
  * This function gets DDR size information from the DT.
- * Returns value in bytes if success, and STM32MP1_DDR_SIZE_DFLT else.
+ * Returns value in bytes on success, and 0 on failure.
  ******************************************************************************/
 uint32_t dt_get_ddr_size(void)
 {
@@ -457,11 +285,10 @@ uint32_t dt_get_ddr_size(void)
        node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
        if (node < 0) {
                INFO("%s: Cannot read DDR node in DT\n", __func__);
-               return STM32MP1_DDR_SIZE_DFLT;
+               return 0;
        }
 
-       return fdt_read_uint32_default(node, "st,mem-size",
-                                      STM32MP1_DDR_SIZE_DFLT);
+       return fdt_read_uint32_default(node, "st,mem-size", 0);
 }
 
 /*******************************************************************************
index fabed370f0a2cab002e8429c689711ee52438a56..becb925c2373ec3802797e57589ced91bb15620b 100644 (file)
@@ -1,18 +1,28 @@
 /*
- * 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
  */
 
+#include <libfdt.h>
+
 #include <platform_def.h>
 
 #include <common/bl_common.h>
+#include <common/debug.h>
 #include <drivers/arm/gicv2.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 
+#include <stm32mp1_dt.h>
 #include <stm32mp1_private.h>
 
+struct stm32_gic_instance {
+       uint32_t cells;
+       uint32_t phandle_node;
+};
+
 /******************************************************************************
  * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
  * interrupts.
@@ -22,19 +32,55 @@ static const interrupt_prop_t stm32mp1_interrupt_props[] = {
        PLATFORM_G0_PROPS(GICV2_INTR_GROUP0)
 };
 
-static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
+/* Fix target_mask_array as secondary core is not able to initialize it */
+static unsigned int target_mask_array[PLATFORM_CORE_COUNT] = {1, 2};
 
-static const gicv2_driver_data_t platform_gic_data = {
-       .gicd_base = STM32MP1_GICD_BASE,
-       .gicc_base = STM32MP1_GICC_BASE,
+static gicv2_driver_data_t platform_gic_data = {
        .interrupt_props = stm32mp1_interrupt_props,
        .interrupt_props_num = ARRAY_SIZE(stm32mp1_interrupt_props),
        .target_masks = target_mask_array,
        .target_masks_num = ARRAY_SIZE(target_mask_array),
 };
 
+static struct stm32_gic_instance stm32_gic;
+
 void stm32mp1_gic_init(void)
 {
+       int node;
+       void *fdt;
+       const fdt32_t *cuint;
+       struct dt_node_info dt_gic;
+
+       if (fdt_get_address(&fdt) == 0) {
+               panic();
+       }
+
+       node = dt_get_node(&dt_gic, -1, "arm,cortex-a7-gic");
+       if (node < 0) {
+               panic();
+       }
+
+       platform_gic_data.gicd_base = dt_gic.base;
+
+       cuint = fdt_getprop(fdt, node, "reg", NULL);
+       if (cuint == NULL) {
+               panic();
+       }
+
+       platform_gic_data.gicc_base = fdt32_to_cpu(*(cuint + 2));
+
+       cuint = fdt_getprop(fdt, node, "#interrupt-cells", NULL);
+       if (cuint == NULL) {
+               panic();
+       }
+
+       stm32_gic.cells = fdt32_to_cpu(*cuint);
+
+       stm32_gic.phandle_node = fdt_get_phandle(fdt, node);
+       if (stm32_gic.phandle_node == 0U) {
+               panic();
+       }
+
        gicv2_driver_init(&platform_gic_data);
        gicv2_distif_init();
 
index 61c587f4f1d0e899701cbe1d7258c5f22d3bdd21..8c2e1b6ea3ea10cb26b72b20d5195728fd7398f1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <drivers/st/stm32_gpio.h>
 #include <drivers/st/stm32mp1_rcc.h>
 
-#define GPIO_BANK_G_ADDRESS    0x50008000
-#define GPIO_TX_PORT           11
-#define GPIO_TX_SHIFT          (GPIO_TX_PORT << 1)
-#define GPIO_TX_ALT_SHIFT      ((GPIO_TX_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
-#define STM32MP1_HSI_CLK       64000000
+#define GPIO_TX_SHIFT          (DEBUG_UART_TX_GPIO_PORT << 1)
+#define GPIO_TX_ALT_SHIFT      ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
 
        .globl  platform_mem_init
        .globl  plat_report_exception
@@ -112,13 +109,13 @@ endfunc plat_my_core_pos
         * ---------------------------------------------
         */
 func plat_crash_console_init
-       /* Enable GPIOs for UART4 TX */
-       ldr     r1, =(RCC_BASE + RCC_MP_AHB4ENSETR)
+       /* Enable GPIOs for UART TX */
+       ldr     r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
        ldr     r2, [r1]
-       /* Configure GPIO G11 */
-       orr     r2, r2, #RCC_MP_AHB4ENSETR_GPIOGEN
+       /* Configure GPIO */
+       orr     r2, r2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN
        str     r2, [r1]
-       ldr     r1, =GPIO_BANK_G_ADDRESS
+       ldr     r1, =DEBUG_UART_TX_GPIO_BANK_ADDRESS
        /* Set GPIO mode alternate */
        ldr     r2, [r1, #GPIO_MODE_OFFSET]
        bic     r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
@@ -132,23 +129,22 @@ func plat_crash_console_init
        ldr     r2, [r1, #GPIO_PUPD_OFFSET]
        bic     r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
        str     r2, [r1, #GPIO_PUPD_OFFSET]
-       /* Set alternate AF6 */
+       /* Set alternate */
        ldr     r2, [r1, #GPIO_AFRH_OFFSET]
        bic     r2, r2, #(GPIO_ALTERNATE_MASK << GPIO_TX_ALT_SHIFT)
-       orr     r2, r2, #(GPIO_ALTERNATE_6 << GPIO_TX_ALT_SHIFT)
+       orr     r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << GPIO_TX_ALT_SHIFT)
        str     r2, [r1, #GPIO_AFRH_OFFSET]
-
-       /* Enable UART clock, with HSI source */
-       ldr     r1, =(RCC_BASE + RCC_UART24CKSELR)
-       mov     r2, #RCC_UART24CKSELR_HSI
+       /* Enable UART clock, with its source */
+       ldr     r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
+       mov     r2, #DEBUG_UART_TX_CLKSRC
        str     r2, [r1]
-       ldr     r1, =(RCC_BASE + RCC_MP_APB1ENSETR)
+       ldr     r1, =(RCC_BASE + DEBUG_UART_TX_EN_REG)
        ldr     r2, [r1]
-       orr     r2, r2, #RCC_MP_APB1ENSETR_UART4EN
+       orr     r2, r2, #DEBUG_UART_TX_EN
        str     r2, [r1]
 
        ldr     r0, =STM32MP1_DEBUG_USART_BASE
-       ldr     r1, =STM32MP1_HSI_CLK
+       ldr     r1, =STM32MP1_DEBUG_USART_CLK_FRQ
        ldr     r2, =STM32MP1_UART_BAUDRATE
        b       console_stm32_core_init
 endfunc plat_crash_console_init
index 85189ff21de06d301982336916407c413f734ff9..c0e9c4eb8c5e133f158ccbb4d4740cff99621c03 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <boot_api.h>
 #include <stm32mp1_private.h>
 
-static uint32_t stm32_sec_entrypoint;
+static uintptr_t stm32_sec_entrypoint;
 static uint32_t cntfrq_core0;
 
-#define SEND_SECURE_IT_TO_CORE_1       0x20000U
-
 /*******************************************************************************
  * STM32MP1 handler called when a CPU is about to enter standby.
  * call by core 1 to enter in wfi
@@ -42,6 +40,7 @@ static void stm32_cpu_standby(plat_local_state_t cpu_state)
         * Enter standby state
         * dsb is good practice before using wfi to enter low power states
         */
+       isb();
        dsb();
        while (interrupt == GIC_SPURIOUS_INTERRUPT) {
                wfi();
@@ -59,7 +58,7 @@ static void stm32_cpu_standby(plat_local_state_t cpu_state)
 /*******************************************************************************
  * STM32MP1 handler called when a power domain is about to be turned on. The
  * mpidr determines the CPU to be turned on.
- * call by core  0 to activate core 1
+ * call by core 0 to activate core 1
  ******************************************************************************/
 static int stm32_pwr_domain_on(u_register_t mpidr)
 {
@@ -102,8 +101,7 @@ static int stm32_pwr_domain_on(u_register_t mpidr)
        }
 
        /* Generate an IT to core 1 */
-       mmio_write_32(STM32MP1_GICD_BASE + GICD_SGIR,
-                     SEND_SECURE_IT_TO_CORE_1 | ARM_IRQ_SEC_SGI_0);
+       gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, STM32MP1_SECONDARY_CPU);
 
        return PSCI_E_SUCCESS;
 }
index 39927040a84e8ecbadc868203fb8a136ab8501fb..cfdbf31852bd7c72e01dc6d48bdbc52d77ac2980 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -65,22 +65,6 @@ static void init_tzc400(void)
  ******************************************************************************/
 static void early_init_tzc400(void)
 {
-       uint32_t rstsr, rst_standby;
-
-       rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
-
-       /* No warning if return from (C)STANDBY */
-       rst_standby = rstsr &
-               (RCC_MP_RSTSCLRR_STDBYRSTF | RCC_MP_RSTSCLRR_CSTDBYRSTF);
-
-       if (stm32mp1_clk_is_enabled(TZC1) && (rst_standby == 0U)) {
-               WARN("TZC400 port 1 clock already enable\n");
-       }
-
-       if (stm32mp1_clk_is_enabled(TZC2) && (rst_standby == 0U)) {
-               WARN("TZC400 port 2 clock already enable\n");
-       }
-
        if (stm32mp1_clk_enable(TZC1) != 0) {
                ERROR("Cannot enable TZC1 clock\n");
                panic();
@@ -103,6 +87,7 @@ static void early_init_tzc400(void)
                                STM32MP1_DDR_BASE +
                                (STM32MP1_DDR_MAX_SIZE - 1U),
                                TZC_REGION_S_RDWR,
+                               TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) |
                                TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID));
 
        /* Raise an exception if a NS device tries to access secure memory */
index 5dd54d4ff3a53dc5a4d2a6a28984b77a0fc5b6a9..49cecd44cabbc57eea711097b605069d5665cb13 100644 (file)
@@ -139,10 +139,10 @@ static inline int k3_sec_proxy_verify_thread(struct k3_sec_proxy_thread *spt,
        if ((mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)
            != (dir << SCFG_THREAD_CTRL_DIR_SHIFT)) {
                if (dir)
-                       ERROR("Trying to receive data on tx Thread %d\n",
+                       ERROR("Trying to send data on RX Thread %d\n",
                              spt->id);
                else
-                       ERROR("Trying to send data on rx Thread %d\n",
+                       ERROR("Trying to receive data on TX Thread %d\n",
                              spt->id);
                return -EINVAL;
        }
@@ -162,6 +162,44 @@ static inline int k3_sec_proxy_verify_thread(struct k3_sec_proxy_thread *spt,
        return 0;
 }
 
+/**
+ * k3_sec_proxy_clear_rx_thread() - Clear Secure Proxy thread
+ *
+ * @id: Channel Identifier
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int k3_sec_proxy_clear_rx_thread(enum k3_sec_proxy_chan_id id)
+{
+       struct k3_sec_proxy_thread *spt = &spm.threads[id];
+
+       /* Check for any errors already available */
+       if (mmio_read_32(spt->rt + RT_THREAD_STATUS) &
+           RT_THREAD_STATUS_ERROR_MASK) {
+               ERROR("Thread %d is corrupted, cannot send data\n", spt->id);
+               return -EINVAL;
+       }
+
+       /* Make sure thread is configured for right direction */
+       if (!(mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)) {
+               ERROR("Cannot clear a transmit thread %d\n", spt->id);
+               return -EINVAL;
+       }
+
+       /* Read off messages from thread until empty */
+       uint32_t try_count = 10;
+       while (mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK) {
+               if (!(try_count--)) {
+                       ERROR("Could not clear all messages from thread %d\n", spt->id);
+                       return -ETIMEDOUT;
+               }
+               WARN("Clearing message from thread %d\n", spt->id);
+               mmio_read_32(spt->data + spm.desc.data_end_offset);
+       }
+
+       return 0;
+}
+
 /**
  * k3_sec_proxy_send() - Send data over a Secure Proxy thread
  * @id: Channel Identifier
index 2d987f83a61c0eda409db4af32bdfa56f9752e3c..6c4f5dfffa7edcdbe380981368d7e5e937d66e12 100644 (file)
@@ -37,6 +37,15 @@ struct k3_sec_proxy_msg {
        uint8_t *buf;
 };
 
+/**
+ * k3_sec_proxy_send() - Send data over a Secure Proxy thread
+ * @id: Channel Identifier
+ * @msg: Pointer to k3_sec_proxy_msg
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int k3_sec_proxy_clear_rx_thread(enum k3_sec_proxy_chan_id id);
+
 /**
  * k3_sec_proxy_send() - Send data over a Secure Proxy thread
  * @id: Channel Identifier
index b211bdf60bf7163f8718fb152f6ca98035b47010..4a33d34494409e11517f5d63349783e4b7d555c6 100644 (file)
@@ -158,6 +158,13 @@ static inline int ti_sci_do_xfer(struct ti_sci_xfer *xfer)
        struct k3_sec_proxy_msg *msg = &xfer->tx_message;
        int ret;
 
+       /* Clear any spurious messages in receive queue */
+       ret = k3_sec_proxy_clear_rx_thread(SP_RESPONSE);
+       if (ret) {
+               ERROR("Could not clear response queue (%d)\n", ret);
+               return ret;
+       }
+
        /* Send the message */
        ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, msg);
        if (ret) {
@@ -165,6 +172,7 @@ static inline int ti_sci_do_xfer(struct ti_sci_xfer *xfer)
                return ret;
        }
 
+       /* Get the response */
        ret = ti_sci_get_response(xfer, SP_RESPONSE);
        if (ret) {
                ERROR("Failed to get response (%d)\n", ret);
@@ -1458,6 +1466,169 @@ int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv,
        return 0;
 }
 
+/**
+ * ti_sci_proc_wait_boot_status() - Wait for a processor boot status
+ *
+ * @proc_id:                   Processor ID this request is for
+ * @num_wait_iterations                Total number of iterations we will check before
+ *                             we will timeout and give up
+ * @num_match_iterations       How many iterations should we have continued
+ *                             status to account for status bits glitching.
+ *                             This is to make sure that match occurs for
+ *                             consecutive checks. This implies that the
+ *                             worst case should consider that the stable
+ *                             time should at the worst be num_wait_iterations
+ *                             num_match_iterations to prevent timeout.
+ * @delay_per_iteration_us     Specifies how long to wait (in micro seconds)
+ *                             between each status checks. This is the minimum
+ *                             duration, and overhead of register reads and
+ *                             checks are on top of this and can vary based on
+ *                             varied conditions.
+ * @delay_before_iterations_us Specifies how long to wait (in micro seconds)
+ *                             before the very first check in the first
+ *                             iteration of status check loop. This is the
+ *                             minimum duration, and overhead of register
+ *                             reads and checks are.
+ * @status_flags_1_set_all_wait        If non-zero, Specifies that all bits of the
+ *                             status matching this field requested MUST be 1.
+ * @status_flags_1_set_any_wait        If non-zero, Specifies that at least one of the
+ *                             bits matching this field requested MUST be 1.
+ * @status_flags_1_clr_all_wait        If non-zero, Specifies that all bits of the
+ *                             status matching this field requested MUST be 0.
+ * @status_flags_1_clr_any_wait        If non-zero, Specifies that at least one of the
+ *                             bits matching this field requested MUST be 0.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations,
+                                uint8_t num_match_iterations,
+                                uint8_t delay_per_iteration_us,
+                                uint8_t delay_before_iterations_us,
+                                uint32_t status_flags_1_set_all_wait,
+                                uint32_t status_flags_1_set_any_wait,
+                                uint32_t status_flags_1_clr_all_wait,
+                                uint32_t status_flags_1_clr_any_wait)
+{
+       struct ti_sci_msg_req_wait_proc_boot_status req;
+       struct ti_sci_msg_hdr resp;
+
+       struct ti_sci_xfer xfer;
+       int ret;
+
+       ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS,
+                                   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                   &req, sizeof(req),
+                                   &resp, sizeof(resp),
+                                   &xfer);
+       if (ret) {
+               ERROR("Message alloc failed (%d)\n", ret);
+               return ret;
+       }
+
+       req.processor_id = proc_id;
+       req.num_wait_iterations = num_wait_iterations;
+       req.num_match_iterations = num_match_iterations;
+       req.delay_per_iteration_us = delay_per_iteration_us;
+       req.delay_before_iterations_us = delay_before_iterations_us;
+       req.status_flags_1_set_all_wait = status_flags_1_set_all_wait;
+       req.status_flags_1_set_any_wait = status_flags_1_set_any_wait;
+       req.status_flags_1_clr_all_wait = status_flags_1_clr_all_wait;
+       req.status_flags_1_clr_any_wait = status_flags_1_clr_any_wait;
+
+       ret = ti_sci_do_xfer(&xfer);
+       if (ret) {
+               ERROR("Transfer send failed (%d)\n", ret);
+               return ret;
+       }
+
+       if (!ti_sci_is_response_ack(&resp))
+               return -ENODEV;
+
+       return 0;
+}
+
+/**
+ * ti_sci_proc_shutdown() - Shutdown Processor without waiting for ACKs
+ *
+ * @proc_id:   Processor ID this request is for
+ * @dev_id:    Device identifier this request is for
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_shutdown(uint8_t proc_id, uint32_t dev_id)
+{
+       struct ti_sci_msg_req_wait_proc_boot_status wait_req;
+       struct ti_sci_msg_req_set_device_state set_req;
+       /*
+        * We will not be waiting for this response, but declare one anyway
+        * to pass to the setup function so the checks will still pass
+        */
+       struct ti_sci_msg_hdr resp;
+
+       struct ti_sci_xfer xfer;
+       int ret;
+
+       /* Start by sending wait command */
+
+       /* Setup with NORESPONSE flag to keep response queue clean */
+       ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS,
+                                   TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
+                                   &wait_req, sizeof(wait_req),
+                                   &resp, sizeof(resp),
+                                   &xfer);
+       if (ret) {
+               ERROR("Message alloc failed (%d)\n", ret);
+               return ret;
+       }
+
+       wait_req.processor_id = proc_id;
+       /*
+        * Wait maximum time to give us the best chance to get
+        * to WFI before this command timeouts
+        */
+       wait_req.delay_before_iterations_us = UINT8_MAX;
+       wait_req.num_wait_iterations = UINT8_MAX;
+       wait_req.delay_per_iteration_us = UINT8_MAX;  /* TODO: optimize time */
+       wait_req.num_match_iterations = 2;
+       wait_req.status_flags_1_set_all_wait = 0;
+       /* Wait for either WFE or WFI */
+       wait_req.status_flags_1_set_any_wait = PROC_BOOT_STATUS_FLAG_ARMV8_WFE |
+                                              PROC_BOOT_STATUS_FLAG_ARMV8_WFI;
+       wait_req.status_flags_1_clr_all_wait = 0;
+       wait_req.status_flags_1_clr_any_wait = 0;
+
+       /* Send wait message */
+       ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &xfer.tx_message);
+       if (ret) {
+               ERROR("Message sending failed (%d)\n", ret);
+               return ret;
+       }
+
+       /* Now queue up the shutdown request */
+       ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_STATE,
+                                   TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
+                                   &set_req, sizeof(set_req),
+                                   &resp, sizeof(resp),
+                                   &xfer);
+       if (ret) {
+               ERROR("Message alloc failed (%d)\n", ret);
+               return ret;
+       }
+
+       set_req.id = dev_id;
+       set_req.state = MSG_DEVICE_SW_STATE_AUTO_OFF;
+
+       /* Send shutdown message */
+       ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &xfer.tx_message);
+       if (ret) {
+               ERROR("Message sending failed (%d)\n", ret);
+               return ret;
+       }
+
+       /* Return without waiting for responses */
+       return 0;
+}
+
 /**
  * ti_sci_init() - Basic initialization
  *
index 1176b00f47b049b82d27249f3e618027395472f5..d07ee61df7479f001f82a3fe89c18708456b0116 100644 (file)
@@ -179,6 +179,7 @@ int ti_sci_core_reboot(void);
  *                                 and then set the processor configuration flags.
  *              @cert_addr: Memory address at which payload image certificate is located.
  * - ti_sci_proc_get_boot_status - Command to get the processor boot status
+ * - ti_sci_proc_wait_boot_status - Command to wait for a processor boot status
  *
  * NOTE: for all these functions, the following are generic in nature:
  * @proc_id:   Processor ID
@@ -197,6 +198,15 @@ int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv,
                                uint32_t *cfg_flags,
                                uint32_t *ctrl_flags,
                                uint32_t *sts_flags);
+int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations,
+                                uint8_t num_match_iterations,
+                                uint8_t delay_per_iteration_us,
+                                uint8_t delay_before_iterations_us,
+                                uint32_t status_flags_1_set_all_wait,
+                                uint32_t status_flags_1_set_any_wait,
+                                uint32_t status_flags_1_clr_all_wait,
+                                uint32_t status_flags_1_clr_any_wait);
+int ti_sci_proc_shutdown(uint8_t proc_id, uint32_t dev_id);
 
 /**
  * ti_sci_init() - Basic initialization
index c6d76d7ea168b862bbf23667aa0a64cbb3e2f2eb..a921e512a8fa39738afd2439278681074d6044a7 100644 (file)
@@ -46,6 +46,7 @@
 #define TISCI_MSG_SET_PROC_BOOT_CTRL   0xc101
 #define TISCI_MSG_PROC_AUTH_BOOT_IMIAGE        0xc120
 #define TISCI_MSG_GET_PROC_BOOT_STATUS 0xc400
+#define TISCI_MSG_WAIT_PROC_BOOT_STATUS        0xc401
 
 /**
  * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
@@ -647,4 +648,52 @@ struct ti_sci_msg_resp_get_proc_boot_status {
        uint32_t status_flags;
 } __packed;
 
+/**
+ * struct ti_sci_msg_req_wait_proc_boot_status - Wait for a processor boot status
+ * @hdr:                       Generic Header
+ * @processor_id:              ID of processor
+ * @num_wait_iterations                Total number of iterations we will check before
+ *                             we will timeout and give up
+ * @num_match_iterations       How many iterations should we have continued
+ *                             status to account for status bits glitching.
+ *                             This is to make sure that match occurs for
+ *                             consecutive checks. This implies that the
+ *                             worst case should consider that the stable
+ *                             time should at the worst be num_wait_iterations
+ *                             num_match_iterations to prevent timeout.
+ * @delay_per_iteration_us     Specifies how long to wait (in micro seconds)
+ *                             between each status checks. This is the minimum
+ *                             duration, and overhead of register reads and
+ *                             checks are on top of this and can vary based on
+ *                             varied conditions.
+ * @delay_before_iterations_us Specifies how long to wait (in micro seconds)
+ *                             before the very first check in the first
+ *                             iteration of status check loop. This is the
+ *                             minimum duration, and overhead of register
+ *                             reads and checks are.
+ * @status_flags_1_set_all_wait        If non-zero, Specifies that all bits of the
+ *                             status matching this field requested MUST be 1.
+ * @status_flags_1_set_any_wait        If non-zero, Specifies that at least one of the
+ *                             bits matching this field requested MUST be 1.
+ * @status_flags_1_clr_all_wait        If non-zero, Specifies that all bits of the
+ *                             status matching this field requested MUST be 0.
+ * @status_flags_1_clr_any_wait        If non-zero, Specifies that at least one of the
+ *                             bits matching this field requested MUST be 0.
+ *
+ * Request type is TISCI_MSG_WAIT_PROC_BOOT_STATUS, response is appropriate
+ * message, or NACK in case of inability to satisfy request.
+ */
+struct ti_sci_msg_req_wait_proc_boot_status {
+       struct ti_sci_msg_hdr hdr;
+       uint8_t processor_id;
+       uint8_t num_wait_iterations;
+       uint8_t num_match_iterations;
+       uint8_t delay_per_iteration_us;
+       uint8_t delay_before_iterations_us;
+       uint32_t status_flags_1_set_all_wait;
+       uint32_t status_flags_1_set_any_wait;
+       uint32_t status_flags_1_clr_all_wait;
+       uint32_t status_flags_1_clr_any_wait;
+} __packed;
+
 #endif /* TI_SCI_PROTOCOL_H */
index 3fa11b2318ec00c73a6707ced936aab8b0313942..78fb696b2200c51db665015a2f45833a03a118f4 100644 (file)
@@ -23,8 +23,7 @@
 const mmap_region_t plat_k3_mmap[] = {
        MAP_REGION_FLAT(SHARED_RAM_BASE, SHARED_RAM_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
        MAP_REGION_FLAT(K3_USART_BASE_ADDRESS, K3_USART_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(K3_GICD_BASE, K3_GICD_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
-       MAP_REGION_FLAT(K3_GICR_BASE, K3_GICR_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(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),
@@ -116,7 +115,7 @@ void bl31_plat_arch_setup(void)
 
 void bl31_platform_setup(void)
 {
-       k3_gic_driver_init(K3_GICD_BASE, K3_GICR_BASE);
+       k3_gic_driver_init(K3_GIC_BASE);
        k3_gic_init();
 
        ti_sci_init();
index b7c7880141ffe9fec1583cfcaf575164f64b55c8..1932eaae571c2fe05a3f748d64b35b8911339411 100644 (file)
@@ -6,10 +6,12 @@
 
 #include <platform_def.h>
 
+#include <assert.h>
 #include <common/bl_common.h>
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/utils.h>
+#include <lib/mmio.h>
 #include <plat/common/platform.h>
 
 #include <k3_gicv3.h>
@@ -35,8 +37,25 @@ gicv3_driver_data_t k3_gic_data = {
        .mpidr_to_core_pos = k3_mpidr_to_core_pos,
 };
 
-void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base)
+void k3_gic_driver_init(uintptr_t gic_base)
 {
+       /* GIC Distributor is always at the base of the IP */
+       uintptr_t gicd_base = gic_base;
+       /* GIC Redistributor base is run-time detected */
+       uintptr_t gicr_base = 0;
+
+       for (unsigned int gicr_shift = 18; gicr_shift < 21; gicr_shift++) {
+               uintptr_t gicr_check = gic_base + BIT(gicr_shift);
+               uint32_t iidr = mmio_read_32(gicr_check + GICR_IIDR);
+               if (iidr != 0) {
+                       /* Found the GICR base */
+                       gicr_base = gicr_check;
+                       break;
+               }
+       }
+       /* Assert if we have not found the GICR base */
+       assert(gicr_base != 0);
+
        /*
         * The GICv3 driver is initialized in EL3 and does not need
         * to be initialized again in SEL1. This is because the S-EL1
index cb75bf6544143f10c530380f1cee4ef35166bcfd..235e6396b6f1f564ae934de841754e368a162f81 100644 (file)
@@ -81,15 +81,16 @@ static int k3_pwr_domain_on(u_register_t mpidr)
 
 void k3_pwr_domain_off(const psci_power_state_t *target_state)
 {
-       int core_id, device, ret;
+       int core_id, proc, device, ret;
 
        /* Prevent interrupts from spuriously waking up this cpu */
        k3_gic_cpuif_disable();
 
        core_id = plat_my_core_pos();
+       proc = PLAT_PROC_START_ID + core_id;
        device = PLAT_PROC_DEVICE_START_ID + core_id;
 
-       ret = ti_sci_device_put(device);
+       ret = ti_sci_proc_shutdown(proc, device);
        if (ret) {
                ERROR("Request to stop core failed: %d\n", ret);
                return;
index 9b3e7d84f51a263f2f58b4d5845a30ba1ac68415..c91a03586fe55c1ba782007017315776d852500e 100644 (file)
@@ -30,6 +30,10 @@ MULTI_CONSOLE_API    :=      1
 TI_16550_MDR_QUIRK     :=      1
 $(eval $(call add_define,TI_16550_MDR_QUIRK))
 
+# Allow customizing the UART baud rate
+K3_USART_BAUD          :=      115200
+$(eval $(call add_define,K3_USART_BAUD))
+
 # Libraries
 include lib/xlat_tables_v2/xlat_tables.mk
 
index 52f34ff1f693682af8d345a43cf69120c6fc6008..2329a16e573f340941dc7f074eb58328455f4412 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <stdint.h>
 
-void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base);
+void k3_gic_driver_init(uintptr_t gic_base);
 void k3_gic_init(void);
 void k3_gic_cpuif_enable(void);
 void k3_gic_cpuif_disable(void);
index 5d563b6f0a0b2435f5682a71f8d9f32a52c9c14f..f1511c136dcd689ee1703baca8847d8d079d087e 100644 (file)
 #define K3_USART_CLK_SPEED 48000000
 #endif
 
-#ifndef K3_USART_BAUD
-#define K3_USART_BAUD 115200
-#endif
-
 /* Crash console defaults */
 #define CRASH_CONSOLE_BASE K3_USART_BASE_ADDRESS
 #define CRASH_CONSOLE_CLK K3_USART_CLK_SPEED
        INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
                        GIC_INTR_CFG_EDGE)
 
-#define K3_GICD_BASE  0x01800000
-#define K3_GICD_SIZE  0x10000
-#define K3_GICR_BASE  0x01880000
-#define K3_GICR_SIZE  0x100000
+#define K3_GIC_BASE    0x01800000
+#define K3_GIC_SIZE    0x200000
 
 #define SEC_PROXY_DATA_BASE    0x32C00000
 #define SEC_PROXY_DATA_SIZE    0x80000
diff --git a/plat/xilinx/common/include/ipi.h b/plat/xilinx/common/include/ipi.h
new file mode 100644 (file)
index 0000000..483902e
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018, Xilinx, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Xilinx IPI management configuration data and macros */
+
+#ifndef IPI_H
+#define IPI_H
+
+#include <stdint.h>
+
+/*********************************************************************
+ * IPI mailbox status macros
+ ********************************************************************/
+#define IPI_MB_STATUS_IDLE             0
+#define IPI_MB_STATUS_SEND_PENDING     1
+#define IPI_MB_STATUS_RECV_PENDING     2
+
+/*********************************************************************
+ * IPI mailbox call is secure or not macros
+ ********************************************************************/
+#define IPI_MB_CALL_NOTSECURE  0
+#define IPI_MB_CALL_SECURE     1
+
+/*********************************************************************
+ * IPI secure check
+ ********************************************************************/
+#define IPI_SECURE_MASK  0x1U
+#define IPI_IS_SECURE(I) ((ipi_table[(I)].secure_only & \
+                          IPI_SECURE_MASK) ? 1 : 0)
+
+/*********************************************************************
+ * Struct definitions
+ ********************************************************************/
+
+/* structure to maintain IPI configuration information */
+struct ipi_config {
+       unsigned int ipi_bit_mask;
+       unsigned int ipi_reg_base;
+       unsigned char secure_only;
+};
+
+/*********************************************************************
+ * IPI APIs declarations
+ ********************************************************************/
+
+/* Initialize IPI configuration table */
+void ipi_config_table_init(const struct ipi_config *ipi_table,
+                          uint32_t total_ipi);
+
+/* Validate IPI mailbox access */
+int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure);
+
+/* Open the IPI mailbox */
+void ipi_mb_open(uint32_t local, uint32_t remote);
+
+/* Release the IPI mailbox */
+void ipi_mb_release(uint32_t local, uint32_t remote);
+
+/* Enquire IPI mailbox status */
+int ipi_mb_enquire_status(uint32_t local, uint32_t remote);
+
+/* Trigger notification on the IPI mailbox */
+void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking);
+
+/* Ack IPI mailbox notification */
+void ipi_mb_ack(uint32_t local, uint32_t remote);
+
+/* Disable IPI mailbox notification interrupt */
+void ipi_mb_disable_irq(uint32_t local, uint32_t remote);
+
+/* Enable IPI mailbox notification interrupt */
+void ipi_mb_enable_irq(uint32_t local, uint32_t remote);
+
+#endif /* IPI_H */
diff --git a/plat/xilinx/common/include/pm_common.h b/plat/xilinx/common/include/pm_common.h
new file mode 100644 (file)
index 0000000..c0a51f0
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Contains definitions of commonly used macros and data types needed
+ * for PU Power Management. This file should be common for all PU's.
+ */
+
+#ifndef PM_COMMON_H
+#define PM_COMMON_H
+
+#include <stdint.h>
+#include <plat_pm_common.h>
+
+/**
+ * pm_ipi - struct for capturing IPI-channel specific info
+ * @local_ipi_id       Local IPI agent ID
+ * @remote_ipi_id      Remote IPI Agent ID
+ * @buffer_base        base address for payload buffer
+ */
+struct pm_ipi {
+       const uint32_t local_ipi_id;
+       const uint32_t remote_ipi_id;
+       const uintptr_t buffer_base;
+};
+
+/**
+ * pm_proc - struct for capturing processor related info
+ * @node_id    node-ID of the processor
+ * @pwrdn_mask cpu-specific mask to be used for power control register
+ * @ipi                pointer to IPI channel structure
+ *             (in APU all processors share one IPI channel)
+ */
+struct pm_proc {
+       const uint32_t node_id;
+       const unsigned int pwrdn_mask;
+       const struct pm_ipi *ipi;
+};
+
+const struct pm_proc *pm_get_proc(unsigned int cpuid);
+
+#endif /* PM_COMMON_H */
diff --git a/plat/xilinx/common/include/pm_ipi.h b/plat/xilinx/common/include/pm_ipi.h
new file mode 100644 (file)
index 0000000..16db5c5
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PM_IPI_H
+#define PM_IPI_H
+
+#include <plat_ipi.h>
+#include "pm_common.h"
+
+#define IPI_BLOCKING           1
+#define IPI_NON_BLOCKING       0
+
+int pm_ipi_init(const struct pm_proc *proc);
+
+enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
+                              uint32_t payload[PAYLOAD_ARG_CNT]);
+enum pm_ret_status pm_ipi_send_non_blocking(const struct pm_proc *proc,
+                                           uint32_t payload[PAYLOAD_ARG_CNT]);
+enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
+                                   uint32_t payload[PAYLOAD_ARG_CNT],
+                                   unsigned int *value, size_t count);
+void pm_ipi_buff_read_callb(unsigned int *value, size_t count);
+void pm_ipi_irq_enable(const struct pm_proc *proc);
+void pm_ipi_irq_clear(const struct pm_proc *proc);
+uint32_t pm_ipi_irq_status(const struct pm_proc *proc);
+
+#endif /* PM_IPI_H */
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
new file mode 100644 (file)
index 0000000..0b8020b
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Xilinx IPI agent registers access management
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+
+#include <ipi.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
+
+/*********************************************************************
+ * Macros definitions
+ ********************************************************************/
+
+/* IPI registers offsets macros */
+#define IPI_TRIG_OFFSET 0x00U
+#define IPI_OBR_OFFSET  0x04U
+#define IPI_ISR_OFFSET  0x10U
+#define IPI_IMR_OFFSET  0x14U
+#define IPI_IER_OFFSET  0x18U
+#define IPI_IDR_OFFSET  0x1CU
+
+/* IPI register start offset */
+#define IPI_REG_BASE(I) (ipi_table[(I)].ipi_reg_base)
+
+/* IPI register bit mask */
+#define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask)
+
+/* IPI configuration table */
+const static struct ipi_config *ipi_table;
+
+/* Total number of IPI */
+static uint32_t ipi_total;
+
+/**
+ * ipi_config_init() - Initialize IPI configuration data
+ *
+ * @ipi_config_table  - IPI configuration table
+ * @ipi_total - Total number of IPI available
+ *
+ */
+void ipi_config_table_init(const struct ipi_config *ipi_config_table,
+                          uint32_t total_ipi)
+{
+       ipi_table = ipi_config_table;
+       ipi_total = total_ipi;
+}
+
+/* is_ipi_mb_within_range() - verify if IPI mailbox is within range
+ *
+ * @local  - local IPI ID
+ * @remote - remote IPI ID
+ *
+ * return - 1 if within range, 0 if not
+ */
+static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
+{
+       int ret = 1;
+
+       if (remote >= ipi_total || local >= ipi_total)
+               ret = 0;
+
+       return ret;
+}
+
+/**
+ * ipi_mb_validate() - validate IPI mailbox access
+ *
+ * @local  - local IPI ID
+ * @remote - remote IPI ID
+ * @is_secure - indicate if the requester is from secure software
+ *
+ * return - 0 success, negative value for errors
+ */
+int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
+{
+       int ret = 0;
+
+       if (!is_ipi_mb_within_range(local, remote))
+               ret = -EINVAL;
+       else if (IPI_IS_SECURE(local) && !is_secure)
+               ret = -EPERM;
+       else if (IPI_IS_SECURE(remote) && !is_secure)
+               ret = -EPERM;
+
+       return ret;
+}
+
+/**
+ * ipi_mb_open() - Open IPI mailbox.
+ *
+ * @local  - local IPI ID
+ * @remote - remote IPI ID
+ *
+ */
+void ipi_mb_open(uint32_t local, uint32_t remote)
+{
+       mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
+                     IPI_BIT_MASK(remote));
+       mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
+                     IPI_BIT_MASK(remote));
+}
+
+/**
+ * ipi_mb_release() - Open IPI mailbox.
+ *
+ * @local  - local IPI ID
+ * @remote - remote IPI ID
+ *
+ */
+void ipi_mb_release(uint32_t local, uint32_t remote)
+{
+       mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
+                     IPI_BIT_MASK(remote));
+}
+
+/**
+ * ipi_mb_enquire_status() - Enquire IPI mailbox status
+ *
+ * @local  - local IPI ID
+ * @remote - remote IPI ID
+ *
+ * return - 0 idle, positive value for pending sending or receiving,
+ *          negative value for errors
+ */
+int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
+{
+       int ret = 0;
+       uint32_t status;
+
+       status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
+       if (status & IPI_BIT_MASK(remote))
+               ret |= IPI_MB_STATUS_SEND_PENDING;
+       status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
+       if (status & IPI_BIT_MASK(remote))
+               ret |= IPI_MB_STATUS_RECV_PENDING;
+
+       return ret;
+}
+
+/* ipi_mb_notify() - Trigger IPI mailbox notification
+ *
+ * @local - local IPI ID
+ * @remote - remote IPI ID
+ * @is_blocking - if to trigger the notification in blocking mode or not.
+ *
+ * It sets the remote bit in the IPI agent trigger register.
+ *
+ */
+void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
+{
+       uint32_t status;
+
+       mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
+                     IPI_BIT_MASK(remote));
+       if (is_blocking) {
+               do {
+                       status = mmio_read_32(IPI_REG_BASE(local) +
+                                             IPI_OBR_OFFSET);
+               } while (status & IPI_BIT_MASK(remote));
+       }
+}
+
+/* ipi_mb_ack() - Ack IPI mailbox notification from the other end
+ *
+ * @local - local IPI ID
+ * @remote - remote IPI ID
+ *
+ * It will clear the remote bit in the isr register.
+ *
+ */
+void ipi_mb_ack(uint32_t local, uint32_t remote)
+{
+       mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
+                     IPI_BIT_MASK(remote));
+}
+
+/* ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt
+ *
+ * @local - local IPI ID
+ * @remote - remote IPI ID
+ *
+ * It will mask the remote bit in the idr register.
+ *
+ */
+void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
+{
+       mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
+                     IPI_BIT_MASK(remote));
+}
+
+/* ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt
+ *
+ * @local - local IPI ID
+ * @remote - remote IPI ID
+ *
+ * It will mask the remote bit in the idr register.
+ *
+ */
+void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
+{
+       mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET,
+                     IPI_BIT_MASK(remote));
+}
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
new file mode 100644 (file)
index 0000000..034cd5b
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <arch_helpers.h>
+
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+
+#include <ipi.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
+#include <plat/common/platform.h>
+
+#include "pm_ipi.h"
+
+
+DEFINE_BAKERY_LOCK(pm_secure_lock);
+
+/**
+ * pm_ipi_init() - Initialize IPI peripheral for communication with
+ *                remote processor
+ *
+ * @proc       Pointer to the processor who is initiating request
+ * @return     On success, the initialization function must return 0.
+ *             Any other return value will cause the framework to ignore
+ *             the service
+ *
+ * Called from pm_setup initialization function
+ */
+int pm_ipi_init(const struct pm_proc *proc)
+{
+       bakery_lock_init(&pm_secure_lock);
+       ipi_mb_open(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
+
+       return 0;
+}
+
+/**
+ * pm_ipi_send_common() - Sends IPI request to the remote processor
+ * @proc       Pointer to the processor who is initiating request
+ * @payload    API id and call arguments to be written in IPI buffer
+ *
+ * Send an IPI request to the power controller. Caller needs to hold
+ * the 'pm_secure_lock' lock.
+ *
+ * @return     Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ipi_send_common(const struct pm_proc *proc,
+                                            uint32_t payload[PAYLOAD_ARG_CNT],
+                                            uint32_t is_blocking)
+{
+       unsigned int offset = 0;
+       uintptr_t buffer_base = proc->ipi->buffer_base +
+                                       IPI_BUFFER_TARGET_REMOTE_OFFSET +
+                                       IPI_BUFFER_REQ_OFFSET;
+
+       /* Write payload into IPI buffer */
+       for (size_t i = 0; i < PAYLOAD_ARG_CNT; i++) {
+               mmio_write_32(buffer_base + offset, payload[i]);
+               offset += PAYLOAD_ARG_SIZE;
+       }
+
+       /* Generate IPI to remote processor */
+       ipi_mb_notify(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id,
+                     is_blocking);
+
+       return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_ipi_send_non_blocking() - Sends IPI request to the remote processor
+ *                             without blocking notification
+ * @proc       Pointer to the processor who is initiating request
+ * @payload    API id and call arguments to be written in IPI buffer
+ *
+ * Send an IPI request to the power controller.
+ *
+ * @return     Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_ipi_send_non_blocking(const struct pm_proc *proc,
+                                           uint32_t payload[PAYLOAD_ARG_CNT])
+{
+       enum pm_ret_status ret;
+
+       bakery_lock_get(&pm_secure_lock);
+
+       ret = pm_ipi_send_common(proc, payload, IPI_NON_BLOCKING);
+
+       bakery_lock_release(&pm_secure_lock);
+
+       return ret;
+}
+
+/**
+ * pm_ipi_send() - Sends IPI request to the remote processor
+ * @proc       Pointer to the processor who is initiating request
+ * @payload    API id and call arguments to be written in IPI buffer
+ *
+ * Send an IPI request to the power controller.
+ *
+ * @return     Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
+                              uint32_t payload[PAYLOAD_ARG_CNT])
+{
+       enum pm_ret_status ret;
+
+       bakery_lock_get(&pm_secure_lock);
+
+       ret = pm_ipi_send_common(proc, payload, IPI_BLOCKING);
+
+       bakery_lock_release(&pm_secure_lock);
+
+       return ret;
+}
+
+
+/**
+ * pm_ipi_buff_read() - Reads IPI response after remote processor has handled
+ *                     interrupt
+ * @proc       Pointer to the processor who is waiting and reading response
+ * @value      Used to return value from IPI buffer element (optional)
+ * @count      Number of values to return in @value
+ *
+ * @return     Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
+                                          unsigned int *value, size_t count)
+{
+       size_t i;
+       uintptr_t buffer_base = proc->ipi->buffer_base +
+                               IPI_BUFFER_TARGET_REMOTE_OFFSET +
+                               IPI_BUFFER_RESP_OFFSET;
+
+       /*
+        * Read response from IPI buffer
+        * buf-0: success or error+reason
+        * buf-1: value
+        * buf-2: unused
+        * buf-3: unused
+        */
+       for (i = 1; i <= count; i++) {
+               *value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
+               value++;
+       }
+
+       return mmio_read_32(buffer_base);
+}
+
+/**
+ * pm_ipi_buff_read_callb() - Reads IPI response after remote processor has
+ *                           handled interrupt
+ * @value      Used to return value from IPI buffer element (optional)
+ * @count      Number of values to return in @value
+ *
+ * @return     Returns status, either success or error+reason
+ */
+void pm_ipi_buff_read_callb(unsigned int *value, size_t count)
+{
+       size_t i;
+       uintptr_t buffer_base = IPI_BUFFER_REMOTE_BASE +
+                               IPI_BUFFER_TARGET_LOCAL_OFFSET +
+                               IPI_BUFFER_REQ_OFFSET;
+
+       if (count > IPI_BUFFER_MAX_WORDS)
+               count = IPI_BUFFER_MAX_WORDS;
+
+       for (i = 0; i <= count; i++) {
+               *value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
+               value++;
+       }
+}
+
+/**
+ * pm_ipi_send_sync() - Sends IPI request to the remote processor
+ * @proc       Pointer to the processor who is initiating request
+ * @payload    API id and call arguments to be written in IPI buffer
+ * @value      Used to return value from IPI buffer element (optional)
+ * @count      Number of values to return in @value
+ *
+ * Send an IPI request to the power controller and wait for it to be handled.
+ *
+ * @return     Returns status, either success or error+reason and, optionally,
+ *             @value
+ */
+enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
+                                   uint32_t payload[PAYLOAD_ARG_CNT],
+                                   unsigned int *value, size_t count)
+{
+       enum pm_ret_status ret;
+
+       bakery_lock_get(&pm_secure_lock);
+
+       ret = pm_ipi_send_common(proc, payload, IPI_BLOCKING);
+       if (ret != PM_RET_SUCCESS)
+               goto unlock;
+
+       ret = pm_ipi_buff_read(proc, value, count);
+
+unlock:
+       bakery_lock_release(&pm_secure_lock);
+
+       return ret;
+}
+
+void pm_ipi_irq_enable(const struct pm_proc *proc)
+{
+       ipi_mb_enable_irq(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
+}
+
+void pm_ipi_irq_clear(const struct pm_proc *proc)
+{
+       ipi_mb_ack(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
+}
+
+uint32_t pm_ipi_irq_status(const struct pm_proc *proc)
+{
+       int ret;
+
+       ret = ipi_mb_enquire_status(proc->ipi->local_ipi_id,
+                                   proc->ipi->remote_ipi_id);
+       if (ret & IPI_MB_STATUS_RECV_PENDING)
+               return 1;
+       else
+               return 0;
+}
index 23c02e068bfb8c2459ea1bdbd6bf8a24351e44c3..8ff6c436046ff86160127576ff78aadc0b21e3af 100644 (file)
@@ -11,9 +11,9 @@
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables.h>
+#include <plat_private.h>
 #include <plat/common/platform.h>
 
-#include "../zynqmp_private.h"
 #include "pm_api_sys.h"
 
 /*
index 01cd781ff64ee13c1079bd35ff00df57ba18f66e..b0eb66ca40aa59ae23bc0ae2834e62d3c668843c 100644 (file)
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/console.h>
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include "zynqmp_private.h"
+#include <plat_private.h>
 
 #define BL31_END (unsigned long)(&__BL31_END__)
 
diff --git a/plat/xilinx/zynqmp/include/plat_ipi.h b/plat/xilinx/zynqmp/include/plat_ipi.h
new file mode 100644 (file)
index 0000000..bccd2f1
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* ZynqMP IPI management enums and defines */
+
+#ifndef PLAT_IPI_H
+#define PLAT_IPI_H
+
+#include <stdint.h>
+#include <ipi.h>
+
+/*********************************************************************
+ * IPI agent IDs macros
+ ********************************************************************/
+#define IPI_ID_APU     0U
+#define IPI_ID_RPU0    1U
+#define IPI_ID_RPU1    2U
+#define IPI_ID_PMU0    3U
+#define IPI_ID_PMU1    4U
+#define IPI_ID_PMU2    5U
+#define IPI_ID_PMU3    6U
+#define IPI_ID_PL0     7U
+#define IPI_ID_PL1     8U
+#define IPI_ID_PL2     9U
+#define IPI_ID_PL3     10U
+
+/*********************************************************************
+ * IPI message buffers
+ ********************************************************************/
+#define IPI_BUFFER_BASEADDR    0xFF990000U
+
+#define IPI_BUFFER_APU_BASE    (IPI_BUFFER_BASEADDR + 0x400U)
+#define IPI_BUFFER_PMU_BASE    (IPI_BUFFER_BASEADDR + 0xE00U)
+
+#define IPI_BUFFER_LOCAL_BASE  IPI_BUFFER_APU_BASE
+#define IPI_BUFFER_REMOTE_BASE IPI_BUFFER_PMU_BASE
+
+#define IPI_BUFFER_TARGET_LOCAL_OFFSET 0x80U
+#define IPI_BUFFER_TARGET_REMOTE_OFFSET        0x1C0U
+
+#define IPI_BUFFER_MAX_WORDS   8
+
+#define IPI_BUFFER_REQ_OFFSET  0x0U
+#define IPI_BUFFER_RESP_OFFSET 0x20U
+
+/*********************************************************************
+ * Platform specific IPI API declarations
+ ********************************************************************/
+
+/* Configure IPI table for zynqmp */
+void zynqmp_ipi_config_table_init(void);
+
+#endif /* PLAT_IPI_H */
index e54cfc49866651ec3ab7e0238ea5adecdceabeb8..bf1ff82b37e45b414536ed52c9abcc3657b53efd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,7 +8,7 @@
 
 #include <arm_macros.S>
 #include <cci_macros.S>
-#include "../zynqmp_def.h"
+#include "zynqmp_def.h"
 
        /* ---------------------------------------------
         * The below required platform porting macro
diff --git a/plat/xilinx/zynqmp/include/plat_pm_common.h b/plat/xilinx/zynqmp/include/plat_pm_common.h
new file mode 100644 (file)
index 0000000..1b371cc
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Contains platform specific definitions of commonly used macros data types
+ * for PU Power Management. This file should be common for all PU's.
+ */
+
+#ifndef PLAT_PM_COMMON_H
+#define PLAT_PM_COMMON_H
+
+#include <stdint.h>
+#include <common/debug.h>
+#include "pm_defs.h"
+
+#define PAYLOAD_ARG_CNT                6U
+#define PAYLOAD_ARG_SIZE       4U      /* size in bytes */
+
+#define ZYNQMP_TZ_VERSION_MAJOR                1
+#define ZYNQMP_TZ_VERSION_MINOR                0
+#define ZYNQMP_TZ_VERSION              ((ZYNQMP_TZ_VERSION_MAJOR << 16) | \
+                                       ZYNQMP_TZ_VERSION_MINOR)
+#endif /* _PLAT_PM_COMMON_H_ */
diff --git a/plat/xilinx/zynqmp/include/plat_private.h b/plat/xilinx/zynqmp/include/plat_private.h
new file mode 100644 (file)
index 0000000..99d0bc6
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_PRIVATE_H
+#define PLAT_PRIVATE_H
+
+#include <stdint.h>
+
+#include <bl31/interrupt_mgmt.h>
+#include <common/bl_common.h>
+
+void zynqmp_config_setup(void);
+
+unsigned int zynqmp_calc_core_pos(u_register_t mpidr);
+
+/* ZynqMP specific functions */
+unsigned int zynqmp_get_uart_clk(void);
+unsigned int zynqmp_get_bootmode(void);
+
+/* For FSBL handover */
+enum fsbl_handoff {
+       FSBL_HANDOFF_SUCCESS = 0,
+       FSBL_HANDOFF_NO_STRUCT,
+       FSBL_HANDOFF_INVAL_STRUCT,
+       FSBL_HANDOFF_TOO_MANY_PARTS,
+};
+
+#if ZYNQMP_WDT_RESTART
+/*
+ * Register handler to specific GIC entrance
+ * for INTR_TYPE_EL3 type of interrupt
+ */
+int request_intr_type_el3(uint32_t, interrupt_type_handler_t);
+#endif
+
+enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32_image_ep_info,
+                      entry_point_info_t *bl33_image_ep_info);
+
+#endif /* PLAT_PRIVATE_H */
index e3c9fcc1720740740e707e26a1f86bd52fb65c0c..fb1041137fde7861ed841912ce621995abf903b8 100644 (file)
@@ -12,7 +12,7 @@
 #include <drivers/arm/gic_common.h>
 #include <lib/utils_def.h>
 
-#include "../zynqmp_def.h"
+#include "zynqmp_def.h"
 
 /*******************************************************************************
  * Generic platform constants
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
new file mode 100644 (file)
index 0000000..8648b9a
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ZYNQMP_DEF_H
+#define ZYNQMP_DEF_H
+
+#include <plat/common/common_def.h>
+
+#define ZYNQMP_CONSOLE_ID_cadence      1
+#define ZYNQMP_CONSOLE_ID_cadence0     1
+#define ZYNQMP_CONSOLE_ID_cadence1     2
+#define ZYNQMP_CONSOLE_ID_dcc          3
+
+#define ZYNQMP_CONSOLE_IS(con) (ZYNQMP_CONSOLE_ID_ ## con == ZYNQMP_CONSOLE)
+
+/* Firmware Image Package */
+#define ZYNQMP_PRIMARY_CPU             0
+
+/* Memory location options for Shared data and TSP in ZYNQMP */
+#define ZYNQMP_IN_TRUSTED_SRAM         0
+#define ZYNQMP_IN_TRUSTED_DRAM         1
+
+/*******************************************************************************
+ * ZYNQMP memory map related constants
+ ******************************************************************************/
+/* Aggregate of all devices in the first GB */
+#define DEVICE0_BASE           U(0xFF000000)
+#define DEVICE0_SIZE           U(0x00E00000)
+#define DEVICE1_BASE           U(0xF9000000)
+#define DEVICE1_SIZE           U(0x00800000)
+
+/* For cpu reset APU space here too 0xFE5F1000 CRF_APB*/
+#define CRF_APB_BASE           U(0xFD1A0000)
+#define CRF_APB_SIZE           U(0x00600000)
+#define CRF_APB_CLK_BASE       U(0xFD1A0020)
+
+/* CRF registers and bitfields */
+#define CRF_APB_RST_FPD_APU    (CRF_APB_BASE + 0X00000104)
+
+#define CRF_APB_RST_FPD_APU_ACPU_RESET         (U(1) << 0)
+#define CRF_APB_RST_FPD_APU_ACPU_PWRON_RESET   (U(1) << 10)
+
+/* CRL registers and bitfields */
+#define CRL_APB_BASE                   U(0xFF5E0000)
+#define CRL_APB_BOOT_MODE_USER         (CRL_APB_BASE + 0x200)
+#define CRL_APB_RESET_CTRL             (CRL_APB_BASE + 0x218)
+#define CRL_APB_RST_LPD_TOP            (CRL_APB_BASE + 0x23C)
+#define CRL_APB_BOOT_PIN_CTRL          (CRL_APB_BASE + U(0x250))
+#define CRL_APB_CLK_BASE               U(0xFF5E0020)
+
+#define CRL_APB_RPU_AMBA_RESET         (U(1) << 2)
+#define CRL_APB_RPLL_CTRL_BYPASS       (U(1) << 3)
+
+#define CRL_APB_RESET_CTRL_SOFT_RESET  (U(1) << 4)
+
+#define CRL_APB_BOOT_MODE_MASK         (U(0xf) << 0)
+#define CRL_APB_BOOT_PIN_MASK          (U(0xf0f) << 0)
+#define CRL_APB_BOOT_DRIVE_PIN_1_SHIFT U(9)
+#define CRL_APB_BOOT_ENABLE_PIN_1_SHIFT        U(1)
+#define CRL_APB_BOOT_ENABLE_PIN_1      (U(0x1) << \
+                                       CRL_APB_BOOT_ENABLE_PIN_1_SHIFT)
+#define CRL_APB_BOOT_DRIVE_PIN_1       (U(0x1) << \
+                                       CRL_APB_BOOT_DRIVE_PIN_1_SHIFT)
+#define ZYNQMP_BOOTMODE_JTAG           U(0)
+#define ZYNQMP_ULPI_RESET_VAL_HIGH     (CRL_APB_BOOT_ENABLE_PIN_1 | \
+                                        CRL_APB_BOOT_DRIVE_PIN_1)
+#define ZYNQMP_ULPI_RESET_VAL_LOW      CRL_APB_BOOT_ENABLE_PIN_1
+
+/* system counter registers and bitfields */
+#define IOU_SCNTRS_BASE                        0xFF260000
+#define IOU_SCNTRS_BASEFREQ            (IOU_SCNTRS_BASE + 0x20)
+
+/* APU registers and bitfields */
+#define APU_BASE               0xFD5C0000
+#define APU_CONFIG_0           (APU_BASE + 0x20)
+#define APU_RVBAR_L_0          (APU_BASE + 0x40)
+#define APU_RVBAR_H_0          (APU_BASE + 0x44)
+#define APU_PWRCTL             (APU_BASE + 0x90)
+
+#define APU_CONFIG_0_VINITHI_SHIFT     8
+#define APU_0_PWRCTL_CPUPWRDWNREQ_MASK         1
+#define APU_1_PWRCTL_CPUPWRDWNREQ_MASK         2
+#define APU_2_PWRCTL_CPUPWRDWNREQ_MASK         4
+#define APU_3_PWRCTL_CPUPWRDWNREQ_MASK         8
+
+/* PMU registers and bitfields */
+#define PMU_GLOBAL_BASE                        0xFFD80000
+#define PMU_GLOBAL_CNTRL               (PMU_GLOBAL_BASE + 0)
+#define PMU_GLOBAL_GEN_STORAGE6                (PMU_GLOBAL_BASE + 0x48)
+#define PMU_GLOBAL_REQ_PWRUP_STATUS    (PMU_GLOBAL_BASE + 0x110)
+#define PMU_GLOBAL_REQ_PWRUP_EN                (PMU_GLOBAL_BASE + 0x118)
+#define PMU_GLOBAL_REQ_PWRUP_DIS       (PMU_GLOBAL_BASE + 0x11c)
+#define PMU_GLOBAL_REQ_PWRUP_TRIG      (PMU_GLOBAL_BASE + 0x120)
+
+#define PMU_GLOBAL_CNTRL_FW_IS_PRESENT (1 << 4)
+
+/*******************************************************************************
+ * CCI-400 related constants
+ ******************************************************************************/
+#define PLAT_ARM_CCI_BASE              0xFD6E0000
+#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX      3
+#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX      4
+
+/*******************************************************************************
+ * GIC-400 & interrupt handling related constants
+ ******************************************************************************/
+#define BASE_GICD_BASE         0xF9010000
+#define BASE_GICC_BASE         0xF9020000
+#define BASE_GICH_BASE         0xF9040000
+#define BASE_GICV_BASE         0xF9060000
+
+#if ZYNQMP_WDT_RESTART
+#define IRQ_SEC_IPI_APU                67
+#define IRQ_TTC3_1             77
+#define TTC3_BASE_ADDR         0xFF140000
+#define TTC3_INTR_REGISTER_1   (TTC3_BASE_ADDR + 0x54)
+#define TTC3_INTR_ENABLE_1     (TTC3_BASE_ADDR + 0x60)
+#endif
+
+#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 MAX_INTR_EL3                   128
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define ZYNQMP_UART0_BASE              0xFF000000
+#define ZYNQMP_UART1_BASE              0xFF010000
+
+#if ZYNQMP_CONSOLE_IS(cadence) || ZYNQMP_CONSOLE_IS(dcc)
+# define ZYNQMP_UART_BASE      ZYNQMP_UART0_BASE
+#elif ZYNQMP_CONSOLE_IS(cadence1)
+# define ZYNQMP_UART_BASE      ZYNQMP_UART1_BASE
+#else
+# error "invalid ZYNQMP_CONSOLE"
+#endif
+
+#define ZYNQMP_CRASH_UART_BASE         ZYNQMP_UART_BASE
+/* impossible to call C routine how it is done now - hardcode any value */
+#define ZYNQMP_CRASH_UART_CLK_IN_HZ    100000000 /* FIXME */
+/* Must be non zero */
+#define ZYNQMP_UART_BAUDRATE           115200
+
+/* Silicon version detection */
+#define ZYNQMP_SILICON_VER_MASK                0xF000
+#define ZYNQMP_SILICON_VER_SHIFT       12
+#define ZYNQMP_CSU_VERSION_SILICON     0
+#define ZYNQMP_CSU_VERSION_QEMU                3
+
+#define ZYNQMP_RTL_VER_MASK            0xFF0
+#define ZYNQMP_RTL_VER_SHIFT           4
+
+#define ZYNQMP_PS_VER_MASK             0xF
+#define ZYNQMP_PS_VER_SHIFT            0
+
+#define ZYNQMP_CSU_BASEADDR            0xFFCA0000
+#define ZYNQMP_CSU_IDCODE_OFFSET       0x40
+
+#define ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT      0
+#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK       (0xFFF << \
+                                       ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT)
+#define ZYNQMP_CSU_IDCODE_XILINX_ID            0x093
+
+#define ZYNQMP_CSU_IDCODE_SVD_SHIFT            12
+#define ZYNQMP_CSU_IDCODE_SVD_MASK             (0x7 << \
+                                                ZYNQMP_CSU_IDCODE_SVD_SHIFT)
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT    15
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK     (0xF << \
+                                       ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
+#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT     19
+#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK      (0x3 << \
+                                       ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT)
+#define ZYNQMP_CSU_IDCODE_FAMILY_SHIFT         21
+#define ZYNQMP_CSU_IDCODE_FAMILY_MASK          (0x7F << \
+                                       ZYNQMP_CSU_IDCODE_FAMILY_SHIFT)
+#define ZYNQMP_CSU_IDCODE_FAMILY               0x23
+
+#define ZYNQMP_CSU_IDCODE_REVISION_SHIFT       28
+#define ZYNQMP_CSU_IDCODE_REVISION_MASK                (0xF << \
+                                       ZYNQMP_CSU_IDCODE_REVISION_SHIFT)
+#define ZYNQMP_CSU_IDCODE_REVISION             0
+
+#define ZYNQMP_CSU_VERSION_OFFSET      0x44
+
+/* Efuse */
+#define EFUSE_BASEADDR         0xFFCC0000
+#define EFUSE_IPDISABLE_OFFSET 0x1018
+#define EFUSE_IPDISABLE_VERSION        0x1FFU
+#define ZYNQMP_EFUSE_IPDISABLE_SHIFT   20
+
+/* Access control register defines */
+#define ACTLR_EL3_L2ACTLR_BIT  (1 << 6)
+#define ACTLR_EL3_CPUACTLR_BIT (1 << 0)
+
+#define FPD_SLCR_BASEADDR              U(0xFD610000)
+#define IOU_SLCR_BASEADDR              U(0xFF180000)
+
+#define ZYNQMP_RPU_GLBL_CNTL                   U(0xFF9A0000)
+#define ZYNQMP_RPU0_CFG                                U(0xFF9A0100)
+#define ZYNQMP_RPU1_CFG                                U(0xFF9A0200)
+#define ZYNQMP_SLSPLIT_MASK                    U(0x08)
+#define ZYNQMP_TCM_COMB_MASK                   U(0x40)
+#define ZYNQMP_SLCLAMP_MASK                    U(0x10)
+#define ZYNQMP_VINITHI_MASK                    U(0x04)
+
+/* Tap delay bypass */
+#define IOU_TAPDLY_BYPASS                      U(0XFF180390)
+#define TAP_DELAY_MASK                         U(0x7)
+
+/* SGMII mode */
+#define IOU_GEM_CTRL                           U(0xFF180360)
+#define IOU_GEM_CLK_CTRL                       U(0xFF180308)
+#define SGMII_SD_MASK                          U(0x3)
+#define SGMII_SD_OFFSET                                U(2)
+#define SGMII_PCS_SD_0                         U(0x0)
+#define SGMII_PCS_SD_1                         U(0x1)
+#define SGMII_PCS_SD_PHY                       U(0x2)
+#define GEM_SGMII_MASK                         U(0x4)
+#define GEM_CLK_CTRL_MASK                      U(0xF)
+#define GEM_CLK_CTRL_OFFSET                    U(5)
+#define GEM_RX_SRC_SEL_GTR                     U(0x1)
+#define GEM_SGMII_MODE                         U(0x4)
+
+/* SD DLL reset */
+#define ZYNQMP_SD_DLL_CTRL                     U(0xFF180358)
+#define ZYNQMP_SD0_DLL_RST_MASK                        U(0x00000004)
+#define ZYNQMP_SD0_DLL_RST                     U(0x00000004)
+#define ZYNQMP_SD1_DLL_RST_MASK                        U(0x00040000)
+#define ZYNQMP_SD1_DLL_RST                     U(0x00040000)
+
+/* SD tap delay */
+#define ZYNQMP_SD_DLL_CTRL                     U(0xFF180358)
+#define ZYNQMP_SD_ITAP_DLY                     U(0xFF180314)
+#define ZYNQMP_SD_OTAP_DLY                     U(0xFF180318)
+#define ZYNQMP_SD_TAP_OFFSET                   U(16)
+#define ZYNQMP_SD_ITAPCHGWIN_MASK              U(0x200)
+#define ZYNQMP_SD_ITAPCHGWIN                   U(0x200)
+#define ZYNQMP_SD_ITAPDLYENA_MASK              U(0x100)
+#define ZYNQMP_SD_ITAPDLYENA                   U(0x100)
+#define ZYNQMP_SD_ITAPDLYSEL_MASK              U(0xFF)
+#define ZYNQMP_SD_OTAPDLYSEL_MASK              U(0x3F)
+#define ZYNQMP_SD_OTAPDLYENA_MASK              U(0x40)
+#define ZYNQMP_SD_OTAPDLYENA                   U(0x40)
+
+/* Clock control registers */
+/* Full power domain clocks */
+#define CRF_APB_APLL_CTRL              (CRF_APB_CLK_BASE + 0x00)
+#define CRF_APB_DPLL_CTRL              (CRF_APB_CLK_BASE + 0x0c)
+#define CRF_APB_VPLL_CTRL              (CRF_APB_CLK_BASE + 0x18)
+#define CRF_APB_PLL_STATUS             (CRF_APB_CLK_BASE + 0x24)
+#define CRF_APB_APLL_TO_LPD_CTRL       (CRF_APB_CLK_BASE + 0x28)
+#define CRF_APB_DPLL_TO_LPD_CTRL       (CRF_APB_CLK_BASE + 0x2c)
+#define CRF_APB_VPLL_TO_LPD_CTRL       (CRF_APB_CLK_BASE + 0x30)
+/* Peripheral clocks */
+#define CRF_APB_ACPU_CTRL              (CRF_APB_CLK_BASE + 0x40)
+#define CRF_APB_DBG_TRACE_CTRL         (CRF_APB_CLK_BASE + 0x44)
+#define CRF_APB_DBG_FPD_CTRL           (CRF_APB_CLK_BASE + 0x48)
+#define CRF_APB_DP_VIDEO_REF_CTRL      (CRF_APB_CLK_BASE + 0x50)
+#define CRF_APB_DP_AUDIO_REF_CTRL      (CRF_APB_CLK_BASE + 0x54)
+#define CRF_APB_DP_STC_REF_CTRL                (CRF_APB_CLK_BASE + 0x5c)
+#define CRF_APB_DDR_CTRL               (CRF_APB_CLK_BASE + 0x60)
+#define CRF_APB_GPU_REF_CTRL           (CRF_APB_CLK_BASE + 0x64)
+#define CRF_APB_SATA_REF_CTRL          (CRF_APB_CLK_BASE + 0x80)
+#define CRF_APB_PCIE_REF_CTRL          (CRF_APB_CLK_BASE + 0x94)
+#define CRF_APB_GDMA_REF_CTRL          (CRF_APB_CLK_BASE + 0x98)
+#define CRF_APB_DPDMA_REF_CTRL         (CRF_APB_CLK_BASE + 0x9c)
+#define CRF_APB_TOPSW_MAIN_CTRL                (CRF_APB_CLK_BASE + 0xa0)
+#define CRF_APB_TOPSW_LSBUS_CTRL       (CRF_APB_CLK_BASE + 0xa4)
+#define CRF_APB_GTGREF0_REF_CTRL       (CRF_APB_CLK_BASE + 0xa8)
+#define CRF_APB_DBG_TSTMP_CTRL         (CRF_APB_CLK_BASE + 0xd8)
+
+/* Low power domain clocks */
+#define CRL_APB_IOPLL_CTRL             (CRL_APB_CLK_BASE + 0x00)
+#define CRL_APB_RPLL_CTRL              (CRL_APB_CLK_BASE + 0x10)
+#define CRL_APB_PLL_STATUS             (CRL_APB_CLK_BASE + 0x20)
+#define CRL_APB_IOPLL_TO_FPD_CTRL      (CRL_APB_CLK_BASE + 0x24)
+#define CRL_APB_RPLL_TO_FPD_CTRL       (CRL_APB_CLK_BASE + 0x28)
+/* Peripheral clocks */
+#define CRL_APB_USB3_DUAL_REF_CTRL     (CRL_APB_CLK_BASE + 0x2c)
+#define CRL_APB_GEM0_REF_CTRL          (CRL_APB_CLK_BASE + 0x30)
+#define CRL_APB_GEM1_REF_CTRL          (CRL_APB_CLK_BASE + 0x34)
+#define CRL_APB_GEM2_REF_CTRL          (CRL_APB_CLK_BASE + 0x38)
+#define CRL_APB_GEM3_REF_CTRL          (CRL_APB_CLK_BASE + 0x3c)
+#define CRL_APB_USB0_BUS_REF_CTRL      (CRL_APB_CLK_BASE + 0x40)
+#define CRL_APB_USB1_BUS_REF_CTRL      (CRL_APB_CLK_BASE + 0x44)
+#define CRL_APB_QSPI_REF_CTRL          (CRL_APB_CLK_BASE + 0x48)
+#define CRL_APB_SDIO0_REF_CTRL         (CRL_APB_CLK_BASE + 0x4c)
+#define CRL_APB_SDIO1_REF_CTRL         (CRL_APB_CLK_BASE + 0x50)
+#define CRL_APB_UART0_REF_CTRL         (CRL_APB_CLK_BASE + 0x54)
+#define CRL_APB_UART1_REF_CTRL         (CRL_APB_CLK_BASE + 0x58)
+#define CRL_APB_SPI0_REF_CTRL          (CRL_APB_CLK_BASE + 0x5c)
+#define CRL_APB_SPI1_REF_CTRL          (CRL_APB_CLK_BASE + 0x60)
+#define CRL_APB_CAN0_REF_CTRL          (CRL_APB_CLK_BASE + 0x64)
+#define CRL_APB_CAN1_REF_CTRL          (CRL_APB_CLK_BASE + 0x68)
+#define CRL_APB_CPU_R5_CTRL            (CRL_APB_CLK_BASE + 0x70)
+#define CRL_APB_IOU_SWITCH_CTRL                (CRL_APB_CLK_BASE + 0x7c)
+#define CRL_APB_CSU_PLL_CTRL           (CRL_APB_CLK_BASE + 0x80)
+#define CRL_APB_PCAP_CTRL              (CRL_APB_CLK_BASE + 0x84)
+#define CRL_APB_LPD_SWITCH_CTRL                (CRL_APB_CLK_BASE + 0x88)
+#define CRL_APB_LPD_LSBUS_CTRL         (CRL_APB_CLK_BASE + 0x8c)
+#define CRL_APB_DBG_LPD_CTRL           (CRL_APB_CLK_BASE + 0x90)
+#define CRL_APB_NAND_REF_CTRL          (CRL_APB_CLK_BASE + 0x94)
+#define CRL_APB_ADMA_REF_CTRL          (CRL_APB_CLK_BASE + 0x98)
+#define CRL_APB_PL0_REF_CTRL           (CRL_APB_CLK_BASE + 0xa0)
+#define CRL_APB_PL1_REF_CTRL           (CRL_APB_CLK_BASE + 0xa4)
+#define CRL_APB_PL2_REF_CTRL           (CRL_APB_CLK_BASE + 0xa8)
+#define CRL_APB_PL3_REF_CTRL           (CRL_APB_CLK_BASE + 0xac)
+#define CRL_APB_PL0_THR_CNT            (CRL_APB_CLK_BASE + 0xb4)
+#define CRL_APB_PL1_THR_CNT            (CRL_APB_CLK_BASE + 0xbc)
+#define CRL_APB_PL2_THR_CNT            (CRL_APB_CLK_BASE + 0xc4)
+#define CRL_APB_PL3_THR_CNT            (CRL_APB_CLK_BASE + 0xdc)
+#define CRL_APB_GEM_TSU_REF_CTRL       (CRL_APB_CLK_BASE + 0xe0)
+#define CRL_APB_DLL_REF_CTRL           (CRL_APB_CLK_BASE + 0xe4)
+#define CRL_APB_AMS_REF_CTRL           (CRL_APB_CLK_BASE + 0xe8)
+#define CRL_APB_I2C0_REF_CTRL          (CRL_APB_CLK_BASE + 0x100)
+#define CRL_APB_I2C1_REF_CTRL          (CRL_APB_CLK_BASE + 0x104)
+#define CRL_APB_TIMESTAMP_REF_CTRL     (CRL_APB_CLK_BASE + 0x108)
+#define IOU_SLCR_GEM_CLK_CTRL          (IOU_SLCR_BASEADDR + 0x308)
+#define IOU_SLCR_CAN_MIO_CTRL          (IOU_SLCR_BASEADDR + 0x304)
+#define FPD_SLCR_WDT_CLK_SEL           (FPD_SLCR_BASEADDR + 0x100)
+
+/* Global general storage register base address */
+#define GGS_BASEADDR           (0xFFD80030U)
+#define GGS_NUM_REGS           U(4)
+
+/* Persistent global general storage register base address */
+#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))
+#define PM_BOOT_HEALTH_STATUS_MASK             U(0x01)
+
+/*AFI registers */
+#define  AFIFM6_WRCTRL         U(13)
+#define  FABRIC_WIDTH          U(3)
+
+#endif /* ZYNQMP_DEF_H */
index 11f382a05392b1b68725e2c98faaf78cab175268..c499d78e91ad44eee0afb242b6fc4514dc784876 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
 
+#include <ipi.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
+
 #include "ipi_mailbox_svc.h"
-#include "../zynqmp_ipi.h"
-#include "../zynqmp_private.h"
 #include "../../../services/spd/trusty/smcall.h"
 
 /*********************************************************************
index 4183979a2c4af7676918227ff2e58664b52e6d63..a32e08988a519feac07b7a2e1a4f9b4c872778ff 100644 (file)
 #include <drivers/arm/gicv2.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
+#include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
-#include "zynqmp_private.h"
 
 uintptr_t zynqmp_sec_entry;
 
index 03f0e3d82d72175181433a8cf1aa9eebc453353f..cd2c3bac6e6816702f522b7a4250aaf75176639a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,9 +9,9 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <lib/mmio.h>
+#include <plat_private.h>
 
 #include "zynqmp_def.h"
-#include "zynqmp_private.h"
 
 /*
  * ATFHandoffParams
index ad18aafc305988298701c3ce2d91df873dda4068..906ce1b7feb3a73ad8c5f3b316fab9b18027bfd7 100644 (file)
@@ -4,10 +4,9 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <plat_private.h>
 #include <plat/common/platform.h>
 
-#include "zynqmp_private.h"
-
 int plat_core_pos_by_mpidr(u_register_t mpidr)
 {
        if (mpidr & MPIDR_CLUSTER_MASK)
index 35c8983cdb1928a0a3629f1cfd2ad905b2f7d74f..b2f91cd8e0df90aeb688b9192e931be4ec7b40a6 100644 (file)
@@ -45,8 +45,8 @@ ifdef ZYNQMP_WDT_RESTART
 $(eval $(call add_define,ZYNQMP_WDT_RESTART))
 endif
 
-PLAT_INCLUDES          :=      -Iinclude/plat/arm/common/                      \
-                               -Iinclude/plat/arm/common/aarch64/              \
+PLAT_INCLUDES          :=      -Iinclude/plat/arm/common/aarch64/              \
+                               -Iplat/xilinx/common/include/                   \
                                -Iplat/xilinx/zynqmp/include/                   \
                                -Iplat/xilinx/zynqmp/pm_service/                \
                                -Iplat/xilinx/zynqmp/ipi_mailbox_service/
@@ -64,6 +64,7 @@ PLAT_BL_COMMON_SOURCES        :=      lib/xlat_tables/xlat_tables_common.c            \
                                plat/arm/common/arm_common.c                    \
                                plat/arm/common/arm_gicv2.c                     \
                                plat/common/plat_gicv2.c                        \
+                               plat/xilinx/common/ipi.c                        \
                                plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S     \
                                plat/xilinx/zynqmp/aarch64/zynqmp_common.c
 
@@ -71,6 +72,7 @@ BL31_SOURCES          +=      drivers/arm/cci/cci.c                           \
                                lib/cpus/aarch64/aem_generic.S                  \
                                lib/cpus/aarch64/cortex_a53.S                   \
                                plat/common/plat_psci_common.c                  \
+                               plat/xilinx/common/pm_service/pm_ipi.c          \
                                plat/xilinx/zynqmp/bl31_zynqmp_setup.c          \
                                plat/xilinx/zynqmp/plat_psci.c                  \
                                plat/xilinx/zynqmp/plat_zynqmp.c                \
@@ -83,6 +85,5 @@ BL31_SOURCES          +=      drivers/arm/cci/cci.c                           \
                                plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c  \
                                plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c    \
                                plat/xilinx/zynqmp/pm_service/pm_api_clock.c    \
-                               plat/xilinx/zynqmp/pm_service/pm_ipi.c          \
                                plat/xilinx/zynqmp/pm_service/pm_client.c       \
                                plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c
index d3f1fbfec1c6329de23b48fc0746aa93a6368ee8..44acb4bd5892abf083d2610b799652e679e3c211 100644 (file)
@@ -12,6 +12,7 @@
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 #include <plat/common/platform.h>
+#include <zynqmp_def.h>
 
 #include "pm_api_clock.h"
 #include "pm_api_ioctl.h"
@@ -19,7 +20,6 @@
 #include "pm_client.h"
 #include "pm_common.h"
 #include "pm_ipi.h"
-#include "../zynqmp_def.h"
 
 /**
  * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
index bebb74ce7fb96963de4ae8430a2835e6f5e2b7ad..163e8916f2fa30019a56c137a61de48856f25653 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,7 +19,8 @@
 #include <lib/mmio.h>
 #include <lib/utils.h>
 
-#include "../zynqmp_def.h"
+#include <plat_ipi.h>
+#include <zynqmp_def.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_ipi.h"
@@ -35,6 +36,12 @@ DEFINE_BAKERY_LOCK(pm_client_secure_lock);
 
 extern const struct pm_ipi apu_ipi;
 
+const struct pm_ipi apu_ipi = {
+       .local_ipi_id = IPI_ID_APU,
+       .remote_ipi_id = IPI_ID_PMU0,
+       .buffer_base = IPI_BUFFER_APU_BASE,
+};
+
 static uint32_t suspend_mode = PM_SUSPEND_MODE_STD;
 
 /* Order in pm_procs_all array must match cpu ids */
index 0a34a07578500b9303593e379bb6f735274d9675..adbb76f9b19fd42ce23722a0602f56fd15c01ece 100644 (file)
@@ -21,6 +21,7 @@ void pm_client_abort_suspend(void);
 void pm_client_wakeup(const struct pm_proc *proc);
 enum pm_ret_status set_ocm_retention(void);
 enum pm_ret_status pm_set_suspend_mode(uint32_t mode);
+const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid);
 
 /* Global variables to be set in pm_client.c */
 extern const struct pm_proc *primary_proc;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_common.h b/plat/xilinx/zynqmp/pm_service/pm_common.h
deleted file mode 100644 (file)
index 94e0568..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/*
- * Contains definitions of commonly used macros and data types needed
- * for PU Power Management. This file should be common for all PU's.
- */
-
-#ifndef PM_COMMON_H
-#define PM_COMMON_H
-
-#include <stdint.h>
-
-#include <common/debug.h>
-
-#include "pm_defs.h"
-
-#define PAYLOAD_ARG_CNT                6U
-#define PAYLOAD_ARG_SIZE       4U      /* size in bytes */
-
-#define ZYNQMP_TZ_VERSION_MAJOR                1
-#define ZYNQMP_TZ_VERSION_MINOR                0
-#define ZYNQMP_TZ_VERSION              ((ZYNQMP_TZ_VERSION_MAJOR << 16) | \
-                                       ZYNQMP_TZ_VERSION_MINOR)
-
-/**
- * pm_ipi - struct for capturing IPI-channel specific info
- * @apu_ipi_id APU IPI agent ID
- * @pmu_ipi_id PMU Agent ID
- * @buffer_base        base address for payload buffer
- */
-struct pm_ipi {
-       const uint32_t apu_ipi_id;
-       const uint32_t pmu_ipi_id;
-       const uintptr_t buffer_base;
-};
-
-/**
- * pm_proc - struct for capturing processor related info
- * @node_id    node-ID of the processor
- * @pwrdn_mask cpu-specific mask to be used for power control register
- * @ipi                pointer to IPI channel structure
- *             (in APU all processors share one IPI channel)
- */
-struct pm_proc {
-       const enum pm_node_id node_id;
-       const unsigned int pwrdn_mask;
-       const struct pm_ipi *ipi;
-};
-
-const struct pm_proc *pm_get_proc(unsigned int cpuid);
-const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid);
-
-#endif /* PM_COMMON_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_ipi.c b/plat/xilinx/zynqmp/pm_service/pm_ipi.c
deleted file mode 100644 (file)
index b3d833d..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch_helpers.h>
-#include <lib/bakery_lock.h>
-#include <lib/mmio.h>
-#include <plat/common/platform.h>
-
-#include "../zynqmp_ipi.h"
-#include "../zynqmp_private.h"
-#include "pm_ipi.h"
-
-/* IPI message buffers */
-#define IPI_BUFFER_BASEADDR    0xFF990000U
-
-#define IPI_BUFFER_APU_BASE    (IPI_BUFFER_BASEADDR + 0x400U)
-#define IPI_BUFFER_PMU_BASE    (IPI_BUFFER_BASEADDR + 0xE00U)
-
-#define IPI_BUFFER_TARGET_APU_OFFSET   0x80U
-#define IPI_BUFFER_TARGET_PMU_OFFSET   0x1C0U
-
-#define IPI_BUFFER_MAX_WORDS   8
-
-#define IPI_BUFFER_REQ_OFFSET  0x0U
-#define IPI_BUFFER_RESP_OFFSET 0x20U
-
-#define IPI_BLOCKING           1
-#define IPI_NON_BLOCKING       0
-
-DEFINE_BAKERY_LOCK(pm_secure_lock);
-
-const struct pm_ipi apu_ipi = {
-       .apu_ipi_id = IPI_ID_APU,
-       .pmu_ipi_id = IPI_ID_PMU0,
-       .buffer_base = IPI_BUFFER_APU_BASE,
-};
-
-/**
- * pm_ipi_init() - Initialize IPI peripheral for communication with PMU
- *
- * @proc       Pointer to the processor who is initiating request
- * @return     On success, the initialization function must return 0.
- *             Any other return value will cause the framework to ignore
- *             the service
- *
- * Called from pm_setup initialization function
- */
-int pm_ipi_init(const struct pm_proc *proc)
-{
-       bakery_lock_init(&pm_secure_lock);
-       ipi_mb_open(proc->ipi->apu_ipi_id, proc->ipi->pmu_ipi_id);
-
-       return 0;
-}
-
-/**
- * pm_ipi_send_common() - Sends IPI request to the PMU
- * @proc       Pointer to the processor who is initiating request
- * @payload    API id and call arguments to be written in IPI buffer
- *
- * Send an IPI request to the power controller. Caller needs to hold
- * the 'pm_secure_lock' lock.
- *
- * @return     Returns status, either success or error+reason
- */
-static enum pm_ret_status pm_ipi_send_common(const struct pm_proc *proc,
-                                            uint32_t payload[PAYLOAD_ARG_CNT],
-                                            uint32_t is_blocking)
-{
-       unsigned int offset = 0;
-       uintptr_t buffer_base = proc->ipi->buffer_base +
-                                       IPI_BUFFER_TARGET_PMU_OFFSET +
-                                       IPI_BUFFER_REQ_OFFSET;
-
-       /* Write payload into IPI buffer */
-       for (size_t i = 0; i < PAYLOAD_ARG_CNT; i++) {
-               mmio_write_32(buffer_base + offset, payload[i]);
-               offset += PAYLOAD_ARG_SIZE;
-       }
-
-       /* Generate IPI to PMU */
-       ipi_mb_notify(proc->ipi->apu_ipi_id, proc->ipi->pmu_ipi_id,
-                     is_blocking);
-
-       return PM_RET_SUCCESS;
-}
-
-/**
- * pm_ipi_send_non_blocking() - Sends IPI request to the PMU without blocking
- *                             notification
- * @proc       Pointer to the processor who is initiating request
- * @payload    API id and call arguments to be written in IPI buffer
- *
- * Send an IPI request to the power controller.
- *
- * @return     Returns status, either success or error+reason
- */
-enum pm_ret_status pm_ipi_send_non_blocking(const struct pm_proc *proc,
-                                           uint32_t payload[PAYLOAD_ARG_CNT])
-{
-       enum pm_ret_status ret;
-
-       bakery_lock_get(&pm_secure_lock);
-
-       ret = pm_ipi_send_common(proc, payload, IPI_NON_BLOCKING);
-
-       bakery_lock_release(&pm_secure_lock);
-
-       return ret;
-}
-
-/**
- * pm_ipi_send() - Sends IPI request to the PMU
- * @proc       Pointer to the processor who is initiating request
- * @payload    API id and call arguments to be written in IPI buffer
- *
- * Send an IPI request to the power controller.
- *
- * @return     Returns status, either success or error+reason
- */
-enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
-                              uint32_t payload[PAYLOAD_ARG_CNT])
-{
-       enum pm_ret_status ret;
-
-       bakery_lock_get(&pm_secure_lock);
-
-       ret = pm_ipi_send_common(proc, payload, IPI_BLOCKING);
-
-       bakery_lock_release(&pm_secure_lock);
-
-       return ret;
-}
-
-
-/**
- * pm_ipi_buff_read() - Reads IPI response after PMU has handled interrupt
- * @proc       Pointer to the processor who is waiting and reading response
- * @value      Used to return value from IPI buffer element (optional)
- * @count      Number of values to return in @value
- *
- * @return     Returns status, either success or error+reason
- */
-static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
-                                          unsigned int *value, size_t count)
-{
-       size_t i;
-       uintptr_t buffer_base = proc->ipi->buffer_base +
-                               IPI_BUFFER_TARGET_PMU_OFFSET +
-                               IPI_BUFFER_RESP_OFFSET;
-
-       /*
-        * Read response from IPI buffer
-        * buf-0: success or error+reason
-        * buf-1: value
-        * buf-2: unused
-        * buf-3: unused
-        */
-       for (i = 1; i <= count; i++) {
-               *value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
-               value++;
-       }
-
-       return mmio_read_32(buffer_base);
-}
-
-/**
- * pm_ipi_buff_read_callb() - Reads IPI response after PMU has handled interrupt
- * @value      Used to return value from IPI buffer element (optional)
- * @count      Number of values to return in @value
- *
- * @return     Returns status, either success or error+reason
- */
-void pm_ipi_buff_read_callb(unsigned int *value, size_t count)
-{
-       size_t i;
-       uintptr_t buffer_base = IPI_BUFFER_PMU_BASE +
-                               IPI_BUFFER_TARGET_APU_OFFSET +
-                               IPI_BUFFER_REQ_OFFSET;
-
-       if (count > IPI_BUFFER_MAX_WORDS)
-               count = IPI_BUFFER_MAX_WORDS;
-
-       for (i = 0; i <= count; i++) {
-               *value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
-               value++;
-       }
-}
-
-/**
- * pm_ipi_send_sync() - Sends IPI request to the PMU
- * @proc       Pointer to the processor who is initiating request
- * @payload    API id and call arguments to be written in IPI buffer
- * @value      Used to return value from IPI buffer element (optional)
- * @count      Number of values to return in @value
- *
- * Send an IPI request to the power controller and wait for it to be handled.
- *
- * @return     Returns status, either success or error+reason and, optionally,
- *             @value
- */
-enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
-                                   uint32_t payload[PAYLOAD_ARG_CNT],
-                                   unsigned int *value, size_t count)
-{
-       enum pm_ret_status ret;
-
-       bakery_lock_get(&pm_secure_lock);
-
-       ret = pm_ipi_send_common(proc, payload, IPI_BLOCKING);
-       if (ret != PM_RET_SUCCESS)
-               goto unlock;
-
-       ret = pm_ipi_buff_read(proc, value, count);
-
-unlock:
-       bakery_lock_release(&pm_secure_lock);
-
-       return ret;
-}
-
-void pm_ipi_irq_enable(const struct pm_proc *proc)
-{
-       ipi_mb_enable_irq(proc->ipi->apu_ipi_id, proc->ipi->pmu_ipi_id);
-}
-
-void pm_ipi_irq_clear(const struct pm_proc *proc)
-{
-       ipi_mb_ack(proc->ipi->apu_ipi_id, proc->ipi->pmu_ipi_id);
-}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_ipi.h b/plat/xilinx/zynqmp/pm_service/pm_ipi.h
deleted file mode 100644 (file)
index 650de52..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PM_IPI_H
-#define PM_IPI_H
-
-#include "pm_common.h"
-
-int pm_ipi_init(const struct pm_proc *proc);
-
-enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
-                              uint32_t payload[PAYLOAD_ARG_CNT]);
-enum pm_ret_status pm_ipi_send_non_blocking(const struct pm_proc *proc,
-                                           uint32_t payload[PAYLOAD_ARG_CNT]);
-enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
-                                   uint32_t payload[PAYLOAD_ARG_CNT],
-                                   unsigned int *value, size_t count);
-void pm_ipi_buff_read_callb(unsigned int *value, size_t count);
-void pm_ipi_irq_enable(const struct pm_proc *proc);
-void pm_ipi_irq_clear(const struct pm_proc *proc);
-
-#endif /* PM_IPI_H */
index 0b8fc23529a5d083d804a29f8ec62ba1412eaf62..faa2827450bb44b2e3abd2b6fcfc6205dffc4e1f 100644 (file)
@@ -20,7 +20,7 @@
 #include <plat/common/platform.h>
 #endif
 
-#include "../zynqmp_private.h"
+#include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_ipi.h"
index 8d23a014c553f4800035d95013e0da44e6851d4d..edb81f5c3b333063c75ff8169d2e06575f1bf54b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,9 +9,9 @@
 #include <common/runtime_svc.h>
 #include <tools_share/uuid.h>
 
+#include <plat_ipi.h>
 #include "ipi_mailbox_svc.h"
 #include "pm_svc_main.h"
-#include "zynqmp_ipi.h"
 
 /* SMC function IDs for SiP Service queries */
 #define ZYNQMP_SIP_SVC_CALL_COUNT      0x8200ff00
@@ -41,6 +41,9 @@ DEFINE_SVC_UUID2(zynqmp_sip_uuid,
  */
 static int32_t sip_svc_setup(void)
 {
+       /* Configure IPI data for ZynqMP */
+       zynqmp_ipi_config_table_init();
+
        /* PM implementation as SiP Service */
        pm_setup();
 
index 25359f91aa4ce55e735848859a17efec41da0c0f..902e4b3b6d09cccb05d844b152cde84a776ef01f 100644 (file)
@@ -7,11 +7,11 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/console.h>
+#include <plat/arm/common/plat_arm.h>
 
-#include <plat_arm.h>
+#include <plat_private.h>
 #include <platform_tsp.h>
 
-#include "../zynqmp_private.h"
 
 #define BL32_END (unsigned long)(&__BL32_END__)
 
diff --git a/plat/xilinx/zynqmp/zynqmp_def.h b/plat/xilinx/zynqmp/zynqmp_def.h
deleted file mode 100644 (file)
index f75530e..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef ZYNQMP_DEF_H
-#define ZYNQMP_DEF_H
-
-#include <plat/common/common_def.h>
-
-#define ZYNQMP_CONSOLE_ID_cadence      1
-#define ZYNQMP_CONSOLE_ID_cadence0     1
-#define ZYNQMP_CONSOLE_ID_cadence1     2
-#define ZYNQMP_CONSOLE_ID_dcc          3
-
-#define ZYNQMP_CONSOLE_IS(con) (ZYNQMP_CONSOLE_ID_ ## con == ZYNQMP_CONSOLE)
-
-/* Firmware Image Package */
-#define ZYNQMP_PRIMARY_CPU             0
-
-/* Memory location options for Shared data and TSP in ZYNQMP */
-#define ZYNQMP_IN_TRUSTED_SRAM         0
-#define ZYNQMP_IN_TRUSTED_DRAM         1
-
-/*******************************************************************************
- * ZYNQMP memory map related constants
- ******************************************************************************/
-/* Aggregate of all devices in the first GB */
-#define DEVICE0_BASE           U(0xFF000000)
-#define DEVICE0_SIZE           U(0x00E00000)
-#define DEVICE1_BASE           U(0xF9000000)
-#define DEVICE1_SIZE           U(0x00800000)
-
-/* For cpu reset APU space here too 0xFE5F1000 CRF_APB*/
-#define CRF_APB_BASE           U(0xFD1A0000)
-#define CRF_APB_SIZE           U(0x00600000)
-#define CRF_APB_CLK_BASE       U(0xFD1A0020)
-
-/* CRF registers and bitfields */
-#define CRF_APB_RST_FPD_APU    (CRF_APB_BASE + 0X00000104)
-
-#define CRF_APB_RST_FPD_APU_ACPU_RESET         (U(1) << 0)
-#define CRF_APB_RST_FPD_APU_ACPU_PWRON_RESET   (U(1) << 10)
-
-/* CRL registers and bitfields */
-#define CRL_APB_BASE                   U(0xFF5E0000)
-#define CRL_APB_BOOT_MODE_USER         (CRL_APB_BASE + 0x200)
-#define CRL_APB_RESET_CTRL             (CRL_APB_BASE + 0x218)
-#define CRL_APB_RST_LPD_TOP            (CRL_APB_BASE + 0x23C)
-#define CRL_APB_BOOT_PIN_CTRL          (CRL_APB_BASE + U(0x250))
-#define CRL_APB_CLK_BASE               U(0xFF5E0020)
-
-#define CRL_APB_RPU_AMBA_RESET         (U(1) << 2)
-#define CRL_APB_RPLL_CTRL_BYPASS       (U(1) << 3)
-
-#define CRL_APB_RESET_CTRL_SOFT_RESET  (U(1) << 4)
-
-#define CRL_APB_BOOT_MODE_MASK         (U(0xf) << 0)
-#define CRL_APB_BOOT_PIN_MASK          (U(0xf0f) << 0)
-#define CRL_APB_BOOT_DRIVE_PIN_1_SHIFT U(9)
-#define CRL_APB_BOOT_ENABLE_PIN_1_SHIFT        U(1)
-#define CRL_APB_BOOT_ENABLE_PIN_1      (U(0x1) << CRL_APB_BOOT_ENABLE_PIN_1_SHIFT)
-#define CRL_APB_BOOT_DRIVE_PIN_1       (U(0x1) << CRL_APB_BOOT_DRIVE_PIN_1_SHIFT)
-#define ZYNQMP_BOOTMODE_JTAG           U(0)
-#define ZYNQMP_ULPI_RESET_VAL_HIGH     (CRL_APB_BOOT_ENABLE_PIN_1 | \
-                                        CRL_APB_BOOT_DRIVE_PIN_1)
-#define ZYNQMP_ULPI_RESET_VAL_LOW      CRL_APB_BOOT_ENABLE_PIN_1
-
-/* system counter registers and bitfields */
-#define IOU_SCNTRS_BASE                        0xFF260000
-#define IOU_SCNTRS_BASEFREQ            (IOU_SCNTRS_BASE + 0x20)
-
-/* APU registers and bitfields */
-#define APU_BASE               0xFD5C0000
-#define APU_CONFIG_0           (APU_BASE + 0x20)
-#define APU_RVBAR_L_0          (APU_BASE + 0x40)
-#define APU_RVBAR_H_0          (APU_BASE + 0x44)
-#define APU_PWRCTL             (APU_BASE + 0x90)
-
-#define APU_CONFIG_0_VINITHI_SHIFT     8
-#define APU_0_PWRCTL_CPUPWRDWNREQ_MASK         1
-#define APU_1_PWRCTL_CPUPWRDWNREQ_MASK         2
-#define APU_2_PWRCTL_CPUPWRDWNREQ_MASK         4
-#define APU_3_PWRCTL_CPUPWRDWNREQ_MASK         8
-
-/* PMU registers and bitfields */
-#define PMU_GLOBAL_BASE                        0xFFD80000
-#define PMU_GLOBAL_CNTRL               (PMU_GLOBAL_BASE + 0)
-#define PMU_GLOBAL_GEN_STORAGE6                (PMU_GLOBAL_BASE + 0x48)
-#define PMU_GLOBAL_REQ_PWRUP_STATUS    (PMU_GLOBAL_BASE + 0x110)
-#define PMU_GLOBAL_REQ_PWRUP_EN                (PMU_GLOBAL_BASE + 0x118)
-#define PMU_GLOBAL_REQ_PWRUP_DIS       (PMU_GLOBAL_BASE + 0x11c)
-#define PMU_GLOBAL_REQ_PWRUP_TRIG      (PMU_GLOBAL_BASE + 0x120)
-
-#define PMU_GLOBAL_CNTRL_FW_IS_PRESENT (1 << 4)
-
-/*******************************************************************************
- * CCI-400 related constants
- ******************************************************************************/
-#define PLAT_ARM_CCI_BASE              0xFD6E0000
-#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX      3
-#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX      4
-
-/*******************************************************************************
- * GIC-400 & interrupt handling related constants
- ******************************************************************************/
-#define BASE_GICD_BASE         0xF9010000
-#define BASE_GICC_BASE         0xF9020000
-#define BASE_GICH_BASE         0xF9040000
-#define BASE_GICV_BASE         0xF9060000
-
-#if ZYNQMP_WDT_RESTART
-#define IRQ_SEC_IPI_APU                67
-#define IRQ_TTC3_1             77
-#define TTC3_BASE_ADDR         0xFF140000
-#define TTC3_INTR_REGISTER_1   (TTC3_BASE_ADDR + 0x54)
-#define TTC3_INTR_ENABLE_1     (TTC3_BASE_ADDR + 0x60)
-#endif
-
-#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 MAX_INTR_EL3                   128
-
-/*******************************************************************************
- * UART related constants
- ******************************************************************************/
-#define ZYNQMP_UART0_BASE              0xFF000000
-#define ZYNQMP_UART1_BASE              0xFF010000
-
-#if ZYNQMP_CONSOLE_IS(cadence)
-# define ZYNQMP_UART_BASE      ZYNQMP_UART0_BASE
-#elif ZYNQMP_CONSOLE_IS(cadence1)
-# define ZYNQMP_UART_BASE      ZYNQMP_UART1_BASE
-#else
-# error "invalid ZYNQMP_CONSOLE"
-#endif
-
-#define ZYNQMP_CRASH_UART_BASE         ZYNQMP_UART_BASE
-/* impossible to call C routine how it is done now - hardcode any value */
-#define ZYNQMP_CRASH_UART_CLK_IN_HZ    100000000 /* FIXME */
-/* Must be non zero */
-#define ZYNQMP_UART_BAUDRATE           115200
-
-/* Silicon version detection */
-#define ZYNQMP_SILICON_VER_MASK                0xF000
-#define ZYNQMP_SILICON_VER_SHIFT       12
-#define ZYNQMP_CSU_VERSION_SILICON     0
-#define ZYNQMP_CSU_VERSION_QEMU                3
-
-#define ZYNQMP_RTL_VER_MASK            0xFF0
-#define ZYNQMP_RTL_VER_SHIFT           4
-
-#define ZYNQMP_PS_VER_MASK             0xF
-#define ZYNQMP_PS_VER_SHIFT            0
-
-#define ZYNQMP_CSU_BASEADDR            0xFFCA0000
-#define ZYNQMP_CSU_IDCODE_OFFSET       0x40
-
-#define ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT      0
-#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK       (0xFFF << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT)
-#define ZYNQMP_CSU_IDCODE_XILINX_ID            0x093
-
-#define ZYNQMP_CSU_IDCODE_SVD_SHIFT            12
-#define ZYNQMP_CSU_IDCODE_SVD_MASK             (0x7 << \
-                                                ZYNQMP_CSU_IDCODE_SVD_SHIFT)
-#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT    15
-#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK     (0xF << ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
-#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT     19
-#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK      (0x3 << ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT)
-#define ZYNQMP_CSU_IDCODE_FAMILY_SHIFT         21
-#define ZYNQMP_CSU_IDCODE_FAMILY_MASK          (0x7F << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT)
-#define ZYNQMP_CSU_IDCODE_FAMILY               0x23
-
-#define ZYNQMP_CSU_IDCODE_REVISION_SHIFT       28
-#define ZYNQMP_CSU_IDCODE_REVISION_MASK                (0xF << ZYNQMP_CSU_IDCODE_REVISION_SHIFT)
-#define ZYNQMP_CSU_IDCODE_REVISION             0
-
-#define ZYNQMP_CSU_VERSION_OFFSET      0x44
-
-/* Efuse */
-#define EFUSE_BASEADDR         0xFFCC0000
-#define EFUSE_IPDISABLE_OFFSET 0x1018
-#define EFUSE_IPDISABLE_VERSION        0x1FFU
-#define ZYNQMP_EFUSE_IPDISABLE_SHIFT   20
-
-/* Access control register defines */
-#define ACTLR_EL3_L2ACTLR_BIT  (1 << 6)
-#define ACTLR_EL3_CPUACTLR_BIT (1 << 0)
-
-#define FPD_SLCR_BASEADDR              U(0xFD610000)
-#define IOU_SLCR_BASEADDR              U(0xFF180000)
-
-#define ZYNQMP_RPU_GLBL_CNTL                   U(0xFF9A0000)
-#define ZYNQMP_RPU0_CFG                                U(0xFF9A0100)
-#define ZYNQMP_RPU1_CFG                                U(0xFF9A0200)
-#define ZYNQMP_SLSPLIT_MASK                    U(0x08)
-#define ZYNQMP_TCM_COMB_MASK                   U(0x40)
-#define ZYNQMP_SLCLAMP_MASK                    U(0x10)
-#define ZYNQMP_VINITHI_MASK                    U(0x04)
-
-/* Tap delay bypass */
-#define IOU_TAPDLY_BYPASS                      U(0XFF180390)
-#define TAP_DELAY_MASK                         U(0x7)
-
-/* SGMII mode */
-#define IOU_GEM_CTRL                           U(0xFF180360)
-#define IOU_GEM_CLK_CTRL                       U(0xFF180308)
-#define SGMII_SD_MASK                          U(0x3)
-#define SGMII_SD_OFFSET                                U(2)
-#define SGMII_PCS_SD_0                         U(0x0)
-#define SGMII_PCS_SD_1                         U(0x1)
-#define SGMII_PCS_SD_PHY                       U(0x2)
-#define GEM_SGMII_MASK                         U(0x4)
-#define GEM_CLK_CTRL_MASK                      U(0xF)
-#define GEM_CLK_CTRL_OFFSET                    U(5)
-#define GEM_RX_SRC_SEL_GTR                     U(0x1)
-#define GEM_SGMII_MODE                         U(0x4)
-
-/* SD DLL reset */
-#define ZYNQMP_SD_DLL_CTRL                     U(0xFF180358)
-#define ZYNQMP_SD0_DLL_RST_MASK                        U(0x00000004)
-#define ZYNQMP_SD0_DLL_RST                     U(0x00000004)
-#define ZYNQMP_SD1_DLL_RST_MASK                        U(0x00040000)
-#define ZYNQMP_SD1_DLL_RST                     U(0x00040000)
-
-/* SD tap delay */
-#define ZYNQMP_SD_DLL_CTRL                     U(0xFF180358)
-#define ZYNQMP_SD_ITAP_DLY                     U(0xFF180314)
-#define ZYNQMP_SD_OTAP_DLY                     U(0xFF180318)
-#define ZYNQMP_SD_TAP_OFFSET                   U(16)
-#define ZYNQMP_SD_ITAPCHGWIN_MASK              U(0x200)
-#define ZYNQMP_SD_ITAPCHGWIN                   U(0x200)
-#define ZYNQMP_SD_ITAPDLYENA_MASK              U(0x100)
-#define ZYNQMP_SD_ITAPDLYENA                   U(0x100)
-#define ZYNQMP_SD_ITAPDLYSEL_MASK              U(0xFF)
-#define ZYNQMP_SD_OTAPDLYSEL_MASK              U(0x3F)
-#define ZYNQMP_SD_OTAPDLYENA_MASK              U(0x40)
-#define ZYNQMP_SD_OTAPDLYENA                   U(0x40)
-
-/* Clock control registers */
-/* Full power domain clocks */
-#define CRF_APB_APLL_CTRL              (CRF_APB_CLK_BASE + 0x00)
-#define CRF_APB_DPLL_CTRL              (CRF_APB_CLK_BASE + 0x0c)
-#define CRF_APB_VPLL_CTRL              (CRF_APB_CLK_BASE + 0x18)
-#define CRF_APB_PLL_STATUS             (CRF_APB_CLK_BASE + 0x24)
-#define CRF_APB_APLL_TO_LPD_CTRL       (CRF_APB_CLK_BASE + 0x28)
-#define CRF_APB_DPLL_TO_LPD_CTRL       (CRF_APB_CLK_BASE + 0x2c)
-#define CRF_APB_VPLL_TO_LPD_CTRL       (CRF_APB_CLK_BASE + 0x30)
-/* Peripheral clocks */
-#define CRF_APB_ACPU_CTRL              (CRF_APB_CLK_BASE + 0x40)
-#define CRF_APB_DBG_TRACE_CTRL         (CRF_APB_CLK_BASE + 0x44)
-#define CRF_APB_DBG_FPD_CTRL           (CRF_APB_CLK_BASE + 0x48)
-#define CRF_APB_DP_VIDEO_REF_CTRL      (CRF_APB_CLK_BASE + 0x50)
-#define CRF_APB_DP_AUDIO_REF_CTRL      (CRF_APB_CLK_BASE + 0x54)
-#define CRF_APB_DP_STC_REF_CTRL                (CRF_APB_CLK_BASE + 0x5c)
-#define CRF_APB_DDR_CTRL               (CRF_APB_CLK_BASE + 0x60)
-#define CRF_APB_GPU_REF_CTRL           (CRF_APB_CLK_BASE + 0x64)
-#define CRF_APB_SATA_REF_CTRL          (CRF_APB_CLK_BASE + 0x80)
-#define CRF_APB_PCIE_REF_CTRL          (CRF_APB_CLK_BASE + 0x94)
-#define CRF_APB_GDMA_REF_CTRL          (CRF_APB_CLK_BASE + 0x98)
-#define CRF_APB_DPDMA_REF_CTRL         (CRF_APB_CLK_BASE + 0x9c)
-#define CRF_APB_TOPSW_MAIN_CTRL                (CRF_APB_CLK_BASE + 0xa0)
-#define CRF_APB_TOPSW_LSBUS_CTRL       (CRF_APB_CLK_BASE + 0xa4)
-#define CRF_APB_GTGREF0_REF_CTRL       (CRF_APB_CLK_BASE + 0xa8)
-#define CRF_APB_DBG_TSTMP_CTRL         (CRF_APB_CLK_BASE + 0xd8)
-
-/* Low power domain clocks */
-#define CRL_APB_IOPLL_CTRL             (CRL_APB_CLK_BASE + 0x00)
-#define CRL_APB_RPLL_CTRL              (CRL_APB_CLK_BASE + 0x10)
-#define CRL_APB_PLL_STATUS             (CRL_APB_CLK_BASE + 0x20)
-#define CRL_APB_IOPLL_TO_FPD_CTRL      (CRL_APB_CLK_BASE + 0x24)
-#define CRL_APB_RPLL_TO_FPD_CTRL       (CRL_APB_CLK_BASE + 0x28)
-/* Peripheral clocks */
-#define CRL_APB_USB3_DUAL_REF_CTRL     (CRL_APB_CLK_BASE + 0x2c)
-#define CRL_APB_GEM0_REF_CTRL          (CRL_APB_CLK_BASE + 0x30)
-#define CRL_APB_GEM1_REF_CTRL          (CRL_APB_CLK_BASE + 0x34)
-#define CRL_APB_GEM2_REF_CTRL          (CRL_APB_CLK_BASE + 0x38)
-#define CRL_APB_GEM3_REF_CTRL          (CRL_APB_CLK_BASE + 0x3c)
-#define CRL_APB_USB0_BUS_REF_CTRL      (CRL_APB_CLK_BASE + 0x40)
-#define CRL_APB_USB1_BUS_REF_CTRL      (CRL_APB_CLK_BASE + 0x44)
-#define CRL_APB_QSPI_REF_CTRL          (CRL_APB_CLK_BASE + 0x48)
-#define CRL_APB_SDIO0_REF_CTRL         (CRL_APB_CLK_BASE + 0x4c)
-#define CRL_APB_SDIO1_REF_CTRL         (CRL_APB_CLK_BASE + 0x50)
-#define CRL_APB_UART0_REF_CTRL         (CRL_APB_CLK_BASE + 0x54)
-#define CRL_APB_UART1_REF_CTRL         (CRL_APB_CLK_BASE + 0x58)
-#define CRL_APB_SPI0_REF_CTRL          (CRL_APB_CLK_BASE + 0x5c)
-#define CRL_APB_SPI1_REF_CTRL          (CRL_APB_CLK_BASE + 0x60)
-#define CRL_APB_CAN0_REF_CTRL          (CRL_APB_CLK_BASE + 0x64)
-#define CRL_APB_CAN1_REF_CTRL          (CRL_APB_CLK_BASE + 0x68)
-#define CRL_APB_CPU_R5_CTRL            (CRL_APB_CLK_BASE + 0x70)
-#define CRL_APB_IOU_SWITCH_CTRL                (CRL_APB_CLK_BASE + 0x7c)
-#define CRL_APB_CSU_PLL_CTRL           (CRL_APB_CLK_BASE + 0x80)
-#define CRL_APB_PCAP_CTRL              (CRL_APB_CLK_BASE + 0x84)
-#define CRL_APB_LPD_SWITCH_CTRL                (CRL_APB_CLK_BASE + 0x88)
-#define CRL_APB_LPD_LSBUS_CTRL         (CRL_APB_CLK_BASE + 0x8c)
-#define CRL_APB_DBG_LPD_CTRL           (CRL_APB_CLK_BASE + 0x90)
-#define CRL_APB_NAND_REF_CTRL          (CRL_APB_CLK_BASE + 0x94)
-#define CRL_APB_ADMA_REF_CTRL          (CRL_APB_CLK_BASE + 0x98)
-#define CRL_APB_PL0_REF_CTRL           (CRL_APB_CLK_BASE + 0xa0)
-#define CRL_APB_PL1_REF_CTRL           (CRL_APB_CLK_BASE + 0xa4)
-#define CRL_APB_PL2_REF_CTRL           (CRL_APB_CLK_BASE + 0xa8)
-#define CRL_APB_PL3_REF_CTRL           (CRL_APB_CLK_BASE + 0xac)
-#define CRL_APB_PL0_THR_CNT            (CRL_APB_CLK_BASE + 0xb4)
-#define CRL_APB_PL1_THR_CNT            (CRL_APB_CLK_BASE + 0xbc)
-#define CRL_APB_PL2_THR_CNT            (CRL_APB_CLK_BASE + 0xc4)
-#define CRL_APB_PL3_THR_CNT            (CRL_APB_CLK_BASE + 0xdc)
-#define CRL_APB_GEM_TSU_REF_CTRL       (CRL_APB_CLK_BASE + 0xe0)
-#define CRL_APB_DLL_REF_CTRL           (CRL_APB_CLK_BASE + 0xe4)
-#define CRL_APB_AMS_REF_CTRL           (CRL_APB_CLK_BASE + 0xe8)
-#define CRL_APB_I2C0_REF_CTRL          (CRL_APB_CLK_BASE + 0x100)
-#define CRL_APB_I2C1_REF_CTRL          (CRL_APB_CLK_BASE + 0x104)
-#define CRL_APB_TIMESTAMP_REF_CTRL     (CRL_APB_CLK_BASE + 0x108)
-#define IOU_SLCR_GEM_CLK_CTRL          (IOU_SLCR_BASEADDR + 0x308)
-#define IOU_SLCR_CAN_MIO_CTRL          (IOU_SLCR_BASEADDR + 0x304)
-#define FPD_SLCR_WDT_CLK_SEL           (FPD_SLCR_BASEADDR + 0x100)
-
-/* Global general storage register base address */
-#define GGS_BASEADDR           (0xFFD80030U)
-#define GGS_NUM_REGS           U(4)
-
-/* Persistent global general storage register base address */
-#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))
-#define PM_BOOT_HEALTH_STATUS_MASK             U(0x01)
-
-/*AFI registers */
-#define  AFIFM6_WRCTRL         U(13)
-#define  FABRIC_WIDTH          U(3)
-
-#endif /* ZYNQMP_DEF_H */
index 54b18380def0158e03c6a416cd1a3a711caa1681..f57369fc3a70c499a6c256e405d54c6a8bd55603 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
 
-#include "zynqmp_ipi.h"
-#include "../zynqmp_private.h"
-
-/*********************************************************************
- * Macros definitions
- ********************************************************************/
-
-/* IPI registers base address */
-#define IPI_REGS_BASE   0xFF300000U
-
-/* IPI registers offsets macros */
-#define IPI_TRIG_OFFSET 0x00U
-#define IPI_OBR_OFFSET  0x04U
-#define IPI_ISR_OFFSET  0x10U
-#define IPI_IMR_OFFSET  0x14U
-#define IPI_IER_OFFSET  0x18U
-#define IPI_IDR_OFFSET  0x1CU
-
-/* IPI register start offset */
-#define IPI_REG_BASE(I) (zynqmp_ipi_table[(I)].ipi_reg_base)
-
-/* IPI register bit mask */
-#define IPI_BIT_MASK(I) (zynqmp_ipi_table[(I)].ipi_bit_mask)
-
-/* IPI secure check */
-#define IPI_SECURE_MASK  0x1U
-#define IPI_IS_SECURE(I) ((zynqmp_ipi_table[(I)].secure_only & \
-                          IPI_SECURE_MASK) ? 1 : 0)
-
-/*********************************************************************
- * Struct definitions
- ********************************************************************/
-
-/* structure to maintain IPI configuration information */
-struct zynqmp_ipi_config {
-       unsigned int ipi_bit_mask;
-       unsigned int ipi_reg_base;
-       unsigned char secure_only;
-};
+#include <ipi.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
 
 /* Zynqmp ipi configuration table */
-const static struct zynqmp_ipi_config zynqmp_ipi_table[] = {
+const static struct ipi_config zynqmp_ipi_table[] = {
        /* APU IPI */
        {
                .ipi_bit_mask = 0x1,
@@ -126,160 +90,11 @@ const static struct zynqmp_ipi_config zynqmp_ipi_table[] = {
        },
 };
 
-/* is_ipi_mb_within_range() - verify if IPI mailbox is within range
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
- *
- * return - 1 if within range, 0 if not
- */
-static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
-{
-       int ret = 1;
-       uint32_t ipi_total = ARRAY_SIZE(zynqmp_ipi_table);
-
-       if (remote >= ipi_total || local >= ipi_total)
-               ret = 0;
-
-       return ret;
-}
-
-/**
- * ipi_mb_validate() - validate IPI mailbox access
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
- * @is_secure - indicate if the requester is from secure software
- *
- * return - 0 success, negative value for errors
- */
-int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
-{
-       int ret = 0;
-
-       if (!is_ipi_mb_within_range(local, remote))
-               ret = -EINVAL;
-       else if (IPI_IS_SECURE(local) && !is_secure)
-               ret = -EPERM;
-       else if (IPI_IS_SECURE(remote) && !is_secure)
-               ret = -EPERM;
-
-       return ret;
-}
-
-/**
- * ipi_mb_open() - Open IPI mailbox.
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
- *
- */
-void ipi_mb_open(uint32_t local, uint32_t remote)
-{
-       mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
-                     IPI_BIT_MASK(remote));
-       mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
-                     IPI_BIT_MASK(remote));
-}
-
-/**
- * ipi_mb_release() - Open IPI mailbox.
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
- *
- */
-void ipi_mb_release(uint32_t local, uint32_t remote)
-{
-       mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
-                     IPI_BIT_MASK(remote));
-}
-
 /**
- * ipi_mb_enquire_status() - Enquire IPI mailbox status
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
- *
- * return - 0 idle, positive value for pending sending or receiving,
- *          negative value for errors
- */
-int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
-{
-       int ret = 0;
-       uint32_t status;
-
-       status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
-       if (status & IPI_BIT_MASK(remote))
-               ret |= IPI_MB_STATUS_SEND_PENDING;
-       status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
-       if (status & IPI_BIT_MASK(remote))
-               ret |= IPI_MB_STATUS_RECV_PENDING;
-
-       return ret;
-}
-
-/* ipi_mb_notify() - Trigger IPI mailbox notification
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
- * @is_blocking - if to trigger the notification in blocking mode or not.
- *
- * It sets the remote bit in the IPI agent trigger register.
- *
- */
-void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
-{
-       uint32_t status;
-
-       mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
-                     IPI_BIT_MASK(remote));
-       if (is_blocking) {
-               do {
-                       status = mmio_read_32(IPI_REG_BASE(local) +
-                                             IPI_OBR_OFFSET);
-               } while (status & IPI_BIT_MASK(remote));
-       }
-}
-
-/* ipi_mb_ack() - Ack IPI mailbox notification from the other end
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
- *
- * It will clear the remote bit in the isr register.
- *
- */
-void ipi_mb_ack(uint32_t local, uint32_t remote)
-{
-       mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
-                     IPI_BIT_MASK(remote));
-}
-
-/* ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
- *
- * It will mask the remote bit in the idr register.
- *
- */
-void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
-{
-       mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
-                     IPI_BIT_MASK(remote));
-}
-
-/* ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
- *
- * It will mask the remote bit in the idr register.
+ * zynqmp_ipi_config_table_init() - Initialize ZynqMP IPI configuration data
  *
  */
-void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
+void zynqmp_ipi_config_table_init(void)
 {
-       mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET,
-                     IPI_BIT_MASK(remote));
+       ipi_config_table_init(zynqmp_ipi_table, ARRAY_SIZE(zynqmp_ipi_table));
 }
diff --git a/plat/xilinx/zynqmp/zynqmp_ipi.h b/plat/xilinx/zynqmp/zynqmp_ipi.h
deleted file mode 100644 (file)
index b9b40dd..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/* ZynqMP IPI management enums and defines */
-
-#ifndef ZYNQMP_IPI_H
-#define ZYNQMP_IPI_H
-
-#include <stdint.h>
-
-/*********************************************************************
- * IPI agent IDs macros
- ********************************************************************/
-#define IPI_ID_APU     0U
-#define IPI_ID_RPU0    1U
-#define IPI_ID_RPU1    2U
-#define IPI_ID_PMU0    3U
-#define IPI_ID_PMU1    4U
-#define IPI_ID_PMU2    5U
-#define IPI_ID_PMU3    6U
-#define IPI_ID_PL0     7U
-#define IPI_ID_PL1     8U
-#define IPI_ID_PL2     9U
-#define IPI_ID_PL3     10U
-
-/*********************************************************************
- * IPI mailbox status macros
- ********************************************************************/
-#define IPI_MB_STATUS_IDLE             0
-#define IPI_MB_STATUS_SEND_PENDING     1
-#define IPI_MB_STATUS_RECV_PENDING     2
-
-/*********************************************************************
- * IPI mailbox call is secure or not macros
- ********************************************************************/
-#define IPI_MB_CALL_NOTSECURE  0
-#define IPI_MB_CALL_SECURE     1
-
-/*********************************************************************
- * IPI APIs declarations
- ********************************************************************/
-
-/* Validate IPI mailbox access */
-int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure);
-
-/* Open the IPI mailbox */
-void ipi_mb_open(uint32_t local, uint32_t remote);
-
-/* Release the IPI mailbox */
-void ipi_mb_release(uint32_t local, uint32_t remote);
-
-/* Enquire IPI mailbox status */
-int ipi_mb_enquire_status(uint32_t local, uint32_t remote);
-
-/* Trigger notification on the IPI mailbox */
-void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking);
-
-/* Ack IPI mailbox notification */
-void ipi_mb_ack(uint32_t local, uint32_t remote);
-
-/* Disable IPI mailbox notification interrupt */
-void ipi_mb_disable_irq(uint32_t local, uint32_t remote);
-
-/* Enable IPI mailbox notification interrupt */
-void ipi_mb_enable_irq(uint32_t local, uint32_t remote);
-
-#endif /* ZYNQMP_IPI_H */
diff --git a/plat/xilinx/zynqmp/zynqmp_private.h b/plat/xilinx/zynqmp/zynqmp_private.h
deleted file mode 100644 (file)
index a8ebceb..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef ZYNQMP_PRIVATE_H
-#define ZYNQMP_PRIVATE_H
-
-#include <stdint.h>
-
-#include <bl31/interrupt_mgmt.h>
-#include <common/bl_common.h>
-
-void zynqmp_config_setup(void);
-
-unsigned int zynqmp_calc_core_pos(u_register_t mpidr);
-
-/* ZynqMP specific functions */
-unsigned int zynqmp_get_uart_clk(void);
-unsigned int zynqmp_get_bootmode(void);
-
-/* For FSBL handover */
-enum fsbl_handoff {
-       FSBL_HANDOFF_SUCCESS = 0,
-       FSBL_HANDOFF_NO_STRUCT,
-       FSBL_HANDOFF_INVAL_STRUCT,
-       FSBL_HANDOFF_TOO_MANY_PARTS,
-};
-
-#if ZYNQMP_WDT_RESTART
-/*
- * Register handler to specific GIC entrance
- * for INTR_TYPE_EL3 type of interrupt
- */
-int request_intr_type_el3(uint32_t, interrupt_type_handler_t);
-#endif
-
-enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32_image_ep_info,
-                      entry_point_info_t *bl33_image_ep_info);
-
-#endif /* ZYNQMP_PRIVATE_H */
index e7fbfb4304809745cd6d26fb878be5fa54927c4d..5404e741bb4f2368e9e7ab24ad30ed494047b243 100644 (file)
@@ -9,7 +9,7 @@ such as:
 -  The `Power State Coordination Interface (PSCI)`_
 -  Trusted Board Boot Requirements (TBBR, Arm DEN0006C-1)
 -  `SMC Calling Convention`_
--  `System Control and Management Interface`_
+-  `System Control and Management Interface (SCMI)`_
 -  `Software Delegated Exception Interface (SDEI)`_
 
 Where possible, the code is designed for reuse or porting to other Armv7-A and
@@ -58,7 +58,7 @@ This release
 
 This release provides a suitable starting point for productization of secure
 world boot and runtime firmware, in either the AArch32 or AArch64 execution
-state.
+states.
 
 Users are encouraged to do their own security validation, including penetration
 testing, on any secure world code derived from TF-A.
@@ -95,13 +95,13 @@ Functionality
 -  Secure Monitor library code such as world switching, EL1 context management
    and interrupt routing.
    When a Secure-EL1 Payload (SP) is present, for example a Secure OS, the
-   AArch64 EL3 Runtime Software must be integrated with a dispatcher component
-   (SPD) to customize the interaction with the SP.
+   AArch64 EL3 Runtime Software must be integrated with a Secure Payload
+   Dispatcher (SPD) component to customize the interaction with the SP.
 
--  A Test SP/SPD to demonstrate AArch64 Secure Monitor functionality and SP
+-  A Test SP and SPD to demonstrate AArch64 Secure Monitor functionality and SP
    interaction with PSCI.
 
--  SPDs for the `OP-TEE Secure OS`_, `NVidia Trusted Little Kernel`_
+-  SPDs for the `OP-TEE Secure OS`_, `NVIDIA Trusted Little Kernel`_
    and `Trusty Secure OS`_.
 
 -  A Trusted Board Boot implementation, conforming to all mandatory TBBR
@@ -136,8 +136,8 @@ Functionality
 
 -  Support for the GCC, LLVM and Arm Compiler 6 toolchains.
 
--  Support combining several libraries into a self-called "romlib" image, that
-   may be shared across images to reduce memory footprint. The romlib image
+-  Support for combining several libraries into a self-called "romlib" image
+   that may be shared across images to reduce memory footprint. The romlib image
    is stored in ROM but is accessed through a jump-table that may be stored
    in read-write memory, allowing for the library code to be patched.
 
@@ -148,8 +148,8 @@ provides details of changes made since the last release.
 Platforms
 ~~~~~~~~~
 
-Various AArch32 and AArch64 builds of this release has been tested on variants
-r0, r1 and r2 of the `Juno Arm Development Platform`_.
+Various AArch32 and AArch64 builds of this release have been tested on r0, r1
+and r2 variants of the `Juno Arm Development Platform`_.
 
 Various AArch64 builds of this release have been tested on the following Arm
 Fixed Virtual Platforms (`FVP`_) without shifted affinities that do not
@@ -194,19 +194,21 @@ This release also contains the following platform support:
 
 -  Allwinner sun50i_64 and sun50i_h6
 -  Amlogic Meson S905 (GXBB)
--  ARM SGI-575 and SGM-775
+-  Arm SGI-575, SGI Clark.A, SGI Clark.H and SGM-775
+-  Arm NeoVerse N1 System Development Platform
 -  HiKey, HiKey960 and Poplar boards
--  Marvell Armada 8K
+-  Marvell Armada 3700 and 8K
 -  MediaTek MT6795 and MT8173 SoCs
--  NVidia T132, T186 and T210 SoCs
--  NXP QorIQ LS1043A, i.MX8QX, i.MX8QM and i.MX7Solo WaRP7
--  QEMU emulator
--  Raspberry Pi 3 board
+-  NVIDIA T132, T186 and T210 SoCs
+-  NXP QorIQ LS1043A, i.MX8MQ, i.MX8QX, i.MX8QM and i.MX7Solo WaRP7
+-  QEMU
+-  Raspberry Pi 3
+-  R-Car Generation 3
 -  RockChip RK3328, RK3368 and RK3399 SoCs
 -  Socionext UniPhier SoC family and SynQuacer SC2A11 SoCs
 -  STMicroelectronics STM32MP1
 -  Texas Instruments K3 SoCs
--  Xilinx Zynq UltraScale + MPSoC
+-  Xilinx Versal and Zynq UltraScale + MPSoC
 
 Still to come
 ~~~~~~~~~~~~~
@@ -229,10 +231,10 @@ Getting started
 
 Get the TF-A source code from `GitHub`_.
 
-See the `User Guide`_ for instructions on how to install, build and use
-the TF-A with the Arm `FVP`_\ s.
+See the `User Guide`_ for instructions on how to install, build and use TF-A
+with the Arm `FVP`_\ s.
 
-See the `Firmware Design`_ for information on how the TF-A works.
+See the `Firmware Design`_ for information on how TF-A works.
 
 See the `Porting Guide`_ as well for information about how to use this
 software on another Armv7-A or Armv8-A platform.
@@ -260,14 +262,14 @@ Arm licensees may contact Arm directly via their partner managers.
 
 --------------
 
-*Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
 
 .. _Armv7-A and Armv8-A: https://developer.arm.com/products/architecture/a-profile
 .. _Secure Monitor: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php
 .. _Power State Coordination Interface (PSCI): PSCI_
 .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
 .. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
-.. _System Control and Management Interface: SCMI_
+.. _System Control and Management Interface (SCMI): SCMI_
 .. _SCMI: http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf
 .. _Software Delegated Exception Interface (SDEI): SDEI_
 .. _SDEI: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
@@ -276,7 +278,7 @@ Arm licensees may contact Arm directly via their partner managers.
 .. _FVP: https://developer.arm.com/products/system-design/fixed-virtual-platforms
 .. _Linaro Release 18.04: https://community.arm.com/dev-platforms/b/documents/posts/linaro-release-notes-deprecated#LinaroRelease18.04
 .. _OP-TEE Secure OS: https://github.com/OP-TEE/optee_os
-.. _NVidia Trusted Little Kernel: http://nv-tegra.nvidia.com/gitweb/?p=3rdparty/ote_partner/tlk.git;a=summary
+.. _NVIDIA Trusted Little Kernel: http://nv-tegra.nvidia.com/gitweb/?p=3rdparty/ote_partner/tlk.git;a=summary
 .. _Trusty Secure OS: https://source.android.com/security/trusty
 .. _GitHub: https://www.github.com/ARM-software/arm-trusted-firmware
 .. _GitHub issue tracker: https://github.com/ARM-software/tf-issues/issues
index 71b8d714d8459244d9a3b1347141ff74f2ba7af4..ec821bae4eb3e4f5d1dd5d465574ec4366db6592 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #define TEESMC_OPTEED_H
 
 /*
- * This file specify SMC function IDs used when returning from TEE to the
+ * This file specifies SMC function IDs used when returning from TEE to the
  * secure monitor.
  *
  * All SMC Function IDs indicates SMC32 Calling Convention but will carry
  * full 64 bit values in the argument registers if invoked from Aarch64
  * mode. This violates the SMC Calling Convention, but since this
- * convention only coveres API towards Normwal World it's something that
+ * convention only coveres API towards Normal World it's something that
  * only concerns the OP-TEE Dispatcher in ARM Trusted Firmware and OP-TEE
  * OS at Secure EL1.
  */
index ffe3319ec6877756863bbf4fc23bbfe4e244e595..b1a04776cce28de49c7ad3ca8ece7aac07ccf8c2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -341,7 +341,7 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid,
 
                /*
                 * SP has been successfully initialized. Register power
-                * managemnt hooks with PSCI
+                * management hooks with PSCI
                 */
                psci_register_spd_pm_hook(&tlkd_pm_ops);
 
index 742c8c43e930f51d3cb90f8813c57c36ae6af209..9c1c38c74ff7bb7c481aeabd6f0b25f5d8ef0697 100644 (file)
@@ -7,69 +7,68 @@
 #ifndef SMCALL_H
 #define SMCALL_H
 
-#define SMC_NUM_ENTITIES       64
-#define SMC_NUM_ARGS           4
-#define SMC_NUM_PARAMS         (SMC_NUM_ARGS - 1)
+#define SMC_NUM_ENTITIES       64U
+#define SMC_NUM_ARGS           4U
+#define SMC_NUM_PARAMS         (SMC_NUM_ARGS - 1U)
 
-#define SMC_IS_FASTCALL(smc_nr)        ((smc_nr) & 0x80000000)
-#define SMC_IS_SMC64(smc_nr)   ((smc_nr) & 0x40000000)
-#define SMC_ENTITY(smc_nr)     (((smc_nr) & 0x3F000000) >> 24)
-#define SMC_FUNCTION(smc_nr)   ((smc_nr) & 0x0000FFFF)
+#define SMC_IS_FASTCALL(smc_nr)        ((smc_nr) & 0x80000000U)
+#define SMC_IS_SMC64(smc_nr)   ((smc_nr) & 0x40000000U)
+#define SMC_ENTITY(smc_nr)     (((smc_nr) & 0x3F000000U) >> 24U)
+#define SMC_FUNCTION(smc_nr)   ((smc_nr) & 0x0000FFFFU)
 
 #define SMC_NR(entity, fn, fastcall, smc64)                    \
-               (((((unsigned int) (fastcall)) & 0x1) << 31) |  \
-               (((smc64) & 0x1) << 30) |                       \
-               (((entity) & 0x3F) << 24) |                     \
-               ((fn) & 0xFFFF)                                 \
-               )
+               (((((uint32_t)(fastcall)) & 0x1U) << 31U) |     \
+               (((smc64) & 0x1U) << 30U) |                     \
+               (((entity) & 0x3FU) << 24U) |                   \
+               ((fn) & 0xFFFFU))
 
-#define SMC_FASTCALL_NR(entity, fn)    SMC_NR((entity), (fn), 1, 0)
-#define SMC_FASTCALL64_NR(entity, fn)  SMC_NR((entity), (fn), 1, 1)
-#define SMC_YIELDCALL_NR(entity, fn)   SMC_NR((entity), (fn), 0, 0)
-#define SMC_YIELDCALL64_NR(entity, fn) SMC_NR((entity), (fn), 0, 1)
+#define SMC_FASTCALL_NR(entity, fn)    SMC_NR((entity), (fn), 1U, 0U)
+#define SMC_FASTCALL64_NR(entity, fn)  SMC_NR((entity), (fn), 1U, 1U)
+#define SMC_YIELDCALL_NR(entity, fn)   SMC_NR((entity), (fn), 0U, 0U)
+#define SMC_YIELDCALL64_NR(entity, fn) SMC_NR((entity), (fn), 0U, 1U)
 
-#define        SMC_ENTITY_ARCH                 0       /* ARM Architecture calls */
-#define        SMC_ENTITY_CPU                  1       /* CPU Service calls */
-#define        SMC_ENTITY_SIP                  2       /* SIP Service calls */
-#define        SMC_ENTITY_OEM                  3       /* OEM Service calls */
-#define        SMC_ENTITY_STD                  4       /* Standard Service calls */
-#define        SMC_ENTITY_RESERVED             5       /* Reserved for future use */
-#define        SMC_ENTITY_TRUSTED_APP          48      /* Trusted Application calls */
-#define        SMC_ENTITY_TRUSTED_OS           50      /* Trusted OS calls */
-#define SMC_ENTITY_LOGGING              51     /* Used for secure -> nonsecure logging */
-#define        SMC_ENTITY_SECURE_MONITOR       60      /* Trusted OS calls internal to secure monitor */
+#define        SMC_ENTITY_ARCH                 0U      /* ARM Architecture calls */
+#define        SMC_ENTITY_CPU                  1U      /* CPU Service calls */
+#define        SMC_ENTITY_SIP                  2U      /* SIP Service calls */
+#define        SMC_ENTITY_OEM                  3U      /* OEM Service calls */
+#define        SMC_ENTITY_STD                  4U      /* Standard Service calls */
+#define        SMC_ENTITY_RESERVED             5U      /* Reserved for future use */
+#define        SMC_ENTITY_TRUSTED_APP          48U     /* Trusted Application calls */
+#define        SMC_ENTITY_TRUSTED_OS           50U     /* Trusted OS calls */
+#define SMC_ENTITY_LOGGING              51U    /* Used for secure -> nonsecure logging */
+#define        SMC_ENTITY_SECURE_MONITOR       60U     /* Trusted OS calls internal to secure monitor */
 
 /* FC = Fast call, YC = Yielding call */
-#define SMC_YC_RESTART_LAST    SMC_YIELDCALL_NR  (SMC_ENTITY_SECURE_MONITOR, 0)
-#define SMC_YC_NOP             SMC_YIELDCALL_NR  (SMC_ENTITY_SECURE_MONITOR, 1)
+#define SMC_YC_RESTART_LAST    SMC_YIELDCALL_NR  (SMC_ENTITY_SECURE_MONITOR, 0U)
+#define SMC_YC_NOP             SMC_YIELDCALL_NR  (SMC_ENTITY_SECURE_MONITOR, 1U)
 
 /*
  * Return from secure os to non-secure os with return value in r1
  */
-#define SMC_YC_NS_RETURN       SMC_YIELDCALL_NR  (SMC_ENTITY_SECURE_MONITOR, 0)
+#define SMC_YC_NS_RETURN       SMC_YIELDCALL_NR  (SMC_ENTITY_SECURE_MONITOR, 0U)
 
-#define SMC_FC_RESERVED                SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0)
-#define SMC_FC_FIQ_EXIT                SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1)
-#define SMC_FC_REQUEST_FIQ     SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 2)
-#define SMC_FC_GET_NEXT_IRQ    SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 3)
-#define SMC_FC_FIQ_ENTER       SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 4)
+#define SMC_FC_RESERVED                SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0U)
+#define SMC_FC_FIQ_EXIT                SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1U)
+#define SMC_FC_REQUEST_FIQ     SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 2U)
+#define SMC_FC_GET_NEXT_IRQ    SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 3U)
+#define SMC_FC_FIQ_ENTER       SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 4U)
 
-#define SMC_FC64_SET_FIQ_HANDLER SMC_FASTCALL64_NR(SMC_ENTITY_SECURE_MONITOR, 5)
-#define SMC_FC64_GET_FIQ_REGS  SMC_FASTCALL64_NR (SMC_ENTITY_SECURE_MONITOR, 6)
+#define SMC_FC64_SET_FIQ_HANDLER SMC_FASTCALL64_NR(SMC_ENTITY_SECURE_MONITOR, 5U)
+#define SMC_FC64_GET_FIQ_REGS  SMC_FASTCALL64_NR (SMC_ENTITY_SECURE_MONITOR, 6U)
 
-#define SMC_FC_CPU_SUSPEND     SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 7)
-#define SMC_FC_CPU_RESUME      SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 8)
+#define SMC_FC_CPU_SUSPEND     SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 7U)
+#define SMC_FC_CPU_RESUME      SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 8U)
 
-#define SMC_FC_AARCH_SWITCH    SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 9)
-#define SMC_FC_GET_VERSION_STR SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 10)
+#define SMC_FC_AARCH_SWITCH    SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 9U)
+#define SMC_FC_GET_VERSION_STR SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 10U)
 
 /* Trusted OS entity calls */
-#define SMC_YC_VIRTIO_GET_DESCR          SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 20)
-#define SMC_YC_VIRTIO_START      SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 21)
-#define SMC_YC_VIRTIO_STOP       SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 22)
+#define SMC_YC_VIRTIO_GET_DESCR          SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 20U)
+#define SMC_YC_VIRTIO_START      SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 21U)
+#define SMC_YC_VIRTIO_STOP       SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 22U)
 
-#define SMC_YC_VDEV_RESET        SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 23)
-#define SMC_YC_VDEV_KICK_VQ      SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 24)
-#define SMC_YC_SET_ROT_PARAMS    SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 65535)
+#define SMC_YC_VDEV_RESET        SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 23U)
+#define SMC_YC_VDEV_KICK_VQ      SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 24U)
+#define SMC_YC_SET_ROT_PARAMS    SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 65535U)
 
 #endif /* SMCALL_H */
index b6ebeeba4e8828d6d9785beffb4023450d2caf5f..83c14b499683ea4db87b8628f8034709ef1fbc54 100644 (file)
@@ -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
  */
 #include "smcall.h"
 
 /* macro to check if Hypervisor is enabled in the HCR_EL2 register */
-#define HYP_ENABLE_FLAG                0x286001
+#define HYP_ENABLE_FLAG                0x286001U
+
+/* length of Trusty's input parameters (in bytes) */
+#define TRUSTY_PARAMS_LEN_BYTES        (4096U * 2)
 
 struct trusty_stack {
        uint8_t space[PLATFORM_STACK_SIZE] __aligned(16);
@@ -32,7 +35,7 @@ struct trusty_cpu_ctx {
        cpu_context_t   cpu_ctx;
        void            *saved_sp;
        uint32_t        saved_security_state;
-       int             fiq_handler_active;
+       int32_t         fiq_handler_active;
        uint64_t        fiq_handler_pc;
        uint64_t        fiq_handler_cpsr;
        uint64_t        fiq_handler_sp;
@@ -43,7 +46,7 @@ struct trusty_cpu_ctx {
        struct trusty_stack     secure_stack;
 };
 
-struct args {
+struct smc_args {
        uint64_t        r0;
        uint64_t        r1;
        uint64_t        r2;
@@ -56,8 +59,8 @@ struct args {
 
 static struct trusty_cpu_ctx trusty_cpu_ctx[PLATFORM_CORE_COUNT];
 
-struct args trusty_init_context_stack(void **sp, void *new_stack);
-struct args trusty_context_switch_helper(void **sp, void *smc_params);
+struct smc_args trusty_init_context_stack(void **sp, void *new_stack);
+struct smc_args trusty_context_switch_helper(void **sp, void *smc_params);
 
 static uint32_t current_vmid;
 
@@ -66,41 +69,41 @@ static struct trusty_cpu_ctx *get_trusty_ctx(void)
        return &trusty_cpu_ctx[plat_my_core_pos()];
 }
 
-static uint32_t is_hypervisor_mode(void)
+static bool is_hypervisor_mode(void)
 {
        uint64_t hcr = read_hcr();
 
-       return !!(hcr & HYP_ENABLE_FLAG);
+       return ((hcr & HYP_ENABLE_FLAG) != 0U) ? true : false;
 }
 
-static struct args trusty_context_switch(uint32_t security_state, uint64_t r0,
+static struct smc_args trusty_context_switch(uint32_t security_state, uint64_t r0,
                                         uint64_t r1, uint64_t r2, uint64_t r3)
 {
-       struct args ret;
+       struct smc_args args, ret_args;
        struct trusty_cpu_ctx *ctx = get_trusty_ctx();
        struct trusty_cpu_ctx *ctx_smc;
 
        assert(ctx->saved_security_state != security_state);
 
-       ret.r7 = 0;
+       args.r7 = 0;
        if (is_hypervisor_mode()) {
                /* According to the ARM DEN0028A spec, VMID is stored in x7 */
                ctx_smc = cm_get_context(NON_SECURE);
-               assert(ctx_smc);
-               ret.r7 = SMC_GET_GP(ctx_smc, CTX_GPREG_X7);
+               assert(ctx_smc != NULL);
+               args.r7 = SMC_GET_GP(ctx_smc, CTX_GPREG_X7);
        }
        /* r4, r5, r6 reserved for future use. */
-       ret.r6 = 0;
-       ret.r5 = 0;
-       ret.r4 = 0;
-       ret.r3 = r3;
-       ret.r2 = r2;
-       ret.r1 = r1;
-       ret.r0 = r0;
+       args.r6 = 0;
+       args.r5 = 0;
+       args.r4 = 0;
+       args.r3 = r3;
+       args.r2 = r2;
+       args.r1 = r1;
+       args.r0 = r0;
 
        /*
         * To avoid the additional overhead in PSCI flow, skip FP context
-        * saving/restoring in case of CPU suspend and resume, asssuming that
+        * saving/restoring in case of CPU suspend and resume, assuming that
         * when it's needed the PSCI caller has preserved FP context before
         * going here.
         */
@@ -109,9 +112,9 @@ static struct args trusty_context_switch(uint32_t security_state, uint64_t r0,
        cm_el1_sysregs_context_save(security_state);
 
        ctx->saved_security_state = security_state;
-       ret = trusty_context_switch_helper(&ctx->saved_sp, &ret);
+       ret_args = trusty_context_switch_helper(&ctx->saved_sp, &args);
 
-       assert(ctx->saved_security_state == !security_state);
+       assert(ctx->saved_security_state == ((security_state == 0U) ? 1U : 0U));
 
        cm_el1_sysregs_context_restore(security_state);
        if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME)
@@ -119,7 +122,7 @@ static struct args trusty_context_switch(uint32_t security_state, uint64_t r0,
 
        cm_set_next_eret_context(security_state);
 
-       return ret;
+       return ret_args;
 }
 
 static uint64_t trusty_fiq_handler(uint32_t id,
@@ -127,29 +130,29 @@ static uint64_t trusty_fiq_handler(uint32_t id,
                                   void *handle,
                                   void *cookie)
 {
-       struct args ret;
+       struct smc_args ret;
        struct trusty_cpu_ctx *ctx = get_trusty_ctx();
 
        assert(!is_caller_secure(flags));
 
        ret = trusty_context_switch(NON_SECURE, SMC_FC_FIQ_ENTER, 0, 0, 0);
-       if (ret.r0) {
+       if (ret.r0 != 0U) {
                SMC_RET0(handle);
        }
 
-       if (ctx->fiq_handler_active) {
+       if (ctx->fiq_handler_active != 0) {
                INFO("%s: fiq handler already active\n", __func__);
                SMC_RET0(handle);
        }
 
        ctx->fiq_handler_active = 1;
-       memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs));
+       (void)memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs));
        ctx->fiq_pc = SMC_GET_EL3(handle, CTX_ELR_EL3);
        ctx->fiq_cpsr = SMC_GET_EL3(handle, CTX_SPSR_EL3);
        ctx->fiq_sp_el1 = read_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1);
 
        write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_handler_sp);
-       cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, ctx->fiq_handler_cpsr);
+       cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, (uint32_t)ctx->fiq_handler_cpsr);
 
        SMC_RET0(handle);
 }
@@ -159,9 +162,9 @@ static uint64_t trusty_set_fiq_handler(void *handle, uint64_t cpu,
 {
        struct trusty_cpu_ctx *ctx;
 
-       if (cpu >= PLATFORM_CORE_COUNT) {
+       if (cpu >= (uint64_t)PLATFORM_CORE_COUNT) {
                ERROR("%s: cpu %lld >= %d\n", __func__, cpu, PLATFORM_CORE_COUNT);
-               return SM_ERR_INVALID_PARAMETERS;
+               return (uint64_t)SM_ERR_INVALID_PARAMETERS;
        }
 
        ctx = &trusty_cpu_ctx[cpu];
@@ -182,16 +185,16 @@ static uint64_t trusty_get_fiq_regs(void *handle)
 
 static uint64_t trusty_fiq_exit(void *handle, uint64_t x1, uint64_t x2, uint64_t x3)
 {
-       struct args ret;
+       struct smc_args ret;
        struct trusty_cpu_ctx *ctx = get_trusty_ctx();
 
-       if (!ctx->fiq_handler_active) {
+       if (ctx->fiq_handler_active == 0) {
                NOTICE("%s: fiq handler not active\n", __func__);
-               SMC_RET1(handle, SM_ERR_INVALID_PARAMETERS);
+               SMC_RET1(handle, (uint64_t)SM_ERR_INVALID_PARAMETERS);
        }
 
        ret = trusty_context_switch(NON_SECURE, SMC_FC_FIQ_EXIT, 0, 0, 0);
-       if (ret.r0 != 1) {
+       if (ret.r0 != 1U) {
                INFO("%s(%p) SMC_FC_FIQ_EXIT returned unexpected value, %lld\n",
                       __func__, handle, ret.r0);
        }
@@ -205,10 +208,10 @@ static uint64_t trusty_fiq_exit(void *handle, uint64_t x1, uint64_t x2, uint64_t
         * x1-x4 and x8-x17 need to be restored here because smc_handler64
         * corrupts them (el1 code also restored them).
         */
-       memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs));
+       (void)memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs));
        ctx->fiq_handler_active = 0;
        write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_sp_el1);
-       cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, ctx->fiq_cpsr);
+       cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, (uint32_t)ctx->fiq_cpsr);
 
        SMC_RET0(handle);
 }
@@ -222,8 +225,8 @@ static uintptr_t trusty_smc_handler(uint32_t smc_fid,
                         void *handle,
                         u_register_t flags)
 {
-       struct args ret;
-       uint32_t vmid = 0;
+       struct smc_args ret;
+       uint32_t vmid = 0U;
        entry_point_info_t *ep_info = bl31_plat_get_next_image_ep_info(SECURE);
 
        /*
@@ -231,10 +234,12 @@ static uintptr_t trusty_smc_handler(uint32_t smc_fid,
         * Verified Boot is not even supported and returning success here
         * would not compromise the boot process.
         */
-       if (!ep_info && (smc_fid == SMC_YC_SET_ROT_PARAMS)) {
+       if ((ep_info == NULL) && (smc_fid == SMC_YC_SET_ROT_PARAMS)) {
                SMC_RET1(handle, 0);
-       } else if (!ep_info) {
+       } else if (ep_info == NULL) {
                SMC_RET1(handle, SMC_UNK);
+       } else {
+               ; /* do nothing */
        }
 
        if (is_caller_secure(flags)) {
@@ -279,12 +284,11 @@ static uintptr_t trusty_smc_handler(uint32_t smc_fid,
 
 static int32_t trusty_init(void)
 {
-       void el3_exit(void);
        entry_point_info_t *ep_info;
-       struct args zero_args = {0};
+       struct smc_args zero_args = {0};
        struct trusty_cpu_ctx *ctx = get_trusty_ctx();
        uint32_t cpu = plat_my_core_pos();
-       int reg_width = GET_RW(read_ctx_reg(get_el3state_ctx(&ctx->cpu_ctx),
+       uint64_t reg_width = GET_RW(read_ctx_reg(get_el3state_ctx(&ctx->cpu_ctx),
                               CTX_SPSR_EL3));
 
        /*
@@ -292,7 +296,7 @@ static int32_t trusty_init(void)
         * failure.
         */
        ep_info = bl31_plat_get_next_image_ep_info(SECURE);
-       assert(ep_info);
+       assert(ep_info != NULL);
 
        fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
        cm_el1_sysregs_context_save(NON_SECURE);
@@ -302,9 +306,9 @@ static int32_t trusty_init(void)
 
        /*
         * Adjust secondary cpu entry point for 32 bit images to the
-        * end of exeption vectors
+        * end of exception vectors
         */
-       if ((cpu != 0) && (reg_width == MODE_RW_32)) {
+       if ((cpu != 0U) && (reg_width == MODE_RW_32)) {
                INFO("trusty: cpu %d, adjust entry point to 0x%lx\n",
                     cpu, ep_info->pc + (1U << 5));
                cm_set_elr_el3(SECURE, ep_info->pc + (1U << 5));
@@ -314,10 +318,10 @@ static int32_t trusty_init(void)
        fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
        cm_set_next_eret_context(SECURE);
 
-       ctx->saved_security_state = ~0; /* initial saved state is invalid */
-       trusty_init_context_stack(&ctx->saved_sp, &ctx->secure_stack.end);
+       ctx->saved_security_state = ~0U; /* initial saved state is invalid */
+       (void)trusty_init_context_stack(&ctx->saved_sp, &ctx->secure_stack.end);
 
-       trusty_context_switch_helper(&ctx->saved_sp, &zero_args);
+       (void)trusty_context_switch_helper(&ctx->saved_sp, &zero_args);
 
        cm_el1_sysregs_context_restore(NON_SECURE);
        fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
@@ -328,10 +332,10 @@ static int32_t trusty_init(void)
 
 static void trusty_cpu_suspend(uint32_t off)
 {
-       struct args ret;
+       struct smc_args ret;
 
        ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_SUSPEND, off, 0, 0);
-       if (ret.r0 != 0) {
+       if (ret.r0 != 0U) {
                INFO("%s: cpu %d, SMC_FC_CPU_SUSPEND returned unexpected value, %lld\n",
                     __func__, plat_my_core_pos(), ret.r0);
        }
@@ -339,10 +343,10 @@ static void trusty_cpu_suspend(uint32_t off)
 
 static void trusty_cpu_resume(uint32_t on)
 {
-       struct args ret;
+       struct smc_args ret;
 
        ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_RESUME, on, 0, 0);
-       if (ret.r0 != 0) {
+       if (ret.r0 != 0U) {
                INFO("%s: cpu %d, SMC_FC_CPU_RESUME returned unexpected value, %lld\n",
                     __func__, plat_my_core_pos(), ret.r0);
        }
@@ -359,8 +363,8 @@ static void trusty_cpu_on_finish_handler(u_register_t unused)
 {
        struct trusty_cpu_ctx *ctx = get_trusty_ctx();
 
-       if (!ctx->saved_sp) {
-               trusty_init();
+       if (ctx->saved_sp == NULL) {
+               (void)trusty_init();
        } else {
                trusty_cpu_resume(1);
        }
@@ -398,12 +402,12 @@ static int32_t trusty_setup(void)
        entry_point_info_t *ep_info;
        uint32_t instr;
        uint32_t flags;
-       int ret;
+       int32_t ret;
        bool aarch32 = false;
 
        /* Get trusty's entry point info */
        ep_info = bl31_plat_get_next_image_ep_info(SECURE);
-       if (!ep_info) {
+       if (ep_info == NULL) {
                INFO("Trusty image missing.\n");
                return -1;
        }
@@ -416,7 +420,8 @@ static int32_t trusty_setup(void)
        } else if (instr >> 8 == 0xd53810U || instr >> 16 == 0x9400U) {
                INFO("trusty: Found 64 bit image\n");
        } else {
-               NOTICE("trusty: Found unknown image, 0x%x\n", instr);
+               ERROR("trusty: Found unknown image, 0x%x\n", instr);
+               return -1;
        }
 
        SET_PARAM_HEAD(ep_info, PARAM_EP, VERSION_1, SECURE | EP_ST_ENABLE);
@@ -444,8 +449,9 @@ static int32_t trusty_setup(void)
        ret = register_interrupt_type_handler(INTR_TYPE_S_EL1,
                                              trusty_fiq_handler,
                                              flags);
-       if (ret)
+       if (ret != 0) {
                ERROR("trusty: failed to register fiq handler, ret = %d\n", ret);
+       }
 
        if (aarch32) {
                entry_point_info_t *ns_ep_info;
index d2bd43f765bc5c91ed4998be68a90277e5b3aaeb..f2067244e1ee0ddfafcf959138c32fd61f392f67 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -375,7 +375,7 @@ static uintptr_t tspd_smc_handler(uint32_t smc_fid,
 
                        /*
                         * TSP has been successfully initialized. Register power
-                        * managemnt hooks with PSCI
+                        * management hooks with PSCI
                         */
                        psci_register_spd_pm_hook(&tspd_pm);
 
index b945394dcf3fd03eacb5180bbe597afd1e21ae32..148643129ca6a59c20a0dd9d4ca93cb04e687b8b 100644 (file)
@@ -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
  */
@@ -54,7 +54,7 @@
 /*
  * 'info' parameter to SDEI_EVENT_GET_INFO SMC.
  *
- * Note that the SDEI v1.0 speification mistakenly enumerates the
+ * Note that the SDEI v1.0 specification mistakenly enumerates the
  * SDEI_INFO_EV_SIGNALED as SDEI_INFO_SIGNALED. This will be corrected in a
  * future version.
  */
diff --git a/services/std_svc/spm_deprecated/aarch64/spm_helpers.S b/services/std_svc/spm_deprecated/aarch64/spm_helpers.S
deleted file mode 100644 (file)
index aa35811..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <asm_macros.S>
-#include "../spm_private.h"
-
-       .global spm_secure_partition_enter
-       .global spm_secure_partition_exit
-
-       /* ---------------------------------------------------------------------
-        * This function is called with SP_EL0 as stack. Here we stash our EL3
-        * callee-saved registers on to the stack as a part of saving the C
-        * runtime and enter the secure payload.
-        * 'x0' contains a pointer to the memory where the address of the C
-        *  runtime context is to be saved.
-        * ---------------------------------------------------------------------
-        */
-func spm_secure_partition_enter
-       /* Make space for the registers that we're going to save */
-       mov     x3, sp
-       str     x3, [x0, #0]
-       sub     sp, sp, #SP_C_RT_CTX_SIZE
-
-       /* Save callee-saved registers on to the stack */
-       stp     x19, x20, [sp, #SP_C_RT_CTX_X19]
-       stp     x21, x22, [sp, #SP_C_RT_CTX_X21]
-       stp     x23, x24, [sp, #SP_C_RT_CTX_X23]
-       stp     x25, x26, [sp, #SP_C_RT_CTX_X25]
-       stp     x27, x28, [sp, #SP_C_RT_CTX_X27]
-       stp     x29, x30, [sp, #SP_C_RT_CTX_X29]
-
-       /* ---------------------------------------------------------------------
-        * Everything is setup now. el3_exit() will use the secure context to
-        * restore to the general purpose and EL3 system registers to ERET
-        * into the secure payload.
-        * ---------------------------------------------------------------------
-        */
-       b       el3_exit
-endfunc spm_secure_partition_enter
-
-       /* ---------------------------------------------------------------------
-        * This function is called with 'x0' pointing to a C runtime context
-        * saved in spm_secure_partition_enter().
-        * It restores the saved registers and jumps to that runtime with 'x0'
-        * as the new SP register. This destroys the C runtime context that had
-        * been built on the stack below the saved context by the caller. Later
-        * the second parameter 'x1' is passed as a return value to the caller.
-        * ---------------------------------------------------------------------
-        */
-func spm_secure_partition_exit
-       /* Restore the previous stack */
-       mov     sp, x0
-
-       /* Restore callee-saved registers on to the stack */
-       ldp     x19, x20, [x0, #(SP_C_RT_CTX_X19 - SP_C_RT_CTX_SIZE)]
-       ldp     x21, x22, [x0, #(SP_C_RT_CTX_X21 - SP_C_RT_CTX_SIZE)]
-       ldp     x23, x24, [x0, #(SP_C_RT_CTX_X23 - SP_C_RT_CTX_SIZE)]
-       ldp     x25, x26, [x0, #(SP_C_RT_CTX_X25 - SP_C_RT_CTX_SIZE)]
-       ldp     x27, x28, [x0, #(SP_C_RT_CTX_X27 - SP_C_RT_CTX_SIZE)]
-       ldp     x29, x30, [x0, #(SP_C_RT_CTX_X29 - SP_C_RT_CTX_SIZE)]
-
-       /* ---------------------------------------------------------------------
-        * This should take us back to the instruction after the call to the
-        * last spm_secure_partition_enter().* Place the second parameter to x0
-        * so that the caller will see it as a return value from the original
-        * entry call.
-        * ---------------------------------------------------------------------
-        */
-       mov     x0, x1
-       ret
-endfunc spm_secure_partition_exit
diff --git a/services/std_svc/spm_deprecated/aarch64/spm_shim_exceptions.S b/services/std_svc/spm_deprecated/aarch64/spm_shim_exceptions.S
deleted file mode 100644 (file)
index dab6150..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2017, 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 <context.h>
-
-/* -----------------------------------------------------------------------------
- * Very simple stackless exception handlers used by the spm shim layer.
- * -----------------------------------------------------------------------------
- */
-       .globl  spm_shim_exceptions_ptr
-
-vector_base spm_shim_exceptions_ptr, .spm_shim_exceptions
-
-       /* -----------------------------------------------------
-        * Current EL with SP0 : 0x0 - 0x200
-        * -----------------------------------------------------
-        */
-vector_entry SynchronousExceptionSP0, .spm_shim_exceptions
-       b       .
-end_vector_entry SynchronousExceptionSP0
-
-vector_entry IrqSP0, .spm_shim_exceptions
-       b       .
-end_vector_entry IrqSP0
-
-vector_entry FiqSP0, .spm_shim_exceptions
-       b       .
-end_vector_entry FiqSP0
-
-vector_entry SErrorSP0, .spm_shim_exceptions
-       b       .
-end_vector_entry SErrorSP0
-
-       /* -----------------------------------------------------
-        * Current EL with SPx: 0x200 - 0x400
-        * -----------------------------------------------------
-        */
-vector_entry SynchronousExceptionSPx, .spm_shim_exceptions
-       b       .
-end_vector_entry SynchronousExceptionSPx
-
-vector_entry IrqSPx, .spm_shim_exceptions
-       b       .
-end_vector_entry IrqSPx
-
-vector_entry FiqSPx, .spm_shim_exceptions
-       b       .
-end_vector_entry FiqSPx
-
-vector_entry SErrorSPx, .spm_shim_exceptions
-       b       .
-end_vector_entry SErrorSPx
-
-       /* -----------------------------------------------------
-        * Lower EL using AArch64 : 0x400 - 0x600. No exceptions
-        * are handled since secure_partition does not implement
-        * a lower EL
-        * -----------------------------------------------------
-        */
-vector_entry SynchronousExceptionA64, .spm_shim_exceptions
-       msr     tpidr_el1, x30
-       mrs     x30, esr_el1
-       ubfx    x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
-
-       cmp     x30, #EC_AARCH64_SVC
-       b.eq    do_smc
-
-       cmp     x30, #EC_AARCH32_SVC
-       b.eq    do_smc
-
-       cmp     x30, #EC_AARCH64_SYS
-       b.eq    handle_sys_trap
-
-       /* Fail in all the other cases */
-       b       panic
-
-       /* ---------------------------------------------
-        * Tell SPM that we are done initialising
-        * ---------------------------------------------
-        */
-do_smc:
-       mrs     x30, tpidr_el1
-       smc     #0
-       eret
-
-       /* AArch64 system instructions trap are handled as a panic for now */
-handle_sys_trap:
-panic:
-       b       panic
-end_vector_entry SynchronousExceptionA64
-
-vector_entry IrqA64, .spm_shim_exceptions
-       b       .
-end_vector_entry IrqA64
-
-vector_entry FiqA64, .spm_shim_exceptions
-       b       .
-end_vector_entry FiqA64
-
-vector_entry SErrorA64, .spm_shim_exceptions
-       b       .
-end_vector_entry SErrorA64
-
-       /* -----------------------------------------------------
-        * Lower EL using AArch32 : 0x600 - 0x800
-        * -----------------------------------------------------
-        */
-vector_entry SynchronousExceptionA32, .spm_shim_exceptions
-       b       .
-end_vector_entry SynchronousExceptionA32
-
-vector_entry IrqA32, .spm_shim_exceptions
-       b       .
-end_vector_entry IrqA32
-
-vector_entry FiqA32, .spm_shim_exceptions
-       b       .
-end_vector_entry FiqA32
-
-vector_entry SErrorA32, .spm_shim_exceptions
-       b       .
-end_vector_entry SErrorA32
diff --git a/services/std_svc/spm_deprecated/spm.mk b/services/std_svc/spm_deprecated/spm.mk
deleted file mode 100644 (file)
index ed36812..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-ifneq (${SPD},none)
-        $(error "Error: SPD and SPM are incompatible build options.")
-endif
-ifneq (${ARCH},aarch64)
-        $(error "Error: SPM is only supported on aarch64.")
-endif
-
-SPM_SOURCES    :=      $(addprefix services/std_svc/spm_deprecated/, \
-                       ${ARCH}/spm_helpers.S                   \
-                       ${ARCH}/spm_shim_exceptions.S           \
-                       spm_main.c                              \
-                       spm_setup.c                             \
-                       spm_xlat.c)
-
-
-# Let the top-level Makefile know that we intend to include a BL32 image
-NEED_BL32              :=      yes
diff --git a/services/std_svc/spm_deprecated/spm_main.c b/services/std_svc/spm_deprecated/spm_main.c
deleted file mode 100644 (file)
index 540f257..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch_helpers.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <bl31/bl31.h>
-#include <bl31/ehf.h>
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/smccc.h>
-#include <lib/spinlock.h>
-#include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <plat/common/platform.h>
-#include <services/mm_svc.h>
-#include <services/secure_partition.h>
-#include <services/spm_svc.h>
-#include <smccc_helpers.h>
-
-#include "spm_private.h"
-
-/*******************************************************************************
- * Secure Partition context information.
- ******************************************************************************/
-static sp_context_t sp_ctx;
-
-/*******************************************************************************
- * Set state of a Secure Partition context.
- ******************************************************************************/
-void sp_state_set(sp_context_t *sp_ptr, sp_state_t state)
-{
-       spin_lock(&(sp_ptr->state_lock));
-       sp_ptr->state = state;
-       spin_unlock(&(sp_ptr->state_lock));
-}
-
-/*******************************************************************************
- * Wait until the state of a Secure Partition is the specified one and change it
- * to the desired state.
- ******************************************************************************/
-void sp_state_wait_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to)
-{
-       int success = 0;
-
-       while (success == 0) {
-               spin_lock(&(sp_ptr->state_lock));
-
-               if (sp_ptr->state == from) {
-                       sp_ptr->state = to;
-
-                       success = 1;
-               }
-
-               spin_unlock(&(sp_ptr->state_lock));
-       }
-}
-
-/*******************************************************************************
- * Check if the state of a Secure Partition is the specified one and, if so,
- * change it to the desired state. Returns 0 on success, -1 on error.
- ******************************************************************************/
-int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to)
-{
-       int ret = -1;
-
-       spin_lock(&(sp_ptr->state_lock));
-
-       if (sp_ptr->state == from) {
-               sp_ptr->state = to;
-
-               ret = 0;
-       }
-
-       spin_unlock(&(sp_ptr->state_lock));
-
-       return ret;
-}
-
-/*******************************************************************************
- * This function takes an SP context pointer and performs a synchronous entry
- * into it.
- ******************************************************************************/
-static uint64_t spm_sp_synchronous_entry(sp_context_t *sp_ctx)
-{
-       uint64_t rc;
-
-       assert(sp_ctx != NULL);
-
-       /* Assign the context of the SP to this CPU */
-       cm_set_context(&(sp_ctx->cpu_ctx), SECURE);
-
-       /* Restore the context assigned above */
-       cm_el1_sysregs_context_restore(SECURE);
-       cm_set_next_eret_context(SECURE);
-
-       /* Invalidate TLBs at EL1. */
-       tlbivmalle1();
-       dsbish();
-
-       /* Enter Secure Partition */
-       rc = spm_secure_partition_enter(&sp_ctx->c_rt_ctx);
-
-       /* Save secure state */
-       cm_el1_sysregs_context_save(SECURE);
-
-       return rc;
-}
-
-/*******************************************************************************
- * This function returns to the place where spm_sp_synchronous_entry() was
- * called originally.
- ******************************************************************************/
-__dead2 static void spm_sp_synchronous_exit(uint64_t rc)
-{
-       sp_context_t *ctx = &sp_ctx;
-
-       /*
-        * The SPM must have initiated the original request through a
-        * synchronous entry into the secure partition. Jump back to the
-        * original C runtime context with the value of rc in x0;
-        */
-       spm_secure_partition_exit(ctx->c_rt_ctx, rc);
-
-       panic();
-}
-
-/*******************************************************************************
- * Jump to each Secure Partition for the first time.
- ******************************************************************************/
-static int32_t spm_init(void)
-{
-       uint64_t rc;
-       sp_context_t *ctx;
-
-       INFO("Secure Partition init...\n");
-
-       ctx = &sp_ctx;
-
-       ctx->state = SP_STATE_RESET;
-
-       rc = spm_sp_synchronous_entry(ctx);
-       assert(rc == 0);
-
-       ctx->state = SP_STATE_IDLE;
-
-       INFO("Secure Partition initialized.\n");
-
-       return rc;
-}
-
-/*******************************************************************************
- * Initialize contexts of all Secure Partitions.
- ******************************************************************************/
-int32_t spm_setup(void)
-{
-       sp_context_t *ctx;
-
-       /* Disable MMU at EL1 (initialized by BL2) */
-       disable_mmu_icache_el1();
-
-       /* Initialize context of the SP */
-       INFO("Secure Partition context setup start...\n");
-
-       ctx = &sp_ctx;
-
-       /* Assign translation tables context. */
-       ctx->xlat_ctx_handle = spm_get_sp_xlat_context();
-
-       spm_sp_setup(ctx);
-
-       /* Register init function for deferred init.  */
-       bl31_register_bl32_init(&spm_init);
-
-       INFO("Secure Partition setup done.\n");
-
-       return 0;
-}
-
-/*******************************************************************************
- * Function to perform a call to a Secure Partition.
- ******************************************************************************/
-uint64_t spm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3)
-{
-       uint64_t rc;
-       sp_context_t *sp_ptr = &sp_ctx;
-
-       /* Wait until the Secure Partition is idle and set it to busy. */
-       sp_state_wait_switch(sp_ptr, SP_STATE_IDLE, SP_STATE_BUSY);
-
-       /* Set values for registers on SP entry */
-       cpu_context_t *cpu_ctx = &(sp_ptr->cpu_ctx);
-
-       write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X0, smc_fid);
-       write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X1, x1);
-       write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X2, x2);
-       write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X3, x3);
-
-       /* Jump to the Secure Partition. */
-       rc = spm_sp_synchronous_entry(sp_ptr);
-
-       /* Flag Secure Partition as idle. */
-       assert(sp_ptr->state == SP_STATE_BUSY);
-       sp_state_set(sp_ptr, SP_STATE_IDLE);
-
-       return rc;
-}
-
-/*******************************************************************************
- * MM_COMMUNICATE handler
- ******************************************************************************/
-static uint64_t mm_communicate(uint32_t smc_fid, uint64_t mm_cookie,
-                              uint64_t comm_buffer_address,
-                              uint64_t comm_size_address, void *handle)
-{
-       uint64_t rc;
-
-       /* Cookie. Reserved for future use. It must be zero. */
-       if (mm_cookie != 0U) {
-               ERROR("MM_COMMUNICATE: cookie is not zero\n");
-               SMC_RET1(handle, SPM_INVALID_PARAMETER);
-       }
-
-       if (comm_buffer_address == 0U) {
-               ERROR("MM_COMMUNICATE: comm_buffer_address is zero\n");
-               SMC_RET1(handle, SPM_INVALID_PARAMETER);
-       }
-
-       if (comm_size_address != 0U) {
-               VERBOSE("MM_COMMUNICATE: comm_size_address is not 0 as recommended.\n");
-       }
-
-       /*
-        * The current secure partition design mandates
-        * - at any point, only a single core can be
-        *   executing in the secure partiton.
-        * - a core cannot be preempted by an interrupt
-        *   while executing in secure partition.
-        * Raise the running priority of the core to the
-        * interrupt level configured for secure partition
-        * so as to block any interrupt from preempting this
-        * core.
-        */
-       ehf_activate_priority(PLAT_SP_PRI);
-
-       /* Save the Normal world context */
-       cm_el1_sysregs_context_save(NON_SECURE);
-
-       rc = spm_sp_call(smc_fid, comm_buffer_address, comm_size_address,
-                        plat_my_core_pos());
-
-       /* Restore non-secure state */
-       cm_el1_sysregs_context_restore(NON_SECURE);
-       cm_set_next_eret_context(NON_SECURE);
-
-       /*
-        * Exited from secure partition. This core can take
-        * interrupts now.
-        */
-       ehf_deactivate_priority(PLAT_SP_PRI);
-
-       SMC_RET1(handle, rc);
-}
-
-/*******************************************************************************
- * Secure Partition Manager SMC handler.
- ******************************************************************************/
-uint64_t spm_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)
-{
-       unsigned int ns;
-
-       /* Determine which security state this SMC originated from */
-       ns = is_caller_non_secure(flags);
-
-       if (ns == SMC_FROM_SECURE) {
-
-               /* Handle SMCs from Secure world. */
-
-               assert(handle == cm_get_context(SECURE));
-
-               /* Make next ERET jump to S-EL0 instead of S-EL1. */
-               cm_set_elr_spsr_el3(SECURE, read_elr_el1(), read_spsr_el1());
-
-               switch (smc_fid) {
-
-               case SPM_VERSION_AARCH32:
-                       SMC_RET1(handle, SPM_VERSION_COMPILED);
-
-               case SP_EVENT_COMPLETE_AARCH64:
-                       spm_sp_synchronous_exit(x1);
-
-               case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
-                       INFO("Received SP_MEMORY_ATTRIBUTES_GET_AARCH64 SMC\n");
-
-                       if (sp_ctx.state != SP_STATE_RESET) {
-                               WARN("SP_MEMORY_ATTRIBUTES_GET_AARCH64 is available at boot time only\n");
-                               SMC_RET1(handle, SPM_NOT_SUPPORTED);
-                       }
-                       SMC_RET1(handle,
-                                spm_memory_attributes_get_smc_handler(
-                                        &sp_ctx, x1));
-
-               case SP_MEMORY_ATTRIBUTES_SET_AARCH64:
-                       INFO("Received SP_MEMORY_ATTRIBUTES_SET_AARCH64 SMC\n");
-
-                       if (sp_ctx.state != SP_STATE_RESET) {
-                               WARN("SP_MEMORY_ATTRIBUTES_SET_AARCH64 is available at boot time only\n");
-                               SMC_RET1(handle, SPM_NOT_SUPPORTED);
-                       }
-                       SMC_RET1(handle,
-                                spm_memory_attributes_set_smc_handler(
-                                       &sp_ctx, x1, x2, x3));
-               default:
-                       break;
-               }
-       } else {
-
-               /* Handle SMCs from Non-secure world. */
-
-               assert(handle == cm_get_context(NON_SECURE));
-
-               switch (smc_fid) {
-
-               case MM_VERSION_AARCH32:
-                       SMC_RET1(handle, MM_VERSION_COMPILED);
-
-               case MM_COMMUNICATE_AARCH32:
-               case MM_COMMUNICATE_AARCH64:
-                       return mm_communicate(smc_fid, x1, x2, x3, handle);
-
-               case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
-               case SP_MEMORY_ATTRIBUTES_SET_AARCH64:
-                       /* SMC interfaces reserved for secure callers. */
-                       SMC_RET1(handle, SPM_NOT_SUPPORTED);
-
-               default:
-                       break;
-               }
-       }
-
-       SMC_RET1(handle, SMC_UNK);
-}
diff --git a/services/std_svc/spm_deprecated/spm_private.h b/services/std_svc/spm_deprecated/spm_private.h
deleted file mode 100644 (file)
index 8e94a28..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_PRIVATE_H
-#define SPM_PRIVATE_H
-
-#include <context.h>
-
-/*******************************************************************************
- * Constants that allow assembler code to preserve callee-saved registers of the
- * C runtime context while performing a security state switch.
- ******************************************************************************/
-#define SP_C_RT_CTX_X19                0x0
-#define SP_C_RT_CTX_X20                0x8
-#define SP_C_RT_CTX_X21                0x10
-#define SP_C_RT_CTX_X22                0x18
-#define SP_C_RT_CTX_X23                0x20
-#define SP_C_RT_CTX_X24                0x28
-#define SP_C_RT_CTX_X25                0x30
-#define SP_C_RT_CTX_X26                0x38
-#define SP_C_RT_CTX_X27                0x40
-#define SP_C_RT_CTX_X28                0x48
-#define SP_C_RT_CTX_X29                0x50
-#define SP_C_RT_CTX_X30                0x58
-
-#define SP_C_RT_CTX_SIZE       0x60
-#define SP_C_RT_CTX_ENTRIES    (SP_C_RT_CTX_SIZE >> DWORD_SHIFT)
-
-#ifndef __ASSEMBLY__
-
-#include <stdint.h>
-
-#include <lib/spinlock.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-
-typedef enum sp_state {
-       SP_STATE_RESET = 0,
-       SP_STATE_IDLE,
-       SP_STATE_BUSY
-} sp_state_t;
-
-typedef struct sp_context {
-       uint64_t c_rt_ctx;
-       cpu_context_t cpu_ctx;
-       xlat_ctx_t *xlat_ctx_handle;
-
-       sp_state_t state;
-       spinlock_t state_lock;
-} sp_context_t;
-
-/* Assembly helpers */
-uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx);
-void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret);
-
-void spm_sp_setup(sp_context_t *sp_ctx);
-
-xlat_ctx_t *spm_get_sp_xlat_context(void);
-
-int32_t spm_memory_attributes_get_smc_handler(sp_context_t *sp_ctx,
-                                             uintptr_t base_va);
-int spm_memory_attributes_set_smc_handler(sp_context_t *sp_ctx,
-                                         u_register_t page_address,
-                                         u_register_t pages_count,
-                                         u_register_t smc_attributes);
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* SPM_PRIVATE_H */
diff --git a/services/std_svc/spm_deprecated/spm_setup.c b/services/std_svc/spm_deprecated/spm_setup.c
deleted file mode 100644 (file)
index d458f4a..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <context.h>
-#include <common/debug.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <platform_def.h>
-#include <plat/common/common_def.h>
-#include <plat/common/platform.h>
-#include <services/secure_partition.h>
-
-#include "spm_private.h"
-#include "spm_shim_private.h"
-
-/* Setup context of the Secure Partition */
-void spm_sp_setup(sp_context_t *sp_ctx)
-{
-       cpu_context_t *ctx = &(sp_ctx->cpu_ctx);
-
-       /*
-        * Initialize CPU context
-        * ----------------------
-        */
-
-       entry_point_info_t ep_info = {0};
-
-       SET_PARAM_HEAD(&ep_info, PARAM_EP, VERSION_1, SECURE | EP_ST_ENABLE);
-
-       /* Setup entrypoint and SPSR */
-       ep_info.pc = BL32_BASE;
-       ep_info.spsr = SPSR_64(MODE_EL0, MODE_SP_EL0, DISABLE_ALL_EXCEPTIONS);
-
-       /*
-        * X0: Virtual address of a buffer shared between EL3 and Secure EL0.
-        *     The buffer will be mapped in the Secure EL1 translation regime
-        *     with Normal IS WBWA attributes and RO data and Execute Never
-        *     instruction access permissions.
-        *
-        * X1: Size of the buffer in bytes
-        *
-        * X2: cookie value (Implementation Defined)
-        *
-        * X3: cookie value (Implementation Defined)
-        *
-        * X4 to X7 = 0
-        */
-       ep_info.args.arg0 = PLAT_SPM_BUF_BASE;
-       ep_info.args.arg1 = PLAT_SPM_BUF_SIZE;
-       ep_info.args.arg2 = PLAT_SPM_COOKIE_0;
-       ep_info.args.arg3 = PLAT_SPM_COOKIE_1;
-
-       cm_setup_context(ctx, &ep_info);
-
-       /*
-        * SP_EL0: A non-zero value will indicate to the SP that the SPM has
-        * initialized the stack pointer for the current CPU through
-        * implementation defined means. The value will be 0 otherwise.
-        */
-       write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_SP_EL0,
-                       PLAT_SP_IMAGE_STACK_BASE + PLAT_SP_IMAGE_STACK_PCPU_SIZE);
-
-       /*
-        * Setup translation tables
-        * ------------------------
-        */
-
-#if ENABLE_ASSERTIONS
-
-       /* Get max granularity supported by the platform. */
-       unsigned int max_granule = xlat_arch_get_max_supported_granule_size();
-
-       VERBOSE("Max translation granule size supported: %u KiB\n",
-               max_granule / 1024U);
-
-       unsigned int max_granule_mask = max_granule - 1U;
-
-       /* Base must be aligned to the max granularity */
-       assert((ARM_SP_IMAGE_NS_BUF_BASE & max_granule_mask) == 0);
-
-       /* Size must be a multiple of the max granularity */
-       assert((ARM_SP_IMAGE_NS_BUF_SIZE & max_granule_mask) == 0);
-
-#endif /* ENABLE_ASSERTIONS */
-
-       /* This region contains the exception vectors used at S-EL1. */
-       const mmap_region_t sel1_exception_vectors =
-               MAP_REGION_FLAT(SPM_SHIM_EXCEPTIONS_START,
-                               SPM_SHIM_EXCEPTIONS_SIZE,
-                               MT_CODE | MT_SECURE | MT_PRIVILEGED);
-       mmap_add_region_ctx(sp_ctx->xlat_ctx_handle,
-                           &sel1_exception_vectors);
-
-       mmap_add_ctx(sp_ctx->xlat_ctx_handle,
-                    plat_get_secure_partition_mmap(NULL));
-
-       init_xlat_tables_ctx(sp_ctx->xlat_ctx_handle);
-
-       /*
-        * MMU-related registers
-        * ---------------------
-        */
-       xlat_ctx_t *xlat_ctx = sp_ctx->xlat_ctx_handle;
-
-       uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
-
-       setup_mmu_cfg((uint64_t *)&mmu_cfg_params, 0, xlat_ctx->base_table,
-                     xlat_ctx->pa_max_address, xlat_ctx->va_max_address,
-                     EL1_EL0_REGIME);
-
-       write_ctx_reg(get_sysregs_ctx(ctx), CTX_MAIR_EL1,
-                     mmu_cfg_params[MMU_CFG_MAIR]);
-
-       write_ctx_reg(get_sysregs_ctx(ctx), CTX_TCR_EL1,
-                     mmu_cfg_params[MMU_CFG_TCR]);
-
-       write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR0_EL1,
-                     mmu_cfg_params[MMU_CFG_TTBR0]);
-
-       /* Setup SCTLR_EL1 */
-       u_register_t sctlr_el1 = read_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1);
-
-       sctlr_el1 |=
-               /*SCTLR_EL1_RES1 |*/
-               /* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */
-               SCTLR_UCI_BIT                                                   |
-               /* RW regions at xlat regime EL1&0 are forced to be XN. */
-               SCTLR_WXN_BIT                                                   |
-               /* Don't trap to EL1 execution of WFI or WFE at EL0. */
-               SCTLR_NTWI_BIT | SCTLR_NTWE_BIT                                 |
-               /* Don't trap to EL1 accesses to CTR_EL0 from EL0. */
-               SCTLR_UCT_BIT                                                   |
-               /* Don't trap to EL1 execution of DZ ZVA at EL0. */
-               SCTLR_DZE_BIT                                                   |
-               /* Enable SP Alignment check for EL0 */
-               SCTLR_SA0_BIT                                                   |
-               /* Allow cacheable data and instr. accesses to normal memory. */
-               SCTLR_C_BIT | SCTLR_I_BIT                                       |
-               /* Alignment fault checking enabled when at EL1 and EL0. */
-               SCTLR_A_BIT                                                     |
-               /* Enable MMU. */
-               SCTLR_M_BIT
-       ;
-
-       sctlr_el1 &= ~(
-               /* Explicit data accesses at EL0 are little-endian. */
-               SCTLR_E0E_BIT                                                   |
-               /* Accesses to DAIF from EL0 are trapped to EL1. */
-               SCTLR_UMA_BIT
-       );
-
-       write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1);
-
-       /*
-        * Setup other system registers
-        * ----------------------------
-        */
-
-       /* Shim Exception Vector Base Address */
-       write_ctx_reg(get_sysregs_ctx(ctx), CTX_VBAR_EL1,
-                       SPM_SHIM_EXCEPTIONS_PTR);
-
-       /*
-        * FPEN: Allow the Secure Partition to access FP/SIMD registers.
-        * Note that SPM will not do any saving/restoring of these registers on
-        * behalf of the SP. This falls under the SP's responsibility.
-        * TTA: Enable access to trace registers.
-        * ZEN (v8.2): Trap SVE instructions and access to SVE registers.
-        */
-       write_ctx_reg(get_sysregs_ctx(ctx), CTX_CPACR_EL1,
-                       CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
-
-       /*
-        * Prepare information in buffer shared between EL3 and S-EL0
-        * ----------------------------------------------------------
-        */
-
-       void *shared_buf_ptr = (void *) PLAT_SPM_BUF_BASE;
-
-       /* Copy the boot information into the shared buffer with the SP. */
-       assert((uintptr_t)shared_buf_ptr + sizeof(secure_partition_boot_info_t)
-              <= (PLAT_SPM_BUF_BASE + PLAT_SPM_BUF_SIZE));
-
-       assert(PLAT_SPM_BUF_BASE <= (UINTPTR_MAX - PLAT_SPM_BUF_SIZE + 1));
-
-       const secure_partition_boot_info_t *sp_boot_info =
-                       plat_get_secure_partition_boot_info(NULL);
-
-       assert(sp_boot_info != NULL);
-
-       memcpy((void *) shared_buf_ptr, (const void *) sp_boot_info,
-              sizeof(secure_partition_boot_info_t));
-
-       /* Pointer to the MP information from the platform port. */
-       secure_partition_mp_info_t *sp_mp_info =
-               ((secure_partition_boot_info_t *) shared_buf_ptr)->mp_info;
-
-       assert(sp_mp_info != NULL);
-
-       /*
-        * Point the shared buffer MP information pointer to where the info will
-        * be populated, just after the boot info.
-        */
-       ((secure_partition_boot_info_t *) shared_buf_ptr)->mp_info =
-               (secure_partition_mp_info_t *) ((uintptr_t)shared_buf_ptr
-                               + sizeof(secure_partition_boot_info_t));
-
-       /*
-        * Update the shared buffer pointer to where the MP information for the
-        * payload will be populated
-        */
-       shared_buf_ptr = ((secure_partition_boot_info_t *) shared_buf_ptr)->mp_info;
-
-       /*
-        * Copy the cpu information into the shared buffer area after the boot
-        * information.
-        */
-       assert(sp_boot_info->num_cpus <= PLATFORM_CORE_COUNT);
-
-       assert((uintptr_t)shared_buf_ptr
-              <= (PLAT_SPM_BUF_BASE + PLAT_SPM_BUF_SIZE -
-                      (sp_boot_info->num_cpus * sizeof(*sp_mp_info))));
-
-       memcpy(shared_buf_ptr, (const void *) sp_mp_info,
-               sp_boot_info->num_cpus * sizeof(*sp_mp_info));
-
-       /*
-        * Calculate the linear indices of cores in boot information for the
-        * secure partition and flag the primary CPU
-        */
-       sp_mp_info = (secure_partition_mp_info_t *) shared_buf_ptr;
-
-       for (unsigned int index = 0; index < sp_boot_info->num_cpus; index++) {
-               u_register_t mpidr = sp_mp_info[index].mpidr;
-
-               sp_mp_info[index].linear_id = plat_core_pos_by_mpidr(mpidr);
-               if (plat_my_core_pos() == sp_mp_info[index].linear_id)
-                       sp_mp_info[index].flags |= MP_INFO_FLAG_PRIMARY_CPU;
-       }
-}
diff --git a/services/std_svc/spm_deprecated/spm_shim_private.h b/services/std_svc/spm_deprecated/spm_shim_private.h
deleted file mode 100644 (file)
index 7fe9692..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_SHIM_PRIVATE_H
-#define SPM_SHIM_PRIVATE_H
-
-#include <stdint.h>
-
-#include <lib/utils_def.h>
-
-/* Assembly source */
-IMPORT_SYM(uintptr_t, spm_shim_exceptions_ptr,         SPM_SHIM_EXCEPTIONS_PTR);
-
-/* Linker symbols */
-IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_START__,   SPM_SHIM_EXCEPTIONS_START);
-IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_END__,     SPM_SHIM_EXCEPTIONS_END);
-
-/* Definitions */
-
-#define SPM_SHIM_EXCEPTIONS_SIZE       \
-       (SPM_SHIM_EXCEPTIONS_END - SPM_SHIM_EXCEPTIONS_START)
-
-#endif /* SPM_SHIM_PRIVATE_H */
diff --git a/services/std_svc/spm_deprecated/spm_xlat.c b/services/std_svc/spm_deprecated/spm_xlat.c
deleted file mode 100644 (file)
index f54168e..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <assert.h>
-#include <errno.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <platform_def.h>
-#include <plat/common/platform.h>
-#include <services/secure_partition.h>
-#include <services/spm_svc.h>
-
-#include "spm_private.h"
-#include "spm_shim_private.h"
-
-/* Place translation tables by default along with the ones used by BL31. */
-#ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
-#define PLAT_SP_IMAGE_XLAT_SECTION_NAME        "xlat_table"
-#endif
-
-/* Allocate and initialise the translation context for the secure partitions. */
-REGISTER_XLAT_CONTEXT2(sp,
-                      PLAT_SP_IMAGE_MMAP_REGIONS,
-                      PLAT_SP_IMAGE_MAX_XLAT_TABLES,
-                      PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
-                      EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME);
-
-/* Lock used for SP_MEMORY_ATTRIBUTES_GET and SP_MEMORY_ATTRIBUTES_SET */
-static spinlock_t mem_attr_smc_lock;
-
-/* Get handle of Secure Partition translation context */
-xlat_ctx_t *spm_get_sp_xlat_context(void)
-{
-       return &sp_xlat_ctx;
-};
-
-/*
- * Attributes are encoded using a different format in the SMC interface than in
- * the Trusted Firmware, where the mmap_attr_t enum type is used. This function
- * converts an attributes value from the SMC format to the mmap_attr_t format by
- * setting MT_RW/MT_RO, MT_USER/MT_PRIVILEGED and MT_EXECUTE/MT_EXECUTE_NEVER.
- * The other fields are left as 0 because they are ignored by the function
- * xlat_change_mem_attributes_ctx().
- */
-static unsigned int smc_attr_to_mmap_attr(unsigned int attributes)
-{
-       unsigned int tf_attr = 0U;
-
-       unsigned int access = (attributes & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
-                             >> SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
-
-       if (access == SP_MEMORY_ATTRIBUTES_ACCESS_RW) {
-               tf_attr |= MT_RW | MT_USER;
-       } else if (access ==  SP_MEMORY_ATTRIBUTES_ACCESS_RO) {
-               tf_attr |= MT_RO | MT_USER;
-       } else {
-               /* Other values are reserved. */
-               assert(access ==  SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS);
-               /* The only requirement is that there's no access from EL0 */
-               tf_attr |= MT_RO | MT_PRIVILEGED;
-       }
-
-       if ((attributes & SP_MEMORY_ATTRIBUTES_NON_EXEC) == 0) {
-               tf_attr |= MT_EXECUTE;
-       } else {
-               tf_attr |= MT_EXECUTE_NEVER;
-       }
-
-       return tf_attr;
-}
-
-/*
- * This function converts attributes from the Trusted Firmware format into the
- * SMC interface format.
- */
-static unsigned int smc_mmap_to_smc_attr(unsigned int attr)
-{
-       unsigned int smc_attr = 0U;
-
-       unsigned int data_access;
-
-       if ((attr & MT_USER) == 0) {
-               /* No access from EL0. */
-               data_access = SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS;
-       } else {
-               if ((attr & MT_RW) != 0) {
-                       assert(MT_TYPE(attr) != MT_DEVICE);
-                       data_access = SP_MEMORY_ATTRIBUTES_ACCESS_RW;
-               } else {
-                       data_access = SP_MEMORY_ATTRIBUTES_ACCESS_RO;
-               }
-       }
-
-       smc_attr |= (data_access & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
-                   << SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
-
-       if ((attr & MT_EXECUTE_NEVER) != 0U) {
-               smc_attr |= SP_MEMORY_ATTRIBUTES_NON_EXEC;
-       }
-
-       return smc_attr;
-}
-
-int32_t spm_memory_attributes_get_smc_handler(sp_context_t *sp_ctx,
-                                             uintptr_t base_va)
-{
-       uint32_t attributes;
-
-       spin_lock(&mem_attr_smc_lock);
-
-       int rc = xlat_get_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
-                                    base_va, &attributes);
-
-       spin_unlock(&mem_attr_smc_lock);
-
-       /* Convert error codes of xlat_get_mem_attributes_ctx() into SPM. */
-       assert((rc == 0) || (rc == -EINVAL));
-
-       if (rc == 0) {
-               return (int32_t) smc_mmap_to_smc_attr(attributes);
-       } else {
-               return SPM_INVALID_PARAMETER;
-       }
-}
-
-int spm_memory_attributes_set_smc_handler(sp_context_t *sp_ctx,
-                                         u_register_t page_address,
-                                         u_register_t pages_count,
-                                         u_register_t smc_attributes)
-{
-       uintptr_t base_va = (uintptr_t) page_address;
-       size_t size = (size_t) (pages_count * PAGE_SIZE);
-       uint32_t attributes = (uint32_t) smc_attributes;
-
-       INFO("  Start address  : 0x%lx\n", base_va);
-       INFO("  Number of pages: %i (%zi bytes)\n", (int) pages_count, size);
-       INFO("  Attributes     : 0x%x\n", attributes);
-
-       spin_lock(&mem_attr_smc_lock);
-
-       int ret = xlat_change_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
-                                       base_va, size,
-                                       smc_attr_to_mmap_attr(attributes));
-
-       spin_unlock(&mem_attr_smc_lock);
-
-       /* Convert error codes of xlat_change_mem_attributes_ctx() into SPM. */
-       assert((ret == 0) || (ret == -EINVAL));
-
-       return (ret == 0) ? SPM_SUCCESS : SPM_INVALID_PARAMETER;
-}
diff --git a/services/std_svc/spm_mm/aarch64/spm_helpers.S b/services/std_svc/spm_mm/aarch64/spm_helpers.S
new file mode 100644 (file)
index 0000000..aa35811
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include "../spm_private.h"
+
+       .global spm_secure_partition_enter
+       .global spm_secure_partition_exit
+
+       /* ---------------------------------------------------------------------
+        * This function is called with SP_EL0 as stack. Here we stash our EL3
+        * callee-saved registers on to the stack as a part of saving the C
+        * runtime and enter the secure payload.
+        * 'x0' contains a pointer to the memory where the address of the C
+        *  runtime context is to be saved.
+        * ---------------------------------------------------------------------
+        */
+func spm_secure_partition_enter
+       /* Make space for the registers that we're going to save */
+       mov     x3, sp
+       str     x3, [x0, #0]
+       sub     sp, sp, #SP_C_RT_CTX_SIZE
+
+       /* Save callee-saved registers on to the stack */
+       stp     x19, x20, [sp, #SP_C_RT_CTX_X19]
+       stp     x21, x22, [sp, #SP_C_RT_CTX_X21]
+       stp     x23, x24, [sp, #SP_C_RT_CTX_X23]
+       stp     x25, x26, [sp, #SP_C_RT_CTX_X25]
+       stp     x27, x28, [sp, #SP_C_RT_CTX_X27]
+       stp     x29, x30, [sp, #SP_C_RT_CTX_X29]
+
+       /* ---------------------------------------------------------------------
+        * Everything is setup now. el3_exit() will use the secure context to
+        * restore to the general purpose and EL3 system registers to ERET
+        * into the secure payload.
+        * ---------------------------------------------------------------------
+        */
+       b       el3_exit
+endfunc spm_secure_partition_enter
+
+       /* ---------------------------------------------------------------------
+        * This function is called with 'x0' pointing to a C runtime context
+        * saved in spm_secure_partition_enter().
+        * It restores the saved registers and jumps to that runtime with 'x0'
+        * as the new SP register. This destroys the C runtime context that had
+        * been built on the stack below the saved context by the caller. Later
+        * the second parameter 'x1' is passed as a return value to the caller.
+        * ---------------------------------------------------------------------
+        */
+func spm_secure_partition_exit
+       /* Restore the previous stack */
+       mov     sp, x0
+
+       /* Restore callee-saved registers on to the stack */
+       ldp     x19, x20, [x0, #(SP_C_RT_CTX_X19 - SP_C_RT_CTX_SIZE)]
+       ldp     x21, x22, [x0, #(SP_C_RT_CTX_X21 - SP_C_RT_CTX_SIZE)]
+       ldp     x23, x24, [x0, #(SP_C_RT_CTX_X23 - SP_C_RT_CTX_SIZE)]
+       ldp     x25, x26, [x0, #(SP_C_RT_CTX_X25 - SP_C_RT_CTX_SIZE)]
+       ldp     x27, x28, [x0, #(SP_C_RT_CTX_X27 - SP_C_RT_CTX_SIZE)]
+       ldp     x29, x30, [x0, #(SP_C_RT_CTX_X29 - SP_C_RT_CTX_SIZE)]
+
+       /* ---------------------------------------------------------------------
+        * This should take us back to the instruction after the call to the
+        * last spm_secure_partition_enter().* Place the second parameter to x0
+        * so that the caller will see it as a return value from the original
+        * entry call.
+        * ---------------------------------------------------------------------
+        */
+       mov     x0, x1
+       ret
+endfunc spm_secure_partition_exit
diff --git a/services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S b/services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S
new file mode 100644 (file)
index 0000000..dab6150
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2017, 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 <context.h>
+
+/* -----------------------------------------------------------------------------
+ * Very simple stackless exception handlers used by the spm shim layer.
+ * -----------------------------------------------------------------------------
+ */
+       .globl  spm_shim_exceptions_ptr
+
+vector_base spm_shim_exceptions_ptr, .spm_shim_exceptions
+
+       /* -----------------------------------------------------
+        * Current EL with SP0 : 0x0 - 0x200
+        * -----------------------------------------------------
+        */
+vector_entry SynchronousExceptionSP0, .spm_shim_exceptions
+       b       .
+end_vector_entry SynchronousExceptionSP0
+
+vector_entry IrqSP0, .spm_shim_exceptions
+       b       .
+end_vector_entry IrqSP0
+
+vector_entry FiqSP0, .spm_shim_exceptions
+       b       .
+end_vector_entry FiqSP0
+
+vector_entry SErrorSP0, .spm_shim_exceptions
+       b       .
+end_vector_entry SErrorSP0
+
+       /* -----------------------------------------------------
+        * Current EL with SPx: 0x200 - 0x400
+        * -----------------------------------------------------
+        */
+vector_entry SynchronousExceptionSPx, .spm_shim_exceptions
+       b       .
+end_vector_entry SynchronousExceptionSPx
+
+vector_entry IrqSPx, .spm_shim_exceptions
+       b       .
+end_vector_entry IrqSPx
+
+vector_entry FiqSPx, .spm_shim_exceptions
+       b       .
+end_vector_entry FiqSPx
+
+vector_entry SErrorSPx, .spm_shim_exceptions
+       b       .
+end_vector_entry SErrorSPx
+
+       /* -----------------------------------------------------
+        * Lower EL using AArch64 : 0x400 - 0x600. No exceptions
+        * are handled since secure_partition does not implement
+        * a lower EL
+        * -----------------------------------------------------
+        */
+vector_entry SynchronousExceptionA64, .spm_shim_exceptions
+       msr     tpidr_el1, x30
+       mrs     x30, esr_el1
+       ubfx    x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+
+       cmp     x30, #EC_AARCH64_SVC
+       b.eq    do_smc
+
+       cmp     x30, #EC_AARCH32_SVC
+       b.eq    do_smc
+
+       cmp     x30, #EC_AARCH64_SYS
+       b.eq    handle_sys_trap
+
+       /* Fail in all the other cases */
+       b       panic
+
+       /* ---------------------------------------------
+        * Tell SPM that we are done initialising
+        * ---------------------------------------------
+        */
+do_smc:
+       mrs     x30, tpidr_el1
+       smc     #0
+       eret
+
+       /* AArch64 system instructions trap are handled as a panic for now */
+handle_sys_trap:
+panic:
+       b       panic
+end_vector_entry SynchronousExceptionA64
+
+vector_entry IrqA64, .spm_shim_exceptions
+       b       .
+end_vector_entry IrqA64
+
+vector_entry FiqA64, .spm_shim_exceptions
+       b       .
+end_vector_entry FiqA64
+
+vector_entry SErrorA64, .spm_shim_exceptions
+       b       .
+end_vector_entry SErrorA64
+
+       /* -----------------------------------------------------
+        * Lower EL using AArch32 : 0x600 - 0x800
+        * -----------------------------------------------------
+        */
+vector_entry SynchronousExceptionA32, .spm_shim_exceptions
+       b       .
+end_vector_entry SynchronousExceptionA32
+
+vector_entry IrqA32, .spm_shim_exceptions
+       b       .
+end_vector_entry IrqA32
+
+vector_entry FiqA32, .spm_shim_exceptions
+       b       .
+end_vector_entry FiqA32
+
+vector_entry SErrorA32, .spm_shim_exceptions
+       b       .
+end_vector_entry SErrorA32
diff --git a/services/std_svc/spm_mm/spm.mk b/services/std_svc/spm_mm/spm.mk
new file mode 100644 (file)
index 0000000..3aa10ee
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${SPD},none)
+        $(error "Error: SPD and SPM are incompatible build options.")
+endif
+ifneq (${ARCH},aarch64)
+        $(error "Error: SPM is only supported on aarch64.")
+endif
+
+SPM_SOURCES    :=      $(addprefix services/std_svc/spm_mm/,   \
+                       ${ARCH}/spm_helpers.S                   \
+                       ${ARCH}/spm_shim_exceptions.S           \
+                       spm_main.c                              \
+                       spm_setup.c                             \
+                       spm_xlat.c)
+
+
+# Let the top-level Makefile know that we intend to include a BL32 image
+NEED_BL32              :=      yes
+
+# required so that SPM code executing at S-EL0 can access the timer registers
+NS_TIMER_SWITCH                :=      1
diff --git a/services/std_svc/spm_mm/spm_main.c b/services/std_svc/spm_mm/spm_main.c
new file mode 100644 (file)
index 0000000..7525763
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <bl31/bl31.h>
+#include <bl31/ehf.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/smccc.h>
+#include <lib/spinlock.h>
+#include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+#include <services/mm_svc.h>
+#include <services/secure_partition.h>
+#include <services/spm_svc.h>
+#include <smccc_helpers.h>
+
+#include "spm_private.h"
+
+/*******************************************************************************
+ * Secure Partition context information.
+ ******************************************************************************/
+static sp_context_t sp_ctx;
+
+/*******************************************************************************
+ * Set state of a Secure Partition context.
+ ******************************************************************************/
+void sp_state_set(sp_context_t *sp_ptr, sp_state_t state)
+{
+       spin_lock(&(sp_ptr->state_lock));
+       sp_ptr->state = state;
+       spin_unlock(&(sp_ptr->state_lock));
+}
+
+/*******************************************************************************
+ * Wait until the state of a Secure Partition is the specified one and change it
+ * to the desired state.
+ ******************************************************************************/
+void sp_state_wait_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to)
+{
+       int success = 0;
+
+       while (success == 0) {
+               spin_lock(&(sp_ptr->state_lock));
+
+               if (sp_ptr->state == from) {
+                       sp_ptr->state = to;
+
+                       success = 1;
+               }
+
+               spin_unlock(&(sp_ptr->state_lock));
+       }
+}
+
+/*******************************************************************************
+ * Check if the state of a Secure Partition is the specified one and, if so,
+ * change it to the desired state. Returns 0 on success, -1 on error.
+ ******************************************************************************/
+int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to)
+{
+       int ret = -1;
+
+       spin_lock(&(sp_ptr->state_lock));
+
+       if (sp_ptr->state == from) {
+               sp_ptr->state = to;
+
+               ret = 0;
+       }
+
+       spin_unlock(&(sp_ptr->state_lock));
+
+       return ret;
+}
+
+/*******************************************************************************
+ * This function takes an SP context pointer and performs a synchronous entry
+ * into it.
+ ******************************************************************************/
+static uint64_t spm_sp_synchronous_entry(sp_context_t *sp_ctx)
+{
+       uint64_t rc;
+
+       assert(sp_ctx != NULL);
+
+       /* Assign the context of the SP to this CPU */
+       cm_set_context(&(sp_ctx->cpu_ctx), SECURE);
+
+       /* Restore the context assigned above */
+       cm_el1_sysregs_context_restore(SECURE);
+       cm_set_next_eret_context(SECURE);
+
+       /* Invalidate TLBs at EL1. */
+       tlbivmalle1();
+       dsbish();
+
+       /* Enter Secure Partition */
+       rc = spm_secure_partition_enter(&sp_ctx->c_rt_ctx);
+
+       /* Save secure state */
+       cm_el1_sysregs_context_save(SECURE);
+
+       return rc;
+}
+
+/*******************************************************************************
+ * This function returns to the place where spm_sp_synchronous_entry() was
+ * called originally.
+ ******************************************************************************/
+__dead2 static void spm_sp_synchronous_exit(uint64_t rc)
+{
+       sp_context_t *ctx = &sp_ctx;
+
+       /*
+        * The SPM must have initiated the original request through a
+        * synchronous entry into the secure partition. Jump back to the
+        * original C runtime context with the value of rc in x0;
+        */
+       spm_secure_partition_exit(ctx->c_rt_ctx, rc);
+
+       panic();
+}
+
+/*******************************************************************************
+ * Jump to each Secure Partition for the first time.
+ ******************************************************************************/
+static int32_t spm_init(void)
+{
+       uint64_t rc;
+       sp_context_t *ctx;
+
+       INFO("Secure Partition init...\n");
+
+       ctx = &sp_ctx;
+
+       ctx->state = SP_STATE_RESET;
+
+       rc = spm_sp_synchronous_entry(ctx);
+       assert(rc == 0);
+
+       ctx->state = SP_STATE_IDLE;
+
+       INFO("Secure Partition initialized.\n");
+
+       return !rc;
+}
+
+/*******************************************************************************
+ * Initialize contexts of all Secure Partitions.
+ ******************************************************************************/
+int32_t spm_setup(void)
+{
+       sp_context_t *ctx;
+
+       /* Disable MMU at EL1 (initialized by BL2) */
+       disable_mmu_icache_el1();
+
+       /* Initialize context of the SP */
+       INFO("Secure Partition context setup start...\n");
+
+       ctx = &sp_ctx;
+
+       /* Assign translation tables context. */
+       ctx->xlat_ctx_handle = spm_get_sp_xlat_context();
+
+       spm_sp_setup(ctx);
+
+       /* Register init function for deferred init.  */
+       bl31_register_bl32_init(&spm_init);
+
+       INFO("Secure Partition setup done.\n");
+
+       return 0;
+}
+
+/*******************************************************************************
+ * Function to perform a call to a Secure Partition.
+ ******************************************************************************/
+uint64_t spm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3)
+{
+       uint64_t rc;
+       sp_context_t *sp_ptr = &sp_ctx;
+
+       /* Wait until the Secure Partition is idle and set it to busy. */
+       sp_state_wait_switch(sp_ptr, SP_STATE_IDLE, SP_STATE_BUSY);
+
+       /* Set values for registers on SP entry */
+       cpu_context_t *cpu_ctx = &(sp_ptr->cpu_ctx);
+
+       write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X0, smc_fid);
+       write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X1, x1);
+       write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X2, x2);
+       write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X3, x3);
+
+       /* Jump to the Secure Partition. */
+       rc = spm_sp_synchronous_entry(sp_ptr);
+
+       /* Flag Secure Partition as idle. */
+       assert(sp_ptr->state == SP_STATE_BUSY);
+       sp_state_set(sp_ptr, SP_STATE_IDLE);
+
+       return rc;
+}
+
+/*******************************************************************************
+ * MM_COMMUNICATE handler
+ ******************************************************************************/
+static uint64_t mm_communicate(uint32_t smc_fid, uint64_t mm_cookie,
+                              uint64_t comm_buffer_address,
+                              uint64_t comm_size_address, void *handle)
+{
+       uint64_t rc;
+
+       /* Cookie. Reserved for future use. It must be zero. */
+       if (mm_cookie != 0U) {
+               ERROR("MM_COMMUNICATE: cookie is not zero\n");
+               SMC_RET1(handle, SPM_INVALID_PARAMETER);
+       }
+
+       if (comm_buffer_address == 0U) {
+               ERROR("MM_COMMUNICATE: comm_buffer_address is zero\n");
+               SMC_RET1(handle, SPM_INVALID_PARAMETER);
+       }
+
+       if (comm_size_address != 0U) {
+               VERBOSE("MM_COMMUNICATE: comm_size_address is not 0 as recommended.\n");
+       }
+
+       /*
+        * The current secure partition design mandates
+        * - at any point, only a single core can be
+        *   executing in the secure partiton.
+        * - a core cannot be preempted by an interrupt
+        *   while executing in secure partition.
+        * Raise the running priority of the core to the
+        * interrupt level configured for secure partition
+        * so as to block any interrupt from preempting this
+        * core.
+        */
+       ehf_activate_priority(PLAT_SP_PRI);
+
+       /* Save the Normal world context */
+       cm_el1_sysregs_context_save(NON_SECURE);
+
+       rc = spm_sp_call(smc_fid, comm_buffer_address, comm_size_address,
+                        plat_my_core_pos());
+
+       /* Restore non-secure state */
+       cm_el1_sysregs_context_restore(NON_SECURE);
+       cm_set_next_eret_context(NON_SECURE);
+
+       /*
+        * Exited from secure partition. This core can take
+        * interrupts now.
+        */
+       ehf_deactivate_priority(PLAT_SP_PRI);
+
+       SMC_RET1(handle, rc);
+}
+
+/*******************************************************************************
+ * Secure Partition Manager SMC handler.
+ ******************************************************************************/
+uint64_t spm_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)
+{
+       unsigned int ns;
+
+       /* Determine which security state this SMC originated from */
+       ns = is_caller_non_secure(flags);
+
+       if (ns == SMC_FROM_SECURE) {
+
+               /* Handle SMCs from Secure world. */
+
+               assert(handle == cm_get_context(SECURE));
+
+               /* Make next ERET jump to S-EL0 instead of S-EL1. */
+               cm_set_elr_spsr_el3(SECURE, read_elr_el1(), read_spsr_el1());
+
+               switch (smc_fid) {
+
+               case SPM_VERSION_AARCH32:
+                       SMC_RET1(handle, SPM_VERSION_COMPILED);
+
+               case SP_EVENT_COMPLETE_AARCH64:
+                       spm_sp_synchronous_exit(x1);
+
+               case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
+                       INFO("Received SP_MEMORY_ATTRIBUTES_GET_AARCH64 SMC\n");
+
+                       if (sp_ctx.state != SP_STATE_RESET) {
+                               WARN("SP_MEMORY_ATTRIBUTES_GET_AARCH64 is available at boot time only\n");
+                               SMC_RET1(handle, SPM_NOT_SUPPORTED);
+                       }
+                       SMC_RET1(handle,
+                                spm_memory_attributes_get_smc_handler(
+                                        &sp_ctx, x1));
+
+               case SP_MEMORY_ATTRIBUTES_SET_AARCH64:
+                       INFO("Received SP_MEMORY_ATTRIBUTES_SET_AARCH64 SMC\n");
+
+                       if (sp_ctx.state != SP_STATE_RESET) {
+                               WARN("SP_MEMORY_ATTRIBUTES_SET_AARCH64 is available at boot time only\n");
+                               SMC_RET1(handle, SPM_NOT_SUPPORTED);
+                       }
+                       SMC_RET1(handle,
+                                spm_memory_attributes_set_smc_handler(
+                                       &sp_ctx, x1, x2, x3));
+               default:
+                       break;
+               }
+       } else {
+
+               /* Handle SMCs from Non-secure world. */
+
+               assert(handle == cm_get_context(NON_SECURE));
+
+               switch (smc_fid) {
+
+               case MM_VERSION_AARCH32:
+                       SMC_RET1(handle, MM_VERSION_COMPILED);
+
+               case MM_COMMUNICATE_AARCH32:
+               case MM_COMMUNICATE_AARCH64:
+                       return mm_communicate(smc_fid, x1, x2, x3, handle);
+
+               case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
+               case SP_MEMORY_ATTRIBUTES_SET_AARCH64:
+                       /* SMC interfaces reserved for secure callers. */
+                       SMC_RET1(handle, SPM_NOT_SUPPORTED);
+
+               default:
+                       break;
+               }
+       }
+
+       SMC_RET1(handle, SMC_UNK);
+}
diff --git a/services/std_svc/spm_mm/spm_private.h b/services/std_svc/spm_mm/spm_private.h
new file mode 100644 (file)
index 0000000..8e94a28
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPM_PRIVATE_H
+#define SPM_PRIVATE_H
+
+#include <context.h>
+
+/*******************************************************************************
+ * Constants that allow assembler code to preserve callee-saved registers of the
+ * C runtime context while performing a security state switch.
+ ******************************************************************************/
+#define SP_C_RT_CTX_X19                0x0
+#define SP_C_RT_CTX_X20                0x8
+#define SP_C_RT_CTX_X21                0x10
+#define SP_C_RT_CTX_X22                0x18
+#define SP_C_RT_CTX_X23                0x20
+#define SP_C_RT_CTX_X24                0x28
+#define SP_C_RT_CTX_X25                0x30
+#define SP_C_RT_CTX_X26                0x38
+#define SP_C_RT_CTX_X27                0x40
+#define SP_C_RT_CTX_X28                0x48
+#define SP_C_RT_CTX_X29                0x50
+#define SP_C_RT_CTX_X30                0x58
+
+#define SP_C_RT_CTX_SIZE       0x60
+#define SP_C_RT_CTX_ENTRIES    (SP_C_RT_CTX_SIZE >> DWORD_SHIFT)
+
+#ifndef __ASSEMBLY__
+
+#include <stdint.h>
+
+#include <lib/spinlock.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+typedef enum sp_state {
+       SP_STATE_RESET = 0,
+       SP_STATE_IDLE,
+       SP_STATE_BUSY
+} sp_state_t;
+
+typedef struct sp_context {
+       uint64_t c_rt_ctx;
+       cpu_context_t cpu_ctx;
+       xlat_ctx_t *xlat_ctx_handle;
+
+       sp_state_t state;
+       spinlock_t state_lock;
+} sp_context_t;
+
+/* Assembly helpers */
+uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx);
+void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret);
+
+void spm_sp_setup(sp_context_t *sp_ctx);
+
+xlat_ctx_t *spm_get_sp_xlat_context(void);
+
+int32_t spm_memory_attributes_get_smc_handler(sp_context_t *sp_ctx,
+                                             uintptr_t base_va);
+int spm_memory_attributes_set_smc_handler(sp_context_t *sp_ctx,
+                                         u_register_t page_address,
+                                         u_register_t pages_count,
+                                         u_register_t smc_attributes);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* SPM_PRIVATE_H */
diff --git a/services/std_svc/spm_mm/spm_setup.c b/services/std_svc/spm_mm/spm_setup.c
new file mode 100644 (file)
index 0000000..aae6cd5
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <context.h>
+#include <common/debug.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <platform_def.h>
+#include <plat/common/common_def.h>
+#include <plat/common/platform.h>
+#include <services/secure_partition.h>
+
+#include "spm_private.h"
+#include "spm_shim_private.h"
+
+/* Setup context of the Secure Partition */
+void spm_sp_setup(sp_context_t *sp_ctx)
+{
+       cpu_context_t *ctx = &(sp_ctx->cpu_ctx);
+
+       /*
+        * Initialize CPU context
+        * ----------------------
+        */
+
+       entry_point_info_t ep_info = {0};
+
+       SET_PARAM_HEAD(&ep_info, PARAM_EP, VERSION_1, SECURE | EP_ST_ENABLE);
+
+       /* Setup entrypoint and SPSR */
+       ep_info.pc = BL32_BASE;
+       ep_info.spsr = SPSR_64(MODE_EL0, MODE_SP_EL0, DISABLE_ALL_EXCEPTIONS);
+
+       /*
+        * X0: Virtual address of a buffer shared between EL3 and Secure EL0.
+        *     The buffer will be mapped in the Secure EL1 translation regime
+        *     with Normal IS WBWA attributes and RO data and Execute Never
+        *     instruction access permissions.
+        *
+        * X1: Size of the buffer in bytes
+        *
+        * X2: cookie value (Implementation Defined)
+        *
+        * X3: cookie value (Implementation Defined)
+        *
+        * X4 to X7 = 0
+        */
+       ep_info.args.arg0 = PLAT_SPM_BUF_BASE;
+       ep_info.args.arg1 = PLAT_SPM_BUF_SIZE;
+       ep_info.args.arg2 = PLAT_SPM_COOKIE_0;
+       ep_info.args.arg3 = PLAT_SPM_COOKIE_1;
+
+       cm_setup_context(ctx, &ep_info);
+
+       /*
+        * SP_EL0: A non-zero value will indicate to the SP that the SPM has
+        * initialized the stack pointer for the current CPU through
+        * implementation defined means. The value will be 0 otherwise.
+        */
+       write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_SP_EL0,
+                       PLAT_SP_IMAGE_STACK_BASE + PLAT_SP_IMAGE_STACK_PCPU_SIZE);
+
+       /*
+        * Setup translation tables
+        * ------------------------
+        */
+
+#if ENABLE_ASSERTIONS
+
+       /* Get max granularity supported by the platform. */
+       unsigned int max_granule = xlat_arch_get_max_supported_granule_size();
+
+       VERBOSE("Max translation granule size supported: %u KiB\n",
+               max_granule / 1024U);
+
+       unsigned int max_granule_mask = max_granule - 1U;
+
+       /* Base must be aligned to the max granularity */
+       assert((PLAT_SP_IMAGE_NS_BUF_BASE & max_granule_mask) == 0);
+
+       /* Size must be a multiple of the max granularity */
+       assert((PLAT_SP_IMAGE_NS_BUF_SIZE & max_granule_mask) == 0);
+
+#endif /* ENABLE_ASSERTIONS */
+
+       /* This region contains the exception vectors used at S-EL1. */
+       const mmap_region_t sel1_exception_vectors =
+               MAP_REGION_FLAT(SPM_SHIM_EXCEPTIONS_START,
+                               SPM_SHIM_EXCEPTIONS_SIZE,
+                               MT_CODE | MT_SECURE | MT_PRIVILEGED);
+       mmap_add_region_ctx(sp_ctx->xlat_ctx_handle,
+                           &sel1_exception_vectors);
+
+       mmap_add_ctx(sp_ctx->xlat_ctx_handle,
+                    plat_get_secure_partition_mmap(NULL));
+
+       init_xlat_tables_ctx(sp_ctx->xlat_ctx_handle);
+
+       /*
+        * MMU-related registers
+        * ---------------------
+        */
+       xlat_ctx_t *xlat_ctx = sp_ctx->xlat_ctx_handle;
+
+       uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
+
+       setup_mmu_cfg((uint64_t *)&mmu_cfg_params, 0, xlat_ctx->base_table,
+                     xlat_ctx->pa_max_address, xlat_ctx->va_max_address,
+                     EL1_EL0_REGIME);
+
+       write_ctx_reg(get_sysregs_ctx(ctx), CTX_MAIR_EL1,
+                     mmu_cfg_params[MMU_CFG_MAIR]);
+
+       write_ctx_reg(get_sysregs_ctx(ctx), CTX_TCR_EL1,
+                     mmu_cfg_params[MMU_CFG_TCR]);
+
+       write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR0_EL1,
+                     mmu_cfg_params[MMU_CFG_TTBR0]);
+
+       /* Setup SCTLR_EL1 */
+       u_register_t sctlr_el1 = read_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1);
+
+       sctlr_el1 |=
+               /*SCTLR_EL1_RES1 |*/
+               /* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */
+               SCTLR_UCI_BIT                                                   |
+               /* RW regions at xlat regime EL1&0 are forced to be XN. */
+               SCTLR_WXN_BIT                                                   |
+               /* Don't trap to EL1 execution of WFI or WFE at EL0. */
+               SCTLR_NTWI_BIT | SCTLR_NTWE_BIT                                 |
+               /* Don't trap to EL1 accesses to CTR_EL0 from EL0. */
+               SCTLR_UCT_BIT                                                   |
+               /* Don't trap to EL1 execution of DZ ZVA at EL0. */
+               SCTLR_DZE_BIT                                                   |
+               /* Enable SP Alignment check for EL0 */
+               SCTLR_SA0_BIT                                                   |
+               /* Allow cacheable data and instr. accesses to normal memory. */
+               SCTLR_C_BIT | SCTLR_I_BIT                                       |
+               /* Enable MMU. */
+               SCTLR_M_BIT
+       ;
+
+       sctlr_el1 &= ~(
+               /* Explicit data accesses at EL0 are little-endian. */
+               SCTLR_E0E_BIT                                                   |
+               /*
+                * Alignment fault checking disabled when at EL1 and EL0 as
+                * the UEFI spec permits unaligned accesses.
+                */
+               SCTLR_A_BIT                                                     |
+               /* Accesses to DAIF from EL0 are trapped to EL1. */
+               SCTLR_UMA_BIT
+       );
+
+       write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1);
+
+       /*
+        * Setup other system registers
+        * ----------------------------
+        */
+
+       /* Shim Exception Vector Base Address */
+       write_ctx_reg(get_sysregs_ctx(ctx), CTX_VBAR_EL1,
+                       SPM_SHIM_EXCEPTIONS_PTR);
+
+       write_ctx_reg(get_sysregs_ctx(ctx), CTX_CNTKCTL_EL1,
+                     EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT);
+
+       /*
+        * FPEN: Allow the Secure Partition to access FP/SIMD registers.
+        * Note that SPM will not do any saving/restoring of these registers on
+        * behalf of the SP. This falls under the SP's responsibility.
+        * TTA: Enable access to trace registers.
+        * ZEN (v8.2): Trap SVE instructions and access to SVE registers.
+        */
+       write_ctx_reg(get_sysregs_ctx(ctx), CTX_CPACR_EL1,
+                       CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
+
+       /*
+        * Prepare information in buffer shared between EL3 and S-EL0
+        * ----------------------------------------------------------
+        */
+
+       void *shared_buf_ptr = (void *) PLAT_SPM_BUF_BASE;
+
+       /* Copy the boot information into the shared buffer with the SP. */
+       assert((uintptr_t)shared_buf_ptr + sizeof(secure_partition_boot_info_t)
+              <= (PLAT_SPM_BUF_BASE + PLAT_SPM_BUF_SIZE));
+
+       assert(PLAT_SPM_BUF_BASE <= (UINTPTR_MAX - PLAT_SPM_BUF_SIZE + 1));
+
+       const secure_partition_boot_info_t *sp_boot_info =
+                       plat_get_secure_partition_boot_info(NULL);
+
+       assert(sp_boot_info != NULL);
+
+       memcpy((void *) shared_buf_ptr, (const void *) sp_boot_info,
+              sizeof(secure_partition_boot_info_t));
+
+       /* Pointer to the MP information from the platform port. */
+       secure_partition_mp_info_t *sp_mp_info =
+               ((secure_partition_boot_info_t *) shared_buf_ptr)->mp_info;
+
+       assert(sp_mp_info != NULL);
+
+       /*
+        * Point the shared buffer MP information pointer to where the info will
+        * be populated, just after the boot info.
+        */
+       ((secure_partition_boot_info_t *) shared_buf_ptr)->mp_info =
+               (secure_partition_mp_info_t *) ((uintptr_t)shared_buf_ptr
+                               + sizeof(secure_partition_boot_info_t));
+
+       /*
+        * Update the shared buffer pointer to where the MP information for the
+        * payload will be populated
+        */
+       shared_buf_ptr = ((secure_partition_boot_info_t *) shared_buf_ptr)->mp_info;
+
+       /*
+        * Copy the cpu information into the shared buffer area after the boot
+        * information.
+        */
+       assert(sp_boot_info->num_cpus <= PLATFORM_CORE_COUNT);
+
+       assert((uintptr_t)shared_buf_ptr
+              <= (PLAT_SPM_BUF_BASE + PLAT_SPM_BUF_SIZE -
+                      (sp_boot_info->num_cpus * sizeof(*sp_mp_info))));
+
+       memcpy(shared_buf_ptr, (const void *) sp_mp_info,
+               sp_boot_info->num_cpus * sizeof(*sp_mp_info));
+
+       /*
+        * Calculate the linear indices of cores in boot information for the
+        * secure partition and flag the primary CPU
+        */
+       sp_mp_info = (secure_partition_mp_info_t *) shared_buf_ptr;
+
+       for (unsigned int index = 0; index < sp_boot_info->num_cpus; index++) {
+               u_register_t mpidr = sp_mp_info[index].mpidr;
+
+               sp_mp_info[index].linear_id = plat_core_pos_by_mpidr(mpidr);
+               if (plat_my_core_pos() == sp_mp_info[index].linear_id)
+                       sp_mp_info[index].flags |= MP_INFO_FLAG_PRIMARY_CPU;
+       }
+}
diff --git a/services/std_svc/spm_mm/spm_shim_private.h b/services/std_svc/spm_mm/spm_shim_private.h
new file mode 100644 (file)
index 0000000..7fe9692
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPM_SHIM_PRIVATE_H
+#define SPM_SHIM_PRIVATE_H
+
+#include <stdint.h>
+
+#include <lib/utils_def.h>
+
+/* Assembly source */
+IMPORT_SYM(uintptr_t, spm_shim_exceptions_ptr,         SPM_SHIM_EXCEPTIONS_PTR);
+
+/* Linker symbols */
+IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_START__,   SPM_SHIM_EXCEPTIONS_START);
+IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_END__,     SPM_SHIM_EXCEPTIONS_END);
+
+/* Definitions */
+
+#define SPM_SHIM_EXCEPTIONS_SIZE       \
+       (SPM_SHIM_EXCEPTIONS_END - SPM_SHIM_EXCEPTIONS_START)
+
+#endif /* SPM_SHIM_PRIVATE_H */
diff --git a/services/std_svc/spm_mm/spm_xlat.c b/services/std_svc/spm_mm/spm_xlat.c
new file mode 100644 (file)
index 0000000..f54168e
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <errno.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <platform_def.h>
+#include <plat/common/platform.h>
+#include <services/secure_partition.h>
+#include <services/spm_svc.h>
+
+#include "spm_private.h"
+#include "spm_shim_private.h"
+
+/* Place translation tables by default along with the ones used by BL31. */
+#ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
+#define PLAT_SP_IMAGE_XLAT_SECTION_NAME        "xlat_table"
+#endif
+
+/* Allocate and initialise the translation context for the secure partitions. */
+REGISTER_XLAT_CONTEXT2(sp,
+                      PLAT_SP_IMAGE_MMAP_REGIONS,
+                      PLAT_SP_IMAGE_MAX_XLAT_TABLES,
+                      PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
+                      EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME);
+
+/* Lock used for SP_MEMORY_ATTRIBUTES_GET and SP_MEMORY_ATTRIBUTES_SET */
+static spinlock_t mem_attr_smc_lock;
+
+/* Get handle of Secure Partition translation context */
+xlat_ctx_t *spm_get_sp_xlat_context(void)
+{
+       return &sp_xlat_ctx;
+};
+
+/*
+ * Attributes are encoded using a different format in the SMC interface than in
+ * the Trusted Firmware, where the mmap_attr_t enum type is used. This function
+ * converts an attributes value from the SMC format to the mmap_attr_t format by
+ * setting MT_RW/MT_RO, MT_USER/MT_PRIVILEGED and MT_EXECUTE/MT_EXECUTE_NEVER.
+ * The other fields are left as 0 because they are ignored by the function
+ * xlat_change_mem_attributes_ctx().
+ */
+static unsigned int smc_attr_to_mmap_attr(unsigned int attributes)
+{
+       unsigned int tf_attr = 0U;
+
+       unsigned int access = (attributes & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
+                             >> SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
+
+       if (access == SP_MEMORY_ATTRIBUTES_ACCESS_RW) {
+               tf_attr |= MT_RW | MT_USER;
+       } else if (access ==  SP_MEMORY_ATTRIBUTES_ACCESS_RO) {
+               tf_attr |= MT_RO | MT_USER;
+       } else {
+               /* Other values are reserved. */
+               assert(access ==  SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS);
+               /* The only requirement is that there's no access from EL0 */
+               tf_attr |= MT_RO | MT_PRIVILEGED;
+       }
+
+       if ((attributes & SP_MEMORY_ATTRIBUTES_NON_EXEC) == 0) {
+               tf_attr |= MT_EXECUTE;
+       } else {
+               tf_attr |= MT_EXECUTE_NEVER;
+       }
+
+       return tf_attr;
+}
+
+/*
+ * This function converts attributes from the Trusted Firmware format into the
+ * SMC interface format.
+ */
+static unsigned int smc_mmap_to_smc_attr(unsigned int attr)
+{
+       unsigned int smc_attr = 0U;
+
+       unsigned int data_access;
+
+       if ((attr & MT_USER) == 0) {
+               /* No access from EL0. */
+               data_access = SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS;
+       } else {
+               if ((attr & MT_RW) != 0) {
+                       assert(MT_TYPE(attr) != MT_DEVICE);
+                       data_access = SP_MEMORY_ATTRIBUTES_ACCESS_RW;
+               } else {
+                       data_access = SP_MEMORY_ATTRIBUTES_ACCESS_RO;
+               }
+       }
+
+       smc_attr |= (data_access & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
+                   << SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
+
+       if ((attr & MT_EXECUTE_NEVER) != 0U) {
+               smc_attr |= SP_MEMORY_ATTRIBUTES_NON_EXEC;
+       }
+
+       return smc_attr;
+}
+
+int32_t spm_memory_attributes_get_smc_handler(sp_context_t *sp_ctx,
+                                             uintptr_t base_va)
+{
+       uint32_t attributes;
+
+       spin_lock(&mem_attr_smc_lock);
+
+       int rc = xlat_get_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
+                                    base_va, &attributes);
+
+       spin_unlock(&mem_attr_smc_lock);
+
+       /* Convert error codes of xlat_get_mem_attributes_ctx() into SPM. */
+       assert((rc == 0) || (rc == -EINVAL));
+
+       if (rc == 0) {
+               return (int32_t) smc_mmap_to_smc_attr(attributes);
+       } else {
+               return SPM_INVALID_PARAMETER;
+       }
+}
+
+int spm_memory_attributes_set_smc_handler(sp_context_t *sp_ctx,
+                                         u_register_t page_address,
+                                         u_register_t pages_count,
+                                         u_register_t smc_attributes)
+{
+       uintptr_t base_va = (uintptr_t) page_address;
+       size_t size = (size_t) (pages_count * PAGE_SIZE);
+       uint32_t attributes = (uint32_t) smc_attributes;
+
+       INFO("  Start address  : 0x%lx\n", base_va);
+       INFO("  Number of pages: %i (%zi bytes)\n", (int) pages_count, size);
+       INFO("  Attributes     : 0x%x\n", attributes);
+
+       spin_lock(&mem_attr_smc_lock);
+
+       int ret = xlat_change_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
+                                       base_va, size,
+                                       smc_attr_to_mmap_attr(attributes));
+
+       spin_unlock(&mem_attr_smc_lock);
+
+       /* Convert error codes of xlat_change_mem_attributes_ctx() into SPM. */
+       assert((ret == 0) || (ret == -EINVAL));
+
+       return (ret == 0) ? SPM_SUCCESS : SPM_INVALID_PARAMETER;
+}
index 7a34655fd78d8ac2d53082adfef5e421b506b755..1d80fa343356eea0bce9c4b4f07549f62cea9898 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -103,7 +103,7 @@ static uintptr_t std_svc_smc_handler(uint32_t smc_fid,
                SMC_RET1(handle, ret);
        }
 
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
        /*
         * Dispatch SPM calls to SPM SMC handler and return its return
         * value
index 0d4f929bb582d25d68c9f923f0c57d65bad7529a..80b498e47eb9a807c3e7375d140e7e10e92e5553 100644 (file)
@@ -271,10 +271,10 @@ static void uuid_from_str(uuid_t *u, const char *s)
            &u->node[2], &u->node[3],
            &u->node[4], &u->node[5]);
        /*
-        * Given the format specifier above, we expect 11 items to be scanned
+        * Given the format specifier above, we expect 16 items to be scanned
         * for a properly formatted UUID.
         */
-       if (n != 11)
+       if (n != 16)
                log_errx("Invalid UUID: %s", s);
 }