arm-trusted-firmware/include/drivers/st/stm32mp_ddr.h
Nicolas Le Bayon d596023bff refactor(st-ddr): create generic services
Disabling AXI port, enabling host interface and both enabling/disabling
software self-refresh services are already present inside the driver
source code.
Factorize by gathering them as services inside the generic part,
and adapt driver to call these new functions.

Add services to manage quasi-dynamic registers. DDRCTRL contains
quasi-dynamic registers, which are dynamic only under some conditions
defined by the user guide (with 4 groups).
In our driver, out of reset state, only groups 3 and 4 are updated.
Group 4 needs only sw_done/sw_done_ack sequence, already available.
Group 3 sequence include more conditions, that are gathered in
specific services. stm32mp_ddr_disable_host_interface() has been added
to do this.

Add dedicated generic service to toggle rfshctl3.refresh_update_level
and wait for completion.

Manage AXI ports and HIF when updating QD3 registers. Quasi-dynamic
group 3 (QD3) registers are updated when DDR is not completely
initialized, i.e. when AXI ports are not enabled and possibly when
host interface (HIF) is not enabled too.
In that case, a specific mechanism is necessary to restore the same
conditions as before accessing QD3 registers.
Static functions have been added to get AXI ports and HIF states and
are used to determine the needed conditions to set/unset.

Signed-off-by: Nicolas Le Bayon <nicolas.le.bayon@st.com>
Change-Id: I880f88b1cb6fc76199ad9ea33e9d63a5c469aed4
2024-10-02 18:27:36 +02:00

81 lines
2.1 KiB
C

/*
* Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
#ifndef STM32MP_DDR_H
#define STM32MP_DDR_H
#include <platform_def.h>
enum stm32mp_ddr_base_type {
DDR_BASE,
DDRPHY_BASE,
NONE_BASE
};
enum stm32mp_ddr_reg_type {
REG_REG,
REG_TIMING,
REG_PERF,
REG_MAP,
REGPHY_REG,
REGPHY_TIMING,
REG_TYPE_NB
};
struct stm32mp_ddr_reg_desc {
uint16_t offset; /* Offset for base address */
uint8_t par_offset; /* Offset for parameter array */
};
struct stm32mp_ddr_reg_info {
const char *name;
const struct stm32mp_ddr_reg_desc *desc;
uint8_t size;
enum stm32mp_ddr_base_type base;
};
struct stm32mp_ddr_size {
uint64_t base;
uint64_t size;
};
struct stm32mp_ddr_priv {
struct stm32mp_ddr_size info;
struct stm32mp_ddrctl *ctl;
struct stm32mp_ddrphy *phy;
uintptr_t pwr;
uintptr_t rcc;
};
struct stm32mp_ddr_info {
const char *name;
uint32_t speed; /* in kHz */
size_t size; /* Memory size in byte = col * row * width */
};
#define DDR_DELAY_1US 1U
#define DDR_DELAY_2US 2U
#define DDR_DELAY_10US 10U
#define DDR_DELAY_50US 50U
#define DDR_TIMEOUT_500US 500U
#define DDR_TIMEOUT_US_1S 1000000U
void stm32mp_ddr_set_reg(const struct stm32mp_ddr_priv *priv, enum stm32mp_ddr_reg_type type,
const void *param, const struct stm32mp_ddr_reg_info *ddr_registers);
void stm32mp_ddr_start_sw_done(struct stm32mp_ddrctl *ctl);
void stm32mp_ddr_wait_sw_done_ack(struct stm32mp_ddrctl *ctl);
void stm32mp_ddr_enable_axi_port(struct stm32mp_ddrctl *ctl);
int stm32mp_ddr_disable_axi_port(struct stm32mp_ddrctl *ctl);
void stm32mp_ddr_enable_host_interface(struct stm32mp_ddrctl *ctl);
void stm32mp_ddr_disable_host_interface(struct stm32mp_ddrctl *ctl);
int stm32mp_ddr_sw_selfref_entry(struct stm32mp_ddrctl *ctl);
void stm32mp_ddr_sw_selfref_exit(struct stm32mp_ddrctl *ctl);
void stm32mp_ddr_set_qd3_update_conditions(struct stm32mp_ddrctl *ctl);
void stm32mp_ddr_unset_qd3_update_conditions(struct stm32mp_ddrctl *ctl);
void stm32mp_ddr_wait_refresh_update_done_ack(struct stm32mp_ddrctl *ctl);
int stm32mp_board_ddr_power_init(enum ddr_type ddr_type);
#endif /* STM32MP_DDR_H */