diff options
author | Christine Gharzuzi <chrisg@marvell.com> | 2018-06-25 13:39:37 +0300 |
---|---|---|
committer | Kostya Porotchkin <kostap@marvell.com> | 2018-11-11 13:47:30 +0200 |
commit | d97f56e645964ee716722040c7d6531f553b5510 (patch) | |
tree | 336168d4683dfb0b368dc130dd1e120719a52f91 | |
parent | f13d6bafc843b2dfba48f584d3ead450c2068aa2 (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.c | 101 | ||||
-rw-r--r-- | include/drivers/marvell/ap807_clocks_init.h | 14 | ||||
-rw-r--r-- | plat/marvell/a8k/common/a8k_common.mk | 1 | ||||
-rw-r--r-- | plat/marvell/a8k/common/plat_ble_setup.c | 110 |
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(); |