ddr_phy: use smc calls to access ddr phy registers

Added smc calls support to access ddr phy registers.

Change-Id: Ibaa0a8e20b6398ab394c7e2e9ea61f9a28cdb870
Signed-off-by: Alex Leibovich <alexl@marvell.com>
Reviewed-on: https://sj1git1.cavium.com/20791
Tested-by: Kostya Porotchkin <kostap@marvell.com>
Reviewed-by: Kostya Porotchkin <kostap@marvell.com>
diff --git a/drivers/marvell/ddr_phy_access.c b/drivers/marvell/ddr_phy_access.c
new file mode 100644
index 0000000..352d1ef
--- /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 <lib/mmio.h>
+#include <drivers/marvell/ccu.h>
+#include <errno.h>
+
+#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 0000000..5f9a668
--- /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 <plat_marvell.h>
+
+#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 e20cf78..dcb64ce 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_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 aa94393..ebc7632 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 <stdbool.h>
 
 /* #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 @@
 			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]);