diff --git a/drivers/marvell/ddr_phy_access.c b/drivers/marvell/ddr_phy_access.c new file mode 100644 index 000000000..352d1eff6 --- /dev/null +++ b/drivers/marvell/ddr_phy_access.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include "ddr_phy_access.h" +#include +#include +#include + +#define DDR_PHY_END_ADDRESS 0x100000 + +#ifdef DDR_PHY_DEBUG +#define debug_printf(...) printf(__VA_ARGS__) +#else +#define debug_printf(...) +#endif + + +/* + * This routine writes 'data' to specified 'address' offset, + * with optional debug print support + */ +int snps_fw_write(uintptr_t offset, uint16_t data) +{ + debug_printf("In %s\n", __func__); + + if (offset < DDR_PHY_END_ADDRESS) { + mmio_write_16(DDR_PHY_BASE_ADDR + (2 * offset), data); + return 0; + } + debug_printf("%s: illegal offset value: 0x%x\n", __func__, offset); + return -EINVAL; +} + +int snps_fw_read(uintptr_t offset, uint16_t *read) +{ + debug_printf("In %s\n", __func__); + + if (offset < DDR_PHY_END_ADDRESS) { + *read = mmio_read_16(DDR_PHY_BASE_ADDR + (2 * offset)); + return 0; + } + debug_printf("%s: illegal offset value: 0x%x\n", __func__, offset); + return -EINVAL; +} + +int mvebu_ddr_phy_write(uintptr_t offset, uint16_t data) +{ + return snps_fw_write(offset, data); +} + +int mvebu_ddr_phy_read(uintptr_t offset, uint16_t *read) +{ + return snps_fw_read(offset, read); +} diff --git a/drivers/marvell/ddr_phy_access.h b/drivers/marvell/ddr_phy_access.h new file mode 100644 index 000000000..5f9a6689d --- /dev/null +++ b/drivers/marvell/ddr_phy_access.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2021 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#define DEVICE_BASE 0xF0000000 +#define DDR_PHY_OFFSET 0x1000000 +#define DDR_PHY_BASE_ADDR (DEVICE_BASE + DDR_PHY_OFFSET) + +int mvebu_ddr_phy_write(uintptr_t offset, uint16_t data); +int mvebu_ddr_phy_read(uintptr_t offset, uint16_t *read); diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index e20cf788a..dcb64ce0f 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -115,7 +115,8 @@ MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \ $(MARVELL_DRV_BASE)/comphy/phy-comphy-cp110.c \ $(MARVELL_DRV_BASE)/mc_trustzone/mc_trustzone.c \ $(MARVELL_DRV_BASE)/mg_conf_cm3/mg_conf_cm3.c \ - $(MARVELL_DRV_BASE)/secure_dfx_access/armada_thermal.c \ + $(MARVELL_DRV_BASE)/secure_dfx_access/armada_thermal.c \ + $(MARVELL_DRV_BASE)/ddr_phy_access.c \ drivers/rambus/trng_ip_76.c BL31_PORTING_SOURCES := $(BOARD_DIR)/board/marvell_plat_config.c diff --git a/plat/marvell/armada/common/mrvl_sip_svc.c b/plat/marvell/armada/common/mrvl_sip_svc.c index aa9439301..ebc7632ac 100644 --- a/plat/marvell/armada/common/mrvl_sip_svc.c +++ b/plat/marvell/armada/common/mrvl_sip_svc.c @@ -17,6 +17,7 @@ #include "comphy/phy-comphy-cp110.h" #include "secure_dfx_access/dfx.h" +#include "ddr_phy_access.h" #include /* #define DEBUG_COMPHY */ @@ -39,6 +40,8 @@ #define MV_SIP_PMU_IRQ_ENABLE 0x82000012 #define MV_SIP_PMU_IRQ_DISABLE 0x82000013 #define MV_SIP_DFX 0x82000014 +#define MV_SIP_DDR_PHY_WRITE 0x82000015 +#define MV_SIP_DDR_PHY_READ 0x82000016 /* TRNG */ #define MV_SIP_RNG_64 0xC200FF11 @@ -145,6 +148,13 @@ uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid, SMC_RET2(handle, ret, read); } SMC_RET1(handle, SMC_UNK); + case MV_SIP_DDR_PHY_WRITE: + ret = mvebu_ddr_phy_write(x1, x2); + SMC_RET1(handle, ret); + case MV_SIP_DDR_PHY_READ: + read = 0; + ret = mvebu_ddr_phy_read(x1, (uint16_t *)&read); + SMC_RET2(handle, ret, read); case MV_SIP_RNG_64: ret = eip76_rng_get_random((uint8_t *)&w2, 4 * (x1 % 2 + 1)); SMC_RET3(handle, ret, w2[0], w2[1]);