Unverified Commit fbf35335 authored by Antonio Niño Díaz's avatar Antonio Niño Díaz Committed by GitHub
Browse files

Merge pull request #1767 from Yann-lms/updates_stm32mp1

Updates for STM32MP1
parents f0bfe15b 7747356d
/*
* Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <limits.h>
#include <libfdt.h>
#include <platform_def.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/st/bsec.h>
#include <lib/mmio.h>
#include <lib/spinlock.h>
#define BSEC_IP_VERSION_1_0 0x10
#define BSEC_COMPAT "st,stm32mp15-bsec"
#define OTP_ACCESS_SIZE (round_up(OTP_MAX_SIZE, __WORD_BIT) / __WORD_BIT)
static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __unused;
static uint32_t bsec_power_safmem(bool power);
/* BSEC access protection */
static spinlock_t bsec_spinlock;
static uintptr_t bsec_base;
static void bsec_lock(void)
{
const uint32_t mask = SCTLR_M_BIT | SCTLR_C_BIT;
/* Lock is currently required only when MMU and cache are enabled */
if ((read_sctlr() & mask) == mask) {
spin_lock(&bsec_spinlock);
}
}
static void bsec_unlock(void)
{
const uint32_t mask = SCTLR_M_BIT | SCTLR_C_BIT;
/* Unlock is required only when MMU and cache are enabled */
if ((read_sctlr() & mask) == mask) {
spin_unlock(&bsec_spinlock);
}
}
static int bsec_get_dt_node(struct dt_node_info *info)
{
int node;
node = dt_get_node(info, -1, BSEC_COMPAT);
if (node < 0) {
return -FDT_ERR_NOTFOUND;
}
return node;
}
#if defined(IMAGE_BL32)
static void enable_non_secure_access(uint32_t otp)
{
otp_nsec_access[otp / __WORD_BIT] |= BIT(otp % __WORD_BIT);
if (bsec_shadow_register(otp) != BSEC_OK) {
panic();
}
}
static bool non_secure_can_access(uint32_t otp)
{
return (otp_nsec_access[otp / __WORD_BIT] &
BIT(otp % __WORD_BIT)) != 0;
}
static int bsec_dt_otp_nsec_access(void *fdt, int bsec_node)
{
int bsec_subnode;
fdt_for_each_subnode(bsec_subnode, fdt, bsec_node) {
const fdt32_t *cuint;
uint32_t reg;
uint32_t i;
uint32_t size;
uint8_t status;
cuint = fdt_getprop(fdt, bsec_subnode, "reg", NULL);
if (cuint == NULL) {
panic();
}
reg = fdt32_to_cpu(*cuint) / sizeof(uint32_t);
if (reg < STM32MP1_UPPER_OTP_START) {
continue;
}
status = fdt_get_status(bsec_subnode);
if ((status & DT_NON_SECURE) == 0U) {
continue;
}
size = fdt32_to_cpu(*(cuint + 1)) / sizeof(uint32_t);
if ((fdt32_to_cpu(*(cuint + 1)) % sizeof(uint32_t)) != 0) {
size++;
}
for (i = reg; i < (reg + size); i++) {
enable_non_secure_access(i);
}
}
return 0;
}
#endif
static uint32_t otp_bank_offset(uint32_t otp)
{
assert(otp <= STM32MP1_OTP_MAX_ID);
return ((otp & ~BSEC_OTP_MASK) >> BSEC_OTP_BANK_SHIFT) *
sizeof(uint32_t);
}
static uint32_t bsec_check_error(uint32_t otp)
{
uint32_t bit = BIT(otp & BSEC_OTP_MASK);
uint32_t bank = otp_bank_offset(otp);
if ((mmio_read_32(bsec_base + BSEC_DISTURBED_OFF + bank) & bit) != 0U) {
return BSEC_DISTURBED;
}
if ((mmio_read_32(bsec_base + BSEC_ERROR_OFF + bank) & bit) != 0U) {
return BSEC_ERROR;
}
return BSEC_OK;
}
/*
* bsec_probe: initialize BSEC driver.
* return value: BSEC_OK if no error.
*/
uint32_t bsec_probe(void)
{
void *fdt;
int node;
struct dt_node_info bsec_info;
if (fdt_get_address(&fdt) == 0) {
panic();
}
node = bsec_get_dt_node(&bsec_info);
if (node < 0) {
panic();
}
bsec_base = bsec_info.base;
#if defined(IMAGE_BL32)
bsec_dt_otp_nsec_access(fdt, node);
#endif
return BSEC_OK;
}
/*
* bsec_get_base: return BSEC base address.
*/
uint32_t bsec_get_base(void)
{
return bsec_base;
}
/*
* bsec_set_config: enable and configure BSEC.
* cfg: pointer to param structure used to set register.
* return value: BSEC_OK if no error.
*/
uint32_t bsec_set_config(struct bsec_config *cfg)
{
uint32_t value;
int32_t result;
value = ((((uint32_t)cfg->freq << BSEC_CONF_FRQ_SHIFT) &
BSEC_CONF_FRQ_MASK) |
(((uint32_t)cfg->pulse_width << BSEC_CONF_PRG_WIDTH_SHIFT) &
BSEC_CONF_PRG_WIDTH_MASK) |
(((uint32_t)cfg->tread << BSEC_CONF_TREAD_SHIFT) &
BSEC_CONF_TREAD_MASK));
bsec_lock();
mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, value);
bsec_unlock();
result = bsec_power_safmem((bool)cfg->power &
BSEC_CONF_POWER_UP_MASK);
if (result != BSEC_OK) {
return result;
}
value = ((((uint32_t)cfg->upper_otp_lock << UPPER_OTP_LOCK_SHIFT) &
UPPER_OTP_LOCK_MASK) |
(((uint32_t)cfg->den_lock << DENREG_LOCK_SHIFT) &
DENREG_LOCK_MASK) |
(((uint32_t)cfg->prog_lock << GPLOCK_LOCK_SHIFT) &
GPLOCK_LOCK_MASK));
bsec_lock();
mmio_write_32(bsec_base + BSEC_OTP_LOCK_OFF, value);
bsec_unlock();
return BSEC_OK;
}
/*
* bsec_get_config: return config parameters set in BSEC registers.
* cfg: config param return.
* return value: BSEC_OK if no error.
*/
uint32_t bsec_get_config(struct bsec_config *cfg)
{
uint32_t value;
if (cfg == NULL) {
return BSEC_INVALID_PARAM;
}
value = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
cfg->power = (uint8_t)((value & BSEC_CONF_POWER_UP_MASK) >>
BSEC_CONF_POWER_UP_SHIFT);
cfg->freq = (uint8_t)((value & BSEC_CONF_FRQ_MASK) >>
BSEC_CONF_FRQ_SHIFT);
cfg->pulse_width = (uint8_t)((value & BSEC_CONF_PRG_WIDTH_MASK) >>
BSEC_CONF_PRG_WIDTH_SHIFT);
cfg->tread = (uint8_t)((value & BSEC_CONF_TREAD_MASK) >>
BSEC_CONF_TREAD_SHIFT);
value = mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF);
cfg->upper_otp_lock = (uint8_t)((value & UPPER_OTP_LOCK_MASK) >>
UPPER_OTP_LOCK_SHIFT);
cfg->den_lock = (uint8_t)((value & DENREG_LOCK_MASK) >>
DENREG_LOCK_SHIFT);
cfg->prog_lock = (uint8_t)((value & GPLOCK_LOCK_MASK) >>
GPLOCK_LOCK_SHIFT);
return BSEC_OK;
}
/*
* bsec_shadow_register: copy SAFMEM OTP to BSEC data.
* otp: OTP number.
* return value: BSEC_OK if no error.
*/
uint32_t bsec_shadow_register(uint32_t otp)
{
uint32_t result;
bool power_up = false;
if (otp > STM32MP1_OTP_MAX_ID) {
return BSEC_INVALID_PARAM;
}
/* Check if shadowing of OTP is locked */
if (bsec_read_sr_lock(otp)) {
VERBOSE("BSEC: OTP %i is locked and will not be refreshed\n",
otp);
}
if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
result = bsec_power_safmem(true);
if (result != BSEC_OK) {
return result;
}
power_up = true;
}
bsec_lock();
/* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_READ);
while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
;
}
result = bsec_check_error(otp);
bsec_unlock();
if (power_up) {
if (bsec_power_safmem(false) != BSEC_OK) {
panic();
}
}
return result;
}
/*
* bsec_read_otp: read an OTP data value.
* val: read value.
* otp: OTP number.
* return value: BSEC_OK if no error.
*/
uint32_t bsec_read_otp(uint32_t *val, uint32_t otp)
{
uint32_t result;
if (otp > STM32MP1_OTP_MAX_ID) {
return BSEC_INVALID_PARAM;
}
bsec_lock();
*val = mmio_read_32(bsec_base + BSEC_OTP_DATA_OFF +
(otp * sizeof(uint32_t)));
result = bsec_check_error(otp);
bsec_unlock();
return result;
}
/*
* bsec_write_otp: write value in BSEC data register.
* val: value to write.
* otp: OTP number.
* return value: BSEC_OK if no error.
*/
uint32_t bsec_write_otp(uint32_t val, uint32_t otp)
{
uint32_t result;
if (otp > STM32MP1_OTP_MAX_ID) {
return BSEC_INVALID_PARAM;
}
/* Check if programming of OTP is locked */
if (bsec_read_sw_lock(otp)) {
VERBOSE("BSEC: OTP %i is locked and write will be ignored\n",
otp);
}
bsec_lock();
mmio_write_32(bsec_base + BSEC_OTP_DATA_OFF +
(otp * sizeof(uint32_t)), val);
result = bsec_check_error(otp);
bsec_unlock();
return result;
}
/*
* bsec_program_otp: program a bit in SAFMEM after the prog.
* The OTP data is not refreshed.
* val: value to program.
* otp: OTP number.
* return value: BSEC_OK if no error.
*/
uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
{
uint32_t result;
bool power_up = false;
if (otp > STM32MP1_OTP_MAX_ID) {
return BSEC_INVALID_PARAM;
}
/* Check if programming of OTP is locked */
if (bsec_read_sp_lock(otp)) {
WARN("BSEC: OTP locked, prog will be ignored\n");
}
if ((mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF) &
BIT(BSEC_LOCK_PROGRAM)) != 0U) {
WARN("BSEC: GPLOCK activated, prog will be ignored\n");
}
if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
result = bsec_power_safmem(true);
if (result != BSEC_OK) {
return result;
}
power_up = true;
}
bsec_lock();
/* Set value in write register */
mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, val);
/* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE);
while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
;
}
if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
result = BSEC_PROG_FAIL;
} else {
result = bsec_check_error(otp);
}
bsec_unlock();
if (power_up) {
if (bsec_power_safmem(false) != BSEC_OK) {
panic();
}
}
return result;
}
/*
* bsec_permanent_lock_otp: permanent lock of OTP in SAFMEM.
* otp: OTP number.
* return value: BSEC_OK if no error.
*/
uint32_t bsec_permanent_lock_otp(uint32_t otp)
{
uint32_t result;
bool power_up = false;
uint32_t data;
uint32_t addr;
if (otp > STM32MP1_OTP_MAX_ID) {
return BSEC_INVALID_PARAM;
}
if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
result = bsec_power_safmem(true);
if (result != BSEC_OK) {
return result;
}
power_up = true;
}
if (otp < STM32MP1_UPPER_OTP_START) {
addr = otp >> ADDR_LOWER_OTP_PERLOCK_SHIFT;
data = DATA_LOWER_OTP_PERLOCK_BIT <<
((otp & DATA_LOWER_OTP_PERLOCK_MASK) << 1U);
} else {
addr = (otp >> ADDR_UPPER_OTP_PERLOCK_SHIFT) + 2U;
data = DATA_UPPER_OTP_PERLOCK_BIT <<
(otp & DATA_UPPER_OTP_PERLOCK_MASK);
}
bsec_lock();
/* Set value in write register */
mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, data);
/* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF,
addr | BSEC_WRITE | BSEC_LOCK);
while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
;
}
if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
result = BSEC_PROG_FAIL;
} else {
result = bsec_check_error(otp);
}
bsec_unlock();
if (power_up) {
if (bsec_power_safmem(false) != BSEC_OK) {
panic();
}
}
return result;
}
/*
* bsec_write_debug_conf: write value in debug feature
* to enable/disable debug service.
* val: value to write.
* return value: BSEC_OK if no error.
*/
uint32_t bsec_write_debug_conf(uint32_t val)
{
uint32_t result = BSEC_ERROR;
uint32_t masked_val = val & BSEC_DEN_ALL_MSK;
bsec_lock();
mmio_write_32(bsec_base + BSEC_DEN_OFF, masked_val);
if ((mmio_read_32(bsec_base + BSEC_DEN_OFF) ^ masked_val) == 0U) {
result = BSEC_OK;
}
bsec_unlock();
return result;
}
/*
* bsec_read_debug_conf: read debug configuration.
*/
uint32_t bsec_read_debug_conf(void)
{
return mmio_read_32(bsec_base + BSEC_DEN_OFF);
}
/*
* bsec_get_status: return status register value.
*/
uint32_t bsec_get_status(void)
{
return mmio_read_32(bsec_base + BSEC_OTP_STATUS_OFF);
}
/*
* bsec_get_hw_conf: return hardware configuration.
*/
uint32_t bsec_get_hw_conf(void)
{
return mmio_read_32(bsec_base + BSEC_IPHW_CFG_OFF);
}
/*
* bsec_get_version: return BSEC version.
*/
uint32_t bsec_get_version(void)
{
return mmio_read_32(bsec_base + BSEC_IPVR_OFF);
}
/*
* bsec_get_id: return BSEC ID.
*/
uint32_t bsec_get_id(void)
{
return mmio_read_32(bsec_base + BSEC_IP_ID_OFF);
}
/*
* bsec_get_magic_id: return BSEC magic number.
*/
uint32_t bsec_get_magic_id(void)
{
return mmio_read_32(bsec_base + BSEC_IP_MAGIC_ID_OFF);
}
/*
* bsec_write_sr_lock: write shadow-read lock.
* otp: OTP number.
* value: value to write in the register.
* Must be always 1.
* return: true if OTP is locked, else false.
*/
bool bsec_write_sr_lock(uint32_t otp, uint32_t value)
{
bool result = false;
uint32_t bank = otp_bank_offset(otp);
uint32_t bank_value;
uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
bsec_lock();
bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
if ((bank_value & otp_mask) == value) {
/*
* In case of write don't need to write,
* the lock is already set.
*/
if (value != 0U) {
result = true;
}
} else {
if (value != 0U) {
bank_value = bank_value | otp_mask;
} else {
bank_value = bank_value & ~otp_mask;
}
/*
* We can write 0 in all other OTP
* if the lock is activated in one of other OTP.
* Write 0 has no effect.
*/
mmio_write_32(bsec_base + BSEC_SRLOCK_OFF + bank, bank_value);
result = true;
}
bsec_unlock();
return result;
}
/*
* bsec_read_sr_lock: read shadow-read lock.
* otp: OTP number.
* return: true if otp is locked, else false.
*/
bool bsec_read_sr_lock(uint32_t otp)
{
uint32_t bank = otp_bank_offset(otp);
uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
return (bank_value & otp_mask) != 0U;
}
/*
* bsec_write_sw_lock: write shadow-write lock.
* otp: OTP number.
* value: Value to write in the register.
* Must be always 1.
* return: true if OTP is locked, else false.
*/
bool bsec_write_sw_lock(uint32_t otp, uint32_t value)
{
bool result = false;
uint32_t bank = otp_bank_offset(otp);
uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
uint32_t bank_value;
bsec_lock();
bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
if ((bank_value & otp_mask) == value) {
/*
* In case of write don't need to write,
* the lock is already set.
*/
if (value != 0U) {
result = true;
}
} else {
if (value != 0U) {
bank_value = bank_value | otp_mask;
} else {
bank_value = bank_value & ~otp_mask;
}
/*
* We can write 0 in all other OTP
* if the lock is activated in one of other OTP.
* Write 0 has no effect.
*/
mmio_write_32(bsec_base + BSEC_SWLOCK_OFF + bank, bank_value);
result = true;
}
bsec_unlock();
return result;
}
/*
* bsec_read_sw_lock: read shadow-write lock.
* otp: OTP number.
* return: true if OTP is locked, else false.
*/
bool bsec_read_sw_lock(uint32_t otp)
{
uint32_t bank = otp_bank_offset(otp);
uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
return (bank_value & otp_mask) != 0U;
}
/*
* bsec_write_sp_lock: write shadow-program lock.
* otp: OTP number.
* value: Value to write in the register.
* Must be always 1.
* return: true if OTP is locked, else false.
*/
bool bsec_write_sp_lock(uint32_t otp, uint32_t value)
{
bool result = false;
uint32_t bank = otp_bank_offset(otp);
uint32_t bank_value;
uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
bsec_lock();
bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
if ((bank_value & otp_mask) == value) {
/*
* In case of write don't need to write,
* the lock is already set.
*/
if (value != 0U) {
result = true;
}
} else {
if (value != 0U) {
bank_value = bank_value | otp_mask;
} else {
bank_value = bank_value & ~otp_mask;
}
/*
* We can write 0 in all other OTP
* if the lock is activated in one of other OTP.
* Write 0 has no effect.
*/
mmio_write_32(bsec_base + BSEC_SPLOCK_OFF + bank, bank_value);
result = true;
}
bsec_unlock();
return result;
}
/*
* bsec_read_sp_lock: read shadow-program lock.
* otp: OTP number.
* return: true if OTP is locked, else false.
*/
bool bsec_read_sp_lock(uint32_t otp)
{
uint32_t bank = otp_bank_offset(otp);
uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
return (bank_value & otp_mask) != 0U;
}
/*
* bsec_wr_lock: Read permanent lock status.
* otp: OTP number.
* return: true if OTP is locked, else false.
*/
bool bsec_wr_lock(uint32_t otp)
{
uint32_t bank = otp_bank_offset(otp);
uint32_t lock_bit = BIT(otp & BSEC_OTP_MASK);
if ((mmio_read_32(bsec_base + BSEC_WRLOCK_OFF + bank) &
lock_bit) != 0U) {
/*
* In case of write don't need to write,
* the lock is already set.
*/
return true;
}
return false;
}
/*
* bsec_otp_lock: Lock Upper OTP or Global programming or debug enable
* service: Service to lock see header file.
* value: Value to write must always set to 1 (only use for debug purpose).
* return: BSEC_OK if succeed.
*/
uint32_t bsec_otp_lock(uint32_t service, uint32_t value)
{
uintptr_t reg = bsec_base + BSEC_OTP_LOCK_OFF;
switch (service) {
case BSEC_LOCK_UPPER_OTP:
mmio_write_32(reg, value << BSEC_LOCK_UPPER_OTP);
break;
case BSEC_LOCK_DEBUG:
mmio_write_32(reg, value << BSEC_LOCK_DEBUG);
break;
case BSEC_LOCK_PROGRAM:
mmio_write_32(reg, value << BSEC_LOCK_PROGRAM);
break;
default:
return BSEC_INVALID_PARAM;
}
return BSEC_OK;
}
/*
* bsec_power_safmem: Activate or deactivate SAFMEM power.
* power: true to power up, false to power down.
* return: BSEC_OK if succeed.
*/
static uint32_t bsec_power_safmem(bool power)
{
uint32_t register_val;
uint32_t timeout = BSEC_TIMEOUT_VALUE;
bsec_lock();
register_val = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
if (power) {
register_val |= BSEC_CONF_POWER_UP_MASK;
} else {
register_val &= ~BSEC_CONF_POWER_UP_MASK;
}
mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, register_val);
/* Waiting loop */
if (power) {
while (((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) &&
(timeout != 0U)) {
timeout--;
}
} else {
while (((bsec_get_status() & BSEC_MODE_PWR_MASK) != 0U) &&
(timeout != 0U)) {
timeout--;
}
}
bsec_unlock();
if (timeout == 0U) {
return BSEC_TIMEOUT;
}
return BSEC_OK;
}
/*
* bsec_mode_is_closed_device: read OTP secure sub-mode.
* return: false if open_device and true of closed_device.
*/
bool bsec_mode_is_closed_device(void)
{
uint32_t value;
if ((bsec_shadow_register(DATA0_OTP) != BSEC_OK) ||
(bsec_read_otp(&value, DATA0_OTP) != BSEC_OK)) {
return true;
}
return (value & DATA0_OTP_SECURED) == DATA0_OTP_SECURED;
}
/*
* bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value
* otp_value: read value.
* word: OTP number.
* return value: BSEC_OK if no error.
*/
uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word)
{
uint32_t result;
result = bsec_shadow_register(word);
if (result != BSEC_OK) {
ERROR("BSEC: %u Shadowing Error %i\n", word, result);
return result;
}
result = bsec_read_otp(otp_value, word);
if (result != BSEC_OK) {
ERROR("BSEC: %u Read Error %i\n", word, result);
}
return result;
}
/*
* bsec_check_nsec_access_rights: check non-secure access rights to target OTP.
* otp: OTP number.
* return: BSEC_OK if authorized access.
*/
uint32_t bsec_check_nsec_access_rights(uint32_t otp)
{
#if defined(IMAGE_BL32)
if (otp > STM32MP1_OTP_MAX_ID) {
return BSEC_INVALID_PARAM;
}
if (otp >= STM32MP1_UPPER_OTP_START) {
/* Check if BSEC is in OTP-SECURED closed_device state. */
if (bsec_mode_is_closed_device()) {
if (!non_secure_can_access(otp)) {
return BSEC_ERROR;
}
}
}
#endif
return BSEC_OK;
}
/* /*
* Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -31,11 +31,19 @@ const char *stm32mp_osc_node_label[NB_OSC] = { ...@@ -31,11 +31,19 @@ const char *stm32mp_osc_node_label[NB_OSC] = {
[_USB_PHY_48] = "ck_usbo_48m" [_USB_PHY_48] = "ck_usbo_48m"
}; };
/*******************************************************************************
* This function returns the RCC node in the device tree.
******************************************************************************/
static int fdt_get_rcc_node(void *fdt)
{
return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
}
/******************************************************************************* /*******************************************************************************
* This function reads the frequency of an oscillator from its name. * This function reads the frequency of an oscillator from its name.
* It reads the value indicated inside the device tree. * It reads the value indicated inside the device tree.
* Returns 0 if success, and a negative value else. * Returns 0 on success, and a negative FDT/ERRNO error code on failure.
* If success, value is stored in the second parameter. * On success, value is stored in the second parameter.
******************************************************************************/ ******************************************************************************/
int fdt_osc_read_freq(const char *name, uint32_t *freq) int fdt_osc_read_freq(const char *name, uint32_t *freq)
{ {
...@@ -127,7 +135,7 @@ bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name) ...@@ -127,7 +135,7 @@ bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name)
/******************************************************************************* /*******************************************************************************
* This function reads a value of a oscillator property from its id. * This function reads a value of a oscillator property from its id.
* Returns value if success, and a default value if property not found. * Returns value on success, and a default value if property not found.
* Default value is passed as parameter. * Default value is passed as parameter.
******************************************************************************/ ******************************************************************************/
uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
...@@ -240,7 +248,7 @@ int fdt_rcc_read_uint32_array(const char *prop_name, ...@@ -240,7 +248,7 @@ int fdt_rcc_read_uint32_array(const char *prop_name,
/******************************************************************************* /*******************************************************************************
* This function gets the subnode offset in rcc-clk section from its name. * This function gets the subnode offset in rcc-clk section from its name.
* It reads the values indicated inside the device tree. * It reads the values indicated inside the device tree.
* Returns offset if success, and a negative value else. * Returns offset on success, and a negative FDT/ERRNO error code on failure.
******************************************************************************/ ******************************************************************************/
int fdt_rcc_subnode_offset(const char *name) int fdt_rcc_subnode_offset(const char *name)
{ {
...@@ -251,7 +259,7 @@ int fdt_rcc_subnode_offset(const char *name) ...@@ -251,7 +259,7 @@ int fdt_rcc_subnode_offset(const char *name)
return -ENOENT; return -ENOENT;
} }
node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); node = fdt_get_rcc_node(fdt);
if (node < 0) { if (node < 0) {
return -FDT_ERR_NOTFOUND; return -FDT_ERR_NOTFOUND;
} }
...@@ -280,7 +288,7 @@ const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp) ...@@ -280,7 +288,7 @@ const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
return NULL; return NULL;
} }
node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); node = fdt_get_rcc_node(fdt);
if (node < 0) { if (node < 0) {
return NULL; return NULL;
} }
...@@ -297,7 +305,7 @@ const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp) ...@@ -297,7 +305,7 @@ const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
/******************************************************************************* /*******************************************************************************
* This function gets the secure status for rcc node. * This function gets the secure status for rcc node.
* It reads secure-status in device tree. * It reads secure-status in device tree.
* Returns 1 if rcc is available from secure world, 0 else. * Returns true if rcc is available from secure world, false if not.
******************************************************************************/ ******************************************************************************/
bool fdt_get_rcc_secure_status(void) bool fdt_get_rcc_secure_status(void)
{ {
...@@ -308,18 +316,18 @@ bool fdt_get_rcc_secure_status(void) ...@@ -308,18 +316,18 @@ bool fdt_get_rcc_secure_status(void)
return false; return false;
} }
node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_COMPAT); node = fdt_get_rcc_node(fdt);
if (node < 0) { if (node < 0) {
return false; return false;
} }
return fdt_check_secure_status(node); return (fdt_get_status(node) & DT_SECURE) != 0U;
} }
/******************************************************************************* /*******************************************************************************
* This function reads the stgen base address. * This function reads the stgen base address.
* It reads the value indicated inside the device tree. * It reads the value indicated inside the device tree.
* Returns address if success, and NULL value else. * Returns address on success, and NULL value on failure.
******************************************************************************/ ******************************************************************************/
uintptr_t fdt_get_stgen_base(void) uintptr_t fdt_get_stgen_base(void)
{ {
...@@ -347,7 +355,7 @@ uintptr_t fdt_get_stgen_base(void) ...@@ -347,7 +355,7 @@ uintptr_t fdt_get_stgen_base(void)
/******************************************************************************* /*******************************************************************************
* This function gets the clock ID of the given node. * This function gets the clock ID of the given node.
* It reads the value indicated inside the device tree. * It reads the value indicated inside the device tree.
* Returns ID if success, and a negative value else. * Returns ID on success, and a negative FDT/ERRNO error code on failure.
******************************************************************************/ ******************************************************************************/
int fdt_get_clock_id(int node) int fdt_get_clock_id(int node)
{ {
......
/* /*
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
* *
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/ */
#include <errno.h>
#include <stddef.h> #include <stddef.h>
#include <platform_def.h> #include <platform_def.h>
...@@ -12,10 +13,10 @@ ...@@ -12,10 +13,10 @@
#include <arch_helpers.h> #include <arch_helpers.h>
#include <common/debug.h> #include <common/debug.h>
#include <drivers/delay_timer.h> #include <drivers/delay_timer.h>
#include <drivers/st/stm32mp_pmic.h>
#include <drivers/st/stm32mp1_clk.h> #include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_ddr.h> #include <drivers/st/stm32mp1_ddr.h>
#include <drivers/st/stm32mp1_ddr_regs.h> #include <drivers/st/stm32mp1_ddr_regs.h>
#include <drivers/st/stm32mp1_pmic.h>
#include <drivers/st/stm32mp1_pwr.h> #include <drivers/st/stm32mp1_pwr.h>
#include <drivers/st/stm32mp1_ram.h> #include <drivers/st/stm32mp1_ram.h>
#include <drivers/st/stm32mp1_rcc.h> #include <drivers/st/stm32mp1_rcc.h>
...@@ -233,40 +234,67 @@ struct ddr_reg_info { ...@@ -233,40 +234,67 @@ struct ddr_reg_info {
static const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = { static const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = {
[REG_REG] = { [REG_REG] = {
"static", ddr_reg, ARRAY_SIZE(ddr_reg), DDR_BASE .name = "static",
.desc = ddr_reg,
.size = ARRAY_SIZE(ddr_reg),
.base = DDR_BASE
}, },
[REG_TIMING] = { [REG_TIMING] = {
"timing", ddr_timing, ARRAY_SIZE(ddr_timing), DDR_BASE .name = "timing",
.desc = ddr_timing,
.size = ARRAY_SIZE(ddr_timing),
.base = DDR_BASE
}, },
[REG_PERF] = { [REG_PERF] = {
"perf", ddr_perf, ARRAY_SIZE(ddr_perf), DDR_BASE .name = "perf",
.desc = ddr_perf,
.size = ARRAY_SIZE(ddr_perf),
.base = DDR_BASE
}, },
[REG_MAP] = { [REG_MAP] = {
"map", ddr_map, ARRAY_SIZE(ddr_map), DDR_BASE .name = "map",
.desc = ddr_map,
.size = ARRAY_SIZE(ddr_map),
.base = DDR_BASE
}, },
[REGPHY_REG] = { [REGPHY_REG] = {
"static", ddrphy_reg, ARRAY_SIZE(ddrphy_reg), DDRPHY_BASE .name = "static",
.desc = ddrphy_reg,
.size = ARRAY_SIZE(ddrphy_reg),
.base = DDRPHY_BASE
}, },
[REGPHY_TIMING] = { [REGPHY_TIMING] = {
"timing", ddrphy_timing, ARRAY_SIZE(ddrphy_timing), DDRPHY_BASE .name = "timing",
.desc = ddrphy_timing,
.size = ARRAY_SIZE(ddrphy_timing),
.base = DDRPHY_BASE
}, },
[REGPHY_CAL] = { [REGPHY_CAL] = {
"cal", ddrphy_cal, ARRAY_SIZE(ddrphy_cal), DDRPHY_BASE .name = "cal",
.desc = ddrphy_cal,
.size = ARRAY_SIZE(ddrphy_cal),
.base = DDRPHY_BASE
}, },
[REG_DYN] = { [REG_DYN] = {
"dyn", ddr_dyn, ARRAY_SIZE(ddr_dyn), DDR_BASE .name = "dyn",
.desc = ddr_dyn,
.size = ARRAY_SIZE(ddr_dyn),
.base = DDR_BASE
}, },
[REGPHY_DYN] = { [REGPHY_DYN] = {
"dyn", ddrphy_dyn, ARRAY_SIZE(ddrphy_dyn), DDRPHY_BASE .name = "dyn",
.desc = ddrphy_dyn,
.size = ARRAY_SIZE(ddrphy_dyn),
.base = DDRPHY_BASE
}, },
}; };
static uint32_t get_base_addr(const struct ddr_info *priv, enum base_type base) static uintptr_t get_base_addr(const struct ddr_info *priv, enum base_type base)
{ {
if (base == DDRPHY_BASE) { if (base == DDRPHY_BASE) {
return (uint32_t)priv->phy; return (uintptr_t)priv->phy;
} else { } else {
return (uint32_t)priv->ctl; return (uintptr_t)priv->ctl;
} }
} }
...@@ -275,21 +303,22 @@ static void set_reg(const struct ddr_info *priv, ...@@ -275,21 +303,22 @@ static void set_reg(const struct ddr_info *priv,
const void *param) const void *param)
{ {
unsigned int i; unsigned int i;
unsigned int *ptr, value; unsigned int value;
enum base_type base = ddr_registers[type].base; enum base_type base = ddr_registers[type].base;
uint32_t base_addr = get_base_addr(priv, base); uintptr_t base_addr = get_base_addr(priv, base);
const struct reg_desc *desc = ddr_registers[type].desc; const struct reg_desc *desc = ddr_registers[type].desc;
VERBOSE("init %s\n", ddr_registers[type].name); VERBOSE("init %s\n", ddr_registers[type].name);
for (i = 0; i < ddr_registers[type].size; i++) { for (i = 0; i < ddr_registers[type].size; i++) {
ptr = (unsigned int *)(base_addr + desc[i].offset); uintptr_t ptr = base_addr + desc[i].offset;
if (desc[i].par_offset == INVALID_OFFSET) { if (desc[i].par_offset == INVALID_OFFSET) {
ERROR("invalid parameter offset for %s", desc[i].name); ERROR("invalid parameter offset for %s", desc[i].name);
panic(); panic();
} else { } else {
value = *((uint32_t *)((uint32_t)param + value = *((uint32_t *)((uintptr_t)param +
desc[i].par_offset)); desc[i].par_offset));
mmio_write_32((uint32_t)ptr, value); mmio_write_32(ptr, value);
} }
} }
} }
...@@ -305,15 +334,15 @@ static void stm32mp1_ddrphy_idone_wait(struct stm32mp1_ddrphy *phy) ...@@ -305,15 +334,15 @@ static void stm32mp1_ddrphy_idone_wait(struct stm32mp1_ddrphy *phy)
time0 = start; time0 = start;
do { do {
pgsr = mmio_read_32((uint32_t)&phy->pgsr); pgsr = mmio_read_32((uintptr_t)&phy->pgsr);
time = get_timer(start); time = get_timer(start);
if (time != time0) { if (time != time0) {
VERBOSE(" > [0x%x] pgsr = 0x%x &\n", VERBOSE(" > [0x%lx] pgsr = 0x%x &\n",
(uint32_t)&phy->pgsr, pgsr); (uintptr_t)&phy->pgsr, pgsr);
VERBOSE(" [0x%x] pir = 0x%x (time=%x)\n", VERBOSE(" [0x%lx] pir = 0x%x (time=%lx)\n",
(uint32_t)&phy->pir, (uintptr_t)&phy->pir,
mmio_read_32((uint32_t)&phy->pir), mmio_read_32((uintptr_t)&phy->pir),
(uint32_t)time); time);
} }
time0 = time; time0 = time;
...@@ -341,18 +370,18 @@ static void stm32mp1_ddrphy_idone_wait(struct stm32mp1_ddrphy *phy) ...@@ -341,18 +370,18 @@ static void stm32mp1_ddrphy_idone_wait(struct stm32mp1_ddrphy *phy)
error++; error++;
} }
} while ((pgsr & DDRPHYC_PGSR_IDONE) == 0U && error == 0); } while ((pgsr & DDRPHYC_PGSR_IDONE) == 0U && error == 0);
VERBOSE("\n[0x%x] pgsr = 0x%x\n", VERBOSE("\n[0x%lx] pgsr = 0x%x\n",
(uint32_t)&phy->pgsr, pgsr); (uintptr_t)&phy->pgsr, pgsr);
} }
static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir) static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir)
{ {
uint32_t pir_init = pir | DDRPHYC_PIR_INIT; uint32_t pir_init = pir | DDRPHYC_PIR_INIT;
mmio_write_32((uint32_t)&phy->pir, pir_init); mmio_write_32((uintptr_t)&phy->pir, pir_init);
VERBOSE("[0x%x] pir = 0x%x -> 0x%x\n", VERBOSE("[0x%lx] pir = 0x%x -> 0x%x\n",
(uint32_t)&phy->pir, pir_init, (uintptr_t)&phy->pir, pir_init,
mmio_read_32((uint32_t)&phy->pir)); mmio_read_32((uintptr_t)&phy->pir));
/* Need to wait 10 configuration clock before start polling */ /* Need to wait 10 configuration clock before start polling */
udelay(10); udelay(10);
...@@ -364,9 +393,9 @@ static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir) ...@@ -364,9 +393,9 @@ static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir)
/* Start quasi dynamic register update */ /* Start quasi dynamic register update */
static void stm32mp1_start_sw_done(struct stm32mp1_ddrctl *ctl) static void stm32mp1_start_sw_done(struct stm32mp1_ddrctl *ctl)
{ {
mmio_clrbits_32((uint32_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE); mmio_clrbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
VERBOSE("[0x%x] swctl = 0x%x\n", VERBOSE("[0x%lx] swctl = 0x%x\n",
(uint32_t)&ctl->swctl, mmio_read_32((uint32_t)&ctl->swctl)); (uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl));
} }
/* Wait quasi dynamic register update */ /* Wait quasi dynamic register update */
...@@ -375,15 +404,15 @@ static void stm32mp1_wait_sw_done_ack(struct stm32mp1_ddrctl *ctl) ...@@ -375,15 +404,15 @@ static void stm32mp1_wait_sw_done_ack(struct stm32mp1_ddrctl *ctl)
unsigned long start; unsigned long start;
uint32_t swstat; uint32_t swstat;
mmio_setbits_32((uint32_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE); mmio_setbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
VERBOSE("[0x%x] swctl = 0x%x\n", VERBOSE("[0x%lx] swctl = 0x%x\n",
(uint32_t)&ctl->swctl, mmio_read_32((uint32_t)&ctl->swctl)); (uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl));
start = get_timer(0); start = get_timer(0);
do { do {
swstat = mmio_read_32((uint32_t)&ctl->swstat); swstat = mmio_read_32((uintptr_t)&ctl->swstat);
VERBOSE("[0x%x] swstat = 0x%x ", VERBOSE("[0x%lx] swstat = 0x%x ",
(uint32_t)&ctl->swstat, swstat); (uintptr_t)&ctl->swstat, swstat);
VERBOSE("timer in ms 0x%x = start 0x%lx\r", VERBOSE("timer in ms 0x%x = start 0x%lx\r",
get_timer(0), start); get_timer(0), start);
if (get_timer(start) > plat_get_syscnt_freq2()) { if (get_timer(start) > plat_get_syscnt_freq2()) {
...@@ -391,8 +420,8 @@ static void stm32mp1_wait_sw_done_ack(struct stm32mp1_ddrctl *ctl) ...@@ -391,8 +420,8 @@ static void stm32mp1_wait_sw_done_ack(struct stm32mp1_ddrctl *ctl)
} }
} while ((swstat & DDRCTRL_SWSTAT_SW_DONE_ACK) == 0U); } while ((swstat & DDRCTRL_SWSTAT_SW_DONE_ACK) == 0U);
VERBOSE("[0x%x] swstat = 0x%x\n", VERBOSE("[0x%lx] swstat = 0x%x\n",
(uint32_t)&ctl->swstat, swstat); (uintptr_t)&ctl->swstat, swstat);
} }
/* Wait quasi dynamic register update */ /* Wait quasi dynamic register update */
...@@ -406,11 +435,11 @@ static void stm32mp1_wait_operating_mode(struct ddr_info *priv, uint32_t mode) ...@@ -406,11 +435,11 @@ static void stm32mp1_wait_operating_mode(struct ddr_info *priv, uint32_t mode)
start = get_timer(0); start = get_timer(0);
for ( ; ; ) { for ( ; ; ) {
stat = mmio_read_32((uint32_t)&priv->ctl->stat); stat = mmio_read_32((uintptr_t)&priv->ctl->stat);
operating_mode = stat & DDRCTRL_STAT_OPERATING_MODE_MASK; operating_mode = stat & DDRCTRL_STAT_OPERATING_MODE_MASK;
selref_type = stat & DDRCTRL_STAT_SELFREF_TYPE_MASK; selref_type = stat & DDRCTRL_STAT_SELFREF_TYPE_MASK;
VERBOSE("[0x%x] stat = 0x%x\n", VERBOSE("[0x%lx] stat = 0x%x\n",
(uint32_t)&priv->ctl->stat, stat); (uintptr_t)&priv->ctl->stat, stat);
VERBOSE("timer in ms 0x%x = start 0x%lx\r", VERBOSE("timer in ms 0x%x = start 0x%lx\r",
get_timer(0), start); get_timer(0), start);
if (get_timer(start) > plat_get_syscnt_freq2()) { if (get_timer(start) > plat_get_syscnt_freq2()) {
...@@ -441,8 +470,8 @@ static void stm32mp1_wait_operating_mode(struct ddr_info *priv, uint32_t mode) ...@@ -441,8 +470,8 @@ static void stm32mp1_wait_operating_mode(struct ddr_info *priv, uint32_t mode)
} }
} }
VERBOSE("[0x%x] stat = 0x%x\n", VERBOSE("[0x%lx] stat = 0x%x\n",
(uint32_t)&priv->ctl->stat, stat); (uintptr_t)&priv->ctl->stat, stat);
} }
/* Mode Register Writes (MRW or MRS) */ /* Mode Register Writes (MRW or MRS) */
...@@ -459,7 +488,7 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr, ...@@ -459,7 +488,7 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr,
* No write should be performed to MRCTRL0 and MRCTRL1 * No write should be performed to MRCTRL0 and MRCTRL1
* if MRSTAT.mr_wr_busy = 1. * if MRSTAT.mr_wr_busy = 1.
*/ */
while ((mmio_read_32((uint32_t)&priv->ctl->mrstat) & while ((mmio_read_32((uintptr_t)&priv->ctl->mrstat) &
DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) { DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) {
; ;
} }
...@@ -472,14 +501,14 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr, ...@@ -472,14 +501,14 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr,
DDRCTRL_MRCTRL0_MR_RANK_ALL | DDRCTRL_MRCTRL0_MR_RANK_ALL |
(((uint32_t)addr << DDRCTRL_MRCTRL0_MR_ADDR_SHIFT) & (((uint32_t)addr << DDRCTRL_MRCTRL0_MR_ADDR_SHIFT) &
DDRCTRL_MRCTRL0_MR_ADDR_MASK); DDRCTRL_MRCTRL0_MR_ADDR_MASK);
mmio_write_32((uint32_t)&priv->ctl->mrctrl0, mrctrl0); mmio_write_32((uintptr_t)&priv->ctl->mrctrl0, mrctrl0);
VERBOSE("[0x%x] mrctrl0 = 0x%x (0x%x)\n", VERBOSE("[0x%lx] mrctrl0 = 0x%x (0x%x)\n",
(uint32_t)&priv->ctl->mrctrl0, (uintptr_t)&priv->ctl->mrctrl0,
mmio_read_32((uint32_t)&priv->ctl->mrctrl0), mrctrl0); mmio_read_32((uintptr_t)&priv->ctl->mrctrl0), mrctrl0);
mmio_write_32((uint32_t)&priv->ctl->mrctrl1, data); mmio_write_32((uintptr_t)&priv->ctl->mrctrl1, data);
VERBOSE("[0x%x] mrctrl1 = 0x%x\n", VERBOSE("[0x%lx] mrctrl1 = 0x%x\n",
(uint32_t)&priv->ctl->mrctrl1, (uintptr_t)&priv->ctl->mrctrl1,
mmio_read_32((uint32_t)&priv->ctl->mrctrl1)); mmio_read_32((uintptr_t)&priv->ctl->mrctrl1));
/* /*
* 3. In a separate APB transaction, write the MRCTRL0.mr_wr to 1. This * 3. In a separate APB transaction, write the MRCTRL0.mr_wr to 1. This
...@@ -489,22 +518,22 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr, ...@@ -489,22 +518,22 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr,
* initiated until it is deasserted. * initiated until it is deasserted.
*/ */
mrctrl0 |= DDRCTRL_MRCTRL0_MR_WR; mrctrl0 |= DDRCTRL_MRCTRL0_MR_WR;
mmio_write_32((uint32_t)&priv->ctl->mrctrl0, mrctrl0); mmio_write_32((uintptr_t)&priv->ctl->mrctrl0, mrctrl0);
while ((mmio_read_32((uint32_t)&priv->ctl->mrstat) & while ((mmio_read_32((uintptr_t)&priv->ctl->mrstat) &
DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) { DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) {
; ;
} }
VERBOSE("[0x%x] mrctrl0 = 0x%x\n", VERBOSE("[0x%lx] mrctrl0 = 0x%x\n",
(uint32_t)&priv->ctl->mrctrl0, mrctrl0); (uintptr_t)&priv->ctl->mrctrl0, mrctrl0);
} }
/* Switch DDR3 from DLL-on to DLL-off */ /* Switch DDR3 from DLL-on to DLL-off */
static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
{ {
uint32_t mr1 = mmio_read_32((uint32_t)&priv->phy->mr1); uint32_t mr1 = mmio_read_32((uintptr_t)&priv->phy->mr1);
uint32_t mr2 = mmio_read_32((uint32_t)&priv->phy->mr2); uint32_t mr2 = mmio_read_32((uintptr_t)&priv->phy->mr2);
uint32_t dbgcam; uint32_t dbgcam;
VERBOSE("mr1: 0x%x\n", mr1); VERBOSE("mr1: 0x%x\n", mr1);
...@@ -514,10 +543,10 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) ...@@ -514,10 +543,10 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
* 1. Set the DBG1.dis_hif = 1. * 1. Set the DBG1.dis_hif = 1.
* This prevents further reads/writes being received on the HIF. * This prevents further reads/writes being received on the HIF.
*/ */
mmio_setbits_32((uint32_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF); mmio_setbits_32((uintptr_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
VERBOSE("[0x%x] dbg1 = 0x%x\n", VERBOSE("[0x%lx] dbg1 = 0x%x\n",
(uint32_t)&priv->ctl->dbg1, (uintptr_t)&priv->ctl->dbg1,
mmio_read_32((uint32_t)&priv->ctl->dbg1)); mmio_read_32((uintptr_t)&priv->ctl->dbg1));
/* /*
* 2. Ensure all commands have been flushed from the uMCTL2 by polling * 2. Ensure all commands have been flushed from the uMCTL2 by polling
...@@ -528,9 +557,9 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) ...@@ -528,9 +557,9 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
* DBGCAM.dbg_hpr_q_depth = 0. * DBGCAM.dbg_hpr_q_depth = 0.
*/ */
do { do {
dbgcam = mmio_read_32((uint32_t)&priv->ctl->dbgcam); dbgcam = mmio_read_32((uintptr_t)&priv->ctl->dbgcam);
VERBOSE("[0x%x] dbgcam = 0x%x\n", VERBOSE("[0x%lx] dbgcam = 0x%x\n",
(uint32_t)&priv->ctl->dbgcam, dbgcam); (uintptr_t)&priv->ctl->dbgcam, dbgcam);
} while ((((dbgcam & DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY) == } while ((((dbgcam & DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY) ==
DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY)) && DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY)) &&
((dbgcam & DDRCTRL_DBGCAM_DBG_Q_DEPTH) == 0U)); ((dbgcam & DDRCTRL_DBGCAM_DBG_Q_DEPTH) == 0U));
...@@ -574,11 +603,11 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) ...@@ -574,11 +603,11 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
* PWRCTL.selfref_sw = 1, and polling STAT.operating_mode to ensure * PWRCTL.selfref_sw = 1, and polling STAT.operating_mode to ensure
* the DDRC has entered self-refresh. * the DDRC has entered self-refresh.
*/ */
mmio_setbits_32((uint32_t)&priv->ctl->pwrctl, mmio_setbits_32((uintptr_t)&priv->ctl->pwrctl,
DDRCTRL_PWRCTL_SELFREF_SW); DDRCTRL_PWRCTL_SELFREF_SW);
VERBOSE("[0x%x] pwrctl = 0x%x\n", VERBOSE("[0x%lx] pwrctl = 0x%x\n",
(uint32_t)&priv->ctl->pwrctl, (uintptr_t)&priv->ctl->pwrctl,
mmio_read_32((uint32_t)&priv->ctl->pwrctl)); mmio_read_32((uintptr_t)&priv->ctl->pwrctl));
/* /*
* 8. Wait until STAT.operating_mode[1:0]==11 indicating that the * 8. Wait until STAT.operating_mode[1:0]==11 indicating that the
...@@ -594,10 +623,10 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) ...@@ -594,10 +623,10 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
*/ */
stm32mp1_start_sw_done(priv->ctl); stm32mp1_start_sw_done(priv->ctl);
mmio_setbits_32((uint32_t)&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE); mmio_setbits_32((uintptr_t)&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE);
VERBOSE("[0x%x] mstr = 0x%x\n", VERBOSE("[0x%lx] mstr = 0x%x\n",
(uint32_t)&priv->ctl->mstr, (uintptr_t)&priv->ctl->mstr,
mmio_read_32((uint32_t)&priv->ctl->mstr)); mmio_read_32((uintptr_t)&priv->ctl->mstr));
stm32mp1_wait_sw_done_ack(priv->ctl); stm32mp1_wait_sw_done_ack(priv->ctl);
...@@ -611,26 +640,26 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) ...@@ -611,26 +640,26 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
/* Change Bypass Mode Frequency Range */ /* Change Bypass Mode Frequency Range */
if (stm32mp1_clk_get_rate(DDRPHYC) < 100000000U) { if (stm32mp1_clk_get_rate(DDRPHYC) < 100000000U) {
mmio_clrbits_32((uint32_t)&priv->phy->dllgcr, mmio_clrbits_32((uintptr_t)&priv->phy->dllgcr,
DDRPHYC_DLLGCR_BPS200); DDRPHYC_DLLGCR_BPS200);
} else { } else {
mmio_setbits_32((uint32_t)&priv->phy->dllgcr, mmio_setbits_32((uintptr_t)&priv->phy->dllgcr,
DDRPHYC_DLLGCR_BPS200); DDRPHYC_DLLGCR_BPS200);
} }
mmio_setbits_32((uint32_t)&priv->phy->acdllcr, DDRPHYC_ACDLLCR_DLLDIS); mmio_setbits_32((uintptr_t)&priv->phy->acdllcr, DDRPHYC_ACDLLCR_DLLDIS);
mmio_setbits_32((uint32_t)&priv->phy->dx0dllcr, mmio_setbits_32((uintptr_t)&priv->phy->dx0dllcr,
DDRPHYC_DXNDLLCR_DLLDIS); DDRPHYC_DXNDLLCR_DLLDIS);
mmio_setbits_32((uint32_t)&priv->phy->dx1dllcr, mmio_setbits_32((uintptr_t)&priv->phy->dx1dllcr,
DDRPHYC_DXNDLLCR_DLLDIS); DDRPHYC_DXNDLLCR_DLLDIS);
mmio_setbits_32((uint32_t)&priv->phy->dx2dllcr, mmio_setbits_32((uintptr_t)&priv->phy->dx2dllcr,
DDRPHYC_DXNDLLCR_DLLDIS); DDRPHYC_DXNDLLCR_DLLDIS);
mmio_setbits_32((uint32_t)&priv->phy->dx3dllcr, mmio_setbits_32((uintptr_t)&priv->phy->dx3dllcr,
DDRPHYC_DXNDLLCR_DLLDIS); DDRPHYC_DXNDLLCR_DLLDIS);
/* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */ /* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
mmio_clrbits_32((uint32_t)&priv->ctl->pwrctl, mmio_clrbits_32((uintptr_t)&priv->ctl->pwrctl,
DDRCTRL_PWRCTL_SELFREF_SW); DDRCTRL_PWRCTL_SELFREF_SW);
stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL); stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
...@@ -646,20 +675,20 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) ...@@ -646,20 +675,20 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
*/ */
/* 15. Write DBG1.dis_hif = 0 to re-enable reads and writes. */ /* 15. Write DBG1.dis_hif = 0 to re-enable reads and writes. */
mmio_clrbits_32((uint32_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF); mmio_clrbits_32((uintptr_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
VERBOSE("[0x%x] dbg1 = 0x%x\n", VERBOSE("[0x%lx] dbg1 = 0x%x\n",
(uint32_t)&priv->ctl->dbg1, (uintptr_t)&priv->ctl->dbg1,
mmio_read_32((uint32_t)&priv->ctl->dbg1)); mmio_read_32((uintptr_t)&priv->ctl->dbg1));
} }
static void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl) static void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl)
{ {
stm32mp1_start_sw_done(ctl); stm32mp1_start_sw_done(ctl);
/* Quasi-dynamic register update*/ /* Quasi-dynamic register update*/
mmio_setbits_32((uint32_t)&ctl->rfshctl3, mmio_setbits_32((uintptr_t)&ctl->rfshctl3,
DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH); DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
mmio_clrbits_32((uint32_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN); mmio_clrbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
mmio_clrbits_32((uint32_t)&ctl->dfimisc, mmio_clrbits_32((uintptr_t)&ctl->dfimisc,
DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
stm32mp1_wait_sw_done_ack(ctl); stm32mp1_wait_sw_done_ack(ctl);
} }
...@@ -669,14 +698,14 @@ static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl, ...@@ -669,14 +698,14 @@ static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl,
{ {
stm32mp1_start_sw_done(ctl); stm32mp1_start_sw_done(ctl);
if ((rfshctl3 & DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH) == 0U) { if ((rfshctl3 & DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH) == 0U) {
mmio_clrbits_32((uint32_t)&ctl->rfshctl3, mmio_clrbits_32((uintptr_t)&ctl->rfshctl3,
DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH); DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
} }
if ((pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN) != 0U) { if ((pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN) != 0U) {
mmio_setbits_32((uint32_t)&ctl->pwrctl, mmio_setbits_32((uintptr_t)&ctl->pwrctl,
DDRCTRL_PWRCTL_POWERDOWN_EN); DDRCTRL_PWRCTL_POWERDOWN_EN);
} }
mmio_setbits_32((uint32_t)&ctl->dfimisc, mmio_setbits_32((uintptr_t)&ctl->dfimisc,
DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
stm32mp1_wait_sw_done_ack(ctl); stm32mp1_wait_sw_done_ack(ctl);
} }
...@@ -694,12 +723,14 @@ void stm32mp1_ddr_init(struct ddr_info *priv, ...@@ -694,12 +723,14 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
struct stm32mp1_ddr_config *config) struct stm32mp1_ddr_config *config)
{ {
uint32_t pir; uint32_t pir;
int ret; int ret = -EINVAL;
if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) { if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) {
ret = board_ddr_power_init(STM32MP_DDR3); ret = board_ddr_power_init(STM32MP_DDR3);
} else { } else if ((config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) != 0U) {
ret = board_ddr_power_init(STM32MP_LPDDR2); ret = board_ddr_power_init(STM32MP_LPDDR2);
} else {
ERROR("DDR type not supported\n");
} }
if (ret != 0) { if (ret != 0) {
...@@ -707,7 +738,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv, ...@@ -707,7 +738,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
} }
VERBOSE("name = %s\n", config->info.name); VERBOSE("name = %s\n", config->info.name);
VERBOSE("speed = %d MHz\n", config->info.speed); VERBOSE("speed = %d kHz\n", config->info.speed);
VERBOSE("size = 0x%x\n", config->info.size); VERBOSE("size = 0x%x\n", config->info.size);
/* DDR INIT SEQUENCE */ /* DDR INIT SEQUENCE */
...@@ -746,11 +777,11 @@ void stm32mp1_ddr_init(struct ddr_info *priv, ...@@ -746,11 +777,11 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
/* 1.5. initialize registers ddr_umctl2 */ /* 1.5. initialize registers ddr_umctl2 */
/* Stop uMCTL2 before PHY is ready */ /* Stop uMCTL2 before PHY is ready */
mmio_clrbits_32((uint32_t)&priv->ctl->dfimisc, mmio_clrbits_32((uintptr_t)&priv->ctl->dfimisc,
DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
VERBOSE("[0x%x] dfimisc = 0x%x\n", VERBOSE("[0x%lx] dfimisc = 0x%x\n",
(uint32_t)&priv->ctl->dfimisc, (uintptr_t)&priv->ctl->dfimisc,
mmio_read_32((uint32_t)&priv->ctl->dfimisc)); mmio_read_32((uintptr_t)&priv->ctl->dfimisc));
set_reg(priv, REG_REG, &config->c_reg); set_reg(priv, REG_REG, &config->c_reg);
...@@ -759,23 +790,23 @@ void stm32mp1_ddr_init(struct ddr_info *priv, ...@@ -759,23 +790,23 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
(DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE))
== (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) { == (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) {
VERBOSE("deactivate DLL OFF in mstr\n"); VERBOSE("deactivate DLL OFF in mstr\n");
mmio_clrbits_32((uint32_t)&priv->ctl->mstr, mmio_clrbits_32((uintptr_t)&priv->ctl->mstr,
DDRCTRL_MSTR_DLL_OFF_MODE); DDRCTRL_MSTR_DLL_OFF_MODE);
VERBOSE("[0x%x] mstr = 0x%x\n", VERBOSE("[0x%lx] mstr = 0x%x\n",
(uint32_t)&priv->ctl->mstr, (uintptr_t)&priv->ctl->mstr,
mmio_read_32((uint32_t)&priv->ctl->mstr)); mmio_read_32((uintptr_t)&priv->ctl->mstr));
} }
set_reg(priv, REG_TIMING, &config->c_timing); set_reg(priv, REG_TIMING, &config->c_timing);
set_reg(priv, REG_MAP, &config->c_map); set_reg(priv, REG_MAP, &config->c_map);
/* Skip CTRL init, SDRAM init is done by PHY PUBL */ /* Skip CTRL init, SDRAM init is done by PHY PUBL */
mmio_clrsetbits_32((uint32_t)&priv->ctl->init0, mmio_clrsetbits_32((uintptr_t)&priv->ctl->init0,
DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK, DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK,
DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL); DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL);
VERBOSE("[0x%x] init0 = 0x%x\n", VERBOSE("[0x%lx] init0 = 0x%x\n",
(uint32_t)&priv->ctl->init0, (uintptr_t)&priv->ctl->init0,
mmio_read_32((uint32_t)&priv->ctl->init0)); mmio_read_32((uintptr_t)&priv->ctl->init0));
set_reg(priv, REG_PERF, &config->c_perf); set_reg(priv, REG_PERF, &config->c_perf);
...@@ -797,10 +828,10 @@ void stm32mp1_ddr_init(struct ddr_info *priv, ...@@ -797,10 +828,10 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
(DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE))
== (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) { == (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) {
VERBOSE("deactivate DLL OFF in mr1\n"); VERBOSE("deactivate DLL OFF in mr1\n");
mmio_clrbits_32((uint32_t)&priv->phy->mr1, BIT(0)); mmio_clrbits_32((uintptr_t)&priv->phy->mr1, BIT(0));
VERBOSE("[0x%x] mr1 = 0x%x\n", VERBOSE("[0x%lx] mr1 = 0x%x\n",
(uint32_t)&priv->phy->mr1, (uintptr_t)&priv->phy->mr1,
mmio_read_32((uint32_t)&priv->phy->mr1)); mmio_read_32((uintptr_t)&priv->phy->mr1));
} }
/* /*
...@@ -830,11 +861,11 @@ void stm32mp1_ddr_init(struct ddr_info *priv, ...@@ -830,11 +861,11 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
*/ */
stm32mp1_start_sw_done(priv->ctl); stm32mp1_start_sw_done(priv->ctl);
mmio_setbits_32((uint32_t)&priv->ctl->dfimisc, mmio_setbits_32((uintptr_t)&priv->ctl->dfimisc,
DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
VERBOSE("[0x%x] dfimisc = 0x%x\n", VERBOSE("[0x%lx] dfimisc = 0x%x\n",
(uint32_t)&priv->ctl->dfimisc, (uintptr_t)&priv->ctl->dfimisc,
mmio_read_32((uint32_t)&priv->ctl->dfimisc)); mmio_read_32((uintptr_t)&priv->ctl->dfimisc));
stm32mp1_wait_sw_done_ack(priv->ctl); stm32mp1_wait_sw_done_ack(priv->ctl);
...@@ -884,14 +915,16 @@ void stm32mp1_ddr_init(struct ddr_info *priv, ...@@ -884,14 +915,16 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
config->c_reg.pwrctl); config->c_reg.pwrctl);
/* Enable uMCTL2 AXI port 0 */ /* Enable uMCTL2 AXI port 0 */
mmio_setbits_32((uint32_t)&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN); mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_0,
VERBOSE("[0x%x] pctrl_0 = 0x%x\n", DDRCTRL_PCTRL_N_PORT_EN);
(uint32_t)&priv->ctl->pctrl_0, VERBOSE("[0x%lx] pctrl_0 = 0x%x\n",
mmio_read_32((uint32_t)&priv->ctl->pctrl_0)); (uintptr_t)&priv->ctl->pctrl_0,
mmio_read_32((uintptr_t)&priv->ctl->pctrl_0));
/* Enable uMCTL2 AXI port 1 */ /* Enable uMCTL2 AXI port 1 */
mmio_setbits_32((uint32_t)&priv->ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN); mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_1,
VERBOSE("[0x%x] pctrl_1 = 0x%x\n", DDRCTRL_PCTRL_N_PORT_EN);
(uint32_t)&priv->ctl->pctrl_1, VERBOSE("[0x%lx] pctrl_1 = 0x%x\n",
mmio_read_32((uint32_t)&priv->ctl->pctrl_1)); (uintptr_t)&priv->ctl->pctrl_1,
mmio_read_32((uintptr_t)&priv->ctl->pctrl_1));
} }
/* /*
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
* *
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/ */
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
static struct ddr_info ddr_priv_data; static struct ddr_info ddr_priv_data;
int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed) int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed)
{ {
unsigned long ddrphy_clk, ddr_clk, mem_speed_hz; unsigned long ddrphy_clk, ddr_clk, mem_speed_hz;
...@@ -33,10 +33,10 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed) ...@@ -33,10 +33,10 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
ddrphy_clk = stm32mp1_clk_get_rate(DDRPHYC); ddrphy_clk = stm32mp1_clk_get_rate(DDRPHYC);
VERBOSE("DDR: mem_speed (%d MHz), RCC %ld MHz\n", VERBOSE("DDR: mem_speed (%d kHz), RCC %ld kHz\n",
mem_speed, ddrphy_clk / 1000U / 1000U); mem_speed, ddrphy_clk / 1000U);
mem_speed_hz = (uint32_t)mem_speed * 1000U * 1000U; mem_speed_hz = mem_speed * 1000U;
/* Max 10% frequency delta */ /* Max 10% frequency delta */
if (ddrphy_clk > mem_speed_hz) { if (ddrphy_clk > mem_speed_hz) {
...@@ -44,9 +44,9 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed) ...@@ -44,9 +44,9 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
} else { } else {
ddr_clk = mem_speed_hz - ddrphy_clk; ddr_clk = mem_speed_hz - ddrphy_clk;
} }
if (ddr_clk > mem_speed_hz) { if (ddr_clk > (mem_speed_hz / 10)) {
ERROR("DDR expected freq %d MHz, current is %ld MHz\n", ERROR("DDR expected freq %d kHz, current is %ld kHz\n",
mem_speed, ddrphy_clk / 1000U / 1000U); mem_speed, ddrphy_clk / 1000U);
return -1; return -1;
} }
return 0; return 0;
...@@ -208,11 +208,16 @@ static int stm32mp1_ddr_setup(void) ...@@ -208,11 +208,16 @@ static int stm32mp1_ddr_setup(void)
return -EINVAL; return -EINVAL;
} }
config.info.speed = config.info.speed = fdt_read_uint32_default(node, "st,mem-speed", 0);
(uint16_t)fdt_read_uint32_default(node, "st,mem-speed", if (!config.info.speed) {
STM32MP1_DDR_SPEED_DFLT); VERBOSE("%s: no st,mem-speed\n", __func__);
config.info.size = fdt_read_uint32_default(node, "st,mem-size", return -EINVAL;
STM32MP1_DDR_SIZE_DFLT); }
config.info.size = fdt_read_uint32_default(node, "st,mem-size", 0);
if (!config.info.size) {
VERBOSE("%s: no st,mem-size\n", __func__);
return -EINVAL;
}
config.info.name = fdt_getprop(fdt, node, "st,mem-name", &len); config.info.name = fdt_getprop(fdt, node, "st,mem-name", &len);
if (config.info.name == NULL) { if (config.info.name == NULL) {
VERBOSE("%s: no st,mem-name\n", __func__); VERBOSE("%s: no st,mem-name\n", __func__);
...@@ -222,7 +227,7 @@ static int stm32mp1_ddr_setup(void) ...@@ -222,7 +227,7 @@ static int stm32mp1_ddr_setup(void)
for (idx = 0; idx < ARRAY_SIZE(param); idx++) { for (idx = 0; idx < ARRAY_SIZE(param); idx++) {
ret = fdt_read_uint32_array(node, param[idx].name, ret = fdt_read_uint32_array(node, param[idx].name,
(void *)((uint32_t)&config + (void *)((uintptr_t)&config +
param[idx].offset), param[idx].offset),
param[idx].size); param[idx].size);
...@@ -261,8 +266,8 @@ static int stm32mp1_ddr_setup(void) ...@@ -261,8 +266,8 @@ static int stm32mp1_ddr_setup(void)
VERBOSE("%s : ram size(%x, %x)\n", __func__, VERBOSE("%s : ram size(%x, %x)\n", __func__,
(uint32_t)priv->info.base, (uint32_t)priv->info.size); (uint32_t)priv->info.base, (uint32_t)priv->info.size);
dcsw_op_all(DC_OP_CISW);
write_sctlr(read_sctlr() & ~SCTLR_C_BIT); write_sctlr(read_sctlr() & ~SCTLR_C_BIT);
dcsw_op_all(DC_OP_CISW);
uret = ddr_test_data_bus(); uret = ddr_test_data_bus();
if (uret != 0U) { if (uret != 0U) {
......
/* /*
* Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
#include <assert.h>
#include <errno.h>
#include <stdbool.h> #include <stdbool.h>
#include <libfdt.h>
#include <platform_def.h>
#include <common/bl_common.h> #include <common/bl_common.h>
#include <common/debug.h> #include <common/debug.h>
#include <drivers/st/stm32_gpio.h> #include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_clkfunc.h>
#include <lib/mmio.h> #include <lib/mmio.h>
#include <lib/utils_def.h>
#define DT_GPIO_BANK_SHIFT 12
#define DT_GPIO_BANK_MASK GENMASK(16, 12)
#define DT_GPIO_PIN_SHIFT 8
#define DT_GPIO_PIN_MASK GENMASK(11, 8)
#define DT_GPIO_MODE_MASK GENMASK(7, 0)
static bool check_gpio(uint32_t bank, uint32_t pin) /*******************************************************************************
* This function gets GPIO bank node in DT.
* Returns node offset if status is okay in DT, else return 0
******************************************************************************/
static int ckeck_gpio_bank(void *fdt, uint32_t bank, int pinctrl_node)
{ {
if (pin > GPIO_PIN_MAX) { int pinctrl_subnode;
ERROR("%s: wrong pin number (%d)\n", __func__, pin); uint32_t bank_offset = stm32_get_gpio_bank_offset(bank);
return false;
fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) {
const fdt32_t *cuint;
if (fdt_getprop(fdt, pinctrl_subnode,
"gpio-controller", NULL) == NULL) {
continue;
} }
if ((bank > GPIO_BANK_K) && (bank != GPIO_BANK_Z)) { cuint = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL);
ERROR("%s: wrong GPIO bank number (%d)\n", __func__, bank); if (cuint == NULL) {
return false; continue;
} }
return true; if ((fdt32_to_cpu(*cuint) == bank_offset) &&
(fdt_get_status(pinctrl_subnode) != DT_DISABLED)) {
return pinctrl_subnode;
}
}
return 0;
} }
void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed, /*******************************************************************************
uint32_t pull, uint32_t alternate) * This function gets the pin settings from DT information.
* When analyze and parsing is done, set the GPIO registers.
* Returns 0 on success and a negative FDT error code on failure.
******************************************************************************/
static int dt_set_gpio_config(void *fdt, int node, uint8_t status)
{ {
volatile uint32_t bank_address; const fdt32_t *cuint, *slewrate;
int len;
int pinctrl_node;
uint32_t i;
uint32_t speed = GPIO_SPEED_LOW;
uint32_t pull = GPIO_NO_PULL;
if (!check_gpio(bank, pin)) { cuint = fdt_getprop(fdt, node, "pinmux", &len);
return; if (cuint == NULL) {
return -FDT_ERR_NOTFOUND;
} }
if (bank == GPIO_BANK_Z) { pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node));
bank_address = STM32_GPIOZ_BANK; if (pinctrl_node < 0) {
return -FDT_ERR_NOTFOUND;
}
slewrate = fdt_getprop(fdt, node, "slew-rate", NULL);
if (slewrate != NULL) {
speed = fdt32_to_cpu(*slewrate);
}
if (fdt_getprop(fdt, node, "bias-pull-up", NULL) != NULL) {
pull = GPIO_PULL_UP;
} else if (fdt_getprop(fdt, node, "bias-pull-down", NULL) != NULL) {
pull = GPIO_PULL_DOWN;
} else { } else {
bank_address = STM32_GPIOA_BANK + VERBOSE("No bias configured in node %d\n", node);
(bank * STM32_GPIO_BANK_OFFSET); }
for (i = 0U; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
uint32_t pincfg;
uint32_t bank;
uint32_t pin;
uint32_t mode;
uint32_t alternate = GPIO_ALTERNATE_(0);
int bank_node;
int clk;
pincfg = fdt32_to_cpu(*cuint);
cuint++;
bank = (pincfg & DT_GPIO_BANK_MASK) >> DT_GPIO_BANK_SHIFT;
pin = (pincfg & DT_GPIO_PIN_MASK) >> DT_GPIO_PIN_SHIFT;
mode = pincfg & DT_GPIO_MODE_MASK;
switch (mode) {
case 0:
mode = GPIO_MODE_INPUT;
break;
case 1 ... 16:
alternate = mode - 1U;
mode = GPIO_MODE_ALTERNATE;
break;
case 17:
mode = GPIO_MODE_ANALOG;
break;
default:
mode = GPIO_MODE_OUTPUT;
break;
}
if (fdt_getprop(fdt, node, "drive-open-drain", NULL) != NULL) {
mode |= GPIO_OPEN_DRAIN;
}
bank_node = ckeck_gpio_bank(fdt, bank, pinctrl_node);
if (bank_node == 0) {
ERROR("PINCTRL inconsistent in DT\n");
panic();
}
clk = fdt_get_clock_id(bank_node);
if (clk < 0) {
return -FDT_ERR_NOTFOUND;
}
/* Platform knows the clock: assert it is okay */
assert((unsigned long)clk == stm32_get_gpio_bank_clock(bank));
set_gpio(bank, pin, mode, speed, pull, alternate, status);
}
return 0;
}
/*******************************************************************************
* This function gets the pin settings from DT information.
* When analyze and parsing is done, set the GPIO registers.
* Returns 0 on success and a negative FDT/ERRNO error code on failure.
******************************************************************************/
int dt_set_pinctrl_config(int node)
{
const fdt32_t *cuint;
int lenp = 0;
uint32_t i;
uint8_t status = fdt_get_status(node);
void *fdt;
if (fdt_get_address(&fdt) == 0) {
return -ENOENT;
}
if (status == DT_DISABLED) {
return -FDT_ERR_NOTFOUND;
}
cuint = fdt_getprop(fdt, node, "pinctrl-0", &lenp);
if (cuint == NULL) {
return -FDT_ERR_NOTFOUND;
}
for (i = 0; i < ((uint32_t)lenp / 4U); i++) {
int p_node, p_subnode;
p_node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
if (p_node < 0) {
return -FDT_ERR_NOTFOUND;
} }
mmio_clrbits_32(bank_address + GPIO_MODE_OFFSET, fdt_for_each_subnode(p_subnode, fdt, p_node) {
int ret = dt_set_gpio_config(fdt, p_subnode, status);
if (ret < 0) {
return ret;
}
}
cuint++;
}
return 0;
}
void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
uint32_t pull, uint32_t alternate, uint8_t status)
{
uintptr_t base = stm32_get_gpio_bank_base(bank);
unsigned long clock = stm32_get_gpio_bank_clock(bank);
assert(pin <= GPIO_PIN_MAX);
stm32mp1_clk_enable(clock);
mmio_clrbits_32(base + GPIO_MODE_OFFSET,
((uint32_t)GPIO_MODE_MASK << (pin << 1))); ((uint32_t)GPIO_MODE_MASK << (pin << 1)));
mmio_setbits_32(bank_address + GPIO_MODE_OFFSET, mmio_setbits_32(base + GPIO_MODE_OFFSET,
(mode & ~GPIO_OPEN_DRAIN) << (pin << 1)); (mode & ~GPIO_OPEN_DRAIN) << (pin << 1));
if ((mode & GPIO_OPEN_DRAIN) != 0U) { if ((mode & GPIO_OPEN_DRAIN) != 0U) {
mmio_setbits_32(bank_address + GPIO_TYPE_OFFSET, mmio_setbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
BIT(pin)); } else {
mmio_clrbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
} }
mmio_clrbits_32(bank_address + GPIO_SPEED_OFFSET, mmio_clrbits_32(base + GPIO_SPEED_OFFSET,
((uint32_t)GPIO_SPEED_MASK << (pin << 1))); ((uint32_t)GPIO_SPEED_MASK << (pin << 1)));
mmio_setbits_32(bank_address + GPIO_SPEED_OFFSET, speed << (pin << 1)); mmio_setbits_32(base + GPIO_SPEED_OFFSET, speed << (pin << 1));
mmio_clrbits_32(bank_address + GPIO_PUPD_OFFSET, mmio_clrbits_32(base + GPIO_PUPD_OFFSET,
((uint32_t)GPIO_PULL_MASK << (pin << 1))); ((uint32_t)GPIO_PULL_MASK << (pin << 1)));
mmio_setbits_32(bank_address + GPIO_PUPD_OFFSET, pull << (pin << 1)); mmio_setbits_32(base + GPIO_PUPD_OFFSET, pull << (pin << 1));
if (pin < GPIO_ALT_LOWER_LIMIT) { if (pin < GPIO_ALT_LOWER_LIMIT) {
mmio_clrbits_32(bank_address + GPIO_AFRL_OFFSET, mmio_clrbits_32(base + GPIO_AFRL_OFFSET,
((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2))); ((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2)));
mmio_setbits_32(bank_address + GPIO_AFRL_OFFSET, mmio_setbits_32(base + GPIO_AFRL_OFFSET,
alternate << (pin << 2)); alternate << (pin << 2));
} else { } else {
mmio_clrbits_32(bank_address + GPIO_AFRH_OFFSET, mmio_clrbits_32(base + GPIO_AFRH_OFFSET,
((uint32_t)GPIO_ALTERNATE_MASK << ((uint32_t)GPIO_ALTERNATE_MASK <<
((pin - GPIO_ALT_LOWER_LIMIT) << 2))); ((pin - GPIO_ALT_LOWER_LIMIT) << 2)));
mmio_setbits_32(bank_address + GPIO_AFRH_OFFSET, mmio_setbits_32(base + GPIO_AFRH_OFFSET,
alternate << ((pin - GPIO_ALT_LOWER_LIMIT) << alternate << ((pin - GPIO_ALT_LOWER_LIMIT) <<
2)); 2));
} }
VERBOSE("GPIO %u mode set to 0x%x\n", bank, VERBOSE("GPIO %u mode set to 0x%x\n", bank,
mmio_read_32(bank_address + GPIO_MODE_OFFSET)); mmio_read_32(base + GPIO_MODE_OFFSET));
VERBOSE("GPIO %u speed set to 0x%x\n", bank, VERBOSE("GPIO %u speed set to 0x%x\n", bank,
mmio_read_32(bank_address + GPIO_SPEED_OFFSET)); mmio_read_32(base + GPIO_SPEED_OFFSET));
VERBOSE("GPIO %u mode pull to 0x%x\n", bank, VERBOSE("GPIO %u mode pull to 0x%x\n", bank,
mmio_read_32(bank_address + GPIO_PUPD_OFFSET)); mmio_read_32(base + GPIO_PUPD_OFFSET));
VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank, VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank,
mmio_read_32(bank_address + GPIO_AFRL_OFFSET)); mmio_read_32(base + GPIO_AFRL_OFFSET));
VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank, VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank,
mmio_read_32(bank_address + GPIO_AFRH_OFFSET)); mmio_read_32(base + GPIO_AFRH_OFFSET));
stm32mp1_clk_disable((unsigned long)clock);
}
void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure)
{
uintptr_t base = stm32_get_gpio_bank_base(bank);
int clock = stm32_get_gpio_bank_clock(bank);
assert(pin <= GPIO_PIN_MAX);
stm32mp1_clk_enable((unsigned long)clock);
if (secure) {
mmio_setbits_32(base + GPIO_SECR_OFFSET, BIT(pin));
} else {
mmio_clrbits_32(base + GPIO_SECR_OFFSET, BIT(pin));
}
stm32mp1_clk_disable((unsigned long)clock);
} }
/* /*
* Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
......
/* /*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -94,6 +94,8 @@ static int stm32image_dev_open(const uintptr_t init_params, ...@@ -94,6 +94,8 @@ static int stm32image_dev_open(const uintptr_t init_params,
for (i = 0; i < STM32_PART_NUM; i++) { for (i = 0; i < STM32_PART_NUM; i++) {
memcpy(stm32image_dev.part_info[i].name, memcpy(stm32image_dev.part_info[i].name,
device_info->part_info[i].name, MAX_PART_NAME_SIZE); device_info->part_info[i].name, MAX_PART_NAME_SIZE);
stm32image_dev.part_info[i].binary_type =
device_info->part_info[i].binary_type;
stm32image_dev.part_info[i].part_offset = stm32image_dev.part_info[i].part_offset =
device_info->part_info[i].part_offset; device_info->part_info[i].part_offset;
stm32image_dev.part_info[i].bkp_offset = stm32image_dev.part_info[i].bkp_offset =
...@@ -193,21 +195,29 @@ static int stm32image_partition_size(io_entity_t *entity, size_t *length) ...@@ -193,21 +195,29 @@ static int stm32image_partition_size(io_entity_t *entity, size_t *length)
result = io_read(backend_handle, (uintptr_t)header, result = io_read(backend_handle, (uintptr_t)header,
MAX_LBA_SIZE, (size_t *)&bytes_read); MAX_LBA_SIZE, (size_t *)&bytes_read);
if (result != 0) { if (result != 0) {
if (current_part->bkp_offset == 0U) {
ERROR("%s: io_read (%i)\n", __func__, result); ERROR("%s: io_read (%i)\n", __func__, result);
break; }
header->magic = 0;
} }
if ((header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) || if ((header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) ||
(header->binary_type != current_part->binary_type) || (header->binary_type != current_part->binary_type) ||
(header->image_length >= stm32image_dev.device_size)) { (header->image_length >= stm32image_dev.device_size)) {
WARN("%s: partition %s wrong header\n", VERBOSE("%s: partition %s not found at %x\n",
__func__, current_part->name); __func__, current_part->name, *stm32_img);
if (current_part->bkp_offset == 0U) {
result = -ENOMEM;
break;
}
/* Header not correct, check next offset for backup */ /* Header not correct, check next offset for backup */
*stm32_img += current_part->bkp_offset; *stm32_img += current_part->bkp_offset;
if (*stm32_img > stm32image_dev.device_size) { if (*stm32_img > stm32image_dev.device_size) {
/* No backup found, end of device reached */ /* No backup found, end of device reached */
WARN("Out of memory\n"); WARN("%s : partition %s not found\n",
__func__, current_part->name);
result = -ENOMEM; result = -ENOMEM;
break; break;
} }
...@@ -221,9 +231,13 @@ static int stm32image_partition_size(io_entity_t *entity, size_t *length) ...@@ -221,9 +231,13 @@ static int stm32image_partition_size(io_entity_t *entity, size_t *length)
return result; return result;
} }
if (header->image_length < stm32image_dev.lba_size) {
*length = stm32image_dev.lba_size;
} else {
*length = header->image_length; *length = header->image_length;
}
INFO("STM32 Image size : %i\n", *length); INFO("STM32 Image size : %lu\n", (unsigned long)*length);
return 0; return 0;
} }
...@@ -266,11 +280,10 @@ static int check_header(boot_api_image_header_t *header, uintptr_t buffer) ...@@ -266,11 +280,10 @@ static int check_header(boot_api_image_header_t *header, uintptr_t buffer)
static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *length_read) size_t length, size_t *length_read)
{ {
int result = 0, offset, local_length = 0; int result = 0;
uint8_t *local_buffer = (uint8_t *)buffer; uint8_t *local_buffer = (uint8_t *)buffer;
boot_api_image_header_t *header = boot_api_image_header_t *header =
(boot_api_image_header_t *)first_lba_buffer; (boot_api_image_header_t *)first_lba_buffer;
uintptr_t backend_handle;
assert(entity != NULL); assert(entity != NULL);
assert(buffer != 0U); assert(buffer != 0U);
...@@ -279,8 +292,17 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, ...@@ -279,8 +292,17 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
*length_read = 0U; *length_read = 0U;
while (*length_read == 0U) { while (*length_read == 0U) {
int offset;
int local_length;
uintptr_t backend_handle;
if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) { if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) {
/* Check for backup as image is corrupted */ /* Check for backup as image is corrupted */
if (current_part->bkp_offset == 0U) {
result = -ENOMEM;
break;
}
*stm32_img += current_part->bkp_offset; *stm32_img += current_part->bkp_offset;
if (*stm32_img >= stm32image_dev.device_size) { if (*stm32_img >= stm32image_dev.device_size) {
/* End of device reached */ /* End of device reached */
...@@ -342,8 +364,8 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, ...@@ -342,8 +364,8 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
if (result != 0) { if (result != 0) {
ERROR("%s: io_read (%i)\n", __func__, result); ERROR("%s: io_read (%i)\n", __func__, result);
*length_read = 0; *length_read = 0;
io_close(backend_handle); header->magic = 0;
break; continue;
} }
result = check_header(header, buffer); result = check_header(header, buffer);
...@@ -351,8 +373,6 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer, ...@@ -351,8 +373,6 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
ERROR("Header check failed\n"); ERROR("Header check failed\n");
*length_read = 0; *length_read = 0;
header->magic = 0; header->magic = 0;
io_close(backend_handle);
break;
} }
io_close(backend_handle); io_close(backend_handle);
......
/* /*
* Copyright (c) 2018, STMicroelectronics - All Rights Reserved * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <common/debug.h> #include <common/debug.h>
#include <drivers/delay_timer.h> #include <drivers/delay_timer.h>
#include <drivers/mmc.h> #include <drivers/mmc.h>
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32_sdmmc2.h> #include <drivers/st/stm32_sdmmc2.h>
#include <drivers/st/stm32mp1_clk.h> #include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_rcc.h> #include <drivers/st/stm32mp1_rcc.h>
...@@ -470,12 +471,11 @@ static int stm32_sdmmc2_prepare(int lba, uintptr_t buf, size_t size) ...@@ -470,12 +471,11 @@ static int stm32_sdmmc2_prepare(int lba, uintptr_t buf, size_t size)
} }
/* Prepare CMD 16*/ /* Prepare CMD 16*/
mmio_write_32(base + SDMMC_DTIMER, UINT32_MAX); mmio_write_32(base + SDMMC_DTIMER, 0);
mmio_write_32(base + SDMMC_DLENR, 0); mmio_write_32(base + SDMMC_DLENR, 0);
mmio_clrsetbits_32(base + SDMMC_DCTRLR, mmio_write_32(base + SDMMC_DCTRLR, 0);
SDMMC_DCTRLR_CLEAR_MASK, SDMMC_DCTRLR_DTDIR);
zeromem(&cmd, sizeof(struct mmc_cmd)); zeromem(&cmd, sizeof(struct mmc_cmd));
...@@ -643,7 +643,7 @@ static int stm32_sdmmc2_dt_get_config(void) ...@@ -643,7 +643,7 @@ static int stm32_sdmmc2_dt_get_config(void)
return -FDT_ERR_NOTFOUND; return -FDT_ERR_NOTFOUND;
} }
if (fdt_check_status(sdmmc_node) == 0) { if (fdt_get_status(sdmmc_node) == DT_DISABLED) {
return -FDT_ERR_NOTFOUND; return -FDT_ERR_NOTFOUND;
} }
...@@ -667,15 +667,15 @@ static int stm32_sdmmc2_dt_get_config(void) ...@@ -667,15 +667,15 @@ static int stm32_sdmmc2_dt_get_config(void)
cuint++; cuint++;
sdmmc2_params.reset_id = fdt32_to_cpu(*cuint); sdmmc2_params.reset_id = fdt32_to_cpu(*cuint);
if ((fdt_getprop(fdt, sdmmc_node, "st,pin-ckin", NULL)) != NULL) { if ((fdt_getprop(fdt, sdmmc_node, "st,use-ckin", NULL)) != NULL) {
sdmmc2_params.pin_ckin = SDMMC_CLKCR_SELCLKRX_0; sdmmc2_params.pin_ckin = SDMMC_CLKCR_SELCLKRX_0;
} }
if ((fdt_getprop(fdt, sdmmc_node, "st,dirpol", NULL)) != NULL) { if ((fdt_getprop(fdt, sdmmc_node, "st,sig-dir", NULL)) != NULL) {
sdmmc2_params.dirpol = SDMMC_POWER_DIRPOL; sdmmc2_params.dirpol = SDMMC_POWER_DIRPOL;
} }
if ((fdt_getprop(fdt, sdmmc_node, "st,negedge", NULL)) != NULL) { if ((fdt_getprop(fdt, sdmmc_node, "st,neg-edge", NULL)) != NULL) {
sdmmc2_params.negedge = SDMMC_CLKCR_NEGEDGE; sdmmc2_params.negedge = SDMMC_CLKCR_NEGEDGE;
} }
......
/* /*
* Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -13,10 +13,10 @@ ...@@ -13,10 +13,10 @@
#include <common/debug.h> #include <common/debug.h>
#include <drivers/delay_timer.h> #include <drivers/delay_timer.h>
#include <drivers/st/stm32mp_pmic.h>
#include <drivers/st/stm32_gpio.h> #include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32mp1_clk.h> #include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_pmic.h> #include <drivers/st/stpmic1.h>
#include <drivers/st/stpmu1.h>
#include <lib/mmio.h> #include <lib/mmio.h>
#include <lib/utils_def.h> #include <lib/utils_def.h>
...@@ -27,23 +27,23 @@ ...@@ -27,23 +27,23 @@
#define MASK_RESET_BUCK3 BIT(2) #define MASK_RESET_BUCK3 BIT(2)
#define STPMU1_LDO12356_OUTPUT_MASK (uint8_t)(GENMASK(6, 2)) #define STPMIC1_LDO12356_OUTPUT_MASK (uint8_t)(GENMASK(6, 2))
#define STPMU1_LDO12356_OUTPUT_SHIFT 2 #define STPMIC1_LDO12356_OUTPUT_SHIFT 2
#define STPMU1_LDO3_MODE (uint8_t)(BIT(7)) #define STPMIC1_LDO3_MODE (uint8_t)(BIT(7))
#define STPMU1_LDO3_DDR_SEL 31U #define STPMIC1_LDO3_DDR_SEL 31U
#define STPMU1_LDO3_1800000 (9U << STPMU1_LDO12356_OUTPUT_SHIFT) #define STPMIC1_LDO3_1800000 (9U << STPMIC1_LDO12356_OUTPUT_SHIFT)
#define STPMU1_BUCK_OUTPUT_SHIFT 2 #define STPMIC1_BUCK_OUTPUT_SHIFT 2
#define STPMU1_BUCK3_1V8 (39U << STPMU1_BUCK_OUTPUT_SHIFT) #define STPMIC1_BUCK3_1V8 (39U << STPMIC1_BUCK_OUTPUT_SHIFT)
#define STPMU1_DEFAULT_START_UP_DELAY_MS 1 #define STPMIC1_DEFAULT_START_UP_DELAY_MS 1
static struct i2c_handle_s i2c_handle; static struct i2c_handle_s i2c_handle;
static uint32_t pmic_i2c_addr; static uint32_t pmic_i2c_addr;
static int dt_get_pmic_node(void *fdt) static int dt_get_pmic_node(void *fdt)
{ {
return fdt_node_offset_by_compatible(fdt, -1, "st,stpmu1"); return fdt_node_offset_by_compatible(fdt, -1, "st,stpmic1");
} }
bool dt_check_pmic(void) bool dt_check_pmic(void)
...@@ -61,7 +61,7 @@ bool dt_check_pmic(void) ...@@ -61,7 +61,7 @@ bool dt_check_pmic(void)
return false; return false;
} }
return fdt_check_status(node); return fdt_get_status(node);
} }
static int dt_pmic_i2c_config(struct dt_node_info *i2c_info) static int dt_pmic_i2c_config(struct dt_node_info *i2c_info)
...@@ -138,16 +138,16 @@ int dt_pmic_enable_boot_on_regulators(void) ...@@ -138,16 +138,16 @@ int dt_pmic_enable_boot_on_regulators(void)
voltage = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U); voltage = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
node_name = fdt_get_name(fdt, regulator_node, NULL); node_name = fdt_get_name(fdt, regulator_node, NULL);
if (stpmu1_is_regulator_enabled(node_name) == 0U) { if (stpmic1_is_regulator_enabled(node_name) == 0U) {
int status; int status;
status = stpmu1_regulator_voltage_set(node_name, status = stpmic1_regulator_voltage_set(node_name,
voltage); voltage);
if (status != 0) { if (status != 0) {
return status; return status;
} }
status = stpmu1_regulator_enable(node_name); status = stpmic1_regulator_enable(node_name);
if (status != 0) { if (status != 0) {
return status; return status;
} }
...@@ -204,7 +204,7 @@ void initialize_pmic_i2c(void) ...@@ -204,7 +204,7 @@ void initialize_pmic_i2c(void)
panic(); panic();
} }
stpmu1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr); stpmic1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr);
} }
void initialize_pmic(void) void initialize_pmic(void)
...@@ -214,7 +214,7 @@ void initialize_pmic(void) ...@@ -214,7 +214,7 @@ void initialize_pmic(void)
initialize_pmic_i2c(); initialize_pmic_i2c();
status = stpmu1_register_read(VERSION_STATUS_REG, &read_val); status = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
if (status != 0) { if (status != 0) {
panic(); panic();
} }
...@@ -222,7 +222,7 @@ void initialize_pmic(void) ...@@ -222,7 +222,7 @@ void initialize_pmic(void)
INFO("PMIC version = 0x%x\n", read_val); INFO("PMIC version = 0x%x\n", read_val);
/* Keep VDD on during the reset cycle */ /* Keep VDD on during the reset cycle */
status = stpmu1_register_update(MASK_RESET_BUCK_REG, status = stpmic1_register_update(MASK_RESET_BUCK_REG,
MASK_RESET_BUCK3, MASK_RESET_BUCK3,
MASK_RESET_BUCK3); MASK_RESET_BUCK3);
if (status != 0) { if (status != 0) {
...@@ -239,45 +239,46 @@ int pmic_ddr_power_init(enum ddr_type ddr_type) ...@@ -239,45 +239,46 @@ int pmic_ddr_power_init(enum ddr_type ddr_type)
switch (ddr_type) { switch (ddr_type) {
case STM32MP_DDR3: case STM32MP_DDR3:
/* Set LDO3 to sync mode */ /* Set LDO3 to sync mode */
status = stpmu1_register_read(LDO3_CONTROL_REG, &read_val); status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
if (status != 0) { if (status != 0) {
return status; return status;
} }
read_val &= ~STPMU1_LDO3_MODE; read_val &= ~STPMIC1_LDO3_MODE;
read_val &= ~STPMU1_LDO12356_OUTPUT_MASK; read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
read_val |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT; read_val |= STPMIC1_LDO3_DDR_SEL <<
STPMIC1_LDO12356_OUTPUT_SHIFT;
status = stpmu1_register_write(LDO3_CONTROL_REG, read_val); status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
if (status != 0) { if (status != 0) {
return status; return status;
} }
status = stpmu1_regulator_voltage_set("buck2", 1350); status = stpmic1_regulator_voltage_set("buck2", 1350);
if (status != 0) { if (status != 0) {
return status; return status;
} }
status = stpmu1_regulator_enable("buck2"); status = stpmic1_regulator_enable("buck2");
if (status != 0) { if (status != 0) {
return status; return status;
} }
mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS); mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
status = stpmu1_regulator_enable("vref_ddr"); status = stpmic1_regulator_enable("vref_ddr");
if (status != 0) { if (status != 0) {
return status; return status;
} }
mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS); mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
status = stpmu1_regulator_enable("ldo3"); status = stpmic1_regulator_enable("ldo3");
if (status != 0) { if (status != 0) {
return status; return status;
} }
mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS); mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
break; break;
case STM32MP_LPDDR2: case STM32MP_LPDDR2:
...@@ -286,57 +287,57 @@ int pmic_ddr_power_init(enum ddr_type ddr_type) ...@@ -286,57 +287,57 @@ int pmic_ddr_power_init(enum ddr_type ddr_type)
* Set LDO3 to bypass mode if BUCK3 = 1.8V * Set LDO3 to bypass mode if BUCK3 = 1.8V
* Set LDO3 to normal mode if BUCK3 != 1.8V * Set LDO3 to normal mode if BUCK3 != 1.8V
*/ */
status = stpmu1_register_read(BUCK3_CONTROL_REG, &read_val); status = stpmic1_register_read(BUCK3_CONTROL_REG, &read_val);
if (status != 0) { if (status != 0) {
return status; return status;
} }
if ((read_val & STPMU1_BUCK3_1V8) == STPMU1_BUCK3_1V8) { if ((read_val & STPMIC1_BUCK3_1V8) == STPMIC1_BUCK3_1V8) {
buck3_at_1v8 = true; buck3_at_1v8 = true;
} }
status = stpmu1_register_read(LDO3_CONTROL_REG, &read_val); status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
if (status != 0) { if (status != 0) {
return status; return status;
} }
read_val &= ~STPMU1_LDO3_MODE; read_val &= ~STPMIC1_LDO3_MODE;
read_val &= ~STPMU1_LDO12356_OUTPUT_MASK; read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
read_val |= STPMU1_LDO3_1800000; read_val |= STPMIC1_LDO3_1800000;
if (buck3_at_1v8) { if (buck3_at_1v8) {
read_val |= STPMU1_LDO3_MODE; read_val |= STPMIC1_LDO3_MODE;
} }
status = stpmu1_register_write(LDO3_CONTROL_REG, read_val); status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
if (status != 0) { if (status != 0) {
return status; return status;
} }
status = stpmu1_regulator_voltage_set("buck2", 1200); status = stpmic1_regulator_voltage_set("buck2", 1200);
if (status != 0) { if (status != 0) {
return status; return status;
} }
status = stpmu1_regulator_enable("ldo3"); status = stpmic1_regulator_enable("ldo3");
if (status != 0) { if (status != 0) {
return status; return status;
} }
mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS); mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
status = stpmu1_regulator_enable("buck2"); status = stpmic1_regulator_enable("buck2");
if (status != 0) { if (status != 0) {
return status; return status;
} }
mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS); mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
status = stpmu1_regulator_enable("vref_ddr"); status = stpmic1_regulator_enable("vref_ddr");
if (status != 0) { if (status != 0) {
return status; return status;
} }
mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS); mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
break; break;
default: default:
......
/* /*
* Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <string.h> #include <string.h>
#include <common/debug.h> #include <common/debug.h>
#include <drivers/st/stpmu1.h> #include <drivers/st/stpmic1.h>
#include <plat/common/platform.h> #include <plat/common/platform.h>
struct regul_struct { struct regul_struct {
...@@ -16,18 +16,22 @@ struct regul_struct { ...@@ -16,18 +16,22 @@ struct regul_struct {
uint8_t voltage_table_size; uint8_t voltage_table_size;
uint8_t control_reg; uint8_t control_reg;
uint8_t low_power_reg; uint8_t low_power_reg;
uint8_t pull_down_reg;
uint8_t pull_down;
uint8_t mask_reset_reg;
uint8_t mask_reset;
}; };
static struct i2c_handle_s *stpmu_i2c_handle; static struct i2c_handle_s *pmic_i2c_handle;
static uint16_t stpmu_i2c_addr; static uint16_t pmic_i2c_addr;
/* Voltage tables in mV */ /* Voltage tables in mV */
static const uint16_t buck1_voltage_table[] = { static const uint16_t buck1_voltage_table[] = {
600, 725,
625, 725,
650, 725,
675, 725,
700, 725,
725, 725,
750, 750,
775, 775,
...@@ -54,7 +58,39 @@ static const uint16_t buck1_voltage_table[] = { ...@@ -54,7 +58,39 @@ static const uint16_t buck1_voltage_table[] = {
1300, 1300,
1325, 1325,
1350, 1350,
1350, 1375,
1400,
1425,
1450,
1475,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
1500,
}; };
static const uint16_t buck2_voltage_table[] = { static const uint16_t buck2_voltage_table[] = {
...@@ -308,6 +344,7 @@ static const uint16_t ldo3_voltage_table[] = { ...@@ -308,6 +344,7 @@ static const uint16_t ldo3_voltage_table[] = {
3300, 3300,
3300, 3300,
3300, 3300,
500,
0xFFFF, /* VREFDDR */ 0xFFFF, /* VREFDDR */
}; };
...@@ -389,6 +426,10 @@ static const struct regul_struct regulators_table[] = { ...@@ -389,6 +426,10 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(buck1_voltage_table), .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
.control_reg = BUCK1_CONTROL_REG, .control_reg = BUCK1_CONTROL_REG,
.low_power_reg = BUCK1_PWRCTRL_REG, .low_power_reg = BUCK1_PWRCTRL_REG,
.pull_down_reg = BUCK_PULL_DOWN_REG,
.pull_down = BUCK1_PULL_DOWN_SHIFT,
.mask_reset_reg = MASK_RESET_BUCK_REG,
.mask_reset = BUCK1_MASK_RESET,
}, },
{ {
.dt_node_name = "buck2", .dt_node_name = "buck2",
...@@ -396,6 +437,10 @@ static const struct regul_struct regulators_table[] = { ...@@ -396,6 +437,10 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(buck2_voltage_table), .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
.control_reg = BUCK2_CONTROL_REG, .control_reg = BUCK2_CONTROL_REG,
.low_power_reg = BUCK2_PWRCTRL_REG, .low_power_reg = BUCK2_PWRCTRL_REG,
.pull_down_reg = BUCK_PULL_DOWN_REG,
.pull_down = BUCK2_PULL_DOWN_SHIFT,
.mask_reset_reg = MASK_RESET_BUCK_REG,
.mask_reset = BUCK2_MASK_RESET,
}, },
{ {
.dt_node_name = "buck3", .dt_node_name = "buck3",
...@@ -403,6 +448,10 @@ static const struct regul_struct regulators_table[] = { ...@@ -403,6 +448,10 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(buck3_voltage_table), .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
.control_reg = BUCK3_CONTROL_REG, .control_reg = BUCK3_CONTROL_REG,
.low_power_reg = BUCK3_PWRCTRL_REG, .low_power_reg = BUCK3_PWRCTRL_REG,
.pull_down_reg = BUCK_PULL_DOWN_REG,
.pull_down = BUCK3_PULL_DOWN_SHIFT,
.mask_reset_reg = MASK_RESET_BUCK_REG,
.mask_reset = BUCK3_MASK_RESET,
}, },
{ {
.dt_node_name = "buck4", .dt_node_name = "buck4",
...@@ -410,6 +459,10 @@ static const struct regul_struct regulators_table[] = { ...@@ -410,6 +459,10 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(buck4_voltage_table), .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
.control_reg = BUCK4_CONTROL_REG, .control_reg = BUCK4_CONTROL_REG,
.low_power_reg = BUCK4_PWRCTRL_REG, .low_power_reg = BUCK4_PWRCTRL_REG,
.pull_down_reg = BUCK_PULL_DOWN_REG,
.pull_down = BUCK4_PULL_DOWN_SHIFT,
.mask_reset_reg = MASK_RESET_BUCK_REG,
.mask_reset = BUCK4_MASK_RESET,
}, },
{ {
.dt_node_name = "ldo1", .dt_node_name = "ldo1",
...@@ -417,6 +470,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -417,6 +470,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table), .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
.control_reg = LDO1_CONTROL_REG, .control_reg = LDO1_CONTROL_REG,
.low_power_reg = LDO1_PWRCTRL_REG, .low_power_reg = LDO1_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO1_MASK_RESET,
}, },
{ {
.dt_node_name = "ldo2", .dt_node_name = "ldo2",
...@@ -424,6 +479,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -424,6 +479,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table), .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
.control_reg = LDO2_CONTROL_REG, .control_reg = LDO2_CONTROL_REG,
.low_power_reg = LDO2_PWRCTRL_REG, .low_power_reg = LDO2_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO2_MASK_RESET,
}, },
{ {
.dt_node_name = "ldo3", .dt_node_name = "ldo3",
...@@ -431,6 +488,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -431,6 +488,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table), .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
.control_reg = LDO3_CONTROL_REG, .control_reg = LDO3_CONTROL_REG,
.low_power_reg = LDO3_PWRCTRL_REG, .low_power_reg = LDO3_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO3_MASK_RESET,
}, },
{ {
.dt_node_name = "ldo4", .dt_node_name = "ldo4",
...@@ -438,6 +497,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -438,6 +497,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table), .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
.control_reg = LDO4_CONTROL_REG, .control_reg = LDO4_CONTROL_REG,
.low_power_reg = LDO4_PWRCTRL_REG, .low_power_reg = LDO4_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO4_MASK_RESET,
}, },
{ {
.dt_node_name = "ldo5", .dt_node_name = "ldo5",
...@@ -445,6 +506,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -445,6 +506,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table), .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
.control_reg = LDO5_CONTROL_REG, .control_reg = LDO5_CONTROL_REG,
.low_power_reg = LDO5_PWRCTRL_REG, .low_power_reg = LDO5_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO5_MASK_RESET,
}, },
{ {
.dt_node_name = "ldo6", .dt_node_name = "ldo6",
...@@ -452,6 +515,8 @@ static const struct regul_struct regulators_table[] = { ...@@ -452,6 +515,8 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table), .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
.control_reg = LDO6_CONTROL_REG, .control_reg = LDO6_CONTROL_REG,
.low_power_reg = LDO6_PWRCTRL_REG, .low_power_reg = LDO6_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = LDO6_MASK_RESET,
}, },
{ {
.dt_node_name = "vref_ddr", .dt_node_name = "vref_ddr",
...@@ -459,12 +524,14 @@ static const struct regul_struct regulators_table[] = { ...@@ -459,12 +524,14 @@ static const struct regul_struct regulators_table[] = {
.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table), .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
.control_reg = VREF_DDR_CONTROL_REG, .control_reg = VREF_DDR_CONTROL_REG,
.low_power_reg = VREF_DDR_PWRCTRL_REG, .low_power_reg = VREF_DDR_PWRCTRL_REG,
.mask_reset_reg = MASK_RESET_LDO_REG,
.mask_reset = VREF_DDR_MASK_RESET,
}, },
}; };
#define MAX_REGUL ARRAY_SIZE(regulators_table) #define MAX_REGUL ARRAY_SIZE(regulators_table)
static const struct regul_struct *stpmu1_get_regulator_data(const char *name) static const struct regul_struct *get_regulator_data(const char *name)
{ {
uint8_t i; uint8_t i;
...@@ -480,10 +547,9 @@ static const struct regul_struct *stpmu1_get_regulator_data(const char *name) ...@@ -480,10 +547,9 @@ static const struct regul_struct *stpmu1_get_regulator_data(const char *name)
return NULL; return NULL;
} }
static uint8_t stpmu1_voltage_find_index(const char *name, static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
uint16_t millivolts)
{ {
const struct regul_struct *regul = stpmu1_get_regulator_data(name); const struct regul_struct *regul = get_regulator_data(name);
uint8_t i; uint8_t i;
for (i = 0 ; i < regul->voltage_table_size ; i++) { for (i = 0 ; i < regul->voltage_table_size ; i++) {
...@@ -498,62 +564,132 @@ static uint8_t stpmu1_voltage_find_index(const char *name, ...@@ -498,62 +564,132 @@ static uint8_t stpmu1_voltage_find_index(const char *name,
return 0; return 0;
} }
int stpmu1_switch_off(void) int stpmic1_powerctrl_on(void)
{
return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
PWRCTRL_PIN_VALID);
}
int stpmic1_switch_off(void)
{ {
return stpmu1_register_update(MAIN_CONTROL_REG, 1, return stpmic1_register_update(MAIN_CONTROL_REG, 1,
SOFTWARE_SWITCH_OFF_ENABLED); SOFTWARE_SWITCH_OFF_ENABLED);
} }
int stpmu1_regulator_enable(const char *name) int stpmic1_regulator_enable(const char *name)
{ {
const struct regul_struct *regul = stpmu1_get_regulator_data(name); const struct regul_struct *regul = get_regulator_data(name);
return stpmu1_register_update(regul->control_reg, BIT(0), BIT(0)); return stpmic1_register_update(regul->control_reg, BIT(0), BIT(0));
} }
int stpmu1_regulator_disable(const char *name) int stpmic1_regulator_disable(const char *name)
{ {
const struct regul_struct *regul = stpmu1_get_regulator_data(name); const struct regul_struct *regul = get_regulator_data(name);
return stpmu1_register_update(regul->control_reg, 0, BIT(0)); return stpmic1_register_update(regul->control_reg, 0, BIT(0));
} }
uint8_t stpmu1_is_regulator_enabled(const char *name) uint8_t stpmic1_is_regulator_enabled(const char *name)
{ {
uint8_t val; uint8_t val;
const struct regul_struct *regul = stpmu1_get_regulator_data(name); const struct regul_struct *regul = get_regulator_data(name);
if (stpmu1_register_read(regul->control_reg, &val) != 0) { if (stpmic1_register_read(regul->control_reg, &val) != 0) {
panic(); panic();
} }
return (val & 0x1U); return (val & 0x1U);
} }
int stpmu1_regulator_voltage_set(const char *name, uint16_t millivolts) int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
{ {
uint8_t voltage_index = stpmu1_voltage_find_index(name, millivolts); uint8_t voltage_index = voltage_to_index(name, millivolts);
const struct regul_struct *regul = stpmu1_get_regulator_data(name); const struct regul_struct *regul = get_regulator_data(name);
uint8_t mask;
/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
if (strncmp(name, "buck", 4) == 0) {
mask = BUCK_VOLTAGE_MASK;
} else if ((strncmp(name, "ldo", 3) == 0) &&
(strncmp(name, "ldo4", 4) != 0)) {
mask = LDO_VOLTAGE_MASK;
} else {
return 0;
}
return stpmic1_register_update(regul->control_reg,
voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
mask);
}
int stpmic1_regulator_pull_down_set(const char *name)
{
const struct regul_struct *regul = get_regulator_data(name);
if (regul->pull_down_reg != 0) {
return stpmic1_register_update(regul->pull_down_reg,
BIT(regul->pull_down),
LDO_BUCK_PULL_DOWN_MASK <<
regul->pull_down);
}
return 0;
}
int stpmic1_regulator_mask_reset_set(const char *name)
{
const struct regul_struct *regul = get_regulator_data(name);
return stpmic1_register_update(regul->mask_reset_reg,
BIT(regul->mask_reset),
LDO_BUCK_RESET_MASK <<
regul->mask_reset);
}
int stpmic1_regulator_voltage_get(const char *name)
{
const struct regul_struct *regul = get_regulator_data(name);
uint8_t value;
uint8_t mask;
/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
if (strncmp(name, "buck", 4) == 0) {
mask = BUCK_VOLTAGE_MASK;
} else if ((strncmp(name, "ldo", 3) == 0) &&
(strncmp(name, "ldo4", 4) != 0)) {
mask = LDO_VOLTAGE_MASK;
} else {
return 0;
}
return stpmu1_register_update(regul->control_reg, voltage_index << 2, if (stpmic1_register_read(regul->control_reg, &value))
0xFC); return -1;
value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
if (value > regul->voltage_table_size)
return -1;
return (int)regul->voltage_table[value];
} }
int stpmu1_register_read(uint8_t register_id, uint8_t *value) int stpmic1_register_read(uint8_t register_id, uint8_t *value)
{ {
return stm32_i2c_mem_read(stpmu_i2c_handle, stpmu_i2c_addr, return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
(uint16_t)register_id, I2C_MEMADD_SIZE_8BIT, (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT,
value, 1, 100000); value, 1, 100000);
} }
int stpmu1_register_write(uint8_t register_id, uint8_t value) int stpmic1_register_write(uint8_t register_id, uint8_t value)
{ {
int status; int status;
status = stm32_i2c_mem_write(stpmu_i2c_handle, stpmu_i2c_addr, status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
(uint16_t)register_id, (uint16_t)register_id,
I2C_MEMADD_SIZE_8BIT, &value, 1, 100000); I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
#if ENABLE_ASSERTIONS
if (status != 0) { if (status != 0) {
return status; return status;
} }
...@@ -561,7 +697,7 @@ int stpmu1_register_write(uint8_t register_id, uint8_t value) ...@@ -561,7 +697,7 @@ int stpmu1_register_write(uint8_t register_id, uint8_t value)
if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) { if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
uint8_t readval; uint8_t readval;
status = stpmu1_register_read(register_id, &readval); status = stpmic1_register_read(register_id, &readval);
if (status != 0) { if (status != 0) {
return status; return status;
} }
...@@ -570,32 +706,57 @@ int stpmu1_register_write(uint8_t register_id, uint8_t value) ...@@ -570,32 +706,57 @@ int stpmu1_register_write(uint8_t register_id, uint8_t value)
return -1; return -1;
} }
} }
#endif
return 0; return status;
} }
int stpmu1_register_update(uint8_t register_id, uint8_t value, uint8_t mask) int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
{ {
int status; int status;
uint8_t val; uint8_t val;
status = stpmu1_register_read(register_id, &val); status = stpmic1_register_read(register_id, &val);
if (status != 0) { if (status != 0) {
return status; return status;
} }
/* Clear bits to update */ val = (val & ~mask) | (value & mask);
val &= ~mask;
/* Update appropriate bits*/ return stpmic1_register_write(register_id, val);
val |= (value & mask); }
/* Send new value on I2C Bus */ void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
return stpmu1_register_write(register_id, val); {
pmic_i2c_handle = i2c_handle;
pmic_i2c_addr = i2c_addr;
} }
void stpmu1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr) void stpmic1_dump_regulators(void)
{ {
stpmu_i2c_handle = i2c_handle; uint32_t i;
stpmu_i2c_addr = i2c_addr;
for (i = 0U; i < MAX_REGUL; i++) {
const char *name __unused = regulators_table[i].dt_node_name;
VERBOSE("PMIC regul %s: %sable, %dmV",
name,
stpmic1_is_regulator_enabled(name) ? "en" : "dis",
stpmic1_regulator_voltage_get(name));
}
}
int stpmic1_get_version(unsigned long *version)
{
int rc;
uint8_t read_val;
rc = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
if (rc) {
return -1;
}
*version = (unsigned long)read_val;
return 0;
} }
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
/ { / {
soc { soc {
ddr: ddr@0x5A003000{ ddr: ddr@5A003000{
compatible = "st,stm32mp1-ddr"; compatible = "st,stm32mp1-ddr";
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
*/ */
/* STM32MP157C ED1 and ED2 BOARD configuration /* STM32MP157C ED1 BOARD configuration
* 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology. * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology.
* Reference used NT5CC256M16DP-DI from NANYA * Reference used NT5CC256M16DP-DI from NANYA
* *
...@@ -15,10 +15,11 @@ ...@@ -15,10 +15,11 @@
* timing mode optimized * timing mode optimized
* Scheduling/QoS options : type = 2 * Scheduling/QoS options : type = 2
* address mapping : RBC * address mapping : RBC
* Tc > + 85C : N
*/ */
#define DDR_MEM_NAME "DDR3-1066 bin G 2x4Gb 533MHz v1.39" #define DDR_MEM_NAME "DDR3-1066/888 bin G 2x4Gb 533MHz v1.41"
#define DDR_MEM_SPEED 533 #define DDR_MEM_SPEED 533000
#define DDR_MEM_SIZE 0x40000000 #define DDR_MEM_SIZE 0x40000000
#define DDR_MSTR 0x00040401 #define DDR_MSTR 0x00040401
...@@ -62,7 +63,7 @@ ...@@ -62,7 +63,7 @@
#define DDR_ADDRMAP11 0x00000000 #define DDR_ADDRMAP11 0x00000000
#define DDR_ODTCFG 0x06000600 #define DDR_ODTCFG 0x06000600
#define DDR_ODTMAP 0x00000001 #define DDR_ODTMAP 0x00000001
#define DDR_SCHED 0x00001201 #define DDR_SCHED 0x00000C01
#define DDR_SCHED1 0x00000000 #define DDR_SCHED1 0x00000000
#define DDR_PERFHPR1 0x01000001 #define DDR_PERFHPR1 0x01000001
#define DDR_PERFLPR1 0x08000200 #define DDR_PERFLPR1 0x08000200
...@@ -74,15 +75,15 @@ ...@@ -74,15 +75,15 @@
#define DDR_PCCFG 0x00000010 #define DDR_PCCFG 0x00000010
#define DDR_PCFGR_0 0x00010000 #define DDR_PCFGR_0 0x00010000
#define DDR_PCFGW_0 0x00000000 #define DDR_PCFGW_0 0x00000000
#define DDR_PCFGQOS0_0 0x02100B03 #define DDR_PCFGQOS0_0 0x02100C03
#define DDR_PCFGQOS1_0 0x00800100 #define DDR_PCFGQOS1_0 0x00800100
#define DDR_PCFGWQOS0_0 0x01100B03 #define DDR_PCFGWQOS0_0 0x01100C03
#define DDR_PCFGWQOS1_0 0x01000200 #define DDR_PCFGWQOS1_0 0x01000200
#define DDR_PCFGR_1 0x00010000 #define DDR_PCFGR_1 0x00010000
#define DDR_PCFGW_1 0x00000000 #define DDR_PCFGW_1 0x00000000
#define DDR_PCFGQOS0_1 0x02100B03 #define DDR_PCFGQOS0_1 0x02100C03
#define DDR_PCFGQOS1_1 0x00800000 #define DDR_PCFGQOS1_1 0x00800040
#define DDR_PCFGWQOS0_1 0x01100B03 #define DDR_PCFGWQOS0_1 0x01100C03
#define DDR_PCFGWQOS1_1 0x01000200 #define DDR_PCFGWQOS1_1 0x01000200
#define DDR_PGCR 0x01442E02 #define DDR_PGCR 0x01442E02
#define DDR_PTR0 0x0022AA5B #define DDR_PTR0 0x0022AA5B
......
...@@ -3,13 +3,14 @@ ...@@ -3,13 +3,14 @@
* Copyright (C) STMicroelectronics 2017 - All Rights Reserved * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics. * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/ */
#include <dt-bindings/pinctrl/stm32-pinfunc.h> #include <dt-bindings/pinctrl/stm32-pinfunc.h>
/ { / {
soc { soc {
pinctrl: pin-controller { pinctrl: pin-controller@50002000 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
compatible = "st,stm32mp157-pinctrl";
ranges = <0 0x50002000 0xa400>; ranges = <0 0x50002000 0xa400>;
pins-are-numbered; pins-are-numbered;
...@@ -134,54 +135,76 @@ ...@@ -134,54 +135,76 @@
status = "disabled"; status = "disabled";
}; };
uart4_pins_a: uart4@0 { qspi_bk1_pins_a: qspi-bk1-0 {
pins1 { pins1 {
pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */ pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
<STM32_PINMUX('F', 9, AF10)>, /* QSPI_BK1_IO1 */
<STM32_PINMUX('F', 7, AF9)>, /* QSPI_BK1_IO2 */
<STM32_PINMUX('F', 6, AF9)>; /* QSPI_BK1_IO3 */
bias-disable; bias-disable;
drive-push-pull; drive-push-pull;
slew-rate = <0>; slew-rate = <1>;
}; };
pins2 { pins2 {
pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */ pinmux = <STM32_PINMUX('B', 6, AF10)>; /* QSPI_BK1_NCS */
bias-disable; bias-pull-up;
drive-push-pull;
slew-rate = <1>;
}; };
}; };
usart3_pins_a: usart3@0 { qspi_bk2_pins_a: qspi-bk2-0 {
pins1 { pins1 {
pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */ pinmux = <STM32_PINMUX('H', 2, AF9)>, /* QSPI_BK2_IO0 */
<STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */ <STM32_PINMUX('H', 3, AF9)>, /* QSPI_BK2_IO1 */
<STM32_PINMUX('G', 10, AF11)>, /* QSPI_BK2_IO2 */
<STM32_PINMUX('G', 7, AF11)>; /* QSPI_BK2_IO3 */
bias-disable; bias-disable;
drive-push-pull; drive-push-pull;
slew-rate = <0>; slew-rate = <1>;
}; };
pins2 { pins2 {
pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */ pinmux = <STM32_PINMUX('C', 0, AF10)>; /* QSPI_BK2_NCS */
<STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */ bias-pull-up;
bias-disable; drive-push-pull;
slew-rate = <1>;
}; };
}; };
sdmmc1_b4_pins_a: sdmmc1-b4@0 { qspi_clk_pins_a: qspi-clk-0 {
pins { pins {
pinmux = <STM32_PINMUX('F', 10, AF9)>; /* QSPI_CLK */
bias-disable;
drive-push-pull;
slew-rate = <3>;
};
};
sdmmc1_b4_pins_a: sdmmc1-b4-0 {
pins1 {
pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */ pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
<STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */ <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
<STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */ <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
<STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */ <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
<STM32_PINMUX('C', 12, AF12)>, /* SDMMC1_CK */
<STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */ <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
slew-rate = <3>; slew-rate = <1>;
drive-push-pull;
bias-disable;
};
pins2 {
pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
slew-rate = <2>;
drive-push-pull; drive-push-pull;
bias-disable; bias-disable;
}; };
}; };
sdmmc1_dir_pins_a: sdmmc1-dir@0 { sdmmc1_dir_pins_a: sdmmc1-dir-0 {
pins1 { pins1 {
pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */ pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
<STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */ <STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */
<STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */ <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
slew-rate = <3>; slew-rate = <1>;
drive-push-pull; drive-push-pull;
bias-pull-up; bias-pull-up;
}; };
...@@ -191,36 +214,85 @@ ...@@ -191,36 +214,85 @@
}; };
}; };
sdmmc2_b4_pins_a: sdmmc2-b4@0 { sdmmc1_dir_pins_b: sdmmc1-dir-1 {
pins { pins1 {
pinmux = <STM32_PINMUX('E', 12, AF8)>, /* SDMMC1_D0DIR */
<STM32_PINMUX('E', 14, AF11)>, /* SDMMC1_D123DIR */
<STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
slew-rate = <3>;
drive-push-pull;
bias-pull-up;
};
pins2 {
pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
bias-pull-up;
};
};
sdmmc2_b4_pins_a: sdmmc2-b4-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */ pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
<STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */ <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
<STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */ <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
<STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */ <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
<STM32_PINMUX('E', 3, AF9)>, /* SDMMC2_CK */
<STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */ <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
slew-rate = <3>; slew-rate = <1>;
drive-push-pull;
bias-pull-up;
};
pins2 {
pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
slew-rate = <2>;
drive-push-pull; drive-push-pull;
bias-pull-up; bias-pull-up;
}; };
}; };
sdmmc2_d47_pins_a: sdmmc2-d47@0 { sdmmc2_d47_pins_a: sdmmc2-d47-0 {
pins { pins {
pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */ pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
<STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */ <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
<STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */ <STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */
<STM32_PINMUX('D', 3, AF9)>; /* SDMMC2_D7 */ <STM32_PINMUX('D', 3, AF9)>; /* SDMMC2_D7 */
slew-rate = <3>; slew-rate = <1>;
drive-push-pull; drive-push-pull;
bias-pull-up; bias-pull-up;
}; };
}; };
uart4_pins_a: uart4-0 {
pins1 {
pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
bias-disable;
drive-push-pull;
slew-rate = <0>;
};
pins2 {
pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
bias-disable;
};
};
usart3_pins_a: usart3-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
<STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
bias-disable;
drive-push-pull;
slew-rate = <0>;
};
pins2 {
pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
<STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */
bias-disable;
};
};
}; };
pinctrl_z: pin-controller-z { pinctrl_z: pin-controller-z@54004000 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
compatible = "st,stm32mp157-z-pinctrl";
ranges = <0 0x54004000 0x400>; ranges = <0 0x54004000 0x400>;
pins-are-numbered; pins-are-numbered;
...@@ -236,7 +308,7 @@ ...@@ -236,7 +308,7 @@
status = "disabled"; status = "disabled";
}; };
i2c4_pins_a: i2c4@0 { i2c4_pins_a: i2c4-0 {
pins { pins {
pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */ pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
<STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */ <STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */
......
...@@ -3,22 +3,28 @@ ...@@ -3,22 +3,28 @@
* Copyright (C) STMicroelectronics 2017 - All Rights Reserved * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics. * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/ */
/dts-v1/; /dts-v1/;
#include "stm32mp157c.dtsi" #include "stm32mp157c.dtsi"
#include "stm32mp157caa-pinctrl.dtsi" #include "stm32mp157caa-pinctrl.dtsi"
/ { / {
model = "STMicroelectronics STM32MP157C-ED1 pmic eval daughter"; model = "STMicroelectronics STM32MP157C eval daughter";
compatible = "st,stm32mp157c-ed1", "st,stm32mp157"; compatible = "st,stm32mp157c-ed1", "st,stm32mp157";
chosen { chosen {
bootargs = "earlyprintk console=ttyS3,115200 root=/dev/ram"; stdout-path = "serial0:115200n8";
stdout-path = "serial3:115200n8"; };
aliases {
serial0 = &uart4;
}; };
}; };
&clk_hse {
st,digbypass;
};
&i2c4 { &i2c4 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&i2c4_pins_a>; pinctrl-0 = <&i2c4_pins_a>;
...@@ -26,37 +32,88 @@ ...@@ -26,37 +32,88 @@
i2c-scl-falling-time-ns = <20>; i2c-scl-falling-time-ns = <20>;
status = "okay"; status = "okay";
pmic: stpmu1@33 { pmic: stpmic@33 {
compatible = "st,stpmu1"; compatible = "st,stpmic1";
reg = <0x33>; reg = <0x33>;
interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <2>;
status = "okay"; status = "okay";
st,main_control_register = <0x04>; st,main-control-register = <0x04>;
st,vin_control_register = <0xc0>; st,vin-control-register = <0xc0>;
st,usb_control_register = <0x30>; st,usb-control-register = <0x30>;
regulators { regulators {
compatible = "st,stpmu1-regulators"; compatible = "st,stpmic1-regulators";
ldo1-supply = <&v3v3>;
ldo2-supply = <&v3v3>;
ldo3-supply = <&vdd_ddr>;
ldo5-supply = <&v3v3>;
ldo6-supply = <&v3v3>;
vddcore: buck1 {
regulator-name = "vddcore";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-initial-mode = <0>;
regulator-over-current-protection;
};
vdd_ddr: buck2 {
regulator-name = "vdd_ddr";
regulator-min-microvolt = <1350000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-initial-mode = <0>;
regulator-over-current-protection;
};
vdd: buck3 {
regulator-name = "vdd";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
st,mask-reset;
regulator-initial-mode = <0>;
regulator-over-current-protection;
};
v3v3: buck4 { v3v3: buck4 {
regulator-name = "v3v3"; regulator-name = "v3v3";
regulator-min-microvolt = <3300000>; regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
regulator-boot-on; regulator-always-on;
regulator-over-current-protection; regulator-over-current-protection;
regulator-initial-mode = <8>; regulator-initial-mode = <0>;
};
regulator-state-standby { vdda: ldo1 {
regulator-suspend-microvolt = <3300000>; regulator-name = "vdda";
regulator-unchanged-in-suspend; regulator-min-microvolt = <2900000>;
regulator-mode = <8>; regulator-max-microvolt = <2900000>;
}; };
regulator-state-mem {
regulator-off-in-suspend; v2v8: ldo2 {
regulator-name = "v2v8";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
}; };
regulator-state-disk {
regulator-off-in-suspend; vtt_ddr: ldo3 {
regulator-name = "vtt_ddr";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <750000>;
regulator-always-on;
regulator-over-current-protection;
}; };
vdd_usb: ldo4 {
regulator-name = "vdd_usb";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
}; };
vdd_sd: ldo5 { vdd_sd: ldo5 {
...@@ -64,24 +121,24 @@ ...@@ -64,24 +121,24 @@
regulator-min-microvolt = <2900000>; regulator-min-microvolt = <2900000>;
regulator-max-microvolt = <2900000>; regulator-max-microvolt = <2900000>;
regulator-boot-on; regulator-boot-on;
regulator-state-standby {
regulator-suspend-microvolt = <2900000>;
regulator-unchanged-in-suspend;
};
regulator-state-mem {
regulator-off-in-suspend;
}; };
regulator-state-disk {
regulator-off-in-suspend; v1v8: ldo6 {
regulator-name = "v1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
}; };
vref_ddr: vref_ddr {
regulator-name = "vref_ddr";
regulator-always-on;
regulator-over-current-protection;
}; };
}; };
}; };
}; };
&iwdg2 { &iwdg2 {
instance = <2>;
timeout-sec = <32>; timeout-sec = <32>;
status = "okay"; status = "okay";
}; };
...@@ -90,14 +147,19 @@ ...@@ -90,14 +147,19 @@
status = "okay"; status = "okay";
}; };
&rtc {
status = "okay";
};
&sdmmc1 { &sdmmc1 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
broken-cd; broken-cd;
st,dirpol; st,sig-dir;
st,negedge; st,neg-edge;
st,pin-ckin; st,use-ckin;
bus-width = <4>; bus-width = <4>;
vmmc-supply = <&vdd_sd>;
sd-uhs-sdr12; sd-uhs-sdr12;
sd-uhs-sdr25; sd-uhs-sdr25;
sd-uhs-sdr50; sd-uhs-sdr50;
...@@ -112,16 +174,17 @@ ...@@ -112,16 +174,17 @@
non-removable; non-removable;
no-sd; no-sd;
no-sdio; no-sdio;
st,dirpol; st,neg-edge;
st,negedge;
bus-width = <8>; bus-width = <8>;
vmmc-supply = <&v3v3>;
vqmmc-supply = <&v3v3>;
mmc-ddr-3_3v;
status = "okay"; status = "okay";
}; };
&uart4 { &uart4 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_a>; pinctrl-0 = <&uart4_pins_a>;
resets = <&rcc UART4_R>;
status = "okay"; status = "okay";
}; };
...@@ -157,6 +220,7 @@ ...@@ -157,6 +220,7 @@
/* CLOCK init */ /* CLOCK init */
&rcc { &rcc {
secure-status = "disabled";
st,clksrc = < st,clksrc = <
CLK_MPU_PLL1P CLK_MPU_PLL1P
CLK_AXI_PLL2P CLK_AXI_PLL2P
...@@ -186,7 +250,7 @@ ...@@ -186,7 +250,7 @@
CLK_FMC_ACLK CLK_FMC_ACLK
CLK_QSPI_ACLK CLK_QSPI_ACLK
CLK_ETH_DISABLED CLK_ETH_DISABLED
CLK_SDMMC12_PLL3R CLK_SDMMC12_PLL4P
CLK_DSI_DSIPLL CLK_DSI_DSIPLL
CLK_STGEN_HSE CLK_STGEN_HSE
CLK_USBPHY_HSE CLK_USBPHY_HSE
...@@ -195,7 +259,7 @@ ...@@ -195,7 +259,7 @@
CLK_SPI45_HSI CLK_SPI45_HSI
CLK_SPI6_HSI CLK_SPI6_HSI
CLK_I2C46_HSI CLK_I2C46_HSI
CLK_SDMMC3_PLL3R CLK_SDMMC3_PLL4P
CLK_USBO_USBPHY CLK_USBO_USBPHY
CLK_ADC_CKPER CLK_ADC_CKPER
CLK_CEC_LSE CLK_CEC_LSE
...@@ -206,17 +270,17 @@ ...@@ -206,17 +270,17 @@
CLK_UART35_HSI CLK_UART35_HSI
CLK_UART6_HSI CLK_UART6_HSI
CLK_UART78_HSI CLK_UART78_HSI
CLK_SPDIF_PLL3Q CLK_SPDIF_PLL4P
CLK_FDCAN_PLL4Q CLK_FDCAN_PLL4Q
CLK_SAI1_PLL3Q CLK_SAI1_PLL3Q
CLK_SAI2_PLL3Q CLK_SAI2_PLL3Q
CLK_SAI3_PLL3Q CLK_SAI3_PLL3Q
CLK_SAI4_PLL3Q CLK_SAI4_PLL3Q
CLK_RNG1_CSI CLK_RNG1_LSI
CLK_RNG2_CSI CLK_RNG2_LSI
CLK_LPTIM1_PCLK1 CLK_LPTIM1_PCLK1
CLK_LPTIM23_PCLK3 CLK_LPTIM23_PCLK3
CLK_LPTIM45_PCLK3 CLK_LPTIM45_LSE
>; >;
/* VCO = 1300.0 MHz => P = 650 (CPU) */ /* VCO = 1300.0 MHz => P = 650 (CPU) */
...@@ -231,15 +295,15 @@ ...@@ -231,15 +295,15 @@
frac = < 0x1400 >; frac = < 0x1400 >;
}; };
/* VCO = 786.4 MHz => P = 197, Q = 49, R = 98 */ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
pll3: st,pll@2 { pll3: st,pll@2 {
cfg = < 2 97 3 15 7 PQR(1,1,1) >; cfg = < 1 33 1 16 36 PQR(1,1,1) >;
frac = < 0x9ba >; frac = < 0x1a04 >;
}; };
/* VCO = 508.0 MHz => P = 56, Q = 56, R = 56 */ /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
pll4: st,pll@3 { pll4: st,pll@3 {
cfg = < 5 126 8 8 8 PQR(1,1,1) >; cfg = < 3 98 5 7 7 PQR(1,1,1) >;
}; };
}; };
......
...@@ -3,23 +3,65 @@ ...@@ -3,23 +3,65 @@
* Copyright (C) STMicroelectronics 2017 - All Rights Reserved * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics. * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/ */
/dts-v1/; /dts-v1/;
#include "stm32mp157c-ed1.dts" #include "stm32mp157c-ed1.dts"
/ { / {
model = "STMicroelectronics STM32MP157C-EV1 pmic eval daughter on eval mother"; model = "STMicroelectronics STM32MP157C eval daughter on eval mother";
compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157"; compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157";
chosen { chosen {
bootargs = "earlyprintk console=ttyS3,115200 root=/dev/ram"; stdout-path = "serial0:115200n8";
stdout-path = "serial3:115200n8"; };
aliases {
serial1 = &usart3;
};
};
&fmc {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
nand: nand@0 {
reg = <0>;
nand-on-flash-bbt;
#address-cells = <1>;
#size-cells = <1>;
};
};
&qspi {
pinctrl-names = "default";
pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>;
reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
flash0: mx66l51235l@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-rx-bus-width = <4>;
spi-max-frequency = <108000000>;
#address-cells = <1>;
#size-cells = <1>;
};
flash1: mx66l51235l@1 {
compatible = "jedec,spi-nor";
reg = <1>;
spi-rx-bus-width = <4>;
spi-max-frequency = <108000000>;
#address-cells = <1>;
#size-cells = <1>;
}; };
}; };
&usart3 { &usart3 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&usart3_pins_a>; pinctrl-0 = <&usart3_pins_a>;
resets = <&rcc USART3_R>;
status = "disabled"; status = "disabled";
}; };
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Copyright (C) STMicroelectronics 2017 - All Rights Reserved * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics. * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/ */
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/stm32mp1-clks.h> #include <dt-bindings/clock/stm32mp1-clks.h>
#include <dt-bindings/reset/stm32mp1-resets.h> #include <dt-bindings/reset/stm32mp1-resets.h>
...@@ -11,15 +11,12 @@ ...@@ -11,15 +11,12 @@
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
aliases { intc: interrupt-controller@a0021000 {
serial0 = &usart1; compatible = "arm,cortex-a7-gic";
serial1 = &usart2; #interrupt-cells = <3>;
serial2 = &usart3; interrupt-controller;
serial3 = &uart4; reg = <0xa0021000 0x1000>,
serial4 = &uart5; <0xa0022000 0x2000>;
serial5 = &usart6;
serial6 = &uart7;
serial7 = &uart8;
}; };
clocks { clocks {
...@@ -56,7 +53,7 @@ ...@@ -56,7 +53,7 @@
clk_i2s_ckin: i2s_ckin { clk_i2s_ckin: i2s_ckin {
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock"; compatible = "fixed-clock";
clock-frequency = <64000000>; clock-frequency = <0>;
}; };
clk_dsi_phy: ck_dsi_phy { clk_dsi_phy: ck_dsi_phy {
...@@ -64,31 +61,28 @@ ...@@ -64,31 +61,28 @@
compatible = "fixed-clock"; compatible = "fixed-clock";
clock-frequency = <0>; clock-frequency = <0>;
}; };
clk_usbo_48m: ck_usbo_48m {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <48000000>;
};
}; };
soc { soc {
compatible = "simple-bus"; compatible = "simple-bus";
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
interrupt-parent = <&intc>;
ranges; ranges;
usart2: serial@4000e000 { usart2: serial@4000e000 {
compatible = "st,stm32h7-usart"; compatible = "st,stm32h7-uart";
reg = <0x4000e000 0x400>; reg = <0x4000e000 0x400>;
clocks = <&rcc USART2_K>; clocks = <&rcc USART2_K>;
resets = <&rcc USART2_R>;
status = "disabled"; status = "disabled";
}; };
usart3: serial@4000f000 { usart3: serial@4000f000 {
compatible = "st,stm32h7-usart"; compatible = "st,stm32h7-uart";
reg = <0x4000f000 0x400>; reg = <0x4000f000 0x400>;
clocks = <&rcc USART3_K>; clocks = <&rcc USART3_K>;
resets = <&rcc USART3_R>;
status = "disabled"; status = "disabled";
}; };
...@@ -96,6 +90,7 @@ ...@@ -96,6 +90,7 @@
compatible = "st,stm32h7-uart"; compatible = "st,stm32h7-uart";
reg = <0x40010000 0x400>; reg = <0x40010000 0x400>;
clocks = <&rcc UART4_K>; clocks = <&rcc UART4_K>;
resets = <&rcc UART4_R>;
status = "disabled"; status = "disabled";
}; };
...@@ -103,6 +98,7 @@ ...@@ -103,6 +98,7 @@
compatible = "st,stm32h7-uart"; compatible = "st,stm32h7-uart";
reg = <0x40011000 0x400>; reg = <0x40011000 0x400>;
clocks = <&rcc UART5_K>; clocks = <&rcc UART5_K>;
resets = <&rcc UART5_R>;
status = "disabled"; status = "disabled";
}; };
...@@ -111,6 +107,7 @@ ...@@ -111,6 +107,7 @@
compatible = "st,stm32h7-uart"; compatible = "st,stm32h7-uart";
reg = <0x40018000 0x400>; reg = <0x40018000 0x400>;
clocks = <&rcc UART7_K>; clocks = <&rcc UART7_K>;
resets = <&rcc UART7_R>;
status = "disabled"; status = "disabled";
}; };
...@@ -118,21 +115,23 @@ ...@@ -118,21 +115,23 @@
compatible = "st,stm32h7-uart"; compatible = "st,stm32h7-uart";
reg = <0x40019000 0x400>; reg = <0x40019000 0x400>;
clocks = <&rcc UART8_K>; clocks = <&rcc UART8_K>;
resets = <&rcc UART8_R>;
status = "disabled"; status = "disabled";
}; };
usart6: serial@44003000 { usart6: serial@44003000 {
compatible = "st,stm32h7-usart"; compatible = "st,stm32h7-uart";
reg = <0x44003000 0x400>; reg = <0x44003000 0x400>;
clocks = <&rcc USART6_K>; clocks = <&rcc USART6_K>;
resets = <&rcc USART6_R>;
status = "disabled"; status = "disabled";
}; };
sdmmc3: sdmmc@48004000 { sdmmc3: sdmmc@48004000 {
compatible = "st,stm32-sdmmc2"; compatible = "st,stm32-sdmmc2";
reg = <0x48004000 0x400>, <0x48005000 0x400>; reg = <0x48004000 0x400>, <0x48005000 0x400>;
reg-names = "sdmmc", "delay";
clocks = <&rcc SDMMC3_K>; clocks = <&rcc SDMMC3_K>;
clock-names = "apb_pclk";
resets = <&rcc SDMMC3_R>; resets = <&rcc SDMMC3_R>;
cap-sd-highspeed; cap-sd-highspeed;
cap-mmc-highspeed; cap-mmc-highspeed;
...@@ -141,17 +140,34 @@ ...@@ -141,17 +140,34 @@
}; };
rcc: rcc@50000000 { rcc: rcc@50000000 {
compatible = "syscon", "st,stm32mp1-rcc"; compatible = "st,stm32mp1-rcc", "syscon";
reg = <0x50000000 0x1000>;
#clock-cells = <1>; #clock-cells = <1>;
#reset-cells = <1>; #reset-cells = <1>;
reg = <0x50000000 0x1000>; interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
}; };
rcc_reboot: rcc-reboot@50000000 { pwr: pwr@50001000 {
compatible = "syscon-reboot"; compatible = "st,stm32mp1-pwr", "syscon", "simple-mfd";
regmap = <&rcc>; reg = <0x50001000 0x400>;
offset = <0x404>; };
mask = <0x1>;
exti: interrupt-controller@5000d000 {
compatible = "st,stm32mp1-exti", "syscon";
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x5000d000 0x400>;
/* exti_pwr is an extra interrupt controller used for
* EXTI 55 to 60. It's mapped on pwr interrupt
* controller.
*/
exti_pwr: exti-pwr {
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&pwr>;
st,irq-number = <6>;
};
}; };
rng1: rng@54003000 { rng1: rng@54003000 {
...@@ -162,13 +178,15 @@ ...@@ -162,13 +178,15 @@
status = "disabled"; status = "disabled";
}; };
fmc_nand: fmc_nand@58002000 { fmc: nand-controller@58002000 {
compatible = "st,stm32mp1-fmc"; compatible = "st,stm32mp15-fmc2";
reg = <0x58002000 0x1000>, reg = <0x58002000 0x1000>,
<0x80000000 0x40000>, <0x80000000 0x1000>,
<0x81000000 0x40000>, <0x88010000 0x1000>,
<0x88000000 0x40000>, <0x88020000 0x1000>,
<0x89000000 0x40000>; <0x81000000 0x1000>,
<0x89010000 0x1000>,
<0x89020000 0x1000>;
clocks = <&rcc FMC_K>; clocks = <&rcc FMC_K>;
resets = <&rcc FMC_R>; resets = <&rcc FMC_R>;
status = "disabled"; status = "disabled";
...@@ -177,15 +195,17 @@ ...@@ -177,15 +195,17 @@
qspi: qspi@58003000 { qspi: qspi@58003000 {
compatible = "st,stm32f469-qspi"; compatible = "st,stm32f469-qspi";
reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
reg-names = "qspi", "qspi_mm";
clocks = <&rcc QSPI_K>; clocks = <&rcc QSPI_K>;
resets = <&rcc QSPI_R>;
status = "disabled"; status = "disabled";
}; };
sdmmc1: sdmmc@58005000 { sdmmc1: sdmmc@58005000 {
compatible = "st,stm32-sdmmc2"; compatible = "st,stm32-sdmmc2";
reg = <0x58005000 0x1000>, <0x58006000 0x1000>; reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
reg-names = "sdmmc", "delay";
clocks = <&rcc SDMMC1_K>; clocks = <&rcc SDMMC1_K>;
clock-names = "apb_pclk";
resets = <&rcc SDMMC1_R>; resets = <&rcc SDMMC1_R>;
cap-sd-highspeed; cap-sd-highspeed;
cap-mmc-highspeed; cap-mmc-highspeed;
...@@ -196,8 +216,8 @@ ...@@ -196,8 +216,8 @@
sdmmc2: sdmmc@58007000 { sdmmc2: sdmmc@58007000 {
compatible = "st,stm32-sdmmc2"; compatible = "st,stm32-sdmmc2";
reg = <0x58007000 0x1000>, <0x58008000 0x1000>; reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
reg-names = "sdmmc", "delay";
clocks = <&rcc SDMMC2_K>; clocks = <&rcc SDMMC2_K>;
clock-names = "apb_pclk";
resets = <&rcc SDMMC2_R>; resets = <&rcc SDMMC2_R>;
cap-sd-highspeed; cap-sd-highspeed;
cap-mmc-highspeed; cap-mmc-highspeed;
...@@ -205,7 +225,7 @@ ...@@ -205,7 +225,7 @@
status = "disabled"; status = "disabled";
}; };
iwdg2: iwdg@5a002000 { iwdg2: watchdog@5a002000 {
compatible = "st,stm32mp1-iwdg"; compatible = "st,stm32mp1-iwdg";
reg = <0x5a002000 0x400>; reg = <0x5a002000 0x400>;
clocks = <&rcc IWDG2>, <&rcc CK_LSI>; clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
...@@ -214,15 +234,34 @@ ...@@ -214,15 +234,34 @@
}; };
usart1: serial@5c000000 { usart1: serial@5c000000 {
compatible = "st,stm32h7-usart"; compatible = "st,stm32h7-uart";
reg = <0x5c000000 0x400>; reg = <0x5c000000 0x400>;
interrupt-names = "event", "wakeup";
interrupts-extended = <&intc GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
<&exti 26 1>;
clocks = <&rcc USART1_K>; clocks = <&rcc USART1_K>;
resets = <&rcc USART1_R>;
status = "disabled";
};
spi6: spi@5c001000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "st,stm32h7-spi";
reg = <0x5c001000 0x400>;
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc SPI6_K>;
resets = <&rcc SPI6_R>;
status = "disabled"; status = "disabled";
}; };
i2c4: i2c@5c002000 { i2c4: i2c@5c002000 {
compatible = "st,stm32f7-i2c"; compatible = "st,stm32f7-i2c";
reg = <0x5c002000 0x400>; reg = <0x5c002000 0x400>;
interrupt-names = "event", "error", "wakeup";
interrupts-extended = <&intc GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
<&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
<&exti 24 1>;
clocks = <&rcc I2C4_K>; clocks = <&rcc I2C4_K>;
resets = <&rcc I2C4_R>; resets = <&rcc I2C4_R>;
#address-cells = <1>; #address-cells = <1>;
...@@ -235,6 +274,36 @@ ...@@ -235,6 +274,36 @@
reg = <0x5c004000 0x400>; reg = <0x5c004000 0x400>;
clocks = <&rcc RTCAPB>, <&rcc RTC>; clocks = <&rcc RTCAPB>, <&rcc RTC>;
clock-names = "pclk", "rtc_ck"; clock-names = "pclk", "rtc_ck";
interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
<&exti 19 1>;
status = "disabled";
};
bsec: nvmem@5c005000 {
compatible = "st,stm32mp15-bsec";
reg = <0x5c005000 0x400>;
#address-cells = <1>;
#size-cells = <1>;
ts_cal1: calib@5c {
reg = <0x5c 0x2>;
};
ts_cal2: calib@5e {
reg = <0x5e 0x2>;
};
};
i2c6: i2c@5c009000 {
compatible = "st,stm32f7-i2c";
reg = <0x5c009000 0x400>;
interrupt-names = "event", "error", "wakeup";
interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
<&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
<&exti 54 1>;
clocks = <&rcc I2C6_K>;
resets = <&rcc I2C6_R>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
}; };
}; };
}; };
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
#include "stm32mp157-pinctrl.dtsi" #include "stm32mp157-pinctrl.dtsi"
/ { / {
soc { soc {
pinctrl: pin-controller { pinctrl: pin-controller@50002000 {
compatible = "st,stm32mp157caa-pinctrl"; st,package = <STM32MP157CAA>;
gpioa: gpio@50002000 { gpioa: gpio@50002000 {
status = "okay"; status = "okay";
...@@ -77,8 +77,8 @@ ...@@ -77,8 +77,8 @@
}; };
}; };
pinctrl_z: pin-controller-z { pinctrl_z: pin-controller-z@54004000 {
compatible = "st,stm32mp157caa-z-pinctrl"; st,package = <STM32MP157CAA>;
gpioz: gpio@54004000 { gpioz: gpio@54004000 {
status = "okay"; status = "okay";
......
/*
* Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef BSEC_H
#define BSEC_H
#include <stdbool.h>
#include <stdint.h>
#include <lib/utils_def.h>
/*
* IP configuration
*/
#define BSEC_OTP_MASK GENMASK(4, 0)
#define BSEC_OTP_BANK_SHIFT 5
#define BSEC_TIMEOUT_VALUE 0xFFFF
#define ADDR_LOWER_OTP_PERLOCK_SHIFT 0x03
#define DATA_LOWER_OTP_PERLOCK_BIT 0x03U /* 2 significants bits are used */
#define DATA_LOWER_OTP_PERLOCK_MASK GENMASK(2, 0)
#define ADDR_UPPER_OTP_PERLOCK_SHIFT 0x04
#define DATA_UPPER_OTP_PERLOCK_BIT 0x01U /* 1 significants bits are used */
#define DATA_UPPER_OTP_PERLOCK_MASK GENMASK(3, 0)
/*
* Return status
*/
#define BSEC_OK 0U
#define BSEC_ERROR 0xFFFFFFFFU
#define BSEC_DISTURBED 0xFFFFFFFEU
#define BSEC_INVALID_PARAM 0xFFFFFFFCU
#define BSEC_PROG_FAIL 0xFFFFFFFBU
#define BSEC_LOCK_FAIL 0xFFFFFFFAU
#define BSEC_WRITE_FAIL 0xFFFFFFF9U
#define BSEC_SHADOW_FAIL 0xFFFFFFF8U
#define BSEC_TIMEOUT 0xFFFFFFF7U
/*
* BSEC REGISTER OFFSET (base relative)
*/
#define BSEC_OTP_CONF_OFF 0x000U
#define BSEC_OTP_CTRL_OFF 0x004U
#define BSEC_OTP_WRDATA_OFF 0x008U
#define BSEC_OTP_STATUS_OFF 0x00CU
#define BSEC_OTP_LOCK_OFF 0x010U
#define BSEC_DEN_OFF 0x014U
#define BSEC_DISTURBED_OFF 0x01CU
#define BSEC_DISTURBED1_OFF 0x020U
#define BSEC_DISTURBED2_OFF 0x024U
#define BSEC_ERROR_OFF 0x034U
#define BSEC_ERROR1_OFF 0x038U
#define BSEC_ERROR2_OFF 0x03CU
#define BSEC_WRLOCK_OFF 0x04CU /* Safmem permanent lock */
#define BSEC_WRLOCK1_OFF 0x050U
#define BSEC_WRLOCK2_OFF 0x054U
#define BSEC_SPLOCK_OFF 0x064U /* Program safmem sticky lock */
#define BSEC_SPLOCK1_OFF 0x068U
#define BSEC_SPLOCK2_OFF 0x06CU
#define BSEC_SWLOCK_OFF 0x07CU /* Write in OTP sticky lock */
#define BSEC_SWLOCK1_OFF 0x080U
#define BSEC_SWLOCK2_OFF 0x084U
#define BSEC_SRLOCK_OFF 0x094U /* Shadowing sticky lock */
#define BSEC_SRLOCK1_OFF 0x098U
#define BSEC_SRLOCK2_OFF 0x09CU
#define BSEC_JTAG_IN_OFF 0x0ACU
#define BSEC_JTAG_OUT_OFF 0x0B0U
#define BSEC_SCRATCH_OFF 0x0B4U
#define BSEC_OTP_DATA_OFF 0x200U
#define BSEC_IPHW_CFG_OFF 0xFF0U
#define BSEC_IPVR_OFF 0xFF4U
#define BSEC_IP_ID_OFF 0xFF8U
#define BSEC_IP_MAGIC_ID_OFF 0xFFCU
/*
* BSEC_CONFIGURATION Register
*/
#define BSEC_CONF_POWER_UP_MASK BIT(0)
#define BSEC_CONF_POWER_UP_SHIFT 0
#define BSEC_CONF_FRQ_MASK GENMASK(2, 1)
#define BSEC_CONF_FRQ_SHIFT 1
#define BSEC_CONF_PRG_WIDTH_MASK GENMASK(6, 3)
#define BSEC_CONF_PRG_WIDTH_SHIFT 3
#define BSEC_CONF_TREAD_MASK GENMASK(8, 7)
#define BSEC_CONF_TREAD_SHIFT 7
/*
* BSEC_CONTROL Register
*/
#define BSEC_READ 0x000U
#define BSEC_WRITE 0x100U
#define BSEC_LOCK 0x200U
/*
* BSEC_OTP_LOCK register
*/
#define UPPER_OTP_LOCK_MASK BIT(0)
#define UPPER_OTP_LOCK_SHIFT 0
#define DENREG_LOCK_MASK BIT(2)
#define DENREG_LOCK_SHIFT 2
#define GPLOCK_LOCK_MASK BIT(4)
#define GPLOCK_LOCK_SHIFT 4
/*
* BSEC_OTP_STATUS Register
*/
#define BSEC_MODE_STATUS_MASK GENMASK(2, 0)
#define BSEC_MODE_BUSY_MASK BIT(3)
#define BSEC_MODE_PROGFAIL_MASK BIT(4)
#define BSEC_MODE_PWR_MASK BIT(5)
#define BSEC_MODE_BIST1_LOCK_MASK BIT(6)
#define BSEC_MODE_BIST2_LOCK_MASK BIT(7)
/* OTP MODE*/
#define BSEC_MODE_OPEN1 0x00
#define BSEC_MODE_SECURED 0x01
#define BSEC_MODE_OPEN2 0x02
#define BSEC_MODE_INVALID 0x04
/* BSEC_DENABLE Register */
#define BSEC_HDPEN BIT(4)
#define BSEC_SPIDEN BIT(5)
#define BSEC_SPINDEN BIT(6)
#define BSEC_DBGSWGEN BIT(10)
#define BSEC_DEN_ALL_MSK GENMASK(10, 0)
/* BSEC_FENABLE Register */
#define BSEC_FEN_ALL_MSK GENMASK(14, 0)
/*
* OTP Lock services definition
* Value must corresponding to the bit number in the register
*/
#define BSEC_LOCK_UPPER_OTP 0x00
#define BSEC_LOCK_DEBUG 0x02
#define BSEC_LOCK_PROGRAM 0x03
/* Values for struct bsec_config::freq */
#define FREQ_10_20_MHZ 0x0
#define FREQ_20_30_MHZ 0x1
#define FREQ_30_45_MHZ 0x2
#define FREQ_45_67_MHZ 0x3
/*
* Device info structure, providing device-specific functions and a means of
* adding driver-specific state
*/
struct bsec_config {
uint8_t tread; /* SAFMEM Reading current level default 0 */
uint8_t pulse_width; /* SAFMEM Programming pulse width default 1 */
uint8_t freq; /* SAFMEM CLOCK see freq value define
* default FREQ_45_67_MHZ
*/
uint8_t power; /* Power up SAFMEM. 1 power up, 0 power off */
uint8_t prog_lock; /* Programming Sticky lock
* 1 programming is locked until next reset
*/
uint8_t den_lock; /* Debug enable sticky lock
* 1 debug enable is locked until next reset
*/
uint8_t upper_otp_lock; /* Shadowing of upper OTP sticky lock
* 1 shadowing of upper OTP is locked
* until next reset
*/
};
uint32_t bsec_probe(void);
uint32_t bsec_get_base(void);
uint32_t bsec_set_config(struct bsec_config *cfg);
uint32_t bsec_get_config(struct bsec_config *cfg);
uint32_t bsec_shadow_register(uint32_t otp);
uint32_t bsec_read_otp(uint32_t *val, uint32_t otp);
uint32_t bsec_write_otp(uint32_t val, uint32_t otp);
uint32_t bsec_program_otp(uint32_t val, uint32_t otp);
uint32_t bsec_permanent_lock_otp(uint32_t otp);
uint32_t bsec_write_debug_conf(uint32_t val);
uint32_t bsec_read_debug_conf(void);
uint32_t bsec_write_feature_conf(uint32_t val);
uint32_t bsec_read_feature_conf(uint32_t *val);
uint32_t bsec_get_status(void);
uint32_t bsec_get_hw_conf(void);
uint32_t bsec_get_version(void);
uint32_t bsec_get_id(void);
uint32_t bsec_get_magic_id(void);
bool bsec_write_sr_lock(uint32_t otp, uint32_t value);
bool bsec_read_sr_lock(uint32_t otp);
bool bsec_write_sw_lock(uint32_t otp, uint32_t value);
bool bsec_read_sw_lock(uint32_t otp);
bool bsec_write_sp_lock(uint32_t otp, uint32_t value);
bool bsec_read_sp_lock(uint32_t otp);
bool bsec_wr_lock(uint32_t otp);
uint32_t bsec_otp_lock(uint32_t service, uint32_t value);
bool bsec_mode_is_closed_device(void);
uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word);
uint32_t bsec_check_nsec_access_rights(uint32_t otp);
#endif /* BSEC_H */
/* /*
* Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -9,10 +9,6 @@ ...@@ -9,10 +9,6 @@
#include <lib/utils_def.h> #include <lib/utils_def.h>
#define STM32_GPIOA_BANK U(0x50002000)
#define STM32_GPIOZ_BANK U(0x54004000)
#define STM32_GPIO_BANK_OFFSET U(0x1000)
#define GPIO_MODE_OFFSET U(0x00) #define GPIO_MODE_OFFSET U(0x00)
#define GPIO_TYPE_OFFSET U(0x04) #define GPIO_TYPE_OFFSET U(0x04)
#define GPIO_SPEED_OFFSET U(0x08) #define GPIO_SPEED_OFFSET U(0x08)
...@@ -20,56 +16,14 @@ ...@@ -20,56 +16,14 @@
#define GPIO_BSRR_OFFSET U(0x18) #define GPIO_BSRR_OFFSET U(0x18)
#define GPIO_AFRL_OFFSET U(0x20) #define GPIO_AFRL_OFFSET U(0x20)
#define GPIO_AFRH_OFFSET U(0x24) #define GPIO_AFRH_OFFSET U(0x24)
#define GPIO_SECR_OFFSET U(0x30)
#define GPIO_ALT_LOWER_LIMIT U(0x08) #define GPIO_ALT_LOWER_LIMIT U(0x08)
#define GPIO_BANK_A U(0x00) #define GPIO_PIN_(_x) U(_x)
#define GPIO_BANK_B U(0x01) #define GPIO_PIN_MAX GPIO_PIN_(15)
#define GPIO_BANK_C U(0x02)
#define GPIO_BANK_D U(0x03)
#define GPIO_BANK_E U(0x04)
#define GPIO_BANK_F U(0x05)
#define GPIO_BANK_G U(0x06)
#define GPIO_BANK_H U(0x07)
#define GPIO_BANK_I U(0x08)
#define GPIO_BANK_J U(0x09)
#define GPIO_BANK_K U(0x0A)
#define GPIO_BANK_Z U(0x19)
#define GPIO_PIN_0 U(0x00)
#define GPIO_PIN_1 U(0x01)
#define GPIO_PIN_2 U(0x02)
#define GPIO_PIN_3 U(0x03)
#define GPIO_PIN_4 U(0x04)
#define GPIO_PIN_5 U(0x05)
#define GPIO_PIN_6 U(0x06)
#define GPIO_PIN_7 U(0x07)
#define GPIO_PIN_8 U(0x08)
#define GPIO_PIN_9 U(0x09)
#define GPIO_PIN_10 U(0x0A)
#define GPIO_PIN_11 U(0x0B)
#define GPIO_PIN_12 U(0x0C)
#define GPIO_PIN_13 U(0x0D)
#define GPIO_PIN_14 U(0x0E)
#define GPIO_PIN_15 U(0x0F)
#define GPIO_PIN_MAX GPIO_PIN_15
#define GPIO_ALTERNATE_0 0x00 #define GPIO_ALTERNATE_(_x) U(_x)
#define GPIO_ALTERNATE_1 0x01
#define GPIO_ALTERNATE_2 0x02
#define GPIO_ALTERNATE_3 0x03
#define GPIO_ALTERNATE_4 0x04
#define GPIO_ALTERNATE_5 0x05
#define GPIO_ALTERNATE_6 0x06
#define GPIO_ALTERNATE_7 0x07
#define GPIO_ALTERNATE_8 0x08
#define GPIO_ALTERNATE_9 0x09
#define GPIO_ALTERNATE_10 0x0A
#define GPIO_ALTERNATE_11 0x0B
#define GPIO_ALTERNATE_12 0x0C
#define GPIO_ALTERNATE_13 0x0D
#define GPIO_ALTERNATE_14 0x0E
#define GPIO_ALTERNATE_15 0x0F
#define GPIO_ALTERNATE_MASK U(0x0F) #define GPIO_ALTERNATE_MASK U(0x0F)
#define GPIO_MODE_INPUT 0x00 #define GPIO_MODE_INPUT 0x00
...@@ -82,8 +36,8 @@ ...@@ -82,8 +36,8 @@
#define GPIO_SPEED_LOW 0x00 #define GPIO_SPEED_LOW 0x00
#define GPIO_SPEED_MEDIUM 0x01 #define GPIO_SPEED_MEDIUM 0x01
#define GPIO_SPEED_FAST 0x02 #define GPIO_SPEED_HIGH 0x02
#define GPIO_SPEED_HIGH 0x03 #define GPIO_SPEED_VERY_HIGH 0x03
#define GPIO_SPEED_MASK U(0x03) #define GPIO_SPEED_MASK U(0x03)
#define GPIO_NO_PULL 0x00 #define GPIO_NO_PULL 0x00
...@@ -94,8 +48,10 @@ ...@@ -94,8 +48,10 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <stdint.h> #include <stdint.h>
int dt_set_pinctrl_config(int node);
void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed, void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
uint32_t pull, uint32_t alternate); uint32_t pull, uint32_t alternate, uint8_t status);
void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure);
#endif /*__ASSEMBLY__*/ #endif /*__ASSEMBLY__*/
#endif /* STM32_GPIO_H */ #endif /* STM32_GPIO_H */
/* /*
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
* *
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/ */
...@@ -153,7 +153,7 @@ struct stm32mp1_ddrphy_cal { ...@@ -153,7 +153,7 @@ struct stm32mp1_ddrphy_cal {
struct stm32mp1_ddr_info { struct stm32mp1_ddr_info {
const char *name; const char *name;
uint16_t speed; /* in MHZ */ uint32_t speed; /* in kHZ */
uint32_t size; /* Memory size in byte = col * row * width */ uint32_t size; /* Memory size in byte = col * row * width */
}; };
...@@ -168,7 +168,7 @@ struct stm32mp1_ddr_config { ...@@ -168,7 +168,7 @@ struct stm32mp1_ddr_config {
struct stm32mp1_ddrphy_cal p_cal; struct stm32mp1_ddrphy_cal p_cal;
}; };
int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed); int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed);
void stm32mp1_ddr_init(struct ddr_info *priv, void stm32mp1_ddr_init(struct ddr_info *priv,
struct stm32mp1_ddr_config *config); struct stm32mp1_ddr_config *config);
#endif /* STM32MP1_DDR_H */ #endif /* STM32MP1_DDR_H */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment