mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-08 06:04:34 +00:00
65e25bea59
In the spirit of using the same base name for all of these related macros, rename this to have the operation at the end. This is not widely used so the impact is fairly small. Signed-off-by: Simon Glass <sjg@chromium.org>
216 lines
4.9 KiB
C
216 lines
4.9 KiB
C
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
|
/*
|
|
* Copyright (C) 2020, STMicroelectronics - All Rights Reserved
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <dm.h>
|
|
#include <asm/io.h>
|
|
#include <asm/arch/ddr.h>
|
|
#include <linux/bitops.h>
|
|
#include <linux/delay.h>
|
|
#include <power/pmic.h>
|
|
#include <power/stpmic1.h>
|
|
|
|
int board_ddr_power_init(enum ddr_type ddr_type)
|
|
{
|
|
struct udevice *dev;
|
|
bool buck3_at_1800000v = false;
|
|
int ret;
|
|
u32 buck2;
|
|
|
|
ret = uclass_get_device_by_driver(UCLASS_PMIC,
|
|
DM_DRIVER_GET(pmic_stpmic1), &dev);
|
|
if (ret)
|
|
/* No PMIC on board */
|
|
return 0;
|
|
|
|
switch (ddr_type) {
|
|
case STM32MP_DDR3:
|
|
/* VTT = Set LDO3 to sync mode */
|
|
ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
ret &= ~STPMIC1_LDO3_MODE;
|
|
ret &= ~STPMIC1_LDO12356_VOUT_MASK;
|
|
ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL);
|
|
|
|
ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
|
|
ret);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
/* VDD_DDR = Set BUCK2 to 1.35V */
|
|
ret = pmic_clrsetbits(dev,
|
|
STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
|
|
STPMIC1_BUCK_VOUT_MASK,
|
|
STPMIC1_BUCK2_1350000V);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
/* Enable VDD_DDR = BUCK2 */
|
|
ret = pmic_clrsetbits(dev,
|
|
STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
|
|
STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
|
|
|
|
/* Enable VREF */
|
|
ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
|
|
STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
|
|
|
|
/* Enable VTT = LDO3 */
|
|
ret = pmic_clrsetbits(dev,
|
|
STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
|
|
STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
|
|
|
|
break;
|
|
|
|
case STM32MP_LPDDR2_16:
|
|
case STM32MP_LPDDR2_32:
|
|
case STM32MP_LPDDR3_16:
|
|
case STM32MP_LPDDR3_32:
|
|
/*
|
|
* configure VDD_DDR1 = LDO3
|
|
* Set LDO3 to 1.8V
|
|
* + bypass mode if BUCK3 = 1.8V
|
|
* + normal mode if BUCK3 != 1.8V
|
|
*/
|
|
ret = pmic_reg_read(dev,
|
|
STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK3));
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
if ((ret & STPMIC1_BUCK3_1800000V) == STPMIC1_BUCK3_1800000V)
|
|
buck3_at_1800000v = true;
|
|
|
|
ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
ret &= ~STPMIC1_LDO3_MODE;
|
|
ret &= ~STPMIC1_LDO12356_VOUT_MASK;
|
|
ret |= STPMIC1_LDO3_1800000;
|
|
if (buck3_at_1800000v)
|
|
ret |= STPMIC1_LDO3_MODE;
|
|
|
|
ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
|
|
ret);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
/* VDD_DDR2 : Set BUCK2 to 1.2V (16bits) or 1.25V (32 bits)*/
|
|
switch (ddr_type) {
|
|
case STM32MP_LPDDR2_32:
|
|
case STM32MP_LPDDR3_32:
|
|
buck2 = STPMIC1_BUCK2_1250000V;
|
|
break;
|
|
default:
|
|
case STM32MP_LPDDR2_16:
|
|
case STM32MP_LPDDR3_16:
|
|
buck2 = STPMIC1_BUCK2_1200000V;
|
|
break;
|
|
}
|
|
|
|
ret = pmic_clrsetbits(dev,
|
|
STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
|
|
STPMIC1_BUCK_VOUT_MASK,
|
|
buck2);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
/* Enable VDD_DDR1 = LDO3 */
|
|
ret = pmic_clrsetbits(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
|
|
STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
|
|
|
|
/* Enable VDD_DDR2 =BUCK2 */
|
|
ret = pmic_clrsetbits(dev,
|
|
STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
|
|
STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
|
|
|
|
/* Enable VREF */
|
|
ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
|
|
STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
};
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int stmpic_buck1_set(struct udevice *dev, u32 voltage_mv)
|
|
{
|
|
u32 value;
|
|
|
|
/* VDDCORE= STMPCI1 BUCK1 ramp=+25mV, 5 => 725mV, 36 => 1500mV */
|
|
value = ((voltage_mv - 725) / 25) + 5;
|
|
if (value < 5)
|
|
value = 5;
|
|
if (value > 36)
|
|
value = 36;
|
|
|
|
return pmic_clrsetbits(dev,
|
|
STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK1),
|
|
STPMIC1_BUCK_VOUT_MASK,
|
|
STPMIC1_BUCK_VOUT(value));
|
|
}
|
|
|
|
/* early init of PMIC */
|
|
void stpmic1_init(u32 voltage_mv)
|
|
{
|
|
struct udevice *dev;
|
|
|
|
if (uclass_get_device_by_driver(UCLASS_PMIC,
|
|
DM_DRIVER_GET(pmic_stpmic1), &dev))
|
|
return;
|
|
|
|
/* update VDDCORE = BUCK1 */
|
|
if (voltage_mv)
|
|
stmpic_buck1_set(dev, voltage_mv);
|
|
|
|
/* Keep vdd on during the reset cycle */
|
|
pmic_clrsetbits(dev,
|
|
STPMIC1_BUCKS_MRST_CR,
|
|
STPMIC1_MRST_BUCK(STPMIC1_BUCK3),
|
|
STPMIC1_MRST_BUCK(STPMIC1_BUCK3));
|
|
|
|
/* Check if debug is enabled to program PMIC according to the bit */
|
|
if (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_DEBUG_ON) {
|
|
printf("Keep debug unit ON\n");
|
|
|
|
pmic_clrsetbits(dev, STPMIC1_BUCKS_MRST_CR,
|
|
STPMIC1_MRST_BUCK_DEBUG,
|
|
STPMIC1_MRST_BUCK_DEBUG);
|
|
|
|
if (STPMIC1_MRST_LDO_DEBUG)
|
|
pmic_clrsetbits(dev, STPMIC1_LDOS_MRST_CR,
|
|
STPMIC1_MRST_LDO_DEBUG,
|
|
STPMIC1_MRST_LDO_DEBUG);
|
|
}
|
|
}
|