plat: marvell: Add common ARMADA platform components

Add common Marvell ARMADA platform components.
This patch also includes common components for Marvell
ARMADA 8K platforms.

Change-Id: I42192fdc6525a42e46b3ac2ad63c83db9bcbfeaf
Signed-off-by: Hanna Hawa <hannah@marvell.com>
Signed-off-by: Konstantin Porotchkin <kostap@marvell.com>
diff --git a/plat/marvell/a8k/common/plat_thermal.c b/plat/marvell/a8k/common/plat_thermal.c
new file mode 100644
index 0000000..02fe820
--- /dev/null
+++ b/plat/marvell/a8k/common/plat_thermal.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <debug.h>
+#include <delay_timer.h>
+#include <mmio.h>
+#include <mvebu_def.h>
+#include <thermal.h>
+
+#define THERMAL_TIMEOUT					1200
+
+#define THERMAL_SEN_CTRL_LSB_STRT_OFFSET		0
+#define THERMAL_SEN_CTRL_LSB_STRT_MASK			\
+				(0x1 << THERMAL_SEN_CTRL_LSB_STRT_OFFSET)
+#define THERMAL_SEN_CTRL_LSB_RST_OFFSET			1
+#define THERMAL_SEN_CTRL_LSB_RST_MASK			\
+				(0x1 << THERMAL_SEN_CTRL_LSB_RST_OFFSET)
+#define THERMAL_SEN_CTRL_LSB_EN_OFFSET			2
+#define THERMAL_SEN_CTRL_LSB_EN_MASK			\
+				(0x1 << THERMAL_SEN_CTRL_LSB_EN_OFFSET)
+
+#define THERMAL_SEN_CTRL_STATS_VALID_OFFSET		16
+#define THERMAL_SEN_CTRL_STATS_VALID_MASK		\
+				(0x1 << THERMAL_SEN_CTRL_STATS_VALID_OFFSET)
+#define THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET		0
+#define THERMAL_SEN_CTRL_STATS_TEMP_OUT_MASK		\
+			(0x3FF << THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET)
+
+#define THERMAL_SEN_OUTPUT_MSB				512
+#define THERMAL_SEN_OUTPUT_COMP				1024
+
+struct tsen_regs {
+	uint32_t ext_tsen_ctrl_lsb;
+	uint32_t ext_tsen_ctrl_msb;
+	uint32_t ext_tsen_status;
+};
+
+static int ext_tsen_probe(struct tsen_config *tsen_cfg)
+{
+	uint32_t reg, timeout = 0;
+	struct tsen_regs *base;
+
+	if (tsen_cfg == NULL && tsen_cfg->regs_base == NULL) {
+		ERROR("initial thermal sensor configuration is missing\n");
+		return -1;
+	}
+	base = (struct tsen_regs *)tsen_cfg->regs_base;
+
+	INFO("initializing thermal sensor\n");
+
+	/* initialize thermal sensor hardware reset once */
+	reg = mmio_read_32((uintptr_t)&base->ext_tsen_ctrl_lsb);
+	reg &= ~THERMAL_SEN_CTRL_LSB_RST_OFFSET; /* de-assert TSEN_RESET */
+	reg |= THERMAL_SEN_CTRL_LSB_EN_MASK; /* set TSEN_EN to 1 */
+	reg |= THERMAL_SEN_CTRL_LSB_STRT_MASK; /* set TSEN_START to 1 */
+	mmio_write_32((uintptr_t)&base->ext_tsen_ctrl_lsb, reg);
+
+	reg = mmio_read_32((uintptr_t)&base->ext_tsen_status);
+	while ((reg & THERMAL_SEN_CTRL_STATS_VALID_MASK) == 0 &&
+	       timeout < THERMAL_TIMEOUT) {
+		udelay(100);
+		reg = mmio_read_32((uintptr_t)&base->ext_tsen_status);
+		timeout++;
+	}
+
+	if ((reg & THERMAL_SEN_CTRL_STATS_VALID_MASK) == 0) {
+		ERROR("thermal sensor is not ready\n");
+		return -1;
+	}
+
+	tsen_cfg->tsen_ready = 1;
+
+	VERBOSE("thermal sensor was initialized\n");
+
+	return 0;
+}
+
+static int ext_tsen_read(struct tsen_config *tsen_cfg, int *temp)
+{
+	uint32_t reg;
+	struct tsen_regs *base;
+
+	if (tsen_cfg == NULL && !tsen_cfg->tsen_ready) {
+		ERROR("thermal sensor was not initialized\n");
+		return -1;
+	}
+	base = (struct tsen_regs *)tsen_cfg->regs_base;
+
+	reg = mmio_read_32((uintptr_t)&base->ext_tsen_status);
+	reg = ((reg & THERMAL_SEN_CTRL_STATS_TEMP_OUT_MASK) >>
+		THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET);
+
+	/*
+	 * TSEN output format is signed as a 2s complement number
+	 * ranging from-512 to +511. when MSB is set, need to
+	 * calculate the complement number
+	 */
+	if (reg >= THERMAL_SEN_OUTPUT_MSB)
+		reg -= THERMAL_SEN_OUTPUT_COMP;
+
+	if (tsen_cfg->tsen_divisor == 0) {
+		ERROR("thermal sensor divisor cannot be zero\n");
+		return -1;
+	}
+
+	*temp = ((tsen_cfg->tsen_gain * ((int)reg)) +
+		 tsen_cfg->tsen_offset) / tsen_cfg->tsen_divisor;
+
+	return 0;
+}
+
+static struct tsen_config tsen_cfg = {
+	.tsen_offset = 153400,
+	.tsen_gain = 425,
+	.tsen_divisor = 1000,
+	.tsen_ready = 0,
+	.regs_base = (void *)MVEBU_AP_EXT_TSEN_BASE,
+	.ptr_tsen_probe = ext_tsen_probe,
+	.ptr_tsen_read = ext_tsen_read
+};
+
+struct tsen_config *marvell_thermal_config_get(void)
+{
+	return &tsen_cfg;
+}