drivers: marvell: mg_conf_cm3: pass comphy lane number to AP FW

Since the AP process can be enabled on different setups, the information
about used comphy lane should be passed to AP FW. For instance:
- A8K development board uses comphy lane 2 for eth 0
- cn913x development board uses comphy lane 4 for eth 0

Change-Id: Icf001fb3eea4d9c24c09384e49844ecaf8655ad2
Signed-off-by: Grzegorz Jaszczyk <jaz@semihalf.com>
diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c
index 7ca7460..1d5b6f5 100644
--- a/drivers/marvell/comphy/phy-comphy-cp110.c
+++ b/drivers/marvell/comphy/phy-comphy-cp110.c
@@ -2251,7 +2251,7 @@
 
 	/* Start AP Firmware */
 	mvebu_cp110_get_ap_and_cp_nr(&ap_nr, &cp_nr, comphy_base);
-	mg_start_ap_fw(cp_nr);
+	mg_start_ap_fw(cp_nr, comphy_index);
 
 	return 0;
 }
diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c
index 0efa30e..98e1896 100644
--- a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c
+++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.c
@@ -6,6 +6,7 @@
  */
 
 #include <a8k_plat_def.h>
+#include <arch_helpers.h>
 #include <common/debug.h>
 #include <lib/mmio.h>
 #include <mss_scp_bl2_format.h>
@@ -18,8 +19,25 @@
 #define MG_CM3_MG_INT_MFX_REG(CP)	(MG_CM3_CONFI_BASE(CP) + 0x2B054)
 #define CM3_SYS_RESET_BIT		BIT(0)
 
+#define MG_CM3_SHARED_MEM_BASE(CP)	(MG_CM3_SRAM_BASE(CP) + 0x1FC00ULL)
+
 #define MG_SRAM_SIZE	0x20000 /* 128KB */
 
+#define MG_ACK_TIMEOUT 10
+
+/**
+ * struct ap_sharedmem_ctrl - used to pass information between the HOST and CM3
+ * @init_done:	Set by CM3 when ap_proces initialzied. Host check if CM3 set
+ *		this flag to confirm that the process is running
+ * @lane_nr:	Set by Host to mark which comphy lane should be configure. E.g.:
+ *		- A8K development board uses comphy lane 2 for eth0
+ *		- CN913x development board uses comphy lane 4 for eth0
+ */
+struct ap_sharedmem_ctrl {
+	uint32_t init_done;
+	uint32_t lane_nr;
+};
+
 int mg_image_load(uintptr_t src_addr, uint32_t size, int cp_index)
 {
 	uintptr_t mg_regs = MG_CM3_SRAM_BASE(cp_index);
@@ -43,17 +61,37 @@
 	return 0;
 }
 
-void mg_start_ap_fw(int cp_nr)
+void mg_start_ap_fw(int cp_nr, uint8_t comphy_index)
 {
+	volatile struct ap_sharedmem_ctrl *ap_shared_ctrl =
+					(void *)MG_CM3_SHARED_MEM_BASE(cp_nr);
+	int timeout = MG_ACK_TIMEOUT;
+
 	if (mmio_read_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr)) & CM3_CPU_EN_BIT) {
 		VERBOSE("cm3 already running\n");
 		return;  /* cm3 already running */
 	}
 
+	/*
+	 * Mark which comphy lane should be used - it will be read via shared
+	 * mem by ap process
+	 */
+	ap_shared_ctrl->lane_nr = comphy_index;
+	/* Make sure it took place before enabling cm3 */
+	dmbst();
+
 	mmio_setbits_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr), CM3_CPU_EN_BIT);
 	mmio_setbits_32(MG_CM3_MG_INT_MFX_REG(cp_nr), CM3_SYS_RESET_BIT);
 
-	/* TODO: add some routine for checking if ap process is running, if not
-	 * disable cm3.
-	 */
+	/* Check for ap process initialization by fw */
+	while (ap_shared_ctrl->init_done != 1 && timeout--)
+		VERBOSE("Waiting for ap process ack, timeout %d\n", timeout);
+
+	if (timeout == 0) {
+		ERROR("AP process failed, disabling cm3\n");
+		mmio_clrbits_32(MG_CM3_MG_INT_MFX_REG(cp_nr),
+				CM3_SYS_RESET_BIT);
+		mmio_clrbits_32(MG_CM3_CONFI_GLOB_CFG_REG(cp_nr),
+				CM3_CPU_EN_BIT);
+	}
 }
diff --git a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h
index 8dfaa32..e2756de 100644
--- a/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h
+++ b/drivers/marvell/mg_conf_cm3/mg_conf_cm3.h
@@ -5,5 +5,5 @@
  * https://spdx.org/licenses
  */
 
-void mg_start_ap_fw(int cp_nr);
+void mg_start_ap_fw(int cp_nr, uint8_t comphy_index);
 int mg_image_load(uintptr_t src_addr, uint32_t size, int cp_index);