driver: brcm: add mdio driver

Change-Id: Id873670f68a4c584e3b7b586cab28565bb5a1c27
Signed-off-by: Bharat Gooty <bharat.gooty@broadcom.com>
diff --git a/drivers/brcm/mdio/mdio.c b/drivers/brcm/mdio/mdio.c
new file mode 100644
index 0000000..1cf9d66
--- /dev/null
+++ b/drivers/brcm/mdio/mdio.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016 - 2021, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <string.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <mdio.h>
+
+static int mdio_op_status(uint32_t result)
+{
+	uint32_t timeout = 1000000U; /* loop for 1s */
+	uint32_t val;
+
+	do {
+		val = mmio_read_32(CMIC_MIIM_STAT);
+		if ((val & MDIO_STAT_DONE) == result) {
+			return 0;
+		}
+
+		udelay(1U);
+	} while (timeout-- != 0U);
+	return -1;
+}
+
+static int mdio_op(uint16_t busid, uint16_t phyid, uint32_t reg,
+	       uint16_t val, uint8_t op)
+{
+	uint32_t param;
+	int ret;
+
+	mmio_write_32(CMIC_MIIM_CTRL, 0U);
+	ret = mdio_op_status(0U);
+	if (ret != 0) {
+		goto err;
+	}
+
+	param = 0U;
+	param |= 1U << MDIO_PARAM_INTERNAL_SEL;
+	param |= (busid & MDIO_PARAM_BUSID_MASK) << MDIO_PARAM_BUSID;
+	param |= (phyid & MDIO_PARAM_PHYID_MASK) << MDIO_PARAM_PHYID;
+	param |= (val & MDIO_PARAM_DATA_MASK) << MDIO_PARAM_DATA;
+
+	mmio_write_32(CMIC_MIIM_PARAM, param);
+
+	mmio_write_32(CMIC_MIIM_ADDRESS, reg);
+
+	mmio_write_32(CMIC_MIIM_CTRL, op);
+
+	ret = mdio_op_status(1U);
+	if (ret != 0) {
+		goto err;
+	}
+
+	if (op == MDIO_CTRL_READ_OP) {
+		ret = mmio_read_32(CMIC_MIIM_READ_DATA) & MDIO_READ_DATA_MASK;
+	}
+err:
+	return ret;
+}
+
+int mdio_write(uint16_t busid, uint16_t phyid, uint32_t reg, uint16_t val)
+{
+	int ret;
+
+	ret = mdio_op(busid, phyid, reg, val, MDIO_CTRL_WRITE_OP);
+	if (ret == -1) {
+		INFO("MDIO write fail\n");
+	}
+	return ret;
+}
+
+int mdio_read(uint16_t busid, uint16_t phyid, uint32_t reg)
+{
+	int ret;
+
+	ret = mdio_op(busid, phyid, reg, 0U, MDIO_CTRL_READ_OP);
+	if (ret == -1) {
+		INFO("MDIO read fail\n");
+	}
+	return ret;
+}
diff --git a/include/drivers/brcm/mdio/mdio.h b/include/drivers/brcm/mdio/mdio.h
new file mode 100644
index 0000000..b27c7b3
--- /dev/null
+++ b/include/drivers/brcm/mdio/mdio.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 - 2021, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MDIO_H
+#define MDIO_H
+
+#define CMIC_MIIM_PARAM		(PLAT_CMIC_MIIM_BASE + 0x23cU)
+#define MDIO_PARAM_MIIM_CYCLE	29U
+#define MDIO_PARAM_INTERNAL_SEL	25U
+#define MDIO_PARAM_BUSID	22U
+#define MDIO_PARAM_BUSID_MASK	0x7U
+#define MDIO_PARAM_C45_SEL	21U
+#define MDIO_PARAM_PHYID	16U
+#define MDIO_PARAM_PHYID_MASK	0x1FU
+#define MDIO_PARAM_DATA		0U
+#define MDIO_PARAM_DATA_MASK	0xFFFFU
+#define CMIC_MIIM_READ_DATA	(PLAT_CMIC_MIIM_BASE + 0x240U)
+#define MDIO_READ_DATA_MASK	0xffffU
+#define CMIC_MIIM_ADDRESS	(PLAT_CMIC_MIIM_BASE + 0x244U)
+#define CMIC_MIIM_CTRL		(PLAT_CMIC_MIIM_BASE + 0x248U)
+#define MDIO_CTRL_WRITE_OP	0x1U
+#define MDIO_CTRL_READ_OP	0x2U
+#define CMIC_MIIM_STAT		(PLAT_CMIC_MIIM_BASE + 0x24cU)
+#define MDIO_STAT_DONE		1U
+
+int mdio_write(uint16_t busid, uint16_t phyid, uint32_t reg, uint16_t val);
+int mdio_read(uint16_t busid, uint16_t phyid, uint32_t reg);
+#endif /* MDIO_H */
diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk
index 3069f91..5f02dc1 100644
--- a/plat/brcm/board/common/board_common.mk
+++ b/plat/brcm/board/common/board_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015 - 2020, Broadcom
+# Copyright (c) 2015 - 2021, Broadcom
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -114,7 +114,8 @@
 
 PLAT_INCLUDES		+=	-Iplat/brcm/board/common \
 				-Iinclude/drivers/brcm \
-				-Iinclude/drivers/brcm/emmc
+				-Iinclude/drivers/brcm/emmc \
+				-Iinclude/drivers/brcm/mdio
 
 PLAT_BL_COMMON_SOURCES	+=	plat/brcm/common/brcm_common.c \
 				plat/brcm/board/common/cmn_sec.c \
diff --git a/plat/brcm/board/stingray/include/sr_def.h b/plat/brcm/board/stingray/include/sr_def.h
index be0dee1..277836e 100644
--- a/plat/brcm/board/stingray/include/sr_def.h
+++ b/plat/brcm/board/stingray/include/sr_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, Broadcom
+ * Copyright (c) 2016-2021, Broadcom
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -193,6 +193,11 @@
 #define PLAT_CHIP_REV_GET	(mmio_read_32(ICFG_CHIP_REVISION_ID))
 
 /*******************************************************************************
+ * CMIC MII (MDIO) related constant
+ ******************************************************************************/
+#define PLAT_CMIC_MIIM_BASE	0x68920000U
+
+/*******************************************************************************
  * Timers related constants
  ******************************************************************************/
 /* ChipcommonG_tim0_TIM_TIMER1Load 0x68930000 */
diff --git a/plat/brcm/board/stingray/platform.mk b/plat/brcm/board/stingray/platform.mk
index c5509bb..7fcf373 100644
--- a/plat/brcm/board/stingray/platform.mk
+++ b/plat/brcm/board/stingray/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2020, Broadcom
+# Copyright (c) 2019-2021, Broadcom
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -190,7 +190,8 @@
 				plat/${SOC_DIR}/src/tz_sec.c \
 				drivers/arm/tzc/tzc400.c \
 				plat/${SOC_DIR}/driver/plat_emmc.c \
-				plat/${SOC_DIR}/src/topology.c
+				plat/${SOC_DIR}/src/topology.c \
+				drivers/brcm/mdio/mdio.c
 
 ifeq (${USE_CHIMP},yes)
 PLAT_BL_COMMON_SOURCES	+=	drivers/brcm/chimp.c