summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristine Gharzuzi <chrisg@marvell.com>2018-06-25 13:39:37 +0300
committerKostya Porotchkin <kostap@marvell.com>2018-11-11 13:47:30 +0200
commitd97f56e645964ee716722040c7d6531f553b5510 (patch)
tree336168d4683dfb0b368dc130dd1e120719a52f91
parentf13d6bafc843b2dfba48f584d3ead450c2068aa2 (diff)
ble: ap807: Switch to PLL mode and update CPU frequency
- Update CPU frequency on AP807 to 2GHz for SAR 0x0. - Increase AVS to 0.88V for 2GHz clock Change-Id: Ic945b682ab2f8543e34294bfc56c3eae2c5e0c8e Signed-off-by: Christine Gharzuzi <chrisg@marvell.com> Signed-off-by: Konstantin Porotchkin <kostap@marvell.com> Reviewed-on: http://vgitil04.il.marvell.com:8080/57248 Tested-by: iSoC Platform CI <ykjenk@marvell.com> Reviewed-by: Igal Liberman <igall@marvell.com>
-rw-r--r--drivers/marvell/ap807_clocks_init.c101
-rw-r--r--include/drivers/marvell/ap807_clocks_init.h14
-rw-r--r--plat/marvell/a8k/common/a8k_common.mk1
-rw-r--r--plat/marvell/a8k/common/plat_ble_setup.c110
4 files changed, 163 insertions, 63 deletions
diff --git a/drivers/marvell/ap807_clocks_init.c b/drivers/marvell/ap807_clocks_init.c
new file mode 100644
index 00000000..841e6aeb
--- /dev/null
+++ b/drivers/marvell/ap807_clocks_init.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <a8k_plat_def.h>
+#include <aro.h>
+#include <delay_timer.h>
+#include <mmio.h>
+
+/* Notify bootloader on DRAM setup */
+#define AP807_CPU_ARO_CTRL(cluster) \
+ (MVEBU_RFU_BASE + 0x82A8 + (0xA58 * (cluster)))
+
+/* 0 - ARO clock is enabled, 1 - ARO clock is disabled */
+#define AP807_CPU_ARO_CLK_EN_OFFSET 0
+#define AP807_CPU_ARO_CLK_EN_MASK (0x1 << AP807_CPU_ARO_CLK_EN_OFFSET)
+
+/* 0 - ARO is the clock source, 1 - PLL is the clock source */
+#define AP807_CPU_ARO_SEL_PLL_OFFSET 5
+#define AP807_CPU_ARO_SEL_PLL_MASK (0x1 << AP807_CPU_ARO_SEL_PLL_OFFSET)
+
+/* AP807 clusters count */
+#define AP807_CLUSTER_NUM 2
+
+/* PLL frequency values */
+#define PLL_FREQ_1200 0x2AE5F002 /* 1200 */
+#define PLL_FREQ_2000 0x2FC9F002 /* 2000 */
+#define PLL_FREQ_2200 0x2AC57001 /* 2200 */
+#define PLL_FREQ_2400 0x2AE5F001 /* 2400 */
+
+/* CPU PLL control registers */
+#define AP807_CPU_PLL_CTRL(cluster) \
+ (MVEBU_RFU_BASE + 0x82E0 + (0x8 * (cluster)))
+
+#define AP807_CPU_PLL_PARAM(cluster) AP807_CPU_PLL_CTRL(cluster)
+#define AP807_CPU_PLL_CFG(cluster) (AP807_CPU_PLL_CTRL(cluster) + 0x4)
+#define AP807_CPU_PLL_CFG_BYPASS_MODE (0x1)
+#define AP807_CPU_PLL_CFG_USE_REG_FILE (0x1 << 9)
+
+static void pll_set_freq(unsigned int freq_val)
+{
+ int i;
+
+ for (i = 0 ; i < AP807_CLUSTER_NUM ; i++) {
+ mmio_write_32(AP807_CPU_PLL_CFG(i),
+ AP807_CPU_PLL_CFG_USE_REG_FILE);
+ mmio_write_32(AP807_CPU_PLL_CFG(i),
+ AP807_CPU_PLL_CFG_USE_REG_FILE |
+ AP807_CPU_PLL_CFG_BYPASS_MODE);
+ mmio_write_32(AP807_CPU_PLL_PARAM(i), freq_val);
+ mmio_write_32(AP807_CPU_PLL_CFG(i),
+ AP807_CPU_PLL_CFG_USE_REG_FILE);
+ }
+}
+
+/* Switch to ARO from PLL in ap807 */
+static void aro_to_pll(void)
+{
+ unsigned int reg;
+ int i;
+
+ for (i = 0 ; i < AP807_CLUSTER_NUM ; i++) {
+ /* switch from ARO to PLL */
+ reg = mmio_read_32(AP807_CPU_ARO_CTRL(i));
+ reg |= AP807_CPU_ARO_SEL_PLL_MASK;
+ mmio_write_32(AP807_CPU_ARO_CTRL(i), reg);
+
+ mdelay(100);
+
+ /* disable ARO clk driver */
+ reg = mmio_read_32(AP807_CPU_ARO_CTRL(i));
+ reg |= (AP807_CPU_ARO_CLK_EN_MASK);
+ mmio_write_32(AP807_CPU_ARO_CTRL(i), reg);
+ }
+}
+
+/* switch from ARO to PLL
+ * in case of default frequency option, configure PLL registers
+ * to be aligned with new default frequency.
+ */
+void ap807_clocks_init(unsigned int freq_option)
+{
+ /* Switch from ARO to PLL */
+ aro_to_pll();
+
+ /* Modifications in frequency table:
+ * 0x0: 764x: change to 2000 MHz.
+ * 0x2: 744x change to 1800 MHz, 764x change to 2200/2400.
+ * 0x3: 3900/744x/764x change to 1200 MHz.
+ */
+ switch (freq_option) {
+ case CPU_2000_DDR_1200_RCLK_1200:
+ pll_set_freq(PLL_FREQ_2000);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/include/drivers/marvell/ap807_clocks_init.h b/include/drivers/marvell/ap807_clocks_init.h
new file mode 100644
index 00000000..4353b83e
--- /dev/null
+++ b/include/drivers/marvell/ap807_clocks_init.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef AP807_INIT_CLOCKS_H
+#define AP807_INIT_CLOCKS_H
+
+void ap807_clocks_init(unsigned int freq_option);
+
+#endif /* AP807_INIT_CLOCKS_H */
+
diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk
index 5d52ae77..ba440630 100644
--- a/plat/marvell/a8k/common/a8k_common.mk
+++ b/plat/marvell/a8k/common/a8k_common.mk
@@ -71,6 +71,7 @@ BLE_SOURCES := $(PLAT_COMMON_BASE)/plat_ble_setup.c \
$(MARVELL_DRV_BASE)/i2c/a8k_i2c.c \
$(PLAT_COMMON_BASE)/plat_pm.c \
$(MARVELL_DRV_BASE)/aro.c \
+ $(MARVELL_DRV_BASE)/ap807_clocks_init.c \
$(MARVELL_DRV_BASE)/thermal.c \
$(PLAT_COMMON_BASE)/plat_thermal.c \
$(BLE_PORTING_SOURCES) \
diff --git a/plat/marvell/a8k/common/plat_ble_setup.c b/plat/marvell/a8k/common/plat_ble_setup.c
index 5f6950e2..d8dbc2e8 100644
--- a/plat/marvell/a8k/common/plat_ble_setup.c
+++ b/plat/marvell/a8k/common/plat_ble_setup.c
@@ -16,6 +16,7 @@
#include <mv_ddr_if.h>
#include <mvebu_def.h>
#include <plat_marvell.h>
+#include "ap807_clocks_init.h"
/* Register for skip image use */
#define SCRATCH_PAD_REG2 0xF06F00A8
@@ -82,21 +83,16 @@
(0x1 << AVS_SOFT_RESET_OFFSET) | \
(0x1 << AVS_ENABLE_OFFSET))
+#define AVS_A3900_HIGH_CLK_VALUE ((0x80 << 24) | \
+ (0x2f5 << 13) | \
+ (0x2f5 << 3) | \
+ (0x1 << AVS_SOFT_RESET_OFFSET) | \
+ (0x1 << AVS_ENABLE_OFFSET))
+
#define MVEBU_AP_EFUSE_SRV_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x8)
#define EFUSE_SRV_CTRL_LD_SELECT_OFFS 6
#define EFUSE_SRV_CTRL_LD_SEL_USER_MASK (1 << EFUSE_SRV_CTRL_LD_SELECT_OFFS)
-/* Notify bootloader on DRAM setup */
-#define AP807_CPU_ARO_0_CTRL_0 (MVEBU_RFU_BASE + 0x82A8)
-#define AP807_CPU_ARO_1_CTRL_0 (MVEBU_RFU_BASE + 0x8D00)
-
-/* 0 - ARO clock is enabled, 1 - ARO clock is disabled */
-#define AP807_CPU_ARO_CLK_EN_OFFSET 0
-#define AP807_CPU_ARO_CLK_EN_MASK (0x1 << AP807_CPU_ARO_CLK_EN_OFFSET)
-
-/* 0 - ARO is the clock source, 1 - PLL is the clock source */
-#define AP807_CPU_ARO_SEL_PLL_OFFSET 5
-#define AP807_CPU_ARO_SEL_PLL_MASK (0x1 << AP807_CPU_ARO_SEL_PLL_OFFSET)
/*
* - Identification information in the LD-0 eFuse:
@@ -211,37 +207,44 @@ static void ble_plat_mmap_config(int restore)
*/
static void ble_plat_avs_config(void)
{
- uint32_t reg_val, device_id;
+ uint32_t freq_mode, device_id;
+ uint32_t avs_val = 0;
+ freq_mode =
+ SAR_CLOCK_FREQ_MODE(mmio_read_32(MVEBU_AP_SAR_REG_BASE(
+ FREQ_MODE_AP_SAR_REG_NUM)));
/* Due to a bug in A3900 device_id we need a special handling here */
if (ble_get_ap_type() == CHIP_ID_AP807) {
- VERBOSE("AVS: Setting AP807 AVS CTRL to 0x%x\n",
- AVS_A3900_CLK_VALUE);
- mmio_write_32(AVS_EN_CTRL_REG, AVS_A3900_CLK_VALUE);
- return;
+ /* Increase CPU voltage for higher CPU clock */
+ if (freq_mode == CPU_2000_DDR_1200_RCLK_1200)
+ avs_val = AVS_A3900_HIGH_CLK_VALUE;
+ else
+ avs_val = AVS_A3900_CLK_VALUE;
+ } else {
+ /* Check which SoC is running and act accordingly */
+ device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0));
+ switch (device_id) {
+ case MVEBU_80X0_DEV_ID:
+ case MVEBU_80X0_CP115_DEV_ID:
+ /* Fix the default AVS value on A80x0 */
+ avs_val = AVS_A8K_CLK_VALUE;
+ break;
+ case MVEBU_70X0_DEV_ID:
+ case MVEBU_70X0_CP115_DEV_ID:
+ /* Only fix AVS for CPU clocks lower than 1600MHz */
+ if ((freq_mode > CPU_1600_DDR_900_RCLK_900_2) &&
+ (freq_mode < CPU_DDR_RCLK_INVALID))
+ avs_val = AVS_A7K_LOW_CLK_VALUE;
+ break;
+ default:
+ ERROR("Unsupported Device ID 0x%x\n", device_id);
+ return;
+ }
}
- /* Check which SoC is running and act accordingly */
- device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0));
- switch (device_id) {
- case MVEBU_80X0_DEV_ID:
- case MVEBU_80X0_CP115_DEV_ID:
- /* Set the new AVS value - fix the default one on A80x0 */
- mmio_write_32(AVS_EN_CTRL_REG, AVS_A8K_CLK_VALUE);
- break;
- case MVEBU_70X0_DEV_ID:
- case MVEBU_70X0_CP115_DEV_ID:
- /* Only fix AVS for CPU clocks lower than 1600MHz on A70x0 */
- reg_val = mmio_read_32(MVEBU_AP_SAR_REG_BASE(
- FREQ_MODE_AP_SAR_REG_NUM));
- reg_val &= SAR_CLOCK_FREQ_MODE_MASK;
- reg_val >>= SAR_CLOCK_FREQ_MODE_OFFSET;
- if ((reg_val > CPU_1600_DDR_900_RCLK_900_2) &&
- (reg_val < CPU_DDR_RCLK_INVALID))
- mmio_write_32(AVS_EN_CTRL_REG, AVS_A7K_LOW_CLK_VALUE);
- break;
- default:
- ERROR("Unsupported Device ID 0x%x\n", device_id);
+ if (avs_val) {
+ VERBOSE("AVS: Setting AVS CTRL to 0x%x\n", avs_val);
+ mmio_write_32(AVS_EN_CTRL_REG, avs_val);
}
}
@@ -609,35 +612,11 @@ static int ble_skip_current_image(void)
}
#endif
-/* Switch to ARO from PLL in ap807 */
-static void aro_to_pll(void)
-{
- unsigned int reg;
-
- /* switch from ARO to PLL */
- reg = mmio_read_32(AP807_CPU_ARO_0_CTRL_0);
- reg |= AP807_CPU_ARO_SEL_PLL_MASK;
- mmio_write_32(AP807_CPU_ARO_0_CTRL_0, reg);
-
- reg = mmio_read_32(AP807_CPU_ARO_1_CTRL_0);
- reg |= AP807_CPU_ARO_SEL_PLL_MASK;
- mmio_write_32(AP807_CPU_ARO_1_CTRL_0, reg);
-
- mdelay(1000);
-
- /* disable ARO clk driver */
- reg = mmio_read_32(AP807_CPU_ARO_0_CTRL_0);
- reg |= (AP807_CPU_ARO_CLK_EN_MASK);
- mmio_write_32(AP807_CPU_ARO_0_CTRL_0, reg);
-
- reg = mmio_read_32(AP807_CPU_ARO_1_CTRL_0);
- reg |= (AP807_CPU_ARO_CLK_EN_MASK);
- mmio_write_32(AP807_CPU_ARO_1_CTRL_0, reg);
-}
int ble_plat_setup(int *skip)
{
int ret;
+ unsigned int freq_mode;
/* Power down unused CPUs */
plat_marvell_early_cpu_powerdown();
@@ -664,9 +643,14 @@ int ble_plat_setup(int *skip)
/* Setup AVS */
ble_plat_svc_config();
+ /* read clk option from sampled-at-reset register */
+ freq_mode =
+ SAR_CLOCK_FREQ_MODE(mmio_read_32(MVEBU_AP_SAR_REG_BASE(
+ FREQ_MODE_AP_SAR_REG_NUM)));
+
/* work with PLL clock driver in AP807 */
if (ble_get_ap_type() == CHIP_ID_AP807)
- aro_to_pll();
+ ap807_clocks_init(freq_mode);
#if ARO_ENABLE
init_aro();